aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinliang David Li <davidxl@google.com>2009-09-30 17:16:35 +0000
committerXinliang David Li <davidxl@google.com>2009-09-30 17:16:35 +0000
commit45b12281d1701b37b6d85633d057992ddf00c708 (patch)
tree9b9c3dcf0d11de08e77d056d8d10e07b7860e7a3
parentff402a15ce17973f30b9734c41f966dda992cd2e (diff)
This is a merge from trunk 151395:151806
Along with the merge, several fixes to resolve the conflicts: 1) Disallow auxiliary functions in ipa early sra. The aux functions may get deleted. 2) Change the assembler name for sra transformed function to avoid name conflict in assembly file -- the conflict may come from a transformed function and another function in aux module which is emitted (e.g, in comdat) 3) Due to the phase ordering change of thunk emission, thunks for external auxilary functions are conditionally emitted -- leading to inconsistent comdat group (with the defining primary module) -- this can result in unsats. 4) during cfg fixup for sra transformation, the eh landing pad can be missing. This is due to the wrong order of eh edge manipulation. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/lw-ipo@152338 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog34
-rw-r--r--MAINTAINERS7
-rw-r--r--boehm-gc/ChangeLog11
-rw-r--r--boehm-gc/Makefile.am4
-rw-r--r--boehm-gc/Makefile.in12
-rwxr-xr-xboehm-gc/configure12
-rw-r--r--config/ChangeLog13
-rw-r--r--config/stdint.m414
-rwxr-xr-xconfigure57
-rw-r--r--configure.ac47
-rw-r--r--contrib/ChangeLog10
-rwxr-xr-xcontrib/compare-debug22
-rw-r--r--fixincludes/ChangeLog35
-rw-r--r--fixincludes/README13
-rw-r--r--fixincludes/check.tpl2
-rw-r--r--fixincludes/fixincl.x235
-rw-r--r--fixincludes/inclhack.def139
-rw-r--r--fixincludes/mkheaders.in2
-rw-r--r--fixincludes/tests/base/Xm/Traversal.h2
-rw-r--r--fixincludes/tests/base/math.h12
-rw-r--r--fixincludes/tests/base/stdio.h7
-rw-r--r--fixincludes/tests/base/sys/limits.h17
-rw-r--r--gcc/ChangeLog1706
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in26
-rw-r--r--gcc/aclocal.m41
-rw-r--r--gcc/ada/ChangeLog235
-rw-r--r--gcc/ada/a-dynpri.adb8
-rw-r--r--gcc/ada/clean.adb13
-rw-r--r--gcc/ada/exp_ch4.adb130
-rw-r--r--gcc/ada/exp_ch5.adb4
-rw-r--r--gcc/ada/exp_ch6.adb27
-rw-r--r--gcc/ada/exp_ch9.adb4
-rw-r--r--gcc/ada/exp_dbug.ads26
-rw-r--r--gcc/ada/exp_disp.adb51
-rw-r--r--gcc/ada/exp_disp.ads5
-rw-r--r--gcc/ada/exp_intr.adb7
-rw-r--r--gcc/ada/freeze.adb11
-rw-r--r--gcc/ada/g-expect.adb12
-rw-r--r--gcc/ada/g-socket.adb41
-rw-r--r--gcc/ada/g-socket.ads3
-rw-r--r--gcc/ada/gcc-interface/Make-lang.in13
-rw-r--r--gcc/ada/gcc-interface/config-lang.in2
-rw-r--r--gcc/ada/gcc-interface/decl.c260
-rw-r--r--gcc/ada/gcc-interface/misc.c26
-rw-r--r--gcc/ada/gcc-interface/targtyps.c3
-rw-r--r--gcc/ada/gcc-interface/trans.c28
-rw-r--r--gcc/ada/gcc-interface/utils.c20
-rw-r--r--gcc/ada/gnat_rm.texi4
-rw-r--r--gcc/ada/gnatcmd.adb18
-rw-r--r--gcc/ada/gprep.adb23
-rw-r--r--gcc/ada/make.adb147
-rw-r--r--gcc/ada/makeutl.adb23
-rw-r--r--gcc/ada/makeutl.ads5
-rw-r--r--gcc/ada/prj-conf.adb49
-rw-r--r--gcc/ada/prj-conf.ads4
-rw-r--r--gcc/ada/prj-env.adb8
-rw-r--r--gcc/ada/prj-env.ads7
-rw-r--r--gcc/ada/prj-ext.adb177
-rw-r--r--gcc/ada/prj-ext.ads48
-rw-r--r--gcc/ada/prj-nmsc.adb235
-rw-r--r--gcc/ada/prj-nmsc.ads11
-rw-r--r--gcc/ada/prj-pars.adb20
-rw-r--r--gcc/ada/prj-pars.ads15
-rw-r--r--gcc/ada/prj-part.adb41
-rw-r--r--gcc/ada/prj-proc.adb43
-rw-r--r--gcc/ada/prj-proc.ads2
-rw-r--r--gcc/ada/prj-tree.adb5
-rw-r--r--gcc/ada/prj-tree.ads36
-rw-r--r--gcc/ada/prj.adb4
-rw-r--r--gcc/ada/prj.ads31
-rw-r--r--gcc/ada/s-oscons-tmplt.c24
-rw-r--r--gcc/ada/sem_ch6.adb2
-rw-r--r--gcc/ada/sinfo.adb16
-rw-r--r--gcc/ada/sinfo.ads16
-rw-r--r--gcc/ada/switch-c.adb8
-rw-r--r--gcc/ada/switch-m.adb8
-rw-r--r--gcc/ada/switch-m.ads8
-rw-r--r--gcc/builtins.c13
-rw-r--r--gcc/builtins.def6
-rw-r--r--gcc/c-common.c2
-rw-r--r--gcc/c-common.h4
-rw-r--r--gcc/c-decl.c26
-rw-r--r--gcc/c-parser.c201
-rw-r--r--gcc/c-pretty-print.c2
-rw-r--r--gcc/c-tree.h6
-rw-r--r--gcc/c-typeck.c10
-rw-r--r--gcc/calls.c6
-rw-r--r--gcc/cfg.c34
-rw-r--r--gcc/cfgbuild.c101
-rw-r--r--gcc/cfgexpand.c35
-rw-r--r--gcc/cfglayout.c20
-rw-r--r--gcc/cfgrtl.c94
-rw-r--r--gcc/cgraph.c7
-rw-r--r--gcc/cgraphunit.c96
-rw-r--r--gcc/combine-stack-adj.c206
-rw-r--r--gcc/combine.c19
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/config.gcc45
-rw-r--r--gcc/config.host9
-rw-r--r--gcc/config.in144
-rw-r--r--gcc/config/alpha/alpha.c5
-rw-r--r--gcc/config/alpha/alpha.md4
-rw-r--r--gcc/config/arm/arm.h1
-rw-r--r--gcc/config/arm/arm.md23
-rw-r--r--gcc/config/arm/vfp.md2
-rw-r--r--gcc/config/bfin/bfin-protos.h42
-rw-r--r--gcc/config/bfin/bfin.c491
-rw-r--r--gcc/config/bfin/bfin.h61
-rw-r--r--gcc/config/bfin/bfin.md172
-rw-r--r--gcc/config/bfin/predicates.md36
-rw-r--r--gcc/config/bfin/t-bfin-elf11
-rw-r--r--gcc/config/bfin/t-bfin-linux11
-rw-r--r--gcc/config/bfin/t-bfin-uclinux11
-rw-r--r--gcc/config/dfp-bit.c3
-rw-r--r--gcc/config/i386/i386.c16
-rw-r--r--gcc/config/i386/mingw-w64.h2
-rw-r--r--gcc/config/ia64/unwind-ia64.c2
-rw-r--r--gcc/config/m32c/m32c.c20
-rw-r--r--gcc/config/m32c/m32c.h12
-rw-r--r--gcc/config/mep/mep-protos.h1
-rw-r--r--gcc/config/mep/mep.c19
-rw-r--r--gcc/config/mep/mep.h5
-rw-r--r--gcc/config/mep/mep.md2
-rw-r--r--gcc/config/mips/mips-dsp.md9
-rw-r--r--gcc/config/mips/mips-protos.h10
-rw-r--r--gcc/config/mips/mips-ps-3d.md58
-rw-r--r--gcc/config/mips/mips.c859
-rw-r--r--gcc/config/mips/mips.h40
-rw-r--r--gcc/config/mips/mips.md301
-rw-r--r--gcc/config/mips/predicates.md8
-rw-r--r--gcc/config/moxie/constraints.md6
-rw-r--r--gcc/config/moxie/moxie.c31
-rw-r--r--gcc/config/moxie/moxie.h8
-rw-r--r--gcc/config/moxie/moxie.md21
-rw-r--r--gcc/config/pa/pa.c7
-rw-r--r--gcc/config/pa/predicates.md7
-rw-r--r--gcc/config/picochip/picochip.c10
-rw-r--r--gcc/config/rs6000/linux64.h4
-rw-r--r--gcc/config/rs6000/rs6000.c414
-rw-r--r--gcc/config/rs6000/rs6000.h20
-rw-r--r--gcc/config/rs6000/rs6000.md77
-rw-r--r--gcc/config/rs6000/spe.md18
-rw-r--r--gcc/config/rs6000/sysv4.h12
-rw-r--r--gcc/config/rs6000/xcoff.h2
-rw-r--r--gcc/config/s390/2084.md6
-rw-r--r--gcc/config/s390/2097.md29
-rw-r--r--gcc/config/s390/s390.c11
-rw-r--r--gcc/config/s390/s390.md22
-rw-r--r--gcc/config/sh/sh.c20
-rw-r--r--gcc/config/sol2-c.c4
-rw-r--r--gcc/config/t-slibgcc-elf-ver8
-rw-r--r--gcc/config/t-slibgcc-libgcc32
-rw-r--r--gcc/config/xtensa/unwind-dw2-xtensa.c2
-rwxr-xr-xgcc/configure587
-rw-r--r--gcc/configure.ac10
-rw-r--r--gcc/cp/ChangeLog81
-rw-r--r--gcc/cp/Make-lang.in6
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/cp-lang.c29
-rw-r--r--gcc/cp/cp-tree.h9
-rw-r--r--gcc/cp/decl.c60
-rw-r--r--gcc/cp/decl2.c23
-rw-r--r--gcc/cp/error.c6
-rw-r--r--gcc/cp/except.c27
-rw-r--r--gcc/cp/method.c2
-rw-r--r--gcc/cp/name-lookup.c16
-rw-r--r--gcc/cp/optimize.c163
-rw-r--r--gcc/cp/parser.c106
-rw-r--r--gcc/cp/pt.c5
-rw-r--r--gcc/cp/repo.c17
-rw-r--r--gcc/cp/semantics.c14
-rw-r--r--gcc/cse.c8
-rw-r--r--gcc/cselib.c44
-rw-r--r--gcc/dbgcnt.c2
-rw-r--r--gcc/dbxout.c8
-rw-r--r--gcc/dce.c23
-rw-r--r--gcc/doc/extend.texi103
-rw-r--r--gcc/doc/install.texi4
-rw-r--r--gcc/doc/invoke.texi39
-rw-r--r--gcc/doc/rtl.texi11
-rw-r--r--gcc/doc/tm.texi8
-rw-r--r--gcc/dse.c2
-rw-r--r--gcc/dwarf2out.c36
-rw-r--r--gcc/emit-rtl.c8
-rw-r--r--gcc/except.c3831
-rw-r--r--gcc/except.h324
-rw-r--r--gcc/expr.c70
-rw-r--r--gcc/expr.h6
-rw-r--r--gcc/final.c62
-rw-r--r--gcc/fold-const.c4
-rw-r--r--gcc/fortran/ChangeLog56
-rw-r--r--gcc/fortran/decl.c14
-rw-r--r--gcc/fortran/f95-lang.c7
-rw-r--r--gcc/fortran/primary.c6
-rw-r--r--gcc/fortran/resolve.c25
-rw-r--r--gcc/fortran/trans-decl.c22
-rw-r--r--gcc/fortran/trans-expr.c2
-rw-r--r--gcc/fortran/trans.c7
-rw-r--r--gcc/fortran/trans.h1
-rw-r--r--gcc/function.h11
-rw-r--r--gcc/gcc.c40
-rw-r--r--gcc/gcse.c13
-rw-r--r--gcc/genattrtab.c2
-rw-r--r--gcc/gengtype.c3
-rw-r--r--gcc/gimple-iterator.c27
-rw-r--r--gcc/gimple-low.c6
-rw-r--r--gcc/gimple-pretty-print.c242
-rw-r--r--gcc/gimple.c300
-rw-r--r--gcc/gimple.def100
-rw-r--r--gcc/gimple.h194
-rw-r--r--gcc/gimplify.c18
-rw-r--r--gcc/graphite-sese-to-poly.c55
-rw-r--r--gcc/gsstruct.def45
-rw-r--r--gcc/integrate.c9
-rw-r--r--gcc/ipa-inline.c55
-rw-r--r--gcc/ipa-pure-const.c4
-rw-r--r--gcc/ipa-type-escape.c3
-rw-r--r--gcc/ipa-utils.c4
-rw-r--r--gcc/ira-conflicts.c10
-rw-r--r--gcc/ira.c14
-rw-r--r--gcc/java/ChangeLog23
-rw-r--r--gcc/java/Make-lang.in2
-rw-r--r--gcc/java/builtins.c2
-rw-r--r--gcc/java/decl.c20
-rw-r--r--gcc/java/except.c86
-rw-r--r--gcc/java/java-tree.h3
-rw-r--r--gcc/java/lang.c20
-rw-r--r--gcc/jump.c40
-rw-r--r--gcc/langhooks-def.h5
-rw-r--r--gcc/langhooks.c7
-rw-r--r--gcc/langhooks.h6
-rw-r--r--gcc/libfuncs.h4
-rw-r--r--gcc/lower-subreg.c26
-rw-r--r--gcc/objc/ChangeLog20
-rw-r--r--gcc/objc/objc-act.c77
-rw-r--r--gcc/objc/objc-act.h2
-rw-r--r--gcc/objc/objc-lang.c7
-rw-r--r--gcc/omp-low.c19
-rw-r--r--gcc/optabs.c69
-rw-r--r--gcc/opts.c3
-rw-r--r--gcc/params.def10
-rw-r--r--gcc/passes.c3
-rw-r--r--gcc/print-rtl.c4
-rw-r--r--gcc/print-tree.c2
-rw-r--r--gcc/real.c65
-rw-r--r--gcc/recog.c312
-rw-r--r--gcc/reg-stack.c33
-rw-r--r--gcc/reginfo.c10
-rw-r--r--gcc/regrename.c15
-rw-r--r--gcc/reload1.c30
-rw-r--r--gcc/reorg.c10
-rw-r--r--gcc/rtl.def10
-rw-r--r--gcc/rtl.h35
-rw-r--r--gcc/sched-deps.c96
-rw-r--r--gcc/sched-int.h6
-rw-r--r--gcc/sched-rgn.c5
-rw-r--r--gcc/sese.c5
-rw-r--r--gcc/stmt.c129
-rw-r--r--gcc/system.h8
-rw-r--r--gcc/target-def.h6
-rw-r--r--gcc/target.h5
-rw-r--r--gcc/targhooks.c17
-rw-r--r--gcc/targhooks.h4
-rw-r--r--gcc/testsuite/ChangeLog497
-rwxr-xr-xgcc/testsuite/ada/acats/run_all.sh2
-rw-r--r--gcc/testsuite/ada/acats/run_test.exp13
-rw-r--r--gcc/testsuite/c-c++-common/asmgoto-1.c15
-rw-r--r--gcc/testsuite/c-c++-common/asmgoto-2.c20
-rw-r--r--gcc/testsuite/c-c++-common/asmgoto-3.c10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist24.C9
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf-eh-personality-1.C17
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/namespace-1.C4
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/pubnames-1.C15
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/template-func-params-6.C4
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/template-func-params-7.C16
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/template-params-6.C4
-rw-r--r--gcc/testsuite/g++.dg/eh/builtin1.C2
-rw-r--r--gcc/testsuite/g++.dg/eh/builtin2.C2
-rw-r--r--gcc/testsuite/g++.dg/eh/builtin3.C2
-rw-r--r--gcc/testsuite/g++.dg/template/crash91.C8
-rw-r--r--gcc/testsuite/g++.dg/torture/pr41144.C23
-rw-r--r--gcc/testsuite/g++.dg/torture/pr41257-2.C16
-rw-r--r--gcc/testsuite/g++.dg/torture/pr41257.C20
-rw-r--r--gcc/testsuite/g++.dg/torture/pr41273.C18
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C2
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr41275.C16
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20090907-1.c84
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20090917-1.c55
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/asmgoto-1.c30
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr41101.c19
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr41181.c10
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr41282.c20
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ipa-sra-1.c29
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ipa-sra-2.c41
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr41239.c67
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr41317.c28
-rw-r--r--gcc/testsuite/gcc.dg/c90-const-expr-10.c14
-rw-r--r--gcc/testsuite/gcc.dg/c90-const-expr-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/c90-const-expr-6.c8
-rw-r--r--gcc/testsuite/gcc.dg/c90-const-expr-9.c4
-rw-r--r--gcc/testsuite/gcc.dg/c99-const-expr-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/dfp/Wbad-function-cast-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/Wtraditional-conversion-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/call-by-value.c12
-rw-r--r--gcc/testsuite/gcc.dg/dfp/cast-bad.c1
-rw-r--r--gcc/testsuite/gcc.dg/dfp/cast.c17
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-eq-const.c6
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-eq-d128.c5
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-eq-d32.c5
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-eq-d64.c5
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-eq-dfp.c18
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-eq.h12
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-rel-const.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-rel-d128.c4
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-rel-d32.c4
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-rel-d64.c4
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-rel-dfp.c18
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-rel.h18
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-special-d128.c4
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-special-d32.c4
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-special-d64.c4
-rw-r--r--gcc/testsuite/gcc.dg/dfp/compare-special.h13
-rw-r--r--gcc/testsuite/gcc.dg/dfp/composite-type.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/constants-hex.c1
-rw-r--r--gcc/testsuite/gcc.dg/dfp/constants-pedantic.c4
-rw-r--r--gcc/testsuite/gcc.dg/dfp/constants-zero.c70
-rw-r--r--gcc/testsuite/gcc.dg/dfp/constants.c1
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp-10.c6
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp-11.c5
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp-12.c9
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp-13.c8
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp-14.c8
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp-2.c6
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp-3.c6
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp-4.c6
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp-5.c6
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp-6.c6
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp-7.c6
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp-8.c6
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp-9.c6
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp-fold.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-bfp.c20
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-complex.c17
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-dfp-fold-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-dfp-fold.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-dfp-round.c19
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-dfp.c20
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-int-fold.c14
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-int-max-fold.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-int-max.c16
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-int-saturate.c25
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert-int.c25
-rw-r--r--gcc/testsuite/gcc.dg/dfp/convert.h13
-rw-r--r--gcc/testsuite/gcc.dg/dfp/ctypes.c1
-rw-r--r--gcc/testsuite/gcc.dg/dfp/ddmode-ice.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/dec-eval-method-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/decfloat-constants.c20
-rw-r--r--gcc/testsuite/gcc.dg/dfp/dfp-dbg.h10
-rw-r--r--gcc/testsuite/gcc.dg/dfp/dfp.exp11
-rw-r--r--gcc/testsuite/gcc.dg/dfp/fe-binop.c5
-rw-r--r--gcc/testsuite/gcc.dg/dfp/fe-check.h12
-rw-r--r--gcc/testsuite/gcc.dg/dfp/fe-convert-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/dfp/fe-convert-2.c6
-rw-r--r--gcc/testsuite/gcc.dg/dfp/fe-convert-3.c6
-rw-r--r--gcc/testsuite/gcc.dg/dfp/float-constant-double.c1
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-array.c19
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-deref.c19
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-mixed.c19
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-pointer.c19
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-scalar.c19
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-struct.c19
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c5
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128.c5
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d32.c5
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d64.c5
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-vararg-alternate.h15
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-vararg-dfp.c19
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c19
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-vararg-mixed.c19
-rw-r--r--gcc/testsuite/gcc.dg/dfp/func-vararg-size0.c9
-rw-r--r--gcc/testsuite/gcc.dg/dfp/inf-1.c40
-rw-r--r--gcc/testsuite/gcc.dg/dfp/keywords-pedantic.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/keywords-reserved.c1
-rw-r--r--gcc/testsuite/gcc.dg/dfp/loop-index.c10
-rw-r--r--gcc/testsuite/gcc.dg/dfp/modes.c1
-rw-r--r--gcc/testsuite/gcc.dg/dfp/nan-1.c64
-rw-r--r--gcc/testsuite/gcc.dg/dfp/nan-2.c30
-rw-r--r--gcc/testsuite/gcc.dg/dfp/operator-arith-fold.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/operator-assignment.c19
-rw-r--r--gcc/testsuite/gcc.dg/dfp/operator-bitwise.c3
-rw-r--r--gcc/testsuite/gcc.dg/dfp/operator-comma.c16
-rw-r--r--gcc/testsuite/gcc.dg/dfp/operator-cond.c16
-rw-r--r--gcc/testsuite/gcc.dg/dfp/operator-logical.c6
-rw-r--r--gcc/testsuite/gcc.dg/dfp/operator-unary.c30
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr31344.c4
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr31385.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr33466.c1
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr35620.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr36800.c18
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr37435.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr39034.c41
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr39035.c28
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr39902.c17
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr39986.c1
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr41049.c562
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-4.c1
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-7.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/dfp/signbit-1.c16
-rw-r--r--gcc/testsuite/gcc.dg/dfp/signbit-2.c18
-rw-r--r--gcc/testsuite/gcc.dg/dfp/struct-layout-1.c24
-rw-r--r--gcc/testsuite/gcc.dg/dfp/typespec.c1
-rw-r--r--gcc/testsuite/gcc.dg/dfp/union-init.c18
-rw-r--r--gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad.c1
-rw-r--r--gcc/testsuite/gcc.dg/dfp/usual-arith-conv-const.c1
-rw-r--r--gcc/testsuite/gcc.dg/dfp/usual-arith-conv.c16
-rw-r--r--gcc/testsuite/gcc.dg/dfp/wtr-conversion-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/guality/guality.exp26
-rw-r--r--gcc/testsuite/gcc.dg/guality/guality.h39
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c41
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-2.c52
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-3.c39
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-4.c68
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-5.c20
-rw-r--r--gcc/testsuite/gcc.dg/large-size-array-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/large-size-array-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr41232.c14
-rw-r--r--gcc/testsuite/gcc.dg/pr41241.c34
-rw-r--r--gcc/testsuite/gcc.dg/profile-dir-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/profile-dir-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/profile-dir-3.c1
-rw-r--r--gcc/testsuite/gcc.dg/struct/wo_prof_escape_arg_to_local.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr39074.c4
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr41261.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/asmgoto-1.c95
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr33920.c7
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/prefetch-7.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-7.c15
-rw-r--r--gcc/testsuite/gcc.dg/vect/O1-pr33854.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr33833.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr33846.c4
-rw-r--r--gcc/testsuite/gcc.misc-tests/i386-prefetch.exp7
-rw-r--r--gcc/testsuite/gcc.target/arm/ctz.c12
-rw-r--r--gcc/testsuite/gcc.target/bfin/20090914-1.c39
-rw-r--r--gcc/testsuite/gcc.target/bfin/20090914-2.c31
-rw-r--r--gcc/testsuite/gcc.target/bfin/20090914-3.c10
-rw-r--r--gcc/testsuite/gcc.target/bfin/mcpu-bf542m.c41
-rw-r--r--gcc/testsuite/gcc.target/bfin/mcpu-bf544m.c41
-rw-r--r--gcc/testsuite/gcc.target/bfin/mcpu-bf547m.c41
-rw-r--r--gcc/testsuite/gcc.target/bfin/mcpu-bf548m.c41
-rw-r--r--gcc/testsuite/gcc.target/bfin/mcpu-bf549m.c41
-rw-r--r--gcc/testsuite/gcc.target/bfin/saveall.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/387-1.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/387-5.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/cmov7.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-1.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-8.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/gcc-have-sync-compare-and-swap-1.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/gcc-have-sync-compare-and-swap-2.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/isa-6.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/lea.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/pentium4-not-mull.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-5.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/ssefn-1.c1
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-10.c13
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-11.c17
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-12.c13
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-13.c17
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-14.c23
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-15.c23
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-2.c13
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-3.c13
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-4.c12
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-5.c14
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-6.c12
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-7.c14
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-8.c13
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-9.c18
-rw-r--r--gcc/testsuite/gcc.target/mips/branch-helper.h37
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bswap64-4.c9
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr41175.c461
-rw-r--r--gcc/testsuite/gcc.target/sh/20080410-1.c2
-rw-r--r--gcc/testsuite/gcc.target/sh/struct-arg-dw2.c26
-rw-r--r--gcc/testsuite/gfortran.dg/allocate_alloc_opt_1.f904
-rw-r--r--gcc/testsuite/gfortran.dg/allocate_stat_2.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/cr_lf.f9036
-rw-r--r--gcc/testsuite/gfortran.dg/deallocate_alloc_opt_1.f904
-rw-r--r--gcc/testsuite/gfortran.dg/default_format_denormal_1.f904
-rw-r--r--gcc/testsuite/gfortran.dg/default_format_denormal_2.f902
-rw-r--r--gcc/testsuite/gfortran.dg/generic_14.f908
-rw-r--r--gcc/testsuite/gfortran.dg/module_procedure_1.f9053
-rw-r--r--gcc/testsuite/gfortran.dg/module_procedure_2.f908
-rw-r--r--gcc/testsuite/gfortran.dg/namelist_59.f9026
-rw-r--r--gcc/testsuite/gfortran.dg/pr41212.f9034
-rw-r--r--gcc/testsuite/gfortran.dg/pr41225.f9020
-rw-r--r--gcc/testsuite/gfortran.dg/pr41229.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/pr41347.f9032
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_comp_21.f9028
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_proc_12.f9012
-rw-r--r--gcc/testsuite/gnat.dg/alignment9.adb30
-rw-r--r--gcc/testsuite/gnat.dg/array8.adb34
-rw-r--r--gcc/testsuite/gnat.dg/discr20.adb10
-rw-r--r--gcc/testsuite/gnat.dg/discr20.ads31
-rw-r--r--gcc/timevar.def1
-rw-r--r--gcc/toplev.c40
-rw-r--r--gcc/tree-cfg.c555
-rw-r--r--gcc/tree-cfgcleanup.c13
-rw-r--r--gcc/tree-dfa.c1
-rw-r--r--gcc/tree-eh.c2632
-rw-r--r--gcc/tree-flow-inline.h10
-rw-r--r--gcc/tree-flow.h40
-rw-r--r--gcc/tree-inline.c213
-rw-r--r--gcc/tree-inline.h10
-rw-r--r--gcc/tree-nested.c210
-rw-r--r--gcc/tree-optimize.c3
-rw-r--r--gcc/tree-pass.h3
-rw-r--r--gcc/tree-pretty-print.c13
-rw-r--r--gcc/tree-sra.c1565
-rw-r--r--gcc/tree-ssa-alias.c18
-rw-r--r--gcc/tree-ssa-ccp.c112
-rw-r--r--gcc/tree-ssa-dce.c22
-rw-r--r--gcc/tree-ssa-loop-ivopts.c67
-rw-r--r--gcc/tree-ssa-operands.c6
-rw-r--r--gcc/tree-ssa-phiopt.c2
-rw-r--r--gcc/tree-ssa-pre.c92
-rw-r--r--gcc/tree-ssa-propagate.c4
-rw-r--r--gcc/tree-ssa-reassoc.c4
-rw-r--r--gcc/tree-ssa-sccvn.c9
-rw-r--r--gcc/tree-ssa-sink.c2
-rw-r--r--gcc/tree-ssa-structalias.c8
-rw-r--r--gcc/tree-ssa.c79
-rw-r--r--gcc/tree-switch-conversion.c12
-rw-r--r--gcc/tree-vect-data-refs.c40
-rw-r--r--gcc/tree-vect-stmts.c3
-rw-r--r--gcc/tree.c354
-rw-r--r--gcc/tree.def15
-rw-r--r--gcc/tree.h72
-rw-r--r--gcc/unwind-dw2.c2
-rw-r--r--gcc/value-prof.c234
-rw-r--r--gcc/var-tracking.c75
-rw-r--r--gcc/varasm.c19
-rw-r--r--gcc/vecprim.h5
-rw-r--r--libcpp/ChangeLog10
-rwxr-xr-xlibcpp/configure1
-rw-r--r--libcpp/configure.ac1
-rw-r--r--libcpp/directives.c3
-rw-r--r--libcpp/po/ChangeLog4
-rw-r--r--libcpp/po/id.po10
-rw-r--r--libdecnumber/ChangeLog8
-rw-r--r--libffi/ChangeLog20
-rw-r--r--libffi/src/java_raw_api.c3
-rw-r--r--libffi/src/mips/ffi.c154
-rw-r--r--libffi/src/mips/ffitarget.h19
-rw-r--r--libffi/src/mips/n32.S57
-rw-r--r--libgfortran/ChangeLog39
-rw-r--r--libgfortran/Makefile.am1
-rw-r--r--libgfortran/Makefile.in4
-rw-r--r--libgfortran/intrinsics/getlog.c3
-rw-r--r--libgfortran/io/list_read.c16
-rw-r--r--libgfortran/io/transfer.c25
-rw-r--r--libgfortran/io/write.c2
-rw-r--r--libgomp/ChangeLog9
-rw-r--r--libgomp/Makefile.am1
-rw-r--r--libgomp/Makefile.in4
-rw-r--r--libgomp/testsuite/libgomp.graphite/bounds.c13
-rw-r--r--libiberty/ChangeLog16
-rw-r--r--libiberty/config.h-vms3
-rw-r--r--libiberty/config.in9
-rwxr-xr-xlibiberty/configure95
-rw-r--r--libiberty/configure.ac6
-rw-r--r--libiberty/hashtab.c3
-rw-r--r--libjava/ChangeLog18
-rw-r--r--libjava/Makefile.am2
-rw-r--r--libjava/Makefile.in8
-rwxr-xr-xlibjava/configure12
-rwxr-xr-xlibjava/gnu/java/security/jce/prng/natVMSecureRandomWin32.cc2
-rw-r--r--libjava/libgcj_bc.c11
-rw-r--r--libstdc++-v3/ChangeLog230
-rw-r--r--libstdc++-v3/config/cpu/sh/atomicity.h2
-rwxr-xr-xlibstdc++-v3/configure47
-rw-r--r--libstdc++-v3/configure.ac5
-rw-r--r--libstdc++-v3/include/bits/basic_string.tcc4
-rw-r--r--libstdc++-v3/include/bits/forward_list.h19
-rw-r--r--libstdc++-v3/include/bits/forward_list.tcc208
-rw-r--r--libstdc++-v3/include/bits/istream.tcc40
-rw-r--r--libstdc++-v3/include/bits/ostream.tcc8
-rw-r--r--libstdc++-v3/include/bits/ostream_insert.h2
-rw-r--r--libstdc++-v3/include/bits/stl_algobase.h10
-rw-r--r--libstdc++-v3/include/parallel/algo.h2945
-rw-r--r--libstdc++-v3/include/parallel/algobase.h318
-rw-r--r--libstdc++-v3/include/parallel/algorithmfwd.h445
-rw-r--r--libstdc++-v3/include/parallel/balanced_quicksort.h435
-rw-r--r--libstdc++-v3/include/parallel/base.h334
-rw-r--r--libstdc++-v3/include/parallel/checkers.h181
-rw-r--r--libstdc++-v3/include/parallel/compatibility.h300
-rw-r--r--libstdc++-v3/include/parallel/compiletime_settings.h14
-rw-r--r--libstdc++-v3/include/parallel/equally_split.h74
-rw-r--r--libstdc++-v3/include/parallel/features.h6
-rw-r--r--libstdc++-v3/include/parallel/find.h367
-rw-r--r--libstdc++-v3/include/parallel/find_selectors.h196
-rw-r--r--libstdc++-v3/include/parallel/for_each.h95
-rw-r--r--libstdc++-v3/include/parallel/for_each_selectors.h342
-rw-r--r--libstdc++-v3/include/parallel/iterator.h164
-rw-r--r--libstdc++-v3/include/parallel/list_partition.h206
-rw-r--r--libstdc++-v3/include/parallel/losertree.h884
-rw-r--r--libstdc++-v3/include/parallel/merge.h348
-rw-r--r--libstdc++-v3/include/parallel/multiseq_selection.h927
-rw-r--r--libstdc++-v3/include/parallel/multiway_merge.h2219
-rw-r--r--libstdc++-v3/include/parallel/multiway_mergesort.h488
-rw-r--r--libstdc++-v3/include/parallel/numeric675
-rw-r--r--libstdc++-v3/include/parallel/numericfwd.h90
-rw-r--r--libstdc++-v3/include/parallel/omp_loop.h83
-rw-r--r--libstdc++-v3/include/parallel/omp_loop_static.h82
-rw-r--r--libstdc++-v3/include/parallel/par_loop.h107
-rw-r--r--libstdc++-v3/include/parallel/partial_sum.h213
-rw-r--r--libstdc++-v3/include/parallel/partition.h407
-rw-r--r--libstdc++-v3/include/parallel/queue.h122
-rw-r--r--libstdc++-v3/include/parallel/quicksort.h175
-rw-r--r--libstdc++-v3/include/parallel/random_number.h88
-rw-r--r--libstdc++-v3/include/parallel/random_shuffle.h532
-rw-r--r--libstdc++-v3/include/parallel/search.h146
-rw-r--r--libstdc++-v3/include/parallel/set_operations.h564
-rw-r--r--libstdc++-v3/include/parallel/settings.h202
-rw-r--r--libstdc++-v3/include/parallel/sort.h168
-rw-r--r--libstdc++-v3/include/parallel/tags.h54
-rw-r--r--libstdc++-v3/include/parallel/types.h23
-rw-r--r--libstdc++-v3/include/parallel/unique_copy.h168
-rw-r--r--libstdc++-v3/include/parallel/workstealing.h249
-rw-r--r--libstdc++-v3/src/Makefile.am2
-rw-r--r--libstdc++-v3/src/Makefile.in4
-rw-r--r--libstdc++-v3/src/compatibility.cc4
-rw-r--r--libstdc++-v3/src/ios_init.cc4
-rw-r--r--libstdc++-v3/src/istream.cc18
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/objects/char/41037.cc35
-rw-r--r--libstdc++-v3/testsuite/27_io/objects/wchar_t/41037.cc35
-rw-r--r--libstdc++-v3/testsuite/30_threads/thread/native_handle/typesizes.cc4
-rw-r--r--libtool.m412
648 files changed, 27746 insertions, 17311 deletions
diff --git a/ChangeLog b/ChangeLog
index 6c297800263..7aaa1f69009 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+2009-09-15 Jie Zhang <jie.zhang@analog.com>
+
+ * configure.ac: Disable java and boehm-gc for bfin-*-*.
+ * configure: Regenerate.
+
+2009-09-12 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * MAINTAINERS (Write After Approval): Update my e-mail address,
+ and move from from here...
+ (Waiting for paperwork): To here.
+
+2009-09-09 Joseph Myers <joseph@codesourcery.com>
+
+ * MAINTAINERS (Reviewers): Add self as driver reviewer.
+
+2009-09-08 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * configure.ac: Do not use $extrasub for replacing @if/@endif
+ parts in Makefile; instead, use additional arguments to
+ AC_CONFIG_COMMANDS to do the replacement manually, with several
+ sed invocations, to avoid HP-UX sed command limits.
+ * configure: Regenerate.
+
+2009-09-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * libtool.m4 (output_verbose_link_cmd): Require leading blank, and
+ blank before -L.
+
+2009-09-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure.ac (with-build-config): Document. Handle without.
+ Handle missing argument.
+ * configure: Rebuilt.
+
2009-09-03 Alexandre Oliva <aoliva@redhat.com>
* configure.ac (--with-build-config): New. Set BUILD_CONFIG.
diff --git a/MAINTAINERS b/MAINTAINERS
index 3fc6f0356e6..854eabbedf6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -245,6 +245,7 @@ outside of the parts of the compiler they maintain.
dataflow Paolo Bonzini bonzini@gnu.org
dataflow Seongbae Park seongbae.park@gmail.com
dataflow Kenneth Zadeck zadeck@naturalbridge.com
+driver Joseph Myers jsm@polyomino.org.uk
Fortran Janne Blomqvist jb@gcc.gnu.org
Fortran Tobias Burnus burnus@net-b.de
Fortran Jerry DeLisle jvdelisle@gcc.gnu.org
@@ -337,6 +338,7 @@ Jon Grimm jgrimm2@us.ibm.com
Laurent Guerby laurent@guerby.net
Xuepeng Guo xuepeng.guo@intel.com
Wei Guozhi carrot@google.com
+Daniel Gutson dgutson@codesourcery.com
Mostafa Hagog hagog@gcc.gnu.org
Olivier Hainque hainque@act-europe.fr
Stuart Hastings stuart@apple.com
@@ -425,7 +427,6 @@ Dwarakanath Rajagopal dwarak.rajagopal@amd.com
Ramana Radhakrishnan ramana.r@gmail.com
Rolf Rasmussen rolfwr@gcc.gnu.org
Volker Reichelt v.reichelt@netcologne.de
-Joern Rennecke joern.rennecke@arc.com
Bernhard Reutner-Fischer rep.dot.nop@gmail.com
Tom Rix trix@redhat.com
Craig Rodrigues rodrigc@gcc.gnu.org
@@ -477,6 +478,10 @@ Jon Ziegler jonz@apple.com
Roman Zippel zippel@linux-m68k.org
Josef Zlomek josef.zlomek@email.cz
+Waiting for paperwork:
+
+Joern Rennecke joern.rennecke@embecosm.com
+
Bug database only accounts
James Dennett jdennett@acm.org
diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog
index 8bd2012ba34..9f05a757d69 100644
--- a/boehm-gc/ChangeLog
+++ b/boehm-gc/ChangeLog
@@ -1,3 +1,14 @@
+2009-09-11 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.am (libgcjgc_la_LINK, gctest_LINK): New.
+ (gctest_LDADD): Depend on libgcjgc.la instead of ./libgcjgc.la,
+ so that library dependency resolution works with portable make.
+ * Makefile.in: Regenerate.
+
+2009-09-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure: Rebuilt with modified libtool.m4.
+
2009-09-03 Loren J. Rittle <ljrittle@acm.org>
* dyn_load.c (HAVE_DL_ITERATE_PHDR): Break definition from use.
diff --git a/boehm-gc/Makefile.am b/boehm-gc/Makefile.am
index 843891110c0..b074ac6df48 100644
--- a/boehm-gc/Makefile.am
+++ b/boehm-gc/Makefile.am
@@ -40,6 +40,7 @@ extra_ldflags_libgc = @extra_ldflags_libgc@
libgcjgc_la_LIBADD = @addobjs@ $(THREADLIBS) $(UNWINDLIBS)
libgcjgc_la_DEPENDENCIES = @addobjs@
libgcjgc_la_LDFLAGS = $(extra_ldflags_libgc) -version-info 1:2:0 -rpath $(toolexeclibdir)
+libgcjgc_la_LINK = $(LINK) $(libgcjgc_la_LDFLAGS)
libgcjgc_convenience_la_LIBADD = @addobjs@
libgcjgc_convenience_la_DEPENDENCIES = @addobjs@
@@ -49,8 +50,9 @@ AM_CFLAGS = @GC_CFLAGS@
check_PROGRAMS = gctest
gctest_SOURCES = tests/test.c
-gctest_LDADD = ./libgcjgc.la $(THREADLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS)
+gctest_LDADD = libgcjgc.la $(THREADLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS)
gctest_LDFLAGS = -shared-libgcc
+gctest_LINK = $(LINK) $(gctest_LDFLAGS)
TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc
TESTS = gctest
diff --git a/boehm-gc/Makefile.in b/boehm-gc/Makefile.in
index 70110d3e194..5b1cfe748a4 100644
--- a/boehm-gc/Makefile.in
+++ b/boehm-gc/Makefile.in
@@ -70,9 +70,6 @@ am_libgcjgc_la_OBJECTS = allchblk.lo alloc.lo blacklst.lo checksums.lo \
backgraph.lo win32_threads.lo pthread_support.lo \
pthread_stop_world.lo darwin_stop_world.lo $(am__objects_1)
libgcjgc_la_OBJECTS = $(am_libgcjgc_la_OBJECTS)
-libgcjgc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libgcjgc_la_LDFLAGS) $(LDFLAGS) -o $@
am__objects_2 = allchblk.lo alloc.lo blacklst.lo checksums.lo \
dbg_mlc.lo dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo \
headers.lo malloc.lo mallocx.lo mark.lo mark_rts.lo misc.lo \
@@ -86,11 +83,8 @@ libgcjgc_convenience_la_OBJECTS = \
am__dirstamp = $(am__leading_dot)dirstamp
am_gctest_OBJECTS = tests/test.$(OBJEXT)
gctest_OBJECTS = $(am_gctest_OBJECTS)
-gctest_DEPENDENCIES = ./libgcjgc.la $(am__DEPENDENCIES_1) \
+gctest_DEPENDENCIES = libgcjgc.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
-gctest_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(gctest_LDFLAGS) \
- $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
depcomp =
am__depfiles_maybe =
@@ -291,13 +285,15 @@ sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s
libgcjgc_la_LIBADD = @addobjs@ $(THREADLIBS) $(UNWINDLIBS)
libgcjgc_la_DEPENDENCIES = @addobjs@
libgcjgc_la_LDFLAGS = $(extra_ldflags_libgc) -version-info 1:2:0 -rpath $(toolexeclibdir)
+libgcjgc_la_LINK = $(LINK) $(libgcjgc_la_LDFLAGS)
libgcjgc_convenience_la_LIBADD = @addobjs@
libgcjgc_convenience_la_DEPENDENCIES = @addobjs@
AM_CXXFLAGS = @GC_CFLAGS@
AM_CFLAGS = @GC_CFLAGS@
gctest_SOURCES = tests/test.c
-gctest_LDADD = ./libgcjgc.la $(THREADLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS)
+gctest_LDADD = libgcjgc.la $(THREADLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS)
gctest_LDFLAGS = -shared-libgcc
+gctest_LINK = $(LINK) $(gctest_LDFLAGS)
TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc
LTCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \
$(CC) $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) \
diff --git a/boehm-gc/configure b/boehm-gc/configure
index 1c615a6a732..101f2b468ab 100755
--- a/boehm-gc/configure
+++ b/boehm-gc/configure
@@ -12407,7 +12407,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
GXX=no
@@ -12744,7 +12744,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "^ .* -L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
;;
*)
if test "$GXX" = yes; then
@@ -12809,7 +12809,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "^ .* -L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
;;
*)
if test "$GXX" = yes; then
@@ -13153,7 +13153,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
# FIXME: insert proper C++ library support
@@ -13237,7 +13237,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
# g++ 2.7 appears to require `-G' NOT `-shared' on this
# platform.
@@ -13248,7 +13248,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
fi
hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
diff --git a/config/ChangeLog b/config/ChangeLog
index ba8fd0011e6..ceea52ed782 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,16 @@
+2009-09-09 Paolo Bonzini <bonzini@gnu.org>
+
+ * stdint.m4 (GCC_HEADER_STDINT): Revert changes to this macro in
+ the previous two patches.
+
+2009-09-09 Paolo Bonzini <bonzini@gnu.org>
+
+ * stdint.m4: Store temporary file in $tmp/_GCC_STDINT_H.
+
+2009-09-08 Paolo Bonzini <bonzini@gnu.org>
+
+ * stdint.m4: Rewrite by using autoconf 2.64 features.
+
2009-09-03 Alexandre Oliva <aoliva@redhat.com>
* bootstrap-debug-big.mk (STAGE2_CFLAGS): Drop -gtoggle.
diff --git a/config/stdint.m4 b/config/stdint.m4
index 025ffad9ea2..b26b4fc266d 100644
--- a/config/stdint.m4
+++ b/config/stdint.m4
@@ -1,3 +1,17 @@
+AC_DEFUN([GCC_STDINT_TYPES],
+[AC_REQUIRE([AC_TYPE_INT8_T])
+AC_REQUIRE([AC_TYPE_INT16_T])
+AC_REQUIRE([AC_TYPE_INT32_T])
+AC_REQUIRE([AC_TYPE_INT64_T])
+AC_REQUIRE([AC_TYPE_INTMAX_T])
+AC_REQUIRE([AC_TYPE_INTPTR_T])
+AC_REQUIRE([AC_TYPE_UINT8_T])
+AC_REQUIRE([AC_TYPE_UINT16_T])
+AC_REQUIRE([AC_TYPE_UINT32_T])
+AC_REQUIRE([AC_TYPE_UINT64_T])
+AC_REQUIRE([AC_TYPE_UINTMAX_T])
+AC_REQUIRE([AC_TYPE_UINTPTR_T])])
+
dnl @synopsis GCC_HEADER_STDINT [( HEADER-TO-GENERATE [, HEADERS-TO-CHECK])]
dnl
dnl the "ISO C9X: 7.18 Integer types <stdint.h>" section requires the
diff --git a/configure b/configure
index 6152f37fa8d..2e71341d2f5 100755
--- a/configure
+++ b/configure
@@ -769,6 +769,7 @@ enable_objc_gc
with_build_sysroot
with_debug_prefix_map
enable_bootstrap
+with_build_config
enable_serial_configure
with_build_time_tools
enable_maintainer_mode
@@ -1498,6 +1499,8 @@ Optional Packages:
use sysroot as the system root during the build
--with-debug-prefix-map='A=B C=D ...'
map A to B, C to D ... in debug information
+--with-build-config='NAME NAME2...'
+ Use config/NAME.mk build configuration
--with-build-time-tools=PATH
use given path to find target tools during the build
@@ -3117,7 +3120,8 @@ case "${target}" in
noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj} target-libssp"
;;
bfin-*-*)
- noconfigdirs="$noconfigdirs gdb"
+ unsupported_languages="$unsupported_languages java"
+ noconfigdirs="$noconfigdirs target-boehm-gc gdb"
if test x${is_cross_compiler} != xno ; then
target_configdirs="${target_configdirs} target-bsp target-cygmon"
fi
@@ -6513,12 +6517,13 @@ INSTALL_GDB_TK=`echo ${GDB_TK} | sed s/-all-/-install-/g`
# configuration, so that the top-level Makefile reconfigures them,
# like we used to do when configure itself was recursive.
-# Loop over modules. $extrasub must be used with care, limiting as
-# much as possible the usage of range addresses. That's because autoconf
-# splits the sed script to overcome limits in the number of commands,
-# and relying on carefully-timed sed passes may turn out to be very hard
-# to maintain later. In this particular case, you just have to be careful
-# not to nest @if/@endif pairs, because configure will not warn you at all.
+# Loop over modules. We used to use the "$extrasub" feature from Autoconf
+# but now we're fixing up the Makefile ourselves with the additional
+# commands passed to AC_CONFIG_FILES. Use separate variables
+# extrasub-{build,host,target} not because there is any reason to split
+# the substitutions up that way, but only to remain below the limit of
+# 99 commands in a script, for HP-UX sed.
+# Do not nest @if/@endif pairs, because configure will not warn you at all.
# Check whether --enable-bootstrap was given.
if test "${enable_bootstrap+set}" = set; then :
@@ -6580,6 +6585,17 @@ esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for default BUILD_CONFIG" >&5
$as_echo_n "checking for default BUILD_CONFIG... " >&6; }
+
+
+# Check whether --with-build-config was given.
+if test "${with_build_config+set}" = set; then :
+ withval=$with_build_config; case $with_build_config in
+ yes) with_build_config= ;;
+ no) with_build_config= BUILD_CONFIG= ;;
+ esac
+fi
+
+
if test "x${with_build_config}" != x; then
BUILD_CONFIG=$with_build_config
else
@@ -6603,18 +6619,20 @@ fi
$as_echo "$BUILD_CONFIG" >&6; }
+extrasub_build=
for module in ${build_configdirs} ; do
if test -z "${no_recursion}" \
&& test -f ${build_subdir}/${module}/Makefile; then
echo 1>&2 "*** removing ${build_subdir}/${module}/Makefile to force reconfigure"
rm -f ${build_subdir}/${module}/Makefile
fi
- extrasub="$extrasub
+ extrasub_build="$extrasub_build
/^@if build-$module\$/d
/^@endif build-$module\$/d
/^@if build-$module-$bootstrap_suffix\$/d
/^@endif build-$module-$bootstrap_suffix\$/d"
done
+extrasub_host=
for module in ${configdirs} ; do
if test -z "${no_recursion}"; then
for file in stage*-${module}/Makefile prev-${module}/Makefile ${module}/Makefile; do
@@ -6624,12 +6642,13 @@ for module in ${configdirs} ; do
fi
done
fi
- extrasub="$extrasub
+ extrasub_host="$extrasub_host
/^@if $module\$/d
/^@endif $module\$/d
/^@if $module-$bootstrap_suffix\$/d
/^@endif $module-$bootstrap_suffix\$/d"
done
+extrasub_target=
for module in ${target_configdirs} ; do
if test -z "${no_recursion}" \
&& test -f ${target_subdir}/${module}/Makefile; then
@@ -6643,14 +6662,15 @@ for module in ${target_configdirs} ; do
*) target_bootstrap_suffix=no-bootstrap ;;
esac
- extrasub="$extrasub
+ extrasub_target="$extrasub_target
/^@if target-$module\$/d
/^@endif target-$module\$/d
/^@if target-$module-$target_bootstrap_suffix\$/d
/^@endif target-$module-$target_bootstrap_suffix\$/d"
done
-extrasub="$extrasub
+# Do the final fixup along with target modules.
+extrasub_target="$extrasub_target
/^@if /,/^@endif /d"
# Create the serialization dependencies. This uses a temporary file.
@@ -14019,6 +14039,13 @@ _ASBOX
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+extrasub_build="$extrasub_build"
+ extrasub_host="$extrasub_host"
+ extrasub_target="$extrasub_target"
+
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
@@ -14474,6 +14501,14 @@ which seems to be undefined. Please make sure it is defined." >&2;}
esac
+
+ case $ac_file$ac_mode in
+ "Makefile":F) sed "$extrasub_build" Makefile |
+ sed "$extrasub_host" |
+ sed "$extrasub_target" > mf$$
+ mv -f mf$$ Makefile ;;
+
+ esac
done # for ac_tag
diff --git a/configure.ac b/configure.ac
index 1616fefd2bb..57fdd09ee2f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -603,7 +603,8 @@ case "${target}" in
noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj} target-libssp"
;;
bfin-*-*)
- noconfigdirs="$noconfigdirs gdb"
+ unsupported_languages="$unsupported_languages java"
+ noconfigdirs="$noconfigdirs target-boehm-gc gdb"
if test x${is_cross_compiler} != xno ; then
target_configdirs="${target_configdirs} target-bsp target-cygmon"
fi
@@ -2407,12 +2408,13 @@ INSTALL_GDB_TK=`echo ${GDB_TK} | sed s/-all-/-install-/g`
# configuration, so that the top-level Makefile reconfigures them,
# like we used to do when configure itself was recursive.
-# Loop over modules. $extrasub must be used with care, limiting as
-# much as possible the usage of range addresses. That's because autoconf
-# splits the sed script to overcome limits in the number of commands,
-# and relying on carefully-timed sed passes may turn out to be very hard
-# to maintain later. In this particular case, you just have to be careful
-# not to nest @if/@endif pairs, because configure will not warn you at all.
+# Loop over modules. We used to use the "$extrasub" feature from Autoconf
+# but now we're fixing up the Makefile ourselves with the additional
+# commands passed to AC_CONFIG_FILES. Use separate variables
+# extrasub-{build,host,target} not because there is any reason to split
+# the substitutions up that way, but only to remain below the limit of
+# 99 commands in a script, for HP-UX sed.
+# Do not nest @if/@endif pairs, because configure will not warn you at all.
AC_ARG_ENABLE([bootstrap],
[ --enable-bootstrap enable bootstrapping @<:@yes if native build@:>@],,
@@ -2468,6 +2470,15 @@ case $enable_bootstrap in
esac
AC_MSG_CHECKING(for default BUILD_CONFIG)
+
+AC_ARG_WITH([build-config],
+ [--with-build-config='NAME NAME2...'
+ Use config/NAME.mk build configuration],
+ [case $with_build_config in
+ yes) with_build_config= ;;
+ no) with_build_config= BUILD_CONFIG= ;;
+ esac])
+
if test "x${with_build_config}" != x; then
BUILD_CONFIG=$with_build_config
else
@@ -2490,18 +2501,20 @@ fi
AC_MSG_RESULT($BUILD_CONFIG)
AC_SUBST(BUILD_CONFIG)
+extrasub_build=
for module in ${build_configdirs} ; do
if test -z "${no_recursion}" \
&& test -f ${build_subdir}/${module}/Makefile; then
echo 1>&2 "*** removing ${build_subdir}/${module}/Makefile to force reconfigure"
rm -f ${build_subdir}/${module}/Makefile
fi
- extrasub="$extrasub
+ extrasub_build="$extrasub_build
/^@if build-$module\$/d
/^@endif build-$module\$/d
/^@if build-$module-$bootstrap_suffix\$/d
/^@endif build-$module-$bootstrap_suffix\$/d"
done
+extrasub_host=
for module in ${configdirs} ; do
if test -z "${no_recursion}"; then
for file in stage*-${module}/Makefile prev-${module}/Makefile ${module}/Makefile; do
@@ -2511,12 +2524,13 @@ for module in ${configdirs} ; do
fi
done
fi
- extrasub="$extrasub
+ extrasub_host="$extrasub_host
/^@if $module\$/d
/^@endif $module\$/d
/^@if $module-$bootstrap_suffix\$/d
/^@endif $module-$bootstrap_suffix\$/d"
done
+extrasub_target=
for module in ${target_configdirs} ; do
if test -z "${no_recursion}" \
&& test -f ${target_subdir}/${module}/Makefile; then
@@ -2530,14 +2544,15 @@ for module in ${target_configdirs} ; do
*) target_bootstrap_suffix=no-bootstrap ;;
esac
- extrasub="$extrasub
+ extrasub_target="$extrasub_target
/^@if target-$module\$/d
/^@endif target-$module\$/d
/^@if target-$module-$target_bootstrap_suffix\$/d
/^@endif target-$module-$target_bootstrap_suffix\$/d"
done
-extrasub="$extrasub
+# Do the final fixup along with target modules.
+extrasub_target="$extrasub_target
/^@if /,/^@endif /d"
# Create the serialization dependencies. This uses a temporary file.
@@ -3155,4 +3170,12 @@ case "$target" in
esac
AC_SUBST(compare_exclusions)
-AC_OUTPUT(Makefile)
+AC_CONFIG_FILES([Makefile],
+ [sed "$extrasub_build" Makefile |
+ sed "$extrasub_host" |
+ sed "$extrasub_target" > mf$$
+ mv -f mf$$ Makefile],
+ [extrasub_build="$extrasub_build"
+ extrasub_host="$extrasub_host"
+ extrasub_target="$extrasub_target"])
+AC_OUTPUT
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index 77d71700464..b4627d293b6 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,13 @@
+2009-09-10 Iain Sandoe <iain.sandoe@sandoe-acoustics.co.uk>
+
+ PR bootstrap/41245
+ * compare-debug: Handle stripping of dwarf debug sections from darwin
+ mach-o objects.
+
+2009-09-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * compare-debug: Grep for blank before dash to avoid grep -e.
+
2009-09-01 Alexandre Oliva <aoliva@redhat.com>
* compare-debug: Look for .gkd files and compare them.
diff --git a/contrib/compare-debug b/contrib/compare-debug
index c2e1335366c..98c80f93e98 100755
--- a/contrib/compare-debug
+++ b/contrib/compare-debug
@@ -57,11 +57,19 @@ done
trap 'rm -f "$1.$suf1" "$2.$suf2"' 0 1 2 15
-cp "$1" "$1.$suf1"
-strip "$1.$suf1"
+case `uname -s` in
+Darwin)
+ ld -S -x -r -no_uuid "$1" -o "$1.$suf1"
+ ld -S -x -r -no_uuid "$2" -o "$2.$suf2"
+ ;;
+*)
+ cp "$1" "$1.$suf1"
+ strip "$1.$suf1"
-cp "$2" "$2.$suf2"
-strip "$2.$suf2"
+ cp "$2" "$2.$suf2"
+ strip "$2.$suf2"
+ ;;
+esac
if cmp "$1.$suf1" "$2.$suf2"; then
status=0
@@ -78,7 +86,7 @@ else
cmp2=
for t in objdump readelf eu-readelf; do
- if ($t --help) 2>&1 | grep -e '--\[*section-\]*headers' > /dev/null; then
+ if ($t --help) 2>&1 | grep ' --\[*section-\]*headers' > /dev/null; then
cmd=$t
$cmd --section-headers "$1.$suf1" | grep '\.eh_frame' > /dev/null
@@ -109,13 +117,13 @@ else
echo stripping off .eh_frame, then retrying >&2
- if (objcopy -v) 2>&1 | grep -e "--remove-section" > /dev/null; then
+ if (objcopy -v) 2>&1 | grep ' --remove-section' > /dev/null; then
objcopy --remove-section .eh_frame --remove-section .rel.eh_frame --remove-section .rela.eh_frame "$1.$suf1" "$1.$suf3"
mv "$1.$suf3" "$1.$suf1"
objcopy --remove-section .eh_frame --remove-section .rel.eh_frame --remove-section .rela.eh_frame "$2.$suf2" "$2.$suf4"
mv "$2.$suf4" "$2.$suf2"
- elif (strip --help) 2>&1 | grep -e --remove-section > /dev/null; then
+ elif (strip --help) 2>&1 | grep ' --remove-section' > /dev/null; then
cp "$1.$suf1" "$1.$suf3"
strip --remove-section .eh_frame --remove-section .rel.eh_frame --remove-section .rela.eh_frame "$1.$suf3"
mv "$1.$suf3" "$1.$suf1"
diff --git a/fixincludes/ChangeLog b/fixincludes/ChangeLog
index 2bf7bf90555..37258669eed 100644
--- a/fixincludes/ChangeLog
+++ b/fixincludes/ChangeLog
@@ -1,3 +1,38 @@
+2009-09-15 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * inclhack.def (isc_fmod, isc_omits_with_stdc)
+ (nested_sys_limits, sco_math): Remove.
+ * tests/base/math.h (ISC_FMOD_CHECK, SCO_MATH_CHECK): Remove.
+ * tests/base/stdio.h (ISC_OMITS_WITH_STDC_CHECK): Remove.
+ * tests/base/sys/limits.h: Remove.
+ * fixincl.x: Regenerate.
+
+2009-09-08 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ PR testsuite/29737
+ PR bootstrap/35938
+ PR testsuite/39655
+ * check.tpl: Fix typos.
+ * README: Likewise. Also, document that 'select' uses ERE.
+ * mkheaders.in: Update copyright years in --version output.
+ * inclhack.def (sco_math): Add missing final newline in sed
+ script 'a', 'c', or 'i' commands, for BSD sed.
+ (sco_math): In the text of 'a', 'c', or 'i' sed
+ commands, prepend leading white space with a backslash to avoid
+ the whitespace to be removed by BSD sed.
+ (sco_math): Match plain 'C++' instead of 'C\+\+' in sed regex.
+ (x11_new): Fix sed expression, for BSD sed.
+ (glibc_mutex_init): Fix newlines in sed 's' command replacement
+ part, for GNU sed 3.02 and Solaris sed.
+ (glibc_mutex_init): Replace unportable \+ sed regex operator
+ with \{1,\}.
+ (glibc_c99_inline_2, glibc_mutex_init): Avoid unportable sed
+ alternation \| regex operator.
+ (solaris_complex): Remove superfluous backslashes from
+ replacement string. Replace \+ operator with \{1,\}.
+ * tests/base/Xm/Traversal.h: This is fixed for BSD sed now.
+ * fixincl.x: Regenerate.
+
2009-09-02 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR libfortran/41169
diff --git a/fixincludes/README b/fixincludes/README
index e9e46546636..5536a34ec98 100644
--- a/fixincludes/README
+++ b/fixincludes/README
@@ -51,7 +51,7 @@ To make your fix, you will need to do several things:
the proper functioning of a different fix. Make sure your
fix is properly tested and it does what it is supposed to do.
-6. Now that you have the right things happening, syncronize the
+6. Now that you have the right things happening, synchronize the
$(srcdir)/tests/base directory with the $(builddir)/tests/res
directory. The output of "make check" will be some diffs that
should give you some hints about what to do.
@@ -82,22 +82,23 @@ MAKING CHANGES TO INCLHACK.DEF
and "c-test" because they are performed internally:
* select - Run a regex on the contents of the file being considered.
- All such regex-es must match.
+ All such regex-es must match. Matching is done with
+ extended regular expressions.
* bypass - Run a regex on the contents of the file being considered.
No such regex may match.
- * c-test - call a function in fixtests.c. See that file.
+ * c_test - call a function in fixtests.c. See that file.
* files - the "fnmatch" pattern of the file(s) to examine for
the issue. There may be several copies of this attribute.
If the header lives in a /usr/include subdirectory, be
sure to include that subdirectory in the name. e.g. net/if.h
- * mach - Match the output of config.conf against a series of fnmatch
+ * mach - Match the output of config.guess against a series of fnmatch
patterns. It must match at least one of the patterns, unless
"not-machine" has also been specified. In that case, the
- config.conf output must not match any of the patterns.
+ config.guess output must not match any of the patterns.
The next test is relatively slow because it must be handled in a
separate shell process. Some platforms do not support server shells,
@@ -113,7 +114,7 @@ MAKING CHANGES TO INCLHACK.DEF
1. Be positive for all header files that require the fix.
- It is desireable to:
+ It is desirable to:
2. Be negative as often as possible whenever the fix is not
required, avoiding the process overhead.
diff --git a/fixincludes/check.tpl b/fixincludes/check.tpl
index bb93bcc3eee..b239d8b5598 100644
--- a/fixincludes/check.tpl
+++ b/fixincludes/check.tpl
@@ -1,7 +1,7 @@
[= autogen5 template sh=check.sh =]
[=
#
-# This file contanes the shell template to run tests on the fixes
+# This file contains the shell template to run tests on the fixes
#
=]#!/bin/sh
diff --git a/fixincludes/fixincl.x b/fixincludes/fixincl.x
index d9c194f217b..b9b9b040f4d 100644
--- a/fixincludes/fixincl.x
+++ b/fixincludes/fixincl.x
@@ -2,11 +2,11 @@
*
* DO NOT EDIT THIS FILE (fixincl.x)
*
- * It has been AutoGen-ed Wednesday September 2, 2009 at 04:57:56 PM MEST
+ * It has been AutoGen-ed Tuesday September 15, 2009 at 06:55:13 AM CEST
* From the definitions inclhack.def
* and the template file fixincl
*/
-/* DO NOT SVN-MERGE THIS FILE, EITHER Wed Sep 2 16:57:56 MEST 2009
+/* DO NOT SVN-MERGE THIS FILE, EITHER Di 15. Sep 06:55:13 CEST 2009
*
* You must regenerate it. Use the ./genfixes script.
*
@@ -15,7 +15,7 @@
* certain ANSI-incompatible system header files which are fixed to work
* correctly with ANSI C and placed in a directory that GNU C will search.
*
- * This file contains 206 fixup descriptions.
+ * This file contains 202 fixup descriptions.
*
* See README for more information.
*
@@ -2644,11 +2644,23 @@ static tTestDesc aGlibc_C99_Inline_2Tests[] = {
* Fix Command Arguments for Glibc_C99_Inline_2
*/
static const char* apzGlibc_C99_Inline_2Patch[] = { sed_cmd_z,
- "-e", "s/extern int \\(stat\\|lstat\\|fstat\\|mknod\\)/#ifdef __GNUC_GNU_INLINE__\\\n\
+ "-e", "s/extern int \\(stat\\)/#ifdef __GNUC_GNU_INLINE__\\\n\
extern\\\n\
#endif\\\n\
__inline__ int \\1/",
- "-e", "s/extern int __REDIRECT\\(_NTH\\|\\) (\\(stat\\|lstat\\|fstat\\)/#ifdef __GNUC_GNU_INLINE__\\\n\
+ "-e", "s/extern int \\([lf]stat\\)/#ifdef __GNUC_GNU_INLINE__\\\n\
+extern\\\n\
+#endif\\\n\
+__inline__ int \\1/",
+ "-e", "s/extern int \\(mknod\\)/#ifdef __GNUC_GNU_INLINE__\\\n\
+extern\\\n\
+#endif\\\n\
+__inline__ int \\1/",
+ "-e", "s/extern int __REDIRECT\\(_NTH\\)\\{0,1\\} (\\(stat\\)/#ifdef __GNUC_GNU_INLINE__\\\n\
+extern\\\n\
+#endif\\\n\
+__inline__ int __REDIRECT\\1 (\\2/",
+ "-e", "s/extern int __REDIRECT\\(_NTH\\)\\{0,1\\} (\\([lf]stat\\)/#ifdef __GNUC_GNU_INLINE__\\\n\
extern\\\n\
#endif\\\n\
__inline__ int __REDIRECT\\1 (\\2/",
@@ -2774,15 +2786,25 @@ static tTestDesc aGlibc_Mutex_InitTests[] = {
* Fix Command Arguments for Glibc_Mutex_Init
*/
static const char* apzGlibc_Mutex_InitPatch[] = { sed_cmd_z,
- "-e", "/define[ \t]\\+PTHREAD_MUTEX_INITIALIZER[ \t]*\\\\/{\n\
+ "-e", "/define[ \t]\\{1,\\}PTHREAD_MUTEX_INITIALIZER[ \t]*\\\\/{\n\
N\n\
s/{ { 0, } }/{ { 0, 0, 0, 0, 0, 0 } }/\n\
}",
- "-e", "s/{ \\(0, 0, 0, 0, PTHREAD_MUTEX_\\(RECURSIVE\\|ERRORCHECK\\|ADAPTIVE\\)_NP\\) }/{ \\1, 0 }/",
- "-e", "s/{ \\(0, 0, 0, PTHREAD_MUTEX_\\(RECURSIVE\\|ERRORCHECK\\|ADAPTIVE\\)_NP\\) }/{ \\1, 0, 0 }/",
- "-e", "/define[ \t]\\+PTHREAD_RWLOCK_INITIALIZER[ \t]*\\\\/N;s/^[ \t]*#[ \t]*\\(define[ \t]\\+PTHREAD_RWLOCK_INITIALIZER[ \t]*\\\\\\)\\n[ \t]*{ { 0, } }/# if __WORDSIZE == 64\\n# \\1\\n { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }\\n# else\\n# \\1\\n { { 0, 0, 0, 0, 0, 0, 0, 0 } }\\n# endif/",
+ "-e", "s/{ \\(0, 0, 0, 0, PTHREAD_MUTEX_\\(RECURSIVE\\)_NP\\) }/{ \\1, 0 }/",
+ "-e", "s/{ \\(0, 0, 0, 0, PTHREAD_MUTEX_\\(ERRORCHECK\\)_NP\\) }/{ \\1, 0 }/",
+ "-e", "s/{ \\(0, 0, 0, 0, PTHREAD_MUTEX_\\(ADAPTIVE\\)_NP\\) }/{ \\1, 0 }/",
+ "-e", "s/{ \\(0, 0, 0, PTHREAD_MUTEX_\\(RECURSIVE\\)_NP\\) }/{ \\1, 0, 0 }/",
+ "-e", "s/{ \\(0, 0, 0, PTHREAD_MUTEX_\\(ERRORCHECK\\)_NP\\) }/{ \\1, 0, 0 }/",
+ "-e", "s/{ \\(0, 0, 0, PTHREAD_MUTEX_\\(ADAPTIVE\\)_NP\\) }/{ \\1, 0, 0 }/",
+ "-e", "/define[ \t]\\{1,\\}PTHREAD_RWLOCK_INITIALIZER[ \t]*\\\\/N;s/^[ \t]*#[ \t]*\\(define[ \t]\\{1,\\}PTHREAD_RWLOCK_INITIALIZER[ \t]*\\\\\\)\\n[ \t]*{ { 0, } }/# if __WORDSIZE == 64\\\n\
+# \\1\\\n\
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }\\\n\
+# else\\\n\
+# \\1\\\n\
+ { { 0, 0, 0, 0, 0, 0, 0, 0 } }\\\n\
+# endif/",
"-e", "s/{ \\(0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP\\) }/{ \\1, 0 }/",
- "-e", "/define[ \t]\\+PTHREAD_COND_INITIALIZER/s/{ { 0, } }/{ { 0, 0, 0, 0, 0, (void *) 0, 0, 0 } }/",
+ "-e", "/define[ \t]\\{1,\\}PTHREAD_COND_INITIALIZER/s/{ { 0, } }/{ { 0, 0, 0, 0, 0, (void *) 0, 0, 0 } }/",
(char*)NULL };
/* * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -4800,76 +4822,6 @@ static const char* apzIrix_WcsftimePatch[] = {
/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
- * Description of Isc_Fmod fix
- */
-tSCC zIsc_FmodName[] =
- "isc_fmod";
-
-/*
- * File name selection pattern
- */
-tSCC zIsc_FmodList[] =
- "math.h\0";
-/*
- * Machine/OS name selection pattern
- */
-#define apzIsc_FmodMachs (const char**)NULL
-
-/*
- * content selection pattern - do fix if pattern found
- */
-tSCC zIsc_FmodSelect0[] =
- "fmod\\(double\\)";
-
-#define ISC_FMOD_TEST_CT 1
-static tTestDesc aIsc_FmodTests[] = {
- { TT_EGREP, zIsc_FmodSelect0, (regex_t*)NULL }, };
-
-/*
- * Fix Command Arguments for Isc_Fmod
- */
-static const char* apzIsc_FmodPatch[] = {
- "format",
- "fmod(double, double)",
- (char*)NULL };
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * *
- *
- * Description of Isc_Omits_With_Stdc fix
- */
-tSCC zIsc_Omits_With_StdcName[] =
- "isc_omits_with_stdc";
-
-/*
- * File name selection pattern
- */
-tSCC zIsc_Omits_With_StdcList[] =
- "stdio.h\0math.h\0ctype.h\0sys/limits.h\0sys/fcntl.h\0sys/dirent.h\0";
-/*
- * Machine/OS name selection pattern
- */
-#define apzIsc_Omits_With_StdcMachs (const char**)NULL
-
-/*
- * content selection pattern - do fix if pattern found
- */
-tSCC zIsc_Omits_With_StdcSelect0[] =
- "!defined\\(__STDC__\\) && !defined\\(_POSIX_SOURCE\\)";
-
-#define ISC_OMITS_WITH_STDC_TEST_CT 1
-static tTestDesc aIsc_Omits_With_StdcTests[] = {
- { TT_EGREP, zIsc_Omits_With_StdcSelect0, (regex_t*)NULL }, };
-
-/*
- * Fix Command Arguments for Isc_Omits_With_Stdc
- */
-static const char* apzIsc_Omits_With_StdcPatch[] = {
- "format",
- "!defined(_POSIX_SOURCE)",
- (char*)NULL };
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * *
- *
* Description of Kandr_Concat fix
*/
tSCC zKandr_ConcatName[] =
@@ -5224,41 +5176,6 @@ static const char* apzNested_Auth_DesPatch[] = {
/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
- * Description of Nested_Sys_Limits fix
- */
-tSCC zNested_Sys_LimitsName[] =
- "nested_sys_limits";
-
-/*
- * File name selection pattern
- */
-tSCC zNested_Sys_LimitsList[] =
- "sys/limits.h\0";
-/*
- * Machine/OS name selection pattern
- */
-#define apzNested_Sys_LimitsMachs (const char**)NULL
-
-/*
- * content selection pattern - do fix if pattern found
- */
-tSCC zNested_Sys_LimitsSelect0[] =
- "CHILD_MAX";
-
-#define NESTED_SYS_LIMITS_TEST_CT 1
-static tTestDesc aNested_Sys_LimitsTests[] = {
- { TT_EGREP, zNested_Sys_LimitsSelect0, (regex_t*)NULL }, };
-
-/*
- * Fix Command Arguments for Nested_Sys_Limits
- */
-static const char* apzNested_Sys_LimitsPatch[] = { sed_cmd_z,
- "-e", "/CHILD_MAX/s,/\\* Max, Max,",
- "-e", "/OPEN_MAX/s,/\\* Max, Max,",
- (char*)NULL };
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * *
- *
* Description of Netbsd_C99_Inline_1 fix
*/
tSCC zNetbsd_C99_Inline_1Name[] =
@@ -6124,60 +6041,6 @@ static const char* apzRs6000_ParamPatch[] = {
/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
- * Description of Sco_Math fix
- */
-tSCC zSco_MathName[] =
- "sco_math";
-
-/*
- * File name selection pattern
- */
-tSCC zSco_MathList[] =
- "math.h\0*/math.h\0";
-/*
- * Machine/OS name selection pattern
- */
-#define apzSco_MathMachs (const char**)NULL
-
-/*
- * content selection pattern - do fix if pattern found
- */
-tSCC zSco_MathSelect0[] =
- "inline double abs";
-
-/*
- * content bypass pattern - skip fix if pattern found
- */
-tSCC zSco_MathBypass0[] =
- "__GNUG__";
-
-#define SCO_MATH_TEST_CT 2
-static tTestDesc aSco_MathTests[] = {
- { TT_NEGREP, zSco_MathBypass0, (regex_t*)NULL },
- { TT_EGREP, zSco_MathSelect0, (regex_t*)NULL }, };
-
-/*
- * Fix Command Arguments for Sco_Math
- */
-static const char* apzSco_MathPatch[] = { sed_cmd_z,
- "-e", "/#define.*__fp_class(a) \\\\/i\\\n\
-#ifndef __GNUC__\n",
- "-e", "/.*__builtin_generic/a\\\n\
-#else\\\n\
-#define __fp_class(a) \\\\\\\n\
- __builtin_choose_expr(__builtin_types_compatible_p(typeof(a),long double),\\\\\\\n\
- __fpclassifyl(a), \\\\\\\n\
- __builtin_choose_expr(__builtin_types_compatible_p(typeof(a), float), \\\\\\\n\
- __fpclassifyf(a),__fpclassify(a)))\\\n\
-#endif",
- "-e", "/extern \"C\\+\\+\"/N;/inline double abs/i\\\n\
-#ifndef __GNUC__\n",
- "-e", "/inline long double trunc/N;/inline long double trunc.*}.*extern \"C\\+\\+\"/a\\\n\
-#endif /* ! __GNUC__ */",
- (char*)NULL };
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * *
- *
* Description of Solaris_Complex fix
*/
tSCC zSolaris_ComplexName[] =
@@ -6209,10 +6072,10 @@ static tTestDesc aSolaris_ComplexTests[] = {
* Fix Command Arguments for Solaris_Complex
*/
static const char* apzSolaris_ComplexPatch[] = { sed_cmd_z,
- "-e", "s/#define[ \t]_Complex_I[ \t]_Complex_I/#define\t_Complex_I\t\\(__extension__ 1.0iF\\)/",
+ "-e", "s/#define[ \t]_Complex_I[ \t]_Complex_I/#define\t_Complex_I\t(__extension__ 1.0iF)/",
"-e", "/#define[ \t]_Imaginary_I[ \t]_Imaginary_I/d",
"-e", "/#define[ \t]imaginary[ \t]_Imaginary/d",
- "-e", "s/#define[ \t]I[ \t]\\+_Imaginary_I/#define\tI\t\t_Complex_I/",
+ "-e", "s/#define[ \t]I[ \t]\\{1,\\}_Imaginary_I/#define\tI\t\t_Complex_I/",
(char*)NULL };
/* * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -8331,7 +8194,7 @@ static tTestDesc aX11_NewTests[] = {
static const char* apzX11_NewPatch[] = { sed_cmd_z,
"-e", "/Widget\told, new;/i\\\n\
#ifdef __cplusplus\\\n\
-\tWidget\told, c_new;\\\n\
+\\\tWidget\told, c_new;\\\n\
#else\n",
"-e", "/Widget\told, new;/a\\\n\
#endif\n",
@@ -8380,9 +8243,9 @@ static const char* apzX11_SprintfPatch[] = {
*
* List of all fixes
*/
-#define REGEX_COUNT 249
+#define REGEX_COUNT 244
#define MACH_LIST_SIZE_LIMIT 181
-#define FIX_COUNT 206
+#define FIX_COUNT 202
/*
* Enumerate the fixes
@@ -8505,8 +8368,6 @@ typedef enum {
IRIX_STDINT_C99_FIXIDX,
IRIX_STDIO_VA_LIST_FIXIDX,
IRIX_WCSFTIME_FIXIDX,
- ISC_FMOD_FIXIDX,
- ISC_OMITS_WITH_STDC_FIXIDX,
KANDR_CONCAT_FIXIDX,
LINUX_IA64_UCONTEXT_FIXIDX,
LYNXOS_NO_WARNING_IN_SYS_TIME_H_FIXIDX,
@@ -8516,7 +8377,6 @@ typedef enum {
MATH_EXCEPTION_FIXIDX,
MATH_HUGE_VAL_FROM_DBL_MAX_FIXIDX,
NESTED_AUTH_DES_FIXIDX,
- NESTED_SYS_LIMITS_FIXIDX,
NETBSD_C99_INLINE_1_FIXIDX,
NETBSD_C99_INLINE_2_FIXIDX,
NETBSD_EXTRA_SEMICOLON_FIXIDX,
@@ -8539,7 +8399,6 @@ typedef enum {
RS6000_DOUBLE_FIXIDX,
RS6000_FCHMOD_FIXIDX,
RS6000_PARAM_FIXIDX,
- SCO_MATH_FIXIDX,
SOLARIS_COMPLEX_FIXIDX,
SOLARIS_MATH_1_FIXIDX,
SOLARIS_MATH_2_FIXIDX,
@@ -9182,16 +9041,6 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
IRIX_WCSFTIME_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
aIrix_WcsftimeTests, apzIrix_WcsftimePatch, 0 },
- { zIsc_FmodName, zIsc_FmodList,
- apzIsc_FmodMachs,
- ISC_FMOD_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
- aIsc_FmodTests, apzIsc_FmodPatch, 0 },
-
- { zIsc_Omits_With_StdcName, zIsc_Omits_With_StdcList,
- apzIsc_Omits_With_StdcMachs,
- ISC_OMITS_WITH_STDC_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
- aIsc_Omits_With_StdcTests, apzIsc_Omits_With_StdcPatch, 0 },
-
{ zKandr_ConcatName, zKandr_ConcatList,
apzKandr_ConcatMachs,
KANDR_CONCAT_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
@@ -9237,11 +9086,6 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
NESTED_AUTH_DES_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
aNested_Auth_DesTests, apzNested_Auth_DesPatch, 0 },
- { zNested_Sys_LimitsName, zNested_Sys_LimitsList,
- apzNested_Sys_LimitsMachs,
- NESTED_SYS_LIMITS_TEST_CT, FD_MACH_ONLY,
- aNested_Sys_LimitsTests, apzNested_Sys_LimitsPatch, 0 },
-
{ zNetbsd_C99_Inline_1Name, zNetbsd_C99_Inline_1List,
apzNetbsd_C99_Inline_1Machs,
NETBSD_C99_INLINE_1_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
@@ -9352,11 +9196,6 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
RS6000_PARAM_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
aRs6000_ParamTests, apzRs6000_ParamPatch, 0 },
- { zSco_MathName, zSco_MathList,
- apzSco_MathMachs,
- SCO_MATH_TEST_CT, FD_MACH_ONLY,
- aSco_MathTests, apzSco_MathPatch, 0 },
-
{ zSolaris_ComplexName, zSolaris_ComplexList,
apzSolaris_ComplexMachs,
SOLARIS_COMPLEX_TEST_CT, FD_MACH_ONLY,
diff --git a/fixincludes/inclhack.def b/fixincludes/inclhack.def
index f7ad8773e2a..72841b31f7a 100644
--- a/fixincludes/inclhack.def
+++ b/fixincludes/inclhack.def
@@ -1451,10 +1451,19 @@ fix = {
hackname = glibc_c99_inline_2;
files = sys/stat.h, '*/sys/stat.h';
select = "extern __inline__ int";
- sed = "s/extern int \\(stat\\|lstat\\|fstat\\|mknod\\)/"
+ sed = "s/extern int \\(stat\\)/"
"#ifdef __GNUC_GNU_INLINE__\\\nextern\\\n#endif\\\n"
"__inline__ int \\1/";
- sed = "s/extern int __REDIRECT\\(_NTH\\|\\) (\\(stat\\|lstat\\|fstat\\)/"
+ sed = "s/extern int \\([lf]stat\\)/"
+ "#ifdef __GNUC_GNU_INLINE__\\\nextern\\\n#endif\\\n"
+ "__inline__ int \\1/";
+ sed = "s/extern int \\(mknod\\)/"
+ "#ifdef __GNUC_GNU_INLINE__\\\nextern\\\n#endif\\\n"
+ "__inline__ int \\1/";
+ sed = "s/extern int __REDIRECT\\(_NTH\\)\\{0,1\\} (\\(stat\\)/"
+ "#ifdef __GNUC_GNU_INLINE__\\\nextern\\\n#endif\\\n"
+ "__inline__ int __REDIRECT\\1 (\\2/";
+ sed = "s/extern int __REDIRECT\\(_NTH\\)\\{0,1\\} (\\([lf]stat\\)/"
"#ifdef __GNUC_GNU_INLINE__\\\nextern\\\n#endif\\\n"
"__inline__ int __REDIRECT\\1 (\\2/";
sed = "s/^extern __inline__ int/"
@@ -1509,25 +1518,33 @@ fix = {
hackname = glibc_mutex_init;
files = pthread.h;
select = '\{ *\{ *0, *\} *\}';
- sed = "/define[ \t]\\+PTHREAD_MUTEX_INITIALIZER[ \t]*\\\\/{\n"
+ sed = "/define[ \t]\\{1,\\}PTHREAD_MUTEX_INITIALIZER[ \t]*\\\\/{\n"
"N\ns/{ { 0, } }/{ { 0, 0, 0, 0, 0, 0 } }/\n}";
sed = "s/{ \\(0, 0, 0, 0, PTHREAD_MUTEX_"
- "\\(RECURSIVE\\|ERRORCHECK\\|ADAPTIVE\\)_NP\\) }/{ \\1, 0 }/";
+ "\\(RECURSIVE\\)_NP\\) }/{ \\1, 0 }/";
+ sed = "s/{ \\(0, 0, 0, 0, PTHREAD_MUTEX_"
+ "\\(ERRORCHECK\\)_NP\\) }/{ \\1, 0 }/";
+ sed = "s/{ \\(0, 0, 0, 0, PTHREAD_MUTEX_"
+ "\\(ADAPTIVE\\)_NP\\) }/{ \\1, 0 }/";
+ sed = "s/{ \\(0, 0, 0, PTHREAD_MUTEX_"
+ "\\(RECURSIVE\\)_NP\\) }/{ \\1, 0, 0 }/";
sed = "s/{ \\(0, 0, 0, PTHREAD_MUTEX_"
- "\\(RECURSIVE\\|ERRORCHECK\\|ADAPTIVE\\)_NP\\) }/{ \\1, 0, 0 }/";
- sed = "/define[ \t]\\+PTHREAD_RWLOCK_INITIALIZER[ \t]*\\\\/"
+ "\\(ERRORCHECK\\)_NP\\) }/{ \\1, 0, 0 }/";
+ sed = "s/{ \\(0, 0, 0, PTHREAD_MUTEX_"
+ "\\(ADAPTIVE\\)_NP\\) }/{ \\1, 0, 0 }/";
+ sed = "/define[ \t]\\{1,\\}PTHREAD_RWLOCK_INITIALIZER[ \t]*\\\\/"
"N;s/^[ \t]*#[ \t]*"
- "\\(define[ \t]\\+PTHREAD_RWLOCK_INITIALIZER[ \t]*\\\\\\)\\n"
- "[ \t]*{ { 0, } }/# if __WORDSIZE == 64\\n"
- "# \\1\\n"
- " { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }\\n"
- "# else\\n"
- "# \\1\\n"
- " { { 0, 0, 0, 0, 0, 0, 0, 0 } }\\n"
+ "\\(define[ \t]\\{1,\\}PTHREAD_RWLOCK_INITIALIZER[ \t]*\\\\\\)\\n"
+ "[ \t]*{ { 0, } }/# if __WORDSIZE == 64\\\n"
+ "# \\1\\\n"
+ " { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }\\\n"
+ "# else\\\n"
+ "# \\1\\\n"
+ " { { 0, 0, 0, 0, 0, 0, 0, 0 } }\\\n"
"# endif/";
sed = "s/{ \\(0, 0, 0, 0, 0, 0, "
"PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP\\) }/{ \\1, 0 }/";
- sed = "/define[ \t]\\+PTHREAD_COND_INITIALIZER/"
+ sed = "/define[ \t]\\{1,\\}PTHREAD_COND_INITIALIZER/"
"s/{ { 0, } }/{ { 0, 0, 0, 0, 0, (void *) 0, 0, 0 } }/";
test_text = <<- _EOText_
@@ -2551,42 +2568,6 @@ fix = {
"const struct tm *);";
};
-/*
- * Fixing ISC fmod declaration
- */
-fix = {
- hackname = isc_fmod;
- files = math.h;
- select = 'fmod\(double\)';
- c_fix = format;
- c_fix_arg = "fmod(double, double)";
- test_text = "extern double fmod(double);";
-};
-
-
-/*
- * On Interactive Unix 2.2, certain traditional Unix definitions
- * (notably getc and putc in stdio.h) are omitted if __STDC__ is
- * defined, not just if _POSIX_SOURCE is defined. This makes it
- * impossible to compile any nontrivial program except with -posix.
- */
-fix = {
- hackname = isc_omits_with_stdc;
-
- files = "stdio.h";
- files = "math.h";
- files = "ctype.h";
- files = "sys/limits.h";
- files = "sys/fcntl.h";
- files = "sys/dirent.h";
-
- select = '!defined\(__STDC__\) && !defined\(_POSIX_SOURCE\)';
- c_fix = format;
- c_fix_arg = '!defined(_POSIX_SOURCE)';
- test_text = "#if !defined(__STDC__) && !defined(_POSIX_SOURCE) /* ? ! */"
- "\nint foo;\n#endif";
-};
-
/*
* These files in Sun OS 4.x and ARM/RISCiX and BSD4.3
@@ -2780,20 +2761,6 @@ fix = {
/*
- * Fixing nested comments in ISC <sys/limits.h>
- */
-fix = {
- hackname = nested_sys_limits;
- files = sys/limits.h;
- select = CHILD_MAX;
- sed = "/CHILD_MAX/s,/\\* Max, Max,";
- sed = "/OPEN_MAX/s,/\\* Max, Max,";
- test_text = "/*\n#define CHILD_MAX 20 /* Max, Max, ... */ /*\n"
- "#define OPEN_MAX 20 /* Max, Max, ... */\n";
-};
-
-
-/*
* Some versions of NetBSD don't expect the C99 inline semantics.
*/
fix = {
@@ -3207,42 +3174,6 @@ fix = {
/*
- * On OpenServer and on UnixWare 7, <math.h> uses the native compiler
- * __builtin_generic. We fix that usage to use the GCC equivalent.
- * It also has a plethora of inline functions that conflict with libstdc++.
- */
-fix = {
- hackname = sco_math;
- files = math.h, '*/math.h';
- select = "inline double abs";
- bypass = "__GNUG__";
- sed = "/#define.*__fp_class(a) \\\\/i\\\n"
- "#ifndef __GNUC__\n";
- sed =
-"/.*__builtin_generic/a\\\n"
-"#else\\\n"
-"#define __fp_class(a) \\\\\\\n"
-" __builtin_choose_expr(__builtin_types_compatible_p(typeof(a),long double),\\\\\\\n"
-" __fpclassifyl(a), \\\\\\\n"
-" __builtin_choose_expr(__builtin_types_compatible_p(typeof(a), float), \\\\\\\n"
-" __fpclassifyf(a),__fpclassify(a)))\\\n"
-"#endif";
-
- sed = "/extern \"C\\+\\+\"/N;"
- "/inline double abs/i\\\n"
- "#ifndef __GNUC__\n";
- sed = "/inline long double trunc/N;"
- "/inline long double trunc.*}.*extern \"C\\+\\+\"/a\\\n"
- "#endif /* ! __GNUC__ */";
-
- test_text =
- "#define __fp_class(a) \\\\\n"
- " __builtin_generic(a,\"ld:__fplcassifyl;f:__fpclassifyf;:__fpclassify\")\n";
-
-};
-
-
-/*
* Solaris 10+ complex.h defines _Complex_I and _Imaginary_I in terms of
* themselves, which are Sun Studio compiler intrinsics. Remove _Imaginary_I
* and imaginary definitions which are not supported by GCC.
@@ -3253,10 +3184,10 @@ fix = {
files = complex.h;
select = "#define[ \t]_Complex_I[ \t]_Complex_I";
sed = "s/#define[ \t]_Complex_I[ \t]_Complex_I/"
- "#define\t_Complex_I\t\\(__extension__ 1.0iF\\)/";
+ "#define\t_Complex_I\t(__extension__ 1.0iF)/";
sed = "/#define[ \t]_Imaginary_I[ \t]_Imaginary_I/d";
sed = "/#define[ \t]imaginary[ \t]_Imaginary/d";
- sed = "s/#define[ \t]I[ \t]\\+_Imaginary_I/#define\tI\t\t_Complex_I/";
+ sed = "s/#define[ \t]I[ \t]\\{1,\\}_Imaginary_I/#define\tI\t\t_Complex_I/";
test_text = "#define _Complex_I _Complex_I\n"
"#define complex _Complex\n"
"#define _Imaginary_I _Imaginary_I\n"
@@ -4438,7 +4369,7 @@ fix = {
sed = "/Widget\told, new;/i\\\n"
"#ifdef __cplusplus\\\n"
- "\tWidget\told, c_new;\\\n"
+ "\\\tWidget\told, c_new;\\\n"
"#else\n";
sed = "/Widget\told, new;/a\\\n"
@@ -4447,7 +4378,7 @@ fix = {
sed = "s/Widget new,/Widget c_new,/g";
test_text =
"struct wedge {\n"
- " Widget\told, new; /* fixinc check FAILS ON BSD */\n"
+ " Widget\told, new;\n"
"};\nextern Wedged( Widget new, Widget old );";
};
diff --git a/fixincludes/mkheaders.in b/fixincludes/mkheaders.in
index 33a7a524835..9109b057c53 100644
--- a/fixincludes/mkheaders.in
+++ b/fixincludes/mkheaders.in
@@ -41,7 +41,7 @@ fi
if [ x$1 = x--version ] ; then
echo "mkheaders (GCC) version $version"
- echo "Copyright 2002, 2007 Free Software Foundation, Inc."
+ echo "Copyright 2002, 2007, 2009 Free Software Foundation, Inc."
echo "This program is free software; you may redistribute it under the"
echo "terms of the GNU General Public License. This program has"
echo "absolutely no warranty."
diff --git a/fixincludes/tests/base/Xm/Traversal.h b/fixincludes/tests/base/Xm/Traversal.h
index 61e6df1164e..2b3cba73fa1 100644
--- a/fixincludes/tests/base/Xm/Traversal.h
+++ b/fixincludes/tests/base/Xm/Traversal.h
@@ -14,7 +14,7 @@ struct wedge {
#ifdef __cplusplus
Widget old, c_new;
#else
- Widget old, new; /* fixinc check FAILS ON BSD */
+ Widget old, new;
#endif
};
extern Wedged( Widget c_new, Widget old );
diff --git a/fixincludes/tests/base/math.h b/fixincludes/tests/base/math.h
index 88b24d33e34..9733744eafc 100644
--- a/fixincludes/tests/base/math.h
+++ b/fixincludes/tests/base/math.h
@@ -71,11 +71,6 @@ extern "C" int abs(int);
#endif /* HPUX8_BOGUS_INLINES_CHECK */
-#if defined( ISC_FMOD_CHECK )
-extern double fmod(double, double);
-#endif /* ISC_FMOD_CHECK */
-
-
#if defined( MATH_EXCEPTION_CHECK )
typedef struct exception t_math_exception;
#endif /* MATH_EXCEPTION_CHECK */
@@ -94,13 +89,6 @@ extern int class();
#endif /* RS6000_DOUBLE_CHECK */
-#if defined( SCO_MATH_CHECK )
-#define __fp_class(a) \
- __builtin_generic(a,"ld:__fplcassifyl;f:__fpclassifyf;:__fpclassify")
-
-#endif /* SCO_MATH_CHECK */
-
-
#if defined( STRICT_ANSI_NOT_CTD_CHECK )
#if 1 && \
&& defined(mumbling) |& ( !defined(__STRICT_ANSI__)) \
diff --git a/fixincludes/tests/base/stdio.h b/fixincludes/tests/base/stdio.h
index 8c46498af9f..5fda7bd34d1 100644
--- a/fixincludes/tests/base/stdio.h
+++ b/fixincludes/tests/base/stdio.h
@@ -54,13 +54,6 @@ extern int printf( const char *, __gnuc_va_list );
#endif /* IRIX_STDIO_DUMMY_VA_LIST_CHECK */
-#if defined( ISC_OMITS_WITH_STDC_CHECK )
-#if !defined(_POSIX_SOURCE) /* ? ! */
-int foo;
-#endif
-#endif /* ISC_OMITS_WITH_STDC_CHECK */
-
-
#if defined( READ_RET_TYPE_CHECK )
extern unsigned int fread(), fwrite();
extern int fclose(), fflush(), foo();
diff --git a/fixincludes/tests/base/sys/limits.h b/fixincludes/tests/base/sys/limits.h
deleted file mode 100644
index 4a80d3bb298..00000000000
--- a/fixincludes/tests/base/sys/limits.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* DO NOT EDIT THIS FILE.
-
- It has been auto-edited by fixincludes from:
-
- "fixinc/tests/inc/sys/limits.h"
-
- This had to be done to correct non-standard usages in the
- original, manufacturer supplied header file. */
-
-
-
-#if defined( NESTED_SYS_LIMITS_CHECK )
-/*
-#define CHILD_MAX 20 Max, Max, ... */ /*
-#define OPEN_MAX 20 Max, Max, ... */
-
-#endif /* NESTED_SYS_LIMITS_CHECK */
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3cbcff39082..27276f90464 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,10 +1,1592 @@
+2009-09-17 Janis Johnson <janis187@us.ibm.com>
+
+ PR c/41049
+ * real.c decimal_from_integer, decimal_integer_string): New.
+ (real_from_integer): Use them as special case for decimal float.
+ * config/dfp-bit.c (_si_to_sd, _usi_to_sd): Use default rounding.
+ (_di_to_sd, _di_to_dd, _di_to_td, _udi_to_sd, _udi_to_dd, _udi_to_td):
+ Do not append zero after the decimal point in string to convert.
+
+2009-09-17 Alexander Monakov <amonakov@ispras.ru>
+
+ * graphite-sese-to-poly.c (pdr_add_data_dimensions): Add bounds only
+ for ARRAY_REFs. Use array_ref_{low,up}_bound to determine bounds.
+
+2009-09-17 Martin Jambor <mjambor@suse.cz>
+
+ * common.opt (fipa-sra): New switch.
+ * opts.c (decode_options): Turn flag_ipa_sra on for opt2.
+ * timevar.def (TV_IPA_SRA): New timevar.
+ * params.def (ipa-sra-ptr-growth-factor): New parameter.
+ * doc/invoke.texi: Document -fipa-sra and ipa-sra-ptr-growth-factor.
+ * tree-sra.c: Include cgraph.c.
+ (enum sra_mode): Added SRA_MODE_EARLY_IPA.
+ (struct access): Added fields stmt, grp_maybe_modified, grp_scalar_ptr
+ and grp_not_necessarilly_dereferenced.
+ (func_param_count): New variable.
+ (encountered_apply_args): New variable.
+ (bb_dereferences): New variable.
+ (final_bbs): New variable.
+ (no_accesses_representant): New variable.
+ (no_accesses_p): New function.
+ (dump_access): Dump the new fields.
+ (sra_initialize): Set encountered_apply_args to false.
+ (get_ssa_base_param): New function.
+ (mark_parm_dereference): New function.
+ (create_access): Caring for INIDRECT_REFs and different handling of
+ varialble length accesses in early IPA SRA. Store the stmt - a new
+ parameter - to the new access.
+ (build_access_from_expr_1): New parameter stmt, passed to
+ create_access. Handle INDIRECT_REFs.
+ (build_access_from_expr): Pass the current statement to
+ build_access_from_expr_1.
+ (disqualify_ops_if_throwing_stmt): Trigger only in intraprocedural
+ passes.
+ (build_accesses_from_assign): Pass the current statement to
+ build_access_from_expr_1. Do not create assign links in IPA-SRA.
+ (scan_function): Call handle_ssa_defs on phi nodes. Set bits in
+ final_bbs when necessary. Check for calls to __builtin_apply_args.
+ Fixup EH info if anythng was changed.
+ (is_unused_scalar_param): New function.
+ (ptr_parm_has_direct_uses): New function.
+ (find_param_candidates): New function.
+ (mark_maybe_modified): New function.
+ (analyze_modified_params): New function.
+ (propagate_dereference_distances): New function.
+ (dump_dereferences_table): New function.
+ (analyze_caller_dereference_legality): New function.
+ (unmodified_by_ref_scalar_representative): New function.
+ (splice_param_accesses): New function.
+ (decide_one_param_reduction): New function.
+ (enum ipa_splicing_result): New type.
+ (splice_all_param_accesses): New function.
+ (get_param_index): New function.
+ (turn_representatives_into_adjustments): New function.
+ (analyze_all_param_acesses): New function.
+ (get_replaced_param_substitute): New function.
+ (get_adjustment_for_base): New function.
+ (replace_removed_params_ssa_names): New function.
+ (sra_ipa_reset_debug_stmts): New function.
+ (sra_ipa_modify_expr): New function.
+ (sra_ipa_modify_assign): New function.
+ (convert_callers): New function.
+ (modify_function): New function.
+ (ipa_sra_preliminary_function_checks): New function.
+ (ipa_early_sra): New function.
+ (ipa_early_sra_gate): New function.
+ (pass_early_ipa_sra): New variable.
+ * Makefile.in (tree-sra.o): Add cgraph.h to dependencies.
+
+2009-09-17 Michael Matz <matz@suse.de>
+
+ PR middle-end/41347
+ * tree.c (build_type_attribute_qual_variant): Export.
+ * tree.h (build_type_attribute_qual_variant): Declare.
+ * tree-inline.c (remap_type_1): Use it to build variants with
+ the original qualifiers and attributes.
+
+2009-09-17 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * cfglayout.c (fixup_reorder_chain): Accept conditional jumps
+ without a fallthrough edge.
+
+2009-09-16 DJ Delorie <dj@redhat.com>
+
+ * config/m32c/m32c.c (m32c_emit_epilogue): Check for R8C or M16C
+ chip and ignore the "fast_interrupt" attribute if so.
+
+2009-09-16 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/41360
+ * cfgbuild.c (find_bb_boundaries): Really re-instate 2009-09-02
+ barrier fix.
+
+2009-09-16 Richard Henderson <rth@redhat.com>
+
+ PR target/41246
+ * tree-cfg.c (verify_gimple_call): Validate that gimple_call_chain
+ is set only if DECL_NO_STATIC_CHAIN is unset.
+ * tree-nested.c (iter_nestinfo_start, iter_nestinfo_next): New.
+ (FOR_EACH_NEST_INFO): New.
+ (walk_all_functions): Use it.
+ (finalize_nesting_tree): Likewise.
+ (unnest_nesting_tree): Likewise.
+ (free_nesting_tree): Use iter_nestinfo_start, iter_nestinfo_next.
+ (get_chain_decl, get_chain_field): Reset DECL_NO_STATIC_CHAIN.
+ (convert_gimple_call): Early out if gimple_call_chain already set.
+ (convert_all_function_calls): Iterate until no new functions
+ require a static chain.
+ (finalize_nesting_tree_1): Assert DECL_NO_STATIC_CHAIN is unset
+ when building a trampoline. Use dump_function_to_file instead
+ of dump_function.
+ (lower_nested_functions): Open dump_file. Validate that decls
+ that have DECL_NO_STATIC_CHAIN from the front end don't have that
+ bit reset by this pass.
+
+2009-09-16 Michael Matz <matz@suse.de>
+
+ PR fortran/41212
+ * tree.h (struct tree_decl_common): Add decl_restricted_flag,
+ shorten decl_common_unused.
+ (DECL_RESTRICTED_P): New accessor.
+ * tree-ssa-alias.c (ptr_deref_may_alias_decl_p): Use it
+ to disambiguate marked decls and restrict pointers.
+
+2009-09-16 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/41360
+ * cfgbuild.c (find_bb_boundaries): Re-instate 2009-09-02 barrier fix.
+
+2009-09-16 Jakub Jelinek <jakub@redhat.com>
+
+ * integrate.c (set_block_abstract_flags): Call
+ set_decl_abstract_flags also on BLOCK_NONLOCALIZED_VARs.
+
+2009-09-16 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/34011
+ * tree-flow-inline.h (may_be_aliased): Compute readonly variables
+ as non-aliased.
+
+2009-09-16 DJ Delorie <dj@redhat.com>
+ Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c (output_stack_adjust): Add new argument frame_p.
+ (sh_expand_prologue): Update calls to output_stack_adjust.
+ (sh_expand_epilogue): Likewise.
+
+2009-09-15 Adam Nemet <anemet@caviumnetworks.com>
+
+ PR bootstrap/41349
+ * reorg.c (redundant_insn): Don't count notes or DEBUG_INSNs when
+ trying to limit the extent of searches in the insn stream.
+
+2009-09-15 Nathan Froyd <froydnj@codesourcery.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR target/41175
+ PR target/40677
+ * config/rs6000/rs6000.c (no_global_regs_above): Fix precedence
+ problem.
+ (SAVRES_NOINLINE_GPRS_SAVES_LR, SAVRES_NOINLINE_FPRS_SAVES_LR,
+ SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR): New strategy bits.
+ (rs6000_savres_strategy): Always save FP registers inline if the
+ target doesn't support hardware double-precision. Set the above
+ bits in return value when needed.
+ (rs6000_savres_routine_sym): Fix computation for cache selector.
+ Mark the generated symbol as a function. Rename exitp argument to
+ lr. Move code for determining the name of the symbol...
+ (rs6000_savres_routine_name): ...here. New function. Add cases for
+ getting the names right on AIX and 64-bit Linux.
+ (savres_routine_name): New variable.
+ (rs6000_make_savres_rtx): Rename exitp argument to lr. Don't assert
+ lr isn't set when savep. Use r12 resp. r1 instead of r11 depending
+ on what the target routine uses as a base register. If savep && lr
+ describe saving of r0 into memory slot.
+ (rs6000_emit_prologue): Correct use of call_used_regs. Fix out of
+ line calls for AIX ABI.
+ (rs6000_output_function_prologue): Use rs6000_savres_routine_name to
+ determine FP save/restore functions.
+ (rs6000_emit_stack_reset): Handle savres if sp_offset != 0 and
+ frame_reg_rtx != sp_reg_rtx. Use gen_add3_insn instead of
+ gen_addsi3.
+ (rs6000_emit_epilogue): Adjust computation of restore_lr.
+ Duplicate restoration of LR and execute the appropriate one
+ depending on whether GPRs are being restored inline. Set r11 from
+ offsetted frame_reg_rtx instead of sp_reg_rtx; if frame_reg_rtx is
+ r11, adjust sp_offset. Use gen_add3_insn instead of gen_addsi3.
+ Fix out of line calls for AIX ABI.
+ * config/rs6000/rs6000.md (*return_and_restore_fpregs_aix_<mode>):
+ New insn.
+ * config/rs6000/spe.md (*save_gpregs_spe): Use explicit match for
+ register 11.
+ (*restore_gpregs_spe): Likewise.
+ (*return_and_restore_gpregs_spe): Likewise.
+ * config/rs6000/linux64.h (SAVE_FP_SUFFIX, RESTORE_FP_SUFFIX):
+ Define to empty string unconditionally.
+ * config/rs6000/sysv4.h (SAVE_FP_SUFFIX, RESTORE_FP_SUFFIX):
+ Define to empty string unconditionally.
+ (GP_SAVE_INLINE, FP_SAVE_INLINE): Handle TARGET_64BIT the same as
+ !TARGET_64BIT.
+
+2009-09-15 Jan Hubicka <jh@suse.cz>
+
+ * doc/invoke.texi (inline-insns-auto): Drop from 60 to 50.
+ * params.def (inline-insns-auto): Likewise.
+
+2009-09-15 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-inline.c (estimate_function_body_sizes): Dump info about
+ individual statements only at TDF_DETAILS dump level. Format
+ source for 80 characters per line.
+
+2009-09-15 Christian Bruel <christian.bruel@st.com>
+
+ * regrename.c (do_replace): Update REG_DEAD notes.
+
+2009-09-15 Revital Eres <eres@il.ibm.com>
+
+ * doc/tm.texi (TARGET_SUPPORT_VECTOR_MISALIGNMENT): Document.
+ * targhooks.c (default_builtin_support_vector_misalignment):
+ New builtin function.
+ * targhooks.h (default_builtin_support_vector_misalignment):
+ Declare.
+ * target.h (builtin_support_vector_misalignment):
+ New field in struct gcc_target.
+ * tree-vect-data-refs.c (vect_supportable_dr_alignment): Call
+ new builtin function.
+ * target-def.h (TARGET_SUPPORT_VECTOR_MISALIGNMENT):
+ Define.
+ * config/rs6000/rs6000.c
+ (rs6000_builtin_support_vector_misalignment): New function.
+ (TARGET_SUPPORT_VECTOR_MISALIGNMENT): Define.
+
+2009-09-15 Jie Zhang <jie.zhang@analog.com>
+
+ * config/bfin/bfin.c (length_for_loop): Use NONDEBUG_INSN_P
+ instead of INSN_P.
+ (bfin_optimize_loop): Likewise.
+ (bfin_gen_bundles): Likewise.
+ (workaround_speculation): Likewise.
+ (find_load): Return NULL_RTX for debug_insn.
+
+2009-09-15 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.md (smaxsf3): Disable for IEEE mode.
+ (sminsf3): Ditto.
+
+2009-09-14 DJ Delorie <dj@redhat.com>
+
+ * config/mep/mep.h (JUMP_TABLES_IN_TEXT_SECTION): Define.
+ * config/mep/mep.c (mep_emit_cbranch): Don't use BEQZ/BNEI in
+ VLIW mode.
+
+2009-09-14 Richard Henderson <rth@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * builtins.c (expand_builtin_synchronize): Use gimple_build_asm_vec.
+ * cfgbuild.c (make_edges): Handle asm goto.
+ * cfglayout.c (fixup_reorder_chain): Likewise.
+ * cfgrtl.c (patch_jump_insn): Likewise.
+ * gimple-pretty-print.c (dump_gimple_asm): Likewise.
+ * gimple.c (gimple_build_asm_1): Add and use nlabels parameter.
+ (gimple_build_asm_vec): Add and use labels parameter.
+ (gimple_build_asm): Remove.
+ (walk_gimple_asm): Walk labels too.
+ * gimple.def (GIMPLE_ASM): Update docs.
+ * gimple.h: Update decls.
+ (struct gimple_statement_asm): Change nc to use unsigned char;
+ add nl member.
+ (gimple_asm_nlabels): New.
+ (gimple_asm_label_op, gimple_asm_set_label_op): New.
+ * gimplify.c (gimplify_asm_expr): Copy labels from ASM_EXPR
+ into gimple_build_asm_vec.
+ * jump.c (mark_jump_label_asm): New.
+ (mark_jump_label): Use it.
+ (redirect_jump_1): Handle asm goto.
+ (invert_jump_1): Soft fail if X is null.
+ * recog.c (extract_asm_operands): New.
+ (asm_noperands): Use it; handle asm labels.
+ (decode_asm_operands): Use extract_asm_operands.
+ (asm_operand_ok): Properly handle empty string.
+ * reg-stack.c (get_asm_operands_in_out): Rename from
+ get_asm_operand_n_inputs; use extract_asm_operands; return both
+ inputs and outputs by reference; update all callers.
+ * rtl.def (ASM_OPERANDS): Add label vector as operand 6.
+ * rtl.h (ASM_OPERANDS_LABEL_VEC): New.
+ (ASM_OPERANDS_LABEL_LENGTH, ASM_OPERANDS_LABEL): New.
+ (ASM_OPERANDS_SOURCE_LOCATION): Renumber.
+ (extract_asm_operands): Declare.
+ * stmt.c (expand_asm_operands): Add and use labels parameter.
+ (check_unique_operand_names): Likewise.
+ (resolve_asm_operand_names, resolve_operand_name_1): Likewise.
+ (expand_asm_stmt): Handle asm labels.
+ * tree-cfg.c (make_gimple_asm_edges): New.
+ (make_edges): Use it.
+ (cleanup_dead_labels): Handle asm labels.
+ (is_ctrl_altering_stmt): Likewise.
+ (gimple_redirect_edge_and_branch): Likewise.
+ * tree.def (ASM_EXPR): Add 5th operand.
+ * tree.h (ASM_LABELS): New.
+ (resolve_asm_operand_names): Update decl.
+
+ * c-parser.c (c_parser_asm_statement): Parse asm goto.
+ (c_parser_asm_goto_operands): New.
+ * c-tree.h (build_asm_expr): Update decl.
+ * c-typeck.c (build_asm_expr): Add and use labels parameter.
+ * doc/extend.texi: Document asm goto.
+
+2009-09-14 Richard Henderson <rth@redhat.com>
+
+ * except.h: Update declarations.
+ (struct pointer_map_t): Forward declare.
+ (ERT_UNKNOWN, ERT_THROW, ERT_CATCH): Remove.
+ (struct eh_landing_pad_d, eh_landing_pad): New.
+ (struct eh_catch_d, eh_catch): New.
+ (struct eh_region_d): Remove next_region_sharing_label, aka,
+ label, tree_label, landing_pad, post_landing_pad, resume,
+ may_contain_throw. Rename region_number to index. Remove
+ u.eh_catch, u.eh_throw. Rename u.eh_try.eh_catch to first_catch.
+ Add u.must_not_throw, landing_pads, exc_ptr_reg, filter_reg.
+ (VEC(eh_landing_pad,gc)): New.
+ (struct eh_status): Remove last_region_number. Add lp_array,
+ throw_stmt_table, ttype_data, ehspec_data.
+ (ehr_next, FOR_ALL_EH_REGION_AT): New.
+ (FOR_ALL_EH_REGION_FN, FOR_ALL_EH_REGION): New.
+ * except.c (lang_protect_cleanup_actions): Return tree.
+ (struct ehl_map_entry): Remove.
+ (init_eh_for_function): Push zero entries for region and lp_array.
+ (gen_eh_region): Add to region_array immediately.
+ (gen_eh_region_catch): Operate on eh_catch objects.
+ (gen_eh_landing_pad): New.
+ (get_eh_region_may_contain_throw, get_eh_region_tree_label): Remove.
+ (get_eh_region_no_tree_label, set_eh_region_tree_label): Remove.
+ (get_eh_region_from_number, get_eh_region_from_number_fn): New.
+ (get_eh_landing_pad_from_number_fn): New.
+ (get_eh_landing_pad_from_number): New.
+ (get_eh_region_from_lp_number_fn): New.
+ (get_eh_region_from_lp_number): New.
+ (expand_resx_stmt, note_eh_region_may_contain_throw): Remove.
+ (get_exception_pointer, get_exception_filter): Remove.
+ (collect_eh_region_array, can_be_reached_by_runtime): Remove.
+ (current_function_has_exception_handlers): Simplify.
+ (bring_to_root, eh_region_replaceable_by_p): Remove.
+ (replace_region, hash_type_list, hash_eh_region): Remove.
+ (eh_regions_equal_p, merge_peers, remove_unreachable_regions): Remove.
+ (label_to_region_map, num_eh_regions): Remove.
+ (get_next_region_sharing_label, must_not_throw_labels): Remove.
+ (find_exception_handler_labels): Remove.
+ (duplicate_eh_regions_0, find_prev_try): Remove.
+ (struct duplicate_eh_regions_data): New.
+ (duplicate_eh_regions_1): Rewrite.
+ (duplicate_eh_regions): Return a pointer map instead of an
+ integer offset.
+ (copy_eh_region_1, copy_eh_region, push_reachable_handler): Remove.
+ (redirect_eh_edge_to_label): Remove.
+ (eh_region_outermost): Rewrite using eh_region pointers
+ instead of integers.
+ (add_ttypes_entry): Update for ttype_data move to eh_status.
+ (add_ehspec_entry): Rewrite with VEC instead of varray.
+ (assign_filter_values): Likewise. Export.
+ (build_post_landing_pads, connect_post_landing_pads): Remove.
+ (dw2_build_landing_pads): Rewrite to use lp_array.
+ (struct sjlj_lp_info, sjlj_find_directly_reachable_regions): Remove.
+ (sjlj_assign_call_site_values): Rewrite to use lp_array.
+ (sjlj_emit_dispatch_table, sjlj_build_landing_pads): Likewise.
+ (sjlj_mark_call_sites): Update for landing pad numbers.
+ (finish_eh_generation): Rewrite.
+ (gate_handle_eh): Do nothing for no eh tree.
+ (pass_rtl_eh): Move up near finish_eh_generation.
+ (remove_eh_landing_pad): New.
+ (remove_eh_handler): Export.
+ (remove_eh_region, remove_eh_handler_and_replace): Remove.
+ (for_each_eh_label): Rewrite to use lp_array.
+ (make_reg_eh_region_note): New.
+ (make_reg_eh_region_note_nothrow_nononlocal): New.
+ (insn_could_throw_p): New.
+ (copy_reg_eh_region_note_forward): New.
+ (copy_reg_eh_region_note_backward): New.
+ (check_handled, add_reachable_handler): Remove.
+ (reachable_next_level, foreach_reachable_handler): Remove.
+ (arh_to_landing_pad, arh_to_label, reachable_handlers): Remove.
+ (get_eh_region_and_lp_from_rtx): New.
+ (get_eh_region_from_rtx): New.
+ (can_throw_internal_1, can_throw_external_1): Remove.
+ (can_throw_internal): Use get_eh_region_from_rtx.
+ (can_throw_external): Use get_eh_region_and_lp_from_rtx.
+ (insn_nothrow_p, can_nonlocal_goto): New.
+ (expand_builtin_eh_common, expand_builtin_eh_pointer): New.
+ (expand_builtin_eh_filter, expand_builtin_eh_copy_values): New.
+ (add_action_record): Use VEC not varray.
+ (collect_one_action_chain): Update for eh_region changes.
+ (convert_to_eh_region_ranges): Make static. Use VEC not varray.
+ Use get_eh_region_and_lp_from_rtx.
+ (gate_convert_to_eh_region_ranges): New.
+ (pass_convert_to_eh_region_ranges): Use it.
+ (push_uleb128, push_sleb128): Use VEC not varray.
+ (output_one_function_exception_table): Likewise.
+ (dump_eh_tree): Update for eh_region changes.
+ (verify_eh_tree): Likewise.
+ (verify_eh_region, default_init_unwind_resume_libfunc): Remove.
+ * tree-eh.c: Include target.h.
+ (add_stmt_to_eh_lp_fn): Rename from add_stmt_to_eh_region_fn.
+ Don't disallow GIMPLE_RESX; adjust argument check.
+ (add_stmt_to_eh_lp): Rename from add_stmt_to_eh_region.
+ (record_stmt_eh_region): Update for landing pad numbers;
+ generate a landing pad if necessary.
+ (remove_stmt_from_eh_lp): Rename from remove_stmt_from_eh_region.
+ (remove_stmt_from_eh_lp_fn): Similarly.
+ (lookup_stmt_eh_lp_fn): Rename from lookup_stmt_eh_region_fn.
+ Update for lp numbers; don't special case missing throw_stmt_table.
+ (lookup_expr_eh_lp): Similarly.
+ (lookup_stmt_eh_lp): Rename from lookup_stmt_eh_region.
+ (eh_seq, eh_region_may_contain_throw): New.
+ (struct leh_state): Add ehp_region.
+ (struct leh_tf_state): Remove eh_label.
+ (emit_post_landing_pad): New.
+ (emit_resx, emit_eh_dispatch): New.
+ (note_eh_region_may_contain_throw): New.
+ (frob_into_branch_around): Take eh_region not eh label;
+ emit eh code into eh_seq.
+ (honor_protect_cleanup_actions): Early exit for no actions. Don't
+ handle EXC_PTR_EXPR, FILTER_EXPR. Use gimple_build_eh_must_not_throw,
+ lower_eh_must_not_throw. Emit code to eh_seq.
+ (lower_try_finally_nofallthru): Emit eh code to eh_seq.
+ (lower_try_finally_onedest): Likewise.
+ (lower_try_finally_copy): Likewise.
+ (lower_try_finally_switch): Likewise.
+ (lower_try_finally): Initialize ehp_region.
+ (lower_catch): Update for eh_catch objects.
+ (lower_eh_filter): Don't handle must_not_throw.
+ (lower_eh_must_not_throw): New.
+ (lower_cleanup): Don't set eh_label.
+ (lower_eh_constructs_2): Resolve eh builtins.
+ Handle GIMPLE_EH_MUST_NOT_THROW.
+ (lower_eh_constructs): Initialize eh_region_may_contain_throw.
+ Add eh_seq to the end of the function body.
+ (make_eh_dispatch_edges): New.
+ (make_eh_edge): Remove.
+ (make_eh_edges): Simplify for landing pads.
+ (redirect_eh_edge_1): New.
+ (redirect_eh_edge): Use it.
+ (redirect_eh_dispatch_edge): New.
+ (stmt_could_throw_p): Use a switch. Allow RESX.
+ (stmt_can_throw_external): Use lookup_stmt_eh_lp.
+ (stmt_can_throw_internal): Likewise.
+ (maybe_clean_eh_stmt_fn, maybe_clean_eh_stmt): New.
+ (maybe_clean_or_replace_eh_stmt): Update for landing pads.
+ (maybe_duplicate_eh_stmt_fn, maybe_duplicate_eh_stmt): New.
+ (gate_refactor_eh): New.
+ (pass_refactor_eh): Use it.
+ (lower_resx, execute_lower_resx, pass_lower_resx): New.
+ (lower_eh_dispatch, execute_lower_eh_dispatch): New.
+ (gate_lower_ehcontrol, pass_lower_eh_dispatch): New.
+ (remove_unreachable_handlers): Rename from
+ tree_remove_unreachable_handlers; rewrite for landing pads;
+ call remove_eh_handler directly.
+ (remove_unreachable_handlers_no_lp): New.
+ (unsplit_eh, unsplit_all_eh): New.
+ (tree_empty_eh_handler_p, all_phis_safe_to_merge): Remove.
+ (cleanup_empty_eh_merge_phis, cleanup_empty_eh_move_lp): New.
+ (cleanup_empty_eh_unsplit): New.
+ (cleanup_empty_eh): Rewrite.
+ (cleanup_all_empty_eh): New.
+ (execute_cleanup_eh): Rename from cleanup_eh. Remove unreachable
+ handlers first. Use unsplit_all_eh, cleanup_all_empty_eh.
+ (gate_cleanup_eh): New.
+ (pass_cleanup_eh): Use it.
+ (verify_eh_edges): Move later in file. Expect one EH edge.
+ (verify_eh_dispatch_edge): New.
+
+ * Makefile.in (FUNCTION_H): Use vecprim.h, not varray.h.
+ (gtype-desc.o): Add TARGET_H.
+ (tree.o): Use EXCEPT_H, not except.h.
+ (cfgbuild.o): Add EXPR_H.
+ (GTFILES): Add vecprim.h.
+ * builtins.c (expand_builtin): Handle BUILT_IN_EH_POINTER,
+ BUILT_IN_EH_FILTER, BUILT_IN_EH_COPY_VALUES.
+ * builtins.def (BUILT_IN_UNWIND_RESUME, BUILT_IN_EH_POINTER,
+ BUILT_IN_EH_FILTER, BUILT_IN_EH_COPY_VALUES): New.
+ * calls.c (emit_call_1): Use make_reg_eh_region_note.
+ * cfgbuild.c (control_flow_insn_p): Use can_nonlocal_goto; tidy
+ calls to can_throw_internal.
+ (rtl_make_eh_edge): Use get_eh_landing_pad_from_rtx.
+ (make_edges): Don't handle RESX; use can_nonlocal_goto.
+ * cfgexpand.c (expand_gimple_stmt_1): Don't handle RESX.
+ (expand_gimple_stmt): Use make_reg_eh_region_note.
+ (expand_debug_expr): Don't handle EXC_PTR_EXPR and FILTER_EXPR.
+ (gimple_expand_cfg): Don't call convert_from_eh_region_ranges,
+ or find_exception_handler_labels.
+ * cfgrtl.c (rtl_verify_flow_info_1): Don't handle RESX. Assert
+ there is exacly one EH edge. Use can_nonlocal_goto and
+ can_throw_internal.
+ * cgraphunit.c (update_call_expr): Use maybe_clean_eh_stmt_fn.
+ (cgraph_materialize_all_clones): Use maybe_clean_or_replace_eh_stmt.
+ * combine.c (can_combine_p, try_combine): Use insn_nothrow_p.
+ * cse.c (count_reg_usage, insn_live_p): Use insn_could_throw_p.
+ * dce.c (deletable_insn_p_1): Don't test may_trap_p.
+ (deletable_insn_p): Use insn_nothrow_p; reorder nonjump insn test.
+ * dse.c (scan_insn): Use insn_could_throw_p.
+ * emit-rtl.c (try_split): Use copy_reg_eh_region_note_backward.
+ * expr.c (expand_expr_real): Use make_reg_eh_region_note.
+ (expand_expr_real_1): Don't handle RESX, EXC_PTR, or FILTER_EXPR.
+ * fold-const.c (tree_expr_nonnegative_warnv_p): Don't handle
+ EXC_PTR_EXPR or FILTER_EXPR.
+ (tree_expr_nonzero_warnv_p): Likewise.
+ * function.h: Include vecprim.h, not varray.h
+ (struct rtl_eh): Remove filter, exc_ptr, built_landing_pad members;
+ move ttype_data and ehspec_data members to struct eh_status; change
+ action_record_data member to a VEC.
+ * gcse.c (hash_scan_set): Use can_throw_internal.
+ * gengtype.c (open_base_files): Add target.h to gtype-desc.c.
+ * gimple-iterator.c (gsi_replace): Use maybe_clean_or_replace_eh_stmt.
+ * gimple-low.c (lower_stmt): Handle GIMPLE_EH_MUST_NOT_THROW.
+ (block_may_fallthru): Don't handle RESX_EXPR.
+ * gimple-pretty-print.c (dump_gimple_label): Dump EH_LANDING_PAD_NR.
+ (dump_gimple_eh_must_not_throw, dump_gimple_eh_dispatch): New.
+ (dump_gimple_stmt): Dump landing pad information with TDF_EH;
+ handle GIMPLE_EH_MUST_NOT_THROW, GIMPLE_EH_DISPATCH.
+ * gimple.c (gss_for_code): Handle GIMPLE_EH_MUST_NOT_THROW,
+ GIMPLE_EH_DISPATCH, GIMPLE_RESX.
+ (gimple_size): Likewise.
+ (gimple_build_eh_dispatch, gimple_build_eh_must_not_throw): New.
+ (gimple_build_resx): Use gimple_build_with_ops.
+ (DEFTREECODE): Don't handle EXC_PTR_EXPR, FILTER_EXPR.
+ (is_gimple_val): Likewise.
+ (is_gimple_stmt): Remove RESX_EXPR.
+ * gimple.def (GIMPLE_EH_MUST_NOT_THROW, GIMPLE_EH_DISPATCH): New.
+ (GIMPLE_RESX): Reorder with other EH constructs.
+ * gimple.h (struct gimple_statement_eh_mnt): New.
+ (struct gimple_statement_eh_ctrl): Rename from gimple_statement_resx.
+ (gimple_eh_filter_must_not_throw): Remove.
+ (gimple_eh_filter_set_must_not_throw): Remove.
+ (gimple_eh_must_not_throw_fndecl): New.
+ (gimple_eh_dispatch_region, gimple_eh_dispatch_set_region): New.
+ (is_gimple_resx): New.
+ * gimplify.c (gimplify_expr): Don't handle EXC_PTR_EXPR, RESX_EXPR.
+ Don't copy EH_FILTER_MUST_NOT_THROW.
+ * gsstruct.def (GSS_EH_MNT, GSS_EHCONTROL): New.
+ * ipa-inline.c (estimate_function_body_sizes): Don't try to
+ handle must_not_throw_labels specially.
+ * ipa-pure-const.c (check_call): Update debug statement for LP.
+ * ipa-type-escape.c (check_operand): Don't handle EXC_PTR or FILTER.
+ * ipa-utils.c (get_base_var): Likewise.
+ * libfunc.h (LTI_unwind_resume, unwind_resume_libfunc): Remove.
+ * lower-subreg.c (move_eh_region_note): Remove.
+ (resolve_simple_move): Use copy_reg_eh_region_note_forward.
+ * omp-low.c (new_omp_context): Update for eh_lp_nr.
+ (create_task_copyfn): Likewise.
+ (maybe_catch_exception): Use gimple_build_eh_filter.
+ * optabs.c (emit_libcall_block): Update test for no-nonlocal-goto
+ REG_EH_REGION. Use make_reg_eh_region_note_nothrow_nononlocal.
+ * passes.c (init_optimization_passes): Add pass_lower_eh_dispatch
+ and pass_lower_resx.
+ * print-tree.c (print_node): Dump EH_LANDING_PAD_NR.
+ * recog.c (peephole2_optimize): Use copy_reg_eh_region_note_backward,
+ can_throw_internal, can_nonlocal_goto.
+ * reload1.c (fixup_eh_region_note): Use insn_could_throw_p,
+ copy_reg_eh_region_note_forward.
+ (emit_input_reload_insns): Use copy_reg_eh_region_note_forward.
+ (emit_output_reload_insns): Likewise.
+ (copy_eh_notes): Remove.
+ * rtl.def (RESX): Remove.
+ * rtl.h: Update declarations.
+ * sese.c (graphite_copy_stmts_from_block): Use maybe_duplicate_eh_stmt.
+ * tree-cfg.c (make_edges): Handle GIMPLE_EH_DISPATCH.
+ (update_eh_label): Remove.
+ (cleanup_dead_labels_eh): New.
+ (cleanup_deal_labels): Use it instead of update_eh_label.
+ (gimple_merge_blocks): Update landing pad data structure when
+ removing a landing pad label.
+ (remove_useless_stmts_tc): Remove gimple_eh_filter_must_not_throw
+ test; handle GIMPLE_EH_MUST_NOT_THROW.
+ (is_ctrl_altering_stmt): Handle GIMPLE_EH_DISPATCH.
+ (verify_gimple_assign_single): Don't handle EXC_PTR or FILTER_EXPR.
+ (verify_types_in_gimple_stmt): Handle GIMPLE_EH_DISPATCH.
+ (verify_stmt): Likewise. Verify landing pads.
+ (gimple_redirect_edge_and_branch): Handle GIMPLE_EH_DISPATCH.
+ (gimple_duplicate_bb): Use maybe_duplicate_eh_stmt.
+ (struct move_stmt_d): Add eh_map.
+ (move_stmt_eh_region_nr, move_stmt_eh_region_tree_nr): New.
+ (move_stmt_r): Remap eh region numbers in builtin calls,
+ resx and eh_dispatch.
+ (move_block_to_fn): Remove eh_offset parameter. Use
+ maybe_duplicate_eh_stmt_fn.
+ (find_outermost_region_in_block): Operate on eh_region pointers
+ instead of region numbers.
+ (move_sese_region_to_fn): Expect eh_map instead of eh_offset from
+ duplicate_eh_regions.
+ * tree-cfgcleanup.c (tree_forwarder_block_p): Move entry block edge
+ test earlier. Disallow EH landing pads.
+ * tree-cfa.c (create_tree_common_ann): Don't set ann->rn.
+ * tree-flow.h: Update declarations.
+ (struct tree_ann_common_d): Replace rn with lp_nr.
+ * tree-inline.c (copy_tree_body_r): Don't handle RESX_EXPR.
+ (remap_eh_region_nr, remap_eh_region_tree_nr): New.
+ (remap_gimple_stmt): Remap eh region numbers in builtin calls,
+ resx and eh_dispatch.
+ (copy_bb): Use maybe_duplicate_eh_stmt_fn.
+ (copy_edges_for_bb): Use make_eh_dispatch_edges.
+ (copy_cfg_body): Expect eh_map instead of eh_region_offset
+ from duplicate_eh_regions.
+ (estimate_num_insns): Don't handle EXC_PTR_EXPR or FILTER_EXPR;
+ update RESX; handle EH_DISPATCH.
+ (expand_call_inline): Set eh_lp_nr, not eh_region.
+ (maybe_inline_call_in_expr): Likewise.
+ * tree-inline.h (struct copy_body_data): Replace eh_region with
+ eh_lp_nr, eh_region_offset with eh_map.
+ * tree-optimize.c (execute_fixup_cfg): Use maybe_clean_eh_stmt.
+ * tree-pass.h (pass_lower_eh_dispatch, pass_lower_resx): New.
+ * tree-pretty-print.c (dump_generic_node): Don't handle
+ EXC_PTR_EXPR, FILTER_EXPR, RESX_EXPR.
+ * tree-sra.c (scan_function): Use maybe_clean_eh_stmt.
+ * tree-ssa-alias.c (ref_maybe_used_by_call_p_1): Don't handle
+ EXC_PTR_EXPR, FILTER_EXPR.
+ * tree-ssa-operands.c (get_expr_operands): Likewise.
+ * tree-ssa-propagate.c (valid_gimple_rhs_p): Likewise.
+ * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Likewise.
+ (ao_ref_init_from_vn_reference): Likewise.
+ * tree-ssa-sink.c (statement_sink_location): Likewise.
+ * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise.
+ (mark_virtual_phi_result_for_renaming): Export. Tidy.
+ * tree-ssa-pre.c (get_or_alloc_expr_for): Don't handle
+ EXC_PTR_EXPR, FILTER_EXPR.
+ (is_exception_related): Remove.
+ (compute_avail): Don't call it.
+ * tree-ssa-structalias.c: Remove VEC definitions for int and unsigned.
+ * tree.c (find_decls_types_in_eh_region): Update for eh_region changes.
+ (find_decls_types_in_node): Use FOR_ALL_EH_REGION_FN.
+ (build_common_builtin_nodes): Add enable_cxa_end_cleanup parameter.
+ Build EH builtins.
+ (build_resx): Remove.
+ * tree.def (EXC_PTR_EXPR, FILTER_EXPR, RESX_EXPR): Remove.
+ * tree.h: Update declarations.
+ (EH_FILTER_MUST_NOT_THROW): Remove.
+ (struct tree_label_decl): Add eh_landing_pad_nr.
+ (EH_LANDING_PAD_NR): New.
+ * value-prof.c (gimple_ic): Tidy variable names. Update for
+ landing pad numbers.
+ (gimple_stringop_fixed_value): Tidy variable names. Assert
+ that neither call stmt can throw.
+ * vecprim.h (uchar): New.
+ (VEC(uchar,heap), VEC(uchar,gc)): New.
+
+ * c-common.c (c_define_builtins): Update call to
+ build_common_builtin_nodes.
+ * c-parser.c (c_parse_file): Don't call
+ default_init_unwind_resume_libfunc.
+
+2009-09-14 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mips/mips-protos.h (mips_cfun_has_cprestore_slot_p): Declare.
+ (mips_cprestore_address_p): Likewise.
+ (mips_save_gp_to_cprestore_slot): Likewise.
+ (mips_restore_gp): Rename to...
+ (mips_restore_gp_from_cprestore_slot): ...this.
+ (mips_must_initialize_gp_p): Declare.
+ (mips_emit_save_slot_move): Likewise.
+ (mips_output_load_label): Return nothing.
+ (mips_eh_uses): Declare.
+ * config/mips/mips.h (TARGET_SPLIT_CALLS): Require epilogue_completed.
+ (TARGET_CPRESTORE_DIRECTIVE): New macro.
+ (TARGET_ABSOLUTE_JUMPS): Likewise.
+ (EH_USES): Likewise.
+ (FIRST_PSEUDO_REGISTER): Update comment.
+ (MIPS_ABSOLUTE_JUMP): New macro, extracted from...
+ (MIPS_CALL): ...here.
+ (REGISTER_NAMES): Add $cprestore.
+ * config/mips/mips.c (machine_function): Remove has_gp_insn_p.
+ Add load_label_length, has_inflexible_gp_insn_p,
+ has_flexible_gp_insn_p, must_initialize_gp_p and
+ must_restore_gp_when_clobbered_p.
+ (mips_expand_call): Don't generate split instructions here.
+ (mips_split_call): Update the call to mips_restore_gp after
+ the above name change.
+ (mips16_cfun_returns_in_fpr_p): Move earlier in file.
+ (mips_find_gp_ref): New function.
+ (mips_insn_has_inflexible_gp_ref_p): Likewise.
+ (mips_cfun_has_inflexible_gp_ref_p): Likewise.
+ (mips_insn_has_flexible_gp_ref_p): Likewise.
+ (mips_cfun_has_flexible_gp_ref_p): Likewise.
+ (mips_function_has_gp_insn): Delete.
+ (mips_global_pointer): Drop the df_regs_ever_live_p check.
+ Use the new functions above. Only return INVALID_REGNUM
+ for TARGET_ABSOLUTE_JUMPS.
+ (mips_must_initialize_gp_p): New function.
+ (mips_get_cprestore_base_and_offset): New function, extracted from...
+ (mips_cprestore_slot): ...here. Take a bool parameter.
+ (mips_cfun_has_cprestore_slot_p): New function.
+ (mips_cprestore_address_p): Likewise.
+ (mips_save_gp_to_cprestore_slot): Likewise.
+ (mips_restore_gp): Rename to...
+ (mips_restore_gp_from_cprestore_slot): ...this. Assert
+ epilogue_completed. Update the call to mips_cprestore_slot.
+ Test cfun->machine->must_restore_gp_when_clobbered_p.
+ (mips_direct_save_slot_move_p): New function.
+ (mips_emit_save_slot_move): Likewise.
+ (mips_output_cplocal): Test mips_must_initialize_gp_p () instead
+ of cfun->machine->global_pointer.
+ (mips_output_function_prologue): Check mips_must_initialize_gp_p ().
+ (mips_save_reg): Use mips_emit_save_slot_move.
+ (mips_expand_prologue): Set must_initialize_gp_p.
+ Use mips_cfun_has_cprestore_slot_p. Use gen_potential_cprestore
+ for all cprestore saves. Emit a use_cprestore instruction after
+ setting up the cprestore slot.
+ (mips_restore_reg): Use mips_emit_save_slot_move.
+ (mips_process_load_label): New function.
+ (mips_load_label_length): Likewise.
+ (mips_output_load_label): Don't return asm: output it here instead.
+ Use mips_process_load_label.
+ (mips_adjust_insn_length): Adjust the length of branch instructions
+ that have length MAX_PIC_BRANCH_LENGTH.
+ (mips_output_conditional_branch): Update the call to
+ mips_output_load_label. Assume the branch target is OPERANDS[0]
+ rather than OPERANDS[1]. Use MIPS_ABSOLUTE_JUMP for absolute jumps.
+ (mips_output_order_conditional_branch): Swap the meaning of
+ OPERANDS[0] and OPERANDS[1].
+ (mips_variable_issue): Don't count ghost instructions.
+ (mips_expand_ghost_gp_insns): New function.
+ (mips_reorg): Rerun mips_reorg_process_insns if it returns true.
+ (mips_output_mi_thunk): Set must_initialize_gp_p.
+ (mips_eh_uses): New function.
+ * config/mips/predicates.md (cprestore_save_slot_operand)
+ (cprestore_load_slot_operand): New predicates.
+ * config/mips/mips.md (UNSPEC_POTENTIAL_CPRESTORE): New unspec.
+ (UNSPEC_MOVE_GP): Likewise.
+ (UNSPEC_CPRESTORE, UNSPEC_RESTORE_GP, UNSPEC_EH_RETURN)
+ (UNSPEC_CONSTTABLE_INT, UNSPEC_CONSTTABLE_FLOAT): Bump to make room.
+ (CPRESTORE_SLOT_REGNUM): New register.
+ (MAX_PIC_BRANCH_LENGTH): New constant.
+ (jal_macro): Use MIPS_ABSOLUTE_JUMPS.
+ (length): Use MAX_PIC_BRANCH_LENGTH as a placeholder for PIC long
+ branches. Fix commentary.
+ (loadgp_newabi_<mode>): Change from unspec_volatile to unspec.
+ Only split if mips_must_initialize_gp_p; expand to nothing otherwise.
+ Change type to "ghost".
+ (loadgp_absolute_<mode>): Likewise.
+ (loadgp_rtp_<mode>): Likewise.
+ (copygp_mips16): Likewise.
+ (loadgp_blockage): Remove redundant mode attribute.
+ (potential_cprestore): New instruction.
+ (cprestore): Turn into an unspec set.
+ (use_cprestore): New instruction.
+ (*branch_fp): Swap operands 0 and 1. Remove redundant mode attribute.
+ (*branch_fp_inverted): Likewise.
+ (*branch_order<mode>): Likewise.
+ (*branch_order<mode>_inverted): Likewise.
+ (*branch_equality<mode>): Likewise.
+ (*branch_equality<mode>_inverted): Likewise.
+ (*branch_bit<bbv><mode>): Likewise.
+ (*branch_bit<bbv><mode>_inverted): Likewise.
+ (*branch_equality<mode>_mips16): Remove redundant mode.
+ (jump): Turn into a define_expand.
+ (*jump_absolute): New instruction.
+ (*jump_pic): Likewise.
+ (*jump_mips16): Rename previously-unnamed pattern. Remove
+ redundant mode attribute.
+ (restore_gp): Split on epilogue_completed rather than
+ reload_completed. Change type to "ghost".
+ (move_gp<mode>): New instruction.
+ * config/mips/mips-dsp.md (mips_bposge): Swap operands 0 and 1.
+ Remove redundant mode attribute.
+ * config/mips/mips-ps-3d.md (bc1any4t): Likewise.
+ (bc1any4f, bc1any2t, bc1any2f): Likewise.
+ (*branch_upper_lower, *branch_upper_lower_inverted): Likewise.
+
+2009-09-14 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/41210
+ * config/rs6000/rs6000.c (rs6000_function_value): V2DF and V2DI
+ are returned in the same register (vs34 or v2) that Altivec vector
+ types are returned in.
+ (rs6000_libcall_value): Ditto.
+
+ PR target/41331
+ * config/rs6000/rs6000.c (rs6000_emit_move): Use gen_add3_insn
+ instead of explicit addsi3/adddi3 calls.
+ (rs6000_split_multireg_move): Ditto.
+ (rs6000_emit_allocate_stack): Ditto.
+ (rs6000_emit_prologue): Ditto.
+ (rs6000_output_mi_thunk): Ditto.
+
+ * config/rs6000/rs6000.md (bswapdi*): Don't assume the pointer
+ size is 64 bits if we can use 64-bit registers.
+
+2009-09-14 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * config/bfin/bfin.c (bfin_longcall_p): Don't use short calls for weak
+ symbols.
+
+ From Jie Zhang <jie.zhang@analog.com>:
+ * config/bfin/bfin.c (bfin_expand_prologue): Ask do_link to
+ save FP and RETS with saveall attribute.
+ (bfin_expand_epilogue): Ask do_unlink to restore FP and RETS
+ with saveall attribute.
+
+ * config/bfin/bfin.c (bfin_expand_builtin,
+ case BFIN_BUILTIN_MULT_1X32X32): Force constants to registers for the
+ operands.
+
+ From Jie Zhang <jie.zhang@analog.com>:
+ * config/bfin/bfin.c (bfin_expand_builtin): Initialize icodes
+ before use in two places.
+ * config/bfin/bfin.md (AREG): Define mode iterator.
+ (reload_in, reload_out): Use mode iterator AREG.
+
+2009-09-14 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41350
+ * dwarf2out.c (dwarf2out_begin_prologue): Adjust non-CFI asm
+ EH personality path.
+
+2009-09-13 Richard Guenther <rguenther@suse.de>
+ Rafael Avila de Espindola <espindola@google.com>
+
+ * langhooks-def.h (LANG_HOOKS_EH_RUNTIME_TYPE): Define.
+ (LANG_HOOKS_EH_PERSONALITY): Likewise.
+ (LANG_HOOKS_INITIALIZER): Adjust.
+ (lhd_pass_through_t): Declare.
+ * langhooks.h (struct lang_hooks): Add eh_runtime_type and
+ eh_personality.
+ * langhooks.c (lhd_pass_through_t): New function.
+ * dwarf2out.c (output_call_frame_info, dwarf2out_do_cfi_startproc,
+ dwarf2out_begin_prologue): Use personality from current_function_decl.
+ * expr.h (get_personality_function): Declare.
+ * expr.c (get_personality_function): New function.
+ (build_personality_function): Likewise.
+ * libfuncs.h (libfunc_index): Remove LTI_eh_personality.
+ (eh_personality_libfunc): Remove.
+ * optabs.c (build_libfunc_function): New function split out from ...
+ (init_one_libfunc): ... here.
+ * tree.h (DECL_FUNCTION_PERSONALITY): New.
+ (tree_function_decl): Add personality.
+ (lhd_gcc_personality): Declare.
+ (build_personality_function): Likewise.
+ * tree.c (gcc_eh_personality_decl): New.
+ (lhd_gcc_personality): New function.
+ * except.h (lang_eh_runtime_type): Remove.
+ (enum eh_personality_kind): New.
+ (build_personality_function): Declare.
+ (function_needs_eh_personality): Declare.
+ * except.c (lang_eh_runtime_type): Remove.
+ (function_needs_eh_personality): New function.
+ (add_type_for_runtime): Call lang_hooks.type_for_runtime instead.
+ (sjlj_emit_function_enter, output_function_exception_table):
+ Use personality from current_function_decl.
+ * tree-eh.c (lower_eh_constructs): Set DECL_FUNCTION_PERSONALITY.
+ * tree-inline.c (tree_can_inline_p): Do not inline across different
+ EH personalities.
+ (expand_call_inline): Likewise. Adjust the callers EH personality.
+ (tree_function_versioning): Copy DECL_FUNCTION_PERSONALITY.
+ * cgraph.c (cgraph_add_new_function): Set DECL_FUNCTION_PERSONALITY.
+ * Makefile.in (cgraph.o): Add $(EXCEPT_H) dependency.
+ (c-parser.o): Likewise
+ * c-tree.h (c_eh_initialized_p): Remove.
+ (c_maybe_initialize_eh): Likewise.
+ * c-decl.c (finish_decl): Don't call c_maybe_initialize_eh.
+ (finish_decl): Don't call c_maybe_initialize_eh.
+ (c_eh_initialized_p): Remove.
+ (c_maybe_initialize_eh): Likewise.
+ * c-parser.c (c_parser_omp_construct): Likewise.
+ (c_parse_file): Initialize exception handling.
+
+2009-09-13 Kai Tietz <kai.tietz@onevision.com>
+
+ * config.gcc (tm_file): Remove i386/biarch32.h
+ for i?86-w64-mingw* case.
+ (i?86-*-mingw* andx86_64-*-mingw*): Add multilib
+ support.
+ * config.host: Set for x64 mingw the option
+ use_long_long_for_widest_fast_int to yes.
+
+2009-09-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree.h (DECL_IGNORED_P): Document further effect for FUNCTION_DECL.
+ * dbxout.c (dbxout_function_end): Do not test DECL_IGNORED_P.
+ (dbxout_begin_function): Likewise.
+ * final.c (dwarf2_debug_info_emitted_p): New predicate.
+ (final_start_function): Do not emit debug info if DECL_IGNORED_P is
+ set on the function.
+ (final_end_function): Likewise.
+ (final_scan_insn): Likewise.
+ (rest_of_handle_final): Likewise.
+ * varasm.c (assemble_start_function): Likewise.
+ * config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Likewise.
+
+2009-09-12 Jason Merrill <jason@redhat.com>
+
+ * dbgcnt.c (dbg_cnt_process_single_pair): constify.
+ * opts.c (common_handle_option): constify.
+
+2009-09-12 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/install.texi (avr): Remove obsolete reference site.
+
+2009-09-12 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/install.texi (Binaries): Adjust AIX link.
+
+2009-09-12 Akim Demaille <demaille@gostai.com>
+
+ * doc/invoke.texi (-fstrict-aliasing): Correct two examples.
+ Use an imperative sentence.
+
+2009-09-11 Richard Henderson <rth@redhat.com>
+
+ * gsstruct.def (DEFGSSTRUCT): Remove printable-name argument; add
+ structure-name and has-tree-operands arguments; update all entries.
+ * gimple.def (DEFGSCODE): Replace 3rd argument with GSS_symbol;
+ update all entries.
+ * gimple.c (gimple_ops_offset_): Use HAS_TREE_OP argument.
+ (gsstruct_code_size): New.
+ (gss_for_code_): New.
+ (gss_for_code): Remove.
+ (gimple_size): Rewrite using gsstruct_code_size.
+ (gimple_statement_structure): Move to gimple.h.
+ * gimple.h (gimple_ops_offset_, gss_for_code_): Declare.
+ (gss_for_code, gimple_statement_structure): New.
+ (gimple_ops): Use new arrays; tidy.
+
+2009-09-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * config/pa/predicates.md (symbolic_operand): Require a CONST symbolic
+ operand to be a PLUS expression.
+ * config/pa/pa.c (pa_secondary_reload): Likewise.
+
+2009-09-11 Jakub Jelinek <jakub@redhat.com>
+
+ * combine.c (propagate_for_debug_subst): Call wrap_constant on top.
+
+ * print-rtl.c (print_rtx): Use JUMP_LABEL (in_rtx) instead of
+ XEXP (in_rtx, 8).
+
+2009-09-11 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ From Jie Zhang <jie.zhang@analog.com>:
+ * doc/extend.texi (node Function Attributes): Document l2
+ function attribute.
+ (node Blackfin Variable Attributes): Document l2 variable attributes.
+
+2009-09-11 Loren J. Rittle <ljrittle@acm.org>
+
+ * config.gcc (*-*-freebsd*): Enable default_use_cxa_atexit
+ to match the system compiler's configuration at inflection point.
+ Add comment to remark a remaining difference with system compiler.
+
+ * configure.ac (*-*-freebsd*): Enable check for __stack_chk_fail.
+ * configure: Regenerate.
+
+2009-09-11 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ From Jie Zhang <jie.zhang@analog.com>:
+ * config/bfin/bfin.c (bfin_expand_call): Handle L2 functions.
+ (bfin_handle_l2_attribute): New.
+ (bfin_attribute_table): Add l2 attribute.
+
+2009-09-11 Michael Matz <matz@suse.de>
+
+ PR middle-end/41275
+ * tree-inline.c (remap_decls): Don't put DECL_EXTERNAL decls
+ on the local_decls list.
+
+2009-09-11 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/41276
+ PR debug/41307
+ * cselib.c (cselib_expand_value_rtx_cb): Document callback
+ interface.
+ (cselib_expand_value_rtx_1): Use callback for SUBREGs. Adjust
+ for VALUEs, to implement the documented interface.
+ * var-tracking.c (vt_expand_loc_callback): Handle SUBREGs.
+ Adjust for VALUEs and anything else, to implement the
+ documented interface.
+
+2009-09-10 Nathan Froyd <froydnj@codesourcery.com>
+
+ * config/rs6000/rs6000.h (DATA_ALIGNMENT): Check that we are dealing
+ with actual SPE/paired vector modes before using 64-bit alignment.
+ Check that TYPE is a REAL_TYPE for TARGET_E500_DOUBLE.
+
+2009-09-10 DJ Delorie <dj@redhat.com>
+
+ * config/mep/mep.md (eh_epilogue): Defer until after epilogue is
+ emitted.
+
+ * config/mep/mep.h (LEGITIMATE_CONSTANT_P): New.
+ * config/mep/mep.c (mep_legitimate_constant_p): New.
+ * config/mep/mep-protos.h: Prototype it.
+
+2009-09-10 Richard Henderson <rth@redhat.com>
+
+ * print-rtl.c (print_rtx): Fix JUMP_LABEL index.
+
+2009-09-10 Jason Merrill <jason@redhat.com>
+
+ * tree.c (chain_index): New fn.
+ * tree.h: Declare it.
+
+2009-09-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * config/sol2-c.c (cmn_err_length_specs): Initialize
+ scalar_identity_flag.
+
+2009-09-10 Richard Henderson <rth@redhat.com>
+
+ * tree.h (struct tree_decl_common): Move align member earlier;
+ move label_decl_uid member ...
+ (struct tree_label_decl): ... here.
+ (LABEL_DECL_UID): Update to match.
+
+ * tree-cfg.c (dump_function_to_file): Dump eh tree with TDF_EH,
+ not TDF_DETAILS.
+
+ * tree-cfg.c (gimple_redirect_edge_and_branch): Do
+ gimple_try_redirect_by_replacing_jump test after no-op and EH tests.
+
+ * tree-cfg.c (split_edge_bb_loc): Don't disallow placement at
+ dest_prev if the edge is complex.
+
+ * tree-cfg.c (is_ctrl_stmt): Use a switch.
+
+ * tree-cfg.c (gimple_can_merge_blocks_p): Move label and
+ loop latch tests earlier.
+
+ * gimple-iterator.c (gimple_find_edge_insert_loc): Insert
+ before GIMPLE_RETURN, not after its predecessor; insert
+ before GIMPLE_RESX.
+
+ * gimple-iterator.c (gimple_find_edge_insert_loc): Use
+ gimple_seq_empty_p to test for no PHI nodes.
+ * tree-cfg.c (split_critical_edges): Likewise.
+
+ * c-common.h (c_dialect_cxx, c_dialect_objc): Boolify.
+
+2009-09-10 Hariharan Sandanagobalane <hariharan@picochip.com>
+
+ * final.c (shorten_branches) : Ignore DEBUG_INSN_P instructions
+ introduced by the VTA branch merge.
+
+2009-09-10 Uros Bizjak <ubizjak@gmail.com>
+
+ * ira-conflicts.c: Use fputs or putc instead of fprintf
+ where appropriate.
+ * cfg.c: Ditto.
+ * toplev.c: Ditto.
+ * tree-switch-conversion.c: Ditto.
+
+2009-09-10 Hariharan Sandanagobalane <hariharan@picochip.com>
+
+ * config/picochip/picochip.c : Ignore DEBUG_INSN_P instructions
+ introduced by the VTA branch merge.
+
+2009-09-10 Uros Bizjak <ubizjak@gmail.com>
+
+ Revert:
+ 2009-09-09 Uros Bizjak <ubizjak@gmail.com>
+
+ PR rtl-optimization/39779
+ * expr.c (convert_modes): Return when mode == oldmode after
+ CONST_INTs are processed.
+
+2009-09-10 Nick Clifton <nickc@redhat.com>
+
+ * config/mep/mep.c (mep_encode_section_info): Copy weakness
+ attribute and referring decl when creating renamed symbol.
+
+2009-09-10 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41257
+ * cgraphunit.c (cgraph_emit_thunks): Emit thunks only for
+ reachable nodes.
+ (cgraph_finalize_compilation_unit): Compute reachability
+ before emitting thunks. Properly process aliases before
+ possibly removing unreachable nodes.
+
+2009-09-10 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41254
+ * tree.c (struct free_lang_data_d): Add worklist member.
+ (find_decls_types_r): Push onto the worklist instead of recursing.
+ Handle TREE_BINFOs properly.
+ (find_decls_types): New function wrapped around find_decls_types_r
+ to process the worklist.
+ (find_decls_types_in_eh_region): Use it.
+ (find_decls_types_in_node): Likewise.
+ (find_decls_types_in_var): Likewise.
+ (free_lang_data_in_cgraph): Likewise. Free the worklist.
+ * tree.h (RECORD_OR_UNION_TYPE_P): New.
+ (AGGREGATE_TYPE_P): Adjust.
+
+2009-09-09 Jason Merrill <jason@redhat.com>
+
+ * configure.ac: Check glibc version even if we have an in-tree
+ assembler.
+
+2009-09-09 Anthony Green <green@moxielogic.com>
+
+ * config/moxie/moxie.md (*movsi, *movhi, *movqi): Use xor to load
+ the constant 0 when appropriate.
+ * config/moxie/constraints.md: Add constraint O.
+
+ * config/moxie/moxie.c (moxie_setup_incoming_varargs): Adjust
+ to pass up to 6 32-bit argument values in registers.
+ (moxie_function_arg): Ditto.
+ (moxie_arg_partial_bytes): Ditto.
+ * config/moxie/moxie.h (FUNCTION_ARG_ADVANCE): Ditto.
+ (REG_PARM_STACK_SPACE): Ditto.
+ (FUNCTION_ARG_REGNO_P): Ditto.
+
+ * config/moxie/moxie.c (moxie_expand_prologue): Use dec
+ instruction to allocate stack space.
+
+2009-09-09 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000.md (bswapdi2_64bit): Fix
+ unnecessarily stringent constraints. Fix address
+ calculation in the splitters.
+
+2009-09-09 Uros Bizjak <ubizjak@gmail.com>
+
+ PR rtl-optimization/39779
+ * expr.c (convert_modes): Return when mode == oldmode after
+ CONST_INTs are processed.
+
+2009-09-09 Kai Tietz <kai.tietz@onevision.com>
+
+ PR/41315
+ * config/i386.c (ix86_can_use_return_insn_p): Check for padding0, too.
+ (ix86_expand_prologue): Take frame.padding0 into logic of
+ to_allocate checks.
+ (ix86_expand_epilogue): Likewise.
+
+2009-09-09 Jakub Jelinek <jakub@redhat.com>
+
+ * config/t-slibgcc-elf-ver (SHLIB_MAKE_SOLINK, SHLIB_INSTALL_SOLINK):
+ New variables.
+ (SHLIB_LINK, SHLIB_INSTALL): Use them.
+ * config/t-slibgcc-libgcc: New file.
+ * config.gcc (powerpc*-*-linux*, powerpc*-*-gnu*): Use it.
+
+2009-09-09 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/41089
+ * tree-sra.c (find_var_candidates): Do not consider va_lists in
+ early SRA.
+
+2009-09-09 Richard Henderson <rth@redhat.com>
+
+ * gimple.h (CASE_GIMPLE_OMP): New.
+ (is_gimple_omp): Use it.
+ * tree-cfg.c (is_ctrl_altering_stmt): Likewise.
+ (verify_gimple_debug): Likewise.
+
+2009-09-09 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/41101
+ * tree-ssa-pre.c (maximal_set): Remove.
+ (compute_antic_aux): Treat the maximal set as implicitly all ones.
+ Defer all blocks we didn't visit at least one successor.
+ (add_to_exp_gen): Do not add to the maximal set.
+ (make_values_for_phi): Likewise.
+ (compute_avail): Likewise.
+ (init_pre): Do not allocate the maximal set.
+ (execute_pre): Do not dump it.
+
+2009-09-09 Martin Jambor <mjambor@suse.cz>
+
+ * tree-cfg.c (verify_gimple_phi): Check that gimple_phi_result is
+ an SSA_NAME rather than a is_gimple_variable.
+
+2009-09-09 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41317
+ * tree-ssa-ccp.c (maybe_fold_offset_to_component_ref): Remove
+ code dealing with plain pointer bases.
+ (maybe_fold_offset_to_reference): Likewise.
+ (maybe_fold_stmt_addition): Adjust.
+
+2009-09-09 Richard Guenther <rguenther@suse.de>
+
+ * tree.c (free_lang_data_in_type): Do not free the type variant
+ chains.
+ (free_lang_data): Merge char_type_node with its properly signed
+ variant.
+ (pass_ipa_free): Collect after freeing language specific data.
+
+2009-09-09 Michael Matz <matz@suse.de>
+
+ PR middle-end/41268
+ * cfgexpand.c (expand_gimple_stmt_1): Use an int for storing
+ SUBREG_PROMOTED_UNSIGNED_P, instead of a bool.
+ * rtl.h (struct rtx, SUBREG_PROMOTED_UNSIGNED_P): Update comments
+ to reflect reality.
+
+2009-09-08 DJ Delorie <dj@redhat.com>
+
+ * config/mep/mep.c (conversions[]): Add "ml" pattern.
+
+2009-09-04 Jason Merrill <jason@redhat.com>
+
+ * tree.c (tree_find_value): Remove.
+ * tree.h: Remove prototype.
+ * varasm.c (assemble_external): Use value_member instead.
+
+2009-09-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * toplev.c (process_options): Choose default debugging type when
+ gtoggle enables debug info and type is unset.
+
+2009-09-08 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/41276
+ PR debug/41307
+ * cselib.c (cselib_expand_value_rtx_1): Don't return copy of
+ invalid subreg.
+
+2009-09-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure: Rebuilt with modified libtool.m4.
+
+2009-09-08 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/41229
+ PR debug/41291
+ PR debug/41300
+ * tree-ssa.c (execute_update_addresses_taken): Update debug insns.
+
+2009-09-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * tree-ssa-loop-ivopts.c (get_phi_with_result): Remove.
+ (remove_statement): Likewise.
+ (rewrite_use_nonlinear_expr): Adjust.
+ (remove_unused_ivs): Collect SSA NAMEs to remove and call...
+ * tree-ssa.c (release_defs_bitset): ... this. New.
+ * tree-flow.h (release_defs_bitset): Declare.
+
+2009-09-08 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/41232
+ * tree-ssa-phiopt.c (minmax_replacement): Skip debug stmts
+ in the middle block.
+
+2009-09-08 Kai Tietz <kai.tietz@onevision.com>
+
+ * tree-ssa-reassoc.c (find_operand_rank): Cast pointer
+ via intptr_t to long type.
+ (insert_operand_rank): Cast long type via intptr_t to
+ pointer type.
+ * genattrtab.c (RTL_HASH): Use intptr_t to cast from
+ pointer to scalar.
+ * c-pretty-print.c (pp_c_tree_decl_identifier): Cast
+ from pointer to unsigned via uintptr_t.
+
+ * configure.ac (GCC_STDINT_TYPES): Initialize intptr_t,
+ uintptr_t, HAVE_INTTYPES_H, HAVE_STDINT_H, HAVE_UINTPTR_T,
+ and HAVE_INTPTR_T.
+ * configure: Regenerated.
+ * config.in: Regenerated
+ * system.h (stdint.h): Add include.
+ (inttypes.h): Likewise.
+ * Makefile.in (aclocal): Add config/stdint.m4.
+ * aclocal.m4: Regenerated.
+
+2009-09-08 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * config/bfin/bfin.c (np_check_regno, np_after_branch): New static
+ variables.
+ (note_np_check_stores): New function.
+ (harmless_null_pointer_p): New function.
+ (trapping_loads_p): New args NP_REG and AFTER_NP_BRANCH. Callers
+ changed. Take into account whether we're in the shadow of a condjump
+ that tested NP_REG for NULL.
+ Lose all code that tested for SEQUENCEs.
+ (workaround_speculation): Avoid inserting NOPs for loads that are
+ either always executed or a NULL pointer.
+
+2009-09-08 Jan Hubicka <jh@suse.cz>
+
+ * doc/invoke.texi (early-inlining-insns): Reduce from 12 to 8.
+ * params.def (early-inlining-insns): Likewise.
+
+2009-09-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/41239
+ * sched-int.h (struct deps): Add last_function_call_may_noreturn field.
+ * sched-rgn.c (deps_join): Join also last_function_call_may_noreturn
+ lists.
+ * sched-deps.c (sched_analyze_insn): Prevent moving trapping insns
+ across calls, as the calls might not always return normally.
+ (call_may_noreturn_p): New function.
+ (deps_analyze_insn): Update last_function_call_may_noreturn list.
+ (init_deps): Initialize it.
+ (remove_from_deps): Also remove calls from
+ last_function_call_may_noreturn list.
+
+2009-09-07 Richard Henderson <rth@redhat.com>
+
+ * tree-ssa-sccvn.c (vn_reference_lookup_3): Don't assume there are
+ more VR->OPERANDS than LHS operands. Free LHS before returning.
+
+2009-09-07 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * config/bfin/bfin.md (UNSPEC_VOLATILE_STALL): New constant.
+ (attr "addrtype"): New member "spreg".
+ Use it if mem_spfp_address_operand is true for the address.
+ (attr "type"): New entry "stall".
+ (cpu_unit "load"): New.
+ (insn_reservations "load32", "loadp", "loadi"): Add reservation of
+ "load".
+ (insn_reservation "loadsp"): New.
+ (insn_reservation "load_stall1"): New.
+ (insn_reservation "load_stall3"): New.
+ (stall): New insn.
+ * config/bfin/predicates.md (const1_operand, const3_operand): New.
+ (mem_p_address_operand): Exclude stack and frame pointer based
+ addresses.
+ (mem_spfp_address_operand): New; match them here.
+ * config/bfin/bfin.c (add_sched_insns_for_speculation): New function.
+ (bfin_reorg): Call it if scheduling insns.
+ (bfin_gen_bundles): Remove dummy insns created by
+ add_sched_insns_for_speculation.
+
+ From Jie Zhang <jie.zhang@analog.com>:
+ * config/bfin/bfin-protos.h (enum bfin_cpu_type, bfin_cpu_type,
+ bfin_si_revision, bfin_workarounds): Move these ...
+ * config/bfin/bfin.h: ... here.
+
+ From Mike Frysinger <michael.frysinger@analog.com>
+ * config/bfin/bfin-protos.h (bfin_cpu_type): Add BFIN_CPU_BF542M,
+ BFIN_CPU_BF544M, BFIN_CPU_BF547M, BFIN_CPU_BF548M, and BFIN_CPU_BF549M.
+ * config/bfin/bfin.c (bfin_cpus[]): Add 0.3 for bf542m, bf544m,
+ bf547m, bf548m, and bf549m.
+ * config/bfin/bfin.h (TARGET_CPU_CPP_BUILTINS): Define __ADSPBF542M__
+ for BFIN_CPU_BF542M, __ADSPBF544M__ for BFIN_CPU_BF544M,
+ __ADSPBF547M__ for BFIN_CPU_BF547M, __ADSPBF548M__ for
+ BFIN_CPU_BF548M, and __ADSPBF549M__ for BFIN_CPU_BF549M.
+ * config/bfin/t-bfin-elf (MULTILIB_MATCHES): Select bf532-none for
+ bf542m-none, bf544m-none, bf547m-none, bf548m-none, and bf549m-none.
+ * config/bfin/t-bfin-linux (MULTILIB_MATCHES): Likewise.
+ * config/bfin/t-bfin-uclinux (MULTILIB_MATCHES): Likewise.
+ * doc/invoke.texi (Blackfin Options): Document that -mcpu now accepts
+ bf542m, bf544m, bf547m, bf548m, and bf549m.
+
+ From Jie Zhang <jie.zhang@analog.com>:
+ * config/bfin/predicates.md (p_register_operand): New predicate.
+ (dp_register_operand): New predicate.
+ * config/bfin/bfin-protos.h (WA_05000074): Define.
+ (ENABLE_WA_05000074): Define.
+ * config/bfin/bfin.c (bfin_cpus[]): Add WA_05000074 for all cpus.
+ (bfin_gen_bundles): Put dsp32shiftimm instruction in slot[0].
+ * config/bfin/bfin.md (define_attr type): Add dsp32shiftimm.
+ (define_attr addrtype): Allow load/store register to be P register.
+ (define_attr storereg): New.
+ (define_cpu_unit anomaly_05000074): New.
+ (define_insn_reservation dsp32shiftimm): New.
+ (define_insn_reservation dsp32shiftimm_anomaly_05000074): New.
+ (define_insn_reservation loadp): Cannot use slot2.
+ (define_insn_reservation loadsp): Cannot use slot2.
+ (define_insn_reservation storep): Cannot use slot2. Does not
+ apply when working around 05000074.
+ (define_insn_reservation storep_anomaly_05000074): New.
+ (define_insn_reservation storei): Does not apply when working
+ around 05000074.
+ (define_insn_reservation storei_anomaly_05000074): New.
+ (define_attr length): Add dsp32shiftimm case.
+ (define_insn movsi_insn32, movsi_insv, ashlsi3_insn, ashrsi3,
+ ror_one, rol_one, lshrsi3, lshrpdi3, ashrpdi3, movhiv2hi_low,
+ movhiv2hi_high, composev2hi, packv2hi, movv2hi_hi,
+ ssashiftv2hi3, ssashifthi3, ssashiftsi3, lshiftv2hi3, lshifthi3):
+ Set type as dsp32shiftimm for dsp32shiftimm alternatives.
+
+2009-09-07 Martin Jambor <mjambor@suse.cz>
+
+ PR middle-end/41282
+ * tree-sra.c (create_artificial_child_access): Return NULL if
+ build_ref_for_offset fails.
+ (propagate_subacesses_accross_link): Allow build_ref_for_offset
+ and create_artificial_child_access to fail.
+
+2009-09-06 Dmitry Gorbachev <d.g.gorbachev@gmail.com>
+
+ PR c++/41214
+ * unwind-dw2.c (uw_init_context_1): Mark noinline.
+ * config/ia64/unwind-ia64.c (uw_init_context_1): Likewise.
+ * config/xtensa/unwind-dw2-xtensa.c (uw_init_context_1): Likewise.
+
+2009-09-07 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * config/bfin/bfin.c (bfin_optimize_loop): When creating a new basic
+ block, ensure it has an exit edge. Emit a barrier after a jump.
+
+2009-09-07 Nick Clifton <nickc@redhat.com>
+
+ * gcc.c (this_is_linker_script): New variable. Like
+ this_is_library_file but for the %T constructor.
+ (end_going_arg): If this_is_linker_script is set then locate the
+ script and insert a --script switch before it
+ (do_spec_2): Initialise this_is_linker_script.
+ (do_spec_1): Likewise. Handle %T construct.
+ (eval_spec_function): Preserve this_is_linker_script.
+ * doc/invoke.texi: Document %T construct in spec files.
+ * config/m32c/m32c.h (LIB_SPEC): Use it.
+
+2009-09-07 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * rtl.h (PREFETCH_SCHEDULE_BARRIER_P): New macro.
+ * sched-deps.c (sched_analyze_2): Make prefetches a hard barrier
+ when volatile flag is set.
+ * doc/rtl.texi (PREFETCH_SCHEDULE_BARRIER_P): Add documentation pieces.
+
+2009-09-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR bootstrap/41241
+ * combine-stack-adj.c (try_apply_stack_adjustment): Handle stores.
+ (combine_stack_adjustments_for_block): Allow insns between stack
+ adjustments and stores with corresponding pre-(dec|inc)rement or
+ pre-modify operation.
+
+2009-09-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR bootstrap/41241
+ * combine-stack-adj.c (struct csa_memlist): Rename to...
+ (struct csa_reflist): ... this. Rename mem field to ref.
+ (free_csa_memlist): Rename to...
+ (free_csa_reflist): ... this.
+ (record_one_stack_memref): Rename to...
+ (record_one_stack_ref): ... this. Handle also REG_P.
+ (try_apply_stack_adjustment): Handle also REG_P.
+ (struct record_stack_memrefs_data): Rename to...
+ (struct record_stack_refs_data): ... this. Rename memlist field to
+ reflist.
+ (record_stack_memrefs): Rename to...
+ (record_stack_refs): ... this. For DEBUG_INSNs keep traversing
+ subexpressions instead of failing when a MEM contains SP references.
+ For SP itself in DEBUG_INSNs queue it also onto reflist chain.
+ (combine_stack_adjustments_for_block): Adjust for mem to ref renaming.
+
+2009-09-06 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41144
+ * tree.c (build_array_type): Do not record types marked
+ with structural equality in the canonical type hashtable.
+
+2009-09-06 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41261
+ * tree-ssa-alias.c (refs_may_alias_p_1): Bail out for function decls.
+
+2009-09-05 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41181
+ * tree-ssa-ccp.c (maybe_fold_stmt_addition): Use the correct type.
+
+2009-09-05 Richard Guenther <rguenther@suse.de>
+
+ PR debug/41273
+ * tree-ssa-operands.c (get_tmr_operands): Pass through opf_no_vops.
+
+2009-09-05 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41271
+ * tree-ssa.c (useless_type_conversion_p): Drop qualifiers
+ before comparing function argument types.
+
+2009-09-05 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR target/41024
+ * config/i386/mingw-w64.h (ASM_SPEC): Pass -v instead of -V to
+ the assembler.
+
+2009-09-04 Uros Bizjak <ubizjak@gmail.com>
+
+ Revert:
+ 2009-08-18 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.c (alpha_output_mi_thunk_osf): Allocate insn
+ locators before emit_insn is called.
+
+2009-09-04 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR bootstrap/41241
+ * ira.c (update_equiv_reg): Revert my previous patch for the PR.
+ * reginfo.c (resize_reg_info): Call allocate_reg_info if necessary.
+ (reginfo_init): Don't call allocate_reg_info.
+
+2009-09-04 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/41262
+ * config/alpha/alpha.c (alpha_does_function_need_gp): Use
+ NONDEBUG_INSN_P instead of INSN_P.
+
+2009-09-04 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/41225
+ * tree-vect-stmts.c (vect_stmt_relevant_p): Skip debug uses.
+
+2009-09-04 Alexandre Oliva <aoliva@redhat.com>
+
+ PR target/41252
+ * config/arm/vfp.md (*cmpdf_split_vfp): Fix src mode in the second
+ pattern of the split.
+
+2009-09-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * toplev.c (process_options): Move setter of flag_var_tracking
+ before other tests that depend on it. Move down setter of
+ flag_rename_registers. Don't enable var-tracking-assignments
+ by default if selective scheduling is enabled. Warn if both
+ are enabled.
+
+2009-09-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * var-tracking.c (dv_is_decl_p): Adjust NULL behavior to match
+ comment. Use switch statement to catch overlaps between rtx
+ and tree codes. Accept FUNCTION_DECLs in addition to those in...
+ (IS_DECL_CODE): ... here. Remove.
+ (check_value_is_not_decl): Remove.
+ (dv_from_decl, dv_from_value): Check after conversion.
+
+2009-09-04 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41257
+ * (cgraph_finalize_compilation_unit): Move finalizing aliases
+ after emitting tunks. Move emitting thunks and ctors from ...
+ (cgraph_optimize): ... here. Remove redundant
+ cgraph_analyze_functions.
+ * varasm.c (find_decl_and_mark_needed): Remove no longer
+ necessary check.
+ (finish_aliases_1): Adjust check for thunk aliases.
+
+2009-09-04 Daniel Gutson <dgutson@codesourcery.com>
+
+ * config/arm/arm.md (ctzsi2): Added braces
+ to avoid warning that broke booststrap.
+
+2009-09-04 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/41112
+ * tree-sra.c (build_ref_for_offset_1): Signal that we cannot
+ handle variable-bounded arrays.
+ (expr_with_var_bounded_array_refs_p): New function.
+ (analyze_access_subtree): Call expr_with_var_bounded_array_refs_p.
+
+2009-09-04 Wolfgang Gellerich <gellerich@de.ibm.com>
+
+ * config/s390/2097.md: Removed two incorrect bypasses.
+ (z10_fsimpdf): Fixed latency.
+ (z10_fhex): New insn_reservation.
+ (z10_floaddf): Fixed latency.
+ (z10_floadsf): Fixed latency.
+ (z10_ftrunctf): Fixed latency.
+ (z10_ftruncdf): Fixed latency.
+ * config/s390/s390.c (z10_cost): Fixed values.
+ (s390_adjust_priority): Added z10 path.
+ * config/s390/s390.md (type): Added fhex.
+ (*mov<mode>_64dfp): Updated type attribute.
+ (*mov<mode>_64): Updated type attribute.
+ (*mov<mode>_31): Updated type attribute.
+ (*mov<mode>"): Likewise.
+ * config/s390/2084.md (x_fsimpdf): Updated condition.
+
+2009-09-04 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.md ("*fmadd<mode>", "*fmsub<mode>"): Enable mem
+ RTXs in the predicate for operand 1.
+
+2009-09-03 Daniel Gutson <dgutson@codesourcery.com>
+
+ * config/arm/arm.md (UNSPEC_RBIT): New constant.
+ (rbitsi2): New insn.
+ (ctzsi2): New expand.
+ * config/arm/arm.h (CTZ_DEFINED_VALUE_AT_ZERO): New macro.
+
2009-09-03 Martin Jambor <mjambor@suse.cz>
* tree-sra.c (duplicate_expr_for_different_base): Removed.
(create_artificial_child_access): Use build_ref_for_offset instead
of duplicate_expr_for_different_base.
(propagate_subacesses_accross_link): Likewise.
-
+
2009-09-03 Richard Sandiford <rdsandiford@googlemail.com>
* config/mips/mips.c (USEFUL_INSN_P): Use NONDEBUG_INSN_P instead
@@ -78,39 +1660,18 @@
2009-09-03 Razya Ladelsky <razya@il.ibm.com>
* tree-parloops.c (separate_decls_in_region): Add space.
-
+
2009-09-03 Razya Ladelsky <razya@il.ibm.com>
- * tree-parloops.c (separate_decls_in_region): Change the condition
+ * tree-parloops.c (separate_decls_in_region): Change the condition
checking if there are reductions in the loop.
2009-09-03 Razya Ladelsky <razya@il.ibm.com>
PR tree-optimization/38275
-
- * tree-parloops.c (parallelize_loops): Replace profitability condition
+ * tree-parloops.c (parallelize_loops): Replace profitability condition
for expected number of iterations.
-2009-09-03 Alon Dayan <alond@il.ibm.com>
-
- PR tree-optimization/38275
-
- * testsuite/gcc.dg/autopar/reduc-1char.c: Increase number
- of iterations. Adjust the logic accordingly.
- * testsuite/gcc.dg/autopar/reduc-2char.c: Ditto.
- * testsuite/gcc.dg/autopar/reduc-1.c: Ditto.
- * testsuite/gcc.dg/autopar/reduc-2.c: Ditto.
- * testsuite/gcc.dg/autopar/reduc-3.c: Ditto.
- * testsuite/gcc.dg/autopar/reduc-6.c: Ditto.
- * testsuite/gcc.dg/autopar/reduc-7.c: Ditto.
- * testsuite/gcc.dg/autopar/reduc-8.c: Ditto.
- * testsuite/gcc.dg/autopar/reduc-9.c: Ditto.
- * testsuite/gcc.dg/autopar/pr39500-1.c: Ditto.
- * testsuite/gcc.dg/autopar/reduc-1short.c: Ditto.
- * testsuite/gcc.dg/autopar/reduc-2short.c: Ditto.
- * testsuite/gcc.dg/autopar/parallelization-1.c: Ditto.
-
-
2009-09-03 Alexandre Oliva <aoliva@redhat.com>
* doc/invoke.texi (BUILD_CONFIG): Document --with-build-config.
@@ -238,8 +1799,7 @@
expand_expr_real_2): Declare.
* expr.c (emit_storent_insn, expand_expr_real_1,
expand_expr_real_2): Export.
- (store_expr): Setting and evaluating dont_return_target is
- useless.
+ (store_expr): Setting and evaluating dont_return_target is useless.
(expand_expr_real_1, <case GOTO_EXPR, RETURN_EXPR, SWITCH_EXPR,
LABEL_EXPR and ASM_EXPR>): Move to gcc_unreachable.
* except.c (expand_resx_expr): Rename to ...
@@ -275,11 +1835,11 @@
* doc/invoke.texi (-fsched-pressure): Document it.
(-fsched-reg-pressure-heuristic): Remove it.
-
+
* reload.c (ira.h): Include.
(find_reloads): Add choosing reload on number of small spilled
classes.
-
+
* haifa-sched.c (ira.h): Include.
(sched_pressure_p, sched_regno_cover_class, curr_reg_pressure,
saved_reg_pressure, curr_reg_live, saved_reg_live,
@@ -296,8 +1856,7 @@
(update_register_pressure, setup_insn_max_reg_pressure,
update_reg_and_insn_max_reg_pressure,
sched_setup_bb_reg_pressure_info): New functions.
- (schedule_insn): Add code for printing and updating reg pressure
- info.
+ (schedule_insn): Add code for printing and updating reg pressure info.
(find_set_reg_weight, find_insn_reg_weight): Remove.
(ok_for_early_queue_removal): Do nothing if pressure_only_p.
(debug_ready_list): Print reg pressure info.
@@ -308,7 +1867,7 @@
(fix_tick_ready): Make insn always ready if pressure_p.
(init_h_i_d): Don't call find_insn_reg_weight.
(haifa_finish_h_i_d): Free insn reg pressure info.
-
+
* ira-int.h (ira_hard_regno_cover_class, ira_reg_class_nregs,
ira_memory_move_cost, ira_class_hard_regs,
ira_class_hard_regs_num, ira_no_alloc_regs,
@@ -344,7 +1903,7 @@
implicit sets when clearing reg_last_in_use.
(init_deps_global): Clear implicit_reg_pending_clobbers and
implicit_reg_pending_uses.
-
+
* ira.h (ira_hard_regno_cover_class, ira_reg_class_nregs,
ira_memory_move_cost, ira_class_hard_regs,
ira_class_hard_regs_num, ira_no_alloc_regs,
@@ -352,7 +1911,7 @@
ira_reg_class_cover, ira_class_translate): Move from ira-int.h.
(ira_setup_eliminable_regset, ira_set_pseudo_classes,
ira_implicitly_set_insn_hard_regs): New prototypes.
-
+
* ira-costs.c (pseudo_classes_defined_p, allocno_p,
cost_elements_num): New variables.
(allocno_costs, total_costs): Rename to costs and
@@ -363,8 +1922,7 @@
(common_classes): Rename to regno_cover_class.
(COST_INDEX): New.
(record_reg_classes): Set allocno attributes only if allocno_p.
- (record_address_regs): Ditto. Use COST_INDEX instead of
- ALLOCNO_NUM.
+ (record_address_regs): Ditto. Use COST_INDEX instead of ALLOCNO_NUM.
(scan_one_insn): Use COST_INDEX and COSTS instead of ALLOCNO_NUM
and COSTS_OF_ALLOCNO.
(print_costs): Rename to print_allocno_costs.
@@ -388,10 +1946,9 @@
(resize_reg_info): Change return type.
(reg_cover_class): New.
(setup_reg_classes): Add new parameter.
-
+
* sched-int.h (struct deps_reg): New member implicit_sets.
- (sched_pressure_p, sched_regno_cover_class): New external
- definitions.
+ (sched_pressure_p, sched_regno_cover_class): New external definitions.
(INCREASE_BITS): New macro.
(struct reg_pressure_data, struct reg_use_data): New.
(struct _haifa_insn_data): Remove reg_weight. Add members
@@ -403,12 +1960,11 @@
(struct reg_pressure_data, struct reg_use_data): New.
(INSN_REG_WEIGHT): Remove.
(INSN_REG_PRESSURE, INSN_MAX_REG_PRESSURE, INSN_REG_USE_LIST,
- INSN_REG_SET_LIST, INSN_REG_PRESSURE_EXCESS_COST_CHANGE): New
- macros.
+ INSN_REG_SET_LIST, INSN_REG_PRESSURE_EXCESS_COST_CHANGE): New macros.
(sched_init_region_reg_pressure_info,
sched_setup_bb_reg_pressure_info): New prototypes.
-
- * reginfo.c (struct reg_pref): New member coverclass.
+
+ * reginfo.c (struct reg_pref): New member coverclass.
(reg_cover_class): New function.
(reginfo_init, pass_reginfo_init): Move after free_reg_info.
(reg_info_size): New variable.
@@ -416,16 +1972,16 @@
(resize_reg_info): Use reg_info_size. Return flag of resizing.
(setup_reg_classes): Add a new parameter. Setup cover class too.
- * Makefile.in (reload.o, haifa-sched.o, sched-deps.o): Add ira.h to the
- dependencies.
+ * Makefile.in (reload.o, haifa-sched.o, sched-deps.o): Add ira.h to
+ the dependencies.
* sched-rgn.c (deps_join): Set up implicit_sets.
(schedule_region): Set up region and basic blocks pressure
relative info.
-
+
* passes.c (init_optimization_passes): Move
pass_subregs_of_mode_init before pass_sched.
-
+
2009-09-02 Martin Jambor <mjambor@suse.cz>
* tree-sra.c (struct access): New field grp_hint.
@@ -459,7 +2015,7 @@
Revert:
2009-07-31 Christian Bruel <christian.bruel@st.com>
* gcc/config.gcc (sh*-*-elf): test with_libgloss.
-
+
2009-09-01 Alexandre Oliva <aoliva@redhat.com>
* doc/invoke.texi (-fvar-tracking-assignments): New.
@@ -472,8 +2028,7 @@
* regrename.c (regrename_optimize): Drop last. Don't count debug
insns as uses. Don't reject change because of debug insn.
(do_replace): Reject DEBUG_INSN as chain starter. Take base_regno
- from the chain starter, and check for inexact matches in
- DEBUG_INSNS.
+ from the chain starter, and check for inexact matches in DEBUG_INSNS.
(scan_rtx_reg): Accept inexact matches in DEBUG_INSNs.
(build_def_use): Simplify and fix the marking of DEBUG_INSNs.
* sched-ebb.c (schedule_ebbs): Skip boundary debug insns.
@@ -512,7 +2067,7 @@
* rtlanal.c (reg_used_between_p): Skip debug insns.
(side_effects_p): Likewise.
(canonicalize_condition): Likewise.
- * ddg.c (create_ddg_dep_from_intra_loop_link): Check that non-debug
+ * ddg.c (create_ddg_dep_from_intra_loop_link): Check that non-debug
insns never depend on debug insns.
(create_ddg_dep_no_link): Likewise.
(add_cross_iteration_register_deps): Use ANTI_DEP for debug insns.
@@ -551,7 +2106,7 @@
(contributes_to_priority): Skip debug insns.
(dep_list_size): New.
(priority): Use it.
- (rank_for_schedule): Likewise. Schedule debug insns as soon as
+ (rank_for_schedule): Likewise. Schedule debug insns as soon as
they're ready. Disregard previous debug insns to make decisions.
(queue_insn): Never queue debug insns.
(ready_add, ready_remove_first, ready_remove): Count debug insns.
@@ -620,8 +2175,7 @@
(fur_orig_expr_not_found): Skip debug insns.
* rtl.def (VALUE): Move up.
(DEBUG_INSN): New.
- * tree-ssa-sink.c (all_immediate_uses_same_place): Skip debug
- stmts.
+ * tree-ssa-sink.c (all_immediate_uses_same_place): Skip debug stmts.
(nearest_common_dominator_of_uses): Take debug_stmts argument.
Set it if debug stmts are found.
(statement_sink_location): Skip debug stmts. Propagate
@@ -657,7 +2211,7 @@
val_long_long change to CONST_DOUBLE rtx from a long hi/lo pair.
(output_die): Likewise. Use HOST_BITS_PER_WIDE_INT size of each
component instead of HOST_BITS_PER_LONG.
- (output_loc_operands): Likewise. For const8* assert
+ (output_loc_operands): Likewise. For const8* assert
HOST_BITS_PER_WIDE_INT rather than HOST_BITS_PER_LONG is >= 64.
(output_loc_operands_raw): For const8* assert HOST_BITS_PER_WIDE_INT
rather than HOST_BITS_PER_LONG is >= 64.
@@ -691,8 +2245,7 @@
in its expression.
* cfgbuild.c (inside_basic_block_p): Handle debug insns.
(control_flow_insn_p): Likewise.
- * tree-parloops.c (eliminate_local_variables_stmt): Handle debug
- stmt.
+ * tree-parloops.c (eliminate_local_variables_stmt): Handle debug stmt.
(separate_decls_in_region_debug_bind): New.
(separate_decls_in_region): Process debug bind stmts afterwards.
* recog.c (verify_changes): Handle debug insns.
@@ -725,8 +2278,7 @@
* function.c (instantiate_virtual_regs): Handle debug insns.
* function.h (struct emit_status): Add x_cur_debug_insn_uid.
* print-rtl.h: Include cselib.h.
- (print_rtx): Print VALUEs. Split out and recurse for
- VAR_LOCATIONs.
+ (print_rtx): Print VALUEs. Split out and recurse for VAR_LOCATIONs.
* df.h (df_inns_rescan_debug_internal): Declare.
* gcse.c (alloc_hash_table): Estimate n_insns.
(cprop_insn): Don't regard debug insns as changes.
@@ -827,8 +2379,7 @@
(cselib_subst_to_values): Adjust.
(cselib_log_lookup): New.
(cselib_lookup): Call it.
- (cselib_invalidate_regno): Don't count preserved values as
- useless.
+ (cselib_invalidate_regno): Don't count preserved values as useless.
(cselib_invalidate_mem): Likewise.
(cselib_record_set): Likewise.
(struct set): Renamed to cselib_set, moved to cselib.h.
@@ -947,8 +2498,7 @@
(copy_body): Copy debug stmts at the end.
(insert_init_debug_bind): New.
(insert_init_stmt): Take id. Skip and emit debug stmts.
- (setup_one_parameter): Remap variable earlier, register debug
- mapping.
+ (setup_one_parameter): Remap variable earlier, register debug mapping.
(estimate_num_insns): Skip debug stmts.
(expand_call_inline): Preserve debug_map.
(optimize_inline_calls): Check for no debug_stmts left-overs.
@@ -1057,8 +2607,7 @@
(dataflow_set_clear_at_call): New.
(onepart_variable_different_p): New.
(variable_different_p): Use it.
- (dataflow_set_different_1): Adjust. Make detailed dump
- more verbose.
+ (dataflow_set_different_1): Adjust. Make detailed dump more verbose.
(track_expr_p): Add need_rtl parameter. Don't generate rtl
if not needed.
(track_loc_p): Pass it true.
@@ -1106,8 +2655,8 @@
(emit_notes_for_differences_1): Adjust. Handle values.
(emit_notes_for_differences_2): Likewise.
(emit_notes_for_differences): Adjust.
- (emit_notes_in_bb): Take pointer to set. Emit AFTER_CALL_INSN
- notes. Adjust. Handle new micro-ops.
+ (emit_notes_in_bb): Take pointer to set. Emit AFTER_CALL_INSN notes.
+ Adjust. Handle new micro-ops.
(vt_add_function_parameters): Adjust. Create and bind values.
(vt_initialize): Adjust. Initialize scratch_regs and
valvar_pool, flooded and perm.. Initialize and use cselib. Log
@@ -1146,7 +2695,7 @@
and var needs to be modified.
(dataflow_set_union): Set traversed_vars during canonicalization.
(VALUE_CHANGED, DECL_CHANGED): Define.
- (set_dv_changed, dv_changed_p): New static inlines.
+ (set_dv_changed, dv_changed_p): New static inlines.
(track_expr_p): Clear DECL_CHANGED.
(dump_dataflow_sets): Set it.
(variable_was_changed): Call set_dv_changed.
@@ -1157,8 +2706,7 @@
empty. Traverse changed_variables with check_changed_vars_1,
call check_changed_vars_2 on each changed_variables_stack entry.
(emit_notes_in_bb): Add SET argument. Just clear it at the
- beginning, use it instead of local &set, don't destroy it at the
- end.
+ beginning, use it instead of local &set, don't destroy it at the end.
(vt_emit_notes): Call dataflow_set_clear early on all
VTI(bb)->out sets, never use them, instead use emit_notes_in_bb
computed set, dataflow_set_clear also VTI(bb)->in when we are
@@ -1185,12 +2733,10 @@
(print-rtl.o): Depend on cselib.h.
(cselib.o): Depend on TREE_PASS_H.
(var-tracking.o): Depend on cselib.h and TARGET_H.
- * sched-rgn.c (rgn_estimate_number_of_insns): Discount
- debug insns.
+ * sched-rgn.c (rgn_estimate_number_of_insns): Discount debug insns.
(init_ready_list): Skip boundary debug insns.
(add_branch_dependences): Skip debug insns.
- (free_block_dependencies): Check for blocks with only debug
- insns.
+ (free_block_dependencies): Check for blocks with only debug insns.
(compute_priorities): Likewise.
* gimple.c (gss_for_code): Handle GIMPLE_DEBUG.
(gimple_build_with_ops_stat): Take subcode as unsigned. Adjust
@@ -1230,13 +2776,11 @@
(verify_stmt): Likewise.
(debug_loop_num): Skip debug stmts.
(remove_edge_and_dominated_blocks): Remove dominators last.
- * tree-ssa-reasssoc.c (rewrite_expr_tree): Propagate into
- debug stmts.
+ * tree-ssa-reasssoc.c (rewrite_expr_tree): Propagate into debug stmts.
(linearize_expr): Likewise.
* config/i386/i386.c (ix86_delegitimize_address): Call
default implementation.
- * config/ia64/ia64.c (ia64_safe_itanium_class): Handle debug
- insns.
+ * config/ia64/ia64.c (ia64_safe_itanium_class): Handle debug insns.
(group_barrier_needed): Skip debug insns.
(emit_insn_group_barriers): Likewise.
(emit_all_insn_group_barriers): Likewise.
@@ -1264,8 +2808,7 @@
* dce.c (deletable_insn_p): Handle VAR_LOCATION.
(mark_reg_dependencies): Skip debug insns.
* params.def (PARAM_MIN_NONDEBUG_INSN_UID): New.
- * tree-ssanames.c (release_ssa_name): Propagate def into
- debug stmts.
+ * tree-ssanames.c (release_ssa_name): Propagate def into debug stmts.
* tree-ssa-threadedge.c
(record_temporary_equivalences_from_stmts): Skip debug stmts.
* regcprop.c (replace_oldest_value_addr): Skip debug insns.
@@ -1283,7 +2826,7 @@
2009-09-01 Richard Henderson <rth@redhat.com>
- * tree-ssa-ccp.c (ccp_initialize): Make sure to simulate
+ * tree-ssa-ccp.c (ccp_initialize): Make sure to simulate
stmt_ends_pp_p statements at least once.
* tree-vrp.c (vrp_initialize): Likewise.
(vrp_visit_stmt): Be prepared for non-interesting stmts.
@@ -1390,7 +2933,6 @@
(mep_return_in_memory): Zero-sized objects are passed in memory.
(mep_reorg_noframe): Make sure we have accurate REG_DEAD notes.
-
2009-08-31 Richard Guenther <rguenther@suse.de>
* builtins.c (fold_builtin_memory_op): Use the alias oracle
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index ff037f0ee12..f2c55ce9897 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20090903
+20090917
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 9c9a4e37288..3b2b14c4f5b 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -856,7 +856,7 @@ RECOG_H = recog.h
ALIAS_H = alias.h coretypes.h
EMIT_RTL_H = emit-rtl.h
FLAGS_H = flags.h options.h
-FUNCTION_H = function.h $(TREE_H) $(HASHTAB_H) varray.h
+FUNCTION_H = function.h $(TREE_H) $(HASHTAB_H) vecprim.h
EXPR_H = expr.h insn-config.h $(FUNCTION_H) $(RTL_H) $(FLAGS_H) $(TREE_H) $(MACHMODE_H) $(EMIT_RTL_H)
OPTABS_H = optabs.h insn-codes.h
REGS_H = regs.h varray.h $(MACHMODE_H) $(OBSTACK_H) $(BASIC_BLOCK_H) $(FUNCTION_H)
@@ -1623,6 +1623,7 @@ aclocal_deps = \
$(srcdir)/../config/lib-prefix.m4 \
$(srcdir)/../config/override.m4 \
$(srcdir)/../config/progtest.m4 \
+ $(srcdir)/../config/stdint.m4 \
$(srcdir)/../config/unwind_ipinfo.m4 \
$(srcdir)/../config/warnings.m4 \
$(srcdir)/acinclude.m4
@@ -1910,7 +1911,7 @@ c-errors.o: c-errors.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
c-parser.o : c-parser.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(GGC_H) $(TIMEVAR_H) $(C_TREE_H) $(INPUT_H) $(FLAGS_H) $(TOPLEV_H) output.h \
$(CPPLIB_H) gt-c-parser.h $(RTL_H) langhooks.h $(C_COMMON_H) $(C_PRAGMA_H) \
- vec.h $(TARGET_H) $(CGRAPH_H) $(PLUGIN_H)
+ vec.h $(TARGET_H) $(CGRAPH_H) $(PLUGIN_H) $(EXCEPT_H)
srcextra: gcc.srcextra lang.srcextra
@@ -2128,7 +2129,7 @@ gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
hard-reg-set.h $(BASIC_BLOCK_H) cselib.h $(INSN_ADDR_H) $(OPTABS_H) \
libfuncs.h debug.h $(GGC_H) $(CGRAPH_H) $(TREE_FLOW_H) reload.h \
$(CPP_ID_DATA_H) tree-chrec.h $(CFGLAYOUT_H) $(EXCEPT_H) output.h \
- $(CFGLOOP_H)
+ $(CFGLOOP_H) $(TARGET_H)
ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(GGC_H) $(HASHTAB_H) $(TOPLEV_H) $(PARAMS_H) hosthooks.h \
@@ -2164,10 +2165,11 @@ langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
intl.h $(GIMPLE_H)
tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
all-tree.def $(FLAGS_H) $(FUNCTION_H) $(PARAMS_H) \
- $(TOPLEV_H) $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
- $(REAL_H) gt-tree.h $(TREE_INLINE_H) tree-iterator.h $(BASIC_BLOCK_H) \
- $(TREE_FLOW_H) $(OBSTACK_H) pointer-set.h fixed-value.h tree-pass.h \
- langhooks-def.h $(DIAGNOSTIC_H) $(CGRAPH_H) $(TIMEVAR_H) except.h debug.h
+ $(TOPLEV_H) $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) \
+ langhooks.h $(REAL_H) gt-tree.h $(TREE_INLINE_H) tree-iterator.h \
+ $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(OBSTACK_H) pointer-set.h fixed-value.h \
+ tree-pass.h langhooks-def.h $(DIAGNOSTIC_H) $(CGRAPH_H) $(TIMEVAR_H) \
+ $(EXCEPT_H) debug.h
tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TOPLEV_H) $(SPLAY_TREE_H) $(TREE_DUMP_H) \
tree-iterator.h $(TREE_PASS_H) $(DIAGNOSTIC_H) $(REAL_H) fixed-value.h
@@ -2768,7 +2770,7 @@ simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
langhooks.h $(TOPLEV_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \
gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
- $(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) value-prof.h
+ $(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) value-prof.h $(EXCEPT_H)
cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) $(TOPLEV_H) $(FLAGS_H) $(GGC_H) \
$(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
@@ -2892,8 +2894,9 @@ tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_H) \
$(TREE_DUMP_H) $(BASIC_BLOCK_H) $(TREE_PASS_H) langhooks.h \
tree-ssa-propagate.h value-prof.h $(FLAGS_H) $(TARGET_H) $(TOPLEV_H)
tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h alloc-pool.h \
- $(TM_H) $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) $(IPA_PROP_H) $(DIAGNOSTIC_H) \
- statistics.h $(TREE_DUMP_H) $(TIMEVAR_H) $(PARAMS_H) $(TARGET_H) $(FLAGS_H)
+ $(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) $(IPA_PROP_H) \
+ $(DIAGNOSTIC_H) statistics.h $(TREE_DUMP_H) $(TIMEVAR_H) $(PARAMS_H) \
+ $(TARGET_H) $(FLAGS_H)
tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \
$(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \
@@ -2974,7 +2977,7 @@ cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TIMEVAR_H) $(OBSTACK_H) $(TOPLEV_H) vecprim.h
cfgbuild.o : cfgbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h $(TOPLEV_H) \
- $(FUNCTION_H) $(EXCEPT_H) $(TIMEVAR_H) $(TREE_H)
+ $(FUNCTION_H) $(EXCEPT_H) $(TIMEVAR_H) $(TREE_H) $(EXPR_H)
cfgcleanup.o : cfgcleanup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TIMEVAR_H) hard-reg-set.h output.h $(FLAGS_H) $(RECOG_H) \
$(TOPLEV_H) insn-config.h cselib.h $(TARGET_H) $(TM_P_H) $(PARAMS_H) \
@@ -3465,6 +3468,7 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
$(host_xm_file_list) \
$(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) $(srcdir)/bitmap.h \
$(srcdir)/alias.h $(srcdir)/coverage.c $(srcdir)/rtl.h \
+ $(srcdir)/vecprim.h \
$(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/varray.h $(srcdir)/libfuncs.h $(SYMTAB_H) \
$(srcdir)/real.h $(srcdir)/function.h $(srcdir)/insn-addr.h $(srcdir)/hwint.h \
$(srcdir)/fixed-value.h \
diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4
index b351de25465..81108ded7e4 100644
--- a/gcc/aclocal.m4
+++ b/gcc/aclocal.m4
@@ -114,6 +114,7 @@ m4_include([../config/lib-link.m4])
m4_include([../config/lib-prefix.m4])
m4_include([../config/override.m4])
m4_include([../config/progtest.m4])
+m4_include([../config/stdint.m4])
m4_include([../config/unwind_ipinfo.m4])
m4_include([../config/warnings.m4])
m4_include([acinclude.m4])
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 9b92ce5f4df..1e4d3db4f95 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,238 @@
+2009-09-17 Bob Duff <duff@adacore.com>
+
+ * g-socket.ads: Document the fact that Close_Selector has no effect on
+ a closed selector.
+ * g-socket.adb: Raise an exception when a Selector that should be open
+ is closed.
+ (Check_Selector): Declare RSig as a constant rather than a renames,
+ less confusing.
+
+2009-09-17 Robert Dewar <dewar@adacore.com>
+
+ * exp_ch9.adb, exp_ch5.adb, exp_ch4.adb, prj-conf.adb, prj-env.ads,
+ prj-ext.adb, prj-ext.ads, prj-pars.adb, prj-part.adb, prj-proc.adb,
+ prj-tree.ads: Minor reformatting
+
+2009-09-17 Emmanuel Briot <briot@adacore.com>
+
+ * prj-conf.adb, prj-env.adb, prj-env.ads (Create_Temp_File): Moved to
+ spec.
+ (Do_Autoconf): If the object directory does not exists, create auto.cgpr
+ in a temporary directory instead
+
+2009-09-17 Bob Duff <duff@adacore.com>
+
+ * a-dynpri.adb (Set_Priority): Don't do anything if the task is already
+ terminated.
+ (Get_Priority): Correct message for "terminated" case -- it said "null".
+
+2009-09-17 Robert Dewar <dewar@adacore.com>
+
+ * exp_ch6.adb: Minor reformatting
+
+2009-09-17 Emmanuel Briot <briot@adacore.com>
+
+ * gnatcmd.adb, make.adb, prj-part.adb, prj-ext.adb, prj-ext.ads,
+ switch-m.adb, switch-m.ads, clean.adb, prj-tree.ads
+ (Project_Node_Tree_Data.Project_Path): New field.
+
+ * prj-conf.adb (Do_Autoconf): Remove "creating auto.cgpr" message
+
+2009-09-17 Emmanuel Briot <briot@adacore.com>
+
+ * prj-ext.adb, prj-ext.ads, makeutl.adb (Is_External_Assignment):
+ Remove duplicate code.
+ (Prj.Ext): Fix memory leak
+ (Check): Now allow the syntax "-Xfoo=" to set an empty value to the
+ variable. This was previously allowed in the code in
+ Is_External_Assignment, and some tests rely on it
+
+2009-09-17 Bob Duff <duff@adacore.com>
+
+ * gnat_rm.texi, s-oscons-tmplt.c: Minor typo
+
+2009-09-17 Emmanuel Briot <briot@adacore.com>
+
+ * gnatcmd.adb, prj-proc.adb, make.adb, prj-ext.adb, prj-ext.ads,
+ makeutl.adb, makeutl.ads, clean.adb, prj-pars.adb, prj-pars.ads,
+ prj-conf.adb, prj-conf.ads, prj-tree.adb, prj-tree.ads, prj-proc.ads,
+ prj-nmsc.ads (Add, Value_Of, Reset): new parameter Tree.
+ Scenario variables are now specific to each project tree loaded in
+ memory.
+ Code clean ups.
+
+2009-09-17 Javier Miranda <miranda@adacore.com>
+
+ * exp_disp.adb (Make_DT): Remove wrong line of code that was
+ undocumented and probably added by mistake.
+
+2009-09-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.c (Attribute_to_gnu) <Attr_Size>: Strip
+ conversions between original and packable version of types from
+ the expression.
+
+2009-09-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_field): Add DEBUG_INFO_P parameter.
+ If a padding type was made for the field, declare it.
+ (components_to_record): Add DEBUG_INFO_P parameter. Adjust call
+ to gnat_to_gnu_field and call to self.
+ (gnat_to_gnu_entity) <E_Array_Type>: Do not redeclare padding types.
+ <E_Array_Subtype>: Likewise.
+ Adjust calls to gnat_to_gnu_field and components_to_record.
+
+2009-09-16 Robert Dewar <dewar@adacore.com>
+
+ * prj-nmsc.adb: Minor reformatting
+
+2009-09-16 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Conditional_Expression): If the type of the
+ expression is a by-reference type (tagged or inherently limited)
+ introduce an access type to capture references to the values of each
+ branch of the conditional.
+
+2009-09-16 Emmanuel Briot <briot@adacore.com>
+
+ * prj-proc.adb, prj-part.adb, prj-tree.adb, prj-tree.ads
+ (Project_Name_And_Node.Display_Name): new field
+ The display name of a project (as written in the .gpr file) is now
+ computed when the project file itself is parsed, not when it is
+ processed.
+
+2009-09-16 Thomas Quinot <quinot@adacore.com>
+
+ * freeze.adb, exp_intr.adb (Expand_Intrinsic_Call): Leave calls to
+ intrinsics untouched (to be expanded later on by gigi) if an external
+ name has been specified.
+ (Freeze_Entity): Do not generate a default external name for
+ imported subprograms with convention Intrinsic (so that the above code
+ can identify the case where an external name has been explicitly
+ provided).
+
+ * s-oscons-tmplt.c: Quote TARGET_OS early so that it is not erroneously
+ replaced by something else due to an existing #define clause.
+
+2009-09-16 Ed Schonberg <schonberg@adacore.com>
+
+ * sinfo.ads, sinfo.adb (Is_Accessibility_Actual): New flag on
+ Parameter_Association node, created for the extra actual generated for
+ an access parameter of a function that dispatches on result, to prevent
+ double generation of such actuals when the call is rewritten is a
+ dispatching call.
+ * exp_ch6.adb (Expand_Call): Set Is_Accessibility_Actual when needed.
+ * exp_disp.adb (Expand_Dispatching_Call): Do not transfer extra actuals
+ that carry this flag when rewriting the original call as a dispatching
+ call, after propagating the controlling tag.
+
+2009-09-16 Vincent Celier <celier@adacore.com>
+
+ * prj-nmsc.adb (Add_Source): New parameter Source_Dir_Rank to be put
+ in the source data.
+ (Check_File): New parameter Source_Dir_Rank, to check if a duplicate
+ source is allowed.
+ (Find_Source_Dirs): New parameter Rank to be recorded with the source
+ directories.
+ (Search_Directories): Call Check_File with the rank of the directory
+ * prj.adb (Project_Empty): Add new component Source_Dir_Ranks
+ (Free): Free also Number_Lists
+ (Reset): Init also Number_Lists
+ * prj.ads (Number_List_Table): New dynamic table for lists of numbers
+ (Source_Data): New component Source_Dir_Rank. Remove component
+ Known_Order_Of_Source_Dirs, no longer needed.
+ (Project_Data): New component Source_Dir_Ranks
+ (Project_Tree_Data): New components Number_Lists
+
+2009-09-16 Vincent Celier <celier@adacore.com>
+
+ * gprep.adb (Yes_No): New global constant
+ Unix_Line_Terminators: New global Boolean variable
+ (Process_One_File): Create the out file with a "Text_Translation=" form
+ that depends on the use of option -T.
+ (Scan_Command_Line): Add option -T
+ (Usage): Add line for option -T
+
+2009-09-16 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_disp.ads, exp_disp.adb (Is_Predefined_Internal_Operation): New
+ predicate that describes a proper subset of
+ Is_Predefined_Dispatching_Operation and excludes stream operations,
+ which can be overridden by the user.
+ * sem_ch6.adb (Create_Extra_Formals): use
+ Is_Predefined_Internal_Operation, so that stream operations get extra
+ formals.
+ * exp_ch6.adb (Prevent double generation of extra actuals in calls to
+ 'Input, which may be expanded twice, first as a function call and then
+ as a dispatching call.
+
+2009-09-16 Thomas Quinot <quinot@adacore.com>
+
+ * s-oscons-tmplt.c (Target_OS, Target_Name): New constants.
+ * g-expect.adb (Set_Up_Child_Communications): Use
+ System.OS_Constants.Target_OS to determine whether running on Windows.
+
+2009-09-14 Richard Henderson <rth@redhat.com>
+
+ * gcc-interface/trans.c (Pragma_to_gnu): Use build5 for ASM_EXPR.
+
+2009-09-14 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_dbug.ads (Packed Array Encoding): Document the new encoding for
+ the unconstrained case.
+ * gcc-interfaces/decl.c (gnat_to_gnu_entity) <E_Array_Type>: Implement
+ the encoding. Do not give a name to the pointer type to the XUT type.
+ * gcc-interfaces/utils.c (gnat_pushdecl): Propagate DECL_ORIGINAL_TYPE
+ for fat pointer types, if any. Make sure DECL_ARTIFICIAL is cleared
+ on nodes with DECL_ORIGINAL_TYPE set.
+ (update_pointer_to): Set DECL_ORIGINAL_TYPE to the original pointer
+ for fat pointer types. Make sure DECL_ARTIFICIAL is cleared.
+
+2009-09-14 Richard Henderson <rth@redhat.com>
+
+ * gcc-interface/misc.c (gnat_init_gcc_eh): Don't call
+ default_init_unwind_resume_libfunc.
+ * gcc-interface/trans.c (Exception_Handler_to_gnu_zcx): Use
+ __builtin_eh_pointer.
+ * gcc-interface/utils.c (gnat_install_builtins): Update call
+ to build_common_builtin_nodes.
+
+2009-09-13 Richard Guenther <rguenther@suse.de>
+ Rafael Avila de Espindola <espindola@google.com>
+
+ * gcc-interface/misc.c (gnat_init_gcc_eh): Do not set variables
+ eh_personality_libfunc and lang_eh_runtime_type.
+ (LANG_HOOKS_EH_PERSONALITY): Define.
+ (gnat_eh_personality_decl): New static variable.
+ (gnat_eh_personality): New static function.
+ Include gt-ada-misc.h.
+ * gcc-interface/Make-lang.in (misc.o): Add gt-ada-misc.h dependency.
+ * gcc-interface/config-lang.in (gtfiles): Add misc.c.
+
+2009-09-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ PR ada/18302
+ * gcc-interface/Make-lang.in (check-acats): Export rootme, EXPECT.
+
+2009-09-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Subtype>: Tidy
+ flow of control.
+ Avoid useless work when processing the Treat_As_Volatile flag.
+
+2009-09-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/targtyps.c: Reorder include directives.
+
+2009-09-07 Laurent GUERBY <laurent@guerby.net>
+
+ * gcc-interface/targtyps.c: Add missing include for tm_p.h.
+ * gcc-interface/Make-lang.in: Update dependencies.
+
+2009-09-07 Laurent GUERBY <laurent@guerby.net>
+
+ * make.adb: Add missing documentation for multilib handling.
+
2009-09-03 Diego Novillo <dnovillo@google.com>
* gcc-interface/misc.c (lang_hooks): Remove const qualifier.
diff --git a/gcc/ada/a-dynpri.adb b/gcc/ada/a-dynpri.adb
index 33122176f0a..9116a573948 100644
--- a/gcc/ada/a-dynpri.adb
+++ b/gcc/ada/a-dynpri.adb
@@ -67,7 +67,7 @@ package body Ada.Dynamic_Priorities is
end if;
if Task_Identification.Is_Terminated (T) then
- raise Tasking_Error with Error_Message & "null task";
+ raise Tasking_Error with Error_Message & "terminated task";
end if;
return Target.Common.Base_Priority;
@@ -93,8 +93,12 @@ package body Ada.Dynamic_Priorities is
raise Program_Error with Error_Message & "null task";
end if;
+ -- Setting the priority of an already-terminated task doesn't do
+ -- anything (see RM-D.5.1(7)). Note that Get_Priority is different in
+ -- this regard.
+
if Task_Identification.Is_Terminated (T) then
- raise Tasking_Error with Error_Message & "terminated task";
+ return;
end if;
SSL.Abort_Defer.all;
diff --git a/gcc/ada/clean.adb b/gcc/ada/clean.adb
index 790b8423529..b7bfd059869 100644
--- a/gcc/ada/clean.adb
+++ b/gcc/ada/clean.adb
@@ -35,6 +35,7 @@ with Prj; use Prj;
with Prj.Env;
with Prj.Ext;
with Prj.Pars;
+with Prj.Tree; use Prj.Tree;
with Prj.Util; use Prj.Util;
with Snames;
with Switch; use Switch;
@@ -90,7 +91,7 @@ package body Clean is
Project_File_Name : String_Access := null;
- Project_Tree : constant Prj.Project_Tree_Ref := new Prj.Project_Tree_Data;
+ Project_Node_Tree : Project_Node_Tree_Ref;
Main_Project : Prj.Project_Id := Prj.No_Project;
@@ -1402,6 +1403,7 @@ package body Clean is
Prj.Pars.Parse
(Project => Main_Project,
In_Tree => Project_Tree,
+ In_Node_Tree => Project_Node_Tree,
Project_File_Name => Project_File_Name.all,
Flags => Gnatmake_Flags,
Packages_To_Check => Packages_To_Check_By_Gnatmake);
@@ -1556,6 +1558,10 @@ package body Clean is
Csets.Initialize;
Namet.Initialize;
Snames.Initialize;
+
+ Project_Node_Tree := new Project_Node_Tree_Data;
+ Prj.Tree.Initialize (Project_Node_Tree);
+
Prj.Initialize (Project_Tree);
-- Check if the platform is VMS and, if it is, change some variables
@@ -1685,7 +1691,7 @@ package body Clean is
elsif Arg (3) = 'P' then
Prj.Ext.Add_Search_Project_Directory
- (Arg (4 .. Arg'Last));
+ (Project_Node_Tree, Arg (4 .. Arg'Last));
else
Bad_Argument;
@@ -1873,7 +1879,8 @@ package body Clean is
if OK then
Prj.Ext.Add
- (External_Name =>
+ (Project_Node_Tree,
+ External_Name =>
Ext_Asgn (Start .. Equal_Pos - 1),
Value =>
Ext_Asgn (Equal_Pos + 1 .. Stop));
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 949027dd0ae..6a65e10a167 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -4017,8 +4017,12 @@ package body Exp_Ch4 is
Thenx : constant Node_Id := Next (Cond);
Elsex : constant Node_Id := Next (Thenx);
Typ : constant Entity_Id := Etype (N);
+
Cnn : Entity_Id;
+ Decl : Node_Id;
New_If : Node_Id;
+ New_N : Node_Id;
+ P_Decl : Node_Id;
begin
-- If either then or else actions are present, then given:
@@ -4038,13 +4042,12 @@ package body Exp_Ch4 is
-- and replace the conditional expression by a reference to Cnn
- -- ??? Note: this expansion is wrong for limited types, since it does
- -- a copy of a limited value. Similarly it's wrong for unconstrained or
- -- class-wide types since in neither case can we have an uninitialized
- -- object declaration The proper fix would be to do the following
- -- expansion:
+ -- If the type is limited or unconstrained, the above expansion is
+ -- not legal, because it involves either an uninitialized object
+ -- or an illegal assignment. Instead, we generate:
- -- Cnn : access typ;
+ -- type Ptr is access all Typ;
+ -- Cnn : Ptr;
-- if cond then
-- <<then actions>>
-- Cnn := then-expr'Unrestricted_Access;
@@ -4053,11 +4056,29 @@ package body Exp_Ch4 is
-- Cnn := else-expr'Unrestricted_Access;
-- end if;
- -- and replace the conditional expresion by a reference to Cnn.all ???
+ -- and replace the conditional expresion by a reference to Cnn.all.
- if Present (Then_Actions (N)) or else Present (Else_Actions (N)) then
+ if Is_By_Reference_Type (Typ) then
Cnn := Make_Temporary (Loc, 'C', N);
+ P_Decl :=
+ Make_Full_Type_Declaration (Loc,
+ Defining_Identifier =>
+ Make_Defining_Identifier (Loc, New_Internal_Name ('A')),
+ Type_Definition =>
+ Make_Access_To_Object_Definition (Loc,
+ All_Present => True,
+ Subtype_Indication =>
+ New_Reference_To (Typ, Loc)));
+
+ Insert_Action (N, P_Decl);
+
+ Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Cnn,
+ Object_Definition =>
+ New_Occurrence_Of (Defining_Identifier (P_Decl), Loc));
+
New_If :=
Make_Implicit_If_Statement (N,
Condition => Relocate_Node (Cond),
@@ -4065,47 +4086,88 @@ package body Exp_Ch4 is
Then_Statements => New_List (
Make_Assignment_Statement (Sloc (Thenx),
Name => New_Occurrence_Of (Cnn, Sloc (Thenx)),
- Expression => Relocate_Node (Thenx))),
+ Expression =>
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_Unrestricted_Access,
+ Prefix => Relocate_Node (Thenx)))),
Else_Statements => New_List (
Make_Assignment_Statement (Sloc (Elsex),
Name => New_Occurrence_Of (Cnn, Sloc (Elsex)),
- Expression => Relocate_Node (Elsex))));
+ Expression =>
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_Unrestricted_Access,
+ Prefix => Relocate_Node (Elsex)))));
- -- Move the SLOC of the parent If statement to the newly created one
- -- and change it to the SLOC of the expression which, after
- -- expansion, will correspond to what is being evaluated.
+ New_N :=
+ Make_Explicit_Dereference (Loc,
+ Prefix => New_Occurrence_Of (Cnn, Loc));
- if Present (Parent (N))
- and then Nkind (Parent (N)) = N_If_Statement
- then
- Set_Sloc (New_If, Sloc (Parent (N)));
- Set_Sloc (Parent (N), Loc);
- end if;
+ -- For other types, we only need to expand if there are other actions
+ -- associated with either branch.
+
+ elsif Present (Then_Actions (N)) or else Present (Else_Actions (N)) then
+ Cnn := Make_Temporary (Loc, 'C', N);
+
+ Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Cnn,
+ Object_Definition => New_Occurrence_Of (Typ, Loc));
+
+ New_If :=
+ Make_Implicit_If_Statement (N,
+ Condition => Relocate_Node (Cond),
+
+ Then_Statements => New_List (
+ Make_Assignment_Statement (Sloc (Thenx),
+ Name => New_Occurrence_Of (Cnn, Sloc (Thenx)),
+ Expression => Relocate_Node (Thenx))),
+
+ Else_Statements => New_List (
+ Make_Assignment_Statement (Sloc (Elsex),
+ Name => New_Occurrence_Of (Cnn, Sloc (Elsex)),
+ Expression => Relocate_Node (Elsex))));
Set_Assignment_OK (Name (First (Then_Statements (New_If))));
Set_Assignment_OK (Name (First (Else_Statements (New_If))));
- if Present (Then_Actions (N)) then
- Insert_List_Before
- (First (Then_Statements (New_If)), Then_Actions (N));
- end if;
+ New_N := New_Occurrence_Of (Cnn, Loc);
- if Present (Else_Actions (N)) then
- Insert_List_Before
- (First (Else_Statements (New_If)), Else_Actions (N));
- end if;
+ else
+ -- No expansion needed, gigi handles it like a C conditional
+ -- expression.
- Rewrite (N, New_Occurrence_Of (Cnn, Loc));
+ return;
+ end if;
- Insert_Action (N,
- Make_Object_Declaration (Loc,
- Defining_Identifier => Cnn,
- Object_Definition => New_Occurrence_Of (Typ, Loc)));
+ -- Move the SLOC of the parent If statement to the newly created one and
+ -- change it to the SLOC of the expression which, after expansion, will
+ -- correspond to what is being evaluated.
- Insert_Action (N, New_If);
- Analyze_And_Resolve (N, Typ);
+ if Present (Parent (N))
+ and then Nkind (Parent (N)) = N_If_Statement
+ then
+ Set_Sloc (New_If, Sloc (Parent (N)));
+ Set_Sloc (Parent (N), Loc);
+ end if;
+
+ -- Make sure Then_Actions and Else_Actions are appropriately moved
+ -- to the new if statement.
+
+ if Present (Then_Actions (N)) then
+ Insert_List_Before
+ (First (Then_Statements (New_If)), Then_Actions (N));
+ end if;
+
+ if Present (Else_Actions (N)) then
+ Insert_List_Before
+ (First (Else_Statements (New_If)), Else_Actions (N));
end if;
+
+ Insert_Action (N, Decl);
+ Insert_Action (N, New_If);
+ Rewrite (N, New_N);
+ Analyze_And_Resolve (N, Typ);
end Expand_N_Conditional_Expression;
-----------------------------------
diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
index 39700bda9e0..021afbf5282 100644
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -3142,8 +3142,8 @@ package body Exp_Ch5 is
-- Second, we deal with the obvious rewriting for the cases where the
-- condition of the IF is known at compile time to be True or False.
- -- Third, we remove elsif parts which have non-empty Condition_Actions
- -- and rewrite as independent if statements. For example:
+ -- Third, we remove elsif parts which have non-empty Condition_Actions and
+ -- rewrite as independent if statements. For example:
-- if x then xs
-- elsif y then ys
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 44944aecaf9..4a31187d9d1 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -171,9 +171,9 @@ package body Exp_Ch6 is
--
-- A := TypeA (Temp);
--
- -- after the call. Here TypeA is the actual type of variable A.
- -- For out parameters, the initial declaration has no expression.
- -- If A is not an entity name, we generate instead:
+ -- after the call. Here TypeA is the actual type of variable A. For out
+ -- parameters, the initial declaration has no expression. If A is not an
+ -- entity name, we generate instead:
--
-- Var : TypeA renames A;
-- Temp : T := Var; -- omitting expression for out parameter.
@@ -183,8 +183,8 @@ package body Exp_Ch6 is
-- For other in-out parameters, we emit the required constraint checks
-- before and/or after the call.
--
- -- For all parameter modes, actuals that denote components and slices
- -- of packed arrays are expanded into suitable temporaries.
+ -- For all parameter modes, actuals that denote components and slices of
+ -- packed arrays are expanded into suitable temporaries.
--
-- For non-scalar objects that are possibly unaligned, add call by copy
-- code (copy in for IN and IN OUT, copy out for OUT and IN OUT).
@@ -419,8 +419,8 @@ package body Exp_Ch6 is
-- Create the actual which is a pointer to the appropriate finalization
-- list. Acc_Type is present if and only if this call is the
- -- initialization of an allocator. Use the Current_Scope or the Acc_Type
- -- as appropriate.
+ -- initialization of an allocator. Use the Current_Scope or the
+ -- Acc_Type as appropriate.
if Present (Acc_Type)
and then (Ekind (Acc_Type) = E_Anonymous_Access_Type
@@ -496,6 +496,7 @@ package body Exp_Ch6 is
declare
Activation_Chain_Actual : Node_Id;
Activation_Chain_Formal : Node_Id;
+
begin
-- Locate implicit activation chain parameter in the called function
@@ -1807,6 +1808,10 @@ package body Exp_Ch6 is
Make_Identifier (Loc, Chars (EF))));
Analyze_And_Resolve (Expr, Etype (EF));
+
+ if Nkind (N) = N_Function_Call then
+ Set_Is_Accessibility_Actual (Parent (Expr));
+ end if;
end Add_Extra_Actual;
---------------------------
@@ -2287,9 +2292,10 @@ package body Exp_Ch6 is
when Attribute_Access =>
Add_Extra_Actual
(Make_Integer_Literal (Loc,
- Intval =>
- Object_Access_Level (Prefix (Prev_Orig))),
- Extra_Accessibility (Formal));
+ Intval =>
+ Object_Access_Level
+ (Prefix (Prev_Orig))),
+ Extra_Accessibility (Formal));
-- Treat the unchecked attributes as library-level
@@ -2328,7 +2334,6 @@ package body Exp_Ch6 is
(Make_Integer_Literal (Loc,
Intval => Type_Access_Level (Etype (Prev))),
Extra_Accessibility (Formal));
-
end case;
end if;
end if;
diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb
index 526a2dd552c..db22726bb64 100644
--- a/gcc/ada/exp_ch9.adb
+++ b/gcc/ada/exp_ch9.adb
@@ -835,8 +835,8 @@ package body Exp_Ch9 is
end loop;
-- If we are in a package body, the activation chain variable is
- -- declared in the body, but the Activation_Chain_Entity is attached to
- -- the spec.
+ -- declared in the body, but the Activation_Chain_Entity is attached
+ -- to the spec.
if Nkind (P) = N_Package_Body then
Decls := Declarations (P);
diff --git a/gcc/ada/exp_dbug.ads b/gcc/ada/exp_dbug.ads
index 2b30248a78c..3c3144641d8 100644
--- a/gcc/ada/exp_dbug.ads
+++ b/gcc/ada/exp_dbug.ads
@@ -1094,8 +1094,8 @@ package Exp_Dbug is
-- Packed Array Encoding --
---------------------------
- -- For every packed array, two types are created, and both appear in
- -- the debugging output.
+ -- For every constrained packed array, two types are created, and both
+ -- appear in the debugging output:
-- The original declared array type is a perfectly normal array type,
-- and its index bounds indicate the original bounds of the array.
@@ -1110,12 +1110,27 @@ package Exp_Dbug is
-- ttt___XPnnn
-- where
+
-- ttt is the name of the original declared array
-- nnn is the component size in bits (1-31)
- -- When the debugger sees that an object is of a type that is encoded
- -- in this manner, it can use the original type to determine the bounds,
- -- and the component size to determine the packing details.
+ -- When the debugger sees that an object is of a type that is encoded in
+ -- this manner, it can use the original type to determine the bounds and
+ -- the component type, and the component size to determine the packing
+ -- details.
+
+ -- For an unconstrained packed array, the corresponding packed array type
+ -- is neither used in the generated code nor for debugging information,
+ -- only the original type is used. In order to convey the packing in the
+ -- debugging information, the compiler generates the associated fat- and
+ -- thin-pointer types (see the Pointers to Unconstrained Array section
+ -- below) using the name of the corresponding packed array type as the
+ -- base name, i.e. ttt___XPnnn___XUP and ttt___XPnnn___XUT respectively.
+
+ -- When the debugger sees that an object is of a type that is encoded in
+ -- this manner, it can use the type of the fields to determine the bounds
+ -- and the component type, and the component size to determine the packing
+ -- details.
-------------------------------------------
-- Packed Array Representation in Memory --
@@ -1257,6 +1272,7 @@ package Exp_Dbug is
-- fat-pointer type whose name is "arr___XUP", where "arr" is the name
-- of the array type, and use it to represent the array type itself in
-- the debugging information.
+
-- For each pointer to this unconstrained array type, the compiler will
-- generate a typedef that points to the above "arr___XUP" fat-pointer
-- type. As a consequence, when it comes to fat-pointer types:
diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb
index f34b1e9af33..00fd9f22e70 100644
--- a/gcc/ada/exp_disp.adb
+++ b/gcc/ada/exp_disp.adb
@@ -692,7 +692,9 @@ package body Exp_Disp is
Append_To (New_Params,
Duplicate_Subexpr_Move_Checks (Param));
- else
+ elsif Nkind (Parent (Param)) /= N_Parameter_Association
+ or else not Is_Accessibility_Actual (Parent (Param))
+ then
Append_To (New_Params, Relocate_Node (Param));
end if;
@@ -1740,6 +1742,48 @@ package body Exp_Disp is
return False;
end Is_Predefined_Dispatching_Operation;
+ ---------------------------------------
+ -- Is_Predefined_Internal_Operation --
+ ---------------------------------------
+
+ function Is_Predefined_Internal_Operation
+ (E : Entity_Id) return Boolean
+ is
+ TSS_Name : TSS_Name_Type;
+
+ begin
+ if not Is_Dispatching_Operation (E) then
+ return False;
+ end if;
+
+ Get_Name_String (Chars (E));
+
+ -- Most predefined primitives have internally generated names. Equality
+ -- must be treated differently; the predefined operation is recognized
+ -- as a homogeneous binary operator that returns Boolean.
+
+ if Name_Len > TSS_Name_Type'Last then
+ TSS_Name :=
+ TSS_Name_Type
+ (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));
+
+ if Chars (E) = Name_uSize
+ or else Chars (E) = Name_uAlignment
+ or else
+ (Chars (E) = Name_Op_Eq
+ and then Etype (First_Entity (E)) = Etype (Last_Entity (E)))
+ or else Chars (E) = Name_uAssign
+ or else TSS_Name = TSS_Deep_Adjust
+ or else TSS_Name = TSS_Deep_Finalize
+ or else Is_Predefined_Interface_Primitive (E)
+ then
+ return True;
+ end if;
+ end if;
+
+ return False;
+ end Is_Predefined_Internal_Operation;
+
-------------------------------------
-- Is_Predefined_Dispatching_Alias --
-------------------------------------
@@ -5096,9 +5140,8 @@ package body Exp_Disp is
exit when Parent_Typ = Current_Typ;
- if Is_CPP_Class (Parent_Typ)
- or else Is_Interface (Typ)
- then
+ if Is_CPP_Class (Parent_Typ) then
+
-- The tags defined in the C++ side will be inherited when
-- the object is constructed (Exp_Ch3.Build_Init_Procedure)
diff --git a/gcc/ada/exp_disp.ads b/gcc/ada/exp_disp.ads
index 18f751d978d..4aea2ca1e65 100644
--- a/gcc/ada/exp_disp.ads
+++ b/gcc/ada/exp_disp.ads
@@ -218,6 +218,11 @@ package Exp_Disp is
function Is_Predefined_Dispatching_Operation (E : Entity_Id) return Boolean;
-- Ada 2005 (AI-251): Determines if E is a predefined primitive operation
+ function Is_Predefined_Internal_Operation (E : Entity_Id) return Boolean;
+ -- Similar to the previous one, but excludes stream operations, because
+ -- these may be overridden, and need extra formals, like user-defined
+ -- operations.
+
function Is_Predefined_Interface_Primitive (E : Entity_Id) return Boolean;
-- Ada 2005 (AI-345): Returns True if E is one of the predefined primitives
-- required to implement interfaces.
diff --git a/gcc/ada/exp_intr.adb b/gcc/ada/exp_intr.adb
index b35c35ea9df..da1314c3aa7 100644
--- a/gcc/ada/exp_intr.adb
+++ b/gcc/ada/exp_intr.adb
@@ -394,6 +394,13 @@ package body Exp_Intr is
Nam : Name_Id;
begin
+ -- If an external name is specified for the intrinsic, it is handled
+ -- by the back-end: leave the call node unchanged for now.
+
+ if Present (Interface_Name (E)) then
+ return;
+ end if;
+
-- If the intrinsic subprogram is generic, gets its original name
if Present (Parent (E))
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 14ba41c9956..56389bb0535 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -2443,11 +2443,16 @@ package body Freeze is
-- If entity is exported or imported and does not have an external
-- name, now is the time to provide the appropriate default name.
-- Skip this if the entity is stubbed, since we don't need a name
- -- for any stubbed routine.
+ -- for any stubbed routine. For the case on intrinsics, if no
+ -- external name is specified, then calls will be handled in
+ -- Exp_Intr.Expand_Intrinsic_Call, and no name is needed; if
+ -- an external name is provided, then Expand_Intrinsic_Call leaves
+ -- calls in place for expansion by GIGI.
if (Is_Imported (E) or else Is_Exported (E))
and then No (Interface_Name (E))
and then Convention (E) /= Convention_Stubbed
+ and then Convention (E) /= Convention_Intrinsic
then
Set_Encoded_Interface_Name
(E, Get_Default_External_Name (E));
@@ -3335,9 +3340,7 @@ package body Freeze is
-- For bit-packed arrays, check the size
- if Is_Bit_Packed_Array (E)
- and then Known_RM_Size (E)
- then
+ if Is_Bit_Packed_Array (E) and then Known_RM_Size (E) then
declare
SizC : constant Node_Id := Size_Clause (E);
diff --git a/gcc/ada/g-expect.adb b/gcc/ada/g-expect.adb
index 02bc6cf8a79..a67696a649d 100644
--- a/gcc/ada/g-expect.adb
+++ b/gcc/ada/g-expect.adb
@@ -31,8 +31,9 @@
-- --
------------------------------------------------------------------------------
-with System; use System;
-with Ada.Calendar; use Ada.Calendar;
+with System; use System;
+with System.OS_Constants; use System.OS_Constants;
+with Ada.Calendar; use Ada.Calendar;
with GNAT.IO;
with GNAT.OS_Lib; use GNAT.OS_Lib;
@@ -1195,15 +1196,14 @@ package body GNAT.Expect is
pragma Warnings (Off, Pipe2);
pragma Warnings (Off, Pipe3);
- On_Windows : constant Boolean := Directory_Separator = '\';
- -- This is ugly, we need a better way of doing this test ???
-
Input : File_Descriptor;
Output : File_Descriptor;
Error : File_Descriptor;
+ No_Fork_On_Target : constant Boolean := Target_OS = Windows;
+
begin
- if On_Windows then
+ if No_Fork_On_Target then
-- Since Windows does not have a separate fork/exec, we need to
-- perform the following actions:
diff --git a/gcc/ada/g-socket.adb b/gcc/ada/g-socket.adb
index d32ebfc37a8..8afde3beec3 100644
--- a/gcc/ada/g-socket.adb
+++ b/gcc/ada/g-socket.adb
@@ -282,6 +282,12 @@ package body GNAT.Sockets is
Res : C.int;
begin
+ if Selector.R_Sig_Socket = No_Socket
+ or else Selector.W_Sig_Socket = No_Socket
+ then
+ raise Program_Error with "closed selector";
+ end if;
+
-- Send one byte to unblock select system call
Res := Signalling_Fds.Write (C.int (Selector.W_Sig_Socket));
@@ -330,6 +336,14 @@ package body GNAT.Sockets is
Status : out Selector_Status)
is
begin
+ if Selector /= null
+ and then (Selector.R_Sig_Socket = No_Socket
+ or else
+ Selector.W_Sig_Socket = No_Socket)
+ then
+ raise Program_Error with "closed selector";
+ end if;
+
-- Wait for socket to become available for reading
Wait_On_Socket
@@ -473,11 +487,17 @@ package body GNAT.Sockets is
is
Res : C.int;
Last : C.int;
- RSig : Socket_Type renames Selector.R_Sig_Socket;
+ RSig : constant Socket_Type := Selector.R_Sig_Socket;
TVal : aliased Timeval;
TPtr : Timeval_Access;
begin
+ if Selector.R_Sig_Socket = No_Socket
+ or else Selector.W_Sig_Socket = No_Socket
+ then
+ raise Program_Error with "closed selector";
+ end if;
+
Status := Completed;
-- No timeout or Forever is indicated by a null timeval pointer
@@ -563,6 +583,12 @@ package body GNAT.Sockets is
procedure Close_Selector (Selector : in out Selector_Type) is
begin
+ if Selector.R_Sig_Socket = No_Socket
+ or else Selector.W_Sig_Socket = No_Socket
+ then
+ return;
+ end if;
+
-- Close the signalling file descriptors used internally for the
-- implementation of Abort_Selector.
@@ -636,6 +662,13 @@ package body GNAT.Sockets is
-- Used to set Socket to non-blocking I/O
begin
+ if Selector /= null and then
+ (Selector.R_Sig_Socket = No_Socket
+ or else Selector.W_Sig_Socket = No_Socket)
+ then
+ raise Program_Error with "closed selector";
+ end if;
+
-- Set the socket to non-blocking I/O
Req := (Name => Non_Blocking_IO, Enabled => True);
@@ -727,6 +760,12 @@ package body GNAT.Sockets is
Res : C.int;
begin
+ if Selector.R_Sig_Socket /= No_Socket
+ or else Selector.W_Sig_Socket /= No_Socket
+ then
+ raise Program_Error with "selector already open";
+ end if;
+
-- We open two signalling file descriptors. One of them is used to send
-- data to the other, which is included in a C_Select socket set. The
-- communication is used to force a call to C_Select to complete, and
diff --git a/gcc/ada/g-socket.ads b/gcc/ada/g-socket.ads
index a6445e044ad..39a917a5480 100644
--- a/gcc/ada/g-socket.ads
+++ b/gcc/ada/g-socket.ads
@@ -1072,7 +1072,8 @@ package GNAT.Sockets is
-- Close Selector and all internal descriptors associated; deallocate any
-- associated resources. This subprogram may be called only when there is
-- no other task still using Selector (i.e. still executing Check_Selector
- -- or Abort_Selector on this Selector).
+ -- or Abort_Selector on this Selector). Has no effect if Selector is
+ -- already closed.
procedure Check_Selector
(Selector : in out Selector_Type;
diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in
index eec47d4c009..163274c4332 100644
--- a/gcc/ada/gcc-interface/Make-lang.in
+++ b/gcc/ada/gcc-interface/Make-lang.in
@@ -841,6 +841,8 @@ check_acats_targets = $(patsubst %,check-acats%, 0 1 2)
check-acats:
@test -d $(ACATSDIR) || mkdir -p $(ACATSDIR); \
+ rootme=`${PWD_COMMAND}`; export rootme; \
+ EXPECT=$(EXPECT); export EXPECT; \
if [ -z "$(CHAPTERS)" ] && [ "$(filter -j, $(MFLAGS))" = "-j" ]; \
then \
$(MAKE) $(check_acats_targets); \
@@ -1070,14 +1072,15 @@ ada/misc.o : ada/gcc-interface/misc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(LANGHOOKS_DEF_H) opts.h options.h $(TREE_INLINE_H) \
ada/gcc-interface/ada.h ada/adadecode.h ada/types.h ada/atree.h \
ada/elists.h ada/namet.h ada/nlists.h ada/stringt.h ada/uintp.h ada/fe.h \
- ada/sinfo.h ada/einfo.h $(ADA_TREE_H) ada/gcc-interface/gigi.h
+ ada/sinfo.h ada/einfo.h $(ADA_TREE_H) ada/gcc-interface/gigi.h \
+ gt-ada-misc.h
$(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
ada/targtyps.o : ada/gcc-interface/targtyps.c $(CONFIG_H) $(SYSTEM_H) \
- coretypes.h $(TM_H) $(TREE_H) ada/gcc-interface/ada.h ada/types.h \
- ada/atree.h ada/elists.h ada/namet.h ada/nlists.h ada/snames.h \
- ada/stringt.h ada/uintp.h ada/urealp.h ada/fe.h ada/sinfo.h ada/einfo.h \
- $(ADA_TREE_H) ada/gcc-interface/gigi.h
+ coretypes.h $(TM_H) $(TM_P_H) $(TREE_H) ada/gcc-interface/ada.h \
+ ada/types.h ada/atree.h ada/elists.h ada/namet.h ada/nlists.h \
+ ada/snames.h ada/stringt.h ada/uintp.h ada/urealp.h ada/fe.h ada/sinfo.h \
+ ada/einfo.h $(ADA_TREE_H) ada/gcc-interface/gigi.h
$(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
ada/trans.o : ada/gcc-interface/trans.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
diff --git a/gcc/ada/gcc-interface/config-lang.in b/gcc/ada/gcc-interface/config-lang.in
index 58253989290..b4a28be14c7 100644
--- a/gcc/ada/gcc-interface/config-lang.in
+++ b/gcc/ada/gcc-interface/config-lang.in
@@ -32,7 +32,7 @@ boot_language_boot_flags='ADAFLAGS="$(BOOT_ADAFLAGS)"'
compilers="gnat1\$(exeext)"
-gtfiles="\$(srcdir)/ada/gcc-interface/ada-tree.h \$(srcdir)/ada/gcc-interface/gigi.h \$(srcdir)/ada/gcc-interface/decl.c \$(srcdir)/ada/gcc-interface/trans.c \$(srcdir)/ada/gcc-interface/utils.c"
+gtfiles="\$(srcdir)/ada/gcc-interface/ada-tree.h \$(srcdir)/ada/gcc-interface/gigi.h \$(srcdir)/ada/gcc-interface/decl.c \$(srcdir)/ada/gcc-interface/trans.c \$(srcdir)/ada/gcc-interface/utils.c \$(srcdir)/ada/gcc-interface/misc.c"
outputs="ada/gcc-interface/Makefile ada/Makefile"
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 9d385302c6b..58c07a777d7 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -131,7 +131,7 @@ static tree elaborate_expression (Node_Id, Entity_Id, tree, bool, bool, bool);
static bool is_variable_size (tree);
static tree elaborate_expression_1 (tree, Entity_Id, tree, bool, bool);
static tree make_packable_type (tree, bool);
-static tree gnat_to_gnu_field (Entity_Id, tree, int, bool);
+static tree gnat_to_gnu_field (Entity_Id, tree, int, bool, bool);
static tree gnat_to_gnu_param (Entity_Id, Mechanism_Type, Entity_Id, bool,
bool *);
static bool same_discriminant_p (Entity_Id, Entity_Id);
@@ -139,7 +139,7 @@ static bool array_type_has_nonaliased_component (Entity_Id, tree);
static bool compile_time_known_address_p (Node_Id);
static bool cannot_be_superflat_p (Node_Id);
static void components_to_record (tree, Node_Id, tree, int, bool, tree *,
- bool, bool, bool, bool);
+ bool, bool, bool, bool, bool);
static Uint annotate_value (tree);
static void annotate_rep (Entity_Id, tree);
static tree compute_field_positions (tree, tree, tree, tree, unsigned int);
@@ -1782,7 +1782,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
case E_String_Type:
case E_Array_Type:
{
- Entity_Id gnat_index;
+ Entity_Id gnat_index, gnat_name;
const bool convention_fortran_p
= (Convention (gnat_entity) == Convention_Fortran);
const int ndim = Number_Dimensions (gnat_entity);
@@ -1990,7 +1990,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* If a padding record was made, declare it now since it will
never be declared otherwise. This is necessary to ensure
that its subtrees are properly marked. */
- if (tem != orig_tem)
+ if (tem != orig_tem && !DECL_P (TYPE_NAME (tem)))
create_type_decl (TYPE_NAME (tem), tem, NULL, true,
debug_info_p, gnat_entity);
}
@@ -2066,8 +2066,13 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
tem, NULL, !Comes_From_Source (gnat_entity),
debug_info_p, gnat_entity);
- /* Give the fat pointer type a name. */
- create_type_decl (create_concat_name (gnat_entity, "XUP"),
+ /* Give the fat pointer type a name. If this is a packed type, tell
+ the debugger how to interpret the underlying bits. */
+ if (Present (Packed_Array_Type (gnat_entity)))
+ gnat_name = Packed_Array_Type (gnat_entity);
+ else
+ gnat_name = gnat_entity;
+ create_type_decl (create_concat_name (gnat_name, "XUP"),
gnu_fat_type, NULL, true,
debug_info_p, gnat_entity);
@@ -2075,16 +2080,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
record type for the object and its template with the field offsets
shifted to have the template at a negative offset. */
tem = build_unc_object_type (gnu_template_type, tem,
- create_concat_name (gnat_entity, "XUT"));
+ create_concat_name (gnat_name, "XUT"));
shift_unc_components_for_thin_pointers (tem);
SET_TYPE_UNCONSTRAINED_ARRAY (tem, gnu_type);
TYPE_OBJECT_RECORD_TYPE (gnu_type) = tem;
-
- /* Give the thin pointer type a name. */
- create_type_decl (create_concat_name (gnat_entity, "XUX"),
- build_pointer_type (tem), NULL, true,
- debug_info_p, gnat_entity);
}
break;
@@ -2093,7 +2093,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* This is the actual data type for array variables. Multidimensional
arrays are implemented as arrays of arrays. Note that arrays which
- have sparse enumeration subtypes as index components create sparse
+ have sparse enumeration subtypes as index components create sparse
arrays, which is obviously space inefficient but so much easier to
code for now.
@@ -2105,7 +2105,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnu_type = gnat_to_gnu_type (Etype (gnat_entity));
if (!Is_Constrained (gnat_entity))
- break;
+ ;
else
{
Entity_Id gnat_index, gnat_base_index;
@@ -2364,7 +2364,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
if (gnu_comp_size && !Is_Bit_Packed_Array (gnat_entity))
{
- tree orig_gnu_type = gnu_type;
+ tree orig_type = gnu_type;
unsigned int max_align;
/* If an alignment is specified, use it as a cap on the
@@ -2381,9 +2381,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnu_type
= make_type_from_size (gnu_type, gnu_comp_size, false);
if (max_align > 0 && TYPE_ALIGN (gnu_type) > max_align)
- gnu_type = orig_gnu_type;
+ gnu_type = orig_type;
else
- orig_gnu_type = gnu_type;
+ orig_type = gnu_type;
gnu_type = maybe_pad_type (gnu_type, gnu_comp_size, 0,
gnat_entity, "C_PAD", false,
@@ -2392,7 +2392,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* If a padding record was made, declare it now since it
will never be declared otherwise. This is necessary
to ensure that its subtrees are properly marked. */
- if (gnu_type != orig_gnu_type)
+ if (gnu_type != orig_type && !DECL_P (TYPE_NAME (gnu_type)))
create_type_decl (TYPE_NAME (gnu_type), gnu_type, NULL,
true, debug_info_p, gnat_entity);
}
@@ -2538,105 +2538,104 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* Set our alias set to that of our base type. This gives all
array subtypes the same alias set. */
relate_alias_sets (gnu_type, gnu_base_type, ALIAS_SET_COPY);
- }
-
- /* If this is a packed type, make this type the same as the packed
- array type, but do some adjusting in the type first. */
- if (Present (Packed_Array_Type (gnat_entity)))
- {
- Entity_Id gnat_index;
- tree gnu_inner_type;
-
- /* First finish the type we had been making so that we output
- debugging information for it. */
- gnu_type
- = build_qualified_type (gnu_type,
- (TYPE_QUALS (gnu_type)
- | (TYPE_QUAL_VOLATILE
- * Treat_As_Volatile (gnat_entity))));
-
- /* Make it artificial only if the base type was artificial as well.
- That's sort of "morally" true and will make it possible for the
- debugger to look it up by name in DWARF, which is necessary in
- order to decode the packed array type. */
- gnu_decl
- = create_type_decl (gnu_entity_name, gnu_type, attr_list,
- !Comes_From_Source (gnat_entity)
- && !Comes_From_Source (Etype (gnat_entity)),
- debug_info_p, gnat_entity);
-
- /* Save it as our equivalent in case the call below elaborates
- this type again. */
- save_gnu_tree (gnat_entity, gnu_decl, false);
-
- gnu_decl = gnat_to_gnu_entity (Packed_Array_Type (gnat_entity),
- NULL_TREE, 0);
- this_made_decl = true;
- gnu_type = TREE_TYPE (gnu_decl);
- save_gnu_tree (gnat_entity, NULL_TREE, false);
- gnu_inner_type = gnu_type;
- while (TREE_CODE (gnu_inner_type) == RECORD_TYPE
- && (TYPE_JUSTIFIED_MODULAR_P (gnu_inner_type)
- || TYPE_IS_PADDING_P (gnu_inner_type)))
- gnu_inner_type = TREE_TYPE (TYPE_FIELDS (gnu_inner_type));
-
- /* We need to attach the index type to the type we just made so
- that the actual bounds can later be put into a template. */
- if ((TREE_CODE (gnu_inner_type) == ARRAY_TYPE
- && !TYPE_ACTUAL_BOUNDS (gnu_inner_type))
- || (TREE_CODE (gnu_inner_type) == INTEGER_TYPE
- && !TYPE_HAS_ACTUAL_BOUNDS_P (gnu_inner_type)))
+ /* If this is a packed type, make this type the same as the packed
+ array type, but do some adjusting in the type first. */
+ if (Present (Packed_Array_Type (gnat_entity)))
{
- if (TREE_CODE (gnu_inner_type) == INTEGER_TYPE)
+ Entity_Id gnat_index;
+ tree gnu_inner;
+
+ /* First finish the type we had been making so that we output
+ debugging information for it. */
+ if (Treat_As_Volatile (gnat_entity))
+ gnu_type
+ = build_qualified_type (gnu_type,
+ TYPE_QUALS (gnu_type)
+ | TYPE_QUAL_VOLATILE);
+
+ /* Make it artificial only if the base type was artificial too.
+ That's sort of "morally" true and will make it possible for
+ the debugger to look it up by name in DWARF, which is needed
+ in order to decode the packed array type. */
+ gnu_decl
+ = create_type_decl (gnu_entity_name, gnu_type, attr_list,
+ !Comes_From_Source (Etype (gnat_entity))
+ && !Comes_From_Source (gnat_entity),
+ debug_info_p, gnat_entity);
+
+ /* Save it as our equivalent in case the call below elaborates
+ this type again. */
+ save_gnu_tree (gnat_entity, gnu_decl, false);
+
+ gnu_decl = gnat_to_gnu_entity (Packed_Array_Type (gnat_entity),
+ NULL_TREE, 0);
+ this_made_decl = true;
+ gnu_type = TREE_TYPE (gnu_decl);
+ save_gnu_tree (gnat_entity, NULL_TREE, false);
+
+ gnu_inner = gnu_type;
+ while (TREE_CODE (gnu_inner) == RECORD_TYPE
+ && (TYPE_JUSTIFIED_MODULAR_P (gnu_inner)
+ || TYPE_IS_PADDING_P (gnu_inner)))
+ gnu_inner = TREE_TYPE (TYPE_FIELDS (gnu_inner));
+
+ /* We need to attach the index type to the type we just made so
+ that the actual bounds can later be put into a template. */
+ if ((TREE_CODE (gnu_inner) == ARRAY_TYPE
+ && !TYPE_ACTUAL_BOUNDS (gnu_inner))
+ || (TREE_CODE (gnu_inner) == INTEGER_TYPE
+ && !TYPE_HAS_ACTUAL_BOUNDS_P (gnu_inner)))
{
- /* The TYPE_ACTUAL_BOUNDS field is overloaded with the
- TYPE_MODULUS for modular types so we make an extra
- subtype if necessary. */
- if (TYPE_MODULAR_P (gnu_inner_type))
+ if (TREE_CODE (gnu_inner) == INTEGER_TYPE)
{
- tree gnu_subtype
- = make_unsigned_type (TYPE_PRECISION (gnu_inner_type));
- TREE_TYPE (gnu_subtype) = gnu_inner_type;
- TYPE_EXTRA_SUBTYPE_P (gnu_subtype) = 1;
- SET_TYPE_RM_MIN_VALUE (gnu_subtype,
- TYPE_MIN_VALUE (gnu_inner_type));
- SET_TYPE_RM_MAX_VALUE (gnu_subtype,
- TYPE_MAX_VALUE (gnu_inner_type));
- gnu_inner_type = gnu_subtype;
- }
-
- TYPE_HAS_ACTUAL_BOUNDS_P (gnu_inner_type) = 1;
+ /* The TYPE_ACTUAL_BOUNDS field is overloaded with the
+ TYPE_MODULUS for modular types so we make an extra
+ subtype if necessary. */
+ if (TYPE_MODULAR_P (gnu_inner))
+ {
+ tree gnu_subtype
+ = make_unsigned_type (TYPE_PRECISION (gnu_inner));
+ TREE_TYPE (gnu_subtype) = gnu_inner;
+ TYPE_EXTRA_SUBTYPE_P (gnu_subtype) = 1;
+ SET_TYPE_RM_MIN_VALUE (gnu_subtype,
+ TYPE_MIN_VALUE (gnu_inner));
+ SET_TYPE_RM_MAX_VALUE (gnu_subtype,
+ TYPE_MAX_VALUE (gnu_inner));
+ gnu_inner = gnu_subtype;
+ }
+
+ TYPE_HAS_ACTUAL_BOUNDS_P (gnu_inner) = 1;
#ifdef ENABLE_CHECKING
- /* Check for other cases of overloading. */
- gcc_assert (!TYPE_ACTUAL_BOUNDS (gnu_inner_type));
+ /* Check for other cases of overloading. */
+ gcc_assert (!TYPE_ACTUAL_BOUNDS (gnu_inner));
#endif
- }
+ }
- for (gnat_index = First_Index (gnat_entity);
- Present (gnat_index); gnat_index = Next_Index (gnat_index))
- SET_TYPE_ACTUAL_BOUNDS
- (gnu_inner_type,
- tree_cons (NULL_TREE,
- get_unpadded_type (Etype (gnat_index)),
- TYPE_ACTUAL_BOUNDS (gnu_inner_type)));
-
- if (Convention (gnat_entity) != Convention_Fortran)
- SET_TYPE_ACTUAL_BOUNDS
- (gnu_inner_type,
- nreverse (TYPE_ACTUAL_BOUNDS (gnu_inner_type)));
-
- if (TREE_CODE (gnu_type) == RECORD_TYPE
- && TYPE_JUSTIFIED_MODULAR_P (gnu_type))
- TREE_TYPE (TYPE_FIELDS (gnu_type)) = gnu_inner_type;
+ for (gnat_index = First_Index (gnat_entity);
+ Present (gnat_index);
+ gnat_index = Next_Index (gnat_index))
+ SET_TYPE_ACTUAL_BOUNDS
+ (gnu_inner,
+ tree_cons (NULL_TREE,
+ get_unpadded_type (Etype (gnat_index)),
+ TYPE_ACTUAL_BOUNDS (gnu_inner)));
+
+ if (Convention (gnat_entity) != Convention_Fortran)
+ SET_TYPE_ACTUAL_BOUNDS
+ (gnu_inner, nreverse (TYPE_ACTUAL_BOUNDS (gnu_inner)));
+
+ if (TREE_CODE (gnu_type) == RECORD_TYPE
+ && TYPE_JUSTIFIED_MODULAR_P (gnu_type))
+ TREE_TYPE (TYPE_FIELDS (gnu_type)) = gnu_inner;
+ }
}
- }
-
- /* Abort if packed array with no packed array type field set. */
- else
- gcc_assert (!Is_Packed (gnat_entity));
+ else
+ /* Abort if packed array with no Packed_Array_Type field set. */
+ gcc_assert (!Is_Packed (gnat_entity));
+ }
break;
case E_String_Literal_Subtype:
@@ -2953,7 +2952,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
continue;
gnu_field
- = gnat_to_gnu_field (gnat_field, gnu_type, packed, definition);
+ = gnat_to_gnu_field (gnat_field, gnu_type, packed, definition,
+ debug_info_p);
/* Make an expression using a PLACEHOLDER_EXPR from the
FIELD_DECL node just created and link that with the
@@ -2974,7 +2974,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* Add the fields into the record type and finish it up. */
components_to_record (gnu_type, Component_List (record_definition),
gnu_field_list, packed, definition, NULL,
- false, all_rep, false, is_unchecked_union);
+ false, all_rep, false, is_unchecked_union,
+ debug_info_p);
/* If it is a tagged record force the type to BLKmode to insure that
these objects will always be put in memory. Likewise for limited
@@ -4634,10 +4635,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
}
}
- gnu_type = build_qualified_type (gnu_type,
- (TYPE_QUALS (gnu_type)
- | (TYPE_QUAL_VOLATILE
- * Treat_As_Volatile (gnat_entity))));
+ if (Treat_As_Volatile (gnat_entity))
+ gnu_type
+ = build_qualified_type (gnu_type,
+ TYPE_QUALS (gnu_type) | TYPE_QUAL_VOLATILE);
if (Is_Atomic (gnat_entity))
check_ok_for_atomic (gnu_type, gnat_entity, false);
@@ -6413,11 +6414,14 @@ adjust_packed (tree field_type, tree record_type, int packed)
record has Component_Alignment of Storage_Unit, -2 if the enclosing
record has a specified alignment.
- DEFINITION is true if this field is for a record being defined. */
+ DEFINITION is true if this field is for a record being defined.
+
+ DEBUG_INFO_P is true if we need to write debug information for types
+ that we may create in the process. */
static tree
gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
- bool definition)
+ bool definition, bool debug_info_p)
{
tree gnu_field_id = get_entity_name (gnat_field);
tree gnu_field_type = gnat_to_gnu_type (Etype (gnat_field));
@@ -6636,6 +6640,8 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
/* If a size is specified, adjust the field's type to it. */
if (gnu_size)
{
+ tree orig_field_type;
+
/* If the field's type is justified modular, we would need to remove
the wrapper to (better) meet the layout requirements. However we
can do so only if the field is not aliased to preserve the unique
@@ -6651,8 +6657,18 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
gnu_field_type
= make_type_from_size (gnu_field_type, gnu_size,
Has_Biased_Representation (gnat_field));
+
+ orig_field_type = gnu_field_type;
gnu_field_type = maybe_pad_type (gnu_field_type, gnu_size, 0, gnat_field,
"PAD", false, definition, true);
+
+ /* If a padding record was made, declare it now since it will never be
+ declared otherwise. This is necessary to ensure that its subtrees
+ are properly marked. */
+ if (gnu_field_type != orig_field_type
+ && !DECL_P (TYPE_NAME (gnu_field_type)))
+ create_type_decl (TYPE_NAME (gnu_field_type), gnu_field_type, NULL,
+ true, debug_info_p, gnat_field);
}
/* Otherwise (or if there was an error), don't specify a position. */
@@ -6747,13 +6763,17 @@ compare_field_bitpos (const PTR rt1, const PTR rt2)
modified afterwards so it will not be finalized here.
UNCHECKED_UNION, if true, means that we are building a type for a record
- with a Pragma Unchecked_Union. */
+ with a Pragma Unchecked_Union.
+
+ DEBUG_INFO_P, if true, means that we need to write debug information for
+ types that we may create in the process. */
static void
components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
tree gnu_field_list, int packed, bool definition,
tree *p_gnu_rep_list, bool cancel_alignment,
- bool all_rep, bool do_not_finalize, bool unchecked_union)
+ bool all_rep, bool do_not_finalize,
+ bool unchecked_union, bool debug_info_p)
{
bool all_rep_and_size = all_rep && TYPE_SIZE (gnu_record_type);
bool layout_with_rep = false;
@@ -6781,8 +6801,8 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
}
else
{
- gnu_field = gnat_to_gnu_field (gnat_field, gnu_record_type,
- packed, definition);
+ gnu_field = gnat_to_gnu_field (gnat_field, gnu_record_type, packed,
+ definition, debug_info_p);
/* If this is the _Tag field, put it before any other fields. */
if (gnat_name == Name_uTag)
@@ -6888,7 +6908,7 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
components_to_record (gnu_variant_type, Component_List (variant),
NULL_TREE, packed, definition,
&gnu_our_rep_list, !all_rep_and_size, all_rep,
- true, unchecked_union);
+ true, unchecked_union, debug_info_p);
gnu_qual = choices_to_gnu (gnu_discr, Discrete_Choices (variant));
diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index f39a60eb4cc..26df68de581 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -79,6 +79,7 @@ static void gnat_parse_file (int);
static void internal_error_function (const char *, va_list *);
static tree gnat_type_max_size (const_tree);
static void gnat_get_subrange_bounds (const_tree, tree *, tree *);
+static tree gnat_eh_personality (void);
/* Definitions for our language-specific hooks. */
@@ -129,7 +130,9 @@ static void gnat_get_subrange_bounds (const_tree, tree *, tree *);
#undef LANG_HOOKS_ATTRIBUTE_TABLE
#define LANG_HOOKS_ATTRIBUTE_TABLE gnat_internal_attribute_table
#undef LANG_HOOKS_BUILTIN_FUNCTION
-#define LANG_HOOKS_BUILTIN_FUNCTION gnat_builtin_function
+#define LANG_HOOKS_BUILTIN_FUNCTION gnat_builtin_function
+#undef LANG_HOOKS_EH_PERSONALITY
+#define LANG_HOOKS_EH_PERSONALITY gnat_eh_personality
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
@@ -431,12 +434,7 @@ gnat_init_gcc_eh (void)
right exception regions. */
using_eh_for_cleanups ();
- eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
- ? "__gnat_eh_personality_sj"
- : "__gnat_eh_personality");
lang_eh_type_covers = gnat_eh_type_covers;
- lang_eh_runtime_type = gnat_return_tree;
- default_init_unwind_resume_libfunc ();
/* Turn on -fexceptions and -fnon-call-exceptions. The first one triggers
the generation of the necessary exception runtime tables. The second one
@@ -811,3 +809,19 @@ fp_size_to_prec (int size)
gcc_unreachable ();
}
+
+static GTY(()) tree gnat_eh_personality_decl;
+
+static tree
+gnat_eh_personality (void)
+{
+ if (!gnat_eh_personality_decl)
+ gnat_eh_personality_decl
+ = build_personality_function (USING_SJLJ_EXCEPTIONS
+ ? "__gnat_eh_personality_sj"
+ : "__gnat_eh_personality");
+
+ return gnat_eh_personality_decl;
+}
+
+#include "gt-ada-misc.h"
diff --git a/gcc/ada/gcc-interface/targtyps.c b/gcc/ada/gcc-interface/targtyps.c
index 3b8aa5cc9f5..716550e397f 100644
--- a/gcc/ada/gcc-interface/targtyps.c
+++ b/gcc/ada/gcc-interface/targtyps.c
@@ -28,8 +28,9 @@
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
#include "tree.h"
+#include "tm.h"
+#include "tm_p.h"
#include "ada.h"
#include "types.h"
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 29ab72a365f..a90a7a060bc 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -1026,14 +1026,14 @@ Pragma_to_gnu (Node_Id gnat_node)
asm_constraint = build_string (strlen (comment), comment);
free (comment);
#endif
- gnu_expr = build4 (ASM_EXPR, void_type_node,
+ gnu_expr = build5 (ASM_EXPR, void_type_node,
asm_constraint,
NULL_TREE,
tree_cons
(build_tree_list (NULL_TREE,
build_string (1, "g")),
gnu_expr, NULL_TREE),
- NULL_TREE);
+ NULL_TREE, NULL_TREE);
ASM_VOLATILE_P (gnu_expr) = 1;
set_expr_location_from_node (gnu_expr, gnat_node);
append_to_statement_list (gnu_expr, &gnu_result);
@@ -1279,9 +1279,16 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
case Attr_Max_Size_In_Storage_Elements:
gnu_expr = gnu_prefix;
- /* Remove NOPs from GNU_EXPR and conversions from GNU_PREFIX.
- We only use GNU_EXPR to see if a COMPONENT_REF was involved. */
- while (TREE_CODE (gnu_expr) == NOP_EXPR)
+ /* Remove NOPs and conversions between original and packable version
+ from GNU_EXPR, and conversions from GNU_PREFIX. We use GNU_EXPR
+ to see if a COMPONENT_REF was involved. */
+ while (TREE_CODE (gnu_expr) == NOP_EXPR
+ || (TREE_CODE (gnu_expr) == VIEW_CONVERT_EXPR
+ && TREE_CODE (TREE_TYPE (gnu_expr)) == RECORD_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_expr, 0)))
+ == RECORD_TYPE
+ && TYPE_NAME (TREE_TYPE (gnu_expr))
+ == TYPE_NAME (TREE_TYPE (TREE_OPERAND (gnu_expr, 0)))))
gnu_expr = TREE_OPERAND (gnu_expr, 0);
gnu_prefix = remove_conversions (gnu_prefix, true);
@@ -3304,7 +3311,7 @@ Exception_Handler_to_gnu_zcx (Node_Id gnat_node)
a new occurrence on top of the stack, which means that this top does not
necessarily match the occurrence this handler was dealing with.
- The EXC_PTR_EXPR object references the exception occurrence being
+ __builtin_eh_pointer references the exception occurrence being
propagated. Upon handler entry, this is the exception for which the
handler is triggered. This might not be the case upon handler exit,
however, as we might have a new occurrence propagated by the handler's
@@ -3312,7 +3319,10 @@ Exception_Handler_to_gnu_zcx (Node_Id gnat_node)
We use a local variable to retrieve the incoming value at handler entry
time, and reuse it to feed the end_handler hook's argument at exit. */
- gnu_current_exc_ptr = build0 (EXC_PTR_EXPR, ptr_type_node);
+
+ gnu_current_exc_ptr
+ = build_call_expr (built_in_decls [BUILT_IN_EH_POINTER],
+ 1, integer_zero_node);
gnu_incoming_exc_ptr = create_var_decl (get_identifier ("EXPTR"), NULL_TREE,
ptr_type_node, gnu_current_exc_ptr,
false, false, false, false, NULL,
@@ -5085,9 +5095,9 @@ gnat_to_gnu (Node_Id gnat_node)
TREE_VALUE (tail) = input;
}
- gnu_result = build4 (ASM_EXPR, void_type_node,
+ gnu_result = build5 (ASM_EXPR, void_type_node,
gnu_template, gnu_outputs,
- gnu_inputs, gnu_clobbers);
+ gnu_inputs, gnu_clobbers, NULL_TREE);
ASM_VOLATILE_P (gnu_result) = Is_Asm_Volatile (gnat_node);
}
else
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 9748caf5463..31f24ce0340 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -495,8 +495,12 @@ gnat_pushdecl (tree decl, Node_Id gnat_node)
TYPE_NAME (tt) = decl;
TREE_USED (tt) = TREE_USED (t);
TREE_TYPE (decl) = tt;
- DECL_ORIGINAL_TYPE (decl) = t;
+ if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
+ DECL_ORIGINAL_TYPE (decl) = DECL_ORIGINAL_TYPE (TYPE_NAME (t));
+ else
+ DECL_ORIGINAL_TYPE (decl) = t;
t = NULL_TREE;
+ DECL_ARTIFICIAL (decl) = 0;
}
else if (DECL_ARTIFICIAL (TYPE_NAME (t)) && !DECL_ARTIFICIAL (decl))
;
@@ -3665,6 +3669,18 @@ update_pointer_to (tree old_type, tree new_type)
TYPE_POINTER_TO (new_type) = TYPE_REFERENCE_TO (new_type)
= TREE_TYPE (new_type) = ptr;
+ /* And show the original pointer NEW_PTR to the debugger. This is the
+ counterpart of the equivalent processing in gnat_pushdecl when the
+ unconstrained array type is frozen after access types to it. Note
+ that update_pointer_to can be invoked multiple times on the same
+ couple of types because of the type variants. */
+ if (TYPE_NAME (ptr)
+ && TREE_CODE (TYPE_NAME (ptr)) == TYPE_DECL
+ && !DECL_ORIGINAL_TYPE (TYPE_NAME (ptr)))
+ {
+ DECL_ORIGINAL_TYPE (TYPE_NAME (ptr)) = new_ptr;
+ DECL_ARTIFICIAL (TYPE_NAME (ptr)) = 0;
+ }
for (var = TYPE_MAIN_VARIANT (ptr); var; var = TYPE_NEXT_VARIANT (var))
SET_TYPE_UNCONSTRAINED_ARRAY (var, new_type);
@@ -5439,7 +5455,7 @@ gnat_install_builtins (void)
know about internal specificities and control attributes accordingly, for
instance __builtin_alloca vs no-throw and -fstack-check. We will ignore
the generic definition from builtins.def. */
- build_common_builtin_nodes ();
+ build_common_builtin_nodes (false);
/* Now, install the target specific builtins, such as the AltiVec family on
ppc, and the common set as exposed by builtins.def. */
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index 1f26563397b..e25400d09fc 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -7733,11 +7733,11 @@ Followed.
In addition to the implementation dependent pragmas and attributes, and
the implementation advice, there are a number of other Ada features
that are potentially implementation dependent. These are mentioned
-throughout the Ada Reference Manual, and are summarized in annex M@.
+throughout the Ada Reference Manual, and are summarized in Annex M@.
A requirement for conforming Ada compilers is that they provide
documentation describing how the implementation deals with each of these
-issues. In this chapter, you will find each point in annex M listed
+issues. In this chapter, you will find each point in Annex M listed
followed by a description in italic font of how GNAT
@c SGI info:
@ignore
diff --git a/gcc/ada/gnatcmd.adb b/gcc/ada/gnatcmd.adb
index 42d08dcd48f..563b92d150e 100644
--- a/gcc/ada/gnatcmd.adb
+++ b/gcc/ada/gnatcmd.adb
@@ -26,7 +26,7 @@
with GNAT.Directory_Operations; use GNAT.Directory_Operations;
with Csets;
-with Makeutl;
+with Makeutl; use Makeutl;
with MLib.Tgt; use MLib.Tgt;
with MLib.Utl;
with MLib.Fil;
@@ -38,6 +38,7 @@ with Prj; use Prj;
with Prj.Env;
with Prj.Ext; use Prj.Ext;
with Prj.Pars;
+with Prj.Tree; use Prj.Tree;
with Prj.Util; use Prj.Util;
with Sinput.P;
with Snames; use Snames;
@@ -57,7 +58,7 @@ with GNAT.OS_Lib; use GNAT.OS_Lib;
with VMS_Conv; use VMS_Conv;
procedure GNATCmd is
- Project_Tree : constant Project_Tree_Ref := new Project_Tree_Data;
+ Project_Node_Tree : Project_Node_Tree_Ref;
Project_File : String_Access;
Project : Prj.Project_Id;
Current_Verbosity : Prj.Verbosity := Prj.Default;
@@ -1268,6 +1269,9 @@ begin
Snames.Initialize;
+ Project_Node_Tree := new Project_Node_Tree_Data;
+ Prj.Tree.Initialize (Project_Node_Tree);
+
Prj.Initialize (Project_Tree);
Last_Switches.Init;
@@ -1600,7 +1604,7 @@ begin
and then Argv (Argv'First + 1 .. Argv'First + 2) = "aP"
then
Add_Search_Project_Directory
- (Argv (Argv'First + 3 .. Argv'Last));
+ (Project_Node_Tree, Argv (Argv'First + 3 .. Argv'Last));
Remove_Switch (Arg_Num);
@@ -1694,7 +1698,8 @@ begin
begin
if Equal_Pos >= Argv'First + 3 and then
Equal_Pos /= Argv'Last then
- Add (External_Name =>
+ Add (Project_Node_Tree,
+ External_Name =>
Argv (Argv'First + 2 .. Equal_Pos - 1),
Value => Argv (Equal_Pos + 1 .. Argv'Last));
else
@@ -1753,6 +1758,7 @@ begin
Prj.Pars.Parse
(Project => Project,
In_Tree => Project_Tree,
+ In_Node_Tree => Project_Node_Tree,
Project_File_Name => Project_File.all,
Flags => Gnatmake_Flags,
Packages_To_Check => Packages_To_Check);
@@ -2114,7 +2120,7 @@ begin
-- arguments.
for J in 1 .. Last_Switches.Last loop
- Test_If_Relative_Path
+ GNATCmd.Test_If_Relative_Path
(Last_Switches.Table (J), Current_Work_Dir);
end loop;
@@ -2124,7 +2130,7 @@ begin
Project_Dir : constant String := Name_Buffer (1 .. Name_Len);
begin
for J in 1 .. First_Switches.Last loop
- Test_If_Relative_Path
+ GNATCmd.Test_If_Relative_Path
(First_Switches.Table (J), Project_Dir);
end loop;
end;
diff --git a/gcc/ada/gprep.adb b/gcc/ada/gprep.adb
index ec56bcc171f..b5e6b063cac 100644
--- a/gcc/ada/gprep.adb
+++ b/gcc/ada/gprep.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2009, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -55,6 +55,14 @@ package body GPrep is
-- Argument Line Data --
------------------------
+ Unix_Line_Terminators : Boolean := False;
+ -- Set to True with option -T
+
+ type String_Array is array (Boolean) of String_Access;
+ Yes_No : constant String_Array :=
+ (False => new String'("YES"),
+ True => new String'("NO"));
+
Infile_Name : Name_Id := No_Name;
Outfile_Name : Name_Id := No_Name;
Deffile_Name : Name_Id := No_Name;
@@ -484,7 +492,12 @@ package body GPrep is
-- Create the output file (fails if this does not work)
begin
- Create (Text_Outfile, Out_File, Get_Name_String (Outfile_Name));
+ Create
+ (File => Text_Outfile,
+ Mode => Out_File,
+ Name => Get_Name_String (Outfile_Name),
+ Form => "Text_Translation=" &
+ Yes_No (Unix_Line_Terminators).all);
exception
when others =>
@@ -722,7 +735,7 @@ package body GPrep is
loop
begin
- Switch := GNAT.Command_Line.Getopt ("D: b c C r s u v");
+ Switch := GNAT.Command_Line.Getopt ("D: b c C r s T u v");
case Switch is
@@ -748,6 +761,9 @@ package body GPrep is
when 's' =>
Opt.List_Preprocessing_Symbols := True;
+ when 'T' =>
+ Unix_Line_Terminators := True;
+
when 'u' =>
Opt.Undefined_Symbols_Are_False := True;
@@ -813,6 +829,7 @@ package body GPrep is
Write_Line (" -D Associate symbol with value");
Write_Line (" -r Generate Source_Reference pragma");
Write_Line (" -s Print a sorted list of symbol names and values");
+ Write_Line (" -T Use LF as line terminators");
Write_Line (" -u Treat undefined symbols as FALSE");
Write_Line (" -v Verbose mode");
Write_Eol;
diff --git a/gcc/ada/make.adb b/gcc/ada/make.adb
index 20fc989a015..dacf290c273 100644
--- a/gcc/ada/make.adb
+++ b/gcc/ada/make.adb
@@ -49,10 +49,16 @@ with Prj; use Prj;
with Prj.Com;
with Prj.Env;
with Prj.Pars;
+with Prj.Tree; use Prj.Tree;
with Prj.Util;
with SFN_Scan;
with Sinput.P;
with Snames; use Snames;
+
+pragma Warnings (Off);
+with System.HTable;
+pragma Warnings (On);
+
with Switch; use Switch;
with Switch.M; use Switch.M;
with Targparm; use Targparm;
@@ -68,8 +74,6 @@ with GNAT.Dynamic_HTables; use GNAT.Dynamic_HTables;
with GNAT.Case_Util; use GNAT.Case_Util;
with GNAT.OS_Lib; use GNAT.OS_Lib;
-with System.HTable;
-
package body Make is
use ASCII;
@@ -640,7 +644,7 @@ package body Make is
-- directory of the ultimate extending project. If it is not, we ignore
-- the fact that this ALI file is read-only.
- procedure Process_Multilib;
+ procedure Process_Multilib (Project_Node_Tree : Project_Node_Tree_Ref);
-- Add appropriate --RTS argument to handle multilib
----------------------------------------------------
@@ -710,7 +714,8 @@ package body Make is
File_Name : String;
Index : Int;
Program : Make_Program_Type;
- Unknown_Switches_To_The_Compiler : Boolean := True);
+ Unknown_Switches_To_The_Compiler : Boolean := True;
+ Project_Node_Tree : Project_Node_Tree_Ref);
procedure Add_Switch
(S : String_Access;
Program : Make_Program_Type;
@@ -998,7 +1003,7 @@ package body Make is
-- during a compilation are also transitively included in the W section
-- of the originally compiled file.
- procedure Initialize;
+ procedure Initialize (Project_Node_Tree : out Project_Node_Tree_Ref);
-- Performs default and package initialization. Therefore,
-- Compile_Sources can be called by an external unit.
@@ -1010,8 +1015,13 @@ package body Make is
-- Args must have a lower bound of 1. Success indicates if the link
-- succeeded or not.
- procedure Scan_Make_Arg (Argv : String; And_Save : Boolean);
- -- Scan make arguments. Argv is a single argument to be processed
+ procedure Scan_Make_Arg
+ (Project_Node_Tree : Project_Node_Tree_Ref;
+ Argv : String;
+ And_Save : Boolean);
+ -- Scan make arguments. Argv is a single argument to be processed.
+ -- Project_Node_Tree will be used to initialize external references. It
+ -- must have been initialized.
-------------------
-- Add_Arguments --
@@ -1233,7 +1243,8 @@ package body Make is
File_Name : String;
Index : Int;
Program : Make_Program_Type;
- Unknown_Switches_To_The_Compiler : Boolean := True)
+ Unknown_Switches_To_The_Compiler : Boolean := True;
+ Project_Node_Tree : Project_Node_Tree_Ref)
is
Switches : Variable_Value;
Switch_List : String_List_Id;
@@ -1274,7 +1285,8 @@ package body Make is
Write_Line (Argv);
end if;
- Scan_Make_Arg (Argv, And_Save => False);
+ Scan_Make_Arg
+ (Project_Node_Tree, Argv, And_Save => False);
if not Gnatmake_Switch_Found
and then not Switch_May_Be_Passed_To_The_Compiler
@@ -4019,6 +4031,8 @@ package body Make is
Mapping_Path : Path_Name_Type := No_Path;
-- The path name of the mapping file
+ Project_Node_Tree : Project_Node_Tree_Ref;
+
Discard : Boolean;
pragma Warnings (Off, Discard);
@@ -4366,7 +4380,7 @@ package body Make is
Obsoleted.Reset;
- Make.Initialize;
+ Make.Initialize (Project_Node_Tree);
Bind_Shared := No_Shared_Switch'Access;
Link_With_Shared_Libgcc := No_Shared_Libgcc_Switch'Access;
@@ -4845,7 +4859,8 @@ package body Make is
end if;
Add_Switches
- (File_Name => Main_Unit_File_Name,
+ (Project_Node_Tree => Project_Node_Tree,
+ File_Name => Main_Unit_File_Name,
Index => Main_Index,
The_Package => Builder_Package,
Program => None,
@@ -4900,7 +4915,8 @@ package body Make is
end if;
Add_Switches
- (File_Name => " ",
+ (Project_Node_Tree => Project_Node_Tree,
+ File_Name => " ",
Index => 0,
The_Package => Builder_Package,
Program => None,
@@ -4916,7 +4932,8 @@ package body Make is
end if;
Add_Switches
- (File_Name => " ",
+ (Project_Node_Tree => Project_Node_Tree,
+ File_Name => " ",
Index => 0,
The_Package => Builder_Package,
Program => None);
@@ -5007,10 +5024,11 @@ package body Make is
end if;
Add_Switches
- (File_Name => Main_Unit_File_Name,
- Index => Main_Index,
- The_Package => Binder_Package,
- Program => Binder);
+ (Project_Node_Tree => Project_Node_Tree,
+ File_Name => Main_Unit_File_Name,
+ Index => Main_Index,
+ The_Package => Binder_Package,
+ Program => Binder);
end if;
-- Add linker switches from the project file for the first main
@@ -5023,10 +5041,11 @@ package body Make is
end if;
Add_Switches
- (File_Name => Main_Unit_File_Name,
- Index => Main_Index,
- The_Package => Linker_Package,
- Program => Linker);
+ (Project_Node_Tree => Project_Node_Tree,
+ File_Name => Main_Unit_File_Name,
+ Index => Main_Index,
+ The_Package => Linker_Package,
+ Program => Linker);
end if;
end;
end if;
@@ -6310,10 +6329,11 @@ package body Make is
end if;
Add_Switches
- (File_Name => Main_Unit_File_Name,
- Index => Main_Index,
- The_Package => Binder_Package,
- Program => Binder);
+ (Project_Node_Tree => Project_Node_Tree,
+ File_Name => Main_Unit_File_Name,
+ Index => Main_Index,
+ The_Package => Binder_Package,
+ Program => Binder);
end if;
-- Add linker switches from the project file for this main,
@@ -6327,10 +6347,11 @@ package body Make is
end if;
Add_Switches
- (File_Name => Main_Unit_File_Name,
- Index => Main_Index,
- The_Package => Linker_Package,
- Program => Linker);
+ (Project_Node_Tree => Project_Node_Tree,
+ File_Name => Main_Unit_File_Name,
+ Index => Main_Index,
+ The_Package => Linker_Package,
+ Program => Linker);
end if;
-- As we are using a project file, for relative paths we add
@@ -6521,7 +6542,7 @@ package body Make is
-- Initialize --
----------------
- procedure Initialize is
+ procedure Initialize (Project_Node_Tree : out Project_Node_Tree_Ref) is
procedure Check_Version_And_Help is
new Check_Version_And_Help_G (Makeusg);
@@ -6529,6 +6550,13 @@ package body Make is
-- Start of processing for Initialize
begin
+ -- Prepare the project's tree, since this is used to hold external
+ -- references, project path and other attributes that can be impacted by
+ -- the command line switches
+
+ Project_Node_Tree := new Project_Node_Tree_Data;
+ Prj.Tree.Initialize (Project_Node_Tree);
+
-- Override default initialization of Check_Object_Consistency since
-- this is normally False for GNATBIND, but is True for GNATMAKE since
-- we do not need to check source consistency again once GNATMAKE has
@@ -6611,11 +6639,12 @@ package body Make is
-- do not include --version or --help.
Scan_Args : for Next_Arg in 1 .. Argument_Count loop
- Scan_Make_Arg (Argument (Next_Arg), And_Save => True);
+ Scan_Make_Arg
+ (Project_Node_Tree, Argument (Next_Arg), And_Save => True);
end loop Scan_Args;
if N_M_Switch > 0 and RTS_Specified = null then
- Process_Multilib;
+ Process_Multilib (Project_Node_Tree);
end if;
if Commands_To_Stdout then
@@ -6700,7 +6729,8 @@ package body Make is
In_Tree => Project_Tree,
Project_File_Name => Project_File_Name.all,
Packages_To_Check => Packages_To_Check_By_Gnatmake,
- Flags => Gnatmake_Flags);
+ Flags => Gnatmake_Flags,
+ In_Node_Tree => Project_Node_Tree);
-- The parsing of project files may have changed the current output
@@ -7281,7 +7311,9 @@ package body Make is
-- Process_Multilib --
----------------------
- procedure Process_Multilib is
+ procedure Process_Multilib
+ (Project_Node_Tree : Project_Node_Tree_Ref)
+ is
Output_FD : File_Descriptor;
Output_Name : String_Access;
Arg_Index : Natural := 0;
@@ -7296,8 +7328,14 @@ package body Make is
begin
pragma Assert (N_M_Switch > 0 and RTS_Specified = null);
- -- This loop needs commenting ??? In fact this entire body is
- -- under-commented ??? And the spec is not much help :-(
+ -- In case we detected a multilib switch and the user has not
+ -- manually specified a specific RTS we emulate the following command:
+ -- gnatmake $FLAGS --RTS=$(gcc -print-multi-directory $FLAGS)
+
+ -- First select the flags which might have an impact on multilib
+ -- processing. Note that this is an heuristic selection and it
+ -- will need to be maintained over time. The condition has to
+ -- be kept synchronized with N_M_Switch counting in Scan_Make_Arg.
for Next_Arg in 1 .. Argument_Count loop
declare
@@ -7322,6 +7360,10 @@ package body Make is
Args (Args'Last) := new String'("-print-multi-directory");
+ -- Call the GCC driver with the collected flags and save its
+ -- output. Alternate design would be to link in gnatmake the
+ -- relevant part of the GCC driver.
+
if Saved_Gcc /= null then
Multilib_Gcc := Saved_Gcc;
else
@@ -7344,6 +7386,8 @@ package body Make is
return;
end if;
+ -- Parse the GCC driver output which is a single line, removing CR/LF
+
Output_FD := Open_Read (Output_Name.all, Binary);
if Output_FD = Invalid_FD then
@@ -7362,12 +7406,17 @@ package body Make is
end if;
end loop;
+ -- In case the standard RTS is selected do nothing
+
if N_Read = 0 or else Line (1 .. N_Read) = "." then
return;
end if;
- Scan_Make_Arg ("-margs", And_Save => True);
- Scan_Make_Arg ("--RTS=" & Line (1 .. N_Read), And_Save => True);
+ -- Otherwise add -margs --RTS=output
+
+ Scan_Make_Arg (Project_Node_Tree, "-margs", And_Save => True);
+ Scan_Make_Arg
+ (Project_Node_Tree, "--RTS=" & Line (1 .. N_Read), And_Save => True);
end Process_Multilib;
-----------------------------
@@ -7469,7 +7518,11 @@ package body Make is
-- Scan_Make_Arg --
-------------------
- procedure Scan_Make_Arg (Argv : String; And_Save : Boolean) is
+ procedure Scan_Make_Arg
+ (Project_Node_Tree : Project_Node_Tree_Ref;
+ Argv : String;
+ And_Save : Boolean)
+ is
Success : Boolean;
begin
@@ -7734,7 +7787,7 @@ package body Make is
Add_Switch (Argv, Linker, And_Save => And_Save);
else
- Scan_Make_Switches (Argv, Success);
+ Scan_Make_Switches (Project_Node_Tree, Argv, Success);
end if;
-- If we have seen a regular switch process it
@@ -7845,6 +7898,9 @@ package body Make is
Add_Switch (Argv, Compiler, And_Save => And_Save);
Add_Switch (Argv, Linker, And_Save => And_Save);
+ -- The following condition has to be kept synchronized with
+ -- the Process_Multilib one.
+
if Argv (2) = 'm'
and then Argv /= "-mieee"
then
@@ -7870,7 +7926,7 @@ package body Make is
"project file");
else
- Scan_Make_Switches (Argv, Success);
+ Scan_Make_Switches (Project_Node_Tree, Argv, Success);
end if;
-- -d
@@ -7887,13 +7943,13 @@ package body Make is
Make_Failed ("-i cannot be used in conjunction with a " &
"project file");
else
- Scan_Make_Switches (Argv, Success);
+ Scan_Make_Switches (Project_Node_Tree, Argv, Success);
end if;
-- -j (need to save the result)
elsif Argv (2) = 'j' then
- Scan_Make_Switches (Argv, Success);
+ Scan_Make_Switches (Project_Node_Tree, Argv, Success);
if And_Save then
Saved_Maximum_Processes := Maximum_Processes;
@@ -7982,7 +8038,7 @@ package body Make is
-- -Xext=val (External assignment)
elsif Argv (2) = 'X'
- and then Is_External_Assignment (Argv)
+ and then Is_External_Assignment (Project_Node_Tree, Argv)
then
-- Is_External_Assignment has side effects
-- when it returns True;
@@ -8033,7 +8089,8 @@ package body Make is
-- is passed to the compiler.
else
- Scan_Make_Switches (Argv, Gnatmake_Switch_Found);
+ Scan_Make_Switches
+ (Project_Node_Tree, Argv, Gnatmake_Switch_Found);
if not Gnatmake_Switch_Found then
Add_Switch (Argv, Compiler, And_Save => And_Save);
diff --git a/gcc/ada/makeutl.adb b/gcc/ada/makeutl.adb
index c0d9de4d764..a570737d711 100644
--- a/gcc/ada/makeutl.adb
+++ b/gcc/ada/makeutl.adb
@@ -447,10 +447,12 @@ package body Makeutl is
-- Is_External_Assignment --
----------------------------
- function Is_External_Assignment (Argv : String) return Boolean is
+ function Is_External_Assignment
+ (Tree : Prj.Tree.Project_Node_Tree_Ref;
+ Argv : String) return Boolean
+ is
Start : Positive := 3;
Finish : Natural := Argv'Last;
- Equal_Pos : Natural;
pragma Assert (Argv'First = 1);
pragma Assert (Argv (1 .. 2) = "-X");
@@ -468,20 +470,9 @@ package body Makeutl is
end if;
end if;
- Equal_Pos := Start;
-
- while Equal_Pos <= Finish and then Argv (Equal_Pos) /= '=' loop
- Equal_Pos := Equal_Pos + 1;
- end loop;
-
- if Equal_Pos = Start or else Equal_Pos > Finish then
- return False;
- else
- Prj.Ext.Add
- (External_Name => Argv (Start .. Equal_Pos - 1),
- Value => Argv (Equal_Pos + 1 .. Finish));
- return True;
- end if;
+ return Prj.Ext.Check
+ (Tree => Tree,
+ Declaration => Argv (Start .. Finish));
end Is_External_Assignment;
---------------
diff --git a/gcc/ada/makeutl.ads b/gcc/ada/makeutl.ads
index 1dff5a16aa1..95114f07c9a 100644
--- a/gcc/ada/makeutl.ads
+++ b/gcc/ada/makeutl.ads
@@ -28,6 +28,7 @@ with Namet; use Namet;
with Opt;
with Osint;
with Prj; use Prj;
+with Prj.Tree;
with Types; use Types;
with GNAT.OS_Lib; use GNAT.OS_Lib;
@@ -83,7 +84,9 @@ package Makeutl is
-- source files are still associated with the same units). Return True
-- if everything is still valid
- function Is_External_Assignment (Argv : String) return Boolean;
+ function Is_External_Assignment
+ (Tree : Prj.Tree.Project_Node_Tree_Ref;
+ Argv : String) return Boolean;
-- Verify that an external assignment switch is syntactically correct
--
-- Correct forms are:
diff --git a/gcc/ada/prj-conf.adb b/gcc/ada/prj-conf.adb
index 879178de122..bcf434b15e1 100644
--- a/gcc/ada/prj-conf.adb
+++ b/gcc/ada/prj-conf.adb
@@ -29,6 +29,7 @@ with Makeutl; use Makeutl;
with MLib.Tgt;
with Opt; use Opt;
with Output; use Output;
+with Prj.Env;
with Prj.Err;
with Prj.Part;
with Prj.PP;
@@ -697,6 +698,8 @@ package body Prj.Conf is
Args : Argument_List (1 .. 5);
Arg_Last : Positive;
+ Obj_Dir_Exists : Boolean := True;
+
begin
-- Check if the object directory exists. If Setup_Projects is True
-- (-p) and directory does not exist, attempt to create it.
@@ -731,6 +734,7 @@ package body Prj.Conf is
Prj.Err.Error_Msg
(Flags,
"?object directory " & Obj_Dir & " does not exist");
+ Obj_Dir_Exists := False;
when Silent =>
null;
end case;
@@ -744,8 +748,35 @@ package body Prj.Conf is
-- If no config file was specified, set the auto.cgpr one
if Config_File_Name = "" then
- Args (3) := new String'
- (Obj_Dir & Directory_Separator & Auto_Cgpr);
+ if Obj_Dir_Exists then
+ Args (3) :=
+ new String'(Obj_Dir & Directory_Separator & Auto_Cgpr);
+
+ else
+ declare
+ Path_FD : File_Descriptor;
+ Path_Name : Path_Name_Type;
+
+ begin
+ Prj.Env.Create_Temp_File
+ (In_Tree => Project_Tree,
+ Path_FD => Path_FD,
+ Path_Name => Path_Name,
+ File_Use => "configuration file");
+
+ if Path_FD /= Invalid_FD then
+ Args (3) := new String'(Get_Name_String (Path_Name));
+ GNAT.OS_Lib.Close (Path_FD);
+
+ else
+ -- We'll have an error message later on
+
+ Args (3) :=
+ new String'
+ (Obj_Dir & Directory_Separator & Auto_Cgpr);
+ end if;
+ end;
+ end if;
else
Args (3) := new String'(Config_File_Name);
end if;
@@ -783,9 +814,16 @@ package body Prj.Conf is
Write_Eol;
elsif not Quiet_Output then
- Write_Str ("creating ");
- Write_Str (Simple_Name (Args (3).all));
- Write_Eol;
+ -- Display no message if we are creating auto.cgpr, unless in
+ -- verbose mode
+
+ if Config_File_Name /= ""
+ or else Verbose_Mode
+ then
+ Write_Str ("creating ");
+ Write_Str (Simple_Name (Args (3).all));
+ Write_Eol;
+ end if;
end if;
Spawn (Gprconfig_Path.all, Args (1 .. Arg_Last) & Switches.all,
@@ -1000,7 +1038,6 @@ package body Prj.Conf is
begin
-- Parse the user project tree
- Prj.Tree.Initialize (Project_Node_Tree);
Prj.Initialize (Project_Tree);
Main_Project := No_Project;
diff --git a/gcc/ada/prj-conf.ads b/gcc/ada/prj-conf.ads
index f228ae3fde3..82b8dc34726 100644
--- a/gcc/ada/prj-conf.ads
+++ b/gcc/ada/prj-conf.ads
@@ -59,6 +59,10 @@ package Prj.Conf is
-- Find the main configuration project and parse the project tree rooted at
-- this configuration project.
--
+ -- Project_Node_Tree must have been initialized first (and possibly the
+ -- value for external references and project path should also have been
+ -- set).
+ --
-- If the processing fails, Main_Project is set to No_Project. If the error
-- happend while parsing the project itself (ie creating the tree),
-- User_Project_Node is also set to Empty_Node.
diff --git a/gcc/ada/prj-env.adb b/gcc/ada/prj-env.adb
index 0ffacdbdc5b..c5182abea09 100644
--- a/gcc/ada/prj-env.adb
+++ b/gcc/ada/prj-env.adb
@@ -97,14 +97,6 @@ package body Prj.Env is
-- Return a project that is either Project or an extended ancestor of
-- Project that itself is not extended.
- procedure Create_Temp_File
- (In_Tree : Project_Tree_Ref;
- Path_FD : out File_Descriptor;
- Path_Name : out Path_Name_Type;
- File_Use : String);
- -- Create a temporary file, and fail with an error if it could not be
- -- created.
-
----------------------
-- Ada_Include_Path --
----------------------
diff --git a/gcc/ada/prj-env.ads b/gcc/ada/prj-env.ads
index ffcea0756b6..27259c29b98 100644
--- a/gcc/ada/prj-env.ads
+++ b/gcc/ada/prj-env.ads
@@ -39,6 +39,13 @@ package Prj.Env is
-- of package Fmap), so that Osint.Find_File will find the correct path
-- corresponding to a source.
+ procedure Create_Temp_File
+ (In_Tree : Project_Tree_Ref;
+ Path_FD : out File_Descriptor;
+ Path_Name : out Path_Name_Type;
+ File_Use : String);
+ -- Create temporary file, and fail with an error if it could not be created
+
procedure Create_Mapping_File
(Project : Project_Id;
Language : Name_Id;
diff --git a/gcc/ada/prj-ext.adb b/gcc/ada/prj-ext.adb
index 8098a3a23b1..9c9707c1cfa 100644
--- a/gcc/ada/prj-ext.adb
+++ b/gcc/ada/prj-ext.adb
@@ -23,63 +23,33 @@
-- --
------------------------------------------------------------------------------
+with System.OS_Lib; use System.OS_Lib;
with Hostparm;
-with Makeutl; use Makeutl;
-with Osint; use Osint;
+with Makeutl; use Makeutl;
+with Osint; use Osint;
+with Prj.Tree; use Prj.Tree;
with Sdefault;
-with Table;
-
-with GNAT.HTable;
package body Prj.Ext is
- Ada_Project_Path : constant String := "ADA_PROJECT_PATH";
- -- Name of alternate env. variable that contain path name(s) of directories
- -- where project files may reside. GPR_PROJECT_PATH has precedence over
- -- ADA_PROJECT_PATH.
-
- Gpr_Prj_Path : constant String_Access := Getenv (Gpr_Project_Path);
- Ada_Prj_Path : constant String_Access := Getenv (Ada_Project_Path);
- -- The path name(s) of directories where project files may reside.
- -- May be empty.
-
No_Project_Default_Dir : constant String := "-";
+ -- Indicator in the project path to indicate that the default search
+ -- directories should not be added to the path
- Current_Project_Path : String_Access;
- -- The project path. Initialized by procedure Initialize_Project_Path
- -- below.
+ Uninitialized_Prefix : constant String := '#' & Path_Separator;
+ -- Prefix to indicate that the project path has not been initilized yet.
+ -- Must be two characters long
- procedure Initialize_Project_Path;
+ procedure Initialize_Project_Path (Tree : Prj.Tree.Project_Node_Tree_Ref);
-- Initialize Current_Project_Path
- package Htable is new GNAT.HTable.Simple_HTable
- (Header_Num => Header_Num,
- Element => Name_Id,
- No_Element => No_Name,
- Key => Name_Id,
- Hash => Hash,
- Equal => "=");
- -- External references are stored in this hash table, either by procedure
- -- Add (directly or through a call to function Check) or by function
- -- Value_Of when an environment variable is found non empty. Value_Of
- -- first for external reference in this table, before checking the
- -- environment. Htable is emptied (reset) by procedure Reset.
-
- package Search_Directories is new Table.Table
- (Table_Component_Type => Name_Id,
- Table_Index_Type => Natural,
- Table_Low_Bound => 1,
- Table_Initial => 4,
- Table_Increment => 100,
- Table_Name => "Prj.Ext.Search_Directories");
- -- The table for the directories specified with -aP switches
-
---------
-- Add --
---------
procedure Add
- (External_Name : String;
+ (Tree : Prj.Tree.Project_Node_Tree_Ref;
+ External_Name : String;
Value : String)
is
The_Key : Name_Id;
@@ -92,34 +62,45 @@ package body Prj.Ext is
Name_Buffer (1 .. Name_Len) := External_Name;
Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
The_Key := Name_Find;
- Htable.Set (The_Key, The_Value);
+ Name_To_Name_HTable.Set (Tree.External_References, The_Key, The_Value);
end Add;
- -----------
----------------------------------
-- Add_Search_Project_Directory --
----------------------------------
- procedure Add_Search_Project_Directory (Path : String) is
+ procedure Add_Search_Project_Directory
+ (Tree : Prj.Tree.Project_Node_Tree_Ref;
+ Path : String)
+ is
+ Tmp : String_Access;
begin
- Name_Len := 0;
- Add_Str_To_Name_Buffer (Path);
- Search_Directories.Append (Name_Find);
+ if Tree.Project_Path = null then
+ Tree.Project_Path := new String'(Uninitialized_Prefix & Path);
+ else
+ Tmp := Tree.Project_Path;
+ Tree.Project_Path := new String'(Tmp.all & Path_Separator & Path);
+ Free (Tmp);
+ end if;
end Add_Search_Project_Directory;
+ -----------
-- Check --
-----------
- function Check (Declaration : String) return Boolean is
+ function Check
+ (Tree : Prj.Tree.Project_Node_Tree_Ref;
+ Declaration : String) return Boolean
+ is
begin
for Equal_Pos in Declaration'Range loop
if Declaration (Equal_Pos) = '=' then
exit when Equal_Pos = Declaration'First;
- exit when Equal_Pos = Declaration'Last;
Add
- (External_Name =>
+ (Tree => Tree,
+ External_Name =>
Declaration (Declaration'First .. Equal_Pos - 1),
- Value =>
+ Value =>
Declaration (Equal_Pos + 1 .. Declaration'Last));
return True;
end if;
@@ -132,42 +113,57 @@ package body Prj.Ext is
-- Initialize_Project_Path --
-----------------------------
- procedure Initialize_Project_Path is
+ procedure Initialize_Project_Path (Tree : Prj.Tree.Project_Node_Tree_Ref) is
Add_Default_Dir : Boolean := True;
First : Positive;
Last : Positive;
New_Len : Positive;
New_Last : Positive;
- begin
- -- The current directory is always first
+ Ada_Project_Path : constant String := "ADA_PROJECT_PATH";
+ Gpr_Project_Path : constant String := "GPR_PROJECT_PATH";
+ -- Name of alternate env. variable that contain path name(s) of
+ -- directories where project files may reside. GPR_PROJECT_PATH has
+ -- precedence over ADA_PROJECT_PATH.
- Name_Len := 1;
- Name_Buffer (Name_Len) := '.';
+ Gpr_Prj_Path : String_Access := Getenv (Gpr_Project_Path);
+ Ada_Prj_Path : String_Access := Getenv (Ada_Project_Path);
+ -- The path name(s) of directories where project files may reside.
+ -- May be empty.
- -- If there are directories in the Search_Directories table, add them
+ begin
+ -- The current directory is always first in the search path. Since the
+ -- Project_Path currently starts with '#:' as a sign that it isn't
+ -- initialized, we simply replace '#' with '.'
+
+ if Tree.Project_Path = null then
+ Tree.Project_Path := new String'('.' & Path_Separator);
+ else
+ Tree.Project_Path (Tree.Project_Path'First) := '.';
+ end if;
- for J in 1 .. Search_Directories.Last loop
- Name_Len := Name_Len + 1;
- Name_Buffer (Name_Len) := Path_Separator;
- Add_Str_To_Name_Buffer
- (Get_Name_String (Search_Directories.Table (J)));
- end loop;
+ -- Then the reset of the project path (if any) currently contains the
+ -- directories added through Add_Search_Project_Directory
- -- If environment variable is defined and not empty, add its content
+ -- If environment variables are defined and not empty, add their content
if Gpr_Prj_Path.all /= "" then
- Name_Len := Name_Len + 1;
- Name_Buffer (Name_Len) := Path_Separator;
- Add_Str_To_Name_Buffer (Gpr_Prj_Path.all);
+ Add_Search_Project_Directory (Tree, Gpr_Prj_Path.all);
end if;
+ Free (Gpr_Prj_Path);
+
if Ada_Prj_Path.all /= "" then
- Name_Len := Name_Len + 1;
- Name_Buffer (Name_Len) := Path_Separator;
- Add_Str_To_Name_Buffer (Ada_Prj_Path.all);
+ Add_Search_Project_Directory (Tree, Ada_Prj_Path.all);
end if;
+ Free (Ada_Prj_Path);
+
+ -- Copy to Name_Buffer, since we will need to manipulate the path
+
+ Name_Len := Tree.Project_Path'Length;
+ Name_Buffer (1 .. Name_Len) := Tree.Project_Path.all;
+
-- Scan the directory path to see if "-" is one of the directories.
-- Remove each occurrence of "-" and set Add_Default_Dir to False.
-- Also resolve relative paths and symbolic links.
@@ -239,6 +235,8 @@ package body Prj.Ext is
First := Last + 1;
end loop;
+ Free (Tree.Project_Path);
+
-- Set the initial value of Current_Project_Path
if Add_Default_Dir then
@@ -260,7 +258,7 @@ package body Prj.Ext is
end if;
else
- Current_Project_Path :=
+ Tree.Project_Path :=
new String'(Name_Buffer (1 .. Name_Len) & Path_Separator &
Prefix.all &
".." & Directory_Separator &
@@ -272,8 +270,8 @@ package body Prj.Ext is
end;
end if;
- if Current_Project_Path = null then
- Current_Project_Path := new String'(Name_Buffer (1 .. Name_Len));
+ if Tree.Project_Path = null then
+ Tree.Project_Path := new String'(Name_Buffer (1 .. Name_Len));
end if;
end Initialize_Project_Path;
@@ -281,32 +279,36 @@ package body Prj.Ext is
-- Project_Path --
------------------
- function Project_Path return String is
+ function Project_Path (Tree : Project_Node_Tree_Ref) return String is
begin
- if Current_Project_Path = null then
- Initialize_Project_Path;
+ if Tree.Project_Path = null
+ or else Tree.Project_Path (Tree.Project_Path'First) = '#'
+ then
+ Initialize_Project_Path (Tree);
end if;
- return Current_Project_Path.all;
+ return Tree.Project_Path.all;
end Project_Path;
-----------
-- Reset --
-----------
- procedure Reset is
+ procedure Reset (Tree : Prj.Tree.Project_Node_Tree_Ref) is
begin
- Htable.Reset;
+ Name_To_Name_HTable.Reset (Tree.External_References);
end Reset;
----------------------
-- Set_Project_Path --
----------------------
- procedure Set_Project_Path (New_Path : String) is
+ procedure Set_Project_Path
+ (Tree : Project_Node_Tree_Ref;
+ New_Path : String) is
begin
- Free (Current_Project_Path);
- Current_Project_Path := new String'(New_Path);
+ Free (Tree.Project_Path);
+ Tree.Project_Path := new String'(New_Path);
end Set_Project_Path;
--------------
@@ -314,7 +316,8 @@ package body Prj.Ext is
--------------
function Value_Of
- (External_Name : Name_Id;
+ (Tree : Prj.Tree.Project_Node_Tree_Ref;
+ External_Name : Name_Id;
With_Default : Name_Id := No_Name)
return Name_Id
is
@@ -325,7 +328,8 @@ package body Prj.Ext is
Canonical_Case_File_Name (Name);
Name_Len := Name'Length;
Name_Buffer (1 .. Name_Len) := Name;
- The_Value := Htable.Get (Name_Find);
+ The_Value :=
+ Name_To_Name_HTable.Get (Tree.External_References, Name_Find);
if The_Value /= No_Name then
return The_Value;
@@ -341,7 +345,8 @@ package body Prj.Ext is
Name_Len := Env_Value'Length;
Name_Buffer (1 .. Name_Len) := Env_Value.all;
The_Value := Name_Find;
- Htable.Set (External_Name, The_Value);
+ Name_To_Name_HTable.Set
+ (Tree.External_References, External_Name, The_Value);
Free (Env_Value);
return The_Value;
diff --git a/gcc/ada/prj-ext.ads b/gcc/ada/prj-ext.ads
index 931c3c5d07f..c171f5940f1 100644
--- a/gcc/ada/prj-ext.ads
+++ b/gcc/ada/prj-ext.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2000-2007, Free Software Foundation, Inc. --
+-- Copyright (C) 2000-2009, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -26,44 +26,70 @@
-- Subprograms to set, get and cache external references, to be used as
-- External functions in project files.
+with Prj.Tree;
+
package Prj.Ext is
- Gpr_Project_Path : constant String := "GPR_PROJECT_PATH";
- -- Name of primary env. variable that contain path name(s) of directories
- -- where project files may reside.
+ ------------------
+ -- Project Path --
+ ------------------
- procedure Add_Search_Project_Directory (Path : String);
+ procedure Add_Search_Project_Directory
+ (Tree : Prj.Tree.Project_Node_Tree_Ref;
+ Path : String);
-- Add a directory to the project path. Directories added with this
-- procedure are added in order after the current directory and before
-- the path given by the environment variable GPR_PROJECT_PATH. A value
-- of "-" will remove the default project directory from the project path.
+ --
+ -- Calls to this subprogram must be performed before the first call to
+ -- Project_Path below, or PATH will be added at the end of the search
+ -- path.
- function Project_Path return String;
+ function Project_Path (Tree : Prj.Tree.Project_Node_Tree_Ref) return String;
-- Return the current value of the project path, either the value set
-- during elaboration of the package or, if procedure Set_Project_Path has
-- been called, the value set by the last call to Set_Project_Path.
- procedure Set_Project_Path (New_Path : String);
+ procedure Set_Project_Path
+ (Tree : Prj.Tree.Project_Node_Tree_Ref;
+ New_Path : String);
-- Give a new value to the project path. The new value New_Path should
-- always start with the current directory (".") and the path separators
-- should be the correct ones for the platform.
+ -------------------------
+ -- External References --
+ -------------------------
+
+ -- External references influence the way a project tree is processed (in
+ -- particular they provide the values for the typed string variables that
+ -- are then used in case constructions).
+
+ -- External references are project-tree specific, so that when multiple
+ -- trees are loaded in parallel we can have different scenarios (or even
+ -- load the same tree twice and see different views of it).
+
procedure Add
- (External_Name : String;
+ (Tree : Prj.Tree.Project_Node_Tree_Ref;
+ External_Name : String;
Value : String);
-- Add an external reference (or modify an existing one)
function Value_Of
- (External_Name : Name_Id;
+ (Tree : Prj.Tree.Project_Node_Tree_Ref;
+ External_Name : Name_Id;
With_Default : Name_Id := No_Name)
return Name_Id;
-- Get the value of an external reference, and cache it for future uses
- function Check (Declaration : String) return Boolean;
+ function Check
+ (Tree : Prj.Tree.Project_Node_Tree_Ref;
+ Declaration : String) return Boolean;
-- Check that an external declaration <external>=<value> is correct.
-- If it is correct, the external reference is Added.
- procedure Reset;
+ procedure Reset (Tree : Prj.Tree.Project_Node_Tree_Ref);
-- Clear the internal data structure that stores the external references
-- and free any allocated memory.
diff --git a/gcc/ada/prj-nmsc.adb b/gcc/ada/prj-nmsc.adb
index 1a0371855c5..cec5e6b0a59 100644
--- a/gcc/ada/prj-nmsc.adb
+++ b/gcc/ada/prj-nmsc.adb
@@ -192,6 +192,7 @@ package body Prj.Nmsc is
(Id : out Source_Id;
Data : in out Tree_Processing_Data;
Project : Project_Id;
+ Source_Dir_Rank : Natural;
Lang_Id : Language_Ptr;
Kind : Source_Kind;
File_Name : File_Name_Type;
@@ -295,6 +296,7 @@ package body Prj.Nmsc is
procedure Check_File
(Project : in out Project_Processing_Data;
Data : in out Tree_Processing_Data;
+ Source_Dir_Rank : Natural;
Path : Path_Name_Type;
File_Name : File_Name_Type;
Display_File_Name : File_Name_Type;
@@ -539,6 +541,7 @@ package body Prj.Nmsc is
(Id : out Source_Id;
Data : in out Tree_Processing_Data;
Project : Project_Id;
+ Source_Dir_Rank : Natural;
Lang_Id : Language_Ptr;
Kind : Source_Kind;
File_Name : File_Name_Type;
@@ -598,7 +601,7 @@ package body Prj.Nmsc is
if Data.Flags.Allow_Duplicate_Basenames then
Add_Src := True;
- elsif Project.Known_Order_Of_Source_Dirs then
+ elsif Source_Dir_Rank /= Source.Source_Dir_Rank then
Add_Src := False;
else
@@ -610,7 +613,7 @@ package body Prj.Nmsc is
end if;
else
- if Project.Known_Order_Of_Source_Dirs then
+ if Source_Dir_Rank /= Source.Source_Dir_Rank then
Add_Src := False;
-- We might be seeing the same file through a different path
@@ -722,6 +725,7 @@ package body Prj.Nmsc is
end if;
Id.Project := Project;
+ Id.Source_Dir_Rank := Source_Dir_Rank;
Id.Language := Lang_Id;
Id.Kind := Kind;
Id.Alternate_Languages := Alternate_Languages;
@@ -2807,6 +2811,7 @@ package body Prj.Nmsc is
(Id => Source,
Data => Data,
Project => Project,
+ Source_Dir_Rank => 0,
Lang_Id => Lang_Id,
Kind => Kind,
File_Name => File_Name,
@@ -2916,16 +2921,17 @@ package body Prj.Nmsc is
if Unit /= No_Name then
Add_Source
- (Id => Source,
- Data => Data,
- Project => Project,
- Lang_Id => Lang_Id,
- Kind => Kind,
- File_Name => File_Name,
- Display_File => File_Name_Type (Element.Value.Value),
- Unit => Unit,
- Index => Index,
- Location => Element.Value.Location,
+ (Id => Source,
+ Data => Data,
+ Project => Project,
+ Source_Dir_Rank => 0,
+ Lang_Id => Lang_Id,
+ Kind => Kind,
+ File_Name => File_Name,
+ Display_File => File_Name_Type (Element.Value.Value),
+ Unit => Unit,
+ Index => Index,
+ Location => Element.Value.Location,
Naming_Exception => True);
end if;
@@ -4675,7 +4681,8 @@ package body Prj.Nmsc is
(Name_Source_Files,
Project.Decl.Attributes, Data.Tree);
- Last_Source_Dir : String_List_Id := Nil_String;
+ Last_Source_Dir : String_List_Id := Nil_String;
+ Last_Src_Dir_Rank : Number_List_Index := No_Number_List;
Languages : constant Variable_Value :=
Prj.Util.Value_Of
@@ -4684,6 +4691,7 @@ package body Prj.Nmsc is
procedure Find_Source_Dirs
(From : File_Name_Type;
Location : Source_Ptr;
+ Rank : Natural;
Removed : Boolean := False);
-- Find one or several source directories, and add (or remove, if
-- Removed is True) them to list of source directories of the project.
@@ -4695,6 +4703,7 @@ package body Prj.Nmsc is
procedure Find_Source_Dirs
(From : File_Name_Type;
Location : Source_Ptr;
+ Rank : Natural;
Removed : Boolean := False)
is
Directory : constant String := Get_Name_String (From);
@@ -4714,6 +4723,8 @@ package body Prj.Nmsc is
Last : Natural;
List : String_List_Id;
Prev : String_List_Id;
+ Rank_List : Number_List_Index;
+ Prev_Rank : Number_List_Index;
Element : String_Element;
Found : Boolean := False;
@@ -4756,6 +4767,8 @@ package body Prj.Nmsc is
List := Project.Source_Dirs;
Prev := Nil_String;
+ Rank_List := Project.Source_Dir_Ranks;
+ Prev_Rank := No_Number_List;
while List /= Nil_String loop
Element := Data.Tree.String_Elements.Table (List);
@@ -4766,6 +4779,8 @@ package body Prj.Nmsc is
Prev := List;
List := Element.Next;
+ Prev_Rank := Rank_List;
+ Rank_List := Data.Tree.Number_Lists.Table (Rank_List).Next;
end loop;
-- If directory is not already in list, put it there
@@ -4785,11 +4800,15 @@ package body Prj.Nmsc is
Next => Nil_String,
Index => 0);
+ Number_List_Table.Increment_Last (Data.Tree.Number_Lists);
+
-- Case of first source directory
if Last_Source_Dir = Nil_String then
Project.Source_Dirs :=
String_Element_Table.Last (Data.Tree.String_Elements);
+ Project.Source_Dir_Ranks :=
+ Number_List_Table.Last (Data.Tree.Number_Lists);
-- Here we already have source directories
@@ -4798,7 +4817,11 @@ package body Prj.Nmsc is
Data.Tree.String_Elements.Table
(Last_Source_Dir).Next :=
- String_Element_Table.Last (Data.Tree.String_Elements);
+ String_Element_Table.Last (Data.Tree.String_Elements);
+ Data.Tree.Number_Lists.Table
+ (Last_Src_Dir_Rank).Next :=
+ Number_List_Table.Last (Data.Tree.Number_Lists);
+
end if;
-- And register this source directory as the new last
@@ -4806,14 +4829,22 @@ package body Prj.Nmsc is
Last_Source_Dir :=
String_Element_Table.Last (Data.Tree.String_Elements);
Data.Tree.String_Elements.Table (Last_Source_Dir) := Element;
+ Last_Src_Dir_Rank :=
+ Number_List_Table.Last (Data.Tree.Number_Lists);
+ Data.Tree.Number_Lists.Table (Last_Src_Dir_Rank) :=
+ (Number => Rank, Next => No_Number_List);
elsif Removed and Found then
if Prev = Nil_String then
Project.Source_Dirs :=
Data.Tree.String_Elements.Table (List).Next;
+ Project.Source_Dir_Ranks :=
+ Data.Tree.Number_Lists.Table (Rank_List).Next;
else
Data.Tree.String_Elements.Table (Prev).Next :=
Data.Tree.String_Elements.Table (List).Next;
+ Data.Tree.Number_Lists.Table (Prev_Rank).Next :=
+ Data.Tree.Number_Lists.Table (Rank_List).Next;
end if;
end if;
@@ -4872,6 +4903,8 @@ package body Prj.Nmsc is
if Current_Verbosity = High and then not Removed then
Write_Str ("Find_Source_Dirs (""");
Write_Str (Directory);
+ Write_Str (",");
+ Write_Str (Rank'Img);
Write_Line (""")");
end if;
@@ -4884,10 +4917,6 @@ package body Prj.Nmsc is
or else
Directory (Directory'Last - 2) = Directory_Separator)
then
- if not Removed then
- Project.Known_Order_Of_Source_Dirs := False;
- end if;
-
Name_Len := Directory'Length - 3;
if Name_Len = 0 then
@@ -4960,6 +4989,8 @@ package body Prj.Nmsc is
Path_Name : Path_Information;
List : String_List_Id;
Prev : String_List_Id;
+ Rank_List : Number_List_Index;
+ Prev_Rank : Number_List_Index;
Dir_Exists : Boolean;
begin
@@ -5011,70 +5042,104 @@ package body Prj.Nmsc is
(Display_Path'First .. Last_Display_Path));
Display_Path_Id := Name_Find;
+ -- Check if the directory is already in the list
+
+ Prev := Nil_String;
+ Prev_Rank := No_Number_List;
+
+ -- Look for source dir in current list
+
+ List := Project.Source_Dirs;
+ Rank_List := Project.Source_Dir_Ranks;
+ while List /= Nil_String loop
+ Element := Data.Tree.String_Elements.Table (List);
+ exit when Element.Value = Path_Id;
+ Prev := List;
+ List := Element.Next;
+ Prev_Rank := Rank_List;
+ Rank_List :=
+ Data.Tree.Number_Lists.Table (Prev_Rank).Next;
+ end loop;
+
+ -- The directory is in the list if List is not Nil_String
+
if not Removed then
-- As it is an existing directory, we add it to the
- -- list of directories.
+ -- list of directories, if not already in the list.
- String_Element_Table.Increment_Last
- (Data.Tree.String_Elements);
- Element :=
- (Value => Path_Id,
- Index => 0,
- Display_Value => Display_Path_Id,
- Location => No_Location,
- Flag => False,
- Next => Nil_String);
+ if List = Nil_String then
+ String_Element_Table.Increment_Last
+ (Data.Tree.String_Elements);
+ Element :=
+ (Value => Path_Id,
+ Index => 0,
+ Display_Value => Display_Path_Id,
+ Location => No_Location,
+ Flag => False,
+ Next => Nil_String);
+ Number_List_Table.Increment_Last
+ (Data.Tree.Number_Lists);
- if Last_Source_Dir = Nil_String then
+ if Last_Source_Dir = Nil_String then
- -- This is the first source directory
+ -- This is the first source directory
- Project.Source_Dirs := String_Element_Table.Last
- (Data.Tree.String_Elements);
+ Project.Source_Dirs :=
+ String_Element_Table.Last
+ (Data.Tree.String_Elements);
+ Project.Source_Dir_Ranks :=
+ Number_List_Table.Last
+ (Data.Tree.Number_Lists);
- else
- -- We already have source directories, link the
- -- previous last to the new one.
+ else
+ -- We already have source directories, link the
+ -- previous last to the new one.
+
+ Data.Tree.String_Elements.Table
+ (Last_Source_Dir).Next :=
+ String_Element_Table.Last
+ (Data.Tree.String_Elements);
+ Data.Tree.Number_Lists.Table
+ (Last_Src_Dir_Rank).Next :=
+ Number_List_Table.Last
+ (Data.Tree.Number_Lists);
- Data.Tree.String_Elements.Table
- (Last_Source_Dir).Next :=
+ end if;
+
+ -- And register this source directory as the new
+ -- last.
+
+ Last_Source_Dir :=
String_Element_Table.Last
(Data.Tree.String_Elements);
+ Data.Tree.String_Elements.Table
+ (Last_Source_Dir) := Element;
+ Last_Src_Dir_Rank :=
+ Number_List_Table.Last
+ (Data.Tree.Number_Lists);
+ Data.Tree.Number_Lists.Table
+ (Last_Src_Dir_Rank) :=
+ (Number => Rank, Next => No_Number_List);
end if;
- -- And register this source directory as the new last
-
- Last_Source_Dir := String_Element_Table.Last
- (Data.Tree.String_Elements);
- Data.Tree.String_Elements.Table
- (Last_Source_Dir) := Element;
-
else
-- Remove source dir, if present
- Prev := Nil_String;
-
- -- Look for source dir in current list
-
- List := Project.Source_Dirs;
- while List /= Nil_String loop
- Element := Data.Tree.String_Elements.Table (List);
- exit when Element.Value = Path_Id;
- Prev := List;
- List := Element.Next;
- end loop;
-
if List /= Nil_String then
-- Source dir was found, remove it from the list
if Prev = Nil_String then
Project.Source_Dirs :=
Data.Tree.String_Elements.Table (List).Next;
+ Project.Source_Dir_Ranks :=
+ Data.Tree.Number_Lists.Table (Rank_List).Next;
else
Data.Tree.String_Elements.Table (Prev).Next :=
Data.Tree.String_Elements.Table (List).Next;
+ Data.Tree.Number_Lists.Table (Prev_Rank).Next :=
+ Data.Tree.Number_Lists.Table (Rank_List).Next;
end if;
end if;
end if;
@@ -5276,6 +5341,13 @@ package body Prj.Nmsc is
Project.Source_Dirs :=
String_Element_Table.Last (Data.Tree.String_Elements);
+ Number_List_Table.Append
+ (Data.Tree.Number_Lists,
+ (Number => 1, Next => No_Number_List));
+
+ Project.Source_Dir_Ranks :=
+ Number_List_Table.Last (Data.Tree.Number_Lists);
+
if Current_Verbosity = High then
Write_Attr
("Default source directory",
@@ -5296,15 +5368,17 @@ package body Prj.Nmsc is
declare
Source_Dir : String_List_Id;
Element : String_Element;
-
+ Rank : Natural;
begin
-- Process the source directories for each element of the list
Source_Dir := Source_Dirs.Values;
+ Rank := 0;
while Source_Dir /= Nil_String loop
Element := Data.Tree.String_Elements.Table (Source_Dir);
+ Rank := Rank + 1;
Find_Source_Dirs
- (File_Name_Type (Element.Value), Element.Location);
+ (File_Name_Type (Element.Value), Element.Location, Rank);
Source_Dir := Element.Next;
end loop;
end;
@@ -5326,6 +5400,7 @@ package body Prj.Nmsc is
Find_Source_Dirs
(File_Name_Type (Element.Value),
Element.Location,
+ 0,
Removed => True);
Source_Dir := Element.Next;
end loop;
@@ -6582,6 +6657,7 @@ package body Prj.Nmsc is
procedure Check_File
(Project : in out Project_Processing_Data;
Data : in out Tree_Processing_Data;
+ Source_Dir_Rank : Natural;
Path : Path_Name_Type;
File_Name : File_Name_Type;
Display_File_Name : File_Name_Type;
@@ -6606,6 +6682,14 @@ package body Prj.Nmsc is
Kind : Source_Kind := Spec;
begin
+ if Current_Verbosity = High then
+ Write_Line ("Checking file:");
+ Write_Str (" Path = ");
+ Write_Line (Get_Name_String (Path));
+ Write_Str (" Rank =");
+ Write_Line (Source_Dir_Rank'Img);
+ end if;
+
if Name_Loc = No_Name_Location then
Check_Name := For_All_Sources;
@@ -6615,7 +6699,7 @@ package body Prj.Nmsc is
-- Check if it is OK to have the same file name in several
-- source directories.
- if not Project.Project.Known_Order_Of_Source_Dirs then
+ if Source_Dir_Rank = Name_Loc.Source.Source_Dir_Rank then
Error_Msg_File_1 := File_Name;
Error_Msg
(Data.Flags,
@@ -6689,6 +6773,7 @@ package body Prj.Nmsc is
Add_Source
(Id => Source,
Project => Project.Project,
+ Source_Dir_Rank => Source_Dir_Rank,
Lang_Id => Language,
Kind => Kind,
Data => Data,
@@ -6698,6 +6783,15 @@ package body Prj.Nmsc is
Unit => Unit,
Locally_Removed => Locally_Removed,
Path => (Canonical_Path, Path));
+
+ -- If it is a source specified in a list, update the entry in
+ -- the Source_Names table.
+
+ if Name_Loc.Found and then Name_Loc.Source = No_Source then
+ Name_Loc.Source := Source;
+ Source_Names_Htable.Set
+ (Project.Source_Names, File_Name, Name_Loc);
+ end if;
end if;
end if;
end Check_File;
@@ -6713,6 +6807,8 @@ package body Prj.Nmsc is
is
Source_Dir : String_List_Id;
Element : String_Element;
+ Src_Dir_Rank : Number_List_Index;
+ Num_Nod : Number_Node;
Dir : Dir_Type;
Name : String (1 .. 1_000);
Last : Natural;
@@ -6727,12 +6823,21 @@ package body Prj.Nmsc is
-- Loop through subdirectories
Source_Dir := Project.Project.Source_Dirs;
+ Src_Dir_Rank := Project.Project.Source_Dir_Ranks;
while Source_Dir /= Nil_String loop
begin
+ Num_Nod := Data.Tree.Number_Lists.Table (Src_Dir_Rank);
Element := Data.Tree.String_Elements.Table (Source_Dir);
+
if Element.Value /= No_Name then
Get_Name_String (Element.Display_Value);
+ if Current_Verbosity = High then
+ Write_Str ("Directory: ");
+ Write_Str (Name_Buffer (1 .. Name_Len));
+ Write_Line (Num_Nod.Number'Img);
+ end if;
+
declare
Source_Directory : constant String :=
Name_Buffer (1 .. Name_Len) &
@@ -6819,7 +6924,7 @@ package body Prj.Nmsc is
-- still need to add it to the list: if we
-- don't, the file will not appear in the
-- mapping file and will cause the compiler
- -- to fail
+ -- to fail.
To_Remove := True;
end if;
@@ -6827,6 +6932,7 @@ package body Prj.Nmsc is
Check_File
(Project => Project,
+ Source_Dir_Rank => Num_Nod.Number,
Data => Data,
Path => Path,
File_Name => File_Name,
@@ -6847,6 +6953,7 @@ package body Prj.Nmsc is
end;
Source_Dir := Element.Next;
+ Src_Dir_Rank := Num_Nod.Next;
end loop;
if Current_Verbosity = High then
@@ -7176,7 +7283,13 @@ package body Prj.Nmsc is
begin
if Current_Verbosity = High then
Write_Str ("Removing source ");
- Write_Line (Get_Name_String (Id.File) & " at" & Id.Index'Img);
+ Write_Str (Get_Name_String (Id.File));
+
+ if Id.Index /= 0 then
+ Write_Str (" at" & Id.Index'Img);
+ end if;
+
+ Write_Eol;
end if;
if Replaced_By /= No_Source then
diff --git a/gcc/ada/prj-nmsc.ads b/gcc/ada/prj-nmsc.ads
index eec6289e503..c69084f99ff 100644
--- a/gcc/ada/prj-nmsc.ads
+++ b/gcc/ada/prj-nmsc.ads
@@ -33,11 +33,10 @@ private package Prj.Nmsc is
Flags : Processing_Flags);
-- Perform consistency and semantic checks on all the projects in the tree.
-- This procedure interprets the various case statements in the project
- -- based on the current environment variables (the "scenario"). After
- -- checking the validity of the naming scheme, it searches for all the
- -- source files of the project. The result of this procedure is a filled-in
- -- data structure for Project_Id which contains all the information about
- -- the project. This information is only valid while the scenario variables
- -- are preserved.
+ -- based on the current external references. After checking the validity of
+ -- the naming scheme, it searches for all the source files of the project.
+ -- The result of this procedure is a filled-in data structure for
+ -- Project_Id which contains all the information about the project. This
+ -- information is only valid while the external references are preserved.
end Prj.Nmsc;
diff --git a/gcc/ada/prj-pars.adb b/gcc/ada/prj-pars.adb
index bacbf8d7f87..7ab7ea047c6 100644
--- a/gcc/ada/prj-pars.adb
+++ b/gcc/ada/prj-pars.adb
@@ -45,18 +45,22 @@ package body Prj.Pars is
Project_File_Name : String;
Packages_To_Check : String_List_Access := All_Packages;
Flags : Processing_Flags;
- Reset_Tree : Boolean := True)
+ Reset_Tree : Boolean := True;
+ In_Node_Tree : Prj.Tree.Project_Node_Tree_Ref := null)
is
- Project_Node : Project_Node_Id := Empty_Node;
- The_Project : Project_Id := No_Project;
- Success : Boolean := True;
- Current_Dir : constant String := Get_Current_Dir;
- Project_Node_Tree : Prj.Tree.Project_Node_Tree_Ref;
+ Project_Node : Project_Node_Id := Empty_Node;
+ The_Project : Project_Id := No_Project;
+ Success : Boolean := True;
+ Current_Dir : constant String := Get_Current_Dir;
+ Project_Node_Tree : Prj.Tree.Project_Node_Tree_Ref := In_Node_Tree;
Automatically_Generated : Boolean;
Config_File_Path : String_Access;
+
begin
- Project_Node_Tree := new Project_Node_Tree_Data;
- Prj.Tree.Initialize (Project_Node_Tree);
+ if Project_Node_Tree = null then
+ Project_Node_Tree := new Project_Node_Tree_Data;
+ Prj.Tree.Initialize (Project_Node_Tree);
+ end if;
-- Parse the main project file into a tree
diff --git a/gcc/ada/prj-pars.ads b/gcc/ada/prj-pars.ads
index 01caff93c19..4e7d4808d4a 100644
--- a/gcc/ada/prj-pars.ads
+++ b/gcc/ada/prj-pars.ads
@@ -25,6 +25,8 @@
-- General wrapper for the parsing of project files
+with Prj.Tree;
+
package Prj.Pars is
procedure Set_Verbosity (To : Verbosity);
@@ -36,20 +38,21 @@ package Prj.Pars is
Project_File_Name : String;
Packages_To_Check : String_List_Access := All_Packages;
Flags : Processing_Flags;
- Reset_Tree : Boolean := True);
+ Reset_Tree : Boolean := True;
+ In_Node_Tree : Prj.Tree.Project_Node_Tree_Ref := null);
-- Parse and process a project files and all its imported project files, in
-- the project tree In_Tree.
-- All the project files are parsed (through Prj.Tree) to create a tree in
-- memory. That tree is then processed (through Prj.Proc) to create a
- -- expanded representation of the tree based on the current scenario
- -- variables. This function is only a convenient wrapper over other
+ -- expanded representation of the tree based on the current external
+ -- references. This function is only a convenient wrapper over other
-- services provided in the Prj.* package hierarchy.
--
-- If parsing is successful, Project is the project ID of the root project
-- file; otherwise, Project_Id is set to No_Project. Project_Node_Tree is
-- set to the tree (unprocessed) representation of the project file. This
-- tree is permanently correct, whereas Project will need to be recomputed
- -- if the scenario variables change.
+ -- if the external references change.
--
-- Packages_To_Check indicates the packages where any unknown attribute
-- produces an error. For other packages, an unknown attribute produces a
@@ -57,5 +60,9 @@ package Prj.Pars is
--
-- When Reset_Tree is True, all the project data are removed from the
-- project table before processing.
+ --
+ -- In_Node_Tree (if given) must have been Initialized. The main reason to
+ -- pass an existing tree, is to pass the external references that will then
+ -- be used to process the tree.
end Prj.Pars;
diff --git a/gcc/ada/prj-part.adb b/gcc/ada/prj-part.adb
index 84e3f6dab7f..1ed78ab227b 100644
--- a/gcc/ada/prj-part.adb
+++ b/gcc/ada/prj-part.adb
@@ -212,7 +212,8 @@ package body Prj.Part is
-- file (.cgpr) since some specific checks apply.
function Project_Path_Name_Of
- (Project_File_Name : String;
+ (In_Tree : Project_Node_Tree_Ref;
+ Project_File_Name : String;
Directory : String) return String;
-- Returns the path name of a project file. Returns an empty string
-- if project file cannot be found.
@@ -455,13 +456,14 @@ package body Prj.Part is
if Current_Verbosity >= Medium then
Write_Str ("GPR_PROJECT_PATH=""");
- Write_Str (Project_Path);
+ Write_Str (Project_Path (In_Tree));
Write_Line ("""");
end if;
declare
Path_Name : constant String :=
- Project_Path_Name_Of (Real_Project_File_Name.all,
+ Project_Path_Name_Of (In_Tree,
+ Real_Project_File_Name.all,
Directory => Current_Directory);
begin
@@ -478,7 +480,7 @@ package body Prj.Part is
("project file """
& Project_File_Name
& """ not found in "
- & Project_Path);
+ & Project_Path (In_Tree));
Project := Empty_Node;
return;
end if;
@@ -755,7 +757,8 @@ package body Prj.Part is
Imported_Path_Name : constant String :=
Project_Path_Name_Of
- (Original_Path,
+ (In_Tree,
+ Original_Path,
Project_Directory_Path);
Resolved_Path : constant String :=
@@ -941,6 +944,7 @@ package body Prj.Part is
Name_From_Path : constant Name_Id :=
Project_Name_From (Path_Name, Is_Config_File => Is_Config_File);
Name_Of_Project : Name_Id := No_Name;
+ Display_Name_Of_Project : Name_Id := No_Name;
Duplicated : Boolean := False;
@@ -1298,9 +1302,6 @@ package body Prj.Part is
-- To get expected name of the project file, replace dots by dashes
- Name_Len := Buffer_Last;
- Name_Buffer (1 .. Name_Len) := Buffer (1 .. Buffer_Last);
-
for Index in 1 .. Name_Len loop
if Name_Buffer (Index) = '.' then
Name_Buffer (Index) := '-';
@@ -1337,6 +1338,21 @@ package body Prj.Part is
end if;
end;
+ -- Read the original casing of the project name
+
+ declare
+ Loc : Source_Ptr;
+
+ begin
+ Loc := Location_Of (Project, In_Tree);
+ for J in 1 .. Name_Len loop
+ Name_Buffer (J) := Sinput.Source (Loc);
+ Loc := Loc + 1;
+ end loop;
+
+ Display_Name_Of_Project := Name_Find;
+ end;
+
declare
From_Ext : Extension_Origin := None;
@@ -1421,7 +1437,8 @@ package body Prj.Part is
Extended_Project_Path_Name : constant String :=
Project_Path_Name_Of
- (Original_Path_Name,
+ (In_Tree,
+ Original_Path_Name,
Get_Name_String
(Project_Directory));
@@ -1700,6 +1717,7 @@ package body Prj.Part is
(T => In_Tree.Projects_HT,
K => Name_Of_Project,
E => (Name => Name_Of_Project,
+ Display_Name => Display_Name_Of_Project,
Node => Project,
Canonical_Path => Canonical_Path_Name,
Extended => Extended,
@@ -1897,7 +1915,8 @@ package body Prj.Part is
--------------------------
function Project_Path_Name_Of
- (Project_File_Name : String;
+ (In_Tree : Project_Node_Tree_Ref;
+ Project_File_Name : String;
Directory : String) return String
is
@@ -1910,7 +1929,7 @@ package body Prj.Part is
-------------------
function Try_Path_Name (Path : String) return String_Access is
- Prj_Path : constant String := Project_Path;
+ Prj_Path : constant String := Project_Path (In_Tree);
First : Natural;
Last : Natural;
Result : String_Access := null;
diff --git a/gcc/ada/prj-proc.adb b/gcc/ada/prj-proc.adb
index c8766229057..0cd20c8f19d 100644
--- a/gcc/ada/prj-proc.adb
+++ b/gcc/ada/prj-proc.adb
@@ -31,7 +31,6 @@ with Prj.Attr; use Prj.Attr;
with Prj.Err; use Prj.Err;
with Prj.Ext; use Prj.Ext;
with Prj.Nmsc; use Prj.Nmsc;
-with Sinput; use Sinput;
with Snames;
with GNAT.Case_Util; use GNAT.Case_Util;
@@ -1042,7 +1041,8 @@ package body Prj.Proc is
end if;
end if;
- Value := Prj.Ext.Value_Of (Name, Default);
+ Value :=
+ Prj.Ext.Value_Of (From_Project_Node_Tree, Name, Default);
if Value = No_Name then
if not Quiet_Output then
@@ -2256,9 +2256,8 @@ package body Prj.Proc is
Check (In_Tree, Project, Flags);
end if;
- -- If main project is an extending all project, set the object
- -- directory of all virtual extending projects to the object
- -- directory of the main project.
+ -- If main project is an extending all project, set object directory of
+ -- all virtual extending projects to object directory of main project.
if Project /= No_Project
and then
@@ -2425,13 +2424,13 @@ package body Prj.Proc is
declare
Imported : Project_List;
Declaration_Node : Project_Node_Id := Empty_Node;
- Tref : Source_Buffer_Ptr;
- Name : constant Name_Id :=
- Name_Of
- (From_Project_Node, From_Project_Node_Tree);
- Location : Source_Ptr :=
- Location_Of
- (From_Project_Node, From_Project_Node_Tree);
+
+ Name : constant Name_Id :=
+ Name_Of (From_Project_Node, From_Project_Node_Tree);
+
+ Name_Node : constant Tree_Private_Part.Project_Name_And_Node :=
+ Tree_Private_Part.Projects_Htable.Get
+ (From_Project_Node_Tree.Projects_HT, Name);
begin
Project := Processed_Projects.Get (Name);
@@ -2458,6 +2457,7 @@ package body Prj.Proc is
Processed_Projects.Set (Name, Project);
Project.Name := Name;
+ Project.Display_Name := Name_Node.Display_Name;
Project.Qualifier :=
Project_Qualifier_Of (From_Project_Node, From_Project_Node_Tree);
@@ -2471,26 +2471,7 @@ package body Prj.Proc is
Virtual_Prefix
then
Project.Virtual := True;
- Project.Display_Name := Name;
-
- -- If there is no file, for example when the project node tree is
- -- built in memory by GPS, the Display_Name cannot be found in
- -- the source, so its value is the same as Name.
-
- elsif Location = No_Location then
- Project.Display_Name := Name;
-
- -- Get the spelling of the project name from the project file
-
- else
- Tref := Source_Text (Get_Source_File_Index (Location));
-
- for J in 1 .. Name_Len loop
- Name_Buffer (J) := Tref (Location);
- Location := Location + 1;
- end loop;
- Project.Display_Name := Name_Find;
end if;
Project.Path.Display_Name :=
diff --git a/gcc/ada/prj-proc.ads b/gcc/ada/prj-proc.ads
index 40b5bf35d19..4257c9004f8 100644
--- a/gcc/ada/prj-proc.ads
+++ b/gcc/ada/prj-proc.ads
@@ -40,7 +40,7 @@ package Prj.Proc is
Flags : Prj.Processing_Flags;
Reset_Tree : Boolean := True);
-- Process a project tree (ie the direct resulting of parsing a .gpr file)
- -- based on the current scenario variables.
+ -- based on the current external references.
--
-- The result of this phase_1 is a partial project tree (Project) where
-- only a few fields have been initialized (in particular the list of
diff --git a/gcc/ada/prj-tree.adb b/gcc/ada/prj-tree.adb
index 2d94f5c4bbb..4823a988d6c 100644
--- a/gcc/ada/prj-tree.adb
+++ b/gcc/ada/prj-tree.adb
@@ -983,6 +983,10 @@ package body Prj.Tree is
begin
Project_Node_Table.Init (Tree.Project_Nodes);
Projects_Htable.Reset (Tree.Projects_HT);
+
+ -- Do not reset the external references, in case we are reloading a
+ -- project, since we want to preserve the current environment
+ -- Name_To_Name_HTable.Reset (Tree.External_References);
end Initialize;
----------
@@ -2854,6 +2858,7 @@ package body Prj.Tree is
Name,
Prj.Tree.Tree_Private_Part.Project_Name_And_Node'
(Name => Name,
+ Display_Name => Name,
Canonical_Path => No_Path,
Node => Project,
Extended => False,
diff --git a/gcc/ada/prj-tree.ads b/gcc/ada/prj-tree.ads
index e68c36eaad4..53f2eefc8b8 100644
--- a/gcc/ada/prj-tree.ads
+++ b/gcc/ada/prj-tree.ads
@@ -1000,9 +1000,8 @@ package Prj.Tree is
package Tree_Private_Part is
- -- This is conceptually in the private part
-
- -- However, for efficiency, some packages are accessing it directly
+ -- This is conceptually in the private part. However, for efficiency,
+ -- some packages are accessing it directly.
type Project_Node_Record is record
@@ -1332,6 +1331,9 @@ package Prj.Tree is
Name : Name_Id;
-- Name of the project
+ Display_Name : Name_Id;
+ -- The name of the project as it appears in the .gpr file
+
Node : Project_Node_Id;
-- Node of the project in table Project_Nodes
@@ -1348,6 +1350,7 @@ package Prj.Tree is
No_Project_Name_And_Node : constant Project_Name_And_Node :=
(Name => No_Name,
+ Display_Name => No_Name,
Node => Empty_Node,
Canonical_Path => No_Path,
Extended => True,
@@ -1367,11 +1370,36 @@ package Prj.Tree is
end Tree_Private_Part;
+ package Name_To_Name_HTable is new GNAT.Dynamic_HTables.Simple_HTable
+ (Header_Num => Header_Num,
+ Element => Name_Id,
+ No_Element => No_Name,
+ Key => Name_Id,
+ Hash => Hash,
+ Equal => "=");
+ -- Comment required describing what this table is used for ???
+
type Project_Node_Tree_Data is record
Project_Nodes : Tree_Private_Part.Project_Node_Table.Instance;
Projects_HT : Tree_Private_Part.Projects_Htable.Instance;
+
+ External_References : Name_To_Name_HTable.Instance;
+ -- External references are stored in this hash table (and manipulated
+ -- through subprogrames in prj-ext.ads). External references are
+ -- project-tree specific so that one can load the same tree twice but
+ -- have two views of it, for instance.
+
+ Project_Path : String_Access;
+ -- The project path, manipulated through subprograms in prj-ext.ads.
+ -- As a special case, if the first character is '#:" or this variable is
+ -- unset, this means that the PATH has not been fully initialized yet
+ -- (although subprograms prj-ext.ads will properly take care of that).
+ --
+ -- The project path is tree specific, since we might want to load
+ -- simultaneously multiple projects, each with its own search path, in
+ -- particular when using different compilers with different default
+ -- search directories.
end record;
- -- The data for a project node tree
procedure Free (Proj : in out Project_Node_Tree_Ref);
-- Free memory used by Prj
diff --git a/gcc/ada/prj.adb b/gcc/ada/prj.adb
index 2bed1a81dc2..b485f706829 100644
--- a/gcc/ada/prj.adb
+++ b/gcc/ada/prj.adb
@@ -89,7 +89,7 @@ package body Prj is
Include_Path => null,
Include_Data_Set => False,
Source_Dirs => Nil_String,
- Known_Order_Of_Source_Dirs => True,
+ Source_Dir_Ranks => No_Number_List,
Object_Directory => No_Path_Information,
Library_TS => Empty_Time_Stamp,
Exec_Directory => No_Path_Information,
@@ -841,6 +841,7 @@ package body Prj is
begin
if Tree /= null then
Name_List_Table.Free (Tree.Name_Lists);
+ Number_List_Table.Free (Tree.Number_Lists);
String_Element_Table.Free (Tree.String_Elements);
Variable_Element_Table.Free (Tree.Variable_Elements);
Array_Element_Table.Free (Tree.Array_Elements);
@@ -868,6 +869,7 @@ package body Prj is
-- Visible tables
Name_List_Table.Init (Tree.Name_Lists);
+ Number_List_Table.Init (Tree.Number_Lists);
String_Element_Table.Init (Tree.String_Elements);
Variable_Element_Table.Init (Tree.Variable_Elements);
Array_Element_Table.Init (Tree.Array_Elements);
diff --git a/gcc/ada/prj.ads b/gcc/ada/prj.ads
index 76eb59aecbb..502ace95f8d 100644
--- a/gcc/ada/prj.ads
+++ b/gcc/ada/prj.ads
@@ -314,7 +314,23 @@ package Prj is
Table_Low_Bound => 1,
Table_Initial => 10,
Table_Increment => 100);
- -- The table for lists of names used in package Language_Processing
+ -- The table for lists of names
+
+ type Number_List_Index is new Nat;
+ No_Number_List : constant Number_List_Index := 0;
+
+ type Number_Node is record
+ Number : Natural := 0;
+ Next : Number_List_Index := No_Number_List;
+ end record;
+
+ package Number_List_Table is new GNAT.Dynamic_Tables
+ (Table_Component_Type => Number_Node,
+ Table_Index_Type => Number_List_Index,
+ Table_Low_Bound => 1,
+ Table_Initial => 10,
+ Table_Increment => 100);
+ -- The table for lists of numbers
package Mapping_Files_Htable is new Simple_HTable
(Header_Num => Header_Num,
@@ -623,6 +639,12 @@ package Prj is
Project : Project_Id := No_Project;
-- Project of the source
+ Source_Dir_Rank : Natural := 0;
+ -- The rank of the source directory in list declared with attribute
+ -- Source_Dirs. Two source files with the same name cannot appears in
+ -- different directory with the same rank. That can happen when the
+ -- recursive notation <dir>/** is used in attribute Source_Dirs.
+
Language : Language_Ptr := No_Language_Index;
-- Index of the language. This is an index into
-- Project_Tree.Languages_Data.
@@ -717,6 +739,7 @@ package Prj is
No_Source_Data : constant Source_Data :=
(Project => No_Project,
+ Source_Dir_Rank => 0,
Language => No_Language_Index,
In_Interfaces => True,
Declared_In_Interfaces => False,
@@ -1155,10 +1178,7 @@ package Prj is
Source_Dirs : String_List_Id := Nil_String;
-- The list of all the source directories
- Known_Order_Of_Source_Dirs : Boolean := True;
- -- False, if there is any /** in the Source_Dirs, because in this case
- -- the ordering of the source subdirs depend on the OS. If True,
- -- duplicate file names in the same project file are allowed.
+ Source_Dir_Ranks : Number_List_Index := No_Number_List;
Ada_Include_Path : String_Access := null;
-- The cached value of source search path for this project file. Set by
@@ -1273,6 +1293,7 @@ package Prj is
type Project_Tree_Data is
record
Name_Lists : Name_List_Table.Instance;
+ Number_Lists : Number_List_Table.Instance;
String_Elements : String_Element_Table.Instance;
Variable_Elements : Variable_Element_Table.Instance;
Array_Elements : Array_Element_Table.Instance;
diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c
index c4218c2ab78..c1075d68126 100644
--- a/gcc/ada/s-oscons-tmplt.c
+++ b/gcc/ada/s-oscons-tmplt.c
@@ -58,7 +58,7 @@ pragma Style_Checks ("M32766");
** s-oscons-tmpl.s.
**
** The default one assumes that the template can be compiled by the newly-
- ** build cross compiler. It uses markup produced in the (pseudo-)assembly
+ ** built cross compiler. It uses markup produced in the (pseudo-)assembly
** listing:
**
** xgcc -DTARGET=\"$target\" -C -E s-oscons-tmplt.c > s-oscons-tmplt.i
@@ -175,6 +175,9 @@ int counter = 0;
#endif
+#define STR(x) STR1(x)
+#define STR1(x) #x
+
#ifdef __MINGW32__
unsigned int _CRT_fmode = _O_BINARY;
#endif
@@ -218,6 +221,25 @@ package System.OS_Constants is
/*
+ -----------------------------
+ -- Platform identification --
+ -----------------------------
+
+*/
+TXT(" Target_Name : constant String := " STR(TARGET) ";")
+/*
+ type Target_OS_Type is (Windows, VMS, Other_OS);
+*/
+#if defined (__MINGW32__)
+# define TARGET_OS "Windows"
+#elif defined (__VMS)
+# define TARGET_OS "VMS"
+#else
+# define TARGET_OS "Other_OS"
+#endif
+TXT(" Target_OS : constant Target_OS_Type := " TARGET_OS ";")
+/*
+
-------------------
-- System limits --
-------------------
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index 32323400b6d..94ed69e2598 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -5465,7 +5465,7 @@ package body Sem_Ch6 is
-- generated stream attributes do get passed through because extra
-- build-in-place formals are needed in some cases (limited 'Input).
- if Is_Predefined_Dispatching_Operation (E) then
+ if Is_Predefined_Internal_Operation (E) then
goto Test_For_BIP_Extras;
end if;
diff --git a/gcc/ada/sinfo.adb b/gcc/ada/sinfo.adb
index 816adcf5afc..dd4aaafce9a 100644
--- a/gcc/ada/sinfo.adb
+++ b/gcc/ada/sinfo.adb
@@ -1583,6 +1583,14 @@ package body Sinfo is
return Uint3 (N);
end Intval;
+ function Is_Accessibility_Actual
+ (N : Node_Id) return Boolean is
+ begin
+ pragma Assert (False
+ or else NT (N).Nkind = N_Parameter_Association);
+ return Flag12 (N);
+ end Is_Accessibility_Actual;
+
function Is_Asynchronous_Call_Block
(N : Node_Id) return Boolean is
begin
@@ -4435,6 +4443,14 @@ package body Sinfo is
Set_Uint3 (N, Val);
end Set_Intval;
+ procedure Set_Is_Accessibility_Actual
+ (N : Node_Id; Val : Boolean := True) is
+ begin
+ pragma Assert (False
+ or else NT (N).Nkind = N_Parameter_Association);
+ Set_Flag12 (N, Val);
+ end Set_Is_Accessibility_Actual;
+
procedure Set_Is_Asynchronous_Call_Block
(N : Node_Id; Val : Boolean := True) is
begin
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index b598b771de3..2e666c49a64 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -1179,6 +1179,13 @@ package Sinfo is
-- to the node for the spec of the instance, inserted as part of the
-- semantic processing for instantiations in Sem_Ch12.
+ -- Is_Accessibility_Actual (Flag12-Sem)
+ -- Present in N_Parameter_Association nodes. True if the parameter is
+ -- an extra actual that carries the accessibility level of the actual
+ -- for an access parameter, in a function that dispatches on result and
+ -- is called in a dispatching context. Used to prevent a formal/actual
+ -- mismatch when the call is rewritten as a dispatching call.
+
-- Is_Asynchronous_Call_Block (Flag7-Sem)
-- A flag set in a Block_Statement node to indicate that it is the
-- expansion of an asynchronous entry call. Such a block needs cleanup
@@ -4450,6 +4457,7 @@ package Sinfo is
-- Selector_Name (Node2) (always non-Empty)
-- Explicit_Actual_Parameter (Node3)
-- Next_Named_Actual (Node4-Sem)
+ -- Is_Accessibility_Actual (Flag12-Sem)
---------------------------
-- 6.4 Actual Parameter --
@@ -8070,6 +8078,9 @@ package Sinfo is
function Intval
(N : Node_Id) return Uint; -- Uint3
+ function Is_Accessibility_Actual
+ (N : Node_Id) return Boolean; -- Flag12
+
function Is_Asynchronous_Call_Block
(N : Node_Id) return Boolean; -- Flag7
@@ -8979,6 +8990,9 @@ package Sinfo is
procedure Set_Intval
(N : Node_Id; Val : Uint); -- Uint3
+ procedure Set_Is_Accessibility_Actual
+ (N : Node_Id; Val : Boolean := True); -- Flag12
+
procedure Set_Is_Asynchronous_Call_Block
(N : Node_Id; Val : Boolean := True); -- Flag7
@@ -11246,6 +11260,7 @@ package Sinfo is
pragma Inline (In_Present);
pragma Inline (Instance_Spec);
pragma Inline (Intval);
+ pragma Inline (Is_Accessibility_Actual);
pragma Inline (Is_Asynchronous_Call_Block);
pragma Inline (Is_Component_Left_Opnd);
pragma Inline (Is_Component_Right_Opnd);
@@ -11545,6 +11560,7 @@ package Sinfo is
pragma Inline (Set_In_Present);
pragma Inline (Set_Instance_Spec);
pragma Inline (Set_Intval);
+ pragma Inline (Set_Is_Accessibility_Actual);
pragma Inline (Set_Is_Asynchronous_Call_Block);
pragma Inline (Set_Is_Component_Left_Opnd);
pragma Inline (Set_Is_Component_Right_Opnd);
diff --git a/gcc/ada/switch-c.adb b/gcc/ada/switch-c.adb
index 1ecae61a013..9ccba42377d 100644
--- a/gcc/ada/switch-c.adb
+++ b/gcc/ada/switch-c.adb
@@ -310,6 +310,7 @@ package body Switch.C is
case Switch_Chars (Ptr) is
-- -gnatea (initial delimiter of explicit switches)
+
-- All switches that come before -gnatea have been added by
-- the GCC driver and are not stored in the ALI file.
-- See also -gnatez below.
@@ -370,6 +371,7 @@ package body Switch.C is
return;
-- -gnateC switch (CodePeer SCIL generation)
+
-- Not enabled for now, keep it for later???
-- use -gnatd.I only for now
@@ -468,9 +470,10 @@ package body Switch.C is
Ptr := Max + 1;
-- -gnatez (final delimiter of explicit switches)
+
-- All switches that come after -gnatez have been added by
- -- the GCC driver and are not stored in the ALI file.
- -- See also -gnatea above.
+ -- the GCC driver and are not stored in the ALI file. See
+ -- also -gnatea above.
when 'z' =>
Store_Switch := False;
@@ -478,6 +481,7 @@ package body Switch.C is
Ptr := Ptr + 1;
-- -gnateS (generate SCO information)
+
-- Include Source Coverage Obligation information in ALI
-- files for the benefit of source coverage analysis tools
-- (xcov).
diff --git a/gcc/ada/switch-m.adb b/gcc/ada/switch-m.adb
index 8456ea32b58..316b77e702b 100644
--- a/gcc/ada/switch-m.adb
+++ b/gcc/ada/switch-m.adb
@@ -532,8 +532,9 @@ package body Switch.M is
------------------------
procedure Scan_Make_Switches
- (Switch_Chars : String;
- Success : out Boolean)
+ (Project_Node_Tree : Prj.Tree.Project_Node_Tree_Ref;
+ Switch_Chars : String;
+ Success : out Boolean)
is
Ptr : Integer := Switch_Chars'First;
Max : constant Integer := Switch_Chars'Last;
@@ -590,7 +591,8 @@ package body Switch.M is
and then Switch_Chars (Ptr .. Ptr + 1) = "aP"
then
Add_Search_Project_Directory
- (Switch_Chars (Ptr + 2 .. Switch_Chars'Last));
+ (Project_Node_Tree,
+ Switch_Chars (Ptr + 2 .. Switch_Chars'Last));
elsif C = 'v' and then Switch_Chars'Length = 3 then
Ptr := Ptr + 1;
diff --git a/gcc/ada/switch-m.ads b/gcc/ada/switch-m.ads
index 9a6124b4640..a7301761f93 100644
--- a/gcc/ada/switch-m.ads
+++ b/gcc/ada/switch-m.ads
@@ -30,17 +30,21 @@
-- the otherwise undocumented debug switches that are also recognized.
with System.OS_Lib; use System.OS_Lib;
+with Prj.Tree;
package Switch.M is
procedure Scan_Make_Switches
- (Switch_Chars : String;
- Success : out Boolean);
+ (Project_Node_Tree : Prj.Tree.Project_Node_Tree_Ref;
+ Switch_Chars : String;
+ Success : out Boolean);
-- Scan a gnatmake switch and act accordingly. For switches that are
-- recognized, Success is set to True. A switch that is not recognized and
-- consists of one small letter causes a fatal error exit and control does
-- not return. For all other not recognized switches, Success is set to
-- False, so that the switch may be passed to the compiler.
+ -- Project_Node_Tree is used to store tree-specific parameters like the
+ -- project path
procedure Normalize_Compiler_Switches
(Switch_Chars : String;
diff --git a/gcc/builtins.c b/gcc/builtins.c
index d4801b14e55..8ef96070c3a 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -6236,6 +6236,7 @@ static void
expand_builtin_synchronize (void)
{
gimple x;
+ VEC (tree, gc) *v_clobbers;
#ifdef HAVE_memory_barrier
if (HAVE_memory_barrier)
@@ -6253,8 +6254,10 @@ expand_builtin_synchronize (void)
/* If no explicit memory barrier instruction is available, create an
empty asm stmt with a memory clobber. */
- x = gimple_build_asm ("", 0, 0, 1,
- tree_cons (NULL, build_string (6, "memory"), NULL));
+ v_clobbers = VEC_alloc (tree, gc, 1);
+ VEC_quick_push (tree, v_clobbers,
+ tree_cons (NULL, build_string (6, "memory"), NULL));
+ x = gimple_build_asm_vec ("", NULL, NULL, v_clobbers, NULL);
gimple_asm_set_volatile (x, true);
expand_asm_stmt (x);
}
@@ -6940,6 +6943,12 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
#endif
case BUILT_IN_EXTEND_POINTER:
return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
+ case BUILT_IN_EH_POINTER:
+ return expand_builtin_eh_pointer (exp);
+ case BUILT_IN_EH_FILTER:
+ return expand_builtin_eh_filter (exp);
+ case BUILT_IN_EH_COPY_VALUES:
+ return expand_builtin_eh_copy_values (exp);
case BUILT_IN_VA_START:
return expand_builtin_va_start (exp);
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 8d1693605a6..00287c7548a 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -759,6 +759,12 @@ DEF_BUILTIN (BUILT_IN_EMUTLS_REGISTER_COMMON,
true, true, true, ATTR_NOTHROW_LIST, false,
!targetm.have_tls)
+/* Exception support. */
+DEF_BUILTIN_STUB (BUILT_IN_UNWIND_RESUME, "__builtin_unwind_resume")
+DEF_BUILTIN_STUB (BUILT_IN_EH_POINTER, "__builtin_eh_pointer")
+DEF_BUILTIN_STUB (BUILT_IN_EH_FILTER, "__builtin_eh_filter")
+DEF_BUILTIN_STUB (BUILT_IN_EH_COPY_VALUES, "__builtin_eh_copy_values")
+
/* Synchronization Primitives. */
#include "sync-builtins.def"
diff --git a/gcc/c-common.c b/gcc/c-common.c
index a19489c49df..25c0c0137d1 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -4574,7 +4574,7 @@ c_define_builtins (tree va_list_ref_type_node, tree va_list_arg_type_node)
targetm.init_builtins ();
- build_common_builtin_nodes ();
+ build_common_builtin_nodes (c_dialect_cxx ());
if (flag_mudflap)
mudflap_init ();
diff --git a/gcc/c-common.h b/gcc/c-common.h
index d372e70631e..9b7905b5a30 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -360,8 +360,8 @@ c_language_kind;
front end. For "ObjC features" or "not C++" use the macros. */
extern c_language_kind c_language;
-#define c_dialect_cxx() (c_language & clk_cxx)
-#define c_dialect_objc() (c_language & clk_objc)
+#define c_dialect_cxx() ((c_language & clk_cxx) != 0)
+#define c_dialect_objc() ((c_language & clk_objc) != 0)
/* Information about a statement tree. */
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index fec9919ea56..6f12df9177e 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -93,9 +93,6 @@ tree pending_invalid_xref;
/* File and line to appear in the eventual error message. */
location_t pending_invalid_xref_location;
-/* True means we've initialized exception handling. */
-bool c_eh_initialized_p;
-
/* The file and line that the prototype came from if this is an
old-style definition; used for diagnostics in
store_parm_decls_oldstyle. */
@@ -2414,7 +2411,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
TREE_USED (olddecl) = 1;
/* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
- But preserve OLDDECL's DECL_UID and DECL_CONTEXT. */
+ But preserve OLDDECL's DECL_UID, DECL_CONTEXT and
+ DECL_ARGUMENTS (if appropriate). */
{
unsigned olddecl_uid = DECL_UID (olddecl);
tree olddecl_context = DECL_CONTEXT (olddecl);
@@ -4092,23 +4090,6 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
return tem;
}
-/* Initialize EH if not initialized yet and exceptions are enabled. */
-
-void
-c_maybe_initialize_eh (void)
-{
- if (!flag_exceptions || c_eh_initialized_p)
- return;
-
- c_eh_initialized_p = true;
- eh_personality_libfunc
- = init_one_libfunc (USING_SJLJ_EXCEPTIONS
- ? "__gcc_personality_sj0"
- : "__gcc_personality_v0");
- default_init_unwind_resume_libfunc ();
- using_eh_for_cleanups ();
-}
-
/* Finish processing of a declaration;
install its initial value.
If ORIGTYPE is not NULL_TREE, it is the original type of INIT.
@@ -4427,9 +4408,6 @@ finish_decl (tree decl, location_t init_loc, tree init,
TREE_USED (decl) = 1;
TREE_USED (cleanup_decl) = 1;
- /* Initialize EH, if we've been told to do so. */
- c_maybe_initialize_eh ();
-
push_cleanup (decl, cleanup, false);
}
}
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 43b0c8ce38c..d9ea159c4e5 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "cgraph.h"
#include "plugin.h"
+#include "except.h"
/* Initialization routine for this file. */
@@ -902,6 +903,7 @@ static void c_parser_do_statement (c_parser *);
static void c_parser_for_statement (c_parser *);
static tree c_parser_asm_statement (c_parser *);
static tree c_parser_asm_operands (c_parser *, bool);
+static tree c_parser_asm_goto_operands (c_parser *);
static tree c_parser_asm_clobbers (c_parser *);
static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *);
static struct c_expr c_parser_conditional_expression (c_parser *,
@@ -4225,12 +4227,17 @@ c_parser_for_statement (c_parser *parser)
asm-statement:
asm type-qualifier[opt] ( asm-argument ) ;
+ asm type-qualifier[opt] goto ( asm-goto-argument ) ;
asm-argument:
asm-string-literal
asm-string-literal : asm-operands[opt]
asm-string-literal : asm-operands[opt] : asm-operands[opt]
- asm-string-literal : asm-operands[opt] : asm-operands[opt] : asm-clobbers
+ asm-string-literal : asm-operands[opt] : asm-operands[opt] : asm-clobbers[opt]
+
+ asm-goto-argument:
+ asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
+ : asm-goto-operands
Qualifiers other than volatile are accepted in the syntax but
warned for. */
@@ -4238,9 +4245,11 @@ c_parser_for_statement (c_parser *parser)
static tree
c_parser_asm_statement (c_parser *parser)
{
- tree quals, str, outputs, inputs, clobbers, ret;
- bool simple;
+ tree quals, str, outputs, inputs, clobbers, labels, ret;
+ bool simple, is_goto;
location_t asm_loc = c_parser_peek_token (parser)->location;
+ int section, nsections;
+
gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
c_parser_consume_token (parser);
if (c_parser_next_token_is_keyword (parser, RID_VOLATILE))
@@ -4260,85 +4269,96 @@ c_parser_asm_statement (c_parser *parser)
}
else
quals = NULL_TREE;
+
+ is_goto = false;
+ if (c_parser_next_token_is_keyword (parser, RID_GOTO))
+ {
+ c_parser_consume_token (parser);
+ is_goto = true;
+ }
+
/* ??? Follow the C++ parser rather than using the
lex_untranslated_string kludge. */
parser->lex_untranslated_string = true;
+ ret = NULL;
+
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
- {
- parser->lex_untranslated_string = false;
- return NULL_TREE;
- }
+ goto error;
+
str = c_parser_asm_string_literal (parser);
if (str == NULL_TREE)
- {
- parser->lex_untranslated_string = false;
- c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- return NULL_TREE;
- }
- if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- {
- simple = true;
- outputs = NULL_TREE;
- inputs = NULL_TREE;
- clobbers = NULL_TREE;
- goto done_asm;
- }
- if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>"))
- {
- parser->lex_untranslated_string = false;
- c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- return NULL_TREE;
- }
- simple = false;
- /* Parse outputs. */
- if (c_parser_next_token_is (parser, CPP_COLON)
- || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- outputs = NULL_TREE;
- else
- outputs = c_parser_asm_operands (parser, false);
- if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- {
- inputs = NULL_TREE;
- clobbers = NULL_TREE;
- goto done_asm;
- }
- if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>"))
- {
- parser->lex_untranslated_string = false;
- c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- return NULL_TREE;
- }
- /* Parse inputs. */
- if (c_parser_next_token_is (parser, CPP_COLON)
- || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- inputs = NULL_TREE;
- else
- inputs = c_parser_asm_operands (parser, true);
- if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- {
- clobbers = NULL_TREE;
- goto done_asm;
- }
- if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>"))
- {
- parser->lex_untranslated_string = false;
- c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- return NULL_TREE;
+ goto error_close_paren;
+
+ simple = true;
+ outputs = NULL_TREE;
+ inputs = NULL_TREE;
+ clobbers = NULL_TREE;
+ labels = NULL_TREE;
+
+ if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
+ goto done_asm;
+
+ /* Parse each colon-delimited section of operands. */
+ nsections = 3 + is_goto;
+ for (section = 0; section < nsections; ++section)
+ {
+ if (!c_parser_require (parser, CPP_COLON,
+ is_goto
+ ? "expected %<:%>"
+ : "expected %<:%> or %<)%>"))
+ goto error_close_paren;
+
+ /* Once past any colon, we're no longer a simple asm. */
+ simple = false;
+
+ if ((!c_parser_next_token_is (parser, CPP_COLON)
+ && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ || section == 3)
+ switch (section)
+ {
+ case 0:
+ /* For asm goto, we don't allow output operands, but reserve
+ the slot for a future extension that does allow them. */
+ if (!is_goto)
+ outputs = c_parser_asm_operands (parser, false);
+ break;
+ case 1:
+ inputs = c_parser_asm_operands (parser, true);
+ break;
+ case 2:
+ clobbers = c_parser_asm_clobbers (parser);
+ break;
+ case 3:
+ labels = c_parser_asm_goto_operands (parser);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
+ goto done_asm;
}
- /* Parse clobbers. */
- clobbers = c_parser_asm_clobbers (parser);
+
done_asm:
- parser->lex_untranslated_string = false;
if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- return NULL_TREE;
+ goto error;
}
+
if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
c_parser_skip_to_end_of_block_or_statement (parser);
+
ret = build_asm_stmt (quals, build_asm_expr (asm_loc, str, outputs, inputs,
- clobbers, simple));
+ clobbers, labels, simple));
+
+ error:
+ parser->lex_untranslated_string = false;
return ret;
+
+ error_close_paren:
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ goto error;
}
/* Parse asm operands, a GNU extension. If CONVERT_P (for inputs but
@@ -4440,6 +4460,45 @@ c_parser_asm_clobbers (c_parser *parser)
return list;
}
+/* Parse asm goto labels, a GNU extension.
+
+ asm-goto-operands:
+ identifier
+ asm-goto-operands , identifier
+*/
+
+static tree
+c_parser_asm_goto_operands (c_parser *parser)
+{
+ tree list = NULL_TREE;
+ while (true)
+ {
+ tree name, label;
+
+ if (c_parser_next_token_is (parser, CPP_NAME))
+ {
+ c_token *tok = c_parser_peek_token (parser);
+ name = tok->value;
+ label = lookup_label_for_goto (tok->location, name);
+ c_parser_consume_token (parser);
+ TREE_USED (label) = 1;
+ }
+ else
+ {
+ c_parser_error (parser, "expected identifier");
+ return NULL_TREE;
+ }
+
+ name = build_string (IDENTIFIER_LENGTH (name),
+ IDENTIFIER_POINTER (name));
+ list = tree_cons (name, label, list);
+ if (c_parser_next_token_is (parser, CPP_COMMA))
+ c_parser_consume_token (parser);
+ else
+ return nreverse (list);
+ }
+}
+
/* Parse an expression other than a compound expression; that is, an
assignment expression (C90 6.3.16, C99 6.5.16). If AFTER is not
NULL then it is an Objective-C message expression which is the
@@ -8489,12 +8548,6 @@ c_parser_omp_construct (c_parser *parser)
p_kind = c_parser_peek_token (parser)->pragma_kind;
c_parser_consume_pragma (parser);
- /* For all constructs below except #pragma omp atomic
- MUST_NOT_THROW catch handlers are needed when exceptions
- are enabled. */
- if (p_kind != PRAGMA_OMP_ATOMIC)
- c_maybe_initialize_eh ();
-
switch (p_kind)
{
case PRAGMA_OMP_ATOMIC:
@@ -8607,6 +8660,10 @@ c_parse_file (void)
the_parser = GGC_NEW (c_parser);
*the_parser = tparser;
+ /* Initialize EH, if we've been told to do so. */
+ if (flag_exceptions)
+ using_eh_for_cleanups ();
+
c_parser_translation_unit (the_parser);
the_parser = NULL;
}
diff --git a/gcc/c-pretty-print.c b/gcc/c-pretty-print.c
index f9694bfc080..c4e6e96c296 100644
--- a/gcc/c-pretty-print.c
+++ b/gcc/c-pretty-print.c
@@ -2235,7 +2235,7 @@ pp_c_tree_decl_identifier (c_pretty_printer *pp, tree t)
else
{
static char xname[8];
- sprintf (xname, "<U%4x>", ((unsigned)((unsigned long)(t) & 0xffff)));
+ sprintf (xname, "<U%4x>", ((unsigned)((uintptr_t)(t) & 0xffff)));
name = xname;
}
diff --git a/gcc/c-tree.h b/gcc/c-tree.h
index 40419f0e8bd..2262edf92c5 100644
--- a/gcc/c-tree.h
+++ b/gcc/c-tree.h
@@ -427,7 +427,6 @@ extern struct c_spot_bindings *c_get_switch_bindings (void);
extern void c_release_switch_bindings (struct c_spot_bindings *);
extern bool c_check_switch_jump_warnings (struct c_spot_bindings *,
location_t, location_t);
-extern void c_maybe_initialize_eh (void);
extern void finish_decl (tree, location_t, tree, tree, tree);
extern tree finish_enum (tree, tree, tree);
extern void finish_function (void);
@@ -542,7 +541,7 @@ extern tree build_compound_literal (location_t, tree, tree, bool);
extern void check_compound_literal_type (location_t, struct c_type_name *);
extern tree c_start_case (location_t, location_t, tree);
extern void c_finish_case (tree);
-extern tree build_asm_expr (location_t, tree, tree, tree, tree, bool);
+extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool);
extern tree build_asm_stmt (tree, tree);
extern int c_types_compatible_p (tree, tree);
extern tree c_begin_compound_stmt (bool);
@@ -589,9 +588,6 @@ extern int system_header_p;
extern bool c_override_global_bindings_to_false;
-/* True means we've initialized exception handling. */
-extern bool c_eh_initialized_p;
-
/* In c-decl.c */
extern void c_finish_incomplete_decl (tree);
extern void c_write_global_declarations (void);
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index c5688e298bb..892ca76cc42 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -7948,7 +7948,7 @@ build_asm_stmt (tree cv_qualifier, tree args)
are subtly different. We use a ASM_EXPR node to represent this. */
tree
build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
- tree clobbers, bool simple)
+ tree clobbers, tree labels, bool simple)
{
tree tail;
tree args;
@@ -7962,7 +7962,7 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
noutputs = list_length (outputs);
oconstraints = (const char **) alloca (noutputs * sizeof (const char *));
- string = resolve_asm_operand_names (string, outputs, inputs);
+ string = resolve_asm_operand_names (string, outputs, inputs, labels);
/* Remove output conversions that change the type but not the mode. */
for (i = 0, tail = outputs; tail; ++i, tail = TREE_CHAIN (tail))
@@ -8032,7 +8032,11 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
TREE_VALUE (tail) = input;
}
- args = build_stmt (loc, ASM_EXPR, string, outputs, inputs, clobbers);
+ /* ASMs with labels cannot have outputs. This should have been
+ enforced by the parser. */
+ gcc_assert (outputs == NULL || labels == NULL);
+
+ args = build_stmt (loc, ASM_EXPR, string, outputs, inputs, clobbers, labels);
/* asm statements without outputs, including simple ones, are treated
as volatile. */
diff --git a/gcc/calls.c b/gcc/calls.c
index 20639098e02..16229cc4def 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -376,10 +376,8 @@ emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNU
if (ecf_flags & ECF_LOOPING_CONST_OR_PURE)
RTL_LOOPING_CONST_OR_PURE_CALL_P (call_insn) = 1;
- /* If this call can't throw, attach a REG_EH_REGION reg note to that
- effect. */
- if (ecf_flags & ECF_NOTHROW)
- add_reg_note (call_insn, REG_EH_REGION, const0_rtx);
+ /* Create a nothrow REG_EH_REGION note, if needed. */
+ make_reg_eh_region_note (call_insn, ecf_flags, 0);
if (ecf_flags & ECF_NORETURN)
add_reg_note (call_insn, REG_NORETURN, const0_rtx);
diff --git a/gcc/cfg.c b/gcc/cfg.c
index 9c41930a36f..550f8f13d3b 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -546,10 +546,10 @@ dump_bb_info (basic_block bb, bool header, bool footer, int flags,
/* Both maybe_hot_bb_p & probably_never_executed_bb_p functions
crash without cfun. */
if (cfun && maybe_hot_bb_p (bb))
- fprintf (file, ", maybe hot");
+ fputs (", maybe hot", file);
if (cfun && probably_never_executed_bb_p (bb))
- fprintf (file, ", probably never executed");
- fprintf (file, ".\n");
+ fputs (", probably never executed", file);
+ fputs (".\n", file);
fprintf (file, "%sPredecessors: ", prefix);
FOR_EACH_EDGE (e, ei, bb->preds)
@@ -559,7 +559,7 @@ dump_bb_info (basic_block bb, bool header, bool footer, int flags,
&& (bb->flags & BB_RTL)
&& df)
{
- fprintf (file, "\n");
+ putc ('\n', file);
df_dump_top (bb, file);
}
}
@@ -574,7 +574,7 @@ dump_bb_info (basic_block bb, bool header, bool footer, int flags,
&& (bb->flags & BB_RTL)
&& df)
{
- fprintf (file, "\n");
+ putc ('\n', file);
df_dump_bottom (bb, file);
}
}
@@ -615,11 +615,11 @@ dump_reg_info (FILE *file)
fprintf (file, "; set %d time%s", DF_REG_DEF_COUNT (i),
(DF_REG_DEF_COUNT (i) == 1) ? "" : "s");
if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
- fprintf (file, "; user var");
+ fputs ("; user var", file);
if (REG_N_DEATHS (i) != 1)
fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
if (REG_N_CALLS_CROSSED (i) == 1)
- fprintf (file, "; crosses 1 call");
+ fputs ("; crosses 1 call", file);
else if (REG_N_CALLS_CROSSED (i))
fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
if (REG_FREQ_CALLS_CROSSED (i))
@@ -643,8 +643,8 @@ dump_reg_info (FILE *file)
}
if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
- fprintf (file, "; pointer");
- fprintf (file, ".\n");
+ fputs ("; pointer", file);
+ fputs (".\n", file);
}
}
@@ -691,7 +691,7 @@ dump_edge_info (FILE *file, edge e, int do_succ)
if (e->count)
{
- fprintf (file, " count:");
+ fputs (" count:", file);
fprintf (file, HOST_WIDEST_INT_PRINT_DEC, e->count);
}
@@ -904,24 +904,24 @@ dump_cfg_bb_info (FILE *file, basic_block bb)
if (bb->flags & (1 << i))
{
if (first)
- fprintf (file, " (");
+ fputs (" (", file);
else
- fprintf (file, ", ");
+ fputs (", ", file);
first = false;
- fprintf (file, bb_bitnames[i]);
+ fputs (bb_bitnames[i], file);
}
if (!first)
- fprintf (file, ")");
- fprintf (file, "\n");
+ putc (')', file);
+ putc ('\n', file);
- fprintf (file, "Predecessors: ");
+ fputs ("Predecessors: ", file);
FOR_EACH_EDGE (e, ei, bb->preds)
dump_edge_info (file, e, 0);
fprintf (file, "\nSuccessors: ");
FOR_EACH_EDGE (e, ei, bb->succs)
dump_edge_info (file, e, 1);
- fprintf (file, "\n\n");
+ fputs ("\n\n", file);
}
/* Dumps a brief description of cfg to FILE. */
diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
index 6e941bf55e9..b063f898507 100644
--- a/gcc/cfgbuild.c
+++ b/gcc/cfgbuild.c
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "output.h"
#include "function.h"
#include "except.h"
+#include "expr.h"
#include "toplev.h"
#include "timevar.h"
@@ -80,8 +81,6 @@ inside_basic_block_p (const_rtx insn)
bool
control_flow_insn_p (const_rtx insn)
{
- rtx note;
-
switch (GET_CODE (insn))
{
case NOTE:
@@ -101,21 +100,20 @@ control_flow_insn_p (const_rtx insn)
|| find_reg_note (insn, REG_NORETURN, 0))
&& GET_CODE (PATTERN (insn)) != COND_EXEC)
return true;
+
/* Call insn may return to the nonlocal goto handler. */
- return ((nonlocal_goto_handler_labels
- && (0 == (note = find_reg_note (insn, REG_EH_REGION,
- NULL_RTX))
- || INTVAL (XEXP (note, 0)) >= 0))
- /* Or may trap. */
- || can_throw_internal (insn));
+ if (can_nonlocal_goto (insn))
+ return true;
+ break;
case INSN:
/* Treat trap instructions like noreturn calls (same provision). */
if (GET_CODE (PATTERN (insn)) == TRAP_IF
&& XEXP (PATTERN (insn), 0) == const1_rtx)
return true;
-
- return (flag_non_call_exceptions && can_throw_internal (insn));
+ if (!flag_non_call_exceptions)
+ return false;
+ break;
case BARRIER:
/* It is nonsense to reach barrier when looking for the
@@ -126,6 +124,8 @@ control_flow_insn_p (const_rtx insn)
default:
gcc_unreachable ();
}
+
+ return can_throw_internal (insn);
}
@@ -155,16 +155,23 @@ make_label_edge (sbitmap edge_cache, basic_block src, rtx label, int flags)
void
rtl_make_eh_edge (sbitmap edge_cache, basic_block src, rtx insn)
{
- int is_call = CALL_P (insn) ? EDGE_ABNORMAL_CALL : 0;
- rtx handlers, i;
+ eh_landing_pad lp = get_eh_landing_pad_from_rtx (insn);
- handlers = reachable_handlers (insn);
+ if (lp)
+ {
+ rtx label = lp->landing_pad;
- for (i = handlers; i; i = XEXP (i, 1))
- make_label_edge (edge_cache, src, XEXP (i, 0),
- EDGE_ABNORMAL | EDGE_EH | is_call);
+ /* During initial rtl generation, use the post_landing_pad. */
+ if (label == NULL)
+ {
+ gcc_assert (lp->post_landing_pad);
+ label = label_rtx (lp->post_landing_pad);
+ }
- free_INSN_LIST_list (&handlers);
+ make_label_edge (edge_cache, src, label,
+ EDGE_ABNORMAL | EDGE_EH
+ | (CALL_P (insn) ? EDGE_ABNORMAL_CALL : 0));
+ }
}
/* States of basic block as seen by find_many_sub_basic_blocks. */
@@ -253,13 +260,9 @@ make_edges (basic_block min, basic_block max, int update_p)
{
rtx tmp;
- /* Recognize exception handling placeholders. */
- if (GET_CODE (PATTERN (insn)) == RESX)
- rtl_make_eh_edge (edge_cache, bb, insn);
-
/* Recognize a non-local goto as a branch outside the
current function. */
- else if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
+ if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
;
/* Recognize a tablejump and do the right thing. */
@@ -300,6 +303,15 @@ make_edges (basic_block min, basic_block max, int update_p)
else if (returnjump_p (insn))
cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR, 0);
+ /* Recognize asm goto and do the right thing. */
+ else if ((tmp = extract_asm_operands (PATTERN (insn))) != NULL)
+ {
+ int i, n = ASM_OPERANDS_LABEL_LENGTH (tmp);
+ for (i = 0; i < n; ++i)
+ make_label_edge (edge_cache, bb,
+ XEXP (ASM_OPERANDS_LABEL (tmp, i), 0), 0);
+ }
+
/* Otherwise, we have a plain conditional or unconditional jump. */
else
{
@@ -333,12 +345,7 @@ make_edges (basic_block min, basic_block max, int update_p)
gotos do not have their addresses taken, then only calls to
those functions or to other nested functions that use them
could possibly do nonlocal gotos. */
-
- /* We do know that a REG_EH_REGION note with a value less
- than 0 is guaranteed not to perform a non-local goto. */
- rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
-
- if (!note || INTVAL (XEXP (note, 0)) >= 0)
+ if (can_nonlocal_goto (insn))
for (x = nonlocal_goto_handler_labels; x; x = XEXP (x, 1))
make_label_edge (edge_cache, bb, XEXP (x, 0),
EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
@@ -446,8 +453,10 @@ find_bb_boundaries (basic_block bb)
{
enum rtx_code code = GET_CODE (insn);
- /* On code label, split current basic block. */
- if (code == CODE_LABEL)
+ /* In case we've previously seen an insn that effects a control
+ flow transfer, split the block. */
+ if ((flow_transfer_insn || code == CODE_LABEL)
+ && inside_basic_block_p (insn))
{
fallthru = split_block (bb, PREV_INSN (insn));
if (flow_transfer_insn)
@@ -465,34 +474,16 @@ find_bb_boundaries (basic_block bb)
bb = fallthru->dest;
remove_edge (fallthru);
flow_transfer_insn = NULL_RTX;
- if (LABEL_ALT_ENTRY_P (insn))
+ if (code == CODE_LABEL && LABEL_ALT_ENTRY_P (insn))
make_edge (ENTRY_BLOCK_PTR, bb, 0);
}
-
- /* __builtin_unreachable () may cause a barrier to be emitted in
- the middle of a BB. We need to split it in the same manner
- as if the barrier were preceded by a control_flow_insn_p
- insn. */
- if (code == BARRIER && !flow_transfer_insn)
- flow_transfer_insn = prev_nonnote_insn_bb (insn);
-
- /* In case we've previously seen an insn that effects a control
- flow transfer, split the block. */
- if (flow_transfer_insn && inside_basic_block_p (insn))
+ else if (code == BARRIER)
{
- fallthru = split_block (bb, PREV_INSN (insn));
- BB_END (bb) = flow_transfer_insn;
-
- /* Clean up the bb field for the insns between the blocks. */
- for (x = NEXT_INSN (flow_transfer_insn);
- x != BB_HEAD (fallthru->dest);
- x = NEXT_INSN (x))
- if (!BARRIER_P (x))
- set_block_for_insn (x, NULL);
-
- bb = fallthru->dest;
- remove_edge (fallthru);
- flow_transfer_insn = NULL_RTX;
+ /* __builtin_unreachable () may cause a barrier to be emitted in
+ the middle of a BB. We need to split it in the same manner as
+ if the barrier were preceded by a control_flow_insn_p insn. */
+ if (!flow_transfer_insn)
+ flow_transfer_insn = prev_nonnote_insn_bb (insn);
}
if (control_flow_insn_p (insn))
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index e840da88bcf..0ed6bd5903d 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -1820,9 +1820,6 @@ expand_gimple_stmt_1 (gimple stmt)
case GIMPLE_NOP:
case GIMPLE_PREDICT:
break;
- case GIMPLE_RESX:
- expand_resx_stmt (stmt);
- break;
case GIMPLE_SWITCH:
expand_case (stmt);
break;
@@ -1920,19 +1917,19 @@ expand_gimple_stmt_1 (gimple stmt)
;
else if (promoted)
{
- bool unsigndp = SUBREG_PROMOTED_UNSIGNED_P (target);
+ int unsignedp = SUBREG_PROMOTED_UNSIGNED_P (target);
/* If TEMP is a VOIDmode constant, use convert_modes to make
sure that we properly convert it. */
if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)
{
temp = convert_modes (GET_MODE (target),
TYPE_MODE (ops.type),
- temp, unsigndp);
+ temp, unsignedp);
temp = convert_modes (GET_MODE (SUBREG_REG (target)),
- GET_MODE (target), temp, unsigndp);
+ GET_MODE (target), temp, unsignedp);
}
- convert_move (SUBREG_REG (target), temp, unsigndp);
+ convert_move (SUBREG_REG (target), temp, unsignedp);
}
else if (nontemporal && emit_storent_insn (target, temp))
;
@@ -1961,7 +1958,7 @@ expand_gimple_stmt_1 (gimple stmt)
static rtx
expand_gimple_stmt (gimple stmt)
{
- int rn = -1;
+ int lp_nr = 0;
rtx last = NULL;
location_t saved_location = input_location;
@@ -1993,8 +1990,8 @@ expand_gimple_stmt (gimple stmt)
input_location = saved_location;
/* Mark all insns that may trap. */
- rn = lookup_stmt_eh_region (stmt);
- if (rn >= 0)
+ lp_nr = lookup_stmt_eh_lp (stmt);
+ if (lp_nr)
{
rtx insn;
for (insn = next_real_insn (last); insn;
@@ -2005,9 +2002,8 @@ expand_gimple_stmt (gimple stmt)
may_trap_p instruction may throw. */
&& GET_CODE (PATTERN (insn)) != CLOBBER
&& GET_CODE (PATTERN (insn)) != USE
- && (CALL_P (insn)
- || (flag_non_call_exceptions && may_trap_p (PATTERN (insn)))))
- add_reg_note (insn, REG_EH_REGION, GEN_INT (rn));
+ && insn_could_throw_p (insn))
+ make_reg_eh_region_note (insn, 0, lp_nr);
}
}
@@ -2540,15 +2536,6 @@ expand_debug_expr (tree exp)
op0, GEN_INT (bitsize), GEN_INT (bitpos));
}
- case EXC_PTR_EXPR:
- /* ??? Do not call get_exception_pointer(), we don't want to gen
- it if it hasn't been created yet. */
- return get_exception_pointer ();
-
- case FILTER_EXPR:
- /* Likewise get_exception_filter(). */
- return get_exception_filter ();
-
case ABS_EXPR:
return gen_rtx_ABS (mode, op0);
@@ -3556,12 +3543,10 @@ gimple_expand_cfg (void)
set_curr_insn_block (DECL_INITIAL (current_function_decl));
insn_locators_finalize ();
- /* Convert tree EH labels to RTL EH labels and zap the tree EH table. */
- convert_from_eh_region_ranges ();
+ /* Zap the tree EH table. */
set_eh_throw_stmt_table (cfun, NULL);
rebuild_jump_labels (get_insns ());
- find_exception_handler_labels ();
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
{
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index ca400a8c503..d6d1b3ab697 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -787,6 +787,17 @@ fixup_reorder_chain (void)
{
if (any_condjump_p (bb_end_insn))
{
+ /* This might happen if the conditional jump has side
+ effects and could therefore not be optimized away.
+ Make the basic block to end with a barrier in order
+ to prevent rtl_verify_flow_info from complaining. */
+ if (!e_fall)
+ {
+ gcc_assert (!onlyjump_p (bb_end_insn));
+ bb->il.rtl->footer = emit_barrier_after (bb_end_insn);
+ continue;
+ }
+
/* If the old fallthru is still next, nothing to do. */
if (bb->aux == e_fall->dest
|| e_fall->dest == EXIT_BLOCK_PTR)
@@ -848,6 +859,15 @@ fixup_reorder_chain (void)
continue;
}
}
+ else if (extract_asm_operands (PATTERN (bb_end_insn)) != NULL)
+ {
+ /* If the old fallthru is still next, nothing to do. */
+ if (bb->aux == e_fall->dest
+ || e_fall->dest == EXIT_BLOCK_PTR)
+ continue;
+
+ /* Otherwise we'll have to use the fallthru fixup below. */
+ }
else
{
/* Otherwise we have some return, switch or computed
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 4c4b3b72cc7..4146b146977 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -956,6 +956,45 @@ patch_jump_insn (rtx insn, rtx old_label, basic_block new_bb)
++LABEL_NUSES (new_label);
}
}
+ else if ((tmp = extract_asm_operands (PATTERN (insn))) != NULL)
+ {
+ int i, n = ASM_OPERANDS_LABEL_LENGTH (tmp);
+ rtx new_label, note;
+
+ if (new_bb == EXIT_BLOCK_PTR)
+ return false;
+ new_label = block_label (new_bb);
+
+ for (i = 0; i < n; ++i)
+ {
+ rtx old_ref = ASM_OPERANDS_LABEL (tmp, i);
+ gcc_assert (GET_CODE (old_ref) == LABEL_REF);
+ if (XEXP (old_ref, 0) == old_label)
+ {
+ ASM_OPERANDS_LABEL (tmp, i)
+ = gen_rtx_LABEL_REF (Pmode, new_label);
+ --LABEL_NUSES (old_label);
+ ++LABEL_NUSES (new_label);
+ }
+ }
+
+ if (JUMP_LABEL (insn) == old_label)
+ {
+ JUMP_LABEL (insn) = new_label;
+ note = find_reg_note (insn, REG_LABEL_TARGET, new_label);
+ if (note)
+ remove_note (insn, note);
+ }
+ else
+ {
+ note = find_reg_note (insn, REG_LABEL_TARGET, old_label);
+ if (note)
+ remove_note (insn, note);
+ if (JUMP_LABEL (insn) != new_label
+ && !find_reg_note (insn, REG_LABEL_TARGET, new_label))
+ add_reg_note (insn, REG_LABEL_TARGET, new_label);
+ }
+ }
else
{
/* ?? We may play the games with moving the named labels from
@@ -1873,12 +1912,16 @@ rtl_verify_flow_info_1 (void)
n_abnormal++;
}
- if (n_eh && GET_CODE (PATTERN (BB_END (bb))) != RESX
- && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX))
+ if (n_eh && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX))
{
error ("missing REG_EH_REGION note in the end of bb %i", bb->index);
err = 1;
}
+ if (n_eh > 1)
+ {
+ error ("too many eh edges %i", bb->index);
+ err = 1;
+ }
if (n_branch
&& (!JUMP_P (BB_END (bb))
|| (n_branch > 1 && (any_uncondjump_p (BB_END (bb))
@@ -1894,7 +1937,8 @@ rtl_verify_flow_info_1 (void)
}
if (n_branch != 1 && any_uncondjump_p (BB_END (bb)))
{
- error ("wrong amount of branch edges after unconditional jump %i", bb->index);
+ error ("wrong number of branch edges after unconditional jump %i",
+ bb->index);
err = 1;
}
if (n_branch != 1 && any_condjump_p (BB_END (bb))
@@ -2217,39 +2261,33 @@ purge_dead_edges (basic_block bb)
/* Cleanup abnormal edges caused by exceptions or non-local gotos. */
for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
{
+ bool remove = false;
+
/* There are three types of edges we need to handle correctly here: EH
edges, abnormal call EH edges, and abnormal call non-EH edges. The
latter can appear when nonlocal gotos are used. */
- if (e->flags & EDGE_EH)
+ if (e->flags & EDGE_ABNORMAL_CALL)
{
- if (can_throw_internal (insn)
- /* If this is a call edge, verify that this is a call insn. */
- && (! (e->flags & EDGE_ABNORMAL_CALL)
- || CALL_P (insn)))
- {
- ei_next (&ei);
- continue;
- }
+ if (!CALL_P (insn))
+ remove = true;
+ else if (can_nonlocal_goto (insn))
+ ;
+ else if ((e->flags & EDGE_EH) && can_throw_internal (insn))
+ ;
+ else
+ remove = true;
}
- else if (e->flags & EDGE_ABNORMAL_CALL)
+ else if (e->flags & EDGE_EH)
+ remove = !can_throw_internal (insn);
+
+ if (remove)
{
- if (CALL_P (insn)
- && (! (note = find_reg_note (insn, REG_EH_REGION, NULL))
- || INTVAL (XEXP (note, 0)) >= 0))
- {
- ei_next (&ei);
- continue;
- }
+ remove_edge (e);
+ df_set_bb_dirty (bb);
+ purged = true;
}
else
- {
- ei_next (&ei);
- continue;
- }
-
- remove_edge (e);
- df_set_bb_dirty (bb);
- purged = true;
+ ei_next (&ei);
}
if (JUMP_P (insn))
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 8310d7b9edd..907dbf743d3 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -84,6 +84,7 @@ The callgraph:
#include "tree-dump.h"
#include "tree-flow.h"
#include "value-prof.h"
+#include "except.h"
static void cgraph_node_remove_callers (struct cgraph_node *node);
static inline void cgraph_edge_remove_caller (struct cgraph_edge *e);
@@ -1998,6 +1999,12 @@ cgraph_add_new_function (tree fndecl, bool lowered)
current_function_decl = NULL;
break;
}
+
+ /* Set a personality if required and we already passed EH lowering. */
+ if (lowered
+ && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
+ == eh_personality_lang))
+ DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
}
/* Return true if NODE can be made local for API change.
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index f1d78b6efb2..789db15d69b 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1040,15 +1040,49 @@ cgraph_analyze_functions (void)
ggc_collect ();
}
+
+/* Emit thunks for every node in the cgraph.
+ FIXME: We really ought to emit thunks only for functions that are needed. */
+
+static void
+cgraph_emit_thunks (void)
+{
+ struct cgraph_node *n;
+
+ for (n = cgraph_nodes; n; n = n->next)
+ {
+ /* Only emit thunks on functions defined in this TU.
+ Note that this may emit more thunks than strictly necessary.
+ During optimization some nodes may disappear. It would be
+ nice to only emit thunks only for the functions that will be
+ emitted, but we cannot know that until the inliner and other
+ IPA passes have run (see the sequencing of the call to
+ cgraph_mark_functions_to_output in cgraph_optimize). */
+ if (n->reachable
+ && !DECL_EXTERNAL (n->decl))
+ lang_hooks.callgraph.emit_associated_thunks (n->decl);
+ }
+}
+
+
/* Analyze the whole compilation unit once it is parsed completely. */
void
cgraph_finalize_compilation_unit (void)
{
+ timevar_push (TV_CGRAPH);
+
/* Do not skip analyzing the functions if there were errors, we
miss diagnostics for following functions otherwise. */
+ /* Emit size functions we didn't inline. */
finalize_size_functions ();
+
+ /* Call functions declared with the "constructor" or "destructor"
+ attribute. */
+ cgraph_build_cdtor_fns ();
+
+ /* Mark alias targets necessary and emit diagnostics. */
finish_aliases_1 ();
if (!quiet_flag)
@@ -1057,9 +1091,19 @@ cgraph_finalize_compilation_unit (void)
fflush (stderr);
}
- timevar_push (TV_CGRAPH);
+ /* Gimplify and lower all functions, compute reachability and
+ remove unreachable nodes. */
+ cgraph_analyze_functions ();
+
+ /* Emit thunks for reachable nodes, if needed. */
+ if (lang_hooks.callgraph.emit_associated_thunks)
+ cgraph_emit_thunks ();
+
+ /* Mark alias targets necessary and emit diagnostics. */
+ finish_aliases_1 ();
+
+ /* Gimplify and lower thunks. */
cgraph_analyze_functions ();
- timevar_pop (TV_CGRAPH);
/* LIPO support */
varpool_do_link ();
@@ -1067,7 +1111,10 @@ cgraph_finalize_compilation_unit (void)
merge their alias sets. */
cgraph_unify_type_alias_sets ();
+ /* Finally drive the pass manager. */
cgraph_optimize ();
+
+ timevar_pop (TV_CGRAPH);
}
/* Hash function for symbol (function) resolution. */
@@ -1479,29 +1526,6 @@ ipa_passes (void)
}
-/* Emit thunks for every node in the cgraph.
- FIXME: We really ought to emit thunks only for functions that are needed. */
-
-static void
-cgraph_emit_thunks (void)
-{
- struct cgraph_node *n;
-
- for (n = cgraph_nodes; n; n = n->next)
- {
- /* Only emit thunks on functions defined in this TU.
- Note that this may emit more thunks than strictly necessary.
- During optimization some nodes may disappear. It would be
- nice to only emit thunks only for the functions that will be
- emitted, but we cannot know that until the inliner and other
- IPA passes have run (see the sequencing of the call to
- cgraph_mark_functions_to_output in cgraph_optimize). */
- if (!DECL_EXTERNAL (n->decl))
- lang_hooks.callgraph.emit_associated_thunks (n->decl);
- }
-}
-
-
/* Perform simple optimizations based on callgraph. */
static void
@@ -1514,22 +1538,9 @@ cgraph_optimize (void)
verify_cgraph ();
#endif
- /* Emit thunks, if needed. */
- if (lang_hooks.callgraph.emit_associated_thunks)
- {
- cgraph_emit_thunks ();
- if (errorcount || sorrycount)
- return;
- }
-
- /* Call functions declared with the "constructor" or "destructor"
- attribute. */
- cgraph_build_cdtor_fns ();
-
/* Frontend may output common variables after the unit has been finalized.
It is safe to deal with them here as they are always zero initialized. */
varpool_analyze_pending_decls ();
- cgraph_analyze_functions ();
timevar_push (TV_CGRAPHOPT);
if (pre_ipa_mem_report)
@@ -1722,10 +1733,7 @@ update_call_expr (struct cgraph_node *new_version)
{
struct function *inner_function = DECL_STRUCT_FUNCTION (e->caller->decl);
gimple_call_set_fndecl (e->call_stmt, new_version->decl);
- /* Update EH information too, just in case. */
- if (!stmt_could_throw_p (e->call_stmt)
- && lookup_stmt_eh_region_fn (inner_function, e->call_stmt))
- remove_stmt_from_eh_region_fn (inner_function, e->call_stmt);
+ maybe_clean_eh_stmt_fn (inner_function, e->call_stmt);
}
}
@@ -2098,9 +2106,7 @@ cgraph_materialize_all_clones (void)
gsi_replace (&gsi, new_stmt, true);
/* Update EH information too, just in case. */
- if (!stmt_could_throw_p (new_stmt)
- && lookup_stmt_eh_region (new_stmt))
- remove_stmt_from_eh_region (new_stmt);
+ maybe_clean_or_replace_eh_stmt (e->call_stmt, new_stmt);
cgraph_set_call_stmt_including_clones (orig_node, e->call_stmt, new_stmt);
diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c
index 1f1759e1049..8849697bfce 100644
--- a/gcc/combine-stack-adj.c
+++ b/gcc/combine-stack-adj.c
@@ -71,25 +71,26 @@ along with GCC; see the file COPYING3. If not see
#define STACK_GROWS_DOWNWARD 0
#endif
-/* This structure records stack memory references between stack adjusting
- instructions. */
+/* This structure records two kinds of stack references between stack
+ adjusting instructions: stack references in memory addresses for
+ regular insns and all stack references for debug insns. */
-struct csa_memlist
+struct csa_reflist
{
HOST_WIDE_INT sp_offset;
- rtx insn, *mem;
- struct csa_memlist *next;
+ rtx insn, *ref;
+ struct csa_reflist *next;
};
static int stack_memref_p (rtx);
static rtx single_set_for_csa (rtx);
-static void free_csa_memlist (struct csa_memlist *);
-static struct csa_memlist *record_one_stack_memref (rtx, rtx *,
- struct csa_memlist *);
-static int try_apply_stack_adjustment (rtx, struct csa_memlist *,
+static void free_csa_reflist (struct csa_reflist *);
+static struct csa_reflist *record_one_stack_ref (rtx, rtx *,
+ struct csa_reflist *);
+static int try_apply_stack_adjustment (rtx, struct csa_reflist *,
HOST_WIDE_INT, HOST_WIDE_INT);
static void combine_stack_adjustments_for_block (basic_block);
-static int record_stack_memrefs (rtx *, void *);
+static int record_stack_refs (rtx *, void *);
/* Main entry point for stack adjustment combination. */
@@ -157,65 +158,80 @@ single_set_for_csa (rtx insn)
return XVECEXP (tmp, 0, 0);
}
-/* Free the list of csa_memlist nodes. */
+/* Free the list of csa_reflist nodes. */
static void
-free_csa_memlist (struct csa_memlist *memlist)
+free_csa_reflist (struct csa_reflist *reflist)
{
- struct csa_memlist *next;
- for (; memlist ; memlist = next)
+ struct csa_reflist *next;
+ for (; reflist ; reflist = next)
{
- next = memlist->next;
- free (memlist);
+ next = reflist->next;
+ free (reflist);
}
}
-/* Create a new csa_memlist node from the given memory reference.
- It is already known that the memory is stack_memref_p. */
+/* Create a new csa_reflist node from the given stack reference.
+ It is already known that the reference is either a MEM satisfying the
+ predicate stack_memref_p or a REG representing the stack pointer. */
-static struct csa_memlist *
-record_one_stack_memref (rtx insn, rtx *mem, struct csa_memlist *next_memlist)
+static struct csa_reflist *
+record_one_stack_ref (rtx insn, rtx *ref, struct csa_reflist *next_reflist)
{
- struct csa_memlist *ml;
+ struct csa_reflist *ml;
- ml = XNEW (struct csa_memlist);
+ ml = XNEW (struct csa_reflist);
- if (XEXP (*mem, 0) == stack_pointer_rtx)
+ if (REG_P (*ref) || XEXP (*ref, 0) == stack_pointer_rtx)
ml->sp_offset = 0;
else
- ml->sp_offset = INTVAL (XEXP (XEXP (*mem, 0), 1));
+ ml->sp_offset = INTVAL (XEXP (XEXP (*ref, 0), 1));
ml->insn = insn;
- ml->mem = mem;
- ml->next = next_memlist;
+ ml->ref = ref;
+ ml->next = next_reflist;
return ml;
}
/* Attempt to apply ADJUST to the stack adjusting insn INSN, as well
- as each of the memories in MEMLIST. Return true on success. */
+ as each of the memories and stack references in REFLIST. Return true
+ on success. */
static int
-try_apply_stack_adjustment (rtx insn, struct csa_memlist *memlist, HOST_WIDE_INT new_adjust,
- HOST_WIDE_INT delta)
+try_apply_stack_adjustment (rtx insn, struct csa_reflist *reflist,
+ HOST_WIDE_INT new_adjust, HOST_WIDE_INT delta)
{
- struct csa_memlist *ml;
+ struct csa_reflist *ml;
rtx set;
set = single_set_for_csa (insn);
- validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (new_adjust), 1);
+ if (MEM_P (SET_DEST (set)))
+ validate_change (insn, &SET_DEST (set),
+ replace_equiv_address (SET_DEST (set), stack_pointer_rtx),
+ 1);
+ else
+ validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (new_adjust), 1);
+
+ for (ml = reflist; ml ; ml = ml->next)
+ {
+ rtx new_addr = plus_constant (stack_pointer_rtx, ml->sp_offset - delta);
+ rtx new_val;
- for (ml = memlist; ml ; ml = ml->next)
- validate_change
- (ml->insn, ml->mem,
- replace_equiv_address_nv (*ml->mem,
- plus_constant (stack_pointer_rtx,
- ml->sp_offset - delta)), 1);
+ if (MEM_P (*ml->ref))
+ new_val = replace_equiv_address_nv (*ml->ref, new_addr);
+ else if (GET_MODE (*ml->ref) == GET_MODE (stack_pointer_rtx))
+ new_val = new_addr;
+ else
+ new_val = lowpart_subreg (GET_MODE (*ml->ref), new_addr,
+ GET_MODE (new_addr));
+ validate_change (ml->insn, ml->ref, new_val, 1);
+ }
if (apply_change_group ())
{
- /* Succeeded. Update our knowledge of the memory references. */
- for (ml = memlist; ml ; ml = ml->next)
+ /* Succeeded. Update our knowledge of the stack references. */
+ for (ml = reflist; ml ; ml = ml->next)
ml->sp_offset -= delta;
return 1;
@@ -224,20 +240,20 @@ try_apply_stack_adjustment (rtx insn, struct csa_memlist *memlist, HOST_WIDE_INT
return 0;
}
-/* Called via for_each_rtx and used to record all stack memory references in
- the insn and discard all other stack pointer references. */
-struct record_stack_memrefs_data
+/* Called via for_each_rtx and used to record all stack memory and other
+ references in the insn and discard all other stack pointer references. */
+struct record_stack_refs_data
{
rtx insn;
- struct csa_memlist *memlist;
+ struct csa_reflist *reflist;
};
static int
-record_stack_memrefs (rtx *xp, void *data)
+record_stack_refs (rtx *xp, void *data)
{
rtx x = *xp;
- struct record_stack_memrefs_data *d =
- (struct record_stack_memrefs_data *) data;
+ struct record_stack_refs_data *d =
+ (struct record_stack_refs_data *) data;
if (!x)
return 0;
switch (GET_CODE (x))
@@ -249,10 +265,11 @@ record_stack_memrefs (rtx *xp, void *data)
stack pointer, so this check is necessary. */
if (stack_memref_p (x))
{
- d->memlist = record_one_stack_memref (d->insn, xp, d->memlist);
+ d->reflist = record_one_stack_ref (d->insn, xp, d->reflist);
return -1;
}
- return 1;
+ /* Try harder for DEBUG_INSNs, handle e.g. (mem (mem (sp + 16) + 4). */
+ return !DEBUG_INSN_P (d->insn);
case REG:
/* ??? We want be able to handle non-memory stack pointer
references later. For now just discard all insns referring to
@@ -262,9 +279,17 @@ record_stack_memrefs (rtx *xp, void *data)
We can't just compare with STACK_POINTER_RTX because the
reference to the stack pointer might be in some other mode.
In particular, an explicit clobber in an asm statement will
- result in a QImode clobber. */
+ result in a QImode clobber.
+
+ In DEBUG_INSNs, we want to replace all occurrences, otherwise
+ they will cause -fcompare-debug failures. */
if (REGNO (x) == STACK_POINTER_REGNUM)
- return 1;
+ {
+ if (!DEBUG_INSN_P (d->insn))
+ return 1;
+ d->reflist = record_one_stack_ref (d->insn, xp, d->reflist);
+ return -1;
+ }
break;
default:
break;
@@ -343,9 +368,9 @@ combine_stack_adjustments_for_block (basic_block bb)
{
HOST_WIDE_INT last_sp_adjust = 0;
rtx last_sp_set = NULL_RTX;
- struct csa_memlist *memlist = NULL;
+ struct csa_reflist *reflist = NULL;
rtx insn, next, set;
- struct record_stack_memrefs_data data;
+ struct record_stack_refs_data data;
bool end_of_block = false;
for (insn = BB_HEAD (bb); !end_of_block ; insn = next)
@@ -379,7 +404,7 @@ combine_stack_adjustments_for_block (basic_block bb)
continue;
}
- /* If not all recorded memrefs can be adjusted, or the
+ /* If not all recorded refs can be adjusted, or the
adjustment is now too large for a constant addition,
we cannot merge the two stack adjustments.
@@ -403,7 +428,7 @@ combine_stack_adjustments_for_block (basic_block bb)
/* Combine an allocation into the first instruction. */
if (STACK_GROWS_DOWNWARD ? this_adjust <= 0 : this_adjust >= 0)
{
- if (try_apply_stack_adjustment (last_sp_set, memlist,
+ if (try_apply_stack_adjustment (last_sp_set, reflist,
last_sp_adjust + this_adjust,
this_adjust))
{
@@ -422,7 +447,7 @@ combine_stack_adjustments_for_block (basic_block bb)
else if (STACK_GROWS_DOWNWARD
? last_sp_adjust >= 0 : last_sp_adjust <= 0)
{
- if (try_apply_stack_adjustment (insn, memlist,
+ if (try_apply_stack_adjustment (insn, reflist,
last_sp_adjust + this_adjust,
-last_sp_adjust))
{
@@ -430,8 +455,8 @@ combine_stack_adjustments_for_block (basic_block bb)
delete_insn (last_sp_set);
last_sp_set = insn;
last_sp_adjust += this_adjust;
- free_csa_memlist (memlist);
- memlist = NULL;
+ free_csa_reflist (reflist);
+ reflist = NULL;
continue;
}
}
@@ -441,39 +466,44 @@ combine_stack_adjustments_for_block (basic_block bb)
delete the old deallocation insn. */
if (last_sp_set && last_sp_adjust == 0)
delete_insn (last_sp_set);
- free_csa_memlist (memlist);
- memlist = NULL;
+ free_csa_reflist (reflist);
+ reflist = NULL;
last_sp_set = insn;
last_sp_adjust = this_adjust;
continue;
}
- /* Find a predecrement of exactly the previous adjustment and
- turn it into a direct store. Obviously we can't do this if
- there were any intervening uses of the stack pointer. */
- if (memlist == NULL
- && MEM_P (dest)
- && ((GET_CODE (XEXP (dest, 0)) == PRE_DEC
- && (last_sp_adjust
- == (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (dest))))
- || (GET_CODE (XEXP (dest, 0)) == PRE_MODIFY
+ /* Find a store with pre-(dec|inc)rement or pre-modify of exactly
+ the previous adjustment and turn it into a simple store. This
+ is equivalent to anticipating the stack adjustment so this must
+ be an allocation. */
+ if (MEM_P (dest)
+ && ((STACK_GROWS_DOWNWARD
+ ? (GET_CODE (XEXP (dest, 0)) == PRE_DEC
+ && last_sp_adjust
+ == (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (dest)))
+ : (GET_CODE (XEXP (dest, 0)) == PRE_INC
+ && last_sp_adjust
+ == -(HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (dest))))
+ || ((STACK_GROWS_DOWNWARD
+ ? last_sp_adjust >= 0 : last_sp_adjust <= 0)
+ && GET_CODE (XEXP (dest, 0)) == PRE_MODIFY
&& GET_CODE (XEXP (XEXP (dest, 0), 1)) == PLUS
- && XEXP (XEXP (XEXP (dest, 0), 1), 0) == stack_pointer_rtx
- && (GET_CODE (XEXP (XEXP (XEXP (dest, 0), 1), 1))
- == CONST_INT)
- && (INTVAL (XEXP (XEXP (XEXP (dest, 0), 1), 1))
- == -last_sp_adjust)))
+ && XEXP (XEXP (XEXP (dest, 0), 1), 0)
+ == stack_pointer_rtx
+ && GET_CODE (XEXP (XEXP (XEXP (dest, 0), 1), 1))
+ == CONST_INT
+ && INTVAL (XEXP (XEXP (XEXP (dest, 0), 1), 1))
+ == -last_sp_adjust))
&& XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx
- && ! reg_mentioned_p (stack_pointer_rtx, src)
+ && !reg_mentioned_p (stack_pointer_rtx, src)
&& memory_address_p (GET_MODE (dest), stack_pointer_rtx)
- && validate_change (insn, &SET_DEST (set),
- replace_equiv_address (dest,
- stack_pointer_rtx),
- 0))
+ && try_apply_stack_adjustment (insn, reflist, 0,
+ -last_sp_adjust))
{
delete_insn (last_sp_set);
- free_csa_memlist (memlist);
- memlist = NULL;
+ free_csa_reflist (reflist);
+ reflist = NULL;
last_sp_set = NULL_RTX;
last_sp_adjust = 0;
continue;
@@ -481,14 +511,14 @@ combine_stack_adjustments_for_block (basic_block bb)
}
data.insn = insn;
- data.memlist = memlist;
+ data.reflist = reflist;
if (!CALL_P (insn) && last_sp_set
- && !for_each_rtx (&PATTERN (insn), record_stack_memrefs, &data))
+ && !for_each_rtx (&PATTERN (insn), record_stack_refs, &data))
{
- memlist = data.memlist;
+ reflist = data.reflist;
continue;
}
- memlist = data.memlist;
+ reflist = data.reflist;
/* Otherwise, we were not able to process the instruction.
Do not continue collecting data across such a one. */
@@ -498,8 +528,8 @@ combine_stack_adjustments_for_block (basic_block bb)
{
if (last_sp_set && last_sp_adjust == 0)
delete_insn (last_sp_set);
- free_csa_memlist (memlist);
- memlist = NULL;
+ free_csa_reflist (reflist);
+ reflist = NULL;
last_sp_set = NULL_RTX;
last_sp_adjust = 0;
}
@@ -508,8 +538,8 @@ combine_stack_adjustments_for_block (basic_block bb)
if (last_sp_set && last_sp_adjust == 0)
delete_insn (last_sp_set);
- if (memlist)
- free_csa_memlist (memlist);
+ if (reflist)
+ free_csa_reflist (reflist);
}
diff --git a/gcc/combine.c b/gcc/combine.c
index bc61fbedcf4..6b507c2991d 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1562,7 +1562,6 @@ can_combine_p (rtx insn, rtx i3, rtx pred ATTRIBUTE_UNUSED, rtx succ,
for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
{
rtx elt = XVECEXP (PATTERN (insn), 0, i);
- rtx note;
switch (GET_CODE (elt))
{
@@ -1613,9 +1612,8 @@ can_combine_p (rtx insn, rtx i3, rtx pred ATTRIBUTE_UNUSED, rtx succ,
/* Ignore SETs whose result isn't used but not those that
have side-effects. */
if (find_reg_note (insn, REG_UNUSED, SET_DEST (elt))
- && (!(note = find_reg_note (insn, REG_EH_REGION, NULL_RTX))
- || INTVAL (XEXP (note, 0)) <= 0)
- && ! side_effects_p (elt))
+ && insn_nothrow_p (insn)
+ && !side_effects_p (elt))
break;
/* If we have already found a SET, this is a second one and
@@ -2314,7 +2312,7 @@ propagate_for_debug_subst (rtx *loc, void *data)
to = simplify_gen_subreg (GET_MODE (x), to,
GET_MODE (from), SUBREG_BYTE (x));
}
- *loc = to;
+ *loc = wrap_constant (GET_MODE (x), to);
pair->changed = true;
return -1;
}
@@ -3108,15 +3106,13 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
{
rtx set0 = XVECEXP (newpat, 0, 0);
rtx set1 = XVECEXP (newpat, 0, 1);
- rtx note;
if (((REG_P (SET_DEST (set1))
&& find_reg_note (i3, REG_UNUSED, SET_DEST (set1)))
|| (GET_CODE (SET_DEST (set1)) == SUBREG
&& find_reg_note (i3, REG_UNUSED, SUBREG_REG (SET_DEST (set1)))))
- && (!(note = find_reg_note (i3, REG_EH_REGION, NULL_RTX))
- || INTVAL (XEXP (note, 0)) <= 0)
- && ! side_effects_p (SET_SRC (set1)))
+ && insn_nothrow_p (i3)
+ && !side_effects_p (SET_SRC (set1)))
{
newpat = set0;
insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
@@ -3127,9 +3123,8 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
|| (GET_CODE (SET_DEST (set0)) == SUBREG
&& find_reg_note (i3, REG_UNUSED,
SUBREG_REG (SET_DEST (set0)))))
- && (!(note = find_reg_note (i3, REG_EH_REGION, NULL_RTX))
- || INTVAL (XEXP (note, 0)) <= 0)
- && ! side_effects_p (SET_SRC (set0)))
+ && insn_nothrow_p (i3)
+ && !side_effects_p (SET_SRC (set0)))
{
newpat = set1;
insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
diff --git a/gcc/common.opt b/gcc/common.opt
index eaa7d03c553..91ef83c3188 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -502,6 +502,10 @@ feliminate-dwarf2-dups
Common Report Var(flag_eliminate_dwarf2_dups)
Perform DWARF2 duplicate elimination
+fipa-sra
+Common Report Var(flag_ipa_sra) Init(0) Optimization
+Perform interprocedural reduction of aggregates
+
feliminate-unused-debug-symbols
Common Report Var(flag_debug_only_used_symbols)
Perform unused type elimination in debug info
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 52a979af60a..00025638ceb 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -373,12 +373,6 @@ then
fi
case ${target} in
-i[34567]86-w64-*)
- tm_file="i386/biarch32.h ${tm_file}"
- ;;
-esac
-
-case ${target} in
i[34567]86-*-*)
if test "x$enable_cld" = xyes; then
tm_defines="${tm_defines} USE_IX86_CLD=1"
@@ -478,6 +472,13 @@ case ${target} in
;;
esac
fbsd_tm_file="${fbsd_tm_file} freebsd-spec.h freebsd.h freebsd-stdint.h"
+ case ${target} in
+ *-*-freebsd[345].*)
+ :;;
+ *)
+ default_use_cxa_atexit=yes;;
+ esac
+ # need_64bit_hwint=yes # system compiler has this for all arch!
use_gcc_stdint=wrap
;;
*-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu)
@@ -1312,11 +1313,35 @@ i[34567]86-*-pe | i[34567]86-*-cygwin*)
i[34567]86-*-mingw* | x86_64-*-mingw*)
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/mingw32.h"
xm_file=i386/xm-mingw32.h
+ case ${target} in
+ x86_64-*-* | *-w64-*)
+ need_64bit_hwint=yes
+ ;;
+ *)
+ ;;
+ esac
# This makes the logic if mingw's or the w64 feature set has to be used
case ${target} in
*-w64-*)
tm_file="${tm_file} i386/mingw-w64.h"
tmake_file="${tmake_file} i386/t-mingw-w64"
+ if test x$enable_targets = xall; then
+ tm_defines="${tm_defines} TARGET_BI_ARCH=1"
+ case X"${with_cpu}" in
+ Xgeneric|Xatom|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
+ ;;
+ X)
+ if test x$with_cpu_64 = x; then
+ with_cpu_64=generic
+ fi
+ ;;
+ *)
+ echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
+ echo "generic atom core2 nocona x86-64 amdfam10 barcelona k8 opteron athlon64 athlon-fx" 1>&2
+ exit 1
+ ;;
+ esac
+ fi
;;
*)
tmake_file="${tmake_file} i386/t-mingw32"
@@ -1927,7 +1952,7 @@ powerpc-*-linux* | powerpc64-*-linux*)
tm_file="${tm_file} rs6000/linux.h glibc-stdint.h"
;;
esac
- tmake_file="${tmake_file} rs6000/t-fprules-softfp soft-fp/t-softfp"
+ tmake_file="${tmake_file} t-slibgcc-libgcc rs6000/t-fprules-softfp soft-fp/t-softfp"
case ${target} in
powerpc*-*-linux*altivec*)
tm_file="${tm_file} rs6000/linuxaltivec.h" ;;
@@ -1943,19 +1968,19 @@ powerpc-*-linux* | powerpc64-*-linux*)
powerpc64-*-gnu*)
tm_file="${tm_file} elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/default64.h rs6000/linux64.h rs6000/gnu.h glibc-stdint.h"
extra_options="${extra_options} rs6000/sysv4.opt rs6000/linux64.opt"
- tmake_file="t-slibgcc-elf-ver t-gnu"
+ tmake_file="t-slibgcc-elf-ver t-slibgcc-libgcc t-gnu"
;;
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 glibc-stdint.h"
extra_options="${extra_options} rs6000/sysv4.opt"
- tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcos t-slibgcc-elf-ver t-slibgcc-libgcc t-gnu rs6000/t-ppccomm"
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
powerpc-*-gnu*)
tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux.h rs6000/gnu.h glibc-stdint.h"
- tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcos t-slibgcc-elf-ver t-slibgcc-libgcc t-gnu rs6000/t-ppccomm"
extra_options="${extra_options} rs6000/sysv4.opt"
if test x$enable_threads = xyes; then
thread_file='posix'
diff --git a/gcc/config.host b/gcc/config.host
index a8ec32455aa..4affcb06b17 100644
--- a/gcc/config.host
+++ b/gcc/config.host
@@ -207,7 +207,14 @@ case ${host} in
host_xmake_file="${host_xmake_file} i386/x-cygwin"
host_exeext=.exe
;;
- i[34567]86-*-mingw32* | x86_64-*-mingw*)
+ i[34567]86-*-mingw32*)
+ host_xm_file=i386/xm-mingw32.h
+ host_xmake_file="${host_xmake_file} i386/x-mingw32"
+ host_exeext=.exe
+ out_host_hook_obj=host-mingw32.o
+ ;;
+ x86_64-*-mingw*)
+ use_long_long_for_widest_fast_int=yes
host_xm_file=i386/xm-mingw32.h
host_xmake_file="${host_xmake_file} i386/x-mingw32"
host_exeext=.exe
diff --git a/gcc/config.in b/gcc/config.in
index 050c0578521..40d7e4d24b6 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -1026,6 +1026,18 @@
#endif
+/* Define to 1 if the system has the type `intmax_t'. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_INTMAX_T
+#endif
+
+
+/* Define to 1 if the system has the type `intptr_t'. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_INTPTR_T
+#endif
+
+
/* Define if you have a working <inttypes.h> header file. */
#ifndef USED_FOR_TARGET
#undef HAVE_INTTYPES_H
@@ -1139,6 +1151,12 @@
#endif
+/* Define to 1 if the system has the type `long long int'. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_LONG_LONG_INT
+#endif
+
+
/* Define to 1 if you have the <malloc.h> header file. */
#ifndef USED_FOR_TARGET
#undef HAVE_MALLOC_H
@@ -1337,12 +1355,30 @@
#endif
+/* Define to 1 if the system has the type `uintmax_t'. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_UINTMAX_T
+#endif
+
+
+/* Define to 1 if the system has the type `uintptr_t'. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_UINTPTR_T
+#endif
+
+
/* Define to 1 if you have the <unistd.h> header file. */
#ifndef USED_FOR_TARGET
#undef HAVE_UNISTD_H
#endif
+/* Define to 1 if the system has the type `unsigned long long int'. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_UNSIGNED_LONG_LONG_INT
+#endif
+
+
/* Define if valgrind's valgrind/memcheck.h header is installed. */
#ifndef USED_FOR_TARGET
#undef HAVE_VALGRIND_MEMCHECK_H
@@ -1624,6 +1660,30 @@
#endif
+/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#ifndef USED_FOR_TARGET
+#undef _UINT32_T
+#endif
+
+
+/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#ifndef USED_FOR_TARGET
+#undef _UINT64_T
+#endif
+
+
+/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#ifndef USED_FOR_TARGET
+#undef _UINT8_T
+#endif
+
+
/* Define to `char *' if <sys/types.h> does not define. */
#ifndef USED_FOR_TARGET
#undef caddr_t
@@ -1636,6 +1696,48 @@
#undef inline
#endif
+/* Define to the type of a signed integer type of width exactly 16 bits if
+ such a type exists and the standard includes do not define it. */
+#ifndef USED_FOR_TARGET
+#undef int16_t
+#endif
+
+
+/* Define to the type of a signed integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+#ifndef USED_FOR_TARGET
+#undef int32_t
+#endif
+
+
+/* Define to the type of a signed integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+#ifndef USED_FOR_TARGET
+#undef int64_t
+#endif
+
+
+/* Define to the type of a signed integer type of width exactly 8 bits if such
+ a type exists and the standard includes do not define it. */
+#ifndef USED_FOR_TARGET
+#undef int8_t
+#endif
+
+
+/* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
+ not define. */
+#ifndef USED_FOR_TARGET
+#undef intmax_t
+#endif
+
+
+/* Define to the type of a signed integer type wide enough to hold a pointer,
+ if such a type exists, and if the system does not define it. */
+#ifndef USED_FOR_TARGET
+#undef intptr_t
+#endif
+
+
/* Define to `int' if <sys/types.h> does not define. */
#ifndef USED_FOR_TARGET
#undef pid_t
@@ -1654,6 +1756,48 @@
#endif
+/* Define to the type of an unsigned integer type of width exactly 16 bits if
+ such a type exists and the standard includes do not define it. */
+#ifndef USED_FOR_TARGET
+#undef uint16_t
+#endif
+
+
+/* Define to the type of an unsigned integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+#ifndef USED_FOR_TARGET
+#undef uint32_t
+#endif
+
+
+/* Define to the type of an unsigned integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+#ifndef USED_FOR_TARGET
+#undef uint64_t
+#endif
+
+
+/* Define to the type of an unsigned integer type of width exactly 8 bits if
+ such a type exists and the standard includes do not define it. */
+#ifndef USED_FOR_TARGET
+#undef uint8_t
+#endif
+
+
+/* Define to the widest unsigned integer type if <stdint.h> and <inttypes.h>
+ do not define. */
+#ifndef USED_FOR_TARGET
+#undef uintmax_t
+#endif
+
+
+/* Define to the type of an unsigned integer type wide enough to hold a
+ pointer, if such a type exists, and if the system does not define it. */
+#ifndef USED_FOR_TARGET
+#undef uintptr_t
+#endif
+
+
/* Define as `fork' if `vfork' does not work. */
#ifndef USED_FOR_TARGET
#undef vfork
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 1c15e53f996..46ad8f4be2d 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -7664,7 +7664,7 @@ alpha_does_function_need_gp (void)
pop_topmost_sequence ();
for (; insn; insn = NEXT_INSN (insn))
- if (INSN_P (insn)
+ if (NONDEBUG_INSN_P (insn)
&& ! JUMP_TABLE_DATA_P (insn)
&& GET_CODE (PATTERN (insn)) != USE
&& GET_CODE (PATTERN (insn)) != CLOBBER
@@ -8663,8 +8663,6 @@ alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
HOST_WIDE_INT hi, lo;
rtx this_rtx, insn, funexp;
- insn_locators_alloc ();
-
/* We always require a valid GP. */
emit_insn (gen_prologue_ldgp ());
emit_note (NOTE_INSN_PROLOGUE_END);
@@ -8741,6 +8739,7 @@ alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
instruction scheduling worth while. Note that use_thunk calls
assemble_start_function and assemble_end_function. */
insn = get_insns ();
+ insn_locators_alloc ();
shorten_branches (insn);
final_start_function (insn, file, 1);
final (insn, file, 1);
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index aeba71e6c2a..ca9032750f3 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -3863,7 +3863,7 @@
(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (eq (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
- "TARGET_FP"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
{
operands[3] = gen_reg_rtx (DFmode);
operands[4] = CONST0_RTX (DFmode);
@@ -3876,7 +3876,7 @@
(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (ne (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
- "TARGET_FP"
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
{
operands[3] = gen_reg_rtx (DFmode);
operands[4] = CONST0_RTX (DFmode);
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index ae32da563e1..215c9fba789 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -2368,6 +2368,7 @@ extern int making_const_table;
/* The arm5 clz instruction returns 32. */
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
+#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
#undef ASM_APP_OFF
#define ASM_APP_OFF (TARGET_THUMB1 ? "\t.code\t16\n" : \
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 09a1b0841e9..e180c2f08f1 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -100,6 +100,7 @@
(UNSPEC_GOTSYM_OFF 24) ; The offset of the start of the the GOT from a
; a given symbolic address.
(UNSPEC_THUMB1_CASESI 25) ; A Thumb1 compressed dispatch-table call.
+ (UNSPEC_RBIT 26) ; rbit operation.
]
)
@@ -10955,6 +10956,28 @@
[(set_attr "predicable" "yes")
(set_attr "insn" "clz")])
+(define_insn "rbitsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
+ "TARGET_32BIT && arm_arch_thumb2"
+ "rbit%?\\t%0, %1"
+ [(set_attr "predicable" "yes")
+ (set_attr "insn" "clz")])
+
+(define_expand "ctzsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
+ "TARGET_32BIT && arm_arch_thumb2"
+ "
+ {
+ rtx tmp = gen_reg_rtx (SImode);
+ emit_insn (gen_rbitsi2 (tmp, operands[1]));
+ emit_insn (gen_clzsi2 (operands[0], tmp));
+ }
+ DONE;
+ "
+)
+
;; V5E instructions.
(define_insn "prefetch"
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index 298a140f071..77c99d241ef 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -960,7 +960,7 @@
(compare:CCFP (match_dup 0)
(match_dup 1)))
(set (reg:CCFP CC_REGNUM)
- (reg:CCFPE VFPCC_REGNUM))]
+ (reg:CCFP VFPCC_REGNUM))]
""
)
diff --git a/gcc/config/bfin/bfin-protos.h b/gcc/config/bfin/bfin-protos.h
index 72698a2b0a1..b2d3d8c2dbd 100644
--- a/gcc/config/bfin/bfin-protos.h
+++ b/gcc/config/bfin/bfin-protos.h
@@ -22,44 +22,6 @@
#ifndef GCC_BFIN_PROTOS_H
#define GCC_BFIN_PROTOS_H
-/* CPU type. */
-typedef enum bfin_cpu_type
-{
- BFIN_CPU_UNKNOWN,
- BFIN_CPU_BF512,
- BFIN_CPU_BF514,
- BFIN_CPU_BF516,
- BFIN_CPU_BF518,
- BFIN_CPU_BF522,
- BFIN_CPU_BF523,
- BFIN_CPU_BF524,
- BFIN_CPU_BF525,
- BFIN_CPU_BF526,
- BFIN_CPU_BF527,
- BFIN_CPU_BF531,
- BFIN_CPU_BF532,
- BFIN_CPU_BF533,
- BFIN_CPU_BF534,
- BFIN_CPU_BF536,
- BFIN_CPU_BF537,
- BFIN_CPU_BF538,
- BFIN_CPU_BF539,
- BFIN_CPU_BF542,
- BFIN_CPU_BF544,
- BFIN_CPU_BF547,
- BFIN_CPU_BF548,
- BFIN_CPU_BF549,
- BFIN_CPU_BF561
-} bfin_cpu_t;
-
-/* Value of -mcpu= */
-extern bfin_cpu_t bfin_cpu_type;
-
-/* Value of -msi-revision= */
-extern int bfin_si_revision;
-
-extern unsigned int bfin_workarounds;
-
/* For the anomaly 05-00-0245 */
#define WA_SPECULATIVE_LOADS 0x00000001
#define ENABLE_WA_SPECULATIVE_LOADS \
@@ -97,6 +59,10 @@ extern unsigned int bfin_workarounds;
#define ENABLE_WA_LOAD_LCREGS \
(bfin_workarounds & WA_LOAD_LCREGS)
+#define WA_05000074 0x00000100
+#define ENABLE_WA_05000074 \
+ (bfin_workarounds & WA_05000074)
+
#define Mmode enum machine_mode
extern rtx function_arg (CUMULATIVE_ARGS *, Mmode, tree, int);
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index ebcd825043e..92aaf5770c4 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -117,184 +117,223 @@ struct bfin_cpu
struct bfin_cpu bfin_cpus[] =
{
{"bf512", BFIN_CPU_BF512, 0x0000,
- WA_SPECULATIVE_LOADS},
+ WA_SPECULATIVE_LOADS | WA_05000074},
{"bf514", BFIN_CPU_BF514, 0x0000,
- WA_SPECULATIVE_LOADS},
+ WA_SPECULATIVE_LOADS | WA_05000074},
{"bf516", BFIN_CPU_BF516, 0x0000,
- WA_SPECULATIVE_LOADS},
+ WA_SPECULATIVE_LOADS | WA_05000074},
{"bf518", BFIN_CPU_BF518, 0x0000,
- WA_SPECULATIVE_LOADS},
+ WA_SPECULATIVE_LOADS | WA_05000074},
{"bf522", BFIN_CPU_BF522, 0x0002,
- WA_SPECULATIVE_LOADS},
+ WA_SPECULATIVE_LOADS | WA_05000074},
{"bf522", BFIN_CPU_BF522, 0x0001,
- WA_SPECULATIVE_LOADS | WA_RETS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
{"bf522", BFIN_CPU_BF522, 0x0000,
- WA_SPECULATIVE_LOADS | WA_RETS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
{"bf523", BFIN_CPU_BF523, 0x0002,
- WA_SPECULATIVE_LOADS},
+ WA_SPECULATIVE_LOADS | WA_05000074},
{"bf523", BFIN_CPU_BF523, 0x0001,
- WA_SPECULATIVE_LOADS | WA_RETS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
{"bf523", BFIN_CPU_BF523, 0x0000,
- WA_SPECULATIVE_LOADS | WA_RETS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
{"bf524", BFIN_CPU_BF524, 0x0002,
- WA_SPECULATIVE_LOADS},
+ WA_SPECULATIVE_LOADS | WA_05000074},
{"bf524", BFIN_CPU_BF524, 0x0001,
- WA_SPECULATIVE_LOADS | WA_RETS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
{"bf524", BFIN_CPU_BF524, 0x0000,
- WA_SPECULATIVE_LOADS | WA_RETS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
{"bf525", BFIN_CPU_BF525, 0x0002,
- WA_SPECULATIVE_LOADS},
+ WA_SPECULATIVE_LOADS | WA_05000074},
{"bf525", BFIN_CPU_BF525, 0x0001,
- WA_SPECULATIVE_LOADS | WA_RETS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
{"bf525", BFIN_CPU_BF525, 0x0000,
- WA_SPECULATIVE_LOADS | WA_RETS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
{"bf526", BFIN_CPU_BF526, 0x0002,
- WA_SPECULATIVE_LOADS},
+ WA_SPECULATIVE_LOADS | WA_05000074},
{"bf526", BFIN_CPU_BF526, 0x0001,
- WA_SPECULATIVE_LOADS | WA_RETS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
{"bf526", BFIN_CPU_BF526, 0x0000,
- WA_SPECULATIVE_LOADS | WA_RETS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
{"bf527", BFIN_CPU_BF527, 0x0002,
- WA_SPECULATIVE_LOADS},
+ WA_SPECULATIVE_LOADS | WA_05000074},
{"bf527", BFIN_CPU_BF527, 0x0001,
- WA_SPECULATIVE_LOADS | WA_RETS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
{"bf527", BFIN_CPU_BF527, 0x0000,
- WA_SPECULATIVE_LOADS | WA_RETS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
{"bf531", BFIN_CPU_BF531, 0x0006,
- WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
{"bf531", BFIN_CPU_BF531, 0x0005,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315
+ | WA_LOAD_LCREGS | WA_05000074},
{"bf531", BFIN_CPU_BF531, 0x0004,
WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf531", BFIN_CPU_BF531, 0x0003,
WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf532", BFIN_CPU_BF532, 0x0006,
- WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
{"bf532", BFIN_CPU_BF532, 0x0005,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315
+ | WA_LOAD_LCREGS | WA_05000074},
{"bf532", BFIN_CPU_BF532, 0x0004,
WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf532", BFIN_CPU_BF532, 0x0003,
WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf533", BFIN_CPU_BF533, 0x0006,
- WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
{"bf533", BFIN_CPU_BF533, 0x0005,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315
+ | WA_LOAD_LCREGS | WA_05000074},
{"bf533", BFIN_CPU_BF533, 0x0004,
WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf533", BFIN_CPU_BF533, 0x0003,
WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf534", BFIN_CPU_BF534, 0x0003,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
{"bf534", BFIN_CPU_BF534, 0x0002,
WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf534", BFIN_CPU_BF534, 0x0001,
WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf536", BFIN_CPU_BF536, 0x0003,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
{"bf536", BFIN_CPU_BF536, 0x0002,
WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf536", BFIN_CPU_BF536, 0x0001,
WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf537", BFIN_CPU_BF537, 0x0003,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
{"bf537", BFIN_CPU_BF537, 0x0002,
WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf537", BFIN_CPU_BF537, 0x0001,
WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf538", BFIN_CPU_BF538, 0x0005,
- WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
{"bf538", BFIN_CPU_BF538, 0x0004,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
{"bf538", BFIN_CPU_BF538, 0x0003,
WA_SPECULATIVE_LOADS | WA_RETS
- | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074},
{"bf538", BFIN_CPU_BF538, 0x0002,
WA_SPECULATIVE_LOADS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf539", BFIN_CPU_BF539, 0x0005,
- WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
{"bf539", BFIN_CPU_BF539, 0x0004,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
{"bf539", BFIN_CPU_BF539, 0x0003,
WA_SPECULATIVE_LOADS | WA_RETS
- | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074},
{"bf539", BFIN_CPU_BF539, 0x0002,
WA_SPECULATIVE_LOADS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
+
+ {"bf542m", BFIN_CPU_BF542M, 0x0003,
+ WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
{"bf542", BFIN_CPU_BF542, 0x0002,
- WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS},
+ WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
{"bf542", BFIN_CPU_BF542, 0x0001,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
{"bf542", BFIN_CPU_BF542, 0x0000,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
+ | WA_05000074},
+
+ {"bf544m", BFIN_CPU_BF544M, 0x0003,
+ WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
{"bf544", BFIN_CPU_BF544, 0x0002,
- WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS},
+ WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
{"bf544", BFIN_CPU_BF544, 0x0001,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
{"bf544", BFIN_CPU_BF544, 0x0000,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
+ | WA_05000074},
+
+ {"bf547m", BFIN_CPU_BF547M, 0x0003,
+ WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
{"bf547", BFIN_CPU_BF547, 0x0002,
- WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS},
+ WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
{"bf547", BFIN_CPU_BF547, 0x0001,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
{"bf547", BFIN_CPU_BF547, 0x0000,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
+ | WA_05000074},
+
+ {"bf548m", BFIN_CPU_BF548M, 0x0003,
+ WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
{"bf548", BFIN_CPU_BF548, 0x0002,
- WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS},
+ WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
{"bf548", BFIN_CPU_BF548, 0x0001,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
{"bf548", BFIN_CPU_BF548, 0x0000,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
+ | WA_05000074},
+
+ {"bf549m", BFIN_CPU_BF549M, 0x0003,
+ WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
{"bf549", BFIN_CPU_BF549, 0x0002,
- WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS},
+ WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
{"bf549", BFIN_CPU_BF549, 0x0001,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
{"bf549", BFIN_CPU_BF549, 0x0000,
- WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS},
+ WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf561", BFIN_CPU_BF561, 0x0005, WA_RETS
- | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074},
{"bf561", BFIN_CPU_BF561, 0x0003,
WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{"bf561", BFIN_CPU_BF561, 0x0002,
WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
- | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS},
+ | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
+ | WA_05000074},
{NULL, 0, 0, 0}
};
@@ -1357,7 +1396,7 @@ bfin_expand_prologue (void)
}
expand_prologue_reg_save (spreg, all, false);
- do_link (spreg, frame_size, false);
+ do_link (spreg, frame_size, all);
if (TARGET_ID_SHARED_LIBRARY
&& !TARGET_SEP_DATA
@@ -1386,7 +1425,7 @@ bfin_expand_epilogue (int need_return, int eh_return, bool sibcall_p)
return;
}
- do_unlink (spreg, get_frame_size (), false, e);
+ do_unlink (spreg, get_frame_size (), all, e);
expand_epilogue_reg_restore (spreg, all, false);
@@ -2180,6 +2219,8 @@ bool
bfin_longcall_p (rtx op, int call_cookie)
{
gcc_assert (GET_CODE (op) == SYMBOL_REF);
+ if (SYMBOL_REF_WEAK (op))
+ return 1;
if (call_cookie & CALL_SHORT)
return 0;
if (call_cookie & CALL_LONG)
@@ -2216,28 +2257,38 @@ bfin_expand_call (rtx retval, rtx fnaddr, rtx callarg1, rtx cookie, int sibcall)
if (TARGET_FDPIC)
{
- int caller_has_l1_text, callee_has_l1_text;
+ int caller_in_sram, callee_in_sram;
- caller_has_l1_text = callee_has_l1_text = 0;
+ /* 0 is not in sram, 1 is in L1 sram, 2 is in L2 sram. */
+ caller_in_sram = callee_in_sram = 0;
if (lookup_attribute ("l1_text",
DECL_ATTRIBUTES (cfun->decl)) != NULL_TREE)
- caller_has_l1_text = 1;
+ caller_in_sram = 1;
+ else if (lookup_attribute ("l2",
+ DECL_ATTRIBUTES (cfun->decl)) != NULL_TREE)
+ caller_in_sram = 2;
if (GET_CODE (callee) == SYMBOL_REF
- && SYMBOL_REF_DECL (callee) && DECL_P (SYMBOL_REF_DECL (callee))
- && lookup_attribute
- ("l1_text",
- DECL_ATTRIBUTES (SYMBOL_REF_DECL (callee))) != NULL_TREE)
- callee_has_l1_text = 1;
+ && SYMBOL_REF_DECL (callee) && DECL_P (SYMBOL_REF_DECL (callee)))
+ {
+ if (lookup_attribute
+ ("l1_text",
+ DECL_ATTRIBUTES (SYMBOL_REF_DECL (callee))) != NULL_TREE)
+ callee_in_sram = 1;
+ else if (lookup_attribute
+ ("l2",
+ DECL_ATTRIBUTES (SYMBOL_REF_DECL (callee))) != NULL_TREE)
+ callee_in_sram = 2;
+ }
if (GET_CODE (callee) != SYMBOL_REF
|| bfin_longcall_p (callee, INTVAL (cookie))
|| (GET_CODE (callee) == SYMBOL_REF
&& !SYMBOL_REF_LOCAL_P (callee)
&& TARGET_INLINE_PLT)
- || caller_has_l1_text != callee_has_l1_text
- || (caller_has_l1_text && callee_has_l1_text
+ || caller_in_sram != callee_in_sram
+ || (caller_in_sram && callee_in_sram
&& (GET_CODE (callee) != SYMBOL_REF
|| !SYMBOL_REF_LOCAL_P (callee))))
{
@@ -3785,7 +3836,7 @@ length_for_loop (rtx insn)
length = 4;
}
- if (INSN_P (insn))
+ if (NONDEBUG_INSN_P (insn))
length += get_attr_length (insn);
return length;
@@ -4022,7 +4073,7 @@ bfin_optimize_loop (loop_info loop)
{
for (; last_insn != BB_HEAD (bb);
last_insn = find_prev_insn_start (last_insn))
- if (INSN_P (last_insn))
+ if (NONDEBUG_INSN_P (last_insn))
break;
if (last_insn != BB_HEAD (bb))
@@ -4185,7 +4236,10 @@ bfin_optimize_loop (loop_info loop)
seq_end = emit_insn (copy_rtx (PATTERN (last_insn)));
}
else
- seq_end = emit_jump_insn (gen_jump (label));
+ {
+ emit_jump_insn (gen_jump (label));
+ seq_end = emit_barrier ();
+ }
}
seq = get_insns ();
@@ -4233,6 +4287,7 @@ bfin_optimize_loop (loop_info loop)
else
redirect_edge_succ (e, new_bb);
}
+ e = make_edge (new_bb, loop->head, 0);
}
delete_insn (loop->loop_end);
@@ -4780,15 +4835,27 @@ bfin_gen_bundles (void)
for (insn = BB_HEAD (bb);; insn = next)
{
int at_end;
- if (INSN_P (insn))
+ rtx delete_this = NULL_RTX;
+
+ if (NONDEBUG_INSN_P (insn))
{
- if (get_attr_type (insn) == TYPE_DSP32)
- slot[0] = insn;
- else if (slot[1] == NULL_RTX)
- slot[1] = insn;
+ enum attr_type type = get_attr_type (insn);
+
+ if (type == TYPE_STALL)
+ {
+ gcc_assert (n_filled == 0);
+ delete_this = insn;
+ }
else
- slot[2] = insn;
- n_filled++;
+ {
+ if (type == TYPE_DSP32 || type == TYPE_DSP32SHIFTIMM)
+ slot[0] = insn;
+ else if (slot[1] == NULL_RTX)
+ slot[1] = insn;
+ else
+ slot[2] = insn;
+ n_filled++;
+ }
}
next = NEXT_INSN (insn);
@@ -4803,7 +4870,7 @@ bfin_gen_bundles (void)
/* BB_END can change due to emitting extra NOPs, so check here. */
at_end = insn == BB_END (bb);
- if (at_end || GET_MODE (next) == TImode)
+ if (delete_this == NULL_RTX && (at_end || GET_MODE (next) == TImode))
{
if ((n_filled < 2
|| !gen_one_bundle (slot))
@@ -4822,6 +4889,8 @@ bfin_gen_bundles (void)
n_filled = 0;
slot[0] = slot[1] = slot[2] = NULL_RTX;
}
+ if (delete_this != NULL_RTX)
+ delete_insn (delete_this);
if (at_end)
break;
}
@@ -4982,28 +5051,38 @@ type_for_anomaly (rtx insn)
return get_attr_type (insn);
}
-/* Return nonzero if INSN contains any loads that may trap. It handles
- SEQUENCEs correctly. */
-
+/* Return true iff the address found in MEM is based on the register
+ NP_REG and optionally has a positive offset. */
static bool
-trapping_loads_p (rtx insn)
+harmless_null_pointer_p (rtx mem, int np_reg)
{
- rtx pat = PATTERN (insn);
- if (GET_CODE (pat) == SEQUENCE)
+ mem = XEXP (mem, 0);
+ if (GET_CODE (mem) == POST_INC || GET_CODE (mem) == POST_DEC)
+ mem = XEXP (mem, 0);
+ if (REG_P (mem) && REGNO (mem) == np_reg)
+ return true;
+ if (GET_CODE (mem) == PLUS
+ && REG_P (XEXP (mem, 0)) && REGNO (XEXP (mem, 0)) == np_reg)
{
- enum attr_type t;
- t = get_attr_type (XVECEXP (pat, 0, 1));
- if (t == TYPE_MCLD
- && may_trap_p (SET_SRC (PATTERN (XVECEXP (pat, 0, 1)))))
- return true;
- t = get_attr_type (XVECEXP (pat, 0, 2));
- if (t == TYPE_MCLD
- && may_trap_p (SET_SRC (PATTERN (XVECEXP (pat, 0, 2)))))
+ mem = XEXP (mem, 1);
+ if (GET_CODE (mem) == CONST_INT && INTVAL (mem) > 0)
return true;
- return false;
}
- else
- return may_trap_p (SET_SRC (single_set (insn)));
+ return false;
+}
+
+/* Return nonzero if INSN contains any loads that may trap. */
+
+static bool
+trapping_loads_p (rtx insn, int np_reg, bool after_np_branch)
+{
+ rtx pat = PATTERN (insn);
+ rtx mem = SET_SRC (single_set (insn));
+
+ if (!after_np_branch)
+ np_reg = -1;
+ return ((np_reg == -1 || !harmless_null_pointer_p (mem, np_reg))
+ && may_trap_p (mem));
}
/* Return INSN if it is of TYPE_MCLD. Alternatively, if INSN is the start of
@@ -5012,6 +5091,8 @@ trapping_loads_p (rtx insn)
static rtx
find_load (rtx insn)
{
+ if (!NONDEBUG_INSN_P (insn))
+ return NULL_RTX;
if (get_attr_type (insn) == TYPE_MCLD)
return insn;
if (GET_MODE (insn) != SImode)
@@ -5041,6 +5122,24 @@ indirect_call_p (rtx pat)
return REG_P (pat);
}
+/* During workaround_speculation, track whether we're in the shadow of a
+ conditional branch that tests a P register for NULL. If so, we can omit
+ emitting NOPs if we see a load from that P register, since a speculative
+ access at address 0 isn't a problem, and the load is executed in all other
+ cases anyway.
+ Global for communication with note_np_check_stores through note_stores.
+ */
+int np_check_regno = -1;
+bool np_after_branch = false;
+
+/* Subroutine of workaround_speculation, called through note_stores. */
+static void
+note_np_check_stores (rtx x, const_rtx pat, void *data ATTRIBUTE_UNUSED)
+{
+ if (REG_P (x) && (REGNO (x) == REG_CC || REGNO (x) == np_check_regno))
+ np_check_regno = -1;
+}
+
static void
workaround_speculation (void)
{
@@ -5062,17 +5161,38 @@ workaround_speculation (void)
next = find_next_insn_start (insn);
- if (NOTE_P (insn) || BARRIER_P (insn) || LABEL_P (insn))
+ if (NOTE_P (insn) || BARRIER_P (insn))
continue;
+ if (LABEL_P (insn))
+ {
+ np_check_regno = -1;
+ continue;
+ }
+
pat = PATTERN (insn);
if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER
- || GET_CODE (pat) == ASM_INPUT || GET_CODE (pat) == ADDR_VEC
- || GET_CODE (pat) == ADDR_DIFF_VEC || asm_noperands (pat) >= 0)
+ || GET_CODE (pat) == ADDR_VEC || GET_CODE (pat) == ADDR_DIFF_VEC)
continue;
+
+ if (GET_CODE (pat) == ASM_INPUT || asm_noperands (pat) >= 0)
+ {
+ np_check_regno = -1;
+ continue;
+ }
if (JUMP_P (insn))
{
+ /* Is this a condjump based on a null pointer comparison we saw
+ earlier? */
+ if (np_check_regno != -1
+ && recog_memoized (insn) == CODE_FOR_cbranchbi4)
+ {
+ rtx op = XEXP (SET_SRC (PATTERN (insn)), 0);
+ gcc_assert (GET_CODE (op) == EQ || GET_CODE (op) == NE);
+ if (GET_CODE (op) == NE)
+ np_after_branch = true;
+ }
if (any_condjump_p (insn)
&& ! cbranch_predicted_taken_p (insn))
{
@@ -5085,6 +5205,7 @@ workaround_speculation (void)
}
else if (CALL_P (insn))
{
+ np_check_regno = -1;
if (cycles_since_jump < INT_MAX)
cycles_since_jump++;
if (indirect_call_p (pat) && ENABLE_WA_INDIRECT_CALLS)
@@ -5092,7 +5213,7 @@ workaround_speculation (void)
delay_needed = 3;
}
}
- else if (INSN_P (insn))
+ else if (NONDEBUG_INSN_P (insn))
{
rtx load_insn = find_load (insn);
enum attr_type type = type_for_anomaly (insn);
@@ -5100,13 +5221,44 @@ workaround_speculation (void)
if (cycles_since_jump < INT_MAX)
cycles_since_jump++;
+ /* Detect a comparison of a P register with zero. If we later
+ see a condjump based on it, we have found a null pointer
+ check. */
+ if (recog_memoized (insn) == CODE_FOR_compare_eq)
+ {
+ rtx src = SET_SRC (PATTERN (insn));
+ if (REG_P (XEXP (src, 0))
+ && P_REGNO_P (REGNO (XEXP (src, 0)))
+ && XEXP (src, 1) == const0_rtx)
+ {
+ np_check_regno = REGNO (XEXP (src, 0));
+ np_after_branch = false;
+ }
+ else
+ np_check_regno = -1;
+ }
+
if (load_insn && ENABLE_WA_SPECULATIVE_LOADS)
{
- if (trapping_loads_p (load_insn))
+ if (trapping_loads_p (load_insn, np_check_regno,
+ np_after_branch))
delay_needed = 4;
}
else if (type == TYPE_SYNC && ENABLE_WA_SPECULATIVE_SYNCS)
delay_needed = 3;
+
+ /* See if we need to forget about a null pointer comparison
+ we found earlier. */
+ if (recog_memoized (insn) != CODE_FOR_compare_eq)
+ {
+ note_stores (PATTERN (insn), note_np_check_stores, NULL);
+ if (np_check_regno != -1)
+ {
+ if (find_regno_note (insn, REG_INC, np_check_regno))
+ np_check_regno = -1;
+ }
+ }
+
}
if (delay_needed > cycles_since_jump
@@ -5174,7 +5326,7 @@ workaround_speculation (void)
|| GET_CODE (pat) == ADDR_DIFF_VEC || asm_noperands (pat) >= 0)
continue;
- if (INSN_P (target))
+ if (NONDEBUG_INSN_P (target))
{
rtx load_insn = find_load (target);
enum attr_type type = type_for_anomaly (target);
@@ -5184,7 +5336,7 @@ workaround_speculation (void)
if (load_insn && ENABLE_WA_SPECULATIVE_LOADS)
{
- if (trapping_loads_p (load_insn))
+ if (trapping_loads_p (load_insn, -1, false))
delay_needed = 2;
}
else if (type == TYPE_SYNC && ENABLE_WA_SPECULATIVE_SYNCS)
@@ -5222,6 +5374,65 @@ workaround_speculation (void)
}
}
+/* Called just before the final scheduling pass. If we need to insert NOPs
+ later on to work around speculative loads, insert special placeholder
+ insns that cause loads to be delayed for as many cycles as necessary
+ (and possible). This reduces the number of NOPs we need to add.
+ The dummy insns we generate are later removed by bfin_gen_bundles. */
+static void
+add_sched_insns_for_speculation (void)
+{
+ rtx insn;
+
+ if (! ENABLE_WA_SPECULATIVE_LOADS && ! ENABLE_WA_SPECULATIVE_SYNCS
+ && ! ENABLE_WA_INDIRECT_CALLS)
+ return;
+
+ /* First pass: find predicted-false branches; if something after them
+ needs nops, insert them or change the branch to predict true. */
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ rtx pat;
+
+ if (NOTE_P (insn) || BARRIER_P (insn) || LABEL_P (insn))
+ continue;
+
+ pat = PATTERN (insn);
+ if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER
+ || GET_CODE (pat) == ASM_INPUT || GET_CODE (pat) == ADDR_VEC
+ || GET_CODE (pat) == ADDR_DIFF_VEC || asm_noperands (pat) >= 0)
+ continue;
+
+ if (JUMP_P (insn))
+ {
+ if (any_condjump_p (insn)
+ && !cbranch_predicted_taken_p (insn))
+ {
+ rtx n = next_real_insn (insn);
+ emit_insn_before (gen_stall (GEN_INT (3)), n);
+ }
+ }
+ }
+
+ /* Second pass: for predicted-true branches, see if anything at the
+ branch destination needs extra nops. */
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ if (JUMP_P (insn)
+ && any_condjump_p (insn)
+ && (cbranch_predicted_taken_p (insn)))
+ {
+ rtx target = JUMP_LABEL (insn);
+ rtx next = next_real_insn (target);
+
+ if (GET_CODE (PATTERN (next)) == UNSPEC_VOLATILE
+ && get_attr_type (next) == TYPE_STALL)
+ continue;
+ emit_insn_before (gen_stall (GEN_INT (1)), next);
+ }
+ }
+}
+
/* We use the machine specific reorg pass for emitting CSYNC instructions
after conditional branches as needed.
@@ -5255,6 +5466,8 @@ bfin_reorg (void)
split_all_insns ();
splitting_for_sched = 0;
+ add_sched_insns_for_speculation ();
+
timevar_push (TV_SCHED2);
schedule_insns ();
timevar_pop (TV_SCHED2);
@@ -5464,6 +5677,45 @@ bfin_handle_l1_data_attribute (tree *node, tree name, tree ARG_UNUSED (args),
return NULL_TREE;
}
+/* Handle a "l2" attribute; arguments as in struct attribute_spec.handler. */
+
+static tree
+bfin_handle_l2_attribute (tree *node, tree ARG_UNUSED (name),
+ tree ARG_UNUSED (args), int ARG_UNUSED (flags),
+ bool *no_add_attrs)
+{
+ tree decl = *node;
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ if (DECL_SECTION_NAME (decl) != NULL_TREE
+ && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
+ ".l2.text") != 0)
+ {
+ error ("section of %q+D conflicts with previous declaration",
+ decl);
+ *no_add_attrs = true;
+ }
+ else
+ DECL_SECTION_NAME (decl) = build_string (9, ".l2.text");
+ }
+ else if (TREE_CODE (decl) == VAR_DECL)
+ {
+ if (DECL_SECTION_NAME (decl) != NULL_TREE
+ && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
+ ".l2.data") != 0)
+ {
+ error ("section of %q+D conflicts with previous declaration",
+ decl);
+ *no_add_attrs = true;
+ }
+ else
+ DECL_SECTION_NAME (decl) = build_string (9, ".l2.data");
+ }
+
+ return NULL_TREE;
+}
+
/* Table of valid machine attributes. */
static const struct attribute_spec bfin_attribute_table[] =
{
@@ -5480,6 +5732,7 @@ static const struct attribute_spec bfin_attribute_table[] =
{ "l1_data", 0, 0, true, false, false, bfin_handle_l1_data_attribute },
{ "l1_data_A", 0, 0, true, false, false, bfin_handle_l1_data_attribute },
{ "l1_data_B", 0, 0, true, false, false, bfin_handle_l1_data_attribute },
+ { "l2", 0, 0, true, false, false, bfin_handle_l2_attribute },
{ NULL, 0, 0, false, false, false, NULL }
};
@@ -6091,6 +6344,10 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
if (! target
|| !register_operand (target, SImode))
target = gen_reg_rtx (SImode);
+ if (! register_operand (op0, SImode))
+ op0 = copy_to_mode_reg (SImode, op0);
+ if (! register_operand (op1, SImode))
+ op1 = copy_to_mode_reg (SImode, op1);
a1reg = gen_rtx_REG (PDImode, REG_A1);
a0reg = gen_rtx_REG (PDImode, REG_A0);
@@ -6144,6 +6401,7 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
accvec = gen_reg_rtx (V2PDImode);
+ icode = CODE_FOR_flag_macv2hi_parts;
if (! target
|| GET_MODE (target) != V2HImode
@@ -6180,6 +6438,7 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
accvec = gen_reg_rtx (V2PDImode);
+ icode = CODE_FOR_flag_macv2hi_parts;
if (! target
|| GET_MODE (target) != V2HImode
diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h
index 53a7957405a..34032b28225 100644
--- a/gcc/config/bfin/bfin.h
+++ b/gcc/config/bfin/bfin.h
@@ -26,6 +26,49 @@
#define BRT 1
#define BRF 0
+/* CPU type. */
+typedef enum bfin_cpu_type
+{
+ BFIN_CPU_UNKNOWN,
+ BFIN_CPU_BF512,
+ BFIN_CPU_BF514,
+ BFIN_CPU_BF516,
+ BFIN_CPU_BF518,
+ BFIN_CPU_BF522,
+ BFIN_CPU_BF523,
+ BFIN_CPU_BF524,
+ BFIN_CPU_BF525,
+ BFIN_CPU_BF526,
+ BFIN_CPU_BF527,
+ BFIN_CPU_BF531,
+ BFIN_CPU_BF532,
+ BFIN_CPU_BF533,
+ BFIN_CPU_BF534,
+ BFIN_CPU_BF536,
+ BFIN_CPU_BF537,
+ BFIN_CPU_BF538,
+ BFIN_CPU_BF539,
+ BFIN_CPU_BF542,
+ BFIN_CPU_BF542M,
+ BFIN_CPU_BF544,
+ BFIN_CPU_BF544M,
+ BFIN_CPU_BF547,
+ BFIN_CPU_BF547M,
+ BFIN_CPU_BF548,
+ BFIN_CPU_BF548M,
+ BFIN_CPU_BF549,
+ BFIN_CPU_BF549M,
+ BFIN_CPU_BF561
+} bfin_cpu_t;
+
+/* Value of -mcpu= */
+extern bfin_cpu_t bfin_cpu_type;
+
+/* Value of -msi-revision= */
+extern int bfin_si_revision;
+
+extern unsigned int bfin_workarounds;
+
/* Print subsidiary information on the compiler version in use. */
#define TARGET_VERSION fprintf (stderr, " (BlackFin bfin)")
@@ -109,22 +152,32 @@ extern int target_flags;
case BFIN_CPU_BF539: \
builtin_define ("__ADSPBF539__"); \
break; \
+ case BFIN_CPU_BF542M: \
+ builtin_define ("__ADSPBF542M__"); \
case BFIN_CPU_BF542: \
builtin_define ("__ADSPBF542__"); \
builtin_define ("__ADSPBF54x__"); \
break; \
+ case BFIN_CPU_BF544M: \
+ builtin_define ("__ADSPBF544M__"); \
case BFIN_CPU_BF544: \
builtin_define ("__ADSPBF544__"); \
builtin_define ("__ADSPBF54x__"); \
break; \
- case BFIN_CPU_BF548: \
- builtin_define ("__ADSPBF548__"); \
- builtin_define ("__ADSPBF54x__"); \
- break; \
+ case BFIN_CPU_BF547M: \
+ builtin_define ("__ADSPBF547M__"); \
case BFIN_CPU_BF547: \
builtin_define ("__ADSPBF547__"); \
builtin_define ("__ADSPBF54x__"); \
break; \
+ case BFIN_CPU_BF548M: \
+ builtin_define ("__ADSPBF548M__"); \
+ case BFIN_CPU_BF548: \
+ builtin_define ("__ADSPBF548__"); \
+ builtin_define ("__ADSPBF54x__"); \
+ break; \
+ case BFIN_CPU_BF549M: \
+ builtin_define ("__ADSPBF549M__"); \
case BFIN_CPU_BF549: \
builtin_define ("__ADSPBF549__"); \
builtin_define ("__ADSPBF54x__"); \
diff --git a/gcc/config/bfin/bfin.md b/gcc/config/bfin/bfin.md
index 01e40125cf6..3fac01ca564 100644
--- a/gcc/config/bfin/bfin.md
+++ b/gcc/config/bfin/bfin.md
@@ -146,7 +146,8 @@
(UNSPEC_VOLATILE_SSYNC 2)
(UNSPEC_VOLATILE_LOAD_FUNCDESC 3)
(UNSPEC_VOLATILE_STORE_EH_HANDLER 4)
- (UNSPEC_VOLATILE_DUMMY 5)])
+ (UNSPEC_VOLATILE_DUMMY 5)
+ (UNSPEC_VOLATILE_STALL 6)])
(define_constants
[(MACFLAG_NONE 0)
@@ -163,28 +164,42 @@
(MACFLAG_IH 11)])
(define_attr "type"
- "move,movcc,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy"
+ "move,movcc,mvi,mcld,mcst,dsp32,dsp32shiftimm,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy,stall"
(const_string "misc"))
-(define_attr "addrtype" "32bit,preg,ireg"
+(define_attr "addrtype" "32bit,preg,spreg,ireg"
(cond [(and (eq_attr "type" "mcld")
- (and (match_operand 0 "d_register_operand" "")
+ (and (match_operand 0 "dp_register_operand" "")
(match_operand 1 "mem_p_address_operand" "")))
(const_string "preg")
(and (eq_attr "type" "mcld")
- (and (match_operand 0 "d_register_operand" "")
+ (and (match_operand 0 "dp_register_operand" "")
+ (match_operand 1 "mem_spfp_address_operand" "")))
+ (const_string "spreg")
+ (and (eq_attr "type" "mcld")
+ (and (match_operand 0 "dp_register_operand" "")
(match_operand 1 "mem_i_address_operand" "")))
(const_string "ireg")
(and (eq_attr "type" "mcst")
- (and (match_operand 1 "d_register_operand" "")
+ (and (match_operand 1 "dp_register_operand" "")
(match_operand 0 "mem_p_address_operand" "")))
(const_string "preg")
(and (eq_attr "type" "mcst")
- (and (match_operand 1 "d_register_operand" "")
+ (and (match_operand 1 "dp_register_operand" "")
+ (match_operand 0 "mem_spfp_address_operand" "")))
+ (const_string "spreg")
+ (and (eq_attr "type" "mcst")
+ (and (match_operand 1 "dp_register_operand" "")
(match_operand 0 "mem_i_address_operand" "")))
(const_string "ireg")]
(const_string "32bit")))
+(define_attr "storereg" "preg,other"
+ (cond [(and (eq_attr "type" "mcst")
+ (match_operand 1 "p_register_operand" ""))
+ (const_string "preg")]
+ (const_string "other")))
+
;; Scheduling definitions
(define_automaton "bfin")
@@ -199,6 +214,13 @@
(define_cpu_unit "store" "bfin")
(define_cpu_unit "pregs" "bfin")
+;; A dummy unit used to delay scheduling of loads after a conditional
+;; branch.
+(define_cpu_unit "load" "bfin")
+
+;; A logical unit used to work around anomaly 05000074.
+(define_cpu_unit "anomaly_05000074" "bfin")
+
(define_reservation "core" "slot0+slot1+slot2")
(define_insn_reservation "alu" 1
@@ -213,20 +235,37 @@
(eq_attr "type" "dsp32")
"slot0")
+(define_insn_reservation "dsp32shiftimm" 1
+ (and (eq_attr "type" "dsp32shiftimm")
+ (eq (symbol_ref "ENABLE_WA_05000074")
+ (const_int 0)))
+ "slot0")
+
+(define_insn_reservation "dsp32shiftimm_anomaly_05000074" 1
+ (and (eq_attr "type" "dsp32shiftimm")
+ (ne (symbol_ref "ENABLE_WA_05000074")
+ (const_int 0)))
+ "slot0+anomaly_05000074")
+
(define_insn_reservation "load32" 1
(and (not (eq_attr "seq_insns" "multi"))
(and (eq_attr "type" "mcld") (eq_attr "addrtype" "32bit")))
- "core")
+ "core+load")
(define_insn_reservation "loadp" 1
(and (not (eq_attr "seq_insns" "multi"))
(and (eq_attr "type" "mcld") (eq_attr "addrtype" "preg")))
- "(slot1|slot2)+pregs")
+ "slot1+pregs+load")
+
+(define_insn_reservation "loadsp" 1
+ (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcld") (eq_attr "addrtype" "spreg")))
+ "slot1+pregs")
(define_insn_reservation "loadi" 1
(and (not (eq_attr "seq_insns" "multi"))
(and (eq_attr "type" "mcld") (eq_attr "addrtype" "ireg")))
- "(slot1|slot2)")
+ "(slot1|slot2)+load")
(define_insn_reservation "store32" 1
(and (not (eq_attr "seq_insns" "multi"))
@@ -234,19 +273,55 @@
"core")
(define_insn_reservation "storep" 1
- (and (not (eq_attr "seq_insns" "multi"))
- (and (eq_attr "type" "mcst") (eq_attr "addrtype" "preg")))
- "(slot1|slot2)+pregs+store")
+ (and (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcst")
+ (ior (eq_attr "addrtype" "preg")
+ (eq_attr "addrtype" "spreg"))))
+ (ior (eq (symbol_ref "ENABLE_WA_05000074")
+ (const_int 0))
+ (eq_attr "storereg" "other")))
+ "slot1+pregs+store")
+
+(define_insn_reservation "storep_anomaly_05000074" 1
+ (and (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcst")
+ (ior (eq_attr "addrtype" "preg")
+ (eq_attr "addrtype" "spreg"))))
+ (and (ne (symbol_ref "ENABLE_WA_05000074")
+ (const_int 0))
+ (eq_attr "storereg" "preg")))
+ "slot1+anomaly_05000074+pregs+store")
(define_insn_reservation "storei" 1
- (and (not (eq_attr "seq_insns" "multi"))
- (and (eq_attr "type" "mcst") (eq_attr "addrtype" "ireg")))
+ (and (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcst") (eq_attr "addrtype" "ireg")))
+ (ior (eq (symbol_ref "ENABLE_WA_05000074")
+ (const_int 0))
+ (eq_attr "storereg" "other")))
"(slot1|slot2)+store")
+(define_insn_reservation "storei_anomaly_05000074" 1
+ (and (and (not (eq_attr "seq_insns" "multi"))
+ (and (eq_attr "type" "mcst") (eq_attr "addrtype" "ireg")))
+ (and (ne (symbol_ref "ENABLE_WA_05000074")
+ (const_int 0))
+ (eq_attr "storereg" "preg")))
+ "((slot1+anomaly_05000074)|slot2)+store")
+
(define_insn_reservation "multi" 2
(eq_attr "seq_insns" "multi")
"core")
+(define_insn_reservation "load_stall1" 1
+ (and (eq_attr "type" "stall")
+ (match_operand 0 "const1_operand" ""))
+ "core+load*2")
+
+(define_insn_reservation "load_stall3" 1
+ (and (eq_attr "type" "stall")
+ (match_operand 0 "const3_operand" ""))
+ "core+load*4")
+
(absence_set "slot0" "slot1,slot2")
(absence_set "slot1" "slot2")
@@ -303,6 +378,7 @@
(eq_attr "type" "move") (const_int 2)
(eq_attr "type" "dsp32") (const_int 4)
+ (eq_attr "type" "dsp32shiftimm") (const_int 4)
(eq_attr "type" "call") (const_int 4)
(eq_attr "type" "br")
@@ -556,7 +632,7 @@
"@
%0 = ROT %1 BY 0%!
%0 = %0 -|- %0%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm,dsp32")])
(define_split
[(set (match_operand:SI 0 "d_register_operand" "")
@@ -679,7 +755,7 @@
"@
%d0 = %h1 << 0%!
%d0 = %1;"
- [(set_attr "type" "dsp32,mvi")])
+ [(set_attr "type" "dsp32shiftimm,mvi")])
(define_expand "insv"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
@@ -1589,7 +1665,7 @@
[(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2)))
(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))]
"operands[3] = GEN_INT (INTVAL (operands[2]) - 2);"
- [(set_attr "type" "shft,dsp32,shft,shft,*")])
+ [(set_attr "type" "shft,dsp32shiftimm,shft,shft,*")])
(define_insn "ashrsi3"
[(set (match_operand:SI 0 "register_operand" "=d,d")
@@ -1599,7 +1675,7 @@
"@
%0 >>>= %2;
%0 = %1 >>> %2%!"
- [(set_attr "type" "shft,dsp32")])
+ [(set_attr "type" "shft,dsp32shiftimm")])
(define_insn "rotl16"
[(set (match_operand:SI 0 "register_operand" "=d")
@@ -1640,7 +1716,7 @@
(zero_extract:BI (match_dup 1) (const_int 1) (const_int 0)))]
""
"%0 = ROT %1 BY -1%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
(define_insn "rol_one"
[(set (match_operand:SI 0 "register_operand" "+d")
@@ -1650,7 +1726,7 @@
(zero_extract:BI (match_dup 1) (const_int 31) (const_int 0)))]
""
"%0 = ROT %1 BY 1%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
(define_expand "lshrdi3"
[(set (match_operand:DI 0 "register_operand" "")
@@ -1725,7 +1801,7 @@
%0 >>= %2;
%0 = %1 >> %2%!
%0 = %1 >> %2;"
- [(set_attr "type" "shft,dsp32,shft")])
+ [(set_attr "type" "shft,dsp32shiftimm,shft")])
(define_insn "lshrpdi3"
[(set (match_operand:PDI 0 "register_operand" "=e")
@@ -1733,7 +1809,7 @@
(match_operand:SI 2 "nonmemory_operand" "Ku5")))]
""
"%0 = %1 >> %2%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
(define_insn "ashrpdi3"
[(set (match_operand:PDI 0 "register_operand" "=e")
@@ -1741,7 +1817,7 @@
(match_operand:SI 2 "nonmemory_operand" "Ku5")))]
""
"%0 = %1 >>> %2%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
;; A pattern to reload the equivalent of
;; (set (Dreg) (plus (FP) (large_constant)))
@@ -1765,9 +1841,11 @@
DONE;
})
-(define_insn "reload_inpdi"
- [(set (match_operand:PDI 0 "register_operand" "=e")
- (match_operand:PDI 1 "memory_operand" "m"))
+(define_mode_iterator AREG [PDI V2PDI])
+
+(define_insn "reload_in<mode>"
+ [(set (match_operand:AREG 0 "register_operand" "=e")
+ (match_operand:AREG 1 "memory_operand" "m"))
(clobber (match_operand:SI 2 "register_operand" "=d"))]
""
{
@@ -1785,9 +1863,9 @@
(set_attr "type" "mcld")
(set_attr "length" "12")])
-(define_insn "reload_outpdi"
- [(set (match_operand:PDI 0 "memory_operand" "=m")
- (match_operand:PDI 1 "register_operand" "e"))
+(define_insn "reload_out<mode>"
+ [(set (match_operand:AREG 0 "memory_operand" "=m")
+ (match_operand:AREG 1 "register_operand" "e"))
(clobber (match_operand:SI 2 "register_operand" "=d"))]
""
{
@@ -2667,6 +2745,9 @@
gcc_unreachable ();
})
+;; When used at a location where CC contains 1, causes a speculative load
+;; that is later cancelled. This is used for certain workarounds in
+;; interrupt handler prologues.
(define_insn "dummy_load"
[(unspec_volatile [(match_operand 0 "register_operand" "a")
(match_operand 1 "register_operand" "C")]
@@ -2677,6 +2758,17 @@
(set_attr "length" "4")
(set_attr "seq_insns" "multi")])
+;; A placeholder insn inserted before the final scheduling pass. It is used
+;; to improve scheduling of loads when workarounds for speculative loads are
+;; needed, by not placing them in the first few cycles after a conditional
+;; branch.
+(define_insn "stall"
+ [(unspec_volatile [(match_operand 0 "const_int_operand" "P1P3")]
+ UNSPEC_VOLATILE_STALL)]
+ ""
+ ""
+ [(set_attr "type" "stall")])
+
(define_insn "csync"
[(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)]
""
@@ -2716,7 +2808,7 @@
(parallel [(const_int 1)]))))]
""
"%h0 = %h2 << 0%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
(define_insn "movhiv2hi_high"
[(set (match_operand:V2HI 0 "register_operand" "=d")
@@ -2726,7 +2818,7 @@
(match_operand:HI 2 "register_operand" "d")))]
""
"%d0 = %h2 << 0%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
;; No earlyclobber on alternative two since our sequence ought to be safe.
;; The order of operands is intentional to match the VDSP builtin (high word
@@ -2749,7 +2841,7 @@
(match_dup 2)
(vec_select:HI (match_dup 0) (parallel [(const_int 1)]))))]
""
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
; Like composev2hi, but operating on elements of V2HI vectors.
; Useful on its own, and as a combiner bridge for the multiply and
@@ -2772,7 +2864,7 @@
%0 = PACK (%h2,%d1)%!
%0 = PACK (%d2,%h1)%!
%0 = PACK (%d2,%d1)%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm,dsp32shiftimm,dsp32shiftimm,dsp32shiftimm,dsp32,dsp32,dsp32,dsp32")])
(define_insn "movv2hi_hi"
[(set (match_operand:HI 0 "register_operand" "=d,d,d")
@@ -2783,7 +2875,7 @@
/* optimized out */
%h0 = %h1 << 0%!
%h0 = %d1 << 0%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32shiftimm")])
(define_expand "movv2hi_hi_low"
[(set (match_operand:HI 0 "register_operand" "")
@@ -4047,7 +4139,7 @@
%0 = ASHIFT %1 BY %h2 (V, S)%!
%0 = %1 << %2 (V,S)%!
%0 = %1 >>> %N2 (V,S)%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
(define_insn "ssashifthi3"
[(set (match_operand:HI 0 "register_operand" "=d,d,d")
@@ -4061,7 +4153,7 @@
%0 = ASHIFT %1 BY %h2 (V, S)%!
%0 = %1 << %2 (V,S)%!
%0 = %1 >>> %N2 (V,S)%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
(define_insn "ssashiftsi3"
[(set (match_operand:SI 0 "register_operand" "=d,d,d")
@@ -4075,7 +4167,7 @@
%0 = ASHIFT %1 BY %h2 (S)%!
%0 = %1 << %2 (S)%!
%0 = %1 >>> %N2 (S)%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
(define_insn "lshiftv2hi3"
[(set (match_operand:V2HI 0 "register_operand" "=d,d,d")
@@ -4089,7 +4181,7 @@
%0 = LSHIFT %1 BY %h2 (V)%!
%0 = %1 << %2 (V)%!
%0 = %1 >> %N2 (V)%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
(define_insn "lshifthi3"
[(set (match_operand:HI 0 "register_operand" "=d,d,d")
@@ -4103,7 +4195,7 @@
%0 = LSHIFT %1 BY %h2 (V)%!
%0 = %1 << %2 (V)%!
%0 = %1 >> %N2 (V)%!"
- [(set_attr "type" "dsp32")])
+ [(set_attr "type" "dsp32,dsp32shiftimm,dsp32shiftimm")])
;; Load without alignment exception (masking off low bits)
diff --git a/gcc/config/bfin/predicates.md b/gcc/config/bfin/predicates.md
index bce725a7009..84bf5919509 100644
--- a/gcc/config/bfin/predicates.md
+++ b/gcc/config/bfin/predicates.md
@@ -59,6 +59,14 @@
(and (match_code "const_int")
(match_test "op == const0_rtx || op == const1_rtx")))
+(define_predicate "const1_operand"
+ (and (match_code "const_int")
+ (match_test "op == const1_rtx")))
+
+(define_predicate "const3_operand"
+ (and (match_code "const_int")
+ (match_test "INTVAL (op) == 3")))
+
(define_predicate "vec_shift_operand"
(ior (and (match_code "const_int")
(match_test "INTVAL (op) >= -16 && INTVAL (op) < 15"))
@@ -80,6 +88,14 @@
(and (match_code "reg")
(match_test "D_REGNO_P (REGNO (op))")))
+(define_predicate "p_register_operand"
+ (and (match_code "reg")
+ (match_test "P_REGNO_P (REGNO (op))")))
+
+(define_predicate "dp_register_operand"
+ (and (match_code "reg")
+ (match_test "D_REGNO_P (REGNO (op)) || P_REGNO_P (REGNO (op))")))
+
;; Return nonzero if OP is a LC register.
(define_predicate "lc_register_operand"
(and (match_code "reg")
@@ -180,10 +196,14 @@
(define_predicate "bfin_direct_comparison_operator"
(match_code "eq,lt,le,leu,ltu"))
-;; The following two are used to compute the addrtype attribute. They return
+;; The following three are used to compute the addrtype attribute. They return
;; true if passed a memory address usable for a 16-bit load or store using a
;; P or I register, respectively. If neither matches, we know we have a
;; 32-bit instruction.
+;; We subdivide the P case into normal P registers, and SP/FP. We can assume
+;; that speculative loads through SP and FP are no problem, so this has
+;; an effect on the anomaly workaround code.
+
(define_predicate "mem_p_address_operand"
(match_code "mem")
{
@@ -193,7 +213,19 @@
if (GET_CODE (op) == PLUS || GET_RTX_CLASS (GET_CODE (op)) == RTX_AUTOINC)
op = XEXP (op, 0);
gcc_assert (REG_P (op));
- return PREG_P (op);
+ return PREG_P (op) && op != stack_pointer_rtx && op != frame_pointer_rtx;
+})
+
+(define_predicate "mem_spfp_address_operand"
+ (match_code "mem")
+{
+ if (effective_address_32bit_p (op, mode))
+ return 0;
+ op = XEXP (op, 0);
+ if (GET_CODE (op) == PLUS || GET_RTX_CLASS (GET_CODE (op)) == RTX_AUTOINC)
+ op = XEXP (op, 0);
+ gcc_assert (REG_P (op));
+ return op == stack_pointer_rtx || op == frame_pointer_rtx;
})
(define_predicate "mem_i_address_operand"
diff --git a/gcc/config/bfin/t-bfin-elf b/gcc/config/bfin/t-bfin-elf
index 87e00ade16b..39209f628ef 100644
--- a/gcc/config/bfin/t-bfin-elf
+++ b/gcc/config/bfin/t-bfin-elf
@@ -48,8 +48,15 @@ MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf531-none mcpu?bf532-none=mcpu?bf533-non
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf534-none mcpu?bf532-none=mcpu?bf536-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf537-none mcpu?bf532-none=mcpu?bf538-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf539-none mcpu?bf532-none=mcpu?bf542-none
-MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf544-none mcpu?bf532-none=mcpu?bf547-none
-MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf548-none mcpu?bf532-none=mcpu?bf549-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf542m-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf544-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf544m-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf547-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf547m-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf548-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf548m-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf549-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf549m-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf561-none
MULTILIB_EXCEPTIONS=mleaf-id-shared-library*
diff --git a/gcc/config/bfin/t-bfin-linux b/gcc/config/bfin/t-bfin-linux
index 3fbfb4947ce..f7ba9550128 100644
--- a/gcc/config/bfin/t-bfin-linux
+++ b/gcc/config/bfin/t-bfin-linux
@@ -47,8 +47,15 @@ MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf531-none mcpu?bf532-none=mcpu?bf533-non
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf534-none mcpu?bf532-none=mcpu?bf536-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf537-none mcpu?bf532-none=mcpu?bf538-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf539-none mcpu?bf532-none=mcpu?bf542-none
-MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf544-none mcpu?bf532-none=mcpu?bf547-none
-MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf548-none mcpu?bf532-none=mcpu?bf549-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf542m-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf544-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf544m-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf547-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf547m-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf548-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf548m-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf549-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf549m-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf561-none
SHLIB_MAPFILES=$(srcdir)/config/bfin/libgcc-bfin.ver
diff --git a/gcc/config/bfin/t-bfin-uclinux b/gcc/config/bfin/t-bfin-uclinux
index f0a8e913d5c..eb6d2253eb0 100644
--- a/gcc/config/bfin/t-bfin-uclinux
+++ b/gcc/config/bfin/t-bfin-uclinux
@@ -48,8 +48,15 @@ MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf531-none mcpu?bf532-none=mcpu?bf533-non
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf534-none mcpu?bf532-none=mcpu?bf536-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf537-none mcpu?bf532-none=mcpu?bf538-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf539-none mcpu?bf532-none=mcpu?bf542-none
-MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf544-none mcpu?bf532-none=mcpu?bf547-none
-MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf548-none mcpu?bf532-none=mcpu?bf549-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf542m-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf544-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf544m-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf547-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf547m-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf548-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf548m-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf549-none
+MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf549m-none
MULTILIB_MATCHES+=mcpu?bf532-none=mcpu?bf561-none
MULTILIB_EXCEPTIONS=mleaf-id-shared-library*
diff --git a/gcc/config/dfp-bit.c b/gcc/config/dfp-bit.c
index d315d5b56f0..19f2fdae67d 100644
--- a/gcc/config/dfp-bit.c
+++ b/gcc/config/dfp-bit.c
@@ -568,7 +568,6 @@ INT_TO_DFP (INT_TYPE i)
decContext context;
decContextDefault (&context, DEC_INIT_DECIMAL128);
- context.round = DEC_ROUND_DOWN;
f64 = *DEC_FLOAT_FROM_INT (&f64, i);
u32.f = *decSingleFromWider (&u32.f, &f64, &context);
if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
@@ -593,7 +592,7 @@ INT_TO_DFP (INT_TYPE i)
DFP_INIT_ROUNDMODE (context.round);
/* Use a C library function to get a floating point string. */
- sprintf (buf, INT_FMT ".0", CAST_FOR_FMT(i));
+ sprintf (buf, INT_FMT ".", CAST_FOR_FMT(i));
/* Convert from the floating point string to a decimal* type. */
FROM_STRING (&s, buf, &context);
IEEE_TO_HOST (s, &f);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index ccb5e2f1459..f8d77dd6cd0 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -7441,7 +7441,8 @@ ix86_can_use_return_insn_p (void)
return 0;
ix86_compute_frame_layout (&frame);
- return frame.to_allocate == 0 && (frame.nregs + frame.nsseregs) == 0;
+ return frame.to_allocate == 0 && frame.padding0 == 0
+ && (frame.nregs + frame.nsseregs) == 0;
}
/* Value should be nonzero if functions must have frame pointers.
@@ -8482,7 +8483,7 @@ ix86_expand_prologue (void)
&& (! TARGET_STACK_PROBE || allocate < CHECK_STACK_LIMIT)))
{
if (!frame_pointer_needed
- || !frame.to_allocate
+ || !(frame.to_allocate + frame.padding0)
|| crtl->stack_realign_needed)
ix86_emit_save_regs_using_mov (stack_pointer_rtx,
frame.to_allocate
@@ -8492,7 +8493,7 @@ ix86_expand_prologue (void)
-frame.nregs * UNITS_PER_WORD);
}
if (!frame_pointer_needed
- || !frame.to_allocate
+ || !(frame.to_allocate + frame.padding0)
|| crtl->stack_realign_needed)
ix86_emit_save_sse_regs_using_mov (stack_pointer_rtx,
frame.to_allocate);
@@ -8804,9 +8805,10 @@ ix86_expand_epilogue (int style)
if ((!sp_valid && (frame.nregs + frame.nsseregs) <= 1)
|| (TARGET_EPILOGUE_USING_MOVE
&& cfun->machine->use_fast_prologue_epilogue
- && ((frame.nregs + frame.nsseregs) > 1 || frame.to_allocate))
+ && ((frame.nregs + frame.nsseregs) > 1
+ || (frame.to_allocate + frame.padding0) != 0))
|| (frame_pointer_needed && !(frame.nregs + frame.nsseregs)
- && frame.to_allocate)
+ && (frame.to_allocate + frame.padding0) != 0)
|| (frame_pointer_needed && TARGET_USE_LEAVE
&& cfun->machine->use_fast_prologue_epilogue
&& (frame.nregs + frame.nsseregs) == 1)
@@ -8822,7 +8824,7 @@ ix86_expand_epilogue (int style)
be addressed by bp. sp must be used instead. */
if (!frame_pointer_needed
- || (sp_valid && !frame.to_allocate)
+ || (sp_valid && !(frame.to_allocate + frame.padding0))
|| stack_realign_fp)
{
ix86_emit_restore_sse_regs_using_mov (stack_pointer_rtx,
@@ -8952,7 +8954,7 @@ ix86_expand_epilogue (int style)
GEN_INT (frame.nsseregs * 16 + frame.padding0),
style, false);
}
- else if (frame.to_allocate || frame.nsseregs)
+ else if (frame.to_allocate || frame.padding0 || frame.nsseregs)
{
ix86_emit_restore_sse_regs_using_mov (stack_pointer_rtx,
frame.to_allocate, red_offset,
diff --git a/gcc/config/i386/mingw-w64.h b/gcc/config/i386/mingw-w64.h
index e38418f7dcd..85840826674 100644
--- a/gcc/config/i386/mingw-w64.h
+++ b/gcc/config/i386/mingw-w64.h
@@ -36,7 +36,7 @@ along with GCC; see the file COPYING3. If not see
/* Enable multilib. */
#undef ASM_SPEC
-#define ASM_SPEC "%{v:-V} %{n} %{T} %{Ym,*} %{Yd,*} \
+#define ASM_SPEC "%{v:-v} %{n} %{T} %{Ym,*} %{Yd,*} \
%{Wa,*:%*} %{m32:--32} %{m64:--64}"
#if TARGET_64BIT_DEFAULT
diff --git a/gcc/config/ia64/unwind-ia64.c b/gcc/config/ia64/unwind-ia64.c
index 34258588292..f935a0ca3e4 100644
--- a/gcc/config/ia64/unwind-ia64.c
+++ b/gcc/config/ia64/unwind-ia64.c
@@ -2126,7 +2126,7 @@ uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
uw_init_context_1 (CONTEXT, __builtin_ia64_bsp ()); \
} while (0)
-static void
+static void __attribute__((noinline))
uw_init_context_1 (struct _Unwind_Context *context, void *bsp)
{
void *rp = __builtin_extract_return_addr (__builtin_return_address (0));
diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c
index ae4c8973dea..1bf3d1bcb2f 100644
--- a/gcc/config/m32c/m32c.c
+++ b/gcc/config/m32c/m32c.c
@@ -4052,8 +4052,26 @@ m32c_emit_epilogue (void)
if (!bank_switch_p (cfun->decl) && cfun->machine->intr_pushm)
emit_insn (gen_popm (GEN_INT (cfun->machine->intr_pushm)));
+ /* The FREIT (Fast REturn from InTerrupt) instruction should be
+ generated only for M32C/M32CM targets (generate the REIT
+ instruction otherwise). */
if (fast_interrupt_p (cfun->decl))
- emit_jump_insn (gen_epilogue_freit ());
+ {
+ /* Check if fast_attribute is set for M32C or M32CM. */
+ if (TARGET_A24)
+ {
+ emit_jump_insn (gen_epilogue_freit ());
+ }
+ /* If fast_interrupt attribute is set for an R8C or M16C
+ target ignore this attribute and generated REIT
+ instruction. */
+ else
+ {
+ warning (OPT_Wattributes,
+ "%<fast_interrupt%> attribute directive ignored");
+ emit_jump_insn (gen_epilogue_reit_16 ());
+ }
+ }
else if (TARGET_A16)
emit_jump_insn (gen_epilogue_reit_16 ());
else
diff --git a/gcc/config/m32c/m32c.h b/gcc/config/m32c/m32c.h
index dea5b55b71a..ee092a56525 100644
--- a/gcc/config/m32c/m32c.h
+++ b/gcc/config/m32c/m32c.h
@@ -48,12 +48,12 @@
thing when no CPU is specified, which defaults to R8C. */
#undef LIB_SPEC
#define LIB_SPEC "-( -lc %{msim*:-lsim}%{!msim*:-lnosys} -) \
-%{msim*:%{!T*: %{mcpu=m32cm:-Tsim24.ld}%{mcpu=m32c:-Tsim24.ld} \
- %{!mcpu=m32cm:%{!mcpu=m32c:-Tsim16.ld}}}} \
-%{!T*:%{!msim*: %{mcpu=m16c:-Tm16c.ld} \
- %{mcpu=m32cm:-Tm32cm.ld} \
- %{mcpu=m32c:-Tm32c.ld} \
- %{!mcpu=m16c:%{!mcpu=m32cm:%{!mcpu=m32c:-Tr8c.ld}}}}} \
+%{msim*:%{!T*: %{mcpu=m32cm:%Tsim24.ld}%{mcpu=m32c:%Tsim24.ld} \
+ %{!mcpu=m32cm:%{!mcpu=m32c:%Tsim16.ld}}}} \
+%{!T*:%{!msim*: %{mcpu=m16c:%Tm16c.ld} \
+ %{mcpu=m32cm:%Tm32cm.ld} \
+ %{mcpu=m32c:%Tm32c.ld} \
+ %{!mcpu=m16c:%{!mcpu=m32cm:%{!mcpu=m32c:%Tr8c.ld}}}}} \
"
/* Run-time Target Specification */
diff --git a/gcc/config/mep/mep-protos.h b/gcc/config/mep/mep-protos.h
index a4de754bbd9..e53ca79639c 100644
--- a/gcc/config/mep/mep-protos.h
+++ b/gcc/config/mep/mep-protos.h
@@ -48,6 +48,7 @@ extern void mep_split_wide_move (rtx *, enum machine_mode);
#ifdef RTX_CODE
extern bool mep_expand_setcc (rtx *);
extern rtx mep_expand_cbranch (rtx *);
+extern bool mep_legitimate_constant_p (rtx);
#endif
extern const char *mep_emit_cbranch (rtx *, int);
extern void mep_expand_call (rtx *, int);
diff --git a/gcc/config/mep/mep.c b/gcc/config/mep/mep.c
index a473328254d..4c37d38f0b0 100644
--- a/gcc/config/mep/mep.c
+++ b/gcc/config/mep/mep.c
@@ -1211,6 +1211,20 @@ mep_multi_slot (rtx x)
}
+bool
+mep_legitimate_constant_p (rtx x)
+{
+ /* We can't convert symbol values to gp- or tp-rel values after
+ reload, as reload might have used $gp or $tp for other
+ purposes. */
+ if (GET_CODE (x) == SYMBOL_REF && (reload_in_progress || reload_completed))
+ {
+ char e = mep_section_tag (x);
+ return (e != 't' && e != 'b');
+ }
+ return 1;
+}
+
/* Be careful not to use macros that need to be compiled one way for
strict, and another way for not-strict, like REG_OK_FOR_BASE_P. */
@@ -1982,7 +1996,7 @@ mep_emit_cbranch (rtx *operands, int ne)
{
if (GET_CODE (operands[1]) == REG)
return ne ? "bne\t%0, %1, %l2" : "beq\t%0, %1, %l2";
- else if (INTVAL (operands[1]) == 0)
+ else if (INTVAL (operands[1]) == 0 && !mep_vliw_function_p(cfun->decl))
return ne ? "bnez\t%0, %l2" : "beqz\t%0, %l2";
else
return ne ? "bnei\t%0, %1, %l2" : "beqi\t%0, %1, %l2";
@@ -3297,6 +3311,7 @@ const conversions[] =
{ 0, "m+ri", "3(2)" },
{ 0, "mr", "(1)" },
{ 0, "ms", "(1)" },
+ { 0, "ml", "(1)" },
{ 0, "mLrs", "%lo(3)(2)" },
{ 0, "mLr+si", "%lo(4+5)(2)" },
{ 0, "m+ru2s", "%tpoff(5)(2)" },
@@ -4563,6 +4578,8 @@ mep_encode_section_info (tree decl, rtx rtl, int first)
idp = get_identifier (newname);
XEXP (rtl, 0) =
gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
+ SYMBOL_REF_WEAK (XEXP (rtl, 0)) = DECL_WEAK (decl);
+ SET_SYMBOL_REF_DECL (XEXP (rtl, 0), decl);
switch (encoding)
{
diff --git a/gcc/config/mep/mep.h b/gcc/config/mep/mep.h
index cb09c308d50..fff79626807 100644
--- a/gcc/config/mep/mep.h
+++ b/gcc/config/mep/mep.h
@@ -599,7 +599,8 @@ typedef struct
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
-#define LEGITIMATE_CONSTANT_P(X) 1
+#define LEGITIMATE_CONSTANT_P(X) \
+ mep_legitimate_constant_p(X)
#define SELECT_CC_MODE(OP, X, Y) CCmode
@@ -620,6 +621,8 @@ typedef struct
#define USE_SELECT_SECTION_FOR_FUNCTIONS 1
+#define JUMP_TABLES_IN_TEXT_SECTION 1
+
#define TARGET_ASM_FILE_END mep_file_cleanups
#define ASM_APP_ON "#APP\n"
diff --git a/gcc/config/mep/mep.md b/gcc/config/mep/mep.md
index 20beef6b438..773a9a0aa14 100644
--- a/gcc/config/mep/mep.md
+++ b/gcc/config/mep/mep.md
@@ -2192,7 +2192,7 @@
(use (reg:SI LP_REGNO))]
""
"#"
- "reload_completed"
+ "epilogue_completed"
[(const_int 1)]
"mep_emit_eh_epilogue (operands); DONE;"
[(set_attr "slot" "multi")])
diff --git a/gcc/config/mips/mips-dsp.md b/gcc/config/mips/mips-dsp.md
index 5112582d3a2..ff2004ccb54 100644
--- a/gcc/config/mips/mips-dsp.md
+++ b/gcc/config/mips/mips-dsp.md
@@ -1102,11 +1102,10 @@
(define_insn "mips_bposge"
[(set (pc)
(if_then_else (ge (reg:CCDSP CCDSP_PO_REGNUM)
- (match_operand:SI 0 "immediate_operand" "I"))
- (label_ref (match_operand 1 "" ""))
+ (match_operand:SI 1 "immediate_operand" "I"))
+ (label_ref (match_operand 0 "" ""))
(pc)))]
"ISA_HAS_DSP"
- "%*bposge%0\t%1%/"
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ "%*bposge%1\t%0%/"
+ [(set_attr "type" "branch")])
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index a1e28ce23c6..91fa72974e8 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -219,7 +219,10 @@ extern rtx mips_subword (rtx, bool);
extern bool mips_split_64bit_move_p (rtx, rtx);
extern void mips_split_doubleword_move (rtx, rtx);
extern const char *mips_output_move (rtx, rtx);
-extern void mips_restore_gp (rtx);
+extern bool mips_cfun_has_cprestore_slot_p (void);
+extern bool mips_cprestore_address_p (rtx, bool);
+extern void mips_save_gp_to_cprestore_slot (rtx, rtx, rtx, rtx);
+extern void mips_restore_gp_from_cprestore_slot (rtx);
#ifdef RTX_CODE
extern void mips_expand_scc (rtx *);
extern void mips_expand_conditional_branch (rtx *);
@@ -276,7 +279,9 @@ extern bool mips_small_data_pattern_p (rtx);
extern rtx mips_rewrite_small_data (rtx);
extern HOST_WIDE_INT mips_initial_elimination_offset (int, int);
extern rtx mips_return_addr (int, rtx);
+extern bool mips_must_initialize_gp_p (void);
extern enum mips_loadgp_style mips_current_loadgp_style (void);
+extern void mips_emit_save_slot_move (rtx, rtx, rtx);
extern void mips_expand_prologue (void);
extern void mips_expand_before_return (void);
extern void mips_expand_epilogue (bool);
@@ -296,7 +301,7 @@ extern int mips_register_move_cost (enum machine_mode, enum reg_class,
enum reg_class);
extern int mips_adjust_insn_length (rtx, int);
-extern const char *mips_output_load_label (void);
+extern void mips_output_load_label (rtx);
extern const char *mips_output_conditional_branch (rtx, rtx *, const char *,
const char *);
extern const char *mips_output_order_conditional_branch (rtx, rtx *, bool);
@@ -334,6 +339,7 @@ extern void mips_expand_atomic_qihi (union mips_gen_fn_ptrs,
extern void mips_expand_vector_init (rtx, rtx);
+extern bool mips_eh_uses (unsigned int);
extern bool mips_epilogue_uses (unsigned int);
extern void mips_final_prescan_insn (rtx, rtx *, int);
diff --git a/gcc/config/mips/mips-ps-3d.md b/gcc/config/mips/mips-ps-3d.md
index 98932d85b11..c13c7a69b28 100644
--- a/gcc/config/mips/mips-ps-3d.md
+++ b/gcc/config/mips/mips-ps-3d.md
@@ -439,50 +439,46 @@
; Branch on Any of Four Floating Point Condition Codes True
(define_insn "bc1any4t"
[(set (pc)
- (if_then_else (ne (match_operand:CCV4 0 "register_operand" "z")
+ (if_then_else (ne (match_operand:CCV4 1 "register_operand" "z")
(const_int 0))
- (label_ref (match_operand 1 "" ""))
+ (label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
- "%*bc1any4t\t%0,%1%/"
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ "%*bc1any4t\t%1,%0%/"
+ [(set_attr "type" "branch")])
; Branch on Any of Four Floating Point Condition Codes False
(define_insn "bc1any4f"
[(set (pc)
- (if_then_else (ne (match_operand:CCV4 0 "register_operand" "z")
+ (if_then_else (ne (match_operand:CCV4 1 "register_operand" "z")
(const_int -1))
- (label_ref (match_operand 1 "" ""))
+ (label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
- "%*bc1any4f\t%0,%1%/"
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ "%*bc1any4f\t%1,%0%/"
+ [(set_attr "type" "branch")])
; Branch on Any of Two Floating Point Condition Codes True
(define_insn "bc1any2t"
[(set (pc)
- (if_then_else (ne (match_operand:CCV2 0 "register_operand" "z")
+ (if_then_else (ne (match_operand:CCV2 1 "register_operand" "z")
(const_int 0))
- (label_ref (match_operand 1 "" ""))
+ (label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
- "%*bc1any2t\t%0,%1%/"
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ "%*bc1any2t\t%1,%0%/"
+ [(set_attr "type" "branch")])
; Branch on Any of Two Floating Point Condition Codes False
(define_insn "bc1any2f"
[(set (pc)
- (if_then_else (ne (match_operand:CCV2 0 "register_operand" "z")
+ (if_then_else (ne (match_operand:CCV2 1 "register_operand" "z")
(const_int -1))
- (label_ref (match_operand 1 "" ""))
+ (label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
- "%*bc1any2f\t%0,%1%/"
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ "%*bc1any2f\t%1,%0%/"
+ [(set_attr "type" "branch")])
; Used to access one register in a CCV2 pair. Operand 0 is the register
; pair and operand 1 is the index of the register we want (a CONST_INT).
@@ -497,45 +493,43 @@
(define_insn "*branch_upper_lower"
[(set (pc)
(if_then_else
- (match_operator 0 "equality_operator"
+ (match_operator 1 "equality_operator"
[(unspec:CC [(match_operand:CCV2 2 "register_operand" "z")
(match_operand 3 "const_int_operand")]
UNSPEC_SINGLE_CC)
(const_int 0)])
- (label_ref (match_operand 1 "" ""))
+ (label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_HARD_FLOAT"
{
operands[2]
= gen_rtx_REG (CCmode, REGNO (operands[2]) + INTVAL (operands[3]));
return mips_output_conditional_branch (insn, operands,
- MIPS_BRANCH ("b%F0", "%2,%1"),
- MIPS_BRANCH ("b%W0", "%2,%1"));
+ MIPS_BRANCH ("b%F1", "%2,%0"),
+ MIPS_BRANCH ("b%W1", "%2,%0"));
}
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ [(set_attr "type" "branch")])
; As above, but with the sense of the condition reversed.
(define_insn "*branch_upper_lower_inverted"
[(set (pc)
(if_then_else
- (match_operator 0 "equality_operator"
+ (match_operator 1 "equality_operator"
[(unspec:CC [(match_operand:CCV2 2 "register_operand" "z")
(match_operand 3 "const_int_operand")]
UNSPEC_SINGLE_CC)
(const_int 0)])
(pc)
- (label_ref (match_operand 1 "" ""))))]
+ (label_ref (match_operand 0 "" ""))))]
"TARGET_HARD_FLOAT"
{
operands[2]
= gen_rtx_REG (CCmode, REGNO (operands[2]) + INTVAL (operands[3]));
return mips_output_conditional_branch (insn, operands,
- MIPS_BRANCH ("b%W0", "%2,%1"),
- MIPS_BRANCH ("b%F0", "%2,%1"));
+ MIPS_BRANCH ("b%W1", "%2,%0"),
+ MIPS_BRANCH ("b%F1", "%2,%0"));
}
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ [(set_attr "type" "branch")])
;----------------------------------------------------------------------------
; Floating Point Reduced Precision Reciprocal Square Root Instructions.
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 958abce0815..2b0df8f0adf 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -307,6 +307,10 @@ struct GTY(()) machine_function {
if the function doesn't need one. */
unsigned int global_pointer;
+ /* How many instructions it takes to load a label into $AT, or 0 if
+ this property hasn't yet been calculated. */
+ unsigned int load_label_length;
+
/* True if mips_adjust_insn_length should ignore an instruction's
hazard attribute. */
bool ignore_hazard_length_p;
@@ -315,8 +319,23 @@ struct GTY(()) machine_function {
.set nomacro. */
bool all_noreorder_p;
- /* True if the function is known to have an instruction that needs $gp. */
- bool has_gp_insn_p;
+ /* True if the function has "inflexible" and "flexible" references
+ to the global pointer. See mips_cfun_has_inflexible_gp_ref_p
+ and mips_cfun_has_flexible_gp_ref_p for details. */
+ bool has_inflexible_gp_insn_p;
+ bool has_flexible_gp_insn_p;
+
+ /* True if the function's prologue must load the global pointer
+ value into pic_offset_table_rtx and store the same value in
+ the function's cprestore slot (if any). Even if this value
+ is currently false, we may decide to set it to true later;
+ see mips_must_initialize_gp_p () for details. */
+ bool must_initialize_gp_p;
+
+ /* True if the current function must restore $gp after any potential
+ clobber. This value is only meaningful during the first post-epilogue
+ split_insns pass; see mips_must_initialize_gp_p () for details. */
+ bool must_restore_gp_when_clobbered_p;
/* True if we have emitted an instruction to initialize
mips16_gp_pseudo_rtx. */
@@ -6313,9 +6332,7 @@ mips_expand_call (enum mips_call_type type, rtx result, rtx addr,
{
rtx (*fn) (rtx, rtx);
- if (type == MIPS_CALL_EPILOGUE && TARGET_SPLIT_CALLS)
- fn = gen_call_split;
- else if (type == MIPS_CALL_SIBCALL)
+ if (type == MIPS_CALL_SIBCALL)
fn = gen_sibcall_internal;
else
fn = gen_call_internal;
@@ -6328,9 +6345,7 @@ mips_expand_call (enum mips_call_type type, rtx result, rtx addr,
rtx (*fn) (rtx, rtx, rtx, rtx);
rtx reg1, reg2;
- if (type == MIPS_CALL_EPILOGUE && TARGET_SPLIT_CALLS)
- fn = gen_call_value_multiple_split;
- else if (type == MIPS_CALL_SIBCALL)
+ if (type == MIPS_CALL_SIBCALL)
fn = gen_sibcall_value_multiple_internal;
else
fn = gen_call_value_multiple_internal;
@@ -6343,9 +6358,7 @@ mips_expand_call (enum mips_call_type type, rtx result, rtx addr,
{
rtx (*fn) (rtx, rtx, rtx);
- if (type == MIPS_CALL_EPILOGUE && TARGET_SPLIT_CALLS)
- fn = gen_call_value_split;
- else if (type == MIPS_CALL_SIBCALL)
+ if (type == MIPS_CALL_SIBCALL)
fn = gen_sibcall_value_internal;
else
fn = gen_call_value_internal;
@@ -6375,7 +6388,7 @@ mips_split_call (rtx insn, rtx call_pattern)
/* Pick a temporary register that is suitable for both MIPS16 and
non-MIPS16 code. $4 and $5 are used for returning complex double
values in soft-float code, so $6 is the first suitable candidate. */
- mips_restore_gp (gen_rtx_REG (Pmode, GP_ARG_FIRST + 2));
+ mips_restore_gp_from_cprestore_slot (gen_rtx_REG (Pmode, GP_ARG_FIRST + 2));
}
/* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */
@@ -8566,42 +8579,131 @@ mips16e_output_save_restore (rtx pattern, HOST_WIDE_INT adjust)
return buffer;
}
-/* Return true if the current function has an insn that implicitly
- refers to $gp. */
+/* Return true if the current function returns its value in a floating-point
+ register in MIPS16 mode. */
static bool
-mips_function_has_gp_insn (void)
+mips16_cfun_returns_in_fpr_p (void)
{
- /* Don't bother rechecking if we found one last time. */
- if (!cfun->machine->has_gp_insn_p)
- {
- rtx insn;
+ tree return_type = DECL_RESULT (current_function_decl);
+ return (TARGET_MIPS16
+ && TARGET_HARD_FLOAT_ABI
+ && !aggregate_value_p (return_type, current_function_decl)
+ && mips_return_mode_in_fpr_p (DECL_MODE (return_type)));
+}
+/* Return true if predicate PRED is true for at least one instruction.
+ Cache the result in *CACHE, and assume that the result is true
+ if *CACHE is already true. */
+
+static bool
+mips_find_gp_ref (bool *cache, bool (*pred) (rtx))
+{
+ rtx insn;
+
+ if (!*cache)
+ {
push_topmost_sequence ();
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if (USEFUL_INSN_P (insn)
- && (get_attr_got (insn) != GOT_UNSET
- || mips_small_data_pattern_p (PATTERN (insn))))
+ if (USEFUL_INSN_P (insn) && pred (insn))
{
- cfun->machine->has_gp_insn_p = true;
+ *cache = true;
break;
}
pop_topmost_sequence ();
}
- return cfun->machine->has_gp_insn_p;
+ return *cache;
}
-/* Return true if the current function returns its value in a floating-point
- register in MIPS16 mode. */
+/* Return true if INSN refers to the global pointer in an "inflexible" way.
+ See mips_cfun_has_inflexible_gp_ref_p for details. */
static bool
-mips16_cfun_returns_in_fpr_p (void)
+mips_insn_has_inflexible_gp_ref_p (rtx insn)
{
- tree return_type = DECL_RESULT (current_function_decl);
- return (TARGET_MIPS16
- && TARGET_HARD_FLOAT_ABI
- && !aggregate_value_p (return_type, current_function_decl)
- && mips_return_mode_in_fpr_p (DECL_MODE (return_type)));
+ /* Uses of pic_offset_table_rtx in CALL_INSN_FUNCTION_USAGE
+ indicate that the target could be a traditional MIPS
+ lazily-binding stub. */
+ return find_reg_fusage (insn, USE, pic_offset_table_rtx);
+}
+
+/* Return true if the current function refers to the global pointer
+ in a way that forces $28 to be valid. This means that we can't
+ change the choice of global pointer, even for NewABI code.
+
+ One example of this (and one which needs several checks) is that
+ $28 must be valid when calling traditional MIPS lazy-binding stubs.
+ (This restriction does not apply to PLTs.) */
+
+static bool
+mips_cfun_has_inflexible_gp_ref_p (void)
+{
+ /* If the function has a nonlocal goto, $28 must hold the correct
+ global pointer for the target function. That is, the target
+ of the goto implicitly uses $28. */
+ if (crtl->has_nonlocal_goto)
+ return true;
+
+ if (TARGET_ABICALLS_PIC2)
+ {
+ /* Symbolic accesses implicitly use the global pointer unless
+ -mexplicit-relocs is in effect. JAL macros to symbolic addresses
+ might go to traditional MIPS lazy-binding stubs. */
+ if (!TARGET_EXPLICIT_RELOCS)
+ return true;
+
+ /* FUNCTION_PROFILER includes a JAL to _mcount, which again
+ can be lazily-bound. */
+ if (crtl->profile)
+ return true;
+
+ /* MIPS16 functions that return in FPRs need to call an
+ external libgcc routine. This call is only made explict
+ during mips_expand_epilogue, and it too might be lazily bound. */
+ if (mips16_cfun_returns_in_fpr_p ())
+ return true;
+ }
+
+ return mips_find_gp_ref (&cfun->machine->has_inflexible_gp_insn_p,
+ mips_insn_has_inflexible_gp_ref_p);
+}
+
+/* Return true if INSN refers to the global pointer in a "flexible" way.
+ See mips_cfun_has_flexible_gp_ref_p for details. */
+
+static bool
+mips_insn_has_flexible_gp_ref_p (rtx insn)
+{
+ return (get_attr_got (insn) != GOT_UNSET
+ || mips_small_data_pattern_p (PATTERN (insn))
+ || reg_overlap_mentioned_p (pic_offset_table_rtx, PATTERN (insn)));
+}
+
+/* Return true if the current function references the global pointer,
+ but if those references do not inherently require the global pointer
+ to be $28. Assume !mips_cfun_has_inflexible_gp_ref_p (). */
+
+static bool
+mips_cfun_has_flexible_gp_ref_p (void)
+{
+ /* Reload can sometimes introduce constant pool references
+ into a function that otherwise didn't need them. For example,
+ suppose we have an instruction like:
+
+ (set (reg:DF R1) (float:DF (reg:SI R2)))
+
+ If R2 turns out to be a constant such as 1, the instruction may
+ have a REG_EQUAL note saying that R1 == 1.0. Reload then has
+ the option of using this constant if R2 doesn't get allocated
+ to a register.
+
+ In cases like these, reload will have added the constant to the
+ pool but no instruction will yet refer to it. */
+ if (TARGET_ABICALLS_PIC2 && !reload_completed && crtl->uses_const_pool)
+ return true;
+
+ return mips_find_gp_ref (&cfun->machine->has_flexible_gp_insn_p,
+ mips_insn_has_flexible_gp_ref_p);
}
/* Return the register that should be used as the global pointer
@@ -8617,57 +8719,18 @@ mips_global_pointer (void)
if (!TARGET_USE_GOT)
return GLOBAL_POINTER_REGNUM;
- /* We must always provide $gp when it is used implicitly. */
- if (!TARGET_EXPLICIT_RELOCS)
- return GLOBAL_POINTER_REGNUM;
-
- /* FUNCTION_PROFILER includes a jal macro, so we need to give it
- a valid gp. */
- if (crtl->profile)
- return GLOBAL_POINTER_REGNUM;
-
- /* If the function has a nonlocal goto, $gp must hold the correct
- global pointer for the target function. */
- if (crtl->has_nonlocal_goto)
+ /* If there are inflexible references to $gp, we must use the
+ standard register. */
+ if (mips_cfun_has_inflexible_gp_ref_p ())
return GLOBAL_POINTER_REGNUM;
- /* There's no need to initialize $gp if it isn't referenced now,
- and if we can be sure that no new references will be added during
- or after reload. */
- if (!df_regs_ever_live_p (GLOBAL_POINTER_REGNUM)
- && !mips_function_has_gp_insn ())
- {
- /* The function doesn't use $gp at the moment. If we're generating
- -call_nonpic code, no new uses will be introduced during or after
- reload. */
- if (TARGET_ABICALLS_PIC0)
- return INVALID_REGNUM;
-
- /* We need to handle the following implicit gp references:
-
- - Reload can sometimes introduce constant pool references
- into a function that otherwise didn't need them. For example,
- suppose we have an instruction like:
-
- (set (reg:DF R1) (float:DF (reg:SI R2)))
-
- If R2 turns out to be constant such as 1, the instruction may
- have a REG_EQUAL note saying that R1 == 1.0. Reload then has
- the option of using this constant if R2 doesn't get allocated
- to a register.
-
- In cases like these, reload will have added the constant to the
- pool but no instruction will yet refer to it.
+ /* If there are no current references to $gp, then the only uses
+ we can introduce later are those involved in long branches. */
+ if (TARGET_ABSOLUTE_JUMPS && !mips_cfun_has_flexible_gp_ref_p ())
+ return INVALID_REGNUM;
- - MIPS16 functions that return in FPRs need to call an
- external libgcc routine. */
- if (!crtl->uses_const_pool
- && !mips16_cfun_returns_in_fpr_p ())
- return INVALID_REGNUM;
- }
-
- /* We need a global pointer, but perhaps we can use a call-clobbered
- register instead of $gp. */
+ /* If the global pointer is call-saved, try to use a call-clobbered
+ alternative. */
if (TARGET_CALL_SAVED_GP && current_function_is_leaf)
for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
if (!df_regs_ever_live_p (regno)
@@ -8679,6 +8742,119 @@ mips_global_pointer (void)
return GLOBAL_POINTER_REGNUM;
}
+/* Return true if current function's prologue must load the global
+ pointer value into pic_offset_table_rtx and store the same value in
+ the function's cprestore slot (if any).
+
+ One problem we have to deal with is that, when emitting GOT-based
+ position independent code, long-branch sequences will need to load
+ the address of the branch target from the GOT. We don't know until
+ the very end of compilation whether (and where) the function needs
+ long branches, so we must ensure that _any_ branch can access the
+ global pointer in some form. However, we do not want to pessimize
+ the usual case in which all branches are short.
+
+ We handle this as follows:
+
+ (1) During reload, we set cfun->machine->global_pointer to
+ INVALID_REGNUM if we _know_ that the current function
+ doesn't need a global pointer. This is only valid if
+ long branches don't need the GOT.
+
+ Otherwise, we assume that we might need a global pointer
+ and pick an appropriate register.
+
+ (2) If cfun->machine->global_pointer != INVALID_REGNUM,
+ we ensure that the global pointer is available at every
+ block boundary bar entry and exit. We do this in one of two ways:
+
+ - If the function has a cprestore slot, we ensure that this
+ slot is valid at every branch. However, as explained in
+ point (6) below, there is no guarantee that pic_offset_table_rtx
+ itself is valid if new uses of the global pointer are introduced
+ after the first post-epilogue split.
+
+ We guarantee that the cprestore slot is valid by loading it
+ into a fake register, CPRESTORE_SLOT_REGNUM. We then make
+ this register live at every block boundary bar function entry
+ and exit. It is then invalid to move the load (and thus the
+ preceding store) across a block boundary.
+
+ - If the function has no cprestore slot, we guarantee that
+ pic_offset_table_rtx itself is valid at every branch.
+
+ See mips_eh_uses for the handling of the register liveness.
+
+ (3) During prologue and epilogue generation, we emit "ghost"
+ placeholder instructions to manipulate the global pointer.
+
+ (4) During prologue generation, we set cfun->machine->must_initialize_gp_p
+ and cfun->machine->must_restore_gp_when_clobbered_p if we already know
+ that the function needs a global pointer. (There is no need to set
+ them earlier than this, and doing it as late as possible leads to
+ fewer false positives.)
+
+ (5) If cfun->machine->must_initialize_gp_p is true during a
+ split_insns pass, we split the ghost instructions into real
+ instructions. These split instructions can then be optimized in
+ the usual way. Otherwise, we keep the ghost instructions intact,
+ and optimize for the case where they aren't needed. We still
+ have the option of splitting them later, if we need to introduce
+ new uses of the global pointer.
+
+ For example, the scheduler ignores a ghost instruction that
+ stores $28 to the stack, but it handles the split form of
+ the ghost instruction as an ordinary store.
+
+ (6) [OldABI only.] If cfun->machine->must_restore_gp_when_clobbered_p
+ is true during the first post-epilogue split_insns pass, we split
+ calls and restore_gp patterns into instructions that explicitly
+ load pic_offset_table_rtx from the cprestore slot. Otherwise,
+ we split these patterns into instructions that _don't_ load from
+ the cprestore slot.
+
+ If cfun->machine->must_restore_gp_when_clobbered_p is true at the
+ time of the split, then any instructions that exist at that time
+ can make free use of pic_offset_table_rtx. However, if we want
+ to introduce new uses of the global pointer after the split,
+ we must explicitly load the value from the cprestore slot, since
+ pic_offset_table_rtx itself might not be valid at a given point
+ in the function.
+
+ The idea is that we want to be able to delete redundant
+ loads from the cprestore slot in the usual case where no
+ long branches are needed.
+
+ (7) If cfun->machine->must_initialize_gp_p is still false at the end
+ of md_reorg, we decide whether the global pointer is needed for
+ long branches. If so, we set cfun->machine->must_initialize_gp_p
+ to true and split the ghost instructions into real instructions
+ at that stage.
+
+ Note that the ghost instructions must have a zero length for three reasons:
+
+ - Giving the length of the underlying $gp sequence might cause
+ us to use long branches in cases where they aren't really needed.
+
+ - They would perturb things like alignment calculations.
+
+ - More importantly, the hazard detection in md_reorg relies on
+ empty instructions having a zero length.
+
+ If we find a long branch and split the ghost instructions at the
+ end of md_reorg, the split could introduce more long branches.
+ That isn't a problem though, because we still do the split before
+ the final shorten_branches pass.
+
+ This is extremely ugly, but it seems like the best compromise between
+ correctness and efficiency. */
+
+bool
+mips_must_initialize_gp_p (void)
+{
+ return cfun->machine->must_initialize_gp_p;
+}
+
/* Return true if REGNO is a register that is ordinarily call-clobbered
but must nevertheless be preserved by an interrupt handler. */
@@ -9198,48 +9374,118 @@ mips_set_return_address (rtx address, rtx scratch)
mips_emit_move (gen_frame_mem (GET_MODE (address), slot_address), address);
}
-/* Return a MEM rtx for the cprestore slot, using TEMP as a temporary base
- register if need be. */
+/* Return true if the current function has a cprestore slot. */
-static rtx
-mips_cprestore_slot (rtx temp)
+bool
+mips_cfun_has_cprestore_slot_p (void)
+{
+ return (cfun->machine->global_pointer != INVALID_REGNUM
+ && cfun->machine->frame.cprestore_size > 0);
+}
+
+/* Fill *BASE and *OFFSET such that *BASE + *OFFSET refers to the
+ cprestore slot. LOAD_P is true if the caller wants to load from
+ the cprestore slot; it is false if the caller wants to store to
+ the slot. */
+
+static void
+mips_get_cprestore_base_and_offset (rtx *base, HOST_WIDE_INT *offset,
+ bool load_p)
{
const struct mips_frame_info *frame;
- rtx base;
- HOST_WIDE_INT offset;
frame = &cfun->machine->frame;
- if (frame_pointer_needed)
- {
- base = hard_frame_pointer_rtx;
- offset = frame->args_size - frame->hard_frame_pointer_offset;
+ /* .cprestore always uses the stack pointer instead of the frame pointer.
+ We have a free choice for direct stores for non-MIPS16 functions,
+ and for MIPS16 functions whose cprestore slot is in range of the
+ stack pointer. Using the stack pointer would sometimes give more
+ (early) scheduling freedom, but using the frame pointer would
+ sometimes give more (late) scheduling freedom. It's hard to
+ predict which applies to a given function, so let's keep things
+ simple.
+
+ Loads must always use the frame pointer in functions that call
+ alloca, and there's little benefit to using the stack pointer
+ otherwise. */
+ if (frame_pointer_needed && !(TARGET_CPRESTORE_DIRECTIVE && !load_p))
+ {
+ *base = hard_frame_pointer_rtx;
+ *offset = frame->args_size - frame->hard_frame_pointer_offset;
}
else
{
- base = stack_pointer_rtx;
- offset = frame->args_size;
+ *base = stack_pointer_rtx;
+ *offset = frame->args_size;
}
+}
+
+/* Return true if X is the load or store address of the cprestore slot;
+ LOAD_P says which. */
+
+bool
+mips_cprestore_address_p (rtx x, bool load_p)
+{
+ rtx given_base, required_base;
+ HOST_WIDE_INT given_offset, required_offset;
+
+ mips_split_plus (x, &given_base, &given_offset);
+ mips_get_cprestore_base_and_offset (&required_base, &required_offset, load_p);
+ return given_base == required_base && given_offset == required_offset;
+}
+
+/* Return a MEM rtx for the cprestore slot. LOAD_P is true if we are
+ going to load from it, false if we are going to store to it.
+ Use TEMP as a temporary register if need be. */
+
+static rtx
+mips_cprestore_slot (rtx temp, bool load_p)
+{
+ rtx base;
+ HOST_WIDE_INT offset;
+
+ mips_get_cprestore_base_and_offset (&base, &offset, load_p);
return gen_frame_mem (Pmode, mips_add_offset (temp, base, offset));
}
+/* Emit instructions to save global pointer value GP into cprestore
+ slot MEM. OFFSET is the offset that MEM applies to the base register.
+
+ MEM may not be a legitimate address. If it isn't, TEMP is a
+ temporary register that can be used, otherwise it is a SCRATCH. */
+
+void
+mips_save_gp_to_cprestore_slot (rtx mem, rtx offset, rtx gp, rtx temp)
+{
+ if (TARGET_CPRESTORE_DIRECTIVE)
+ {
+ gcc_assert (gp == pic_offset_table_rtx);
+ emit_insn (gen_cprestore (mem, offset));
+ }
+ else
+ mips_emit_move (mips_cprestore_slot (temp, false), gp);
+}
+
/* Restore $gp from its save slot, using TEMP as a temporary base register
- if need be. This function is for o32 and o64 abicalls only. */
+ if need be. This function is for o32 and o64 abicalls only.
+
+ See mips_must_initialize_gp_p for details about how we manage the
+ global pointer. */
void
-mips_restore_gp (rtx temp)
+mips_restore_gp_from_cprestore_slot (rtx temp)
{
- gcc_assert (TARGET_ABICALLS && TARGET_OLDABI);
+ gcc_assert (TARGET_ABICALLS && TARGET_OLDABI && epilogue_completed);
- if (cfun->machine->global_pointer == INVALID_REGNUM)
+ if (!cfun->machine->must_restore_gp_when_clobbered_p)
return;
if (TARGET_MIPS16)
{
- mips_emit_move (temp, mips_cprestore_slot (temp));
+ mips_emit_move (temp, mips_cprestore_slot (temp, true));
mips_emit_move (pic_offset_table_rtx, temp);
}
else
- mips_emit_move (pic_offset_table_rtx, mips_cprestore_slot (temp));
+ mips_emit_move (pic_offset_table_rtx, mips_cprestore_slot (temp, true));
if (!TARGET_EXPLICIT_RELOCS)
emit_insn (gen_blockage ());
}
@@ -9327,6 +9573,89 @@ mips_for_each_saved_gpr_and_fpr (HOST_WIDE_INT sp_offset,
offset -= GET_MODE_SIZE (fpr_mode);
}
}
+
+/* Return true if a move between register REGNO and its save slot (MEM)
+ can be done in a single move. LOAD_P is true if we are loading
+ from the slot, false if we are storing to it. */
+
+static bool
+mips_direct_save_slot_move_p (unsigned int regno, rtx mem, bool load_p)
+{
+ /* There is a specific MIPS16 instruction for saving $31 to the stack. */
+ if (TARGET_MIPS16 && !load_p && regno == GP_REG_FIRST + 31)
+ return false;
+
+ return mips_secondary_reload_class (REGNO_REG_CLASS (regno),
+ GET_MODE (mem), mem, load_p) == NO_REGS;
+}
+
+/* Emit a move from SRC to DEST, given that one of them is a register
+ save slot and that the other is a register. TEMP is a temporary
+ GPR of the same mode that is available if need be. */
+
+void
+mips_emit_save_slot_move (rtx dest, rtx src, rtx temp)
+{
+ unsigned int regno;
+ rtx mem;
+
+ if (REG_P (src))
+ {
+ regno = REGNO (src);
+ mem = dest;
+ }
+ else
+ {
+ regno = REGNO (dest);
+ mem = src;
+ }
+
+ if (regno == cfun->machine->global_pointer && !mips_must_initialize_gp_p ())
+ {
+ /* We don't yet know whether we'll need this instruction or not.
+ Postpone the decision by emitting a ghost move. This move
+ is specifically not frame-related; only the split version is. */
+ if (TARGET_64BIT)
+ emit_insn (gen_move_gpdi (dest, src));
+ else
+ emit_insn (gen_move_gpsi (dest, src));
+ return;
+ }
+
+ if (regno == HI_REGNUM)
+ {
+ if (REG_P (dest))
+ {
+ mips_emit_move (temp, src);
+ if (TARGET_64BIT)
+ emit_insn (gen_mthisi_di (gen_rtx_REG (TImode, MD_REG_FIRST),
+ temp, gen_rtx_REG (DImode, LO_REGNUM)));
+ else
+ emit_insn (gen_mthisi_di (gen_rtx_REG (DImode, MD_REG_FIRST),
+ temp, gen_rtx_REG (SImode, LO_REGNUM)));
+ }
+ else
+ {
+ if (TARGET_64BIT)
+ emit_insn (gen_mfhidi_ti (temp,
+ gen_rtx_REG (TImode, MD_REG_FIRST)));
+ else
+ emit_insn (gen_mfhisi_di (temp,
+ gen_rtx_REG (DImode, MD_REG_FIRST)));
+ mips_emit_move (dest, temp);
+ }
+ }
+ else if (mips_direct_save_slot_move_p (regno, mem, mem == src))
+ mips_emit_move (dest, src);
+ else
+ {
+ gcc_assert (!reg_overlap_mentioned_p (dest, temp));
+ mips_emit_move (temp, src);
+ mips_emit_move (dest, temp);
+ }
+ if (MEM_P (dest))
+ mips_set_frame_expr (mips_frame_set (dest, src));
+}
/* If we're generating n32 or n64 abicalls, and the current function
does not use $28 as its global pointer, emit a cplocal directive.
@@ -9336,7 +9665,7 @@ static void
mips_output_cplocal (void)
{
if (!TARGET_EXPLICIT_RELOCS
- && cfun->machine->global_pointer != INVALID_REGNUM
+ && mips_must_initialize_gp_p ()
&& cfun->machine->global_pointer != GLOBAL_POINTER_REGNUM)
output_asm_insn (".cplocal %+", 0);
}
@@ -9408,7 +9737,8 @@ mips_output_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
/* Handle the initialization of $gp for SVR4 PIC, if applicable.
Also emit the ".set noreorder; .set nomacro" sequence for functions
that need it. */
- if (mips_current_loadgp_style () == LOADGP_OLDABI)
+ if (mips_must_initialize_gp_p ()
+ && mips_current_loadgp_style () == LOADGP_OLDABI)
{
if (TARGET_MIPS16)
{
@@ -9490,33 +9820,7 @@ mips_save_reg (rtx reg, rtx mem)
mips_set_frame_expr (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, x1, x2)));
}
else
- {
- if (REGNO (reg) == HI_REGNUM)
- {
- if (TARGET_64BIT)
- emit_insn (gen_mfhidi_ti (MIPS_PROLOGUE_TEMP (DImode),
- gen_rtx_REG (TImode, MD_REG_FIRST)));
- else
- emit_insn (gen_mfhisi_di (MIPS_PROLOGUE_TEMP (SImode),
- gen_rtx_REG (DImode, MD_REG_FIRST)));
- mips_emit_move (mem, MIPS_PROLOGUE_TEMP (GET_MODE (reg)));
- }
- else if ((TARGET_MIPS16
- && REGNO (reg) != GP_REG_FIRST + 31
- && !M16_REG_P (REGNO (reg)))
- || ACC_REG_P (REGNO (reg)))
- {
- /* If the register has no direct store instruction, move it
- through a temporary. Note that there's a special MIPS16
- instruction to save $31. */
- mips_emit_move (MIPS_PROLOGUE_TEMP (GET_MODE (reg)), reg);
- mips_emit_move (mem, MIPS_PROLOGUE_TEMP (GET_MODE (reg)));
- }
- else
- mips_emit_move (mem, reg);
-
- mips_set_frame_expr (mips_frame_set (mem, reg));
- }
+ mips_emit_save_slot_move (mem, reg, MIPS_PROLOGUE_TEMP (GET_MODE (reg)));
}
/* The __gnu_local_gp symbol. */
@@ -9599,7 +9903,19 @@ mips_expand_prologue (void)
rtx insn;
if (cfun->machine->global_pointer != INVALID_REGNUM)
- SET_REGNO (pic_offset_table_rtx, cfun->machine->global_pointer);
+ {
+ /* Check whether an insn uses pic_offset_table_rtx, either explicitly
+ or implicitly. If so, we can commit to using a global pointer
+ straight away, otherwise we need to defer the decision. */
+ if (mips_cfun_has_inflexible_gp_ref_p ()
+ || mips_cfun_has_flexible_gp_ref_p ())
+ {
+ cfun->machine->must_initialize_gp_p = true;
+ cfun->machine->must_restore_gp_when_clobbered_p = true;
+ }
+
+ SET_REGNO (pic_offset_table_rtx, cfun->machine->global_pointer);
+ }
frame = &cfun->machine->frame;
size = frame->total_size;
@@ -9801,17 +10117,22 @@ mips_expand_prologue (void)
mips_emit_loadgp ();
/* Initialize the $gp save slot. */
- if (frame->cprestore_size > 0
- && cfun->machine->global_pointer != INVALID_REGNUM)
+ if (mips_cfun_has_cprestore_slot_p ())
{
- if (TARGET_MIPS16)
- mips_emit_move (mips_cprestore_slot (MIPS_PROLOGUE_TEMP (Pmode)),
- MIPS16_PIC_TEMP);
- else if (TARGET_ABICALLS_PIC2)
- emit_insn (gen_cprestore (GEN_INT (frame->args_size)));
- else
- emit_move_insn (mips_cprestore_slot (MIPS_PROLOGUE_TEMP (Pmode)),
- pic_offset_table_rtx);
+ rtx base, mem, gp, temp;
+ HOST_WIDE_INT offset;
+
+ mips_get_cprestore_base_and_offset (&base, &offset, false);
+ mem = gen_frame_mem (Pmode, plus_constant (base, offset));
+ gp = TARGET_MIPS16 ? MIPS16_PIC_TEMP : pic_offset_table_rtx;
+ temp = (SMALL_OPERAND (offset)
+ ? gen_rtx_SCRATCH (Pmode)
+ : MIPS_PROLOGUE_TEMP (Pmode));
+ emit_insn (gen_potential_cprestore (mem, GEN_INT (offset), gp, temp));
+
+ mips_get_cprestore_base_and_offset (&base, &offset, true);
+ mem = gen_frame_mem (Pmode, plus_constant (base, offset));
+ emit_insn (gen_use_cprestore (mem));
}
/* We need to search back to the last use of K0 or K1. */
@@ -9844,27 +10165,7 @@ mips_restore_reg (rtx reg, rtx mem)
if (TARGET_MIPS16 && REGNO (reg) == GP_REG_FIRST + 31)
reg = gen_rtx_REG (GET_MODE (reg), GP_REG_FIRST + 7);
- if (REGNO (reg) == HI_REGNUM)
- {
- mips_emit_move (MIPS_EPILOGUE_TEMP (GET_MODE (reg)), mem);
- if (TARGET_64BIT)
- emit_insn (gen_mthisi_di (gen_rtx_REG (TImode, MD_REG_FIRST),
- MIPS_EPILOGUE_TEMP (DImode),
- gen_rtx_REG (DImode, LO_REGNUM)));
- else
- emit_insn (gen_mthisi_di (gen_rtx_REG (DImode, MD_REG_FIRST),
- MIPS_EPILOGUE_TEMP (SImode),
- gen_rtx_REG (SImode, LO_REGNUM)));
- }
- else if ((TARGET_MIPS16 && !M16_REG_P (REGNO (reg)))
- || ACC_REG_P (REGNO (reg)))
- {
- /* Can't restore directly; move through a temporary. */
- mips_emit_move (MIPS_EPILOGUE_TEMP (GET_MODE (reg)), mem);
- mips_emit_move (reg, MIPS_EPILOGUE_TEMP (GET_MODE (reg)));
- }
- else
- mips_emit_move (reg, mem);
+ mips_emit_save_slot_move (reg, mem, MIPS_EPILOGUE_TEMP (GET_MODE (reg)));
}
/* Emit any instructions needed before a return. */
@@ -10732,12 +11033,112 @@ mips_init_libfuncs (void)
synchronize_libfunc = init_one_libfunc ("__sync_synchronize");
}
+/* Build up a multi-insn sequence that loads label TARGET into $AT. */
+
+static void
+mips_process_load_label (rtx target)
+{
+ rtx base, gp, intop;
+ HOST_WIDE_INT offset;
+
+ mips_multi_start ();
+ switch (mips_abi)
+ {
+ case ABI_N32:
+ mips_multi_add_insn ("lw\t%@,%%got_page(%0)(%+)", target, 0);
+ mips_multi_add_insn ("addiu\t%@,%@,%%got_ofst(%0)", target, 0);
+ break;
+
+ case ABI_64:
+ mips_multi_add_insn ("ld\t%@,%%got_page(%0)(%+)", target, 0);
+ mips_multi_add_insn ("daddiu\t%@,%@,%%got_ofst(%0)", target, 0);
+ break;
+
+ default:
+ gp = pic_offset_table_rtx;
+ if (mips_cfun_has_cprestore_slot_p ())
+ {
+ gp = gen_rtx_REG (Pmode, AT_REGNUM);
+ mips_get_cprestore_base_and_offset (&base, &offset, true);
+ if (!SMALL_OPERAND (offset))
+ {
+ intop = GEN_INT (CONST_HIGH_PART (offset));
+ mips_multi_add_insn ("lui\t%0,%1", gp, intop, 0);
+ mips_multi_add_insn ("addu\t%0,%0,%1", gp, base, 0);
+
+ base = gp;
+ offset = CONST_LOW_PART (offset);
+ }
+ intop = GEN_INT (offset);
+ if (ISA_HAS_LOAD_DELAY)
+ mips_multi_add_insn ("lw\t%0,%1(%2)%#", gp, intop, base, 0);
+ else
+ mips_multi_add_insn ("lw\t%0,%1(%2)", gp, intop, base, 0);
+ }
+ if (ISA_HAS_LOAD_DELAY)
+ mips_multi_add_insn ("lw\t%@,%%got(%0)(%1)%#", target, gp, 0);
+ else
+ mips_multi_add_insn ("lw\t%@,%%got(%0)(%1)", target, gp, 0);
+ mips_multi_add_insn ("addiu\t%@,%@,%%lo(%0)", target, 0);
+ break;
+ }
+}
+
+/* Return the number of instructions needed to load a label into $AT. */
+
+static unsigned int
+mips_load_label_length (void)
+{
+ if (cfun->machine->load_label_length == 0)
+ {
+ mips_process_load_label (pc_rtx);
+ cfun->machine->load_label_length = mips_multi_num_insns;
+ }
+ return cfun->machine->load_label_length;
+}
+
+/* Emit an asm sequence to start a noat block and load the address
+ of a label into $1. */
+
+void
+mips_output_load_label (rtx target)
+{
+ mips_push_asm_switch (&mips_noat);
+ if (TARGET_EXPLICIT_RELOCS)
+ {
+ mips_process_load_label (target);
+ mips_multi_write ();
+ }
+ else
+ {
+ if (Pmode == DImode)
+ output_asm_insn ("dla\t%@,%0", &target);
+ else
+ output_asm_insn ("la\t%@,%0", &target);
+ }
+}
+
/* Return the length of INSN. LENGTH is the initial length computed by
attributes in the machine-description file. */
int
mips_adjust_insn_length (rtx insn, int length)
{
+ /* mips.md uses MAX_PIC_BRANCH_LENGTH as a placeholder for the length
+ of a PIC long-branch sequence. Substitute the correct value. */
+ if (length == MAX_PIC_BRANCH_LENGTH
+ && INSN_CODE (insn) >= 0
+ && get_attr_type (insn) == TYPE_BRANCH)
+ {
+ /* Add the branch-over instruction and its delay slot, if this
+ is a conditional branch. */
+ length = simplejump_p (insn) ? 0 : 8;
+
+ /* Load the label into $AT and jump to it. Ignore the delay
+ slot of the jump. */
+ length += mips_load_label_length () + 4;
+ }
+
/* A unconditional jump has an unfilled delay slot if it is not part
of a sequence. A conditional jump normally has a delay slot, but
does not on MIPS16. */
@@ -10769,38 +11170,9 @@ mips_adjust_insn_length (rtx insn, int length)
return length;
}
-/* Return an asm sequence to start a noat block and load the address
- of a label into $1. */
-
-const char *
-mips_output_load_label (void)
-{
- if (TARGET_EXPLICIT_RELOCS)
- switch (mips_abi)
- {
- case ABI_N32:
- return "%[lw\t%@,%%got_page(%0)(%+)\n\taddiu\t%@,%@,%%got_ofst(%0)";
-
- case ABI_64:
- return "%[ld\t%@,%%got_page(%0)(%+)\n\tdaddiu\t%@,%@,%%got_ofst(%0)";
-
- default:
- if (ISA_HAS_LOAD_DELAY)
- return "%[lw\t%@,%%got(%0)(%+)%#\n\taddiu\t%@,%@,%%lo(%0)";
- return "%[lw\t%@,%%got(%0)(%+)\n\taddiu\t%@,%@,%%lo(%0)";
- }
- else
- {
- if (Pmode == DImode)
- return "%[dla\t%@,%0";
- else
- return "%[la\t%@,%0";
- }
-}
-
/* Return the assembly code for INSN, which has the operands given by
- OPERANDS, and which branches to OPERANDS[1] if some condition is true.
- BRANCH_IF_TRUE is the asm template that should be used if OPERANDS[1]
+ OPERANDS, and which branches to OPERANDS[0] if some condition is true.
+ BRANCH_IF_TRUE is the asm template that should be used if OPERANDS[0]
is in range of a direct branch. BRANCH_IF_FALSE is an inverted
version of BRANCH_IF_TRUE. */
@@ -10812,7 +11184,7 @@ mips_output_conditional_branch (rtx insn, rtx *operands,
unsigned int length;
rtx taken, not_taken;
- gcc_assert (LABEL_P (operands[1]));
+ gcc_assert (LABEL_P (operands[0]));
length = get_attr_length (insn);
if (length <= 8)
@@ -10826,10 +11198,10 @@ mips_output_conditional_branch (rtx insn, rtx *operands,
not use branch-likely instructions. */
mips_branch_likely = false;
not_taken = gen_label_rtx ();
- taken = operands[1];
+ taken = operands[0];
/* Generate the reversed branch to NOT_TAKEN. */
- operands[1] = not_taken;
+ operands[0] = not_taken;
output_asm_insn (branch_if_false, operands);
/* If INSN has a delay slot, we must provide delay slots for both the
@@ -10851,11 +11223,11 @@ mips_output_conditional_branch (rtx insn, rtx *operands,
}
/* Output the unconditional branch to TAKEN. */
- if (length <= 16)
- output_asm_insn ("j\t%0%/", &taken);
+ if (TARGET_ABSOLUTE_JUMPS)
+ output_asm_insn (MIPS_ABSOLUTE_JUMP ("j\t%0%/"), &taken);
else
{
- output_asm_insn (mips_output_load_label (), &taken);
+ mips_output_load_label (taken);
output_asm_insn ("jr\t%@%]%/", 0);
}
@@ -10881,10 +11253,10 @@ mips_output_conditional_branch (rtx insn, rtx *operands,
return "";
}
-/* Return the assembly code for INSN, which branches to OPERANDS[1]
+/* Return the assembly code for INSN, which branches to OPERANDS[0]
if some ordering condition is true. The condition is given by
- OPERANDS[0] if !INVERTED_P, otherwise it is the inverse of
- OPERANDS[0]. OPERANDS[2] is the comparison's first operand;
+ OPERANDS[1] if !INVERTED_P, otherwise it is the inverse of
+ OPERANDS[1]. OPERANDS[2] is the comparison's first operand;
its second is always zero. */
const char *
@@ -10892,17 +11264,17 @@ mips_output_order_conditional_branch (rtx insn, rtx *operands, bool inverted_p)
{
const char *branch[2];
- /* Make BRANCH[1] branch to OPERANDS[1] when the condition is true.
+ /* Make BRANCH[1] branch to OPERANDS[0] when the condition is true.
Make BRANCH[0] branch on the inverse condition. */
- switch (GET_CODE (operands[0]))
+ switch (GET_CODE (operands[1]))
{
/* These cases are equivalent to comparisons against zero. */
case LEU:
inverted_p = !inverted_p;
/* Fall through. */
case GTU:
- branch[!inverted_p] = MIPS_BRANCH ("bne", "%2,%.,%1");
- branch[inverted_p] = MIPS_BRANCH ("beq", "%2,%.,%1");
+ branch[!inverted_p] = MIPS_BRANCH ("bne", "%2,%.,%0");
+ branch[inverted_p] = MIPS_BRANCH ("beq", "%2,%.,%0");
break;
/* These cases are always true or always false. */
@@ -10910,13 +11282,13 @@ mips_output_order_conditional_branch (rtx insn, rtx *operands, bool inverted_p)
inverted_p = !inverted_p;
/* Fall through. */
case GEU:
- branch[!inverted_p] = MIPS_BRANCH ("beq", "%.,%.,%1");
- branch[inverted_p] = MIPS_BRANCH ("bne", "%.,%.,%1");
+ branch[!inverted_p] = MIPS_BRANCH ("beq", "%.,%.,%0");
+ branch[inverted_p] = MIPS_BRANCH ("bne", "%.,%.,%0");
break;
default:
- branch[!inverted_p] = MIPS_BRANCH ("b%C0z", "%2,%1");
- branch[inverted_p] = MIPS_BRANCH ("b%N0z", "%2,%1");
+ branch[!inverted_p] = MIPS_BRANCH ("b%C1z", "%2,%0");
+ branch[inverted_p] = MIPS_BRANCH ("b%N1z", "%2,%0");
break;
}
return mips_output_conditional_branch (insn, operands, branch[1], branch[0]);
@@ -11915,7 +12287,8 @@ mips_variable_issue (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
/* Ignore USEs and CLOBBERs; don't count them against the issue rate. */
if (USEFUL_INSN_P (insn))
{
- more--;
+ if (get_attr_type (insn) != TYPE_GHOST)
+ more--;
if (!reload_completed && TUNE_MACC_CHAINS)
mips_macc_chains_record (insn);
vr4130_last_insn = insn;
@@ -14173,6 +14546,46 @@ mips_reorg_process_insns (void)
htab_delete (htab);
}
+/* If we are using a GOT, but have not decided to use a global pointer yet,
+ see whether we need one to implement long branches. Convert the ghost
+ global-pointer instructions into real ones if so. */
+
+static bool
+mips_expand_ghost_gp_insns (void)
+{
+ rtx insn;
+ int normal_length;
+
+ /* Quick exit if we already know that we will or won't need a
+ global pointer. */
+ if (!TARGET_USE_GOT
+ || cfun->machine->global_pointer == INVALID_REGNUM
+ || mips_must_initialize_gp_p ())
+ return false;
+
+ shorten_branches (get_insns ());
+
+ /* Look for a branch that is longer than normal. The normal length for
+ non-MIPS16 branches is 8, because the length includes the delay slot.
+ It is 4 for MIPS16, because MIPS16 branches are extended instructions,
+ but they have no delay slot. */
+ normal_length = (TARGET_MIPS16 ? 4 : 8);
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ if (JUMP_P (insn)
+ && USEFUL_INSN_P (insn)
+ && get_attr_length (insn) > normal_length)
+ break;
+
+ if (insn == NULL_RTX)
+ return false;
+
+ /* We've now established that we need $gp. */
+ cfun->machine->must_initialize_gp_p = true;
+ split_all_insns_noflow ();
+
+ return true;
+}
+
/* Implement TARGET_MACHINE_DEPENDENT_REORG. */
static void
@@ -14189,6 +14602,10 @@ mips_reorg (void)
&& TUNE_MIPS4130
&& TARGET_VR4130_ALIGN)
vr4130_align_insns ();
+ if (mips_expand_ghost_gp_insns ())
+ /* The expansion could invalidate some of the VR4130 alignment
+ optimizations, but this should be an extremely rare case anyhow. */
+ mips_reorg_process_insns ();
}
/* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
@@ -14222,6 +14639,7 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
TARGET_CALL_SAVED_GP. */
cfun->machine->global_pointer
= TARGET_CALL_SAVED_GP ? 15 : GLOBAL_POINTER_REGNUM;
+ cfun->machine->must_initialize_gp_p = true;
SET_REGNO (pic_offset_table_rtx, cfun->machine->global_pointer);
/* Set up the global pointer for n32 or n64 abicalls. */
@@ -15137,6 +15555,31 @@ mips_order_regs_for_local_alloc (void)
}
}
+/* Implement EH_USES. */
+
+bool
+mips_eh_uses (unsigned int regno)
+{
+ if (reload_completed && !TARGET_ABSOLUTE_JUMPS)
+ {
+ /* We need to force certain registers to be live in order to handle
+ PIC long branches correctly. See mips_must_initialize_gp_p for
+ details. */
+ if (mips_cfun_has_cprestore_slot_p ())
+ {
+ if (regno == CPRESTORE_SLOT_REGNUM)
+ return true;
+ }
+ else
+ {
+ if (cfun->machine->global_pointer == regno)
+ return true;
+ }
+ }
+
+ return false;
+}
+
/* Implement EPILOGUE_USES. */
bool
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 352dbd25618..eda74479ed2 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -161,10 +161,13 @@ enum mips_code_readable_setting {
/* True if the call patterns should be split into a jalr followed by
an instruction to restore $gp. It is only safe to split the load
- from the call when every use of $gp is explicit. */
+ from the call when every use of $gp is explicit.
+
+ See mips_must_initialize_gp_p for details about how we manage the
+ global pointer. */
#define TARGET_SPLIT_CALLS \
- (TARGET_EXPLICIT_RELOCS && TARGET_CALL_CLOBBERED_GP)
+ (TARGET_EXPLICIT_RELOCS && TARGET_CALL_CLOBBERED_GP && epilogue_completed)
/* True if we're generating a form of -mabicalls in which we can use
operators like %hi and %lo to refer to locally-binding symbols.
@@ -202,6 +205,17 @@ enum mips_code_readable_setting {
/* True if TARGET_USE_GOT and if $gp is a call-saved register. */
#define TARGET_CALL_SAVED_GP (TARGET_USE_GOT && !TARGET_CALL_CLOBBERED_GP)
+/* True if we should use .cprestore to store to the cprestore slot.
+
+ We continue to use .cprestore for explicit-reloc code so that JALs
+ inside inline asms will work correctly. */
+#define TARGET_CPRESTORE_DIRECTIVE \
+ (TARGET_ABICALLS_PIC2 && !TARGET_MIPS16)
+
+/* True if we can use the J and JAL instructions. */
+#define TARGET_ABSOLUTE_JUMPS \
+ (!flag_pic || TARGET_ABSOLUTE_ABICALLS)
+
/* True if indirect calls must use register class PIC_FN_ADDR_REG.
This is true for both the PIC and non-PIC VxWorks RTP modes. */
#define TARGET_USE_PIC_FN_ADDR_REG (TARGET_ABICALLS || TARGET_VXWORKS_RTP)
@@ -1300,6 +1314,8 @@ enum mips_code_readable_setting {
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, GP_REG_FIRST + 3)
+#define EH_USES(N) mips_eh_uses (N)
+
/* Offsets recorded in opcodes are a multiple of this alignment factor.
The default for this in 64-bit mode is 8, which causes problems with
SFmode register saves. */
@@ -1543,11 +1559,12 @@ enum mips_code_readable_setting {
- 8 condition code registers
- 2 accumulator registers (hi and lo)
- 32 registers each for coprocessors 0, 2 and 3
- - 3 fake registers:
+ - 4 fake registers:
- ARG_POINTER_REGNUM
- FRAME_POINTER_REGNUM
- GOT_VERSION_REGNUM (see the comment above load_call<mode> for details)
- - 3 dummy entries that were used at various times in the past.
+ - CPRESTORE_SLOT_REGNUM
+ - 2 dummy entries that were used at various times in the past.
- 6 DSP accumulator registers (3 hi-lo pairs) for MIPS DSP ASE
- 6 DSP control registers */
@@ -2661,6 +2678,13 @@ typedef struct mips_args {
#define MIPS_BRANCH(OPCODE, OPERANDS) \
"%*" OPCODE "%?\t" OPERANDS "%/"
+/* Return an asm string that forces INSN to be treated as an absolute
+ J or JAL instruction instead of an assembler macro. */
+#define MIPS_ABSOLUTE_JUMP(INSN) \
+ (TARGET_ABICALLS_PIC2 \
+ ? ".option\tpic0\n\t" INSN "\n\t.option\tpic2" \
+ : INSN)
+
/* Return the asm template for a call. INSN is the instruction's mnemonic
("j" or "jal"), OPERANDS are its operands, and OPNO is the operand number
of the target.
@@ -2675,11 +2699,7 @@ typedef struct mips_args {
? "%*" INSN "\t%" #OPNO "%/" \
: REG_P (OPERANDS[OPNO]) \
? "%*" INSN "r\t%" #OPNO "%/" \
- : TARGET_ABICALLS_PIC2 \
- ? (".option\tpic0\n\t" \
- "%*" INSN "\t%" #OPNO "%/\n\t" \
- ".option\tpic2") \
- : "%*" INSN "\t%" #OPNO "%/")
+ : MIPS_ABSOLUTE_JUMP ("%*" INSN "\t%" #OPNO "%/"))
/* Control the assembler format that we output. */
@@ -2707,7 +2727,7 @@ typedef struct mips_args {
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", \
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", \
"hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4", \
- "$fcc5","$fcc6","$fcc7","", "", "$arg", "$frame", "$fakec", \
+ "$fcc5","$fcc6","$fcc7","", "$cprestore", "$arg", "$frame", "$fakec", \
"$c0r0", "$c0r1", "$c0r2", "$c0r3", "$c0r4", "$c0r5", "$c0r6", "$c0r7", \
"$c0r8", "$c0r9", "$c0r10","$c0r11","$c0r12","$c0r13","$c0r14","$c0r15", \
"$c0r16","$c0r17","$c0r18","$c0r19","$c0r20","$c0r21","$c0r22","$c0r23", \
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index a510e0a7b74..4e1e7852c71 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -29,11 +29,13 @@
(UNSPEC_STORE_WORD 2)
(UNSPEC_GET_FNADDR 3)
(UNSPEC_BLOCKAGE 4)
- (UNSPEC_CPRESTORE 5)
- (UNSPEC_RESTORE_GP 6)
- (UNSPEC_EH_RETURN 7)
- (UNSPEC_CONSTTABLE_INT 8)
- (UNSPEC_CONSTTABLE_FLOAT 9)
+ (UNSPEC_POTENTIAL_CPRESTORE 5)
+ (UNSPEC_CPRESTORE 6)
+ (UNSPEC_RESTORE_GP 7)
+ (UNSPEC_MOVE_GP 8)
+ (UNSPEC_EH_RETURN 9)
+ (UNSPEC_CONSTTABLE_INT 10)
+ (UNSPEC_CONSTTABLE_FLOAT 11)
(UNSPEC_ALIGN 14)
(UNSPEC_HIGH 17)
(UNSPEC_LOAD_LEFT 18)
@@ -77,6 +79,7 @@
(UNSPEC_ADDRESS_FIRST 100)
(TLS_GET_TP_REGNUM 3)
+ (CPRESTORE_SLOT_REGNUM 76)
(GOT_VERSION_REGNUM 79)
;; For MIPS Paired-Singled Floating Point Instructions.
@@ -256,6 +259,9 @@
(UNSPEC_MIPS_CACHE 600)
(UNSPEC_R10K_CACHE_BARRIER 601)
+
+ ;; PIC long branch sequences are never longer than 100 bytes.
+ (MAX_PIC_BRANCH_LENGTH 100)
]
)
@@ -281,12 +287,11 @@
;;
;; jal is always a macro for TARGET_CALL_CLOBBERED_GP because it includes
;; an instruction to restore $gp. Direct jals are also macros for
-;; flag_pic && !TARGET_ABSOLUTE_ABICALLS because they first load
-;; the target address into a register.
+;; !TARGET_ABSOLUTE_JUMPS because they first load the target address
+;; into a register.
(define_attr "jal_macro" "no,yes"
(cond [(eq_attr "jal" "direct")
- (symbol_ref "((TARGET_CALL_CLOBBERED_GP
- || (flag_pic && !TARGET_ABSOLUTE_ABICALLS))
+ (symbol_ref "(TARGET_CALL_CLOBBERED_GP || !TARGET_ABSOLUTE_JUMPS
? JAL_MACRO_YES : JAL_MACRO_NO)")
(eq_attr "jal" "indirect")
(symbol_ref "(TARGET_CALL_CLOBBERED_GP
@@ -498,9 +503,10 @@
(ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
(const_int 8)
- ;; Direct branch instructions have a range of [-0x40000,0x3fffc].
- ;; If a branch is outside this range, we have a choice of two
- ;; sequences. For PIC, an out-of-range branch like:
+ ;; Direct branch instructions have a range of [-0x20000,0x1fffc],
+ ;; relative to the address of the delay slot. If a branch is
+ ;; outside this range, we have a choice of two sequences.
+ ;; For PIC, an out-of-range branch like:
;;
;; bne r1,r2,target
;; dslot
@@ -514,9 +520,6 @@
;; nop
;; 1:
;;
- ;; where the load address can be up to three instructions long
- ;; (lw, nop, addiu).
- ;;
;; The non-PIC case is similar except that we use a direct
;; jump instead of an la/jr pair. Since the target of this
;; jump is an absolute 28-bit bit address (the other bits
@@ -531,12 +534,21 @@
;; will add the length of the implicit nop. The values for
;; forward and backward branches will be different as well.
(eq_attr "type" "branch")
- (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
- (le (minus (pc) (match_dup 1)) (const_int 131068)))
- (const_int 4)
- (ne (symbol_ref "flag_pic") (const_int 0))
- (const_int 24)
- ] (const_int 12))
+ (cond [(and (le (minus (match_dup 0) (pc)) (const_int 131064))
+ (le (minus (pc) (match_dup 0)) (const_int 131068)))
+ (const_int 4)
+
+ ;; The non-PIC case: branch, first delay slot, and J.
+ (ne (symbol_ref "TARGET_ABSOLUTE_JUMPS") (const_int 0))
+ (const_int 12)]
+
+ ;; Use MAX_PIC_BRANCH_LENGTH as a (gross) overestimate.
+ ;; mips_adjust_insn_length substitutes the correct length.
+ ;;
+ ;; Note that we can't simply use (symbol_ref ...) here
+ ;; because genattrtab needs to know the maximum length
+ ;; of an insn.
+ (const_int MAX_PIC_BRANCH_LENGTH))
;; "Ghost" instructions occupy no space.
(eq_attr "type" "ghost")
@@ -4754,12 +4766,12 @@
;; function address.
(define_insn_and_split "loadgp_newabi_<mode>"
[(set (match_operand:P 0 "register_operand" "=d")
- (unspec_volatile:P [(match_operand:P 1)
- (match_operand:P 2 "register_operand" "d")]
- UNSPEC_LOADGP))]
+ (unspec:P [(match_operand:P 1)
+ (match_operand:P 2 "register_operand" "d")]
+ UNSPEC_LOADGP))]
"mips_current_loadgp_style () == LOADGP_NEWABI"
- "#"
- ""
+ { return mips_must_initialize_gp_p () ? "#" : ""; }
+ "&& mips_must_initialize_gp_p ()"
[(set (match_dup 0) (match_dup 3))
(set (match_dup 0) (match_dup 4))
(set (match_dup 0) (match_dup 5))]
@@ -4768,21 +4780,21 @@
operands[4] = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
operands[5] = gen_rtx_LO_SUM (Pmode, operands[0], operands[1]);
}
- [(set_attr "length" "12")])
+ [(set_attr "type" "ghost")])
;; Likewise, for -mno-shared code. Operand 0 is the __gnu_local_gp symbol.
(define_insn_and_split "loadgp_absolute_<mode>"
[(set (match_operand:P 0 "register_operand" "=d")
- (unspec_volatile:P [(match_operand:P 1)] UNSPEC_LOADGP))]
+ (unspec:P [(match_operand:P 1)] UNSPEC_LOADGP))]
"mips_current_loadgp_style () == LOADGP_ABSOLUTE"
- "#"
- ""
+ { return mips_must_initialize_gp_p () ? "#" : ""; }
+ "&& mips_must_initialize_gp_p ()"
[(const_int 0)]
{
mips_emit_move (operands[0], operands[1]);
DONE;
}
- [(set_attr "length" "8")])
+ [(set_attr "type" "ghost")])
;; This blockage instruction prevents the gp load from being
;; scheduled after an implicit use of gp. It also prevents
@@ -4791,19 +4803,18 @@
[(unspec_volatile [(reg:SI 28)] UNSPEC_BLOCKAGE)]
""
""
- [(set_attr "type" "ghost")
- (set_attr "mode" "none")])
+ [(set_attr "type" "ghost")])
;; Initialize $gp for RTP PIC. Operand 0 is the __GOTT_BASE__ symbol
;; and operand 1 is the __GOTT_INDEX__ symbol.
(define_insn_and_split "loadgp_rtp_<mode>"
[(set (match_operand:P 0 "register_operand" "=d")
- (unspec_volatile:P [(match_operand:P 1 "symbol_ref_operand")
- (match_operand:P 2 "symbol_ref_operand")]
- UNSPEC_LOADGP))]
+ (unspec:P [(match_operand:P 1 "symbol_ref_operand")
+ (match_operand:P 2 "symbol_ref_operand")]
+ UNSPEC_LOADGP))]
"mips_current_loadgp_style () == LOADGP_RTP"
- "#"
- ""
+ { return mips_must_initialize_gp_p () ? "#" : ""; }
+ "&& mips_must_initialize_gp_p ()"
[(set (match_dup 0) (high:P (match_dup 3)))
(set (match_dup 0) (unspec:P [(match_dup 0)
(match_dup 3)] UNSPEC_LOAD_GOT))
@@ -4813,37 +4824,72 @@
operands[3] = mips_unspec_address (operands[1], SYMBOL_ABSOLUTE);
operands[4] = mips_unspec_address (operands[2], SYMBOL_HALF);
}
- [(set_attr "length" "12")])
+ [(set_attr "type" "ghost")])
;; Initialize the global pointer for MIPS16 code. Operand 0 is the
;; global pointer and operand 1 is the MIPS16 register that holds
;; the required value.
(define_insn_and_split "copygp_mips16"
[(set (match_operand:SI 0 "register_operand" "=y")
- (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d")]
- UNSPEC_COPYGP))]
+ (unspec:SI [(match_operand:SI 1 "register_operand" "d")]
+ UNSPEC_COPYGP))]
"TARGET_MIPS16"
- "#"
- "&& reload_completed"
- [(set (match_dup 0) (match_dup 1))])
+ { return mips_must_initialize_gp_p () ? "#" : ""; }
+ "&& mips_must_initialize_gp_p ()"
+ [(set (match_dup 0) (match_dup 1))]
+ ""
+ [(set_attr "type" "ghost")])
+
+;; A placeholder for where the cprestore instruction should go,
+;; if we decide we need one. Operand 0 and operand 1 are as for
+;; "cprestore". Operand 2 is a register that holds the gp value.
+;;
+;; The "cprestore" pattern requires operand 2 to be pic_offset_table_rtx,
+;; otherwise any register that holds the correct value will do.
+(define_insn_and_split "potential_cprestore"
+ [(set (match_operand:SI 0 "cprestore_save_slot_operand" "=X,X")
+ (unspec:SI [(match_operand:SI 1 "const_int_operand" "I,i")
+ (match_operand:SI 2 "register_operand" "d,d")]
+ UNSPEC_POTENTIAL_CPRESTORE))
+ (clobber (match_operand:SI 3 "scratch_operand" "=X,&d"))]
+ "!TARGET_CPRESTORE_DIRECTIVE || operands[2] == pic_offset_table_rtx"
+ { return mips_must_initialize_gp_p () ? "#" : ""; }
+ "mips_must_initialize_gp_p ()"
+ [(const_int 0)]
+{
+ mips_save_gp_to_cprestore_slot (operands[0], operands[1],
+ operands[2], operands[3]);
+ DONE;
+}
+ [(set_attr "type" "ghost")])
;; Emit a .cprestore directive, which normally expands to a single store
-;; instruction. Note that we continue to use .cprestore for explicit reloc
-;; code so that jals inside inline asms will work correctly.
+;; instruction. Operand 0 is a (possibly illegitimate) sp-based MEM
+;; for the cprestore slot. Operand 1 is the offset of the slot from
+;; the stack pointer. (This is redundant with operand 0, but it makes
+;; things a little simpler.)
(define_insn "cprestore"
- [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")
- (use (reg:SI 28))]
- UNSPEC_CPRESTORE)]
- ""
+ [(set (match_operand:SI 0 "cprestore_save_slot_operand" "=X,X")
+ (unspec:SI [(match_operand:SI 1 "const_int_operand" "I,i")
+ (reg:SI 28)]
+ UNSPEC_CPRESTORE))]
+ "TARGET_CPRESTORE_DIRECTIVE"
{
if (mips_nomacro.nesting_level > 0 && which_alternative == 1)
- return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro";
+ return ".set\tmacro\;.cprestore\t%1\;.set\tnomacro";
else
- return ".cprestore\t%0";
+ return ".cprestore\t%1";
}
[(set_attr "type" "store")
(set_attr "length" "4,12")])
+(define_insn "use_cprestore"
+ [(set (reg:SI CPRESTORE_SLOT_REGNUM)
+ (match_operand:SI 0 "cprestore_load_slot_operand"))]
+ ""
+ ""
+ [(set_attr "type" "ghost")])
+
;; Expand in-line code to clear the instruction cache between operand[0] and
;; operand[1].
(define_expand "clear_cache"
@@ -5149,100 +5195,94 @@
(define_insn "*branch_fp"
[(set (pc)
(if_then_else
- (match_operator 0 "equality_operator"
+ (match_operator 1 "equality_operator"
[(match_operand:CC 2 "register_operand" "z")
(const_int 0)])
- (label_ref (match_operand 1 "" ""))
+ (label_ref (match_operand 0 "" ""))
(pc)))]
"TARGET_HARD_FLOAT"
{
return mips_output_conditional_branch (insn, operands,
- MIPS_BRANCH ("b%F0", "%Z2%1"),
- MIPS_BRANCH ("b%W0", "%Z2%1"));
+ MIPS_BRANCH ("b%F1", "%Z2%0"),
+ MIPS_BRANCH ("b%W1", "%Z2%0"));
}
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ [(set_attr "type" "branch")])
(define_insn "*branch_fp_inverted"
[(set (pc)
(if_then_else
- (match_operator 0 "equality_operator"
+ (match_operator 1 "equality_operator"
[(match_operand:CC 2 "register_operand" "z")
(const_int 0)])
(pc)
- (label_ref (match_operand 1 "" ""))))]
+ (label_ref (match_operand 0 "" ""))))]
"TARGET_HARD_FLOAT"
{
return mips_output_conditional_branch (insn, operands,
- MIPS_BRANCH ("b%W0", "%Z2%1"),
- MIPS_BRANCH ("b%F0", "%Z2%1"));
+ MIPS_BRANCH ("b%W1", "%Z2%0"),
+ MIPS_BRANCH ("b%F1", "%Z2%0"));
}
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ [(set_attr "type" "branch")])
;; Conditional branches on ordered comparisons with zero.
(define_insn "*branch_order<mode>"
[(set (pc)
(if_then_else
- (match_operator 0 "order_operator"
+ (match_operator 1 "order_operator"
[(match_operand:GPR 2 "register_operand" "d")
(const_int 0)])
- (label_ref (match_operand 1 "" ""))
+ (label_ref (match_operand 0 "" ""))
(pc)))]
"!TARGET_MIPS16"
{ return mips_output_order_conditional_branch (insn, operands, false); }
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ [(set_attr "type" "branch")])
(define_insn "*branch_order<mode>_inverted"
[(set (pc)
(if_then_else
- (match_operator 0 "order_operator"
+ (match_operator 1 "order_operator"
[(match_operand:GPR 2 "register_operand" "d")
(const_int 0)])
(pc)
- (label_ref (match_operand 1 "" ""))))]
+ (label_ref (match_operand 0 "" ""))))]
"!TARGET_MIPS16"
{ return mips_output_order_conditional_branch (insn, operands, true); }
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ [(set_attr "type" "branch")])
;; Conditional branch on equality comparison.
(define_insn "*branch_equality<mode>"
[(set (pc)
(if_then_else
- (match_operator 0 "equality_operator"
+ (match_operator 1 "equality_operator"
[(match_operand:GPR 2 "register_operand" "d")
(match_operand:GPR 3 "reg_or_0_operand" "dJ")])
- (label_ref (match_operand 1 "" ""))
+ (label_ref (match_operand 0 "" ""))
(pc)))]
"!TARGET_MIPS16"
{
return mips_output_conditional_branch (insn, operands,
- MIPS_BRANCH ("b%C0", "%2,%z3,%1"),
- MIPS_BRANCH ("b%N0", "%2,%z3,%1"));
+ MIPS_BRANCH ("b%C1", "%2,%z3,%0"),
+ MIPS_BRANCH ("b%N1", "%2,%z3,%0"));
}
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ [(set_attr "type" "branch")])
(define_insn "*branch_equality<mode>_inverted"
[(set (pc)
(if_then_else
- (match_operator 0 "equality_operator"
+ (match_operator 1 "equality_operator"
[(match_operand:GPR 2 "register_operand" "d")
(match_operand:GPR 3 "reg_or_0_operand" "dJ")])
(pc)
- (label_ref (match_operand 1 "" ""))))]
+ (label_ref (match_operand 0 "" ""))))]
"!TARGET_MIPS16"
{
return mips_output_conditional_branch (insn, operands,
- MIPS_BRANCH ("b%N0", "%2,%z3,%1"),
- MIPS_BRANCH ("b%C0", "%2,%z3,%1"));
+ MIPS_BRANCH ("b%N1", "%2,%z3,%0"),
+ MIPS_BRANCH ("b%C1", "%2,%z3,%0"));
}
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ [(set_attr "type" "branch")])
;; MIPS16 branches
@@ -5271,8 +5311,7 @@
return "bt%N0z\t%3";
}
}
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ [(set_attr "type" "branch")])
(define_expand "cbranch<mode>4"
[(set (pc)
@@ -5313,42 +5352,40 @@
[(set (pc)
(if_then_else
(equality_op (zero_extract:GPR
- (match_operand:GPR 0 "register_operand" "d")
+ (match_operand:GPR 1 "register_operand" "d")
(const_int 1)
(match_operand 2 "const_int_operand" ""))
(const_int 0))
- (label_ref (match_operand 1 ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
"ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
{
return
mips_output_conditional_branch (insn, operands,
- MIPS_BRANCH ("bbit<bbv>", "%0,%2,%1"),
- MIPS_BRANCH ("bbit<bbinv>", "%0,%2,%1"));
+ MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"),
+ MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"));
}
[(set_attr "type" "branch")
- (set_attr "mode" "none")
(set_attr "branch_likely" "no")])
(define_insn "*branch_bit<bbv><mode>_inverted"
[(set (pc)
(if_then_else
(equality_op (zero_extract:GPR
- (match_operand:GPR 0 "register_operand" "d")
+ (match_operand:GPR 1 "register_operand" "d")
(const_int 1)
(match_operand 2 "const_int_operand" ""))
(const_int 0))
(pc)
- (label_ref (match_operand 1 ""))))]
+ (label_ref (match_operand 0 ""))))]
"ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
{
return
mips_output_conditional_branch (insn, operands,
- MIPS_BRANCH ("bbit<bbinv>", "%0,%2,%1"),
- MIPS_BRANCH ("bbit<bbv>", "%0,%2,%1"));
+ MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"),
+ MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"));
}
[(set_attr "type" "branch")
- (set_attr "mode" "none")
(set_attr "branch_likely" "no")])
;;
@@ -5535,47 +5572,41 @@
;; Unconditional branches.
-(define_insn "jump"
+(define_expand "jump"
[(set (pc)
- (label_ref (match_operand 0 "" "")))]
- "!TARGET_MIPS16"
+ (label_ref (match_operand 0)))])
+
+(define_insn "*jump_absolute"
+ [(set (pc)
+ (label_ref (match_operand 0)))]
+ "!TARGET_MIPS16 && TARGET_ABSOLUTE_JUMPS"
+ { return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/"); }
+ [(set_attr "type" "jump")])
+
+(define_insn "*jump_pic"
+ [(set (pc)
+ (label_ref (match_operand 0)))]
+ "!TARGET_MIPS16 && !TARGET_ABSOLUTE_JUMPS"
{
- if (flag_pic)
+ if (get_attr_length (insn) <= 8)
+ return "%*b\t%l0%/";
+ else
{
- if (get_attr_length (insn) <= 8)
- return "%*b\t%l0%/";
- else
- {
- output_asm_insn (mips_output_load_label (), operands);
- return "%*jr\t%@%/%]";
- }
+ mips_output_load_label (operands[0]);
+ return "%*jr\t%@%/%]";
}
- else
- return "%*j\t%l0%/";
}
- [(set_attr "type" "jump")
- (set_attr "mode" "none")
- (set (attr "length")
- ;; We can't use `j' when emitting PIC. Emit a branch if it's
- ;; in range, otherwise load the address of the branch target into
- ;; $at and then jump to it.
- (if_then_else
- (ior (eq (symbol_ref "flag_pic") (const_int 0))
- (lt (abs (minus (match_dup 0)
- (plus (pc) (const_int 4))))
- (const_int 131072)))
- (const_int 4) (const_int 16)))])
+ [(set_attr "type" "branch")])
;; We need a different insn for the mips16, because a mips16 branch
;; does not have a delay slot.
-(define_insn ""
+(define_insn "*jump_mips16"
[(set (pc)
(label_ref (match_operand 0 "" "")))]
"TARGET_MIPS16"
"b\t%l0"
- [(set_attr "type" "branch")
- (set_attr "mode" "none")])
+ [(set_attr "type" "branch")])
(define_expand "indirect_jump"
[(set (pc) (match_operand 0 "register_operand"))]
@@ -5876,14 +5907,28 @@
(clobber (match_scratch:SI 0 "=&d"))]
"TARGET_CALL_CLOBBERED_GP"
"#"
- "&& reload_completed"
+ "&& epilogue_completed"
[(const_int 0)]
{
- mips_restore_gp (operands[0]);
+ mips_restore_gp_from_cprestore_slot (operands[0]);
DONE;
}
- [(set_attr "type" "load")
- (set_attr "length" "12")])
+ [(set_attr "type" "ghost")])
+
+;; Move between $gp and its register save slot.
+(define_insn_and_split "move_gp<mode>"
+ [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,m")
+ (unspec:GPR [(match_operand:GPR 1 "move_operand" "m,d")]
+ UNSPEC_MOVE_GP))]
+ ""
+ { return mips_must_initialize_gp_p () ? "#" : ""; }
+ "mips_must_initialize_gp_p ()"
+ [(const_int 0)]
+{
+ mips_emit_move (operands[0], operands[1]);
+ DONE;
+}
+ [(set_attr "type" "ghost")])
;;
;; ....................
diff --git a/gcc/config/mips/predicates.md b/gcc/config/mips/predicates.md
index a9a0177197e..e1cb4573688 100644
--- a/gcc/config/mips/predicates.md
+++ b/gcc/config/mips/predicates.md
@@ -244,6 +244,14 @@
}
})
+(define_predicate "cprestore_save_slot_operand"
+ (and (match_code "mem")
+ (match_test "mips_cprestore_address_p (XEXP (op, 0), false)")))
+
+(define_predicate "cprestore_load_slot_operand"
+ (and (match_code "mem")
+ (match_test "mips_cprestore_address_p (XEXP (op, 0), true)")))
+
(define_predicate "consttable_operand"
(match_test "CONSTANT_P (op)"))
diff --git a/gcc/config/moxie/constraints.md b/gcc/config/moxie/constraints.md
index 038be5d4c6e..f76726813e3 100644
--- a/gcc/config/moxie/constraints.md
+++ b/gcc/config/moxie/constraints.md
@@ -40,6 +40,11 @@
(match_test "REG_P (XEXP (op, 0))
&& REGNO_OK_FOR_BASE_P (REGNO (XEXP (op, 0)))")))
+(define_constraint "O"
+ "The constant zero"
+ (and (match_code "const_int")
+ (match_test "ival == 0")))
+
(define_constraint "I"
"An 8-bit constant (0..255)"
(and (match_code "const_int")
@@ -49,4 +54,3 @@
"A constant -(0..255)"
(and (match_code "const_int")
(match_test "ival >= -255 && ival <= 0")))
-
diff --git a/gcc/config/moxie/moxie.c b/gcc/config/moxie/moxie.c
index 39a5c10bb69..8b2d8b23fe3 100644
--- a/gcc/config/moxie/moxie.c
+++ b/gcc/config/moxie/moxie.c
@@ -273,25 +273,22 @@ moxie_expand_prologue (void)
if (cfun->machine->size_for_adjusting_sp > 0)
{
- if (cfun->machine->size_for_adjusting_sp <= 255)
+ int i = cfun->machine->size_for_adjusting_sp;
+ while (i > 255)
{
insn = emit_insn (gen_subsi3 (stack_pointer_rtx,
stack_pointer_rtx,
- GEN_INT (cfun->machine->size_for_adjusting_sp)));
+ GEN_INT (255)));
RTX_FRAME_RELATED_P (insn) = 1;
+ i -= 255;
}
- else
+ if (i > 0)
{
- insn =
- emit_insn (gen_movsi
- (gen_rtx_REG (Pmode, MOXIE_R5),
- GEN_INT (-cfun->machine->size_for_adjusting_sp)));
- RTX_FRAME_RELATED_P (insn) = 1;
- insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
+ insn = emit_insn (gen_subsi3 (stack_pointer_rtx,
stack_pointer_rtx,
- gen_rtx_REG (Pmode, MOXIE_R5)));
+ GEN_INT (i)));
RTX_FRAME_RELATED_P (insn) = 1;
- }
+ }
}
}
@@ -359,14 +356,14 @@ moxie_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
int *pretend_size, int no_rtl)
{
int regno;
- int regs = 7 - *cum;
+ int regs = 8 - *cum;
*pretend_size = regs < 0 ? 0 : GET_MODE_SIZE (SImode) * regs;
if (no_rtl)
return;
- for (regno = *cum; regno < 7; regno++)
+ for (regno = *cum; regno < 8; regno++)
{
rtx reg = gen_rtx_REG (SImode, regno);
rtx slot = gen_rtx_PLUS (Pmode,
@@ -395,7 +392,7 @@ rtx
moxie_function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode,
tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED)
{
- if (cum < 7)
+ if (cum < 8)
return gen_rtx_REG (mode, cum);
else
return NULL_RTX;
@@ -420,7 +417,7 @@ moxie_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
else
size = GET_MODE_SIZE (mode);
- return size > 4*5;
+ return size > 4*6;
}
/* Some function arguments will only partially fit in the registers
@@ -434,7 +431,7 @@ moxie_arg_partial_bytes (CUMULATIVE_ARGS *cum,
{
int bytes_left, size;
- if (*cum >= 7)
+ if (*cum >= 8)
return 0;
if (moxie_pass_by_reference (cum, mode, type, named))
@@ -448,7 +445,7 @@ moxie_arg_partial_bytes (CUMULATIVE_ARGS *cum,
else
size = GET_MODE_SIZE (mode);
- bytes_left = (4 * 5) - ((*cum - 2) * 4);
+ bytes_left = (4 * 6) - ((*cum - 2) * 4);
if (size > bytes_left)
return bytes_left;
diff --git a/gcc/config/moxie/moxie.h b/gcc/config/moxie/moxie.h
index f50a6b2a27e..21792da6527 100644
--- a/gcc/config/moxie/moxie.h
+++ b/gcc/config/moxie/moxie.h
@@ -182,7 +182,7 @@ enum reg_class
/* A C expression whose value is a register class containing hard
register REGNO. */
-#define REGNO_REG_CLASS(R) ((R < MOXIE_PC) ? GENERAL_REGS : \
+#define REGNO_REG_CLASS(R) ((R < MOXIE_PC) ? GENERAL_REGS : \
(R == MOXIE_CC ? CC_REGS : SPECIAL_REGS))
/* A C expression for the number of consecutive hard registers,
@@ -263,7 +263,7 @@ enum reg_class
: (unsigned) int_size_in_bytes (TYPE))
#define FUNCTION_ARG_ADVANCE(CUM,MODE,TYPE,NAMED) \
- (CUM = (CUM < MOXIE_R5 ? \
+ (CUM = (CUM < MOXIE_R6 ? \
CUM + ((3 + MOXIE_FUNCTION_ARG_SIZE(MODE,TYPE))/4) : CUM ))
/* How Scalar Function Values Are Returned */
@@ -299,7 +299,7 @@ enum reg_class
/* Define this if it is the responsibility of the caller to allocate
the area reserved for arguments passed in registers. */
-#define REG_PARM_STACK_SPACE(FNDECL) (5 * UNITS_PER_WORD)
+#define REG_PARM_STACK_SPACE(FNDECL) (6 * UNITS_PER_WORD)
/* Offset from the argument pointer register to the first argument's
address. On some machines it may depend on the data type of the
@@ -463,7 +463,7 @@ do \
/* A C expression that is nonzero if REGNO is the number of a hard
register in which function arguments are sometimes passed. */
-#define FUNCTION_ARG_REGNO_P(r) (r >= MOXIE_R0 && r <= MOXIE_R4)
+#define FUNCTION_ARG_REGNO_P(r) (r >= MOXIE_R0 && r <= MOXIE_R5)
/* A C expression that is nonzero if REGNO is the number of a hard
register in which the values of called function may come back. */
diff --git a/gcc/config/moxie/moxie.md b/gcc/config/moxie/moxie.md
index 02072f48388..a8e68872e3f 100644
--- a/gcc/config/moxie/moxie.md
+++ b/gcc/config/moxie/moxie.md
@@ -223,11 +223,12 @@
}")
(define_insn "*movsi"
- [(set (match_operand:SI 0 "general_operand" "=r,r,W,A,r,r,B,r")
- (match_operand:SI 1 "moxie_general_movsrc_operand" "r,i,r,r,W,A,r,B"))]
+ [(set (match_operand:SI 0 "general_operand" "=r,r,r,W,A,r,r,B,r")
+ (match_operand:SI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
"register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode)"
"@
+ xor %0, %0
mov %0, %1
ldi.l %0, %1
st.l %0, %1
@@ -236,7 +237,7 @@
lda.l %0, %1
sto.l %0, %1
ldo.l %0, %1"
- [(set_attr "length" "2,6,2,6,2,6,6,6")])
+ [(set_attr "length" "2,2,6,2,6,2,6,6,6")])
(define_expand "movqi"
[(set (match_operand:QI 0 "general_operand" "")
@@ -250,11 +251,12 @@
}")
(define_insn "*movqi"
- [(set (match_operand:QI 0 "general_operand" "=r,r,W,A,r,r,B,r")
- (match_operand:QI 1 "moxie_general_movsrc_operand" "r,i,r,r,W,A,r,B"))]
+ [(set (match_operand:QI 0 "general_operand" "=r,r,r,W,A,r,r,B,r")
+ (match_operand:QI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
"register_operand (operands[0], QImode)
|| register_operand (operands[1], QImode)"
"@
+ xor %0, %0
mov %0, %1
ldi.b %0, %1
st.b %0, %1
@@ -263,7 +265,7 @@
lda.b %0, %1
sto.b %0, %1
ldo.b %0, %1"
- [(set_attr "length" "2,6,2,6,2,6,6,6")])
+ [(set_attr "length" "2,2,6,2,6,2,6,6,6")])
(define_expand "movhi"
[(set (match_operand:HI 0 "general_operand" "")
@@ -277,11 +279,12 @@
}")
(define_insn "*movhi"
- [(set (match_operand:HI 0 "general_operand" "=r,r,W,A,r,r,B,r")
- (match_operand:HI 1 "moxie_general_movsrc_operand" "r,i,r,r,W,A,r,B"))]
+ [(set (match_operand:HI 0 "general_operand" "=r,r,r,W,A,r,r,B,r")
+ (match_operand:HI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))]
"(register_operand (operands[0], HImode)
|| register_operand (operands[1], HImode))"
"@
+ xor %0, %0
mov %0, %1
ldi.s %0, %1
st.s %0, %1
@@ -290,7 +293,7 @@
lda.s %0, %1
sto.s %0, %1
ldo.s %0, %1"
- [(set_attr "length" "2,6,2,6,2,6,6,6")])
+ [(set_attr "length" "2,2,6,2,6,2,6,6,6")])
;; -------------------------------------------------------------------------
;; Compare instructions
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 4355d0a2ac7..65a07d9eb93 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -5793,9 +5793,10 @@ pa_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
break;
case CONST:
op = XEXP (x, 0);
- is_symbolic = (((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
- && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0)))
- || GET_CODE (XEXP (op, 0)) == LABEL_REF)
+ is_symbolic = (GET_CODE (op) == PLUS
+ && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0)))
+ || GET_CODE (XEXP (op, 0)) == LABEL_REF)
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
break;
default:
diff --git a/gcc/config/pa/predicates.md b/gcc/config/pa/predicates.md
index 1fc921e9b1b..0f0a42488b9 100644
--- a/gcc/config/pa/predicates.md
+++ b/gcc/config/pa/predicates.md
@@ -73,9 +73,10 @@
return 1;
case CONST:
op = XEXP (op, 0);
- return (((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
- && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0)))
- || GET_CODE (XEXP (op, 0)) == LABEL_REF)
+ return (GET_CODE (op) == PLUS
+ && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0)))
+ || GET_CODE (XEXP (op, 0)) == LABEL_REF)
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
default:
return 0;
diff --git a/gcc/config/picochip/picochip.c b/gcc/config/picochip/picochip.c
index ecec1f7121e..5155e7695ad 100644
--- a/gcc/config/picochip/picochip.c
+++ b/gcc/config/picochip/picochip.c
@@ -2920,7 +2920,7 @@ reorder_var_tracking_notes (void)
{
next = NEXT_INSN (insn);
- if (INSN_P (insn))
+ if (NONDEBUG_INSN_P (insn))
{
/* Emit queued up notes before the first instruction of a bundle. */
if (GET_MODE (insn) == TImode)
@@ -3016,7 +3016,7 @@ picochip_reorg (void)
INSN_LOCATOR (insn1) = vliw_insn_location;
}
/* Tag subsequent instructions with the same location. */
- if (INSN_P (insn))
+ if (NONDEBUG_INSN_P (insn))
INSN_LOCATOR (insn) = vliw_insn_location;
}
}
@@ -3160,7 +3160,7 @@ picochip_reset_vliw (rtx insn)
local_insn = insn;
do
{
- if (NOTE_P (local_insn))
+ if (NOTE_P (local_insn) || DEBUG_INSN_P(local_insn))
{
local_insn = NEXT_INSN (local_insn);
continue;
@@ -3599,7 +3599,7 @@ picochip_final_prescan_insn (rtx insn, rtx * opvec ATTRIBUTE_UNUSED,
for (local_insn = NEXT_INSN (local_insn); local_insn;
local_insn = NEXT_INSN (local_insn))
{
- if (NOTE_P (local_insn))
+ if (NOTE_P (local_insn) || DEBUG_INSN_P(local_insn))
continue;
else if (!INSN_P (local_insn))
break;
@@ -3611,7 +3611,7 @@ picochip_final_prescan_insn (rtx insn, rtx * opvec ATTRIBUTE_UNUSED,
/* Set the continuation flag if the next instruction can be packed
with the current instruction (i.e., the next instruction is
valid, and isn't the start of a new cycle). */
- picochip_vliw_continuation = (local_insn && INSN_P (local_insn) &&
+ picochip_vliw_continuation = (local_insn && NONDEBUG_INSN_P (local_insn) &&
(GET_MODE (local_insn) != TImode));
}
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index 94d18aee1da..37148c6aec6 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -437,11 +437,11 @@ extern int dot_symbols;
#undef SAVE_FP_PREFIX
#define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_")
#undef SAVE_FP_SUFFIX
-#define SAVE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
+#define SAVE_FP_SUFFIX ""
#undef RESTORE_FP_PREFIX
#define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_")
#undef RESTORE_FP_SUFFIX
-#define RESTORE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
+#define RESTORE_FP_SUFFIX ""
/* Dwarf2 debugging. */
#undef PREFERRED_DEBUGGING_TYPE
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 40d83900bc9..564b5407322 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -919,6 +919,10 @@ static tree rs6000_builtin_mul_widen_even (tree);
static tree rs6000_builtin_mul_widen_odd (tree);
static tree rs6000_builtin_conversion (unsigned int, tree);
static tree rs6000_builtin_vec_perm (tree, tree *);
+static bool rs6000_builtin_support_vector_misalignment (enum
+ machine_mode,
+ const_tree,
+ int, bool);
static void def_builtin (int, const char *, tree, int);
static bool rs6000_vector_alignment_reachable (const_tree, bool);
@@ -1300,7 +1304,9 @@ static const struct attribute_spec rs6000_attribute_table[] =
#define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
#undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
#define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
-
+#undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
+#define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
+ rs6000_builtin_support_vector_misalignment
#undef TARGET_VECTOR_ALIGNMENT_REACHABLE
#define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
@@ -2895,6 +2901,36 @@ rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_pac
}
}
+/* Return true if the vector misalignment factor is supported by the
+ target. */
+bool
+rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
+ const_tree type,
+ int misalignment,
+ bool is_packed)
+{
+ if (TARGET_VSX)
+ {
+ /* Return if movmisalign pattern is not supported for this mode. */
+ if (optab_handler (movmisalign_optab, mode)->insn_code ==
+ CODE_FOR_nothing)
+ return false;
+
+ if (misalignment == -1)
+ {
+ /* misalignment factor is unknown at compile time but we know
+ it's word aligned. */
+ if (rs6000_vector_alignment_reachable (type, is_packed))
+ return true;
+ return false;
+ }
+ /* VSX supports word-aligned vector. */
+ if (misalignment % 4 == 0)
+ return true;
+ }
+ return false;
+}
+
/* Implement targetm.vectorize.builtin_vec_perm. */
tree
rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
@@ -6488,10 +6524,7 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
rtx other = XEXP (XEXP (operands[1], 0), 1);
sym = force_reg (mode, sym);
- if (mode == SImode)
- emit_insn (gen_addsi3 (operands[0], sym, other));
- else
- emit_insn (gen_adddi3 (operands[0], sym, other));
+ emit_insn (gen_add3_insn (operands[0], sym, other));
return;
}
@@ -16473,9 +16506,7 @@ rs6000_split_multireg_move (rtx dst, rtx src)
delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
: GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (breg, breg, delta_rtx)
- : gen_adddi3 (breg, breg, delta_rtx));
+ emit_insn (gen_add3_insn (breg, breg, delta_rtx));
src = replace_equiv_address (src, breg);
}
else if (! rs6000_offsettable_memref_p (src))
@@ -16525,9 +16556,7 @@ rs6000_split_multireg_move (rtx dst, rtx src)
used_update = true;
}
else
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (breg, breg, delta_rtx)
- : gen_adddi3 (breg, breg, delta_rtx));
+ emit_insn (gen_add3_insn (breg, breg, delta_rtx));
dst = replace_equiv_address (dst, breg);
}
else
@@ -17728,14 +17757,7 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
&& REGNO (stack_limit_rtx) > 1
&& REGNO (stack_limit_rtx) <= 31)
{
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (tmp_reg,
- stack_limit_rtx,
- GEN_INT (size))
- : gen_adddi3 (tmp_reg,
- stack_limit_rtx,
- GEN_INT (size)));
-
+ emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
const0_rtx));
}
@@ -18011,7 +18033,8 @@ static bool
no_global_regs_above (int first, bool gpr)
{
int i;
- for (i = first; i < gpr ? 32 : 64 ; i++)
+ int last = gpr ? 32 : 64;
+ for (i = first; i < last; i++)
if (global_regs[i])
return false;
return true;
@@ -18028,54 +18051,136 @@ no_global_regs_above (int first, bool gpr)
static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
-/* Return the symbol for an out-of-line register save/restore routine.
+/* Temporary holding space for an out-of-line register save/restore
+ routine name. */
+static char savres_routine_name[30];
+
+/* Return the name for an out-of-line register save/restore routine.
+ We are saving/restoring GPRs if GPR is true. */
+
+static char *
+rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
+ bool savep, bool gpr, bool lr)
+{
+ const char *prefix = "";
+ const char *suffix = "";
+
+ /* Different targets are supposed to define
+ {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
+ routine name could be defined with:
+
+ sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
+
+ This is a nice idea in practice, but in reality, things are
+ complicated in several ways:
+
+ - ELF targets have save/restore routines for GPRs.
+
+ - SPE targets use different prefixes for 32/64-bit registers, and
+ neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
+
+ - PPC64 ELF targets have routines for save/restore of GPRs that
+ differ in what they do with the link register, so having a set
+ prefix doesn't work. (We only use one of the save routines at
+ the moment, though.)
+
+ - PPC32 elf targets have "exit" versions of the restore routines
+ that restore the link register and can save some extra space.
+ These require an extra suffix. (There are also "tail" versions
+ of the restore routines and "GOT" versions of the save routines,
+ but we don't generate those at present. Same problems apply,
+ though.)
+
+ We deal with all this by synthesizing our own prefix/suffix and
+ using that for the simple sprintf call shown above. */
+ if (TARGET_SPE)
+ {
+ /* No floating point saves on the SPE. */
+ gcc_assert (gpr);
+
+ if (savep)
+ prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
+ else
+ prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
+
+ if (lr)
+ suffix = "_x";
+ }
+ else if (DEFAULT_ABI == ABI_V4)
+ {
+ if (TARGET_64BIT)
+ goto aix_names;
+
+ if (gpr)
+ prefix = savep ? "_savegpr_" : "_restgpr_";
+ else
+ prefix = savep ? "_savefpr_" : "_restfpr_";
+
+ if (lr)
+ suffix = "_x";
+ }
+ else if (DEFAULT_ABI == ABI_AIX)
+ {
+#ifndef POWERPC_LINUX
+ /* No out-of-line save/restore routines for GPRs on AIX. */
+ gcc_assert (!TARGET_AIX || !gpr);
+#endif
+
+ aix_names:
+ if (gpr)
+ prefix = (savep
+ ? (lr ? "_savegpr0_" : "_savegpr1_")
+ : (lr ? "_restgpr0_" : "_restgpr1_"));
+#ifdef POWERPC_LINUX
+ else if (lr)
+ prefix = (savep ? "_savefpr_" : "_restfpr_");
+#endif
+ else
+ {
+ prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
+ suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
+ }
+ }
+ else if (DEFAULT_ABI == ABI_DARWIN)
+ sorry ("Out-of-line save/restore routines not supported on Darwin");
+
+ sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
+
+ return savres_routine_name;
+}
+
+/* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
We are saving/restoring GPRs if GPR is true. */
static rtx
-rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep, bool gpr, bool exitp)
+rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
+ bool gpr, bool lr)
{
int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
rtx sym;
int select = ((savep ? 1 : 0) << 2
- | (gpr
- /* On the SPE, we never have any FPRs, but we do have
- 32/64-bit versions of the routines. */
- ? (TARGET_SPE_ABI && info->spe_64bit_regs_used ? 1 : 0)
- : 0) << 1
- | (exitp ? 1: 0));
+ | ((TARGET_SPE_ABI
+ /* On the SPE, we never have any FPRs, but we do have
+ 32/64-bit versions of the routines. */
+ ? (info->spe_64bit_regs_used ? 1 : 0)
+ : (gpr ? 1 : 0)) << 1)
+ | (lr ? 1: 0));
/* Don't generate bogus routine names. */
- gcc_assert (FIRST_SAVRES_REGISTER <= regno && regno <= LAST_SAVRES_REGISTER);
+ gcc_assert (FIRST_SAVRES_REGISTER <= regno
+ && regno <= LAST_SAVRES_REGISTER);
sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
if (sym == NULL)
{
- char name[30];
- const char *action;
- const char *regkind;
- const char *exit_suffix;
-
- action = savep ? "save" : "rest";
-
- /* SPE has slightly different names for its routines depending on
- whether we are saving 32-bit or 64-bit registers. */
- if (TARGET_SPE_ABI)
- {
- /* No floating point saves on the SPE. */
- gcc_assert (gpr);
-
- regkind = info->spe_64bit_regs_used ? "64gpr" : "32gpr";
- }
- else
- regkind = gpr ? "gpr" : "fpr";
+ char *name;
- exit_suffix = exitp ? "_x" : "";
-
- sprintf (name, "_%s%s_%d%s", action, regkind, regno, exit_suffix);
+ name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
= gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
+ SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
}
return sym;
@@ -18102,8 +18207,11 @@ rs6000_emit_stack_reset (rs6000_stack_t *info,
if (frame_reg_rtx != sp_reg_rtx)
{
if (sp_offset != 0)
- return emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx,
- GEN_INT (sp_offset)));
+ {
+ rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
+ return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
+ GEN_INT (sp_offset)));
+ }
else if (!savres)
return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
}
@@ -18132,7 +18240,7 @@ static rtx
rs6000_make_savres_rtx (rs6000_stack_t *info,
rtx frame_reg_rtx, int save_area_offset,
enum machine_mode reg_mode,
- bool savep, bool gpr, bool exitp)
+ bool savep, bool gpr, bool lr)
{
int i;
int offset, start_reg, end_reg, n_regs;
@@ -18146,20 +18254,21 @@ rs6000_make_savres_rtx (rs6000_stack_t *info,
: info->first_fp_reg_save);
end_reg = gpr ? 32 : 64;
n_regs = end_reg - start_reg;
- p = rtvec_alloc ((exitp ? 4 : 3) + n_regs);
-
- /* If we're saving registers, then we should never say we're exiting. */
- gcc_assert ((savep && !exitp) || !savep);
+ p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
- if (exitp)
+ if (!savep && lr)
RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
RTVEC_ELT (p, offset++)
= gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
- sym = rs6000_savres_routine_sym (info, savep, gpr, exitp);
+ sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
- RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 11));
+ RTVEC_ELT (p, offset++)
+ = gen_rtx_USE (VOIDmode,
+ gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
+ : gpr && !lr ? 12
+ : 1));
for (i = 0; i < end_reg - start_reg; i++)
{
@@ -18174,6 +18283,16 @@ rs6000_make_savres_rtx (rs6000_stack_t *info,
savep ? reg : mem);
}
+ if (savep && lr)
+ {
+ rtx addr, reg, mem;
+ reg = gen_rtx_REG (Pmode, 0);
+ addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ GEN_INT (info->lr_save_offset));
+ mem = gen_frame_mem (Pmode, addr);
+ RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
+ }
+
return gen_rtx_PARALLEL (VOIDmode, p);
}
@@ -18194,7 +18313,10 @@ rs6000_reg_live_or_pic_offset_p (int reg)
enum {
SAVRES_MULTIPLE = 0x1,
SAVRES_INLINE_FPRS = 0x2,
- SAVRES_INLINE_GPRS = 0x4
+ SAVRES_INLINE_GPRS = 0x4,
+ SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
+ SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
+ SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
};
/* Determine the strategy for savings/restoring registers. */
@@ -18209,6 +18331,7 @@ rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
bool savres_gprs_inline;
bool noclobber_global_gprs
= no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
+ int strategy;
using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
&& (!TARGET_SPE_ABI
@@ -18228,6 +18351,10 @@ rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
|| info->first_fp_reg_save == 64
|| !no_global_regs_above (info->first_fp_reg_save,
/*gpr=*/false)
+ /* The out-of-line FP routines use
+ double-precision stores; we can't use those
+ routines if we don't have such stores. */
+ || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
|| FP_SAVE_INLINE (info->first_fp_reg_save));
savres_gprs_inline = (common
/* Saving CR interferes with the exit routines
@@ -18265,9 +18392,22 @@ rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
savres_gprs_inline = savres_gprs_inline || using_multiple_p;
}
- return (using_multiple_p
- | (savres_fprs_inline << 1)
- | (savres_gprs_inline << 2));
+ strategy = (using_multiple_p
+ | (savres_fprs_inline << 1)
+ | (savres_gprs_inline << 2));
+#ifdef POWERPC_LINUX
+ if (TARGET_64BIT)
+ {
+ if (!savres_fprs_inline)
+ strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
+ else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
+ strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
+ }
+#else
+ if (TARGET_AIX && !savres_fprs_inline)
+ strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
+#endif
+ return strategy;
}
/* Emit function prologue as insns. */
@@ -18289,7 +18429,7 @@ rs6000_emit_prologue (void)
int using_store_multiple;
int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
&& df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
- && !call_used_regs[STATIC_CHAIN_REGNUM]);
+ && call_used_regs[STATIC_CHAIN_REGNUM]);
HOST_WIDE_INT sp_offset = 0;
if (TARGET_FIX_AND_CONTINUE)
@@ -18474,24 +18614,30 @@ rs6000_emit_prologue (void)
gen_rtx_REG (Pmode, LR_REGNO));
RTX_FRAME_RELATED_P (insn) = 1;
- addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
+ | SAVRES_NOINLINE_FPRS_SAVES_LR)))
+ {
+ addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
GEN_INT (info->lr_save_offset + sp_offset));
- reg = gen_rtx_REG (Pmode, 0);
- mem = gen_rtx_MEM (Pmode, addr);
- /* This should not be of rs6000_sr_alias_set, because of
- __builtin_return_address. */
+ reg = gen_rtx_REG (Pmode, 0);
+ mem = gen_rtx_MEM (Pmode, addr);
+ /* This should not be of rs6000_sr_alias_set, because of
+ __builtin_return_address. */
- insn = emit_move_insn (mem, reg);
- rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
- NULL_RTX, NULL_RTX);
+ insn = emit_move_insn (mem, reg);
+ rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+ NULL_RTX, NULL_RTX);
+ }
}
- /* If we need to save CR, put it into r12. */
+ /* If we need to save CR, put it into r12 or r11. */
if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
{
rtx set;
- cr_save_rtx = gen_rtx_REG (SImode, 12);
+ cr_save_rtx
+ = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
+ ? 11 : 12);
insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
RTX_FRAME_RELATED_P (insn) = 1;
/* Now, there's no way that dwarf2out_frame_debug_expr is going
@@ -18528,7 +18674,9 @@ rs6000_emit_prologue (void)
info->fp_save_offset + sp_offset,
DFmode,
/*savep=*/true, /*gpr=*/false,
- /*exitp=*/false);
+ /*lr=*/(strategy
+ & SAVRES_NOINLINE_FPRS_SAVES_LR)
+ != 0);
insn = emit_insn (par);
rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
NULL_RTX, NULL_RTX);
@@ -18624,7 +18772,7 @@ rs6000_emit_prologue (void)
par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
0, reg_mode,
/*savep=*/true, /*gpr=*/true,
- /*exitp=*/false);
+ /*lr=*/false);
insn = emit_insn (par);
rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
NULL_RTX, NULL_RTX);
@@ -18639,25 +18787,23 @@ rs6000_emit_prologue (void)
{
rtx par;
- /* Need to adjust r11 if we saved any FPRs. */
+ /* Need to adjust r11 (r12) if we saved any FPRs. */
if (info->first_fp_reg_save != 64)
{
- rtx r11 = gen_rtx_REG (reg_mode, 11);
- rtx offset = GEN_INT (info->total_size
+ rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
+ ? 12 : 11);
+ rtx offset = GEN_INT (sp_offset
+ (-8 * (64-info->first_fp_reg_save)));
- rtx ptr_reg = (sp_reg_rtx == frame_reg_rtx
- ? sp_reg_rtx : r11);
-
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (r11, ptr_reg, offset)
- : gen_adddi3 (r11, ptr_reg, offset));
+ emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
}
par = rs6000_make_savres_rtx (info, frame_reg_rtx,
info->gp_save_offset + sp_offset,
reg_mode,
/*savep=*/true, /*gpr=*/true,
- /*exitp=*/false);
+ /*lr=*/(strategy
+ & SAVRES_NOINLINE_GPRS_SAVES_LR)
+ != 0);
insn = emit_insn (par);
rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
NULL_RTX, NULL_RTX);
@@ -18934,9 +19080,18 @@ rs6000_output_function_prologue (FILE *file,
fp values. */
if (info->first_fp_reg_save < 64
&& !FP_SAVE_INLINE (info->first_fp_reg_save))
- fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
- SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
- RESTORE_FP_PREFIX, info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
+ {
+ char *name;
+ int regno = info->first_fp_reg_save - 32;
+
+ name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
+ /*gpr=*/false, /*lr=*/false);
+ fprintf (file, "\t.extern %s\n", name);
+
+ name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
+ /*gpr=*/false, /*lr=*/true);
+ fprintf (file, "\t.extern %s\n", name);
+ }
/* Write .extern for AIX common mode routines, if needed. */
if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
@@ -19062,6 +19217,7 @@ rs6000_emit_epilogue (int sibcall)
rtx frame_reg_rtx = sp_reg_rtx;
rtx cfa_restores = NULL_RTX;
rtx insn;
+ rtx cr_save_reg = NULL_RTX;
enum machine_mode reg_mode = Pmode;
int reg_size = TARGET_32BIT ? 4 : 8;
int i;
@@ -19095,8 +19251,10 @@ rs6000_emit_epilogue (int sibcall)
|| (cfun->calls_alloca
&& !frame_pointer_needed));
restore_lr = (info->lr_save_p
- && restoring_GPRs_inline
- && restoring_FPRs_inline);
+ && (restoring_FPRs_inline
+ || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
+ && (restoring_GPRs_inline
+ || info->first_fp_reg_save < 64));
if (WORLD_SAVE_P (info))
{
@@ -19383,7 +19541,7 @@ rs6000_emit_epilogue (int sibcall)
/* Get the old lr if we saved it. If we are restoring registers
out-of-line, then the out-of-line routines can do this for us. */
- if (restore_lr)
+ if (restore_lr && restoring_GPRs_inline)
{
rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
info->lr_save_offset + sp_offset);
@@ -19398,12 +19556,17 @@ rs6000_emit_epilogue (int sibcall)
GEN_INT (info->cr_save_offset + sp_offset));
rtx mem = gen_frame_mem (SImode, addr);
- emit_move_insn (gen_rtx_REG (SImode, 12), mem);
+ cr_save_reg = gen_rtx_REG (SImode,
+ DEFAULT_ABI == ABI_AIX
+ && !restoring_GPRs_inline
+ && info->first_fp_reg_save < 64
+ ? 11 : 12);
+ emit_move_insn (cr_save_reg, mem);
}
/* Set LR here to try to overlap restores below. LR is always saved
above incoming stack, so it never needs REG_CFA_RESTORE. */
- if (restore_lr)
+ if (restore_lr && restoring_GPRs_inline)
emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
gen_rtx_REG (Pmode, 0));
@@ -19520,7 +19683,7 @@ rs6000_emit_epilogue (int sibcall)
par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
0, reg_mode,
/*savep=*/false, /*gpr=*/true,
- /*exitp=*/true);
+ /*lr=*/true);
emit_jump_insn (par);
/* We don't want anybody else emitting things after we jumped
back. */
@@ -19538,21 +19701,25 @@ rs6000_emit_epilogue (int sibcall)
rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
sp_offset, can_use_exit);
else
- emit_insn (gen_addsi3 (gen_rtx_REG (Pmode, 11),
- sp_reg_rtx,
- GEN_INT (sp_offset - info->fp_size)));
+ {
+ emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
+ ? 12 : 11),
+ frame_reg_rtx,
+ GEN_INT (sp_offset - info->fp_size)));
+ if (REGNO (frame_reg_rtx) == 11)
+ sp_offset += info->fp_size;
+ }
par = rs6000_make_savres_rtx (info, frame_reg_rtx,
info->gp_save_offset, reg_mode,
/*savep=*/false, /*gpr=*/true,
- /*exitp=*/can_use_exit);
+ /*lr=*/can_use_exit);
if (can_use_exit)
{
if (info->cr_save_p)
{
- rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12),
- using_mtcr_multiple);
+ rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
if (DEFAULT_ABI == ABI_V4)
cfa_restores
= alloc_reg_note (REG_CFA_RESTORE,
@@ -19639,6 +19806,16 @@ rs6000_emit_epilogue (int sibcall)
}
}
+ if (restore_lr && !restoring_GPRs_inline)
+ {
+ rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
+ info->lr_save_offset + sp_offset);
+
+ emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
+ emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
+ gen_rtx_REG (Pmode, 0));
+ }
+
/* Restore fpr's if we need to do it without calling a function. */
if (restoring_FPRs_inline)
for (i = 0; i < 64 - info->first_fp_reg_save; i++)
@@ -19665,7 +19842,7 @@ rs6000_emit_epilogue (int sibcall)
/* If we saved cr, restore it here. Just those that were used. */
if (info->cr_save_p)
{
- rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12), using_mtcr_multiple);
+ rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
if (DEFAULT_ABI == ABI_V4)
cfa_restores
= alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
@@ -19696,13 +19873,14 @@ rs6000_emit_epilogue (int sibcall)
if (!sibcall)
{
rtvec p;
+ bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
if (! restoring_FPRs_inline)
p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
else
p = rtvec_alloc (2);
RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
- RTVEC_ELT (p, 1) = (restoring_FPRs_inline
+ RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
: gen_rtx_CLOBBER (VOIDmode,
gen_rtx_REG (Pmode, 65)));
@@ -19717,10 +19895,12 @@ rs6000_emit_epilogue (int sibcall)
sym = rs6000_savres_routine_sym (info,
/*savep=*/false,
/*gpr=*/false,
- /*exitp=*/true);
+ /*lr=*/lr);
RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
- gen_rtx_REG (Pmode, 11));
+ gen_rtx_REG (Pmode,
+ DEFAULT_ABI == ABI_AIX
+ ? 1 : 11));
for (i = 0; i < 64 - info->first_fp_reg_save; i++)
{
rtx addr, mem;
@@ -20090,12 +20270,7 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
/* Apply the constant offset, if required. */
if (delta)
- {
- rtx delta_rtx = GEN_INT (delta);
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (this_rtx, this_rtx, delta_rtx)
- : gen_adddi3 (this_rtx, this_rtx, delta_rtx));
- }
+ emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
/* Apply the offset from the vtable, if required. */
if (vcall_offset)
@@ -20106,9 +20281,7 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
{
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
- : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
+ emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
}
else
@@ -20117,9 +20290,7 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
}
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (this_rtx, this_rtx, tmp)
- : gen_adddi3 (this_rtx, this_rtx, tmp));
+ emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
}
/* Generate a tail call to the target function. */
@@ -25002,6 +25173,10 @@ rs6000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
&& TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode))
regno = ALTIVEC_ARG_RETURN;
+ else if (TREE_CODE (valtype) == VECTOR_TYPE
+ && TARGET_VSX && TARGET_ALTIVEC_ABI
+ && VSX_VECTOR_MODE (mode))
+ regno = ALTIVEC_ARG_RETURN;
else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
&& (mode == DFmode || mode == DCmode
|| mode == TFmode || mode == TCmode))
@@ -25043,6 +25218,9 @@ rs6000_libcall_value (enum machine_mode mode)
else if (ALTIVEC_VECTOR_MODE (mode)
&& TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
regno = ALTIVEC_ARG_RETURN;
+ else if (VSX_VECTOR_MODE (mode)
+ && TARGET_VSX && TARGET_ALTIVEC_ABI)
+ regno = ALTIVEC_ARG_RETURN;
else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
return rs6000_complex_function_value (mode);
else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index d837d44c9be..6152e3655ec 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -743,14 +743,18 @@ extern unsigned rs6000_pointer_size;
/* Make arrays of chars word-aligned for the same reasons.
Align vectors to 128 bits. Align SPE vectors and E500 v2 doubles to
64 bits. */
-#define DATA_ALIGNMENT(TYPE, ALIGN) \
- (TREE_CODE (TYPE) == VECTOR_TYPE ? ((TARGET_SPE_ABI \
- || TARGET_PAIRED_FLOAT) ? 64 : 128) \
- : (TARGET_E500_DOUBLE \
- && TYPE_MODE (TYPE) == DFmode) ? 64 \
- : TREE_CODE (TYPE) == ARRAY_TYPE \
- && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
- && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
+#define DATA_ALIGNMENT(TYPE, ALIGN) \
+ (TREE_CODE (TYPE) == VECTOR_TYPE \
+ ? (((TARGET_SPE && SPE_VECTOR_MODE (TYPE_MODE (TYPE))) \
+ || (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (TYPE_MODE (TYPE)))) \
+ ? 64 : 128) \
+ : ((TARGET_E500_DOUBLE \
+ && TREE_CODE (TYPE) == REAL_TYPE \
+ && TYPE_MODE (TYPE) == DFmode) \
+ ? 64 \
+ : (TREE_CODE (TYPE) == ARRAY_TYPE \
+ && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
+ && (ALIGN) < BITS_PER_WORD) ? BITS_PER_WORD : (ALIGN)))
/* Nonzero if move instructions will actually fail to work
when given unaligned data. */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index ea046d3e920..97a128bf69e 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -2392,9 +2392,11 @@
if (!REG_P (operands[0]) && !REG_P (operands[1]))
operands[1] = force_reg (DImode, operands[1]);
- if (TARGET_32BIT)
+ if (!TARGET_POWERPC64)
{
- /* 32-bit needs fewer scratch registers. */
+ /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
+ that uses 64-bit registers needs the same scratch registers as 64-bit
+ mode. */
emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
DONE;
}
@@ -2421,8 +2423,8 @@
[(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
(clobber (match_scratch:DI 2 "=&b,&b,&r"))
- (clobber (match_scratch:DI 3 "=&b,&r,&r"))
- (clobber (match_scratch:DI 4 "=&b,X,&r"))]
+ (clobber (match_scratch:DI 3 "=&r,&r,&r"))
+ (clobber (match_scratch:DI 4 "=&r,X,&r"))]
"TARGET_POWERPC64 && !TARGET_LDBRX
&& (REG_P (operands[0]) || REG_P (operands[1]))"
"#"
@@ -2453,13 +2455,14 @@
addr1 = XEXP (src, 0);
if (GET_CODE (addr1) == PLUS)
{
- emit_insn (gen_adddi3 (op2, XEXP (addr1, 0), GEN_INT (4)));
- addr1 = XEXP (addr1, 1);
+ emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
+ addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
}
else
- emit_move_insn (op2, GEN_INT (4));
-
- addr2 = gen_rtx_PLUS (DImode, op2, addr1);
+ {
+ emit_move_insn (op2, GEN_INT (4));
+ addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
+ }
if (BYTES_BIG_ENDIAN)
{
@@ -2484,7 +2487,7 @@
(clobber (match_operand:DI 2 "gpc_reg_operand" ""))
(clobber (match_operand:DI 3 "gpc_reg_operand" ""))
(clobber (match_operand:DI 4 "" ""))]
- "TARGET_POWERPC64 && reload_completed && !TARGET_LDBRX"
+ "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
[(const_int 0)]
"
{
@@ -2502,13 +2505,14 @@
addr1 = XEXP (dest, 0);
if (GET_CODE (addr1) == PLUS)
{
- emit_insn (gen_adddi3 (op2, XEXP (addr1, 0), GEN_INT (4)));
- addr1 = XEXP (addr1, 1);
+ emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
+ addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
}
else
- emit_move_insn (op2, GEN_INT (4));
-
- addr2 = gen_rtx_PLUS (DImode, op2, addr1);
+ {
+ emit_move_insn (op2, GEN_INT (4));
+ addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
+ }
emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
if (BYTES_BIG_ENDIAN)
@@ -2557,7 +2561,7 @@
[(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
(clobber (match_scratch:SI 2 "=&b,&b,X"))]
- "TARGET_32BIT && (REG_P (operands[0]) || REG_P (operands[1]))"
+ "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
"#"
[(set_attr "length" "16,12,36")])
@@ -2565,7 +2569,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
(clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
- "TARGET_32BIT && reload_completed"
+ "!TARGET_POWERPC64 && reload_completed"
[(const_int 0)]
"
{
@@ -2582,13 +2586,14 @@
addr1 = XEXP (src, 0);
if (GET_CODE (addr1) == PLUS)
{
- emit_insn (gen_adddi3 (op2, XEXP (addr1, 0), GEN_INT (4)));
- addr1 = XEXP (addr1, 1);
+ emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
+ addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
}
else
- emit_move_insn (op2, GEN_INT (4));
-
- addr2 = gen_rtx_PLUS (DImode, op2, addr1);
+ {
+ emit_move_insn (op2, GEN_INT (4));
+ addr2 = gen_rtx_PLUS (SImode, op2, addr1);
+ }
if (BYTES_BIG_ENDIAN)
{
@@ -2609,7 +2614,7 @@
[(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
(clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
- "TARGET_32BIT && reload_completed"
+ "!TARGET_POWERPC64 && reload_completed"
[(const_int 0)]
"
{
@@ -2626,13 +2631,14 @@
addr1 = XEXP (dest, 0);
if (GET_CODE (addr1) == PLUS)
{
- emit_insn (gen_addsi3 (op2, XEXP (addr1, 0), GEN_INT (4)));
- addr1 = XEXP (addr1, 1);
+ emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
+ addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
}
else
- emit_move_insn (op2, GEN_INT (4));
-
- addr2 = gen_rtx_PLUS (SImode, op2, addr1);
+ {
+ emit_move_insn (op2, GEN_INT (4));
+ addr2 = gen_rtx_PLUS (SImode, op2, addr1);
+ }
if (BYTES_BIG_ENDIAN)
{
@@ -2653,7 +2659,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
(clobber (match_operand:SI 2 "" ""))]
- "TARGET_32BIT && reload_completed"
+ "!TARGET_POWERPC64 && reload_completed"
[(const_int 0)]
"
{
@@ -15430,6 +15436,19 @@
[(set_attr "type" "branch")
(set_attr "length" "4")])
+(define_insn "*return_and_restore_fpregs_aix_<mode>"
+ [(match_parallel 0 "any_parallel_operand"
+ [(return)
+ (use (match_operand:P 1 "register_operand" "l"))
+ (use (match_operand:P 2 "symbol_ref_operand" "s"))
+ (use (match_operand:P 3 "gpc_reg_operand" "r"))
+ (set (match_operand:DF 4 "gpc_reg_operand" "=d")
+ (match_operand:DF 5 "memory_operand" "m"))])]
+ ""
+ "b %z2"
+ [(set_attr "type" "branch")
+ (set_attr "length" "4")])
+
; This is used in compiling the unwind routines.
(define_expand "eh_return"
[(use (match_operand 0 "general_operand" ""))]
diff --git a/gcc/config/rs6000/spe.md b/gcc/config/rs6000/spe.md
index 917f817c2bf..ee608b97384 100644
--- a/gcc/config/rs6000/spe.md
+++ b/gcc/config/rs6000/spe.md
@@ -3156,9 +3156,9 @@
[(match_parallel 0 "any_parallel_operand"
[(clobber (reg:P 65))
(use (match_operand:P 1 "symbol_ref_operand" "s"))
- (use (match_operand:P 2 "gpc_reg_operand" "r"))
- (set (match_operand:V2SI 3 "memory_operand" "=m")
- (match_operand:V2SI 4 "gpc_reg_operand" "r"))])]
+ (use (reg:P 11))
+ (set (match_operand:V2SI 2 "memory_operand" "=m")
+ (match_operand:V2SI 3 "gpc_reg_operand" "r"))])]
"TARGET_SPE_ABI"
"bl %z1"
[(set_attr "type" "branch")
@@ -3168,9 +3168,9 @@
[(match_parallel 0 "any_parallel_operand"
[(clobber (reg:P 65))
(use (match_operand:P 1 "symbol_ref_operand" "s"))
- (use (match_operand:P 2 "gpc_reg_operand" "r"))
- (set (match_operand:V2SI 3 "gpc_reg_operand" "=r")
- (match_operand:V2SI 4 "memory_operand" "m"))])]
+ (use (reg:P 11))
+ (set (match_operand:V2SI 2 "gpc_reg_operand" "=r")
+ (match_operand:V2SI 3 "memory_operand" "m"))])]
"TARGET_SPE_ABI"
"bl %z1"
[(set_attr "type" "branch")
@@ -3181,9 +3181,9 @@
[(return)
(clobber (reg:P 65))
(use (match_operand:P 1 "symbol_ref_operand" "s"))
- (use (match_operand:P 2 "gpc_reg_operand" "r"))
- (set (match_operand:V2SI 3 "gpc_reg_operand" "=r")
- (match_operand:V2SI 4 "memory_operand" "m"))])]
+ (use (reg:P 11))
+ (set (match_operand:V2SI 2 "gpc_reg_operand" "=r")
+ (match_operand:V2SI 3 "memory_operand" "m"))])]
"TARGET_SPE_ABI"
"b %z1"
[(set_attr "type" "branch")
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 4d28e375363..5377b474da5 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -272,27 +272,25 @@ do { \
#endif
/* Define cutoff for using external functions to save floating point.
- Currently on 64-bit V.4, always use inline stores. When optimizing
- for size on 32-bit targets, use external functions when
- profitable. */
-#define FP_SAVE_INLINE(FIRST_REG) (optimize_size && !TARGET_64BIT \
+ When optimizing for size, use external functions when profitable. */
+#define FP_SAVE_INLINE(FIRST_REG) (optimize_size \
? ((FIRST_REG) == 62 \
|| (FIRST_REG) == 63) \
: (FIRST_REG) < 64)
/* And similarly for general purpose registers. */
#define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 32 \
- && (TARGET_64BIT || !optimize_size))
+ && !optimize_size)
/* Put jump tables in read-only memory, rather than in .text. */
#define JUMP_TABLES_IN_TEXT_SECTION 0
/* Prefix and suffix to use to saving floating point. */
#define SAVE_FP_PREFIX "_savefpr_"
-#define SAVE_FP_SUFFIX (TARGET_64BIT ? "_l" : "")
+#define SAVE_FP_SUFFIX ""
/* Prefix and suffix to use to restoring floating point. */
#define RESTORE_FP_PREFIX "_restfpr_"
-#define RESTORE_FP_SUFFIX (TARGET_64BIT ? "_l" : "")
+#define RESTORE_FP_SUFFIX ""
/* Type used for ptrdiff_t, as a string used in a declaration. */
#define PTRDIFF_TYPE "int"
diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h
index 6560f319a25..e5c47822355 100644
--- a/gcc/config/rs6000/xcoff.h
+++ b/gcc/config/rs6000/xcoff.h
@@ -190,7 +190,7 @@
putc ('.', FILE); \
RS6000_OUTPUT_BASENAME (FILE, buffer); \
fputs (":\n", FILE); \
- if (write_symbols != NO_DEBUG) \
+ if (write_symbols != NO_DEBUG && !DECL_IGNORED_P (DECL)) \
xcoffout_declare_function (FILE, DECL, buffer); \
}
diff --git a/gcc/config/s390/2084.md b/gcc/config/s390/2084.md
index 38669c23a97..bedc5c322ba 100644
--- a/gcc/config/s390/2084.md
+++ b/gcc/config/s390/2084.md
@@ -163,17 +163,17 @@
(define_insn_reservation "x_fsimptf" 7
(and (eq_attr "cpu" "z990,z9_109")
- (eq_attr "type" "fsimptf"))
+ (eq_attr "type" "fsimptf,fhex"))
"x_e1_t*2,x-wr-fp")
(define_insn_reservation "x_fsimpdf" 6
(and (eq_attr "cpu" "z990,z9_109")
- (eq_attr "type" "fsimpdf,fmuldf"))
+ (eq_attr "type" "fsimpdf,fmuldf,fhex"))
"x_e1_t,x-wr-fp")
(define_insn_reservation "x_fsimpsf" 6
(and (eq_attr "cpu" "z990,z9_109")
- (eq_attr "type" "fsimpsf,fmulsf"))
+ (eq_attr "type" "fsimpsf,fmulsf,fhex"))
"x_e1_t,x-wr-fp")
diff --git a/gcc/config/s390/2097.md b/gcc/config/s390/2097.md
index f27302e0a2b..eb7240effd4 100644
--- a/gcc/config/s390/2097.md
+++ b/gcc/config/s390/2097.md
@@ -463,29 +463,34 @@
; BFP multiplication and general instructions
-(define_insn_reservation "z10_fsimpdf" 12
+(define_insn_reservation "z10_fsimpdf" 6
(and (eq_attr "cpu" "z10")
(eq_attr "type" "fsimpdf,fmuldf"))
"z10_e1_BOTH, z10_Gate_FP")
-; Wg "z10_e1_T, z10_Gate_FP")
-(define_insn_reservation "z10_fsimpsf" 12
+; LOAD ZERO produces a hex value but we need bin. Using the stage 7
+; bypass causes an exception for format conversion which is very
+; expensive. So, make sure subsequent instructions only get the zero
+; in the normal way.
+(define_insn_reservation "z10_fhex" 12
+ (and (eq_attr "cpu" "z10")
+ (eq_attr "type" "fhex"))
+ "z10_e1_BOTH, z10_Gate_FP")
+
+(define_insn_reservation "z10_fsimpsf" 6
(and (eq_attr "cpu" "z10")
(eq_attr "type" "fsimpsf,fmulsf"))
"z10_e1_BOTH, z10_Gate_FP")
-; Wg "z10_e1_T, z10_Gate_FP")
(define_insn_reservation "z10_fmultf" 52
(and (eq_attr "cpu" "z10")
(eq_attr "type" "fmultf"))
"z10_e1_BOTH*4, z10_Gate_FP")
-; Wg "z10_e1_T*4, z10_Gate_FP")
(define_insn_reservation "z10_fsimptf" 14
(and (eq_attr "cpu" "z10")
(eq_attr "type" "fsimptf"))
"z10_e1_BOTH*2, z10_Gate_FP")
-; Wg "z10_e1_T*2, z10_Gate_FP")
; BFP division
@@ -531,12 +536,12 @@
(eq_attr "type" "floadtf"))
"z10_e1_T, z10_Gate_FP")
-(define_insn_reservation "z10_floaddf" 12
+(define_insn_reservation "z10_floaddf" 1
(and (eq_attr "cpu" "z10")
(eq_attr "type" "floaddf"))
"z10_e1_T, z10_Gate_FP")
-(define_insn_reservation "z10_floadsf" 12
+(define_insn_reservation "z10_floadsf" 1
(and (eq_attr "cpu" "z10")
(eq_attr "type" "floadsf"))
"z10_e1_T, z10_Gate_FP")
@@ -553,12 +558,12 @@
; BFP truncate
-(define_insn_reservation "z10_ftrunctf" 12
+(define_insn_reservation "z10_ftrunctf" 16
(and (eq_attr "cpu" "z10")
(eq_attr "type" "ftrunctf"))
"z10_e1_T, z10_Gate_FP")
-(define_insn_reservation "z10_ftruncdf" 16
+(define_insn_reservation "z10_ftruncdf" 12
(and (eq_attr "cpu" "z10")
(eq_attr "type" "ftruncdf"))
"z10_e1_T, z10_Gate_FP")
@@ -585,8 +590,8 @@
; BFP-related bypasses. There is no bypass for extended mode.
(define_bypass 1 "z10_fsimpdf" "z10_fstoredf")
(define_bypass 1 "z10_fsimpsf" "z10_fstoresf")
-(define_bypass 1 "z10_floaddf" "z10_fsimpdf, z10_fstoredf, z10_floaddf")
-(define_bypass 1 "z10_floadsf" "z10_fsimpsf, z10_fstoresf, z10_floadsf")
+(define_bypass 1 "z10_floaddf" "z10_fsimpdf, z10_fstoredf")
+(define_bypass 1 "z10_floadsf" "z10_fsimpsf, z10_fstoresf")
;
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 05896064d6e..a4ac3a38b6b 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -205,13 +205,13 @@ struct processor_costs z10_cost =
COSTS_N_INSNS (10), /* MSGFR */
COSTS_N_INSNS (10), /* MSGR */
COSTS_N_INSNS (10), /* MSR */
- COSTS_N_INSNS (10), /* multiplication in DFmode */
+ COSTS_N_INSNS (1) , /* multiplication in DFmode */
COSTS_N_INSNS (50), /* MXBR */
COSTS_N_INSNS (120), /* SQXBR */
COSTS_N_INSNS (52), /* SQDBR */
COSTS_N_INSNS (38), /* SQEBR */
- COSTS_N_INSNS (10), /* MADBR */
- COSTS_N_INSNS (10), /* MAEBR */
+ COSTS_N_INSNS (1), /* MADBR */
+ COSTS_N_INSNS (1), /* MAEBR */
COSTS_N_INSNS (111), /* DXBR */
COSTS_N_INSNS (39), /* DDBR */
COSTS_N_INSNS (32), /* DEBR */
@@ -5297,6 +5297,7 @@ s390_agen_dep_p (rtx dep_insn, rtx insn)
A STD instruction should be scheduled earlier,
in order to use the bypass. */
+
static int
s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
{
@@ -5304,7 +5305,8 @@ s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
return priority;
if (s390_tune != PROCESSOR_2084_Z990
- && s390_tune != PROCESSOR_2094_Z9_109)
+ && s390_tune != PROCESSOR_2094_Z9_109
+ && s390_tune != PROCESSOR_2097_Z10)
return priority;
switch (s390_safe_attr_type (insn))
@@ -5323,6 +5325,7 @@ s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
return priority;
}
+
/* The number of instructions that can be issued per cycle. */
static int
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 0a4361ff267..db326ee766c 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -202,7 +202,7 @@
(define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
cs,vs,store,sem,idiv,
imulhi,imulsi,imuldi,
- branch,jsr,fsimptf,fsimpdf,fsimpsf,
+ branch,jsr,fsimptf,fsimpdf,fsimpsf,fhex,
floadtf,floaddf,floadsf,fstoredf,fstoresf,
fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
ftoi,fsqrttf,fsqrtdf,fsqrtsf,
@@ -1937,7 +1937,7 @@
#
#"
[(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*")
- (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*")])
+ (set_attr "type" "fhex,fsimptf,*,*,lm,stm,*,*")])
(define_insn "*mov<mode>_31"
[(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
@@ -1949,7 +1949,7 @@
#
#"
[(set_attr "op_type" "RRE,RRE,*,*")
- (set_attr "type" "fsimptf,fsimptf,*,*")])
+ (set_attr "type" "fhex,fsimptf,*,*")])
; TFmode in GPRs splitters
@@ -2057,7 +2057,7 @@
lg\t%0,%1
stg\t%1,%0"
[(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RRE,RXY,RXY")
- (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
+ (set_attr "type" "fhex,floaddf,floaddf,floaddf,floaddf,floaddf,
fstoredf,fstoredf,lr,load,store")
(set_attr "z10prop" "*,
*,
@@ -2087,7 +2087,7 @@
lg\t%0,%1
stg\t%1,%0"
[(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RRE,RXY,RXY")
- (set_attr "type" "fsimp<mode>,fload<mode>,fload<mode>,fload<mode>,
+ (set_attr "type" "fhex,fload<mode>,fload<mode>,fload<mode>,
fstore<mode>,fstore<mode>,lr,load,store")
(set_attr "z10prop" "*,
*,
@@ -2119,7 +2119,7 @@
#
#"
[(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
- (set_attr "type" "fsimp<mode>,fload<mode>,fload<mode>,fload<mode>,
+ (set_attr "type" "fhex,fload<mode>,fload<mode>,fload<mode>,
fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")])
(define_split
@@ -2186,7 +2186,7 @@
st\t%1,%0
sty\t%1,%0"
[(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY")
- (set_attr "type" "fsimp<mode>,fload<mode>,fload<mode>,fload<mode>,
+ (set_attr "type" "fhex,fload<mode>,fload<mode>,fload<mode>,
fstore<mode>,fstore<mode>,lr,load,load,store,store")
(set_attr "z10prop" "*,
*,
@@ -5286,8 +5286,8 @@
; madbr, maebr, maxb, madb, maeb
(define_insn "*fmadd<mode>"
[(set (match_operand:DSF 0 "register_operand" "=f,f")
- (plus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "%f,f")
- (match_operand:DSF 2 "nonimmediate_operand" "f,R"))
+ (plus:DSF (mult:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f")
+ (match_operand:DSF 2 "nonimmediate_operand" "f,R"))
(match_operand:DSF 3 "register_operand" "0,0")))]
"TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
"@
@@ -5299,8 +5299,8 @@
; msxbr, msdbr, msebr, msxb, msdb, mseb
(define_insn "*fmsub<mode>"
[(set (match_operand:DSF 0 "register_operand" "=f,f")
- (minus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "f,f")
- (match_operand:DSF 2 "nonimmediate_operand" "f,R"))
+ (minus:DSF (mult:DSF (match_operand:DSF 1 "nonimmediate_operand" "f,f")
+ (match_operand:DSF 2 "nonimmediate_operand" "f,R"))
(match_operand:DSF 3 "register_operand" "0,0")))]
"TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
"@
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index ed8a698cbbc..d0f9932288a 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -177,7 +177,7 @@ static rtx find_barrier (int, rtx, rtx);
static int noncall_uses_reg (rtx, rtx, rtx *);
static rtx gen_block_redirect (rtx, int, int);
static void sh_reorg (void);
-static void output_stack_adjust (int, rtx, int, HARD_REG_SET *);
+static void output_stack_adjust (int, rtx, int, HARD_REG_SET *, bool);
static rtx frame_insn (rtx);
static rtx push (int);
static void pop (int);
@@ -6037,9 +6037,9 @@ output_jump_label_table (void)
static void
output_stack_adjust (int size, rtx reg, int epilogue_p,
- HARD_REG_SET *live_regs_mask)
+ HARD_REG_SET *live_regs_mask, bool frame_p)
{
- rtx (*emit_fn) (rtx) = epilogue_p ? &emit_insn : &frame_insn;
+ rtx (*emit_fn) (rtx) = frame_p ? &frame_insn : &emit_insn;
if (size)
{
HOST_WIDE_INT align = STACK_BOUNDARY / BITS_PER_UNIT;
@@ -6701,9 +6701,10 @@ sh_expand_prologue (void)
&& (NPARM_REGS(SImode)
> crtl->args.info.arg_count[(int) SH_ARG_INT]))
pretend_args = 0;
+ /* Dwarf2 module doesn't expect frame related insns here. */
output_stack_adjust (-pretend_args
- crtl->args.info.stack_regs * 8,
- stack_pointer_rtx, 0, NULL);
+ stack_pointer_rtx, 0, NULL, false);
if (TARGET_SHCOMPACT && flag_pic && crtl->args.info.call_cookie)
/* We're going to use the PIC register to load the address of the
@@ -6834,7 +6835,7 @@ sh_expand_prologue (void)
offset_base = d + d_rounding;
output_stack_adjust (-(save_size + d_rounding), stack_pointer_rtx,
- 0, NULL);
+ 0, NULL, true);
sh5_schedule_saves (&live_regs_mask, &schedule, offset_base);
tmp_pnt = schedule.temps;
@@ -7009,7 +7010,7 @@ sh_expand_prologue (void)
target_flags = save_flags;
output_stack_adjust (-rounded_frame_size (d) + d_rounding,
- stack_pointer_rtx, 0, NULL);
+ stack_pointer_rtx, 0, NULL, true);
if (frame_pointer_needed)
frame_insn (GEN_MOV (hard_frame_pointer_rtx, stack_pointer_rtx));
@@ -7074,7 +7075,7 @@ sh_expand_epilogue (bool sibcall_p)
See PR/18032 and PR/40313. */
emit_insn (gen_blockage ());
output_stack_adjust (frame_size, hard_frame_pointer_rtx, e,
- &live_regs_mask);
+ &live_regs_mask, false);
/* We must avoid moving the stack pointer adjustment past code
which reads from the local frame, else an interrupt could
@@ -7090,7 +7091,8 @@ sh_expand_epilogue (bool sibcall_p)
occur after the SP adjustment and clobber data in the local
frame. */
emit_insn (gen_blockage ());
- output_stack_adjust (frame_size, stack_pointer_rtx, e, &live_regs_mask);
+ output_stack_adjust (frame_size, stack_pointer_rtx, e,
+ &live_regs_mask, false);
}
if (SHMEDIA_REGS_STACK_ADJUST ())
@@ -7277,7 +7279,7 @@ sh_expand_epilogue (bool sibcall_p)
output_stack_adjust (crtl->args.pretend_args_size
+ save_size + d_rounding
+ crtl->args.info.stack_regs * 8,
- stack_pointer_rtx, e, NULL);
+ stack_pointer_rtx, e, NULL, false);
if (crtl->calls_eh_return)
emit_insn (GEN_ADD3 (stack_pointer_rtx, stack_pointer_rtx,
diff --git a/gcc/config/sol2-c.c b/gcc/config/sol2-c.c
index fc527b1beb7..da00377a432 100644
--- a/gcc/config/sol2-c.c
+++ b/gcc/config/sol2-c.c
@@ -36,8 +36,8 @@ along with GCC; see the file COPYING3. If not see
/* cmn_err only accepts "l" and "ll". */
static const format_length_info cmn_err_length_specs[] =
{
- { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 },
- { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89 }
+ { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
+ { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 }
};
static const format_flag_spec cmn_err_flag_specs[] =
diff --git a/gcc/config/t-slibgcc-elf-ver b/gcc/config/t-slibgcc-elf-ver
index 49692818476..d5ef9ca163f 100644
--- a/gcc/config/t-slibgcc-elf-ver
+++ b/gcc/config/t-slibgcc-elf-ver
@@ -28,6 +28,9 @@ SHLIB_OBJS = @shlib_objs@
SHLIB_DIR = @multilib_dir@
SHLIB_SLIBDIR_QUAL = @shlib_slibdir_qual@
SHLIB_LC = -lc
+SHLIB_MAKE_SOLINK = $(LN_S) $(SHLIB_SONAME) $(SHLIB_DIR)/$(SHLIB_SOLINK)
+SHLIB_INSTALL_SOLINK = $(LN_S) $(SHLIB_SONAME) \
+ $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK)
SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
-Wl,--soname=$(SHLIB_SONAME) \
@@ -40,7 +43,7 @@ SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
$(SHLIB_DIR)/$(SHLIB_SONAME).backup; \
else true; fi && \
mv $(SHLIB_DIR)/$(SHLIB_SONAME).tmp $(SHLIB_DIR)/$(SHLIB_SONAME) && \
- $(LN_S) $(SHLIB_SONAME) $(SHLIB_DIR)/$(SHLIB_SOLINK)
+ $(SHLIB_MAKE_SOLINK)
# $(slibdir) double quoted to protect it from expansion while building
# libgcc.mk. We want this delayed until actual install time.
SHLIB_INSTALL = \
@@ -48,7 +51,6 @@ SHLIB_INSTALL = \
$(INSTALL_DATA) $(SHLIB_DIR)/$(SHLIB_SONAME) \
$$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SONAME); \
rm -f $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK); \
- $(LN_S) $(SHLIB_SONAME) \
- $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK)
+ $(SHLIB_INSTALL_SOLINK)
SHLIB_MKMAP = $(srcdir)/mkmap-symver.awk
SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver
diff --git a/gcc/config/t-slibgcc-libgcc b/gcc/config/t-slibgcc-libgcc
new file mode 100644
index 00000000000..df004a5e964
--- /dev/null
+++ b/gcc/config/t-slibgcc-libgcc
@@ -0,0 +1,32 @@
+# Copyright (C) 2009 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 3, 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 COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Instead of creating $(SHLIB_SOLINK) symlink create a GNU ld
+# linker script which sources in both $(SHLIB_SONAME) and libgcc.a.
+# This is needed on targets where libgcc.a contains routines that aren't in
+# $(SHLIB_SONAME) and are needed for shared libraries.
+
+SHLIB_MAKE_SOLINK = \
+ (echo "/* GNU ld script"; \
+ echo " Use the shared library, but some functions are only in"; \
+ echo " the static library. */"; \
+ echo "GROUP ( $(SHLIB_SONAME) libgcc.a )" \
+ ) > $(SHLIB_DIR)/$(SHLIB_SOLINK)
+SHLIB_INSTALL_SOLINK = \
+ $(INSTALL_DATA) $(SHLIB_DIR)/$(SHLIB_SOLINK) \
+ $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK)
diff --git a/gcc/config/xtensa/unwind-dw2-xtensa.c b/gcc/config/xtensa/unwind-dw2-xtensa.c
index e7ca86a10fb..9544f65ab78 100644
--- a/gcc/config/xtensa/unwind-dw2-xtensa.c
+++ b/gcc/config/xtensa/unwind-dw2-xtensa.c
@@ -459,7 +459,7 @@ uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
} \
while (0)
-static void
+static void __attribute__((noinline))
uw_init_context_1 (struct _Unwind_Context *context, void *outer_cfa,
void *outer_ra)
{
diff --git a/gcc/configure b/gcc/configure
index dbc7f154a3b..2e9385e1756 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -2385,34 +2385,76 @@ $as_echo "$ac_res" >&6; }
} # ac_fn_c_check_type
-# ac_fn_c_check_header_preproc LINENO HEADER VAR
-# ----------------------------------------------
-# Tests whether HEADER is present, setting the cache variable VAR accordingly.
-ac_fn_c_check_header_preproc ()
+# ac_fn_c_find_intX_t LINENO BITS VAR
+# -----------------------------------
+# Finds a signed integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_intX_t ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5
+$as_echo_n "checking for int$2_t... " >&6; }
if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
+ eval "$3=no"
+ for ac_type in int$2_t 'int' 'long int' \
+ 'long long int' 'short int' 'signed char'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(0 < ($ac_type) (((($ac_type) 1 << ($2 - 2)) - 1) * 2 + 1))];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <$2>
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(($ac_type) (((($ac_type) 1 << ($2 - 2)) - 1) * 2 + 1)
+ < ($ac_type) (((($ac_type) 1 << ($2 - 2)) - 1) * 2 + 2))];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- eval "$3=yes"
+if ac_fn_c_try_compile "$LINENO"; then :
+
else
- eval "$3=no"
+ case $ac_type in #(
+ int$2_t) :
+ eval "$3=yes" ;; #(
+ *) :
+ eval "$3=\$ac_type" ;;
+esac
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ eval as_val=\$$3
+ if test "x$as_val" = x""no; then :
+
+else
+ break
+fi
+ done
fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-} # ac_fn_c_check_header_preproc
+} # ac_fn_c_find_intX_t
# ac_fn_c_try_link LINENO
# -----------------------
@@ -2460,6 +2502,87 @@ fi
} # ac_fn_c_try_link
+# ac_fn_c_find_uintX_t LINENO BITS VAR
+# ------------------------------------
+# Finds an unsigned integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_uintX_t ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5
+$as_echo_n "checking for uint$2_t... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \
+ 'unsigned long long int' 'unsigned short int' 'unsigned char'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(($ac_type) -1 >> ($2 - 1) == 1)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ case $ac_type in #(
+ uint$2_t) :
+ eval "$3=yes" ;; #(
+ *) :
+ eval "$3=\$ac_type" ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ eval as_val=\$$3
+ if test "x$as_val" = x""no; then :
+
+else
+ break
+fi
+ done
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_find_uintX_t
+
+# ac_fn_c_check_header_preproc LINENO HEADER VAR
+# ----------------------------------------------
+# Tests whether HEADER is present, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_preproc ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_preproc
+
# ac_fn_c_check_func LINENO FUNC VAR
# ----------------------------------
# Tests whether FUNC exists, setting the cache variable VAR accordingly
@@ -5698,6 +5821,370 @@ _ACEOF
fi
+ac_fn_c_find_intX_t "$LINENO" "8" "ac_cv_c_int8_t"
+case $ac_cv_c_int8_t in #(
+ no|yes) ;; #(
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define int8_t $ac_cv_c_int8_t
+_ACEOF
+;;
+esac
+
+ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t"
+case $ac_cv_c_int16_t in #(
+ no|yes) ;; #(
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define int16_t $ac_cv_c_int16_t
+_ACEOF
+;;
+esac
+
+ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t"
+case $ac_cv_c_int32_t in #(
+ no|yes) ;; #(
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define int32_t $ac_cv_c_int32_t
+_ACEOF
+;;
+esac
+
+ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t"
+case $ac_cv_c_int64_t in #(
+ no|yes) ;; #(
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define int64_t $ac_cv_c_int64_t
+_ACEOF
+;;
+esac
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5
+$as_echo_n "checking for long long int... " >&6; }
+if test "${ac_cv_type_long_long_int+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ /* For now, do not test the preprocessor; as of 2007 there are too many
+ implementations with broken preprocessors. Perhaps this can
+ be revisited in 2012. In the meantime, code should not expect
+ #if to work with literals wider than 32 bits. */
+ /* Test literals. */
+ long long int ll = 9223372036854775807ll;
+ long long int nll = -9223372036854775807LL;
+ unsigned long long int ull = 18446744073709551615ULL;
+ /* Test constant expressions. */
+ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+ ? 1 : -1)];
+ typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
+ ? 1 : -1)];
+ int i = 63;
+int
+main ()
+{
+/* Test availability of runtime routines for shift and division. */
+ long long int llmax = 9223372036854775807ll;
+ unsigned long long int ullmax = 18446744073709551615ull;
+ return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
+ | (llmax / ll) | (llmax % ll)
+ | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+ | (ullmax / ull) | (ullmax % ull));
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if test "$cross_compiling" = yes; then :
+ ac_cv_type_long_long_int=yes
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+ #ifndef LLONG_MAX
+ # define HALF \
+ (1LL << (sizeof (long long int) * CHAR_BIT - 2))
+ # define LLONG_MAX (HALF - 1 + HALF)
+ #endif
+int
+main ()
+{
+long long int n = 1;
+ int i;
+ for (i = 0; ; i++)
+ {
+ long long int m = n << i;
+ if (m >> i != n)
+ return 1;
+ if (LLONG_MAX / 2 < m)
+ break;
+ }
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_type_long_long_int=yes
+else
+ ac_cv_type_long_long_int=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+else
+ ac_cv_type_long_long_int=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5
+$as_echo "$ac_cv_type_long_long_int" >&6; }
+ if test $ac_cv_type_long_long_int = yes; then
+
+$as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h
+
+ fi
+
+
+
+ ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" "$ac_includes_default"
+if test "x$ac_cv_type_intmax_t" = x""yes; then :
+
+$as_echo "#define HAVE_INTMAX_T 1" >>confdefs.h
+
+else
+ test $ac_cv_type_long_long_int = yes \
+ && ac_type='long long int' \
+ || ac_type='long int'
+
+cat >>confdefs.h <<_ACEOF
+#define intmax_t $ac_type
+_ACEOF
+
+fi
+
+
+
+ ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default"
+if test "x$ac_cv_type_intptr_t" = x""yes; then :
+
+$as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h
+
+else
+ for ac_type in 'int' 'long int' 'long long int'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define intptr_t $ac_type
+_ACEOF
+
+ ac_type=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test -z "$ac_type" && break
+ done
+fi
+
+
+ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t"
+case $ac_cv_c_uint8_t in #(
+ no|yes) ;; #(
+ *)
+
+$as_echo "#define _UINT8_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint8_t $ac_cv_c_uint8_t
+_ACEOF
+;;
+ esac
+
+ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t"
+case $ac_cv_c_uint16_t in #(
+ no|yes) ;; #(
+ *)
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint16_t $ac_cv_c_uint16_t
+_ACEOF
+;;
+ esac
+
+ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t"
+case $ac_cv_c_uint32_t in #(
+ no|yes) ;; #(
+ *)
+
+$as_echo "#define _UINT32_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint32_t $ac_cv_c_uint32_t
+_ACEOF
+;;
+ esac
+
+ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t"
+case $ac_cv_c_uint64_t in #(
+ no|yes) ;; #(
+ *)
+
+$as_echo "#define _UINT64_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint64_t $ac_cv_c_uint64_t
+_ACEOF
+;;
+ esac
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5
+$as_echo_n "checking for unsigned long long int... " >&6; }
+if test "${ac_cv_type_unsigned_long_long_int+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ /* For now, do not test the preprocessor; as of 2007 there are too many
+ implementations with broken preprocessors. Perhaps this can
+ be revisited in 2012. In the meantime, code should not expect
+ #if to work with literals wider than 32 bits. */
+ /* Test literals. */
+ long long int ll = 9223372036854775807ll;
+ long long int nll = -9223372036854775807LL;
+ unsigned long long int ull = 18446744073709551615ULL;
+ /* Test constant expressions. */
+ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+ ? 1 : -1)];
+ typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
+ ? 1 : -1)];
+ int i = 63;
+int
+main ()
+{
+/* Test availability of runtime routines for shift and division. */
+ long long int llmax = 9223372036854775807ll;
+ unsigned long long int ullmax = 18446744073709551615ull;
+ return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
+ | (llmax / ll) | (llmax % ll)
+ | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+ | (ullmax / ull) | (ullmax % ull));
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_type_unsigned_long_long_int=yes
+else
+ ac_cv_type_unsigned_long_long_int=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5
+$as_echo "$ac_cv_type_unsigned_long_long_int" >&6; }
+ if test $ac_cv_type_unsigned_long_long_int = yes; then
+
+$as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h
+
+ fi
+
+
+
+ ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "$ac_includes_default"
+if test "x$ac_cv_type_uintmax_t" = x""yes; then :
+
+$as_echo "#define HAVE_UINTMAX_T 1" >>confdefs.h
+
+else
+ test $ac_cv_type_unsigned_long_long_int = yes \
+ && ac_type='unsigned long long int' \
+ || ac_type='unsigned long int'
+
+cat >>confdefs.h <<_ACEOF
+#define uintmax_t $ac_type
+_ACEOF
+
+fi
+
+
+
+ ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default"
+if test "x$ac_cv_type_uintptr_t" = x""yes; then :
+
+$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h
+
+else
+ for ac_type in 'unsigned int' 'unsigned long int' \
+ 'unsigned long long int'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define uintptr_t $ac_type
+_ACEOF
+
+ ac_type=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test -z "$ac_type" && break
+ done
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# ---------------------
# Warnings and checking
@@ -11078,13 +11565,13 @@ if test "${lt_cv_nm_interface+set}" = set; then :
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:11081: $ac_compile\"" >&5)
+ (eval echo "\"\$as_me:11568: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
- (eval echo "\"\$as_me:11084: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval echo "\"\$as_me:11571: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
- (eval echo "\"\$as_me:11087: output\"" >&5)
+ (eval echo "\"\$as_me:11574: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -12289,7 +12776,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 12292 "configure"' > conftest.$ac_ext
+ echo '#line 12779 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -13949,11 +14436,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13952: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:14439: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:13956: \$? = $ac_status" >&5
+ echo "$as_me:14443: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -14288,11 +14775,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:14291: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:14778: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:14295: \$? = $ac_status" >&5
+ echo "$as_me:14782: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -14393,11 +14880,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:14396: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:14883: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:14400: \$? = $ac_status" >&5
+ echo "$as_me:14887: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -14448,11 +14935,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:14451: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:14938: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:14455: \$? = $ac_status" >&5
+ echo "$as_me:14942: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -16830,7 +17317,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 16833 "configure"
+#line 17320 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -16926,7 +17413,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 16929 "configure"
+#line 17416 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -17403,7 +17890,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
GXX=no
@@ -17734,7 +18221,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "^ .* -L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
;;
*)
if test "$GXX" = yes; then
@@ -17799,7 +18286,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "^ .* -L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
;;
*)
if test "$GXX" = yes; then
@@ -18143,7 +18630,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
# FIXME: insert proper C++ library support
@@ -18227,7 +18714,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
# g++ 2.7 appears to require `-G' NOT `-shared' on this
# platform.
@@ -18238,7 +18725,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
fi
hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
@@ -18882,11 +19369,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:18885: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:19372: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:18889: \$? = $ac_status" >&5
+ echo "$as_me:19376: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -18981,11 +19468,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:18984: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:19471: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:18988: \$? = $ac_status" >&5
+ echo "$as_me:19475: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -19033,11 +19520,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:19036: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:19523: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:19040: \$? = $ac_status" >&5
+ echo "$as_me:19527: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -23498,16 +23985,7 @@ fi
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; }
then
- # Also check for ld.so support, i.e. glibc 2.11 or higher.
- if test x$host = x$build -a x$host = x$target &&
- glibcver=`ldd --version 2>/dev/null`; then
- glibcmajor=`expr "$glibcver" : "ldd (GNU libc) \([0-9]*\)"`
- glibcminor=`expr "$glibcver" : "ldd (GNU libc) [0-9]*\.\([0-9]*\)"`
- glibcnum=`expr $glibcmajor \* 1000 + $glibcminor`
- if test "$glibcnum" -ge 2011 ; then
- gcc_cv_as_gnu_unique_object=yes
- fi
- fi
+ gcc_cv_as_gnu_unique_object=yes
else
echo "configure: failed program was" >&5
cat conftest.s >&5
@@ -23518,7 +23996,16 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_gnu_unique_object" >&5
$as_echo "$gcc_cv_as_gnu_unique_object" >&6; }
if test $gcc_cv_as_gnu_unique_object = yes; then
- enable_gnu_unique_object=yes
+ # Also check for ld.so support, i.e. glibc 2.11 or higher.
+ if test x$host = x$build -a x$host = x$target &&
+ glibcver=`ldd --version 2>/dev/null`; then
+ glibcmajor=`expr "$glibcver" : "ldd (GNU libc) \([0-9]*\)"`
+ glibcminor=`expr "$glibcver" : "ldd (GNU libc) [0-9]*\.\([0-9]*\)"`
+ glibcnum=`expr $glibcmajor \* 1000 + $glibcminor`
+ if test "$glibcnum" -ge 2011 ; then
+ enable_gnu_unique_object=yes
+ fi
+ fi
fi
fi
@@ -23901,7 +24388,7 @@ else
# simply assert that glibc does provide this, which is true for all
# realistically usable GNU/Hurd configurations.
gcc_cv_libc_provides_ssp=yes;;
- *-*-darwin*)
+ *-*-darwin* | *-*-freebsd*)
ac_fn_c_check_func "$LINENO" "__stack_chk_fail" "ac_cv_func___stack_chk_fail"
if test "x$ac_cv_func___stack_chk_fail" = x""yes; then :
gcc_cv_libc_provides_ssp=yes
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 6cc94d88344..ca6e3c2ac51 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -311,6 +311,7 @@ AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_TYPES([long long], [AC_CHECK_SIZEOF(long long)])
AC_CHECK_TYPES([__int64], [AC_CHECK_SIZEOF(__int64)])
+GCC_STDINT_TYPES
# ---------------------
# Warnings and checking
@@ -3390,7 +3391,7 @@ Valid choices are 'yes' and 'no'.]) ;;
esac],
[gcc_GAS_CHECK_FEATURE([gnu_unique_object], gcc_cv_as_gnu_unique_object,
[elf,2,19,52],,
- [.type foo, @gnu_unique_object],
+ [.type foo, @gnu_unique_object],,
# Also check for ld.so support, i.e. glibc 2.11 or higher.
[if test x$host = x$build -a x$host = x$target &&
glibcver=`ldd --version 2>/dev/null`; then
@@ -3398,10 +3399,9 @@ Valid choices are 'yes' and 'no'.]) ;;
glibcminor=`expr "$glibcver" : "ldd (GNU libc) [[0-9]]*\.\([[0-9]]*\)"`
glibcnum=`expr $glibcmajor \* 1000 + $glibcminor`
if test "$glibcnum" -ge 2011 ; then
- gcc_cv_as_gnu_unique_object=yes
+ enable_gnu_unique_object=yes
fi
- fi],
- [enable_gnu_unique_object=yes])])
+ fi])])
if test x$enable_gnu_unique_object = xyes; then
AC_DEFINE(HAVE_GAS_GNU_UNIQUE_OBJECT, 1,
[Define if your assembler supports @gnu_unique_object.])
@@ -3720,7 +3720,7 @@ AC_CACHE_CHECK(__stack_chk_fail in target C library,
# simply assert that glibc does provide this, which is true for all
# realistically usable GNU/Hurd configurations.
gcc_cv_libc_provides_ssp=yes;;
- *-*-darwin*)
+ *-*-darwin* | *-*-freebsd*)
AC_CHECK_FUNC(__stack_chk_fail,[gcc_cv_libc_provides_ssp=yes],
[echo "no __stack_chk_fail on this target"])
;;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index bac7098db72..93b90b5c0ee 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,84 @@
+2009-09-14 Richard Henderson <rth@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (finish_asm_stmt): Update decl.
+ * parser.c (cp_parser_asm_definition): Parse asm goto.
+ (cp_parser_asm_label_list): New.
+ * pt.c (tsubst_copy_asm_operands): Don't recurse on labels.
+ (tsubst_expr): Handle asm labels.
+ * semantics.c (finish_asm_stmt): Add and use labels parameter.
+
+2009-09-14 Richard Henderson <rth@redhat.com>
+
+ * except.c (init_exception_processing): Don't call
+ default_init_unwind_resume_libfunc.
+ (cp_protect_cleanup_actions): Return the decl to call.
+ (build_exc_ptr): Use __builtin_eh_pointer.
+ * optimize.c (clone_body): Set eh_lp_nr, not eh_region.
+
+2009-09-13 Richard Guenther <rguenther@suse.de>
+ Rafael Avila de Espindola <espindola@google.com>
+
+ * except.c (init_exception_processing): Do not set
+ lang_eh_runtime_type.
+ (choose_personality_routine): Do not set eh_personality_decl,
+ set pragma_java_exceptions.
+ * cp-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define.
+ (LANG_HOOKS_EH_PERSONALITY): Likewise.
+ (cp_eh_personality_decl): New.
+ (cp_eh_personality): Likewise.
+ * Make-lang.in (cp-lang.o): Add $(EXPR_H) and $(EXCEPT_H)
+ dependencies.
+
+2009-09-13 Wei Guozhi <carrot@google.com>
+
+ PR c++/3187
+ * cp/optimize.c (build_delete_destructor_body): New function.
+ (maybe_clone_body): Call build_delete_destructor_body for
+ deleting destructor.
+
+2009-09-10 Jason Merrill <jason@redhat.com>
+
+ * repo.c (extract_string, get_base_filename, init_repo): constify.
+
+2009-09-09 Jason Merrill <jason@redhat.com>
+
+ * error.c (find_typenames_r): Also add decltypes.
+
+2009-09-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/28293
+ * decl2.c (grokfield): Check for explicit template argument lists.
+
+2009-09-09 Jack Howarth <howarth@bromo.med.uc.edu>
+
+ PR bootstrap/41180
+ * Make-lang.in: Remove redundant code from linkage for darwin10.
+
+2009-09-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/39923
+ * decl.c (build_init_list_var_init): Check return value of
+ perform_implicit_conversion.
+
+2009-09-03 Jason Merrill <jason@redhat.com>
+
+ * class.c (currently_open_class): Make sure we're dealing with the
+ main variant.
+
+ * cp-tree.h (enum overload_flags): Remove OP_FLAG.
+ * method.c (lazily_declare_fn): Check for dtorness in ABI warning.
+
+ * name-lookup.c (is_class_level): Remove.
+ (push_binding_level, leave_scope, resume_scope): Adjust.
+ (pushlevel_class): Adjust.
+ (poplevel_class): Make sure we're on class_binding_level.
+
+ * decl.c (grokmethod): Rename from start_method.
+ (finish_method): Remove.
+ * cp-tree.h: Adjust.
+ * parser.c (cp_parser_save_member_function_body): Adjust.
+
2009-09-03 Doug Kwan <dougkwan@google.com>
* tree.c (cp_fix_function_decl_p): New.
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 95feca4ada8..2b53ce58fef 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -73,8 +73,8 @@ g++-cross$(exeext): g++$(exeext)
# Shared with C front end:
CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o \
- incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o \
- c-gimplify.o c-omp.o tree-inline.o
+ incpath.o c-ppoutput.o c-cppbuiltin.o prefix.o \
+ c-gimplify.o c-omp.o
# Language-specific object files for C++ and Objective C++.
CXX_AND_OBJCXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
@@ -250,7 +250,7 @@ cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \
$(C_PRAGMA_H) toplev.h output.h input.h cp/operators.def $(TM_P_H)
cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) toplev.h debug.h langhooks.h \
$(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-cp.h \
- $(DIAGNOSTIC_H) cp/cp-objcp-common.h
+ $(DIAGNOSTIC_H) cp/cp-objcp-common.h $(EXPR_H) $(EXCEPT_H)
cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h \
output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(RTL_H) \
cp/operators.def $(TM_P_H) $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(C_PRAGMA_H) \
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 2c308cfb5c9..9938a3d84d1 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5846,6 +5846,8 @@ currently_open_class (tree t)
if (!CLASS_TYPE_P (t))
return false;
+ t = TYPE_MAIN_VARIANT (t);
+
/* We start looking from 1 because entry 0 is from global scope,
and has no type. */
for (i = current_class_depth; i > 0; --i)
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index 942bea94e98..2572fa99538 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -32,12 +32,15 @@ along with GCC; see the file COPYING3. If not see
#include "debug.h"
#include "cp-objcp-common.h"
#include "hashtab.h"
+#include "except.h"
+#include "expr.h"
enum c_language_kind c_language = clk_cxx;
static void cp_init_ts (void);
static const char * cxx_dwarf_name (tree t, int verbosity);
static enum classify_record cp_classify_record (tree type);
static bool cp_user_conv_function_p (tree);
+static tree cp_eh_personality (void);
/* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h;
consequently, there should be very few hooks below. */
@@ -74,6 +77,10 @@ static bool cp_user_conv_function_p (tree);
#define LANG_HOOKS_INIT_TS cp_init_ts
#undef LANG_HOOKS_USER_CONV_FUNCTION
#define LANG_HOOKS_USER_CONV_FUNCTION cp_user_conv_function_p
+#undef LANG_HOOKS_EH_PERSONALITY
+#define LANG_HOOKS_EH_PERSONALITY cp_eh_personality
+#undef LANG_HOOKS_EH_RUNTIME_TYPE
+#define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type
/* LIPO support. */
@@ -186,4 +193,26 @@ finish_file (void)
{
}
+static GTY(()) tree cp_eh_personality_decl;
+
+static tree
+cp_eh_personality (void)
+{
+ if (!cp_eh_personality_decl)
+ {
+ if (!pragma_java_exceptions)
+ cp_eh_personality_decl
+ = build_personality_function (USING_SJLJ_EXCEPTIONS
+ ? "__gxx_personality_sj0"
+ : "__gxx_personality_v0");
+ else
+ cp_eh_personality_decl
+ = build_personality_function (USING_SJLJ_EXCEPTIONS
+ ? "__gcj_personality_sj0"
+ : "__gcj_personality_v0");
+ }
+
+ return cp_eh_personality_decl;
+}
+
#include "gtype-cp.h"
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9ac09da99d9..1444367aa3b 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3805,7 +3805,7 @@ extern int at_eof;
TREE_PURPOSE slot. */
extern GTY(()) tree static_aggregates;
-enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
+enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
/* These are uses as bits in flags passed to various functions to
control their behavior. Despite the LOOKUP_ prefix, many of these
@@ -4419,8 +4419,7 @@ extern tree begin_function_body (void);
extern void finish_function_body (tree);
extern tree outer_curly_brace_block (tree);
extern tree finish_function (int);
-extern tree start_method (cp_decl_specifier_seq *, const cp_declarator *, tree);
-extern tree finish_method (tree);
+extern tree grokmethod (cp_decl_specifier_seq *, const cp_declarator *, tree);
extern void maybe_register_incomplete_var (tree);
extern void maybe_commonize_var (tree);
extern void complete_vars (tree);
@@ -4526,6 +4525,7 @@ extern void choose_personality_routine (enum languages);
extern tree eh_type_info (tree);
extern tree begin_eh_spec_block (void);
extern void finish_eh_spec_block (tree, tree);
+extern tree build_eh_type_type (tree);
/* in expr.c */
extern tree cplus_expand_constant (tree);
@@ -4824,7 +4824,8 @@ enum {
extern tree begin_compound_stmt (unsigned int);
extern void finish_compound_stmt (tree);
-extern tree finish_asm_stmt (int, tree, tree, tree, tree);
+extern tree finish_asm_stmt (int, tree, tree, tree, tree,
+ tree);
extern tree finish_label_stmt (tree);
extern void finish_label_decl (tree);
extern tree finish_parenthesized_expr (tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 70862fee674..fcc634d1336 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4434,6 +4434,9 @@ build_init_list_var_init (tree decl, tree type, tree init, tree *cleanup)
{
tree aggr_init, array, arrtype;
init = perform_implicit_conversion (type, init, tf_warning_or_error);
+ if (error_operand_p (init))
+ return error_mark_node;
+
aggr_init = TARGET_EXPR_INITIAL (init);
init = build2 (INIT_EXPR, type, decl, init);
@@ -12470,8 +12473,8 @@ finish_function (int flags)
CHANGES TO CODE IN `grokfield'. */
tree
-start_method (cp_decl_specifier_seq *declspecs,
- const cp_declarator *declarator, tree attrlist)
+grokmethod (cp_decl_specifier_seq *declspecs,
+ const cp_declarator *declarator, tree attrlist)
{
tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,
&attrlist);
@@ -12525,62 +12528,9 @@ start_method (cp_decl_specifier_seq *declspecs,
cp_finish_decl (fndecl, NULL_TREE, false, NULL_TREE, 0);
- /* Make a place for the parms. */
- begin_scope (sk_function_parms, fndecl);
-
DECL_IN_AGGR_P (fndecl) = 1;
return fndecl;
}
-
-/* Go through the motions of finishing a function definition.
- We don't compile this method until after the whole class has
- been processed.
-
- FINISH_METHOD must return something that looks as though it
- came from GROKFIELD (since we are defining a method, after all).
-
- This is called after parsing the body of the function definition.
- STMTS is the chain of statements that makes up the function body.
-
- DECL is the ..._DECL that `start_method' provided. */
-
-tree
-finish_method (tree decl)
-{
- tree fndecl = decl;
- tree old_initial;
-
- tree link;
-
- if (decl == void_type_node)
- return decl;
-
- old_initial = DECL_INITIAL (fndecl);
-
- /* Undo the level for the parms (from start_method).
- This is like poplevel, but it causes nothing to be
- saved. Saving information here confuses symbol-table
- output routines. Besides, this information will
- be correctly output when this method is actually
- compiled. */
-
- /* Clear out the meanings of the local variables of this level;
- also record in each decl which block it belongs to. */
-
- for (link = current_binding_level->names; link; link = TREE_CHAIN (link))
- {
- if (DECL_NAME (link) != NULL_TREE)
- pop_binding (DECL_NAME (link), link);
- gcc_assert (TREE_CODE (link) != FUNCTION_DECL);
- DECL_CONTEXT (link) = NULL_TREE;
- }
-
- poplevel (0, 0, 0);
-
- DECL_INITIAL (fndecl) = old_initial;
-
- return decl;
-}
/* VAR is a VAR_DECL. If its type is incomplete, remember VAR so that
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 2276ee8ee10..7432cab573c 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -250,7 +250,7 @@ maybe_retrofit_in_chrg (tree fn)
FUNCTION is a FUNCTION_DECL. It was created by `grokdeclarator'.
FLAGS contains bits saying what's special about today's
- arguments. 1 == DESTRUCTOR. 2 == OPERATOR.
+ arguments. DTOR_FLAG == DESTRUCTOR.
If FUNCTION is a destructor, then we must add the `auto-delete' field
as a second parameter. There is some hair associated with the fact
@@ -760,6 +760,7 @@ grokfield (const cp_declarator *declarator,
tree value;
const char *asmspec = 0;
int flags = LOOKUP_ONLYCONVERTING;
+ tree name;
if (init
&& TREE_CODE (init) == TREE_LIST
@@ -788,11 +789,21 @@ grokfield (const cp_declarator *declarator,
&& DECL_CONTEXT (value) != current_class_type)
return value;
- if (DECL_NAME (value) != NULL_TREE
- && IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_'
- && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr"))
- error ("member %qD conflicts with virtual function table field name",
- value);
+ name = DECL_NAME (value);
+
+ if (name != NULL_TREE)
+ {
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ {
+ error ("explicit template argument list not allowed");
+ return error_mark_node;
+ }
+
+ if (IDENTIFIER_POINTER (name)[0] == '_'
+ && ! strcmp (IDENTIFIER_POINTER (name), "_vptr"))
+ error ("member %qD conflicts with virtual function table field name",
+ value);
+ }
/* Stash away type declarations. */
if (TREE_CODE (value) == TYPE_DECL)
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 19649292627..5d38e026454 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1159,7 +1159,8 @@ dump_template_decl (tree t, int flags)
}
/* find_typenames looks through the type of the function template T
- and returns a VEC containing any typedefs or TYPENAME_TYPEs it finds. */
+ and returns a VEC containing any typedefs, decltypes or TYPENAME_TYPEs
+ it finds. */
struct find_typenames_t
{
@@ -1176,7 +1177,8 @@ find_typenames_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
if (TYPE_P (*tp) && is_typedef_decl (TYPE_NAME (*tp)))
/* Add the type of the typedef without any additional cv-quals. */
mv = TREE_TYPE (TYPE_NAME (*tp));
- else if (TREE_CODE (*tp) == TYPENAME_TYPE)
+ else if (TREE_CODE (*tp) == TYPENAME_TYPE
+ || TREE_CODE (*tp) == DECLTYPE_TYPE)
/* Add the typename without any cv-qualifiers. */
mv = TYPE_MAIN_VARIANT (*tp);
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index fdef154f5d1..1b13819ed67 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -43,7 +43,6 @@ along with GCC; see the file COPYING3. If not see
static void push_eh_cleanup (tree);
static tree prepare_eh_type (tree);
-static tree build_eh_type_type (tree);
static tree do_begin_catch (void);
static int dtor_nothrow (tree);
static tree do_end_catch (tree);
@@ -54,7 +53,7 @@ static tree wrap_cleanups_r (tree *, int *, void *);
static int complete_ptr_ref_or_void_ptr_p (tree, tree);
static bool is_admissible_throw_operand (tree);
static int can_convert_eh (tree, tree);
-static gimple cp_protect_cleanup_actions (void);
+static tree cp_protect_cleanup_actions (void);
/* Sets up all the global eh stuff that needs to be initialized at the
start of compilation. */
@@ -78,29 +77,20 @@ init_exception_processing (void)
call_unexpected_node
= push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
- eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
- ? "__gxx_personality_sj0"
- : "__gxx_personality_v0");
- if (targetm.arm_eabi_unwinder)
- unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
- else
- default_init_unwind_resume_libfunc ();
-
- lang_eh_runtime_type = build_eh_type_type;
lang_protect_cleanup_actions = &cp_protect_cleanup_actions;
}
/* Returns an expression to be executed if an unhandled exception is
propagated out of a cleanup region. */
-static gimple
+static tree
cp_protect_cleanup_actions (void)
{
/* [except.terminate]
When the destruction of an object during stack unwinding exits
using an exception ... void terminate(); is called. */
- return gimple_build_call (terminate_node, 0);
+ return terminate_node;
}
static tree
@@ -143,7 +133,7 @@ eh_type_info (tree type)
/* Build the address of a typeinfo decl for use in the runtime
matching field of the exception model. */
-static tree
+tree
build_eh_type_type (tree type)
{
tree exp = eh_type_info (type);
@@ -159,7 +149,8 @@ build_eh_type_type (tree type)
tree
build_exc_ptr (void)
{
- return build0 (EXC_PTR_EXPR, ptr_type_node);
+ return build_call_n (built_in_decls [BUILT_IN_EH_POINTER],
+ 1, integer_zero_node);
}
/* Declare a function NAME, returning RETURN_TYPE, taking a single
@@ -313,7 +304,7 @@ decl_is_java_type (tree decl, int err)
/* Select the personality routine to be used for exception handling,
or issue an error if we need two different ones in the same
translation unit.
- ??? At present eh_personality_libfunc is set to
+ ??? At present eh_personality_decl is set to
__gxx_personality_(sj|v)0 in init_exception_processing - should it
be done here instead? */
void
@@ -354,9 +345,7 @@ choose_personality_routine (enum languages lang)
case lang_java:
state = chose_java;
terminate_node = built_in_decls [BUILT_IN_ABORT];
- eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
- ? "__gcj_personality_sj0"
- : "__gcj_personality_v0");
+ pragma_java_exceptions = true;
break;
default:
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 4563e8f6b5c..6acf1bb4b71 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1161,7 +1161,7 @@ lazily_declare_fn (special_function_kind sfk, tree type)
/* G++ 3.2 put the implicit destructor at the *beginning* of the
TYPE_METHODS list, which cause the destructor to be emitted
in an incorrect location in the vtable. */
- if (warn_abi && DECL_VIRTUAL_P (fn))
+ if (warn_abi && sfk == sfk_destructor && DECL_VIRTUAL_P (fn))
warning (OPT_Wabi, "vtable layout for class %qT may not be ABI-compliant"
"and may change in a future version of GCC due to "
"implicit virtual destructor",
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 07eefa5fbbc..dbac8ba916a 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -1261,7 +1261,6 @@ check_for_out_of_scope_variable (tree decl)
static bool keep_next_level_flag;
static int binding_depth = 0;
-static int is_class_level = 0;
static void
indent (int depth)
@@ -1343,7 +1342,6 @@ push_binding_level (struct cp_binding_level *scope)
scope->binding_depth = binding_depth;
indent (binding_depth);
cxx_scope_debug (scope, input_line, "push");
- is_class_level = 0;
binding_depth++;
}
}
@@ -1431,12 +1429,6 @@ leave_scope (void)
{
indent (--binding_depth);
cxx_scope_debug (scope, input_line, "leave");
- if (is_class_level != (scope == class_binding_level))
- {
- indent (binding_depth);
- verbatim ("XXX is_class_level != (current_scope == class_scope)\n");
- }
- is_class_level = 0;
}
/* Move one nesting level up. */
@@ -1486,7 +1478,6 @@ resume_scope (struct cp_binding_level* b)
b->binding_depth = binding_depth;
indent (binding_depth);
cxx_scope_debug (b, input_line, "resume");
- is_class_level = 0;
binding_depth++;
}
}
@@ -2566,9 +2557,6 @@ pop_inner_scope (tree outer, tree inner)
void
pushlevel_class (void)
{
- if (ENABLE_SCOPE_CHECKING)
- is_class_level = 1;
-
class_binding_level = begin_scope (sk_class, current_class_type);
}
@@ -2606,9 +2594,7 @@ poplevel_class (void)
/* Now, pop out of the binding level which we created up in the
`pushlevel_class' routine. */
- if (ENABLE_SCOPE_CHECKING)
- is_class_level = 1;
-
+ gcc_assert (current_binding_level == level);
leave_scope ();
timevar_pop (TV_NAME_LOOKUP);
}
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index c9d6cebb817..58d5b9001d2 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, 2005, 2007, 2008
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
Written by Mark Michell (mark@codesourcery.com).
@@ -99,13 +99,48 @@ clone_body (tree clone, tree fn, void *arg_map)
id.transform_lang_insert_block = NULL;
/* We're not inside any EH region. */
- id.eh_region = -1;
+ id.eh_lp_nr = 0;
stmts = DECL_SAVED_TREE (fn);
walk_tree (&stmts, copy_tree_body_r, &id, NULL);
append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
}
+/* DELETE_DTOR is a delete destructor whose body will be built.
+ COMPLETE_DTOR is the corresponding complete destructor. */
+
+static void
+build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
+{
+ tree call_dtor, call_delete;
+ tree parm = DECL_ARGUMENTS (delete_dtor);
+ tree virtual_size = cxx_sizeof (current_class_type);
+
+ /* Call the corresponding complete destructor. */
+ gcc_assert (complete_dtor);
+ call_dtor = build_cxx_call (complete_dtor, 1, &parm);
+ add_stmt (call_dtor);
+
+ add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label));
+
+ /* Call the delete function. */
+ call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
+ virtual_size,
+ /*global_p=*/false,
+ /*placement=*/NULL_TREE,
+ /*alloc_fn=*/NULL_TREE);
+ add_stmt (call_delete);
+
+ /* Return the address of the object. */
+ if (targetm.cxx.cdtor_returns_this ())
+ {
+ tree val = DECL_ARGUMENTS (delete_dtor);
+ val = build2 (MODIFY_EXPR, TREE_TYPE (val),
+ DECL_RESULT (delete_dtor), val);
+ add_stmt (build_stmt (0, RETURN_EXPR, val));
+ }
+}
+
/* FN is a function that has a complete body. Clone the body as
necessary. Returns nonzero if there's no longer any need to
process the main body. */
@@ -114,6 +149,7 @@ bool
maybe_clone_body (tree fn)
{
tree clone;
+ tree complete_dtor = NULL_TREE;
bool first = true;
/* We only clone constructors and destructors. */
@@ -124,6 +160,15 @@ maybe_clone_body (tree fn)
/* Emit the DWARF1 abstract instance. */
(*debug_hooks->deferred_inline_function) (fn);
+ /* Look for the complete destructor which may be used to build the
+ delete destructor. */
+ FOR_EACH_CLONE (clone, fn)
+ if (DECL_NAME (clone) == complete_dtor_identifier)
+ {
+ complete_dtor = clone;
+ break;
+ }
+
/* We know that any clones immediately follow FN in the TYPE_METHODS
list. */
push_to_top_level ();
@@ -176,59 +221,67 @@ maybe_clone_body (tree fn)
/* Start processing the function. */
start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED);
- /* Remap the parameters. */
- decl_map = pointer_map_create ();
- for (parmno = 0,
- parm = DECL_ARGUMENTS (fn),
- clone_parm = DECL_ARGUMENTS (clone);
- parm;
- ++parmno,
- parm = TREE_CHAIN (parm))
- {
- /* Map the in-charge parameter to an appropriate constant. */
- if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
- {
- tree in_charge;
- in_charge = in_charge_arg_for_name (DECL_NAME (clone));
- *pointer_map_insert (decl_map, parm) = in_charge;
- }
- else if (DECL_ARTIFICIAL (parm)
- && DECL_NAME (parm) == vtt_parm_identifier)
- {
- /* For a subobject constructor or destructor, the next
- argument is the VTT parameter. Remap the VTT_PARM
- from the CLONE to this parameter. */
- if (DECL_HAS_VTT_PARM_P (clone))
- {
- DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
- *pointer_map_insert (decl_map, parm) = clone_parm;
- clone_parm = TREE_CHAIN (clone_parm);
- }
- /* Otherwise, map the VTT parameter to `NULL'. */
- else
- *pointer_map_insert (decl_map, parm)
- = fold_convert (TREE_TYPE (parm), null_pointer_node);
- }
- /* Map other parameters to their equivalents in the cloned
- function. */
- else
- {
- *pointer_map_insert (decl_map, parm) = clone_parm;
- clone_parm = TREE_CHAIN (clone_parm);
- }
- }
-
- if (targetm.cxx.cdtor_returns_this ())
- {
- parm = DECL_RESULT (fn);
- clone_parm = DECL_RESULT (clone);
- *pointer_map_insert (decl_map, parm) = clone_parm;
- }
- /* Clone the body. */
- clone_body (clone, fn, decl_map);
-
- /* Clean up. */
- pointer_map_destroy (decl_map);
+ /* Build the delete destructor by calling complete destructor
+ and delete function. */
+ if (DECL_NAME (clone) == deleting_dtor_identifier)
+ build_delete_destructor_body (clone, complete_dtor);
+ else
+ {
+ /* Remap the parameters. */
+ decl_map = pointer_map_create ();
+ for (parmno = 0,
+ parm = DECL_ARGUMENTS (fn),
+ clone_parm = DECL_ARGUMENTS (clone);
+ parm;
+ ++parmno,
+ parm = TREE_CHAIN (parm))
+ {
+ /* Map the in-charge parameter to an appropriate constant. */
+ if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
+ {
+ tree in_charge;
+ in_charge = in_charge_arg_for_name (DECL_NAME (clone));
+ *pointer_map_insert (decl_map, parm) = in_charge;
+ }
+ else if (DECL_ARTIFICIAL (parm)
+ && DECL_NAME (parm) == vtt_parm_identifier)
+ {
+ /* For a subobject constructor or destructor, the next
+ argument is the VTT parameter. Remap the VTT_PARM
+ from the CLONE to this parameter. */
+ if (DECL_HAS_VTT_PARM_P (clone))
+ {
+ DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
+ *pointer_map_insert (decl_map, parm) = clone_parm;
+ clone_parm = TREE_CHAIN (clone_parm);
+ }
+ /* Otherwise, map the VTT parameter to `NULL'. */
+ else
+ *pointer_map_insert (decl_map, parm)
+ = fold_convert (TREE_TYPE (parm), null_pointer_node);
+ }
+ /* Map other parameters to their equivalents in the cloned
+ function. */
+ else
+ {
+ *pointer_map_insert (decl_map, parm) = clone_parm;
+ clone_parm = TREE_CHAIN (clone_parm);
+ }
+ }
+
+ if (targetm.cxx.cdtor_returns_this ())
+ {
+ parm = DECL_RESULT (fn);
+ clone_parm = DECL_RESULT (clone);
+ *pointer_map_insert (decl_map, parm) = clone_parm;
+ }
+
+ /* Clone the body. */
+ clone_body (clone, fn, decl_map);
+
+ /* Clean up. */
+ pointer_map_destroy (decl_map);
+ }
/* The clone can throw iff the original function can throw. */
cp_function_chain->can_throw = !TREE_NOTHROW (fn);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b757d4f0a42..35d093da739 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1859,6 +1859,8 @@ static tree cp_parser_asm_operand_list
(cp_parser *);
static tree cp_parser_asm_clobber_list
(cp_parser *);
+static tree cp_parser_asm_label_list
+ (cp_parser *);
static tree cp_parser_attributes_opt
(cp_parser *);
static tree cp_parser_attribute_list
@@ -12531,7 +12533,10 @@ cp_parser_using_directive (cp_parser* parser)
: asm-operand-list [opt] ) ;
asm volatile [opt] ( string-literal : asm-operand-list [opt]
: asm-operand-list [opt]
- : asm-operand-list [opt] ) ; */
+ : asm-clobber-list [opt] ) ;
+ asm volatile [opt] goto ( string-literal : : asm-operand-list [opt]
+ : asm-clobber-list [opt]
+ : asm-goto-list ) ; */
static void
cp_parser_asm_definition (cp_parser* parser)
@@ -12540,11 +12545,14 @@ cp_parser_asm_definition (cp_parser* parser)
tree outputs = NULL_TREE;
tree inputs = NULL_TREE;
tree clobbers = NULL_TREE;
+ tree labels = NULL_TREE;
tree asm_stmt;
bool volatile_p = false;
bool extended_p = false;
bool invalid_inputs_p = false;
bool invalid_outputs_p = false;
+ bool goto_p = false;
+ const char *missing = NULL;
/* Look for the `asm' keyword. */
cp_parser_require_keyword (parser, RID_ASM, "%<asm%>");
@@ -12557,6 +12565,15 @@ cp_parser_asm_definition (cp_parser* parser)
/* Consume the token. */
cp_lexer_consume_token (parser->lexer);
}
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && parser->in_function_body
+ && cp_lexer_next_token_is_keyword (parser->lexer, RID_GOTO))
+ {
+ /* Remember that we saw the `goto' keyword. */
+ goto_p = true;
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
/* Look for the opening `('. */
if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
return;
@@ -12581,6 +12598,7 @@ cp_parser_asm_definition (cp_parser* parser)
{
bool inputs_p = false;
bool clobbers_p = false;
+ bool labels_p = false;
/* The extended syntax was used. */
extended_p = true;
@@ -12596,7 +12614,8 @@ cp_parser_asm_definition (cp_parser* parser)
&& cp_lexer_next_token_is_not (parser->lexer,
CPP_SCOPE)
&& cp_lexer_next_token_is_not (parser->lexer,
- CPP_CLOSE_PAREN))
+ CPP_CLOSE_PAREN)
+ && !goto_p)
outputs = cp_parser_asm_operand_list (parser);
if (outputs == error_mark_node)
@@ -12618,6 +12637,8 @@ cp_parser_asm_definition (cp_parser* parser)
if (cp_lexer_next_token_is_not (parser->lexer,
CPP_COLON)
&& cp_lexer_next_token_is_not (parser->lexer,
+ CPP_SCOPE)
+ && cp_lexer_next_token_is_not (parser->lexer,
CPP_CLOSE_PAREN))
inputs = cp_parser_asm_operand_list (parser);
@@ -12632,16 +12653,41 @@ cp_parser_asm_definition (cp_parser* parser)
if (clobbers_p
|| cp_lexer_next_token_is (parser->lexer, CPP_COLON))
{
+ clobbers_p = true;
/* Consume the `:' or `::'. */
cp_lexer_consume_token (parser->lexer);
/* Parse the clobbers. */
if (cp_lexer_next_token_is_not (parser->lexer,
- CPP_CLOSE_PAREN))
+ CPP_COLON)
+ && cp_lexer_next_token_is_not (parser->lexer,
+ CPP_CLOSE_PAREN))
clobbers = cp_parser_asm_clobber_list (parser);
}
+ else if (goto_p
+ && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+ /* The labels are coming next. */
+ labels_p = true;
+
+ /* Look for labels. */
+ if (labels_p
+ || (goto_p && cp_lexer_next_token_is (parser->lexer, CPP_COLON)))
+ {
+ labels_p = true;
+ /* Consume the `:' or `::'. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the labels. */
+ labels = cp_parser_asm_label_list (parser);
+ }
+
+ if (goto_p && !labels_p)
+ missing = clobbers_p ? "%<:%>" : "%<:%> or %<::%>";
}
+ else if (goto_p)
+ missing = "%<:%> or %<::%>";
+
/* Look for the closing `)'. */
- if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
+ if (!cp_parser_require (parser, missing ? CPP_COLON : CPP_CLOSE_PAREN,
+ missing ? missing : "%<)%>"))
cp_parser_skip_to_closing_parenthesis (parser, true, false,
/*consume_paren=*/true);
cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
@@ -12652,7 +12698,7 @@ cp_parser_asm_definition (cp_parser* parser)
if (parser->in_function_body)
{
asm_stmt = finish_asm_stmt (volatile_p, string, outputs,
- inputs, clobbers);
+ inputs, clobbers, labels);
/* If the extended syntax was not used, mark the ASM_EXPR. */
if (!extended_p)
{
@@ -16866,6 +16912,49 @@ cp_parser_asm_clobber_list (cp_parser* parser)
return clobbers;
}
+/* Parse an asm-label-list.
+
+ asm-label-list:
+ identifier
+ asm-label-list , identifier
+
+ Returns a TREE_LIST, indicating the labels in the order that they
+ appeared. The TREE_VALUE of each node is a label. */
+
+static tree
+cp_parser_asm_label_list (cp_parser* parser)
+{
+ tree labels = NULL_TREE;
+
+ while (true)
+ {
+ tree identifier, label, name;
+
+ /* Look for the identifier. */
+ identifier = cp_parser_identifier (parser);
+ if (!error_operand_p (identifier))
+ {
+ label = lookup_label (identifier);
+ if (TREE_CODE (label) == LABEL_DECL)
+ {
+ TREE_USED (label) = 1;
+ check_goto (label);
+ name = build_string (IDENTIFIER_LENGTH (identifier),
+ IDENTIFIER_POINTER (identifier));
+ labels = tree_cons (name, label, labels);
+ }
+ }
+ /* If the next token is not a `,', then the list is
+ complete. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ /* Consume the `,' token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ return nreverse (labels);
+}
+
/* Parse an (optional) series of attributes.
attributes:
@@ -18172,8 +18261,8 @@ cp_parser_save_member_function_body (cp_parser* parser,
cp_token *last;
tree fn;
- /* Create the function-declaration. */
- fn = start_method (decl_specifiers, declarator, attributes);
+ /* Create the FUNCTION_DECL. */
+ fn = grokmethod (decl_specifiers, declarator, attributes);
/* If something went badly wrong, bail out now. */
if (fn == error_mark_node)
{
@@ -18221,9 +18310,6 @@ cp_parser_save_member_function_body (cp_parser* parser,
friend templates are handled correctly. */
DECL_INITIALIZED_IN_CLASS_P (fn) = 1;
- /* We're done with the inline definition. */
- finish_method (fn);
-
/* Add FN to the queue of functions to be parsed later. */
TREE_VALUE (parser->unparsed_functions_queues)
= tree_cons (NULL_TREE, fn,
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 0e219627e24..0bd7deb1f43 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -10820,7 +10820,7 @@ tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain,
if (purpose)
purpose = RECUR (purpose);
value = TREE_VALUE (t);
- if (value)
+ if (value && TREE_CODE (value) != LABEL_DECL)
value = RECUR (value);
chain = TREE_CHAIN (t);
if (chain && chain != void_type_node)
@@ -11212,7 +11212,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
RECUR (ASM_STRING (t)),
tsubst_copy_asm_operands (ASM_OUTPUTS (t), args, complain, in_decl),
tsubst_copy_asm_operands (ASM_INPUTS (t), args, complain, in_decl),
- tsubst_copy_asm_operands (ASM_CLOBBERS (t), args, complain, in_decl));
+ tsubst_copy_asm_operands (ASM_CLOBBERS (t), args, complain, in_decl),
+ tsubst_copy_asm_operands (ASM_LABELS (t), args, complain, in_decl));
{
tree asm_expr = tmp;
if (TREE_CODE (asm_expr) == CLEANUP_POINT_EXPR)
diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c
index 0f531e2627c..aa970785ca3 100644
--- a/gcc/cp/repo.c
+++ b/gcc/cp/repo.c
@@ -37,7 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "flags.h"
-static char *extract_string (char **);
+static const char *extract_string (const char **);
static const char *get_base_filename (const char *);
static FILE *open_repo_file (const char *);
static char *afgets (FILE *);
@@ -53,10 +53,10 @@ static bool temporary_obstack_initialized_p;
/* Parse a reasonable subset of shell quoting syntax. */
-static char *
-extract_string (char **pp)
+static const char *
+extract_string (const char **pp)
{
- char *p = *pp;
+ const char *p = *pp;
int backquote = 0;
int inside = 0;
@@ -89,13 +89,13 @@ extract_string (char **pp)
static const char *
get_base_filename (const char *filename)
{
- char *p = getenv ("COLLECT_GCC_OPTIONS");
+ const char *p = getenv ("COLLECT_GCC_OPTIONS");
const char *output = NULL;
int compiling = 0;
while (p && *p)
{
- char *q = extract_string (&p);
+ const char *q = extract_string (&p);
if (strcmp (q, "-o") == 0)
{
@@ -161,6 +161,7 @@ void
init_repo (void)
{
char *buf;
+ const char *p;
FILE *repo_file;
if (! flag_use_repository)
@@ -212,8 +213,8 @@ init_repo (void)
fclose (repo_file);
if (old_args && !get_random_seed (true)
- && (buf = strstr (old_args, "'-frandom-seed=")))
- set_random_seed (extract_string (&buf) + strlen ("-frandom-seed="));
+ && (p = strstr (old_args, "'-frandom-seed=")))
+ set_random_seed (extract_string (&p) + strlen ("-frandom-seed="));
}
static FILE *
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 8a3c831d544..ee1d22d889b 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1200,12 +1200,13 @@ finish_compound_stmt (tree stmt)
}
/* Finish an asm-statement, whose components are a STRING, some
- OUTPUT_OPERANDS, some INPUT_OPERANDS, and some CLOBBERS. Also note
- whether the asm-statement should be considered volatile. */
+ OUTPUT_OPERANDS, some INPUT_OPERANDS, some CLOBBERS and some
+ LABELS. Also note whether the asm-statement should be
+ considered volatile. */
tree
finish_asm_stmt (int volatile_p, tree string, tree output_operands,
- tree input_operands, tree clobbers)
+ tree input_operands, tree clobbers, tree labels)
{
tree r;
tree t;
@@ -1223,7 +1224,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
oconstraints = (const char **) alloca (noutputs * sizeof (char *));
string = resolve_asm_operand_names (string, output_operands,
- input_operands);
+ input_operands, labels);
for (i = 0, t = output_operands; t; t = TREE_CHAIN (t), ++i)
{
@@ -1309,7 +1310,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
r = build_stmt (input_location, ASM_EXPR, string,
output_operands, input_operands,
- clobbers);
+ clobbers, labels);
ASM_VOLATILE_P (r) = volatile_p || noutputs == 0;
r = maybe_cleanup_point_expr_void (r);
return add_stmt (r);
@@ -3192,7 +3193,8 @@ emit_associated_thunks (tree fn)
enabling you to output all the thunks with the function itself. */
if (DECL_VIRTUAL_P (fn)
/* Do not emit thunks for extern template instantiations. */
- && ! DECL_REALLY_EXTERN (fn))
+ && ! DECL_REALLY_EXTERN (fn)
+ && ! cgraph_is_auxiliary (fn))
{
tree thunk;
diff --git a/gcc/cse.c b/gcc/cse.c
index 3f3b863794f..8f49a9af9f5 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -6544,9 +6544,9 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr)
case CALL_INSN:
case INSN:
case JUMP_INSN:
- /* We expect dest to be NULL_RTX here. If the insn may trap, mark
- this fact by setting DEST to pc_rtx. */
- if (flag_non_call_exceptions && may_trap_p (PATTERN (x)))
+ /* We expect dest to be NULL_RTX here. If the insn may trap, mark
+ this fact by setting DEST to pc_rtx. */
+ if (insn_could_throw_p (x))
dest = pc_rtx;
if (code == CALL_INSN)
count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, dest, incr);
@@ -6658,7 +6658,7 @@ static bool
insn_live_p (rtx insn, int *counts)
{
int i;
- if (flag_non_call_exceptions && may_trap_p (PATTERN (insn)))
+ if (insn_could_throw_p (insn))
return true;
else if (GET_CODE (PATTERN (insn)) == SET)
return set_live_p (PATTERN (insn), insn, counts);
diff --git a/gcc/cselib.c b/gcc/cselib.c
index 8d52c519ff3..e6e5c143dad 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -1053,7 +1053,10 @@ cselib_expand_value_rtx (rtx orig, bitmap regs_active, int max_depth)
}
/* Same as cselib_expand_value_rtx, but using a callback to try to
- resolve VALUEs that expand to nothing. */
+ resolve some expressions. The CB function should return ORIG if it
+ can't or does not want to deal with a certain RTX. Any other
+ return value, including NULL, will be used as the expansion for
+ VALUE, without any further changes. */
rtx
cselib_expand_value_rtx_cb (rtx orig, bitmap regs_active, int max_depth,
@@ -1068,6 +1071,9 @@ cselib_expand_value_rtx_cb (rtx orig, bitmap regs_active, int max_depth,
return cselib_expand_value_rtx_1 (orig, &evd, max_depth);
}
+/* Internal implementation of cselib_expand_value_rtx and
+ cselib_expand_value_rtx_cb. */
+
static rtx
cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
int max_depth)
@@ -1158,8 +1164,18 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
case SUBREG:
{
- rtx subreg = cselib_expand_value_rtx_1 (SUBREG_REG (orig), evd,
- max_depth - 1);
+ rtx subreg;
+
+ if (evd->callback)
+ {
+ subreg = evd->callback (orig, evd->regs_active, max_depth,
+ evd->callback_arg);
+ if (subreg != orig)
+ return subreg;
+ }
+
+ subreg = cselib_expand_value_rtx_1 (SUBREG_REG (orig), evd,
+ max_depth - 1);
if (!subreg)
return NULL;
scopy = simplify_gen_subreg (GET_MODE (orig), subreg,
@@ -1168,16 +1184,16 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
if (scopy == NULL
|| (GET_CODE (scopy) == SUBREG
&& !REG_P (SUBREG_REG (scopy))
- && !MEM_P (SUBREG_REG (scopy))
- && (REG_P (SUBREG_REG (orig))
- || MEM_P (SUBREG_REG (orig)))))
- return shallow_copy_rtx (orig);
+ && !MEM_P (SUBREG_REG (scopy))))
+ return NULL;
+
return scopy;
}
case VALUE:
{
rtx result;
+
if (dump_file && (dump_flags & TDF_DETAILS))
{
fputs ("\nexpanding ", dump_file);
@@ -1185,20 +1201,16 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
fputs (" into...", dump_file);
}
- if (!evd->callback)
- result = NULL;
- else
+ if (evd->callback)
{
result = evd->callback (orig, evd->regs_active, max_depth,
evd->callback_arg);
- if (result == orig)
- result = NULL;
- else if (result)
- result = cselib_expand_value_rtx_1 (result, evd, max_depth);
+
+ if (result != orig)
+ return result;
}
- if (!result)
- result = expand_loc (CSELIB_VAL_PTR (orig)->locs, evd, max_depth);
+ result = expand_loc (CSELIB_VAL_PTR (orig)->locs, evd, max_depth);
return result;
}
default:
diff --git a/gcc/dbgcnt.c b/gcc/dbgcnt.c
index 0c496b308d6..3fe34854f06 100644
--- a/gcc/dbgcnt.c
+++ b/gcc/dbgcnt.c
@@ -101,7 +101,7 @@ dbg_cnt_set_limit_by_name (const char *name, int len, int value)
static const char *
dbg_cnt_process_single_pair (const char *arg)
{
- char *colon = strchr (arg, ':');
+ const char *colon = strchr (arg, ':');
char *endptr = NULL;
int value;
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index bc7965e25b8..097b20be860 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -902,7 +902,7 @@ dbxout_finish_complex_stabs (tree sym, stab_code_type code,
#if defined (DBX_DEBUGGING_INFO)
static void
-dbxout_function_end (tree decl)
+dbxout_function_end (tree decl ATTRIBUTE_UNUSED)
{
char lscope_label_name[100];
@@ -921,8 +921,7 @@ dbxout_function_end (tree decl)
named sections. */
if (!use_gnu_debug_info_extensions
|| NO_DBX_FUNCTION_END
- || !targetm.have_named_sections
- || DECL_IGNORED_P (decl))
+ || !targetm.have_named_sections)
return;
/* By convention, GCC will mark the end of a function with an N_FUN
@@ -3683,9 +3682,6 @@ dbxout_begin_function (tree decl)
{
int saved_tree_used1;
- if (DECL_IGNORED_P (decl))
- return;
-
saved_tree_used1 = TREE_USED (decl);
TREE_USED (decl) = 1;
if (DECL_NAME (DECL_RESULT (decl)) != 0)
diff --git a/gcc/dce.c b/gcc/dce.c
index 3e1dd47f3a4..b937dd44a19 100644
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -79,13 +79,7 @@ deletable_insn_p_1 (rtx body)
return false;
default:
- if (volatile_refs_p (body))
- return false;
-
- if (flag_non_call_exceptions && may_trap_p (body))
- return false;
-
- return true;
+ return !volatile_refs_p (body);
}
}
@@ -99,6 +93,14 @@ deletable_insn_p (rtx insn, bool fast, bitmap arg_stores)
rtx body, x;
int i;
+ /* Don't delete jumps, notes and the like. */
+ if (!NONJUMP_INSN_P (insn))
+ return false;
+
+ /* Don't delete insns that can throw. */
+ if (!insn_nothrow_p (insn))
+ return false;
+
if (CALL_P (insn)
/* We cannot delete calls inside of the recursive dce because
this may cause basic blocks to be deleted and this messes up
@@ -113,13 +115,6 @@ deletable_insn_p (rtx insn, bool fast, bitmap arg_stores)
&& !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)))
return find_call_stack_args (insn, false, fast, arg_stores);
- if (!NONJUMP_INSN_P (insn))
- return false;
-
- /* Similarly, we cannot delete other insns that can throw either. */
- if (df_in_progress && flag_non_call_exceptions && can_throw_internal (insn))
- return false;
-
body = PATTERN (insn);
switch (GET_CODE (body))
{
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 4e9f18924d1..22d9f6e3cc2 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2564,6 +2564,13 @@ SRAM@. The function will be put into a specific section named @code{.l1.text}.
With @option{-mfdpic}, function calls with a such function as the callee
or caller will use inlined PLT.
+@item l2
+@cindex @code{l2} function attribute
+On the Blackfin, this attribute specifies a function to be placed into L2
+SRAM. The function will be put into a specific section named
+@code{.l1.text}. With @option{-mfdpic}, callers of such functions will use
+an inlined PLT.
+
@item long_call/short_call
@cindex indirect calls on ARM
This attribute specifies how a particular function is called on
@@ -4191,6 +4198,12 @@ Variables with @code{l1_data} attribute will be put into the specific section
named @code{.l1.data}. Those with @code{l1_data_A} attribute will be put into
the specific section named @code{.l1.data.A}. Those with @code{l1_data_B}
attribute will be put into the specific section named @code{.l1.data.B}.
+
+@item l2
+@cindex @code{l2} variable attribute
+Use this attribute on the Blackfin to place the variable into L2 SRAM.
+Variables with @code{l2} attribute will be put into the specific section
+named @code{.l2.data}.
@end table
@subsection M32R/D Variable Attributes
@@ -5238,7 +5251,7 @@ and most Unix assemblers do.
Speaking of labels, jumps from one @code{asm} to another are not
supported. The compiler's optimizers do not know about these jumps, and
therefore they cannot take account of them when deciding how to
-optimize.
+optimize. @xref{Extended asm with goto}.
@cindex macros containing @code{asm}
Usually the most convenient way to use these @code{asm} instructions is to
@@ -5337,6 +5350,94 @@ For reasons similar to those described above, it is not possible to give
an assembler instruction access to the condition code left by previous
instructions.
+@anchor{Extended asm with goto}
+As of GCC version 4.5, @code{asm goto} may be used to have the assembly
+jump to one or more C labels. In this form, a fifth section after the
+clobber list contains a list of all C labels to which the assembly may jump.
+Each label operand is implicitly self-named. The @code{asm} is also assumed
+to fall through to the next statement.
+
+This form of @code{asm} is restricted to not have outputs. This is due
+to a internal restriction in the compiler that control transfer instructions
+cannot have outputs. This restriction on @code{asm goto} may be lifted
+in some future version of the compiler. In the mean time, @code{asm goto}
+may include a memory clobber, and so leave outputs in memory.
+
+@smallexample
+int frob(int x)
+@{
+ int y;
+ asm goto ("frob %%r5, %1; jc %l[error]; mov (%2), %%r5"
+ : : "r"(x), "r"(&y) : "r5", "memory" : error);
+ return y;
+ error:
+ return -1;
+@}
+@end smallexample
+
+In this (inefficient) example, the @code{frob} instruction sets the
+carry bit to indicate an error. The @code{jc} instruction detects
+this and branches to the @code{error} label. Finally, the output
+of the @code{frob} instruction (@code{%r5}) is stored into the memory
+for variable @code{y}, which is later read by the @code{return} statement.
+
+@smallexample
+void doit(void)
+@{
+ int i = 0;
+ asm goto ("mfsr %%r1, 123; jmp %%r1;"
+ ".pushsection doit_table;"
+ ".long %l0, %l1, %l2, %l3;"
+ ".popsection"
+ : : : "r1" : label1, label2, label3, label4);
+ __builtin_unreachable ();
+
+ label1:
+ f1();
+ return;
+ label2:
+ f2();
+ return;
+ label3:
+ i = 1;
+ label4:
+ f3(i);
+@}
+@end smallexample
+
+In this (also inefficient) example, the @code{mfsr} instruction reads
+an address from some out-of-band machine register, and the following
+@code{jmp} instruction branches to that address. The address read by
+the @code{mfsr} instruction is assumed to have been previously set via
+some application-specific mechanism to be one of the four values stored
+in the @code{doit_table} section. Finally, the @code{asm} is followed
+by a call to @code{__builtin_unreachable} to indicate that the @code{asm}
+does not in fact fall through.
+
+@smallexample
+#define TRACE1(NUM) \
+ do @{ \
+ asm goto ("0: nop;" \
+ ".pushsection trace_table;" \
+ ".long 0b, %l0;" \
+ ".popsection" \
+ : : : : trace#NUM); \
+ if (0) @{ trace#NUM: trace(); @} \
+ @} while (0)
+#define TRACE TRACE1(__COUNTER__)
+@end smallexample
+
+In this example (which in fact inspired the @code{asm goto} feature)
+we want on rare occasions to call the @code{trace} function; on other
+occasions we'd like to keep the overhead to the absolute minimum.
+The normal code path consists of a single @code{nop} instruction.
+However, we record the address of this @code{nop} together with the
+address of a label that calls the @code{trace} function. This allows
+the @code{nop} instruction to be patched at runtime to be an
+unconditional branch to the stored label. It is assumed that an
+optimizing compiler will move the labeled block out of line, to
+optimize the fall through path from the @code{asm}.
+
If you are writing a header file that should be includable in ISO C
programs, write @code{__asm__} instead of @code{asm}. @xref{Alternate
Keywords}.
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index e0098bc156a..a929cca24fd 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -2710,7 +2710,7 @@ AIX:
@uref{http://pware.hvcc.edu,,Hudson Valley Community College Open Source Software for IBM System p};
@item
-@uref{http://www.perzl.org/aix,,AIX 5L and 6 Open Source Packages}.
+@uref{http://www.perzl.org/aix/,,AIX 5L and 6 Open Source Packages}.
@end itemize
@item
@@ -3070,8 +3070,6 @@ can also be obtained from:
@item
@uref{http://www.nongnu.org/avr/,,http://www.nongnu.org/avr/}
@item
-@uref{http://home.overta.ru/users/denisc/,,http://home.overta.ru/users/denisc/}
-@item
@uref{http://www.amelek.gda.pl/avr/,,http://www.amelek.gda.pl/avr/}
@end itemize
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 59e250168ae..142abeec978 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -335,7 +335,7 @@ Objective-C and Objective-C++ Dialects}.
-fcse-follow-jumps -fcse-skip-blocks -fcx-fortran-rules -fcx-limited-range @gol
-fdata-sections -fdce -fdce @gol
-fdelayed-branch -fdelete-null-pointer-checks -fdse -fdse @gol
--fearly-inlining -fexpensive-optimizations -ffast-math @gol
+-fearly-inlining -fipa-sra -fexpensive-optimizations -ffast-math @gol
-ffinite-math-only -ffloat-store -fexcess-precision=@var{style} @gol
-fforward-propagate -ffunction-sections @gol
-fgcse -fgcse-after-reload -fgcse-las -fgcse-lm @gol
@@ -5670,6 +5670,7 @@ also turns on the following optimization flags:
-fgcse -fgcse-lm @gol
-finline-small-functions @gol
-findirect-inlining @gol
+-fipa-sra @gol
-foptimize-sibling-calls @gol
-fpeephole2 @gol
-fregmove @gol
@@ -5830,6 +5831,14 @@ having large chains of nested wrapper functions.
Enabled by default.
+@item -fipa-sra
+@opindex fipa-sra
+Perform interprocedural scalar replacement of aggregates, removal of
+unused parameters and replacement of parameters passed by reference
+by parameters passed by value.
+
+Enabled at levels @option{-O2}, @option{-O3} and @option{-Os}.
+
@item -finline-limit=@var{n}
@opindex finline-limit
By default, GCC limits the size of functions that can be inlined. This flag
@@ -6880,7 +6889,7 @@ Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
@item -fstrict-aliasing
@opindex fstrict-aliasing
-Allows the compiler to assume the strictest aliasing rules applicable to
+Allow the compiler to assume the strictest aliasing rules applicable to
the language being compiled. For C (and C++), this activates
optimizations based on the type of expressions. In particular, an
object of one type is assumed never to reside at the same address as an
@@ -6897,7 +6906,7 @@ union a_union @{
@};
int f() @{
- a_union t;
+ union a_union t;
t.d = 3.0;
return t.i;
@}
@@ -6910,7 +6919,7 @@ expected. @xref{Structures unions enumerations and bit-fields
implementation}. However, this code might not:
@smallexample
int f() @{
- a_union t;
+ union a_union t;
int* ip;
t.d = 3.0;
ip = &t.i;
@@ -7661,7 +7670,7 @@ a lot of functions that would otherwise not be considered for inlining
by the compiler will be investigated. To those functions, a different
(more restrictive) limit compared to functions declared inline can
be applied.
-The default value is 60.
+The default value is 50.
@item large-function-insns
The limit specifying really large functions. For functions larger than this
@@ -7741,7 +7750,7 @@ whose probability exceeds given threshold (in percents). The default value is
@item early-inlining-insns
Specify growth that early inliner can make. In effect it increases amount of
-inlining for code having large abstraction penalty. The default value is 12.
+inlining for code having large abstraction penalty. The default value is 8.
@item max-early-inliner-iterations
@itemx max-early-inliner-iterations
@@ -8154,6 +8163,12 @@ the parameter is reserved exclusively for debug insns created by
@option{-fvar-tracking-assignments}, but debug insns may get
(non-overlapping) uids above it if the reserved range is exhausted.
+@item ipa-sra-ptr-growth-factor
+IPA-SRA will replace a pointer to an aggregate with one or more new
+parameters only when their cumulative size is less or equal to
+@option{ipa-sra-ptr-growth-factor} times the size of the original
+pointer parameter.
+
@end table
@end table
@@ -8867,7 +8882,16 @@ and @option{-imultilib} as necessary.
@item %s
Current argument is the name of a library or startup file of some sort.
Search for that file in a standard list of directories and substitute
-the full name found.
+the full name found. The current working directory is included in the
+list of directories scanned.
+
+@item %T
+Current argument is the name of a linker script. Search for that file
+in the current list of directories to scan for libraries. If the file
+is located insert a @option{--script} option into the command line
+followed by the full path name found. If the file is not found then
+generate an error message. Note: the current working directory is not
+searched.
@item %e@var{str}
Print @var{str} as an error message. @var{str} is terminated by a newline.
@@ -9716,6 +9740,7 @@ can be one of @samp{bf512}, @samp{bf514}, @samp{bf516}, @samp{bf518},
@samp{bf527}, @samp{bf531}, @samp{bf532}, @samp{bf533},
@samp{bf534}, @samp{bf536}, @samp{bf537}, @samp{bf538}, @samp{bf539},
@samp{bf542}, @samp{bf544}, @samp{bf547}, @samp{bf548}, @samp{bf549},
+@samp{bf542m}, @samp{bf544m}, @samp{bf547m}, @samp{bf548m}, @samp{bf549m},
@samp{bf561}.
The optional @var{sirevision} specifies the silicon revision of the target
Blackfin processor. Any workarounds available for the targeted silicon revision
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index 79baa10e25d..ba72b48096b 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -882,6 +882,14 @@ Stored in the @code{volatil} field and printed as @samp{/v}.
Most uses of @code{SYMBOL_REF_FLAG} are historic and may be subsumed
by @code{SYMBOL_REF_FLAGS}. Certainly use of @code{SYMBOL_REF_FLAGS}
is mandatory if the target requires more than one bit of storage.
+
+@findex PREFETCH_SCHEDULE_BARRIER_P
+@cindex @code{prefetch} and @samp{/v}
+@cindex @code{volatile}, in @code{prefetch}
+@item PREFETCH_SCHEDULE_BARRIER_P (@var{x})
+In a @code{prefetch}, indicates that the prefetch is a scheduling barrier.
+No other INSNs will be moved over it.
+Stored in the @code{volatil} field and printed as @samp{/v}.
@end table
These are the fields to which the above macros refer:
@@ -1034,6 +1042,9 @@ In an @code{insn}, 1 means the insn has been deleted.
In @code{label_ref} and @code{reg_label} expressions, 1 means a reference
to a non-local label.
+In @code{prefetch} expressions, 1 means that the containing insn is a
+scheduling barrier.
+
In an RTL dump, this flag is represented as @samp{/v}.
@end table
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index f236a7d1c1b..0139a8bfe6f 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5679,6 +5679,14 @@ the vectorized function shall be of vector type @var{vec_type_out} and the
argument types should be @var{vec_type_in}.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_SUPPORT_VECTOR_MISALIGNMENT (enum machine_mode @var{mode}, tree @var{type}, int @var{misalignment}, bool @var{is_packed})
+This hook should return true if the target supports misaligned vector
+store/load of a specific factor denoted in the @var{misalignment}
+parameter. The vector store/load should be of machine mode @var{mode} and
+the elements in the vectors should be of type @var{type}. @var{is_packed}
+parameter is true if the memory access is defined in a packed struct.
+@end deftypefn
+
@node Anchored Addresses
@section Anchored Addresses
@cindex anchored addresses
diff --git a/gcc/dse.c b/gcc/dse.c
index 3e6b57d6ca1..9d3e2c07ed6 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -2531,7 +2531,7 @@ scan_insn (bb_info_t bb_info, rtx insn)
them. */
if ((GET_CODE (PATTERN (insn)) == CLOBBER)
|| volatile_refs_p (PATTERN (insn))
- || (flag_non_call_exceptions && may_trap_p (PATTERN (insn)))
+ || insn_could_throw_p (insn)
|| (RTX_FRAME_RELATED_P (insn))
|| find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX))
insn_info->cannot_delete = true;
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 3809765c405..37bd1e2d5da 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -216,6 +216,10 @@ static GTY(()) section *debug_str_section;
static GTY(()) section *debug_ranges_section;
static GTY(()) section *debug_frame_section;
+/* Personality decl of current unit. Used only when assembler does not support
+ personality CFI. */
+static GTY(()) rtx current_unit_personality;
+
/* How to start an assembler comment. */
#ifndef ASM_COMMENT_START
#define ASM_COMMENT_START ";#"
@@ -3599,6 +3603,7 @@ output_call_frame_info (int for_eh)
int per_encoding = DW_EH_PE_absptr;
int lsda_encoding = DW_EH_PE_absptr;
int return_reg;
+ rtx personality = NULL;
int dw_cie_version;
/* Don't emit a CIE if there won't be any FDEs. */
@@ -3684,6 +3689,8 @@ output_call_frame_info (int for_eh)
augmentation[0] = 0;
augmentation_size = 0;
+
+ personality = current_unit_personality;
if (for_eh)
{
char *p;
@@ -3703,11 +3710,11 @@ output_call_frame_info (int for_eh)
lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
p = augmentation + 1;
- if (eh_personality_libfunc)
+ if (personality)
{
*p++ = 'P';
augmentation_size += 1 + size_of_encoded_value (per_encoding);
- assemble_external_libcall (eh_personality_libfunc);
+ assemble_external_libcall (personality);
}
if (any_lsda_needed)
{
@@ -3726,7 +3733,7 @@ output_call_frame_info (int for_eh)
}
/* Ug. Some platforms can't do unaligned dynamic relocations at all. */
- if (eh_personality_libfunc && per_encoding == DW_EH_PE_aligned)
+ if (personality && per_encoding == DW_EH_PE_aligned)
{
int offset = ( 4 /* Length */
+ 4 /* CIE Id */
@@ -3760,12 +3767,12 @@ output_call_frame_info (int for_eh)
if (augmentation[0])
{
dw2_asm_output_data_uleb128 (augmentation_size, "Augmentation size");
- if (eh_personality_libfunc)
+ if (personality)
{
dw2_asm_output_data (1, per_encoding, "Personality (%s)",
eh_data_format_name (per_encoding));
dw2_asm_output_encoded_addr_rtx (per_encoding,
- eh_personality_libfunc,
+ personality,
true, NULL);
}
@@ -3824,13 +3831,14 @@ dwarf2out_do_cfi_startproc (bool second)
{
int enc;
rtx ref;
+ rtx personality = get_personality_function (current_function_decl);
fprintf (asm_out_file, "\t.cfi_startproc\n");
- if (eh_personality_libfunc)
+ if (personality)
{
enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
- ref = eh_personality_libfunc;
+ ref = personality;
/* ??? The GAS support isn't entirely consistent. We have to
handle indirect support ourselves, but PC-relative is done
@@ -3969,6 +3977,20 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
if (dwarf2out_do_cfi_asm ())
dwarf2out_do_cfi_startproc (false);
+ else
+ {
+ rtx personality = get_personality_function (current_function_decl);
+ if (!current_unit_personality)
+ current_unit_personality = personality;
+
+ /* We cannot keep a current personality per function as without CFI
+ asm at the point where we emit the CFI data there is no current
+ function anymore. */
+ if (personality
+ && current_unit_personality != personality)
+ sorry ("Multiple EH personalities are supported only with assemblers "
+ "supporting .cfi.personality directive.");
+ }
}
/* Output a marker (i.e. a label) for the absolute end of the generated code
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 65022fc65e3..9ed36b33211 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3492,13 +3492,7 @@ try_split (rtx pat, rtx trial, int last)
switch (REG_NOTE_KIND (note))
{
case REG_EH_REGION:
- for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
- {
- if (CALL_P (insn)
- || (flag_non_call_exceptions && INSN_P (insn)
- && may_trap_p (PATTERN (insn))))
- add_reg_note (insn, REG_EH_REGION, XEXP (note, 0));
- }
+ copy_reg_eh_region_note_backward (note, insn_last, NULL);
break;
case REG_NORETURN:
diff --git a/gcc/except.c b/gcc/except.c
index 7f9bc4af1a5..47c5681c4b5 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -21,30 +21,94 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
-/* An exception is an event that can be signaled from within a
- function. This event can then be "caught" or "trapped" by the
- callers of this function. This potentially allows program flow to
- be transferred to any arbitrary code associated with a function call
- several levels up the stack.
-
- The intended use for this mechanism is for signaling "exceptional
- events" in an out-of-band fashion, hence its name. The C++ language
- (and many other OO-styled or functional languages) practically
- requires such a mechanism, as otherwise it becomes very difficult
- or even impossible to signal failure conditions in complex
- situations. The traditional C++ example is when an error occurs in
- the process of constructing an object; without such a mechanism, it
- is impossible to signal that the error occurs without adding global
- state variables and error checks around every object construction.
-
- The act of causing this event to occur is referred to as "throwing
- an exception". (Alternate terms include "raising an exception" or
- "signaling an exception".) The term "throw" is used because control
- is returned to the callers of the function that is signaling the
- exception, and thus there is the concept of "throwing" the
- exception up the call stack.
-
- [ Add updated documentation on how to use this. ] */
+/* An exception is an event that can be "thrown" from within a
+ function. This event can then be "caught" by the callers of
+ the function.
+
+ The representation of exceptions changes several times during
+ the compilation process:
+
+ In the beginning, in the front end, we have the GENERIC trees
+ TRY_CATCH_EXPR, TRY_FINALLY_EXPR, WITH_CLEANUP_EXPR,
+ CLEANUP_POINT_EXPR, CATCH_EXPR, and EH_FILTER_EXPR.
+
+ During initial gimplification (gimplify.c) these are lowered
+ to the GIMPLE_TRY, GIMPLE_CATCH, and GIMPLE_EH_FILTER nodes.
+ The WITH_CLEANUP_EXPR and CLEANUP_POINT_EXPR nodes are converted
+ into GIMPLE_TRY_FINALLY nodes; the others are a more direct 1-1
+ conversion.
+
+ During pass_lower_eh (tree-eh.c) we record the nested structure
+ of the TRY nodes in EH_REGION nodes in CFUN->EH->REGION_TREE.
+ We expand the lang_protect_cleanup_actions hook into MUST_NOT_THROW
+ regions at this time. We can then flatten the statements within
+ the TRY nodes to straight-line code. Statements that had been within
+ TRY nodes that can throw are recorded within CFUN->EH->THROW_STMT_TABLE,
+ so that we may remember what action is supposed to be taken if
+ a given statement does throw. During this lowering process,
+ we create an EH_LANDING_PAD node for each EH_REGION that has
+ some code within the function that needs to be executed if a
+ throw does happen. We also create RESX statements that are
+ used to transfer control from an inner EH_REGION to an outer
+ EH_REGION. We also create EH_DISPATCH statements as placeholders
+ for a runtime type comparison that should be made in order to
+ select the action to perform among different CATCH and EH_FILTER
+ regions.
+
+ During pass_lower_eh_dispatch (tree-eh.c), which is run after
+ all inlining is complete, we are able to run assign_filter_values,
+ which allows us to map the set of types manipulated by all of the
+ CATCH and EH_FILTER regions to a set of integers. This set of integers
+ will be how the exception runtime communicates with the code generated
+ within the function. We then expand the GIMPLE_EH_DISPATCH statements
+ to a switch or conditional branches that use the argument provided by
+ the runtime (__builtin_eh_filter) and the set of integers we computed
+ in assign_filter_values.
+
+ During pass_lower_resx (tree-eh.c), which is run near the end
+ of optimization, we expand RESX statements. If the eh region
+ that is outer to the RESX statement is a MUST_NOT_THROW, then
+ the RESX expands to some form of abort statement. If the eh
+ region that is outer to the RESX statement is within the current
+ function, then the RESX expands to a bookkeeping call
+ (__builtin_eh_copy_values) and a goto. Otherwise, the next
+ handler for the exception must be within a function somewhere
+ up the call chain, so we call back into the exception runtime
+ (__builtin_unwind_resume).
+
+ During pass_expand (cfgexpand.c), we generate REG_EH_REGION notes
+ that create an rtl to eh_region mapping that corresponds to the
+ gimple to eh_region mapping that had been recorded in the
+ THROW_STMT_TABLE.
+
+ During pass_rtl_eh (except.c), we generate the real landing pads
+ to which the runtime will actually transfer control. These new
+ landing pads perform whatever bookkeeping is needed by the target
+ backend in order to resume execution within the current function.
+ Each of these new landing pads falls through into the post_landing_pad
+ label which had been used within the CFG up to this point. All
+ exception edges within the CFG are redirected to the new landing pads.
+ If the target uses setjmp to implement exceptions, the various extra
+ calls into the runtime to register and unregister the current stack
+ frame are emitted at this time.
+
+ During pass_convert_to_eh_region_ranges (except.c), we transform
+ the REG_EH_REGION notes attached to individual insns into
+ non-overlapping ranges of insns bounded by NOTE_INSN_EH_REGION_BEG
+ and NOTE_INSN_EH_REGION_END. Each insn within such ranges has the
+ same associated action within the exception region tree, meaning
+ that (1) the exception is caught by the same landing pad within the
+ current function, (2) the exception is blocked by the runtime with
+ a MUST_NOT_THROW region, or (3) the exception is not handled at all
+ within the current function.
+
+ Finally, during assembly generation, we call
+ output_function_exception_table (except.c) to emit the tables with
+ which the exception runtime can determine if a given stack frame
+ handles a given exception, and if so what filter value to provide
+ to the function when the non-local control transfer is effected.
+ If the target uses dwarf2 unwinding to implement exceptions, then
+ output_call_frame_info (dwarf2out.c) emits the required unwind data. */
#include "config.h"
@@ -87,21 +151,11 @@ along with GCC; see the file COPYING3. If not see
/* Protect cleanup actions with must-not-throw regions, with a call
to the given failure handler. */
-gimple (*lang_protect_cleanup_actions) (void);
+tree (*lang_protect_cleanup_actions) (void);
/* Return true if type A catches type B. */
int (*lang_eh_type_covers) (tree a, tree b);
-/* Map a type to a runtime object to match type. */
-tree (*lang_eh_runtime_type) (tree);
-
-/* A hash table of label to region number. */
-
-struct GTY(()) ehl_map_entry {
- rtx label;
- struct eh_region_d *region;
-};
-
static GTY(()) int call_site_base;
static GTY ((param_is (union tree_node)))
htab_t type_to_runtime_map;
@@ -121,6 +175,9 @@ struct GTY(()) call_site_record_d
int action;
};
+static bool get_eh_region_and_lp_from_rtx (const_rtx, eh_region *,
+ eh_landing_pad *);
+
static int t2r_eq (const void *, const void *);
static hashval_t t2r_hash (const void *);
@@ -130,49 +187,16 @@ static int ehspec_filter_eq (const void *, const void *);
static hashval_t ehspec_filter_hash (const void *);
static int add_ttypes_entry (htab_t, tree);
static int add_ehspec_entry (htab_t, htab_t, tree);
-static void assign_filter_values (void);
-static void build_post_landing_pads (void);
-static void connect_post_landing_pads (void);
static void dw2_build_landing_pads (void);
-struct sjlj_lp_info;
-static bool sjlj_find_directly_reachable_regions (struct sjlj_lp_info *);
-static void sjlj_assign_call_site_values (rtx, struct sjlj_lp_info *);
-static void sjlj_mark_call_sites (struct sjlj_lp_info *);
-static void sjlj_emit_function_enter (rtx);
-static void sjlj_emit_function_exit (void);
-static void sjlj_emit_dispatch_table (rtx, struct sjlj_lp_info *);
-static void sjlj_build_landing_pads (void);
-
-static void remove_eh_handler (struct eh_region_d *);
-static void remove_eh_handler_and_replace (struct eh_region_d *,
- struct eh_region_d *, bool);
-
-/* The return value of reachable_next_level. */
-enum reachable_code
-{
- /* The given exception is not processed by the given region. */
- RNL_NOT_CAUGHT,
- /* The given exception may need processing by the given region. */
- RNL_MAYBE_CAUGHT,
- /* The given exception is completely processed by the given region. */
- RNL_CAUGHT,
- /* The given exception is completely processed by the runtime. */
- RNL_BLOCKED
-};
-
-struct reachable_info;
-static enum reachable_code reachable_next_level (struct eh_region_d *, tree,
- struct reachable_info *, bool);
-
static int action_record_eq (const void *, const void *);
static hashval_t action_record_hash (const void *);
static int add_action_record (htab_t, int, int);
-static int collect_one_action_chain (htab_t, struct eh_region_d *);
+static int collect_one_action_chain (htab_t, eh_region);
static int add_call_site (rtx, int, int);
-static void push_uleb128 (varray_type *, unsigned int);
-static void push_sleb128 (varray_type *, int);
+static void push_uleb128 (VEC (uchar, gc) **, unsigned int);
+static void push_sleb128 (VEC (uchar, gc) **, int);
#ifndef HAVE_AS_LEB128
static int dw2_size_of_call_site_table (int);
static int sjlj_size_of_call_site_table (void);
@@ -308,16 +332,20 @@ void
init_eh_for_function (void)
{
cfun->eh = GGC_CNEW (struct eh_status);
+
+ /* Make sure zero'th entries are used. */
+ VEC_safe_push (eh_region, gc, cfun->eh->region_array, NULL);
+ VEC_safe_push (eh_landing_pad, gc, cfun->eh->lp_array, NULL);
}
/* Routines to generate the exception tree somewhat directly.
These are used from tree-eh.c when processing exception related
nodes during tree optimization. */
-static struct eh_region_d *
-gen_eh_region (enum eh_region_type type, struct eh_region_d *outer)
+static eh_region
+gen_eh_region (enum eh_region_type type, eh_region outer)
{
- struct eh_region_d *new_eh;
+ eh_region new_eh;
#ifdef ENABLE_CHECKING
gcc_assert (doing_eh (0));
@@ -338,30 +366,32 @@ gen_eh_region (enum eh_region_type type, struct eh_region_d *outer)
cfun->eh->region_tree = new_eh;
}
- new_eh->region_number = ++cfun->eh->last_region_number;
+ new_eh->index = VEC_length (eh_region, cfun->eh->region_array);
+ VEC_safe_push (eh_region, gc, cfun->eh->region_array, new_eh);
return new_eh;
}
-struct eh_region_d *
-gen_eh_region_cleanup (struct eh_region_d *outer)
+eh_region
+gen_eh_region_cleanup (eh_region outer)
{
- struct eh_region_d *cleanup = gen_eh_region (ERT_CLEANUP, outer);
- return cleanup;
+ return gen_eh_region (ERT_CLEANUP, outer);
}
-struct eh_region_d *
-gen_eh_region_try (struct eh_region_d *outer)
+eh_region
+gen_eh_region_try (eh_region outer)
{
return gen_eh_region (ERT_TRY, outer);
}
-struct eh_region_d *
-gen_eh_region_catch (struct eh_region_d *t, tree type_or_list)
+eh_catch
+gen_eh_region_catch (eh_region t, tree type_or_list)
{
- struct eh_region_d *c, *l;
+ eh_catch c, l;
tree type_list, type_node;
+ gcc_assert (t->type == ERT_TRY);
+
/* Ensure to always end up with a type list to normalize further
processing, then register each type against the runtime types map. */
type_list = type_or_list;
@@ -375,23 +405,23 @@ gen_eh_region_catch (struct eh_region_d *t, tree type_or_list)
add_type_for_runtime (TREE_VALUE (type_node));
}
- c = gen_eh_region (ERT_CATCH, t->outer);
- c->u.eh_catch.type_list = type_list;
+ c = GGC_CNEW (struct eh_catch_d);
+ c->type_list = type_list;
l = t->u.eh_try.last_catch;
- c->u.eh_catch.prev_catch = l;
+ c->prev_catch = l;
if (l)
- l->u.eh_catch.next_catch = c;
+ l->next_catch = c;
else
- t->u.eh_try.eh_catch = c;
+ t->u.eh_try.first_catch = c;
t->u.eh_try.last_catch = c;
return c;
}
-struct eh_region_d *
-gen_eh_region_allowed (struct eh_region_d *outer, tree allowed)
+eh_region
+gen_eh_region_allowed (eh_region outer, tree allowed)
{
- struct eh_region_d *region = gen_eh_region (ERT_ALLOWED_EXCEPTIONS, outer);
+ eh_region region = gen_eh_region (ERT_ALLOWED_EXCEPTIONS, outer);
region->u.allowed.type_list = allowed;
for (; allowed ; allowed = TREE_CHAIN (allowed))
@@ -400,1271 +430,226 @@ gen_eh_region_allowed (struct eh_region_d *outer, tree allowed)
return region;
}
-struct eh_region_d *
-gen_eh_region_must_not_throw (struct eh_region_d *outer)
+eh_region
+gen_eh_region_must_not_throw (eh_region outer)
{
return gen_eh_region (ERT_MUST_NOT_THROW, outer);
}
-int
-get_eh_region_number (struct eh_region_d *region)
+eh_landing_pad
+gen_eh_landing_pad (eh_region region)
{
- return region->region_number;
-}
+ eh_landing_pad lp = GGC_CNEW (struct eh_landing_pad_d);
-bool
-get_eh_region_may_contain_throw (struct eh_region_d *region)
-{
- return region->may_contain_throw;
-}
+ lp->next_lp = region->landing_pads;
+ lp->region = region;
+ lp->index = VEC_length (eh_landing_pad, cfun->eh->lp_array);
+ region->landing_pads = lp;
-tree
-get_eh_region_tree_label (struct eh_region_d *region)
-{
- return region->tree_label;
-}
+ VEC_safe_push (eh_landing_pad, gc, cfun->eh->lp_array, lp);
-tree
-get_eh_region_no_tree_label (int region)
-{
- return VEC_index (eh_region, cfun->eh->region_array, region)->tree_label;
+ return lp;
}
-void
-set_eh_region_tree_label (struct eh_region_d *region, tree lab)
+eh_region
+get_eh_region_from_number_fn (struct function *ifun, int i)
{
- region->tree_label = lab;
+ return VEC_index (eh_region, ifun->eh->region_array, i);
}
-
-void
-expand_resx_stmt (gimple stmt)
-{
- int region_nr = gimple_resx_region (stmt);
- rtx insn;
- struct eh_region_d *reg = VEC_index (eh_region,
- cfun->eh->region_array, region_nr);
- do_pending_stack_adjust ();
- insn = emit_jump_insn (gen_rtx_RESX (VOIDmode, region_nr));
- if (reg->resume)
- reg->resume = gen_rtx_INSN_LIST (VOIDmode, insn, reg->resume);
- else
- reg->resume = insn;
- emit_barrier ();
-}
-
-/* Note that the current EH region (if any) may contain a throw, or a
- call to a function which itself may contain a throw. */
-
-void
-note_eh_region_may_contain_throw (struct eh_region_d *region)
+eh_region
+get_eh_region_from_number (int i)
{
- while (region && !region->may_contain_throw)
- {
- region->may_contain_throw = 1;
- region = region->outer;
- }
+ return get_eh_region_from_number_fn (cfun, i);
}
-
-/* Return an rtl expression for a pointer to the exception object
- within a handler. */
-
-rtx
-get_exception_pointer (void)
+eh_landing_pad
+get_eh_landing_pad_from_number_fn (struct function *ifun, int i)
{
- if (! crtl->eh.exc_ptr)
- crtl->eh.exc_ptr = gen_reg_rtx (ptr_mode);
- return crtl->eh.exc_ptr;
+ return VEC_index (eh_landing_pad, ifun->eh->lp_array, i);
}
-/* Return an rtl expression for the exception dispatch filter
- within a handler. */
-
-rtx
-get_exception_filter (void)
+eh_landing_pad
+get_eh_landing_pad_from_number (int i)
{
- if (! crtl->eh.filter)
- crtl->eh.filter = gen_reg_rtx (targetm.eh_return_filter_mode ());
- return crtl->eh.filter;
+ return get_eh_landing_pad_from_number_fn (cfun, i);
}
-
-/* This section is for the exception handling specific optimization pass. */
-/* Random access the exception region tree. */
-
-void
-collect_eh_region_array (void)
+eh_region
+get_eh_region_from_lp_number_fn (struct function *ifun, int i)
{
- struct eh_region_d *i;
-
- i = cfun->eh->region_tree;
- if (! i)
- return;
-
- VEC_safe_grow (eh_region, gc, cfun->eh->region_array,
- cfun->eh->last_region_number + 1);
- VEC_replace (eh_region, cfun->eh->region_array, 0, 0);
-
- while (1)
+ if (i < 0)
+ return VEC_index (eh_region, ifun->eh->region_array, -i);
+ else if (i == 0)
+ return NULL;
+ else
{
- VEC_replace (eh_region, cfun->eh->region_array, i->region_number, i);
-
- /* If there are sub-regions, process them. */
- if (i->inner)
- i = i->inner;
- /* If there are peers, process them. */
- else if (i->next_peer)
- i = i->next_peer;
- /* Otherwise, step back up the tree to the next peer. */
- else
- {
- do {
- i = i->outer;
- if (i == NULL)
- return;
- } while (i->next_peer == NULL);
- i = i->next_peer;
- }
+ eh_landing_pad lp;
+ lp = VEC_index (eh_landing_pad, ifun->eh->lp_array, i);
+ return lp->region;
}
}
-/* R is MUST_NOT_THROW region that is not reachable via local
- RESX instructions. It still must be kept in the tree in case runtime
- can unwind through it, or we will eliminate out terminate call
- runtime would do otherwise. Return TRUE if R contains throwing statements
- or some of the exceptions in inner regions can be unwound up to R.
-
- CONTAINS_STMT is bitmap of all regions that contains some throwing
- statements.
-
- Function looks O(^3) at first sight. In fact the function is called at most
- once for every MUST_NOT_THROW in EH tree from remove_unreachable_regions
- Because the outer loop walking subregions does not dive in MUST_NOT_THROW,
- the outer loop examines every region at most once. The inner loop
- is doing unwinding from the throwing statement same way as we do during
- CFG construction, so it is O(^2) in size of EH tree, but O(n) in size
- of CFG. In practice Eh trees are wide, not deep, so this is not
- a problem. */
-
-static bool
-can_be_reached_by_runtime (sbitmap contains_stmt, struct eh_region_d *r)
+eh_region
+get_eh_region_from_lp_number (int i)
{
- struct eh_region_d *i = r->inner;
- unsigned n;
- bitmap_iterator bi;
-
- if (TEST_BIT (contains_stmt, r->region_number))
- return true;
- if (r->aka)
- EXECUTE_IF_SET_IN_BITMAP (r->aka, 0, n, bi)
- if (TEST_BIT (contains_stmt, n))
- return true;
- if (!i)
- return false;
- while (1)
- {
- /* It is pointless to look into MUST_NOT_THROW
- or dive into subregions. They never unwind up. */
- if (i->type != ERT_MUST_NOT_THROW)
- {
- bool found = TEST_BIT (contains_stmt, i->region_number);
- if (!found && i->aka)
- EXECUTE_IF_SET_IN_BITMAP (i->aka, 0, n, bi)
- if (TEST_BIT (contains_stmt, n))
- {
- found = true;
- break;
- }
- /* We have nested region that contains throwing statement.
- See if resuming might lead up to the resx or we get locally
- caught sooner. If we get locally caught sooner, we either
- know region R is not reachable or it would have direct edge
- from the EH resx and thus consider region reachable at
- firest place. */
- if (found)
- {
- struct eh_region_d *i1 = i;
- tree type_thrown = NULL_TREE;
-
- if (i1->type == ERT_THROW)
- {
- type_thrown = i1->u.eh_throw.type;
- i1 = i1->outer;
- }
- for (; i1 != r; i1 = i1->outer)
- if (reachable_next_level (i1, type_thrown, NULL,
- false) >= RNL_CAUGHT)
- break;
- if (i1 == r)
- return true;
- }
- }
- /* If there are sub-regions, process them. */
- if (i->type != ERT_MUST_NOT_THROW && i->inner)
- i = i->inner;
- /* If there are peers, process them. */
- else if (i->next_peer)
- i = i->next_peer;
- /* Otherwise, step back up the tree to the next peer. */
- else
- {
- do
- {
- i = i->outer;
- if (i == r)
- return false;
- }
- while (i->next_peer == NULL);
- i = i->next_peer;
- }
- }
+ return get_eh_region_from_lp_number_fn (cfun, i);
}
+
+/* Returns true if the current function has exception handling regions. */
-/* Bring region R to the root of tree. */
-
-static void
-bring_to_root (struct eh_region_d *r)
+bool
+current_function_has_exception_handlers (void)
{
- struct eh_region_d **pp;
- struct eh_region_d *outer = r->outer;
- if (!r->outer)
- return;
- for (pp = &outer->inner; *pp != r; pp = &(*pp)->next_peer)
- continue;
- *pp = r->next_peer;
- r->outer = NULL;
- r->next_peer = cfun->eh->region_tree;
- cfun->eh->region_tree = r;
+ return cfun->eh->region_tree != NULL;
}
+
+/* A subroutine of duplicate_eh_regions. Copy the eh_region tree at OLD.
+ Root it at OUTER, and apply LP_OFFSET to the lp numbers. */
-/* Return true if region R2 can be replaced by R1. */
-
-static bool
-eh_region_replaceable_by_p (const struct eh_region_d *r1,
- const struct eh_region_d *r2)
+struct duplicate_eh_regions_data
{
- /* Regions are semantically same if they are of same type,
- have same label and type. */
- if (r1->type != r2->type)
- return false;
- if (r1->tree_label != r2->tree_label)
- return false;
-
- /* Verify that also region type dependent data are the same. */
- switch (r1->type)
- {
- case ERT_MUST_NOT_THROW:
- case ERT_CLEANUP:
- break;
- case ERT_TRY:
- {
- struct eh_region_d *c1, *c2;
- for (c1 = r1->u.eh_try.eh_catch,
- c2 = r2->u.eh_try.eh_catch;
- c1 && c2;
- c1 = c1->u.eh_catch.next_catch,
- c2 = c2->u.eh_catch.next_catch)
- if (!eh_region_replaceable_by_p (c1, c2))
- return false;
- if (c1 || c2)
- return false;
- }
- break;
- case ERT_CATCH:
- if (!list_equal_p (r1->u.eh_catch.type_list, r2->u.eh_catch.type_list))
- return false;
- if (!list_equal_p (r1->u.eh_catch.filter_list,
- r2->u.eh_catch.filter_list))
- return false;
- break;
- case ERT_ALLOWED_EXCEPTIONS:
- if (!list_equal_p (r1->u.allowed.type_list, r2->u.allowed.type_list))
- return false;
- if (r1->u.allowed.filter != r2->u.allowed.filter)
- return false;
- break;
- case ERT_THROW:
- if (r1->u.eh_throw.type != r2->u.eh_throw.type)
- return false;
- break;
- default:
- gcc_unreachable ();
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Regions %i and %i match\n", r1->region_number,
- r2->region_number);
- return true;
-}
-
-/* Replace region R2 by R1. */
+ duplicate_eh_regions_map label_map;
+ void *label_map_data;
+ struct pointer_map_t *eh_map;
+};
static void
-replace_region (struct eh_region_d *r1, struct eh_region_d *r2)
-{
- struct eh_region_d *next1 = r1->u.eh_try.eh_catch;
- struct eh_region_d *next2 = r2->u.eh_try.eh_catch;
- bool is_try = r1->type == ERT_TRY;
-
- gcc_assert (r1->type != ERT_CATCH);
- remove_eh_handler_and_replace (r2, r1, false);
- if (is_try)
- {
- while (next1)
- {
- r1 = next1;
- r2 = next2;
- gcc_assert (next1->type == ERT_CATCH);
- gcc_assert (next2->type == ERT_CATCH);
- next1 = next1->u.eh_catch.next_catch;
- next2 = next2->u.eh_catch.next_catch;
- remove_eh_handler_and_replace (r2, r1, false);
- }
- }
-}
-
-/* Return hash value of type list T. */
-
-static hashval_t
-hash_type_list (tree t)
+duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
+ eh_region old_r, eh_region outer)
{
- hashval_t val = 0;
- for (; t; t = TREE_CHAIN (t))
- val = iterative_hash_hashval_t (TREE_HASH (TREE_VALUE (t)), val);
- return val;
-}
-
-/* Hash EH regions so semantically same regions get same hash value. */
+ eh_landing_pad old_lp, new_lp;
+ eh_region new_r;
+ void **slot;
-static hashval_t
-hash_eh_region (const void *r)
-{
- const struct eh_region_d *region = (const struct eh_region_d *) r;
- hashval_t val = region->type;
+ new_r = gen_eh_region (old_r->type, outer);
+ slot = pointer_map_insert (data->eh_map, (void *)old_r);
+ gcc_assert (*slot == NULL);
+ *slot = (void *)new_r;
- if (region->tree_label)
- val = iterative_hash_hashval_t (LABEL_DECL_UID (region->tree_label), val);
- switch (region->type)
+ switch (old_r->type)
{
- case ERT_MUST_NOT_THROW:
- case ERT_CLEANUP:
- break;
- case ERT_TRY:
- {
- struct eh_region_d *c;
- for (c = region->u.eh_try.eh_catch;
- c; c = c->u.eh_catch.next_catch)
- val = iterative_hash_hashval_t (hash_eh_region (c), val);
- }
- break;
- case ERT_CATCH:
- val = iterative_hash_hashval_t (hash_type_list
- (region->u.eh_catch.type_list), val);
- break;
- case ERT_ALLOWED_EXCEPTIONS:
- val = iterative_hash_hashval_t
- (hash_type_list (region->u.allowed.type_list), val);
- val = iterative_hash_hashval_t (region->u.allowed.filter, val);
- break;
- case ERT_THROW:
- val |= iterative_hash_hashval_t (TYPE_UID (region->u.eh_throw.type), val);
- break;
- default:
- gcc_unreachable ();
- }
- return val;
-}
-
-/* Return true if regions R1 and R2 are equal. */
-
-static int
-eh_regions_equal_p (const void *r1, const void *r2)
-{
- return eh_region_replaceable_by_p ((const struct eh_region_d *) r1,
- (const struct eh_region_d *) r2);
-}
-
-/* Walk all peers of REGION and try to merge those regions
- that are semantically equivalent. Look into subregions
- recursively too. */
-
-static bool
-merge_peers (struct eh_region_d *region)
-{
- struct eh_region_d *r1, *r2, *outer = NULL, *next;
- bool merged = false;
- int num_regions = 0;
- if (region)
- outer = region->outer;
- else
- return false;
+ case ERT_CLEANUP:
+ break;
- /* First see if there is inner region equivalent to region
- in question. EH control flow is acyclic so we know we
- can merge them. */
- if (outer)
- for (r1 = region; r1; r1 = next)
+ case ERT_TRY:
{
- next = r1->next_peer;
- if (r1->type == ERT_CATCH)
- continue;
- if (eh_region_replaceable_by_p (r1->outer, r1))
+ eh_catch oc, nc;
+ for (oc = old_r->u.eh_try.first_catch; oc ; oc = oc->next_catch)
{
- replace_region (r1->outer, r1);
- merged = true;
+ /* We should be doing all our region duplication before and
+ during inlining, which is before filter lists are created. */
+ gcc_assert (oc->filter_list == NULL);
+ nc = gen_eh_region_catch (new_r, oc->type_list);
+ nc->label = data->label_map (oc->label, data->label_map_data);
}
- else
- num_regions ++;
}
+ break;
- /* Get new first region and try to match the peers
- for equivalence. */
- if (outer)
- region = outer->inner;
- else
- region = cfun->eh->region_tree;
-
- /* There are few regions to inspect:
- N^2 loop matching each region with each region
- will do the job well. */
- if (num_regions < 10)
- {
- for (r1 = region; r1; r1 = r1->next_peer)
- {
- if (r1->type == ERT_CATCH)
- continue;
- for (r2 = r1->next_peer; r2; r2 = next)
- {
- next = r2->next_peer;
- if (eh_region_replaceable_by_p (r1, r2))
- {
- replace_region (r1, r2);
- merged = true;
- }
- }
- }
- }
- /* Or use hashtable to avoid N^2 behaviour. */
- else
- {
- htab_t hash;
- hash = htab_create (num_regions, hash_eh_region,
- eh_regions_equal_p, NULL);
- for (r1 = region; r1; r1 = next)
- {
- void **slot;
-
- next = r1->next_peer;
- if (r1->type == ERT_CATCH)
- continue;
- slot = htab_find_slot (hash, r1, INSERT);
- if (!*slot)
- *slot = r1;
- else
- replace_region ((struct eh_region_d *) *slot, r1);
- }
- htab_delete (hash);
- }
- for (r1 = region; r1; r1 = r1->next_peer)
- merged |= merge_peers (r1->inner);
- return merged;
-}
-
-/* Remove all regions whose labels are not reachable.
- REACHABLE is bitmap of all regions that are used by the function
- CONTAINS_STMT is bitmap of all regions that contains stmt (or NULL). */
-
-void
-remove_unreachable_regions (sbitmap reachable, sbitmap contains_stmt)
-{
- int i;
- struct eh_region_d *r;
- VEC(eh_region,heap) *must_not_throws = VEC_alloc (eh_region, heap, 16);
- struct eh_region_d *local_must_not_throw = NULL;
- struct eh_region_d *first_must_not_throw = NULL;
-
- for (i = cfun->eh->last_region_number; i > 0; --i)
- {
- r = VEC_index (eh_region, cfun->eh->region_array, i);
- if (!r || r->region_number != i)
- continue;
- if (!TEST_BIT (reachable, i) && !r->resume)
- {
- bool kill_it = true;
-
- r->tree_label = NULL;
- switch (r->type)
- {
- case ERT_THROW:
- /* Don't remove ERT_THROW regions if their outer region
- is reachable. */
- if (r->outer && TEST_BIT (reachable, r->outer->region_number))
- kill_it = false;
- break;
- case ERT_MUST_NOT_THROW:
- /* MUST_NOT_THROW regions are implementable solely in the
- runtime, but we need them when inlining function.
-
- Keep them if outer region is not MUST_NOT_THROW a well
- and if they contain some statement that might unwind through
- them. */
- if ((!r->outer || r->outer->type != ERT_MUST_NOT_THROW)
- && (!contains_stmt
- || can_be_reached_by_runtime (contains_stmt, r)))
- kill_it = false;
- break;
- case ERT_TRY:
- {
- /* TRY regions are reachable if any of its CATCH regions
- are reachable. */
- struct eh_region_d *c;
- for (c = r->u.eh_try.eh_catch; c;
- c = c->u.eh_catch.next_catch)
- if (TEST_BIT (reachable, c->region_number))
- {
- kill_it = false;
- break;
- }
- break;
- }
-
- default:
- break;
- }
-
- if (kill_it)
- {
- if (dump_file)
- fprintf (dump_file, "Removing unreachable eh region %i\n",
- r->region_number);
- remove_eh_handler (r);
- }
- else if (r->type == ERT_MUST_NOT_THROW)
- {
- if (!first_must_not_throw)
- first_must_not_throw = r;
- VEC_safe_push (eh_region, heap, must_not_throws, r);
- }
- }
- else
- if (r->type == ERT_MUST_NOT_THROW)
- {
- if (!local_must_not_throw)
- local_must_not_throw = r;
- if (r->outer)
- VEC_safe_push (eh_region, heap, must_not_throws, r);
- }
- }
-
- /* MUST_NOT_THROW regions without local handler are all the same; they
- trigger terminate call in runtime.
- MUST_NOT_THROW handled locally can differ in debug info associated
- to std::terminate () call or if one is coming from Java and other
- from C++ whether they call terminate or abort.
-
- We merge all MUST_NOT_THROW regions handled by the run-time into one.
- We alsobring all local MUST_NOT_THROW regions to the roots of EH tree
- (since unwinding never continues to the outer region anyway).
- If MUST_NOT_THROW with local handler is present in the tree, we use
- that region to merge into, since it will remain in tree anyway;
- otherwise we use first MUST_NOT_THROW.
-
- Merging of locally handled regions needs changes to the CFG. Crossjumping
- should take care of this, by looking at the actual code and
- ensuring that the cleanup actions are really the same. */
-
- if (local_must_not_throw)
- first_must_not_throw = local_must_not_throw;
-
- for (i = 0; VEC_iterate (eh_region, must_not_throws, i, r); i++)
- {
- if (!r->label && !r->tree_label && r != first_must_not_throw)
- {
- if (dump_file)
- fprintf (dump_file, "Replacing MUST_NOT_THROW region %i by %i\n",
- r->region_number,
- first_must_not_throw->region_number);
- remove_eh_handler_and_replace (r, first_must_not_throw, false);
- first_must_not_throw->may_contain_throw |= r->may_contain_throw;
- }
- else
- bring_to_root (r);
- }
- merge_peers (cfun->eh->region_tree);
-#ifdef ENABLE_CHECKING
- verify_eh_tree (cfun);
-#endif
- VEC_free (eh_region, heap, must_not_throws);
-}
-
-/* Return array mapping LABEL_DECL_UID to region such that region's tree_label
- is identical to label. */
-
-VEC (int, heap) *
-label_to_region_map (void)
-{
- VEC (int, heap) * label_to_region = NULL;
- int i;
- int idx;
-
- VEC_safe_grow_cleared (int, heap, label_to_region,
- cfun->cfg->last_label_uid + 1);
- for (i = cfun->eh->last_region_number; i > 0; --i)
- {
- struct eh_region_d *r = VEC_index (eh_region, cfun->eh->region_array, i);
- if (r && r->region_number == i
- && r->tree_label && LABEL_DECL_UID (r->tree_label) >= 0)
- {
- if ((idx = VEC_index (int, label_to_region,
- LABEL_DECL_UID (r->tree_label))) != 0)
- r->next_region_sharing_label =
- VEC_index (eh_region, cfun->eh->region_array, idx);
- else
- r->next_region_sharing_label = NULL;
- VEC_replace (int, label_to_region, LABEL_DECL_UID (r->tree_label),
- i);
- }
- }
- return label_to_region;
-}
-
-/* Return number of EH regions. */
-int
-num_eh_regions (void)
-{
- return cfun->eh->last_region_number + 1;
-}
-
-/* Return next region sharing same label as REGION. */
-
-int
-get_next_region_sharing_label (int region)
-{
- struct eh_region_d *r;
- if (!region)
- return 0;
- r = VEC_index (eh_region, cfun->eh->region_array, region);
- if (!r || !r->next_region_sharing_label)
- return 0;
- return r->next_region_sharing_label->region_number;
-}
-
-/* Return bitmap of all labels that are handlers of must not throw regions. */
-
-bitmap
-must_not_throw_labels (void)
-{
- struct eh_region_d *i;
- bitmap labels = BITMAP_ALLOC (NULL);
-
- i = cfun->eh->region_tree;
- if (! i)
- return labels;
-
- while (1)
- {
- if (i->type == ERT_MUST_NOT_THROW && i->tree_label
- && LABEL_DECL_UID (i->tree_label) >= 0)
- bitmap_set_bit (labels, LABEL_DECL_UID (i->tree_label));
-
- /* If there are sub-regions, process them. */
- if (i->inner)
- i = i->inner;
- /* If there are peers, process them. */
- else if (i->next_peer)
- i = i->next_peer;
- /* Otherwise, step back up the tree to the next peer. */
- else
- {
- do {
- i = i->outer;
- if (i == NULL)
- return labels;
- } while (i->next_peer == NULL);
- i = i->next_peer;
- }
- }
-}
-
-/* Set up EH labels for RTL. */
-
-void
-convert_from_eh_region_ranges (void)
-{
- int i, n = cfun->eh->last_region_number;
-
- /* Most of the work is already done at the tree level. All we need to
- do is collect the rtl labels that correspond to the tree labels that
- collect the rtl labels that correspond to the tree labels
- we allocated earlier. */
- for (i = 1; i <= n; ++i)
- {
- struct eh_region_d *region;
+ case ERT_ALLOWED_EXCEPTIONS:
+ new_r->u.allowed.type_list = old_r->u.allowed.type_list;
+ new_r->u.allowed.label
+ = data->label_map (old_r->u.allowed.label, data->label_map_data);
+ break;
- region = VEC_index (eh_region, cfun->eh->region_array, i);
- if (region && region->tree_label)
- region->label = DECL_RTL_IF_SET (region->tree_label);
+ case ERT_MUST_NOT_THROW:
+ new_r->u.must_not_throw = old_r->u.must_not_throw;
+ break;
}
-}
-void
-find_exception_handler_labels (void)
-{
- int i;
-
- if (cfun->eh->region_tree == NULL)
- return;
-
- for (i = cfun->eh->last_region_number; i > 0; --i)
+ for (old_lp = old_r->landing_pads; old_lp ; old_lp = old_lp->next_lp)
{
- struct eh_region_d *region;
- rtx lab;
-
- region = VEC_index (eh_region, cfun->eh->region_array, i);
- if (! region || region->region_number != i)
+ /* Don't bother copying unused landing pads. */
+ if (old_lp->post_landing_pad == NULL)
continue;
- if (crtl->eh.built_landing_pads)
- lab = region->landing_pad;
- else
- lab = region->label;
- }
-}
-
-/* Returns true if the current function has exception handling regions. */
-
-bool
-current_function_has_exception_handlers (void)
-{
- int i;
-
- for (i = cfun->eh->last_region_number; i > 0; --i)
- {
- struct eh_region_d *region;
-
- region = VEC_index (eh_region, cfun->eh->region_array, i);
- if (region
- && region->region_number == i
- && region->type != ERT_THROW)
- return true;
- }
-
- return false;
-}
-
-/* A subroutine of duplicate_eh_regions. Search the region tree under O
- for the minimum and maximum region numbers. Update *MIN and *MAX. */
-
-static void
-duplicate_eh_regions_0 (eh_region o, int *min, int *max)
-{
- int i;
-
- if (o->aka)
- {
- i = bitmap_first_set_bit (o->aka);
- if (i < *min)
- *min = i;
- i = bitmap_last_set_bit (o->aka);
- if (i > *max)
- *max = i;
- }
- if (o->region_number < *min)
- *min = o->region_number;
- if (o->region_number > *max)
- *max = o->region_number;
-
- if (o->inner)
- {
- o = o->inner;
- duplicate_eh_regions_0 (o, min, max);
- while (o->next_peer)
- {
- o = o->next_peer;
- duplicate_eh_regions_0 (o, min, max);
- }
- }
-}
-
-/* A subroutine of duplicate_eh_regions. Copy the region tree under OLD.
- Root it at OUTER, and apply EH_OFFSET to the region number. Don't worry
- about the other internal pointers just yet, just the tree-like pointers. */
-
-static eh_region
-duplicate_eh_regions_1 (eh_region old, eh_region outer, int eh_offset)
-{
- eh_region ret, n;
-
- ret = n = GGC_NEW (struct eh_region_d);
-
- *n = *old;
- n->outer = outer;
- n->next_peer = NULL;
- if (old->aka)
- {
- unsigned i;
- bitmap_iterator bi;
- n->aka = BITMAP_GGC_ALLOC ();
-
- EXECUTE_IF_SET_IN_BITMAP (old->aka, 0, i, bi)
- {
- bitmap_set_bit (n->aka, i + eh_offset);
- VEC_replace (eh_region, cfun->eh->region_array, i + eh_offset, n);
- }
- }
- n->region_number += eh_offset;
- VEC_replace (eh_region, cfun->eh->region_array, n->region_number, n);
+ new_lp = gen_eh_landing_pad (new_r);
+ slot = pointer_map_insert (data->eh_map, (void *)old_lp);
+ gcc_assert (*slot == NULL);
+ *slot = (void *)new_lp;
- if (old->inner)
- {
- old = old->inner;
- n = n->inner = duplicate_eh_regions_1 (old, ret, eh_offset);
- while (old->next_peer)
- {
- old = old->next_peer;
- n = n->next_peer = duplicate_eh_regions_1 (old, ret, eh_offset);
- }
+ new_lp->post_landing_pad
+ = data->label_map (old_lp->post_landing_pad, data->label_map_data);
+ EH_LANDING_PAD_NR (new_lp->post_landing_pad) = new_lp->index;
}
- return ret;
+ for (old_r = old_r->inner; old_r ; old_r = old_r->next_peer)
+ duplicate_eh_regions_1 (data, old_r, new_r);
}
-/* Look for first outer region of R (or R itself) that is
- TRY region. Return NULL if none. */
+/* Duplicate the EH regions from IFUN rooted at COPY_REGION into
+ the current function and root the tree below OUTER_REGION.
+ The special case of COPY_REGION of NULL means all regions.
+ Remap labels using MAP/MAP_DATA callback. Return a pointer map
+ that allows the caller to remap uses of both EH regions and
+ EH landing pads. */
-static struct eh_region_d *
-find_prev_try (struct eh_region_d * r)
+struct pointer_map_t *
+duplicate_eh_regions (struct function *ifun,
+ eh_region copy_region, int outer_lp,
+ duplicate_eh_regions_map map, void *map_data)
{
- for (; r && r->type != ERT_TRY; r = r->outer)
- if (r->type == ERT_MUST_NOT_THROW
- || (r->type == ERT_ALLOWED_EXCEPTIONS
- && !r->u.allowed.type_list))
- {
- r = NULL;
- break;
- }
- return r;
-}
-
-/* Duplicate the EH regions of IFUN, rooted at COPY_REGION, into current
- function and root the tree below OUTER_REGION. Remap labels using MAP
- callback. The special case of COPY_REGION of 0 means all regions. */
+ struct duplicate_eh_regions_data data;
+ eh_region outer_region;
-int
-duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map,
- void *data, int copy_region, int outer_region)
-{
- eh_region cur, outer, *splice;
- int i, min_region, max_region, eh_offset, cfun_last_region_number;
- int num_regions;
-
- if (!ifun->eh)
- return 0;
#ifdef ENABLE_CHECKING
verify_eh_tree (ifun);
#endif
- /* Find the range of region numbers to be copied. The interface we
- provide here mandates a single offset to find new number from old,
- which means we must look at the numbers present, instead of the
- count or something else. */
- if (copy_region > 0)
- {
- min_region = INT_MAX;
- max_region = 0;
-
- cur = VEC_index (eh_region, ifun->eh->region_array, copy_region);
- duplicate_eh_regions_0 (cur, &min_region, &max_region);
- }
- else
- {
- min_region = 1;
- max_region = ifun->eh->last_region_number;
- }
- num_regions = max_region - min_region + 1;
- cfun_last_region_number = cfun->eh->last_region_number;
- eh_offset = cfun_last_region_number + 1 - min_region;
-
- /* If we've not yet created a region array, do so now. */
- cfun->eh->last_region_number = cfun_last_region_number + num_regions;
- VEC_safe_grow_cleared (eh_region, gc, cfun->eh->region_array,
- cfun->eh->last_region_number + 1);
-
- /* Locate the spot at which to insert the new tree. */
- if (outer_region > 0)
- {
- outer = VEC_index (eh_region, cfun->eh->region_array, outer_region);
- if (outer)
- splice = &outer->inner;
- else
- splice = &cfun->eh->region_tree;
- }
- else
- {
- outer = NULL;
- splice = &cfun->eh->region_tree;
- }
- while (*splice)
- splice = &(*splice)->next_peer;
-
- if (!ifun->eh->region_tree)
- {
- if (outer)
- for (i = cfun_last_region_number + 1;
- i <= cfun->eh->last_region_number; i++)
- {
- VEC_replace (eh_region, cfun->eh->region_array, i, outer);
- if (outer->aka == NULL)
- outer->aka = BITMAP_GGC_ALLOC ();
- bitmap_set_bit (outer->aka, i);
- }
- return eh_offset;
- }
+ data.label_map = map;
+ data.label_map_data = map_data;
+ data.eh_map = pointer_map_create ();
+ outer_region = get_eh_region_from_lp_number (outer_lp);
+
/* Copy all the regions in the subtree. */
- if (copy_region > 0)
- {
- cur = VEC_index (eh_region, ifun->eh->region_array, copy_region);
- *splice = duplicate_eh_regions_1 (cur, outer, eh_offset);
- }
+ if (copy_region)
+ duplicate_eh_regions_1 (&data, copy_region, outer_region);
else
{
- eh_region n;
-
- cur = ifun->eh->region_tree;
- *splice = n = duplicate_eh_regions_1 (cur, outer, eh_offset);
- while (cur->next_peer)
- {
- cur = cur->next_peer;
- n = n->next_peer = duplicate_eh_regions_1 (cur, outer, eh_offset);
- }
+ eh_region r;
+ for (r = ifun->eh->region_tree; r ; r = r->next_peer)
+ duplicate_eh_regions_1 (&data, r, outer_region);
}
- /* Remap all the labels in the new regions. */
- for (i = cfun_last_region_number + 1;
- VEC_iterate (eh_region, cfun->eh->region_array, i, cur); ++i)
- if (cur && cur->tree_label)
- cur->tree_label = map (cur->tree_label, data);
-
- /* Remap all of the internal catch and cleanup linkages. Since we
- duplicate entire subtrees, all of the referenced regions will have
- been copied too. And since we renumbered them as a block, a simple
- bit of arithmetic finds us the index for the replacement region. */
- for (i = cfun_last_region_number + 1;
- VEC_iterate (eh_region, cfun->eh->region_array, i, cur); ++i)
- {
- /* All removed EH that is toplevel in input function is now
- in outer EH of output function. */
- if (cur == NULL)
- {
- gcc_assert (VEC_index
- (eh_region, ifun->eh->region_array,
- i - eh_offset) == NULL);
- if (outer)
- {
- VEC_replace (eh_region, cfun->eh->region_array, i, outer);
- if (outer->aka == NULL)
- outer->aka = BITMAP_GGC_ALLOC ();
- bitmap_set_bit (outer->aka, i);
- }
- continue;
- }
- if (i != cur->region_number)
- continue;
-
-#define REMAP(REG) \
- (REG) = VEC_index (eh_region, cfun->eh->region_array, \
- (REG)->region_number + eh_offset)
-
- switch (cur->type)
- {
- case ERT_TRY:
- if (cur->u.eh_try.eh_catch)
- REMAP (cur->u.eh_try.eh_catch);
- if (cur->u.eh_try.last_catch)
- REMAP (cur->u.eh_try.last_catch);
- break;
-
- case ERT_CATCH:
- if (cur->u.eh_catch.next_catch)
- REMAP (cur->u.eh_catch.next_catch);
- if (cur->u.eh_catch.prev_catch)
- REMAP (cur->u.eh_catch.prev_catch);
- break;
-
- default:
- break;
- }
-
-#undef REMAP
- }
#ifdef ENABLE_CHECKING
verify_eh_tree (cfun);
#endif
- return eh_offset;
-}
-
-/* Return new copy of eh region OLD inside region NEW_OUTER.
- Do not care about updating the tree otherwise. */
-
-static struct eh_region_d *
-copy_eh_region_1 (struct eh_region_d *old, struct eh_region_d *new_outer)
-{
- struct eh_region_d *new_eh = gen_eh_region (old->type, new_outer);
- new_eh->u = old->u;
- new_eh->tree_label = old->tree_label;
- new_eh->may_contain_throw = old->may_contain_throw;
- VEC_safe_grow (eh_region, gc, cfun->eh->region_array,
- cfun->eh->last_region_number + 1);
- VEC_replace (eh_region, cfun->eh->region_array, new_eh->region_number, new_eh);
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Copying region %i to %i\n", old->region_number, new_eh->region_number);
- return new_eh;
-}
-
-/* Return new copy of eh region OLD inside region NEW_OUTER.
-
- Copy whole catch-try chain if neccesary. */
-
-static struct eh_region_d *
-copy_eh_region (struct eh_region_d *old, struct eh_region_d *new_outer)
-{
- struct eh_region_d *r, *n, *old_try, *new_try, *ret = NULL;
- VEC(eh_region,heap) *catch_list = NULL;
-
- if (old->type != ERT_CATCH)
- {
- gcc_assert (old->type != ERT_TRY);
- r = copy_eh_region_1 (old, new_outer);
- return r;
- }
-
- /* Locate and copy corresponding TRY. */
- for (old_try = old->next_peer; old_try->type == ERT_CATCH; old_try = old_try->next_peer)
- continue;
- gcc_assert (old_try->type == ERT_TRY);
- new_try = gen_eh_region_try (new_outer);
- new_try->tree_label = old_try->tree_label;
- new_try->may_contain_throw = old_try->may_contain_throw;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Copying try-catch regions. Try: %i to %i\n",
- old_try->region_number, new_try->region_number);
- VEC_safe_grow (eh_region, gc, cfun->eh->region_array,
- cfun->eh->last_region_number + 1);
- VEC_replace (eh_region, cfun->eh->region_array, new_try->region_number, new_try);
-
- /* In order to keep CATCH list in order, we need to copy in reverse order. */
- for (r = old_try->u.eh_try.last_catch; r->type == ERT_CATCH; r = r->next_peer)
- VEC_safe_push (eh_region, heap, catch_list, r);
-
- while (VEC_length (eh_region, catch_list))
- {
- r = VEC_pop (eh_region, catch_list);
-
- /* Duplicate CATCH. */
- n = gen_eh_region_catch (new_try, r->u.eh_catch.type_list);
- n->tree_label = r->tree_label;
- n->may_contain_throw = r->may_contain_throw;
- VEC_safe_grow (eh_region, gc, cfun->eh->region_array,
- cfun->eh->last_region_number + 1);
- VEC_replace (eh_region, cfun->eh->region_array, n->region_number, n);
- n->tree_label = r->tree_label;
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Copying try-catch regions. Catch: %i to %i\n",
- r->region_number, n->region_number);
- if (r == old)
- ret = n;
- }
- VEC_free (eh_region, heap, catch_list);
- gcc_assert (ret);
- return ret;
-}
-
-/* Callback for forach_reachable_handler that push REGION into single VECtor DATA. */
-
-static void
-push_reachable_handler (struct eh_region_d *region, void *data)
-{
- VEC(eh_region,heap) **trace = (VEC(eh_region,heap) **) data;
- VEC_safe_push (eh_region, heap, *trace, region);
-}
-
-/* Redirect EH edge E that to NEW_DEST_LABEL.
- IS_RESX, INLINABLE_CALL and REGION_NMUBER match the parameter of
- foreach_reachable_handler. */
-
-struct eh_region_d *
-redirect_eh_edge_to_label (edge e, tree new_dest_label, bool is_resx,
- bool inlinable_call, int region_number)
-{
- struct eh_region_d *outer;
- struct eh_region_d *region;
- VEC (eh_region, heap) * trace = NULL;
- int i;
- int start_here = -1;
- basic_block old_bb = e->dest;
- struct eh_region_d *old, *r = NULL;
- bool update_inplace = true;
- edge_iterator ei;
- edge e2;
-
- /* If there is only one EH edge, we don't need to duplicate;
- just update labels in the tree. */
- FOR_EACH_EDGE (e2, ei, old_bb->preds)
- if ((e2->flags & EDGE_EH) && e2 != e)
- {
- update_inplace = false;
- break;
- }
-
- region = VEC_index (eh_region, cfun->eh->region_array, region_number);
- gcc_assert (region);
-
- foreach_reachable_handler (region_number, is_resx, inlinable_call,
- push_reachable_handler, &trace);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- dump_eh_tree (dump_file, cfun);
- fprintf (dump_file, "Trace: ");
- for (i = 0; i < (int) VEC_length (eh_region, trace); i++)
- fprintf (dump_file, " %i", VEC_index (eh_region, trace, i)->region_number);
- fprintf (dump_file, " inplace: %i\n", update_inplace);
- }
-
- if (update_inplace)
- {
- /* In easy route just walk trace and update all occurences of the label. */
- for (i = 0; i < (int) VEC_length (eh_region, trace); i++)
- {
- r = VEC_index (eh_region, trace, i);
- if (r->tree_label && label_to_block (r->tree_label) == old_bb)
- {
- r->tree_label = new_dest_label;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Updating label for region %i\n",
- r->region_number);
- }
- }
- r = region;
- }
- else
- {
- /* Now look for outermost handler that reffers to the basic block in question.
- We start our duplication there. */
- for (i = 0; i < (int) VEC_length (eh_region, trace); i++)
- {
- r = VEC_index (eh_region, trace, i);
- if (r->tree_label && label_to_block (r->tree_label) == old_bb)
- start_here = i;
- }
- outer = VEC_index (eh_region, trace, start_here)->outer;
- gcc_assert (start_here >= 0);
-
- /* And now do the dirty job! */
- for (i = start_here; i >= 0; i--)
- {
- old = VEC_index (eh_region, trace, i);
- gcc_assert (!outer || old->outer != outer->outer);
-
- /* Copy region and update label. */
- r = copy_eh_region (old, outer);
- VEC_replace (eh_region, trace, i, r);
- if (r->tree_label && label_to_block (r->tree_label) == old_bb)
- {
- r->tree_label = new_dest_label;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Updating label for region %i\n",
- r->region_number);
- }
-
- /* We got into copying CATCH. copy_eh_region already did job
- of copying all catch blocks corresponding to the try. Now
- we need to update labels in all of them and see trace.
-
- We continue nesting into TRY region corresponding to CATCH:
- When duplicating EH tree contaiing subregions of CATCH,
- the CATCH region itself is never inserted to trace so we
- never get here anyway. */
- if (r->type == ERT_CATCH)
- {
- /* Walk other catch regions we copied and update labels as needed. */
- for (r = r->next_peer; r->type == ERT_CATCH; r = r->next_peer)
- if (r->tree_label && label_to_block (r->tree_label) == old_bb)
- {
- r->tree_label = new_dest_label;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Updating label for region %i\n",
- r->region_number);
- }
- gcc_assert (r->type == ERT_TRY);
-
- /* Skip sibling catch regions from the trace.
- They are already updated. */
- while (i > 0 && VEC_index (eh_region, trace, i - 1)->outer == old->outer)
- {
- gcc_assert (VEC_index (eh_region, trace, i - 1)->type == ERT_CATCH);
- i--;
- }
- }
-
- outer = r;
- }
-
- if (is_resx || region->type == ERT_THROW)
- r = copy_eh_region (region, outer);
- }
-
- VEC_free (eh_region, heap, trace);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- dump_eh_tree (dump_file, cfun);
- fprintf (dump_file, "New region: %i\n", r->region_number);
- }
- return r;
+ return data.eh_map;
}
-/* Return region number of region that is outer to both if REGION_A and
- REGION_B in IFUN. */
+/* Return the region that is outer to both REGION_A and REGION_B in IFUN. */
-int
-eh_region_outermost (struct function *ifun, int region_a, int region_b)
+eh_region
+eh_region_outermost (struct function *ifun, eh_region region_a,
+ eh_region region_b)
{
- struct eh_region_d *rp_a, *rp_b;
sbitmap b_outer;
- gcc_assert (ifun->eh->last_region_number > 0);
+ gcc_assert (ifun->eh->region_array);
gcc_assert (ifun->eh->region_tree);
- rp_a = VEC_index (eh_region, ifun->eh->region_array, region_a);
- rp_b = VEC_index (eh_region, ifun->eh->region_array, region_b);
- gcc_assert (rp_a != NULL);
- gcc_assert (rp_b != NULL);
-
- b_outer = sbitmap_alloc (ifun->eh->last_region_number + 1);
+ b_outer = sbitmap_alloc (VEC_length (eh_region, ifun->eh->region_array));
sbitmap_zero (b_outer);
do
{
- SET_BIT (b_outer, rp_b->region_number);
- rp_b = rp_b->outer;
+ SET_BIT (b_outer, region_b->index);
+ region_b = region_b->outer;
}
- while (rp_b);
+ while (region_b);
do
{
- if (TEST_BIT (b_outer, rp_a->region_number))
- {
- sbitmap_free (b_outer);
- return rp_a->region_number;
- }
- rp_a = rp_a->outer;
+ if (TEST_BIT (b_outer, region_a->index))
+ break;
+ region_a = region_a->outer;
}
- while (rp_a);
+ while (region_a);
sbitmap_free (b_outer);
- return -1;
+ return region_a;
}
static int
@@ -1696,7 +681,7 @@ add_type_for_runtime (tree type)
TREE_HASH (type), INSERT);
if (*slot == NULL)
{
- tree runtime = (*lang_eh_runtime_type) (type);
+ tree runtime = lang_hooks.eh_runtime_type (type);
*slot = tree_cons (type, runtime, NULL_TREE);
}
}
@@ -1773,7 +758,7 @@ ehspec_filter_hash (const void *pentry)
return h;
}
-/* Add TYPE (which may be NULL) to crtl->eh.ttype_data, using TYPES_HASH
+/* Add TYPE (which may be NULL) to cfun->eh->ttype_data, using TYPES_HASH
to speed up the search. Return the filter value to be used. */
static int
@@ -1790,16 +775,16 @@ add_ttypes_entry (htab_t ttypes_hash, tree type)
n = XNEW (struct ttypes_filter);
n->t = type;
- n->filter = VEC_length (tree, crtl->eh.ttype_data) + 1;
+ n->filter = VEC_length (tree, cfun->eh->ttype_data) + 1;
*slot = n;
- VEC_safe_push (tree, gc, crtl->eh.ttype_data, type);
+ VEC_safe_push (tree, gc, cfun->eh->ttype_data, type);
}
return n->filter;
}
-/* Add LIST to crtl->eh.ehspec_data, using EHSPEC_HASH and TYPES_HASH
+/* Add LIST to cfun->eh->ehspec_data, using EHSPEC_HASH and TYPES_HASH
to speed up the search. Return the filter value to be used. */
static int
@@ -1814,30 +799,38 @@ add_ehspec_entry (htab_t ehspec_hash, htab_t ttypes_hash, tree list)
if ((n = *slot) == NULL)
{
+ int len;
+
+ if (targetm.arm_eabi_unwinder)
+ len = VEC_length (tree, cfun->eh->ehspec_data.arm_eabi);
+ else
+ len = VEC_length (uchar, cfun->eh->ehspec_data.other);
+
/* Filter value is a -1 based byte index into a uleb128 buffer. */
n = XNEW (struct ttypes_filter);
n->t = list;
- n->filter = -(VARRAY_ACTIVE_SIZE (crtl->eh.ehspec_data) + 1);
+ n->filter = -(len + 1);
*slot = n;
/* Generate a 0 terminated list of filter values. */
for (; list ; list = TREE_CHAIN (list))
{
if (targetm.arm_eabi_unwinder)
- VARRAY_PUSH_TREE (crtl->eh.ehspec_data, TREE_VALUE (list));
+ VEC_safe_push (tree, gc, cfun->eh->ehspec_data.arm_eabi,
+ TREE_VALUE (list));
else
{
/* Look up each type in the list and encode its filter
value as a uleb128. */
- push_uleb128 (&crtl->eh.ehspec_data,
- add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
+ push_uleb128 (&cfun->eh->ehspec_data.other,
+ add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
}
}
if (targetm.arm_eabi_unwinder)
- VARRAY_PUSH_TREE (crtl->eh.ehspec_data, NULL_TREE);
+ VEC_safe_push (tree, gc, cfun->eh->ehspec_data.arm_eabi, NULL_TREE);
else
- VARRAY_PUSH_UCHAR (crtl->eh.ehspec_data, 0);
+ VEC_safe_push (uchar, gc, cfun->eh->ehspec_data.other, 0);
}
return n->filter;
@@ -1848,64 +841,63 @@ add_ehspec_entry (htab_t ehspec_hash, htab_t ttypes_hash, tree list)
we use lots of landing pads, and so every type or list can share
the same filter value, which saves table space. */
-static void
+void
assign_filter_values (void)
{
int i;
htab_t ttypes, ehspec;
+ eh_region r;
+ eh_catch c;
- crtl->eh.ttype_data = VEC_alloc (tree, gc, 16);
+ cfun->eh->ttype_data = VEC_alloc (tree, gc, 16);
if (targetm.arm_eabi_unwinder)
- VARRAY_TREE_INIT (crtl->eh.ehspec_data, 64, "ehspec_data");
+ cfun->eh->ehspec_data.arm_eabi = VEC_alloc (tree, gc, 64);
else
- VARRAY_UCHAR_INIT (crtl->eh.ehspec_data, 64, "ehspec_data");
+ cfun->eh->ehspec_data.other = VEC_alloc (uchar, gc, 64);
ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free);
ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free);
- for (i = cfun->eh->last_region_number; i > 0; --i)
+ for (i = 1; VEC_iterate (eh_region, cfun->eh->region_array, i, r); ++i)
{
- struct eh_region_d *r;
-
- r = VEC_index (eh_region, cfun->eh->region_array, i);
-
- /* Mind we don't process a region more than once. */
- if (!r || r->region_number != i)
+ if (r == NULL)
continue;
switch (r->type)
{
- case ERT_CATCH:
- /* Whatever type_list is (NULL or true list), we build a list
- of filters for the region. */
- r->u.eh_catch.filter_list = NULL_TREE;
-
- if (r->u.eh_catch.type_list != NULL)
+ case ERT_TRY:
+ for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
{
- /* Get a filter value for each of the types caught and store
- them in the region's dedicated list. */
- tree tp_node = r->u.eh_catch.type_list;
+ /* Whatever type_list is (NULL or true list), we build a list
+ of filters for the region. */
+ c->filter_list = NULL_TREE;
- for (;tp_node; tp_node = TREE_CHAIN (tp_node))
+ if (c->type_list != NULL)
{
- int flt = add_ttypes_entry (ttypes, TREE_VALUE (tp_node));
- tree flt_node = build_int_cst (NULL_TREE, flt);
+ /* Get a filter value for each of the types caught and store
+ them in the region's dedicated list. */
+ tree tp_node = c->type_list;
+
+ for ( ; tp_node; tp_node = TREE_CHAIN (tp_node))
+ {
+ int flt = add_ttypes_entry (ttypes, TREE_VALUE (tp_node));
+ tree flt_node = build_int_cst (NULL_TREE, flt);
- r->u.eh_catch.filter_list
- = tree_cons (NULL_TREE, flt_node, r->u.eh_catch.filter_list);
+ c->filter_list
+ = tree_cons (NULL_TREE, flt_node, c->filter_list);
+ }
}
- }
- else
- {
- /* Get a filter value for the NULL list also since it will need
- an action record anyway. */
- int flt = add_ttypes_entry (ttypes, NULL);
- tree flt_node = build_int_cst (NULL_TREE, flt);
+ else
+ {
+ /* Get a filter value for the NULL list also since it
+ will need an action record anyway. */
+ int flt = add_ttypes_entry (ttypes, NULL);
+ tree flt_node = build_int_cst (NULL_TREE, flt);
- r->u.eh_catch.filter_list
- = tree_cons (NULL_TREE, flt_node, r->u.eh_catch.filter_list);
+ c->filter_list
+ = tree_cons (NULL_TREE, flt_node, NULL);
+ }
}
-
break;
case ERT_ALLOWED_EXCEPTIONS:
@@ -1949,256 +941,29 @@ emit_to_new_bb_before (rtx seq, rtx insn)
bb->flags |= BB_SUPERBLOCK;
return bb;
}
-
-/* Generate the code to actually handle exceptions, which will follow the
- landing pads. */
-
-static void
-build_post_landing_pads (void)
-{
- int i;
-
- for (i = cfun->eh->last_region_number; i > 0; --i)
- {
- struct eh_region_d *region;
- rtx seq;
-
- region = VEC_index (eh_region, cfun->eh->region_array, i);
- /* Mind we don't process a region more than once. */
- if (!region || region->region_number != i)
- continue;
-
- switch (region->type)
- {
- case ERT_TRY:
- /* It is possible that TRY region is kept alive only because some of
- contained catch region still have RESX instruction but they are
- reached via their copies. In this case we need to do nothing. */
- if (!region->u.eh_try.eh_catch->label)
- break;
-
- /* ??? Collect the set of all non-overlapping catch handlers
- all the way up the chain until blocked by a cleanup. */
- /* ??? Outer try regions can share landing pads with inner
- try regions if the types are completely non-overlapping,
- and there are no intervening cleanups. */
-
- region->post_landing_pad = gen_label_rtx ();
-
- start_sequence ();
-
- emit_label (region->post_landing_pad);
-
- /* ??? It is mighty inconvenient to call back into the
- switch statement generation code in expand_end_case.
- Rapid prototyping sez a sequence of ifs. */
- {
- struct eh_region_d *c;
- for (c = region->u.eh_try.eh_catch; c ; c = c->u.eh_catch.next_catch)
- {
- if (c->u.eh_catch.type_list == NULL)
- emit_jump (c->label);
- else
- {
- /* Need for one cmp/jump per type caught. Each type
- list entry has a matching entry in the filter list
- (see assign_filter_values). */
- tree tp_node = c->u.eh_catch.type_list;
- tree flt_node = c->u.eh_catch.filter_list;
-
- for (; tp_node; )
- {
- emit_cmp_and_jump_insns
- (crtl->eh.filter,
- GEN_INT (tree_low_cst (TREE_VALUE (flt_node), 0)),
- EQ, NULL_RTX,
- targetm.eh_return_filter_mode (), 0, c->label);
-
- tp_node = TREE_CHAIN (tp_node);
- flt_node = TREE_CHAIN (flt_node);
- }
- }
- }
- }
-
- /* We delay the generation of the _Unwind_Resume until we generate
- landing pads. We emit a marker here so as to get good control
- flow data in the meantime. */
- gcc_assert (!region->resume);
- region->resume
- = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
- emit_barrier ();
-
- seq = get_insns ();
- end_sequence ();
-
- emit_to_new_bb_before (seq, region->u.eh_try.eh_catch->label);
-
- break;
-
- case ERT_ALLOWED_EXCEPTIONS:
- if (!region->label)
- break;
- region->post_landing_pad = gen_label_rtx ();
-
- start_sequence ();
-
- emit_label (region->post_landing_pad);
-
- emit_cmp_and_jump_insns (crtl->eh.filter,
- GEN_INT (region->u.allowed.filter),
- EQ, NULL_RTX,
- targetm.eh_return_filter_mode (), 0, region->label);
-
- /* We delay the generation of the _Unwind_Resume until we generate
- landing pads. We emit a marker here so as to get good control
- flow data in the meantime. */
- gcc_assert (!region->resume);
- region->resume
- = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
- emit_barrier ();
-
- seq = get_insns ();
- end_sequence ();
-
- emit_to_new_bb_before (seq, region->label);
- break;
-
- case ERT_CLEANUP:
- case ERT_MUST_NOT_THROW:
- region->post_landing_pad = region->label;
- break;
-
- case ERT_CATCH:
- case ERT_THROW:
- /* Nothing to do. */
- break;
-
- default:
- gcc_unreachable ();
- }
- }
-}
-
-/* Replace RESX patterns with jumps to the next handler if any, or calls to
- _Unwind_Resume otherwise. */
-
-static void
-connect_post_landing_pads (void)
-{
- int i;
-
- for (i = cfun->eh->last_region_number; i > 0; --i)
- {
- struct eh_region_d *region;
- struct eh_region_d *outer;
- rtx seq;
- rtx barrier;
- rtx resume_list;
-
- region = VEC_index (eh_region, cfun->eh->region_array, i);
- /* Mind we don't process a region more than once. */
- if (!region || region->region_number != i)
- continue;
-
- /* If there is no RESX, or it has been deleted by flow, there's
- nothing to fix up. */
- if (! region->resume)
- continue;
-
- /* Search for another landing pad in this function. */
- for (outer = region->outer; outer ; outer = outer->outer)
- if (outer->post_landing_pad)
- break;
-
- for (resume_list = region->resume; resume_list;
- resume_list = (GET_CODE (resume_list) == INSN_LIST
- ? XEXP (resume_list, 1) : NULL_RTX))
- {
- rtx resume = (GET_CODE (resume_list) == INSN_LIST
- ? XEXP (resume_list, 0) : resume_list);
- if (INSN_DELETED_P (resume))
- continue;
- start_sequence ();
-
- if (outer)
- {
- edge e;
- basic_block src, dest;
-
- emit_jump (outer->post_landing_pad);
- src = BLOCK_FOR_INSN (resume);
- dest = BLOCK_FOR_INSN (outer->post_landing_pad);
- while (EDGE_COUNT (src->succs) > 0)
- remove_edge (EDGE_SUCC (src, 0));
- e = make_edge (src, dest, 0);
- e->probability = REG_BR_PROB_BASE;
- e->count = src->count;
- }
- else
- {
- emit_library_call (unwind_resume_libfunc, LCT_THROW,
- VOIDmode, 1, crtl->eh.exc_ptr, ptr_mode);
-
- /* What we just emitted was a throwing libcall, so it got a
- barrier automatically added after it. If the last insn in
- the libcall sequence isn't the barrier, it's because the
- target emits multiple insns for a call, and there are insns
- after the actual call insn (which are redundant and would be
- optimized away). The barrier is inserted exactly after the
- call insn, so let's go get that and delete the insns after
- it, because below we need the barrier to be the last insn in
- the sequence. */
- delete_insns_since (NEXT_INSN (last_call_insn ()));
- }
-
- seq = get_insns ();
- end_sequence ();
- barrier = emit_insn_before (seq, resume);
- /* Avoid duplicate barrier. */
- gcc_assert (BARRIER_P (barrier));
- delete_insn (barrier);
- delete_insn (resume);
- }
-
- /* ??? From tree-ssa we can wind up with catch regions whose
- label is not instantiated, but whose resx is present. Now
- that we've dealt with the resx, kill the region. */
- if (region->label == NULL && region->type == ERT_CLEANUP)
- remove_eh_handler (region);
- }
-}
-
+/* Expand the extra code needed at landing pads for dwarf2 unwinding. */
+
static void
dw2_build_landing_pads (void)
{
int i;
+ eh_landing_pad lp;
- for (i = cfun->eh->last_region_number; i > 0; --i)
+ for (i = 1; VEC_iterate (eh_landing_pad, cfun->eh->lp_array, i, lp); ++i)
{
- struct eh_region_d *region;
- rtx seq;
+ eh_region region;
basic_block bb;
+ rtx seq;
edge e;
- region = VEC_index (eh_region, cfun->eh->region_array, i);
- /* Mind we don't process a region more than once. */
- if (!region || region->region_number != i)
- continue;
-
- if (region->type != ERT_CLEANUP
- && region->type != ERT_TRY
- && region->type != ERT_ALLOWED_EXCEPTIONS)
- continue;
-
- if (!region->post_landing_pad)
+ if (lp == NULL || lp->post_landing_pad == NULL)
continue;
start_sequence ();
- region->landing_pad = gen_label_rtx ();
- emit_label (region->landing_pad);
+ lp->landing_pad = gen_label_rtx ();
+ emit_label (lp->landing_pad);
#ifdef HAVE_exception_receiver
if (HAVE_exception_receiver)
@@ -2212,16 +977,19 @@ dw2_build_landing_pads (void)
#endif
{ /* Nothing */ }
- emit_move_insn (crtl->eh.exc_ptr,
- gen_rtx_REG (ptr_mode, EH_RETURN_DATA_REGNO (0)));
- emit_move_insn (crtl->eh.filter,
- gen_rtx_REG (targetm.eh_return_filter_mode (),
- EH_RETURN_DATA_REGNO (1)));
+ region = lp->region;
+ if (region->exc_ptr_reg)
+ emit_move_insn (region->exc_ptr_reg,
+ gen_rtx_REG (ptr_mode, EH_RETURN_DATA_REGNO (0)));
+ if (region->filter_reg)
+ emit_move_insn (region->filter_reg,
+ gen_rtx_REG (targetm.eh_return_filter_mode (),
+ EH_RETURN_DATA_REGNO (1)));
seq = get_insns ();
end_sequence ();
- bb = emit_to_new_bb_before (seq, region->post_landing_pad);
+ bb = emit_to_new_bb_before (seq, label_rtx (lp->post_landing_pad));
e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
e->count = bb->count;
e->probability = REG_BR_PROB_BASE;
@@ -2229,140 +997,71 @@ dw2_build_landing_pads (void)
}
-struct sjlj_lp_info
-{
- int directly_reachable;
- int action_index;
- int dispatch_index;
- int call_site_index;
-};
-
-static bool
-sjlj_find_directly_reachable_regions (struct sjlj_lp_info *lp_info)
-{
- rtx insn;
- bool found_one = false;
-
- for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
- {
- struct eh_region_d *region;
- enum reachable_code rc;
- tree type_thrown;
- rtx note;
+static VEC (int, heap) *sjlj_lp_call_site_index;
- if (! INSN_P (insn))
- continue;
-
- note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
- if (!note || INTVAL (XEXP (note, 0)) <= 0)
- continue;
-
- region = VEC_index (eh_region, cfun->eh->region_array, INTVAL (XEXP (note, 0)));
- if (!region)
- continue;
+/* Process all active landing pads. Assign each one a compact dispatch
+ index, and a call-site index. */
- type_thrown = NULL_TREE;
- if (region->type == ERT_THROW)
- {
- type_thrown = region->u.eh_throw.type;
- region = region->outer;
- }
-
- /* Find the first containing region that might handle the exception.
- That's the landing pad to which we will transfer control. */
- rc = RNL_NOT_CAUGHT;
- for (; region; region = region->outer)
- {
- rc = reachable_next_level (region, type_thrown, NULL, false);
- if (rc != RNL_NOT_CAUGHT)
- break;
- }
- if (rc == RNL_MAYBE_CAUGHT || rc == RNL_CAUGHT)
- {
- lp_info[region->region_number].directly_reachable = 1;
- found_one = true;
- }
- }
-
- return found_one;
-}
-
-static void
-sjlj_assign_call_site_values (rtx dispatch_label, struct sjlj_lp_info *lp_info)
+static int
+sjlj_assign_call_site_values (void)
{
htab_t ar_hash;
- int i, index;
+ int i, disp_index;
+ eh_landing_pad lp;
- /* First task: build the action table. */
-
- VARRAY_UCHAR_INIT (crtl->eh.action_record_data, 64, "action_record_data");
+ crtl->eh.action_record_data = VEC_alloc (uchar, gc, 64);
ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
- for (i = cfun->eh->last_region_number; i > 0; --i)
- if (lp_info[i].directly_reachable)
+ disp_index = 0;
+ call_site_base = 1;
+ for (i = 1; VEC_iterate (eh_landing_pad, cfun->eh->lp_array, i, lp); ++i)
+ if (lp && lp->post_landing_pad)
{
- struct eh_region_d *r =
- VEC_index (eh_region, cfun->eh->region_array, i);
+ int action, call_site;
- r->landing_pad = dispatch_label;
- lp_info[i].action_index = collect_one_action_chain (ar_hash, r);
- if (lp_info[i].action_index != -1)
+ /* First: build the action table. */
+ action = collect_one_action_chain (ar_hash, lp->region);
+ if (action != -1)
crtl->uses_eh_lsda = 1;
- }
-
- htab_delete (ar_hash);
-
- /* Next: assign dispatch values. In dwarf2 terms, this would be the
- landing pad label for the region. For sjlj though, there is one
- common landing pad from which we dispatch to the post-landing pads.
-
- A region receives a dispatch index if it is directly reachable
- and requires in-function processing. Regions that share post-landing
- pads may share dispatch indices. */
- /* ??? Post-landing pad sharing doesn't actually happen at the moment
- (see build_post_landing_pads) so we don't bother checking for it. */
-
- index = 0;
- for (i = cfun->eh->last_region_number; i > 0; --i)
- if (lp_info[i].directly_reachable)
- lp_info[i].dispatch_index = index++;
-
- /* Finally: assign call-site values. If dwarf2 terms, this would be
- the region number assigned by convert_to_eh_region_ranges, but
- handles no-action and must-not-throw differently. */
-
- call_site_base = 1;
- for (i = cfun->eh->last_region_number; i > 0; --i)
- if (lp_info[i].directly_reachable)
- {
- int action = lp_info[i].action_index;
+ /* Next: assign call-site values. If dwarf2 terms, this would be
+ the region number assigned by convert_to_eh_region_ranges, but
+ handles no-action and must-not-throw differently. */
/* Map must-not-throw to otherwise unused call-site index 0. */
if (action == -2)
- index = 0;
+ call_site = 0;
/* Map no-action to otherwise unused call-site index -1. */
else if (action == -1)
- index = -1;
+ call_site = -1;
/* Otherwise, look it up in the table. */
else
- index = add_call_site (GEN_INT (lp_info[i].dispatch_index),
- action, 0);
+ call_site = add_call_site (GEN_INT (disp_index), action, 0);
+ VEC_replace (int, sjlj_lp_call_site_index, i, call_site);
- lp_info[i].call_site_index = index;
+ disp_index++;
}
+
+ htab_delete (ar_hash);
+
+ return disp_index;
}
+/* Emit code to record the current call-site index before every
+ insn that can throw. */
+
static void
-sjlj_mark_call_sites (struct sjlj_lp_info *lp_info)
+sjlj_mark_call_sites (void)
{
int last_call_site = -2;
rtx insn, mem;
for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
{
- struct eh_region_d *region;
+ eh_landing_pad lp;
+ eh_region r;
+ bool nothrow;
int this_call_site;
- rtx note, before, p;
+ rtx before, p;
/* Reset value tracking at extended basic block boundaries. */
if (LABEL_P (insn))
@@ -2371,31 +1070,23 @@ sjlj_mark_call_sites (struct sjlj_lp_info *lp_info)
if (! INSN_P (insn))
continue;
- note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
-
- /* Calls that are known to not throw need not be marked. */
- if (note && INTVAL (XEXP (note, 0)) <= 0)
+ nothrow = get_eh_region_and_lp_from_rtx (insn, &r, &lp);
+ if (nothrow)
continue;
-
- if (note)
- region = VEC_index (eh_region, cfun->eh->region_array, INTVAL (XEXP (note, 0)));
- else
- region = NULL;
-
- if (!region)
+ if (lp)
+ this_call_site = VEC_index (int, sjlj_lp_call_site_index, lp->index);
+ else if (r == NULL)
{
/* Calls (and trapping insns) without notes are outside any
exception handling region in this function. Mark them as
no action. */
- if (CALL_P (insn)
- || (flag_non_call_exceptions
- && may_trap_p (PATTERN (insn))))
- this_call_site = -1;
- else
- continue;
+ this_call_site = -1;
}
else
- this_call_site = lp_info[region->region_number].call_site_index;
+ {
+ gcc_assert (r->type == ERT_MUST_NOT_THROW);
+ this_call_site = 0;
+ }
if (this_call_site == last_call_site)
continue;
@@ -2424,6 +1115,7 @@ sjlj_emit_function_enter (rtx dispatch_label)
{
rtx fn_begin, fc, mem, seq;
bool fn_begin_outside_block;
+ rtx personality = get_personality_function (current_function_decl);
fc = crtl->eh.sjlj_fc;
@@ -2432,9 +1124,9 @@ sjlj_emit_function_enter (rtx dispatch_label)
/* We're storing this libcall's address into memory instead of
calling it directly. Thus, we must call assemble_external_libcall
here, as we can not depend on emit_library_call to do it for us. */
- assemble_external_libcall (eh_personality_libfunc);
+ assemble_external_libcall (personality);
mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
- emit_move_insn (mem, eh_personality_libfunc);
+ emit_move_insn (mem, personality);
mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
if (crtl->uses_eh_lsda)
@@ -2527,15 +1219,18 @@ sjlj_emit_function_exit (void)
}
static void
-sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info)
+sjlj_emit_dispatch_table (rtx dispatch_label, int num_dispatch)
{
enum machine_mode unwind_word_mode = targetm.unwind_word_mode ();
enum machine_mode filter_mode = targetm.eh_return_filter_mode ();
- int i, first_reachable;
- rtx mem, dispatch, seq, fc;
- rtx before;
+ eh_landing_pad lp;
+ rtx mem, seq, fc, before, exc_ptr_reg, filter_reg;
+ rtx first_reachable_label;
basic_block bb;
+ eh_region r;
edge e;
+ int i, disp_index;
+ gimple switch_stmt;
fc = crtl->eh.sjlj_fc;
@@ -2545,14 +1240,18 @@ sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info)
#ifndef DONT_USE_BUILTIN_SETJMP
expand_builtin_setjmp_receiver (dispatch_label);
-#endif
- /* Load up dispatch index, exc_ptr and filter values from the
- function context. */
- mem = adjust_address (fc, TYPE_MODE (integer_type_node),
- sjlj_fc_call_site_ofs);
- dispatch = copy_to_reg (mem);
+ /* The caller of expand_builtin_setjmp_receiver is responsible for
+ making sure that the label doesn't vanish. The only other caller
+ is the expander for __builtin_setjmp_receiver, which places this
+ label on the nonlocal_goto_label list. Since we're modeling these
+ CFG edges more exactly, we can use the forced_labels list instead. */
+ LABEL_PRESERVE_P (dispatch_label) = 1;
+ forced_labels
+ = gen_rtx_EXPR_LIST (VOIDmode, dispatch_label, forced_labels);
+#endif
+ /* Load up exc_ptr and filter values from the function context. */
mem = adjust_address (fc, unwind_word_mode, sjlj_fc_data_ofs);
if (unwind_word_mode != ptr_mode)
{
@@ -2562,58 +1261,110 @@ sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info)
mem = convert_to_mode (ptr_mode, mem, 0);
#endif
}
- emit_move_insn (crtl->eh.exc_ptr, mem);
+ exc_ptr_reg = force_reg (ptr_mode, mem);
mem = adjust_address (fc, unwind_word_mode,
sjlj_fc_data_ofs + GET_MODE_SIZE (unwind_word_mode));
if (unwind_word_mode != filter_mode)
mem = convert_to_mode (filter_mode, mem, 0);
- emit_move_insn (crtl->eh.filter, mem);
+ filter_reg = force_reg (filter_mode, mem);
/* Jump to one of the directly reachable regions. */
- /* ??? This really ought to be using a switch statement. */
- first_reachable = 0;
- for (i = cfun->eh->last_region_number; i > 0; --i)
+ disp_index = 0;
+ first_reachable_label = NULL;
+
+ /* If there's exactly one call site in the function, don't bother
+ generating a switch statement. */
+ switch_stmt = NULL;
+ if (num_dispatch > 1)
{
- if (! lp_info[i].directly_reachable)
- continue;
+ tree disp;
- if (! first_reachable)
- {
- first_reachable = i;
- continue;
- }
+ mem = adjust_address (fc, TYPE_MODE (integer_type_node),
+ sjlj_fc_call_site_ofs);
+ disp = make_tree (integer_type_node, mem);
+
+ switch_stmt = gimple_build_switch_nlabels (num_dispatch, disp, NULL);
+ }
+
+ for (i = 1; VEC_iterate (eh_landing_pad, cfun->eh->lp_array, i, lp); ++i)
+ if (lp && lp->post_landing_pad)
+ {
+ rtx seq2, label;
+
+ start_sequence ();
+
+ lp->landing_pad = dispatch_label;
+
+ if (num_dispatch > 1)
+ {
+ tree t_label, case_elt;
+
+ t_label = create_artificial_label (UNKNOWN_LOCATION);
+ case_elt = build3 (CASE_LABEL_EXPR, void_type_node,
+ build_int_cst (NULL, disp_index),
+ NULL, t_label);
+ gimple_switch_set_label (switch_stmt, disp_index, case_elt);
+
+ label = label_rtx (t_label);
+ }
+ else
+ label = gen_label_rtx ();
- emit_cmp_and_jump_insns (dispatch, GEN_INT (lp_info[i].dispatch_index),
- EQ, NULL_RTX, TYPE_MODE (integer_type_node), 0,
- (((struct eh_region_d *)
- VEC_index (eh_region,
- cfun->eh->region_array, i))
- ->post_landing_pad));
+ if (disp_index == 0)
+ first_reachable_label = label;
+ emit_label (label);
+
+ r = lp->region;
+ if (r->exc_ptr_reg)
+ emit_move_insn (r->exc_ptr_reg, exc_ptr_reg);
+ if (r->filter_reg)
+ emit_move_insn (r->filter_reg, filter_reg);
+
+ seq2 = get_insns ();
+ end_sequence ();
+
+ before = label_rtx (lp->post_landing_pad);
+ bb = emit_to_new_bb_before (seq2, before);
+ e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
+ e->count = bb->count;
+ e->probability = REG_BR_PROB_BASE;
+
+ disp_index++;
+ }
+ gcc_assert (disp_index == num_dispatch);
+
+ if (num_dispatch > 1)
+ {
+ expand_case (switch_stmt);
+ expand_builtin_trap ();
}
seq = get_insns ();
end_sequence ();
- before = (((struct eh_region_d *)
- VEC_index (eh_region, cfun->eh->region_array, first_reachable))
- ->post_landing_pad);
-
- bb = emit_to_new_bb_before (seq, before);
- e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
- e->count = bb->count;
- e->probability = REG_BR_PROB_BASE;
+ bb = emit_to_new_bb_before (seq, first_reachable_label);
+ if (num_dispatch == 1)
+ {
+ e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
+ e->count = bb->count;
+ e->probability = REG_BR_PROB_BASE;
+ }
}
static void
sjlj_build_landing_pads (void)
{
- struct sjlj_lp_info *lp_info;
+ int num_dispatch;
- lp_info = XCNEWVEC (struct sjlj_lp_info, cfun->eh->last_region_number + 1);
+ num_dispatch = VEC_length (eh_landing_pad, cfun->eh->lp_array);
+ if (num_dispatch == 0)
+ return;
+ VEC_safe_grow (int, heap, sjlj_lp_call_site_index, num_dispatch);
- if (sjlj_find_directly_reachable_regions (lp_info))
+ num_dispatch = sjlj_assign_call_site_values ();
+ if (num_dispatch > 0)
{
rtx dispatch_label = gen_label_rtx ();
int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node,
@@ -2624,15 +1375,13 @@ sjlj_build_landing_pads (void)
int_size_in_bytes (sjlj_fc_type_node),
align);
- sjlj_assign_call_site_values (dispatch_label, lp_info);
- sjlj_mark_call_sites (lp_info);
-
+ sjlj_mark_call_sites ();
sjlj_emit_function_enter (dispatch_label);
- sjlj_emit_dispatch_table (dispatch_label, lp_info);
+ sjlj_emit_dispatch_table (dispatch_label, num_dispatch);
sjlj_emit_function_exit ();
}
- free (lp_info);
+ VEC_free (int, heap, sjlj_lp_call_site_index);
}
/* After initial rtl generation, call back to finish generating
@@ -2643,700 +1392,405 @@ finish_eh_generation (void)
{
basic_block bb;
- /* Nothing to do if no regions created. */
- if (cfun->eh->region_tree == NULL)
- return;
-
- /* The object here is to provide detailed information (via
- reachable_handlers) on how exception control flows within the
- function for the CFG construction. In this first pass, we can
- include type information garnered from ERT_THROW and
- ERT_ALLOWED_EXCEPTIONS regions, and hope that it will be useful
- in deleting unreachable handlers. Subsequently, we will generate
- landing pads which will connect many of the handlers, and then
- type information will not be effective. Still, this is a win
- over previous implementations. */
-
- /* These registers are used by the landing pads. Make sure they
- have been generated. */
- get_exception_pointer ();
- get_exception_filter ();
-
/* Construct the landing pads. */
-
- assign_filter_values ();
- build_post_landing_pads ();
- connect_post_landing_pads ();
if (USING_SJLJ_EXCEPTIONS)
sjlj_build_landing_pads ();
else
dw2_build_landing_pads ();
-
- crtl->eh.built_landing_pads = 1;
-
- /* We've totally changed the CFG. Start over. */
- find_exception_handler_labels ();
break_superblocks ();
+
if (USING_SJLJ_EXCEPTIONS
/* Kludge for Alpha/Tru64 (see alpha_gp_save_rtx). */
|| single_succ_edge (ENTRY_BLOCK_PTR)->insns.r)
commit_edge_insertions ();
+
+ /* Redirect all EH edges from the post_landing_pad to the landing pad. */
FOR_EACH_BB (bb)
{
- edge e;
+ eh_landing_pad lp;
edge_iterator ei;
- bool eh = false;
- for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
+ edge e;
+
+ lp = get_eh_landing_pad_from_rtx (BB_END (bb));
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (e->flags & EDGE_EH)
+ break;
+
+ /* We should not have generated any new throwing insns during this
+ pass, and we should not have lost any EH edges, so we only need
+ to handle two cases here:
+ (1) reachable handler and an existing edge to post-landing-pad,
+ (2) no reachable handler and no edge. */
+ gcc_assert ((lp != NULL) == (e != NULL));
+ if (lp != NULL)
{
- if (e->flags & EDGE_EH)
- {
- remove_edge (e);
- eh = true;
- }
- else
- ei_next (&ei);
+ gcc_assert (BB_HEAD (e->dest) == label_rtx (lp->post_landing_pad));
+
+ redirect_edge_succ (e, BLOCK_FOR_INSN (lp->landing_pad));
+ e->flags |= (CALL_P (BB_END (bb))
+ ? EDGE_ABNORMAL | EDGE_ABNORMAL_CALL
+ : EDGE_ABNORMAL);
}
- if (eh)
- rtl_make_eh_edge (NULL, bb, BB_END (bb));
}
}
-
-/* This section handles removing dead code for flow. */
-/* Splice REGION from the region tree and replace it by REPLACE etc.
- When UPDATE_CATCH_TRY is true mind updating links from catch to try
- region.*/
+static bool
+gate_handle_eh (void)
+{
+ /* Nothing to do if no regions created. */
+ return cfun->eh->region_tree != NULL;
+}
-static void
-remove_eh_handler_and_replace (struct eh_region_d *region,
- struct eh_region_d *replace,
- bool update_catch_try)
+/* Complete generation of exception handling code. */
+static unsigned int
+rest_of_handle_eh (void)
{
- struct eh_region_d **pp, **pp_start, *p, *outer, *inner;
- rtx lab;
+ finish_eh_generation ();
+ cleanup_cfg (CLEANUP_NO_INSN_DEL);
+ return 0;
+}
- outer = region->outer;
+struct rtl_opt_pass pass_rtl_eh =
+{
+ {
+ RTL_PASS,
+ "eh", /* name */
+ gate_handle_eh, /* gate */
+ rest_of_handle_eh, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_JUMP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func /* todo_flags_finish */
+ }
+};
+
+/* This section handles removing dead code for flow. */
+
+void
+remove_eh_landing_pad (eh_landing_pad lp)
+{
+ eh_landing_pad *pp;
- /* For the benefit of efficiently handling REG_EH_REGION notes,
- replace this region in the region array with its containing
- region. Note that previous region deletions may result in
- multiple copies of this region in the array, so we have a
- list of alternate numbers by which we are known. */
+ for (pp = &lp->region->landing_pads; *pp != lp; pp = &(*pp)->next_lp)
+ continue;
+ *pp = lp->next_lp;
+
+ if (lp->post_landing_pad)
+ EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
+ VEC_replace (eh_landing_pad, cfun->eh->lp_array, lp->index, NULL);
+}
- VEC_replace (eh_region, cfun->eh->region_array, region->region_number,
- replace);
- if (region->aka)
- {
- unsigned i;
- bitmap_iterator bi;
+/* Splice REGION from the region tree. */
- EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i, bi)
- {
- VEC_replace (eh_region, cfun->eh->region_array, i, replace);
- }
- }
+void
+remove_eh_handler (eh_region region)
+{
+ eh_region *pp, *pp_start, p, outer;
+ eh_landing_pad lp;
- if (replace)
+ for (lp = region->landing_pads; lp ; lp = lp->next_lp)
{
- if (!replace->aka)
- replace->aka = BITMAP_GGC_ALLOC ();
- if (region->aka)
- bitmap_ior_into (replace->aka, region->aka);
- bitmap_set_bit (replace->aka, region->region_number);
+ if (lp->post_landing_pad)
+ EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
+ VEC_replace (eh_landing_pad, cfun->eh->lp_array, lp->index, NULL);
}
- if (crtl->eh.built_landing_pads)
- lab = region->landing_pad;
- else
- lab = region->label;
+ outer = region->outer;
if (outer)
pp_start = &outer->inner;
else
pp_start = &cfun->eh->region_tree;
for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp)
continue;
- *pp = region->next_peer;
-
- if (replace)
- pp_start = &replace->inner;
- else
- pp_start = &cfun->eh->region_tree;
- inner = region->inner;
- if (inner)
+ if (region->inner)
{
- for (p = inner; p->next_peer ; p = p->next_peer)
- p->outer = replace;
- p->outer = replace;
-
- p->next_peer = *pp_start;
- *pp_start = inner;
+ *pp = p = region->inner;
+ do
+ {
+ p->outer = outer;
+ pp = &p->next_peer;
+ p = *pp;
+ }
+ while (p);
}
+ *pp = region->next_peer;
- if (region->type == ERT_CATCH
- && update_catch_try)
- {
- struct eh_region_d *eh_try, *next, *prev;
+ VEC_replace (eh_region, cfun->eh->region_array, region->index, NULL);
+}
- for (eh_try = region->next_peer;
- eh_try->type == ERT_CATCH;
- eh_try = eh_try->next_peer)
- continue;
- gcc_assert (eh_try->type == ERT_TRY);
+/* Invokes CALLBACK for every exception handler landing pad label.
+ Only used by reload hackery; should not be used by new code. */
- next = region->u.eh_catch.next_catch;
- prev = region->u.eh_catch.prev_catch;
+void
+for_each_eh_label (void (*callback) (rtx))
+{
+ eh_landing_pad lp;
+ int i;
- if (next)
- next->u.eh_catch.prev_catch = prev;
- else
- eh_try->u.eh_try.last_catch = prev;
- if (prev)
- prev->u.eh_catch.next_catch = next;
- else
+ for (i = 1; VEC_iterate (eh_landing_pad, cfun->eh->lp_array, i, lp); ++i)
+ {
+ if (lp)
{
- eh_try->u.eh_try.eh_catch = next;
- if (! next)
- remove_eh_handler (eh_try);
+ rtx lab = lp->landing_pad;
+ if (lab && LABEL_P (lab))
+ (*callback) (lab);
}
}
}
-
-/* Splice REGION from the region tree and replace it by the outer region
- etc. */
-
-static void
-remove_eh_handler (struct eh_region_d *region)
-{
- remove_eh_handler_and_replace (region, region->outer, true);
-}
-
-/* Remove Eh region R that has turned out to have no code in its handler. */
+
+/* Create the REG_EH_REGION note for INSN, given its ECF_FLAGS for a
+ call insn.
+
+ At the gimple level, we use LP_NR
+ > 0 : The statement transfers to landing pad LP_NR
+ = 0 : The statement is outside any EH region
+ < 0 : The statement is within MUST_NOT_THROW region -LP_NR.
+
+ At the rtl level, we use LP_NR
+ > 0 : The insn transfers to landing pad LP_NR
+ = 0 : The insn cannot throw
+ < 0 : The insn is within MUST_NOT_THROW region -LP_NR
+ = INT_MIN : The insn cannot throw or execute a nonlocal-goto.
+ missing note: The insn is outside any EH region.
+
+ ??? This difference probably ought to be avoided. We could stand
+ to record nothrow for arbitrary gimple statements, and so avoid
+ some moderately complex lookups in stmt_could_throw_p. Perhaps
+ NOTHROW should be mapped on both sides to INT_MIN. Perhaps the
+ no-nonlocal-goto property should be recorded elsewhere as a bit
+ on the call_insn directly. Perhaps we should make more use of
+ attaching the trees to call_insns (reachable via symbol_ref in
+ direct call cases) and just pull the data out of the trees. */
void
-remove_eh_region (int r)
+make_reg_eh_region_note (rtx insn, int ecf_flags, int lp_nr)
{
- struct eh_region_d *region;
-
- region = VEC_index (eh_region, cfun->eh->region_array, r);
- remove_eh_handler (region);
+ rtx value;
+ if (ecf_flags & ECF_NOTHROW)
+ value = const0_rtx;
+ else if (lp_nr != 0)
+ value = GEN_INT (lp_nr);
+ else
+ return;
+ add_reg_note (insn, REG_EH_REGION, value);
}
-/* Remove Eh region R that has turned out to have no code in its handler
- and replace in by R2. */
+/* Create a REG_EH_REGION note for a CALL_INSN that cannot throw
+ nor perform a non-local goto. Replace the region note if it
+ already exists. */
void
-remove_eh_region_and_replace_by_outer_of (int r, int r2)
+make_reg_eh_region_note_nothrow_nononlocal (rtx insn)
{
- struct eh_region_d *region, *region2;
+ rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+ rtx intmin = GEN_INT (INT_MIN);
- region = VEC_index (eh_region, cfun->eh->region_array, r);
- region2 = VEC_index (eh_region, cfun->eh->region_array, r2);
- remove_eh_handler_and_replace (region, region2->outer, true);
+ if (note != 0)
+ XEXP (note, 0) = intmin;
+ else
+ add_reg_note (insn, REG_EH_REGION, intmin);
}
-/* Invokes CALLBACK for every exception handler label. Only used by old
- loop hackery; should not be used by new code. */
+/* Return true if INSN could throw, assuming no REG_EH_REGION note
+ to the contrary. */
-void
-for_each_eh_label (void (*callback) (rtx))
+bool
+insn_could_throw_p (const_rtx insn)
{
- int i;
- for (i = 0; i < cfun->eh->last_region_number; i++)
- {
- struct eh_region_d *r = VEC_index (eh_region, cfun->eh->region_array, i);
- if (r && r->region_number == i && r->label
- && LABEL_P (r->label))
- (*callback) (r->label);
- }
+ if (CALL_P (insn))
+ return true;
+ if (INSN_P (insn) && flag_non_call_exceptions)
+ return may_trap_p (PATTERN (insn));
+ return false;
}
-/* Invoke CALLBACK for every exception region in the current function. */
+/* Copy an REG_EH_REGION note to each insn that might throw beginning
+ at FIRST and ending at LAST. NOTE_OR_INSN is either the source insn
+ to look for a note, or the note itself. */
void
-for_each_eh_region (void (*callback) (struct eh_region_d *))
+copy_reg_eh_region_note_forward (rtx note_or_insn, rtx first, rtx last)
{
- int i, n = cfun->eh->last_region_number;
- for (i = 1; i <= n; ++i)
- {
- struct eh_region_d *region;
+ rtx insn, note = note_or_insn;
- region = VEC_index (eh_region, cfun->eh->region_array, i);
- if (region)
- (*callback) (region);
+ if (INSN_P (note_or_insn))
+ {
+ note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX);
+ if (note == NULL)
+ return;
}
-}
-
-/* This section describes CFG exception edges for flow. */
+ note = XEXP (note, 0);
-/* For communicating between calls to reachable_next_level. */
-struct reachable_info
-{
- tree types_caught;
- tree types_allowed;
- void (*callback) (struct eh_region_d *, void *);
- void *callback_data;
-};
+ for (insn = first; insn != last ; insn = NEXT_INSN (insn))
+ if (!find_reg_note (insn, REG_EH_REGION, NULL_RTX)
+ && insn_could_throw_p (insn))
+ add_reg_note (insn, REG_EH_REGION, note);
+}
-/* A subroutine of reachable_next_level. Return true if TYPE, or a
- base class of TYPE, is in HANDLED. */
+/* Likewise, but iterate backward. */
-static int
-check_handled (tree handled, tree type)
+void
+copy_reg_eh_region_note_backward (rtx note_or_insn, rtx last, rtx first)
{
- tree t;
+ rtx insn, note = note_or_insn;
- /* We can check for exact matches without front-end help. */
- if (! lang_eh_type_covers)
- {
- for (t = handled; t ; t = TREE_CHAIN (t))
- {
- tree t1 = TREE_VALUE (t);
- tree t2 = type;
-
- /* If the types have been converted to runtime types (i.e.,
- when the IL is being read from disk in an LTO
- compilation), then T1 and T2 will be pointers to the
- runtime type of the form '(void *) &<runtime_type>' (See
- cp/except.c:build_eh_type_type). Strip the conversion
- and the address. */
- if (CONVERT_EXPR_P (t1))
- {
- STRIP_NOPS (t1);
- gcc_assert (TREE_CODE (t1) == ADDR_EXPR);
- t1 = TREE_OPERAND (t1, 0);
- }
-
- if (CONVERT_EXPR_P (t2))
- {
- STRIP_NOPS (t2);
- gcc_assert (TREE_CODE (t2) == ADDR_EXPR);
- t2 = TREE_OPERAND (t2, 0);
- }
-
- if (t1 == t2)
- return 1;
- }
- }
- else
+ if (INSN_P (note_or_insn))
{
- for (t = handled; t ; t = TREE_CHAIN (t))
- if ((*lang_eh_type_covers) (TREE_VALUE (t), type))
- return 1;
+ note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX);
+ if (note == NULL)
+ return;
}
+ note = XEXP (note, 0);
- return 0;
+ for (insn = last; insn != first; insn = PREV_INSN (insn))
+ if (insn_could_throw_p (insn))
+ add_reg_note (insn, REG_EH_REGION, note);
}
-/* A subroutine of reachable_next_level. If we are collecting a list
- of handlers, add one. After landing pad generation, reference
- it instead of the handlers themselves. Further, the handlers are
- all wired together, so by referencing one, we've got them all.
- Before landing pad generation we reference each handler individually.
- LP_REGION contains the landing pad; REGION is the handler. */
+/* Extract all EH information from INSN. Return true if the insn
+ was marked NOTHROW. */
-static void
-add_reachable_handler (struct reachable_info *info,
- struct eh_region_d *lp_region,
- struct eh_region_d *region)
+static bool
+get_eh_region_and_lp_from_rtx (const_rtx insn, eh_region *pr,
+ eh_landing_pad *plp)
{
- if (! info)
- return;
+ eh_landing_pad lp = NULL;
+ eh_region r = NULL;
+ bool ret = false;
+ rtx note;
+ int lp_nr;
- if (crtl->eh.built_landing_pads)
- info->callback (lp_region, info->callback_data);
- else
- info->callback (region, info->callback_data);
-}
+ if (! INSN_P (insn))
+ goto egress;
-/* Process one level of exception regions for reachability.
- If TYPE_THROWN is non-null, then it is the *exact* type being
- propagated. If INFO is non-null, then collect handler labels
- and caught/allowed type information between invocations. */
+ if (NONJUMP_INSN_P (insn)
+ && GET_CODE (PATTERN (insn)) == SEQUENCE)
+ insn = XVECEXP (PATTERN (insn), 0, 0);
-static enum reachable_code
-reachable_next_level (struct eh_region_d *region, tree type_thrown,
- struct reachable_info *info,
- bool maybe_resx)
-{
- switch (region->type)
+ note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+ if (!note)
{
- case ERT_CLEANUP:
- /* Before landing-pad generation, we model control flow
- directly to the individual handlers. In this way we can
- see that catch handler types may shadow one another. */
- add_reachable_handler (info, region, region);
- return RNL_MAYBE_CAUGHT;
-
- case ERT_TRY:
- {
- struct eh_region_d *c;
- enum reachable_code ret = RNL_NOT_CAUGHT;
-
- for (c = region->u.eh_try.eh_catch; c ; c = c->u.eh_catch.next_catch)
- {
- /* A catch-all handler ends the search. */
- if (c->u.eh_catch.type_list == NULL)
- {
- add_reachable_handler (info, region, c);
- return RNL_CAUGHT;
- }
-
- if (type_thrown)
- {
- /* If we have at least one type match, end the search. */
- tree tp_node = c->u.eh_catch.type_list;
-
- for (; tp_node; tp_node = TREE_CHAIN (tp_node))
- {
- tree type = TREE_VALUE (tp_node);
-
- if (type == type_thrown
- || (lang_eh_type_covers
- && (*lang_eh_type_covers) (type, type_thrown)))
- {
- add_reachable_handler (info, region, c);
- return RNL_CAUGHT;
- }
- }
-
- /* If we have definitive information of a match failure,
- the catch won't trigger. */
- if (lang_eh_type_covers)
- return RNL_NOT_CAUGHT;
- }
-
- /* At this point, we either don't know what type is thrown or
- don't have front-end assistance to help deciding if it is
- covered by one of the types in the list for this region.
-
- We'd then like to add this region to the list of reachable
- handlers since it is indeed potentially reachable based on the
- information we have.
-
- Actually, this handler is for sure not reachable if all the
- types it matches have already been caught. That is, it is only
- potentially reachable if at least one of the types it catches
- has not been previously caught. */
-
- if (! info)
- ret = RNL_MAYBE_CAUGHT;
- else
- {
- tree tp_node = c->u.eh_catch.type_list;
- bool maybe_reachable = false;
-
- /* Compute the potential reachability of this handler and
- update the list of types caught at the same time. */
- for (; tp_node; tp_node = TREE_CHAIN (tp_node))
- {
- tree type = TREE_VALUE (tp_node);
-
- if (! check_handled (info->types_caught, type))
- {
- info->types_caught
- = tree_cons (NULL, type, info->types_caught);
-
- maybe_reachable = true;
- }
- }
-
- if (maybe_reachable)
- {
- add_reachable_handler (info, region, c);
-
- /* ??? If the catch type is a base class of every allowed
- type, then we know we can stop the search. */
- ret = RNL_MAYBE_CAUGHT;
- }
- }
- }
-
- return ret;
- }
-
- case ERT_ALLOWED_EXCEPTIONS:
- /* An empty list of types definitely ends the search. */
- if (region->u.allowed.type_list == NULL_TREE)
- {
- add_reachable_handler (info, region, region);
- return RNL_CAUGHT;
- }
-
- /* Collect a list of lists of allowed types for use in detecting
- when a catch may be transformed into a catch-all. */
- if (info)
- info->types_allowed = tree_cons (NULL_TREE,
- region->u.allowed.type_list,
- info->types_allowed);
-
- /* If we have definitive information about the type hierarchy,
- then we can tell if the thrown type will pass through the
- filter. */
- if (type_thrown && lang_eh_type_covers)
- {
- if (check_handled (region->u.allowed.type_list, type_thrown))
- return RNL_NOT_CAUGHT;
- else
- {
- add_reachable_handler (info, region, region);
- return RNL_CAUGHT;
- }
- }
-
- add_reachable_handler (info, region, region);
- return RNL_MAYBE_CAUGHT;
-
- case ERT_CATCH:
- /* Catch regions are handled by their controlling try region. */
- return RNL_NOT_CAUGHT;
-
- case ERT_MUST_NOT_THROW:
- /* Here we end our search, since no exceptions may propagate.
-
- Local landing pads of ERT_MUST_NOT_THROW instructions are reachable
- only via locally handled RESX instructions.
-
- When we inline a function call, we can bring in new handlers. In order
- to avoid ERT_MUST_NOT_THROW landing pads from being deleted as unreachable
- assume that such handlers exists prior for any inlinable call prior
- inlining decisions are fixed. */
-
- if (maybe_resx)
- {
- add_reachable_handler (info, region, region);
- return RNL_CAUGHT;
- }
- else
- return RNL_BLOCKED;
-
- case ERT_THROW:
- case ERT_UNKNOWN:
- /* Shouldn't see these here. */
- gcc_unreachable ();
- break;
- default:
- gcc_unreachable ();
+ ret = !insn_could_throw_p (insn);
+ goto egress;
}
-}
-
-/* Invoke CALLBACK on each region reachable from REGION_NUMBER. */
-
-void
-foreach_reachable_handler (int region_number, bool is_resx, bool inlinable_call,
- void (*callback) (struct eh_region_d *, void *),
- void *callback_data)
-{
- struct reachable_info info;
- struct eh_region_d *region;
- tree type_thrown;
- memset (&info, 0, sizeof (info));
- info.callback = callback;
- info.callback_data = callback_data;
-
- region = VEC_index (eh_region, cfun->eh->region_array, region_number);
- if (!region)
- return;
-
- type_thrown = NULL_TREE;
- if (is_resx)
+ lp_nr = INTVAL (XEXP (note, 0));
+ if (lp_nr == 0 || lp_nr == INT_MIN)
{
- /* A RESX leaves a region instead of entering it. Thus the
- region itself may have been deleted out from under us. */
- if (region == NULL)
- return;
- region = region->outer;
- }
- else if (region->type == ERT_THROW)
- {
- type_thrown = region->u.eh_throw.type;
- region = region->outer;
+ ret = true;
+ goto egress;
}
- while (region)
+ if (lp_nr < 0)
+ r = VEC_index (eh_region, cfun->eh->region_array, -lp_nr);
+ else
{
- if (reachable_next_level (region, type_thrown, &info,
- inlinable_call || is_resx) >= RNL_CAUGHT)
- break;
- /* If we have processed one cleanup, there is no point in
- processing any more of them. Each cleanup will have an edge
- to the next outer cleanup region, so the flow graph will be
- accurate. */
- if (region->type == ERT_CLEANUP)
- {
- enum reachable_code code = RNL_NOT_CAUGHT;
- region = find_prev_try (region->outer);
- /* Continue looking for outer TRY region until we find one
- that might cath something. */
- while (region
- && (code = reachable_next_level (region, type_thrown, &info,
- inlinable_call || is_resx))
- == RNL_NOT_CAUGHT)
- region = find_prev_try (region->outer);
- if (code >= RNL_CAUGHT)
- break;
- }
- if (region)
- region = region->outer;
+ lp = VEC_index (eh_landing_pad, cfun->eh->lp_array, lp_nr);
+ r = lp->region;
}
+
+ egress:
+ *plp = lp;
+ *pr = r;
+ return ret;
}
-/* Retrieve a list of labels of exception handlers which can be
- reached by a given insn. */
+/* Return the landing pad to which INSN may go, or NULL if it does not
+ have a reachable landing pad within this function. */
-static void
-arh_to_landing_pad (struct eh_region_d *region, void *data)
+eh_landing_pad
+get_eh_landing_pad_from_rtx (const_rtx insn)
{
- rtx *p_handlers = (rtx *) data;
- if (! *p_handlers)
- *p_handlers = alloc_INSN_LIST (region->landing_pad, NULL_RTX);
-}
+ eh_landing_pad lp;
+ eh_region r;
-static void
-arh_to_label (struct eh_region_d *region, void *data)
-{
- rtx *p_handlers = (rtx *) data;
- *p_handlers = alloc_INSN_LIST (region->label, *p_handlers);
+ get_eh_region_and_lp_from_rtx (insn, &r, &lp);
+ return lp;
}
-rtx
-reachable_handlers (rtx insn)
-{
- bool is_resx = false;
- rtx handlers = NULL;
- int region_number;
-
- if (JUMP_P (insn)
- && GET_CODE (PATTERN (insn)) == RESX)
- {
- region_number = XINT (PATTERN (insn), 0);
- is_resx = true;
- }
- else
- {
- rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
- if (!note || INTVAL (XEXP (note, 0)) <= 0)
- return NULL;
- region_number = INTVAL (XEXP (note, 0));
- }
+/* Return the region to which INSN may go, or NULL if it does not
+ have a reachable region within this function. */
- foreach_reachable_handler (region_number, is_resx, false,
- (crtl->eh.built_landing_pads
- ? arh_to_landing_pad
- : arh_to_label),
- &handlers);
+eh_region
+get_eh_region_from_rtx (const_rtx insn)
+{
+ eh_landing_pad lp;
+ eh_region r;
- return handlers;
+ get_eh_region_and_lp_from_rtx (insn, &r, &lp);
+ return r;
}
-/* Determine if the given INSN can throw an exception that is caught
- within the function. */
+/* Return true if INSN throws and is caught by something in this function. */
bool
-can_throw_internal_1 (int region_number, bool is_resx, bool inlinable_call)
+can_throw_internal (const_rtx insn)
{
- struct eh_region_d *region;
- tree type_thrown;
-
- region = VEC_index (eh_region, cfun->eh->region_array, region_number);
- if (!region)
- return false;
-
- type_thrown = NULL_TREE;
- if (is_resx)
- region = region->outer;
- else if (region->type == ERT_THROW)
- {
- type_thrown = region->u.eh_throw.type;
- region = region->outer;
- }
-
- /* If this exception is ignored by each and every containing region,
- then control passes straight out. The runtime may handle some
- regions, which also do not require processing internally. */
- for (; region; region = region->outer)
- {
- enum reachable_code how = reachable_next_level (region, type_thrown, 0,
- inlinable_call || is_resx);
- if (how == RNL_BLOCKED)
- return false;
- if (how != RNL_NOT_CAUGHT)
- return true;
- }
-
- return false;
+ return get_eh_landing_pad_from_rtx (insn) != NULL;
}
+/* Return true if INSN throws and escapes from the current function. */
+
bool
-can_throw_internal (const_rtx insn)
+can_throw_external (const_rtx insn)
{
- rtx note;
+ eh_landing_pad lp;
+ eh_region r;
+ bool nothrow;
if (! INSN_P (insn))
return false;
- if (JUMP_P (insn)
- && GET_CODE (PATTERN (insn)) == RESX
- && XINT (PATTERN (insn), 0) > 0)
- return can_throw_internal_1 (XINT (PATTERN (insn), 0), true, false);
-
if (NONJUMP_INSN_P (insn)
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
- insn = XVECEXP (PATTERN (insn), 0, 0);
-
- /* Every insn that might throw has an EH_REGION note. */
- note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
- if (!note || INTVAL (XEXP (note, 0)) <= 0)
- return false;
+ {
+ rtx seq = PATTERN (insn);
+ int i, n = XVECLEN (seq, 0);
- return can_throw_internal_1 (INTVAL (XEXP (note, 0)), false, false);
-}
+ for (i = 0; i < n; i++)
+ if (can_throw_external (XVECEXP (seq, 0, i)))
+ return true;
-/* Determine if the given INSN can throw an exception that is
- visible outside the function. */
+ return false;
+ }
-bool
-can_throw_external_1 (int region_number, bool is_resx, bool inlinable_call)
-{
- struct eh_region_d *region;
- tree type_thrown;
+ nothrow = get_eh_region_and_lp_from_rtx (insn, &r, &lp);
- region = VEC_index (eh_region, cfun->eh->region_array, region_number);
- if (!region)
- return true;
+ /* If we can't throw, we obviously can't throw external. */
+ if (nothrow)
+ return false;
- type_thrown = NULL_TREE;
- if (is_resx)
- region = region->outer;
- else if (region->type == ERT_THROW)
- {
- type_thrown = region->u.eh_throw.type;
- region = region->outer;
- }
+ /* If we have an internal landing pad, then we're not external. */
+ if (lp != NULL)
+ return false;
- /* If the exception is caught or blocked by any containing region,
- then it is not seen by any calling function. */
- for (; region ; region = region->outer)
- if (reachable_next_level (region, type_thrown, NULL,
- inlinable_call || is_resx) >= RNL_CAUGHT)
- return false;
+ /* If we're not within an EH region, then we are external. */
+ if (r == NULL)
+ return true;
- return true;
+ /* The only thing that ought to be left is MUST_NOT_THROW regions,
+ which don't always have landing pads. */
+ gcc_assert (r->type == ERT_MUST_NOT_THROW);
+ return false;
}
+/* Return true if INSN cannot throw at all. */
+
bool
-can_throw_external (const_rtx insn)
+insn_nothrow_p (const_rtx insn)
{
- rtx note;
+ eh_landing_pad lp;
+ eh_region r;
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, false);
+ return true;
if (NONJUMP_INSN_P (insn)
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
@@ -3345,30 +1799,30 @@ can_throw_external (const_rtx insn)
int i, n = XVECLEN (seq, 0);
for (i = 0; i < n; i++)
- if (can_throw_external (XVECEXP (seq, 0, i)))
- return true;
+ if (!insn_nothrow_p (XVECEXP (seq, 0, i)))
+ return false;
- return false;
+ return true;
}
- note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
- if (!note)
+ return get_eh_region_and_lp_from_rtx (insn, &r, &lp);
+}
+
+/* Return true if INSN can perform a non-local goto. */
+/* ??? This test is here in this file because it (ab)uses REG_EH_REGION. */
+
+bool
+can_nonlocal_goto (const_rtx insn)
+{
+ if (nonlocal_goto_handler_labels && CALL_P (insn))
{
- /* Calls (and trapping insns) without notes are outside any
- exception handling region in this function. We have to
- assume it might throw. Given that the front end and middle
- ends mark known NOTHROW functions, this isn't so wildly
- inaccurate. */
- return (CALL_P (insn)
- || (flag_non_call_exceptions
- && may_trap_p (PATTERN (insn))));
+ rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+ if (!note || INTVAL (XEXP (note, 0)) != INT_MIN)
+ return true;
}
- if (INTVAL (XEXP (note, 0)) <= 0)
- return false;
-
- return can_throw_external_1 (INTVAL (XEXP (note, 0)), false, false);
+ return false;
}
-
+
/* Set TREE_NOTHROW and crtl->all_throwers_are_sibcalls. */
unsigned int
@@ -3459,6 +1913,79 @@ struct rtl_opt_pass pass_set_nothrow_function_flags =
/* Various hooks for unwind library. */
+/* Expand the EH support builtin functions:
+ __builtin_eh_pointer and __builtin_eh_filter. */
+
+static eh_region
+expand_builtin_eh_common (tree region_nr_t)
+{
+ HOST_WIDE_INT region_nr;
+ eh_region region;
+
+ gcc_assert (host_integerp (region_nr_t, 0));
+ region_nr = tree_low_cst (region_nr_t, 0);
+
+ region = VEC_index (eh_region, cfun->eh->region_array, region_nr);
+
+ /* ??? We shouldn't have been able to delete a eh region without
+ deleting all the code that depended on it. */
+ gcc_assert (region != NULL);
+
+ return region;
+}
+
+/* Expand to the exc_ptr value from the given eh region. */
+
+rtx
+expand_builtin_eh_pointer (tree exp)
+{
+ eh_region region
+ = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
+ if (region->exc_ptr_reg == NULL)
+ region->exc_ptr_reg = gen_reg_rtx (ptr_mode);
+ return region->exc_ptr_reg;
+}
+
+/* Expand to the filter value from the given eh region. */
+
+rtx
+expand_builtin_eh_filter (tree exp)
+{
+ eh_region region
+ = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
+ if (region->filter_reg == NULL)
+ region->filter_reg = gen_reg_rtx (targetm.eh_return_filter_mode ());
+ return region->filter_reg;
+}
+
+/* Copy the exc_ptr and filter values from one landing pad's registers
+ to another. This is used to inline the resx statement. */
+
+rtx
+expand_builtin_eh_copy_values (tree exp)
+{
+ eh_region dst
+ = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
+ eh_region src
+ = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 1));
+ enum machine_mode fmode = targetm.eh_return_filter_mode ();
+
+ if (dst->exc_ptr_reg == NULL)
+ dst->exc_ptr_reg = gen_reg_rtx (ptr_mode);
+ if (src->exc_ptr_reg == NULL)
+ src->exc_ptr_reg = gen_reg_rtx (ptr_mode);
+
+ if (dst->filter_reg == NULL)
+ dst->filter_reg = gen_reg_rtx (fmode);
+ if (src->filter_reg == NULL)
+ src->filter_reg = gen_reg_rtx (fmode);
+
+ emit_move_insn (dst->exc_ptr_reg, src->exc_ptr_reg);
+ emit_move_insn (dst->filter_reg, src->filter_reg);
+
+ return const0_rtx;
+}
+
/* Do any necessary initialization to access arbitrary stack frames.
On the SPARC, this means flushing the register windows. */
@@ -3474,6 +2001,10 @@ expand_builtin_unwind_init (void)
#endif
}
+/* Map a non-negative number to an eh return data register number; expands
+ to -1 if no return data register is associated with the input number.
+ At least the inputs 0 and 1 must be mapped; the target may provide more. */
+
rtx
expand_builtin_eh_return_data_regno (tree exp)
{
@@ -3582,6 +2113,10 @@ expand_builtin_eh_return (tree stackadj_tree ATTRIBUTE_UNUSED,
emit_jump (crtl->eh.ehr_label);
}
+/* Expand __builtin_eh_return. This exit path from the function loads up
+ the eh return data registers, adjusts the stack, and branches to a
+ given PC other than the normal return address. */
+
void
expand_eh_return (void)
{
@@ -3687,7 +2222,7 @@ add_action_record (htab_t ar_hash, int filter, int next)
if ((new_ar = *slot) == NULL)
{
new_ar = XNEW (struct action_record);
- new_ar->offset = VARRAY_ACTIVE_SIZE (crtl->eh.action_record_data) + 1;
+ new_ar->offset = VEC_length (uchar, crtl->eh.action_record_data) + 1;
new_ar->filter = filter;
new_ar->next = next;
*slot = new_ar;
@@ -3699,7 +2234,7 @@ add_action_record (htab_t ar_hash, int filter, int next)
push_sleb128 (&crtl->eh.action_record_data, filter);
if (next)
- next -= VARRAY_ACTIVE_SIZE (crtl->eh.action_record_data) + 1;
+ next -= VEC_length (uchar, crtl->eh.action_record_data) + 1;
push_sleb128 (&crtl->eh.action_record_data, next);
}
@@ -3707,9 +2242,8 @@ add_action_record (htab_t ar_hash, int filter, int next)
}
static int
-collect_one_action_chain (htab_t ar_hash, struct eh_region_d *region)
+collect_one_action_chain (htab_t ar_hash, eh_region region)
{
- struct eh_region_d *c;
int next;
/* If we've reached the top of the region chain, then we have
@@ -3720,67 +2254,72 @@ collect_one_action_chain (htab_t ar_hash, struct eh_region_d *region)
switch (region->type)
{
case ERT_CLEANUP:
- /* A cleanup adds a zero filter to the beginning of the chain, but
- there are special cases to look out for. If there are *only*
- cleanups along a path, then it compresses to a zero action.
- Further, if there are multiple cleanups along a path, we only
- need to represent one of them, as that is enough to trigger
- entry to the landing pad at runtime. */
- next = collect_one_action_chain (ar_hash, region->outer);
- if (next <= 0)
- return 0;
- for (c = region->outer; c ; c = c->outer)
- if (c->type == ERT_CLEANUP)
- return next;
- return add_action_record (ar_hash, 0, next);
+ {
+ eh_region r;
+ /* A cleanup adds a zero filter to the beginning of the chain, but
+ there are special cases to look out for. If there are *only*
+ cleanups along a path, then it compresses to a zero action.
+ Further, if there are multiple cleanups along a path, we only
+ need to represent one of them, as that is enough to trigger
+ entry to the landing pad at runtime. */
+ next = collect_one_action_chain (ar_hash, region->outer);
+ if (next <= 0)
+ return 0;
+ for (r = region->outer; r ; r = r->outer)
+ if (r->type == ERT_CLEANUP)
+ return next;
+ return add_action_record (ar_hash, 0, next);
+ }
case ERT_TRY:
- /* Process the associated catch regions in reverse order.
- If there's a catch-all handler, then we don't need to
- search outer regions. Use a magic -3 value to record
- that we haven't done the outer search. */
- next = -3;
- for (c = region->u.eh_try.last_catch; c ; c = c->u.eh_catch.prev_catch)
- {
- if (c->u.eh_catch.type_list == NULL)
- {
- /* Retrieve the filter from the head of the filter list
- where we have stored it (see assign_filter_values). */
- int filter
- = TREE_INT_CST_LOW (TREE_VALUE (c->u.eh_catch.filter_list));
-
- next = add_action_record (ar_hash, filter, 0);
- }
- else
- {
- /* Once the outer search is done, trigger an action record for
- each filter we have. */
- tree flt_node;
+ {
+ eh_catch c;
+
+ /* Process the associated catch regions in reverse order.
+ If there's a catch-all handler, then we don't need to
+ search outer regions. Use a magic -3 value to record
+ that we haven't done the outer search. */
+ next = -3;
+ for (c = region->u.eh_try.last_catch; c ; c = c->prev_catch)
+ {
+ if (c->type_list == NULL)
+ {
+ /* Retrieve the filter from the head of the filter list
+ where we have stored it (see assign_filter_values). */
+ int filter = TREE_INT_CST_LOW (TREE_VALUE (c->filter_list));
+ next = add_action_record (ar_hash, filter, 0);
+ }
+ else
+ {
+ /* Once the outer search is done, trigger an action record for
+ each filter we have. */
+ tree flt_node;
- if (next == -3)
- {
- next = collect_one_action_chain (ar_hash, region->outer);
-
- /* If there is no next action, terminate the chain. */
- if (next == -1)
- next = 0;
- /* If all outer actions are cleanups or must_not_throw,
- we'll have no action record for it, since we had wanted
- to encode these states in the call-site record directly.
- Add a cleanup action to the chain to catch these. */
- else if (next <= 0)
- next = add_action_record (ar_hash, 0, 0);
- }
+ if (next == -3)
+ {
+ next = collect_one_action_chain (ar_hash, region->outer);
+
+ /* If there is no next action, terminate the chain. */
+ if (next == -1)
+ next = 0;
+ /* If all outer actions are cleanups or must_not_throw,
+ we'll have no action record for it, since we had wanted
+ to encode these states in the call-site record directly.
+ Add a cleanup action to the chain to catch these. */
+ else if (next <= 0)
+ next = add_action_record (ar_hash, 0, 0);
+ }
- flt_node = c->u.eh_catch.filter_list;
- for (; flt_node; flt_node = TREE_CHAIN (flt_node))
- {
- int filter = TREE_INT_CST_LOW (TREE_VALUE (flt_node));
- next = add_action_record (ar_hash, filter, next);
- }
- }
- }
- return next;
+ flt_node = c->filter_list;
+ for (; flt_node; flt_node = TREE_CHAIN (flt_node))
+ {
+ int filter = TREE_INT_CST_LOW (TREE_VALUE (flt_node));
+ next = add_action_record (ar_hash, filter, next);
+ }
+ }
+ }
+ return next;
+ }
case ERT_ALLOWED_EXCEPTIONS:
/* An exception specification adds its filter to the
@@ -3805,23 +2344,16 @@ collect_one_action_chain (htab_t ar_hash, struct eh_region_d *region)
the no handler or cleanup case in that we do require an lsda
to be generated. Return a magic -2 value to record this. */
return -2;
-
- case ERT_CATCH:
- case ERT_THROW:
- /* CATCH regions are handled in TRY above. THROW regions are
- for optimization information only and produce no output. */
- return collect_one_action_chain (ar_hash, region->outer);
-
- default:
- gcc_unreachable ();
}
+
+ gcc_unreachable ();
}
static int
add_call_site (rtx landing_pad, int action, int section)
{
call_site_record record;
-
+
record = GGC_NEW (struct call_site_record_d);
record->landing_pad = landing_pad;
record->action = action;
@@ -3837,7 +2369,7 @@ add_call_site (rtx landing_pad, int action, int section)
The new note numbers will not refer to region numbers, but
instead to call site entries. */
-unsigned int
+static unsigned int
convert_to_eh_region_ranges (void)
{
rtx insn, iter, note;
@@ -3856,17 +2388,16 @@ convert_to_eh_region_ranges (void)
int min_labelno = 0, max_labelno = 0;
int saved_call_site_base = call_site_base;
- if (USING_SJLJ_EXCEPTIONS || cfun->eh->region_tree == NULL)
- return 0;
-
- VARRAY_UCHAR_INIT (crtl->eh.action_record_data, 64, "action_record_data");
+ crtl->eh.action_record_data = VEC_alloc (uchar, gc, 64);
ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
if (INSN_P (iter))
{
- struct eh_region_d *region;
+ eh_landing_pad lp;
+ eh_region region;
+ bool nothrow;
int this_action;
rtx this_landing_pad;
@@ -3875,23 +2406,13 @@ convert_to_eh_region_ranges (void)
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
insn = XVECEXP (PATTERN (insn), 0, 0);
- note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
- if (!note)
- {
- if (! (CALL_P (insn)
- || (flag_non_call_exceptions
- && may_trap_p (PATTERN (insn)))))
- continue;
- this_action = -1;
- region = NULL;
- }
+ nothrow = get_eh_region_and_lp_from_rtx (insn, &region, &lp);
+ if (nothrow)
+ continue;
+ if (region)
+ this_action = collect_one_action_chain (ar_hash, region);
else
- {
- if (INTVAL (XEXP (note, 0)) <= 0)
- continue;
- region = VEC_index (eh_region, cfun->eh->region_array, INTVAL (XEXP (note, 0)));
- this_action = collect_one_action_chain (ar_hash, region);
- }
+ this_action = -1;
/* Existence of catch handlers, or must-not-throw regions
implies that an lsda is needed (even if empty). */
@@ -3906,15 +2427,8 @@ convert_to_eh_region_ranges (void)
last_action = -1;
}
- /* Cleanups and handlers may share action chains but not
- landing pads. Collect the landing pad for this region. */
if (this_action >= 0)
- {
- struct eh_region_d *o;
- for (o = region; ! o->landing_pad ; o = o->outer)
- continue;
- this_landing_pad = o->landing_pad;
- }
+ this_landing_pad = lp->landing_pad;
else
this_landing_pad = NULL_RTX;
@@ -4118,12 +2632,19 @@ convert_to_eh_region_ranges (void)
return 0;
}
+static bool
+gate_convert_to_eh_region_ranges (void)
+{
+ /* Nothing to do for SJLJ exceptions or if no regions created. */
+ return !(USING_SJLJ_EXCEPTIONS || cfun->eh->region_tree == NULL);
+}
+
struct rtl_opt_pass pass_convert_to_eh_region_ranges =
{
{
RTL_PASS,
"eh_ranges", /* name */
- NULL, /* gate */
+ gate_convert_to_eh_region_ranges, /* gate */
convert_to_eh_region_ranges, /* execute */
NULL, /* sub */
NULL, /* next */
@@ -4136,10 +2657,9 @@ struct rtl_opt_pass pass_convert_to_eh_region_ranges =
TODO_dump_func, /* todo_flags_finish */
}
};
-
static void
-push_uleb128 (varray_type *data_area, unsigned int value)
+push_uleb128 (VEC (uchar, gc) **data_area, unsigned int value)
{
do
{
@@ -4147,13 +2667,13 @@ push_uleb128 (varray_type *data_area, unsigned int value)
value >>= 7;
if (value)
byte |= 0x80;
- VARRAY_PUSH_UCHAR (*data_area, byte);
+ VEC_safe_push (uchar, gc, *data_area, byte);
}
while (value);
}
static void
-push_sleb128 (varray_type *data_area, int value)
+push_sleb128 (VEC (uchar, gc) **data_area, int value)
{
unsigned char byte;
int more;
@@ -4166,7 +2686,7 @@ push_sleb128 (varray_type *data_area, int value)
|| (value == -1 && (byte & 0x40) != 0));
if (more)
byte |= 0x80;
- VARRAY_PUSH_UCHAR (*data_area, byte);
+ VEC_safe_push (uchar, gc, *data_area, byte);
}
while (more);
}
@@ -4394,9 +2914,9 @@ output_ttype (tree type, int tt_format, int tt_format_size)
static void
output_one_function_exception_table (const char * ARG_UNUSED (fnname),
- int section)
+ int section, rtx ARG_UNUSED (personality))
{
- int tt_format, cs_format, lp_format, i, n;
+ int tt_format, cs_format, lp_format, i;
#ifdef HAVE_AS_LEB128
char ttype_label[32];
char cs_after_size_label[32];
@@ -4410,7 +2930,7 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname),
#ifdef TARGET_UNWIND_INFO
/* TODO: Move this into target file. */
fputs ("\t.personality\t", asm_out_file);
- output_addr_const (asm_out_file, eh_personality_libfunc);
+ output_addr_const (asm_out_file, personality);
fputs ("\n\t.handlerdata\n", asm_out_file);
/* Note that varasm still thinks we're in the function's code section.
The ".endp" directive that will immediately follow will take us back. */
@@ -4421,8 +2941,10 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname),
/* If the target wants a label to begin the table, emit it here. */
targetm.asm_out.except_table_label (asm_out_file);
- have_tt_data = (VEC_length (tree, crtl->eh.ttype_data) > 0
- || VARRAY_ACTIVE_SIZE (crtl->eh.ehspec_data) > 0);
+ have_tt_data = (VEC_length (tree, cfun->eh->ttype_data)
+ || (targetm.arm_eabi_unwinder
+ ? VEC_length (tree, cfun->eh->ehspec_data.arm_eabi)
+ : VEC_length (uchar, cfun->eh->ehspec_data.other)));
/* Indicate the format of the @TType entries. */
if (! have_tt_data)
@@ -4485,8 +3007,8 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname),
before_disp = 1 + 1;
after_disp = (1 + size_of_uleb128 (call_site_len)
+ call_site_len
- + VARRAY_ACTIVE_SIZE (crtl->eh.action_record_data)
- + (VEC_length (tree, crtl->eh.ttype_data)
+ + VEC_length (uchar, crtl->eh.action_record_data)
+ + (VEC_length (tree, cfun->eh->ttype_data)
* tt_format_size));
disp = after_disp;
@@ -4542,18 +3064,19 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname),
#endif
/* ??? Decode and interpret the data for flag_debug_asm. */
- n = VARRAY_ACTIVE_SIZE (crtl->eh.action_record_data);
- for (i = 0; i < n; ++i)
- dw2_asm_output_data (1, VARRAY_UCHAR (crtl->eh.action_record_data, i),
- (i ? NULL : "Action record table"));
+ {
+ uchar uc;
+ for (i = 0; VEC_iterate (uchar, crtl->eh.action_record_data, i, uc); ++i)
+ dw2_asm_output_data (1, uc, i ? NULL : "Action record table");
+ }
if (have_tt_data)
assemble_align (tt_format_size * BITS_PER_UNIT);
- i = VEC_length (tree, crtl->eh.ttype_data);
+ i = VEC_length (tree, cfun->eh->ttype_data);
while (i-- > 0)
{
- tree type = VEC_index (tree, crtl->eh.ttype_data, i);
+ tree type = VEC_index (tree, cfun->eh->ttype_data, i);
output_ttype (type, tt_format, tt_format_size);
}
@@ -4563,33 +3086,38 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname),
#endif
/* ??? Decode and interpret the data for flag_debug_asm. */
- n = VARRAY_ACTIVE_SIZE (crtl->eh.ehspec_data);
- for (i = 0; i < n; ++i)
+ if (targetm.arm_eabi_unwinder)
{
- if (targetm.arm_eabi_unwinder)
- {
- tree type = VARRAY_TREE (crtl->eh.ehspec_data, i);
- output_ttype (type, tt_format, tt_format_size);
- }
- else
- dw2_asm_output_data (1, VARRAY_UCHAR (crtl->eh.ehspec_data, i),
- (i ? NULL : "Exception specification table"));
+ tree type;
+ for (i = 0;
+ VEC_iterate (tree, cfun->eh->ehspec_data.arm_eabi, i, type); ++i)
+ output_ttype (type, tt_format, tt_format_size);
+ }
+ else
+ {
+ uchar uc;
+ for (i = 0;
+ VEC_iterate (uchar, cfun->eh->ehspec_data.other, i, uc); ++i)
+ dw2_asm_output_data (1, uc,
+ i ? NULL : "Exception specification table");
}
}
void
output_function_exception_table (const char * ARG_UNUSED (fnname))
{
+ rtx personality = get_personality_function (current_function_decl);
+
/* Not all functions need anything. */
if (! crtl->uses_eh_lsda)
return;
- if (eh_personality_libfunc)
- assemble_external_libcall (eh_personality_libfunc);
+ if (personality)
+ assemble_external_libcall (personality);
- output_one_function_exception_table (fnname, 0);
+ output_one_function_exception_table (fnname, 0, personality);
if (crtl->eh.call_site_record[1] != NULL)
- output_one_function_exception_table (fnname, 1);
+ output_one_function_exception_table (fnname, 1, personality);
switch_to_section (current_function_section ());
}
@@ -4605,18 +3133,50 @@ get_eh_throw_stmt_table (struct function *fun)
{
return fun->eh->throw_stmt_table;
}
+
+/* Determine if the function needs an EH personality function. */
+
+enum eh_personality_kind
+function_needs_eh_personality (struct function *fn)
+{
+ enum eh_personality_kind kind = eh_personality_none;
+ eh_region i;
+
+ FOR_ALL_EH_REGION_FN (i, fn)
+ {
+ switch (i->type)
+ {
+ case ERT_CLEANUP:
+ /* Can do with any personality including the generic C one. */
+ kind = eh_personality_any;
+ break;
+ case ERT_TRY:
+ case ERT_ALLOWED_EXCEPTIONS:
+ /* Always needs a EH personality function. The generic C
+ personality doesn't handle these even for empty type lists. */
+ return eh_personality_lang;
+
+ case ERT_MUST_NOT_THROW:
+ /* Always needs a EH personality function. The language may specify
+ what abort routine that must be used, e.g. std::terminate. */
+ return eh_personality_lang;
+ }
+ }
+
+ return kind;
+}
+
/* Dump EH information to OUT. */
void
dump_eh_tree (FILE * out, struct function *fun)
{
- struct eh_region_d *i;
+ eh_region i;
int depth = 0;
- static const char *const type_name[] = { "unknown", "cleanup", "try", "catch",
- "allowed_exceptions", "must_not_throw",
- "throw"
- };
+ static const char *const type_name[] = {
+ "cleanup", "try", "allowed_exceptions", "must_not_throw"
+ };
i = fun->eh->region_tree;
if (!i)
@@ -4626,91 +3186,82 @@ dump_eh_tree (FILE * out, struct function *fun)
while (1)
{
fprintf (out, " %*s %i %s", depth * 2, "",
- i->region_number, type_name[(int) i->type]);
- if (i->tree_label)
- {
- fprintf (out, " tree_label:");
- print_generic_expr (out, i->tree_label, 0);
- }
- if (i->label)
- fprintf (out, " label:%i", INSN_UID (i->label));
- if (i->landing_pad)
- {
- fprintf (out, " landing_pad:%i", INSN_UID (i->landing_pad));
- if (NOTE_P (i->landing_pad))
- fprintf (out, " (deleted)");
- }
- if (i->post_landing_pad)
- {
- fprintf (out, " post_landing_pad:%i", INSN_UID (i->post_landing_pad));
- if (NOTE_P (i->post_landing_pad))
- fprintf (out, " (deleted)");
- }
- if (i->resume)
+ i->index, type_name[(int) i->type]);
+
+ if (i->landing_pads)
{
- rtx resume_list = i->resume;
- fprintf (out, " resume:");
- while (GET_CODE (resume_list) == INSN_LIST)
+ eh_landing_pad lp;
+
+ fprintf (out, " land:");
+ if (current_ir_type () == IR_GIMPLE)
{
- fprintf (out, "%i,", INSN_UID (XEXP (resume_list, 0)));
- if (NOTE_P (XEXP (resume_list, 0)))
- fprintf (out, " (deleted)");
- resume_list = XEXP (resume_list, 1);
+ for (lp = i->landing_pads; lp ; lp = lp->next_lp)
+ {
+ fprintf (out, "{%i,", lp->index);
+ print_generic_expr (out, lp->post_landing_pad, 0);
+ fputc ('}', out);
+ if (lp->next_lp)
+ fputc (',', out);
+ }
+ }
+ else
+ {
+ for (lp = i->landing_pads; lp ; lp = lp->next_lp);
+ {
+ fprintf (out, "{%i,", lp->index);
+ if (lp->landing_pad)
+ fprintf (out, "%i%s,", INSN_UID (lp->landing_pad),
+ NOTE_P (lp->landing_pad) ? "(del)" : "");
+ else
+ fprintf (out, "(nil),");
+ if (lp->post_landing_pad)
+ {
+ rtx lab = label_rtx (lp->post_landing_pad);
+ fprintf (out, "%i%s}", INSN_UID (lab),
+ NOTE_P (lab) ? "(del)" : "");
+ }
+ else
+ fprintf (out, "(nil)}");
+ if (lp->next_lp)
+ fputc (',', out);
+ }
}
- fprintf (out, " resume:%i", INSN_UID (i->resume));
- if (NOTE_P (i->resume))
- fprintf (out, " (deleted)");
}
- if (i->may_contain_throw)
- fprintf (out, " may_contain_throw");
+
switch (i->type)
{
case ERT_CLEANUP:
+ case ERT_MUST_NOT_THROW:
break;
case ERT_TRY:
{
- struct eh_region_d *c;
- fprintf (out, " catch regions:");
- for (c = i->u.eh_try.eh_catch; c; c = c->u.eh_catch.next_catch)
- fprintf (out, " %i", c->region_number);
+ eh_catch c;
+ fprintf (out, " catch:");
+ for (c = i->u.eh_try.first_catch; c; c = c->next_catch)
+ {
+ fputc ('{', out);
+ if (c->label)
+ {
+ fprintf (out, "lab:");
+ print_generic_expr (out, c->label, 0);
+ fputc (';', out);
+ }
+ print_generic_expr (out, c->type_list, 0);
+ fputc ('}', out);
+ if (c->next_catch)
+ fputc (',', out);
+ }
}
break;
- case ERT_CATCH:
- if (i->u.eh_catch.prev_catch)
- fprintf (out, " prev: %i",
- i->u.eh_catch.prev_catch->region_number);
- if (i->u.eh_catch.next_catch)
- fprintf (out, " next %i",
- i->u.eh_catch.next_catch->region_number);
- fprintf (out, " type:");
- print_generic_expr (out, i->u.eh_catch.type_list, 0);
- break;
-
case ERT_ALLOWED_EXCEPTIONS:
fprintf (out, " filter :%i types:", i->u.allowed.filter);
print_generic_expr (out, i->u.allowed.type_list, 0);
break;
-
- case ERT_THROW:
- fprintf (out, " type:");
- print_generic_expr (out, i->u.eh_throw.type, 0);
- break;
-
- case ERT_MUST_NOT_THROW:
- break;
-
- case ERT_UNKNOWN:
- break;
- }
- if (i->aka)
- {
- fprintf (out, " also known as:");
- dump_bitmap (out, i->aka);
}
- else
- fprintf (out, "\n");
+ fputc ('\n', out);
+
/* If there are sub-regions, process them. */
if (i->inner)
i = i->inner, depth++;
@@ -4741,217 +3292,123 @@ debug_eh_tree (struct function *fn)
dump_eh_tree (stderr, fn);
}
-
-/* Verify EH region invariants. */
-
-static bool
-verify_eh_region (struct eh_region_d *region)
-{
- bool found = false;
- if (!region)
- return false;
- switch (region->type)
- {
- case ERT_TRY:
- {
- struct eh_region_d *c, *prev = NULL;
- if (region->u.eh_try.eh_catch->u.eh_catch.prev_catch)
- {
- error ("Try region %i has wrong rh_catch pointer to %i",
- region->region_number,
- region->u.eh_try.eh_catch->region_number);
- found = true;
- }
- for (c = region->u.eh_try.eh_catch; c; c = c->u.eh_catch.next_catch)
- {
- if (c->outer != region->outer)
- {
- error
- ("Catch region %i has different outer region than try region %i",
- c->region_number, region->region_number);
- found = true;
- }
- if (c->u.eh_catch.prev_catch != prev)
- {
- error ("Catch region %i has corrupted catchlist",
- c->region_number);
- found = true;
- }
- prev = c;
- }
- if (prev != region->u.eh_try.last_catch)
- {
- error
- ("Try region %i has wrong last_catch pointer to %i instead of %i",
- region->region_number,
- region->u.eh_try.last_catch->region_number,
- prev->region_number);
- found = true;
- }
- }
- break;
- case ERT_CATCH:
- if (!region->u.eh_catch.prev_catch
- && (!region->next_peer || region->next_peer->type != ERT_TRY))
- {
- error ("Catch region %i should be followed by try", region->region_number);
- found = true;
- }
- break;
- case ERT_CLEANUP:
- case ERT_ALLOWED_EXCEPTIONS:
- case ERT_MUST_NOT_THROW:
- case ERT_THROW:
- break;
- case ERT_UNKNOWN:
- gcc_unreachable ();
- }
- for (region = region->inner; region; region = region->next_peer)
- found |= verify_eh_region (region);
- return found;
-}
-
/* Verify invariants on EH datastructures. */
void
verify_eh_tree (struct function *fun)
{
- struct eh_region_d *i, *outer = NULL;
+ eh_region r, outer;
+ int nvisited_lp, nvisited_r;
+ int count_lp, count_r, depth, i;
+ eh_landing_pad lp;
bool err = false;
- int nvisited = 0;
- int count = 0;
- int j;
- int depth = 0;
if (!fun->eh->region_tree)
return;
- for (j = fun->eh->last_region_number; j > 0; --j)
- if ((i = VEC_index (eh_region, fun->eh->region_array, j)))
+
+ count_r = 0;
+ for (i = 1; VEC_iterate (eh_region, fun->eh->region_array, i, r); ++i)
+ if (r)
{
- if (i->region_number == j)
- count++;
- if (i->region_number != j && (!i->aka || !bitmap_bit_p (i->aka, j)))
+ if (r->index == i)
+ count_r++;
+ else
{
- error ("region_array is corrupted for region %i",
- i->region_number);
+ error ("region_array is corrupted for region %i", r->index);
err = true;
}
}
- i = fun->eh->region_tree;
+ count_lp = 0;
+ for (i = 1; VEC_iterate (eh_landing_pad, fun->eh->lp_array, i, lp); ++i)
+ if (lp)
+ {
+ if (lp->index == i)
+ count_lp++;
+ else
+ {
+ error ("lp_array is corrupted for lp %i", lp->index);
+ err = true;
+ }
+ }
+
+ depth = nvisited_lp = nvisited_r = 0;
+ outer = NULL;
+ r = fun->eh->region_tree;
while (1)
{
- if (VEC_index (eh_region, fun->eh->region_array, i->region_number) != i)
+ if (VEC_index (eh_region, fun->eh->region_array, r->index) != r)
{
- error ("region_array is corrupted for region %i", i->region_number);
+ error ("region_array is corrupted for region %i", r->index);
err = true;
}
- if (i->outer != outer)
+ if (r->outer != outer)
{
- error ("outer block of region %i is wrong", i->region_number);
+ error ("outer block of region %i is wrong", r->index);
err = true;
}
- if (i->may_contain_throw && outer && !outer->may_contain_throw)
+ if (depth < 0)
{
- error
- ("region %i may contain throw and is contained in region that may not",
- i->region_number);
+ error ("negative nesting depth of region %i", r->index);
err = true;
}
- if (depth < 0)
+ nvisited_r++;
+
+ for (lp = r->landing_pads; lp ; lp = lp->next_lp)
{
- error ("negative nesting depth of region %i", i->region_number);
- err = true;
+ if (VEC_index (eh_landing_pad, fun->eh->lp_array, lp->index) != lp)
+ {
+ error ("lp_array is corrupted for lp %i", lp->index);
+ err = true;
+ }
+ if (lp->region != r)
+ {
+ error ("region of lp %i is wrong", lp->index);
+ err = true;
+ }
+ nvisited_lp++;
}
- nvisited++;
- /* If there are sub-regions, process them. */
- if (i->inner)
- outer = i, i = i->inner, depth++;
- /* If there are peers, process them. */
- else if (i->next_peer)
- i = i->next_peer;
- /* Otherwise, step back up the tree to the next peer. */
+
+ if (r->inner)
+ outer = r, r = r->inner, depth++;
+ else if (r->next_peer)
+ r = r->next_peer;
else
{
do
{
- i = i->outer;
+ r = r->outer;
+ if (r == NULL)
+ goto region_done;
depth--;
- if (i == NULL)
- {
- if (depth != -1)
- {
- error ("tree list ends on depth %i", depth + 1);
- err = true;
- }
- if (count != nvisited)
- {
- error ("array does not match the region tree");
- err = true;
- }
- if (!err)
- for (i = fun->eh->region_tree; i; i = i->next_peer)
- err |= verify_eh_region (i);
-
- if (err)
- {
- dump_eh_tree (stderr, fun);
- internal_error ("verify_eh_tree failed");
- }
- return;
- }
- outer = i->outer;
+ outer = r->outer;
}
- while (i->next_peer == NULL);
- i = i->next_peer;
+ while (r->next_peer == NULL);
+ r = r->next_peer;
}
}
-}
-
-/* Initialize unwind_resume_libfunc. */
+ region_done:
+ if (depth != 0)
+ {
+ error ("tree list ends on depth %i", depth);
+ err = true;
+ }
+ if (count_r != nvisited_r)
+ {
+ error ("region_array does not match region_tree");
+ err = true;
+ }
+ if (count_lp != nvisited_lp)
+ {
+ error ("lp_array does not match region_tree");
+ err = true;
+ }
-void
-default_init_unwind_resume_libfunc (void)
-{
- /* The default c++ routines aren't actually c++ specific, so use those. */
- unwind_resume_libfunc =
- init_one_libfunc ( USING_SJLJ_EXCEPTIONS ? "_Unwind_SjLj_Resume"
- : "_Unwind_Resume");
+ if (err)
+ {
+ dump_eh_tree (stderr, fun);
+ internal_error ("verify_eh_tree failed");
+ }
}
-
-static bool
-gate_handle_eh (void)
-{
- return doing_eh (0);
-}
-
-/* Complete generation of exception handling code. */
-static unsigned int
-rest_of_handle_eh (void)
-{
- finish_eh_generation ();
- cleanup_cfg (CLEANUP_NO_INSN_DEL);
- return 0;
-}
-
-struct rtl_opt_pass pass_rtl_eh =
-{
- {
- RTL_PASS,
- "eh", /* name */
- gate_handle_eh, /* gate */
- rest_of_handle_eh, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_JUMP, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_dump_func /* todo_flags_finish */
- }
-};
-
#include "gt-except.h"
diff --git a/gcc/except.h b/gcc/except.h
index f332b2b1bb7..3e9a39cbb5f 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -23,20 +23,96 @@ along with GCC; see the file COPYING3. If not see
#include "vecprim.h"
struct function;
+struct eh_region_d;
+struct pointer_map_t;
/* The type of an exception region. */
enum eh_region_type
{
- ERT_UNKNOWN = 0,
+ /* CLEANUP regions implement e.g. destructors run when exiting a block.
+ They can be generated from both GIMPLE_TRY_FINALLY and GIMPLE_TRY_CATCH
+ nodes. It is expected by the runtime that cleanup regions will *not*
+ resume normal program flow, but will continue propagation of the
+ exception. */
ERT_CLEANUP,
+
+ /* TRY regions implement catching an exception. The list of types associated
+ with the attached catch handlers is examined in order by the runtime and
+ control is transfered to the appropriate handler. Note that a NULL type
+ list is a catch-all handler, and that it will catch *all* exceptions
+ including those originating from a different language. */
ERT_TRY,
- ERT_CATCH,
+
+ /* ALLOWED_EXCEPTIONS regions implement exception filtering, e.g. the
+ throw(type-list) specification that can be added to C++ functions.
+ The runtime examines the thrown exception vs the type list, and if
+ the exception does not match, transfers control to the handler. The
+ normal handler for C++ calls __cxa_call_unexpected. */
ERT_ALLOWED_EXCEPTIONS,
- ERT_MUST_NOT_THROW,
- ERT_THROW
+
+ /* MUST_NOT_THROW regions prevent all exceptions from propagating. This
+ region type is used in C++ to surround destructors being run inside a
+ CLEANUP region. This differs from an ALLOWED_EXCEPTIONS region with
+ an empty type list in that the runtime is prepared to terminate the
+ program directly. We only generate code for MUST_NOT_THROW regions
+ along control paths that are already handling an exception within the
+ current function. */
+ ERT_MUST_NOT_THROW
+};
+
+
+/* A landing pad for a given exception region. Any transfer of control
+ from the EH runtime to the function happens at a landing pad. */
+
+struct GTY(()) eh_landing_pad_d
+{
+ /* The linked list of all landing pads associated with the region. */
+ struct eh_landing_pad_d *next_lp;
+
+ /* The region with which this landing pad is associated. */
+ struct eh_region_d *region;
+
+ /* At the gimple level, the location to which control will be transfered
+ for this landing pad. There can be both EH and normal edges into the
+ block containing the post-landing-pad label. */
+ tree post_landing_pad;
+
+ /* At the rtl level, the location to which the runtime will transfer
+ control. This differs from the post-landing-pad in that the target's
+ EXCEPTION_RECEIVER pattern will be expanded here, as well as other
+ bookkeeping specific to exceptions. There must not be normal edges
+ into the block containing the landing-pad label. */
+ rtx landing_pad;
+
+ /* The index of this landing pad within fun->eh->lp_array. */
+ int index;
+};
+
+/* A catch handler associated with an ERT_TRY region. */
+
+struct GTY(()) eh_catch_d
+{
+ /* The double-linked list of all catch handlers for the region. */
+ struct eh_catch_d *next_catch;
+ struct eh_catch_d *prev_catch;
+
+ /* A TREE_LIST of runtime type objects that this catch handler
+ will catch, or NULL if all exceptions are caught. */
+ tree type_list;
+
+ /* A TREE_LIST of INTEGER_CSTs that correspond to the type_list entries,
+ having been mapped by assign_filter_values. These integers are to be
+ compared against the __builtin_eh_filter value. */
+ tree filter_list;
+
+ /* The code that should be executed if this catch handler matches the
+ thrown exception. This label is only maintained until
+ pass_lower_eh_dispatch, at which point it is cleared. */
+ tree label;
};
/* Describes one exception region. */
+
struct GTY(()) eh_region_d
{
/* The immediately surrounding region. */
@@ -46,124 +122,123 @@ struct GTY(()) eh_region_d
struct eh_region_d *inner;
struct eh_region_d *next_peer;
- /* List of regions sharing label. */
- struct eh_region_d *next_region_sharing_label;
-
- /* An identifier for this region. */
- int region_number;
-
- /* When a region is deleted, its parents inherit the REG_EH_REGION
- numbers already assigned. */
- bitmap aka;
+ /* The index of this region within fun->eh->region_array. */
+ int index;
/* Each region does exactly one thing. */
enum eh_region_type type;
/* Holds the action to perform based on the preceding type. */
union eh_region_u {
- /* A list of catch blocks, a surrounding try block,
- and the label for continuing after a catch. */
struct eh_region_u_try {
- struct eh_region_d *eh_catch;
- struct eh_region_d *last_catch;
+ /* The double-linked list of all catch handlers for this region. */
+ struct eh_catch_d *first_catch;
+ struct eh_catch_d *last_catch;
} GTY ((tag ("ERT_TRY"))) eh_try;
- /* The list through the catch handlers, the list of type objects
- matched, and the list of associated filters. */
- struct eh_region_u_catch {
- struct eh_region_d *next_catch;
- struct eh_region_d *prev_catch;
- tree type_list;
- tree filter_list;
- } GTY ((tag ("ERT_CATCH"))) eh_catch;
-
- /* A tree_list of allowed types. */
struct eh_region_u_allowed {
+ /* A TREE_LIST of runtime type objects allowed to pass. */
tree type_list;
+ /* The code that should be executed if the thrown exception does
+ not match the type list. This label is only maintained until
+ pass_lower_eh_dispatch, at which point it is cleared. */
+ tree label;
+ /* The integer that will be passed by the runtime to signal that
+ we should execute the code at LABEL. This integer is assigned
+ by assign_filter_values and is to be compared against the
+ __builtin_eh_filter value. */
int filter;
} GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
- /* The type given by a call to "throw foo();", or discovered
- for a throw. */
- struct eh_region_u_throw {
- tree type;
- } GTY ((tag ("ERT_THROW"))) eh_throw;
+ struct eh_region_u_must_not_throw {
+ /* A function decl to be invoked if this region is actually reachable
+ from within the function, rather than implementable from the runtime.
+ The normal way for this to happen is for there to be a CLEANUP region
+ contained within this MUST_NOT_THROW region. Note that if the
+ runtime handles the MUST_NOT_THROW region, we have no control over
+ what termination function is called; it will be decided by the
+ personality function in effect for this CIE. */
+ tree failure_decl;
+ /* The location assigned to the call of FAILURE_DECL, if expanded. */
+ location_t failure_loc;
+ } GTY ((tag ("ERT_MUST_NOT_THROW"))) must_not_throw;
} GTY ((desc ("%0.type"))) u;
- /* Entry point for this region's handler before landing pads are built. */
- rtx label;
- tree tree_label;
-
- /* Entry point for this region's handler from the runtime eh library. */
- rtx landing_pad;
-
- /* Entry point for this region's handler from an inner region. */
- rtx post_landing_pad;
-
- /* The RESX insn for handing off control to the next outermost handler,
- if appropriate. */
- rtx resume;
+ /* The list of landing pads associated with this region. */
+ struct eh_landing_pad_d *landing_pads;
- /* True if something in this region may throw. */
- unsigned may_contain_throw : 1;
+ /* EXC_PTR and FILTER values copied from the runtime for this region.
+ Each region gets its own psuedos so that if there are nested exceptions
+ we do not overwrite the values of the first exception. */
+ rtx exc_ptr_reg, filter_reg;
};
+typedef struct eh_landing_pad_d *eh_landing_pad;
+typedef struct eh_catch_d *eh_catch;
typedef struct eh_region_d *eh_region;
+
DEF_VEC_P(eh_region);
DEF_VEC_ALLOC_P(eh_region, gc);
DEF_VEC_ALLOC_P(eh_region, heap);
-/* Per-function EH data. Used to save exception status for each
- function. */
+DEF_VEC_P(eh_landing_pad);
+DEF_VEC_ALLOC_P(eh_landing_pad, gc);
+
+
+/* The exception status for each function. */
+
struct GTY(()) eh_status
{
/* The tree of all regions for this function. */
- struct eh_region_d *region_tree;
+ eh_region region_tree;
/* The same information as an indexable array. */
VEC(eh_region,gc) *region_array;
- int last_region_number;
+ /* The landing pads as an indexable array. */
+ VEC(eh_landing_pad,gc) *lp_array;
+
+ /* At the gimple level, a mapping from gimple statement to landing pad
+ or must-not-throw region. See record_stmt_eh_region. */
htab_t GTY((param_is (struct throw_stmt_node))) throw_stmt_table;
+
+ /* All of the runtime type data used by the function. These objects
+ are emitted to the lang-specific-data-area for the function. */
+ VEC(tree,gc) *ttype_data;
+
+ /* The table of all action chains. These encode the eh_region tree in
+ a compact form for use by the runtime, and is also emitted to the
+ lang-specific-data-area. Note that the ARM EABI uses a different
+ format for the encoding than all other ports. */
+ union eh_status_u {
+ VEC(tree,gc) * GTY((tag ("1"))) arm_eabi;
+ VEC(uchar,gc) * GTY((tag ("0"))) other;
+ } GTY ((desc ("targetm.arm_eabi_unwinder"))) ehspec_data;
};
/* Test: is exception handling turned on? */
extern int doing_eh (int);
-/* Note that the current EH region (if any) may contain a throw, or a
- call to a function which itself may contain a throw. */
-extern void note_eh_region_may_contain_throw (struct eh_region_d *);
-
/* Invokes CALLBACK for every exception handler label. Only used by old
loop hackery; should not be used by new code. */
extern void for_each_eh_label (void (*) (rtx));
-/* Invokes CALLBACK for every exception region in the current function. */
-extern void for_each_eh_region (void (*) (struct eh_region_d *));
-
-/* Determine if the given INSN can throw an exception. */
-extern bool can_throw_internal_1 (int, bool, bool);
-extern bool can_throw_internal (const_rtx);
-extern bool can_throw_external_1 (int, bool, bool);
-extern bool can_throw_external (const_rtx);
-
/* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */
extern unsigned int set_nothrow_function_flags (void);
extern void init_eh (void);
extern void init_eh_for_function (void);
-extern rtx reachable_handlers (rtx);
-extern void remove_eh_region (int);
-extern void remove_eh_region_and_replace_by_outer_of (int, int);
+extern void remove_eh_landing_pad (eh_landing_pad);
+extern void remove_eh_handler (eh_region);
-extern void convert_from_eh_region_ranges (void);
-extern unsigned int convert_to_eh_region_ranges (void);
-extern void find_exception_handler_labels (void);
extern bool current_function_has_exception_handlers (void);
extern void output_function_exception_table (const char *);
+extern rtx expand_builtin_eh_pointer (tree);
+extern rtx expand_builtin_eh_filter (tree);
+extern rtx expand_builtin_eh_copy_values (tree);
extern void expand_builtin_unwind_init (void);
extern rtx expand_builtin_eh_return_data_regno (tree);
extern rtx expand_builtin_extract_return_addr (tree);
@@ -173,53 +248,54 @@ extern rtx expand_builtin_dwarf_sp_column (void);
extern void expand_builtin_eh_return (tree, tree);
extern void expand_eh_return (void);
extern rtx expand_builtin_extend_pointer (tree);
-extern rtx get_exception_pointer (void);
-extern rtx get_exception_filter (void);
+
typedef tree (*duplicate_eh_regions_map) (tree, void *);
-extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map,
- void *, int, int);
+extern struct pointer_map_t *duplicate_eh_regions
+ (struct function *, eh_region, int, duplicate_eh_regions_map, void *);
extern void sjlj_emit_function_exit_after (rtx);
-extern void default_init_unwind_resume_libfunc (void);
-
-extern struct eh_region_d *gen_eh_region_cleanup (struct eh_region_d *);
-extern struct eh_region_d *gen_eh_region_try (struct eh_region_d *);
-extern struct eh_region_d *gen_eh_region_catch (struct eh_region_d *, tree);
-extern struct eh_region_d *gen_eh_region_allowed (struct eh_region_d *, tree);
-extern struct eh_region_d *gen_eh_region_must_not_throw (struct eh_region_d *);
-extern int get_eh_region_number (struct eh_region_d *);
-extern bool get_eh_region_may_contain_throw (struct eh_region_d *);
-extern tree get_eh_region_no_tree_label (int);
-extern tree get_eh_region_tree_label (struct eh_region_d *);
-extern void set_eh_region_tree_label (struct eh_region_d *, tree);
-
-extern void foreach_reachable_handler (int, bool, bool,
- void (*) (struct eh_region_d *, void *),
- void *);
-
-extern void collect_eh_region_array (void);
-extern void expand_resx_stmt (gimple);
+
+extern eh_region gen_eh_region_cleanup (eh_region);
+extern eh_region gen_eh_region_try (eh_region);
+extern eh_region gen_eh_region_allowed (eh_region, tree);
+extern eh_region gen_eh_region_must_not_throw (eh_region);
+
+extern eh_catch gen_eh_region_catch (eh_region, tree);
+extern eh_landing_pad gen_eh_landing_pad (eh_region);
+
+extern eh_region get_eh_region_from_number_fn (struct function *, int);
+extern eh_region get_eh_region_from_number (int);
+extern eh_landing_pad get_eh_landing_pad_from_number_fn (struct function*,int);
+extern eh_landing_pad get_eh_landing_pad_from_number (int);
+extern eh_region get_eh_region_from_lp_number_fn (struct function *, int);
+extern eh_region get_eh_region_from_lp_number (int);
+
+extern eh_region eh_region_outermost (struct function *, eh_region, eh_region);
+
+extern void make_reg_eh_region_note (rtx insn, int ecf_flags, int lp_nr);
+extern void make_reg_eh_region_note_nothrow_nononlocal (rtx);
+
extern void verify_eh_tree (struct function *);
extern void dump_eh_tree (FILE *, struct function *);
void debug_eh_tree (struct function *);
-extern int eh_region_outermost (struct function *, int, int);
extern void add_type_for_runtime (tree);
extern tree lookup_type_for_runtime (tree);
+extern void assign_filter_values (void);
-/* If non-NULL, this is a function that returns an expression to be
+extern eh_region get_eh_region_from_rtx (const_rtx);
+extern eh_landing_pad get_eh_landing_pad_from_rtx (const_rtx);
+
+/* If non-NULL, this is a function that returns a function decl to be
executed if an unhandled exception is propagated out of a cleanup
region. For example, in C++, an exception thrown by a destructor
during stack unwinding is required to result in a call to
`std::terminate', so the C++ version of this function returns a
- CALL_EXPR for `std::terminate'. */
-extern gimple (*lang_protect_cleanup_actions) (void);
+ FUNCTION_DECL for `std::terminate'. */
+extern tree (*lang_protect_cleanup_actions) (void);
/* Return true if type A catches type B. */
extern int (*lang_eh_type_covers) (tree a, tree b);
-/* Map a type to a runtime object to match type. */
-extern tree (*lang_eh_runtime_type) (tree);
-
/* Just because the user configured --with-sjlj-exceptions=no doesn't
mean that we can use call frame exceptions. Detect that the target
@@ -266,14 +342,48 @@ extern tree (*lang_eh_runtime_type) (tree);
struct GTY(()) throw_stmt_node {
gimple stmt;
- int region_nr;
+ int lp_nr;
};
extern struct htab *get_eh_throw_stmt_table (struct function *);
extern void set_eh_throw_stmt_table (struct function *, struct htab *);
-extern void remove_unreachable_regions (sbitmap, sbitmap);
-extern VEC(int,heap) * label_to_region_map (void);
-extern int num_eh_regions (void);
-extern bitmap must_not_throw_labels (void);
-extern struct eh_region_d *redirect_eh_edge_to_label (struct edge_def *, tree, bool, bool, int);
-extern int get_next_region_sharing_label (int);
+
+enum eh_personality_kind {
+ eh_personality_none,
+ eh_personality_any,
+ eh_personality_lang
+};
+
+extern enum eh_personality_kind
+function_needs_eh_personality (struct function *);
+
+/* Pre-order iteration within the eh_region tree. */
+
+static inline eh_region
+ehr_next (eh_region r, eh_region start)
+{
+ if (r->inner)
+ r = r->inner;
+ else if (r->next_peer && r != start)
+ r = r->next_peer;
+ else
+ {
+ do
+ {
+ r = r->outer;
+ if (r == start)
+ return NULL;
+ }
+ while (r->next_peer == NULL);
+ r = r->next_peer;
+ }
+ return r;
+}
+
+#define FOR_ALL_EH_REGION_AT(R, START) \
+ for ((R) = (START); (R) != NULL; (R) = ehr_next (R, START))
+
+#define FOR_ALL_EH_REGION_FN(R, FN) \
+ for ((R) = (FN)->eh->region_tree; (R) != NULL; (R) = ehr_next (R, NULL))
+
+#define FOR_ALL_EH_REGION(R) FOR_ALL_EH_REGION_FN (R, cfun)
diff --git a/gcc/expr.c b/gcc/expr.c
index cd5eae16880..5d18435a99a 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -7110,7 +7110,7 @@ rtx
expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
enum expand_modifier modifier, rtx *alt_rtl)
{
- int rn = -1;
+ int lp_nr = 0;
rtx ret, last = NULL;
/* Handle ERROR_MARK before anybody tries to access its type. */
@@ -7123,10 +7123,8 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
if (flag_non_call_exceptions)
{
- rn = lookup_expr_eh_region (exp);
-
- /* If rn < 0, then either (1) tree-ssa not used or (2) doesn't throw. */
- if (rn >= 0)
+ lp_nr = lookup_expr_eh_lp (exp);
+ if (lp_nr)
last = get_last_insn ();
}
@@ -7159,7 +7157,7 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
/* If using non-call exceptions, mark all insns that may trap.
expand_call() will mark CALL_INSNs before we get to this code,
but it doesn't handle libcalls, and these may trap. */
- if (rn >= 0)
+ if (lp_nr)
{
rtx insn;
for (insn = next_real_insn (last); insn;
@@ -7170,8 +7168,8 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
may_trap_p instruction may throw. */
&& GET_CODE (PATTERN (insn)) != CLOBBER
&& GET_CODE (PATTERN (insn)) != USE
- && (CALL_P (insn) || may_trap_p (PATTERN (insn))))
- add_reg_note (insn, REG_EH_REGION, GEN_INT (rn));
+ && insn_could_throw_p (insn))
+ make_reg_eh_region_note (insn, 0, lp_nr);
}
}
@@ -7239,6 +7237,7 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
switch (code)
{
+ case NON_LVALUE_EXPR:
case PAREN_EXPR:
CASE_CONVERT:
if (treeop0 == error_mark_node)
@@ -9490,7 +9489,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
case GOTO_EXPR:
case SWITCH_EXPR:
case ASM_EXPR:
- case RESX_EXPR:
/* Expanded in cfgexpand.c. */
gcc_unreachable ();
@@ -9519,12 +9517,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
/* Lowered by gimplify.c. */
gcc_unreachable ();
- case EXC_PTR_EXPR:
- return get_exception_pointer ();
-
- case FILTER_EXPR:
- return get_exception_filter ();
-
case FDESC_EXPR:
/* Function descriptors are not valid except for as
initialization constants, and should not be expanded. */
@@ -10214,4 +10206,52 @@ const_vector_from_tree (tree exp)
return gen_rtx_CONST_VECTOR (mode, v);
}
+
+
+/* Build a decl for a EH personality function named NAME. */
+
+tree
+build_personality_function (const char *name)
+{
+ tree decl, type;
+
+ type = build_function_type_list (integer_type_node, integer_type_node,
+ long_long_unsigned_type_node,
+ ptr_type_node, ptr_type_node, NULL_TREE);
+ decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
+ get_identifier (name), type);
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+
+ /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
+ are the flags assigned by targetm.encode_section_info. */
+ SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
+
+ return decl;
+}
+
+/* Extracts the personality function of DECL and returns the corresponding
+ libfunc. */
+
+rtx
+get_personality_function (tree decl)
+{
+ tree personality = DECL_FUNCTION_PERSONALITY (decl);
+ enum eh_personality_kind pk;
+
+ pk = function_needs_eh_personality (DECL_STRUCT_FUNCTION (decl));
+ if (pk == eh_personality_none)
+ return NULL;
+
+ if (!personality
+ && pk == eh_personality_any)
+ personality = lang_hooks.eh_personality ();
+
+ if (pk == eh_personality_lang)
+ gcc_assert (personality != NULL_TREE);
+
+ return XEXP (DECL_RTL (personality), 0);
+}
+
#include "gt-expr.h"
diff --git a/gcc/expr.h b/gcc/expr.h
index 8eddb44be43..9bf0c38f5d2 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -814,6 +814,12 @@ extern void init_all_optabs (void);
extern rtx init_one_libfunc (const char *);
extern rtx set_user_assembler_libfunc (const char *, const char *);
+/* Build a decl for a libfunc named NAME. */
+extern tree build_libfunc_function (const char *);
+
+/* Get the personality libfunc for a function decl. */
+rtx get_personality_function (tree);
+
extern int vector_mode_valid_p (enum machine_mode);
#endif /* GCC_EXPR_H */
diff --git a/gcc/final.c b/gcc/final.c
index 76c52ca100e..3ecb415d795 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -1081,7 +1081,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
INSN_ADDRESSES (uid) = insn_current_address + insn_lengths[uid];
if (NOTE_P (insn) || BARRIER_P (insn)
- || LABEL_P (insn))
+ || LABEL_P (insn) || DEBUG_INSN_P(insn))
continue;
if (INSN_DELETED_P (insn))
continue;
@@ -1484,6 +1484,20 @@ remap_debug_filename (const char *filename)
return ggc_strdup (s);
}
+/* Return true if DWARF2 debug info can be emitted for DECL. */
+
+static bool
+dwarf2_debug_info_emitted_p (tree decl)
+{
+ if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG)
+ return false;
+
+ if (DECL_IGNORED_P (decl))
+ return false;
+
+ return true;
+}
+
/* Output assembler code for the start of a function,
and initialize some of the variables in this file
for the new function. The label for the function and associated
@@ -1508,10 +1522,11 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file,
high_block_linenum = high_function_linenum = last_linenum;
- (*debug_hooks->begin_prologue) (last_linenum, last_filename);
+ if (!DECL_IGNORED_P (current_function_decl))
+ debug_hooks->begin_prologue (last_linenum, last_filename);
#if defined (DWARF2_UNWIND_INFO) || defined (TARGET_UNWIND_INFO)
- if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG)
+ if (!dwarf2_debug_info_emitted_p (current_function_decl))
dwarf2out_begin_prologue (0, NULL);
#endif
@@ -1648,17 +1663,19 @@ final_end_function (void)
{
app_disable ();
- (*debug_hooks->end_function) (high_function_linenum);
+ if (!DECL_IGNORED_P (current_function_decl))
+ debug_hooks->end_function (high_function_linenum);
/* Finally, output the function epilogue:
code to restore the stack frame and return to the caller. */
targetm.asm_out.function_epilogue (asm_out_file, get_frame_size ());
/* And debug output. */
- (*debug_hooks->end_epilogue) (last_linenum, last_filename);
+ if (!DECL_IGNORED_P (current_function_decl))
+ debug_hooks->end_epilogue (last_linenum, last_filename);
#if defined (DWARF2_UNWIND_INFO)
- if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG
+ if (!dwarf2_debug_info_emitted_p (current_function_decl)
&& dwarf2out_do_frame ())
dwarf2out_end_epilogue (last_linenum, last_filename);
#endif
@@ -1839,7 +1856,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
dwarf2out_switch_text_section ();
else
#endif
- (*debug_hooks->switch_text_section) ();
+ if (!DECL_IGNORED_P (current_function_decl))
+ debug_hooks->switch_text_section ();
switch_to_section (current_function_section ());
break;
@@ -1905,7 +1923,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
case NOTE_INSN_FUNCTION_BEG:
app_disable ();
- (*debug_hooks->end_prologue) (last_linenum, last_filename);
+ if (!DECL_IGNORED_P (current_function_decl))
+ debug_hooks->end_prologue (last_linenum, last_filename);
if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
{
@@ -1931,7 +1950,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
high_block_linenum = last_linenum;
/* Output debugging info about the symbol-block beginning. */
- (*debug_hooks->begin_block) (last_linenum, n);
+ if (!DECL_IGNORED_P (current_function_decl))
+ debug_hooks->begin_block (last_linenum, n);
/* Mark this block as output. */
TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
@@ -1965,7 +1985,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
--block_depth;
gcc_assert (block_depth >= 0);
- (*debug_hooks->end_block) (high_block_linenum, n);
+ if (!DECL_IGNORED_P (current_function_decl))
+ debug_hooks->end_block (high_block_linenum, n);
}
if (write_symbols == DBX_DEBUG
|| write_symbols == SDB_DEBUG)
@@ -1995,7 +2016,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
break;
case NOTE_INSN_VAR_LOCATION:
- (*debug_hooks->var_location) (insn);
+ if (!DECL_IGNORED_P (current_function_decl))
+ debug_hooks->var_location (insn);
break;
default:
@@ -2038,8 +2060,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
CC_STATUS_INIT;
#endif
- if (LABEL_NAME (insn))
- (*debug_hooks->label) (insn);
+ if (!DECL_IGNORED_P (current_function_decl) && LABEL_NAME (insn))
+ debug_hooks->label (insn);
app_disable ();
@@ -2193,13 +2215,10 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
}
/* Output this line note if it is the first or the last line
note in a row. */
- if (notice_source_line (insn, &is_stmt))
- {
- (*debug_hooks->source_line) (last_linenum,
- last_filename,
- last_discriminator,
- is_stmt);
- }
+ if (!DECL_IGNORED_P (current_function_decl)
+ && notice_source_line (insn, &is_stmt))
+ (*debug_hooks->source_line) (last_linenum, last_filename,
+ last_discriminator, is_stmt);
if (GET_CODE (body) == ASM_INPUT)
{
@@ -4261,7 +4280,8 @@ rest_of_handle_final (void)
*will* be routed past here. */
timevar_push (TV_SYMOUT);
- (*debug_hooks->function_decl) (current_function_decl);
+ if (!DECL_IGNORED_P (current_function_decl))
+ debug_hooks->function_decl (current_function_decl);
timevar_pop (TV_SYMOUT);
/* Release the blocks that are linked to DECL_INITIAL() to free the memory. */
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 342e3760bdf..1ce0013ef35 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -15224,9 +15224,7 @@ tree_expr_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
case ASSERT_EXPR:
case ADDR_EXPR:
case WITH_SIZE_EXPR:
- case EXC_PTR_EXPR:
case SSA_NAME:
- case FILTER_EXPR:
return tree_single_nonnegative_warnv_p (t, strict_overflow_p);
default:
@@ -15518,9 +15516,7 @@ tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
case ASSERT_EXPR:
case ADDR_EXPR:
case WITH_SIZE_EXPR:
- case EXC_PTR_EXPR:
case SSA_NAME:
- case FILTER_EXPR:
return tree_single_nonzero_warnv_p (t, strict_overflow_p);
case COMPOUND_EXPR:
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index aeae2835f3a..9c9744b140e 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,59 @@
+2009-09-16 Michael Matz <matz@suse.de>
+
+ PR fortran/41212
+ * trans.h (struct lang_type): Remove nontarget_type member.
+ * trans.c (gfc_add_modify): Don't access it.
+ * trans-decl.c (gfc_finish_var_decl): Don't allocate and set it,
+ instead set DECL_RESTRICTED_P on affected decls.
+
+2009-09-14 Richard Henderson <rth@redhat.com>
+
+ * f95-lang.c (gfc_init_builtin_functions): Update call to
+ build_common_builtin_nodes.
+ (gfc_maybe_initialize_eh): Don't call
+ default_init_unwind_resume_libfunc.
+
+2009-09-13 Richard Guenther <rguenther@suse.de>
+ Rafael Avila de Espindola <espindola@google.com>
+
+ * f95-lang.c (gfc_maybe_initialize_eh): Do not init
+ eh_personality_libfunc.
+
+2009-09-11 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/41242
+ * resolve.c (resolve_ordinary_assign): Don't call resolve_code,
+ to avoid that subsequent codes are resolved more than once.
+ (resolve_code): Make sure that type-bound assignment operators are
+ resolved correctly.
+
+
+2009-09-10 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/31292
+ * fortran/decl.c(gfc_match_modproc): Check that module procedures
+ from a module can USEd in module procedure statements in other
+ program units. Update locus for better error message display.
+ Detect intrinsic procedures in module procedure statements.
+
+2009-09-09 Richard Guenther <rguenther@suse.de>
+
+ PR fortran/41297
+ * trans-expr.c (gfc_trans_scalar_assign): Correct typo that
+ left 'tmp' unused in derived type assignment.
+
+2009-09-07 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/41197
+ * resolve_c (resolve_allocate_deallocate): Complain
+ if stat or errmsg varaible is an array.
+
+2009-09-05 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/41258
+ * primary.c (gfc_match_varspec): Do not look for typebound
+ procedures unless the derived type has a f2k_derived namespace.
+
2009-09-03 Diego Novillo <dnovillo@google.com>
* f95-lang.c (lang_hooks): Remove const qualifier.
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 52796a65575..3ce7fd4a337 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -6485,7 +6485,10 @@ gfc_match_modproc (void)
module_ns = gfc_current_ns->parent;
for (; module_ns; module_ns = module_ns->parent)
- if (module_ns->proc_name->attr.flavor == FL_MODULE)
+ if (module_ns->proc_name->attr.flavor == FL_MODULE
+ || module_ns->proc_name->attr.flavor == FL_PROGRAM
+ || (module_ns->proc_name->attr.flavor == FL_PROCEDURE
+ && !module_ns->proc_name->attr.contained))
break;
if (module_ns == NULL)
@@ -6497,6 +6500,7 @@ gfc_match_modproc (void)
for (;;)
{
+ locus old_locus = gfc_current_locus;
bool last = false;
m = gfc_match_name (name);
@@ -6517,6 +6521,13 @@ gfc_match_modproc (void)
if (gfc_get_symbol (name, module_ns, &sym))
return MATCH_ERROR;
+ if (sym->attr.intrinsic)
+ {
+ gfc_error ("Intrinsic procedure at %L cannot be a MODULE "
+ "PROCEDURE", &old_locus);
+ return MATCH_ERROR;
+ }
+
if (sym->attr.proc != PROC_MODULE
&& gfc_add_procedure (&sym->attr, PROC_MODULE,
sym->name, NULL) == FAILURE)
@@ -6526,6 +6537,7 @@ gfc_match_modproc (void)
return MATCH_ERROR;
sym->attr.mod_proc = 1;
+ sym->declared_at = old_locus;
if (last)
break;
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index e061538878f..a21044c64ae 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -1131,7 +1131,7 @@ gfc_init_builtin_functions (void)
BUILT_IN_EMUTLS_REGISTER_COMMON,
"__emutls_register_common", false);
- build_common_builtin_nodes ();
+ build_common_builtin_nodes (false);
targetm.init_builtins ();
}
@@ -1155,11 +1155,6 @@ gfc_maybe_initialize_eh (void)
return;
gfc_eh_initialized_p = true;
- eh_personality_libfunc
- = init_one_libfunc (USING_SJLJ_EXCEPTIONS
- ? "__gcc_personality_sj0"
- : "__gcc_personality_v0");
- default_init_unwind_resume_libfunc ();
using_eh_for_cleanups ();
}
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index 267819c69f6..f25de2397bf 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -1783,7 +1783,11 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
if (m != MATCH_YES)
return MATCH_ERROR;
- tbp = gfc_find_typebound_proc (sym, &t, name, false, &gfc_current_locus);
+ if (sym->f2k_derived)
+ tbp = gfc_find_typebound_proc (sym, &t, name, false, &gfc_current_locus);
+ else
+ tbp = NULL;
+
if (tbp)
{
gfc_symbol* tbp_sym;
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index b665c354503..f208f406626 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -5732,9 +5732,10 @@ resolve_allocate_deallocate (gfc_code *code, const char *fcn)
gfc_error ("Illegal stat-variable at %L for a PURE procedure",
&stat->where);
- if (stat->ts.type != BT_INTEGER
- && !(stat->ref && (stat->ref->type == REF_ARRAY
- || stat->ref->type == REF_COMPONENT)))
+ if ((stat->ts.type != BT_INTEGER
+ && !(stat->ref && (stat->ref->type == REF_ARRAY
+ || stat->ref->type == REF_COMPONENT)))
+ || stat->rank > 0)
gfc_error ("Stat-variable at %L must be a scalar INTEGER "
"variable", &stat->where);
@@ -5759,10 +5760,11 @@ resolve_allocate_deallocate (gfc_code *code, const char *fcn)
gfc_error ("Illegal errmsg-variable at %L for a PURE procedure",
&errmsg->where);
- if (errmsg->ts.type != BT_CHARACTER
- && !(errmsg->ref
- && (errmsg->ref->type == REF_ARRAY
- || errmsg->ref->type == REF_COMPONENT)))
+ if ((errmsg->ts.type != BT_CHARACTER
+ && !(errmsg->ref
+ && (errmsg->ref->type == REF_ARRAY
+ || errmsg->ref->type == REF_COMPONENT)))
+ || errmsg->rank > 0 )
gfc_error ("Errmsg-variable at %L must be a scalar CHARACTER "
"variable", &errmsg->where);
@@ -6956,7 +6958,6 @@ resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns)
&& (lhs->symtree->n.sym == (*rhsptr)->symtree->n.sym))
*rhsptr = gfc_get_parentheses (*rhsptr);
- resolve_code (code, ns);
return true;
}
@@ -7188,7 +7189,12 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
break;
if (resolve_ordinary_assign (code, ns))
- goto call;
+ {
+ if (code->op == EXEC_COMPCALL)
+ goto compcall;
+ else
+ goto call;
+ }
break;
@@ -7239,6 +7245,7 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
break;
case EXEC_COMPCALL:
+ compcall:
resolve_typebound_call (code);
break;
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 6a4c3e45cc9..4e72a23bd5c 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -581,26 +581,8 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
if (!sym->attr.target
&& !sym->attr.pointer
- && !sym->attr.proc_pointer
- /* For now, don't bother with aggregate types. We would need
- to adjust DECL_CONTEXT of all field decls. */
- && !AGGREGATE_TYPE_P (TREE_TYPE (decl)))
- {
- tree type = TREE_TYPE (decl);
- if (!TYPE_LANG_SPECIFIC (type))
- TYPE_LANG_SPECIFIC (type) = (struct lang_type *)
- ggc_alloc_cleared (sizeof (struct lang_type));
- if (!TYPE_LANG_SPECIFIC (type)->nontarget_type)
- {
- alias_set_type set = new_alias_set ();
- type = build_distinct_type_copy (type);
- TYPE_ALIAS_SET (type) = set;
- TYPE_LANG_SPECIFIC (type)->nontarget_type = type;
- }
- else
- type = TYPE_LANG_SPECIFIC (type)->nontarget_type;
- TREE_TYPE (decl) = type;
- }
+ && !sym->attr.proc_pointer)
+ DECL_RESTRICTED_P (decl) = 1;
}
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 3d675eb0499..b3642c2232c 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -4460,7 +4460,7 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
gfc_add_block_to_block (&block, &lse->pre);
gfc_add_block_to_block (&block, &rse->pre);
tmp = gfc_evaluate_now (rse->expr, &block);
- tmp = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lse->expr), rse->expr);
+ tmp = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lse->expr), tmp);
gfc_add_modify (&block, lse->expr, tmp);
}
else
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index f4a215aeeaf..136987a7488 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -162,13 +162,6 @@ gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs)
tree t1, t2;
t1 = TREE_TYPE (rhs);
t2 = TREE_TYPE (lhs);
- /* ??? This is actually backwards, we should test the "base" type
- from which the nontarget_type was copied, but we don't have this
- backlink. This will do for now, it's for checking anyway. */
- if (TYPE_LANG_SPECIFIC (t1))
- t1 = TYPE_LANG_SPECIFIC (t1)->nontarget_type;
- if (TYPE_LANG_SPECIFIC (t2))
- t2 = TYPE_LANG_SPECIFIC (t2)->nontarget_type;
/* Make sure that the types of the rhs and the lhs are the same
for scalar assignments. We should probably have something
similar for aggregates, but right now removing that check just
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 643f28b37f4..4469023499d 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -629,7 +629,6 @@ struct GTY(()) lang_type {
tree dataptr_type;
tree span;
tree base_decl[2];
- tree nontarget_type;
};
struct GTY(()) lang_decl {
diff --git a/gcc/function.h b/gcc/function.h
index c6be988a877..a51785361a9 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "hashtab.h"
-#include "varray.h"
+#include "vecprim.h"
/* Stack of pending (incomplete) sequences saved by `start_sequence'.
Each element describes one pending sequence.
@@ -144,11 +144,6 @@ DEF_VEC_ALLOC_P(call_site_record, gc);
/* RTL representation of exception handling. */
struct GTY(()) rtl_eh {
- rtx filter;
- rtx exc_ptr;
-
- int built_landing_pads;
-
rtx ehr_stackadj;
rtx ehr_handler;
rtx ehr_label;
@@ -156,9 +151,7 @@ struct GTY(()) rtl_eh {
rtx sjlj_fc;
rtx sjlj_exit_after;
- VEC(tree,gc) *ttype_data;
- varray_type ehspec_data;
- varray_type action_record_data;
+ VEC(uchar,gc) *action_record_data;
VEC(call_site_record,gc) *call_site_record[2];
};
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 25deb494a8d..a9ed7e21696 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -427,7 +427,7 @@ or with constant text in a single argument.
%b substitute the basename of the input file being processed.
This is the substring up to (and not including) the last period
and not including the directory unless -save-temps was specified
- to put temporaries in a different location.
+ to put temporaries in a different location.
%B same as %b, but include the file suffix (text after the last period).
%gSUFFIX
substitute a file name that has suffix SUFFIX and is chosen
@@ -564,7 +564,7 @@ or with constant text in a single argument.
%{!.S:X} substitutes X, if NOT processing a file with suffix S.
%{,S:X} substitutes X, if processing a file which will use spec S.
%{!,S:X} substitutes X, if NOT processing a file which will use spec S.
-
+
%{S|T:X} substitutes X if either -S or -T was given to GCC. This may be
combined with '!', '.', ',', and '*' as above binding stronger
than the OR.
@@ -3443,7 +3443,7 @@ add_linker_option (const char *option, int len)
if (! linker_options)
linker_options = XNEWVEC (char *, n_linker_options);
else
- linker_options = XRESIZEVEC (char *, linker_options, n_linker_options);
+ linker_options = XRESIZEVEC (char *, linker_options, n_linker_options);
linker_options [n_linker_options - 1] = save_string (option, len);
}
@@ -4685,6 +4685,13 @@ static int this_is_output_file;
search dirs for it. */
static int this_is_library_file;
+/* Nonzero means %T has been seen; the next arg to be terminated
+ is the name of a linker script and we should try all of the
+ standard search dirs for it. If it is found insert a --script
+ command line switch and then substitute the full path in place,
+ otherwise generate an error message. */
+static int this_is_linker_script;
+
/* Nonzero means that the input of this command is coming from a pipe. */
static int input_from_pipe;
@@ -4705,6 +4712,19 @@ end_going_arg (void)
string = XOBFINISH (&obstack, const char *);
if (this_is_library_file)
string = find_file (string);
+ if (this_is_linker_script)
+ {
+ char * full_script_path = find_a_file (&startfile_prefixes, string, R_OK, true);
+
+ if (full_script_path == NULL)
+ {
+ error (_("unable to locate default linker script '%s' in the library search paths"), string);
+ /* Script was not found on search path. */
+ return;
+ }
+ store_arg ("--script", false, false);
+ string = full_script_path;
+ }
store_arg (string, delete_this_arg, this_is_output_file);
if (this_is_output_file)
outfiles[input_file_number] = string;
@@ -4794,6 +4814,7 @@ do_spec_2 (const char *spec)
delete_this_arg = 0;
this_is_output_file = 0;
this_is_library_file = 0;
+ this_is_linker_script = 0;
input_from_pipe = 0;
suffix_subst = NULL;
@@ -5081,6 +5102,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
delete_this_arg = 0;
this_is_output_file = 0;
this_is_library_file = 0;
+ this_is_linker_script = 0;
input_from_pipe = 0;
break;
@@ -5100,6 +5122,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
delete_this_arg = 0;
this_is_output_file = 0;
this_is_library_file = 0;
+ this_is_linker_script = 0;
break;
case '%':
@@ -5547,6 +5570,10 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
this_is_library_file = 1;
break;
+ case 'T':
+ this_is_linker_script = 1;
+ break;
+
case 'V':
outfiles[input_file_number] = NULL;
break;
@@ -5921,6 +5948,7 @@ eval_spec_function (const char *func, const char *args)
int save_this_is_output_file;
int save_this_is_library_file;
int save_input_from_pipe;
+ int save_this_is_linker_script;
const char *save_suffix_subst;
@@ -5937,6 +5965,7 @@ eval_spec_function (const char *func, const char *args)
save_delete_this_arg = delete_this_arg;
save_this_is_output_file = this_is_output_file;
save_this_is_library_file = this_is_library_file;
+ save_this_is_linker_script = this_is_linker_script;
save_input_from_pipe = input_from_pipe;
save_suffix_subst = suffix_subst;
@@ -5962,6 +5991,7 @@ eval_spec_function (const char *func, const char *args)
delete_this_arg = save_delete_this_arg;
this_is_output_file = save_this_is_output_file;
this_is_library_file = save_this_is_library_file;
+ this_is_linker_script = save_this_is_linker_script;
input_from_pipe = save_input_from_pipe;
suffix_subst = save_suffix_subst;
@@ -6206,7 +6236,7 @@ handle_braces (const char *p)
{
if ((a_is_suffix || a_is_spectype) && a_is_starred)
goto invalid;
-
+
if (!a_is_starred)
disj_starred = false;
@@ -6220,7 +6250,7 @@ handle_braces (const char *p)
a_matched = input_spec_matches (atom, end_atom);
else
a_matched = switch_matches (atom, end_atom, a_is_starred);
-
+
if (a_matched != a_is_negated)
{
disj_matched = true;
diff --git a/gcc/gcse.c b/gcc/gcse.c
index dc4aa8b9a96..803ab3e5a14 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -1353,9 +1353,11 @@ hash_scan_set (rtx pat, rtx insn, struct hash_table_d *table)
/* Don't GCSE something if we can't do a reg/reg copy. */
&& can_copy_p (GET_MODE (dest))
/* GCSE commonly inserts instruction after the insn. We can't
- do that easily for EH_REGION notes so disable GCSE on these
- for now. */
- && !find_reg_note (insn, REG_EH_REGION, NULL_RTX)
+ do that easily for EH edges so disable GCSE on these for now. */
+ /* ??? We can now easily create new EH landing pads at the
+ gimple level, for splitting edges; there's no reason we
+ can't do the same thing at the rtl level. */
+ && !can_throw_internal (insn)
/* Is SET_SRC something we want to gcse? */
&& want_to_gcse_p (src)
/* Don't CSE a nop. */
@@ -1415,9 +1417,8 @@ hash_scan_set (rtx pat, rtx insn, struct hash_table_d *table)
/* Don't GCSE something if we can't do a reg/reg copy. */
&& can_copy_p (GET_MODE (src))
/* GCSE commonly inserts instruction after the insn. We can't
- do that easily for EH_REGION notes so disable GCSE on these
- for now. */
- && ! find_reg_note (insn, REG_EH_REGION, NULL_RTX)
+ do that easily for EH edges so disable GCSE on these for now. */
+ && !can_throw_internal (insn)
/* Is SET_DEST something we want to gcse? */
&& want_to_gcse_p (dest)
/* Don't CSE a nop. */
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index def9a694a0e..4d6295af604 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -319,7 +319,7 @@ static struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
/* Here is how primitive or already-shared RTL's hash
codes are made. */
-#define RTL_HASH(RTL) ((long) (RTL) & 0777777)
+#define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
/* Add an entry to the hash table for RTL with hash code HASHCODE. */
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 1a2f38bd8b5..69fa68ddb42 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1567,7 +1567,8 @@ open_base_files (void)
"hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
"optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
"tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
- "cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h", NULL
+ "cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h",
+ "target.h", NULL
};
const char *const *ifp;
outf_p gtype_desc_c;
diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c
index 666b47b47a8..66927d67c2c 100644
--- a/gcc/gimple-iterator.c
+++ b/gcc/gimple-iterator.c
@@ -363,7 +363,6 @@ gsi_split_seq_before (gimple_stmt_iterator *i)
void
gsi_replace (gimple_stmt_iterator *gsi, gimple stmt, bool update_eh_info)
{
- int eh_region;
gimple orig_stmt = gsi_stmt (*gsi);
if (stmt == orig_stmt)
@@ -375,14 +374,7 @@ gsi_replace (gimple_stmt_iterator *gsi, gimple stmt, bool update_eh_info)
/* Preserve EH region information from the original statement, if
requested by the caller. */
if (update_eh_info)
- {
- eh_region = lookup_stmt_eh_region (orig_stmt);
- if (eh_region >= 0)
- {
- remove_stmt_from_eh_region (orig_stmt);
- add_stmt_to_eh_region (stmt, eh_region);
- }
- }
+ maybe_clean_or_replace_eh_stmt (orig_stmt, stmt);
gimple_duplicate_stmt_histograms (cfun, stmt, cfun, orig_stmt);
gimple_remove_stmt_histograms (cfun, orig_stmt);
@@ -485,7 +477,7 @@ gsi_remove (gimple_stmt_iterator *i, bool remove_permanently)
if (remove_permanently)
{
- remove_stmt_from_eh_region (stmt);
+ remove_stmt_from_eh_lp (stmt);
gimple_remove_stmt_histograms (cfun, stmt);
}
@@ -623,9 +615,9 @@ gimple_find_edge_insert_loc (edge e, gimple_stmt_iterator *gsi,
would have to examine the PHIs to prove that none of them used
the value set by the statement we want to insert on E. That
hardly seems worth the effort. */
-restart:
+ restart:
if (single_pred_p (dest)
- && ! phi_nodes (dest)
+ && gimple_seq_empty_p (phi_nodes (dest))
&& dest != EXIT_BLOCK_PTR)
{
*gsi = gsi_start_bb (dest);
@@ -667,10 +659,13 @@ restart:
if (!stmt_ends_bb_p (tmp))
return true;
- if (gimple_code (tmp) == GIMPLE_RETURN)
- {
- gsi_prev (gsi);
- return true;
+ switch (gimple_code (tmp))
+ {
+ case GIMPLE_RETURN:
+ case GIMPLE_RESX:
+ return false;
+ default:
+ break;
}
}
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index eba86727a05..b58fd7b42f5 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -360,6 +360,7 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
case GIMPLE_PREDICT:
case GIMPLE_LABEL:
case GIMPLE_SWITCH:
+ case GIMPLE_EH_MUST_NOT_THROW:
case GIMPLE_OMP_FOR:
case GIMPLE_OMP_SECTIONS:
case GIMPLE_OMP_SECTIONS_SWITCH:
@@ -497,8 +498,8 @@ try_catch_may_fallthru (const_tree stmt)
default:
/* This case represents statements to be executed when an
exception occurs. Those statements are implicitly followed
- by a RESX_EXPR to resume execution after the exception. So
- in this case the TRY_CATCH never falls through. */
+ by a RESX statement to resume execution after the exception.
+ So in this case the TRY_CATCH never falls through. */
return false;
}
}
@@ -571,7 +572,6 @@ block_may_fallthru (const_tree block)
{
case GOTO_EXPR:
case RETURN_EXPR:
- case RESX_EXPR:
/* Easy cases. If the last statement of the block implies
control transfer, then we can't fall through. */
return false;
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 50180203e2d..3d3134beaa6 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -626,6 +626,8 @@ dump_gimple_label (pretty_printer *buffer, gimple gs, int spc, int flags)
}
if (DECL_NONLOCAL (label))
pp_string (buffer, " [non-local]");
+ if ((flags & TDF_EH) && EH_LANDING_PAD_NR (label))
+ pp_printf (buffer, " [LP %d]", EH_LANDING_PAD_NR (label));
}
/* Dump a GIMPLE_GOTO tuple on the pretty_printer BUFFER, SPC
@@ -766,6 +768,21 @@ dump_gimple_eh_filter (pretty_printer *buffer, gimple gs, int spc, int flags)
}
+/* Dump a GIMPLE_EH_MUST_NOT_THROW tuple. */
+
+static void
+dump_gimple_eh_must_not_throw (pretty_printer *buffer, gimple gs,
+ int spc, int flags)
+{
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs,
+ gimple_eh_must_not_throw_fndecl (gs));
+ else
+ dump_gimple_fmt (buffer, spc, flags, "<<<eh_must_not_throw (%T)>>>",
+ gimple_eh_must_not_throw_fndecl (gs));
+}
+
+
/* Dump a GIMPLE_RESX tuple on the pretty_printer BUFFER, SPC spaces of
indent. FLAGS specifies details to show in the dump (see TDF_* in
tree-pass.h). */
@@ -775,11 +792,24 @@ dump_gimple_resx (pretty_printer *buffer, gimple gs, int spc, int flags)
{
if (flags & TDF_RAW)
dump_gimple_fmt (buffer, spc, flags, "%G <%d>", gs,
- gimple_resx_region (gs));
+ gimple_resx_region (gs));
else
dump_gimple_fmt (buffer, spc, flags, "resx %d", gimple_resx_region (gs));
}
+/* Dump a GIMPLE_EH_DISPATCH tuple on the pretty_printer BUFFER. */
+
+static void
+dump_gimple_eh_dispatch (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%d>", gs,
+ gimple_eh_dispatch_region (gs));
+ else
+ dump_gimple_fmt (buffer, spc, flags, "eh_dispatch %d",
+ gimple_eh_dispatch_region (gs));
+}
+
/* Dump a GIMPLE_DEBUG tuple on the pretty_printer BUFFER, SPC spaces
of indent. FLAGS specifies details to show in the dump (see TDF_*
in tree-pass.h). */
@@ -1071,89 +1101,151 @@ dump_gimple_omp_return (pretty_printer *buffer, gimple gs, int spc, int flags)
static void
dump_gimple_asm (pretty_printer *buffer, gimple gs, int spc, int flags)
{
- unsigned int i;
+ unsigned int i, n, f, fields;
if (flags & TDF_RAW)
- dump_gimple_fmt (buffer, spc, flags, "%G <%+STRING <%n%s%n>", gs,
- gimple_asm_string (gs));
+ {
+ dump_gimple_fmt (buffer, spc, flags, "%G <%+STRING <%n%s%n>", gs,
+ gimple_asm_string (gs));
+
+ n = gimple_asm_noutputs (gs);
+ if (n)
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_string (buffer, "OUTPUT: ");
+ for (i = 0; i < n; i++)
+ {
+ dump_generic_node (buffer, gimple_asm_output_op (gs, i),
+ spc, flags, false);
+ if (i < n - 1)
+ pp_string (buffer, ", ");
+ }
+ }
+
+ n = gimple_asm_ninputs (gs);
+ if (n)
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_string (buffer, "INPUT: ");
+ for (i = 0; i < n; i++)
+ {
+ dump_generic_node (buffer, gimple_asm_input_op (gs, i),
+ spc, flags, false);
+ if (i < n - 1)
+ pp_string (buffer, ", ");
+ }
+ }
+
+ n = gimple_asm_nclobbers (gs);
+ if (n)
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_string (buffer, "CLOBBER: ");
+ for (i = 0; i < n; i++)
+ {
+ dump_generic_node (buffer, gimple_asm_clobber_op (gs, i),
+ spc, flags, false);
+ if (i < n - 1)
+ pp_string (buffer, ", ");
+ }
+ }
+
+ n = gimple_asm_nlabels (gs);
+ if (n)
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_string (buffer, "LABEL: ");
+ for (i = 0; i < n; i++)
+ {
+ dump_generic_node (buffer, gimple_asm_label_op (gs, i),
+ spc, flags, false);
+ if (i < n - 1)
+ pp_string (buffer, ", ");
+ }
+ }
+
+ newline_and_indent (buffer, spc);
+ pp_character (buffer, '>');
+ }
else
{
pp_string (buffer, "__asm__");
if (gimple_asm_volatile_p (gs))
pp_string (buffer, " __volatile__");
+ if (gimple_asm_nlabels (gs))
+ pp_string (buffer, " goto");
pp_string (buffer, "(\"");
pp_string (buffer, gimple_asm_string (gs));
pp_string (buffer, "\"");
- }
- if (gimple_asm_ninputs (gs)
- || gimple_asm_noutputs (gs)
- || gimple_asm_nclobbers (gs))
- {
- if (gimple_asm_noutputs (gs))
- {
- if (flags & TDF_RAW)
- {
- newline_and_indent (buffer, spc + 2);
- pp_string (buffer, "OUTPUT: ");
- }
- else
- pp_string (buffer, " : ");
- }
+ if (gimple_asm_nlabels (gs))
+ fields = 4;
+ else if (gimple_asm_nclobbers (gs))
+ fields = 3;
+ else if (gimple_asm_ninputs (gs))
+ fields = 2;
+ else if (gimple_asm_noutputs (gs))
+ fields = 1;
+ else
+ fields = 0;
- for (i = 0; i < gimple_asm_noutputs (gs); i++)
- {
- dump_generic_node (buffer, gimple_asm_output_op (gs, i), spc, flags,
- false);
- if ( i < gimple_asm_noutputs (gs) -1)
- pp_string (buffer, ", ");
- }
+ for (f = 0; f < fields; ++f)
+ {
+ pp_string (buffer, " : ");
- if (gimple_asm_ninputs (gs))
- {
- if (flags & TDF_RAW)
- {
- newline_and_indent (buffer, spc + 2);
- pp_string (buffer, "INPUT: ");
- }
- else
- pp_string (buffer, " : ");
- }
+ switch (f)
+ {
+ case 0:
+ n = gimple_asm_noutputs (gs);
+ for (i = 0; i < n; i++)
+ {
+ dump_generic_node (buffer, gimple_asm_output_op (gs, i),
+ spc, flags, false);
+ if (i < n - 1)
+ pp_string (buffer, ", ");
+ }
+ break;
- for (i = 0; i < gimple_asm_ninputs (gs); i++)
- {
- dump_generic_node (buffer, gimple_asm_input_op (gs, i), spc, flags,
- false);
- if (i < gimple_asm_ninputs (gs) -1)
- pp_string (buffer, " : ");
- }
+ case 1:
+ n = gimple_asm_ninputs (gs);
+ for (i = 0; i < n; i++)
+ {
+ dump_generic_node (buffer, gimple_asm_input_op (gs, i),
+ spc, flags, false);
+ if (i < n - 1)
+ pp_string (buffer, ", ");
+ }
+ break;
- if (gimple_asm_nclobbers (gs))
- {
- if (flags & TDF_RAW)
- {
- newline_and_indent (buffer, spc + 2);
- pp_string (buffer, "CLOBBER: ");
- }
- else
- pp_string (buffer, " : ");
- }
+ case 2:
+ n = gimple_asm_nclobbers (gs);
+ for (i = 0; i < n; i++)
+ {
+ dump_generic_node (buffer, gimple_asm_clobber_op (gs, i),
+ spc, flags, false);
+ if (i < n - 1)
+ pp_string (buffer, ", ");
+ }
+ break;
- for (i = 0; i < gimple_asm_nclobbers (gs); i++)
- {
- dump_generic_node (buffer, gimple_asm_clobber_op (gs, i), spc, flags,
- false);
- if ( i < gimple_asm_nclobbers (gs) -1)
- pp_string (buffer, ", ");
- }
- }
- if (flags & TDF_RAW)
- {
- newline_and_indent (buffer, spc);
- pp_character (buffer, '>');
+ case 3:
+ n = gimple_asm_nlabels (gs);
+ for (i = 0; i < n; i++)
+ {
+ dump_generic_node (buffer, gimple_asm_label_op (gs, i),
+ spc, flags, false);
+ if (i < n - 1)
+ pp_string (buffer, ", ");
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+
+ pp_string (buffer, ");");
}
- else
- pp_string (buffer, ");");
}
@@ -1427,9 +1519,11 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
if (flags & TDF_EH)
{
- int eh_region = lookup_stmt_eh_region_fn (cfun, gs);
- if (eh_region >= 0)
- pp_printf (buffer, "[EH #%d] ", eh_region);
+ int lp_nr = lookup_stmt_eh_lp (gs);
+ if (lp_nr > 0)
+ pp_printf (buffer, "[LP %d] ", lp_nr);
+ else if (lp_nr < 0)
+ pp_printf (buffer, "[MNT %d] ", -lp_nr);
}
if ((flags & (TDF_VOPS|TDF_MEMSYMS))
@@ -1545,10 +1639,18 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
dump_gimple_eh_filter (buffer, gs, spc, flags);
break;
+ case GIMPLE_EH_MUST_NOT_THROW:
+ dump_gimple_eh_must_not_throw (buffer, gs, spc, flags);
+ break;
+
case GIMPLE_RESX:
dump_gimple_resx (buffer, gs, spc, flags);
break;
+ case GIMPLE_EH_DISPATCH:
+ dump_gimple_eh_dispatch (buffer, gs, spc, flags);
+ break;
+
case GIMPLE_DEBUG:
dump_gimple_debug (buffer, gs, spc, flags);
break;
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 9223aaa8824..425463c31ca 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -35,18 +35,32 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "demangle.h"
-#define DEFGSCODE(SYM, NAME, STRUCT) NAME,
-const char *const gimple_code_name[] = {
-#include "gimple.def"
-};
-#undef DEFGSCODE
-/* All the tuples have their operand vector at the very bottom
+/* All the tuples have their operand vector (if present) at the very bottom
of the structure. Therefore, the offset required to find the
operands vector the size of the structure minus the size of the 1
element tree array at the end (see gimple_ops). */
-#define DEFGSCODE(SYM, NAME, STRUCT) (sizeof (STRUCT) - sizeof (tree)),
+#define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) \
+ (HAS_TREE_OP ? sizeof (struct STRUCT) - sizeof (tree) : 0),
EXPORTED_CONST size_t gimple_ops_offset_[] = {
+#include "gsstruct.def"
+};
+#undef DEFGSSTRUCT
+
+#define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) sizeof(struct STRUCT),
+static const size_t gsstruct_code_size[] = {
+#include "gsstruct.def"
+};
+#undef DEFGSSTRUCT
+
+#define DEFGSCODE(SYM, NAME, GSSCODE) NAME,
+const char *const gimple_code_name[] = {
+#include "gimple.def"
+};
+#undef DEFGSCODE
+
+#define DEFGSCODE(SYM, NAME, GSSCODE) GSSCODE,
+EXPORTED_CONST enum gimple_statement_structure_enum gss_for_code_[] = {
#include "gimple.def"
};
#undef DEFGSCODE
@@ -89,118 +103,15 @@ gimple_set_code (gimple g, enum gimple_code code)
g->gsbase.code = code;
}
-
-/* Return the GSS_* identifier for the given GIMPLE statement CODE. */
-
-static enum gimple_statement_structure_enum
-gss_for_code (enum gimple_code code)
-{
- switch (code)
- {
- case GIMPLE_ASSIGN:
- case GIMPLE_CALL:
- case GIMPLE_RETURN: return GSS_WITH_MEM_OPS;
- case GIMPLE_COND:
- case GIMPLE_GOTO:
- case GIMPLE_LABEL:
- case GIMPLE_DEBUG:
- case GIMPLE_SWITCH: return GSS_WITH_OPS;
- case GIMPLE_ASM: return GSS_ASM;
- case GIMPLE_BIND: return GSS_BIND;
- case GIMPLE_CATCH: return GSS_CATCH;
- case GIMPLE_EH_FILTER: return GSS_EH_FILTER;
- case GIMPLE_NOP: return GSS_BASE;
- case GIMPLE_PHI: return GSS_PHI;
- case GIMPLE_RESX: return GSS_RESX;
- case GIMPLE_TRY: return GSS_TRY;
- case GIMPLE_WITH_CLEANUP_EXPR: return GSS_WCE;
- case GIMPLE_OMP_CRITICAL: return GSS_OMP_CRITICAL;
- case GIMPLE_OMP_FOR: return GSS_OMP_FOR;
- case GIMPLE_OMP_MASTER:
- case GIMPLE_OMP_ORDERED:
- case GIMPLE_OMP_SECTION: return GSS_OMP;
- case GIMPLE_OMP_RETURN:
- case GIMPLE_OMP_SECTIONS_SWITCH: return GSS_BASE;
- case GIMPLE_OMP_CONTINUE: return GSS_OMP_CONTINUE;
- case GIMPLE_OMP_PARALLEL: return GSS_OMP_PARALLEL;
- case GIMPLE_OMP_TASK: return GSS_OMP_TASK;
- case GIMPLE_OMP_SECTIONS: return GSS_OMP_SECTIONS;
- case GIMPLE_OMP_SINGLE: return GSS_OMP_SINGLE;
- case GIMPLE_OMP_ATOMIC_LOAD: return GSS_OMP_ATOMIC_LOAD;
- case GIMPLE_OMP_ATOMIC_STORE: return GSS_OMP_ATOMIC_STORE;
- case GIMPLE_PREDICT: return GSS_BASE;
- default: gcc_unreachable ();
- }
-}
-
-
/* Return the number of bytes needed to hold a GIMPLE statement with
code CODE. */
-static size_t
+static inline size_t
gimple_size (enum gimple_code code)
{
- enum gimple_statement_structure_enum gss = gss_for_code (code);
-
- if (gss == GSS_WITH_OPS)
- return sizeof (struct gimple_statement_with_ops);
- else if (gss == GSS_WITH_MEM_OPS)
- return sizeof (struct gimple_statement_with_memory_ops);
-
- switch (code)
- {
- case GIMPLE_ASM:
- return sizeof (struct gimple_statement_asm);
- case GIMPLE_NOP:
- return sizeof (struct gimple_statement_base);
- case GIMPLE_BIND:
- return sizeof (struct gimple_statement_bind);
- case GIMPLE_CATCH:
- return sizeof (struct gimple_statement_catch);
- case GIMPLE_EH_FILTER:
- return sizeof (struct gimple_statement_eh_filter);
- case GIMPLE_TRY:
- return sizeof (struct gimple_statement_try);
- case GIMPLE_RESX:
- return sizeof (struct gimple_statement_resx);
- case GIMPLE_OMP_CRITICAL:
- return sizeof (struct gimple_statement_omp_critical);
- case GIMPLE_OMP_FOR:
- return sizeof (struct gimple_statement_omp_for);
- case GIMPLE_OMP_PARALLEL:
- return sizeof (struct gimple_statement_omp_parallel);
- case GIMPLE_OMP_TASK:
- return sizeof (struct gimple_statement_omp_task);
- case GIMPLE_OMP_SECTION:
- case GIMPLE_OMP_MASTER:
- case GIMPLE_OMP_ORDERED:
- return sizeof (struct gimple_statement_omp);
- case GIMPLE_OMP_RETURN:
- return sizeof (struct gimple_statement_base);
- case GIMPLE_OMP_CONTINUE:
- return sizeof (struct gimple_statement_omp_continue);
- case GIMPLE_OMP_SECTIONS:
- return sizeof (struct gimple_statement_omp_sections);
- case GIMPLE_OMP_SECTIONS_SWITCH:
- return sizeof (struct gimple_statement_base);
- case GIMPLE_OMP_SINGLE:
- return sizeof (struct gimple_statement_omp_single);
- case GIMPLE_OMP_ATOMIC_LOAD:
- return sizeof (struct gimple_statement_omp_atomic_load);
- case GIMPLE_OMP_ATOMIC_STORE:
- return sizeof (struct gimple_statement_omp_atomic_store);
- case GIMPLE_WITH_CLEANUP_EXPR:
- return sizeof (struct gimple_statement_wce);
- case GIMPLE_PREDICT:
- return sizeof (struct gimple_statement_base);
- default:
- break;
- }
-
- gcc_unreachable ();
+ return gsstruct_code_size[gss_for_code (code)];
}
-
/* Allocate memory for a GIMPLE statement with code CODE and NUM_OPS
operands. */
@@ -596,17 +507,22 @@ gimple_build_bind (tree vars, gimple_seq body, tree block)
static inline gimple
gimple_build_asm_1 (const char *string, unsigned ninputs, unsigned noutputs,
- unsigned nclobbers)
+ unsigned nclobbers, unsigned nlabels)
{
gimple p;
int size = strlen (string);
+ /* ASMs with labels cannot have outputs. This should have been
+ enforced by the front end. */
+ gcc_assert (nlabels == 0 || noutputs == 0);
+
p = gimple_build_with_ops (GIMPLE_ASM, ERROR_MARK,
- ninputs + noutputs + nclobbers);
+ ninputs + noutputs + nclobbers + nlabels);
p->gimple_asm.ni = ninputs;
p->gimple_asm.no = noutputs;
p->gimple_asm.nc = nclobbers;
+ p->gimple_asm.nl = nlabels;
p->gimple_asm.string = ggc_alloc_string (string, size);
#ifdef GATHER_STATISTICS
@@ -624,11 +540,13 @@ gimple_build_asm_1 (const char *string, unsigned ninputs, unsigned noutputs,
NCLOBBERS is the number of clobbered registers.
INPUTS is a vector of the input register parameters.
OUTPUTS is a vector of the output register parameters.
- CLOBBERS is a vector of the clobbered register parameters. */
+ CLOBBERS is a vector of the clobbered register parameters.
+ LABELS is a vector of destination labels. */
gimple
gimple_build_asm_vec (const char *string, VEC(tree,gc)* inputs,
- VEC(tree,gc)* outputs, VEC(tree,gc)* clobbers)
+ VEC(tree,gc)* outputs, VEC(tree,gc)* clobbers,
+ VEC(tree,gc)* labels)
{
gimple p;
unsigned i;
@@ -636,7 +554,8 @@ gimple_build_asm_vec (const char *string, VEC(tree,gc)* inputs,
p = gimple_build_asm_1 (string,
VEC_length (tree, inputs),
VEC_length (tree, outputs),
- VEC_length (tree, clobbers));
+ VEC_length (tree, clobbers),
+ VEC_length (tree, labels));
for (i = 0; i < VEC_length (tree, inputs); i++)
gimple_asm_set_input_op (p, i, VEC_index (tree, inputs, i));
@@ -647,39 +566,8 @@ gimple_build_asm_vec (const char *string, VEC(tree,gc)* inputs,
for (i = 0; i < VEC_length (tree, clobbers); i++)
gimple_asm_set_clobber_op (p, i, VEC_index (tree, clobbers, i));
- return p;
-}
-
-/* Build a GIMPLE_ASM statement.
-
- STRING is the assembly code.
- NINPUT is the number of register inputs.
- NOUTPUT is the number of register outputs.
- NCLOBBERS is the number of clobbered registers.
- ... are trees for each input, output and clobbered register. */
-
-gimple
-gimple_build_asm (const char *string, unsigned ninputs, unsigned noutputs,
- unsigned nclobbers, ...)
-{
- gimple p;
- unsigned i;
- va_list ap;
-
- p = gimple_build_asm_1 (string, ninputs, noutputs, nclobbers);
-
- va_start (ap, nclobbers);
-
- for (i = 0; i < ninputs; i++)
- gimple_asm_set_input_op (p, i, va_arg (ap, tree));
-
- for (i = 0; i < noutputs; i++)
- gimple_asm_set_output_op (p, i, va_arg (ap, tree));
-
- for (i = 0; i < nclobbers; i++)
- gimple_asm_set_clobber_op (p, i, va_arg (ap, tree));
-
- va_end (ap);
+ for (i = 0; i < VEC_length (tree, labels); i++)
+ gimple_asm_set_label_op (p, i, VEC_index (tree, labels, i));
return p;
}
@@ -716,6 +604,20 @@ gimple_build_eh_filter (tree types, gimple_seq failure)
return p;
}
+/* Build a GIMPLE_EH_MUST_NOT_THROW statement. */
+
+gimple
+gimple_build_eh_must_not_throw (tree decl)
+{
+ gimple p = gimple_alloc (GIMPLE_EH_MUST_NOT_THROW, 1);
+
+ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
+ gcc_assert (flags_from_decl_or_type (decl) & ECF_NORETURN);
+ p->gimple_eh_mnt.fndecl = decl;
+
+ return p;
+}
+
/* Build a GIMPLE_TRY statement.
EVAL is the expression to evaluate.
@@ -755,16 +657,13 @@ gimple_build_wce (gimple_seq cleanup)
}
-/* Build a GIMPLE_RESX statement.
-
- REGION is the region number from which this resx causes control flow to
- leave. */
+/* Build a GIMPLE_RESX statement. */
gimple
gimple_build_resx (int region)
{
- gimple p = gimple_alloc (GIMPLE_RESX, 0);
- gimple_resx_set_region (p, region);
+ gimple p = gimple_build_with_ops (GIMPLE_RESX, ERROR_MARK, 0);
+ p->gimple_eh_ctrl.region = region;
return p;
}
@@ -774,14 +673,15 @@ gimple_build_resx (int region)
NLABELS is the number of labels in the switch excluding the default.
DEFAULT_LABEL is the default label for the switch statement. */
-static inline gimple
-gimple_build_switch_1 (unsigned nlabels, tree index, tree default_label)
+gimple
+gimple_build_switch_nlabels (unsigned nlabels, tree index, tree default_label)
{
/* nlabels + 1 default label + 1 index. */
gimple p = gimple_build_with_ops (GIMPLE_SWITCH, ERROR_MARK,
- nlabels + 1 + 1);
+ 1 + (default_label != NULL) + nlabels);
gimple_switch_set_index (p, index);
- gimple_switch_set_default_label (p, default_label);
+ if (default_label)
+ gimple_switch_set_default_label (p, default_label);
return p;
}
@@ -796,15 +696,14 @@ gimple
gimple_build_switch (unsigned nlabels, tree index, tree default_label, ...)
{
va_list al;
- unsigned i;
- gimple p;
-
- p = gimple_build_switch_1 (nlabels, index, default_label);
+ unsigned i, offset;
+ gimple p = gimple_build_switch_nlabels (nlabels, index, default_label);
/* Store the rest of the labels. */
va_start (al, default_label);
- for (i = 1; i <= nlabels; i++)
- gimple_switch_set_label (p, i, va_arg (al, tree));
+ offset = (default_label != NULL);
+ for (i = 0; i < nlabels; i++)
+ gimple_switch_set_label (p, i + offset, va_arg (al, tree));
va_end (al);
return p;
@@ -820,18 +719,26 @@ gimple_build_switch (unsigned nlabels, tree index, tree default_label, ...)
gimple
gimple_build_switch_vec (tree index, tree default_label, VEC(tree, heap) *args)
{
- unsigned i;
- unsigned nlabels = VEC_length (tree, args);
- gimple p = gimple_build_switch_1 (nlabels, index, default_label);
+ unsigned i, offset, nlabels = VEC_length (tree, args);
+ gimple p = gimple_build_switch_nlabels (nlabels, index, default_label);
- /* Put labels in labels[1 - (nlabels + 1)].
- Default label is in labels[0]. */
- for (i = 1; i <= nlabels; i++)
- gimple_switch_set_label (p, i, VEC_index (tree, args, i - 1));
+ /* Copy the labels from the vector to the switch statement. */
+ offset = (default_label != NULL);
+ for (i = 0; i < nlabels; i++)
+ gimple_switch_set_label (p, i + offset, VEC_index (tree, args, i));
return p;
}
+/* Build a GIMPLE_EH_DISPATCH statement. */
+
+gimple
+gimple_build_eh_dispatch (int region)
+{
+ gimple p = gimple_build_with_ops (GIMPLE_EH_DISPATCH, ERROR_MARK, 0);
+ p->gimple_eh_ctrl.region = region;
+ return p;
+}
/* Build a new GIMPLE_DEBUG_BIND statement.
@@ -1103,15 +1010,6 @@ gimple_build_predict (enum br_predictor predictor, enum prediction outcome)
return p;
}
-/* Return which gimple structure is used by T. The enums here are defined
- in gsstruct.def. */
-
-enum gimple_statement_structure_enum
-gimple_statement_structure (gimple gs)
-{
- return gss_for_code (gimple_code (gs));
-}
-
#if defined ENABLE_GIMPLE_CHECKING
/* Complain of a gimple type mismatch and die. */
@@ -1309,10 +1207,10 @@ static tree
walk_gimple_asm (gimple stmt, walk_tree_fn callback_op,
struct walk_stmt_info *wi)
{
- tree ret;
+ tree ret, op;
unsigned noutputs;
const char **oconstraints;
- unsigned i;
+ unsigned i, n;
const char *constraint;
bool allows_mem, allows_reg, is_inout;
@@ -1324,7 +1222,7 @@ walk_gimple_asm (gimple stmt, walk_tree_fn callback_op,
for (i = 0; i < noutputs; i++)
{
- tree op = gimple_asm_output_op (stmt, i);
+ op = gimple_asm_output_op (stmt, i);
constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
oconstraints[i] = constraint;
parse_output_constraint (&constraint, i, 0, 0, &allows_mem, &allows_reg,
@@ -1336,18 +1234,19 @@ walk_gimple_asm (gimple stmt, walk_tree_fn callback_op,
return ret;
}
- for (i = 0; i < gimple_asm_ninputs (stmt); i++)
+ n = gimple_asm_ninputs (stmt);
+ for (i = 0; i < n; i++)
{
- tree op = gimple_asm_input_op (stmt, i);
+ op = gimple_asm_input_op (stmt, i);
constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
parse_input_constraint (&constraint, 0, 0, noutputs, 0,
oconstraints, &allows_mem, &allows_reg);
if (wi)
- wi->val_only = (allows_reg || !allows_mem);
-
- /* Although input "m" is not really a LHS, we need a lvalue. */
- if (wi)
- wi->is_lhs = !wi->val_only;
+ {
+ wi->val_only = (allows_reg || !allows_mem);
+ /* Although input "m" is not really a LHS, we need a lvalue. */
+ wi->is_lhs = !wi->val_only;
+ }
ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
if (ret)
return ret;
@@ -1359,6 +1258,15 @@ walk_gimple_asm (gimple stmt, walk_tree_fn callback_op,
wi->val_only = true;
}
+ n = gimple_asm_nlabels (stmt);
+ for (i = 0; i < n; i++)
+ {
+ op = gimple_asm_label_op (stmt, i);
+ ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
+ if (ret)
+ return ret;
+ }
+
return NULL_TREE;
}
@@ -2492,9 +2400,7 @@ get_gimple_rhs_num_ops (enum tree_code code)
|| (SYM) == ASSERT_EXPR \
|| (SYM) == ADDR_EXPR \
|| (SYM) == WITH_SIZE_EXPR \
- || (SYM) == EXC_PTR_EXPR \
|| (SYM) == SSA_NAME \
- || (SYM) == FILTER_EXPR \
|| (SYM) == POLYNOMIAL_CHREC \
|| (SYM) == DOT_PROD_EXPR \
|| (SYM) == VEC_COND_EXPR \
@@ -2756,7 +2662,6 @@ is_gimple_stmt (tree t)
case EH_FILTER_EXPR:
case CATCH_EXPR:
case ASM_EXPR:
- case RESX_EXPR:
case STATEMENT_LIST:
case OMP_PARALLEL:
case OMP_FOR:
@@ -2882,11 +2787,6 @@ is_gimple_val (tree t)
&& !is_gimple_reg (t))
return false;
- /* FIXME make these decls. That can happen only when we expose the
- entire landing-pad construct at the tree level. */
- if (TREE_CODE (t) == EXC_PTR_EXPR || TREE_CODE (t) == FILTER_EXPR)
- return true;
-
return (is_gimple_variable (t) || is_gimple_min_invariant (t));
}
diff --git a/gcc/gimple.def b/gcc/gimple.def
index 716f6e2acbb..d736dd719cb 100644
--- a/gcc/gimple.def
+++ b/gcc/gimple.def
@@ -1,6 +1,6 @@
/* This file contains the definitions of the GIMPLE IR tuples used in GCC.
- Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by Aldy Hernandez <aldyh@redhat.com>
This file is part of GCC.
@@ -20,19 +20,11 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* The format of this file is
- DEFGSCODE(GIMPLE_symbol, printable name, structure).
+ DEFGSCODE(GIMPLE_symbol, printable name, GSS_symbol). */
- Where symbol is the enumeration name without the ``GIMPLE_''.
- The argument STRUCTURE is used to compute offsets into each of the
- tuple structures that contain operands. Since vector operands
- are at different offsets depending on the particular structure
- used, these offsets are computed at compile time for efficient
- lookup at runtime. See gimple_ops().
-
- If a code does not use operand vectors, STRUCTURE should be NULL. */
/* Error marker. This is used in similar ways as ERROR_MARK in tree.def. */
-DEFGSCODE(GIMPLE_ERROR_MARK, "gimple_error_mark", NULL)
+DEFGSCODE(GIMPLE_ERROR_MARK, "gimple_error_mark", GSS_BASE)
/* IMPORTANT. Do not rearrange the codes between GIMPLE_COND and
GIMPLE_RETURN. The ordering is exposed by gimple_has_ops calls.
@@ -51,18 +43,18 @@ DEFGSCODE(GIMPLE_ERROR_MARK, "gimple_error_mark", NULL)
TRUE_LABEL and FALSE_LABEL are the LABEL_DECL nodes used as the
jump target for the comparison. */
-DEFGSCODE(GIMPLE_COND, "gimple_cond", struct gimple_statement_with_ops)
+DEFGSCODE(GIMPLE_COND, "gimple_cond", GSS_WITH_OPS)
/* GIMPLE_DEBUG represents a debug statement. */
-DEFGSCODE(GIMPLE_DEBUG, "gimple_debug", struct gimple_statement_with_ops)
+DEFGSCODE(GIMPLE_DEBUG, "gimple_debug", GSS_WITH_OPS)
/* GIMPLE_GOTO <TARGET> represents unconditional jumps.
TARGET is a LABEL_DECL or an expression node for computed GOTOs. */
-DEFGSCODE(GIMPLE_GOTO, "gimple_goto", struct gimple_statement_with_ops)
+DEFGSCODE(GIMPLE_GOTO, "gimple_goto", GSS_WITH_OPS)
/* GIMPLE_LABEL <LABEL> represents label statements. LABEL is a
LABEL_DECL representing a jump target. */
-DEFGSCODE(GIMPLE_LABEL, "gimple_label", struct gimple_statement_with_ops)
+DEFGSCODE(GIMPLE_LABEL, "gimple_label", GSS_WITH_OPS)
/* GIMPLE_SWITCH <INDEX, DEFAULT_LAB, LAB1, ..., LABN> represents the
multiway branch:
@@ -79,7 +71,7 @@ DEFGSCODE(GIMPLE_LABEL, "gimple_label", struct gimple_statement_with_ops)
DEFAULT_LAB, LAB1 ... LABN are the tree nodes representing case labels.
They must be CASE_LABEL_EXPR nodes. */
-DEFGSCODE(GIMPLE_SWITCH, "gimple_switch", struct gimple_statement_with_ops)
+DEFGSCODE(GIMPLE_SWITCH, "gimple_switch", GSS_WITH_OPS)
/* IMPORTANT.
@@ -106,8 +98,7 @@ DEFGSCODE(GIMPLE_SWITCH, "gimple_switch", struct gimple_statement_with_ops)
RHS2 is the second operand on the RHS of the assignment. It must be a tree
node accepted by is_gimple_val. This argument exists only if SUBCODE is
of class GIMPLE_BINARY_RHS. */
-DEFGSCODE(GIMPLE_ASSIGN, "gimple_assign",
- struct gimple_statement_with_memory_ops)
+DEFGSCODE(GIMPLE_ASSIGN, "gimple_assign", GSS_WITH_MEM_OPS)
/* GIMPLE_ASM <STRING, I1, ..., IN, O1, ... OM, C1, ..., CP>
represents inline assembly statements.
@@ -115,8 +106,9 @@ DEFGSCODE(GIMPLE_ASSIGN, "gimple_assign",
STRING is the string containing the assembly statements.
I1 ... IN are the N input operands.
O1 ... OM are the M output operands.
- C1 ... CP are the P clobber operands. */
-DEFGSCODE(GIMPLE_ASM, "gimple_asm", struct gimple_statement_asm)
+ C1 ... CP are the P clobber operands.
+ L1 ... LQ are the Q label operands. */
+DEFGSCODE(GIMPLE_ASM, "gimple_asm", GSS_ASM)
/* GIMPLE_CALL <FN, LHS, ARG1, ..., ARGN[, CHAIN]> represents function
calls.
@@ -130,31 +122,41 @@ DEFGSCODE(GIMPLE_ASM, "gimple_asm", struct gimple_statement_asm)
is_gimple_operand.
CHAIN is the optional static chain link for nested functions. */
-DEFGSCODE(GIMPLE_CALL, "gimple_call",
- struct gimple_statement_with_memory_ops)
+DEFGSCODE(GIMPLE_CALL, "gimple_call", GSS_WITH_MEM_OPS)
/* GIMPLE_RETURN <RETVAL> represents return statements.
RETVAL is the value to return or NULL. If a value is returned it
must be accepted by is_gimple_operand. */
-DEFGSCODE(GIMPLE_RETURN, "gimple_return",
- struct gimple_statement_with_memory_ops)
+DEFGSCODE(GIMPLE_RETURN, "gimple_return", GSS_WITH_MEM_OPS)
/* GIMPLE_BIND <VARS, BLOCK, BODY> represents a lexical scope.
VARS is the set of variables declared in that scope.
BLOCK is the symbol binding block used for debug information.
BODY is the sequence of statements in the scope. */
-DEFGSCODE(GIMPLE_BIND, "gimple_bind", NULL)
+DEFGSCODE(GIMPLE_BIND, "gimple_bind", GSS_BIND)
/* GIMPLE_CATCH <TYPES, HANDLER> represents a typed exception handler.
TYPES is the type (or list of types) handled. HANDLER is the
sequence of statements that handle these types. */
-DEFGSCODE(GIMPLE_CATCH, "gimple_catch", NULL)
+DEFGSCODE(GIMPLE_CATCH, "gimple_catch", GSS_CATCH)
/* GIMPLE_EH_FILTER <TYPES, FAILURE> represents an exception
specification. TYPES is a list of allowed types and FAILURE is the
sequence of statements to execute on failure. */
-DEFGSCODE(GIMPLE_EH_FILTER, "gimple_eh_filter", NULL)
+DEFGSCODE(GIMPLE_EH_FILTER, "gimple_eh_filter", GSS_EH_FILTER)
+
+/* GIMPLE_EH_MUST_NOT_THROW <DECL> represents an exception barrier.
+ DECL is a noreturn function decl taking no arguments that will
+ be invoked if an exception propagates to this point. */
+DEFGSCODE(GIMPLE_EH_MUST_NOT_THROW, "gimple_eh_must_not_throw", GSS_EH_MNT)
+
+/* GIMPLE_RESX resumes execution after an exception. */
+DEFGSCODE(GIMPLE_RESX, "gimple_resx", GSS_EH_CTRL)
+
+/* GIMPLE_EH_DISPATCH demultiplexes an exception edge based on
+ the FILTER argument. */
+DEFGSCODE(GIMPLE_EH_DISPATCH, "gimple_eh_dispatch", GSS_EH_CTRL)
/* GIMPLE_PHI <RESULT, ARG1, ..., ARGN> represents the PHI node
@@ -166,11 +168,7 @@ DEFGSCODE(GIMPLE_EH_FILTER, "gimple_eh_filter", NULL)
exactly the same as the number of incoming edges to the basic block
holding the PHI node. Every argument is either an SSA name or a
tree node of class tcc_constant. */
-DEFGSCODE(GIMPLE_PHI, "gimple_phi", NULL)
-
-/* GIMPLE_RESX <REGION> resumes execution after an exception.
- REGION is the region number being left. */
-DEFGSCODE(GIMPLE_RESX, "gimple_resx", NULL)
+DEFGSCODE(GIMPLE_PHI, "gimple_phi", GSS_PHI)
/* GIMPLE_TRY <TRY_KIND, EVAL, CLEANUP>
represents a try/catch or a try/finally statement.
@@ -185,10 +183,10 @@ DEFGSCODE(GIMPLE_RESX, "gimple_resx", NULL)
GIMPLE_TRY_FINALLY, CLEANUP is always executed after executing EVAL
(regardless of whether EVAL finished normally, or jumped out or an
exception was thrown). */
-DEFGSCODE(GIMPLE_TRY, "gimple_try", NULL)
+DEFGSCODE(GIMPLE_TRY, "gimple_try", GSS_TRY)
/* GIMPLE_NOP represents the "do nothing" statement. */
-DEFGSCODE(GIMPLE_NOP, "gimple_nop", NULL)
+DEFGSCODE(GIMPLE_NOP, "gimple_nop", GSS_BASE)
/* IMPORTANT.
@@ -206,12 +204,14 @@ DEFGSCODE(GIMPLE_NOP, "gimple_nop", NULL)
GIMPLE_OMP_LOAD (tmp, mem)
val = some computations involving tmp;
GIMPLE_OMP_STORE (val). */
-DEFGSCODE(GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load", NULL)
-DEFGSCODE(GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store", NULL)
+DEFGSCODE(GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load",
+ GSS_OMP_ATOMIC_LOAD)
+DEFGSCODE(GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store",
+ GSS_OMP_ATOMIC_STORE)
/* GIMPLE_OMP_CONTINUE marks the location of the loop or sections
iteration in partially lowered OpenMP code. */
-DEFGSCODE(GIMPLE_OMP_CONTINUE, "gimple_omp_continue", NULL)
+DEFGSCODE(GIMPLE_OMP_CONTINUE, "gimple_omp_continue", GSS_OMP_CONTINUE)
/* GIMPLE_OMP_CRITICAL <NAME, BODY> represents
@@ -219,7 +219,7 @@ DEFGSCODE(GIMPLE_OMP_CONTINUE, "gimple_omp_continue", NULL)
NAME is the name given to the critical section.
BODY is the sequence of statements that are inside the critical section. */
-DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical", NULL)
+DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical", GSS_OMP_CRITICAL)
/* GIMPLE_OMP_FOR <BODY, CLAUSES, INDEX, INITIAL, FINAL, COND, INCR, PRE_BODY>
represents
@@ -256,15 +256,15 @@ DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical", NULL)
expressions that are evaluated without any synchronization.
The evaluation order, frequency of evaluation and side-effects are
unspecified by the standard. */
-DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_for", NULL)
+DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_for", GSS_OMP_FOR)
/* GIMPLE_OMP_MASTER <BODY> represents #pragma omp master.
BODY is the sequence of statements to execute in the master section. */
-DEFGSCODE(GIMPLE_OMP_MASTER, "gimple_omp_master", NULL)
+DEFGSCODE(GIMPLE_OMP_MASTER, "gimple_omp_master", GSS_OMP)
/* GIMPLE_OMP_ORDERED <BODY> represents #pragma omp ordered.
BODY is the sequence of statements to execute in the ordered section. */
-DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", NULL)
+DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP)
/* GIMPLE_OMP_PARALLEL <BODY, CLAUSES, CHILD_FN, DATA_ARG> represents
@@ -282,7 +282,7 @@ DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", NULL)
DATA_ARG is a local variable in the parent function containing data
to be shared with CHILD_FN. This is used to implement all the data
sharing clauses. */
-DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", NULL)
+DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL)
/* GIMPLE_OMP_TASK <BODY, CLAUSES, CHILD_FN, DATA_ARG, COPY_FN,
ARG_SIZE, ARG_ALIGN> represents
@@ -308,14 +308,14 @@ DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", NULL)
ARG_SIZE and ARG_ALIGN are the size and alignment of the incoming
data area allocated by GOMP_task and passed to CHILD_FN. */
-DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", NULL)
+DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", GSS_OMP_TASK)
/* OMP_RETURN marks the end of an OpenMP directive. */
-DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", NULL)
+DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_BASE)
/* OMP_SECTION <BODY> represents #pragma omp section.
BODY is the sequence of statements in the section body. */
-DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", NULL)
+DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", GSS_OMP)
/* OMP_SECTIONS <BODY, CLAUSES, CONTROL> represents #pragma omp sections.
@@ -323,28 +323,28 @@ DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", NULL)
CLAUSES is a TREE_LIST node holding the list of associated clauses.
CONTROL is a VAR_DECL used for deciding which of the sections
to execute. */
-DEFGSCODE(GIMPLE_OMP_SECTIONS, "gimple_omp_sections", NULL)
+DEFGSCODE(GIMPLE_OMP_SECTIONS, "gimple_omp_sections", GSS_OMP_SECTIONS)
/* GIMPLE_OMP_SECTIONS_SWITCH is a marker placed immediately after
OMP_SECTIONS. It represents the GIMPLE_SWITCH used to decide which
branch is taken. */
-DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", NULL)
+DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE)
/* GIMPLE_OMP_SINGLE <BODY, CLAUSES> represents #pragma omp single
BODY is the sequence of statements inside the single section.
CLAUSES is a TREE_LIST node holding the associated clauses. */
-DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", NULL)
+DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE)
/* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction.
PREDICT is one of the predictors from predict.def.
OUTCOME is NOT_TAKEN or TAKEN. */
-DEFGSCODE(GIMPLE_PREDICT, "gimple_predict", NULL)
+DEFGSCODE(GIMPLE_PREDICT, "gimple_predict", GSS_BASE)
/* This node represents a cleanup expression. It is ONLY USED INTERNALLY
by the gimplifier as a placeholder for cleanups, and its uses will be
cleaned up by the time gimplification is done.
This tuple should not exist outside of the gimplifier proper. */
-DEFGSCODE(GIMPLE_WITH_CLEANUP_EXPR, "gimple_with_cleanup_expr", NULL)
+DEFGSCODE(GIMPLE_WITH_CLEANUP_EXPR, "gimple_with_cleanup_expr", GSS_WCE)
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 97d2c3789ac..e1e3b655b7d 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -444,9 +444,6 @@ struct GTY(()) gimple_statement_eh_filter {
/* [ WORD 1-4 ] */
struct gimple_statement_base gsbase;
- /* Subcode: EH_FILTER_MUST_NOT_THROW. A boolean flag analogous to
- the tree counterpart. */
-
/* [ WORD 5 ]
Filter types. */
tree types;
@@ -457,6 +454,16 @@ struct GTY(()) gimple_statement_eh_filter {
};
+/* GIMPLE_EH_MUST_NOT_THROW */
+
+struct GTY(()) gimple_statement_eh_mnt {
+ /* [ WORD 1-4 ] */
+ struct gimple_statement_base gsbase;
+
+ /* [ WORD 5 ] Abort function decl. */
+ tree fndecl;
+};
+
/* GIMPLE_PHI */
struct GTY(()) gimple_statement_phi {
@@ -475,9 +482,10 @@ struct GTY(()) gimple_statement_phi {
};
-/* GIMPLE_RESX */
+/* GIMPLE_RESX, GIMPLE_EH_DISPATCH */
-struct GTY(()) gimple_statement_resx {
+struct GTY(()) gimple_statement_eh_ctrl
+{
/* [ WORD 1-4 ] */
struct gimple_statement_base gsbase;
@@ -545,10 +553,11 @@ struct GTY(()) gimple_statement_asm
const char *string;
/* [ WORD 10 ]
- Number of inputs, outputs and clobbers. */
+ Number of inputs, outputs, clobbers, labels. */
unsigned char ni;
unsigned char no;
- unsigned short nc;
+ unsigned char nc;
+ unsigned char nl;
/* [ WORD 11 ]
Operand vector. NOTE! This must always be the last field
@@ -714,12 +723,12 @@ struct GTY(()) gimple_statement_omp_atomic_store {
tree val;
};
+#define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) SYM,
enum gimple_statement_structure_enum {
-#define DEFGSSTRUCT(SYM, STRING) SYM,
#include "gsstruct.def"
-#undef DEFGSSTRUCT
LAST_GSS_ENUM
};
+#undef DEFGSSTRUCT
/* Define the overall contents of a gimple tuple. It may be any of the
@@ -733,8 +742,9 @@ union GTY ((desc ("gimple_statement_structure (&%h)"))) gimple_statement_d {
struct gimple_statement_bind GTY ((tag ("GSS_BIND"))) gimple_bind;
struct gimple_statement_catch GTY ((tag ("GSS_CATCH"))) gimple_catch;
struct gimple_statement_eh_filter GTY ((tag ("GSS_EH_FILTER"))) gimple_eh_filter;
+ struct gimple_statement_eh_mnt GTY ((tag ("GSS_EH_MNT"))) gimple_eh_mnt;
struct gimple_statement_phi GTY ((tag ("GSS_PHI"))) gimple_phi;
- struct gimple_statement_resx GTY ((tag ("GSS_RESX"))) gimple_resx;
+ struct gimple_statement_eh_ctrl GTY ((tag ("GSS_EH_CTRL"))) gimple_eh_ctrl;
struct gimple_statement_try GTY ((tag ("GSS_TRY"))) gimple_try;
struct gimple_statement_wce GTY ((tag ("GSS_WCE"))) gimple_wce;
struct gimple_statement_asm GTY ((tag ("GSS_ASM"))) gimple_asm;
@@ -750,6 +760,14 @@ union GTY ((desc ("gimple_statement_structure (&%h)"))) gimple_statement_d {
};
/* In gimple.c. */
+
+/* Offset in bytes to the location of the operand vector.
+ Zero if there is no operand vector for this tuple structure. */
+extern size_t const gimple_ops_offset_[];
+
+/* Map GIMPLE codes to GSS codes. */
+extern enum gimple_statement_structure_enum const gss_for_code_[];
+
gimple gimple_build_return (tree);
gimple gimple_build_assign_stat (tree, tree MEM_STAT_DECL);
@@ -775,14 +793,16 @@ gimple gimple_build_label (tree label);
gimple gimple_build_goto (tree dest);
gimple gimple_build_nop (void);
gimple gimple_build_bind (tree, gimple_seq, tree);
-gimple gimple_build_asm (const char *, unsigned, unsigned, unsigned, ...);
gimple gimple_build_asm_vec (const char *, VEC(tree,gc) *, VEC(tree,gc) *,
- VEC(tree,gc) *);
+ VEC(tree,gc) *, VEC(tree,gc) *);
gimple gimple_build_catch (tree, gimple_seq);
gimple gimple_build_eh_filter (tree, gimple_seq);
+gimple gimple_build_eh_must_not_throw (tree);
gimple gimple_build_try (gimple_seq, gimple_seq, enum gimple_try_flags);
gimple gimple_build_wce (gimple_seq);
gimple gimple_build_resx (int);
+gimple gimple_build_eh_dispatch (int);
+gimple gimple_build_switch_nlabels (unsigned, tree, tree);
gimple gimple_build_switch (unsigned, tree, tree, ...);
gimple gimple_build_switch_vec (tree, tree, VEC(tree,heap) *);
gimple gimple_build_omp_parallel (gimple_seq, tree, tree, tree);
@@ -801,7 +821,6 @@ gimple gimple_build_cdt (tree, tree);
gimple gimple_build_omp_atomic_load (tree, tree);
gimple gimple_build_omp_atomic_store (tree);
gimple gimple_build_predict (enum br_predictor, enum prediction);
-enum gimple_statement_structure_enum gimple_statement_structure (gimple);
enum gimple_statement_structure_enum gss_for_assign (enum tree_code);
void sort_case_labels (VEC(tree,heap) *);
void gimple_set_body (tree, gimple_seq);
@@ -1023,6 +1042,25 @@ gimple_code (const_gimple g)
}
+/* Return the GSS code used by a GIMPLE code. */
+
+static inline enum gimple_statement_structure_enum
+gss_for_code (enum gimple_code code)
+{
+ gcc_assert ((unsigned int)code < LAST_AND_UNUSED_GIMPLE_CODE);
+ return gss_for_code_[code];
+}
+
+
+/* Return which GSS code is used by GS. */
+
+static inline enum gimple_statement_structure_enum
+gimple_statement_structure (gimple gs)
+{
+ return gss_for_code (gimple_code (gs));
+}
+
+
/* Return true if statement G has sub-statements. This is only true for
High GIMPLE statements. */
@@ -1557,16 +1595,15 @@ gimple_set_num_ops (gimple gs, unsigned num_ops)
static inline tree *
gimple_ops (gimple gs)
{
- /* Offset in bytes to the location of the operand vector in every
- tuple structure. Defined in gimple.c */
- extern size_t const gimple_ops_offset_[];
-
- if (!gimple_has_ops (gs))
- return NULL;
+ size_t off;
/* All the tuples have their operand vector at the very bottom
- of the structure. */
- return ((tree *) ((char *) gs + gimple_ops_offset_[gimple_code (gs)]));
+ of the structure. Note that those structures that do not
+ have an operand vector have a zero offset. */
+ off = gimple_ops_offset_[gimple_statement_structure (gs)];
+ gcc_assert (off != 0);
+
+ return (tree *) ((char *) gs + off);
}
@@ -2577,6 +2614,14 @@ gimple_asm_nclobbers (const_gimple gs)
return gs->gimple_asm.nc;
}
+/* Return the number of label operands for GIMPLE_ASM GS. */
+
+static inline unsigned
+gimple_asm_nlabels (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ return gs->gimple_asm.nl;
+}
/* Return input operand INDEX of GIMPLE_ASM GS. */
@@ -2666,6 +2711,26 @@ gimple_asm_set_clobber_op (gimple gs, unsigned index, tree clobber_op)
gimple_set_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.no, clobber_op);
}
+/* Return label operand INDEX of GIMPLE_ASM GS. */
+
+static inline tree
+gimple_asm_label_op (const_gimple gs, unsigned index)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ gcc_assert (index <= gs->gimple_asm.nl);
+ return gimple_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.nc);
+}
+
+/* Set LABEL_OP to be label operand INDEX in GIMPLE_ASM GS. */
+
+static inline void
+gimple_asm_set_label_op (gimple gs, unsigned index, tree label_op)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ gcc_assert (index <= gs->gimple_asm.nl);
+ gcc_assert (TREE_CODE (label_op) == TREE_LIST);
+ gimple_set_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.nc, label_op);
+}
/* Return the string representing the assembly instruction in
GIMPLE_ASM GS. */
@@ -2838,26 +2903,15 @@ gimple_eh_filter_set_failure (gimple gs, gimple_seq failure)
gs->gimple_eh_filter.failure = failure;
}
-/* Return the EH_FILTER_MUST_NOT_THROW flag. */
+/* Get the function decl to be called by the MUST_NOT_THROW region. */
-static inline bool
-
-gimple_eh_filter_must_not_throw (gimple gs)
-{
- GIMPLE_CHECK (gs, GIMPLE_EH_FILTER);
- return gs->gsbase.subcode != 0;
-}
-
-/* Set the EH_FILTER_MUST_NOT_THROW flag to the value MNTP. */
-
-static inline void
-gimple_eh_filter_set_must_not_throw (gimple gs, bool mntp)
+static inline tree
+gimple_eh_must_not_throw_fndecl (gimple gs)
{
- GIMPLE_CHECK (gs, GIMPLE_EH_FILTER);
- gs->gsbase.subcode = (unsigned int) mntp;
+ GIMPLE_CHECK (gs, GIMPLE_EH_MUST_NOT_THROW);
+ return gs->gimple_eh_mnt.fndecl;
}
-
/* GIMPLE_TRY accessors. */
/* Return the kind of try block represented by GIMPLE_TRY GS. This is
@@ -3067,7 +3121,7 @@ static inline int
gimple_resx_region (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_RESX);
- return gs->gimple_resx.region;
+ return gs->gimple_eh_ctrl.region;
}
/* Set REGION to be the region number for GIMPLE_RESX GS. */
@@ -3076,9 +3130,26 @@ static inline void
gimple_resx_set_region (gimple gs, int region)
{
GIMPLE_CHECK (gs, GIMPLE_RESX);
- gs->gimple_resx.region = region;
+ gs->gimple_eh_ctrl.region = region;
}
+/* Return the region number for GIMPLE_EH_DISPATCH GS. */
+
+static inline int
+gimple_eh_dispatch_region (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_EH_DISPATCH);
+ return gs->gimple_eh_ctrl.region;
+}
+
+/* Set REGION to be the region number for GIMPLE_EH_DISPATCH GS. */
+
+static inline void
+gimple_eh_dispatch_set_region (gimple gs, int region)
+{
+ GIMPLE_CHECK (gs, GIMPLE_EH_DISPATCH);
+ gs->gimple_eh_ctrl.region = region;
+}
/* Return the number of labels associated with the switch statement GS. */
@@ -4190,23 +4261,32 @@ gimple_return_set_retval (gimple gs, tree retval)
/* Returns true when the gimple statment STMT is any of the OpenMP types. */
+#define CASE_GIMPLE_OMP \
+ case GIMPLE_OMP_PARALLEL: \
+ case GIMPLE_OMP_TASK: \
+ case GIMPLE_OMP_FOR: \
+ case GIMPLE_OMP_SECTIONS: \
+ case GIMPLE_OMP_SECTIONS_SWITCH: \
+ case GIMPLE_OMP_SINGLE: \
+ case GIMPLE_OMP_SECTION: \
+ case GIMPLE_OMP_MASTER: \
+ case GIMPLE_OMP_ORDERED: \
+ case GIMPLE_OMP_CRITICAL: \
+ case GIMPLE_OMP_RETURN: \
+ case GIMPLE_OMP_ATOMIC_LOAD: \
+ case GIMPLE_OMP_ATOMIC_STORE: \
+ case GIMPLE_OMP_CONTINUE
+
static inline bool
is_gimple_omp (const_gimple stmt)
{
- return (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
- || gimple_code (stmt) == GIMPLE_OMP_TASK
- || gimple_code (stmt) == GIMPLE_OMP_FOR
- || gimple_code (stmt) == GIMPLE_OMP_SECTIONS
- || gimple_code (stmt) == GIMPLE_OMP_SECTIONS_SWITCH
- || gimple_code (stmt) == GIMPLE_OMP_SINGLE
- || gimple_code (stmt) == GIMPLE_OMP_SECTION
- || gimple_code (stmt) == GIMPLE_OMP_MASTER
- || gimple_code (stmt) == GIMPLE_OMP_ORDERED
- || gimple_code (stmt) == GIMPLE_OMP_CRITICAL
- || gimple_code (stmt) == GIMPLE_OMP_RETURN
- || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
- || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE
- || gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
+ switch (gimple_code (stmt))
+ {
+ CASE_GIMPLE_OMP:
+ return true;
+ default:
+ return false;
+ }
}
@@ -4219,6 +4299,14 @@ gimple_nop_p (const_gimple g)
}
+/* Return true if GS is a GIMPLE_RESX. */
+
+static inline bool
+is_gimple_resx (const_gimple gs)
+{
+ return gimple_code (gs) == GIMPLE_RESX;
+}
+
/* Return the predictor of GIMPLE_PREDICT statement GS. */
static inline enum br_predictor
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 0181814bb69..0dd277c5202 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -4775,13 +4775,14 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
VEC(tree, gc) *inputs;
VEC(tree, gc) *outputs;
VEC(tree, gc) *clobbers;
+ VEC(tree, gc) *labels;
tree link_next;
expr = *expr_p;
noutputs = list_length (ASM_OUTPUTS (expr));
oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
- inputs = outputs = clobbers = NULL;
+ inputs = outputs = clobbers = labels = NULL;
ret = GS_ALL_DONE;
link_next = NULL_TREE;
@@ -4963,13 +4964,16 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
}
for (link = ASM_CLOBBERS (expr); link; ++i, link = TREE_CHAIN (link))
- VEC_safe_push (tree, gc, clobbers, link);
+ VEC_safe_push (tree, gc, clobbers, link);
+
+ for (link = ASM_LABELS (expr); link; ++i, link = TREE_CHAIN (link))
+ VEC_safe_push (tree, gc, labels, link);
/* Do not add ASMs with errors to the gimple IL stream. */
if (ret != GS_ERROR)
{
stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
- inputs, outputs, clobbers);
+ inputs, outputs, clobbers, labels);
gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr));
gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
@@ -6655,11 +6659,6 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
ret = gimplify_decl_expr (expr_p, pre_p);
break;
- case EXC_PTR_EXPR:
- /* FIXME make this a decl. */
- ret = GS_ALL_DONE;
- break;
-
case BIND_EXPR:
ret = gimplify_bind_expr (expr_p, pre_p);
break;
@@ -6851,8 +6850,6 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p));
- gimple_eh_filter_set_must_not_throw
- (ehf, EH_FILTER_MUST_NOT_THROW (*expr_p));
gimplify_seq_add_stmt (pre_p, ehf);
ret = GS_ALL_DONE;
break;
@@ -7188,7 +7185,6 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
&& code != GOTO_EXPR
&& code != LABEL_EXPR
&& code != LOOP_EXPR
- && code != RESX_EXPR
&& code != SWITCH_EXPR
&& code != TRY_FINALLY_EXPR
&& code != OMP_CRITICAL
diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c
index ad64b8c3499..ccf539eb0dc 100644
--- a/gcc/graphite-sese-to-poly.c
+++ b/gcc/graphite-sese-to-poly.c
@@ -1654,45 +1654,26 @@ pdr_add_data_dimensions (ppl_Polyhedron_t accesses, data_reference_p dr,
{
tree ref = DR_REF (dr);
int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
- tree array_size;
- HOST_WIDE_INT elt_size;
- array_size = TYPE_SIZE (TREE_TYPE (ref));
- if (array_size == NULL_TREE
- || TREE_CODE (array_size) != INTEGER_CST)
- return;
-
- elt_size = int_cst_value (array_size);
-
- for (i = nb_subscripts - 1; i >= 0; i--)
+ for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
{
ppl_Linear_Expression_t expr;
ppl_Constraint_t cstr;
ppl_dimension_type subscript = dom_nb_dims + 1 + i;
- int size;
-
- /* 0 <= subscript */
- ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
- ppl_set_coef (expr, subscript, 1);
- ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
- ppl_Polyhedron_add_constraint (accesses, cstr);
- ppl_delete_Linear_Expression (expr);
- ppl_delete_Constraint (cstr);
+ tree low, high;
- ref = TREE_OPERAND (ref, 0);
- array_size = TYPE_SIZE (TREE_TYPE (ref));
- if (array_size == NULL_TREE
- || TREE_CODE (array_size) != INTEGER_CST)
+ if (TREE_CODE (ref) != ARRAY_REF)
break;
- /* subscript <= array_size */
- size = elt_size ? int_cst_value (array_size) / elt_size : 0;
- if (size)
+ low = array_ref_low_bound (ref);
+
+ /* subscript - low >= 0 */
+ if (host_integerp (low, 0))
{
ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
- ppl_set_coef (expr, subscript, -1);
+ ppl_set_coef (expr, subscript, 1);
- ppl_set_inhomogeneous (expr, size);
+ ppl_set_inhomogeneous (expr, -int_cst_value (low));
ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
ppl_Polyhedron_add_constraint (accesses, cstr);
@@ -1700,7 +1681,23 @@ pdr_add_data_dimensions (ppl_Polyhedron_t accesses, data_reference_p dr,
ppl_delete_Constraint (cstr);
}
- elt_size = int_cst_value (array_size);
+ high = array_ref_up_bound (ref);
+
+ /* high - subscript >= 0
+ XXX: 1-element arrays at end of structures may extend over their
+ declared size. */
+ if (high && host_integerp (high, 0))
+ {
+ ppl_new_Linear_Expression_with_dimension (&expr, accessp_nb_dims);
+ ppl_set_coef (expr, subscript, -1);
+
+ ppl_set_inhomogeneous (expr, int_cst_value (high));
+
+ ppl_new_Constraint (&cstr, expr, PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
+ ppl_Polyhedron_add_constraint (accesses, cstr);
+ ppl_delete_Linear_Expression (expr);
+ ppl_delete_Constraint (cstr);
+ }
}
}
diff --git a/gcc/gsstruct.def b/gcc/gsstruct.def
index 58f4476c25e..29cb90d913c 100644
--- a/gcc/gsstruct.def
+++ b/gcc/gsstruct.def
@@ -21,28 +21,29 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* The format of this file is
- DEFGSSTRUCT(GSS_enumeration value, printable name).
+ DEFGSSTRUCT(GSS enumeration value, structure name, has-tree-operands).
Each enum value should correspond with a single member of the union
gimple_statement_d. */
-DEFGSSTRUCT(GSS_BASE, "base")
-DEFGSSTRUCT(GSS_WITH_OPS, "with_ops")
-DEFGSSTRUCT(GSS_WITH_MEM_OPS, "with_mem_ops")
-DEFGSSTRUCT(GSS_OMP, "omp")
-DEFGSSTRUCT(GSS_BIND, "bind")
-DEFGSSTRUCT(GSS_CATCH, "catch")
-DEFGSSTRUCT(GSS_EH_FILTER, "eh_filter")
-DEFGSSTRUCT(GSS_PHI, "phi")
-DEFGSSTRUCT(GSS_RESX, "resx")
-DEFGSSTRUCT(GSS_TRY, "try")
-DEFGSSTRUCT(GSS_WCE, "with_cleanup_expression")
-DEFGSSTRUCT(GSS_ASM, "asm")
-DEFGSSTRUCT(GSS_OMP_CRITICAL, "omp_critical")
-DEFGSSTRUCT(GSS_OMP_FOR, "omp_for")
-DEFGSSTRUCT(GSS_OMP_PARALLEL, "omp_parallel")
-DEFGSSTRUCT(GSS_OMP_TASK, "omp_task")
-DEFGSSTRUCT(GSS_OMP_SECTIONS, "sections")
-DEFGSSTRUCT(GSS_OMP_SINGLE, "single")
-DEFGSSTRUCT(GSS_OMP_CONTINUE, "omp_continue")
-DEFGSSTRUCT(GSS_OMP_ATOMIC_LOAD, "omp_atomic_load")
-DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE, "omp_atomic_store")
+DEFGSSTRUCT(GSS_BASE, gimple_statement_base, false)
+DEFGSSTRUCT(GSS_WITH_OPS, gimple_statement_with_ops, true)
+DEFGSSTRUCT(GSS_WITH_MEM_OPS, gimple_statement_with_memory_ops, true)
+DEFGSSTRUCT(GSS_ASM, gimple_statement_asm, true)
+DEFGSSTRUCT(GSS_BIND, gimple_statement_bind, false)
+DEFGSSTRUCT(GSS_PHI, gimple_statement_phi, false)
+DEFGSSTRUCT(GSS_TRY, gimple_statement_try, false)
+DEFGSSTRUCT(GSS_CATCH, gimple_statement_catch, false)
+DEFGSSTRUCT(GSS_EH_FILTER, gimple_statement_eh_filter, false)
+DEFGSSTRUCT(GSS_EH_MNT, gimple_statement_eh_mnt, false)
+DEFGSSTRUCT(GSS_EH_CTRL, gimple_statement_eh_ctrl, false)
+DEFGSSTRUCT(GSS_WCE, gimple_statement_wce, false)
+DEFGSSTRUCT(GSS_OMP, gimple_statement_omp, false)
+DEFGSSTRUCT(GSS_OMP_CRITICAL, gimple_statement_omp_critical, false)
+DEFGSSTRUCT(GSS_OMP_FOR, gimple_statement_omp_for, false)
+DEFGSSTRUCT(GSS_OMP_PARALLEL, gimple_statement_omp_parallel, false)
+DEFGSSTRUCT(GSS_OMP_TASK, gimple_statement_omp_task, false)
+DEFGSSTRUCT(GSS_OMP_SECTIONS, gimple_statement_omp_sections, false)
+DEFGSSTRUCT(GSS_OMP_SINGLE, gimple_statement_omp_single, false)
+DEFGSSTRUCT(GSS_OMP_CONTINUE, gimple_statement_omp_continue, false)
+DEFGSSTRUCT(GSS_OMP_ATOMIC_LOAD, gimple_statement_omp_atomic_load, false)
+DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store, false)
diff --git a/gcc/integrate.c b/gcc/integrate.c
index 30ef854ffff..d92cec5f67e 100644
--- a/gcc/integrate.c
+++ b/gcc/integrate.c
@@ -167,6 +167,7 @@ set_block_abstract_flags (tree stmt, int setting)
{
tree local_decl;
tree subblock;
+ unsigned int i;
BLOCK_ABSTRACT (stmt) = setting;
@@ -175,6 +176,14 @@ set_block_abstract_flags (tree stmt, int setting)
local_decl = TREE_CHAIN (local_decl))
set_decl_abstract_flags (local_decl, setting);
+ for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++)
+ {
+ local_decl = BLOCK_NONLOCALIZED_VAR (stmt, i);
+ if ((TREE_CODE (local_decl) == VAR_DECL && !TREE_STATIC (local_decl))
+ || TREE_CODE (local_decl) == PARM_DECL)
+ set_decl_abstract_flags (local_decl, setting);
+ }
+
for (subblock = BLOCK_SUBBLOCKS (stmt);
subblock != NULL_TREE;
subblock = BLOCK_CHAIN (subblock))
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 2c0b89b51f2..fa82f181e3a 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -1252,7 +1252,7 @@ cgraph_decide_inlining (void)
continue;
if (!tree_can_inline_p (e))
continue;
- if (dbg_cnt (inl))
+ if (!dbg_cnt (inl))
continue;
if (cgraph_mark_inline_edge (e, true, NULL))
@@ -1848,12 +1848,10 @@ estimate_function_body_sizes (struct cgraph_node *node)
tree arg;
int freq;
tree funtype = TREE_TYPE (node->decl);
- bitmap must_not_throw = must_not_throw_labels ();
if (dump_file)
- {
- fprintf (dump_file, "Analyzing function body size: %s\n", cgraph_node_name (node));
- }
+ fprintf (dump_file, "Analyzing function body size: %s\n",
+ cgraph_node_name (node));
gcc_assert (my_function && my_function->cfg);
FOR_EACH_BB_FN (bb, my_function)
@@ -1861,25 +1859,15 @@ estimate_function_body_sizes (struct cgraph_node *node)
freq = compute_call_stmt_bb_frequency (node->decl, bb);
for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
{
- int this_size = estimate_num_insns (gsi_stmt (bsi), &eni_size_weights);
- int this_time = estimate_num_insns (gsi_stmt (bsi), &eni_time_weights);
-
- /* MUST_NOT_THROW is usually handled by runtime calling terminate and stopping
- stacking unwinding. However when there is local cleanup that can resume
- to MUST_NOT_THROW then we generate explicit handler containing
- std::terminate () call.
-
- Because inlining of function can introduce new cleanup region, prior
- inlining we keep std::terinate () calls for every MUST_NOT_THROW containing
- function call. Wast majority of these will be eliminated after inlining
- and crossjumping will inify possible duplicated calls. So ignore
- the handlers for function body estimates. */
- if (gimple_code (gsi_stmt (bsi)) == GIMPLE_LABEL
- && bitmap_bit_p (must_not_throw,
- LABEL_DECL_UID (gimple_label_label (gsi_stmt (bsi)))))
+ gimple stmt = gsi_stmt (bsi);
+ int this_size = estimate_num_insns (stmt, &eni_size_weights);
+ int this_time = estimate_num_insns (stmt, &eni_time_weights);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
{
- if (dump_file)
- fprintf (dump_file, " MUST_NOT_THROW landing pad. Ignoring whole BB.\n");
+ fprintf (dump_file, " freq:%6i size:%3i time:%3i ",
+ freq, this_size, this_time);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
if (!dbg_cnt (inl))
continue;
@@ -1892,11 +1880,11 @@ estimate_function_body_sizes (struct cgraph_node *node)
this_time *= freq;
time += this_time;
size += this_size;
- if (likely_eliminated_by_inlining_p (gsi_stmt (bsi)))
+ if (likely_eliminated_by_inlining_p (stmt))
{
size_inlining_benefit += this_size;
time_inlining_benefit += this_time;
- if (dump_file)
+ if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Likely eliminated\n");
}
gcc_assert (time >= 0);
@@ -1907,11 +1895,9 @@ estimate_function_body_sizes (struct cgraph_node *node)
time_inlining_benefit = ((time_inlining_benefit + CGRAPH_FREQ_BASE / 2)
/ CGRAPH_FREQ_BASE);
if (dump_file)
- {
- fprintf (dump_file, "Overall function body time: %i-%i size: %i-%i\n",
- (int)time, (int)time_inlining_benefit,
- size, size_inlining_benefit);
- }
+ fprintf (dump_file, "Overall function body time: %i-%i size: %i-%i\n",
+ (int)time, (int)time_inlining_benefit,
+ size, size_inlining_benefit);
time_inlining_benefit += eni_time_weights.call_cost;
size_inlining_benefit += eni_size_weights.call_cost;
if (!VOID_TYPE_P (TREE_TYPE (funtype)))
@@ -1934,14 +1920,11 @@ estimate_function_body_sizes (struct cgraph_node *node)
inline_summary (node)->self_time = time;
inline_summary (node)->self_size = size;
if (dump_file)
- {
- fprintf (dump_file, "With function call overhead time: %i-%i size: %i-%i\n",
- (int)time, (int)time_inlining_benefit,
- size, size_inlining_benefit);
- }
+ fprintf (dump_file, "With function call overhead time: %i-%i size: %i-%i\n",
+ (int)time, (int)time_inlining_benefit,
+ size, size_inlining_benefit);
inline_summary (node)->time_inlining_benefit = time_inlining_benefit;
inline_summary (node)->size_inlining_benefit = size_inlining_benefit;
- BITMAP_FREE (must_not_throw);
}
/* Compute parameters of functions used by inliner. */
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index f16eb971180..8b53c8a85c1 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -346,8 +346,8 @@ check_call (funct_state local, gimple call, bool ipa)
{
if (dump_file)
{
- fprintf (dump_file, " can throw externally in region %i\n",
- lookup_stmt_eh_region (call));
+ fprintf (dump_file, " can throw externally to lp %i\n",
+ lookup_stmt_eh_lp (call));
if (callee_t)
fprintf (dump_file, " callee:%s\n",
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (callee_t)));
diff --git a/gcc/ipa-type-escape.c b/gcc/ipa-type-escape.c
index 62516d0f34c..edfaab0a0f8 100644
--- a/gcc/ipa-type-escape.c
+++ b/gcc/ipa-type-escape.c
@@ -1128,9 +1128,6 @@ check_operand (tree t)
static void
check_tree (tree t)
{
- if ((TREE_CODE (t) == EXC_PTR_EXPR) || (TREE_CODE (t) == FILTER_EXPR))
- return;
-
/* We want to catch here also REALPART_EXPR and IMAGEPART_EXPR,
but they already included in handled_component_p. */
while (handled_component_p (t))
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index a001916fb00..0b7ec66ab2c 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -215,10 +215,6 @@ ipa_utils_reduced_inorder (struct cgraph_node **order,
tree
get_base_var (tree t)
{
- if (TREE_CODE (t) == EXC_PTR_EXPR
- || TREE_CODE (t) == FILTER_EXPR)
- return t;
-
while (!SSA_VAR_P (t)
&& (!CONSTANT_CLASS_P (t))
&& TREE_CODE (t) != LABEL_DECL
diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c
index bce5c7f6294..6d84e5643b5 100644
--- a/gcc/ira-conflicts.c
+++ b/gcc/ira-conflicts.c
@@ -662,7 +662,7 @@ print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set)
{
int i, start;
- fprintf (file, title);
+ fputs (title, file);
for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
if (TEST_HARD_REG_BIT (set, i))
@@ -682,7 +682,7 @@ print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set)
start = -1;
}
}
- fprintf (file, "\n");
+ putc ('\n', file);
}
/* Print information about allocno or only regno (if REG_P) conflicts
@@ -709,9 +709,9 @@ print_conflicts (FILE *file, bool reg_p)
fprintf (file, "b%d", bb->index);
else
fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num);
- fprintf (file, ")");
+ putc (')', file);
}
- fprintf (file, " conflicts:");
+ fputs (" conflicts:", file);
if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) != NULL)
FOR_EACH_ALLOCNO_CONFLICT (a, conflict_a, aci)
{
@@ -743,7 +743,7 @@ print_conflicts (FILE *file, bool reg_p)
print_hard_reg_set (file, ";; conflict hard regs:",
conflicting_hard_regs);
}
- fprintf (file, "\n");
+ putc ('\n', file);
}
/* Print information about allocno or only regno (if REG_P) conflicts
diff --git a/gcc/ira.c b/gcc/ira.c
index b9b10dc9d3c..b960f769534 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -2384,9 +2384,21 @@ update_equiv_regs (void)
/* We only handle the case of a pseudo register being set
once, or always to the same value. */
+ /* ??? The mn10200 port breaks if we add equivalences for
+ values that need an ADDRESS_REGS register and set them equivalent
+ to a MEM of a pseudo. The actual problem is in the over-conservative
+ handling of INPADDR_ADDRESS / INPUT_ADDRESS / INPUT triples in
+ calculate_needs, but we traditionally work around this problem
+ here by rejecting equivalences when the destination is in a register
+ that's likely spilled. This is fragile, of course, since the
+ preferred class of a pseudo depends on all instructions that set
+ or use it. */
+
if (!REG_P (dest)
|| (regno = REGNO (dest)) < FIRST_PSEUDO_REGISTER
- || reg_equiv[regno].init_insns == const0_rtx)
+ || reg_equiv[regno].init_insns == const0_rtx
+ || (CLASS_LIKELY_SPILLED_P (reg_preferred_class (regno))
+ && MEM_P (src) && ! reg_equiv[regno].is_arg_equivalence))
{
/* This might be setting a SUBREG of a pseudo, a pseudo that is
also set somewhere else to a constant. */
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 569b5fe16fe..6c58a99b4c1 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,26 @@
+2009-09-14 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (initialize_builtins): Update call to
+ build_common_builtin_nodes.
+ * decl.c (java_init_decl_processing): Don't call
+ default_init_unwind_resume_libfunc.
+ * except.c: Include tree-iterator.h.
+ (build_exception_object_var): New.
+ (build_exception_object_ref): Use it.
+ (expand_end_java_handler): Initialize it from __builtin_eh_pointer.
+ Attach all CATCH_EXPRs to a single TRY_CATCH_EXPR.
+ * java-tree.h (DECL_FUNCTION_EXC_OBJ): New.
+
+2009-09-13 Richard Guenther <rguenther@suse.de>
+ Rafael Avila de Espindola <espindola@google.com>
+
+ * decl.c (do_nothing): Remove.
+ (java_init_decl_processing): Do not set lang_eh_runtime_type.
+ * Make-lang.in (lang.o): Add $(EXCEPT_H) dependency.
+ * lang.c (java_eh_personality): New.
+ (java_eh_personality_decl): Likewise.
+ (LANG_HOOKS_EH_PERSONALITY): Define.
+
2009-09-03 Diego Novillo <dnovillo@google.com>
* lang.c (lang_hooks): Remove const qualifier.
diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in
index ff330fda4e5..a56e2b62943 100644
--- a/gcc/java/Make-lang.in
+++ b/gcc/java/Make-lang.in
@@ -284,7 +284,7 @@ java/jvgenmain.o: java/jvgenmain.c $(CONFIG_H) $(JAVA_TREE_H) $(SYSTEM_H) \
coretypes.h $(TM_H) intl.h
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
+ langhooks.h $(LANGHOOKS_DEF_H) gt-java-lang.h opts.h options.h $(EXCEPT_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 $(LANGHOOKS_DEF_H)
java/mangle_name.o: java/mangle_name.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) \
diff --git a/gcc/java/builtins.c b/gcc/java/builtins.c
index 6e4815beeab..a05ff53ceb9 100644
--- a/gcc/java/builtins.c
+++ b/gcc/java/builtins.c
@@ -584,7 +584,7 @@ initialize_builtins (void)
build_function_type_list (ptr_type_node, int_type_node, NULL_TREE),
"__builtin_return_address", BUILTIN_NOTHROW);
- build_common_builtin_nodes ();
+ build_common_builtin_nodes (true);
}
/* If the call matches a builtin, return the
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 4ab67d6cf51..c593b53df5c 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -1,7 +1,7 @@
/* Process declarations and variables for the GNU compiler for the
Java(TM) language.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007,
- 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
@@ -510,12 +510,6 @@ create_primitive_vtable (const char *name)
return r;
}
-static tree
-do_nothing (tree t)
-{
- return t;
-}
-
/* Parse the version string and compute the ABI version number. */
static void
parse_version (void)
@@ -1194,18 +1188,8 @@ java_init_decl_processing (void)
build_function_type (long_type_node, t),
0, NOT_BUILT_IN, NULL, NULL_TREE);
- /* Initialize variables for except.c. */
- eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
- ? "__gcj_personality_sj0"
- : "__gcj_personality_v0");
- if (targetm.arm_eabi_unwinder)
- unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
- else
- default_init_unwind_resume_libfunc ();
-
- lang_eh_runtime_type = do_nothing;
-
initialize_builtins ();
+
soft_fmod_node = built_in_decls[BUILT_IN_FMOD];
parse_version ();
diff --git a/gcc/java/except.c b/gcc/java/except.c
index e97ed7755d9..4e4651421d4 100644
--- a/gcc/java/except.c
+++ b/gcc/java/except.c
@@ -1,6 +1,6 @@
/* Handle exceptions for GNU compiler for the Java(TM) language.
Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
- 2007, 2008 Free Software Foundation, Inc.
+ 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
@@ -37,6 +37,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "except.h"
#include "java-except.h"
#include "toplev.h"
+#include "tree-iterator.h"
+
static void expand_start_java_handler (struct eh_range *);
static struct eh_range *find_handler_in_range (int, struct eh_range *,
@@ -457,6 +459,26 @@ java_expand_catch_classes (tree this_class)
expand_catch_class, NULL);
}
+/* Build and push the variable that will hold the exception object
+ within this function. */
+
+static tree
+build_exception_object_var (void)
+{
+ tree decl = DECL_FUNCTION_EXC_OBJ (current_function_decl);
+ if (decl == NULL)
+ {
+ decl = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
+ VAR_DECL, get_identifier ("#exc_obj"), ptr_type_node);
+ DECL_IGNORED_P (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+
+ DECL_FUNCTION_EXC_OBJ (current_function_decl) = decl;
+ pushdecl_function_level (decl);
+ }
+ return decl;
+}
+
/* Build a reference to the jthrowable object being carried in the
exception header. */
@@ -467,7 +489,8 @@ build_exception_object_ref (tree type)
/* Java only passes object via pointer and doesn't require adjusting.
The java object is immediately before the generic exception header. */
- obj = build0 (EXC_PTR_EXPR, build_pointer_type (type));
+ obj = build_exception_object_var ();
+ obj = fold_convert (build_pointer_type (type), obj);
obj = build2 (POINTER_PLUS_EXPR, TREE_TYPE (obj), obj,
fold_build1 (NEGATE_EXPR, sizetype,
TYPE_SIZE_UNIT (TREE_TYPE (obj))));
@@ -482,29 +505,48 @@ void
expand_end_java_handler (struct eh_range *range)
{
tree handler = range->handlers;
-
- for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler))
+ if (handler)
{
- /* For bytecode we treat exceptions a little unusually. A
- `finally' clause looks like an ordinary exception handler for
- Throwable. The reason for this is that the bytecode has
- already expanded the finally logic, and we would have to do
- extra (and difficult) work to get this to look like a
- gcc-style finally clause. */
- tree type = TREE_PURPOSE (handler);
- if (type == NULL)
- type = throwable_type_node;
- type = prepare_eh_table_type (type);
+ tree exc_obj = build_exception_object_var ();
+ tree catches = make_node (STATEMENT_LIST);
+ tree_stmt_iterator catches_i = tsi_last (catches);
+ tree *body;
- {
- tree catch_expr = build2 (CATCH_EXPR, void_type_node, type,
- build1 (GOTO_EXPR, void_type_node,
- TREE_VALUE (handler)));
- tree try_catch_expr = build2 (TRY_CATCH_EXPR, void_type_node,
- *get_stmts (), catch_expr);
- *get_stmts () = try_catch_expr;
- }
+ for (; handler; handler = TREE_CHAIN (handler))
+ {
+ tree type, eh_type, x;
+ tree stmts = make_node (STATEMENT_LIST);
+ tree_stmt_iterator stmts_i = tsi_last (stmts);
+
+ type = TREE_PURPOSE (handler);
+ if (type == NULL)
+ type = throwable_type_node;
+ eh_type = prepare_eh_table_type (type);
+
+ x = build_call_expr (built_in_decls[BUILT_IN_EH_POINTER],
+ 1, integer_zero_node);
+ x = build2 (MODIFY_EXPR, void_type_node, exc_obj, x);
+ tsi_link_after (&stmts_i, x, TSI_CONTINUE_LINKING);
+
+ x = build1 (GOTO_EXPR, void_type_node, TREE_VALUE (handler));
+ tsi_link_after (&stmts_i, x, TSI_CONTINUE_LINKING);
+
+ x = build2 (CATCH_EXPR, void_type_node, eh_type, stmts);
+ tsi_link_after (&catches_i, x, TSI_CONTINUE_LINKING);
+
+ /* Throwable can match anything in Java, and therefore
+ any subsequent handlers are unreachable. */
+ /* ??? If we're assured of no foreign language exceptions,
+ we'd be better off using NULL as the exception type
+ for the catch. */
+ if (type == throwable_type_node)
+ break;
+ }
+
+ body = get_stmts ();
+ *body = build2 (TRY_CATCH_EXPR, void_type_node, *body, catches);
}
+
#if defined(DEBUG_JAVA_BINDING_LEVELS)
indent ();
fprintf (stderr, "expand end handler pc %d <-- %d\n",
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 29027eb6463..8ffe2422967 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -714,6 +714,8 @@ union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
/* List of checked thrown exceptions, as specified with the `throws'
keyword */
#define DECL_FUNCTION_THROWS(DECL) (DECL_LANG_SPECIFIC(DECL)->u.f.throws_list)
+/* VAR_DECL containing the caught exception object. */
+#define DECL_FUNCTION_EXC_OBJ(DECL) (DECL_LANG_SPECIFIC(DECL)->u.f.exc_obj)
/* For each function decl, init_test_table contains a hash table whose
entries are keyed on class names, and whose values are local
boolean decls. The variables are intended to be TRUE when the
@@ -785,6 +787,7 @@ struct GTY(()) lang_decl_func {
int arg_slot_count;
source_location last_line; /* End line number for a function decl */
tree throws_list; /* Exception specified by `throws' */
+ tree exc_obj; /* Decl holding the exception object. */
/* Class initialization test variables */
htab_t GTY ((param_is (struct treetreehash_entry))) init_test_table;
diff --git a/gcc/java/lang.c b/gcc/java/lang.c
index d97b508b707..504d0295bf0 100644
--- a/gcc/java/lang.c
+++ b/gcc/java/lang.c
@@ -45,6 +45,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "tree-dump.h"
#include "opts.h"
#include "options.h"
+#include "except.h"
static bool java_init (void);
static void java_finish (void);
@@ -64,6 +65,8 @@ static bool java_decl_ok_for_sibcall (const_tree);
static enum classify_record java_classify_record (tree type);
+static tree java_eh_personality (void);
+
#ifndef TARGET_OBJECT_SUFFIX
# define TARGET_OBJECT_SUFFIX ".o"
#endif
@@ -158,6 +161,9 @@ struct GTY(()) language_function {
#undef LANG_HOOKS_ATTRIBUTE_TABLE
#define LANG_HOOKS_ATTRIBUTE_TABLE java_attribute_table
+#undef LANG_HOOKS_EH_PERSONALITY
+#define LANG_HOOKS_EH_PERSONALITY java_eh_personality
+
/* Each front end provides its own. */
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
@@ -880,4 +886,18 @@ java_classify_record (tree type)
return RECORD_IS_CLASS;
}
+static GTY(()) tree java_eh_personality_decl;
+
+static tree
+java_eh_personality (void)
+{
+ if (!java_eh_personality_decl)
+ java_eh_personality_decl
+ = build_personality_function (USING_SJLJ_EXCEPTIONS
+ ? "__gcj_personality_sj0"
+ : "__gcj_personality_v0");
+
+ return java_eh_personality_decl;
+}
+
#include "gt-java-lang.h"
diff --git a/gcc/jump.c b/gcc/jump.c
index 28a9b0f43ea..a12d0404500 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -68,6 +68,7 @@ along with GCC; see the file COPYING3. If not see
static void init_label_info (rtx);
static void mark_all_labels (rtx);
static void mark_jump_label_1 (rtx, rtx, bool, bool);
+static void mark_jump_label_asm (rtx, rtx);
static void redirect_exp_1 (rtx *, rtx, rtx, rtx);
static int invert_exp_1 (rtx, rtx);
static int returnjump_p_1 (rtx *, void *);
@@ -1006,8 +1007,12 @@ sets_cc0_p (const_rtx x)
void
mark_jump_label (rtx x, rtx insn, int in_mem)
{
- mark_jump_label_1 (x, insn, in_mem != 0,
- (insn != NULL && x == PATTERN (insn) && JUMP_P (insn)));
+ rtx asmop = extract_asm_operands (x);
+ if (asmop)
+ mark_jump_label_asm (asmop, insn);
+ else
+ mark_jump_label_1 (x, insn, in_mem != 0,
+ (insn != NULL && x == PATTERN (insn) && JUMP_P (insn)));
}
/* Worker function for mark_jump_label. IN_MEM is TRUE when X occurs
@@ -1145,6 +1150,22 @@ mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target)
}
}
+/* Worker function for mark_jump_label. Handle asm insns specially.
+ In particular, output operands need not be considered so we can
+ avoid re-scanning the replicated asm_operand. Also, the asm_labels
+ need to be considered targets. */
+
+static void
+mark_jump_label_asm (rtx asmop, rtx insn)
+{
+ int i;
+
+ for (i = ASM_OPERANDS_INPUT_LENGTH (asmop) - 1; i >= 0; --i)
+ mark_jump_label_1 (ASM_OPERANDS_INPUT (asmop, i), insn, false, false);
+
+ for (i = ASM_OPERANDS_LABEL_LENGTH (asmop) - 1; i >= 0; --i)
+ mark_jump_label_1 (ASM_OPERANDS_LABEL (asmop, i), insn, false, true);
+}
/* Delete insn INSN from the chain of insns and update label ref counts
and delete insns now unreachable.
@@ -1386,9 +1407,17 @@ int
redirect_jump_1 (rtx jump, rtx nlabel)
{
int ochanges = num_validated_changes ();
- rtx *loc;
+ rtx *loc, asmop;
- if (GET_CODE (PATTERN (jump)) == PARALLEL)
+ asmop = extract_asm_operands (PATTERN (jump));
+ if (asmop)
+ {
+ if (nlabel == NULL)
+ return 0;
+ gcc_assert (ASM_OPERANDS_LABEL_LENGTH (asmop) == 1);
+ loc = &ASM_OPERANDS_LABEL (asmop, 0);
+ }
+ else if (GET_CODE (PATTERN (jump)) == PARALLEL)
loc = &XVECEXP (PATTERN (jump), 0, 0);
else
loc = &PATTERN (jump);
@@ -1514,7 +1543,8 @@ invert_jump_1 (rtx jump, rtx nlabel)
int ok;
ochanges = num_validated_changes ();
- gcc_assert (x);
+ if (x == NULL)
+ return 0;
ok = invert_exp_1 (SET_SRC (x), jump);
gcc_assert (ok);
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 45f00e05e32..9ccb894d8f7 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -46,6 +46,7 @@ extern bool lhd_do_nothing_t_return_bool (tree);
extern int lhd_do_nothing_t_t_return_int (tree, tree);
extern bool lhd_do_nothing_t_vp_return_bool (tree, void *);
extern void lhd_do_nothing_f (struct function *);
+extern tree lhd_pass_through_t (tree);
extern bool lhd_post_options (const char **);
extern alias_set_type lhd_get_alias_set (tree);
extern tree lhd_return_null_tree_v (void);
@@ -115,6 +116,8 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
#define LANG_HOOKS_EXPR_TO_DECL lhd_expr_to_decl
#define LANG_HOOKS_TO_TARGET_CHARSET lhd_to_target_charset
#define LANG_HOOKS_INIT_TS lhd_do_nothing
+#define LANG_HOOKS_EH_PERSONALITY lhd_gcc_personality
+#define LANG_HOOKS_EH_RUNTIME_TYPE lhd_pass_through_t
/* Attribute hooks. */
#define LANG_HOOKS_ATTRIBUTE_TABLE NULL
@@ -314,6 +317,8 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_USER_CONV_FUNCTION, \
LANG_HOOKS_INIT_TS, \
LANG_HOOKS_EXPR_TO_DECL, \
+ LANG_HOOKS_EH_PERSONALITY, \
+ LANG_HOOKS_EH_RUNTIME_TYPE, \
}
#endif /* GCC_LANG_HOOKS_DEF_H */
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 0455153e557..3a4e887c07f 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -53,6 +53,13 @@ lhd_do_nothing_t (tree ARG_UNUSED (t))
{
}
+/* Pass through (tree). */
+tree
+lhd_pass_through_t (tree t)
+{
+ return t;
+}
+
/* Do nothing (int). */
void
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index a8aaef9bef5..7148ec4ee58 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -474,6 +474,12 @@ struct lang_hooks
if in the process TREE_CONSTANT or TREE_SIDE_EFFECTS need updating. */
tree (*expr_to_decl) (tree expr, bool *tc, bool *se);
+ /* The EH personality function decl. */
+ tree (*eh_personality) (void);
+
+ /* Map a type to a runtime object to match type. */
+ tree (*eh_runtime_type) (tree);
+
/* Whenever you add entries here, make sure you adjust langhooks-def.h
and langhooks.c accordingly. */
};
diff --git a/gcc/libfuncs.h b/gcc/libfuncs.h
index 70621cf2889..d3e69e3e241 100644
--- a/gcc/libfuncs.h
+++ b/gcc/libfuncs.h
@@ -30,8 +30,6 @@ enum libfunc_index
LTI_memset,
LTI_setbits,
- LTI_unwind_resume,
- LTI_eh_personality,
LTI_setjmp,
LTI_longjmp,
LTI_unwind_sjlj_register,
@@ -60,8 +58,6 @@ extern GTY(()) rtx libfunc_table[LTI_MAX];
#define memset_libfunc (libfunc_table[LTI_memset])
#define setbits_libfunc (libfunc_table[LTI_setbits])
-#define unwind_resume_libfunc (libfunc_table[LTI_unwind_resume])
-#define eh_personality_libfunc (libfunc_table[LTI_eh_personality])
#define setjmp_libfunc (libfunc_table[LTI_setjmp])
#define longjmp_libfunc (libfunc_table[LTI_longjmp])
#define unwind_sjlj_register_libfunc (libfunc_table[LTI_unwind_sjlj_register])
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index 3ff20eb3de5..3ce714b2bf8 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -559,30 +559,6 @@ adjust_decomposed_uses (rtx *px, void *data ATTRIBUTE_UNUSED)
return 0;
}
-/* We are deleting INSN. Move any EH_REGION notes to INSNS. */
-
-static void
-move_eh_region_note (rtx insn, rtx insns)
-{
- rtx note, p;
-
- note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
- if (note == NULL_RTX)
- return;
-
- gcc_assert (CALL_P (insn)
- || (flag_non_call_exceptions && may_trap_p (PATTERN (insn))));
-
- for (p = insns; p != NULL_RTX; p = NEXT_INSN (p))
- {
- if (CALL_P (p)
- || (flag_non_call_exceptions
- && INSN_P (p)
- && may_trap_p (PATTERN (p))))
- add_reg_note (p, REG_EH_REGION, XEXP (note, 0));
- }
-}
-
/* Resolve any decomposed registers which appear in register notes on
INSN. */
@@ -847,7 +823,7 @@ resolve_simple_move (rtx set, rtx insn)
insns = get_insns ();
end_sequence ();
- move_eh_region_note (insn, insns);
+ copy_reg_eh_region_note_forward (insn, insns, NULL_RTX);
emit_insn_before (insns, insn);
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index d499f0a55c9..70f841be2ba 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,23 @@
+2009-09-14 Richard Henderson <rth@redhat.com>
+
+ * objc-act.c (objc_init_exceptions): Don't call
+ default_init_unwind_resume_libfunc.
+ (objc_build_exc_ptr): Use __builtin_eh_pointer.
+
+2009-09-13 Richard Guenther <rguenther@suse.de>
+ Rafael Avila de Espindola <espindola@google.com>
+
+ * objc-act.c (objc_eh_runtime_type): Export.
+ (objc_init_exceptions): Remove. Move warning code ...
+ (objc_begin_try_stmt): ... here
+ (objc_build_throw_stmt): ... and here.
+ (objc_eh_personality_decl): New.
+ (objc_eh_personality): New function.
+ * objc-act.h (objc_eh_runtime_type): Declare.
+ (objc_eh_personality): Likewise.
+ * objc-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define.
+ (LANG_HOOKS_EH_PERSONALITY): Likewise.
+
2009-09-03 Diego Novillo <dnovillo@google.com>
* objc-lang.c (lang_hooks): Remove const qualifier.
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 8b1a596c323..eac7ff02f09 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -3475,7 +3475,7 @@ struct objc_try_context
/* The CATCH_EXPR of an open @catch clause. */
tree current_catch;
- /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
+ /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */
tree caught_decl;
tree stack_decl;
tree rethrow_decl;
@@ -3483,54 +3483,36 @@ struct objc_try_context
static struct objc_try_context *cur_try_context;
+static GTY(()) tree objc_eh_personality_decl;
+
/* This hook, called via lang_eh_runtime_type, generates a runtime object
that represents TYPE. For Objective-C, this is just the class name. */
/* ??? Isn't there a class object or some such? Is it easy to get? */
#ifndef OBJCPLUS
-static tree
+tree
objc_eh_runtime_type (tree type)
{
return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
}
-#endif
-
-/* Initialize exception handling. */
-static void
-objc_init_exceptions (void)
+tree
+objc_eh_personality (void)
{
- static bool done = false;
- if (done)
- return;
- done = true;
+ if (!flag_objc_sjlj_exceptions
+ && !objc_eh_personality_decl)
+ objc_eh_personality_decl
+ = build_personality_function (USING_SJLJ_EXCEPTIONS
+ ? "__gnu_objc_personality_sj0"
+ : "__gnu_objc_personality_v0");
- if (flag_objc_sjlj_exceptions)
- {
- /* On Darwin, ObjC exceptions require a sufficiently recent
- version of the runtime, so the user must ask for them explicitly. */
- if (!flag_objc_exceptions)
- warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
- "exception syntax");
- }
-#ifndef OBJCPLUS
- else
- {
- c_eh_initialized_p = true;
- eh_personality_libfunc
- = init_one_libfunc (USING_SJLJ_EXCEPTIONS
- ? "__gnu_objc_personality_sj0"
- : "__gnu_objc_personality_v0");
- default_init_unwind_resume_libfunc ();
- using_eh_for_cleanups ();
- lang_eh_runtime_type = objc_eh_runtime_type;
- }
-#endif
+ return objc_eh_personality_decl;
}
+#endif
-/* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
- we'll arrange for it to be initialized (and associated with a binding)
- later. */
+/* Build __builtin_eh_pointer, or the moral equivalent. In the case
+ of Darwin, we'll arrange for it to be initialized (and associated
+ with a binding) later. */
static tree
objc_build_exc_ptr (void)
@@ -3546,7 +3528,12 @@ objc_build_exc_ptr (void)
return var;
}
else
- return build0 (EXC_PTR_EXPR, objc_object_type);
+ {
+ tree t;
+ t = built_in_decls[BUILT_IN_EH_POINTER];
+ t = build_call_expr (t, 1, integer_zero_node);
+ return fold_convert (objc_object_type, t);
+ }
}
/* Build "objc_exception_try_exit(&_stack)". */
@@ -3824,7 +3811,14 @@ objc_begin_try_stmt (location_t try_locus, tree body)
c->end_try_locus = input_location;
cur_try_context = c;
- objc_init_exceptions ();
+ if (flag_objc_sjlj_exceptions)
+ {
+ /* On Darwin, ObjC exceptions require a sufficiently recent
+ version of the runtime, so the user must ask for them explicitly. */
+ if (!flag_objc_exceptions)
+ warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
+ "exception syntax");
+ }
if (flag_objc_sjlj_exceptions)
objc_mark_locals_volatile (NULL);
@@ -3973,7 +3967,14 @@ objc_build_throw_stmt (location_t loc, tree throw_expr)
{
tree args;
- objc_init_exceptions ();
+ if (flag_objc_sjlj_exceptions)
+ {
+ /* On Darwin, ObjC exceptions require a sufficiently recent
+ version of the runtime, so the user must ask for them explicitly. */
+ if (!flag_objc_exceptions)
+ warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
+ "exception syntax");
+ }
if (throw_expr == NULL)
{
diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h
index fb929342b99..f0970f90bfd 100644
--- a/gcc/objc/objc-act.h
+++ b/gcc/objc/objc-act.h
@@ -32,6 +32,8 @@ const char *objc_printable_name (tree, int);
void objc_finish_file (void);
tree objc_fold_obj_type_ref (tree, tree);
int objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
+tree objc_eh_runtime_type (tree);
+tree objc_eh_personality (void);
/* NB: The remaining public functions are prototyped in c-common.h, for the
benefit of stub-objc.c and objc-act.c. */
diff --git a/gcc/objc/objc-lang.c b/gcc/objc/objc-lang.c
index 98f46d741ab..acb1c84649d 100644
--- a/gcc/objc/objc-lang.c
+++ b/gcc/objc/objc-lang.c
@@ -51,6 +51,13 @@ static void objc_init_ts (void);
#undef LANG_HOOKS_INIT_TS
#define LANG_HOOKS_INIT_TS objc_init_ts
+#ifndef OBJCPLUS
+#undef LANG_HOOKS_EH_PERSONALITY
+#define LANG_HOOKS_EH_PERSONALITY objc_eh_personality
+#undef LANG_HOOKS_EH_RUNTIME_TYPE
+#define LANG_HOOKS_EH_RUNTIME_TYPE objc_eh_runtime_type
+#endif
+
/* Each front end provides its own lang hook initializer. */
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index a7de367e432..5cd9463c122 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -1214,7 +1214,7 @@ new_omp_context (gimple stmt, omp_context *outer_ctx)
ctx->cb.dst_node = ctx->cb.src_node;
ctx->cb.src_cfun = cfun;
ctx->cb.copy_decl = omp_copy_decl;
- ctx->cb.eh_region = -1;
+ ctx->cb.eh_lp_nr = 0;
ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
ctx->depth = 1;
}
@@ -3114,23 +3114,22 @@ expand_task_call (basic_block bb, gimple entry_stmt)
static gimple_seq
maybe_catch_exception (gimple_seq body)
{
- gimple f, t;
+ gimple g;
+ tree decl;
if (!flag_exceptions)
return body;
if (lang_protect_cleanup_actions)
- t = lang_protect_cleanup_actions ();
+ decl = lang_protect_cleanup_actions ();
else
- t = gimple_build_call (built_in_decls[BUILT_IN_TRAP], 0);
+ decl = built_in_decls[BUILT_IN_TRAP];
- f = gimple_build_eh_filter (NULL, gimple_seq_alloc_with_stmt (t));
- gimple_eh_filter_set_must_not_throw (f, true);
-
- t = gimple_build_try (body, gimple_seq_alloc_with_stmt (f),
+ g = gimple_build_eh_must_not_throw (decl);
+ g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
GIMPLE_TRY_CATCH);
- return gimple_seq_alloc_with_stmt (t);
+ return gimple_seq_alloc_with_stmt (g);
}
/* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
@@ -6244,7 +6243,7 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
tcctx.cb.dst_node = tcctx.cb.src_node;
tcctx.cb.src_cfun = ctx->cb.src_cfun;
tcctx.cb.copy_decl = task_copyfn_copy_decl;
- tcctx.cb.eh_region = -1;
+ tcctx.cb.eh_lp_nr = 0;
tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
tcctx.cb.decl_map = pointer_map_create ();
tcctx.ctx = ctx;
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 61d8bcfe298..a1adc581dc1 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -3858,32 +3858,31 @@ emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
/* If we're using non-call exceptions, a libcall corresponding to an
operation that may trap may also trap. */
+ /* ??? See the comment in front of make_reg_eh_region_note. */
if (flag_non_call_exceptions && may_trap_p (equiv))
{
for (insn = insns; insn; insn = NEXT_INSN (insn))
if (CALL_P (insn))
{
rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
-
- if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
- remove_note (insn, note);
+ if (note)
+ {
+ int lp_nr = INTVAL (XEXP (note, 0));
+ if (lp_nr == 0 || lp_nr == INT_MIN)
+ remove_note (insn, note);
+ }
}
}
else
- /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
- reg note to indicate that this call cannot throw or execute a nonlocal
- goto (unless there is already a REG_EH_REGION note, in which case
- we update it). */
- for (insn = insns; insn; insn = NEXT_INSN (insn))
- if (CALL_P (insn))
- {
- rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
-
- if (note != 0)
- XEXP (note, 0) = constm1_rtx;
- else
- add_reg_note (insn, REG_EH_REGION, constm1_rtx);
- }
+ {
+ /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
+ reg note to indicate that this call cannot throw or execute a nonlocal
+ goto (unless there is already a REG_EH_REGION note, in which case
+ we update it). */
+ for (insn = insns; insn; insn = NEXT_INSN (insn))
+ if (CALL_P (insn))
+ make_reg_eh_region_note_nothrow_nononlocal (insn);
+ }
/* First emit all insns that set pseudos. Remove them from the list as
we go. Avoid insns that set pseudos which were referenced in previous
@@ -6023,6 +6022,28 @@ libfunc_decl_eq (const void *entry1, const void *entry2)
return DECL_NAME ((const_tree) entry1) == (const_tree) entry2;
}
+/* Build a decl for a libfunc named NAME. */
+
+tree
+build_libfunc_function (const char *name)
+{
+ tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
+ get_identifier (name),
+ build_function_type (integer_type_node, NULL_TREE));
+ /* ??? We don't have any type information except for this is
+ a function. Pretend this is "int foo()". */
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+ gcc_assert (DECL_ASSEMBLER_NAME (decl));
+
+ /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
+ are the flags assigned by targetm.encode_section_info. */
+ SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
+
+ return decl;
+}
+
rtx
init_one_libfunc (const char *name)
{
@@ -6043,19 +6064,7 @@ init_one_libfunc (const char *name)
{
/* Create a new decl, so that it can be passed to
targetm.encode_section_info. */
- /* ??? We don't have any type information except for this is
- a function. Pretend this is "int foo()". */
- decl = build_decl (UNKNOWN_LOCATION,
- FUNCTION_DECL, get_identifier (name),
- build_function_type (integer_type_node, NULL_TREE));
- DECL_ARTIFICIAL (decl) = 1;
- DECL_EXTERNAL (decl) = 1;
- TREE_PUBLIC (decl) = 1;
-
- /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
- are the flags assigned by targetm.encode_section_info. */
- SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
-
+ decl = build_libfunc_function (name);
*slot = decl;
}
return XEXP (DECL_RTL (decl), 0);
diff --git a/gcc/opts.c b/gcc/opts.c
index 02dfa2cbd98..23a00abac87 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -940,6 +940,7 @@ decode_options (unsigned int argc, const char **argv)
flag_tree_pre = opt2;
flag_tree_switch_conversion = 1;
flag_ipa_cp = opt2;
+ flag_ipa_sra = opt2;
/* Track fields in field-sensitive alias analysis. */
set_param_value ("max-fields-for-field-sensitive",
@@ -1554,7 +1555,7 @@ common_handle_option (size_t scode, const char *arg, int value,
{ NULL, 0 }
};
unsigned int * pflags;
- char * comma;
+ const char * comma;
unsigned int lang_flag, specific_flag;
unsigned int len;
unsigned int i;
diff --git a/gcc/params.def b/gcc/params.def
index 8d0719fb6cb..e9dcb38d9a2 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -82,7 +82,7 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE,
DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO,
"max-inline-insns-auto",
"The maximum number of instructions when automatically inlining",
- 60, 0, 0)
+ 50, 0, 0)
DEFPARAM (PARAM_MAX_INLINE_INSNS_RECURSIVE,
"max-inline-insns-recursive",
@@ -185,7 +185,7 @@ DEFPARAM(PARAM_IPCP_UNIT_GROWTH,
DEFPARAM(PARAM_EARLY_INLINING_INSNS,
"early-inlining-insns",
"maximal estimated growth of function body caused by early inlining of single call",
- 12, 0, 0)
+ 8, 0, 0)
DEFPARAM(PARAM_LARGE_STACK_FRAME,
"large-stack-frame",
"The size of stack frame to be considered large",
@@ -804,6 +804,12 @@ DEFPARAM (PARAM_MIN_NONDEBUG_INSN_UID,
"The minimum UID to be used for a nondebug insn",
0, 1, 0)
+DEFPARAM (PARAM_IPA_SRA_PTR_GROWTH_FACTOR,
+ "ipa-sra-ptr-growth-factor",
+ "maximum allowed growth of size of new parameters ipa-sra replaces "
+ "a pointer to an aggregate with",
+ 2, 0, 0)
+
/*
Local variables:
mode:c
diff --git a/gcc/passes.c b/gcc/passes.c
index fcc26696b13..1fa62023cb1 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -575,6 +575,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_copy_prop);
NEXT_PASS (pass_merge_phi);
NEXT_PASS (pass_cd_dce);
+ NEXT_PASS (pass_early_ipa_sra);
NEXT_PASS (pass_tail_recursion);
NEXT_PASS (pass_convert_switch);
NEXT_PASS (pass_cleanup_eh);
@@ -600,6 +601,7 @@ init_optimization_passes (void)
output to the assembler file. */
p = &all_passes;
NEXT_PASS (pass_direct_call_profile);
+ NEXT_PASS (pass_lower_eh_dispatch);
NEXT_PASS (pass_all_optimizations);
{
struct opt_pass **p = &pass_all_optimizations.pass.sub;
@@ -723,6 +725,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_local_pure_const);
}
NEXT_PASS (pass_cleanup_eh);
+ NEXT_PASS (pass_lower_resx);
NEXT_PASS (pass_nrv);
NEXT_PASS (pass_mudflap_2);
NEXT_PASS (pass_cleanup_cfg_post_optimizing);
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index cb09597b579..a75442eb6c7 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -305,9 +305,9 @@ print_rtx (const_rtx in_rtx)
break;
}
}
- else if (i == 9 && JUMP_P (in_rtx) && XEXP (in_rtx, i) != NULL)
+ else if (i == 8 && JUMP_P (in_rtx) && JUMP_LABEL (in_rtx) != NULL)
/* Output the JUMP_LABEL reference. */
- fprintf (outfile, "\n -> %d", INSN_UID (XEXP (in_rtx, i)));
+ fprintf (outfile, "\n -> %d", INSN_UID (JUMP_LABEL (in_rtx)));
else if (i == 0 && GET_CODE (in_rtx) == VALUE)
{
#ifndef GENERATOR_FILE
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 26f467cba8e..1d66769a1f7 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -393,6 +393,8 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
if (code == LABEL_DECL && DECL_ERROR_ISSUED (node))
fputs (" error-issued", file);
+ if (code == LABEL_DECL && EH_LANDING_PAD_NR (node))
+ fprintf (file, " landing-pad:%d", EH_LANDING_PAD_NR (node));
if (code == VAR_DECL && DECL_IN_TEXT_SECTION (node))
fputs (" in-text-section", file);
diff --git a/gcc/real.c b/gcc/real.c
index f4c493bd041..eb4e25bba83 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -110,6 +110,9 @@ static int do_compare (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int);
static void do_fix_trunc (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
static unsigned long rtd_divmod (REAL_VALUE_TYPE *, REAL_VALUE_TYPE *);
+static void decimal_from_integer (REAL_VALUE_TYPE *);
+static void decimal_integer_string (char *, const REAL_VALUE_TYPE *,
+ size_t);
static const REAL_VALUE_TYPE * ten_to_ptwo (int);
static const REAL_VALUE_TYPE * ten_to_mptwo (int);
@@ -2168,10 +2171,70 @@ real_from_integer (REAL_VALUE_TYPE *r, enum machine_mode mode,
normalize (r);
}
- if (mode != VOIDmode)
+ if (DECIMAL_FLOAT_MODE_P (mode))
+ decimal_from_integer (r);
+ else if (mode != VOIDmode)
real_convert (r, mode, r);
}
+/* Render R, an integral value, as a floating point constant with no
+ specified exponent. */
+
+static void
+decimal_integer_string (char *str, const REAL_VALUE_TYPE *r_orig,
+ size_t buf_size)
+{
+ int dec_exp, digit, digits;
+ REAL_VALUE_TYPE r, pten;
+ char *p;
+ bool sign;
+
+ r = *r_orig;
+
+ if (r.cl == rvc_zero)
+ {
+ strcpy (str, "0.");
+ return;
+ }
+
+ sign = r.sign;
+ r.sign = 0;
+
+ dec_exp = REAL_EXP (&r) * M_LOG10_2;
+ digits = dec_exp + 1;
+ gcc_assert ((digits + 2) < (int)buf_size);
+
+ pten = *real_digit (1);
+ times_pten (&pten, dec_exp);
+
+ p = str;
+ if (sign)
+ *p++ = '-';
+
+ digit = rtd_divmod (&r, &pten);
+ gcc_assert (digit >= 0 && digit <= 9);
+ *p++ = digit + '0';
+ while (--digits > 0)
+ {
+ times_pten (&r, 1);
+ digit = rtd_divmod (&r, &pten);
+ *p++ = digit + '0';
+ }
+ *p++ = '.';
+ *p++ = '\0';
+}
+
+/* Convert a real with an integral value to decimal float. */
+
+static void
+decimal_from_integer (REAL_VALUE_TYPE *r)
+{
+ char str[256];
+
+ decimal_integer_string (str, r, sizeof (str) - 1);
+ decimal_real_from_string (r, str);
+}
+
/* Returns 10**2**N. */
static const REAL_VALUE_TYPE *
diff --git a/gcc/recog.c b/gcc/recog.c
index c1e25d746a1..6874d6c5c60 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1373,6 +1373,42 @@ comparison_operator (rtx op, enum machine_mode mode)
&& COMPARISON_P (op));
}
+/* If BODY is an insn body that uses ASM_OPERANDS, return it. */
+
+rtx
+extract_asm_operands (rtx body)
+{
+ rtx tmp;
+ switch (GET_CODE (body))
+ {
+ case ASM_OPERANDS:
+ return body;
+
+ case SET:
+ /* Single output operand: BODY is (set OUTPUT (asm_operands ...)). */
+ tmp = SET_SRC (body);
+ if (GET_CODE (tmp) == ASM_OPERANDS)
+ return tmp;
+ break;
+
+ case PARALLEL:
+ tmp = XVECEXP (body, 0, 0);
+ if (GET_CODE (tmp) == ASM_OPERANDS)
+ return tmp;
+ if (GET_CODE (tmp) == SET)
+ {
+ tmp = SET_SRC (tmp);
+ if (GET_CODE (tmp) == ASM_OPERANDS)
+ return tmp;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return NULL;
+}
+
/* If BODY is an insn body that uses ASM_OPERANDS,
return the number of operands (both input and output) in the insn.
Otherwise return -1. */
@@ -1380,26 +1416,22 @@ comparison_operator (rtx op, enum machine_mode mode)
int
asm_noperands (const_rtx body)
{
- switch (GET_CODE (body))
+ rtx asm_op = extract_asm_operands (CONST_CAST_RTX (body));
+ int n_sets = 0;
+
+ if (asm_op == NULL)
+ return -1;
+
+ if (GET_CODE (body) == SET)
+ n_sets = 1;
+ else if (GET_CODE (body) == PARALLEL)
{
- case ASM_OPERANDS:
- /* No output operands: return number of input operands. */
- return ASM_OPERANDS_INPUT_LENGTH (body);
- case SET:
- if (GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
- /* Single output operand: BODY is (set OUTPUT (asm_operands ...)). */
- return ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body)) + 1;
- else
- return -1;
- case PARALLEL:
- if (GET_CODE (XVECEXP (body, 0, 0)) == SET
- && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
+ int i;
+ if (GET_CODE (XVECEXP (body, 0, 0)) == SET)
{
/* Multiple output operands, or 1 output plus some clobbers:
- body is [(set OUTPUT (asm_operands ...))... (clobber (reg ...))...]. */
- int i;
- int n_sets;
-
+ body is
+ [(set OUTPUT (asm_operands ...))... (clobber (reg ...))...]. */
/* Count backwards through CLOBBERs to determine number of SETs. */
for (i = XVECLEN (body, 0); i > 0; i--)
{
@@ -1425,30 +1457,23 @@ asm_noperands (const_rtx body)
/* If these ASM_OPERANDS rtx's came from different original insns
then they aren't allowed together. */
if (ASM_OPERANDS_INPUT_VEC (SET_SRC (elt))
- != ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (body, 0, 0))))
+ != ASM_OPERANDS_INPUT_VEC (asm_op))
return -1;
}
- return (ASM_OPERANDS_INPUT_LENGTH (SET_SRC (XVECEXP (body, 0, 0)))
- + n_sets);
}
- else if (GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
+ else
{
/* 0 outputs, but some clobbers:
body is [(asm_operands ...) (clobber (reg ...))...]. */
- int i;
-
/* Make sure all the other parallel things really are clobbers. */
for (i = XVECLEN (body, 0) - 1; i > 0; i--)
if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
return -1;
-
- return ASM_OPERANDS_INPUT_LENGTH (XVECEXP (body, 0, 0));
}
- else
- return -1;
- default:
- return -1;
}
+
+ return (ASM_OPERANDS_INPUT_LENGTH (asm_op)
+ + ASM_OPERANDS_LABEL_LENGTH (asm_op) + n_sets);
}
/* Assuming BODY is an insn body that uses ASM_OPERANDS,
@@ -1466,28 +1491,19 @@ decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
const char **constraints, enum machine_mode *modes,
location_t *loc)
{
- int i;
- int noperands;
- rtx asmop = 0;
+ int noperands, nbase = 0, n, i;
+ rtx asmop;
- if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
+ switch (GET_CODE (body))
{
- asmop = SET_SRC (body);
- /* Single output operand: BODY is (set OUTPUT (asm_operands ....)). */
-
- noperands = ASM_OPERANDS_INPUT_LENGTH (asmop) + 1;
+ case ASM_OPERANDS:
+ /* Zero output asm: BODY is (asm_operands ...). */
+ asmop = body;
+ break;
- for (i = 1; i < noperands; i++)
- {
- if (operand_locs)
- operand_locs[i] = &ASM_OPERANDS_INPUT (asmop, i - 1);
- if (operands)
- operands[i] = ASM_OPERANDS_INPUT (asmop, i - 1);
- if (constraints)
- constraints[i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i - 1);
- if (modes)
- modes[i] = ASM_OPERANDS_INPUT_MODE (asmop, i - 1);
- }
+ case SET:
+ /* Single output asm: BODY is (set OUTPUT (asm_operands ...)). */
+ asmop = SET_SRC (body);
/* The output is in the SET.
Its constraint is in the ASM_OPERANDS itself. */
@@ -1499,93 +1515,70 @@ decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
constraints[0] = ASM_OPERANDS_OUTPUT_CONSTRAINT (asmop);
if (modes)
modes[0] = GET_MODE (SET_DEST (body));
- }
- else if (GET_CODE (body) == ASM_OPERANDS)
- {
- asmop = body;
- /* No output operands: BODY is (asm_operands ....). */
-
- noperands = ASM_OPERANDS_INPUT_LENGTH (asmop);
-
- /* The input operands are found in the 1st element vector. */
- /* Constraints for inputs are in the 2nd element vector. */
- for (i = 0; i < noperands; i++)
- {
- if (operand_locs)
- operand_locs[i] = &ASM_OPERANDS_INPUT (asmop, i);
- if (operands)
- operands[i] = ASM_OPERANDS_INPUT (asmop, i);
- if (constraints)
- constraints[i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i);
- if (modes)
- modes[i] = ASM_OPERANDS_INPUT_MODE (asmop, i);
- }
- }
- else if (GET_CODE (body) == PARALLEL
- && GET_CODE (XVECEXP (body, 0, 0)) == SET
- && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
- {
- int nparallel = XVECLEN (body, 0); /* Includes CLOBBERs. */
- int nin;
- int nout = 0; /* Does not include CLOBBERs. */
-
- asmop = SET_SRC (XVECEXP (body, 0, 0));
- nin = ASM_OPERANDS_INPUT_LENGTH (asmop);
+ nbase = 1;
+ break;
- /* At least one output, plus some CLOBBERs. */
+ case PARALLEL:
+ {
+ int nparallel = XVECLEN (body, 0); /* Includes CLOBBERs. */
- /* The outputs are in the SETs.
- Their constraints are in the ASM_OPERANDS itself. */
- for (i = 0; i < nparallel; i++)
- {
- if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
- break; /* Past last SET */
+ asmop = XVECEXP (body, 0, 0);
+ if (GET_CODE (asmop) == SET)
+ {
+ asmop = SET_SRC (asmop);
- if (operands)
- operands[i] = SET_DEST (XVECEXP (body, 0, i));
- if (operand_locs)
- operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i));
- if (constraints)
- constraints[i] = XSTR (SET_SRC (XVECEXP (body, 0, i)), 1);
- if (modes)
- modes[i] = GET_MODE (SET_DEST (XVECEXP (body, 0, i)));
- nout++;
- }
+ /* At least one output, plus some CLOBBERs. The outputs are in
+ the SETs. Their constraints are in the ASM_OPERANDS itself. */
+ for (i = 0; i < nparallel; i++)
+ {
+ if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
+ break; /* Past last SET */
+ if (operands)
+ operands[i] = SET_DEST (XVECEXP (body, 0, i));
+ if (operand_locs)
+ operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i));
+ if (constraints)
+ constraints[i] = XSTR (SET_SRC (XVECEXP (body, 0, i)), 1);
+ if (modes)
+ modes[i] = GET_MODE (SET_DEST (XVECEXP (body, 0, i)));
+ }
+ nbase = i;
+ }
+ break;
+ }
- for (i = 0; i < nin; i++)
- {
- if (operand_locs)
- operand_locs[i + nout] = &ASM_OPERANDS_INPUT (asmop, i);
- if (operands)
- operands[i + nout] = ASM_OPERANDS_INPUT (asmop, i);
- if (constraints)
- constraints[i + nout] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i);
- if (modes)
- modes[i + nout] = ASM_OPERANDS_INPUT_MODE (asmop, i);
- }
+ default:
+ gcc_unreachable ();
}
- else if (GET_CODE (body) == PARALLEL
- && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
- {
- /* No outputs, but some CLOBBERs. */
-
- int nin;
- asmop = XVECEXP (body, 0, 0);
- nin = ASM_OPERANDS_INPUT_LENGTH (asmop);
+ noperands = (ASM_OPERANDS_INPUT_LENGTH (asmop)
+ + ASM_OPERANDS_LABEL_LENGTH (asmop) + nbase);
- for (i = 0; i < nin; i++)
- {
- if (operand_locs)
- operand_locs[i] = &ASM_OPERANDS_INPUT (asmop, i);
- if (operands)
- operands[i] = ASM_OPERANDS_INPUT (asmop, i);
- if (constraints)
- constraints[i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i);
- if (modes)
- modes[i] = ASM_OPERANDS_INPUT_MODE (asmop, i);
- }
+ n = ASM_OPERANDS_INPUT_LENGTH (asmop);
+ for (i = 0; i < n; i++)
+ {
+ if (operand_locs)
+ operand_locs[nbase + i] = &ASM_OPERANDS_INPUT (asmop, i);
+ if (operands)
+ operands[nbase + i] = ASM_OPERANDS_INPUT (asmop, i);
+ if (constraints)
+ constraints[nbase + i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i);
+ if (modes)
+ modes[nbase + i] = ASM_OPERANDS_INPUT_MODE (asmop, i);
+ }
+ nbase += n;
+ n = ASM_OPERANDS_LABEL_LENGTH (asmop);
+ for (i = 0; i < n; i++)
+ {
+ if (operand_locs)
+ operand_locs[nbase + i] = &ASM_OPERANDS_LABEL (asmop, i);
+ if (operands)
+ operands[nbase + i] = ASM_OPERANDS_LABEL (asmop, i);
+ if (constraints)
+ constraints[nbase + i] = "";
+ if (modes)
+ modes[nbase + i] = Pmode;
}
if (loc)
@@ -1605,6 +1598,11 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints)
/* Use constrain_operands after reload. */
gcc_assert (!reload_completed);
+ /* Empty constraint string is the same as "X,...,X", i.e. X for as
+ many alternatives as required to match the other operands. */
+ if (*constraint == '\0')
+ return 1;
+
while (*constraint)
{
char c = *constraint;
@@ -3234,37 +3232,35 @@ peephole2_optimize (void)
if (eh_edge->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
break;
- for (x = attempt ; x != before_try ; x = PREV_INSN (x))
- if (CALL_P (x)
- || (flag_non_call_exceptions
- && may_trap_p (PATTERN (x))
- && !find_reg_note (x, REG_EH_REGION, NULL)))
- {
- if (note)
- add_reg_note (x, REG_EH_REGION, XEXP (note, 0));
-
- if (x != BB_END (bb) && eh_edge)
- {
- edge nfte, nehe;
- int flags;
-
- nfte = split_block (bb, x);
- flags = (eh_edge->flags
- & (EDGE_EH | EDGE_ABNORMAL));
- if (CALL_P (x))
- flags |= EDGE_ABNORMAL_CALL;
- nehe = make_edge (nfte->src, eh_edge->dest,
- flags);
-
- nehe->probability = eh_edge->probability;
- nfte->probability
- = REG_BR_PROB_BASE - nehe->probability;
-
- do_cleanup_cfg |= purge_dead_edges (nfte->dest);
- bb = nfte->src;
- eh_edge = nehe;
- }
- }
+ if (note)
+ copy_reg_eh_region_note_backward (note, attempt,
+ before_try);
+
+ if (eh_edge)
+ for (x = attempt ; x != before_try ; x = PREV_INSN (x))
+ if (x != BB_END (bb)
+ && (can_throw_internal (x)
+ || can_nonlocal_goto (x)))
+ {
+ edge nfte, nehe;
+ int flags;
+
+ nfte = split_block (bb, x);
+ flags = (eh_edge->flags
+ & (EDGE_EH | EDGE_ABNORMAL));
+ if (CALL_P (x))
+ flags |= EDGE_ABNORMAL_CALL;
+ nehe = make_edge (nfte->src, eh_edge->dest,
+ flags);
+
+ nehe->probability = eh_edge->probability;
+ nfte->probability
+ = REG_BR_PROB_BASE - nehe->probability;
+
+ do_cleanup_cfg |= purge_dead_edges (nfte->dest);
+ bb = nfte->src;
+ eh_edge = nehe;
+ }
/* Converting possibly trapping insn to non-trapping is
possible. Zap dummy outgoing edges. */
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index ff09ad224d9..7e4ba6cad20 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -254,7 +254,7 @@ static void pop_stack (stack, int);
static rtx *get_true_reg (rtx *);
static int check_asm_stack_operands (rtx);
-static int get_asm_operand_n_inputs (rtx);
+static void get_asm_operands_in_out (rtx, int *, int *);
static rtx stack_result (tree);
static void replace_reg (rtx *, int);
static void remove_regno_note (rtx, enum reg_note, unsigned int);
@@ -480,8 +480,7 @@ check_asm_stack_operands (rtx insn)
preprocess_constraints ();
- n_inputs = get_asm_operand_n_inputs (body);
- n_outputs = recog_data.n_operands - n_inputs;
+ get_asm_operands_in_out (body, &n_outputs, &n_inputs);
if (alt < 0)
{
@@ -645,24 +644,15 @@ check_asm_stack_operands (rtx insn)
N_INPUTS and N_OUTPUTS are pointers to ints into which the results are
placed. */
-static int
-get_asm_operand_n_inputs (rtx body)
+static void
+get_asm_operands_in_out (rtx body, int *pout, int *pin)
{
- switch (GET_CODE (body))
- {
- case SET:
- gcc_assert (GET_CODE (SET_SRC (body)) == ASM_OPERANDS);
- return ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body));
-
- case ASM_OPERANDS:
- return ASM_OPERANDS_INPUT_LENGTH (body);
-
- case PARALLEL:
- return get_asm_operand_n_inputs (XVECEXP (body, 0, 0));
-
- default:
- gcc_unreachable ();
- }
+ rtx asmop = extract_asm_operands (body);
+
+ *pin = ASM_OPERANDS_INPUT_LENGTH (asmop);
+ *pout = (recog_data.n_operands
+ - ASM_OPERANDS_INPUT_LENGTH (asmop)
+ - ASM_OPERANDS_LABEL_LENGTH (asmop));
}
/* If current function returns its result in an fp stack register,
@@ -2034,8 +2024,7 @@ subst_asm_stack_regs (rtx insn, stack regstack)
preprocess_constraints ();
- n_inputs = get_asm_operand_n_inputs (body);
- n_outputs = recog_data.n_operands - n_inputs;
+ get_asm_operands_in_out (body, &n_outputs, &n_inputs);
gcc_assert (alt >= 0);
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index 9b03d64f590..0f11c91a3de 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -952,13 +952,18 @@ allocate_reg_info (void)
}
-/* Resize reg info. The new elements will be uninitialized. */
+/* Resize reg info. The new elements will be uninitialized. Return
+ TRUE if new elements (for new pseudos) were added. */
bool
resize_reg_info (void)
{
int old;
- gcc_assert (reg_pref != NULL);
+ if (reg_pref == NULL)
+ {
+ allocate_reg_info ();
+ return true;
+ }
if (reg_info_size == max_reg_num ())
return false;
old = reg_info_size;
@@ -1000,7 +1005,6 @@ reginfo_init (void)
/* This prevents dump_flow_info from losing if called
before reginfo is run. */
reg_pref = NULL;
- allocate_reg_info ();
/* No more global register variables may be declared. */
no_global_reg_vars = 1;
return 1;
diff --git a/gcc/regrename.c b/gcc/regrename.c
index 03aba8073a2..68d08749e6e 100644
--- a/gcc/regrename.c
+++ b/gcc/regrename.c
@@ -376,11 +376,26 @@ do_replace (struct du_chain *chain, int reg)
INSN_VAR_LOCATION_LOC (chain->insn) = gen_rtx_UNKNOWN_VAR_LOC ();
else
{
+ rtx note;
+
*chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg);
if (regno >= FIRST_PSEUDO_REGISTER)
ORIGINAL_REGNO (*chain->loc) = regno;
REG_ATTRS (*chain->loc) = attr;
REG_POINTER (*chain->loc) = reg_ptr;
+
+ for (note = REG_NOTES (chain->insn); note; note = XEXP (note, 1))
+ {
+ if (REG_NOTE_KIND (note) == REG_DEAD
+ || REG_NOTE_KIND (note) == REG_UNUSED)
+ {
+ rtx reg = XEXP (note, 0);
+ gcc_assert (HARD_REGISTER_P (reg));
+
+ if (REGNO (reg) == base_regno)
+ XEXP (note, 0) = *chain->loc;
+ }
+ }
}
df_insn_rescan (chain->insn);
diff --git a/gcc/reload1.c b/gcc/reload1.c
index d5cd37ce0bd..984913a5fc1 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -447,7 +447,6 @@ static rtx inc_for_reload (rtx, rtx, rtx, int);
#ifdef AUTO_INC_DEC
static void add_auto_inc_notes (rtx, rtx);
#endif
-static void copy_eh_notes (rtx, rtx);
static void substitute (rtx *, const_rtx, rtx);
static bool gen_reload_chain_without_interm_reg_p (int, int);
static int reloads_conflict (int, int);
@@ -4132,17 +4131,11 @@ static void
fixup_eh_region_note (rtx insn, rtx prev, rtx next)
{
rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
- rtx i;
-
if (note == NULL)
return;
-
- if (! may_trap_p (PATTERN (insn)))
+ if (!insn_could_throw_p (insn))
remove_note (insn, note);
-
- for (i = NEXT_INSN (prev); i != next; i = NEXT_INSN (i))
- if (INSN_P (i) && i != insn && may_trap_p (PATTERN (i)))
- add_reg_note (i, REG_EH_REGION, XEXP (note, 0));
+ copy_reg_eh_region_note_forward (note, NEXT_INSN (prev), next);
}
/* Reload pseudo-registers into hard regs around each insn as needed.
@@ -7294,7 +7287,7 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
}
if (flag_non_call_exceptions)
- copy_eh_notes (insn, get_insns ());
+ copy_reg_eh_region_note_forward (insn, get_insns (), NULL);
/* End this sequence. */
*where = get_insns ();
@@ -7514,7 +7507,7 @@ emit_output_reload_insns (struct insn_chain *chain, struct reload *rl,
output_reload_insns[rl->opnum] = get_insns ();
if (flag_non_call_exceptions)
- copy_eh_notes (insn, get_insns ());
+ copy_reg_eh_region_note_forward (insn, get_insns (), NULL);
end_sequence ();
}
@@ -8890,21 +8883,6 @@ add_auto_inc_notes (rtx insn, rtx x)
}
#endif
-/* Copy EH notes from an insn to its reloads. */
-static void
-copy_eh_notes (rtx insn, rtx x)
-{
- rtx eh_note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
- if (eh_note)
- {
- for (; x != 0; x = NEXT_INSN (x))
- {
- if (may_trap_p (PATTERN (x)))
- add_reg_note (x, REG_EH_REGION, XEXP (eh_note, 0));
- }
- }
-}
-
/* This is used by reload pass, that does emit some instructions after
abnormal calls moving basic block end, but in fact it wants to emit
them on the edge. Looks for abnormal call edges, find backward the
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 4453ccabca6..4871b0e8c29 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -1630,13 +1630,14 @@ redundant_insn (rtx insn, rtx target, rtx delay_list)
for (trial = PREV_INSN (target),
insns_to_search = MAX_DELAY_SLOT_INSN_SEARCH;
trial && insns_to_search > 0;
- trial = PREV_INSN (trial), --insns_to_search)
+ trial = PREV_INSN (trial))
{
if (LABEL_P (trial))
return 0;
- if (! INSN_P (trial))
+ if (!NONDEBUG_INSN_P (trial))
continue;
+ --insns_to_search;
pat = PATTERN (trial);
if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER)
@@ -1735,10 +1736,11 @@ redundant_insn (rtx insn, rtx target, rtx delay_list)
for (trial = PREV_INSN (target),
insns_to_search = MAX_DELAY_SLOT_INSN_SEARCH;
trial && !LABEL_P (trial) && insns_to_search > 0;
- trial = PREV_INSN (trial), --insns_to_search)
+ trial = PREV_INSN (trial))
{
- if (!INSN_P (trial))
+ if (!NONDEBUG_INSN_P (trial))
continue;
+ --insns_to_search;
pat = PATTERN (trial);
if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER)
diff --git a/gcc/rtl.def b/gcc/rtl.def
index bcb5cbcd9b0..2aa76b1f6c8 100644
--- a/gcc/rtl.def
+++ b/gcc/rtl.def
@@ -187,8 +187,9 @@ DEF_RTL_EXPR(ASM_INPUT, "asm_input", "si", RTX_EXTRA)
5th is a vector of modes and constraints for the input operands.
Each element is an ASM_INPUT containing a constraint string
and whose mode indicates the mode of the input operand.
- 6th is the source line number. */
-DEF_RTL_EXPR(ASM_OPERANDS, "asm_operands", "ssiEEi", RTX_EXTRA)
+ 6th is a vector of labels that may be branched to by the asm.
+ 7th is the source line number. */
+DEF_RTL_EXPR(ASM_OPERANDS, "asm_operands", "ssiEEEi", RTX_EXTRA)
/* A machine-specific operation.
1st operand is a vector of operands being used by the operation so that
@@ -301,11 +302,6 @@ DEF_RTL_EXPR(EH_RETURN, "eh_return", "", RTX_EXTRA)
For an unconditional trap, make the condition (const_int 1). */
DEF_RTL_EXPR(TRAP_IF, "trap_if", "ee", RTX_EXTRA)
-/* Placeholder for _Unwind_Resume before we know if a function call
- or a branch is needed. Operand 1 is the exception region from
- which control is flowing. */
-DEF_RTL_EXPR(RESX, "resx", "i", RTX_EXTRA)
-
/* ----------------------------------------------------------------------
Primitive values for use in expressions.
---------------------------------------------------------------------- */
diff --git a/gcc/rtl.h b/gcc/rtl.h
index c5839df4ecb..925246f787b 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -255,8 +255,7 @@ struct GTY((chain_next ("RTX_NEXT (&%h)"),
ECF_LOOPING_CONST_OR_PURE and DECL_LOOPING_CONST_OR_PURE_P. */
unsigned int call : 1;
/* 1 in a REG, MEM, or CONCAT if the value is set at most once, anywhere.
- 1 in a SUBREG if it references an unsigned object whose mode has been
- from a promoted to a wider mode.
+ 1 in a SUBREG used for SUBREG_PROMOTED_UNSIGNED_P.
1 in a SYMBOL_REF if it addresses something in the per-function
constants pool.
1 in a CALL_INSN logically equivalent to ECF_CONST and TREE_READONLY.
@@ -268,10 +267,12 @@ struct GTY((chain_next ("RTX_NEXT (&%h)"),
if it has been deleted.
1 in a REG expression if corresponds to a variable declared by the user,
0 for an internally generated temporary.
- 1 in a SUBREG with a negative value.
+ 1 in a SUBREG used for SUBREG_PROMOTED_UNSIGNED_P.
1 in a LABEL_REF, REG_LABEL_TARGET or REG_LABEL_OPERAND note for a
non-local label.
- In a SYMBOL_REF, this flag is used for machine-specific purposes. */
+ In a SYMBOL_REF, this flag is used for machine-specific purposes.
+ In a PREFETCH, this flag indicates that it should be considered a scheduling
+ barrier. */
unsigned int volatil : 1;
/* 1 in a MEM referring to a field of an aggregate.
0 if the MEM was a variable or the result of a * operator in C;
@@ -1159,6 +1160,15 @@ do { \
_rtx->unchanging = (VAL); \
} \
} while (0)
+
+/* Valid for subregs which are SUBREG_PROMOTED_VAR_P(). In that case
+ this gives the necessary extensions:
+ 0 - signed
+ 1 - normal unsigned
+ -1 - pointer unsigned, which most often can be handled like unsigned
+ extension, except for generating instructions where we need to
+ emit special code (ptr_extend insns) on some architectures. */
+
#define SUBREG_PROMOTED_UNSIGNED_P(RTX) \
((RTL_FLAG_CHECK1("SUBREG_PROMOTED_UNSIGNED_P", (RTX), SUBREG)->volatil) \
? -1 : (int) (RTX)->unchanging)
@@ -1178,7 +1188,10 @@ do { \
XSTR (XCVECEXP (RTX, 4, N, ASM_OPERANDS), 0)
#define ASM_OPERANDS_INPUT_MODE(RTX, N) \
GET_MODE (XCVECEXP (RTX, 4, N, ASM_OPERANDS))
-#define ASM_OPERANDS_SOURCE_LOCATION(RTX) XCUINT (RTX, 5, ASM_OPERANDS)
+#define ASM_OPERANDS_LABEL_VEC(RTX) XCVEC (RTX, 5, ASM_OPERANDS)
+#define ASM_OPERANDS_LABEL_LENGTH(RTX) XCVECLEN (RTX, 5, ASM_OPERANDS)
+#define ASM_OPERANDS_LABEL(RTX, N) XCVECEXP (RTX, 5, N, ASM_OPERANDS)
+#define ASM_OPERANDS_SOURCE_LOCATION(RTX) XCUINT (RTX, 6, ASM_OPERANDS)
#define ASM_INPUT_SOURCE_LOCATION(RTX) XCUINT (RTX, 1, ASM_INPUT)
/* 1 if RTX is a mem that is statically allocated in read-only memory. */
@@ -1423,6 +1436,10 @@ do { \
offset within that block. */
#define SYMBOL_REF_BLOCK_OFFSET(RTX) (BLOCK_SYMBOL_CHECK (RTX)->offset)
+/* True if RTX is flagged to be a scheduling barrier. */
+#define PREFETCH_SCHEDULE_BARRIER_P(RTX) \
+ (RTL_FLAG_CHECK1("PREFETCH_SCHEDULE_BARRIER_P", (RTX), PREFETCH)->volatil)
+
/* Indicate whether the machine has any sort of auto increment addressing.
If not, we can avoid checking for REG_INC notes. */
@@ -1827,6 +1844,13 @@ extern int volatile_insn_p (const_rtx);
extern int may_trap_p_1 (const_rtx, unsigned);
extern int may_trap_p (const_rtx);
extern int may_trap_or_fault_p (const_rtx);
+extern bool can_throw_internal (const_rtx);
+extern bool can_throw_external (const_rtx);
+extern bool insn_could_throw_p (const_rtx);
+extern bool insn_nothrow_p (const_rtx);
+extern bool can_nonlocal_goto (const_rtx);
+extern void copy_reg_eh_region_note_forward (rtx, rtx, rtx);
+extern void copy_reg_eh_region_note_backward(rtx, rtx, rtx);
extern int inequality_comparisons_p (const_rtx);
extern rtx replace_rtx (rtx, rtx, rtx);
extern int replace_label (rtx *, void *);
@@ -1905,6 +1929,7 @@ extern bool resize_reg_info (void);
extern void free_reg_info (void);
/* recog.c */
+extern rtx extract_asm_operands (rtx);
extern int asm_noperands (const_rtx);
extern const char *decode_asm_operands (rtx, rtx *, rtx **, const char **,
enum machine_mode *, location_t *);
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 25f03d26b57..cef383a1d0e 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -2487,6 +2487,11 @@ sched_analyze_2 (struct deps *deps, rtx x, rtx insn)
flush_pending_lists (deps, insn, true, false);
break;
+ case PREFETCH:
+ if (PREFETCH_SCHEDULE_BARRIER_P (x))
+ reg_pending_barrier = TRUE_BARRIER;
+ break;
+
case UNSPEC_VOLATILE:
flush_pending_lists (deps, insn, true, true);
/* FALLTHRU */
@@ -2593,6 +2598,12 @@ sched_analyze_insn (struct deps *deps, rtx x, rtx insn)
can_start_lhs_rhs_p = (NONJUMP_INSN_P (insn)
&& code == SET);
+ if (may_trap_p (x))
+ /* Avoid moving trapping instructions accross function calls that might
+ not always return. */
+ add_dependence_list (insn, deps->last_function_call_may_noreturn,
+ 1, REG_DEP_ANTI);
+
if (code == COND_EXEC)
{
sched_analyze_2 (deps, COND_EXEC_TEST (x), insn);
@@ -3109,6 +3120,73 @@ sched_analyze_insn (struct deps *deps, rtx x, rtx insn)
}
}
+/* Return TRUE if INSN might not always return normally (e.g. call exit,
+ longjmp, loop forever, ...). */
+static bool
+call_may_noreturn_p (rtx insn)
+{
+ rtx call;
+
+ /* const or pure calls that aren't looping will always return. */
+ if (RTL_CONST_OR_PURE_CALL_P (insn)
+ && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn))
+ return false;
+
+ call = PATTERN (insn);
+ if (GET_CODE (call) == PARALLEL)
+ call = XVECEXP (call, 0, 0);
+ if (GET_CODE (call) == SET)
+ call = SET_SRC (call);
+ if (GET_CODE (call) == CALL
+ && MEM_P (XEXP (call, 0))
+ && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
+ {
+ rtx symbol = XEXP (XEXP (call, 0), 0);
+ if (SYMBOL_REF_DECL (symbol)
+ && TREE_CODE (SYMBOL_REF_DECL (symbol)) == FUNCTION_DECL)
+ {
+ if (DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (symbol))
+ == BUILT_IN_NORMAL)
+ switch (DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol)))
+ {
+ case BUILT_IN_BCMP:
+ case BUILT_IN_BCOPY:
+ case BUILT_IN_BZERO:
+ case BUILT_IN_INDEX:
+ case BUILT_IN_MEMCHR:
+ case BUILT_IN_MEMCMP:
+ case BUILT_IN_MEMCPY:
+ case BUILT_IN_MEMMOVE:
+ case BUILT_IN_MEMPCPY:
+ case BUILT_IN_MEMSET:
+ case BUILT_IN_RINDEX:
+ case BUILT_IN_STPCPY:
+ case BUILT_IN_STPNCPY:
+ case BUILT_IN_STRCAT:
+ case BUILT_IN_STRCHR:
+ case BUILT_IN_STRCMP:
+ case BUILT_IN_STRCPY:
+ case BUILT_IN_STRCSPN:
+ case BUILT_IN_STRLEN:
+ case BUILT_IN_STRNCAT:
+ case BUILT_IN_STRNCMP:
+ case BUILT_IN_STRNCPY:
+ case BUILT_IN_STRPBRK:
+ case BUILT_IN_STRRCHR:
+ case BUILT_IN_STRSPN:
+ case BUILT_IN_STRSTR:
+ /* Assume certain string/memory builtins always return. */
+ return false;
+ default:
+ break;
+ }
+ }
+ }
+
+ /* For all other calls assume that they might not always return. */
+ return true;
+}
+
/* Analyze INSN with DEPS as a context. */
void
deps_analyze_insn (struct deps *deps, rtx insn)
@@ -3207,7 +3285,16 @@ deps_analyze_insn (struct deps *deps, rtx insn)
/* Remember the last function call for limiting lifetimes. */
free_INSN_LIST_list (&deps->last_function_call);
deps->last_function_call = alloc_INSN_LIST (insn, NULL_RTX);
-
+
+ if (call_may_noreturn_p (insn))
+ {
+ /* Remember the last function call that might not always return
+ normally for limiting moves of trapping insns. */
+ free_INSN_LIST_list (&deps->last_function_call_may_noreturn);
+ deps->last_function_call_may_noreturn
+ = alloc_INSN_LIST (insn, NULL_RTX);
+ }
+
/* Before reload, begin a post-call group, so as to keep the
lifetimes of hard registers correct. */
if (! reload_completed)
@@ -3361,6 +3448,7 @@ init_deps (struct deps *deps)
deps->pending_flush_length = 0;
deps->last_pending_memory_flush = 0;
deps->last_function_call = 0;
+ deps->last_function_call_may_noreturn = 0;
deps->sched_before_next_call = 0;
deps->in_post_call_group_p = not_post_call;
deps->last_debug_insn = 0;
@@ -3441,7 +3529,11 @@ remove_from_deps (struct deps *deps, rtx insn)
}
if (CALL_P (insn))
- remove_from_dependence_list (insn, &deps->last_function_call);
+ {
+ remove_from_dependence_list (insn, &deps->last_function_call);
+ remove_from_dependence_list (insn,
+ &deps->last_function_call_may_noreturn);
+ }
remove_from_dependence_list (insn, &deps->sched_before_next_call);
}
diff --git a/gcc/sched-int.h b/gcc/sched-int.h
index de780e5e395..4d60ece28c9 100644
--- a/gcc/sched-int.h
+++ b/gcc/sched-int.h
@@ -502,6 +502,12 @@ struct deps
Used to prevent register lifetimes from expanding unnecessarily. */
rtx last_function_call;
+ /* A list of the last function calls that may not return normally
+ we have seen. We use a list to represent last function calls from
+ multiple predecessor blocks. Used to prevent moving trapping insns
+ across such calls. */
+ rtx last_function_call_may_noreturn;
+
/* A list of insns which use a pseudo register that does not already
cross a call. We create dependencies between each of those insn
and the next call insn, to ensure that they won't cross a call after
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index ff559adcda5..de2dd0acd1d 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -2645,6 +2645,11 @@ deps_join (struct deps *succ_deps, struct deps *pred_deps)
= concat_INSN_LIST (pred_deps->last_function_call,
succ_deps->last_function_call);
+ /* last_function_call_may_noreturn is inherited by successor. */
+ succ_deps->last_function_call_may_noreturn
+ = concat_INSN_LIST (pred_deps->last_function_call_may_noreturn,
+ succ_deps->last_function_call_may_noreturn);
+
/* sched_before_next_call is inherited by successor. */
succ_deps->sched_before_next_call
= concat_INSN_LIST (pred_deps->sched_before_next_call,
diff --git a/gcc/sese.c b/gcc/sese.c
index 394d465f098..e2c9eb8848f 100644
--- a/gcc/sese.c
+++ b/gcc/sese.c
@@ -1186,7 +1186,6 @@ graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb, htab_t map)
{
def_operand_p def_p;
ssa_op_iter op_iter;
- int region;
gimple stmt = gsi_stmt (gsi);
gimple copy;
@@ -1199,9 +1198,7 @@ graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb, htab_t map)
gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);
mark_sym_for_renaming (gimple_vop (cfun));
- region = lookup_stmt_eh_region (stmt);
- if (region >= 0)
- add_stmt_to_eh_region (copy, region);
+ maybe_duplicate_eh_stmt (copy, stmt);
gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt);
/* Create new names for all the definitions created by COPY and
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 23fdd08dd30..42f22b5868b 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -110,8 +110,8 @@ static int n_occurrences (int, const char *);
static bool tree_conflicts_with_clobbers_p (tree, HARD_REG_SET *);
static void expand_nl_goto_receiver (void);
static bool check_operand_nalternatives (tree, tree);
-static bool check_unique_operand_names (tree, tree);
-static char *resolve_operand_name_1 (char *, tree, tree);
+static bool check_unique_operand_names (tree, tree, tree);
+static char *resolve_operand_name_1 (char *, tree, tree, tree);
static void expand_null_return_1 (void);
static void expand_value_return (rtx);
static int estimate_case_costs (case_node_ptr);
@@ -633,12 +633,13 @@ tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET *clobbered_regs)
static void
expand_asm_operands (tree string, tree outputs, tree inputs,
- tree clobbers, int vol, location_t locus)
+ tree clobbers, tree labels, int vol, location_t locus)
{
- rtvec argvec, constraintvec;
+ rtvec argvec, constraintvec, labelvec;
rtx body;
int ninputs = list_length (inputs);
int noutputs = list_length (outputs);
+ int nlabels = list_length (labels);
int ninout;
int nclobbers;
HARD_REG_SET clobbered_regs;
@@ -661,7 +662,7 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
if (! check_operand_nalternatives (outputs, inputs))
return;
- string = resolve_asm_operand_names (string, outputs, inputs);
+ string = resolve_asm_operand_names (string, outputs, inputs, labels);
/* Collect constraints. */
i = 0;
@@ -845,12 +846,13 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
argvec = rtvec_alloc (ninputs);
constraintvec = rtvec_alloc (ninputs);
+ labelvec = rtvec_alloc (nlabels);
body = gen_rtx_ASM_OPERANDS ((noutputs == 0 ? VOIDmode
: GET_MODE (output_rtx[0])),
ggc_strdup (TREE_STRING_POINTER (string)),
empty_string, 0, argvec, constraintvec,
- locus);
+ labelvec, locus);
MEM_VOLATILE_P (body) = vol;
@@ -959,6 +961,11 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
= gen_rtx_ASM_INPUT (inout_mode[i], ggc_strdup (buffer));
}
+ /* Copy labels to the vector. */
+ for (i = 0, tail = labels; i < nlabels; ++i, tail = TREE_CHAIN (tail))
+ ASM_OPERANDS_LABEL (body, i)
+ = gen_rtx_LABEL_REF (Pmode, label_rtx (TREE_VALUE (tail)));
+
generating_concat_p = old_generating_concat_p;
/* Now, for each output, construct an rtx
@@ -966,18 +973,21 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
ARGVEC CONSTRAINTS OPNAMES))
If there is more than one, put them inside a PARALLEL. */
- if (noutputs == 1 && nclobbers == 0)
+ if (nlabels > 0 && nclobbers == 0)
{
- ASM_OPERANDS_OUTPUT_CONSTRAINT (body) = ggc_strdup (constraints[0]);
- emit_insn (gen_rtx_SET (VOIDmode, output_rtx[0], body));
+ gcc_assert (noutputs == 0);
+ emit_jump_insn (body);
}
-
else if (noutputs == 0 && nclobbers == 0)
{
/* No output operands: put in a raw ASM_OPERANDS rtx. */
emit_insn (body);
}
-
+ else if (noutputs == 1 && nclobbers == 0)
+ {
+ ASM_OPERANDS_OUTPUT_CONSTRAINT (body) = ggc_strdup (constraints[0]);
+ emit_insn (gen_rtx_SET (VOIDmode, output_rtx[0], body));
+ }
else
{
rtx obody = body;
@@ -998,7 +1008,7 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
(GET_MODE (output_rtx[i]),
ggc_strdup (TREE_STRING_POINTER (string)),
ggc_strdup (constraints[i]),
- i, argvec, constraintvec, locus));
+ i, argvec, constraintvec, labelvec, locus));
MEM_VOLATILE_P (SET_SRC (XVECEXP (body, 0, i))) = vol;
}
@@ -1062,7 +1072,10 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
= gen_rtx_CLOBBER (VOIDmode, clobbered_reg);
}
- emit_insn (body);
+ if (nlabels > 0)
+ emit_jump_insn (body);
+ else
+ emit_insn (body);
}
/* For any outputs that needed reloading into registers, spill them
@@ -1083,7 +1096,7 @@ expand_asm_stmt (gimple stmt)
tree *o;
size_t i, n;
const char *s;
- tree str, out, in, cl;
+ tree str, out, in, cl, labels;
/* Meh... convert the gimple asm operands into real tree lists.
Eventually we should make all routines work on the vectors instead
@@ -1094,10 +1107,7 @@ expand_asm_stmt (gimple stmt)
{
t = out = gimple_asm_output_op (stmt, 0);
for (i = 1; i < n; i++)
- {
- TREE_CHAIN (t) = gimple_asm_output_op (stmt, i);
- t = gimple_asm_output_op (stmt, i);
- }
+ t = TREE_CHAIN (t) = gimple_asm_output_op (stmt, i);
}
in = NULL_TREE;
@@ -1106,10 +1116,7 @@ expand_asm_stmt (gimple stmt)
{
t = in = gimple_asm_input_op (stmt, 0);
for (i = 1; i < n; i++)
- {
- TREE_CHAIN (t) = gimple_asm_input_op (stmt, i);
- t = gimple_asm_input_op (stmt, i);
- }
+ t = TREE_CHAIN (t) = gimple_asm_input_op (stmt, i);
}
cl = NULL_TREE;
@@ -1118,10 +1125,16 @@ expand_asm_stmt (gimple stmt)
{
t = cl = gimple_asm_clobber_op (stmt, 0);
for (i = 1; i < n; i++)
- {
- TREE_CHAIN (t) = gimple_asm_clobber_op (stmt, i);
- t = gimple_asm_clobber_op (stmt, i);
- }
+ t = TREE_CHAIN (t) = gimple_asm_clobber_op (stmt, i);
+ }
+
+ labels = NULL_TREE;
+ n = gimple_asm_nlabels (stmt);
+ if (n > 0)
+ {
+ t = labels = gimple_asm_label_op (stmt, 0);
+ for (i = 1; i < n; i++)
+ t = TREE_CHAIN (t) = gimple_asm_label_op (stmt, i);
}
s = gimple_asm_string (stmt);
@@ -1144,8 +1157,8 @@ expand_asm_stmt (gimple stmt)
/* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of
OUTPUTS some trees for where the values were actually stored. */
- expand_asm_operands (str, outputs, in, cl, gimple_asm_volatile_p (stmt),
- input_location);
+ expand_asm_operands (str, outputs, in, cl, labels,
+ gimple_asm_volatile_p (stmt), input_location);
/* Copy all the intermediate outputs into the specified outputs. */
for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
@@ -1210,7 +1223,7 @@ check_operand_nalternatives (tree outputs, tree inputs)
so all we need are pointer comparisons. */
static bool
-check_unique_operand_names (tree outputs, tree inputs)
+check_unique_operand_names (tree outputs, tree inputs, tree labels)
{
tree i, j;
@@ -1239,6 +1252,20 @@ check_unique_operand_names (tree outputs, tree inputs)
goto failure;
}
+ for (i = labels; i ; i = TREE_CHAIN (i))
+ {
+ tree i_name = TREE_PURPOSE (i);
+ if (! i_name)
+ continue;
+
+ for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
+ if (simple_cst_equal (i_name, TREE_PURPOSE (j)))
+ goto failure;
+ for (j = inputs; j ; j = TREE_CHAIN (j))
+ if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
+ goto failure;
+ }
+
return true;
failure:
@@ -1252,14 +1279,14 @@ check_unique_operand_names (tree outputs, tree inputs)
STRING and in the constraints to those numbers. */
tree
-resolve_asm_operand_names (tree string, tree outputs, tree inputs)
+resolve_asm_operand_names (tree string, tree outputs, tree inputs, tree labels)
{
char *buffer;
char *p;
const char *c;
tree t;
- check_unique_operand_names (outputs, inputs);
+ check_unique_operand_names (outputs, inputs, labels);
/* Substitute [<name>] in input constraint strings. There should be no
named operands in output constraints. */
@@ -1270,7 +1297,7 @@ resolve_asm_operand_names (tree string, tree outputs, tree inputs)
{
p = buffer = xstrdup (c);
while ((p = strchr (p, '[')) != NULL)
- p = resolve_operand_name_1 (p, outputs, inputs);
+ p = resolve_operand_name_1 (p, outputs, inputs, NULL);
TREE_VALUE (TREE_PURPOSE (t))
= build_string (strlen (buffer), buffer);
free (buffer);
@@ -1313,7 +1340,7 @@ resolve_asm_operand_names (tree string, tree outputs, tree inputs)
continue;
}
- p = resolve_operand_name_1 (p, outputs, inputs);
+ p = resolve_operand_name_1 (p, outputs, inputs, labels);
}
string = build_string (strlen (buffer), buffer);
@@ -1329,53 +1356,49 @@ resolve_asm_operand_names (tree string, tree outputs, tree inputs)
balance of the string after substitution. */
static char *
-resolve_operand_name_1 (char *p, tree outputs, tree inputs)
+resolve_operand_name_1 (char *p, tree outputs, tree inputs, tree labels)
{
char *q;
int op;
tree t;
- size_t len;
/* Collect the operand name. */
- q = strchr (p, ']');
+ q = strchr (++p, ']');
if (!q)
{
error ("missing close brace for named operand");
return strchr (p, '\0');
}
- len = q - p - 1;
+ *q = '\0';
/* Resolve the name to a number. */
for (op = 0, t = outputs; t ; t = TREE_CHAIN (t), op++)
{
tree name = TREE_PURPOSE (TREE_PURPOSE (t));
- if (name)
- {
- const char *c = TREE_STRING_POINTER (name);
- if (strncmp (c, p + 1, len) == 0 && c[len] == '\0')
- goto found;
- }
+ if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
+ goto found;
}
for (t = inputs; t ; t = TREE_CHAIN (t), op++)
{
tree name = TREE_PURPOSE (TREE_PURPOSE (t));
- if (name)
- {
- const char *c = TREE_STRING_POINTER (name);
- if (strncmp (c, p + 1, len) == 0 && c[len] == '\0')
- goto found;
- }
+ if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
+ goto found;
+ }
+ for (t = labels; t ; t = TREE_CHAIN (t), op++)
+ {
+ tree name = TREE_PURPOSE (t);
+ if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
+ goto found;
}
- *q = '\0';
- error ("undefined named operand %qs", identifier_to_locale (p + 1));
+ error ("undefined named operand %qs", identifier_to_locale (p));
op = 0;
- found:
+ found:
/* Replace the name with the number. Unfortunately, not all libraries
get the return value of sprintf correct, so search for the end of the
generated string by hand. */
- sprintf (p, "%d", op);
+ sprintf (--p, "%d", op);
p = strchr (p, '\0');
/* Verify the no extra buffer space assumption. */
diff --git a/gcc/system.h b/gcc/system.h
index b74e0e5df2f..1b36ddf389a 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -414,6 +414,14 @@ extern void *calloc (size_t, size_t);
extern void *realloc (void *, size_t);
#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
/* If the system doesn't provide strsignal, we get it defined in
libiberty but no declaration is supplied. */
#if !defined (HAVE_STRSIGNAL) \
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 286e1e68cd7..728e018f71d 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -388,6 +388,9 @@
#define TARGET_VECTOR_ALIGNMENT_REACHABLE \
default_builtin_vector_alignment_reachable
#define TARGET_VECTORIZE_BUILTIN_VEC_PERM 0
+#define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
+ default_builtin_support_vector_misalignment
+
#define TARGET_VECTORIZE \
{ \
@@ -398,7 +401,8 @@
TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD, \
TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST, \
TARGET_VECTOR_ALIGNMENT_REACHABLE, \
- TARGET_VECTORIZE_BUILTIN_VEC_PERM \
+ TARGET_VECTORIZE_BUILTIN_VEC_PERM, \
+ TARGET_SUPPORT_VECTOR_MISALIGNMENT \
}
#define TARGET_DEFAULT_TARGET_FLAGS 0
diff --git a/gcc/target.h b/gcc/target.h
index 7f7f177904f..c57b683a4fc 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -481,6 +481,11 @@ struct gcc_target
/* Target builtin that implements vector permute. */
tree (* builtin_vec_perm) (tree, tree*);
+ /* Return true if the target supports misaligned store/load of a
+ specific factor denoted in the third parameter. The last parameter
+ is true if the access is defined in a packed struct. */
+ bool (* builtin_support_vector_misalignment) (enum machine_mode,
+ const_tree, int, bool);
} vectorize;
/* The initial value of target_flags. */
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 7535bc10ab7..8480c0b833f 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -771,6 +771,23 @@ default_builtin_vector_alignment_reachable (const_tree type, bool is_packed)
return true;
}
+/* By default, assume that a target supports any factor of misalignment
+ memory access if it supports movmisalign patten.
+ is_packed is true if the memory access is defined in a packed struct. */
+bool
+default_builtin_support_vector_misalignment (enum machine_mode mode,
+ const_tree type
+ ATTRIBUTE_UNUSED,
+ int misalignment
+ ATTRIBUTE_UNUSED,
+ bool is_packed
+ ATTRIBUTE_UNUSED)
+{
+ if (optab_handler (movmisalign_optab, mode)->insn_code != CODE_FOR_nothing)
+ return true;
+ return false;
+}
+
bool
default_hard_regno_scratch_ok (unsigned int regno ATTRIBUTE_UNUSED)
{
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 4e5f631e76c..7a9355292ae 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -77,6 +77,10 @@ extern tree default_builtin_vectorized_conversion (unsigned int, tree);
extern tree default_builtin_reciprocal (unsigned int, bool, bool);
extern bool default_builtin_vector_alignment_reachable (const_tree, bool);
+extern bool
+default_builtin_support_vector_misalignment (enum machine_mode mode,
+ const_tree,
+ int, bool);
/* These are here, and not in hooks.[ch], because not all users of
hooks.h include tm.h, and thus we don't have CUMULATIVE_ARGS. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1317b16d5e7..c6270142d4a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,492 @@
+2009-09-17 Janis Johnson <janis187@us.ibm.com>
+
+ PR c/41049
+ * dfp/pr41049.c: New test.
+
+2009-09-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR testsuite/41385
+ * gcc.dg/dfp/dfp.exp: Properly save DEFAULT_CFLAGS.
+
+2009-09-17 Martin Jambor <mjambor@suse.cz>
+
+ * gcc.dg/struct/wo_prof_escape_arg_to_local.c: Do not run IPA-SRA.
+ * gcc.dg/ipa/ipa-sra-1.c: New test.
+ * gcc.dg/ipa/ipa-sra-2.c: New test.
+ * gcc.dg/ipa/ipa-sra-3.c: New test.
+ * gcc.dg/ipa/ipa-sra-4.c: New test.
+ * gcc.dg/ipa/ipa-sra-5.c: New test.
+ * gcc.c-torture/execute/ipa-sra-1.c: New test.
+ * gcc.c-torture/execute/ipa-sra-2.c: New test.
+
+2009-09-17 Michael Matz <matz@suse.de>
+
+ PR middle-end/41347
+ * gfortran.dg/pr41347.f90: New test.
+
+2009-09-17 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * gcc.c-torture/compile/20090917-1.c: New testcase.
+
+2009-09-16 Uros Bizjak <ubizjak@gmail.com>
+
+ * gfortran.dg/default_format_denormal_2.f90: Add ieee options.
+ * gfortran.dg/default_format_denormal_1.f90: Ditto. Remove
+ alpha*-*-* target from XFAIL list.
+
+2009-09-16 Janis Johnson <janis187@us.ibm.com>
+
+ * gcc.dg/dfp/dfp.exp: Use appropriate default options.
+ * gcc.dg/dfp/dfp-dbg.h: New; define FAILURE, FINISH.
+ * gcc.dg/dfp/cast-bad.c: Use default options.
+ * gcc.dg/dfp/compare-rel-const.c: Ditto.
+ * gcc.dg/dfp/composite-type.c: Ditto.
+ * gcc.dg/dfp/constants.c: Ditto.
+ * gcc.dg/dfp/constants-hex.c: Ditto.
+ * gcc.dg/dfp/constants-pedantic.c: Ditto.
+ * gcc.dg/dfp/convert-bfp-fold.c: Ditto.
+ * gcc.dg/dfp/convert-dfp-fold.c: Ditto.
+ * gcc.dg/dfp/convert-int-max-fold.c: Ditto.
+ * gcc.dg/dfp/ctypes.c: Ditto.
+ * gcc.dg/dfp/ddmode-ice.c: Ditto.
+ * gcc.dg/dfp/dec-eval-method-2.c: Ditto.
+ * gcc.dg/dfp/float-constant-double.c: Ditto.
+ * gcc.dg/dfp/keywords-pedantic.c: Ditto.
+ * gcc.dg/dfp/keywords-reserved.c: Ditto.
+ * gcc.dg/dfp/modes.c: Ditto.
+ * gcc.dg/dfp/operator-bitwise.c: Ditto.
+ * gcc.dg/dfp/pr31344.c: Ditto.
+ * gcc.dg/dfp/pr31385.c: Ditto.
+ * gcc.dg/dfp/pr33466.c: Ditto.
+ * gcc.dg/dfp/pr35620.c: Ditto.
+ * gcc.dg/dfp/pr37435.c: Ditto.
+ * gcc.dg/dfp/pr39986.c: Ditto.
+ * gcc.dg/dfp/pragma-float-const-decimal64-1.c: Ditto.
+ * gcc.dg/dfp/pragma-float-const-decimal64-2.c: Ditto.
+ * gcc.dg/dfp/pragma-float-const-decimal64-3.c: Ditto.
+ * gcc.dg/dfp/pragma-float-const-decimal64-4.c: Ditto.
+ * gcc.dg/dfp/pragma-float-const-decimal64-7.c: Ditto.
+ * gcc.dg/dfp/pragma-float-const-decimal64-8.c: Ditto.
+ * gcc.dg/dfp/typespec.c: Ditto.
+ * gcc.dg/dfp/usual-arith-conv-bad.c: Ditto.
+ * gcc.dg/dfp/usual-arith-conv-bad-2.c: Ditto.
+ * gcc.dg/dfp/usual-arith-conv-const.c: Ditto.
+ * gcc.dg/dfp/Wbad-function-cast-1.c: Ditto.
+ * gcc.dg/dfp/Wtraditional-conversion-2.c: Ditto.
+ * gcc.dg/dfp/wtr-conversion-1.c: Ditto.
+ * gcc.dg/dfp/compare-eq.h: Define custom debug macros.
+ * gcc.dg/dfp/compare-rel.h: Ditto.
+ * gcc.dg/dfp/compare-special.h: Ditto.
+ * gcc.dg/dfp/convert.h: Ditto.
+ * gcc.dg/dfp/fe-check.h: Ditto.
+ * gcc.dg/dfp/call-by-value.c: Use default options and
+ debug macros.
+ * gcc.dg/dfp/cast.c: Ditto.
+ * gcc.dg/dfp/compare-eq-const.c: Ditto.
+ * gcc.dg/dfp/compare-eq-d32.c: Ditto.
+ * gcc.dg/dfp/compare-eq-d64.c: Ditto.
+ * gcc.dg/dfp/compare-eq-d128.c: Ditto.
+ * gcc.dg/dfp/compare-eq-dfp.c: Ditto.
+ * gcc.dg/dfp/compare-rel-d32.c: Ditto.
+ * gcc.dg/dfp/compare-rel-d64.c: Ditto.
+ * gcc.dg/dfp/compare-rel-d128.c: Ditto.
+ * gcc.dg/dfp/compare-rel-dfp.c: Ditto.
+ * gcc.dg/dfp/compare-special-d32.c: Ditto.
+ * gcc.dg/dfp/compare-special-d64.c: Ditto.
+ * gcc.dg/dfp/compare-special-d128.c: Ditto.
+ * gcc.dg/dfp/constants-zero.c: Ditto.
+ * gcc.dg/dfp/convert-bfp-2.c: Ditto.
+ * gcc.dg/dfp/convert-bfp-3.c: Ditto.
+ * gcc.dg/dfp/convert-bfp-4.c: Ditto.
+ * gcc.dg/dfp/convert-bfp-5.c: Ditto.
+ * gcc.dg/dfp/convert-bfp-6.c: Ditto.
+ * gcc.dg/dfp/convert-bfp-7.c: Ditto.
+ * gcc.dg/dfp/convert-bfp-8.c: Ditto.
+ * gcc.dg/dfp/convert-bfp-9.c: Ditto.
+ * gcc.dg/dfp/convert-bfp-10.c: Ditto.
+ * gcc.dg/dfp/convert-bfp-11.c: Ditto.
+ * gcc.dg/dfp/convert-bfp-12.c: Ditto.
+ * gcc.dg/dfp/convert-bfp-13.c: Ditto.
+ * gcc.dg/dfp/convert-bfp-14.c: Ditto.
+ * gcc.dg/dfp/convert-bfp.c: Ditto.
+ * gcc.dg/dfp/convert-complex.c: Ditto.
+ * gcc.dg/dfp/convert-dfp.c: Ditto.
+ * gcc.dg/dfp/convert-dfp-fold-2.c: Ditto.
+ * gcc.dg/dfp/convert-dfp-round.c: Ditto.
+ * gcc.dg/dfp/convert-int.c: Ditto.
+ * gcc.dg/dfp/convert-int-fold.c: Ditto.
+ * gcc.dg/dfp/convert-int-max.c: Ditto.
+ * gcc.dg/dfp/convert-int-saturate.c: Ditto.
+ * gcc.dg/dfp/decfloat-constants.c: Ditto.
+ * gcc.dg/dfp/fe-binop.c: Ditto.
+ * gcc.dg/dfp/fe-convert-1.c: Ditto.
+ * gcc.dg/dfp/fe-convert-2.c: Ditto.
+ * gcc.dg/dfp/fe-convert-3.c: Ditto.
+ * gcc.dg/dfp/func-array.c: Ditto.
+ * gcc.dg/dfp/func-deref.c: Ditto.
+ * gcc.dg/dfp/func-mixed.c: Ditto.
+ * gcc.dg/dfp/func-pointer.c: Ditto.
+ * gcc.dg/dfp/func-scalar.c: Ditto.
+ * gcc.dg/dfp/func-struct.c: Ditto.
+ * gcc.dg/dfp/func-vararg-alternate.h: Ditto.
+ * gcc.dg/dfp/func-vararg-alternate-d32.c: Ditto.
+ * gcc.dg/dfp/func-vararg-alternate-d64.c: Ditto.
+ * gcc.dg/dfp/func-vararg-alternate-d128.c: Ditto.
+ * gcc.dg/dfp/func-vararg-alternate-d128-2.c: Ditto.
+ * gcc.dg/dfp/func-vararg-dfp.c: Ditto.
+ * gcc.dg/dfp/func-vararg-mixed.c: Ditto.
+ * gcc.dg/dfp/func-vararg-mixed-2.c: Ditto.
+ * gcc.dg/dfp/func-vararg-size0.c: Ditto.
+ * gcc.dg/dfp/inf-1.c: Ditto.
+ * gcc.dg/dfp/loop-index.c: Ditto.
+ * gcc.dg/dfp/nan-1.c: Ditto.
+ * gcc.dg/dfp/nan-2.c: Ditto.
+ * gcc.dg/dfp/operator-arith-fold.c: Ditto.
+ * gcc.dg/dfp/operator-assignment.c: Ditto.
+ * gcc.dg/dfp/operator-comma.c: Ditto.
+ * gcc.dg/dfp/operator-cond.c: Ditto.
+ * gcc.dg/dfp/operator-logical.c: Ditto.
+ * gcc.dg/dfp/operator-unary.c: Ditto.
+ * gcc.dg/dfp/pr36800.c: Ditto.
+ * gcc.dg/dfp/pr39034.c: Ditto.
+ * gcc.dg/dfp/pr39035.c: Ditto.
+ * gcc.dg/dfp/pr39902.c: Ditto.
+ * gcc.dg/dfp/signbit-1.c: Ditto.
+ * gcc.dg/dfp/signbit-2.c: Ditto.
+ * gcc.dg/dfp/struct-layout-1.c: Ditto.
+ * gcc.dg/dfp/union-init.c: Ditto.
+ * gcc.dg/dfp/usual-arith-conv.c: Ditto.
+
+2009-09-16 Michael Matz <matz@suse.de>
+
+ PR fortran/41212
+ * gfortran.dg/pr41212.f90: New test.
+
+2009-09-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/alignment9.adb: New test.
+
+2009-09-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/discr20.ad[sb]: New test.
+
+2009-09-16 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/34011
+ * gcc.dg/tree-ssa/ssa-lim-7.c: New testcase.
+
+2009-09-16 DJ Delorie <dj@redhat.com>
+ Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * gcc.target/sh/struct-arg-dw2.c: New test.
+
+2009-09-15 Nathan Froyd <froydnj@codesourcery.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR target/41175
+ * gcc.target/powerpc/pr41175.c: New test.
+
+2009-09-14 Richard Henderson <rth@redhat.com>
+
+ * c-c++-common/asmgoto-1.c, c-c++-common/asmgoto-2.c,
+ c-c++-common/asmgoto-3.c, gcc.c-torture/compile/asmgoto-1.c,
+ gcc.dg/tree-ssa/asmgoto-1.c: New files.
+
+2009-09-14 Richard Henderson <rth@redhat.com>
+
+ * g++.dg/eh/builtin1.C: Update resx pattern match.
+ * g++.dg/eh/builtin2.C, g++.dg/eh/builtin3.C: Likewise.
+
+2009-09-14 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * gcc.target/mips/branch-helper.h: New file.
+ * gcc.target/mips/branch-2.c,
+ * gcc.target/mips/branch-3.c,
+ * gcc.target/mips/branch-4.c,
+ * gcc.target/mips/branch-5.c,
+ * gcc.target/mips/branch-6.c,
+ * gcc.target/mips/branch-7.c,
+ * gcc.target/mips/branch-8.c,
+ * gcc.target/mips/branch-9.c,
+ * gcc.target/mips/branch-10.c,
+ * gcc.target/mips/branch-11.c,
+ * gcc.target/mips/branch-12.c,
+ * gcc.target/mips/branch-13.c,
+ * gcc.target/mips/branch-14.c,
+ * gcc.target/mips/branch-15.c: New tests.
+
+2009-09-14 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/41331
+ * gcc.target/powerpc/bswap64-4.c: New file to test bswap64 on a
+ -m32 -mpowerpc64 system.
+
+2009-09-14 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ From Jie Zhang <jie.zhang@analog.com>:
+ * gcc.target/bfin/saveall.c: New test.
+ * gcc.target/bfin/20090914-1.c: New test.
+ * gcc.target/bfin/20090914-2.c: New test.
+
+ * gcc.target/bfin/20090914-3.c: New test.
+
+2009-09-14 Andrew Stubbs <ams@codesourcery.com>
+
+ * gcc.target/sh/20080410-1.c: Remove obsolete -fira option.
+
+2009-09-14 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41350
+ * g++.dg/debug/dwarf-eh-personality-1.C: New testcase.
+
+2009-09-12 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libgfortran/41328
+ * gfortran.dg/cr_lf.f90: New test.
+
+2009-09-11 Michael Matz <matz@suse.de>
+
+ PR middle-end/41275
+ * g++.dg/tree-ssa/pr41275.C: New test.
+
+2009-09-11 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/41242
+ * gfortran.dg/proc_ptr_comp_21.f90: New.
+
+2009-09-10 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/31292
+ * gfortran.dg/module_procedure_1.f90: New test.
+ * gfortran.dg/module_procedure_2.f90: Ditto.
+ * gfortran.dg/generic_14.f90: Move dg-error to new location.
+
+2009-09-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+ James A. Morrison <phython@gcc.gnu.org>
+
+ PR ada/18302
+ * ada/acats/run_all.sh (target_run): Use run_test.exp to execute
+ commands.
+ * ada/acats/run_test.exp: New file.
+
+2009-09-10 Uros Bizjak <ubizjak@gmail.com>
+
+ Revert:
+ 2009-09-09 Uros Bizjak <ubizjak@gmail.com>
+
+ PR rtl-optimization/39779
+ * gcc.dg/pr39979.c: New test.
+
+2009-09-10 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41257
+ * g++.dg/torture/pr41257-2.C: New testcase.
+
+2009-09-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/28293
+ * g++.dg/template/crash91.C: New.
+
+2009-09-09 Uros Bizjak <ubizjak@gmail.com>
+
+ PR rtl-optimization/39779
+ * gcc.dg/pr39979.c: New test.
+
+2009-09-09 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/41101
+ * gcc.c-torture/compile/pr41101.c: New testcase.
+
+2009-09-09 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41317
+ * gcc.c-torture/execute/pr41317.c: New testcase.
+ * gcc.dg/tree-ssa/forwprop-11.c: XFAIL.
+ * gcc.dg/tree-ssa/forwprop-12.c: Likewise.
+
+2009-09-08 Dodji Seketeli <dodji@redhat.com>
+
+ Fix some test breakages on Darwin
+ * g++.dg/debug/dwarf2/namespace-1.C: Use -fno-merge-debug-string
+ and adjust.
+ * g++.dg/debug/dwarf2/template-func-params-6.C: Likewise.
+ * g++.dg/debug/dwarf2/template-func-params-7.C: Likewise.
+ * g++.dg/debug/dwarf2/template-params-6.C: Likewise.
+ * g++.dg/debug/dwarf2/pubnames-1.C: Likewise. Also, adjust to
+ take darwin specifics in account.
+
+2009-09-08 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/profile-dir-1.c, gcc.dg/profile-dir-2.c,
+ gcc.dg/profile-dir-3.c: Disable for remote-host testing.
+
+2009-09-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/39923
+ * g++.dg/cpp0x/initlist24.C: New.
+
+2009-09-08 Ozkan Sezer <sezeroz@gmail.com>
+
+ * gcc.dg/large-size-array-2.c: Fix target requirement.
+ * gcc.dg/large-size-array-4.c: Likewise.
+ * gcc.dg/c90-const-expr-2.c: Define ZERO as 0LL for _WIN64.
+ * gcc.dg/c99-const-expr-2.c: Likewise.
+ * gcc.dg/c90-const-expr-6.c: Typedef ptrdiff_t with __extension__.
+ * gcc.dg/c90-const-expr-9.c: Typedef size_t with __extension__.
+ * gcc.dg/c90-const-expr-10.c: Likewise.
+ * gcc.dg/torture/pr39074.c: Use intptr_t typedef'ed as __PTRDIFF_TYPE__
+ instead of long.
+ * gcc.dg/tree-ssa/pr33920.c: Likewise.
+ * gcc.dg/vect/pr33846.c: Likewise.
+ * gcc.dg/vect/pr33833.c: Use uintptr_t, typedef'ed as unsigned
+ __PTRDIFF_TYPE__, instead of unsigned long.
+ * gcc.dg/vect/O1-pr33854.c: Use __SIZE_TYPE__ instead of unsigned long.
+
+2009-09-08 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/41229
+ PR debug/41291
+ PR debug/41300
+ * gfortran.dg/pr41229.f90: New.
+
+2009-09-08 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/41232
+ * gcc.dg/pr41232.c: New.
+
+2009-09-08 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.misc-tests/i386-prefetch.exp: Skip tests when multilib flags
+ contain -march.
+ * gcc.dg/tree-ssa/prefetch-7.c, gcc.target/i386/387-1.c,
+ gcc.target/i386/387-5.c, gcc.target/i386/cmov7.c,
+ gcc.target/i386/funcspec-1.c, gcc.target/i386/funcspec-8.c,
+ gcc.target/i386/gcc-have-sync-compare-and-swap-1.c,
+ gcc.target/i386/gcc-have-sync-compare-and-swap-2.c,
+ gcc.target/i386/isa-6.c, gcc.target/i386/lea.c,
+ gcc.target/i386/pentium4-not-mull.c, gcc.target/i386/sse-5.c,
+ gcc.target/i386/ssefn-1.c: Skip when multilib flags contain -march
+ options other than that used in dg-options.
+
+2009-09-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/41239
+ * gcc.c-torture/execute/pr41239.c: New test.
+
+2009-09-07 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libgfortran/41192
+ * gfortran.dg/namelist_59.f90: New test.
+
+2009-09-07 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ From Mike Frysinger <michael.frysinger@analog.com>
+ * gcc.target/bfin/mcpu-bf542m.c: New file.
+ * gcc.target/bfin/mcpu-bf544m.c: Likewise.
+ * gcc.target/bfin/mcpu-bf546m.c: Likewise.
+ * gcc.target/bfin/mcpu-bf548m.c: Likewise.
+ * gcc.target/bfin/mcpu-bf549m.c: Likewise.
+
+2009-09-07 Martin Jambor <mjambor@suse.cz>
+
+ PR middle-end/41282
+ * gcc.c-torture/compile/pr41282.c: New test.
+
+2009-09-07 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/41197
+ * gfortran.dg/allocate_alloc_opt_1.f90: Use scalar
+ variables for stat and errmsg.
+ * gfortran.dg/deallocate_alloc_opt_1.f90: Likewise.
+ * gfortran.dg/allocate_stat_2.f90: New test.
+
+2009-09-07 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * gcc.c-torture/compile/20090907-1.c: New test.
+
+2009-09-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR bootstrap/41241
+ * gcc.dg/pr41241.c: New test.
+
+2009-09-06 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41144
+ * g++.dg/torture/pr41144.C: New testcase.
+
+2009-09-06 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41261
+ * gcc.dg/torture/pr41261.c: New testcase.
+
+2009-09-05 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41181
+ * gcc.c-torture/compile/pr41181.c: New testcase.
+
+2009-09-05 Richard Guenther <rguenther@suse.de>
+
+ PR debug/41273
+ * g++.dg/torture/pr41273.C: New testcase.
+
+2009-09-05 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/41258
+ * gfortran.dg/typebound_proc_12.f90 : New test.
+
+2009-09-04 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/41225
+ * gfortran.dg/pr41225.f90: New.
+
+2009-09-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * gcc.dg/guality/guality.h: Include stdint.h. Drop unnecessary
+ unistd.h, sys/types.h and sys/wait.h.
+ (gualchk_t): New.
+ (GUALCVT): New.
+ (GUALCHKXPR, GUALCHKVAL, GUALCHKFLA): Use it.
+ (GUALITY_GDB_REDIRECT): New.
+ (GUALITY_GDB_ARGS): Use it.
+
+2009-09-04 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41257
+ * g++.dg/torture/pr41257.C: New testcase.
+
+2009-09-04 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/41112
+ * gnat.dg/array8.adb: New test.
+
+2009-09-03 Daniel Gutson <dgutson@codesourcery.com>
+
+ * gcc.target/arm/ctz.c: New test case.
+
+2009-09-03 Alon Dayan <alond@il.ibm.com>
+
+ PR tree-optimization/38275
+ * testsuite/gcc.dg/autopar/reduc-1char.c: Increase number
+ of iterations. Adjust the logic accordingly.
+ * testsuite/gcc.dg/autopar/reduc-2char.c: Ditto.
+ * testsuite/gcc.dg/autopar/reduc-1.c: Ditto.
+ * testsuite/gcc.dg/autopar/reduc-2.c: Ditto.
+ * testsuite/gcc.dg/autopar/reduc-3.c: Ditto.
+ * testsuite/gcc.dg/autopar/reduc-6.c: Ditto.
+ * testsuite/gcc.dg/autopar/reduc-7.c: Ditto.
+ * testsuite/gcc.dg/autopar/reduc-8.c: Ditto.
+ * testsuite/gcc.dg/autopar/reduc-9.c: Ditto.
+ * testsuite/gcc.dg/autopar/pr39500-1.c: Ditto.
+ * testsuite/gcc.dg/autopar/reduc-1short.c: Ditto.
+ * testsuite/gcc.dg/autopar/reduc-2short.c: Ditto.
+ * testsuite/gcc.dg/autopar/parallelization-1.c: Ditto.
+
+2009-09-03 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.dg/guality/guality.exp: Only run guality tests if a trivial
+ testcase using guality.h compiles and links and if a global variable
+ can be verified by gdb.
+
2009-09-03 Bernd Schmidt <bernd.schmidt@analog.com>
* lib/target-supports.exp (check_effective_target_sync_int_long):
@@ -28,7 +517,7 @@
* gcc.dg/memcpy-1.c: Add . to match pattern.
* gcc.dg/uninit-I.c: XFAIL warning test.
* g++.dg/warn/unit-1.C: XFAIL warning test.
-
+
2009-09-02 Ian Lance Taylor <iant@google.com>
* gcc.dg/20090902-1.c: New test.
@@ -40,9 +529,9 @@
2009-09-02 Olivier Hainque <hainque@adacore.com>
* gnat.dg/array7.ad[bs]: Add check for Signed_Integer_Type_Definition.
-
+
2009-09-02 Eric Botcazou <ebotcazou@adacore.com>
- Olivier Hainque <hainque@adacore.com>
+ Olivier Hainque <hainque@adacore.com>
* gnat.dg/misaligned_param.adb: New test.
* gnat.dg/misaligned_param_pkg.ad[sb]: New helper.
@@ -350,7 +839,7 @@
2009-08-11 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
- * gcc.target/arm/combine-cmp-shift.c: New test.
+ * gcc.target/arm/combine-cmp-shift.c: New test.
2009-08-24 Kai Tietz <kai.tietz@onevision.com>
diff --git a/gcc/testsuite/ada/acats/run_all.sh b/gcc/testsuite/ada/acats/run_all.sh
index ddd4da0f300..e28ec7a838a 100755
--- a/gcc/testsuite/ada/acats/run_all.sh
+++ b/gcc/testsuite/ada/acats/run_all.sh
@@ -13,7 +13,7 @@ gccflags="-O2"
gnatflags="-gnatws"
target_run () {
-$*
+ eval $EXPECT -f $testdir/run_test.exp $*
}
# End of customization section.
diff --git a/gcc/testsuite/ada/acats/run_test.exp b/gcc/testsuite/ada/acats/run_test.exp
new file mode 100644
index 00000000000..07dec27709b
--- /dev/null
+++ b/gcc/testsuite/ada/acats/run_test.exp
@@ -0,0 +1,13 @@
+#!/usr/bin/expect -f
+
+if {[info exists env(DEJAGNU_TIMEOUT)]} {
+ set timeout $env(DEJAGNU_TIMEOUT)
+} else {
+ set timeout 300
+}
+
+spawn -noecho $argv
+expect timeout {
+ send_user "Program timed out.\n"
+ exit 1
+}
diff --git a/gcc/testsuite/c-c++-common/asmgoto-1.c b/gcc/testsuite/c-c++-common/asmgoto-1.c
new file mode 100644
index 00000000000..9c729fdd571
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asmgoto-1.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+foo (void)
+{
+ int i = 0;
+ asm ("" : : : "memory");
+ asm ("" : : : );
+ asm ("" : : "r" (i));
+ asm ("" : : );
+ asm ("" : "=r" (i));
+ asm ("" : );
+ asm ("");
+}
diff --git a/gcc/testsuite/c-c++-common/asmgoto-2.c b/gcc/testsuite/c-c++-common/asmgoto-2.c
new file mode 100644
index 00000000000..5bf45725d80
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asmgoto-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+foo (void)
+{
+ __label__ lab;
+ int i = 0;
+ asm goto ("" : : : : lab);
+ asm goto ("" : "=r" (i) : : : lab); /* { dg-error "expected" } */
+ asm goto ("" : : : : ); /* { dg-error "expected" } */
+ asm goto ("" : : : "memory"); /* { dg-error "expected" } */
+ asm goto ("" : : : ); /* { dg-error "expected" } */
+ asm goto ("" : : "r" (i)); /* { dg-error "expected" } */
+ asm goto ("" : : ); /* { dg-error "expected" } */
+ asm goto ("" : "=r" (i)); /* { dg-error "expected" } */
+ asm goto ("" : ); /* { dg-error "expected" } */
+ asm goto (""); /* { dg-error "expected" } */
+ lab:;
+}
diff --git a/gcc/testsuite/c-c++-common/asmgoto-3.c b/gcc/testsuite/c-c++-common/asmgoto-3.c
new file mode 100644
index 00000000000..5224429a3ce
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asmgoto-3.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-Wunused" } */
+
+int foo ()
+{
+ asm goto ("" : : : : label);
+ return 1;
+ label:
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist24.C b/gcc/testsuite/g++.dg/cpp0x/initlist24.C
new file mode 100644
index 00000000000..33e97c7dfb4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist24.C
@@ -0,0 +1,9 @@
+// PR c++/39923
+// { dg-options "-std=c++0x" }
+
+#include <initializer_list>
+
+void test3()
+{
+ std::initializer_list<int> list{move}; // { dg-error "not declared|could not convert" }
+}
diff --git a/gcc/testsuite/g++.dg/debug/dwarf-eh-personality-1.C b/gcc/testsuite/g++.dg/debug/dwarf-eh-personality-1.C
new file mode 100644
index 00000000000..5c72588e513
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf-eh-personality-1.C
@@ -0,0 +1,17 @@
+// { dg-options "-fno-dwarf2-cfi-asm" }
+
+extern void bar (void);
+int foo (void)
+{
+ try {
+ bar();
+ } catch (...) {
+ return 1;
+ }
+ return 0;
+}
+
+int foobar (void)
+{
+}
+
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/namespace-1.C b/gcc/testsuite/g++.dg/debug/dwarf2/namespace-1.C
index 59b608fc7ec..d3f26f11222 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/namespace-1.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/namespace-1.C
@@ -1,12 +1,12 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR debug/41170
-// { dg-options "-g -dA" }
+// { dg-options "-g -dA -fno-merge-debug-strings" }
//
// We want to test that there is a DW_TAG_namespace DIE DW_AT_name is set
// to "not_emitted". That namespace die has a child DW_TAG_typedef DIE
// which DW_AT_name is the null terminated string "T".
// { dg-final { scan-assembler-times "DIE +\\(.*?\\) DW_TAG_namespace" 1 } }
-// { dg-final { scan-assembler-times "DW_AT_name: \"not_emitted\"" 1 } }
+// { dg-final { scan-assembler-times "\"not_emitted.0\".*?DW_AT_name" 1 } }
// { dg-final { scan-assembler-times "DIE +\\(.*?\\) DW_TAG_typedef" 1 } }
// { dg-final { scan-assembler-times "\.ascii \"T.0\"\[\t \]+.*?DW_AT_name" 1 } }
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-1.C b/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-1.C
index b2f67036e24..543439da323 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-1.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-1.C
@@ -1,9 +1,18 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR debug/39706
-// { dg-options "-g -dA" }
+// { dg-options "-g -dA -fno-merge-debug-strings" }
// { dg-do compile }
-// { dg-final { scan-assembler-times ".debug_pubnames" 1 } }
-// { dg-final { scan-assembler-times "\"main\".*external name" 1 } }
+//
+// There should be one debug_pubnames section generated.
+// On Darwin though, there is also a label pointing at the begining of the
+// debug_pubnames section. The assembly code of that label adds an occurence
+// of section declaration assembly. So on Darwin, we need to check for two
+// occurences of the debug_pubnames section declaration.
+// { dg-final { scan-assembler-times "\.section\[\t \].*?debug_pubnames" 1 { target { ! *-*-darwin* } } } }
+// { dg-final { scan-assembler-times "\.section\[\t \].*?debug_pubnames" 2 { target { *-*-darwin* } } } }
+//
+// Then check of the presence of the names we are interested in.
+// { dg-final { scan-assembler-times "\"main.0\".*external name" 1 } }
// { dg-final { scan-assembler-times "\"ns::ns_x.*external name" 1 } }
// { dg-final { scan-assembler-times "\"y::y_x.*external name" 1 } }
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/template-func-params-6.C b/gcc/testsuite/g++.dg/debug/dwarf2/template-func-params-6.C
index 155add48ef4..99bbba3da8d 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/template-func-params-6.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/template-func-params-6.C
@@ -1,8 +1,8 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR debug/30161
-// { dg-options "-g -dA" }
+// { dg-options "-g -dA -fno-merge-debug-strings" }
// { dg-final { scan-assembler-times "DW_TAG_GNU_template_template_param" 2 } }
-// { dg-final { scan-assembler-times "DW_AT_GNU_template_name: \"vector\"" 1 } }
+// { dg-final { scan-assembler-times "\"vector.0\".*?DW_AT_GNU_template_name" 1 } }
// { dg-final { scan-assembler-times ".ascii \"U.0\".*?DW_AT_name" 1 } }
template <class T>
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/template-func-params-7.C b/gcc/testsuite/g++.dg/debug/dwarf2/template-func-params-7.C
index 07aece6917f..dc6ac990313 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/template-func-params-7.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/template-func-params-7.C
@@ -1,6 +1,6 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR debug/30161
-// { dg-options "-g -dA -std=c++0x" }
+// { dg-options "-g -dA -std=c++0x -fno-merge-debug-strings" }
// { dg-do compile }
// There must be 5 subprograms generated:
@@ -10,10 +10,10 @@
// That makes 6 template type parameters.
// { dg-final {scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_template_type_param" 6 } }
-// { dg-final {scan-assembler-times "DW_AT_name: \"printf<int, char, int>\"" 1 } }
-// { dg-final {scan-assembler-times "DW_AT_name: \"printf<char, int>\"" 1 } }
-// { dg-final {scan-assembler-times "DW_AT_name: \"printf<int>\"" 1 } }
-// { dg-final {scan-assembler-times "DW_AT_name: \"printf\"" 1 } }
+// { dg-final {scan-assembler-times "\"printf<int, char, int>.0\".*?DW_AT_name" 1 } }
+// { dg-final {scan-assembler-times "\"printf<char, int>.0\".*?DW_AT_name" 1 } }
+// { dg-final {scan-assembler-times "\"printf<int>.0\".*?DW_AT_name" 1 } }
+// { dg-final {scan-assembler-times "\"printf.0\".*?DW_AT_name" 1 } }
// printf<int, char, int> and printf<char, int> have a pack expansion as
// function parameters. In the former, the elements of the parameter pack
@@ -21,9 +21,9 @@
// args#1. In the later, the element of the parameter pack expansion
// is PackTypes#0 and the argument is args#0.
// { dg-final {scan-assembler-times "DW_AT_name: \"PackTypes#0\"" 2 } }
-// { dg-final {scan-assembler-times "DW_AT_name: \"args#0\"" 2 } }
-// { dg-final {scan-assembler-times "DW_AT_name: \"PackTypes#1\"" 1 } }
-// { dg-final {scan-assembler-times "DW_AT_name: \"args#1\"" 1 } }
+// { dg-final {scan-assembler-times "\"args#0.0\".*?DW_AT_name" 2 } }
+// { dg-final {scan-assembler-times "\"PackTypes#1.0\".*?DW_AT_name" 1 } }
+// { dg-final {scan-assembler-times "\"args#1.0\".*?DW_AT_name" 1 } }
// { dg_final {scan-assembler-times "\.ascii \"T.0\"\[\t \]+.*?DW_AT_name" 3 } }
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/template-params-6.C b/gcc/testsuite/g++.dg/debug/dwarf2/template-params-6.C
index dc401fa06e7..184a90f98aa 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/template-params-6.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/template-params-6.C
@@ -1,8 +1,8 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR debug/30161
-// { dg-options "-g -dA" }
+// { dg-options "-g -dA -fno-merge-debug-strings" }
// { dg-final { scan-assembler-times "DW_TAG_GNU_template_template_param" 2 } }
-// { dg-final { scan-assembler-times "DW_AT_GNU_template_name: \"vector\"" 1 } }
+// { dg-final { scan-assembler-times "\"vector.0\".*?DW_AT_GNU_template_name" 1 } }
// { dg-final { scan-assembler-times ".ascii \"U.0\".*?DW_AT_name" 1 } }
template <class T>
diff --git a/gcc/testsuite/g++.dg/eh/builtin1.C b/gcc/testsuite/g++.dg/eh/builtin1.C
index 1f56d1a833d..ed49e9a962a 100644
--- a/gcc/testsuite/g++.dg/eh/builtin1.C
+++ b/gcc/testsuite/g++.dg/eh/builtin1.C
@@ -22,5 +22,5 @@ bar ()
__builtin_printf ("foo %d\n", a.i);
}
-/* { dg-final { scan-tree-dump-times "resx 1" 2 "eh" } } */
+/* { dg-final { scan-tree-dump-times "resx" 2 "eh" } } */
/* { dg-final { cleanup-tree-dump "eh" } } */
diff --git a/gcc/testsuite/g++.dg/eh/builtin2.C b/gcc/testsuite/g++.dg/eh/builtin2.C
index b106516da68..fe0c4de6b3e 100644
--- a/gcc/testsuite/g++.dg/eh/builtin2.C
+++ b/gcc/testsuite/g++.dg/eh/builtin2.C
@@ -21,5 +21,5 @@ bar ()
__builtin_printf ("foo %d\n", a.i);
}
-/* { dg-final { scan-tree-dump-times "resx 1" 0 "eh" } } */
+/* { dg-final { scan-tree-dump-times "resx" 0 "eh" } } */
/* { dg-final { cleanup-tree-dump "eh" } } */
diff --git a/gcc/testsuite/g++.dg/eh/builtin3.C b/gcc/testsuite/g++.dg/eh/builtin3.C
index be1629ea5f8..45809b81553 100644
--- a/gcc/testsuite/g++.dg/eh/builtin3.C
+++ b/gcc/testsuite/g++.dg/eh/builtin3.C
@@ -12,5 +12,5 @@ bar ()
__builtin_printf ("foo %d\n", a.i);
}
-/* { dg-final { scan-tree-dump-times "resx 1" 1 "eh" } } */
+/* { dg-final { scan-tree-dump-times "resx" 1 "eh" } } */
/* { dg-final { cleanup-tree-dump "eh" } } */
diff --git a/gcc/testsuite/g++.dg/template/crash91.C b/gcc/testsuite/g++.dg/template/crash91.C
new file mode 100644
index 00000000000..39575cd9f27
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash91.C
@@ -0,0 +1,8 @@
+// PR c++/28293
+
+template<int> void foo();
+
+struct A
+{
+ typedef void foo<0>(); // { dg-error "explicit template argument list not allowed" }
+};
diff --git a/gcc/testsuite/g++.dg/torture/pr41144.C b/gcc/testsuite/g++.dg/torture/pr41144.C
new file mode 100644
index 00000000000..64dc117d7c6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr41144.C
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+
+struct rgba8;
+template<class ColorT> class span_gouraud {
+public:
+ struct coord_type { };
+ coord_type m_coord[3];
+};
+template<class ColorT> class span_gouraud_rgba : public span_gouraud<ColorT>
+{
+ typedef ColorT color_type;
+ typedef span_gouraud<color_type> base_type;
+ typedef typename base_type::coord_type coord_type;
+public:
+ void prepare() {
+ coord_type coord[3];
+ }
+};
+void the_application() {
+ typedef span_gouraud_rgba<rgba8> gouraud_span_gen_type;
+ gouraud_span_gen_type span_gouraud;
+ span_gouraud.prepare();
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr41257-2.C b/gcc/testsuite/g++.dg/torture/pr41257-2.C
new file mode 100644
index 00000000000..230fa5dde49
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr41257-2.C
@@ -0,0 +1,16 @@
+/* { dg-do link } */
+
+struct A
+{
+ virtual ~A();
+};
+
+struct B : virtual A
+{
+ virtual ~B() {}
+};
+
+int main()
+{
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr41257.C b/gcc/testsuite/g++.dg/torture/pr41257.C
new file mode 100644
index 00000000000..60cfc533979
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr41257.C
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+struct A
+{
+ virtual void foo();
+ virtual ~A();
+ int i;
+};
+
+struct B : virtual A {};
+
+struct C : B
+{
+ virtual void foo();
+};
+
+void bar()
+{
+ C().foo();
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr41273.C b/gcc/testsuite/g++.dg/torture/pr41273.C
new file mode 100644
index 00000000000..bdce0535583
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr41273.C
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-g" } */
+
+long *H2_ipX_ener_sort;
+double H2_old_populations[2];
+double H2_total;
+
+void H2_LevelPops()
+{
+ double sum_pop = 0.;
+ long nEner = 0;
+ while( nEner < 3 && sum_pop/H2_total < 0.99999 )
+ {
+ long ip = H2_ipX_ener_sort[nEner];
+ sum_pop += H2_old_populations[ip];
+ ++nEner;
+ }
+}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C b/gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C
index 3de72aac590..8dfaa52b6bb 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C
@@ -19,6 +19,6 @@ t (void)
// { dg-final { scan-tree-dump-times "Empty EH handler" 1 "ehcleanup1" } }
//
// And as a result also contained control flow.
-// { dg-final { scan-tree-dump-times "Removing unreachable" 1 "ehcleanup1" } }
+// { dg-final { scan-tree-dump-times "Removing unreachable" 2 "ehcleanup1" } }
//
// { dg-final { cleanup-tree-dump "ehcleanup1" } }
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr41275.C b/gcc/testsuite/g++.dg/tree-ssa/pr41275.C
new file mode 100644
index 00000000000..d9b3dce8fb1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr41275.C
@@ -0,0 +1,16 @@
+// PR middle-end/41275
+// { dg-do compile }
+// { dg-options "-O2" }
+// this used to ICE
+struct ErrmsgWindow
+{
+ virtual ~ErrmsgWindow()
+ {
+ extern int _switch_mode_errorstr;
+ _switch_mode_errorstr = 42;
+ }
+};
+void ShowErrorMessage(void)
+{
+ ErrmsgWindow w;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20090907-1.c b/gcc/testsuite/gcc.c-torture/compile/20090907-1.c
new file mode 100644
index 00000000000..907574c4230
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20090907-1.c
@@ -0,0 +1,84 @@
+struct platform_device;
+typedef unsigned long __kernel_size_t;
+typedef unsigned short __u16;
+typedef unsigned int __u32;
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef __kernel_size_t size_t;
+typedef __u32 uint32_t;
+static inline __attribute__ ((always_inline))
+uint32_t __attribute__ ((pure)) bfin_dspid (void)
+{
+ return ( {
+ uint32_t __v; __v;}
+ );
+}
+struct list_head {
+ struct list_head *next, *prev;
+};
+struct page {
+ union {
+ };
+ struct list_head lru;
+};
+struct device_driver {
+ const char *name;
+ struct module *owner;
+};
+struct fb_info {
+ struct device *dev;
+};
+struct platform_driver {
+ int (*probe) (struct platform_device *);
+ int (*remove) (struct platform_device *);
+ struct device_driver driver;
+};
+struct firmware {
+ size_t size;
+ const u8 *data;
+};
+struct metronomefb_par {
+ struct fb_info *info;
+};
+struct waveform_hdr {
+ u8 trc;
+};
+static u8 calc_cksum (int start, int end, u8 * mem)
+{
+ u8 tmp = 0;
+ int i;
+ for (i = start; i < end; i++)
+ tmp += mem[i];
+ return tmp;
+}
+extern struct waveform_hdr *wfm_hdr;
+extern int wmta;
+
+static int
+load_waveform (u8 * mem, size_t size, int m, int t, struct metronomefb_par *par)
+{
+ int tta;
+ int trn = 0;
+ int i;
+ u8 cksum;
+ int cksum_idx;
+ struct device *dev = par->info->dev;
+ for (i = 0; i <= sizeof (*wfm_hdr) + wfm_hdr->trc; i++) {
+ if (mem[i] > t) {
+ trn = i - sizeof (*wfm_hdr) - 1;
+ }
+ }
+ tta = * (mem + wmta + m * 4) & 0x00FFFFFF;
+ cksum_idx = tta + trn * 4 + 3;
+ cksum = calc_cksum (cksum_idx - 3, cksum_idx, mem);
+ if (cksum != mem[cksum_idx]) {
+ abort();
+ }
+}
+extern struct firmware *fw_entry;
+extern struct metronomefb_par *par;
+
+int metronomefb_probe (struct platform_device *dev)
+{
+ return load_waveform ((u8 *) fw_entry->data, fw_entry->size, 3, 31, par);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20090917-1.c b/gcc/testsuite/gcc.c-torture/compile/20090917-1.c
new file mode 100644
index 00000000000..2b8c37148bd
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20090917-1.c
@@ -0,0 +1,55 @@
+typedef int *loop_p;
+typedef struct VEC_loop_p_base
+{
+ unsigned num;
+ loop_p vec[1];
+}
+VEC_loop_p_base;
+
+__inline__ int
+VEC_loop_p_base_iterate (const VEC_loop_p_base * vec_, unsigned ix_,
+ loop_p * ptr)
+{
+ if (vec_ && ix_ < vec_->num)
+ {
+ *ptr = vec_->vec[ix_];
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+typedef struct VEC_loop_p_heap
+{
+ VEC_loop_p_base base;
+}
+VEC_loop_p_heap;
+
+
+static __inline__ int
+am_vector_index_for_loop (VEC_loop_p_heap * loop_nest, int loop_num)
+{
+ int i;
+ loop_p l;
+
+ for (i = 0;
+ VEC_loop_p_base_iterate ((loop_nest) ? &(loop_nest)->base : 0, i,
+ &(l)); i++)
+ if (l == loop_num)
+ return i;
+
+ __builtin_unreachable ();
+}
+
+unsigned char
+build_access_matrix (unsigned max)
+{
+ unsigned i;
+ for (i = 0; i < max; i++)
+ {
+ if (am_vector_index_for_loop (foo (), 0))
+ return 0;
+ }
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/asmgoto-1.c b/gcc/testsuite/gcc.c-torture/compile/asmgoto-1.c
new file mode 100644
index 00000000000..cc34610aba7
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/asmgoto-1.c
@@ -0,0 +1,30 @@
+void fn (void);
+
+void
+foo (void *x, unsigned long y)
+{
+ asm goto ("": : : : lab);
+lab:
+ fn ();
+}
+
+static void
+bar (unsigned long x)
+{
+ foo (0, x);
+}
+
+static void
+baz (unsigned long x)
+{
+ if (x > 8192)
+ bar (x);
+ else
+ ({ __here: (unsigned long) &&__here; });
+}
+
+void
+test (void)
+{
+ baz (16384);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr41101.c b/gcc/testsuite/gcc.c-torture/compile/pr41101.c
new file mode 100644
index 00000000000..8d21a00ce8a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr41101.c
@@ -0,0 +1,19 @@
+int func(int);
+
+void
+bug(int* x, int* y, unsigned long int N)
+{
+ unsigned long int i;
+ int* t;
+
+ while (1)
+ {
+ for (i=1; i<=N; i++)
+ {
+ y[i] = func(x[i] - x[1]);
+ if (y[i])
+ return;
+ }
+ t=x; x=y; y=t;
+ }
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr41181.c b/gcc/testsuite/gcc.c-torture/compile/pr41181.c
new file mode 100644
index 00000000000..d0af52d912b
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr41181.c
@@ -0,0 +1,10 @@
+char paths[1024];
+static void x264_slicetype_path(char (*best_paths)[250], int n, int length)
+{
+ __builtin_memcpy (best_paths[n], paths, length);
+}
+void x264_slicetype_analyse(int n, int length)
+{
+ char best_paths[250][250];
+ x264_slicetype_path (best_paths, n, length);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr41282.c b/gcc/testsuite/gcc.c-torture/compile/pr41282.c
new file mode 100644
index 00000000000..3a0f02d63ab
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr41282.c
@@ -0,0 +1,20 @@
+struct S
+{
+ unsigned int iu;
+};
+
+union U
+{
+ struct S s;
+ signed int is;
+};
+
+extern signed int bar ();
+
+struct S foo (void)
+{
+ union U u;
+
+ u.is = bar ();
+ return u.s;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/ipa-sra-1.c b/gcc/testsuite/gcc.c-torture/execute/ipa-sra-1.c
new file mode 100644
index 00000000000..777ed2a83d9
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/ipa-sra-1.c
@@ -0,0 +1,29 @@
+/* Trivially making sure IPA-SRA does not introduce segfaults where they should
+ not be. */
+
+struct bovid
+{
+ float red;
+ int green;
+ void *blue;
+};
+
+static int
+__attribute__((noinline))
+ox (int fail, struct bovid *cow)
+{
+ int r;
+ if (fail)
+ r = cow->red;
+ else
+ r = 0;
+ return r;
+}
+
+int main (int argc, char *argv[])
+{
+ int r;
+
+ r = ox ((argc > 2000), (void *) 0);
+ return r;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/ipa-sra-2.c b/gcc/testsuite/gcc.c-torture/execute/ipa-sra-2.c
new file mode 100644
index 00000000000..9d5ae440975
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/ipa-sra-2.c
@@ -0,0 +1,41 @@
+struct big
+{
+ int data[1000000];
+};
+
+struct small
+{
+ int data[10];
+};
+
+union both
+{
+ struct big big;
+ struct small small;
+};
+
+extern void *malloc(__SIZE_TYPE__);
+extern void free (void *);
+
+static int
+__attribute__((noinline))
+foo (int fail, union both *agg)
+{
+ int r;
+ if (fail)
+ r = agg->big.data[999999];
+ else
+ r = agg->small.data[0];
+ return r;
+}
+
+int main (int argc, char *argv[])
+{
+ union both *agg = malloc (sizeof (struct small));
+ int r;
+
+ r = foo ((argc > 2000), agg);
+
+ free (agg);
+ return r;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr41239.c b/gcc/testsuite/gcc.c-torture/execute/pr41239.c
new file mode 100644
index 00000000000..9966b867c3b
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr41239.c
@@ -0,0 +1,67 @@
+/* PR rtl-optimization/41239 */
+
+struct S
+{
+ short nargs;
+ unsigned long arg[2];
+};
+
+extern void abort (void);
+extern void exit (int);
+extern char fn1 (int, const char *, int, const char *, const char *);
+extern void fn2 (int, ...);
+extern int fn3 (int);
+extern int fn4 (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
+
+unsigned long
+test (struct S *x)
+{
+ signed int arg1 = x->arg[0];
+ long int arg2 = x->arg[1];
+
+ if (arg2 == 0)
+ (fn1 (20, "foo", 924, __func__, ((void *) 0))
+ ? (fn2 (fn3 (0x2040082), fn4 ("division by zero")))
+ : (void) 0);
+
+ return (long int) arg1 / arg2;
+}
+
+int
+main (void)
+{
+ struct S s = { 2, { 5, 0 } };
+ test (&s);
+ abort ();
+}
+
+__attribute__((noinline)) char
+fn1 (int x, const char *y, int z, const char *w, const char *v)
+{
+ asm volatile ("" : : "r" (w), "r" (v) : "memory");
+ asm volatile ("" : "+r" (x) : "r" (y), "r" (z) : "memory");
+ return x;
+}
+
+__attribute__((noinline)) int
+fn3 (int x)
+{
+ asm volatile ("" : "+r" (x) : : "memory");
+ return x;
+}
+
+__attribute__((noinline)) int
+fn4 (const char *x, ...)
+{
+ asm volatile ("" : "+r" (x) : : "memory");
+ return *x;
+}
+
+__attribute__((noinline)) void
+fn2 (int x, ...)
+{
+ asm volatile ("" : "+r" (x) : : "memory");
+ if (x)
+ /* Could be a longjmp or throw too. */
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr41317.c b/gcc/testsuite/gcc.c-torture/execute/pr41317.c
new file mode 100644
index 00000000000..742068b9ad4
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr41317.c
@@ -0,0 +1,28 @@
+extern void abort (void);
+
+struct A
+{
+ int i;
+};
+struct B
+{
+ struct A a;
+ int j;
+};
+
+static void
+foo (struct B *p)
+{
+ ((struct A *)p)->i = 1;
+}
+
+int main()
+{
+ struct A a;
+ a.i = 0;
+ foo ((struct B *)&a);
+ if (a.i != 1)
+ abort ();
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-10.c b/gcc/testsuite/gcc.dg/c90-const-expr-10.c
index 6159390bb94..bad388c90b1 100644
--- a/gcc/testsuite/gcc.dg/c90-const-expr-10.c
+++ b/gcc/testsuite/gcc.dg/c90-const-expr-10.c
@@ -5,24 +5,26 @@
/* { dg-do compile } */
/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */
-void *p = (__SIZE_TYPE__)(void *)0; /* { dg-error "without a cast" } */
-struct s { void *a; } q = { (__SIZE_TYPE__)(void *)0 }; /* { dg-error "without a cast" } */
+__extension__ typedef __SIZE_TYPE__ size_t;
+
+void *p = (size_t)(void *)0; /* { dg-error "without a cast" } */
+struct s { void *a; } q = { (size_t)(void *)0 }; /* { dg-error "without a cast" } */
void *
f (void)
{
void *r;
- r = (__SIZE_TYPE__)(void *)0; /* { dg-error "without a cast" } */
- return (__SIZE_TYPE__)(void *)0; /* { dg-error "without a cast" } */
+ r = (size_t)(void *)0; /* { dg-error "without a cast" } */
+ return (size_t)(void *)0; /* { dg-error "without a cast" } */
}
void g (void *); /* { dg-message "but argument is of type" } */
void
h (void)
{
- g ((__SIZE_TYPE__)(void *)0); /* { dg-error "without a cast" } */
+ g ((size_t)(void *)0); /* { dg-error "without a cast" } */
}
void g2 (int, void *); /* { dg-message "but argument is of type" } */
void
h2 (void)
{
- g2 (0, (__SIZE_TYPE__)(void *)0); /* { dg-error "without a cast" } */
+ g2 (0, (size_t)(void *)0); /* { dg-error "without a cast" } */
}
diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-2.c b/gcc/testsuite/gcc.dg/c90-const-expr-2.c
index 662d8e790dc..ee57d550372 100644
--- a/gcc/testsuite/gcc.dg/c90-const-expr-2.c
+++ b/gcc/testsuite/gcc.dg/c90-const-expr-2.c
@@ -14,8 +14,10 @@ int *a;
int b;
long *c;
-#if defined(_LP64) || defined(_WIN64)
+#if defined(_LP64)
#define ZERO 0L
+#elif defined(_WIN64)
+#define ZERO 0LL
#else
#define ZERO 0
#endif
diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-6.c b/gcc/testsuite/gcc.dg/c90-const-expr-6.c
index 50de3a9525f..c432cca6343 100644
--- a/gcc/testsuite/gcc.dg/c90-const-expr-6.c
+++ b/gcc/testsuite/gcc.dg/c90-const-expr-6.c
@@ -4,11 +4,13 @@
/* { dg-do compile } */
/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */
+__extension__ typedef __PTRDIFF_TYPE__ ptrdiff_t;
+
/* PR 29116. */
int n = 0, p[n * 0 + 1]; /* { dg-error "variabl|can't be evaluated" } */
/* PR 31871. */
-extern int c[1 + ((__PTRDIFF_TYPE__) (void *) 0)]; /* { dg-error "variab|can't be evaluated" } */
+extern int c[1 + ((ptrdiff_t) (void *) 0)]; /* { dg-error "variab|can't be evaluated" } */
/* Implicit conversions from floating-point constants are not OK,
although explicit ones are. */
@@ -32,7 +34,7 @@ struct s {
};
enum e {
- E = (1 + ((__PTRDIFF_TYPE__) (void *) 0)), /* { dg-error "constant" } */
+ E = (1 + ((ptrdiff_t) (void *) 0)), /* { dg-error "constant" } */
E2 = 0
};
@@ -44,7 +46,7 @@ enum f {
void
f (int a)
{
- int v[1 + ((__PTRDIFF_TYPE__) (void *) 0)]; /* { dg-error "variab|can't be evaluated" } */
+ int v[1 + ((ptrdiff_t) (void *) 0)]; /* { dg-error "variab|can't be evaluated" } */
switch (a)
{
case (n * 0 + 1): /* { dg-error "constant" } */
diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-9.c b/gcc/testsuite/gcc.dg/c90-const-expr-9.c
index d9ab3756599..a06cdd951b2 100644
--- a/gcc/testsuite/gcc.dg/c90-const-expr-9.c
+++ b/gcc/testsuite/gcc.dg/c90-const-expr-9.c
@@ -14,7 +14,9 @@ struct t {
int b[2];
};
-#define old_offsetof(TYPE, MEMBER) ((__SIZE_TYPE__) &((TYPE *)0)->MEMBER)
+__extension__ typedef __SIZE_TYPE__ size_t;
+
+#define old_offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
enum e {
E1 = old_offsetof (struct s, a), /* { dg-error "constant" } */
diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-2.c b/gcc/testsuite/gcc.dg/c99-const-expr-2.c
index 8e5a600185f..a78e412d35a 100644
--- a/gcc/testsuite/gcc.dg/c99-const-expr-2.c
+++ b/gcc/testsuite/gcc.dg/c99-const-expr-2.c
@@ -14,8 +14,10 @@ int *a;
int b;
long *c;
-#if defined(_LP64) || defined(_WIN64)
+#if defined(_LP64)
#define ZERO 0L
+#elif defined(_WIN64)
+#define ZERO 0LL
#else
#define ZERO 0
#endif
diff --git a/gcc/testsuite/gcc.dg/dfp/Wbad-function-cast-1.c b/gcc/testsuite/gcc.dg/dfp/Wbad-function-cast-1.c
index 95e8ce19810..99d8f0655d7 100644
--- a/gcc/testsuite/gcc.dg/dfp/Wbad-function-cast-1.c
+++ b/gcc/testsuite/gcc.dg/dfp/Wbad-function-cast-1.c
@@ -2,7 +2,7 @@
/* Based on gcc.dg/Wbad-function-cast-1.c. */
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -Wbad-function-cast" } */
+/* { dg-options "-Wbad-function-cast" } */
int if1(void);
char if2(void);
diff --git a/gcc/testsuite/gcc.dg/dfp/Wtraditional-conversion-2.c b/gcc/testsuite/gcc.dg/dfp/Wtraditional-conversion-2.c
index 7e0d3ad994c..2436afc8ae5 100644
--- a/gcc/testsuite/gcc.dg/dfp/Wtraditional-conversion-2.c
+++ b/gcc/testsuite/gcc.dg/dfp/Wtraditional-conversion-2.c
@@ -2,7 +2,7 @@
(based on gcc.dg/Wtraditional-conversion-2.c). */
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -Wtraditional-conversion" } */
+/* { dg-options "-Wtraditional-conversion" } */
void fsi(signed int);
void fd32(_Decimal32);
diff --git a/gcc/testsuite/gcc.dg/dfp/call-by-value.c b/gcc/testsuite/gcc.dg/dfp/call-by-value.c
index 4232a30186c..74aec53aefb 100644
--- a/gcc/testsuite/gcc.dg/dfp/call-by-value.c
+++ b/gcc/testsuite/gcc.dg/dfp/call-by-value.c
@@ -1,11 +1,9 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.9.1(9) Function definitions; parameter has automatic storage.
Test that actual parameters are passed by value and that modifications
made within functions are lost on function return. */
-extern void abort (void);
+#include "dfp-dbg.h"
int foo32 (_Decimal32 z)
{
@@ -31,15 +29,15 @@ main ()
foo32 (d32);
if (d32 != 1.1df)
- abort ();
+ FAILURE
foo64 (d64);
if (d64 != 1.2dd)
- abort ();
+ FAILURE
foo128 (d128);
if (d128 != 1.3dl)
- abort ();
+ FAILURE
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/cast-bad.c b/gcc/testsuite/gcc.dg/dfp/cast-bad.c
index e99180824fe..e9e31ff3067 100644
--- a/gcc/testsuite/gcc.dg/dfp/cast-bad.c
+++ b/gcc/testsuite/gcc.dg/dfp/cast-bad.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
/* C99 6.5.4 Cast operators.
Test invalid casts involving decimal float. */
diff --git a/gcc/testsuite/gcc.dg/dfp/cast.c b/gcc/testsuite/gcc.dg/dfp/cast.c
index 1e88bee7c8e..b6585d70c8b 100644
--- a/gcc/testsuite/gcc.dg/dfp/cast.c
+++ b/gcc/testsuite/gcc.dg/dfp/cast.c
@@ -1,17 +1,7 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.5.4 Cast operators.
Test valid casts involving decimal float. */
-extern void abort (void);
-int failcnt;
-
-#ifdef DBG
-extern int printf (const char *, ...);
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
_Decimal32 d32;
_Decimal64 d64;
@@ -81,8 +71,5 @@ main (void)
if (d128 != (_Decimal128) d)
FAILURE
- if (failcnt != 0)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-eq-const.c b/gcc/testsuite/gcc.dg/dfp/compare-eq-const.c
index dd295200f2a..0c9ff200b28 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-eq-const.c
+++ b/gcc/testsuite/gcc.dg/dfp/compare-eq-const.c
@@ -1,8 +1,8 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.5.9 Equality operators.
Compare decimal float constants against each other. */
+#include "dfp-dbg.h"
+
extern void link_error (void);
int
@@ -24,5 +24,5 @@ main ()
if (1.4dd + 1.4dd + 1.4dd != 4.2dd)
link_error ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-eq-d128.c b/gcc/testsuite/gcc.dg/dfp/compare-eq-d128.c
index 158e2f90ba5..79fcac3195e 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-eq-d128.c
+++ b/gcc/testsuite/gcc.dg/dfp/compare-eq-d128.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* C99 6.5.9 Equality operators.
Compare decimal float values against each other at runtime. */
@@ -9,5 +9,6 @@
int main ()
{
test_compares ();
- return 0;
+
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-eq-d32.c b/gcc/testsuite/gcc.dg/dfp/compare-eq-d32.c
index d5e3bb378c9..6b1a4c6d7c4 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-eq-d32.c
+++ b/gcc/testsuite/gcc.dg/dfp/compare-eq-d32.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* C99 6.5.9 Equality operators.
Compare decimal float values against each other at runtime. */
@@ -9,5 +9,6 @@
int main ()
{
test_compares ();
- return 0;
+
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-eq-d64.c b/gcc/testsuite/gcc.dg/dfp/compare-eq-d64.c
index 8fa39dfcd8f..f1b463ebe6a 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-eq-d64.c
+++ b/gcc/testsuite/gcc.dg/dfp/compare-eq-d64.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* C99 6.5.9 Equality operators.
Compare decimal float values against each other at runtime. */
@@ -9,5 +9,6 @@
int main ()
{
test_compares ();
- return 0;
+
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-eq-dfp.c b/gcc/testsuite/gcc.dg/dfp/compare-eq-dfp.c
index 4203470a4be..79a5691ebfc 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-eq-dfp.c
+++ b/gcc/testsuite/gcc.dg/dfp/compare-eq-dfp.c
@@ -1,19 +1,9 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* C99 6.5.9 Equality operators.
Compare decimal float values against variables of different types. */
-extern void abort (void);
-static int failcnt;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
_Decimal32 d32;
_Decimal64 d64;
@@ -59,7 +49,5 @@ main ()
compare_dfp ();
- if (failcnt)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-eq.h b/gcc/testsuite/gcc.dg/dfp/compare-eq.h
index 809d642593c..830b3289bde 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-eq.h
+++ b/gcc/testsuite/gcc.dg/dfp/compare-eq.h
@@ -2,19 +2,18 @@
are not affected by rounding. */
#include <stdlib.h>
-
-static int failcnt;
+#include "dfp-dbg.h"
#define PASTE2(A,B) A ## B
#define PASTE(A,B) PASTE2(A,B)
+#undef FAILURE
#ifdef DBG
-#include <stdio.h>
#define FAILURE(OP,KIND) \
{ printf ("failed at line %d: %s for %s values\n", __LINE__, OP, KIND); \
- failcnt++; }
+ failures++; }
#else
-#define FAILURE(OP,KIND) abort ();
+#define FAILURE(OP,KIND) __builtin_abort ();
#endif
#ifndef WIDTH
@@ -90,7 +89,4 @@ test_compares (void)
if (! (x != zero)) FAILURE ("!=", "greater")
if (! (y != m_one)) FAILURE ("!=", "greater")
if (! (z != m_two)) FAILURE ("!=", "greater")
-
- if (failcnt)
- abort ();
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-rel-const.c b/gcc/testsuite/gcc.dg/dfp/compare-rel-const.c
index d2dda48e614..8e99b4466dc 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-rel-const.c
+++ b/gcc/testsuite/gcc.dg/dfp/compare-rel-const.c
@@ -1,5 +1,3 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.5.8 Relational operators.
Compare decimal float constants against each other. */
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-rel-d128.c b/gcc/testsuite/gcc.dg/dfp/compare-rel-d128.c
index 0d46925c2bb..38c931a0207 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-rel-d128.c
+++ b/gcc/testsuite/gcc.dg/dfp/compare-rel-d128.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* C99 6.5.8 Relational operators.
Compare decimal float values against each other at runtime. */
@@ -10,5 +10,5 @@ int
main ()
{
test_compares ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-rel-d32.c b/gcc/testsuite/gcc.dg/dfp/compare-rel-d32.c
index 257a3c2b4df..04128aab924 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-rel-d32.c
+++ b/gcc/testsuite/gcc.dg/dfp/compare-rel-d32.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* C99 6.5.8 Relational operators.
Compare decimal float values against each other at runtime. */
@@ -10,5 +10,5 @@ int
main ()
{
test_compares ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-rel-d64.c b/gcc/testsuite/gcc.dg/dfp/compare-rel-d64.c
index 73cbcee44d7..92f904a8154 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-rel-d64.c
+++ b/gcc/testsuite/gcc.dg/dfp/compare-rel-d64.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* C99 6.5.8 Relational operators.
Compare decimal float values against each other at runtime. */
@@ -10,5 +10,5 @@ int
main ()
{
test_compares ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-rel-dfp.c b/gcc/testsuite/gcc.dg/dfp/compare-rel-dfp.c
index 58523b6ab02..59cc2035306 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-rel-dfp.c
+++ b/gcc/testsuite/gcc.dg/dfp/compare-rel-dfp.c
@@ -1,19 +1,9 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* C99 6.5.8 Relational operators.
Compare decimal float values against variables of different types. */
-extern void abort (void);
-static int failcnt;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
_Decimal32 d32;
_Decimal64 d64;
@@ -59,7 +49,5 @@ main ()
compare_dfp ();
- if (failcnt)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-rel.h b/gcc/testsuite/gcc.dg/dfp/compare-rel.h
index 06b2559bdb5..7840108142d 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-rel.h
+++ b/gcc/testsuite/gcc.dg/dfp/compare-rel.h
@@ -2,21 +2,20 @@
are not affected by rounding. */
#include <stdlib.h>
+#include "dfp-dbg.h"
-static int failcnt;
-
-#define PASTE2(A,B) A ## B
-#define PASTE(A,B) PASTE2(A,B)
-
+#undef FAILURE
#ifdef DBG
-#include <stdio.h>
#define FAILURE(OP,KIND) \
{ printf ("failed at line %d: %s for %s values\n", __LINE__, OP, KIND); \
- failcnt++; }
+ failures++; }
#else
-#define FAILURE(OP,KIND) abort ();
+#define FAILURE(OP,KIND) __builtin_abort ();
#endif
+#define PASTE2(A,B) A ## B
+#define PASTE(A,B) PASTE2(A,B)
+
#ifndef WIDTH
#error define WIDTH as decimal float size in bytes
#endif
@@ -130,7 +129,4 @@ test_compares (void)
if (y > one) FAILURE (">", "greater")
if (z > zero) FAILURE (">", "greater")
if (z > one) FAILURE (">", "greater")
-
- if (failcnt)
- abort ();
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-special-d128.c b/gcc/testsuite/gcc.dg/dfp/compare-special-d128.c
index cef4670b766..d1f5bc5edd4 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-special-d128.c
+++ b/gcc/testsuite/gcc.dg/dfp/compare-special-d128.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* C99 6.5.8 Relational operators.
C99 6.5.9 Equality operators.
@@ -11,5 +11,5 @@ int
main ()
{
test_compares ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-special-d32.c b/gcc/testsuite/gcc.dg/dfp/compare-special-d32.c
index fa91d7edd33..377c65a5bb7 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-special-d32.c
+++ b/gcc/testsuite/gcc.dg/dfp/compare-special-d32.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* C99 6.5.8 Relational operators.
C99 6.5.9 Equality operators.
@@ -11,5 +11,5 @@ int
main ()
{
test_compares ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-special-d64.c b/gcc/testsuite/gcc.dg/dfp/compare-special-d64.c
index 2238e0190e3..16154eff323 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-special-d64.c
+++ b/gcc/testsuite/gcc.dg/dfp/compare-special-d64.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* C99 6.5.8 Relational operators.
C99 6.5.9 Equality operators.
@@ -11,5 +11,5 @@ int
main ()
{
test_compares ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-special.h b/gcc/testsuite/gcc.dg/dfp/compare-special.h
index c5bef234424..9c27d126c29 100644
--- a/gcc/testsuite/gcc.dg/dfp/compare-special.h
+++ b/gcc/testsuite/gcc.dg/dfp/compare-special.h
@@ -1,19 +1,19 @@
/* Basic test of runtime relational comparisons using NaNs and infinities. */
#include <stdlib.h>
-
-static int failcnt;
+#include "dfp-dbg.h"
#define PASTE2(A,B) A ## B
#define PASTE(A,B) PASTE2(A,B)
+/* Override FAILURE from dfp-dbg.h with one that provides additional info. */
+#undef FAILURE
#ifdef DBG
-#include <stdio.h>
#define FAILURE(OP,KIND) \
{ printf ("failed at line %d: %s for %s values\n", __LINE__, OP, KIND); \
- failcnt++; }
+ failures++; }
#else
-#define FAILURE(OP,KIND) abort ();
+#define FAILURE(OP,KIND) __builtin_abort ();
#endif
#ifndef WIDTH
@@ -281,7 +281,4 @@ test_compares (void)
if (!(y != m_inf)) FAILURE ("!=", "inf")
if (!(z != inf)) FAILURE ("!=", "inf")
if (z != m_inf) FAILURE ("!=", "inf")
-
- if (failcnt)
- abort ();
}
diff --git a/gcc/testsuite/gcc.dg/dfp/composite-type.c b/gcc/testsuite/gcc.dg/dfp/composite-type.c
index 2abc8217595..508ebbd5e29 100644
--- a/gcc/testsuite/gcc.dg/dfp/composite-type.c
+++ b/gcc/testsuite/gcc.dg/dfp/composite-type.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -O -Wall" } */
+/* { dg-options "-O -Wall" } */
/* C99 6.2.7: Compatible type and composite type. */
diff --git a/gcc/testsuite/gcc.dg/dfp/constants-hex.c b/gcc/testsuite/gcc.dg/dfp/constants-hex.c
index 936f0ed8481..980eae012a8 100644
--- a/gcc/testsuite/gcc.dg/dfp/constants-hex.c
+++ b/gcc/testsuite/gcc.dg/dfp/constants-hex.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
/* N1150 6: Constants.
C99 6.4.4.2: Floating constants.
diff --git a/gcc/testsuite/gcc.dg/dfp/constants-pedantic.c b/gcc/testsuite/gcc.dg/dfp/constants-pedantic.c
index 540b7684035..be81b0fc44a 100644
--- a/gcc/testsuite/gcc.dg/dfp/constants-pedantic.c
+++ b/gcc/testsuite/gcc.dg/dfp/constants-pedantic.c
@@ -1,9 +1,11 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -pedantic" } */
+/* { dg-options "-pedantic" } */
/* N1150 6: Constants.
C99 6.4.4.2: Floating constants. */
+#include "dfp-dbg.h"
+
_Decimal32 a = 1.1df; /* { dg-warning "GCC extension|ISO C" } */
_Decimal32 b = -.003DF; /* { dg-warning "GCC extension|ISO C" } */
_Decimal64 c = 11e-1dl; /* { dg-warning "GCC extension|ISO C" } */
diff --git a/gcc/testsuite/gcc.dg/dfp/constants-zero.c b/gcc/testsuite/gcc.dg/dfp/constants-zero.c
index e0db28cc38f..64b0054d2d3 100644
--- a/gcc/testsuite/gcc.dg/dfp/constants-zero.c
+++ b/gcc/testsuite/gcc.dg/dfp/constants-zero.c
@@ -1,10 +1,10 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* Decimal float values can have significant trailing zeroes. This is
true for zero values as well. Check that various representations of
zero are handled correctly when specified as literal constants. */
-extern void abort (void);
+#include "dfp-dbg.h"
int big_endian;
@@ -58,74 +58,74 @@ void
dpd_tests (void)
{
if (! compare32 (0.DF, 0x22500000U))
- abort ();
+ FAILURE
if (! compare32 (-0.DF, 0xa2500000U))
- abort ();
+ FAILURE
if (! compare32 (0.E-4DF, 0x22100000U))
- abort ();
+ FAILURE
if (! compare32 (0.E-7DF, 0x21e00000U))
- abort ();
+ FAILURE
if (! compare32 (0.E+3DF, 0x22800000U))
- abort ();
+ FAILURE
if (! compare64 (0.DD, 0x2238000000000000ULL))
- abort ();
+ FAILURE
if (! compare64 (-0.DD, 0xa238000000000000ULL))
- abort ();
+ FAILURE
if (! compare64 (0.E-6DD, 0x2220000000000000ULL))
- abort ();
+ FAILURE
if (! compare64 (0.E-7DD, 0x221c000000000000ULL))
- abort ();
+ FAILURE
if (! compare64 (0.E+2DD, 0x2240000000000000ULL))
- abort ();
+ FAILURE
if (! compare128 (0.DL, 0x2208000000000000ULL, 0x0000000000000000ULL))
- abort ();
+ FAILURE
if (! compare128 (-0.DL, 0xa208000000000000ULL, 0x0000000000000000ULL))
- abort ();
+ FAILURE
if (! compare128 (0.E-3DL, 0x2207400000000000ULL, 0x0000000000000000ULL))
- abort ();
+ FAILURE
if (! compare128 (0.E-8DL, 0x2206000000000000ULL, 0x0000000000000000ULL))
- abort ();
+ FAILURE
if (! compare128 (0.E+2DL, 0x2208800000000000ULL, 0x0000000000000000ULL))
- abort ();
+ FAILURE
}
void
bid_tests (void)
{
if (! compare32 (0.DF, 0x32800000U))
- abort ();
+ FAILURE
if (! compare32 (-0.DF, 0xb2800000U))
- abort ();
+ FAILURE
if (! compare32 (0.E-4DF, 0x30800000U))
- abort ();
+ FAILURE
if (! compare32 (0.E-7DF, 0x2f000000U))
- abort ();
+ FAILURE
if (! compare32 (0.E+3DF, 0x34000000U))
- abort ();
+ FAILURE
if (! compare64 (0.DD, 0x31c0000000000000ULL))
- abort ();
+ FAILURE
if (! compare64 (-0.DD, 0xb1c0000000000000ULL))
- abort ();
+ FAILURE
if (! compare64 (0.E-6DD, 0x3100000000000000ULL))
- abort ();
+ FAILURE
if (! compare64 (0.E-7DD, 0x30e0000000000000ULL))
- abort ();
+ FAILURE
if (! compare64 (0.E+2DD, 0x3200000000000000ULL))
- abort ();
+ FAILURE
if (! compare128 (0.DL, 0x3040000000000000ULL, 0x0000000000000000ULL))
- abort ();
+ FAILURE
if (! compare128 (-0.DL, 0xb040000000000000ULL, 0x0000000000000000ULL))
- abort ();
+ FAILURE
if (! compare128 (0.E-3DL, 0x303a000000000000ULL, 0x0000000000000000ULL))
- abort ();
+ FAILURE
if (! compare128 (0.E-8DL, 0x3030000000000000ULL, 0x0000000000000000ULL))
- abort ();
+ FAILURE
if (! compare128 (0.E+2DL, 0x3044000000000000ULL, 0x0000000000000000ULL))
- abort ();
+ FAILURE
}
int
@@ -138,7 +138,7 @@ main ()
if ((sizeof (_Decimal64) != sizeof (long long))
|| (sizeof (_Decimal128) != 2 * sizeof (long long))
|| (sizeof (_Decimal32) != sizeof (_Decimal32)))
- abort ();
+ FAILURE
u32.d = 1.DF;
@@ -153,7 +153,7 @@ main ()
bid_tests ();
}
else
- abort (); /* unknown format; test problem */
+ FAILURE /* unknown format; test problem */
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/constants.c b/gcc/testsuite/gcc.dg/dfp/constants.c
index 50045ed9cec..bb61ea3352b 100644
--- a/gcc/testsuite/gcc.dg/dfp/constants.c
+++ b/gcc/testsuite/gcc.dg/dfp/constants.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
/* N1150 6: Constants.
C99 6.4.4.2: Floating constants. */
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-10.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-10.c
index dec7b515fcf..743eb293c55 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp-10.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-10.c
@@ -1,5 +1,3 @@
-/* { dg-options "-std=gnu99" } */
-
/* This test assumes IEEE float and double. */
#define __STDC_WANT_DEC_FP__
@@ -108,7 +106,5 @@ main ()
convert_246 ();
convert_247 ();
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-11.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-11.c
index 283f9bd4f88..d16919f81ac 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp-11.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-11.c
@@ -1,4 +1,3 @@
-/* { dg-options "-std=gnu99" } */
/* { dg-skip-if "" { ! "powerpc*-*-linux*" } { "*" } { "" } } */
/* Test decimal float conversions to and from IBM 128-bit long double.
@@ -55,7 +54,5 @@ main ()
convert_311 ();
convert_312 ();
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-12.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-12.c
index 96381415dce..7a909552afc 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp-12.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-12.c
@@ -1,9 +1,7 @@
/* Test for bug where fold wrongly removed conversions to double and
replaced them by conversions to float. */
-/* { dg-options "-std=gnu99" } */
-extern void abort (void);
-extern void exit (int);
+#include "dfp-dbg.h"
volatile float f = __builtin_inff ();
volatile _Decimal32 d32 = 1e40DF;
@@ -12,6 +10,7 @@ int
main (void)
{
if ((double) f == (double) d32)
- abort ();
- exit (0);
+ FAILURE
+
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-13.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-13.c
index 91a5b494884..259cc745ce3 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp-13.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-13.c
@@ -1,9 +1,7 @@
/* Test for bug where fold changed binary operation to decimal
depending on typedefs. */
-/* { dg-options "-std=gnu99" } */
-extern void abort (void);
-extern void exit (int);
+#include "dfp-dbg.h"
volatile double d = 1.2345675;
@@ -15,6 +13,6 @@ main (void)
_Decimal32 a = (d * d);
d32 b = (d * d);
if (a != b)
- abort ();
- exit (0);
+ FAILURE
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-14.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-14.c
index a1312d2a0e6..858c92980b5 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp-14.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-14.c
@@ -1,9 +1,7 @@
/* Test for bug where fold narrowed decimal floating-point
operations. */
-/* { dg-options "-std=gnu99" } */
-extern void abort (void);
-extern void exit (int);
+#include "dfp-dbg.h"
volatile _Decimal32 f = 1.23456DF;
volatile _Decimal64 d = 1.23456DD;
@@ -12,6 +10,6 @@ int
main (void)
{
if ((double)((_Decimal64)f * (_Decimal64)f) != (double)(d * d))
- abort ();
- exit (0);
+ FAILURE
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-2.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-2.c
index 28273512005..463d27f355f 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp-2.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-2.c
@@ -1,5 +1,3 @@
-/* { dg-options "-std=gnu99" } */
-
/* This test assumes IEEE float and double. It also tests long double
but makes no assumption about its size or range of values. */
@@ -31,7 +29,5 @@ main ()
CALL_VALID_ALL (t6)
CALL_VALID_ALL (t7)
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-3.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-3.c
index 67d31c33ac9..3e1d9d57a77 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp-3.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-3.c
@@ -1,5 +1,3 @@
-/* { dg-options "-std=gnu99" } */
-
/* This test assumes IEEE float and double. It also tests long double
but makes no assumption about its size or range of values. */
@@ -19,7 +17,5 @@ main ()
{
CALL_ZEROES_ALL (t)
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-4.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-4.c
index feba37a9eae..b97b9c6cb08 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp-4.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-4.c
@@ -1,5 +1,3 @@
-/* { dg-options "-std=gnu99" } */
-
/* This test assumes IEEE float and double. It also tests long double
but makes no assumption about its size or range of values. */
@@ -19,7 +17,5 @@ main ()
{
CALL_INF_ALL (t)
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-5.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-5.c
index cfb86fd015d..ada2d352cca 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp-5.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-5.c
@@ -1,5 +1,3 @@
-/* { dg-options "-std=gnu99" } */
-
/* This test assumes IEEE float and double. It also tests long double
but makes no assumption about its size or range of values. */
@@ -19,7 +17,5 @@ main ()
{
CALL_NAN_ALL (t)
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-6.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-6.c
index 7603f751992..64198a95f2a 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp-6.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-6.c
@@ -1,5 +1,5 @@
/* { dg-xfail-run-if "" { lax_strtofp } "*" "" } */
-/* { dg-options "-std=gnu99 -w" } */
+/* { dg-options "-w" } */
/* This test assumes IEEE float and double. */
@@ -174,7 +174,5 @@ main ()
convert_364 ();
}
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-7.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-7.c
index 0fb4f076d25..f51d696cee6 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp-7.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-7.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -w" } */
+/* { dg-options "-w" } */
/* This test assumes IEEE float and double. */
@@ -79,7 +79,5 @@ main ()
convert_351 ();
convert_352 ();
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-8.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-8.c
index 269fc37f208..532bd861314 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp-8.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-8.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -w" } */
+/* { dg-options "-w" } */
/* This test assumes IEEE float and double. */
@@ -67,7 +67,5 @@ main ()
convert_443 ();
convert_444 ();
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-9.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-9.c
index 90f0692136c..e609087525a 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp-9.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-9.c
@@ -1,5 +1,5 @@
/* { dg-xfail-run-if "" { lax_strtofp } "*" "" } */
-/* { dg-options "-std=gnu99 -w" } */
+/* { dg-options "-w" } */
/* This test assumes IEEE float and double. */
@@ -188,7 +188,5 @@ main ()
convert_419 ();
convert_420 ();
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-fold.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-fold.c
index 8c20a52ee69..41a04febf61 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp-fold.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-fold.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O2" } */
+/* { dg-options "-O2" } */
/* N1150 5.2 Conversions among decimal floating types and between
decimal floating types and generic floating types.
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp.c
index b2e8ca87b16..710538d467b 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-bfp.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp.c
@@ -1,23 +1,12 @@
-/* { dg-options "-std=gnu99" } */
-
/* N1150 5.2 Conversions among decimal floating types and between
decimal floating types and generic floating types.
C99 6.3.1.5(4) Conversions, arithmetic operands, real floating types. */
/* Long double isn't supported yet at runtime, so disable those checks. */
-extern void abort (void);
-static int failcnt;
-static int skip_long_double;
+#include "dfp-dbg.h"
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+static int skip_long_double;
volatile _Decimal32 d32;
volatile _Decimal64 d64;
@@ -138,8 +127,5 @@ main ()
|| df > (2.9802322387695312e-08 + 0.00000000001))
FAILURE
- if (failcnt != 0)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-complex.c b/gcc/testsuite/gcc.dg/dfp/convert-complex.c
index 0083b091880..76eef87cb7c 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-complex.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-complex.c
@@ -3,17 +3,7 @@
/* N1150 5.3 Conversions between decimal floating and complex.
C99 6.3.1.7 Conversions, arithmetic operands, real and complex. */
-extern void abort(void);
-static int failcnt;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
int
main ()
@@ -124,8 +114,5 @@ main ()
if (d128 != 0.0625DL)
FAILURE
- if (failcnt != 0)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-dfp-fold-2.c b/gcc/testsuite/gcc.dg/dfp/convert-dfp-fold-2.c
index 9f0927963a1..073f7abc4a6 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-dfp-fold-2.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-dfp-fold-2.c
@@ -1,9 +1,7 @@
/* Test for bug where fold narrowed decimal floating-point
operations. */
-/* { dg-options "-std=gnu99" } */
-extern void abort (void);
-extern void exit (int);
+#include "dfp-dbg.h"
volatile _Decimal32 f = 1.23456DF;
volatile _Decimal64 d = 1.23456DD;
@@ -12,6 +10,6 @@ int
main (void)
{
if ((_Decimal128)((_Decimal64)f * (_Decimal64)f) != (_Decimal128)(d * d))
- abort ();
- exit (0);
+ FAILURE
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-dfp-fold.c b/gcc/testsuite/gcc.dg/dfp/convert-dfp-fold.c
index a56f0dfc25e..349fb3545ec 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-dfp-fold.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-dfp-fold.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O2" } */
+/* { dg-options "-O2" } */
/* N1150 5.2 Conversions among decimal floating types and between
decimal floating types and generic floating types.
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-dfp-round.c b/gcc/testsuite/gcc.dg/dfp/convert-dfp-round.c
index 9833abb7ff0..e3781bfc967 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-dfp-round.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-dfp-round.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O0 -std=gnu99" } */
+/* { dg-options "-O0" } */
/* { dg-skip-if "test is for emulation" { hard_dfp } { "*" } { "" } } */
/* N1150 5.2: Conversions among decimal floating types and between
@@ -12,20 +12,9 @@
Normally this would not be part of compiler testing, but conversions
are currently handled in libgcc via decNumber. */
+#include "dfp-dbg.h"
#include "dfp-round.h"
-extern void abort (void);
-static int failcnt = 0;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
-
_Decimal32 d32;
_Decimal64 d64;
_Decimal128 d128;
@@ -131,7 +120,5 @@ main ()
if (!do_d128_to_d64 (-1.1111111111111125dl, -1.111111111111112dd)) FAILURE
if (!do_d128_to_d64 (-1.1111111111111135dl, -1.111111111111113dd)) FAILURE
- if (failcnt)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-dfp.c b/gcc/testsuite/gcc.dg/dfp/convert-dfp.c
index 148dff60e3f..d52ba51b0be 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-dfp.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-dfp.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* N1150 5.2 Conversions among decimal floating types and between
decimal floating types and generic floating types.
@@ -10,20 +10,9 @@
#define __STDC_WANT_DEC_FP__ 1
#endif
+#include "dfp-dbg.h"
#include <float.h>
-extern void abort (void);
-static int failcnt;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
-
volatile _Decimal32 d32;
volatile _Decimal64 d64;
volatile _Decimal128 d128;
@@ -101,8 +90,5 @@ main ()
if (d64 != __builtin_infd64())
FAILURE
- if (failcnt != 0)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-int-fold.c b/gcc/testsuite/gcc.dg/dfp/convert-int-fold.c
index e550369be23..ae0945b0d5d 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-int-fold.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-int-fold.c
@@ -1,9 +1,13 @@
-/* { dg-options "-std=gnu99 -O2" } */
+/* { dg-options "-O2" } */
/* N1150 5.1 Conversion between decimal floating integer.
C99 6.3.1.4(1a) New.
These should all be folded at compile time. */
+#include "dfp-dbg.h"
+
+#define BOOL _Bool
+
extern void link_error (void);
int
@@ -18,11 +22,11 @@ main ()
int si;
long sl;
long long sll;
- _Bool b;
+ BOOL b;
/* C99 Section 6.7.2 Type specifiers. Type _Bool is
mentioned in this section. Conversions between
- _Bool and DFP types. */
+ BOOL and DFP types. */
/* Decimal float to unsigned integer. */
d32 = 456.789df;
@@ -61,7 +65,7 @@ main ()
/* Decimal float to signed integer. */
- /* Decimal float to _Bool. */
+ /* Decimal float to BOOL. */
d32 = 1.23df;
d64 = -3.4dd;
d128 = 0.00003dl;
@@ -146,7 +150,7 @@ main ()
if (d128 != -1234567.dl)
link_error ();
- /* _Bool to decimal float. */
+ /* BOOL to decimal float. */
d32 = 0.0DF;
d64 = 0.0DD;
d128 = 0.0DL;
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-int-max-fold.c b/gcc/testsuite/gcc.dg/dfp/convert-int-max-fold.c
index 7e016918ad2..9abbbbb6078 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-int-max-fold.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-int-max-fold.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O2" } */
+/* { dg-options "-O2 -w" } */
/* N1150 5.1 Conversions from decimal float to integer. */
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-int-max.c b/gcc/testsuite/gcc.dg/dfp/convert-int-max.c
index cb0c428a164..724627d3763 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-int-max.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-int-max.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0 -w" } */
/* N1150 5.1 Conversions from decimal float to integer. */
@@ -6,15 +6,7 @@
what will fit into the destination type. This assumes 32-bit int and
64-bit long long (there's a check for that below). */
-extern void abort (void);
-int failcnt;
-
-#ifdef DBG
-extern int printf (const char *, ...);
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
volatile _Decimal32 d32;
volatile _Decimal64 d64;
@@ -150,7 +142,5 @@ main ()
doit ();
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-int-saturate.c b/gcc/testsuite/gcc.dg/dfp/convert-int-saturate.c
index ab4c8d268ad..c92502d56ad 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-int-saturate.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-int-saturate.c
@@ -1,5 +1,3 @@
-/* { dg-options "-std=gnu99" } */
-
/* N1150 5.1 Conversion between decimal floating integer.
C99 6.3.1.4(1a) New.
Test integer saturation. */
@@ -8,11 +6,10 @@
#define __STDC_WANT_DEC_FP__ 1
#endif
+#include "dfp-dbg.h"
#include <float.h>
#include <limits.h>
-extern void abort (void);
-
volatile _Decimal32 d32;
volatile _Decimal64 d64;
volatile _Decimal128 d128;
@@ -28,40 +25,40 @@ main ()
/* Unsigned. */
usi = DEC32_MAX; /* { dg-warning "overflow in implicit constant conversion" } */
if (usi != UINT_MAX)
- abort ();
+ FAILURE
usi = DEC64_MAX; /* { dg-warning "overflow in implicit constant conversion" } */
if (usi != UINT_MAX)
- abort ();
+ FAILURE
usi = DEC128_MAX; /* { dg-warning "overflow in implicit constant conversion" } */
if (usi != UINT_MAX)
- abort ();
+ FAILURE
/* Signed. */
si = DEC32_MAX; /* { dg-warning "overflow in implicit constant conversion" } */
if (si != INT_MAX)
- abort ();
+ FAILURE
si = DEC64_MAX; /* { dg-warning "overflow in implicit constant conversion" } */
if (si != INT_MAX)
- abort ();
+ FAILURE
si = DEC128_MAX; /* { dg-warning "overflow in implicit constant conversion" } */
if (si != INT_MAX)
- abort ();
+ FAILURE
si = - DEC32_MAX; /* { dg-warning "overflow in implicit constant conversion" } */
if (si != INT_MIN)
- abort ();
+ FAILURE
si = - DEC64_MAX; /* { dg-warning "overflow in implicit constant conversion" } */
if (si != INT_MIN)
- abort ();
+ FAILURE
si = - DEC128_MAX; /* { dg-warning "overflow in implicit constant conversion" } */
if (si != INT_MIN)
- abort ();
+ FAILURE
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-int.c b/gcc/testsuite/gcc.dg/dfp/convert-int.c
index 45efe32a5e8..0c2d7938604 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert-int.c
+++ b/gcc/testsuite/gcc.dg/dfp/convert-int.c
@@ -1,17 +1,11 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* N1150 5.1 Conversion between decimal floating types and integer.
C99 6.3.1.4(1a) New. */
-extern void abort (void);
-int failcnt;
+#include "dfp-dbg.h"
-#ifdef DBG
-extern int printf (const char *, ...);
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#define BOOL _Bool
_Decimal32 d32;
_Decimal64 d64;
@@ -22,7 +16,7 @@ unsigned long long ull;
int si;
long sl;
long long sll;
-_Bool b;
+BOOL b;
void
init_dfp_1 (void)
@@ -68,7 +62,7 @@ main ()
{
/* C99 Section 6.7.2 Type specifiers. Type _Bool is
mentioned in this section. Conversions between
- _Bool and DFP types. */
+ BOOL and DFP types. */
/* Decimal float to unsigned integer. */
init_dfp_1 ();
@@ -105,7 +99,7 @@ main ()
/* Decimal float to signed integer. */
- /* Decimal float to _Bool. */
+ /* Decimal float to BOOL. */
init_dfp_2 ();
b = d32;
@@ -184,7 +178,7 @@ main ()
if (d128 != -1234567.dl)
FAILURE
- /* _Bool to decimal float. */
+ /* BOOL to decimal float. */
init_dfp_3 ();
b = d32;
@@ -197,8 +191,5 @@ main ()
if (b)
FAILURE
- if (failcnt != 0)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert.h b/gcc/testsuite/gcc.dg/dfp/convert.h
index bc9ef42f4dd..304164ff627 100644
--- a/gcc/testsuite/gcc.dg/dfp/convert.h
+++ b/gcc/testsuite/gcc.dg/dfp/convert.h
@@ -1,5 +1,4 @@
-extern void abort (void);
-static int failcnt = 0;
+#include "dfp-dbg.h"
/* Macros are set up to skip using long double, which doesn't necessarily
map to TF mode. If there's a reason to skip those for a test, the
@@ -8,14 +7,16 @@ static int failcnt = 0;
#define USE_TF 1
#endif
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
+/* Provide more information with FAILURE than what is available with
+ the version of that macro in dfp-dbg.h. */
+
+#undef FAILURE
#if defined(DBG) || defined(DBG2)
#include <stdio.h>
#define FAILURE(NUM) \
- { printf ("failed for test %s\n", NUM); failcnt++; }
+ { printf ("failed for test %s\n", NUM); failures++; }
#else
-#define FAILURE(N) abort ();
+#define FAILURE(N) __builtin_abort ();
#endif
/* This is useful when modifying the test to make sure that tests are
diff --git a/gcc/testsuite/gcc.dg/dfp/ctypes.c b/gcc/testsuite/gcc.dg/dfp/ctypes.c
index 6afacd5173d..ca8fe954e5e 100644
--- a/gcc/testsuite/gcc.dg/dfp/ctypes.c
+++ b/gcc/testsuite/gcc.dg/dfp/ctypes.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
/* N1150 3: Decimal floating types.
C99 6.7.2: Type specifiers */
diff --git a/gcc/testsuite/gcc.dg/dfp/ddmode-ice.c b/gcc/testsuite/gcc.dg/dfp/ddmode-ice.c
index 979dabe11e2..19f3038010b 100644
--- a/gcc/testsuite/gcc.dg/dfp/ddmode-ice.c
+++ b/gcc/testsuite/gcc.dg/dfp/ddmode-ice.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -O1" } */
+/* { dg-options "-O1" } */
/* This used to result in an ICE. */
diff --git a/gcc/testsuite/gcc.dg/dfp/dec-eval-method-2.c b/gcc/testsuite/gcc.dg/dfp/dec-eval-method-2.c
index 55001cc3822..b87f159bf3b 100644
--- a/gcc/testsuite/gcc.dg/dfp/dec-eval-method-2.c
+++ b/gcc/testsuite/gcc.dg/dfp/dec-eval-method-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -D__STDC_WANT_DEC_FP__" } */
+/* { dg-options "-D__STDC_WANT_DEC_FP__" } */
/* N1107 4: Characteristics of decimal floating types <float.h>.
C99 5.2.4.2.2a[2] (New).
diff --git a/gcc/testsuite/gcc.dg/dfp/decfloat-constants.c b/gcc/testsuite/gcc.dg/dfp/decfloat-constants.c
index ec9d3816706..c72933f4233 100644
--- a/gcc/testsuite/gcc.dg/dfp/decfloat-constants.c
+++ b/gcc/testsuite/gcc.dg/dfp/decfloat-constants.c
@@ -1,5 +1,3 @@
-/* { dg-options "-std=gnu99" } */
-
/* N1150 4: Characteristics of decimal floating types <float.h>.
C99 5.2.4.2.2a[3]: New.
@@ -11,20 +9,9 @@
#define __STDC_WANT_DEC_FP__ 1
#endif
+#include "dfp-dbg.h"
#include <float.h>
-extern void abort (void);
-static int failcnt;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
-
int main ()
{
if (DEC32_MANT_DIG != 7) FAILURE
@@ -56,8 +43,5 @@ int main ()
if (DEC128_SUBNORMAL_MIN != 0.000000000000000000000000000000001E-6143DL)
FAILURE
- if (failcnt != 0)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/dfp-dbg.h b/gcc/testsuite/gcc.dg/dfp/dfp-dbg.h
new file mode 100644
index 00000000000..a32afa96bae
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/dfp-dbg.h
@@ -0,0 +1,10 @@
+int failures;
+
+#ifdef DBG
+extern int printf (const char *, ...);
+#define FAILURE { printf ("failed at line %d\n", __LINE__); failures++; }
+#define FINISH if (failures != 0) __builtin_abort (); return 0;
+#else
+#define FAILURE __builtin_abort ();
+#define FINISH return 0;
+#endif
diff --git a/gcc/testsuite/gcc.dg/dfp/dfp.exp b/gcc/testsuite/gcc.dg/dfp/dfp.exp
index 2619a94122f..ce6668fb66f 100644
--- a/gcc/testsuite/gcc.dg/dfp/dfp.exp
+++ b/gcc/testsuite/gcc.dg/dfp/dfp.exp
@@ -37,12 +37,14 @@ if { ![check_effective_target_dfprt] } {
}
verbose "dfp.exp: dg-do-what-default is ${dg-do-what-default}" 2
-# If a testcase doesn't have special options, use these.
global DEFAULT_CFLAGS
-if ![info exists DEFAULT_CFLAGS] then {
- set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+if [info exists DEFAULT_CFLAGS] then {
+ set save_default_cflags $DEFAULT_CFLAGS
}
+# If a testcase doesn't have special options, use these.
+set DEFAULT_CFLAGS "-std=gnu99"
+
# Initialize `dg'.
dg-init
@@ -55,3 +57,6 @@ dg-finish
set dg-do-what-default ${save-dg-do-what-default}
verbose "dfp.exp: dg-do-what-default is ${dg-do-what-default}" 2
+if [info exists save_default_cflags] {
+ set DEFAULT_CFLAGS $save_default_cflags
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/fe-binop.c b/gcc/testsuite/gcc.dg/dfp/fe-binop.c
index 23f137818ed..eb0da1b2c6e 100644
--- a/gcc/testsuite/gcc.dg/dfp/fe-binop.c
+++ b/gcc/testsuite/gcc.dg/dfp/fe-binop.c
@@ -1,4 +1,3 @@
-/* { dg-options "-std=gnu99" } */
/* { dg-skip-if "test is for emulation" { hard_dfp } { "*" } { "" } } */
/* Touch tests that check for raising appropriate exceptions for binary
@@ -102,7 +101,5 @@ main ()
binop_501 ();
binop_502 ();
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/fe-check.h b/gcc/testsuite/gcc.dg/dfp/fe-check.h
index 0e072aa9fa1..9c5f0ff8c59 100644
--- a/gcc/testsuite/gcc.dg/dfp/fe-check.h
+++ b/gcc/testsuite/gcc.dg/dfp/fe-check.h
@@ -2,19 +2,17 @@
are raised for decimal float operations. These tests are here to test
the software decimal float support in libgcc. */
+#include "dfp-dbg.h"
#include "dfp-except.h"
-extern void abort (void);
-static int failcnt = 0;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
#if defined(DBG) || defined(DBG2)
#include <stdio.h>
+#undef FAILURE
#define FAILURE(NUM,KIND,EXCEPT) \
- { printf ("failed for test %d: %s %s\n", NUM, KIND, EXCEPT); failcnt++; }
+ { printf ("failed for test %d: %s %s\n", NUM, KIND, EXCEPT); failures++; }
#else
-#define FAILURE(N,K,E) abort ();
+#undef FAILURE
+#define FAILURE(N,K,E) __builtin_abort ();
#endif
/* This is useful when modifying the test to make sure that tests are
diff --git a/gcc/testsuite/gcc.dg/dfp/fe-convert-1.c b/gcc/testsuite/gcc.dg/dfp/fe-convert-1.c
index f65cf7870ae..b6528029b40 100644
--- a/gcc/testsuite/gcc.dg/dfp/fe-convert-1.c
+++ b/gcc/testsuite/gcc.dg/dfp/fe-convert-1.c
@@ -1,4 +1,3 @@
-/* { dg-options "-std=gnu99" } */
/* { dg-skip-if "test is for emulation" { hard_dfp } { "*" } { "" } } */
/* Check that appropriate exceptions are raised for conversions involving
@@ -37,7 +36,5 @@ main ()
convert_121 ();
convert_122 ();
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/fe-convert-2.c b/gcc/testsuite/gcc.dg/dfp/fe-convert-2.c
index 83b490d54be..4abce24c608 100644
--- a/gcc/testsuite/gcc.dg/dfp/fe-convert-2.c
+++ b/gcc/testsuite/gcc.dg/dfp/fe-convert-2.c
@@ -1,5 +1,3 @@
-/* { dg-options "-std=gnu99" } */
-
/* Check that appropriate exceptions are raised for BFP to DFP conversions.
The test only uses double and _Decimal32; tests for conversions to
_Decimal64 would need 128-bit long double. */
@@ -29,7 +27,5 @@ main ()
convert_104 ();
convert_105 ();
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/fe-convert-3.c b/gcc/testsuite/gcc.dg/dfp/fe-convert-3.c
index e3fe30eeb11..5938edb94e7 100644
--- a/gcc/testsuite/gcc.dg/dfp/fe-convert-3.c
+++ b/gcc/testsuite/gcc.dg/dfp/fe-convert-3.c
@@ -1,5 +1,3 @@
-/* { dg-options "-std=gnu99" } */
-
/* Check that appropriate exceptions are raised for int to DFP conversions. */
#include "fe-check.h"
@@ -43,7 +41,5 @@ main ()
convert_210 ();
convert_211 ();
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/float-constant-double.c b/gcc/testsuite/gcc.dg/dfp/float-constant-double.c
index 3f8de656bf6..52c5d712665 100644
--- a/gcc/testsuite/gcc.dg/dfp/float-constant-double.c
+++ b/gcc/testsuite/gcc.dg/dfp/float-constant-double.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
/* Constant float values of type double in <float.h> are suffixed with L
and cast to double so they can be used within code that uses pragma
diff --git a/gcc/testsuite/gcc.dg/dfp/func-array.c b/gcc/testsuite/gcc.dg/dfp/func-array.c
index 93713486baa..6d158f35523 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-array.c
+++ b/gcc/testsuite/gcc.dg/dfp/func-array.c
@@ -1,19 +1,7 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.5.2.2 Function calls.
Test passing array elements involving decimal floating point types. */
-extern void abort (void);
-static int failcnt;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
/* A handful of functions that return the Nth _Decimal32 argument of
an incoming array. */
@@ -165,8 +153,5 @@ int main()
if (arg4_128 (d128) != 4.0dl) FAILURE
if (arg5_128 (d128) != 5.0dl) FAILURE
- if (failcnt != 0)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-deref.c b/gcc/testsuite/gcc.dg/dfp/func-deref.c
index d16e70d29d5..81a48a9f8e8 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-deref.c
+++ b/gcc/testsuite/gcc.dg/dfp/func-deref.c
@@ -1,20 +1,8 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.5.2.2 Function calls.
Test scalar passing and return values involving decimal floating
point types and dereferenced pointers. */
-extern void abort (void);
-static int failcnt;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
/* A handful of functions that return their Nth _Decimal32
argument. */
@@ -213,8 +201,5 @@ main ()
if (arg5_128 (*pdl0, *pdl1, *pdl2, *pdl3, *pdl4, *pdl5) != 5.0dl)
FAILURE
- if (failcnt != 0)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-mixed.c b/gcc/testsuite/gcc.dg/dfp/func-mixed.c
index 620d342e980..6f7e2eb4157 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-mixed.c
+++ b/gcc/testsuite/gcc.dg/dfp/func-mixed.c
@@ -1,20 +1,10 @@
-/* { dg-options "-std=gnu99 -Wall" } */
+/* { dg-options "-Wall" } */
/* C99 6.5.2.2 Function calls.
Test scalar passing and return values involving decimal floating
point types. */
-extern void abort (void);
-static int failcnt;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
/* A handful of functions that return their Nth _Decimal32
argument with mixed types in parameter list. */
@@ -180,8 +170,5 @@ main ()
if (arg4_128 (0, -1, 2.0f, 3.0, 4.0dl, 5.0l) != 4.0dl) FAILURE
if (arg5_128 (0, -1, 2.0f, 3.0, 4.0l, 5.0dl) != 5.0dl) FAILURE
- if (failcnt != 0)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-pointer.c b/gcc/testsuite/gcc.dg/dfp/func-pointer.c
index e1faceb63f0..cfdf2356c9d 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-pointer.c
+++ b/gcc/testsuite/gcc.dg/dfp/func-pointer.c
@@ -1,20 +1,8 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.5.2.2 Function calls.
Test pointer argument passing and return values involving decimal floating
point types. */
-extern void abort (void);
-static int failcnt;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
/* A handful of functions that return their Nth pointer to Decimal32
argument. */
@@ -213,8 +201,5 @@ main ()
if (*arg5_128 (pdl0, pdl1, pdl2, pdl3, pdl4, pdl5) != 5.0dl)
FAILURE
- if (failcnt != 0)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-scalar.c b/gcc/testsuite/gcc.dg/dfp/func-scalar.c
index bbda52c0773..370c21b20e2 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-scalar.c
+++ b/gcc/testsuite/gcc.dg/dfp/func-scalar.c
@@ -1,20 +1,8 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.5.2.2 Function calls.
Test scalar passing and return values involving decimal floating
point types. */
-extern void abort (void);
-static int failcnt;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
/* A handful of functions that return their Nth _Decimal32
argument. */
@@ -200,8 +188,5 @@ main ()
if (arg5_128 (0.0dl, 1.0dl, 2.0dl, 3.0dl, 4.0dl, 5.0dl) != 5.0dl)
FAILURE
- if (failcnt != 0)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-struct.c b/gcc/testsuite/gcc.dg/dfp/func-struct.c
index f022f181659..ad0224d6cad 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-struct.c
+++ b/gcc/testsuite/gcc.dg/dfp/func-struct.c
@@ -1,20 +1,8 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.5.2.2 Function calls.
Test structure passing and return values involving decimal floating
point types. */
-extern void abort (void);
-static int failcnt;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
struct example
{
@@ -101,8 +89,5 @@ main ()
if (ptr_dummy1_field (&nums) != 'a') FAILURE
if (ptr_dummy2_field (&nums) != 'b') FAILURE
- if (failcnt != 0)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c
index 167da24b889..2960c357ade 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c
+++ b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128-2.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
-/* { dg-options "-std=gnu99 -mpreferred-stack-boundary=2" } */
+/* { dg-options "-mpreferred-stack-boundary=2" } */
/* Simple test of vararg passing for problematic types with and without
double values passed between them. */
@@ -17,5 +17,6 @@ int
main ()
{
doit ();
- return 0;
+
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128.c b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128.c
index e8fc0271dcb..8d452eadc38 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128.c
+++ b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d128.c
@@ -1,5 +1,3 @@
-/* { dg-options "-std=gnu99" } */
-
/* Simple test of vararg passing for problematic types with and without
double values passed between them. */
@@ -16,5 +14,6 @@ int
main ()
{
doit ();
- return 0;
+
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d32.c b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d32.c
index cd6853cc985..651b7e8c50f 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d32.c
+++ b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d32.c
@@ -1,5 +1,3 @@
-/* { dg-options "-std=gnu99" } */
-
/* Simple test of vararg passing for problematic types with and without
double values passed between them. */
@@ -16,5 +14,6 @@ int
main ()
{
doit ();
- return 0;
+
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d64.c b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d64.c
index 39470013ecd..86b475d2ada 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d64.c
+++ b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate-d64.c
@@ -1,5 +1,3 @@
-/* { dg-options "-std=gnu99" } */
-
/* Simple test of vararg passing for problematic types with and without
double values passed between them. */
@@ -16,5 +14,6 @@ int
main ()
{
doit ();
- return 0;
+
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate.h b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate.h
index 393111b33bc..8dbb5093fe2 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate.h
+++ b/gcc/testsuite/gcc.dg/dfp/func-vararg-alternate.h
@@ -1,14 +1,9 @@
/* Simple test of vararg passing for problematic types with and without
double values passed between them. */
+#include "dfp-dbg.h"
#include <stdarg.h>
-#ifdef DBG
-#include <stdio.h>
-#endif
-extern void abort (void);
-
-int failcnt;
DTYPE a[10];
double b[10];
@@ -28,6 +23,7 @@ compare (double r, double s, int *p, int *q, int n, int line)
{
int j;
+ failures++;
printf ("line %-3d", line);
for (j = 0; j < n; j++)
printf (" %08x", p[j]);
@@ -39,7 +35,7 @@ compare (double r, double s, int *p, int *q, int n, int line)
return;
}
#else
- abort ();
+ __builtin_abort ();
#endif
}
@@ -102,7 +98,7 @@ doit ()
printf ("test error: INTS = %d, sizeof (DTYPE) = %d\n",
INTS, sizeof (DTYPE));
#endif
- abort ();
+ __builtin_abort ();
}
x = ONE / THREE;
@@ -144,7 +140,4 @@ doit ()
u1.d = x; u2.d = a[0]; compare (1.5, b[0], u1.i, u2.i, INTS, __LINE__);
u1.d = y; u2.d = a[1]; compare (2.5, b[1], u1.i, u2.i, INTS, __LINE__);
u1.d = z; u2.d = a[2]; compare (3.5, b[2], u1.i, u2.i, INTS, __LINE__);
-
- if (failcnt != 0)
- abort ();
}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-dfp.c b/gcc/testsuite/gcc.dg/dfp/func-vararg-dfp.c
index 1a681bcaf9b..5add1f7fd38 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-vararg-dfp.c
+++ b/gcc/testsuite/gcc.dg/dfp/func-vararg-dfp.c
@@ -1,21 +1,8 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.5.2.2 Function calls.
Test passing varargs of the decimal float types. */
#include <stdarg.h>
-
-extern void abort (void);
-static int failcnt = 0;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
static _Decimal32
vararg32 (unsigned arg, ...)
@@ -104,7 +91,5 @@ int main()
if (vararg128 (5, 0.0dl, 1.0dl, 2.0dl, 3.0dl, 4.0dl, 5.0dl) != 5.0dl)
FAILURE
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c b/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c
index c1b349c6728..893cdae27ff 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c
+++ b/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed-2.c
@@ -1,23 +1,12 @@
/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
-/* { dg-options "-std=gnu99 -mpreferred-stack-boundary=2" } */
+/* { dg-options "-mpreferred-stack-boundary=2" } */
/* C99 6.5.2.2 Function calls.
Test passing varargs of the combination of decimal float types and
other types. */
#include <stdarg.h>
-
-extern void abort (void);
-static int failcnt = 0;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
/* Supposing the list of varying number of arguments is:
unsigned int, _Decimal128, double, _Decimal32, _Decimal64. */
@@ -112,7 +101,5 @@ main ()
if (vararg_int (0, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 0) FAILURE
if (vararg_double (2, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 2.0) FAILURE
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed.c b/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed.c
index b5a5be45d7e..1669eaf959a 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed.c
+++ b/gcc/testsuite/gcc.dg/dfp/func-vararg-mixed.c
@@ -1,22 +1,9 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.5.2.2 Function calls.
Test passing varargs of the combination of decimal float types and
other types. */
#include <stdarg.h>
-
-extern void abort (void);
-static int failcnt = 0;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
/* Supposing the list of varying number of arguments is:
unsigned int, _Decimal128, double, _Decimal32, _Decimal64. */
@@ -111,7 +98,5 @@ main ()
if (vararg_int (0, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 0) FAILURE
if (vararg_double (2, 0, 1.0dl, 2.0, 3.0df, 4.0dd) != 2.0) FAILURE
- if (failcnt != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/func-vararg-size0.c b/gcc/testsuite/gcc.dg/dfp/func-vararg-size0.c
index dc94709c108..bc8b20fd484 100644
--- a/gcc/testsuite/gcc.dg/dfp/func-vararg-size0.c
+++ b/gcc/testsuite/gcc.dg/dfp/func-vararg-size0.c
@@ -1,10 +1,7 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.5.2.2 Function calls. */
#include <stdarg.h>
-
-extern void abort (void);
+#include "dfp-dbg.h"
struct S1
{
@@ -38,7 +35,7 @@ main ()
struct S1 a1[5];
if (check_var(5, 1.0, s1, 2LL, a1[2], a1[2]) == 0)
- abort ();
+ FAILURE
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/inf-1.c b/gcc/testsuite/gcc.dg/dfp/inf-1.c
index 86aa9e4cfaa..c4f8cd79610 100644
--- a/gcc/testsuite/gcc.dg/dfp/inf-1.c
+++ b/gcc/testsuite/gcc.dg/dfp/inf-1.c
@@ -1,63 +1,61 @@
-/* { dg-options "-std=gnu99" } */
-
/* N1150 4: Characteristics of decimal floating types (not explicit)
C99 5.2.4.2.2: Characteristics of floating types.
A few simple checks on arithmetic operations. */
-extern void abort (void);
+#include "dfp-dbg.h"
int main()
{
/* Assumes rounding mode. */
if (9999999.E90DF + 1.E90df != __builtin_infd32 ())
- abort ();
+ FAILURE
if (!__builtin_isinfd32 (9999999.E90DF + 1.E90df))
- abort ();
+ FAILURE
if (9.999999999999999E384dd + .000000000000001e384dd
!= __builtin_infd32 ())
- abort ();
+ FAILURE
if (-9999999.E90DF - 1.E90df != -__builtin_infd32 ())
- abort ();
+ FAILURE
if (!__builtin_isinfd32 (9.999999999999999E384dd + .000000000000001e384dd))
- abort ();
+ FAILURE
if (7.999999999999999999999999999999999E6144dl + 3.0E6144dl
!= __builtin_infd32 ())
- abort ();
+ FAILURE
if (__builtin_infd32 () * __builtin_infd32 () != __builtin_infd32 ())
- abort ();
+ FAILURE
if (__builtin_infd32 () * 2 != __builtin_infd32 ())
- abort ();
+ FAILURE
if (__builtin_infd64 () * -5 != -__builtin_infd32 ())
- abort ();
+ FAILURE
if (!__builtin_isinfd128 (__builtin_infd32 () / 4))
- abort ();
+ FAILURE
if (__builtin_infd64 () != __builtin_infd128 ())
- abort ();
+ FAILURE
if (!__builtin_isinfd64 (__builtin_infd128 ()))
- abort ();
+ FAILURE
if (__builtin_finited64 (__builtin_infd32 () * 4))
- abort ();
+ FAILURE
if (!__builtin_finited128 (9.999999E90DL - 1.E90dd))
- abort ();
+ FAILURE
if (__builtin_finited128 (__builtin_infd32 () *__builtin_infd128 ()))
- abort ();
+ FAILURE
if (__builtin_finited32 (__builtin_nand32 ("")))
- abort ();
-
- return 0;
+ FAILURE
+
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/keywords-pedantic.c b/gcc/testsuite/gcc.dg/dfp/keywords-pedantic.c
index 9492c798555..bca51066be3 100644
--- a/gcc/testsuite/gcc.dg/dfp/keywords-pedantic.c
+++ b/gcc/testsuite/gcc.dg/dfp/keywords-pedantic.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -pedantic" } */
+/* { dg-options "-pedantic" } */
/* Decimal float is a GCC extension. */
diff --git a/gcc/testsuite/gcc.dg/dfp/keywords-reserved.c b/gcc/testsuite/gcc.dg/dfp/keywords-reserved.c
index 4a042adf4c2..1117ae8d937 100644
--- a/gcc/testsuite/gcc.dg/dfp/keywords-reserved.c
+++ b/gcc/testsuite/gcc.dg/dfp/keywords-reserved.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
/* N1150 3: Decimal floating types.
C99 6.4.1(2): Keywords.
diff --git a/gcc/testsuite/gcc.dg/dfp/loop-index.c b/gcc/testsuite/gcc.dg/dfp/loop-index.c
index ff52189bc15..a944042a79b 100644
--- a/gcc/testsuite/gcc.dg/dfp/loop-index.c
+++ b/gcc/testsuite/gcc.dg/dfp/loop-index.c
@@ -1,9 +1,8 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.8.5.2: The for statement. */
#include <stdio.h>
#include <stdlib.h>
+#include "dfp-dbg.h"
void
f32 (void)
@@ -15,7 +14,7 @@ f32 (void)
i++;
if (i != 5)
- abort();
+ FAILURE
}
void
@@ -28,7 +27,7 @@ f64 (void)
i++;
if (i != 5)
- abort();
+ FAILURE
}
void
@@ -41,7 +40,7 @@ f128 (void)
i++;
if (i != 5)
- abort();
+ FAILURE
}
int
@@ -53,5 +52,6 @@ main ()
f64 ();
f128 ();
+ FINISH
return (0);
}
diff --git a/gcc/testsuite/gcc.dg/dfp/modes.c b/gcc/testsuite/gcc.dg/dfp/modes.c
index ff2382b1c75..09d4a15c264 100644
--- a/gcc/testsuite/gcc.dg/dfp/modes.c
+++ b/gcc/testsuite/gcc.dg/dfp/modes.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
typedef float decimal32 __attribute__ ((mode (SD)));
typedef float decimal64 __attribute__ ((mode (DD)));
diff --git a/gcc/testsuite/gcc.dg/dfp/nan-1.c b/gcc/testsuite/gcc.dg/dfp/nan-1.c
index 50972e0eb00..8961777c79b 100644
--- a/gcc/testsuite/gcc.dg/dfp/nan-1.c
+++ b/gcc/testsuite/gcc.dg/dfp/nan-1.c
@@ -1,108 +1,106 @@
-/* { dg-options "-std=gnu99" } */
-
/* N1150 4: Characteristics of decimal floating types (not explicit)
C99 5.2.4.2.2: Characteristics of floating types.
A few simple checks on arithmetic operations. */
-extern void abort (void);
+#include "dfp-dbg.h"
int main()
{
/* Some possibly non-obvious tests, but most logical
operations on NaN return false, including NaN == NaN. */
if (__builtin_nand32("") == __builtin_nand32(""))
- abort();
+ FAILURE
if (__builtin_nand64("") == __builtin_nand64(""))
- abort();
+ FAILURE
if (__builtin_nand128("") == __builtin_nand128(""))
- abort();
+ FAILURE
if (!(__builtin_nand32("") != __builtin_nand32("")))
- abort();
+ FAILURE
if (!(__builtin_nand64("") != __builtin_nand64("")))
- abort();
+ FAILURE
if (!(__builtin_nand128("") != __builtin_nand128("")))
- abort();
+ FAILURE
if (__builtin_nand32("") > __builtin_nand32(""))
- abort();
+ FAILURE
if (__builtin_nand64("") >= __builtin_nand64(""))
- abort();
+ FAILURE
if (__builtin_nand128("") < __builtin_nand128(""))
- abort();
+ FAILURE
if (-__builtin_nand128("") < +__builtin_nand128(""))
- abort();
+ FAILURE
/* 0.0/0.0 => NaN, but NaN != NaN. */
if (0.0df/0.0dl == __builtin_nand32(""))
- abort();
+ FAILURE
/* 0.0 * INF => NaN. */
if (!__builtin_isnand32 (0.0df * __builtin_infd32()))
- abort ();
+ FAILURE
if (!__builtin_isnand64 (0.0dd * __builtin_infd64()))
- abort ();
+ FAILURE
if (!__builtin_isnand128 (0.0dd * __builtin_infd128()))
- abort ();
+ FAILURE
/* INF - INF => NaN. */
if (!__builtin_isnand32 (__builtin_infd32() - __builtin_infd32()))
- abort ();
+ FAILURE
if (!__builtin_isnand64 (__builtin_infd64() - __builtin_infd64()))
- abort ();
+ FAILURE
if (!__builtin_isnand128 (__builtin_infd128() - __builtin_infd128()))
- abort ();
+ FAILURE
/* INF/INF => NaN. */
if (!__builtin_isnand32 (__builtin_infd32()/__builtin_infd32()) )
- abort ();
+ FAILURE
if (!__builtin_isnand64 (__builtin_infd64()/__builtin_infd64()) )
- abort ();
+ FAILURE
if (!__builtin_isnand128 (__builtin_infd128()/__builtin_infd128()) )
- abort ();
+ FAILURE
/* 0.0/0.0 => NaN, but NaN != NaN. */
if ((0.0dd/0.0df) == (0.0dd/0.0df))
- abort();
+ FAILURE
if (__builtin_nand32("") < __builtin_infd32())
- abort();
+ FAILURE
if (__builtin_nand32("") >= __builtin_infd32())
- abort();
+ FAILURE
/* Fixme: Add sqrtdf(-x.df) test when sqrt is supported. */
if (!__builtin_isnand32(__builtin_nand32("")))
- abort();
+ FAILURE
if (!__builtin_isnand64(__builtin_nand64("")))
- abort();
+ FAILURE
if (!__builtin_isnand128(__builtin_nand128("")))
- abort();
+ FAILURE
if (!__builtin_isnand128(8.0df * __builtin_nand128("")))
- abort();
+ FAILURE
if (!__builtin_isnand32(8.1dl - __builtin_nand32("")))
- abort();
+ FAILURE
if (!__builtin_isnand128(__builtin_nand64("") + __builtin_nand128("")))
- abort();
+ FAILURE
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/nan-2.c b/gcc/testsuite/gcc.dg/dfp/nan-2.c
index e8a663e74e1..ec9d18e1000 100644
--- a/gcc/testsuite/gcc.dg/dfp/nan-2.c
+++ b/gcc/testsuite/gcc.dg/dfp/nan-2.c
@@ -1,11 +1,9 @@
-/* { dg-options "-std=gnu99" } */
-
/* N1150 4: Characteristics of decimal floating types (not explicit)
C99 5.2.4.2.2: Characteristics of floating types.
A few simple checks on arithmetic operations. Based on nan-1.c with
the consideration of negative zero. */
-extern void abort (void);
+#include "dfp-dbg.h"
int main()
{
@@ -17,39 +15,39 @@ int main()
result. */
d32 = 123.45f;
if (d32/-0.0df != -__builtin_infd32())
- abort();
+ FAILURE
if (123.45df/-0.0df != -__builtin_infd32())
- abort();
+ FAILURE
d64 = 123.45f;
if (d64/-0.0dd != -__builtin_infd64())
- abort();
+ FAILURE
if (123.45dd/-0.0dd != -__builtin_infd64())
- abort();
+ FAILURE
d128 = 123.45f;
if (d128/-0.0dl != -__builtin_infd64())
- abort();
+ FAILURE
if (123.45dl/-0.0dl != -__builtin_infd128())
- abort();
+ FAILURE
d32 = 0.0df;
if (!__builtin_isnand32(-(d32/-0.0df)))
- abort();
+ FAILURE
if (!__builtin_isnand32(-(0.0df/-0.0df)))
- abort();
+ FAILURE
d64 = 0.0dd;
if (!__builtin_isnand64(-(d64/-0.0dd)))
- abort();
+ FAILURE
if (!__builtin_isnand64(-(0.0dd/-0.0dd)))
- abort();
+ FAILURE
d128 = 0.0dl;
if (!__builtin_isnand128(-(d128/-0.0dl)))
- abort();
+ FAILURE
if (!__builtin_isnand128(-(0.0dl/-0.0dl)))
- abort();
+ FAILURE
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/operator-arith-fold.c b/gcc/testsuite/gcc.dg/dfp/operator-arith-fold.c
index ad398d9b67c..65105899fb4 100644
--- a/gcc/testsuite/gcc.dg/dfp/operator-arith-fold.c
+++ b/gcc/testsuite/gcc.dg/dfp/operator-arith-fold.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O2" } */
+/* { dg-options "-O2" } */
/* C99 6.5.5: Multiplicative operators.
C99 6.5.6: Additive operators. */
diff --git a/gcc/testsuite/gcc.dg/dfp/operator-assignment.c b/gcc/testsuite/gcc.dg/dfp/operator-assignment.c
index 49d15d2382d..faadf1e8650 100644
--- a/gcc/testsuite/gcc.dg/dfp/operator-assignment.c
+++ b/gcc/testsuite/gcc.dg/dfp/operator-assignment.c
@@ -1,21 +1,9 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.5.16 Assignment operators.
Verify the compound assignment operator for decimal float types,
using it with other decimal float types, integers, and other binary
float types cast to decimal float types. */
-extern void abort (void);
-static int failcnt;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
#define OPERATE(OPRD1,OPRT,OPRD2,RLT) \
if (( OPRD1 OPRT OPRD2 )!= RLT) \
@@ -64,8 +52,5 @@ main ()
DECIMAL_COMPOUND_ASSIGNMENT(64, d64);
DECIMAL_COMPOUND_ASSIGNMENT(128, d128);
- if (failcnt != 0)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/operator-bitwise.c b/gcc/testsuite/gcc.dg/dfp/operator-bitwise.c
index 8523cb91a5f..f895a970578 100644
--- a/gcc/testsuite/gcc.dg/dfp/operator-bitwise.c
+++ b/gcc/testsuite/gcc.dg/dfp/operator-bitwise.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
/* C99 6.5.10: Bitwise AND operator.
C99 6.5.11: Bitwise exclusive OR operator.
@@ -7,8 +6,6 @@
Test that these operators do not accept decimal float operands. */
-extern void abort (void);
-
#define OPERATE(OPRD1,OPRT,OPRD2) \
do \
{ \
diff --git a/gcc/testsuite/gcc.dg/dfp/operator-comma.c b/gcc/testsuite/gcc.dg/dfp/operator-comma.c
index 904f9b3a676..be6bf6f8cd1 100644
--- a/gcc/testsuite/gcc.dg/dfp/operator-comma.c
+++ b/gcc/testsuite/gcc.dg/dfp/operator-comma.c
@@ -1,19 +1,9 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* C99 6.5.17: Comma operator.
Test with decimal float operands. */
-extern void abort (void);
-static int failcnt = 0;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
volatile _Decimal32 d32a, d32b, d32c;
volatile _Decimal64 d64a, d64b, d64c;
@@ -53,5 +43,5 @@ main ()
if (d64a != 12.0dd)
FAILURE;
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/operator-cond.c b/gcc/testsuite/gcc.dg/dfp/operator-cond.c
index 5230134f637..140dd95074a 100644
--- a/gcc/testsuite/gcc.dg/dfp/operator-cond.c
+++ b/gcc/testsuite/gcc.dg/dfp/operator-cond.c
@@ -1,19 +1,9 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* C99 6.5.15 Conditional operator.
Test with decimal float operands. */
-extern void abort (void);
-static int failcnt = 0;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
volatile _Decimal32 d32a, d32b, d32c;
volatile _Decimal64 d64a, d64b, d64c;
@@ -63,5 +53,5 @@ main ()
if (d128a != d128b)
FAILURE
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/operator-logical.c b/gcc/testsuite/gcc.dg/dfp/operator-logical.c
index 90a94b078fa..c784468c77a 100644
--- a/gcc/testsuite/gcc.dg/dfp/operator-logical.c
+++ b/gcc/testsuite/gcc.dg/dfp/operator-logical.c
@@ -1,16 +1,14 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 Logical AND operator.
C99 Logical OR operator.
Test with decimal float operands. */
-extern void abort (void);
+#include "dfp-dbg.h"
#define OPERATE(OPRD1,OPRT,OPRD2,RLT) \
do \
{ \
if (( (OPRD1) OPRT (OPRD2) )!= RLT) \
- abort (); \
+ __builtin_abort (); \
} while (0)
#define DECIMAL_LOGICAL_OR(OPRD) \
diff --git a/gcc/testsuite/gcc.dg/dfp/operator-unary.c b/gcc/testsuite/gcc.dg/dfp/operator-unary.c
index bcf50683c0c..65f0be074d9 100644
--- a/gcc/testsuite/gcc.dg/dfp/operator-unary.c
+++ b/gcc/testsuite/gcc.dg/dfp/operator-unary.c
@@ -1,23 +1,21 @@
-/* { dg-options "-std=gnu99" } */
-
/* C99 6.5.3 Unary operators. */
-extern void abort (void);
+#include "dfp-dbg.h"
#define AUTO_INCREASE_DECREASE(TYPE,SUFFIX) \
do \
{ \
- _Decimal##TYPE in_de_d##TYPE = 0.0##SUFFIX; \
- if (in_de_d##TYPE++) abort (); \
- if (--in_de_d##TYPE) abort (); \
- if (++in_de_d##TYPE == 0.0##SUFFIX) abort (); \
- if (in_de_d##TYPE-- == 0.0##SUFFIX) abort (); \
+ _Decimal##TYPE in_de_d##TYPE = 0.0##SUFFIX; \
+ if (in_de_d##TYPE++) FAILURE \
+ if (--in_de_d##TYPE) FAILURE \
+ if (++in_de_d##TYPE == 0.0##SUFFIX) FAILURE \
+ if (in_de_d##TYPE-- == 0.0##SUFFIX) FAILURE \
} while(0)
#define UNARY_OPERATOR(TYPE,SUFFIX) \
do \
{ \
- _Decimal##TYPE unary_d##TYPE = 1.0##SUFFIX; \
+ _Decimal##TYPE unary_d##TYPE = 1.0##SUFFIX; \
_Decimal##TYPE* unary_dp##TYPE; \
/* & operator. */ \
unary_dp##TYPE = &(unary_d##TYPE); \
@@ -25,11 +23,11 @@ do \
unary_d##TYPE = *(unary_dp##TYPE); \
/* - operator. */ \
unary_d##TYPE = -unary_d##TYPE; \
- if (unary_d##TYPE != -1.0##SUFFIX) abort (); \
+ if (unary_d##TYPE != -1.0##SUFFIX) FAILURE \
/* + operator. */ \
unary_d##TYPE = +unary_d##TYPE; \
- if (unary_d##TYPE != -1.0##SUFFIX) abort (); \
- if (!unary_d##TYPE) abort (); /*! operator. */ \
+ if (unary_d##TYPE != -1.0##SUFFIX) FAILURE \
+ if (!unary_d##TYPE) FAILURE /*! operator. */ \
} while (0)
int
@@ -46,9 +44,9 @@ main ()
UNARY_OPERATOR(128, DL);
/* C99 6.5.3 Unary operators for zero values. */
- if (- +0.df != -0.df) abort ();
- if (+ -0.df != -0.df) abort ();
- if (- -0.df != +0.df) abort ();
+ if (- +0.df != -0.df) FAILURE
+ if (+ -0.df != -0.df) FAILURE
+ if (- -0.df != +0.df) FAILURE
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/pr31344.c b/gcc/testsuite/gcc.dg/dfp/pr31344.c
index de76a72f937..0f5e21ecdff 100644
--- a/gcc/testsuite/gcc.dg/dfp/pr31344.c
+++ b/gcc/testsuite/gcc.dg/dfp/pr31344.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-O -std=gnu99 -mtune=i386" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
-/* { dg-options "-O -std=gnu99" } */
+/* { dg-options "-O -mtune=i386" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-O" } */
typedef struct
{
diff --git a/gcc/testsuite/gcc.dg/dfp/pr31385.c b/gcc/testsuite/gcc.dg/dfp/pr31385.c
index 63a23c4bb75..72f5f935f09 100644
--- a/gcc/testsuite/gcc.dg/dfp/pr31385.c
+++ b/gcc/testsuite/gcc.dg/dfp/pr31385.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -O2" } */
+/* { dg-options "-O2" } */
typedef _Decimal32 fp_t;
diff --git a/gcc/testsuite/gcc.dg/dfp/pr33466.c b/gcc/testsuite/gcc.dg/dfp/pr33466.c
index c8ac1116558..e1cd76b74ff 100644
--- a/gcc/testsuite/gcc.dg/dfp/pr33466.c
+++ b/gcc/testsuite/gcc.dg/dfp/pr33466.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
/* The suffix for a decimal float constant must use a single case.
diff --git a/gcc/testsuite/gcc.dg/dfp/pr35620.c b/gcc/testsuite/gcc.dg/dfp/pr35620.c
index 90f9500c384..08137cfb6d9 100644
--- a/gcc/testsuite/gcc.dg/dfp/pr35620.c
+++ b/gcc/testsuite/gcc.dg/dfp/pr35620.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -O2" } */
+/* { dg-options "-O2" } */
extern void foo (_Decimal32);
_Decimal32 *p;
diff --git a/gcc/testsuite/gcc.dg/dfp/pr36800.c b/gcc/testsuite/gcc.dg/dfp/pr36800.c
index 5b899cf0e7f..76ff28c9815 100644
--- a/gcc/testsuite/gcc.dg/dfp/pr36800.c
+++ b/gcc/testsuite/gcc.dg/dfp/pr36800.c
@@ -1,26 +1,25 @@
/* { dg-do run } */
-/* { dg-options "-std=gnu99" } */
#include <stdarg.h>
-extern void abort (void);
+#include "dfp-dbg.h"
void
f (int a, ...)
{
va_list ap;
if (a != 0)
- abort ();
+ FAILURE
va_start (ap, a);
if (va_arg (ap, _Decimal128) != 1.2DL)
- abort ();
+ FAILURE
if (va_arg (ap, _Decimal128) != 2.34DL)
- abort ();
+ FAILURE
if (va_arg (ap, _Decimal128) != 3.456DL)
- abort ();
+ FAILURE
if (va_arg (ap, _Decimal128) != 4.567DL)
- abort ();
+ FAILURE
if (va_arg (ap, double) != 5.125)
- abort ();
+ FAILURE
va_end (ap);
}
@@ -28,5 +27,6 @@ int
main (void)
{
f (0, 1.2DL, 2.34DL, 3.456DL, 4.567DL, 5.125);
- return 0;
+
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/pr37435.c b/gcc/testsuite/gcc.dg/dfp/pr37435.c
index 98acc9c118b..867fdd26bc4 100644
--- a/gcc/testsuite/gcc.dg/dfp/pr37435.c
+++ b/gcc/testsuite/gcc.dg/dfp/pr37435.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target fpic } } */
-/* { dg-options "-std=gnu99 -O2 -fPIC" } */
+/* { dg-options "-O2 -fPIC" } */
volatile _Decimal32 d;
volatile int i;
diff --git a/gcc/testsuite/gcc.dg/dfp/pr39034.c b/gcc/testsuite/gcc.dg/dfp/pr39034.c
index 6a261c9ddc2..2a7eedbdbe2 100644
--- a/gcc/testsuite/gcc.dg/dfp/pr39034.c
+++ b/gcc/testsuite/gcc.dg/dfp/pr39034.c
@@ -1,19 +1,10 @@
/* { dg-do run } */
-/* { dg-options "-std=gnu99 -O" } */
+/* { dg-options "-O" } */
/* DFP TR 24732 == WG14 / N1176, N1312 */
/* Based on a test from Fred Tydeman. */
-extern void abort (void);
-int failures = 0;
-
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE(MSG) { printf ("line %d: %s\n", __LINE__, MSG); failures++; }
-#else
-#define FAILURE(MSG) failures++;
-#endif
-
+#include "dfp-dbg.h"
/* Test runtime computations. */
@@ -25,9 +16,9 @@ runtime32 (void)
_Decimal32 d32 = (float)((v1/v2-v3) - (v4/v5-v6));
if (b32)
- FAILURE ("runtime: b32 should be zero")
+ FAILURE
if (d32)
- FAILURE ("runtime: d32 should be zero")
+ FAILURE
}
void
@@ -38,9 +29,9 @@ runtime64 (void)
_Decimal64 d64 = (double)((v1/v2-v3) - (v4/v5-v6));
if (b64)
- FAILURE ("runtime: b64 should be zero")
+ FAILURE
if (d64)
- FAILURE ("runtime: d64 should be zero")
+ FAILURE
}
void
@@ -52,9 +43,9 @@ runtime128 (void)
_Decimal128 d128 = (long double)((v1/v2-v3) - (v4/v5-v6));
if (b128)
- FAILURE ("runtime: b128 should be zero")
+ FAILURE
if (d128)
- FAILURE ("runtime: d128 should be zero")
+ FAILURE
}
/* Test constant folding. */
@@ -66,9 +57,9 @@ fold32 (void)
_Decimal32 b32 = (float)((28.f/3.f-9.f) - (31.f/3.f-10.f));
if (b32)
- FAILURE ("fold: b32 should be zero")
+ FAILURE
if (d32)
- FAILURE ("fold: d32 should be zero")
+ FAILURE
}
void
@@ -78,9 +69,9 @@ fold64 (void)
_Decimal64 d64 = (double)((28./3.-9.) - (31./3.-10.));
if (b64)
- FAILURE ("fold: b64 should be zero")
+ FAILURE
if (d64)
- FAILURE ("fold: d64 should be zero")
+ FAILURE
}
void
@@ -90,9 +81,9 @@ fold128 (void)
_Decimal128 d128 = (long double)((28./3.-9.) - (31./3.-10.));
if (b128)
- FAILURE ("fold: b128 should be zero")
+ FAILURE
if (d128)
- FAILURE ("fold: d128 should be zero")
+ FAILURE
}
int
@@ -105,7 +96,5 @@ main ()
fold64 ();
fold128 ();
- if (failures != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/pr39035.c b/gcc/testsuite/gcc.dg/dfp/pr39035.c
index 2d44e06a432..2c9e8b386ed 100644
--- a/gcc/testsuite/gcc.dg/dfp/pr39035.c
+++ b/gcc/testsuite/gcc.dg/dfp/pr39035.c
@@ -1,18 +1,10 @@
/* { dg-do run } */
-/* { dg-options "-std=gnu99 -O" } */
+/* { dg-options "-O" } */
/* DFP TR 24732 == WG14 / N1176, N1312 */
/* Based on a test from Fred Tydeman. */
-extern void abort (void);
-int failures = 0;
-
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE(MSG) { printf ("line %d: %s\n", __LINE__, MSG); failures++; }
-#else
-#define FAILURE(MSG) failures++;
-#endif
+#include "dfp-dbg.h"
/* Test runtime computations. */
@@ -22,7 +14,7 @@ runtime32 (void)
volatile _Decimal32 d;
d = 0.0DF;
if (d)
- FAILURE ("0.0DF should be zero")
+ FAILURE
}
void
@@ -31,7 +23,7 @@ runtime64 (void)
volatile _Decimal64 d;
d = 0.0DD;
if (d)
- FAILURE ("0.0DD should be zero")
+ FAILURE
}
void
@@ -40,28 +32,28 @@ runtime128 (void)
volatile _Decimal128 d;
d = 0.0DL;
if (d)
- FAILURE ("0.0DL should be zero")
+ FAILURE
}
void
fold32 (void)
{
if (0.0DF)
- FAILURE ("0.0DF should be zero")
+ FAILURE
}
void
fold64 (void)
{
if (0.0DD)
- FAILURE ("0.0DD should be zero")
+ FAILURE
}
void
fold128 (void)
{
if (0.0DL)
- FAILURE ("0.0DL should be zero")
+ FAILURE
}
int
@@ -75,7 +67,5 @@ main(void)
fold64 ();
fold128 ();
- if (failures != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/pr39902.c b/gcc/testsuite/gcc.dg/dfp/pr39902.c
index 120610c3779..847069966e3 100644
--- a/gcc/testsuite/gcc.dg/dfp/pr39902.c
+++ b/gcc/testsuite/gcc.dg/dfp/pr39902.c
@@ -1,18 +1,8 @@
-/* { dg-options "--std=gnu99" } */
-
/* Check that optimizations like (x * 1) to x, or (x * -1) to -x,
do not apply to decimal float computations where trailing zeroes
are significant. */
-extern void abort (void);
-int failcnt;
-
-#ifdef DBG
-extern int printf (const char *, ...);
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
#define COMPARE32(A,B) \
A.i == B.i
@@ -232,8 +222,5 @@ main (void)
doit64 ();
doit128 ();
- if (failcnt != 0)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/pr39986.c b/gcc/testsuite/gcc.dg/dfp/pr39986.c
index 53bda3c824a..04ff2b623e0 100644
--- a/gcc/testsuite/gcc.dg/dfp/pr39986.c
+++ b/gcc/testsuite/gcc.dg/dfp/pr39986.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
/* Check that the compiler generates the correct decimal float constants. */
diff --git a/gcc/testsuite/gcc.dg/dfp/pr41049.c b/gcc/testsuite/gcc.dg/dfp/pr41049.c
new file mode 100644
index 00000000000..6187481eca1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/pr41049.c
@@ -0,0 +1,562 @@
+/* { dg-options "-std=gnu99" } */
+
+/* The preferred exponent of the result of a conversion from an
+ integral type to a decimal float type is zero. A conversion at
+ either compile time or runtime should not change the number of
+ trailing zeroes. */
+
+#include "dfp-dbg.h"
+
+#define PASTE2(A,B) A ## B
+#define PASTE(A,B) PASTE2(A,B)
+
+#define TESTVAL_NEG(VAL,SUF,SIZE) \
+ x = PASTE(PASTE(VAL,.),SUF); \
+ si = VAL; \
+ sll = PASTE(VAL,LL); \
+ a = si; \
+ b = sll; \
+ c = VAL; \
+ d = PASTE(VAL,LL); \
+ if ((__builtin_memcmp ((void *)&x, (void *)&a, SIZE) != 0) \
+ || (__builtin_memcmp ((void *)&x, (void *)&b,SIZE) != 0) \
+ || (__builtin_memcmp ((void *)&x, (void *)&c,SIZE) != 0) \
+ || (__builtin_memcmp ((void *)&x, (void *)&d,SIZE) != 0)) \
+ FAILURE
+
+#define TESTVAL_NEG_BIG(VAL,SUF,SIZE) \
+ x = PASTE(PASTE(VAL,.),SUF); \
+ sll = PASTE(VAL,LL); \
+ a = sll; \
+ b = PASTE(VAL,LL); \
+ if ((__builtin_memcmp ((void *)&x, (void *)&a, SIZE) != 0) \
+ || (__builtin_memcmp ((void *)&x, (void *)&b,SIZE) != 0)) \
+ FAILURE
+
+#define TESTVAL_NONNEG(VAL,SUF,SIZE) \
+ x = PASTE(PASTE(VAL,.),SUF); \
+ si = VAL; \
+ ui = VAL; \
+ sll = PASTE(VAL,LL); \
+ ull = PASTE(VAL,ULL); \
+ a = si; \
+ b = sll; \
+ c = ui; \
+ d = ull; \
+ e = VAL; \
+ f = VAL; \
+ g = PASTE(VAL,LL); \
+ h = PASTE(VAL,ULL); \
+ if ((__builtin_memcmp ((void *)&x, (void *)&a, SIZE) != 0) \
+ || (__builtin_memcmp ((void *)&x, (void *)&b,SIZE) != 0) \
+ || (__builtin_memcmp ((void *)&x, (void *)&c,SIZE) != 0) \
+ || (__builtin_memcmp ((void *)&x, (void *)&d,SIZE) != 0) \
+ || (__builtin_memcmp ((void *)&x, (void *)&e,SIZE) != 0) \
+ || (__builtin_memcmp ((void *)&x, (void *)&f,SIZE) != 0) \
+ || (__builtin_memcmp ((void *)&x, (void *)&g,SIZE) != 0) \
+ || (__builtin_memcmp ((void *)&x, (void *)&h,SIZE) != 0)) \
+ FAILURE
+
+#define TESTVAL_NONNEG_BIG(VAL,SUF,SIZE) \
+ x = PASTE(PASTE(VAL,.),SUF); \
+ sll = PASTE(VAL,LL); \
+ ull = PASTE(VAL,ULL); \
+ b = sll; \
+ d = ull; \
+ f = PASTE(VAL,LL); \
+ g = PASTE(VAL,ULL); \
+ if ((__builtin_memcmp ((void *)&x, (void *)&b, SIZE) != 0) \
+ || (__builtin_memcmp ((void *)&d, (void *)&d,SIZE) != 0) \
+ || (__builtin_memcmp ((void *)&f, (void *)&d,SIZE) != 0) \
+ || (__builtin_memcmp ((void *)&g, (void *)&d,SIZE) != 0)) \
+ FAILURE
+
+#undef SUFFIX
+#define SUFFIX DF
+#undef TYPE
+#define TYPE _Decimal32
+
+void
+zeroes_32 (void)
+{
+ volatile TYPE x, a, b, c, d, e, f, g, h;
+ volatile int si;
+ volatile unsigned int ui;
+ volatile long long sll;
+ volatile unsigned long long ull;
+
+ TESTVAL_NONNEG (0, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (1, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (5, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (9, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (50, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (90, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (100, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (500, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (900, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (1000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (5000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (9000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (50000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (90000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (100000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (500000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (900000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (1000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (5000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (9000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (50000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (90000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (100000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (500000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (900000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (1000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (5000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (9000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (50000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (90000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (100000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (500000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (900000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (1000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (5000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (9000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (50000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (90000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (100000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (500000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (900000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (1000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (5000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (9000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (50000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (90000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (100000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (500000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (900000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (1000000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (5000000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (9000000000000000000, SUFFIX, sizeof (TYPE));
+
+ TESTVAL_NEG (0, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-1, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-5, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-9, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-50, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-90, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-100, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-500, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-900, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-1000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-5000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-9000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-50000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-90000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-100000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-500000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-900000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-1000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-5000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-9000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-50000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-90000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-100000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-500000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-900000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-1000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-5000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-9000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-50000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-90000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-100000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-500000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-900000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-1000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-5000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-9000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-50000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-90000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-100000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-500000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-900000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-1000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-5000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-9000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-50000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-90000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-100000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-500000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-900000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-1000000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-5000000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-9000000000000000000, SUFFIX, sizeof (TYPE));
+}
+
+void
+round_32 (void)
+{
+ volatile TYPE x, a, b, c, d, e, f, g, h;
+ volatile int si;
+ volatile unsigned int ui;
+ volatile long long sll;
+ volatile unsigned long long ull;
+
+ TESTVAL_NONNEG (10000049, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000050, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000051, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000001, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000002, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000003, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000004, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (100000049, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (100000051, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000006, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000007, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000008, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000009, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000010, SUFFIX, sizeof (TYPE));
+
+ TESTVAL_NEG (-10000049, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000050, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000051, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000001, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000002, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000003, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000004, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-100000049, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-100000051, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000006, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000007, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000008, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000009, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000010, SUFFIX, sizeof (TYPE));
+}
+
+#undef SUFFIX
+#define SUFFIX DD
+#undef TYPE
+#define TYPE _Decimal64
+
+void
+zeroes_64 (void)
+{
+ volatile TYPE x, a, b, c, d, e, f, g, h;
+ volatile int si;
+ volatile unsigned int ui;
+ volatile long long sll;
+ volatile unsigned long long ull;
+
+ TESTVAL_NONNEG (0, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (1, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (5, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (9, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (50, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (90, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (100, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (500, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (900, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (1000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (5000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (9000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (50000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (90000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (100000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (500000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (900000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (1000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (5000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (9000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (50000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (90000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (100000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (500000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (900000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (1000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (5000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (9000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (50000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (90000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (100000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (500000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (900000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (1000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (5000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (9000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (50000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (90000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (100000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (500000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (900000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (1000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (5000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (9000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (50000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (90000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (100000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (500000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (900000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (1000000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (5000000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (9000000000000000000, SUFFIX, sizeof (TYPE));
+
+ TESTVAL_NEG (0, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-1, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-5, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-9, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-50, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-90, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-100, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-500, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-900, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-1000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-5000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-9000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-50000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-90000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-100000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-500000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-900000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-1000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-5000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-9000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-50000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-90000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-100000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-500000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-900000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-1000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-5000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-9000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-50000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-90000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-100000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-500000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-900000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-1000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-5000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-9000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-50000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-90000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-100000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-500000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-900000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-1000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-5000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-9000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-50000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-90000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-100000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-500000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-900000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-1000000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-5000000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-9000000000000000000, SUFFIX, sizeof (TYPE));
+}
+
+void
+round_64 (void)
+{
+ volatile TYPE x, a, b, c, d, e, f, g, h;
+ volatile int si;
+ volatile unsigned int ui;
+ volatile long long sll;
+ volatile unsigned long long ull;
+
+ TESTVAL_NONNEG_BIG (10000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000001, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000002, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000003, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000004, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (100000000000000049, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (100000000000000051, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000006, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000007, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000008, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000009, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000010, SUFFIX, sizeof (TYPE));
+
+ TESTVAL_NEG_BIG (-10000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000001, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000002, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000003, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000004, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-100000000000000049, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-100000000000000051, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000006, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000007, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000008, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000009, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000010, SUFFIX, sizeof (TYPE));
+}
+
+#undef SUFFIX
+#define SUFFIX DL
+#undef TYPE
+#define TYPE _Decimal128
+
+void
+zeroes_128 (void)
+{
+ volatile TYPE x, a, b, c, d, e, f, g, h;
+ volatile int si;
+ volatile unsigned int ui;
+ volatile long long sll;
+ volatile unsigned long long ull;
+
+ TESTVAL_NONNEG (0, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (1, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (5, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (9, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (50, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (90, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (100, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (500, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (900, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (1000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (5000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (9000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (50000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (90000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (100000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (500000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (900000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (1000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (5000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (9000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (10000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (50000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (90000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (100000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (500000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (900000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG (1000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (5000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (9000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (50000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (90000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (100000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (500000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (900000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (1000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (5000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (9000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (50000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (90000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (100000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (500000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (900000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (1000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (5000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (9000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (10000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (50000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (90000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (100000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (500000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (900000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (1000000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (5000000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NONNEG_BIG (9000000000000000000, SUFFIX, sizeof (TYPE));
+
+ TESTVAL_NEG (0, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-1, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-5, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-9, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-50, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-90, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-100, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-500, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-900, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-1000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-5000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-9000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-50000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-90000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-100000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-500000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-900000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-1000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-5000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-9000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-10000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-50000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-90000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-100000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-500000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-900000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG (-1000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-5000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-9000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-50000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-90000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-100000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-500000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-900000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-1000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-5000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-9000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-50000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-90000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-100000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-500000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-900000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-1000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-5000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-9000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-10000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-50000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-90000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-100000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-500000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-900000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-1000000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-5000000000000000000, SUFFIX, sizeof (TYPE));
+ TESTVAL_NEG_BIG (-9000000000000000000, SUFFIX, sizeof (TYPE));
+}
+
+
+int
+main ()
+{
+ zeroes_32 ();
+ zeroes_64 ();
+ zeroes_128 ();
+ round_32 ();
+ round_64 ();
+
+ FINISH
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-1.c b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-1.c
index 79fabf34484..62d85b6d349 100644
--- a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-1.c
+++ b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -Wall" } */
+/* { dg-options "-Wall" } */
/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma.
C99 6.4.4.2a (New).
diff --git a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-2.c b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-2.c
index 212748c6c78..8bc49f77106 100644
--- a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-2.c
+++ b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -Wall" } */
+/* { dg-options "-Wall" } */
/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma.
C99 6.4.4.2a (New).
diff --git a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-3.c b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-3.c
index b9286aac11a..19599867035 100644
--- a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-3.c
+++ b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -Wall" } */
+/* { dg-options "-Wall" } */
/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma.
C99 6.4.4.2a (New). */
diff --git a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-4.c b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-4.c
index 86cec1dbd45..af0398daf79 100644
--- a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-4.c
+++ b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-4.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma.
C99 6.4.4.2a (New).
diff --git a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-7.c b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-7.c
index 7533ee7f0de..55e0d661c03 100644
--- a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-7.c
+++ b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -Wall" } */
+/* { dg-options "-Wall" } */
/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma.
C99 6.4.4.2a (New).
diff --git a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-8.c b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-8.c
index 5dbbda5b8f2..39d38c1d8f0 100644
--- a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-8.c
+++ b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-8.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -Wall" } */
+/* { dg-options "-Wall" } */
/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma.
C99 6.4.4.2a (New).
diff --git a/gcc/testsuite/gcc.dg/dfp/signbit-1.c b/gcc/testsuite/gcc.dg/dfp/signbit-1.c
index cde28f9ba84..d83d2a48ed7 100644
--- a/gcc/testsuite/gcc.dg/dfp/signbit-1.c
+++ b/gcc/testsuite/gcc.dg/dfp/signbit-1.c
@@ -1,16 +1,8 @@
-/* { dg-options "-O0 -std=gnu99" } */
+/* { dg-options "-O0" } */
/* Decimal float versions of __builtin_signbit. */
-extern void abort (void);
-int failures;
-
-#ifdef DBG
-extern int printf (const char *, ...);
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failures++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
#define CHECK32(D,I) \
if ((__builtin_signbitd32 (D) != 0) != I) FAILURE
@@ -44,7 +36,5 @@ main ()
td = 0.0dl; CHECK128 (td, 0)
td = -0.0dl; CHECK128 (td, 1)
- if (failures != 0)
- abort ();
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/signbit-2.c b/gcc/testsuite/gcc.dg/dfp/signbit-2.c
index 6f9a2276b8a..e7d3f0405e7 100644
--- a/gcc/testsuite/gcc.dg/dfp/signbit-2.c
+++ b/gcc/testsuite/gcc.dg/dfp/signbit-2.c
@@ -1,9 +1,9 @@
-/* { dg-options "-O0 -std=gnu99" } */
+/* { dg-options "-O0" } */
/* Check that the compiler uses builtins for signbit; if not the link
will fail because library functions are in libm. */
-extern void abort (void);
+#include "dfp-dbg.h"
volatile _Decimal32 sd = 2.3df;
volatile _Decimal64 dd = -4.5dd;
@@ -22,12 +22,12 @@ extern int signbitd128 (_Decimal128);
int
main ()
{
- if (signbitf (f) != 0) abort ();
- if (signbit (d) == 0) abort ();
- if (signbitl (ld) != 0) abort ();
- if (signbitd32 (sd) != 0) abort ();
- if (signbitd64 (dd) == 0) abort ();
- if (signbitd128 (tf) != 0) abort ();
+ if (signbitf (f) != 0) FAILURE
+ if (signbit (d) == 0) FAILURE
+ if (signbitl (ld) != 0) FAILURE
+ if (signbitd32 (sd) != 0) FAILURE
+ if (signbitd64 (dd) == 0) FAILURE
+ if (signbitd128 (tf) != 0) FAILURE
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/struct-layout-1.c b/gcc/testsuite/gcc.dg/dfp/struct-layout-1.c
index 9e54e48c726..2a9d7304fd1 100644
--- a/gcc/testsuite/gcc.dg/dfp/struct-layout-1.c
+++ b/gcc/testsuite/gcc.dg/dfp/struct-layout-1.c
@@ -1,8 +1,5 @@
-/* { dg-options "-std=gnu99" } */
-
#include <stdarg.h>
-
-extern void abort (void);
+#include "dfp-dbg.h"
struct S1
{
@@ -39,20 +36,6 @@ struct S5
} a;
};
-static int failcnt = 0;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE do \
-{ printf ("failed at line %d\n", __LINE__); \
- failcnt++; \
-}while(0)
-#else
-#define FAILURE abort ()
-#endif
-
int check_var (int z, ...)
{
long long result;
@@ -84,8 +67,5 @@ int main ()
if (check_var (2, s5, 2LL) == 0)
FAILURE;
- if (failcnt)
- abort ();
-
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/typespec.c b/gcc/testsuite/gcc.dg/dfp/typespec.c
index c7fc343ec43..a4545d5d921 100644
--- a/gcc/testsuite/gcc.dg/dfp/typespec.c
+++ b/gcc/testsuite/gcc.dg/dfp/typespec.c
@@ -1,7 +1,6 @@
/* Test for valid and invalid combinations of type specifiers.
Based off gcc.dg/test-spec-1.c */
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
typedef char type;
void _Decimal32 *x0; /* { dg-error "" "void _Decimal32" } */
diff --git a/gcc/testsuite/gcc.dg/dfp/union-init.c b/gcc/testsuite/gcc.dg/dfp/union-init.c
index fede76ba328..6896ece99b2 100644
--- a/gcc/testsuite/gcc.dg/dfp/union-init.c
+++ b/gcc/testsuite/gcc.dg/dfp/union-init.c
@@ -1,8 +1,6 @@
-/* { dg-options "-std=gnu99" } */
-
/* Cast to union is a GNU C extension. */
-extern void abort (void);
+#include "dfp-dbg.h"
union u
{
@@ -30,10 +28,10 @@ int main ()
double d;
if (u1.d128 != 0.0dl)
- abort ();
+ FAILURE
if (u2.d128 != 4.2dl)
- abort ();
+ FAILURE
/* cast decimal floating point to union type. */
d128 = 1.23dl;
@@ -42,19 +40,19 @@ int main ()
u4 = (union u) d128;
if (u4.d128 != 1.23dl)
- abort ();
+ FAILURE
u4 = (union u) d;
if (u4.d != 3.25)
- abort ();
+ FAILURE
n1 = (union n) d64;
if (n1.d64 != 4.56dd)
- abort ();
+ FAILURE
n1 = (union n)d;
if (n1.d != 3.25)
- abort ();
+ FAILURE
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad-2.c b/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad-2.c
index 4693abc90d9..7bd0f64f136 100644
--- a/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad-2.c
+++ b/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad-2.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
/* This used to result in an ICE. */
diff --git a/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad.c b/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad.c
index e4033ca50f4..e14c7b20a12 100644
--- a/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad.c
+++ b/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-bad.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
/* N1150 5.4: Usual arithmetic conversions.
C99 6.3.1.8[1] (New).
diff --git a/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-const.c b/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-const.c
index 3f06e4753ff..0d39a24bb65 100644
--- a/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-const.c
+++ b/gcc/testsuite/gcc.dg/dfp/usual-arith-conv-const.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-options "-std=gnu99" } */
/* Test various conversions involving decimal floating types. */
diff --git a/gcc/testsuite/gcc.dg/dfp/usual-arith-conv.c b/gcc/testsuite/gcc.dg/dfp/usual-arith-conv.c
index 584058b8cc4..baff06bc175 100644
--- a/gcc/testsuite/gcc.dg/dfp/usual-arith-conv.c
+++ b/gcc/testsuite/gcc.dg/dfp/usual-arith-conv.c
@@ -1,4 +1,4 @@
-/* { dg-options "-std=gnu99 -O0" } */
+/* { dg-options "-O0" } */
/* N1150 5.4: Usual arithmetic conversions.
C99 6.3.1.8[1] (New).
@@ -6,17 +6,7 @@
Test arithmetic operators with different decimal float types, and
between decimal float types and integer types. */
-extern void abort (void);
-static int failcnt = 0;
-
-/* Support compiling the test to report individual failures; default is
- to abort as soon as a check fails. */
-#ifdef DBG
-#include <stdio.h>
-#define FAILURE { printf ("failed at line %d\n", __LINE__); failcnt++; }
-#else
-#define FAILURE abort ();
-#endif
+#include "dfp-dbg.h"
volatile _Decimal32 d32a, d32b, d32c;
volatile _Decimal64 d64a, d64b, d64c;
@@ -123,5 +113,5 @@ main ()
if (d128a != d128c / 2.0dl)
FAILURE
- return 0;
+ FINISH
}
diff --git a/gcc/testsuite/gcc.dg/dfp/wtr-conversion-1.c b/gcc/testsuite/gcc.dg/dfp/wtr-conversion-1.c
index 0994c65783e..2b50fe6a56e 100644
--- a/gcc/testsuite/gcc.dg/dfp/wtr-conversion-1.c
+++ b/gcc/testsuite/gcc.dg/dfp/wtr-conversion-1.c
@@ -3,7 +3,7 @@
Based on gcc.dg/wtr-conversion-1.c */
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -Wtraditional" } */
+/* { dg-options "-Wtraditional" } */
extern void foo_i (int);
extern void foo_f (float);
diff --git a/gcc/testsuite/gcc.dg/guality/guality.exp b/gcc/testsuite/gcc.dg/guality/guality.exp
index b151c2e0772..15a6e5e6342 100644
--- a/gcc/testsuite/gcc.dg/guality/guality.exp
+++ b/gcc/testsuite/gcc.dg/guality/guality.exp
@@ -2,6 +2,30 @@
load_lib gcc-dg.exp
+proc check_guality {args} {
+ set result [eval check_compile guality_check executable $args "-g -O0"]
+ set lines [lindex $result 0]
+ set output [lindex $result 1]
+ set ret 0
+ if {[string match "" $lines]} {
+ set execout [gcc_load "./$output"]
+ set ret [string match "*1 PASS, 0 FAIL, 0 UNRESOLVED*" $execout]
+ }
+ remote_file build delete $output
+ return $ret
+}
+
dg-init
-gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] ""
+
+if {[check_guality "
+ #include \"$srcdir/$subdir/guality.h\"
+ volatile long int varl = 6;
+ int main (int argc, char *argv\[\])
+ {
+ GUALCHKVAL (varl);
+ return 0;
+ }
+"]} {
+ gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] ""
+}
dg-finish
diff --git a/gcc/testsuite/gcc.dg/guality/guality.h b/gcc/testsuite/gcc.dg/guality/guality.h
index 6025da8b028..eec0ab6bedf 100644
--- a/gcc/testsuite/gcc.dg/guality/guality.h
+++ b/gcc/testsuite/gcc.dg/guality/guality.h
@@ -21,9 +21,7 @@ along with GCC; see the file COPYING3. If not see
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
+#include <stdint.h>
/* This is a first cut at checking that debug information matches
run-time. The idea is to annotate programs with GUALCHK* macros
@@ -56,8 +54,20 @@ along with GCC; see the file COPYING3. If not see
so that __FILE__ and __LINE__ will be usable to identify them.
*/
+/* This is the type we use to pass values to guality_check. */
+
+typedef intmax_t gualchk_t;
+
+/* Convert a pointer or integral type to the widest integral type,
+ as expected by guality_check. */
+
+#define GUALCVT(val) \
+ ((gualchk_t)__builtin_choose_expr \
+ (__builtin_types_compatible_p (__typeof (val), gualchk_t), \
+ (val), (intptr_t)(val)))
+
/* Attach a debugger to the current process and verify that the string
- EXPR, evaluated by the debugger, yields the long long number VAL.
+ EXPR, evaluated by the debugger, yields the gualchk_t number VAL.
If the debugger cannot compute the expression, say because the
variable is unavailable, this will count as an error, unless unkok
is nonzero. */
@@ -73,13 +83,13 @@ along with GCC; see the file COPYING3. If not see
guality_check, although not necessarily after the call. */
#define GUALCHKXPR(expr) \
- GUALCHKXPRVAL (#expr, (long long)(expr), 1)
+ GUALCHKXPRVAL (#expr, GUALCVT (expr), 1)
/* Same as GUALCHKXPR, but issue an error if the variable is optimized
away. */
#define GUALCHKVAL(expr) \
- GUALCHKXPRVAL (#expr, (long long)(expr), 0)
+ GUALCHKXPRVAL (#expr, GUALCVT (expr), 0)
/* Check that a debugger knows that EXPR evaluates to the run-time
value of EXPR. Unknown values are marked as errors, because the
@@ -91,7 +101,7 @@ along with GCC; see the file COPYING3. If not see
#define GUALCHKFLA(expr) do { \
__typeof(expr) volatile __preserve_after; \
__typeof(expr) __preserve_before = (expr); \
- GUALCHKXPRVAL (#expr, (long long)(__preserve_before), 0); \
+ GUALCHKXPRVAL (#expr, GUALCVT (__preserve_before), 0); \
__preserve_after = __preserve_before; \
asm ("" : : "m" (__preserve_after)); \
} while (0)
@@ -119,7 +129,14 @@ along with GCC; see the file COPYING3. If not see
static const char *guality_gdb_command;
#define GUALITY_GDB_DEFAULT "gdb"
-#define GUALITY_GDB_ARGS " -nx -nw --quiet > /dev/null 2>&1"
+#if defined(__unix)
+# define GUALITY_GDB_REDIRECT " > /dev/null 2>&1"
+#elif defined (_WIN32) || defined (MSDOS)
+# define GUALITY_GDB_REDIRECT " > nul"
+#else
+# define GUALITY_GDB_REDRECT ""
+#endif
+#define GUALITY_GDB_ARGS " -nx -nw --quiet" GUALITY_GDB_REDIRECT
/* Kinds of results communicated as exit status from child process
that runs gdb to the parent process that's being monitored. */
@@ -155,7 +172,7 @@ int volatile guality_attached;
extern int guality_main (int argc, char *argv[]);
static void __attribute__((noinline))
-guality_check (const char *name, long long value, int unknown_ok);
+guality_check (const char *name, gualchk_t value, int unknown_ok);
/* Set things up, run guality_main, then print a summary and quit. */
@@ -228,7 +245,7 @@ continue\n\
have an UNRESOLVED. Otherwise, it's a FAIL. */
static void __attribute__((noinline))
-guality_check (const char *name, long long value, int unknown_ok)
+guality_check (const char *name, gualchk_t value, int unknown_ok)
{
int result;
@@ -236,7 +253,7 @@ guality_check (const char *name, long long value, int unknown_ok)
return;
{
- volatile long long xvalue = -1;
+ volatile gualchk_t xvalue = -1;
volatile int unavailable = 0;
if (name)
{
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c
new file mode 100644
index 00000000000..2dea78ddd1c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-eipa_sra-details" } */
+
+struct bovid
+{
+ float red;
+ int green;
+ void *blue;
+};
+
+extern int printf (const char *, ...);
+extern void abort (void);
+
+static int
+__attribute__((noinline))
+ox (struct bovid cow)
+{
+ if (cow.green != 6)
+ abort ();
+
+ printf ("green: %f\nblue: %p\nblue again: %p\n", cow.green,
+ cow.blue, cow.blue);
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ struct bovid cow;
+
+ cow.red = 7.4;
+ cow.green = 6;
+ cow.blue = &cow;
+
+ ox (cow);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "About to replace expr cow.green with ISRA" "eipa_sra" } } */
+/* { dg-final { scan-tree-dump "About to replace expr cow.blue with ISRA" "eipa_sra" } } */
+/* { dg-final { cleanup-tree-dump "eipa_sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-2.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-2.c
new file mode 100644
index 00000000000..0e382015686
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-2.c
@@ -0,0 +1,52 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-eipa_sra-details" } */
+
+struct bovid
+{
+ float red;
+ int green;
+ void *blue;
+};
+
+static int
+__attribute__((noinline))
+ox (struct bovid *cow)
+{
+ cow->red = cow->red + cow->green + cow->green;
+ return 0;
+}
+
+int something;
+
+static int
+__attribute__((noinline))
+ox_improved (struct bovid *calf)
+{
+ if (something > 0)
+ calf->red = calf->red + calf->green;
+ else
+ calf->red = calf->green + 87;
+ something = 77;
+ return 0;
+}
+
+
+int main (int argc, char *argv[])
+{
+ struct bovid cow;
+
+ cow.red = 7.4;
+ cow.green = 6;
+ cow.blue = &cow;
+
+ ox (&cow);
+
+ ox_improved (&cow);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "About to replace expr cow_.*D.->red with \\*ISRA" "eipa_sra" } } */
+/* { dg-final { scan-tree-dump "About to replace expr cow_.*D.->green with ISRA" "eipa_sra" } } */
+/* { dg-final { scan-tree-dump "About to replace expr calf_.*D.->red with \\*ISRA" "eipa_sra" } } */
+/* { dg-final { scan-tree-dump "About to replace expr calf_.*D.->green with ISRA" "eipa_sra" } } */
+/* { dg-final { cleanup-tree-dump "eipa_sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-3.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-3.c
new file mode 100644
index 00000000000..f4e91bbe563
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-3.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-eipa_sra-details" } */
+
+struct bovid
+{
+ float red;
+ int green;
+ void *blue;
+};
+
+extern void foo (float, void *, void *, long);
+
+static int
+__attribute__((noinline))
+ox (struct bovid cow, int z, struct bovid calf, long l)
+{
+ foo (cow.red, cow.blue, cow.blue, l);
+ return 0;
+}
+
+void caller (void)
+{
+ struct bovid cow, calf;
+
+ cow.red = 7.4;
+ cow.green = 6;
+ cow.blue = &cow;
+
+ calf.red = 8.4;
+ calf.green = 5;
+ calf.blue = &cow;
+
+ ox (cow,4,calf,2);
+ return;
+}
+
+/* { dg-final { scan-tree-dump "base: z, remove_param" "eipa_sra" } } */
+/* { dg-final { scan-tree-dump "base: calf, remove_param" "eipa_sra" } } */
+/* { dg-final { cleanup-tree-dump "eipa_sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-4.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-4.c
new file mode 100644
index 00000000000..a832329b6ae
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-4.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-eipa_sra-details" } */
+
+static int
+__attribute__((noinline))
+ox (int *i)
+{
+ return *i+4**i;
+}
+
+int *holder;
+
+static int
+__attribute__((noinline))
+ox_ctrl_1 (int *j)
+{
+ holder = j;
+ return *j+4 * *j+1;
+}
+
+static void
+__attribute__((noinline))
+ox_ctrl_2 (int *k)
+{
+ *k = 8;
+}
+
+static int zzz[10];
+
+static int
+__attribute__((noinline))
+ox_improved (int recurse, int *l)
+{
+ int r = 0;
+
+ r = *l;
+
+ if (recurse)
+ {
+ if (recurse > 2)
+ l = &zzz[3];
+ else
+ l = zzz;
+
+ ox_improved (0, l);
+ }
+
+ return r;
+}
+
+void caller (void)
+{
+ int a = 1;
+ int b = 10;
+ int c;
+
+ ox (&a);
+ ox_ctrl_1 (&a);
+ ox_ctrl_2 (&a);
+ *holder = ox_improved (1, &b);
+ return;
+}
+
+/* { dg-final { scan-tree-dump "About to replace expr \\*i_.*D. with ISRA" "eipa_sra" } } */
+/* { dg-final { scan-tree-dump "About to replace expr \\*l_.*D. with ISRA" "eipa_sra" } } */
+/* { dg-final { scan-tree-dump-times "About to replace expr \*j_.*D. with ISRA" 0 "eipa_sra" } } */
+/* { dg-final { scan-tree-dump-times "About to replace expr \*k_.*D. with ISRA" 0 "eipa_sra" } } */
+/* { dg-final { cleanup-tree-dump "eipa_sra" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-5.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-5.c
new file mode 100644
index 00000000000..317e9b5aedd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-5.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-eipa_sra-details" } */
+
+static int *
+__attribute__((noinline,used))
+ ox (int *i, int *j)
+{
+ return i;
+}
+
+int a;
+
+int *caller (void)
+{
+ int b = 10;
+
+ return ox (&a, &b);
+}
+/* { dg-final { scan-tree-dump-times "base: j, remove_param" 0 "eipa_sra" } } */
+/* { dg-final { cleanup-tree-dump "eipa_sra" } } */
diff --git a/gcc/testsuite/gcc.dg/large-size-array-2.c b/gcc/testsuite/gcc.dg/large-size-array-2.c
index a1da14b1f72..bff2f8250fb 100644
--- a/gcc/testsuite/gcc.dg/large-size-array-2.c
+++ b/gcc/testsuite/gcc.dg/large-size-array-2.c
@@ -4,4 +4,4 @@
static char * name[] = {
[0x80000000] = "bar"
};
-/* { dg-error "too large" "" { target { { ! lp64 } || x86_64-*-mingw* } } 6 } */
+/* { dg-error "too large" "" { target { { ! lp64 } && { ! llp64 } } } 6 } */
diff --git a/gcc/testsuite/gcc.dg/large-size-array-4.c b/gcc/testsuite/gcc.dg/large-size-array-4.c
index 4f88f2c93ed..f6099b9152b 100644
--- a/gcc/testsuite/gcc.dg/large-size-array-4.c
+++ b/gcc/testsuite/gcc.dg/large-size-array-4.c
@@ -4,4 +4,4 @@
static char * name[] = {
[0x80000000] = "bar"
};
-/* { dg-error "too large" "" { target { { ! lp64 } || x86_64-*-mingw* } } 6 } */
+/* { dg-error "too large" "" { target { { ! lp64 } && { ! llp64 } } } 6 } */
diff --git a/gcc/testsuite/gcc.dg/pr41232.c b/gcc/testsuite/gcc.dg/pr41232.c
new file mode 100644
index 00000000000..17ec54899d7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr41232.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -g" } */
+extern int atoi (const char *);
+extern int sprintf (char *, const char *, ...);
+void malloc_init() {
+ char *cptr;
+ char buf[1];
+ int tmbd = atoi(cptr);
+ if (tmbd > 0)
+ tmbd = (tmbd <= 124) ? tmbd : 124;
+ else
+ tmbd = 0;
+ sprintf(buf, "%d\n", tmbd);
+}
diff --git a/gcc/testsuite/gcc.dg/pr41241.c b/gcc/testsuite/gcc.dg/pr41241.c
new file mode 100644
index 00000000000..b69aa96ca5e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr41241.c
@@ -0,0 +1,34 @@
+/* PR bootstrap/41241 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcompare-debug -g" } */
+/* { dg-options "-O2 -fcompare-debug -g -march=i586 -mtune=i586 -fomit-frame-pointer" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+typedef struct { int t1; int t2; int t3; } *T;
+typedef struct { int s; } S;
+
+int fn1 (int);
+int fn2 (int, int, int);
+int fn3 (void);
+
+static S
+bar ()
+{
+ S s = { 0 };
+ return s;
+}
+
+void
+foo (T x)
+{
+ int a, b, c, d, e;
+ T f, g;
+ S h;
+ a = x->t2;
+ fn1 (x->t1);
+ h = bar (b);
+ c = fn1 (e);
+ d = fn3 ();
+ f->t3 &= g->t3 |= fn2 (0, b, x->t1);
+ fn2 (0, c, d);
+ fn2 (0, e, 0);
+}
diff --git a/gcc/testsuite/gcc.dg/profile-dir-1.c b/gcc/testsuite/gcc.dg/profile-dir-1.c
index a0a22ffb0b0..6745c3b0daa 100644
--- a/gcc/testsuite/gcc.dg/profile-dir-1.c
+++ b/gcc/testsuite/gcc.dg/profile-dir-1.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O -fprofile-generate=. -fdump-tree-tree_profile" } */
+/* { dg-require-host-local "" } */
/* { dg-final { scan-tree-dump " ./profile-dir-1.gcda" "tree_profile" } } */
int
diff --git a/gcc/testsuite/gcc.dg/profile-dir-2.c b/gcc/testsuite/gcc.dg/profile-dir-2.c
index 454f0641aa2..2bfbee3f408 100644
--- a/gcc/testsuite/gcc.dg/profile-dir-2.c
+++ b/gcc/testsuite/gcc.dg/profile-dir-2.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O -fprofile-generate -fdump-tree-tree_profile" } */
+/* { dg-require-host-local "" } */
/* { dg-final { scan-tree-dump "/profile-dir-2.gcda" "tree_profile" } } */
int
diff --git a/gcc/testsuite/gcc.dg/profile-dir-3.c b/gcc/testsuite/gcc.dg/profile-dir-3.c
index 29b0a558712..8de891f03b8 100644
--- a/gcc/testsuite/gcc.dg/profile-dir-3.c
+++ b/gcc/testsuite/gcc.dg/profile-dir-3.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O -fprofile-generate -fprofile-dir=. -fdump-tree-tree_profile" } */
+/* { dg-require-host-local "" } */
/* { dg-final { scan-tree-dump " ./profile-dir-3.gcda" "tree_profile" } } */
int
diff --git a/gcc/testsuite/gcc.dg/struct/wo_prof_escape_arg_to_local.c b/gcc/testsuite/gcc.dg/struct/wo_prof_escape_arg_to_local.c
index 43ca58b9ef2..29630252e00 100644
--- a/gcc/testsuite/gcc.dg/struct/wo_prof_escape_arg_to_local.c
+++ b/gcc/testsuite/gcc.dg/struct/wo_prof_escape_arg_to_local.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O3 -fno-inline -fipa-type-escape -fdump-ipa-all -fipa-struct-reorg -fwhole-program -combine" } */
+/* { dg-options "-O3 -fno-inline -fno-ipa-sra -fipa-type-escape -fdump-ipa-all -fipa-struct-reorg -fwhole-program -combine" } */
/* { dg-do compile } */
/* { dg-do run } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr39074.c b/gcc/testsuite/gcc.dg/torture/pr39074.c
index 7be7e227b25..fe35cd908ae 100644
--- a/gcc/testsuite/gcc.dg/torture/pr39074.c
+++ b/gcc/testsuite/gcc.dg/torture/pr39074.c
@@ -2,9 +2,11 @@
/* { dg-options "-fdump-tree-alias" } */
/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+typedef __PTRDIFF_TYPE__ intptr_t;
+
int i;
void __attribute__((noinline))
-foo(long b, long q)
+foo(long b, intptr_t q)
{
int *y;
int **a = &y, **x;
diff --git a/gcc/testsuite/gcc.dg/torture/pr41261.c b/gcc/testsuite/gcc.dg/torture/pr41261.c
new file mode 100644
index 00000000000..8e601555cb5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr41261.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-fprofile-arcs" } */
+
+extern void relocate_kernel();
+void machine_kexec(void *control_page)
+{
+ __builtin_memcpy(control_page, relocate_kernel, 2048);
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/asmgoto-1.c b/gcc/testsuite/gcc.dg/tree-ssa/asmgoto-1.c
new file mode 100644
index 00000000000..1d08067bba2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/asmgoto-1.c
@@ -0,0 +1,95 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+extern void XYZZY (void);
+typedef unsigned long __kernel_size_t;
+typedef __kernel_size_t size_t;
+typedef unsigned gfp_t;
+struct per_cpu_pageset { } __attribute__ ((__aligned__ ((1 << (6)))));
+struct zone { struct per_cpu_pageset *pageset[64]; }
+zone_flags_t; typedef struct pglist_data { struct zone node_zones[4]; } pg_data_t;
+extern struct pglist_data *first_online_pgdat (void);
+extern struct zone *next_zone (struct zone *zone);
+extern volatile int per_cpu__x86_cpu_to_node_map[];
+struct kmem_cache { int size; };
+extern struct kmem_cache kmalloc_caches[(12 + 2)];
+struct tracepoint { void **funcs; } __attribute__ ((aligned (32)));
+extern struct tracepoint __tracepoint_kmalloc_node;
+void *__kmalloc_node (size_t size, gfp_t flags, int node);
+
+static inline int
+cpu_to_node (int cpu)
+{
+ return per_cpu__x86_cpu_to_node_map[cpu];
+}
+
+static inline void
+trace_kmalloc_node (unsigned long call_site, const void *ptr,
+ size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags,
+ int node)
+{
+ asm goto ("" : : : : trace_label);
+ if (0)
+ {
+ void **it_func;
+ trace_label:
+ asm ("" : "=r"(it_func) : "0"(&__tracepoint_kmalloc_node.funcs));
+ }
+};
+
+static inline __attribute__ ((always_inline)) int
+kmalloc_index (size_t size)
+{
+ if (size <= 64)
+ return 6;
+ return -1;
+}
+
+static inline __attribute__ ((always_inline)) struct kmem_cache *
+kmalloc_slab (size_t size)
+{
+ int index = kmalloc_index (size);
+ if (index == 0)
+ return ((void *) 0);
+ return &kmalloc_caches[index];
+}
+
+static inline __attribute__ ((always_inline)) void *
+kmalloc_node (size_t size, gfp_t flags, int node)
+{
+ void *ret;
+ if (__builtin_constant_p (size) && size <= (2 * ((1UL) << 12))
+ && !(flags & ((gfp_t) 0x01u)))
+ {
+ struct kmem_cache *s = kmalloc_slab (size);
+ if (!s)
+ return ((void *) 16);
+ trace_kmalloc_node (({ __here:(unsigned long) &&__here;}),
+ ret, size, s->size, flags, node);
+ }
+ return __kmalloc_node (size, flags, node);
+}
+
+int
+process_zones (int cpu)
+{
+ struct zone *zone, *dzone;
+ int node = cpu_to_node (cpu);
+ for (zone = (first_online_pgdat ())->node_zones;
+ zone; zone = next_zone (zone))
+ {
+ ((zone)->pageset[(cpu)]) =
+ kmalloc_node (sizeof (struct per_cpu_pageset),
+ (((gfp_t) 0x10u) | ((gfp_t) 0x40u) | ((gfp_t) 0x80u)),
+ node);
+ if (!((zone)->pageset[(cpu)]))
+ goto bad;
+ }
+ return 0;
+bad:
+ XYZZY ();
+ return -12;
+}
+
+/* { dg-final { scan-tree-dump-times "XYZZY" 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c
index eaaa6dd4e24..73051ae9645 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c
@@ -15,5 +15,5 @@ int g(int *p, int n)
return q[-1];
}
-/* { dg-final { scan-tree-dump-times "= \\\(\\\*a_..\\\)\\\[1\\\];" 2 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times "= \\\(\\\*a_..\\\)\\\[1\\\];" 2 "forwprop1" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c
index a74809b609e..1c5ea02ba78 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-12.c
@@ -18,5 +18,5 @@ int bar(struct X *p, int i)
/* We should have propagated the base array address through the
address arithmetic into the memory access as an array access. */
-/* { dg-final { scan-tree-dump-times "->a\\\[D\\\." 2 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times "->a\\\[D\\\." 2 "forwprop1" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr33920.c b/gcc/testsuite/gcc.dg/tree-ssa/pr33920.c
index 7ddcb21921f..0b91dae3840 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr33920.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr33920.c
@@ -2,6 +2,7 @@
/* { dg-do compile } */
/* { dg-options "-O3" } */
+typedef __PTRDIFF_TYPE__ intptr_t;
typedef union lispunion *object;
struct character
{
@@ -22,14 +23,14 @@ void init_code ()
object V659;
object _x, _y;
object V643;
- long V648;
+ intptr_t V648;
unsigned char V653;
object V651;
object V654;
object V658;
T1240:
-if (V648 >= (long)V651) /* { dg-warning "cast from pointer to integer of different size" "" { target { ! int32plus } } } */
+if (V648 >= (intptr_t)V651) /* { dg-warning "cast from pointer to integer of different size" "" { target { ! int32plus } } } */
goto T1243;
V653 = ((char *) V654->v.v_self)[V648];
V659 = (object) V654 + V653;
@@ -41,7 +42,7 @@ T1261:
goto T1249;
goto T1224;
T1249:
- V648 = (long) V648 + 1;
+ V648 = (intptr_t) V648 + 1;
goto T1240;
T1243:
V643 = (object) & Cnil_body;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/prefetch-7.c b/gcc/testsuite/gcc.dg/tree-ssa/prefetch-7.c
index 3024bed1b71..856df0a4a8f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/prefetch-7.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/prefetch-7.c
@@ -1,5 +1,6 @@
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-require-effective-target ilp32 } */
+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=athlon" } } */
/* { dg-options "-O2 -fprefetch-loop-arrays -march=athlon -msse2 -mfpmath=sse --param simultaneous-prefetches=100 --param max-unrolled-insns=1 -fdump-tree-aprefetch-details -fdump-tree-optimized" } */
#define K 1000000
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-7.c
new file mode 100644
index 00000000000..f8e15f34486
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-7.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-lim1-details" } */
+
+extern const int srcshift;
+
+void foo (int *srcdata, int *dstdata)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ dstdata[i] = srcdata[i] << srcshift;
+}
+
+/* { dg-final { scan-tree-dump "Moving statement" "lim1" } } */
+/* { dg-final { cleanup-tree-dump "lim1" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/O1-pr33854.c b/gcc/testsuite/gcc.dg/vect/O1-pr33854.c
index 346da6b60bd..4d4171fc449 100644
--- a/gcc/testsuite/gcc.dg/vect/O1-pr33854.c
+++ b/gcc/testsuite/gcc.dg/vect/O1-pr33854.c
@@ -1,7 +1,7 @@
/* Testcase by Martin Michlmayr <tbm@cyrius.com> */
/* { dg-do compile } */
-extern void *malloc (long unsigned int __size);
+extern void *malloc (__SIZE_TYPE__ __size);
typedef struct VMatrix_ VMatrix;
struct VMatrix_
{
diff --git a/gcc/testsuite/gcc.dg/vect/pr33833.c b/gcc/testsuite/gcc.dg/vect/pr33833.c
index f862a915cb6..ebdfcb1f818 100644
--- a/gcc/testsuite/gcc.dg/vect/pr33833.c
+++ b/gcc/testsuite/gcc.dg/vect/pr33833.c
@@ -1,6 +1,10 @@
/* Testcase by Martin Michlmayr <tbm@cyrius.com> */
/* { dg-do compile } */
+#define signed
+typedef unsigned __PTRDIFF_TYPE__ uintptr_t;
+#undef signed
+
struct list_head
{
struct list_head *prev;
@@ -14,7 +18,7 @@ struct rq
struct prio_array *active, arrays[2];
} per_cpu__runqueues;
-void sched_init (unsigned long __ptr)
+void sched_init (uintptr_t __ptr)
{
int j, k;
struct prio_array *array;
diff --git a/gcc/testsuite/gcc.dg/vect/pr33846.c b/gcc/testsuite/gcc.dg/vect/pr33846.c
index f31e207bdef..3f421c9b75d 100644
--- a/gcc/testsuite/gcc.dg/vect/pr33846.c
+++ b/gcc/testsuite/gcc.dg/vect/pr33846.c
@@ -7,7 +7,9 @@ int clamp_val (int i)
return ~i >> 31;
}
-void _mix_some_samples (long buf, int *mix_buffer, int mix_size)
+typedef __PTRDIFF_TYPE__ intptr_t;
+
+void _mix_some_samples (intptr_t buf, int *mix_buffer, int mix_size)
{
int i;
signed int *p = mix_buffer;
diff --git a/gcc/testsuite/gcc.misc-tests/i386-prefetch.exp b/gcc/testsuite/gcc.misc-tests/i386-prefetch.exp
index e9909845c44..a9f767cde0a 100644
--- a/gcc/testsuite/gcc.misc-tests/i386-prefetch.exp
+++ b/gcc/testsuite/gcc.misc-tests/i386-prefetch.exp
@@ -90,6 +90,13 @@ load_lib torture-options.exp
dg-init
torture-init
+if { [board_info target exists multilib_flags]
+ && [string match "* -march=*" " [board_info target multilib_flags] "] } {
+ # Multilib flags come after the -march flags we pass and override
+ # them, so skip these tests when such flags are passed.
+ return
+}
+
set-torture-options $PREFETCH_NONE
gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/i386-pf-none-*.c]] ""
diff --git a/gcc/testsuite/gcc.target/arm/ctz.c b/gcc/testsuite/gcc.target/arm/ctz.c
new file mode 100644
index 00000000000..63e9d0266d2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/ctz.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm32 } */
+/* { dg-options "-O2 -march=armv6t2" } */
+
+unsigned int functest(unsigned int x)
+{
+ return __builtin_ctz(x);
+}
+
+/* { dg-final { scan-assembler "rbit" } } */
+/* { dg-final { scan-assembler "clz" } } */
+/* { dg-final { scan-assembler-not "rsb" } } */
diff --git a/gcc/testsuite/gcc.target/bfin/20090914-1.c b/gcc/testsuite/gcc.target/bfin/20090914-1.c
new file mode 100644
index 00000000000..10445405710
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bfin/20090914-1.c
@@ -0,0 +1,39 @@
+/* { dg-do compile { target bfin-*-* } } */
+
+typedef short __v2hi __attribute__ ((vector_size (4)));
+typedef __v2hi raw2x16;
+typedef raw2x16 fract2x16;
+
+typedef short fract16;
+typedef struct complex_fract16
+{
+ fract16 re;
+ fract16 im;
+} __attribute__ ((aligned (4))) complex_fract16;
+
+typedef union composite_complex_fract16
+{
+ struct complex_fract16 x;
+ long raw;
+} composite_complex_fract16;
+
+__inline__ __attribute__ ((always_inline))
+static complex_fract16 cmsu_fr16 (complex_fract16 _sum,
+ complex_fract16 _a, complex_fract16 _b)
+{
+ complex_fract16 r;
+ fract2x16 i =
+ __builtin_bfin_cmplx_msu (__builtin_bfin_compose_2x16
+ ((_sum).im, (_sum).re),
+ __builtin_bfin_compose_2x16 ((_a).im, (_a).re),
+ __builtin_bfin_compose_2x16 ((_b).im, (_b).re));
+ (r).re = __builtin_bfin_extract_lo (i);
+ (r).im = __builtin_bfin_extract_hi (i);
+ return r;
+}
+
+composite_complex_fract16
+f (complex_fract16 _sum, complex_fract16 _a, complex_fract16 _b)
+{
+ return (composite_complex_fract16) cmsu_fr16 (_sum, _a, _b);
+}
diff --git a/gcc/testsuite/gcc.target/bfin/20090914-2.c b/gcc/testsuite/gcc.target/bfin/20090914-2.c
new file mode 100644
index 00000000000..55255d7a847
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bfin/20090914-2.c
@@ -0,0 +1,31 @@
+/* { dg-do compile { target bfin-*-* } } */
+
+typedef short fract16;
+typedef short __v2hi __attribute__ ((vector_size (4)));
+typedef __v2hi raw2x16;
+typedef raw2x16 fract2x16;
+typedef struct complex_fract16 {
+ fract16 re;
+ fract16 im;
+} __attribute__((aligned(4))) complex_fract16;
+
+
+__inline__
+__attribute__ ((always_inline))
+static complex_fract16 cmlt_fr16 (complex_fract16 _a,
+ complex_fract16 _b)
+{
+ complex_fract16 r;
+ fract2x16 i;
+
+ i = __builtin_bfin_cmplx_mul(__builtin_bfin_compose_2x16((_a).im, (_a).re),
+ __builtin_bfin_compose_2x16((_b).im, (_b).re));
+ (r).re = __builtin_bfin_extract_lo(i);
+ (r).im = __builtin_bfin_extract_hi(i);
+ return r;
+}
+
+
+complex_fract16 f(complex_fract16 a, complex_fract16 b) {
+ return cmlt_fr16(a, b);
+}
diff --git a/gcc/testsuite/gcc.target/bfin/20090914-3.c b/gcc/testsuite/gcc.target/bfin/20090914-3.c
new file mode 100644
index 00000000000..fb0a9e16c73
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bfin/20090914-3.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target bfin-*-* } } */
+typedef long fract32;
+main() {
+ fract32 val_tmp;
+ fract32 val1 = 0x7FFFFFFF;
+ fract32 val2 = 0x40000000;
+ val_tmp = __builtin_bfin_mult_fr1x32x32 (0x06666667, val1);
+ val2 = __builtin_bfin_mult_fr1x32x32 (0x79999999, val2);
+ val2 = __builtin_bfin_add_fr1x32 (val_tmp, val2);
+}
diff --git a/gcc/testsuite/gcc.target/bfin/mcpu-bf542m.c b/gcc/testsuite/gcc.target/bfin/mcpu-bf542m.c
new file mode 100644
index 00000000000..74d377045c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bfin/mcpu-bf542m.c
@@ -0,0 +1,41 @@
+/* Test for -mcpu=. */
+/* { dg-do preprocess } */
+/* { dg-bfin-options "-mcpu=bf542m" } */
+
+#ifndef __ADSPBF542__
+#error "__ADSPBF542__ is not defined"
+#endif
+
+#ifndef __ADSPBF542M__
+#error "__ADSPBF542M__ is not defined"
+#endif
+
+#ifndef __ADSPBF54x__
+#error "__ADSPBF54x__ is not defined"
+#endif
+
+#if __SILICON_REVISION__ != 0x0003
+#error "__SILICON_REVISION__ is not 0x0003"
+#endif
+
+#ifndef __WORKAROUNDS_ENABLED
+#error "__WORKAROUNDS_ENABLED is not defined"
+#endif
+
+#if __SILICON_REVISION__ <= 0x0001
+#ifndef __WORKAROUND_RETS
+#error "__WORKAROUND_RETS is not defined"
+#endif
+#else
+#ifdef __WORKAROUND_RETS
+#error "__WORKAROUND_RETS is defined"
+#endif
+#endif
+
+#ifndef __WORKAROUND_SPECULATIVE_LOADS
+#error "__WORKAROUND_SPECULATIVE_LOADS is not defined"
+#endif
+
+#ifdef __WORKAROUND_SPECULATIVE_SYNCS
+#error "__WORKAROUND_SPECULATIVE_SYNCS is defined"
+#endif
diff --git a/gcc/testsuite/gcc.target/bfin/mcpu-bf544m.c b/gcc/testsuite/gcc.target/bfin/mcpu-bf544m.c
new file mode 100644
index 00000000000..a0289378c1a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bfin/mcpu-bf544m.c
@@ -0,0 +1,41 @@
+/* Test for -mcpu=. */
+/* { dg-do preprocess } */
+/* { dg-bfin-options "-mcpu=bf544m" } */
+
+#ifndef __ADSPBF544__
+#error "__ADSPBF544__ is not defined"
+#endif
+
+#ifndef __ADSPBF544M__
+#error "__ADSPBF544M__ is not defined"
+#endif
+
+#ifndef __ADSPBF54x__
+#error "__ADSPBF54x__ is not defined"
+#endif
+
+#if __SILICON_REVISION__ != 0x0003
+#error "__SILICON_REVISION__ is not 0x0003"
+#endif
+
+#ifndef __WORKAROUNDS_ENABLED
+#error "__WORKAROUNDS_ENABLED is not defined"
+#endif
+
+#if __SILICON_REVISION__ <= 0x0001
+#ifndef __WORKAROUND_RETS
+#error "__WORKAROUND_RETS is not defined"
+#endif
+#else
+#ifdef __WORKAROUND_RETS
+#error "__WORKAROUND_RETS is defined"
+#endif
+#endif
+
+#ifndef __WORKAROUND_SPECULATIVE_LOADS
+#error "__WORKAROUND_SPECULATIVE_LOADS is not defined"
+#endif
+
+#ifdef __WORKAROUND_SPECULATIVE_SYNCS
+#error "__WORKAROUND_SPECULATIVE_SYNCS is defined"
+#endif
diff --git a/gcc/testsuite/gcc.target/bfin/mcpu-bf547m.c b/gcc/testsuite/gcc.target/bfin/mcpu-bf547m.c
new file mode 100644
index 00000000000..e5e1f9b30ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bfin/mcpu-bf547m.c
@@ -0,0 +1,41 @@
+/* Test for -mcpu=. */
+/* { dg-do preprocess } */
+/* { dg-bfin-options "-mcpu=bf547m" } */
+
+#ifndef __ADSPBF547__
+#error "__ADSPBF547__ is not defined"
+#endif
+
+#ifndef __ADSPBF547M__
+#error "__ADSPBF547M__ is not defined"
+#endif
+
+#ifndef __ADSPBF54x__
+#error "__ADSPBF54x__ is not defined"
+#endif
+
+#if __SILICON_REVISION__ != 0x0003
+#error "__SILICON_REVISION__ is not 0x0003"
+#endif
+
+#ifndef __WORKAROUNDS_ENABLED
+#error "__WORKAROUNDS_ENABLED is not defined"
+#endif
+
+#if __SILICON_REVISION__ <= 0x0001
+#ifndef __WORKAROUND_RETS
+#error "__WORKAROUND_RETS is not defined"
+#endif
+#else
+#ifdef __WORKAROUND_RETS
+#error "__WORKAROUND_RETS is defined"
+#endif
+#endif
+
+#ifndef __WORKAROUND_SPECULATIVE_LOADS
+#error "__WORKAROUND_SPECULATIVE_LOADS is not defined"
+#endif
+
+#ifdef __WORKAROUND_SPECULATIVE_SYNCS
+#error "__WORKAROUND_SPECULATIVE_SYNCS is defined"
+#endif
diff --git a/gcc/testsuite/gcc.target/bfin/mcpu-bf548m.c b/gcc/testsuite/gcc.target/bfin/mcpu-bf548m.c
new file mode 100644
index 00000000000..47afafffef5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bfin/mcpu-bf548m.c
@@ -0,0 +1,41 @@
+/* Test for -mcpu=. */
+/* { dg-do preprocess } */
+/* { dg-bfin-options "-mcpu=bf548m" } */
+
+#ifndef __ADSPBF548__
+#error "__ADSPBF548__ is not defined"
+#endif
+
+#ifndef __ADSPBF548M__
+#error "__ADSPBF548M__ is not defined"
+#endif
+
+#ifndef __ADSPBF54x__
+#error "__ADSPBF54x__ is not defined"
+#endif
+
+#if __SILICON_REVISION__ != 0x0003
+#error "__SILICON_REVISION__ is not 0x0003"
+#endif
+
+#ifndef __WORKAROUNDS_ENABLED
+#error "__WORKAROUNDS_ENABLED is not defined"
+#endif
+
+#if __SILICON_REVISION__ <= 0x0001
+#ifndef __WORKAROUND_RETS
+#error "__WORKAROUND_RETS is not defined"
+#endif
+#else
+#ifdef __WORKAROUND_RETS
+#error "__WORKAROUND_RETS is defined"
+#endif
+#endif
+
+#ifndef __WORKAROUND_SPECULATIVE_LOADS
+#error "__WORKAROUND_SPECULATIVE_LOADS is not defined"
+#endif
+
+#ifdef __WORKAROUND_SPECULATIVE_SYNCS
+#error "__WORKAROUND_SPECULATIVE_SYNCS is defined"
+#endif
diff --git a/gcc/testsuite/gcc.target/bfin/mcpu-bf549m.c b/gcc/testsuite/gcc.target/bfin/mcpu-bf549m.c
new file mode 100644
index 00000000000..8aa7ad56057
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bfin/mcpu-bf549m.c
@@ -0,0 +1,41 @@
+/* Test for -mcpu=. */
+/* { dg-do preprocess } */
+/* { dg-bfin-options "-mcpu=bf549m" } */
+
+#ifndef __ADSPBF549__
+#error "__ADSPBF549__ is not defined"
+#endif
+
+#ifndef __ADSPBF549M__
+#error "__ADSPBF549M__ is not defined"
+#endif
+
+#ifndef __ADSPBF54x__
+#error "__ADSPBF54x__ is not defined"
+#endif
+
+#if __SILICON_REVISION__ != 0x0003
+#error "__SILICON_REVISION__ is not 0x0003"
+#endif
+
+#ifndef __WORKAROUNDS_ENABLED
+#error "__WORKAROUNDS_ENABLED is not defined"
+#endif
+
+#if __SILICON_REVISION__ <= 0x0001
+#ifndef __WORKAROUND_RETS
+#error "__WORKAROUND_RETS is not defined"
+#endif
+#else
+#ifdef __WORKAROUND_RETS
+#error "__WORKAROUND_RETS is defined"
+#endif
+#endif
+
+#ifndef __WORKAROUND_SPECULATIVE_LOADS
+#error "__WORKAROUND_SPECULATIVE_LOADS is not defined"
+#endif
+
+#ifdef __WORKAROUND_SPECULATIVE_SYNCS
+#error "__WORKAROUND_SPECULATIVE_SYNCS is defined"
+#endif
diff --git a/gcc/testsuite/gcc.target/bfin/saveall.c b/gcc/testsuite/gcc.target/bfin/saveall.c
new file mode 100644
index 00000000000..19f9decd74d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bfin/saveall.c
@@ -0,0 +1,14 @@
+/* { dg-do run { target bfin*-*-* } } */
+/* { dg-options "-fomit-frame-pointer" } */
+
+void foo (void) __attribute__ ((saveall));
+void foo ()
+{
+ asm ("R0 = 0; RETS = R0;");
+}
+
+int main ()
+{
+ foo ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/387-1.c b/gcc/testsuite/gcc.target/i386/387-1.c
index 2b3ca0b0610..83af71f9647 100644
--- a/gcc/testsuite/gcc.target/i386/387-1.c
+++ b/gcc/testsuite/gcc.target/i386/387-1.c
@@ -1,6 +1,7 @@
/* Verify that -mno-fancy-math-387 works. */
/* { dg-do compile } */
/* { dg-require-effective-target ilp32 } */
+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=i386" } } */
/* { 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.target/i386/387-5.c b/gcc/testsuite/gcc.target/i386/387-5.c
index 0a050081780..027799a878a 100644
--- a/gcc/testsuite/gcc.target/i386/387-5.c
+++ b/gcc/testsuite/gcc.target/i386/387-5.c
@@ -1,6 +1,7 @@
/* Verify that -mno-fancy-math-387 works. */
/* { dg-do compile } */
/* { dg-require-effective-target ilp32 } */
+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=i386" } } */
/* { 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.target/i386/cmov7.c b/gcc/testsuite/gcc.target/i386/cmov7.c
index 31b48165432..433bf57f8e7 100644
--- a/gcc/testsuite/gcc.target/i386/cmov7.c
+++ b/gcc/testsuite/gcc.target/i386/cmov7.c
@@ -1,6 +1,7 @@
/* PR middle-end/33187 */
/* { dg-do compile } */
+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=k8" } } */
/* { dg-options "-O2 -ffast-math -march=k8 -mbranch-cost=5 -mfpmath=387" } */
/* { dg-final { scan-assembler "fcmov" } } */
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-1.c b/gcc/testsuite/gcc.target/i386/funcspec-1.c
index 1416c75f357..52420ec93e9 100644
--- a/gcc/testsuite/gcc.target/i386/funcspec-1.c
+++ b/gcc/testsuite/gcc.target/i386/funcspec-1.c
@@ -3,6 +3,7 @@
for a function that doesn't use attribute((option)). */
/* { dg-do compile } */
/* { dg-require-effective-target ilp32 } */
+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=i386" } } */
/* { dg-options "-O3 -ftree-vectorize -march=i386" } */
/* { dg-final { scan-assembler "addps\[ \t\]" } } */
/* { dg-final { scan-assembler "fsubs\[ \t\]" } } */
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-8.c b/gcc/testsuite/gcc.target/i386/funcspec-8.c
index 2b8bb6f4af6..c370733a01b 100644
--- a/gcc/testsuite/gcc.target/i386/funcspec-8.c
+++ b/gcc/testsuite/gcc.target/i386/funcspec-8.c
@@ -1,6 +1,7 @@
/* Test whether using target specific options, we can use the x86 builtin
functions in functions with the appropriate function specific options. */
/* { dg-do compile } */
+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=k8" } } */
/* { dg-options "-O2 -march=k8 -mfpmath=sse" } */
typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
diff --git a/gcc/testsuite/gcc.target/i386/gcc-have-sync-compare-and-swap-1.c b/gcc/testsuite/gcc.target/i386/gcc-have-sync-compare-and-swap-1.c
index 598f2ddbc31..d20a7176038 100644
--- a/gcc/testsuite/gcc.target/i386/gcc-have-sync-compare-and-swap-1.c
+++ b/gcc/testsuite/gcc.target/i386/gcc-have-sync-compare-and-swap-1.c
@@ -1,5 +1,6 @@
/* { dg-do preprocess } */
/* { dg-require-effective-target ilp32 } */
+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=i386" } } */
/* { dg-options "-march=i386" } */
#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
diff --git a/gcc/testsuite/gcc.target/i386/gcc-have-sync-compare-and-swap-2.c b/gcc/testsuite/gcc.target/i386/gcc-have-sync-compare-and-swap-2.c
index fa6e7c654ef..01a49b64a83 100644
--- a/gcc/testsuite/gcc.target/i386/gcc-have-sync-compare-and-swap-2.c
+++ b/gcc/testsuite/gcc.target/i386/gcc-have-sync-compare-and-swap-2.c
@@ -1,5 +1,6 @@
/* { dg-do preprocess } */
/* { dg-require-effective-target ilp32 } */
+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=i486" } } */
/* { dg-options "-march=i486" } */
#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
diff --git a/gcc/testsuite/gcc.target/i386/isa-6.c b/gcc/testsuite/gcc.target/i386/isa-6.c
index ec1fbeaa4d4..7f01a884ea6 100644
--- a/gcc/testsuite/gcc.target/i386/isa-6.c
+++ b/gcc/testsuite/gcc.target/i386/isa-6.c
@@ -1,4 +1,5 @@
/* { dg-do run } */
+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=amdfam10" } } */
/* { dg-options "-march=amdfam10 -mno-sse4" } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.target/i386/lea.c b/gcc/testsuite/gcc.target/i386/lea.c
index afbbfa4fbc0..f8f967e00f1 100644
--- a/gcc/testsuite/gcc.target/i386/lea.c
+++ b/gcc/testsuite/gcc.target/i386/lea.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-require-effective-target ilp32 } */
+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=pentiumpro" } } */
/* { dg-options "-O2 -march=pentiumpro" } */
/* { dg-final { scan-assembler "leal" } } */
typedef struct {
diff --git a/gcc/testsuite/gcc.target/i386/pentium4-not-mull.c b/gcc/testsuite/gcc.target/i386/pentium4-not-mull.c
index be48185a86c..a846aae61b0 100644
--- a/gcc/testsuite/gcc.target/i386/pentium4-not-mull.c
+++ b/gcc/testsuite/gcc.target/i386/pentium4-not-mull.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-require-effective-target ilp32 } */
+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=pentium4" } } */
/* { dg-options "-O2 -march=pentium4" } */
/* { dg-final { scan-assembler-not "imull" } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse-5.c b/gcc/testsuite/gcc.target/i386/sse-5.c
index c3ed8f2672b..bdbd5012e48 100644
--- a/gcc/testsuite/gcc.target/i386/sse-5.c
+++ b/gcc/testsuite/gcc.target/i386/sse-5.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-require-effective-target ilp32 } */
+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=i386" } } */
/* { dg-options "-Winline -O2 -march=i386" } */
typedef double v2df __attribute__ ((vector_size (16)));
diff --git a/gcc/testsuite/gcc.target/i386/ssefn-1.c b/gcc/testsuite/gcc.target/i386/ssefn-1.c
index 0279a553346..bea6cb2bf0b 100644
--- a/gcc/testsuite/gcc.target/i386/ssefn-1.c
+++ b/gcc/testsuite/gcc.target/i386/ssefn-1.c
@@ -7,6 +7,7 @@
/* { dg-final { scan-assembler "mulss" } } */
/* { dg-final { scan-assembler-not "movsd" } } */
/* { dg-final { scan-assembler-not "mulsd" } } */
+/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=i386" } } */
/* { dg-options "-O2 -march=i386 -msse -mfpmath=sse -fno-inline" } */
static float xs (void)
diff --git a/gcc/testsuite/gcc.target/mips/branch-10.c b/gcc/testsuite/gcc.target/mips/branch-10.c
new file mode 100644
index 00000000000..7fdebfcc3f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-10.c
@@ -0,0 +1,13 @@
+/* { dg-options "-mabicalls -mshared -mabi=n32" } */
+/* { dg-final { scan-assembler-not "(\\\$28|%gp_rel|%got)" } } */
+/* { dg-final { scan-assembler-not "\tjr\t\\\$1\n" } } */
+
+#include "branch-helper.h"
+
+NOMIPS16 void
+foo (void (*bar) (void), volatile int *x)
+{
+ bar ();
+ if (__builtin_expect (*x == 0, 1))
+ OCCUPY_0x1fff8;
+}
diff --git a/gcc/testsuite/gcc.target/mips/branch-11.c b/gcc/testsuite/gcc.target/mips/branch-11.c
new file mode 100644
index 00000000000..1c57f82f533
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-11.c
@@ -0,0 +1,17 @@
+/* { dg-options "-mabicalls -mshared -mabi=n32" } */
+/* { dg-final { scan-assembler "\tsd\t\\\$28," } } */
+/* { dg-final { scan-assembler "\tld\t\\\$28," } } */
+/* { dg-final { scan-assembler "\taddiu\t\\\$28,\\\$28,%lo\\(%neg\\(%gp_rel\\(foo\\)\\)\\)\n" } } */
+/* { dg-final { scan-assembler "\tlw\t\\\$1,%got_page\\(\[^)\]*\\)\\(\\\$28\\)\n" } } */
+/* { dg-final { scan-assembler "\taddiu\t\\\$1,\\\$1,%got_ofst\\(\[^)\]*\\)\n" } } */
+/* { dg-final { scan-assembler "\tjr\t\\\$1\n" } } */
+
+#include "branch-helper.h"
+
+NOMIPS16 void
+foo (void (*bar) (void), volatile int *x)
+{
+ bar ();
+ if (__builtin_expect (*x == 0, 1))
+ OCCUPY_0x1fffc;
+}
diff --git a/gcc/testsuite/gcc.target/mips/branch-12.c b/gcc/testsuite/gcc.target/mips/branch-12.c
new file mode 100644
index 00000000000..f1b6f1e8244
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-12.c
@@ -0,0 +1,13 @@
+/* { dg-options "-mabicalls -mshared -mabi=64" } */
+/* { dg-final { scan-assembler-not "(\\\$28|%gp_rel|%got)" } } */
+/* { dg-final { scan-assembler-not "\tjr\t\\\$1\n" } } */
+
+#include "branch-helper.h"
+
+NOMIPS16 void
+foo (void (*bar) (void), volatile int *x)
+{
+ bar ();
+ if (__builtin_expect (*x == 0, 1))
+ OCCUPY_0x1fff8;
+}
diff --git a/gcc/testsuite/gcc.target/mips/branch-13.c b/gcc/testsuite/gcc.target/mips/branch-13.c
new file mode 100644
index 00000000000..cc0b607d728
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-13.c
@@ -0,0 +1,17 @@
+/* { dg-options "-mabicalls -mshared -mabi=64" } */
+/* { dg-final { scan-assembler "\tsd\t\\\$28," } } */
+/* { dg-final { scan-assembler "\tld\t\\\$28," } } */
+/* { dg-final { scan-assembler "\tdaddiu\t\\\$28,\\\$28,%lo\\(%neg\\(%gp_rel\\(foo\\)\\)\\)\n" } } */
+/* { dg-final { scan-assembler "\tld\t\\\$1,%got_page\\(\[^)\]*\\)\\(\\\$28\\)\n" } } */
+/* { dg-final { scan-assembler "\tdaddiu\t\\\$1,\\\$1,%got_ofst\\(\[^)\]*\\)\n" } } */
+/* { dg-final { scan-assembler "\tjr\t\\\$1\n" } } */
+
+#include "branch-helper.h"
+
+NOMIPS16 void
+foo (void (*bar) (void), volatile int *x)
+{
+ bar ();
+ if (__builtin_expect (*x == 0, 1))
+ OCCUPY_0x1fffc;
+}
diff --git a/gcc/testsuite/gcc.target/mips/branch-14.c b/gcc/testsuite/gcc.target/mips/branch-14.c
new file mode 100644
index 00000000000..026417e162b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-14.c
@@ -0,0 +1,23 @@
+/* An executable version of branch-2.c. */
+/* { dg-do run } */
+
+#include "branch-helper.h"
+
+void __attribute__((noinline))
+foo (volatile int *x)
+{
+ if (__builtin_expect (*x == 0, 1))
+ OCCUPY_0x1fff8;
+}
+
+int
+main (void)
+{
+ int x = 0;
+ int y = 1;
+
+ foo (&x);
+ foo (&y);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/mips/branch-15.c b/gcc/testsuite/gcc.target/mips/branch-15.c
new file mode 100644
index 00000000000..dee7a0504d6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-15.c
@@ -0,0 +1,23 @@
+/* An executable version of branch-3.c. */
+/* { dg-do run } */
+
+#include "branch-helper.h"
+
+void
+foo (volatile int *x)
+{
+ if (__builtin_expect (*x == 0, 1))
+ OCCUPY_0x1fffc;
+}
+
+int
+main (void)
+{
+ int x = 0;
+ int y = 1;
+
+ foo (&x);
+ foo (&y);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/mips/branch-2.c b/gcc/testsuite/gcc.target/mips/branch-2.c
new file mode 100644
index 00000000000..845e7481729
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-2.c
@@ -0,0 +1,13 @@
+/* { dg-options "-mabicalls -mshared -mabi=32" } */
+/* { dg-final { scan-assembler-not "(\\\$25|\\\$28|cpload)" } } */
+/* { dg-final { scan-assembler-not "\tjr\t\\\$1\n" } } */
+/* { dg-final { scan-assembler-not "cprestore" } } */
+
+#include "branch-helper.h"
+
+NOMIPS16 void
+foo (volatile int *x)
+{
+ if (__builtin_expect (*x == 0, 1))
+ OCCUPY_0x1fff8;
+}
diff --git a/gcc/testsuite/gcc.target/mips/branch-3.c b/gcc/testsuite/gcc.target/mips/branch-3.c
new file mode 100644
index 00000000000..0a4ffbba604
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-3.c
@@ -0,0 +1,13 @@
+/* { dg-options "-mabicalls -mshared -mabi=32" } */
+/* { dg-final { scan-assembler "\t\\.cpload\t\\\$25\n" } } */
+/* { dg-final { scan-assembler "\tjr\t\\\$1\n" } } */
+/* { dg-final { scan-assembler-not "cprestore" } } */
+
+#include "branch-helper.h"
+
+NOMIPS16 void
+foo (volatile int *x)
+{
+ if (__builtin_expect (*x == 0, 1))
+ OCCUPY_0x1fffc;
+}
diff --git a/gcc/testsuite/gcc.target/mips/branch-4.c b/gcc/testsuite/gcc.target/mips/branch-4.c
new file mode 100644
index 00000000000..277bd0af76f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-4.c
@@ -0,0 +1,12 @@
+/* { dg-options "-mabicalls -mshared -mabi=n32" } */
+/* { dg-final { scan-assembler-not "(\\\$25|\\\$28|%gp_rel|%got)" } } */
+/* { dg-final { scan-assembler-not "\tjr\t\\\$1\n" } } */
+
+#include "branch-helper.h"
+
+NOMIPS16 void
+foo (volatile int *x)
+{
+ if (__builtin_expect (*x == 0, 1))
+ OCCUPY_0x1fff8;
+}
diff --git a/gcc/testsuite/gcc.target/mips/branch-5.c b/gcc/testsuite/gcc.target/mips/branch-5.c
new file mode 100644
index 00000000000..3d151d824ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-5.c
@@ -0,0 +1,14 @@
+/* { dg-options "-mabicalls -mshared -mabi=n32" } */
+/* { dg-final { scan-assembler "\taddiu\t\\\$3,\\\$3,%lo\\(%neg\\(%gp_rel\\(foo\\)\\)\\)\n" } } */
+/* { dg-final { scan-assembler "\tlw\t\\\$1,%got_page\\(\[^)\]*\\)\\(\\\$3\\)\\n" } } */
+/* { dg-final { scan-assembler "\tjr\t\\\$1\n" } } */
+/* { dg-final { scan-assembler-not "\\\$28" } } */
+
+#include "branch-helper.h"
+
+NOMIPS16 void
+foo (volatile int *x)
+{
+ if (__builtin_expect (*x == 0, 1))
+ OCCUPY_0x1fffc;
+}
diff --git a/gcc/testsuite/gcc.target/mips/branch-6.c b/gcc/testsuite/gcc.target/mips/branch-6.c
new file mode 100644
index 00000000000..9bf73f01c9b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-6.c
@@ -0,0 +1,12 @@
+/* { dg-options "-mabicalls -mshared -mabi=64" } */
+/* { dg-final { scan-assembler-not "(\\\$25|\\\$28|%gp_rel|%got)" } } */
+/* { dg-final { scan-assembler-not "\tjr\t\\\$1\n" } } */
+
+#include "branch-helper.h"
+
+NOMIPS16 void
+foo (volatile int *x)
+{
+ if (__builtin_expect (*x == 0, 1))
+ OCCUPY_0x1fff8;
+}
diff --git a/gcc/testsuite/gcc.target/mips/branch-7.c b/gcc/testsuite/gcc.target/mips/branch-7.c
new file mode 100644
index 00000000000..053ec610c3d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-7.c
@@ -0,0 +1,14 @@
+/* { dg-options "-mabicalls -mshared -mabi=64" } */
+/* { dg-final { scan-assembler "\tdaddiu\t\\\$3,\\\$3,%lo\\(%neg\\(%gp_rel\\(foo\\)\\)\\)\n" } } */
+/* { dg-final { scan-assembler "\tld\t\\\$1,%got_page\\(\[^)\]*\\)\\(\\\$3\\)\\n" } } */
+/* { dg-final { scan-assembler "\tjr\t\\\$1\n" } } */
+/* { dg-final { scan-assembler-not "\\\$28" } } */
+
+#include "branch-helper.h"
+
+NOMIPS16 void
+foo (volatile int *x)
+{
+ if (__builtin_expect (*x == 0, 1))
+ OCCUPY_0x1fffc;
+}
diff --git a/gcc/testsuite/gcc.target/mips/branch-8.c b/gcc/testsuite/gcc.target/mips/branch-8.c
new file mode 100644
index 00000000000..c2cbae36905
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-8.c
@@ -0,0 +1,13 @@
+/* { dg-options "-mabicalls -mshared -mabi=32" } */
+/* { dg-final { scan-assembler-not "(\\\$28|cpload|cprestore)" } } */
+/* { dg-final { scan-assembler-not "\tjr\t\\\$1\n" } } */
+
+#include "branch-helper.h"
+
+NOMIPS16 void
+foo (void (*bar) (void), volatile int *x)
+{
+ bar ();
+ if (__builtin_expect (*x == 0, 1))
+ OCCUPY_0x1fff8;
+}
diff --git a/gcc/testsuite/gcc.target/mips/branch-9.c b/gcc/testsuite/gcc.target/mips/branch-9.c
new file mode 100644
index 00000000000..2b83ea5b591
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-9.c
@@ -0,0 +1,18 @@
+/* { dg-options "-mabicalls -mshared -mabi=32" } */
+/* { dg-final { scan-assembler "\t\\.cpload\t\\\$25\n" } } */
+/* { dg-final { scan-assembler "\t\\.cprestore\t16\n" } } */
+/* { dg-final { scan-assembler "\tlw\t\\\$1,16\\(\\\$fp\\)\n" } } */
+/* { dg-final { scan-assembler "\tlw\t\\\$1,%got\\(\[^)\]*\\)\\(\\\$1\\)\n" } } */
+/* { dg-final { scan-assembler "\taddiu\t\\\$1,\\\$1,%lo\\(\[^)\]*\\)\n" } } */
+/* { dg-final { scan-assembler "\tjr\t\\\$1\n" } } */
+/* { dg-final { scan-assembler-not "\tlw\t\\\$28,16\\(\\\$sp\\)\n" } } */
+
+#include "branch-helper.h"
+
+NOMIPS16 void
+foo (void (*bar) (void), volatile int *x)
+{
+ bar ();
+ if (__builtin_expect (*x == 0, 1))
+ OCCUPY_0x1fffc;
+}
diff --git a/gcc/testsuite/gcc.target/mips/branch-helper.h b/gcc/testsuite/gcc.target/mips/branch-helper.h
new file mode 100644
index 00000000000..85399be4c7d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/branch-helper.h
@@ -0,0 +1,37 @@
+/* DN(X) generates 2**N copies of asm instruction X. */
+#define D0(X) X
+#define D1(X) X "\n\t" X
+#define D2(X) D1 (D1 (X))
+#define D3(X) D2 (D1 (X))
+#define D4(X) D2 (D2 (X))
+#define D5(X) D4 (D1 (X))
+#define D6(X) D4 (D2 (X))
+#define D7(X) D4 (D2 (D1 (X)))
+#define D8(X) D4 (D4 (X))
+#define D9(X) D8 (D1 (X))
+#define D10(X) D8 (D2 (X))
+#define D11(X) D8 (D2 (D1 (X)))
+#define D12(X) D8 (D4 (X))
+#define D13(X) D8 (D4 (D1 (X)))
+#define D14(X) D8 (D4 (D2 (X)))
+
+/* Emit something that is 0x1fff8 bytes long, which is the largest
+ permissible range for non-MIPS16 forward branches. */
+#define OCCUPY_0x1fff8 \
+ asm (D14 ("nop") "\n\t" \
+ D13 ("nop") "\n\t" \
+ D12 ("nop") "\n\t" \
+ D11 ("nop") "\n\t" \
+ D10 ("nop") "\n\t" \
+ D9 ("nop") "\n\t" \
+ D8 ("nop") "\n\t" \
+ D7 ("nop") "\n\t" \
+ D6 ("nop") "\n\t" \
+ D5 ("nop") "\n\t" \
+ D4 ("nop") "\n\t" \
+ D3 ("nop") "\n\t" \
+ D2 ("nop") "\n\t" \
+ D1 ("nop"))
+
+/* Likewise emit something that is 0x1fffc bytes long. */
+#define OCCUPY_0x1fffc do { asm ("nop"); OCCUPY_0x1fff8; } while (0)
diff --git a/gcc/testsuite/gcc.target/powerpc/bswap64-4.c b/gcc/testsuite/gcc.target/powerpc/bswap64-4.c
new file mode 100644
index 00000000000..074780ceaa4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/bswap64-4.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-O2 -mpowerpc64" } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-final { scan-assembler-times "lwbrx" 2 } } */
+/* { dg-final { scan-assembler-times "stwbrx" 2 } } */
+
+long long swap_load (long long *a) { return __builtin_bswap64 (*a); }
+long long swap_reg (long long a) { return __builtin_bswap64 (a); }
+void swap_store (long long *a, long long b) { *a = __builtin_bswap64 (b); }
diff --git a/gcc/testsuite/gcc.target/powerpc/pr41175.c b/gcc/testsuite/gcc.target/powerpc/pr41175.c
new file mode 100644
index 00000000000..2f0137962c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr41175.c
@@ -0,0 +1,461 @@
+/* PR target/41175 */
+/* { dg-do run } */
+/* { dg-options "-Os" } */
+
+#define X2(n) X1(n##0) X1(n##1)
+#define X4(n) X2(n##0) X2(n##1)
+#define X8(n) X4(n##0) X4(n##1)
+
+#ifndef __SPE__
+#define FLOAT_REG_CONSTRAINT "f"
+#else
+#define FLOAT_REG_CONSTRAINT "r"
+#endif
+
+volatile int ll;
+
+__attribute__((noinline)) void
+foo (void)
+{
+ asm volatile ("" : : : "memory");
+}
+
+__attribute__((noinline)) void
+bar (char *p)
+{
+ asm volatile ("" : : "r" (p) : "memory");
+}
+
+__attribute__((noinline)) void
+f1 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X8(c)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(c) "=m" (mem) : : "memory");
+ foo ();
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X8(c) "m" (mem) : "memory");
+}
+
+__attribute__((noinline)) void
+f2 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X8(c)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(c) "=m" (mem) : : "memory");
+ char *pp = __builtin_alloca (ll);
+ bar (pp);
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X8(c) "m" (mem) : "memory");
+}
+
+__attribute__((noinline)) void
+f3 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X8(c)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(c) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X8(c) "m" (mem) : "memory");
+}
+
+#ifndef __NO_FPRS__
+__attribute__((noinline)) void
+f4 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X8(c)
+#undef X1
+#define X1(n) double fpr##n = 0.0;
+ X4(d)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(c) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : X4(d) "=m" (mem) : : "memory");
+ foo ();
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X8(c) "m" (mem) : "memory");
+#undef X1
+#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : : X4(d) "m" (mem) : "memory");
+}
+
+__attribute__((noinline)) void
+f5 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X8(c)
+#undef X1
+#define X1(n) double fpr##n = 0.0;
+ X4(d)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(c) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : X4(d) "=m" (mem) : : "memory");
+ char *pp = __builtin_alloca (ll);
+ bar (pp);
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X8(c) "m" (mem) : "memory");
+#undef X1
+#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : : X4(d) "m" (mem) : "memory");
+}
+
+__attribute__((noinline)) void
+f6 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X8(c)
+#undef X1
+#define X1(n) double fpr##n = 0.0;
+ X4(d)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(c) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : X4(d) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X8(c) "m" (mem) : "memory");
+#undef X1
+#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : : X4(d) "m" (mem) : "memory");
+}
+
+__attribute__((noinline)) void
+f7 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X8(c)
+#undef X1
+#define X1(n) double fpr##n = 0.0;
+ X2(d)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(c) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : X2(d) "=m" (mem) : : "memory");
+ foo ();
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X8(c) "m" (mem) : "memory");
+#undef X1
+#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : : X2(d) "m" (mem) : "memory");
+}
+
+__attribute__((noinline)) void
+f8 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X8(c)
+#undef X1
+#define X1(n) double fpr##n = 0.0;
+ X2(d)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(c) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : X2(d) "=m" (mem) : : "memory");
+ char *pp = __builtin_alloca (ll);
+ bar (pp);
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X8(c) "m" (mem) : "memory");
+#undef X1
+#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : : X2(d) "m" (mem) : "memory");
+}
+
+__attribute__((noinline)) void
+f9 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X8(c)
+#undef X1
+#define X1(n) double fpr##n = 0.0;
+ X2(d)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(c) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : X2(d) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X8(c) "m" (mem) : "memory");
+#undef X1
+#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : : X2(d) "m" (mem) : "memory");
+}
+
+__attribute__((noinline)) void
+f10 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X4(c)
+#undef X1
+#define X1(n) double fpr##n = 0.0;
+ X1(d)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X4(c) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : X1(d) "=m" (mem) : : "memory");
+ foo ();
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X4(c) "m" (mem) : "memory");
+#undef X1
+#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : : X1(d) "m" (mem) : "memory");
+}
+
+__attribute__((noinline)) void
+f11 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X4(c)
+#undef X1
+#define X1(n) double fpr##n = 0.0;
+ X1(d)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X4(c) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : X1(d) "=m" (mem) : : "memory");
+ char *pp = __builtin_alloca (ll);
+ bar (pp);
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X4(c) "m" (mem) : "memory");
+#undef X1
+#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : : X1(d) "m" (mem) : "memory");
+}
+
+__attribute__((noinline)) void
+f12 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X4(c)
+#undef X1
+#define X1(n) double fpr##n = 0.0;
+ X1(d)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X4(c) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : X1(d) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X4(c) "m" (mem) : "memory");
+#undef X1
+#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : : X1(d) "m" (mem) : "memory");
+}
+
+__attribute__((noinline)) void
+f13 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X2(c)
+#undef X1
+#define X1(n) double fpr##n = 0.0;
+ X8(d)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X2(c) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : X8(d) "=m" (mem) : : "memory");
+ foo ();
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X2(c) "m" (mem) : "memory");
+#undef X1
+#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : : X8(d) "m" (mem) : "memory");
+}
+
+__attribute__((noinline)) void
+f14 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X2(c)
+#undef X1
+#define X1(n) double fpr##n = 0.0;
+ X8(d)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X2(c) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : X8(d) "=m" (mem) : : "memory");
+ char *pp = __builtin_alloca (ll);
+ bar (pp);
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X2(c) "m" (mem) : "memory");
+#undef X1
+#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : : X8(d) "m" (mem) : "memory");
+}
+
+__attribute__((noinline)) void
+f15 (void)
+{
+ int mem;
+#undef X1
+#define X1(n) int gpr##n = 0;
+ X8(a) X8(b) X2(c)
+#undef X1
+#define X1(n) double fpr##n = 0.0;
+ X8(d)
+#undef X1
+#define X1(n) "+r" (gpr##n),
+ asm volatile ("" : X8(a) "=m" (mem) : : "memory");
+ asm volatile ("" : X8(b) "=m" (mem) : : "memory");
+ asm volatile ("" : X2(c) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : X8(d) "=m" (mem) : : "memory");
+#undef X1
+#define X1(n) "r" (gpr##n),
+ asm volatile ("" : : X8(a) "m" (mem) : "memory");
+ asm volatile ("" : : X8(b) "m" (mem) : "memory");
+ asm volatile ("" : : X2(c) "m" (mem) : "memory");
+#undef X1
+#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
+ asm volatile ("" : : X8(d) "m" (mem) : "memory");
+}
+#endif
+
+int
+main ()
+{
+ ll = 60;
+ f1 ();
+ f2 ();
+ f3 ();
+#ifndef __NO_FPRS__
+ f4 ();
+ f5 ();
+ f6 ();
+ f7 ();
+ f8 ();
+ f9 ();
+ f10 ();
+ f11 ();
+ f12 ();
+ f13 ();
+ f14 ();
+ f15 ();
+#endif
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/sh/20080410-1.c b/gcc/testsuite/gcc.target/sh/20080410-1.c
index ebd783dd05d..0ba7792c078 100644
--- a/gcc/testsuite/gcc.target/sh/20080410-1.c
+++ b/gcc/testsuite/gcc.target/sh/20080410-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target "sh-*-*" } } */
-/* { dg-options "-O0 -m4 -ml -fira" } */
+/* { dg-options "-O0 -m4 -ml" } */
/* { dg-final { scan-assembler-not "add\tr0,r0" } } */
/* This test checks that chain reloads conflict. I they don't
diff --git a/gcc/testsuite/gcc.target/sh/struct-arg-dw2.c b/gcc/testsuite/gcc.target/sh/struct-arg-dw2.c
new file mode 100644
index 00000000000..effd13d19a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/struct-arg-dw2.c
@@ -0,0 +1,26 @@
+/* Verify that we don't generate fame related insn against stack adjustment
+ for the object sent partially in registers. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-g" } */
+/* { dg-final { scan-assembler-not "\t.cfi_def_cfa_offset 16" } } */
+
+typedef struct
+{
+ unsigned short A1;
+ unsigned short A2;
+} A_t;
+
+typedef struct
+{
+ A_t C13[10];
+} C_t;
+
+void
+Store (C_t Par)
+{
+ unsigned char *ptr;
+ unsigned int test;
+
+ ptr = (unsigned char*) 0x12345678;
+ ptr++;
+}
diff --git a/gcc/testsuite/gfortran.dg/allocate_alloc_opt_1.f90 b/gcc/testsuite/gfortran.dg/allocate_alloc_opt_1.f90
index cd611ccfde6..52e0262f4e6 100644
--- a/gcc/testsuite/gfortran.dg/allocate_alloc_opt_1.f90
+++ b/gcc/testsuite/gfortran.dg/allocate_alloc_opt_1.f90
@@ -26,8 +26,8 @@ program a
allocate(err) ! { dg-error "nonprocedure pointer or an allocatable" }
- allocate(error(2),stat=j,errmsg=error) ! { dg-error "shall not be ALLOCATEd within" }
- allocate(i(2), stat = i) ! { dg-error "shall not be ALLOCATEd within" }
+ allocate(error(2),stat=j,errmsg=error(1)) ! { dg-error "shall not be ALLOCATEd within" }
+ allocate(i(2), stat = i(1)) ! { dg-error "shall not be ALLOCATEd within" }
allocate(n) ! { dg-error "must be ALLOCATABLE or a POINTER" }
diff --git a/gcc/testsuite/gfortran.dg/allocate_stat_2.f90 b/gcc/testsuite/gfortran.dg/allocate_stat_2.f90
new file mode 100644
index 00000000000..7cf6d659ea2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/allocate_stat_2.f90
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! PR 41197
+program main
+ integer, dimension (4) :: ier = 0
+ character(len=30), dimension(2) :: er
+ integer, dimension (:), allocatable :: a
+ allocate (a (16), stat = ier) ! { dg-error "must be a scalar INTEGER" }
+ allocate (a (14), stat=ier(1),errmsg=er) ! { dg-error "must be a scalar CHARACTER" }
+end
+
diff --git a/gcc/testsuite/gfortran.dg/cr_lf.f90 b/gcc/testsuite/gfortran.dg/cr_lf.f90
new file mode 100644
index 00000000000..855e7036095
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/cr_lf.f90
@@ -0,0 +1,36 @@
+! { dg-do run }
+! { dg-options "-fbackslash" }
+! PR41328 and PR41168 Improper read of CR-LF sequences.
+! Test case prepared by Jerry DeLisle <jvdelisle@gcc.gnu.org>
+program main
+ implicit none
+ integer :: iostat, n_chars_read
+ character(len=1) :: buffer(64) = ""
+ open( unit=10, form="formatted", access="stream", status="scratch")
+ write(10, fmt="(a)", advance="no") "a\rb\rc\r"
+ rewind(10)
+
+ read( unit=10, fmt='(64A)', advance='NO', iostat=iostat, &
+ size=n_chars_read ) buffer
+ if (n_chars_read.ne.1) call abort
+ if (any(buffer(1:n_chars_read).ne."a")) call abort
+ if (.not.is_iostat_eor(iostat)) call abort
+
+ read( unit=10, fmt='(64A)', advance='NO', iostat=iostat, &
+ size=n_chars_read ) buffer
+ if (n_chars_read.ne.1) call abort
+ if (any(buffer(1:n_chars_read).ne."b")) call abort
+ if (.not.is_iostat_eor(iostat)) call abort
+
+ read( unit=10, fmt='(64A)', advance='NO', iostat=iostat, &
+ size=n_chars_read ) buffer
+ if (n_chars_read.ne.1) call abort
+ if (any(buffer(1:n_chars_read).ne."c")) call abort
+ if (.not.is_iostat_eor(iostat)) call abort
+
+ read( unit=10, fmt='(64A)', advance='NO', iostat=iostat, &
+ size=n_chars_read ) buffer
+ if (n_chars_read.ne.0) call abort
+ if (any(buffer(1:n_chars_read).ne."a")) call abort
+ if (.not.is_iostat_end(iostat)) call abort
+end program main
diff --git a/gcc/testsuite/gfortran.dg/deallocate_alloc_opt_1.f90 b/gcc/testsuite/gfortran.dg/deallocate_alloc_opt_1.f90
index 75da7013f30..5c00741f61c 100644
--- a/gcc/testsuite/gfortran.dg/deallocate_alloc_opt_1.f90
+++ b/gcc/testsuite/gfortran.dg/deallocate_alloc_opt_1.f90
@@ -26,8 +26,8 @@ program a
deallocate(err) ! { dg-error "nonprocedure pointer or an allocatable" }
- deallocate(error,stat=j,errmsg=error) ! { dg-error "shall not be DEALLOCATEd within" }
- deallocate(i, stat = i) ! { dg-error "shall not be DEALLOCATEd within" }
+ deallocate(error,stat=j,errmsg=error(1)) ! { dg-error "shall not be DEALLOCATEd within" }
+ deallocate(i, stat = i(1)) ! { dg-error "shall not be DEALLOCATEd within" }
deallocate(n) ! { dg-error "must be ALLOCATABLE or a POINTER" }
diff --git a/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 b/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90
index debc113ffc1..9709c508c50 100644
--- a/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90
+++ b/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90
@@ -1,4 +1,4 @@
-! { dg-do run { xfail alpha*-*-* *-*-darwin[89]* *-*-freebsd* *-*-mingw* *-*-cygwin* spu-*-* } }
+! { dg-do run { xfail *-*-darwin[89]* *-*-freebsd* *-*-mingw* *-*-cygwin* spu-*-* } }
! Test XFAILed on these platforms because the system's printf() lacks
! proper support for denormals.
!
@@ -6,6 +6,8 @@
! wide enough and have enough precision, by checking that values can
! be written and read back.
!
+! { dg-add-options ieee }
+
include "default_format_1.inc"
program main
diff --git a/gcc/testsuite/gfortran.dg/default_format_denormal_2.f90 b/gcc/testsuite/gfortran.dg/default_format_denormal_2.f90
index 0ae32f8cb60..ae2f71f42e7 100644
--- a/gcc/testsuite/gfortran.dg/default_format_denormal_2.f90
+++ b/gcc/testsuite/gfortran.dg/default_format_denormal_2.f90
@@ -7,6 +7,8 @@
! wide enough and have enough precision, by checking that values can
! be written and read back.
!
+! { dg-add-options ieee }
+
include "default_format_2.inc"
program main
diff --git a/gcc/testsuite/gfortran.dg/generic_14.f90 b/gcc/testsuite/gfortran.dg/generic_14.f90
index 3198da1dafc..e95f6f2edeb 100644
--- a/gcc/testsuite/gfortran.dg/generic_14.f90
+++ b/gcc/testsuite/gfortran.dg/generic_14.f90
@@ -85,18 +85,18 @@ end module f
module g
implicit none
- external wrong_b ! { dg-error "has no explicit interface" }
+ external wrong_b
interface gen_wrong_5
- module procedure wrong_b ! wrong, see above
+ module procedure wrong_b ! { dg-error "has no explicit interface" }
end interface gen_wrong_5
end module g
module h
implicit none
- external wrong_c ! { dg-error "has no explicit interface" }
+ external wrong_c
real wrong_c
interface gen_wrong_6
- module procedure wrong_c ! wrong, see above
+ module procedure wrong_c ! { dg-error "has no explicit interface" }
end interface gen_wrong_6
end module h
diff --git a/gcc/testsuite/gfortran.dg/module_procedure_1.f90 b/gcc/testsuite/gfortran.dg/module_procedure_1.f90
new file mode 100644
index 00000000000..5e1fa15c729
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/module_procedure_1.f90
@@ -0,0 +1,53 @@
+! { dg-do run }
+! Modified program from http://groups.google.com/group/\
+! comp.lang.fortran/browse_frm/thread/423e4392dc965ab7#
+!
+module myoperator
+ contains
+ function dadd(arg1,arg2)
+ integer ::dadd(2)
+ integer, intent(in) :: arg1(2), arg2(2)
+ dadd(1)=arg1(1)+arg2(1)
+ dadd(2)=arg1(2)+arg2(2)
+ end function dadd
+end module myoperator
+
+program test_interface
+
+ use myoperator
+
+ implicit none
+
+ interface operator (.myadd.)
+ module procedure dadd
+ end interface
+
+ integer input1(2), input2(2), mysum(2)
+
+ input1 = (/0,1/)
+ input2 = (/3,3/)
+ mysum = input1 .myadd. input2
+ if (mysum(1) /= 3 .and. mysum(2) /= 4) call abort
+
+ call test_sub(input1, input2)
+
+end program test_interface
+
+subroutine test_sub(input1, input2)
+
+ use myoperator
+
+ implicit none
+
+ interface operator (.myadd.)
+ module procedure dadd
+ end interface
+
+ integer, intent(in) :: input1(2), input2(2)
+ integer mysum(2)
+
+ mysum = input1 .myadd. input2
+ if (mysum(1) /= 3 .and. mysum(2) /= 4) call abort
+
+end subroutine test_sub
+! { dg-final { cleanup-modules "myoperator" } }
diff --git a/gcc/testsuite/gfortran.dg/module_procedure_2.f90 b/gcc/testsuite/gfortran.dg/module_procedure_2.f90
new file mode 100644
index 00000000000..8f6db25fb13
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/module_procedure_2.f90
@@ -0,0 +1,8 @@
+! { dg-do compile }
+program test
+ implicit none
+ intrinsic sin
+ interface gen2
+ module procedure sin ! { dg-error "cannot be a MODULE PROCEDURE" }
+ end interface gen2
+end program test
diff --git a/gcc/testsuite/gfortran.dg/namelist_59.f90 b/gcc/testsuite/gfortran.dg/namelist_59.f90
new file mode 100644
index 00000000000..bb68b9bebe9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/namelist_59.f90
@@ -0,0 +1,26 @@
+! { dg-do run }
+! PR41192 NAMELIST input with just a comment ("&NAME ! comment \") error
+program cmdline
+! comment by itself causes error in gfortran
+ call process(' ')
+ call process('i=10 , j=20 k=30 ! change all three values')
+ call process(' ')
+ call process('! change no values')! before patch this failed.
+end program cmdline
+
+subroutine process(string)
+ implicit none
+ character(len=*) :: string
+ character(len=132) :: lines(3)
+ character(len=255) :: message
+ integer :: i=1,j=2,k=3
+ integer ios
+ namelist /cmd/ i,j,k
+ save cmd
+ lines(1)='&cmd'
+ lines(2)=string
+ lines(3)='/'
+
+ read(lines,nml=cmd,iostat=ios,iomsg=message)
+ if (ios.ne.0) call abort
+end subroutine process
diff --git a/gcc/testsuite/gfortran.dg/pr41212.f90 b/gcc/testsuite/gfortran.dg/pr41212.f90
new file mode 100644
index 00000000000..4bdae6dad28
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr41212.f90
@@ -0,0 +1,34 @@
+! { dg-do run }
+! { dg-options "-O2" }
+program m
+ double precision :: y,z
+ call b(1.0d0,y,z)
+ if (ABS (z - 1.213) > 0.1) call abort
+contains
+ subroutine b( x, y, z)
+ implicit none
+ double precision :: x,y,z
+ integer :: i, k
+ double precision :: h, r
+
+ y = 1.0d0
+ z = 0.0d0
+
+ h = 0
+ DO k = 1,10
+ h = h + 1.0d0/k
+
+ r = 1
+ DO i = 1,k
+ r = (x/(2*i) ) * r
+ END DO
+
+ y = y + (-1)**k * r
+ z = z + (-1)**(k+1) * h * r
+
+ IF ( ABS(2*k/x*r) < 1d-6 ) EXIT
+ END DO
+
+ z = 2*y
+ end subroutine b
+end program m
diff --git a/gcc/testsuite/gfortran.dg/pr41225.f90 b/gcc/testsuite/gfortran.dg/pr41225.f90
new file mode 100644
index 00000000000..54daf4d1e24
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr41225.f90
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-O2 -ffast-math -funroll-loops -ftree-vectorize -g" }
+ SUBROUTINE block_15_1_1_1(kbd,kbc,kad,kac,pbd,pbc,pad,pac,prim,scale)
+ INTEGER, PARAMETER :: dp=8
+ REAL(KIND=dp) :: kbd(1*1), kbc(1*1), kad(15*1), kac(15*1), pbd(1*1), &
+ pbc(1*1), pad(15*1), pac(15*1), prim(15*1*1*1), scale
+ INTEGER :: ma, mb, mc, md, p_index
+ DO md = 1,1
+ DO mc = 1,1
+ DO mb = 1,1
+ DO ma = 1,15
+ p_index=p_index+1
+ tmp = scale*prim(p_index)
+ ks_bd = ks_bd + tmp* pac((mc-1)*15+ma)
+ END DO
+ kbd((md-1)*1+mb) = kbd((md-1)*1+mb) - ks_bd
+ END DO
+ END DO
+ END DO
+ END SUBROUTINE block_15_1_1_1
diff --git a/gcc/testsuite/gfortran.dg/pr41229.f90 b/gcc/testsuite/gfortran.dg/pr41229.f90
new file mode 100644
index 00000000000..9f6e566fc9b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr41229.f90
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! { dg-options "-O2 -g" }
+SUBROUTINE cp_fm_triangular_multiply()
+ INTEGER, PARAMETER :: dp=KIND(0.0D0)
+ REAL(dp), ALLOCATABLE, DIMENSION(:) :: tau, work
+ REAL(KIND=dp), DIMENSION(:, :), POINTER :: a
+ ndim = SIZE(a,2)
+ ALLOCATE(tau(ndim),STAT=istat)
+ ALLOCATE(work(2*ndim),STAT=istat)
+END SUBROUTINE
diff --git a/gcc/testsuite/gfortran.dg/pr41347.f90 b/gcc/testsuite/gfortran.dg/pr41347.f90
new file mode 100644
index 00000000000..ae48857d507
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr41347.f90
@@ -0,0 +1,32 @@
+! { dg-do compile }
+! { dg-options "-O3" }
+module hsl_ma41_m
+
+ implicit none
+
+ contains
+
+ subroutine solve_ma41
+ integer, dimension(20) :: info
+ call prininfo(15, info)
+ end subroutine solve_ma41
+
+ subroutine prininfo (ni, info)
+ integer, intent(in) :: ni
+ integer, intent(in), dimension(:) :: info
+
+ integer i
+
+ call prinfo
+
+ contains
+
+ subroutine prinfo
+ do i = 1, ni
+ write(*,'(i5,1x,i0)') i, info(i)
+ end do
+ end subroutine prinfo
+
+ end subroutine prininfo
+
+end module hsl_ma41_m
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_comp_21.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_comp_21.f90
new file mode 100644
index 00000000000..c000896d549
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_comp_21.f90
@@ -0,0 +1,28 @@
+! { dg-do compile }
+!
+! PR 41242: [4.5 Regression] PPC call rejected (related to user-defined assignment?)
+!
+! Original test case by Juergen Reuter <reuter@physik.uni-freiburg.de>
+! Modified by Janus Weil <janus@gcc.gnu.org>
+
+ type :: nf_t
+ procedure(integer), nopass, pointer :: get_n_in
+ end type
+
+ interface assignment(=)
+ procedure op_assign
+ end interface
+
+ type(nf_t) :: prc_lib
+ prc_lib = "foobar"
+ print *, prc_lib%get_n_in()
+
+contains
+
+ elemental subroutine op_assign (str, ch)
+ type(nf_t), intent(out) :: str
+ character(len=*), intent(in) :: ch
+ end subroutine
+
+end
+
diff --git a/gcc/testsuite/gfortran.dg/typebound_proc_12.f90 b/gcc/testsuite/gfortran.dg/typebound_proc_12.f90
new file mode 100644
index 00000000000..4612d4982f3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/typebound_proc_12.f90
@@ -0,0 +1,12 @@
+! { dg-do compile }
+! Test the fix for PR41258, where an ICE was caused by a search
+! for a typebound procedure to resolve d%c%e
+!
+! Contributed by Joost VandeVondele <jv244@cam.ac.uk>
+!
+ TYPE a
+ TYPE(b), DIMENSION(:), POINTER :: c ! { dg-error "type that has not been declared" }
+ END TYPE
+ TYPE(a), POINTER :: d
+ CALL X(d%c%e) ! { dg-error "before it is defined" }
+end
diff --git a/gcc/testsuite/gnat.dg/alignment9.adb b/gcc/testsuite/gnat.dg/alignment9.adb
new file mode 100644
index 00000000000..ae7a7f67e9e
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/alignment9.adb
@@ -0,0 +1,30 @@
+-- { dg-do run }
+-- { dg-options "-gnatws" }
+
+procedure Alignment9 is
+
+ type Kind is (Small, Large);
+ for Kind'Size use 8;
+
+ type Header is
+ record
+ K : Kind;
+ I : Integer;
+ end record;
+
+ for Header use
+ record
+ K at 4 range 0..7;
+ I at 0 range 0..31;
+ end record;
+
+ for Header'Size use 5*8;
+ for Header'Alignment use 1;
+
+ H : Header;
+
+begin
+ if H'Size /= 40 then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/array8.adb b/gcc/testsuite/gnat.dg/array8.adb
new file mode 100644
index 00000000000..6e18ecadf94
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/array8.adb
@@ -0,0 +1,34 @@
+-- { dg-do compile }
+-- { dg-options "-O2" }
+
+PROCEDURE Array8 IS
+
+ function ID (I : Integer) return Integer is
+ begin
+ return I;
+ end;
+
+ SUBTYPE STB IS INTEGER RANGE ID(-8) .. -5;
+
+ TYPE TB IS ARRAY (STB RANGE <>) OF INTEGER;
+
+ GENERIC
+ B1 : TB;
+ PROCEDURE PROC1;
+
+ PROCEDURE PROC1 IS
+ BEGIN
+ IF B1'FIRST /= -8 THEN
+ raise Program_Error;
+ ELSIF B1'LAST /= ID(-5) THEN
+ raise Program_Error;
+ ELSIF B1 /= (7, 6, 5, 4) THEN
+ raise Program_Error;
+ END IF;
+ END;
+
+ PROCEDURE PROC2 IS NEW PROC1 ((7, 6, ID(5), 4));
+
+BEGIN
+ PROC2;
+END;
diff --git a/gcc/testsuite/gnat.dg/discr20.adb b/gcc/testsuite/gnat.dg/discr20.adb
new file mode 100644
index 00000000000..358d5654058
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/discr20.adb
@@ -0,0 +1,10 @@
+-- { dg-do compile }
+
+package body Discr20 is
+
+ function Get (X : Wrapper) return Def is
+ begin
+ return X.It;
+ end Get;
+
+end Discr20;
diff --git a/gcc/testsuite/gnat.dg/discr20.ads b/gcc/testsuite/gnat.dg/discr20.ads
new file mode 100644
index 00000000000..a447b3309c3
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/discr20.ads
@@ -0,0 +1,31 @@
+package Discr20 is
+
+ Size : Integer;
+
+ type Name is new String (1..Size);
+
+ type Rec is record
+ It : Name;
+ end record;
+
+ type Danger is (This, That);
+ type def (X : Danger := This) is record
+ case X is
+ when This => It : Rec;
+ when That => null;
+ end case;
+ end record;
+
+ type Switch is (On, Off);
+ type Wrapper (Disc : Switch := On) is private;
+ function Get (X : Wrapper) return Def;
+
+private
+ type Wrapper (Disc : Switch := On) is record
+ Case Disc is
+ when On => It : Def;
+ when Off => null;
+ end case;
+ end record;
+
+end Discr20;
diff --git a/gcc/timevar.def b/gcc/timevar.def
index 7e3d702dd5a..92f280d4a73 100644
--- a/gcc/timevar.def
+++ b/gcc/timevar.def
@@ -46,6 +46,7 @@ DEFTIMEVAR (TV_IPA_REFERENCE , "ipa reference")
DEFTIMEVAR (TV_IPA_PURE_CONST , "ipa pure const")
DEFTIMEVAR (TV_IPA_TYPE_ESCAPE , "ipa type escape")
DEFTIMEVAR (TV_IPA_PTA , "ipa points-to")
+DEFTIMEVAR (TV_IPA_SRA , "ipa SRA")
DEFTIMEVAR (TV_IPA_FREE_LANG_DATA , "ipa free lang data")
/* Time spent by constructing CFG. */
DEFTIMEVAR (TV_CFG , "cfg construction")
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 1a546d13f5f..8aa6f468192 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -720,7 +720,7 @@ output_file_directive (FILE *asm_file, const char *input_name)
#else
fprintf (asm_file, "\t.file\t");
output_quoted_string (asm_file, na);
- fputc ('\n', asm_file);
+ putc ('\n', asm_file);
#endif
}
@@ -1283,7 +1283,7 @@ print_to_asm_out_file (print_switch_type type, const char * text)
case SWITCH_TYPE_ENABLED:
if (prepend_sep)
fputc (' ', asm_out_file);
- fprintf (asm_out_file, text);
+ fputs (text, asm_out_file);
/* No need to return the length here as
print_single_switch has already done it. */
return 0;
@@ -1312,7 +1312,7 @@ print_to_stderr (print_switch_type type, const char * text)
/* Drop through. */
case SWITCH_TYPE_DESCRIPTIVE:
- fprintf (stderr, text);
+ fputs (text, stderr);
/* No need to return the length here as
print_single_switch has already done it. */
return 0;
@@ -1472,7 +1472,7 @@ init_asm_output (const char *name)
into the assembler file as comments. */
print_version (asm_out_file, ASM_COMMENT_START);
print_switch_values (print_to_asm_out_file);
- fprintf (asm_out_file, "\n");
+ putc ('\n', asm_out_file);
}
#endif
}
@@ -1895,7 +1895,12 @@ process_options (void)
if (flag_gtoggle)
{
if (debug_info_level == DINFO_LEVEL_NONE)
- debug_info_level = DINFO_LEVEL_NORMAL;
+ {
+ debug_info_level = DINFO_LEVEL_NORMAL;
+
+ if (write_symbols == NO_DEBUG)
+ write_symbols = PREFERRED_DEBUGGING_TYPE;
+ }
else
debug_info_level = DINFO_LEVEL_NONE;
}
@@ -1994,15 +1999,18 @@ process_options (void)
flag_var_tracking_uninit = 0;
}
- if (flag_rename_registers == AUTODETECT_VALUE)
- flag_rename_registers = default_debug_hooks->var_location
- != do_nothing_debug_hooks.var_location;
+ /* If the user specifically requested variable tracking with tagging
+ uninitialized variables, we need to turn on variable tracking.
+ (We already determined above that variable tracking is feasible.) */
+ if (flag_var_tracking_uninit)
+ flag_var_tracking = 1;
if (flag_var_tracking == AUTODETECT_VALUE)
flag_var_tracking = optimize >= 1;
if (flag_var_tracking_assignments == AUTODETECT_VALUE)
- flag_var_tracking_assignments = flag_var_tracking;
+ flag_var_tracking_assignments = flag_var_tracking
+ && !(flag_selective_scheduling || flag_selective_scheduling2);
if (flag_var_tracking_assignments_toggle)
flag_var_tracking_assignments = !flag_var_tracking_assignments;
@@ -2010,6 +2018,14 @@ process_options (void)
if (flag_var_tracking_assignments && !flag_var_tracking)
flag_var_tracking = flag_var_tracking_assignments = -1;
+ if (flag_var_tracking_assignments
+ && (flag_selective_scheduling || flag_selective_scheduling2))
+ warning (0, "var-tracking-assignments changes selective scheduling");
+
+ if (flag_rename_registers == AUTODETECT_VALUE)
+ flag_rename_registers = default_debug_hooks->var_location
+ != do_nothing_debug_hooks.var_location;
+
if (flag_tree_cselim == AUTODETECT_VALUE)
#ifdef HAVE_conditional_move
flag_tree_cselim = 1;
@@ -2017,12 +2033,6 @@ process_options (void)
flag_tree_cselim = 0;
#endif
- /* If the user specifically requested variable tracking with tagging
- uninitialized variables, we need to turn on variable tracking.
- (We already determined above that variable tracking is feasible.) */
- if (flag_var_tracking_uninit)
- flag_var_tracking = 1;
-
/* If auxiliary info generation is desired, open the output file.
This goes in the same directory as the source file--unlike
all the other output files. */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 50f96da83a1..8de62e3d534 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -99,6 +99,7 @@ static void make_edges (void);
static void make_cond_expr_edges (basic_block);
static void make_gimple_switch_edges (basic_block);
static void make_goto_expr_edges (basic_block);
+static void make_gimple_asm_edges (basic_block);
static unsigned int locus_map_hash (const void *);
static int locus_map_eq (const void *, const void *);
static void assign_discriminator (location_t, basic_block);
@@ -545,6 +546,9 @@ make_edges (void)
make_eh_edges (last);
fallthru = false;
break;
+ case GIMPLE_EH_DISPATCH:
+ fallthru = make_eh_dispatch_edges (last);
+ break;
case GIMPLE_CALL:
/* If this function receives a nonlocal goto, then we need to
@@ -565,9 +569,12 @@ make_edges (void)
/* A GIMPLE_ASSIGN may throw internally and thus be considered
control-altering. */
if (is_ctrl_altering_stmt (last))
- {
- make_eh_edges (last);
- }
+ make_eh_edges (last);
+ fallthru = true;
+ break;
+
+ case GIMPLE_ASM:
+ make_gimple_asm_edges (bb);
fallthru = true;
break;
@@ -592,13 +599,11 @@ make_edges (void)
fallthru = false;
break;
-
case GIMPLE_OMP_ATOMIC_LOAD:
case GIMPLE_OMP_ATOMIC_STORE:
fallthru = true;
break;
-
case GIMPLE_OMP_RETURN:
/* In the case of a GIMPLE_OMP_SECTION, the edge will go
somewhere other than the next block. This will be
@@ -1010,6 +1015,23 @@ make_goto_expr_edges (basic_block bb)
make_abnormal_goto_edges (bb, false);
}
+/* Create edges for an asm statement with labels at block BB. */
+
+static void
+make_gimple_asm_edges (basic_block bb)
+{
+ gimple stmt = last_stmt (bb);
+ location_t stmt_loc = gimple_location (stmt);
+ int i, n = gimple_asm_nlabels (stmt);
+
+ for (i = 0; i < n; ++i)
+ {
+ tree label = TREE_VALUE (gimple_asm_label_op (stmt, i));
+ basic_block label_bb = label_to_block (label);
+ make_edge (bb, label_bb, 0);
+ assign_discriminator (stmt_loc, label_bb);
+ }
+}
/*---------------------------------------------------------------------------
Flowgraph analysis
@@ -1033,29 +1055,6 @@ static struct label_record
bool used;
} *label_for_bb;
-/* Callback for for_each_eh_region. Helper for cleanup_dead_labels. */
-static void
-update_eh_label (struct eh_region_d *region)
-{
- tree old_label = get_eh_region_tree_label (region);
- if (old_label)
- {
- tree new_label;
- basic_block bb = label_to_block (old_label);
-
- /* ??? After optimizing, there may be EH regions with labels
- that have already been removed from the function body, so
- there is no basic block for them. */
- if (! bb)
- return;
-
- new_label = label_for_bb[bb->index].label;
- label_for_bb[bb->index].used = true;
- set_eh_region_tree_label (region, new_label);
- }
-}
-
-
/* Given LABEL return the first label in the same basic block. */
static tree
@@ -1075,6 +1074,58 @@ main_block_label (tree label)
return main_label;
}
+/* Clean up redundant labels within the exception tree. */
+
+static void
+cleanup_dead_labels_eh (void)
+{
+ eh_landing_pad lp;
+ eh_region r;
+ tree lab;
+ int i;
+
+ if (cfun->eh == NULL)
+ return;
+
+ for (i = 1; VEC_iterate (eh_landing_pad, cfun->eh->lp_array, i, lp); ++i)
+ if (lp && lp->post_landing_pad)
+ {
+ lab = main_block_label (lp->post_landing_pad);
+ if (lab != lp->post_landing_pad)
+ {
+ EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
+ EH_LANDING_PAD_NR (lab) = lp->index;
+ }
+ }
+
+ FOR_ALL_EH_REGION (r)
+ switch (r->type)
+ {
+ case ERT_CLEANUP:
+ case ERT_MUST_NOT_THROW:
+ break;
+
+ case ERT_TRY:
+ {
+ eh_catch c;
+ for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
+ {
+ lab = c->label;
+ if (lab)
+ c->label = main_block_label (lab);
+ }
+ }
+ break;
+
+ case ERT_ALLOWED_EXCEPTIONS:
+ lab = r->u.allowed.label;
+ if (lab)
+ r->u.allowed.label = main_block_label (lab);
+ break;
+ }
+}
+
+
/* Cleanup redundant labels. This is a three-step process:
1) Find the leading label for each block.
2) Redirect all references to labels to the leading labels.
@@ -1158,6 +1209,19 @@ cleanup_dead_labels (void)
break;
}
+ case GIMPLE_ASM:
+ {
+ int i, n = gimple_asm_nlabels (stmt);
+
+ for (i = 0; i < n; ++i)
+ {
+ tree cons = gimple_asm_label_op (stmt, i);
+ tree label = main_block_label (TREE_VALUE (cons));
+ TREE_VALUE (cons) = label;
+ }
+ break;
+ }
+
/* We have to handle gotos until they're removed, and we don't
remove them until after we've created the CFG edges. */
case GIMPLE_GOTO:
@@ -1165,15 +1229,16 @@ cleanup_dead_labels (void)
{
tree new_dest = main_block_label (gimple_goto_dest (stmt));
gimple_goto_set_dest (stmt, new_dest);
- break;
}
+ break;
default:
break;
}
}
- for_each_eh_region (update_eh_label);
+ /* Do the same for the exception region tree labels. */
+ cleanup_dead_labels_eh ();
/* Finally, purge dead labels. All user-defined labels and labels that
can be the target of non-local gotos and labels which have their
@@ -1354,6 +1419,24 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b)
&& DECL_NONLOCAL (gimple_label_label (stmt)))
return false;
+ /* Examine the labels at the beginning of B. */
+ for (gsi = gsi_start_bb (b); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ tree lab;
+ stmt = gsi_stmt (gsi);
+ if (gimple_code (stmt) != GIMPLE_LABEL)
+ break;
+ lab = gimple_label_label (stmt);
+
+ /* Do not remove user labels. */
+ if (!DECL_ARTIFICIAL (lab))
+ return false;
+ }
+
+ /* Protect the loop latches. */
+ if (current_loops && b->loop_father->latch == b)
+ return false;
+
/* It must be possible to eliminate all phi nodes in B. If ssa form
is not up-to-date, we cannot eliminate any phis; however, if only
some symbols as whole are marked for renaming, this is not a problem,
@@ -1377,21 +1460,6 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b)
}
}
- /* Do not remove user labels. */
- for (gsi = gsi_start_bb (b); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- stmt = gsi_stmt (gsi);
- if (gimple_code (stmt) != GIMPLE_LABEL)
- break;
- if (!DECL_ARTIFICIAL (gimple_label_label (stmt)))
- return false;
- }
-
- /* Protect the loop latches. */
- if (current_loops
- && b->loop_father->latch == b)
- return false;
-
return true;
}
@@ -1581,9 +1649,11 @@ gimple_merge_blocks (basic_block a, basic_block b)
/* Remove labels from B and set gimple_bb to A for other statements. */
for (gsi = gsi_start_bb (b); !gsi_end_p (gsi);)
{
- if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
+ gimple stmt = gsi_stmt (gsi);
+ if (gimple_code (stmt) == GIMPLE_LABEL)
{
- gimple label = gsi_stmt (gsi);
+ tree label = gimple_label_label (stmt);
+ int lp_nr;
gsi_remove (&gsi, false);
@@ -1593,15 +1663,22 @@ gimple_merge_blocks (basic_block a, basic_block b)
used in other ways (think about the runtime checking for
Fortran assigned gotos). So we can not just delete the
label. Instead we move the label to the start of block A. */
- if (FORCED_LABEL (gimple_label_label (label)))
+ if (FORCED_LABEL (label))
{
gimple_stmt_iterator dest_gsi = gsi_start_bb (a);
- gsi_insert_before (&dest_gsi, label, GSI_NEW_STMT);
+ gsi_insert_before (&dest_gsi, stmt, GSI_NEW_STMT);
+ }
+
+ lp_nr = EH_LANDING_PAD_NR (label);
+ if (lp_nr)
+ {
+ eh_landing_pad lp = get_eh_landing_pad_from_number (lp_nr);
+ lp->post_landing_pad = NULL;
}
}
else
{
- gimple_set_bb (gsi_stmt (gsi), a);
+ gimple_set_bb (stmt, a);
gsi_next (&gsi);
}
}
@@ -1914,10 +1991,7 @@ remove_useless_stmts_tc (gimple_stmt_iterator *gsi, struct rus_data *data)
break;
case GIMPLE_EH_FILTER:
- /* If the first element is an eh_filter, it should stand alone. */
- if (gimple_eh_filter_must_not_throw (stmt))
- this_may_throw = false;
- else if (gimple_eh_filter_types (stmt) == NULL)
+ if (gimple_eh_filter_types (stmt) == NULL)
this_may_throw = false;
failure_seq = gimple_eh_filter_failure (stmt);
failure_gsi = gsi_start (failure_seq);
@@ -1925,6 +1999,10 @@ remove_useless_stmts_tc (gimple_stmt_iterator *gsi, struct rus_data *data)
gsi_next (gsi);
break;
+ case GIMPLE_EH_MUST_NOT_THROW:
+ this_may_throw = false;
+ break;
+
default:
/* Otherwise this is a list of cleanup statements. */
remove_useless_stmts_1 (&cleanup_gsi, data);
@@ -2732,11 +2810,17 @@ gimple_cfg2vcg (FILE *file)
bool
is_ctrl_stmt (gimple t)
{
- return gimple_code (t) == GIMPLE_COND
- || gimple_code (t) == GIMPLE_SWITCH
- || gimple_code (t) == GIMPLE_GOTO
- || gimple_code (t) == GIMPLE_RETURN
- || gimple_code (t) == GIMPLE_RESX;
+ switch (gimple_code (t))
+ {
+ case GIMPLE_COND:
+ case GIMPLE_SWITCH:
+ case GIMPLE_GOTO:
+ case GIMPLE_RETURN:
+ case GIMPLE_RESX:
+ return true;
+ default:
+ return false;
+ }
}
@@ -2748,24 +2832,41 @@ is_ctrl_altering_stmt (gimple t)
{
gcc_assert (t);
- if (is_gimple_call (t))
+ switch (gimple_code (t))
{
- int flags = gimple_call_flags (t);
+ case GIMPLE_CALL:
+ {
+ int flags = gimple_call_flags (t);
- /* A non-pure/const call alters flow control if the current
- function has nonlocal labels. */
- if (!(flags & (ECF_CONST | ECF_PURE))
- && cfun->has_nonlocal_label)
- return true;
+ /* A non-pure/const call alters flow control if the current
+ function has nonlocal labels. */
+ if (!(flags & (ECF_CONST | ECF_PURE)) && cfun->has_nonlocal_label)
+ return true;
+
+ /* A call also alters control flow if it does not return. */
+ if (gimple_call_flags (t) & ECF_NORETURN)
+ return true;
+ }
+ break;
+
+ case GIMPLE_EH_DISPATCH:
+ /* EH_DISPATCH branches to the individual catch handlers at
+ this level of a try or allowed-exceptions region. It can
+ fallthru to the next statement as well. */
+ return true;
- /* A call also alters control flow if it does not return. */
- if (gimple_call_flags (t) & ECF_NORETURN)
+ case GIMPLE_ASM:
+ if (gimple_asm_nlabels (t) > 0)
return true;
- }
+ break;
- /* OpenMP directives alter control flow. */
- if (is_gimple_omp (t))
- return true;
+ CASE_GIMPLE_OMP:
+ /* OpenMP directives alter control flow. */
+ return true;
+
+ default:
+ break;
+ }
/* If a statement can throw, it alters control flow. */
return stmt_can_throw_internal (t);
@@ -2966,11 +3067,15 @@ static basic_block
split_edge_bb_loc (edge edge_in)
{
basic_block dest = edge_in->dest;
+ basic_block dest_prev = dest->prev_bb;
- if (dest->prev_bb && find_edge (dest->prev_bb, dest))
- return edge_in->src;
- else
- return dest->prev_bb;
+ if (dest_prev)
+ {
+ edge e = find_edge (dest_prev, dest);
+ if (e && !(e->flags & EDGE_COMPLEX))
+ return edge_in->src;
+ }
+ return dest_prev;
}
/* Split a (typically critical) edge EDGE_IN. Return the new block.
@@ -3470,6 +3575,25 @@ verify_gimple_call (gimple stmt)
return true;
}
+ /* If there is a static chain argument, this should not be an indirect
+ call, and the decl should not have DECL_NO_STATIC_CHAIN set. */
+ if (gimple_call_chain (stmt))
+ {
+ if (TREE_CODE (fn) != ADDR_EXPR
+ || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
+ {
+ error ("static chain in indirect gimple call");
+ return true;
+ }
+ fn = TREE_OPERAND (fn, 0);
+
+ if (DECL_NO_STATIC_CHAIN (fn))
+ {
+ error ("static chain with function that doesn't use one");
+ return true;
+ }
+ }
+
/* ??? The C frontend passes unpromoted arguments in case it
didn't see a function declaration before the call. So for now
leave the call arguments unverified. Once we gimplify
@@ -4024,8 +4148,6 @@ verify_gimple_assign_single (gimple stmt)
case OBJ_TYPE_REF:
case ASSERT_EXPR:
case WITH_SIZE_EXPR:
- case EXC_PTR_EXPR:
- case FILTER_EXPR:
case POLYNOMIAL_CHREC:
case DOT_PROD_EXPR:
case VEC_COND_EXPR:
@@ -4148,7 +4270,7 @@ verify_gimple_phi (gimple stmt)
tree type = TREE_TYPE (gimple_phi_result (stmt));
unsigned i;
- if (!is_gimple_variable (gimple_phi_result (stmt)))
+ if (TREE_CODE (gimple_phi_result (stmt)) != SSA_NAME)
{
error ("Invalid PHI result");
return true;
@@ -4201,17 +4323,6 @@ verify_gimple_debug (gimple stmt ATTRIBUTE_UNUSED)
static bool
verify_types_in_gimple_stmt (gimple stmt)
{
- if (is_gimple_omp (stmt))
- {
- /* OpenMP directives are validated by the FE and never operated
- on by the optimizers. Furthermore, GIMPLE_OMP_FOR may contain
- non-gimple expressions when the main index variable has had
- its address taken. This does not affect the loop itself
- because the header of an GIMPLE_OMP_FOR is merely used to determine
- how to setup the parallel iteration. */
- return false;
- }
-
switch (gimple_code (stmt))
{
case GIMPLE_ASSIGN:
@@ -4245,8 +4356,18 @@ verify_types_in_gimple_stmt (gimple stmt)
/* Tuples that do not have tree operands. */
case GIMPLE_NOP:
- case GIMPLE_RESX:
case GIMPLE_PREDICT:
+ case GIMPLE_RESX:
+ case GIMPLE_EH_DISPATCH:
+ return false;
+
+ CASE_GIMPLE_OMP:
+ /* OpenMP directives are validated by the FE and never operated
+ on by the optimizers. Furthermore, GIMPLE_OMP_FOR may contain
+ non-gimple expressions when the main index variable has had
+ its address taken. This does not affect the loop itself
+ because the header of an GIMPLE_OMP_FOR is merely used to determine
+ how to setup the parallel iteration. */
return false;
case GIMPLE_DEBUG:
@@ -4322,6 +4443,7 @@ verify_stmt (gimple_stmt_iterator *gsi)
struct walk_stmt_info wi;
bool last_in_block = gsi_one_before_end_p (*gsi);
gimple stmt = gsi_stmt (*gsi);
+ int lp_nr;
if (is_gimple_omp (stmt))
{
@@ -4376,17 +4498,21 @@ verify_stmt (gimple_stmt_iterator *gsi)
have optimizations that simplify statements such that we prove
that they cannot throw, that we update other data structures
to match. */
- if (lookup_stmt_eh_region (stmt) >= 0)
+ lp_nr = lookup_stmt_eh_lp (stmt);
+ if (lp_nr != 0)
{
- /* During IPA passes, ipa-pure-const sets nothrow flags on calls
- and they are updated on statements only after fixup_cfg
- is executed at beggining of expansion stage. */
- if (!stmt_could_throw_p (stmt) && cgraph_state != CGRAPH_STATE_IPA_SSA)
+ if (!stmt_could_throw_p (stmt))
{
- error ("statement marked for throw, but doesn%'t");
- goto fail;
+ /* During IPA passes, ipa-pure-const sets nothrow flags on calls
+ and they are updated on statements only after fixup_cfg
+ is executed at beggining of expansion stage. */
+ if (cgraph_state != CGRAPH_STATE_IPA_SSA)
+ {
+ error ("statement marked for throw, but doesn%'t");
+ goto fail;
+ }
}
- if (!last_in_block && stmt_can_throw_internal (stmt))
+ else if (lp_nr > 0 && !last_in_block && stmt_can_throw_internal (stmt))
{
error ("statement marked for throw in middle of block");
goto fail;
@@ -4574,9 +4700,20 @@ verify_stmts (void)
if (uid == -1
|| VEC_index (basic_block, label_to_block_map, uid) != bb)
{
- error ("incorrect entry in label_to_block_map.\n");
+ error ("incorrect entry in label_to_block_map");
err |= true;
}
+
+ uid = EH_LANDING_PAD_NR (decl);
+ if (uid)
+ {
+ eh_landing_pad lp = get_eh_landing_pad_from_number (uid);
+ if (decl != lp->post_landing_pad)
+ {
+ error ("incorrect setting of landing pad number");
+ err |= true;
+ }
+ }
}
err |= verify_stmt (&gsi);
@@ -4723,6 +4860,9 @@ gimple_verify_flow_info (void)
stmt = gsi_stmt (gsi);
+ if (gimple_code (stmt) == GIMPLE_LABEL)
+ continue;
+
/* FIXME: there does seem to be an overassertion in eh
edge verification -- triggered by -fdyn-ipa: after eh
cleanup, there might not be an direct edge from a BB
@@ -4898,8 +5038,14 @@ gimple_verify_flow_info (void)
FOR_EACH_EDGE (e, ei, bb->succs)
e->dest->aux = (void *)0;
}
+ break;
+
+ case GIMPLE_EH_DISPATCH:
+ err |= verify_eh_dispatch_edge (stmt);
+ break;
- default: ;
+ default:
+ break;
}
}
@@ -5039,16 +5185,19 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
if (e->flags & EDGE_ABNORMAL)
return NULL;
- if (e->src != ENTRY_BLOCK_PTR
- && (ret = gimple_try_redirect_by_replacing_jump (e, dest)))
- return ret;
-
if (e->dest == dest)
return NULL;
if (e->flags & EDGE_EH)
return redirect_eh_edge (e, dest);
+ if (e->src != ENTRY_BLOCK_PTR)
+ {
+ ret = gimple_try_redirect_by_replacing_jump (e, dest);
+ if (ret)
+ return ret;
+ }
+
gsi = gsi_last_bb (bb);
stmt = gsi_end_p (gsi) ? NULL : gsi_stmt (gsi);
@@ -5104,9 +5253,22 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
CASE_LABEL (elt) = label;
}
}
+ }
+ break;
- break;
+ case GIMPLE_ASM:
+ {
+ int i, n = gimple_asm_nlabels (stmt);
+ tree label = gimple_block_label (dest);
+
+ for (i = 0; i < n; ++i)
+ {
+ tree cons = gimple_asm_label_op (stmt, i);
+ if (label_to_block (TREE_VALUE (cons)) == e->dest)
+ TREE_VALUE (cons) = label;
+ }
}
+ break;
case GIMPLE_RETURN:
gsi_remove (&gsi, true);
@@ -5120,6 +5282,11 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
/* The edges from OMP constructs can be simply redirected. */
break;
+ case GIMPLE_EH_DISPATCH:
+ if (!(e->flags & EDGE_FALLTHRU))
+ redirect_eh_dispatch_edge (stmt, e, dest);
+ break;
+
default:
/* Otherwise it must be a fallthru edge, and we don't need to
do anything besides redirecting it. */
@@ -5269,7 +5436,6 @@ gimple_duplicate_bb (basic_block bb)
{
def_operand_p def_p;
ssa_op_iter op_iter;
- int region;
stmt = gsi_stmt (gsi);
if (gimple_code (stmt) == GIMPLE_LABEL)
@@ -5279,9 +5445,8 @@ gimple_duplicate_bb (basic_block bb)
operands. */
copy = gimple_copy (stmt);
gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);
- region = lookup_stmt_eh_region (stmt);
- if (region >= 0)
- add_stmt_to_eh_region (copy, region);
+
+ maybe_duplicate_eh_stmt (copy, stmt);
gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt);
/* Create new names for all the definitions created by COPY and
@@ -5809,6 +5974,7 @@ struct move_stmt_d
tree to_context;
struct pointer_map_t *vars_map;
htab_t new_label_map;
+ struct pointer_map_t *eh_map;
bool remap_decls_p;
};
@@ -5874,6 +6040,35 @@ move_stmt_op (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE;
}
+/* Helper for move_stmt_r. Given an EH region number for the source
+ function, map that to the duplicate EH regio number in the dest. */
+
+static int
+move_stmt_eh_region_nr (int old_nr, struct move_stmt_d *p)
+{
+ eh_region old_r, new_r;
+ void **slot;
+
+ old_r = get_eh_region_from_number (old_nr);
+ slot = pointer_map_contains (p->eh_map, old_r);
+ new_r = (eh_region) *slot;
+
+ return new_r->index;
+}
+
+/* Similar, but operate on INTEGER_CSTs. */
+
+static tree
+move_stmt_eh_region_tree_nr (tree old_t_nr, struct move_stmt_d *p)
+{
+ int old_nr, new_nr;
+
+ old_nr = tree_low_cst (old_t_nr, 0);
+ new_nr = move_stmt_eh_region_nr (old_nr, p);
+
+ return build_int_cst (NULL, new_nr);
+}
+
/* Like move_stmt_op, but for gimple statements.
Helper for move_block_to_fn. Set GIMPLE_BLOCK in every expression
@@ -5902,21 +6097,70 @@ move_stmt_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
}
#endif
- if (is_gimple_omp (stmt)
- && gimple_code (stmt) != GIMPLE_OMP_RETURN
- && gimple_code (stmt) != GIMPLE_OMP_CONTINUE)
+ switch (gimple_code (stmt))
{
- /* Do not remap variables inside OMP directives. Variables
- referenced in clauses and directive header belong to the
- parent function and should not be moved into the child
- function. */
- bool save_remap_decls_p = p->remap_decls_p;
- p->remap_decls_p = false;
- *handled_ops_p = true;
+ case GIMPLE_CALL:
+ /* Remap the region numbers for __builtin_eh_{pointer,filter}. */
+ {
+ tree r, fndecl = gimple_call_fndecl (stmt);
+ if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_EH_COPY_VALUES:
+ r = gimple_call_arg (stmt, 1);
+ r = move_stmt_eh_region_tree_nr (r, p);
+ gimple_call_set_arg (stmt, 1, r);
+ /* FALLTHRU */
+
+ case BUILT_IN_EH_POINTER:
+ case BUILT_IN_EH_FILTER:
+ r = gimple_call_arg (stmt, 0);
+ r = move_stmt_eh_region_tree_nr (r, p);
+ gimple_call_set_arg (stmt, 0, r);
+ break;
- walk_gimple_seq (gimple_omp_body (stmt), move_stmt_r, move_stmt_op, wi);
+ default:
+ break;
+ }
+ }
+ break;
+
+ case GIMPLE_RESX:
+ {
+ int r = gimple_resx_region (stmt);
+ r = move_stmt_eh_region_nr (r, p);
+ gimple_resx_set_region (stmt, r);
+ }
+ break;
- p->remap_decls_p = save_remap_decls_p;
+ case GIMPLE_EH_DISPATCH:
+ {
+ int r = gimple_eh_dispatch_region (stmt);
+ r = move_stmt_eh_region_nr (r, p);
+ gimple_eh_dispatch_set_region (stmt, r);
+ }
+ break;
+
+ case GIMPLE_OMP_RETURN:
+ case GIMPLE_OMP_CONTINUE:
+ break;
+ default:
+ if (is_gimple_omp (stmt))
+ {
+ /* Do not remap variables inside OMP directives. Variables
+ referenced in clauses and directive header belong to the
+ parent function and should not be moved into the child
+ function. */
+ bool save_remap_decls_p = p->remap_decls_p;
+ p->remap_decls_p = false;
+ *handled_ops_p = true;
+
+ walk_gimple_seq (gimple_omp_body (stmt), move_stmt_r,
+ move_stmt_op, wi);
+
+ p->remap_decls_p = save_remap_decls_p;
+ }
+ break;
}
return NULL_TREE;
@@ -5950,7 +6194,7 @@ mark_virtual_ops_in_bb (basic_block bb)
static void
move_block_to_fn (struct function *dest_cfun, basic_block bb,
basic_block after, bool update_edge_count_p,
- struct move_stmt_d *d, int eh_offset)
+ struct move_stmt_d *d)
{
struct control_flow_graph *cfg;
edge_iterator ei;
@@ -6026,7 +6270,6 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
gimple stmt = gsi_stmt (si);
- int region;
struct walk_stmt_info wi;
memset (&wi, 0, sizeof (wi));
@@ -6056,17 +6299,12 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
if (uid >= dest_cfun->cfg->last_label_uid)
dest_cfun->cfg->last_label_uid = uid + 1;
}
- else if (gimple_code (stmt) == GIMPLE_RESX && eh_offset != 0)
- gimple_resx_set_region (stmt, gimple_resx_region (stmt) + eh_offset);
- region = lookup_stmt_eh_region (stmt);
- if (region >= 0)
- {
- add_stmt_to_eh_region_fn (dest_cfun, stmt, region + eh_offset);
- remove_stmt_from_eh_region (stmt);
- gimple_duplicate_stmt_histograms (dest_cfun, stmt, cfun, stmt);
- gimple_remove_stmt_histograms (cfun, stmt);
- }
+ maybe_duplicate_eh_stmt_fn (dest_cfun, stmt, cfun, stmt, d->eh_map, 0);
+ remove_stmt_from_eh_lp_fn (cfun, stmt);
+
+ gimple_duplicate_stmt_histograms (dest_cfun, stmt, cfun, stmt);
+ gimple_remove_stmt_histograms (cfun, stmt);
/* We cannot leave any operands allocated from the operand caches of
the current function. */
@@ -6097,29 +6335,28 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
/* Examine the statements in BB (which is in SRC_CFUN); find and return
the outermost EH region. Use REGION as the incoming base EH region. */
-static int
+static eh_region
find_outermost_region_in_block (struct function *src_cfun,
- basic_block bb, int region)
+ basic_block bb, eh_region region)
{
gimple_stmt_iterator si;
for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
gimple stmt = gsi_stmt (si);
- int stmt_region;
+ eh_region stmt_region;
+ int lp_nr;
- if (gimple_code (stmt) == GIMPLE_RESX)
- stmt_region = gimple_resx_region (stmt);
- else
- stmt_region = lookup_stmt_eh_region_fn (src_cfun, stmt);
- if (stmt_region > 0)
+ lp_nr = lookup_stmt_eh_lp_fn (src_cfun, stmt);
+ stmt_region = get_eh_region_from_lp_number_fn (src_cfun, lp_nr);
+ if (stmt_region)
{
- if (region < 0)
+ if (region == NULL)
region = stmt_region;
else if (stmt_region != region)
{
region = eh_region_outermost (src_cfun, stmt_region, region);
- gcc_assert (region != -1);
+ gcc_assert (region != NULL);
}
}
}
@@ -6209,13 +6446,13 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
basic_block dom_entry = get_immediate_dominator (CDI_DOMINATORS, entry_bb);
basic_block after, bb, *entry_pred, *exit_succ, abb;
struct function *saved_cfun = cfun;
- int *entry_flag, *exit_flag, eh_offset;
+ int *entry_flag, *exit_flag;
unsigned *entry_prob, *exit_prob;
unsigned i, num_entry_edges, num_exit_edges;
edge e;
edge_iterator ei;
htab_t new_label_map;
- struct pointer_map_t *vars_map;
+ struct pointer_map_t *vars_map, *eh_map;
struct loop *loop = entry_bb->loop_father;
struct move_stmt_d d;
@@ -6285,21 +6522,21 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
init_empty_tree_cfg ();
/* Initialize EH information for the new function. */
- eh_offset = 0;
+ eh_map = NULL;
new_label_map = NULL;
if (saved_cfun->eh)
{
- int region = -1;
+ eh_region region = NULL;
for (i = 0; VEC_iterate (basic_block, bbs, i, bb); i++)
region = find_outermost_region_in_block (saved_cfun, bb, region);
init_eh_for_function ();
- if (region != -1)
+ if (region != NULL)
{
new_label_map = htab_create (17, tree_map_hash, tree_map_eq, free);
- eh_offset = duplicate_eh_regions (saved_cfun, new_label_mapper,
- new_label_map, region, 0);
+ eh_map = duplicate_eh_regions (saved_cfun, region, 0,
+ new_label_mapper, new_label_map);
}
}
@@ -6311,20 +6548,21 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
vars_map = pointer_map_create ();
memset (&d, 0, sizeof (d));
- d.vars_map = vars_map;
+ d.orig_block = orig_block;
+ d.new_block = DECL_INITIAL (dest_cfun->decl);
d.from_context = cfun->decl;
d.to_context = dest_cfun->decl;
+ d.vars_map = vars_map;
d.new_label_map = new_label_map;
+ d.eh_map = eh_map;
d.remap_decls_p = true;
- d.orig_block = orig_block;
- d.new_block = DECL_INITIAL (dest_cfun->decl);
for (i = 0; VEC_iterate (basic_block, bbs, i, bb); i++)
{
/* No need to update edge counts on the last block. It has
already been updated earlier when we detached the region from
the original CFG. */
- move_block_to_fn (dest_cfun, bb, after, bb != exit_bb, &d, eh_offset);
+ move_block_to_fn (dest_cfun, bb, after, bb != exit_bb, &d);
after = bb;
}
@@ -6347,6 +6585,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
if (new_label_map)
htab_delete (new_label_map);
+ if (eh_map)
+ pointer_map_destroy (eh_map);
pointer_map_destroy (vars_map);
/* Rewire the entry and exit blocks. The successor to the entry
@@ -6433,7 +6673,7 @@ dump_function_to_file (tree fn, FILE *file, int flags)
print_node (file, "", fn, 2);
dsf = DECL_STRUCT_FUNCTION (fn);
- if (dsf && (flags & TDF_DETAILS))
+ if (dsf && (flags & TDF_EH))
dump_eh_tree (file, dsf);
if (flags & TDF_RAW && !gimple_has_body_p (fn))
@@ -7257,7 +7497,7 @@ split_critical_edges (void)
Go ahead and split them too. This matches the logic in
gimple_find_edge_insert_loc. */
else if ((!single_pred_p (e->dest)
- || phi_nodes (e->dest)
+ || !gimple_seq_empty_p (phi_nodes (e->dest))
|| e->dest == EXIT_BLOCK_PTR)
&& e->src != ENTRY_BLOCK_PTR
&& !(e->flags & EDGE_ABNORMAL))
@@ -7573,4 +7813,3 @@ struct gimple_opt_pass pass_warn_unused_result =
0, /* todo_flags_finish */
}
};
-
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index 5cce1b6eec7..d3a8ca91aa9 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -239,6 +239,16 @@ tree_forwarder_block_p (basic_block bb, bool phi_wanted)
gcc_assert (bb != ENTRY_BLOCK_PTR);
#endif
+ /* There should not be an edge coming from entry, or an EH edge. */
+ {
+ edge_iterator ei;
+ edge e;
+
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (e->src == ENTRY_BLOCK_PTR || (e->flags & EDGE_EH))
+ return false;
+ }
+
/* Now walk through the statements backward. We can ignore labels,
anything else means this is not a forwarder block. */
for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
@@ -262,9 +272,6 @@ tree_forwarder_block_p (basic_block bb, bool phi_wanted)
}
}
- if (find_edge (ENTRY_BLOCK_PTR, bb))
- return false;
-
if (current_loops)
{
basic_block dest;
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index b6eff5ea8f1..e9a645ef7f2 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -201,7 +201,6 @@ create_tree_common_ann (tree t)
ann = GGC_CNEW (struct tree_ann_common_d);
ann->type = TREE_ANN_COMMON;
- ann->rn = -1;
t->base.ann = (tree_ann_t) ann;
return ann;
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index a90c4b2c953..c1f3d6a94a4 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "toplev.h"
#include "gimple.h"
+#include "target.h"
/* In some instances a tree and a gimple need to be stored in a same table,
i.e. in hash tables. This is a structure to do this. */
@@ -74,7 +75,7 @@ struct_ptr_hash (const void *a)
}
-/* Remember and lookup EH region data for arbitrary statements.
+/* Remember and lookup EH landing pad data for arbitrary statements.
Really this means any statement that could_throw_p. We could
stuff this information into the stmt_ann data structure, but:
@@ -86,30 +87,19 @@ struct_ptr_hash (const void *a)
compared to those that can. We should be saving some amount
of space by only allocating memory for those that can throw. */
-static void
-record_stmt_eh_region (struct eh_region_d *region, gimple t)
-{
- if (!region)
- return;
-
- add_stmt_to_eh_region (t, get_eh_region_number (region));
-}
-
-
-/* Add statement T in function IFUN to EH region NUM. */
+/* Add statement T in function IFUN to landing pad NUM. */
void
-add_stmt_to_eh_region_fn (struct function *ifun, gimple t, int num)
+add_stmt_to_eh_lp_fn (struct function *ifun, gimple t, int num)
{
struct throw_stmt_node *n;
void **slot;
- gcc_assert (num >= 0);
- gcc_assert (gimple_code (t) != GIMPLE_RESX);
+ gcc_assert (num != 0);
n = GGC_NEW (struct throw_stmt_node);
n->stmt = t;
- n->region_nr = num;
+ n->lp_nr = num;
if (!get_eh_throw_stmt_table (ifun))
set_eh_throw_stmt_table (ifun, htab_create_ggc (31, struct_ptr_hash,
@@ -121,21 +111,39 @@ add_stmt_to_eh_region_fn (struct function *ifun, gimple t, int num)
*slot = n;
}
-
-/* Add statement T in the current function (cfun) to EH region number
- NUM. */
+/* Add statement T in the current function (cfun) to EH landing pad NUM. */
void
-add_stmt_to_eh_region (gimple t, int num)
+add_stmt_to_eh_lp (gimple t, int num)
{
- add_stmt_to_eh_region_fn (cfun, t, num);
+ add_stmt_to_eh_lp_fn (cfun, t, num);
+}
+
+/* Add statement T to the single EH landing pad in REGION. */
+
+static void
+record_stmt_eh_region (eh_region region, gimple t)
+{
+ if (region == NULL)
+ return;
+ if (region->type == ERT_MUST_NOT_THROW)
+ add_stmt_to_eh_lp_fn (cfun, t, -region->index);
+ else
+ {
+ eh_landing_pad lp = region->landing_pads;
+ if (lp == NULL)
+ lp = gen_eh_landing_pad (region);
+ else
+ gcc_assert (lp->next_lp == NULL);
+ add_stmt_to_eh_lp_fn (cfun, t, lp->index);
+ }
}
-/* Remove statement T in function IFUN from the EH region holding it. */
+/* Remove statement T in function IFUN from its EH landing pad. */
bool
-remove_stmt_from_eh_region_fn (struct function *ifun, gimple t)
+remove_stmt_from_eh_lp_fn (struct function *ifun, gimple t)
{
struct throw_stmt_node dummy;
void **slot;
@@ -156,75 +164,57 @@ remove_stmt_from_eh_region_fn (struct function *ifun, gimple t)
}
-/* Remove statement T in the current function (cfun) from the EH
- region holding it. */
+/* Remove statement T in the current function (cfun) from its
+ EH landing pad. */
bool
-remove_stmt_from_eh_region (gimple t)
+remove_stmt_from_eh_lp (gimple t)
{
- return remove_stmt_from_eh_region_fn (cfun, t);
+ return remove_stmt_from_eh_lp_fn (cfun, t);
}
/* Determine if statement T is inside an EH region in function IFUN.
- Return the EH region number if found, return -2 if IFUN does not
- have an EH table and -1 if T could not be found in IFUN's EH region
- table. */
+ Positive numbers indicate a landing pad index; negative numbers
+ indicate a MUST_NOT_THROW region index; zero indicates that the
+ statement is not recorded in the region table. */
int
-lookup_stmt_eh_region_fn (struct function *ifun, gimple t)
+lookup_stmt_eh_lp_fn (struct function *ifun, gimple t)
{
struct throw_stmt_node *p, n;
- if (!get_eh_throw_stmt_table (ifun))
- return -2;
+ if (ifun->eh->throw_stmt_table == NULL)
+ return 0;
n.stmt = t;
- p = (struct throw_stmt_node *) htab_find (get_eh_throw_stmt_table (ifun), &n);
- return (p ? p->region_nr : -1);
+ p = (struct throw_stmt_node *) htab_find (ifun->eh->throw_stmt_table, &n);
+ return p ? p->lp_nr : 0;
}
-
-/* Determine if statement T is inside an EH region in the current
- function (cfun). Return the EH region number if found, return -2
- if cfun does not have an EH table and -1 if T could not be found in
- cfun's EH region table. */
+/* Likewise, but always use the current function. */
int
-lookup_stmt_eh_region (gimple t)
+lookup_stmt_eh_lp (gimple t)
{
/* We can get called from initialized data when -fnon-call-exceptions
is on; prevent crash. */
if (!cfun)
- return -1;
-
- return lookup_stmt_eh_region_fn (cfun, t);
+ return 0;
+ return lookup_stmt_eh_lp_fn (cfun, t);
}
-
-/* Determine if expression T is inside an EH region in the current
- function (cfun). Return the EH region number if found, return -2
- if IFUN does not have an EH table and -1 if T could not be found in
- IFUN's EH region table. */
+/* Likewise, but reference a tree expression instead. */
int
-lookup_expr_eh_region (tree t)
+lookup_expr_eh_lp (tree t)
{
- /* We can get called from initialized data when -fnon-call-exceptions
- is on; prevent crash. */
- if (!cfun)
- return -1;
-
- if (!get_eh_throw_stmt_table (cfun))
- return -2;
-
- if (t && EXPR_P (t))
+ if (cfun && cfun->eh->throw_stmt_table && t && EXPR_P (t))
{
tree_ann_common_t ann = tree_common_ann (t);
if (ann)
- return (int) ann->rn;
+ return ann->lp_nr;
}
-
- return -1;
+ return 0;
}
@@ -238,7 +228,7 @@ struct finally_tree_node
when deciding whether a GOTO to a certain LABEL_DECL (which is a
tree) leaves the TRY block, its necessary to record a tree in
this field. Thus a treemple is used. */
- treemple child;
+ treemple child;
gimple parent;
};
@@ -263,7 +253,7 @@ record_in_finally_tree (treemple child, gimple parent)
static void
collect_finally_tree (gimple stmt, gimple region);
-/* Go through the gimple sequence. Works with collect_finally_tree to
+/* Go through the gimple sequence. Works with collect_finally_tree to
record all GIMPLE_LABEL and GIMPLE_TRY statements. */
static void
@@ -344,6 +334,14 @@ outside_finally_tree (treemple start, gimple target)
The eh region creation is straight-forward, but frobbing all the gotos
and such into shape isn't. */
+/* The sequence into which we record all EH stuff. This will be
+ placed at the end of the function when we're all done. */
+static gimple_seq eh_seq;
+
+/* Record whether an EH region contains something that can throw,
+ indexed by EH region number. */
+static bitmap eh_region_may_contain_throw;
+
/* The GOTO_QUEUE is is an array of GIMPLE_GOTO and GIMPLE_RETURN
statements that are seen to escape this GIMPLE_TRY_FINALLY node.
The idea is to record a gimple statement for everything except for
@@ -371,7 +369,12 @@ struct leh_state
/* What's "current" while constructing the eh region tree. These
correspond to variables of the same name in cfun->eh, which we
don't have easy access to. */
- struct eh_region_d *cur_region;
+ eh_region cur_region;
+
+ /* What's "current" for the purposes of __builtin_eh_pointer. For
+ a CATCH, this is the associated TRY. For an EH_FILTER, this is
+ the associated ALLOWED_EXCEPTIONS, etc. */
+ eh_region ehp_region;
/* Processing of TRY_FINALLY requires a bit more state. This is
split out into a separate structure so that we don't have to
@@ -387,6 +390,7 @@ struct leh_tf_state
in the collect_finally_tree data structures. */
gimple try_finally_expr;
gimple top_p;
+
/* While lowering a top_p usually it is expanded into multiple statements,
thus we need the following field to store them. */
gimple_seq top_p_seq;
@@ -395,7 +399,7 @@ struct leh_tf_state
struct leh_state *outer;
/* The exception region created for it. */
- struct eh_region_d *region;
+ eh_region region;
/* The goto queue. */
struct goto_queue_node *goto_queue;
@@ -413,10 +417,6 @@ struct leh_tf_state
though subsequent transformations may have cleared that flag. */
tree fallthru_label;
- /* A label that has been registered with except.c to be the
- landing pad for this try block. */
- tree eh_label;
-
/* True if it is possible to fall out the bottom of the try block.
Cleared if the fallthru is converted to a goto. */
bool may_fallthru;
@@ -429,7 +429,7 @@ struct leh_tf_state
bool may_throw;
};
-static gimple_seq lower_eh_filter (struct leh_state *, gimple);
+static gimple_seq lower_eh_must_not_throw (struct leh_state *, gimple);
/* Search for STMT in the goto queue. Return the replacement,
or null if the statement isn't in the queue. */
@@ -810,7 +810,7 @@ do_goto_redirection (struct goto_queue_node *q, tree finlab, gimple_seq mod,
if (!q->repl_stmt)
q->repl_stmt = gimple_seq_alloc ();
- q->cont_stmt = gimple_build_goto (VEC_index (tree, tf->dest_array,q->index));
+ q->cont_stmt = gimple_build_goto (VEC_index (tree, tf->dest_array, q->index));
if (mod)
gimple_seq_add_seq (&q->repl_stmt, mod);
@@ -819,17 +819,76 @@ do_goto_redirection (struct goto_queue_node *q, tree finlab, gimple_seq mod,
gimple_seq_add_stmt (&q->repl_stmt, x);
}
+/* Emit a standard landing pad sequence into SEQ for REGION. */
+
+static void
+emit_post_landing_pad (gimple_seq *seq, eh_region region)
+{
+ eh_landing_pad lp = region->landing_pads;
+ gimple x;
+
+ if (lp == NULL)
+ lp = gen_eh_landing_pad (region);
+
+ lp->post_landing_pad = create_artificial_label (UNKNOWN_LOCATION);
+ EH_LANDING_PAD_NR (lp->post_landing_pad) = lp->index;
+
+ x = gimple_build_label (lp->post_landing_pad);
+ gimple_seq_add_stmt (seq, x);
+}
+
+/* Emit a RESX statement into SEQ for REGION. */
+
+static void
+emit_resx (gimple_seq *seq, eh_region region)
+{
+ gimple x = gimple_build_resx (region->index);
+ gimple_seq_add_stmt (seq, x);
+ if (region->outer)
+ record_stmt_eh_region (region->outer, x);
+}
+
+/* Emit an EH_DISPATCH statement into SEQ for REGION. */
+
+static void
+emit_eh_dispatch (gimple_seq *seq, eh_region region)
+{
+ gimple x = gimple_build_eh_dispatch (region->index);
+ gimple_seq_add_stmt (seq, x);
+}
+
+/* Note that the current EH region may contain a throw, or a
+ call to a function which itself may contain a throw. */
+
+static void
+note_eh_region_may_contain_throw (eh_region region)
+{
+ while (!bitmap_bit_p (eh_region_may_contain_throw, region->index))
+ {
+ bitmap_set_bit (eh_region_may_contain_throw, region->index);
+ region = region->outer;
+ if (region == NULL)
+ break;
+ }
+}
+
/* We want to transform
try { body; } catch { stuff; }
to
- body; goto over; lab: stuff; over:
-
- TP is a GIMPLE_TRY node. LAB is the label that
+ normal_seqence:
+ body;
+ over:
+ eh_seqence:
+ landing_pad:
+ stuff;
+ goto over;
+
+ TP is a GIMPLE_TRY node. REGION is the region whose post_landing_pad
should be placed before the second operand, or NULL. OVER is
an existing label that should be put at the exit, or NULL. */
static gimple_seq
-frob_into_branch_around (gimple tp, tree lab, tree over)
+frob_into_branch_around (gimple tp, eh_region region, tree over)
{
gimple x;
gimple_seq cleanup, result;
@@ -838,21 +897,17 @@ frob_into_branch_around (gimple tp, tree lab, tree over)
cleanup = gimple_try_cleanup (tp);
result = gimple_try_eval (tp);
- if (gimple_seq_may_fallthru (result))
+ if (region)
+ emit_post_landing_pad (&eh_seq, region);
+
+ if (gimple_seq_may_fallthru (cleanup))
{
if (!over)
over = create_artificial_label (loc);
x = gimple_build_goto (over);
- gimple_seq_add_stmt (&result, x);
+ gimple_seq_add_stmt (&cleanup, x);
}
-
- if (lab)
- {
- x = gimple_build_label (lab);
- gimple_seq_add_stmt (&result, x);
- }
-
- gimple_seq_add_seq (&result, cleanup);
+ gimple_seq_add_seq (&eh_seq, cleanup);
if (over)
{
@@ -928,44 +983,21 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
struct leh_state *this_state,
struct leh_tf_state *tf)
{
- gimple protect_cleanup_actions;
+ tree protect_cleanup_actions;
gimple_stmt_iterator gsi;
bool finally_may_fallthru;
gimple_seq finally;
gimple x;
/* First check for nothing to do. */
- if (lang_protect_cleanup_actions)
- protect_cleanup_actions = lang_protect_cleanup_actions ();
- else
- protect_cleanup_actions = NULL;
+ if (lang_protect_cleanup_actions == NULL)
+ return;
+ protect_cleanup_actions = lang_protect_cleanup_actions ();
+ if (protect_cleanup_actions == NULL)
+ return;
finally = gimple_try_cleanup (tf->top_p);
-
- /* If the EH case of the finally block can fall through, this may be a
- structure of the form
- try {
- try {
- throw ...;
- } cleanup {
- try {
- throw ...;
- } catch (...) {
- }
- }
- } catch (...) {
- yyy;
- }
- E.g. with an inline destructor with an embedded try block. In this
- case we must save the runtime EH data around the nested exception.
-
- This complication means that any time the previous runtime data might
- be used (via fallthru from the finally) we handle the eh case here,
- whether or not protect_cleanup_actions is active. */
-
finally_may_fallthru = gimple_seq_may_fallthru (finally);
- if (!finally_may_fallthru && !protect_cleanup_actions)
- return;
/* Duplicate the FINALLY block. Only need to do this for try-finally,
and not for cleanups. */
@@ -981,8 +1013,7 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
MUST_NOT_THROW filter. */
gsi = gsi_start (finally);
x = gsi_stmt (gsi);
- if (protect_cleanup_actions
- && gimple_code (x) == GIMPLE_TRY
+ if (gimple_code (x) == GIMPLE_TRY
&& gimple_try_kind (x) == GIMPLE_TRY_CATCH
&& gimple_try_catch_is_cleanup (x))
{
@@ -990,77 +1021,17 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
gsi_remove (&gsi, false);
}
- /* Resume execution after the exception. Adding this now lets
- lower_eh_filter not add unnecessary gotos, as it is clear that
- we never fallthru from this copy of the finally block. */
- if (finally_may_fallthru)
- {
- tree save_eptr, save_filt;
- tree tmp;
-
- save_eptr = create_tmp_var (ptr_type_node, "save_eptr");
- save_filt = create_tmp_var (integer_type_node, "save_filt");
-
- gsi = gsi_start (finally);
- tmp = build0 (EXC_PTR_EXPR, ptr_type_node);
- x = gimple_build_assign (save_eptr, tmp);
- gsi_insert_before (&gsi, x, GSI_CONTINUE_LINKING);
-
- tmp = build0 (FILTER_EXPR, integer_type_node);
- x = gimple_build_assign (save_filt, tmp);
- gsi_insert_before (&gsi, x, GSI_CONTINUE_LINKING);
-
- gsi = gsi_last (finally);
- tmp = build0 (EXC_PTR_EXPR, ptr_type_node);
- x = gimple_build_assign (tmp, save_eptr);
- gsi_insert_after (&gsi, x, GSI_CONTINUE_LINKING);
-
- tmp = build0 (FILTER_EXPR, integer_type_node);
- x = gimple_build_assign (tmp, save_filt);
- gsi_insert_after (&gsi, x, GSI_CONTINUE_LINKING);
-
- x = gimple_build_resx (get_eh_region_number (tf->region));
- gsi_insert_after (&gsi, x, GSI_CONTINUE_LINKING);
- }
-
/* Wrap the block with protect_cleanup_actions as the action. */
- if (protect_cleanup_actions)
- {
- gimple_seq seq = NULL, failure = NULL;
-
- gimple_seq_add_stmt (&failure, protect_cleanup_actions);
- x = gimple_build_eh_filter (NULL, failure);
- gimple_eh_filter_set_must_not_throw (x, 1);
-
- gimple_seq_add_stmt (&seq, x);
- x = gimple_build_try (finally, seq, GIMPLE_TRY_CATCH);
- finally = lower_eh_filter (outer_state, x);
- }
- else
- lower_eh_constructs_1 (outer_state, finally);
-
- /* Hook this up to the end of the existing try block. If we
- previously fell through the end, we'll have to branch around.
- This means adding a new goto, and adding it to the queue. */
-
- gsi = gsi_last (gimple_try_eval (tf->top_p));
-
- if (tf->may_fallthru)
- {
- tree tmp;
- tmp = lower_try_finally_fallthru_label (tf);
- x = gimple_build_goto (tmp);
- gsi_insert_after (&gsi, x, GSI_CONTINUE_LINKING);
-
- if (this_state)
- maybe_record_in_goto_queue (this_state, x);
-
- tf->may_fallthru = false;
- }
-
- x = gimple_build_label (tf->eh_label);
- gsi_insert_after (&gsi, x, GSI_CONTINUE_LINKING);
- gsi_insert_seq_after (&gsi, finally, GSI_CONTINUE_LINKING);
+ x = gimple_build_eh_must_not_throw (protect_cleanup_actions);
+ x = gimple_build_try (finally, gimple_seq_alloc_with_stmt (x),
+ GIMPLE_TRY_CATCH);
+ finally = lower_eh_must_not_throw (outer_state, x);
+
+ /* Drop all of this into the exception sequence. */
+ emit_post_landing_pad (&eh_seq, tf->region);
+ gimple_seq_add_seq (&eh_seq, finally);
+ if (finally_may_fallthru)
+ emit_resx (&eh_seq, tf->region);
/* Having now been handled, EH isn't to be considered with
the rest of the outgoing edges. */
@@ -1081,10 +1052,7 @@ lower_try_finally_nofallthru (struct leh_state *state,
gimple_seq finally;
struct goto_queue_node *q, *qe;
- if (tf->may_throw)
- lab = tf->eh_label;
- else
- lab = create_artificial_label (gimple_location (tf->try_finally_expr));
+ lab = create_artificial_label (gimple_location (tf->try_finally_expr));
/* We expect that tf->top_p is a GIMPLE_TRY. */
finally = gimple_try_cleanup (tf->top_p);
@@ -1106,6 +1074,14 @@ lower_try_finally_nofallthru (struct leh_state *state,
lower_eh_constructs_1 (state, finally);
gimple_seq_add_seq (&tf->top_p_seq, finally);
+
+ if (tf->may_throw)
+ {
+ emit_post_landing_pad (&eh_seq, tf->region);
+
+ x = gimple_build_goto (lab);
+ gimple_seq_add_stmt (&eh_seq, x);
+ }
}
/* A subroutine of lower_try_finally. We have determined that there is
@@ -1130,16 +1106,9 @@ lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf)
{
/* Only reachable via the exception edge. Add the given label to
the head of the FINALLY block. Append a RESX at the end. */
-
- x = gimple_build_label (tf->eh_label);
- gimple_seq_add_stmt (&tf->top_p_seq, x);
-
- gimple_seq_add_seq (&tf->top_p_seq, finally);
-
- x = gimple_build_resx (get_eh_region_number (tf->region));
-
- gimple_seq_add_stmt (&tf->top_p_seq, x);
-
+ emit_post_landing_pad (&eh_seq, tf->region);
+ gimple_seq_add_seq (&eh_seq, finally);
+ emit_resx (&eh_seq, tf->region);
return;
}
@@ -1223,15 +1192,13 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
if (tf->may_throw)
{
- x = gimple_build_label (tf->eh_label);
- gimple_seq_add_stmt (&new_stmt, x);
+ emit_post_landing_pad (&eh_seq, tf->region);
seq = lower_try_finally_dup_block (finally, state);
lower_eh_constructs_1 (state, seq);
- gimple_seq_add_seq (&new_stmt, seq);
+ gimple_seq_add_seq (&eh_seq, seq);
- x = gimple_build_resx (get_eh_region_number (tf->region));
- gimple_seq_add_stmt (&new_stmt, x);
+ emit_resx (&eh_seq, tf->region);
}
if (tf->goto_queue)
@@ -1301,7 +1268,7 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
else
do_goto_redirection (q, lab, NULL, tf);
}
-
+
replace_goto_queue (tf);
free (labels);
}
@@ -1375,20 +1342,13 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
if (tf->may_fallthru)
{
- x = gimple_build_assign (finally_tmp, build_int_cst (integer_type_node,
- fallthru_index));
+ x = gimple_build_assign (finally_tmp,
+ build_int_cst (NULL, fallthru_index));
gimple_seq_add_stmt (&tf->top_p_seq, x);
- if (tf->may_throw)
- {
- x = gimple_build_goto (finally_label);
- gimple_seq_add_stmt (&tf->top_p_seq, x);
- }
-
-
last_case = build3 (CASE_LABEL_EXPR, void_type_node,
- build_int_cst (NULL_TREE, fallthru_index), NULL,
- create_artificial_label (tf_loc));
+ build_int_cst (NULL, fallthru_index),
+ NULL, create_artificial_label (tf_loc));
VEC_quick_push (tree, case_label_vec, last_case);
last_case_index++;
@@ -1402,23 +1362,24 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
if (tf->may_throw)
{
- x = gimple_build_label (tf->eh_label);
- gimple_seq_add_stmt (&tf->top_p_seq, x);
+ emit_post_landing_pad (&eh_seq, tf->region);
- x = gimple_build_assign (finally_tmp, build_int_cst (integer_type_node,
- eh_index));
- gimple_seq_add_stmt (&tf->top_p_seq, x);
+ x = gimple_build_assign (finally_tmp,
+ build_int_cst (NULL, eh_index));
+ gimple_seq_add_stmt (&eh_seq, x);
+
+ x = gimple_build_goto (finally_label);
+ gimple_seq_add_stmt (&eh_seq, x);
last_case = build3 (CASE_LABEL_EXPR, void_type_node,
- build_int_cst (NULL_TREE, eh_index), NULL,
- create_artificial_label (tf_loc));
+ build_int_cst (NULL, eh_index),
+ NULL, create_artificial_label (tf_loc));
VEC_quick_push (tree, case_label_vec, last_case);
last_case_index++;
x = gimple_build_label (CASE_LABEL (last_case));
- gimple_seq_add_stmt (&switch_body, x);
- x = gimple_build_resx (get_eh_region_number (tf->region));
- gimple_seq_add_stmt (&switch_body, x);
+ gimple_seq_add_stmt (&eh_seq, x);
+ emit_resx (&eh_seq, tf->region);
}
x = gimple_build_label (finally_label);
@@ -1443,8 +1404,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
if (q->index < 0)
{
x = gimple_build_assign (finally_tmp,
- build_int_cst (integer_type_node,
- return_index));
+ build_int_cst (NULL, return_index));
gimple_seq_add_stmt (&mod, x);
do_return_redirection (q, finally_label, mod, &return_val);
switch_id = return_index;
@@ -1452,7 +1412,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
else
{
x = gimple_build_assign (finally_tmp,
- build_int_cst (integer_type_node, q->index));
+ build_int_cst (NULL, q->index));
gimple_seq_add_stmt (&mod, x);
do_goto_redirection (q, finally_label, mod, tf);
switch_id = q->index;
@@ -1465,11 +1425,11 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
tree case_lab;
void **slot;
case_lab = build3 (CASE_LABEL_EXPR, void_type_node,
- build_int_cst (NULL_TREE, switch_id), NULL,
- NULL);
+ build_int_cst (NULL, switch_id),
+ NULL, NULL);
/* We store the cont_stmt in the pointer map, so that we can recover
it in the loop below. We don't create the new label while
- walking the goto_queue because pointers don't offer a stable
+ walking the goto_queue because pointers don't offer a stable
order. */
if (!cont_map)
cont_map = pointer_map_create ();
@@ -1577,7 +1537,6 @@ lower_try_finally (struct leh_state *state, gimple tp)
struct leh_tf_state this_tf;
struct leh_state this_state;
int ndests;
- location_t tf_loc = gimple_location (tp);
/* Process the try block. */
@@ -1586,12 +1545,12 @@ lower_try_finally (struct leh_state *state, gimple tp)
this_tf.top_p = tp;
this_tf.outer = state;
if (using_eh_for_cleanups_p)
- this_tf.region
- = gen_eh_region_cleanup (state->cur_region);
+ this_tf.region = gen_eh_region_cleanup (state->cur_region);
else
this_tf.region = NULL;
this_state.cur_region = this_tf.region;
+ this_state.ehp_region = state->ehp_region;
this_state.tf = &this_tf;
lower_eh_constructs_1 (&this_state, gimple_try_eval(tp));
@@ -1601,13 +1560,10 @@ lower_try_finally (struct leh_state *state, gimple tp)
/* Determine if any exceptions are possible within the try block. */
if (using_eh_for_cleanups_p)
- this_tf.may_throw = get_eh_region_may_contain_throw (this_tf.region);
+ this_tf.may_throw = bitmap_bit_p (eh_region_may_contain_throw,
+ this_tf.region->index);
if (this_tf.may_throw)
- {
- this_tf.eh_label = create_artificial_label (tf_loc);
- set_eh_region_tree_label (this_tf.region, this_tf.eh_label);
- honor_protect_cleanup_actions (state, &this_state, &this_tf);
- }
+ honor_protect_cleanup_actions (state, &this_state, &this_tf);
/* Determine how many edges (still) reach the finally block. Or rather,
how many destinations are reached by the finally block. Use this to
@@ -1663,58 +1619,65 @@ lower_try_finally (struct leh_state *state, gimple tp)
static gimple_seq
lower_catch (struct leh_state *state, gimple tp)
{
- struct eh_region_d *try_region;
+ eh_region try_region;
struct leh_state this_state;
gimple_stmt_iterator gsi;
tree out_label;
+ gimple_seq new_seq;
+ gimple x;
location_t try_catch_loc = gimple_location (tp);
try_region = gen_eh_region_try (state->cur_region);
+
+ this_state = *state;
this_state.cur_region = try_region;
- this_state.tf = state->tf;
lower_eh_constructs_1 (&this_state, gimple_try_eval (tp));
- if (!get_eh_region_may_contain_throw (try_region))
- {
- return gimple_try_eval (tp);
- }
+ if (!bitmap_bit_p (eh_region_may_contain_throw, try_region->index))
+ return gimple_try_eval (tp);
+
+ new_seq = NULL;
+ emit_eh_dispatch (&new_seq, try_region);
+ emit_resx (&new_seq, try_region);
+
+ this_state.cur_region = state->cur_region;
+ this_state.ehp_region = try_region;
out_label = NULL;
- for (gsi = gsi_start (gimple_try_cleanup (tp)); !gsi_end_p (gsi); )
+ for (gsi = gsi_start (gimple_try_cleanup (tp));
+ !gsi_end_p (gsi);
+ gsi_next (&gsi))
{
- struct eh_region_d *catch_region;
- tree eh_label;
- gimple x, gcatch;
+ eh_catch c;
+ gimple gcatch;
+ gimple_seq handler;
gcatch = gsi_stmt (gsi);
- catch_region = gen_eh_region_catch (try_region,
- gimple_catch_types (gcatch));
+ c = gen_eh_region_catch (try_region, gimple_catch_types (gcatch));
- this_state.cur_region = catch_region;
- lower_eh_constructs_1 (&this_state, gimple_catch_handler (gcatch));
+ handler = gimple_catch_handler (gcatch);
+ lower_eh_constructs_1 (&this_state, handler);
- eh_label = create_artificial_label (try_catch_loc);
- set_eh_region_tree_label (catch_region, eh_label);
+ c->label = create_artificial_label (UNKNOWN_LOCATION);
+ x = gimple_build_label (c->label);
+ gimple_seq_add_stmt (&new_seq, x);
- x = gimple_build_label (eh_label);
- gsi_insert_before (&gsi, x, GSI_SAME_STMT);
+ gimple_seq_add_seq (&new_seq, handler);
- if (gimple_seq_may_fallthru (gimple_catch_handler (gcatch)))
+ if (gimple_seq_may_fallthru (new_seq))
{
if (!out_label)
out_label = create_artificial_label (try_catch_loc);
x = gimple_build_goto (out_label);
- gimple_seq_add_stmt (gimple_catch_handler_ptr (gcatch), x);
+ gimple_seq_add_stmt (&new_seq, x);
}
-
- gsi_insert_seq_before (&gsi, gimple_catch_handler (gcatch),
- GSI_SAME_STMT);
- gsi_remove (&gsi, false);
}
- return frob_into_branch_around (tp, NULL, out_label);
+ gimple_try_set_cleanup (tp, new_seq);
+
+ return frob_into_branch_around (tp, try_region, out_label);
}
/* A subroutine of lower_eh_constructs_1. Lower a GIMPLE_TRY with a
@@ -1725,34 +1688,70 @@ static gimple_seq
lower_eh_filter (struct leh_state *state, gimple tp)
{
struct leh_state this_state;
- struct eh_region_d *this_region;
- gimple inner;
- tree eh_label;
+ eh_region this_region;
+ gimple inner, x;
+ gimple_seq new_seq;
inner = gimple_seq_first_stmt (gimple_try_cleanup (tp));
- if (gimple_eh_filter_must_not_throw (inner))
- this_region = gen_eh_region_must_not_throw (state->cur_region);
- else
- this_region = gen_eh_region_allowed (state->cur_region,
- gimple_eh_filter_types (inner));
+ this_region = gen_eh_region_allowed (state->cur_region,
+ gimple_eh_filter_types (inner));
this_state = *state;
this_state.cur_region = this_region;
lower_eh_constructs_1 (&this_state, gimple_try_eval (tp));
- if (!get_eh_region_may_contain_throw (this_region))
- {
- return gimple_try_eval (tp);
- }
+ if (!bitmap_bit_p (eh_region_may_contain_throw, this_region->index))
+ return gimple_try_eval (tp);
+
+ new_seq = NULL;
+ this_state.cur_region = state->cur_region;
+ this_state.ehp_region = this_region;
+
+ emit_eh_dispatch (&new_seq, this_region);
+ emit_resx (&new_seq, this_region);
+
+ this_region->u.allowed.label = create_artificial_label (UNKNOWN_LOCATION);
+ x = gimple_build_label (this_region->u.allowed.label);
+ gimple_seq_add_stmt (&new_seq, x);
- lower_eh_constructs_1 (state, gimple_eh_filter_failure (inner));
- gimple_try_set_cleanup (tp, gimple_eh_filter_failure (inner));
+ lower_eh_constructs_1 (&this_state, gimple_eh_filter_failure (inner));
+ gimple_seq_add_seq (&new_seq, gimple_eh_filter_failure (inner));
- eh_label = create_artificial_label (gimple_location (inner));
- set_eh_region_tree_label (this_region, eh_label);
+ gimple_try_set_cleanup (tp, new_seq);
- return frob_into_branch_around (tp, eh_label, NULL);
+ return frob_into_branch_around (tp, this_region, NULL);
+}
+
+/* A subroutine of lower_eh_constructs_1. Lower a GIMPLE_TRY with
+ an GIMPLE_EH_MUST_NOT_THROW to a sequence of labels and blocks,
+ plus the exception region trees that record all the magic. */
+
+static gimple_seq
+lower_eh_must_not_throw (struct leh_state *state, gimple tp)
+{
+ struct leh_state this_state;
+ eh_region this_region;
+ gimple inner;
+
+ inner = gimple_seq_first_stmt (gimple_try_cleanup (tp));
+
+ this_region = gen_eh_region_must_not_throw (state->cur_region);
+ this_region->u.must_not_throw.failure_decl
+ = gimple_eh_must_not_throw_fndecl (inner);
+ this_region->u.must_not_throw.failure_loc = gimple_location (tp);
+
+ /* In order to get mangling applied to this decl, we must mark it
+ used now. Otherwise, pass_ipa_free_lang_data won't think it
+ needs to happen. */
+ TREE_USED (this_region->u.must_not_throw.failure_decl) = 1;
+
+ this_state = *state;
+ this_state.cur_region = this_region;
+
+ lower_eh_constructs_1 (&this_state, gimple_try_eval (tp));
+
+ return gimple_try_eval (tp);
}
/* Implement a cleanup expression. This is similar to try-finally,
@@ -1762,7 +1761,7 @@ static gimple_seq
lower_cleanup (struct leh_state *state, gimple tp)
{
struct leh_state this_state;
- struct eh_region_d *this_region;
+ eh_region this_region;
struct leh_tf_state fake_tf;
gimple_seq result;
@@ -1780,10 +1779,8 @@ lower_cleanup (struct leh_state *state, gimple tp)
lower_eh_constructs_1 (&this_state, gimple_try_eval (tp));
- if (!get_eh_region_may_contain_throw (this_region))
- {
- return gimple_try_eval (tp);
- }
+ if (!bitmap_bit_p (eh_region_may_contain_throw, this_region->index))
+ return gimple_try_eval (tp);
/* Build enough of a try-finally state so that we can reuse
honor_protect_cleanup_actions. */
@@ -1794,9 +1791,6 @@ lower_cleanup (struct leh_state *state, gimple tp)
fake_tf.may_fallthru = gimple_seq_may_fallthru (gimple_try_eval (tp));
fake_tf.may_throw = true;
- fake_tf.eh_label = create_artificial_label (gimple_location (tp));
- set_eh_region_tree_label (this_region, fake_tf.eh_label);
-
honor_protect_cleanup_actions (state, NULL, &fake_tf);
if (fake_tf.may_throw)
@@ -1804,8 +1798,8 @@ lower_cleanup (struct leh_state *state, gimple tp)
/* In this case honor_protect_cleanup_actions had nothing to do,
and we should process this normally. */
lower_eh_constructs_1 (state, gimple_try_cleanup (tp));
- result = frob_into_branch_around (tp, fake_tf.eh_label,
- fake_tf.fallthru_label);
+ result = frob_into_branch_around (tp, this_region,
+ fake_tf.fallthru_label);
}
else
{
@@ -1822,9 +1816,7 @@ lower_cleanup (struct leh_state *state, gimple tp)
return result;
}
-
-
-/* Main loop for lowering eh constructs. Also moves gsi to the next
+/* Main loop for lowering eh constructs. Also moves gsi to the next
statement. */
static void
@@ -1837,6 +1829,52 @@ lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi)
switch (gimple_code (stmt))
{
case GIMPLE_CALL:
+ {
+ tree fndecl = gimple_call_fndecl (stmt);
+ tree rhs, lhs;
+
+ if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_EH_POINTER:
+ /* The front end may have generated a call to
+ __builtin_eh_pointer (0) within a catch region. Replace
+ this zero argument with the current catch region number. */
+ if (state->ehp_region)
+ {
+ tree nr = build_int_cst (NULL, state->ehp_region->index);
+ gimple_call_set_arg (stmt, 0, nr);
+ }
+ else
+ {
+ /* The user has dome something silly. Remove it. */
+ rhs = build_int_cst (ptr_type_node, 0);
+ goto do_replace;
+ }
+ break;
+
+ case BUILT_IN_EH_FILTER:
+ /* ??? This should never appear, but since it's a builtin it
+ is accessible to abuse by users. Just remove it and
+ replace the use with the arbitrary value zero. */
+ rhs = build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
+ do_replace:
+ lhs = gimple_call_lhs (stmt);
+ x = gimple_build_assign (lhs, rhs);
+ gsi_insert_before (gsi, x, GSI_SAME_STMT);
+ /* FALLTHRU */
+
+ case BUILT_IN_EH_COPY_VALUES:
+ /* Likewise this should not appear. Remove it. */
+ gsi_remove (gsi, true);
+ return;
+
+ default:
+ break;
+ }
+ }
+ /* FALLTHRU */
+
case GIMPLE_ASSIGN:
/* If the stmt can throw use a new temporary for the assignment
to a LHS. This makes sure the old value of the LHS is
@@ -1889,6 +1927,9 @@ lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi)
case GIMPLE_EH_FILTER:
replace = lower_eh_filter (state, stmt);
break;
+ case GIMPLE_EH_MUST_NOT_THROW:
+ replace = lower_eh_must_not_throw (state, stmt);
+ break;
default:
replace = lower_cleanup (state, stmt);
break;
@@ -1926,19 +1967,40 @@ static unsigned int
lower_eh_constructs (void)
{
struct leh_state null_state;
+ gimple_seq bodyp;
- gimple_seq bodyp = gimple_body (current_function_decl);
+ bodyp = gimple_body (current_function_decl);
+ if (bodyp == NULL)
+ return 0;
finally_tree = htab_create (31, struct_ptr_hash, struct_ptr_eq, free);
+ eh_region_may_contain_throw = BITMAP_ALLOC (NULL);
+ memset (&null_state, 0, sizeof (null_state));
collect_finally_tree_1 (bodyp, NULL);
-
- memset (&null_state, 0, sizeof (null_state));
lower_eh_constructs_1 (&null_state, bodyp);
+ /* We assume there's a return statement, or something, at the end of
+ the function, and thus ploping the EH sequence afterward won't
+ change anything. */
+ gcc_assert (!gimple_seq_may_fallthru (bodyp));
+ gimple_seq_add_seq (&bodyp, eh_seq);
+
+ /* We assume that since BODYP already existed, adding EH_SEQ to it
+ didn't change its value, and we don't have to re-set the function. */
+ gcc_assert (bodyp == gimple_body (current_function_decl));
+
htab_delete (finally_tree);
+ BITMAP_FREE (eh_region_may_contain_throw);
+ eh_seq = NULL;
+
+ /* If this function needs a language specific EH personality routine
+ and the frontend didn't already set one do so now. */
+ if (function_needs_eh_personality (cfun) == eh_personality_lang
+ && !DECL_FUNCTION_PERSONALITY (current_function_decl))
+ DECL_FUNCTION_PERSONALITY (current_function_decl)
+ = lang_hooks.eh_personality ();
- collect_eh_region_array ();
return 0;
}
@@ -1960,234 +2022,213 @@ struct gimple_opt_pass pass_lower_eh =
TODO_dump_func /* todo_flags_finish */
}
};
-
-/* Construct EH edges for STMT. */
+/* Create the multiple edges from an EH_DISPATCH statement to all of
+ the possible handlers for its EH region. Return true if there's
+ no fallthru edge; false if there is. */
-static void
-make_eh_edge (struct eh_region_d *region, void *data)
+bool
+make_eh_dispatch_edges (gimple stmt)
{
- gimple stmt;
- tree lab;
+ eh_region r;
+ eh_catch c;
basic_block src, dst;
- stmt = (gimple) data;
- lab = get_eh_region_tree_label (region);
-
- /* The code region is removed. */
- if (!lab)
- return;
+ r = get_eh_region_from_number (gimple_eh_dispatch_region (stmt));
src = gimple_bb (stmt);
- dst = label_to_block (lab);
- /* ??? unreachable eh region cleanup may not
- happen before early inlining. This can lead
- to NULL dst returned. */
- if (dst)
- make_edge (src, dst, EDGE_EH);
-}
-
-/* See if STMT is call that might be inlined. */
+ switch (r->type)
+ {
+ case ERT_TRY:
+ for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
+ {
+ dst = label_to_block (c->label);
+ make_edge (src, dst, 0);
-static bool
-inlinable_call_p (gimple stmt)
-{
- tree decl;
- if (gimple_code (stmt) != GIMPLE_CALL)
- return false;
- if (cfun->after_inlining)
- return false;
- /* Indirect calls can be propagated to direct call
- and inlined. */
- decl = gimple_call_fndecl (stmt);
- if (!decl)
- return true;
- if (cgraph_function_flags_ready
- && cgraph_function_body_availability (cgraph_node (decl))
- < AVAIL_OVERWRITABLE)
- return false;
- return !DECL_UNINLINABLE (decl);
-}
+ /* A catch-all handler doesn't have a fallthru. */
+ if (c->type_list == NULL)
+ return false;
+ }
+ break;
-void
-make_eh_edges (gimple stmt)
-{
- int region_nr;
- bool is_resx;
- bool inlinable = false;
- basic_block bb;
+ case ERT_ALLOWED_EXCEPTIONS:
+ dst = label_to_block (r->u.allowed.label);
+ make_edge (src, dst, 0);
+ break;
- if (gimple_code (stmt) == GIMPLE_RESX)
- {
- region_nr = gimple_resx_region (stmt);
- is_resx = true;
- }
- else
- {
- region_nr = lookup_stmt_eh_region (stmt);
- if (region_nr < 0)
- return;
- is_resx = false;
- inlinable = inlinable_call_p (stmt);
+ default:
+ gcc_unreachable ();
}
- foreach_reachable_handler (region_nr, is_resx, inlinable, make_eh_edge, stmt);
-
- /* Make CFG profile more consistent assuming that exception will resume to first
- available EH handler. In practice this makes little difference, but we get
- fewer consistency errors in the dumps. */
- bb = gimple_bb (stmt);
- if (is_resx && EDGE_COUNT (bb->succs))
- EDGE_SUCC (bb, 0)->probability = REG_BR_PROB_BASE;
+ return true;
}
-/* Redirect EH edge E to NEW_BB. */
+/* Create the single EH edge from STMT to its nearest landing pad,
+ if there is such a landing pad within the current function. */
-edge
-redirect_eh_edge (edge e, basic_block new_bb)
+void
+make_eh_edges (gimple stmt)
{
- gimple stmt = gsi_stmt (gsi_last_bb (e->src));
- int region_nr, new_region_nr;
- bool is_resx;
- bool inlinable = false;
- tree label = gimple_block_label (new_bb);
- struct eh_region_d *r;
+ basic_block src, dst;
+ eh_landing_pad lp;
+ int lp_nr;
- if (gimple_code (stmt) == GIMPLE_RESX)
- {
- region_nr = gimple_resx_region (stmt);
- is_resx = true;
- }
- else
- {
- region_nr = lookup_stmt_eh_region (stmt);
- gcc_assert (region_nr >= 0);
- is_resx = false;
- inlinable = inlinable_call_p (stmt);
- }
+ lp_nr = lookup_stmt_eh_lp (stmt);
+ if (lp_nr <= 0)
+ return;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Redirecting EH edge %i->%i to %i, region %i, resx %i\n",
- e->src->index, e->dest->index, new_bb->index, region_nr, is_resx);
- r = redirect_eh_edge_to_label (e, label, is_resx, inlinable, region_nr);
- new_region_nr = get_eh_region_number (r);
- if (new_region_nr != region_nr)
- {
- if (is_resx)
- gimple_resx_set_region (stmt, new_region_nr);
- else
- {
- remove_stmt_from_eh_region (stmt);
- add_stmt_to_eh_region (stmt, new_region_nr);
- }
- }
- e = ssa_redirect_edge (e, new_bb);
- return e;
+ lp = get_eh_landing_pad_from_number (lp_nr);
+ gcc_assert (lp != NULL);
+
+ src = gimple_bb (stmt);
+ dst = label_to_block (lp->post_landing_pad);
+#if 0
+ /* ??? unreachable eh region cleanup may not
+ happen before early inlining. This can lead
+ to NULL dst returned. */
+ if (dst)
+#endif
+ make_edge (src, dst, EDGE_EH);
}
-static bool mark_eh_edge_found_error;
+/* Do the work in redirecting EDGE_IN to NEW_BB within the EH region tree;
+ do not actually perform the final edge redirection.
-/* Mark edge make_eh_edge would create for given region by setting it aux
- field, output error if something goes wrong. */
+ CHANGE_REGION is true when we're being called from cleanup_empty_eh and
+ we intend to change the destination EH region as well; this means
+ EH_LANDING_PAD_NR must already be set on the destination block label.
+ If false, we're being called from generic cfg manipulation code and we
+ should preserve our place within the region tree. */
static void
-mark_eh_edge (struct eh_region_d *region, void *data)
+redirect_eh_edge_1 (edge edge_in, basic_block new_bb, bool change_region)
{
- gimple stmt;
- tree lab;
- basic_block src, dst;
+ eh_landing_pad old_lp, new_lp;
+ basic_block old_bb;
+ gimple throw_stmt;
+ int old_lp_nr, new_lp_nr;
+ tree old_label, new_label;
+ edge_iterator ei;
edge e;
- stmt = (gimple) data;
- lab = get_eh_region_tree_label (region);
+ old_bb = edge_in->dest;
+ old_label = gimple_block_label (old_bb);
+ old_lp_nr = EH_LANDING_PAD_NR (old_label);
+ gcc_assert (old_lp_nr > 0);
+ old_lp = get_eh_landing_pad_from_number (old_lp_nr);
- src = gimple_bb (stmt);
- dst = label_to_block (lab);
+ throw_stmt = last_stmt (edge_in->src);
+ gcc_assert (lookup_stmt_eh_lp (throw_stmt) == old_lp_nr);
- /* ??? unreachable eh region not removed. */
- if (!dst)
- return;
+ new_label = gimple_block_label (new_bb);
- e = find_edge (src, dst);
- if (!e)
+ /* Look for an existing region that might be using NEW_BB already. */
+ new_lp_nr = EH_LANDING_PAD_NR (new_label);
+ if (new_lp_nr)
{
- error ("EH edge %i->%i is missing", src->index, dst->index);
- mark_eh_edge_found_error = true;
+ new_lp = get_eh_landing_pad_from_number (new_lp_nr);
+ gcc_assert (new_lp);
+
+ /* Unless CHANGE_REGION is true, the new and old landing pad
+ had better be associated with the same EH region. */
+ gcc_assert (change_region || new_lp->region == old_lp->region);
}
- else if (!(e->flags & EDGE_EH))
- {
- error ("EH edge %i->%i miss EH flag", src->index, dst->index);
- mark_eh_edge_found_error = true;
- }
- else if (e->aux)
+ else
{
- /* ??? might not be mistake. */
- error ("EH edge %i->%i has duplicated regions", src->index, dst->index);
- mark_eh_edge_found_error = true;
+ new_lp = NULL;
+ gcc_assert (!change_region);
}
- else
- e->aux = (void *)1;
-}
-/* Verify that BB containing STMT as the last statement, has precisely the
- edges that make_eh_edges would create. */
-
-bool
-verify_eh_edges (gimple stmt)
-{
- int region_nr;
- bool is_resx;
- basic_block bb = gimple_bb (stmt);
- edge_iterator ei;
- edge e;
- bool inlinable = false;
+ /* Notice when we redirect the last EH edge away from OLD_BB. */
+ FOR_EACH_EDGE (e, ei, old_bb->preds)
+ if (e != edge_in && (e->flags & EDGE_EH))
+ break;
- FOR_EACH_EDGE (e, ei, bb->succs)
- gcc_assert (!e->aux);
- mark_eh_edge_found_error = false;
- if (gimple_code (stmt) == GIMPLE_RESX)
+ if (new_lp)
{
- region_nr = gimple_resx_region (stmt);
- is_resx = true;
+ /* NEW_LP already exists. If there are still edges into OLD_LP,
+ there's nothing to do with the EH tree. If there are no more
+ edges into OLD_LP, then we want to remove OLD_LP as it is unused.
+ If CHANGE_REGION is true, then our caller is expecting to remove
+ the landing pad. */
+ if (e == NULL && !change_region)
+ remove_eh_landing_pad (old_lp);
}
else
{
- region_nr = lookup_stmt_eh_region (stmt);
- if (region_nr < 0)
+ /* No correct landing pad exists. If there are no more edges
+ into OLD_LP, then we can simply re-use the existing landing pad.
+ Otherwise, we have to create a new landing pad. */
+ if (e == NULL)
{
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (e->flags & EDGE_EH)
- {
- error ("BB %i can not throw but has EH edges", bb->index);
- return true;
- }
- return false;
+ EH_LANDING_PAD_NR (old_lp->post_landing_pad) = 0;
+ new_lp = old_lp;
}
- if (!stmt_could_throw_p (stmt))
- {
- error ("BB %i last statement has incorrectly set region", bb->index);
- return true;
- }
- inlinable = inlinable_call_p (stmt);
- is_resx = false;
+ else
+ new_lp = gen_eh_landing_pad (old_lp->region);
+ new_lp->post_landing_pad = new_label;
+ EH_LANDING_PAD_NR (new_label) = new_lp->index;
}
- foreach_reachable_handler (region_nr, is_resx, inlinable, mark_eh_edge, stmt);
- FOR_EACH_EDGE (e, ei, bb->succs)
+ /* Maybe move the throwing statement to the new region. */
+ if (old_lp != new_lp)
+ {
+ remove_stmt_from_eh_lp (throw_stmt);
+ add_stmt_to_eh_lp (throw_stmt, new_lp->index);
+ }
+}
+
+/* Redirect EH edge E to NEW_BB. */
+
+edge
+redirect_eh_edge (edge edge_in, basic_block new_bb)
+{
+ redirect_eh_edge_1 (edge_in, new_bb, false);
+ return ssa_redirect_edge (edge_in, new_bb);
+}
+
+/* This is a subroutine of gimple_redirect_edge_and_branch. Update the
+ labels for redirecting a non-fallthru EH_DISPATCH edge E to NEW_BB.
+ The actual edge update will happen in the caller. */
+
+void
+redirect_eh_dispatch_edge (gimple stmt, edge e, basic_block new_bb)
+{
+ tree new_lab = gimple_block_label (new_bb);
+ bool any_changed = false;
+ basic_block old_bb;
+ eh_region r;
+ eh_catch c;
+
+ r = get_eh_region_from_number (gimple_eh_dispatch_region (stmt));
+ switch (r->type)
{
- if ((e->flags & EDGE_EH) && !e->aux)
+ case ERT_TRY:
+ for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
{
- error ("unnecessary EH edge %i->%i", bb->index, e->dest->index);
- mark_eh_edge_found_error = true;
- return true;
+ old_bb = label_to_block (c->label);
+ if (old_bb == e->dest)
+ {
+ c->label = new_lab;
+ any_changed = true;
+ }
}
- e->aux = NULL;
+ break;
+
+ case ERT_ALLOWED_EXCEPTIONS:
+ old_bb = label_to_block (r->u.allowed.label);
+ gcc_assert (old_bb == e->dest);
+ r->u.allowed.label = new_lab;
+ any_changed = true;
+ break;
+
+ default:
+ gcc_unreachable ();
}
- return mark_eh_edge_found_error;
+ gcc_assert (any_changed);
}
-
/* Helper function for operation_could_trap_p and stmt_could_throw_p. */
@@ -2311,7 +2352,7 @@ tree_could_trap_p (tree expr)
if (!expr)
return false;
-
+
code = TREE_CODE (expr);
t = TREE_TYPE (expr);
@@ -2353,20 +2394,16 @@ tree_could_trap_p (tree expr)
base = TREE_OPERAND (expr, 0);
if (tree_could_trap_p (base))
return true;
-
if (TREE_THIS_NOTRAP (expr))
return false;
-
return !range_in_array_bounds_p (expr);
case ARRAY_REF:
base = TREE_OPERAND (expr, 0);
if (tree_could_trap_p (base))
return true;
-
if (TREE_THIS_NOTRAP (expr))
return false;
-
return !in_array_bounds_p (expr);
case INDIRECT_REF:
@@ -2377,7 +2414,6 @@ tree_could_trap_p (tree expr)
case ASM_EXPR:
return TREE_THIS_VOLATILE (expr);
-
case CALL_EXPR:
t = get_callee_fndecl (expr);
/* Assume that calls to weak functions may trap. */
@@ -2444,35 +2480,33 @@ stmt_could_throw_1_p (gimple stmt)
bool
stmt_could_throw_p (gimple stmt)
{
- enum gimple_code code;
-
if (!flag_exceptions)
return false;
/* The only statements that can throw an exception are assignments,
- conditionals, calls and asms. */
- code = gimple_code (stmt);
- if (code != GIMPLE_ASSIGN
- && code != GIMPLE_COND
- && code != GIMPLE_CALL
- && code != GIMPLE_ASM)
- return false;
+ conditionals, calls, resx, and asms. */
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_RESX:
+ return true;
- /* If exceptions can only be thrown by function calls and STMT is not a
- GIMPLE_CALL, the statement cannot throw. */
- if (!flag_non_call_exceptions && code != GIMPLE_CALL)
- return false;
+ case GIMPLE_CALL:
+ return !gimple_call_nothrow_p (stmt);
- if (code == GIMPLE_ASSIGN || code == GIMPLE_COND)
- return stmt_could_throw_1_p (stmt);
- else if (is_gimple_call (stmt))
- return (gimple_call_flags (stmt) & ECF_NOTHROW) == 0;
- else if (gimple_code (stmt) == GIMPLE_ASM)
- return (gimple_asm_volatile_p (stmt));
- else
- gcc_unreachable ();
+ case GIMPLE_ASSIGN:
+ case GIMPLE_COND:
+ if (!flag_non_call_exceptions)
+ return false;
+ return stmt_could_throw_1_p (stmt);
- return false;
+ case GIMPLE_ASM:
+ if (!flag_non_call_exceptions)
+ return false;
+ return gimple_asm_volatile_p (stmt);
+
+ default:
+ return false;
+ }
}
@@ -2486,8 +2520,8 @@ tree_could_throw_p (tree t)
if (TREE_CODE (t) == MODIFY_EXPR)
{
if (flag_non_call_exceptions
- && tree_could_trap_p (TREE_OPERAND (t, 0)))
- return true;
+ && tree_could_trap_p (TREE_OPERAND (t, 0)))
+ return true;
t = TREE_OPERAND (t, 1);
}
@@ -2506,25 +2540,13 @@ tree_could_throw_p (tree t)
bool
stmt_can_throw_external (gimple stmt)
{
- int region_nr;
- bool is_resx = false;
- bool inlinable_call = false;
+ int lp_nr;
if (!stmt_could_throw_p (stmt))
return false;
- if (gimple_code (stmt) == GIMPLE_RESX)
- {
- region_nr = gimple_resx_region (stmt);
- is_resx = true;
- }
- else
- region_nr = lookup_stmt_eh_region (stmt);
-
- if (region_nr < 0)
- return true;
-
- return can_throw_external_1 (region_nr, is_resx, inlinable_call);
+ lp_nr = lookup_stmt_eh_lp (stmt);
+ return lp_nr == 0;
}
/* Return true if STMT can throw an exception that is caught within
@@ -2533,49 +2555,56 @@ stmt_can_throw_external (gimple stmt)
bool
stmt_can_throw_internal (gimple stmt)
{
- int region_nr;
- bool is_resx = false;
- bool inlinable_call = false;
-
- if (gimple_code (stmt) == GIMPLE_RESX)
- {
- region_nr = gimple_resx_region (stmt);
- is_resx = true;
- }
- else
- {
- region_nr = lookup_stmt_eh_region (stmt);
- inlinable_call = inlinable_call_p (stmt);
- }
+ int lp_nr;
- if (region_nr < 0)
+ if (!stmt_could_throw_p (stmt))
return false;
- return can_throw_internal_1 (region_nr, is_resx, inlinable_call);
+ lp_nr = lookup_stmt_eh_lp (stmt);
+ return lp_nr > 0;
+}
+
+/* Given a statement STMT in IFUN, if STMT can no longer throw, then
+ remove any entry it might have from the EH table. Return true if
+ any change was made. */
+
+bool
+maybe_clean_eh_stmt_fn (struct function *ifun, gimple stmt)
+{
+ if (stmt_could_throw_p (stmt))
+ return false;
+ return remove_stmt_from_eh_lp_fn (ifun, stmt);
}
+/* Likewise, but always use the current function. */
+
+bool
+maybe_clean_eh_stmt (gimple stmt)
+{
+ return maybe_clean_eh_stmt_fn (cfun, stmt);
+}
/* Given a statement OLD_STMT and a new statement NEW_STMT that has replaced
OLD_STMT in the function, remove OLD_STMT from the EH table and put NEW_STMT
in the table if it should be in there. Return TRUE if a replacement was
done that my require an EH edge purge. */
-bool
-maybe_clean_or_replace_eh_stmt (gimple old_stmt, gimple new_stmt)
+bool
+maybe_clean_or_replace_eh_stmt (gimple old_stmt, gimple new_stmt)
{
- int region_nr = lookup_stmt_eh_region (old_stmt);
+ int lp_nr = lookup_stmt_eh_lp (old_stmt);
- if (region_nr >= 0)
+ if (lp_nr != 0)
{
bool new_stmt_could_throw = stmt_could_throw_p (new_stmt);
if (new_stmt == old_stmt && new_stmt_could_throw)
return false;
- remove_stmt_from_eh_region (old_stmt);
+ remove_stmt_from_eh_lp (old_stmt);
if (new_stmt_could_throw)
{
- add_stmt_to_eh_region (new_stmt, region_nr);
+ add_stmt_to_eh_lp (new_stmt, lp_nr);
return false;
}
else
@@ -2584,6 +2613,70 @@ maybe_clean_or_replace_eh_stmt (gimple old_stmt, gimple new_stmt)
return false;
}
+
+/* Given a statement OLD_STMT in OLD_FUN and a duplicate statment NEW_STMT
+ in NEW_FUN, copy the EH table data from OLD_STMT to NEW_STMT. The MAP
+ operand is the return value of duplicate_eh_regions. */
+
+bool
+maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple new_stmt,
+ struct function *old_fun, gimple old_stmt,
+ struct pointer_map_t *map, int default_lp_nr)
+{
+ int old_lp_nr, new_lp_nr;
+ void **slot;
+
+ if (!stmt_could_throw_p (new_stmt))
+ return false;
+
+ old_lp_nr = lookup_stmt_eh_lp_fn (old_fun, old_stmt);
+ if (old_lp_nr == 0)
+ {
+ if (default_lp_nr == 0)
+ return false;
+ new_lp_nr = default_lp_nr;
+ }
+ else if (old_lp_nr > 0)
+ {
+ eh_landing_pad old_lp, new_lp;
+
+ old_lp = VEC_index (eh_landing_pad, old_fun->eh->lp_array, old_lp_nr);
+ slot = pointer_map_contains (map, old_lp);
+ new_lp = (eh_landing_pad) *slot;
+ new_lp_nr = new_lp->index;
+ }
+ else
+ {
+ eh_region old_r, new_r;
+
+ old_r = VEC_index (eh_region, old_fun->eh->region_array, -old_lp_nr);
+ slot = pointer_map_contains (map, old_r);
+ new_r = (eh_region) *slot;
+ new_lp_nr = -new_r->index;
+ }
+
+ add_stmt_to_eh_lp_fn (new_fun, new_stmt, new_lp_nr);
+ return true;
+}
+
+/* Similar, but both OLD_STMT and NEW_STMT are within the current function,
+ and thus no remapping is required. */
+
+bool
+maybe_duplicate_eh_stmt (gimple new_stmt, gimple old_stmt)
+{
+ int lp_nr;
+
+ if (!stmt_could_throw_p (new_stmt))
+ return false;
+
+ lp_nr = lookup_stmt_eh_lp (old_stmt);
+ if (lp_nr == 0)
+ return false;
+
+ add_stmt_to_eh_lp (new_stmt, lp_nr);
+ return true;
+}
/* Returns TRUE if oneh and twoh are exception handlers (gimple_try_cleanup of
GIMPLE_TRY) that are similar enough to be considered the same. Currently
@@ -2620,7 +2713,7 @@ same_handler_p (gimple_seq oneh, gimple_seq twoh)
for (ai = 0; ai < gimple_call_num_args (ones); ++ai)
if (!operand_equal_p (gimple_call_arg (ones, ai),
- gimple_call_arg (twos, ai), 0))
+ gimple_call_arg (twos, ai), 0))
return false;
return true;
@@ -2719,12 +2812,18 @@ refactor_eh (void)
return 0;
}
+static bool
+gate_refactor_eh (void)
+{
+ return flag_exceptions != 0;
+}
+
struct gimple_opt_pass pass_refactor_eh =
{
{
GIMPLE_PASS,
"ehopt", /* name */
- NULL, /* gate */
+ gate_refactor_eh, /* gate */
refactor_eh, /* execute */
NULL, /* sub */
NULL, /* next */
@@ -2737,512 +2836,919 @@ struct gimple_opt_pass pass_refactor_eh =
TODO_dump_func /* todo_flags_finish */
}
};
+
+/* At the end of gimple optimization, we can lower RESX. */
+
+static bool
+lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map)
+{
+ int lp_nr;
+ eh_region src_r, dst_r;
+ gimple_stmt_iterator gsi;
+ gimple x;
+ tree fn, src_nr;
+ bool ret = false;
-/* Walk statements, see what regions are really references and remove unreachable ones. */
+ lp_nr = lookup_stmt_eh_lp (stmt);
+ if (lp_nr != 0)
+ dst_r = get_eh_region_from_lp_number (lp_nr);
+ else
+ dst_r = NULL;
-static void
-tree_remove_unreachable_handlers (void)
+ src_r = get_eh_region_from_number (gimple_resx_region (stmt));
+ src_nr = build_int_cst (NULL, src_r->index);
+ gsi = gsi_last_bb (bb);
+
+ if (dst_r)
+ {
+ /* When we have a destination region, we resolve this by copying
+ the excptr and filter values into place, and changing the edge
+ to immediately after the landing pad. */
+ edge e;
+
+ if (lp_nr < 0)
+ {
+ basic_block new_bb;
+ void **slot;
+ tree lab;
+
+ /* We are resuming into a MUST_NOT_CALL region. Expand a call to
+ the failure decl into a new block, if needed. */
+ gcc_assert (dst_r->type == ERT_MUST_NOT_THROW);
+
+ slot = pointer_map_contains (mnt_map, dst_r);
+ if (slot == NULL)
+ {
+ gimple_stmt_iterator gsi2;
+
+ new_bb = create_empty_bb (bb);
+ lab = gimple_block_label (new_bb);
+ gsi2 = gsi_start_bb (new_bb);
+
+ fn = dst_r->u.must_not_throw.failure_decl;
+ x = gimple_build_call (fn, 0);
+ gimple_set_location (x, dst_r->u.must_not_throw.failure_loc);
+ gsi_insert_after (&gsi2, x, GSI_CONTINUE_LINKING);
+
+ slot = pointer_map_insert (mnt_map, dst_r);
+ *slot = lab;
+ }
+ else
+ {
+ lab = (tree) *slot;
+ new_bb = label_to_block (lab);
+ }
+
+ gcc_assert (EDGE_COUNT (bb->succs) == 0);
+ e = make_edge (bb, new_bb, EDGE_FALLTHRU);
+ e->count = bb->count;
+ e->probability = REG_BR_PROB_BASE;
+ }
+ else
+ {
+ edge_iterator ei;
+ tree dst_nr = build_int_cst (NULL, dst_r->index);
+
+ fn = implicit_built_in_decls[BUILT_IN_EH_COPY_VALUES];
+ x = gimple_build_call (fn, 2, dst_nr, src_nr);
+ gsi_insert_before (&gsi, x, GSI_SAME_STMT);
+
+ /* Update the flags for the outgoing edge. */
+ e = single_succ_edge (bb);
+ gcc_assert (e->flags & EDGE_EH);
+ e->flags = (e->flags & ~EDGE_EH) | EDGE_FALLTHRU;
+
+ /* If there are no more EH users of the landing pad, delete it. */
+ FOR_EACH_EDGE (e, ei, e->dest->preds)
+ if (e->flags & EDGE_EH)
+ break;
+ if (e == NULL)
+ {
+ eh_landing_pad lp = get_eh_landing_pad_from_number (lp_nr);
+ remove_eh_landing_pad (lp);
+ }
+ }
+
+ ret = true;
+ }
+ else
+ {
+ tree var;
+
+ /* When we don't have a destination region, this exception escapes
+ up the call chain. We resolve this by generating a call to the
+ _Unwind_Resume library function. */
+
+ /* ??? The ARM EABI redefines _Unwind_Resume as __cxa_end_cleanup
+ with no arguments for C++ and Java. Check for that. */
+ switch (targetm.arm_eabi_unwinder)
+ {
+ default:
+ fn = implicit_built_in_decls[BUILT_IN_UNWIND_RESUME];
+ if (TYPE_ARG_TYPES (TREE_TYPE (fn)) == void_list_node)
+ {
+ x = gimple_build_call (fn, 0);
+ gsi_insert_before (&gsi, x, GSI_SAME_STMT);
+ break;
+ }
+ /* FALLTHRU */
+
+ case 0:
+ fn = implicit_built_in_decls[BUILT_IN_EH_POINTER];
+ x = gimple_build_call (fn, 1, src_nr);
+ var = create_tmp_var (ptr_type_node, NULL);
+ var = make_ssa_name (var, x);
+ gimple_call_set_lhs (x, var);
+ gsi_insert_before (&gsi, x, GSI_SAME_STMT);
+
+ fn = implicit_built_in_decls[BUILT_IN_UNWIND_RESUME];
+ x = gimple_build_call (fn, 1, var);
+ gsi_insert_before (&gsi, x, GSI_SAME_STMT);
+ break;
+ }
+
+ gcc_assert (EDGE_COUNT (bb->succs) == 0);
+ }
+
+ gsi_remove (&gsi, true);
+
+ return ret;
+}
+
+static unsigned
+execute_lower_resx (void)
{
- sbitmap reachable, contains_stmt;
- VEC(int,heap) * label_to_region;
basic_block bb;
+ struct pointer_map_t *mnt_map;
+ bool dominance_invalidated = false;
+ bool any_rewritten = false;
- label_to_region = label_to_region_map ();
- reachable = sbitmap_alloc (num_eh_regions ());
- sbitmap_zero (reachable);
- contains_stmt = sbitmap_alloc (num_eh_regions ());
- sbitmap_zero (contains_stmt);
+ mnt_map = pointer_map_create ();
FOR_EACH_BB (bb)
- {
- gimple_stmt_iterator gsi;
- int region;
- bool has_eh_preds = bb_has_eh_pred (bb);
+ {
+ gimple last = last_stmt (bb);
+ if (last && is_gimple_resx (last))
+ {
+ dominance_invalidated |= lower_resx (bb, last, mnt_map);
+ any_rewritten = true;
+ }
+ }
+
+ pointer_map_destroy (mnt_map);
+
+ if (dominance_invalidated)
+ {
+ free_dominance_info (CDI_DOMINATORS);
+ free_dominance_info (CDI_POST_DOMINATORS);
+ }
+
+ return any_rewritten ? TODO_update_ssa_only_virtuals : 0;
+}
+
+static bool
+gate_lower_ehcontrol (void)
+{
+ return cfun->eh->region_tree != NULL;
+}
+
+struct gimple_opt_pass pass_lower_resx =
+{
+ {
+ GIMPLE_PASS,
+ "resx", /* name */
+ gate_lower_ehcontrol, /* gate */
+ execute_lower_resx, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_EH, /* tv_id */
+ PROP_gimple_lcf, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_verify_flow /* todo_flags_finish */
+ }
+};
+
+
+/* At the end of inlining, we can lower EH_DISPATCH. */
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+static void
+lower_eh_dispatch (basic_block src, gimple stmt)
+{
+ gimple_stmt_iterator gsi;
+ int region_nr;
+ eh_region r;
+ tree filter, fn;
+ gimple x;
+
+ region_nr = gimple_eh_dispatch_region (stmt);
+ r = get_eh_region_from_number (region_nr);
+
+ gsi = gsi_last_bb (src);
+
+ switch (r->type)
+ {
+ case ERT_TRY:
{
- gimple stmt = gsi_stmt (gsi);
+ VEC (tree, heap) *labels = NULL;
+ tree default_label = NULL;
+ eh_catch c;
+ edge_iterator ei;
+ edge e;
+
+ /* Collect the labels for a switch. Zero the post_landing_pad
+ field becase we'll no longer have anything keeping these labels
+ in existance and the optimizer will be free to merge these
+ blocks at will. */
+ for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
+ {
+ tree tp_node, flt_node, lab = c->label;
+
+ c->label = NULL;
+ tp_node = c->type_list;
+ flt_node = c->filter_list;
- if (gimple_code (stmt) == GIMPLE_LABEL && has_eh_preds)
+ if (tp_node == NULL)
+ {
+ default_label = lab;
+ break;
+ }
+ do
+ {
+ tree t = build3 (CASE_LABEL_EXPR, void_type_node,
+ TREE_VALUE (flt_node), NULL, lab);
+ VEC_safe_push (tree, heap, labels, t);
+
+ tp_node = TREE_CHAIN (tp_node);
+ flt_node = TREE_CHAIN (flt_node);
+ }
+ while (tp_node);
+ }
+
+ /* Clean up the edge flags. */
+ FOR_EACH_EDGE (e, ei, src->succs)
{
- int uid = LABEL_DECL_UID (gimple_label_label (stmt));
- int region;
+ if (e->flags & EDGE_FALLTHRU)
+ {
+ /* If there was no catch-all, use the fallthru edge. */
+ if (default_label == NULL)
+ default_label = gimple_block_label (e->dest);
+ e->flags &= ~EDGE_FALLTHRU;
+ }
+ }
+ gcc_assert (default_label != NULL);
- for (region = VEC_index (int, label_to_region, uid);
- region; region = get_next_region_sharing_label (region))
- SET_BIT (reachable, region);
+ /* Don't generate a switch if there's only a default case.
+ This is common in the form of try { A; } catch (...) { B; }. */
+ if (labels == NULL)
+ {
+ e = single_succ_edge (src);
+ e->flags |= EDGE_FALLTHRU;
+ }
+ else
+ {
+ fn = implicit_built_in_decls[BUILT_IN_EH_FILTER];
+ x = gimple_build_call (fn, 1, build_int_cst (NULL, region_nr));
+ filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)), NULL);
+ filter = make_ssa_name (filter, x);
+ gimple_call_set_lhs (x, filter);
+ gsi_insert_before (&gsi, x, GSI_SAME_STMT);
+
+ /* Turn the default label into a default case. */
+ default_label = build3 (CASE_LABEL_EXPR, void_type_node,
+ NULL, NULL, default_label);
+ sort_case_labels (labels);
+
+ x = gimple_build_switch_vec (filter, default_label, labels);
+ gsi_insert_before (&gsi, x, GSI_SAME_STMT);
+
+ VEC_free (tree, heap, labels);
}
- if (gimple_code (stmt) == GIMPLE_RESX)
- SET_BIT (reachable,
- VEC_index (eh_region, cfun->eh->region_array,
- gimple_resx_region (stmt))->region_number);
- if ((region = lookup_stmt_eh_region (stmt)) >= 0)
- SET_BIT (contains_stmt, region);
}
- }
+ break;
+
+ case ERT_ALLOWED_EXCEPTIONS:
+ {
+ edge b_e = BRANCH_EDGE (src);
+ edge f_e = FALLTHRU_EDGE (src);
+
+ fn = implicit_built_in_decls[BUILT_IN_EH_FILTER];
+ x = gimple_build_call (fn, 1, build_int_cst (NULL, region_nr));
+ filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)), NULL);
+ filter = make_ssa_name (filter, x);
+ gimple_call_set_lhs (x, filter);
+ gsi_insert_before (&gsi, x, GSI_SAME_STMT);
+
+ r->u.allowed.label = NULL;
+ x = gimple_build_cond (EQ_EXPR, filter,
+ build_int_cst (TREE_TYPE (filter),
+ r->u.allowed.filter),
+ NULL_TREE, NULL_TREE);
+ gsi_insert_before (&gsi, x, GSI_SAME_STMT);
+
+ b_e->flags = b_e->flags | EDGE_TRUE_VALUE;
+ f_e->flags = (f_e->flags & ~EDGE_FALLTHRU) | EDGE_FALSE_VALUE;
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ /* Replace the EH_DISPATCH with the SWITCH or COND generated above. */
+ gsi_remove (&gsi, true);
+}
+
+static unsigned
+execute_lower_eh_dispatch (void)
+{
+ basic_block bb;
+ bool any_rewritten = false;
+
+ assign_filter_values ();
+
+ FOR_EACH_BB (bb)
+ {
+ gimple last = last_stmt (bb);
+ if (last && gimple_code (last) == GIMPLE_EH_DISPATCH)
+ {
+ lower_eh_dispatch (bb, last);
+ any_rewritten = true;
+ }
+ }
+
+ return any_rewritten ? TODO_update_ssa_only_virtuals : 0;
+}
+
+struct gimple_opt_pass pass_lower_eh_dispatch =
+{
+ {
+ GIMPLE_PASS,
+ "ehdisp", /* name */
+ gate_lower_ehcontrol, /* gate */
+ execute_lower_eh_dispatch, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_EH, /* tv_id */
+ PROP_gimple_lcf, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_verify_flow /* todo_flags_finish */
+ }
+};
+
+/* Walk statements, see what regions are really referenced and remove
+ those that are unused. */
+
+static void
+remove_unreachable_handlers (void)
+{
+ sbitmap r_reachable, lp_reachable;
+ eh_region region;
+ eh_landing_pad lp;
+ basic_block bb;
+ int lp_nr, r_nr;
+
+ r_reachable = sbitmap_alloc (VEC_length (eh_region, cfun->eh->region_array));
+ lp_reachable
+ = sbitmap_alloc (VEC_length (eh_landing_pad, cfun->eh->lp_array));
+ sbitmap_zero (r_reachable);
+ sbitmap_zero (lp_reachable);
+
+ FOR_EACH_BB (bb)
+ {
+ gimple_stmt_iterator gsi = gsi_start_bb (bb);
+
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ lp_nr = lookup_stmt_eh_lp (stmt);
+
+ /* Negative LP numbers are MUST_NOT_THROW regions which
+ are not considered BB enders. */
+ if (lp_nr < 0)
+ SET_BIT (r_reachable, -lp_nr);
+
+ /* Positive LP numbers are real landing pads, are are BB enders. */
+ else if (lp_nr > 0)
+ {
+ gcc_assert (gsi_one_before_end_p (gsi));
+ region = get_eh_region_from_lp_number (lp_nr);
+ SET_BIT (r_reachable, region->index);
+ SET_BIT (lp_reachable, lp_nr);
+ }
+ }
+ }
if (dump_file)
{
fprintf (dump_file, "Before removal of unreachable regions:\n");
dump_eh_tree (dump_file, cfun);
fprintf (dump_file, "Reachable regions: ");
- dump_sbitmap_file (dump_file, reachable);
- fprintf (dump_file, "Regions containing insns: ");
- dump_sbitmap_file (dump_file, contains_stmt);
+ dump_sbitmap_file (dump_file, r_reachable);
+ fprintf (dump_file, "Reachable landing pads: ");
+ dump_sbitmap_file (dump_file, lp_reachable);
}
- remove_unreachable_regions (reachable, contains_stmt);
- sbitmap_free (reachable);
- sbitmap_free (contains_stmt);
- VEC_free (int, heap, label_to_region);
+ for (r_nr = 1;
+ VEC_iterate (eh_region, cfun->eh->region_array, r_nr, region); ++r_nr)
+ if (region && !TEST_BIT (r_reachable, r_nr))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Removing unreachable region %d\n", r_nr);
+ remove_eh_handler (region);
+ }
+
+ for (lp_nr = 1;
+ VEC_iterate (eh_landing_pad, cfun->eh->lp_array, lp_nr, lp); ++lp_nr)
+ if (lp && !TEST_BIT (lp_reachable, lp_nr))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Removing unreachable landing pad %d\n", lp_nr);
+ remove_eh_landing_pad (lp);
+ }
+
if (dump_file)
{
fprintf (dump_file, "\n\nAfter removal of unreachable regions:\n");
dump_eh_tree (dump_file, cfun);
fprintf (dump_file, "\n\n");
}
+
+ sbitmap_free (r_reachable);
+ sbitmap_free (lp_reachable);
+
+#ifdef ENABLE_CHECKING
+ verify_eh_tree (cfun);
+#endif
}
-/* Pattern match emtpy EH receiver looking like:
-
- save_filt.6352_662 = [filter_expr] <<<filter object>>>;
- save_eptr.6351_663 = [exc_ptr_expr] <<<exception object>>>;
- <<<exception object>>> = save_eptr.6351_663;
- <<<filter object>>> = save_filt.6352_662;
- resx 1
+/* Remove regions that do not have landing pads. This assumes
+ that remove_unreachable_handlers has already been run, and
+ that we've just manipulated the landing pads since then. */
- And various minor variants after DCE or copy propagation.
- */
+static void
+remove_unreachable_handlers_no_lp (void)
+{
+ eh_region r;
+ int i;
-static int
-tree_empty_eh_handler_p (basic_block bb)
+ for (i = 1; VEC_iterate (eh_region, cfun->eh->region_array, i, r); ++i)
+ if (r && r->landing_pads == NULL && r->type != ERT_MUST_NOT_THROW)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Removing unreachable region %d\n", i);
+ remove_eh_handler (r);
+ }
+}
+
+/* Undo critical edge splitting on an EH landing pad. Earlier, we
+ optimisticaly split all sorts of edges, including EH edges. The
+ optimization passes in between may not have needed them; if not,
+ we should undo the split.
+
+ Recognize this case by having one EH edge incoming to the BB and
+ one normal edge outgoing; BB should be empty apart from the
+ post_landing_pad label.
+
+ Note that this is slightly different from the empty handler case
+ handled by cleanup_empty_eh, in that the actual handler may yet
+ have actual code but the landing pad has been separated from the
+ handler. As such, cleanup_empty_eh relies on this transformation
+ having been done first. */
+
+static bool
+unsplit_eh (eh_landing_pad lp)
{
+ basic_block bb = label_to_block (lp->post_landing_pad);
gimple_stmt_iterator gsi;
- int region;
+ edge e_in, e_out;
+
+ /* Quickly check the edge counts on BB for singularity. */
+ if (EDGE_COUNT (bb->preds) != 1 || EDGE_COUNT (bb->succs) != 1)
+ return false;
+ e_in = EDGE_PRED (bb, 0);
+ e_out = EDGE_SUCC (bb, 0);
+
+ /* Input edge must be EH and output edge must be normal. */
+ if ((e_in->flags & EDGE_EH) == 0 || (e_out->flags & EDGE_EH) != 0)
+ return false;
+
+ /* The block must be empty except for the labels. */
+ if (!gsi_end_p (gsi_after_labels (bb)))
+ return false;
+
+ /* The destination block must not already have a landing pad
+ for a different region. */
+ for (gsi = gsi_start_bb (e_out->dest); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ tree lab;
+ int lp_nr;
+
+ if (gimple_code (stmt) != GIMPLE_LABEL)
+ break;
+ lab = gimple_label_label (stmt);
+ lp_nr = EH_LANDING_PAD_NR (lab);
+ if (lp_nr && get_eh_region_from_lp_number (lp_nr) != lp->region)
+ return false;
+ }
+
+ /* ??? I can't imagine there would be PHI nodes, since by nature
+ of critical edge splitting this block should never have been
+ a dominance frontier. If cfg cleanups somehow confuse this,
+ due to single edges in and out we ought to have degenerate PHIs
+ and can easily propagate the PHI arguments. */
+ gcc_assert (gimple_seq_empty_p (phi_nodes (bb)));
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Unsplit EH landing pad %d to block %i.\n",
+ lp->index, e_out->dest->index);
+
+ /* Redirect the edge. Since redirect_eh_edge_1 expects to be moving
+ a successor edge, humor it. But do the real CFG change with the
+ predecessor of E_OUT in order to preserve the ordering of arguments
+ to the PHI nodes in E_OUT->DEST. */
+ redirect_eh_edge_1 (e_in, e_out->dest, false);
+ redirect_edge_pred (e_out, e_in->src);
+ e_out->flags = e_in->flags;
+ e_out->probability = e_in->probability;
+ e_out->count = e_in->count;
+ remove_edge (e_in);
+
+ return true;
+}
+
+/* Examine each landing pad block and see if it matches unsplit_eh. */
+
+static bool
+unsplit_all_eh (void)
+{
+ bool changed = false;
+ eh_landing_pad lp;
+ int i;
+
+ for (i = 1; VEC_iterate (eh_landing_pad, cfun->eh->lp_array, i, lp); ++i)
+ if (lp)
+ changed |= unsplit_eh (lp);
+
+ return changed;
+}
+
+/* A subroutine of cleanup_empty_eh. Redirect all EH edges incoming
+ to OLD_BB to NEW_BB; return true on success, false on failure.
+
+ OLD_BB_OUT is the edge into NEW_BB from OLD_BB, so if we miss any
+ PHI variables from OLD_BB we can pick them up from OLD_BB_OUT.
+ Virtual PHIs may be deleted and marked for renaming. */
+
+static bool
+cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb,
+ edge old_bb_out)
+{
+ gimple_stmt_iterator ngsi, ogsi;
edge_iterator ei;
edge e;
- use_operand_p imm_use;
- gimple use_stmt;
- bool found = false;
+ bitmap rename_virts;
+ bitmap ophi_handled;
- gsi = gsi_last_bb (bb);
+ FOR_EACH_EDGE (e, ei, old_bb->preds)
+ redirect_edge_var_map_clear (e);
- /* RESX */
- if (gsi_end_p (gsi))
- return 0;
- if (gimple_code (gsi_stmt (gsi)) != GIMPLE_RESX)
- return 0;
- region = gimple_resx_region (gsi_stmt (gsi));
+ ophi_handled = BITMAP_ALLOC (NULL);
+ rename_virts = BITMAP_ALLOC (NULL);
- /* filter_object set. */
- gsi_prev_nondebug (&gsi);
- if (gsi_end_p (gsi))
- return 0;
- if (gimple_code (gsi_stmt (gsi)) == GIMPLE_ASSIGN)
+ /* First, iterate through the PHIs on NEW_BB and set up the edge_var_map
+ for the edges we're going to move. */
+ for (ngsi = gsi_start_phis (new_bb); !gsi_end_p (ngsi); gsi_next (&ngsi))
{
- tree filter_tmp;
- tree exc_ptr_tmp;
+ gimple ophi, nphi = gsi_stmt (ngsi);
+ tree nresult, nop;
- if (TREE_CODE (gimple_assign_lhs (gsi_stmt (gsi))) != FILTER_EXPR)
- return 0;
- filter_tmp = gimple_assign_rhs1 (gsi_stmt (gsi));
+ nresult = gimple_phi_result (nphi);
+ nop = gimple_phi_arg_def (nphi, old_bb_out->dest_idx);
- /* filter_object set. */
- gsi_prev_nondebug (&gsi);
- if (gsi_end_p (gsi))
- return 0;
- if (gimple_code (gsi_stmt (gsi)) != GIMPLE_ASSIGN)
- return 0;
- if (TREE_CODE (gimple_assign_lhs (gsi_stmt (gsi))) != EXC_PTR_EXPR)
- return 0;
- exc_ptr_tmp = gimple_assign_rhs1 (gsi_stmt (gsi));
-
- /* exc_ptr get. */
- if (TREE_CODE (exc_ptr_tmp) != EXC_PTR_EXPR)
+ /* Find the corresponding PHI in OLD_BB so we can forward-propagate
+ the source ssa_name. */
+ ophi = NULL;
+ for (ogsi = gsi_start_phis (old_bb); !gsi_end_p (ogsi); gsi_next (&ogsi))
{
- gsi_prev_nondebug (&gsi);
- if (gsi_end_p (gsi))
- return 0;
- if (gimple_code (gsi_stmt (gsi)) != GIMPLE_ASSIGN)
- return 0;
- if (TREE_CODE (gimple_assign_rhs1 (gsi_stmt (gsi))) != EXC_PTR_EXPR)
- return 0;
- if (exc_ptr_tmp != gimple_assign_lhs (gsi_stmt (gsi)))
- return 0;
- if (!single_imm_use (exc_ptr_tmp, &imm_use, &use_stmt))
- return 0;
+ ophi = gsi_stmt (ogsi);
+ if (gimple_phi_result (ophi) == nop)
+ break;
+ ophi = NULL;
}
- /* filter_object get. */
- if (TREE_CODE (filter_tmp) != FILTER_EXPR)
+ /* If we did find the corresponding PHI, copy those inputs. */
+ if (ophi)
{
- gsi_prev_nondebug (&gsi);
- if (gsi_end_p (gsi))
- return 0;
- if (gimple_code (gsi_stmt (gsi)) != GIMPLE_ASSIGN)
- return 0;
- if (TREE_CODE (gimple_assign_rhs1 (gsi_stmt (gsi))) != FILTER_EXPR)
- return 0;
- if (filter_tmp != gimple_assign_lhs (gsi_stmt (gsi)))
- return 0;
- if (!single_imm_use (filter_tmp, &imm_use, &use_stmt))
- return 0;
+ bitmap_set_bit (ophi_handled, SSA_NAME_VERSION (nop));
+ FOR_EACH_EDGE (e, ei, old_bb->preds)
+ {
+ location_t oloc;
+ tree oop;
+
+ if ((e->flags & EDGE_EH) == 0)
+ continue;
+ oop = gimple_phi_arg_def (ophi, e->dest_idx);
+ oloc = gimple_phi_arg_location (ophi, e->dest_idx);
+ redirect_edge_var_map_add (e, nresult, oop, oloc);
+ }
+ }
+ /* If we didn't find the PHI, but it's a VOP, remember to rename
+ it later, assuming all other tests succeed. */
+ else if (!is_gimple_reg (nresult))
+ bitmap_set_bit (rename_virts, SSA_NAME_VERSION (nresult));
+ /* If we didn't find the PHI, and it's a real variable, we know
+ from the fact that OLD_BB is tree_empty_eh_handler_p that the
+ variable is unchanged from input to the block and we can simply
+ re-use the input to NEW_BB from the OLD_BB_OUT edge. */
+ else
+ {
+ location_t nloc
+ = gimple_phi_arg_location (nphi, old_bb_out->dest_idx);
+ FOR_EACH_EDGE (e, ei, old_bb->preds)
+ redirect_edge_var_map_add (e, nresult, nop, nloc);
}
-
- /* label. */
- gsi_prev_nondebug (&gsi);
- if (gsi_end_p (gsi))
- return 0;
}
- if (gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
- return 0;
- /* Be sure that there is at least on EH region reaching the block directly.
- After EH edge redirection, it is possible that block is reached by one handler
- but resumed by different. */
- FOR_EACH_EDGE (e, ei, bb->preds)
- if ((e->flags & EDGE_EH))
- found = true;
- if (found)
- return region;
- return 0;
-}
-
-/* Return true if it is possible to remove basic block BB and propagate
- through PHIs.
-
- This means that every PHI in BB has all uses such that they are PHIs
- of basic blocks reachable througt BB and they appears only in use
- reachable by the edge from BB to the block contianing the use.
-
- This is same as in merge-phi code, but in slightly more general setting
- because BB can have multiple successors. */
+ /* Second, verify that all PHIs from OLD_BB have been handled. If not,
+ we don't know what values from the other edges into NEW_BB to use. */
+ for (ogsi = gsi_start_phis (old_bb); !gsi_end_p (ogsi); gsi_next (&ogsi))
+ {
+ gimple ophi = gsi_stmt (ogsi);
+ tree oresult = gimple_phi_result (ophi);
+ if (!bitmap_bit_p (ophi_handled, SSA_NAME_VERSION (oresult)))
+ goto fail;
+ }
-static bool
-all_phis_safe_to_merge (basic_block bb)
-{
- gimple_stmt_iterator si;
- bool ok = true;
-
- for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
- {
- gimple phi = gsi_stmt (si);
- tree result = gimple_phi_result (phi);
- gimple stmt;
- use_operand_p imm_use;
- imm_use_iterator imm_iter;
-
- /* If the PHI's result is never used, then we can just
- ignore it. */
- if (has_zero_uses (result))
- continue;
- /* We can always rebuild virtuals if needed. */
- if (!is_gimple_reg (result))
- continue;
- FOR_EACH_IMM_USE_STMT (stmt, imm_iter, result)
- {
- if (gimple_code (stmt) != GIMPLE_PHI)
+ /* At this point we know that the merge will succeed. Remove the PHI
+ nodes for the virtuals that we want to rename. */
+ if (!bitmap_empty_p (rename_virts))
+ {
+ for (ngsi = gsi_start_phis (new_bb); !gsi_end_p (ngsi); )
+ {
+ gimple nphi = gsi_stmt (ngsi);
+ tree nresult = gimple_phi_result (nphi);
+ if (bitmap_bit_p (rename_virts, SSA_NAME_VERSION (nresult)))
{
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- "PHI result has use in non-PHI statement.\n");
- ok = false;
- BREAK_FROM_IMM_USE_STMT (imm_iter);
+ mark_virtual_phi_result_for_renaming (nphi);
+ remove_phi_node (&ngsi, true);
}
else
- FOR_EACH_IMM_USE_ON_STMT (imm_use, imm_iter)
- {
- edge e;
- e = gimple_phi_arg_edge (stmt, PHI_ARG_INDEX_FROM_USE (imm_use));
- if (e->src != bb)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "PHI has use in PHI not reached from"
- "empty cleanup itself.\n");
- ok = false;
- break;
- }
- }
- if (!ok)
- BREAK_FROM_IMM_USE_STMT (imm_iter);
- }
- if (!ok)
- return false;
+ gsi_next (&ngsi);
+ }
}
- return ok;
-}
-static bool dominance_info_invalidated;
+ /* Finally, move the edges and update the PHIs. */
+ for (ei = ei_start (old_bb->preds); (e = ei_safe_edge (ei)); )
+ if (e->flags & EDGE_EH)
+ {
+ redirect_eh_edge_1 (e, new_bb, true);
+ redirect_edge_succ (e, new_bb);
+ flush_pending_stmts (e);
+ }
+ else
+ ei_next (&ei);
-/* Information to pass into make_eh_edge_and_update_phi. */
+ BITMAP_FREE (ophi_handled);
+ BITMAP_FREE (rename_virts);
+ return true;
-struct update_info
-{
- basic_block bb_to_remove, bb;
- edge edge_to_remove;
-};
+ fail:
+ FOR_EACH_EDGE (e, ei, old_bb->preds)
+ redirect_edge_var_map_clear (e);
+ BITMAP_FREE (ophi_handled);
+ BITMAP_FREE (rename_virts);
+ return false;
+}
-/* DATA points to update-info structure.
- Like make_eh_edge create EH edge from DATA->bb to basic block containing
- handler of REGION. In addition also update PHI operands by copying
- operands from DATA->bb_to_remove. */
+/* A subroutine of cleanup_empty_eh. Move a landing pad LP from its
+ old region to NEW_REGION at BB. */
static void
-make_eh_edge_and_update_phi (struct eh_region_d *region, void *data)
+cleanup_empty_eh_move_lp (basic_block bb, edge e_out,
+ eh_landing_pad lp, eh_region new_region)
{
- struct update_info *info = (struct update_info *) data;
- edge e, e2;
- tree lab;
- basic_block src, dst;
- gimple_stmt_iterator si;
+ gimple_stmt_iterator gsi;
+ eh_landing_pad *pp;
- lab = get_eh_region_tree_label (region);
+ for (pp = &lp->region->landing_pads; *pp != lp; pp = &(*pp)->next_lp)
+ continue;
+ *pp = lp->next_lp;
- src = info->bb;
- dst = label_to_block (lab);
+ lp->region = new_region;
+ lp->next_lp = new_region->landing_pads;
+ new_region->landing_pads = lp;
- e = find_edge (src, dst);
- if (e)
- {
- gcc_assert (e->flags & EDGE_EH);
- e->aux = e;
- return;
- }
- dominance_info_invalidated = true;
- e2 = find_edge (info->bb_to_remove, dst);
- e = make_edge (src, dst, EDGE_EH);
- e->aux = e;
- gcc_assert (e2);
- for (si = gsi_start_phis (dst); !gsi_end_p (si); gsi_next (&si))
- {
- gimple phi = gsi_stmt (si);
- tree use = USE_FROM_PTR (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e2));
- gimple def = (TREE_CODE (use) == SSA_NAME
- ? SSA_NAME_DEF_STMT (use) : NULL);
+ /* Delete the RESX that was matched within the empty handler block. */
+ gsi = gsi_last_bb (bb);
+ mark_virtual_ops_for_renaming (gsi_stmt (gsi));
+ gsi_remove (&gsi, true);
- if (def && gimple_bb (def) == info->bb_to_remove)
- {
- use = USE_FROM_PTR (PHI_ARG_DEF_PTR_FROM_EDGE (def,
- info->edge_to_remove));
- gcc_assert (info->bb_to_remove == info->edge_to_remove->dest);
- def = TREE_CODE (use) == SSA_NAME ? SSA_NAME_DEF_STMT (use) : NULL;
- gcc_assert (!def
- || gimple_bb (def) != info->bb_to_remove
- || !is_gimple_reg (use));
- }
- SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), use);
- }
+ /* Clean up E_OUT for the fallthru. */
+ e_out->flags = (e_out->flags & ~EDGE_EH) | EDGE_FALLTHRU;
+ e_out->probability = REG_BR_PROB_BASE;
}
-/* Make EH edges corresponding to STMT while updating PHI nodes after removal
- empty cleanup BB_TO_REMOVE joined to BB containing STMT
- by EDGE_TO_REMOVE.
-
- Return if EDGE_TO_REMOVE was really removed. It might stay reachable when
- not all EH regions are cleaned up. */
+/* A subroutine of cleanup_empty_eh. Handle more complex cases of
+ unsplitting than unsplit_eh was prepared to handle, e.g. when
+ multiple incoming edges and phis are involved. */
static bool
-update_eh_edges (gimple stmt, basic_block bb_to_remove, edge edge_to_remove)
+cleanup_empty_eh_unsplit (basic_block bb, edge e_out, eh_landing_pad olp)
{
- int region_nr;
- bool is_resx;
- bool inlinable = false;
- struct update_info info;
- edge_iterator ei;
- edge e;
- int probability_sum = 0;
- bool removed = false;
+ gimple_stmt_iterator gsi;
+ eh_landing_pad nlp;
+ tree lab;
- info.bb_to_remove = bb_to_remove;
- info.bb = gimple_bb (stmt);
- info.edge_to_remove = edge_to_remove;
+ /* We really ought not have totally lost everything following
+ a landing pad label. Given that BB is empty, there had better
+ be a successor. */
+ gcc_assert (e_out != NULL);
- if (gimple_code (stmt) == GIMPLE_RESX)
+ /* Look for an EH label in the successor block. */
+ lab = NULL;
+ for (gsi = gsi_start_bb (e_out->dest); !gsi_end_p (gsi); gsi_next (&gsi))
{
- region_nr = gimple_resx_region (stmt);
- is_resx = true;
- }
- else
- {
- region_nr = lookup_stmt_eh_region (stmt);
- is_resx = false;
- inlinable = inlinable_call_p (stmt);
+ gimple stmt = gsi_stmt (gsi);
+ if (gimple_code (stmt) != GIMPLE_LABEL)
+ break;
+ lab = gimple_label_label (stmt);
+ if (EH_LANDING_PAD_NR (lab))
+ goto found;
}
+ return false;
+ found:
- /* First add new edges as neccesary. */
- foreach_reachable_handler (region_nr, is_resx, inlinable,
- make_eh_edge_and_update_phi, &info);
+ /* The other label had better be part of the same EH region. Given that
+ we've not lowered RESX, there should be no way to have a totally empty
+ landing pad that crosses to another EH region. */
+ nlp = get_eh_landing_pad_from_number (EH_LANDING_PAD_NR (lab));
+ gcc_assert (nlp->region == olp->region);
- /* And remove edges we didn't marked. */
- for (ei = ei_start (info.bb->succs); (e = ei_safe_edge (ei)); )
+ /* Attempt to move the PHIs into the successor block. */
+ if (cleanup_empty_eh_merge_phis (e_out->dest, bb, e_out))
{
- if ((e->flags & EDGE_EH) && !e->aux)
- {
- dominance_info_invalidated = true;
- if (e == edge_to_remove)
- removed = true;
- remove_edge (e);
- }
- else
- {
- e->aux = NULL;
- probability_sum += e->probability;
- ei_next (&ei);
- }
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "Unsplit EH landing pad %d to block %d via lp %d.\n",
+ olp->index, e_out->dest->index, nlp->index);
+
+ remove_eh_landing_pad (olp);
+ return true;
}
- /* Make CFG profile more consistent assuming that exception will resume to
- first available EH handler. In practice this makes little difference, but
- we get fewer consistency errors in the dumps. */
- if (is_resx && EDGE_COUNT (info.bb->succs) && !probability_sum)
- EDGE_SUCC (info.bb, 0)->probability = REG_BR_PROB_BASE;
- return removed;
+ return false;
}
-/* Look for basic blocks containing empty exception handler and remove them.
- This is similar to jump forwarding, just across EH edges. */
+/* Examine the block associated with LP to determine if it's an empty
+ handler for its EH region. If so, attempt to redirect EH edges to
+ an outer region. Return true the CFG was updated in any way. This
+ is similar to jump forwarding, just across EH edges. */
static bool
-cleanup_empty_eh (basic_block bb, VEC(int,heap) * label_to_region)
+cleanup_empty_eh (eh_landing_pad lp)
{
- int region;
- gimple_stmt_iterator si;
+ basic_block bb = label_to_block (lp->post_landing_pad);
+ gimple_stmt_iterator gsi;
+ gimple resx;
+ eh_region new_region;
edge_iterator ei;
+ edge e, e_out;
+ bool has_non_eh_pred;
+ int new_lp_nr;
- /* When handler of EH region winds up to be empty, we can safely
- remove it. This leads to inner EH regions to be redirected
- to outer one, if present in function. So we need to rebuild
- EH edges in all sources. */
- if ((region = tree_empty_eh_handler_p (bb))
- && all_phis_safe_to_merge (bb))
+ /* There can be zero or one edges out of BB. This is the quickest test. */
+ switch (EDGE_COUNT (bb->succs))
{
- edge e;
- bool found = false, removed_some = false, has_non_eh_preds = false;
- gimple_stmt_iterator gsi;
-
- /* Look for all EH regions sharing label of this block.
- If they are not same as REGION, remove them and replace them
- by outer region of REGION. Also note if REGION itself is one
- of them. */
+ case 0:
+ e_out = NULL;
+ break;
+ case 1:
+ e_out = EDGE_SUCC (bb, 0);
+ break;
+ default:
+ return false;
+ }
+ gsi = gsi_after_labels (bb);
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
- {
- int uid = LABEL_DECL_UID (gimple_label_label (gsi_stmt (gsi)));
- int r = VEC_index (int, label_to_region, uid);
- int next;
+ /* Make sure to skip debug statements. */
+ if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
+ gsi_next_nondebug (&gsi);
- while (r)
- {
- next = get_next_region_sharing_label (r);
- if (r == region)
- found = true;
- else
- {
- removed_some = true;
- remove_eh_region_and_replace_by_outer_of (r, region);
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Empty EH handler %i removed and "
- "replaced by %i\n", r, region);
- }
- r = next;
- }
- }
- else
- break;
-
- gcc_assert (found || removed_some);
- FOR_EACH_EDGE (e, ei, bb->preds)
- if (!(e->flags & EDGE_EH))
- has_non_eh_preds = true;
+ /* If the block is totally empty, look for more unsplitting cases. */
+ if (gsi_end_p (gsi))
+ return cleanup_empty_eh_unsplit (bb, e_out, lp);
- /* When block is empty EH cleanup, but it is reachable via non-EH code too,
- we can not remove the region it is resumed via, because doing so will
- lead to redirection of its RESX edges.
+ /* The block should consist only of a single RESX statement. */
+ resx = gsi_stmt (gsi);
+ if (!is_gimple_resx (resx))
+ return false;
+ gcc_assert (gsi_one_before_end_p (gsi));
- This case will be handled later after edge forwarding if the EH cleanup
- is really dead. */
+ /* Determine if there are non-EH edges, or resx edges into the handler. */
+ has_non_eh_pred = false;
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (!(e->flags & EDGE_EH))
+ has_non_eh_pred = true;
- if (found && !has_non_eh_preds)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Empty EH handler %i removed.\n", region);
- remove_eh_region (region);
- }
- else if (!removed_some)
- return false;
+ /* Find the handler that's outer of the empty handler by looking at
+ where the RESX instruction was vectored. */
+ new_lp_nr = lookup_stmt_eh_lp (resx);
+ new_region = get_eh_region_from_lp_number (new_lp_nr);
+ /* If there's no destination region within the current function,
+ redirection is trivial via removing the throwing statements from
+ the EH region, removing the EH edges, and allowing the block
+ to go unreachable. */
+ if (new_region == NULL)
+ {
+ gcc_assert (e_out == NULL);
for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
- {
- basic_block src = e->src;
- if (!(e->flags & EDGE_EH))
- {
- ei_next (&ei);
- continue;
- }
- if (stmt_can_throw_internal (last_stmt (src)))
- {
- if (!update_eh_edges (last_stmt (src), bb, e))
- ei_next (&ei);
- }
- else
+ if (e->flags & EDGE_EH)
+ {
+ gimple stmt = last_stmt (e->src);
+ remove_stmt_from_eh_lp (stmt);
remove_edge (e);
- }
-
- /* Verify that we eliminated all uses of PHI we are going to remove.
- If we didn't, rebuild SSA on affected variable (this is allowed only
- for virtuals). */
- for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
- {
- gimple phi = gsi_stmt (si);
- tree result = gimple_phi_result (phi);
- if (!has_zero_uses (result))
- {
- use_operand_p use_p;
- imm_use_iterator iter;
- gimple stmt;
+ }
+ else
+ ei_next (&ei);
+ goto succeed;
+ }
- FOR_EACH_IMM_USE_STMT (stmt, iter, result)
- {
- /* We have use, see if it won't disappear after
- removing BB. */
- if (gimple_bb (stmt) == bb)
- continue;
- if (gimple_code (stmt) == GIMPLE_PHI)
- {
- bool bad = false;
-
- FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
- if (gimple_phi_arg_edge (stmt,
- PHI_ARG_INDEX_FROM_USE (use_p))->src != bb)
- {
- bad = true;
- break;
- }
-
- if (!bad)
- continue;
- }
-
- gcc_assert (!is_gimple_reg (result));
- mark_sym_for_renaming (SSA_NAME_VAR (result));
- /* As we are going to delete this block we will release all
- defs which makes the immediate uses on use stmts invalid.
- Avoid that by replacing all uses with the bare variable
- and updating the stmts. */
- FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
- SET_USE (use_p, SSA_NAME_VAR (result));
- update_stmt (stmt);
- }
- }
- }
- if (!ei_safe_edge (ei_start (bb->preds)))
- delete_basic_block (bb);
+ /* If the destination region is a MUST_NOT_THROW, allow the runtime
+ to handle the abort and allow the blocks to go unreachable. */
+ if (new_region->type == ERT_MUST_NOT_THROW)
+ {
+ for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
+ if (e->flags & EDGE_EH)
+ {
+ gimple stmt = last_stmt (e->src);
+ remove_stmt_from_eh_lp (stmt);
+ add_stmt_to_eh_lp (stmt, new_lp_nr);
+ remove_edge (e);
+ }
+ else
+ ei_next (&ei);
+ goto succeed;
+ }
+
+ /* Try to redirect the EH edges and merge the PHIs into the destination
+ landing pad block. If the merge succeeds, we'll already have redirected
+ all the EH edges. The handler itself will go unreachable if there were
+ no normal edges. */
+ if (cleanup_empty_eh_merge_phis (e_out->dest, bb, e_out))
+ goto succeed;
+
+ /* Finally, if all input edges are EH edges, then we can (potentially)
+ reduce the number of transfers from the runtime by moving the landing
+ pad from the original region to the new region. This is a win when
+ we remove the last CLEANUP region along a particular exception
+ propagation path. Since nothing changes except for the region with
+ which the landing pad is associated, the PHI nodes do not need to be
+ adjusted at all. */
+ if (!has_non_eh_pred)
+ {
+ cleanup_empty_eh_move_lp (bb, e_out, lp, new_region);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Empty EH handler %i moved to EH region %i.\n",
+ lp->index, new_region->index);
+
+ /* ??? The CFG didn't change, but we may have rendered the
+ old EH region unreachable. Trigger a cleanup there. */
return true;
}
+
return false;
+
+ succeed:
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Empty EH handler %i removed.\n", lp->index);
+ remove_eh_landing_pad (lp);
+ return true;
}
+/* Do a post-order traversal of the EH region tree. Examine each
+ post_landing_pad block and see if we can eliminate it as empty. */
+
+static bool
+cleanup_all_empty_eh (void)
+{
+ bool changed = false;
+ eh_landing_pad lp;
+ int i;
+
+ for (i = 1; VEC_iterate (eh_landing_pad, cfun->eh->lp_array, i, lp); ++i)
+ if (lp)
+ changed |= cleanup_empty_eh (lp);
+
+ return changed;
+}
/* Perform cleanups and lowering of exception handling
1) cleanups regions with handlers doing nothing are optimized out
@@ -3250,63 +3756,58 @@ cleanup_empty_eh (basic_block bb, VEC(int,heap) * label_to_region)
3) Info about regions that are containing instructions, and regions
reachable via local EH edges is collected
4) Eh tree is pruned for regions no longer neccesary.
- */
+
+ TODO: Push MUST_NOT_THROW regions to the root of the EH tree.
+ Unify those that have the same failure decl and locus.
+*/
static unsigned int
-cleanup_eh (void)
+execute_cleanup_eh (void)
{
- bool changed = false;
- basic_block bb;
- VEC(int,heap) * label_to_region;
- int i;
+ /* Do this first: unsplit_all_eh and cleanup_all_empty_eh can die
+ looking up unreachable landing pads. */
+ remove_unreachable_handlers ();
- if (!cfun->eh)
- return 0;
- if (dump_file)
+ /* Watch out for the region tree vanishing due to all unreachable. */
+ if (cfun->eh->region_tree && optimize)
{
- fprintf (dump_file, "Before cleanups:\n");
- dump_eh_tree (dump_file, cfun);
- }
+ bool changed = false;
- if (optimize)
- {
- label_to_region = label_to_region_map ();
- dominance_info_invalidated = false;
- /* We cannot use FOR_EACH_BB, since the basic blocks may get removed. */
- for (i = NUM_FIXED_BLOCKS; i < last_basic_block; i++)
- {
- bb = BASIC_BLOCK (i);
- if (bb)
- changed |= cleanup_empty_eh (bb, label_to_region);
- }
- VEC_free (int, heap, label_to_region);
- if (dominance_info_invalidated)
+ changed |= unsplit_all_eh ();
+ changed |= cleanup_all_empty_eh ();
+
+ if (changed)
{
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
- }
- /* Removing contained cleanup can render MUST_NOT_THROW regions empty. */
- if (changed)
- delete_unreachable_blocks ();
- }
+ /* We delayed all basic block deletion, as we may have performed
+ cleanups on EH edges while non-EH edges were still present. */
+ delete_unreachable_blocks ();
- tree_remove_unreachable_handlers ();
- if (dump_file)
- {
- fprintf (dump_file, "After cleanups:\n");
- dump_eh_tree (dump_file, cfun);
+ /* We manipulated the landing pads. Remove any region that no
+ longer has a landing pad. */
+ remove_unreachable_handlers_no_lp ();
+
+ return TODO_cleanup_cfg | TODO_update_ssa_only_virtuals;
+ }
}
- return (changed ? TODO_cleanup_cfg | TODO_update_ssa : 0);
+ return 0;
+}
+
+static bool
+gate_cleanup_eh (void)
+{
+ return cfun->eh != NULL && cfun->eh->region_tree != NULL;
}
struct gimple_opt_pass pass_cleanup_eh = {
{
GIMPLE_PASS,
"ehcleanup", /* name */
- NULL, /* gate */
- cleanup_eh, /* execute */
+ gate_cleanup_eh, /* gate */
+ execute_cleanup_eh, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
@@ -3318,3 +3819,150 @@ struct gimple_opt_pass pass_cleanup_eh = {
TODO_dump_func /* todo_flags_finish */
}
};
+
+/* Verify that BB containing STMT as the last statement, has precisely the
+ edge that make_eh_edges would create. */
+
+bool
+verify_eh_edges (gimple stmt)
+{
+ basic_block bb = gimple_bb (stmt);
+ eh_landing_pad lp = NULL;
+ int lp_nr;
+ edge_iterator ei;
+ edge e, eh_edge;
+
+ lp_nr = lookup_stmt_eh_lp (stmt);
+ if (lp_nr > 0)
+ lp = get_eh_landing_pad_from_number (lp_nr);
+
+ eh_edge = NULL;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ if (e->flags & EDGE_EH)
+ {
+ if (eh_edge)
+ {
+ error ("BB %i has multiple EH edges", bb->index);
+ return true;
+ }
+ else
+ eh_edge = e;
+ }
+ }
+
+ if (lp == NULL)
+ {
+ if (eh_edge)
+ {
+ error ("BB %i can not throw but has an EH edge", bb->index);
+ return true;
+ }
+ return false;
+ }
+
+ if (!stmt_could_throw_p (stmt))
+ {
+ error ("BB %i last statement has incorrectly set lp", bb->index);
+ return true;
+ }
+
+ if (eh_edge == NULL)
+ {
+ error ("BB %i is missing an EH edge", bb->index);
+ return true;
+ }
+
+ if (eh_edge->dest != label_to_block (lp->post_landing_pad))
+ {
+ error ("Incorrect EH edge %i->%i", bb->index, eh_edge->dest->index);
+ return true;
+ }
+
+ return false;
+}
+
+/* Similarly, but handle GIMPLE_EH_DISPATCH specifically. */
+
+bool
+verify_eh_dispatch_edge (gimple stmt)
+{
+ eh_region r;
+ eh_catch c;
+ basic_block src, dst;
+ bool want_fallthru = true;
+ edge_iterator ei;
+ edge e, fall_edge;
+
+ r = get_eh_region_from_number (gimple_eh_dispatch_region (stmt));
+ src = gimple_bb (stmt);
+
+ FOR_EACH_EDGE (e, ei, src->succs)
+ gcc_assert (e->aux == NULL);
+
+ switch (r->type)
+ {
+ case ERT_TRY:
+ for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
+ {
+ dst = label_to_block (c->label);
+ e = find_edge (src, dst);
+ if (e == NULL)
+ {
+ error ("BB %i is missing an edge", src->index);
+ return true;
+ }
+ e->aux = (void *)e;
+
+ /* A catch-all handler doesn't have a fallthru. */
+ if (c->type_list == NULL)
+ {
+ want_fallthru = false;
+ break;
+ }
+ }
+ break;
+
+ case ERT_ALLOWED_EXCEPTIONS:
+ dst = label_to_block (r->u.allowed.label);
+ e = find_edge (src, dst);
+ if (e == NULL)
+ {
+ error ("BB %i is missing an edge", src->index);
+ return true;
+ }
+ e->aux = (void *)e;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ fall_edge = NULL;
+ FOR_EACH_EDGE (e, ei, src->succs)
+ {
+ if (e->flags & EDGE_FALLTHRU)
+ {
+ if (fall_edge != NULL)
+ {
+ error ("BB %i too many fallthru edges", src->index);
+ return true;
+ }
+ fall_edge = e;
+ }
+ else if (e->aux)
+ e->aux = NULL;
+ else
+ {
+ error ("BB %i has incorrect edge", src->index);
+ return true;
+ }
+ }
+ if ((fall_edge != NULL) ^ want_fallthru)
+ {
+ error ("BB %i has incorrect fallthru edge", src->index);
+ return true;
+ }
+
+ return false;
+}
diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h
index eef2f4324a9..fdb33378bee 100644
--- a/gcc/tree-flow-inline.h
+++ b/gcc/tree-flow-inline.h
@@ -616,12 +616,18 @@ is_global_var (const_tree t)
/* Return true if VAR may be aliased. A variable is considered as
maybe aliased if it has its address taken by the local TU
- or possibly by another TU. */
+ or possibly by another TU and might be modified through a pointer. */
static inline bool
may_be_aliased (const_tree var)
{
- return (TREE_PUBLIC (var) || DECL_EXTERNAL (var) || TREE_ADDRESSABLE (var));
+ return (TREE_CODE (var) != CONST_DECL
+ && !((TREE_STATIC (var) || TREE_PUBLIC (var) || DECL_EXTERNAL (var))
+ && TREE_READONLY (var)
+ && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (var)))
+ && (TREE_PUBLIC (var)
+ || DECL_EXTERNAL (var)
+ || TREE_ADDRESSABLE (var)));
}
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 11b67120e39..b93e2f4a373 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -134,9 +134,9 @@ struct GTY(()) tree_ann_common_d {
/* Annotation type. */
enum tree_ann_type type;
- /* Record EH region number into a statement tree created during RTL
- expansion (see gimple_to_tree). */
- int rn;
+ /* Record EH landing pad number into a statement tree created
+ during RTL expansion (see gimple_to_tree). */
+ int lp_nr;
/* Pointer to original GIMPLE statement. Used during RTL expansion
(see gimple_to_tree). */
@@ -637,9 +637,10 @@ typedef bool (*walk_use_def_chains_fn) (tree, gimple, void *);
extern void walk_use_def_chains (tree, walk_use_def_chains_fn, void *, bool);
void propagate_defs_into_debug_stmts (gimple, basic_block,
- const gimple_stmt_iterator *);
+ const gimple_stmt_iterator *);
void propagate_var_def_into_debug_stmts (tree, basic_block,
- const gimple_stmt_iterator *);
+ const gimple_stmt_iterator *);
+void release_defs_bitset (bitmap toremove);
/* In tree-into-ssa.c */
void update_ssa (unsigned);
@@ -806,6 +807,9 @@ bool contains_abnormal_ssa_name_p (tree);
bool stmt_dominates_stmt_p (gimple, gimple);
void mark_virtual_ops_for_renaming (gimple);
+/* In tree-ssa-dce.c */
+void mark_virtual_phi_result_for_renaming (gimple);
+
/* In tree-ssa-threadedge.c */
extern void threadedge_initialize_values (void);
extern void threadedge_finalize_values (void);
@@ -841,6 +845,9 @@ static inline bool array_ref_contains_indirect_ref (const_tree);
/* In tree-eh.c */
extern void make_eh_edges (gimple);
+extern bool make_eh_dispatch_edges (gimple);
+extern edge redirect_eh_edge (edge, basic_block);
+extern void redirect_eh_dispatch_edge (gimple, edge, basic_block);
extern bool tree_could_trap_p (tree);
extern bool operation_could_trap_helper_p (enum tree_code, bool, bool, bool,
bool, tree, bool *);
@@ -849,16 +856,22 @@ extern bool stmt_could_throw_p (gimple);
extern bool tree_could_throw_p (tree);
extern bool stmt_can_throw_internal (gimple);
extern bool stmt_can_throw_external (gimple);
-extern void add_stmt_to_eh_region (gimple, int);
-extern bool remove_stmt_from_eh_region (gimple);
+extern void add_stmt_to_eh_lp_fn (struct function *, gimple, int);
+extern void add_stmt_to_eh_lp (gimple, int);
+extern bool remove_stmt_from_eh_lp (gimple);
+extern bool remove_stmt_from_eh_lp_fn (struct function *, gimple);
+extern int lookup_stmt_eh_lp_fn (struct function *, gimple);
+extern int lookup_expr_eh_lp (tree);
+extern int lookup_stmt_eh_lp (gimple);
+extern bool maybe_clean_eh_stmt_fn (struct function *, gimple);
+extern bool maybe_clean_eh_stmt (gimple);
extern bool maybe_clean_or_replace_eh_stmt (gimple, gimple);
-extern void add_stmt_to_eh_region_fn (struct function *, gimple, int);
-extern bool remove_stmt_from_eh_region_fn (struct function *, gimple);
-extern int lookup_stmt_eh_region_fn (struct function *, gimple);
-extern int lookup_expr_eh_region (tree);
-extern int lookup_stmt_eh_region (gimple);
+extern bool maybe_duplicate_eh_stmt_fn (struct function *, gimple,
+ struct function *, gimple,
+ struct pointer_map_t *, int);
+extern bool maybe_duplicate_eh_stmt (gimple, gimple);
extern bool verify_eh_edges (gimple);
-
+extern bool verify_eh_dispatch_edge (gimple);
/* In tree-ssa-pre.c */
struct pre_expr_d;
@@ -925,6 +938,5 @@ unsigned int execute_fixup_cfg (void);
void swap_tree_operands (gimple, tree *, tree *);
int least_common_multiple (int, int);
-edge redirect_eh_edge (edge e, basic_block new_bb);
#endif /* _TREE_FLOW_H */
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index a2d27c8b766..c0c28a5fd05 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -65,7 +65,7 @@ along with GCC; see the file COPYING3. If not see
MODIFY_EXPRs that store to a dedicated returned-value variable.
The duplicated eh_region info of the copy will later be appended
to the info for the caller; the eh_region info in copied throwing
- statements and RESX_EXPRs is adjusted accordingly.
+ statements and RESX statements are adjusted accordingly.
Cloning: (only in C++) We have one body for a con/de/structor, and
multiple function decls, each with a unique parameter list.
@@ -343,6 +343,10 @@ remap_type_1 (tree type, copy_body_data *id)
new_tree = build_pointer_type_for_mode (remap_type (TREE_TYPE (type), id),
TYPE_MODE (type),
TYPE_REF_CAN_ALIAS_ALL (type));
+ if (TYPE_ATTRIBUTES (type) || TYPE_QUALS (type))
+ new_tree = build_type_attribute_qual_variant (new_tree,
+ TYPE_ATTRIBUTES (type),
+ TYPE_QUALS (type));
insert_decl_map (id, type, new_tree);
return new_tree;
}
@@ -351,6 +355,10 @@ remap_type_1 (tree type, copy_body_data *id)
new_tree = build_reference_type_for_mode (remap_type (TREE_TYPE (type), id),
TYPE_MODE (type),
TYPE_REF_CAN_ALIAS_ALL (type));
+ if (TYPE_ATTRIBUTES (type) || TYPE_QUALS (type))
+ new_tree = build_type_attribute_qual_variant (new_tree,
+ TYPE_ATTRIBUTES (type),
+ TYPE_QUALS (type));
insert_decl_map (id, type, new_tree);
return new_tree;
}
@@ -537,6 +545,7 @@ remap_decls (tree decls, VEC(tree,gc) **nonlocalized_list, copy_body_data *id)
if (can_be_nonlocal (old_var, id))
{
if (TREE_CODE (old_var) == VAR_DECL
+ && ! DECL_EXTERNAL (old_var)
&& (var_ann (old_var) || !gimple_in_ssa_p (cfun)))
cfun->local_decls = tree_cons (NULL_TREE, old_var,
cfun->local_decls);
@@ -1105,12 +1114,6 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
TREE_BLOCK (*tp) = new_block;
}
- if (TREE_CODE (*tp) == RESX_EXPR && id->eh_region_offset)
- TREE_OPERAND (*tp, 0) =
- build_int_cst (NULL_TREE,
- id->eh_region_offset
- + TREE_INT_CST_LOW (TREE_OPERAND (*tp, 0)));
-
if (TREE_CODE (*tp) != OMP_CLAUSE)
TREE_TYPE (*tp) = remap_type (TREE_TYPE (*tp), id);
@@ -1150,6 +1153,35 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE;
}
+/* Helper for remap_gimple_stmt. Given an EH region number for the
+ source function, map that to the duplicate EH region number in
+ the destination function. */
+
+static int
+remap_eh_region_nr (int old_nr, copy_body_data *id)
+{
+ eh_region old_r, new_r;
+ void **slot;
+
+ old_r = get_eh_region_from_number_fn (id->src_cfun, old_nr);
+ slot = pointer_map_contains (id->eh_map, old_r);
+ new_r = (eh_region) *slot;
+
+ return new_r->index;
+}
+
+/* Similar, but operate on INTEGER_CSTs. */
+
+static tree
+remap_eh_region_tree_nr (tree old_t_nr, copy_body_data *id)
+{
+ int old_nr, new_nr;
+
+ old_nr = tree_low_cst (old_t_nr, 0);
+ new_nr = remap_eh_region_nr (old_nr, id);
+
+ return build_int_cst (NULL, new_nr);
+}
/* Helper for copy_bb. Remap statement STMT using the inlining
information in ID. Return the new statement copy. */
@@ -1339,9 +1371,59 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
VEC_safe_push (gimple, heap, id->debug_stmts, copy);
return copy;
}
- else
- /* Create a new deep copy of the statement. */
- copy = gimple_copy (stmt);
+
+ /* Create a new deep copy of the statement. */
+ copy = gimple_copy (stmt);
+
+ /* Remap the region numbers for __builtin_eh_{pointer,filter},
+ RESX and EH_DISPATCH. */
+ if (id->eh_map)
+ switch (gimple_code (copy))
+ {
+ case GIMPLE_CALL:
+ {
+ tree r, fndecl = gimple_call_fndecl (copy);
+ if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_EH_COPY_VALUES:
+ r = gimple_call_arg (copy, 1);
+ r = remap_eh_region_tree_nr (r, id);
+ gimple_call_set_arg (copy, 1, r);
+ /* FALLTHRU */
+
+ case BUILT_IN_EH_POINTER:
+ case BUILT_IN_EH_FILTER:
+ r = gimple_call_arg (copy, 0);
+ r = remap_eh_region_tree_nr (r, id);
+ gimple_call_set_arg (copy, 0, r);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case GIMPLE_RESX:
+ {
+ int r = gimple_resx_region (copy);
+ r = remap_eh_region_nr (r, id);
+ gimple_resx_set_region (copy, r);
+ }
+ break;
+
+ case GIMPLE_EH_DISPATCH:
+ {
+ int r = gimple_eh_dispatch_region (copy);
+ r = remap_eh_region_nr (r, id);
+ gimple_eh_dispatch_set_region (copy, r);
+ }
+ break;
+
+ default:
+ break;
+ }
}
/* If STMT has a block defined, map it to the newly constructed
@@ -1377,12 +1459,6 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
gimple_set_vuse (copy, NULL_TREE);
}
- /* We have to handle EH region remapping of GIMPLE_RESX specially because
- the region number is not an operand. */
- if (gimple_code (stmt) == GIMPLE_RESX && id->eh_region_offset)
- {
- gimple_resx_set_region (copy, gimple_resx_region (stmt) + id->eh_region_offset);
- }
return copy;
}
@@ -1617,43 +1693,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
cfun->calls_setjmp = true;
}
- /* If you think we can abort here, you are wrong.
- There is no region 0 in gimple. */
- gcc_assert (lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt) != 0);
-
- if (stmt_could_throw_p (stmt)
- /* When we are cloning for inlining, we are supposed to
- construct a clone that calls precisely the same functions
- as original. However IPA optimizers might've proved
- earlier some function calls as non-trapping that might
- render some basic blocks dead that might become
- unreachable.
-
- We can't update SSA with unreachable blocks in CFG and thus
- we prevent the scenario by preserving even the "dead" eh
- edges until the point they are later removed by
- fixup_cfg pass. */
- || (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES
- && lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt) > 0))
- {
- int region = lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt);
-
- /* Add an entry for the copied tree in the EH hashtable.
- When cloning or versioning, use the hashtable in
- cfun, and just copy the EH number. When inlining, use the
- hashtable in the caller, and adjust the region number. */
- if (region > 0)
- add_stmt_to_eh_region (stmt, region + id->eh_region_offset);
-
- /* If this tree doesn't have a region associated with it,
- and there is a "current region,"
- then associate this tree with the current region
- and add edges associated with this region. */
- if (lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt) <= 0
- && id->eh_region > 0
- && stmt_could_throw_p (stmt))
- add_stmt_to_eh_region (stmt, id->eh_region);
- }
+ maybe_duplicate_eh_stmt_fn (cfun, stmt, id->src_cfun, orig_stmt,
+ id->eh_map, id->eh_lp_nr);
if (gimple_in_ssa_p (cfun) && !is_gimple_debug (stmt))
{
@@ -1822,7 +1863,9 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb)
}
}
- if (can_throw)
+ if (gimple_code (copy_stmt) == GIMPLE_EH_DISPATCH)
+ make_eh_dispatch_edges (copy_stmt);
+ else if (can_throw)
make_eh_edges (copy_stmt);
if (nonlocal_goto)
@@ -2025,11 +2068,8 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency,
/* Duplicate any exception-handling regions. */
if (cfun->eh)
- {
- id->eh_region_offset
- = duplicate_eh_regions (cfun_to_copy, remap_decl_1, id,
- 0, id->eh_region);
- }
+ id->eh_map = duplicate_eh_regions (cfun_to_copy, NULL, id->eh_lp_nr,
+ remap_decl_1, id);
/* Use aux pointers to map the original blocks to copy. */
FOR_EACH_BB_FN (bb, cfun_to_copy)
@@ -2062,6 +2102,12 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency,
entry_block_map->aux = NULL;
exit_block_map->aux = NULL;
+ if (id->eh_map)
+ {
+ pointer_map_destroy (id->eh_map);
+ id->eh_map = NULL;
+ }
+
return new_fndecl;
}
@@ -3195,14 +3241,6 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
lhs = gimple_assign_lhs (stmt);
rhs = gimple_assign_rhs1 (stmt);
- /* EH magic stuff is most probably going to be optimized out.
- We rarely really need to save EH info for unwinding
- nested exceptions. */
- if (TREE_CODE (lhs) == FILTER_EXPR
- || TREE_CODE (lhs) == EXC_PTR_EXPR
- || TREE_CODE (rhs) == FILTER_EXPR
- || TREE_CODE (rhs) == EXC_PTR_EXPR)
- return 0;
if (is_gimple_reg (lhs))
cost = 0;
else
@@ -3313,9 +3351,19 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
return 0;
case GIMPLE_ASM:
- case GIMPLE_RESX:
return 1;
+ case GIMPLE_RESX:
+ /* This is either going to be an external function call with one
+ argument, or two register copy statements plus a goto. */
+ return 2;
+
+ case GIMPLE_EH_DISPATCH:
+ /* ??? This is going to turn into a switch statement. Ideally
+ we'd have a look at the eh region and estimate the number of
+ edges involved. */
+ return 10;
+
case GIMPLE_BIND:
return estimate_num_insns_seq (gimple_bind_body (stmt), weights);
@@ -3510,6 +3558,13 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
cg_edge = cgraph_edge (id->dst_node, stmt);
+ /* Don't inline functions with different EH personalities. */
+ if (DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl)
+ && DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl)
+ && (DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl)
+ != DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl)))
+ goto egress;
+
/* Don't try to inline functions that are not well-suited to
inlining. */
if (!cgraph_inline_p (cg_edge, &reason))
@@ -3549,7 +3604,12 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
#endif
/* We will be inlining this callee. */
- id->eh_region = lookup_stmt_eh_region (stmt);
+ id->eh_lp_nr = lookup_stmt_eh_lp (stmt);
+
+ /* Update the callers EH personality. */
+ if (DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl))
+ DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl)
+ = DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl);
/* Split the block holding the GIMPLE_CALL. */
e = split_block (bb, stmt);
@@ -4752,6 +4812,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
DECL_ARTIFICIAL (new_decl) = 1;
DECL_ABSTRACT_ORIGIN (new_decl) = DECL_ORIGIN (old_decl);
+ DECL_FUNCTION_PERSONALITY (new_decl) = DECL_FUNCTION_PERSONALITY (old_decl);
/* Prepare the data structures for the tree copy. */
memset (&id, 0, sizeof (id));
@@ -4944,7 +5005,7 @@ maybe_inline_call_in_expr (tree exp)
id.do_not_unshare = true;
/* We're not inside any EH region. */
- id.eh_region = -1;
+ id.eh_lp_nr = 0;
t = copy_tree_body (&id);
pointer_map_destroy (decl_map);
@@ -5022,6 +5083,18 @@ tree_can_inline_p (struct cgraph_edge *e)
caller = e->caller->decl;
callee = e->callee->decl;
+ /* We cannot inline a function that uses a different EH personality
+ than the caller. */
+ if (DECL_FUNCTION_PERSONALITY (caller)
+ && DECL_FUNCTION_PERSONALITY (callee)
+ && (DECL_FUNCTION_PERSONALITY (caller)
+ != DECL_FUNCTION_PERSONALITY (callee)))
+ {
+ e->inline_failed = CIF_UNSPECIFIED;
+ gimple_call_set_cannot_inline (e->call_stmt, true);
+ return false;
+ }
+
/* Allow the backend to decide if inlining is ok. */
if (!targetm.target_option.can_inline_p (caller, callee))
{
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index f04a3f0a843..29932e84e38 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -77,12 +77,12 @@ typedef struct copy_body_data
is not. */
gimple gimple_call;
- /* Exception region the inlined call lie in. */
- int eh_region;
+ /* Exception landing pad the inlined call lies in. */
+ int eh_lp_nr;
- /* Take region number in the function being copied, add this value and
- get eh region number of the duplicate in the function we inline into. */
- int eh_region_offset;
+ /* Maps region and landing pad structures from the function being copied
+ to duplicates created within the function we inline into. */
+ struct pointer_map_t *eh_map;
/* We use the same mechanism do all sorts of different things. Rather
than enumerating the different cases, we categorize the behavior
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 7c55c8adc23..fe938d913e1 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -1,5 +1,6 @@
/* Nested function decomposition for GIMPLE.
- Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -102,6 +103,27 @@ struct nesting_info
};
+/* Iterate over the nesting tree, starting with ROOT, depth first. */
+
+static inline struct nesting_info *
+iter_nestinfo_start (struct nesting_info *root)
+{
+ while (root->inner)
+ root = root->inner;
+ return root;
+}
+
+static inline struct nesting_info *
+iter_nestinfo_next (struct nesting_info *node)
+{
+ if (node->next)
+ return iter_nestinfo_start (node->next);
+ return node->outer;
+}
+
+#define FOR_EACH_NEST_INFO(I, ROOT) \
+ for ((I) = iter_nestinfo_start (ROOT); (I); (I) = iter_nestinfo_next (I))
+
/* Obstack used for the bitmaps in the struct above. */
static struct bitmap_obstack nesting_info_bitmap_obstack;
@@ -301,6 +323,7 @@ static tree
get_chain_decl (struct nesting_info *info)
{
tree decl = info->chain_decl;
+
if (!decl)
{
tree type;
@@ -327,6 +350,14 @@ get_chain_decl (struct nesting_info *info)
TREE_READONLY (decl) = 1;
info->chain_decl = decl;
+
+ if (dump_file
+ && (dump_flags & TDF_DETAILS)
+ && DECL_NO_STATIC_CHAIN (info->context))
+ fprintf (dump_file, "Resetting no-static-chain for %s\n",
+ lang_hooks.decl_printable_name (info->context, 2));
+
+ DECL_NO_STATIC_CHAIN (info->context) = 0;
}
return decl;
}
@@ -339,6 +370,7 @@ static tree
get_chain_field (struct nesting_info *info)
{
tree field = info->chain_field;
+
if (!field)
{
tree type = build_pointer_type (get_frame_type (info->outer));
@@ -352,6 +384,14 @@ get_chain_field (struct nesting_info *info)
insert_field_into_struct (get_frame_type (info), field);
info->chain_field = field;
+
+ if (dump_file
+ && (dump_flags & TDF_DETAILS)
+ && DECL_NO_STATIC_CHAIN (info->context))
+ fprintf (dump_file, "Resetting no-static-chain for %s\n",
+ lang_hooks.decl_printable_name (info->context, 2));
+
+ DECL_NO_STATIC_CHAIN (info->context) = 0;
}
return field;
}
@@ -622,14 +662,9 @@ static void
walk_all_functions (walk_stmt_fn callback_stmt, walk_tree_fn callback_op,
struct nesting_info *root)
{
- do
- {
- if (root->inner)
- walk_all_functions (callback_stmt, callback_op, root->inner);
- walk_function (callback_stmt, callback_op, root);
- root = root->next;
- }
- while (root);
+ struct nesting_info *n;
+ FOR_EACH_NEST_INFO (n, root)
+ walk_function (callback_stmt, callback_op, n);
}
@@ -1931,6 +1966,8 @@ convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p,
switch (gimple_code (stmt))
{
case GIMPLE_CALL:
+ if (gimple_call_chain (stmt))
+ break;
decl = gimple_call_fndecl (stmt);
if (!decl)
break;
@@ -1998,32 +2035,69 @@ convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p,
return NULL_TREE;
}
-
-/* Walk the nesting tree starting with ROOT, depth first. Convert all
- trampolines and call expressions. On the way back up, determine if
- a nested function actually uses its static chain; if not, remember that. */
+/* Walk the nesting tree starting with ROOT. Convert all trampolines and
+ call expressions. At the same time, determine if a nested function
+ actually uses its static chain; if not, remember that. */
static void
convert_all_function_calls (struct nesting_info *root)
{
+ struct nesting_info *n;
+ int iter_count;
+ bool any_changed;
+
+ /* First, optimistically set no_static_chain for all decls that haven't
+ used the static chain already for variable access. */
+ FOR_EACH_NEST_INFO (n, root)
+ {
+ tree decl = n->context;
+ if (n->outer && !n->chain_decl && !n->chain_field)
+ {
+ DECL_NO_STATIC_CHAIN (decl) = 1;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Guessing no-static-chain for %s\n",
+ lang_hooks.decl_printable_name (decl, 2));
+ }
+ else
+ gcc_assert (!DECL_NO_STATIC_CHAIN (decl));
+ }
+
+ /* Walk the functions and perform transformations. Note that these
+ transformations can induce new uses of the static chain, which in turn
+ require re-examining all users of the decl. */
+ /* ??? It would make sense to try to use the call graph to speed this up,
+ but the call graph hasn't really been built yet. Even if it did, we
+ would still need to iterate in this loop since address-of references
+ wouldn't show up in the callgraph anyway. */
+ iter_count = 0;
do
{
- if (root->inner)
- convert_all_function_calls (root->inner);
+ any_changed = false;
+ iter_count++;
- walk_function (convert_tramp_reference_stmt, convert_tramp_reference_op,
- root);
- walk_function (convert_gimple_call, NULL, root);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fputc ('\n', dump_file);
- /* If the function does not use a static chain, then remember that. */
- if (root->outer && !root->chain_decl && !root->chain_field)
- DECL_NO_STATIC_CHAIN (root->context) = 1;
- else
- gcc_assert (!DECL_NO_STATIC_CHAIN (root->context));
+ FOR_EACH_NEST_INFO (n, root)
+ {
+ tree decl = n->context;
+ bool old_no_static_chain = DECL_NO_STATIC_CHAIN (decl);
- root = root->next;
+ walk_function (convert_tramp_reference_stmt,
+ convert_tramp_reference_op, n);
+ walk_function (convert_gimple_call, NULL, n);
+
+ /* If a call to another function created the use of a chain
+ within this function, we'll have to continue iteration. */
+ if (old_no_static_chain && !DECL_NO_STATIC_CHAIN (decl))
+ any_changed = true;
+ }
}
- while (root);
+ while (any_changed);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "convert_all_function_calls iterations: %d\n\n",
+ iter_count);
}
struct nesting_copy_body_data
@@ -2263,10 +2337,8 @@ finalize_nesting_tree_1 (struct nesting_info *root)
if (!field)
continue;
- if (DECL_NO_STATIC_CHAIN (i->context))
- arg3 = null_pointer_node;
- else
- arg3 = build_addr (root->frame_decl, context);
+ gcc_assert (!DECL_NO_STATIC_CHAIN (i->context));
+ arg3 = build_addr (root->frame_decl, context);
arg2 = build_addr (i->context, context);
@@ -2379,20 +2451,19 @@ finalize_nesting_tree_1 (struct nesting_info *root)
}
/* Dump the translated tree function. */
- dump_function (TDI_nested, root->context);
+ if (dump_file)
+ {
+ fputs ("\n\n", dump_file);
+ dump_function_to_file (root->context, dump_file, dump_flags);
+ }
}
static void
finalize_nesting_tree (struct nesting_info *root)
{
- do
- {
- if (root->inner)
- finalize_nesting_tree (root->inner);
- finalize_nesting_tree_1 (root);
- root = root->next;
- }
- while (root);
+ struct nesting_info *n;
+ FOR_EACH_NEST_INFO (n, root)
+ finalize_nesting_tree_1 (n);
}
/* Unnest the nodes and pass them to cgraph. */
@@ -2414,14 +2485,9 @@ unnest_nesting_tree_1 (struct nesting_info *root)
static void
unnest_nesting_tree (struct nesting_info *root)
{
- do
- {
- if (root->inner)
- unnest_nesting_tree (root->inner);
- unnest_nesting_tree_1 (root);
- root = root->next;
- }
- while (root);
+ struct nesting_info *n;
+ FOR_EACH_NEST_INFO (n, root)
+ unnest_nesting_tree_1 (n);
}
/* Free the data structures allocated during this pass. */
@@ -2429,18 +2495,18 @@ unnest_nesting_tree (struct nesting_info *root)
static void
free_nesting_tree (struct nesting_info *root)
{
- struct nesting_info *next;
+ struct nesting_info *node, *next;
+
+ node = iter_nestinfo_start (root);
do
{
- if (root->inner)
- free_nesting_tree (root->inner);
- pointer_map_destroy (root->var_map);
- pointer_map_destroy (root->field_map);
- next = root->next;
- free (root);
- root = next;
+ next = iter_nestinfo_next (node);
+ pointer_map_destroy (node->var_map);
+ pointer_map_destroy (node->field_map);
+ free (node);
+ node = next;
}
- while (root);
+ while (node);
}
/* Gimplify a function and all its nested functions. */
@@ -2462,6 +2528,10 @@ lower_nested_functions (tree fndecl)
{
struct cgraph_node *cgn;
struct nesting_info *root;
+#ifdef ENABLE_CHECKING
+ struct nesting_info *n;
+ bitmap orig_decl_no_static_chain;
+#endif
/* If there are no nested functions, there's nothing to do. */
cgn = cgraph_node (fndecl);
@@ -2470,8 +2540,23 @@ lower_nested_functions (tree fndecl)
gimplify_all_functions (cgn);
+ dump_file = dump_begin (TDI_nested, &dump_flags);
+ if (dump_file)
+ fprintf (dump_file, "\n;; Function %s\n\n",
+ lang_hooks.decl_printable_name (fndecl, 2));
+
bitmap_obstack_initialize (&nesting_info_bitmap_obstack);
root = create_nesting_tree (cgn);
+
+#ifdef ENABLE_CHECKING
+ /* The C++ and Ada front ends set DECL_NO_STATIC_CHAIN in various
+ instances where they expect no static chain needed. */
+ orig_decl_no_static_chain = BITMAP_ALLOC (&nesting_info_bitmap_obstack);
+ FOR_EACH_NEST_INFO (n, root)
+ if (DECL_NO_STATIC_CHAIN (n->context))
+ bitmap_set_bit (orig_decl_no_static_chain, DECL_UID (n->context));
+#endif
+
walk_all_functions (convert_nonlocal_reference_stmt,
convert_nonlocal_reference_op,
root);
@@ -2480,11 +2565,26 @@ lower_nested_functions (tree fndecl)
root);
walk_all_functions (convert_nl_goto_reference, NULL, root);
walk_all_functions (convert_nl_goto_receiver, NULL, root);
+
convert_all_function_calls (root);
finalize_nesting_tree (root);
unnest_nesting_tree (root);
+
+#ifdef ENABLE_CHECKING
+ /* Validate the original settings of DECL_NO_STATIC_CHAIN. */
+ FOR_EACH_NEST_INFO (n, root)
+ if (bitmap_bit_p (orig_decl_no_static_chain, DECL_UID (n->context)))
+ gcc_assert (DECL_NO_STATIC_CHAIN (n->context));
+#endif
+
free_nesting_tree (root);
bitmap_obstack_release (&nesting_info_bitmap_obstack);
+
+ if (dump_file)
+ {
+ dump_end (TDI_nested, dump_file);
+ dump_file = NULL;
+ }
}
#include "gt-tree-nested.h"
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c
index 7a9d2bd7c46..73eacf6c2f2 100644
--- a/gcc/tree-optimize.c
+++ b/gcc/tree-optimize.c
@@ -269,8 +269,7 @@ execute_fixup_cfg (void)
}
}
- if (!stmt_could_throw_p (stmt) && lookup_stmt_eh_region (stmt))
- remove_stmt_from_eh_region (stmt);
+ maybe_clean_eh_stmt (stmt);
}
if (gimple_purge_dead_eh_edges (bb))
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 06db5f1bf2f..28b25cb984a 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -316,6 +316,8 @@ extern struct gimple_opt_pass pass_remove_useless_stmts;
extern struct gimple_opt_pass pass_lower_cf;
extern struct gimple_opt_pass pass_refactor_eh;
extern struct gimple_opt_pass pass_lower_eh;
+extern struct gimple_opt_pass pass_lower_eh_dispatch;
+extern struct gimple_opt_pass pass_lower_resx;
extern struct gimple_opt_pass pass_build_cfg;
extern struct gimple_opt_pass pass_tree_profile;
extern struct gimple_opt_pass pass_direct_call_profile;
@@ -326,6 +328,7 @@ extern struct gimple_opt_pass pass_cleanup_eh;
extern struct gimple_opt_pass pass_fixup_cfg;
extern struct gimple_opt_pass pass_sra;
extern struct gimple_opt_pass pass_sra_early;
+extern struct gimple_opt_pass pass_early_ipa_sra;
extern struct gimple_opt_pass pass_tail_recursion;
extern struct gimple_opt_pass pass_tail_calls;
extern struct gimple_opt_pass pass_tree_loop;
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 2c64ab96aa0..a325d75d914 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -1687,14 +1687,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
pp_string (buffer, " [non-local]");
break;
- case EXC_PTR_EXPR:
- pp_string (buffer, "<<<exception object>>>");
- break;
-
- case FILTER_EXPR:
- pp_string (buffer, "<<<filter object>>>");
- break;
-
case LOOP_EXPR:
pp_string (buffer, "while (1)");
if (!(flags & TDF_SLIM))
@@ -1795,11 +1787,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, op0, spc, flags, false);
break;
- case RESX_EXPR:
- pp_string (buffer, "resx ");
- dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- break;
-
case ASM_EXPR:
pp_string (buffer, "__asm__");
if (ASM_VOLATILE_P (node))
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index e611368b653..fb16861cee3 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -78,6 +78,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "tree.h"
#include "gimple.h"
+#include "cgraph.h"
#include "tree-flow.h"
#include "ipa-prop.h"
#include "diagnostic.h"
@@ -90,8 +91,9 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
/* Enumeration of all aggregate reductions we can do. */
-enum sra_mode { SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
- SRA_MODE_INTRA }; /* late intraprocedural SRA */
+enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
+ SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
+ SRA_MODE_INTRA }; /* late intraprocedural SRA */
/* Global variable describing which aggregate reduction we are performing at
the moment. */
@@ -129,6 +131,9 @@ struct access
/* Type. */
tree type;
+ /* The statement this access belongs to. */
+ gimple stmt;
+
/* Next group representative for this aggregate. */
struct access *next_grp;
@@ -160,26 +165,33 @@ struct access
/* Is this access currently in the work queue? */
unsigned grp_queued : 1;
+
/* Does this group contain a write access? This flag is propagated down the
access tree. */
unsigned grp_write : 1;
+
/* Does this group contain a read access? This flag is propagated down the
access tree. */
unsigned grp_read : 1;
+
/* Other passes of the analysis use this bit to make function
analyze_access_subtree create scalar replacements for this group if
possible. */
unsigned grp_hint : 1;
+
/* Is the subtree rooted in this access fully covered by scalar
replacements? */
unsigned grp_covered : 1;
+
/* If set to true, this access and all below it in an access tree must not be
scalarized. */
unsigned grp_unscalarizable_region : 1;
+
/* Whether data have been written to parts of the aggregate covered by this
access which is not to be scalarized. This flag is propagated up in the
access tree. */
unsigned grp_unscalarized_data : 1;
+
/* Does this access and/or group contain a write access through a
BIT_FIELD_REF? */
unsigned grp_partial_lhs : 1;
@@ -188,6 +200,19 @@ struct access
the decision and creation at different places because create_tmp_var
cannot be called from within FOR_EACH_REFERENCED_VAR. */
unsigned grp_to_be_replaced : 1;
+
+ /* Is it possible that the group refers to data which might be (directly or
+ otherwise) modified? */
+ unsigned grp_maybe_modified : 1;
+
+ /* Set when this is a representative of a pointer to scalar (i.e. by
+ reference) parameter which we consider for turning into a plain scalar
+ (i.e. a by value parameter). */
+ unsigned grp_scalar_ptr : 1;
+
+ /* Set when we discover that this pointer is not safe to dereference in the
+ caller. */
+ unsigned grp_not_necessarilly_dereferenced : 1;
};
typedef struct access *access_p;
@@ -213,8 +238,9 @@ static alloc_pool link_pool;
/* Base (tree) -> Vector (VEC(access_p,heap) *) map. */
static struct pointer_map_t *base_access_vec;
-/* Bitmap of bases (candidates). */
+/* Bitmap of candidates. */
static bitmap candidate_bitmap;
+
/* Obstack for creation of fancy names. */
static struct obstack name_obstack;
@@ -222,12 +248,42 @@ static struct obstack name_obstack;
propagated to their assignment counterparts. */
static struct access *work_queue_head;
+/* Number of parameters of the analyzed function when doing early ipa SRA. */
+static int func_param_count;
+
+/* scan_function sets the following to true if it encounters a call to
+ __builtin_apply_args. */
+static bool encountered_apply_args;
+
+/* This is a table in which for each basic block and parameter there is a
+ distance (offset + size) in that parameter which is dereferenced and
+ accessed in that BB. */
+static HOST_WIDE_INT *bb_dereferences;
+/* Bitmap of BBs that can cause the function to "stop" progressing by
+ returning, throwing externally, looping infinitely or calling a function
+ which might abort etc.. */
+static bitmap final_bbs;
+
+/* Representative of no accesses at all. */
+static struct access no_accesses_representant;
+
+/* Predicate to test the special value. */
+
+static inline bool
+no_accesses_p (struct access *access)
+{
+ return access == &no_accesses_representant;
+}
+
/* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
representative fields are dumped, otherwise those which only describe the
individual access are. */
static struct
{
+ /* Number of processed aggregates is readily available in
+ analyze_all_variable_accesses and so is not stored here. */
+
/* Number of created scalar replacements. */
int replacements;
@@ -249,8 +305,19 @@ static struct
references. */
int separate_lhs_rhs_handling;
- /* Number of processed aggregates is readily available in
- analyze_all_variable_accesses and so is not stored here. */
+ /* Number of parameters that were removed because they were unused. */
+ int deleted_unused_parameters;
+
+ /* Number of scalars passed as parameters by reference that have been
+ converted to be passed by value. */
+ int scalar_by_ref_to_by_val;
+
+ /* Number of aggregate parameters that were replaced by one or more of their
+ components. */
+ int aggregate_params_reduced;
+
+ /* Numbber of components created when splitting aggregate parameters. */
+ int param_reductions_created;
} sra_stats;
static void
@@ -269,11 +336,13 @@ dump_access (FILE *f, struct access *access, bool grp)
fprintf (f, ", grp_write = %d, grp_read = %d, grp_hint = %d, "
"grp_covered = %d, grp_unscalarizable_region = %d, "
"grp_unscalarized_data = %d, grp_partial_lhs = %d, "
- "grp_to_be_replaced = %d\n",
+ "grp_to_be_replaced = %d\n grp_maybe_modified = %d, "
+ "grp_not_necessarilly_dereferenced = %d\n",
access->grp_write, access->grp_read, access->grp_hint,
access->grp_covered, access->grp_unscalarizable_region,
access->grp_unscalarized_data, access->grp_partial_lhs,
- access->grp_to_be_replaced);
+ access->grp_to_be_replaced, access->grp_maybe_modified,
+ access->grp_not_necessarilly_dereferenced);
else
fprintf (f, ", write = %d, grp_partial_lhs = %d\n", access->write,
access->grp_partial_lhs);
@@ -472,6 +541,7 @@ sra_initialize (void)
link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
base_access_vec = pointer_map_create ();
memset (&sra_stats, 0, sizeof (sra_stats));
+ encountered_apply_args = false;
}
/* Hook fed to pointer_map_traverse, deallocate stored vectors. */
@@ -561,34 +631,105 @@ type_internals_preclude_sra_p (tree type)
}
}
+/* If T is an SSA_NAME, return NULL if it is not a default def or return its
+ base variable if it is. Return T if it is not an SSA_NAME. */
+
+static tree
+get_ssa_base_param (tree t)
+{
+ if (TREE_CODE (t) == SSA_NAME)
+ {
+ if (SSA_NAME_IS_DEFAULT_DEF (t))
+ return SSA_NAME_VAR (t);
+ else
+ return NULL_TREE;
+ }
+ return t;
+}
+
+/* Mark a dereference of BASE of distance DIST in a basic block tht STMT
+ belongs to, unless the BB has already been marked as a potentially
+ final. */
+
+static void
+mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple stmt)
+{
+ basic_block bb = gimple_bb (stmt);
+ int idx, parm_index = 0;
+ tree parm;
+
+ if (bitmap_bit_p (final_bbs, bb->index))
+ return;
+
+ for (parm = DECL_ARGUMENTS (current_function_decl);
+ parm && parm != base;
+ parm = TREE_CHAIN (parm))
+ parm_index++;
+
+ gcc_assert (parm_index < func_param_count);
+
+ idx = bb->index * func_param_count + parm_index;
+ if (bb_dereferences[idx] < dist)
+ bb_dereferences[idx] = dist;
+}
+
/* Create and insert access for EXPR. Return created access, or NULL if it is
not possible. */
static struct access *
-create_access (tree expr, bool write)
+create_access (tree expr, gimple stmt, bool write)
{
struct access *access;
void **slot;
VEC (access_p,heap) *vec;
HOST_WIDE_INT offset, size, max_size;
tree base = expr;
- bool unscalarizable_region = false;
+ bool ptr, unscalarizable_region = false;
base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
+ if (sra_mode == SRA_MODE_EARLY_IPA && INDIRECT_REF_P (base))
+ {
+ base = get_ssa_base_param (TREE_OPERAND (base, 0));
+ if (!base)
+ return NULL;
+ ptr = true;
+ }
+ else
+ ptr = false;
+
if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
return NULL;
- if (size != max_size)
+ if (sra_mode == SRA_MODE_EARLY_IPA)
{
- size = max_size;
- unscalarizable_region = true;
- }
+ if (size < 0 || size != max_size)
+ {
+ disqualify_candidate (base, "Encountered a variable sized access.");
+ return NULL;
+ }
+ if ((offset % BITS_PER_UNIT) != 0 || (size % BITS_PER_UNIT) != 0)
+ {
+ disqualify_candidate (base,
+ "Encountered an acces not aligned to a byte.");
+ return NULL;
+ }
- if (size < 0)
+ if (ptr)
+ mark_parm_dereference (base, offset + size, stmt);
+ }
+ else
{
- disqualify_candidate (base, "Encountered an unconstrained access.");
- return NULL;
+ if (size != max_size)
+ {
+ size = max_size;
+ unscalarizable_region = true;
+ }
+ if (size < 0)
+ {
+ disqualify_candidate (base, "Encountered an unconstrained access.");
+ return NULL;
+ }
}
access = (struct access *) pool_alloc (access_pool);
@@ -601,6 +742,7 @@ create_access (tree expr, bool write)
access->type = TREE_TYPE (expr);
access->write = write;
access->grp_unscalarizable_region = unscalarizable_region;
+ access->stmt = stmt;
slot = pointer_map_contains (base_access_vec, base);
if (slot)
@@ -626,7 +768,14 @@ disqualify_base_of_expr (tree t, const char *reason)
while (handled_component_p (t))
t = TREE_OPERAND (t, 0);
- if (DECL_P (t))
+ if (sra_mode == SRA_MODE_EARLY_IPA)
+ {
+ if (INDIRECT_REF_P (t))
+ t = TREE_OPERAND (t, 0);
+ t = get_ssa_base_param (t);
+ }
+
+ if (t && DECL_P (t))
disqualify_candidate (t, reason);
}
@@ -635,7 +784,7 @@ disqualify_base_of_expr (tree t, const char *reason)
created. */
static struct access *
-build_access_from_expr_1 (tree *expr_ptr, bool write)
+build_access_from_expr_1 (tree *expr_ptr, gimple stmt, bool write)
{
struct access *ret = NULL;
tree expr = *expr_ptr;
@@ -667,13 +816,17 @@ build_access_from_expr_1 (tree *expr_ptr, bool write)
switch (TREE_CODE (expr))
{
+ case INDIRECT_REF:
+ if (sra_mode != SRA_MODE_EARLY_IPA)
+ return NULL;
+ /* fall through */
case VAR_DECL:
case PARM_DECL:
case RESULT_DECL:
case COMPONENT_REF:
case ARRAY_REF:
case ARRAY_RANGE_REF:
- ret = create_access (expr, write);
+ ret = create_access (expr, stmt, write);
break;
default:
@@ -695,7 +848,7 @@ build_access_from_expr (tree *expr_ptr,
gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, bool write,
void *data ATTRIBUTE_UNUSED)
{
- return build_access_from_expr_1 (expr_ptr, write) != NULL;
+ return build_access_from_expr_1 (expr_ptr, gsi_stmt (*gsi), write) != NULL;
}
/* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
@@ -706,7 +859,8 @@ build_access_from_expr (tree *expr_ptr,
static bool
disqualify_ops_if_throwing_stmt (gimple stmt, tree lhs, tree rhs)
{
- if (stmt_can_throw_internal (stmt) || stmt_ends_bb_p (stmt))
+ if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
+ && (stmt_can_throw_internal (stmt) || stmt_ends_bb_p (stmt)))
{
disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
if (rhs)
@@ -747,10 +901,11 @@ build_accesses_from_assign (gimple *stmt_ptr,
if (disqualify_ops_if_throwing_stmt (stmt, *lhs_ptr, *rhs_ptr))
return SRA_SA_NONE;
- racc = build_access_from_expr_1 (rhs_ptr, false);
- lacc = build_access_from_expr_1 (lhs_ptr, true);
+ racc = build_access_from_expr_1 (rhs_ptr, stmt, false);
+ lacc = build_access_from_expr_1 (lhs_ptr, stmt, true);
if (lacc && racc
+ && (sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
&& !lacc->grp_unscalarizable_region
&& !racc->grp_unscalarizable_region
&& AGGREGATE_TYPE_P (TREE_TYPE (*lhs_ptr))
@@ -793,12 +948,11 @@ asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED, tree op,
those deemed entirely unsuitable for some reason (all operands in such
statements and expression are removed from candidate_bitmap). SCAN_ASSIGN
is a callback called on all assign statements, HANDLE_SSA_DEFS is a callback
- called on assign statements and those call statements which have a lhs and
- it is the only callback which can be NULL. ANALYSIS_STAGE is true when
- running in the analysis stage of a pass and thus no statement is being
- modified. DATA is a pointer passed to all callbacks. If any single
- callback returns true, this function also returns true, otherwise it returns
- false. */
+ called on assign statements and those call statements which have a lhs, it
+ can be NULL. ANALYSIS_STAGE is true when running in the analysis stage of a
+ pass and thus no statement is being modified. DATA is a pointer passed to
+ all callbacks. If any single callback returns true, this function also
+ returns true, otherwise it returns false. */
static bool
scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
@@ -818,6 +972,10 @@ scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
{
bool bb_changed = false;
+ if (handle_ssa_defs)
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ ret |= handle_ssa_defs (gsi_stmt (gsi), data);
+
gsi = gsi_start_bb (bb);
while (!gsi_end_p (gsi))
{
@@ -825,12 +983,16 @@ scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
enum scan_assign_result assign_result;
bool any = false, deleted = false;
+ if (analysis_stage && final_bbs && stmt_can_throw_external (stmt))
+ bitmap_set_bit (final_bbs, bb->index);
switch (gimple_code (stmt))
{
case GIMPLE_RETURN:
t = gimple_return_retval_ptr (stmt);
if (*t != NULL_TREE)
any |= scan_expr (t, &gsi, false, data);
+ if (analysis_stage && final_bbs)
+ bitmap_set_bit (final_bbs, bb->index);
break;
case GIMPLE_ASSIGN:
@@ -849,6 +1011,21 @@ scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
any |= scan_expr (argp, &gsi, false, data);
}
+ if (analysis_stage)
+ {
+ tree dest = gimple_call_fndecl (stmt);
+ int flags = gimple_call_flags (stmt);
+
+ if (dest
+ && DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
+ && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
+ encountered_apply_args = true;
+
+ if (final_bbs
+ && (flags & (ECF_CONST | ECF_PURE)) == 0)
+ bitmap_set_bit (final_bbs, bb->index);
+ }
+
if (gimple_call_lhs (stmt))
{
tree *lhs_ptr = gimple_call_lhs_ptr (stmt);
@@ -864,10 +1041,13 @@ scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
break;
case GIMPLE_ASM:
-
if (analysis_stage)
- walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
- asm_visit_addr);
+ {
+ walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
+ asm_visit_addr);
+ if (final_bbs)
+ bitmap_set_bit (final_bbs, bb->index);
+ }
for (i = 0; i < gimple_asm_ninputs (stmt); i++)
{
tree *op = &TREE_VALUE (gimple_asm_input_op (stmt, i));
@@ -878,6 +1058,7 @@ scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
tree *op = &TREE_VALUE (gimple_asm_output_op (stmt, i));
any |= scan_expr (op, &gsi, true, data);
}
+ break;
default:
break;
@@ -886,13 +1067,12 @@ scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
if (any)
{
ret = true;
- bb_changed = true;
if (!analysis_stage)
{
+ bb_changed = true;
update_stmt (stmt);
- if (!stmt_could_throw_p (stmt))
- remove_stmt_from_eh_region (stmt);
+ maybe_clean_eh_stmt (stmt);
}
}
if (deleted)
@@ -903,7 +1083,7 @@ scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
ret = true;
}
}
- if (!analysis_stage && bb_changed)
+ if (!analysis_stage && bb_changed && sra_mode == SRA_MODE_EARLY_IPA)
gimple_purge_dead_eh_edges (bb);
}
@@ -1040,7 +1220,7 @@ build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset,
while (1)
{
tree fld;
- tree tr_size, index;
+ tree tr_size, index, minidx;
HOST_WIDE_INT el_size;
if (offset == 0 && exp_type
@@ -1091,13 +1271,14 @@ build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset,
return false;
el_size = tree_low_cst (tr_size, 1);
+ minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
+ if (TREE_CODE (minidx) != INTEGER_CST)
+ return false;
if (res)
{
index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
- if (!integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
- index = int_const_binop (PLUS_EXPR, index,
- TYPE_MIN_VALUE (TYPE_DOMAIN (type)),
- 0);
+ if (!integer_zerop (minidx))
+ index = int_const_binop (PLUS_EXPR, index, minidx, 0);
*res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
NULL_TREE, NULL_TREE);
}
@@ -1165,7 +1346,13 @@ find_var_candidates (void)
|| !COMPLETE_TYPE_P (type)
|| !host_integerp (TYPE_SIZE (type), 1)
|| tree_low_cst (TYPE_SIZE (type), 1) == 0
- || type_internals_preclude_sra_p (type))
+ || type_internals_preclude_sra_p (type)
+ /* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but
+ we also want to schedule it rather late. Thus we ignore it in
+ the early pass. */
+ || (sra_mode == SRA_MODE_EARLY_INTRA
+ && (TYPE_MAIN_VARIANT (TREE_TYPE (var))
+ == TYPE_MAIN_VARIANT (va_list_type_node))))
continue;
bitmap_set_bit (candidate_bitmap, DECL_UID (var));
@@ -1379,6 +1566,22 @@ build_access_trees (struct access *access)
}
}
+/* Return true if expr contains some ARRAY_REFs into a variable bounded
+ array. */
+
+static bool
+expr_with_var_bounded_array_refs_p (tree expr)
+{
+ while (handled_component_p (expr))
+ {
+ if (TREE_CODE (expr) == ARRAY_REF
+ && !host_integerp (array_ref_low_bound (expr), 0))
+ return true;
+ expr = TREE_OPERAND (expr, 0);
+ }
+ return false;
+}
+
/* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set
all sorts of access flags appropriately along the way, notably always ser
@@ -1408,6 +1611,9 @@ analyze_access_subtree (struct access *root, bool allow_replacements,
if (root->grp_unscalarizable_region)
allow_replacements = false;
+ if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
+ allow_replacements = false;
+
for (child = root->first_child; child; child = child->next_sibling)
{
if (!hole && child->offset < covered_to)
@@ -1499,9 +1705,9 @@ child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
/* Create a new child access of PARENT, with all properties just like MODEL
except for its offset and with its grp_write false and grp_read true.
- Return the new access. Note that this access is created long after all
- splicing and sorting, it's not located in any access vector and is
- automatically a representative of its group. */
+ Return the new access or NULL if it cannot be created. Note that this access
+ is created long after all splicing and sorting, it's not located in any
+ access vector and is automatically a representative of its group. */
static struct access *
create_artificial_child_access (struct access *parent, struct access *model,
@@ -1509,22 +1715,23 @@ create_artificial_child_access (struct access *parent, struct access *model,
{
struct access *access;
struct access **child;
- bool ok;
+ tree expr = parent->base;;
gcc_assert (!model->grp_unscalarizable_region);
+ if (!build_ref_for_offset (&expr, TREE_TYPE (expr), new_offset,
+ model->type, false))
+ return NULL;
+
access = (struct access *) pool_alloc (access_pool);
memset (access, 0, sizeof (struct access));
access->base = parent->base;
+ access->expr = expr;
access->offset = new_offset;
access->size = model->size;
access->type = model->type;
access->grp_write = true;
access->grp_read = false;
- access->expr = access->base;
- ok = build_ref_for_offset (&access->expr, TREE_TYPE (access->expr),
- new_offset, access->type, false);
- gcc_assert (ok);
child = &parent->first_child;
while (*child && (*child)->offset < new_offset)
@@ -1539,7 +1746,7 @@ create_artificial_child_access (struct access *parent, struct access *model,
/* Propagate all subaccesses of RACC across an assignment link to LACC. Return
true if any new subaccess was created. Additionally, if RACC is a scalar
- access but LACC is not, change the type of the latter. */
+ access but LACC is not, change the type of the latter, if possible. */
static bool
propagate_subacesses_accross_link (struct access *lacc, struct access *racc)
@@ -1556,13 +1763,14 @@ propagate_subacesses_accross_link (struct access *lacc, struct access *racc)
if (!lacc->first_child && !racc->first_child
&& is_gimple_reg_type (racc->type))
{
- bool ok;
+ tree t = lacc->base;
- lacc->expr = lacc->base;
- ok = build_ref_for_offset (&lacc->expr, TREE_TYPE (lacc->expr),
- lacc->offset, racc->type, false);
- gcc_assert (ok);
- lacc->type = racc->type;
+ if (build_ref_for_offset (&t, TREE_TYPE (t), lacc->offset, racc->type,
+ false))
+ {
+ lacc->expr = t;
+ lacc->type = racc->type;
+ }
return false;
}
@@ -1596,10 +1804,12 @@ propagate_subacesses_accross_link (struct access *lacc, struct access *racc)
rchild->grp_hint = 1;
new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
- if (racc->first_child)
- propagate_subacesses_accross_link (new_acc, rchild);
-
- ret = true;
+ if (new_acc)
+ {
+ ret = true;
+ if (racc->first_child)
+ propagate_subacesses_accross_link (new_acc, rchild);
+ }
}
return ret;
@@ -2344,8 +2554,7 @@ perform_intra_sra (void)
if (!analyze_all_variable_accesses ())
goto out;
- scan_function (sra_modify_expr, sra_modify_assign, NULL,
- false, NULL);
+ scan_function (sra_modify_expr, sra_modify_assign, NULL, false, NULL);
initialize_parameter_reductions ();
statistics_counter_event (cfun, "Scalar replacements created",
@@ -2412,7 +2621,6 @@ struct gimple_opt_pass pass_sra_early =
}
};
-
struct gimple_opt_pass pass_sra =
{
{
@@ -2434,3 +2642,1232 @@ struct gimple_opt_pass pass_sra =
| TODO_verify_ssa /* todo_flags_finish */
}
};
+
+
+/* Return true iff PARM (which must be a parm_decl) is an unused scalar
+ parameter. */
+
+static bool
+is_unused_scalar_param (tree parm)
+{
+ tree name;
+ return (is_gimple_reg (parm)
+ && (!(name = gimple_default_def (cfun, parm))
+ || has_zero_uses (name)));
+}
+
+/* Scan immediate uses of a default definition SSA name of a parameter PARM and
+ examine whether there are any direct or otherwise infeasible ones. If so,
+ return true, otherwise return false. PARM must be a gimple register with a
+ non-NULL default definition. */
+
+static bool
+ptr_parm_has_direct_uses (tree parm)
+{
+ imm_use_iterator ui;
+ gimple stmt;
+ tree name = gimple_default_def (cfun, parm);
+ bool ret = false;
+
+ FOR_EACH_IMM_USE_STMT (stmt, ui, name)
+ {
+ if (gimple_assign_single_p (stmt))
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+ if (rhs == name)
+ ret = true;
+ else if (TREE_CODE (rhs) == ADDR_EXPR)
+ {
+ do
+ {
+ rhs = TREE_OPERAND (rhs, 0);
+ }
+ while (handled_component_p (rhs));
+ if (INDIRECT_REF_P (rhs) && TREE_OPERAND (rhs, 0) == name)
+ ret = true;
+ }
+ }
+ else if (gimple_code (stmt) == GIMPLE_RETURN)
+ {
+ tree t = gimple_return_retval (stmt);
+ if (t == name)
+ ret = true;
+ }
+ else if (is_gimple_call (stmt))
+ {
+ unsigned i;
+ for (i = 0; i < gimple_call_num_args (stmt); i++)
+ {
+ tree arg = gimple_call_arg (stmt, i);
+ if (arg == name)
+ {
+ ret = true;
+ break;
+ }
+ }
+ }
+ else if (!is_gimple_debug (stmt))
+ ret = true;
+
+ if (ret)
+ BREAK_FROM_IMM_USE_STMT (ui);
+ }
+
+ return ret;
+}
+
+/* Identify candidates for reduction for IPA-SRA based on their type and mark
+ them in candidate_bitmap. Note that these do not necessarily include
+ parameter which are unused and thus can be removed. Return true iff any
+ such candidate has been found. */
+
+static bool
+find_param_candidates (void)
+{
+ tree parm;
+ int count = 0;
+ bool ret = false;
+
+ for (parm = DECL_ARGUMENTS (current_function_decl);
+ parm;
+ parm = TREE_CHAIN (parm))
+ {
+ tree type;
+
+ count++;
+ if (TREE_THIS_VOLATILE (parm)
+ || TREE_ADDRESSABLE (parm))
+ continue;
+
+ if (is_unused_scalar_param (parm))
+ {
+ ret = true;
+ continue;
+ }
+
+ type = TREE_TYPE (parm);
+ if (POINTER_TYPE_P (type))
+ {
+ type = TREE_TYPE (type);
+
+ if (TREE_CODE (type) == FUNCTION_TYPE
+ || TYPE_VOLATILE (type)
+ || !is_gimple_reg (parm)
+ || ptr_parm_has_direct_uses (parm))
+ continue;
+ }
+ else if (!AGGREGATE_TYPE_P (type))
+ continue;
+
+ if (!COMPLETE_TYPE_P (type)
+ || !host_integerp (TYPE_SIZE (type), 1)
+ || tree_low_cst (TYPE_SIZE (type), 1) == 0
+ || (AGGREGATE_TYPE_P (type)
+ && type_internals_preclude_sra_p (type)))
+ continue;
+
+ bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
+ ret = true;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Candidate (%d): ", DECL_UID (parm));
+ print_generic_expr (dump_file, parm, 0);
+ fprintf (dump_file, "\n");
+ }
+ }
+
+ func_param_count = count;
+ return ret;
+}
+
+/* Callback of walk_aliased_vdefs, marks the access passed as DATA as
+ maybe_modified. */
+
+static bool
+mark_maybe_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
+ void *data)
+{
+ struct access *repr = (struct access *) data;
+
+ repr->grp_maybe_modified = 1;
+ return true;
+}
+
+/* Analyze what representatives (in linked lists accessible from
+ REPRESENTATIVES) can be modified by side effects of statements in the
+ current function. */
+
+static void
+analyze_modified_params (VEC (access_p, heap) *representatives)
+{
+ int i;
+
+ for (i = 0; i < func_param_count; i++)
+ {
+ struct access *repr = VEC_index (access_p, representatives, i);
+ VEC (access_p, heap) *access_vec;
+ int j, access_count;
+ tree parm;
+
+ if (!repr || no_accesses_p (repr))
+ continue;
+ parm = repr->base;
+ if (!POINTER_TYPE_P (TREE_TYPE (parm))
+ || repr->grp_maybe_modified)
+ continue;
+
+ access_vec = get_base_access_vector (parm);
+ access_count = VEC_length (access_p, access_vec);
+ for (j = 0; j < access_count; j++)
+ {
+ struct access *access;
+ ao_ref ar;
+
+ /* All accesses are read ones, otherwise grp_maybe_modified would be
+ trivially set. */
+ access = VEC_index (access_p, access_vec, j);
+ ao_ref_init (&ar, access->expr);
+ walk_aliased_vdefs (&ar, gimple_vuse (access->stmt),
+ mark_maybe_modified, repr, NULL);
+ if (repr->grp_maybe_modified)
+ break;
+ }
+ }
+}
+
+/* Propagate distances in bb_dereferences in the opposite direction than the
+ control flow edges, in each step storing the maximum of the current value
+ and the minimum of all successors. These steps are repeated until the table
+ stabilizes. Note that BBs which might terminate the functions (according to
+ final_bbs bitmap) never updated in this way. */
+
+static void
+propagate_dereference_distances (void)
+{
+ VEC (basic_block, heap) *queue;
+ basic_block bb;
+
+ queue = VEC_alloc (basic_block, heap, last_basic_block_for_function (cfun));
+ VEC_quick_push (basic_block, queue, ENTRY_BLOCK_PTR);
+ FOR_EACH_BB (bb)
+ {
+ VEC_quick_push (basic_block, queue, bb);
+ bb->aux = bb;
+ }
+
+ while (!VEC_empty (basic_block, queue))
+ {
+ edge_iterator ei;
+ edge e;
+ bool change = false;
+ int i;
+
+ bb = VEC_pop (basic_block, queue);
+ bb->aux = NULL;
+
+ if (bitmap_bit_p (final_bbs, bb->index))
+ continue;
+
+ for (i = 0; i < func_param_count; i++)
+ {
+ int idx = bb->index * func_param_count + i;
+ bool first = true;
+ HOST_WIDE_INT inh = 0;
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ int succ_idx = e->dest->index * func_param_count + i;
+
+ if (e->src == EXIT_BLOCK_PTR)
+ continue;
+
+ if (first)
+ {
+ first = false;
+ inh = bb_dereferences [succ_idx];
+ }
+ else if (bb_dereferences [succ_idx] < inh)
+ inh = bb_dereferences [succ_idx];
+ }
+
+ if (!first && bb_dereferences[idx] < inh)
+ {
+ bb_dereferences[idx] = inh;
+ change = true;
+ }
+ }
+
+ if (change && !bitmap_bit_p (final_bbs, bb->index))
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ {
+ if (e->src->aux)
+ continue;
+
+ e->src->aux = e->src;
+ VEC_quick_push (basic_block, queue, e->src);
+ }
+ }
+
+ VEC_free (basic_block, heap, queue);
+}
+
+/* Dump a dereferences TABLE with heading STR to file F. */
+
+static void
+dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table)
+{
+ basic_block bb;
+
+ fprintf (dump_file, str);
+ FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
+ {
+ fprintf (f, "%4i %i ", bb->index, bitmap_bit_p (final_bbs, bb->index));
+ if (bb != EXIT_BLOCK_PTR)
+ {
+ int i;
+ for (i = 0; i < func_param_count; i++)
+ {
+ int idx = bb->index * func_param_count + i;
+ fprintf (f, " %4" HOST_WIDE_INT_PRINT "d", table[idx]);
+ }
+ }
+ fprintf (f, "\n");
+ }
+ fprintf (dump_file, "\n");
+}
+
+/* Determine what (parts of) parameters passed by reference that are not
+ assigned to are not certainly dereferenced in this function and thus the
+ dereferencing cannot be safely moved to the caller without potentially
+ introducing a segfault. Mark such REPRESENTATIVES as
+ grp_not_necessarilly_dereferenced.
+
+ The dereferenced maximum "distance," i.e. the offset + size of the accessed
+ part is calculated rather than simple booleans are calculated for each
+ pointer parameter to handle cases when only a fraction of the whole
+ aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for
+ an example).
+
+ The maximum dereference distances for each pointer parameter and BB are
+ already stored in bb_dereference. This routine simply propagates these
+ values upwards by propagate_dereference_distances and then compares the
+ distances of individual parameters in the ENTRY BB to the equivalent
+ distances of each representative of a (fraction of a) parameter. */
+
+static void
+analyze_caller_dereference_legality (VEC (access_p, heap) *representatives)
+{
+ int i;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ dump_dereferences_table (dump_file,
+ "Dereference table before propagation:\n",
+ bb_dereferences);
+
+ propagate_dereference_distances ();
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ dump_dereferences_table (dump_file,
+ "Dereference table after propagation:\n",
+ bb_dereferences);
+
+ for (i = 0; i < func_param_count; i++)
+ {
+ struct access *repr = VEC_index (access_p, representatives, i);
+ int idx = ENTRY_BLOCK_PTR->index * func_param_count + i;
+
+ if (!repr || no_accesses_p (repr))
+ continue;
+
+ do
+ {
+ if ((repr->offset + repr->size) > bb_dereferences[idx])
+ repr->grp_not_necessarilly_dereferenced = 1;
+ repr = repr->next_grp;
+ }
+ while (repr);
+ }
+}
+
+/* Return the representative access for the parameter declaration PARM if it is
+ a scalar passed by reference which is not written to and the pointer value
+ is not used directly. Thus, if it is legal to dereference it in the caller
+ and we can rule out modifications through aliases, such parameter should be
+ turned into one passed by value. Return NULL otherwise. */
+
+static struct access *
+unmodified_by_ref_scalar_representative (tree parm)
+{
+ int i, access_count;
+ struct access *access;
+ VEC (access_p, heap) *access_vec;
+
+ access_vec = get_base_access_vector (parm);
+ gcc_assert (access_vec);
+ access_count = VEC_length (access_p, access_vec);
+
+ for (i = 0; i < access_count; i++)
+ {
+ access = VEC_index (access_p, access_vec, i);
+ if (access->write)
+ return NULL;
+ }
+
+ access = VEC_index (access_p, access_vec, 0);
+ access->grp_read = 1;
+ access->grp_scalar_ptr = 1;
+ return access;
+}
+
+/* Sort collected accesses for parameter PARM, identify representatives for
+ each accessed region and link them together. Return NULL if there are
+ different but overlapping accesses, return the special ptr value meaning
+ there are no accesses for this parameter if that is the case and return the
+ first representative otherwise. Set *RO_GRP if there is a group of accesses
+ with only read (i.e. no write) accesses. */
+
+static struct access *
+splice_param_accesses (tree parm, bool *ro_grp)
+{
+ int i, j, access_count, group_count;
+ int agg_size, total_size = 0;
+ struct access *access, *res, **prev_acc_ptr = &res;
+ VEC (access_p, heap) *access_vec;
+
+ access_vec = get_base_access_vector (parm);
+ if (!access_vec)
+ return &no_accesses_representant;
+ access_count = VEC_length (access_p, access_vec);
+
+ qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
+ compare_access_positions);
+
+ i = 0;
+ total_size = 0;
+ group_count = 0;
+ while (i < access_count)
+ {
+ bool modification;
+ access = VEC_index (access_p, access_vec, i);
+ modification = access->write;
+
+ /* Access is about to become group representative unless we find some
+ nasty overlap which would preclude us from breaking this parameter
+ apart. */
+
+ j = i + 1;
+ while (j < access_count)
+ {
+ struct access *ac2 = VEC_index (access_p, access_vec, j);
+ if (ac2->offset != access->offset)
+ {
+ /* All or nothing law for parameters. */
+ if (access->offset + access->size > ac2->offset)
+ return NULL;
+ else
+ break;
+ }
+ else if (ac2->size != access->size)
+ return NULL;
+
+ modification |= ac2->write;
+ j++;
+ }
+
+ group_count++;
+ access->grp_maybe_modified = modification;
+ if (!modification)
+ *ro_grp = true;
+ *prev_acc_ptr = access;
+ prev_acc_ptr = &access->next_grp;
+ total_size += access->size;
+ i = j;
+ }
+
+ if (POINTER_TYPE_P (TREE_TYPE (parm)))
+ agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
+ else
+ agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
+ if (total_size >= agg_size)
+ return NULL;
+
+ gcc_assert (group_count > 0);
+ return res;
+}
+
+/* Decide whether parameters with representative accesses given by REPR should
+ be reduced into components. */
+
+static int
+decide_one_param_reduction (struct access *repr)
+{
+ int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit;
+ bool by_ref;
+ tree parm;
+
+ parm = repr->base;
+ cur_parm_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (parm)), 1);
+ gcc_assert (cur_parm_size > 0);
+
+ if (POINTER_TYPE_P (TREE_TYPE (parm)))
+ {
+ by_ref = true;
+ agg_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm))), 1);
+ }
+ else
+ {
+ by_ref = false;
+ agg_size = cur_parm_size;
+ }
+
+ if (dump_file)
+ {
+ struct access *acc;
+ fprintf (dump_file, "Evaluating PARAM group sizes for ");
+ print_generic_expr (dump_file, parm, 0);
+ fprintf (dump_file, " (UID: %u): \n", DECL_UID (parm));
+ for (acc = repr; acc; acc = acc->next_grp)
+ dump_access (dump_file, acc, true);
+ }
+
+ total_size = 0;
+ new_param_count = 0;
+
+ for (; repr; repr = repr->next_grp)
+ {
+ gcc_assert (parm == repr->base);
+ new_param_count++;
+
+ if (!by_ref || (!repr->grp_maybe_modified
+ && !repr->grp_not_necessarilly_dereferenced))
+ total_size += repr->size;
+ else
+ total_size += cur_parm_size;
+ }
+
+ gcc_assert (new_param_count > 0);
+
+ if (optimize_function_for_size_p (cfun))
+ parm_size_limit = cur_parm_size;
+ else
+ parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR)
+ * cur_parm_size);
+
+ if (total_size < agg_size
+ && total_size <= parm_size_limit)
+ {
+ if (dump_file)
+ fprintf (dump_file, " ....will be split into %i components\n",
+ new_param_count);
+ return new_param_count;
+ }
+ else
+ return 0;
+}
+
+/* The order of the following enums is important, we need to do extra work for
+ UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES. */
+enum ipa_splicing_result { NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES,
+ MODIF_BY_REF_ACCESSES, UNMODIF_BY_REF_ACCESSES };
+
+/* Identify representatives of all accesses to all candidate parameters for
+ IPA-SRA. Return result based on what representatives have been found. */
+
+static enum ipa_splicing_result
+splice_all_param_accesses (VEC (access_p, heap) **representatives)
+{
+ enum ipa_splicing_result result = NO_GOOD_ACCESS;
+ tree parm;
+ struct access *repr;
+
+ *representatives = VEC_alloc (access_p, heap, func_param_count);
+
+ for (parm = DECL_ARGUMENTS (current_function_decl);
+ parm;
+ parm = TREE_CHAIN (parm))
+ {
+ if (is_unused_scalar_param (parm))
+ {
+ VEC_quick_push (access_p, *representatives,
+ &no_accesses_representant);
+ if (result == NO_GOOD_ACCESS)
+ result = UNUSED_PARAMS;
+ }
+ else if (POINTER_TYPE_P (TREE_TYPE (parm))
+ && is_gimple_reg_type (TREE_TYPE (TREE_TYPE (parm)))
+ && bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
+ {
+ repr = unmodified_by_ref_scalar_representative (parm);
+ VEC_quick_push (access_p, *representatives, repr);
+ if (repr)
+ result = UNMODIF_BY_REF_ACCESSES;
+ }
+ else if (bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
+ {
+ bool ro_grp = false;
+ repr = splice_param_accesses (parm, &ro_grp);
+ VEC_quick_push (access_p, *representatives, repr);
+
+ if (repr && !no_accesses_p (repr))
+ {
+ if (POINTER_TYPE_P (TREE_TYPE (parm)))
+ {
+ if (ro_grp)
+ result = UNMODIF_BY_REF_ACCESSES;
+ else if (result < MODIF_BY_REF_ACCESSES)
+ result = MODIF_BY_REF_ACCESSES;
+ }
+ else if (result < BY_VAL_ACCESSES)
+ result = BY_VAL_ACCESSES;
+ }
+ else if (no_accesses_p (repr) && (result == NO_GOOD_ACCESS))
+ result = UNUSED_PARAMS;
+ }
+ else
+ VEC_quick_push (access_p, *representatives, NULL);
+ }
+
+ if (result == NO_GOOD_ACCESS)
+ {
+ VEC_free (access_p, heap, *representatives);
+ *representatives = NULL;
+ return NO_GOOD_ACCESS;
+ }
+
+ return result;
+}
+
+/* Return the index of BASE in PARMS. Abort if it is not found. */
+
+static inline int
+get_param_index (tree base, VEC(tree, heap) *parms)
+{
+ int i, len;
+
+ len = VEC_length (tree, parms);
+ for (i = 0; i < len; i++)
+ if (VEC_index (tree, parms, i) == base)
+ return i;
+ gcc_unreachable ();
+}
+
+/* Convert the decisions made at the representative level into compact
+ parameter adjustments. REPRESENTATIVES are pointers to first
+ representatives of each param accesses, ADJUSTMENTS_COUNT is the expected
+ final number of adjustments. */
+
+static ipa_parm_adjustment_vec
+turn_representatives_into_adjustments (VEC (access_p, heap) *representatives,
+ int adjustments_count)
+{
+ VEC (tree, heap) *parms;
+ ipa_parm_adjustment_vec adjustments;
+ tree parm;
+ int i;
+
+ gcc_assert (adjustments_count > 0);
+ parms = ipa_get_vector_of_formal_parms (current_function_decl);
+ adjustments = VEC_alloc (ipa_parm_adjustment_t, heap, adjustments_count);
+ parm = DECL_ARGUMENTS (current_function_decl);
+ for (i = 0; i < func_param_count; i++, parm = TREE_CHAIN (parm))
+ {
+ struct access *repr = VEC_index (access_p, representatives, i);
+
+ if (!repr || no_accesses_p (repr))
+ {
+ struct ipa_parm_adjustment *adj;
+
+ adj = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
+ memset (adj, 0, sizeof (*adj));
+ adj->base_index = get_param_index (parm, parms);
+ adj->base = parm;
+ if (!repr)
+ adj->copy_param = 1;
+ else
+ adj->remove_param = 1;
+ }
+ else
+ {
+ struct ipa_parm_adjustment *adj;
+ int index = get_param_index (parm, parms);
+
+ for (; repr; repr = repr->next_grp)
+ {
+ adj = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
+ memset (adj, 0, sizeof (*adj));
+ gcc_assert (repr->base == parm);
+ adj->base_index = index;
+ adj->base = repr->base;
+ adj->type = repr->type;
+ adj->offset = repr->offset;
+ adj->by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
+ && (repr->grp_maybe_modified
+ || repr->grp_not_necessarilly_dereferenced));
+
+ }
+ }
+ }
+ VEC_free (tree, heap, parms);
+ return adjustments;
+}
+
+/* Analyze the collected accesses and produce a plan what to do with the
+ parameters in the form of adjustments, NULL meaning nothing. */
+
+static ipa_parm_adjustment_vec
+analyze_all_param_acesses (void)
+{
+ enum ipa_splicing_result repr_state;
+ bool proceed = false;
+ int i, adjustments_count = 0;
+ VEC (access_p, heap) *representatives;
+ ipa_parm_adjustment_vec adjustments;
+
+ repr_state = splice_all_param_accesses (&representatives);
+ if (repr_state == NO_GOOD_ACCESS)
+ return NULL;
+
+ /* If there are any parameters passed by reference which are not modified
+ directly, we need to check whether they can be modified indirectly. */
+ if (repr_state == UNMODIF_BY_REF_ACCESSES)
+ {
+ analyze_caller_dereference_legality (representatives);
+ analyze_modified_params (representatives);
+ }
+
+ for (i = 0; i < func_param_count; i++)
+ {
+ struct access *repr = VEC_index (access_p, representatives, i);
+
+ if (repr && !no_accesses_p (repr))
+ {
+ if (repr->grp_scalar_ptr)
+ {
+ adjustments_count++;
+ if (repr->grp_not_necessarilly_dereferenced
+ || repr->grp_maybe_modified)
+ VEC_replace (access_p, representatives, i, NULL);
+ else
+ {
+ proceed = true;
+ sra_stats.scalar_by_ref_to_by_val++;
+ }
+ }
+ else
+ {
+ int new_components = decide_one_param_reduction (repr);
+
+ if (new_components == 0)
+ {
+ VEC_replace (access_p, representatives, i, NULL);
+ adjustments_count++;
+ }
+ else
+ {
+ adjustments_count += new_components;
+ sra_stats.aggregate_params_reduced++;
+ sra_stats.param_reductions_created += new_components;
+ proceed = true;
+ }
+ }
+ }
+ else
+ {
+ if (no_accesses_p (repr))
+ {
+ proceed = true;
+ sra_stats.deleted_unused_parameters++;
+ }
+ adjustments_count++;
+ }
+ }
+
+ if (!proceed && dump_file)
+ fprintf (dump_file, "NOT proceeding to change params.\n");
+
+ if (proceed)
+ adjustments = turn_representatives_into_adjustments (representatives,
+ adjustments_count);
+ else
+ adjustments = NULL;
+
+ VEC_free (access_p, heap, representatives);
+ return adjustments;
+}
+
+/* If a parameter replacement identified by ADJ does not yet exist in the form
+ of declaration, create it and record it, otherwise return the previously
+ created one. */
+
+static tree
+get_replaced_param_substitute (struct ipa_parm_adjustment *adj)
+{
+ tree repl;
+ if (!adj->new_ssa_base)
+ {
+ char *pretty_name = make_fancy_name (adj->base);
+
+ repl = make_rename_temp (TREE_TYPE (adj->base), "ISR");
+ DECL_NAME (repl) = get_identifier (pretty_name);
+ obstack_free (&name_obstack, pretty_name);
+
+ get_var_ann (repl);
+ add_referenced_var (repl);
+ adj->new_ssa_base = repl;
+ }
+ else
+ repl = adj->new_ssa_base;
+ return repl;
+}
+
+/* Find the first adjustment for a particular parameter BASE in a vector of
+ ADJUSTMENTS which is not a copy_param. Return NULL if there is no such
+ adjustment. */
+
+static struct ipa_parm_adjustment *
+get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
+{
+ int i, len;
+
+ len = VEC_length (ipa_parm_adjustment_t, adjustments);
+ for (i = 0; i < len; i++)
+ {
+ struct ipa_parm_adjustment *adj;
+
+ adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
+ if (!adj->copy_param && adj->base == base)
+ return adj;
+ }
+
+ return NULL;
+}
+
+/* Callback for scan_function. If the statement STMT defines an SSA_NAME of a
+ parameter which is to be removed because its value is not used, replace the
+ SSA_NAME with a one relating to a created VAR_DECL and replace all of its
+ uses too. DATA is a pointer to an adjustments vector. */
+
+static bool
+replace_removed_params_ssa_names (gimple stmt, void *data)
+{
+ VEC (ipa_parm_adjustment_t, heap) *adjustments;
+ struct ipa_parm_adjustment *adj;
+ tree lhs, decl, repl, name;
+
+ adjustments = (VEC (ipa_parm_adjustment_t, heap) *) data;
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ lhs = gimple_phi_result (stmt);
+ else if (is_gimple_assign (stmt))
+ lhs = gimple_assign_lhs (stmt);
+ else if (is_gimple_call (stmt))
+ lhs = gimple_call_lhs (stmt);
+ else
+ gcc_unreachable ();
+
+ if (TREE_CODE (lhs) != SSA_NAME)
+ return false;
+ decl = SSA_NAME_VAR (lhs);
+ if (TREE_CODE (decl) != PARM_DECL)
+ return false;
+
+ adj = get_adjustment_for_base (adjustments, decl);
+ if (!adj)
+ return false;
+
+ repl = get_replaced_param_substitute (adj);
+ name = make_ssa_name (repl, stmt);
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "replacing an SSA name of a removed param ");
+ print_generic_expr (dump_file, lhs, 0);
+ fprintf (dump_file, " with ");
+ print_generic_expr (dump_file, name, 0);
+ fprintf (dump_file, "\n");
+ }
+
+ if (is_gimple_assign (stmt))
+ gimple_assign_set_lhs (stmt, name);
+ else if (is_gimple_call (stmt))
+ gimple_call_set_lhs (stmt, name);
+ else
+ gimple_phi_set_result (stmt, name);
+
+ replace_uses_by (lhs, name);
+ return true;
+}
+
+/* Callback for scan_function. If the expression *EXPR should be replaced by a
+ reduction of a parameter, do so. DATA is a pointer to a vector of
+ adjustments. */
+
+static bool
+sra_ipa_modify_expr (tree *expr, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
+ bool write ATTRIBUTE_UNUSED, void *data)
+{
+ ipa_parm_adjustment_vec adjustments;
+ int i, len;
+ struct ipa_parm_adjustment *adj, *cand = NULL;
+ HOST_WIDE_INT offset, size, max_size;
+ tree base, src;
+
+ adjustments = (VEC (ipa_parm_adjustment_t, heap) *) data;
+ len = VEC_length (ipa_parm_adjustment_t, adjustments);
+
+ if (TREE_CODE (*expr) == BIT_FIELD_REF
+ || TREE_CODE (*expr) == IMAGPART_EXPR
+ || TREE_CODE (*expr) == REALPART_EXPR)
+ expr = &TREE_OPERAND (*expr, 0);
+ while (TREE_CODE (*expr) == NOP_EXPR
+ || TREE_CODE (*expr) == VIEW_CONVERT_EXPR)
+ expr = &TREE_OPERAND (*expr, 0);
+
+ base = get_ref_base_and_extent (*expr, &offset, &size, &max_size);
+ if (!base || size == -1 || max_size == -1)
+ return false;
+
+ if (INDIRECT_REF_P (base))
+ base = TREE_OPERAND (base, 0);
+
+ base = get_ssa_base_param (base);
+ if (!base || TREE_CODE (base) != PARM_DECL)
+ return false;
+
+ for (i = 0; i < len; i++)
+ {
+ adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
+
+ if (adj->base == base &&
+ (adj->offset == offset || adj->remove_param))
+ {
+ cand = adj;
+ break;
+ }
+ }
+ if (!cand || cand->copy_param || cand->remove_param)
+ return false;
+
+ if (cand->by_ref)
+ {
+ tree folded;
+ src = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (cand->reduction)),
+ cand->reduction);
+ folded = gimple_fold_indirect_ref (src);
+ if (folded)
+ src = folded;
+ }
+ else
+ src = cand->reduction;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "About to replace expr ");
+ print_generic_expr (dump_file, *expr, 0);
+ fprintf (dump_file, " with ");
+ print_generic_expr (dump_file, src, 0);
+ fprintf (dump_file, "\n");
+ }
+
+ if (!useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
+ {
+ tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
+ *expr = vce;
+ }
+ else
+ *expr = src;
+ return true;
+}
+
+/* Callback for scan_function to process assign statements. Performs
+ essentially the same function like sra_ipa_modify_expr. */
+
+static enum scan_assign_result
+sra_ipa_modify_assign (gimple *stmt_ptr,
+ gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, void *data)
+{
+ gimple stmt = *stmt_ptr;
+ bool any = false;
+
+ if (!gimple_assign_single_p (stmt))
+ return SRA_SA_NONE;
+
+ any |= sra_ipa_modify_expr (gimple_assign_rhs1_ptr (stmt), gsi, false,
+ data);
+ any |= sra_ipa_modify_expr (gimple_assign_lhs_ptr (stmt), gsi, true, data);
+
+ return any ? SRA_SA_PROCESSED : SRA_SA_NONE;
+}
+
+/* Call gimple_debug_bind_reset_value on all debug statements describing
+ gimple register parameters that are being removed or replaced. */
+
+static void
+sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
+{
+ int i, len;
+
+ len = VEC_length (ipa_parm_adjustment_t, adjustments);
+ for (i = 0; i < len; i++)
+ {
+ struct ipa_parm_adjustment *adj;
+ imm_use_iterator ui;
+ gimple stmt;
+ tree name;
+
+ adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
+ if (adj->copy_param || !is_gimple_reg (adj->base))
+ continue;
+ name = gimple_default_def (cfun, adj->base);
+ if (!name)
+ continue;
+ FOR_EACH_IMM_USE_STMT (stmt, ui, name)
+ {
+ /* All other users must have been removed by scan_function. */
+ gcc_assert (is_gimple_debug (stmt));
+ gimple_debug_bind_reset_value (stmt);
+ update_stmt (stmt);
+ }
+ }
+}
+
+/* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS. */
+
+static void
+convert_callers (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
+{
+ tree old_cur_fndecl = current_function_decl;
+ struct cgraph_edge *cs;
+ basic_block this_block;
+
+ for (cs = node->callers; cs; cs = cs->next_caller)
+ {
+ current_function_decl = cs->caller->decl;
+ push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl));
+
+ if (dump_file)
+ fprintf (dump_file, "Adjusting call %s -> %s\n",
+ cgraph_node_name (cs->caller),
+ cgraph_node_name (cs->callee));
+
+ if (cs->call_stmt)
+ ipa_modify_call_arguments (cs, cs->call_stmt, adjustments);
+
+ compute_inline_parameters (cs->caller);
+
+ pop_cfun ();
+ }
+ current_function_decl = old_cur_fndecl;
+ FOR_EACH_BB (this_block)
+ {
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ if (gimple_code (stmt) == GIMPLE_CALL
+ && gimple_call_fndecl (stmt) == node->decl)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Adjusting recursive call");
+ ipa_modify_call_arguments (NULL, stmt, adjustments);
+ }
+ }
+ }
+
+ return;
+}
+
+/* Create a new name for omp child function. Returns an identifier. */
+
+static GTY(()) unsigned int clone_fn_id_num;
+
+static tree
+clone_function_name (tree decl)
+{
+ tree name = DECL_ASSEMBLER_NAME (decl);
+ size_t len = IDENTIFIER_LENGTH (name);
+ char *tmp_name, *prefix;
+
+ prefix = XALLOCAVEC (char, len + strlen ("_clone.sra") + 1);
+ memcpy (prefix, IDENTIFIER_POINTER (name), len);
+ strcpy (prefix + len, "_clone.sra");
+#ifndef NO_DOT_IN_LABEL
+ prefix[len] = '.';
+#elif !defined NO_DOLLAR_IN_LABEL
+ prefix[len] = '$';
+#endif
+ ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, clone_fn_id_num++);
+ return get_identifier (tmp_name);
+}
+
+
+/* Perform all the modification required in IPA-SRA for NODE to have parameters
+ as given in ADJUSTMENTS. */
+
+static void
+modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
+{
+ ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA");
+ scan_function (sra_ipa_modify_expr, sra_ipa_modify_assign,
+ replace_removed_params_ssa_names, false, adjustments);
+ sra_ipa_reset_debug_stmts (adjustments);
+ convert_callers (node, adjustments);
+ cgraph_make_node_local (node);
+
+ /* In LIPO mode, it is possible that the function with the same assember name
+ from the aux module needs to be emitted as well (e.g. in comdat). To avoid
+ conflicts in assembler, change the name. */
+ if (L_IPO_COMP_MODE)
+ {
+ cgraph_remove_assembler_hash_node (node);
+ DECL_NAME (node->decl) = clone_function_name (node->decl);
+ SET_DECL_ASSEMBLER_NAME (node->decl, DECL_NAME (node->decl));
+ cgraph_add_assembler_hash_node (node);
+ }
+ return;
+}
+
+/* Return false the function is apparently unsuitable for IPA-SRA based on it's
+ attributes, return true otherwise. NODE is the cgraph node of the current
+ function. */
+
+static bool
+ipa_sra_preliminary_function_checks (struct cgraph_node *node)
+{
+ if (!cgraph_node_can_be_local_p (node))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Function not local to this compilation unit.\n");
+ return false;
+ }
+
+ if (DECL_VIRTUAL_P (current_function_decl))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Function is a virtual method.\n");
+ return false;
+ }
+
+ if ((DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
+ && node->global.size >= MAX_INLINE_INSNS_AUTO)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Function too big to be made truly local.\n");
+ return false;
+ }
+
+ if (!node->callers)
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Function has no callers in this compilation unit.\n");
+ return false;
+ }
+
+ if (cfun->stdarg)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Function uses stdarg. \n");
+ return false;
+ }
+
+ /* After ipa_sra, the global function will be localized.
+ However an aux function will still be deleted leading
+ to bad consequence (call to the modified function gets
+ resolved to the external version). Note that changing
+ cgraph_is_aux_decl_external is not enough, as the needed
+ bit is already computed. */
+ if (L_IPO_COMP_MODE && cgraph_is_auxiliary (node->decl))
+ return false;
+
+ return true;
+}
+
+/* Perform early interprocedural SRA. */
+
+static unsigned int
+ipa_early_sra (void)
+{
+ struct cgraph_node *node = cgraph_node (current_function_decl);
+ ipa_parm_adjustment_vec adjustments;
+ int ret = 0;
+
+ if (!ipa_sra_preliminary_function_checks (node))
+ return 0;
+
+ sra_initialize ();
+ sra_mode = SRA_MODE_EARLY_IPA;
+
+ if (!find_param_candidates ())
+ {
+ if (dump_file)
+ fprintf (dump_file, "Function has no IPA-SRA candidates.\n");
+ goto simple_out;
+ }
+
+ bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
+ func_param_count
+ * last_basic_block_for_function (cfun));
+ final_bbs = BITMAP_ALLOC (NULL);
+
+ scan_function (build_access_from_expr, build_accesses_from_assign,
+ NULL, true, NULL);
+ if (encountered_apply_args)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Function calls __builtin_apply_args().\n");
+ goto out;
+ }
+
+ adjustments = analyze_all_param_acesses ();
+ if (!adjustments)
+ goto out;
+ if (dump_file)
+ ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
+
+ modify_function (node, adjustments);
+ VEC_free (ipa_parm_adjustment_t, heap, adjustments);
+ ret = TODO_update_ssa;
+
+ statistics_counter_event (cfun, "Unused parameters deleted",
+ sra_stats.deleted_unused_parameters);
+ statistics_counter_event (cfun, "Scalar parameters converted to by-value",
+ sra_stats.scalar_by_ref_to_by_val);
+ statistics_counter_event (cfun, "Aggregate parameters broken up",
+ sra_stats.aggregate_params_reduced);
+ statistics_counter_event (cfun, "Aggregate parameter components created",
+ sra_stats.param_reductions_created);
+
+ out:
+ BITMAP_FREE (final_bbs);
+ free (bb_dereferences);
+ simple_out:
+ sra_deinitialize ();
+ return ret;
+}
+
+/* Return if early ipa sra shall be performed. */
+static bool
+ipa_early_sra_gate (void)
+{
+ return flag_ipa_sra;
+}
+
+struct gimple_opt_pass pass_early_ipa_sra =
+{
+ {
+ GIMPLE_PASS,
+ "eipa_sra", /* name */
+ ipa_early_sra_gate, /* gate */
+ ipa_early_sra, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_IPA_SRA, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_dump_cgraph /* todo_flags_finish */
+ }
+};
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 4b08f85e493..bb91d8b7cd5 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -210,6 +210,14 @@ ptr_deref_may_alias_decl_p (tree ptr, tree decl)
if (!pi)
return true;
+ /* If the decl can be used as a restrict tag and we have a restrict
+ pointer and that pointers points-to set doesn't contain this decl
+ then they can't alias. */
+ if (DECL_RESTRICTED_P (decl)
+ && TYPE_RESTRICT (TREE_TYPE (ptr))
+ && pi->pt.vars_contains_restrict)
+ return bitmap_bit_p (pi->pt.vars, DECL_UID (decl));
+
return pt_solution_includes (&pi->pt, decl);
}
@@ -792,6 +800,12 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
|| is_gimple_min_invariant (base2))
return false;
+ /* We can end up refering to code via function decls. As we likely
+ do not properly track code aliases conservatively bail out. */
+ if (TREE_CODE (base1) == FUNCTION_DECL
+ || TREE_CODE (base2) == FUNCTION_DECL)
+ return true;
+
/* Defer to simple offset based disambiguation if we have
references based on two decls. Do this before defering to
TBAA to handle must-alias cases in conformance with the
@@ -1030,10 +1044,6 @@ process_args:
{
tree op = gimple_call_arg (call, i);
- if (TREE_CODE (op) == EXC_PTR_EXPR
- || TREE_CODE (op) == FILTER_EXPR)
- continue;
-
if (TREE_CODE (op) == WITH_SIZE_EXPR)
op = TREE_OPERAND (op, 0);
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 949c4b5ce77..61827a74ab4 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -1818,8 +1818,7 @@ maybe_fold_offset_to_array_ref (location_t loc, tree base, tree offset,
static tree
maybe_fold_offset_to_component_ref (location_t loc, tree record_type,
- tree base, tree offset,
- tree orig_type, bool base_is_ptr)
+ tree base, tree offset, tree orig_type)
{
tree f, t, field_type, tail_array_field, field_offset;
tree ret;
@@ -1871,8 +1870,6 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type,
if (cmp == 0
&& useless_type_conversion_p (orig_type, field_type))
{
- if (base_is_ptr)
- base = build1 (INDIRECT_REF, record_type, base);
t = build3 (COMPONENT_REF, field_type, base, f, NULL_TREE);
return t;
}
@@ -1897,13 +1894,8 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type,
/* If we matched, then set offset to the displacement into
this field. */
- if (base_is_ptr)
- new_base = build1 (INDIRECT_REF, record_type, base);
- else
- new_base = base;
- protected_set_expr_location (new_base, loc);
- new_base = build3 (COMPONENT_REF, field_type, new_base, f, NULL_TREE);
- protected_set_expr_location (new_base, loc);
+ new_base = build3 (COMPONENT_REF, field_type, base, f, NULL_TREE);
+ SET_EXPR_LOCATION (new_base, loc);
/* Recurse to possibly find the match. */
ret = maybe_fold_offset_to_array_ref (loc, new_base, t, orig_type,
@@ -1911,7 +1903,7 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type,
if (ret)
return ret;
ret = maybe_fold_offset_to_component_ref (loc, field_type, new_base, t,
- orig_type, false);
+ orig_type);
if (ret)
return ret;
}
@@ -1925,11 +1917,6 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type,
/* If we get here, we've got an aggregate field, and a possibly
nonzero offset into them. Recurse and hope for a valid match. */
- if (base_is_ptr)
- {
- base = build1 (INDIRECT_REF, record_type, base);
- SET_EXPR_LOCATION (base, loc);
- }
base = build3 (COMPONENT_REF, field_type, base, f, NULL_TREE);
SET_EXPR_LOCATION (base, loc);
@@ -1938,7 +1925,7 @@ maybe_fold_offset_to_component_ref (location_t loc, tree record_type,
if (t)
return t;
return maybe_fold_offset_to_component_ref (loc, field_type, base, offset,
- orig_type, false);
+ orig_type);
}
/* Attempt to express (ORIG_TYPE)BASE+OFFSET as BASE->field_of_orig_type
@@ -1955,61 +1942,44 @@ maybe_fold_offset_to_reference (location_t loc, tree base, tree offset,
{
tree ret;
tree type;
- bool base_is_ptr = true;
STRIP_NOPS (base);
- if (TREE_CODE (base) == ADDR_EXPR)
- {
- base_is_ptr = false;
-
- base = TREE_OPERAND (base, 0);
+ if (TREE_CODE (base) != ADDR_EXPR)
+ return NULL_TREE;
- /* Handle case where existing COMPONENT_REF pick e.g. wrong field of union,
- so it needs to be removed and new COMPONENT_REF constructed.
- The wrong COMPONENT_REF are often constructed by folding the
- (type *)&object within the expression (type *)&object+offset */
- if (handled_component_p (base))
+ base = TREE_OPERAND (base, 0);
+
+ /* Handle case where existing COMPONENT_REF pick e.g. wrong field of union,
+ so it needs to be removed and new COMPONENT_REF constructed.
+ The wrong COMPONENT_REF are often constructed by folding the
+ (type *)&object within the expression (type *)&object+offset */
+ if (handled_component_p (base))
+ {
+ HOST_WIDE_INT sub_offset, size, maxsize;
+ tree newbase;
+ newbase = get_ref_base_and_extent (base, &sub_offset,
+ &size, &maxsize);
+ gcc_assert (newbase);
+ if (size == maxsize
+ && size != -1
+ && !(sub_offset & (BITS_PER_UNIT - 1)))
{
- HOST_WIDE_INT sub_offset, size, maxsize;
- tree newbase;
- newbase = get_ref_base_and_extent (base, &sub_offset,
- &size, &maxsize);
- gcc_assert (newbase);
- if (size == maxsize
- && size != -1
- && !(sub_offset & (BITS_PER_UNIT - 1)))
- {
- base = newbase;
- if (sub_offset)
- offset = int_const_binop (PLUS_EXPR, offset,
- build_int_cst (TREE_TYPE (offset),
- sub_offset / BITS_PER_UNIT), 1);
- }
+ base = newbase;
+ if (sub_offset)
+ offset = int_const_binop (PLUS_EXPR, offset,
+ build_int_cst (TREE_TYPE (offset),
+ sub_offset / BITS_PER_UNIT), 1);
}
- if (useless_type_conversion_p (orig_type, TREE_TYPE (base))
- && integer_zerop (offset))
- return base;
- type = TREE_TYPE (base);
}
- else
- {
- base_is_ptr = true;
- if (!POINTER_TYPE_P (TREE_TYPE (base)))
- return NULL_TREE;
- type = TREE_TYPE (TREE_TYPE (base));
- }
- ret = maybe_fold_offset_to_component_ref (loc, type, base, offset,
- orig_type, base_is_ptr);
+ if (useless_type_conversion_p (orig_type, TREE_TYPE (base))
+ && integer_zerop (offset))
+ return base;
+ type = TREE_TYPE (base);
+
+ ret = maybe_fold_offset_to_component_ref (loc, type, base, offset, orig_type);
if (!ret)
- {
- if (base_is_ptr)
- {
- base = build1 (INDIRECT_REF, type, base);
- SET_EXPR_LOCATION (base, loc);
- }
- ret = maybe_fold_offset_to_array_ref (loc,
- base, offset, orig_type, true);
- }
+ ret = maybe_fold_offset_to_array_ref (loc, base, offset, orig_type, true);
+
return ret;
}
@@ -2214,16 +2184,16 @@ maybe_fold_stmt_addition (location_t loc, tree res_type, tree op0, tree op1)
&& TREE_CODE (gimple_assign_rhs2 (offset_def)) == INTEGER_CST
&& tree_int_cst_equal (gimple_assign_rhs2 (offset_def),
TYPE_SIZE_UNIT (TREE_TYPE (op0))))
- return build1 (ADDR_EXPR, res_type,
- build4 (ARRAY_REF, TREE_TYPE (op0),
+ return build_fold_addr_expr
+ (build4 (ARRAY_REF, TREE_TYPE (op0),
TREE_OPERAND (op0, 0),
gimple_assign_rhs1 (offset_def),
TREE_OPERAND (op0, 2),
TREE_OPERAND (op0, 3)));
else if (integer_onep (TYPE_SIZE_UNIT (TREE_TYPE (op0)))
&& gimple_assign_rhs_code (offset_def) != MULT_EXPR)
- return build1 (ADDR_EXPR, res_type,
- build4 (ARRAY_REF, TREE_TYPE (op0),
+ return build_fold_addr_expr
+ (build4 (ARRAY_REF, TREE_TYPE (op0),
TREE_OPERAND (op0, 0),
op1,
TREE_OPERAND (op0, 2),
@@ -2286,7 +2256,7 @@ maybe_fold_stmt_addition (location_t loc, tree res_type, tree op0, tree op1)
t = maybe_fold_offset_to_array_ref (loc, op0, op1, ptd_type, true);
if (!t)
t = maybe_fold_offset_to_component_ref (loc, TREE_TYPE (op0), op0, op1,
- ptd_type, false);
+ ptd_type);
if (t)
{
t = build1 (ADDR_EXPR, res_type, t);
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 99a039fffee..67d0472cc59 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -322,15 +322,6 @@ mark_stmt_if_obviously_necessary (gimple stmt, bool aggressive)
case GIMPLE_ASSIGN:
if (!lhs)
lhs = gimple_assign_lhs (stmt);
- /* These values are mildly magic bits of the EH runtime. We can't
- see the entire lifetime of these values until landing pads are
- generated. */
- if (TREE_CODE (lhs) == EXC_PTR_EXPR
- || TREE_CODE (lhs) == FILTER_EXPR)
- {
- mark_stmt_necessary (stmt, true);
- return;
- }
break;
case GIMPLE_DEBUG:
@@ -817,28 +808,33 @@ propagate_necessity (struct edge_list *el)
/* Replace all uses of result of PHI by underlying variable and mark it
for renaming. */
-static void
+void
mark_virtual_phi_result_for_renaming (gimple phi)
{
bool used = false;
imm_use_iterator iter;
use_operand_p use_p;
gimple stmt;
+ tree result_ssa, result_var;
+
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Marking result for renaming : ");
print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
- FOR_EACH_IMM_USE_STMT (stmt, iter, gimple_phi_result (phi))
+
+ result_ssa = gimple_phi_result (phi);
+ result_var = SSA_NAME_VAR (result_ssa);
+ FOR_EACH_IMM_USE_STMT (stmt, iter, result_ssa)
{
FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
- SET_USE (use_p, SSA_NAME_VAR (gimple_phi_result (phi)));
+ SET_USE (use_p, result_var);
update_stmt (stmt);
used = true;
}
if (used)
- mark_sym_for_renaming (SSA_NAME_VAR (PHI_RESULT (phi)));
+ mark_sym_for_renaming (result_var);
}
/* Remove dead PHI nodes from block BB. */
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 05988636489..42b2ef36252 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -5297,42 +5297,6 @@ create_new_ivs (struct ivopts_data *data, struct iv_ca *set)
}
}
-/* Returns the phi-node in BB with result RESULT. */
-
-static gimple
-get_phi_with_result (basic_block bb, tree result)
-{
- gimple_stmt_iterator i = gsi_start_phis (bb);
-
- for (; !gsi_end_p (i); gsi_next (&i))
- if (gimple_phi_result (gsi_stmt (i)) == result)
- return gsi_stmt (i);
-
- gcc_unreachable ();
- return NULL;
-}
-
-
-/* Removes statement STMT (real or a phi node). If INCLUDING_DEFINED_NAME
- is true, remove also the ssa name defined by the statement. */
-
-static void
-remove_statement (gimple stmt, bool including_defined_name)
-{
- if (gimple_code (stmt) == GIMPLE_PHI)
- {
- gimple bb_phi = get_phi_with_result (gimple_bb (stmt),
- gimple_phi_result (stmt));
- gimple_stmt_iterator bsi = gsi_for_stmt (bb_phi);
- remove_phi_node (&bsi, including_defined_name);
- }
- else
- {
- gimple_stmt_iterator bsi = gsi_for_stmt (stmt);
- gsi_remove (&bsi, true);
- release_defs (stmt);
- }
-}
/* Rewrites USE (definition of iv used in a nonlinear expression)
using candidate CAND. */
@@ -5435,7 +5399,9 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
{
ass = gimple_build_assign (tgt, op);
gsi_insert_before (&bsi, ass, GSI_SAME_STMT);
- remove_statement (use->stmt, false);
+
+ bsi = gsi_for_stmt (use->stmt);
+ remove_phi_node (&bsi, false);
}
else
{
@@ -5611,7 +5577,11 @@ remove_unused_ivs (struct ivopts_data *data)
{
unsigned j;
bitmap_iterator bi;
+ bitmap toremove = BITMAP_ALLOC (NULL);
+ /* Figure out an order in which to release SSA DEFs so that we don't
+ release something that we'd have to propagate into a debug stmt
+ afterwards. */
EXECUTE_IF_SET_IN_BITMAP (data->relevant, 0, j, bi)
{
struct version_info *info;
@@ -5622,25 +5592,12 @@ remove_unused_ivs (struct ivopts_data *data)
&& !info->inv_id
&& !info->iv->have_use_for
&& !info->preserve_biv)
- {
- if (MAY_HAVE_DEBUG_STMTS)
- {
- gimple stmt;
- imm_use_iterator iter;
-
- FOR_EACH_IMM_USE_STMT (stmt, iter, info->iv->ssa_name)
- {
- if (!gimple_debug_bind_p (stmt))
- continue;
-
- /* ??? We can probably do better than this. */
- gimple_debug_bind_reset_value (stmt);
- update_stmt (stmt);
- }
- }
- remove_statement (SSA_NAME_DEF_STMT (info->iv->ssa_name), true);
- }
+ bitmap_set_bit (toremove, SSA_NAME_VERSION (info->iv->ssa_name));
}
+
+ release_defs_bitset (toremove);
+
+ BITMAP_FREE (toremove);
}
/* Frees data allocated by the optimization of a single loop. */
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index ac84fb978b0..28e6ec65826 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -735,8 +735,8 @@ static void
get_tmr_operands (gimple stmt, tree expr, int flags)
{
/* First record the real operands. */
- get_expr_operands (stmt, &TMR_BASE (expr), opf_use);
- get_expr_operands (stmt, &TMR_INDEX (expr), opf_use);
+ get_expr_operands (stmt, &TMR_BASE (expr), opf_use | (flags & opf_no_vops));
+ get_expr_operands (stmt, &TMR_INDEX (expr), opf_use | (flags & opf_no_vops));
if (TMR_SYMBOL (expr))
mark_address_taken (TMR_SYMBOL (expr));
@@ -1000,8 +1000,6 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags)
case LABEL_DECL:
case CONST_DECL:
case CASE_LABEL_EXPR:
- case FILTER_EXPR:
- case EXC_PTR_EXPR:
/* Expressions that make no memory references. */
return;
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index b809ab30f8d..3accbbc2bb1 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -857,7 +857,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
/* Move the statement from the middle block. */
gsi = gsi_last_bb (cond_bb);
- gsi_from = gsi_last_bb (middle_bb);
+ gsi_from = gsi_last_nondebug_bb (middle_bb);
gsi_move_before (&gsi_from, &gsi);
}
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 7a0533e4301..5da6c63b400 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -401,10 +401,6 @@ typedef struct bb_bitmap_sets
#define BB_DEFERRED(BB) ((bb_value_sets_t) ((BB)->aux))->deferred
-/* Maximal set of values, used to initialize the ANTIC problem, which
- is an intersection problem. */
-static bitmap_set_t maximal_set;
-
/* Basic block list in postorder. */
static int *postorder;
@@ -1072,9 +1068,7 @@ get_or_alloc_expr_for (tree t)
{
if (TREE_CODE (t) == SSA_NAME)
return get_or_alloc_expr_for_name (t);
- else if (is_gimple_min_invariant (t)
- || TREE_CODE (t) == EXC_PTR_EXPR
- || TREE_CODE (t) == FILTER_EXPR)
+ else if (is_gimple_min_invariant (t))
return get_or_alloc_expr_for_constant (t);
else
{
@@ -2201,49 +2195,45 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
{
VEC(basic_block, heap) * worklist;
size_t i;
- basic_block bprime, first;
+ basic_block bprime, first = NULL;
worklist = VEC_alloc (basic_block, heap, EDGE_COUNT (block->succs));
FOR_EACH_EDGE (e, ei, block->succs)
- VEC_quick_push (basic_block, worklist, e->dest);
- first = VEC_index (basic_block, worklist, 0);
-
- if (phi_nodes (first))
{
- bitmap_set_t from = ANTIC_IN (first);
-
- if (!BB_VISITED (first))
- from = maximal_set;
- phi_translate_set (ANTIC_OUT, from, block, first);
+ if (!first
+ && BB_VISITED (e->dest))
+ first = e->dest;
+ else if (BB_VISITED (e->dest))
+ VEC_quick_push (basic_block, worklist, e->dest);
}
- else
+
+ /* Of multiple successors we have to have visited one already. */
+ if (!first)
{
- if (!BB_VISITED (first))
- bitmap_set_copy (ANTIC_OUT, maximal_set);
- else
- bitmap_set_copy (ANTIC_OUT, ANTIC_IN (first));
+ SET_BIT (changed_blocks, block->index);
+ BB_VISITED (block) = 0;
+ BB_DEFERRED (block) = 1;
+ changed = true;
+ VEC_free (basic_block, heap, worklist);
+ goto maybe_dump_sets;
}
- for (i = 1; VEC_iterate (basic_block, worklist, i, bprime); i++)
+ if (phi_nodes (first))
+ phi_translate_set (ANTIC_OUT, ANTIC_IN (first), block, first);
+ else
+ bitmap_set_copy (ANTIC_OUT, ANTIC_IN (first));
+
+ for (i = 0; VEC_iterate (basic_block, worklist, i, bprime); i++)
{
if (phi_nodes (bprime))
{
bitmap_set_t tmp = bitmap_set_new ();
- bitmap_set_t from = ANTIC_IN (bprime);
-
- if (!BB_VISITED (bprime))
- from = maximal_set;
- phi_translate_set (tmp, from, block, bprime);
+ phi_translate_set (tmp, ANTIC_IN (bprime), block, bprime);
bitmap_set_and (ANTIC_OUT, tmp);
bitmap_set_free (tmp);
}
else
- {
- if (!BB_VISITED (bprime))
- bitmap_set_and (ANTIC_OUT, maximal_set);
- else
- bitmap_set_and (ANTIC_OUT, ANTIC_IN (bprime));
- }
+ bitmap_set_and (ANTIC_OUT, ANTIC_IN (bprime));
}
VEC_free (basic_block, heap, worklist);
}
@@ -2557,17 +2547,6 @@ can_value_number_call (gimple stmt)
return false;
}
-/* Return true if OP is an exception handler related operation, such as
- FILTER_EXPR or EXC_PTR_EXPR. */
-
-static bool
-is_exception_related (gimple stmt)
-{
- return (is_gimple_assign (stmt)
- && (gimple_assign_rhs_code (stmt) == FILTER_EXPR
- || gimple_assign_rhs_code (stmt) == EXC_PTR_EXPR));
-}
-
/* Return true if OP is a tree which we can perform PRE on.
This may not match the operations we can value number, but in
a perfect world would. */
@@ -3711,7 +3690,6 @@ add_to_exp_gen (basic_block block, tree op)
return;
result = get_or_alloc_expr_for_name (op);
bitmap_value_insert_into_set (EXP_GEN (block), result);
- bitmap_value_insert_into_set (maximal_set, result);
}
}
@@ -3740,7 +3718,6 @@ make_values_for_phi (gimple phi, basic_block block)
{
e = get_or_alloc_expr_for_name (arg);
add_to_value (get_expr_value_id (e), e);
- bitmap_value_insert_into_set (maximal_set, e);
}
}
}
@@ -3781,10 +3758,7 @@ compute_avail (void)
e = get_or_alloc_expr_for_name (name);
add_to_value (get_expr_value_id (e), e);
if (!in_fre)
- {
- bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR), e);
- bitmap_value_insert_into_set (maximal_set, e);
- }
+ bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR), e);
bitmap_value_insert_into_set (AVAIL_OUT (ENTRY_BLOCK_PTR), e);
}
@@ -3888,11 +3862,7 @@ compute_avail (void)
get_or_alloc_expression_id (result);
add_to_value (get_expr_value_id (result), result);
if (!in_fre)
- {
- bitmap_value_insert_into_set (EXP_GEN (block),
- result);
- bitmap_value_insert_into_set (maximal_set, result);
- }
+ bitmap_value_insert_into_set (EXP_GEN (block), result);
continue;
}
@@ -3902,8 +3872,6 @@ compute_avail (void)
switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
{
case tcc_unary:
- if (is_exception_related (stmt))
- continue;
case tcc_binary:
case tcc_comparison:
{
@@ -3974,10 +3942,7 @@ compute_avail (void)
get_or_alloc_expression_id (result);
add_to_value (get_expr_value_id (result), result);
if (!in_fre)
- {
- bitmap_value_insert_into_set (EXP_GEN (block), result);
- bitmap_value_insert_into_set (maximal_set, result);
- }
+ bitmap_value_insert_into_set (EXP_GEN (block), result);
continue;
}
@@ -4515,7 +4480,6 @@ init_pre (bool do_fre)
TMP_GEN (bb) = bitmap_set_new ();
AVAIL_OUT (bb) = bitmap_set_new ();
}
- maximal_set = in_fre ? NULL : bitmap_set_new ();
need_eh_cleanup = BITMAP_ALLOC (NULL);
}
@@ -4601,8 +4565,6 @@ execute_pre (bool do_fre ATTRIBUTE_UNUSED)
print_bitmap_set (dump_file, TMP_GEN (bb), "tmp_gen", bb->index);
print_bitmap_set (dump_file, AVAIL_OUT (bb), "avail_out", bb->index);
}
-
- print_bitmap_set (dump_file, maximal_set, "maximal", 0);
}
/* Insert can get quite slow on an incredibly large number of basic
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
index ab9cee34a21..42d89e91920 100644
--- a/gcc/tree-ssa-propagate.c
+++ b/gcc/tree-ssa-propagate.c
@@ -617,10 +617,6 @@ valid_gimple_rhs_p (tree expr)
return false;
break;
- case EXC_PTR_EXPR:
- case FILTER_EXPR:
- break;
-
default:
return false;
}
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index d97f51367e2..55ce2f65a4f 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -192,7 +192,7 @@ static inline long
find_operand_rank (tree e)
{
void **slot = pointer_map_contains (operand_rank, e);
- return slot ? (long) *slot : -1;
+ return slot ? (long) (intptr_t) *slot : -1;
}
/* Insert {E,RANK} into the operand rank hashtable. */
@@ -204,7 +204,7 @@ insert_operand_rank (tree e, long rank)
gcc_assert (rank > 0);
slot = pointer_map_insert (operand_rank, e);
gcc_assert (!*slot);
- *slot = (void *) rank;
+ *slot = (void *) (intptr_t) rank;
}
/* Given an expression E, return the rank of the expression. */
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 3d814fc2e0b..4158fbd88df 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -576,8 +576,6 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
case CONST_DECL:
case RESULT_DECL:
case SSA_NAME:
- case EXC_PTR_EXPR:
- case FILTER_EXPR:
temp.op0 = ref;
break;
case ADDR_EXPR:
@@ -688,8 +686,6 @@ ao_ref_init_from_vn_reference (ao_ref *ref,
case PARM_DECL:
case RESULT_DECL:
case SSA_NAME:
- case FILTER_EXPR:
- case EXC_PTR_EXPR:
*op0_p = op->op0;
break;
@@ -1120,7 +1116,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_)
copy_reference_ops_from_ref (gimple_assign_lhs (def_stmt), &lhs);
i = VEC_length (vn_reference_op_s, vr->operands) - 1;
j = VEC_length (vn_reference_op_s, lhs) - 1;
- while (j >= 0
+ while (j >= 0 && i >= 0
&& vn_reference_op_eq (VEC_index (vn_reference_op_s,
vr->operands, i),
VEC_index (vn_reference_op_s, lhs, j)))
@@ -1128,13 +1124,14 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_)
i--;
j--;
}
+
+ VEC_free (vn_reference_op_s, heap, lhs);
/* i now points to the first additional op.
??? LHS may not be completely contained in VR, one or more
VIEW_CONVERT_EXPRs could be in its way. We could at least
try handling outermost VIEW_CONVERT_EXPRs. */
if (j != -1)
return (void *)-1;
- VEC_free (vn_reference_op_s, heap, lhs);
/* Now re-write REF to be based on the rhs of the assignment. */
copy_reference_ops_from_ref (gimple_assign_rhs1 (def_stmt), &rhs);
diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c
index 5b9b4be3090..a9b4b67679b 100644
--- a/gcc/tree-ssa-sink.c
+++ b/gcc/tree-ssa-sink.c
@@ -323,8 +323,6 @@ statement_sink_location (gimple stmt, basic_block frombb,
code = gimple_assign_rhs_code (stmt);
if (stmt_ends_bb_p (stmt)
|| gimple_has_side_effects (stmt)
- || code == EXC_PTR_EXPR
- || code == FILTER_EXPR
|| is_hidden_global_store (stmt)
|| gimple_has_volatile_ops (stmt)
|| gimple_vuse (stmt)
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index a9d31325b57..e5f4a292855 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -425,10 +425,6 @@ struct constraint
static VEC(constraint_t,heap) *constraints;
static alloc_pool constraint_pool;
-
-DEF_VEC_I(int);
-DEF_VEC_ALLOC_I(int, heap);
-
/* The constraint graph is represented as an array of bitmaps
containing successor nodes. */
@@ -1287,10 +1283,6 @@ build_succ_graph (void)
static unsigned int changed_count;
static sbitmap changed;
-DEF_VEC_I(unsigned);
-DEF_VEC_ALLOC_I(unsigned,heap);
-
-
/* Strongly Connected Component visitation info. */
struct scc_info
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 2f8aead694c..64280f0527f 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -444,6 +444,74 @@ propagate_defs_into_debug_stmts (gimple def, basic_block tobb,
}
}
+/* Delete SSA DEFs for SSA versions in the TOREMOVE bitmap, removing
+ dominated stmts before their dominators, so that release_ssa_defs
+ stands a chance of propagating DEFs into debug bind stmts. */
+
+void
+release_defs_bitset (bitmap toremove)
+{
+ unsigned j;
+ bitmap_iterator bi;
+
+ /* Performing a topological sort is probably overkill, this will
+ most likely run in slightly superlinear time, rather than the
+ pathological quadratic worst case. */
+ while (!bitmap_empty_p (toremove))
+ EXECUTE_IF_SET_IN_BITMAP (toremove, 0, j, bi)
+ {
+ bool remove_now = true;
+ tree var = ssa_name (j);
+ gimple stmt;
+ imm_use_iterator uit;
+
+ FOR_EACH_IMM_USE_STMT (stmt, uit, var)
+ {
+ ssa_op_iter dit;
+ def_operand_p def_p;
+
+ /* We can't propagate PHI nodes into debug stmts. */
+ if (gimple_code (stmt) == GIMPLE_PHI
+ || is_gimple_debug (stmt))
+ continue;
+
+ /* If we find another definition to remove that uses
+ the one we're looking at, defer the removal of this
+ one, so that it can be propagated into debug stmts
+ after the other is. */
+ FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, dit, SSA_OP_DEF)
+ {
+ tree odef = DEF_FROM_PTR (def_p);
+
+ if (bitmap_bit_p (toremove, SSA_NAME_VERSION (odef)))
+ {
+ remove_now = false;
+ break;
+ }
+ }
+
+ if (!remove_now)
+ BREAK_FROM_IMM_USE_STMT (uit);
+ }
+
+ if (remove_now)
+ {
+ gimple def = SSA_NAME_DEF_STMT (var);
+ gimple_stmt_iterator gsi = gsi_for_stmt (def);
+
+ if (gimple_code (def) == GIMPLE_PHI)
+ remove_phi_node (&gsi, true);
+ else
+ {
+ gsi_remove (&gsi, true);
+ release_defs (def);
+ }
+
+ bitmap_clear_bit (toremove, j);
+ }
+ }
+}
+
/* Return true if SSA_NAME is malformed and mark it visited.
IS_VIRTUAL is true if this SSA_NAME was found inside a virtual
@@ -1309,7 +1377,8 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
if (!TYPE_ARG_TYPES (outer_type))
return true;
- /* If the argument types are compatible the conversion is useless. */
+ /* If the unqualified argument types are compatible the conversion
+ is useless. */
if (TYPE_ARG_TYPES (outer_type) == TYPE_ARG_TYPES (inner_type))
return true;
@@ -1318,8 +1387,9 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
outer_parm && inner_parm;
outer_parm = TREE_CHAIN (outer_parm),
inner_parm = TREE_CHAIN (inner_parm))
- if (!useless_type_conversion_p (TREE_VALUE (outer_parm),
- TREE_VALUE (inner_parm)))
+ if (!useless_type_conversion_p
+ (TYPE_MAIN_VARIANT (TREE_VALUE (outer_parm)),
+ TYPE_MAIN_VARIANT (TREE_VALUE (inner_parm))))
return false;
/* If there is a mismatch in the number of arguments the functions
@@ -1920,7 +1990,8 @@ execute_update_addresses_taken (bool do_optimize)
{
gimple stmt = gsi_stmt (gsi);
- if (gimple_references_memory_p (stmt))
+ if (gimple_references_memory_p (stmt)
+ || is_gimple_debug (stmt))
update_stmt (stmt);
}
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 1309e822fe2..3409ef83259 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -875,7 +875,7 @@ do_switchconv (void)
"SWITCH statement (%s:%d) : ------- \n",
loc.file, loc.line);
print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
- fprintf (dump_file, "\n");
+ putc ('\n', dump_file);
}
info.reason = NULL;
@@ -883,8 +883,8 @@ do_switchconv (void)
{
if (dump_file)
{
- fprintf (dump_file, "Switch converted\n");
- fprintf (dump_file, "--------------------------------\n");
+ fputs ("Switch converted\n", dump_file);
+ fputs ("--------------------------------\n", dump_file);
}
}
else
@@ -892,9 +892,9 @@ do_switchconv (void)
if (dump_file)
{
gcc_assert (info.reason);
- fprintf (dump_file, "Bailing out - ");
- fprintf (dump_file, info.reason);
- fprintf (dump_file, "--------------------------------\n");
+ fputs ("Bailing out - ", dump_file);
+ fputs (info.reason, dump_file);
+ fputs ("--------------------------------\n", dump_file);
}
}
}
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index facde06969e..bc18f0272f8 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -3455,6 +3455,9 @@ vect_supportable_dr_alignment (struct data_reference *dr)
if (DR_IS_READ (dr))
{
+ bool is_packed = false;
+ tree type = (TREE_TYPE (DR_REF (dr)));
+
if (optab_handler (vec_realign_load_optab, mode)->insn_code !=
CODE_FOR_nothing
&& (!targetm.vectorize.builtin_mask_for_load
@@ -3468,18 +3471,39 @@ vect_supportable_dr_alignment (struct data_reference *dr)
else
return dr_explicit_realign_optimized;
}
-
- if (optab_handler (movmisalign_optab, mode)->insn_code !=
- CODE_FOR_nothing)
+ if (!known_alignment_for_access_p (dr))
+ {
+ tree ba = DR_BASE_OBJECT (dr);
+
+ if (ba)
+ is_packed = contains_packed_reference (ba);
+ }
+
+ if (targetm.vectorize.
+ builtin_support_vector_misalignment (mode, type,
+ DR_MISALIGNMENT (dr), is_packed))
/* Can't software pipeline the loads, but can at least do them. */
return dr_unaligned_supported;
}
- else
- {
- if (movmisalign_optab->handlers[mode].insn_code != CODE_FOR_nothing)
- return dr_unaligned_supported;
- }
+ else
+ {
+ bool is_packed = false;
+ tree type = (TREE_TYPE (DR_REF (dr)));
+ if (!known_alignment_for_access_p (dr))
+ {
+ tree ba = DR_BASE_OBJECT (dr);
+
+ if (ba)
+ is_packed = contains_packed_reference (ba);
+ }
+
+ if (targetm.vectorize.
+ builtin_support_vector_misalignment (mode, type,
+ DR_MISALIGNMENT (dr), is_packed))
+ return dr_unaligned_supported;
+ }
+
/* Unsupported. */
return dr_unaligned_unsupported;
}
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 0a2ab19a232..7e45123faff 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -145,6 +145,9 @@ vect_stmt_relevant_p (gimple stmt, loop_vec_info loop_vinfo,
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "vec_stmt_relevant_p: used out of loop.");
+ if (is_gimple_debug (USE_STMT (use_p)))
+ continue;
+
/* We expect all such uses to be in the loop exit phis
(because of loop closed form) */
gcc_assert (gimple_code (USE_STMT (use_p)) == GIMPLE_PHI);
diff --git a/gcc/tree.c b/gcc/tree.c
index 1db7d0a86c3..846dd983ea7 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1905,6 +1905,17 @@ purpose_member (const_tree elem, tree list)
return NULL_TREE;
}
+/* Returns element number IDX (zero-origin) of chain CHAIN, or
+ NULL_TREE. */
+
+tree
+chain_index (int idx, tree chain)
+{
+ for (; chain && idx > 0; --idx)
+ chain = TREE_CHAIN (chain);
+ return chain;
+}
+
/* Return nonzero if ELEM is part of the chain CHAIN. */
int
@@ -2003,18 +2014,6 @@ tree_last (tree chain)
return chain;
}
-/* Return the node in a chain of nodes whose value is x, NULL if not found. */
-
-tree
-tree_find_value (tree chain, tree x)
-{
- tree list;
- for (list = chain; list; list = TREE_CHAIN (list))
- if (TREE_VALUE (list) == x)
- return list;
- return NULL;
-}
-
/* Reverse the order of elements in the chain T,
and return the new head of the chain (old last element). */
@@ -4035,7 +4034,7 @@ iterative_hash_host_wide_int (HOST_WIDE_INT val, hashval_t val2)
Record such modified types already made so we don't make duplicates. */
-static tree
+tree
build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
{
if (! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute))
@@ -4250,16 +4249,6 @@ free_lang_data_in_type (tree type)
TYPE_CONTEXT (type) = NULL_TREE;
TYPE_STUB_DECL (type) = NULL_TREE;
-
- /* Remove type variants other than the main variant. This is both
- wasteful and it may introduce infinite loops when the types are
- read from disk and merged (since the variant will be the same
- type as the main variant, traversing type variants will get into
- an infinite loop). */
- if (TYPE_MAIN_VARIANT (type))
- TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (type)) = NULL_TREE;
-
- TYPE_NEXT_VARIANT (type) = NULL_TREE;
}
@@ -4469,6 +4458,9 @@ free_lang_data_in_decl (tree decl)
struct free_lang_data_d
{
+ /* Worklist to avoid excessive recursion. */
+ VEC(tree,heap) *worklist;
+
/* Set of traversed objects. Used to avoid duplicate visits. */
struct pointer_set_t *pset;
@@ -4530,6 +4522,9 @@ add_tree_to_fld_list (tree t, struct free_lang_data_d *fld)
gcc_unreachable ();
}
+#define PUSH(t) \
+ if (t && !pointer_set_contains (fld->pset, t)) \
+ VEC_safe_push (tree, heap, fld->worklist, (t))
/* Operand callback helper for free_lang_data_in_node. *TP is the
subtree operand being considered. */
@@ -4540,49 +4535,49 @@ find_decls_types_r (tree *tp, int *ws ATTRIBUTE_UNUSED, void *data)
tree t = *tp;
struct free_lang_data_d *fld = (struct free_lang_data_d *) data;
+ if (TREE_CODE (t) == TREE_LIST)
+ return NULL_TREE;
+
if (DECL_P (t))
{
/* Note that walk_tree does not traverse every possible field in
decls, so we have to do our own traversals here. */
add_tree_to_fld_list (t, fld);
- walk_tree (&DECL_NAME (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&DECL_CONTEXT (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&DECL_SIZE (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&DECL_SIZE_UNIT (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&DECL_INITIAL (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&DECL_ATTRIBUTES (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&DECL_ABSTRACT_ORIGIN (t), find_decls_types_r, fld, fld->pset);
+ PUSH (DECL_NAME (t));
+ PUSH (DECL_CONTEXT (t));
+ PUSH (DECL_SIZE (t));
+ PUSH (DECL_SIZE_UNIT (t));
+ PUSH (DECL_INITIAL(t));
+ PUSH (DECL_ATTRIBUTES (t));
+ PUSH (DECL_ABSTRACT_ORIGIN (t));
if (TREE_CODE (t) == FUNCTION_DECL)
{
- walk_tree (&DECL_ARGUMENTS (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&DECL_RESULT (t), find_decls_types_r, fld, fld->pset);
+ PUSH (DECL_ARGUMENTS (t));
+ PUSH (DECL_RESULT (t));
}
else if (TREE_CODE (t) == TYPE_DECL)
{
- walk_tree (&DECL_ARGUMENT_FLD (t), find_decls_types_r, fld,
- fld->pset);
- walk_tree (&DECL_VINDEX (t), find_decls_types_r, fld, fld->pset);
+ PUSH (DECL_ARGUMENT_FLD (t));
+ PUSH (DECL_VINDEX (t));
}
else if (TREE_CODE (t) == FIELD_DECL)
{
- walk_tree (&DECL_FIELD_OFFSET (t), find_decls_types_r, fld,
- fld->pset);
- walk_tree (&DECL_BIT_FIELD_TYPE (t), find_decls_types_r, fld,
- fld->pset);
- walk_tree (&DECL_QUALIFIER (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&DECL_FIELD_BIT_OFFSET (t), find_decls_types_r, fld,
- fld->pset);
- walk_tree (&DECL_FCONTEXT (t), find_decls_types_r, fld, fld->pset);
+ PUSH (DECL_FIELD_OFFSET (t));
+ PUSH (DECL_BIT_FIELD_TYPE (t));
+ PUSH (DECL_QUALIFIER (t));
+ PUSH (DECL_FIELD_BIT_OFFSET (t));
+ PUSH (DECL_FCONTEXT (t));
}
else if (TREE_CODE (t) == VAR_DECL)
{
- walk_tree (&DECL_SECTION_NAME (t), find_decls_types_r, fld,
- fld->pset);
- walk_tree (&DECL_COMDAT_GROUP (t), find_decls_types_r, fld,
- fld->pset);
+ PUSH (DECL_SECTION_NAME (t));
+ PUSH (DECL_COMDAT_GROUP (t));
}
+
+ PUSH (TREE_CHAIN (t));
+ *ws = 0;
}
else if (TYPE_P (t))
{
@@ -4590,36 +4585,55 @@ find_decls_types_r (tree *tp, int *ws ATTRIBUTE_UNUSED, void *data)
types, so we have to do our own traversals here. */
add_tree_to_fld_list (t, fld);
- walk_tree (&TYPE_CACHED_VALUES (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&TYPE_SIZE (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&TYPE_SIZE_UNIT (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&TYPE_ATTRIBUTES (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&TYPE_POINTER_TO (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&TYPE_REFERENCE_TO (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&TYPE_NAME (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&TYPE_MINVAL (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&TYPE_MAXVAL (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&TYPE_NEXT_VARIANT (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&TYPE_MAIN_VARIANT (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&TYPE_CONTEXT (t), find_decls_types_r, fld, fld->pset);
- walk_tree (&TYPE_CANONICAL (t), find_decls_types_r, fld, fld->pset);
- }
-
- if (TREE_TYPE (t))
- walk_tree (&TREE_TYPE (t), find_decls_types_r, fld, fld->pset);
+ PUSH (TYPE_CACHED_VALUES (t));
+ PUSH (TYPE_SIZE (t));
+ PUSH (TYPE_SIZE_UNIT (t));
+ PUSH (TYPE_ATTRIBUTES (t));
+ PUSH (TYPE_POINTER_TO (t));
+ PUSH (TYPE_REFERENCE_TO (t));
+ PUSH (TYPE_NAME (t));
+ PUSH (TYPE_MINVAL (t));
+ PUSH (TYPE_MAXVAL (t));
+ PUSH (TYPE_MAIN_VARIANT (t));
+ PUSH (TYPE_NEXT_VARIANT (t));
+ PUSH (TYPE_CONTEXT (t));
+ PUSH (TYPE_CANONICAL (t));
+
+ if (RECORD_OR_UNION_TYPE_P (t)
+ && TYPE_BINFO (t))
+ {
+ unsigned i;
+ tree tem;
+ for (i = 0; VEC_iterate (tree, BINFO_BASE_BINFOS (TYPE_BINFO (t)),
+ i, tem); ++i)
+ PUSH (TREE_TYPE (tem));
+ }
- /* Do not recurse into TREE_CHAIN to avoid blowing up the stack. */
- for (tp = &TREE_CHAIN (t); *tp; tp = &TREE_CHAIN (*tp))
- {
- tree saved_chain = TREE_CHAIN (*tp);
- TREE_CHAIN (*tp) = NULL_TREE;
- walk_tree (tp, find_decls_types_r, fld, fld->pset);
- TREE_CHAIN (*tp) = saved_chain;
+ PUSH (TREE_CHAIN (t));
+ *ws = 0;
}
+ PUSH (TREE_TYPE (t));
+
return NULL_TREE;
}
+#undef PUSH
+
+/* Find decls and types in T. */
+
+static void
+find_decls_types (tree t, struct free_lang_data_d *fld)
+{
+ while (1)
+ {
+ if (!pointer_set_contains (fld->pset, t))
+ walk_tree (&t, find_decls_types_r, fld, fld->pset);
+ if (VEC_empty (tree, fld->worklist))
+ break;
+ t = VEC_pop (tree, fld->worklist);
+ }
+}
/* Translate all the types in LIST with the corresponding runtime
types. */
@@ -4653,23 +4667,36 @@ get_eh_types_for_runtime (tree list)
static void
find_decls_types_in_eh_region (eh_region r, struct free_lang_data_d *fld)
{
- if (r == NULL)
- return;
-
- /* The types referenced in R must first be changed to the EH types
- used at runtime. This removes references to FE types in the
- region. */
- if (r->type == ERT_CATCH)
- {
- tree list = r->u.eh_catch.type_list;
- r->u.eh_catch.type_list = get_eh_types_for_runtime (list);
- walk_tree (&r->u.eh_catch.type_list, find_decls_types_r, fld, fld->pset);
- }
- else if (r->type == ERT_ALLOWED_EXCEPTIONS)
+ switch (r->type)
{
- tree list = r->u.allowed.type_list;
- r->u.allowed.type_list = get_eh_types_for_runtime (list);
+ case ERT_CLEANUP:
+ break;
+
+ case ERT_TRY:
+ {
+ eh_catch c;
+
+ /* The types referenced in each catch must first be changed to the
+ EH types used at runtime. This removes references to FE types
+ in the region. */
+ for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
+ {
+ c->type_list = get_eh_types_for_runtime (c->type_list);
+ walk_tree (&c->type_list, find_decls_types_r, fld, fld->pset);
+ }
+ }
+ break;
+
+ case ERT_ALLOWED_EXCEPTIONS:
+ r->u.allowed.type_list
+ = get_eh_types_for_runtime (r->u.allowed.type_list);
walk_tree (&r->u.allowed.type_list, find_decls_types_r, fld, fld->pset);
+ break;
+
+ case ERT_MUST_NOT_THROW:
+ walk_tree (&r->u.must_not_throw.failure_decl,
+ find_decls_types_r, fld, fld->pset);
+ break;
}
}
@@ -4687,7 +4714,7 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld)
struct function *fn;
tree t;
- walk_tree (&n->decl, find_decls_types_r, fld, fld->pset);
+ find_decls_types (n->decl, fld);
if (!gimple_has_body_p (n->decl))
return;
@@ -4698,23 +4725,14 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld)
/* Traverse locals. */
for (t = fn->local_decls; t; t = TREE_CHAIN (t))
- {
- tree *tp = &TREE_VALUE (t);
- tree saved_chain = TREE_CHAIN (*tp);
- TREE_CHAIN (*tp) = NULL_TREE;
- walk_tree (tp, find_decls_types_r, fld, fld->pset);
- TREE_CHAIN (*tp) = saved_chain;
- }
+ find_decls_types (TREE_VALUE (t), fld);
/* Traverse EH regions in FN. */
- if (fn->eh->region_array)
- {
- unsigned i;
- eh_region r;
-
- for (i = 0; VEC_iterate (eh_region, fn->eh->region_array, i, r); i++)
- find_decls_types_in_eh_region (r, fld);
- }
+ {
+ eh_region r;
+ FOR_ALL_EH_REGION_FN (r, fn)
+ find_decls_types_in_eh_region (r, fld);
+ }
/* Traverse every statement in FN. */
FOR_EACH_BB_FN (bb, fn)
@@ -4729,7 +4747,7 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld)
for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree *arg_p = gimple_phi_arg_def_ptr (phi, i);
- walk_tree (arg_p, find_decls_types_r, fld, fld->pset);
+ find_decls_types (*arg_p, fld);
}
}
@@ -4739,8 +4757,8 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld)
for (i = 0; i < gimple_num_ops (stmt); i++)
{
- tree *arg_p = gimple_op_ptr (stmt, i);
- walk_tree (arg_p, find_decls_types_r, fld, fld->pset);
+ tree arg = gimple_op (stmt, i);
+ find_decls_types (arg, fld);
}
}
}
@@ -4756,7 +4774,7 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld)
static void
find_decls_types_in_var (struct varpool_node *v, struct free_lang_data_d *fld)
{
- walk_tree (&v->decl, find_decls_types_r, fld, fld->pset);
+ find_decls_types (v->decl, fld);
}
@@ -4789,6 +4807,7 @@ free_lang_data_in_cgraph (void)
/* Initialize sets and arrays to store referenced decls and types. */
fld.pset = pointer_set_create ();
+ fld.worklist = NULL;
fld.decls = VEC_alloc (tree, heap, 100);
fld.types = VEC_alloc (tree, heap, 100);
@@ -4797,7 +4816,7 @@ free_lang_data_in_cgraph (void)
find_decls_types_in_node (n, &fld);
for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); i++)
- walk_tree (&p->decl, find_decls_types_r, &fld, fld.pset);
+ find_decls_types (p->decl, &fld);
/* Find decls and types in every varpool symbol. */
for (v = varpool_nodes_queue; v; v = v->next_needed)
@@ -4837,6 +4856,7 @@ free_lang_data_in_cgraph (void)
free_lang_data_in_type (t);
pointer_set_destroy (fld.pset);
+ VEC_free (tree, heap, fld.worklist);
VEC_free (tree, heap, fld.decls);
VEC_free (tree, heap, fld.types);
}
@@ -4868,6 +4888,12 @@ free_lang_data (void)
boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
}
+ /* Unify char_type_node with its properly signed variant. */
+ if (TYPE_UNSIGNED (char_type_node))
+ unsigned_char_type_node = char_type_node;
+ else
+ signed_char_type_node = char_type_node;
+
/* Reset some langhooks. */
lang_hooks.callgraph.analyze_expr = NULL;
lang_hooks.types_compatible_p = NULL;
@@ -4910,7 +4936,7 @@ struct simple_ipa_opt_pass pass_ipa_free_lang_data =
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- 0 /* todo_flags_finish */
+ TODO_ggc_collect /* todo_flags_finish */
}
};
@@ -6906,44 +6932,29 @@ build_array_type (tree elt_type, tree index_type)
t = make_node (ARRAY_TYPE);
TREE_TYPE (t) = elt_type;
TYPE_DOMAIN (t) = index_type;
-
- if (index_type == 0)
- {
- tree save = t;
- hashcode = iterative_hash_object (TYPE_HASH (elt_type), hashcode);
- t = type_hash_canon (hashcode, t);
- if (save == t)
- layout_type (t);
-
- if (TYPE_CANONICAL (t) == t)
- {
- if (TYPE_STRUCTURAL_EQUALITY_P (elt_type))
- SET_TYPE_STRUCTURAL_EQUALITY (t);
- else if (TYPE_CANONICAL (elt_type) != elt_type)
- TYPE_CANONICAL (t)
- = build_array_type (TYPE_CANONICAL (elt_type), index_type);
- }
+ layout_type (t);
- return t;
- }
+ /* If the element type is incomplete at this point we get marked for
+ structural equality. Do not record these types in the canonical
+ type hashtable. */
+ if (TYPE_STRUCTURAL_EQUALITY_P (t))
+ return t;
hashcode = iterative_hash_object (TYPE_HASH (elt_type), hashcode);
- hashcode = iterative_hash_object (TYPE_HASH (index_type), hashcode);
+ if (index_type)
+ hashcode = iterative_hash_object (TYPE_HASH (index_type), hashcode);
t = type_hash_canon (hashcode, t);
- if (!COMPLETE_TYPE_P (t))
- layout_type (t);
-
if (TYPE_CANONICAL (t) == t)
{
if (TYPE_STRUCTURAL_EQUALITY_P (elt_type)
- || TYPE_STRUCTURAL_EQUALITY_P (index_type))
+ || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type)))
SET_TYPE_STRUCTURAL_EQUALITY (t);
else if (TYPE_CANONICAL (elt_type) != elt_type
- || TYPE_CANONICAL (index_type) != index_type)
+ || (index_type && TYPE_CANONICAL (index_type) != index_type))
TYPE_CANONICAL (t)
= build_array_type (TYPE_CANONICAL (elt_type),
- TYPE_CANONICAL (index_type));
+ index_type ? TYPE_CANONICAL (index_type) : NULL);
}
return t;
@@ -8879,12 +8890,15 @@ local_define_builtin (const char *name, tree type, enum built_in_function code,
/* Call this function after instantiating all builtins that the language
front end cares about. This will build the rest of the builtins that
- are relied upon by the tree optimizers and the middle-end. */
+ are relied upon by the tree optimizers and the middle-end.
+
+ ENABLE_CXA_END_CLEANUP should be true for C++ and Java, where the ARM
+ EABI requires a slightly different implementation of _Unwind_Resume. */
void
-build_common_builtin_nodes (void)
+build_common_builtin_nodes (bool enable_cxa_end_cleanup)
{
- tree tmp, ftype;
+ tree tmp, tmp2, ftype;
if (built_in_decls[BUILT_IN_MEMCPY] == NULL
|| built_in_decls[BUILT_IN_MEMMOVE] == NULL)
@@ -8989,6 +9003,47 @@ build_common_builtin_nodes (void)
local_define_builtin ("__builtin_profile_func_exit", ftype,
BUILT_IN_PROFILE_FUNC_EXIT, "profile_func_exit", 0);
+ if (enable_cxa_end_cleanup && targetm.arm_eabi_unwinder)
+ {
+ ftype = build_function_type (void_type_node, void_list_node);
+ local_define_builtin ("__builtin_unwind_resume", ftype,
+ BUILT_IN_UNWIND_RESUME,
+ "__cxa_end_cleanup", ECF_NORETURN);
+ }
+ else
+ {
+ tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
+ ftype = build_function_type (void_type_node, tmp);
+ local_define_builtin ("__builtin_unwind_resume", ftype,
+ BUILT_IN_UNWIND_RESUME,
+ (USING_SJLJ_EXCEPTIONS
+ ? "_Unwind_SjLj_Resume" : "_Unwind_Resume"),
+ ECF_NORETURN);
+ }
+
+ /* The exception object and filter values from the runtime. The argument
+ must be zero before exception lowering, i.e. from the front end. After
+ exception lowering, it will be the region number for the exception
+ landing pad. These functions are PURE instead of CONST to prevent
+ them from being hoisted past the exception edge that will initialize
+ its value in the landing pad. */
+ tmp = tree_cons (NULL_TREE, integer_type_node, void_list_node);
+ ftype = build_function_type (ptr_type_node, tmp);
+ local_define_builtin ("__builtin_eh_pointer", ftype, BUILT_IN_EH_POINTER,
+ "__builtin_eh_pointer", ECF_PURE | ECF_NOTHROW);
+
+ tmp2 = lang_hooks.types.type_for_mode (targetm.eh_return_filter_mode (), 0);
+ ftype = build_function_type (tmp2, tmp);
+ local_define_builtin ("__builtin_eh_filter", ftype, BUILT_IN_EH_FILTER,
+ "__builtin_eh_filter", ECF_PURE | ECF_NOTHROW);
+
+ tmp = tree_cons (NULL_TREE, integer_type_node, void_list_node);
+ tmp = tree_cons (NULL_TREE, integer_type_node, tmp);
+ ftype = build_function_type (void_type_node, tmp);
+ local_define_builtin ("__builtin_eh_copy_values", ftype,
+ BUILT_IN_EH_COPY_VALUES,
+ "__builtin_eh_copy_values", ECF_NOTHROW);
+
/* Complex multiplication and division. These are handled as builtins
rather than optabs because emit_library_call_value doesn't support
complex. Further, we can do slightly better with folding these
@@ -9150,16 +9205,6 @@ build_opaque_vector_type (tree innertype, int nunits)
}
-/* Build RESX_EXPR with given REGION_NUMBER. */
-tree
-build_resx (int region_number)
-{
- tree t;
- t = build1 (RESX_EXPR, void_type_node,
- build_int_cst (NULL_TREE, region_number));
- return t;
-}
-
/* Given an initializer INIT, return TRUE if INIT is zero or some
aggregate of zeros. Otherwise return FALSE. */
bool
@@ -10565,5 +10610,20 @@ tree_strip_sign_nop_conversions (tree exp)
return exp;
}
+static GTY(()) tree gcc_eh_personality_decl;
+
+/* Return the GCC personality function decl. */
+
+tree
+lhd_gcc_personality (void)
+{
+ if (!gcc_eh_personality_decl)
+ gcc_eh_personality_decl
+ = build_personality_function (USING_SJLJ_EXCEPTIONS
+ ? "__gcc_personality_sj0"
+ : "__gcc_personality_v0");
+
+ return gcc_eh_personality_decl;
+}
#include "gt-tree.h"
diff --git a/gcc/tree.def b/gcc/tree.def
index e7be1d0abab..c1ba96aa966 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -440,12 +440,6 @@ DEFTREECODE (MISALIGNED_INDIRECT_REF, "misaligned_indirect_ref", tcc_reference,
identifier or a vtable index. */
DEFTREECODE (OBJ_TYPE_REF, "obj_type_ref", tcc_expression, 3)
-/* The exception object from the runtime. */
-DEFTREECODE (EXC_PTR_EXPR, "exc_ptr_expr", tcc_expression, 0)
-
-/* The filter object from the runtime. */
-DEFTREECODE (FILTER_EXPR, "filter_expr", tcc_expression, 0)
-
/* Constructor: return an aggregate value made from specified components.
In C, this is used only for structure and array initializers.
The operand is a sequence of component values made out of a VEC of
@@ -878,15 +872,12 @@ DEFTREECODE (SWITCH_EXPR, "switch_expr", tcc_statement, 3)
label. CASE_LABEL is the corresponding LABEL_DECL. */
DEFTREECODE (CASE_LABEL_EXPR, "case_label_expr", tcc_statement, 3)
-/* RESX. Resume execution after an exception. Operand 0 is a
- number indicating the exception region that is being left. */
-DEFTREECODE (RESX_EXPR, "resx_expr", tcc_statement, 1)
-
/* Used to represent an inline assembly statement. ASM_STRING returns a
STRING_CST for the instruction (e.g., "mov x, y"). ASM_OUTPUTS,
ASM_INPUTS, and ASM_CLOBBERS represent the outputs, inputs, and clobbers
- for the statement. */
-DEFTREECODE (ASM_EXPR, "asm_expr", tcc_statement, 4)
+ for the statement. ASM_LABELS, if present, indicates various destinations
+ for the asm; labels cannot be combined with outputs. */
+DEFTREECODE (ASM_EXPR, "asm_expr", tcc_statement, 5)
/* Variable references for SSA analysis. New SSA names are created every
time a variable is assigned a new value. The SSA builder uses SSA_NAME
diff --git a/gcc/tree.h b/gcc/tree.h
index 880f71d9f17..afb1d4260a0 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -444,9 +444,6 @@ struct GTY(()) tree_common {
ASM_INPUT_P in
ASM_EXPR
- EH_FILTER_MUST_NOT_THROW in
- EH_FILTER_EXPR
-
TYPE_REF_CAN_ALIAS_ALL in
POINTER_TYPE, REFERENCE_TYPE
@@ -1065,12 +1062,17 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
(SCALAR_FLOAT_TYPE_P (TYPE) \
&& DECIMAL_FLOAT_MODE_P (TYPE_MODE (TYPE)))
+/* Nonzero if TYPE is a record or union type. */
+#define RECORD_OR_UNION_TYPE_P(TYPE) \
+ (TREE_CODE (TYPE) == RECORD_TYPE \
+ || TREE_CODE (TYPE) == UNION_TYPE \
+ || TREE_CODE (TYPE) == QUAL_UNION_TYPE)
+
/* Nonzero if TYPE represents an aggregate (multi-component) type.
Keep these checks in ascending code order. */
#define AGGREGATE_TYPE_P(TYPE) \
- (TREE_CODE (TYPE) == ARRAY_TYPE || TREE_CODE (TYPE) == RECORD_TYPE \
- || TREE_CODE (TYPE) == UNION_TYPE || TREE_CODE (TYPE) == QUAL_UNION_TYPE)
+ (TREE_CODE (TYPE) == ARRAY_TYPE || RECORD_OR_UNION_TYPE_P (TYPE))
/* Nonzero if TYPE represents a pointer or reference type.
(It should be renamed to INDIRECT_TYPE_P.) Keep these checks in
@@ -1304,6 +1306,15 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
(TREE_CHECK3 (NODE, VAR_DECL, PARM_DECL, \
RESULT_DECL)->decl_common.decl_by_reference_flag)
+/* In a RESULT_DECL, PARM_DECL and VAR_DECL, means that this decl
+ can be used as restricted tag to disambiguate against other restrict
+ pointers. Used by fortran to capture something like non-addressability
+ (which it isn't really because the middle-end does take addresses of
+ such variables). */
+#define DECL_RESTRICTED_P(NODE) \
+ (TREE_CHECK3 (NODE, VAR_DECL, PARM_DECL, \
+ RESULT_DECL)->decl_common.decl_restricted_flag)
+
/* In a CALL_EXPR, means that the call is the jump from a thunk to the
thunked-to function. */
#define CALL_FROM_THUNK_P(NODE) (CALL_EXPR_CHECK (NODE)->base.protected_flag)
@@ -1624,6 +1635,7 @@ extern void protected_set_expr_location (tree, location_t);
#define ASM_OUTPUTS(NODE) TREE_OPERAND (ASM_EXPR_CHECK (NODE), 1)
#define ASM_INPUTS(NODE) TREE_OPERAND (ASM_EXPR_CHECK (NODE), 2)
#define ASM_CLOBBERS(NODE) TREE_OPERAND (ASM_EXPR_CHECK (NODE), 3)
+#define ASM_LABELS(NODE) TREE_OPERAND (ASM_EXPR_CHECK (NODE), 4)
/* Nonzero if we want to create an ASM_INPUT instead of an
ASM_OPERAND with no operands. */
#define ASM_INPUT_P(NODE) (ASM_EXPR_CHECK (NODE)->base.static_flag)
@@ -1654,8 +1666,6 @@ extern void protected_set_expr_location (tree, location_t);
/* EH_FILTER_EXPR accessors. */
#define EH_FILTER_TYPES(NODE) TREE_OPERAND (EH_FILTER_EXPR_CHECK (NODE), 0)
#define EH_FILTER_FAILURE(NODE) TREE_OPERAND (EH_FILTER_EXPR_CHECK (NODE), 1)
-#define EH_FILTER_MUST_NOT_THROW(NODE) \
- (EH_FILTER_EXPR_CHECK (NODE)->base.static_flag)
/* OBJ_TYPE_REF accessors. */
#define OBJ_TYPE_REF_EXPR(NODE) TREE_OPERAND (OBJ_TYPE_REF_CHECK (NODE), 0)
@@ -2533,8 +2543,12 @@ struct GTY(()) tree_decl_minimal {
#define DECL_DEBUG_EXPR_IS_FROM(NODE) \
(DECL_COMMON_CHECK (NODE)->decl_common.debug_expr_is_from)
+#define DECL_FUNCTION_PERSONALITY(NODE) \
+ (FUNCTION_DECL_CHECK (NODE)->function_decl.personality)
+
/* Nonzero for a given ..._DECL node means that the name of this node should
- be ignored for symbolic debug purposes. */
+ be ignored for symbolic debug purposes. Moreover, for a FUNCTION_DECL,
+ the body of the function should also be ignored. */
#define DECL_IGNORED_P(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.ignored_flag)
/* Nonzero for a given ..._DECL node means that this node represents an
@@ -2641,21 +2655,24 @@ struct GTY(()) tree_decl_common {
unsigned gimple_reg_flag : 1;
/* In VAR_DECL, PARM_DECL and RESULT_DECL, this is DECL_BY_REFERENCE. */
unsigned decl_by_reference_flag : 1;
+ /* In VAR_DECL, PARM_DECL and RESULT_DECL, this is DECL_RESTRICTED_P. */
+ unsigned decl_restricted_flag : 1;
/* Padding so that 'off_align' can be on a 32-bit boundary. */
- unsigned decl_common_unused : 4;
+ unsigned decl_common_unused : 3;
/* DECL_OFFSET_ALIGN, used only for FIELD_DECLs. */
unsigned int off_align : 8;
+ /* 24-bits unused. */
+
+ /* DECL_ALIGN. It should have the same size as TYPE_ALIGN. */
+ unsigned int align;
+
tree size_unit;
tree initial;
tree attributes;
tree abstract_origin;
- /* DECL_ALIGN. It should have the same size as TYPE_ALIGN. */
- unsigned int align;
-
- int label_decl_uid;
/* Points to a structure whose details depend on the language in use. */
struct lang_decl *lang_specific;
};
@@ -2778,21 +2795,28 @@ struct GTY(()) tree_field_decl {
tree qualifier;
tree bit_offset;
tree fcontext;
-
};
/* A numeric unique identifier for a LABEL_DECL. The UID allocation is
dense, unique within any one function, and may be used to index arrays.
If the value is -1, then no UID has been assigned. */
#define LABEL_DECL_UID(NODE) \
- (LABEL_DECL_CHECK (NODE)->decl_common.label_decl_uid)
+ (LABEL_DECL_CHECK (NODE)->label_decl.label_decl_uid)
+
+/* In a LABEL_DECL, the EH region number for which the label is the
+ post_landing_pad. */
+#define EH_LANDING_PAD_NR(NODE) \
+ (LABEL_DECL_CHECK (NODE)->label_decl.eh_landing_pad_nr)
/* In LABEL_DECL nodes, nonzero means that an error message about
jumping into such a binding contour has been printed for this label. */
-#define DECL_ERROR_ISSUED(NODE) (LABEL_DECL_CHECK (NODE)->decl_common.decl_flag_0)
+#define DECL_ERROR_ISSUED(NODE) \
+ (LABEL_DECL_CHECK (NODE)->decl_common.decl_flag_0)
struct GTY(()) tree_label_decl {
struct tree_decl_with_rtl common;
+ int label_decl_uid;
+ int eh_landing_pad_nr;
};
struct GTY(()) tree_result_decl {
@@ -3183,6 +3207,9 @@ struct GTY(()) tree_function_decl {
struct function *f;
+ /* The personality function. Used for stack unwinding. */
+ tree personality;
+
/* Function specific options that are used by this function. */
tree function_specific_target; /* target options */
tree function_specific_optimization; /* optimization options */
@@ -3900,13 +3927,13 @@ extern tree build_method_type_directly (tree, tree, tree);
extern tree build_method_type (tree, tree);
extern tree build_offset_type (tree, tree);
extern tree build_complex_type (tree);
-extern tree build_resx (int);
extern tree array_type_nelts (const_tree);
extern bool in_array_bounds_p (tree);
extern bool range_in_array_bounds_p (tree);
extern tree value_member (tree, tree);
extern tree purpose_member (const_tree, tree);
+extern tree chain_index (int, tree);
extern int attribute_list_equal (const_tree, const_tree);
extern int attribute_list_contained (const_tree, const_tree);
@@ -3970,6 +3997,7 @@ extern tree make_tree (tree, rtx);
extern tree build_type_attribute_variant (tree, tree);
extern tree build_decl_attribute_variant (tree, tree);
+extern tree build_type_attribute_qual_variant (tree, tree, int);
/* Structure describing an attribute and a function to handle it. */
struct attribute_spec
@@ -4278,10 +4306,6 @@ extern tree tree_cons_stat (tree, tree, tree MEM_STAT_DECL);
extern tree tree_last (tree);
-/* Return the node in a chain whose TREE_VALUE is x, NULL if not found. */
-
-extern tree tree_find_value (tree, tree);
-
/* Reverse the order of elements in a chain, and return the new head. */
extern tree nreverse (tree);
@@ -4648,6 +4672,7 @@ extern bool auto_var_in_fn_p (const_tree, const_tree);
extern tree build_low_bits_mask (tree, unsigned);
extern tree tree_strip_nop_conversions (tree);
extern tree tree_strip_sign_nop_conversions (tree);
+extern tree lhd_gcc_personality (void);
/* In cgraph.c */
extern void change_decl_assembler_name (tree, tree);
@@ -4925,7 +4950,7 @@ extern int real_minus_onep (const_tree);
extern void init_ttree (void);
extern void build_common_tree_nodes (bool, bool);
extern void build_common_tree_nodes_2 (int);
-extern void build_common_builtin_nodes (void);
+extern void build_common_builtin_nodes (bool);
extern tree build_nonstandard_integer_type (unsigned HOST_WIDE_INT, int);
extern tree build_range_type (tree, tree, tree);
extern bool subrange_type_for_debug_p (const_tree, tree *, tree *);
@@ -5075,7 +5100,7 @@ extern bool parse_output_constraint (const char **, int, int, int,
extern bool parse_input_constraint (const char **, int, int, int, int,
const char * const *, bool *, bool *);
extern void expand_asm_stmt (gimple);
-extern tree resolve_asm_operand_names (tree, tree, tree);
+extern tree resolve_asm_operand_names (tree, tree, tree, tree);
extern void expand_case (gimple);
extern void expand_decl (tree);
#ifdef HARD_CONST
@@ -5259,6 +5284,7 @@ extern unsigned HOST_WIDE_INT compute_builtin_object_size (tree, int);
/* In expr.c. */
extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree);
+extern tree build_personality_function (const char *);
/* In tree-inline.c. */
diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index 68a1a282b34..a86c21b7129 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -1431,7 +1431,7 @@ init_dwarf_reg_size_table (void)
__builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
}
-static void
+static void __attribute__((noinline))
uw_init_context_1 (struct _Unwind_Context *context,
void *outer_cfa, void *outer_ra)
{
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 9e168a40997..cee0a26b74e 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -1296,84 +1296,86 @@ check_ic_target (tree call_expr, struct cgraph_node *target)
*/
static gimple
-gimple_ic (gimple stmt, gimple call, struct cgraph_node *direct_call,
+gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
int prob, gcov_type count, gcov_type all)
{
- gimple stmt1, stmt2, stmt3;
+ gimple dcall_stmt, load_stmt, cond_stmt;
tree tmp1, tmpv, tmp;
- gimple bb1end, bb2end, bb3end;
- basic_block bb, bb2, bb3, bb4;
+ basic_block cond_bb, dcall_bb, icall_bb, join_bb;
tree optype = build_pointer_type (void_type_node);
- edge e12, e13, e23, e24, e34;
+ edge e_cd, e_ci, e_di, e_dj, e_ij;
gimple_stmt_iterator gsi;
- int region;
+ int lp_nr;
- bb = gimple_bb (stmt);
- gsi = gsi_for_stmt (stmt);
+ cond_bb = gimple_bb (icall_stmt);
+ gsi = gsi_for_stmt (icall_stmt);
tmpv = create_tmp_var (optype, "PROF");
tmp1 = create_tmp_var (optype, "PROF");
- stmt1 = gimple_build_assign (tmpv, unshare_expr (gimple_call_fn (call)));
+ tmp = unshare_expr (gimple_call_fn (icall_stmt));
+ load_stmt = gimple_build_assign (tmpv, tmp);
+ gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
tmp = fold_convert (optype, build_addr (direct_call->decl,
current_function_decl));
- stmt2 = gimple_build_assign (tmp1, tmp);
- stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
- gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
- gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
- gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
- bb1end = stmt3;
+ load_stmt = gimple_build_assign (tmp1, tmp);
+ gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
- stmt1 = gimple_copy (stmt);
- gimple_call_set_fndecl (stmt1, direct_call->decl);
- gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
- bb2end = stmt1;
- bb3end = stmt;
+ cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
+ gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
+
+ dcall_stmt = gimple_copy (icall_stmt);
+ gimple_call_set_fndecl (dcall_stmt, direct_call->decl);
+ gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT);
/* Fix CFG. */
- /* Edge e23 connects bb2 to bb3, etc. */
- e12 = split_block (bb, bb1end);
- bb2 = e12->dest;
- bb2->count = count;
- e23 = split_block (bb2, bb2end);
- bb3 = e23->dest;
- bb3->count = all - count;
- e34 = split_block (bb3, bb3end);
- bb4 = e34->dest;
- bb4->count = all;
+ /* Edge e_cd connects cond_bb to dcall_bb, etc; note the first letters. */
+ e_cd = split_block (cond_bb, cond_stmt);
+ dcall_bb = e_cd->dest;
+ dcall_bb->count = count;
- e12->flags &= ~EDGE_FALLTHRU;
- e12->flags |= EDGE_FALSE_VALUE;
- e12->probability = prob;
- e12->count = count;
+ e_di = split_block (dcall_bb, dcall_stmt);
+ icall_bb = e_di->dest;
+ icall_bb->count = all - count;
- e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
- e13->probability = REG_BR_PROB_BASE - prob;
- e13->count = all - count;
+ e_ij = split_block (icall_bb, icall_stmt);
+ join_bb = e_ij->dest;
+ join_bb->count = all;
- remove_edge (e23);
+ e_cd->flags = (e_cd->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
+ e_cd->probability = prob;
+ e_cd->count = count;
+
+ e_ci = make_edge (cond_bb, icall_bb, EDGE_FALSE_VALUE);
+ e_ci->probability = REG_BR_PROB_BASE - prob;
+ e_ci->count = all - count;
+
+ remove_edge (e_di);
- e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
- e24->probability = REG_BR_PROB_BASE;
- e24->count = count;
- e34->probability = REG_BR_PROB_BASE;
- e34->count = all - count;
+ e_dj = make_edge (dcall_bb, join_bb, EDGE_FALLTHRU);
+ e_dj->probability = REG_BR_PROB_BASE;
+ e_dj->count = count;
+
+ e_ij->probability = REG_BR_PROB_BASE;
+ e_ij->count = all - count;
/* Fix eh edges */
- region = lookup_stmt_eh_region (stmt);
- if (region >= 0 && stmt_could_throw_p (stmt1))
+ lp_nr = lookup_stmt_eh_lp (icall_stmt);
+ if (lp_nr != 0)
{
- add_stmt_to_eh_region (stmt1, region);
- make_eh_edges (stmt1);
- }
+ if (stmt_could_throw_p (dcall_stmt))
+ {
+ add_stmt_to_eh_lp (dcall_stmt, lp_nr);
+ make_eh_edges (dcall_stmt);
+ }
- if (region >= 0 && stmt_could_throw_p (stmt))
- {
- gimple_purge_dead_eh_edges (bb4);
- make_eh_edges (stmt);
+ gcc_assert (stmt_could_throw_p (icall_stmt));
+ make_eh_edges (icall_stmt);
+
+ gimple_purge_dead_eh_edges (join_bb);
}
- return stmt1;
+ return dcall_stmt;
}
/*
@@ -1418,7 +1420,7 @@ gimple_ic_transform_single_targ (gimple stmt, histogram_value histogram)
if (!check_ic_target (gimple_call_fn (stmt), direct_call))
return false;
- modify = gimple_ic (stmt, stmt, direct_call, prob, count, all);
+ modify = gimple_ic (stmt, direct_call, prob, count, all);
if (dump_file)
{
@@ -1524,7 +1526,7 @@ gimple_ic_transform_mult_targ (gimple stmt, histogram_value histogram)
EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val1), (unsigned) count1);
- modify1 = gimple_ic (stmt, stmt, direct_call1, prob1, count1, all);
+ modify1 = gimple_ic (stmt, direct_call1, prob1, count1, all);
inform (locus, "Promote indirect call to target %s",
lang_hooks.decl_printable_name (direct_call1->decl, 3));
if (always_inline && count1 >= always_inline)
@@ -1555,7 +1557,7 @@ gimple_ic_transform_mult_targ (gimple stmt, histogram_value histogram)
&& DECL_ARTIFICIAL (direct_call2->decl)
&& ! TREE_PUBLIC (direct_call2->decl)))
{
- modify2 = gimple_ic (stmt, stmt, direct_call2,
+ modify2 = gimple_ic (stmt, direct_call2,
prob2, count2, all - count1);
inform (locus, "Promote indirect call to target %s",
lang_hooks.decl_printable_name (direct_call2->decl, 3));
@@ -1643,89 +1645,79 @@ interesting_stringop_to_profile_p (tree fndecl, gimple call)
}
}
-/* Convert stringop (..., size)
+/* Convert stringop (..., vcall_size)
into
- if (size == VALUE)
- stringop (...., VALUE);
+ if (vcall_size == icall_size)
+ stringop (..., icall_size);
else
- stringop (...., size);
- assuming constant propagation of VALUE will happen later.
-*/
+ stringop (..., vcall_size);
+ assuming we'll propagate a true constant into ICALL_SIZE later. */
+
static void
-gimple_stringop_fixed_value (gimple stmt, tree value, int prob, gcov_type count,
- gcov_type all)
+gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
+ gcov_type count, gcov_type all)
{
- gimple stmt1, stmt2, stmt3;
- tree tmp1, tmpv;
- gimple bb1end, bb2end;
- basic_block bb, bb2, bb3, bb4;
- edge e12, e13, e23, e24, e34;
+ gimple tmp_stmt, cond_stmt, icall_stmt;
+ tree tmp1, tmpv, vcall_size, optype;
+ basic_block cond_bb, icall_bb, vcall_bb, join_bb;
+ edge e_ci, e_cv, e_iv, e_ij, e_vj;
gimple_stmt_iterator gsi;
- tree blck_size = gimple_call_arg (stmt, 2);
- tree optype = TREE_TYPE (blck_size);
- int region;
- bb = gimple_bb (stmt);
- gsi = gsi_for_stmt (stmt);
+ cond_bb = gimple_bb (vcall_stmt);
+ gsi = gsi_for_stmt (vcall_stmt);
- if (gsi_end_p (gsi))
- {
- edge_iterator ei;
- for (ei = ei_start (bb->succs); (e34 = ei_safe_edge (ei)); )
- if (!(e34->flags & EDGE_ABNORMAL))
- break;
- }
- else
- {
- e34 = split_block (bb, stmt);
- gsi = gsi_for_stmt (stmt);
- }
- bb4 = e34->dest;
+ vcall_size = gimple_call_arg (vcall_stmt, 2);
+ optype = TREE_TYPE (vcall_size);
tmpv = create_tmp_var (optype, "PROF");
tmp1 = create_tmp_var (optype, "PROF");
- stmt1 = gimple_build_assign (tmpv, fold_convert (optype, value));
- stmt2 = gimple_build_assign (tmp1, blck_size);
- stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
- gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
- gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
- gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
- bb1end = stmt3;
+ tmp_stmt = gimple_build_assign (tmpv, fold_convert (optype, icall_size));
+ gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
- stmt1 = gimple_copy (stmt);
- gimple_call_set_arg (stmt1, 2, value);
- gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
- region = lookup_stmt_eh_region (stmt);
- if (region >= 0)
- add_stmt_to_eh_region (stmt1, region);
- bb2end = stmt1;
+ tmp_stmt = gimple_build_assign (tmp1, vcall_size);
+ gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
+
+ cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
+ gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
+
+ icall_stmt = gimple_copy (vcall_stmt);
+ gimple_call_set_arg (icall_stmt, 2, icall_size);
+ gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT);
/* Fix CFG. */
- /* Edge e23 connects bb2 to bb3, etc. */
- e12 = split_block (bb, bb1end);
- bb2 = e12->dest;
- bb2->count = count;
- e23 = split_block (bb2, bb2end);
- bb3 = e23->dest;
- bb3->count = all - count;
+ /* Edge e_ci connects cond_bb to icall_bb, etc. */
+ e_ci = split_block (cond_bb, cond_stmt);
+ icall_bb = e_ci->dest;
+ icall_bb->count = count;
- e12->flags &= ~EDGE_FALLTHRU;
- e12->flags |= EDGE_FALSE_VALUE;
- e12->probability = prob;
- e12->count = count;
+ e_iv = split_block (icall_bb, icall_stmt);
+ vcall_bb = e_iv->dest;
+ vcall_bb->count = all - count;
- e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
- e13->probability = REG_BR_PROB_BASE - prob;
- e13->count = all - count;
+ e_vj = split_block (vcall_bb, vcall_stmt);
+ join_bb = e_vj->dest;
+ join_bb->count = all;
- remove_edge (e23);
+ e_ci->flags = (e_ci->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
+ e_ci->probability = prob;
+ e_ci->count = count;
+
+ e_cv = make_edge (cond_bb, vcall_bb, EDGE_FALSE_VALUE);
+ e_cv->probability = REG_BR_PROB_BASE - prob;
+ e_cv->count = all - count;
+
+ remove_edge (e_iv);
- e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
- e24->probability = REG_BR_PROB_BASE;
- e24->count = count;
+ e_ij = make_edge (icall_bb, join_bb, EDGE_FALLTHRU);
+ e_ij->probability = REG_BR_PROB_BASE;
+ e_ij->count = count;
- e34->probability = REG_BR_PROB_BASE;
- e34->count = all - count;
+ e_vj->probability = REG_BR_PROB_BASE;
+ e_vj->count = all - count;
+
+ /* Because these are all string op builtins, they're all nothrow. */
+ gcc_assert (!stmt_could_throw_p (vcall_stmt));
+ gcc_assert (!stmt_could_throw_p (icall_stmt));
}
/* Find values inside STMT for that we want to measure histograms for
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 4d30324569b..0e665b91bed 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -723,12 +723,24 @@ static inline bool
dv_is_decl_p (decl_or_value dv)
{
if (!dv)
- return false;
+ return true;
- if (GET_CODE ((rtx)dv) == VALUE)
- return false;
+ /* Make sure relevant codes don't overlap. */
+ switch ((int)TREE_CODE ((tree)dv))
+ {
+ case (int)VAR_DECL:
+ case (int)PARM_DECL:
+ case (int)RESULT_DECL:
+ case (int)FUNCTION_DECL:
+ case (int)COMPONENT_REF:
+ return true;
- return true;
+ case (int)VALUE:
+ return false;
+
+ default:
+ gcc_unreachable ();
+ }
}
/* Return true if a decl_or_value is a VALUE rtl. */
@@ -790,21 +802,13 @@ dv_pool (decl_or_value dv)
return dv_onepart_p (dv) ? valvar_pool : var_pool;
}
-#define IS_DECL_CODE(C) ((C) == VAR_DECL || (C) == PARM_DECL \
- || (C) == RESULT_DECL || (C) == COMPONENT_REF)
-
-/* Check that VALUE won't ever look like a DECL. */
-static char check_value_is_not_decl [(!IS_DECL_CODE ((enum tree_code)VALUE))
- ? 1 : -1] ATTRIBUTE_UNUSED;
-
-
/* Build a decl_or_value out of a decl. */
static inline decl_or_value
dv_from_decl (tree decl)
{
decl_or_value dv;
- gcc_assert (!decl || IS_DECL_CODE (TREE_CODE (decl)));
dv = decl;
+ gcc_assert (dv_is_decl_p (dv));
return dv;
}
@@ -813,8 +817,8 @@ static inline decl_or_value
dv_from_value (rtx value)
{
decl_or_value dv;
- gcc_assert (value);
dv = value;
+ gcc_assert (dv_is_value_p (dv));
return dv;
}
@@ -6239,7 +6243,8 @@ check_wrap_constant (enum machine_mode mode, rtx result)
}
/* Callback for cselib_expand_value, that looks for expressions
- holding the value in the var-tracking hash tables. */
+ holding the value in the var-tracking hash tables. Return X for
+ standard processing, anything else is to be used as-is. */
static rtx
vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data)
@@ -6250,19 +6255,46 @@ vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data)
location_chain loc;
rtx result;
- gcc_assert (GET_CODE (x) == VALUE);
+ if (GET_CODE (x) == SUBREG)
+ {
+ rtx subreg = SUBREG_REG (x);
+
+ if (GET_CODE (SUBREG_REG (x)) != VALUE)
+ return x;
+
+ subreg = cselib_expand_value_rtx_cb (SUBREG_REG (x), regs,
+ max_depth - 1,
+ vt_expand_loc_callback, data);
+
+ if (!subreg)
+ return NULL;
+
+ result = simplify_gen_subreg (GET_MODE (x), subreg,
+ GET_MODE (SUBREG_REG (x)),
+ SUBREG_BYTE (x));
+
+ /* Invalid SUBREGs are ok in debug info. ??? We could try
+ alternate expansions for the VALUE as well. */
+ if (!result && (REG_P (subreg) || MEM_P (subreg)))
+ result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x));
+
+ return result;
+ }
+
+ if (GET_CODE (x) != VALUE)
+ return x;
if (VALUE_RECURSED_INTO (x))
- return NULL;
+ return x;
dv = dv_from_value (x);
var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
if (!var)
- return NULL;
+ return x;
if (var->n_var_parts == 0)
- return NULL;
+ return x;
gcc_assert (var->n_var_parts == 1);
@@ -6279,7 +6311,10 @@ vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data)
}
VALUE_RECURSED_INTO (x) = false;
- return result;
+ if (result)
+ return result;
+ else
+ return x;
}
/* Expand VALUEs in LOC, using VARS as well as cselib's equivalence
diff --git a/gcc/varasm.c b/gcc/varasm.c
index b9802aa996f..21c453e8d4d 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1756,7 +1756,8 @@ assemble_start_function (tree decl, const char *fnname)
ASM_OUTPUT_FUNCTION_PREFIX (asm_out_file, fnname);
#endif
- (*debug_hooks->begin_function) (decl);
+ if (!DECL_IGNORED_P (decl))
+ (*debug_hooks->begin_function) (decl);
/* Make function name accessible from other files, if appropriate. */
@@ -2342,11 +2343,11 @@ assemble_external (tree decl ATTRIBUTE_UNUSED)
for declarations that can be weak, it happens to be
match. */
&& !TREE_STATIC (decl)
- && tree_find_value (weak_decls, decl) == NULL_TREE)
- weak_decls = tree_cons (NULL, decl, weak_decls);
+ && value_member (decl, weak_decls) == NULL_TREE)
+ weak_decls = tree_cons (NULL, decl, weak_decls);
#ifdef ASM_OUTPUT_EXTERNAL
- if (tree_find_value (pending_assemble_externals, decl) == NULL_TREE)
+ if (value_member (decl, pending_assemble_externals) == NULL_TREE)
pending_assemble_externals = tree_cons (NULL, decl,
pending_assemble_externals);
#endif
@@ -5409,13 +5410,7 @@ find_decl_and_mark_needed (tree decl, tree target)
if (fnode)
{
- /* We can't mark function nodes as used after cgraph global info
- is finished. This wouldn't generally be necessary, but C++
- virtual table thunks are introduced late in the game and
- might seem like they need marking, although in fact they
- don't. */
- if (! cgraph_global_info_ready)
- cgraph_mark_needed_node (fnode);
+ cgraph_mark_needed_node (fnode);
return fnode->decl;
}
else if (vnode)
@@ -5585,7 +5580,7 @@ finish_aliases_1 (void)
to bind locally. Of course this is a hack - to keep it
working do the following (which is not strictly correct). */
&& (! TREE_CODE (target_decl) == FUNCTION_DECL
- || ! TREE_STATIC (target_decl))
+ || ! DECL_VIRTUAL_P (target_decl))
&& ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
{
/* In lightweight IPO, find the merged decl and check that
diff --git a/gcc/vecprim.h b/gcc/vecprim.h
index c546a2bff9b..e9ccc52bcb0 100644
--- a/gcc/vecprim.h
+++ b/gcc/vecprim.h
@@ -23,6 +23,11 @@ along with GCC; see the file COPYING3. If not see
DEF_VEC_I(char);
DEF_VEC_ALLOC_I(char,heap);
+typedef unsigned char uchar;
+DEF_VEC_I(uchar);
+DEF_VEC_ALLOC_I(uchar,heap);
+DEF_VEC_ALLOC_I(uchar,gc);
+
DEF_VEC_I(int);
DEF_VEC_ALLOC_I(int,heap);
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 1b020ac0ab8..5d278223113 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,13 @@
+2009-09-13 Kai Tietz <kai.tietz@onevision.com>
+
+ * configure.ac: Set for i?86-w64-mingw*
+ need_64bit_hwint to yes.
+ * configure: Regenerated.
+
+2009-09-10 Jason Merrill <jason@redhat.com>
+
+ * directives.c (cpp_define): constify.
+
2009-09-02 Ian Lance Taylor <iant@google.com>
* macro.c (stringify_arg): Escape CPP_WCHAR tokens.
diff --git a/libcpp/configure b/libcpp/configure
index 80249e76925..eaf99dd28d6 100755
--- a/libcpp/configure
+++ b/libcpp/configure
@@ -6876,6 +6876,7 @@ case $target in
hppa*64*-*-* | \
i[34567]86-*-darwin* | \
i[34567]86-*-solaris2.1[0-9]* | \
+ i[34567]86-w64-mingw* | \
mips*-*-* | \
mmix-*-* | \
powerpc*-*-* | \
diff --git a/libcpp/configure.ac b/libcpp/configure.ac
index 3af4e166e71..52465462165 100644
--- a/libcpp/configure.ac
+++ b/libcpp/configure.ac
@@ -146,6 +146,7 @@ case $target in
hppa*64*-*-* | \
i[34567]86-*-darwin* | \
i[34567]86-*-solaris2.1[0-9]* | \
+ i[34567]86-w64-mingw* | \
mips*-*-* | \
mmix-*-* | \
powerpc*-*-* | \
diff --git a/libcpp/directives.c b/libcpp/directives.c
index 9c988dfa136..c5a1895b86e 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -2156,7 +2156,8 @@ do_unassert (cpp_reader *pfile)
void
cpp_define (cpp_reader *pfile, const char *str)
{
- char *buf, *p;
+ char *buf;
+ const char *p;
size_t count;
/* Copy the entire option so we can modify it.
diff --git a/libcpp/po/ChangeLog b/libcpp/po/ChangeLog
index 03e5017bd02..179a1c6d523 100644
--- a/libcpp/po/ChangeLog
+++ b/libcpp/po/ChangeLog
@@ -1,3 +1,7 @@
+2009-09-08 Joseph Myers <joseph@codesourcery.com>
+
+ * id.po: Update.
+
2009-09-02 Joseph Myers <joseph@codesourcery.com>
* es.po: Update.
diff --git a/libcpp/po/id.po b/libcpp/po/id.po
index da4c89cb9d3..ba92679d03b 100644
--- a/libcpp/po/id.po
+++ b/libcpp/po/id.po
@@ -1,14 +1,14 @@
# Pesan bahasa indonesia untuk cpplib
# Copyright (C) 2008 Free Software Foundation, Inc.
# This file is distributed under the same license as the gcc package.
-# Arif E. Nugroho <arif_endro@yahoo.com>, 2008.
+# Arif E. Nugroho <arif_endro@yahoo.com>, 2008, 2009.
#
msgid ""
msgstr ""
-"Project-Id-Version: cpplib 4.4-b20081121\n"
+"Project-Id-Version: cpplib 4.4.1\n"
"Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n"
"POT-Creation-Date: 2009-04-22 16:32+0000\n"
-"PO-Revision-Date: 2008-11-26 07:30+0700\n"
+"PO-Revision-Date: 2009-09-08 18:00+0700\n"
"Last-Translator: Arif E. Nugroho <arif_endro@yahoo.com>\n"
"Language-Team: Indonesian <translation-team-id@lists.sourceforge.net>\n"
"MIME-Version: 1.0\n"
@@ -900,9 +900,9 @@ msgid "while writing precompiled header"
msgstr "ketika menulis precompiled header"
#: pch.c:484
-#, fuzzy, c-format
+#, c-format
msgid "%s: not used because `%.*s' is poisoned"
-msgstr "%s: tidak digunakan karena `%s' didefinisikan"
+msgstr "%s: tidak digunakan karena `%.*s' teracuni"
#: pch.c:506
#, c-format
diff --git a/libdecnumber/ChangeLog b/libdecnumber/ChangeLog
index 52415c8727e..b64e561a0cc 100644
--- a/libdecnumber/ChangeLog
+++ b/libdecnumber/ChangeLog
@@ -1,3 +1,11 @@
+2009-09-09 Paolo Bonzini <bonzini@gnu.org>
+
+ * configure: Regenerate.
+
+2009-09-08 Paolo Bonzini <bonzini@gnu.org>
+
+ * configure: Regenerate.
+
2009-08-24 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* configure.ac (AC_PREREQ): Bump to 2.64.
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index a8b922876a8..684a0e88fce 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,3 +1,23 @@
+2009-09-15 David Daney <ddaney@caviumnetworks.com>
+
+ * src/java_raw_api.c (ffi_java_raw_to_rvalue): Remove special
+ handling for FFI_TYPE_POINTER.
+ * src/mips/ffitarget.h (FFI_TYPE_STRUCT_D_SOFT,
+ FFI_TYPE_STRUCT_F_SOFT, FFI_TYPE_STRUCT_DD_SOFT,
+ FFI_TYPE_STRUCT_FF_SOFT, FFI_TYPE_STRUCT_FD_SOFT,
+ FFI_TYPE_STRUCT_DF_SOFT, FFI_TYPE_STRUCT_SOFT): New defines.
+ (FFI_N32_SOFT_FLOAT, FFI_N64_SOFT_FLOAT): New ffi_abi enumerations.
+ (enum ffi_abi): Set FFI_DEFAULT_ABI for soft-float.
+ * src/mips/n32.S (ffi_call_N32): Add handling for soft-float
+ structure and pointer returns.
+ (ffi_closure_N32): Add handling for pointer returns.
+ * src/mips/ffi.c (ffi_prep_args, calc_n32_struct_flags,
+ calc_n32_return_struct_flags): Handle soft-float.
+ (ffi_prep_cif_machdep): Handle soft-float, fix pointer handling.
+ (ffi_call_N32): Declare proper argument types.
+ (ffi_call, copy_struct_N32, ffi_closure_mips_inner_N32): Handle
+ soft-float.
+
2009-08-24 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* configure.ac (AC_PREREQ): Bump to 2.64.
diff --git a/libffi/src/java_raw_api.c b/libffi/src/java_raw_api.c
index 1f8f9833186..9c5383e6d5a 100644
--- a/libffi/src/java_raw_api.c
+++ b/libffi/src/java_raw_api.c
@@ -276,9 +276,6 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
case FFI_TYPE_SINT16:
case FFI_TYPE_SINT32:
case FFI_TYPE_INT:
-#if FFI_SIZEOF_JAVA_RAW == 4
- case FFI_TYPE_POINTER:
-#endif
*(SINT64 *)rvalue >>= 32;
break;
diff --git a/libffi/src/mips/ffi.c b/libffi/src/mips/ffi.c
index b6887be839b..3143dcfc653 100644
--- a/libffi/src/mips/ffi.c
+++ b/libffi/src/mips/ffi.c
@@ -99,7 +99,7 @@ static void ffi_prep_args(char *stack,
p_argv = ecif->avalue;
- for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
+ for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; i++, p_arg++)
{
size_t z;
unsigned int a;
@@ -123,9 +123,25 @@ static void ffi_prep_args(char *stack,
/* The size of a pointer depends on the ABI */
if (type == FFI_TYPE_POINTER)
- type =
- (ecif->cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
+ type = (ecif->cif->abi == FFI_N64
+ || ecif->cif->abi == FFI_N64_SOFT_FLOAT)
+ ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
+ if (i < 8 && (ecif->cif->abi == FFI_N32_SOFT_FLOAT
+ || ecif->cif->abi == FFI_N64_SOFT_FLOAT))
+ {
+ switch (type)
+ {
+ case FFI_TYPE_FLOAT:
+ type = FFI_TYPE_UINT32;
+ break;
+ case FFI_TYPE_DOUBLE:
+ type = FFI_TYPE_UINT64;
+ break;
+ default:
+ break;
+ }
+ }
switch (type)
{
case FFI_TYPE_SINT8:
@@ -205,13 +221,17 @@ static void ffi_prep_args(char *stack,
definitions and generates the appropriate flags. */
static unsigned
-calc_n32_struct_flags(ffi_type *arg, unsigned *loc, unsigned *arg_reg)
+calc_n32_struct_flags(int soft_float, ffi_type *arg,
+ unsigned *loc, unsigned *arg_reg)
{
unsigned flags = 0;
unsigned index = 0;
ffi_type *e;
+ if (soft_float)
+ return 0;
+
while ((e = arg->elements[index]))
{
/* Align this object. */
@@ -236,7 +256,7 @@ calc_n32_struct_flags(ffi_type *arg, unsigned *loc, unsigned *arg_reg)
}
static unsigned
-calc_n32_return_struct_flags(ffi_type *arg)
+calc_n32_return_struct_flags(int soft_float, ffi_type *arg)
{
unsigned flags = 0;
unsigned small = FFI_TYPE_SMALLSTRUCT;
@@ -256,6 +276,7 @@ calc_n32_return_struct_flags(ffi_type *arg)
small = FFI_TYPE_SMALLSTRUCT2;
e = arg->elements[0];
+
if (e->type == FFI_TYPE_DOUBLE)
flags = FFI_TYPE_DOUBLE;
else if (e->type == FFI_TYPE_FLOAT)
@@ -276,6 +297,8 @@ calc_n32_return_struct_flags(ffi_type *arg)
floats! This must be passed the old way. */
return small;
}
+ if (soft_float)
+ flags += FFI_TYPE_STRUCT_SOFT;
}
else
if (!flags)
@@ -382,16 +405,19 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
#ifdef FFI_MIPS_N32
/* Set the flags necessary for N32 processing */
{
+ int type;
unsigned arg_reg = 0;
unsigned loc = 0;
unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
unsigned index = 0;
unsigned struct_flags = 0;
+ int soft_float = (cif->abi == FFI_N32_SOFT_FLOAT
+ || cif->abi == FFI_N64_SOFT_FLOAT);
if (cif->rtype->type == FFI_TYPE_STRUCT)
{
- struct_flags = calc_n32_return_struct_flags(cif->rtype);
+ struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype);
if (struct_flags == 0)
{
@@ -411,7 +437,22 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
while (count-- > 0 && arg_reg < 8)
{
- switch ((cif->arg_types)[index]->type)
+ type = (cif->arg_types)[index]->type;
+ if (soft_float)
+ {
+ switch (type)
+ {
+ case FFI_TYPE_FLOAT:
+ type = FFI_TYPE_UINT32;
+ break;
+ case FFI_TYPE_DOUBLE:
+ type = FFI_TYPE_UINT64;
+ break;
+ default:
+ break;
+ }
+ }
+ switch (type)
{
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
@@ -423,17 +464,25 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
/* Align it. */
arg_reg = ALIGN(arg_reg, 2);
/* Treat it as two adjacent doubles. */
- cif->flags +=
- (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
- arg_reg++;
- cif->flags +=
- (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
- arg_reg++;
+ if (soft_float)
+ {
+ arg_reg += 2;
+ }
+ else
+ {
+ cif->flags +=
+ (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
+ arg_reg++;
+ cif->flags +=
+ (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
+ arg_reg++;
+ }
break;
case FFI_TYPE_STRUCT:
loc = arg_reg * FFI_SIZEOF_ARG;
- cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
+ cif->flags += calc_n32_struct_flags(soft_float,
+ (cif->arg_types)[index],
&loc, &arg_reg);
break;
@@ -469,17 +518,43 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
case FFI_TYPE_VOID:
/* Do nothing, 'cause FFI_TYPE_VOID is 0 */
break;
-
+
+ case FFI_TYPE_POINTER:
+ if (cif->abi == FFI_N32_SOFT_FLOAT || cif->abi == FFI_N32)
+ cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
+ else
+ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
+ break;
+
case FFI_TYPE_FLOAT:
+ if (soft_float)
+ {
+ cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
+ break;
+ }
+ /* else fall through */
case FFI_TYPE_DOUBLE:
- cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
+ if (soft_float)
+ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
+ else
+ cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
break;
+
case FFI_TYPE_LONGDOUBLE:
/* Long double is returned as if it were a struct containing
two doubles. */
- cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
- cif->flags += (FFI_TYPE_DOUBLE + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))
- << (4 + (FFI_FLAG_BITS * 8));
+ if (soft_float)
+ {
+ cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
+ cif->flags += FFI_TYPE_SMALLSTRUCT2 << (4 + (FFI_FLAG_BITS * 8));
+ }
+ else
+ {
+ cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
+ cif->flags += (FFI_TYPE_DOUBLE
+ + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))
+ << (4 + (FFI_FLAG_BITS * 8));
+ }
break;
default:
cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
@@ -499,7 +574,7 @@ extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
/* Low level routine for calling N32 functions */
extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
extended_cif *, unsigned,
- unsigned, unsigned *, void (*)(void));
+ unsigned, void *, void (*)(void));
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
@@ -529,10 +604,13 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
#ifdef FFI_MIPS_N32
case FFI_N32:
+ case FFI_N32_SOFT_FLOAT:
case FFI_N64:
+ case FFI_N64_SOFT_FLOAT:
{
int copy_rvalue = 0;
- void *rvalue_copy = ecif.rvalue;
+ int copy_offset = 0;
+ char *rvalue_copy = ecif.rvalue;
if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
{
/* For structures smaller than 16 bytes we clobber memory
@@ -541,10 +619,20 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
rvalue_copy = alloca(16);
copy_rvalue = 1;
}
+ else if (cif->rtype->type == FFI_TYPE_FLOAT
+ && (cif->abi == FFI_N64_SOFT_FLOAT
+ || cif->abi == FFI_N32_SOFT_FLOAT))
+ {
+ rvalue_copy = alloca (8);
+ copy_rvalue = 1;
+#ifdef __MIPSEB__
+ copy_offset = 4;
+#endif
+ }
ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
cif->flags, rvalue_copy, fn);
if (copy_rvalue)
- memcpy(ecif.rvalue, rvalue_copy, cif->rtype->size);
+ memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size);
}
break;
#endif
@@ -755,7 +843,7 @@ ffi_closure_mips_inner_O32 (ffi_closure *closure,
static void
copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
int argn, unsigned arg_offset, ffi_arg *ar,
- ffi_arg *fpr)
+ ffi_arg *fpr, int soft_float)
{
ffi_type **elt_typep = type->elements;
while(*elt_typep)
@@ -777,7 +865,7 @@ copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
tp = target + offset;
- if (elt_type->type == FFI_TYPE_DOUBLE)
+ if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float)
*(double *)tp = *(double *)fpp;
else
memcpy(tp, argp + arg_offset, elt_type->size);
@@ -815,8 +903,12 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
ffi_arg *avalue;
ffi_type **arg_types;
int i, avn, argn;
+ int soft_float;
+ ffi_arg *argp;
cif = closure->cif;
+ soft_float = cif->abi == FFI_N64_SOFT_FLOAT
+ || cif->abi == FFI_N32_SOFT_FLOAT;
avalue = alloca (cif->nargs * sizeof (ffi_arg));
avaluep = alloca (cif->nargs * sizeof (ffi_arg));
@@ -839,9 +931,9 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
while (i < avn)
{
if (arg_types[i]->type == FFI_TYPE_FLOAT
- || arg_types[i]->type == FFI_TYPE_DOUBLE)
+ || arg_types[i]->type == FFI_TYPE_DOUBLE)
{
- ffi_arg *argp = argn >= 8 ? ar + argn : fpr + argn;
+ argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn;
#ifdef __MIPSEB__
if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
avaluep[i] = ((char *) argp) + sizeof (float);
@@ -856,11 +948,15 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
if (arg_types[i]->alignment > sizeof(ffi_arg))
argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
- ffi_arg *argp = ar + argn;
+ argp = ar + argn;
/* The size of a pointer depends on the ABI */
if (type == FFI_TYPE_POINTER)
- type = (cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
+ type = (cif->abi == FFI_N64 || cif->abi == FFI_N64_SOFT_FLOAT)
+ ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
+
+ if (soft_float && type == FFI_TYPE_FLOAT)
+ type = FFI_TYPE_UINT32;
switch (type)
{
@@ -901,7 +997,7 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
it was passed in registers. */
avaluep[i] = alloca(arg_types[i]->size);
copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
- argn, 0, ar, fpr);
+ argn, 0, ar, fpr, soft_float);
break;
}
diff --git a/libffi/src/mips/ffitarget.h b/libffi/src/mips/ffitarget.h
index 214afe46560..dd3fe739c22 100644
--- a/libffi/src/mips/ffitarget.h
+++ b/libffi/src/mips/ffitarget.h
@@ -95,6 +95,15 @@
#define FFI_TYPE_STRUCT_DF 189
#define FFI_TYPE_STRUCT_SMALL 93
#define FFI_TYPE_STRUCT_SMALL2 109
+
+/* and for n32 soft float, add 16 * 2^4 */
+#define FFI_TYPE_STRUCT_D_SOFT 317
+#define FFI_TYPE_STRUCT_F_SOFT 301
+#define FFI_TYPE_STRUCT_DD_SOFT 509
+#define FFI_TYPE_STRUCT_FF_SOFT 429
+#define FFI_TYPE_STRUCT_FD_SOFT 493
+#define FFI_TYPE_STRUCT_DF_SOFT 445
+#define FFI_TYPE_STRUCT_SOFT 16
#endif
#ifdef LIBFFI_ASM
@@ -161,6 +170,8 @@ typedef enum ffi_abi {
FFI_N32,
FFI_N64,
FFI_O32_SOFT_FLOAT,
+ FFI_N32_SOFT_FLOAT,
+ FFI_N64_SOFT_FLOAT,
#ifdef FFI_MIPS_O32
#ifdef __mips_soft_float
@@ -170,9 +181,17 @@ typedef enum ffi_abi {
#endif
#else
# if _MIPS_SIM==_ABI64
+# ifdef __mips_soft_float
+ FFI_DEFAULT_ABI = FFI_N64_SOFT_FLOAT,
+# else
FFI_DEFAULT_ABI = FFI_N64,
+# endif
# else
+# ifdef __mips_soft_float
+ FFI_DEFAULT_ABI = FFI_N32_SOFT_FLOAT,
+# else
FFI_DEFAULT_ABI = FFI_N32,
+# endif
# endif
#endif
diff --git a/libffi/src/mips/n32.S b/libffi/src/mips/n32.S
index 477f30b77b3..6f0f4c6d530 100644
--- a/libffi/src/mips/n32.S
+++ b/libffi/src/mips/n32.S
@@ -217,8 +217,10 @@ callit:
# Shift the return type flag over
SRL t6, 8*FFI_FLAG_BITS
-
+
+ beq t6, FFI_TYPE_SINT32, retint
bne t6, FFI_TYPE_INT, retfloat
+retint:
jal t9
REG_L t4, 4*FFI_SIZEOF_ARG($fp)
REG_S v0, 0(t4)
@@ -277,12 +279,58 @@ retstruct_d_f:
b epilogue
retstruct_f_d:
- bne t6, FFI_TYPE_STRUCT_FD, retstruct_small
+ bne t6, FFI_TYPE_STRUCT_FD, retstruct_d_soft
jal t9
REG_L t4, 4*FFI_SIZEOF_ARG($fp)
s.s $f0, 0(t4)
s.d $f2, 8(t4)
b epilogue
+
+retstruct_d_soft:
+ bne t6, FFI_TYPE_STRUCT_D_SOFT, retstruct_f_soft
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ sd v0, 0(t4)
+ b epilogue
+
+retstruct_f_soft:
+ bne t6, FFI_TYPE_STRUCT_F_SOFT, retstruct_d_d_soft
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ sw v0, 0(t4)
+ b epilogue
+
+retstruct_d_d_soft:
+ bne t6, FFI_TYPE_STRUCT_DD_SOFT, retstruct_f_f_soft
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ sd v0, 0(t4)
+ sd v1, 8(t4)
+ b epilogue
+
+retstruct_f_f_soft:
+ bne t6, FFI_TYPE_STRUCT_FF_SOFT, retstruct_d_f_soft
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ sw v0, 0(t4)
+ sw v1, 4(t4)
+ b epilogue
+
+retstruct_d_f_soft:
+ bne t6, FFI_TYPE_STRUCT_DF_SOFT, retstruct_f_d_soft
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ sd v0, 0(t4)
+ sw v1, 8(t4)
+ b epilogue
+
+retstruct_f_d_soft:
+ bne t6, FFI_TYPE_STRUCT_FD_SOFT, retstruct_small
+ jal t9
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
+ sw v0, 0(t4)
+ sd v1, 8(t4)
+ b epilogue
retstruct_small:
bne t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2
@@ -413,6 +461,11 @@ ffi_closure_N32:
jalr t9
# Return flags are in v0
+ bne v0, FFI_TYPE_SINT32, cls_retint
+ lw v0, V0_OFF2($sp)
+ b cls_epilogue
+
+cls_retint:
bne v0, FFI_TYPE_INT, cls_retfloat
REG_L v0, V0_OFF2($sp)
b cls_epilogue
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 065a4ba3c73..346981415f1 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,42 @@
+2009-09-12 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libgfortran/41328
+ * io/transfer.c (read_sf): Adjust fbuf position and do proper
+ fbuf reads to traverse CR, CR-LF, and LF style line ends.
+
+2009-09-12 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libgfortran/41219
+ * io/write.c (write_a_char4): Use correct type for crlf constant.
+
+2009-09-11 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.am (libgfortranbegin_la_LINK): New.
+ * Makefile.in: Regenerate.
+
+2009-09-09 Paolo Bonzini <bonzini@gnu.org>
+
+ * configure: Regenerate.
+
+2009-09-08 Paolo Bonzini <bonzini@gnu.org>
+
+ * configure: Regenerate.
+
+2009-09-07 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libgfortran/41192
+ * io/list_read.c (eat_line): Enable eat_line to function on
+ internal units.
+
+ PR libgfortran/41219
+ * io/list_read.c (nml_read_obj): Replace GFC_DTYPE_UNKNOWN with
+ BT_NULL to get rid of warning.
+
+2009-09-04 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/41219
+ * intrinsics/getlog.c: Define _POSIX for MINGW32.
+
2009-09-03 Tobias Burnus <burnus@net-b.de>
PR fortran/41219
diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am
index 08609557ce6..c2fd941a992 100644
--- a/libgfortran/Makefile.am
+++ b/libgfortran/Makefile.am
@@ -24,6 +24,7 @@ myexeclib_LTLIBRARIES = libgfortranbegin.la
myexeclibdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR)
libgfortranbegin_la_SOURCES = fmain.c
libgfortranbegin_la_LDFLAGS = -static
+libgfortranbegin_la_LINK = $(LINK) $(libgfortranbegin_la_LDFLAGS)
## io.h conflicts with a system header on some platforms, so
## use -iquote
diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in
index 1bcae42d52d..462b07b487b 100644
--- a/libgfortran/Makefile.in
+++ b/libgfortran/Makefile.in
@@ -777,9 +777,6 @@ libgfortran_la_OBJECTS = $(am_libgfortran_la_OBJECTS)
libgfortranbegin_la_LIBADD =
am_libgfortranbegin_la_OBJECTS = fmain.lo
libgfortranbegin_la_OBJECTS = $(am_libgfortranbegin_la_OBJECTS)
-libgfortranbegin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libgfortranbegin_la_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/../depcomp
am__depfiles_maybe = depfiles
@@ -984,6 +981,7 @@ myexeclib_LTLIBRARIES = libgfortranbegin.la
myexeclibdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR)
libgfortranbegin_la_SOURCES = fmain.c
libgfortranbegin_la_LDFLAGS = -static
+libgfortranbegin_la_LINK = $(LINK) $(libgfortranbegin_la_LDFLAGS)
AM_CPPFLAGS = -iquote$(srcdir)/io -I$(srcdir)/$(MULTISRCTOP)../gcc \
-I$(srcdir)/$(MULTISRCTOP)../gcc/config \
-I$(MULTIBUILDTOP)../../$(host_subdir)/gcc -D_GNU_SOURCE
diff --git a/libgfortran/intrinsics/getlog.c b/libgfortran/intrinsics/getlog.c
index 0456c5796a2..e75aa1cb7d2 100644
--- a/libgfortran/intrinsics/getlog.c
+++ b/libgfortran/intrinsics/getlog.c
@@ -28,6 +28,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <string.h>
#ifdef HAVE_UNISTD_H
+# if defined __MINGW32__ && defined HAVE_GETLOGIN
+# define _POSIX 1
+# endif
#include <unistd.h>
#endif
#ifdef HAVE_PWD_H
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
index bcc00e17c26..d8ad602e593 100644
--- a/libgfortran/io/list_read.c
+++ b/libgfortran/io/list_read.c
@@ -287,10 +287,10 @@ static void
eat_line (st_parameter_dt *dtp)
{
char c;
- if (!is_internal_unit (dtp))
- do
- c = next_char (dtp);
- while (c != '\n');
+
+ do
+ c = next_char (dtp);
+ while (c != '\n');
}
@@ -2374,10 +2374,10 @@ nml_read_obj (st_parameter_dt *dtp, namelist_info * nl, index_type offset,
if (dtp->u.p.input_complete)
return SUCCESS;
- /* GFC_TYPE_UNKNOWN through for nulls and is detected
- after the switch block. */
+ /* BT_NULL (equivalent to GFC_DTYPE_UNKNOWN) falls through
+ for nulls and is detected at default: of switch block. */
- dtp->u.p.saved_type = GFC_DTYPE_UNKNOWN;
+ dtp->u.p.saved_type = BT_NULL;
free_saved (dtp);
switch (nl->type)
@@ -2467,7 +2467,7 @@ nml_read_obj (st_parameter_dt *dtp, namelist_info * nl, index_type offset,
return SUCCESS;
}
- if (dtp->u.p.saved_type == GFC_DTYPE_UNKNOWN)
+ if (dtp->u.p.saved_type == BT_NULL)
{
dtp->u.p.expanded_read = 0;
goto incr_idx;
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index 59f88d4fb9b..2362a154592 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -232,21 +232,28 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error)
if (q == '\n' || q == '\r')
{
- /* Unexpected end of line. */
+ /* Unexpected end of line. Set the position. */
+ fbuf_seek (dtp->u.p.current_unit, n + 1 ,SEEK_CUR);
+ dtp->u.p.sf_seen_eor = 1;
/* 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 (dtp->u.p.advance_status == ADVANCE_NO || dtp->u.p.seen_dollar)
dtp->u.p.eor_condition = 1;
-
+
/* If we encounter a CR, it might be a CRLF. */
if (q == '\r') /* Probably a CRLF */
{
- if (n < *length && *(p + 1) == '\n')
- dtp->u.p.sf_seen_eor = 2;
+ /* See if there is an LF. Use fbuf_read rather then fbuf_getc so
+ the position is not advanced unless it really is an LF. */
+ int readlen = 1;
+ p = fbuf_read (dtp->u.p.current_unit, &readlen);
+ if (*p == '\n' && readlen == 1)
+ {
+ dtp->u.p.sf_seen_eor = 2;
+ fbuf_seek (dtp->u.p.current_unit, 1 ,SEEK_CUR);
+ }
}
- else
- dtp->u.p.sf_seen_eor = 1;
/* Without padding, terminate the I/O statement without assigning
the value. With padding, the value still needs to be assigned,
@@ -260,7 +267,7 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error)
}
*length = n;
- break;
+ goto done;
}
/* Short circuit the read if a comma is found during numeric input.
The flag is set to zero during character reads so that commas in
@@ -274,13 +281,11 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error)
*length = n;
break;
}
-
n++;
p++;
}
- fbuf_seek (dtp->u.p.current_unit, n + dtp->u.p.sf_seen_eor + seen_comma,
- SEEK_CUR);
+ fbuf_seek (dtp->u.p.current_unit, n + seen_comma, SEEK_CUR);
/* A short read implies we hit EOF, unless we hit EOR, a comma, or
some other stuff. Set the relevant flags. */
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index 4956da8cf80..3c16a43b9ab 100644
--- a/libgfortran/io/write.c
+++ b/libgfortran/io/write.c
@@ -293,7 +293,7 @@ write_a_char4 (st_parameter_dt *dtp, const fnode *f, const char *source, int len
Standard sections 10.6.3 and 9.9 for further information. */
if (is_stream_io (dtp))
{
- const char crlf[] = "\r\n";
+ const gfc_char4_t crlf[] = {0x000d,0x000a};
int i, bytes;
gfc_char4_t *qq;
bytes = 0;
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index e88bdee68ad..3572d1794de 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,12 @@
+2009-09-17 Alexander Monakov <amonakov@ispras.ru>
+
+ * testsuite/libgomp.graphite/bounds.c: New test.
+
+2009-09-11 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.am (libgomp_la_LINK): New.
+ * Makefile.in: Regenerate.
+
2009-08-24 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* configure.ac (AC_PREREQ): Bump to 2.64.
diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am
index 5bc0732c01f..3786bee4c13 100644
--- a/libgomp/Makefile.am
+++ b/libgomp/Makefile.am
@@ -29,6 +29,7 @@ endif
libgomp_version_info = -version-info $(libtool_VERSION)
libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script) \
-no-undefined -bindir "$(bindir)"
+libgomp_la_LINK = $(LINK) $(libgomp_la_LDFLAGS)
libgomp_la_SOURCES = alloc.c barrier.c critical.c env.c error.c iter.c \
iter_ull.c loop.c loop_ull.c ordered.c parallel.c sections.c single.c \
diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in
index d5b9c474904..20c6975833e 100644
--- a/libgomp/Makefile.in
+++ b/libgomp/Makefile.in
@@ -100,9 +100,6 @@ am_libgomp_la_OBJECTS = alloc.lo barrier.lo critical.lo env.lo \
lock.lo mutex.lo proc.lo sem.lo bar.lo ptrlock.lo time.lo \
fortran.lo affinity.lo
libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS)
-libgomp_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libgomp_la_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/../depcomp
am__depfiles_maybe = depfiles
@@ -347,6 +344,7 @@ libgomp_version_info = -version-info $(libtool_VERSION)
libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script) \
-no-undefined -bindir "$(bindir)"
+libgomp_la_LINK = $(LINK) $(libgomp_la_LDFLAGS)
libgomp_la_SOURCES = alloc.c barrier.c critical.c env.c error.c iter.c \
iter_ull.c loop.c loop_ull.c ordered.c parallel.c sections.c single.c \
task.c team.c work.c lock.c mutex.c proc.c sem.c bar.c ptrlock.c \
diff --git a/libgomp/testsuite/libgomp.graphite/bounds.c b/libgomp/testsuite/libgomp.graphite/bounds.c
new file mode 100644
index 00000000000..bd36c0f8a22
--- /dev/null
+++ b/libgomp/testsuite/libgomp.graphite/bounds.c
@@ -0,0 +1,13 @@
+int foo(int *a, int n)
+{
+ int i;
+ for (i = 2; i < n; i++)
+ a[i] += a[i+1];
+}
+
+/* Check that Graphite dependency checking notes the dependency. */
+/* { dg-do compile } */
+/* { dg-final { scan-tree-dump-times "0 loops carried no dependency" 1 "graphite" } } */
+/* { dg-final { cleanup-tree-dump "graphite" } } */
+/* { dg-final { cleanup-tree-dump "parloops" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 17fb033c6f9..c86cbc6075a 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,19 @@
+2009-09-16 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * hashtab.c [HAVE_INTTYPES_H]: Include <inttypes.h>.
+
+2009-09-15 Tristan Gingold <gingold@adacore.com>
+
+ * config.h-vms (intptr_t): Define to compile hashtab.c
+
+2009-09-04 Ozkan Sezer <sezeroz@gmail.com>
+
+ PR target/39065
+ * configure.ac: Replace AC_CHECK_TYPE() for intptr_t and uintptr_t
+ with AC_TYPE_INTPTR_T and AC_TYPE_UINTPTR_T.
+ * config.in: Regenerated.
+ * configure: Regenerated.
+
2009-09-03 Ozkan Sezer <sezeroz@gmail.com>
PR target/39065
diff --git a/libiberty/config.h-vms b/libiberty/config.h-vms
index d84453101e8..d923ecb3cf2 100644
--- a/libiberty/config.h-vms
+++ b/libiberty/config.h-vms
@@ -5,6 +5,9 @@
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TIME_H 1
+/* intptr_t is defined in inttypes.h! */
+#define intptr_t __int64
+
/* Cheat: use vms builtin alloca. */
#ifdef __DECC
#define C_alloca(x) __ALLOCA(x)
diff --git a/libiberty/config.in b/libiberty/config.in
index e962769e6a9..193164830cf 100644
--- a/libiberty/config.in
+++ b/libiberty/config.in
@@ -121,6 +121,9 @@
/* Define to 1 if you have the `insque' function. */
#undef HAVE_INSQUE
+/* Define to 1 if the system has the type `intptr_t'. */
+#undef HAVE_INTPTR_T
+
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
@@ -457,13 +460,15 @@
#undef inline
#endif
-/* Define to `long' if <sys/types.h> does not define. */
+/* Define to the type of a signed integer type wide enough to hold a pointer,
+ if such a type exists, and if the system does not define it. */
#undef intptr_t
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
-/* Define to `unsigned long' if <sys/types.h> does not define. */
+/* Define to the type of an unsigned integer type wide enough to hold a
+ pointer, if such a type exists, and if the system does not define it. */
#undef uintptr_t
/* Define as `fork' if `vfork' does not work. */
diff --git a/libiberty/configure b/libiberty/configure
index 9463f8f506f..423e59b9b30 100755
--- a/libiberty/configure
+++ b/libiberty/configure
@@ -5046,29 +5046,6 @@ _ACEOF
-ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default"
-if test "x$ac_cv_type_intptr_t" = x""yes; then :
-
-else
-
-cat >>confdefs.h <<_ACEOF
-#define intptr_t long
-_ACEOF
-
-fi
-
-ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default"
-if test "x$ac_cv_type_uintptr_t" = x""yes; then :
-
-else
-
-cat >>confdefs.h <<_ACEOF
-#define uintptr_t unsigned long
-_ACEOF
-
-fi
-
-
# Look for a 64-bit type.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a 64-bit type" >&5
$as_echo_n "checking for a 64-bit type... " >&6; }
@@ -5148,6 +5125,78 @@ _ACEOF
fi
+
+ ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default"
+if test "x$ac_cv_type_intptr_t" = x""yes; then :
+
+$as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h
+
+else
+ for ac_type in 'int' 'long int' 'long long int'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define intptr_t $ac_type
+_ACEOF
+
+ ac_type=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test -z "$ac_type" && break
+ done
+fi
+
+
+
+ ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default"
+if test "x$ac_cv_type_uintptr_t" = x""yes; then :
+
+$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h
+
+else
+ for ac_type in 'unsigned int' 'unsigned long int' \
+ 'unsigned long long int'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define uintptr_t $ac_type
+_ACEOF
+
+ ac_type=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test -z "$ac_type" && break
+ done
+fi
+
+
+
# Given the above check, we always have uintptr_t or a fallback
# definition. So define HAVE_UINTPTR_T in case any imported code
# relies on it.
diff --git a/libiberty/configure.ac b/libiberty/configure.ac
index c34fc10b81b..00dd68dcef2 100644
--- a/libiberty/configure.ac
+++ b/libiberty/configure.ac
@@ -254,9 +254,6 @@ libiberty_AC_DECLARE_ERRNO
# Determine the size of an int for struct fibnode.
AC_CHECK_SIZEOF([int])
-AC_CHECK_TYPE(intptr_t, long)
-AC_CHECK_TYPE(uintptr_t, unsigned long)
-
# Look for a 64-bit type.
AC_MSG_CHECKING([for a 64-bit type])
AC_CACHE_VAL(liberty_cv_uint64,
@@ -290,6 +287,9 @@ if test "$liberty_cv_uint64" != none; then
[Define to an unsigned 64-bit type available in the compiler.])
fi
+AC_TYPE_INTPTR_T
+AC_TYPE_UINTPTR_T
+
# Given the above check, we always have uintptr_t or a fallback
# definition. So define HAVE_UINTPTR_T in case any imported code
# relies on it.
diff --git a/libiberty/hashtab.c b/libiberty/hashtab.c
index 8c8bd3110ad..8c89bfcd839 100644
--- a/libiberty/hashtab.c
+++ b/libiberty/hashtab.c
@@ -50,6 +50,9 @@ Boston, MA 02110-1301, USA. */
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 2498fc742b2..b58bc9966bb 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,21 @@
+2009-09-16 Jonathan Yong <jon_y@users.sourceforge.net>
+
+ * gnu/java/security/jce/prng/natVMSecureRandomWin32.cc: Correct
+ UnsupportedOperationException namespace.
+
+2009-09-16 Andrew Haley <aph@redhat.com>
+
+ * libgcj_bc.c (__data_start, data_start, _end): Add dummy usage.
+
+2009-09-11 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.am (libgij_la_LINK, libjvm_la_LINK): New.
+ * Makefile.in: Regenerate.
+
+2009-09-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure: Rebuilt with modified libtool.m4.
+
2009-08-24 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* configure.ac (AC_PREREQ): Bump to 2.64.
diff --git a/libjava/Makefile.am b/libjava/Makefile.am
index 13b25ac7ea6..7b6750c493c 100644
--- a/libjava/Makefile.am
+++ b/libjava/Makefile.am
@@ -223,6 +223,7 @@ libgij_la_LIBADD = -L$(here)/.libs libgcj.la
## The mysterious backslash in the grep pattern is consumed by make.
libgij_la_LDFLAGS = -rpath $(toolexeclibdir) \
-version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LIBGCJ_LD_SYMBOLIC)
+libgij_la_LINK = $(CXXLINK) $(libgij_la_LDFLAGS)
if INTERPRETER
libgcj_interpret_source_files = jvmti.cc interpret.cc
@@ -326,6 +327,7 @@ libjvm_la_DEPENDENCIES = libgcj.la libgcj.spec
## See jv_convert_LDADD.
libjvm_la_LIBADD = -L$(here)/.libs libgcj.la
libjvm_la_LDFLAGS = -avoid-version $(LIBGCJ_LD_SYMBOLIC)
+libjvm_la_LINK = $(CXXLINK) $(libjvm_la_LDFLAGS)
## The .db file. This rule is only used for native builds, so it is
## safe to invoke gcj-dbtool.
diff --git a/libjava/Makefile.in b/libjava/Makefile.in
index 9608e7941df..349b9074d34 100644
--- a/libjava/Makefile.in
+++ b/libjava/Makefile.in
@@ -454,14 +454,8 @@ libgcj_bc_la_OBJECTS = $(am_libgcj_bc_la_OBJECTS)
@USE_LIBGCJ_BC_TRUE@am_libgcj_bc_la_rpath = -rpath $(toolexeclibdir)
am_libgij_la_OBJECTS = gij.lo
libgij_la_OBJECTS = $(am_libgij_la_OBJECTS)
-libgij_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
- $(CXXFLAGS) $(libgij_la_LDFLAGS) $(LDFLAGS) -o $@
am_libjvm_la_OBJECTS = jni-libjvm.lo
libjvm_la_OBJECTS = $(am_libjvm_la_OBJECTS)
-libjvm_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
- $(CXXFLAGS) $(libjvm_la_LDFLAGS) $(LDFLAGS) -o $@
@CREATE_GJDOC_TRUE@@NATIVE_TRUE@am__EXEEXT_1 = gjdoc$(EXEEXT)
@NATIVE_TRUE@am__EXEEXT_2 = jv-convert$(EXEEXT) gij$(EXEEXT) \
@NATIVE_TRUE@ grmic$(EXEEXT) grmiregistry$(EXEEXT) \
@@ -973,6 +967,7 @@ libgij_la_LIBADD = -L$(here)/.libs libgcj.la
libgij_la_LDFLAGS = -rpath $(toolexeclibdir) \
-version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LIBGCJ_LD_SYMBOLIC)
+libgij_la_LINK = $(CXXLINK) $(libgij_la_LDFLAGS)
@INTERPRETER_FALSE@libgcj_interpret_source_files =
@INTERPRETER_TRUE@libgcj_interpret_source_files = jvmti.cc interpret.cc
libgcj_la_SOURCES = prims.cc jni.cc exception.cc stacktrace.cc link.cc \
@@ -1027,6 +1022,7 @@ libjvm_la_SOURCES = jni-libjvm.cc
libjvm_la_DEPENDENCIES = libgcj.la libgcj.spec
libjvm_la_LIBADD = -L$(here)/.libs libgcj.la
libjvm_la_LDFLAGS = -avoid-version $(LIBGCJ_LD_SYMBOLIC)
+libjvm_la_LINK = $(CXXLINK) $(libjvm_la_LDFLAGS)
lib_gnu_awt_xlib_la_SOURCES = $(xlib_nat_source_files)
lib_gnu_awt_xlib_la_LIBADD = gnu/awt/xlib.lo gnu/gcj/xlib.lo
lib_gnu_awt_xlib_la_DEPENDENCIES = libgcj-$(gcc_version).jar \
diff --git a/libjava/configure b/libjava/configure
index 63a238fbd14..a7c464a0bdb 100755
--- a/libjava/configure
+++ b/libjava/configure
@@ -14080,7 +14080,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
GXX=no
@@ -14417,7 +14417,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "^ .* -L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
;;
*)
if test "$GXX" = yes; then
@@ -14482,7 +14482,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "^ .* -L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
;;
*)
if test "$GXX" = yes; then
@@ -14826,7 +14826,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
# FIXME: insert proper C++ library support
@@ -14910,7 +14910,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
# g++ 2.7 appears to require `-G' NOT `-shared' on this
# platform.
@@ -14921,7 +14921,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
fi
hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
diff --git a/libjava/gnu/java/security/jce/prng/natVMSecureRandomWin32.cc b/libjava/gnu/java/security/jce/prng/natVMSecureRandomWin32.cc
index 66eaf82215f..1a9d0d355e2 100755
--- a/libjava/gnu/java/security/jce/prng/natVMSecureRandomWin32.cc
+++ b/libjava/gnu/java/security/jce/prng/natVMSecureRandomWin32.cc
@@ -26,7 +26,7 @@ jint
gnu::java::security::jce::prng::VMSecureRandom::natGenerateSeed(jbyteArray byte_array, jint offset, jint length)
{
if (length != 0)
- throw new UnsupportedOperationException (
+ throw new java::lang::UnsupportedOperationException (
JvNewStringLatin1 ("natGenerateSeed is not available for Win32 target."));
return 0;
}
diff --git a/libjava/libgcj_bc.c b/libjava/libgcj_bc.c
index e8da443f5fb..67f00aebfb0 100644
--- a/libjava/libgcj_bc.c
+++ b/libjava/libgcj_bc.c
@@ -112,3 +112,14 @@ DECLARE_PRIM_TYPE(char)
DECLARE_PRIM_TYPE(float)
DECLARE_PRIM_TYPE(double)
DECLARE_PRIM_TYPE(void)
+
+
+/* Force executable to export __data_start et al. */
+
+#pragma weak __data_start
+extern int __data_start[];
+#pragma weak data_start
+extern int data_start[];
+#pragma weak _end
+extern int _end[];
+static void *dummy[] __attribute__((used)) = {__data_start, data_start, _end};
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index d0562a6d89c..37de63fba14 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,231 @@
+2009-09-17 Johannes Singler <singler@ira.uka.de>
+
+ * include/parallel/algobase.h: Replace tabs by spaces;
+ correct line breaks.
+ * include/parallel/algorithmfwd.h: Likewise.
+ * include/parallel/balanced_quicksort.h: Likewise.
+ * include/parallel/base.h: Likewise.
+ * include/parallel/checkers.h: Likewise.
+ * include/parallel/compatibility.h: Likewise.
+ * include/parallel/equally_split.h: Likewise.
+ * include/parallel/find.h: Likewise.
+ * include/parallel/for_each.h: Likewise.
+ * include/parallel/for_each_selectors.h: Likewise.
+ * include/parallel/iterator.h: Likewise.
+ * include/parallel/list_partition.h: Likewise.
+ * include/parallel/losertree.h: Likewise.
+ * include/parallel/merge.h: Likewise.
+ * include/parallel/multiseq_selection.h: Likewise.
+ * include/parallel/multiway_merge.h: Likewise.
+ * include/parallel/multiway_mergesort.h: Likewise.
+ * include/parallel/numeric: Likewise.
+ * include/parallel/numericfwd.h: Likewise.
+ * include/parallel/omp_loop.h: Likewise.
+ * include/parallel/omp_loop_static.h: Likewise.
+ * include/parallel/par_loop.h: Likewise.
+ * include/parallel/partial_sum.h: Likewise.
+ * include/parallel/partition.h: Likewise.
+ * include/parallel/queue.h: Likewise.
+ * include/parallel/quicksort.h: Likewise.
+ * include/parallel/random_number.h: Likewise.
+ * include/parallel/random_shuffle.h: Likewise.
+ * include/parallel/search.h: Likewise.
+ * include/parallel/set_operations.h: Likewise.
+ * include/parallel/settings.h: Likewise.
+ * include/parallel/sort.h: Likewise.
+ * include/parallel/types.h: Likewise.
+ * include/parallel/unique_copy.h: Likewise.
+ * include/parallel/workstealing.h: Likewise.
+ * include/parallel/algo.h: Likewise;
+ shorten _ForwardIterator to _FIterator.
+ * include/parallel/find_selectors.h: Likewise.
+
+2009-09-16 Johannes Singler <singler@ira.uka.de>
+
+ * include/parallel/base.h: Correct some comments accidentally changed
+ during uglification.
+ * include/parallel/find.h: Likewise.
+ * include/parallel/find_selectors.h: Likewise.
+ * include/parallel/multiway_merge.h: Likewise.
+ * include/parallel/multiway_mergesort.h: Likewise.
+ * include/parallel/partial_sum.h: Likewise.
+ * include/parallel/partition.h: Likewise.
+ * include/parallel/queue.h: Likewise.
+ * include/parallel/random_shuffle.h: Likewise.
+ * include/parallel/settings.h: Likewise.
+ * include/parallel/sort.h: Likewise.
+ * include/parallel/tags.h: Likewise.
+ * include/parallel/workstealing.h: Likewise.
+
+2009-09-16 Johannes Singler <singler@ira.uka.de>
+
+ * include/parallel/base.h (_EqualFromLess):
+ Correct uglification of member variables and method arguments.
+ * include/parallel/balanced_quicksort.h (_QSBThreadLocal): Likewise.
+ * include/parallel/find_selectors.h (__find_first_of_selector):
+ Likewise.
+ * include/parallel/iterator.h (_IteratorTriple): Likewise.
+ * include/parallel/multiseq_selection.h
+ (_Lexicographic, _LexicographicReverse): Likewise.
+ * include/parallel/multiway_mergesort.h (_Piece, _PMWMSSortingData):
+ Likewise.
+ * include/parallel/random_number.h (_RandomNumber): Likewise.
+ * include/parallel/random_shuffle.h (_DRandomShufflingGlobalData):
+ Likewise.
+ * include/parallel/set_operations.h (__symmetric_difference_func,
+ __difference_func, __intersection_func, __union_func,
+ parallel_set_union, parallel_set_intersection, parallel_set_difference,
+ parallel_set_symmetric_difference): Likewise.
+ * include/parallel/tags.h (parallel_tag): Likewise.
+ * include/parallel/workstealing.h (_Job): Likewise.
+ * include/parallel/multiway_merge.h
+ (__multiway_merge_k_variant_sentinel_switch:operator())
+ correct uglification of _*LoserTree*.
+ * include/parallel/losertree.h (_*LoserTree*): Likewise; correct
+ uglification of member variables and method arguments.
+ * include/parallel/par_loop.h: Correct uglification of finish_iterator.
+ * include/parallel/for_each_selectors.h: Likewise.
+ * include/parallel/omp_loop.h: Likewise.
+ * include/parallel/algo.h: Likewise; uglify c_rand_number.
+
+2009-09-16 Johannes Singler <singler@ira.uka.de>
+
+ * include/parallel/base.h (_PseudoSequenceIterator, _PseudoSequence):
+ Replace redundant _Self.
+ * include/parallel/iterator.h (_IteratorPair, _IteratorTriple):
+ Replace redundant _Self.
+ * include/parallel/algo.h: Correct accidental _Self in comments.
+ * include/parallel/losertree.h: Likewise.
+ * include/parallel/multiway_merge.h: Likewise.
+ * include/parallel/random_shuffle.h: Likewise.
+
+2009-09-16 Johannes Singler <singler@ira.uka.de>
+
+ * include/parallel/algobase.h: Uglify internal identifiers.
+ * include/parallel/algo.h: Likewise.
+ * include/parallel/algorithm: Likewise.
+ * include/parallel/algorithmfwd.h: Likewise.
+ * include/parallel/balanced_quicksort.h: Likewise.
+ * include/parallel/base.h: Likewise.
+ * include/parallel/basic_iterator.h: Likewise.
+ * include/parallel/checkers.h: Likewise.
+ * include/parallel/compatibility.h: Likewise.
+ * include/parallel/compiletime_settings.: Likewise.
+ * include/parallel/equally_split.h: Likewise.
+ * include/parallel/features.h: Likewise.
+ * include/parallel/find.h: Likewise.
+ * include/parallel/find_selectors.h: Likewise.
+ * include/parallel/for_each.h: Likewise.
+ * include/parallel/for_each_selectors.h: Likewise.
+ * include/parallel/iterator.h: Likewise.
+ * include/parallel/list_partition.h: Likewise.
+ * include/parallel/losertree.h: Likewise.
+ * include/parallel/merge.h: Likewise.
+ * include/parallel/multiseq_selection.h: Likewise.
+ * include/parallel/multiway_merge.h: Likewise.
+ * include/parallel/multiway_mergesort.h: Likewise.
+ * include/parallel/numeric: Likewise.
+ * include/parallel/numericfwd.h: Likewise.
+ * include/parallel/omp_loop.h: Likewise.
+ * include/parallel/omp_loop_static.h: Likewise.
+ * include/parallel/parallel.h: Likewise.
+ * include/parallel/par_loop.h: Likewise.
+ * include/parallel/partial_sum.h: Likewise.
+ * include/parallel/partition.h: Likewise.
+ * include/parallel/queue.h: Likewise.
+ * include/parallel/quicksort.h: Likewise.
+ * include/parallel/random_number.h: Likewise.
+ * include/parallel/random_shuffle.h: Likewise.
+ * include/parallel/search.h: Likewise.
+ * include/parallel/set_operations.h: Likewise.
+ * include/parallel/settings.h: Likewise.
+ * include/parallel/sort.h: Likewise.
+ * include/parallel/tags.h: Likewise.
+ * include/parallel/types.h: Likewise.
+ * include/parallel/unique_copy.h: Likewise.
+ * include/parallel/workstealing.h: Likewise.
+
+2009-09-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/41037
+ * src/ios_init.cc (ios_base::Init::Init): Properly initialize cerr
+ and wcerr flags.
+ * testsuite/27_io/objects/char/41037.cc: New.
+ * testsuite/27_io/objects/wchar_t/41037.cc: Likewise.
+
+2009-09-14 Andrew Stubbs <ams@codesourcery.com>
+
+ * config/cpu/sh/atomicity.h (__exchange_and_add): Set earlyclobber
+ constraint.
+
+2009-09-11 Johannes Singler <singler@ira.uka.de>
+
+ * include/parallel/multiway_merge.h
+ (multiway_merge_exact_splitting): Deallocate borders correctly.
+ (parallel_multiway_merge): Remove unnecessarily complicated
+ allocation, random access iterators are default-constructible;
+ deallocate ne_seqs correctly.
+
+2009-09-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/41316
+ * include/bits/forward_list.h (_Fwd_list_node_base<>::_M_sort_after):
+ Remove.
+ (forward_list<>::sort(_Comp)): Only declare.
+ (forward_list<>::sort()): Forward to the latter.
+ * include/bits/forward_list.tcc (_Fwd_list_node_base<>::_M_sort_after):
+ Remove definition.
+ (forward_list<>::sort(_Comp)): Define.
+ * testsuite/23_containers/forward_list/requirements/dr438/
+ assign_neg.cc: Adjust dg-error line number.
+ * testsuite/23_containers/forward_list/requirements/dr438/
+ insert_neg.cc: Likewise.
+ * testsuite/23_containers/forward_list/requirements/dr438/
+ constructor_1_neg.cc: Likewise.
+ * testsuite/23_containers/forward_list/requirements/dr438/
+ constructor_2_neg.cc: Likewise.
+
+2009-09-11 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * src/Makefile.am (libstdc___la_LINK): New.
+ * src/Makefile.in: Regenerate.
+
+2009-09-09 Loren J. Rittle <ljrittle@acm.org>
+
+ * testsuite/30_threads/thread/native_handle/typesizes.cc: Remove
+ *-*-freebsd* from both dg-do and dg-options.
+
+2009-09-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure: Rebuilt with modified libtool.m4.
+
+2009-09-07 H.J. Lu <hongjiu.lu@intel.com>
+ Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ PR libstdc++/41280
+ * configure.ac: Run "${multi_basedir}/config-ml.in" to generate
+ MULTISUBDIR = in subdirectory Makefiles, with ml_norecursion set.
+ * configure: Regenerate.
+
+2009-09-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/41267
+ * include/bits/stl_algobase.h (__copy_move::__copy_m,
+ __copy_move_backward::__copy_move_b): Don't call __builtin_memmove
+ with a null third argument.
+
+2009-09-04 Benjamin Kosnik <bkoz@redhat.com>
+
+ Revert.
+ 2009-08-06 Benjamin Kosnik <bkoz@redhat.com>
+ * src/compatibility.cc: Make C++0x safe, add in explicit casts to
+ bool for stream sentry objects.
+ * include/bits/istream.tcc: Same.
+ * include/bits/ostream.tcc: Same.
+ * include/bits/basic_string.tcc: Same.
+ * include/bits/ostream_insert.h: Same.
+ * src/istream.cc: Same.
+
2009-09-02 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* configure.ac: Replace AC_CONFIG_COMMANDS([default])
@@ -21,7 +249,7 @@
2009-09-02 Paolo Carlini <paolo.carlini@oracle.com>
* include/bits/stl_uninitialized.h
- (__uninitialized_copy::uninitialized_copy): Just call (the now
+ (__uninitialized_copy::uninitialized_copy): Just call (the now
forwarding) _Construct.
2009-09-01 Chris Jefferson <chris@bubblescope.net>
diff --git a/libstdc++-v3/config/cpu/sh/atomicity.h b/libstdc++-v3/config/cpu/sh/atomicity.h
index 251d49ff2b9..9b240afbcc7 100644
--- a/libstdc++-v3/config/cpu/sh/atomicity.h
+++ b/libstdc++-v3/config/cpu/sh/atomicity.h
@@ -44,7 +44,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
"\tadd\t%3,r0\n"
"\tmovco.l\tr0,@%2\n"
"\tbf\t0b"
- : "+m" (*__mem), "=r" (__result)
+ : "+m" (*__mem), "=&r" (__result)
: "r" (__mem), "rI08" (__val)
: "r0");
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 2d0c97782cf..1430a8b0307 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -12336,7 +12336,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
GXX=no
@@ -12673,7 +12673,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "^ .* -L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
;;
*)
if test "$GXX" = yes; then
@@ -12738,7 +12738,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "^ .* -L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
;;
*)
if test "$GXX" = yes; then
@@ -13082,7 +13082,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
# FIXME: insert proper C++ library support
@@ -13166,7 +13166,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
# g++ 2.7 appears to require `-G' NOT `-shared' on this
# platform.
@@ -13177,7 +13177,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
fi
hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
@@ -61956,57 +61956,78 @@ fi
s!`test -f '$<' || echo '$(srcdir)/'`!!
_EOF
sed -f vpsed$$ $ac_file > tmp$$
- grep '^MULTISUBDIR =' Makefile >> tmp$$
mv tmp$$ $ac_file
rm vpsed$$
+ echo 'MULTISUBDIR =' >> $ac_file
+ ml_norecursion=yes
+ . ${multi_basedir}/config-ml.in
+ { ml_norecursion=; unset ml_norecursion;}
;;
"libsupc++/Makefile":F) cat > vpsed$$ << \_EOF
s!`test -f '$<' || echo '$(srcdir)/'`!!
_EOF
sed -f vpsed$$ $ac_file > tmp$$
- grep '^MULTISUBDIR =' Makefile >> tmp$$
mv tmp$$ $ac_file
rm vpsed$$
+ echo 'MULTISUBDIR =' >> $ac_file
+ ml_norecursion=yes
+ . ${multi_basedir}/config-ml.in
+ { ml_norecursion=; unset ml_norecursion;}
;;
"python/Makefile":F) cat > vpsed$$ << \_EOF
s!`test -f '$<' || echo '$(srcdir)/'`!!
_EOF
sed -f vpsed$$ $ac_file > tmp$$
- grep '^MULTISUBDIR =' Makefile >> tmp$$
mv tmp$$ $ac_file
rm vpsed$$
+ echo 'MULTISUBDIR =' >> $ac_file
+ ml_norecursion=yes
+ . ${multi_basedir}/config-ml.in
+ { ml_norecursion=; unset ml_norecursion;}
;;
"src/Makefile":F) cat > vpsed$$ << \_EOF
s!`test -f '$<' || echo '$(srcdir)/'`!!
_EOF
sed -f vpsed$$ $ac_file > tmp$$
- grep '^MULTISUBDIR =' Makefile >> tmp$$
mv tmp$$ $ac_file
rm vpsed$$
+ echo 'MULTISUBDIR =' >> $ac_file
+ ml_norecursion=yes
+ . ${multi_basedir}/config-ml.in
+ { ml_norecursion=; unset ml_norecursion;}
;;
"doc/Makefile":F) cat > vpsed$$ << \_EOF
s!`test -f '$<' || echo '$(srcdir)/'`!!
_EOF
sed -f vpsed$$ $ac_file > tmp$$
- grep '^MULTISUBDIR =' Makefile >> tmp$$
mv tmp$$ $ac_file
rm vpsed$$
+ echo 'MULTISUBDIR =' >> $ac_file
+ ml_norecursion=yes
+ . ${multi_basedir}/config-ml.in
+ { ml_norecursion=; unset ml_norecursion;}
;;
"po/Makefile":F) cat > vpsed$$ << \_EOF
s!`test -f '$<' || echo '$(srcdir)/'`!!
_EOF
sed -f vpsed$$ $ac_file > tmp$$
- grep '^MULTISUBDIR =' Makefile >> tmp$$
mv tmp$$ $ac_file
rm vpsed$$
+ echo 'MULTISUBDIR =' >> $ac_file
+ ml_norecursion=yes
+ . ${multi_basedir}/config-ml.in
+ { ml_norecursion=; unset ml_norecursion;}
;;
"testsuite/Makefile":F) cat > vpsed$$ << \_EOF
s!`test -f '$<' || echo '$(srcdir)/'`!!
_EOF
sed -f vpsed$$ $ac_file > tmp$$
- grep '^MULTISUBDIR =' Makefile >> tmp$$
mv tmp$$ $ac_file
rm vpsed$$
+ echo 'MULTISUBDIR =' >> $ac_file
+ ml_norecursion=yes
+ . ${multi_basedir}/config-ml.in
+ { ml_norecursion=; unset ml_norecursion;}
;;
"generate-headers":C) (cd include && ${MAKE-make} pch_build= ) ;;
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index e8f680526e9..e35bc0a9d51 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -404,9 +404,12 @@ AC_CONFIG_FILES(AC_FOREACH([DIR], glibcxx_SUBDIRS, [DIR/Makefile ]),
s!`test -f '$<' || echo '$(srcdir)/'`!!
_EOF
sed -f vpsed$$ $ac_file > tmp$$
- grep '^MULTISUBDIR =' Makefile >> tmp$$
mv tmp$$ $ac_file
rm vpsed$$
+ echo 'MULTISUBDIR =' >> $ac_file
+ ml_norecursion=yes
+ . ${multi_basedir}/config-ml.in
+ AS_UNSET([ml_norecursion])
])
AC_CONFIG_COMMANDS([generate-headers],
diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc
index 10dea7563d8..d450a4717de 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -1007,7 +1007,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__size_type __extracted = 0;
typename __ios_base::iostate __err = __ios_base::goodbit;
typename __istream_type::sentry __cerb(__in, false);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
@@ -1078,7 +1078,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const __size_type __n = __str.max_size();
typename __ios_base::iostate __err = __ios_base::goodbit;
typename __istream_type::sentry __cerb(__in, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index 5158f2dac64..0ec5a1141a9 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -92,10 +92,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
: _Fwd_list_node_base<_Alloc>(),
_M_value(std::forward<_Args>(__args)...) { }
- template<typename _Comp>
- void
- _M_sort_after(_Comp __comp);
-
_Tp _M_value;
};
@@ -1149,7 +1145,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
*/
void
merge(forward_list&& __list)
- { this->merge(std::forward<forward_list>(__list), std::less<_Tp>()); }
+ { this->merge(std::move(__list), std::less<_Tp>()); }
/**
* @brief Merge sorted lists according to comparison function.
@@ -1174,10 +1170,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
*/
void
sort()
- {
- _Node* __tmp = __static_pointer_cast<_Node*>(&this->_M_impl._M_head);
- __tmp->_M_sort_after(std::less<_Tp>());
- }
+ { this->sort(std::less<_Tp>()); }
/**
* @brief Sort the forward_list using a comparison function.
@@ -1187,11 +1180,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
*/
template<typename _Comp>
void
- sort(_Comp __comp)
- {
- _Node* __tmp = __static_pointer_cast<_Node*>(&this->_M_impl._M_head);
- __tmp->_M_sort_after(__comp);
- }
+ sort(_Comp __comp);
/**
* @brief Reverse the elements in list.
@@ -1285,7 +1274,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
template<typename _Tp, typename _Alloc>
inline void
swap(forward_list<_Tp, _Alloc>& __lx,
- forward_list<_Tp, _Alloc>& __ly)
+ forward_list<_Tp, _Alloc>& __ly)
{ __lx.swap(__ly); }
_GLIBCXX_END_NAMESPACE // namespace std
diff --git a/libstdc++-v3/include/bits/forward_list.tcc b/libstdc++-v3/include/bits/forward_list.tcc
index 8458e7e5fee..13573699061 100644
--- a/libstdc++-v3/include/bits/forward_list.tcc
+++ b/libstdc++-v3/include/bits/forward_list.tcc
@@ -75,111 +75,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
}
}
- /**
- * @brief Sort the singly linked list starting after this node.
- * This node is assumed to be an empty head node (of type
- * _Fwd_list_node_base).
- */
- template<typename _Tp, class _Alloc>
- template<typename _Comp>
- void
- _Fwd_list_node<_Tp, _Alloc>::
- _M_sort_after(_Comp __comp)
- {
- // If `next' is 0, return immediately.
- _Pointer __list = __static_pointer_cast<_Pointer>(this->_M_next);
- if (!__list)
- return;
-
- unsigned long __insize = 1;
-
- while (1)
- {
- _Pointer __p = __list;
- __list = 0;
- _Pointer __tail = 0;
-
- // Count number of merges we do in this pass.
- unsigned long __nmerges = 0;
-
- while (__p)
- {
- ++__nmerges;
- // There exists a merge to be done.
- // Step `insize' places along from p.
- _Pointer __q = __p;
- unsigned long __psize = 0;
- for (unsigned long __i = 0; __i < __insize; ++__i)
- {
- ++__psize;
- __q = __static_pointer_cast<_Pointer>(__q->_M_next);
- if (!__q)
- break;
- }
-
- // If q hasn't fallen off end, we have two lists to merge.
- unsigned long __qsize = __insize;
-
- // Now we have two lists; merge them.
- while (__psize > 0 || (__qsize > 0 && __q))
- {
- // Decide whether next node of merge comes from p or q.
- _Pointer __e;
- if (__psize == 0)
- {
- // p is empty; e must come from q.
- __e = __q;
- __q = __static_pointer_cast<_Pointer>(__q->_M_next);
- --__qsize;
- }
- else if (__qsize == 0 || !__q)
- {
- // q is empty; e must come from p.
- __e = __p;
- __p = __static_pointer_cast<_Pointer>(__p->_M_next);
- --__psize;
- }
- else if (__comp(__p->_M_value, __q->_M_value))
- {
- // First node of p is lower; e must come from p.
- __e = __p;
- __p = __static_pointer_cast<_Pointer>(__p->_M_next);
- --__psize;
- }
- else
- {
- // First node of q is lower; e must come from q.
- __e = __q;
- __q = __static_pointer_cast<_Pointer>(__q->_M_next);
- --__qsize;
- }
-
- // Add the next node to the merged list.
- if (__tail)
- __tail->_M_next = __e;
- else
- __list = __e;
- __tail = __e;
- }
-
- // Now p has stepped `insize' places along, and q has too.
- __p = __q;
- }
- __tail->_M_next = 0;
-
- // If we have done only one merge, we're finished.
- // Allow for nmerges == 0, the empty list case.
- if (__nmerges <= 1)
- {
- this->_M_next = __list;
- return;
- }
-
- // Otherwise repeat, merging lists twice the size.
- __insize *= 2;
- }
- }
-
template<typename _Tp, typename _Alloc>
_Fwd_list_base<_Tp, _Alloc>::
_Fwd_list_base(const _Fwd_list_base& __lst, const _Alloc& __a)
@@ -472,6 +367,109 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
return false;
}
+ template<typename _Tp, class _Alloc>
+ template<typename _Comp>
+ void
+ forward_list<_Tp, _Alloc>::
+ sort(_Comp __comp)
+ {
+ typedef typename _Node::_Pointer _Pointer;
+
+ // If `next' is 0, return immediately.
+ _Pointer __list =
+ __static_pointer_cast<_Pointer>(this->_M_impl._M_head._M_next);
+ if (!__list)
+ return;
+
+ unsigned long __insize = 1;
+
+ while (1)
+ {
+ _Pointer __p = __list;
+ __list = 0;
+ _Pointer __tail = 0;
+
+ // Count number of merges we do in this pass.
+ unsigned long __nmerges = 0;
+
+ while (__p)
+ {
+ ++__nmerges;
+ // There exists a merge to be done.
+ // Step `insize' places along from p.
+ _Pointer __q = __p;
+ unsigned long __psize = 0;
+ for (unsigned long __i = 0; __i < __insize; ++__i)
+ {
+ ++__psize;
+ __q = __static_pointer_cast<_Pointer>(__q->_M_next);
+ if (!__q)
+ break;
+ }
+
+ // If q hasn't fallen off end, we have two lists to merge.
+ unsigned long __qsize = __insize;
+
+ // Now we have two lists; merge them.
+ while (__psize > 0 || (__qsize > 0 && __q))
+ {
+ // Decide whether next node of merge comes from p or q.
+ _Pointer __e;
+ if (__psize == 0)
+ {
+ // p is empty; e must come from q.
+ __e = __q;
+ __q = __static_pointer_cast<_Pointer>(__q->_M_next);
+ --__qsize;
+ }
+ else if (__qsize == 0 || !__q)
+ {
+ // q is empty; e must come from p.
+ __e = __p;
+ __p = __static_pointer_cast<_Pointer>(__p->_M_next);
+ --__psize;
+ }
+ else if (__comp(__p->_M_value, __q->_M_value))
+ {
+ // First node of p is lower; e must come from p.
+ __e = __p;
+ __p = __static_pointer_cast<_Pointer>(__p->_M_next);
+ --__psize;
+ }
+ else
+ {
+ // First node of q is lower; e must come from q.
+ __e = __q;
+ __q = __static_pointer_cast<_Pointer>(__q->_M_next);
+ --__qsize;
+ }
+
+ // Add the next node to the merged list.
+ if (__tail)
+ __tail->_M_next = __e;
+ else
+ __list = __e;
+ __tail = __e;
+ }
+
+ // Now p has stepped `insize' places along, and q has too.
+ __p = __q;
+ }
+ __tail->_M_next = 0;
+
+ // If we have done only one merge, we're finished.
+ // Allow for nmerges == 0, the empty list case.
+ if (__nmerges <= 1)
+ {
+ this->_M_impl._M_head._M_next = __list;
+ return;
+ }
+
+ // Otherwise repeat, merging lists twice the size.
+ __insize *= 2;
+ }
+ }
+
_GLIBCXX_END_NAMESPACE // namespace std
#endif /* _FORWARD_LIST_TCC */
diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc
index 6d1679d152f..d005f736f03 100644
--- a/libstdc++-v3/include/bits/istream.tcc
+++ b/libstdc++-v3/include/bits/istream.tcc
@@ -87,7 +87,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_extract(_ValueT& __v)
{
sentry __cerb(*this, false);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -116,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 118. basic_istream uses nonexistent num_get member functions.
sentry __cerb(*this, false);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -161,7 +161,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 118. basic_istream uses nonexistent num_get member functions.
sentry __cerb(*this, false);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -205,7 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
ios_base::iostate __err = ios_base::goodbit;
sentry __cerb(*this, false);
- if (__sbout && static_cast<bool>(__cerb))
+ if (__cerb && __sbout)
{
__try
{
@@ -240,7 +240,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_gcount = 0;
ios_base::iostate __err = ios_base::goodbit;
sentry __cerb(*this, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
@@ -274,7 +274,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_gcount = 0;
ios_base::iostate __err = ios_base::goodbit;
sentry __cerb(*this, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
@@ -311,7 +311,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_gcount = 0;
ios_base::iostate __err = ios_base::goodbit;
sentry __cerb(*this, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
@@ -358,7 +358,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_gcount = 0;
ios_base::iostate __err = ios_base::goodbit;
sentry __cerb(*this, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
@@ -402,7 +402,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_gcount = 0;
ios_base::iostate __err = ios_base::goodbit;
sentry __cerb(*this, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
@@ -461,7 +461,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
_M_gcount = 0;
sentry __cerb(*this, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -494,7 +494,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
_M_gcount = 0;
sentry __cerb(*this, true);
- if (__n > 0 && static_cast<bool>(__cerb))
+ if (__cerb && __n > 0)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -556,7 +556,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
_M_gcount = 0;
sentry __cerb(*this, true);
- if (__n > 0 && static_cast<bool>(__cerb))
+ if (__cerb && __n > 0)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -622,7 +622,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
int_type __c = traits_type::eof();
_M_gcount = 0;
sentry __cerb(*this, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -651,7 +651,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
_M_gcount = 0;
sentry __cerb(*this, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -680,7 +680,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
_M_gcount = 0;
sentry __cerb(*this, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -714,7 +714,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// 60. What is a formatted input function?
_M_gcount = 0;
sentry __cerb(*this, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -747,7 +747,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// 60. What is a formatted input function?
_M_gcount = 0;
sentry __cerb(*this, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -780,7 +780,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// DR60. Do not change _M_gcount.
int __ret = -1;
sentry __cerb(*this, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -906,7 +906,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
typedef typename __istream_type::int_type __int_type;
typename __istream_type::sentry __cerb(__in, false);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -943,7 +943,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
streamsize __extracted = 0;
ios_base::iostate __err = ios_base::goodbit;
typename __istream_type::sentry __cerb(__in, false);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
diff --git a/libstdc++-v3/include/bits/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc
index df68a57fa61..1147212aa14 100644
--- a/libstdc++-v3/include/bits/ostream.tcc
+++ b/libstdc++-v3/include/bits/ostream.tcc
@@ -64,7 +64,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_insert(_ValueT __v)
{
sentry __cerb(*this);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -121,7 +121,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
ios_base::iostate __err = ios_base::goodbit;
sentry __cerb(*this);
- if (__sbin && static_cast<bool>(__cerb))
+ if (__cerb && __sbin)
{
__try
{
@@ -155,7 +155,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// Unformatted output functions should catch exceptions thrown
// from streambuf members.
sentry __cerb(*this);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -190,7 +190,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// Unformatted output functions should catch exceptions thrown
// from streambuf members.
sentry __cerb(*this);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{ _M_write(__s, __n); }
diff --git a/libstdc++-v3/include/bits/ostream_insert.h b/libstdc++-v3/include/bits/ostream_insert.h
index 4fc52c86aff..e0017ee7cfd 100644
--- a/libstdc++-v3/include/bits/ostream_insert.h
+++ b/libstdc++-v3/include/bits/ostream_insert.h
@@ -78,7 +78,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
typedef typename __ostream_type::ios_base __ios_base;
typename __ostream_type::sentry __cerb(__out);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index 2cef9237d76..c638c547887 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -375,9 +375,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
static _Tp*
__copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result)
{
- __builtin_memmove(__result, __first,
- sizeof(_Tp) * (__last - __first));
- return __result + (__last - __first);
+ const ptrdiff_t _Num = __last - __first;
+ if (_Num)
+ __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
+ return __result + _Num;
}
};
@@ -572,7 +573,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__copy_move_b(const _Tp* __first, const _Tp* __last, _Tp* __result)
{
const ptrdiff_t _Num = __last - __first;
- __builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num);
+ if (_Num)
+ __builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num);
return __result - _Num;
}
};
diff --git a/libstdc++-v3/include/parallel/algo.h b/libstdc++-v3/include/parallel/algo.h
index a0fbd8d91d6..1a75d24b917 100644
--- a/libstdc++-v3/include/parallel/algo.h
+++ b/libstdc++-v3/include/parallel/algo.h
@@ -63,1784 +63,1805 @@ namespace std
namespace __parallel
{
// Sequential fallback
- template<typename InputIterator, typename Function>
- inline Function
- for_each(InputIterator begin, InputIterator end, Function f,
+ template<typename _IIter, typename _Function>
+ inline _Function
+ for_each(_IIter __begin, _IIter __end, _Function __f,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::for_each(begin, end, f); }
+ { return _GLIBCXX_STD_P::for_each(__begin, __end, __f); }
// Sequential fallback for input iterator case
- template<typename InputIterator, typename Function, typename IteratorTag>
- inline Function
- for_each_switch(InputIterator begin, InputIterator end, Function f,
- IteratorTag)
- { return for_each(begin, end, f, __gnu_parallel::sequential_tag()); }
+ template<typename _IIter, typename _Function, typename _IteratorTag>
+ inline _Function
+ __for_each_switch(_IIter __begin, _IIter __end, _Function __f,
+ _IteratorTag)
+ { return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators
- template<typename RandomAccessIterator, typename Function>
- Function
- for_each_switch(RandomAccessIterator begin, RandomAccessIterator end,
- Function f, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism_tag
+ template<typename _RAIter, typename _Function>
+ _Function
+ __for_each_switch(_RAIter __begin, _RAIter __end,
+ _Function __f, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag
= __gnu_parallel::parallel_balanced)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().for_each_minimal_n
- && __gnu_parallel::is_parallel(parallelism_tag)))
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
{
- bool dummy;
- __gnu_parallel::for_each_selector<RandomAccessIterator> functionality;
+ bool __dummy;
+ __gnu_parallel::__for_each_selector<_RAIter> __functionality;
return __gnu_parallel::
- for_each_template_random_access(begin, end, f, functionality,
- __gnu_parallel::dummy_reduct(),
- true, dummy, -1, parallelism_tag);
+ __for_each_template_random_access(
+ __begin, __end, __f, __functionality,
+ __gnu_parallel::_DummyReduct(), true, __dummy, -1,
+ __parallelism_tag);
}
else
- return for_each(begin, end, f, __gnu_parallel::sequential_tag());
+ return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag());
}
// Public interface
- template<typename Iterator, typename Function>
- inline Function
- for_each(Iterator begin, Iterator end, Function f,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _Iterator, typename _Function>
+ inline _Function
+ for_each(_Iterator __begin, _Iterator __end, _Function __f,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef std::iterator_traits<Iterator> iterator_traits;
- typedef typename iterator_traits::iterator_category iterator_category;
- return for_each_switch(begin, end, f, iterator_category(),
- parallelism_tag);
+ typedef std::iterator_traits<_Iterator> _IteratorTraits;
+ typedef typename _IteratorTraits::iterator_category _IteratorCategory;
+ return __for_each_switch(__begin, __end, __f, _IteratorCategory(),
+ __parallelism_tag);
}
- template<typename Iterator, typename Function>
- inline Function
- for_each(Iterator begin, Iterator end, Function f)
+ template<typename _Iterator, typename _Function>
+ inline _Function
+ for_each(_Iterator __begin, _Iterator __end, _Function __f)
{
- typedef std::iterator_traits<Iterator> iterator_traits;
- typedef typename iterator_traits::iterator_category iterator_category;
- return for_each_switch(begin, end, f, iterator_category());
+ typedef std::iterator_traits<_Iterator> _IteratorTraits;
+ typedef typename _IteratorTraits::iterator_category _IteratorCategory;
+ return __for_each_switch(__begin, __end, __f, _IteratorCategory());
}
// Sequential fallback
- template<typename InputIterator, typename T>
- inline InputIterator
- find(InputIterator begin, InputIterator end, const T& val,
+ template<typename _IIter, typename _Tp>
+ inline _IIter
+ find(_IIter __begin, _IIter __end, const _Tp& __val,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::find(begin, end, val); }
+ { return _GLIBCXX_STD_P::find(__begin, __end, __val); }
// Sequential fallback for input iterator case
- template<typename InputIterator, typename T, typename IteratorTag>
- inline InputIterator
- find_switch(InputIterator begin, InputIterator end, const T& val,
- IteratorTag)
- { return _GLIBCXX_STD_P::find(begin, end, val); }
+ template<typename _IIter, typename _Tp, typename _IteratorTag>
+ inline _IIter
+ __find_switch(_IIter __begin, _IIter __end, const _Tp& __val,
+ _IteratorTag)
+ { return _GLIBCXX_STD_P::find(__begin, __end, __val); }
// Parallel find for random access iterators
- template<typename RandomAccessIterator, typename T>
- RandomAccessIterator
- find_switch(RandomAccessIterator begin, RandomAccessIterator end,
- const T& val, random_access_iterator_tag)
+ template<typename _RAIter, typename _Tp>
+ _RAIter
+ __find_switch(_RAIter __begin, _RAIter __end,
+ const _Tp& __val, random_access_iterator_tag)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
if (_GLIBCXX_PARALLEL_CONDITION(true))
{
- binder2nd<__gnu_parallel::equal_to<value_type, const T&> >
- comp(__gnu_parallel::equal_to<value_type, const T&>(), val);
- return __gnu_parallel::find_template(begin, end, begin, comp,
- __gnu_parallel::
- find_if_selector()).first;
+ binder2nd<__gnu_parallel::equal_to<_ValueType, const _Tp&> >
+ __comp(__gnu_parallel::equal_to<_ValueType, const _Tp&>(), __val);
+ return __gnu_parallel::__find_template(
+ __begin, __end, __begin, __comp,
+ __gnu_parallel::__find_if_selector()).first;
}
else
- return _GLIBCXX_STD_P::find(begin, end, val);
+ return _GLIBCXX_STD_P::find(__begin, __end, __val);
}
// Public interface
- template<typename InputIterator, typename T>
- inline InputIterator
- find(InputIterator begin, InputIterator end, const T& val)
+ template<typename _IIter, typename _Tp>
+ inline _IIter
+ find(_IIter __begin, _IIter __end, const _Tp& __val)
{
- typedef std::iterator_traits<InputIterator> iterator_traits;
- typedef typename iterator_traits::iterator_category iterator_category;
- return find_switch(begin, end, val, iterator_category());
+ typedef std::iterator_traits<_IIter> _IteratorTraits;
+ typedef typename _IteratorTraits::iterator_category _IteratorCategory;
+ return __find_switch(__begin, __end, __val, _IteratorCategory());
}
// Sequential fallback
- template<typename InputIterator, typename Predicate>
- inline InputIterator
- find_if(InputIterator begin, InputIterator end, Predicate pred,
+ template<typename _IIter, typename _Predicate>
+ inline _IIter
+ find_if(_IIter __begin, _IIter __end, _Predicate __pred,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::find_if(begin, end, pred); }
+ { return _GLIBCXX_STD_P::find_if(__begin, __end, __pred); }
// Sequential fallback for input iterator case
- template<typename InputIterator, typename Predicate, typename IteratorTag>
- inline InputIterator
- find_if_switch(InputIterator begin, InputIterator end, Predicate pred,
- IteratorTag)
- { return _GLIBCXX_STD_P::find_if(begin, end, pred); }
+ template<typename _IIter, typename _Predicate, typename _IteratorTag>
+ inline _IIter
+ __find_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
+ _IteratorTag)
+ { return _GLIBCXX_STD_P::find_if(__begin, __end, __pred); }
// Parallel find_if for random access iterators
- template<typename RandomAccessIterator, typename Predicate>
- RandomAccessIterator
- find_if_switch(RandomAccessIterator begin, RandomAccessIterator end,
- Predicate pred, random_access_iterator_tag)
+ template<typename _RAIter, typename _Predicate>
+ _RAIter
+ __find_if_switch(_RAIter __begin, _RAIter __end,
+ _Predicate __pred, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(true))
- return __gnu_parallel::find_template(begin, end, begin, pred,
+ return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
__gnu_parallel::
- find_if_selector()).first;
+ __find_if_selector()).first;
else
- return _GLIBCXX_STD_P::find_if(begin, end, pred);
+ return _GLIBCXX_STD_P::find_if(__begin, __end, __pred);
}
// Public interface
- template<typename InputIterator, typename Predicate>
- inline InputIterator
- find_if(InputIterator begin, InputIterator end, Predicate pred)
+ template<typename _IIter, typename _Predicate>
+ inline _IIter
+ find_if(_IIter __begin, _IIter __end, _Predicate __pred)
{
- typedef std::iterator_traits<InputIterator> iterator_traits;
- typedef typename iterator_traits::iterator_category iterator_category;
- return find_if_switch(begin, end, pred, iterator_category());
+ typedef std::iterator_traits<_IIter> _IteratorTraits;
+ typedef typename _IteratorTraits::iterator_category _IteratorCategory;
+ return __find_if_switch(__begin, __end, __pred, _IteratorCategory());
}
// Sequential fallback
- template<typename InputIterator, typename ForwardIterator>
- inline InputIterator
- find_first_of(InputIterator begin1, InputIterator end1,
- ForwardIterator begin2, ForwardIterator end2,
+ template<typename _IIter, typename _FIterator>
+ inline _IIter
+ find_first_of(_IIter __begin1, _IIter __end1,
+ _FIterator __begin2, _FIterator __end2,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::find_first_of(begin1, end1, begin2, end2); }
+ { return _GLIBCXX_STD_P::find_first_of(__begin1, __end1, __begin2, __end2);
+ }
// Sequential fallback
- template<typename InputIterator, typename ForwardIterator,
- typename BinaryPredicate>
- inline InputIterator
- find_first_of(InputIterator begin1, InputIterator end1,
- ForwardIterator begin2, ForwardIterator end2,
- BinaryPredicate comp, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::find_first_of(begin1, end1, begin2, end2, comp); }
+ template<typename _IIter, typename _FIterator,
+ typename _BinaryPredicate>
+ inline _IIter
+ find_first_of(_IIter __begin1, _IIter __end1,
+ _FIterator __begin2, _FIterator __end2,
+ _BinaryPredicate __comp, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::find_first_of(
+ __begin1, __end1, __begin2, __end2, __comp); }
// Sequential fallback for input iterator type
- template<typename InputIterator, typename ForwardIterator,
- typename IteratorTag1, typename IteratorTag2>
- inline InputIterator
- find_first_of_switch(InputIterator begin1, InputIterator end1,
- ForwardIterator begin2, ForwardIterator end2,
- IteratorTag1, IteratorTag2)
- { return find_first_of(begin1, end1, begin2, end2,
+ template<typename _IIter, typename _FIterator,
+ typename _IteratorTag1, typename _IteratorTag2>
+ inline _IIter
+ __find_first_of_switch(_IIter __begin1, _IIter __end1,
+ _FIterator __begin2, _FIterator __end2,
+ _IteratorTag1, _IteratorTag2)
+ { return find_first_of(__begin1, __end1, __begin2, __end2,
__gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators
- template<typename RandomAccessIterator, typename ForwardIterator,
- typename BinaryPredicate, typename IteratorTag>
- inline RandomAccessIterator
- find_first_of_switch(RandomAccessIterator begin1,
- RandomAccessIterator end1,
- ForwardIterator begin2, ForwardIterator end2,
- BinaryPredicate comp, random_access_iterator_tag,
- IteratorTag)
+ template<typename _RAIter, typename _FIterator,
+ typename _BinaryPredicate, typename _IteratorTag>
+ inline _RAIter
+ __find_first_of_switch(_RAIter __begin1,
+ _RAIter __end1,
+ _FIterator __begin2, _FIterator __end2,
+ _BinaryPredicate __comp, random_access_iterator_tag,
+ _IteratorTag)
{
return __gnu_parallel::
- find_template(begin1, end1, begin1, comp,
- __gnu_parallel::find_first_of_selector
- <ForwardIterator>(begin2, end2)).first;
+ __find_template(__begin1, __end1, __begin1, __comp,
+ __gnu_parallel::__find_first_of_selector
+ <_FIterator>(__begin2, __end2)).first;
}
// Sequential fallback for input iterator type
- template<typename InputIterator, typename ForwardIterator,
- typename BinaryPredicate, typename IteratorTag1,
- typename IteratorTag2>
- inline InputIterator
- find_first_of_switch(InputIterator begin1, InputIterator end1,
- ForwardIterator begin2, ForwardIterator end2,
- BinaryPredicate comp, IteratorTag1, IteratorTag2)
- { return find_first_of(begin1, end1, begin2, end2, comp,
+ template<typename _IIter, typename _FIterator,
+ typename _BinaryPredicate, typename _IteratorTag1,
+ typename _IteratorTag2>
+ inline _IIter
+ __find_first_of_switch(_IIter __begin1, _IIter __end1,
+ _FIterator __begin2, _FIterator __end2,
+ _BinaryPredicate __comp, _IteratorTag1, _IteratorTag2)
+ { return find_first_of(__begin1, __end1, __begin2, __end2, __comp,
__gnu_parallel::sequential_tag()); }
// Public interface
- template<typename InputIterator, typename ForwardIterator,
- typename BinaryPredicate>
- inline InputIterator
- find_first_of(InputIterator begin1, InputIterator end1,
- ForwardIterator begin2, ForwardIterator end2,
- BinaryPredicate comp)
- {
- typedef std::iterator_traits<InputIterator> iteratori_traits;
- typedef std::iterator_traits<ForwardIterator> iteratorf_traits;
- typedef typename iteratori_traits::iterator_category iteratori_category;
+ template<typename _IIter, typename _FIterator,
+ typename _BinaryPredicate>
+ inline _IIter
+ find_first_of(_IIter __begin1, _IIter __end1,
+ _FIterator __begin2, _FIterator __end2,
+ _BinaryPredicate __comp)
+ {
+ typedef std::iterator_traits<_IIter> _IIterTraits;
+ typedef std::iterator_traits<_FIterator> iteratorf_traits;
+ typedef typename _IIterTraits::iterator_category _IIteratorCategory;
typedef typename iteratorf_traits::iterator_category iteratorf_category;
- return find_first_of_switch(begin1, end1, begin2, end2, comp,
- iteratori_category(), iteratorf_category());
+ return __find_first_of_switch(__begin1, __end1, __begin2, __end2, __comp,
+ _IIteratorCategory(), iteratorf_category());
}
// Public interface, insert default comparator
- template<typename InputIterator, typename ForwardIterator>
- inline InputIterator
- find_first_of(InputIterator begin1, InputIterator end1,
- ForwardIterator begin2, ForwardIterator end2)
+ template<typename _IIter, typename _FIterator>
+ inline _IIter
+ find_first_of(_IIter __begin1, _IIter __end1,
+ _FIterator __begin2, _FIterator __end2)
{
- typedef std::iterator_traits<InputIterator> iteratori_traits;
- typedef std::iterator_traits<ForwardIterator> iteratorf_traits;
- typedef typename iteratori_traits::value_type valuei_type;
- typedef typename iteratorf_traits::value_type valuef_type;
+ typedef std::iterator_traits<_IIter> _IIterTraits;
+ typedef std::iterator_traits<_FIterator> iteratorf_traits;
+ typedef typename _IIterTraits::value_type _IValueType;
+ typedef typename iteratorf_traits::value_type _FValueType;
- return find_first_of(begin1, end1, begin2, end2, __gnu_parallel::
- equal_to<valuei_type, valuef_type>());
+ return find_first_of(__begin1, __end1, __begin2, __end2, __gnu_parallel::
+ equal_to<_IValueType, _FValueType>());
}
// Sequential fallback
- template<typename InputIterator, typename OutputIterator>
- inline OutputIterator
- unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out,
+ template<typename _IIter, typename _OutputIterator>
+ inline _OutputIterator
+ unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::unique_copy(begin1, end1, out); }
+ { return _GLIBCXX_STD_P::unique_copy(__begin1, __end1, __out); }
// Sequential fallback
- template<typename InputIterator, typename OutputIterator,
- typename Predicate>
- inline OutputIterator
- unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out,
- Predicate pred, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::unique_copy(begin1, end1, out, pred); }
+ template<typename _IIter, typename _OutputIterator,
+ typename _Predicate>
+ inline _OutputIterator
+ unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
+ _Predicate __pred, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::unique_copy(__begin1, __end1, __out, __pred); }
// Sequential fallback for input iterator case
- template<typename InputIterator, typename OutputIterator,
- typename Predicate, typename IteratorTag1, typename IteratorTag2>
- inline OutputIterator
- unique_copy_switch(InputIterator begin, InputIterator last,
- OutputIterator out, Predicate pred,
- IteratorTag1, IteratorTag2)
- { return _GLIBCXX_STD_P::unique_copy(begin, last, out, pred); }
+ template<typename _IIter, typename _OutputIterator,
+ typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
+ inline _OutputIterator
+ __unique_copy_switch(_IIter __begin, _IIter __last,
+ _OutputIterator __out, _Predicate __pred,
+ _IteratorTag1, _IteratorTag2)
+ { return _GLIBCXX_STD_P::unique_copy(__begin, __last, __out, __pred); }
// Parallel unique_copy for random access iterators
- template<typename RandomAccessIterator, typename RandomAccessOutputIterator,
- typename Predicate>
+ template<typename _RAIter, typename RandomAccessOutputIterator,
+ typename _Predicate>
RandomAccessOutputIterator
- unique_copy_switch(RandomAccessIterator begin, RandomAccessIterator last,
- RandomAccessOutputIterator out, Predicate pred,
+ __unique_copy_switch(_RAIter __begin, _RAIter __last,
+ RandomAccessOutputIterator __out, _Predicate __pred,
random_access_iterator_tag, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(last - begin)
+ static_cast<__gnu_parallel::_SequenceIndex>(__last - __begin)
> __gnu_parallel::_Settings::get().unique_copy_minimal_n))
- return __gnu_parallel::parallel_unique_copy(begin, last, out, pred);
+ return __gnu_parallel::__parallel_unique_copy(
+ __begin, __last, __out, __pred);
else
- return _GLIBCXX_STD_P::unique_copy(begin, last, out, pred);
+ return _GLIBCXX_STD_P::unique_copy(__begin, __last, __out, __pred);
}
// Public interface
- template<typename InputIterator, typename OutputIterator>
- inline OutputIterator
- unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out)
+ template<typename _IIter, typename _OutputIterator>
+ inline _OutputIterator
+ unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out)
{
- typedef std::iterator_traits<InputIterator> iteratori_traits;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratori_traits::iterator_category iteratori_category;
- typedef typename iteratori_traits::value_type value_type;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
+ typedef std::iterator_traits<_IIter> _IIterTraits;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _IIterTraits::iterator_category _IIteratorCategory;
+ typedef typename _IIterTraits::value_type _ValueType;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
- return unique_copy_switch(begin1, end1, out, equal_to<value_type>(),
- iteratori_category(), iteratoro_category());
+ return __unique_copy_switch(
+ __begin1, __end1, __out, equal_to<_ValueType>(),
+ _IIteratorCategory(), _OIterCategory());
}
// Public interface
- template<typename InputIterator, typename OutputIterator, typename Predicate>
- inline OutputIterator
- unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out,
- Predicate pred)
+ template<typename _IIter, typename _OutputIterator, typename _Predicate>
+ inline _OutputIterator
+ unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
+ _Predicate __pred)
{
- typedef std::iterator_traits<InputIterator> iteratori_traits;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratori_traits::iterator_category iteratori_category;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
+ typedef std::iterator_traits<_IIter> _IIterTraits;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _IIterTraits::iterator_category _IIteratorCategory;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
- return unique_copy_switch(begin1, end1, out, pred, iteratori_category(),
- iteratoro_category());
+ return __unique_copy_switch(
+ __begin1, __end1, __out, __pred,
+ _IIteratorCategory(), _OIterCategory());
}
// Sequential fallback
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator>
- inline OutputIterator
- set_union(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::set_union(begin1, end1, begin2, end2, out); }
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator>
+ inline _OutputIterator
+ set_union(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::set_union(
+ __begin1, __end1, __begin2, __end2, __out); }
// Sequential fallback
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename Predicate>
- inline OutputIterator
- set_union(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out, Predicate pred,
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _Predicate>
+ inline _OutputIterator
+ set_union(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::set_union(begin1, end1,
- begin2, end2, out, pred); }
+ { return _GLIBCXX_STD_P::set_union(__begin1, __end1,
+ __begin2, __end2, __out, __pred); }
// Sequential fallback for input iterator case
- template<typename InputIterator1, typename InputIterator2,
- typename Predicate, typename OutputIterator,
- typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
- inline OutputIterator
- set_union_switch(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator result, Predicate pred, IteratorTag1,
- IteratorTag2, IteratorTag3)
- { return _GLIBCXX_STD_P::set_union(begin1, end1,
- begin2, end2, result, pred); }
+ template<typename _IIter1, typename _IIter2, typename _Predicate,
+ typename _OutputIterator, typename _IteratorTag1,
+ typename _IteratorTag2, typename _IteratorTag3>
+ inline _OutputIterator
+ __set_union_switch(
+ _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __result, _Predicate __pred,
+ _IteratorTag1, _IteratorTag2, _IteratorTag3)
+ { return _GLIBCXX_STD_P::set_union(__begin1, __end1,
+ __begin2, __end2, __result, __pred); }
// Parallel set_union for random access iterators
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename OutputRandomAccessIterator, typename Predicate>
- OutputRandomAccessIterator
- set_union_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2, RandomAccessIterator2 end2,
- OutputRandomAccessIterator result, Predicate pred,
+ template<typename _RAIter1, typename _RAIter2,
+ typename _Output_RAIter, typename _Predicate>
+ _Output_RAIter
+ __set_union_switch(_RAIter1 __begin1, _RAIter1 __end1,
+ _RAIter2 __begin2, _RAIter2 __end2,
+ _Output_RAIter __result, _Predicate __pred,
random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
+ static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
>= __gnu_parallel::_Settings::get().set_union_minimal_n
- || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
+ || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
>= __gnu_parallel::_Settings::get().set_union_minimal_n))
- return __gnu_parallel::parallel_set_union(begin1, end1,
- begin2, end2, result, pred);
+ return __gnu_parallel::__parallel_set_union(
+ __begin1, __end1, __begin2, __end2, __result, __pred);
else
- return _GLIBCXX_STD_P::set_union(begin1, end1,
- begin2, end2, result, pred);
+ return _GLIBCXX_STD_P::set_union(__begin1, __end1,
+ __begin2, __end2, __result, __pred);
}
// Public interface
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator>
- inline OutputIterator
- set_union(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2, OutputIterator out)
- {
- typedef std::iterator_traits<InputIterator1> iteratori1_traits;
- typedef std::iterator_traits<InputIterator2> iteratori2_traits;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratori1_traits::iterator_category
- iteratori1_category;
- typedef typename iteratori2_traits::iterator_category
- iteratori2_category;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
- typedef typename iteratori1_traits::value_type value1_type;
- typedef typename iteratori2_traits::value_type value2_type;
-
- return set_union_switch(begin1, end1, begin2, end2, out,
- __gnu_parallel::less<value1_type, value2_type>(),
- iteratori1_category(), iteratori2_category(),
- iteratoro_category());
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator>
+ inline _OutputIterator
+ set_union(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out)
+ {
+ typedef std::iterator_traits<_IIter1> _IIterTraits1;
+ typedef std::iterator_traits<_IIter2> _IIterTraits2;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _IIterTraits1::iterator_category
+ _IIterCategory1;
+ typedef typename _IIterTraits2::iterator_category
+ _IIterCategory2;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
+ typedef typename _IIterTraits1::value_type _ValueType1;
+ typedef typename _IIterTraits2::value_type _ValueType2;
+
+ return __set_union_switch(
+ __begin1, __end1, __begin2, __end2, __out,
+ __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
+ _IIterCategory1(), _IIterCategory2(), _OIterCategory());
}
// Public interface
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename Predicate>
- inline OutputIterator
- set_union(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out, Predicate pred)
- {
- typedef std::iterator_traits<InputIterator1> iteratori1_traits;
- typedef std::iterator_traits<InputIterator2> iteratori2_traits;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratori1_traits::iterator_category
- iteratori1_category;
- typedef typename iteratori2_traits::iterator_category
- iteratori2_category;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
-
- return set_union_switch(begin1, end1, begin2, end2, out, pred,
- iteratori1_category(), iteratori2_category(),
- iteratoro_category());
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _Predicate>
+ inline _OutputIterator
+ set_union(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred)
+ {
+ typedef std::iterator_traits<_IIter1> _IIterTraits1;
+ typedef std::iterator_traits<_IIter2> _IIterTraits2;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _IIterTraits1::iterator_category
+ _IIterCategory1;
+ typedef typename _IIterTraits2::iterator_category
+ _IIterCategory2;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
+
+ return __set_union_switch(
+ __begin1, __end1, __begin2, __end2, __out, __pred,
+ _IIterCategory1(), _IIterCategory2(), _OIterCategory());
}
// Sequential fallback.
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator>
- inline OutputIterator
- set_intersection(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::set_intersection(begin1, end1,
- begin2, end2, out); }
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator>
+ inline _OutputIterator
+ set_intersection(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::set_intersection(__begin1, __end1,
+ __begin2, __end2, __out); }
// Sequential fallback.
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename Predicate>
- inline OutputIterator
- set_intersection(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out, Predicate pred,
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _Predicate>
+ inline _OutputIterator
+ set_intersection(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::set_intersection(begin1, end1, begin2, end2,
- out, pred); }
+ { return _GLIBCXX_STD_P::set_intersection(
+ __begin1, __end1, __begin2, __end2, __out, __pred); }
// Sequential fallback for input iterator case
- template<typename InputIterator1, typename InputIterator2,
- typename Predicate, typename OutputIterator,
- typename IteratorTag1, typename IteratorTag2,
- typename IteratorTag3>
- inline OutputIterator
- set_intersection_switch(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator result, Predicate pred,
- IteratorTag1, IteratorTag2, IteratorTag3)
- { return _GLIBCXX_STD_P::set_intersection(begin1, end1, begin2,
- end2, result, pred); }
+ template<typename _IIter1, typename _IIter2,
+ typename _Predicate, typename _OutputIterator,
+ typename _IteratorTag1, typename _IteratorTag2,
+ typename _IteratorTag3>
+ inline _OutputIterator
+ __set_intersection_switch(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __result, _Predicate __pred,
+ _IteratorTag1, _IteratorTag2, _IteratorTag3)
+ { return _GLIBCXX_STD_P::set_intersection(__begin1, __end1, __begin2,
+ __end2, __result, __pred); }
// Parallel set_intersection for random access iterators
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename OutputRandomAccessIterator, typename Predicate>
- OutputRandomAccessIterator
- set_intersection_switch(RandomAccessIterator1 begin1,
- RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2,
- RandomAccessIterator2 end2,
- OutputRandomAccessIterator result,
- Predicate pred,
+ template<typename _RAIter1, typename _RAIter2,
+ typename _Output_RAIter, typename _Predicate>
+ _Output_RAIter
+ __set_intersection_switch(_RAIter1 __begin1,
+ _RAIter1 __end1,
+ _RAIter2 __begin2,
+ _RAIter2 __end2,
+ _Output_RAIter __result,
+ _Predicate __pred,
random_access_iterator_tag,
random_access_iterator_tag,
random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
+ static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
>= __gnu_parallel::_Settings::get().set_union_minimal_n
- || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
+ || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
>= __gnu_parallel::_Settings::get().set_union_minimal_n))
- return __gnu_parallel::parallel_set_intersection(begin1, end1, begin2,
- end2, result, pred);
+ return __gnu_parallel::__parallel_set_intersection(
+ __begin1, __end1, __begin2, __end2, __result, __pred);
else
- return _GLIBCXX_STD_P::set_intersection(begin1, end1, begin2,
- end2, result, pred);
+ return _GLIBCXX_STD_P::set_intersection(
+ __begin1, __end1, __begin2, __end2, __result, __pred);
}
// Public interface
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator>
- inline OutputIterator
- set_intersection(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out)
- {
- typedef std::iterator_traits<InputIterator1> iteratori1_traits;
- typedef std::iterator_traits<InputIterator2> iteratori2_traits;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratori1_traits::iterator_category
- iteratori1_category;
- typedef typename iteratori2_traits::iterator_category
- iteratori2_category;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
- typedef typename iteratori1_traits::value_type value1_type;
- typedef typename iteratori2_traits::value_type value2_type;
-
- return set_intersection_switch(begin1, end1, begin2, end2, out,
- __gnu_parallel::
- less<value1_type, value2_type>(),
- iteratori1_category(),
- iteratori2_category(),
- iteratoro_category());
- }
-
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename Predicate>
- inline OutputIterator
- set_intersection(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out, Predicate pred)
- {
- typedef std::iterator_traits<InputIterator1> iteratori1_traits;
- typedef std::iterator_traits<InputIterator2> iteratori2_traits;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratori1_traits::iterator_category
- iteratori1_category;
- typedef typename iteratori2_traits::iterator_category
- iteratori2_category;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
-
- return set_intersection_switch(begin1, end1, begin2, end2, out, pred,
- iteratori1_category(),
- iteratori2_category(),
- iteratoro_category());
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator>
+ inline _OutputIterator
+ set_intersection(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out)
+ {
+ typedef std::iterator_traits<_IIter1> _IIterTraits1;
+ typedef std::iterator_traits<_IIter2> _IIterTraits2;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _IIterTraits1::iterator_category
+ _IIterCategory1;
+ typedef typename _IIterTraits2::iterator_category
+ _IIterCategory2;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
+ typedef typename _IIterTraits1::value_type _ValueType1;
+ typedef typename _IIterTraits2::value_type _ValueType2;
+
+ return __set_intersection_switch(
+ __begin1, __end1, __begin2, __end2, __out,
+ __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
+ _IIterCategory1(), _IIterCategory2(), _OIterCategory());
+ }
+
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _Predicate>
+ inline _OutputIterator
+ set_intersection(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred)
+ {
+ typedef std::iterator_traits<_IIter1> _IIterTraits1;
+ typedef std::iterator_traits<_IIter2> _IIterTraits2;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _IIterTraits1::iterator_category
+ _IIterCategory1;
+ typedef typename _IIterTraits2::iterator_category
+ _IIterCategory2;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
+
+ return __set_intersection_switch(
+ __begin1, __end1, __begin2, __end2, __out, __pred,
+ _IIterCategory1(), _IIterCategory2(), _OIterCategory());
}
// Sequential fallback
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator>
- inline OutputIterator
- set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out,
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator>
+ inline _OutputIterator
+ set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::set_symmetric_difference(begin1,end1,
- begin2, end2, out); }
+ { return _GLIBCXX_STD_P::set_symmetric_difference(
+ __begin1, __end1, __begin2, __end2, __out); }
// Sequential fallback
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename Predicate>
- inline OutputIterator
- set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out, Predicate pred,
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _Predicate>
+ inline _OutputIterator
+ set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::set_symmetric_difference(begin1, end1, begin2,
- end2, out, pred); }
+ { return _GLIBCXX_STD_P::set_symmetric_difference(
+ __begin1, __end1, __begin2, __end2, __out, __pred); }
// Sequential fallback for input iterator case
- template<typename InputIterator1, typename InputIterator2,
- typename Predicate, typename OutputIterator,
- typename IteratorTag1, typename IteratorTag2,
- typename IteratorTag3>
- inline OutputIterator
- set_symmetric_difference_switch(InputIterator1 begin1,
- InputIterator1 end1,
- InputIterator2 begin2,
- InputIterator2 end2,
- OutputIterator result, Predicate pred,
- IteratorTag1, IteratorTag2, IteratorTag3)
- { return _GLIBCXX_STD_P::set_symmetric_difference(begin1, end1,
- begin2, end2,
- result, pred); }
+ template<typename _IIter1, typename _IIter2,
+ typename _Predicate, typename _OutputIterator,
+ typename _IteratorTag1, typename _IteratorTag2,
+ typename _IteratorTag3>
+ inline _OutputIterator
+ __set_symmetric_difference_switch(
+ _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __result, _Predicate __pred,
+ _IteratorTag1, _IteratorTag2, _IteratorTag3)
+ { return _GLIBCXX_STD_P::set_symmetric_difference(
+ __begin1, __end1, __begin2, __end2, __result, __pred); }
// Parallel set_symmetric_difference for random access iterators
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename OutputRandomAccessIterator, typename Predicate>
- OutputRandomAccessIterator
- set_symmetric_difference_switch(RandomAccessIterator1 begin1,
- RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2,
- RandomAccessIterator2 end2,
- OutputRandomAccessIterator result,
- Predicate pred,
+ template<typename _RAIter1, typename _RAIter2,
+ typename _Output_RAIter, typename _Predicate>
+ _Output_RAIter
+ __set_symmetric_difference_switch(_RAIter1 __begin1,
+ _RAIter1 __end1,
+ _RAIter2 __begin2,
+ _RAIter2 __end2,
+ _Output_RAIter __result,
+ _Predicate __pred,
random_access_iterator_tag,
random_access_iterator_tag,
random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
+ static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
>= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n
- || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
+ || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
>= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n))
- return __gnu_parallel::parallel_set_symmetric_difference(begin1, end1,
- begin2, end2,
- result, pred);
+ return __gnu_parallel::__parallel_set_symmetric_difference(
+ __begin1, __end1, __begin2, __end2, __result, __pred);
else
- return _GLIBCXX_STD_P::set_symmetric_difference(begin1, end1,
- begin2, end2,
- result, pred);
+ return _GLIBCXX_STD_P::set_symmetric_difference(
+ __begin1, __end1, __begin2, __end2, __result, __pred);
}
// Public interface.
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator>
- inline OutputIterator
- set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out)
- {
- typedef std::iterator_traits<InputIterator1> iteratori1_traits;
- typedef std::iterator_traits<InputIterator2> iteratori2_traits;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratori1_traits::iterator_category
- iteratori1_category;
- typedef typename iteratori2_traits::iterator_category
- iteratori2_category;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
- typedef typename iteratori1_traits::value_type value1_type;
- typedef typename iteratori2_traits::value_type value2_type;
-
- return set_symmetric_difference_switch(begin1, end1, begin2, end2, out,
- __gnu_parallel::
- less<value1_type, value2_type>(),
- iteratori1_category(),
- iteratori2_category(),
- iteratoro_category());
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator>
+ inline _OutputIterator
+ set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out)
+ {
+ typedef std::iterator_traits<_IIter1> _IIterTraits1;
+ typedef std::iterator_traits<_IIter2> _IIterTraits2;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _IIterTraits1::iterator_category
+ _IIterCategory1;
+ typedef typename _IIterTraits2::iterator_category
+ _IIterCategory2;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
+ typedef typename _IIterTraits1::value_type _ValueType1;
+ typedef typename _IIterTraits2::value_type _ValueType2;
+
+ return __set_symmetric_difference_switch(
+ __begin1, __end1, __begin2, __end2, __out,
+ __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
+ _IIterCategory1(), _IIterCategory2(), _OIterCategory());
}
// Public interface.
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename Predicate>
- inline OutputIterator
- set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out, Predicate pred)
- {
- typedef std::iterator_traits<InputIterator1> iteratori1_traits;
- typedef std::iterator_traits<InputIterator2> iteratori2_traits;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratori1_traits::iterator_category
- iteratori1_category;
- typedef typename iteratori2_traits::iterator_category
- iteratori2_category;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
-
- return set_symmetric_difference_switch(begin1, end1, begin2, end2, out,
- pred, iteratori1_category(),
- iteratori2_category(),
- iteratoro_category());
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _Predicate>
+ inline _OutputIterator
+ set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred)
+ {
+ typedef std::iterator_traits<_IIter1> _IIterTraits1;
+ typedef std::iterator_traits<_IIter2> _IIterTraits2;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _IIterTraits1::iterator_category
+ _IIterCategory1;
+ typedef typename _IIterTraits2::iterator_category
+ _IIterCategory2;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
+
+ return __set_symmetric_difference_switch(
+ __begin1, __end1, __begin2, __end2, __out, __pred,
+ _IIterCategory1(), _IIterCategory2(), _OIterCategory());
}
// Sequential fallback.
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator>
- inline OutputIterator
- set_difference(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::set_difference(begin1,end1, begin2, end2, out); }
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator>
+ inline _OutputIterator
+ set_difference(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::set_difference(
+ __begin1,__end1, __begin2, __end2, __out); }
// Sequential fallback.
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename Predicate>
- inline OutputIterator
- set_difference(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out, Predicate pred,
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _Predicate>
+ inline _OutputIterator
+ set_difference(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::set_difference(begin1, end1,
- begin2, end2, out, pred); }
+ { return _GLIBCXX_STD_P::set_difference(__begin1, __end1,
+ __begin2, __end2, __out, __pred); }
// Sequential fallback for input iterator case.
- template<typename InputIterator1, typename InputIterator2,
- typename Predicate, typename OutputIterator,
- typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
- inline OutputIterator
- set_difference_switch(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator result, Predicate pred,
- IteratorTag1, IteratorTag2, IteratorTag3)
- { return _GLIBCXX_STD_P::set_difference(begin1, end1,
- begin2, end2, result, pred); }
+ template<typename _IIter1, typename _IIter2, typename _Predicate,
+ typename _OutputIterator, typename _IteratorTag1,
+ typename _IteratorTag2, typename _IteratorTag3>
+ inline _OutputIterator
+ __set_difference_switch(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __result, _Predicate __pred,
+ _IteratorTag1, _IteratorTag2, _IteratorTag3)
+ { return _GLIBCXX_STD_P::set_difference(
+ __begin1, __end1, __begin2, __end2, __result, __pred); }
// Parallel set_difference for random access iterators
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename OutputRandomAccessIterator, typename Predicate>
- OutputRandomAccessIterator
- set_difference_switch(RandomAccessIterator1 begin1,
- RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2,
- RandomAccessIterator2 end2,
- OutputRandomAccessIterator result, Predicate pred,
+ template<typename _RAIter1, typename _RAIter2,
+ typename _Output_RAIter, typename _Predicate>
+ _Output_RAIter
+ __set_difference_switch(_RAIter1 __begin1,
+ _RAIter1 __end1,
+ _RAIter2 __begin2,
+ _RAIter2 __end2,
+ _Output_RAIter __result, _Predicate __pred,
random_access_iterator_tag,
random_access_iterator_tag,
random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
+ static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
>= __gnu_parallel::_Settings::get().set_difference_minimal_n
- || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
+ || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
>= __gnu_parallel::_Settings::get().set_difference_minimal_n))
- return __gnu_parallel::parallel_set_difference(begin1, end1,
- begin2, end2,
- result, pred);
+ return __gnu_parallel::__parallel_set_difference(
+ __begin1, __end1, __begin2, __end2, __result, __pred);
else
- return _GLIBCXX_STD_P::set_difference(begin1, end1,
- begin2, end2, result, pred);
+ return _GLIBCXX_STD_P::set_difference(
+ __begin1, __end1, __begin2, __end2, __result, __pred);
}
// Public interface
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator>
- inline OutputIterator
- set_difference(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out)
- {
- typedef std::iterator_traits<InputIterator1> iteratori1_traits;
- typedef std::iterator_traits<InputIterator2> iteratori2_traits;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratori1_traits::iterator_category
- iteratori1_category;
- typedef typename iteratori2_traits::iterator_category
- iteratori2_category;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
- typedef typename iteratori1_traits::value_type value1_type;
- typedef typename iteratori2_traits::value_type value2_type;
-
- return set_difference_switch(begin1, end1, begin2, end2, out,
- __gnu_parallel::
- less<value1_type, value2_type>(),
- iteratori1_category(),
- iteratori2_category(),
- iteratoro_category());
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator>
+ inline _OutputIterator
+ set_difference(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out)
+ {
+ typedef std::iterator_traits<_IIter1> _IIterTraits1;
+ typedef std::iterator_traits<_IIter2> _IIterTraits2;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _IIterTraits1::iterator_category
+ _IIterCategory1;
+ typedef typename _IIterTraits2::iterator_category
+ _IIterCategory2;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
+ typedef typename _IIterTraits1::value_type _ValueType1;
+ typedef typename _IIterTraits2::value_type _ValueType2;
+
+ return __set_difference_switch(
+ __begin1, __end1, __begin2, __end2, __out,
+ __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
+ _IIterCategory1(), _IIterCategory2(), _OIterCategory());
}
// Public interface
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename Predicate>
- inline OutputIterator
- set_difference(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out, Predicate pred)
- {
- typedef std::iterator_traits<InputIterator1> iteratori1_traits;
- typedef std::iterator_traits<InputIterator2> iteratori2_traits;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratori1_traits::iterator_category
- iteratori1_category;
- typedef typename iteratori2_traits::iterator_category
- iteratori2_category;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
-
- return set_difference_switch(begin1, end1, begin2, end2, out, pred,
- iteratori1_category(),
- iteratori2_category(),
- iteratoro_category());
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _Predicate>
+ inline _OutputIterator
+ set_difference(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __out, _Predicate __pred)
+ {
+ typedef std::iterator_traits<_IIter1> _IIterTraits1;
+ typedef std::iterator_traits<_IIter2> _IIterTraits2;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _IIterTraits1::iterator_category
+ _IIterCategory1;
+ typedef typename _IIterTraits2::iterator_category
+ _IIterCategory2;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
+
+ return __set_difference_switch(
+ __begin1, __end1, __begin2, __end2, __out, __pred,
+ _IIterCategory1(), _IIterCategory2(), _OIterCategory());
}
// Sequential fallback
- template<typename ForwardIterator>
- inline ForwardIterator
- adjacent_find(ForwardIterator begin, ForwardIterator end,
+ template<typename _FIterator>
+ inline _FIterator
+ adjacent_find(_FIterator __begin, _FIterator __end,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::adjacent_find(begin, end); }
+ { return _GLIBCXX_STD_P::adjacent_find(__begin, __end); }
// Sequential fallback
- template<typename ForwardIterator, typename BinaryPredicate>
- inline ForwardIterator
- adjacent_find(ForwardIterator begin, ForwardIterator end,
- BinaryPredicate binary_pred, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::adjacent_find(begin, end, binary_pred); }
+ template<typename _FIterator, typename _BinaryPredicate>
+ inline _FIterator
+ adjacent_find(_FIterator __begin, _FIterator __end,
+ _BinaryPredicate __binary_pred,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::adjacent_find(__begin, __end, __binary_pred); }
// Parallel algorithm for random access iterators
- template<typename RandomAccessIterator>
- RandomAccessIterator
- adjacent_find_switch(RandomAccessIterator begin, RandomAccessIterator end,
+ template<typename _RAIter>
+ _RAIter
+ __adjacent_find_switch(_RAIter __begin, _RAIter __end,
random_access_iterator_tag)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
if (_GLIBCXX_PARALLEL_CONDITION(true))
{
- RandomAccessIterator spot = __gnu_parallel::
- find_template(begin, end - 1, begin, equal_to<value_type>(),
- __gnu_parallel::adjacent_find_selector()).first;
- if (spot == (end - 1))
- return end;
+ _RAIter spot = __gnu_parallel::
+ __find_template(
+ __begin, __end - 1, __begin, equal_to<_ValueType>(),
+ __gnu_parallel::__adjacent_find_selector())
+ .first;
+ if (spot == (__end - 1))
+ return __end;
else
return spot;
}
else
- return adjacent_find(begin, end, __gnu_parallel::sequential_tag());
+ return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case
- template<typename ForwardIterator, typename IteratorTag>
- inline ForwardIterator
- adjacent_find_switch(ForwardIterator begin, ForwardIterator end,
- IteratorTag)
- { return adjacent_find(begin, end, __gnu_parallel::sequential_tag()); }
+ template<typename _FIterator, typename _IteratorTag>
+ inline _FIterator
+ __adjacent_find_switch(_FIterator __begin, _FIterator __end,
+ _IteratorTag)
+ { return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag()); }
// Public interface
- template<typename ForwardIterator>
- inline ForwardIterator
- adjacent_find(ForwardIterator begin, ForwardIterator end)
+ template<typename _FIterator>
+ inline _FIterator
+ adjacent_find(_FIterator __begin, _FIterator __end)
{
- typedef iterator_traits<ForwardIterator> traits_type;
- typedef typename traits_type::iterator_category iterator_category;
- return adjacent_find_switch(begin, end, iterator_category());
+ typedef iterator_traits<_FIterator> _TraitsType;
+ typedef typename _TraitsType::iterator_category _IteratorCategory;
+ return __adjacent_find_switch(__begin, __end, _IteratorCategory());
}
// Sequential fallback for input iterator case
- template<typename ForwardIterator, typename BinaryPredicate,
- typename IteratorTag>
- inline ForwardIterator
- adjacent_find_switch(ForwardIterator begin, ForwardIterator end,
- BinaryPredicate pred, IteratorTag)
- { return adjacent_find(begin, end, pred,
+ template<typename _FIterator, typename _BinaryPredicate,
+ typename _IteratorTag>
+ inline _FIterator
+ __adjacent_find_switch(_FIterator __begin, _FIterator __end,
+ _BinaryPredicate __pred, _IteratorTag)
+ { return adjacent_find(__begin, __end, __pred,
__gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators
- template<typename RandomAccessIterator, typename BinaryPredicate>
- RandomAccessIterator
- adjacent_find_switch(RandomAccessIterator begin, RandomAccessIterator end,
- BinaryPredicate pred, random_access_iterator_tag)
+ template<typename _RAIter, typename _BinaryPredicate>
+ _RAIter
+ __adjacent_find_switch(_RAIter __begin, _RAIter __end,
+ _BinaryPredicate __pred, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(true))
- return __gnu_parallel::find_template(begin, end, begin, pred,
+ return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
__gnu_parallel::
- adjacent_find_selector()).first;
+ __adjacent_find_selector()).first;
else
- return adjacent_find(begin, end, pred,
+ return adjacent_find(__begin, __end, __pred,
__gnu_parallel::sequential_tag());
}
// Public interface
- template<typename ForwardIterator, typename BinaryPredicate>
- inline ForwardIterator
- adjacent_find(ForwardIterator begin, ForwardIterator end,
- BinaryPredicate pred)
+ template<typename _FIterator, typename _BinaryPredicate>
+ inline _FIterator
+ adjacent_find(_FIterator __begin, _FIterator __end,
+ _BinaryPredicate __pred)
{
- typedef iterator_traits<ForwardIterator> traits_type;
- typedef typename traits_type::iterator_category iterator_category;
- return adjacent_find_switch(begin, end, pred, iterator_category());
+ typedef iterator_traits<_FIterator> _TraitsType;
+ typedef typename _TraitsType::iterator_category _IteratorCategory;
+ return __adjacent_find_switch(__begin, __end, __pred,
+ _IteratorCategory());
}
// Sequential fallback
- template<typename InputIterator, typename T>
- inline typename iterator_traits<InputIterator>::difference_type
- count(InputIterator begin, InputIterator end, const T& value,
+ template<typename _IIter, typename _Tp>
+ inline typename iterator_traits<_IIter>::difference_type
+ count(_IIter __begin, _IIter __end, const _Tp& __value,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::count(begin, end, value); }
+ { return _GLIBCXX_STD_P::count(__begin, __end, __value); }
// Parallel code for random access iterators
- template<typename RandomAccessIterator, typename T>
- typename iterator_traits<RandomAccessIterator>::difference_type
- count_switch(RandomAccessIterator begin, RandomAccessIterator end,
- const T& value, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism_tag
+ template<typename _RAIter, typename _Tp>
+ typename iterator_traits<_RAIter>::difference_type
+ __count_switch(_RAIter __begin, _RAIter __end,
+ const _Tp& __value, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag
= __gnu_parallel::parallel_unbalanced)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
- typedef __gnu_parallel::sequence_index_t sequence_index_t;
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
+ typedef __gnu_parallel::_SequenceIndex _SequenceIndex;
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<sequence_index_t>(end - begin)
+ static_cast<_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().count_minimal_n
- && __gnu_parallel::is_parallel(parallelism_tag)))
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
{
- __gnu_parallel::count_selector<RandomAccessIterator, difference_type>
- functionality;
- difference_type res = 0;
+ __gnu_parallel::__count_selector<_RAIter, _DifferenceType>
+ __functionality;
+ _DifferenceType __res = 0;
__gnu_parallel::
- for_each_template_random_access(begin, end, value,
- functionality,
- std::plus<sequence_index_t>(),
- res, res, -1, parallelism_tag);
- return res;
+ __for_each_template_random_access(
+ __begin, __end, __value, __functionality,
+ std::plus<_SequenceIndex>(), __res, __res, -1,
+ __parallelism_tag);
+ return __res;
}
else
- return count(begin, end, value, __gnu_parallel::sequential_tag());
+ return count(__begin, __end, __value,
+ __gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case.
- template<typename InputIterator, typename T, typename IteratorTag>
- inline typename iterator_traits<InputIterator>::difference_type
- count_switch(InputIterator begin, InputIterator end, const T& value,
- IteratorTag)
- { return count(begin, end, value, __gnu_parallel::sequential_tag()); }
+ template<typename _IIter, typename _Tp, typename _IteratorTag>
+ inline typename iterator_traits<_IIter>::difference_type
+ __count_switch(_IIter __begin, _IIter __end, const _Tp& __value,
+ _IteratorTag)
+ { return count(__begin, __end, __value, __gnu_parallel::sequential_tag());
+ }
// Public interface.
- template<typename InputIterator, typename T>
- inline typename iterator_traits<InputIterator>::difference_type
- count(InputIterator begin, InputIterator end, const T& value,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _IIter, typename _Tp>
+ inline typename iterator_traits<_IIter>::difference_type
+ count(_IIter __begin, _IIter __end, const _Tp& __value,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::iterator_category iterator_category;
- return count_switch(begin, end, value, iterator_category(),
- parallelism_tag);
+ typedef iterator_traits<_IIter> _TraitsType;
+ typedef typename _TraitsType::iterator_category _IteratorCategory;
+ return __count_switch(__begin, __end, __value, _IteratorCategory(),
+ __parallelism_tag);
}
- template<typename InputIterator, typename T>
- inline typename iterator_traits<InputIterator>::difference_type
- count(InputIterator begin, InputIterator end, const T& value)
+ template<typename _IIter, typename _Tp>
+ inline typename iterator_traits<_IIter>::difference_type
+ count(_IIter __begin, _IIter __end, const _Tp& __value)
{
- typedef iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::iterator_category iterator_category;
- return count_switch(begin, end, value, iterator_category());
+ typedef iterator_traits<_IIter> _TraitsType;
+ typedef typename _TraitsType::iterator_category _IteratorCategory;
+ return __count_switch(__begin, __end, __value, _IteratorCategory());
}
// Sequential fallback.
- template<typename InputIterator, typename Predicate>
- inline typename iterator_traits<InputIterator>::difference_type
- count_if(InputIterator begin, InputIterator end, Predicate pred,
+ template<typename _IIter, typename _Predicate>
+ inline typename iterator_traits<_IIter>::difference_type
+ count_if(_IIter __begin, _IIter __end, _Predicate __pred,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::count_if(begin, end, pred); }
+ { return _GLIBCXX_STD_P::count_if(__begin, __end, __pred); }
// Parallel count_if for random access iterators
- template<typename RandomAccessIterator, typename Predicate>
- typename iterator_traits<RandomAccessIterator>::difference_type
- count_if_switch(RandomAccessIterator begin, RandomAccessIterator end,
- Predicate pred, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism_tag
+ template<typename _RAIter, typename _Predicate>
+ typename iterator_traits<_RAIter>::difference_type
+ __count_if_switch(_RAIter __begin, _RAIter __end,
+ _Predicate __pred, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag
= __gnu_parallel::parallel_unbalanced)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
- typedef __gnu_parallel::sequence_index_t sequence_index_t;
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
+ typedef __gnu_parallel::_SequenceIndex _SequenceIndex;
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<sequence_index_t>(end - begin)
+ static_cast<_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().count_minimal_n
- && __gnu_parallel::is_parallel(parallelism_tag)))
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
{
- difference_type res = 0;
+ _DifferenceType __res = 0;
__gnu_parallel::
- count_if_selector<RandomAccessIterator, difference_type>
- functionality;
+ __count_if_selector<_RAIter, _DifferenceType>
+ __functionality;
__gnu_parallel::
- for_each_template_random_access(begin, end, pred,
- functionality,
- std::plus<sequence_index_t>(),
- res, res, -1, parallelism_tag);
- return res;
+ __for_each_template_random_access(
+ __begin, __end, __pred, __functionality,
+ std::plus<_SequenceIndex>(), __res, __res, -1,
+ __parallelism_tag);
+ return __res;
}
else
- return count_if(begin, end, pred, __gnu_parallel::sequential_tag());
+ return count_if(__begin, __end, __pred,
+ __gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case.
- template<typename InputIterator, typename Predicate, typename IteratorTag>
- inline typename iterator_traits<InputIterator>::difference_type
- count_if_switch(InputIterator begin, InputIterator end, Predicate pred,
- IteratorTag)
- { return count_if(begin, end, pred, __gnu_parallel::sequential_tag()); }
+ template<typename _IIter, typename _Predicate, typename _IteratorTag>
+ inline typename iterator_traits<_IIter>::difference_type
+ __count_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
+ _IteratorTag)
+ { return count_if(__begin, __end, __pred,
+ __gnu_parallel::sequential_tag()); }
// Public interface.
- template<typename InputIterator, typename Predicate>
- inline typename iterator_traits<InputIterator>::difference_type
- count_if(InputIterator begin, InputIterator end, Predicate pred,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _IIter, typename _Predicate>
+ inline typename iterator_traits<_IIter>::difference_type
+ count_if(_IIter __begin, _IIter __end, _Predicate __pred,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::iterator_category iterator_category;
- return count_if_switch(begin, end, pred, iterator_category(),
- parallelism_tag);
+ typedef iterator_traits<_IIter> _TraitsType;
+ typedef typename _TraitsType::iterator_category _IteratorCategory;
+ return __count_if_switch(__begin, __end, __pred, _IteratorCategory(),
+ __parallelism_tag);
}
- template<typename InputIterator, typename Predicate>
- inline typename iterator_traits<InputIterator>::difference_type
- count_if(InputIterator begin, InputIterator end, Predicate pred)
+ template<typename _IIter, typename _Predicate>
+ inline typename iterator_traits<_IIter>::difference_type
+ count_if(_IIter __begin, _IIter __end, _Predicate __pred)
{
- typedef iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::iterator_category iterator_category;
- return count_if_switch(begin, end, pred, iterator_category());
+ typedef iterator_traits<_IIter> _TraitsType;
+ typedef typename _TraitsType::iterator_category _IteratorCategory;
+ return __count_if_switch(__begin, __end, __pred, _IteratorCategory());
}
// Sequential fallback.
- template<typename ForwardIterator1, typename ForwardIterator2>
- inline ForwardIterator1
- search(ForwardIterator1 begin1, ForwardIterator1 end1,
- ForwardIterator2 begin2, ForwardIterator2 end2,
+ template<typename _FIterator1, typename _FIterator2>
+ inline _FIterator1
+ search(_FIterator1 __begin1, _FIterator1 __end1,
+ _FIterator2 __begin2, _FIterator2 __end2,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::search(begin1, end1, begin2, end2); }
+ { return _GLIBCXX_STD_P::search(__begin1, __end1, __begin2, __end2); }
// Parallel algorithm for random access iterator
- template<typename RandomAccessIterator1, typename RandomAccessIterator2>
- RandomAccessIterator1
- search_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2, RandomAccessIterator2 end2,
+ template<typename _RAIter1, typename _RAIter2>
+ _RAIter1
+ __search_switch(_RAIter1 __begin1, _RAIter1 __end1,
+ _RAIter2 __begin2, _RAIter2 __end2,
random_access_iterator_tag, random_access_iterator_tag)
{
- typedef std::iterator_traits<RandomAccessIterator1> iterator1_traits;
- typedef typename iterator1_traits::value_type value1_type;
- typedef std::iterator_traits<RandomAccessIterator2> iterator2_traits;
- typedef typename iterator2_traits::value_type value2_type;
+ typedef std::iterator_traits<_RAIter1> iterator1_traits;
+ typedef typename iterator1_traits::value_type _ValueType1;
+ typedef std::iterator_traits<_RAIter2> iterator2_traits;
+ typedef typename iterator2_traits::value_type _ValueType2;
if (_GLIBCXX_PARALLEL_CONDITION(true))
return __gnu_parallel::
- search_template(begin1, end1, begin2, end2, __gnu_parallel::
- equal_to<value1_type, value2_type>());
+ __search_template(
+ __begin1, __end1, __begin2, __end2,
+ __gnu_parallel::equal_to<_ValueType1, _ValueType2>());
else
- return search(begin1, end1, begin2, end2,
+ return search(__begin1, __end1, __begin2, __end2,
__gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case
- template<typename ForwardIterator1, typename ForwardIterator2,
- typename IteratorTag1, typename IteratorTag2>
- inline ForwardIterator1
- search_switch(ForwardIterator1 begin1, ForwardIterator1 end1,
- ForwardIterator2 begin2, ForwardIterator2 end2,
- IteratorTag1, IteratorTag2)
- { return search(begin1, end1, begin2, end2,
+ template<typename _FIterator1, typename _FIterator2,
+ typename _IteratorTag1, typename _IteratorTag2>
+ inline _FIterator1
+ __search_switch(_FIterator1 __begin1, _FIterator1 __end1,
+ _FIterator2 __begin2, _FIterator2 __end2,
+ _IteratorTag1, _IteratorTag2)
+ { return search(__begin1, __end1, __begin2, __end2,
__gnu_parallel::sequential_tag()); }
// Public interface.
- template<typename ForwardIterator1, typename ForwardIterator2>
- inline ForwardIterator1
- search(ForwardIterator1 begin1, ForwardIterator1 end1,
- ForwardIterator2 begin2, ForwardIterator2 end2)
+ template<typename _FIterator1, typename _FIterator2>
+ inline _FIterator1
+ search(_FIterator1 __begin1, _FIterator1 __end1,
+ _FIterator2 __begin2, _FIterator2 __end2)
{
- typedef std::iterator_traits<ForwardIterator1> iterator1_traits;
- typedef typename iterator1_traits::iterator_category iterator1_category;
- typedef std::iterator_traits<ForwardIterator2> iterator2_traits;
- typedef typename iterator2_traits::iterator_category iterator2_category;
+ typedef std::iterator_traits<_FIterator1> iterator1_traits;
+ typedef typename iterator1_traits::iterator_category _IteratorCategory1;
+ typedef std::iterator_traits<_FIterator2> iterator2_traits;
+ typedef typename iterator2_traits::iterator_category _IteratorCategory2;
- return search_switch(begin1, end1, begin2, end2,
- iterator1_category(), iterator2_category());
+ return __search_switch(__begin1, __end1, __begin2, __end2,
+ _IteratorCategory1(), _IteratorCategory2());
}
// Public interface.
- template<typename ForwardIterator1, typename ForwardIterator2,
- typename BinaryPredicate>
- inline ForwardIterator1
- search(ForwardIterator1 begin1, ForwardIterator1 end1,
- ForwardIterator2 begin2, ForwardIterator2 end2,
- BinaryPredicate pred, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::search(begin1, end1, begin2, end2, pred); }
+ template<typename _FIterator1, typename _FIterator2,
+ typename _BinaryPredicate>
+ inline _FIterator1
+ search(_FIterator1 __begin1, _FIterator1 __end1,
+ _FIterator2 __begin2, _FIterator2 __end2,
+ _BinaryPredicate __pred, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::search(
+ __begin1, __end1, __begin2, __end2, __pred); }
// Parallel algorithm for random access iterator.
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename BinaryPredicate>
- RandomAccessIterator1
- search_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2, RandomAccessIterator2 end2,
- BinaryPredicate pred,
+ template<typename _RAIter1, typename _RAIter2,
+ typename _BinaryPredicate>
+ _RAIter1
+ __search_switch(_RAIter1 __begin1, _RAIter1 __end1,
+ _RAIter2 __begin2, _RAIter2 __end2,
+ _BinaryPredicate __pred,
random_access_iterator_tag, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(true))
- return __gnu_parallel::search_template(begin1, end1,
- begin2, end2, pred);
+ return __gnu_parallel::__search_template(__begin1, __end1,
+ __begin2, __end2, __pred);
else
- return search(begin1, end1, begin2, end2, pred,
+ return search(__begin1, __end1, __begin2, __end2, __pred,
__gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case
- template<typename ForwardIterator1, typename ForwardIterator2,
- typename BinaryPredicate, typename IteratorTag1,
- typename IteratorTag2>
- inline ForwardIterator1
- search_switch(ForwardIterator1 begin1, ForwardIterator1 end1,
- ForwardIterator2 begin2, ForwardIterator2 end2,
- BinaryPredicate pred, IteratorTag1, IteratorTag2)
- { return search(begin1, end1, begin2, end2, pred,
+ template<typename _FIterator1, typename _FIterator2,
+ typename _BinaryPredicate, typename _IteratorTag1,
+ typename _IteratorTag2>
+ inline _FIterator1
+ __search_switch(_FIterator1 __begin1, _FIterator1 __end1,
+ _FIterator2 __begin2, _FIterator2 __end2,
+ _BinaryPredicate __pred, _IteratorTag1, _IteratorTag2)
+ { return search(__begin1, __end1, __begin2, __end2, __pred,
__gnu_parallel::sequential_tag()); }
// Public interface
- template<typename ForwardIterator1, typename ForwardIterator2,
- typename BinaryPredicate>
- inline ForwardIterator1
- search(ForwardIterator1 begin1, ForwardIterator1 end1,
- ForwardIterator2 begin2, ForwardIterator2 end2,
- BinaryPredicate pred)
+ template<typename _FIterator1, typename _FIterator2,
+ typename _BinaryPredicate>
+ inline _FIterator1
+ search(_FIterator1 __begin1, _FIterator1 __end1,
+ _FIterator2 __begin2, _FIterator2 __end2,
+ _BinaryPredicate __pred)
{
- typedef std::iterator_traits<ForwardIterator1> iterator1_traits;
- typedef typename iterator1_traits::iterator_category iterator1_category;
- typedef std::iterator_traits<ForwardIterator2> iterator2_traits;
- typedef typename iterator2_traits::iterator_category iterator2_category;
- return search_switch(begin1, end1, begin2, end2, pred,
- iterator1_category(), iterator2_category());
+ typedef std::iterator_traits<_FIterator1> iterator1_traits;
+ typedef typename iterator1_traits::iterator_category _IteratorCategory1;
+ typedef std::iterator_traits<_FIterator2> iterator2_traits;
+ typedef typename iterator2_traits::iterator_category _IteratorCategory2;
+ return __search_switch(__begin1, __end1, __begin2, __end2, __pred,
+ _IteratorCategory1(), _IteratorCategory2());
}
// Sequential fallback
- template<typename ForwardIterator, typename Integer, typename T>
- inline ForwardIterator
- search_n(ForwardIterator begin, ForwardIterator end, Integer count,
- const T& val, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::search_n(begin, end, count, val); }
+ template<typename _FIterator, typename _Integer, typename _Tp>
+ inline _FIterator
+ search_n(_FIterator __begin, _FIterator __end, _Integer count,
+ const _Tp& __val, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::search_n(__begin, __end, count, __val); }
// Sequential fallback
- template<typename ForwardIterator, typename Integer, typename T,
- typename BinaryPredicate>
- inline ForwardIterator
- search_n(ForwardIterator begin, ForwardIterator end, Integer count,
- const T& val, BinaryPredicate binary_pred,
+ template<typename _FIterator, typename _Integer, typename _Tp,
+ typename _BinaryPredicate>
+ inline _FIterator
+ search_n(_FIterator __begin, _FIterator __end, _Integer count,
+ const _Tp& __val, _BinaryPredicate __binary_pred,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::search_n(begin, end, count, val, binary_pred); }
+ { return _GLIBCXX_STD_P::search_n(
+ __begin, __end, count, __val, __binary_pred); }
// Public interface.
- template<typename ForwardIterator, typename Integer, typename T>
- inline ForwardIterator
- search_n(ForwardIterator begin, ForwardIterator end, Integer count,
- const T& val)
+ template<typename _FIterator, typename _Integer, typename _Tp>
+ inline _FIterator
+ search_n(_FIterator __begin, _FIterator __end, _Integer count,
+ const _Tp& __val)
{
- typedef typename iterator_traits<ForwardIterator>::value_type value_type;
- return search_n(begin, end, count, val,
- __gnu_parallel::equal_to<value_type, T>());
+ typedef typename iterator_traits<_FIterator>::value_type _ValueType;
+ return search_n(__begin, __end, count, __val,
+ __gnu_parallel::equal_to<_ValueType, _Tp>());
}
// Parallel algorithm for random access iterators.
- template<typename RandomAccessIterator, typename Integer,
- typename T, typename BinaryPredicate>
- RandomAccessIterator
- search_n_switch(RandomAccessIterator begin, RandomAccessIterator end,
- Integer count, const T& val, BinaryPredicate binary_pred,
- random_access_iterator_tag)
+ template<typename _RAIter, typename _Integer,
+ typename _Tp, typename _BinaryPredicate>
+ _RAIter
+ __search_n_switch(_RAIter __begin, _RAIter __end, _Integer count,
+ const _Tp& __val, _BinaryPredicate __binary_pred,
+ random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(true))
{
- __gnu_parallel::pseudo_sequence<T, Integer> ps(val, count);
- return __gnu_parallel::search_template(begin, end, ps.begin(),
- ps.end(), binary_pred);
+ __gnu_parallel::_PseudoSequence<_Tp, _Integer> __ps(__val, count);
+ return __gnu_parallel::__search_template(
+ __begin, __end, __ps.begin(), __ps.end(), __binary_pred);
}
else
- return std::__search_n(begin, end, count, val,
- binary_pred, random_access_iterator_tag());
+ return std::__search_n(__begin, __end, count, __val,
+ __binary_pred, random_access_iterator_tag());
}
// Sequential fallback for input iterator case.
- template<typename ForwardIterator, typename Integer, typename T,
- typename BinaryPredicate, typename IteratorTag>
- inline ForwardIterator
- search_n_switch(ForwardIterator begin, ForwardIterator end, Integer count,
- const T& val, BinaryPredicate binary_pred, IteratorTag)
- { return __search_n(begin, end, count, val, binary_pred, IteratorTag()); }
+ template<typename _FIterator, typename _Integer, typename _Tp,
+ typename _BinaryPredicate, typename _IteratorTag>
+ inline _FIterator
+ __search_n_switch(_FIterator __begin, _FIterator __end, _Integer count,
+ const _Tp& __val, _BinaryPredicate __binary_pred,
+ _IteratorTag)
+ { return __search_n(__begin, __end, count, __val, __binary_pred,
+ _IteratorTag()); }
// Public interface.
- template<typename ForwardIterator, typename Integer, typename T,
- typename BinaryPredicate>
- inline ForwardIterator
- search_n(ForwardIterator begin, ForwardIterator end, Integer count,
- const T& val, BinaryPredicate binary_pred)
- {
- return search_n_switch(begin, end, count, val, binary_pred,
- typename std::iterator_traits<ForwardIterator>::
+ template<typename _FIterator, typename _Integer, typename _Tp,
+ typename _BinaryPredicate>
+ inline _FIterator
+ search_n(_FIterator __begin, _FIterator __end, _Integer count,
+ const _Tp& __val, _BinaryPredicate __binary_pred)
+ {
+ return __search_n_switch(__begin, __end, count, __val, __binary_pred,
+ typename std::iterator_traits<_FIterator>::
iterator_category());
}
// Sequential fallback.
- template<typename InputIterator, typename OutputIterator,
- typename UnaryOperation>
- inline OutputIterator
- transform(InputIterator begin, InputIterator end, OutputIterator result,
- UnaryOperation unary_op, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::transform(begin, end, result, unary_op); }
+ template<typename _IIter, typename _OutputIterator,
+ typename _UnaryOperation>
+ inline _OutputIterator
+ transform(_IIter __begin, _IIter __end, _OutputIterator __result,
+ _UnaryOperation unary_op, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::transform(__begin, __end, __result, unary_op); }
// Parallel unary transform for random access iterators.
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename UnaryOperation>
- RandomAccessIterator2
- transform1_switch(RandomAccessIterator1 begin, RandomAccessIterator1 end,
- RandomAccessIterator2 result, UnaryOperation unary_op,
+ template<typename _RAIter1, typename _RAIter2,
+ typename _UnaryOperation>
+ _RAIter2
+ __transform1_switch(_RAIter1 __begin, _RAIter1 __end,
+ _RAIter2 __result, _UnaryOperation unary_op,
random_access_iterator_tag, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism_tag
+ __gnu_parallel::_Parallelism __parallelism_tag
= __gnu_parallel::parallel_balanced)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().transform_minimal_n
- && __gnu_parallel::is_parallel(parallelism_tag)))
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
{
- bool dummy = true;
- typedef __gnu_parallel::iterator_pair<RandomAccessIterator1,
- RandomAccessIterator2, random_access_iterator_tag> ip;
- ip begin_pair(begin, result), end_pair(end, result + (end - begin));
- __gnu_parallel::transform1_selector<ip> functionality;
+ bool __dummy = true;
+ typedef __gnu_parallel::_IteratorPair<_RAIter1,
+ _RAIter2, random_access_iterator_tag> _ItTrip;
+ _ItTrip begin_pair(__begin, __result),
+ end_pair(__end, __result + (__end - __begin));
+ __gnu_parallel::__transform1_selector<_ItTrip> __functionality;
__gnu_parallel::
- for_each_template_random_access(begin_pair, end_pair,
- unary_op, functionality,
- __gnu_parallel::dummy_reduct(),
- dummy, dummy, -1, parallelism_tag);
- return functionality.finish_iterator;
+ __for_each_template_random_access(
+ begin_pair, end_pair, unary_op, __functionality,
+ __gnu_parallel::_DummyReduct(),
+ __dummy, __dummy, -1, __parallelism_tag);
+ return __functionality._M_finish_iterator;
}
else
- return transform(begin, end, result, unary_op,
+ return transform(__begin, __end, __result, unary_op,
__gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case.
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename UnaryOperation, typename IteratorTag1,
- typename IteratorTag2>
- inline RandomAccessIterator2
- transform1_switch(RandomAccessIterator1 begin, RandomAccessIterator1 end,
- RandomAccessIterator2 result, UnaryOperation unary_op,
- IteratorTag1, IteratorTag2)
- { return transform(begin, end, result, unary_op,
+ template<typename _RAIter1, typename _RAIter2,
+ typename _UnaryOperation, typename _IteratorTag1,
+ typename _IteratorTag2>
+ inline _RAIter2
+ __transform1_switch(_RAIter1 __begin, _RAIter1 __end,
+ _RAIter2 __result, _UnaryOperation unary_op,
+ _IteratorTag1, _IteratorTag2)
+ { return transform(__begin, __end, __result, unary_op,
__gnu_parallel::sequential_tag()); }
// Public interface.
- template<typename InputIterator, typename OutputIterator,
- typename UnaryOperation>
- inline OutputIterator
- transform(InputIterator begin, InputIterator end, OutputIterator result,
- UnaryOperation unary_op,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _IIter, typename _OutputIterator,
+ typename _UnaryOperation>
+ inline _OutputIterator
+ transform(_IIter __begin, _IIter __end, _OutputIterator __result,
+ _UnaryOperation unary_op,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef std::iterator_traits<InputIterator> iteratori_traits;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratori_traits::iterator_category iteratori_category;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
+ typedef std::iterator_traits<_IIter> _IIterTraits;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _IIterTraits::iterator_category _IIteratorCategory;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
- return transform1_switch(begin, end, result, unary_op,
- iteratori_category(), iteratoro_category(),
- parallelism_tag);
+ return __transform1_switch(__begin, __end, __result, unary_op,
+ _IIteratorCategory(), _OIterCategory(),
+ __parallelism_tag);
}
- template<typename InputIterator, typename OutputIterator,
- typename UnaryOperation>
- inline OutputIterator
- transform(InputIterator begin, InputIterator end, OutputIterator result,
- UnaryOperation unary_op)
+ template<typename _IIter, typename _OutputIterator,
+ typename _UnaryOperation>
+ inline _OutputIterator
+ transform(_IIter __begin, _IIter __end, _OutputIterator __result,
+ _UnaryOperation unary_op)
{
- typedef std::iterator_traits<InputIterator> iteratori_traits;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratori_traits::iterator_category iteratori_category;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
+ typedef std::iterator_traits<_IIter> _IIterTraits;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _IIterTraits::iterator_category _IIteratorCategory;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
- return transform1_switch(begin, end, result, unary_op,
- iteratori_category(), iteratoro_category());
+ return __transform1_switch(__begin, __end, __result, unary_op,
+ _IIteratorCategory(), _OIterCategory());
}
// Sequential fallback
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename BinaryOperation>
- inline OutputIterator
- transform(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, OutputIterator result,
- BinaryOperation binary_op, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::transform(begin1, end1,
- begin2, result, binary_op); }
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _BinaryOperation>
+ inline _OutputIterator
+ transform(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _OutputIterator __result,
+ _BinaryOperation __binary_op, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::transform(__begin1, __end1,
+ __begin2, __result, __binary_op); }
// Parallel binary transform for random access iterators.
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename RandomAccessIterator3, typename BinaryOperation>
- RandomAccessIterator3
- transform2_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2,
- RandomAccessIterator3 result, BinaryOperation binary_op,
+ template<typename _RAIter1, typename _RAIter2,
+ typename _RAIter3, typename _BinaryOperation>
+ _RAIter3
+ __transform2_switch(_RAIter1 __begin1, _RAIter1 __end1,
+ _RAIter2 __begin2,
+ _RAIter3 __result, _BinaryOperation __binary_op,
random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism_tag
+ __gnu_parallel::_Parallelism __parallelism_tag
= __gnu_parallel::parallel_balanced)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- (end1 - begin1) >=
+ (__end1 - __begin1) >=
__gnu_parallel::_Settings::get().transform_minimal_n
- && __gnu_parallel::is_parallel(parallelism_tag)))
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
{
- bool dummy = true;
- typedef __gnu_parallel::iterator_triple<RandomAccessIterator1,
- RandomAccessIterator2, RandomAccessIterator3,
- random_access_iterator_tag> ip;
- ip begin_triple(begin1, begin2, result),
- end_triple(end1, begin2 + (end1 - begin1),
- result + (end1 - begin1));
- __gnu_parallel::transform2_selector<ip> functionality;
+ bool __dummy = true;
+ typedef __gnu_parallel::_IteratorTriple<_RAIter1,
+ _RAIter2, _RAIter3,
+ random_access_iterator_tag> _ItTrip;
+ _ItTrip __begin_triple(__begin1, __begin2, __result),
+ __end_triple(__end1, __begin2 + (__end1 - __begin1),
+ __result + (__end1 - __begin1));
+ __gnu_parallel::__transform2_selector<_ItTrip> __functionality;
__gnu_parallel::
- for_each_template_random_access(begin_triple, end_triple,
- binary_op, functionality,
- __gnu_parallel::dummy_reduct(),
- dummy, dummy, -1,
- parallelism_tag);
- return functionality.finish_iterator;
+ __for_each_template_random_access(__begin_triple, __end_triple,
+ __binary_op, __functionality,
+ __gnu_parallel::_DummyReduct(),
+ __dummy, __dummy, -1,
+ __parallelism_tag);
+ return __functionality._M_finish_iterator;
}
else
- return transform(begin1, end1, begin2, result, binary_op,
+ return transform(__begin1, __end1, __begin2, __result, __binary_op,
__gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case.
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename BinaryOperation,
- typename tag1, typename tag2, typename tag3>
- inline OutputIterator
- transform2_switch(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, OutputIterator result,
- BinaryOperation binary_op, tag1, tag2, tag3)
- { return transform(begin1, end1, begin2, result, binary_op,
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _BinaryOperation,
+ typename _Tag1, typename _Tag2, typename _Tag3>
+ inline _OutputIterator
+ __transform2_switch(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _OutputIterator __result,
+ _BinaryOperation __binary_op, _Tag1, _Tag2, _Tag3)
+ { return transform(__begin1, __end1, __begin2, __result, __binary_op,
__gnu_parallel::sequential_tag()); }
// Public interface.
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename BinaryOperation>
- inline OutputIterator
- transform(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, OutputIterator result,
- BinaryOperation binary_op,
- __gnu_parallel::_Parallelism parallelism_tag)
- {
- typedef std::iterator_traits<InputIterator1> iteratori1_traits;
- typedef typename iteratori1_traits::iterator_category
- iteratori1_category;
- typedef std::iterator_traits<InputIterator2> iteratori2_traits;
- typedef typename iteratori2_traits::iterator_category
- iteratori2_category;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
-
- return transform2_switch(begin1, end1, begin2, result, binary_op,
- iteratori1_category(), iteratori2_category(),
- iteratoro_category(), parallelism_tag);
- }
-
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename BinaryOperation>
- inline OutputIterator
- transform(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, OutputIterator result,
- BinaryOperation binary_op)
- {
- typedef std::iterator_traits<InputIterator1> iteratori1_traits;
- typedef typename iteratori1_traits::iterator_category
- iteratori1_category;
- typedef std::iterator_traits<InputIterator2> iteratori2_traits;
- typedef typename iteratori2_traits::iterator_category
- iteratori2_category;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
-
- return transform2_switch(begin1, end1, begin2, result, binary_op,
- iteratori1_category(), iteratori2_category(),
- iteratoro_category());
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _BinaryOperation>
+ inline _OutputIterator
+ transform(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _OutputIterator __result,
+ _BinaryOperation __binary_op,
+ __gnu_parallel::_Parallelism __parallelism_tag)
+ {
+ typedef std::iterator_traits<_IIter1> _IIterTraits1;
+ typedef typename _IIterTraits1::iterator_category
+ _IIterCategory1;
+ typedef std::iterator_traits<_IIter2> _IIterTraits2;
+ typedef typename _IIterTraits2::iterator_category
+ _IIterCategory2;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
+
+ return __transform2_switch(
+ __begin1, __end1, __begin2, __result, __binary_op,
+ _IIterCategory1(), _IIterCategory2(), _OIterCategory(),
+ __parallelism_tag);
+ }
+
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _BinaryOperation>
+ inline _OutputIterator
+ transform(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _OutputIterator __result,
+ _BinaryOperation __binary_op)
+ {
+ typedef std::iterator_traits<_IIter1> _IIterTraits1;
+ typedef typename _IIterTraits1::iterator_category
+ _IIterCategory1;
+ typedef std::iterator_traits<_IIter2> _IIterTraits2;
+ typedef typename _IIterTraits2::iterator_category
+ _IIterCategory2;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
+
+ return __transform2_switch(
+ __begin1, __end1, __begin2, __result, __binary_op,
+ _IIterCategory1(), _IIterCategory2(), _OIterCategory());
}
// Sequential fallback
- template<typename ForwardIterator, typename T>
+ template<typename _FIterator, typename _Tp>
inline void
- replace(ForwardIterator begin, ForwardIterator end, const T& old_value,
- const T& new_value, __gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_P::replace(begin, end, old_value, new_value); }
+ replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
+ const _Tp& __new_value, __gnu_parallel::sequential_tag)
+ { _GLIBCXX_STD_P::replace(__begin, __end, __old_value, __new_value); }
// Sequential fallback for input iterator case
- template<typename ForwardIterator, typename T, typename IteratorTag>
+ template<typename _FIterator, typename _Tp, typename _IteratorTag>
inline void
- replace_switch(ForwardIterator begin, ForwardIterator end,
- const T& old_value, const T& new_value, IteratorTag)
- { replace(begin, end, old_value, new_value,
+ __replace_switch(_FIterator __begin, _FIterator __end,
+ const _Tp& __old_value, const _Tp& __new_value,
+ _IteratorTag)
+ { replace(__begin, __end, __old_value, __new_value,
__gnu_parallel::sequential_tag()); }
// Parallel replace for random access iterators
- template<typename RandomAccessIterator, typename T>
+ template<typename _RAIter, typename _Tp>
inline void
- replace_switch(RandomAccessIterator begin, RandomAccessIterator end,
- const T& old_value, const T& new_value,
+ __replace_switch(_RAIter __begin, _RAIter __end,
+ const _Tp& __old_value, const _Tp& __new_value,
random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism_tag
+ __gnu_parallel::_Parallelism __parallelism_tag
= __gnu_parallel::parallel_balanced)
{
// XXX parallel version is where?
- replace(begin, end, old_value, new_value,
+ replace(__begin, __end, __old_value, __new_value,
__gnu_parallel::sequential_tag());
}
// Public interface
- template<typename ForwardIterator, typename T>
+ template<typename _FIterator, typename _Tp>
inline void
- replace(ForwardIterator begin, ForwardIterator end, const T& old_value,
- const T& new_value, __gnu_parallel::_Parallelism parallelism_tag)
+ replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
+ const _Tp& __new_value,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<ForwardIterator> traits_type;
- typedef typename traits_type::iterator_category iterator_category;
- replace_switch(begin, end, old_value, new_value, iterator_category(),
- parallelism_tag);
+ typedef iterator_traits<_FIterator> _TraitsType;
+ typedef typename _TraitsType::iterator_category _IteratorCategory;
+ __replace_switch(__begin, __end, __old_value, __new_value,
+ _IteratorCategory(),
+ __parallelism_tag);
}
- template<typename ForwardIterator, typename T>
+ template<typename _FIterator, typename _Tp>
inline void
- replace(ForwardIterator begin, ForwardIterator end, const T& old_value,
- const T& new_value)
+ replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
+ const _Tp& __new_value)
{
- typedef iterator_traits<ForwardIterator> traits_type;
- typedef typename traits_type::iterator_category iterator_category;
- replace_switch(begin, end, old_value, new_value, iterator_category());
+ typedef iterator_traits<_FIterator> _TraitsType;
+ typedef typename _TraitsType::iterator_category _IteratorCategory;
+ __replace_switch(__begin, __end, __old_value, __new_value,
+ _IteratorCategory());
}
// Sequential fallback
- template<typename ForwardIterator, typename Predicate, typename T>
+ template<typename _FIterator, typename _Predicate, typename _Tp>
inline void
- replace_if(ForwardIterator begin, ForwardIterator end, Predicate pred,
- const T& new_value, __gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_P::replace_if(begin, end, pred, new_value); }
+ replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred,
+ const _Tp& __new_value, __gnu_parallel::sequential_tag)
+ { _GLIBCXX_STD_P::replace_if(__begin, __end, __pred, __new_value); }
// Sequential fallback for input iterator case
- template<typename ForwardIterator, typename Predicate, typename T,
- typename IteratorTag>
+ template<typename _FIterator, typename _Predicate, typename _Tp,
+ typename _IteratorTag>
inline void
- replace_if_switch(ForwardIterator begin, ForwardIterator end,
- Predicate pred, const T& new_value, IteratorTag)
- { replace_if(begin, end, pred, new_value,
+ __replace_if_switch(_FIterator __begin, _FIterator __end,
+ _Predicate __pred, const _Tp& __new_value, _IteratorTag)
+ { replace_if(__begin, __end, __pred, __new_value,
__gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators.
- template<typename RandomAccessIterator, typename Predicate, typename T>
+ template<typename _RAIter, typename _Predicate, typename _Tp>
void
- replace_if_switch(RandomAccessIterator begin, RandomAccessIterator end,
- Predicate pred, const T& new_value,
+ __replace_if_switch(_RAIter __begin, _RAIter __end,
+ _Predicate __pred, const _Tp& __new_value,
random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism_tag
+ __gnu_parallel::_Parallelism __parallelism_tag
= __gnu_parallel::parallel_balanced)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().replace_minimal_n
- && __gnu_parallel::is_parallel(parallelism_tag)))
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
{
- bool dummy;
+ bool __dummy;
__gnu_parallel::
- replace_if_selector<RandomAccessIterator, Predicate, T>
- functionality(new_value);
+ __replace_if_selector<_RAIter, _Predicate, _Tp>
+ __functionality(__new_value);
__gnu_parallel::
- for_each_template_random_access(begin, end, pred,
- functionality,
- __gnu_parallel::dummy_reduct(),
- true, dummy, -1, parallelism_tag);
+ __for_each_template_random_access(
+ __begin, __end, __pred, __functionality,
+ __gnu_parallel::_DummyReduct(),
+ true, __dummy, -1, __parallelism_tag);
}
else
- replace_if(begin, end, pred, new_value,
+ replace_if(__begin, __end, __pred, __new_value,
__gnu_parallel::sequential_tag());
}
// Public interface.
- template<typename ForwardIterator, typename Predicate, typename T>
+ template<typename _FIterator, typename _Predicate, typename _Tp>
inline void
- replace_if(ForwardIterator begin, ForwardIterator end,
- Predicate pred, const T& new_value,
- __gnu_parallel::_Parallelism parallelism_tag)
+ replace_if(_FIterator __begin, _FIterator __end,
+ _Predicate __pred, const _Tp& __new_value,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef std::iterator_traits<ForwardIterator> iterator_traits;
- typedef typename iterator_traits::iterator_category iterator_category;
- replace_if_switch(begin, end, pred, new_value, iterator_category(),
- parallelism_tag);
+ typedef std::iterator_traits<_FIterator> _IteratorTraits;
+ typedef typename _IteratorTraits::iterator_category _IteratorCategory;
+ __replace_if_switch(__begin, __end, __pred, __new_value,
+ _IteratorCategory(), __parallelism_tag);
}
- template<typename ForwardIterator, typename Predicate, typename T>
+ template<typename _FIterator, typename _Predicate, typename _Tp>
inline void
- replace_if(ForwardIterator begin, ForwardIterator end,
- Predicate pred, const T& new_value)
+ replace_if(_FIterator __begin, _FIterator __end,
+ _Predicate __pred, const _Tp& __new_value)
{
- typedef std::iterator_traits<ForwardIterator> iterator_traits;
- typedef typename iterator_traits::iterator_category iterator_category;
- replace_if_switch(begin, end, pred, new_value, iterator_category());
+ typedef std::iterator_traits<_FIterator> _IteratorTraits;
+ typedef typename _IteratorTraits::iterator_category _IteratorCategory;
+ __replace_if_switch(__begin, __end, __pred, __new_value,
+ _IteratorCategory());
}
// Sequential fallback
- template<typename ForwardIterator, typename Generator>
+ template<typename _FIterator, typename Generator>
inline void
- generate(ForwardIterator begin, ForwardIterator end, Generator gen,
+ generate(_FIterator __begin, _FIterator __end, Generator __gen,
__gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_P::generate(begin, end, gen); }
+ { _GLIBCXX_STD_P::generate(__begin, __end, __gen); }
// Sequential fallback for input iterator case.
- template<typename ForwardIterator, typename Generator, typename IteratorTag>
+ template<typename _FIterator, typename Generator, typename _IteratorTag>
inline void
- generate_switch(ForwardIterator begin, ForwardIterator end, Generator gen,
- IteratorTag)
- { generate(begin, end, gen, __gnu_parallel::sequential_tag()); }
+ __generate_switch(_FIterator __begin, _FIterator __end, Generator __gen,
+ _IteratorTag)
+ { generate(__begin, __end, __gen, __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators.
- template<typename RandomAccessIterator, typename Generator>
+ template<typename _RAIter, typename Generator>
void
- generate_switch(RandomAccessIterator begin, RandomAccessIterator end,
- Generator gen, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism_tag
+ __generate_switch(_RAIter __begin, _RAIter __end,
+ Generator __gen, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag
= __gnu_parallel::parallel_balanced)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().generate_minimal_n
- && __gnu_parallel::is_parallel(parallelism_tag)))
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
{
- bool dummy;
- __gnu_parallel::generate_selector<RandomAccessIterator>
- functionality;
+ bool __dummy;
+ __gnu_parallel::__generate_selector<_RAIter>
+ __functionality;
__gnu_parallel::
- for_each_template_random_access(begin, end, gen, functionality,
- __gnu_parallel::dummy_reduct(),
- true, dummy, -1, parallelism_tag);
+ __for_each_template_random_access(
+ __begin, __end, __gen, __functionality,
+ __gnu_parallel::_DummyReduct(),
+ true, __dummy, -1, __parallelism_tag);
}
else
- generate(begin, end, gen, __gnu_parallel::sequential_tag());
+ generate(__begin, __end, __gen, __gnu_parallel::sequential_tag());
}
// Public interface.
- template<typename ForwardIterator, typename Generator>
+ template<typename _FIterator, typename Generator>
inline void
- generate(ForwardIterator begin, ForwardIterator end,
- Generator gen, __gnu_parallel::_Parallelism parallelism_tag)
+ generate(_FIterator __begin, _FIterator __end,
+ Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef std::iterator_traits<ForwardIterator> iterator_traits;
- typedef typename iterator_traits::iterator_category iterator_category;
- generate_switch(begin, end, gen, iterator_category(), parallelism_tag);
+ typedef std::iterator_traits<_FIterator> _IteratorTraits;
+ typedef typename _IteratorTraits::iterator_category _IteratorCategory;
+ __generate_switch(__begin, __end, __gen, _IteratorCategory(),
+ __parallelism_tag);
}
- template<typename ForwardIterator, typename Generator>
+ template<typename _FIterator, typename Generator>
inline void
- generate(ForwardIterator begin, ForwardIterator end, Generator gen)
+ generate(_FIterator __begin, _FIterator __end, Generator __gen)
{
- typedef std::iterator_traits<ForwardIterator> iterator_traits;
- typedef typename iterator_traits::iterator_category iterator_category;
- generate_switch(begin, end, gen, iterator_category());
+ typedef std::iterator_traits<_FIterator> _IteratorTraits;
+ typedef typename _IteratorTraits::iterator_category _IteratorCategory;
+ __generate_switch(__begin, __end, __gen, _IteratorCategory());
}
// Sequential fallback.
- template<typename OutputIterator, typename Size, typename Generator>
- inline OutputIterator
- generate_n(OutputIterator begin, Size n, Generator gen,
+ template<typename _OutputIterator, typename _Size, typename Generator>
+ inline _OutputIterator
+ generate_n(_OutputIterator __begin, _Size __n, Generator __gen,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::generate_n(begin, n, gen); }
+ { return _GLIBCXX_STD_P::generate_n(__begin, __n, __gen); }
// Sequential fallback for input iterator case.
- template<typename OutputIterator, typename Size, typename Generator,
- typename IteratorTag>
- inline OutputIterator
- generate_n_switch(OutputIterator begin, Size n, Generator gen, IteratorTag)
- { return generate_n(begin, n, gen, __gnu_parallel::sequential_tag()); }
+ template<typename _OutputIterator, typename _Size, typename Generator,
+ typename _IteratorTag>
+ inline _OutputIterator
+ __generate_n_switch(_OutputIterator __begin, _Size __n, Generator __gen,
+ _IteratorTag)
+ { return generate_n(__begin, __n, __gen,
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators.
- template<typename RandomAccessIterator, typename Size, typename Generator>
- inline RandomAccessIterator
- generate_n_switch(RandomAccessIterator begin, Size n, Generator gen,
+ template<typename _RAIter, typename _Size, typename Generator>
+ inline _RAIter
+ __generate_n_switch(_RAIter __begin, _Size __n, Generator __gen,
random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism_tag
+ __gnu_parallel::_Parallelism __parallelism_tag
= __gnu_parallel::parallel_balanced)
{
// XXX parallel version is where?
- return generate_n(begin, n, gen, __gnu_parallel::sequential_tag());
+ return generate_n(__begin, __n, __gen, __gnu_parallel::sequential_tag());
}
// Public interface.
- template<typename OutputIterator, typename Size, typename Generator>
- inline OutputIterator
- generate_n(OutputIterator begin, Size n, Generator gen,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _OutputIterator, typename _Size, typename Generator>
+ inline _OutputIterator
+ generate_n(_OutputIterator __begin, _Size __n, Generator __gen,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef std::iterator_traits<OutputIterator> iterator_traits;
- typedef typename iterator_traits::iterator_category iterator_category;
- return generate_n_switch(begin, n, gen, iterator_category(),
- parallelism_tag);
+ typedef std::iterator_traits<_OutputIterator> _IteratorTraits;
+ typedef typename _IteratorTraits::iterator_category _IteratorCategory;
+ return __generate_n_switch(__begin, __n, __gen, _IteratorCategory(),
+ __parallelism_tag);
}
- template<typename OutputIterator, typename Size, typename Generator>
- inline OutputIterator
- generate_n(OutputIterator begin, Size n, Generator gen)
+ template<typename _OutputIterator, typename _Size, typename Generator>
+ inline _OutputIterator
+ generate_n(_OutputIterator __begin, _Size __n, Generator __gen)
{
- typedef std::iterator_traits<OutputIterator> iterator_traits;
- typedef typename iterator_traits::iterator_category iterator_category;
- return generate_n_switch(begin, n, gen, iterator_category());
+ typedef std::iterator_traits<_OutputIterator> _IteratorTraits;
+ typedef typename _IteratorTraits::iterator_category _IteratorCategory;
+ return __generate_n_switch(__begin, __n, __gen, _IteratorCategory());
}
// Sequential fallback.
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- random_shuffle(RandomAccessIterator begin, RandomAccessIterator end,
+ random_shuffle(_RAIter __begin, _RAIter __end,
__gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_P::random_shuffle(begin, end); }
+ { _GLIBCXX_STD_P::random_shuffle(__begin, __end); }
// Sequential fallback.
- template<typename RandomAccessIterator, typename RandomNumberGenerator>
+ template<typename _RAIter, typename RandomNumberGenerator>
inline void
- random_shuffle(RandomAccessIterator begin, RandomAccessIterator end,
- RandomNumberGenerator& rand, __gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_P::random_shuffle(begin, end, rand); }
+ random_shuffle(_RAIter __begin, _RAIter __end,
+ RandomNumberGenerator& __rand,
+ __gnu_parallel::sequential_tag)
+ { _GLIBCXX_STD_P::random_shuffle(__begin, __end, __rand); }
/** @brief Functor wrapper for std::rand(). */
- template<typename must_be_int = int>
- struct c_rand_number
+ template<typename _MustBeInt = int>
+ struct _CRandNumber
{
int
- operator()(int limit)
- { return rand() % limit; }
+ operator()(int __limit)
+ { return rand() % __limit; }
};
// Fill in random number generator.
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- random_shuffle(RandomAccessIterator begin, RandomAccessIterator end)
+ random_shuffle(_RAIter __begin, _RAIter __end)
{
- c_rand_number<> r;
+ _CRandNumber<> __r;
// Parallelization still possible.
- __gnu_parallel::random_shuffle(begin, end, r);
+ __gnu_parallel::random_shuffle(__begin, __end, __r);
}
// Parallel algorithm for random access iterators.
- template<typename RandomAccessIterator, typename RandomNumberGenerator>
+ template<typename _RAIter, typename RandomNumberGenerator>
void
- random_shuffle(RandomAccessIterator begin, RandomAccessIterator end,
- RandomNumberGenerator& rand)
+ random_shuffle(_RAIter __begin, _RAIter __end,
+ RandomNumberGenerator& __rand)
{
- if (begin == end)
+ if (__begin == __end)
return;
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().random_shuffle_minimal_n))
- __gnu_parallel::parallel_random_shuffle(begin, end, rand);
+ __gnu_parallel::__parallel_random_shuffle(__begin, __end, __rand);
else
- __gnu_parallel::sequential_random_shuffle(begin, end, rand);
+ __gnu_parallel::__sequential_random_shuffle(__begin, __end, __rand);
}
// Sequential fallback.
- template<typename ForwardIterator, typename Predicate>
- inline ForwardIterator
- partition(ForwardIterator begin, ForwardIterator end,
- Predicate pred, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::partition(begin, end, pred); }
+ template<typename _FIterator, typename _Predicate>
+ inline _FIterator
+ partition(_FIterator __begin, _FIterator __end,
+ _Predicate __pred, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::partition(__begin, __end, __pred); }
// Sequential fallback for input iterator case.
- template<typename ForwardIterator, typename Predicate, typename IteratorTag>
- inline ForwardIterator
- partition_switch(ForwardIterator begin, ForwardIterator end,
- Predicate pred, IteratorTag)
- { return partition(begin, end, pred, __gnu_parallel::sequential_tag()); }
+ template<typename _FIterator, typename _Predicate, typename _IteratorTag>
+ inline _FIterator
+ __partition_switch(_FIterator __begin, _FIterator __end,
+ _Predicate __pred, _IteratorTag)
+ { return partition(__begin, __end, __pred,
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators.
- template<typename RandomAccessIterator, typename Predicate>
- RandomAccessIterator
- partition_switch(RandomAccessIterator begin, RandomAccessIterator end,
- Predicate pred, random_access_iterator_tag)
+ template<typename _RAIter, typename _Predicate>
+ _RAIter
+ __partition_switch(_RAIter __begin, _RAIter __end,
+ _Predicate __pred, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().partition_minimal_n))
{
- typedef typename std::iterator_traits<RandomAccessIterator>::
- difference_type difference_type;
- difference_type middle = __gnu_parallel::
- parallel_partition(begin, end, pred,
- __gnu_parallel::get_max_threads());
- return begin + middle;
+ typedef typename std::iterator_traits<_RAIter>::
+ difference_type _DifferenceType;
+ _DifferenceType __middle = __gnu_parallel::
+ __parallel_partition(__begin, __end, __pred,
+ __gnu_parallel::__get_max_threads());
+ return __begin + __middle;
}
else
- return partition(begin, end, pred, __gnu_parallel::sequential_tag());
+ return partition(__begin, __end, __pred,
+ __gnu_parallel::sequential_tag());
}
// Public interface.
- template<typename ForwardIterator, typename Predicate>
- inline ForwardIterator
- partition(ForwardIterator begin, ForwardIterator end, Predicate pred)
+ template<typename _FIterator, typename _Predicate>
+ inline _FIterator
+ partition(_FIterator __begin, _FIterator __end, _Predicate __pred)
{
- typedef iterator_traits<ForwardIterator> traits_type;
- typedef typename traits_type::iterator_category iterator_category;
- return partition_switch(begin, end, pred, iterator_category());
+ typedef iterator_traits<_FIterator> _TraitsType;
+ typedef typename _TraitsType::iterator_category _IteratorCategory;
+ return __partition_switch(__begin, __end, __pred, _IteratorCategory());
}
// sort interface
// Sequential fallback
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- sort(RandomAccessIterator begin, RandomAccessIterator end,
+ sort(_RAIter __begin, _RAIter __end,
__gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_P::sort(begin, end); }
+ { _GLIBCXX_STD_P::sort(__begin, __end); }
// Sequential fallback
- template<typename RandomAccessIterator, typename Comparator>
+ template<typename _RAIter, typename _Compare>
inline void
- sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp,
+ sort(_RAIter __begin, _RAIter __end, _Compare __comp,
__gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_P::sort<RandomAccessIterator, Comparator>(begin, end,
- comp); }
+ { _GLIBCXX_STD_P::sort<_RAIter, _Compare>(__begin, __end,
+ __comp); }
// Public interface
- template<typename RandomAccessIterator, typename Comparator,
- typename Parallelism>
+ template<typename _RAIter, typename _Compare,
+ typename _Parallelism>
void
- sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp,
- Parallelism parallelism)
+ sort(_RAIter __begin, _RAIter __end, _Compare __comp,
+ _Parallelism __parallelism)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
- if (begin != end)
+ if (__begin != __end)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin) >=
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
__gnu_parallel::_Settings::get().sort_minimal_n))
- __gnu_parallel::parallel_sort<false>(begin, end, comp, parallelism);
+ __gnu_parallel::parallel_sort<false>(
+ __begin, __end, __comp, __parallelism);
else
- sort(begin, end, comp, __gnu_parallel::sequential_tag());
+ sort(__begin, __end, __comp, __gnu_parallel::sequential_tag());
}
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- sort(RandomAccessIterator begin, RandomAccessIterator end)
+ sort(_RAIter __begin, _RAIter __end)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- sort(begin, end, std::less<value_type>(),
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(),
__gnu_parallel::default_parallel_tag());
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- sort(RandomAccessIterator begin, RandomAccessIterator end,
- __gnu_parallel::default_parallel_tag parallelism)
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::default_parallel_tag __parallelism)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- sort(begin, end, std::less<value_type>(), parallelism);
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(), __parallelism);
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- sort(RandomAccessIterator begin, RandomAccessIterator end,
- __gnu_parallel::parallel_tag parallelism)
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::parallel_tag __parallelism)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- sort(begin, end, std::less<value_type>(), parallelism);
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(), __parallelism);
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- sort(RandomAccessIterator begin, RandomAccessIterator end,
- __gnu_parallel::multiway_mergesort_tag parallelism)
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::multiway_mergesort_tag __parallelism)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- sort(begin, end, std::less<value_type>(), parallelism);
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(), __parallelism);
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- sort(RandomAccessIterator begin, RandomAccessIterator end,
- __gnu_parallel::multiway_mergesort_sampling_tag parallelism)
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::multiway_mergesort_sampling_tag __parallelism)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- sort(begin, end, std::less<value_type>(), parallelism);
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(), __parallelism);
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- sort(RandomAccessIterator begin, RandomAccessIterator end,
- __gnu_parallel::multiway_mergesort_exact_tag parallelism)
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::multiway_mergesort_exact_tag __parallelism)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- sort(begin, end, std::less<value_type>(), parallelism);
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(), __parallelism);
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- sort(RandomAccessIterator begin, RandomAccessIterator end,
- __gnu_parallel::quicksort_tag parallelism)
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::quicksort_tag __parallelism)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- sort(begin, end, std::less<value_type>(), parallelism);
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(), __parallelism);
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- sort(RandomAccessIterator begin, RandomAccessIterator end,
- __gnu_parallel::balanced_quicksort_tag parallelism)
+ sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::balanced_quicksort_tag __parallelism)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- sort(begin, end, std::less<value_type>(), parallelism);
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ sort(__begin, __end, std::less<_ValueType>(), __parallelism);
}
// Public interface
- template<typename RandomAccessIterator, typename Comparator>
+ template<typename _RAIter, typename _Compare>
void
- sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp)
+ sort(_RAIter __begin, _RAIter __end, _Compare __comp)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- sort(begin, end, comp, __gnu_parallel::default_parallel_tag());
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ sort(__begin, __end, __comp, __gnu_parallel::default_parallel_tag());
}
@@ -1848,515 +1869,479 @@ namespace __parallel
// Sequential fallback
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
+ stable_sort(_RAIter __begin, _RAIter __end,
__gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_P::stable_sort(begin, end); }
+ { _GLIBCXX_STD_P::stable_sort(__begin, __end); }
// Sequential fallback
- template<typename RandomAccessIterator, typename Comparator>
+ template<typename _RAIter, typename _Compare>
inline void
- stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp, __gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_P::stable_sort<RandomAccessIterator, Comparator>(
- begin, end, comp); }
+ stable_sort(_RAIter __begin, _RAIter __end,
+ _Compare __comp, __gnu_parallel::sequential_tag)
+ { _GLIBCXX_STD_P::stable_sort<_RAIter, _Compare>(
+ __begin, __end, __comp); }
// Public interface
- template<typename RandomAccessIterator, typename Comparator,
- typename Parallelism>
+ template<typename _RAIter, typename _Compare,
+ typename _Parallelism>
void
- stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp, Parallelism parallelism)
+ stable_sort(_RAIter __begin, _RAIter __end,
+ _Compare __comp, _Parallelism __parallelism)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
- if (begin != end)
+ if (__begin != __end)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin) >=
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
__gnu_parallel::_Settings::get().sort_minimal_n))
- __gnu_parallel::parallel_sort<true>(begin, end, comp, parallelism);
+ __gnu_parallel::parallel_sort<true>(
+ __begin, __end, __comp, __parallelism);
else
- stable_sort(begin, end, comp, __gnu_parallel::sequential_tag());
+ stable_sort(__begin, __end, __comp,
+ __gnu_parallel::sequential_tag());
}
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- stable_sort(RandomAccessIterator begin, RandomAccessIterator end)
+ stable_sort(_RAIter __begin, _RAIter __end)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- stable_sort(begin, end, std::less<value_type>(),
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ stable_sort(__begin, __end, std::less<_ValueType>(),
__gnu_parallel::default_parallel_tag());
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
- __gnu_parallel::default_parallel_tag parallelism)
+ stable_sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::default_parallel_tag __parallelism)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- stable_sort(begin, end, std::less<value_type>(), parallelism);
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
- __gnu_parallel::parallel_tag parallelism)
+ stable_sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::parallel_tag __parallelism)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- stable_sort(begin, end, std::less<value_type>(), parallelism);
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
- __gnu_parallel::multiway_mergesort_tag parallelism)
+ stable_sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::multiway_mergesort_tag __parallelism)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- stable_sort(begin, end, std::less<value_type>(), parallelism);
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
- __gnu_parallel::quicksort_tag parallelism)
+ stable_sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::quicksort_tag __parallelism)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- stable_sort(begin, end, std::less<value_type>(), parallelism);
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
- __gnu_parallel::balanced_quicksort_tag parallelism)
+ stable_sort(_RAIter __begin, _RAIter __end,
+ __gnu_parallel::balanced_quicksort_tag __parallelism)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- stable_sort(begin, end, std::less<value_type>(), parallelism);
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
}
// Public interface
- template<typename RandomAccessIterator, typename Comparator>
+ template<typename _RAIter, typename _Compare>
void
- stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp)
+ stable_sort(_RAIter __begin, _RAIter __end,
+ _Compare __comp)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- stable_sort(begin, end, comp, __gnu_parallel::default_parallel_tag());
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ stable_sort(
+ __begin, __end, __comp, __gnu_parallel::default_parallel_tag());
}
-
-// // Sequential fallback
-// template<typename RandomAccessIterator>
-// inline void
-// stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
-// __gnu_parallel::sequential_tag)
-// { return _GLIBCXX_STD_P::stable_sort(begin, end); }
-//
-// // Sequential fallback
-// template<typename RandomAccessIterator, typename Comparator>
-// inline void
-// stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
-// Comparator comp, __gnu_parallel::sequential_tag)
-// { return _GLIBCXX_STD_P::stable_sort(begin, end, comp); }
-//
-// template<typename RandomAccessIterator>
-// void
-// stable_sort(RandomAccessIterator begin, RandomAccessIterator end)
-// {
-// typedef iterator_traits<RandomAccessIterator> traits_type;
-// typedef typename traits_type::value_type value_type;
-// stable_sort(begin, end, std::less<value_type>());
-// }
-//
-// // Parallel algorithm for random access iterators
-// template<typename RandomAccessIterator, typename Comparator>
-// void
-// stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
-// Comparator comp)
-// {
-// if (begin != end)
-// {
-// if (_GLIBCXX_PARALLEL_CONDITION(
-// static_cast<__gnu_parallel::sequence_index_t>(end - begin) >=
-// __gnu_parallel::_Settings::get().sort_minimal_n))
-// __gnu_parallel::parallel_sort(begin, end, comp,
-// __gnu_parallel::parallel_tag());
-// else
-// stable_sort(begin, end, comp, __gnu_parallel::sequential_tag());
-// }
-// }
-
// Sequential fallback
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator>
- inline OutputIterator
- merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
- InputIterator2 end2, OutputIterator result,
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator>
+ inline _OutputIterator
+ merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
+ _IIter2 __end2, _OutputIterator __result,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::merge(begin1, end1, begin2, end2, result); }
+ { return _GLIBCXX_STD_P::merge(
+ __begin1, __end1, __begin2, __end2, __result); }
// Sequential fallback
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename Comparator>
- inline OutputIterator
- merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
- InputIterator2 end2, OutputIterator result, Comparator comp,
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _Compare>
+ inline _OutputIterator
+ merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
+ _IIter2 __end2, _OutputIterator __result, _Compare __comp,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::merge(begin1, end1, begin2, end2, result, comp); }
+ { return _GLIBCXX_STD_P::merge(
+ __begin1, __end1, __begin2, __end2, __result, __comp); }
// Sequential fallback for input iterator case
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename Comparator,
- typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
- inline OutputIterator
- merge_switch(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator result, Comparator comp,
- IteratorTag1, IteratorTag2, IteratorTag3)
- { return _GLIBCXX_STD_P::merge(begin1, end1, begin2, end2,
- result, comp); }
+ template<typename _IIter1, typename _IIter2, typename _OutputIterator,
+ typename _Compare, typename _IteratorTag1,
+ typename _IteratorTag2, typename _IteratorTag3>
+ inline _OutputIterator
+ __merge_switch(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __result, _Compare __comp,
+ _IteratorTag1, _IteratorTag2, _IteratorTag3)
+ { return _GLIBCXX_STD_P::merge(__begin1, __end1, __begin2, __end2,
+ __result, __comp); }
// Parallel algorithm for random access iterators
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename Comparator>
- OutputIterator
- merge_switch(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- OutputIterator result, Comparator comp,
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _Compare>
+ _OutputIterator
+ __merge_switch(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _OutputIterator __result, _Compare __comp,
random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- (static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
+ (static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
>= __gnu_parallel::_Settings::get().merge_minimal_n
- || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
+ || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
>= __gnu_parallel::_Settings::get().merge_minimal_n)))
- return __gnu_parallel::parallel_merge_advance(begin1, end1,
- begin2, end2,
- result, (end1 - begin1)
- + (end2 - begin2), comp);
+ return __gnu_parallel::__parallel_merge_advance(
+ __begin1, __end1, __begin2, __end2, __result,
+ (__end1 - __begin1) + (__end2 - __begin2), __comp);
else
- return __gnu_parallel::merge_advance(begin1, end1, begin2, end2,
- result, (end1 - begin1)
- + (end2 - begin2), comp);
+ return __gnu_parallel::__merge_advance(
+ __begin1, __end1, __begin2, __end2, __result,
+ (__end1 - __begin1) + (__end2 - __begin2), __comp);
}
// Public interface
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator, typename Comparator>
- inline OutputIterator
- merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
- InputIterator2 end2, OutputIterator result, Comparator comp)
- {
- typedef typename iterator_traits<InputIterator1>::value_type value_type;
-
- typedef std::iterator_traits<InputIterator1> iteratori1_traits;
- typedef std::iterator_traits<InputIterator2> iteratori2_traits;
- typedef std::iterator_traits<OutputIterator> iteratoro_traits;
- typedef typename iteratori1_traits::iterator_category
- iteratori1_category;
- typedef typename iteratori2_traits::iterator_category
- iteratori2_category;
- typedef typename iteratoro_traits::iterator_category iteratoro_category;
-
- return merge_switch(begin1, end1, begin2, end2, result, comp,
- iteratori1_category(), iteratori2_category(),
- iteratoro_category());
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator, typename _Compare>
+ inline _OutputIterator
+ merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
+ _IIter2 __end2, _OutputIterator __result, _Compare __comp)
+ {
+ typedef typename iterator_traits<_IIter1>::value_type _ValueType;
+
+ typedef std::iterator_traits<_IIter1> _IIterTraits1;
+ typedef std::iterator_traits<_IIter2> _IIterTraits2;
+ typedef std::iterator_traits<_OutputIterator> _OIterTraits;
+ typedef typename _IIterTraits1::iterator_category
+ _IIterCategory1;
+ typedef typename _IIterTraits2::iterator_category
+ _IIterCategory2;
+ typedef typename _OIterTraits::iterator_category _OIterCategory;
+
+ return __merge_switch(
+ __begin1, __end1, __begin2, __end2, __result, __comp,
+ _IIterCategory1(), _IIterCategory2(), _OIterCategory());
}
// Public interface, insert default comparator
- template<typename InputIterator1, typename InputIterator2,
- typename OutputIterator>
- inline OutputIterator
- merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
- InputIterator2 end2, OutputIterator result)
+ template<typename _IIter1, typename _IIter2,
+ typename _OutputIterator>
+ inline _OutputIterator
+ merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
+ _IIter2 __end2, _OutputIterator __result)
{
- typedef std::iterator_traits<InputIterator1> iterator1_traits;
- typedef std::iterator_traits<InputIterator2> iterator2_traits;
- typedef typename iterator1_traits::value_type value1_type;
- typedef typename iterator2_traits::value_type value2_type;
+ typedef std::iterator_traits<_IIter1> iterator1_traits;
+ typedef std::iterator_traits<_IIter2> iterator2_traits;
+ typedef typename iterator1_traits::value_type _ValueType1;
+ typedef typename iterator2_traits::value_type _ValueType2;
- return merge(begin1, end1, begin2, end2, result,
- __gnu_parallel::less<value1_type, value2_type>());
+ return merge(__begin1, __end1, __begin2, __end2, __result,
+ __gnu_parallel::_Less<_ValueType1, _ValueType2>());
}
// Sequential fallback
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
- RandomAccessIterator end, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::nth_element(begin, nth, end); }
+ nth_element(_RAIter __begin, _RAIter __nth,
+ _RAIter __end, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::nth_element(__begin, __nth, __end); }
// Sequential fallback
- template<typename RandomAccessIterator, typename Comparator>
+ template<typename _RAIter, typename _Compare>
inline void
- nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
- RandomAccessIterator end, Comparator comp,
+ nth_element(_RAIter __begin, _RAIter __nth,
+ _RAIter __end, _Compare __comp,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::nth_element(begin, nth, end, comp); }
+ { return _GLIBCXX_STD_P::nth_element(__begin, __nth, __end, __comp); }
// Public interface
- template<typename RandomAccessIterator, typename Comparator>
+ template<typename _RAIter, typename _Compare>
inline void
- nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
- RandomAccessIterator end, Comparator comp)
+ nth_element(_RAIter __begin, _RAIter __nth,
+ _RAIter __end, _Compare __comp)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().nth_element_minimal_n))
- __gnu_parallel::parallel_nth_element(begin, nth, end, comp);
+ __gnu_parallel::parallel_nth_element(__begin, __nth, __end, __comp);
else
- nth_element(begin, nth, end, comp, __gnu_parallel::sequential_tag());
+ nth_element(__begin, __nth, __end, __comp,
+ __gnu_parallel::sequential_tag());
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
- RandomAccessIterator end)
+ nth_element(_RAIter __begin, _RAIter __nth,
+ _RAIter __end)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- nth_element(begin, nth, end, std::less<value_type>());
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ nth_element(__begin, __nth, __end, std::less<_ValueType>());
}
// Sequential fallback
- template<typename RandomAccessIterator, typename _Compare>
+ template<typename _RAIter, typename _Compare>
inline void
- partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
- RandomAccessIterator end, _Compare comp,
+ partial_sort(_RAIter __begin, _RAIter __middle,
+ _RAIter __end, _Compare __comp,
__gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_P::partial_sort(begin, middle, end, comp); }
+ { _GLIBCXX_STD_P::partial_sort(__begin, __middle, __end, __comp); }
// Sequential fallback
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
- RandomAccessIterator end, __gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_P::partial_sort(begin, middle, end); }
+ partial_sort(_RAIter __begin, _RAIter __middle,
+ _RAIter __end, __gnu_parallel::sequential_tag)
+ { _GLIBCXX_STD_P::partial_sort(__begin, __middle, __end); }
// Public interface, parallel algorithm for random access iterators
- template<typename RandomAccessIterator, typename _Compare>
+ template<typename _RAIter, typename _Compare>
void
- partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
- RandomAccessIterator end, _Compare comp)
+ partial_sort(_RAIter __begin, _RAIter __middle,
+ _RAIter __end, _Compare __comp)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().partial_sort_minimal_n))
- __gnu_parallel::parallel_partial_sort(begin, middle, end, comp);
+ __gnu_parallel::
+ parallel_partial_sort(__begin, __middle, __end, __comp);
else
- partial_sort(begin, middle, end, comp,
+ partial_sort(__begin, __middle, __end, __comp,
__gnu_parallel::sequential_tag());
}
// Public interface, insert default comparator
- template<typename RandomAccessIterator>
+ template<typename _RAIter>
inline void
- partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
- RandomAccessIterator end)
+ partial_sort(_RAIter __begin, _RAIter __middle,
+ _RAIter __end)
{
- typedef iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- partial_sort(begin, middle, end, std::less<value_type>());
+ typedef iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ partial_sort(__begin, __middle, __end, std::less<_ValueType>());
}
// Sequential fallback
- template<typename ForwardIterator>
- inline ForwardIterator
- max_element(ForwardIterator begin, ForwardIterator end,
+ template<typename _FIterator>
+ inline _FIterator
+ max_element(_FIterator __begin, _FIterator __end,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::max_element(begin, end); }
+ { return _GLIBCXX_STD_P::max_element(__begin, __end); }
// Sequential fallback
- template<typename ForwardIterator, typename Comparator>
- inline ForwardIterator
- max_element(ForwardIterator begin, ForwardIterator end, Comparator comp,
+ template<typename _FIterator, typename _Compare>
+ inline _FIterator
+ max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::max_element(begin, end, comp); }
+ { return _GLIBCXX_STD_P::max_element(__begin, __end, __comp); }
// Sequential fallback for input iterator case
- template<typename ForwardIterator, typename Comparator, typename IteratorTag>
- inline ForwardIterator
- max_element_switch(ForwardIterator begin, ForwardIterator end,
- Comparator comp, IteratorTag)
- { return max_element(begin, end, comp, __gnu_parallel::sequential_tag()); }
+ template<typename _FIterator, typename _Compare, typename _IteratorTag>
+ inline _FIterator
+ __max_element_switch(_FIterator __begin, _FIterator __end,
+ _Compare __comp, _IteratorTag)
+ { return max_element(__begin, __end, __comp,
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators
- template<typename RandomAccessIterator, typename Comparator>
- RandomAccessIterator
- max_element_switch(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism_tag
+ template<typename _RAIter, typename _Compare>
+ _RAIter
+ __max_element_switch(_RAIter __begin, _RAIter __end,
+ _Compare __comp, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag
= __gnu_parallel::parallel_balanced)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().max_element_minimal_n
- && __gnu_parallel::is_parallel(parallelism_tag)))
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
{
- RandomAccessIterator res(begin);
- __gnu_parallel::identity_selector<RandomAccessIterator>
- functionality;
+ _RAIter __res(__begin);
+ __gnu_parallel::__identity_selector<_RAIter>
+ __functionality;
__gnu_parallel::
- for_each_template_random_access(begin, end,
- __gnu_parallel::nothing(),
- functionality,
- __gnu_parallel::
- max_element_reduct<Comparator,
- RandomAccessIterator>(comp),
- res, res, -1, parallelism_tag);
- return res;
+ __for_each_template_random_access(
+ __begin, __end, __gnu_parallel::_Nothing(), __functionality,
+ __gnu_parallel::__max_element_reduct<_Compare, _RAIter>(__comp),
+ __res, __res, -1, __parallelism_tag);
+ return __res;
}
else
- return max_element(begin, end, comp, __gnu_parallel::sequential_tag());
+ return max_element(__begin, __end, __comp,
+ __gnu_parallel::sequential_tag());
}
// Public interface, insert default comparator
- template<typename ForwardIterator>
- inline ForwardIterator
- max_element(ForwardIterator begin, ForwardIterator end,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _FIterator>
+ inline _FIterator
+ max_element(_FIterator __begin, _FIterator __end,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef typename iterator_traits<ForwardIterator>::value_type value_type;
- return max_element(begin, end, std::less<value_type>(), parallelism_tag);
+ typedef typename iterator_traits<_FIterator>::value_type _ValueType;
+ return max_element(__begin, __end, std::less<_ValueType>(),
+ __parallelism_tag);
}
- template<typename ForwardIterator>
- inline ForwardIterator
- max_element(ForwardIterator begin, ForwardIterator end)
+ template<typename _FIterator>
+ inline _FIterator
+ max_element(_FIterator __begin, _FIterator __end)
{
- typedef typename iterator_traits<ForwardIterator>::value_type value_type;
- return max_element(begin, end, std::less<value_type>());
+ typedef typename iterator_traits<_FIterator>::value_type _ValueType;
+ return max_element(__begin, __end, std::less<_ValueType>());
}
// Public interface
- template<typename ForwardIterator, typename Comparator>
- inline ForwardIterator
- max_element(ForwardIterator begin, ForwardIterator end, Comparator comp,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _FIterator, typename _Compare>
+ inline _FIterator
+ max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<ForwardIterator> traits_type;
- typedef typename traits_type::iterator_category iterator_category;
- return max_element_switch(begin, end, comp, iterator_category(),
- parallelism_tag);
+ typedef iterator_traits<_FIterator> _TraitsType;
+ typedef typename _TraitsType::iterator_category _IteratorCategory;
+ return __max_element_switch(__begin, __end, __comp, _IteratorCategory(),
+ __parallelism_tag);
}
- template<typename ForwardIterator, typename Comparator>
- inline ForwardIterator
- max_element(ForwardIterator begin, ForwardIterator end, Comparator comp)
+ template<typename _FIterator, typename _Compare>
+ inline _FIterator
+ max_element(_FIterator __begin, _FIterator __end, _Compare __comp)
{
- typedef iterator_traits<ForwardIterator> traits_type;
- typedef typename traits_type::iterator_category iterator_category;
- return max_element_switch(begin, end, comp, iterator_category());
+ typedef iterator_traits<_FIterator> _TraitsType;
+ typedef typename _TraitsType::iterator_category _IteratorCategory;
+ return __max_element_switch(__begin, __end, __comp, _IteratorCategory());
}
// Sequential fallback
- template<typename ForwardIterator>
- inline ForwardIterator
- min_element(ForwardIterator begin, ForwardIterator end,
+ template<typename _FIterator>
+ inline _FIterator
+ min_element(_FIterator __begin, _FIterator __end,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::min_element(begin, end); }
+ { return _GLIBCXX_STD_P::min_element(__begin, __end); }
// Sequential fallback
- template<typename ForwardIterator, typename Comparator>
- inline ForwardIterator
- min_element(ForwardIterator begin, ForwardIterator end, Comparator comp,
+ template<typename _FIterator, typename _Compare>
+ inline _FIterator
+ min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
__gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::min_element(begin, end, comp); }
+ { return _GLIBCXX_STD_P::min_element(__begin, __end, __comp); }
// Sequential fallback for input iterator case
- template<typename ForwardIterator, typename Comparator, typename IteratorTag>
- inline ForwardIterator
- min_element_switch(ForwardIterator begin, ForwardIterator end,
- Comparator comp, IteratorTag)
- { return min_element(begin, end, comp, __gnu_parallel::sequential_tag()); }
+ template<typename _FIterator, typename _Compare, typename _IteratorTag>
+ inline _FIterator
+ __min_element_switch(_FIterator __begin, _FIterator __end,
+ _Compare __comp, _IteratorTag)
+ { return min_element(__begin, __end, __comp,
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators
- template<typename RandomAccessIterator, typename Comparator>
- RandomAccessIterator
- min_element_switch(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism_tag
+ template<typename _RAIter, typename _Compare>
+ _RAIter
+ __min_element_switch(_RAIter __begin, _RAIter __end,
+ _Compare __comp, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag
= __gnu_parallel::parallel_balanced)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
>= __gnu_parallel::_Settings::get().min_element_minimal_n
- && __gnu_parallel::is_parallel(parallelism_tag)))
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
{
- RandomAccessIterator res(begin);
- __gnu_parallel::identity_selector<RandomAccessIterator>
- functionality;
+ _RAIter __res(__begin);
+ __gnu_parallel::__identity_selector<_RAIter>
+ __functionality;
__gnu_parallel::
- for_each_template_random_access(begin, end,
- __gnu_parallel::nothing(),
- functionality,
- __gnu_parallel::
- min_element_reduct<Comparator,
- RandomAccessIterator>(comp),
- res, res, -1, parallelism_tag);
- return res;
+ __for_each_template_random_access(
+ __begin, __end, __gnu_parallel::_Nothing(), __functionality,
+ __gnu_parallel::__min_element_reduct<_Compare, _RAIter>(__comp),
+ __res, __res, -1, __parallelism_tag);
+ return __res;
}
else
- return min_element(begin, end, comp, __gnu_parallel::sequential_tag());
+ return min_element(__begin, __end, __comp,
+ __gnu_parallel::sequential_tag());
}
// Public interface, insert default comparator
- template<typename ForwardIterator>
- inline ForwardIterator
- min_element(ForwardIterator begin, ForwardIterator end,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _FIterator>
+ inline _FIterator
+ min_element(_FIterator __begin, _FIterator __end,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef typename iterator_traits<ForwardIterator>::value_type value_type;
- return min_element(begin, end, std::less<value_type>(), parallelism_tag);
+ typedef typename iterator_traits<_FIterator>::value_type _ValueType;
+ return min_element(__begin, __end, std::less<_ValueType>(),
+ __parallelism_tag);
}
- template<typename ForwardIterator>
- inline ForwardIterator
- min_element(ForwardIterator begin, ForwardIterator end)
+ template<typename _FIterator>
+ inline _FIterator
+ min_element(_FIterator __begin, _FIterator __end)
{
- typedef typename iterator_traits<ForwardIterator>::value_type value_type;
- return min_element(begin, end, std::less<value_type>());
+ typedef typename iterator_traits<_FIterator>::value_type _ValueType;
+ return min_element(__begin, __end, std::less<_ValueType>());
}
// Public interface
- template<typename ForwardIterator, typename Comparator>
- inline ForwardIterator
- min_element(ForwardIterator begin, ForwardIterator end, Comparator comp,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _FIterator, typename _Compare>
+ inline _FIterator
+ min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<ForwardIterator> traits_type;
- typedef typename traits_type::iterator_category iterator_category;
- return min_element_switch(begin, end, comp, iterator_category(),
- parallelism_tag);
+ typedef iterator_traits<_FIterator> _TraitsType;
+ typedef typename _TraitsType::iterator_category _IteratorCategory;
+ return __min_element_switch(__begin, __end, __comp, _IteratorCategory(),
+ __parallelism_tag);
}
- template<typename ForwardIterator, typename Comparator>
- inline ForwardIterator
- min_element(ForwardIterator begin, ForwardIterator end, Comparator comp)
+ template<typename _FIterator, typename _Compare>
+ inline _FIterator
+ min_element(_FIterator __begin, _FIterator __end, _Compare __comp)
{
- typedef iterator_traits<ForwardIterator> traits_type;
- typedef typename traits_type::iterator_category iterator_category;
- return min_element_switch(begin, end, comp, iterator_category());
+ typedef iterator_traits<_FIterator> _TraitsType;
+ typedef typename _TraitsType::iterator_category _IteratorCategory;
+ return __min_element_switch(__begin, __end, __comp, _IteratorCategory());
}
} // end namespace
} // end namespace
diff --git a/libstdc++-v3/include/parallel/algobase.h b/libstdc++-v3/include/parallel/algobase.h
index aaffb3e5f3b..b0571a47933 100644
--- a/libstdc++-v3/include/parallel/algobase.h
+++ b/libstdc++-v3/include/parallel/algobase.h
@@ -50,230 +50,222 @@ namespace __parallel
// NB: equal and lexicographical_compare require mismatch.
// Sequential fallback
- template<typename InputIterator1, typename InputIterator2>
- inline pair<InputIterator1, InputIterator2>
- mismatch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
- __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::mismatch(begin1, end1, begin2); }
+ template<typename _IIter1, typename _IIter2>
+ inline pair<_IIter1, _IIter2>
+ mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::mismatch(__begin1, __end1, __begin2); }
// Sequential fallback
- template<typename InputIterator1, typename InputIterator2,
- typename Predicate>
- inline pair<InputIterator1, InputIterator2>
- mismatch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
- Predicate pred, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::mismatch(begin1, end1, begin2, pred); }
+ template<typename _IIter1, typename _IIter2, typename _Predicate>
+ inline pair<_IIter1, _IIter2>
+ mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
+ _Predicate __pred, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::mismatch(__begin1, __end1, __begin2, __pred); }
// Sequential fallback for input iterator case
- template<typename InputIterator1, typename InputIterator2,
- typename Predicate, typename IteratorTag1, typename IteratorTag2>
- inline pair<InputIterator1, InputIterator2>
- mismatch_switch(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, Predicate pred, IteratorTag1,
- IteratorTag2)
- { return _GLIBCXX_STD_P::mismatch(begin1, end1, begin2, pred); }
+ template<typename _IIter1, typename _IIter2,
+ typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
+ inline pair<_IIter1, _IIter2>
+ __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
+ _Predicate __pred, _IteratorTag1, _IteratorTag2)
+ { return _GLIBCXX_STD_P::mismatch(__begin1, __end1, __begin2, __pred); }
// Parallel mismatch for random access iterators
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename Predicate>
- pair<RandomAccessIterator1, RandomAccessIterator2>
- mismatch_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2, Predicate pred,
- random_access_iterator_tag, random_access_iterator_tag)
+ template<typename _RAIter1, typename _RAIter2, typename _Predicate>
+ pair<_RAIter1, _RAIter2>
+ __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1,
+ _RAIter2 __begin2, _Predicate __pred,
+ random_access_iterator_tag, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(true))
- {
- RandomAccessIterator1 res =
- __gnu_parallel::find_template(begin1, end1, begin2, pred,
- __gnu_parallel::
- mismatch_selector()).first;
- return make_pair(res , begin2 + (res - begin1));
- }
+ {
+ _RAIter1 __res =
+ __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred,
+ __gnu_parallel::
+ __mismatch_selector()).first;
+ return make_pair(__res , __begin2 + (__res - __begin1));
+ }
else
- return _GLIBCXX_STD_P::mismatch(begin1, end1, begin2, pred);
+ return _GLIBCXX_STD_P::mismatch(__begin1, __end1, __begin2, __pred);
}
// Public interface
- template<typename InputIterator1, typename InputIterator2>
- inline pair<InputIterator1, InputIterator2>
- mismatch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2)
+ template<typename _IIter1, typename _IIter2>
+ inline pair<_IIter1, _IIter2>
+ mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
{
- typedef std::iterator_traits<InputIterator1> iterator1_traits;
- typedef std::iterator_traits<InputIterator2> iterator2_traits;
- typedef typename iterator1_traits::value_type value1_type;
- typedef typename iterator2_traits::value_type value2_type;
- typedef typename iterator1_traits::iterator_category iterator1_category;
- typedef typename iterator2_traits::iterator_category iterator2_category;
+ typedef std::iterator_traits<_IIter1> iterator1_traits;
+ typedef std::iterator_traits<_IIter2> iterator2_traits;
+ typedef typename iterator1_traits::value_type _ValueType1;
+ typedef typename iterator2_traits::value_type _ValueType2;
+ typedef typename iterator1_traits::iterator_category _IteratorCategory1;
+ typedef typename iterator2_traits::iterator_category _IteratorCategory2;
- typedef __gnu_parallel::equal_to<value1_type, value2_type> equal_to_type;
+ typedef __gnu_parallel::equal_to<_ValueType1, _ValueType2> equal_to_type;
- return mismatch_switch(begin1, end1, begin2, equal_to_type(),
- iterator1_category(), iterator2_category());
+ return __mismatch_switch(__begin1, __end1, __begin2, equal_to_type(),
+ _IteratorCategory1(), _IteratorCategory2());
}
// Public interface
- template<typename InputIterator1, typename InputIterator2,
- typename Predicate>
- inline pair<InputIterator1, InputIterator2>
- mismatch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
- Predicate pred)
+ template<typename _IIter1, typename _IIter2, typename _Predicate>
+ inline pair<_IIter1, _IIter2>
+ mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
+ _Predicate __pred)
{
- typedef std::iterator_traits<InputIterator1> iterator1_traits;
- typedef std::iterator_traits<InputIterator2> iterator2_traits;
- typedef typename iterator1_traits::iterator_category iterator1_category;
- typedef typename iterator2_traits::iterator_category iterator2_category;
+ typedef std::iterator_traits<_IIter1> iterator1_traits;
+ typedef std::iterator_traits<_IIter2> iterator2_traits;
+ typedef typename iterator1_traits::iterator_category _IteratorCategory1;
+ typedef typename iterator2_traits::iterator_category _IteratorCategory2;
- return mismatch_switch(begin1, end1, begin2, pred, iterator1_category(),
- iterator2_category());
+ return __mismatch_switch(__begin1, __end1, __begin2, __pred,
+ _IteratorCategory1(), _IteratorCategory2());
}
// Sequential fallback
- template<typename InputIterator1, typename InputIterator2>
+ template<typename _IIter1, typename _IIter2>
inline bool
- equal(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
- __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::equal(begin1, end1, begin2); }
+ equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::equal(__begin1, __end1, __begin2); }
// Sequential fallback
- template<typename InputIterator1, typename InputIterator2,
- typename Predicate>
+ template<typename _IIter1, typename _IIter2, typename _Predicate>
inline bool
- equal(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
- Predicate pred, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::equal(begin1, end1, begin2, pred); }
+ equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
+ _Predicate __pred, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::equal(__begin1, __end1, __begin2, __pred); }
// Public interface
- template<typename InputIterator1, typename InputIterator2>
+ template<typename _IIter1, typename _IIter2>
inline bool
- equal(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2)
- { return mismatch(begin1, end1, begin2).first == end1; }
+ equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
+ { return mismatch(__begin1, __end1, __begin2).first == __end1; }
// Public interface
- template<typename InputIterator1, typename InputIterator2,
- typename Predicate>
+ template<typename _IIter1, typename _IIter2, typename _Predicate>
inline bool
- equal(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
- Predicate pred)
- { return mismatch(begin1, end1, begin2, pred).first == end1; }
+ equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
+ _Predicate __pred)
+ { return mismatch(__begin1, __end1, __begin2, __pred).first == __end1; }
// Sequential fallback
- template<typename InputIterator1, typename InputIterator2>
+ template<typename _IIter1, typename _IIter2>
inline bool
- lexicographical_compare(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::lexicographical_compare(begin1, end1,
- begin2, end2); }
+ lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::lexicographical_compare(__begin1, __end1,
+ __begin2, __end2); }
// Sequential fallback
- template<typename InputIterator1, typename InputIterator2,
- typename Predicate>
+ template<typename _IIter1, typename _IIter2, typename _Predicate>
inline bool
- lexicographical_compare(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- Predicate pred, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::lexicographical_compare(begin1, end1,
- begin2, end2, pred); }
+ lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _Predicate __pred, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::lexicographical_compare(
+ __begin1, __end1, __begin2, __end2, __pred); }
// Sequential fallback for input iterator case
- template<typename InputIterator1, typename InputIterator2,
- typename Predicate, typename IteratorTag1, typename IteratorTag2>
+ template<typename _IIter1, typename _IIter2,
+ typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
inline bool
- lexicographical_compare_switch(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- Predicate pred, IteratorTag1, IteratorTag2)
- { return _GLIBCXX_STD_P::lexicographical_compare(begin1, end1,
- begin2, end2, pred); }
+ __lexicographical_compare_switch(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _Predicate __pred,
+ _IteratorTag1, _IteratorTag2)
+ { return _GLIBCXX_STD_P::lexicographical_compare(
+ __begin1, __end1, __begin2, __end2, __pred); }
// Parallel lexicographical_compare for random access iterators
// Limitation: Both valuetypes must be the same
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename Predicate>
+ template<typename _RAIter1, typename _RAIter2, typename _Predicate>
bool
- lexicographical_compare_switch(RandomAccessIterator1 begin1,
- RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2,
- RandomAccessIterator2 end2, Predicate pred,
- random_access_iterator_tag,
- random_access_iterator_tag)
+ __lexicographical_compare_switch(_RAIter1 __begin1, _RAIter1 __end1,
+ _RAIter2 __begin2, _RAIter2 __end2,
+ _Predicate __pred,
+ random_access_iterator_tag,
+ random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(true))
- {
- typedef iterator_traits<RandomAccessIterator1> traits1_type;
- typedef typename traits1_type::value_type value1_type;
-
- typedef iterator_traits<RandomAccessIterator2> traits2_type;
- typedef typename traits2_type::value_type value2_type;
-
- typedef __gnu_parallel::equal_from_less<Predicate, value1_type,
- value2_type> equal_type;
-
- // Longer sequence in first place.
- if ((end1 - begin1) < (end2 - begin2))
- {
- typedef pair<RandomAccessIterator1, RandomAccessIterator2>
- pair_type;
- pair_type mm = mismatch_switch(begin1, end1, begin2,
- equal_type(pred),
- random_access_iterator_tag(),
- random_access_iterator_tag());
-
- return (mm.first == end1) || bool(pred(*mm.first, *mm.second));
- }
- else
- {
- typedef pair<RandomAccessIterator2, RandomAccessIterator1>
- pair_type;
- pair_type mm = mismatch_switch(begin2, end2, begin1,
- equal_type(pred),
- random_access_iterator_tag(),
- random_access_iterator_tag());
-
- return (mm.first != end2) && bool(pred(*mm.second, *mm.first));
- }
- }
+ {
+ typedef iterator_traits<_RAIter1> _TraitsType1;
+ typedef typename _TraitsType1::value_type _ValueType1;
+
+ typedef iterator_traits<_RAIter2> _TraitsType2;
+ typedef typename _TraitsType2::value_type _ValueType2;
+
+ typedef __gnu_parallel::
+ _EqualFromLess<_Predicate, _ValueType1, _ValueType2>
+ _EqualFromLessCompare;
+
+ // Longer sequence in first place.
+ if ((__end1 - __begin1) < (__end2 - __begin2))
+ {
+ typedef pair<_RAIter1, _RAIter2> _SpotType;
+ _SpotType __mm = __mismatch_switch(__begin1, __end1, __begin2,
+ _EqualFromLessCompare(__pred),
+ random_access_iterator_tag(),
+ random_access_iterator_tag());
+
+ return (__mm.first == __end1)
+ || bool(__pred(*__mm.first, *__mm.second));
+ }
+ else
+ {
+ typedef pair<_RAIter2, _RAIter1> _SpotType;
+ _SpotType __mm = __mismatch_switch(__begin2, __end2, __begin1,
+ _EqualFromLessCompare(__pred),
+ random_access_iterator_tag(),
+ random_access_iterator_tag());
+
+ return (__mm.first != __end2)
+ && bool(__pred(*__mm.second, *__mm.first));
+ }
+ }
else
- return _GLIBCXX_STD_P::lexicographical_compare(begin1, end1,
- begin2, end2, pred);
+ return _GLIBCXX_STD_P::lexicographical_compare(
+ __begin1, __end1, __begin2, __end2, __pred);
}
// Public interface
- template<typename InputIterator1, typename InputIterator2>
+ template<typename _IIter1, typename _IIter2>
inline bool
- lexicographical_compare(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2)
+ lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2)
{
- typedef iterator_traits<InputIterator1> traits1_type;
- typedef typename traits1_type::value_type value1_type;
- typedef typename traits1_type::iterator_category iterator1_category;
-
- typedef iterator_traits<InputIterator2> traits2_type;
- typedef typename traits2_type::value_type value2_type;
- typedef typename traits2_type::iterator_category iterator2_category;
- typedef __gnu_parallel::less<value1_type, value2_type> less_type;
-
- return lexicographical_compare_switch(begin1, end1, begin2, end2,
- less_type(), iterator1_category(),
- iterator2_category());
+ typedef iterator_traits<_IIter1> _TraitsType1;
+ typedef typename _TraitsType1::value_type _ValueType1;
+ typedef typename _TraitsType1::iterator_category _IteratorCategory1;
+
+ typedef iterator_traits<_IIter2> _TraitsType2;
+ typedef typename _TraitsType2::value_type _ValueType2;
+ typedef typename _TraitsType2::iterator_category _IteratorCategory2;
+ typedef __gnu_parallel::_Less<_ValueType1, _ValueType2> _LessType;
+
+ return __lexicographical_compare_switch(
+ __begin1, __end1, __begin2, __end2, _LessType(),
+ _IteratorCategory1(), _IteratorCategory2());
}
// Public interface
- template<typename InputIterator1, typename InputIterator2,
- typename Predicate>
+ template<typename _IIter1, typename _IIter2, typename _Predicate>
inline bool
- lexicographical_compare(InputIterator1 begin1, InputIterator1 end1,
- InputIterator2 begin2, InputIterator2 end2,
- Predicate pred)
+ lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
+ _IIter2 __begin2, _IIter2 __end2,
+ _Predicate __pred)
{
- typedef iterator_traits<InputIterator1> traits1_type;
- typedef typename traits1_type::iterator_category iterator1_category;
+ typedef iterator_traits<_IIter1> _TraitsType1;
+ typedef typename _TraitsType1::iterator_category _IteratorCategory1;
- typedef iterator_traits<InputIterator2> traits2_type;
- typedef typename traits2_type::iterator_category iterator2_category;
+ typedef iterator_traits<_IIter2> _TraitsType2;
+ typedef typename _TraitsType2::iterator_category _IteratorCategory2;
- return lexicographical_compare_switch(begin1, end1, begin2, end2, pred,
- iterator1_category(),
- iterator2_category());
+ return __lexicographical_compare_switch(
+ __begin1, __end1, __begin2, __end2, __pred,
+ _IteratorCategory1(), _IteratorCategory2());
}
} // end namespace
} // end namespace
diff --git a/libstdc++-v3/include/parallel/algorithmfwd.h b/libstdc++-v3/include/parallel/algorithmfwd.h
index 7c3b3f23ff2..5c93615da26 100644
--- a/libstdc++-v3/include/parallel/algorithmfwd.h
+++ b/libstdc++-v3/include/parallel/algorithmfwd.h
@@ -48,11 +48,11 @@ namespace __parallel
template<typename _FIter, typename _IterTag>
_FIter
- adjacent_find_switch(_FIter, _FIter, _IterTag);
+ __adjacent_find_switch(_FIter, _FIter, _IterTag);
template<typename _RAIter>
_RAIter
- adjacent_find_switch(_RAIter, _RAIter, random_access_iterator_tag);
+ __adjacent_find_switch(_RAIter, _RAIter, random_access_iterator_tag);
template<typename _FIter, typename _BiPredicate>
@@ -62,16 +62,16 @@ namespace __parallel
template<typename _FIter, typename _BiPredicate>
_FIter
adjacent_find(_FIter, _FIter, _BiPredicate,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _FIter, typename _BiPredicate, typename _IterTag>
_FIter
- adjacent_find_switch(_FIter, _FIter, _BiPredicate, _IterTag);
+ __adjacent_find_switch(_FIter, _FIter, _BiPredicate, _IterTag);
template<typename _RAIter, typename _BiPredicate>
_RAIter
- adjacent_find_switch(_RAIter, _RAIter, _BiPredicate,
- random_access_iterator_tag);
+ __adjacent_find_switch(_RAIter, _RAIter, _BiPredicate,
+ random_access_iterator_tag);
template<typename _IIter, typename _Tp>
@@ -88,13 +88,13 @@ namespace __parallel
template<typename _IIter, typename _Tp, typename _IterTag>
typename iterator_traits<_IIter>::difference_type
- count_switch(_IIter, _IIter, const _Tp&, _IterTag);
+ __count_switch(_IIter, _IIter, const _Tp&, _IterTag);
template<typename _RAIter, typename _Tp>
typename iterator_traits<_RAIter>::difference_type
- count_switch(_RAIter, _RAIter, const _Tp&, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism
- = __gnu_parallel::parallel_unbalanced);
+ __count_switch(_RAIter, _RAIter, const _Tp&, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism
+ = __gnu_parallel::parallel_unbalanced);
template<typename _IIter, typename _Predicate>
@@ -111,31 +111,31 @@ namespace __parallel
template<typename _IIter, typename _Predicate, typename _IterTag>
typename iterator_traits<_IIter>::difference_type
- count_if_switch(_IIter, _IIter, _Predicate, _IterTag);
+ __count_if_switch(_IIter, _IIter, _Predicate, _IterTag);
template<typename _RAIter, typename _Predicate>
typename iterator_traits<_RAIter>::difference_type
- count_if_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism
- = __gnu_parallel::parallel_unbalanced);
+ __count_if_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism
+ = __gnu_parallel::parallel_unbalanced);
// algobase.h
template<typename _IIter1, typename _IIter2>
bool
equal(_IIter1, _IIter1, _IIter2, __gnu_parallel::sequential_tag);
- template<typename _IIter1, typename _IIter2, typename Predicate>
+ template<typename _IIter1, typename _IIter2, typename _Predicate>
bool
- equal(_IIter1, _IIter1, _IIter2, Predicate,
- __gnu_parallel::sequential_tag);
+ equal(_IIter1, _IIter1, _IIter2, _Predicate,
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2>
bool
equal(_IIter1, _IIter1, _IIter2);
- template<typename _IIter1, typename _IIter2, typename Predicate>
+ template<typename _IIter1, typename _IIter2, typename _Predicate>
bool
- equal(_IIter1, _IIter1, _IIter2, Predicate);
+ equal(_IIter1, _IIter1, _IIter2, _Predicate);
template<typename _IIter, typename _Tp>
_IIter
@@ -143,15 +143,15 @@ namespace __parallel
template<typename _IIter, typename _Tp>
_IIter
- find(_IIter, _IIter, const _Tp& val);
+ find(_IIter, _IIter, const _Tp& __val);
template<typename _IIter, typename _Tp, typename _IterTag>
_IIter
- find_switch(_IIter, _IIter, const _Tp&, _IterTag);
+ __find_switch(_IIter, _IIter, const _Tp&, _IterTag);
template<typename _RAIter, typename _Tp>
_RAIter
- find_switch(_RAIter, _RAIter, const _Tp&, random_access_iterator_tag);
+ __find_switch(_RAIter, _RAIter, const _Tp&, random_access_iterator_tag);
template<typename _IIter, typename _Predicate>
_IIter
@@ -163,21 +163,21 @@ namespace __parallel
template<typename _IIter, typename _Predicate, typename _IterTag>
_IIter
- find_if_switch(_IIter, _IIter, _Predicate, _IterTag);
+ __find_if_switch(_IIter, _IIter, _Predicate, _IterTag);
template<typename _RAIter, typename _Predicate>
_RAIter
- find_if_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag);
+ __find_if_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag);
template<typename _IIter, typename _FIter>
_IIter
find_first_of(_IIter, _IIter, _FIter, _FIter,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter, typename _FIter, typename _BiPredicate>
_IIter
find_first_of(_IIter, _IIter, _FIter, _FIter, _BiPredicate,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter, typename _FIter, typename _BiPredicate>
_IIter
@@ -188,21 +188,22 @@ namespace __parallel
find_first_of(_IIter, _IIter, _FIter, _FIter);
template<typename _IIter, typename _FIter,
- typename _IterTag1, typename _IterTag2>
+ typename _IterTag1, typename _IterTag2>
_IIter
- find_first_of_switch(_IIter, _IIter, _FIter, _FIter, _IterTag1, _IterTag2);
+ __find_first_of_switch(
+ _IIter, _IIter, _FIter, _FIter, _IterTag1, _IterTag2);
template<typename _RAIter, typename _FIter, typename _BiPredicate,
- typename _IterTag>
+ typename _IterTag>
_RAIter
- find_first_of_switch(_RAIter, _RAIter, _FIter, _FIter, _BiPredicate,
- random_access_iterator_tag, _IterTag);
+ __find_first_of_switch(_RAIter, _RAIter, _FIter, _FIter, _BiPredicate,
+ random_access_iterator_tag, _IterTag);
template<typename _IIter, typename _FIter, typename _BiPredicate,
- typename _IterTag1, typename _IterTag2>
+ typename _IterTag1, typename _IterTag2>
_IIter
- find_first_of_switch(_IIter, _IIter, _FIter, _FIter, _BiPredicate,
- _IterTag1, _IterTag2);
+ __find_first_of_switch(_IIter, _IIter, _FIter, _FIter, _BiPredicate,
+ _IterTag1, _IterTag2);
template<typename _IIter, typename _Function>
@@ -219,13 +220,13 @@ namespace __parallel
template<typename _IIter, typename _Function, typename _IterTag>
_Function
- for_each_switch(_IIter, _IIter, _Function, _IterTag);
+ __for_each_switch(_IIter, _IIter, _Function, _IterTag);
template<typename _RAIter, typename _Function>
_Function
- for_each_switch(_RAIter, _RAIter, _Function, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism
- = __gnu_parallel::parallel_balanced);
+ __for_each_switch(_RAIter, _RAIter, _Function, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism
+ = __gnu_parallel::parallel_balanced);
template<typename _FIter, typename _Generator>
@@ -242,13 +243,13 @@ namespace __parallel
template<typename _FIter, typename _Generator, typename _IterTag>
void
- generate_switch(_FIter, _FIter, _Generator, _IterTag);
+ __generate_switch(_FIter, _FIter, _Generator, _IterTag);
template<typename _RAIter, typename _Generator>
void
- generate_switch(_RAIter, _RAIter, _Generator, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism
- = __gnu_parallel::parallel_balanced);
+ __generate_switch(_RAIter, _RAIter, _Generator, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism
+ = __gnu_parallel::parallel_balanced);
template<typename _OIter, typename _Size, typename _Generator>
_OIter
@@ -263,25 +264,25 @@ namespace __parallel
generate_n(_OIter, _Size, _Generator, __gnu_parallel::_Parallelism);
template<typename _OIter, typename _Size, typename _Generator,
- typename _IterTag>
+ typename _IterTag>
_OIter
- generate_n_switch(_OIter, _Size, _Generator, _IterTag);
+ __generate_n_switch(_OIter, _Size, _Generator, _IterTag);
template<typename _RAIter, typename _Size, typename _Generator>
_RAIter
- generate_n_switch(_RAIter, _Size, _Generator, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism
- = __gnu_parallel::parallel_balanced);
+ __generate_n_switch(_RAIter, _Size, _Generator, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism
+ = __gnu_parallel::parallel_balanced);
template<typename _IIter1, typename _IIter2>
bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _Predicate>
bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Predicate,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2>
bool
@@ -292,16 +293,16 @@ namespace __parallel
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Predicate);
template<typename _IIter1, typename _IIter2,
- typename _Predicate, typename _IterTag1, typename _IterTag2>
+ typename _Predicate, typename _IterTag1, typename _IterTag2>
bool
- lexicographical_compare_switch(_IIter1, _IIter1, _IIter2, _IIter2,
- _Predicate, _IterTag1, _IterTag2);
+ __lexicographical_compare_switch(_IIter1, _IIter1, _IIter2, _IIter2,
+ _Predicate, _IterTag1, _IterTag2);
template<typename _RAIter1, typename _RAIter2, typename _Predicate>
bool
- lexicographical_compare_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
- _Predicate, random_access_iterator_tag,
- random_access_iterator_tag);
+ __lexicographical_compare_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
+ _Predicate, random_access_iterator_tag,
+ random_access_iterator_tag);
// algo.h
template<typename _IIter1, typename _IIter2>
@@ -311,7 +312,7 @@ namespace __parallel
template<typename _IIter1, typename _IIter2, typename _Predicate>
pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2, _Predicate,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2>
pair<_IIter1, _IIter2>
@@ -322,15 +323,15 @@ namespace __parallel
mismatch(_IIter1, _IIter1, _IIter2, _Predicate);
template<typename _IIter1, typename _IIter2, typename _Predicate,
- typename _IterTag1, typename _IterTag2>
+ typename _IterTag1, typename _IterTag2>
pair<_IIter1, _IIter2>
- mismatch_switch(_IIter1, _IIter1, _IIter2, _Predicate,
- _IterTag1, _IterTag2);
+ __mismatch_switch(_IIter1, _IIter1, _IIter2, _Predicate,
+ _IterTag1, _IterTag2);
template<typename _RAIter1, typename _RAIter2, typename _Predicate>
pair<_RAIter1, _RAIter2>
- mismatch_switch(_RAIter1, _RAIter1, _RAIter2, _Predicate,
- random_access_iterator_tag, random_access_iterator_tag);
+ __mismatch_switch(_RAIter1, _RAIter1, _RAIter2, _Predicate,
+ random_access_iterator_tag, random_access_iterator_tag);
template<typename _FIter1, typename _FIter2>
_FIter1
@@ -343,7 +344,7 @@ namespace __parallel
template<typename _FIter1, typename _FIter2, typename _BiPredicate>
_FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _FIter1, typename _FIter2, typename _BiPredicate>
_FIter1
@@ -351,119 +352,119 @@ namespace __parallel
template<typename _RAIter1, typename _RAIter2>
_RAIter1
- search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
- random_access_iterator_tag, random_access_iterator_tag);
+ __search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
+ random_access_iterator_tag, random_access_iterator_tag);
template<typename _FIter1, typename _FIter2, typename _IterTag1,
- typename _IterTag2>
+ typename _IterTag2>
_FIter1
- search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _IterTag1, _IterTag2);
+ __search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _IterTag1, _IterTag2);
template<typename _RAIter1, typename _RAIter2, typename _BiPredicate>
_RAIter1
- search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _BiPredicate,
- random_access_iterator_tag, random_access_iterator_tag);
+ __search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _BiPredicate,
+ random_access_iterator_tag, random_access_iterator_tag);
template<typename _FIter1, typename _FIter2, typename _BiPredicate,
- typename _IterTag1, typename _IterTag2>
+ typename _IterTag1, typename _IterTag2>
_FIter1
- search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate,
- _IterTag1, _IterTag2);
+ __search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate,
+ _IterTag1, _IterTag2);
template<typename _FIter, typename _Integer, typename _Tp>
_FIter
search_n(_FIter, _FIter, _Integer, const _Tp&,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _FIter, typename _Integer, typename _Tp,
- typename _BiPredicate>
+ typename _BiPredicate>
_FIter
search_n(_FIter, _FIter, _Integer, const _Tp&, _BiPredicate,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _FIter, typename _Integer, typename _Tp>
_FIter
search_n(_FIter, _FIter, _Integer, const _Tp&);
template<typename _FIter, typename _Integer, typename _Tp,
- typename _BiPredicate>
+ typename _BiPredicate>
_FIter
search_n(_FIter, _FIter, _Integer, const _Tp&, _BiPredicate);
template<typename _RAIter, typename _Integer, typename _Tp,
- typename _BiPredicate>
+ typename _BiPredicate>
_RAIter
- search_n_switch(_RAIter, _RAIter, _Integer, const _Tp&,
- _BiPredicate, random_access_iterator_tag);
+ __search_n_switch(_RAIter, _RAIter, _Integer, const _Tp&,
+ _BiPredicate, random_access_iterator_tag);
template<typename _FIter, typename _Integer, typename _Tp,
- typename _BiPredicate, typename _IterTag>
+ typename _BiPredicate, typename _IterTag>
_FIter
- search_n_switch(_FIter, _FIter, _Integer, const _Tp&,
- _BiPredicate, _IterTag);
+ __search_n_switch(_FIter, _FIter, _Integer, const _Tp&,
+ _BiPredicate, _IterTag);
- template<typename _IIter, typename _OIter, typename UnaryOperation>
+ template<typename _IIter, typename _OIter, typename _UnaryOperation>
_OIter
- transform(_IIter, _IIter, _OIter, UnaryOperation);
+ transform(_IIter, _IIter, _OIter, _UnaryOperation);
- template<typename _IIter, typename _OIter, typename UnaryOperation>
+ template<typename _IIter, typename _OIter, typename _UnaryOperation>
_OIter
- transform(_IIter, _IIter, _OIter, UnaryOperation,
- __gnu_parallel::sequential_tag);
+ transform(_IIter, _IIter, _OIter, _UnaryOperation,
+ __gnu_parallel::sequential_tag);
- template<typename _IIter, typename _OIter, typename UnaryOperation>
+ template<typename _IIter, typename _OIter, typename _UnaryOperation>
_OIter
- transform(_IIter, _IIter, _OIter, UnaryOperation,
- __gnu_parallel::_Parallelism);
+ transform(_IIter, _IIter, _OIter, _UnaryOperation,
+ __gnu_parallel::_Parallelism);
- template<typename _IIter, typename _OIter, typename UnaryOperation,
- typename _IterTag1, typename _IterTag2>
+ template<typename _IIter, typename _OIter, typename _UnaryOperation,
+ typename _IterTag1, typename _IterTag2>
_OIter
- transform1_switch(_IIter, _IIter, _OIter, UnaryOperation,
- _IterTag1, _IterTag2);
+ __transform1_switch(_IIter, _IIter, _OIter, _UnaryOperation,
+ _IterTag1, _IterTag2);
- template<typename _RAIIter, typename _RAOIter, typename UnaryOperation>
+ template<typename _RAIIter, typename _RAOIter, typename _UnaryOperation>
_RAOIter
- transform1_switch(_RAIIter, _RAIIter, _RAOIter, UnaryOperation,
- random_access_iterator_tag, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism
- = __gnu_parallel::parallel_balanced);
+ __transform1_switch(_RAIIter, _RAIIter, _RAOIter, _UnaryOperation,
+ random_access_iterator_tag, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism
+ = __gnu_parallel::parallel_balanced);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _BiOperation>
+ typename _BiOperation>
_OIter
transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _BiOperation>
+ typename _BiOperation>
_OIter
transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _BiOperation>
+ typename _BiOperation>
_OIter
transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation,
- __gnu_parallel::_Parallelism);
+ __gnu_parallel::_Parallelism);
template<typename _RAIter1, typename _RAIter2, typename _RAIter3,
- typename _BiOperation>
+ typename _BiOperation>
_RAIter3
- transform2_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter3, _BiOperation,
- random_access_iterator_tag, random_access_iterator_tag,
- random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism
- = __gnu_parallel::parallel_balanced);
+ __transform2_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter3, _BiOperation,
+ random_access_iterator_tag, random_access_iterator_tag,
+ random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism
+ = __gnu_parallel::parallel_balanced);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _BiOperation, typename _Tag1,
- typename _Tag2, typename _Tag3>
+ typename _BiOperation, typename _Tag1,
+ typename _Tag2, typename _Tag3>
_OIter
- transform2_switch(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation,
- _Tag1, _Tag2, _Tag3);
+ __transform2_switch(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation,
+ _Tag1, _Tag2, _Tag3);
template<typename _FIter, typename _Tp>
@@ -473,21 +474,21 @@ namespace __parallel
template<typename _FIter, typename _Tp>
void
replace(_FIter, _FIter, const _Tp&, const _Tp&,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _FIter, typename _Tp>
void
replace(_FIter, _FIter, const _Tp&, const _Tp&,
- __gnu_parallel::_Parallelism);
+ __gnu_parallel::_Parallelism);
template<typename _FIter, typename _Tp, typename _IterTag>
void
- replace_switch(_FIter, _FIter, const _Tp&, const _Tp&, _IterTag);
+ __replace_switch(_FIter, _FIter, const _Tp&, const _Tp&, _IterTag);
template<typename _RAIter, typename _Tp>
void
- replace_switch(_RAIter, _RAIter, const _Tp&, const _Tp&,
- random_access_iterator_tag, __gnu_parallel::_Parallelism);
+ __replace_switch(_RAIter, _RAIter, const _Tp&, const _Tp&,
+ random_access_iterator_tag, __gnu_parallel::_Parallelism);
template<typename _FIter, typename _Predicate, typename _Tp>
@@ -497,23 +498,23 @@ namespace __parallel
template<typename _FIter, typename _Predicate, typename _Tp>
void
replace_if(_FIter, _FIter, _Predicate, const _Tp&,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _FIter, typename _Predicate, typename _Tp>
void
replace_if(_FIter, _FIter, _Predicate, const _Tp&,
- __gnu_parallel::_Parallelism);
+ __gnu_parallel::_Parallelism);
template<typename _FIter, typename _Predicate, typename _Tp,
- typename _IterTag>
+ typename _IterTag>
void
- replace_if_switch(_FIter, _FIter, _Predicate, const _Tp&, _IterTag);
+ __replace_if_switch(_FIter, _FIter, _Predicate, const _Tp&, _IterTag);
template<typename _RAIter, typename _Predicate, typename _Tp>
void
- replace_if_switch(_RAIter, _RAIter, _Predicate, const _Tp&,
- random_access_iterator_tag,
- __gnu_parallel::_Parallelism);
+ __replace_if_switch(_RAIter, _RAIter, _Predicate, const _Tp&,
+ random_access_iterator_tag,
+ __gnu_parallel::_Parallelism);
template<typename _FIter>
@@ -542,28 +543,29 @@ namespace __parallel
template<typename _FIter, typename _Compare, typename _IterTag>
_FIter
- max_element_switch(_FIter, _FIter, _Compare, _IterTag);
+ __max_element_switch(_FIter, _FIter, _Compare, _IterTag);
template<typename _RAIter, typename _Compare>
_RAIter
- max_element_switch(_RAIter, _RAIter, _Compare, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism
- = __gnu_parallel::parallel_balanced);
+ __max_element_switch(
+ _RAIter, _RAIter, _Compare, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism
+ = __gnu_parallel::parallel_balanced);
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _Compare>
+ typename _Compare>
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _Compare>
+ typename _Compare>
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
@@ -572,18 +574,18 @@ namespace __parallel
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _Compare, typename _IterTag1, typename _IterTag2,
- typename _IterTag3>
+ typename _Compare, typename _IterTag1, typename _IterTag2,
+ typename _IterTag3>
_OIter
- merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare,
- _IterTag1, _IterTag2, _IterTag3);
+ __merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare,
+ _IterTag1, _IterTag2, _IterTag3);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _Compare>
+ typename _Compare>
_OIter
- merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare,
- random_access_iterator_tag, random_access_iterator_tag,
- random_access_iterator_tag);
+ __merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare,
+ random_access_iterator_tag, random_access_iterator_tag,
+ random_access_iterator_tag);
template<typename _FIter>
@@ -596,7 +598,8 @@ namespace __parallel
template<typename _FIter>
_FIter
- min_element(_FIter, _FIter, __gnu_parallel::_Parallelism parallelism_tag);
+ min_element(_FIter, _FIter,
+ __gnu_parallel::_Parallelism __parallelism_tag);
template<typename _FIter, typename _Compare>
_FIter
@@ -612,13 +615,14 @@ namespace __parallel
template<typename _FIter, typename _Compare, typename _IterTag>
_FIter
- min_element_switch(_FIter, _FIter, _Compare, _IterTag);
+ __min_element_switch(_FIter, _FIter, _Compare, _IterTag);
template<typename _RAIter, typename _Compare>
_RAIter
- min_element_switch(_RAIter, _RAIter, _Compare, random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism
- = __gnu_parallel::parallel_balanced);
+ __min_element_switch(
+ _RAIter, _RAIter, _Compare, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism
+ = __gnu_parallel::parallel_balanced);
template<typename _RAIter>
void
@@ -627,7 +631,7 @@ namespace __parallel
template<typename _RAIter, typename _Compare>
void
nth_element(_RAIter, _RAIter, _RAIter, _Compare,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _RAIter, typename _Compare>
void
@@ -640,7 +644,7 @@ namespace __parallel
template<typename _RAIter, typename _Compare>
void
partial_sort(_RAIter, _RAIter, _RAIter, _Compare,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _RAIter>
void
@@ -654,21 +658,22 @@ namespace __parallel
void
partial_sort(_RAIter, _RAIter, _RAIter);
- template<typename _FIter, typename Predicate>
+ template<typename _FIter, typename _Predicate>
_FIter
- partition(_FIter, _FIter, Predicate, __gnu_parallel::sequential_tag);
+ partition(_FIter, _FIter, _Predicate, __gnu_parallel::sequential_tag);
- template<typename _FIter, typename Predicate>
+ template<typename _FIter, typename _Predicate>
_FIter
- partition(_FIter, _FIter, Predicate);
+ partition(_FIter, _FIter, _Predicate);
- template<typename _FIter, typename Predicate, typename _IterTag>
+ template<typename _FIter, typename _Predicate, typename _IterTag>
_FIter
- partition_switch(_FIter, _FIter, Predicate, _IterTag);
+ __partition_switch(_FIter, _FIter, _Predicate, _IterTag);
- template<typename _RAIter, typename Predicate>
+ template<typename _RAIter, typename _Predicate>
_RAIter
- partition_switch(_RAIter, _RAIter, Predicate, random_access_iterator_tag);
+ __partition_switch(
+ _RAIter, _RAIter, _Predicate, random_access_iterator_tag);
template<typename _RAIter>
void
@@ -677,7 +682,7 @@ namespace __parallel
template<typename _RAIter, typename _RandomNumberGenerator>
void
random_shuffle(_RAIter, _RAIter, _RandomNumberGenerator&,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _RAIter>
void
@@ -690,147 +695,147 @@ namespace __parallel
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename Predicate>
+ typename _Predicate>
_OIter
- set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate,
- __gnu_parallel::sequential_tag);
+ set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate,
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _Predicate>
+ typename _Predicate>
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate);
template<typename _IIter1, typename _IIter2, typename _Predicate,
- typename _OIter, typename _IterTag1, typename _IterTag2,
- typename _IterTag3>
+ typename _OIter, typename _IterTag1, typename _IterTag2,
+ typename _IterTag3>
_OIter
- set_union_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
- _Predicate, _IterTag1, _IterTag2, _IterTag3);
+ __set_union_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
+ _Predicate, _IterTag1, _IterTag2, _IterTag3);
template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter,
- typename _Predicate>
+ typename _Predicate>
_Output_RAIter
- set_union_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter,
- _Predicate, random_access_iterator_tag,
- random_access_iterator_tag, random_access_iterator_tag);
+ __set_union_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter,
+ _Predicate, random_access_iterator_tag,
+ random_access_iterator_tag, random_access_iterator_tag);
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _Predicate>
+ typename _Predicate>
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _Predicate>
+ typename _Predicate>
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate);
template<typename _IIter1, typename _IIter2, typename _Predicate,
- typename _OIter, typename _IterTag1, typename _IterTag2,
- typename _IterTag3>
+ typename _OIter, typename _IterTag1, typename _IterTag2,
+ typename _IterTag3>
_OIter
- set_intersection_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
- _Predicate, _IterTag1, _IterTag2, _IterTag3);
+ __set_intersection_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
+ _Predicate, _IterTag1, _IterTag2, _IterTag3);
template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter,
- typename _Predicate>
+ typename _Predicate>
_Output_RAIter
- set_intersection_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
- _Output_RAIter, _Predicate,
- random_access_iterator_tag,
- random_access_iterator_tag,
- random_access_iterator_tag);
+ __set_intersection_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
+ _Output_RAIter, _Predicate,
+ random_access_iterator_tag,
+ random_access_iterator_tag,
+ random_access_iterator_tag);
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _Predicate>
+ typename _Predicate>
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
- _Predicate, __gnu_parallel::sequential_tag);
+ _Predicate, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _Predicate>
+ typename _Predicate>
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
- _Predicate);
+ _Predicate);
template<typename _IIter1, typename _IIter2, typename _Predicate,
- typename _OIter, typename _IterTag1, typename _IterTag2,
- typename _IterTag3>
+ typename _OIter, typename _IterTag1, typename _IterTag2,
+ typename _IterTag3>
_OIter
- set_symmetric_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2,
- _OIter, _Predicate, _IterTag1, _IterTag2,
- _IterTag3);
+ __set_symmetric_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2,
+ _OIter, _Predicate, _IterTag1, _IterTag2,
+ _IterTag3);
template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter,
- typename _Predicate>
+ typename _Predicate>
_Output_RAIter
- set_symmetric_difference_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
- _Output_RAIter, _Predicate,
- random_access_iterator_tag,
- random_access_iterator_tag,
- random_access_iterator_tag);
+ __set_symmetric_difference_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
+ _Output_RAIter, _Predicate,
+ random_access_iterator_tag,
+ random_access_iterator_tag,
+ random_access_iterator_tag);
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _Predicate>
+ typename _Predicate>
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter>
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
- typename _Predicate>
+ typename _Predicate>
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate);
template<typename _IIter1, typename _IIter2, typename _Predicate,
- typename _OIter, typename _IterTag1, typename _IterTag2,
- typename _IterTag3>
+ typename _OIter, typename _IterTag1, typename _IterTag2,
+ typename _IterTag3>
_OIter
- set_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
- _Predicate, _IterTag1, _IterTag2, _IterTag3);
+ __set_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
+ _Predicate, _IterTag1, _IterTag2, _IterTag3);
template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter,
- typename _Predicate>
+ typename _Predicate>
_Output_RAIter
- set_difference_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
- _Output_RAIter, _Predicate,
- random_access_iterator_tag,
- random_access_iterator_tag,
- random_access_iterator_tag);
+ __set_difference_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2,
+ _Output_RAIter, _Predicate,
+ random_access_iterator_tag,
+ random_access_iterator_tag,
+ random_access_iterator_tag);
template<typename _RAIter>
@@ -872,7 +877,7 @@ namespace __parallel
template<typename _IIter, typename _OIter, typename _Predicate>
_OIter
unique_copy(_IIter, _IIter, _OIter, _Predicate,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter, typename _OIter>
_OIter
@@ -883,15 +888,15 @@ namespace __parallel
unique_copy(_IIter, _IIter, _OIter, _Predicate);
template<typename _IIter, typename _OIter, typename _Predicate,
- typename _IterTag1, typename _IterTag2>
+ typename _IterTag1, typename _IterTag2>
_OIter
- unique_copy_switch(_IIter, _IIter, _OIter, _Predicate,
- _IterTag1, _IterTag2);
+ __unique_copy_switch(_IIter, _IIter, _OIter, _Predicate,
+ _IterTag1, _IterTag2);
template<typename _RAIter, typename _RandomAccess_OIter, typename _Predicate>
_RandomAccess_OIter
- unique_copy_switch(_RAIter, _RAIter, _RandomAccess_OIter, _Predicate,
- random_access_iterator_tag, random_access_iterator_tag);
+ __unique_copy_switch(_RAIter, _RAIter, _RandomAccess_OIter, _Predicate,
+ random_access_iterator_tag, random_access_iterator_tag);
} // end namespace __parallel
} // end namespace std
diff --git a/libstdc++-v3/include/parallel/balanced_quicksort.h b/libstdc++-v3/include/parallel/balanced_quicksort.h
index 2310110bb62..85e4d699e26 100644
--- a/libstdc++-v3/include/parallel/balanced_quicksort.h
+++ b/libstdc++-v3/include/parallel/balanced_quicksort.h
@@ -58,171 +58,179 @@
namespace __gnu_parallel
{
/** @brief Information local to one thread in the parallel quicksort run. */
-template<typename RandomAccessIterator>
- struct QSBThreadLocal
+template<typename _RAIter>
+ struct _QSBThreadLocal
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
/** @brief Continuous part of the sequence, described by an
iterator pair. */
- typedef std::pair<RandomAccessIterator, RandomAccessIterator> Piece;
+ typedef std::pair<_RAIter, _RAIter> _Piece;
/** @brief Initial piece to work on. */
- Piece initial;
+ _Piece _M_initial;
/** @brief Work-stealing queue. */
- RestrictedBoundedConcurrentQueue<Piece> leftover_parts;
+ _RestrictedBoundedConcurrentQueue<_Piece> _M_leftover_parts;
/** @brief Number of threads involved in this algorithm. */
- thread_index_t num_threads;
+ _ThreadIndex _M_num_threads;
/** @brief Pointer to a counter of elements left over to sort. */
- volatile difference_type* elements_leftover;
+ volatile _DifferenceType* _M_elements_leftover;
/** @brief The complete sequence to sort. */
- Piece global;
+ _Piece _M_global;
/** @brief Constructor.
- * @param queue_size Size of the work-stealing queue. */
- QSBThreadLocal(int queue_size) : leftover_parts(queue_size) { }
+ * @param __queue_size size of the work-stealing queue. */
+ _QSBThreadLocal(int __queue_size) : _M_leftover_parts(__queue_size) { }
};
/** @brief Balanced quicksort divide step.
- * @param begin Begin iterator of subsequence.
- * @param end End iterator of subsequence.
- * @param comp Comparator.
- * @param num_threads Number of threads that are allowed to work on
+ * @param __begin Begin iterator of subsequence.
+ * @param __end End iterator of subsequence.
+ * @param __comp Comparator.
+ * @param __num_threads Number of threads that are allowed to work on
* this part.
- * @pre @c (end-begin)>=1 */
-template<typename RandomAccessIterator, typename Comparator>
- typename std::iterator_traits<RandomAccessIterator>::difference_type
- qsb_divide(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp, thread_index_t num_threads)
+ * @pre @__c (__end-__begin)>=1 */
+template<typename _RAIter, typename _Compare>
+ typename std::iterator_traits<_RAIter>::difference_type
+ __qsb_divide(_RAIter __begin, _RAIter __end,
+ _Compare __comp, _ThreadIndex __num_threads)
{
- _GLIBCXX_PARALLEL_ASSERT(num_threads > 0);
+ _GLIBCXX_PARALLEL_ASSERT(__num_threads > 0);
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- RandomAccessIterator pivot_pos =
- median_of_three_iterators(begin, begin + (end - begin) / 2,
- end - 1, comp);
+ _RAIter __pivot_pos =
+ __median_of_three_iterators(__begin, __begin + (__end - __begin) / 2,
+ __end - 1, __comp);
#if defined(_GLIBCXX_ASSERTIONS)
// Must be in between somewhere.
- difference_type n = end - begin;
+ _DifferenceType __n = __end - __begin;
_GLIBCXX_PARALLEL_ASSERT(
- (!comp(*pivot_pos, *begin) && !comp(*(begin + n / 2), *pivot_pos))
- || (!comp(*pivot_pos, *begin) && !comp(*(end - 1), *pivot_pos))
- || (!comp(*pivot_pos, *(begin + n / 2)) && !comp(*begin, *pivot_pos))
- || (!comp(*pivot_pos, *(begin + n / 2)) && !comp(*(end - 1), *pivot_pos))
- || (!comp(*pivot_pos, *(end - 1)) && !comp(*begin, *pivot_pos))
- || (!comp(*pivot_pos, *(end - 1)) && !comp(*(begin + n / 2), *pivot_pos)));
+ (!__comp(*__pivot_pos, *__begin) &&
+ !__comp(*(__begin + __n / 2), *__pivot_pos))
+ || (!__comp(*__pivot_pos, *__begin) &&
+ !__comp(*(__end - 1), *__pivot_pos))
+ || (!__comp(*__pivot_pos, *(__begin + __n / 2)) &&
+ !__comp(*__begin, *__pivot_pos))
+ || (!__comp(*__pivot_pos, *(__begin + __n / 2)) &&
+ !__comp(*(__end - 1), *__pivot_pos))
+ || (!__comp(*__pivot_pos, *(__end - 1)) &&
+ !__comp(*__begin, *__pivot_pos))
+ || (!__comp(*__pivot_pos, *(__end - 1)) &&
+ !__comp(*(__begin + __n / 2), *__pivot_pos)));
#endif
// Swap pivot value to end.
- if (pivot_pos != (end - 1))
- std::swap(*pivot_pos, *(end - 1));
- pivot_pos = end - 1;
+ if (__pivot_pos != (__end - 1))
+ std::swap(*__pivot_pos, *(__end - 1));
+ __pivot_pos = __end - 1;
- __gnu_parallel::binder2nd<Comparator, value_type, value_type, bool>
- pred(comp, *pivot_pos);
+ __gnu_parallel::binder2nd<_Compare, _ValueType, _ValueType, bool>
+ __pred(__comp, *__pivot_pos);
- // Divide, returning end - begin - 1 in the worst case.
- difference_type split_pos = parallel_partition(
- begin, end - 1, pred, num_threads);
+ // Divide, returning __end - __begin - 1 in the worst case.
+ _DifferenceType __split_pos = __parallel_partition(
+ __begin, __end - 1, __pred, __num_threads);
// Swap back pivot to middle.
- std::swap(*(begin + split_pos), *pivot_pos);
- pivot_pos = begin + split_pos;
+ std::swap(*(__begin + __split_pos), *__pivot_pos);
+ __pivot_pos = __begin + __split_pos;
#if _GLIBCXX_ASSERTIONS
- RandomAccessIterator r;
- for (r = begin; r != pivot_pos; ++r)
- _GLIBCXX_PARALLEL_ASSERT(comp(*r, *pivot_pos));
- for (; r != end; ++r)
- _GLIBCXX_PARALLEL_ASSERT(!comp(*r, *pivot_pos));
+ _RAIter __r;
+ for (__r = __begin; __r != __pivot_pos; ++__r)
+ _GLIBCXX_PARALLEL_ASSERT(__comp(*__r, *__pivot_pos));
+ for (; __r != __end; ++__r)
+ _GLIBCXX_PARALLEL_ASSERT(!__comp(*__r, *__pivot_pos));
#endif
- return split_pos;
+ return __split_pos;
}
/** @brief Quicksort conquer step.
- * @param tls Array of thread-local storages.
- * @param begin Begin iterator of subsequence.
- * @param end End iterator of subsequence.
- * @param comp Comparator.
- * @param iam Number of the thread processing this function.
- * @param num_threads
+ * @param __tls Array of thread-local storages.
+ * @param __begin Begin iterator of subsequence.
+ * @param __end End iterator of subsequence.
+ * @param __comp Comparator.
+ * @param __iam Number of the thread processing this function.
+ * @param __num_threads
* Number of threads that are allowed to work on this part. */
-template<typename RandomAccessIterator, typename Comparator>
+template<typename _RAIter, typename _Compare>
void
- qsb_conquer(QSBThreadLocal<RandomAccessIterator>** tls,
- RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp,
- thread_index_t iam, thread_index_t num_threads,
- bool parent_wait)
+ __qsb_conquer(_QSBThreadLocal<_RAIter>** __tls,
+ _RAIter __begin, _RAIter __end,
+ _Compare __comp,
+ _ThreadIndex __iam, _ThreadIndex __num_threads,
+ bool __parent_wait)
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- difference_type n = end - begin;
+ _DifferenceType __n = __end - __begin;
- if (num_threads <= 1 || n <= 1)
+ if (__num_threads <= 1 || __n <= 1)
{
- tls[iam]->initial.first = begin;
- tls[iam]->initial.second = end;
+ __tls[__iam]->_M_initial.first = __begin;
+ __tls[__iam]->_M_initial.second = __end;
- qsb_local_sort_with_helping(tls, comp, iam, parent_wait);
+ __qsb_local_sort_with_helping(__tls, __comp, __iam, __parent_wait);
return;
}
// Divide step.
- difference_type split_pos = qsb_divide(begin, end, comp, num_threads);
+ _DifferenceType __split_pos =
+ __qsb_divide(__begin, __end, __comp, __num_threads);
#if _GLIBCXX_ASSERTIONS
- _GLIBCXX_PARALLEL_ASSERT(0 <= split_pos && split_pos < (end - begin));
+ _GLIBCXX_PARALLEL_ASSERT(0 <= __split_pos &&
+ __split_pos < (__end - __begin));
#endif
- thread_index_t num_threads_leftside =
- std::max<thread_index_t>(1, std::min<thread_index_t>(
- num_threads - 1, split_pos * num_threads / n));
+ _ThreadIndex __num_threads_leftside =
+ std::max<_ThreadIndex>(1, std::min<_ThreadIndex>(
+ __num_threads - 1, __split_pos * __num_threads / __n));
# pragma omp atomic
- *tls[iam]->elements_leftover -= (difference_type)1;
+ *__tls[__iam]->_M_elements_leftover -= (_DifferenceType)1;
// Conquer step.
# pragma omp parallel num_threads(2)
{
- bool wait;
+ bool __wait;
if(omp_get_num_threads() < 2)
- wait = false;
+ __wait = false;
else
- wait = parent_wait;
+ __wait = __parent_wait;
# pragma omp sections
{
# pragma omp section
{
- qsb_conquer(tls, begin, begin + split_pos, comp,
- iam,
- num_threads_leftside,
- wait);
- wait = parent_wait;
+ __qsb_conquer(__tls, __begin, __begin + __split_pos, __comp,
+ __iam,
+ __num_threads_leftside,
+ __wait);
+ __wait = __parent_wait;
}
// The pivot_pos is left in place, to ensure termination.
# pragma omp section
{
- qsb_conquer(tls, begin + split_pos + 1, end, comp,
- iam + num_threads_leftside,
- num_threads - num_threads_leftside,
- wait);
- wait = parent_wait;
+ __qsb_conquer(__tls, __begin + __split_pos + 1, __end, __comp,
+ __iam + __num_threads_leftside,
+ __num_threads - __num_threads_leftside,
+ __wait);
+ __wait = __parent_wait;
}
}
}
@@ -230,175 +238,178 @@ template<typename RandomAccessIterator, typename Comparator>
/**
* @brief Quicksort step doing load-balanced local sort.
- * @param tls Array of thread-local storages.
- * @param comp Comparator.
- * @param iam Number of the thread processing this function.
+ * @param __tls Array of thread-local storages.
+ * @param __comp Comparator.
+ * @param __iam Number of the thread processing this function.
*/
-template<typename RandomAccessIterator, typename Comparator>
+template<typename _RAIter, typename _Compare>
void
- qsb_local_sort_with_helping(QSBThreadLocal<RandomAccessIterator>** tls,
- Comparator& comp, int iam, bool wait)
+ __qsb_local_sort_with_helping(_QSBThreadLocal<_RAIter>** __tls,
+ _Compare& __comp, int __iam, bool __wait)
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
- typedef std::pair<RandomAccessIterator, RandomAccessIterator> Piece;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
+ typedef std::pair<_RAIter, _RAIter> _Piece;
- QSBThreadLocal<RandomAccessIterator>& tl = *tls[iam];
+ _QSBThreadLocal<_RAIter>& __tl = *__tls[__iam];
- difference_type base_case_n =
+ _DifferenceType __base_case_n =
_Settings::get().sort_qsb_base_case_maximal_n;
- if (base_case_n < 2)
- base_case_n = 2;
- thread_index_t num_threads = tl.num_threads;
+ if (__base_case_n < 2)
+ __base_case_n = 2;
+ _ThreadIndex __num_threads = __tl._M_num_threads;
// Every thread has its own random number generator.
- random_number rng(iam + 1);
+ _RandomNumber __rng(__iam + 1);
- Piece current = tl.initial;
+ _Piece __current = __tl._M_initial;
- difference_type elements_done = 0;
+ _DifferenceType __elements_done = 0;
#if _GLIBCXX_ASSERTIONS
- difference_type total_elements_done = 0;
+ _DifferenceType __total_elements_done = 0;
#endif
for (;;)
{
- // Invariant: current must be a valid (maybe empty) range.
- RandomAccessIterator begin = current.first, end = current.second;
- difference_type n = end - begin;
+ // Invariant: __current must be a valid (maybe empty) range.
+ _RAIter __begin = __current.first, __end = __current.second;
+ _DifferenceType __n = __end - __begin;
- if (n > base_case_n)
+ if (__n > __base_case_n)
{
// Divide.
- RandomAccessIterator pivot_pos = begin + rng(n);
+ _RAIter __pivot_pos = __begin + __rng(__n);
- // Swap pivot_pos value to end.
- if (pivot_pos != (end - 1))
- std::swap(*pivot_pos, *(end - 1));
- pivot_pos = end - 1;
+ // Swap __pivot_pos value to end.
+ if (__pivot_pos != (__end - 1))
+ std::swap(*__pivot_pos, *(__end - 1));
+ __pivot_pos = __end - 1;
__gnu_parallel::binder2nd
- <Comparator, value_type, value_type, bool>
- pred(comp, *pivot_pos);
+ <_Compare, _ValueType, _ValueType, bool>
+ __pred(__comp, *__pivot_pos);
// Divide, leave pivot unchanged in last place.
- RandomAccessIterator split_pos1, split_pos2;
- split_pos1 = __gnu_sequential::partition(begin, end - 1, pred);
+ _RAIter __split_pos1, __split_pos2;
+ __split_pos1 =
+ __gnu_sequential::partition(__begin, __end - 1, __pred);
- // Left side: < pivot_pos; right side: >= pivot_pos.
+ // Left side: < __pivot_pos; __right side: >= __pivot_pos.
#if _GLIBCXX_ASSERTIONS
- _GLIBCXX_PARALLEL_ASSERT(begin <= split_pos1 && split_pos1 < end);
+ _GLIBCXX_PARALLEL_ASSERT(__begin <= __split_pos1
+ && __split_pos1 < __end);
#endif
// Swap pivot back to middle.
- if (split_pos1 != pivot_pos)
- std::swap(*split_pos1, *pivot_pos);
- pivot_pos = split_pos1;
+ if (__split_pos1 != __pivot_pos)
+ std::swap(*__split_pos1, *__pivot_pos);
+ __pivot_pos = __split_pos1;
- // In case all elements are equal, split_pos1 == 0.
- if ((split_pos1 + 1 - begin) < (n >> 7)
- || (end - split_pos1) < (n >> 7))
+ // In case all elements are equal, __split_pos1 == 0.
+ if ((__split_pos1 + 1 - __begin) < (__n >> 7)
+ || (__end - __split_pos1) < (__n >> 7))
{
// Very unequal split, one part smaller than one 128th
// elements not strictly larger than the pivot.
- __gnu_parallel::unary_negate<__gnu_parallel::binder1st
- <Comparator, value_type, value_type, bool>, value_type>
- pred(__gnu_parallel::binder1st
- <Comparator, value_type, value_type, bool>(comp,
- *pivot_pos));
+ __gnu_parallel::__unary_negate<__gnu_parallel::__binder1st
+ <_Compare, _ValueType, _ValueType, bool>, _ValueType>
+ __pred(__gnu_parallel::__binder1st
+ <_Compare, _ValueType, _ValueType, bool>(
+ __comp, *__pivot_pos));
// Find other end of pivot-equal range.
- split_pos2 = __gnu_sequential::partition(split_pos1 + 1,
- end, pred);
+ __split_pos2 = __gnu_sequential::partition(__split_pos1 + 1,
+ __end, __pred);
}
else
// Only skip the pivot.
- split_pos2 = split_pos1 + 1;
+ __split_pos2 = __split_pos1 + 1;
// Elements equal to pivot are done.
- elements_done += (split_pos2 - split_pos1);
+ __elements_done += (__split_pos2 - __split_pos1);
#if _GLIBCXX_ASSERTIONS
- total_elements_done += (split_pos2 - split_pos1);
+ __total_elements_done += (__split_pos2 - __split_pos1);
#endif
// Always push larger part onto stack.
- if (((split_pos1 + 1) - begin) < (end - (split_pos2)))
+ if (((__split_pos1 + 1) - __begin) < (__end - (__split_pos2)))
{
// Right side larger.
- if ((split_pos2) != end)
- tl.leftover_parts.push_front(std::make_pair(split_pos2,
- end));
+ if ((__split_pos2) != __end)
+ __tl._M_leftover_parts.push_front(
+ std::make_pair(__split_pos2, __end));
- //current.first = begin; //already set anyway
- current.second = split_pos1;
+ //__current.first = __begin; //already set anyway
+ __current.second = __split_pos1;
continue;
}
else
{
// Left side larger.
- if (begin != split_pos1)
- tl.leftover_parts.push_front(std::make_pair(begin,
- split_pos1));
+ if (__begin != __split_pos1)
+ __tl._M_leftover_parts.push_front(std::make_pair(__begin,
+ __split_pos1));
- current.first = split_pos2;
- //current.second = end; //already set anyway
+ __current.first = __split_pos2;
+ //__current.second = __end; //already set anyway
continue;
}
}
else
{
- __gnu_sequential::sort(begin, end, comp);
- elements_done += n;
+ __gnu_sequential::sort(__begin, __end, __comp);
+ __elements_done += __n;
#if _GLIBCXX_ASSERTIONS
- total_elements_done += n;
+ __total_elements_done += __n;
#endif
// Prefer own stack, small pieces.
- if (tl.leftover_parts.pop_front(current))
+ if (__tl._M_leftover_parts.pop_front(__current))
continue;
# pragma omp atomic
- *tl.elements_leftover -= elements_done;
+ *__tl._M_elements_leftover -= __elements_done;
- elements_done = 0;
+ __elements_done = 0;
#if _GLIBCXX_ASSERTIONS
- double search_start = omp_get_wtime();
+ double __search_start = omp_get_wtime();
#endif
// Look for new work.
- bool successfully_stolen = false;
- while (wait && *tl.elements_leftover > 0 && !successfully_stolen
+ bool __successfully_stolen = false;
+ while (__wait && *__tl._M_elements_leftover > 0
+ && !__successfully_stolen
#if _GLIBCXX_ASSERTIONS
- // Possible dead-lock.
- && (omp_get_wtime() < (search_start + 1.0))
+ // Possible dead-lock.
+ && (omp_get_wtime() < (__search_start + 1.0))
#endif
)
{
- thread_index_t victim;
- victim = rng(num_threads);
+ _ThreadIndex __victim;
+ __victim = __rng(__num_threads);
// Large pieces.
- successfully_stolen = (victim != iam)
- && tls[victim]->leftover_parts.pop_back(current);
- if (!successfully_stolen)
- yield();
+ __successfully_stolen = (__victim != __iam)
+ && __tls[__victim]->_M_leftover_parts.pop_back(__current);
+ if (!__successfully_stolen)
+ __yield();
#if !defined(__ICC) && !defined(__ECC)
# pragma omp flush
#endif
}
#if _GLIBCXX_ASSERTIONS
- if (omp_get_wtime() >= (search_start + 1.0))
+ if (omp_get_wtime() >= (__search_start + 1.0))
{
sleep(1);
_GLIBCXX_PARALLEL_ASSERT(omp_get_wtime()
- < (search_start + 1.0));
+ < (__search_start + 1.0));
}
#endif
- if (!successfully_stolen)
+ if (!__successfully_stolen)
{
#if _GLIBCXX_ASSERTIONS
- _GLIBCXX_PARALLEL_ASSERT(*tl.elements_leftover == 0);
+ _GLIBCXX_PARALLEL_ASSERT(*__tl._M_elements_leftover == 0);
#endif
return;
}
@@ -407,70 +418,74 @@ template<typename RandomAccessIterator, typename Comparator>
}
/** @brief Top-level quicksort routine.
- * @param begin Begin iterator of sequence.
- * @param end End iterator of sequence.
- * @param comp Comparator.
- * @param num_threads Number of threads that are allowed to work on
+ * @param __begin Begin iterator of sequence.
+ * @param __end End iterator of sequence.
+ * @param __comp Comparator.
+ * @param __num_threads Number of threads that are allowed to work on
* this part.
*/
-template<typename RandomAccessIterator, typename Comparator>
+template<typename _RAIter, typename _Compare>
void
- parallel_sort_qsb(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp,
- thread_index_t num_threads)
+ __parallel_sort_qsb(_RAIter __begin, _RAIter __end,
+ _Compare __comp,
+ _ThreadIndex __num_threads)
{
- _GLIBCXX_CALL(end - begin)
+ _GLIBCXX_CALL(__end - __begin)
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
- typedef std::pair<RandomAccessIterator, RandomAccessIterator> Piece;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
+ typedef std::pair<_RAIter, _RAIter> _Piece;
- typedef QSBThreadLocal<RandomAccessIterator> tls_type;
+ typedef _QSBThreadLocal<_RAIter> _TLSType;
- difference_type n = end - begin;
+ _DifferenceType __n = __end - __begin;
- if (n <= 1)
+ if (__n <= 1)
return;
// At least one element per processor.
- if (num_threads > n)
- num_threads = static_cast<thread_index_t>(n);
+ if (__num_threads > __n)
+ __num_threads = static_cast<_ThreadIndex>(__n);
// Initialize thread local storage
- tls_type** tls = new tls_type*[num_threads];
- difference_type queue_size = num_threads * (thread_index_t)(log2(n) + 1);
- for (thread_index_t t = 0; t < num_threads; ++t)
- tls[t] = new QSBThreadLocal<RandomAccessIterator>(queue_size);
-
- // There can never be more than ceil(log2(n)) ranges on the stack, because
+ _TLSType** __tls = new _TLSType*[__num_threads];
+ _DifferenceType __queue_size =
+ __num_threads * (_ThreadIndex)(log2(__n) + 1);
+ for (_ThreadIndex __t = 0; __t < __num_threads; ++__t)
+ __tls[__t] = new _QSBThreadLocal<_RAIter>(__queue_size);
+
+ // There can never be more than ceil(log2(__n)) ranges on the stack,
+ // because
// 1. Only one processor pushes onto the stack
- // 2. The largest range has at most length n
+ // 2. The largest range has at most length __n
// 3. Each range is larger than half of the range remaining
- volatile difference_type elements_leftover = n;
- for (int i = 0; i < num_threads; ++i)
+ volatile _DifferenceType _M_elements_leftover = __n;
+ for (int __i = 0; __i < __num_threads; ++__i)
{
- tls[i]->elements_leftover = &elements_leftover;
- tls[i]->num_threads = num_threads;
- tls[i]->global = std::make_pair(begin, end);
+ __tls[__i]->_M_elements_leftover = &_M_elements_leftover;
+ __tls[__i]->_M_num_threads = __num_threads;
+ __tls[__i]->_M_global = std::make_pair(__begin, __end);
// Just in case nothing is left to assign.
- tls[i]->initial = std::make_pair(end, end);
+ __tls[__i]->_M_initial = std::make_pair(__end, __end);
}
// Main recursion call.
- qsb_conquer(tls, begin, begin + n, comp, 0, num_threads, true);
+ __qsb_conquer(
+ __tls, __begin, __begin + __n, __comp, 0, __num_threads, true);
#if _GLIBCXX_ASSERTIONS
// All stack must be empty.
- Piece dummy;
- for (int i = 1; i < num_threads; ++i)
- _GLIBCXX_PARALLEL_ASSERT(!tls[i]->leftover_parts.pop_back(dummy));
+ _Piece __dummy;
+ for (int __i = 1; __i < __num_threads; ++__i)
+ _GLIBCXX_PARALLEL_ASSERT(
+ !__tls[__i]->_M_leftover_parts.pop_back(__dummy));
#endif
- for (int i = 0; i < num_threads; ++i)
- delete tls[i];
- delete[] tls;
+ for (int __i = 0; __i < __num_threads; ++__i)
+ delete __tls[__i];
+ delete[] __tls;
}
} // namespace __gnu_parallel
diff --git a/libstdc++-v3/include/parallel/base.h b/libstdc++-v3/include/parallel/base.h
index 7f855dfca5c..6925696a72e 100644
--- a/libstdc++-v3/include/parallel/base.h
+++ b/libstdc++-v3/include/parallel/base.h
@@ -82,7 +82,7 @@ namespace __gnu_parallel
// and active, which imples that the OpenMP runtime is actually
// going to be linked in.
inline int
- get_max_threads()
+ __get_max_threads()
{
int __i = omp_get_max_threads();
return __i > 1 ? __i : 1;
@@ -90,91 +90,91 @@ namespace __gnu_parallel
inline bool
- is_parallel(const _Parallelism __p) { return __p != sequential; }
+ __is_parallel(const _Parallelism __p) { return __p != sequential; }
// XXX remove std::duplicates from here if possible,
// XXX but keep minimal dependencies.
-/** @brief Calculates the rounded-down logarithm of @c n for base 2.
- * @param n Argument.
+/** @brief Calculates the rounded-down logarithm of @__c __n for base 2.
+ * @param __n Argument.
* @return Returns 0 for any argument <1.
*/
-template<typename Size>
- inline Size
- __log2(Size n)
+template<typename _Size>
+ inline _Size
+ __log2(_Size __n)
{
- Size k;
- for (k = 0; n > 1; n >>= 1)
- ++k;
- return k;
+ _Size __k;
+ for (__k = 0; __n > 1; __n >>= 1)
+ ++__k;
+ return __k;
}
-/** @brief Encode two integers into one __gnu_parallel::lcas_t.
- * @param a First integer, to be encoded in the most-significant @c
- * lcas_t_bits/2 bits.
- * @param b Second integer, to be encoded in the least-significant
- * @c lcas_t_bits/2 bits.
- * @return __gnu_parallel::lcas_t value encoding @c a and @c b.
+/** @brief Encode two integers into one gnu_parallel::_CASable.
+ * @param __a First integer, to be encoded in the most-significant @__c
+ * _CASable_bits/2 bits.
+ * @param __b Second integer, to be encoded in the least-significant
+ * @__c _CASable_bits/2 bits.
+ * @return __gnu_parallel::_CASable _M_value encoding @__c __a and @__c __b.
* @see decode2
*/
-inline lcas_t
-encode2(int a, int b) //must all be non-negative, actually
+inline _CASable
+__encode2(int __a, int __b) //must all be non-negative, actually
{
- return (((lcas_t)a) << (lcas_t_bits / 2)) | (((lcas_t)b) << 0);
+ return (((_CASable)__a) << (_CASable_bits / 2)) | (((_CASable)__b) << 0);
}
-/** @brief Decode two integers from one __gnu_parallel::lcas_t.
- * @param x __gnu_parallel::lcas_t to decode integers from.
- * @param a First integer, to be decoded from the most-significant
- * @c lcas_t_bits/2 bits of @c x.
- * @param b Second integer, to be encoded in the least-significant
- * @c lcas_t_bits/2 bits of @c x.
- * @see encode2
+/** @brief Decode two integers from one gnu_parallel::_CASable.
+ * @param __x __gnu_parallel::_CASable to decode integers from.
+ * @param __a First integer, to be decoded from the most-significant
+ * @__c _CASable_bits/2 bits of @__c __x.
+ * @param __b Second integer, to be encoded in the least-significant
+ * @__c _CASable_bits/2 bits of @__c __x.
+ * @see __encode2
*/
inline void
-decode2(lcas_t x, int& a, int& b)
+decode2(_CASable __x, int& __a, int& __b)
{
- a = (int)((x >> (lcas_t_bits / 2)) & lcas_t_mask);
- b = (int)((x >> 0 ) & lcas_t_mask);
+ __a = (int)((__x >> (_CASable_bits / 2)) & _CASable_mask);
+ __b = (int)((__x >> 0 ) & _CASable_mask);
}
/** @brief Equivalent to std::min. */
-template<typename T>
- const T&
- min(const T& a, const T& b)
- { return (a < b) ? a : b; }
+template<typename _Tp>
+ const _Tp&
+ min(const _Tp& __a, const _Tp& __b)
+ { return (__a < __b) ? __a : __b; }
/** @brief Equivalent to std::max. */
-template<typename T>
- const T&
- max(const T& a, const T& b)
- { return (a > b) ? a : b; }
+template<typename _Tp>
+ const _Tp&
+ max(const _Tp& __a, const _Tp& __b)
+ { return (__a > __b) ? __a : __b; }
/** @brief Constructs predicate for equality from strict weak
* ordering predicate
*/
// XXX comparator at the end, as per others
-template<typename Comparator, typename T1, typename T2>
- class equal_from_less : public std::binary_function<T1, T2, bool>
+template<typename _Compare, typename _T1, typename _T2>
+ class _EqualFromLess : public std::binary_function<_T1, _T2, bool>
{
private:
- Comparator& comp;
+ _Compare& _M_comp;
public:
- equal_from_less(Comparator& _comp) : comp(_comp) { }
+ _EqualFromLess(_Compare& __comp) : _M_comp(__comp) { }
- bool operator()(const T1& a, const T2& b)
+ bool operator()(const _T1& __a, const _T2& __b)
{
- return !comp(a, b) && !comp(b, a);
+ return !_M_comp(__a, __b) && !_M_comp(__b, __a);
}
};
-/** @brief Similar to std::binder1st,
+/** @brief Similar to std::__binder1st,
* but giving the argument types explicitly. */
template<typename _Predicate, typename argument_type>
- class unary_negate
+ class __unary_negate
: public std::unary_function<argument_type, bool>
{
protected:
@@ -182,93 +182,93 @@ template<typename _Predicate, typename argument_type>
public:
explicit
- unary_negate(const _Predicate& __x) : _M_pred(__x) { }
+ __unary_negate(const _Predicate& __x) : _M_pred(__x) { }
bool
operator()(const argument_type& __x)
{ return !_M_pred(__x); }
};
-/** @brief Similar to std::binder1st,
+/** @brief Similar to std::__binder1st,
* but giving the argument types explicitly. */
-template<typename _Operation, typename first_argument_type,
- typename second_argument_type, typename result_type>
- class binder1st
- : public std::unary_function<second_argument_type, result_type>
+template<typename _Operation, typename _FirstArgumentType,
+ typename _SecondArgumentType, typename _ResultType>
+ class __binder1st
+ : public std::unary_function<_SecondArgumentType, _ResultType>
{
protected:
- _Operation op;
- first_argument_type value;
+ _Operation _M_op;
+ _FirstArgumentType _M_value;
public:
- binder1st(const _Operation& __x,
- const first_argument_type& __y)
- : op(__x), value(__y) { }
+ __binder1st(const _Operation& __x,
+ const _FirstArgumentType& __y)
+ : _M_op(__x), _M_value(__y) { }
- result_type
- operator()(const second_argument_type& __x)
- { return op(value, __x); }
+ _ResultType
+ operator()(const _SecondArgumentType& __x)
+ { return _M_op(_M_value, __x); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 109. Missing binders for non-const sequence elements
- result_type
- operator()(second_argument_type& __x) const
- { return op(value, __x); }
+ _ResultType
+ operator()(_SecondArgumentType& __x) const
+ { return _M_op(_M_value, __x); }
};
/**
* @brief Similar to std::binder2nd, but giving the argument types
* explicitly.
*/
-template<typename _Operation, typename first_argument_type,
- typename second_argument_type, typename result_type>
+template<typename _Operation, typename _FirstArgumentType,
+ typename _SecondArgumentType, typename _ResultType>
class binder2nd
- : public std::unary_function<first_argument_type, result_type>
+ : public std::unary_function<_FirstArgumentType, _ResultType>
{
protected:
- _Operation op;
- second_argument_type value;
+ _Operation _M_op;
+ _SecondArgumentType _M_value;
public:
binder2nd(const _Operation& __x,
- const second_argument_type& __y)
- : op(__x), value(__y) { }
+ const _SecondArgumentType& __y)
+ : _M_op(__x), _M_value(__y) { }
- result_type
- operator()(const first_argument_type& __x) const
- { return op(__x, value); }
+ _ResultType
+ operator()(const _FirstArgumentType& __x) const
+ { return _M_op(__x, _M_value); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 109. Missing binders for non-const sequence elements
- result_type
- operator()(first_argument_type& __x)
- { return op(__x, value); }
+ _ResultType
+ operator()(_FirstArgumentType& __x)
+ { return _M_op(__x, _M_value); }
};
/** @brief Similar to std::equal_to, but allows two different types. */
-template<typename T1, typename T2>
- struct equal_to : std::binary_function<T1, T2, bool>
+template<typename _T1, typename _T2>
+ struct equal_to : std::binary_function<_T1, _T2, bool>
{
- bool operator()(const T1& t1, const T2& t2) const
- { return t1 == t2; }
+ bool operator()(const _T1& __t1, const _T2& __t2) const
+ { return __t1 == __t2; }
};
/** @brief Similar to std::less, but allows two different types. */
-template<typename T1, typename T2>
- struct less : std::binary_function<T1, T2, bool>
+template<typename _T1, typename _T2>
+ struct _Less : std::binary_function<_T1, _T2, bool>
{
bool
- operator()(const T1& t1, const T2& t2) const
- { return t1 < t2; }
+ operator()(const _T1& __t1, const _T2& __t2) const
+ { return __t1 < __t2; }
bool
- operator()(const T2& t2, const T1& t1) const
- { return t2 < t1; }
+ operator()(const _T2& __t2, const _T1& __t1) const
+ { return __t2 < __t1; }
};
// Partial specialization for one type. Same as std::less.
template<typename _Tp>
-struct less<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, bool>
+struct _Less<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
@@ -278,24 +278,24 @@ struct less<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, bool>
/** @brief Similar to std::plus, but allows two different types. */
template<typename _Tp1, typename _Tp2>
- struct plus : public std::binary_function<_Tp1, _Tp2, _Tp1>
+ struct _Plus : public std::binary_function<_Tp1, _Tp2, _Tp1>
{
typedef __typeof__(*static_cast<_Tp1*>(NULL)
- + *static_cast<_Tp2*>(NULL)) result;
+ + *static_cast<_Tp2*>(NULL)) __result;
- result
+ __result
operator()(const _Tp1& __x, const _Tp2& __y) const
{ return __x + __y; }
};
// Partial specialization for one type. Same as std::plus.
template<typename _Tp>
- struct plus<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, _Tp>
+ struct _Plus<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, _Tp>
{
typedef __typeof__(*static_cast<_Tp*>(NULL)
- + *static_cast<_Tp*>(NULL)) result;
+ + *static_cast<_Tp*>(NULL)) __result;
- result
+ __result
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x + __y; }
};
@@ -303,164 +303,160 @@ template<typename _Tp>
/** @brief Similar to std::multiplies, but allows two different types. */
template<typename _Tp1, typename _Tp2>
- struct multiplies : public std::binary_function<_Tp1, _Tp2, _Tp1>
+ struct _Multiplies : public std::binary_function<_Tp1, _Tp2, _Tp1>
{
typedef __typeof__(*static_cast<_Tp1*>(NULL)
- * *static_cast<_Tp2*>(NULL)) result;
+ * *static_cast<_Tp2*>(NULL)) __result;
- result
+ __result
operator()(const _Tp1& __x, const _Tp2& __y) const
{ return __x * __y; }
};
// Partial specialization for one type. Same as std::multiplies.
template<typename _Tp>
- struct multiplies<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, _Tp>
+ struct _Multiplies<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, _Tp>
{
typedef __typeof__(*static_cast<_Tp*>(NULL)
- * *static_cast<_Tp*>(NULL)) result;
+ * *static_cast<_Tp*>(NULL)) __result;
- result
+ __result
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x * __y; }
};
-template<typename T, typename _DifferenceTp>
- class pseudo_sequence;
+template<typename _Tp, typename _DifferenceTp>
+ class _PseudoSequence;
-/** @brief Iterator associated with __gnu_parallel::pseudo_sequence.
+/** @brief _Iterator associated with __gnu_parallel::_PseudoSequence.
* If features the usual random-access iterator functionality.
- * @param T Sequence value type.
- * @param difference_type Sequence difference type.
+ * @param _Tp Sequence _M_value type.
+ * @param _DifferenceType Sequence difference type.
*/
-template<typename T, typename _DifferenceTp>
- class pseudo_sequence_iterator
+template<typename _Tp, typename _DifferenceTp>
+ class _PseudoSequenceIterator
{
public:
- typedef _DifferenceTp difference_type;
+ typedef _DifferenceTp _DifferenceType;
private:
- typedef pseudo_sequence_iterator<T, _DifferenceTp> type;
-
- const T& val;
- difference_type pos;
+ const _Tp& _M_val;
+ _DifferenceType _M_pos;
public:
- pseudo_sequence_iterator(const T& val, difference_type pos)
- : val(val), pos(pos) { }
+ _PseudoSequenceIterator(const _Tp& _M_val, _DifferenceType _M_pos)
+ : _M_val(_M_val), _M_pos(_M_pos) { }
// Pre-increment operator.
- type&
+ _PseudoSequenceIterator&
operator++()
{
- ++pos;
+ ++_M_pos;
return *this;
}
// Post-increment operator.
- const type
+ const _PseudoSequenceIterator
operator++(int)
- { return type(pos++); }
+ { return _PseudoSequenceIterator(_M_pos++); }
- const T&
+ const _Tp&
operator*() const
- { return val; }
+ { return _M_val; }
- const T&
- operator[](difference_type) const
- { return val; }
+ const _Tp&
+ operator[](_DifferenceType) const
+ { return _M_val; }
bool
- operator==(const type& i2)
- { return pos == i2.pos; }
+ operator==(const _PseudoSequenceIterator& __i2)
+ { return _M_pos == __i2._M_pos; }
- difference_type
- operator!=(const type& i2)
- { return pos != i2.pos; }
+ _DifferenceType
+ operator!=(const _PseudoSequenceIterator& __i2)
+ { return _M_pos != __i2._M_pos; }
- difference_type
- operator-(const type& i2)
- { return pos - i2.pos; }
+ _DifferenceType
+ operator-(const _PseudoSequenceIterator& __i2)
+ { return _M_pos - __i2._M_pos; }
};
/** @brief Sequence that conceptually consists of multiple copies of
the same element.
* The copies are not stored explicitly, of course.
- * @param T Sequence value type.
- * @param difference_type Sequence difference type.
+ * @param _Tp Sequence _M_value type.
+ * @param _DifferenceType Sequence difference type.
*/
-template<typename T, typename _DifferenceTp>
- class pseudo_sequence
+template<typename _Tp, typename _DifferenceTp>
+ class _PseudoSequence
{
- typedef pseudo_sequence<T, _DifferenceTp> type;
-
public:
- typedef _DifferenceTp difference_type;
+ typedef _DifferenceTp _DifferenceType;
// Better case down to uint64, than up to _DifferenceTp.
- typedef pseudo_sequence_iterator<T, uint64> iterator;
+ typedef _PseudoSequenceIterator<_Tp, uint64> iterator;
/** @brief Constructor.
- * @param val Element of the sequence.
- * @param count Number of (virtual) copies.
+ * @param _M_val Element of the sequence.
+ * @param __count Number of (virtual) copies.
*/
- pseudo_sequence(const T& val, difference_type count)
- : val(val), count(count) { }
+ _PseudoSequence(const _Tp& _M_val, _DifferenceType __count)
+ : _M_val(_M_val), __count(__count) { }
/** @brief Begin iterator. */
iterator
begin() const
- { return iterator(val, 0); }
+ { return iterator(_M_val, 0); }
/** @brief End iterator. */
iterator
end() const
- { return iterator(val, count); }
+ { return iterator(_M_val, __count); }
private:
- const T& val;
- difference_type count;
+ const _Tp& _M_val;
+ _DifferenceType __count;
};
/** @brief Functor that does nothing */
template<typename _ValueTp>
- class void_functor
+ class _VoidFunctor
{
inline void
- operator()(const _ValueTp& v) const { }
+ operator()(const _ValueTp& __v) const { }
};
/** @brief Compute the median of three referenced elements,
- according to @c comp.
- * @param a First iterator.
- * @param b Second iterator.
- * @param c Third iterator.
- * @param comp Comparator.
+ according to @__c __comp.
+ * @param __a First iterator.
+ * @param __b Second iterator.
+ * @param __c Third iterator.
+ * @param __comp Comparator.
*/
-template<typename RandomAccessIterator, typename Comparator>
- RandomAccessIterator
- median_of_three_iterators(RandomAccessIterator a, RandomAccessIterator b,
- RandomAccessIterator c, Comparator& comp)
+template<typename _RAIter, typename _Compare>
+ _RAIter
+ __median_of_three_iterators(_RAIter __a, _RAIter __b,
+ _RAIter __c, _Compare& __comp)
{
- if (comp(*a, *b))
- if (comp(*b, *c))
- return b;
+ if (__comp(*__a, *__b))
+ if (__comp(*__b, *__c))
+ return __b;
else
- if (comp(*a, *c))
- return c;
+ if (__comp(*__a, *__c))
+ return __c;
else
- return a;
+ return __a;
else
{
- // Just swap a and b.
- if (comp(*a, *c))
- return a;
+ // Just swap __a and __b.
+ if (__comp(*__a, *__c))
+ return __a;
else
- if (comp(*b, *c))
- return c;
+ if (__comp(*__b, *__c))
+ return __c;
else
- return b;
+ return __b;
}
}
diff --git a/libstdc++-v3/include/parallel/checkers.h b/libstdc++-v3/include/parallel/checkers.h
index 819e8ad26d4..5d3acfa4b8d 100644
--- a/libstdc++-v3/include/parallel/checkers.h
+++ b/libstdc++-v3/include/parallel/checkers.h
@@ -39,115 +39,118 @@
namespace __gnu_parallel
{
/**
- * @brief Check whether @c [begin, @c end) is sorted according to @c comp.
- * @param begin Begin iterator of sequence.
- * @param end End iterator of sequence.
- * @param comp Comparator.
- * @return @c true if sorted, @c false otherwise.
+ * @brief Check whether @__c [__begin, @__c __end) is sorted according
+ * to @__c __comp.
+ * @param __begin Begin iterator of sequence.
+ * @param __end End iterator of sequence.
+ * @param __comp Comparator.
+ * @return @__c true if sorted, @__c false otherwise.
*/
- // XXX Comparator default template argument
- template<typename InputIterator, typename Comparator>
+ // XXX Compare default template argument
+ template<typename _IIter, typename _Compare>
bool
- is_sorted(InputIterator begin, InputIterator end,
- Comparator comp
- = std::less<typename std::iterator_traits<InputIterator>::
- value_type>())
+ __is_sorted(_IIter __begin, _IIter __end,
+ _Compare __comp
+ = std::less<typename std::iterator_traits<_IIter>::
+ _ValueType>())
{
- if (begin == end)
- return true;
-
- InputIterator current(begin), recent(begin);
-
- unsigned long long position = 1;
- for (current++; current != end; current++)
- {
- if (comp(*current, *recent))
- {
- printf("is_sorted: check failed before position %i.\n",
- position);
- return false;
- }
- recent = current;
- position++;
- }
+ if (__begin == __end)
+ return true;
+
+ _IIter __current(__begin), __recent(__begin);
+
+ unsigned long long __position = 1;
+ for (__current++; __current != __end; __current++)
+ {
+ if (__comp(*__current, *__recent))
+ {
+ printf("__is_sorted: check failed before position %__i.\n",
+ __position);
+ return false;
+ }
+ __recent = __current;
+ __position++;
+ }
return true;
}
/**
- * @brief Check whether @c [begin, @c end) is sorted according to @c comp.
+ * @brief Check whether @__c [__begin, @__c __end) is sorted according to
+ * @__c __comp.
* Prints the position in case an unordered pair is found.
- * @param begin Begin iterator of sequence.
- * @param end End iterator of sequence.
- * @param first_failure The first failure is returned in this variable.
- * @param comp Comparator.
- * @return @c true if sorted, @c false otherwise.
+ * @param __begin Begin iterator of sequence.
+ * @param __end End iterator of sequence.
+ * @param __first_failure The first failure is returned in this variable.
+ * @param __comp Comparator.
+ * @return @__c true if sorted, @__c false otherwise.
*/
- // XXX Comparator default template argument
- template<typename InputIterator, typename Comparator>
+ // XXX Compare default template argument
+ template<typename _IIter, typename _Compare>
bool
- is_sorted_failure(InputIterator begin, InputIterator end,
- InputIterator& first_failure,
- Comparator comp
- = std::less<typename std::iterator_traits<InputIterator>::
- value_type>())
+ is_sorted_failure(_IIter __begin, _IIter __end,
+ _IIter& __first_failure,
+ _Compare __comp
+ = std::less<typename std::iterator_traits<_IIter>::
+ _ValueType>())
{
- if (begin == end)
- return true;
-
- InputIterator current(begin), recent(begin);
-
- unsigned long long position = 1;
- for (current++; current != end; current++)
- {
- if (comp(*current, *recent))
- {
- first_failure = current;
- printf("is_sorted: check failed before position %lld.\n",
- position);
- return false;
- }
- recent = current;
- position++;
- }
-
- first_failure = end;
+ if (__begin == __end)
+ return true;
+
+ _IIter __current(__begin), __recent(__begin);
+
+ unsigned long long __position = 1;
+ for (__current++; __current != __end; __current++)
+ {
+ if (__comp(*__current, *__recent))
+ {
+ __first_failure = __current;
+ printf("__is_sorted: check failed before position %lld.\n",
+ __position);
+ return false;
+ }
+ __recent = __current;
+ __position++;
+ }
+
+ __first_failure = __end;
return true;
}
/**
- * @brief Check whether @c [begin, @c end) is sorted according to @c comp.
+ * @brief Check whether @__c [__begin, @__c __end) is sorted according to
+ * @__c __comp.
* Prints all unordered pair, including the surrounding two elements.
- * @param begin Begin iterator of sequence.
- * @param end End iterator of sequence.
- * @param comp Comparator.
- * @return @c true if sorted, @c false otherwise.
+ * @param __begin Begin iterator of sequence.
+ * @param __end End iterator of sequence.
+ * @param __comp Comparator.
+ * @return @__c true if sorted, @__c false otherwise.
*/
- template<typename InputIterator, typename Comparator>
+ template<typename _IIter, typename _Compare>
bool
- // XXX Comparator default template argument
- is_sorted_print_failures(InputIterator begin, InputIterator end,
- Comparator comp
- = std::less<typename std::iterator_traits
- <InputIterator>::value_type>())
+ // XXX Compare default template argument
+ is_sorted_print_failures(_IIter __begin, _IIter __end,
+ _Compare __comp
+ = std::less<typename std::iterator_traits
+ <_IIter>::value_type>())
{
- if (begin == end)
- return true;
-
- InputIterator recent(begin);
- bool ok = true;
-
- for (InputIterator pos(begin + 1); pos != end; pos++)
- {
- if (comp(*pos, *recent))
- {
- printf("%ld: %d %d %d %d\n", pos - begin, *(pos - 2),
- *(pos- 1), *pos, *(pos + 1));
- ok = false;
- }
- recent = pos;
- }
- return ok;
+ if (__begin == __end)
+ return true;
+
+ _IIter __recent(__begin);
+ bool __ok = true;
+
+ for (_IIter __pos(__begin + 1); __pos != __end; __pos++)
+ {
+ if (__comp(*__pos, *__recent))
+ {
+ printf("%ld: %d %d %d %d\n", __pos - __begin, *(__pos - 2),
+ *(__pos- 1), *__pos, *(__pos + 1));
+ __ok = false;
+ }
+ __recent = __pos;
+ }
+ return __ok;
}
}
diff --git a/libstdc++-v3/include/parallel/compatibility.h b/libstdc++-v3/include/parallel/compatibility.h
index a5726dd35b3..e10370b6f54 100644
--- a/libstdc++-v3/include/parallel/compatibility.h
+++ b/libstdc++-v3/include/parallel/compatibility.h
@@ -61,24 +61,24 @@ __attribute((dllimport)) void __attribute__((stdcall)) Sleep (unsigned long);
namespace __gnu_parallel
{
#if defined(__ICC)
- template<typename must_be_int = int>
- int32 faa32(int32* x, int32 inc)
+ template<typename _MustBeInt = int>
+ int32 __faa32(int32* __x, int32 __inc)
{
asm volatile("lock xadd %0,%1"
- : "=r" (inc), "=m" (*x)
- : "0" (inc)
- : "memory");
- return inc;
+ : "=__r" (__inc), "=__m" (*__x)
+ : "0" (__inc)
+ : "memory");
+ return __inc;
}
#if defined(__x86_64)
- template<typename must_be_int = int>
- int64 faa64(int64* x, int64 inc)
+ template<typename _MustBeInt = int>
+ int64 __faa64(int64* __x, int64 __inc)
{
asm volatile("lock xadd %0,%1"
- : "=r" (inc), "=m" (*x)
- : "0" (inc)
- : "memory");
- return inc;
+ : "=__r" (__inc), "=__m" (*__x)
+ : "0" (__inc)
+ : "memory");
+ return __inc;
}
#endif
#endif
@@ -88,106 +88,106 @@ namespace __gnu_parallel
/** @brief Add a value to a variable, atomically.
*
* Implementation is heavily platform-dependent.
- * @param ptr Pointer to a 32-bit signed integer.
- * @param addend Value to add.
+ * @param __ptr Pointer to a 32-bit signed integer.
+ * @param __addend Value to add.
*/
inline int32
- fetch_and_add_32(volatile int32* ptr, int32 addend)
+ __fetch_and_add_32(volatile int32* __ptr, int32 __addend)
{
-#if defined(__ICC) //x86 version
- return _InterlockedExchangeAdd((void*)ptr, addend);
-#elif defined(__ECC) //IA-64 version
- return _InterlockedExchangeAdd((void*)ptr, addend);
+#if defined(__ICC) //x86 version
+ return _InterlockedExchangeAdd((void*)__ptr, __addend);
+#elif defined(__ECC) //IA-64 version
+ return _InterlockedExchangeAdd((void*)__ptr, __addend);
#elif defined(__ICL) || defined(_MSC_VER)
- return _InterlockedExchangeAdd(reinterpret_cast<volatile long*>(ptr),
- addend);
+ return _InterlockedExchangeAdd(reinterpret_cast<volatile long*>(__ptr),
+ __addend);
#elif defined(__GNUC__)
- return __sync_fetch_and_add(ptr, addend);
+ return __sync_fetch_and_add(__ptr, __addend);
#elif defined(__SUNPRO_CC) && defined(__sparc)
- volatile int32 before, after;
+ volatile int32 __before, __after;
do
{
- before = *ptr;
- after = before + addend;
- } while (atomic_cas_32((volatile unsigned int*)ptr, before,
- after) != before);
- return before;
-#else //fallback, slow
-#pragma message("slow fetch_and_add_32")
- int32 res;
+ __before = *__ptr;
+ __after = __before + __addend;
+ } while (atomic_cas_32((volatile unsigned int*)__ptr, __before,
+ __after) != __before);
+ return __before;
+#else //fallback, slow
+#pragma message("slow __fetch_and_add_32")
+ int32 __res;
#pragma omp critical
{
- res = *ptr;
- *(ptr) += addend;
+ __res = *__ptr;
+ *(__ptr) += __addend;
}
- return res;
+ return __res;
#endif
}
/** @brief Add a value to a variable, atomically.
*
* Implementation is heavily platform-dependent.
- * @param ptr Pointer to a 64-bit signed integer.
- * @param addend Value to add.
+ * @param __ptr Pointer to a 64-bit signed integer.
+ * @param __addend Value to add.
*/
inline int64
- fetch_and_add_64(volatile int64* ptr, int64 addend)
+ __fetch_and_add_64(volatile int64* __ptr, int64 __addend)
{
-#if defined(__ICC) && defined(__x86_64) //x86 version
- return faa64<int>((int64*)ptr, addend);
-#elif defined(__ECC) //IA-64 version
- return _InterlockedExchangeAdd64((void*)ptr, addend);
+#if defined(__ICC) && defined(__x86_64) //x86 version
+ return __faa64<int>((int64*)__ptr, __addend);
+#elif defined(__ECC) //IA-64 version
+ return _InterlockedExchangeAdd64((void*)__ptr, __addend);
#elif defined(__ICL) || defined(_MSC_VER)
#ifndef _WIN64
- _GLIBCXX_PARALLEL_ASSERT(false); //not available in this case
+ _GLIBCXX_PARALLEL_ASSERT(false); //not available in this case
return 0;
#else
- return _InterlockedExchangeAdd64(ptr, addend);
+ return _InterlockedExchangeAdd64(__ptr, __addend);
#endif
#elif defined(__GNUC__) && defined(__x86_64)
- return __sync_fetch_and_add(ptr, addend);
-#elif defined(__GNUC__) && defined(__i386) && \
+ return __sync_fetch_and_add(__ptr, __addend);
+#elif defined(__GNUC__) && defined(__i386) && \
(defined(__i686) || defined(__pentium4) || defined(__athlon))
- return __sync_fetch_and_add(ptr, addend);
+ return __sync_fetch_and_add(__ptr, __addend);
#elif defined(__SUNPRO_CC) && defined(__sparc)
- volatile int64 before, after;
+ volatile int64 __before, __after;
do
{
- before = *ptr;
- after = before + addend;
- } while (atomic_cas_64((volatile unsigned long long*)ptr, before,
- after) != before);
- return before;
-#else //fallback, slow
+ __before = *__ptr;
+ __after = __before + __addend;
+ } while (atomic_cas_64((volatile unsigned long long*)__ptr, __before,
+ __after) != __before);
+ return __before;
+#else //fallback, slow
#if defined(__GNUC__) && defined(__i386)
- // XXX doesn't work with -march=native
+ // XXX doesn'__t work with -march=native
//#warning "please compile with -march=i686 or better"
#endif
-#pragma message("slow fetch_and_add_64")
- int64 res;
+#pragma message("slow __fetch_and_add_64")
+ int64 __res;
#pragma omp critical
{
- res = *ptr;
- *(ptr) += addend;
+ __res = *__ptr;
+ *(__ptr) += __addend;
}
- return res;
+ return __res;
#endif
}
/** @brief Add a value to a variable, atomically.
*
* Implementation is heavily platform-dependent.
- * @param ptr Pointer to a signed integer.
- * @param addend Value to add.
+ * @param __ptr Pointer to a signed integer.
+ * @param __addend Value to add.
*/
- template<typename T>
- inline T
- fetch_and_add(volatile T* ptr, T addend)
+ template<typename _Tp>
+ inline _Tp
+ __fetch_and_add(volatile _Tp* __ptr, _Tp __addend)
{
- if (sizeof(T) == sizeof(int32))
- return (T)fetch_and_add_32((volatile int32*) ptr, (int32)addend);
- else if (sizeof(T) == sizeof(int64))
- return (T)fetch_and_add_64((volatile int64*) ptr, (int64)addend);
+ if (sizeof(_Tp) == sizeof(int32))
+ return (_Tp)__fetch_and_add_32((volatile int32*) __ptr, (int32)__addend);
+ else if (sizeof(_Tp) == sizeof(int64))
+ return (_Tp)__fetch_and_add_64((volatile int64*) __ptr, (int64)__addend);
else
_GLIBCXX_PARALLEL_ASSERT(false);
}
@@ -195,141 +195,149 @@ namespace __gnu_parallel
#if defined(__ICC)
- template<typename must_be_int = int>
+ template<typename _MustBeInt = int>
inline int32
- cas32(volatile int32* ptr, int32 old, int32 nw)
+ __cas32(volatile int32* __ptr, int32 __old, int32 __nw)
{
- int32 before;
+ int32 __before;
__asm__ __volatile__("lock; cmpxchgl %1,%2"
- : "=a"(before)
- : "q"(nw), "m"(*(volatile long long*)(ptr)), "0"(old)
- : "memory");
- return before;
+ : "=a"(__before)
+ : "q"(__nw), "__m"(*(volatile long long*)(__ptr)),
+ "0"(__old)
+ : "memory");
+ return __before;
}
#if defined(__x86_64)
- template<typename must_be_int = int>
+ template<typename _MustBeInt = int>
inline int64
- cas64(volatile int64 *ptr, int64 old, int64 nw)
+ __cas64(volatile int64 *__ptr, int64 __old, int64 __nw)
{
- int64 before;
+ int64 __before;
__asm__ __volatile__("lock; cmpxchgq %1,%2"
- : "=a"(before)
- : "q"(nw), "m"(*(volatile long long*)(ptr)), "0"(old)
- : "memory");
- return before;
+ : "=a"(__before)
+ : "q"(__nw), "__m"(*(volatile long long*)(__ptr)),
+ "0"(__old)
+ : "memory");
+ return __before;
}
#endif
#endif
- /** @brief Compare @c *ptr and @c comparand. If equal, let @c
- * *ptr=replacement and return @c true, return @c false otherwise.
+ /** @brief Compare @__c *__ptr and @__c __comparand. If equal, let @__c
+ * *__ptr=__replacement and return @__c true, return @__c false otherwise.
*
* Implementation is heavily platform-dependent.
- * @param ptr Pointer to 32-bit signed integer.
- * @param comparand Compare value.
- * @param replacement Replacement value.
+ * @param __ptr Pointer to 32-bit signed integer.
+ * @param __comparand Compare value.
+ * @param __replacement Replacement value.
*/
inline bool
- compare_and_swap_32(volatile int32* ptr, int32 comparand, int32 replacement)
+ __compare_and_swap_32(volatile int32* __ptr, int32 __comparand,
+ int32 __replacement)
{
-#if defined(__ICC) //x86 version
- return _InterlockedCompareExchange((void*)ptr, replacement,
- comparand) == comparand;
-#elif defined(__ECC) //IA-64 version
- return _InterlockedCompareExchange((void*)ptr, replacement,
- comparand) == comparand;
+#if defined(__ICC) //x86 version
+ return _InterlockedCompareExchange((void*)__ptr, __replacement,
+ __comparand) == __comparand;
+#elif defined(__ECC) //IA-64 version
+ return _InterlockedCompareExchange((void*)__ptr, __replacement,
+ __comparand) == __comparand;
#elif defined(__ICL) || defined(_MSC_VER)
- return _InterlockedCompareExchange(reinterpret_cast<volatile long*>(ptr),
- replacement, comparand) == comparand;
+ return _InterlockedCompareExchange(
+ reinterpret_cast<volatile long*>(__ptr),
+ __replacement, __comparand)
+ == __comparand;
#elif defined(__GNUC__)
- return __sync_bool_compare_and_swap(ptr, comparand, replacement);
+ return __sync_bool_compare_and_swap(__ptr, __comparand, __replacement);
#elif defined(__SUNPRO_CC) && defined(__sparc)
- return atomic_cas_32((volatile unsigned int*)ptr, comparand,
- replacement) == comparand;
+ return atomic_cas_32((volatile unsigned int*)__ptr, __comparand,
+ __replacement) == __comparand;
#else
-#pragma message("slow compare_and_swap_32")
- bool res = false;
+#pragma message("slow __compare_and_swap_32")
+ bool __res = false;
#pragma omp critical
{
- if (*ptr == comparand)
- {
- *ptr = replacement;
- res = true;
- }
+ if (*__ptr == __comparand)
+ {
+ *__ptr = __replacement;
+ __res = true;
+ }
}
- return res;
+ return __res;
#endif
}
- /** @brief Compare @c *ptr and @c comparand. If equal, let @c
- * *ptr=replacement and return @c true, return @c false otherwise.
+ /** @brief Compare @__c *__ptr and @__c __comparand. If equal, let @__c
+ * *__ptr=__replacement and return @__c true, return @__c false otherwise.
*
* Implementation is heavily platform-dependent.
- * @param ptr Pointer to 64-bit signed integer.
- * @param comparand Compare value.
- * @param replacement Replacement value.
+ * @param __ptr Pointer to 64-bit signed integer.
+ * @param __comparand Compare value.
+ * @param __replacement Replacement value.
*/
inline bool
- compare_and_swap_64(volatile int64* ptr, int64 comparand, int64 replacement)
+ __compare_and_swap_64(volatile int64* __ptr, int64 __comparand,
+ int64 __replacement)
{
-#if defined(__ICC) && defined(__x86_64) //x86 version
- return cas64<int>(ptr, comparand, replacement) == comparand;
-#elif defined(__ECC) //IA-64 version
- return _InterlockedCompareExchange64((void*)ptr, replacement,
- comparand) == comparand;
+#if defined(__ICC) && defined(__x86_64) //x86 version
+ return __cas64<int>(__ptr, __comparand, __replacement) == __comparand;
+#elif defined(__ECC) //IA-64 version
+ return _InterlockedCompareExchange64((void*)__ptr, __replacement,
+ __comparand) == __comparand;
#elif defined(__ICL) || defined(_MSC_VER)
#ifndef _WIN64
- _GLIBCXX_PARALLEL_ASSERT(false); //not available in this case
+ _GLIBCXX_PARALLEL_ASSERT(false); //not available in this case
return 0;
#else
- return _InterlockedCompareExchange64(ptr, replacement,
- comparand) == comparand;
+ return _InterlockedCompareExchange64(__ptr, __replacement,
+ __comparand) == __comparand;
#endif
#elif defined(__GNUC__) && defined(__x86_64)
- return __sync_bool_compare_and_swap(ptr, comparand, replacement);
-#elif defined(__GNUC__) && defined(__i386) && \
+ return __sync_bool_compare_and_swap(__ptr, __comparand, __replacement);
+#elif defined(__GNUC__) && defined(__i386) && \
(defined(__i686) || defined(__pentium4) || defined(__athlon))
- return __sync_bool_compare_and_swap(ptr, comparand, replacement);
+ return __sync_bool_compare_and_swap(__ptr, __comparand, __replacement);
#elif defined(__SUNPRO_CC) && defined(__sparc)
- return atomic_cas_64((volatile unsigned long long*)ptr,
- comparand, replacement) == comparand;
+ return atomic_cas_64((volatile unsigned long long*)__ptr,
+ __comparand, __replacement) == __comparand;
#else
#if defined(__GNUC__) && defined(__i386)
// XXX -march=native
//#warning "please compile with -march=i686 or better"
#endif
-#pragma message("slow compare_and_swap_64")
- bool res = false;
+#pragma message("slow __compare_and_swap_64")
+ bool __res = false;
#pragma omp critical
{
- if (*ptr == comparand)
- {
- *ptr = replacement;
- res = true;
- }
+ if (*__ptr == __comparand)
+ {
+ *__ptr = __replacement;
+ __res = true;
+ }
}
- return res;
+ return __res;
#endif
}
- /** @brief Compare @c *ptr and @c comparand. If equal, let @c
- * *ptr=replacement and return @c true, return @c false otherwise.
+ /** @brief Compare @__c *__ptr and @__c __comparand. If equal, let @__c
+ * *__ptr=__replacement and return @__c true, return @__c false otherwise.
*
* Implementation is heavily platform-dependent.
- * @param ptr Pointer to signed integer.
- * @param comparand Compare value.
- * @param replacement Replacement value. */
- template<typename T>
+ * @param __ptr Pointer to signed integer.
+ * @param __comparand Compare value.
+ * @param __replacement Replacement value. */
+ template<typename _Tp>
inline bool
- compare_and_swap(volatile T* ptr, T comparand, T replacement)
+ __compare_and_swap(volatile _Tp* __ptr, _Tp __comparand, _Tp __replacement)
{
- if (sizeof(T) == sizeof(int32))
- return compare_and_swap_32((volatile int32*) ptr, (int32)comparand, (int32)replacement);
- else if (sizeof(T) == sizeof(int64))
- return compare_and_swap_64((volatile int64*) ptr, (int64)comparand, (int64)replacement);
+ if (sizeof(_Tp) == sizeof(int32))
+ return __compare_and_swap_32((volatile int32*) __ptr, (int32)__comparand,
+ (int32)__replacement);
+ else if (sizeof(_Tp) == sizeof(int64))
+ return __compare_and_swap_64((volatile int64*) __ptr, (int64)__comparand,
+ (int64)__replacement);
else
_GLIBCXX_PARALLEL_ASSERT(false);
}
@@ -337,7 +345,7 @@ namespace __gnu_parallel
/** @brief Yield the control to another thread, without waiting for
the end to the time slice. */
inline void
- yield()
+ __yield()
{
#if defined (_WIN32) && !defined (__CYGWIN__)
Sleep(0);
diff --git a/libstdc++-v3/include/parallel/compiletime_settings.h b/libstdc++-v3/include/parallel/compiletime_settings.h
index e7e31d068cb..e375a94a9da 100644
--- a/libstdc++-v3/include/parallel/compiletime_settings.h
+++ b/libstdc++-v3/include/parallel/compiletime_settings.h
@@ -38,15 +38,15 @@
/** @def _GLIBCXX_CALL
* @brief Macro to produce log message when entering a function.
- * @param n Input size.
+ * @param __n Input size.
* @see _GLIBCXX_VERBOSE_LEVEL */
#if (_GLIBCXX_VERBOSE_LEVEL == 0)
-#define _GLIBCXX_CALL(n)
+#define _GLIBCXX_CALL(__n)
#endif
#if (_GLIBCXX_VERBOSE_LEVEL == 1)
-#define _GLIBCXX_CALL(n) \
- printf(" %s:\niam = %d, n = %ld, num_threads = %d\n", \
- __PRETTY_FUNCTION__, omp_get_thread_num(), (n), get_max_threads());
+#define _GLIBCXX_CALL(__n) \
+ printf(" %__s:\niam = %d, __n = %ld, __num_threads = %d\n", \
+ __PRETTY_FUNCTION__, omp_get_thread_num(), (__n), __get_max_threads());
#endif
#ifndef _GLIBCXX_SCALE_DOWN_FPU
@@ -64,12 +64,12 @@
#ifndef _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1
/** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code.
* Consider the size of the L1 cache for
- * __gnu_parallel::parallel_random_shuffle(). */
+* gnu_parallel::__parallel_random_shuffle(). */
#define _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 0
#endif
#ifndef _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB
/** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code.
* Consider the size of the TLB for
- * __gnu_parallel::parallel_random_shuffle(). */
+* gnu_parallel::__parallel_random_shuffle(). */
#define _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB 0
#endif
diff --git a/libstdc++-v3/include/parallel/equally_split.h b/libstdc++-v3/include/parallel/equally_split.h
index ee4bfeeeb0e..a41ed6ec41e 100644
--- a/libstdc++-v3/include/parallel/equally_split.h
+++ b/libstdc++-v3/include/parallel/equally_split.h
@@ -33,54 +33,56 @@
namespace __gnu_parallel
{
-/** @brief Function to split a sequence into parts of almost equal size.
+/** @brief function to split a sequence into parts of almost equal size.
*
- * The resulting sequence s of length num_threads+1 contains the splitting
- * positions when splitting the range [0,n) into parts of almost
+ * The resulting sequence __s of length __num_threads+1 contains the splitting
+ * positions when splitting the range [0,__n) into parts of almost
* equal size (plus minus 1). The first entry is 0, the last one
- * n. There may result empty parts.
- * @param n Number of elements
- * @param num_threads Number of parts
- * @param s Splitters
- * @returns End of splitter sequence, i. e. @c s+num_threads+1 */
-template<typename difference_type, typename OutputIterator>
- OutputIterator
- equally_split(difference_type n, thread_index_t num_threads, OutputIterator s)
+* n. There may result empty parts.
+ * @param __n Number of elements
+ * @param __num_threads Number of parts
+ * @param __s Splitters
+ * @returns End of splitter sequence, i.e. @__c __s+__num_threads+1 */
+template<typename _DifferenceType, typename _OutputIterator>
+ _OutputIterator
+ equally_split(_DifferenceType __n, _ThreadIndex __num_threads,
+ _OutputIterator __s)
{
- difference_type chunk_length = n / num_threads;
- difference_type num_longer_chunks = n % num_threads;
- difference_type pos = 0;
- for (thread_index_t i = 0; i < num_threads; ++i)
+ _DifferenceType __chunk_length = __n / __num_threads;
+ _DifferenceType __num_longer_chunks = __n % __num_threads;
+ _DifferenceType __pos = 0;
+ for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
{
- *s++ = pos;
- pos += (i < num_longer_chunks) ? (chunk_length + 1) : chunk_length;
+ *__s++ = __pos;
+ __pos += (__i < __num_longer_chunks) ?
+ (__chunk_length + 1) : __chunk_length;
}
- *s++ = n;
- return s;
+ *__s++ = __n;
+ return __s;
}
-/** @brief Function to split a sequence into parts of almost equal size.
+/** @brief function to split a sequence into parts of almost equal size.
*
* Returns the position of the splitting point between
- * thread number thread_no (included) and
- * thread number thread_no+1 (excluded).
- * @param n Number of elements
- * @param num_threads Number of parts
- * @returns _SplittingAlgorithm point */
-template<typename difference_type>
- difference_type
- equally_split_point(difference_type n,
- thread_index_t num_threads,
- thread_index_t thread_no)
+ * thread number __thread_no (included) and
+ * thread number __thread_no+1 (excluded).
+ * @param __n Number of elements
+ * @param __num_threads Number of parts
+ * @returns splitting point */
+template<typename _DifferenceType>
+ _DifferenceType
+ equally_split_point(_DifferenceType __n,
+ _ThreadIndex __num_threads,
+ _ThreadIndex __thread_no)
{
- difference_type chunk_length = n / num_threads;
- difference_type num_longer_chunks = n % num_threads;
- if (thread_no < num_longer_chunks)
- return thread_no * (chunk_length + 1);
+ _DifferenceType __chunk_length = __n / __num_threads;
+ _DifferenceType __num_longer_chunks = __n % __num_threads;
+ if (__thread_no < __num_longer_chunks)
+ return __thread_no * (__chunk_length + 1);
else
- return num_longer_chunks * (chunk_length + 1)
- + (thread_no - num_longer_chunks) * chunk_length;
+ return __num_longer_chunks * (__chunk_length + 1)
+ + (__thread_no - __num_longer_chunks) * __chunk_length;
}
}
diff --git a/libstdc++-v3/include/parallel/features.h b/libstdc++-v3/include/parallel/features.h
index 417606ea7ac..077429f1688 100644
--- a/libstdc++-v3/include/parallel/features.h
+++ b/libstdc++-v3/include/parallel/features.h
@@ -78,7 +78,7 @@
#ifndef _GLIBCXX_TREE_INITIAL_SPLITTING
/** @def _GLIBCXX_TREE_INITIAL_SPLITTING
* @brief Include the initial splitting variant for
- * _Rb_tree::insert_unique(InputIterator beg, InputIterator end).
+ * _Rb_tree::insert_unique(_IIter beg, _IIter __end).
* @see __gnu_parallel::_Rb_tree */
#define _GLIBCXX_TREE_INITIAL_SPLITTING 1
#endif
@@ -86,7 +86,7 @@
#ifndef _GLIBCXX_TREE_DYNAMIC_BALANCING
/** @def _GLIBCXX_TREE_DYNAMIC_BALANCING
* @brief Include the dynamic balancing variant for
- * _Rb_tree::insert_unique(InputIterator beg, InputIterator end).
+ * _Rb_tree::insert_unique(_IIter beg, _IIter __end).
* @see __gnu_parallel::_Rb_tree */
#define _GLIBCXX_TREE_DYNAMIC_BALANCING 1
#endif
@@ -94,7 +94,7 @@
#ifndef _GLIBCXX_TREE_FULL_COPY
/** @def _GLIBCXX_TREE_FULL_COPY
* @brief In order to sort the input sequence of
- * _Rb_tree::insert_unique(InputIterator beg, InputIterator end) a
+ * _Rb_tree::insert_unique(_IIter beg, _IIter __end) a
* full copy of the input elements is done.
* @see __gnu_parallel::_Rb_tree */
#define _GLIBCXX_TREE_FULL_COPY 1
diff --git a/libstdc++-v3/include/parallel/find.h b/libstdc++-v3/include/parallel/find.h
index 0597cc58ec6..e7f0d839086 100644
--- a/libstdc++-v3/include/parallel/find.h
+++ b/libstdc++-v3/include/parallel/find.h
@@ -23,7 +23,7 @@
// <http://www.gnu.org/licenses/>.
/** @file parallel/find.h
- * @brief Parallel implementation base for std::find(), std::equal()
+ * @brief Parallel implementation __base for std::find(), std::equal()
* and related functions.
* This file is a GNU parallel extension to the Standard C++ Library.
*/
@@ -44,36 +44,36 @@ namespace __gnu_parallel
{
/**
* @brief Parallel std::find, switch for different algorithms.
- * @param begin1 Begin iterator of first sequence.
- * @param end1 End iterator of first sequence.
- * @param begin2 Begin iterator of second sequence. Must have same
+ * @param __begin1 Begin iterator of first sequence.
+ * @param __end1 End iterator of first sequence.
+ * @param __begin2 Begin iterator of second sequence. Must have same
* length as first sequence.
- * @param pred Find predicate.
- * @param selector Functionality (e. g. std::find_if (), std::equal(),...)
+ * @param __pred Find predicate.
+ * @param __selector _Functionality (e. g. std::find_if (), std::equal(),...)
* @return Place of finding in both sequences.
*/
-template<typename RandomAccessIterator1,
- typename RandomAccessIterator2,
- typename Pred,
- typename Selector>
- inline std::pair<RandomAccessIterator1, RandomAccessIterator2>
- find_template(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2, Pred pred, Selector selector)
+template<typename _RAIter1,
+ typename _RAIter2,
+ typename _Pred,
+ typename _Selector>
+ inline std::pair<_RAIter1, _RAIter2>
+ __find_template(_RAIter1 __begin1, _RAIter1 __end1,
+ _RAIter2 __begin2, _Pred __pred, _Selector __selector)
{
switch (_Settings::get().find_algorithm)
{
case GROWING_BLOCKS:
- return find_template(begin1, end1, begin2, pred, selector,
- growing_blocks_tag());
+ return __find_template(__begin1, __end1, __begin2, __pred, __selector,
+ growing_blocks_tag());
case CONSTANT_SIZE_BLOCKS:
- return find_template(begin1, end1, begin2, pred, selector,
- constant_size_blocks_tag());
+ return __find_template(__begin1, __end1, __begin2, __pred, __selector,
+ constant_size_blocks_tag());
case EQUAL_SPLIT:
- return find_template(begin1, end1, begin2, pred, selector,
- equal_split_tag());
+ return __find_template(__begin1, __end1, __begin2, __pred, __selector,
+ equal_split_tag());
default:
_GLIBCXX_PARALLEL_ASSERT(false);
- return std::make_pair(begin1, begin2);
+ return std::make_pair(__begin1, __begin2);
}
}
@@ -81,80 +81,80 @@ template<typename RandomAccessIterator1,
/**
* @brief Parallel std::find, equal splitting variant.
- * @param begin1 Begin iterator of first sequence.
- * @param end1 End iterator of first sequence.
- * @param begin2 Begin iterator of second sequence. Second sequence
+ * @param __begin1 Begin iterator of first sequence.
+ * @param __end1 End iterator of first sequence.
+ * @param __begin2 Begin iterator of second sequence. Second __sequence
* must have same length as first sequence.
- * @param pred Find predicate.
- * @param selector Functionality (e. g. std::find_if (), std::equal(),...)
+ * @param __pred Find predicate.
+ * @param __selector _Functionality (e. g. std::find_if (), std::equal(),...)
* @return Place of finding in both sequences.
*/
-template<typename RandomAccessIterator1,
- typename RandomAccessIterator2,
- typename Pred,
- typename Selector>
- std::pair<RandomAccessIterator1, RandomAccessIterator2>
- find_template(RandomAccessIterator1 begin1,
- RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2,
- Pred pred,
- Selector selector,
+template<typename _RAIter1,
+ typename _RAIter2,
+ typename _Pred,
+ typename _Selector>
+ std::pair<_RAIter1, _RAIter2>
+ __find_template(_RAIter1 __begin1,
+ _RAIter1 __end1,
+ _RAIter2 __begin2,
+ _Pred __pred,
+ _Selector __selector,
equal_split_tag)
{
- _GLIBCXX_CALL(end1 - begin1)
+ _GLIBCXX_CALL(__end1 - __begin1)
- typedef std::iterator_traits<RandomAccessIterator1> traits_type;
- typedef typename traits_type::difference_type difference_type;
- typedef typename traits_type::value_type value_type;
+ typedef std::iterator_traits<_RAIter1> _TraitsType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
+ typedef typename _TraitsType::value_type _ValueType;
- difference_type length = end1 - begin1;
- difference_type result = length;
- difference_type* borders;
+ _DifferenceType __length = __end1 - __begin1;
+ _DifferenceType __result = __length;
+ _DifferenceType* __borders;
- omp_lock_t result_lock;
- omp_init_lock(&result_lock);
+ omp_lock_t __result_lock;
+ omp_init_lock(&__result_lock);
- thread_index_t num_threads = get_max_threads();
-# pragma omp parallel num_threads(num_threads)
+ _ThreadIndex __num_threads = __get_max_threads();
+# pragma omp parallel num_threads(__num_threads)
{
# pragma omp single
{
- num_threads = omp_get_num_threads();
- borders = new difference_type[num_threads + 1];
- equally_split(length, num_threads, borders);
+ __num_threads = omp_get_num_threads();
+ __borders = new _DifferenceType[__num_threads + 1];
+ equally_split(__length, __num_threads, __borders);
} //single
- thread_index_t iam = omp_get_thread_num();
- difference_type start = borders[iam], stop = borders[iam + 1];
+ _ThreadIndex __iam = omp_get_thread_num();
+ _DifferenceType __start = __borders[__iam],
+ __stop = __borders[__iam + 1];
- RandomAccessIterator1 i1 = begin1 + start;
- RandomAccessIterator2 i2 = begin2 + start;
- for (difference_type pos = start; pos < stop; ++pos)
+ _RAIter1 __i1 = __begin1 + __start;
+ _RAIter2 __i2 = __begin2 + __start;
+ for (_DifferenceType __pos = __start; __pos < __stop; ++__pos)
{
- #pragma omp flush(result)
+ #pragma omp flush(__result)
// Result has been set to something lower.
- if (result < pos)
+ if (__result < __pos)
break;
- if (selector(i1, i2, pred))
+ if (__selector(__i1, __i2, __pred))
{
- omp_set_lock(&result_lock);
- if (pos < result)
- result = pos;
- omp_unset_lock(&result_lock);
+ omp_set_lock(&__result_lock);
+ if (__pos < __result)
+ __result = __pos;
+ omp_unset_lock(&__result_lock);
break;
}
- ++i1;
- ++i2;
+ ++__i1;
+ ++__i2;
}
} //parallel
- omp_destroy_lock(&result_lock);
- delete[] borders;
+ omp_destroy_lock(&__result_lock);
+ delete[] __borders;
return
- std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result,
- begin2 + result);
+ std::pair<_RAIter1, _RAIter2>(__begin1 + __result, __begin2 + __result);
}
#endif
@@ -163,12 +163,12 @@ template<typename RandomAccessIterator1,
/**
* @brief Parallel std::find, growing block size variant.
- * @param begin1 Begin iterator of first sequence.
- * @param end1 End iterator of first sequence.
- * @param begin2 Begin iterator of second sequence. Second sequence
+ * @param __begin1 Begin iterator of first sequence.
+ * @param __end1 End iterator of first sequence.
+ * @param __begin2 Begin iterator of second sequence. Second __sequence
* must have same length as first sequence.
- * @param pred Find predicate.
- * @param selector Functionality (e. g. std::find_if (), std::equal(),...)
+ * @param __pred Find predicate.
+ * @param __selector _Functionality (e. g. std::find_if (), std::equal(),...)
* @return Place of finding in both sequences.
* @see __gnu_parallel::_Settings::find_sequential_search_size
* @see __gnu_parallel::_Settings::find_initial_block_size
@@ -178,110 +178,111 @@ template<typename RandomAccessIterator1,
* There are two main differences between the growing blocks and
* the constant-size blocks variants.
* 1. For GB, the block size grows; for CSB, the block size is fixed.
-
* 2. For GB, the blocks are allocated dynamically;
* for CSB, the blocks are allocated in a predetermined manner,
* namely spacial round-robin.
*/
-template<typename RandomAccessIterator1,
- typename RandomAccessIterator2,
- typename Pred,
- typename Selector>
- std::pair<RandomAccessIterator1, RandomAccessIterator2>
- find_template(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2, Pred pred, Selector selector,
+template<typename _RAIter1,
+ typename _RAIter2,
+ typename _Pred,
+ typename _Selector>
+ std::pair<_RAIter1, _RAIter2>
+ __find_template(_RAIter1 __begin1, _RAIter1 __end1,
+ _RAIter2 __begin2, _Pred __pred, _Selector __selector,
growing_blocks_tag)
{
- _GLIBCXX_CALL(end1 - begin1)
+ _GLIBCXX_CALL(__end1 - __begin1)
- typedef std::iterator_traits<RandomAccessIterator1> traits_type;
- typedef typename traits_type::difference_type difference_type;
- typedef typename traits_type::value_type value_type;
+ typedef std::iterator_traits<_RAIter1> _TraitsType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
+ typedef typename _TraitsType::value_type _ValueType;
const _Settings& __s = _Settings::get();
- difference_type length = end1 - begin1;
+ _DifferenceType __length = __end1 - __begin1;
- difference_type sequential_search_size =
- std::min<difference_type>(length, __s.find_sequential_search_size);
+ _DifferenceType __sequential_search_size =
+ std::min<_DifferenceType>(__length, __s.find_sequential_search_size);
// Try it sequentially first.
- std::pair<RandomAccessIterator1, RandomAccessIterator2> find_seq_result =
- selector.sequential_algorithm(
- begin1, begin1 + sequential_search_size, begin2, pred);
+ std::pair<_RAIter1, _RAIter2> __find_seq_result =
+ __selector._M_sequential_algorithm(
+ __begin1, __begin1 + __sequential_search_size, __begin2, __pred);
- if (find_seq_result.first != (begin1 + sequential_search_size))
- return find_seq_result;
+ if (__find_seq_result.first != (__begin1 + __sequential_search_size))
+ return __find_seq_result;
// Index of beginning of next free block (after sequential find).
- difference_type next_block_start = sequential_search_size;
- difference_type result = length;
+ _DifferenceType __next_block_start = __sequential_search_size;
+ _DifferenceType __result = __length;
- omp_lock_t result_lock;
- omp_init_lock(&result_lock);
+ omp_lock_t __result_lock;
+ omp_init_lock(&__result_lock);
- thread_index_t num_threads = get_max_threads();
-# pragma omp parallel shared(result) num_threads(num_threads)
+ _ThreadIndex __num_threads = __get_max_threads();
+# pragma omp parallel shared(__result) num_threads(__num_threads)
{
# pragma omp single
- num_threads = omp_get_num_threads();
+ __num_threads = omp_get_num_threads();
- // Not within first k elements -> start parallel.
- thread_index_t iam = omp_get_thread_num();
+ // Not within first __k elements -> start parallel.
+ _ThreadIndex __iam = omp_get_thread_num();
- difference_type block_size = __s.find_initial_block_size;
- difference_type start =
- fetch_and_add<difference_type>(&next_block_start, block_size);
+ _DifferenceType __block_size = __s.find_initial_block_size;
+ _DifferenceType __start =
+ __fetch_and_add<_DifferenceType>(&__next_block_start, __block_size);
// Get new block, update pointer to next block.
- difference_type stop =
- std::min<difference_type>(length, start + block_size);
+ _DifferenceType __stop =
+ std::min<_DifferenceType>(__length, __start + __block_size);
- std::pair<RandomAccessIterator1, RandomAccessIterator2> local_result;
+ std::pair<_RAIter1, _RAIter2> __local_result;
- while (start < length)
+ while (__start < __length)
{
-# pragma omp flush(result)
+# pragma omp flush(__result)
// Get new value of result.
- if (result < start)
+ if (__result < __start)
{
// No chance to find first element.
break;
}
- local_result = selector.sequential_algorithm(
- begin1 + start, begin1 + stop, begin2 + start, pred);
- if (local_result.first != (begin1 + stop))
+ __local_result = __selector._M_sequential_algorithm(
+ __begin1 + __start, __begin1 + __stop,
+ __begin2 + __start, __pred);
+ if (__local_result.first != (__begin1 + __stop))
{
- omp_set_lock(&result_lock);
- if ((local_result.first - begin1) < result)
+ omp_set_lock(&__result_lock);
+ if ((__local_result.first - __begin1) < __result)
{
- result = local_result.first - begin1;
+ __result = __local_result.first - __begin1;
// Result cannot be in future blocks, stop algorithm.
- fetch_and_add<difference_type>(&next_block_start, length);
+ __fetch_and_add<_DifferenceType>(
+ &__next_block_start, __length);
}
- omp_unset_lock(&result_lock);
+ omp_unset_lock(&__result_lock);
}
- block_size =
- std::min<difference_type>(block_size * __s.find_increasing_factor,
- __s.find_maximum_block_size);
+ __block_size = std::min<_DifferenceType>(
+ __block_size * __s.find_increasing_factor,
+ __s.find_maximum_block_size);
// Get new block, update pointer to next block.
- start =
- fetch_and_add<difference_type>(&next_block_start, block_size);
- stop = ((length < (start + block_size))
- ? length : (start + block_size));
+ __start =
+ __fetch_and_add<_DifferenceType>(
+ &__next_block_start, __block_size);
+ __stop = ((__length < (__start + __block_size))
+ ? __length : (__start + __block_size));
}
} //parallel
- omp_destroy_lock(&result_lock);
+ omp_destroy_lock(&__result_lock);
// Return iterator on found element.
return
- std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result,
- begin2 + result);
+ std::pair<_RAIter1, _RAIter2>(__begin1 + __result, __begin2 + __result);
}
#endif
@@ -290,12 +291,12 @@ template<typename RandomAccessIterator1,
/**
* @brief Parallel std::find, constant block size variant.
- * @param begin1 Begin iterator of first sequence.
- * @param end1 End iterator of first sequence.
- * @param begin2 Begin iterator of second sequence. Second sequence
+ * @param __begin1 Begin iterator of first sequence.
+ * @param __end1 End iterator of first sequence.
+ * @param __begin2 Begin iterator of second sequence. Second __sequence
* must have same length as first sequence.
- * @param pred Find predicate.
- * @param selector Functionality (e. g. std::find_if (), std::equal(),...)
+ * @param __pred Find predicate.
+ * @param __selector _Functionality (e. g. std::find_if (), std::equal(),...)
* @return Place of finding in both sequences.
* @see __gnu_parallel::_Settings::find_sequential_search_size
* @see __gnu_parallel::_Settings::find_block_size
@@ -306,94 +307,94 @@ template<typename RandomAccessIterator1,
* blocks are allocated in a predetermined manner, namely spacial
* round-robin.
*/
-template<typename RandomAccessIterator1,
- typename RandomAccessIterator2,
- typename Pred,
- typename Selector>
- std::pair<RandomAccessIterator1, RandomAccessIterator2>
- find_template(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2, Pred pred, Selector selector,
+template<typename _RAIter1,
+ typename _RAIter2,
+ typename _Pred,
+ typename _Selector>
+ std::pair<_RAIter1, _RAIter2>
+ __find_template(_RAIter1 __begin1, _RAIter1 __end1,
+ _RAIter2 __begin2, _Pred __pred, _Selector __selector,
constant_size_blocks_tag)
{
- _GLIBCXX_CALL(end1 - begin1)
- typedef std::iterator_traits<RandomAccessIterator1> traits_type;
- typedef typename traits_type::difference_type difference_type;
- typedef typename traits_type::value_type value_type;
+ _GLIBCXX_CALL(__end1 - __begin1)
+ typedef std::iterator_traits<_RAIter1> _TraitsType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
+ typedef typename _TraitsType::value_type _ValueType;
const _Settings& __s = _Settings::get();
- difference_type length = end1 - begin1;
+ _DifferenceType __length = __end1 - __begin1;
- difference_type sequential_search_size = std::min<difference_type>(
- length, __s.find_sequential_search_size);
+ _DifferenceType __sequential_search_size = std::min<_DifferenceType>(
+ __length, __s.find_sequential_search_size);
// Try it sequentially first.
- std::pair<RandomAccessIterator1, RandomAccessIterator2> find_seq_result =
- selector.sequential_algorithm(begin1, begin1 + sequential_search_size,
- begin2, pred);
+ std::pair<_RAIter1, _RAIter2> __find_seq_result =
+ __selector._M_sequential_algorithm(
+ __begin1, __begin1 + __sequential_search_size, __begin2, __pred);
- if (find_seq_result.first != (begin1 + sequential_search_size))
- return find_seq_result;
+ if (__find_seq_result.first != (__begin1 + __sequential_search_size))
+ return __find_seq_result;
- difference_type result = length;
- omp_lock_t result_lock;
- omp_init_lock(&result_lock);
+ _DifferenceType __result = __length;
+ omp_lock_t __result_lock;
+ omp_init_lock(&__result_lock);
- // Not within first sequential_search_size elements -> start parallel.
+ // Not within first __sequential_search_size elements -> start parallel.
- thread_index_t num_threads = get_max_threads();
-# pragma omp parallel shared(result) num_threads(num_threads)
+ _ThreadIndex __num_threads = __get_max_threads();
+# pragma omp parallel shared(__result) num_threads(__num_threads)
{
# pragma omp single
- num_threads = omp_get_num_threads();
+ __num_threads = omp_get_num_threads();
- thread_index_t iam = omp_get_thread_num();
- difference_type block_size = __s.find_initial_block_size;
+ _ThreadIndex __iam = omp_get_thread_num();
+ _DifferenceType __block_size = __s.find_initial_block_size;
// First element of thread's current iteration.
- difference_type iteration_start = sequential_search_size;
+ _DifferenceType __iteration_start = __sequential_search_size;
// Where to work (initialization).
- difference_type start = iteration_start + iam * block_size;
- difference_type stop =
- std::min<difference_type>(length, start + block_size);
+ _DifferenceType __start = __iteration_start + __iam * __block_size;
+ _DifferenceType __stop =
+ std::min<_DifferenceType>(__length, __start + __block_size);
- std::pair<RandomAccessIterator1, RandomAccessIterator2> local_result;
+ std::pair<_RAIter1, _RAIter2> __local_result;
- while (start < length)
+ while (__start < __length)
{
// Get new value of result.
-# pragma omp flush(result)
+# pragma omp flush(__result)
// No chance to find first element.
- if (result < start)
+ if (__result < __start)
break;
- local_result = selector.sequential_algorithm(
- begin1 + start, begin1 + stop,
- begin2 + start, pred);
- if (local_result.first != (begin1 + stop))
+ __local_result = __selector._M_sequential_algorithm(
+ __begin1 + __start, __begin1 + __stop,
+ __begin2 + __start, __pred);
+ if (__local_result.first != (__begin1 + __stop))
{
- omp_set_lock(&result_lock);
- if ((local_result.first - begin1) < result)
- result = local_result.first - begin1;
- omp_unset_lock(&result_lock);
+ omp_set_lock(&__result_lock);
+ if ((__local_result.first - __begin1) < __result)
+ __result = __local_result.first - __begin1;
+ omp_unset_lock(&__result_lock);
// Will not find better value in its interval.
break;
}
- iteration_start += num_threads * block_size;
+ __iteration_start += __num_threads * __block_size;
// Where to work.
- start = iteration_start + iam * block_size;
- stop = std::min<difference_type>(length, start + block_size);
+ __start = __iteration_start + __iam * __block_size;
+ __stop = std::min<_DifferenceType>(
+ __length, __start + __block_size);
}
} //parallel
- omp_destroy_lock(&result_lock);
+ omp_destroy_lock(&__result_lock);
// Return iterator on found element.
return
- std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result,
- begin2 + result);
+ std::pair<_RAIter1, _RAIter2>(__begin1 + __result, __begin2 + __result);
}
#endif
} // end namespace
diff --git a/libstdc++-v3/include/parallel/find_selectors.h b/libstdc++-v3/include/parallel/find_selectors.h
index 3cbc1b80ef8..2b1e118a64f 100644
--- a/libstdc++-v3/include/parallel/find_selectors.h
+++ b/libstdc++-v3/include/parallel/find_selectors.h
@@ -23,7 +23,7 @@
// <http://www.gnu.org/licenses/>.
/** @file parallel/find_selectors.h
- * @brief Function objects representing different tasks to be plugged
+ * @brief _Function objects representing different tasks to be plugged
* into the parallel find algorithm.
* This file is a GNU parallel extension to the Standard C++ Library.
*/
@@ -39,153 +39,157 @@
namespace __gnu_parallel
{
- /** @brief Base class of all __gnu_parallel::find_template selectors. */
- struct generic_find_selector
+ /** @brief Base class of all __gnu_parallel::__find_template selectors. */
+ struct __generic_find_selector
{ };
/**
* @brief Test predicate on a single element, used for std::find()
* and std::find_if ().
*/
- struct find_if_selector : public generic_find_selector
+ struct __find_if_selector : public __generic_find_selector
{
/** @brief Test on one position.
- * @param i1 Iterator on first sequence.
- * @param i2 Iterator on second sequence (unused).
- * @param pred Find predicate.
+ * @param __i1 _Iterator on first sequence.
+ * @param __i2 _Iterator on second sequence (unused).
+ * @param __pred Find predicate.
*/
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename Pred>
+ template<typename _RAIter1, typename _RAIter2,
+ typename _Pred>
bool
- operator()(RandomAccessIterator1 i1, RandomAccessIterator2 i2, Pred pred)
- { return pred(*i1); }
+ operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
+ { return __pred(*__i1); }
/** @brief Corresponding sequential algorithm on a sequence.
- * @param begin1 Begin iterator of first sequence.
- * @param end1 End iterator of first sequence.
- * @param begin2 Begin iterator of second sequence.
- * @param pred Find predicate.
+ * @param __begin1 Begin iterator of first sequence.
+ * @param __end1 End iterator of first sequence.
+ * @param __begin2 Begin iterator of second sequence.
+ * @param __pred Find predicate.
*/
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename Pred>
- std::pair<RandomAccessIterator1, RandomAccessIterator2>
- sequential_algorithm(RandomAccessIterator1 begin1,
- RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2, Pred pred)
- { return std::make_pair(find_if(begin1, end1, pred,
- sequential_tag()), begin2); }
+ template<typename _RAIter1, typename _RAIter2,
+ typename _Pred>
+ std::pair<_RAIter1, _RAIter2>
+ _M_sequential_algorithm(_RAIter1 __begin1,
+ _RAIter1 __end1,
+ _RAIter2 __begin2, _Pred __pred)
+ { return std::make_pair(find_if(__begin1, __end1, __pred,
+ sequential_tag()), __begin2); }
};
/** @brief Test predicate on two adjacent elements. */
- struct adjacent_find_selector : public generic_find_selector
+ struct __adjacent_find_selector : public __generic_find_selector
{
/** @brief Test on one position.
- * @param i1 Iterator on first sequence.
- * @param i2 Iterator on second sequence (unused).
- * @param pred Find predicate.
+ * @param __i1 _Iterator on first sequence.
+ * @param __i2 _Iterator on second sequence (unused).
+ * @param __pred Find predicate.
*/
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename Pred>
+ template<typename _RAIter1, typename _RAIter2,
+ typename _Pred>
bool
- operator()(RandomAccessIterator1 i1, RandomAccessIterator2 i2, Pred pred)
+ operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
{
- // Passed end iterator is one short.
- return pred(*i1, *(i1 + 1));
+ // Passed end iterator is one short.
+ return __pred(*__i1, *(__i1 + 1));
}
/** @brief Corresponding sequential algorithm on a sequence.
- * @param begin1 Begin iterator of first sequence.
- * @param end1 End iterator of first sequence.
- * @param begin2 Begin iterator of second sequence.
- * @param pred Find predicate.
+ * @param __begin1 Begin iterator of first sequence.
+ * @param __end1 End iterator of first sequence.
+ * @param __begin2 Begin iterator of second sequence.
+ * @param __pred Find predicate.
*/
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename Pred>
- std::pair<RandomAccessIterator1, RandomAccessIterator2>
- sequential_algorithm(RandomAccessIterator1 begin1,
- RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2, Pred pred)
+ template<typename _RAIter1, typename _RAIter2,
+ typename _Pred>
+ std::pair<_RAIter1, _RAIter2>
+ _M_sequential_algorithm(_RAIter1 __begin1,
+ _RAIter1 __end1,
+ _RAIter2 __begin2, _Pred __pred)
{
- // Passed end iterator is one short.
- RandomAccessIterator1 spot = adjacent_find(begin1, end1 + 1,
- pred, sequential_tag());
- if (spot == (end1 + 1))
- spot = end1;
- return std::make_pair(spot, begin2);
+ // Passed end iterator is one short.
+ _RAIter1 spot = adjacent_find(__begin1, __end1 + 1,
+ __pred, sequential_tag());
+ if (spot == (__end1 + 1))
+ spot = __end1;
+ return std::make_pair(spot, __begin2);
}
};
/** @brief Test inverted predicate on a single element. */
- struct mismatch_selector : public generic_find_selector
+ struct __mismatch_selector : public __generic_find_selector
{
/**
* @brief Test on one position.
- * @param i1 Iterator on first sequence.
- * @param i2 Iterator on second sequence (unused).
- * @param pred Find predicate.
+ * @param __i1 _Iterator on first sequence.
+ * @param __i2 _Iterator on second sequence (unused).
+ * @param __pred Find predicate.
*/
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename Pred>
+ template<typename _RAIter1, typename _RAIter2,
+ typename _Pred>
bool
- operator()(RandomAccessIterator1 i1, RandomAccessIterator2 i2, Pred pred)
- { return !pred(*i1, *i2); }
+ operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
+ { return !__pred(*__i1, *__i2); }
/**
* @brief Corresponding sequential algorithm on a sequence.
- * @param begin1 Begin iterator of first sequence.
- * @param end1 End iterator of first sequence.
- * @param begin2 Begin iterator of second sequence.
- * @param pred Find predicate.
+ * @param __begin1 Begin iterator of first sequence.
+ * @param __end1 End iterator of first sequence.
+ * @param __begin2 Begin iterator of second sequence.
+ * @param __pred Find predicate.
*/
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename Pred>
- std::pair<RandomAccessIterator1, RandomAccessIterator2>
- sequential_algorithm(RandomAccessIterator1 begin1,
- RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2, Pred pred)
- { return mismatch(begin1, end1, begin2, pred, sequential_tag()); }
+ template<typename _RAIter1, typename _RAIter2,
+ typename _Pred>
+ std::pair<_RAIter1, _RAIter2>
+ _M_sequential_algorithm(_RAIter1 __begin1,
+ _RAIter1 __end1,
+ _RAIter2 __begin2, _Pred __pred)
+ { return mismatch(__begin1, __end1, __begin2, __pred, sequential_tag());
+ }
};
/** @brief Test predicate on several elements. */
- template<typename ForwardIterator>
- struct find_first_of_selector : public generic_find_selector
+ template<typename _FIterator>
+ struct __find_first_of_selector : public __generic_find_selector
{
- ForwardIterator begin;
- ForwardIterator end;
+ _FIterator _M_begin;
+ _FIterator _M_end;
- explicit find_first_of_selector(ForwardIterator begin, ForwardIterator end)
- : begin(begin), end(end) { }
+ explicit __find_first_of_selector(_FIterator __begin, _FIterator __end)
+ : _M_begin(__begin), _M_end(__end) { }
/** @brief Test on one position.
- * @param i1 Iterator on first sequence.
- * @param i2 Iterator on second sequence (unused).
- * @param pred Find predicate. */
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename Pred>
+ * @param __i1 _Iterator on first sequence.
+ * @param __i2 _Iterator on second sequence (unused).
+ * @param __pred Find predicate. */
+ template<typename _RAIter1, typename _RAIter2,
+ typename _Pred>
bool
- operator()(RandomAccessIterator1 i1, RandomAccessIterator2 i2, Pred pred)
+ operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
{
- for (ForwardIterator pos_in_candidates = begin;
- pos_in_candidates != end; ++pos_in_candidates)
- if (pred(*i1, *pos_in_candidates))
- return true;
- return false;
+ for (_FIterator __pos_in_candidates = _M_begin;
+ __pos_in_candidates != _M_end; ++__pos_in_candidates)
+ if (__pred(*__i1, *__pos_in_candidates))
+ return true;
+ return false;
}
/** @brief Corresponding sequential algorithm on a sequence.
- * @param begin1 Begin iterator of first sequence.
- * @param end1 End iterator of first sequence.
- * @param begin2 Begin iterator of second sequence.
- * @param pred Find predicate. */
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename Pred>
- std::pair<RandomAccessIterator1, RandomAccessIterator2>
- sequential_algorithm(RandomAccessIterator1 begin1,
- RandomAccessIterator1 end1,
- RandomAccessIterator2 begin2, Pred pred)
- { return std::make_pair(find_first_of(begin1, end1, begin, end, pred,
- sequential_tag()), begin2); }
+ * @param __begin1 Begin iterator of first sequence.
+ * @param __end1 End iterator of first sequence.
+ * @param __begin2 Begin iterator of second sequence.
+ * @param __pred Find predicate. */
+ template<typename _RAIter1, typename _RAIter2,
+ typename _Pred>
+ std::pair<_RAIter1, _RAIter2>
+ _M_sequential_algorithm(_RAIter1 __begin1,
+ _RAIter1 __end1,
+ _RAIter2 __begin2, _Pred __pred)
+ {
+ return std::make_pair(
+ find_first_of(__begin1, __end1, _M_begin, _M_end, __pred,
+ sequential_tag()), __begin2);
+ }
};
}
diff --git a/libstdc++-v3/include/parallel/for_each.h b/libstdc++-v3/include/parallel/for_each.h
index 61158f86582..f1c9c23b8a5 100644
--- a/libstdc++-v3/include/parallel/for_each.h
+++ b/libstdc++-v3/include/parallel/for_each.h
@@ -42,55 +42,58 @@
namespace __gnu_parallel
{
- /** @brief Chose the desired algorithm by evaluating @c parallelism_tag.
- * @param begin Begin iterator of input sequence.
- * @param end End iterator of input sequence.
- * @param user_op A user-specified functor (comparator, predicate,
+ /** @brief Chose the desired algorithm by evaluating @__c __parallelism_tag.
+ * @param __begin Begin iterator of input sequence.
+ * @param __end End iterator of input sequence.
+ * @param __user_op A user-specified functor (comparator, predicate,
* associative operator,...)
- * @param functionality functor to "process" an element with
- * user_op (depends on desired functionality, e. g. accumulate,
+ * @param __functionality functor to "process" an element with
+ * __user_op (depends on desired functionality, e. g. accumulate,
* for_each,...
- * @param reduction Reduction functor.
- * @param reduction_start Initial value for reduction.
- * @param output Output iterator.
- * @param bound Maximum number of elements processed.
- * @param parallelism_tag Parallelization method */
- template<typename InputIterator, typename UserOp,
- typename Functionality, typename Red, typename Result>
- UserOp
- for_each_template_random_access(InputIterator begin, InputIterator end,
- UserOp user_op,
- Functionality& functionality,
- Red reduction, Result reduction_start,
- Result& output, typename
- std::iterator_traits<InputIterator>::
- difference_type bound,
- _Parallelism parallelism_tag)
+ * @param __reduction Reduction functor.
+ * @param __reduction_start Initial value for reduction.
+ * @param __output Output iterator.
+ * @param __bound Maximum number of elements processed.
+ * @param __parallelism_tag Parallelization method */
+ template<typename _IIter, typename _UserOp,
+ typename _Functionality, typename _Red, typename _Result>
+ _UserOp
+ __for_each_template_random_access(_IIter __begin, _IIter __end,
+ _UserOp __user_op,
+ _Functionality& __functionality,
+ _Red __reduction,
+ _Result __reduction_start,
+ _Result& __output, typename
+ std::iterator_traits<_IIter>::
+ difference_type __bound,
+ _Parallelism __parallelism_tag)
{
- if (parallelism_tag == parallel_unbalanced)
- return for_each_template_random_access_ed(begin, end, user_op,
- functionality, reduction,
- reduction_start,
- output, bound);
- else if (parallelism_tag == parallel_omp_loop)
- return for_each_template_random_access_omp_loop(begin, end, user_op,
- functionality,
- reduction,
- reduction_start,
- output, bound);
- else if (parallelism_tag == parallel_omp_loop_static)
- return for_each_template_random_access_omp_loop(begin, end, user_op,
- functionality,
- reduction,
- reduction_start,
- output, bound);
- else //e. g. parallel_balanced
- return for_each_template_random_access_workstealing(begin, end,
- user_op,
- functionality,
- reduction,
- reduction_start,
- output, bound);
+ if (__parallelism_tag == parallel_unbalanced)
+ return for_each_template_random_access_ed(__begin, __end, __user_op,
+ __functionality, __reduction,
+ __reduction_start,
+ __output, __bound);
+ else if (__parallelism_tag == parallel_omp_loop)
+ return for_each_template_random_access_omp_loop(
+ __begin, __end, __user_op,
+ __functionality,
+ __reduction,
+ __reduction_start,
+ __output, __bound);
+ else if (__parallelism_tag == parallel_omp_loop_static)
+ return for_each_template_random_access_omp_loop(
+ __begin, __end, __user_op,
+ __functionality,
+ __reduction,
+ __reduction_start,
+ __output, __bound);
+ else //e. g. parallel_balanced
+ return for_each_template_random_access_workstealing(__begin, __end,
+ __user_op,
+ __functionality,
+ __reduction,
+ __reduction_start,
+ __output, __bound);
}
}
diff --git a/libstdc++-v3/include/parallel/for_each_selectors.h b/libstdc++-v3/include/parallel/for_each_selectors.h
index b46d30f51f2..9b3bb6b5703 100644
--- a/libstdc++-v3/include/parallel/for_each_selectors.h
+++ b/libstdc++-v3/include/parallel/for_each_selectors.h
@@ -38,192 +38,193 @@
namespace __gnu_parallel
{
- /** @brief Generic selector for embarrassingly parallel functions. */
- template<typename It>
- struct generic_for_each_selector
+ /** @brief Generic __selector for embarrassingly parallel functions. */
+ template<typename _It>
+ struct __generic_for_each_selector
{
- /** @brief Iterator on last element processed; needed for some
+ /** @brief _Iterator on last element processed; needed for some
* algorithms (e. g. std::transform()).
*/
- It finish_iterator;
+ _It _M_finish_iterator;
};
/** @brief std::for_each() selector. */
- template<typename It>
- struct for_each_selector : public generic_for_each_selector<It>
+ template<typename _It>
+ struct __for_each_selector : public __generic_for_each_selector<_It>
{
/** @brief Functor execution.
- * @param o Operator.
- * @param i Iterator referencing object. */
- template<typename Op>
+ * @param __o Operator.
+ * @param __i iterator referencing object. */
+ template<typename _Op>
bool
- operator()(Op& o, It i)
- {
- o(*i);
- return true;
- }
+ operator()(_Op& __o, _It __i)
+ {
+ __o(*__i);
+ return true;
+ }
};
/** @brief std::generate() selector. */
- template<typename It>
- struct generate_selector : public generic_for_each_selector<It>
+ template<typename _It>
+ struct __generate_selector : public __generic_for_each_selector<_It>
{
/** @brief Functor execution.
- * @param o Operator.
- * @param i Iterator referencing object. */
- template<typename Op>
+ * @param __o Operator.
+ * @param __i iterator referencing object. */
+ template<typename _Op>
bool
- operator()(Op& o, It i)
+ operator()(_Op& __o, _It __i)
{
- *i = o();
- return true;
- }
+ *__i = __o();
+ return true;
+ }
};
/** @brief std::fill() selector. */
- template<typename It>
- struct fill_selector : public generic_for_each_selector<It>
+ template<typename _It>
+ struct __fill_selector : public __generic_for_each_selector<_It>
{
/** @brief Functor execution.
- * @param v Current value.
- * @param i Iterator referencing object. */
+ * @param __v Current value.
+ * @param __i iterator referencing object. */
template<typename Val>
bool
- operator()(Val& v, It i)
- {
- *i = v;
- return true;
- }
+ operator()(Val& __v, _It __i)
+ {
+ *__i = __v;
+ return true;
+ }
};
- /** @brief std::transform() selector, one input sequence variant. */
- template<typename It>
- struct transform1_selector : public generic_for_each_selector<It>
+ /** @brief std::transform() __selector, one input sequence variant. */
+ template<typename _It>
+ struct __transform1_selector : public __generic_for_each_selector<_It>
{
/** @brief Functor execution.
- * @param o Operator.
- * @param i Iterator referencing object. */
- template<typename Op>
+ * @param __o Operator.
+ * @param __i iterator referencing object. */
+ template<typename _Op>
bool
- operator()(Op& o, It i)
- {
- *i.second = o(*i.first);
- return true;
- }
+ operator()(_Op& __o, _It __i)
+ {
+ *__i.second = __o(*__i.first);
+ return true;
+ }
};
- /** @brief std::transform() selector, two input sequences variant. */
- template<typename It>
- struct transform2_selector : public generic_for_each_selector<It>
+ /** @brief std::transform() __selector, two input sequences variant. */
+ template<typename _It>
+ struct __transform2_selector : public __generic_for_each_selector<_It>
{
/** @brief Functor execution.
- * @param o Operator.
- * @param i Iterator referencing object. */
- template<typename Op>
+ * @param __o Operator.
+ * @param __i iterator referencing object. */
+ template<typename _Op>
bool
- operator()(Op& o, It i)
- {
- *i.third = o(*i.first, *i.second);
- return true;
- }
+ operator()(_Op& __o, _It __i)
+ {
+ *__i._M_third = __o(*__i._M_first, *__i._M_second);
+ return true;
+ }
};
/** @brief std::replace() selector. */
- template<typename It, typename T>
- struct replace_selector : public generic_for_each_selector<It>
+ template<typename _It, typename _Tp>
+ struct __replace_selector : public __generic_for_each_selector<_It>
{
/** @brief Value to replace with. */
- const T& new_val;
+ const _Tp& __new_val;
/** @brief Constructor
- * @param new_val Value to replace with. */
+ * @param __new_val Value to replace with. */
explicit
- replace_selector(const T &new_val) : new_val(new_val) {}
+ __replace_selector(const _Tp &__new_val) : __new_val(__new_val) {}
/** @brief Functor execution.
- * @param v Current value.
- * @param i Iterator referencing object. */
+ * @param __v Current value.
+ * @param __i iterator referencing object. */
bool
- operator()(T& v, It i)
+ operator()(_Tp& __v, _It __i)
{
- if (*i == v)
- *i = new_val;
- return true;
+ if (*__i == __v)
+ *__i = __new_val;
+ return true;
}
};
/** @brief std::replace() selector. */
- template<typename It, typename Op, typename T>
- struct replace_if_selector : public generic_for_each_selector<It>
+ template<typename _It, typename _Op, typename _Tp>
+ struct __replace_if_selector : public __generic_for_each_selector<_It>
{
/** @brief Value to replace with. */
- const T& new_val;
+ const _Tp& __new_val;
/** @brief Constructor.
- * @param new_val Value to replace with. */
+ * @param __new_val Value to replace with. */
explicit
- replace_if_selector(const T &new_val) : new_val(new_val) { }
+ __replace_if_selector(const _Tp &__new_val) : __new_val(__new_val) { }
/** @brief Functor execution.
- * @param o Operator.
- * @param i Iterator referencing object. */
+ * @param __o Operator.
+ * @param __i iterator referencing object. */
bool
- operator()(Op& o, It i)
+ operator()(_Op& __o, _It __i)
{
- if (o(*i))
- *i = new_val;
- return true;
+ if (__o(*__i))
+ *__i = __new_val;
+ return true;
}
};
/** @brief std::count() selector. */
- template<typename It, typename Diff>
- struct count_selector : public generic_for_each_selector<It>
+ template<typename _It, typename _Diff>
+ struct __count_selector : public __generic_for_each_selector<_It>
{
/** @brief Functor execution.
- * @param v Current value.
- * @param i Iterator referencing object.
+ * @param __v Current value.
+ * @param __i iterator referencing object.
* @return 1 if count, 0 if does not count. */
template<typename Val>
- Diff
- operator()(Val& v, It i)
- { return (v == *i) ? 1 : 0; }
+ _Diff
+ operator()(Val& __v, _It __i)
+ { return (__v == *__i) ? 1 : 0; }
};
/** @brief std::count_if () selector. */
- template<typename It, typename Diff>
- struct count_if_selector : public generic_for_each_selector<It>
+ template<typename _It, typename _Diff>
+ struct __count_if_selector : public __generic_for_each_selector<_It>
{
/** @brief Functor execution.
- * @param o Operator.
- * @param i Iterator referencing object.
+ * @param __o Operator.
+ * @param __i iterator referencing object.
* @return 1 if count, 0 if does not count. */
- template<typename Op>
- Diff
- operator()(Op& o, It i)
- { return (o(*i)) ? 1 : 0; }
+ template<typename _Op>
+ _Diff
+ operator()(_Op& __o, _It __i)
+ { return (__o(*__i)) ? 1 : 0; }
};
/** @brief std::accumulate() selector. */
- template<typename It>
- struct accumulate_selector : public generic_for_each_selector<It>
+ template<typename _It>
+ struct __accumulate_selector : public __generic_for_each_selector<_It>
{
/** @brief Functor execution.
- * @param o Operator (unused).
- * @param i Iterator referencing object.
+ * @param __o Operator (unused).
+ * @param __i iterator referencing object.
* @return The current value. */
- template<typename Op>
- typename std::iterator_traits<It>::value_type operator()(Op o, It i)
- { return *i; }
+ template<typename _Op>
+ typename std::iterator_traits<_It>::value_type
+ operator()(_Op __o, _It __i)
+ { return *__i; }
};
/** @brief std::inner_product() selector. */
- template<typename It, typename It2, typename T>
- struct inner_product_selector : public generic_for_each_selector<It>
+ template<typename _It, typename It2, typename _Tp>
+ struct __inner_product_selector : public __generic_for_each_selector<_It>
{
/** @brief Begin iterator of first sequence. */
- It begin1_iterator;
+ _It __begin1_iterator;
/** @brief Begin iterator of second sequence. */
It2 begin2_iterator;
@@ -232,128 +233,129 @@ namespace __gnu_parallel
* @param b1 Begin iterator of first sequence.
* @param b2 Begin iterator of second sequence. */
explicit
- inner_product_selector(It b1, It2 b2)
- : begin1_iterator(b1), begin2_iterator(b2) { }
+ __inner_product_selector(_It b1, It2 b2)
+ : __begin1_iterator(b1), begin2_iterator(b2) { }
/** @brief Functor execution.
- * @param mult Multiplication functor.
- * @param current Iterator referencing object.
- * @return Inner product elemental result. */
- template<typename Op>
- T
- operator()(Op mult, It current)
- {
- typename std::iterator_traits<It>::difference_type position
- = current - begin1_iterator;
- return mult(*current, *(begin2_iterator + position));
- }
+ * @param __mult Multiplication functor.
+ * @param __current iterator referencing object.
+ * @return Inner product elemental __result. */
+ template<typename _Op>
+ _Tp
+ operator()(_Op __mult, _It __current)
+ {
+ typename std::iterator_traits<_It>::difference_type __position
+ = __current - __begin1_iterator;
+ return __mult(*__current, *(begin2_iterator + __position));
+ }
};
/** @brief Selector that just returns the passed iterator. */
- template<typename It>
- struct identity_selector : public generic_for_each_selector<It>
+ template<typename _It>
+ struct __identity_selector : public __generic_for_each_selector<_It>
{
/** @brief Functor execution.
- * @param o Operator (unused).
- * @param i Iterator referencing object.
+ * @param __o Operator (unused).
+ * @param __i iterator referencing object.
* @return Passed iterator. */
- template<typename Op>
- It
- operator()(Op o, It i)
- { return i; }
+ template<typename _Op>
+ _It
+ operator()(_Op __o, _It __i)
+ { return __i; }
};
/** @brief Selector that returns the difference between two adjacent
- * elements.
+ * __elements.
*/
- template<typename It>
- struct adjacent_difference_selector : public generic_for_each_selector<It>
+ template<typename _It>
+ struct __adjacent_difference_selector :
+ public __generic_for_each_selector<_It>
{
- template<typename Op>
+ template<typename _Op>
bool
- operator()(Op& o, It i)
- {
- typename It::first_type go_back_one = i.first;
- --go_back_one;
- *i.second = o(*i.first, *go_back_one);
- return true;
- }
+ operator()(_Op& __o, _It __i)
+ {
+ typename _It::first_type __go_back_one = __i.first;
+ --__go_back_one;
+ *__i.__second = __o(*__i.__first, *__go_back_one);
+ return true;
+ }
};
// XXX move into type_traits?
/** @brief Functor doing nothing
*
- * For some reduction tasks (this is not a function object, but is
- * passed as selector dummy parameter.
+ * For some __reduction tasks (this is not a function object, but is
+ * passed as __selector __dummy parameter.
*/
- struct nothing
+ struct _Nothing
{
/** @brief Functor execution.
- * @param i Iterator referencing object. */
- template<typename It>
+ * @param __i iterator referencing object. */
+ template<typename _It>
void
- operator()(It i) { }
+ operator()(_It __i) { }
};
/** @brief Reduction function doing nothing. */
- struct dummy_reduct
+ struct _DummyReduct
{
bool
- operator()(bool /*x*/, bool /*y*/) const
+ operator()(bool /*__x*/, bool /*__y*/) const
{ return true; }
};
/** @brief Reduction for finding the maximum element, using a comparator. */
- template<typename Comp, typename It>
- struct min_element_reduct
+ template<typename _Compare, typename _It>
+ struct __min_element_reduct
{
- Comp& comp;
+ _Compare& __comp;
explicit
- min_element_reduct(Comp &c) : comp(c) { }
+ __min_element_reduct(_Compare &__c) : __comp(__c) { }
- It
- operator()(It x, It y)
+ _It
+ operator()(_It __x, _It __y)
{
- if (comp(*x, *y))
- return x;
- else
- return y;
+ if (__comp(*__x, *__y))
+ return __x;
+ else
+ return __y;
}
};
/** @brief Reduction for finding the maximum element, using a comparator. */
- template<typename Comp, typename It>
- struct max_element_reduct
+ template<typename _Compare, typename _It>
+ struct __max_element_reduct
{
- Comp& comp;
+ _Compare& __comp;
explicit
- max_element_reduct(Comp& c) : comp(c) { }
+ __max_element_reduct(_Compare& __c) : __comp(__c) { }
- It
- operator()(It x, It y)
+ _It
+ operator()(_It __x, _It __y)
{
- if (comp(*x, *y))
- return y;
- else
- return x;
+ if (__comp(*__x, *__y))
+ return __y;
+ else
+ return __x;
}
};
/** @brief General reduction, using a binary operator. */
- template<typename BinOp>
- struct accumulate_binop_reduct
+ template<typename _BinOp>
+ struct __accumulate_binop_reduct
{
- BinOp& binop;
+ _BinOp& __binop;
explicit
- accumulate_binop_reduct(BinOp& b) : binop(b) { }
+ __accumulate_binop_reduct(_BinOp& __b) : __binop(__b) { }
- template<typename Result, typename Addend>
- Result
- operator()(const Result& x, const Addend& y)
- { return binop(x, y); }
+ template<typename _Result, typename _Addend>
+ _Result
+ operator()(const _Result& __x, const _Addend& __y)
+ { return __binop(__x, __y); }
};
}
diff --git a/libstdc++-v3/include/parallel/iterator.h b/libstdc++-v3/include/parallel/iterator.h
index c9bfd5a2fdb..013855076f4 100644
--- a/libstdc++-v3/include/parallel/iterator.h
+++ b/libstdc++-v3/include/parallel/iterator.h
@@ -40,160 +40,158 @@ namespace __gnu_parallel
/** @brief A pair of iterators. The usual iterator operations are
* applied to both child iterators.
*/
- template<typename Iterator1, typename Iterator2, typename IteratorCategory>
- class iterator_pair : public std::pair<Iterator1, Iterator2>
+ template<typename _Iterator1, typename _Iterator2,
+ typename _IteratorCategory>
+ class _IteratorPair : public std::pair<_Iterator1, _Iterator2>
{
private:
- typedef iterator_pair<Iterator1, Iterator2, IteratorCategory> type;
- typedef std::pair<Iterator1, Iterator2> base_type;
+ typedef std::pair<_Iterator1, _Iterator2> _Base;
public:
- typedef IteratorCategory iterator_category;
+ typedef _IteratorCategory iterator_category;
typedef void value_type;
- typedef std::iterator_traits<Iterator1> traits_type;
- typedef typename traits_type::difference_type difference_type;
- typedef type* pointer;
- typedef type& reference;
+ typedef std::iterator_traits<_Iterator1> _TraitsType;
+ typedef typename _TraitsType::difference_type difference_type;
+ typedef _IteratorPair* pointer;
+ typedef _IteratorPair& reference;
- iterator_pair() { }
+ _IteratorPair() { }
- iterator_pair(const Iterator1& first, const Iterator2& second)
- : base_type(first, second) { }
+ _IteratorPair(const _Iterator1& __first, const _Iterator2& __second)
+ : _Base(__first, __second) { }
// Pre-increment operator.
- type&
+ _IteratorPair&
operator++()
{
- ++base_type::first;
- ++base_type::second;
- return *this;
+ ++_Base::first;
+ ++_Base::second;
+ return *this;
}
// Post-increment operator.
- const type
+ const _IteratorPair
operator++(int)
- { return type(base_type::first++, base_type::second++); }
+ { return _IteratorPair(_Base::first++, _Base::second++); }
// Pre-decrement operator.
- type&
+ _IteratorPair&
operator--()
{
- --base_type::first;
- --base_type::second;
- return *this;
+ --_Base::first;
+ --_Base::second;
+ return *this;
}
// Post-decrement operator.
- const type
+ const _IteratorPair
operator--(int)
- { return type(base_type::first--, base_type::second--); }
+ { return _IteratorPair(_Base::first--, _Base::second--); }
// Type conversion.
- operator Iterator2() const
- { return base_type::second; }
+ operator _Iterator2() const
+ { return _Base::second; }
- type&
- operator=(const type& other)
+ _IteratorPair&
+ operator=(const _IteratorPair& __other)
{
- base_type::first = other.first;
- base_type::second = other.second;
- return *this;
+ _Base::first = __other.first;
+ _Base::second = __other.second;
+ return *this;
}
- type
- operator+(difference_type delta) const
- { return type(base_type::first + delta, base_type::second + delta); }
+ _IteratorPair
+ operator+(difference_type __delta) const
+ { return _IteratorPair(_Base::first + __delta, _Base::second + __delta);
+ }
difference_type
- operator-(const type& other) const
- { return base_type::first - other.first; }
+ operator-(const _IteratorPair& __other) const
+ { return _Base::first - __other.first; }
};
/** @brief A triple of iterators. The usual iterator operations are
applied to all three child iterators.
*/
- template<typename Iterator1, typename Iterator2, typename Iterator3,
- typename IteratorCategory>
- class iterator_triple
+ template<typename _Iterator1, typename _Iterator2, typename _Iterator3,
+ typename _IteratorCategory>
+ class _IteratorTriple
{
- private:
- typedef iterator_triple<Iterator1, Iterator2, Iterator3,
- IteratorCategory> type;
-
public:
- typedef IteratorCategory iterator_category;
+ typedef _IteratorCategory iterator_category;
typedef void value_type;
- typedef typename std::iterator_traits<Iterator1>::difference_type
+ typedef typename std::iterator_traits<_Iterator1>::difference_type
difference_type;
- typedef type* pointer;
- typedef type& reference;
+ typedef _IteratorTriple* pointer;
+ typedef _IteratorTriple& reference;
- Iterator1 first;
- Iterator2 second;
- Iterator3 third;
+ _Iterator1 _M_first;
+ _Iterator2 _M_second;
+ _Iterator3 _M_third;
- iterator_triple() { }
+ _IteratorTriple() { }
- iterator_triple(const Iterator1& _first, const Iterator2& _second,
- const Iterator3& _third)
+ _IteratorTriple(const _Iterator1& __first, const _Iterator2& __second,
+ const _Iterator3& __third)
{
- first = _first;
- second = _second;
- third = _third;
+ _M_first = __first;
+ _M_second = __second;
+ _M_third = __third;
}
// Pre-increment operator.
- type&
+ _IteratorTriple&
operator++()
{
- ++first;
- ++second;
- ++third;
- return *this;
+ ++_M_first;
+ ++_M_second;
+ ++_M_third;
+ return *this;
}
// Post-increment operator.
- const type
+ const _IteratorTriple
operator++(int)
- { return type(first++, second++, third++); }
+ { return _IteratorTriple(_M_first++, _M_second++, _M_third++); }
// Pre-decrement operator.
- type&
+ _IteratorTriple&
operator--()
{
- --first;
- --second;
- --third;
- return *this;
+ --_M_first;
+ --_M_second;
+ --_M_third;
+ return *this;
}
// Post-decrement operator.
- const type
+ const _IteratorTriple
operator--(int)
- { return type(first--, second--, third--); }
+ { return _IteratorTriple(_M_first--, _M_second--, _M_third--); }
// Type conversion.
- operator Iterator3() const
- { return third; }
+ operator _Iterator3() const
+ { return _M_third; }
- type&
- operator=(const type& other)
+ _IteratorTriple&
+ operator=(const _IteratorTriple& __other)
{
- first = other.first;
- second = other.second;
- third = other.third;
- return *this;
+ _M_first = __other._M_first;
+ _M_second = __other._M_second;
+ _M_third = __other._M_third;
+ return *this;
}
- type
- operator+(difference_type delta) const
- { return type(first + delta, second + delta, third + delta); }
+ _IteratorTriple
+ operator+(difference_type __delta) const
+ { return _IteratorTriple(_M_first + __delta, _M_second + __delta,
+ _M_third + __delta); }
difference_type
- operator-(const type& other) const
- { return first - other.first; }
+ operator-(const _IteratorTriple& __other) const
+ { return _M_first - __other._M_first; }
};
}
diff --git a/libstdc++-v3/include/parallel/list_partition.h b/libstdc++-v3/include/parallel/list_partition.h
index a359a3f3a40..7eed96b4a0d 100644
--- a/libstdc++-v3/include/parallel/list_partition.h
+++ b/libstdc++-v3/include/parallel/list_partition.h
@@ -3,12 +3,12 @@
// Copyright (C) 2007, 2008, 2009 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
+// 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 3, or (at your option) any later
// version.
-// This library is distributed in the hope that it will be useful, but
+// 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.
@@ -23,7 +23,7 @@
// <http://www.gnu.org/licenses/>.
/** @file parallel/list_partition.h
- * @brief Functionality to split sequence referenced by only input
+ * @brief _Functionality to split __sequence referenced by only input
* iterators.
* This file is a GNU parallel extension to the Standard C++ Library.
*/
@@ -39,137 +39,139 @@
namespace __gnu_parallel
{
/** @brief Shrinks and doubles the ranges.
- * @param os_starts Start positions worked on (oversampled).
- * @param count_to_two Counts up to 2.
- * @param range_length Current length of a chunk.
- * @param make_twice Whether the @c os_starts is allowed to be
+ * @param __os_starts Start positions worked on (oversampled).
+ * @param __count_to_two Counts up to 2.
+ * @param __range_length Current length of a chunk.
+ * @param __make_twice Whether the @__c __os_starts is allowed to be
* grown or not
*/
- template<typename InputIterator>
+ template<typename _IIter>
void
- shrink_and_double(std::vector<InputIterator>& os_starts,
- size_t& count_to_two, size_t& range_length,
- const bool make_twice)
+ __shrink_and_double(std::vector<_IIter>& __os_starts,
+ size_t& __count_to_two, size_t& __range_length,
+ const bool __make_twice)
{
- ++count_to_two;
- if (not make_twice or count_to_two < 2)
- shrink(os_starts, count_to_two, range_length);
+ ++__count_to_two;
+ if (not __make_twice or __count_to_two < 2)
+ __shrink(__os_starts, __count_to_two, __range_length);
else
- {
- os_starts.resize((os_starts.size() - 1) * 2 + 1);
- count_to_two = 0;
- }
+ {
+ __os_starts.resize((__os_starts.size() - 1) * 2 + 1);
+ __count_to_two = 0;
+ }
}
/** @brief Combines two ranges into one and thus halves the number of ranges.
- * @param os_starts Start positions worked on (oversampled).
- * @param count_to_two Counts up to 2.
- * @param range_length Current length of a chunk. */
- template<typename InputIterator>
+ * @param __os_starts Start positions worked on (oversampled).
+ * @param __count_to_two Counts up to 2.
+ * @param __range_length Current length of a chunk. */
+ template<typename _IIter>
void
- shrink(std::vector<InputIterator>& os_starts, size_t& count_to_two,
- size_t& range_length)
+ __shrink(std::vector<_IIter>& __os_starts, size_t& __count_to_two,
+ size_t& __range_length)
{
- for (typename std::vector<InputIterator>::size_type i = 0;
- i <= (os_starts.size() / 2); ++i)
- os_starts[i] = os_starts[i * 2];
- range_length *= 2;
+ for (typename std::vector<_IIter>::size_type __i = 0;
+ __i <= (__os_starts.size() / 2); ++__i)
+ __os_starts[__i] = __os_starts[__i * 2];
+ __range_length *= 2;
}
/** @brief Splits a sequence given by input iterators into parts of
* almost equal size
*
* The function needs only one pass over the sequence.
- * @param begin Begin iterator of input sequence.
- * @param end End iterator of input sequence.
- * @param starts Start iterators for the resulting parts, dimension
- * @c num_parts+1. For convenience, @c starts @c [num_parts]
+ * @param __begin Begin iterator of input sequence.
+ * @param __end End iterator of input sequence.
+ * @param __starts Start iterators for the resulting parts, dimension
+ * @__c __num_parts+1. For convenience, @__c __starts @__c [__num_parts]
* contains the end iterator of the sequence.
- * @param lengths Length of the resulting parts.
- * @param num_parts Number of parts to split the sequence into.
- * @param f Functor to be applied to each element by traversing it
- * @param oversampling Oversampling factor. If 0, then the
- * partitions will differ in at most @f$ \sqrt{\mathrm{end} -
- * \mathrm{begin}} @f$ elements. Otherwise, the ratio between the
- * longest and the shortest part is bounded by @f$
- * 1/(\mathrm{oversampling} \cdot \mathrm{num\_parts}) @f$.
+ * @param __lengths Length of the resulting parts.
+ * @param __num_parts Number of parts to split the sequence into.
+ * @param __f Functor to be applied to each element by traversing __it
+ * @param __oversampling Oversampling factor. If 0, then the
+ * partitions will differ in at most @__f$ \sqrt{\mathrm{__end} -
+ * \mathrm{__begin}} @__f$ __elements. Otherwise, the ratio between the
+ * longest and the shortest part is bounded by @__f$
+ * 1/(\mathrm{__oversampling} \cdot \mathrm{num\_parts}) @__f$.
* @return Length of the whole sequence.
*/
- template<typename InputIterator, typename FunctorType>
+ template<typename _IIter, typename _FunctorType>
size_t
- list_partition(const InputIterator begin, const InputIterator end,
- InputIterator* starts, size_t* lengths, const int num_parts,
- FunctorType& f, int oversampling = 0)
+ list_partition(const _IIter __begin, const _IIter __end,
+ _IIter* __starts, size_t* __lengths, const int __num_parts,
+ _FunctorType& __f, int __oversampling = 0)
{
- bool make_twice = false;
+ bool __make_twice = false;
// The resizing algorithm is chosen according to the oversampling factor.
- if (oversampling == 0)
- {
- make_twice = true;
- oversampling = 1;
- }
-
- std::vector<InputIterator> os_starts(2 * oversampling * num_parts + 1);
-
- os_starts[0]= begin;
- InputIterator prev = begin, it = begin;
- size_t dist_limit = 0, dist = 0;
- size_t cur = 1, next = 1;
- size_t range_length = 1;
- size_t count_to_two = 0;
- while (it != end)
- {
- cur = next;
- for (; cur < os_starts.size() and it != end; ++cur)
- {
- for (dist_limit += range_length;
- dist < dist_limit and it != end; ++dist)
- {
- f(it);
- ++it;
- }
- os_starts[cur] = it;
- }
-
- // Must compare for end and not cur < os_starts.size() , because
- // cur could be == os_starts.size() as well
- if (it == end)
- break;
-
- shrink_and_double(os_starts, count_to_two, range_length, make_twice);
- next = os_starts.size() / 2 + 1;
- }
-
- // Calculation of the parts (one must be extracted from current
- // because the partition beginning at end, consists only of
+ if (__oversampling == 0)
+ {
+ __make_twice = true;
+ __oversampling = 1;
+ }
+
+ std::vector<_IIter> __os_starts(2 * __oversampling * __num_parts + 1);
+
+ __os_starts[0]= __begin;
+ _IIter __prev = __begin, __it = __begin;
+ size_t __dist_limit = 0, __dist = 0;
+ size_t __cur = 1, __next = 1;
+ size_t __range_length = 1;
+ size_t __count_to_two = 0;
+ while (__it != __end)
+ {
+ __cur = __next;
+ for (; __cur < __os_starts.size() and __it != __end; ++__cur)
+ {
+ for (__dist_limit += __range_length;
+ __dist < __dist_limit and __it != __end; ++__dist)
+ {
+ __f(__it);
+ ++__it;
+ }
+ __os_starts[__cur] = __it;
+ }
+
+ // Must compare for end and not __cur < __os_starts.size() , because
+ // __cur could be == __os_starts.size() as well
+ if (__it == __end)
+ break;
+
+ __shrink_and_double(__os_starts, __count_to_two, __range_length,
+ __make_twice);
+ __next = __os_starts.size() / 2 + 1;
+ }
+
+ // Calculation of the parts (one must be extracted from __current
+ // because the partition beginning at __end, consists only of
// itself).
- size_t size_part = (cur - 1) / num_parts;
- int size_greater = static_cast<int>((cur - 1) % num_parts);
- starts[0] = os_starts[0];
+ size_t __size_part = (__cur - 1) / __num_parts;
+ int __size_greater = static_cast<int>((__cur - 1) % __num_parts);
+ __starts[0] = __os_starts[0];
- size_t index = 0;
+ size_t __index = 0;
// Smallest partitions.
- for (int i = 1; i < (num_parts + 1 - size_greater); ++i)
- {
- lengths[i - 1] = size_part * range_length;
- index += size_part;
- starts[i] = os_starts[index];
- }
+ for (int __i = 1; __i < (__num_parts + 1 - __size_greater); ++__i)
+ {
+ __lengths[__i - 1] = __size_part * __range_length;
+ __index += __size_part;
+ __starts[__i] = __os_starts[__index];
+ }
// Biggest partitions.
- for (int i = num_parts + 1 - size_greater; i <= num_parts; ++i)
- {
- lengths[i - 1] = (size_part+1) * range_length;
- index += (size_part+1);
- starts[i] = os_starts[index];
- }
+ for (int __i = __num_parts + 1 - __size_greater; __i <= __num_parts;
+ ++__i)
+ {
+ __lengths[__i - 1] = (__size_part+1) * __range_length;
+ __index += (__size_part+1);
+ __starts[__i] = __os_starts[__index];
+ }
// Correction of the end size (the end iteration has not finished).
- lengths[num_parts - 1] -= (dist_limit - dist);
+ __lengths[__num_parts - 1] -= (__dist_limit - __dist);
- return dist;
+ return __dist;
}
}
diff --git a/libstdc++-v3/include/parallel/losertree.h b/libstdc++-v3/include/parallel/losertree.h
index 6dbd5928864..239aac8c057 100644
--- a/libstdc++-v3/include/parallel/losertree.h
+++ b/libstdc++-v3/include/parallel/losertree.h
@@ -46,164 +46,165 @@ namespace __gnu_parallel
*
* The smallest element is at the top.
*
- * Guarding is done explicitly through one flag sup per element,
+ * Guarding is done explicitly through one flag _M_sup per element,
* inf is not needed due to a better initialization routine. This
* is a well-performing variant.
*
- * @param T the element type
- * @param Comparator the comparator to use, defaults to std::less<T>
+ * @param _Tp the element type
+ * @param _Compare the comparator to use, defaults to std::less<_Tp>
*/
-template<typename T, typename Comparator>
-class LoserTreeBase
+template<typename _Tp, typename _Compare>
+class _LoserTreeBase
{
protected:
- /** @brief Internal representation of a LoserTree element. */
- struct Loser
- {
- /** @brief flag, true iff this is a "maximum" sentinel. */
- bool sup;
- /** @brief index of the source sequence. */
- int source;
- /** @brief key of the element in the LoserTree. */
- T key;
+ /** @brief Internal representation of a _LoserTree element. */
+ struct _Loser
+ {
+ /** @brief flag, true iff this is a "maximum" __sentinel. */
+ bool _M_sup;
+ /** @brief __index of the _M_source __sequence. */
+ int _M_source;
+ /** @brief _M_key of the element in the _LoserTree. */
+ _Tp _M_key;
};
- unsigned int ik, k, offset;
+ unsigned int _M_ik, _M_k, _M_offset;
- /** log_2{k} */
+ /** log_2{_M_k} */
unsigned int _M_log_k;
- /** @brief LoserTree elements. */
- Loser* losers;
+ /** @brief _LoserTree __elements. */
+ _Loser* _M_losers;
- /** @brief Comparator to use. */
- Comparator comp;
+ /** @brief _Compare to use. */
+ _Compare _M_comp;
/**
- * @brief State flag that determines whether the LoserTree is empty.
+ * @brief State flag that determines whether the _LoserTree is empty.
*
- * Only used for building the LoserTree.
+ * Only used for building the _LoserTree.
*/
- bool first_insert;
+ bool _M_first_insert;
public:
/**
* @brief The constructor.
*
- * @param _k The number of sequences to merge.
- * @param _comp The comparator to use.
+ * @param __k The number of sequences to merge.
+ * @param __comp The comparator to use.
*/
- LoserTreeBase(unsigned int _k, Comparator _comp)
- : comp(_comp)
+ _LoserTreeBase(unsigned int __k, _Compare __comp)
+ : _M_comp(__comp)
{
- ik = _k;
+ _M_ik = __k;
- // Compute log_2{k} for the Loser Tree
- _M_log_k = __log2(ik - 1) + 1;
+ // Compute log_2{_M_k} for the _Loser Tree
+ _M_log_k = __log2(_M_ik - 1) + 1;
// Next greater power of 2.
- k = 1 << _M_log_k;
- offset = k;
+ _M_k = 1 << _M_log_k;
+ _M_offset = _M_k;
- // Avoid default-constructing losers[].key
- losers = static_cast<Loser*>(::operator new(2 * k * sizeof(Loser)));
- for (unsigned int i = ik - 1; i < k; ++i)
- losers[i + k].sup = true;
+ // Avoid default-constructing _M_losers[]._M_key
+ _M_losers
+ = static_cast<_Loser*>(::operator new(2 * _M_k * sizeof(_Loser)));
+ for (unsigned int __i = _M_ik - 1; __i < _M_k; ++__i)
+ _M_losers[__i + _M_k]._M_sup = true;
- first_insert = true;
+ _M_first_insert = true;
}
/**
* @brief The destructor.
*/
- ~LoserTreeBase()
- { ::operator delete(losers); }
+ ~_LoserTreeBase()
+ { ::operator delete(_M_losers); }
/**
- * @brief Initializes the sequence "source" with the element "key".
+ * @brief Initializes the sequence "_M_source" with the element "_M_key".
*
- * @param key the element to insert
- * @param source index of the source sequence
- * @param sup flag that determines whether the value to insert is an
- * explicit supremum.
+ * @param _M_key the element to insert
+ * @param _M_source __index of the _M_source __sequence
+ * @param _M_sup flag that determines whether the value to insert is an
+ * explicit __supremum.
*/
inline void
- insert_start(const T& key, int source, bool sup)
+ __insert_start(const _Tp& _M_key, int _M_source, bool _M_sup)
{
- unsigned int pos = k + source;
+ unsigned int __pos = _M_k + _M_source;
- if(first_insert)
+ if(_M_first_insert)
{
// Construct all keys, so we can easily deconstruct them.
- for (unsigned int i = 0; i < (2 * k); ++i)
- new(&(losers[i].key)) T(key);
- first_insert = false;
+ for (unsigned int __i = 0; __i < (2 * _M_k); ++__i)
+ new(&(_M_losers[__i]._M_key)) _Tp(_M_key);
+ _M_first_insert = false;
}
else
- new(&(losers[pos].key)) T(key);
+ new(&(_M_losers[__pos]._M_key)) _Tp(_M_key);
- losers[pos].sup = sup;
- losers[pos].source = source;
+ _M_losers[__pos]._M_sup = _M_sup;
+ _M_losers[__pos]._M_source = _M_source;
}
/**
* @return the index of the sequence with the smallest element.
*/
- int get_min_source()
- { return losers[0].source; }
+ int __get_min_source()
+ { return _M_losers[0]._M_source; }
};
/**
- * @brief Stable LoserTree variant.
+ * @brief Stable _LoserTree variant.
*
- * Provides the stable implementations of insert_start, init_winner,
- * init and delete_min_insert.
+ * Provides the stable implementations of insert_start, __init_winner,
+ * __init and __delete_min_insert.
*
* Unstable variant is done using partial specialisation below.
*/
-template<bool stable/* default == true */, typename T, typename Comparator>
-class LoserTree : public LoserTreeBase<T, Comparator>
+template<bool __stable/* default == true */, typename _Tp, typename _Compare>
+class _LoserTree : public _LoserTreeBase<_Tp, _Compare>
{
- typedef LoserTreeBase<T, Comparator> Base;
- using Base::k;
- using Base::losers;
- using Base::first_insert;
+ typedef _LoserTreeBase<_Tp, _Compare> Base;
+ using Base::_M_k;
+ using Base::_M_losers;
+ using Base::_M_first_insert;
public:
- LoserTree(unsigned int _k, Comparator _comp)
- : Base::LoserTreeBase(_k, _comp)
+ _LoserTree(unsigned int __k, _Compare __comp)
+ : Base::_LoserTreeBase(__k, __comp)
{}
unsigned int
- init_winner(unsigned int root)
+ __init_winner(unsigned int __root)
{
- if (root >= k)
+ if (__root >= _M_k)
{
- return root;
+ return __root;
}
else
{
- unsigned int left = init_winner (2 * root);
- unsigned int right = init_winner (2 * root + 1);
- if (losers[right].sup
- || (!losers[left].sup
- && !comp(losers[right].key, losers[left].key)))
+ unsigned int __left = __init_winner (2 * __root);
+ unsigned int __right = __init_winner (2 * __root + 1);
+ if (_M_losers[__right]._M_sup
+ || (!_M_losers[__left]._M_sup
+ && !_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key)))
{
// Left one is less or equal.
- losers[root] = losers[right];
- return left;
+ _M_losers[__root] = _M_losers[__right];
+ return __left;
}
else
{
// Right one is less.
- losers[root] = losers[left];
- return right;
+ _M_losers[__root] = _M_losers[__left];
+ return __right;
}
}
}
- void init()
- { losers[0] = losers[init_winner(1)]; }
+ void __init()
+ { _M_losers[0] = _M_losers[__init_winner(1)]; }
/**
* @brief Delete the smallest element and insert a new element from
@@ -211,808 +212,817 @@ public:
*
* This implementation is stable.
*/
- // Do not pass a const reference since key will be used as local variable.
- void delete_min_insert(T key, bool sup)
+ // Do not pass a const reference since _M_key will be used as local variable.
+ void __delete_min_insert(_Tp _M_key, bool _M_sup)
{
#if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top!
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
- int source = losers[0].source;
- for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
+ int _M_source = _M_losers[0]._M_source;
+ for (unsigned int __pos = (_M_k + _M_source) / 2; __pos > 0; __pos /= 2)
{
- // The smaller one gets promoted, ties are broken by source.
- if ((sup && (!losers[pos].sup || losers[pos].source < source))
- || (!sup && !losers[pos].sup
- && ((comp(losers[pos].key, key))
- || (!comp(key, losers[pos].key)
- && losers[pos].source < source))))
+ // The smaller one gets promoted, ties are broken by _M_source.
+ if ((_M_sup && (!_M_losers[__pos]._M_sup
+ || _M_losers[__pos]._M_source < _M_source))
+ || (!_M_sup && !_M_losers[__pos]._M_sup
+ && ((_M_comp(_M_losers[__pos]._M_key, _M_key))
+ || (!_M_comp(_M_key, _M_losers[__pos]._M_key)
+ && _M_losers[__pos]._M_source < _M_source))))
{
// The other one is smaller.
- std::swap(losers[pos].sup, sup);
- std::swap(losers[pos].source, source);
- std::swap(losers[pos].key, key);
+ std::swap(_M_losers[__pos]._M_sup, _M_sup);
+ std::swap(_M_losers[__pos]._M_source, _M_source);
+ std::swap(_M_losers[__pos]._M_key, _M_key);
}
}
- losers[0].sup = sup;
- losers[0].source = source;
- losers[0].key = key;
+ _M_losers[0]._M_sup = _M_sup;
+ _M_losers[0]._M_source = _M_source;
+ _M_losers[0]._M_key = _M_key;
}
};
/**
- * @brief Unstable LoserTree variant.
+ * @brief Unstable _LoserTree variant.
*
* Stability (non-stable here) is selected with partial specialization.
*/
-template<typename T, typename Comparator>
-class LoserTree</* stable == */false, T, Comparator> :
- public LoserTreeBase<T, Comparator>
+template<typename _Tp, typename _Compare>
+class _LoserTree</* __stable == */false, _Tp, _Compare> :
+ public _LoserTreeBase<_Tp, _Compare>
{
- typedef LoserTreeBase<T, Comparator> Base;
+ typedef _LoserTreeBase<_Tp, _Compare> Base;
using Base::_M_log_k;
- using Base::k;
- using Base::losers;
- using Base::first_insert;
+ using Base::_M_k;
+ using Base::_M_losers;
+ using Base::_M_first_insert;
public:
- LoserTree(unsigned int _k, Comparator _comp)
- : Base::LoserTreeBase(_k, _comp)
+ _LoserTree(unsigned int __k, _Compare __comp)
+ : Base::_LoserTreeBase(__k, __comp)
{}
/**
- * Computes the winner of the competition at position "root".
+ * Computes the winner of the competition at __position "__root".
*
* Called recursively (starting at 0) to build the initial tree.
*
- * @param root index of the "game" to start.
+ * @param __root __index of the "game" to start.
*/
unsigned int
- init_winner (unsigned int root)
+ __init_winner (unsigned int __root)
{
- if (root >= k)
+ if (__root >= _M_k)
{
- return root;
+ return __root;
}
else
{
- unsigned int left = init_winner (2 * root);
- unsigned int right = init_winner (2 * root + 1);
- if (losers[right].sup ||
- (!losers[left].sup
- && !comp(losers[right].key, losers[left].key)))
+ unsigned int __left = __init_winner (2 * __root);
+ unsigned int __right = __init_winner (2 * __root + 1);
+ if (_M_losers[__right]._M_sup
+ || (!_M_losers[__left]._M_sup
+ && !_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key)))
{
// Left one is less or equal.
- losers[root] = losers[right];
- return left;
+ _M_losers[__root] = _M_losers[__right];
+ return __left;
}
else
{
// Right one is less.
- losers[root] = losers[left];
- return right;
+ _M_losers[__root] = _M_losers[__left];
+ return __right;
}
}
}
inline void
- init()
- { losers[0] = losers[init_winner(1)]; }
+ __init()
+ { _M_losers[0] = _M_losers[__init_winner(1)]; }
/**
- * Delete the key smallest element and insert the element key instead.
+ * Delete the _M_key smallest element and insert the element _M_key instead.
*
- * @param key the key to insert
- * @param sup true iff key is an explicitly marked supremum
+ * @param _M_key the _M_key to insert
+ * @param _M_sup true iff _M_key is an explicitly marked supremum
*/
- // Do not pass a const reference since key will be used as local variable.
+ // Do not pass a const reference since _M_key will be used as local variable.
inline void
- delete_min_insert(T key, bool sup)
+ __delete_min_insert(_Tp _M_key, bool _M_sup)
{
#if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top!
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
- int source = losers[0].source;
- for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
+ int _M_source = _M_losers[0]._M_source;
+ for (unsigned int __pos = (_M_k + _M_source) / 2; __pos > 0; __pos /= 2)
{
// The smaller one gets promoted.
- if (sup || (!losers[pos].sup && comp(losers[pos].key, key)))
+ if (_M_sup || (!_M_losers[__pos]._M_sup
+ && _M_comp(_M_losers[__pos]._M_key, _M_key)))
{
// The other one is smaller.
- std::swap(losers[pos].sup, sup);
- std::swap(losers[pos].source, source);
- std::swap(losers[pos].key, key);
+ std::swap(_M_losers[__pos]._M_sup, _M_sup);
+ std::swap(_M_losers[__pos]._M_source, _M_source);
+ std::swap(_M_losers[__pos]._M_key, _M_key);
}
}
- losers[0].sup = sup;
- losers[0].source = source;
- losers[0].key = key;
+ _M_losers[0]._M_sup = _M_sup;
+ _M_losers[0]._M_source = _M_source;
+ _M_losers[0]._M_key = _M_key;
}
};
/**
- * @brief Base class of Loser Tree implementation using pointers.
+ * @brief Base class of _Loser Tree implementation using pointers.
*/
-template<typename T, typename Comparator>
-class LoserTreePointerBase
+template<typename _Tp, typename _Compare>
+class _LoserTreePointerBase
{
protected:
- /** @brief Internal representation of LoserTree elements. */
- struct Loser
+ /** @brief Internal representation of _LoserTree __elements. */
+ struct _Loser
{
- bool sup;
- int source;
- const T* keyp;
+ bool _M_sup;
+ int _M_source;
+ const _Tp* _M_keyp;
};
- unsigned int ik, k, offset;
- Loser* losers;
- Comparator comp;
+ unsigned int _M_ik, _M_k, _M_offset;
+ _Loser* _M_losers;
+ _Compare _M_comp;
public:
- LoserTreePointerBase(unsigned int _k, Comparator _comp = std::less<T>())
- : comp(_comp)
+ _LoserTreePointerBase(unsigned int __k, _Compare __comp = std::less<_Tp>())
+ : _M_comp(__comp)
{
- ik = _k;
+ _M_ik = __k;
// Next greater power of 2.
- k = 1 << (__log2(ik - 1) + 1);
- offset = k;
- losers = new Loser[k * 2];
- for (unsigned int i = ik - 1; i < k; i++)
- losers[i + k].sup = true;
+ _M_k = 1 << (__log2(_M_ik - 1) + 1);
+ _M_offset = _M_k;
+ _M_losers = new _Loser[_M_k * 2];
+ for (unsigned int __i = _M_ik - 1; __i < _M_k; __i++)
+ _M_losers[__i + _M_k]._M_sup = true;
}
- ~LoserTreePointerBase()
- { ::operator delete[](losers); }
+ ~_LoserTreePointerBase()
+ { ::operator delete[](_M_losers); }
- int get_min_source()
- { return losers[0].source; }
+ int __get_min_source()
+ { return _M_losers[0]._M_source; }
- void insert_start(const T& key, int source, bool sup)
+ void __insert_start(const _Tp& _M_key, int _M_source, bool _M_sup)
{
- unsigned int pos = k + source;
+ unsigned int __pos = _M_k + _M_source;
- losers[pos].sup = sup;
- losers[pos].source = source;
- losers[pos].keyp = &key;
+ _M_losers[__pos]._M_sup = _M_sup;
+ _M_losers[__pos]._M_source = _M_source;
+ _M_losers[__pos]._M_keyp = &_M_key;
}
};
/**
- * @brief Stable LoserTree implementation.
+ * @brief Stable _LoserTree implementation.
*
* The unstable variant is implemented using partial instantiation below.
*/
-template<bool stable/* default == true */, typename T, typename Comparator>
-class LoserTreePointer : public LoserTreePointerBase<T, Comparator>
+template<bool __stable/* default == true */, typename _Tp, typename _Compare>
+class _LoserTreePointer : public _LoserTreePointerBase<_Tp, _Compare>
{
- typedef LoserTreePointerBase<T, Comparator> Base;
- using Base::k;
- using Base::losers;
+ typedef _LoserTreePointerBase<_Tp, _Compare> Base;
+ using Base::_M_k;
+ using Base::_M_losers;
public:
- LoserTreePointer(unsigned int _k, Comparator _comp = std::less<T>())
- : Base::LoserTreePointerBase(_k, _comp)
+ _LoserTreePointer(unsigned int __k, _Compare __comp = std::less<_Tp>())
+ : Base::_LoserTreePointerBase(__k, __comp)
{}
unsigned int
- init_winner(unsigned int root)
+ __init_winner(unsigned int __root)
{
- if (root >= k)
+ if (__root >= _M_k)
{
- return root;
+ return __root;
}
else
{
- unsigned int left = init_winner (2 * root);
- unsigned int right = init_winner (2 * root + 1);
- if (losers[right].sup
- || (!losers[left].sup && !comp(*losers[right].keyp,
- *losers[left].keyp)))
+ unsigned int __left = __init_winner (2 * __root);
+ unsigned int __right = __init_winner (2 * __root + 1);
+ if (_M_losers[__right]._M_sup
+ || (!_M_losers[__left]._M_sup
+ && !_M_comp(*_M_losers[__right]._M_keyp,
+ *_M_losers[__left]._M_keyp)))
{
// Left one is less or equal.
- losers[root] = losers[right];
- return left;
+ _M_losers[__root] = _M_losers[__right];
+ return __left;
}
else
{
// Right one is less.
- losers[root] = losers[left];
- return right;
+ _M_losers[__root] = _M_losers[__left];
+ return __right;
}
}
}
- void init()
- { losers[0] = losers[init_winner(1)]; }
+ void __init()
+ { _M_losers[0] = _M_losers[__init_winner(1)]; }
- void delete_min_insert(const T& key, bool sup)
+ void __delete_min_insert(const _Tp& _M_key, bool _M_sup)
{
#if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top!
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
- const T* keyp = &key;
- int source = losers[0].source;
- for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
+ const _Tp* _M_keyp = &_M_key;
+ int _M_source = _M_losers[0]._M_source;
+ for (unsigned int __pos = (_M_k + _M_source) / 2; __pos > 0; __pos /= 2)
{
- // The smaller one gets promoted, ties are broken by source.
- if ((sup && (!losers[pos].sup || losers[pos].source < source)) ||
- (!sup && !losers[pos].sup &&
- ((comp(*losers[pos].keyp, *keyp)) ||
- (!comp(*keyp, *losers[pos].keyp)
- && losers[pos].source < source))))
+ // The smaller one gets promoted, ties are broken by _M_source.
+ if ((_M_sup && (!_M_losers[__pos]._M_sup ||
+ _M_losers[__pos]._M_source < _M_source)) ||
+ (!_M_sup && !_M_losers[__pos]._M_sup &&
+ ((_M_comp(*_M_losers[__pos]._M_keyp, *_M_keyp)) ||
+ (!_M_comp(*_M_keyp, *_M_losers[__pos]._M_keyp)
+ && _M_losers[__pos]._M_source < _M_source))))
{
// The other one is smaller.
- std::swap(losers[pos].sup, sup);
- std::swap(losers[pos].source, source);
- std::swap(losers[pos].keyp, keyp);
+ std::swap(_M_losers[__pos]._M_sup, _M_sup);
+ std::swap(_M_losers[__pos]._M_source, _M_source);
+ std::swap(_M_losers[__pos]._M_keyp, _M_keyp);
}
}
- losers[0].sup = sup;
- losers[0].source = source;
- losers[0].keyp = keyp;
+ _M_losers[0]._M_sup = _M_sup;
+ _M_losers[0]._M_source = _M_source;
+ _M_losers[0]._M_keyp = _M_keyp;
}
};
/**
- * @brief Unstable LoserTree implementation.
+ * @brief Unstable _LoserTree implementation.
*
* The stable variant is above.
*/
-template<typename T, typename Comparator>
-class LoserTreePointer</* stable == */false, T, Comparator> :
- public LoserTreePointerBase<T, Comparator>
+template<typename _Tp, typename _Compare>
+class _LoserTreePointer</* __stable == */false, _Tp, _Compare> :
+ public _LoserTreePointerBase<_Tp, _Compare>
{
- typedef LoserTreePointerBase<T, Comparator> Base;
- using Base::k;
- using Base::losers;
+ typedef _LoserTreePointerBase<_Tp, _Compare> Base;
+ using Base::_M_k;
+ using Base::_M_losers;
public:
- LoserTreePointer(unsigned int _k, Comparator _comp = std::less<T>())
- : Base::LoserTreePointerBase(_k, _comp)
+ _LoserTreePointer(unsigned int __k, _Compare __comp = std::less<_Tp>())
+ : Base::_LoserTreePointerBase(__k, __comp)
{}
unsigned int
- init_winner(unsigned int root)
+ __init_winner(unsigned int __root)
{
- if (root >= k)
+ if (__root >= _M_k)
{
- return root;
+ return __root;
}
else
{
- unsigned int left = init_winner (2 * root);
- unsigned int right = init_winner (2 * root + 1);
- if (losers[right].sup
- || (!losers[left].sup
- && !comp(*losers[right].keyp, *losers[left].keyp)))
+ unsigned int __left = __init_winner (2 * __root);
+ unsigned int __right = __init_winner (2 * __root + 1);
+ if (_M_losers[__right]._M_sup
+ || (!_M_losers[__left]._M_sup
+ && !_M_comp(*_M_losers[__right]._M_keyp,
+ *_M_losers[__left]._M_keyp)))
{
// Left one is less or equal.
- losers[root] = losers[right];
- return left;
+ _M_losers[__root] = _M_losers[__right];
+ return __left;
}
else
{
// Right one is less.
- losers[root] = losers[left];
- return right;
+ _M_losers[__root] = _M_losers[__left];
+ return __right;
}
}
}
- void init()
- { losers[0] = losers[init_winner(1)]; }
+ void __init()
+ { _M_losers[0] = _M_losers[__init_winner(1)]; }
- void delete_min_insert(const T& key, bool sup)
+ void __delete_min_insert(const _Tp& _M_key, bool _M_sup)
{
#if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top!
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
- const T* keyp = &key;
- int source = losers[0].source;
- for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
+ const _Tp* _M_keyp = &_M_key;
+ int _M_source = _M_losers[0]._M_source;
+ for (unsigned int __pos = (_M_k + _M_source) / 2; __pos > 0; __pos /= 2)
{
// The smaller one gets promoted.
- if (sup || (!losers[pos].sup && comp(*losers[pos].keyp, *keyp)))
+ if (_M_sup || (!_M_losers[__pos]._M_sup
+ && _M_comp(*_M_losers[__pos]._M_keyp, *_M_keyp)))
{
// The other one is smaller.
- std::swap(losers[pos].sup, sup);
- std::swap(losers[pos].source, source);
- std::swap(losers[pos].keyp, keyp);
+ std::swap(_M_losers[__pos]._M_sup, _M_sup);
+ std::swap(_M_losers[__pos]._M_source, _M_source);
+ std::swap(_M_losers[__pos]._M_keyp, _M_keyp);
}
}
- losers[0].sup = sup;
- losers[0].source = source;
- losers[0].keyp = keyp;
+ _M_losers[0]._M_sup = _M_sup;
+ _M_losers[0]._M_source = _M_source;
+ _M_losers[0]._M_keyp = _M_keyp;
}
};
-/** @brief Base class for unguarded LoserTree implementation.
+/** @brief Base class for unguarded _LoserTree implementation.
*
* The whole element is copied into the tree structure.
*
* No guarding is done, therefore not a single input sequence must
- * run empty. Unused sequence heads are marked with a sentinel which
+ * run empty. Unused __sequence heads are marked with a sentinel which
* is &gt; all elements that are to be merged.
*
* This is a very fast variant.
*/
-template<typename T, typename Comparator>
-class LoserTreeUnguardedBase
+template<typename _Tp, typename _Compare>
+class _LoserTreeUnguardedBase
{
protected:
- struct Loser
+ struct _Loser
{
- int source;
- T key;
+ int _M_source;
+ _Tp _M_key;
};
- unsigned int ik, k, offset;
- Loser* losers;
- Comparator comp;
+ unsigned int _M_ik, _M_k, _M_offset;
+ _Loser* _M_losers;
+ _Compare _M_comp;
public:
inline
- LoserTreeUnguardedBase(unsigned int _k, const T _sentinel,
- Comparator _comp = std::less<T>())
- : comp(_comp)
+ _LoserTreeUnguardedBase(unsigned int __k, const _Tp _sentinel,
+ _Compare __comp = std::less<_Tp>())
+ : _M_comp(__comp)
{
- ik = _k;
+ _M_ik = __k;
// Next greater power of 2.
- k = 1 << (__log2(ik - 1) + 1);
- offset = k;
- // Avoid default-constructing losers[].key
- losers = static_cast<Loser*>(::operator new(2 * k * sizeof(Loser)));
+ _M_k = 1 << (__log2(_M_ik - 1) + 1);
+ _M_offset = _M_k;
+ // Avoid default-constructing _M_losers[]._M_key
+ _M_losers
+ = static_cast<_Loser*>(::operator new(2 * _M_k * sizeof(_Loser)));
- for (unsigned int i = k + ik - 1; i < (2 * k); ++i)
+ for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i)
{
- losers[i].key = _sentinel;
- losers[i].source = -1;
+ _M_losers[__i]._M_key = _sentinel;
+ _M_losers[__i]._M_source = -1;
}
}
- inline ~LoserTreeUnguardedBase()
- { ::operator delete(losers); }
+ inline ~_LoserTreeUnguardedBase()
+ { ::operator delete(_M_losers); }
inline int
- get_min_source()
+ __get_min_source()
{
#if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top!
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
- return losers[0].source;
+ return _M_losers[0]._M_source;
}
inline void
- insert_start(const T& key, int source, bool)
+ __insert_start(const _Tp& _M_key, int _M_source, bool)
{
- unsigned int pos = k + source;
+ unsigned int __pos = _M_k + _M_source;
- new(&(losers[pos].key)) T(key);
- losers[pos].source = source;
+ new(&(_M_losers[__pos]._M_key)) _Tp(_M_key);
+ _M_losers[__pos]._M_source = _M_source;
}
};
/**
- * @brief Stable implementation of unguarded LoserTree.
+ * @brief Stable implementation of unguarded _LoserTree.
*
* Unstable variant is selected below with partial specialization.
*/
-template<bool stable/* default == true */, typename T, typename Comparator>
-class LoserTreeUnguarded : public LoserTreeUnguardedBase<T, Comparator>
+template<bool __stable/* default == true */, typename _Tp, typename _Compare>
+class _LoserTreeUnguarded : public _LoserTreeUnguardedBase<_Tp, _Compare>
{
- typedef LoserTreeUnguardedBase<T, Comparator> Base;
- using Base::k;
- using Base::losers;
+ typedef _LoserTreeUnguardedBase<_Tp, _Compare> Base;
+ using Base::_M_k;
+ using Base::_M_losers;
public:
- LoserTreeUnguarded(unsigned int _k, const T _sentinel,
- Comparator _comp = std::less<T>())
- : Base::LoserTreeUnguardedBase(_k, _sentinel, _comp)
+ _LoserTreeUnguarded(unsigned int __k, const _Tp _sentinel,
+ _Compare __comp = std::less<_Tp>())
+ : Base::_LoserTreeUnguardedBase(__k, _sentinel, __comp)
{}
unsigned int
- init_winner(unsigned int root)
+ __init_winner(unsigned int __root)
{
- if (root >= k)
+ if (__root >= _M_k)
{
- return root;
+ return __root;
}
else
{
- unsigned int left = init_winner (2 * root);
- unsigned int right = init_winner (2 * root + 1);
- if (!comp(losers[right].key, losers[left].key))
+ unsigned int __left = __init_winner (2 * __root);
+ unsigned int __right = __init_winner (2 * __root + 1);
+ if (!_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key))
{
// Left one is less or equal.
- losers[root] = losers[right];
- return left;
+ _M_losers[__root] = _M_losers[__right];
+ return __left;
}
else
{
// Right one is less.
- losers[root] = losers[left];
- return right;
+ _M_losers[__root] = _M_losers[__left];
+ return __right;
}
}
}
inline void
- init()
+ __init()
{
- losers[0] = losers[init_winner(1)];
+ _M_losers[0] = _M_losers[__init_winner(1)];
#if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top at the beginning (0 sequences!)
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
}
- // Do not pass a const reference since key will be used as local variable.
+ // Do not pass a const reference since _M_key will be used as local variable.
inline void
- delete_min_insert(T key, bool)
+ __delete_min_insert(_Tp _M_key, bool)
{
#if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top!
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
- int source = losers[0].source;
- for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
+ int _M_source = _M_losers[0]._M_source;
+ for (unsigned int __pos = (_M_k + _M_source) / 2; __pos > 0; __pos /= 2)
{
- // The smaller one gets promoted, ties are broken by source.
- if (comp(losers[pos].key, key)
- || (!comp(key, losers[pos].key) && losers[pos].source < source))
+ // The smaller one gets promoted, ties are broken by _M_source.
+ if (_M_comp(_M_losers[__pos]._M_key, _M_key)
+ || (!_M_comp(_M_key, _M_losers[__pos]._M_key)
+ && _M_losers[__pos]._M_source < _M_source))
{
// The other one is smaller.
- std::swap(losers[pos].source, source);
- std::swap(losers[pos].key, key);
+ std::swap(_M_losers[__pos]._M_source, _M_source);
+ std::swap(_M_losers[__pos]._M_key, _M_key);
}
}
- losers[0].source = source;
- losers[0].key = key;
+ _M_losers[0]._M_source = _M_source;
+ _M_losers[0]._M_key = _M_key;
}
};
/**
- * @brief Non-Stable implementation of unguarded LoserTree.
+ * @brief Non-Stable implementation of unguarded _LoserTree.
*
* Stable implementation is above.
*/
-template<typename T, typename Comparator>
-class LoserTreeUnguarded</* stable == */false, T, Comparator> :
- public LoserTreeUnguardedBase<T, Comparator>
+template<typename _Tp, typename _Compare>
+class _LoserTreeUnguarded</* __stable == */false, _Tp, _Compare> :
+ public _LoserTreeUnguardedBase<_Tp, _Compare>
{
- typedef LoserTreeUnguardedBase<T, Comparator> Base;
- using Base::k;
- using Base::losers;
+ typedef _LoserTreeUnguardedBase<_Tp, _Compare> Base;
+ using Base::_M_k;
+ using Base::_M_losers;
public:
- LoserTreeUnguarded(unsigned int _k, const T _sentinel,
- Comparator _comp = std::less<T>())
- : Base::LoserTreeUnguardedBase(_k, _sentinel, _comp)
+ _LoserTreeUnguarded(unsigned int __k, const _Tp _sentinel,
+ _Compare __comp = std::less<_Tp>())
+ : Base::_LoserTreeUnguardedBase(__k, _sentinel, __comp)
{}
unsigned int
- init_winner (unsigned int root)
+ __init_winner (unsigned int __root)
{
- if (root >= k)
+ if (__root >= _M_k)
{
- return root;
+ return __root;
}
else
{
- unsigned int left = init_winner (2 * root);
- unsigned int right = init_winner (2 * root + 1);
+ unsigned int __left = __init_winner (2 * __root);
+ unsigned int __right = __init_winner (2 * __root + 1);
#if _GLIBCXX_ASSERTIONS
- // If left one is sentinel then right one must be, too.
- if (losers[left].source == -1)
- _GLIBCXX_PARALLEL_ASSERT(losers[right].source == -1);
+ // If __left one is sentinel then __right one must be, too.
+ if (_M_losers[__left]._M_source == -1)
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[__right]._M_source == -1);
#endif
- if (!comp(losers[right].key, losers[left].key))
+ if (!_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key))
{
// Left one is less or equal.
- losers[root] = losers[right];
- return left;
+ _M_losers[__root] = _M_losers[__right];
+ return __left;
}
else
{
// Right one is less.
- losers[root] = losers[left];
- return right;
+ _M_losers[__root] = _M_losers[__left];
+ return __right;
}
}
}
inline void
- init()
+ __init()
{
- losers[0] = losers[init_winner(1)];
+ _M_losers[0] = _M_losers[__init_winner(1)];
#if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top at the beginning (0 sequences!)
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
}
- // Do not pass a const reference since key will be used as local variable.
+ // Do not pass a const reference since _M_key will be used as local variable.
inline void
- delete_min_insert(T key, bool)
+ __delete_min_insert(_Tp _M_key, bool)
{
#if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top!
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
- int source = losers[0].source;
- for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
+ int _M_source = _M_losers[0]._M_source;
+ for (unsigned int __pos = (_M_k + _M_source) / 2; __pos > 0; __pos /= 2)
{
// The smaller one gets promoted.
- if (comp(losers[pos].key, key))
+ if (_M_comp(_M_losers[__pos]._M_key, _M_key))
{
// The other one is smaller.
- std::swap(losers[pos].source, source);
- std::swap(losers[pos].key, key);
+ std::swap(_M_losers[__pos]._M_source, _M_source);
+ std::swap(_M_losers[__pos]._M_key, _M_key);
}
}
- losers[0].source = source;
- losers[0].key = key;
+ _M_losers[0]._M_source = _M_source;
+ _M_losers[0]._M_key = _M_key;
}
};
/** @brief Unguarded loser tree, keeping only pointers to the
-* elements in the tree structure.
+* __elements in the tree structure.
*
* No guarding is done, therefore not a single input sequence must
* run empty. This is a very fast variant.
*/
-template<typename T, typename Comparator>
+template<typename _Tp, typename _Compare>
class LoserTreePointerUnguardedBase
{
protected:
- struct Loser
+ struct _Loser
{
- int source;
- const T* keyp;
+ int _M_source;
+ const _Tp* _M_keyp;
};
- unsigned int ik, k, offset;
- Loser* losers;
- Comparator comp;
+ unsigned int _M_ik, _M_k, _M_offset;
+ _Loser* _M_losers;
+ _Compare _M_comp;
public:
inline
- LoserTreePointerUnguardedBase(unsigned int _k, const T& _sentinel,
- Comparator _comp = std::less<T>())
- : comp(_comp)
+ LoserTreePointerUnguardedBase(unsigned int __k, const _Tp& _sentinel,
+ _Compare __comp = std::less<_Tp>())
+ : _M_comp(__comp)
{
- ik = _k;
+ _M_ik = __k;
// Next greater power of 2.
- k = 1 << (__log2(ik - 1) + 1);
- offset = k;
- // Avoid default-constructing losers[].key
- losers = new Loser[2 * k];
+ _M_k = 1 << (__log2(_M_ik - 1) + 1);
+ _M_offset = _M_k;
+ // Avoid default-constructing _M_losers[]._M_key
+ _M_losers = new _Loser[2 * _M_k];
- for (unsigned int i = k + ik - 1; i < (2 * k); ++i)
+ for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i)
{
- losers[i].keyp = &_sentinel;
- losers[i].source = -1;
+ _M_losers[__i]._M_keyp = &_sentinel;
+ _M_losers[__i]._M_source = -1;
}
}
inline ~LoserTreePointerUnguardedBase()
- { delete[] losers; }
+ { delete[] _M_losers; }
inline int
- get_min_source()
+ __get_min_source()
{
#if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top!
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
- return losers[0].source;
+ return _M_losers[0]._M_source;
}
inline void
- insert_start(const T& key, int source, bool)
+ __insert_start(const _Tp& _M_key, int _M_source, bool)
{
- unsigned int pos = k + source;
+ unsigned int __pos = _M_k + _M_source;
- losers[pos].keyp = &key;
- losers[pos].source = source;
+ _M_losers[__pos]._M_keyp = &_M_key;
+ _M_losers[__pos]._M_source = _M_source;
}
};
/**
- * @brief Stable unguarded LoserTree variant storing pointers.
+ * @brief Stable unguarded _LoserTree variant storing pointers.
*
* Unstable variant is implemented below using partial specialization.
*/
-template<bool stable/* default == true */, typename T, typename Comparator>
+template<bool __stable/* default == true */, typename _Tp, typename _Compare>
class LoserTreePointerUnguarded :
- public LoserTreePointerUnguardedBase<T, Comparator>
+ public LoserTreePointerUnguardedBase<_Tp, _Compare>
{
- typedef LoserTreePointerUnguardedBase<T, Comparator> Base;
- using Base::k;
- using Base::losers;
+ typedef LoserTreePointerUnguardedBase<_Tp, _Compare> Base;
+ using Base::_M_k;
+ using Base::_M_losers;
public:
- LoserTreePointerUnguarded(unsigned int _k, const T& _sentinel,
- Comparator _comp = std::less<T>())
- : Base::LoserTreePointerUnguardedBase(_k, _sentinel, _comp)
+ LoserTreePointerUnguarded(unsigned int __k, const _Tp& _sentinel,
+ _Compare __comp = std::less<_Tp>())
+ : Base::LoserTreePointerUnguardedBase(__k, _sentinel, __comp)
{}
unsigned int
- init_winner(unsigned int root)
+ __init_winner(unsigned int __root)
{
- if (root >= k)
+ if (__root >= _M_k)
{
- return root;
+ return __root;
}
else
{
- unsigned int left = init_winner (2 * root);
- unsigned int right = init_winner (2 * root + 1);
- if (!comp(*losers[right].keyp, *losers[left].keyp))
+ unsigned int __left = __init_winner (2 * __root);
+ unsigned int __right = __init_winner (2 * __root + 1);
+ if (!_M_comp(*_M_losers[__right]._M_keyp, *_M_losers[__left]._M_keyp))
{
// Left one is less or equal.
- losers[root] = losers[right];
- return left;
+ _M_losers[__root] = _M_losers[__right];
+ return __left;
}
else
{
// Right one is less.
- losers[root] = losers[left];
- return right;
+ _M_losers[__root] = _M_losers[__left];
+ return __right;
}
}
}
inline void
- init()
+ __init()
{
- losers[0] = losers[init_winner(1)];
+ _M_losers[0] = _M_losers[__init_winner(1)];
#if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top at the beginning (0 sequences!)
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
}
inline void
- delete_min_insert(const T& key, bool sup)
+ __delete_min_insert(const _Tp& _M_key, bool _M_sup)
{
#if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top!
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
- const T* keyp = &key;
- int source = losers[0].source;
- for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
+ const _Tp* _M_keyp = &_M_key;
+ int _M_source = _M_losers[0]._M_source;
+ for (unsigned int __pos = (_M_k + _M_source) / 2; __pos > 0; __pos /= 2)
{
- // The smaller one gets promoted, ties are broken by source.
- if (comp(*losers[pos].keyp, *keyp)
- || (!comp(*keyp, *losers[pos].keyp) && losers[pos].source < source))
+ // The smaller one gets promoted, ties are broken by _M_source.
+ if (_M_comp(*_M_losers[__pos]._M_keyp, *_M_keyp)
+ || (!_M_comp(*_M_keyp, *_M_losers[__pos]._M_keyp)
+ && _M_losers[__pos]._M_source < _M_source))
{
// The other one is smaller.
- std::swap(losers[pos].source, source);
- std::swap(losers[pos].keyp, keyp);
+ std::swap(_M_losers[__pos]._M_source, _M_source);
+ std::swap(_M_losers[__pos]._M_keyp, _M_keyp);
}
}
- losers[0].source = source;
- losers[0].keyp = keyp;
+ _M_losers[0]._M_source = _M_source;
+ _M_losers[0]._M_keyp = _M_keyp;
}
};
/**
- * @brief Unstable unguarded LoserTree variant storing pointers.
+ * @brief Unstable unguarded _LoserTree variant storing pointers.
*
* Stable variant is above.
*/
-template<typename T, typename Comparator>
-class LoserTreePointerUnguarded</* stable == */false, T, Comparator> :
- public LoserTreePointerUnguardedBase<T, Comparator>
+template<typename _Tp, typename _Compare>
+class LoserTreePointerUnguarded</* __stable == */false, _Tp, _Compare> :
+ public LoserTreePointerUnguardedBase<_Tp, _Compare>
{
- typedef LoserTreePointerUnguardedBase<T, Comparator> Base;
- using Base::k;
- using Base::losers;
+ typedef LoserTreePointerUnguardedBase<_Tp, _Compare> Base;
+ using Base::_M_k;
+ using Base::_M_losers;
public:
- LoserTreePointerUnguarded(unsigned int _k, const T& _sentinel,
- Comparator _comp = std::less<T>())
- : Base::LoserTreePointerUnguardedBase(_k, _sentinel, _comp)
+ LoserTreePointerUnguarded(unsigned int __k, const _Tp& _sentinel,
+ _Compare __comp = std::less<_Tp>())
+ : Base::LoserTreePointerUnguardedBase(__k, _sentinel, __comp)
{}
unsigned int
- init_winner(unsigned int root)
+ __init_winner(unsigned int __root)
{
- if (root >= k)
+ if (__root >= _M_k)
{
- return root;
+ return __root;
}
else
{
- unsigned int left = init_winner (2 * root);
- unsigned int right = init_winner (2 * root + 1);
+ unsigned int __left = __init_winner (2 * __root);
+ unsigned int __right = __init_winner (2 * __root + 1);
#if _GLIBCXX_ASSERTIONS
- // If left one is sentinel then right one must be, too.
- if (losers[left].source == -1)
- _GLIBCXX_PARALLEL_ASSERT(losers[right].source == -1);
+ // If __left one is sentinel then __right one must be, too.
+ if (_M_losers[__left]._M_source == -1)
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[__right]._M_source == -1);
#endif
- if (!comp(*losers[right].keyp, *losers[left].keyp))
+ if (!_M_comp(*_M_losers[__right]._M_keyp, *_M_losers[__left]._M_keyp))
{
// Left one is less or equal.
- losers[root] = losers[right];
- return left;
+ _M_losers[__root] = _M_losers[__right];
+ return __left;
}
else
{
// Right one is less.
- losers[root] = losers[left];
- return right;
+ _M_losers[__root] = _M_losers[__left];
+ return __right;
}
}
}
inline void
- init()
+ __init()
{
- losers[0] = losers[init_winner(1)];
+ _M_losers[0] = _M_losers[__init_winner(1)];
#if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top at the beginning (0 sequences!)
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
}
inline void
- delete_min_insert(const T& key, bool sup)
+ __delete_min_insert(const _Tp& _M_key, bool _M_sup)
{
#if _GLIBCXX_ASSERTIONS
// no dummy sequence can ever be at the top!
- _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
+ _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
- const T* keyp = &key;
- int source = losers[0].source;
- for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
+ const _Tp* _M_keyp = &_M_key;
+ int _M_source = _M_losers[0]._M_source;
+ for (unsigned int __pos = (_M_k + _M_source) / 2; __pos > 0; __pos /= 2)
{
// The smaller one gets promoted.
- if (comp(*(losers[pos].keyp), *keyp))
+ if (_M_comp(*(_M_losers[__pos]._M_keyp), *_M_keyp))
{
// The other one is smaller.
- std::swap(losers[pos].source, source);
- std::swap(losers[pos].keyp, keyp);
+ std::swap(_M_losers[__pos]._M_source, _M_source);
+ std::swap(_M_losers[__pos]._M_keyp, _M_keyp);
}
}
- losers[0].source = source;
- losers[0].keyp = keyp;
+ _M_losers[0]._M_source = _M_source;
+ _M_losers[0]._M_keyp = _M_keyp;
}
};
diff --git a/libstdc++-v3/include/parallel/merge.h b/libstdc++-v3/include/parallel/merge.h
index d947e258aa8..b2d8996ae5a 100644
--- a/libstdc++-v3/include/parallel/merge.h
+++ b/libstdc++-v3/include/parallel/merge.h
@@ -37,225 +37,225 @@
namespace __gnu_parallel
{
- /** @brief Merge routine being able to merge only the @c max_length
+ /** @brief Merge routine being able to merge only the @__c __max_length
* smallest elements.
*
- * The @c begin iterators are advanced accordingly, they might not
- * reach @c end, in contrast to the usual variant.
- * @param begin1 Begin iterator of first sequence.
- * @param end1 End iterator of first sequence.
- * @param begin2 Begin iterator of second sequence.
- * @param end2 End iterator of second sequence.
- * @param target Target begin iterator.
- * @param max_length Maximum number of elements to merge.
- * @param comp Comparator.
+ * The @__c __begin iterators are advanced accordingly, they might not
+ * reach @__c __end, in contrast to the usual variant.
+ * @param __begin1 Begin iterator of first sequence.
+ * @param __end1 End iterator of first sequence.
+ * @param __begin2 Begin iterator of second sequence.
+ * @param __end2 End iterator of second sequence.
+ * @param __target Target begin iterator.
+ * @param __max_length Maximum number of elements to merge.
+ * @param __comp Comparator.
* @return Output end iterator. */
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename OutputIterator, typename _DifferenceTp,
- typename Comparator>
- OutputIterator
- merge_advance_usual(RandomAccessIterator1& begin1,
- RandomAccessIterator1 end1,
- RandomAccessIterator2& begin2,
- RandomAccessIterator2 end2, OutputIterator target,
- _DifferenceTp max_length, Comparator comp)
+ template<typename _RAIter1, typename _RAIter2,
+ typename _OutputIterator, typename _DifferenceTp,
+ typename _Compare>
+ _OutputIterator
+ __merge_advance_usual(_RAIter1& __begin1,
+ _RAIter1 __end1,
+ _RAIter2& __begin2,
+ _RAIter2 __end2, _OutputIterator __target,
+ _DifferenceTp __max_length, _Compare __comp)
{
- typedef _DifferenceTp difference_type;
- while (begin1 != end1 && begin2 != end2 && max_length > 0)
- {
- // array1[i1] < array0[i0]
- if (comp(*begin2, *begin1))
- *target++ = *begin2++;
- else
- *target++ = *begin1++;
- --max_length;
- }
+ typedef _DifferenceTp _DifferenceType;
+ while (__begin1 != __end1 && __begin2 != __end2 && __max_length > 0)
+ {
+ // array1[__i1] < array0[i0]
+ if (__comp(*__begin2, *__begin1))
+ *__target++ = *__begin2++;
+ else
+ *__target++ = *__begin1++;
+ --__max_length;
+ }
- if (begin1 != end1)
- {
- target = std::copy(begin1, begin1 + max_length, target);
- begin1 += max_length;
- }
+ if (__begin1 != __end1)
+ {
+ __target = std::copy(__begin1, __begin1 + __max_length, __target);
+ __begin1 += __max_length;
+ }
else
- {
- target = std::copy(begin2, begin2 + max_length, target);
- begin2 += max_length;
- }
- return target;
+ {
+ __target = std::copy(__begin2, __begin2 + __max_length, __target);
+ __begin2 += __max_length;
+ }
+ return __target;
}
- /** @brief Merge routine being able to merge only the @c max_length
+ /** @brief Merge routine being able to merge only the @__c __max_length
* smallest elements.
*
- * The @c begin iterators are advanced accordingly, they might not
- * reach @c end, in contrast to the usual variant.
+ * The @__c __begin iterators are advanced accordingly, they might not
+ * reach @__c __end, in contrast to the usual variant.
* Specially designed code should allow the compiler to generate
* conditional moves instead of branches.
- * @param begin1 Begin iterator of first sequence.
- * @param end1 End iterator of first sequence.
- * @param begin2 Begin iterator of second sequence.
- * @param end2 End iterator of second sequence.
- * @param target Target begin iterator.
- * @param max_length Maximum number of elements to merge.
- * @param comp Comparator.
+ * @param __begin1 Begin iterator of first sequence.
+ * @param __end1 End iterator of first sequence.
+ * @param __begin2 Begin iterator of second sequence.
+ * @param __end2 End iterator of second sequence.
+ * @param __target Target begin iterator.
+ * @param __max_length Maximum number of elements to merge.
+ * @param __comp Comparator.
* @return Output end iterator. */
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename OutputIterator, typename _DifferenceTp,
- typename Comparator>
- OutputIterator
- merge_advance_movc(RandomAccessIterator1& begin1,
- RandomAccessIterator1 end1,
- RandomAccessIterator2& begin2,
- RandomAccessIterator2 end2,
- OutputIterator target,
- _DifferenceTp max_length, Comparator comp)
+ template<typename _RAIter1, typename _RAIter2,
+ typename _OutputIterator, typename _DifferenceTp,
+ typename _Compare>
+ _OutputIterator
+ __merge_advance_movc(_RAIter1& __begin1,
+ _RAIter1 __end1,
+ _RAIter2& __begin2,
+ _RAIter2 __end2,
+ _OutputIterator __target,
+ _DifferenceTp __max_length, _Compare __comp)
{
- typedef _DifferenceTp difference_type;
- typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
- value_type1;
- typedef typename std::iterator_traits<RandomAccessIterator2>::value_type
- value_type2;
+ typedef _DifferenceTp _DifferenceType;
+ typedef typename std::iterator_traits<_RAIter1>::value_type
+ value_type1;
+ typedef typename std::iterator_traits<_RAIter2>::value_type
+ value_type2;
#if _GLIBCXX_ASSERTIONS
- _GLIBCXX_PARALLEL_ASSERT(max_length >= 0);
+ _GLIBCXX_PARALLEL_ASSERT(__max_length >= 0);
#endif
- while (begin1 != end1 && begin2 != end2 && max_length > 0)
- {
- RandomAccessIterator1 next1 = begin1 + 1;
- RandomAccessIterator2 next2 = begin2 + 1;
- value_type1 element1 = *begin1;
- value_type2 element2 = *begin2;
+ while (__begin1 != __end1 && __begin2 != __end2 && __max_length > 0)
+ {
+ _RAIter1 __next1 = __begin1 + 1;
+ _RAIter2 __next2 = __begin2 + 1;
+ value_type1 __element1 = *__begin1;
+ value_type2 __element2 = *__begin2;
- if (comp(element2, element1))
- {
- element1 = element2;
- begin2 = next2;
- }
- else
- begin1 = next1;
+ if (__comp(__element2, __element1))
+ {
+ __element1 = __element2;
+ __begin2 = __next2;
+ }
+ else
+ __begin1 = __next1;
- *target = element1;
+ *__target = __element1;
- ++target;
- --max_length;
- }
- if (begin1 != end1)
- {
- target = std::copy(begin1, begin1 + max_length, target);
- begin1 += max_length;
- }
+ ++__target;
+ --__max_length;
+ }
+ if (__begin1 != __end1)
+ {
+ __target = std::copy(__begin1, __begin1 + __max_length, __target);
+ __begin1 += __max_length;
+ }
else
- {
- target = std::copy(begin2, begin2 + max_length, target);
- begin2 += max_length;
- }
- return target;
+ {
+ __target = std::copy(__begin2, __begin2 + __max_length, __target);
+ __begin2 += __max_length;
+ }
+ return __target;
}
- /** @brief Merge routine being able to merge only the @c max_length
+ /** @brief Merge routine being able to merge only the @__c __max_length
* smallest elements.
*
- * The @c begin iterators are advanced accordingly, they might not
- * reach @c end, in contrast to the usual variant.
+ * The @__c __begin iterators are advanced accordingly, they might not
+ * reach @__c __end, in contrast to the usual variant.
* Static switch on whether to use the conditional-move variant.
- * @param begin1 Begin iterator of first sequence.
- * @param end1 End iterator of first sequence.
- * @param begin2 Begin iterator of second sequence.
- * @param end2 End iterator of second sequence.
- * @param target Target begin iterator.
- * @param max_length Maximum number of elements to merge.
- * @param comp Comparator.
+ * @param __begin1 Begin iterator of first sequence.
+ * @param __end1 End iterator of first sequence.
+ * @param __begin2 Begin iterator of second sequence.
+ * @param __end2 End iterator of second sequence.
+ * @param __target Target begin iterator.
+ * @param __max_length Maximum number of elements to merge.
+ * @param __comp Comparator.
* @return Output end iterator. */
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename OutputIterator, typename _DifferenceTp,
- typename Comparator>
- inline OutputIterator
- merge_advance(RandomAccessIterator1& begin1, RandomAccessIterator1 end1,
- RandomAccessIterator2& begin2, RandomAccessIterator2 end2,
- OutputIterator target, _DifferenceTp max_length,
- Comparator comp)
+ template<typename _RAIter1, typename _RAIter2,
+ typename _OutputIterator, typename _DifferenceTp,
+ typename _Compare>
+ inline _OutputIterator
+ __merge_advance(_RAIter1& __begin1, _RAIter1 __end1,
+ _RAIter2& __begin2, _RAIter2 __end2,
+ _OutputIterator __target, _DifferenceTp __max_length,
+ _Compare __comp)
{
- _GLIBCXX_CALL(max_length)
+ _GLIBCXX_CALL(__max_length)
- return merge_advance_movc(begin1, end1, begin2, end2, target,
- max_length, comp);
+ return __merge_advance_movc(__begin1, __end1, __begin2, __end2, __target,
+ __max_length, __comp);
}
/** @brief Merge routine fallback to sequential in case the
iterators of the two input sequences are of different type.
- * @param begin1 Begin iterator of first sequence.
- * @param end1 End iterator of first sequence.
- * @param begin2 Begin iterator of second sequence.
- * @param end2 End iterator of second sequence.
- * @param target Target begin iterator.
- * @param max_length Maximum number of elements to merge.
- * @param comp Comparator.
+ * @param __begin1 Begin iterator of first sequence.
+ * @param __end1 End iterator of first sequence.
+ * @param __begin2 Begin iterator of second sequence.
+ * @param __end2 End iterator of second sequence.
+ * @param __target Target begin iterator.
+ * @param __max_length Maximum number of elements to merge.
+ * @param __comp Comparator.
* @return Output end iterator. */
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename RandomAccessIterator3, typename Comparator>
- inline RandomAccessIterator3
- parallel_merge_advance(RandomAccessIterator1& begin1,
- RandomAccessIterator1 end1,
- RandomAccessIterator2& begin2,
- // different iterators, parallel implementation
- // not available
- RandomAccessIterator2 end2,
- RandomAccessIterator3 target, typename
- std::iterator_traits<RandomAccessIterator1>::
- difference_type max_length, Comparator comp)
- { return merge_advance(begin1, end1, begin2, end2, target,
- max_length, comp); }
+ template<typename _RAIter1, typename _RAIter2,
+ typename _RAIter3, typename _Compare>
+ inline _RAIter3
+ __parallel_merge_advance(_RAIter1& __begin1,
+ _RAIter1 __end1,
+ _RAIter2& __begin2,
+ // different iterators, parallel implementation
+ // not available
+ _RAIter2 __end2,
+ _RAIter3 __target, typename
+ std::iterator_traits<_RAIter1>::
+ difference_type __max_length, _Compare __comp)
+ { return __merge_advance(__begin1, __end1, __begin2, __end2, __target,
+ __max_length, __comp); }
- /** @brief Parallel merge routine being able to merge only the @c
- * max_length smallest elements.
+ /** @brief Parallel merge routine being able to merge only the @__c
+ * __max_length smallest elements.
*
- * The @c begin iterators are advanced accordingly, they might not
- * reach @c end, in contrast to the usual variant.
+ * The @__c __begin iterators are advanced accordingly, they might not
+ * reach @__c __end, in contrast to the usual variant.
* The functionality is projected onto parallel_multiway_merge.
- * @param begin1 Begin iterator of first sequence.
- * @param end1 End iterator of first sequence.
- * @param begin2 Begin iterator of second sequence.
- * @param end2 End iterator of second sequence.
- * @param target Target begin iterator.
- * @param max_length Maximum number of elements to merge.
- * @param comp Comparator.
+ * @param __begin1 Begin iterator of first sequence.
+ * @param __end1 End iterator of first sequence.
+ * @param __begin2 Begin iterator of second sequence.
+ * @param __end2 End iterator of second sequence.
+ * @param __target Target begin iterator.
+ * @param __max_length Maximum number of elements to merge.
+ * @param __comp Comparator.
* @return Output end iterator.
*/
- template<typename RandomAccessIterator1, typename RandomAccessIterator3,
- typename Comparator>
- inline RandomAccessIterator3
- parallel_merge_advance(RandomAccessIterator1& begin1,
- RandomAccessIterator1 end1,
- RandomAccessIterator1& begin2,
- RandomAccessIterator1 end2,
- RandomAccessIterator3 target, typename
- std::iterator_traits<RandomAccessIterator1>::
- difference_type max_length, Comparator comp)
+ template<typename _RAIter1, typename _RAIter3,
+ typename _Compare>
+ inline _RAIter3
+ __parallel_merge_advance(_RAIter1& __begin1,
+ _RAIter1 __end1,
+ _RAIter1& __begin2,
+ _RAIter1 __end2,
+ _RAIter3 __target, typename
+ std::iterator_traits<_RAIter1>::
+ difference_type __max_length, _Compare __comp)
{
typedef typename
- std::iterator_traits<RandomAccessIterator1>::value_type value_type;
- typedef typename std::iterator_traits<RandomAccessIterator1>::
- difference_type difference_type1 /* == difference_type2 */;
- typedef typename std::iterator_traits<RandomAccessIterator3>::
- difference_type difference_type3;
- typedef typename std::pair<RandomAccessIterator1, RandomAccessIterator1>
- iterator_pair;
+ std::iterator_traits<_RAIter1>::value_type _ValueType;
+ typedef typename std::iterator_traits<_RAIter1>::
+ difference_type _DifferenceType1 /* == difference_type2 */;
+ typedef typename std::iterator_traits<_RAIter3>::
+ difference_type _DifferenceType3;
+ typedef typename std::pair<_RAIter1, _RAIter1>
+ _IteratorPair;
- iterator_pair
- seqs[2] = { std::make_pair(begin1, end1),
- std::make_pair(begin2, end2) };
- RandomAccessIterator3
- target_end = parallel_multiway_merge
- < /* stable = */ true, /* sentinels = */ false>(
- seqs, seqs + 2, target,
+ _IteratorPair
+ seqs[2] = { std::make_pair(__begin1, __end1),
+ std::make_pair(__begin2, __end2) };
+ _RAIter3
+ __target_end = parallel_multiway_merge
+ < /* __stable = */ true, /* __sentinels = */ false>(
+ seqs, seqs + 2, __target,
multiway_merge_exact_splitting
- < /* stable = */ true, iterator_pair*,
- Comparator, difference_type1>,
- max_length, comp, omp_get_max_threads());
+ < /* __stable = */ true, _IteratorPair*,
+ _Compare, _DifferenceType1>,
+ __max_length, __comp, omp_get_max_threads());
- return target_end;
+ return __target_end;
}
-} //namespace __gnu_parallel
+} //namespace __gnu_parallel
#endif /* _GLIBCXX_PARALLEL_MERGE_H */
diff --git a/libstdc++-v3/include/parallel/multiseq_selection.h b/libstdc++-v3/include/parallel/multiseq_selection.h
index 6ef3d22b15c..539695fc766 100644
--- a/libstdc++-v3/include/parallel/multiseq_selection.h
+++ b/libstdc++-v3/include/parallel/multiseq_selection.h
@@ -23,7 +23,7 @@
// <http://www.gnu.org/licenses/>.
/** @file parallel/multiseq_selection.h
- * @brief Functions to find elements of a certain global rank in
+ * @brief Functions to find elements of a certain global __rank in
* multiple sorted sequences. Also serves for splitting such
* sequence sets.
*
@@ -50,584 +50,601 @@
namespace __gnu_parallel
{
- /** @brief Compare a pair of types lexicographically, ascending. */
- template<typename T1, typename T2, typename Comparator>
- class lexicographic
- : public std::binary_function<std::pair<T1, T2>, std::pair<T1, T2>, bool>
+ /** @brief Compare __a pair of types lexicographically, ascending. */
+ template<typename _T1, typename _T2, typename _Compare>
+ class _Lexicographic
+ : public std::binary_function<
+ std::pair<_T1, _T2>, std::pair<_T1, _T2>, bool>
{
private:
- Comparator& comp;
+ _Compare& _M_comp;
public:
- lexicographic(Comparator& _comp) : comp(_comp) { }
+ _Lexicographic(_Compare& __comp) : _M_comp(__comp) { }
bool
- operator()(const std::pair<T1, T2>& p1,
- const std::pair<T1, T2>& p2) const
+ operator()(const std::pair<_T1, _T2>& __p1,
+ const std::pair<_T1, _T2>& __p2) const
{
- if (comp(p1.first, p2.first))
- return true;
+ if (_M_comp(__p1.first, __p2.first))
+ return true;
- if (comp(p2.first, p1.first))
- return false;
+ if (_M_comp(__p2.first, __p1.first))
+ return false;
- // Firsts are equal.
- return p1.second < p2.second;
+ // Firsts are equal.
+ return __p1.second < __p2.second;
}
};
- /** @brief Compare a pair of types lexicographically, descending. */
- template<typename T1, typename T2, typename Comparator>
- class lexicographic_reverse : public std::binary_function<T1, T2, bool>
+ /** @brief Compare __a pair of types lexicographically, descending. */
+ template<typename _T1, typename _T2, typename _Compare>
+ class _LexicographicReverse : public std::binary_function<_T1, _T2, bool>
{
private:
- Comparator& comp;
+ _Compare& _M_comp;
public:
- lexicographic_reverse(Comparator& _comp) : comp(_comp) { }
+ _LexicographicReverse(_Compare& __comp) : _M_comp(__comp) { }
bool
- operator()(const std::pair<T1, T2>& p1,
- const std::pair<T1, T2>& p2) const
+ operator()(const std::pair<_T1, _T2>& __p1,
+ const std::pair<_T1, _T2>& __p2) const
{
- if (comp(p2.first, p1.first))
- return true;
+ if (_M_comp(__p2.first, __p1.first))
+ return true;
- if (comp(p1.first, p2.first))
- return false;
+ if (_M_comp(__p1.first, __p2.first))
+ return false;
- // Firsts are equal.
- return p2.second < p1.second;
+ // Firsts are equal.
+ return __p2.second < __p1.second;
}
};
/**
- * @brief Splits several sorted sequences at a certain global rank,
+ * @brief Splits several sorted sequences at __a certain global __rank,
* resulting in a splitting point for each sequence.
- * The sequences are passed via a sequence of random-access
+ * The sequences are passed via __a __sequence of random-access
* iterator pairs, none of the sequences may be empty. If there
* are several equal elements across the split, the ones on the
- * left side will be chosen from sequences with smaller number.
- * @param begin_seqs Begin of the sequence of iterator pairs.
- * @param end_seqs End of the sequence of iterator pairs.
- * @param rank The global rank to partition at.
- * @param begin_offsets A random-access sequence begin where the
- * result will be stored in. Each element of the sequence is an
+ * __left side will be chosen from sequences with smaller number.
+ * @param __begin_seqs Begin of the sequence of iterator pairs.
+ * @param __end_seqs End of the sequence of iterator pairs.
+ * @param __rank The global __rank to partition at.
+ * @param __begin_offsets A random-access __sequence __begin where the
+ * __result will be stored in. Each element of the sequence is an
* iterator that points to the first element on the greater part of
- * the respective sequence.
- * @param comp The ordering functor, defaults to std::less<T>.
+ * the respective __sequence.
+ * @param __comp The ordering functor, defaults to std::less<_Tp>.
*/
- template<typename RanSeqs, typename RankType, typename RankIterator,
- typename Comparator>
+ template<typename _RanSeqs, typename _RankType, typename _RankIterator,
+ typename _Compare>
void
- multiseq_partition(RanSeqs begin_seqs, RanSeqs end_seqs,
- RankType rank,
- RankIterator begin_offsets,
- Comparator comp = std::less<
+ multiseq_partition(_RanSeqs __begin_seqs, _RanSeqs __end_seqs,
+ _RankType __rank,
+ _RankIterator __begin_offsets,
+ _Compare __comp = std::less<
typename std::iterator_traits<typename
- std::iterator_traits<RanSeqs>::value_type::
- first_type>::value_type>()) // std::less<T>
+ std::iterator_traits<_RanSeqs>::value_type::
+ first_type>::value_type>()) // std::less<_Tp>
{
- _GLIBCXX_CALL(end_seqs - begin_seqs)
+ _GLIBCXX_CALL(__end_seqs - __begin_seqs)
- typedef typename std::iterator_traits<RanSeqs>::value_type::first_type
- It;
- typedef typename std::iterator_traits<It>::difference_type
- difference_type;
- typedef typename std::iterator_traits<It>::value_type value_type;
+ typedef typename std::iterator_traits<_RanSeqs>::value_type::first_type
+ _It;
+ typedef typename std::iterator_traits<_It>::difference_type
+ _DifferenceType;
+ typedef typename std::iterator_traits<_It>::value_type _ValueType;
- lexicographic<value_type, int, Comparator> lcomp(comp);
- lexicographic_reverse<value_type, int, Comparator> lrcomp(comp);
+ _Lexicographic<_ValueType, int, _Compare> __lcomp(__comp);
+ _LexicographicReverse<_ValueType, int, _Compare> __lrcomp(__comp);
// Number of sequences, number of elements in total (possibly
// including padding).
- difference_type m = std::distance(begin_seqs, end_seqs), N = 0,
- nmax, n, r;
+ _DifferenceType __m = std::distance(__begin_seqs, __end_seqs), __N = 0,
+ __nmax, __n, __r;
- for (int i = 0; i < m; i++)
+ for (int __i = 0; __i < __m; __i++)
{
- N += std::distance(begin_seqs[i].first, begin_seqs[i].second);
+ __N += std::distance(__begin_seqs[__i].first,
+ __begin_seqs[__i].second);
_GLIBCXX_PARALLEL_ASSERT(
- std::distance(begin_seqs[i].first, begin_seqs[i].second) > 0);
+ std::distance(__begin_seqs[__i].first,
+ __begin_seqs[__i].second) > 0);
}
- if (rank == N)
+ if (__rank == __N)
{
- for (int i = 0; i < m; i++)
- begin_offsets[i] = begin_seqs[i].second; // Very end.
- // Return m - 1;
+ for (int __i = 0; __i < __m; __i++)
+ __begin_offsets[__i] = __begin_seqs[__i].second; // Very end.
+ // Return __m - 1;
return;
}
- _GLIBCXX_PARALLEL_ASSERT(m != 0);
- _GLIBCXX_PARALLEL_ASSERT(N != 0);
- _GLIBCXX_PARALLEL_ASSERT(rank >= 0);
- _GLIBCXX_PARALLEL_ASSERT(rank < N);
+ _GLIBCXX_PARALLEL_ASSERT(__m != 0);
+ _GLIBCXX_PARALLEL_ASSERT(__N != 0);
+ _GLIBCXX_PARALLEL_ASSERT(__rank >= 0);
+ _GLIBCXX_PARALLEL_ASSERT(__rank < __N);
- difference_type* ns = new difference_type[m];
- difference_type* a = new difference_type[m];
- difference_type* b = new difference_type[m];
- difference_type l;
+ _DifferenceType* __ns = new _DifferenceType[__m];
+ _DifferenceType* __a = new _DifferenceType[__m];
+ _DifferenceType* __b = new _DifferenceType[__m];
+ _DifferenceType __l;
- ns[0] = std::distance(begin_seqs[0].first, begin_seqs[0].second);
- nmax = ns[0];
- for (int i = 0; i < m; i++)
- {
- ns[i] = std::distance(begin_seqs[i].first, begin_seqs[i].second);
- nmax = std::max(nmax, ns[i]);
- }
+ __ns[0] = std::distance(__begin_seqs[0].first, __begin_seqs[0].second);
+ __nmax = __ns[0];
+ for (int __i = 0; __i < __m; __i++)
+ {
+ __ns[__i] = std::distance(__begin_seqs[__i].first,
+ __begin_seqs[__i].second);
+ __nmax = std::max(__nmax, __ns[__i]);
+ }
- r = __log2(nmax) + 1;
+ __r = __log2(__nmax) + 1;
- // Pad all lists to this length, at least as long as any ns[i],
- // equality iff nmax = 2^k - 1.
- l = (1ULL << r) - 1;
+ // Pad all lists to this length, at least as long as any ns[__i],
+ // equality iff __nmax = 2^__k - 1.
+ __l = (1ULL << __r) - 1;
// From now on, including padding.
- N = l * m;
+ __N = __l * __m;
- for (int i = 0; i < m; i++)
- {
- a[i] = 0;
- b[i] = l;
- }
- n = l / 2;
+ for (int __i = 0; __i < __m; __i++)
+ {
+ __a[__i] = 0;
+ __b[__i] = __l;
+ }
+ __n = __l / 2;
// Invariants:
- // 0 <= a[i] <= ns[i], 0 <= b[i] <= l
+ // 0 <= __a[__i] <= __ns[__i], 0 <= __b[__i] <= __l
-#define S(i) (begin_seqs[i].first)
+#define __S(__i) (__begin_seqs[__i].first)
// Initial partition.
- std::vector<std::pair<value_type, int> > sample;
-
- for (int i = 0; i < m; i++)
- if (n < ns[i]) //sequence long enough
- sample.push_back(std::make_pair(S(i)[n], i));
- __gnu_sequential::sort(sample.begin(), sample.end(), lcomp);
-
- for (int i = 0; i < m; i++) //conceptual infinity
- if (n >= ns[i]) //sequence too short, conceptual infinity
- sample.push_back(std::make_pair(S(i)[0] /*dummy element*/, i));
-
- difference_type localrank = rank * m / N ;
-
- int j;
- for (j = 0; j < localrank && ((n + 1) <= ns[sample[j].second]); ++j)
- a[sample[j].second] += n + 1;
- for (; j < m; j++)
- b[sample[j].second] -= n + 1;
+ std::vector<std::pair<_ValueType, int> > __sample;
+
+ for (int __i = 0; __i < __m; __i++)
+ if (__n < __ns[__i]) //__sequence long enough
+ __sample.push_back(std::make_pair(__S(__i)[__n], __i));
+ __gnu_sequential::sort(__sample.begin(), __sample.end(), __lcomp);
+
+ for (int __i = 0; __i < __m; __i++) //conceptual infinity
+ if (__n >= __ns[__i]) //__sequence too short, conceptual infinity
+ __sample.push_back(
+ std::make_pair(__S(__i)[0] /*__dummy element*/, __i));
+
+ _DifferenceType localrank = __rank * __m / __N ;
+
+ int __j;
+ for (__j = 0;
+ __j < localrank && ((__n + 1) <= __ns[__sample[__j].second]); ++__j)
+ __a[__sample[__j].second] += __n + 1;
+ for (; __j < __m; __j++)
+ __b[__sample[__j].second] -= __n + 1;
// Further refinement.
- while (n > 0)
- {
- n /= 2;
-
- int lmax_seq = -1; // to avoid warning
- const value_type* lmax = NULL; // impossible to avoid the warning?
- for (int i = 0; i < m; i++)
- {
- if (a[i] > 0)
- {
- if (!lmax)
- {
- lmax = &(S(i)[a[i] - 1]);
- lmax_seq = i;
- }
- else
- {
- // Max, favor rear sequences.
- if (!comp(S(i)[a[i] - 1], *lmax))
- {
- lmax = &(S(i)[a[i] - 1]);
- lmax_seq = i;
- }
- }
- }
- }
-
- int i;
- for (i = 0; i < m; i++)
- {
- difference_type middle = (b[i] + a[i]) / 2;
- if (lmax && middle < ns[i] &&
- lcomp(std::make_pair(S(i)[middle], i),
- std::make_pair(*lmax, lmax_seq)))
- a[i] = std::min(a[i] + n + 1, ns[i]);
- else
- b[i] -= n + 1;
- }
-
- difference_type leftsize = 0, total = 0;
- for (int i = 0; i < m; i++)
- {
- leftsize += a[i] / (n + 1);
- total += l / (n + 1);
- }
-
- difference_type skew = static_cast<difference_type>
- (static_cast<uint64>(total) * rank / N - leftsize);
-
- if (skew > 0)
- {
- // Move to the left, find smallest.
- std::priority_queue<std::pair<value_type, int>,
- std::vector<std::pair<value_type, int> >,
- lexicographic_reverse<value_type, int, Comparator> >
- pq(lrcomp);
-
- for (int i = 0; i < m; i++)
- if (b[i] < ns[i])
- pq.push(std::make_pair(S(i)[b[i]], i));
-
- for (; skew != 0 && !pq.empty(); --skew)
- {
- int source = pq.top().second;
- pq.pop();
-
- a[source] = std::min(a[source] + n + 1, ns[source]);
- b[source] += n + 1;
-
- if (b[source] < ns[source])
- pq.push(std::make_pair(S(source)[b[source]], source));
- }
- }
- else if (skew < 0)
- {
- // Move to the right, find greatest.
- std::priority_queue<std::pair<value_type, int>,
- std::vector<std::pair<value_type, int> >,
- lexicographic<value_type, int, Comparator> > pq(lcomp);
-
- for (int i = 0; i < m; i++)
- if (a[i] > 0)
- pq.push(std::make_pair(S(i)[a[i] - 1], i));
-
- for (; skew != 0; ++skew)
- {
- int source = pq.top().second;
- pq.pop();
-
- a[source] -= n + 1;
- b[source] -= n + 1;
-
- if (a[source] > 0)
- pq.push(std::make_pair(S(source)[a[source] - 1], source));
- }
- }
- }
+ while (__n > 0)
+ {
+ __n /= 2;
+
+ int __lmax_seq = -1; // to avoid warning
+ const _ValueType* __lmax = NULL; // impossible to avoid the warning?
+ for (int __i = 0; __i < __m; __i++)
+ {
+ if (__a[__i] > 0)
+ {
+ if (!__lmax)
+ {
+ __lmax = &(__S(__i)[__a[__i] - 1]);
+ __lmax_seq = __i;
+ }
+ else
+ {
+ // Max, favor rear sequences.
+ if (!__comp(__S(__i)[__a[__i] - 1], *__lmax))
+ {
+ __lmax = &(__S(__i)[__a[__i] - 1]);
+ __lmax_seq = __i;
+ }
+ }
+ }
+ }
+
+ int __i;
+ for (__i = 0; __i < __m; __i++)
+ {
+ _DifferenceType __middle = (__b[__i] + __a[__i]) / 2;
+ if (__lmax && __middle < __ns[__i] &&
+ __lcomp(std::make_pair(__S(__i)[__middle], __i),
+ std::make_pair(*__lmax, __lmax_seq)))
+ __a[__i] = std::min(__a[__i] + __n + 1, __ns[__i]);
+ else
+ __b[__i] -= __n + 1;
+ }
+
+ _DifferenceType __leftsize = 0, __total = 0;
+ for (int __i = 0; __i < __m; __i++)
+ {
+ __leftsize += __a[__i] / (__n + 1);
+ __total += __l / (__n + 1);
+ }
+
+ _DifferenceType __skew = static_cast<_DifferenceType>
+ (static_cast<uint64>(__total) * __rank / __N - __leftsize);
+
+ if (__skew > 0)
+ {
+ // Move to the left, find smallest.
+ std::priority_queue<std::pair<_ValueType, int>,
+ std::vector<std::pair<_ValueType, int> >,
+ _LexicographicReverse<_ValueType, int, _Compare> >
+ __pq(__lrcomp);
+
+ for (int __i = 0; __i < __m; __i++)
+ if (__b[__i] < __ns[__i])
+ __pq.push(std::make_pair(__S(__i)[__b[__i]], __i));
+
+ for (; __skew != 0 && !__pq.empty(); --__skew)
+ {
+ int source = __pq.top().second;
+ __pq.pop();
+
+ __a[source] = std::min(__a[source] + __n + 1, __ns[source]);
+ __b[source] += __n + 1;
+
+ if (__b[source] < __ns[source])
+ __pq.push(
+ std::make_pair(__S(source)[__b[source]], source));
+ }
+ }
+ else if (__skew < 0)
+ {
+ // Move to the right, find greatest.
+ std::priority_queue<std::pair<_ValueType, int>,
+ std::vector<std::pair<_ValueType, int> >,
+ _Lexicographic<_ValueType, int, _Compare> > __pq(__lcomp);
+
+ for (int __i = 0; __i < __m; __i++)
+ if (__a[__i] > 0)
+ __pq.push(std::make_pair(__S(__i)[__a[__i] - 1], __i));
+
+ for (; __skew != 0; ++__skew)
+ {
+ int source = __pq.top().second;
+ __pq.pop();
+
+ __a[source] -= __n + 1;
+ __b[source] -= __n + 1;
+
+ if (__a[source] > 0)
+ __pq.push(
+ std::make_pair(__S(source)[__a[source] - 1], source));
+ }
+ }
+ }
// Postconditions:
- // a[i] == b[i] in most cases, except when a[i] has been clamped
- // because of having reached the boundary
+ // __a[__i] == __b[__i] in most cases, except when __a[__i] has been
+ // clamped because of having reached the boundary
// Now return the result, calculate the offset.
// Compare the keys on both edges of the border.
// Maximum of left edge, minimum of right edge.
- value_type* maxleft = NULL;
- value_type* minright = NULL;
- for (int i = 0; i < m; i++)
- {
- if (a[i] > 0)
- {
- if (!maxleft)
- maxleft = &(S(i)[a[i] - 1]);
- else
- {
- // Max, favor rear sequences.
- if (!comp(S(i)[a[i] - 1], *maxleft))
- maxleft = &(S(i)[a[i] - 1]);
- }
- }
- if (b[i] < ns[i])
- {
- if (!minright)
- minright = &(S(i)[b[i]]);
- else
- {
- // Min, favor fore sequences.
- if (comp(S(i)[b[i]], *minright))
- minright = &(S(i)[b[i]]);
- }
- }
- }
-
- int seq = 0;
- for (int i = 0; i < m; i++)
- begin_offsets[i] = S(i) + a[i];
-
- delete[] ns;
- delete[] a;
- delete[] b;
+ _ValueType* __maxleft = NULL;
+ _ValueType* __minright = NULL;
+ for (int __i = 0; __i < __m; __i++)
+ {
+ if (__a[__i] > 0)
+ {
+ if (!__maxleft)
+ __maxleft = &(__S(__i)[__a[__i] - 1]);
+ else
+ {
+ // Max, favor rear sequences.
+ if (!__comp(__S(__i)[__a[__i] - 1], *__maxleft))
+ __maxleft = &(__S(__i)[__a[__i] - 1]);
+ }
+ }
+ if (__b[__i] < __ns[__i])
+ {
+ if (!__minright)
+ __minright = &(__S(__i)[__b[__i]]);
+ else
+ {
+ // Min, favor fore sequences.
+ if (__comp(__S(__i)[__b[__i]], *__minright))
+ __minright = &(__S(__i)[__b[__i]]);
+ }
+ }
+ }
+
+ int __seq = 0;
+ for (int __i = 0; __i < __m; __i++)
+ __begin_offsets[__i] = __S(__i) + __a[__i];
+
+ delete[] __ns;
+ delete[] __a;
+ delete[] __b;
}
/**
- * @brief Selects the element at a certain global rank from several
+ * @brief Selects the element at __a certain global __rank from several
* sorted sequences.
*
- * The sequences are passed via a sequence of random-access
+ * The sequences are passed via __a __sequence of random-access
* iterator pairs, none of the sequences may be empty.
- * @param begin_seqs Begin of the sequence of iterator pairs.
- * @param end_seqs End of the sequence of iterator pairs.
- * @param rank The global rank to partition at.
- * @param offset The rank of the selected element in the global
+ * @param __begin_seqs Begin of the sequence of iterator pairs.
+ * @param __end_seqs End of the sequence of iterator pairs.
+ * @param __rank The global __rank to partition at.
+ * @param __offset The rank of the selected element in the global
* subsequence of elements equal to the selected element. If the
* selected element is unique, this number is 0.
- * @param comp The ordering functor, defaults to std::less.
+ * @param __comp The ordering functor, defaults to std::less.
*/
- template<typename T, typename RanSeqs, typename RankType,
- typename Comparator>
- T
- multiseq_selection(RanSeqs begin_seqs, RanSeqs end_seqs, RankType rank,
- RankType& offset, Comparator comp = std::less<T>())
+ template<typename _Tp, typename _RanSeqs, typename _RankType,
+ typename _Compare>
+ _Tp
+ multiseq_selection(_RanSeqs __begin_seqs, _RanSeqs __end_seqs,
+ _RankType __rank,
+ _RankType& __offset, _Compare __comp = std::less<_Tp>())
{
- _GLIBCXX_CALL(end_seqs - begin_seqs)
+ _GLIBCXX_CALL(__end_seqs - __begin_seqs)
- typedef typename std::iterator_traits<RanSeqs>::value_type::first_type
- It;
- typedef typename std::iterator_traits<It>::difference_type
- difference_type;
+ typedef typename std::iterator_traits<_RanSeqs>::value_type::first_type
+ _It;
+ typedef typename std::iterator_traits<_It>::difference_type
+ _DifferenceType;
- lexicographic<T, int, Comparator> lcomp(comp);
- lexicographic_reverse<T, int, Comparator> lrcomp(comp);
+ _Lexicographic<_Tp, int, _Compare> __lcomp(__comp);
+ _LexicographicReverse<_Tp, int, _Compare> __lrcomp(__comp);
// Number of sequences, number of elements in total (possibly
// including padding).
- difference_type m = std::distance(begin_seqs, end_seqs);
- difference_type N = 0;
- difference_type nmax, n, r;
+ _DifferenceType __m = std::distance(__begin_seqs, __end_seqs);
+ _DifferenceType __N = 0;
+ _DifferenceType __nmax, __n, __r;
- for (int i = 0; i < m; i++)
- N += std::distance(begin_seqs[i].first, begin_seqs[i].second);
+ for (int __i = 0; __i < __m; __i++)
+ __N += std::distance(__begin_seqs[__i].first,
+ __begin_seqs[__i].second);
- if (m == 0 || N == 0 || rank < 0 || rank >= N)
- {
- // Result undefined when there is no data or rank is outside bounds.
- throw std::exception();
- }
+ if (__m == 0 || __N == 0 || __rank < 0 || __rank >= __N)
+ {
+ // result undefined if there is no data or __rank is outside bounds
+ throw std::exception();
+ }
- difference_type* ns = new difference_type[m];
- difference_type* a = new difference_type[m];
- difference_type* b = new difference_type[m];
- difference_type l;
+ _DifferenceType* __ns = new _DifferenceType[__m];
+ _DifferenceType* __a = new _DifferenceType[__m];
+ _DifferenceType* __b = new _DifferenceType[__m];
+ _DifferenceType __l;
- ns[0] = std::distance(begin_seqs[0].first, begin_seqs[0].second);
- nmax = ns[0];
- for (int i = 0; i < m; ++i)
- {
- ns[i] = std::distance(begin_seqs[i].first, begin_seqs[i].second);
- nmax = std::max(nmax, ns[i]);
- }
+ __ns[0] = std::distance(__begin_seqs[0].first, __begin_seqs[0].second);
+ __nmax = __ns[0];
+ for (int __i = 0; __i < __m; ++__i)
+ {
+ __ns[__i] = std::distance(__begin_seqs[__i].first,
+ __begin_seqs[__i].second);
+ __nmax = std::max(__nmax, __ns[__i]);
+ }
- r = __log2(nmax) + 1;
+ __r = __log2(__nmax) + 1;
- // Pad all lists to this length, at least as long as any ns[i],
- // equality iff nmax = 2^k - 1
- l = pow2(r) - 1;
+ // Pad all lists to this length, at least as long as any ns[__i],
+ // equality iff __nmax = 2^__k - 1
+ __l = pow2(__r) - 1;
// From now on, including padding.
- N = l * m;
+ __N = __l * __m;
- for (int i = 0; i < m; ++i)
- {
- a[i] = 0;
- b[i] = l;
- }
- n = l / 2;
+ for (int __i = 0; __i < __m; ++__i)
+ {
+ __a[__i] = 0;
+ __b[__i] = __l;
+ }
+ __n = __l / 2;
// Invariants:
- // 0 <= a[i] <= ns[i], 0 <= b[i] <= l
+ // 0 <= __a[__i] <= __ns[__i], 0 <= __b[__i] <= __l
-#define S(i) (begin_seqs[i].first)
+#define __S(__i) (__begin_seqs[__i].first)
// Initial partition.
- std::vector<std::pair<T, int> > sample;
+ std::vector<std::pair<_Tp, int> > __sample;
- for (int i = 0; i < m; i++)
- if (n < ns[i])
- sample.push_back(std::make_pair(S(i)[n], i));
- __gnu_sequential::sort(sample.begin(), sample.end(),
- lcomp, sequential_tag());
+ for (int __i = 0; __i < __m; __i++)
+ if (__n < __ns[__i])
+ __sample.push_back(std::make_pair(__S(__i)[__n], __i));
+ __gnu_sequential::sort(__sample.begin(), __sample.end(),
+ __lcomp, sequential_tag());
// Conceptual infinity.
- for (int i = 0; i < m; i++)
- if (n >= ns[i])
- sample.push_back(std::make_pair(S(i)[0] /*dummy element*/, i));
+ for (int __i = 0; __i < __m; __i++)
+ if (__n >= __ns[__i])
+ __sample.push_back(
+ std::make_pair(__S(__i)[0] /*__dummy element*/, __i));
- difference_type localrank = rank * m / N ;
+ _DifferenceType localrank = __rank * __m / __N ;
- int j;
- for (j = 0; j < localrank && ((n + 1) <= ns[sample[j].second]); ++j)
- a[sample[j].second] += n + 1;
- for (; j < m; ++j)
- b[sample[j].second] -= n + 1;
+ int __j;
+ for (__j = 0;
+ __j < localrank && ((__n + 1) <= __ns[__sample[__j].second]); ++__j)
+ __a[__sample[__j].second] += __n + 1;
+ for (; __j < __m; ++__j)
+ __b[__sample[__j].second] -= __n + 1;
// Further refinement.
- while (n > 0)
- {
- n /= 2;
-
- const T* lmax = NULL;
- for (int i = 0; i < m; ++i)
- {
- if (a[i] > 0)
- {
- if (!lmax)
- lmax = &(S(i)[a[i] - 1]);
- else
- {
- if (comp(*lmax, S(i)[a[i] - 1])) //max
- lmax = &(S(i)[a[i] - 1]);
- }
- }
- }
-
- int i;
- for (i = 0; i < m; i++)
- {
- difference_type middle = (b[i] + a[i]) / 2;
- if (lmax && middle < ns[i] && comp(S(i)[middle], *lmax))
- a[i] = std::min(a[i] + n + 1, ns[i]);
- else
- b[i] -= n + 1;
- }
-
- difference_type leftsize = 0, total = 0;
- for (int i = 0; i < m; ++i)
- {
- leftsize += a[i] / (n + 1);
- total += l / (n + 1);
- }
-
- difference_type skew = ((unsigned long long)total * rank / N
- - leftsize);
-
- if (skew > 0)
- {
- // Move to the left, find smallest.
- std::priority_queue<std::pair<T, int>,
- std::vector<std::pair<T, int> >,
- lexicographic_reverse<T, int, Comparator> > pq(lrcomp);
-
- for (int i = 0; i < m; ++i)
- if (b[i] < ns[i])
- pq.push(std::make_pair(S(i)[b[i]], i));
-
- for (; skew != 0 && !pq.empty(); --skew)
- {
- int source = pq.top().second;
- pq.pop();
-
- a[source] = std::min(a[source] + n + 1, ns[source]);
- b[source] += n + 1;
-
- if (b[source] < ns[source])
- pq.push(std::make_pair(S(source)[b[source]], source));
- }
- }
- else if (skew < 0)
- {
- // Move to the right, find greatest.
- std::priority_queue<std::pair<T, int>,
- std::vector<std::pair<T, int> >,
- lexicographic<T, int, Comparator> > pq(lcomp);
-
- for (int i = 0; i < m; ++i)
- if (a[i] > 0)
- pq.push(std::make_pair(S(i)[a[i] - 1], i));
-
- for (; skew != 0; ++skew)
- {
- int source = pq.top().second;
- pq.pop();
-
- a[source] -= n + 1;
- b[source] -= n + 1;
-
- if (a[source] > 0)
- pq.push(std::make_pair(S(source)[a[source] - 1], source));
- }
- }
- }
+ while (__n > 0)
+ {
+ __n /= 2;
+
+ const _Tp* __lmax = NULL;
+ for (int __i = 0; __i < __m; ++__i)
+ {
+ if (__a[__i] > 0)
+ {
+ if (!__lmax)
+ __lmax = &(__S(__i)[__a[__i] - 1]);
+ else
+ {
+ if (__comp(*__lmax, __S(__i)[__a[__i] - 1])) //max
+ __lmax = &(__S(__i)[__a[__i] - 1]);
+ }
+ }
+ }
+
+ int __i;
+ for (__i = 0; __i < __m; __i++)
+ {
+ _DifferenceType __middle = (__b[__i] + __a[__i]) / 2;
+ if (__lmax && __middle < __ns[__i]
+ && __comp(__S(__i)[__middle], *__lmax))
+ __a[__i] = std::min(__a[__i] + __n + 1, __ns[__i]);
+ else
+ __b[__i] -= __n + 1;
+ }
+
+ _DifferenceType __leftsize = 0, __total = 0;
+ for (int __i = 0; __i < __m; ++__i)
+ {
+ __leftsize += __a[__i] / (__n + 1);
+ __total += __l / (__n + 1);
+ }
+
+ _DifferenceType __skew = ((unsigned long long)__total * __rank / __N
+ - __leftsize);
+
+ if (__skew > 0)
+ {
+ // Move to the left, find smallest.
+ std::priority_queue<std::pair<_Tp, int>,
+ std::vector<std::pair<_Tp, int> >,
+ _LexicographicReverse<_Tp, int, _Compare> > __pq(__lrcomp);
+
+ for (int __i = 0; __i < __m; ++__i)
+ if (__b[__i] < __ns[__i])
+ __pq.push(std::make_pair(__S(__i)[__b[__i]], __i));
+
+ for (; __skew != 0 && !__pq.empty(); --__skew)
+ {
+ int source = __pq.top().second;
+ __pq.pop();
+
+ __a[source] = std::min(__a[source] + __n + 1, __ns[source]);
+ __b[source] += __n + 1;
+
+ if (__b[source] < __ns[source])
+ __pq.push(
+ std::make_pair(__S(source)[__b[source]], source));
+ }
+ }
+ else if (__skew < 0)
+ {
+ // Move to the right, find greatest.
+ std::priority_queue<std::pair<_Tp, int>,
+ std::vector<std::pair<_Tp, int> >,
+ _Lexicographic<_Tp, int, _Compare> > __pq(__lcomp);
+
+ for (int __i = 0; __i < __m; ++__i)
+ if (__a[__i] > 0)
+ __pq.push(std::make_pair(__S(__i)[__a[__i] - 1], __i));
+
+ for (; __skew != 0; ++__skew)
+ {
+ int source = __pq.top().second;
+ __pq.pop();
+
+ __a[source] -= __n + 1;
+ __b[source] -= __n + 1;
+
+ if (__a[source] > 0)
+ __pq.push(
+ std::make_pair(__S(source)[__a[source] - 1], source));
+ }
+ }
+ }
// Postconditions:
- // a[i] == b[i] in most cases, except when a[i] has been clamped
- // because of having reached the boundary
+ // __a[__i] == __b[__i] in most cases, except when __a[__i] has been
+ // clamped because of having reached the boundary
// Now return the result, calculate the offset.
// Compare the keys on both edges of the border.
// Maximum of left edge, minimum of right edge.
- bool maxleftset = false, minrightset = false;
+ bool __maxleftset = false, __minrightset = false;
// Impossible to avoid the warning?
- T maxleft, minright;
- for (int i = 0; i < m; ++i)
- {
- if (a[i] > 0)
- {
- if (!maxleftset)
- {
- maxleft = S(i)[a[i] - 1];
- maxleftset = true;
- }
- else
- {
- // Max.
- if (comp(maxleft, S(i)[a[i] - 1]))
- maxleft = S(i)[a[i] - 1];
- }
- }
- if (b[i] < ns[i])
- {
- if (!minrightset)
- {
- minright = S(i)[b[i]];
- minrightset = true;
- }
- else
- {
- // Min.
- if (comp(S(i)[b[i]], minright))
- minright = S(i)[b[i]];
- }
- }
+ _Tp __maxleft, __minright;
+ for (int __i = 0; __i < __m; ++__i)
+ {
+ if (__a[__i] > 0)
+ {
+ if (!__maxleftset)
+ {
+ __maxleft = __S(__i)[__a[__i] - 1];
+ __maxleftset = true;
+ }
+ else
+ {
+ // Max.
+ if (__comp(__maxleft, __S(__i)[__a[__i] - 1]))
+ __maxleft = __S(__i)[__a[__i] - 1];
+ }
+ }
+ if (__b[__i] < __ns[__i])
+ {
+ if (!__minrightset)
+ {
+ __minright = __S(__i)[__b[__i]];
+ __minrightset = true;
+ }
+ else
+ {
+ // Min.
+ if (__comp(__S(__i)[__b[__i]], __minright))
+ __minright = __S(__i)[__b[__i]];
+ }
+ }
}
// Minright is the splitter, in any case.
- if (!maxleftset || comp(minright, maxleft))
- {
- // Good luck, everything is split unambiguously.
- offset = 0;
- }
+ if (!__maxleftset || __comp(__minright, __maxleft))
+ {
+ // Good luck, everything is split unambiguously.
+ __offset = 0;
+ }
else
- {
- // We have to calculate an offset.
- offset = 0;
-
- for (int i = 0; i < m; ++i)
- {
- difference_type lb = std::lower_bound(S(i), S(i) + ns[i],
- minright,
- comp) - S(i);
- offset += a[i] - lb;
- }
- }
-
- delete[] ns;
- delete[] a;
- delete[] b;
-
- return minright;
+ {
+ // We have to calculate an offset.
+ __offset = 0;
+
+ for (int __i = 0; __i < __m; ++__i)
+ {
+ _DifferenceType lb
+ = std::lower_bound(__S(__i), __S(__i) + __ns[__i],
+ __minright,
+ __comp) - __S(__i);
+ __offset += __a[__i] - lb;
+ }
+ }
+
+ delete[] __ns;
+ delete[] __a;
+ delete[] __b;
+
+ return __minright;
}
}
-#undef S
+#undef __S
#endif /* _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H */
diff --git a/libstdc++-v3/include/parallel/multiway_merge.h b/libstdc++-v3/include/parallel/multiway_merge.h
index bacff8dbadb..b5540e71426 100644
--- a/libstdc++-v3/include/parallel/multiway_merge.h
+++ b/libstdc++-v3/include/parallel/multiway_merge.h
@@ -50,303 +50,303 @@
#endif
/** @brief Length of a sequence described by a pair of iterators. */
-#define _GLIBCXX_PARALLEL_LENGTH(s) ((s).second - (s).first)
+#define _GLIBCXX_PARALLEL_LENGTH(__s) ((__s).second - (__s).first)
namespace __gnu_parallel
{
// Announce guarded and unguarded iterator.
-template<typename RandomAccessIterator, typename Comparator>
- class guarded_iterator;
+template<typename _RAIter, typename _Compare>
+ class _GuardedIterator;
// Making the arguments const references seems to dangerous,
// the user-defined comparator might not be const.
-template<typename RandomAccessIterator, typename Comparator>
+template<typename _RAIter, typename _Compare>
inline bool
- operator<(guarded_iterator<RandomAccessIterator, Comparator>& bi1,
- guarded_iterator<RandomAccessIterator, Comparator>& bi2);
+ operator<(_GuardedIterator<_RAIter, _Compare>& __bi1,
+ _GuardedIterator<_RAIter, _Compare>& __bi2);
-template<typename RandomAccessIterator, typename Comparator>
+template<typename _RAIter, typename _Compare>
inline bool
- operator<=(guarded_iterator<RandomAccessIterator, Comparator>& bi1,
- guarded_iterator<RandomAccessIterator, Comparator>& bi2);
+ operator<=(_GuardedIterator<_RAIter, _Compare>& __bi1,
+ _GuardedIterator<_RAIter, _Compare>& __bi2);
-/** @brief Iterator wrapper supporting an implicit supremum at the end
+/** @brief _Iterator wrapper supporting an implicit supremum at the end
* of the sequence, dominating all comparisons.
*
- * The implicit supremum comes with a performance cost.
+ * The implicit supremum comes with __a performance cost.
*
- * Deriving from RandomAccessIterator is not possible since
- * RandomAccessIterator need not be a class.
+ * Deriving from _RAIter is not possible since
+ * _RAIter need not be a class.
*/
-template<typename RandomAccessIterator, typename Comparator>
- class guarded_iterator
+template<typename _RAIter, typename _Compare>
+ class _GuardedIterator
{
private:
- /** @brief Current iterator position. */
- RandomAccessIterator current;
+ /** @brief Current iterator __position. */
+ _RAIter _M_current;
/** @brief End iterator of the sequence. */
- RandomAccessIterator end;
+ _RAIter _M_end;
- /** @brief Comparator. */
- Comparator& comp;
+ /** @brief _Compare. */
+ _Compare& __comp;
public:
/** @brief Constructor. Sets iterator to beginning of sequence.
- * @param begin Begin iterator of sequence.
- * @param end End iterator of sequence.
- * @param comp Comparator provided for associated overloaded
+ * @param __begin Begin iterator of sequence.
+ * @param _M_end End iterator of sequence.
+ * @param __comp Comparator provided for associated overloaded
* compare operators. */
- guarded_iterator(RandomAccessIterator begin,
- RandomAccessIterator end, Comparator& comp)
- : current(begin), end(end), comp(comp)
+ _GuardedIterator(_RAIter __begin,
+ _RAIter _M_end, _Compare& __comp)
+ : _M_current(__begin), _M_end(_M_end), __comp(__comp)
{ }
/** @brief Pre-increment operator.
* @return This. */
- guarded_iterator<RandomAccessIterator, Comparator>&
+ _GuardedIterator<_RAIter, _Compare>&
operator++()
{
- ++current;
+ ++_M_current;
return *this;
}
/** @brief Dereference operator.
* @return Referenced element. */
- typename std::iterator_traits<RandomAccessIterator>::value_type&
+ typename std::iterator_traits<_RAIter>::value_type&
operator*()
- { return *current; }
+ { return *_M_current; }
/** @brief Convert to wrapped iterator.
* @return Wrapped iterator. */
- operator RandomAccessIterator()
- { return current; }
+ operator _RAIter()
+ { return _M_current; }
friend bool
- operator< <RandomAccessIterator, Comparator>(
- guarded_iterator<RandomAccessIterator, Comparator>& bi1,
- guarded_iterator<RandomAccessIterator, Comparator>& bi2);
+ operator< <_RAIter, _Compare>(
+ _GuardedIterator<_RAIter, _Compare>& __bi1,
+ _GuardedIterator<_RAIter, _Compare>& __bi2);
friend bool
- operator<= <RandomAccessIterator, Comparator>(
- guarded_iterator<RandomAccessIterator, Comparator>& bi1,
- guarded_iterator<RandomAccessIterator, Comparator>& bi2);
+ operator<= <_RAIter, _Compare>(
+ _GuardedIterator<_RAIter, _Compare>& __bi1,
+ _GuardedIterator<_RAIter, _Compare>& __bi2);
};
/** @brief Compare two elements referenced by guarded iterators.
- * @param bi1 First iterator.
- * @param bi2 Second iterator.
- * @return @c True if less. */
-template<typename RandomAccessIterator, typename Comparator>
+ * @param __bi1 First iterator.
+ * @param __bi2 Second iterator.
+ * @return @__c true if less. */
+template<typename _RAIter, typename _Compare>
inline bool
- operator<(guarded_iterator<RandomAccessIterator, Comparator>& bi1,
- guarded_iterator<RandomAccessIterator, Comparator>& bi2)
+ operator<(_GuardedIterator<_RAIter, _Compare>& __bi1,
+ _GuardedIterator<_RAIter, _Compare>& __bi2)
{
- if (bi1.current == bi1.end) //bi1 is sup
- return bi2.current == bi2.end; //bi2 is not sup
- if (bi2.current == bi2.end) //bi2 is sup
+ if (__bi1._M_current == __bi1._M_end) //__bi1 is sup
+ return __bi2._M_current == __bi2._M_end; //__bi2 is not sup
+ if (__bi2._M_current == __bi2._M_end) //__bi2 is sup
return true;
- return (bi1.comp)(*bi1, *bi2); //normal compare
+ return (__bi1.__comp)(*__bi1, *__bi2); //normal compare
}
/** @brief Compare two elements referenced by guarded iterators.
- * @param bi1 First iterator.
- * @param bi2 Second iterator.
- * @return @c True if less equal. */
-template<typename RandomAccessIterator, typename Comparator>
+ * @param __bi1 First iterator.
+ * @param __bi2 Second iterator.
+ * @return @__c True if less equal. */
+template<typename _RAIter, typename _Compare>
inline bool
- operator<=(guarded_iterator<RandomAccessIterator, Comparator>& bi1,
- guarded_iterator<RandomAccessIterator, Comparator>& bi2)
+ operator<=(_GuardedIterator<_RAIter, _Compare>& __bi1,
+ _GuardedIterator<_RAIter, _Compare>& __bi2)
{
- if (bi2.current == bi2.end) //bi1 is sup
- return bi1.current != bi1.end; //bi2 is not sup
- if (bi1.current == bi1.end) //bi2 is sup
+ if (__bi2._M_current == __bi2._M_end) //__bi1 is sup
+ return __bi1._M_current != __bi1._M_end; //__bi2 is not sup
+ if (__bi1._M_current == __bi1._M_end) //__bi2 is sup
return false;
- return !(bi1.comp)(*bi2, *bi1); //normal compare
+ return !(__bi1.__comp)(*__bi2, *__bi1); //normal compare
}
-template<typename RandomAccessIterator, typename Comparator>
+template<typename _RAIter, typename _Compare>
class unguarded_iterator;
-template<typename RandomAccessIterator, typename Comparator>
+template<typename _RAIter, typename _Compare>
inline bool
- operator<(unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
- unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
+ operator<(unguarded_iterator<_RAIter, _Compare>& __bi1,
+ unguarded_iterator<_RAIter, _Compare>& __bi2);
-template<typename RandomAccessIterator, typename Comparator>
+template<typename _RAIter, typename _Compare>
inline bool
- operator<=(unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
- unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
+ operator<=(unguarded_iterator<_RAIter, _Compare>& __bi1,
+ unguarded_iterator<_RAIter, _Compare>& __bi2);
-template<typename RandomAccessIterator, typename Comparator>
+template<typename _RAIter, typename _Compare>
class unguarded_iterator
{
private:
- /** @brief Current iterator position. */
- RandomAccessIterator current;
- /** @brief Comparator. */
- mutable Comparator& comp;
+ /** @brief Current iterator __position. */
+ _RAIter _M_current;
+ /** @brief _Compare. */
+ mutable _Compare& __comp;
public:
/** @brief Constructor. Sets iterator to beginning of sequence.
- * @param begin Begin iterator of sequence.
- * @param end Unused, only for compatibility.
- * @param comp Unused, only for compatibility. */
- unguarded_iterator(RandomAccessIterator begin,
- RandomAccessIterator end, Comparator& comp)
- : current(begin), comp(comp)
+ * @param __begin Begin iterator of sequence.
+ * @param _M_end Unused, only for compatibility.
+ * @param __comp Unused, only for compatibility. */
+ unguarded_iterator(_RAIter __begin,
+ _RAIter _M_end, _Compare& __comp)
+ : _M_current(__begin), __comp(__comp)
{ }
/** @brief Pre-increment operator.
* @return This. */
- unguarded_iterator<RandomAccessIterator, Comparator>&
+ unguarded_iterator<_RAIter, _Compare>&
operator++()
{
- ++current;
+ ++_M_current;
return *this;
}
/** @brief Dereference operator.
* @return Referenced element. */
- typename std::iterator_traits<RandomAccessIterator>::value_type&
+ typename std::iterator_traits<_RAIter>::value_type&
operator*()
- { return *current; }
+ { return *_M_current; }
/** @brief Convert to wrapped iterator.
* @return Wrapped iterator. */
- operator RandomAccessIterator()
- { return current; }
+ operator _RAIter()
+ { return _M_current; }
friend bool
- operator< <RandomAccessIterator, Comparator>(
- unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
- unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
+ operator< <_RAIter, _Compare>(
+ unguarded_iterator<_RAIter, _Compare>& __bi1,
+ unguarded_iterator<_RAIter, _Compare>& __bi2);
friend bool
- operator<= <RandomAccessIterator, Comparator>(
- unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
- unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
+ operator<= <_RAIter, _Compare>(
+ unguarded_iterator<_RAIter, _Compare>& __bi1,
+ unguarded_iterator<_RAIter, _Compare>& __bi2);
};
/** @brief Compare two elements referenced by unguarded iterators.
- * @param bi1 First iterator.
- * @param bi2 Second iterator.
- * @return @c True if less. */
-template<typename RandomAccessIterator, typename Comparator>
+ * @param __bi1 First iterator.
+ * @param __bi2 Second iterator.
+ * @return @__c true if less. */
+template<typename _RAIter, typename _Compare>
inline bool
- operator<(unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
- unguarded_iterator<RandomAccessIterator, Comparator>& bi2)
+ operator<(unguarded_iterator<_RAIter, _Compare>& __bi1,
+ unguarded_iterator<_RAIter, _Compare>& __bi2)
{
// Normal compare.
- return (bi1.comp)(*bi1, *bi2);
+ return (__bi1.__comp)(*__bi1, *__bi2);
}
/** @brief Compare two elements referenced by unguarded iterators.
- * @param bi1 First iterator.
- * @param bi2 Second iterator.
- * @return @c True if less equal. */
-template<typename RandomAccessIterator, typename Comparator>
+ * @param __bi1 First iterator.
+ * @param __bi2 Second iterator.
+ * @return @__c True if less equal. */
+template<typename _RAIter, typename _Compare>
inline bool
- operator<=(unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
- unguarded_iterator<RandomAccessIterator, Comparator>& bi2)
+ operator<=(unguarded_iterator<_RAIter, _Compare>& __bi1,
+ unguarded_iterator<_RAIter, _Compare>& __bi2)
{
// Normal compare.
- return !(bi1.comp)(*bi2, *bi1);
+ return !(__bi1.__comp)(*__bi2, *__bi1);
}
/** @brief Highly efficient 3-way merging procedure.
*
* Merging is done with the algorithm implementation described by Peter
* Sanders. Basically, the idea is to minimize the number of necessary
- * comparison after merging out an element. The implementation trick
+ * comparison after merging an element. The implementation trick
* that makes this fast is that the order of the sequences is stored
* in the instruction pointer (translated into labels in C++).
*
* This works well for merging up to 4 sequences.
*
- * Note that making the merging stable does <em>not</em> come at a
+ * Note that making the merging stable does <em>not</em> come at __a
* performance hit.
*
* Whether the merging is done guarded or unguarded is selected by the
* used iterator class.
*
- * @param seqs_begin Begin iterator of iterator pair input sequence.
- * @param seqs_end End iterator of iterator pair input sequence.
- * @param target Begin iterator out output sequence.
- * @param comp Comparator.
- * @param length Maximum length to merge, less equal than the
+ * @param __seqs_begin Begin iterator of iterator pair input sequence.
+ * @param __seqs_end End iterator of iterator pair input sequence.
+ * @param __target Begin iterator of __output sequence.
+ * @param __comp Comparator.
+ * @param __length Maximum length to merge, less equal than the
* total number of elements available.
*
* @return End iterator of output sequence.
*/
template<template<typename RAI, typename C> class iterator,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
- RandomAccessIterator3
+ typename _RAIterIterator,
+ typename _RAIter3,
+ typename _DifferenceTp,
+ typename _Compare>
+ _RAIter3
multiway_merge_3_variant(
- RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
- _DifferenceTp length, Comparator comp)
+ _RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _RAIter3 __target,
+ _DifferenceTp __length, _Compare __comp)
{
- _GLIBCXX_CALL(length);
+ _GLIBCXX_CALL(__length);
- typedef _DifferenceTp difference_type;
+ typedef _DifferenceTp _DifferenceType;
- typedef typename std::iterator_traits<RandomAccessIteratorIterator>
+ typedef typename std::iterator_traits<_RAIterIterator>
::value_type::first_type
- RandomAccessIterator1;
- typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
- value_type;
+ _RAIter1;
+ typedef typename std::iterator_traits<_RAIter1>::value_type
+ _ValueType;
- if (length == 0)
- return target;
+ if (__length == 0)
+ return __target;
#if _GLIBCXX_ASSERTIONS
- _DifferenceTp orig_length = length;
+ _DifferenceTp orig_length = __length;
#endif
- iterator<RandomAccessIterator1, Comparator>
- seq0(seqs_begin[0].first, seqs_begin[0].second, comp),
- seq1(seqs_begin[1].first, seqs_begin[1].second, comp),
- seq2(seqs_begin[2].first, seqs_begin[2].second, comp);
+ iterator<_RAIter1, _Compare>
+ __seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp),
+ __seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp),
+ __seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp);
- if (seq0 <= seq1)
+ if (__seq0 <= __seq1)
{
- if (seq1 <= seq2)
- goto s012;
+ if (__seq1 <= __seq2)
+ goto __s012;
else
- if (seq2 < seq0)
- goto s201;
+ if (__seq2 < __seq0)
+ goto __s201;
else
- goto s021;
+ goto __s021;
}
else
{
- if (seq1 <= seq2)
+ if (__seq1 <= __seq2)
{
- if (seq0 <= seq2)
- goto s102;
+ if (__seq0 <= __seq2)
+ goto __s102;
else
- goto s120;
+ goto __s120;
}
else
- goto s210;
+ goto __s210;
}
-#define _GLIBCXX_PARALLEL_MERGE_3_CASE(a,b,c,c0,c1) \
- s ## a ## b ## c : \
- *target = *seq ## a; \
- ++target; \
- --length; \
- ++seq ## a; \
- if (length == 0) goto finish; \
- if (seq ## a c0 seq ## b) goto s ## a ## b ## c; \
- if (seq ## a c1 seq ## c) goto s ## b ## a ## c; \
- goto s ## b ## c ## a;
+#define _GLIBCXX_PARALLEL_MERGE_3_CASE(__a,__b,__c,c0,c1) \
+ __s ## __a ## __b ## __c : \
+ *__target = *__seq ## __a; \
+ ++__target; \
+ --__length; \
+ ++__seq ## __a; \
+ if (__length == 0) goto finish; \
+ if (__seq ## __a c0 __seq ## __b) goto __s ## __a ## __b ## __c; \
+ if (__seq ## __a c1 __seq ## __c) goto __s ## __b ## __a ## __c; \
+ goto __s ## __b ## __c ## __a;
_GLIBCXX_PARALLEL_MERGE_3_CASE(0, 1, 2, <=, <=);
_GLIBCXX_PARALLEL_MERGE_3_CASE(1, 2, 0, <=, < );
@@ -362,17 +362,17 @@ template<template<typename RAI, typename C> class iterator,
#if _GLIBCXX_ASSERTIONS
_GLIBCXX_PARALLEL_ASSERT(
- ((RandomAccessIterator1)seq0 - seqs_begin[0].first) +
- ((RandomAccessIterator1)seq1 - seqs_begin[1].first) +
- ((RandomAccessIterator1)seq2 - seqs_begin[2].first)
+ ((_RAIter1)__seq0 - __seqs_begin[0].first) +
+ ((_RAIter1)__seq1 - __seqs_begin[1].first) +
+ ((_RAIter1)__seq2 - __seqs_begin[2].first)
== orig_length);
#endif
- seqs_begin[0].first = seq0;
- seqs_begin[1].first = seq1;
- seqs_begin[2].first = seq2;
+ __seqs_begin[0].first = __seq0;
+ __seqs_begin[1].first = __seq1;
+ __seqs_begin[2].first = __seq2;
- return target;
+ return __target;
}
/**
@@ -380,74 +380,74 @@ template<template<typename RAI, typename C> class iterator,
*
* Merging is done with the algorithm implementation described by Peter
* Sanders. Basically, the idea is to minimize the number of necessary
- * comparison after merging out an element. The implementation trick
+ * comparison after merging an element. The implementation trick
* that makes this fast is that the order of the sequences is stored
* in the instruction pointer (translated into goto labels in C++).
*
* This works well for merging up to 4 sequences.
*
- * Note that making the merging stable does <em>not</em> come at a
+ * Note that making the merging stable does <em>not</em> come at __a
* performance hit.
*
* Whether the merging is done guarded or unguarded is selected by the
* used iterator class.
*
- * @param seqs_begin Begin iterator of iterator pair input sequence.
- * @param seqs_end End iterator of iterator pair input sequence.
- * @param target Begin iterator out output sequence.
- * @param comp Comparator.
- * @param length Maximum length to merge, less equal than the
+ * @param __seqs_begin Begin iterator of iterator pair input sequence.
+ * @param __seqs_end End iterator of iterator pair input sequence.
+ * @param __target Begin iterator of __output sequence.
+ * @param __comp Comparator.
+ * @param __length Maximum length to merge, less equal than the
* total number of elements available.
*
* @return End iterator of output sequence.
*/
template<template<typename RAI, typename C> class iterator,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
- RandomAccessIterator3
- multiway_merge_4_variant(RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
- _DifferenceTp length, Comparator comp)
+ typename _RAIterIterator,
+ typename _RAIter3,
+ typename _DifferenceTp,
+ typename _Compare>
+ _RAIter3
+ multiway_merge_4_variant(_RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _RAIter3 __target,
+ _DifferenceTp __length, _Compare __comp)
{
- _GLIBCXX_CALL(length);
- typedef _DifferenceTp difference_type;
+ _GLIBCXX_CALL(__length);
+ typedef _DifferenceTp _DifferenceType;
- typedef typename std::iterator_traits<RandomAccessIteratorIterator>
+ typedef typename std::iterator_traits<_RAIterIterator>
::value_type::first_type
- RandomAccessIterator1;
- typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
- value_type;
-
- iterator<RandomAccessIterator1, Comparator>
- seq0(seqs_begin[0].first, seqs_begin[0].second, comp),
- seq1(seqs_begin[1].first, seqs_begin[1].second, comp),
- seq2(seqs_begin[2].first, seqs_begin[2].second, comp),
- seq3(seqs_begin[3].first, seqs_begin[3].second, comp);
-
-#define _GLIBCXX_PARALLEL_DECISION(a,b,c,d) { \
- if (seq ## d < seq ## a) goto s ## d ## a ## b ## c; \
- if (seq ## d < seq ## b) goto s ## a ## d ## b ## c; \
- if (seq ## d < seq ## c) goto s ## a ## b ## d ## c; \
- goto s ## a ## b ## c ## d; }
-
- if (seq0 <= seq1)
+ _RAIter1;
+ typedef typename std::iterator_traits<_RAIter1>::value_type
+ _ValueType;
+
+ iterator<_RAIter1, _Compare>
+ __seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp),
+ __seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp),
+ __seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp),
+ __seq3(__seqs_begin[3].first, __seqs_begin[3].second, __comp);
+
+#define _GLIBCXX_PARALLEL_DECISION(__a,__b,__c,d) { \
+ if (__seq ## d < __seq ## __a) goto __s ## d ## __a ## __b ## __c; \
+ if (__seq ## d < __seq ## __b) goto __s ## __a ## d ## __b ## __c; \
+ if (__seq ## d < __seq ## __c) goto __s ## __a ## __b ## d ## __c; \
+ goto __s ## __a ## __b ## __c ## d; }
+
+ if (__seq0 <= __seq1)
{
- if (seq1 <= seq2)
+ if (__seq1 <= __seq2)
_GLIBCXX_PARALLEL_DECISION(0,1,2,3)
else
- if (seq2 < seq0)
+ if (__seq2 < __seq0)
_GLIBCXX_PARALLEL_DECISION(2,0,1,3)
else
_GLIBCXX_PARALLEL_DECISION(0,2,1,3)
}
else
{
- if (seq1 <= seq2)
+ if (__seq1 <= __seq2)
{
- if (seq0 <= seq2)
+ if (__seq0 <= __seq2)
_GLIBCXX_PARALLEL_DECISION(1,0,2,3)
else
_GLIBCXX_PARALLEL_DECISION(1,2,0,3)
@@ -456,17 +456,17 @@ template<template<typename RAI, typename C> class iterator,
_GLIBCXX_PARALLEL_DECISION(2,1,0,3)
}
-#define _GLIBCXX_PARALLEL_MERGE_4_CASE(a,b,c,d,c0,c1,c2) \
- s ## a ## b ## c ## d: \
- if (length == 0) goto finish; \
- *target = *seq ## a; \
- ++target; \
- --length; \
- ++seq ## a; \
- if (seq ## a c0 seq ## b) goto s ## a ## b ## c ## d; \
- if (seq ## a c1 seq ## c) goto s ## b ## a ## c ## d; \
- if (seq ## a c2 seq ## d) goto s ## b ## c ## a ## d; \
- goto s ## b ## c ## d ## a;
+#define _GLIBCXX_PARALLEL_MERGE_4_CASE(__a,__b,__c,d,c0,c1,c2) \
+ __s ## __a ## __b ## __c ## d: \
+ if (__length == 0) goto finish; \
+ *__target = *__seq ## __a; \
+ ++__target; \
+ --__length; \
+ ++__seq ## __a; \
+ if (__seq ## __a c0 __seq ## __b) goto __s ## __a ## __b ## __c ## d; \
+ if (__seq ## __a c1 __seq ## __c) goto __s ## __b ## __a ## __c ## d; \
+ if (__seq ## __a c2 __seq ## d) goto __s ## __b ## __c ## __a ## d; \
+ goto __s ## __b ## __c ## d ## __a;
_GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 2, 3, <=, <=, <=);
_GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 3, 2, <=, <=, <=);
@@ -499,94 +499,94 @@ template<template<typename RAI, typename C> class iterator,
finish:
;
- seqs_begin[0].first = seq0;
- seqs_begin[1].first = seq1;
- seqs_begin[2].first = seq2;
- seqs_begin[3].first = seq3;
+ __seqs_begin[0].first = __seq0;
+ __seqs_begin[1].first = __seq1;
+ __seqs_begin[2].first = __seq2;
+ __seqs_begin[3].first = __seq3;
- return target;
+ return __target;
}
/** @brief Multi-way merging procedure for a high branching factor,
* guarded case.
*
- * This merging variant uses a LoserTree class as selected by <tt>LT</tt>.
+ * This merging variant uses __a LoserTree class as selected by <tt>LT</tt>.
*
* Stability is selected through the used LoserTree class <tt>LT</tt>.
*
- * At least one non-empty sequence is required.
+ * At least one non-empty __sequence is required.
*
- * @param seqs_begin Begin iterator of iterator pair input sequence.
- * @param seqs_end End iterator of iterator pair input sequence.
- * @param target Begin iterator out output sequence.
- * @param comp Comparator.
- * @param length Maximum length to merge, less equal than the
+ * @param __seqs_begin Begin iterator of iterator pair input sequence.
+ * @param __seqs_end End iterator of iterator pair input sequence.
+ * @param __target Begin iterator of __output sequence.
+ * @param __comp Comparator.
+ * @param __length Maximum length to merge, less equal than the
* total number of elements available.
*
* @return End iterator of output sequence.
*/
template<typename LT,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
- RandomAccessIterator3
- multiway_merge_loser_tree(RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
- _DifferenceTp length, Comparator comp)
+ typename _RAIterIterator,
+ typename _RAIter3,
+ typename _DifferenceTp,
+ typename _Compare>
+ _RAIter3
+ multiway_merge_loser_tree(_RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _RAIter3 __target,
+ _DifferenceTp __length, _Compare __comp)
{
- _GLIBCXX_CALL(length)
+ _GLIBCXX_CALL(__length)
- typedef _DifferenceTp difference_type;
- typedef typename std::iterator_traits<RandomAccessIteratorIterator>
+ typedef _DifferenceTp _DifferenceType;
+ typedef typename std::iterator_traits<_RAIterIterator>
::value_type::first_type
- RandomAccessIterator1;
- typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
- value_type;
+ _RAIter1;
+ typedef typename std::iterator_traits<_RAIter1>::value_type
+ _ValueType;
- int k = static_cast<int>(seqs_end - seqs_begin);
+ int __k = static_cast<int>(__seqs_end - __seqs_begin);
- LT lt(k, comp);
+ LT __lt(__k, __comp);
// Default value for potentially non-default-constructible types.
- value_type* arbitrary_element = NULL;
+ _ValueType* __arbitrary_element = NULL;
- for (int t = 0; t < k; ++t)
+ for (int __t = 0; __t < __k; ++__t)
{
- if(arbitrary_element == NULL
- && _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]) > 0)
- arbitrary_element = &(*seqs_begin[t].first);
+ if(__arbitrary_element == NULL
+ && _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__t]) > 0)
+ __arbitrary_element = &(*__seqs_begin[__t].first);
}
- for (int t = 0; t < k; ++t)
+ for (int __t = 0; __t < __k; ++__t)
{
- if (seqs_begin[t].first == seqs_begin[t].second)
- lt.insert_start(*arbitrary_element, t, true);
+ if (__seqs_begin[__t].first == __seqs_begin[__t].second)
+ __lt.__insert_start(*__arbitrary_element, __t, true);
else
- lt.insert_start(*seqs_begin[t].first, t, false);
+ __lt.__insert_start(*__seqs_begin[__t].first, __t, false);
}
- lt.init();
+ __lt.__init();
int source;
- for (difference_type i = 0; i < length; ++i)
+ for (_DifferenceType __i = 0; __i < __length; ++__i)
{
//take out
- source = lt.get_min_source();
+ source = __lt.__get_min_source();
- *(target++) = *(seqs_begin[source].first++);
+ *(__target++) = *(__seqs_begin[source].first++);
// Feed.
- if (seqs_begin[source].first == seqs_begin[source].second)
- lt.delete_min_insert(*arbitrary_element, true);
+ if (__seqs_begin[source].first == __seqs_begin[source].second)
+ __lt.__delete_min_insert(*__arbitrary_element, true);
else
// Replace from same source.
- lt.delete_min_insert(*seqs_begin[source].first, false);
+ __lt.__delete_min_insert(*__seqs_begin[source].first, false);
}
- return target;
+ return __target;
}
/** @brief Multi-way merging procedure for a high branching factor,
@@ -598,161 +598,162 @@ template<typename LT,
*
* @pre No input will run out of elements during the merge.
*
- * @param seqs_begin Begin iterator of iterator pair input sequence.
- * @param seqs_end End iterator of iterator pair input sequence.
- * @param target Begin iterator out output sequence.
- * @param comp Comparator.
- * @param length Maximum length to merge, less equal than the
+ * @param __seqs_begin Begin iterator of iterator pair input sequence.
+ * @param __seqs_end End iterator of iterator pair input sequence.
+ * @param __target Begin iterator of __output sequence.
+ * @param __comp Comparator.
+ * @param __length Maximum length to merge, less equal than the
* total number of elements available.
*
* @return End iterator of output sequence.
*/
template<typename LT,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp, typename Comparator>
- RandomAccessIterator3
+ typename _RAIterIterator,
+ typename _RAIter3,
+ typename _DifferenceTp, typename _Compare>
+ _RAIter3
multiway_merge_loser_tree_unguarded(
- RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
+ _RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _RAIter3 __target,
const typename std::iterator_traits<typename std::iterator_traits<
- RandomAccessIteratorIterator>::value_type::first_type>::value_type&
- sentinel,
- _DifferenceTp length,
- Comparator comp)
+ _RAIterIterator>::value_type::first_type>::value_type&
+ __sentinel,
+ _DifferenceTp __length,
+ _Compare __comp)
{
- _GLIBCXX_CALL(length)
- typedef _DifferenceTp difference_type;
+ _GLIBCXX_CALL(__length)
+ typedef _DifferenceTp _DifferenceType;
- typedef typename std::iterator_traits<RandomAccessIteratorIterator>
+ typedef typename std::iterator_traits<_RAIterIterator>
::value_type::first_type
- RandomAccessIterator1;
- typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
- value_type;
+ _RAIter1;
+ typedef typename std::iterator_traits<_RAIter1>::value_type
+ _ValueType;
- int k = seqs_end - seqs_begin;
+ int __k = __seqs_end - __seqs_begin;
- LT lt(k, sentinel, comp);
+ LT __lt(__k, __sentinel, __comp);
- for (int t = 0; t < k; ++t)
+ for (int __t = 0; __t < __k; ++__t)
{
#if _GLIBCXX_ASSERTIONS
- _GLIBCXX_PARALLEL_ASSERT(seqs_begin[t].first != seqs_begin[t].second);
+ _GLIBCXX_PARALLEL_ASSERT(__seqs_begin[__t].first
+ != __seqs_begin[__t].second);
#endif
- lt.insert_start(*seqs_begin[t].first, t, false);
+ __lt.__insert_start(*__seqs_begin[__t].first, __t, false);
}
- lt.init();
+ __lt.__init();
int source;
#if _GLIBCXX_ASSERTIONS
- difference_type i = 0;
+ _DifferenceType __i = 0;
#endif
- RandomAccessIterator3 target_end = target + length;
- while (target < target_end)
+ _RAIter3 __target_end = __target + __length;
+ while (__target < __target_end)
{
// Take out.
- source = lt.get_min_source();
+ source = __lt.__get_min_source();
#if _GLIBCXX_ASSERTIONS
- _GLIBCXX_PARALLEL_ASSERT(0 <= source && source < k);
- _GLIBCXX_PARALLEL_ASSERT(i == 0
- || !comp(*(seqs_begin[source].first), *(target - 1)));
+ _GLIBCXX_PARALLEL_ASSERT(0 <= source && source < __k);
+ _GLIBCXX_PARALLEL_ASSERT(__i == 0
+ || !__comp(*(__seqs_begin[source].first), *(__target - 1)));
#endif
// Feed.
- *(target++) = *(seqs_begin[source].first++);
+ *(__target++) = *(__seqs_begin[source].first++);
#if _GLIBCXX_ASSERTIONS
- ++i;
+ ++__i;
#endif
// Replace from same source.
- lt.delete_min_insert(*seqs_begin[source].first, false);
+ __lt.__delete_min_insert(*__seqs_begin[source].first, false);
}
- return target;
+ return __target;
}
/** @brief Multi-way merging procedure for a high branching factor,
* requiring sentinels to exist.
*
- * @param stable The value must the same as for the used LoserTrees.
- * @param UnguardedLoserTree Loser Tree variant to use for the unguarded
+ * @param __stable The value must the same as for the used LoserTrees.
+ * @param UnguardedLoserTree _Loser Tree variant to use for the unguarded
* merging.
- * @param GuardedLoserTree Loser Tree variant to use for the guarded
+ * @param GuardedLoserTree _Loser Tree variant to use for the guarded
* merging.
*
- * @param seqs_begin Begin iterator of iterator pair input sequence.
- * @param seqs_end End iterator of iterator pair input sequence.
- * @param target Begin iterator out output sequence.
- * @param comp Comparator.
- * @param length Maximum length to merge, less equal than the
+ * @param __seqs_begin Begin iterator of iterator pair input sequence.
+ * @param __seqs_end End iterator of iterator pair input sequence.
+ * @param __target Begin iterator of __output sequence.
+ * @param __comp Comparator.
+ * @param __length Maximum length to merge, less equal than the
* total number of elements available.
*
* @return End iterator of output sequence.
*/
template<
typename UnguardedLoserTree,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
+ typename _RAIterIterator,
+ typename _RAIter3,
typename _DifferenceTp,
- typename Comparator>
- RandomAccessIterator3
+ typename _Compare>
+ _RAIter3
multiway_merge_loser_tree_sentinel(
- RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
+ _RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _RAIter3 __target,
const typename std::iterator_traits<typename std::iterator_traits<
- RandomAccessIteratorIterator>::value_type::first_type>::value_type&
- sentinel,
- _DifferenceTp length,
- Comparator comp)
+ _RAIterIterator>::value_type::first_type>::value_type&
+ __sentinel,
+ _DifferenceTp __length,
+ _Compare __comp)
{
- _GLIBCXX_CALL(length)
+ _GLIBCXX_CALL(__length)
- typedef _DifferenceTp difference_type;
- typedef std::iterator_traits<RandomAccessIteratorIterator> traits_type;
- typedef typename std::iterator_traits<RandomAccessIteratorIterator>
+ typedef _DifferenceTp _DifferenceType;
+ typedef std::iterator_traits<_RAIterIterator> _TraitsType;
+ typedef typename std::iterator_traits<_RAIterIterator>
::value_type::first_type
- RandomAccessIterator1;
- typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
- value_type;
+ _RAIter1;
+ typedef typename std::iterator_traits<_RAIter1>::value_type
+ _ValueType;
- RandomAccessIterator3 target_end;
+ _RAIter3 __target_end;
- for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
- // Move the sequends end behind the sentinel spots. This has the
+ for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
+ // Move the sequends _M_end behind the sentinel spots. This has the
// effect that the sentinel appears to be within the sequence. Then,
// we can use the unguarded variant if we merge out as many
// non-sentinel elements as we have.
- ++((*s).second);
+ ++((*__s).second);
- target_end = multiway_merge_loser_tree_unguarded
+ __target_end = multiway_merge_loser_tree_unguarded
<UnguardedLoserTree>
- (seqs_begin, seqs_end, target, sentinel, length, comp);
+ (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
#if _GLIBCXX_ASSERTIONS
- _GLIBCXX_PARALLEL_ASSERT(target_end == target + length);
- _GLIBCXX_PARALLEL_ASSERT(is_sorted(target, target_end, comp));
+ _GLIBCXX_PARALLEL_ASSERT(__target_end == __target + __length);
+ _GLIBCXX_PARALLEL_ASSERT(__is_sorted(__target, __target_end, __comp));
#endif
// Restore the sequence ends so the sentinels are not contained in the
// sequence any more (see comment in loop above).
- for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
- --((*s).second);
+ for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
+ --((*__s).second);
- return target_end;
+ return __target_end;
}
/**
* @brief Traits for determining whether the loser tree should
* use pointers or copies.
*
- * The field "use_pointer" is used to determine whether to use pointers in
+ * The field "_M_use_pointer" is used to determine whether to use pointers in
* the loser trees or whether to copy the values into the loser tree.
*
* The default behavior is to use pointers if the data type is 4 times as
@@ -763,17 +764,17 @@ template<
* Example:
*
* template<>
- * struct loser_tree_traits<int>
- * { static const bool use_pointer = false; };
+ * struct _LoserTreeTraits<int>
+ * { static const bool _M_use_pointer = false; };
*
* template<>
- * struct loser_tree_traits<heavyweight_type>
- * { static const bool use_pointer = true; };
+ * struct _LoserTreeTraits<heavyweight_type>
+ * { static const bool _M_use_pointer = true; };
*
- * @param T type to give the loser tree traits for.
+ * @param _Tp type to give the loser tree traits for.
*/
-template <typename T>
-struct loser_tree_traits
+template <typename _Tp>
+struct _LoserTreeTraits
{
/**
* @brief True iff to use pointers instead of values in loser trees.
@@ -781,177 +782,178 @@ struct loser_tree_traits
* The default behavior is to use pointers if the data type is four
* times as big as the pointer to it.
*/
- static const bool use_pointer = (sizeof(T) > 4 * sizeof(T*));
+ static const bool _M_use_pointer = (sizeof(_Tp) > 4 * sizeof(_Tp*));
};
/**
- * @brief Switch for 3-way merging with sentinels turned off.
+ * @brief Switch for 3-way merging with __sentinels turned off.
*
* Note that 3-way merging is always stable!
*/
template<
- bool sentinels /*default == false*/,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
+ bool __sentinels /*default == false*/,
+ typename _RAIterIterator,
+ typename _RAIter3,
typename _DifferenceTp,
- typename Comparator>
-struct multiway_merge_3_variant_sentinel_switch
+ typename _Compare>
+struct __multiway_merge_3_variant_sentinel_switch
{
- RandomAccessIterator3 operator()(
- RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
- _DifferenceTp length, Comparator comp)
+ _RAIter3 operator()(
+ _RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _RAIter3 __target,
+ _DifferenceTp __length, _Compare __comp)
{
- return multiway_merge_3_variant<guarded_iterator>(
- seqs_begin, seqs_end, target, length, comp);
+ return multiway_merge_3_variant<_GuardedIterator>(
+ __seqs_begin, __seqs_end, __target, __length, __comp);
}
};
/**
- * @brief Switch for 3-way merging with sentinels turned on.
+ * @brief Switch for 3-way merging with __sentinels turned on.
*
* Note that 3-way merging is always stable!
*/
template<
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
+ typename _RAIterIterator,
+ typename _RAIter3,
typename _DifferenceTp,
- typename Comparator>
-struct multiway_merge_3_variant_sentinel_switch
- <true, RandomAccessIteratorIterator, RandomAccessIterator3,
- _DifferenceTp, Comparator>
+ typename _Compare>
+struct __multiway_merge_3_variant_sentinel_switch
+ <true, _RAIterIterator, _RAIter3,
+ _DifferenceTp, _Compare>
{
- RandomAccessIterator3 operator()(
- RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
- _DifferenceTp length, Comparator comp)
+ _RAIter3 operator()(
+ _RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _RAIter3 __target,
+ _DifferenceTp __length, _Compare __comp)
{
return multiway_merge_3_variant<unguarded_iterator>(
- seqs_begin, seqs_end, target, length, comp);
+ __seqs_begin, __seqs_end, __target, __length, __comp);
}
};
/**
- * @brief Switch for 4-way merging with sentinels turned off.
+ * @brief Switch for 4-way merging with __sentinels turned off.
*
* Note that 4-way merging is always stable!
*/
template<
- bool sentinels /*default == false*/,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
+ bool __sentinels /*default == false*/,
+ typename _RAIterIterator,
+ typename _RAIter3,
typename _DifferenceTp,
- typename Comparator>
-struct multiway_merge_4_variant_sentinel_switch
+ typename _Compare>
+struct __multiway_merge_4_variant_sentinel_switch
{
- RandomAccessIterator3 operator()(
- RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
- _DifferenceTp length, Comparator comp)
+ _RAIter3 operator()(
+ _RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _RAIter3 __target,
+ _DifferenceTp __length, _Compare __comp)
{
- return multiway_merge_4_variant<guarded_iterator>(
- seqs_begin, seqs_end, target, length, comp);
+ return multiway_merge_4_variant<_GuardedIterator>(
+ __seqs_begin, __seqs_end, __target, __length, __comp);
}
};
/**
- * @brief Switch for 4-way merging with sentinels turned on.
+ * @brief Switch for 4-way merging with __sentinels turned on.
*
* Note that 4-way merging is always stable!
*/
template<
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
+ typename _RAIterIterator,
+ typename _RAIter3,
typename _DifferenceTp,
- typename Comparator>
-struct multiway_merge_4_variant_sentinel_switch
- <true, RandomAccessIteratorIterator, RandomAccessIterator3,
- _DifferenceTp, Comparator>
+ typename _Compare>
+struct __multiway_merge_4_variant_sentinel_switch
+ <true, _RAIterIterator, _RAIter3,
+ _DifferenceTp, _Compare>
{
- RandomAccessIterator3 operator()(
- RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
- _DifferenceTp length, Comparator comp)
+ _RAIter3 operator()(
+ _RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _RAIter3 __target,
+ _DifferenceTp __length, _Compare __comp)
{
return multiway_merge_4_variant<unguarded_iterator>(
- seqs_begin, seqs_end, target, length, comp);
+ __seqs_begin, __seqs_end, __target, __length, __comp);
}
};
/**
- * @brief Switch for k-way merging with sentinels turned on.
+ * @brief Switch for k-way merging with __sentinels turned on.
*/
template<
- bool sentinels,
- bool stable,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
+ bool __sentinels,
+ bool __stable,
+ typename _RAIterIterator,
+ typename _RAIter3,
typename _DifferenceTp,
- typename Comparator>
-struct multiway_merge_k_variant_sentinel_switch
+ typename _Compare>
+struct __multiway_merge_k_variant_sentinel_switch
{
- RandomAccessIterator3 operator()(
- RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
+ _RAIter3 operator()(
+ _RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _RAIter3 __target,
const typename std::iterator_traits<typename std::iterator_traits<
- RandomAccessIteratorIterator>::value_type::first_type>::value_type&
- sentinel,
- _DifferenceTp length, Comparator comp)
+ _RAIterIterator>::value_type::first_type>::value_type&
+ __sentinel,
+ _DifferenceTp __length, _Compare __comp)
{
- typedef typename std::iterator_traits<RandomAccessIteratorIterator>
+ typedef typename std::iterator_traits<_RAIterIterator>
::value_type::first_type
- RandomAccessIterator1;
- typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
- value_type;
+ _RAIter1;
+ typedef typename std::iterator_traits<_RAIter1>::value_type
+ _ValueType;
return multiway_merge_loser_tree_sentinel<
typename __gnu_cxx::__conditional_type<
- loser_tree_traits<value_type>::use_pointer
- , LoserTreePointerUnguarded<stable, value_type, Comparator>
- , LoserTreeUnguarded<stable, value_type, Comparator>
- >::__type>(seqs_begin, seqs_end, target, sentinel, length, comp);
+ _LoserTreeTraits<_ValueType>::_M_use_pointer
+ , LoserTreePointerUnguarded<__stable, _ValueType, _Compare>
+ , _LoserTreeUnguarded<__stable, _ValueType, _Compare>
+ >::__type>(
+ __seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
}
};
/**
- * @brief Switch for k-way merging with sentinels turned off.
+ * @brief Switch for k-way merging with __sentinels turned off.
*/
template<
- bool stable,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
+ bool __stable,
+ typename _RAIterIterator,
+ typename _RAIter3,
typename _DifferenceTp,
- typename Comparator>
-struct multiway_merge_k_variant_sentinel_switch
- <false, stable, RandomAccessIteratorIterator, RandomAccessIterator3,
- _DifferenceTp, Comparator>
+ typename _Compare>
+struct __multiway_merge_k_variant_sentinel_switch
+ <false, __stable, _RAIterIterator, _RAIter3,
+ _DifferenceTp, _Compare>
{
- RandomAccessIterator3 operator()(
- RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
+ _RAIter3 operator()(
+ _RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _RAIter3 __target,
const typename std::iterator_traits<typename std::iterator_traits<
- RandomAccessIteratorIterator>::value_type::first_type>::value_type&
- sentinel,
- _DifferenceTp length, Comparator comp)
+ _RAIterIterator>::value_type::first_type>::value_type&
+ __sentinel,
+ _DifferenceTp __length, _Compare __comp)
{
- typedef typename std::iterator_traits<RandomAccessIteratorIterator>
+ typedef typename std::iterator_traits<_RAIterIterator>
::value_type::first_type
- RandomAccessIterator1;
- typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
- value_type;
+ _RAIter1;
+ typedef typename std::iterator_traits<_RAIter1>::value_type
+ _ValueType;
return multiway_merge_loser_tree<
typename __gnu_cxx::__conditional_type<
- loser_tree_traits<value_type>::use_pointer
- , LoserTreePointer<stable, value_type, Comparator>
- , LoserTree<stable, value_type, Comparator>
- >::__type >(seqs_begin, seqs_end, target, length, comp);
+ _LoserTreeTraits<_ValueType>::_M_use_pointer
+ , _LoserTreePointer<__stable, _ValueType, _Compare>
+ , _LoserTree<__stable, _ValueType, _Compare>
+ >::__type >(__seqs_begin, __seqs_end, __target, __length, __comp);
}
};
@@ -959,108 +961,111 @@ struct multiway_merge_k_variant_sentinel_switch
*
* The _GLIBCXX_PARALLEL_DECISION is based on the branching factor and
* runtime settings.
- * @param seqs_begin Begin iterator of iterator pair input sequence.
- * @param seqs_end End iterator of iterator pair input sequence.
- * @param target Begin iterator out output sequence.
- * @param comp Comparator.
- * @param length Maximum length to merge, possibly larger than the
+ * @param __seqs_begin Begin iterator of iterator pair input sequence.
+ * @param __seqs_end End iterator of iterator pair input sequence.
+ * @param __target Begin iterator of __output sequence.
+ * @param __comp Comparator.
+ * @param __length Maximum length to merge, possibly larger than the
* number of elements available.
- * @param stable Stable merging incurs a performance penalty.
- * @param sentinel The sequences have a sentinel element.
+ * @param __stable Stable merging incurs __a performance penalty.
+ * @param __sentinel The sequences have __a __sentinel element.
* @return End iterator of output sequence. */
template<
- bool stable,
- bool sentinels,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
+ bool __stable,
+ bool __sentinels,
+ typename _RAIterIterator,
+ typename _RAIter3,
typename _DifferenceTp,
- typename Comparator>
- RandomAccessIterator3
- sequential_multiway_merge(
- RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
+ typename _Compare>
+ _RAIter3
+ __sequential_multiway_merge(
+ _RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _RAIter3 __target,
const typename std::iterator_traits<typename std::iterator_traits<
- RandomAccessIteratorIterator>::value_type::first_type>::value_type&
- sentinel,
- _DifferenceTp length, Comparator comp)
+ _RAIterIterator>::value_type::first_type>::value_type&
+ __sentinel,
+ _DifferenceTp __length, _Compare __comp)
{
- _GLIBCXX_CALL(length)
+ _GLIBCXX_CALL(__length)
- typedef _DifferenceTp difference_type;
- typedef typename std::iterator_traits<RandomAccessIteratorIterator>
+ typedef _DifferenceTp _DifferenceType;
+ typedef typename std::iterator_traits<_RAIterIterator>
::value_type::first_type
- RandomAccessIterator1;
- typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
- value_type;
+ _RAIter1;
+ typedef typename std::iterator_traits<_RAIter1>::value_type
+ _ValueType;
#if _GLIBCXX_ASSERTIONS
- for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
+ for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
{
- _GLIBCXX_PARALLEL_ASSERT(is_sorted((*s).first, (*s).second, comp));
+ _GLIBCXX_PARALLEL_ASSERT(
+ __is_sorted((*__s).first, (*__s).second, __comp));
}
#endif
- _DifferenceTp total_length = 0;
- for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
- total_length += _GLIBCXX_PARALLEL_LENGTH(*s);
+ _DifferenceTp __total_length = 0;
+ for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
+ __total_length += _GLIBCXX_PARALLEL_LENGTH(*__s);
- length = std::min<_DifferenceTp>(length, total_length);
+ __length = std::min<_DifferenceTp>(__length, __total_length);
- if(length == 0)
- return target;
+ if(__length == 0)
+ return __target;
- RandomAccessIterator3 return_target = target;
- int k = static_cast<int>(seqs_end - seqs_begin);
+ _RAIter3 __return_target = __target;
+ int __k = static_cast<int>(__seqs_end - __seqs_begin);
- switch (k)
+ switch (__k)
{
case 0:
break;
case 1:
- return_target = std::copy(seqs_begin[0].first,
- seqs_begin[0].first + length,
- target);
- seqs_begin[0].first += length;
+ __return_target = std::copy(__seqs_begin[0].first,
+ __seqs_begin[0].first + __length,
+ __target);
+ __seqs_begin[0].first += __length;
break;
case 2:
- return_target = merge_advance(seqs_begin[0].first,
- seqs_begin[0].second,
- seqs_begin[1].first,
- seqs_begin[1].second,
- target, length, comp);
+ __return_target = __merge_advance(__seqs_begin[0].first,
+ __seqs_begin[0].second,
+ __seqs_begin[1].first,
+ __seqs_begin[1].second,
+ __target, __length, __comp);
break;
case 3:
- return_target = multiway_merge_3_variant_sentinel_switch<
- sentinels
- , RandomAccessIteratorIterator
- , RandomAccessIterator3
+ __return_target = __multiway_merge_3_variant_sentinel_switch<
+ __sentinels
+ , _RAIterIterator
+ , _RAIter3
, _DifferenceTp
- , Comparator>()(seqs_begin, seqs_end, target, length, comp);
+ , _Compare>()(__seqs_begin, __seqs_end, __target, __length, __comp);
break;
case 4:
- return_target = multiway_merge_4_variant_sentinel_switch<
- sentinels
- , RandomAccessIteratorIterator
- , RandomAccessIterator3
+ __return_target = __multiway_merge_4_variant_sentinel_switch<
+ __sentinels
+ , _RAIterIterator
+ , _RAIter3
, _DifferenceTp
- , Comparator>()(seqs_begin, seqs_end, target, length, comp);
+ , _Compare>()(__seqs_begin, __seqs_end, __target, __length, __comp);
break;
default:
- return_target = multiway_merge_k_variant_sentinel_switch<
- sentinels
- , stable
- , RandomAccessIteratorIterator
- , RandomAccessIterator3
+ __return_target = __multiway_merge_k_variant_sentinel_switch<
+ __sentinels
+ , __stable
+ , _RAIterIterator
+ , _RAIter3
, _DifferenceTp
- , Comparator>()(seqs_begin, seqs_end, target, sentinel, length, comp);
+ , _Compare>()(__seqs_begin, __seqs_end, __target, __sentinel,
+ __length, __comp);
break;
}
#if _GLIBCXX_ASSERTIONS
- _GLIBCXX_PARALLEL_ASSERT(is_sorted(target, target + length, comp));
+ _GLIBCXX_PARALLEL_ASSERT(
+ __is_sorted(__target, __target + __length, __comp));
#endif
- return return_target;
+ return __return_target;
}
/**
@@ -1068,104 +1073,105 @@ template<
*
* Used to reduce code instanciation in multiway_merge_sampling_splitting.
*/
-template<bool stable, class RandomAccessIterator, class StrictWeakOrdering>
-struct sampling_sorter
+template<bool __stable, class _RAIter, class _StrictWeakOrdering>
+struct _SamplingSorter
{
- void operator()(RandomAccessIterator first, RandomAccessIterator last,
- StrictWeakOrdering comp)
- { __gnu_sequential::stable_sort(first, last, comp); }
+ void operator()(_RAIter __first, _RAIter __last,
+ _StrictWeakOrdering __comp)
+ { __gnu_sequential::stable_sort(__first, __last, __comp); }
};
/**
- * @brief Non-stable sorting functor.
+ * @brief Non-__stable sorting functor.
*
* Used to reduce code instantiation in multiway_merge_sampling_splitting.
*/
-template<class RandomAccessIterator, class StrictWeakOrdering>
-struct sampling_sorter<false, RandomAccessIterator, StrictWeakOrdering>
+template<class _RAIter, class _StrictWeakOrdering>
+struct _SamplingSorter<false, _RAIter, _StrictWeakOrdering>
{
- void operator()(RandomAccessIterator first, RandomAccessIterator last,
- StrictWeakOrdering comp)
- { __gnu_sequential::sort(first, last, comp); }
+ void operator()(_RAIter __first, _RAIter __last,
+ _StrictWeakOrdering __comp)
+ { __gnu_sequential::sort(__first, __last, __comp); }
};
/**
* @brief Sampling based splitting for parallel multiway-merge routine.
*/
template<
- bool stable
- , typename RandomAccessIteratorIterator
- , typename Comparator
- , typename difference_type>
+ bool __stable
+ , typename _RAIterIterator
+ , typename _Compare
+ , typename _DifferenceType>
void multiway_merge_sampling_splitting(
- RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- difference_type length, difference_type total_length, Comparator comp,
- std::vector<std::pair<difference_type, difference_type> > *pieces)
+ _RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _DifferenceType __length, _DifferenceType __total_length, _Compare __comp,
+ std::vector<std::pair<_DifferenceType, _DifferenceType> > *__pieces)
{
- typedef typename std::iterator_traits<RandomAccessIteratorIterator>
+ typedef typename std::iterator_traits<_RAIterIterator>
::value_type::first_type
- RandomAccessIterator1;
- typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
- value_type;
+ _RAIter1;
+ typedef typename std::iterator_traits<_RAIter1>::value_type
+ _ValueType;
- // k sequences.
- int k = static_cast<int>(seqs_end - seqs_begin);
+ // __k sequences.
+ int __k = static_cast<int>(__seqs_end - __seqs_begin);
- int num_threads = omp_get_num_threads();
+ int __num_threads = omp_get_num_threads();
- difference_type num_samples =
- __gnu_parallel::_Settings::get().merge_oversampling * num_threads;
+ _DifferenceType __num_samples =
+ __gnu_parallel::_Settings::get().merge_oversampling * __num_threads;
- value_type* samples = static_cast<value_type*>(
- ::operator new(sizeof(value_type) * k * num_samples));
+ _ValueType* __samples = static_cast<_ValueType*>(
+ ::operator new(sizeof(_ValueType) * __k * __num_samples));
// Sample.
- for (int s = 0; s < k; ++s)
- for (difference_type i = 0; i < num_samples; ++i)
+ for (int __s = 0; __s < __k; ++__s)
+ for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
{
- difference_type sample_index =
- static_cast<difference_type>(
- _GLIBCXX_PARALLEL_LENGTH(seqs_begin[s])
- * (double(i + 1) / (num_samples + 1))
- * (double(length) / total_length));
- new(&(samples[s * num_samples + i]))
- value_type(seqs_begin[s].first[sample_index]);
+ _DifferenceType sample_index =
+ static_cast<_DifferenceType>(
+ _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__s])
+ * (double(__i + 1) / (__num_samples + 1))
+ * (double(__length) / __total_length));
+ new(&(__samples[__s * __num_samples + __i]))
+ _ValueType(__seqs_begin[__s].first[sample_index]);
}
// Sort stable or non-stable, depending on value of template parameter
- // "stable".
- sampling_sorter<stable, value_type*, Comparator>()(
- samples, samples + (num_samples * k), comp);
+ // "__stable".
+ _SamplingSorter<__stable, _ValueType*, _Compare>()(
+ __samples, __samples + (__num_samples * __k), __comp);
- for (int slab = 0; slab < num_threads; ++slab)
+ for (int __slab = 0; __slab < __num_threads; ++__slab)
// For each slab / processor.
- for (int seq = 0; seq < k; ++seq)
+ for (int __seq = 0; __seq < __k; ++__seq)
{
// For each sequence.
- if (slab > 0)
- pieces[slab][seq].first =
+ if (__slab > 0)
+ __pieces[__slab][__seq].first =
std::upper_bound(
- seqs_begin[seq].first,
- seqs_begin[seq].second,
- samples[num_samples * k * slab / num_threads],
- comp)
- - seqs_begin[seq].first;
+ __seqs_begin[__seq].first,
+ __seqs_begin[__seq].second,
+ __samples[__num_samples * __k * __slab / __num_threads],
+ __comp)
+ - __seqs_begin[__seq].first;
else
// Absolute beginning.
- pieces[slab][seq].first = 0;
- if ((slab + 1) < num_threads)
- pieces[slab][seq].second =
+ __pieces[__slab][__seq].first = 0;
+ if ((__slab + 1) < __num_threads)
+ __pieces[__slab][__seq].second =
std::upper_bound(
- seqs_begin[seq].first,
- seqs_begin[seq].second,
- samples[num_samples * k * (slab + 1) /
- num_threads], comp)
- - seqs_begin[seq].first;
+ __seqs_begin[__seq].first,
+ __seqs_begin[__seq].second,
+ __samples[__num_samples * __k * (__slab + 1) /
+ __num_threads], __comp)
+ - __seqs_begin[__seq].first;
else
// Absolute end.
- pieces[slab][seq].second = _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
+ __pieces[__slab][__seq].second
+ = _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]);
}
- ::operator delete(samples);
+ ::operator delete(__samples);
}
/**
@@ -1174,84 +1180,84 @@ void multiway_merge_sampling_splitting(
* None of the passed sequences may be empty.
*/
template<
- bool stable
- , typename RandomAccessIteratorIterator
- , typename Comparator
- , typename difference_type>
+ bool __stable
+ , typename _RAIterIterator
+ , typename _Compare
+ , typename _DifferenceType>
void multiway_merge_exact_splitting(
- RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- difference_type length, difference_type total_length, Comparator comp,
- std::vector<std::pair<difference_type, difference_type> > *pieces)
+ _RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _DifferenceType __length, _DifferenceType __total_length, _Compare __comp,
+ std::vector<std::pair<_DifferenceType, _DifferenceType> > *__pieces)
{
- typedef typename std::iterator_traits<RandomAccessIteratorIterator>
+ typedef typename std::iterator_traits<_RAIterIterator>
::value_type::first_type
- RandomAccessIterator1;
+ _RAIter1;
- const bool tight = (total_length == length);
+ const bool __tight = (__total_length == __length);
- // k sequences.
- const int k = static_cast<int>(seqs_end - seqs_begin);
+ // __k sequences.
+ const int __k = static_cast<int>(__seqs_end - __seqs_begin);
- const int num_threads = omp_get_num_threads();
+ const int __num_threads = omp_get_num_threads();
// (Settings::multiway_merge_splitting == __gnu_parallel::_Settings::EXACT).
- std::vector<RandomAccessIterator1>* offsets =
- new std::vector<RandomAccessIterator1>[num_threads];
+ std::vector<_RAIter1>* __offsets =
+ new std::vector<_RAIter1>[__num_threads];
std::vector<
- std::pair<RandomAccessIterator1, RandomAccessIterator1>
- > se(k);
+ std::pair<_RAIter1, _RAIter1>
+ > __se(__k);
- copy(seqs_begin, seqs_end, se.begin());
+ copy(__seqs_begin, __seqs_end, __se.begin());
- difference_type* borders =
- new difference_type[num_threads + 1];
- equally_split(length, num_threads, borders);
+ _DifferenceType* __borders =
+ new _DifferenceType[__num_threads + 1];
+ equally_split(__length, __num_threads, __borders);
- for (int s = 0; s < (num_threads - 1); ++s)
+ for (int __s = 0; __s < (__num_threads - 1); ++__s)
{
- offsets[s].resize(k);
+ __offsets[__s].resize(__k);
multiseq_partition(
- se.begin(), se.end(), borders[s + 1],
- offsets[s].begin(), comp);
+ __se.begin(), __se.end(), __borders[__s + 1],
+ __offsets[__s].begin(), __comp);
// Last one also needed and available.
- if (!tight)
+ if (!__tight)
{
- offsets[num_threads - 1].resize(k);
- multiseq_partition(se.begin(), se.end(),
- difference_type(length),
- offsets[num_threads - 1].begin(), comp);
+ __offsets[__num_threads - 1].resize(__k);
+ multiseq_partition(__se.begin(), __se.end(),
+ _DifferenceType(__length),
+ __offsets[__num_threads - 1].begin(), __comp);
}
}
+ delete[] __borders;
-
- for (int slab = 0; slab < num_threads; ++slab)
+ for (int __slab = 0; __slab < __num_threads; ++__slab)
{
// For each slab / processor.
- for (int seq = 0; seq < k; ++seq)
+ for (int __seq = 0; __seq < __k; ++__seq)
{
// For each sequence.
- if (slab == 0)
+ if (__slab == 0)
{
// Absolute beginning.
- pieces[slab][seq].first = 0;
+ __pieces[__slab][__seq].first = 0;
}
else
- pieces[slab][seq].first =
- pieces[slab - 1][seq].second;
- if (!tight || slab < (num_threads - 1))
- pieces[slab][seq].second =
- offsets[slab][seq] - seqs_begin[seq].first;
+ __pieces[__slab][__seq].first =
+ __pieces[__slab - 1][__seq].second;
+ if (!__tight || __slab < (__num_threads - 1))
+ __pieces[__slab][__seq].second =
+ __offsets[__slab][__seq] - __seqs_begin[__seq].first;
else
{
- // slab == num_threads - 1
- pieces[slab][seq].second =
- _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
+ // __slab == __num_threads - 1
+ __pieces[__slab][__seq].second =
+ _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]);
}
}
}
- delete[] offsets;
+ delete[] __offsets;
}
/** @brief Parallel multi-way merge routine.
@@ -1261,155 +1267,151 @@ void multiway_merge_exact_splitting(
*
* Must not be called if the number of sequences is 1.
*
- * @param Splitter functor to split input (either exact or sampling based)
+ * @param Splitter functor to split input (either __exact or sampling based)
*
- * @param seqs_begin Begin iterator of iterator pair input sequence.
- * @param seqs_end End iterator of iterator pair input sequence.
- * @param target Begin iterator out output sequence.
- * @param comp Comparator.
- * @param length Maximum length to merge, possibly larger than the
+ * @param __seqs_begin Begin iterator of iterator pair input sequence.
+ * @param __seqs_end End iterator of iterator pair input sequence.
+ * @param __target Begin iterator of __output sequence.
+ * @param __comp Comparator.
+ * @param __length Maximum length to merge, possibly larger than the
* number of elements available.
- * @param stable Stable merging incurs a performance penalty.
- * @param sentinel Ignored.
+ * @param __stable Stable merging incurs __a performance penalty.
+ * @param __sentinel Ignored.
* @return End iterator of output sequence.
*/
template<
- bool stable,
- bool sentinels,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
+ bool __stable,
+ bool __sentinels,
+ typename _RAIterIterator,
+ typename _RAIter3,
typename _DifferenceTp,
typename Splitter,
- typename Comparator
+ typename _Compare
>
- RandomAccessIterator3
- parallel_multiway_merge(RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
+ _RAIter3
+ parallel_multiway_merge(_RAIterIterator __seqs_begin,
+ _RAIterIterator __seqs_end,
+ _RAIter3 __target,
Splitter splitter,
- _DifferenceTp length,
- Comparator comp,
- thread_index_t num_threads)
+ _DifferenceTp __length,
+ _Compare __comp,
+ _ThreadIndex __num_threads)
{
#if _GLIBCXX_ASSERTIONS
- _GLIBCXX_PARALLEL_ASSERT(seqs_end - seqs_begin > 1);
+ _GLIBCXX_PARALLEL_ASSERT(__seqs_end - __seqs_begin > 1);
#endif
- _GLIBCXX_CALL(length)
+ _GLIBCXX_CALL(__length)
- typedef _DifferenceTp difference_type;
- typedef typename std::iterator_traits<RandomAccessIteratorIterator>
+ typedef _DifferenceTp _DifferenceType;
+ typedef typename std::iterator_traits<_RAIterIterator>
::value_type::first_type
- RandomAccessIterator1;
+ _RAIter1;
typedef typename
- std::iterator_traits<RandomAccessIterator1>::value_type value_type;
+ std::iterator_traits<_RAIter1>::value_type _ValueType;
// Leave only non-empty sequences.
- std::pair<RandomAccessIterator1, RandomAccessIterator1>* ne_seqs =
- static_cast<std::pair<RandomAccessIterator1, RandomAccessIterator1>*>(
- ::operator new(
- sizeof(std::pair<RandomAccessIterator1, RandomAccessIterator1>)
- * (seqs_end - seqs_begin)));
- int k = 0;
- difference_type total_length = 0;
- for (RandomAccessIteratorIterator raii = seqs_begin;
- raii != seqs_end; ++raii)
+ typedef std::pair<_RAIter1, _RAIter1> seq_type;
+ seq_type* __ne_seqs = new seq_type[__seqs_end - __seqs_begin];
+ int __k = 0;
+ _DifferenceType __total_length = 0;
+ for (_RAIterIterator __raii = __seqs_begin;
+ __raii != __seqs_end; ++__raii)
{
- _DifferenceTp seq_length = _GLIBCXX_PARALLEL_LENGTH(*raii);
- if(seq_length > 0)
+ _DifferenceTp __seq_length = _GLIBCXX_PARALLEL_LENGTH(*__raii);
+ if(__seq_length > 0)
{
- total_length += seq_length;
- //ne_seqs[k] = *raii;
- new(&(ne_seqs[k++]))
- std::pair<RandomAccessIterator1, RandomAccessIterator1>(*raii);
+ __total_length += __seq_length;
+ __ne_seqs[__k++] = *__raii;
}
}
- _GLIBCXX_CALL(total_length)
+ _GLIBCXX_CALL(__total_length)
- length = std::min<_DifferenceTp>(length, total_length);
+ __length = std::min<_DifferenceTp>(__length, __total_length);
- if (total_length == 0 || k == 0)
+ if (__total_length == 0 || __k == 0)
{
- ::operator delete(ne_seqs);
- return target;
+ delete[] __ne_seqs;
+ return __target;
}
- std::vector<std::pair<difference_type, difference_type> >* pieces;
+ std::vector<std::pair<_DifferenceType, _DifferenceType> >* __pieces;
- num_threads = static_cast<thread_index_t>
- (std::min<difference_type>(num_threads, total_length));
+ __num_threads = static_cast<_ThreadIndex>
+ (std::min<_DifferenceType>(__num_threads, __total_length));
-# pragma omp parallel num_threads (num_threads)
+# pragma omp parallel num_threads (__num_threads)
{
# pragma omp single
{
- num_threads = omp_get_num_threads();
- // Thread t will have to merge pieces[iam][0..k - 1]
- pieces = new std::vector<
- std::pair<difference_type, difference_type> >[num_threads];
- for (int s = 0; s < num_threads; ++s)
- pieces[s].resize(k);
-
- difference_type num_samples =
+ __num_threads = omp_get_num_threads();
+ // Thread __t will have to merge pieces[__iam][0..__k - 1]
+ __pieces = new std::vector<
+ std::pair<_DifferenceType, _DifferenceType> >[__num_threads];
+ for (int __s = 0; __s < __num_threads; ++__s)
+ __pieces[__s].resize(__k);
+
+ _DifferenceType __num_samples =
__gnu_parallel::_Settings::get().merge_oversampling *
- num_threads;
+ __num_threads;
- splitter(ne_seqs, ne_seqs + k, length, total_length,
- comp, pieces);
+ splitter(__ne_seqs, __ne_seqs + __k, __length, __total_length,
+ __comp, __pieces);
} //single
- thread_index_t iam = omp_get_thread_num();
+ _ThreadIndex __iam = omp_get_thread_num();
- difference_type target_position = 0;
+ _DifferenceType __target_position = 0;
- for (int c = 0; c < k; ++c)
- target_position += pieces[iam][c].first;
+ for (int __c = 0; __c < __k; ++__c)
+ __target_position += __pieces[__iam][__c].first;
- std::pair<RandomAccessIterator1, RandomAccessIterator1>* chunks
- = new std::pair<RandomAccessIterator1, RandomAccessIterator1>[k];
+ seq_type* __chunks = new seq_type[__k];
- for (int s = 0; s < k; ++s)
+ for (int __s = 0; __s < __k; ++__s)
{
- chunks[s] = std::make_pair(
- ne_seqs[s].first + pieces[iam][s].first,
- ne_seqs[s].first + pieces[iam][s].second);
+ __chunks[__s] = std::make_pair(
+ __ne_seqs[__s].first + __pieces[__iam][__s].first,
+ __ne_seqs[__s].first + __pieces[__iam][__s].second);
}
- if(length > target_position)
- sequential_multiway_merge<stable, sentinels>(
- chunks, chunks + k, target + target_position,
- *(seqs_begin->second), length - target_position, comp);
+ if(__length > __target_position)
+ __sequential_multiway_merge<__stable, __sentinels>(
+ __chunks, __chunks + __k, __target + __target_position,
+ *(__seqs_begin->second), __length - __target_position, __comp);
- delete[] chunks;
+ delete[] __chunks;
} // parallel
#if _GLIBCXX_ASSERTIONS
- _GLIBCXX_PARALLEL_ASSERT(is_sorted(target, target + length, comp));
+ _GLIBCXX_PARALLEL_ASSERT(
+ __is_sorted(__target, __target + __length, __comp));
#endif
- k = 0;
+ __k = 0;
// Update ends of sequences.
- for (RandomAccessIteratorIterator raii = seqs_begin;
- raii != seqs_end; ++raii)
+ for (_RAIterIterator __raii = __seqs_begin;
+ __raii != __seqs_end; ++__raii)
{
- _DifferenceTp length = _GLIBCXX_PARALLEL_LENGTH(*raii);
- if(length > 0)
- (*raii).first += pieces[num_threads - 1][k++].second;
+ _DifferenceTp __length = _GLIBCXX_PARALLEL_LENGTH(*__raii);
+ if(__length > 0)
+ (*__raii).first += __pieces[__num_threads - 1][__k++].second;
}
- delete[] pieces;
+ delete[] __pieces;
+ delete[] __ne_seqs;
- return target + length;
+ return __target + __length;
}
/**
* @brief Multiway Merge Frontend.
*
- * Merge the sequences specified by seqs_begin and seqs_end into
- * target. seqs_begin and seqs_end must point to a sequence of
+ * Merge the sequences specified by seqs_begin and __seqs_end into
+ * __target. __seqs_begin and __seqs_end must point to a sequence of
* pairs. These pairs must contain an iterator to the beginning
- * of a sequence in their first entry and an iterator the end of
+ * of a sequence in their first entry and an iterator the _M_end of
* the same sequence in their second entry.
*
* Ties are broken arbitrarily. See stable_multiway_merge for a variant
@@ -1432,16 +1434,16 @@ template<
*
* <pre>
* int sequences[10][10];
- * for (int i = 0; i < 10; ++i)
- * for (int j = 0; i < 10; ++j)
- * sequences[i][j] = j;
+ * for (int __i = 0; __i < 10; ++__i)
+ * for (int __j = 0; __i < 10; ++__j)
+ * sequences[__i][__j] = __j;
*
- * int out[33];
+ * int __out[33];
* std::vector<std::pair<int*> > seqs;
- * for (int i = 0; i < 10; ++i)
- * { seqs.push(std::make_pair<int*>(sequences[i], sequences[i] + 10)) }
+ * for (int __i = 0; __i < 10; ++__i)
+ * { seqs.push(std::make_pair<int*>(sequences[__i], sequences[__i] + 10)) }
*
- * multiway_merge(seqs.begin(), seqs.end(), target, std::less<int>(), 33);
+ * multiway_merge(seqs.begin(), seqs.end(), __target, std::less<int>(), 33);
* </pre>
*
* @see stable_multiway_merge
@@ -1450,331 +1452,340 @@ template<
* @pre Target must provide enough space to merge out length elements or
* the number of elements in all sequences, whichever is smaller.
*
- * @post [target, return value) contains merged elements from the
+ * @post [__target, return __value) contains merged __elements from the
* input sequences.
- * @post return value - target = min(length, number of elements in all
+ * @post return __value - __target = min(__length, number of elements in all
* sequences).
*
- * @param RandomAccessIteratorPairIterator iterator over sequence
+ * @param _RAIterPairIterator iterator over sequence
* of pairs of iterators
- * @param RandomAccessIteratorOut iterator over target sequence
+ * @param _RAIterOut iterator over target sequence
* @param _DifferenceTp difference type for the sequence
- * @param Comparator strict weak ordering type to compare elements
+ * @param _Compare strict weak ordering type to compare elements
* in sequences
*
- * @param seqs_begin begin of sequence sequence
- * @param seqs_end end of sequence sequence
- * @param target target sequence to merge to.
- * @param comp strict weak ordering to use for element comparison.
- * @param length Maximum length to merge, possibly larger than the
+ * @param __seqs_begin __begin of sequence __sequence
+ * @param __seqs_end _M_end of sequence __sequence
+ * @param __target target sequence to merge to.
+ * @param __comp strict weak ordering to use for element comparison.
+ * @param __length Maximum length to merge, possibly larger than the
* number of elements available.
*
- * @return end iterator of output sequence
+ * @return _M_end iterator of output sequence
*/
// multiway_merge
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-multiway_merge(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
+ , typename _Compare>
+_RAIterOut
+multiway_merge(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
, __gnu_parallel::sequential_tag)
{
- typedef _DifferenceTp difference_type;
- _GLIBCXX_CALL(seqs_end - seqs_begin)
+ typedef _DifferenceTp _DifferenceType;
+ _GLIBCXX_CALL(__seqs_end - __seqs_begin)
// catch special case: no sequences
- if (seqs_begin == seqs_end)
- return target;
+ if (__seqs_begin == __seqs_end)
+ return __target;
// Execute multiway merge *sequentially*.
- return sequential_multiway_merge
- </* stable = */ false, /* sentinels = */ false>
- (seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
+ return __sequential_multiway_merge
+ </* __stable = */ false, /* __sentinels = */ false>
+ (__seqs_begin, __seqs_end, __target,
+ *(__seqs_begin->second), __length, __comp);
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-multiway_merge(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , __gnu_parallel::exact_tag tag)
+ , typename _Compare>
+_RAIterOut
+multiway_merge(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , __gnu_parallel::exact_tag __tag)
{
- typedef _DifferenceTp difference_type;
- _GLIBCXX_CALL(seqs_end - seqs_begin)
+ typedef _DifferenceTp _DifferenceType;
+ _GLIBCXX_CALL(__seqs_end - __seqs_begin)
// catch special case: no sequences
- if (seqs_begin == seqs_end)
- return target;
+ if (__seqs_begin == __seqs_end)
+ return __target;
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
- if ((seqs_end - seqs_begin > 1) &&
+ if ((__seqs_end - __seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
- ((seqs_end - seqs_begin) >=
+ ((__seqs_end - __seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
- && ((sequence_index_t)length >=
+ && ((_SequenceIndex)__length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
return parallel_multiway_merge
- </* stable = */ false, /* sentinels = */ false>(
- seqs_begin, seqs_end, target,
- multiway_merge_exact_splitting</* stable = */ false,
- typename std::iterator_traits<RandomAccessIteratorPairIterator>
- ::value_type*, Comparator, _DifferenceTp>,
- static_cast<difference_type>(length), comp, tag.get_num_threads());
+ </* __stable = */ false, /* __sentinels = */ false>(
+ __seqs_begin, __seqs_end, __target,
+ multiway_merge_exact_splitting</* __stable = */ false,
+ typename std::iterator_traits<_RAIterPairIterator>
+ ::value_type*, _Compare, _DifferenceTp>,
+ static_cast<_DifferenceType>(__length), __comp,
+ __tag.__get_num_threads());
else
- return sequential_multiway_merge
- </* stable = */ false, /* sentinels = */ false>(
- seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
+ return __sequential_multiway_merge
+ </* __stable = */ false, /* __sentinels = */ false>(
+ __seqs_begin, __seqs_end, __target, *(__seqs_begin->second),
+ __length, __comp);
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-multiway_merge(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , __gnu_parallel::sampling_tag tag)
+ , typename _Compare>
+_RAIterOut
+multiway_merge(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , __gnu_parallel::sampling_tag __tag)
{
- typedef _DifferenceTp difference_type;
- _GLIBCXX_CALL(seqs_end - seqs_begin)
+ typedef _DifferenceTp _DifferenceType;
+ _GLIBCXX_CALL(__seqs_end - __seqs_begin)
// catch special case: no sequences
- if (seqs_begin == seqs_end)
- return target;
+ if (__seqs_begin == __seqs_end)
+ return __target;
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
- if ((seqs_end - seqs_begin > 1) &&
+ if ((__seqs_end - __seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
- ((seqs_end - seqs_begin) >=
+ ((__seqs_end - __seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
- && ((sequence_index_t)length >=
+ && ((_SequenceIndex)__length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
return parallel_multiway_merge
- </* stable = */ false, /* sentinels = */ false>(
- seqs_begin, seqs_end,
- target,
- multiway_merge_exact_splitting</* stable = */ false,
- typename std::iterator_traits<RandomAccessIteratorPairIterator>
- ::value_type*, Comparator, _DifferenceTp>,
- static_cast<difference_type>(length), comp, tag.get_num_threads());
+ </* __stable = */ false, /* __sentinels = */ false>(
+ __seqs_begin, __seqs_end,
+ __target,
+ multiway_merge_exact_splitting</* __stable = */ false,
+ typename std::iterator_traits<_RAIterPairIterator>
+ ::value_type*, _Compare, _DifferenceTp>,
+ static_cast<_DifferenceType>(__length), __comp,
+ __tag.__get_num_threads());
else
- return sequential_multiway_merge
- </* stable = */ false, /* sentinels = */ false>(
- seqs_begin, seqs_end,
- target, *(seqs_begin->second), length, comp);
+ return __sequential_multiway_merge
+ </* __stable = */ false, /* __sentinels = */ false>(
+ __seqs_begin, __seqs_end,
+ __target, *(__seqs_begin->second), __length, __comp);
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-multiway_merge(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , parallel_tag tag = parallel_tag(0))
+ , typename _Compare>
+_RAIterOut
+multiway_merge(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , parallel_tag __tag = parallel_tag(0))
{
- return multiway_merge(seqs_begin, seqs_end, target, length, comp,
- exact_tag(tag.get_num_threads()));
+ return multiway_merge(__seqs_begin, __seqs_end, __target, __length, __comp,
+ exact_tag(__tag.__get_num_threads()));
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-multiway_merge(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , default_parallel_tag tag)
+ , typename _Compare>
+_RAIterOut
+multiway_merge(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , default_parallel_tag __tag)
{
- return multiway_merge(seqs_begin, seqs_end, target, length, comp,
- exact_tag(tag.get_num_threads()));
+ return multiway_merge(__seqs_begin, __seqs_end, __target, __length, __comp,
+ exact_tag(__tag.__get_num_threads()));
}
// stable_multiway_merge
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
+ , typename _Compare>
+_RAIterOut
+stable_multiway_merge(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
, __gnu_parallel::sequential_tag)
{
- typedef _DifferenceTp difference_type;
- _GLIBCXX_CALL(seqs_end - seqs_begin)
+ typedef _DifferenceTp _DifferenceType;
+ _GLIBCXX_CALL(__seqs_end - __seqs_begin)
// catch special case: no sequences
- if (seqs_begin == seqs_end)
- return target;
+ if (__seqs_begin == __seqs_end)
+ return __target;
// Execute multiway merge *sequentially*.
- return sequential_multiway_merge
- </* stable = */ true, /* sentinels = */ false>
- (seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
+ return __sequential_multiway_merge
+ </* __stable = */ true, /* __sentinels = */ false>
+ (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length,
+ __comp);
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , __gnu_parallel::exact_tag tag)
+ , typename _Compare>
+_RAIterOut
+stable_multiway_merge(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , __gnu_parallel::exact_tag __tag)
{
- typedef _DifferenceTp difference_type;
- _GLIBCXX_CALL(seqs_end - seqs_begin)
+ typedef _DifferenceTp _DifferenceType;
+ _GLIBCXX_CALL(__seqs_end - __seqs_begin)
// catch special case: no sequences
- if (seqs_begin == seqs_end)
- return target;
+ if (__seqs_begin == __seqs_end)
+ return __target;
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
- if ((seqs_end - seqs_begin > 1) &&
+ if ((__seqs_end - __seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
- ((seqs_end - seqs_begin) >=
+ ((__seqs_end - __seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
- && ((sequence_index_t)length >=
+ && ((_SequenceIndex)__length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
return parallel_multiway_merge
- </* stable = */ true, /* sentinels = */ false>(
- seqs_begin, seqs_end,
- target,
- multiway_merge_exact_splitting</* stable = */ true,
- typename std::iterator_traits<RandomAccessIteratorPairIterator>
- ::value_type*, Comparator, _DifferenceTp>,
- static_cast<difference_type>(length), comp, tag.get_num_threads());
+ </* __stable = */ true, /* __sentinels = */ false>(
+ __seqs_begin, __seqs_end,
+ __target,
+ multiway_merge_exact_splitting</* __stable = */ true,
+ typename std::iterator_traits<_RAIterPairIterator>
+ ::value_type*, _Compare, _DifferenceTp>,
+ static_cast<_DifferenceType>(__length), __comp,
+ __tag.__get_num_threads());
else
- return sequential_multiway_merge</* stable = */ true,
- /* sentinels = */ false>(
- seqs_begin, seqs_end,
- target, *(seqs_begin->second), length, comp);
+ return __sequential_multiway_merge</* __stable = */ true,
+ /* __sentinels = */ false>(
+ __seqs_begin, __seqs_end,
+ __target, *(__seqs_begin->second), __length, __comp);
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , sampling_tag tag)
+ , typename _Compare>
+_RAIterOut
+stable_multiway_merge(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , sampling_tag __tag)
{
- typedef _DifferenceTp difference_type;
- _GLIBCXX_CALL(seqs_end - seqs_begin)
+ typedef _DifferenceTp _DifferenceType;
+ _GLIBCXX_CALL(__seqs_end - __seqs_begin)
// catch special case: no sequences
- if (seqs_begin == seqs_end)
- return target;
+ if (__seqs_begin == __seqs_end)
+ return __target;
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
- if ((seqs_end - seqs_begin > 1) &&
+ if ((__seqs_end - __seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
- ((seqs_end - seqs_begin) >=
+ ((__seqs_end - __seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
- && ((sequence_index_t)length >=
+ && ((_SequenceIndex)__length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
return parallel_multiway_merge
- </* stable = */ true, /* sentinels = */ false>(
- seqs_begin, seqs_end,
- target,
- multiway_merge_sampling_splitting</* stable = */ true,
- typename std::iterator_traits<RandomAccessIteratorPairIterator>
- ::value_type*, Comparator, _DifferenceTp>,
- static_cast<difference_type>(length), comp, tag.get_num_threads());
+ </* __stable = */ true, /* __sentinels = */ false>(
+ __seqs_begin, __seqs_end,
+ __target,
+ multiway_merge_sampling_splitting</* __stable = */ true,
+ typename std::iterator_traits<_RAIterPairIterator>
+ ::value_type*, _Compare, _DifferenceTp>,
+ static_cast<_DifferenceType>(__length), __comp,
+ __tag.__get_num_threads());
else
- return sequential_multiway_merge
- </* stable = */ true, /* sentinels = */ false>(
- seqs_begin, seqs_end,
- target, *(seqs_begin->second), length, comp);
+ return __sequential_multiway_merge
+ </* __stable = */ true, /* __sentinels = */ false>(
+ __seqs_begin, __seqs_end,
+ __target, *(__seqs_begin->second), __length, __comp);
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , parallel_tag tag = parallel_tag(0))
+ , typename _Compare>
+_RAIterOut
+stable_multiway_merge(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , parallel_tag __tag = parallel_tag(0))
{
- return stable_multiway_merge(seqs_begin, seqs_end, target, length, comp,
- exact_tag(tag.get_num_threads()));
+ return stable_multiway_merge(
+ __seqs_begin, __seqs_end, __target, __length, __comp,
+ exact_tag(__tag.__get_num_threads()));
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , default_parallel_tag tag)
+ , typename _Compare>
+_RAIterOut
+stable_multiway_merge(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , default_parallel_tag __tag)
{
- return stable_multiway_merge(seqs_begin, seqs_end, target, length, comp,
- exact_tag(tag.get_num_threads()));
+ return stable_multiway_merge(
+ __seqs_begin, __seqs_end, __target, __length, __comp,
+ exact_tag(__tag.__get_num_threads()));
}
/**
* @brief Multiway Merge Frontend.
*
- * Merge the sequences specified by seqs_begin and seqs_end into
- * target. seqs_begin and seqs_end must point to a sequence of
+ * Merge the sequences specified by seqs_begin and __seqs_end into
+ * __target. __seqs_begin and __seqs_end must point to a sequence of
* pairs. These pairs must contain an iterator to the beginning
- * of a sequence in their first entry and an iterator the end of
+ * of a sequence in their first entry and an iterator the _M_end of
* the same sequence in their second entry.
*
* Ties are broken arbitrarily. See stable_multiway_merge for a variant
@@ -1793,7 +1804,7 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
* - using sampling for splitting
* - using sentinels
*
- * You have to take care that the element the end iterator points to is
+ * You have to take care that the element the _M_end iterator points to is
* readable and contains a value that is greater than any other non-sentinel
* value in all sequences.
*
@@ -1801,343 +1812,353 @@ stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
*
* <pre>
* int sequences[10][11];
- * for (int i = 0; i < 10; ++i)
- * for (int j = 0; i < 11; ++j)
- * sequences[i][j] = j; // last one is sentinel!
+ * for (int __i = 0; __i < 10; ++__i)
+ * for (int __j = 0; __i < 11; ++__j)
+ * sequences[__i][__j] = __j; // __last one is sentinel!
*
- * int out[33];
+ * int __out[33];
* std::vector<std::pair<int*> > seqs;
- * for (int i = 0; i < 10; ++i)
- * { seqs.push(std::make_pair<int*>(sequences[i], sequences[i] + 10)) }
+ * for (int __i = 0; __i < 10; ++__i)
+ * { seqs.push(std::make_pair<int*>(sequences[__i], sequences[__i] + 10)) }
*
- * multiway_merge(seqs.begin(), seqs.end(), target, std::less<int>(), 33);
+ * multiway_merge(seqs.begin(), seqs.end(), __target, std::less<int>(), 33);
* </pre>
*
* @pre All input sequences must be sorted.
* @pre Target must provide enough space to merge out length elements or
* the number of elements in all sequences, whichever is smaller.
- * @pre For each @c i, @c seqs_begin[i].second must be the end
- * marker of the sequence, but also reference the one more sentinel
+ * @pre For each @__c __i, @__c __seqs_begin[__i].second must be the end
+ * marker of the sequence, but also reference the one more __sentinel
* element.
*
- * @post [target, return value) contains merged elements from the
+ * @post [__target, return __value) contains merged __elements from the
* input sequences.
- * @post return value - target = min(length, number of elements in all
+ * @post return __value - __target = min(__length, number of elements in all
* sequences).
*
* @see stable_multiway_merge_sentinels
*
- * @param RandomAccessIteratorPairIterator iterator over sequence
+ * @param _RAIterPairIterator iterator over sequence
* of pairs of iterators
- * @param RandomAccessIteratorOut iterator over target sequence
+ * @param _RAIterOut iterator over target sequence
* @param _DifferenceTp difference type for the sequence
- * @param Comparator strict weak ordering type to compare elements
+ * @param _Compare strict weak ordering type to compare elements
* in sequences
*
- * @param seqs_begin begin of sequence sequence
- * @param seqs_end end of sequence sequence
- * @param target target sequence to merge to.
- * @param comp strict weak ordering to use for element comparison.
- * @param length Maximum length to merge, possibly larger than the
+ * @param __seqs_begin __begin of sequence __sequence
+ * @param __seqs_end _M_end of sequence __sequence
+ * @param __target target sequence to merge to.
+ * @param __comp strict weak ordering to use for element comparison.
+ * @param __length Maximum length to merge, possibly larger than the
* number of elements available.
*
- * @return end iterator of output sequence
+ * @return _M_end iterator of output sequence
*/
// multiway_merge_sentinels
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
+ , typename _Compare>
+_RAIterOut
+multiway_merge_sentinels(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
, __gnu_parallel::sequential_tag)
{
- typedef _DifferenceTp difference_type;
- _GLIBCXX_CALL(seqs_end - seqs_begin)
+ typedef _DifferenceTp _DifferenceType;
+ _GLIBCXX_CALL(__seqs_end - __seqs_begin)
// catch special case: no sequences
- if (seqs_begin == seqs_end)
- return target;
+ if (__seqs_begin == __seqs_end)
+ return __target;
// Execute multiway merge *sequentially*.
- return sequential_multiway_merge
- </* stable = */ false, /* sentinels = */ true>
- (seqs_begin, seqs_end,
- target, *(seqs_begin->second), length, comp);
+ return __sequential_multiway_merge
+ </* __stable = */ false, /* __sentinels = */ true>
+ (__seqs_begin, __seqs_end,
+ __target, *(__seqs_begin->second), __length, __comp);
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , __gnu_parallel::exact_tag tag)
+ , typename _Compare>
+_RAIterOut
+multiway_merge_sentinels(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , __gnu_parallel::exact_tag __tag)
{
- typedef _DifferenceTp difference_type;
- _GLIBCXX_CALL(seqs_end - seqs_begin)
+ typedef _DifferenceTp _DifferenceType;
+ _GLIBCXX_CALL(__seqs_end - __seqs_begin)
// catch special case: no sequences
- if (seqs_begin == seqs_end)
- return target;
+ if (__seqs_begin == __seqs_end)
+ return __target;
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
- if ((seqs_end - seqs_begin > 1) &&
+ if ((__seqs_end - __seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
- ((seqs_end - seqs_begin) >=
+ ((__seqs_end - __seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
- && ((sequence_index_t)length >=
+ && ((_SequenceIndex)__length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
return parallel_multiway_merge
- </* stable = */ false, /* sentinels = */ true>(
- seqs_begin, seqs_end,
- target,
- multiway_merge_exact_splitting</* stable = */ false,
- typename std::iterator_traits<RandomAccessIteratorPairIterator>
- ::value_type*, Comparator, _DifferenceTp>,
- static_cast<difference_type>(length), comp, tag.get_num_threads());
+ </* __stable = */ false, /* __sentinels = */ true>(
+ __seqs_begin, __seqs_end,
+ __target,
+ multiway_merge_exact_splitting</* __stable = */ false,
+ typename std::iterator_traits<_RAIterPairIterator>
+ ::value_type*, _Compare, _DifferenceTp>,
+ static_cast<_DifferenceType>(__length), __comp,
+ __tag.__get_num_threads());
else
- return sequential_multiway_merge
- </* stable = */ false, /* sentinels = */ true>(
- seqs_begin, seqs_end,
- target, *(seqs_begin->second), length, comp);
+ return __sequential_multiway_merge
+ </* __stable = */ false, /* __sentinels = */ true>(
+ __seqs_begin, __seqs_end,
+ __target, *(__seqs_begin->second), __length, __comp);
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , sampling_tag tag)
+ , typename _Compare>
+_RAIterOut
+multiway_merge_sentinels(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , sampling_tag __tag)
{
- typedef _DifferenceTp difference_type;
- _GLIBCXX_CALL(seqs_end - seqs_begin)
+ typedef _DifferenceTp _DifferenceType;
+ _GLIBCXX_CALL(__seqs_end - __seqs_begin)
// catch special case: no sequences
- if (seqs_begin == seqs_end)
- return target;
+ if (__seqs_begin == __seqs_end)
+ return __target;
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
- if ((seqs_end - seqs_begin > 1) &&
+ if ((__seqs_end - __seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
- ((seqs_end - seqs_begin) >=
+ ((__seqs_end - __seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
- && ((sequence_index_t)length >=
+ && ((_SequenceIndex)__length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
return parallel_multiway_merge
- </* stable = */ false, /* sentinels = */ true>
- (seqs_begin, seqs_end, target,
- multiway_merge_sampling_splitting</* stable = */ false,
- typename std::iterator_traits<RandomAccessIteratorPairIterator>
- ::value_type*, Comparator, _DifferenceTp>,
- static_cast<difference_type>(length), comp, tag.get_num_threads());
+ </* __stable = */ false, /* __sentinels = */ true>
+ (__seqs_begin, __seqs_end, __target,
+ multiway_merge_sampling_splitting</* __stable = */ false,
+ typename std::iterator_traits<_RAIterPairIterator>
+ ::value_type*, _Compare, _DifferenceTp>,
+ static_cast<_DifferenceType>(__length), __comp,
+ __tag.__get_num_threads());
else
- return sequential_multiway_merge
- </* stable = */false, /* sentinels = */ true>(
- seqs_begin, seqs_end,
- target, *(seqs_begin->second), length, comp);
+ return __sequential_multiway_merge
+ </* __stable = */false, /* __sentinels = */ true>(
+ __seqs_begin, __seqs_end,
+ __target, *(__seqs_begin->second), __length, __comp);
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , parallel_tag tag = parallel_tag(0))
+ , typename _Compare>
+_RAIterOut
+multiway_merge_sentinels(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , parallel_tag __tag = parallel_tag(0))
{
- return multiway_merge_sentinels(seqs_begin, seqs_end, target, length, comp,
- exact_tag(tag.get_num_threads()));
+ return multiway_merge_sentinels(
+ __seqs_begin, __seqs_end, __target, __length, __comp,
+ exact_tag(__tag.__get_num_threads()));
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , default_parallel_tag tag)
+ , typename _Compare>
+_RAIterOut
+multiway_merge_sentinels(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , default_parallel_tag __tag)
{
- return multiway_merge_sentinels(seqs_begin, seqs_end, target, length, comp,
- exact_tag(tag.get_num_threads()));
+ return multiway_merge_sentinels(
+ __seqs_begin, __seqs_end, __target, __length, __comp,
+ exact_tag(__tag.__get_num_threads()));
}
// stable_multiway_merge_sentinels
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
+ , typename _Compare>
+_RAIterOut
+stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
, __gnu_parallel::sequential_tag)
{
- typedef _DifferenceTp difference_type;
- _GLIBCXX_CALL(seqs_end - seqs_begin)
+ typedef _DifferenceTp _DifferenceType;
+ _GLIBCXX_CALL(__seqs_end - __seqs_begin)
// catch special case: no sequences
- if (seqs_begin == seqs_end)
- return target;
+ if (__seqs_begin == __seqs_end)
+ return __target;
// Execute multiway merge *sequentially*.
- return sequential_multiway_merge
- </* stable = */ true, /* sentinels = */ true>
- (seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
+ return __sequential_multiway_merge
+ </* __stable = */ true, /* __sentinels = */ true>
+ (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length,
+ __comp);
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , __gnu_parallel::exact_tag tag)
+ , typename _Compare>
+_RAIterOut
+stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , __gnu_parallel::exact_tag __tag)
{
- typedef _DifferenceTp difference_type;
- _GLIBCXX_CALL(seqs_end - seqs_begin)
+ typedef _DifferenceTp _DifferenceType;
+ _GLIBCXX_CALL(__seqs_end - __seqs_begin)
// catch special case: no sequences
- if (seqs_begin == seqs_end)
- return target;
+ if (__seqs_begin == __seqs_end)
+ return __target;
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
- if ((seqs_end - seqs_begin > 1) &&
+ if ((__seqs_end - __seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
- ((seqs_end - seqs_begin) >=
+ ((__seqs_end - __seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
- && ((sequence_index_t)length >=
+ && ((_SequenceIndex)__length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
return parallel_multiway_merge
- </* stable = */ true, /* sentinels = */ true>(
- seqs_begin, seqs_end,
- target,
- multiway_merge_exact_splitting</* stable = */ true,
- typename std::iterator_traits<RandomAccessIteratorPairIterator>
- ::value_type*, Comparator, _DifferenceTp>,
- static_cast<difference_type>(length), comp, tag.get_num_threads());
+ </* __stable = */ true, /* __sentinels = */ true>(
+ __seqs_begin, __seqs_end,
+ __target,
+ multiway_merge_exact_splitting</* __stable = */ true,
+ typename std::iterator_traits<_RAIterPairIterator>
+ ::value_type*, _Compare, _DifferenceTp>,
+ static_cast<_DifferenceType>(__length), __comp,
+ __tag.__get_num_threads());
else
- return sequential_multiway_merge
- </* stable = */ true, /* sentinels = */ true>(
- seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
+ return __sequential_multiway_merge
+ </* __stable = */ true, /* __sentinels = */ true>(
+ __seqs_begin, __seqs_end, __target, *(__seqs_begin->second),
+ __length, __comp);
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , sampling_tag tag)
+ , typename _Compare>
+_RAIterOut
+stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , sampling_tag __tag)
{
- typedef _DifferenceTp difference_type;
- _GLIBCXX_CALL(seqs_end - seqs_begin)
+ typedef _DifferenceTp _DifferenceType;
+ _GLIBCXX_CALL(__seqs_end - __seqs_begin)
// catch special case: no sequences
- if (seqs_begin == seqs_end)
- return target;
+ if (__seqs_begin == __seqs_end)
+ return __target;
// Execute merge; maybe parallel, depending on the number of merged
// elements and the number of sequences and global thresholds in
// Settings.
- if ((seqs_end - seqs_begin > 1) &&
+ if ((__seqs_end - __seqs_begin > 1) &&
_GLIBCXX_PARALLEL_CONDITION(
- ((seqs_end - seqs_begin) >=
+ ((__seqs_end - __seqs_begin) >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_k)
- && ((sequence_index_t)length >=
+ && ((_SequenceIndex)__length >=
__gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
return parallel_multiway_merge
- </* stable = */ true, /* sentinels = */ true>(
- seqs_begin, seqs_end,
- target,
- multiway_merge_sampling_splitting</* stable = */ true,
- typename std::iterator_traits<RandomAccessIteratorPairIterator>
- ::value_type*, Comparator, _DifferenceTp>,
- static_cast<difference_type>(length), comp, tag.get_num_threads());
+ </* __stable = */ true, /* __sentinels = */ true>(
+ __seqs_begin, __seqs_end,
+ __target,
+ multiway_merge_sampling_splitting</* __stable = */ true,
+ typename std::iterator_traits<_RAIterPairIterator>
+ ::value_type*, _Compare, _DifferenceTp>,
+ static_cast<_DifferenceType>(__length), __comp,
+ __tag.__get_num_threads());
else
- return sequential_multiway_merge
- </* stable = */ true, /* sentinels = */ true>(
- seqs_begin, seqs_end,
- target, *(seqs_begin->second), length, comp);
+ return __sequential_multiway_merge
+ </* __stable = */ true, /* __sentinels = */ true>(
+ __seqs_begin, __seqs_end,
+ __target, *(__seqs_begin->second), __length, __comp);
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , parallel_tag tag = parallel_tag(0))
+ , typename _Compare>
+_RAIterOut
+stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , parallel_tag __tag = parallel_tag(0))
{
- return stable_multiway_merge_sentinels(seqs_begin, seqs_end, target, length, comp,
- exact_tag(tag.get_num_threads()));
+ return stable_multiway_merge_sentinels(
+ __seqs_begin, __seqs_end, __target, __length, __comp,
+ exact_tag(__tag.__get_num_threads()));
}
// public interface
template<
- typename RandomAccessIteratorPairIterator
- , typename RandomAccessIteratorOut
+ typename _RAIterPairIterator
+ , typename _RAIterOut
, typename _DifferenceTp
- , typename Comparator>
-RandomAccessIteratorOut
-stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
- , RandomAccessIteratorPairIterator seqs_end
- , RandomAccessIteratorOut target
- , _DifferenceTp length, Comparator comp
- , default_parallel_tag tag)
+ , typename _Compare>
+_RAIterOut
+stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin
+ , _RAIterPairIterator __seqs_end
+ , _RAIterOut __target
+ , _DifferenceTp __length, _Compare __comp
+ , default_parallel_tag __tag)
{
- return stable_multiway_merge_sentinels(seqs_begin, seqs_end, target, length, comp,
- exact_tag(tag.get_num_threads()));
+ return stable_multiway_merge_sentinels(
+ __seqs_begin, __seqs_end, __target, __length, __comp,
+ exact_tag(__tag.__get_num_threads()));
}
}; // namespace __gnu_parallel
diff --git a/libstdc++-v3/include/parallel/multiway_mergesort.h b/libstdc++-v3/include/parallel/multiway_mergesort.h
index 11dd885c8ae..9f61ce305a2 100644
--- a/libstdc++-v3/include/parallel/multiway_mergesort.h
+++ b/libstdc++-v3/include/parallel/multiway_mergesort.h
@@ -44,431 +44,447 @@ namespace __gnu_parallel
/** @brief Subsequence description. */
template<typename _DifferenceTp>
- struct Piece
+ struct _Piece
{
- typedef _DifferenceTp difference_type;
+ typedef _DifferenceTp _DifferenceType;
/** @brief Begin of subsequence. */
- difference_type begin;
+ _DifferenceType _M_begin;
/** @brief End of subsequence. */
- difference_type end;
+ _DifferenceType _M_end;
};
/** @brief Data accessed by all threads.
*
* PMWMS = parallel multiway mergesort */
-template<typename RandomAccessIterator>
- struct PMWMSSortingData
+template<typename _RAIter>
+ struct _PMWMSSortingData
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
/** @brief Number of threads involved. */
- thread_index_t num_threads;
+ _ThreadIndex _M_num_threads;
- /** @brief Input begin. */
- RandomAccessIterator source;
+ /** @brief Input __begin. */
+ _RAIter _M_source;
/** @brief Start indices, per thread. */
- difference_type* starts;
+ _DifferenceType* _M_starts;
/** @brief Storage in which to sort. */
- value_type** temporary;
+ _ValueType** _M_temporary;
/** @brief Samples. */
- value_type* samples;
+ _ValueType* _M_samples;
/** @brief Offsets to add to the found positions. */
- difference_type* offsets;
+ _DifferenceType* _M_offsets;
- /** @brief Pieces of data to merge @c [thread][sequence] */
- std::vector<Piece<difference_type> >* pieces;
+ /** @brief Pieces of data to merge @__c [thread][__sequence] */
+ std::vector<_Piece<_DifferenceType> >* _M_pieces;
};
/**
- * @brief Select samples from a sequence.
- * @param sd Pointer to algorithm data. Result will be placed in
- * @c sd->samples.
- * @param num_samples Number of samples to select.
+ * @brief Select _M_samples from a sequence.
+ * @param __sd Pointer to algorithm data. _Result will be placed in
+ * @__c __sd->_M_samples.
+ * @param __num_samples Number of _M_samples to select.
*/
-template<typename RandomAccessIterator, typename _DifferenceTp>
+template<typename _RAIter, typename _DifferenceTp>
void
- determine_samples(PMWMSSortingData<RandomAccessIterator>* sd,
- _DifferenceTp num_samples)
+ __determine_samples(_PMWMSSortingData<_RAIter>* __sd,
+ _DifferenceTp __num_samples)
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef _DifferenceTp difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef _DifferenceTp _DifferenceType;
- thread_index_t iam = omp_get_thread_num();
+ _ThreadIndex __iam = omp_get_thread_num();
- difference_type* es = new difference_type[num_samples + 2];
+ _DifferenceType* __es = new _DifferenceType[__num_samples + 2];
- equally_split(sd->starts[iam + 1] - sd->starts[iam],
- num_samples + 1, es);
+ equally_split(__sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam],
+ __num_samples + 1, __es);
- for (difference_type i = 0; i < num_samples; ++i)
- ::new(&(sd->samples[iam * num_samples + i]))
- value_type(sd->source[sd->starts[iam] + es[i + 1]]);
+ for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
+ ::new(&(__sd->_M_samples[__iam * __num_samples + __i]))
+ _ValueType(__sd->_M_source[__sd->_M_starts[__iam] + __es[__i + 1]]);
- delete[] es;
+ delete[] __es;
}
/** @brief Split consistently. */
-template<bool exact, typename RandomAccessIterator,
- typename Comparator, typename SortingPlacesIterator>
- struct split_consistently
+template<bool __exact, typename _RAIter,
+ typename _Compare, typename _SortingPlacesIterator>
+ struct _SplitConsistently
{
};
/** @brief Split by exact splitting. */
-template<typename RandomAccessIterator, typename Comparator,
- typename SortingPlacesIterator>
- struct split_consistently
- <true, RandomAccessIterator, Comparator, SortingPlacesIterator>
+template<typename _RAIter, typename _Compare,
+ typename _SortingPlacesIterator>
+ struct _SplitConsistently
+ <true, _RAIter, _Compare, _SortingPlacesIterator>
{
void operator()(
- const thread_index_t iam,
- PMWMSSortingData<RandomAccessIterator>* sd,
- Comparator& comp,
+ const _ThreadIndex __iam,
+ _PMWMSSortingData<_RAIter>* __sd,
+ _Compare& __comp,
const typename
- std::iterator_traits<RandomAccessIterator>::difference_type
- num_samples)
+ std::iterator_traits<_RAIter>::difference_type
+ __num_samples)
const
{
# pragma omp barrier
- std::vector<std::pair<SortingPlacesIterator, SortingPlacesIterator> >
- seqs(sd->num_threads);
- for (thread_index_t s = 0; s < sd->num_threads; s++)
- seqs[s] = std::make_pair(sd->temporary[s],
- sd->temporary[s]
- + (sd->starts[s + 1] - sd->starts[s]));
+ std::vector<std::pair<_SortingPlacesIterator, _SortingPlacesIterator> >
+ seqs(__sd->_M_num_threads);
+ for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; __s++)
+ seqs[__s] = std::make_pair(__sd->_M_temporary[__s],
+ __sd->_M_temporary[__s]
+ + (__sd->_M_starts[__s + 1]
+ - __sd->_M_starts[__s]));
- std::vector<SortingPlacesIterator> offsets(sd->num_threads);
+ std::vector<_SortingPlacesIterator> _M_offsets(__sd->_M_num_threads);
// if not last thread
- if (iam < sd->num_threads - 1)
+ if (__iam < __sd->_M_num_threads - 1)
multiseq_partition(seqs.begin(), seqs.end(),
- sd->starts[iam + 1], offsets.begin(), comp);
+ __sd->_M_starts[__iam + 1], _M_offsets.begin(),
+ __comp);
- for (int seq = 0; seq < sd->num_threads; seq++)
+ for (int __seq = 0; __seq < __sd->_M_num_threads; __seq++)
{
// for each sequence
- if (iam < (sd->num_threads - 1))
- sd->pieces[iam][seq].end = offsets[seq] - seqs[seq].first;
+ if (__iam < (__sd->_M_num_threads - 1))
+ __sd->_M_pieces[__iam][__seq]._M_end
+ = _M_offsets[__seq] - seqs[__seq].first;
else
// very end of this sequence
- sd->pieces[iam][seq].end =
- sd->starts[seq + 1] - sd->starts[seq];
+ __sd->_M_pieces[__iam][__seq]._M_end =
+ __sd->_M_starts[__seq + 1] - __sd->_M_starts[__seq];
}
# pragma omp barrier
- for (thread_index_t seq = 0; seq < sd->num_threads; seq++)
+ for (_ThreadIndex __seq = 0; __seq < __sd->_M_num_threads; __seq++)
{
// For each sequence.
- if (iam > 0)
- sd->pieces[iam][seq].begin = sd->pieces[iam - 1][seq].end;
+ if (__iam > 0)
+ __sd->_M_pieces[__iam][__seq]._M_begin =
+ __sd->_M_pieces[__iam - 1][__seq]._M_end;
else
// Absolute beginning.
- sd->pieces[iam][seq].begin = 0;
+ __sd->_M_pieces[__iam][__seq]._M_begin = 0;
}
}
};
/** @brief Split by sampling. */
-template<typename RandomAccessIterator, typename Comparator,
- typename SortingPlacesIterator>
- struct split_consistently<false, RandomAccessIterator, Comparator,
- SortingPlacesIterator>
+template<typename _RAIter, typename _Compare,
+ typename _SortingPlacesIterator>
+ struct _SplitConsistently<false, _RAIter, _Compare,
+ _SortingPlacesIterator>
{
void operator()(
- const thread_index_t iam,
- PMWMSSortingData<RandomAccessIterator>* sd,
- Comparator& comp,
+ const _ThreadIndex __iam,
+ _PMWMSSortingData<_RAIter>* __sd,
+ _Compare& __comp,
const typename
- std::iterator_traits<RandomAccessIterator>::difference_type
- num_samples)
+ std::iterator_traits<_RAIter>::difference_type
+ __num_samples)
const
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- determine_samples(sd, num_samples);
+ __determine_samples(__sd, __num_samples);
# pragma omp barrier
# pragma omp single
- __gnu_sequential::sort(sd->samples,
- sd->samples + (num_samples * sd->num_threads),
- comp);
+ __gnu_sequential::sort(__sd->_M_samples,
+ __sd->_M_samples
+ + (__num_samples * __sd->_M_num_threads),
+ __comp);
# pragma omp barrier
- for (thread_index_t s = 0; s < sd->num_threads; ++s)
+ for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; ++__s)
{
// For each sequence.
- if (num_samples * iam > 0)
- sd->pieces[iam][s].begin =
- std::lower_bound(sd->temporary[s],
- sd->temporary[s]
- + (sd->starts[s + 1] - sd->starts[s]),
- sd->samples[num_samples * iam],
- comp)
- - sd->temporary[s];
+ if (__num_samples * __iam > 0)
+ __sd->_M_pieces[__iam][__s]._M_begin =
+ std::lower_bound(__sd->_M_temporary[__s],
+ __sd->_M_temporary[__s]
+ + (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s]),
+ __sd->_M_samples[__num_samples * __iam],
+ __comp)
+ - __sd->_M_temporary[__s];
else
// Absolute beginning.
- sd->pieces[iam][s].begin = 0;
-
- if ((num_samples * (iam + 1)) < (num_samples * sd->num_threads))
- sd->pieces[iam][s].end =
- std::lower_bound(sd->temporary[s],
- sd->temporary[s]
- + (sd->starts[s + 1] - sd->starts[s]),
- sd->samples[num_samples * (iam + 1)],
- comp)
- - sd->temporary[s];
+ __sd->_M_pieces[__iam][__s]._M_begin = 0;
+
+ if ((__num_samples * (__iam + 1)) <
+ (__num_samples * __sd->_M_num_threads))
+ __sd->_M_pieces[__iam][__s]._M_end =
+ std::lower_bound(__sd->_M_temporary[__s],
+ __sd->_M_temporary[__s]
+ + (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s]),
+ __sd->_M_samples[__num_samples * (__iam + 1)],
+ __comp)
+ - __sd->_M_temporary[__s];
else
// Absolute end.
- sd->pieces[iam][s].end = sd->starts[s + 1] - sd->starts[s];
+ __sd->_M_pieces[__iam][__s]._M_end = __sd->_M_starts[__s + 1]
+ - __sd->_M_starts[__s];
}
}
};
-template<bool stable, typename RandomAccessIterator, typename Comparator>
- struct possibly_stable_sort
+template<bool __stable, typename _RAIter, typename _Compare>
+ struct __possibly_stable_sort
{
};
-template<typename RandomAccessIterator, typename Comparator>
- struct possibly_stable_sort<true, RandomAccessIterator, Comparator>
+template<typename _RAIter, typename _Compare>
+ struct __possibly_stable_sort<true, _RAIter, _Compare>
{
- void operator()(const RandomAccessIterator& begin,
- const RandomAccessIterator& end, Comparator& comp) const
+ void operator()(const _RAIter& __begin,
+ const _RAIter& __end, _Compare& __comp) const
{
- __gnu_sequential::stable_sort(begin, end, comp);
+ __gnu_sequential::stable_sort(__begin, __end, __comp);
}
};
-template<typename RandomAccessIterator, typename Comparator>
- struct possibly_stable_sort<false, RandomAccessIterator, Comparator>
+template<typename _RAIter, typename _Compare>
+ struct __possibly_stable_sort<false, _RAIter, _Compare>
{
- void operator()(const RandomAccessIterator begin,
- const RandomAccessIterator end, Comparator& comp) const
+ void operator()(const _RAIter __begin,
+ const _RAIter __end, _Compare& __comp) const
{
- __gnu_sequential::sort(begin, end, comp);
+ __gnu_sequential::sort(__begin, __end, __comp);
}
};
-template<bool stable, typename SeqRandomAccessIterator,
- typename RandomAccessIterator, typename Comparator,
+template<bool __stable, typename Seq_RAIter,
+ typename _RAIter, typename _Compare,
typename DiffType>
- struct possibly_stable_multiway_merge
+ struct __possibly_stable_multiway_merge
{
};
-template<typename SeqRandomAccessIterator, typename RandomAccessIterator,
- typename Comparator, typename DiffType>
- struct possibly_stable_multiway_merge
- <true, SeqRandomAccessIterator, RandomAccessIterator, Comparator,
+template<typename Seq_RAIter, typename _RAIter,
+ typename _Compare, typename DiffType>
+ struct __possibly_stable_multiway_merge
+ <true, Seq_RAIter, _RAIter, _Compare,
DiffType>
{
- void operator()(const SeqRandomAccessIterator& seqs_begin,
- const SeqRandomAccessIterator& seqs_end,
- const RandomAccessIterator& target,
- Comparator& comp,
- DiffType length_am) const
+ void operator()(const Seq_RAIter& __seqs_begin,
+ const Seq_RAIter& __seqs_end,
+ const _RAIter& __target,
+ _Compare& __comp,
+ DiffType __length_am) const
{
- stable_multiway_merge(seqs_begin, seqs_end, target, length_am, comp,
- sequential_tag());
+ stable_multiway_merge(__seqs_begin, __seqs_end, __target, __length_am,
+ __comp, sequential_tag());
}
};
-template<typename SeqRandomAccessIterator, typename RandomAccessIterator,
- typename Comparator, typename DiffType>
- struct possibly_stable_multiway_merge
- <false, SeqRandomAccessIterator, RandomAccessIterator, Comparator,
+template<typename Seq_RAIter, typename _RAIter,
+ typename _Compare, typename DiffType>
+ struct __possibly_stable_multiway_merge
+ <false, Seq_RAIter, _RAIter, _Compare,
DiffType>
{
- void operator()(const SeqRandomAccessIterator& seqs_begin,
- const SeqRandomAccessIterator& seqs_end,
- const RandomAccessIterator& target,
- Comparator& comp,
- DiffType length_am) const
+ void operator()(const Seq_RAIter& __seqs_begin,
+ const Seq_RAIter& __seqs_end,
+ const _RAIter& __target,
+ _Compare& __comp,
+ DiffType __length_am) const
{
- multiway_merge(seqs_begin, seqs_end, target, length_am, comp,
+ multiway_merge(__seqs_begin, __seqs_end, __target, __length_am, __comp,
sequential_tag());
}
};
/** @brief PMWMS code executed by each thread.
- * @param sd Pointer to algorithm data.
- * @param comp Comparator.
+ * @param __sd Pointer to algorithm data.
+ * @param __comp Comparator.
*/
-template<bool stable, bool exact, typename RandomAccessIterator,
- typename Comparator>
+template<bool __stable, bool __exact, typename _RAIter,
+ typename _Compare>
void
- parallel_sort_mwms_pu(PMWMSSortingData<RandomAccessIterator>* sd,
- Comparator& comp)
+ parallel_sort_mwms_pu(_PMWMSSortingData<_RAIter>* __sd,
+ _Compare& __comp)
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- thread_index_t iam = omp_get_thread_num();
+ _ThreadIndex __iam = omp_get_thread_num();
// Length of this thread's chunk, before merging.
- difference_type length_local = sd->starts[iam + 1] - sd->starts[iam];
+ _DifferenceType __length_local
+ = __sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam];
// Sort in temporary storage, leave space for sentinel.
- typedef value_type* SortingPlacesIterator;
+ typedef _ValueType* _SortingPlacesIterator;
- sd->temporary[iam] =
- static_cast<value_type*>(
- ::operator new(sizeof(value_type) * (length_local + 1)));
+ __sd->_M_temporary[__iam] =
+ static_cast<_ValueType*>(
+ ::operator new(sizeof(_ValueType) * (__length_local + 1)));
// Copy there.
- std::uninitialized_copy(sd->source + sd->starts[iam],
- sd->source + sd->starts[iam] + length_local,
- sd->temporary[iam]);
+ std::uninitialized_copy(
+ __sd->_M_source + __sd->_M_starts[__iam],
+ __sd->_M_source + __sd->_M_starts[__iam] + __length_local,
+ __sd->_M_temporary[__iam]);
- possibly_stable_sort<stable, SortingPlacesIterator, Comparator>()
- (sd->temporary[iam], sd->temporary[iam] + length_local, comp);
+ __possibly_stable_sort<__stable, _SortingPlacesIterator, _Compare>()
+ (__sd->_M_temporary[__iam],
+ __sd->_M_temporary[__iam] + __length_local,
+ __comp);
- // Invariant: locally sorted subsequence in sd->temporary[iam],
- // sd->temporary[iam] + length_local.
+ // Invariant: locally sorted subsequence in sd->_M_temporary[__iam],
+ // __sd->_M_temporary[__iam] + __length_local.
// No barrier here: Synchronization is done by the splitting routine.
- difference_type num_samples =
- _Settings::get().sort_mwms_oversampling * sd->num_threads - 1;
- split_consistently
- <exact, RandomAccessIterator, Comparator, SortingPlacesIterator>()
- (iam, sd, comp, num_samples);
+ _DifferenceType __num_samples =
+ _Settings::get().sort_mwms_oversampling * __sd->_M_num_threads - 1;
+ _SplitConsistently
+ <__exact, _RAIter, _Compare, _SortingPlacesIterator>()
+ (__iam, __sd, __comp, __num_samples);
- // Offset from target begin, length after merging.
- difference_type offset = 0, length_am = 0;
- for (thread_index_t s = 0; s < sd->num_threads; s++)
+ // Offset from __target __begin, __length after merging.
+ _DifferenceType __offset = 0, __length_am = 0;
+ for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; __s++)
{
- length_am += sd->pieces[iam][s].end - sd->pieces[iam][s].begin;
- offset += sd->pieces[iam][s].begin;
+ __length_am += __sd->_M_pieces[__iam][__s]._M_end
+ - __sd->_M_pieces[__iam][__s]._M_begin;
+ __offset += __sd->_M_pieces[__iam][__s]._M_begin;
}
typedef std::vector<
- std::pair<SortingPlacesIterator, SortingPlacesIterator> >
+ std::pair<_SortingPlacesIterator, _SortingPlacesIterator> >
seq_vector_type;
- seq_vector_type seqs(sd->num_threads);
+ seq_vector_type seqs(__sd->_M_num_threads);
- for (int s = 0; s < sd->num_threads; ++s)
+ for (int __s = 0; __s < __sd->_M_num_threads; ++__s)
{
- seqs[s] =
- std::make_pair(sd->temporary[s] + sd->pieces[iam][s].begin,
- sd->temporary[s] + sd->pieces[iam][s].end);
+ seqs[__s] =
+ std::make_pair(
+ __sd->_M_temporary[__s] + __sd->_M_pieces[__iam][__s]._M_begin,
+ __sd->_M_temporary[__s] + __sd->_M_pieces[__iam][__s]._M_end);
}
- possibly_stable_multiway_merge<
- stable,
+ __possibly_stable_multiway_merge<
+ __stable,
typename seq_vector_type::iterator,
- RandomAccessIterator,
- Comparator, difference_type>()
+ _RAIter,
+ _Compare, _DifferenceType>()
(seqs.begin(), seqs.end(),
- sd->source + offset, comp,
- length_am);
+ __sd->_M_source + __offset, __comp,
+ __length_am);
# pragma omp barrier
- ::operator delete(sd->temporary[iam]);
+ ::operator delete(__sd->_M_temporary[__iam]);
}
/** @brief PMWMS main call.
- * @param begin Begin iterator of sequence.
- * @param end End iterator of sequence.
- * @param comp Comparator.
- * @param n Length of sequence.
- * @param num_threads Number of threads to use.
+ * @param __begin Begin iterator of sequence.
+ * @param __end End iterator of sequence.
+ * @param __comp Comparator.
+ * @param __n Length of sequence.
+ * @param __num_threads Number of threads to use.
*/
-template<bool stable, bool exact, typename RandomAccessIterator,
- typename Comparator>
+template<bool __stable, bool __exact, typename _RAIter,
+ typename _Compare>
void
- parallel_sort_mwms(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp,
- thread_index_t num_threads)
+ parallel_sort_mwms(_RAIter __begin, _RAIter __end,
+ _Compare __comp,
+ _ThreadIndex __num_threads)
{
- _GLIBCXX_CALL(end - begin)
+ _GLIBCXX_CALL(__end - __begin)
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- difference_type n = end - begin;
+ _DifferenceType __n = __end - __begin;
- if (n <= 1)
+ if (__n <= 1)
return;
// at least one element per thread
- if (num_threads > n)
- num_threads = static_cast<thread_index_t>(n);
+ if (__num_threads > __n)
+ __num_threads = static_cast<_ThreadIndex>(__n);
// shared variables
- PMWMSSortingData<RandomAccessIterator> sd;
- difference_type* starts;
+ _PMWMSSortingData<_RAIter> __sd;
+ _DifferenceType* _M_starts;
-# pragma omp parallel num_threads(num_threads)
+# pragma omp parallel num_threads(__num_threads)
{
- num_threads = omp_get_num_threads(); //no more threads than requested
+ __num_threads = omp_get_num_threads(); //no more threads than requested
# pragma omp single
{
- sd.num_threads = num_threads;
- sd.source = begin;
+ __sd._M_num_threads = __num_threads;
+ __sd._M_source = __begin;
- sd.temporary = new value_type*[num_threads];
+ __sd._M_temporary = new _ValueType*[__num_threads];
- if (!exact)
+ if (!__exact)
{
- difference_type size =
- (_Settings::get().sort_mwms_oversampling * num_threads - 1)
- * num_threads;
- sd.samples = static_cast<value_type*>(
- ::operator new(size * sizeof(value_type)));
+ _DifferenceType size =
+ (_Settings::get().sort_mwms_oversampling * __num_threads - 1)
+ * __num_threads;
+ __sd._M_samples = static_cast<_ValueType*>(
+ ::operator new(size * sizeof(_ValueType)));
}
else
- sd.samples = NULL;
-
- sd.offsets = new difference_type[num_threads - 1];
- sd.pieces = new std::vector<Piece<difference_type> >[num_threads];
- for (int s = 0; s < num_threads; ++s)
- sd.pieces[s].resize(num_threads);
- starts = sd.starts = new difference_type[num_threads + 1];
-
- difference_type chunk_length = n / num_threads;
- difference_type split = n % num_threads;
- difference_type pos = 0;
- for (int i = 0; i < num_threads; ++i)
+ __sd._M_samples = NULL;
+
+ __sd._M_offsets = new _DifferenceType[__num_threads - 1];
+ __sd._M_pieces
+ = new std::vector<_Piece<_DifferenceType> >[__num_threads];
+ for (int __s = 0; __s < __num_threads; ++__s)
+ __sd._M_pieces[__s].resize(__num_threads);
+ _M_starts = __sd._M_starts
+ = new _DifferenceType[__num_threads + 1];
+
+ _DifferenceType __chunk_length = __n / __num_threads;
+ _DifferenceType __split = __n % __num_threads;
+ _DifferenceType __pos = 0;
+ for (int __i = 0; __i < __num_threads; ++__i)
{
- starts[i] = pos;
- pos += (i < split) ? (chunk_length + 1) : chunk_length;
+ _M_starts[__i] = __pos;
+ __pos += (__i < __split)
+ ? (__chunk_length + 1) : __chunk_length;
}
- starts[num_threads] = pos;
+ _M_starts[__num_threads] = __pos;
} //single
// Now sort in parallel.
- parallel_sort_mwms_pu<stable, exact>(&sd, comp);
+ parallel_sort_mwms_pu<__stable, __exact>(&__sd, __comp);
} //parallel
- delete[] starts;
- delete[] sd.temporary;
+ delete[] _M_starts;
+ delete[] __sd._M_temporary;
- if (!exact)
- ::operator delete(sd.samples);
+ if (!__exact)
+ ::operator delete(__sd._M_samples);
- delete[] sd.offsets;
- delete[] sd.pieces;
+ delete[] __sd._M_offsets;
+ delete[] __sd._M_pieces;
}
} //namespace __gnu_parallel
diff --git a/libstdc++-v3/include/parallel/numeric b/libstdc++-v3/include/parallel/numeric
index 33b1411f1b0..5d03e679c27 100644
--- a/libstdc++-v3/include/parallel/numeric
+++ b/libstdc++-v3/include/parallel/numeric
@@ -51,448 +51,455 @@ namespace std
namespace __parallel
{
// Sequential fallback.
- template<typename InputIterator, typename T>
- inline T
- accumulate(InputIterator begin, InputIterator end, T init,
- __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::accumulate(begin, end, init); }
-
- template<typename InputIterator, typename T, typename BinaryOperation>
- inline T
- accumulate(InputIterator begin, InputIterator end, T init,
- BinaryOperation binary_op, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::accumulate(begin, end, init, binary_op); }
+ template<typename _IIter, typename _Tp>
+ inline _Tp
+ accumulate(_IIter __begin, _IIter __end, _Tp __init,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::accumulate(__begin, __end, __init); }
+
+ template<typename _IIter, typename _Tp, typename _BinaryOperation>
+ inline _Tp
+ accumulate(_IIter __begin, _IIter __end, _Tp __init,
+ _BinaryOperation __binary_op, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::accumulate(__begin, __end, __init, __binary_op); }
// Sequential fallback for input iterator case.
- template<typename InputIterator, typename T, typename IteratorTag>
- inline T
- accumulate_switch(InputIterator begin, InputIterator end,
- T init, IteratorTag)
- { return accumulate(begin, end, init, __gnu_parallel::sequential_tag()); }
-
- template<typename InputIterator, typename T, typename BinaryOperation,
- typename IteratorTag>
- inline T
- accumulate_switch(InputIterator begin, InputIterator end, T init,
- BinaryOperation binary_op, IteratorTag)
- { return accumulate(begin, end, init, binary_op,
- __gnu_parallel::sequential_tag()); }
+ template<typename _IIter, typename _Tp, typename _IteratorTag>
+ inline _Tp
+ __accumulate_switch(_IIter __begin, _IIter __end,
+ _Tp __init, _IteratorTag)
+ { return accumulate(__begin, __end, __init,
+__gnu_parallel::sequential_tag()); }
+
+ template<typename _IIter, typename _Tp, typename _BinaryOperation,
+ typename _IteratorTag>
+ inline _Tp
+ __accumulate_switch(_IIter __begin, _IIter __end, _Tp __init,
+ _BinaryOperation __binary_op, _IteratorTag)
+ { return accumulate(__begin, __end, __init, __binary_op,
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators.
- template<typename _RandomAccessIterator, typename T,
- typename BinaryOperation>
- T
- accumulate_switch(_RandomAccessIterator begin, _RandomAccessIterator end,
- T init, BinaryOperation binary_op,
- random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism_tag
- = __gnu_parallel::parallel_unbalanced)
+ template<typename __RAIter, typename _Tp,
+ typename _BinaryOperation>
+ _Tp
+ __accumulate_switch(__RAIter __begin, __RAIter __end,
+ _Tp __init, _BinaryOperation __binary_op,
+ random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag
+ = __gnu_parallel::parallel_unbalanced)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin)
- >= __gnu_parallel::_Settings::get().accumulate_minimal_n
- && __gnu_parallel::is_parallel(parallelism_tag)))
- {
- T res = init;
- __gnu_parallel::accumulate_selector<_RandomAccessIterator>
- my_selector;
- __gnu_parallel::
- for_each_template_random_access_ed(begin, end,
- __gnu_parallel::nothing(),
- my_selector,
- __gnu_parallel::
- accumulate_binop_reduct
- <BinaryOperation>(binary_op),
- res, res, -1);
- return res;
- }
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().accumulate_minimal_n
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
+ {
+ _Tp __res = __init;
+ __gnu_parallel::__accumulate_selector<__RAIter>
+ __my_selector;
+ __gnu_parallel::
+ for_each_template_random_access_ed(__begin, __end,
+ __gnu_parallel::_Nothing(),
+ __my_selector,
+ __gnu_parallel::
+ __accumulate_binop_reduct
+ <_BinaryOperation>(__binary_op),
+ __res, __res, -1);
+ return __res;
+ }
else
- return accumulate(begin, end, init, binary_op,
- __gnu_parallel::sequential_tag());
+ return accumulate(__begin, __end, __init, __binary_op,
+ __gnu_parallel::sequential_tag());
}
// Public interface.
- template<typename InputIterator, typename T>
- inline T
- accumulate(InputIterator begin, InputIterator end, T init,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _IIter, typename _Tp>
+ inline _Tp
+ accumulate(_IIter __begin, _IIter __end, _Tp __init,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef std::iterator_traits<InputIterator> iterator_traits;
- typedef typename iterator_traits::value_type value_type;
- typedef typename iterator_traits::iterator_category iterator_category;
+ typedef std::iterator_traits<_IIter> _IteratorTraits;
+ typedef typename _IteratorTraits::value_type _ValueType;
+ typedef typename _IteratorTraits::iterator_category _IteratorCategory;
- return accumulate_switch(begin, end, init,
- __gnu_parallel::plus<T, value_type>(),
- iterator_category(), parallelism_tag);
+ return __accumulate_switch(__begin, __end, __init,
+ __gnu_parallel::_Plus<_Tp, _ValueType>(),
+ _IteratorCategory(), __parallelism_tag);
}
- template<typename InputIterator, typename T>
- inline T
- accumulate(InputIterator begin, InputIterator end, T init)
+ template<typename _IIter, typename _Tp>
+ inline _Tp
+ accumulate(_IIter __begin, _IIter __end, _Tp __init)
{
- typedef std::iterator_traits<InputIterator> iterator_traits;
- typedef typename iterator_traits::value_type value_type;
- typedef typename iterator_traits::iterator_category iterator_category;
+ typedef std::iterator_traits<_IIter> _IteratorTraits;
+ typedef typename _IteratorTraits::value_type _ValueType;
+ typedef typename _IteratorTraits::iterator_category _IteratorCategory;
- return accumulate_switch(begin, end, init,
- __gnu_parallel::plus<T, value_type>(),
- iterator_category());
+ return __accumulate_switch(__begin, __end, __init,
+ __gnu_parallel::_Plus<_Tp, _ValueType>(),
+ _IteratorCategory());
}
- template<typename InputIterator, typename T, typename BinaryOperation>
- inline T
- accumulate(InputIterator begin, InputIterator end, T init,
- BinaryOperation binary_op,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _IIter, typename _Tp, typename _BinaryOperation>
+ inline _Tp
+ accumulate(_IIter __begin, _IIter __end, _Tp __init,
+ _BinaryOperation __binary_op,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<InputIterator> iterator_traits;
- typedef typename iterator_traits::iterator_category iterator_category;
- return accumulate_switch(begin, end, init, binary_op,
- iterator_category(), parallelism_tag);
+ typedef iterator_traits<_IIter> _IteratorTraits;
+ typedef typename _IteratorTraits::iterator_category _IteratorCategory;
+ return __accumulate_switch(__begin, __end, __init, __binary_op,
+ _IteratorCategory(), __parallelism_tag);
}
- template<typename InputIterator, typename T, typename BinaryOperation>
- inline T
- accumulate(InputIterator begin, InputIterator end, T init,
- BinaryOperation binary_op)
+ template<typename _IIter, typename _Tp, typename _BinaryOperation>
+ inline _Tp
+ accumulate(_IIter __begin, _IIter __end, _Tp __init,
+ _BinaryOperation __binary_op)
{
- typedef iterator_traits<InputIterator> iterator_traits;
- typedef typename iterator_traits::iterator_category iterator_category;
- return accumulate_switch(begin, end, init, binary_op,
- iterator_category());
+ typedef iterator_traits<_IIter> _IteratorTraits;
+ typedef typename _IteratorTraits::iterator_category _IteratorCategory;
+ return __accumulate_switch(__begin, __end, __init, __binary_op,
+ _IteratorCategory());
}
// Sequential fallback.
- template<typename InputIterator1, typename InputIterator2, typename T>
- inline T
- inner_product(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, T init,
- __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init); }
-
- template<typename InputIterator1, typename InputIterator2, typename T,
- typename BinaryFunction1, typename BinaryFunction2>
- inline T
- inner_product(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, T init, BinaryFunction1 binary_op1,
- BinaryFunction2 binary_op2, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init,
- binary_op1, binary_op2); }
+ template<typename _IIter1, typename _IIter2, typename _Tp>
+ inline _Tp
+ inner_product(_IIter1 __first1, _IIter1 __last1,
+ _IIter2 __first2, _Tp __init,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::inner_product(
+ __first1, __last1, __first2, __init); }
+
+ template<typename _IIter1, typename _IIter2, typename _Tp,
+ typename BinaryFunction1, typename BinaryFunction2>
+ inline _Tp
+ inner_product(_IIter1 __first1, _IIter1 __last1,
+ _IIter2 __first2, _Tp __init, BinaryFunction1 __binary_op1,
+ BinaryFunction2 __binary_op2, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::inner_product(__first1, __last1, __first2, __init,
+ __binary_op1, __binary_op2); }
// Parallel algorithm for random access iterators.
- template<typename RandomAccessIterator1, typename RandomAccessIterator2,
- typename T, typename BinaryFunction1, typename BinaryFunction2>
- T
- inner_product_switch(RandomAccessIterator1 first1,
- RandomAccessIterator1 last1,
- RandomAccessIterator2 first2, T init,
- BinaryFunction1 binary_op1,
- BinaryFunction2 binary_op2,
- random_access_iterator_tag,
- random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism_tag
- = __gnu_parallel::parallel_unbalanced)
+ template<typename _RAIter1, typename _RAIter2,
+ typename _Tp, typename BinaryFunction1, typename BinaryFunction2>
+ _Tp
+ __inner_product_switch(_RAIter1 __first1,
+ _RAIter1 __last1,
+ _RAIter2 __first2, _Tp __init,
+ BinaryFunction1 __binary_op1,
+ BinaryFunction2 __binary_op2,
+ random_access_iterator_tag,
+ random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag
+ = __gnu_parallel::parallel_unbalanced)
{
- if (_GLIBCXX_PARALLEL_CONDITION((last1 - first1)
- >= __gnu_parallel::_Settings::get().
- accumulate_minimal_n
- && __gnu_parallel::
- is_parallel(parallelism_tag)))
- {
- T res = init;
- __gnu_parallel::
- inner_product_selector<RandomAccessIterator1,
- RandomAccessIterator2, T> my_selector(first1, first2);
- __gnu_parallel::
- for_each_template_random_access_ed(first1, last1, binary_op2,
- my_selector, binary_op1,
- res, res, -1);
- return res;
- }
+ if (_GLIBCXX_PARALLEL_CONDITION((__last1 - __first1)
+ >= __gnu_parallel::_Settings::get().
+ accumulate_minimal_n
+ && __gnu_parallel::
+ __is_parallel(__parallelism_tag)))
+ {
+ _Tp __res = __init;
+ __gnu_parallel::
+ __inner_product_selector<_RAIter1,
+ _RAIter2, _Tp> __my_selector(__first1, __first2);
+ __gnu_parallel::
+ for_each_template_random_access_ed(__first1, __last1, __binary_op2,
+ __my_selector, __binary_op1,
+ __res, __res, -1);
+ return __res;
+ }
else
- return inner_product(first1, last1, first2, init,
- __gnu_parallel::sequential_tag());
+ return inner_product(__first1, __last1, __first2, __init,
+ __gnu_parallel::sequential_tag());
}
// No parallelism for input iterators.
- template<typename InputIterator1, typename InputIterator2, typename T,
- typename BinaryFunction1, typename BinaryFunction2,
- typename IteratorTag1, typename IteratorTag2>
- inline T
- inner_product_switch(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, T init,
- BinaryFunction1 binary_op1,
- BinaryFunction2 binary_op2,
- IteratorTag1, IteratorTag2)
- { return inner_product(first1, last1, first2, init,
- binary_op1, binary_op2,
- __gnu_parallel::sequential_tag()); }
-
- template<typename InputIterator1, typename InputIterator2, typename T,
- typename BinaryFunction1, typename BinaryFunction2>
- inline T
- inner_product(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, T init, BinaryFunction1 binary_op1,
- BinaryFunction2 binary_op2,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _IIter1, typename _IIter2, typename _Tp,
+ typename BinaryFunction1, typename BinaryFunction2,
+ typename _IteratorTag1, typename _IteratorTag2>
+ inline _Tp
+ __inner_product_switch(_IIter1 __first1, _IIter1 __last1,
+ _IIter2 __first2, _Tp __init,
+ BinaryFunction1 __binary_op1,
+ BinaryFunction2 __binary_op2,
+ _IteratorTag1, _IteratorTag2)
+ { return inner_product(__first1, __last1, __first2, __init,
+ __binary_op1, __binary_op2,
+ __gnu_parallel::sequential_tag()); }
+
+ template<typename _IIter1, typename _IIter2, typename _Tp,
+ typename BinaryFunction1, typename BinaryFunction2>
+ inline _Tp
+ inner_product(_IIter1 __first1, _IIter1 __last1,
+ _IIter2 __first2, _Tp __init, BinaryFunction1 __binary_op1,
+ BinaryFunction2 __binary_op2,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<InputIterator1> traits1_type;
- typedef typename traits1_type::iterator_category iterator1_category;
+ typedef iterator_traits<_IIter1> _TraitsType1;
+ typedef typename _TraitsType1::iterator_category _IteratorCategory1;
- typedef iterator_traits<InputIterator2> traits2_type;
- typedef typename traits2_type::iterator_category iterator2_category;
+ typedef iterator_traits<_IIter2> _TraitsType2;
+ typedef typename _TraitsType2::iterator_category _IteratorCategory2;
- return inner_product_switch(first1, last1, first2, init, binary_op1,
- binary_op2, iterator1_category(),
- iterator2_category(), parallelism_tag);
+ return __inner_product_switch(
+ __first1, __last1, __first2, __init, __binary_op1,
+ __binary_op2, _IteratorCategory1(), _IteratorCategory2(),
+ __parallelism_tag);
}
- template<typename InputIterator1, typename InputIterator2, typename T,
- typename BinaryFunction1, typename BinaryFunction2>
- inline T
- inner_product(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, T init, BinaryFunction1 binary_op1,
- BinaryFunction2 binary_op2)
+ template<typename _IIter1, typename _IIter2, typename _Tp,
+ typename BinaryFunction1, typename BinaryFunction2>
+ inline _Tp
+ inner_product(_IIter1 __first1, _IIter1 __last1,
+ _IIter2 __first2, _Tp __init, BinaryFunction1 __binary_op1,
+ BinaryFunction2 __binary_op2)
{
- typedef iterator_traits<InputIterator1> traits1_type;
- typedef typename traits1_type::iterator_category iterator1_category;
+ typedef iterator_traits<_IIter1> _TraitsType1;
+ typedef typename _TraitsType1::iterator_category _IteratorCategory1;
- typedef iterator_traits<InputIterator2> traits2_type;
- typedef typename traits2_type::iterator_category iterator2_category;
+ typedef iterator_traits<_IIter2> _TraitsType2;
+ typedef typename _TraitsType2::iterator_category _IteratorCategory2;
- return inner_product_switch(first1, last1, first2, init, binary_op1,
- binary_op2, iterator1_category(),
- iterator2_category());
+ return __inner_product_switch(
+ __first1, __last1, __first2, __init, __binary_op1, __binary_op2,
+ _IteratorCategory1(), _IteratorCategory2());
}
- template<typename InputIterator1, typename InputIterator2, typename T>
- inline T
- inner_product(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, T init,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _IIter1, typename _IIter2, typename _Tp>
+ inline _Tp
+ inner_product(_IIter1 __first1, _IIter1 __last1,
+ _IIter2 __first2, _Tp __init,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<InputIterator1> traits_type1;
+ typedef iterator_traits<_IIter1> traits_type1;
typedef typename traits_type1::value_type value_type1;
- typedef iterator_traits<InputIterator2> traits_type2;
+ typedef iterator_traits<_IIter2> traits_type2;
typedef typename traits_type2::value_type value_type2;
typedef typename
- __gnu_parallel::multiplies<value_type1, value_type2>::result
- multiplies_result_type;
- return inner_product(first1, last1, first2, init,
- __gnu_parallel::plus<T, multiplies_result_type>(),
+ __gnu_parallel::_Multiplies<value_type1, value_type2>::__result
+ _MultipliesResultType;
+ return inner_product(__first1, __last1, __first2, __init,
+ __gnu_parallel::_Plus<_Tp, _MultipliesResultType>(),
__gnu_parallel::
- multiplies<value_type1, value_type2>(),
- parallelism_tag);
+ _Multiplies<value_type1, value_type2>(),
+ __parallelism_tag);
}
- template<typename InputIterator1, typename InputIterator2, typename T>
- inline T
- inner_product(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, T init)
+ template<typename _IIter1, typename _IIter2, typename _Tp>
+ inline _Tp
+ inner_product(_IIter1 __first1, _IIter1 __last1,
+ _IIter2 __first2, _Tp __init)
{
- typedef iterator_traits<InputIterator1> traits_type1;
+ typedef iterator_traits<_IIter1> traits_type1;
typedef typename traits_type1::value_type value_type1;
- typedef iterator_traits<InputIterator2> traits_type2;
+ typedef iterator_traits<_IIter2> traits_type2;
typedef typename traits_type2::value_type value_type2;
typedef typename
- __gnu_parallel::multiplies<value_type1, value_type2>::result
- multiplies_result_type;
- return inner_product(first1, last1, first2, init,
- __gnu_parallel::plus<T, multiplies_result_type>(),
+ __gnu_parallel::_Multiplies<value_type1, value_type2>::__result
+ _MultipliesResultType;
+ return inner_product(__first1, __last1, __first2, __init,
+ __gnu_parallel::_Plus<_Tp, _MultipliesResultType>(),
__gnu_parallel::
- multiplies<value_type1, value_type2>());
+ _Multiplies<value_type1, value_type2>());
}
// Sequential fallback.
- template<typename InputIterator, typename OutputIterator>
- inline OutputIterator
- partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
- __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::partial_sum(begin, end, result); }
+ template<typename _IIter, typename _OutputIterator>
+ inline _OutputIterator
+ partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::partial_sum(__begin, __end, __result); }
// Sequential fallback.
- template<typename InputIterator, typename OutputIterator,
- typename BinaryOperation>
- inline OutputIterator
- partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
- BinaryOperation bin_op, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op); }
+ template<typename _IIter, typename _OutputIterator,
+ typename _BinaryOperation>
+ inline _OutputIterator
+ partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result,
+ _BinaryOperation __bin_op, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::partial_sum(__begin, __end, __result, __bin_op); }
// Sequential fallback for input iterator case.
- template<typename InputIterator, typename OutputIterator,
- typename BinaryOperation, typename IteratorTag1,
- typename IteratorTag2>
- inline OutputIterator
- partial_sum_switch(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation bin_op,
- IteratorTag1, IteratorTag2)
- { return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op); }
+ template<typename _IIter, typename _OutputIterator,
+ typename _BinaryOperation, typename _IteratorTag1,
+ typename _IteratorTag2>
+ inline _OutputIterator
+ __partial_sum_switch(_IIter __begin, _IIter __end,
+ _OutputIterator __result, _BinaryOperation __bin_op,
+ _IteratorTag1, _IteratorTag2)
+ { return _GLIBCXX_STD_P::partial_sum(__begin, __end, __result, __bin_op); }
// Parallel algorithm for random access iterators.
- template<typename InputIterator, typename OutputIterator,
- typename BinaryOperation>
- OutputIterator
- partial_sum_switch(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation bin_op,
- random_access_iterator_tag, random_access_iterator_tag)
+ template<typename _IIter, typename _OutputIterator,
+ typename _BinaryOperation>
+ _OutputIterator
+ __partial_sum_switch(_IIter __begin, _IIter __end,
+ _OutputIterator __result, _BinaryOperation __bin_op,
+ random_access_iterator_tag, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin)
- >= __gnu_parallel::_Settings::get().partial_sum_minimal_n))
- return __gnu_parallel::parallel_partial_sum(begin, end,
- result, bin_op);
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().partial_sum_minimal_n))
+ return __gnu_parallel::__parallel_partial_sum(__begin, __end,
+ __result, __bin_op);
else
- return partial_sum(begin, end, result, bin_op,
- __gnu_parallel::sequential_tag());
+ return partial_sum(__begin, __end, __result, __bin_op,
+ __gnu_parallel::sequential_tag());
}
// Public interface.
- template<typename InputIterator, typename OutputIterator>
- inline OutputIterator
- partial_sum(InputIterator begin, InputIterator end, OutputIterator result)
+ template<typename _IIter, typename _OutputIterator>
+ inline _OutputIterator
+ partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result)
{
- typedef typename iterator_traits<InputIterator>::value_type value_type;
- return partial_sum(begin, end, result, std::plus<value_type>());
+ typedef typename iterator_traits<_IIter>::value_type _ValueType;
+ return partial_sum(__begin, __end, __result, std::plus<_ValueType>());
}
// Public interface
- template<typename InputIterator, typename OutputIterator,
- typename BinaryOperation>
- inline OutputIterator
- partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
- BinaryOperation binary_op)
+ template<typename _IIter, typename _OutputIterator,
+ typename _BinaryOperation>
+ inline _OutputIterator
+ partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result,
+ _BinaryOperation __binary_op)
{
- typedef iterator_traits<InputIterator> traitsi_type;
- typedef typename traitsi_type::iterator_category iteratori_category;
+ typedef iterator_traits<_IIter> traitsi_type;
+ typedef typename traitsi_type::iterator_category _IIteratorCategory;
- typedef iterator_traits<OutputIterator> traitso_type;
- typedef typename traitso_type::iterator_category iteratoro_category;
+ typedef iterator_traits<_OutputIterator> _OTraitsType;
+ typedef typename _OTraitsType::iterator_category _OIterCategory;
- return partial_sum_switch(begin, end, result, binary_op,
- iteratori_category(), iteratoro_category());
+ return __partial_sum_switch(__begin, __end, __result, __binary_op,
+ _IIteratorCategory(), _OIterCategory());
}
// Sequential fallback.
- template<typename InputIterator, typename OutputIterator>
- inline OutputIterator
- adjacent_difference(InputIterator begin, InputIterator end,
- OutputIterator result, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::adjacent_difference(begin, end, result); }
+ template<typename _IIter, typename _OutputIterator>
+ inline _OutputIterator
+ adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::adjacent_difference(__begin, __end, __result); }
// Sequential fallback.
- template<typename InputIterator, typename OutputIterator,
- typename BinaryOperation>
- inline OutputIterator
- adjacent_difference(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation bin_op,
- __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::adjacent_difference(begin, end, result, bin_op); }
+ template<typename _IIter, typename _OutputIterator,
+ typename _BinaryOperation>
+ inline _OutputIterator
+ adjacent_difference(_IIter __begin, _IIter __end,
+ _OutputIterator __result, _BinaryOperation __bin_op,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::adjacent_difference(
+ __begin, __end, __result, __bin_op); }
// Sequential fallback for input iterator case.
- template<typename InputIterator, typename OutputIterator,
- typename BinaryOperation, typename IteratorTag1,
- typename IteratorTag2>
- inline OutputIterator
- adjacent_difference_switch(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation bin_op,
- IteratorTag1, IteratorTag2)
- { return adjacent_difference(begin, end, result, bin_op,
- __gnu_parallel::sequential_tag()); }
+ template<typename _IIter, typename _OutputIterator,
+ typename _BinaryOperation, typename _IteratorTag1,
+ typename _IteratorTag2>
+ inline _OutputIterator
+ __adjacent_difference_switch(
+ _IIter __begin, _IIter __end, _OutputIterator __result,
+ _BinaryOperation __bin_op, _IteratorTag1, _IteratorTag2)
+ { return adjacent_difference(__begin, __end, __result, __bin_op,
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators.
- template<typename InputIterator, typename OutputIterator,
- typename BinaryOperation>
- OutputIterator
- adjacent_difference_switch(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation bin_op,
- random_access_iterator_tag,
- random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism_tag
- = __gnu_parallel::parallel_balanced)
+ template<typename _IIter, typename _OutputIterator,
+ typename _BinaryOperation>
+ _OutputIterator
+ __adjacent_difference_switch(
+ _IIter __begin, _IIter __end, _OutputIterator __result,
+ _BinaryOperation __bin_op,
+ random_access_iterator_tag, random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism_tag
+ = __gnu_parallel::parallel_balanced)
{
if (_GLIBCXX_PARALLEL_CONDITION(
- static_cast<__gnu_parallel::sequence_index_t>(end - begin)
- >= __gnu_parallel::_Settings::get().adjacent_difference_minimal_n
- && __gnu_parallel::is_parallel(parallelism_tag)))
- {
- bool dummy = true;
- typedef __gnu_parallel::iterator_pair<InputIterator, OutputIterator,
- random_access_iterator_tag> ip;
- *result = *begin;
- ip begin_pair(begin + 1, result + 1),
- end_pair(end, result + (end - begin));
- __gnu_parallel::adjacent_difference_selector<ip> functionality;
- __gnu_parallel::
- for_each_template_random_access_ed(begin_pair, end_pair, bin_op,
- functionality,
- __gnu_parallel::dummy_reduct(),
- dummy, dummy, -1);
- return functionality.finish_iterator;
- }
+ static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
+ >= __gnu_parallel::_Settings::get().adjacent_difference_minimal_n
+ && __gnu_parallel::__is_parallel(__parallelism_tag)))
+ {
+ bool __dummy = true;
+ typedef __gnu_parallel::_IteratorPair<_IIter, _OutputIterator,
+ random_access_iterator_tag> _ItTrip;
+ *__result = *__begin;
+ _ItTrip begin_pair(__begin + 1, __result + 1),
+ end_pair(__end, __result + (__end - __begin));
+ __gnu_parallel::__adjacent_difference_selector<_ItTrip>
+ __functionality;
+ __gnu_parallel::
+ for_each_template_random_access_ed(begin_pair, end_pair, __bin_op,
+ __functionality,
+ __gnu_parallel::_DummyReduct(),
+ __dummy, __dummy, -1);
+ return __functionality.finish_iterator;
+ }
else
- return adjacent_difference(begin, end, result, bin_op,
- __gnu_parallel::sequential_tag());
+ return adjacent_difference(__begin, __end, __result, __bin_op,
+ __gnu_parallel::sequential_tag());
}
// Public interface.
- template<typename InputIterator, typename OutputIterator>
- inline OutputIterator
- adjacent_difference(InputIterator begin, InputIterator end,
- OutputIterator result,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _IIter, typename _OutputIterator>
+ inline _OutputIterator
+ adjacent_difference(_IIter __begin, _IIter __end,
+ _OutputIterator __result,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- return adjacent_difference(begin, end, result, std::minus<value_type>(),
- parallelism_tag);
+ typedef iterator_traits<_IIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ return adjacent_difference(
+ __begin, __end, __result, std::minus<_ValueType>(),
+ __parallelism_tag);
}
- template<typename InputIterator, typename OutputIterator>
- inline OutputIterator
- adjacent_difference(InputIterator begin, InputIterator end,
- OutputIterator result)
+ template<typename _IIter, typename _OutputIterator>
+ inline _OutputIterator
+ adjacent_difference(_IIter __begin, _IIter __end,
+ _OutputIterator __result)
{
- typedef iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- return adjacent_difference(begin, end, result, std::minus<value_type>());
+ typedef iterator_traits<_IIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ return adjacent_difference(__begin, __end, __result,
+ std::minus<_ValueType>());
}
- template<typename InputIterator, typename OutputIterator,
- typename BinaryOperation>
- inline OutputIterator
- adjacent_difference(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation binary_op,
- __gnu_parallel::_Parallelism parallelism_tag)
+ template<typename _IIter, typename _OutputIterator,
+ typename _BinaryOperation>
+ inline _OutputIterator
+ adjacent_difference(_IIter __begin, _IIter __end,
+ _OutputIterator __result, _BinaryOperation __binary_op,
+ __gnu_parallel::_Parallelism __parallelism_tag)
{
- typedef iterator_traits<InputIterator> traitsi_type;
- typedef typename traitsi_type::iterator_category iteratori_category;
+ typedef iterator_traits<_IIter> traitsi_type;
+ typedef typename traitsi_type::iterator_category _IIteratorCategory;
- typedef iterator_traits<OutputIterator> traitso_type;
- typedef typename traitso_type::iterator_category iteratoro_category;
+ typedef iterator_traits<_OutputIterator> _OTraitsType;
+ typedef typename _OTraitsType::iterator_category _OIterCategory;
- return adjacent_difference_switch(begin, end, result, binary_op,
- iteratori_category(),
- iteratoro_category(), parallelism_tag);
+ return __adjacent_difference_switch(
+ __begin, __end, __result, __binary_op,
+ _IIteratorCategory(), _OIterCategory(), __parallelism_tag);
}
- template<typename InputIterator, typename OutputIterator,
- typename BinaryOperation>
- inline OutputIterator
- adjacent_difference(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation binary_op)
+ template<typename _IIter, typename _OutputIterator,
+ typename _BinaryOperation>
+ inline _OutputIterator
+ adjacent_difference(_IIter __begin, _IIter __end,
+ _OutputIterator __result, _BinaryOperation __binary_op)
{
- typedef iterator_traits<InputIterator> traitsi_type;
- typedef typename traitsi_type::iterator_category iteratori_category;
+ typedef iterator_traits<_IIter> traitsi_type;
+ typedef typename traitsi_type::iterator_category _IIteratorCategory;
- typedef iterator_traits<OutputIterator> traitso_type;
- typedef typename traitso_type::iterator_category iteratoro_category;
+ typedef iterator_traits<_OutputIterator> _OTraitsType;
+ typedef typename _OTraitsType::iterator_category _OIterCategory;
- return adjacent_difference_switch(begin, end, result, binary_op,
- iteratori_category(),
- iteratoro_category());
+ return __adjacent_difference_switch(
+ __begin, __end, __result, __binary_op,
+ _IIteratorCategory(), _OIterCategory());
}
} // end namespace
} // end namespace
diff --git a/libstdc++-v3/include/parallel/numericfwd.h b/libstdc++-v3/include/parallel/numericfwd.h
index af2d0416f6f..e8d887be05c 100644
--- a/libstdc++-v3/include/parallel/numericfwd.h
+++ b/libstdc++-v3/include/parallel/numericfwd.h
@@ -52,7 +52,7 @@ namespace __parallel
template<typename _IIter, typename _Tp, typename _Tag>
_Tp
- accumulate_switch(_IIter, _IIter, _Tp, _Tag);
+ __accumulate_switch(_IIter, _IIter, _Tp, _Tag);
template<typename _IIter, typename _Tp, typename _BinaryOper>
_Tp
@@ -61,24 +61,24 @@ namespace __parallel
template<typename _IIter, typename _Tp, typename _BinaryOper>
_Tp
accumulate(_IIter, _IIter, _Tp, _BinaryOper,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter, typename _Tp, typename _BinaryOper>
_Tp
accumulate(_IIter, _IIter, _Tp, _BinaryOper,
- __gnu_parallel::_Parallelism);
+ __gnu_parallel::_Parallelism);
template<typename _IIter, typename _Tp, typename _BinaryOper,
- typename _Tag>
+ typename _Tag>
_Tp
- accumulate_switch(_IIter, _IIter, _Tp, _BinaryOper, _Tag);
+ __accumulate_switch(_IIter, _IIter, _Tp, _BinaryOper, _Tag);
template<typename _RAIter, typename _Tp, typename _BinaryOper>
_Tp
- accumulate_switch(_RAIter, _RAIter, _Tp, _BinaryOper,
- random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism
- = __gnu_parallel::parallel_unbalanced);
+ __accumulate_switch(_RAIter, _RAIter, _Tp, _BinaryOper,
+ random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism
+ = __gnu_parallel::parallel_unbalanced);
template<typename _IIter, typename _OIter>
_OIter
@@ -91,36 +91,36 @@ namespace __parallel
template<typename _IIter, typename _OIter>
_OIter
adjacent_difference(_IIter, _IIter, _OIter,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter, typename _OIter, typename _BinaryOper>
_OIter
adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter, typename _OIter>
_OIter
adjacent_difference(_IIter, _IIter, _OIter,
- __gnu_parallel::_Parallelism);
+ __gnu_parallel::_Parallelism);
template<typename _IIter, typename _OIter, typename _BinaryOper>
_OIter
adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper,
- __gnu_parallel::_Parallelism);
+ __gnu_parallel::_Parallelism);
template<typename _IIter, typename _OIter, typename _BinaryOper,
- typename _Tag1, typename _Tag2>
+ typename _Tag1, typename _Tag2>
_OIter
- adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper,
- _Tag1, _Tag2);
+ __adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper,
+ _Tag1, _Tag2);
template<typename _IIter, typename _OIter, typename _BinaryOper>
_OIter
- adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper,
- random_access_iterator_tag,
- random_access_iterator_tag,
- __gnu_parallel::_Parallelism parallelism
- = __gnu_parallel::parallel_unbalanced);
+ __adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper,
+ random_access_iterator_tag,
+ random_access_iterator_tag,
+ __gnu_parallel::_Parallelism __parallelism
+ = __gnu_parallel::parallel_unbalanced);
template<typename _IIter1, typename _IIter2, typename _Tp>
_Tp
@@ -129,46 +129,46 @@ namespace __parallel
template<typename _IIter1, typename _IIter2, typename _Tp>
_Tp
inner_product(_IIter1, _IIter1, _IIter2, _Tp,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _Tp>
_Tp
inner_product(_IIter1, _IIter1, _IIter2, _Tp,
- __gnu_parallel::_Parallelism);
+ __gnu_parallel::_Parallelism);
template<typename _IIter1, typename _IIter2, typename _Tp,
- typename _BinaryFunction1, typename _BinaryFunction2>
+ typename _BinaryFunction1, typename _BinaryFunction2>
_Tp
inner_product(_IIter1, _IIter1, _IIter2, _Tp,
- _BinaryFunction1, _BinaryFunction2);
+ _BinaryFunction1, _BinaryFunction2);
template<typename _IIter1, typename _IIter2, typename _Tp,
- typename _BinaryFunction1, typename _BinaryFunction2>
+ typename _BinaryFunction1, typename _BinaryFunction2>
_Tp
inner_product(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1,
- _BinaryFunction2, __gnu_parallel::sequential_tag);
+ _BinaryFunction2, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _Tp,
- typename BinaryFunction1, typename BinaryFunction2>
+ typename BinaryFunction1, typename BinaryFunction2>
_Tp
inner_product(_IIter1, _IIter1, _IIter2, _Tp, BinaryFunction1,
- BinaryFunction2, __gnu_parallel::_Parallelism);
+ BinaryFunction2, __gnu_parallel::_Parallelism);
template<typename _RAIter1, typename _RAIter2, typename _Tp,
- typename BinaryFunction1, typename BinaryFunction2>
+ typename BinaryFunction1, typename BinaryFunction2>
_Tp
- inner_product_switch(_RAIter1, _RAIter1, _RAIter2, _Tp, BinaryFunction1,
- BinaryFunction2, random_access_iterator_tag,
- random_access_iterator_tag,
- __gnu_parallel::_Parallelism
- = __gnu_parallel::parallel_unbalanced);
+ __inner_product_switch(_RAIter1, _RAIter1, _RAIter2, _Tp, BinaryFunction1,
+ BinaryFunction2, random_access_iterator_tag,
+ random_access_iterator_tag,
+ __gnu_parallel::_Parallelism
+ = __gnu_parallel::parallel_unbalanced);
template<typename _IIter1, typename _IIter2, typename _Tp,
- typename _BinaryFunction1, typename _BinaryFunction2,
- typename _Tag1, typename _Tag2>
+ typename _BinaryFunction1, typename _BinaryFunction2,
+ typename _Tag1, typename _Tag2>
_Tp
- inner_product_switch(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1,
- _BinaryFunction2, _Tag1, _Tag2);
+ __inner_product_switch(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1,
+ _BinaryFunction2, _Tag1, _Tag2);
template<typename _IIter, typename _OIter>
@@ -178,25 +178,25 @@ namespace __parallel
template<typename _IIter, typename _OIter, typename _BinaryOper>
_OIter
partial_sum(_IIter, _IIter, _OIter, _BinaryOper,
- __gnu_parallel::sequential_tag);
+ __gnu_parallel::sequential_tag);
template<typename _IIter, typename _OIter>
_OIter
- partial_sum(_IIter, _IIter, _OIter result);
+ partial_sum(_IIter, _IIter, _OIter __result);
template<typename _IIter, typename _OIter, typename _BinaryOper>
_OIter
partial_sum(_IIter, _IIter, _OIter, _BinaryOper);
template<typename _IIter, typename _OIter, typename _BinaryOper,
- typename _Tag1, typename _Tag2>
+ typename _Tag1, typename _Tag2>
_OIter
- partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2);
+ __partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2);
template<typename _IIter, typename _OIter, typename _BinaryOper>
_OIter
- partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper,
- random_access_iterator_tag, random_access_iterator_tag);
+ __partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper,
+ random_access_iterator_tag, random_access_iterator_tag);
} // end namespace
} // end namespace
diff --git a/libstdc++-v3/include/parallel/omp_loop.h b/libstdc++-v3/include/parallel/omp_loop.h
index 66f6d44bccc..7147961df98 100644
--- a/libstdc++-v3/include/parallel/omp_loop.h
+++ b/libstdc++-v3/include/parallel/omp_loop.h
@@ -44,73 +44,70 @@ namespace __gnu_parallel
/** @brief Embarrassingly parallel algorithm for random access
* iterators, using an OpenMP for loop.
*
- * @param begin Begin iterator of element sequence.
- * @param end End iterator of element sequence.
- * @param o User-supplied functor (comparator, predicate, adding
+ * @param __begin Begin iterator of element __sequence.
+ * @param __end End iterator of element __sequence.
+ * @param __o User-supplied functor (comparator, predicate, adding
* functor, etc.).
- * @param f Functor to "process" an element with op (depends on
+ * @param __f Functor to "process" an element with __op (depends on
* desired functionality, e. g. for std::for_each(), ...).
- * @param r Functor to "add" a single result to the already
- * processed elements (depends on functionality).
- * @param base Base value for reduction.
- * @param output Pointer to position where final result is written to
- * @param bound Maximum number of elements processed (e. g. for
+ * @param __r Functor to "add" a single __result to the already
+ * processed __elements (depends on functionality).
+ * @param __base Base value for reduction.
+ * @param __output Pointer to position where final result is written to
+ * @param __bound Maximum number of elements processed (e. g. for
* std::count_n()).
* @return User-supplied functor (that may contain a part of the result).
*/
-template<typename RandomAccessIterator,
- typename Op,
- typename Fu,
- typename Red,
- typename Result>
- Op
- for_each_template_random_access_omp_loop(RandomAccessIterator begin,
- RandomAccessIterator end,
- Op o, Fu& f, Red r, Result base,
- Result& output,
- typename std::iterator_traits
- <RandomAccessIterator>::
- difference_type bound)
+template<typename _RAIter,
+ typename _Op,
+ typename _Fu,
+ typename _Red,
+ typename _Result>
+ _Op
+ for_each_template_random_access_omp_loop(
+ _RAIter __begin, _RAIter __end, _Op __o, _Fu& __f, _Red __r,
+ _Result __base, _Result& __output,
+ typename std::iterator_traits<_RAIter>::difference_type __bound)
{
typedef typename
- std::iterator_traits<RandomAccessIterator>::difference_type
- difference_type;
+ std::iterator_traits<_RAIter>::difference_type
+ _DifferenceType;
- difference_type length = end - begin;
- thread_index_t num_threads =
- __gnu_parallel::min<difference_type>(get_max_threads(), length);
+ _DifferenceType __length = __end - __begin;
+ _ThreadIndex __num_threads =
+ __gnu_parallel::min<_DifferenceType>(__get_max_threads(), __length);
- Result *thread_results;
+ _Result *__thread_results;
-# pragma omp parallel num_threads(num_threads)
+# pragma omp parallel num_threads(__num_threads)
{
# pragma omp single
{
- num_threads = omp_get_num_threads();
- thread_results = new Result[num_threads];
+ __num_threads = omp_get_num_threads();
+ __thread_results = new _Result[__num_threads];
- for (thread_index_t i = 0; i < num_threads; ++i)
- thread_results[i] = Result();
+ for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
+ __thread_results[__i] = _Result();
}
- thread_index_t iam = omp_get_thread_num();
+ _ThreadIndex __iam = omp_get_thread_num();
-# pragma omp for schedule(dynamic, _Settings::get().workstealing_chunk_size)
- for (difference_type pos = 0; pos < length; ++pos)
- thread_results[iam] =
- r(thread_results[iam], f(o, begin+pos));
+#pragma omp for schedule(dynamic, _Settings::get().workstealing_chunk_size)
+ for (_DifferenceType __pos = 0; __pos < __length; ++__pos)
+ __thread_results[__iam] =
+ __r(__thread_results[__iam], __f(__o, __begin+__pos));
} //parallel
- for (thread_index_t i = 0; i < num_threads; ++i)
- output = r(output, thread_results[i]);
+ for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
+ __output = __r(__output, __thread_results[__i]);
- delete [] thread_results;
+ delete [] __thread_results;
// Points to last element processed (needed as return value for
// some algorithms like transform).
- f.finish_iterator = begin + length;
+ __f._M_finish_iterator = __begin + __length;
- return o;
+ return __o;
}
} // end namespace
diff --git a/libstdc++-v3/include/parallel/omp_loop_static.h b/libstdc++-v3/include/parallel/omp_loop_static.h
index 52361830729..cc3443ba1a9 100644
--- a/libstdc++-v3/include/parallel/omp_loop_static.h
+++ b/libstdc++-v3/include/parallel/omp_loop_static.h
@@ -44,72 +44,70 @@ namespace __gnu_parallel
/** @brief Embarrassingly parallel algorithm for random access
* iterators, using an OpenMP for loop with static scheduling.
*
- * @param begin Begin iterator of element sequence.
- * @param end End iterator of element sequence.
- * @param o User-supplied functor (comparator, predicate, adding
+ * @param __begin Begin iterator of element __sequence.
+ * @param __end End iterator of element __sequence.
+ * @param __o User-supplied functor (comparator, predicate, adding
* functor, ...).
- * @param f Functor to "process" an element with op (depends on
+ * @param __f Functor to "process" an element with __op (depends on
* desired functionality, e. g. for std::for_each(), ...).
- * @param r Functor to "add" a single result to the already processed
- * elements (depends on functionality).
- * @param base Base value for reduction.
- * @param output Pointer to position where final result is written to
- * @param bound Maximum number of elements processed (e. g. for
+ * @param __r Functor to "add" a single __result to the already processed
+ * __elements (depends on functionality).
+ * @param __base Base value for reduction.
+ * @param __output Pointer to position where final result is written to
+ * @param __bound Maximum number of elements processed (e. g. for
* std::count_n()).
* @return User-supplied functor (that may contain a part of the result).
*/
-template<typename RandomAccessIterator,
- typename Op,
- typename Fu,
- typename Red,
- typename Result>
- Op
- for_each_template_random_access_omp_loop_static(RandomAccessIterator begin,
- RandomAccessIterator end,
- Op o, Fu& f, Red r,
- Result base, Result& output,
- typename std::iterator_traits
- <RandomAccessIterator>::
- difference_type bound)
+template<typename _RAIter,
+ typename _Op,
+ typename _Fu,
+ typename _Red,
+ typename _Result>
+ _Op
+ for_each_template_random_access_omp_loop_static(
+ _RAIter __begin, _RAIter __end, _Op __o, _Fu& __f, _Red __r,
+ _Result __base, _Result& __output,
+ typename std::iterator_traits<_RAIter>::difference_type __bound)
{
typedef typename
- std::iterator_traits<RandomAccessIterator>::difference_type
- difference_type;
+ std::iterator_traits<_RAIter>::difference_type
+ _DifferenceType;
- difference_type length = end - begin;
- thread_index_t num_threads =
- std::min<difference_type>(get_max_threads(), length);
+ _DifferenceType __length = __end - __begin;
+ _ThreadIndex __num_threads =
+ std::min<_DifferenceType>(__get_max_threads(), __length);
- Result *thread_results;
+ _Result *__thread_results;
-# pragma omp parallel num_threads(num_threads)
+# pragma omp parallel num_threads(__num_threads)
{
# pragma omp single
{
- num_threads = omp_get_num_threads();
- thread_results = new Result[num_threads];
+ __num_threads = omp_get_num_threads();
+ __thread_results = new _Result[__num_threads];
- for (thread_index_t i = 0; i < num_threads; ++i)
- thread_results[i] = Result();
+ for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
+ __thread_results[__i] = _Result();
}
- thread_index_t iam = omp_get_thread_num();
+ _ThreadIndex __iam = omp_get_thread_num();
-# pragma omp for schedule(static, _Settings::get().workstealing_chunk_size)
- for (difference_type pos = 0; pos < length; ++pos)
- thread_results[iam] = r(thread_results[iam], f(o, begin+pos));
+#pragma omp for schedule(static, _Settings::get().workstealing_chunk_size)
+ for (_DifferenceType __pos = 0; __pos < __length; ++__pos)
+ __thread_results[__iam] = __r(__thread_results[__iam],
+ __f(__o, __begin+__pos));
} //parallel
- for (thread_index_t i = 0; i < num_threads; ++i)
- output = r(output, thread_results[i]);
+ for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
+ __output = __r(__output, __thread_results[__i]);
- delete [] thread_results;
+ delete [] __thread_results;
// Points to last element processed (needed as return value for
// some algorithms like transform).
- f.finish_iterator = begin + length;
+ __f.finish_iterator = __begin + __length;
- return o;
+ return __o;
}
} // end namespace
diff --git a/libstdc++-v3/include/parallel/par_loop.h b/libstdc++-v3/include/parallel/par_loop.h
index be61d4ca223..0a71831342e 100644
--- a/libstdc++-v3/include/parallel/par_loop.h
+++ b/libstdc++-v3/include/parallel/par_loop.h
@@ -45,89 +45,88 @@ namespace __gnu_parallel
* iterators, using hand-crafted parallelization by equal splitting
* the work.
*
- * @param begin Begin iterator of element sequence.
- * @param end End iterator of element sequence.
- * @param o User-supplied functor (comparator, predicate, adding
+ * @param __begin Begin iterator of element __sequence.
+ * @param __end End iterator of element __sequence.
+ * @param __o User-supplied functor (comparator, predicate, adding
* functor, ...)
- * @param f Functor to "process" an element with op (depends on
+ * @param __f Functor to "process" an element with __op (depends on
* desired functionality, e. g. for std::for_each(), ...).
- * @param r Functor to "add" a single result to the already
- * processed elements (depends on functionality).
- * @param base Base value for reduction.
- * @param output Pointer to position where final result is written to
- * @param bound Maximum number of elements processed (e. g. for
+ * @param __r Functor to "add" a single __result to the already
+ * processed __elements (depends on functionality).
+ * @param __base Base value for reduction.
+ * @param __output Pointer to position where final result is written to
+ * @param __bound Maximum number of elements processed (e. g. for
* std::count_n()).
* @return User-supplied functor (that may contain a part of the result).
*/
-template<typename RandomAccessIterator,
- typename Op,
- typename Fu,
- typename Red,
- typename Result>
- Op
- for_each_template_random_access_ed(RandomAccessIterator begin,
- RandomAccessIterator end,
- Op o, Fu& f, Red r, Result base,
- Result& output,
- typename std::iterator_traits
- <RandomAccessIterator>::
- difference_type bound)
+template<typename _RAIter,
+ typename _Op,
+ typename _Fu,
+ typename _Red,
+ typename _Result>
+ _Op
+ for_each_template_random_access_ed(
+ _RAIter __begin, _RAIter __end, _Op __o, _Fu& __f, _Red __r,
+ _Result __base, _Result& __output,
+ typename std::iterator_traits<_RAIter>::difference_type __bound)
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::difference_type difference_type;
- const difference_type length = end - begin;
- Result *thread_results;
- bool* constructed;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
+ const _DifferenceType __length = __end - __begin;
+ _Result *__thread_results;
+ bool* __constructed;
- thread_index_t num_threads =
- __gnu_parallel::min<difference_type>(get_max_threads(), length);
+ _ThreadIndex __num_threads =
+ __gnu_parallel::min<_DifferenceType>(__get_max_threads(), __length);
-# pragma omp parallel num_threads(num_threads)
+# pragma omp parallel num_threads(__num_threads)
{
# pragma omp single
{
- num_threads = omp_get_num_threads();
- thread_results = static_cast<Result*>(
- ::operator new(num_threads * sizeof(Result)));
- constructed = new bool[num_threads];
+ __num_threads = omp_get_num_threads();
+ __thread_results =
+ static_cast<_Result*>(
+ ::operator new(__num_threads * sizeof(_Result)));
+ __constructed = new bool[__num_threads];
}
- thread_index_t iam = omp_get_thread_num();
+ _ThreadIndex __iam = omp_get_thread_num();
// Neutral element.
- Result* reduct = static_cast<Result*>(::operator new(sizeof(Result)));
+ _Result* __reduct =
+ static_cast<_Result*>(::operator new(sizeof(_Result)));
- difference_type
- start = equally_split_point(length, num_threads, iam),
- stop = equally_split_point(length, num_threads, iam + 1);
+ _DifferenceType
+ __start = equally_split_point(__length, __num_threads, __iam),
+ __stop = equally_split_point(__length, __num_threads, __iam + 1);
- if (start < stop)
+ if (__start < __stop)
{
- new(reduct) Result(f(o, begin + start));
- ++start;
- constructed[iam] = true;
+ new(__reduct) _Result(__f(__o, __begin + __start));
+ ++__start;
+ __constructed[__iam] = true;
}
else
- constructed[iam] = false;
+ __constructed[__iam] = false;
- for (; start < stop; ++start)
- *reduct = r(*reduct, f(o, begin + start));
+ for (; __start < __stop; ++__start)
+ *__reduct = __r(*__reduct, __f(__o, __begin + __start));
- thread_results[iam] = *reduct;
+ __thread_results[__iam] = *__reduct;
} //parallel
- for (thread_index_t i = 0; i < num_threads; ++i)
- if (constructed[i])
- output = r(output, thread_results[i]);
+ for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
+ if (__constructed[__i])
+ __output = __r(__output, __thread_results[__i]);
// Points to last element processed (needed as return value for
// some algorithms like transform).
- f.finish_iterator = begin + length;
+ __f._M_finish_iterator = __begin + __length;
- delete[] thread_results;
- delete[] constructed;
+ delete[] __thread_results;
+ delete[] __constructed;
- return o;
+ return __o;
}
} // end namespace
diff --git a/libstdc++-v3/include/parallel/partial_sum.h b/libstdc++-v3/include/parallel/partial_sum.h
index 92630936d3f..b121e1ff8c7 100644
--- a/libstdc++-v3/include/parallel/partial_sum.h
+++ b/libstdc++-v3/include/parallel/partial_sum.h
@@ -23,8 +23,8 @@
// <http://www.gnu.org/licenses/>.
/** @file parallel/partial_sum.h
- * @brief Parallel implementation of std::partial_sum(), i. e. prefix
- * sums.
+ * @brief Parallel implementation of std::partial_sum(), i.e. prefix
+* sums.
* This file is a GNU parallel extension to the Standard C++ Library.
*/
@@ -44,175 +44,178 @@ namespace __gnu_parallel
// Problem: there is no 0-element given.
/** @brief Base case prefix sum routine.
- * @param begin Begin iterator of input sequence.
- * @param end End iterator of input sequence.
- * @param result Begin iterator of output sequence.
- * @param bin_op Associative binary function.
- * @param value Start value. Must be passed since the neutral
+ * @param __begin Begin iterator of input sequence.
+ * @param __end End iterator of input sequence.
+ * @param __result Begin iterator of output sequence.
+ * @param __bin_op Associative binary function.
+ * @param __value Start value. Must be passed since the neutral
* element is unknown in general.
* @return End iterator of output sequence. */
-template<typename InputIterator,
- typename OutputIterator,
- typename BinaryOperation>
- OutputIterator
- parallel_partial_sum_basecase(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation bin_op,
- typename std::iterator_traits
- <InputIterator>::value_type value)
+template<typename _IIter,
+ typename _OutputIterator,
+ typename _BinaryOperation>
+ _OutputIterator
+ __parallel_partial_sum_basecase(
+ _IIter __begin, _IIter __end, _OutputIterator __result,
+ _BinaryOperation __bin_op,
+ typename std::iterator_traits <_IIter>::value_type __value)
{
- if (begin == end)
- return result;
+ if (__begin == __end)
+ return __result;
- while (begin != end)
+ while (__begin != __end)
{
- value = bin_op(value, *begin);
- *result = value;
- ++result;
- ++begin;
+ __value = __bin_op(__value, *__begin);
+ *__result = __value;
+ ++__result;
+ ++__begin;
}
- return result;
+ return __result;
}
/** @brief Parallel partial sum implementation, two-phase approach,
no recursion.
- * @param begin Begin iterator of input sequence.
- * @param end End iterator of input sequence.
- * @param result Begin iterator of output sequence.
- * @param bin_op Associative binary function.
- * @param n Length of sequence.
- * @param num_threads Number of threads to use.
+ * @param __begin Begin iterator of input sequence.
+ * @param __end End iterator of input sequence.
+ * @param __result Begin iterator of output sequence.
+ * @param __bin_op Associative binary function.
+ * @param __n Length of sequence.
+ * @param __num_threads Number of threads to use.
* @return End iterator of output sequence.
*/
-template<typename InputIterator,
- typename OutputIterator,
- typename BinaryOperation>
- OutputIterator
- parallel_partial_sum_linear(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation bin_op,
- typename std::iterator_traits
- <InputIterator>::difference_type n)
+template<typename _IIter,
+ typename _OutputIterator,
+ typename _BinaryOperation>
+ _OutputIterator
+ __parallel_partial_sum_linear(
+ _IIter __begin, _IIter __end, _OutputIterator __result,
+ _BinaryOperation __bin_op,
+ typename std::iterator_traits<_IIter>::difference_type __n)
{
- typedef std::iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_IIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- if (begin == end)
- return result;
+ if (__begin == __end)
+ return __result;
- thread_index_t num_threads =
- std::min<difference_type>(get_max_threads(), n - 1);
+ _ThreadIndex __num_threads =
+ std::min<_DifferenceType>(__get_max_threads(), __n - 1);
- if (num_threads < 2)
+ if (__num_threads < 2)
{
- *result = *begin;
- return parallel_partial_sum_basecase(
- begin + 1, end, result + 1, bin_op, *begin);
+ *__result = *__begin;
+ return __parallel_partial_sum_basecase(
+ __begin + 1, __end, __result + 1, __bin_op, *__begin);
}
- difference_type* borders;
- value_type* sums;
+ _DifferenceType* __borders;
+ _ValueType* __sums;
const _Settings& __s = _Settings::get();
-# pragma omp parallel num_threads(num_threads)
+# pragma omp parallel num_threads(__num_threads)
{
# pragma omp single
{
- num_threads = omp_get_num_threads();
+ __num_threads = omp_get_num_threads();
- borders = new difference_type[num_threads + 2];
+ __borders = new _DifferenceType[__num_threads + 2];
if (__s.partial_sum_dilation == 1.0f)
- equally_split(n, num_threads + 1, borders);
+ equally_split(__n, __num_threads + 1, __borders);
else
{
- difference_type chunk_length =
- ((double)n
- / ((double)num_threads + __s.partial_sum_dilation)),
- borderstart = n - num_threads * chunk_length;
- borders[0] = 0;
- for (int i = 1; i < (num_threads + 1); ++i)
+ _DifferenceType __chunk_length =
+ ((double)__n
+ / ((double)__num_threads + __s.partial_sum_dilation)),
+ __borderstart = __n - __num_threads * __chunk_length;
+ __borders[0] = 0;
+ for (int __i = 1; __i < (__num_threads + 1); ++__i)
{
- borders[i] = borderstart;
- borderstart += chunk_length;
+ __borders[__i] = __borderstart;
+ __borderstart += __chunk_length;
}
- borders[num_threads + 1] = n;
+ __borders[__num_threads + 1] = __n;
}
- sums = static_cast<value_type*>(::operator new(sizeof(value_type)
- * num_threads));
- OutputIterator target_end;
+ __sums = static_cast<_ValueType*>(::operator new(sizeof(_ValueType)
+ * __num_threads));
+ _OutputIterator __target_end;
} //single
- thread_index_t iam = omp_get_thread_num();
- if (iam == 0)
+ _ThreadIndex __iam = omp_get_thread_num();
+ if (__iam == 0)
{
- *result = *begin;
- parallel_partial_sum_basecase(begin + 1, begin + borders[1],
- result + 1, bin_op, *begin);
- ::new(&(sums[iam])) value_type(*(result + borders[1] - 1));
+ *__result = *__begin;
+ __parallel_partial_sum_basecase(
+ __begin + 1, __begin + __borders[1], __result + 1,
+ __bin_op, *__begin);
+ ::new(&(__sums[__iam])) _ValueType(*(__result + __borders[1] - 1));
}
else
{
- ::new(&(sums[iam]))
- value_type(std::accumulate(begin + borders[iam] + 1,
- begin + borders[iam + 1],
- *(begin + borders[iam]),
- bin_op,
- __gnu_parallel::sequential_tag()));
+ ::new(&(__sums[__iam]))
+ _ValueType(std::accumulate(__begin + __borders[__iam] + 1,
+ __begin + __borders[__iam + 1],
+ *(__begin + __borders[__iam]),
+ __bin_op,
+ __gnu_parallel::sequential_tag()));
}
# pragma omp barrier
# pragma omp single
- parallel_partial_sum_basecase(
- sums + 1, sums + num_threads, sums + 1, bin_op, sums[0]);
+ __parallel_partial_sum_basecase(__sums + 1, __sums + __num_threads,
+ __sums + 1, __bin_op, __sums[0]);
# pragma omp barrier
// Still same team.
- parallel_partial_sum_basecase(begin + borders[iam + 1],
- begin + borders[iam + 2],
- result + borders[iam + 1], bin_op,
- sums[iam]);
+ __parallel_partial_sum_basecase(
+ __begin + __borders[__iam + 1],
+ __begin + __borders[__iam + 2],
+ __result + __borders[__iam + 1],
+ __bin_op, __sums[__iam]);
} //parallel
- ::operator delete(sums);
- delete[] borders;
+ ::operator delete(__sums);
+ delete[] __borders;
- return result + n;
+ return __result + __n;
}
-/** @brief Parallel partial sum front-end.
- * @param begin Begin iterator of input sequence.
- * @param end End iterator of input sequence.
- * @param result Begin iterator of output sequence.
- * @param bin_op Associative binary function.
+/** @brief Parallel partial sum front-__end.
+ * @param __begin Begin iterator of input sequence.
+ * @param __end End iterator of input sequence.
+ * @param __result Begin iterator of output sequence.
+ * @param __bin_op Associative binary function.
* @return End iterator of output sequence. */
-template<typename InputIterator,
- typename OutputIterator,
- typename BinaryOperation>
- OutputIterator
- parallel_partial_sum(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation bin_op)
+template<typename _IIter,
+ typename _OutputIterator,
+ typename _BinaryOperation>
+ _OutputIterator
+ __parallel_partial_sum(_IIter __begin, _IIter __end,
+ _OutputIterator __result, _BinaryOperation __bin_op)
{
- _GLIBCXX_CALL(begin - end)
+ _GLIBCXX_CALL(__begin - __end)
- typedef std::iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_IIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- difference_type n = end - begin;
+ _DifferenceType __n = __end - __begin;
switch (_Settings::get().partial_sum_algorithm)
{
case LINEAR:
// Need an initial offset.
- return parallel_partial_sum_linear(begin, end, result, bin_op, n);
+ return __parallel_partial_sum_linear(
+ __begin, __end, __result, __bin_op, __n);
default:
// Partial_sum algorithm not implemented.
_GLIBCXX_PARALLEL_ASSERT(0);
- return result + n;
+ return __result + __n;
}
}
}
diff --git a/libstdc++-v3/include/parallel/partition.h b/libstdc++-v3/include/parallel/partition.h
index b88133c59e6..f50e83bbfd3 100644
--- a/libstdc++-v3/include/parallel/partition.h
+++ b/libstdc++-v3/include/parallel/partition.h
@@ -45,231 +45,235 @@
namespace __gnu_parallel
{
/** @brief Parallel implementation of std::partition.
- * @param begin Begin iterator of input sequence to split.
- * @param end End iterator of input sequence to split.
- * @param pred Partition predicate, possibly including some kind of pivot.
- * @param num_threads Maximum number of threads to use for this task.
+ * @param __begin Begin iterator of input sequence to split.
+ * @param __end End iterator of input sequence to split.
+ * @param __pred Partition predicate, possibly including some kind of pivot.
+ * @param __num_threads Maximum number of threads to use for this task.
* @return Number of elements not fulfilling the predicate. */
-template<typename RandomAccessIterator, typename Predicate>
- typename std::iterator_traits<RandomAccessIterator>::difference_type
- parallel_partition(RandomAccessIterator begin, RandomAccessIterator end,
- Predicate pred, thread_index_t num_threads)
+template<typename _RAIter, typename _Predicate>
+ typename std::iterator_traits<_RAIter>::difference_type
+ __parallel_partition(_RAIter __begin, _RAIter __end,
+ _Predicate __pred, _ThreadIndex __num_threads)
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- difference_type n = end - begin;
+ _DifferenceType __n = __end - __begin;
- _GLIBCXX_CALL(n)
+ _GLIBCXX_CALL(__n)
const _Settings& __s = _Settings::get();
// Shared.
- _GLIBCXX_VOLATILE difference_type left = 0, right = n - 1;
- _GLIBCXX_VOLATILE difference_type leftover_left, leftover_right;
- _GLIBCXX_VOLATILE difference_type leftnew, rightnew;
+ _GLIBCXX_VOLATILE _DifferenceType __left = 0, __right = __n - 1;
+ _GLIBCXX_VOLATILE _DifferenceType __leftover_left, __leftover_right;
+ _GLIBCXX_VOLATILE _DifferenceType __leftnew, __rightnew;
- bool* reserved_left = NULL, * reserved_right = NULL;
+ bool* __reserved_left = NULL, * __reserved_right = NULL;
- difference_type chunk_size;
+ _DifferenceType __chunk_size;
- omp_lock_t result_lock;
- omp_init_lock(&result_lock);
+ omp_lock_t __result_lock;
+ omp_init_lock(&__result_lock);
//at least two chunks per thread
- if(right - left + 1 >= 2 * num_threads * chunk_size)
-# pragma omp parallel num_threads(num_threads)
+ if(__right - __left + 1 >= 2 * __num_threads * __chunk_size)
+# pragma omp parallel num_threads(__num_threads)
{
# pragma omp single
{
- num_threads = omp_get_num_threads();
- reserved_left = new bool[num_threads];
- reserved_right = new bool[num_threads];
+ __num_threads = omp_get_num_threads();
+ __reserved_left = new bool[__num_threads];
+ __reserved_right = new bool[__num_threads];
if (__s.partition_chunk_share > 0.0)
- chunk_size = std::max<difference_type>(__s.partition_chunk_size,
- (double)n * __s.partition_chunk_share
- / (double)num_threads);
+ __chunk_size = std::max<_DifferenceType>(
+ __s.partition_chunk_size,
+ (double)__n * __s.partition_chunk_share /
+ (double)__num_threads);
else
- chunk_size = __s.partition_chunk_size;
+ __chunk_size = __s.partition_chunk_size;
}
- while (right - left + 1 >= 2 * num_threads * chunk_size)
+ while (__right - __left + 1 >= 2 * __num_threads * __chunk_size)
{
# pragma omp single
{
- difference_type num_chunks = (right - left + 1) / chunk_size;
+ _DifferenceType __num_chunks
+ = (__right - __left + 1) / __chunk_size;
- for (int r = 0; r < num_threads; ++r)
+ for (int __r = 0; __r < __num_threads; ++__r)
{
- reserved_left[r] = false;
- reserved_right[r] = false;
+ __reserved_left[__r] = false;
+ __reserved_right[__r] = false;
}
- leftover_left = 0;
- leftover_right = 0;
+ __leftover_left = 0;
+ __leftover_right = 0;
} //implicit barrier
// Private.
- difference_type thread_left, thread_left_border,
- thread_right, thread_right_border;
- thread_left = left + 1;
+ _DifferenceType __thread_left, __thread_left_border,
+ thread_right, __thread_right_border;
+ __thread_left = __left + 1;
// Just to satisfy the condition below.
- thread_left_border = thread_left - 1;
- thread_right = n - 1;
- thread_right_border = thread_right + 1;
+ __thread_left_border = __thread_left - 1;
+ thread_right = __n - 1;
+ __thread_right_border = thread_right + 1;
- bool iam_finished = false;
- while (!iam_finished)
+ bool __iam_finished = false;
+ while (!__iam_finished)
{
- if (thread_left > thread_left_border)
+ if (__thread_left > __thread_left_border)
{
- omp_set_lock(&result_lock);
- if (left + (chunk_size - 1) > right)
- iam_finished = true;
+ omp_set_lock(&__result_lock);
+ if (__left + (__chunk_size - 1) > __right)
+ __iam_finished = true;
else
{
- thread_left = left;
- thread_left_border = left + (chunk_size - 1);
- left += chunk_size;
+ __thread_left = __left;
+ __thread_left_border = __left + (__chunk_size - 1);
+ __left += __chunk_size;
}
- omp_unset_lock(&result_lock);
+ omp_unset_lock(&__result_lock);
}
- if (thread_right < thread_right_border)
+ if (thread_right < __thread_right_border)
{
- omp_set_lock(&result_lock);
- if (left > right - (chunk_size - 1))
- iam_finished = true;
+ omp_set_lock(&__result_lock);
+ if (__left > __right - (__chunk_size - 1))
+ __iam_finished = true;
else
{
- thread_right = right;
- thread_right_border = right - (chunk_size - 1);
- right -= chunk_size;
+ thread_right = __right;
+ __thread_right_border = __right - (__chunk_size - 1);
+ __right -= __chunk_size;
}
- omp_unset_lock(&result_lock);
+ omp_unset_lock(&__result_lock);
}
- if (iam_finished)
+ if (__iam_finished)
break;
// Swap as usual.
- while (thread_left < thread_right)
+ while (__thread_left < thread_right)
{
- while (pred(begin[thread_left])
- && thread_left <= thread_left_border)
- ++thread_left;
- while (!pred(begin[thread_right])
- && thread_right >= thread_right_border)
+ while (__pred(__begin[__thread_left])
+ && __thread_left <= __thread_left_border)
+ ++__thread_left;
+ while (!__pred(__begin[thread_right])
+ && thread_right >= __thread_right_border)
--thread_right;
- if (thread_left > thread_left_border
- || thread_right < thread_right_border)
- // Fetch new chunk(s).
+ if (__thread_left > __thread_left_border
+ || thread_right < __thread_right_border)
+ // Fetch new chunk(__s).
break;
- std::swap(begin[thread_left], begin[thread_right]);
- ++thread_left;
+ std::swap(__begin[__thread_left], __begin[thread_right]);
+ ++__thread_left;
--thread_right;
}
}
// Now swap the leftover chunks to the right places.
- if (thread_left <= thread_left_border)
+ if (__thread_left <= __thread_left_border)
# pragma omp atomic
- ++leftover_left;
- if (thread_right >= thread_right_border)
+ ++__leftover_left;
+ if (thread_right >= __thread_right_border)
# pragma omp atomic
- ++leftover_right;
+ ++__leftover_right;
# pragma omp barrier
# pragma omp single
{
- leftnew = left - leftover_left * chunk_size;
- rightnew = right + leftover_right * chunk_size;
+ __leftnew = __left - __leftover_left * __chunk_size;
+ __rightnew = __right + __leftover_right * __chunk_size;
}
# pragma omp barrier
- // <=> thread_left_border + (chunk_size - 1) >= leftnew
- if (thread_left <= thread_left_border
- && thread_left_border >= leftnew)
+ // <=> __thread_left_border + (__chunk_size - 1) >= __leftnew
+ if (__thread_left <= __thread_left_border
+ && __thread_left_border >= __leftnew)
{
// Chunk already in place, reserve spot.
- reserved_left[(left - (thread_left_border + 1)) / chunk_size]
+ __reserved_left
+ [(__left - (__thread_left_border + 1)) / __chunk_size]
= true;
}
- // <=> thread_right_border - (chunk_size - 1) <= rightnew
- if (thread_right >= thread_right_border
- && thread_right_border <= rightnew)
+ // <=> __thread_right_border - (__chunk_size - 1) <= __rightnew
+ if (thread_right >= __thread_right_border
+ && __thread_right_border <= __rightnew)
{
// Chunk already in place, reserve spot.
- reserved_right[((thread_right_border - 1) - right)
- / chunk_size] = true;
+ __reserved_right[((__thread_right_border - 1) - __right)
+ / __chunk_size] = true;
}
# pragma omp barrier
- if (thread_left <= thread_left_border
- && thread_left_border < leftnew)
+ if (__thread_left <= __thread_left_border
+ && __thread_left_border < __leftnew)
{
// Find spot and swap.
- difference_type swapstart = -1;
- omp_set_lock(&result_lock);
- for (int r = 0; r < leftover_left; ++r)
- if (!reserved_left[r])
+ _DifferenceType __swapstart = -1;
+ omp_set_lock(&__result_lock);
+ for (int __r = 0; __r < __leftover_left; ++__r)
+ if (!__reserved_left[__r])
{
- reserved_left[r] = true;
- swapstart = left - (r + 1) * chunk_size;
+ __reserved_left[__r] = true;
+ __swapstart = __left - (__r + 1) * __chunk_size;
break;
}
- omp_unset_lock(&result_lock);
+ omp_unset_lock(&__result_lock);
#if _GLIBCXX_ASSERTIONS
- _GLIBCXX_PARALLEL_ASSERT(swapstart != -1);
+ _GLIBCXX_PARALLEL_ASSERT(__swapstart != -1);
#endif
- std::swap_ranges(begin + thread_left_border
- - (chunk_size - 1),
- begin + thread_left_border + 1,
- begin + swapstart);
+ std::swap_ranges(__begin + __thread_left_border
+ - (__chunk_size - 1),
+ __begin + __thread_left_border + 1,
+ __begin + __swapstart);
}
- if (thread_right >= thread_right_border
- && thread_right_border > rightnew)
+ if (thread_right >= __thread_right_border
+ && __thread_right_border > __rightnew)
{
// Find spot and swap
- difference_type swapstart = -1;
- omp_set_lock(&result_lock);
- for (int r = 0; r < leftover_right; ++r)
- if (!reserved_right[r])
+ _DifferenceType __swapstart = -1;
+ omp_set_lock(&__result_lock);
+ for (int __r = 0; __r < __leftover_right; ++__r)
+ if (!__reserved_right[__r])
{
- reserved_right[r] = true;
- swapstart = right + r * chunk_size + 1;
+ __reserved_right[__r] = true;
+ __swapstart = __right + __r * __chunk_size + 1;
break;
}
- omp_unset_lock(&result_lock);
+ omp_unset_lock(&__result_lock);
#if _GLIBCXX_ASSERTIONS
- _GLIBCXX_PARALLEL_ASSERT(swapstart != -1);
+ _GLIBCXX_PARALLEL_ASSERT(__swapstart != -1);
#endif
- std::swap_ranges(begin + thread_right_border,
- begin + thread_right_border + chunk_size,
- begin + swapstart);
+ std::swap_ranges(
+ __begin + __thread_right_border,
+ __begin + __thread_right_border + __chunk_size,
+ __begin + __swapstart);
}
#if _GLIBCXX_ASSERTIONS
# pragma omp barrier
# pragma omp single
{
- for (int r = 0; r < leftover_left; ++r)
- _GLIBCXX_PARALLEL_ASSERT(reserved_left[r]);
- for (int r = 0; r < leftover_right; ++r)
- _GLIBCXX_PARALLEL_ASSERT(reserved_right[r]);
+ for (int __r = 0; __r < __leftover_left; ++__r)
+ _GLIBCXX_PARALLEL_ASSERT(__reserved_left[__r]);
+ for (int __r = 0; __r < __leftover_right; ++__r)
+ _GLIBCXX_PARALLEL_ASSERT(__reserved_right[__r]);
}
# pragma omp barrier
@@ -277,149 +281,150 @@ template<typename RandomAccessIterator, typename Predicate>
# pragma omp barrier
- left = leftnew;
- right = rightnew;
+ __left = __leftnew;
+ __right = __rightnew;
}
-# pragma omp flush(left, right)
+# pragma omp flush(__left, __right)
} // end "recursion" //parallel
- difference_type final_left = left, final_right = right;
+ _DifferenceType __final_left = __left, __final_right = __right;
- while (final_left < final_right)
+ while (__final_left < __final_right)
{
// Go right until key is geq than pivot.
- while (pred(begin[final_left]) && final_left < final_right)
- ++final_left;
+ while (__pred(__begin[__final_left]) && __final_left < __final_right)
+ ++__final_left;
// Go left until key is less than pivot.
- while (!pred(begin[final_right]) && final_left < final_right)
- --final_right;
+ while (!__pred(__begin[__final_right]) && __final_left < __final_right)
+ --__final_right;
- if (final_left == final_right)
+ if (__final_left == __final_right)
break;
- std::swap(begin[final_left], begin[final_right]);
- ++final_left;
- --final_right;
+ std::swap(__begin[__final_left], __begin[__final_right]);
+ ++__final_left;
+ --__final_right;
}
// All elements on the left side are < piv, all elements on the
// right are >= piv
- delete[] reserved_left;
- delete[] reserved_right;
+ delete[] __reserved_left;
+ delete[] __reserved_right;
- omp_destroy_lock(&result_lock);
+ omp_destroy_lock(&__result_lock);
- // Element "between" final_left and final_right might not have
+ // Element "between" __final_left and __final_right might not have
// been regarded yet
- if (final_left < n && !pred(begin[final_left]))
+ if (__final_left < __n && !__pred(__begin[__final_left]))
// Really swapped.
- return final_left;
+ return __final_left;
else
- return final_left + 1;
+ return __final_left + 1;
}
/**
* @brief Parallel implementation of std::nth_element().
- * @param begin Begin iterator of input sequence.
- * @param nth Iterator of element that must be in position afterwards.
- * @param end End iterator of input sequence.
- * @param comp Comparator.
+ * @param __begin Begin iterator of input sequence.
+ * @param __nth _Iterator of element that must be in position afterwards.
+ * @param __end End iterator of input sequence.
+ * @param __comp Comparator.
*/
-template<typename RandomAccessIterator, typename Comparator>
+template<typename _RAIter, typename _Compare>
void
- parallel_nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
- RandomAccessIterator end, Comparator comp)
+ parallel_nth_element(_RAIter __begin, _RAIter __nth,
+ _RAIter __end, _Compare __comp)
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- _GLIBCXX_CALL(end - begin)
+ _GLIBCXX_CALL(__end - __begin)
- RandomAccessIterator split;
- random_number rng;
+ _RAIter __split;
+ _RandomNumber __rng;
- difference_type minimum_length =
- std::max<difference_type>(2, _Settings::get().partition_minimal_n);
+ _DifferenceType minimum_length =
+ std::max<_DifferenceType>(2, _Settings::get().partition_minimal_n);
// Break if input range to small.
- while (static_cast<sequence_index_t>(end - begin) >= minimum_length)
+ while (static_cast<_SequenceIndex>(__end - __begin) >= minimum_length)
{
- difference_type n = end - begin;
+ _DifferenceType __n = __end - __begin;
- RandomAccessIterator pivot_pos = begin + rng(n);
+ _RAIter __pivot_pos = __begin + __rng(__n);
- // Swap pivot_pos value to end.
- if (pivot_pos != (end - 1))
- std::swap(*pivot_pos, *(end - 1));
- pivot_pos = end - 1;
+ // Swap __pivot_pos value to end.
+ if (__pivot_pos != (__end - 1))
+ std::swap(*__pivot_pos, *(__end - 1));
+ __pivot_pos = __end - 1;
- // XXX Comparator must have first_value_type, second_value_type,
- // result_type
- // Comparator == __gnu_parallel::lexicographic<S, int,
- // __gnu_parallel::less<S, S> >
- // pivot_pos == std::pair<S, int>*
- // XXX binder2nd only for RandomAccessIterators??
- __gnu_parallel::binder2nd<Comparator, value_type, value_type, bool>
- pred(comp, *pivot_pos);
+ // XXX _Compare must have first__ValueType, second__ValueType,
+ // _ResultType
+ // _Compare == __gnu_parallel::_Lexicographic<S, int,
+ // __gnu_parallel::_Less<S, S> >
+ // __pivot_pos == std::pair<S, int>*
+ // XXX binder2nd only for _RAIters??
+ __gnu_parallel::binder2nd<_Compare, _ValueType, _ValueType, bool>
+ __pred(__comp, *__pivot_pos);
// Divide, leave pivot unchanged in last place.
- RandomAccessIterator split_pos1, split_pos2;
- split_pos1 = begin + parallel_partition(begin, end - 1, pred,
- get_max_threads());
+ _RAIter __split_pos1, __split_pos2;
+ __split_pos1 = __begin
+ + __parallel_partition(__begin, __end - 1, __pred,
+ __get_max_threads());
- // Left side: < pivot_pos; right side: >= pivot_pos
+ // Left side: < __pivot_pos; __right side: >= __pivot_pos
// Swap pivot back to middle.
- if (split_pos1 != pivot_pos)
- std::swap(*split_pos1, *pivot_pos);
- pivot_pos = split_pos1;
+ if (__split_pos1 != __pivot_pos)
+ std::swap(*__split_pos1, *__pivot_pos);
+ __pivot_pos = __split_pos1;
- // In case all elements are equal, split_pos1 == 0
- if ((split_pos1 + 1 - begin) < (n >> 7)
- || (end - split_pos1) < (n >> 7))
+ // In case all elements are equal, __split_pos1 == 0
+ if ((__split_pos1 + 1 - __begin) < (__n >> 7)
+ || (__end - __split_pos1) < (__n >> 7))
{
// Very unequal split, one part smaller than one 128th
// elements not strictly larger than the pivot.
- __gnu_parallel::unary_negate<__gnu_parallel::
- binder1st<Comparator, value_type, value_type, bool>, value_type>
- pred(__gnu_parallel::binder1st<Comparator, value_type,
- value_type, bool>(comp, *pivot_pos));
+ __gnu_parallel::__unary_negate<__gnu_parallel::
+ __binder1st<_Compare, _ValueType, _ValueType, bool>, _ValueType>
+ __pred(__gnu_parallel::__binder1st<_Compare, _ValueType,
+ _ValueType, bool>(__comp, *__pivot_pos));
// Find other end of pivot-equal range.
- split_pos2 = __gnu_sequential::partition(split_pos1 + 1,
- end, pred);
+ __split_pos2 = __gnu_sequential::partition(__split_pos1 + 1,
+ __end, __pred);
}
else
// Only skip the pivot.
- split_pos2 = split_pos1 + 1;
+ __split_pos2 = __split_pos1 + 1;
// Compare iterators.
- if (split_pos2 <= nth)
- begin = split_pos2;
- else if (nth < split_pos1)
- end = split_pos1;
+ if (__split_pos2 <= __nth)
+ __begin = __split_pos2;
+ else if (__nth < __split_pos1)
+ __end = __split_pos1;
else
break;
}
- // Only at most _Settings::partition_minimal_n elements left.
- __gnu_sequential::sort(begin, end, comp);
+ // Only at most _Settings::partition_minimal_n __elements __left.
+ __gnu_sequential::sort(__begin, __end, __comp);
}
/** @brief Parallel implementation of std::partial_sort().
-* @param begin Begin iterator of input sequence.
-* @param middle Sort until this position.
-* @param end End iterator of input sequence.
-* @param comp Comparator. */
-template<typename RandomAccessIterator, typename Comparator>
+* @param __begin Begin iterator of input sequence.
+* @param __middle Sort until this position.
+* @param __end End iterator of input sequence.
+* @param __comp Comparator. */
+template<typename _RAIter, typename _Compare>
void
- parallel_partial_sort(RandomAccessIterator begin,
- RandomAccessIterator middle,
- RandomAccessIterator end, Comparator comp)
+ parallel_partial_sort(_RAIter __begin,
+ _RAIter __middle,
+ _RAIter __end, _Compare __comp)
{
- parallel_nth_element(begin, middle, end, comp);
- std::sort(begin, middle, comp);
+ parallel_nth_element(__begin, __middle, __end, __comp);
+ std::sort(__begin, __middle, __comp);
}
} //namespace __gnu_parallel
diff --git a/libstdc++-v3/include/parallel/queue.h b/libstdc++-v3/include/parallel/queue.h
index 9686a9ac2b6..348bb1ac900 100644
--- a/libstdc++-v3/include/parallel/queue.h
+++ b/libstdc++-v3/include/parallel/queue.h
@@ -45,104 +45,110 @@ namespace __gnu_parallel
* atomic access. push_front() and pop_front() must not be called
* concurrently to each other, while pop_back() can be called
* concurrently at all times.
- * @c empty(), @c size(), and @c top() are intentionally not provided.
+ * @__c empty(), @__c size(), and @__c top() are intentionally not provided.
* Calling them would not make sense in a concurrent setting.
- * @param T Contained element type. */
- template<typename T>
- class RestrictedBoundedConcurrentQueue
+ * @param _Tp Contained element type. */
+ template<typename _Tp>
+ class _RestrictedBoundedConcurrentQueue
{
private:
/** @brief Array of elements, seen as cyclic buffer. */
- T* base;
+ _Tp* _M_base;
/** @brief Maximal number of elements contained at the same time. */
- sequence_index_t max_size;
+ _SequenceIndex _M_max_size;
- /** @brief Cyclic begin and end pointers contained in one
- atomically changeable value. */
- _GLIBCXX_VOLATILE lcas_t borders;
+ /** @brief Cyclic __begin and __end pointers contained in one
+ atomically changeable value. */
+ _GLIBCXX_VOLATILE _CASable _M_borders;
public:
/** @brief Constructor. Not to be called concurrent, of course.
- * @param max_size Maximal number of elements to be contained. */
- RestrictedBoundedConcurrentQueue(sequence_index_t max_size)
+ * @param _M_max_size Maximal number of elements to be contained. */
+ _RestrictedBoundedConcurrentQueue(_SequenceIndex _M_max_size)
{
- this->max_size = max_size;
- base = new T[max_size];
- borders = encode2(0, 0);
+ this->_M_max_size = _M_max_size;
+ _M_base = new _Tp[_M_max_size];
+ _M_borders = __encode2(0, 0);
#pragma omp flush
}
/** @brief Destructor. Not to be called concurrent, of course. */
- ~RestrictedBoundedConcurrentQueue()
- { delete[] base; }
+ ~_RestrictedBoundedConcurrentQueue()
+ { delete[] _M_base; }
/** @brief Pushes one element into the queue at the front end.
* Must not be called concurrently with pop_front(). */
void
- push_front(const T& t)
+ push_front(const _Tp& __t)
{
- lcas_t former_borders = borders;
- int former_front, former_back;
- decode2(former_borders, former_front, former_back);
- *(base + former_front % max_size) = t;
+ _CASable __former_borders = _M_borders;
+ int __former_front, __former_back;
+ decode2(__former_borders, __former_front, __former_back);
+ *(_M_base + __former_front % _M_max_size) = __t;
#if _GLIBCXX_ASSERTIONS
- // Otherwise: front - back > max_size eventually.
- _GLIBCXX_PARALLEL_ASSERT(((former_front + 1) - former_back)
- <= max_size);
+ // Otherwise: front - back > _M_max_size eventually.
+ _GLIBCXX_PARALLEL_ASSERT(((__former_front + 1) - __former_back)
+ <= _M_max_size);
#endif
- fetch_and_add(&borders, encode2(1, 0));
+ __fetch_and_add(&_M_borders, __encode2(1, 0));
}
/** @brief Pops one element from the queue at the front end.
* Must not be called concurrently with pop_front(). */
bool
- pop_front(T& t)
+ pop_front(_Tp& __t)
{
- int former_front, former_back;
+ int __former_front, __former_back;
#pragma omp flush
- decode2(borders, former_front, former_back);
- while (former_front > former_back)
- {
- // Chance.
- lcas_t former_borders = encode2(former_front, former_back);
- lcas_t new_borders = encode2(former_front - 1, former_back);
- if (compare_and_swap(&borders, former_borders, new_borders))
- {
- t = *(base + (former_front - 1) % max_size);
- return true;
- }
+ decode2(_M_borders, __former_front, __former_back);
+ while (__former_front > __former_back)
+ {
+ // Chance.
+ _CASable
+ __former_borders = __encode2(__former_front, __former_back);
+ _CASable
+ __new_borders = __encode2(__former_front - 1, __former_back);
+ if (__compare_and_swap(
+ &_M_borders, __former_borders, __new_borders))
+ {
+ __t = *(_M_base + (__former_front - 1) % _M_max_size);
+ return true;
+ }
#pragma omp flush
- decode2(borders, former_front, former_back);
- }
- return false;
+ decode2(_M_borders, __former_front, __former_back);
+ }
+ return false;
}
/** @brief Pops one element from the queue at the front end.
* Must not be called concurrently with pop_front(). */
bool
- pop_back(T& t) //queue behavior
+ pop_back(_Tp& __t) //queue behavior
{
- int former_front, former_back;
+ int __former_front, __former_back;
#pragma omp flush
- decode2(borders, former_front, former_back);
- while (former_front > former_back)
- {
- // Chance.
- lcas_t former_borders = encode2(former_front, former_back);
- lcas_t new_borders = encode2(former_front, former_back + 1);
- if (compare_and_swap(&borders, former_borders, new_borders))
- {
- t = *(base + former_back % max_size);
- return true;
- }
+ decode2(_M_borders, __former_front, __former_back);
+ while (__former_front > __former_back)
+ {
+ // Chance.
+ _CASable
+ __former_borders = __encode2(__former_front, __former_back);
+ _CASable
+ __new_borders = __encode2(__former_front, __former_back + 1);
+ if (__compare_and_swap(
+ &_M_borders, __former_borders, __new_borders))
+ {
+ __t = *(_M_base + __former_back % _M_max_size);
+ return true;
+ }
#pragma omp flush
- decode2(borders, former_front, former_back);
- }
- return false;
+ decode2(_M_borders, __former_front, __former_back);
+ }
+ return false;
}
};
-} //namespace __gnu_parallel
+} //namespace __gnu_parallel
#undef _GLIBCXX_VOLATILE
diff --git a/libstdc++-v3/include/parallel/quicksort.h b/libstdc++-v3/include/parallel/quicksort.h
index 712b479e7e7..1ed46b4a77f 100644
--- a/libstdc++-v3/include/parallel/quicksort.h
+++ b/libstdc++-v3/include/parallel/quicksort.h
@@ -38,140 +38,141 @@
namespace __gnu_parallel
{
/** @brief Unbalanced quicksort divide step.
- * @param begin Begin iterator of subsequence.
- * @param end End iterator of subsequence.
- * @param comp Comparator.
- * @param pivot_rank Desired rank of the pivot.
- * @param num_samples Choose pivot from that many samples.
- * @param num_threads Number of threads that are allowed to work on
+ * @param __begin Begin iterator of subsequence.
+ * @param __end End iterator of subsequence.
+ * @param __comp Comparator.
+ * @param __pivot_rank Desired __rank of the pivot.
+ * @param __num_samples Choose pivot from that many samples.
+ * @param __num_threads Number of threads that are allowed to work on
* this part.
*/
- template<typename RandomAccessIterator, typename Comparator>
- typename std::iterator_traits<RandomAccessIterator>::difference_type
- parallel_sort_qs_divide(RandomAccessIterator begin,
- RandomAccessIterator end,
- Comparator comp, typename std::iterator_traits
- <RandomAccessIterator>::difference_type pivot_rank,
- typename std::iterator_traits
- <RandomAccessIterator>::difference_type
- num_samples, thread_index_t num_threads)
+ template<typename _RAIter, typename _Compare>
+ typename std::iterator_traits<_RAIter>::difference_type
+ __parallel_sort_qs_divide(_RAIter __begin,
+ _RAIter __end,
+ _Compare __comp, typename std::iterator_traits
+ <_RAIter>::difference_type __pivot_rank,
+ typename std::iterator_traits
+ <_RAIter>::difference_type
+ __num_samples, _ThreadIndex __num_threads)
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- difference_type n = end - begin;
- num_samples = std::min(num_samples, n);
+ _DifferenceType __n = __end - __begin;
+ __num_samples = std::min(__num_samples, __n);
// Allocate uninitialized, to avoid default constructor.
- value_type* samples =
- static_cast<value_type*>(::operator new(num_samples
- * sizeof(value_type)));
+ _ValueType* __samples =
+ static_cast<_ValueType*>(::operator new(__num_samples
+ * sizeof(_ValueType)));
- for (difference_type s = 0; s < num_samples; ++s)
- {
- const unsigned long long index = static_cast<unsigned long long>(s)
- * n / num_samples;
- ::new(&(samples[s])) value_type(begin[index]);
- }
+ for (_DifferenceType __s = 0; __s < __num_samples; ++__s)
+ {
+ const unsigned long long __index
+ = static_cast<unsigned long long>(__s) * __n / __num_samples;
+ ::new(&(__samples[__s])) _ValueType(__begin[__index]);
+ }
- __gnu_sequential::sort(samples, samples + num_samples, comp);
+ __gnu_sequential::sort(__samples, __samples + __num_samples, __comp);
- value_type& pivot = samples[pivot_rank * num_samples / n];
+ _ValueType& pivot = __samples[__pivot_rank * __num_samples / __n];
- __gnu_parallel::binder2nd<Comparator, value_type, value_type, bool>
- pred(comp, pivot);
- difference_type split =
- parallel_partition(begin, end, pred, num_threads);
+ __gnu_parallel::binder2nd<_Compare, _ValueType, _ValueType, bool>
+ __pred(__comp, pivot);
+ _DifferenceType __split =
+ __parallel_partition(__begin, __end, __pred, __num_threads);
- ::operator delete(samples);
+ ::operator delete(__samples);
- return split;
+ return __split;
}
/** @brief Unbalanced quicksort conquer step.
- * @param begin Begin iterator of subsequence.
- * @param end End iterator of subsequence.
- * @param comp Comparator.
- * @param num_threads Number of threads that are allowed to work on
+ * @param __begin Begin iterator of subsequence.
+ * @param __end End iterator of subsequence.
+ * @param __comp Comparator.
+ * @param __num_threads Number of threads that are allowed to work on
* this part.
*/
- template<typename RandomAccessIterator, typename Comparator>
+ template<typename _RAIter, typename _Compare>
void
- parallel_sort_qs_conquer(RandomAccessIterator begin,
- RandomAccessIterator end,
- Comparator comp,
- thread_index_t num_threads)
+ __parallel_sort_qs_conquer(_RAIter __begin,
+ _RAIter __end,
+ _Compare __comp,
+ _ThreadIndex __num_threads)
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- if (num_threads <= 1)
- {
- __gnu_sequential::sort(begin, end, comp);
- return;
- }
+ if (__num_threads <= 1)
+ {
+ __gnu_sequential::sort(__begin, __end, __comp);
+ return;
+ }
- difference_type n = end - begin, pivot_rank;
+ _DifferenceType __n = __end - __begin, __pivot_rank;
- if (n <= 1)
- return;
+ if (__n <= 1)
+ return;
- thread_index_t num_threads_left;
+ _ThreadIndex __num_threads_left;
- if ((num_threads % 2) == 1)
- num_threads_left = num_threads / 2 + 1;
+ if ((__num_threads % 2) == 1)
+ __num_threads_left = __num_threads / 2 + 1;
else
- num_threads_left = num_threads / 2;
+ __num_threads_left = __num_threads / 2;
- pivot_rank = n * num_threads_left / num_threads;
+ __pivot_rank = __n * __num_threads_left / __num_threads;
- difference_type split =
- parallel_sort_qs_divide(begin, end, comp, pivot_rank,
- _Settings::get().sort_qs_num_samples_preset,
- num_threads);
+ _DifferenceType __split =
+ __parallel_sort_qs_divide(__begin, __end, __comp, __pivot_rank,
+ _Settings::get().sort_qs_num_samples_preset,
+ __num_threads);
#pragma omp parallel sections num_threads(2)
{
#pragma omp section
- parallel_sort_qs_conquer(begin, begin + split,
- comp, num_threads_left);
+ __parallel_sort_qs_conquer(__begin, __begin + __split,
+ __comp, __num_threads_left);
#pragma omp section
- parallel_sort_qs_conquer(begin + split, end,
- comp, num_threads - num_threads_left);
+ __parallel_sort_qs_conquer(__begin + __split, __end,
+ __comp, __num_threads - __num_threads_left);
}
}
/** @brief Unbalanced quicksort main call.
- * @param begin Begin iterator of input sequence.
- * @param end End iterator input sequence, ignored.
- * @param comp Comparator.
- * @param num_threads Number of threads that are allowed to work on
+ * @param __begin Begin iterator of input sequence.
+ * @param __end End iterator input sequence, ignored.
+ * @param __comp Comparator.
+ * @param __num_threads Number of threads that are allowed to work on
* this part.
*/
- template<typename RandomAccessIterator, typename Comparator>
+ template<typename _RAIter, typename _Compare>
void
- parallel_sort_qs(RandomAccessIterator begin,
- RandomAccessIterator end,
- Comparator comp,
- thread_index_t num_threads)
+ __parallel_sort_qs(_RAIter __begin,
+ _RAIter __end,
+ _Compare __comp,
+ _ThreadIndex __num_threads)
{
- _GLIBCXX_CALL(n)
+ _GLIBCXX_CALL(__n)
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- difference_type n = end - begin;
+ _DifferenceType __n = __end - __begin;
// At least one element per processor.
- if (num_threads > n)
- num_threads = static_cast<thread_index_t>(n);
+ if (__num_threads > __n)
+ __num_threads = static_cast<_ThreadIndex>(__n);
- parallel_sort_qs_conquer(begin, begin + n, comp, num_threads);
+ __parallel_sort_qs_conquer(
+ __begin, __begin + __n, __comp, __num_threads);
}
} //namespace __gnu_parallel
diff --git a/libstdc++-v3/include/parallel/random_number.h b/libstdc++-v3/include/parallel/random_number.h
index 7e821a47390..6447087ebbb 100644
--- a/libstdc++-v3/include/parallel/random_number.h
+++ b/libstdc++-v3/include/parallel/random_number.h
@@ -38,84 +38,84 @@
namespace __gnu_parallel
{
/** @brief Random number generator, based on the Mersenne twister. */
- class random_number
+ class _RandomNumber
{
private:
- std::tr1::mt19937 mt;
- uint64 supremum;
- uint64 RAND_SUP;
- double supremum_reciprocal;
- double RAND_SUP_REC;
+ std::tr1::mt19937 _M_mt;
+ uint64 _M_supremum;
+ uint64 _M_rand_sup;
+ double _M_supremum_reciprocal;
+ double _M_rand_sup_reciprocal;
// Assumed to be twice as long as the usual random number.
- uint64 cache;
+ uint64 __cache;
// Bit results.
- int bits_left;
+ int __bits_left;
static uint32
- scale_down(uint64 x,
+ __scale_down(uint64 __x,
#if _GLIBCXX_SCALE_DOWN_FPU
- uint64 /*supremum*/, double supremum_reciprocal)
+ uint64 /*_M_supremum*/, double _M_supremum_reciprocal)
#else
- uint64 supremum, double /*supremum_reciprocal*/)
+ uint64 _M_supremum, double /*_M_supremum_reciprocal*/)
#endif
- {
+ {
#if _GLIBCXX_SCALE_DOWN_FPU
- return uint32(x * supremum_reciprocal);
+ return uint32(__x * _M_supremum_reciprocal);
#else
- return static_cast<uint32>(x % supremum);
+ return static_cast<uint32>(__x % _M_supremum);
#endif
- }
+ }
public:
/** @brief Default constructor. Seed with 0. */
- random_number()
- : mt(0), supremum(0x100000000ULL),
- RAND_SUP(1ULL << (sizeof(uint32) * 8)),
- supremum_reciprocal(double(supremum) / double(RAND_SUP)),
- RAND_SUP_REC(1.0 / double(RAND_SUP)),
- cache(0), bits_left(0) { }
+ _RandomNumber()
+ : _M_mt(0), _M_supremum(0x100000000ULL),
+ _M_rand_sup(1ULL << (sizeof(uint32) * 8)),
+ _M_supremum_reciprocal(double(_M_supremum) / double(_M_rand_sup)),
+ _M_rand_sup_reciprocal(1.0 / double(_M_rand_sup)),
+ __cache(0), __bits_left(0) { }
/** @brief Constructor.
- * @param seed Random seed.
- * @param supremum Generate integer random numbers in the
- * interval @c [0,supremum). */
- random_number(uint32 seed, uint64 supremum = 0x100000000ULL)
- : mt(seed), supremum(supremum),
- RAND_SUP(1ULL << (sizeof(uint32) * 8)),
- supremum_reciprocal(double(supremum) / double(RAND_SUP)),
- RAND_SUP_REC(1.0 / double(RAND_SUP)),
- cache(0), bits_left(0) { }
+ * @param __seed Random __seed.
+ * @param _M_supremum Generate integer random numbers in the
+ * interval @__c [0,_M_supremum). */
+ _RandomNumber(uint32 __seed, uint64 _M_supremum = 0x100000000ULL)
+ : _M_mt(__seed), _M_supremum(_M_supremum),
+ _M_rand_sup(1ULL << (sizeof(uint32) * 8)),
+ _M_supremum_reciprocal(double(_M_supremum) / double(_M_rand_sup)),
+ _M_rand_sup_reciprocal(1.0 / double(_M_rand_sup)),
+ __cache(0), __bits_left(0) { }
/** @brief Generate unsigned random 32-bit integer. */
uint32
operator()()
- { return scale_down(mt(), supremum, supremum_reciprocal); }
+ { return __scale_down(_M_mt(), _M_supremum, _M_supremum_reciprocal); }
/** @brief Generate unsigned random 32-bit integer in the
- interval @c [0,local_supremum). */
+ interval @__c [0,local_supremum). */
uint32
operator()(uint64 local_supremum)
{
- return scale_down(mt(), local_supremum,
- double(local_supremum * RAND_SUP_REC));
+ return __scale_down(_M_mt(), local_supremum,
+ double(local_supremum * _M_rand_sup_reciprocal));
}
/** @brief Generate a number of random bits, run-time parameter.
* @param bits Number of bits to generate. */
unsigned long
- genrand_bits(int bits)
+ __genrand_bits(int __bits)
{
- unsigned long res = cache & ((1 << bits) - 1);
- cache = cache >> bits;
- bits_left -= bits;
- if (bits_left < 32)
- {
- cache |= ((uint64(mt())) << bits_left);
- bits_left += 32;
- }
- return res;
+ unsigned long __res = __cache & ((1 << __bits) - 1);
+ __cache = __cache >> __bits;
+ __bits_left -= __bits;
+ if (__bits_left < 32)
+ {
+ __cache |= ((uint64(_M_mt())) << __bits_left);
+ __bits_left += 32;
+ }
+ return __res;
}
};
diff --git a/libstdc++-v3/include/parallel/random_shuffle.h b/libstdc++-v3/include/parallel/random_shuffle.h
index 6e0ebef1523..49d0d8557b7 100644
--- a/libstdc++-v3/include/parallel/random_shuffle.h
+++ b/libstdc++-v3/include/parallel/random_shuffle.h
@@ -44,474 +44,484 @@ namespace __gnu_parallel
* Since many variables of this type are allocated, it should be
* chosen as small as possible.
*/
-typedef unsigned short bin_index;
+typedef unsigned short _BinIndex;
/** @brief Data known to every thread participating in
- __gnu_parallel::parallel_random_shuffle(). */
-template<typename RandomAccessIterator>
- struct DRandomShufflingGlobalData
+ __gnu_parallel::__parallel_random_shuffle(). */
+template<typename _RAIter>
+ struct _DRandomShufflingGlobalData
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- /** @brief Begin iterator of the source. */
- RandomAccessIterator& source;
+ /** @brief Begin iterator of the _M_source. */
+ _RAIter& _M_source;
/** @brief Temporary arrays for each thread. */
- value_type** temporaries;
+ _ValueType** _M_temporaries;
/** @brief Two-dimensional array to hold the thread-bin distribution.
*
- * Dimensions (num_threads + 1) x (num_bins + 1). */
- difference_type** dist;
+ * Dimensions (_M_num_threads + 1) __x (_M_num_bins + 1). */
+ _DifferenceType** _M_dist;
- /** @brief Start indexes of the threads' chunks. */
- difference_type* starts;
+ /** @brief Start indexes of the threads' __chunks. */
+ _DifferenceType* _M_starts;
/** @brief Number of the thread that will further process the
- corresponding bin. */
- thread_index_t* bin_proc;
+ corresponding bin. */
+ _ThreadIndex* _M_bin_proc;
/** @brief Number of bins to distribute to. */
- int num_bins;
+ int _M_num_bins;
/** @brief Number of bits needed to address the bins. */
- int num_bits;
+ int _M_num_bits;
/** @brief Constructor. */
- DRandomShufflingGlobalData(RandomAccessIterator& _source)
- : source(_source) { }
+ _DRandomShufflingGlobalData(_RAIter& _source)
+ : _M_source(_source) { }
};
/** @brief Local data for a thread participating in
- __gnu_parallel::parallel_random_shuffle().
+ __gnu_parallel::__parallel_random_shuffle().
*/
-template<typename RandomAccessIterator, typename RandomNumberGenerator>
- struct DRSSorterPU
+template<typename _RAIter, typename RandomNumberGenerator>
+ struct _DRSSorterPU
{
/** @brief Number of threads participating in total. */
- int num_threads;
+ int _M_num_threads;
/** @brief Begin index for bins taken care of by this thread. */
- bin_index bins_begin;
+ _BinIndex _M_bins_begin;
/** @brief End index for bins taken care of by this thread. */
- bin_index bins_end;
+ _BinIndex __bins_end;
- /** @brief Random seed for this thread. */
- uint32 seed;
+ /** @brief Random _M_seed for this thread. */
+ uint32 _M_seed;
/** @brief Pointer to global data. */
- DRandomShufflingGlobalData<RandomAccessIterator>* sd;
+ _DRandomShufflingGlobalData<_RAIter>* _M_sd;
};
-/** @brief Generate a random number in @c [0,2^logp).
- * @param logp Logarithm (basis 2) of the upper range bound.
- * @param rng Random number generator to use.
+/** @brief Generate a random number in @__c [0,2^logp).
+ * @param logp Logarithm (basis 2) of the upper range __bound.
+ * @param __rng Random number generator to use.
*/
template<typename RandomNumberGenerator>
inline int
- random_number_pow2(int logp, RandomNumberGenerator& rng)
- { return rng.genrand_bits(logp); }
+ __random_number_pow2(int logp, RandomNumberGenerator& __rng)
+ { return __rng.__genrand_bits(logp); }
/** @brief Random shuffle code executed by each thread.
- * @param pus Array of thread-local data records. */
-template<typename RandomAccessIterator, typename RandomNumberGenerator>
+ * @param __pus Array of thread-local data records. */
+template<typename _RAIter, typename RandomNumberGenerator>
void
- parallel_random_shuffle_drs_pu(DRSSorterPU<RandomAccessIterator,
- RandomNumberGenerator>* pus)
+ __parallel_random_shuffle_drs_pu(_DRSSorterPU<_RAIter,
+ RandomNumberGenerator>* __pus)
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
-
- thread_index_t iam = omp_get_thread_num();
- DRSSorterPU<RandomAccessIterator, RandomNumberGenerator>* d = &pus[iam];
- DRandomShufflingGlobalData<RandomAccessIterator>* sd = d->sd;
-
- // Indexing: dist[bin][processor]
- difference_type length = sd->starts[iam + 1] - sd->starts[iam];
- bin_index* oracles = new bin_index[length];
- difference_type* dist = new difference_type[sd->num_bins + 1];
- bin_index* bin_proc = new bin_index[sd->num_bins];
- value_type** temporaries = new value_type*[d->num_threads];
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
+
+ _ThreadIndex __iam = omp_get_thread_num();
+ _DRSSorterPU<_RAIter, RandomNumberGenerator>* d = &__pus[__iam];
+ _DRandomShufflingGlobalData<_RAIter>* _M_sd = d->_M_sd;
+
+ // Indexing: _M_dist[bin][processor]
+ _DifferenceType __length = _M_sd->_M_starts[__iam + 1] -
+ _M_sd->_M_starts[__iam];
+ _BinIndex* __oracles = new _BinIndex[__length];
+ _DifferenceType* _M_dist = new _DifferenceType[_M_sd->_M_num_bins + 1];
+ _BinIndex* _M_bin_proc = new _BinIndex[_M_sd->_M_num_bins];
+ _ValueType** _M_temporaries = new _ValueType*[d->_M_num_threads];
// Compute oracles and count appearances.
- for (bin_index b = 0; b < sd->num_bins + 1; ++b)
- dist[b] = 0;
- int num_bits = sd->num_bits;
+ for (_BinIndex __b = 0; __b < _M_sd->_M_num_bins + 1; ++__b)
+ _M_dist[__b] = 0;
+ int _M_num_bits = _M_sd->_M_num_bits;
- random_number rng(d->seed);
+ _RandomNumber __rng(d->_M_seed);
// First main loop.
- for (difference_type i = 0; i < length; ++i)
+ for (_DifferenceType __i = 0; __i < __length; ++__i)
{
- bin_index oracle = random_number_pow2(num_bits, rng);
- oracles[i] = oracle;
+ _BinIndex __oracle = __random_number_pow2(_M_num_bits, __rng);
+ __oracles[__i] = __oracle;
// To allow prefix (partial) sum.
- ++(dist[oracle + 1]);
+ ++(_M_dist[__oracle + 1]);
}
- for (bin_index b = 0; b < sd->num_bins + 1; ++b)
- sd->dist[b][iam + 1] = dist[b];
+ for (_BinIndex __b = 0; __b < _M_sd->_M_num_bins + 1; ++__b)
+ _M_sd->_M_dist[__b][__iam + 1] = _M_dist[__b];
# pragma omp barrier
# pragma omp single
{
- // Sum up bins, sd->dist[s + 1][d->num_threads] now contains the
- // total number of items in bin s
- for (bin_index s = 0; s < sd->num_bins; ++s)
- __gnu_sequential::partial_sum(sd->dist[s + 1],
- sd->dist[s + 1] + d->num_threads + 1,
- sd->dist[s + 1]);
+ // Sum up bins, _M_sd->_M_dist[__s + 1][d->_M_num_threads] now contains
+ // the total number of items in bin __s
+ for (_BinIndex __s = 0; __s < _M_sd->_M_num_bins; ++__s)
+ __gnu_sequential::partial_sum(
+ _M_sd->_M_dist[__s + 1],
+ _M_sd->_M_dist[__s + 1] + d->_M_num_threads + 1,
+ _M_sd->_M_dist[__s + 1]);
}
# pragma omp barrier
- sequence_index_t offset = 0, global_offset = 0;
- for (bin_index s = 0; s < d->bins_begin; ++s)
- global_offset += sd->dist[s + 1][d->num_threads];
+ _SequenceIndex __offset = 0, __global_offset = 0;
+ for (_BinIndex __s = 0; __s < d->_M_bins_begin; ++__s)
+ __global_offset += _M_sd->_M_dist[__s + 1][d->_M_num_threads];
# pragma omp barrier
- for (bin_index s = d->bins_begin; s < d->bins_end; ++s)
+ for (_BinIndex __s = d->_M_bins_begin; __s < d->__bins_end; ++__s)
{
- for (int t = 0; t < d->num_threads + 1; ++t)
- sd->dist[s + 1][t] += offset;
- offset = sd->dist[s + 1][d->num_threads];
+ for (int __t = 0; __t < d->_M_num_threads + 1; ++__t)
+ _M_sd->_M_dist[__s + 1][__t] += __offset;
+ __offset = _M_sd->_M_dist[__s + 1][d->_M_num_threads];
}
- sd->temporaries[iam] = static_cast<value_type*>(
- ::operator new(sizeof(value_type) * offset));
+ _M_sd->_M_temporaries[__iam] = static_cast<_ValueType*>(
+ ::operator new(sizeof(_ValueType) * __offset));
# pragma omp barrier
// Draw local copies to avoid false sharing.
- for (bin_index b = 0; b < sd->num_bins + 1; ++b)
- dist[b] = sd->dist[b][iam];
- for (bin_index b = 0; b < sd->num_bins; ++b)
- bin_proc[b] = sd->bin_proc[b];
- for (thread_index_t t = 0; t < d->num_threads; ++t)
- temporaries[t] = sd->temporaries[t];
+ for (_BinIndex __b = 0; __b < _M_sd->_M_num_bins + 1; ++__b)
+ _M_dist[__b] = _M_sd->_M_dist[__b][__iam];
+ for (_BinIndex __b = 0; __b < _M_sd->_M_num_bins; ++__b)
+ _M_bin_proc[__b] = _M_sd->_M_bin_proc[__b];
+ for (_ThreadIndex __t = 0; __t < d->_M_num_threads; ++__t)
+ _M_temporaries[__t] = _M_sd->_M_temporaries[__t];
- RandomAccessIterator source = sd->source;
- difference_type start = sd->starts[iam];
+ _RAIter _M_source = _M_sd->_M_source;
+ _DifferenceType __start = _M_sd->_M_starts[__iam];
// Distribute according to oracles, second main loop.
- for (difference_type i = 0; i < length; ++i)
+ for (_DifferenceType __i = 0; __i < __length; ++__i)
{
- bin_index target_bin = oracles[i];
- thread_index_t target_p = bin_proc[target_bin];
+ _BinIndex target_bin = __oracles[__i];
+ _ThreadIndex target_p = _M_bin_proc[target_bin];
- // Last column [d->num_threads] stays unchanged.
- ::new(&(temporaries[target_p][dist[target_bin + 1]++]))
- value_type(*(source + i + start));
+ // Last column [d->_M_num_threads] stays unchanged.
+ ::new(&(_M_temporaries[target_p][_M_dist[target_bin + 1]++]))
+ _ValueType(*(_M_source + __i + __start));
}
- delete[] oracles;
- delete[] dist;
- delete[] bin_proc;
- delete[] temporaries;
+ delete[] __oracles;
+ delete[] _M_dist;
+ delete[] _M_bin_proc;
+ delete[] _M_temporaries;
# pragma omp barrier
// Shuffle bins internally.
- for (bin_index b = d->bins_begin; b < d->bins_end; ++b)
+ for (_BinIndex __b = d->_M_bins_begin; __b < d->__bins_end; ++__b)
{
- value_type* begin =
- sd->temporaries[iam] +
- ((b == d->bins_begin) ? 0 : sd->dist[b][d->num_threads]),
- * end =
- sd->temporaries[iam] + sd->dist[b + 1][d->num_threads];
- sequential_random_shuffle(begin, end, rng);
- std::copy(begin, end, sd->source + global_offset +
- ((b == d->bins_begin) ? 0 : sd->dist[b][d->num_threads]));
+ _ValueType* __begin =
+ _M_sd->_M_temporaries[__iam] +
+ ((__b == d->_M_bins_begin)
+ ? 0 : _M_sd->_M_dist[__b][d->_M_num_threads]),
+ * __end =
+ _M_sd->_M_temporaries[__iam] +
+ _M_sd->_M_dist[__b + 1][d->_M_num_threads];
+ __sequential_random_shuffle(__begin, __end, __rng);
+ std::copy(__begin, __end, _M_sd->_M_source + __global_offset +
+ ((__b == d->_M_bins_begin)
+ ? 0 : _M_sd->_M_dist[__b][d->_M_num_threads]));
}
- ::operator delete(sd->temporaries[iam]);
+ ::operator delete(_M_sd->_M_temporaries[__iam]);
}
/** @brief Round up to the next greater power of 2.
- * @param x Integer to round up */
-template<typename T>
- T
- round_up_to_pow2(T x)
+ * @param __x _Integer to round up */
+template<typename _Tp>
+ _Tp
+ __round_up_to_pow2(_Tp __x)
{
- if (x <= 1)
+ if (__x <= 1)
return 1;
else
- return (T)1 << (__log2(x - 1) + 1);
+ return (_Tp)1 << (__log2(__x - 1) + 1);
}
/** @brief Main parallel random shuffle step.
- * @param begin Begin iterator of sequence.
- * @param end End iterator of sequence.
- * @param n Length of sequence.
- * @param num_threads Number of threads to use.
- * @param rng Random number generator to use.
+ * @param __begin Begin iterator of sequence.
+ * @param __end End iterator of sequence.
+ * @param __n Length of sequence.
+ * @param __num_threads Number of threads to use.
+ * @param __rng Random number generator to use.
*/
-template<typename RandomAccessIterator, typename RandomNumberGenerator>
+template<typename _RAIter, typename RandomNumberGenerator>
void
- parallel_random_shuffle_drs(RandomAccessIterator begin,
- RandomAccessIterator end,
- typename std::iterator_traits
- <RandomAccessIterator>::difference_type n,
- thread_index_t num_threads,
- RandomNumberGenerator& rng)
+ __parallel_random_shuffle_drs(_RAIter __begin,
+ _RAIter __end,
+ typename std::iterator_traits
+ <_RAIter>::difference_type __n,
+ _ThreadIndex __num_threads,
+ RandomNumberGenerator& __rng)
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- _GLIBCXX_CALL(n)
+ _GLIBCXX_CALL(__n)
const _Settings& __s = _Settings::get();
- if (num_threads > n)
- num_threads = static_cast<thread_index_t>(n);
+ if (__num_threads > __n)
+ __num_threads = static_cast<_ThreadIndex>(__n);
- bin_index num_bins, num_bins_cache;
+ _BinIndex _M_num_bins, __num_bins_cache;
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1
// Try the L1 cache first.
// Must fit into L1.
- num_bins_cache = std::max<difference_type>(
- 1, n / (__s.L1_cache_size_lb / sizeof(value_type)));
- num_bins_cache = round_up_to_pow2(num_bins_cache);
+ __num_bins_cache = std::max<_DifferenceType>(
+ 1, __n / (__s.L1_cache_size_lb / sizeof(_ValueType)));
+ __num_bins_cache = __round_up_to_pow2(__num_bins_cache);
// No more buckets than TLB entries, power of 2
// Power of 2 and at least one element per bin, at most the TLB size.
- num_bins = std::min<difference_type>(n, num_bins_cache);
+ _M_num_bins = std::min<_DifferenceType>(__n, __num_bins_cache);
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB
// 2 TLB entries needed per bin.
- num_bins = std::min<difference_type>(__s.TLB_size / 2, num_bins);
+ _M_num_bins = std::min<_DifferenceType>(__s.TLB_size / 2, _M_num_bins);
#endif
- num_bins = round_up_to_pow2(num_bins);
+ _M_num_bins = __round_up_to_pow2(_M_num_bins);
- if (num_bins < num_bins_cache)
+ if (_M_num_bins < __num_bins_cache)
{
#endif
// Now try the L2 cache
// Must fit into L2
- num_bins_cache = static_cast<bin_index>(std::max<difference_type>(
- 1, n / (__s.L2_cache_size / sizeof(value_type))));
- num_bins_cache = round_up_to_pow2(num_bins_cache);
+ __num_bins_cache = static_cast<_BinIndex>(std::max<_DifferenceType>(
+ 1, __n / (__s.L2_cache_size / sizeof(_ValueType))));
+ __num_bins_cache = __round_up_to_pow2(__num_bins_cache);
// No more buckets than TLB entries, power of 2.
- num_bins = static_cast<bin_index>(
- std::min(n, static_cast<difference_type>(num_bins_cache)));
+ _M_num_bins = static_cast<_BinIndex>(
+ std::min(__n, static_cast<_DifferenceType>(__num_bins_cache)));
// Power of 2 and at least one element per bin, at most the TLB size.
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB
// 2 TLB entries needed per bin.
- num_bins = std::min(
- static_cast<difference_type>(__s.TLB_size / 2), num_bins);
+ _M_num_bins = std::min(
+ static_cast<_DifferenceType>(__s.TLB_size / 2), _M_num_bins);
#endif
- num_bins = round_up_to_pow2(num_bins);
+ _M_num_bins = __round_up_to_pow2(_M_num_bins);
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1
}
#endif
- num_threads = std::min<bin_index>(num_threads, num_bins);
+ __num_threads = std::min<_BinIndex>(__num_threads, _M_num_bins);
- if (num_threads <= 1)
- return sequential_random_shuffle(begin, end, rng);
+ if (__num_threads <= 1)
+ return __sequential_random_shuffle(__begin, __end, __rng);
- DRandomShufflingGlobalData<RandomAccessIterator> sd(begin);
- DRSSorterPU<RandomAccessIterator, random_number >* pus;
- difference_type* starts;
+ _DRandomShufflingGlobalData<_RAIter> _M_sd(__begin);
+ _DRSSorterPU<_RAIter, _RandomNumber >* __pus;
+ _DifferenceType* _M_starts;
-# pragma omp parallel num_threads(num_threads)
+# pragma omp parallel num_threads(__num_threads)
{
- thread_index_t num_threads = omp_get_num_threads();
+ _ThreadIndex __num_threads = omp_get_num_threads();
# pragma omp single
{
- pus = new DRSSorterPU<RandomAccessIterator, random_number>
- [num_threads];
-
- sd.temporaries = new value_type*[num_threads];
- sd.dist = new difference_type*[num_bins + 1];
- sd.bin_proc = new thread_index_t[num_bins];
- for (bin_index b = 0; b < num_bins + 1; ++b)
- sd.dist[b] = new difference_type[num_threads + 1];
- for (bin_index b = 0; b < (num_bins + 1); ++b)
+ __pus = new _DRSSorterPU<_RAIter, _RandomNumber>
+ [__num_threads];
+
+ _M_sd._M_temporaries = new _ValueType*[__num_threads];
+ _M_sd._M_dist = new _DifferenceType*[_M_num_bins + 1];
+ _M_sd._M_bin_proc = new _ThreadIndex[_M_num_bins];
+ for (_BinIndex __b = 0; __b < _M_num_bins + 1; ++__b)
+ _M_sd._M_dist[__b] = new _DifferenceType[__num_threads + 1];
+ for (_BinIndex __b = 0; __b < (_M_num_bins + 1); ++__b)
{
- sd.dist[0][0] = 0;
- sd.dist[b][0] = 0;
+ _M_sd._M_dist[0][0] = 0;
+ _M_sd._M_dist[__b][0] = 0;
}
- starts = sd.starts = new difference_type[num_threads + 1];
+ _M_starts = _M_sd._M_starts
+ = new _DifferenceType[__num_threads + 1];
int bin_cursor = 0;
- sd.num_bins = num_bins;
- sd.num_bits = __log2(num_bins);
-
- difference_type chunk_length = n / num_threads,
- split = n % num_threads, start = 0;
- difference_type bin_chunk_length = num_bins / num_threads,
- bin_split = num_bins % num_threads;
- for (thread_index_t i = 0; i < num_threads; ++i)
+ _M_sd._M_num_bins = _M_num_bins;
+ _M_sd._M_num_bits = __log2(_M_num_bins);
+
+ _DifferenceType __chunk_length = __n / __num_threads,
+ __split = __n % __num_threads, __start = 0;
+ _DifferenceType bin_chunk_length = _M_num_bins / __num_threads,
+ bin_split = _M_num_bins % __num_threads;
+ for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
{
- starts[i] = start;
- start += (i < split) ? (chunk_length + 1) : chunk_length;
- int j = pus[i].bins_begin = bin_cursor;
+ _M_starts[__i] = __start;
+ __start += (__i < __split)
+ ? (__chunk_length + 1) : __chunk_length;
+ int __j = __pus[__i]._M_bins_begin = bin_cursor;
// Range of bins for this processor.
- bin_cursor += (i < bin_split) ?
+ bin_cursor += (__i < bin_split) ?
(bin_chunk_length + 1) : bin_chunk_length;
- pus[i].bins_end = bin_cursor;
- for (; j < bin_cursor; ++j)
- sd.bin_proc[j] = i;
- pus[i].num_threads = num_threads;
- pus[i].seed = rng(std::numeric_limits<uint32>::max());
- pus[i].sd = &sd;
+ __pus[__i].__bins_end = bin_cursor;
+ for (; __j < bin_cursor; ++__j)
+ _M_sd._M_bin_proc[__j] = __i;
+ __pus[__i]._M_num_threads = __num_threads;
+ __pus[__i]._M_seed = __rng(std::numeric_limits<uint32>::max());
+ __pus[__i]._M_sd = &_M_sd;
}
- starts[num_threads] = start;
+ _M_starts[__num_threads] = __start;
} //single
// Now shuffle in parallel.
- parallel_random_shuffle_drs_pu(pus);
+ __parallel_random_shuffle_drs_pu(__pus);
} // parallel
- delete[] starts;
- delete[] sd.bin_proc;
- for (int s = 0; s < (num_bins + 1); ++s)
- delete[] sd.dist[s];
- delete[] sd.dist;
- delete[] sd.temporaries;
+ delete[] _M_starts;
+ delete[] _M_sd._M_bin_proc;
+ for (int __s = 0; __s < (_M_num_bins + 1); ++__s)
+ delete[] _M_sd._M_dist[__s];
+ delete[] _M_sd._M_dist;
+ delete[] _M_sd._M_temporaries;
- delete[] pus;
+ delete[] __pus;
}
/** @brief Sequential cache-efficient random shuffle.
- * @param begin Begin iterator of sequence.
- * @param end End iterator of sequence.
- * @param rng Random number generator to use.
+ * @param __begin Begin iterator of sequence.
+ * @param __end End iterator of sequence.
+ * @param __rng Random number generator to use.
*/
-template<typename RandomAccessIterator, typename RandomNumberGenerator>
+template<typename _RAIter, typename RandomNumberGenerator>
void
- sequential_random_shuffle(RandomAccessIterator begin,
- RandomAccessIterator end,
- RandomNumberGenerator& rng)
+ __sequential_random_shuffle(_RAIter __begin,
+ _RAIter __end,
+ RandomNumberGenerator& __rng)
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- difference_type n = end - begin;
+ _DifferenceType __n = __end - __begin;
const _Settings& __s = _Settings::get();
- bin_index num_bins, num_bins_cache;
+ _BinIndex _M_num_bins, __num_bins_cache;
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1
// Try the L1 cache first, must fit into L1.
- num_bins_cache =
- std::max<difference_type>
- (1, n / (__s.L1_cache_size_lb / sizeof(value_type)));
- num_bins_cache = round_up_to_pow2(num_bins_cache);
+ __num_bins_cache =
+ std::max<_DifferenceType>
+ (1, __n / (__s.L1_cache_size_lb / sizeof(_ValueType)));
+ __num_bins_cache = __round_up_to_pow2(__num_bins_cache);
// No more buckets than TLB entries, power of 2
// Power of 2 and at least one element per bin, at most the TLB size
- num_bins = std::min(n, (difference_type)num_bins_cache);
+ _M_num_bins = std::min(__n, (_DifferenceType)__num_bins_cache);
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB
// 2 TLB entries needed per bin
- num_bins = std::min((difference_type)__s.TLB_size / 2, num_bins);
+ _M_num_bins = std::min((_DifferenceType)__s.TLB_size / 2, _M_num_bins);
#endif
- num_bins = round_up_to_pow2(num_bins);
+ _M_num_bins = __round_up_to_pow2(_M_num_bins);
- if (num_bins < num_bins_cache)
+ if (_M_num_bins < __num_bins_cache)
{
#endif
// Now try the L2 cache, must fit into L2.
- num_bins_cache =
- static_cast<bin_index>(std::max<difference_type>(
- 1, n / (__s.L2_cache_size / sizeof(value_type))));
- num_bins_cache = round_up_to_pow2(num_bins_cache);
+ __num_bins_cache =
+ static_cast<_BinIndex>(std::max<_DifferenceType>(
+ 1, __n / (__s.L2_cache_size / sizeof(_ValueType))));
+ __num_bins_cache = __round_up_to_pow2(__num_bins_cache);
// No more buckets than TLB entries, power of 2
// Power of 2 and at least one element per bin, at most the TLB size.
- num_bins = static_cast<bin_index>
- (std::min(n, static_cast<difference_type>(num_bins_cache)));
+ _M_num_bins = static_cast<_BinIndex>
+ (std::min(__n, static_cast<_DifferenceType>(__num_bins_cache)));
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB
// 2 TLB entries needed per bin
- num_bins =
- std::min<difference_type>(__s.TLB_size / 2, num_bins);
+ _M_num_bins =
+ std::min<_DifferenceType>(__s.TLB_size / 2, _M_num_bins);
#endif
- num_bins = round_up_to_pow2(num_bins);
+ _M_num_bins = __round_up_to_pow2(_M_num_bins);
#if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1
}
#endif
- int num_bits = __log2(num_bins);
+ int _M_num_bits = __log2(_M_num_bins);
- if (num_bins > 1)
+ if (_M_num_bins > 1)
{
- value_type* target = static_cast<value_type*>(
- ::operator new(sizeof(value_type) * n));
- bin_index* oracles = new bin_index[n];
- difference_type* dist0 = new difference_type[num_bins + 1],
- * dist1 = new difference_type[num_bins + 1];
+ _ValueType* __target = static_cast<_ValueType*>(
+ ::operator new(sizeof(_ValueType) * __n));
+ _BinIndex* __oracles = new _BinIndex[__n];
+ _DifferenceType* __dist0 = new _DifferenceType[_M_num_bins + 1],
+ * __dist1 = new _DifferenceType[_M_num_bins + 1];
- for (int b = 0; b < num_bins + 1; ++b)
- dist0[b] = 0;
+ for (int __b = 0; __b < _M_num_bins + 1; ++__b)
+ __dist0[__b] = 0;
- random_number bitrng(rng(0xFFFFFFFF));
+ _RandomNumber bitrng(__rng(0xFFFFFFFF));
- for (difference_type i = 0; i < n; ++i)
+ for (_DifferenceType __i = 0; __i < __n; ++__i)
{
- bin_index oracle = random_number_pow2(num_bits, bitrng);
- oracles[i] = oracle;
+ _BinIndex __oracle = __random_number_pow2(_M_num_bits, bitrng);
+ __oracles[__i] = __oracle;
// To allow prefix (partial) sum.
- ++(dist0[oracle + 1]);
+ ++(__dist0[__oracle + 1]);
}
// Sum up bins.
- __gnu_sequential::partial_sum(dist0, dist0 + num_bins + 1, dist0);
+ __gnu_sequential::
+ partial_sum(__dist0, __dist0 + _M_num_bins + 1, __dist0);
- for (int b = 0; b < num_bins + 1; ++b)
- dist1[b] = dist0[b];
+ for (int __b = 0; __b < _M_num_bins + 1; ++__b)
+ __dist1[__b] = __dist0[__b];
// Distribute according to oracles.
- for (difference_type i = 0; i < n; ++i)
- ::new(&(target[(dist0[oracles[i]])++])) value_type(*(begin + i));
+ for (_DifferenceType __i = 0; __i < __n; ++__i)
+ ::new(&(__target[(__dist0[__oracles[__i]])++]))
+ _ValueType(*(__begin + __i));
- for (int b = 0; b < num_bins; ++b)
+ for (int __b = 0; __b < _M_num_bins; ++__b)
{
- sequential_random_shuffle(target + dist1[b],
- target + dist1[b + 1],
- rng);
+ __sequential_random_shuffle(__target + __dist1[__b],
+ __target + __dist1[__b + 1],
+ __rng);
}
// Copy elements back.
- std::copy(target, target + n, begin);
+ std::copy(__target, __target + __n, __begin);
- delete[] dist0;
- delete[] dist1;
- delete[] oracles;
- ::operator delete(target);
+ delete[] __dist0;
+ delete[] __dist1;
+ delete[] __oracles;
+ ::operator delete(__target);
}
else
- __gnu_sequential::random_shuffle(begin, end, rng);
+ __gnu_sequential::random_shuffle(__begin, __end, __rng);
}
/** @brief Parallel random public call.
- * @param begin Begin iterator of sequence.
- * @param end End iterator of sequence.
- * @param rng Random number generator to use.
+ * @param __begin Begin iterator of sequence.
+ * @param __end End iterator of sequence.
+ * @param __rng Random number generator to use.
*/
-template<typename RandomAccessIterator, typename RandomNumberGenerator>
+template<typename _RAIter, typename RandomNumberGenerator>
inline void
- parallel_random_shuffle(RandomAccessIterator begin,
- RandomAccessIterator end,
- RandomNumberGenerator rng = random_number())
+ __parallel_random_shuffle(_RAIter __begin,
+ _RAIter __end,
+ RandomNumberGenerator __rng = _RandomNumber())
{
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::difference_type difference_type;
- difference_type n = end - begin;
- parallel_random_shuffle_drs(begin, end, n, get_max_threads(), rng) ;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
+ _DifferenceType __n = __end - __begin;
+ __parallel_random_shuffle_drs(
+ __begin, __end, __n, __get_max_threads(), __rng) ;
}
}
diff --git a/libstdc++-v3/include/parallel/search.h b/libstdc++-v3/include/parallel/search.h
index 31a8534029b..a253126d90a 100644
--- a/libstdc++-v3/include/parallel/search.h
+++ b/libstdc++-v3/include/parallel/search.h
@@ -23,7 +23,7 @@
// <http://www.gnu.org/licenses/>.
/** @file parallel/search.h
- * @brief Parallel implementation base for std::search() and
+ * @brief Parallel implementation __base for std::search() and
* std::search_n().
* This file is a GNU parallel extension to the Standard C++ Library.
*/
@@ -42,130 +42,132 @@
namespace __gnu_parallel
{
/**
- * @brief Precalculate advances for Knuth-Morris-Pratt algorithm.
- * @param elements Begin iterator of sequence to search for.
- * @param length Length of sequence to search for.
- * @param advances Returned offsets.
+ * @brief Precalculate __advances for Knuth-Morris-Pratt algorithm.
+ * @param __elements Begin iterator of sequence to search for.
+ * @param __length Length of sequence to search for.
+ * @param __advances Returned __offsets.
*/
-template<typename RandomAccessIterator, typename _DifferenceTp>
+template<typename _RAIter, typename _DifferenceTp>
void
- calc_borders(RandomAccessIterator elements, _DifferenceTp length,
- _DifferenceTp* off)
+ __calc_borders(_RAIter __elements, _DifferenceTp __length,
+ _DifferenceTp* __off)
{
- typedef _DifferenceTp difference_type;
+ typedef _DifferenceTp _DifferenceType;
- off[0] = -1;
- if (length > 1)
- off[1] = 0;
- difference_type k = 0;
- for (difference_type j = 2; j <= length; j++)
+ __off[0] = -1;
+ if (__length > 1)
+ __off[1] = 0;
+ _DifferenceType __k = 0;
+ for (_DifferenceType __j = 2; __j <= __length; __j++)
{
- while ((k >= 0) && !(elements[k] == elements[j-1]))
- k = off[k];
- off[j] = ++k;
+ while ((__k >= 0) && !(__elements[__k] == __elements[__j-1]))
+ __k = __off[__k];
+ __off[__j] = ++__k;
}
}
// Generic parallel find algorithm (requires random access iterator).
/** @brief Parallel std::search.
- * @param begin1 Begin iterator of first sequence.
- * @param end1 End iterator of first sequence.
- * @param begin2 Begin iterator of second sequence.
- * @param end2 End iterator of second sequence.
- * @param pred Find predicate.
+ * @param __begin1 Begin iterator of first sequence.
+ * @param __end1 End iterator of first sequence.
+ * @param __begin2 Begin iterator of second sequence.
+ * @param __end2 End iterator of second sequence.
+ * @param __pred Find predicate.
* @return Place of finding in first sequences. */
-template<typename _RandomAccessIterator1,
- typename _RandomAccessIterator2,
- typename Pred>
- _RandomAccessIterator1
- search_template(_RandomAccessIterator1 begin1, _RandomAccessIterator1 end1,
- _RandomAccessIterator2 begin2, _RandomAccessIterator2 end2,
- Pred pred)
+template<typename __RAIter1,
+ typename __RAIter2,
+ typename _Pred>
+ __RAIter1
+ __search_template(__RAIter1 __begin1, __RAIter1 __end1,
+ __RAIter2 __begin2, __RAIter2 __end2,
+ _Pred __pred)
{
- typedef std::iterator_traits<_RandomAccessIterator1> traits_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<__RAIter1> _TraitsType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- _GLIBCXX_CALL((end1 - begin1) + (end2 - begin2));
+ _GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2));
- difference_type pattern_length = end2 - begin2;
+ _DifferenceType __pattern_length = __end2 - __begin2;
// Pattern too short.
- if(pattern_length <= 0)
- return end1;
+ if(__pattern_length <= 0)
+ return __end1;
// Last point to start search.
- difference_type input_length = (end1 - begin1) - pattern_length;
+ _DifferenceType __input_length = (__end1 - __begin1) - __pattern_length;
// Where is first occurrence of pattern? defaults to end.
- difference_type result = (end1 - begin1);
- difference_type *splitters;
+ _DifferenceType __result = (__end1 - __begin1);
+ _DifferenceType *__splitters;
// Pattern too long.
- if (input_length < 0)
- return end1;
+ if (__input_length < 0)
+ return __end1;
- omp_lock_t result_lock;
- omp_init_lock(&result_lock);
+ omp_lock_t __result_lock;
+ omp_init_lock(&__result_lock);
- thread_index_t num_threads =
- std::max<difference_type>(1,
- std::min<difference_type>(input_length, get_max_threads()));
+ _ThreadIndex __num_threads =
+ std::max<_DifferenceType>(1,
+ std::min<_DifferenceType>(__input_length, __get_max_threads()));
- difference_type advances[pattern_length];
- calc_borders(begin2, pattern_length, advances);
+ _DifferenceType __advances[__pattern_length];
+ __calc_borders(__begin2, __pattern_length, __advances);
-# pragma omp parallel num_threads(num_threads)
+# pragma omp parallel num_threads(__num_threads)
{
# pragma omp single
{
- num_threads = omp_get_num_threads();
- splitters = new difference_type[num_threads + 1];
- equally_split(input_length, num_threads, splitters);
+ __num_threads = omp_get_num_threads();
+ __splitters = new _DifferenceType[__num_threads + 1];
+ equally_split(__input_length, __num_threads, __splitters);
}
- thread_index_t iam = omp_get_thread_num();
+ _ThreadIndex __iam = omp_get_thread_num();
- difference_type start = splitters[iam], stop = splitters[iam + 1];
+ _DifferenceType __start = __splitters[__iam],
+ __stop = __splitters[__iam + 1];
- difference_type pos_in_pattern = 0;
- bool found_pattern = false;
+ _DifferenceType __pos_in_pattern = 0;
+ bool __found_pattern = false;
- while (start <= stop && !found_pattern)
+ while (__start <= __stop && !__found_pattern)
{
// Get new value of result.
- #pragma omp flush(result)
+ #pragma omp flush(__result)
// No chance for this thread to find first occurrence.
- if (result < start)
+ if (__result < __start)
break;
- while (pred(begin1[start + pos_in_pattern],
- begin2[pos_in_pattern]))
+ while (__pred(__begin1[__start + __pos_in_pattern],
+ __begin2[__pos_in_pattern]))
{
- ++pos_in_pattern;
- if (pos_in_pattern == pattern_length)
+ ++__pos_in_pattern;
+ if (__pos_in_pattern == __pattern_length)
{
// Found new candidate for result.
- omp_set_lock(&result_lock);
- result = std::min(result, start);
- omp_unset_lock(&result_lock);
+ omp_set_lock(&__result_lock);
+ __result = std::min(__result, __start);
+ omp_unset_lock(&__result_lock);
- found_pattern = true;
+ __found_pattern = true;
break;
}
}
// Make safe jump.
- start += (pos_in_pattern - advances[pos_in_pattern]);
- pos_in_pattern =
- (advances[pos_in_pattern] < 0) ? 0 : advances[pos_in_pattern];
+ __start += (__pos_in_pattern - __advances[__pos_in_pattern]);
+ __pos_in_pattern =
+ (__advances[__pos_in_pattern] < 0) ?
+ 0 : __advances[__pos_in_pattern];
}
} //parallel
- omp_destroy_lock(&result_lock);
+ omp_destroy_lock(&__result_lock);
- delete[] splitters;
+ delete[] __splitters;
// Return iterator on found element.
- return (begin1 + result);
+ return (__begin1 + __result);
}
} // end namespace
diff --git a/libstdc++-v3/include/parallel/set_operations.h b/libstdc++-v3/include/parallel/set_operations.h
index 28008195b6f..ac669c55d5d 100644
--- a/libstdc++-v3/include/parallel/set_operations.h
+++ b/libstdc++-v3/include/parallel/set_operations.h
@@ -41,482 +41,488 @@
namespace __gnu_parallel
{
-template<typename InputIterator, typename OutputIterator>
- OutputIterator
- copy_tail(std::pair<InputIterator, InputIterator> b,
- std::pair<InputIterator, InputIterator> e, OutputIterator r)
+template<typename _IIter, typename _OutputIterator>
+ _OutputIterator
+ copy_tail(std::pair<_IIter, _IIter> __b,
+ std::pair<_IIter, _IIter> __e, _OutputIterator __r)
{
- if (b.first != e.first)
+ if (__b.first != __e.first)
{
do
{
- *r++ = *b.first++;
+ *__r++ = *__b.first++;
}
- while (b.first != e.first);
+ while (__b.first != __e.first);
}
else
{
- while (b.second != e.second)
- *r++ = *b.second++;
+ while (__b.second != __e.second)
+ *__r++ = *__b.second++;
}
- return r;
+ return __r;
}
-template<typename InputIterator,
- typename OutputIterator,
- typename Comparator>
+template<typename _IIter,
+ typename _OutputIterator,
+ typename _Compare>
struct symmetric_difference_func
{
- typedef std::iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::difference_type difference_type;
- typedef typename std::pair<InputIterator, InputIterator> iterator_pair;
+ typedef std::iterator_traits<_IIter> _TraitsType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
+ typedef typename std::pair<_IIter, _IIter> _IteratorPair;
- symmetric_difference_func(Comparator c) : comp(c) {}
+ symmetric_difference_func(_Compare __comp) : _M_comp(__comp) {}
- Comparator comp;
+ _Compare _M_comp;
- OutputIterator
- invoke(InputIterator a, InputIterator b,
- InputIterator c, InputIterator d,
- OutputIterator r) const
+ _OutputIterator
+ _M_invoke(_IIter __a, _IIter __b,
+ _IIter __c, _IIter d,
+ _OutputIterator __r) const
{
- while (a != b && c != d)
+ while (__a != __b && __c != d)
{
- if (comp(*a, *c))
+ if (_M_comp(*__a, *__c))
{
- *r = *a;
- ++a;
- ++r;
+ *__r = *__a;
+ ++__a;
+ ++__r;
}
- else if (comp(*c, *a))
+ else if (_M_comp(*__c, *__a))
{
- *r = *c;
- ++c;
- ++r;
+ *__r = *__c;
+ ++__c;
+ ++__r;
}
else
{
- ++a;
- ++c;
+ ++__a;
+ ++__c;
}
}
- return std::copy(c, d, std::copy(a, b, r));
+ return std::copy(__c, d, std::copy(__a, __b, __r));
}
- difference_type
- count(InputIterator a, InputIterator b,
- InputIterator c, InputIterator d) const
+ _DifferenceType
+ __count(_IIter __a, _IIter __b,
+ _IIter __c, _IIter d) const
{
- difference_type counter = 0;
+ _DifferenceType __counter = 0;
- while (a != b && c != d)
+ while (__a != __b && __c != d)
{
- if (comp(*a, *c))
+ if (_M_comp(*__a, *__c))
{
- ++a;
- ++counter;
+ ++__a;
+ ++__counter;
}
- else if (comp(*c, *a))
+ else if (_M_comp(*__c, *__a))
{
- ++c;
- ++counter;
+ ++__c;
+ ++__counter;
}
else
{
- ++a;
- ++c;
+ ++__a;
+ ++__c;
}
}
- return counter + (b - a) + (d - c);
+ return __counter + (__b - __a) + (d - __c);
}
- OutputIterator
- first_empty(InputIterator c, InputIterator d, OutputIterator out) const
- { return std::copy(c, d, out); }
+ _OutputIterator
+ __first_empty(_IIter __c, _IIter d, _OutputIterator __out) const
+ { return std::copy(__c, d, __out); }
- OutputIterator
- second_empty(InputIterator a, InputIterator b, OutputIterator out) const
- { return std::copy(a, b, out); }
+ _OutputIterator
+ __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const
+ { return std::copy(__a, __b, __out); }
};
-template<typename InputIterator,
- typename OutputIterator,
- typename Comparator>
- struct difference_func
+template<typename _IIter,
+ typename _OutputIterator,
+ typename _Compare>
+ struct __difference_func
{
- typedef std::iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::difference_type difference_type;
- typedef typename std::pair<InputIterator, InputIterator> iterator_pair;
+ typedef std::iterator_traits<_IIter> _TraitsType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
+ typedef typename std::pair<_IIter, _IIter> _IteratorPair;
- difference_func(Comparator c) : comp(c) {}
+ __difference_func(_Compare __comp) : _M_comp(__comp) {}
- Comparator comp;
+ _Compare _M_comp;
- OutputIterator
- invoke(InputIterator a, InputIterator b, InputIterator c, InputIterator d,
- OutputIterator r) const
+ _OutputIterator
+ _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter d,
+ _OutputIterator __r) const
{
- while (a != b && c != d)
+ while (__a != __b && __c != d)
{
- if (comp(*a, *c))
+ if (_M_comp(*__a, *__c))
{
- *r = *a;
- ++a;
- ++r;
+ *__r = *__a;
+ ++__a;
+ ++__r;
}
- else if (comp(*c, *a))
- { ++c; }
+ else if (_M_comp(*__c, *__a))
+ { ++__c; }
else
{
- ++a;
- ++c;
+ ++__a;
+ ++__c;
}
}
- return std::copy(a, b, r);
+ return std::copy(__a, __b, __r);
}
- difference_type
- count(InputIterator a, InputIterator b,
- InputIterator c, InputIterator d) const
+ _DifferenceType
+ __count(_IIter __a, _IIter __b,
+ _IIter __c, _IIter d) const
{
- difference_type counter = 0;
+ _DifferenceType __counter = 0;
- while (a != b && c != d)
+ while (__a != __b && __c != d)
{
- if (comp(*a, *c))
+ if (_M_comp(*__a, *__c))
{
- ++a;
- ++counter;
+ ++__a;
+ ++__counter;
}
- else if (comp(*c, *a))
- { ++c; }
+ else if (_M_comp(*__c, *__a))
+ { ++__c; }
else
- { ++a; ++c; }
+ { ++__a; ++__c; }
}
- return counter + (b - a);
+ return __counter + (__b - __a);
}
- inline OutputIterator
- first_empty(InputIterator c, InputIterator d, OutputIterator out) const
- { return out; }
+ inline _OutputIterator
+ __first_empty(_IIter __c, _IIter d, _OutputIterator __out) const
+ { return __out; }
- inline OutputIterator
- second_empty(InputIterator a, InputIterator b, OutputIterator out) const
- { return std::copy(a, b, out); }
+ inline _OutputIterator
+ __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const
+ { return std::copy(__a, __b, __out); }
};
-template<typename InputIterator,
- typename OutputIterator,
- typename Comparator>
- struct intersection_func
+template<typename _IIter,
+ typename _OutputIterator,
+ typename _Compare>
+ struct __intersection_func
{
- typedef std::iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::difference_type difference_type;
- typedef typename std::pair<InputIterator, InputIterator> iterator_pair;
+ typedef std::iterator_traits<_IIter> _TraitsType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
+ typedef typename std::pair<_IIter, _IIter> _IteratorPair;
- intersection_func(Comparator c) : comp(c) {}
+ __intersection_func(_Compare __comp) : _M_comp(__comp) {}
- Comparator comp;
+ _Compare _M_comp;
- OutputIterator
- invoke(InputIterator a, InputIterator b, InputIterator c, InputIterator d,
- OutputIterator r) const
+ _OutputIterator
+ _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter d,
+ _OutputIterator __r) const
{
- while (a != b && c != d)
+ while (__a != __b && __c != d)
{
- if (comp(*a, *c))
- { ++a; }
- else if (comp(*c, *a))
- { ++c; }
+ if (_M_comp(*__a, *__c))
+ { ++__a; }
+ else if (_M_comp(*__c, *__a))
+ { ++__c; }
else
{
- *r = *a;
- ++a;
- ++c;
- ++r;
+ *__r = *__a;
+ ++__a;
+ ++__c;
+ ++__r;
}
}
- return r;
+ return __r;
}
- difference_type
- count(InputIterator a, InputIterator b,
- InputIterator c, InputIterator d) const
+ _DifferenceType
+ __count(_IIter __a, _IIter __b,
+ _IIter __c, _IIter d) const
{
- difference_type counter = 0;
+ _DifferenceType __counter = 0;
- while (a != b && c != d)
+ while (__a != __b && __c != d)
{
- if (comp(*a, *c))
- { ++a; }
- else if (comp(*c, *a))
- { ++c; }
+ if (_M_comp(*__a, *__c))
+ { ++__a; }
+ else if (_M_comp(*__c, *__a))
+ { ++__c; }
else
{
- ++a;
- ++c;
- ++counter;
+ ++__a;
+ ++__c;
+ ++__counter;
}
}
- return counter;
+ return __counter;
}
- inline OutputIterator
- first_empty(InputIterator c, InputIterator d, OutputIterator out) const
- { return out; }
+ inline _OutputIterator
+ __first_empty(_IIter __c, _IIter d, _OutputIterator __out) const
+ { return __out; }
- inline OutputIterator
- second_empty(InputIterator a, InputIterator b, OutputIterator out) const
- { return out; }
+ inline _OutputIterator
+ __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const
+ { return __out; }
};
-template<class InputIterator, class OutputIterator, class Comparator>
- struct union_func
+template<class _IIter, class _OutputIterator, class _Compare>
+ struct __union_func
{
- typedef typename std::iterator_traits<InputIterator>::difference_type
- difference_type;
+ typedef typename std::iterator_traits<_IIter>::difference_type
+ _DifferenceType;
- union_func(Comparator c) : comp(c) {}
+ __union_func(_Compare __comp) : _M_comp(__comp) {}
- Comparator comp;
+ _Compare _M_comp;
- OutputIterator
- invoke(InputIterator a, const InputIterator b, InputIterator c,
- const InputIterator d, OutputIterator r) const
+ _OutputIterator
+ _M_invoke(_IIter __a, const _IIter __b, _IIter __c,
+ const _IIter d, _OutputIterator __r) const
{
- while (a != b && c != d)
+ while (__a != __b && __c != d)
{
- if (comp(*a, *c))
+ if (_M_comp(*__a, *__c))
{
- *r = *a;
- ++a;
+ *__r = *__a;
+ ++__a;
}
- else if (comp(*c, *a))
+ else if (_M_comp(*__c, *__a))
{
- *r = *c;
- ++c;
+ *__r = *__c;
+ ++__c;
}
else
{
- *r = *a;
- ++a;
- ++c;
+ *__r = *__a;
+ ++__a;
+ ++__c;
}
- ++r;
+ ++__r;
}
- return std::copy(c, d, std::copy(a, b, r));
+ return std::copy(__c, d, std::copy(__a, __b, __r));
}
- difference_type
- count(InputIterator a, InputIterator b,
- InputIterator c, InputIterator d) const
+ _DifferenceType
+ __count(_IIter __a, _IIter __b,
+ _IIter __c, _IIter d) const
{
- difference_type counter = 0;
+ _DifferenceType __counter = 0;
- while (a != b && c != d)
+ while (__a != __b && __c != d)
{
- if (comp(*a, *c))
- { ++a; }
- else if (comp(*c, *a))
- { ++c; }
+ if (_M_comp(*__a, *__c))
+ { ++__a; }
+ else if (_M_comp(*__c, *__a))
+ { ++__c; }
else
{
- ++a;
- ++c;
+ ++__a;
+ ++__c;
}
- ++counter;
+ ++__counter;
}
- counter += (b - a);
- counter += (d - c);
- return counter;
+ __counter += (__b - __a);
+ __counter += (d - __c);
+ return __counter;
}
- inline OutputIterator
- first_empty(InputIterator c, InputIterator d, OutputIterator out) const
- { return std::copy(c, d, out); }
+ inline _OutputIterator
+ __first_empty(_IIter __c, _IIter d, _OutputIterator __out) const
+ { return std::copy(__c, d, __out); }
- inline OutputIterator
- second_empty(InputIterator a, InputIterator b, OutputIterator out) const
- { return std::copy(a, b, out); }
+ inline _OutputIterator
+ __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const
+ { return std::copy(__a, __b, __out); }
};
-template<typename InputIterator,
- typename OutputIterator,
- typename Operation>
- OutputIterator
- parallel_set_operation(InputIterator begin1, InputIterator end1,
- InputIterator begin2, InputIterator end2,
- OutputIterator result, Operation op)
+template<typename _IIter,
+ typename _OutputIterator,
+ typename Operation>
+ _OutputIterator
+ __parallel_set_operation(_IIter __begin1, _IIter __end1,
+ _IIter __begin2, _IIter __end2,
+ _OutputIterator __result, Operation __op)
{
- _GLIBCXX_CALL((end1 - begin1) + (end2 - begin2))
+ _GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2))
- typedef std::iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::difference_type difference_type;
- typedef typename std::pair<InputIterator, InputIterator> iterator_pair;
+ typedef std::iterator_traits<_IIter> _TraitsType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
+ typedef typename std::pair<_IIter, _IIter> _IteratorPair;
- if (begin1 == end1)
- return op.first_empty(begin2, end2, result);
+ if (__begin1 == __end1)
+ return __op.__first_empty(__begin2, __end2, __result);
- if (begin2 == end2)
- return op.second_empty(begin1, end1, result);
+ if (__begin2 == __end2)
+ return __op.__second_empty(__begin1, __end1, __result);
- const difference_type size = (end1 - begin1) + (end2 - begin2);
+ const _DifferenceType size = (__end1 - __begin1) + (__end2 - __begin2);
- const iterator_pair sequence[ 2 ] =
- { std::make_pair(begin1, end1), std::make_pair(begin2, end2) } ;
- OutputIterator return_value = result;
- difference_type *borders;
- iterator_pair *block_begins;
- difference_type* lengths;
+ const _IteratorPair __sequence[ 2 ] =
+ { std::make_pair(__begin1, __end1), std::make_pair(__begin2, __end2) };
+ _OutputIterator return_value = __result;
+ _DifferenceType *__borders;
+ _IteratorPair *__block_begins;
+ _DifferenceType* __lengths;
- thread_index_t num_threads =
- std::min<difference_type>(get_max_threads(),
- std::min(end1 - begin1, end2 - begin2));
+ _ThreadIndex __num_threads =
+ std::min<_DifferenceType>(__get_max_threads(),
+ std::min(__end1 - __begin1, __end2 - __begin2));
-# pragma omp parallel num_threads(num_threads)
+# pragma omp parallel num_threads(__num_threads)
{
# pragma omp single
{
- num_threads = omp_get_num_threads();
-
- borders = new difference_type[num_threads + 2];
- equally_split(size, num_threads + 1, borders);
- block_begins = new iterator_pair[num_threads + 1];
- // Very start.
- block_begins[0] = std::make_pair(begin1, begin2);
- lengths = new difference_type[num_threads];
+ __num_threads = omp_get_num_threads();
+
+ __borders = new _DifferenceType[__num_threads + 2];
+ equally_split(size, __num_threads + 1, __borders);
+ __block_begins = new _IteratorPair[__num_threads + 1];
+ // Very __start.
+ __block_begins[0] = std::make_pair(__begin1, __begin2);
+ __lengths = new _DifferenceType[__num_threads];
} //single
- thread_index_t iam = omp_get_thread_num();
+ _ThreadIndex __iam = omp_get_thread_num();
- // Result from multiseq_partition.
- InputIterator offset[2];
- const difference_type rank = borders[iam + 1];
+ // _Result from multiseq_partition.
+ _IIter __offset[2];
+ const _DifferenceType __rank = __borders[__iam + 1];
- multiseq_partition(sequence, sequence + 2, rank, offset, op.comp);
+ multiseq_partition(__sequence, __sequence + 2,
+ __rank, __offset, __op._M_comp);
// allowed to read?
// together
- // *(offset[ 0 ] - 1) == *offset[ 1 ]
- if (offset[ 0 ] != begin1 && offset[ 1 ] != end2
- && !op.comp(*(offset[ 0 ] - 1), *offset[ 1 ])
- && !op.comp(*offset[ 1 ], *(offset[ 0 ] - 1)))
+ // *(__offset[ 0 ] - 1) == *__offset[ 1 ]
+ if (__offset[ 0 ] != __begin1 && __offset[ 1 ] != __end2
+ && !__op._M_comp(*(__offset[ 0 ] - 1), *__offset[ 1 ])
+ && !__op._M_comp(*__offset[ 1 ], *(__offset[ 0 ] - 1)))
{
// Avoid split between globally equal elements: move one to
// front in first sequence.
- --offset[ 0 ];
+ --__offset[ 0 ];
}
- iterator_pair block_end = block_begins[ iam + 1 ] =
- iterator_pair(offset[ 0 ], offset[ 1 ]);
+ _IteratorPair block_end = __block_begins[ __iam + 1 ] =
+ _IteratorPair(__offset[ 0 ], __offset[ 1 ]);
// Make sure all threads have their block_begin result written out.
# pragma omp barrier
- iterator_pair block_begin = block_begins[ iam ];
+ _IteratorPair __block_begin = __block_begins[ __iam ];
// Begin working for the first block, while the others except
// the last start to count.
- if (iam == 0)
+ if (__iam == 0)
{
// The first thread can copy already.
- lengths[ iam ] = op.invoke(block_begin.first, block_end.first,
- block_begin.second, block_end.second,
- result)
- - result;
+ __lengths[ __iam ] =
+ __op._M_invoke(__block_begin.first, block_end.first,
+ __block_begin.second, block_end.second, __result)
+ - __result;
}
else
{
- lengths[ iam ] = op.count(block_begin.first, block_end.first,
- block_begin.second, block_end.second);
+ __lengths[ __iam ] =
+ __op.__count(__block_begin.first, block_end.first,
+ __block_begin.second, block_end.second);
}
// Make sure everyone wrote their lengths.
# pragma omp barrier
- OutputIterator r = result;
+ _OutputIterator __r = __result;
- if (iam == 0)
+ if (__iam == 0)
{
// Do the last block.
- for (int i = 0; i < num_threads; ++i)
- r += lengths[i];
+ for (int __i = 0; __i < __num_threads; ++__i)
+ __r += __lengths[__i];
- block_begin = block_begins[num_threads];
+ __block_begin = __block_begins[__num_threads];
// Return the result iterator of the last block.
- return_value = op.invoke(
- block_begin.first, end1, block_begin.second, end2, r);
+ return_value = __op._M_invoke(
+ __block_begin.first, __end1, __block_begin.second, __end2, __r);
}
else
{
- for (int i = 0; i < iam; ++i)
- r += lengths[ i ];
+ for (int __i = 0; __i < __iam; ++__i)
+ __r += __lengths[ __i ];
// Reset begins for copy pass.
- op.invoke(block_begin.first, block_end.first,
- block_begin.second, block_end.second, r);
+ __op._M_invoke(__block_begin.first, block_end.first,
+ __block_begin.second, block_end.second, __r);
}
}
return return_value;
}
-template<typename InputIterator,
- typename OutputIterator,
- typename Comparator>
- inline OutputIterator
- parallel_set_union(InputIterator begin1, InputIterator end1,
- InputIterator begin2, InputIterator end2,
- OutputIterator result, Comparator comp)
+template<typename _IIter,
+ typename _OutputIterator,
+ typename _Compare>
+ inline _OutputIterator
+ __parallel_set_union(_IIter __begin1, _IIter __end1,
+ _IIter __begin2, _IIter __end2,
+ _OutputIterator __result, _Compare _M_comp)
{
- return parallel_set_operation(begin1, end1, begin2, end2, result,
- union_func< InputIterator, OutputIterator, Comparator>(comp));
+ return __parallel_set_operation(__begin1, __end1, __begin2, __end2,
+ __result, __union_func< _IIter, _OutputIterator, _Compare>(_M_comp));
}
-template<typename InputIterator,
- typename OutputIterator,
- typename Comparator>
- inline OutputIterator
- parallel_set_intersection(InputIterator begin1, InputIterator end1,
- InputIterator begin2, InputIterator end2,
- OutputIterator result, Comparator comp)
+template<typename _IIter,
+ typename _OutputIterator,
+ typename _Compare>
+ inline _OutputIterator
+ __parallel_set_intersection(_IIter __begin1, _IIter __end1,
+ _IIter __begin2, _IIter __end2,
+ _OutputIterator __result, _Compare _M_comp)
{
- return parallel_set_operation(begin1, end1, begin2, end2, result,
- intersection_func<InputIterator, OutputIterator, Comparator>(comp));
+ return __parallel_set_operation(
+ __begin1, __end1, __begin2, __end2, __result,
+ __intersection_func<_IIter, _OutputIterator, _Compare>(_M_comp));
}
-template<typename InputIterator,
- typename OutputIterator,
- typename Comparator>
- inline OutputIterator
- parallel_set_difference(InputIterator begin1, InputIterator end1,
- InputIterator begin2, InputIterator end2,
- OutputIterator result, Comparator comp)
+template<typename _IIter,
+ typename _OutputIterator,
+ typename _Compare>
+ inline _OutputIterator
+ __parallel_set_difference(_IIter __begin1, _IIter __end1,
+ _IIter __begin2, _IIter __end2,
+ _OutputIterator __result, _Compare _M_comp)
{
- return parallel_set_operation(begin1, end1, begin2, end2, result,
- difference_func<InputIterator, OutputIterator, Comparator>(comp));
+ return __parallel_set_operation(
+ __begin1, __end1, __begin2, __end2, __result,
+ __difference_func<_IIter, _OutputIterator, _Compare>(_M_comp));
}
-template<typename InputIterator,
- typename OutputIterator,
- typename Comparator>
- inline OutputIterator
- parallel_set_symmetric_difference(InputIterator begin1, InputIterator end1,
- InputIterator begin2, InputIterator end2,
- OutputIterator result, Comparator comp)
+template<typename _IIter,
+ typename _OutputIterator,
+ typename _Compare>
+ inline _OutputIterator
+ __parallel_set_symmetric_difference(_IIter __begin1, _IIter __end1,
+ _IIter __begin2, _IIter __end2,
+ _OutputIterator __result,
+ _Compare _M_comp)
{
- return parallel_set_operation(begin1, end1, begin2, end2, result,
- symmetric_difference_func<InputIterator, OutputIterator, Comparator>
- (comp));
+ return __parallel_set_operation(
+ __begin1, __end1, __begin2, __end2, __result,
+ symmetric_difference_func<_IIter, _OutputIterator, _Compare>
+ (_M_comp));
}
}
diff --git a/libstdc++-v3/include/parallel/settings.h b/libstdc++-v3/include/parallel/settings.h
index e4873b4100b..e83ecc50ea5 100644
--- a/libstdc++-v3/include/parallel/settings.h
+++ b/libstdc++-v3/include/parallel/settings.h
@@ -30,7 +30,7 @@
* @section parallelization_decision
* The decision whether to run an algorithm in parallel.
*
- * There are several ways the user can switch on and off the parallel
+ * There are several ways the user can switch on and __off the parallel
* execution of an algorithm, both at compile- and run-time.
*
* Only sequential execution can be forced at compile-time. This
@@ -46,11 +46,11 @@
*
* To force sequential execution of an algorithm ultimately at
* compile-time, the user must add the tag
- * __gnu_parallel::sequential_tag() to the end of the parameter list,
+* gnu_parallel::sequential_tag() to the end of the parameter list,
* e. g.
*
* \code
- * std::sort(v.begin(), v.end(), __gnu_parallel::sequential_tag());
+ * std::sort(__v.begin(), __v.end(), __gnu_parallel::sequential_tag());
* \endcode
*
* This is compatible with all overloaded algorithm variants. No
@@ -60,18 +60,18 @@
* If the algorithm call is not forced to be executed sequentially
* at compile-time, the decision is made at run-time.
* The global variable __gnu_parallel::_Settings::algorithm_strategy
- * is checked. It is a tristate variable corresponding to:
+ * is checked. _It is a tristate variable corresponding to:
*
* a. force_sequential, meaning the sequential algorithm is executed.
- * b. force_parallel, meaning the parallel algorithm is executed.
- * c. heuristic
+* b. force_parallel, meaning the parallel algorithm is executed.
+* c. heuristic
*
* For heuristic, the parallel algorithm implementation is called
* only if the input size is sufficiently large. For most
* algorithms, the input size is the (combined) length of the input
- * sequence(s). The threshold can be set by the user, individually
+* sequence(__s). The threshold can be set by the user, individually
* for each algorithm. The according variables are called
- * __gnu_parallel::_Settings::[algorithm]_minimal_n .
+* gnu_parallel::_Settings::[algorithm]_minimal_n .
*
* For some of the algorithms, there are even more tuning options,
* e. g. the ability to choose from multiple algorithm variants. See
@@ -88,24 +88,29 @@
/**
* @brief Determine at compile(?)-time if the parallel variant of an
* algorithm should be called.
- * @param c A condition that is convertible to bool that is overruled by
+ * @param __c A condition that is convertible to bool that is overruled by
* __gnu_parallel::_Settings::algorithm_strategy. Usually a decision
* based on the input size.
*/
-#define _GLIBCXX_PARALLEL_CONDITION(c) (__gnu_parallel::_Settings::get().algorithm_strategy != __gnu_parallel::force_sequential && ((__gnu_parallel::get_max_threads() > 1 && (c)) || __gnu_parallel::_Settings::get().algorithm_strategy == __gnu_parallel::force_parallel))
+#define _GLIBCXX_PARALLEL_CONDITION(__c) \
+ (__gnu_parallel::_Settings::get().algorithm_strategy \
+ != __gnu_parallel::force_sequential \
+ && ((__gnu_parallel::__get_max_threads() > 1 && (__c)) \
+ || __gnu_parallel::_Settings::get().algorithm_strategy \
+ == __gnu_parallel::force_parallel))
/*
inline bool
-parallel_condition(bool c)
+parallel_condition(bool __c)
{
bool ret = false;
- const _Settings& s = _Settings::get();
- if (s.algorithm_strategy != force_seqential)
+ const _Settings& __s = _Settings::get();
+ if (__s.algorithm_strategy != force_seqential)
{
- if (s.algorithm_strategy == force_parallel)
- ret = true;
+ if (__s.algorithm_strategy == force_parallel)
+ ret = true;
else
- ret = get_max_threads() > 1 && c;
+ ret = __get_max_threads() > 1 && __c;
}
return ret;
}
@@ -113,156 +118,156 @@ parallel_condition(bool c)
namespace __gnu_parallel
{
- /// class _Settings
- /// Run-time settings for the parallel mode, including all tunable parameters.
+ /// class _Settings
+ /// Run-time settings for the parallel mode including all tunable parameters.
struct _Settings
{
- _AlgorithmStrategy algorithm_strategy;
+ _AlgorithmStrategy algorithm_strategy;
- _SortAlgorithm sort_algorithm;
- _PartialSumAlgorithm partial_sum_algorithm;
- _MultiwayMergeAlgorithm multiway_merge_algorithm;
- _FindAlgorithm find_algorithm;
+ _SortAlgorithm sort_algorithm;
+ _PartialSumAlgorithm partial_sum_algorithm;
+ _MultiwayMergeAlgorithm multiway_merge_algorithm;
+ _FindAlgorithm find_algorithm;
- _SplittingAlgorithm sort_splitting;
- _SplittingAlgorithm merge_splitting;
- _SplittingAlgorithm multiway_merge_splitting;
+ _SplittingAlgorithm sort_splitting;
+ _SplittingAlgorithm merge_splitting;
+ _SplittingAlgorithm multiway_merge_splitting;
// Per-algorithm settings.
/// Minimal input size for accumulate.
- sequence_index_t accumulate_minimal_n;
+ _SequenceIndex accumulate_minimal_n;
/// Minimal input size for adjacent_difference.
- unsigned int adjacent_difference_minimal_n;
+ unsigned int adjacent_difference_minimal_n;
/// Minimal input size for count and count_if.
- sequence_index_t count_minimal_n;
+ _SequenceIndex count_minimal_n;
/// Minimal input size for fill.
- sequence_index_t fill_minimal_n;
+ _SequenceIndex fill_minimal_n;
/// Block size increase factor for find.
- double find_increasing_factor;
+ double find_increasing_factor;
/// Initial block size for find.
- sequence_index_t find_initial_block_size;
+ _SequenceIndex find_initial_block_size;
/// Maximal block size for find.
- sequence_index_t find_maximum_block_size;
+ _SequenceIndex find_maximum_block_size;
/// Start with looking for this many elements sequentially, for find.
- sequence_index_t find_sequential_search_size;
+ _SequenceIndex find_sequential_search_size;
/// Minimal input size for for_each.
- sequence_index_t for_each_minimal_n;
+ _SequenceIndex for_each_minimal_n;
/// Minimal input size for generate.
- sequence_index_t generate_minimal_n;
+ _SequenceIndex generate_minimal_n;
/// Minimal input size for max_element.
- sequence_index_t max_element_minimal_n;
+ _SequenceIndex max_element_minimal_n;
/// Minimal input size for merge.
- sequence_index_t merge_minimal_n;
+ _SequenceIndex merge_minimal_n;
/// Oversampling factor for merge.
- unsigned int merge_oversampling;
+ unsigned int merge_oversampling;
/// Minimal input size for min_element.
- sequence_index_t min_element_minimal_n;
+ _SequenceIndex min_element_minimal_n;
/// Minimal input size for multiway_merge.
- sequence_index_t multiway_merge_minimal_n;
+ _SequenceIndex multiway_merge_minimal_n;
/// Oversampling factor for multiway_merge.
- int multiway_merge_minimal_k;
+ int multiway_merge_minimal_k;
/// Oversampling factor for multiway_merge.
- unsigned int multiway_merge_oversampling;
+ unsigned int multiway_merge_oversampling;
/// Minimal input size for nth_element.
- sequence_index_t nth_element_minimal_n;
+ _SequenceIndex nth_element_minimal_n;
/// Chunk size for partition.
- sequence_index_t partition_chunk_size;
+ _SequenceIndex partition_chunk_size;
/// Chunk size for partition, relative to input size. If > 0.0,
/// this value overrides partition_chunk_size.
- double partition_chunk_share;
+ double partition_chunk_share;
/// Minimal input size for partition.
- sequence_index_t partition_minimal_n;
+ _SequenceIndex partition_minimal_n;
/// Minimal input size for partial_sort.
- sequence_index_t partial_sort_minimal_n;
+ _SequenceIndex partial_sort_minimal_n;
/// Ratio for partial_sum. Assume "sum and write result" to be
/// this factor slower than just "sum".
- float partial_sum_dilation;
+ float partial_sum_dilation;
/// Minimal input size for partial_sum.
- unsigned int partial_sum_minimal_n;
+ unsigned int partial_sum_minimal_n;
/// Minimal input size for random_shuffle.
- unsigned int random_shuffle_minimal_n;
+ unsigned int random_shuffle_minimal_n;
/// Minimal input size for replace and replace_if.
- sequence_index_t replace_minimal_n;
+ _SequenceIndex replace_minimal_n;
/// Minimal input size for set_difference.
- sequence_index_t set_difference_minimal_n;
+ _SequenceIndex set_difference_minimal_n;
/// Minimal input size for set_intersection.
- sequence_index_t set_intersection_minimal_n;
+ _SequenceIndex set_intersection_minimal_n;
/// Minimal input size for set_symmetric_difference.
- sequence_index_t set_symmetric_difference_minimal_n;
+ _SequenceIndex set_symmetric_difference_minimal_n;
/// Minimal input size for set_union.
- sequence_index_t set_union_minimal_n;
+ _SequenceIndex set_union_minimal_n;
/// Minimal input size for parallel sorting.
- sequence_index_t sort_minimal_n;
+ _SequenceIndex sort_minimal_n;
/// Oversampling factor for parallel std::sort (MWMS).
- unsigned int sort_mwms_oversampling;
+ unsigned int sort_mwms_oversampling;
/// Such many samples to take to find a good pivot (quicksort).
- unsigned int sort_qs_num_samples_preset;
+ unsigned int sort_qs_num_samples_preset;
- /// Maximal subsequence length to switch to unbalanced base case.
+ /// Maximal subsequence __length to switch to unbalanced __base case.
/// Applies to std::sort with dynamically load-balanced quicksort.
- sequence_index_t sort_qsb_base_case_maximal_n;
+ _SequenceIndex sort_qsb_base_case_maximal_n;
/// Minimal input size for parallel std::transform.
- sequence_index_t transform_minimal_n;
+ _SequenceIndex transform_minimal_n;
/// Minimal input size for unique_copy.
- sequence_index_t unique_copy_minimal_n;
+ _SequenceIndex unique_copy_minimal_n;
- sequence_index_t workstealing_chunk_size;
+ _SequenceIndex workstealing_chunk_size;
// Hardware dependent tuning parameters.
- /// Size of the L1 cache in bytes (underestimation).
- unsigned long long L1_cache_size;
+ /// size of the L1 cache in bytes (underestimation).
+ unsigned long long L1_cache_size;
- /// Size of the L2 cache in bytes (underestimation).
- unsigned long long L2_cache_size;
+ /// size of the L2 cache in bytes (underestimation).
+ unsigned long long L2_cache_size;
- /// Size of the Translation Lookaside Buffer (underestimation).
- unsigned int TLB_size;
+ /// size of the Translation Lookaside Buffer (underestimation).
+ unsigned int TLB_size;
/// Overestimation of cache line size. Used to avoid false
- /// sharing, i. e. elements of different threads are at least this
+ /// sharing, i.e. elements of different threads are at least this
/// amount apart.
- unsigned int cache_line_size;
+ unsigned int cache_line_size;
// Statistics.
/// The number of stolen ranges in load-balanced quicksort.
- sequence_index_t qsb_steals;
+ _SequenceIndex qsb_steals;
/// Get the global settings.
_GLIBCXX_CONST static const _Settings&
@@ -273,7 +278,56 @@ namespace __gnu_parallel
set(_Settings&) throw();
explicit
- _Settings() : algorithm_strategy(heuristic), sort_algorithm(MWMS), partial_sum_algorithm(LINEAR), multiway_merge_algorithm(LOSER_TREE), find_algorithm(CONSTANT_SIZE_BLOCKS), sort_splitting(EXACT), merge_splitting(EXACT), multiway_merge_splitting(EXACT), accumulate_minimal_n(1000), adjacent_difference_minimal_n(1000), count_minimal_n(1000), fill_minimal_n(1000), find_increasing_factor(2.0), find_initial_block_size(256), find_maximum_block_size(8192), find_sequential_search_size(256), for_each_minimal_n(1000), generate_minimal_n(1000), max_element_minimal_n(1000), merge_minimal_n(1000), merge_oversampling(10), min_element_minimal_n(1000), multiway_merge_minimal_n(1000), multiway_merge_minimal_k(2), multiway_merge_oversampling(10), nth_element_minimal_n(1000), partition_chunk_size(1000), partition_chunk_share(0.0), partition_minimal_n(1000), partial_sort_minimal_n(1000), partial_sum_dilation(1.0f), partial_sum_minimal_n(1000), random_shuffle_minimal_n(1000), replace_minimal_n(1000), set_difference_minimal_n(1000), set_intersection_minimal_n(1000), set_symmetric_difference_minimal_n(1000), set_union_minimal_n(1000), sort_minimal_n(1000), sort_mwms_oversampling(10), sort_qs_num_samples_preset(100), sort_qsb_base_case_maximal_n(100), transform_minimal_n(1000), unique_copy_minimal_n(10000), workstealing_chunk_size(100), L1_cache_size(16 << 10), L2_cache_size(256 << 10), TLB_size(128), cache_line_size(64), qsb_steals(0)
+ _Settings() :
+ algorithm_strategy(heuristic),
+ sort_algorithm(MWMS),
+ partial_sum_algorithm(LINEAR),
+ multiway_merge_algorithm(LOSER_TREE),
+ find_algorithm(CONSTANT_SIZE_BLOCKS),
+ sort_splitting(EXACT),
+ merge_splitting(EXACT),
+ multiway_merge_splitting(EXACT),
+ accumulate_minimal_n(1000),
+ adjacent_difference_minimal_n(1000),
+ count_minimal_n(1000),
+ fill_minimal_n(1000),
+ find_increasing_factor(2.0),
+ find_initial_block_size(256),
+ find_maximum_block_size(8192),
+ find_sequential_search_size(256),
+ for_each_minimal_n(1000),
+ generate_minimal_n(1000),
+ max_element_minimal_n(1000),
+ merge_minimal_n(1000),
+ merge_oversampling(10),
+ min_element_minimal_n(1000),
+ multiway_merge_minimal_n(1000),
+ multiway_merge_minimal_k(2), multiway_merge_oversampling(10),
+ nth_element_minimal_n(1000),
+ partition_chunk_size(1000),
+ partition_chunk_share(0.0),
+ partition_minimal_n(1000),
+ partial_sort_minimal_n(1000),
+ partial_sum_dilation(1.0f),
+ partial_sum_minimal_n(1000),
+ random_shuffle_minimal_n(1000),
+ replace_minimal_n(1000),
+ set_difference_minimal_n(1000),
+ set_intersection_minimal_n(1000),
+ set_symmetric_difference_minimal_n(1000),
+ set_union_minimal_n(1000),
+ sort_minimal_n(1000),
+ sort_mwms_oversampling(10),
+ sort_qs_num_samples_preset(100),
+ sort_qsb_base_case_maximal_n(100),
+ transform_minimal_n(1000),
+ unique_copy_minimal_n(10000),
+ workstealing_chunk_size(100),
+ L1_cache_size(16 << 10),
+ L2_cache_size(256 << 10),
+ TLB_size(128),
+ cache_line_size(64),
+ qsb_steals(0)
{ }
};
}
diff --git a/libstdc++-v3/include/parallel/sort.h b/libstdc++-v3/include/parallel/sort.h
index de226e8b418..03b19210a82 100644
--- a/libstdc++-v3/include/parallel/sort.h
+++ b/libstdc++-v3/include/parallel/sort.h
@@ -54,175 +54,179 @@
namespace __gnu_parallel
{
- //prototype
- template<bool stable, typename RandomAccessIterator,
- typename Comparator, typename Parallelism>
+ //prototype
+ template<bool __stable, typename _RAIter,
+ typename _Compare, typename _Parallelism>
void
- parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp, Parallelism parallelism);
-
+ parallel_sort(_RAIter __begin, _RAIter __end,
+ _Compare __comp, _Parallelism __parallelism);
+
/**
* @brief Choose multiway mergesort, splitting variant at run-time,
* for parallel sorting.
- * @param begin Begin iterator of input sequence.
- * @param end End iterator of input sequence.
- * @param comp Comparator.
+ * @param __begin Begin iterator of input sequence.
+ * @param __end End iterator of input sequence.
+ * @param __comp Comparator.
* @callgraph
*/
- template<bool stable, typename RandomAccessIterator, typename Comparator>
+ template<bool __stable, typename _RAIter, typename _Compare>
inline void
- parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp, multiway_mergesort_tag parallelism)
+ parallel_sort(_RAIter __begin, _RAIter __end,
+ _Compare __comp, multiway_mergesort_tag __parallelism)
{
- _GLIBCXX_CALL(end - begin)
+ _GLIBCXX_CALL(__end - __begin)
if(_Settings::get().sort_splitting == EXACT)
- parallel_sort_mwms<stable, true>
- (begin, end, comp, parallelism.get_num_threads());
+ parallel_sort_mwms<__stable, true>
+ (__begin, __end, __comp, __parallelism.__get_num_threads());
else
- parallel_sort_mwms<stable, false>
- (begin, end, comp, parallelism.get_num_threads());
+ parallel_sort_mwms<__stable, false>
+ (__begin, __end, __comp, __parallelism.__get_num_threads());
}
/**
* @brief Choose multiway mergesort with exact splitting,
* for parallel sorting.
- * @param begin Begin iterator of input sequence.
- * @param end End iterator of input sequence.
- * @param comp Comparator.
+ * @param __begin Begin iterator of input sequence.
+ * @param __end End iterator of input sequence.
+ * @param __comp Comparator.
* @callgraph
*/
- template<bool stable, typename RandomAccessIterator, typename Comparator>
+ template<bool __stable, typename _RAIter, typename _Compare>
inline void
- parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp, multiway_mergesort_exact_tag parallelism)
+ parallel_sort(_RAIter __begin, _RAIter __end,
+ _Compare __comp, multiway_mergesort_exact_tag __parallelism)
{
- _GLIBCXX_CALL(end - begin)
+ _GLIBCXX_CALL(__end - __begin)
- parallel_sort_mwms<stable, true>
- (begin, end, comp, parallelism.get_num_threads());
+ parallel_sort_mwms<__stable, true>
+ (__begin, __end, __comp, __parallelism.__get_num_threads());
}
/**
* @brief Choose multiway mergesort with splitting by sampling,
* for parallel sorting.
- * @param begin Begin iterator of input sequence.
- * @param end End iterator of input sequence.
- * @param comp Comparator.
+ * @param __begin Begin iterator of input sequence.
+ * @param __end End iterator of input sequence.
+ * @param __comp Comparator.
* @callgraph
*/
- template<bool stable, typename RandomAccessIterator, typename Comparator>
+ template<bool __stable, typename _RAIter, typename _Compare>
inline void
- parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp, multiway_mergesort_sampling_tag parallelism)
+ parallel_sort(_RAIter __begin, _RAIter __end,
+ _Compare __comp, multiway_mergesort_sampling_tag __parallelism)
{
- _GLIBCXX_CALL(end - begin)
+ _GLIBCXX_CALL(__end - __begin)
- parallel_sort_mwms<stable, false>
- (begin, end, comp, parallelism.get_num_threads());
+ parallel_sort_mwms<__stable, false>
+ (__begin, __end, __comp, __parallelism.__get_num_threads());
}
/**
* @brief Choose quicksort for parallel sorting.
- * @param begin Begin iterator of input sequence.
- * @param end End iterator of input sequence.
- * @param comp Comparator.
+ * @param __begin Begin iterator of input sequence.
+ * @param __end End iterator of input sequence.
+ * @param __comp Comparator.
* @callgraph
*/
- template<bool stable, typename RandomAccessIterator, typename Comparator>
+ template<bool __stable, typename _RAIter, typename _Compare>
inline void
- parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp, quicksort_tag parallelism)
+ parallel_sort(_RAIter __begin, _RAIter __end,
+ _Compare __comp, quicksort_tag __parallelism)
{
- _GLIBCXX_CALL(end - begin)
+ _GLIBCXX_CALL(__end - __begin)
- _GLIBCXX_PARALLEL_ASSERT(stable == false);
+ _GLIBCXX_PARALLEL_ASSERT(__stable == false);
- parallel_sort_qs(begin, end, comp, parallelism.get_num_threads());
+ __parallel_sort_qs(__begin, __end, __comp,
+ __parallelism.__get_num_threads());
}
/**
* @brief Choose balanced quicksort for parallel sorting.
- * @param begin Begin iterator of input sequence.
- * @param end End iterator of input sequence.
- * @param comp Comparator.
- * @param stable Sort stable.
+ * @param __begin Begin iterator of input sequence.
+ * @param __end End iterator of input sequence.
+ * @param __comp Comparator.
+ * @param __stable Sort __stable.
* @callgraph
*/
- template<bool stable, typename RandomAccessIterator, typename Comparator>
+ template<bool __stable, typename _RAIter, typename _Compare>
inline void
- parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp, balanced_quicksort_tag parallelism)
+ parallel_sort(_RAIter __begin, _RAIter __end,
+ _Compare __comp, balanced_quicksort_tag __parallelism)
{
- _GLIBCXX_CALL(end - begin)
+ _GLIBCXX_CALL(__end - __begin)
- _GLIBCXX_PARALLEL_ASSERT(stable == false);
+ _GLIBCXX_PARALLEL_ASSERT(__stable == false);
- parallel_sort_qsb(begin, end, comp, parallelism.get_num_threads());
+ __parallel_sort_qsb(__begin, __end, __comp,
+ __parallelism.__get_num_threads());
}
/**
* @brief Choose multiway mergesort with exact splitting,
* for parallel sorting.
- * @param begin Begin iterator of input sequence.
- * @param end End iterator of input sequence.
- * @param comp Comparator.
+ * @param __begin Begin iterator of input sequence.
+ * @param __end End iterator of input sequence.
+ * @param __comp Comparator.
* @callgraph
*/
- template<bool stable, typename RandomAccessIterator, typename Comparator>
+ template<bool __stable, typename _RAIter, typename _Compare>
inline void
- parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp, default_parallel_tag parallelism)
+ parallel_sort(_RAIter __begin, _RAIter __end,
+ _Compare __comp, default_parallel_tag __parallelism)
{
- _GLIBCXX_CALL(end - begin)
+ _GLIBCXX_CALL(__end - __begin)
- parallel_sort<stable>
- (begin, end, comp,
- multiway_mergesort_exact_tag(parallelism.get_num_threads()));
+ parallel_sort<__stable>
+ (__begin, __end, __comp,
+ multiway_mergesort_exact_tag(__parallelism.__get_num_threads()));
}
/**
* @brief Choose a parallel sorting algorithm.
- * @param begin Begin iterator of input sequence.
- * @param end End iterator of input sequence.
- * @param comp Comparator.
- * @param stable Sort stable.
+ * @param __begin Begin iterator of input sequence.
+ * @param __end End iterator of input sequence.
+ * @param __comp Comparator.
+ * @param __stable Sort __stable.
* @callgraph
*/
- template<bool stable, typename RandomAccessIterator, typename Comparator>
+ template<bool __stable, typename _RAIter, typename _Compare>
inline void
- parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp, parallel_tag parallelism)
+ parallel_sort(_RAIter __begin, _RAIter __end,
+ _Compare __comp, parallel_tag __parallelism)
{
- _GLIBCXX_CALL(end - begin)
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ _GLIBCXX_CALL(__end - __begin)
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
if (false) ;
#if _GLIBCXX_MERGESORT
- else if (stable || _Settings::get().sort_algorithm == MWMS)
+ else if (__stable || _Settings::get().sort_algorithm == MWMS)
{
if(_Settings::get().sort_splitting == EXACT)
- parallel_sort_mwms<stable, true>
- (begin, end, comp, parallelism.get_num_threads());
+ parallel_sort_mwms<__stable, true>
+ (__begin, __end, __comp, __parallelism.__get_num_threads());
else
parallel_sort_mwms<false, false>
- (begin, end, comp, parallelism.get_num_threads());
+ (__begin, __end, __comp, __parallelism.__get_num_threads());
}
#endif
#if _GLIBCXX_QUICKSORT
else if (_Settings::get().sort_algorithm == QS)
- parallel_sort_qs(begin, end, comp, parallelism.get_num_threads());
+ __parallel_sort_qs(__begin, __end, __comp,
+ __parallelism.__get_num_threads());
#endif
#if _GLIBCXX_BAL_QUICKSORT
else if (_Settings::get().sort_algorithm == QS_BALANCED)
- parallel_sort_qsb(begin, end, comp, parallelism.get_num_threads());
+ __parallel_sort_qsb(__begin, __end, __comp,
+ __parallelism.__get_num_threads());
#endif
else
- __gnu_sequential::sort(begin, end, comp);
+ __gnu_sequential::sort(__begin, __end, __comp);
}
} // end namespace __gnu_parallel
diff --git a/libstdc++-v3/include/parallel/tags.h b/libstdc++-v3/include/parallel/tags.h
index bc1a7e5c635..43561d28d5c 100644
--- a/libstdc++-v3/include/parallel/tags.h
+++ b/libstdc++-v3/include/parallel/tags.h
@@ -46,37 +46,37 @@ namespace __gnu_parallel
struct parallel_tag
{
private:
- thread_index_t num_threads;
+ _ThreadIndex _M_num_threads;
public:
/** @brief Default constructor. Use default number of threads. */
parallel_tag()
{
- this->num_threads = 0;
+ this->_M_num_threads = 0;
}
/** @brief Default constructor. Recommend number of threads to use.
- * @param num_threads Desired number of threads. */
- parallel_tag(thread_index_t num_threads)
+ * @param __num_threads Desired number of threads. */
+ parallel_tag(_ThreadIndex __num_threads)
{
- this->num_threads = num_threads;
+ this->_M_num_threads = __num_threads;
}
/** @brief Find out desired number of threads.
* @return Desired number of threads. */
- inline thread_index_t get_num_threads()
+ inline _ThreadIndex __get_num_threads()
{
- if(num_threads == 0)
+ if(_M_num_threads == 0)
return omp_get_max_threads();
else
- return num_threads;
+ return _M_num_threads;
}
/** @brief Set the desired number of threads.
- * @param num_threads Desired number of threads. */
- inline void set_num_threads(thread_index_t num_threads)
+ * @param __num_threads Desired number of threads. */
+ inline void set_num_threads(_ThreadIndex __num_threads)
{
- this->num_threads = num_threads;
+ this->_M_num_threads = __num_threads;
}
};
@@ -85,8 +85,8 @@ namespace __gnu_parallel
struct default_parallel_tag : public parallel_tag
{
default_parallel_tag() { }
- default_parallel_tag(thread_index_t num_threads)
- : parallel_tag(num_threads) { }
+ default_parallel_tag(_ThreadIndex __num_threads)
+ : parallel_tag(__num_threads) { }
};
/** @brief Recommends parallel execution using dynamic
@@ -115,8 +115,8 @@ namespace __gnu_parallel
struct exact_tag : public parallel_tag
{
exact_tag() { }
- exact_tag(thread_index_t num_threads)
- : parallel_tag(num_threads) { }
+ exact_tag(_ThreadIndex __num_threads)
+ : parallel_tag(__num_threads) { }
};
/** @brief Forces parallel merging
@@ -124,8 +124,8 @@ namespace __gnu_parallel
struct sampling_tag : public parallel_tag
{
sampling_tag() { }
- sampling_tag(thread_index_t num_threads)
- : parallel_tag(num_threads) { }
+ sampling_tag(_ThreadIndex __num_threads)
+ : parallel_tag(__num_threads) { }
};
@@ -134,8 +134,8 @@ namespace __gnu_parallel
struct multiway_mergesort_tag : public parallel_tag
{
multiway_mergesort_tag() { }
- multiway_mergesort_tag(thread_index_t num_threads)
- : parallel_tag(num_threads) { }
+ multiway_mergesort_tag(_ThreadIndex __num_threads)
+ : parallel_tag(__num_threads) { }
};
/** @brief Forces parallel sorting using multiway mergesort
@@ -143,8 +143,8 @@ namespace __gnu_parallel
struct multiway_mergesort_exact_tag : public parallel_tag
{
multiway_mergesort_exact_tag() { }
- multiway_mergesort_exact_tag(thread_index_t num_threads)
- : parallel_tag(num_threads) { }
+ multiway_mergesort_exact_tag(_ThreadIndex __num_threads)
+ : parallel_tag(__num_threads) { }
};
/** @brief Forces parallel sorting using multiway mergesort
@@ -152,8 +152,8 @@ namespace __gnu_parallel
struct multiway_mergesort_sampling_tag : public parallel_tag
{
multiway_mergesort_sampling_tag() { }
- multiway_mergesort_sampling_tag(thread_index_t num_threads)
- : parallel_tag(num_threads) { }
+ multiway_mergesort_sampling_tag(_ThreadIndex __num_threads)
+ : parallel_tag(__num_threads) { }
};
/** @brief Forces parallel sorting using unbalanced quicksort
@@ -161,8 +161,8 @@ namespace __gnu_parallel
struct quicksort_tag : public parallel_tag
{
quicksort_tag() { }
- quicksort_tag(thread_index_t num_threads)
- : parallel_tag(num_threads) { }
+ quicksort_tag(_ThreadIndex __num_threads)
+ : parallel_tag(__num_threads) { }
};
/** @brief Forces parallel sorting using balanced quicksort
@@ -170,8 +170,8 @@ namespace __gnu_parallel
struct balanced_quicksort_tag : public parallel_tag
{
balanced_quicksort_tag() { }
- balanced_quicksort_tag(thread_index_t num_threads)
- : parallel_tag(num_threads) { }
+ balanced_quicksort_tag(_ThreadIndex __num_threads)
+ : parallel_tag(__num_threads) { }
};
diff --git a/libstdc++-v3/include/parallel/types.h b/libstdc++-v3/include/parallel/types.h
index 053dfff159b..3321f2d5bad 100644
--- a/libstdc++-v3/include/parallel/types.h
+++ b/libstdc++-v3/include/parallel/types.h
@@ -79,7 +79,7 @@ namespace __gnu_parallel
};
/// Merging algorithms:
- // bubblesort-alike, loser-tree variants, enum sentinel.
+ // bubblesort-alike, loser-tree variants, enum __sentinel.
enum _MultiwayMergeAlgorithm
{
LOSER_TREE
@@ -92,7 +92,7 @@ namespace __gnu_parallel
LINEAR
};
- /// Sorting/merging algorithms: sampling, exact.
+ /// Sorting/merging algorithms: sampling, __exact.
enum _SplittingAlgorithm
{
SAMPLING,
@@ -108,7 +108,7 @@ namespace __gnu_parallel
EQUAL_SPLIT
};
- /// Integer Types.
+ /// _Integer Types.
// XXX need to use <cstdint>
/** @brief 16-bit signed integer. */
typedef short int16;
@@ -129,27 +129,28 @@ namespace __gnu_parallel
typedef unsigned long long uint64;
/**
- * @brief Unsigned integer to index elements.
+ * @brief Unsigned integer to index __elements.
* The total number of elements for each algorithm must fit into this type.
*/
- typedef uint64 sequence_index_t;
+ typedef uint64 _SequenceIndex;
/**
* @brief Unsigned integer to index a thread number.
* The maximum thread number (for each processor) must fit into this type.
*/
- typedef uint16 thread_index_t;
+ typedef uint16 _ThreadIndex;
// XXX atomics interface?
/// Longest compare-and-swappable integer type on this platform.
- typedef int64 lcas_t;
+ typedef int64 _CASable;
// XXX numeric_limits::digits?
- /// Number of bits of ::lcas_t.
- static const int lcas_t_bits = sizeof(lcas_t) * 8;
+ /// Number of bits of ::_CASable.
+ static const int _CASable_bits = sizeof(_CASable) * 8;
- /// ::lcas_t with the right half of bits set to 1.
- static const lcas_t lcas_t_mask = ((lcas_t(1) << (lcas_t_bits / 2)) - 1);
+ /// ::_CASable with the right half of bits set to 1.
+ static const _CASable _CASable_mask =
+ ((_CASable(1) << (_CASable_bits / 2)) - 1);
}
#endif /* _GLIBCXX_PARALLEL_TYPES_H */
diff --git a/libstdc++-v3/include/parallel/unique_copy.h b/libstdc++-v3/include/parallel/unique_copy.h
index a83c2c0c504..327870e7d86 100644
--- a/libstdc++-v3/include/parallel/unique_copy.h
+++ b/libstdc++-v3/include/parallel/unique_copy.h
@@ -38,153 +38,153 @@
namespace __gnu_parallel
{
-/** @brief Parallel std::unique_copy(), w/o explicit equality predicate.
- * @param first Begin iterator of input sequence.
- * @param last End iterator of input sequence.
- * @param result Begin iterator of result sequence.
- * @param binary_pred Equality predicate.
- * @return End iterator of result sequence. */
-template<typename InputIterator,
- class OutputIterator,
- class BinaryPredicate>
- OutputIterator
- parallel_unique_copy(InputIterator first, InputIterator last,
- OutputIterator result, BinaryPredicate binary_pred)
+/** @brief Parallel std::unique_copy(), w/__o explicit equality predicate.
+ * @param __first Begin iterator of input sequence.
+ * @param __last End iterator of input sequence.
+ * @param __result Begin iterator of result __sequence.
+ * @param __binary_pred Equality predicate.
+ * @return End iterator of result __sequence. */
+template<typename _IIter,
+ class _OutputIterator,
+ class _BinaryPredicate>
+ _OutputIterator
+ __parallel_unique_copy(_IIter __first, _IIter __last,
+ _OutputIterator __result, _BinaryPredicate __binary_pred)
{
- _GLIBCXX_CALL(last - first)
+ _GLIBCXX_CALL(__last - __first)
- typedef std::iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_IIter> _TraitsType;
+ typedef typename _TraitsType::value_type _ValueType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
- difference_type size = last - first;
+ _DifferenceType size = __last - __first;
if (size == 0)
- return result;
+ return __result;
// Let the first thread process two parts.
- difference_type *counter;
- difference_type *borders;
+ _DifferenceType *__counter;
+ _DifferenceType *__borders;
- thread_index_t num_threads = get_max_threads();
+ _ThreadIndex __num_threads = __get_max_threads();
// First part contains at least one element.
-# pragma omp parallel num_threads(num_threads)
+# pragma omp parallel num_threads(__num_threads)
{
# pragma omp single
{
- num_threads = omp_get_num_threads();
- borders = new difference_type[num_threads + 2];
- equally_split(size, num_threads + 1, borders);
- counter = new difference_type[num_threads + 1];
+ __num_threads = omp_get_num_threads();
+ __borders = new _DifferenceType[__num_threads + 2];
+ equally_split(size, __num_threads + 1, __borders);
+ __counter = new _DifferenceType[__num_threads + 1];
}
- thread_index_t iam = omp_get_thread_num();
+ _ThreadIndex __iam = omp_get_thread_num();
- difference_type begin, end;
+ _DifferenceType __begin, __end;
// Check for length without duplicates
// Needed for position in output
- difference_type i = 0;
- OutputIterator out = result;
+ _DifferenceType __i = 0;
+ _OutputIterator __out = __result;
- if (iam == 0)
+ if (__iam == 0)
{
- begin = borders[0] + 1; // == 1
- end = borders[iam + 1];
+ __begin = __borders[0] + 1; // == 1
+ __end = __borders[__iam + 1];
- ++i;
- *out++ = *first;
+ ++__i;
+ *__out++ = *__first;
- for (InputIterator iter = first + begin; iter < first + end; ++iter)
+ for (_IIter iter = __first + __begin; iter < __first + __end; ++iter)
{
- if (!binary_pred(*iter, *(iter-1)))
+ if (!__binary_pred(*iter, *(iter-1)))
{
- ++i;
- *out++ = *iter;
+ ++__i;
+ *__out++ = *iter;
}
}
}
else
{
- begin = borders[iam]; //one part
- end = borders[iam + 1];
+ __begin = __borders[__iam]; //one part
+ __end = __borders[__iam + 1];
- for (InputIterator iter = first + begin; iter < first + end; ++iter)
+ for (_IIter iter = __first + __begin; iter < __first + __end; ++iter)
{
- if (!binary_pred(*iter, *(iter - 1)))
- ++i;
- }
+ if (!__binary_pred(*iter, *(iter - 1)))
+ ++__i;
+ }
}
- counter[iam] = i;
+ __counter[__iam] = __i;
// Last part still untouched.
- difference_type begin_output;
+ _DifferenceType __begin_output;
# pragma omp barrier
// Store result in output on calculated positions.
- begin_output = 0;
+ __begin_output = 0;
- if (iam == 0)
+ if (__iam == 0)
{
- for (int t = 0; t < num_threads; ++t)
- begin_output += counter[t];
+ for (int __t = 0; __t < __num_threads; ++__t)
+ __begin_output += __counter[__t];
- i = 0;
+ __i = 0;
- OutputIterator iter_out = result + begin_output;
+ _OutputIterator __iter_out = __result + __begin_output;
- begin = borders[num_threads];
- end = size;
+ __begin = __borders[__num_threads];
+ __end = size;
- for (InputIterator iter = first + begin; iter < first + end; ++iter)
+ for (_IIter iter = __first + __begin; iter < __first + __end; ++iter)
{
- if (iter == first || !binary_pred(*iter, *(iter - 1)))
+ if (iter == __first || !__binary_pred(*iter, *(iter - 1)))
{
- ++i;
- *iter_out++ = *iter;
+ ++__i;
+ *__iter_out++ = *iter;
}
}
- counter[num_threads] = i;
+ __counter[__num_threads] = __i;
}
else
{
- for (int t = 0; t < iam; t++)
- begin_output += counter[t];
+ for (int __t = 0; __t < __iam; __t++)
+ __begin_output += __counter[__t];
- OutputIterator iter_out = result + begin_output;
- for (InputIterator iter = first + begin; iter < first + end; ++iter)
+ _OutputIterator __iter_out = __result + __begin_output;
+ for (_IIter iter = __first + __begin; iter < __first + __end; ++iter)
{
- if (!binary_pred(*iter, *(iter-1)))
- *iter_out++ = *iter;
- }
+ if (!__binary_pred(*iter, *(iter-1)))
+ *__iter_out++ = *iter;
+ }
}
}
- difference_type end_output = 0;
- for (int t = 0; t < num_threads + 1; t++)
- end_output += counter[t];
+ _DifferenceType __end_output = 0;
+ for (int __t = 0; __t < __num_threads + 1; __t++)
+ __end_output += __counter[__t];
- delete[] borders;
+ delete[] __borders;
- return result + end_output;
+ return __result + __end_output;
}
/** @brief Parallel std::unique_copy(), without explicit equality predicate
- * @param first Begin iterator of input sequence.
- * @param last End iterator of input sequence.
- * @param result Begin iterator of result sequence.
- * @return End iterator of result sequence. */
-template<typename InputIterator, class OutputIterator>
- inline OutputIterator
- parallel_unique_copy(InputIterator first, InputIterator last,
- OutputIterator result)
+ * @param __first Begin iterator of input sequence.
+ * @param __last End iterator of input sequence.
+ * @param __result Begin iterator of result __sequence.
+ * @return End iterator of result __sequence. */
+template<typename _IIter, class _OutputIterator>
+ inline _OutputIterator
+ __parallel_unique_copy(_IIter __first, _IIter __last,
+ _OutputIterator __result)
{
- typedef typename std::iterator_traits<InputIterator>::value_type
- value_type;
- return parallel_unique_copy(first, last, result,
- std::equal_to<value_type>());
+ typedef typename std::iterator_traits<_IIter>::value_type
+ _ValueType;
+ return __parallel_unique_copy(__first, __last, __result,
+ std::equal_to<_ValueType>());
}
}//namespace __gnu_parallel
diff --git a/libstdc++-v3/include/parallel/workstealing.h b/libstdc++-v3/include/parallel/workstealing.h
index b82fe7cef98..ca6eb0cc4d3 100644
--- a/libstdc++-v3/include/parallel/workstealing.h
+++ b/libstdc++-v3/include/parallel/workstealing.h
@@ -49,257 +49,260 @@ namespace __gnu_parallel
#define _GLIBCXX_JOB_VOLATILE volatile
-/** @brief One job for a certain thread. */
+/** @brief One __job for a certain thread. */
template<typename _DifferenceTp>
- struct Job
+ struct _Job
{
- typedef _DifferenceTp difference_type;
+ typedef _DifferenceTp _DifferenceType;
/** @brief First element.
*
* Changed by owning and stealing thread. By stealing thread,
* always incremented. */
- _GLIBCXX_JOB_VOLATILE difference_type first;
+ _GLIBCXX_JOB_VOLATILE _DifferenceType _M_first;
/** @brief Last element.
*
* Changed by owning thread only. */
- _GLIBCXX_JOB_VOLATILE difference_type last;
+ _GLIBCXX_JOB_VOLATILE _DifferenceType _M_last;
- /** @brief Number of elements, i. e. @c last-first+1.
+ /** @brief Number of elements, i.e. @__c _M_last-_M_first+1.
*
* Changed by owning thread only. */
- _GLIBCXX_JOB_VOLATILE difference_type load;
+ _GLIBCXX_JOB_VOLATILE _DifferenceType _M_load;
};
/** @brief Work stealing algorithm for random access iterators.
*
- * Uses O(1) additional memory. Synchronization at job lists is
+ * Uses O(1) additional memory. Synchronization at __job lists is
* done with atomic operations.
- * @param begin Begin iterator of element sequence.
- * @param end End iterator of element sequence.
- * @param op User-supplied functor (comparator, predicate, adding
+ * @param __begin Begin iterator of element __sequence.
+ * @param __end End iterator of element __sequence.
+ * @param __op User-supplied functor (comparator, predicate, adding
* functor, ...).
- * @param f Functor to "process" an element with op (depends on
+ * @param __f Functor to "process" an element with __op (depends on
* desired functionality, e. g. for std::for_each(), ...).
- * @param r Functor to "add" a single result to the already
- * processed elements (depends on functionality).
- * @param base Base value for reduction.
- * @param output Pointer to position where final result is written to
- * @param bound Maximum number of elements processed (e. g. for
+ * @param __r Functor to "add" a single __result to the already
+ * processed __elements (depends on functionality).
+ * @param __base Base value for reduction.
+ * @param __output Pointer to position where final result is written to
+ * @param __bound Maximum number of elements processed (e. g. for
* std::count_n()).
* @return User-supplied functor (that may contain a part of the result).
*/
-template<typename RandomAccessIterator,
- typename Op,
- typename Fu,
- typename Red,
- typename Result>
- Op
- for_each_template_random_access_workstealing(RandomAccessIterator begin,
- RandomAccessIterator end,
- Op op, Fu& f, Red r,
- Result base, Result& output,
- typename std::iterator_traits
- <RandomAccessIterator>::
- difference_type bound)
+template<typename _RAIter,
+ typename _Op,
+ typename _Fu,
+ typename _Red,
+ typename _Result>
+ _Op
+ for_each_template_random_access_workstealing(
+ _RAIter __begin, _RAIter __end, _Op __op, _Fu& __f, _Red __r,
+ _Result __base, _Result& __output,
+ typename std::iterator_traits<_RAIter>::difference_type __bound)
{
- _GLIBCXX_CALL(end - begin)
+ _GLIBCXX_CALL(__end - __begin)
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::difference_type difference_type;
+ typedef std::iterator_traits<_RAIter> _TraitsType;
+ typedef typename _TraitsType::difference_type _DifferenceType;
const _Settings& __s = _Settings::get();
- difference_type chunk_size = static_cast<difference_type>(__s.workstealing_chunk_size);
+ _DifferenceType __chunk_size =
+ static_cast<_DifferenceType>(__s.workstealing_chunk_size);
// How many jobs?
- difference_type length = (bound < 0) ? (end - begin) : bound;
+ _DifferenceType __length = (__bound < 0) ? (__end - __begin) : __bound;
// To avoid false sharing in a cache line.
- const int stride = __s.cache_line_size * 10 / sizeof(Job<difference_type>) + 1;
+ const int __stride =
+ __s.cache_line_size * 10 / sizeof(_Job<_DifferenceType>) + 1;
// Total number of threads currently working.
- thread_index_t busy = 0;
+ _ThreadIndex __busy = 0;
- Job<difference_type> *job;
+ _Job<_DifferenceType> *__job;
- omp_lock_t output_lock;
- omp_init_lock(&output_lock);
+ omp_lock_t __output_lock;
+ omp_init_lock(&__output_lock);
// Write base value to output.
- output = base;
+ __output = __base;
// No more threads than jobs, at least one thread.
- thread_index_t num_threads =
- __gnu_parallel::max<thread_index_t>(1,
- __gnu_parallel::min<difference_type>(length, get_max_threads()));
+ _ThreadIndex __num_threads =
+ __gnu_parallel::max<_ThreadIndex>(1,
+ __gnu_parallel::min<_DifferenceType>(__length, __get_max_threads()));
-# pragma omp parallel shared(busy) num_threads(num_threads)
+# pragma omp parallel shared(__busy) num_threads(__num_threads)
{
# pragma omp single
{
- num_threads = omp_get_num_threads();
+ __num_threads = omp_get_num_threads();
// Create job description array.
- job = new Job<difference_type>[num_threads * stride];
+ __job = new _Job<_DifferenceType>[__num_threads * __stride];
}
// Initialization phase.
// Flags for every thread if it is doing productive work.
- bool iam_working = false;
+ bool __iam_working = false;
// Thread id.
- thread_index_t iam = omp_get_thread_num();
+ _ThreadIndex __iam = omp_get_thread_num();
// This job.
- Job<difference_type>& my_job = job[iam * stride];
+ _Job<_DifferenceType>& __my_job = __job[__iam * __stride];
// Random number (for work stealing).
- thread_index_t victim;
+ _ThreadIndex __victim;
// Local value for reduction.
- Result result = Result();
+ _Result __result = _Result();
// Number of elements to steal in one attempt.
- difference_type steal;
+ _DifferenceType __steal;
// Every thread has its own random number generator
- // (modulo num_threads).
- random_number rand_gen(iam, num_threads);
+ // (modulo __num_threads).
+ _RandomNumber rand_gen(__iam, __num_threads);
// This thread is currently working.
# pragma omp atomic
- ++busy;
+ ++__busy;
- iam_working = true;
+ __iam_working = true;
// How many jobs per thread? last thread gets the rest.
- my_job.first =
- static_cast<difference_type>(iam * (length / num_threads));
+ __my_job._M_first =
+ static_cast<_DifferenceType>(__iam * (__length / __num_threads));
- my_job.last = (iam == (num_threads - 1)) ?
- (length - 1) : ((iam + 1) * (length / num_threads) - 1);
- my_job.load = my_job.last - my_job.first + 1;
+ __my_job._M_last = (__iam == (__num_threads - 1)) ?
+ (__length - 1) : ((__iam + 1) * (__length / __num_threads) - 1);
+ __my_job._M_load = __my_job._M_last - __my_job._M_first + 1;
- // Init result with first value (to have a base value for reduction).
- if (my_job.first <= my_job.last)
+ // Init result with _M_first value (to have a base value for reduction)
+ if (__my_job._M_first <= __my_job._M_last)
{
// Cannot use volatile variable directly.
- difference_type my_first = my_job.first;
- result = f(op, begin + my_first);
- ++my_job.first;
- --my_job.load;
+ _DifferenceType __my_first = __my_job._M_first;
+ __result = __f(__op, __begin + __my_first);
+ ++__my_job._M_first;
+ --__my_job._M_load;
}
- RandomAccessIterator current;
+ _RAIter __current;
# pragma omp barrier
// Actual work phase
- // Work on own or stolen start
- while (busy > 0)
+ // Work on own or stolen current start
+ while (__busy > 0)
{
// Work until no productive thread left.
-# pragma omp flush(busy)
+# pragma omp flush(__busy)
// Thread has own work to do
- while (my_job.first <= my_job.last)
+ while (__my_job._M_first <= __my_job._M_last)
{
// fetch-and-add call
- // Reserve current job block (size chunk_size) in my queue.
- difference_type current_job =
- fetch_and_add<difference_type>(&(my_job.first), chunk_size);
-
- // Update load, to make the three values consistent,
- // first might have been changed in the meantime
- my_job.load = my_job.last - my_job.first + 1;
- for (difference_type job_counter = 0;
- job_counter < chunk_size && current_job <= my_job.last;
+ // Reserve current job block (size __chunk_size) in my queue.
+ _DifferenceType current_job =
+ __fetch_and_add<_DifferenceType>(
+ &(__my_job._M_first), __chunk_size);
+
+ // Update _M_load, to make the three values consistent,
+ // _M_first might have been changed in the meantime
+ __my_job._M_load = __my_job._M_last - __my_job._M_first + 1;
+ for (_DifferenceType job_counter = 0;
+ job_counter < __chunk_size
+ && current_job <= __my_job._M_last;
++job_counter)
{
// Yes: process it!
- current = begin + current_job;
+ __current = __begin + current_job;
++current_job;
// Do actual work.
- result = r(result, f(op, current));
+ __result = __r(__result, __f(__op, __current));
}
-# pragma omp flush(busy)
+# pragma omp flush(__busy)
}
- // After reaching this point, a thread's job list is empty.
- if (iam_working)
+ // After reaching this point, a thread's __job list is empty.
+ if (__iam_working)
{
// This thread no longer has work.
# pragma omp atomic
- --busy;
+ --__busy;
- iam_working = false;
+ __iam_working = false;
}
- difference_type supposed_first, supposed_last, supposed_load;
+ _DifferenceType __supposed_first, __supposed_last, __supposed_load;
do
{
// Find random nonempty deque (not own), do consistency check.
- yield();
-# pragma omp flush(busy)
- victim = rand_gen();
- supposed_first = job[victim * stride].first;
- supposed_last = job[victim * stride].last;
- supposed_load = job[victim * stride].load;
+ __yield();
+# pragma omp flush(__busy)
+ __victim = rand_gen();
+ __supposed_first = __job[__victim * __stride]._M_first;
+ __supposed_last = __job[__victim * __stride]._M_last;
+ __supposed_load = __job[__victim * __stride]._M_load;
}
- while (busy > 0
- && ((supposed_load <= 0)
- || ((supposed_first + supposed_load - 1) != supposed_last)));
+ while (__busy > 0
+ && ((__supposed_load <= 0)
+ || ((__supposed_first + __supposed_load - 1)
+ != __supposed_last)));
- if (busy == 0)
+ if (__busy == 0)
break;
- if (supposed_load > 0)
+ if (__supposed_load > 0)
{
// Has work and work to do.
// Number of elements to steal (at least one).
- steal = (supposed_load < 2) ? 1 : supposed_load / 2;
+ __steal = (__supposed_load < 2) ? 1 : __supposed_load / 2;
- // Push victim's start forward.
- difference_type stolen_first =
- fetch_and_add<difference_type>(
- &(job[victim * stride].first), steal);
- difference_type stolen_try =
- stolen_first + steal - difference_type(1);
+ // Push __victim's current start forward.
+ _DifferenceType __stolen_first =
+ __fetch_and_add<_DifferenceType>(
+ &(__job[__victim * __stride]._M_first), __steal);
+ _DifferenceType stolen_try =
+ __stolen_first + __steal - _DifferenceType(1);
- my_job.first = stolen_first;
- my_job.last = __gnu_parallel::min(stolen_try, supposed_last);
- my_job.load = my_job.last - my_job.first + 1;
+ __my_job._M_first = __stolen_first;
+ __my_job._M_last =
+ __gnu_parallel::min(stolen_try, __supposed_last);
+ __my_job._M_load = __my_job._M_last - __my_job._M_first + 1;
// Has potential work again.
# pragma omp atomic
- ++busy;
- iam_working = true;
+ ++__busy;
+ __iam_working = true;
-# pragma omp flush(busy)
+# pragma omp flush(__busy)
}
-# pragma omp flush(busy)
- } // end while busy > 0
+# pragma omp flush(__busy)
+ } // end while __busy > 0
// Add accumulated result to output.
- omp_set_lock(&output_lock);
- output = r(output, result);
- omp_unset_lock(&output_lock);
+ omp_set_lock(&__output_lock);
+ __output = __r(__output, __result);
+ omp_unset_lock(&__output_lock);
}
- delete[] job;
+ delete[] __job;
// Points to last element processed (needed as return value for
// some algorithms like transform)
- f.finish_iterator = begin + length;
+ __f._M_finish_iterator = __begin + __length;
- omp_destroy_lock(&output_lock);
+ omp_destroy_lock(&__output_lock);
- return op;
+ return __op;
}
} // end namespace
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 54d521825c4..9513bd52dbf 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -209,6 +209,8 @@ libstdc___la_DEPENDENCIES = \
libstdc___la_LDFLAGS = \
-version-info $(libtool_VERSION) ${version_arg} -lm
+libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS)
+
# Use special rules for the deprecated source files so that they find
# deprecated include files.
GLIBCXX_INCLUDE_DIR=$(glibcxx_builddir)/include
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index e484d86e130..9c03ac4dc78 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -129,9 +129,6 @@ am__objects_5 = atomic.lo bitmap_allocator.lo pool_allocator.lo \
thread.lo future.lo $(am__objects_1) $(am__objects_4)
am_libstdc___la_OBJECTS = $(am__objects_5)
libstdc___la_OBJECTS = $(am_libstdc___la_OBJECTS)
-libstdc___la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
- $(CXXFLAGS) $(libstdc___la_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp =
am__depfiles_maybe =
@@ -450,6 +447,7 @@ libstdc___la_DEPENDENCIES = \
libstdc___la_LDFLAGS = \
-version-info $(libtool_VERSION) ${version_arg} -lm
+libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS)
# Use special rules for the deprecated source files so that they find
# deprecated include files.
diff --git a/libstdc++-v3/src/compatibility.cc b/libstdc++-v3/src/compatibility.cc
index 53d8e84e4f2..c81f08e070f 100644
--- a/libstdc++-v3/src/compatibility.cc
+++ b/libstdc++-v3/src/compatibility.cc
@@ -62,7 +62,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_gcount = 0;
sentry __cerb(*this, true);
- if (__n > 0 && static_cast<bool>(__cerb))
+ if ( __n > 0 && __cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -134,7 +134,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_gcount = 0;
sentry __cerb(*this, true);
- if (__n > 0 && static_cast<bool>(__cerb))
+ if (__n > 0 && __cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
diff --git a/libstdc++-v3/src/ios_init.cc b/libstdc++-v3/src/ios_init.cc
index 5c53bcae822..1885d825971 100644
--- a/libstdc++-v3/src/ios_init.cc
+++ b/libstdc++-v3/src/ios_init.cc
@@ -93,7 +93,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
new (&cerr) ostream(&buf_cerr_sync);
new (&clog) ostream(&buf_cerr_sync);
cin.tie(&cout);
- cerr.flags(ios_base::unitbuf);
+ cerr.setf(ios_base::unitbuf);
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 455. cerr::tie() and wcerr::tie() are overspecified.
cerr.tie(&cout);
@@ -108,7 +108,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
new (&wcerr) wostream(&buf_wcerr_sync);
new (&wclog) wostream(&buf_wcerr_sync);
wcin.tie(&wcout);
- wcerr.flags(ios_base::unitbuf);
+ wcerr.setf(ios_base::unitbuf);
wcerr.tie(&wcout);
#endif
diff --git a/libstdc++-v3/src/istream.cc b/libstdc++-v3/src/istream.cc
index 0e7cbfb9084..e4102779aa8 100644
--- a/libstdc++-v3/src/istream.cc
+++ b/libstdc++-v3/src/istream.cc
@@ -39,7 +39,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_gcount = 0;
ios_base::iostate __err = ios_base::goodbit;
sentry __cerb(*this, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
@@ -116,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_gcount = 0;
sentry __cerb(*this, true);
- if (__n > 0 && static_cast<bool>(__cerb))
+ if (__n > 0 && __cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
@@ -205,7 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
streamsize __extracted = 0;
ios_base::iostate __err = ios_base::goodbit;
__istream_type::sentry __cerb(__in, false);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
@@ -288,7 +288,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__size_type __extracted = 0;
ios_base::iostate __err = ios_base::goodbit;
__istream_type::sentry __cerb(__in, false);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
@@ -370,7 +370,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const __size_type __n = __str.max_size();
ios_base::iostate __err = ios_base::goodbit;
__istream_type::sentry __cerb(__in, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
@@ -446,7 +446,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_gcount = 0;
ios_base::iostate __err = ios_base::goodbit;
sentry __cerb(*this, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
@@ -523,12 +523,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_gcount = 0;
sentry __cerb(*this, true);
- if (__n > 0 && static_cast<bool>(__cerb))
+ if (__n > 0 && __cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
{
- const char_type __cdelim = traits_type::to_char_type(__delim);
+ const char_type __cdelim = traits_type::to_char_type(__delim);
const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf();
int_type __c = __sb->sgetc();
@@ -616,7 +616,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const __size_type __n = __str.max_size();
ios_base::iostate __err = ios_base::goodbit;
__istream_type::sentry __cerb(__in, true);
- if (static_cast<bool>(__cerb))
+ if (__cerb)
{
__try
{
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc
index 93f0e6d591d..5062ddfa234 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc
@@ -1,6 +1,6 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
-// { dg-error "no matching" "" { target *-*-* } 1209 }
+// { dg-error "no matching" "" { target *-*-* } 1198 }
// { dg-excess-errors "" }
// Copyright (C) 2009 Free Software Foundation
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc
index 70d0447a5d6..6347d964a46 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc
@@ -1,6 +1,6 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
-// { dg-error "no matching" "" { target *-*-* } 1209 }
+// { dg-error "no matching" "" { target *-*-* } 1198 }
// { dg-excess-errors "" }
// Copyright (C) 2009 Free Software Foundation
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc
index 2ee8b9f6baf..af668527dfb 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc
@@ -1,6 +1,6 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
-// { dg-error "no matching" "" { target *-*-* } 1209 }
+// { dg-error "no matching" "" { target *-*-* } 1198 }
// { dg-excess-errors "" }
// Copyright (C) 2009 Free Software Foundation
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc
index a21c22242b3..bc8a62d54ab 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc
@@ -1,6 +1,6 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
-// { dg-error "no matching" "" { target *-*-* } 1209 }
+// { dg-error "no matching" "" { target *-*-* } 1198 }
// { dg-excess-errors "" }
// Copyright (C) 2009 Free Software Foundation
diff --git a/libstdc++-v3/testsuite/27_io/objects/char/41037.cc b/libstdc++-v3/testsuite/27_io/objects/char/41037.cc
new file mode 100644
index 00000000000..a38221cab6e
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/objects/char/41037.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2009 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 3, 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 COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <iostream>
+#include <testsuite_hooks.h>
+
+// PR libstdc++/41037
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ VERIFY( std::cerr.flags() & std::ios_base::dec );
+ VERIFY( std::cerr.flags() & std::ios_base::skipws );
+ VERIFY( std::cerr.flags() & std::ios_base::unitbuf );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/41037.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/41037.cc
new file mode 100644
index 00000000000..b3c01a0b7dc
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/41037.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2009 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 3, 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 COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <iostream>
+#include <testsuite_hooks.h>
+
+// PR libstdc++/41037
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ VERIFY( std::wcerr.flags() & std::ios_base::dec );
+ VERIFY( std::wcerr.flags() & std::ios_base::skipws );
+ VERIFY( std::wcerr.flags() & std::ios_base::unitbuf );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/thread/native_handle/typesizes.cc b/libstdc++-v3/testsuite/30_threads/thread/native_handle/typesizes.cc
index 8f9b1933bfc..ffc0e40f630 100644
--- a/libstdc++-v3/testsuite/30_threads/thread/native_handle/typesizes.cc
+++ b/libstdc++-v3/testsuite/30_threads/thread/native_handle/typesizes.cc
@@ -1,5 +1,5 @@
-// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } }
-// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-do run { target *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } }
+// { dg-options " -std=gnu++0x -pthread" { target *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } }
// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } }
// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } }
// { dg-require-cstdint "" }
diff --git a/libtool.m4 b/libtool.m4
index c17514b9260..12d45a5a8a5 100644
--- a/libtool.m4
+++ b/libtool.m4
@@ -5471,7 +5471,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
GXX=no
@@ -5716,7 +5716,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "^ .* -L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
;;
*)
if test "$GXX" = yes; then
@@ -5781,7 +5781,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "^ .* -L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
;;
*)
if test "$GXX" = yes; then
@@ -6125,7 +6125,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
# FIXME: insert proper C++ library support
@@ -6209,7 +6209,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
else
# g++ 2.7 appears to require `-G' NOT `-shared' on this
# platform.
@@ -6220,7 +6220,7 @@ if test "$_lt_caught_CXX_error" != yes; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "^ .* -L"'
fi
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'