aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2007-10-09 06:48:34 +0000
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2007-10-09 06:48:34 +0000
commit8694f844c271b560d429dca7860b0d03b86045bc (patch)
tree0ec790a1917467c841e7ebe62e38e8c206caf5d2
parent7be7e70ae29a26c871e95386d1407491f671a0bf (diff)
Merging trunk 128923..129153 into var-tracking-assignments branch.var-tracking-assignments-merge-129153-after
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/var-tracking-assignments-branch@129158 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog12
-rw-r--r--MAINTAINERS1
-rw-r--r--config/ChangeLog14
-rw-r--r--config/no-executables.m48
-rwxr-xr-xconfigure8
-rw-r--r--configure.ac8
-rw-r--r--contrib/ChangeLog5
-rwxr-xr-xcontrib/texi2pod.pl15
-rw-r--r--gcc/ChangeLog447
-rw-r--r--gcc/ChangeLog.vta20
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in10
-rw-r--r--gcc/ada/ChangeLog19
-rw-r--r--gcc/ada/Makefile.in9
-rw-r--r--gcc/ada/misc.c14
-rw-r--r--gcc/ada/system-linux-ppc64.ads153
-rw-r--r--gcc/basic-block.h15
-rw-r--r--gcc/cgraphunit.c18
-rw-r--r--gcc/combine.c10
-rw-r--r--gcc/config.gcc14
-rw-r--r--gcc/config/avr/avr.c89
-rw-r--r--gcc/config/darwin.h3
-rw-r--r--gcc/config/m68k/m68k.c32
-rw-r--r--gcc/config/m68k/m68k.h20
-rw-r--r--gcc/config/m68k/m68k.md73
-rw-r--r--gcc/config/mips/mips-protos.h2
-rw-r--r--gcc/config/mips/mips.c169
-rw-r--r--gcc/config/mips/mips.h2
-rw-r--r--gcc/config/mips/mips.md172
-rw-r--r--gcc/config/rs6000/paired.md21
-rw-r--r--gcc/config/rs6000/predicates.md5
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.c53
-rw-r--r--gcc/cp/ChangeLog39
-rw-r--r--gcc/cp/call.c6
-rw-r--r--gcc/cp/cp-objcp-common.h2
-rw-r--r--gcc/cp/decl.c127
-rw-r--r--gcc/cp/expr.c3
-rw-r--r--gcc/cp/mangle.c4
-rw-r--r--gcc/cp/name-lookup.c94
-rw-r--r--gcc/cp/name-lookup.h8
-rw-r--r--gcc/cp/parser.c12
-rw-r--r--gcc/cp/typeck2.c19
-rw-r--r--gcc/dce.c6
-rw-r--r--gcc/df-problems.c757
-rw-r--r--gcc/df-scan.c72
-rw-r--r--gcc/df.h141
-rw-r--r--gcc/doc/invoke.texi57
-rw-r--r--gcc/dse.c2
-rw-r--r--gcc/dwarf2out.c7
-rw-r--r--gcc/expr.c10
-rw-r--r--gcc/fold-const.c51
-rw-r--r--gcc/fortran/ChangeLog180
-rw-r--r--gcc/fortran/Make-lang.in3
-rw-r--r--gcc/fortran/data.c1
-rw-r--r--gcc/fortran/data.h24
-rw-r--r--gcc/fortran/decl.c247
-rw-r--r--gcc/fortran/expr.c21
-rw-r--r--gcc/fortran/gfortran.h16
-rw-r--r--gcc/fortran/match.h3
-rw-r--r--gcc/fortran/mathbuiltins.def2
-rw-r--r--gcc/fortran/options.c4
-rw-r--r--gcc/fortran/parse.c73
-rw-r--r--gcc/fortran/parse.h2
-rw-r--r--gcc/fortran/primary.c13
-rw-r--r--gcc/fortran/resolve.c546
-rw-r--r--gcc/fortran/scanner.c61
-rw-r--r--gcc/fortran/simplify.c5
-rw-r--r--gcc/fortran/trans-array.c17
-rw-r--r--gcc/fortran/trans-decl.c70
-rw-r--r--gcc/fortran/trans-intrinsic.c7
-rw-r--r--gcc/fortran/trans.h4
-rw-r--r--gcc/function.c2
-rw-r--r--gcc/global.c1523
-rw-r--r--gcc/gthr-posix.h33
-rw-r--r--gcc/gthr-posix95.h29
-rw-r--r--gcc/gthr.h18
-rw-r--r--gcc/hard-reg-set.h2
-rw-r--r--gcc/init-regs.c6
-rw-r--r--gcc/java/ChangeLog8
-rw-r--r--gcc/java/class.c57
-rw-r--r--gcc/lambda-code.c5
-rw-r--r--gcc/lambda.h2
-rw-r--r--gcc/langhooks-def.h3
-rw-r--r--gcc/langhooks.c8
-rw-r--r--gcc/langhooks.h5
-rw-r--r--gcc/local-alloc.c88
-rw-r--r--gcc/lower-subreg.c2
-rw-r--r--gcc/passes.c1
-rw-r--r--gcc/ra-conflict.c1228
-rw-r--r--gcc/ra.h223
-rw-r--r--gcc/reload.c4
-rw-r--r--gcc/reload1.c7
-rw-r--r--gcc/rtl.h2
-rw-r--r--gcc/rtlanal.c12
-rw-r--r--gcc/simplify-rtx.c11
-rw-r--r--gcc/sparseset.c232
-rw-r--r--gcc/sparseset.h162
-rw-r--r--gcc/testsuite/ChangeLog269
-rw-r--r--gcc/testsuite/g++.dg/debug/using3.C8
-rw-r--r--gcc/testsuite/g++.dg/eh/init-temp1.C44
-rw-r--r--gcc/testsuite/g++.dg/ext/gnu-inline-global-redecl.C19
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/namespace2.C20
-rw-r--r--gcc/testsuite/g++.dg/init/ref15.C32
-rw-r--r--gcc/testsuite/g++.dg/torture/pr33572.C17
-rw-r--r--gcc/testsuite/g++.dg/torture/pr33627.C57
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/obj-type-ref.C19
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr33617.c7
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr33641.c12
-rw-r--r--gcc/testsuite/gcc.dg/float-range-3.c12
-rw-r--r--gcc/testsuite/gcc.dg/float-range-4.c12
-rw-r--r--gcc/testsuite/gcc.dg/float-range-5.c12
-rw-r--r--gcc/testsuite/gcc.dg/pr33653.c10
-rw-r--r--gcc/testsuite/gcc.dg/pr33666.c11
-rw-r--r--gcc/testsuite/gcc.dg/pr33667.c21
-rw-r--r--gcc/testsuite/gcc.dg/pr33691.c8
-rw-r--r--gcc/testsuite/gcc.dg/pr33693.c8
-rw-r--r--gcc/testsuite/gcc.dg/pr33694.c8
-rw-r--r--gcc/testsuite/gcc.dg/pr33695.c8
-rw-r--r--gcc/testsuite/gcc.dg/pr33696.c13
-rw-r--r--gcc/testsuite/gcc.dg/pr33697.c10
-rw-r--r--gcc/testsuite/gcc.dg/pragma-darwin-2.c24
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr33655.c14
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr33576.c20
-rw-r--r--gcc/testsuite/gcc.target/i386/pr33600.c10
-rw-r--r--gcc/testsuite/gcc.target/mips/fpr-moves-1.c26
-rw-r--r--gcc/testsuite/gcc.target/mips/fpr-moves-2.c26
-rw-r--r--gcc/testsuite/gcc.target/mips/fpr-moves-3.c18
-rw-r--r--gcc/testsuite/gcc.target/mips/fpr-moves-4.c18
-rw-r--r--gcc/testsuite/gcc.target/mips/fpr-moves-5.c33
-rw-r--r--gcc/testsuite/gcc.target/mips/fpr-moves-6.c34
-rw-r--r--gcc/testsuite/gcc.target/mips/mips.exp105
-rw-r--r--gcc/testsuite/gcc.target/mips/mips32r2-mxhc1.c2
-rw-r--r--gcc/testsuite/gcc.target/mips/pr33256.c2
-rw-r--r--gcc/testsuite/gcc.target/mips/pr33635-1.c13
-rw-r--r--gcc/testsuite/gcc.target/mips/save-restore-1.c2
-rw-r--r--gcc/testsuite/gcc.target/mips/save-restore-2.c2
-rw-r--r--gcc/testsuite/gcc.target/mips/save-restore-3.c2
-rw-r--r--gcc/testsuite/gcc.target/mips/save-restore-4.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/paired-10.c25
-rw-r--r--gcc/testsuite/gcc.target/powerpc/paired-8.c25
-rw-r--r--gcc/testsuite/gcc.target/powerpc/paired-9.c25
-rw-r--r--gcc/testsuite/gcc.target/powerpc/stabs-attrib-vect-darwin.c2
-rw-r--r--gcc/testsuite/gfortran.dg/ambiguous_reference_1.f9050
-rw-r--r--gcc/testsuite/gfortran.dg/char_decl_2.f904
-rw-r--r--gcc/testsuite/gfortran.dg/char_length_2.f902
-rw-r--r--gcc/testsuite/gfortran.dg/char_type_len_2.f908
-rw-r--r--gcc/testsuite/gfortran.dg/common_errors_1.f9038
-rw-r--r--gcc/testsuite/gfortran.dg/default_format_1.f9029
-rw-r--r--gcc/testsuite/gfortran.dg/default_format_1.inc74
-rw-r--r--gcc/testsuite/gfortran.dg/default_format_2.f9023
-rw-r--r--gcc/testsuite/gfortran.dg/default_format_2.inc43
-rw-r--r--gcc/testsuite/gfortran.dg/default_format_denormal_1.f9021
-rw-r--r--gcc/testsuite/gfortran.dg/default_format_denormal_2.f9019
-rw-r--r--gcc/testsuite/gfortran.dg/derived_comp_array_ref_5.f9036
-rw-r--r--gcc/testsuite/gfortran.dg/derived_function_interface_1.f9013
-rw-r--r--gcc/testsuite/gfortran.dg/error_recovery_4.f905
-rw-r--r--gcc/testsuite/gfortran.dg/forall_11.f9033
-rw-r--r--gcc/testsuite/gfortran.dg/function_kinds_1.f9054
-rw-r--r--gcc/testsuite/gfortran.dg/function_kinds_2.f9021
-rw-r--r--gcc/testsuite/gfortran.dg/gamma_5.f9042
-rw-r--r--gcc/testsuite/gfortran.dg/initialization_1.f904
-rw-r--r--gcc/testsuite/gfortran.dg/initialization_14.f9045
-rw-r--r--gcc/testsuite/gfortran.dg/initialization_7.f902
-rw-r--r--gcc/testsuite/gfortran.dg/initialization_9.f902
-rw-r--r--gcc/testsuite/gfortran.dg/intent_out_2.f9047
-rw-r--r--gcc/testsuite/gfortran.dg/namelist_15.f9018
-rw-r--r--gcc/testsuite/gfortran.dg/namelist_38.f9036
-rw-r--r--gcc/testsuite/gfortran.dg/namelist_39.f9029
-rw-r--r--gcc/testsuite/gfortran.dg/namelist_print_1.f2
-rw-r--r--gcc/testsuite/gfortran.dg/parens_6.f9011
-rw-r--r--gcc/testsuite/gfortran.dg/pr33646.f9059
-rw-r--r--gcc/testsuite/gfortran.dg/real_const_3.f9024
-rw-r--r--gcc/testsuite/gfortran.dg/repeat_2.f904
-rw-r--r--gcc/testsuite/gfortran.dg/repeat_4.f904
-rw-r--r--gcc/testsuite/gfortran.dg/spec_expr_5.f908
-rw-r--r--gcc/testsuite/gfortran.dg/zero_length_2.f902
-rw-r--r--gcc/tree-cfg.c43
-rw-r--r--gcc/tree-eh.c156
-rw-r--r--gcc/tree-gimple.c44
-rw-r--r--gcc/tree-gimple.h1
-rw-r--r--gcc/tree-inline.c11
-rw-r--r--gcc/tree-loop-linear.c8
-rw-r--r--gcc/tree-pass.h1
-rw-r--r--gcc/tree-sra.c48
-rw-r--r--gcc/tree-ssa-forwprop.c42
-rw-r--r--gcc/tree-ssa-ifcombine.c3
-rw-r--r--gcc/tree-ssa-ter.c2
-rw-r--r--gcc/tree.h3
-rw-r--r--gcc/varasm.c37
-rw-r--r--libgfortran/ChangeLog29
-rw-r--r--libgfortran/io/list_read.c47
-rw-r--r--libgfortran/io/write.c12
-rw-r--r--libgfortran/libgfortran.h8
-rw-r--r--libgfortran/runtime/environ.c137
-rw-r--r--libstdc++-v3/ChangeLog478
-rw-r--r--libstdc++-v3/acinclude.m4197
-rwxr-xr-xlibstdc++-v3/configure553
-rw-r--r--libstdc++-v3/docs/html/parallel_mode.html172
-rw-r--r--libstdc++-v3/include/Makefile.am1
-rw-r--r--libstdc++-v3/include/Makefile.in1
-rw-r--r--libstdc++-v3/include/bits/algorithmfwd.h18
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h102
-rw-r--r--libstdc++-v3/include/bits/stl_algobase.h22
-rw-r--r--libstdc++-v3/include/bits/stl_bvector.h37
-rw-r--r--libstdc++-v3/include/bits/stl_deque.h76
-rw-r--r--libstdc++-v3/include/bits/stl_iterator.h169
-rw-r--r--libstdc++-v3/include/bits/stl_list.h67
-rw-r--r--libstdc++-v3/include/bits/stl_map.h103
-rw-r--r--libstdc++-v3/include/bits/stl_move.h67
-rw-r--r--libstdc++-v3/include/bits/stl_multimap.h95
-rw-r--r--libstdc++-v3/include/bits/stl_multiset.h98
-rw-r--r--libstdc++-v3/include/bits/stl_pair.h16
-rw-r--r--libstdc++-v3/include/bits/stl_set.h107
-rw-r--r--libstdc++-v3/include/bits/stl_tree.h65
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h72
-rw-r--r--libstdc++-v3/include/debug/debug.h18
-rw-r--r--libstdc++-v3/include/debug/deque52
-rw-r--r--libstdc++-v3/include/debug/functions.h38
-rw-r--r--libstdc++-v3/include/debug/list58
-rw-r--r--libstdc++-v3/include/debug/macros.h29
-rw-r--r--libstdc++-v3/include/debug/map.h98
-rw-r--r--libstdc++-v3/include/debug/multimap.h101
-rw-r--r--libstdc++-v3/include/debug/multiset.h75
-rw-r--r--libstdc++-v3/include/debug/set.h77
-rw-r--r--libstdc++-v3/include/debug/vector45
-rw-r--r--libstdc++-v3/include/ext/concurrence.h104
-rw-r--r--libstdc++-v3/include/ext/rc_string_base.h1
-rw-r--r--libstdc++-v3/include/ext/vstring_util.h2
-rw-r--r--libstdc++-v3/include/parallel/algo.h904
-rw-r--r--libstdc++-v3/include/parallel/algobase.h89
-rw-r--r--libstdc++-v3/include/parallel/algorithmfwd.h658
-rw-r--r--libstdc++-v3/include/parallel/balanced_quicksort.h8
-rw-r--r--libstdc++-v3/include/parallel/base.h63
-rw-r--r--libstdc++-v3/include/parallel/for_each_selectors.h4
-rw-r--r--libstdc++-v3/include/parallel/multiseq_selection.h7
-rw-r--r--libstdc++-v3/include/parallel/multiway_merge.h7
-rw-r--r--libstdc++-v3/include/parallel/numeric213
-rw-r--r--libstdc++-v3/include/parallel/numericfwd.h80
-rw-r--r--libstdc++-v3/include/parallel/partial_sum.h20
-rw-r--r--libstdc++-v3/include/parallel/partition.h8
-rw-r--r--libstdc++-v3/include/parallel/random_shuffle.h33
-rw-r--r--libstdc++-v3/include/parallel/search.h5
-rw-r--r--libstdc++-v3/include/parallel/tags.h9
-rw-r--r--libstdc++-v3/include/parallel/tree.h230
-rw-r--r--libstdc++-v3/include/parallel/workstealing.h7
-rw-r--r--libstdc++-v3/include/std/utility24
-rw-r--r--libstdc++-v3/include/tr1/functional1
-rw-r--r--libstdc++-v3/libsupc++/guard.cc192
-rw-r--r--libstdc++-v3/libsupc++/typeinfo14
-rw-r--r--libstdc++-v3/testsuite/20_util/pair/moveable.cc72
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/capacity/moveable.cc82
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/cons/moveable.cc65
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/modifiers/moveable.cc144
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/moveable.cc51
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/moveable.cc51
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/moveable.cc52
-rw-r--r--libstdc++-v3/testsuite/23_containers/multimap/moveable.cc52
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/moveable.cc52
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/moveable.cc52
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/cons/moveable.cc65
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable.cc147
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/moveable.cc71
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/resize/moveable.cc85
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/binary_search/2.cc122
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/binary_search/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/count_if/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/equal/no_operator_ne.cc (renamed from libstdc++-v3/testsuite/25_algorithms/equal/equal.cc)0
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/equal_range/2.cc90
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/equal_range/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/find_end/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/find_first_of/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/find_if/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/for_each/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/heap/1.cc (renamed from libstdc++-v3/testsuite/25_algorithms/heap/heap.cc)0
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/heap/moveable.cc120
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/includes/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/inplace_merge/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/lexicographical_compare/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/lower_bound/2.cc81
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/lower_bound/33613.cc36
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/lower_bound/no_operator_ne.cc (renamed from libstdc++-v3/testsuite/25_algorithms/lower_bound/lower_bound.cc)0
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/lower_bound/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/make_heap/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/max/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/max_element/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/merge/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/min/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/min_element/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/next_permutation/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/nth_element/moveable.cc76
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/nth_element/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/partial_sort/moveable.cc70
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/partial_sort/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/partial_sort_copy/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/partition/1.cc (renamed from libstdc++-v3/testsuite/25_algorithms/partition/partition.cc)15
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/partition/moveable.cc89
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/partition/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pop_heap/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/prev_permutation/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/push_heap/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/random_shuffle/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/remove/moveable.cc67
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/remove/requirements/explicit_instantiation/pod.cc3
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/remove_copy_if/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/remove_if/moveable.cc67
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/remove_if/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/replace_copy_if/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/replace_if/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/reverse/moveable.cc44
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/rotate/moveable.cc78
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/search/1.cc50
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/search/check_type.cc37
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/search/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/search_n/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/set_difference/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/set_intersection/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/set_symmetric_difference/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/set_union/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/sort/moveable.cc64
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/sort/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/sort/vectorbool.cc44
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/sort_heap/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/stable_partition/1.cc56
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/stable_partition/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/stable_sort/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/swap_ranges/moveable.cc44
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/transform/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/unique/moveable.cc73
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/unique/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/unique_copy/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/upper_bound/2.cc81
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/upper_bound/33613.cc36
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/upper_bound/requirements/explicit_instantiation/2.cc1
-rw-r--r--libstdc++-v3/testsuite/26_numerics/accumulate/1.cc54
-rw-r--r--libstdc++-v3/testsuite/26_numerics/inner_product/1.cc56
-rw-r--r--libstdc++-v3/testsuite/lib/dg-options.exp9
-rw-r--r--libstdc++-v3/testsuite/lib/libstdc++.exp85
-rw-r--r--libstdc++-v3/testsuite/thread/guard.cc67
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_api.h1
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_rvalref.h194
353 files changed, 14302 insertions, 4850 deletions
diff --git a/ChangeLog b/ChangeLog
index a93fa2c46aa..3c88e364b66 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2007-10-08 Mike Frysinger <vapier@gentoo.org>
+
+ * configure.ac (CFLAGS_FOR_BUILD, CXXFLAGS_FOR_BUILD,
+ LDFLAGS_FOR_BUILD): Default them to host flags only for $host = $build.
+ Set default CXXFLAGS_FOR_BUILD to CXXFLAGS, not CFLAGS. Set default
+ LDFLAGS_FOR_BUILD to LDFLAGS, not CFLAGS.
+ * configure: Regenerate.
+
+2006-10-04 Seongbae Park <seongbae.park@gmail.com>
+
+ * MAINTAINERS (Register allocation reviewer): Add myself.
+
2007-10-01 Paolo Bonzini <bonzini@gnu.org>
* Makefile.tpl (AR_FOR_BUILD, AS_FOR_BUILD, CXX_FOR_BUILD,
diff --git a/MAINTAINERS b/MAINTAINERS
index da17e67b586..3eab1b544d8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -252,6 +252,7 @@ Fortran Tobias Schlüter tobias.schlueter@physik.uni-muenchen.de
Fortran Paul Thomas pault@gcc.gnu.org
register allocation Peter Bergner bergner@vnet.ibm.com
register allocation Kenneth Zadeck zadeck@naturalbridge.com
+register allocation Seongbae Park seongbae.park@gmail.com
Note that while reviewers can approve changes to parts of the compiler
that they maintain, they still need approval for their own patches
diff --git a/config/ChangeLog b/config/ChangeLog
index f3d9fe98d70..d1ee4bc7cb8 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,17 @@
+2007-10-03 Richard Sandiford <richard@codesourcery.com>
+
+ * no-executables.m4 (GCC_TRY_COMPILE_OR_LINK): New function.
+
+2007-10-03 Kazu Hirata <kazu@codesourcery.com>
+
+ Revert:
+ 2007-10-02 Richard Sandiford <richard@codesourcery.com>
+ * no-executables.m4 (GCC_TRY_COMPILE_OR_LINK): New function.
+
+2007-10-02 Richard Sandiford <richard@codesourcery.com>
+
+ * no-executables.m4 (GCC_TRY_COMPILE_OR_LINK): New function.
+
2007-09-21 Richard Sandiford <rsandifo@nildram.co.uk>
* mt-sde (CFLAGS_FOR_TARGET): Replace -fno-optimize-sibling-calls
diff --git a/config/no-executables.m4 b/config/no-executables.m4
index 54e5a024288..c4d0b70c375 100644
--- a/config/no-executables.m4
+++ b/config/no-executables.m4
@@ -59,3 +59,11 @@ fi)
m4_divert_pop()dnl
])# GCC_NO_EXECUTABLES
+
+# Use the strongest available test out of AC_TRY_COMPILE and AC_TRY_LINK.
+AC_DEFUN([GCC_TRY_COMPILE_OR_LINK],
+[if test x$gcc_no_link = xyes; then
+ AC_TRY_COMPILE([$1], [$2], [$3], [$4])
+else
+ AC_TRY_LINK([$1], [$2], [$3], [$4])
+fi])
diff --git a/configure b/configure
index 3d4545102f6..d8afdf2b4d7 100755
--- a/configure
+++ b/configure
@@ -5876,9 +5876,11 @@ esac
# Allow the user to override the flags for
# our build compiler if desired.
-CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-${CFLAGS}}
-CXXFLAGS_FOR_BUILD=${CXXFLAGS_FOR_BUILD-${CFLAGS}}
-LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-${CFLAGS}}
+if test x"${build}" = x"${host}" ; then
+ CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-${CFLAGS}}
+ CXXFLAGS_FOR_BUILD=${CXXFLAGS_FOR_BUILD-${CXXFLAGS}}
+ LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-${LDFLAGS}}
+fi
# On Canadian crosses, we'll be searching the right directories for
# the previously-installed cross compiler, so don't bother to add
diff --git a/configure.ac b/configure.ac
index e1cce0746e2..da6adf1e6b8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2387,9 +2387,11 @@ esac
# Allow the user to override the flags for
# our build compiler if desired.
-CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-${CFLAGS}}
-CXXFLAGS_FOR_BUILD=${CXXFLAGS_FOR_BUILD-${CFLAGS}}
-LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-${CFLAGS}}
+if test x"${build}" = x"${host}" ; then
+ CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-${CFLAGS}}
+ CXXFLAGS_FOR_BUILD=${CXXFLAGS_FOR_BUILD-${CXXFLAGS}}
+ LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-${LDFLAGS}}
+fi
# On Canadian crosses, we'll be searching the right directories for
# the previously-installed cross compiler, so don't bother to add
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index 5f99c24e0f8..8df5f828743 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,8 @@
+2007-10-08 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * texi2pod.pl: Handle @asis.
+ (postprocess): Move @gccoptlist{} after all formatting commands.
+
2007-10-01 Alexandre Oliva <aoliva@redhat.com>
* compare-debug: Avoid spurious errors when .stripped files
diff --git a/contrib/texi2pod.pl b/contrib/texi2pod.pl
index cd0ffd9435f..e45f2724d94 100755
--- a/contrib/texi2pod.pl
+++ b/contrib/texi2pod.pl
@@ -297,6 +297,7 @@ while(<$inf>) {
$ic =~ s/\@(?:code|kbd)/C/;
$ic =~ s/\@(?:dfn|var|emph|cite|i)/I/;
$ic =~ s/\@(?:file)/F/;
+ $ic =~ s/\@(?:asis)//;
$_ = "\n=over 4\n";
};
@@ -319,8 +320,12 @@ while(<$inf>) {
/^\@itemx?\s*(.+)?$/ and do {
if (defined $1) {
- # Entity escapes prevent munging by the <> processing below.
- $_ = "\n=item $ic\&LT;$1\&GT;\n";
+ if ($ic) {
+ # Entity escapes prevent munging by the <> processing below.
+ $_ = "\n=item $ic\&LT;$1\&GT;\n";
+ } else {
+ $_ = "\n=item $1\n";
+ }
} else {
$_ = "\n=item $ic\n";
$ic =~ y/A-Ya-y/B-Zb-z/;
@@ -376,7 +381,7 @@ sub postprocess
s/\@r\{([^\}]*)\}/R<$1>/g;
s/\@(?:dfn|var|emph|cite|i)\{([^\}]*)\}/I<$1>/g;
s/\@(?:code|kbd)\{([^\}]*)\}/C<$1>/g;
- s/\@(?:gccoptlist|samp|strong|key|option|env|command|b)\{([^\}]*)\}/B<$1>/g;
+ s/\@(?:samp|strong|key|option|env|command|b)\{([^\}]*)\}/B<$1>/g;
s/\@sc\{([^\}]*)\}/\U$1/g;
s/\@file\{([^\}]*)\}/F<$1>/g;
s/\@w\{([^\}]*)\}/S<$1>/g;
@@ -412,6 +417,10 @@ sub postprocess
s/\@uref\{([^\},]*),([^\},]*)\}/$2 (C<$1>)/g;
s/\@uref\{([^\},]*),([^\},]*),([^\},]*)\}/$3/g;
+ # Handle gccoptlist here, so it can contain the above formatting
+ # commands.
+ s/\@gccoptlist\{([^\}]*)\}/B<$1>/g;
+
# Un-escape <> at this point.
s/&LT;/</g;
s/&GT;/>/g;
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 45344244cce..03230d1eebe 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,450 @@
+2007-10-09 James E. Wilson <wilson@specifix.com>
+
+ PR tree-optimization/33655
+ PR middle-end/22156
+ * tree-sra.c (bitfield_overlaps_p): When fld->element is INTEGER_CST,
+ convert it to bitsizetype before size_binop call.
+
+2007-10-09 Alexandre Oliva <aoliva@redhat.com>
+
+ PR tree-optimization/33572
+ * tree-inline.c (update_ssa_across_abnormal_edges): Tolerate
+ the absence of a corresponding edge from the exit block.
+
+2007-10-09 Alexandre Oliva <aoliva@redhat.com>
+
+ PR middle-end/22156
+ * tree-sra.c (instantiate_element): Use BYTES_BIG_ENDIAN for
+ bit-field layout.
+ (sra_build_assignment): Likewise. Set up mask depending on
+ precision, not type.
+ (sra_build_bf_assignment): Use BYTES_BIG_ENDIAN. Don't overflow
+ computing bit masks.
+ (sra_build_elt_assignment): Don't view-convert from signed to
+ unsigned.
+ (sra_explode_bitfield_assignment): Use bit-field type if
+ possible. Use BYTES_BIG_ENDIAN.
+
+2007-10-08 Alexandre Oliva <aoliva@redhat.com>
+
+ PR middle-end/22156
+ * tree-sra.c (scalarize_lsdt): Fix thinko in testing whether
+ the original stmt can throw.
+ (sra_build_bf_assignment): Fix type mismatch when applying negated
+ mask.
+
+2007-10-08 Geoffrey Keating <geoffk@apple.com>
+
+ * config/darwin.h (DARWIN_REGISTER_TARGET_PRAGMAS): Register
+ '#pragma mark' to be executed at preprocessing time.
+
+2007-10-08 Ollie Wild <aaw@google.com>
+
+ * varasm.c (compare_constant): Removed call to
+ lang_hooks.expand_constant.
+ (copy_constants): Removed call to lang_hooks.expand_constant.
+ (compute_reloc_for_constant): Removed call to
+ lang_hooks.expand_constant.
+ (output_addressed_constants): Removed call to
+ lang_hooks.expand_constant.
+ (constructor_static_from_elts_p): Removed call to
+ lang_hooks.expand_constant.
+ (output_constant): Removed calls to lang_hooks.expand_constant.
+ * langhooks.h (struct lang_hooks): Removed field expand_constant.
+ * langhooks-def.h (lhd_return_tree): Removed.
+ (LANG_HOOKS_EXPAND_CONSTANT): Removed.
+ (LANG_HOOKS_INITIALIZER): Removed LANG_HOOKS_EXPAND_CONSTANT.
+ * langhooks.c (lhd_return_tree): Removed.
+
+2007-10-08 Mark Shinwell <shinwell@codesourcery.com>
+
+ * combine.c (setup_incoming_promotions): Ensure that
+ arguments that have not undergone mode promotions do not
+ incorrectly get marked as being sign- or zero-extended.
+
+2007-10-08 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/33693
+ PR middle-end/33695
+ PR middle-end/33697
+ * fold-const.c (fold_binary): Use correct types in folding
+ of a * (1 << b) to (a << b). Likewise for ~A & ~B to ~(A | B)
+ and building of RROTATE_EXPR.
+
+2007-10-08 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/33691
+ PR middle-end/33694
+ PR middle-end/33696
+ * fold-const.c (fold_binary): Use the correct types when
+ folding (A | CST1) & CST2 to (A & CST2) | (CST1 & CST2).
+ (fold_binary): Use the correct types when folding
+ (-A) - B to (-B) - A.
+ (fold_unary): Use the correct types when folding ~(X).
+
+2007-10-08 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * doc/invoke.texi (Wall): fix formatting issues.
+
+2007-10-07 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * simplify-rtx.c (simplify_binary_operation_1): Canonicalize
+ truncated shift counts.
+
+2007-10-07 Kazu Hirata <kazu@codesourcery.com>
+
+ * config/m68k/m68k.c, config/m68k/m68k.md: Use the assembly
+ syntax for ASSEMBLER_DIALECT.
+ * config/m68k/m68k.h (ASSEMBLER_DIALECT): New.
+
+2007-10-06 Eric Botcazou <ebotcazou@adacore.com>
+ Nathan Froyd <froydnj@codesourcery.com>
+
+ * dwarf2out.c (dwarf2out_frame_init): Check for DWARF2_FRAME_INFO
+ when determining whether to record INCOMING_RETURN_ADDR_RTX.
+
+2007-10-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ Revert:
+ 2007-02-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree.h (DECL_IGNORED_P): Document further effect for FUNCTION_DECL.
+ * cgraphunit.c (cgraph_expand_function): If DECL_IGNORED_P is set on
+ the function, temporarily point the debug interface to the null one.
+
+2007-10-06 Alexandre Oliva <aoliva@redhat.com>
+
+ PR tree-optimization/33655
+ PR middle-end/22156
+ * tree-sra.c (bitfield_overlaps_p): Handle array and complex
+ elements.
+
+2007-10-06 Alexandre Oliva <aoliva@redhat.com>
+
+ PR tree-optimization/33572
+ * tree-cfg.c (verify_stmts): Check for missing PHI defs.
+ * tree-inline.c (update_ssa_across_eh_edges): Renamed to...
+ (update_ssa_across_abnormal_edges): ... this. Set slots in the
+ return PHI node.
+ (copy_edges_for_bb): Handle nonlocal label edges.
+ (make_nonlocal_label_edges): Deleted.
+ (optimize_inline_calls): Don't call it.
+
+2007-10-05 Hans-Peter Nilsson <hp@axis.com>
+
+ * gthr-single.h: Revert last change.
+
+2007-10-05 Michael Matz <matz@suse.de>
+
+ PR middle-end/33667
+ * lower-subreg.c (decompose_multiword_subregs): Use
+ validate_unshare_change().
+
+2007-10-05 Peter Bergner <bergner@vnet.ibm.com>
+
+ * ra-conflict.c: Include "sparseset.h".
+ (conflicts): Change to HOST_WIDEST_FAST_INT.
+ (allocnos_live): Redefine variable as a sparseset.
+ (SET_ALLOCNO_LIVE, CLEAR_ALLOCNO_LIVE, GET_ALLOCNO_LIVE): Delete macros.
+ (allocno_row_words): Removed global variable.
+ (partial_bitnum, max_bitnum, adjacency_pool, adjacency): New variables.
+ (CONFLICT_BITNUM, CONFLICT_BITNUM_FAST): New defines.
+ (conflict_p, set_conflict_p, set_conflicts_p): New functions.
+ (record_one_conflict_between_regnos): Cache allocno values and reuse.
+ Use set_conflict_p.
+ (record_one_conflict): Update uses of allocnos_live to use
+ the sparseset routines. Use set_conflicts_p.
+ (mark_reg_store): Likewise.
+ (set_reg_in_live): Likewise.
+ (global_conflicts): Update uses of allocnos_live.
+ Use the new adjacency list to visit an allocno's neighbors
+ rather than iterating over all possible allocnos.
+ Call set_conflicts_p to setup conflicts rather than adding
+ them manually.
+ * global.c: Comments updated.
+ (CONFLICTP): Delete define.
+ (regno_compare): New function. Add prototype.
+ (global_alloc): Sort the allocno to regno mapping according to
+ which basic blocks the regnos are referenced in. Modify the
+ conflict bit matrix to a compressed triangular bitmatrix.
+ Only allocate the conflict bit matrix and adjacency lists if
+ we are actually going to allocate something.
+ (expand_preferences): Use conflict_p. Update uses of allocnos_live.
+ (prune_preferences): Use the FOR_EACH_CONFLICT macro to visit an
+ allocno's neighbors rather than iterating over all possible allocnos.
+ (mirror_conflicts): Removed function.
+ (dump_conflicts): Iterate over regnos rather than allocnos so
+ that all dump output will be sorted by regno number.
+ Use the FOR_EACH_CONFLICT macro.
+ * ra.h: Comments updated.
+ (conflicts): Update prototype to HOST_WIDEST_FAST_INT.
+ (partial_bitnum, max_bitnum, adjacency, adjacency_pool): Add prototypes.
+ (ADJACENCY_VEC_LENGTH, FOR_EACH_CONFLICT): New defines.
+ (adjacency_list_d, adjacency_iterator_d): New types.
+ (add_neighbor, adjacency_iter_init, adjacency_iter_done,
+ adjacency_iter_next, regno_basic_block): New static inline functions.
+ (EXECUTE_IF_SET_IN_ALLOCNO_SET): Removed define.
+ (conflict_p): Add function prototype.
+ * sparseset.h, sparseset.c: New files.
+ * Makefile.in (OBJS-common): Add sparseset.o.
+ (sparseset.o): New rule.
+
+2007-10-05 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/33666
+ * fold-const.c (fold_unary): Do not fold (long long)(int)ptr
+ to (long long)ptr.
+
+2007-10-05 Michael Matz <matz@suse.de>
+
+ PR inline-asm/33600
+ * function.c (match_asm_constraints_1): Check for input
+ being used in the outputs.
+
+2007-10-05 Richard Guenther <rguenther@suse.de>
+
+ * tree-cfg.c (verify_gimple_expr): Accept OBJ_TYPE_REF.
+
+2007-10-05 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ PR target/33635
+ * config/mips/mips.c (mips_register_move_cost): Rewrite to use
+ subset checks. Make the cost of FPR -> FPR moves depend on
+ mips_mode_ok_for_mov_fmt_p.
+
+2007-10-04 Doug Kwan <dougkwan@google.com>
+
+ * gthr-posix.h (__gthread_cond_broadcast, __gthread_cond_wait,
+ __gthread_cond_wait_recursive): Add to extend interface for POSIX
+ conditional variables. (__GTHREAD_HAS_COND): Macro defined to signify
+ support of conditional variables.
+ * gthr-posix95.h (__gthread_cond_broadcast, __gthread_cond_wait,
+ __gthread_cond_wait_recursive): Add to extend interface for POSIX
+ conditional variables. (__GTHREAD_HAS_COND): Macro defined to signify
+ support of conditional variables.
+ * gthr-single.h (__gthread_cond_broadcast, __gthread_cond_wait,
+ __gthread_cond_wait_recursive): Add to extend interface for POSIX
+ conditional variables.
+ * gthr.h: Update comments to document new interface.
+
+2007-10-04 Geoffrey Keating <geoffk@apple.com>
+
+ * cgraphunit.c (cgraph_build_static_cdtor): Don't set
+ DECL_IGNORED_P.
+
+2007-10-04 Anatoly Sokolov <aesok@post.ru>
+
+ * config/avr/avr.c (expand_epilogue): Don't set RTX_FRAME_RELATED_P.
+
+2007-10-04 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/33641
+ * tree-cfg.c (verify_gimple_expr): Operand one of POINTER_PLUS_EXPR
+ does not need to be of INTEGER_TYPE.
+ (verify_gimple_2): New function split out from ...
+ (verify_gimple_1): ... here. ICE if there was an error during
+ verification.
+
+2007-10-04 Michael Matz <matz@suse.de>
+
+ PR rtl-optimization/33653
+ * dce.c (deletable_insn_p_1): Use volatile_refs_p().
+ * dse.c (scan_insn): Same.
+
+2007-10-04 Kazu Hirata <kazu@codesourcery.com>
+
+ * config.gcc: Remove USE_GAS for m68k targets.
+
+2007-10-04 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/33627
+ * tree-gimple.h (canonicalize_cond_expr_cond): Declare.
+ * tree-gimple.c (canonicalize_cond_expr_cond): New function,
+ split out from ...
+ * tree-ssa-forwprop.c (combine_cond_expr_cond): ... here.
+ * tree-ssa-ifcombine.c (ifcombine_iforif): Use it.
+
+2007-10-04 Anatoly Sokolov <aesok@post.ru>
+
+ * config/avr/avr.c (commands_in_file, commands_in_prologues,
+ commands_in_epilogues): Remove variables.
+ (avr_file_start): Remove unneded initializations of commands_in_file,
+ commands_in_prologues and commands_in_epilogues variables.
+ (avr_file_end): Remove dead code.
+
+2007-10-04 Kazu Hirata <kazu@codesourcery.com>
+
+ * config/m68k/m68k.c (m68k_output_movem): Use the MOTOROLA if
+ MOTOROLA is to true.
+
+2007-10-03 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ PR target/33635
+ * config/mips/mips-protos.h (mips_split_64bit_move): Rename to...
+ (mips_split_doubleword_move): ...this.
+ * config/mips/mips.c (mips_subword): Extend to handle 64-bit words;
+ use natural endianness for multi-format FPR values.
+ (mips_split_64bit_move): Rename to...
+ (mips_split_doubleword_move): ...this and extend to 64-bit words.
+ Use move_doubleword_fpr* patterns for moves involving FPRs.
+ (mips_save_reg): Update the call to mips_split_64bit_move.
+ (mips_secondary_reload_class): Return NO_REGS for any reload of a
+ nonzero constant into an FPR if the constant can be forced to memory.
+ * config/mips/mips.md: Update the splitter calls to
+ mips_split_64bit_move.
+ (UNSPEC_LOAD_DF_LOW): Rename to...
+ (UNSPEC_LOAD_LOW): ...this.
+ (UNSPEC_LOAD_DF_HIGH): Rename to...
+ (UNSPEC_LOAD_HIGH): ...this.
+ (UNSPEC_STORE_DF_HIGH): Rename to...
+ (UNSPEC_STORE_WORD): ...this.
+ (SPLITF): New mode iterator.
+ (HALFMODE): New mode attribute.
+ (movtf): New expander.
+ (*movtf_internal): New define_insn_and_split.
+ (move_doubleword_fpr<mode>): New expander.
+ (load_df_low, load_df_high, store_df_high, mthc1, mfhc1): Replace
+ with...
+ (load_low<mode>, load_high<mode>, store_word<mode>, mthc1<mode>)
+ (mfhc1<mode>): ...these more general patterns.
+
+2007-10-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * cfgrtl.c (rtl_block_ends_with_call_p): Skip notes at the end.
+
+2007-10-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * gcse.c (hash_scan_set): Insert set in insn before note at
+ the end of basic block.
+
+2007-10-03 Sebastian Pop <sebastian.pop@amd.com>
+
+ PR tree-optimization/33576
+ * testsuite/gcc.dg/tree-ssa/pr33576.c: New.
+ * tree-loop-linear.c (linear_transform_loops): Call remove_iv.
+ * lambda.h (lambda_loopnest_to_gcc_loopnest): New parameter.
+ (remove_iv): Declared.
+ * lambda-code.c (remove_iv): Not static.
+ (lambda_loopnest_to_gcc_loopnest): New parameter remove_ivs.
+ Don't remove ivs there, save ivs in the buffer.
+
+2007-10-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/15764
+ * tree-eh.c (same_handler_p): New fn.
+ (optimize_double_finally): New fn.
+ (refactor_eh_r): New fn.
+ (refactor_eh): New fn.
+ (pass_refactor_eh): New pass.
+ * tree-pass.h: Declare it.
+ * passes.c (init_optimization_passes): Add it.
+
+2007-10-03 Doug Kwan <dougkwan@google.com>
+ Richard Guenther <rguenther@suse.de>
+
+ PR debug/31899
+ * dwarf2out.c (reference_to_unused): Disable sanity checking,
+ be conservative instead.
+
+2007-10-03 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/26682
+ * doc/invoke.texi (-fwhole-program): Document that Fortran
+ doesn't support this option.
+
+2007-10-02 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ PR middle-end/33617
+ * expr.c (expand_expr_addr_expr_1): Pass CONSTRUCTORs to
+ expand_expr.
+
+2007-10-02 David Daney <ddaney@avtrex.com>
+
+ * config/mips/mips.md (sync_compare_and_swap<mode>): Handle compare
+ against constant zero.
+ * config/mips/mips.h (MIPS_COMPARE_AND_SWAP): Handle constant zero
+ operand.
+
+2007-09-02 Kenneth Zadeck <zadeck@naturalbridge.com>
+
+ * ra-conflict.c: New file.
+ * ra.h: New file.
+ * reload.c (push_reload, find_dummy_reload): Change DF_RA_LIVE
+ usage to DF_LIVE usage.
+ * rtlanal.c (subreg_nregs_with_regno): New function.
+ * df-scan.c (df_def_record_1, df_uses_record): Add code to set
+ DF_REF_EXTRACT, DF_REF_STRICT_LOWER_PART, and DF_REF_SUBREG flags.
+ (df_has_eh_preds): Removed.
+ (df_bb_refs_collect, df_bb_refs_collect, df_bb_refs_collect,
+ df_exit_block_uses_collect): Changed call from df_has_eh_preds to
+ bb_has_eh_pred.
+ * global.c (allocno, max_allocno, conflicts, allocno_row_words,
+ reg_allocno, EXECUTE_IF_SET_IN_ALLOCNO_SET): Moved to ra.h
+ (SET_ALLOCNO_LIVE, CLEAR_ALLOCNO_LIVE): Moved to ra-conflicts.c.
+ (regs_set, record_one_conflict, record_conflicts, mark_reg_store,
+ mark_reg_clobber, mark_reg_conflicts, mark_reg_death): Deleted.
+ (global_alloc): Turn off rescanning insns after call to
+ global_conflicts and added call to set_preferences.
+ (global_conflicts): Moved to ra-alloc.c.
+ (set_preferences_1, set_preferences): New function.
+ (mirror_conflicts): Changed types for various variables.
+ (mark_elimination): Change DF_RA_LIVE
+ usage to DF_LIVE usage.
+ (build_insn_chain): Rewritten from scratch and made local.
+ (print_insn_chain, print_insn_chains): New functions.
+ (dump_conflicts): Do not print conflicts for fixed_regs.
+ (rest_of_handle_global_alloc): Turn off insn rescanning.
+ * hard-reg-set.h: Fixed comment.
+ * local-alloc.c (update_equiv_regs): Change DF_RA_LIVE
+ usage to DF_LIVE usage and delete refs to TOP sets.
+ (block_alloc): Mark regs as live if they are in the artificial
+ defs at top of block.
+ (find_stack_regs): New function.
+ (rest_of_handle_local_alloc): Changed urec problem to live
+ problem and do not turn off df rescanning.
+ * df.h (DF_UREC, DF_UREC_BB_INFO, DF_LIVE_TOP, DF_RA_LIVE_IN,
+ DF_RA_LIVE_TOP, DF_RA_LIVE_OUT, df_urec_bb_info, df_urec,
+ df_urec_add_problem, df_urec_get_bb_info, df_has_eh_preds): Removed.
+ (DF_CHAIN, DF_NOTE, DF_CHAIN): Renumbered.
+ (DF_REF_EXTRACT, DF_REF_STRICT_LOWER_PART, DF_REF_SUBREG): New
+ fields in df_ref_flags. The rest have been renumbered.
+ * init-regs.c (initialize_uninitialized_regs): Enhanced debugging
+ at -O1.
+ * rtl.h (subreg_nregs_with_regno): New function.
+ * df-problems.c: (df_get_live_out, df_get_live_in,
+ df_get_live_top): Removed reference to DF_RA_LIVE.
+ (df_lr_reset, df_lr_transfer_function, df_live_free_bb_info,
+ df_live_alloc, df_live_reset, df_live_local_finalize,
+ df_live_free): Make top set only if different from in set.
+ (df_lr_top_dump, df_live_top_dump): Only print top set if
+ different from in set.
+ (df_lr_bb_local_compute): Removed unnecessary check.
+ (df_urec_problem_data, df_urec_set_bb_info, df_urec_free_bb_info,
+ df_urec_alloc, df_urec_mark_reg_change, earlyclobber_regclass,
+ df_urec_check_earlyclobber, df_urec_mark_reg_use_for_earlyclobber,
+ df_urec_mark_reg_use_for_earlyclobber_1, df_urec_bb_local_compute,
+ df_urec_local_compute, df_urec_init, df_urec_local_finalize,
+ df_urec_confluence_n, df_urec_transfer_function, df_urec_free,
+ df_urec_top_dump, df_urec_bottom_dump, problem_UREC,
+ df_urec_add_problem): Removed.
+ (df_simulate_fixup_sets): Changed call from df_has_eh_preds to
+ bb_has_eh_pred.
+ * Makefile.in (ra-conflict.o, ra.h): New dependencies.
+ * basic_block.h (bb_has_abnormal_pred): New function.
+ * reload1.c (compute_use_by_pseudos): Change DF_RA_LIVE
+ usage to DF_LIVE usage.
+
+2007-10-02 Revital Eres <eres@il.ibm.com>
+
+ * config/rs6000/predicates.md (easy_vector_constant): Return false
+ for 750CL paired vectors.
+ * config/rs6000/paired.md (movv2sf_paired): Fix move of easy
+ vector constant.
+ (vec_initv2sf): Add new description.
+ (vconcatsf): Likewise.
+ * config/rs6000/rs6000-protos.h: Declare paired_expand_vector_init.
+ * config/rs6000/rs6000.c (paired_expand_vector_init): New function.
+
2007-10-01 Alexandre Oliva <aoliva@redhat.com>
* tree-ssa-sink.c (sink_code_in_bb): Don't stop sinking after
diff --git a/gcc/ChangeLog.vta b/gcc/ChangeLog.vta
index 9c27274ce3e..a3c1f10f6d5 100644
--- a/gcc/ChangeLog.vta
+++ b/gcc/ChangeLog.vta
@@ -269,10 +269,6 @@
2007-10-01 Alexandre Oliva <aoliva@redhat.com>
- * cfgrtl.c (rtl_block_ends_with_call_p): Skip notes at the end.
-
-2007-10-01 Alexandre Oliva <aoliva@redhat.com>
-
* tree-inline.c (self_inlining_addr_expr): Delete.
(setup_one_parameter): Drop fn argument. Adjust callers.
Don't short-circuit optimization of declarations.
@@ -284,22 +280,6 @@
2007-10-01 Alexandre Oliva <aoliva@redhat.com>
- * gcse.c (hash_scan_set): Insert set in insn before note at
- the end of basic block.
-
-2007-10-01 Alexandre Oliva <aoliva@redhat.com>
-
- PR tree-optimization/33572
- * tree-cfg.c (verify_stmts): Check for missing PHI defs.
- * tree-inline.c (update_ssa_across_eh_edges): Renamed to...
- (update_ssa_across_abnormal_edges): ... this. Set slots in the
- return PHI node.
- (copy_edges_for_bb): Handle nonlocal label edges.
- (make_nonlocal_label_edges): Deleted.
- (optimize_inline_calls): Don't call it.
-
-2007-10-01 Alexandre Oliva <aoliva@redhat.com>
-
* tree-ssa-copyrename.c (copy_rename_partition_coalesce):
Permit coalescing of user variables.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 92212d037ef..791e015e87f 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20071001
+20071009
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index c3fe42a9cd5..c31b25916a7 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -791,6 +791,7 @@ FUNCTION_H = function.h $(TREE_H) $(HASHTAB_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)
+RA_H = ra.h $(REGS_H)
RESOURCE_H = resource.h hard-reg-set.h
SCHED_INT_H = sched-int.h $(INSN_ATTR_H) $(BASIC_BLOCK_H) $(RTL_H) $(DF_H)
INTEGRATE_H = integrate.h $(VARRAY_H)
@@ -1100,6 +1101,7 @@ OBJS-common = \
print-rtl.o \
print-tree.o \
profile.o \
+ ra-conflict.o \
real.o \
recog.o \
reg-stack.o \
@@ -1124,6 +1126,7 @@ OBJS-common = \
sdbout.o \
see.o \
simplify-rtx.o \
+ sparseset.o \
sreal.o \
stack-ptr-mod.o \
stmt.o \
@@ -1763,6 +1766,7 @@ sbitmap.o: sbitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(OBSTACK_H)
ebitmap.o: ebitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(EBITMAP_H)
+sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h
COLLECT2_OBJS = collect2.o tlink.o intl.o version.o
COLLECT2_LIBS = @COLLECT2_LIBS@
@@ -2702,7 +2706,11 @@ bitmap.o : bitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) reload.h $(FUNCTION_H) $(RECOG_H) $(REGS_H) hard-reg-set.h \
insn-config.h output.h toplev.h $(TM_P_H) $(MACHMODE_H) tree-pass.h \
- $(TIMEVAR_H) vecprim.h $(DF_H)
+ $(TIMEVAR_H) vecprim.h $(DF_H) $(DBGCNT_H) $(RA_H)
+ra-conflict.o : ra-conflict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ $(FLAGS_H) reload.h $(FUNCTION_H) $(RECOG_H) $(REGS_H) hard-reg-set.h \
+ insn-config.h output.h toplev.h $(TM_P_H) $(MACHMODE_H) tree-pass.h \
+ $(TIMEVAR_H) vecprim.h $(DF_H) $(RA_H) sbitmap.h
varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \
$(HASHTAB_H) $(BCONFIG_H) $(VARRAY_H) toplev.h
vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h vec.h $(GGC_H) \
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 3da4b568811..aee18d08a4a 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,22 @@
+2007-10-08 Ollie Wild <aaw@google.com>
+
+ * misc.c (LANG_HOOKS_PUSHDECL): Replaced lhd_return_tree with
+ gnat_return_tree.
+ (gnat_init_gcc_eh): Replaced gnat_eh_runtime_type with
+ gnat_return_tree.
+ (gnat_eh_runtime_type): Removed.
+ (gnat_return_tree): New function.
+
+2007-10-08 Ben Elliston <bje@au.ibm.com>
+
+ PR ada/33454
+ Revert:
+ 2007-08-31 Ben Elliston <bje@au.ibm.com>
+
+ * Makefile.in (LIBGNAT_TARGET_PAIRS): Use system-linux-ppc64.ads
+ when compiling for powerpc64-*-linux.
+ * system-linux-ppc64.ads: New file.
+
2007-09-27 Eric Botcazou <ebotcazou@adacore.com>
Mapped location support
diff --git a/gcc/ada/Makefile.in b/gcc/ada/Makefile.in
index 64a5315ae62..24068808496 100644
--- a/gcc/ada/Makefile.in
+++ b/gcc/ada/Makefile.in
@@ -1324,13 +1324,8 @@ ifeq ($(strip $(filter-out powerpc% linux%,$(arch) $(osys))),)
s-osprim.adb<s-osprim-posix.adb \
s-taprop.adb<s-taprop-linux.adb \
s-taspri.ads<s-taspri-posix.ads \
- s-tpopsp.adb<s-tpopsp-posix-foreign.adb
-
- ifeq ($(strip $(filter-out powerpc64,$(arch))),)
- LIBGNAT_TARGET_PAIRS += system.ads<system-linux-ppc64.ads
- else
- LIBGNAT_TARGET_PAIRS += system.ads<system-linux-ppc.ads
- endif
+ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \
+ system.ads<system-linux-ppc.ads
TOOLS_TARGET_PAIRS = \
mlib-tgt-specific.adb<mlib-tgt-linux.adb \
diff --git a/gcc/ada/misc.c b/gcc/ada/misc.c
index 473beb059fd..b7830040c41 100644
--- a/gcc/ada/misc.c
+++ b/gcc/ada/misc.c
@@ -95,7 +95,7 @@ static void gnat_print_decl (FILE *, tree, int);
static void gnat_print_type (FILE *, tree, int);
static const char *gnat_printable_name (tree, int);
static const char *gnat_dwarf_name (tree, int);
-static tree gnat_eh_runtime_type (tree);
+static tree gnat_return_tree (tree);
static int gnat_eh_type_covers (tree, tree);
static void gnat_parse_file (int);
static rtx gnat_expand_expr (tree, rtx, enum machine_mode, int,
@@ -125,7 +125,7 @@ static tree gnat_type_max_size (const_tree);
#undef LANG_HOOKS_GETDECLS
#define LANG_HOOKS_GETDECLS lhd_return_null_tree_v
#undef LANG_HOOKS_PUSHDECL
-#define LANG_HOOKS_PUSHDECL lhd_return_tree
+#define LANG_HOOKS_PUSHDECL gnat_return_tree
#undef LANG_HOOKS_WRITE_GLOBALS
#define LANG_HOOKS_WRITE_GLOBALS gnat_write_global_declarations
#undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
@@ -512,7 +512,7 @@ gnat_init_gcc_eh (void)
? "__gnat_eh_personality_sj"
: "__gnat_eh_personality");
lang_eh_type_covers = gnat_eh_type_covers;
- lang_eh_runtime_type = gnat_eh_runtime_type;
+ lang_eh_runtime_type = gnat_return_tree;
default_init_unwind_resume_libfunc ();
/* Turn on -fexceptions and -fnon-call-exceptions. The first one triggers
@@ -703,15 +703,13 @@ gnat_adjust_rli (record_layout_info rli ATTRIBUTE_UNUSED)
rli->record_align = record_align;
#endif
}
-
-/* These routines are used in conjunction with GCC exception handling. */
-/* Map compile-time to run-time tree for GCC exception handling scheme. */
+/* Do nothing (return the tree node passed). */
static tree
-gnat_eh_runtime_type (tree type)
+gnat_return_tree (tree t)
{
- return type;
+ return t;
}
/* Return true if type A catches type B. Callback for flow analysis from
diff --git a/gcc/ada/system-linux-ppc64.ads b/gcc/ada/system-linux-ppc64.ads
deleted file mode 100644
index 2d9e528185a..00000000000
--- a/gcc/ada/system-linux-ppc64.ads
+++ /dev/null
@@ -1,153 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME COMPONENTS --
--- --
--- S Y S T E M --
--- --
--- S p e c --
--- (GNU-Linux/PPC64 Version) --
--- --
--- Copyright (C) 1992-2007, Free Software Foundation, Inc. --
--- --
--- This specification is derived from the Ada Reference Manual for use with --
--- GNAT. The copyright notice above, and the license provisions that follow --
--- apply solely to the contents of the part following the private keyword. --
--- --
--- 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- --
--- ware Foundation; either version 2, or (at your option) any later ver- --
--- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
--- OUT 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 distributed with GNAT; see file COPYING. If not, write --
--- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
--- Boston, MA 02110-1301, USA. --
--- --
--- As a special exception, if other files instantiate generics from this --
--- unit, or you link this unit with other files to produce an executable, --
--- this unit does not by itself cause the resulting executable to be --
--- covered by the GNU General Public License. This exception does not --
--- however invalidate any other reasons why the executable file might be --
--- covered by the GNU Public License. --
--- --
--- GNAT was originally developed by the GNAT team at New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc. --
--- --
-------------------------------------------------------------------------------
-
-package System is
- pragma Pure;
- -- Note that we take advantage of the implementation permission to make
- -- this unit Pure instead of Preelaborable; see RM 13.7.1(15). In Ada
- -- 2005, this is Pure in any case (AI-362).
-
- type Name is (SYSTEM_NAME_GNAT);
- System_Name : constant Name := SYSTEM_NAME_GNAT;
-
- -- System-Dependent Named Numbers
-
- Min_Int : constant := Long_Long_Integer'First;
- Max_Int : constant := Long_Long_Integer'Last;
-
- Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
- Max_Nonbinary_Modulus : constant := 2 ** Integer'Size - 1;
-
- Max_Base_Digits : constant := Long_Long_Float'Digits;
- Max_Digits : constant := Long_Long_Float'Digits;
-
- Max_Mantissa : constant := 63;
- Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
-
- Tick : constant := 0.000_001;
-
- -- Storage-related Declarations
-
- type Address is private;
- pragma Preelaborable_Initialization (Address);
- Null_Address : constant Address;
-
- Storage_Unit : constant := 8;
- Word_Size : constant := 64;
- Memory_Size : constant := 2 ** 64;
-
- -- Address comparison
-
- function "<" (Left, Right : Address) return Boolean;
- function "<=" (Left, Right : Address) return Boolean;
- function ">" (Left, Right : Address) return Boolean;
- function ">=" (Left, Right : Address) return Boolean;
- function "=" (Left, Right : Address) return Boolean;
-
- pragma Import (Intrinsic, "<");
- pragma Import (Intrinsic, "<=");
- pragma Import (Intrinsic, ">");
- pragma Import (Intrinsic, ">=");
- pragma Import (Intrinsic, "=");
-
- -- Other System-Dependent Declarations
-
- type Bit_Order is (High_Order_First, Low_Order_First);
- Default_Bit_Order : constant Bit_Order := High_Order_First;
- pragma Warnings (Off, Default_Bit_Order); -- kill constant condition warning
-
- -- Priority-related Declarations (RM D.1)
-
- -- 0 .. 98 corresponds to the system priority range 1 .. 99.
- --
- -- If the scheduling policy is SCHED_FIFO or SCHED_RR the runtime makes use
- -- of the entire range provided by the system.
- --
- -- If the scheduling policy is SCHED_OTHER the only valid system priority
- -- is 1 and other values are simply ignored.
-
- Max_Priority : constant Positive := 97;
- Max_Interrupt_Priority : constant Positive := 98;
-
- subtype Any_Priority is Integer range 0 .. 98;
- subtype Priority is Any_Priority range 0 .. 97;
- subtype Interrupt_Priority is Any_Priority range 98 .. 98;
-
- Default_Priority : constant Priority := 48;
-
-private
-
- type Address is mod Memory_Size;
- Null_Address : constant Address := 0;
-
- --------------------------------------
- -- System Implementation Parameters --
- --------------------------------------
-
- -- These parameters provide information about the target that is used
- -- by the compiler. They are in the private part of System, where they
- -- can be accessed using the special circuitry in the Targparm unit
- -- whose source should be consulted for more detailed descriptions
- -- of the individual switch values.
-
- Backend_Divide_Checks : constant Boolean := False;
- Backend_Overflow_Checks : constant Boolean := False;
- Command_Line_Args : constant Boolean := True;
- Configurable_Run_Time : constant Boolean := False;
- Denorm : constant Boolean := True;
- Duration_32_Bits : constant Boolean := False;
- Exit_Status_Supported : constant Boolean := True;
- Fractional_Fixed_Ops : constant Boolean := False;
- Frontend_Layout : constant Boolean := False;
- Machine_Overflows : constant Boolean := False;
- Machine_Rounds : constant Boolean := True;
- Preallocated_Stacks : constant Boolean := False;
- Signed_Zeros : constant Boolean := True;
- Stack_Check_Default : constant Boolean := False;
- Stack_Check_Probes : constant Boolean := False;
- Support_64_Bit_Divides : constant Boolean := True;
- Support_Aggregates : constant Boolean := True;
- Support_Composite_Assign : constant Boolean := True;
- Support_Composite_Compare : constant Boolean := True;
- Support_Long_Shifts : constant Boolean := True;
- Suppress_Standard_Library : constant Boolean := False;
- Use_Ada_Main_Program_Name : constant Boolean := False;
- ZCX_By_Default : constant Boolean := True;
- GCC_ZCX_Support : constant Boolean := True;
-
-end System;
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index e2cd90211f1..eb719ca26e0 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -1135,6 +1135,21 @@ bb_has_eh_pred (basic_block bb)
return false;
}
+/* Return true when one of the predecessor edges of BB is marked with EDGE_ABNORMAL. */
+static inline bool
+bb_has_abnormal_pred (basic_block bb)
+{
+ edge e;
+ edge_iterator ei;
+
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ {
+ if (e->flags & EDGE_ABNORMAL)
+ return true;
+ }
+ return false;
+}
+
/* In cfgloopmanip.c. */
extern edge mfb_kj_edge;
bool mfb_keep_just (edge);
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 0218d260066..b2e196026bd 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1044,8 +1044,6 @@ cgraph_mark_functions_to_output (void)
static void
cgraph_expand_function (struct cgraph_node *node)
{
- enum debug_info_type save_write_symbols = NO_DEBUG;
- const struct gcc_debug_hooks *save_debug_hooks = NULL;
tree decl = node->decl;
/* We ought to not compile any inline clones. */
@@ -1056,14 +1054,6 @@ cgraph_expand_function (struct cgraph_node *node)
gcc_assert (node->lowered);
- if (DECL_IGNORED_P (decl))
- {
- save_write_symbols = write_symbols;
- write_symbols = NO_DEBUG;
- save_debug_hooks = debug_hooks;
- debug_hooks = &do_nothing_debug_hooks;
- }
-
/* Generate RTL for the body of DECL. */
if (lang_hooks.callgraph.emit_associated_thunks)
lang_hooks.callgraph.emit_associated_thunks (decl);
@@ -1073,12 +1063,6 @@ cgraph_expand_function (struct cgraph_node *node)
/* ??? Can happen with nested function of extern inline. */
gcc_assert (TREE_ASM_WRITTEN (node->decl));
- if (DECL_IGNORED_P (decl))
- {
- write_symbols = save_write_symbols;
- debug_hooks = save_debug_hooks;
- }
-
current_function_decl = NULL;
if (!cgraph_preserve_function_body_p (node->decl))
{
@@ -1400,7 +1384,6 @@ cgraph_build_static_cdtor (char which, tree body, int priority)
resdecl = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
DECL_ARTIFICIAL (resdecl) = 1;
- DECL_IGNORED_P (resdecl) = 1;
DECL_RESULT (decl) = resdecl;
allocate_struct_function (decl);
@@ -1408,7 +1391,6 @@ cgraph_build_static_cdtor (char which, tree body, int priority)
TREE_STATIC (decl) = 1;
TREE_USED (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
- DECL_IGNORED_P (decl) = 1;
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
DECL_SAVED_TREE (decl) = body;
TREE_PUBLIC (decl) = ! targetm.have_ctors_dtors;
diff --git a/gcc/combine.c b/gcc/combine.c
index 866a4890329..502d4d2a8b3 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1363,15 +1363,17 @@ setup_incoming_promotions (rtx first)
/* Eliminate sign extensions in the callee when possible. Only
do this when:
- (a) the mode of the register is the same as the mode of
+ (a) a mode promotion has occurred;
+ (b) the mode of the register is the same as the mode of
the argument as it is passed; and
- (b) the signedness does not change across any of the promotions; and
- (c) when no language-level promotions (which we cannot guarantee
+ (c) the signedness does not change across any of the promotions; and
+ (d) when no language-level promotions (which we cannot guarantee
will have been done by an external caller) are necessary,
unless we know that this function is only ever called from
the current compilation unit -- all of whose call sites will
do the mode1 --> mode2 promotion. */
- if (mode3 == mode4
+ if (mode1 != mode3
+ && mode3 == mode4
&& uns1 == uns3
&& (mode1 == mode2 || strictly_local))
{
diff --git a/gcc/config.gcc b/gcc/config.gcc
index a5b8f60d43b..2b89432e31a 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1521,7 +1521,7 @@ m68k-*-coff*)
default_m68k_cpu=68020
default_cf_cpu=5206
tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-mlibs"
- tm_defines="${tm_defines} MOTOROLA=1 USE_GAS"
+ tm_defines="${tm_defines} MOTOROLA=1"
tm_file="${tm_file} m68k/m68k-none.h m68k/m68kemb.h dbxcoff.h m68k/coff.h dbx.h"
use_fixproto=yes
;;
@@ -1545,7 +1545,7 @@ m68020-*-elf* | m68k-*-elf* | fido-*-elf*)
;;
esac
tm_file="${tm_file} m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h m68k/m68kemb.h m68k/m68020-elf.h"
- tm_defines="${tm_defines} MOTOROLA=1 USE_GAS"
+ tm_defines="${tm_defines} MOTOROLA=1"
tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-m68kelf"
# Add multilibs for targets other than fido.
case ${target} in
@@ -1561,7 +1561,7 @@ m68010-*-netbsdelf* | m68k*-*-netbsdelf*)
default_m68k_cpu=68020
default_cf_cpu=5475
tm_file="${tm_file} dbxelf.h elfos.h netbsd.h netbsd-elf.h m68k/netbsd-elf.h"
- tm_defines="${tm_defines} MOTOROLA=1 USE_GAS"
+ tm_defines="${tm_defines} MOTOROLA=1"
;;
m68k*-*-openbsd*)
default_m68k_cpu=68020
@@ -1579,7 +1579,7 @@ m68k-*-uclinuxoldabi*) # Motorola m68k/ColdFire running uClinux
default_m68k_cpu=68020
default_cf_cpu=5206
tm_file="${tm_file} m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h m68k/uclinux-oldabi.h"
- tm_defines="${tm_defines} MOTOROLA=1 USE_GAS"
+ tm_defines="${tm_defines} MOTOROLA=1"
tmake_file="m68k/t-floatlib m68k/t-uclinux"
use_fixproto=no
;;
@@ -1589,7 +1589,7 @@ m68k-*-uclinux*) # Motorola m68k/ColdFire running uClinux
default_m68k_cpu=68020
default_cf_cpu=5206
tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h flat.h m68k/linux.h m68k/uclinux.h ./sysroot-suffix.h"
- tm_defines="${tm_defines} MOTOROLA=1 USE_GAS UCLIBC_DEFAULT=1"
+ tm_defines="${tm_defines} MOTOROLA=1 UCLIBC_DEFAULT=1"
extra_options="${extra_options} linux.opt"
tmake_file="m68k/t-floatlib m68k/t-uclinux m68k/t-mlibs"
use_fixproto=no
@@ -1601,7 +1601,7 @@ m68k-*-linux*) # Motorola m68k's running GNU/Linux
default_cf_cpu=5475
tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h m68k/linux.h"
extra_options="${extra_options} m68k/ieee.opt"
- tm_defines="${tm_defines} MOTOROLA=1 USE_GAS"
+ tm_defines="${tm_defines} MOTOROLA=1"
# if not configured with --enable-sjlj-exceptions, bump the
# libgcc version number
if test x$sjlj != x1; then
@@ -1613,7 +1613,7 @@ m68k-*-rtems*)
default_cf_cpu=5206
tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-crtstuff t-rtems m68k/t-rtems m68k/t-mlibs"
tm_file="${tm_file} m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h m68k/m68kemb.h m68k/m68020-elf.h m68k/rtemself.h rtems.h"
- tm_defines="${tm_defines} MOTOROLA=1 USE_GAS"
+ tm_defines="${tm_defines} MOTOROLA=1"
extra_parts="crtbegin.o crtend.o"
;;
mcore-*-elf)
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 1382479369f..8e3de6a3597 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -95,15 +95,6 @@ static const char *const avr_regnames[] = REGISTER_NAMES;
/* This holds the last insn address. */
static int last_insn_address = 0;
-/* Commands count in the compiled file */
-static int commands_in_file;
-
-/* Commands in the functions prologues in the compiled file */
-static int commands_in_prologues;
-
-/* Commands in the functions epilogues in the compiled file */
-static int commands_in_epilogues;
-
/* Preprocessor macros to define depending on MCU type. */
const char *avr_base_arch_macro;
const char *avr_extra_arch_macro;
@@ -796,13 +787,11 @@ expand_epilogue (void)
int live_seq;
int minimize;
HOST_WIDE_INT size = get_frame_size();
- rtx insn;
/* epilogue: naked */
if (cfun->machine->is_naked)
{
- insn = emit_jump_insn (gen_return ());
- RTX_FRAME_RELATED_P (insn) = 1;
+ emit_jump_insn (gen_return ());
return;
}
@@ -815,29 +804,23 @@ expand_epilogue (void)
{
/* Return value from main() is already in the correct registers
(r25:r24) as the exit() argument. */
- insn = emit_jump_insn (gen_return ());
- RTX_FRAME_RELATED_P (insn) = 1;
+ emit_jump_insn (gen_return ());
}
else if (minimize && (frame_pointer_needed || live_seq > 4))
{
if (frame_pointer_needed)
{
/* Get rid of frame. */
- insn =
- emit_move_insn(frame_pointer_rtx,
- gen_rtx_PLUS (HImode, frame_pointer_rtx,
- gen_int_mode (size, HImode)));
- RTX_FRAME_RELATED_P (insn) = 1;
+ emit_move_insn(frame_pointer_rtx,
+ gen_rtx_PLUS (HImode, frame_pointer_rtx,
+ gen_int_mode (size, HImode)));
}
else
{
- insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
- RTX_FRAME_RELATED_P (insn) = 1;
+ emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
}
- insn =
- emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
- RTX_FRAME_RELATED_P (insn) = 1;
+ emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
}
else
{
@@ -851,7 +834,7 @@ expand_epilogue (void)
fp_plus_length =
get_attr_length (gen_move_insn (frame_pointer_rtx,
gen_rtx_PLUS (HImode, frame_pointer_rtx,
- gen_int_mode (size,
+ gen_int_mode (size,
HImode))));
/* Copy to stack pointer. */
fp_plus_length +=
@@ -864,32 +847,28 @@ expand_epilogue (void)
sp_plus_length =
get_attr_length (gen_move_insn (stack_pointer_rtx,
gen_rtx_PLUS (HImode, stack_pointer_rtx,
- gen_int_mode (size,
+ gen_int_mode (size,
HImode))));
}
/* Use shortest method. */
if (size <= 5 && (sp_plus_length < fp_plus_length))
{
- insn = emit_move_insn (stack_pointer_rtx,
- gen_rtx_PLUS (HImode, stack_pointer_rtx,
- gen_int_mode (size, HImode)));
- RTX_FRAME_RELATED_P (insn) = 1;
+ emit_move_insn (stack_pointer_rtx,
+ gen_rtx_PLUS (HImode, stack_pointer_rtx,
+ gen_int_mode (size, HImode)));
}
else
{
- insn = emit_move_insn (frame_pointer_rtx,
- gen_rtx_PLUS (HImode, frame_pointer_rtx,
- gen_int_mode (size, HImode)));
- RTX_FRAME_RELATED_P (insn) = 1;
+ emit_move_insn (frame_pointer_rtx,
+ gen_rtx_PLUS (HImode, frame_pointer_rtx,
+ gen_int_mode (size, HImode)));
/* Copy to stack pointer. */
- insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
- RTX_FRAME_RELATED_P (insn) = 1;
+ emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
}
}
/* Restore previous frame_pointer. */
- insn = emit_insn (gen_pophi (frame_pointer_rtx));
- RTX_FRAME_RELATED_P (insn) = 1;
+ emit_insn (gen_pophi (frame_pointer_rtx));
}
/* Restore used registers. */
HARD_REG_SET set;
@@ -897,33 +876,25 @@ expand_epilogue (void)
for (reg = 31; reg >= 0; --reg)
{
if (TEST_HARD_REG_BIT (set, reg))
- {
- insn = emit_insn (gen_popqi (gen_rtx_REG (QImode, reg)));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
+ emit_insn (gen_popqi (gen_rtx_REG (QImode, reg)));
}
if (cfun->machine->is_interrupt || cfun->machine->is_signal)
{
/* Restore SREG using tmp reg as scratch. */
- insn = emit_insn (gen_popqi (tmp_reg_rtx));
- RTX_FRAME_RELATED_P (insn) = 1;
+ emit_insn (gen_popqi (tmp_reg_rtx));
- insn = emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(SREG_ADDR)),
- tmp_reg_rtx);
- RTX_FRAME_RELATED_P (insn) = 1;
+ emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(SREG_ADDR)),
+ tmp_reg_rtx);
/* Restore tmp REG. */
- insn = emit_insn (gen_popqi (tmp_reg_rtx));
- RTX_FRAME_RELATED_P (insn) = 1;
+ emit_insn (gen_popqi (tmp_reg_rtx));
/* Restore zero REG. */
- insn = emit_insn (gen_popqi (zero_reg_rtx));
- RTX_FRAME_RELATED_P (insn) = 1;
+ emit_insn (gen_popqi (zero_reg_rtx));
}
- insn = emit_jump_insn (gen_return ());
- RTX_FRAME_RELATED_P (insn) = 1;
+ emit_jump_insn (gen_return ());
}
}
@@ -4807,10 +4778,6 @@ avr_file_start (void)
initialization code from libgcc if one or both sections are empty. */
fputs ("\t.global __do_copy_data\n", asm_out_file);
fputs ("\t.global __do_clear_bss\n", asm_out_file);
-
- commands_in_file = 0;
- commands_in_prologues = 0;
- commands_in_epilogues = 0;
}
/* Outputs to the stdio stream FILE some
@@ -4819,14 +4786,6 @@ avr_file_start (void)
static void
avr_file_end (void)
{
- fputs ("/* File ", asm_out_file);
- output_quoted_string (asm_out_file, main_input_filename);
- fprintf (asm_out_file,
- ": code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
- commands_in_file,
- commands_in_file,
- commands_in_file - commands_in_prologues - commands_in_epilogues,
- commands_in_prologues, commands_in_epilogues);
}
/* Choose the order in which to allocate hard registers for
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index e135191c3fc..d4c7ce515e4 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -892,7 +892,8 @@ enum machopic_addr_class {
#define DARWIN_REGISTER_TARGET_PRAGMAS() \
do { \
- c_register_pragma (0, "mark", darwin_pragma_ignore); \
+ cpp_register_pragma (parse_in, NULL, "mark", \
+ darwin_pragma_ignore, false); \
c_register_pragma (0, "options", darwin_pragma_options); \
c_register_pragma (0, "segment", darwin_pragma_ignore); \
c_register_pragma (0, "unused", darwin_pragma_unused); \
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index d2b023f4160..099a220a870 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -3318,16 +3318,16 @@ m68k_output_movem (rtx *operands, rtx pattern,
if (FP_REGNO_P (REGNO (XEXP (XVECEXP (pattern, 0, first), store_p))))
{
if (store_p)
- return MOTOROLA ? "fmovm %1,%a0" : "fmovem %1,%a0";
+ return "fmovem %1,%a0";
else
- return MOTOROLA ? "fmovm %a0,%1" : "fmovem %a0,%1";
+ return "fmovem %a0,%1";
}
else
{
if (store_p)
- return MOTOROLA ? "movm.l %1,%a0" : "moveml %1,%a0";
+ return "movem%.l %1,%a0";
else
- return MOTOROLA ? "movm.l %a0,%1" : "moveml %a0,%1";
+ return "movem%.l %a0,%1";
}
}
@@ -3375,8 +3375,8 @@ output_addsi3 (rtx *operands)
&& (INTVAL (operands[2]) < -32768 || INTVAL (operands[2]) > 32767))
return "move%.l %2,%0\n\tadd%.l %1,%0";
if (GET_CODE (operands[2]) == REG)
- return MOTOROLA ? "lea (%1,%2.l),%0" : "lea %1@(0,%2:l),%0";
- return MOTOROLA ? "lea (%c2,%1),%0" : "lea %1@(%c2),%0";
+ return "lea {(%1,%2.l)|%1@(0,%2:l)},%0";
+ return "lea {(%c2,%1)|%1@(%c2)},%0";
}
if (GET_CODE (operands[2]) == CONST_INT)
{
@@ -3414,7 +3414,7 @@ output_addsi3 (rtx *operands)
if (TUNE_68040)
return "add%.w %2,%0";
else
- return MOTOROLA ? "lea (%c2,%0),%0" : "lea %0@(%c2),%0";
+ return "lea {(%c2,%0)|%0@(%c2)},%0";
}
}
return "add%.l %2,%0";
@@ -3730,11 +3730,11 @@ print_operand (FILE *file, rtx op, int letter)
else if (letter == '#')
asm_fprintf (file, "%I");
else if (letter == '-')
- asm_fprintf (file, MOTOROLA ? "-(%Rsp)" : "%Rsp@-");
+ asm_fprintf (file, "{-(%Rsp)|%Rsp@-}");
else if (letter == '+')
- asm_fprintf (file, MOTOROLA ? "(%Rsp)+" : "%Rsp@+");
+ asm_fprintf (file, "{(%Rsp)+|%Rsp@+}");
else if (letter == '@')
- asm_fprintf (file, MOTOROLA ? "(%Rsp)" : "%Rsp@");
+ asm_fprintf (file, "{(%Rsp)|%Rsp@}");
else if (letter == '!')
asm_fprintf (file, "%Rfpcr");
else if (letter == '$')
@@ -3774,7 +3774,7 @@ print_operand (FILE *file, rtx op, int letter)
&& !(GET_CODE (XEXP (op, 0)) == CONST_INT
&& INTVAL (XEXP (op, 0)) < 0x8000
&& INTVAL (XEXP (op, 0)) >= -0x8000))
- fprintf (file, MOTOROLA ? ".l" : ":l");
+ asm_fprintf (file, "{.|:}l");
}
else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
{
@@ -3834,11 +3834,11 @@ print_operand_address (FILE *file, rtx addr)
gcc_unreachable ();
if (address.code == PRE_DEC)
- fprintf (file, MOTOROLA ? "-(%s)" : "%s@-",
- M68K_REGNAME (REGNO (address.base)));
+ asm_fprintf (file, "{-(%s)|%s@-}",
+ M68K_REGNAME (REGNO (address.base)));
else if (address.code == POST_INC)
- fprintf (file, MOTOROLA ? "(%s)+" : "%s@+",
- M68K_REGNAME (REGNO (address.base)));
+ asm_fprintf (file, "{(%s)+|%s@+}",
+ M68K_REGNAME (REGNO (address.base)));
else if (!address.base && !address.index)
{
/* A constant address. */
@@ -3847,7 +3847,7 @@ print_operand_address (FILE *file, rtx addr)
{
/* (xxx).w or (xxx).l. */
if (IN_RANGE (INTVAL (addr), -0x8000, 0x7fff))
- fprintf (file, MOTOROLA ? "%d.w" : "%d:w", (int) INTVAL (addr));
+ asm_fprintf (file, "%d{.|:}w", (int) INTVAL (addr));
else
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (addr));
}
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index 93b962a9fef..6f915d95839 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -29,6 +29,10 @@ along with GCC; see the file COPYING3. If not see
# define TARGET_VERSION fprintf (stderr, " (68k, MIT syntax)")
#endif
+/* Options 0 and 1 are the Motorola and MIT syntaxes,
+ respectively. */
+#define ASSEMBLER_DIALECT !MOTOROLA
+
/* Handle --with-cpu default option from configure script. */
#define OPTION_DEFAULT_SPECS \
{ "cpu", "%{!mc68000:%{!m68000:%{!m68302:%{!m68010:%{!mc68020:%{!m68020:\
@@ -971,17 +975,11 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
sprintf (LABEL, "*%s%s%ld", LOCAL_LABEL_PREFIX, PREFIX, (long)(NUM))
-#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
- asm_fprintf (FILE, (MOTOROLA \
- ? "\tmove.l %s,-(%Rsp)\n" \
- : "\tmovel %s,%Rsp@-\n"), \
- reg_names[REGNO])
-
-#define ASM_OUTPUT_REG_POP(FILE,REGNO) \
- asm_fprintf (FILE, (MOTOROLA \
- ? "\tmove.l (%Rsp)+,%s\n" \
- : "\tmovel %Rsp@+,%s\n"), \
- reg_names[REGNO])
+#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
+ asm_fprintf (FILE, "\tmove%.l %s,{-(%Rsp)|%Rsp@-}\n", reg_names[REGNO])
+
+#define ASM_OUTPUT_REG_POP(FILE,REGNO) \
+ asm_fprintf (FILE, "\tmove%.l {(%Rsp)+|%Rsp@+},%s\n", reg_names[REGNO])
/* The m68k does not use absolute case-vectors, but we must define this macro
anyway. */
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 68053b33b70..a46b3fa8381 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -825,7 +825,7 @@
"TUNE_68040_60"
{
if (which_alternative == 0)
- return MOTOROLA ? "lea 0.w,%0" : "lea 0:w,%0";
+ return "lea 0{.|:}w,%0";
else if (which_alternative == 1)
return "clr%.l %0";
else
@@ -1140,7 +1140,7 @@
{
/* On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 */
if (TUNE_68040_60)
- return MOTOROLA ? "lea 0.w,%0" : "lea 0:w,%0";
+ return "lea 0{.|:}w,%0";
else
return "sub%.l %0,%0";
}
@@ -2444,13 +2444,13 @@
return "#";
case 5:
- return MOTOROLA ? "lea (%1,%2.l),%0" : "lea %1@(0,%2:l),%0";
+ return "lea {(%1,%2.l)|%1@(0,%2:l)},%0";
case 6:
- return MOTOROLA ? "lea (%2,%1.l),%0" : "lea %2@(0,%1:l),%0";
+ return "lea {(%2,%1.l)|%2@(0,%1:l)},%0";
case 7:
- return MOTOROLA ? "lea (%c2,%1),%0" : "lea %1@(%c2),%0";
+ return "lea {(%c2,%1)|%1@(%c2)},%0";
default:
gcc_unreachable ();
@@ -2521,7 +2521,7 @@
}
}
if (ADDRESS_REG_P (operands[0]) && !TUNE_68040)
- return MOTOROLA ? "lea (%c2,%0),%0" : "lea %0@(%c2),%0";
+ return "lea {(%c2,%0)|%0@(%c2)},%0";
}
return "add%.w %2,%0";
})
@@ -2576,7 +2576,7 @@
}
}
if (ADDRESS_REG_P (operands[0]) && !TUNE_68040)
- return MOTOROLA ? "lea (%c1,%0),%0" : "lea %0@(%c1),%0";
+ return "lea {(%c1,%0)|%0@(%c1)},%0";
}
return "add%.w %1,%0";
})
@@ -2625,7 +2625,7 @@
}
}
if (ADDRESS_REG_P (operands[0]) && !TUNE_68040)
- return MOTOROLA ? "lea (%c1,%0),%0" : "lea %0@(%c1),%0";
+ return "lea {(%c1,%0)|%0@(%c1)},%0";
}
return "add%.w %1,%0";
})
@@ -2971,9 +2971,7 @@
(mult:HI (match_operand:HI 1 "general_operand" "%0")
(match_operand:HI 2 "general_src_operand" "dmSn")))]
""
-{
- return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
-}
+ "muls{.w} %2,%0"
[(set_attr "type" "muls_w")
(set_attr "opy" "2")])
@@ -2984,9 +2982,7 @@
(sign_extend:SI
(match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
""
-{
- return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
-}
+ "muls{.w} %2,%0"
[(set_attr "type" "muls_w")
(set_attr "opy" "2")])
@@ -2996,9 +2992,7 @@
(match_operand:HI 1 "nonimmediate_operand" "%0"))
(match_operand:SI 2 "const_int_operand" "n")))]
"INTVAL (operands[2]) >= -0x8000 && INTVAL (operands[2]) <= 0x7fff"
-{
- return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
-}
+ "muls{.w} %2,%0"
[(set_attr "type" "muls_w")
(set_attr "opy" "2")])
@@ -3035,9 +3029,7 @@
(zero_extend:SI
(match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
""
-{
- return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0";
-}
+ "mulu{.w} %2,%0"
[(set_attr "type" "mulu_w")
(set_attr "opy" "2")])
@@ -3047,9 +3039,7 @@
(match_operand:HI 1 "nonimmediate_operand" "%0"))
(match_operand:SI 2 "const_int_operand" "n")))]
"INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 0xffff"
-{
- return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0";
-}
+ "mulu{.w} %2,%0"
[(set_attr "type" "mulu_w")
(set_attr "opy" "2")])
@@ -3472,10 +3462,7 @@
(mod:HI (match_dup 1) (match_dup 2)))]
"!TARGET_COLDFIRE || TARGET_CF_HWDIV"
{
- output_asm_insn (MOTOROLA ?
- "ext%.l %0\;divs%.w %2,%0" :
- "extl %0\;divs %2,%0",
- operands);
+ output_asm_insn ("ext%.l %0\;divs{.w} %2,%0", operands);
if (!find_reg_note(insn, REG_UNUSED, operands[3]))
{
CC_STATUS_INIT;
@@ -3494,15 +3481,9 @@
"!TARGET_COLDFIRE || TARGET_CF_HWDIV"
{
if (ISA_HAS_MVS_MVZ)
- output_asm_insn (MOTOROLA ?
- "mvz%.w %0,%0\;divu%.w %2,%0" :
- "mvz%.w %0,%0\;divu %2,%0",
- operands);
+ output_asm_insn ("mvz%.w %0,%0\;divu{.w} %2,%0", operands);
else
- output_asm_insn (MOTOROLA ?
- "and%.l #0xFFFF,%0\;divu%.w %2,%0" :
- "and%.l #0xFFFF,%0\;divu %2,%0",
- operands);
+ output_asm_insn ("and%.l #0xFFFF,%0\;divu{.w} %2,%0", operands);
if (!find_reg_note(insn, REG_UNUSED, operands[3]))
{
@@ -6832,9 +6813,7 @@
[(set (pc) (match_operand:SI 0 "register_operand" "a"))
(use (label_ref (match_operand 1 "" "")))]
""
-{
- return MOTOROLA ? "jmp (%0)" : "jmp %0@";
-}
+ "jmp {(%0)|%0@}"
[(set_attr "type" "bra")])
;; Jump to variable address from dispatch table of relative addresses.
@@ -6851,14 +6830,12 @@
if (TARGET_COLDFIRE)
{
if (ADDRESS_REG_P (operands[0]))
- return MOTOROLA ? "jmp (2,pc,%0.l)" : "jmp pc@(2,%0:l)";
- else if (MOTOROLA)
- return "ext%.l %0\;jmp (2,pc,%0.l)";
+ return "jmp {(2,pc,%0.l)|pc@(2,%0:l)}";
else
- return "extl %0\;jmp pc@(2,%0:l)";
+ return "ext%.l %0\;jmp {(2,pc,%0.l)|pc@(2,%0:l)}";
}
else
- return MOTOROLA ? "jmp (2,pc,%0.w)" : "jmp pc@(2,%0:w)";
+ return "jmp {(2,pc,%0.w)|pc@(2,%0:w)}";
#endif
})
@@ -7225,12 +7202,10 @@
"TARGET_68020 || INTVAL (operands[1]) >= -0x8004"
{
operands[1] = GEN_INT (INTVAL (operands[1]) + 4);
- if (!MOTOROLA)
- return "link %0,%1";
- else if (INTVAL (operands[1]) >= -0x8000)
- return "link.w %0,%1";
+ if (INTVAL (operands[1]) >= -0x8000)
+ return "link{.w} %0,%1";
else
- return "link.l %0,%1";
+ return "link{.l} %0,%1";
})
(define_expand "unlink"
@@ -7263,7 +7238,7 @@
if (TARGET_ID_SHARED_LIBRARY)
{
operands[1] = gen_rtx_REG (Pmode, PIC_REG);
- return MOTOROLA ? "move.l %?(%1),%0" : "movel %1@(%?), %0";
+ return "move%.l {%?(%1)|%1@(%?)},%0";
}
else if (MOTOROLA)
{
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 623774961e2..371fd93447e 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -201,7 +201,7 @@ extern int m16_nsimm8_8 (rtx, enum machine_mode);
extern rtx mips_subword (rtx, int);
extern bool mips_split_64bit_move_p (rtx, rtx);
-extern void mips_split_64bit_move (rtx, rtx);
+extern void mips_split_doubleword_move (rtx, rtx);
extern const char *mips_output_move (rtx, rtx);
extern void mips_restore_gp (void);
#ifdef RTX_CODE
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 6ac976abe6e..889997d8c33 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -3477,7 +3477,7 @@ mips_address_cost (rtx addr)
rtx
mips_subword (rtx op, int high_p)
{
- unsigned int byte;
+ unsigned int byte, offset;
enum machine_mode mode;
mode = GET_MODE (op);
@@ -3490,7 +3490,11 @@ mips_subword (rtx op, int high_p)
byte = 0;
if (FP_REG_RTX_P (op))
- return gen_rtx_REG (word_mode, high_p ? REGNO (op) + 1 : REGNO (op));
+ {
+ /* Paired FPRs are always ordered little-endian. */
+ offset = (UNITS_PER_WORD < UNITS_PER_HWFPVALUE ? high_p : byte != 0);
+ return gen_rtx_REG (word_mode, REGNO (op) + offset);
+ }
if (MEM_P (op))
return mips_rewrite_small_data (adjust_address (op, word_mode, byte));
@@ -3524,58 +3528,23 @@ mips_split_64bit_move_p (rtx dest, rtx src)
}
-/* Split a 64-bit move from SRC to DEST assuming that
- mips_split_64bit_move_p holds.
-
- Moves into and out of FPRs cause some difficulty here. Such moves
- will always be DFmode, since paired FPRs are not allowed to store
- DImode values. The most natural representation would be two separate
- 32-bit moves, such as:
-
- (set (reg:SI $f0) (mem:SI ...))
- (set (reg:SI $f1) (mem:SI ...))
-
- However, the second insn is invalid because odd-numbered FPRs are
- not allowed to store independent values. Use the patterns load_df_low,
- load_df_high and store_df_high instead. */
+/* Split a doubleword move from SRC to DEST. On 32-bit targets,
+ this function handles 64-bit moves for which mips_split_64bit_move_p
+ holds. For 64-bit targets, this function handles 128-bit moves. */
void
-mips_split_64bit_move (rtx dest, rtx src)
+mips_split_doubleword_move (rtx dest, rtx src)
{
- if (FP_REG_RTX_P (dest))
+ if (FP_REG_RTX_P (dest) || FP_REG_RTX_P (src))
{
- /* Loading an FPR from memory or from GPRs. */
- if (ISA_HAS_MXHC1)
- {
- if (GET_MODE (dest) != DFmode)
- dest = gen_rtx_REG_offset (dest, DFmode, REGNO (dest), 0);
- emit_insn (gen_load_df_low (dest, mips_subword (src, 0)));
- emit_insn (gen_mthc1 (dest, mips_subword (src, 1),
- copy_rtx (dest)));
- }
+ if (!TARGET_64BIT && GET_MODE (dest) == DImode)
+ emit_insn (gen_move_doubleword_fprdi (dest, src));
+ else if (!TARGET_64BIT && GET_MODE (dest) == DFmode)
+ emit_insn (gen_move_doubleword_fprdf (dest, src));
+ else if (TARGET_64BIT && GET_MODE (dest) == TFmode)
+ emit_insn (gen_move_doubleword_fprtf (dest, src));
else
- {
- emit_insn (gen_load_df_low (copy_rtx (dest),
- mips_subword (src, 0)));
- emit_insn (gen_load_df_high (dest, mips_subword (src, 1),
- copy_rtx (dest)));
- }
- }
- else if (FP_REG_RTX_P (src))
- {
- /* Storing an FPR into memory or GPRs. */
- if (ISA_HAS_MXHC1)
- {
- if (GET_MODE (src) != DFmode)
- src = gen_rtx_REG_offset (src, DFmode, REGNO (src), 0);
- mips_emit_move (mips_subword (dest, 0), mips_subword (src, 0));
- emit_insn (gen_mfhc1 (mips_subword (dest, 1), src));
- }
- else
- {
- mips_emit_move (mips_subword (dest, 0), mips_subword (src, 0));
- emit_insn (gen_store_df_high (mips_subword (dest, 1), src));
- }
+ gcc_unreachable ();
}
else
{
@@ -8042,7 +8011,7 @@ mips_save_reg (rtx reg, rtx mem)
rtx x1, x2;
if (mips_split_64bit_move_p (mem, reg))
- mips_split_64bit_move (mem, reg);
+ mips_split_doubleword_move (mem, reg);
else
mips_emit_move (mem, reg);
@@ -9472,18 +9441,15 @@ mips_secondary_reload_class (enum reg_class class,
/* In this case we can use mtc1, mfc1, dmtc1 or dmfc1. */
return NO_REGS;
- if (mips_mode_ok_for_mov_fmt_p (mode))
- {
- if (CONSTANT_P (x))
- /* We can force the constants to memory and use lwc1
- and ldc1. As above, we will use pairs of lwc1s if
- ldc1 is not supported. */
- return NO_REGS;
-
- if (FP_REG_P (regno))
- /* In this case we can use mov.fmt. */
- return NO_REGS;
- }
+ if (CONSTANT_P (x) && !targetm.cannot_force_const_mem (x))
+ /* We can force the constant to memory and use lwc1
+ and ldc1. As above, we will use pairs of lwc1s if
+ ldc1 is not supported. */
+ return NO_REGS;
+
+ if (FP_REG_P (regno) && mips_mode_ok_for_mov_fmt_p (mode))
+ /* In this case we can use mov.fmt. */
+ return NO_REGS;
/* Otherwise, we need to reload through an integer register. */
return GR_REGS;
@@ -11003,69 +10969,54 @@ mips_init_libfuncs (void)
we need to use. This gets pretty messy, but it is feasible. */
int
-mips_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
+mips_register_move_cost (enum machine_mode mode,
enum reg_class to, enum reg_class from)
{
- if (from == M16_REGS && reg_class_subset_p (to, GENERAL_REGS))
- return 2;
- else if (from == M16_NA_REGS && reg_class_subset_p (to, GENERAL_REGS))
- return 2;
- else if (reg_class_subset_p (from, GENERAL_REGS))
+ if (TARGET_MIPS16)
{
- if (to == M16_REGS)
- return 2;
- else if (to == M16_NA_REGS)
- return 2;
- else if (reg_class_subset_p (to, GENERAL_REGS))
+ if (reg_class_subset_p (from, GENERAL_REGS)
+ && reg_class_subset_p (to, GENERAL_REGS))
{
- if (TARGET_MIPS16)
- return 4;
- else
+ if (reg_class_subset_p (from, M16_REGS)
+ || reg_class_subset_p (to, M16_REGS))
return 2;
- }
- else if (to == FP_REGS)
- return 4;
- else if (reg_class_subset_p (to, ACC_REGS))
- {
- if (TARGET_MIPS16)
- return 12;
- else
- return 6;
- }
- else if (reg_class_subset_p (to, ALL_COP_REGS))
- {
- return 5;
+ /* Two MOVEs. */
+ return 4;
}
}
- else if (from == FP_REGS)
+ else if (reg_class_subset_p (from, GENERAL_REGS))
{
if (reg_class_subset_p (to, GENERAL_REGS))
- return 4;
- else if (to == FP_REGS)
return 2;
- else if (to == ST_REGS)
- return 8;
+ if (reg_class_subset_p (to, FP_REGS))
+ return 4;
+ if (reg_class_subset_p (to, ALL_COP_AND_GR_REGS))
+ return 5;
+ if (reg_class_subset_p (to, ACC_REGS))
+ return 6;
}
- else if (reg_class_subset_p (from, ACC_REGS))
+ else if (reg_class_subset_p (to, GENERAL_REGS))
{
- if (reg_class_subset_p (to, GENERAL_REGS))
- {
- if (TARGET_MIPS16)
- return 12;
- else
- return 6;
- }
+ if (reg_class_subset_p (from, FP_REGS))
+ return 4;
+ if (reg_class_subset_p (from, ST_REGS))
+ /* LUI followed by MOVF. */
+ return 4;
+ if (reg_class_subset_p (from, ALL_COP_AND_GR_REGS))
+ return 5;
+ if (reg_class_subset_p (from, ACC_REGS))
+ return 6;
}
- else if (from == ST_REGS && reg_class_subset_p (to, GENERAL_REGS))
- return 4;
- else if (reg_class_subset_p (from, ALL_COP_REGS))
+ else if (reg_class_subset_p (from, FP_REGS))
{
- return 5;
+ if (reg_class_subset_p (to, FP_REGS)
+ && mips_mode_ok_for_mov_fmt_p (mode))
+ return 4;
+ if (reg_class_subset_p (to, ST_REGS))
+ /* An expensive sequence. */
+ return 8;
}
- /* Fall through.
- ??? What cases are these? Shouldn't we return 2 here? */
-
return 12;
}
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index ce22f4f5be9..534e88b36e6 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -2959,7 +2959,7 @@ while (0)
#define MIPS_COMPARE_AND_SWAP(SUFFIX, OP) \
"%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%0,%1\n" \
- "\tbne\t%0,%2,2f\n" \
+ "\tbne\t%0,%z2,2f\n" \
"\t" OP "\t%@,%3\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
"\tbeq\t%@,%.,1b\n" \
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 890cc706590..f4b90eb6ee0 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -24,9 +24,9 @@
;; <http://www.gnu.org/licenses/>.
(define_constants
- [(UNSPEC_LOAD_DF_LOW 0)
- (UNSPEC_LOAD_DF_HIGH 1)
- (UNSPEC_STORE_DF_HIGH 2)
+ [(UNSPEC_LOAD_LOW 0)
+ (UNSPEC_LOAD_HIGH 1)
+ (UNSPEC_STORE_WORD 2)
(UNSPEC_GET_FNADDR 3)
(UNSPEC_BLOCKAGE 4)
(UNSPEC_CPRESTORE 5)
@@ -498,6 +498,11 @@
(define_mode_iterator SCALARF [(SF "TARGET_HARD_FLOAT")
(DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
+;; A floating-point mode for which moves involving FPRs may need to be split.
+(define_mode_iterator SPLITF [(DF "!TARGET_64BIT")
+ (DI "!TARGET_64BIT")
+ (TF "TARGET_64BIT")])
+
;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
;; 32-bit version and "dsubu" in the 64-bit version.
(define_mode_attr d [(SI "") (DI "d")
@@ -546,6 +551,10 @@
(V4UQQ "SI") (V2UHQ "SI") (V2UHA "SI")
(V2HQ "SI") (V2HA "SI")])
+;; This attribute gives the integer mode that has half the size of
+;; the controlling mode.
+(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
+
;; This attribute works around the early SB-1 rev2 core "F2" erratum:
;;
;; In certain cases, div.s and div.ps may have a rounding error
@@ -3999,6 +4008,32 @@
(set_attr "mode" "DF")
(set_attr "length" "8,8,8,*,*")])
+;; 128-bit floating point moves
+
+(define_expand "movtf"
+ [(set (match_operand:TF 0 "")
+ (match_operand:TF 1 ""))]
+ ""
+{
+ if (mips_legitimize_move (TFmode, operands[0], operands[1]))
+ DONE;
+})
+
+;; This pattern handles both hard- and soft-float cases.
+(define_insn_and_split "*movtf_internal"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=d,R,f,dR")
+ (match_operand:TF 1 "move_operand" "dGR,dG,dGR,f"))]
+ ""
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ mips_split_doubleword_move (operands[0], operands[1]);
+ DONE;
+}
+ [(set_attr "type" "multi")
+ (set_attr "length" "16")])
+
(define_split
[(set (match_operand:DI 0 "nonimmediate_operand")
(match_operand:DI 1 "move_operand"))]
@@ -4006,7 +4041,7 @@
&& mips_split_64bit_move_p (operands[0], operands[1])"
[(const_int 0)]
{
- mips_split_64bit_move (operands[0], operands[1]);
+ mips_split_doubleword_move (operands[0], operands[1]);
DONE;
})
@@ -4017,7 +4052,7 @@
&& mips_split_64bit_move_p (operands[0], operands[1])"
[(const_int 0)]
{
- mips_split_64bit_move (operands[0], operands[1]);
+ mips_split_doubleword_move (operands[0], operands[1]);
DONE;
})
@@ -4099,74 +4134,105 @@
[(set_attr "type" "mfhilo")
(set_attr "mode" "<MODE>")])
-;; Patterns for loading or storing part of a paired floating point
-;; register. We need them because odd-numbered floating-point registers
-;; are not fully independent: see mips_split_64bit_move.
+;; Emit a doubleword move in which exactly one of the operands is
+;; a floating-point register. We can't just emit two normal moves
+;; because of the constraints imposed by the FPU register model;
+;; see mips_cannot_change_mode_class for details. Instead, we keep
+;; the FPR whole and use special patterns to refer to each word of
+;; the other operand.
+
+(define_expand "move_doubleword_fpr<mode>"
+ [(set (match_operand:SPLITF 0)
+ (match_operand:SPLITF 1))]
+ ""
+{
+ if (FP_REG_RTX_P (operands[0]))
+ {
+ rtx low = mips_subword (operands[1], 0);
+ rtx high = mips_subword (operands[1], 1);
+ emit_insn (gen_load_low<mode> (operands[0], low));
+ if (ISA_HAS_MXHC1)
+ emit_insn (gen_mthc1<mode> (operands[0], high, operands[0]));
+ else
+ emit_insn (gen_load_high<mode> (operands[0], high, operands[0]));
+ }
+ else
+ {
+ rtx low = mips_subword (operands[0], 0);
+ rtx high = mips_subword (operands[0], 1);
+ emit_insn (gen_store_word<mode> (low, operands[1], const0_rtx));
+ if (ISA_HAS_MXHC1)
+ emit_insn (gen_mfhc1<mode> (high, operands[1]));
+ else
+ emit_insn (gen_store_word<mode> (high, operands[1], const1_rtx));
+ }
+ DONE;
+})
;; Load the low word of operand 0 with operand 1.
-(define_insn "load_df_low"
- [(set (match_operand:DF 0 "register_operand" "=f,f")
- (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
- UNSPEC_LOAD_DF_LOW))]
- "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
+(define_insn "load_low<mode>"
+ [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
+ (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")]
+ UNSPEC_LOAD_LOW))]
+ "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
{
operands[0] = mips_subword (operands[0], 0);
return mips_output_move (operands[0], operands[1]);
}
- [(set_attr "type" "mtc,fpload")
- (set_attr "mode" "SF")])
+ [(set_attr "type" "mtc,fpload")
+ (set_attr "mode" "<HALFMODE>")])
;; Load the high word of operand 0 from operand 1, preserving the value
;; in the low word.
-(define_insn "load_df_high"
- [(set (match_operand:DF 0 "register_operand" "=f,f")
- (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
- (match_operand:DF 2 "register_operand" "0,0")]
- UNSPEC_LOAD_DF_HIGH))]
- "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
+(define_insn "load_high<mode>"
+ [(set (match_operand:SPLITF 0 "register_operand" "=f,f")
+ (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")
+ (match_operand:SPLITF 2 "register_operand" "0,0")]
+ UNSPEC_LOAD_HIGH))]
+ "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
{
operands[0] = mips_subword (operands[0], 1);
return mips_output_move (operands[0], operands[1]);
}
- [(set_attr "type" "mtc,fpload")
- (set_attr "mode" "SF")])
-
-;; Store the high word of operand 1 in operand 0. The corresponding
-;; low-word move is done in the normal way.
-(define_insn "store_df_high"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
- (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
- UNSPEC_STORE_DF_HIGH))]
- "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
+ [(set_attr "type" "mtc,fpload")
+ (set_attr "mode" "<HALFMODE>")])
+
+;; Store one word of operand 1 in operand 0. Operand 2 is 1 to store the
+;; high word and 0 to store the low word.
+(define_insn "store_word<mode>"
+ [(set (match_operand:<HALFMODE> 0 "nonimmediate_operand" "=d,m")
+ (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f,f")
+ (match_operand 2 "const_int_operand")]
+ UNSPEC_STORE_WORD))]
+ "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
{
- operands[1] = mips_subword (operands[1], 1);
+ operands[1] = mips_subword (operands[1], INTVAL (operands[2]));
return mips_output_move (operands[0], operands[1]);
}
- [(set_attr "type" "mfc,fpstore")
- (set_attr "mode" "SF")])
+ [(set_attr "type" "mfc,fpstore")
+ (set_attr "mode" "<HALFMODE>")])
;; Move operand 1 to the high word of operand 0 using mthc1, preserving the
;; value in the low word.
-(define_insn "mthc1"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (unspec:DF [(match_operand:SI 1 "general_operand" "dJ")
- (match_operand:DF 2 "register_operand" "0")]
- UNSPEC_MTHC1))]
- "TARGET_HARD_FLOAT && !TARGET_64BIT && ISA_HAS_MXHC1"
+(define_insn "mthc1<mode>"
+ [(set (match_operand:SPLITF 0 "register_operand" "=f")
+ (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ")
+ (match_operand:SPLITF 2 "register_operand" "0")]
+ UNSPEC_MTHC1))]
+ "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
"mthc1\t%z1,%0"
- [(set_attr "type" "mtc")
- (set_attr "mode" "SF")])
-
-;; Move high word of operand 1 to operand 0 using mfhc1. The corresponding
-;; low-word move is done in the normal way.
-(define_insn "mfhc1"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (unspec:SI [(match_operand:DF 1 "register_operand" "f")]
- UNSPEC_MFHC1))]
- "TARGET_HARD_FLOAT && !TARGET_64BIT && ISA_HAS_MXHC1"
+ [(set_attr "type" "mtc")
+ (set_attr "mode" "<HALFMODE>")])
+
+;; Move high word of operand 1 to operand 0 using mfhc1.
+(define_insn "mfhc1<mode>"
+ [(set (match_operand:<HALFMODE> 0 "register_operand" "=d")
+ (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f")]
+ UNSPEC_MFHC1))]
+ "TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
"mfhc1\t%0,%1"
- [(set_attr "type" "mfc")
- (set_attr "mode" "SF")])
+ [(set_attr "type" "mfc")
+ (set_attr "mode" "<HALFMODE>")])
;; Move a constant that satisfies CONST_GP_P into operand 0.
(define_expand "load_const_gp"
@@ -4329,7 +4395,7 @@
[(set (match_operand:GPR 0 "register_operand" "=&d,&d")
(match_operand:GPR 1 "memory_operand" "+R,R"))
(set (match_dup 1)
- (unspec_volatile:GPR [(match_operand:GPR 2 "register_operand" "d,d")
+ (unspec_volatile:GPR [(match_operand:GPR 2 "reg_or_0_operand" "dJ,dJ")
(match_operand:GPR 3 "arith_operand" "I,d")]
UNSPEC_COMPARE_AND_SWAP))]
"GENERATE_LL_SC"
diff --git a/gcc/config/rs6000/paired.md b/gcc/config/rs6000/paired.md
index ad3001d884c..67eee233c5e 100644
--- a/gcc/config/rs6000/paired.md
+++ b/gcc/config/rs6000/paired.md
@@ -188,7 +188,7 @@
[(set_attr "type" "fp")])
(define_insn "*movv2sf_paired"
- [(set (match_operand:V2SF 0 "nonimmediate_operand" "=Z,f,f,o,r,r,v")
+ [(set (match_operand:V2SF 0 "nonimmediate_operand" "=Z,f,f,o,r,r,f")
(match_operand:V2SF 1 "input_operand" "f,Z,f,r,o,r,W"))]
"TARGET_PAIRED_FLOAT
&& (register_operand (operands[0], V2SFmode)
@@ -202,7 +202,7 @@
case 3: return "#";
case 4: return "#";
case 5: return "#";
- case 6: return output_vec_const_move (operands);
+ case 6: return "#";
default: gcc_unreachable ();
}
}
@@ -352,4 +352,21 @@
"ps_muls1 %0, %1, %2"
[(set_attr "type" "fp")])
+(define_expand "vec_initv2sf"
+ [(match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (match_operand 1 "" "")]
+ "TARGET_PAIRED_FLOAT"
+{
+ paired_expand_vector_init (operands[0], operands[1]);
+ DONE;
+})
+
+(define_insn "*vconcatsf"
+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (vec_concat:V2SF
+ (match_operand:SF 1 "gpc_reg_operand" "f")
+ (match_operand:SF 2 "gpc_reg_operand" "f")))]
+ "TARGET_PAIRED_FLOAT"
+ "ps_merge00 %0, %1, %2"
+ [(set_attr "type" "fp")])
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index f56c176b37c..3dd4bf560d7 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -275,6 +275,11 @@
(define_predicate "easy_vector_constant"
(match_code "const_vector")
{
+ /* As the paired vectors are actually FPRs it seems that there is
+ no easy way to load a CONST_VECTOR without using memory. */
+ if (TARGET_PAIRED_FLOAT)
+ return false;
+
if (ALTIVEC_VECTOR_MODE (mode))
{
if (zero_constant (op, mode))
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 799a15ac0a4..8c9eb0696c1 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -48,6 +48,7 @@ extern rtx find_addr_reg (rtx);
extern rtx gen_easy_altivec_constant (rtx);
extern const char *output_vec_const_move (rtx *);
extern void rs6000_expand_vector_init (rtx, rtx);
+extern void paired_expand_vector_init (rtx, rtx);
extern void rs6000_expand_vector_set (rtx, rtx, int);
extern void rs6000_expand_vector_extract (rtx, rtx, int);
extern void build_mask64_2_operands (rtx, rtx *);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 8a840ef568a..0f2617fd82b 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -2716,6 +2716,59 @@ output_vec_const_move (rtx *operands)
return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
}
+/* Initialize TARGET of vector PAIRED to VALS. */
+
+void
+paired_expand_vector_init (rtx target, rtx vals)
+{
+ enum machine_mode mode = GET_MODE (target);
+ int n_elts = GET_MODE_NUNITS (mode);
+ int n_var = 0;
+ rtx x, new, tmp, constant_op, op1, op2;
+ int i;
+
+ for (i = 0; i < n_elts; ++i)
+ {
+ x = XVECEXP (vals, 0, i);
+ if (!CONSTANT_P (x))
+ ++n_var;
+ }
+ if (n_var == 0)
+ {
+ /* Load from constant pool. */
+ emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
+ return;
+ }
+
+ if (n_var == 2)
+ {
+ /* The vector is initialized only with non-constants. */
+ new = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
+ XVECEXP (vals, 0, 1));
+
+ emit_move_insn (target, new);
+ return;
+ }
+
+ /* One field is non-constant and the other one is a constant. Load the
+ constant from the constant pool and use ps_merge instruction to
+ construct the whole vector. */
+ op1 = XVECEXP (vals, 0, 0);
+ op2 = XVECEXP (vals, 0, 1);
+
+ constant_op = (CONSTANT_P (op1)) ? op1 : op2;
+
+ tmp = gen_reg_rtx (GET_MODE (constant_op));
+ emit_move_insn (tmp, constant_op);
+
+ if (CONSTANT_P (op1))
+ new = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
+ else
+ new = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
+
+ emit_move_insn (target, new);
+}
+
/* Initialize vector TARGET to VALS. */
void
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5609f1a1626..4f737229412 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,42 @@
+2007-10-08 Ollie Wild <aaw@google.com>
+
+ * typeck2.c (digest_init): Call cplus_expand_constant after
+ convert_for_initialization.
+ * cp-objcp-common.h (LANG_HOOKS_EXPAND_CONSTANT): Removed.
+ * expr.c (cplus_expand_constant): Updated function description.
+
+2007-10-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/20416
+ * call.c (initialize_reference): Handle local static reference
+ temps properly.
+
+2007-10-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/32470
+ * name-lookup.c (push_namespace_with_attrs): Fold back into...
+ (push_namespace): Here.
+ (handle_namespace_attrs): New fn for the attr code.
+ (leave_scope): Don't pop_visibility.
+ * name-lookup.h (struct cp_binding_level): Remove has_visibility.
+ * parser.c (cp_parser_namespace_definition): Call
+ handle_namespace_attrs and pop_visibility as appropriate.
+
+ PR c++/11756
+ * mangle.c (write_type) [TYPEOF_TYPE]: Just sorry.
+
+2007-10-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * decl.c (duplicate_decls): Preserve linkage flags for mere
+ redeclarations of gnu_inline definitions.
+
+2007-10-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/15764
+ * decl.c (wrap_cleanups_r): New fn.
+ (wrap_temporary_cleanups): New fn.
+ (initialize_local_var): Call it.
+
2007-09-29 Jason Merrill <jason@redhat.com>
PR c++/33094
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 645eeb26488..cf3aea7e959 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6824,7 +6824,11 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
if (at_function_scope_p ())
{
add_decl_expr (var);
- *cleanup = cxx_maybe_build_cleanup (var);
+
+ if (TREE_STATIC (var))
+ init = add_stmt_to_compound (init, register_dtor_fn (var));
+ else
+ *cleanup = cxx_maybe_build_cleanup (var);
/* We must be careful to destroy the temporary only
after its initialization has taken place. If the
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index 7f8138c6e60..60d78181ad1 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -50,8 +50,6 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
#undef LANG_HOOKS_GET_ALIAS_SET
#define LANG_HOOKS_GET_ALIAS_SET cxx_get_alias_set
-#undef LANG_HOOKS_EXPAND_CONSTANT
-#define LANG_HOOKS_EXPAND_CONSTANT cplus_expand_constant
#undef LANG_HOOKS_EXPAND_EXPR
#define LANG_HOOKS_EXPAND_EXPR cxx_expand_expr
#undef LANG_HOOKS_EXPAND_DECL
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 469e6b836ee..83195af1b49 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1846,24 +1846,24 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
new_template = NULL_TREE;
if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl))
{
- bool old_decl_gnu_inline;
+ bool new_redefines_gnu_inline = false;
- if ((DECL_INTERFACE_KNOWN (olddecl)
- && TREE_CODE (olddecl) == FUNCTION_DECL)
- || (TREE_CODE (olddecl) == TEMPLATE_DECL
- && TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL))
+ if (new_defines_function
+ && ((DECL_INTERFACE_KNOWN (olddecl)
+ && TREE_CODE (olddecl) == FUNCTION_DECL)
+ || (TREE_CODE (olddecl) == TEMPLATE_DECL
+ && (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl))
+ == FUNCTION_DECL))))
{
tree fn = olddecl;
if (TREE_CODE (fn) == TEMPLATE_DECL)
fn = DECL_TEMPLATE_RESULT (olddecl);
- old_decl_gnu_inline = GNU_INLINE_P (fn) && DECL_INITIAL (fn);
+ new_redefines_gnu_inline = GNU_INLINE_P (fn) && DECL_INITIAL (fn);
}
- else
- old_decl_gnu_inline = false;
- if (!old_decl_gnu_inline)
+ if (!new_redefines_gnu_inline)
{
DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl);
DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl);
@@ -5136,6 +5136,41 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
rest_of_decl_compilation (decl, toplev, at_eof);
}
+/* walk_tree helper for wrap_temporary_cleanups, below. */
+
+static tree
+wrap_cleanups_r (tree *stmt_p, int *walk_subtrees, void *data)
+{
+ if (TYPE_P (*stmt_p))
+ {
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE (*stmt_p) == TARGET_EXPR)
+ {
+ tree guard = (tree)data;
+ tree tcleanup = TARGET_EXPR_CLEANUP (*stmt_p);
+
+ tcleanup = build2 (TRY_CATCH_EXPR, void_type_node, tcleanup, guard);
+
+ TARGET_EXPR_CLEANUP (*stmt_p) = tcleanup;
+ }
+
+ return NULL_TREE;
+}
+
+/* We're initializing a local variable which has a cleanup GUARD. If there
+ are any temporaries used in the initializer INIT of this variable, we
+ need to wrap their cleanups with TRY_CATCH_EXPR (, GUARD) so that the
+ variable will be cleaned up properly if one of them throws. */
+
+static void
+wrap_temporary_cleanups (tree init, tree guard)
+{
+ cp_walk_tree_without_duplicates (&init, wrap_cleanups_r, (void *)guard);
+}
+
/* Generate code to initialize DECL (a local variable). */
static void
@@ -5143,6 +5178,7 @@ initialize_local_var (tree decl, tree init)
{
tree type = TREE_TYPE (decl);
tree cleanup;
+ int already_used;
gcc_assert (TREE_CODE (decl) == VAR_DECL
|| TREE_CODE (decl) == RESULT_DECL);
@@ -5153,46 +5189,53 @@ initialize_local_var (tree decl, tree init)
/* If we used it already as memory, it must stay in memory. */
DECL_INITIAL (decl) = NULL_TREE;
TREE_ADDRESSABLE (decl) = TREE_USED (decl);
+ return;
}
- if (DECL_SIZE (decl) && type != error_mark_node)
- {
- int already_used;
+ if (type == error_mark_node)
+ return;
- /* Compute and store the initial value. */
- already_used = TREE_USED (decl) || TREE_USED (type);
+ /* Compute and store the initial value. */
+ already_used = TREE_USED (decl) || TREE_USED (type);
- /* Perform the initialization. */
- if (init)
- {
- int saved_stmts_are_full_exprs_p;
+ /* Generate a cleanup, if necessary. */
+ cleanup = cxx_maybe_build_cleanup (decl);
- gcc_assert (building_stmt_tree ());
- saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
- current_stmt_tree ()->stmts_are_full_exprs_p = 1;
- finish_expr_stmt (init);
- current_stmt_tree ()->stmts_are_full_exprs_p =
- saved_stmts_are_full_exprs_p;
- }
+ /* Perform the initialization. */
+ if (init)
+ {
+ int saved_stmts_are_full_exprs_p;
- /* Set this to 0 so we can tell whether an aggregate which was
- initialized was ever used. Don't do this if it has a
- destructor, so we don't complain about the 'resource
- allocation is initialization' idiom. Now set
- attribute((unused)) on types so decls of that type will be
- marked used. (see TREE_USED, above.) */
- if (TYPE_NEEDS_CONSTRUCTING (type)
- && ! already_used
- && TYPE_HAS_TRIVIAL_DESTRUCTOR (type)
- && DECL_NAME (decl))
- TREE_USED (decl) = 0;
- else if (already_used)
- TREE_USED (decl) = 1;
- }
+ /* If we're only initializing a single object, guard the destructors
+ of any temporaries used in its initializer with its destructor.
+ This isn't right for arrays because each element initialization is
+ a full-expression. */
+ if (cleanup && TREE_CODE (type) != ARRAY_TYPE)
+ wrap_temporary_cleanups (init, cleanup);
- /* Generate a cleanup, if necessary. */
- cleanup = cxx_maybe_build_cleanup (decl);
- if (DECL_SIZE (decl) && cleanup)
+ gcc_assert (building_stmt_tree ());
+ saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
+ current_stmt_tree ()->stmts_are_full_exprs_p = 1;
+ finish_expr_stmt (init);
+ current_stmt_tree ()->stmts_are_full_exprs_p =
+ saved_stmts_are_full_exprs_p;
+ }
+
+ /* Set this to 0 so we can tell whether an aggregate which was
+ initialized was ever used. Don't do this if it has a
+ destructor, so we don't complain about the 'resource
+ allocation is initialization' idiom. Now set
+ attribute((unused)) on types so decls of that type will be
+ marked used. (see TREE_USED, above.) */
+ if (TYPE_NEEDS_CONSTRUCTING (type)
+ && ! already_used
+ && TYPE_HAS_TRIVIAL_DESTRUCTOR (type)
+ && DECL_NAME (decl))
+ TREE_USED (decl) = 0;
+ else if (already_used)
+ TREE_USED (decl) = 1;
+
+ if (cleanup)
finish_decl_cleanup (decl, cleanup);
}
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index 267b847770e..b5186462e5e 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -33,8 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "except.h"
#include "tm_p.h"
-/* Hook used by output_constant to expand language-specific
- constants. */
+/* Expand C++-specific constants. Currently, this means PTRMEM_CST. */
tree
cplus_expand_constant (tree cst)
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index cad76e37631..7377a3ea455 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1687,6 +1687,10 @@ write_type (tree type)
write_char ('E');
break;
+ case TYPEOF_TYPE:
+ sorry ("mangling typeof, use decltype instead");
+ break;
+
default:
gcc_unreachable ();
}
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 70a395b2f3c..a7bb710dace 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -1364,11 +1364,6 @@ leave_scope (void)
is_class_level = 0;
}
-#ifdef HANDLE_PRAGMA_VISIBILITY
- if (scope->has_visibility)
- pop_visibility ();
-#endif
-
/* Move one nesting level up. */
current_binding_level = scope->level_chain;
@@ -3027,20 +3022,59 @@ current_decl_namespace (void)
return result;
}
-/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we
- select a name that is unique to this compilation unit. */
+/* Process any ATTRIBUTES on a namespace definition. Currently only
+ attribute visibility is meaningful, which is a property of the syntactic
+ block rather than the namespace as a whole, so we don't touch the
+ NAMESPACE_DECL at all. Returns true if attribute visibility is seen. */
-void
-push_namespace (tree name)
+bool
+handle_namespace_attrs (tree ns, tree attributes)
{
- push_namespace_with_attribs (name, NULL_TREE);
-}
+ tree d;
+ bool saw_vis = false;
+
+ for (d = attributes; d; d = TREE_CHAIN (d))
+ {
+ tree name = TREE_PURPOSE (d);
+ tree args = TREE_VALUE (d);
+
+#ifdef HANDLE_PRAGMA_VISIBILITY
+ if (is_attribute_p ("visibility", name))
+ {
+ tree x = args ? TREE_VALUE (args) : NULL_TREE;
+ if (x == NULL_TREE || TREE_CODE (x) != STRING_CST || TREE_CHAIN (args))
+ {
+ warning (OPT_Wattributes,
+ "%qD attribute requires a single NTBS argument",
+ name);
+ continue;
+ }
+
+ if (!TREE_PUBLIC (ns))
+ warning (OPT_Wattributes,
+ "%qD attribute is meaningless since members of the "
+ "anonymous namespace get local symbols", name);
+
+ push_visibility (TREE_STRING_POINTER (x));
+ saw_vis = true;
+ }
+ else
+#endif
+ {
+ warning (OPT_Wattributes, "%qD attribute directive ignored",
+ name);
+ continue;
+ }
+ }
-/* Same, but specify attributes to apply to the namespace. The attributes
- only apply to the current namespace-body, not to any later extensions. */
+ return saw_vis;
+}
+
+/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we
+ select a name that is unique to this compilation unit. */
void
-push_namespace_with_attribs (tree name, tree attributes)
+push_namespace (tree name)
{
tree d = NULL_TREE;
int need_new = 1;
@@ -3107,38 +3141,6 @@ push_namespace_with_attribs (tree name, tree attributes)
/* Enter the name space. */
current_namespace = d;
-#ifdef HANDLE_PRAGMA_VISIBILITY
- /* Clear has_visibility in case a previous namespace-definition had a
- visibility attribute and this one doesn't. */
- current_binding_level->has_visibility = 0;
- for (d = attributes; d; d = TREE_CHAIN (d))
- {
- tree name = TREE_PURPOSE (d);
- tree args = TREE_VALUE (d);
- tree x;
-
- if (! is_attribute_p ("visibility", name))
- {
- warning (OPT_Wattributes, "%qs attribute directive ignored",
- IDENTIFIER_POINTER (name));
- continue;
- }
-
- x = args ? TREE_VALUE (args) : NULL_TREE;
- if (x == NULL_TREE || TREE_CODE (x) != STRING_CST || TREE_CHAIN (args))
- {
- warning (OPT_Wattributes, "%qs attribute requires a single NTBS argument",
- IDENTIFIER_POINTER (name));
- continue;
- }
-
- current_binding_level->has_visibility = 1;
- push_visibility (TREE_STRING_POINTER (x));
- goto found;
- }
- found:
-#endif
-
timevar_pop (TV_NAME_LOOKUP);
}
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 88551f2b8ac..7da57be9f1f 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -255,11 +255,7 @@ struct cp_binding_level GTY(())
unsigned more_cleanups_ok : 1;
unsigned have_cleanups : 1;
- /* Nonzero if this level has associated visibility which we should pop
- when leaving the scope. */
- unsigned has_visibility : 1;
-
- /* 23 bits left to fill a 32-bit word. */
+ /* 24 bits left to fill a 32-bit word. */
};
/* The binding level currently in effect. */
@@ -307,10 +303,10 @@ extern void pop_inner_scope (tree, tree);
extern void push_binding_level (struct cp_binding_level *);
extern void push_namespace (tree);
-extern void push_namespace_with_attribs (tree, tree);
extern void pop_namespace (void);
extern void push_nested_namespace (tree);
extern void pop_nested_namespace (tree);
+extern bool handle_namespace_attrs (tree, tree);
extern void pushlevel_class (void);
extern void poplevel_class (void);
extern tree pushdecl_with_scope (tree, cxx_scope *, bool);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index ede0d7e3244..3720b5567a5 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -11475,6 +11475,7 @@ static void
cp_parser_namespace_definition (cp_parser* parser)
{
tree identifier, attribs;
+ bool has_visibility;
/* Look for the `namespace' keyword. */
cp_parser_require_keyword (parser, RID_NAMESPACE, "`namespace'");
@@ -11494,9 +11495,18 @@ cp_parser_namespace_definition (cp_parser* parser)
/* Look for the `{' to start the namespace. */
cp_parser_require (parser, CPP_OPEN_BRACE, "`{'");
/* Start the namespace. */
- push_namespace_with_attribs (identifier, attribs);
+ push_namespace (identifier);
+
+ has_visibility = handle_namespace_attrs (current_namespace, attribs);
+
/* Parse the body of the namespace. */
cp_parser_namespace_body (parser);
+
+#ifdef HANDLE_PRAGMA_VISIBILITY
+ if (has_visibility)
+ pop_visibility ();
+#endif
+
/* Finish the namespace. */
pop_namespace ();
/* Look for the final `}'. */
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 53e22023f27..adbe9de7541 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -703,8 +703,23 @@ digest_init (tree type, tree init)
/* Handle scalar types (including conversions) and references. */
if (TREE_CODE (type) != COMPLEX_TYPE
&& (SCALAR_TYPE_P (type) || code == REFERENCE_TYPE))
- return convert_for_initialization (0, type, init, LOOKUP_NORMAL,
- "initialization", NULL_TREE, 0);
+ {
+ tree *exp;
+
+ init = convert_for_initialization (0, type, init, LOOKUP_NORMAL,
+ "initialization", NULL_TREE, 0);
+ exp = &init;
+
+ /* Skip any conversions since we'll be outputting the underlying
+ constant. */
+ while (TREE_CODE (*exp) == NOP_EXPR || TREE_CODE (*exp) == CONVERT_EXPR
+ || TREE_CODE (*exp) == NON_LVALUE_EXPR)
+ exp = &TREE_OPERAND (*exp, 0);
+
+ *exp = cplus_expand_constant (*exp);
+
+ return init;
+ }
/* Come here only for aggregates: records, arrays, unions, complex numbers
and vectors. */
diff --git a/gcc/dce.c b/gcc/dce.c
index 7e02e215263..1021e991cff 100644
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -78,7 +78,7 @@ deletable_insn_p_1 (rtx body)
return false;
default:
- if (volatile_insn_p (body))
+ if (volatile_refs_p (body))
return false;
if (flag_non_call_exceptions && may_trap_p (body))
@@ -574,8 +574,8 @@ dce_process_block (basic_block bb, bool redo_out)
/* These regs are considered always live so if they end up dying
because of some def, we need to bring the back again.
Calling df_simulate_fixup_sets has the disadvantage of calling
- df_has_eh_preds once per insn, so we cache the information here. */
- if (df_has_eh_preds (bb))
+ bb_has_eh_pred once per insn, so we cache the information here. */
+ if (bb_has_eh_pred (bb))
au = df->eh_block_artificial_uses;
else
au = df->regular_block_artificial_uses;
diff --git a/gcc/df-problems.c b/gcc/df-problems.c
index 79e09ce4ae1..818f7f103b1 100644
--- a/gcc/df-problems.c
+++ b/gcc/df-problems.c
@@ -71,9 +71,7 @@ df_get_live_out (basic_block bb)
{
gcc_assert (df_lr);
- if (df_urec)
- return DF_RA_LIVE_OUT (bb);
- else if (df_live)
+ if (df_live)
return DF_LIVE_OUT (bb);
else
return DF_LR_OUT (bb);
@@ -89,31 +87,12 @@ df_get_live_in (basic_block bb)
{
gcc_assert (df_lr);
- if (df_urec)
- return DF_RA_LIVE_IN (bb);
- else if (df_live)
+ if (df_live)
return DF_LIVE_IN (bb);
else
return DF_LR_IN (bb);
}
-/* Get the live at top set for BB no matter what problem happens to be
- defined. This function is used by the register allocators who
- choose different dataflow problems depending on the optimization
- level. */
-
-bitmap
-df_get_live_top (basic_block bb)
-{
- gcc_assert (df_lr);
-
- if (df_urec)
- return DF_RA_LIVE_TOP (bb);
- else
- return DF_LR_TOP (bb);
-}
-
-
/*----------------------------------------------------------------------------
Utility functions.
----------------------------------------------------------------------------*/
@@ -210,9 +189,28 @@ df_unset_seen (void)
See df.h for details.
----------------------------------------------------------------------------*/
-/* See the comment at the top of the Reaching Uses problem for how the
- uses are represented in the kill sets. The same games are played
- here for the defs. */
+/* This problem plays a large number of games for the sake of
+ efficiency.
+
+ 1) The order of the bits in the bitvectors. After the scanning
+ phase, all of the defs are sorted. All of the defs for the reg 0
+ are first, followed by all defs for reg 1 and so on.
+
+ 2) There are two kill sets, one if the number of defs is less or
+ equal to DF_SPARSE_THRESHOLD and another if the number of defs is
+ greater.
+
+ <= : Data is built directly in the kill set.
+
+ > : One level of indirection is used to keep from generating long
+ strings of 1 bits in the kill sets. Bitvectors that are indexed
+ by the regnum are used to represent that there is a killing def
+ for the register. The confluence and transfer functions use
+ these along with the bitmap_clear_range call to remove ranges of
+ bits without actually generating a knockout vector.
+
+ The kill and sparse_kill and the dense_invalidated_by_call and
+ sparse_invalidated_by_call both play this game. */
/* Private data used to compute the solution for this problem. These
data structures are not accessible outside of this module. */
@@ -740,14 +738,6 @@ df_lr_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
{
BITMAP_FREE (bb_info->use);
BITMAP_FREE (bb_info->def);
- if (bb_info->in == bb_info->top)
- bb_info->top = NULL;
- else
- {
- BITMAP_FREE (bb_info->top);
- BITMAP_FREE (bb_info->ause);
- BITMAP_FREE (bb_info->adef);
- }
BITMAP_FREE (bb_info->in);
BITMAP_FREE (bb_info->out);
pool_free (df_lr->block_pool, bb_info);
@@ -777,11 +767,6 @@ df_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
{
bitmap_clear (bb_info->def);
bitmap_clear (bb_info->use);
- if (bb_info->adef)
- {
- bitmap_clear (bb_info->adef);
- bitmap_clear (bb_info->ause);
- }
}
else
{
@@ -791,9 +776,6 @@ df_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
bb_info->def = BITMAP_ALLOC (NULL);
bb_info->in = BITMAP_ALLOC (NULL);
bb_info->out = BITMAP_ALLOC (NULL);
- bb_info->top = bb_info->in;
- bb_info->adef = NULL;
- bb_info->ause = NULL;
}
}
@@ -815,7 +797,6 @@ df_lr_reset (bitmap all_blocks)
gcc_assert (bb_info);
bitmap_clear (bb_info->in);
bitmap_clear (bb_info->out);
- bitmap_clear (bb_info->top);
}
}
@@ -879,23 +860,18 @@ df_lr_bb_local_compute (unsigned int bb_index)
bitmap_set_bit (bb_info->use, DF_REF_REGNO (use));
}
}
- /* Process the registers set in an exception handler. */
+
+ /* Process the registers set in an exception handler or the hard
+ frame pointer if this block is the target of a non local
+ goto. */
for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
{
struct df_ref *def = *def_rec;
- if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP)
- && (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))))
+ if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
{
unsigned int dregno = DF_REF_REGNO (def);
- if (bb_info->adef == NULL)
- {
- gcc_assert (bb_info->ause == NULL);
- gcc_assert (bb_info->top == bb_info->in);
- bb_info->adef = BITMAP_ALLOC (NULL);
- bb_info->ause = BITMAP_ALLOC (NULL);
- bb_info->top = BITMAP_ALLOC (NULL);
- }
- bitmap_set_bit (bb_info->adef, dregno);
+ bitmap_set_bit (bb_info->def, dregno);
+ bitmap_clear_bit (bb_info->use, dregno);
}
}
@@ -906,17 +882,7 @@ df_lr_bb_local_compute (unsigned int bb_index)
struct df_ref *use = *use_rec;
/* Add use to set of uses in this BB. */
if (DF_REF_FLAGS (use) & DF_REF_AT_TOP)
- {
- if (bb_info->adef == NULL)
- {
- gcc_assert (bb_info->ause == NULL);
- gcc_assert (bb_info->top == bb_info->in);
- bb_info->adef = BITMAP_ALLOC (NULL);
- bb_info->ause = BITMAP_ALLOC (NULL);
- bb_info->top = BITMAP_ALLOC (NULL);
- }
- bitmap_set_bit (bb_info->ause, DF_REF_REGNO (use));
- }
+ bitmap_set_bit (bb_info->use, DF_REF_REGNO (use));
}
#endif
@@ -1041,19 +1007,8 @@ df_lr_transfer_function (int bb_index)
bitmap out = bb_info->out;
bitmap use = bb_info->use;
bitmap def = bb_info->def;
- bitmap top = bb_info->top;
- bitmap ause = bb_info->ause;
- bitmap adef = bb_info->adef;
- bool changed;
-
- changed = bitmap_ior_and_compl (top, use, out, def);
- if (in != top)
- {
- gcc_assert (ause && adef);
- changed |= bitmap_ior_and_compl (in, ause, top, adef);
- }
- return changed;
+ return bitmap_ior_and_compl (in, use, out, def);
}
@@ -1097,14 +1052,6 @@ df_lr_free (void)
{
BITMAP_FREE (bb_info->use);
BITMAP_FREE (bb_info->def);
- if (bb_info->in == bb_info->top)
- bb_info->top = NULL;
- else
- {
- BITMAP_FREE (bb_info->top);
- BITMAP_FREE (bb_info->ause);
- BITMAP_FREE (bb_info->adef);
- }
BITMAP_FREE (bb_info->in);
BITMAP_FREE (bb_info->out);
}
@@ -1297,7 +1244,6 @@ df_lr_verify_transfer_functions (void)
bitmap saved_adef;
bitmap saved_ause;
bitmap all_blocks;
- bool need_as;
if (!df)
return;
@@ -1326,33 +1272,9 @@ df_lr_verify_transfer_functions (void)
bitmap_clear (bb_info->def);
bitmap_clear (bb_info->use);
- if (bb_info->adef)
- {
- need_as = true;
- bitmap_copy (saved_adef, bb_info->adef);
- bitmap_copy (saved_ause, bb_info->ause);
- bitmap_clear (bb_info->adef);
- bitmap_clear (bb_info->ause);
- }
- else
- need_as = false;
-
df_lr_bb_local_compute (bb->index);
gcc_assert (bitmap_equal_p (saved_def, bb_info->def));
gcc_assert (bitmap_equal_p (saved_use, bb_info->use));
-
- if (need_as)
- {
- gcc_assert (bb_info->adef);
- gcc_assert (bb_info->ause);
- gcc_assert (bitmap_equal_p (saved_adef, bb_info->adef));
- gcc_assert (bitmap_equal_p (saved_ause, bb_info->ause));
- }
- else
- {
- gcc_assert (!bb_info->adef);
- gcc_assert (!bb_info->ause);
- }
}
}
else
@@ -1633,7 +1555,7 @@ df_live_local_finalize (bitmap all_blocks)
{
struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
struct df_live_bb_info *bb_live_info = df_live_get_bb_info (bb_index);
-
+
/* No register may reach a location where it is not used. Thus
we trim the rr result to the places where it is used. */
bitmap_and_into (bb_live_info->in, bb_lr_info->in);
@@ -1913,615 +1835,6 @@ df_live_verify_transfer_functions (void)
BITMAP_FREE (saved_kill);
BITMAP_FREE (all_blocks);
}
-
-
-
-/*----------------------------------------------------------------------------
- UNINITIALIZED REGISTERS WITH EARLYCLOBBER
-
- Find the set of uses for registers that are reachable from the entry
- block without passing thru a definition. In and out bitvectors are built
- for each basic block. The regnum is used to index into these sets.
- See df.h for details.
-
- This is a variant of the UR problem above that has a lot of special
- features just for the register allocation phase. This problem
- should go away if someone would fix the interference graph.
-
- ----------------------------------------------------------------------------*/
-
-/* Private data used to compute the solution for this problem. These
- data structures are not accessible outside of this module. */
-struct df_urec_problem_data
-{
- bool earlyclobbers_found; /* True if any instruction contains an
- earlyclobber. */
-#ifdef STACK_REGS
- bitmap stack_regs; /* Registers that may be allocated to a STACK_REGS. */
-#endif
-};
-
-
-/* Set basic block info. */
-
-static void
-df_urec_set_bb_info (unsigned int index,
- struct df_urec_bb_info *bb_info)
-{
- gcc_assert (df_urec);
- gcc_assert (index < df_urec->block_info_size);
- df_urec->block_info[index] = bb_info;
-}
-
-
-/* Free basic block info. */
-
-static void
-df_urec_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
- void *vbb_info)
-{
- struct df_urec_bb_info *bb_info = (struct df_urec_bb_info *) vbb_info;
- if (bb_info)
- {
- BITMAP_FREE (bb_info->gen);
- BITMAP_FREE (bb_info->kill);
- BITMAP_FREE (bb_info->in);
- BITMAP_FREE (bb_info->out);
- BITMAP_FREE (bb_info->earlyclobber);
- pool_free (df_urec->block_pool, bb_info);
- }
-}
-
-
-/* Allocate or reset bitmaps for DF_UREC blocks. The solution bits are
- not touched unless the block is new. */
-
-static void
-df_urec_alloc (bitmap all_blocks)
-
-{
- unsigned int bb_index;
- bitmap_iterator bi;
- struct df_urec_problem_data *problem_data
- = (struct df_urec_problem_data *) df_urec->problem_data;
-
- if (!df_urec->block_pool)
- df_urec->block_pool = create_alloc_pool ("df_urec_block pool",
- sizeof (struct df_urec_bb_info), 50);
-
- if (!df_urec->problem_data)
- {
- problem_data = XNEW (struct df_urec_problem_data);
- df_urec->problem_data = problem_data;
- }
- problem_data->earlyclobbers_found = false;
-
- df_grow_bb_info (df_urec);
-
- EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
- {
- struct df_urec_bb_info *bb_info = df_urec_get_bb_info (bb_index);
- if (bb_info)
- {
- bitmap_clear (bb_info->kill);
- bitmap_clear (bb_info->gen);
- bitmap_clear (bb_info->earlyclobber);
- }
- else
- {
- bb_info = (struct df_urec_bb_info *) pool_alloc (df_urec->block_pool);
- df_urec_set_bb_info (bb_index, bb_info);
- bb_info->kill = BITMAP_ALLOC (NULL);
- bb_info->gen = BITMAP_ALLOC (NULL);
- bb_info->in = BITMAP_ALLOC (NULL);
- bb_info->out = BITMAP_ALLOC (NULL);
- bb_info->top = BITMAP_ALLOC (NULL);
- bb_info->earlyclobber = BITMAP_ALLOC (NULL);
- }
- }
- df_urec->optional_p = true;
-}
-
-
-/* The function modifies local info for register REG being changed in
- SETTER. DATA is used to pass the current basic block info. */
-
-static void
-df_urec_mark_reg_change (rtx reg, const_rtx setter, void *data)
-{
- int regno;
- int endregno;
- int i;
- struct df_urec_bb_info *bb_info = (struct df_urec_bb_info*) data;
-
- if (GET_CODE (reg) == SUBREG)
- reg = SUBREG_REG (reg);
-
- if (!REG_P (reg))
- return;
-
- regno = REGNO (reg);
- if (regno < FIRST_PSEUDO_REGISTER)
- {
- endregno = END_HARD_REGNO (reg);
- for (i = regno; i < endregno; i++)
- {
- bitmap_set_bit (bb_info->kill, i);
-
- if (GET_CODE (setter) != CLOBBER)
- bitmap_set_bit (bb_info->gen, i);
- else
- bitmap_clear_bit (bb_info->gen, i);
- }
- }
- else
- {
- bitmap_set_bit (bb_info->kill, regno);
-
- if (GET_CODE (setter) != CLOBBER)
- bitmap_set_bit (bb_info->gen, regno);
- else
- bitmap_clear_bit (bb_info->gen, regno);
- }
-}
-/* Classes of registers which could be early clobbered in the current
- insn. */
-
-static VEC(int,heap) *earlyclobber_regclass;
-
-/* This function finds and stores register classes that could be early
- clobbered in INSN. If any earlyclobber classes are found, the function
- returns TRUE, in all other cases it returns FALSE. */
-
-static bool
-df_urec_check_earlyclobber (rtx insn)
-{
- int opno;
- bool found = false;
-
- extract_insn (insn);
-
- VEC_truncate (int, earlyclobber_regclass, 0);
- for (opno = 0; opno < recog_data.n_operands; opno++)
- {
- char c;
- bool amp_p;
- int i;
- enum reg_class class;
- const char *p = recog_data.constraints[opno];
-
- class = NO_REGS;
- amp_p = false;
- for (;;)
- {
- c = *p;
- switch (c)
- {
- case '=': case '+': case '?':
- case '#': case '!':
- case '*': case '%':
- case 'm': case '<': case '>': case 'V': case 'o':
- case 'E': case 'F': case 'G': case 'H':
- case 's': case 'i': case 'n':
- case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P':
- case 'X':
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- /* These don't say anything we care about. */
- break;
-
- case '&':
- amp_p = true;
- break;
- case '\0':
- case ',':
- if (amp_p && class != NO_REGS)
- {
- int rc;
-
- found = true;
- for (i = 0;
- VEC_iterate (int, earlyclobber_regclass, i, rc);
- i++)
- {
- if (rc == (int) class)
- goto found_rc;
- }
-
- /* We use VEC_quick_push here because
- earlyclobber_regclass holds no more than
- N_REG_CLASSES elements. */
- VEC_quick_push (int, earlyclobber_regclass, (int) class);
- found_rc:
- ;
- }
-
- amp_p = false;
- class = NO_REGS;
- break;
-
- case 'r':
- class = GENERAL_REGS;
- break;
-
- default:
- class = REG_CLASS_FROM_CONSTRAINT (c, p);
- break;
- }
- if (c == '\0')
- break;
- p += CONSTRAINT_LEN (c, p);
- }
- }
-
- return found;
-}
-
-/* The function checks that pseudo-register *X has a class
- intersecting with the class of pseudo-register could be early
- clobbered in the same insn.
-
- This function is a no-op if earlyclobber_regclass is empty.
-
- Reload can assign the same hard register to uninitialized
- pseudo-register and early clobbered pseudo-register in an insn if
- the pseudo-register is used first time in given BB and not lived at
- the BB start. To prevent this we don't change life information for
- such pseudo-registers. */
-
-static int
-df_urec_mark_reg_use_for_earlyclobber (rtx *x, void *data)
-{
- enum reg_class pref_class, alt_class;
- int i, regno;
- struct df_urec_bb_info *bb_info = (struct df_urec_bb_info*) data;
-
- if (REG_P (*x) && REGNO (*x) >= FIRST_PSEUDO_REGISTER)
- {
- int rc;
-
- regno = REGNO (*x);
- if (bitmap_bit_p (bb_info->kill, regno)
- || bitmap_bit_p (bb_info->gen, regno))
- return 0;
- pref_class = reg_preferred_class (regno);
- alt_class = reg_alternate_class (regno);
- for (i = 0; VEC_iterate (int, earlyclobber_regclass, i, rc); i++)
- {
- if (reg_classes_intersect_p (rc, pref_class)
- || (rc != NO_REGS
- && reg_classes_intersect_p (rc, alt_class)))
- {
- bitmap_set_bit (bb_info->earlyclobber, regno);
- break;
- }
- }
- }
- return 0;
-}
-
-/* The function processes all pseudo-registers in *X with the aid of
- previous function. */
-
-static void
-df_urec_mark_reg_use_for_earlyclobber_1 (rtx *x, void *data)
-{
- for_each_rtx (x, df_urec_mark_reg_use_for_earlyclobber, data);
-}
-
-
-/* Compute local uninitialized register info for basic block BB. */
-
-static void
-df_urec_bb_local_compute (unsigned int bb_index)
-{
- basic_block bb = BASIC_BLOCK (bb_index);
- struct df_urec_bb_info *bb_info = df_urec_get_bb_info (bb_index);
- rtx insn;
- struct df_ref **def_rec;
-
- for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
- {
- struct df_ref *def = *def_rec;
- if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
- {
- unsigned int regno = DF_REF_REGNO (def);
- bitmap_set_bit (bb_info->gen, regno);
- }
- }
-
- FOR_BB_INSNS (bb, insn)
- {
- if (INSN_P (insn))
- {
- note_stores (PATTERN (insn), df_urec_mark_reg_change, bb_info);
- if (df_urec_check_earlyclobber (insn))
- {
- struct df_urec_problem_data *problem_data
- = (struct df_urec_problem_data *) df_urec->problem_data;
- problem_data->earlyclobbers_found = true;
- note_uses (&PATTERN (insn),
- df_urec_mark_reg_use_for_earlyclobber_1, bb_info);
- }
- }
- }
-
- for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
- {
- struct df_ref *def = *def_rec;
- if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
- {
- unsigned int regno = DF_REF_REGNO (def);
- bitmap_set_bit (bb_info->gen, regno);
- }
- }
-}
-
-
-/* Compute local uninitialized register info. */
-
-static void
-df_urec_local_compute (bitmap all_blocks)
-{
- unsigned int bb_index;
- bitmap_iterator bi;
-#ifdef STACK_REGS
- int i;
- HARD_REG_SET stack_hard_regs, used;
- struct df_urec_problem_data *problem_data
- = (struct df_urec_problem_data *) df_urec->problem_data;
-
- /* Any register that MAY be allocated to a register stack (like the
- 387) is treated poorly. Each such register is marked as being
- live everywhere. This keeps the register allocator and the
- subsequent passes from doing anything useful with these values.
-
- FIXME: This seems like an incredibly poor idea. */
-
- CLEAR_HARD_REG_SET (stack_hard_regs);
- for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
- SET_HARD_REG_BIT (stack_hard_regs, i);
- problem_data->stack_regs = BITMAP_ALLOC (NULL);
- for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
- {
- COPY_HARD_REG_SET (used, reg_class_contents[reg_preferred_class (i)]);
- IOR_HARD_REG_SET (used, reg_class_contents[reg_alternate_class (i)]);
- AND_HARD_REG_SET (used, stack_hard_regs);
- if (!hard_reg_set_empty_p (used))
- bitmap_set_bit (problem_data->stack_regs, i);
- }
-#endif
-
- /* We know that earlyclobber_regclass holds no more than
- N_REG_CLASSES elements. See df_urec_check_earlyclobber. */
- earlyclobber_regclass = VEC_alloc (int, heap, N_REG_CLASSES);
-
- EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
- {
- df_urec_bb_local_compute (bb_index);
- }
-
- VEC_free (int, heap, earlyclobber_regclass);
-}
-
-
-/* Initialize the solution vectors. */
-
-static void
-df_urec_init (bitmap all_blocks)
-{
- unsigned int bb_index;
- bitmap_iterator bi;
-
- EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
- {
- struct df_urec_bb_info *bb_info = df_urec_get_bb_info (bb_index);
-
- bitmap_copy (bb_info->out, bb_info->gen);
- bitmap_clear (bb_info->in);
- }
-}
-
-
-/* Or in the stack regs, hard regs and early clobber regs into the
- urec_in sets of all of the blocks. */
-
-
-static void
-df_urec_local_finalize (bitmap all_blocks)
-{
- bitmap tmp = BITMAP_ALLOC (NULL);
- bitmap_iterator bi;
- unsigned int bb_index;
- struct df_urec_problem_data *problem_data
- = (struct df_urec_problem_data *) df_urec->problem_data;
-
- EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
- {
- struct df_urec_bb_info *bb_info = df_urec_get_bb_info (bb_index);
- struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
-
- if (bb_index != ENTRY_BLOCK && bb_index != EXIT_BLOCK)
- {
- if (problem_data->earlyclobbers_found)
- bitmap_ior_into (bb_info->in, bb_info->earlyclobber);
-
-#ifdef STACK_REGS
- /* We can not use the same stack register for uninitialized
- pseudo-register and another living pseudo-register
- because if the uninitialized pseudo-register dies,
- subsequent pass reg-stack will be confused (it will
- believe that the other register dies). */
- bitmap_ior_into (bb_info->in, problem_data->stack_regs);
- bitmap_ior_into (bb_info->out, problem_data->stack_regs);
-#endif
- }
-
- /* No register may reach a location where it is not used. Thus
- we trim the rr result to the places where it is used. */
- bitmap_and_into (bb_info->in, bb_lr_info->in);
- bitmap_and_into (bb_info->out, bb_lr_info->out);
- bitmap_copy (bb_info->top, bb_info->in);
- if (bb_lr_info->adef)
- bitmap_ior_into (bb_info->top, bb_lr_info->adef);
- bitmap_and_into (bb_info->top, bb_lr_info->top);
-#if 0
- /* Hard registers may still stick in the ur_out set, but not
- be in the ur_in set, if their only mention was in a call
- in this block. This is because a call kills in the lr
- problem but does not kill in the rr problem. To clean
- this up, we execute the transfer function on the lr_in
- set and then use that to knock bits out of ur_out. */
- bitmap_ior_and_compl (tmp, bb_info->gen, bb_lr_info->in,
- bb_info->kill);
- bitmap_and_into (bb_info->out, tmp);
-#endif
- }
-
-#ifdef STACK_REGS
- BITMAP_FREE (problem_data->stack_regs);
-#endif
- BITMAP_FREE (tmp);
-}
-
-
-/* Confluence function that ignores fake edges. */
-
-static void
-df_urec_confluence_n (edge e)
-{
- bitmap op1 = df_urec_get_bb_info (e->dest->index)->in;
- bitmap op2 = df_urec_get_bb_info (e->src->index)->out;
-
- if (e->flags & EDGE_FAKE)
- return;
-
- bitmap_ior_into (op1, op2);
-}
-
-
-/* Transfer function. */
-
-static bool
-df_urec_transfer_function (int bb_index)
-{
- struct df_urec_bb_info *bb_info = df_urec_get_bb_info (bb_index);
- bitmap in = bb_info->in;
- bitmap out = bb_info->out;
- bitmap gen = bb_info->gen;
- bitmap kill = bb_info->kill;
-
- return bitmap_ior_and_compl (out, gen, in, kill);
-}
-
-
-/* Free all storage associated with the problem. */
-
-static void
-df_urec_free (void)
-{
- if (df_urec->block_info)
- {
- unsigned int i;
-
- for (i = 0; i < df_urec->block_info_size; i++)
- {
- struct df_urec_bb_info *bb_info = df_urec_get_bb_info (i);
- if (bb_info)
- {
- BITMAP_FREE (bb_info->gen);
- BITMAP_FREE (bb_info->kill);
- BITMAP_FREE (bb_info->in);
- BITMAP_FREE (bb_info->out);
- BITMAP_FREE (bb_info->earlyclobber);
- BITMAP_FREE (bb_info->top);
- }
- }
-
- free_alloc_pool (df_urec->block_pool);
-
- df_urec->block_info_size = 0;
- free (df_urec->block_info);
- free (df_urec->problem_data);
- }
- free (df_urec);
-}
-
-
-/* Debugging info at top of bb. */
-
-static void
-df_urec_top_dump (basic_block bb, FILE *file)
-{
- struct df_urec_bb_info *bb_info = df_urec_get_bb_info (bb->index);
- if (!bb_info || !bb_info->in)
- return;
-
- fprintf (file, ";; urec in \t");
- df_print_regset (file, bb_info->in);
- fprintf (file, ";; urec gen \t");
- df_print_regset (file, bb_info->gen);
- fprintf (file, ";; urec kill\t");
- df_print_regset (file, bb_info->kill);
- fprintf (file, ";; urec ec\t");
- df_print_regset (file, bb_info->earlyclobber);
-}
-
-
-/* Debugging info at bottom of bb. */
-
-static void
-df_urec_bottom_dump (basic_block bb, FILE *file)
-{
- struct df_urec_bb_info *bb_info = df_urec_get_bb_info (bb->index);
- if (!bb_info || !bb_info->out)
- return;
- fprintf (file, ";; urec out \t");
- df_print_regset (file, bb_info->out);
-}
-
-
-/* All of the information associated with every instance of the problem. */
-
-static struct df_problem problem_UREC =
-{
- DF_UREC, /* Problem id. */
- DF_FORWARD, /* Direction. */
- df_urec_alloc, /* Allocate the problem specific data. */
- NULL, /* Reset global information. */
- df_urec_free_bb_info, /* Free basic block info. */
- df_urec_local_compute, /* Local compute function. */
- df_urec_init, /* Init the solution specific data. */
- df_worklist_dataflow, /* Worklist solver. */
- NULL, /* Confluence operator 0. */
- df_urec_confluence_n, /* Confluence operator n. */
- df_urec_transfer_function, /* Transfer function. */
- df_urec_local_finalize, /* Finalize function. */
- df_urec_free, /* Free all of the problem information. */
- df_urec_free, /* Remove this problem from the stack of dataflow problems. */
- NULL, /* Debugging. */
- df_urec_top_dump, /* Debugging start block. */
- df_urec_bottom_dump, /* Debugging end block. */
- NULL, /* Incremental solution verify start. */
- NULL, /* Incremental solution verify end. */
- &problem_LR, /* Dependent problem. */
- TV_DF_UREC, /* Timing variable. */
- false /* Reset blocks on dropping out of blocks_to_analyze. */
-};
-
-
-/* Create a new DATAFLOW instance and add it to an existing instance
- of DF. The returned structure is what is used to get at the
- solution. */
-
-void
-df_urec_add_problem (void)
-{
- df_add_problem (&problem_UREC);
-}
-
-
/*----------------------------------------------------------------------------
CREATE DEF_USE (DU) and / or USE_DEF (UD) CHAINS
@@ -3750,7 +3063,7 @@ df_simulate_fixup_sets (basic_block bb, bitmap live)
{
/* These regs are considered always live so if they end up dying
because of some def, we need to bring the back again. */
- if (df_has_eh_preds (bb))
+ if (bb_has_eh_pred (bb))
bitmap_ior_into (live, df->eh_block_artificial_uses);
else
bitmap_ior_into (live, df->regular_block_artificial_uses);
diff --git a/gcc/df-scan.c b/gcc/df-scan.c
index 0b77e691fd8..a762bcfd1db 100644
--- a/gcc/df-scan.c
+++ b/gcc/df-scan.c
@@ -2772,23 +2772,37 @@ df_def_record_1 (struct df_collection_rec *collection_rec,
|| GET_CODE (dst) == ZERO_EXTRACT)
{
flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL;
+ if (GET_CODE (dst) == ZERO_EXTRACT)
+ flags |= DF_REF_EXTRACT;
+ else
+ flags |= DF_REF_STRICT_LOWER_PART;
+
loc = &XEXP (dst, 0);
dst = *loc;
}
- if (df_read_modify_subreg_p (dst))
- flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL;
+ /* At this point if we do not have a reg or a subreg, just return. */
+ if (REG_P (dst))
+ {
+ df_ref_record (collection_rec,
+ dst, loc, bb, insn, DF_REF_REG_DEF, flags);
- if (REG_P (dst)
- || (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst))))
- df_ref_record (collection_rec,
- dst, loc, bb, insn, DF_REF_REG_DEF, flags);
+ /* We want to keep sp alive everywhere - by making all
+ writes to sp also use of sp. */
+ if (REGNO (dst) == STACK_POINTER_REGNUM)
+ df_ref_record (collection_rec,
+ dst, NULL, bb, insn, DF_REF_REG_USE, flags);
+ }
+ else if (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst)))
+ {
+ if (df_read_modify_subreg_p (dst))
+ flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL;
- /* We want to keep sp alive everywhere - by making all
- writes to sp also use of sp. */
- if (REG_P (dst) && REGNO (dst) == STACK_POINTER_REGNUM)
- df_ref_record (collection_rec,
- dst, NULL, bb, insn, DF_REF_REG_USE, flags);
+ flags |= DF_REF_SUBREG;
+
+ df_ref_record (collection_rec,
+ dst, loc, bb, insn, DF_REF_REG_DEF, flags);
+ }
}
@@ -2900,7 +2914,8 @@ df_uses_record (struct df_collection_rec *collection_rec,
if (df_read_modify_subreg_p (dst))
{
df_uses_record (collection_rec, &SUBREG_REG (dst),
- DF_REF_REG_USE, bb, insn, flags | DF_REF_READ_WRITE);
+ DF_REF_REG_USE, bb, insn,
+ flags | DF_REF_READ_WRITE | DF_REF_SUBREG);
break;
}
/* Fall through. */
@@ -2922,13 +2937,15 @@ df_uses_record (struct df_collection_rec *collection_rec,
dst = XEXP (dst, 0);
df_uses_record (collection_rec,
(GET_CODE (dst) == SUBREG) ? &SUBREG_REG (dst) : temp,
- DF_REF_REG_USE, bb, insn, DF_REF_READ_WRITE);
+ DF_REF_REG_USE, bb, insn,
+ DF_REF_READ_WRITE | DF_REF_STRICT_LOWER_PART);
}
break;
case ZERO_EXTRACT:
case SIGN_EXTRACT:
df_uses_record (collection_rec, &XEXP (dst, 0),
- DF_REF_REG_USE, bb, insn, DF_REF_READ_WRITE);
+ DF_REF_REG_USE, bb, insn,
+ DF_REF_READ_WRITE | DF_REF_EXTRACT);
df_uses_record (collection_rec, &XEXP (dst, 1),
DF_REF_REG_USE, bb, insn, flags);
df_uses_record (collection_rec, &XEXP (dst, 2),
@@ -3207,23 +3224,6 @@ df_insn_refs_collect (struct df_collection_rec* collection_rec,
df_canonize_collection_rec (collection_rec);
}
-/* Return true if any pred of BB is an eh. */
-
-bool
-df_has_eh_preds (basic_block bb)
-{
- edge e;
- edge_iterator ei;
-
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- if (e->flags & EDGE_EH)
- return true;
- }
- return false;
-}
-
-
/* Recompute the luids for the insns in BB. */
void
@@ -3288,7 +3288,7 @@ df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb)
}
#ifdef EH_RETURN_DATA_REGNO
- if (df_has_eh_preds (bb))
+ if (bb_has_eh_pred (bb))
{
unsigned int i;
/* Mark the registers that will contain data for the handler. */
@@ -3305,7 +3305,7 @@ df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb)
#ifdef EH_USES
- if (df_has_eh_preds (bb))
+ if (bb_has_eh_pred (bb))
{
unsigned int i;
/* This code is putting in an artificial ref for the use at the
@@ -3337,7 +3337,7 @@ df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb)
{
bitmap_iterator bi;
unsigned int regno;
- bitmap au = df_has_eh_preds (bb)
+ bitmap au = bb_has_eh_pred (bb)
? df->eh_block_artificial_uses
: df->regular_block_artificial_uses;
@@ -3508,8 +3508,6 @@ df_mark_reg (rtx reg, void *vset)
}
-
-
/* Set the bit for regs that are considered being defined at the entry. */
static void
@@ -3807,7 +3805,7 @@ df_exit_block_uses_collect (struct df_collection_rec *collection_rec, bitmap exi
I do not know why. */
if (reload_completed
&& !bitmap_bit_p (exit_block_uses, ARG_POINTER_REGNUM)
- && df_has_eh_preds (EXIT_BLOCK_PTR)
+ && bb_has_eh_pred (EXIT_BLOCK_PTR)
&& fixed_regs[ARG_POINTER_REGNUM])
df_ref_record (collection_rec, regno_reg_rtx[ARG_POINTER_REGNUM], NULL,
EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0);
diff --git a/gcc/df.h b/gcc/df.h
index b129d45c3fa..1fbf121be7b 100644
--- a/gcc/df.h
+++ b/gcc/df.h
@@ -43,11 +43,9 @@ struct df_link;
#define DF_SCAN 0
#define DF_LR 1 /* Live Registers backward. */
#define DF_LIVE 2 /* Live Registers & Uninitialized Registers */
-
#define DF_RD 3 /* Reaching Defs. */
-#define DF_UREC 4 /* Uninitialized Registers with Early Clobber. */
-#define DF_CHAIN 5 /* Def-Use and/or Use-Def Chains. */
-#define DF_NOTE 6 /* REG_DEF and REG_UNUSED notes. */
+#define DF_CHAIN 4 /* Def-Use and/or Use-Def Chains. */
+#define DF_NOTE 5 /* REG_DEF and REG_UNUSED notes. */
#define DF_LAST_PROBLEM_PLUS1 (DF_NOTE + 1)
@@ -70,10 +68,9 @@ enum df_ref_type {DF_REF_REG_DEF, DF_REF_REG_USE, DF_REF_REG_MEM_LOAD,
enum df_ref_flags
{
- /* Read-modify-write refs generate both a use and a def and
- these are marked with this flag to show that they are not
- independent. */
- DF_REF_READ_WRITE = 1 << 0,
+ /* This flag is set if this ref occurs inside of a conditional
+ execution instruction. */
+ DF_REF_CONDITIONAL = 1 << 0,
/* If this flag is set for an artificial use or def, that ref
logically happens at the top of the block. If it is not set
@@ -85,14 +82,26 @@ enum df_ref_flags
note. */
DF_REF_IN_NOTE = 1 << 2,
+ /* This bit is true if this ref can make regs_ever_live true for
+ this regno. */
+ DF_HARD_REG_LIVE = 1 << 3,
+
+
+ /* This flag is set if this ref is a partial use or def of the
+ associated register. */
+ DF_REF_PARTIAL = 1 << 4,
+
+ /* Read-modify-write refs generate both a use and a def and
+ these are marked with this flag to show that they are not
+ independent. */
+ DF_REF_READ_WRITE = 1 << 5,
+
/* This flag is set if this ref, generally a def, may clobber the
referenced register. This is generally only set for hard
registers that cross a call site. With better information
about calls, some of these could be changed in the future to
DF_REF_MUST_CLOBBER. */
- DF_REF_MAY_CLOBBER = 1 << 3,
-
-
+ DF_REF_MAY_CLOBBER = 1 << 6,
/* This flag is set if this ref, generally a def, is a real
clobber. This is not currently set for registers live across a
@@ -103,34 +112,31 @@ enum df_ref_flags
clobber is to a subreg. So in order to tell if the clobber
wipes out the entire register, it is necessary to also check
the DF_REF_PARTIAL flag. */
- DF_REF_MUST_CLOBBER = 1 << 4,
+ DF_REF_MUST_CLOBBER = 1 << 7,
- /* This bit is true if this ref is part of a multiword hardreg. */
- DF_REF_MW_HARDREG = 1 << 5,
- /* This flag is set if this ref is a partial use or def of the
- associated register. */
- DF_REF_PARTIAL = 1 << 6,
-
- /* This flag is set if this ref occurs inside of a conditional
- execution instruction. */
- DF_REF_CONDITIONAL = 1 << 7,
+ /* This flag is set if this ref is inside a pre/post modify. */
+ DF_REF_PRE_POST_MODIFY = 1 << 8,
+ /* This flag is set if the ref contains a ZERO_EXTRACT or SIGN_EXTRACT. */
+ DF_REF_EXTRACT = 1 << 9,
+ /* This flag is set if the ref contains a STRICT_LOWER_PART. */
+ DF_REF_STRICT_LOWER_PART = 1 << 10,
- /* This flag is set if this ref is inside a pre/post modify. */
- DF_REF_PRE_POST_MODIFY = 1 << 8,
+ /* This flag is set if the ref contains a SUBREG. */
+ DF_REF_SUBREG = 1 << 11,
+
+
+ /* This bit is true if this ref is part of a multiword hardreg. */
+ DF_REF_MW_HARDREG = 1 << 12,
/* This flag is set if this ref is a usage of the stack pointer by
a function call. */
- DF_REF_CALL_STACK_USAGE = 1 << 9,
+ DF_REF_CALL_STACK_USAGE = 1 << 13,
/* This flag is used for verification of existing refs. */
- DF_REF_REG_MARKER = 1 << 10,
-
- /* This bit is true if this ref can make regs_ever_live true for
- this regno. */
- DF_HARD_REG_LIVE = 1 << 11
+ DF_REF_REG_MARKER = 1 << 14
};
/* The possible ordering of refs within the df_ref_info. */
@@ -544,7 +550,6 @@ struct df
#define DF_SCAN_BB_INFO(BB) (df_scan_get_bb_info((BB)->index))
#define DF_RD_BB_INFO(BB) (df_rd_get_bb_info((BB)->index))
#define DF_LR_BB_INFO(BB) (df_lr_get_bb_info((BB)->index))
-#define DF_UREC_BB_INFO(BB) (df_urec_get_bb_info((BB)->index))
#define DF_LIVE_BB_INFO(BB) (df_live_get_bb_info((BB)->index))
/* Most transformations that wish to use live register analysis will
@@ -552,17 +557,10 @@ struct df
#define DF_LIVE_IN(BB) (DF_LIVE_BB_INFO(BB)->in)
#define DF_LIVE_OUT(BB) (DF_LIVE_BB_INFO(BB)->out)
-
-/* Live in for register allocation also takes into account several other factors. */
-#define DF_RA_LIVE_IN(BB) (DF_UREC_BB_INFO(BB)->in)
-#define DF_RA_LIVE_TOP(BB) (DF_UREC_BB_INFO(BB)->top)
-#define DF_RA_LIVE_OUT(BB) (DF_UREC_BB_INFO(BB)->out)
-
/* These macros are currently used by only reg-stack since it is not
tolerant of uninitialized variables. This intolerance should be
fixed because it causes other problems. */
#define DF_LR_IN(BB) (DF_LR_BB_INFO(BB)->in)
-#define DF_LR_TOP(BB) (DF_LR_BB_INFO(BB)->top)
#define DF_LR_OUT(BB) (DF_LR_BB_INFO(BB)->out)
/* Macros to access the elements within the ref structure. */
@@ -685,11 +683,21 @@ extern bitmap df_invalidated_by_call;
/* One of these structures is allocated for every basic block. */
struct df_scan_bb_info
{
- /* Defs at the start of a basic block that is the target of an
- exception edge. */
+ /* The entry block has many artificial defs and these are at the
+ bottom of the block.
+
+ Blocks that are targets of exception edges may have some
+ artificial defs. These are logically located at the top of the
+ block.
+
+ Blocks that are the targets of non-local goto's have the hard
+ frame pointer defined at the top of the block. */
struct df_ref **artificial_defs;
- /* Uses of hard registers that are live at every block. */
+ /* Blocks that are targets of exception edges may have some
+ artificial uses. These are logically at the top of the block.
+
+ Most blocks have artificial uses at the bottom of the block. */
struct df_ref **artificial_uses;
};
@@ -710,23 +718,8 @@ struct df_rd_bb_info
};
-/* Live registers. All bitmaps are referenced by the register number.
-
- df_lr_bb_info:IN is the "in" set of the traditional dataflow sense
- which is the confluence of out sets of all predecessor blocks.
- The difference between IN and TOP is
- due to the artificial defs and uses at the top (DF_REF_TOP)
- (e.g. exception handling dispatch block, which can have
- a few registers defined by the runtime) - which is NOT included
- in the "in" set before this function but is included after.
- For the initial live set of forward scanning, TOP should be used
- instead of IN - otherwise, artificial defs won't be in IN set
- causing the bad transformation. TOP set can not simply be
- the union of IN set and artificial defs at the top,
- because artificial defs might not be used at all,
- in which case those defs are not live at any point
- (except as a dangling def) - hence TOP has to be calculated
- during the LR problem computation and stored in df_lr_bb_info. */
+/* Live registers, a backwards dataflow problem. All bitmaps are
+ referenced by the register number. */
struct df_lr_bb_info
{
@@ -734,12 +727,9 @@ struct df_lr_bb_info
bitmap def; /* The set of registers set in this block
- except artificial defs at the top. */
bitmap use; /* The set of registers used in this block. */
- bitmap adef; /* The artificial defs at top. */
- bitmap ause; /* The artificial uses at top. */
/* The results of the dataflow problem. */
bitmap in; /* Just before the block itself. */
- bitmap top; /* Just before the first insn in the block. */
bitmap out; /* At the bottom of the block. */
};
@@ -761,23 +751,6 @@ struct df_live_bb_info
};
-/* Uninitialized registers. All bitmaps are referenced by the register number. */
-struct df_urec_bb_info
-{
- /* Local sets to describe the basic blocks. */
- bitmap earlyclobber; /* The set of registers that are referenced
- with an early clobber mode. */
- /* Kill and gen are defined as in the UR problem. */
- bitmap kill;
- bitmap gen;
-
- /* The results of the dataflow problem. */
- bitmap in; /* Just before the block. */
- bitmap top; /* Just before the first insn in the block. */
- bitmap out; /* At the bottom of the block. */
-};
-
-
/* This is used for debugging and for the dumpers to find the latest
instance so that the df info can be added to the dumps. This
should not be used by regular code. */
@@ -786,7 +759,6 @@ extern struct df *df;
#define df_rd (df->problems_by_index[DF_RD])
#define df_lr (df->problems_by_index[DF_LR])
#define df_live (df->problems_by_index[DF_LIVE])
-#define df_urec (df->problems_by_index[DF_UREC])
#define df_chain (df->problems_by_index[DF_CHAIN])
#define df_note (df->problems_by_index[DF_NOTE])
@@ -861,7 +833,6 @@ extern void df_chain_unlink (struct df_ref *);
extern void df_chain_copy (struct df_ref *, struct df_link *);
extern bitmap df_get_live_in (basic_block);
extern bitmap df_get_live_out (basic_block);
-extern bitmap df_get_live_top (basic_block);
extern void df_grow_bb_info (struct dataflow *);
extern void df_chain_dump (struct df_link *, FILE *);
extern void df_print_bb_index (basic_block bb, FILE *file);
@@ -871,7 +842,6 @@ extern void df_lr_verify_transfer_functions (void);
extern void df_live_verify_transfer_functions (void);
extern void df_live_add_problem (void);
extern void df_live_set_all_dirty (void);
-extern void df_urec_add_problem (void);
extern void df_chain_add_problem (enum df_chain_flags);
extern void df_note_add_problem (void);
extern void df_simulate_find_defs (rtx, bitmap);
@@ -899,7 +869,6 @@ extern bool df_insn_rescan (rtx);
extern bool df_insn_rescan_debug_internal (rtx);
extern void df_insn_rescan_all (void);
extern void df_process_deferred_rescans (void);
-extern bool df_has_eh_preds (basic_block);
extern void df_recompute_luids (basic_block);
extern void df_insn_change_bb (rtx);
extern void df_maybe_reorganize_use_refs (enum df_ref_order);
@@ -957,16 +926,6 @@ df_live_get_bb_info (unsigned int index)
return NULL;
}
-static inline struct df_urec_bb_info *
-df_urec_get_bb_info (unsigned int index)
-{
- if (index < df_urec->block_info_size)
- return (struct df_urec_bb_info *) df_urec->block_info[index];
- else
- return NULL;
-}
-
-
/* Get the artificial defs for a basic block. */
static inline struct df_ref **
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 59975011528..2ca4dfead58 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -2601,34 +2601,34 @@ enables some language-specific warnings described in @ref{C++ Dialect
Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
@option{-Wall} turns on the following warning flags:
-@gccoptlist{
--Waddress @gol
--Warray-bounds (only with @option{-O2}) @gol
--Wc++0x-compat @gol
--Wchar-subscripts @gol
--Wimplicit-int @gol
--Wimplicit-function-declaration @gol
--Wcomment @gol
--Wformat @gol
--Wmain (only for C/ObjC and unless @option{-ffreestanding}) @gol
--Wmissing-braces @gol
--Wnonnull @gol
--Wparentheses @gol
--Wpointer-sign
--Wreorder @gol
--Wreturn-type @gol
--Wsequence-point @gol
--Wsign-compare (only in C++) @gol
--Wstrict-aliasing @gol
--Wstrict-overflow @gol
--Wswitch @gol
--Wtrigraphs @gol
--Wuninitialized (only with @option{-O1}, @option{-O2} or @option{-O3}) @gol
--Wunknown-pragmas @gol
--Wunused-function @gol
--Wunused-label @gol
--Wunused-value @gol
--Wunused-variable @gol
+
+@gccoptlist{-Waddress @gol
+-Warray-bounds @r{(only with} @option{-O2}@r{)} @gol
+-Wc++0x-compat @gol
+-Wchar-subscripts @gol
+-Wimplicit-int @gol
+-Wimplicit-function-declaration @gol
+-Wcomment @gol
+-Wformat @gol
+-Wmain @r{(only for C/ObjC and unless} @option{-ffreestanding}@r{)} @gol
+-Wmissing-braces @gol
+-Wnonnull @gol
+-Wparentheses @gol
+-Wpointer-sign @gol
+-Wreorder @gol
+-Wreturn-type @gol
+-Wsequence-point @gol
+-Wsign-compare @r{(only in C++)} @gol
+-Wstrict-aliasing @gol
+-Wstrict-overflow @gol
+-Wswitch @gol
+-Wtrigraphs @gol
+-Wuninitialized @r{(only with} @option{-O1}@r{,} @option{-O2} @r{or} @option{-O3}@r{)} @gol
+-Wunknown-pragmas @gol
+-Wunused-function @gol
+-Wunused-label @gol
+-Wunused-value @gol
+-Wunused-variable @gol
}
@item -Wno-import
@@ -6155,6 +6155,7 @@ programs consisting of single file, in combination with option
programs since the functions and variables become local for the whole combined
compilation unit, not for the single source file itself.
+This option is not supported for Fortran programs.
@item -fno-cprop-registers
@opindex fno-cprop-registers
diff --git a/gcc/dse.c b/gcc/dse.c
index 5ac3fee7dff..a400d273992 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -2003,7 +2003,7 @@ scan_insn (bb_info_t bb_info, rtx insn)
/* Assuming that there are sets in these insns, we cannot delete
them. */
if ((GET_CODE (PATTERN (insn)) == CLOBBER)
- || volatile_insn_p (PATTERN (insn))
+ || volatile_refs_p (PATTERN (insn))
|| (flag_non_call_exceptions && may_trap_p (PATTERN (insn)))
|| (RTX_FRAME_RELATED_P (insn))
|| find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX))
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 0b8e6f8b41e..51793352390 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -2662,7 +2662,7 @@ dwarf2out_frame_init (void)
dwarf2out_def_cfa (NULL, STACK_POINTER_REGNUM, INCOMING_FRAME_SP_OFFSET);
#ifdef DWARF2_UNWIND_INFO
- if (DWARF2_UNWIND_INFO)
+ if (DWARF2_UNWIND_INFO || DWARF2_FRAME_INFO)
initial_return_save (INCOMING_RETURN_ADDR_RTX);
#endif
}
@@ -10348,9 +10348,12 @@ reference_to_unused (tree * tp, int * walk_subtrees,
return *tp;
else if (!flag_unit_at_a_time)
return NULL_TREE;
+ /* ??? The C++ FE emits debug information for using decls, so
+ putting gcc_unreachable here falls over. See PR31899. For now
+ be conservative. */
else if (!cgraph_global_info_ready
&& (TREE_CODE (*tp) == VAR_DECL || TREE_CODE (*tp) == FUNCTION_DECL))
- gcc_unreachable ();
+ return *tp;
else if (DECL_P (*tp) && TREE_CODE (*tp) == VAR_DECL)
{
struct varpool_node *node = varpool_node (*tp);
diff --git a/gcc/expr.c b/gcc/expr.c
index 0578cf676f5..de2575fad91 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6740,8 +6740,7 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
/* ??? This should be considered a front-end bug. We should not be
generating ADDR_EXPR of something that isn't an LVALUE. The only
exception here is STRING_CST. */
- if (TREE_CODE (exp) == CONSTRUCTOR
- || CONSTANT_CLASS_P (exp))
+ if (CONSTANT_CLASS_P (exp))
return XEXP (expand_expr_constant (exp, 0, modifier), 0);
/* Everything must be something allowed by is_gimple_addressable. */
@@ -6788,9 +6787,12 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
default:
/* If the object is a DECL, then expand it for its rtl. Don't bypass
expand_expr, as that can have various side effects; LABEL_DECLs for
- example, may not have their DECL_RTL set yet. Assume language
- specific tree nodes can be expanded in some interesting way. */
+ example, may not have their DECL_RTL set yet. Expand the rtl of
+ CONSTRUCTORs too, which should yield a memory reference for the
+ constructor's contents. Assume language specific tree nodes can
+ be expanded in some interesting way. */
if (DECL_P (exp)
+ || TREE_CODE (exp) == CONSTRUCTOR
|| TREE_CODE (exp) >= LAST_AND_UNUSED_TREE_CODE)
{
result = expand_expr (exp, target, tmode,
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 62cbfd11ee0..4a8153cb499 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8128,7 +8128,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
(for integers). Avoid this if the final type is a pointer
since then we sometimes need the inner conversion. Likewise if
the outer has a precision not equal to the size of its mode. */
- if ((((inter_int || inter_ptr) && (inside_int || inside_ptr))
+ if (((inter_int && inside_int)
|| (inter_float && inside_float)
|| (inter_vec && inside_vec))
&& inter_prec >= inside_prec
@@ -8158,7 +8158,6 @@ fold_unary (enum tree_code code, tree type, tree op0)
intermediate and final types differ, or
- the final type is a pointer type and the precisions of the
initial and intermediate types differ.
- - the final type is a pointer type and the initial type not
- the initial type is a pointer to an array and the final type
not. */
if (! inside_float && ! inter_float && ! final_float
@@ -8173,8 +8172,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
&& ! (final_ptr && inside_prec != inter_prec)
&& ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
&& TYPE_MODE (type) == TYPE_MODE (inter_type))
- && final_ptr == inside_ptr
- && ! (inside_ptr
+ && ! (inside_ptr && final_ptr
&& TREE_CODE (TREE_TYPE (inside_type)) == ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
return fold_build1 (code, type, TREE_OPERAND (op0, 0));
@@ -8376,10 +8374,11 @@ fold_unary (enum tree_code code, tree type, tree op0)
if (TREE_CODE (arg0) == INTEGER_CST)
return fold_not_const (arg0, type);
else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
- return TREE_OPERAND (arg0, 0);
+ return TREE_OPERAND (op0, 0);
/* Convert ~ (-A) to A - 1. */
else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
- return fold_build2 (MINUS_EXPR, type, TREE_OPERAND (arg0, 0),
+ return fold_build2 (MINUS_EXPR, type,
+ fold_convert (type, TREE_OPERAND (arg0, 0)),
build_int_cst (type, 1));
/* Convert ~ (A - 1) or ~ (A + -1) to -A. */
else if (INTEGRAL_TYPE_P (type)
@@ -8387,7 +8386,8 @@ fold_unary (enum tree_code code, tree type, tree op0)
&& integer_onep (TREE_OPERAND (arg0, 1)))
|| (TREE_CODE (arg0) == PLUS_EXPR
&& integer_all_onesp (TREE_OPERAND (arg0, 1)))))
- return fold_build1 (NEGATE_EXPR, type, TREE_OPERAND (arg0, 0));
+ return fold_build1 (NEGATE_EXPR, type,
+ fold_convert (type, TREE_OPERAND (arg0, 0)));
/* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify. */
else if (TREE_CODE (arg0) == BIT_XOR_EXPR
&& (tem = fold_unary (BIT_NOT_EXPR, type,
@@ -10128,15 +10128,17 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
}
/* A - (-B) -> A + B */
if (TREE_CODE (arg1) == NEGATE_EXPR)
- return fold_build2 (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0));
+ return fold_build2 (PLUS_EXPR, type, op0,
+ fold_convert (type, TREE_OPERAND (arg1, 0)));
/* (-A) - B -> (-B) - A where B is easily negated and we can swap. */
if (TREE_CODE (arg0) == NEGATE_EXPR
&& (FLOAT_TYPE_P (type)
|| INTEGRAL_TYPE_P (type))
&& negate_expr_p (arg1)
&& reorder_operands_p (arg0, arg1))
- return fold_build2 (MINUS_EXPR, type, negate_expr (arg1),
- TREE_OPERAND (arg0, 0));
+ return fold_build2 (MINUS_EXPR, type,
+ fold_convert (type, negate_expr (arg1)),
+ fold_convert (type, TREE_OPERAND (arg0, 0)));
/* Convert -A - 1 to ~A. */
if (INTEGRAL_TYPE_P (type)
&& TREE_CODE (arg0) == NEGATE_EXPR
@@ -10346,16 +10348,16 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
&& (tem = negate_expr (arg1)) != arg1
&& !TREE_OVERFLOW (tem))
return fold_build2 (MULT_EXPR, type,
- negate_expr (arg0), tem);
+ fold_convert (type, negate_expr (arg0)), tem);
/* (a * (1 << b)) is (a << b) */
if (TREE_CODE (arg1) == LSHIFT_EXPR
&& integer_onep (TREE_OPERAND (arg1, 0)))
- return fold_build2 (LSHIFT_EXPR, type, arg0,
+ return fold_build2 (LSHIFT_EXPR, type, op0,
TREE_OPERAND (arg1, 1));
if (TREE_CODE (arg0) == LSHIFT_EXPR
&& integer_onep (TREE_OPERAND (arg0, 0)))
- return fold_build2 (LSHIFT_EXPR, type, arg1,
+ return fold_build2 (LSHIFT_EXPR, type, op1,
TREE_OPERAND (arg0, 1));
strict_overflow_p = false;
@@ -10891,11 +10893,16 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
if (TREE_CODE (arg0) == BIT_IOR_EXPR
&& TREE_CODE (arg1) == INTEGER_CST
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
- return fold_build2 (BIT_IOR_EXPR, type,
- fold_build2 (BIT_AND_EXPR, type,
- TREE_OPERAND (arg0, 0), arg1),
- fold_build2 (BIT_AND_EXPR, type,
- TREE_OPERAND (arg0, 1), arg1));
+ {
+ tree tmp1 = fold_convert (TREE_TYPE (arg0), arg1);
+ tree tmp2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
+ TREE_OPERAND (arg0, 0), tmp1);
+ tree tmp3 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
+ TREE_OPERAND (arg0, 1), tmp1);
+ return fold_convert (type,
+ fold_build2 (BIT_IOR_EXPR, TREE_TYPE (arg0),
+ tmp2, tmp3));
+ }
/* (X | Y) & Y is (X, Y). */
if (TREE_CODE (arg0) == BIT_IOR_EXPR
@@ -11005,8 +11012,10 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
{
return fold_build1 (BIT_NOT_EXPR, type,
build2 (BIT_IOR_EXPR, type,
- TREE_OPERAND (arg0, 0),
- TREE_OPERAND (arg1, 0)));
+ fold_convert (type,
+ TREE_OPERAND (arg0, 0)),
+ fold_convert (type,
+ TREE_OPERAND (arg1, 0))));
}
/* If arg0 is derived from the address of an object or function, we may
@@ -11542,7 +11551,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
tree tem = build_int_cst (TREE_TYPE (arg1),
GET_MODE_BITSIZE (TYPE_MODE (type)));
tem = const_binop (MINUS_EXPR, tem, arg1, 0);
- return fold_build2 (RROTATE_EXPR, type, arg0, tem);
+ return fold_build2 (RROTATE_EXPR, type, op0, tem);
}
/* If we have a rotate of a bit operation with the rotate count and
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 3f18b8eb3a4..85cb8194db2 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,183 @@
+2007-10-08 Tobias Schlüter <tobi@gcc.gnu.org>
+
+ PR fortran/33689
+ * resolve.c (gfc_resolve_expr): Fix indentation.
+ (resolve_fl_variable_derived): Rename argument.
+ (resolve_fl_variable): Fix case in message. Clarify logic.
+ Correctly simplify array bounds.
+
+2007-10-07 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR libfortran/33683
+ * mathbuiltins.def (GAMMA): Change function name to
+ "tgamma" instad of "gamma".
+
+2007-10-07 Tobias Schlüter <tobi@gcc.gnu.org>
+
+ PR fortran/20851
+ * expr.c (check_inquiry): Typo fix in error message.
+ (check_init_expr): Same * 3.
+ (check_restricted): Verify that no dummy arguments appear in
+ restricted expressions in ELEMENTAL procedures.
+ * resolve.c (resolve_fl_variable): Exchange order of checks to
+ avoid side-effect.
+
+2007-10-06 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR fortran/33609
+ * simplify.c (range_check): Return gfc_bad_expr if incoming expression
+ is NULL.
+
+2007-10-06 Tobias Schlüter <tobi@gcc.gnu.org>
+
+ * simplify.c (gfc_simplify_size): Fix typo.
+
+2007-10-06 Tobias Schlüter <tobi@gcc.gnu.org>
+
+ PR fortran/25076
+ * resolve.c (gfc_find_forall_index): Move towards top,
+ renaming to ...
+ (find_forall_index): ... this. Add check for NULL expr.
+ (resolve_forall_iterators): Verify additional constraint.
+ (resolve_forall): Remove checks obsoleted by new code in
+ resolve_forall_iterators.
+
+2007-10-05 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * gfortran.h (gfc_get_data_variable, gfc_get_data_value,
+ gfc_get_data): Move to decl.c.
+ (global_used): Rename into gfc_global_used.
+ (gfc_formalize_init_value, gfc_get_section_index,
+ gfc_assign_data_value, gfc_assign_data_value_range,
+ gfc_advance_section): Move to data.h.
+ (gfc_set_in_match_data): Remove.
+ * decl.c (gfc_get_data_variable, gfc_get_data_value,
+ gfc_get_data): Move here.
+ (gfc_set_in_match_data): Rename into set_in_match_data.
+ (gfc_match_data): Likewise.
+ (add_global_entry): Rename global_used into gfc_global_used.
+ * data.c: Include data.h.
+ * trans.h (gfc_todo_error): Remove.
+ * trans-array.c (gfc_trans_array_constructor,
+ gfc_conv_ss_startstride, gfc_conv_loop_setup): Change
+ gfc_todo_error into assertions.
+ * resolve.c (resolve_global_procedure): Rename global_used into
+ gfc_global_used.
+ * parse.c (gfc_global_used, parse_module, add_global_procedure,
+ add_global_program): Likewise.
+ * trans-intrinsic.c (gfc_walk_intrinsic_function): Rename
+ global_used into gfc_global_used.
+ * Make-lang.in: Add dependencies on fortran/data.h.
+ * data.h: New file.
+
+2007-10-04 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/33529
+ * decl.c (match_char_kind): New function.
+ (match_char_spec): Use match_char_kind.
+
+2007-10-04 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/33502
+ * scanner.c (gfc_advance_line): Call debug_hooks->end_source_file
+ and debug_hooks->start_source_file when appropriate, and set
+ dbg_emitted.
+ (gfc_define_undef_line): New function.
+ (load_file): Don't error out on #define and #undef lines.
+ * parse.c (next_statement): Call gfc_define_undef_line.
+ (gfc_parse_file): Call debug_hooks->start_source_file and
+ debug_hooks->end_source_file for the main source file if
+ required.
+ * gfortran.h (gfc_linebuf): Add dbg_emitted field.
+ (gfc_define_undef_line): New prototype.
+
+2007-10-04 Tobias Schlüter <tobi@gcc.gnu.org>
+
+ PR fortran/33626
+ * resolve.c (resolve_operator): Always copy the type for
+ expressions in parentheses.
+
+2007-10-04 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/33646
+ PR fortran/33542
+ * interface.c (check_interface1): Revert patch of 10-02.
+
+2007-10-03 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/26682
+ * trans-decl.c (build_function_decl): Set "externally_visible"
+ attribute on the MAIN program decl.
+
+2007-10-03 Tobias Schlüter <tobi@gcc.gnu.org>
+
+ PR fortran/33198
+ * resolve.c (has_default_initializer): Move to top. Make bool.
+ (resolve_common_blocks): Simplify logic. Add case for derived
+ type initialization.
+ (resolve_fl_variable_derived): Split out from ...
+ (resolve_fl_variable): ... here, while adapting to new h_d_i
+ interface.
+
+2007-10-03 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/26682
+ * options.c (gfc_post_options): Issue an error when
+ -fwhole-program is used.
+
+2007-10-02 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/33542
+ * interface.c (check_interface1): Specific procedures are
+ always ambiguous if they have the same name.
+
+2007-10-02 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/33566
+ * primary.c (gfc_match_rvalue): Make all expressions with array
+ references to structure parameters into variable expressions.
+
+2007-10-02 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/33554
+ * trans-decl.c (init_intent_out_dt): New function.
+ (gfc_trans_deferred_vars): Remove the code for default
+ initialization of INTENT(OUT) derived types and put it
+ in the new function. Call it earlier than before, so
+ that array offsets and lower bounds are available.
+
+2007-10-02 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/33550
+ * decl.c (get_proc_name): Return rc if rc is non-zero; ie. if
+ the name is a reference to an ambiguous symbol.
+
+2007-10-02 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/31154
+ PR fortran/31229
+ PR fortran/33334
+ * decl.c : Declare gfc_function_kind_locs and
+ gfc_function_type_locus.
+ (gfc_match_kind_spec): Add second argument kind_expr_only.
+ Store locus before trying to match the expression. If the
+ current state corresponds to a function declaration and there
+ is no match to the expression, read to the parenthesis, return
+ kind = -1, dump the expression and return.
+ (gfc_match_type_spec): Renamed from match_type_spec and all
+ references changed. If an interface or an external function,
+ store the locus, set kind = -1 and return. Otherwise, if kind
+ is already = -1, use gfc_find_symbol to try to find a use
+ associated or imported type.
+ match.h : Prototype for gfc_match_type_spec.
+ * parse.c (match_deferred_characteristics): New function.
+ (parse_spec): If in a function, statement is USE or IMPORT
+ or DERIVED_DECL and the function kind=-1, call
+ match_deferred_characteristics. If kind=-1 at the end of the
+ specification expressions, this is an error.
+ * parse.h : Declare external gfc_function_kind_locs and
+ gfc_function_type_locus.
+
2007-09-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* module.c (mio_expr): Avoid -Wcast-qual warning.
diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in
index 7b4b4c73b4d..16d4d3534ee 100644
--- a/gcc/fortran/Make-lang.in
+++ b/gcc/fortran/Make-lang.in
@@ -324,5 +324,6 @@ fortran/trans-intrinsic.o: $(GFORTRAN_TRANS_DEPS) fortran/mathbuiltins.def \
gt-fortran-trans-intrinsic.h
fortran/dependency.o: $(GFORTRAN_TRANS_DEPS) fortran/dependency.h
fortran/trans-common.o: $(GFORTRAN_TRANS_DEPS) $(TARGET_H) $(RTL_H)
-fortran/resolve.o: fortran/dependency.h
+fortran/resolve.o: fortran/dependency.h fortran/data.h
+fortran/data.o: fortran/data.h
fortran/options.o: $(PARAMS_H) $(TARGET_H)
diff --git a/gcc/fortran/data.c b/gcc/fortran/data.c
index 14c1b1a122e..59ac5e9d8e6 100644
--- a/gcc/fortran/data.c
+++ b/gcc/fortran/data.c
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "gfortran.h"
+#include "data.h"
static void formalize_init_expr (gfc_expr *);
diff --git a/gcc/fortran/data.h b/gcc/fortran/data.h
new file mode 100644
index 00000000000..5f89d981f7e
--- /dev/null
+++ b/gcc/fortran/data.h
@@ -0,0 +1,24 @@
+/* Header for functions resolving DATA statements.
+ Copyright (C) 2007 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/>. */
+
+void gfc_formalize_init_value (gfc_symbol *);
+void gfc_get_section_index (gfc_array_ref *, mpz_t *, mpz_t *);
+try gfc_assign_data_value (gfc_expr *, gfc_expr *, mpz_t);
+void gfc_assign_data_value_range (gfc_expr *, gfc_expr *, mpz_t, mpz_t);
+void gfc_advance_section (mpz_t *, gfc_array_ref *, mpz_t *);
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 7fa8548fb56..d2c94a1d727 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -25,6 +25,14 @@ along with GCC; see the file COPYING3. If not see
#include "match.h"
#include "parse.h"
+
+/* Macros to access allocate memory for gfc_data_variable,
+ gfc_data_value and gfc_data. */
+#define gfc_get_data_variable() gfc_getmem (sizeof (gfc_data_variable))
+#define gfc_get_data_value() gfc_getmem (sizeof (gfc_data_value))
+#define gfc_get_data() gfc_getmem( sizeof (gfc_data))
+
+
/* This flag is set if an old-style length selector is matched
during a type-declaration statement. */
@@ -78,6 +86,9 @@ static enumerator_history *max_enum = NULL;
gfc_symbol *gfc_new_block;
+locus gfc_function_kind_locus;
+locus gfc_function_type_locus;
+
/********************* DATA statement subroutines *********************/
@@ -89,8 +100,8 @@ gfc_in_match_data (void)
return in_match_data;
}
-void
-gfc_set_in_match_data (bool set_value)
+static void
+set_in_match_data (bool set_value)
{
in_match_data = set_value;
}
@@ -493,7 +504,7 @@ gfc_match_data (void)
gfc_data *new;
match m;
- gfc_set_in_match_data (true);
+ set_in_match_data (true);
for (;;)
{
@@ -517,7 +528,7 @@ gfc_match_data (void)
gfc_match_char (','); /* Optional comma */
}
- gfc_set_in_match_data (false);
+ set_in_match_data (false);
if (gfc_pure (NULL))
{
@@ -528,7 +539,7 @@ gfc_match_data (void)
return MATCH_YES;
cleanup:
- gfc_set_in_match_data (false);
+ set_in_match_data (false);
gfc_free_data (new);
return MATCH_ERROR;
}
@@ -669,7 +680,7 @@ get_proc_name (const char *name, gfc_symbol **result, bool module_fcn_entry)
{
gfc_symtree *st;
gfc_symbol *sym;
- int rc;
+ int rc = 0;
/* Module functions have to be left in their own namespace because
they have potentially (almost certainly!) already been referenced.
@@ -706,6 +717,9 @@ get_proc_name (const char *name, gfc_symbol **result, bool module_fcn_entry)
else
rc = gfc_get_symbol (name, gfc_current_ns->parent, result);
+ if (rc)
+ return rc;
+
sym = *result;
gfc_current_ns->refs++;
@@ -1762,17 +1776,21 @@ gfc_match_old_kind_spec (gfc_typespec *ts)
string is found, then we know we have an error. */
match
-gfc_match_kind_spec (gfc_typespec *ts)
+gfc_match_kind_spec (gfc_typespec *ts, bool kind_expr_only)
{
- locus where;
+ locus where, loc;
gfc_expr *e;
match m, n;
const char *msg;
m = MATCH_NO;
+ n = MATCH_YES;
e = NULL;
- where = gfc_current_locus;
+ where = loc = gfc_current_locus;
+
+ if (kind_expr_only)
+ goto kind_expr;
if (gfc_match_char ('(') == MATCH_NO)
return MATCH_NO;
@@ -1781,11 +1799,42 @@ gfc_match_kind_spec (gfc_typespec *ts)
if (gfc_match (" kind = ") == MATCH_YES)
m = MATCH_ERROR;
+ loc = gfc_current_locus;
+
+kind_expr:
n = gfc_match_init_expr (&e);
- if (n == MATCH_NO)
- gfc_error ("Expected initialization expression at %C");
+
if (n != MATCH_YES)
- return MATCH_ERROR;
+ {
+ if (gfc_current_state () == COMP_INTERFACE
+ || gfc_current_state () == COMP_NONE
+ || gfc_current_state () == COMP_CONTAINS)
+ {
+ /* Signal using kind = -1 that the expression might include
+ use associated or imported parameters and try again after
+ the specification expressions..... */
+ if (gfc_match_char (')') != MATCH_YES)
+ {
+ gfc_error ("Missing right parenthesis at %C");
+ m = MATCH_ERROR;
+ goto no_match;
+ }
+
+ gfc_free_expr (e);
+ ts->kind = -1;
+ gfc_function_kind_locus = loc;
+ gfc_undo_symbols ();
+ return MATCH_YES;
+ }
+ else
+ {
+ /* ....or else, the match is real. */
+ if (n == MATCH_NO)
+ gfc_error ("Expected initialization expression at %C");
+ if (n != MATCH_YES)
+ return MATCH_ERROR;
+ }
+ }
if (e->rank != 0)
{
@@ -1826,7 +1875,7 @@ gfc_match_kind_spec (gfc_typespec *ts)
else if (gfc_match_char (')') != MATCH_YES)
{
gfc_error ("Missing right parenthesis at %C");
- m = MATCH_ERROR;
+ m = MATCH_ERROR;
}
else
/* All tests passed. */
@@ -1845,20 +1894,80 @@ no_match:
}
+static match
+match_char_kind (int * kind, int * is_iso_c)
+{
+ locus where;
+ gfc_expr *e;
+ match m, n;
+ const char *msg;
+
+ m = MATCH_NO;
+ e = NULL;
+ where = gfc_current_locus;
+
+ n = gfc_match_init_expr (&e);
+ if (n == MATCH_NO)
+ gfc_error ("Expected initialization expression at %C");
+ if (n != MATCH_YES)
+ return MATCH_ERROR;
+
+ if (e->rank != 0)
+ {
+ gfc_error ("Expected scalar initialization expression at %C");
+ m = MATCH_ERROR;
+ goto no_match;
+ }
+
+ msg = gfc_extract_int (e, kind);
+ *is_iso_c = e->ts.is_iso_c;
+ if (msg != NULL)
+ {
+ gfc_error (msg);
+ m = MATCH_ERROR;
+ goto no_match;
+ }
+
+ gfc_free_expr (e);
+
+ /* Ignore errors to this point, if we've gotten here. This means
+ we ignore the m=MATCH_ERROR from above. */
+ if (gfc_validate_kind (BT_CHARACTER, *kind, true) < 0)
+ {
+ gfc_error ("Kind %d is not supported for CHARACTER at %C", *kind);
+ m = MATCH_ERROR;
+ }
+ else
+ /* All tests passed. */
+ m = MATCH_YES;
+
+ if (m == MATCH_ERROR)
+ gfc_current_locus = where;
+
+ /* Return what we know from the test(s). */
+ return m;
+
+no_match:
+ gfc_free_expr (e);
+ gfc_current_locus = where;
+ return m;
+}
+
/* Match the various kind/length specifications in a CHARACTER
declaration. We don't return MATCH_NO. */
static match
match_char_spec (gfc_typespec *ts)
{
- int kind, seen_length;
+ int kind, seen_length, is_iso_c;
gfc_charlen *cl;
gfc_expr *len;
match m;
- gfc_expr *kind_expr = NULL;
- kind = gfc_default_character_kind;
+
len = NULL;
seen_length = 0;
+ kind = 0;
+ is_iso_c = 0;
/* Try the old-style specification first. */
old_char_selector = 0;
@@ -1882,7 +1991,7 @@ match_char_spec (gfc_typespec *ts)
/* Try the weird case: ( KIND = <int> [ , LEN = <len-param> ] ). */
if (gfc_match (" kind =") == MATCH_YES)
{
- m = gfc_match_small_int_expr(&kind, &kind_expr);
+ m = match_char_kind (&kind, &is_iso_c);
if (m == MATCH_ERROR)
goto done;
@@ -1918,13 +2027,8 @@ match_char_spec (gfc_typespec *ts)
if (gfc_match (" , kind =") != MATCH_YES)
goto syntax;
- gfc_match_small_int_expr(&kind, &kind_expr);
-
- if (gfc_validate_kind (BT_CHARACTER, kind, true) < 0)
- {
- gfc_error ("Kind %d is not a CHARACTER kind at %C", kind);
- return MATCH_YES;
- }
+ if (match_char_kind (&kind, &is_iso_c) == MATCH_ERROR)
+ goto done;
goto rparen;
}
@@ -1946,7 +2050,7 @@ match_char_spec (gfc_typespec *ts)
gfc_match (" kind ="); /* Gobble optional text. */
- m = gfc_match_small_int_expr(&kind, &kind_expr);
+ m = match_char_kind (&kind, &is_iso_c);
if (m == MATCH_ERROR)
goto done;
if (m == MATCH_NO)
@@ -1965,23 +2069,9 @@ syntax:
return m;
done:
- if (gfc_validate_kind (BT_CHARACTER, kind, true) < 0)
- {
- gfc_error ("Kind %d is not a CHARACTER kind at %C", kind);
- m = MATCH_ERROR;
- }
-
- if (seen_length == 1 && len != NULL
- && len->ts.type != BT_INTEGER && len->ts.type != BT_UNKNOWN)
- {
- gfc_error ("Expression at %C must be of INTEGER type");
- m = MATCH_ERROR;
- }
-
if (m != MATCH_YES)
{
gfc_free_expr (len);
- gfc_free_expr (kind_expr);
return m;
}
@@ -1996,30 +2086,24 @@ done:
cl->length = len;
ts->cl = cl;
- ts->kind = kind;
+ ts->kind = kind == 0 ? gfc_default_character_kind : kind;
/* We have to know if it was a c interoperable kind so we can
do accurate type checking of bind(c) procs, etc. */
- if (kind_expr != NULL)
- {
- /* Mark this as c interoperable if being declared with one
- of the named constants from iso_c_binding. */
- ts->is_c_interop = kind_expr->ts.is_iso_c;
- gfc_free_expr (kind_expr);
- }
+ if (kind != 0)
+ /* Mark this as c interoperable if being declared with one
+ of the named constants from iso_c_binding. */
+ ts->is_c_interop = is_iso_c;
else if (len != NULL)
- {
- /* Here, we might have parsed something such as:
- character(c_char)
- In this case, the parsing code above grabs the c_char when
- looking for the length (line 1690, roughly). it's the last
- testcase for parsing the kind params of a character variable.
- However, it's not actually the length. this seems like it
- could be an error.
- To see if the user used a C interop kind, test the expr
- of the so called length, and see if it's C interoperable. */
- ts->is_c_interop = len->ts.is_iso_c;
- }
+ /* Here, we might have parsed something such as: character(c_char)
+ In this case, the parsing code above grabs the c_char when
+ looking for the length (line 1690, roughly). it's the last
+ testcase for parsing the kind params of a character variable.
+ However, it's not actually the length. this seems like it
+ could be an error.
+ To see if the user used a C interop kind, test the expr
+ of the so called length, and see if it's C interoperable. */
+ ts->is_c_interop = len->ts.is_iso_c;
return MATCH_YES;
}
@@ -2033,13 +2117,14 @@ done:
kind specification. Not doing so is needed for matching an IMPLICIT
statement correctly. */
-static match
-match_type_spec (gfc_typespec *ts, int implicit_flag)
+match
+gfc_match_type_spec (gfc_typespec *ts, int implicit_flag)
{
char name[GFC_MAX_SYMBOL_LEN + 1];
gfc_symbol *sym;
match m;
int c;
+ locus loc = gfc_current_locus;
gfc_clear_ts (ts);
@@ -2123,12 +2208,34 @@ match_type_spec (gfc_typespec *ts, int implicit_flag)
if (m != MATCH_YES)
return m;
- /* Search for the name but allow the components to be defined later. */
- if (gfc_get_ha_symbol (name, &sym))
+ if (gfc_current_state () == COMP_INTERFACE
+ || gfc_current_state () == COMP_NONE)
+ {
+ gfc_function_type_locus = loc;
+ ts->type = BT_UNKNOWN;
+ ts->kind = -1;
+ return MATCH_YES;
+ }
+
+ /* Search for the name but allow the components to be defined later. If
+ type = -1, this typespec has been seen in a function declaration but
+ the type could not legally be accessed at that point. */
+ if (ts->kind != -1 && gfc_get_ha_symbol (name, &sym))
{
gfc_error ("Type name '%s' at %C is ambiguous", name);
return MATCH_ERROR;
}
+ else if (ts->kind == -1)
+ {
+ if (gfc_find_symbol (name, NULL, 0, &sym))
+ {
+ gfc_error ("Type name '%s' at %C is ambiguous", name);
+ return MATCH_ERROR;
+ }
+
+ if (sym == NULL)
+ return MATCH_NO;
+ }
if (sym->attr.flavor != FL_DERIVED
&& gfc_add_flavor (&sym->attr, FL_DERIVED, sym->name, NULL) == FAILURE)
@@ -2154,7 +2261,7 @@ get_kind:
return MATCH_NO;
}
- m = gfc_match_kind_spec (ts);
+ m = gfc_match_kind_spec (ts, false);
if (m == MATCH_NO && ts->type != BT_CHARACTER)
m = gfc_match_old_kind_spec (ts);
@@ -2301,7 +2408,7 @@ gfc_match_implicit (void)
gfc_clear_new_implicit ();
/* A basic type is mandatory here. */
- m = match_type_spec (&ts, 1);
+ m = gfc_match_type_spec (&ts, 1);
if (m == MATCH_ERROR)
goto error;
if (m == MATCH_NO)
@@ -2344,7 +2451,7 @@ gfc_match_implicit (void)
m = match_char_spec (&ts);
else
{
- m = gfc_match_kind_spec (&ts);
+ m = gfc_match_kind_spec (&ts, false);
if (m == MATCH_NO)
{
m = gfc_match_old_kind_spec (&ts);
@@ -3390,7 +3497,7 @@ gfc_match_data_decl (void)
num_idents_on_line = 0;
- m = match_type_spec (&current_ts, 0);
+ m = gfc_match_type_spec (&current_ts, 0);
if (m != MATCH_YES)
return m;
@@ -3492,7 +3599,7 @@ match_prefix (gfc_typespec *ts)
loop:
if (!seen_type && ts != NULL
- && match_type_spec (ts, 0) == MATCH_YES
+ && gfc_match_type_spec (ts, 0) == MATCH_YES
&& gfc_match_space () == MATCH_YES)
{
@@ -3798,7 +3905,7 @@ match_procedure_decl (void)
/* Get the type spec. for the procedure interface. */
old_loc = gfc_current_locus;
- m = match_type_spec (&current_ts, 0);
+ m = gfc_match_type_spec (&current_ts, 0);
if (m == MATCH_YES || (m == MATCH_NO && gfc_peek_char () == ')'))
goto got_ts;
@@ -4157,7 +4264,7 @@ add_global_entry (const char *name, int sub)
if (s->defined
|| (s->type != GSYM_UNKNOWN
&& s->type != (sub ? GSYM_SUBROUTINE : GSYM_FUNCTION)))
- global_used(s, NULL);
+ gfc_global_used(s, NULL);
else
{
s->type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION;
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 0c68095e6a8..151b465ae9f 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -2012,7 +2012,7 @@ check_inquiry (gfc_expr *e, int not_restricted)
&& ap->expr->symtree->n.sym->ts.type == BT_CHARACTER
&& ap->expr->symtree->n.sym->ts.cl->length == NULL)
{
- gfc_error ("assumed character length variable '%s' in constant "
+ gfc_error ("Assumed character length variable '%s' in constant "
"expression at %L", e->symtree->n.sym->name, &e->where);
return MATCH_ERROR;
}
@@ -2204,19 +2204,19 @@ check_init_expr (gfc_expr *e)
switch (e->symtree->n.sym->as->type)
{
case AS_ASSUMED_SIZE:
- gfc_error ("assumed size array '%s' at %L is not permitted "
+ gfc_error ("Assumed size array '%s' at %L is not permitted "
"in an initialization expression",
e->symtree->n.sym->name, &e->where);
break;
case AS_ASSUMED_SHAPE:
- gfc_error ("assumed shape array '%s' at %L is not permitted "
+ gfc_error ("Assumed shape array '%s' at %L is not permitted "
"in an initialization expression",
e->symtree->n.sym->name, &e->where);
break;
case AS_DEFERRED:
- gfc_error ("deferred array '%s' at %L is not permitted "
+ gfc_error ("Deferred array '%s' at %L is not permitted "
"in an initialization expression",
e->symtree->n.sym->name, &e->where);
break;
@@ -2429,6 +2429,19 @@ check_restricted (gfc_expr *e)
sym = e->symtree->n.sym;
t = FAILURE;
+ /* If a dummy argument appears in a context that is valid for a
+ restricted expression in an elemental procedure, it will have
+ already been simplified away once we get here. Therefore we
+ don't need to jump through hoops to distinguish valid from
+ invalid cases. */
+ if (sym->attr.dummy && sym->ns == gfc_current_ns
+ && sym->ns->proc_name && sym->ns->proc_name->attr.elemental)
+ {
+ gfc_error ("Dummy argument '%s' not allowed in expression at %L",
+ sym->name, &e->where);
+ break;
+ }
+
if (sym->attr.optional)
{
gfc_error ("Dummy argument '%s' at %L cannot be OPTIONAL",
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 42002cee21e..203e1e78f40 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -723,6 +723,7 @@ typedef struct gfc_linebuf
struct gfc_linebuf *next;
int truncated;
+ bool dbg_emitted;
char line[1];
} gfc_linebuf;
@@ -1792,10 +1793,6 @@ typedef struct gfc_data
}
gfc_data;
-#define gfc_get_data_variable() gfc_getmem(sizeof(gfc_data_variable))
-#define gfc_get_data_value() gfc_getmem(sizeof(gfc_data_value))
-#define gfc_get_data() gfc_getmem(sizeof(gfc_data))
-
/* Structure for holding compile options */
typedef struct
@@ -1908,16 +1905,8 @@ extern iterator_stack *iter_stack;
/************************ Function prototypes *************************/
-/* data.c */
-void gfc_formalize_init_value (gfc_symbol *);
-void gfc_get_section_index (gfc_array_ref *, mpz_t *, mpz_t *);
-try gfc_assign_data_value (gfc_expr *, gfc_expr *, mpz_t);
-void gfc_assign_data_value_range (gfc_expr *, gfc_expr *, mpz_t, mpz_t);
-void gfc_advance_section (mpz_t *, gfc_array_ref *, mpz_t *);
-
/* decl.c */
bool gfc_in_match_data (void);
-void gfc_set_in_match_data (bool);
/* scanner.c */
void gfc_scanner_done_1 (void);
@@ -1935,6 +1924,7 @@ int gfc_at_bol (void);
int gfc_at_eol (void);
void gfc_advance_line (void);
int gfc_check_include (void);
+int gfc_define_undef_line (void);
void gfc_skip_comments (void);
int gfc_next_char_literal (int);
@@ -2369,7 +2359,7 @@ void gfc_show_typespec (gfc_typespec *);
/* parse.c */
try gfc_parse_file (void);
-void global_used (gfc_gsymbol *, locus *);
+void gfc_global_used (gfc_gsymbol *, locus *);
/* dependency.c */
int gfc_dep_compare_expr (gfc_expr *, gfc_expr *);
diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h
index 4841f33eacc..f9d6aea7010 100644
--- a/gcc/fortran/match.h
+++ b/gcc/fortran/match.h
@@ -127,8 +127,9 @@ match gfc_match_omp_end_single (void);
match gfc_match_data (void);
match gfc_match_null (gfc_expr **);
-match gfc_match_kind_spec (gfc_typespec *);
+match gfc_match_kind_spec (gfc_typespec *, bool);
match gfc_match_old_kind_spec (gfc_typespec *);
+match gfc_match_type_spec (gfc_typespec *, int);
match gfc_match_end (gfc_statement *);
match gfc_match_data_decl (void);
diff --git a/gcc/fortran/mathbuiltins.def b/gcc/fortran/mathbuiltins.def
index 33e87d14290..37758e1adfa 100644
--- a/gcc/fortran/mathbuiltins.def
+++ b/gcc/fortran/mathbuiltins.def
@@ -30,5 +30,5 @@ DEFINE_MATH_BUILTIN (Y1, "y1", 0)
DEFINE_MATH_BUILTIN (YN, "yn", 2)
DEFINE_MATH_BUILTIN (ERF, "erf", 0)
DEFINE_MATH_BUILTIN (ERFC, "erfc", 0)
-DEFINE_MATH_BUILTIN (GAMMA, "gamma", 0)
+DEFINE_MATH_BUILTIN (GAMMA, "tgamma", 0)
DEFINE_MATH_BUILTIN (LGAMMA,"lgamma", 0)
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 5c3aefa4fe1..b2c17dca14e 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -211,6 +211,10 @@ gfc_post_options (const char **pfilename)
char *source_path;
int i;
+ /* Issue an error if -fwhole-program was used. */
+ if (flag_whole_program)
+ gfc_fatal_error ("Option -fwhole-program is not supported for Fortran");
+
/* Verify the input file name. */
if (!filename || strcmp (filename, "-") == 0)
{
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index a6672f46ca6..f357c7a6523 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "gfortran.h"
#include "match.h"
#include "parse.h"
+#include "debug.h"
/* Current statement label. Zero means no statement label. Because new_st
can get wiped during statement matching, we have to keep it separate. */
@@ -673,6 +674,9 @@ next_statement (void)
break;
}
+ if (gfc_define_undef_line ())
+ continue;
+
st = (gfc_current_form == FORM_FIXED) ? next_fixed () : next_free ();
if (st != ST_NONE)
@@ -1866,6 +1870,35 @@ done:
}
+/* Recover use associated or imported function characteristics. */
+
+static try
+match_deferred_characteristics (gfc_typespec * ts)
+{
+ locus loc;
+ match m;
+
+ loc = gfc_current_locus;
+
+ if (gfc_current_block ()->ts.type != BT_UNKNOWN)
+ {
+ /* Kind expression for an intrinsic type. */
+ gfc_current_locus = gfc_function_kind_locus;
+ m = gfc_match_kind_spec (ts, true);
+ }
+ else
+ {
+ /* A derived type. */
+ gfc_current_locus = gfc_function_type_locus;
+ m = gfc_match_type_spec (ts, 0);
+ }
+
+ gfc_current_ns->proc_name->result->ts = *ts;
+ gfc_current_locus =loc;
+ return m;
+}
+
+
/* Parse a set of specification statements. Returns the statement
that doesn't fit. */
@@ -1951,6 +1984,15 @@ loop:
}
accept_statement (st);
+
+ /* Look out for function kind/type information that used
+ use associated or imported parameter. This is signalled
+ by kind = -1. */
+ if (gfc_current_state () == COMP_FUNCTION
+ && (st == ST_USE || st == ST_IMPORT || st == ST_DERIVED_DECL)
+ && gfc_current_block ()->ts.kind == -1)
+ match_deferred_characteristics (&gfc_current_block ()->ts);
+
st = next_statement ();
goto loop;
@@ -1964,6 +2006,19 @@ loop:
break;
}
+ /* If we still have kind = -1 at the end of the specification block,
+ then there is an error. */
+ if (gfc_current_state () == COMP_FUNCTION
+ && gfc_current_block ()->ts.kind == -1)
+ {
+ if (gfc_current_block ()->ts.type != BT_UNKNOWN)
+ gfc_error ("Bad kind expression for function '%s' at %L",
+ gfc_current_block ()->name, &gfc_function_kind_locus);
+ else
+ gfc_error ("The type for function '%s' at %L is not accessible",
+ gfc_current_block ()->name, &gfc_function_type_locus);
+ }
+
return st;
}
@@ -3033,7 +3088,7 @@ done:
something else. */
void
-global_used (gfc_gsymbol *sym, locus *where)
+gfc_global_used (gfc_gsymbol *sym, locus *where)
{
const char *name;
@@ -3099,7 +3154,7 @@ parse_block_data (void)
s = gfc_get_gsymbol (gfc_new_block->name);
if (s->defined
|| (s->type != GSYM_UNKNOWN && s->type != GSYM_BLOCK_DATA))
- global_used(s, NULL);
+ gfc_global_used(s, NULL);
else
{
s->type = GSYM_BLOCK_DATA;
@@ -3130,7 +3185,7 @@ parse_module (void)
s = gfc_get_gsymbol (gfc_new_block->name);
if (s->defined || (s->type != GSYM_UNKNOWN && s->type != GSYM_MODULE))
- global_used(s, NULL);
+ gfc_global_used(s, NULL);
else
{
s->type = GSYM_MODULE;
@@ -3177,7 +3232,7 @@ add_global_procedure (int sub)
if (s->defined
|| (s->type != GSYM_UNKNOWN
&& s->type != (sub ? GSYM_SUBROUTINE : GSYM_FUNCTION)))
- global_used(s, NULL);
+ gfc_global_used(s, NULL);
else
{
s->type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION;
@@ -3199,7 +3254,7 @@ add_global_program (void)
s = gfc_get_gsymbol (gfc_new_block->name);
if (s->defined || (s->type != GSYM_UNKNOWN && s->type != GSYM_PROGRAM))
- global_used(s, NULL);
+ gfc_global_used(s, NULL);
else
{
s->type = GSYM_PROGRAM;
@@ -3219,6 +3274,11 @@ gfc_parse_file (void)
gfc_statement st;
locus prog_locus;
+ /* If the debugger wants the name of the main source file,
+ we give it. */
+ if (debug_hooks->start_end_main_source_file)
+ (*debug_hooks->start_source_file) (0, gfc_source_file);
+
top.state = COMP_NONE;
top.sym = NULL;
top.previous = NULL;
@@ -3329,6 +3389,9 @@ loop:
goto loop;
done:
+ if (debug_hooks->start_end_main_source_file)
+ (*debug_hooks->end_source_file) (0);
+
return SUCCESS;
duplicate_main:
diff --git a/gcc/fortran/parse.h b/gcc/fortran/parse.h
index 92806ba49a5..307d59a0ff8 100644
--- a/gcc/fortran/parse.h
+++ b/gcc/fortran/parse.h
@@ -66,5 +66,7 @@ const char *gfc_ascii_statement (gfc_statement);
match gfc_match_enum (void);
match gfc_match_enumerator_def (void);
void gfc_free_enum_history (void);
+extern locus gfc_function_kind_locus;
+extern locus gfc_function_type_locus;
#endif /* GFC_PARSE_H */
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index 575a4c7411a..d5e4b64d26e 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -2148,18 +2148,17 @@ gfc_match_rvalue (gfc_expr **result)
if (sym->ts.is_c_interop || sym->ts.is_iso_c)
break;
- /* Variable array references to use associated derived type
- parameters cause all sorts of headaches in simplification.
- For this reason, we write the parameter to the module and
- treat them as variable references. */
- if (sym->value && sym->ts.type == BT_DERIVED
- && sym->attr.use_assoc && e->ref)
+ /* Variable array references to derived type parameters cause
+ all sorts of headaches in simplification. Treating such
+ expressions as variable works just fine for all array
+ references. */
+ if (sym->value && sym->ts.type == BT_DERIVED && e->ref)
{
for (ref = e->ref; ref; ref = ref->next)
if (ref->type == REF_ARRAY)
break;
- if (ref == NULL)
+ if (ref == NULL || ref->u.ar.type == AR_FULL)
break;
ref = e->ref;
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 2f578e736d5..2686c3dac82 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "bitmap.h"
#include "arith.h" /* For gfc_compare_expr(). */
#include "dependency.h"
+#include "data.h"
/* Types used in equivalence statements. */
@@ -602,6 +603,22 @@ resolve_entries (gfc_namespace *ns)
}
+static bool
+has_default_initializer (gfc_symbol *der)
+{
+ gfc_component *c;
+
+ gcc_assert (der->attr.flavor == FL_DERIVED);
+ for (c = der->components; c; c = c->next)
+ if ((c->ts.type != BT_DERIVED && c->initializer)
+ || (c->ts.type == BT_DERIVED
+ && (!c->pointer && has_default_initializer (c->ts.derived))))
+ break;
+
+ return c != NULL;
+}
+
+
/* Resolve common blocks. */
static void
resolve_common_blocks (gfc_symtree *common_root)
@@ -618,23 +635,22 @@ resolve_common_blocks (gfc_symtree *common_root)
for (csym = common_root->n.common->head; csym; csym = csym->common_next)
{
- if (csym->ts.type == BT_DERIVED
- && !(csym->ts.derived->attr.sequence
- || csym->ts.derived->attr.is_bind_c))
- {
- gfc_error_now ("Derived type variable '%s' in COMMON at %L "
- "has neither the SEQUENCE nor the BIND(C) "
- "attribute", csym->name,
- &csym->declared_at);
- }
- else if (csym->ts.type == BT_DERIVED
- && csym->ts.derived->attr.alloc_comp)
- {
- gfc_error_now ("Derived type variable '%s' in COMMON at %L "
- "has an ultimate component that is "
- "allocatable", csym->name,
- &csym->declared_at);
- }
+ if (csym->ts.type != BT_DERIVED)
+ continue;
+
+ if (!(csym->ts.derived->attr.sequence
+ || csym->ts.derived->attr.is_bind_c))
+ gfc_error_now ("Derived type variable '%s' in COMMON at %L "
+ "has neither the SEQUENCE nor the BIND(C) "
+ "attribute", csym->name, &csym->declared_at);
+ if (csym->ts.derived->attr.alloc_comp)
+ gfc_error_now ("Derived type variable '%s' in COMMON at %L "
+ "has an ultimate component that is "
+ "allocatable", csym->name, &csym->declared_at);
+ if (has_default_initializer (csym->ts.derived))
+ gfc_error_now ("Derived type variable '%s' in COMMON at %L "
+ "may not have default initializer", csym->name,
+ &csym->declared_at);
}
gfc_find_symbol (common_root->name, gfc_current_ns, 0, &sym);
@@ -1344,7 +1360,7 @@ resolve_global_procedure (gfc_symbol *sym, locus *where, int sub)
gsym = gfc_get_gsymbol (sym->name);
if ((gsym->type != GSYM_UNKNOWN && gsym->type != type))
- global_used (gsym, where);
+ gfc_global_used (gsym, where);
if (gsym->type == GSYM_UNKNOWN)
{
@@ -2927,6 +2943,9 @@ resolve_operator (gfc_expr *e)
goto bad_op;
case INTRINSIC_PARENTHESES:
+ e->ts = op1->ts;
+ if (e->ts.type == BT_CHARACTER)
+ e->ts.cl = op1->ts.cl;
break;
default:
@@ -3011,14 +3030,6 @@ resolve_operator (gfc_expr *e)
break;
case INTRINSIC_PARENTHESES:
-
- /* This is always correct and sometimes necessary! */
- if (e->ts.type == BT_UNKNOWN)
- e->ts = op1->ts;
-
- if (e->ts.type == BT_CHARACTER && !e->ts.cl)
- e->ts.cl = op1->ts.cl;
-
case INTRINSIC_NOT:
case INTRINSIC_UPLUS:
case INTRINSIC_UMINUS:
@@ -4127,7 +4138,7 @@ gfc_resolve_expr (gfc_expr *e)
}
if (e->ts.type == BT_CHARACTER && e->ts.cl == NULL && e->ref
- && e->ref->type != REF_SUBSTRING)
+ && e->ref->type != REF_SUBSTRING)
gfc_resolve_substring_charlen (e);
break;
@@ -4285,14 +4296,147 @@ gfc_resolve_iterator (gfc_iterator *iter, bool real_ok)
}
+/* Check whether the FORALL index appears in the expression or not.
+ Returns SUCCESS if SYM is found in EXPR. */
+
+static try
+find_forall_index (gfc_expr *expr, gfc_symbol *symbol)
+{
+ gfc_array_ref ar;
+ gfc_ref *tmp;
+ gfc_actual_arglist *args;
+ int i;
+
+ if (!expr)
+ return FAILURE;
+
+ switch (expr->expr_type)
+ {
+ case EXPR_VARIABLE:
+ gcc_assert (expr->symtree->n.sym);
+
+ /* A scalar assignment */
+ if (!expr->ref)
+ {
+ if (expr->symtree->n.sym == symbol)
+ return SUCCESS;
+ else
+ return FAILURE;
+ }
+
+ /* the expr is array ref, substring or struct component. */
+ tmp = expr->ref;
+ while (tmp != NULL)
+ {
+ switch (tmp->type)
+ {
+ case REF_ARRAY:
+ /* Check if the symbol appears in the array subscript. */
+ ar = tmp->u.ar;
+ for (i = 0; i < GFC_MAX_DIMENSIONS; i++)
+ {
+ if (ar.start[i])
+ if (find_forall_index (ar.start[i], symbol) == SUCCESS)
+ return SUCCESS;
+
+ if (ar.end[i])
+ if (find_forall_index (ar.end[i], symbol) == SUCCESS)
+ return SUCCESS;
+
+ if (ar.stride[i])
+ if (find_forall_index (ar.stride[i], symbol) == SUCCESS)
+ return SUCCESS;
+ } /* end for */
+ break;
+
+ case REF_SUBSTRING:
+ if (expr->symtree->n.sym == symbol)
+ return SUCCESS;
+ tmp = expr->ref;
+ /* Check if the symbol appears in the substring section. */
+ if (find_forall_index (tmp->u.ss.start, symbol) == SUCCESS)
+ return SUCCESS;
+ if (find_forall_index (tmp->u.ss.end, symbol) == SUCCESS)
+ return SUCCESS;
+ break;
+
+ case REF_COMPONENT:
+ break;
+
+ default:
+ gfc_error("expression reference type error at %L", &expr->where);
+ }
+ tmp = tmp->next;
+ }
+ break;
+
+ /* If the expression is a function call, then check if the symbol
+ appears in the actual arglist of the function. */
+ case EXPR_FUNCTION:
+ for (args = expr->value.function.actual; args; args = args->next)
+ {
+ if (find_forall_index(args->expr,symbol) == SUCCESS)
+ return SUCCESS;
+ }
+ break;
+
+ /* It seems not to happen. */
+ case EXPR_SUBSTRING:
+ if (expr->ref)
+ {
+ tmp = expr->ref;
+ gcc_assert (expr->ref->type == REF_SUBSTRING);
+ if (find_forall_index (tmp->u.ss.start, symbol) == SUCCESS)
+ return SUCCESS;
+ if (find_forall_index (tmp->u.ss.end, symbol) == SUCCESS)
+ return SUCCESS;
+ }
+ break;
+
+ /* It seems not to happen. */
+ case EXPR_STRUCTURE:
+ case EXPR_ARRAY:
+ gfc_error ("Unsupported statement while finding forall index in "
+ "expression");
+ break;
+
+ case EXPR_OP:
+ /* Find the FORALL index in the first operand. */
+ if (expr->value.op.op1)
+ {
+ if (find_forall_index (expr->value.op.op1, symbol) == SUCCESS)
+ return SUCCESS;
+ }
+
+ /* Find the FORALL index in the second operand. */
+ if (expr->value.op.op2)
+ {
+ if (find_forall_index (expr->value.op.op2, symbol) == SUCCESS)
+ return SUCCESS;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return FAILURE;
+}
+
+
/* Resolve a list of FORALL iterators. The FORALL index-name is constrained
to be a scalar INTEGER variable. The subscripts and stride are scalar
- INTEGERs, and if stride is a constant it must be nonzero. */
+ INTEGERs, and if stride is a constant it must be nonzero.
+ Furthermore "A subscript or stride in a forall-triplet-spec shall
+ not contain a reference to any index-name in the
+ forall-triplet-spec-list in which it appears." (7.5.4.1) */
static void
-resolve_forall_iterators (gfc_forall_iterator *iter)
+resolve_forall_iterators (gfc_forall_iterator *it)
{
- while (iter)
+ gfc_forall_iterator *iter, *iter2;
+
+ for (iter = it; iter; iter = iter->next)
{
if (gfc_resolve_expr (iter->var) == SUCCESS
&& (iter->var->ts.type != BT_INTEGER || iter->var->rank != 0))
@@ -4326,9 +4470,21 @@ resolve_forall_iterators (gfc_forall_iterator *iter)
}
if (iter->var->ts.kind != iter->stride->ts.kind)
gfc_convert_type (iter->stride, &iter->var->ts, 2);
-
- iter = iter->next;
}
+
+ for (iter = it; iter; iter = iter->next)
+ for (iter2 = iter; iter2; iter2 = iter2->next)
+ {
+ if (find_forall_index (iter2->start,
+ iter->var->symtree->n.sym) == SUCCESS
+ || find_forall_index (iter2->end,
+ iter->var->symtree->n.sym) == SUCCESS
+ || find_forall_index (iter2->stride,
+ iter->var->symtree->n.sym) == SUCCESS)
+ gfc_error ("FORALL index '%s' may not appear in triplet "
+ "specification at %L", iter->var->symtree->name,
+ &iter2->start->where);
+ }
}
@@ -5518,130 +5674,6 @@ resolve_where (gfc_code *code, gfc_expr *mask)
}
-/* Check whether the FORALL index appears in the expression or not. */
-
-static try
-gfc_find_forall_index (gfc_expr *expr, gfc_symbol *symbol)
-{
- gfc_array_ref ar;
- gfc_ref *tmp;
- gfc_actual_arglist *args;
- int i;
-
- switch (expr->expr_type)
- {
- case EXPR_VARIABLE:
- gcc_assert (expr->symtree->n.sym);
-
- /* A scalar assignment */
- if (!expr->ref)
- {
- if (expr->symtree->n.sym == symbol)
- return SUCCESS;
- else
- return FAILURE;
- }
-
- /* the expr is array ref, substring or struct component. */
- tmp = expr->ref;
- while (tmp != NULL)
- {
- switch (tmp->type)
- {
- case REF_ARRAY:
- /* Check if the symbol appears in the array subscript. */
- ar = tmp->u.ar;
- for (i = 0; i < GFC_MAX_DIMENSIONS; i++)
- {
- if (ar.start[i])
- if (gfc_find_forall_index (ar.start[i], symbol) == SUCCESS)
- return SUCCESS;
-
- if (ar.end[i])
- if (gfc_find_forall_index (ar.end[i], symbol) == SUCCESS)
- return SUCCESS;
-
- if (ar.stride[i])
- if (gfc_find_forall_index (ar.stride[i], symbol) == SUCCESS)
- return SUCCESS;
- } /* end for */
- break;
-
- case REF_SUBSTRING:
- if (expr->symtree->n.sym == symbol)
- return SUCCESS;
- tmp = expr->ref;
- /* Check if the symbol appears in the substring section. */
- if (gfc_find_forall_index (tmp->u.ss.start, symbol) == SUCCESS)
- return SUCCESS;
- if (gfc_find_forall_index (tmp->u.ss.end, symbol) == SUCCESS)
- return SUCCESS;
- break;
-
- case REF_COMPONENT:
- break;
-
- default:
- gfc_error("expression reference type error at %L", &expr->where);
- }
- tmp = tmp->next;
- }
- break;
-
- /* If the expression is a function call, then check if the symbol
- appears in the actual arglist of the function. */
- case EXPR_FUNCTION:
- for (args = expr->value.function.actual; args; args = args->next)
- {
- if (gfc_find_forall_index(args->expr,symbol) == SUCCESS)
- return SUCCESS;
- }
- break;
-
- /* It seems not to happen. */
- case EXPR_SUBSTRING:
- if (expr->ref)
- {
- tmp = expr->ref;
- gcc_assert (expr->ref->type == REF_SUBSTRING);
- if (gfc_find_forall_index (tmp->u.ss.start, symbol) == SUCCESS)
- return SUCCESS;
- if (gfc_find_forall_index (tmp->u.ss.end, symbol) == SUCCESS)
- return SUCCESS;
- }
- break;
-
- /* It seems not to happen. */
- case EXPR_STRUCTURE:
- case EXPR_ARRAY:
- gfc_error ("Unsupported statement while finding forall index in "
- "expression");
- break;
-
- case EXPR_OP:
- /* Find the FORALL index in the first operand. */
- if (expr->value.op.op1)
- {
- if (gfc_find_forall_index (expr->value.op.op1, symbol) == SUCCESS)
- return SUCCESS;
- }
-
- /* Find the FORALL index in the second operand. */
- if (expr->value.op.op2)
- {
- if (gfc_find_forall_index (expr->value.op.op2, symbol) == SUCCESS)
- return SUCCESS;
- }
- break;
-
- default:
- break;
- }
-
- return FAILURE;
-}
-
-
/* Resolve assignment in FORALL construct.
NVAR is the number of FORALL index variables, and VAR_EXPR records the
FORALL index variables. */
@@ -5668,7 +5700,7 @@ gfc_resolve_assign_in_forall (gfc_code *code, int nvar, gfc_expr **var_expr)
/* If one of the FORALL index variables doesn't appear in the
assignment target, then there will be a many-to-one
assignment. */
- if (gfc_find_forall_index (code->expr, forall_index) == FAILURE)
+ if (find_forall_index (code->expr, forall_index) == FAILURE)
gfc_error ("The FORALL with index '%s' cause more than one "
"assignment to this object at %L",
var_expr[n]->symtree->name, &code->expr->where);
@@ -5774,7 +5806,6 @@ gfc_resolve_forall (gfc_code *code, gfc_namespace *ns, int forall_save)
static int total_var = 0;
static int nvar = 0;
gfc_forall_iterator *fa;
- gfc_symbol *forall_index;
gfc_code *next;
int i;
@@ -5813,18 +5844,6 @@ gfc_resolve_forall (gfc_code *code, gfc_namespace *ns, int forall_save)
/* Record the current FORALL index. */
var_expr[nvar] = gfc_copy_expr (fa->var);
- forall_index = fa->var->symtree->n.sym;
-
- /* Check if the FORALL index appears in start, end or stride. */
- if (gfc_find_forall_index (fa->start, forall_index) == SUCCESS)
- gfc_error ("A FORALL index must not appear in a limit or stride "
- "expression in the same FORALL at %L", &fa->start->where);
- if (gfc_find_forall_index (fa->end, forall_index) == SUCCESS)
- gfc_error ("A FORALL index must not appear in a limit or stride "
- "expression in the same FORALL at %L", &fa->end->where);
- if (gfc_find_forall_index (fa->stride, forall_index) == SUCCESS)
- gfc_error ("A FORALL index must not appear in a limit or stride "
- "expression in the same FORALL at %L", &fa->stride->where);
nvar++;
}
@@ -5913,21 +5932,6 @@ gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns)
}
-static gfc_component *
-has_default_initializer (gfc_symbol *der)
-{
- gfc_component *c;
- for (c = der->components; c; c = c->next)
- if ((c->ts.type != BT_DERIVED && c->initializer)
- || (c->ts.type == BT_DERIVED
- && !c->pointer
- && has_default_initializer (c->ts.derived)))
- break;
-
- return c;
-}
-
-
/* Given a block of code, recursively resolve everything pointed to by this
code block. */
@@ -6563,7 +6567,7 @@ resolve_charlen (gfc_charlen *cl)
/* "If the character length parameter value evaluates to a negative
value, the length of character entities declared is zero." */
- if (cl->length && !gfc_extract_int (cl->length, &i) && i <= 0)
+ if (cl->length && !gfc_extract_int (cl->length, &i) && i < 0)
{
gfc_warning_now ("CHARACTER variable has zero length at %L",
&cl->length->where);
@@ -6883,18 +6887,76 @@ resolve_fl_var_and_proc (gfc_symbol *sym, int mp_flag)
}
+/* Additional checks for symbols with flavor variable and derived
+ type. To be called from resolve_fl_variable. */
+
+static try
+resolve_fl_variable_derived (gfc_symbol *sym, int no_init_flag)
+{
+ gcc_assert (sym->ts.type == BT_DERIVED);
+
+ /* Check to see if a derived type is blocked from being host
+ associated by the presence of another class I symbol in the same
+ namespace. 14.6.1.3 of the standard and the discussion on
+ comp.lang.fortran. */
+ if (sym->ns != sym->ts.derived->ns
+ && sym->ns->proc_name->attr.if_source != IFSRC_IFBODY)
+ {
+ gfc_symbol *s;
+ gfc_find_symbol (sym->ts.derived->name, sym->ns, 0, &s);
+ if (s && (s->attr.flavor != FL_DERIVED
+ || !gfc_compare_derived_types (s, sym->ts.derived)))
+ {
+ gfc_error ("The type '%s' cannot be host associated at %L "
+ "because it is blocked by an incompatible object "
+ "of the same name declared at %L",
+ sym->ts.derived->name, &sym->declared_at,
+ &s->declared_at);
+ return FAILURE;
+ }
+ }
+
+ /* 4th constraint in section 11.3: "If an object of a type for which
+ component-initialization is specified (R429) appears in the
+ specification-part of a module and does not have the ALLOCATABLE
+ or POINTER attribute, the object shall have the SAVE attribute."
+
+ The check for initializers is performed with
+ has_default_initializer because gfc_default_initializer generates
+ a hidden default for allocatable components. */
+ if (!(sym->value || no_init_flag) && sym->ns->proc_name
+ && sym->ns->proc_name->attr.flavor == FL_MODULE
+ && !sym->ns->save_all && !sym->attr.save
+ && !sym->attr.pointer && !sym->attr.allocatable
+ && has_default_initializer (sym->ts.derived))
+ {
+ gfc_error("Object '%s' at %L must have the SAVE attribute for "
+ "default initialization of a component",
+ sym->name, &sym->declared_at);
+ return FAILURE;
+ }
+
+ /* Assign default initializer. */
+ if (!(sym->value || sym->attr.pointer || sym->attr.allocatable)
+ && (!no_init_flag || sym->attr.intent == INTENT_OUT))
+ {
+ sym->value = gfc_default_initializer (&sym->ts);
+ }
+
+ return SUCCESS;
+}
+
+
/* Resolve symbols with flavor variable. */
static try
resolve_fl_variable (gfc_symbol *sym, int mp_flag)
{
- int flag;
- int i;
+ int no_init_flag, automatic_flag;
gfc_expr *e;
- gfc_component *c;
const char *auto_save_msg;
- auto_save_msg = "automatic object '%s' at %L cannot have the "
+ auto_save_msg = "Automatic object '%s' at %L cannot have the "
"SAVE attribute";
if (resolve_fl_var_and_proc (sym, mp_flag) == FAILURE)
@@ -6905,22 +6967,20 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
is_non_constant_shape_array. */
specification_expr = 1;
- if (!sym->attr.use_assoc
+ if (sym->ns->proc_name
+ && (sym->ns->proc_name->attr.flavor == FL_MODULE
+ || sym->ns->proc_name->attr.is_main_program)
+ && !sym->attr.use_assoc
&& !sym->attr.allocatable
&& !sym->attr.pointer
&& is_non_constant_shape_array (sym))
{
- /* The shape of a main program or module array needs to be
- constant. */
- if (sym->ns->proc_name
- && (sym->ns->proc_name->attr.flavor == FL_MODULE
- || sym->ns->proc_name->attr.is_main_program))
- {
- gfc_error ("The module or main program array '%s' at %L must "
- "have constant shape", sym->name, &sym->declared_at);
- specification_expr = 0;
- return FAILURE;
- }
+ /* The shape of a main program or module array needs to be
+ constant. */
+ gfc_error ("The module or main program array '%s' at %L must "
+ "have constant shape", sym->name, &sym->declared_at);
+ specification_expr = 0;
+ return FAILURE;
}
if (sym->ts.type == BT_CHARACTER)
@@ -6958,37 +7018,27 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
if (sym->value == NULL && sym->attr.referenced)
apply_default_init_local (sym); /* Try to apply a default initialization. */
- /* Can the symbol have an initializer? */
- flag = 0;
+ /* Determine if the symbol may not have an initializer. */
+ no_init_flag = automatic_flag = 0;
if (sym->attr.allocatable || sym->attr.external || sym->attr.dummy
- || sym->attr.intrinsic || sym->attr.result)
- flag = 1;
- else if (sym->attr.dimension && !sym->attr.pointer)
+ || sym->attr.intrinsic || sym->attr.result)
+ no_init_flag = 1;
+ else if (sym->attr.dimension && !sym->attr.pointer
+ && is_non_constant_shape_array (sym))
{
- /* Don't allow initialization of automatic arrays. */
- for (i = 0; i < sym->as->rank; i++)
- {
- if (sym->as->lower[i] == NULL
- || sym->as->lower[i]->expr_type != EXPR_CONSTANT
- || sym->as->upper[i] == NULL
- || sym->as->upper[i]->expr_type != EXPR_CONSTANT)
- {
- flag = 2;
- break;
- }
- }
+ no_init_flag = automatic_flag = 1;
/* Also, they must not have the SAVE attribute.
SAVE_IMPLICIT is checked below. */
- if (flag && sym->attr.save == SAVE_EXPLICIT)
+ if (sym->attr.save == SAVE_EXPLICIT)
{
gfc_error (auto_save_msg, sym->name, &sym->declared_at);
return FAILURE;
}
- }
+ }
/* Reject illegal initializers. */
- if (!sym->mark && sym->value && flag)
+ if (!sym->mark && sym->value)
{
if (sym->attr.allocatable)
gfc_error ("Allocatable '%s' at %L cannot have an initializer",
@@ -7006,7 +7056,7 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
else if (sym->attr.result)
gfc_error ("Function result '%s' at %L cannot have an initializer",
sym->name, &sym->declared_at);
- else if (flag == 2)
+ else if (automatic_flag)
gfc_error ("Automatic array '%s' at %L cannot have an initializer",
sym->name, &sym->declared_at);
else
@@ -7015,54 +7065,8 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
}
no_init_error:
- /* Check to see if a derived type is blocked from being host associated
- by the presence of another class I symbol in the same namespace.
- 14.6.1.3 of the standard and the discussion on comp.lang.fortran. */
- if (sym->ts.type == BT_DERIVED && sym->ns != sym->ts.derived->ns
- && sym->ns->proc_name->attr.if_source != IFSRC_IFBODY)
- {
- gfc_symbol *s;
- gfc_find_symbol (sym->ts.derived->name, sym->ns, 0, &s);
- if (s && (s->attr.flavor != FL_DERIVED
- || !gfc_compare_derived_types (s, sym->ts.derived)))
- {
- gfc_error ("The type %s cannot be host associated at %L because "
- "it is blocked by an incompatible object of the same "
- "name at %L", sym->ts.derived->name, &sym->declared_at,
- &s->declared_at);
- return FAILURE;
- }
- }
-
- /* Do not use gfc_default_initializer to test for a default initializer
- in the fortran because it generates a hidden default for allocatable
- components. */
- c = NULL;
- if (sym->ts.type == BT_DERIVED && !(sym->value || flag))
- c = has_default_initializer (sym->ts.derived);
-
- /* 4th constraint in section 11.3: "If an object of a type for which
- component-initialization is specified (R429) appears in the
- specification-part of a module and does not have the ALLOCATABLE
- or POINTER attribute, the object shall have the SAVE attribute." */
- if (c && sym->ns->proc_name
- && sym->ns->proc_name->attr.flavor == FL_MODULE
- && !sym->ns->save_all && !sym->attr.save
- && !sym->attr.pointer && !sym->attr.allocatable)
- {
- gfc_error("Object '%s' at %L must have the SAVE attribute %s",
- sym->name, &sym->declared_at,
- "for default initialization of a component");
- return FAILURE;
- }
-
- /* Assign default initializer. */
- if (sym->ts.type == BT_DERIVED
- && !sym->value
- && !sym->attr.pointer
- && !sym->attr.allocatable
- && (!flag || sym->attr.intent == INTENT_OUT))
- sym->value = gfc_default_initializer (&sym->ts);
+ if (sym->ts.type == BT_DERIVED)
+ return resolve_fl_variable_derived (sym, no_init_flag);
return SUCCESS;
}
diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c
index 682c60c99ac..b9e71149110 100644
--- a/gcc/fortran/scanner.c
+++ b/gcc/fortran/scanner.c
@@ -45,6 +45,8 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "gfortran.h"
#include "toplev.h"
+#include "debug.h"
+#include "flags.h"
/* Structure for holding module and include file search path. */
typedef struct gfc_directorylist
@@ -312,6 +314,29 @@ gfc_advance_line (void)
return;
}
+ if (gfc_current_locus.lb->next
+ && gfc_current_locus.lb->next->file != gfc_current_locus.lb->file)
+ {
+ if (gfc_current_locus.lb->next->file
+ && !gfc_current_locus.lb->next->dbg_emitted
+ && gfc_current_locus.lb->file->up == gfc_current_locus.lb->next->file)
+ {
+ /* We exit from an included file. */
+ (*debug_hooks->end_source_file)
+ (gfc_linebuf_linenum (gfc_current_locus.lb->next));
+ gfc_current_locus.lb->next->dbg_emitted = true;
+ }
+ else if (gfc_current_locus.lb->next->file != gfc_current_locus.lb->file
+ && !gfc_current_locus.lb->next->dbg_emitted)
+ {
+ /* We enter into a new file. */
+ (*debug_hooks->start_source_file)
+ (gfc_linebuf_linenum (gfc_current_locus.lb),
+ gfc_current_locus.lb->next->file->filename);
+ gfc_current_locus.lb->next->dbg_emitted = true;
+ }
+ }
+
gfc_current_locus.lb = gfc_current_locus.lb->next;
if (gfc_current_locus.lb != NULL)
@@ -372,6 +397,28 @@ skip_comment_line (void)
}
+int
+gfc_define_undef_line (void)
+{
+ /* All lines beginning with '#' are either #define or #undef. */
+ if (debug_info_level != DINFO_LEVEL_VERBOSE || gfc_peek_char () != '#')
+ return 0;
+
+ if (strncmp (gfc_current_locus.nextc, "#define ", 8) == 0)
+ (*debug_hooks->define) (gfc_linebuf_linenum (gfc_current_locus.lb),
+ &(gfc_current_locus.nextc[8]));
+
+ if (strncmp (gfc_current_locus.nextc, "#undef ", 7) == 0)
+ (*debug_hooks->undef) (gfc_linebuf_linenum (gfc_current_locus.lb),
+ &(gfc_current_locus.nextc[7]));
+
+ /* Skip the rest of the line. */
+ skip_comment_line ();
+
+ return 1;
+}
+
+
/* Comment lines are null lines, lines containing only blanks or lines
on which the first nonblank line is a '!'.
Return true if !$ openmp conditional compilation sentinel was
@@ -1505,8 +1552,18 @@ load_file (const char *filename, bool initial)
if (line[0] == '#')
{
- preprocessor_line (line);
- continue;
+ /* When -g3 is specified, it's possible that we emit #define
+ and #undef lines, which we need to pass to the middle-end
+ so that it can emit correct debug info. */
+ if (debug_info_level == DINFO_LEVEL_VERBOSE
+ && (strncmp (line, "#define ", 8) == 0
+ || strncmp (line, "#undef ", 7) == 0))
+ ;
+ else
+ {
+ preprocessor_line (line);
+ continue;
+ }
}
/* Preprocessed files have preprocessor lines added before the byte
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index e581a21603b..c9885ddd90f 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -70,6 +70,9 @@ gfc_expr gfc_bad_expr;
static gfc_expr *
range_check (gfc_expr *result, const char *name)
{
+ if (result == NULL)
+ return &gfc_bad_expr;
+
switch (gfc_range_check (result))
{
case ARITH_OK:
@@ -3651,7 +3654,7 @@ gfc_simplify_size (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
mpz_t size;
gfc_expr *result;
int d;
- int k = get_kind (BT_INTEGER, kind, "SCAN", gfc_default_integer_kind);
+ int k = get_kind (BT_INTEGER, kind, "SIZE", gfc_default_integer_kind);
if (k == -1)
return &gfc_bad_expr;
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 64a62dbd018..2edc95b0572 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -1636,8 +1636,10 @@ gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss)
if (ss->expr->ts.type == BT_CHARACTER)
{
bool const_string = get_array_ctor_strlen (&loop->pre, c, &ss->string_length);
- if (!ss->string_length)
- gfc_todo_error ("complex character array constructors");
+
+ /* Complex character array constructors should have been taken care of
+ and not end up here. */
+ gcc_assert (ss->string_length);
ss->expr->ts.cl->backend_decl = ss->string_length;
@@ -2787,9 +2789,9 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
}
}
- if (loop->dimen == 0)
- gfc_todo_error ("Unable to determine rank of expression");
-
+ /* We should have determined the rank of the expression by now. If
+ not, that's bad news. */
+ gcc_assert (loop->dimen != 0);
/* Loop over all the SS in the chain. */
for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
@@ -3280,8 +3282,9 @@ gfc_conv_loop_setup (gfc_loopinfo * loop)
loopspec[n] = ss; */
}
- if (!loopspec[n])
- gfc_todo_error ("Unable to find scalarization loop specifier");
+ /* We should have found the scalarization loop specifier. If not,
+ that's bad news. */
+ gcc_assert (loopspec[n]);
info = &loopspec[n]->data.info;
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index e27a04bd4c7..5b6b88bde63 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -1321,6 +1321,12 @@ build_function_decl (gfc_symbol * sym)
TREE_SIDE_EFFECTS (fndecl) = 0;
}
+ /* For -fwhole-program to work well, MAIN__ needs to have the
+ "externally_visible" attribute. */
+ if (attr.is_main_program)
+ DECL_ATTRIBUTES (fndecl)
+ = tree_cons (get_identifier("externally_visible"), NULL_TREE, NULL_TREE);
+
/* Layout the function declaration and put it in the binding level
of the current function. */
pushdecl (fndecl);
@@ -2558,6 +2564,44 @@ gfc_trans_vla_type_sizes (gfc_symbol *sym, stmtblock_t *body)
}
+/* Initialize INTENT(OUT) derived type dummies. */
+static tree
+init_intent_out_dt (gfc_symbol * proc_sym, tree body)
+{
+ stmtblock_t fnblock;
+ gfc_formal_arglist *f;
+ gfc_expr *tmpe;
+ tree tmp;
+ tree present;
+
+ gfc_init_block (&fnblock);
+
+ for (f = proc_sym->formal; f; f = f->next)
+ {
+ if (f->sym && f->sym->attr.intent == INTENT_OUT
+ && f->sym->ts.type == BT_DERIVED
+ && !f->sym->ts.derived->attr.alloc_comp
+ && f->sym->value)
+ {
+ gcc_assert (!f->sym->attr.allocatable);
+ gfc_set_sym_referenced (f->sym);
+ tmpe = gfc_lval_expr_from_sym (f->sym);
+ tmp = gfc_trans_assignment (tmpe, f->sym->value, false);
+
+ present = gfc_conv_expr_present (f->sym);
+ tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present,
+ tmp, build_empty_stmt ());
+ gfc_add_expr_to_block (&fnblock, tmp);
+ gfc_free_expr (tmpe);
+ }
+ }
+
+ gfc_add_expr_to_block (&fnblock, body);
+ return gfc_finish_block (&fnblock);
+}
+
+
+
/* Generate function entry and exit code, and add it to the function body.
This includes:
Allocation and initialization of array variables.
@@ -2612,6 +2656,11 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody)
&& proc_sym->ts.type == BT_COMPLEX);
}
+ /* Initialize the INTENT(OUT) derived type dummy arguments. This
+ should be done here so that the offsets and lbounds of arrays
+ are available. */
+ fnbody = init_intent_out_dt (proc_sym, fnbody);
+
for (sym = proc_sym->tlink; sym != proc_sym; sym = sym->tlink)
{
bool sym_has_alloc_comp = (sym->ts.type == BT_DERIVED)
@@ -2710,27 +2759,6 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody)
if (TREE_CODE (f->sym->ts.cl->backend_decl) == PARM_DECL)
gfc_trans_vla_type_sizes (f->sym, &body);
}
-
- /* If an INTENT(OUT) dummy of derived type has a default
- initializer, it must be initialized here. */
- if (f->sym && f->sym->attr.intent == INTENT_OUT
- && f->sym->ts.type == BT_DERIVED
- && !f->sym->ts.derived->attr.alloc_comp
- && f->sym->value)
- {
- gfc_expr *tmpe;
- tree tmp, present;
- gcc_assert (!f->sym->attr.allocatable);
- gfc_set_sym_referenced (f->sym);
- tmpe = gfc_lval_expr_from_sym (f->sym);
- tmp = gfc_trans_assignment (tmpe, f->sym->value, false);
-
- present = gfc_conv_expr_present (f->sym);
- tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present,
- tmp, build_empty_stmt ());
- gfc_add_expr_to_block (&body, tmp);
- gfc_free_expr (tmpe);
- }
}
if (gfc_return_by_reference (proc_sym) && proc_sym->ts.type == BT_CHARACTER
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index cf7d1e13450..7cc0c6fe10f 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -4269,10 +4269,9 @@ gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
default:
/* This probably meant someone forgot to add an intrinsic to the above
- list(s) when they implemented it, or something's gone horribly wrong.
- */
- gfc_todo_error ("Scalarization of non-elemental intrinsic: %s",
- expr->value.function.name);
+ list(s) when they implemented it, or something's gone horribly
+ wrong. */
+ gcc_unreachable ();
}
}
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 7bff3aa14b4..eafd2802777 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -632,10 +632,6 @@ struct lang_decl GTY(())
#define GFC_TYPE_ARRAY_DATAPTR_TYPE(node) \
(TYPE_LANG_SPECIFIC(node)->dataptr_type)
-/* I changed this from sorry(...) because it should not return. */
-/* TODO: Remove gfc_todo_error before releasing version 1.0. */
-#define gfc_todo_error(args...) fatal_error("gfc_todo: Not Implemented: " args)
-
/* Build an expression with void type. */
#define build1_v(code, arg) build1(code, void_type_node, arg)
#define build2_v(code, arg1, arg2) build2(code, void_type_node, \
diff --git a/gcc/function.c b/gcc/function.c
index c55918d0572..d9521f67ccc 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -5719,7 +5719,7 @@ match_asm_constraints_1 (rtx insn, rtx *p_sets, int noutputs)
which wouldn't have happen without this pass. So, iterate over
all operands and replace all occurences of the register used. */
for (j = 0; j < noutputs; j++)
- if (!rtx_equal_p (SET_DEST (p_sets[j]), output)
+ if (!rtx_equal_p (SET_DEST (p_sets[j]), input)
&& reg_overlap_mentioned_p (input, SET_DEST (p_sets[j])))
SET_DEST (p_sets[j]) = replace_rtx (SET_DEST (p_sets[j]),
input, output);
diff --git a/gcc/global.c b/gcc/global.c
index b74629381de..f1964f4fc1d 100644
--- a/gcc/global.c
+++ b/gcc/global.c
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
#include "df.h"
#include "vecprim.h"
#include "dbgcnt.h"
+#include "ra.h"
/* This pass of the compiler performs global register allocation.
It assigns hard register numbers to all the pseudo registers
@@ -62,148 +63,48 @@ along with GCC; see the file COPYING3. If not see
reg numbers to allocnos and vice versa.
max_allocno gets the number of allocnos in use.
- 2. Allocate a max_allocno by max_allocno conflict bit matrix and clear it.
- Allocate a max_allocno by FIRST_PSEUDO_REGISTER conflict matrix
- for conflicts between allocnos and explicit hard register use
- (which includes use of pseudo-registers allocated by local_alloc).
+ 2. Allocate a max_allocno by max_allocno compressed triangular conflict
+ bit matrix (a triangular bit matrix with portions removed for which we
+ can guarantee there are no conflicts, example: two local pseudos that
+ live in different basic blocks) and clear it. This is called "conflict".
+ Note that for triangular bit matrices, there are two possible equations
+ for computing the bit number for two allocnos: LOW and HIGH (LOW < HIGH):
- 3. For each basic block
- walk forward through the block, recording which
- pseudo-registers and which hardware registers are live.
- Build the conflict matrix between the pseudo-registers
- and another of pseudo-registers versus hardware registers.
- Also record the preferred hardware registers
- for each pseudo-register.
+ 1) BITNUM = f(HIGH) + LOW, where
+ f(HIGH) = (HIGH * (HIGH - 1)) / 2
- 4. Sort a table of the allocnos into order of
- desirability of the variables.
+ 2) BITNUM = f(LOW) + HIGH, where
+ f(LOW) = LOW * (max_allocno - LOW) + (LOW * (LOW - 1)) / 2 - LOW - 1
- 5. Allocate the variables in that order; each if possible into
- a preferred register, else into another register. */
-
-/* Number of pseudo-registers which are candidates for allocation. */
-
-static int max_allocno;
-
-/* Indexed by (pseudo) reg number, gives the allocno, or -1
- for pseudo registers which are not to be allocated. */
-
-static int *reg_allocno;
-
-struct allocno
-{
- int reg;
- /* Gives the number of consecutive hard registers needed by that
- pseudo reg. */
- int size;
-
- /* Number of calls crossed by each allocno. */
- int calls_crossed;
-
- /* Number of calls that might throw crossed by each allocno. */
- int throwing_calls_crossed;
-
- /* Number of refs to each allocno. */
- int n_refs;
-
- /* Frequency of uses of each allocno. */
- int freq;
-
- /* Guess at live length of each allocno.
- This is actually the max of the live lengths of the regs. */
- int live_length;
-
- /* Set of hard regs conflicting with allocno N. */
-
- HARD_REG_SET hard_reg_conflicts;
-
- /* Set of hard regs preferred by allocno N.
- This is used to make allocnos go into regs that are copied to or from them,
- when possible, to reduce register shuffling. */
-
- HARD_REG_SET hard_reg_preferences;
-
- /* Similar, but just counts register preferences made in simple copy
- operations, rather than arithmetic. These are given priority because
- we can always eliminate an insn by using these, but using a register
- in the above list won't always eliminate an insn. */
-
- HARD_REG_SET hard_reg_copy_preferences;
-
- /* Similar to hard_reg_preferences, but includes bits for subsequent
- registers when an allocno is multi-word. The above variable is used for
- allocation while this is used to build reg_someone_prefers, below. */
+ We use the second (and less common) equation as this gives us better
+ cache locality for local allocnos that are live within the same basic
+ block. Also note that f(HIGH) and f(LOW) can be precalculated for all
+ values of HIGH and LOW, so all that is necessary to compute the bit
+ number for two allocnos LOW and HIGH is a load followed by an addition.
- HARD_REG_SET hard_reg_full_preferences;
+ Allocate a max_allocno by FIRST_PSEUDO_REGISTER conflict matrix for
+ conflicts between allocnos and explicit hard register use (which
+ includes use of pseudo-registers allocated by local_alloc). This
+ is the hard_reg_conflicts inside each allocno.
- /* Set of hard registers that some later allocno has a preference for. */
+ 3. For each basic block, walk backward through the block, recording
+ which pseudo-registers and which hardware registers are live.
+ Build the conflict matrix between the pseudo-registers and another of
+ pseudo-registers versus hardware registers.
- HARD_REG_SET regs_someone_prefers;
+ 4. For each basic block, walk backward through the block, recording
+ the preferred hardware registers for each pseudo-register.
-#ifdef STACK_REGS
- /* Set to true if allocno can't be allocated in the stack register. */
- bool no_stack_reg;
-#endif
-};
-
-static struct allocno *allocno;
+ 5. Sort a table of the allocnos into order of desirability of the variables.
+ 6. Allocate the variables in that order; each if possible into
+ a preferred register, else into another register. */
+
/* A vector of the integers from 0 to max_allocno-1,
sorted in the order of first-to-be-allocated first. */
static int *allocno_order;
-/* Define the number of bits in each element of `conflicts' and what
- type that element has. We use the largest integer format on the
- host machine. */
-
-#define INT_BITS HOST_BITS_PER_WIDE_INT
-#define INT_TYPE HOST_WIDE_INT
-
-/* max_allocno by max_allocno array of bits,
- recording whether two allocno's conflict (can't go in the same
- hardware register).
-
- `conflicts' is symmetric after the call to mirror_conflicts. */
-
-static INT_TYPE *conflicts;
-
-/* Number of ints required to hold max_allocno bits.
- This is the length of a row in `conflicts'. */
-
-static int allocno_row_words;
-
-/* Two macros to test or store 1 in an element of `conflicts'. */
-
-#define CONFLICTP(I, J) \
- (conflicts[(I) * allocno_row_words + (unsigned) (J) / INT_BITS] \
- & ((INT_TYPE) 1 << ((unsigned) (J) % INT_BITS)))
-
-/* For any allocno set in ALLOCNO_SET, set ALLOCNO to that allocno,
- and execute CODE. */
-#define EXECUTE_IF_SET_IN_ALLOCNO_SET(ALLOCNO_SET, ALLOCNO, CODE) \
-do { \
- int i_; \
- int allocno_; \
- INT_TYPE *p_ = (ALLOCNO_SET); \
- \
- for (i_ = allocno_row_words - 1, allocno_ = 0; i_ >= 0; \
- i_--, allocno_ += INT_BITS) \
- { \
- unsigned INT_TYPE word_ = (unsigned INT_TYPE) *p_++; \
- \
- for ((ALLOCNO) = allocno_; word_; word_ >>= 1, (ALLOCNO)++) \
- { \
- if (word_ & 1) \
- {CODE;} \
- } \
- } \
-} while (0)
-
-/* Set of hard regs currently live (during scan of all insns). */
-
-static HARD_REG_SET hard_regs_live;
-
/* Set of registers that global-alloc isn't supposed to use. */
static HARD_REG_SET no_global_alloc_regs;
@@ -230,21 +131,6 @@ static int local_reg_live_length[FIRST_PSEUDO_REGISTER];
#define SET_REGBIT(TABLE, I, J) SET_HARD_REG_BIT (allocno[I].TABLE, J)
-/* Bit mask for allocnos live at current point in the scan. */
-
-static INT_TYPE *allocnos_live;
-
-/* Test, set or clear bit number I in allocnos_live,
- a bit vector indexed by allocno. */
-
-#define SET_ALLOCNO_LIVE(I) \
- (allocnos_live[(unsigned) (I) / INT_BITS] \
- |= ((INT_TYPE) 1 << ((unsigned) (I) % INT_BITS)))
-
-#define CLEAR_ALLOCNO_LIVE(I) \
- (allocnos_live[(unsigned) (I) / INT_BITS] \
- &= ~((INT_TYPE) 1 << ((unsigned) (I) % INT_BITS)))
-
/* This is turned off because it doesn't work right for DImode.
(And it is only used for DImode, so the other cases are worthless.)
The problem is that it isn't true that there is NO possibility of conflict;
@@ -270,12 +156,6 @@ static struct { int allocno1, allocno2;}
no_conflict_pairs[NUM_NO_CONFLICT_PAIRS];
#endif /* 0 */
-/* Record all regs that are set in any one insn.
- Communication from mark_reg_{store,clobber} and global_conflicts. */
-
-static VEC(rtx, heap) *regs_set;
-
-
/* Return true if *LOC contains an asm. */
static int
@@ -335,24 +215,14 @@ compute_regs_asm_clobbered (char *regs_asm_clobbered)
static HARD_REG_SET eliminable_regset;
+static int regno_compare (const void *, const void *);
static int allocno_compare (const void *, const void *);
-static void global_conflicts (void);
-static void mirror_conflicts (void);
static void expand_preferences (void);
static void prune_preferences (void);
+static void set_preferences (void);
static void find_reg (int, HARD_REG_SET, int, int, int);
-static void record_one_conflict (int);
-static void record_conflicts (int *, int);
-static void mark_reg_store (rtx, const_rtx, void *);
-static void mark_reg_clobber (rtx, const_rtx, void *);
-static void mark_reg_conflicts (rtx);
-static void mark_reg_death (rtx);
-static void set_preference (rtx, rtx);
static void dump_conflicts (FILE *);
-static void reg_becomes_live (rtx, const_rtx, void *);
-static void reg_dies (int, enum machine_mode, struct insn_chain *);
-
-
+static void build_insn_chain (void);
/* Look through the list of eliminable registers. Set ELIM_SET to the
@@ -454,6 +324,8 @@ global_alloc (void)
{
int retval;
size_t i;
+ int max_blk;
+ int *num_allocnos_per_blk;
compute_regsets (&eliminable_regset, &no_global_alloc_regs);
@@ -496,9 +368,8 @@ global_alloc (void)
reg_allocno = XNEWVEC (int, max_regno);
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- reg_allocno[i] = -1;
-
+ /* Initially fill the reg_allocno array with regno's... */
+ max_blk = 0;
max_allocno = 0;
for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
/* Note that reg_live_length[i] < 0 indicates a "constant" reg
@@ -510,28 +381,88 @@ global_alloc (void)
&& (! current_function_has_nonlocal_label
|| REG_N_CALLS_CROSSED (i) == 0))
{
- reg_allocno[i] = max_allocno++;
+ int blk = regno_basic_block (i);
+ reg_allocno[max_allocno++] = i;
+ if (blk > max_blk)
+ max_blk = blk;
gcc_assert (REG_LIVE_LENGTH (i));
}
- else
- reg_allocno[i] = -1;
allocno = XCNEWVEC (struct allocno, max_allocno);
+ partial_bitnum = XNEWVEC (int, max_allocno);
+ num_allocnos_per_blk = XCNEWVEC (int, max_blk + 1);
- for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
- if (reg_allocno[i] >= 0)
- {
- int num = reg_allocno[i];
- allocno[num].reg = i;
- allocno[num].size = PSEUDO_REGNO_SIZE (i);
- allocno[num].calls_crossed += REG_N_CALLS_CROSSED (i);
- allocno[num].throwing_calls_crossed
- += REG_N_THROWING_CALLS_CROSSED (i);
- allocno[num].n_refs += REG_N_REFS (i);
- allocno[num].freq += REG_FREQ (i);
- if (allocno[num].live_length < REG_LIVE_LENGTH (i))
- allocno[num].live_length = REG_LIVE_LENGTH (i);
- }
+ /* ...so we can sort them in the order we want them to receive
+ their allocnos. */
+ qsort (reg_allocno, max_allocno, sizeof (int), regno_compare);
+
+ for (i = 0; i < (size_t) max_allocno; i++)
+ {
+ int regno = reg_allocno[i];
+ int blk = regno_basic_block (regno);
+ num_allocnos_per_blk[blk]++;
+ allocno[i].reg = regno;
+ allocno[i].size = PSEUDO_REGNO_SIZE (regno);
+ allocno[i].calls_crossed += REG_N_CALLS_CROSSED (regno);
+ allocno[i].throwing_calls_crossed
+ += REG_N_THROWING_CALLS_CROSSED (regno);
+ allocno[i].n_refs += REG_N_REFS (regno);
+ allocno[i].freq += REG_FREQ (regno);
+ if (allocno[i].live_length < REG_LIVE_LENGTH (regno))
+ allocno[i].live_length = REG_LIVE_LENGTH (regno);
+ }
+
+ /* The "global" block must contain all allocnos. */
+ num_allocnos_per_blk[0] = max_allocno;
+
+ /* Now reinitialize the reg_allocno array in terms of the
+ optimized regno to allocno mapping we created above. */
+ for (i = 0; i < (size_t) max_regno; i++)
+ reg_allocno[i] = -1;
+
+ max_bitnum = 0;
+ for (i = 0; i < (size_t) max_allocno; i++)
+ {
+ int regno = allocno[i].reg;
+ int blk = regno_basic_block (regno);
+ int row_size = --num_allocnos_per_blk[blk];
+ reg_allocno[regno] = (int) i;
+ partial_bitnum[i] = (row_size > 0) ? max_bitnum - ((int) i + 1) : -1;
+ max_bitnum += row_size;
+ }
+
+#ifdef ENABLE_CHECKING
+ gcc_assert (max_bitnum <= ((max_allocno * (max_allocno - 1)) / 2));
+#endif
+
+ if (dump_file)
+ {
+ int num_bits, num_bytes, actual_bytes;
+
+ fprintf (dump_file, "## max_blk: %d\n", max_blk);
+ fprintf (dump_file, "## max_regno: %d\n", max_regno);
+ fprintf (dump_file, "## max_allocno: %d\n", max_allocno);
+
+ num_bits = max_bitnum;
+ num_bytes = CEIL (num_bits, 8);
+ actual_bytes = num_bytes;
+ fprintf (dump_file, "## Compressed triangular bitmatrix size: ");
+ fprintf (dump_file, "%d bits, %d bytes\n", num_bits, num_bytes);
+
+ num_bits = (max_allocno * (max_allocno - 1)) / 2;
+ num_bytes = CEIL (num_bits, 8);
+ fprintf (dump_file, "## Standard triangular bitmatrix size: ");
+ fprintf (dump_file, "%d bits, %d bytes [%.2f%%]\n",
+ num_bits, num_bytes,
+ 100.0 * ((double) actual_bytes / (double) num_bytes));
+
+ num_bits = max_allocno * max_allocno;
+ num_bytes = CEIL (num_bits, 8);
+ fprintf (dump_file, "## Square bitmatrix size: ");
+ fprintf (dump_file, "%d bits, %d bytes [%.2f%%]\n",
+ num_bits, num_bytes,
+ 100.0 * ((double) actual_bytes / (double) num_bytes));
+ }
/* Calculate amount of usage of each hard reg by pseudos
allocated by local-alloc. This is to see if we want to
@@ -572,30 +503,40 @@ global_alloc (void)
fprintf (dump_file, " %d", (int)i);
fprintf (dump_file, "\n");
}
- allocno_row_words = (max_allocno + INT_BITS - 1) / INT_BITS;
-
- /* We used to use alloca here, but the size of what it would try to
- allocate would occasionally cause it to exceed the stack limit and
- cause unpredictable core dumps. Some examples were > 2Mb in size. */
- conflicts = XCNEWVEC (INT_TYPE, max_allocno * allocno_row_words);
- allocnos_live = XNEWVEC (INT_TYPE, allocno_row_words);
+ conflicts = NULL;
+ adjacency = NULL;
+ adjacency_pool = NULL;
/* If there is work to be done (at least one reg to allocate),
perform global conflict analysis and allocate the regs. */
if (max_allocno > 0)
{
- /* Make a vector that mark_reg_{store,clobber} will store in. */
- if (!regs_set)
- regs_set = VEC_alloc (rtx, heap, 10);
+ /* We used to use alloca here, but the size of what it would try to
+ allocate would occasionally cause it to exceed the stack limit and
+ cause unpredictable core dumps. Some examples were > 2Mb in size. */
+ conflicts = XCNEWVEC (HOST_WIDEST_FAST_INT,
+ CEIL(max_bitnum, HOST_BITS_PER_WIDEST_FAST_INT));
+
+ adjacency = XCNEWVEC (adjacency_t *, max_allocno);
+ adjacency_pool = create_alloc_pool ("global_alloc adjacency list pool",
+ sizeof (adjacency_t), 1024);
/* Scan all the insns and compute the conflicts among allocnos
and between allocnos and hard regs. */
global_conflicts ();
- mirror_conflicts ();
+ /* There is just too much going on in the register allocators to
+ keep things up to date. At the end we have to rescan anyway
+ because things change when the reload_completed flag is set.
+ So we just turn off scanning and we will rescan by hand.
+
+ However, we needed to do the rescanning before this point to
+ get the new insns scanned inserted by local_alloc scanned for
+ global_conflicts. */
+ df_set_flags (DF_NO_INSN_RESCAN);
/* Eliminate conflicts between pseudos and eliminable registers. If
the register is not eliminated, the pseudo won't really be able to
@@ -604,6 +545,8 @@ global_alloc (void)
So in either case, we can ignore the conflict. Likewise for
preferences. */
+ set_preferences ();
+
for (i = 0; i < (size_t) max_allocno; i++)
{
AND_COMPL_HARD_REG_SET (allocno[i].hard_reg_conflicts,
@@ -669,6 +612,7 @@ global_alloc (void)
}
free (allocno_order);
+ free (conflicts);
}
/* Do the reloads now while the allocno data still exists, so that we can
@@ -679,19 +623,50 @@ global_alloc (void)
if (n_basic_blocks > NUM_FIXED_BLOCKS)
#endif
{
- build_insn_chain (get_insns ());
+ build_insn_chain ();
retval = reload (get_insns (), 1);
}
/* Clean up. */
free (reg_allocno);
+ free (num_allocnos_per_blk);
+ free (partial_bitnum);
free (allocno);
- free (conflicts);
- free (allocnos_live);
+ if (adjacency != NULL)
+ {
+ free_alloc_pool (adjacency_pool);
+ free (adjacency);
+ }
return retval;
}
+/* Sort predicate for ordering the regnos. We want the regno to allocno
+ mapping to have the property that all "global" regnos (ie, regnos that
+ are referenced in more than one basic block) have smaller allocno values
+ than "local" regnos (ie, regnos referenced in only one basic block).
+ In addition, for two basic blocks "i" and "j" with i < j, all regnos
+ local to basic block i should have smaller allocno values than regnos
+ local to basic block j.
+ Returns -1 (1) if *v1p should be allocated before (after) *v2p. */
+
+static int
+regno_compare (const void *v1p, const void *v2p)
+{
+ int regno1 = *(const int *)v1p;
+ int regno2 = *(const int *)v2p;
+ int blk1 = REG_BASIC_BLOCK (regno1);
+ int blk2 = REG_BASIC_BLOCK (regno2);
+
+ /* Prefer lower numbered basic blocks. Note that global and unknown
+ blocks have negative values, giving them high precedence. */
+ if (blk1 - blk2)
+ return blk1 - blk2;
+
+ /* If both regs are referenced from the same block, sort by regno. */
+ return regno1 - regno2;
+}
+
/* Sort predicate for ordering the allocnos.
Returns -1 (1) if *v1 should be allocated before (after) *v2. */
@@ -720,238 +695,6 @@ allocno_compare (const void *v1p, const void *v2p)
return v1 - v2;
}
-/* Scan the rtl code and record all conflicts and register preferences in the
- conflict matrices and preference tables. */
-
-static void
-global_conflicts (void)
-{
- unsigned i;
- basic_block b;
- rtx insn;
- int *block_start_allocnos;
-
- block_start_allocnos = XNEWVEC (int, max_allocno);
-
- FOR_EACH_BB (b)
- {
- memset (allocnos_live, 0, allocno_row_words * sizeof (INT_TYPE));
-
- /* Initialize table of registers currently live
- to the state at the beginning of this basic block.
- This also marks the conflicts among hard registers
- and any allocnos that are live.
-
- For pseudo-regs, there is only one bit for each one
- no matter how many hard regs it occupies.
- This is ok; we know the size from PSEUDO_REGNO_SIZE.
- For explicit hard regs, we cannot know the size that way
- since one hard reg can be used with various sizes.
- Therefore, we must require that all the hard regs
- implicitly live as part of a multi-word hard reg
- be explicitly marked in basic_block_live_at_start. */
-
- {
- int ax = 0;
- reg_set_iterator rsi;
-
- REG_SET_TO_HARD_REG_SET (hard_regs_live, DF_RA_LIVE_TOP (b));
- EXECUTE_IF_SET_IN_REG_SET (DF_RA_LIVE_TOP (b), FIRST_PSEUDO_REGISTER, i, rsi)
- {
- int a = reg_allocno[i];
- if (a >= 0)
- {
- SET_ALLOCNO_LIVE (a);
- block_start_allocnos[ax++] = a;
- }
- else if ((a = reg_renumber[i]) >= 0)
- add_to_hard_reg_set (&hard_regs_live, PSEUDO_REGNO_MODE (i), a);
- }
-
- /* Record that each allocno now live conflicts with each hard reg
- now live.
-
- It is not necessary to mark any conflicts between pseudos at
- this point, even for pseudos which are live at the start of
- the basic block.
-
- Given two pseudos X and Y and any point in the CFG P.
-
- On any path to point P where X and Y are live one of the
- following conditions must be true:
-
- 1. X is live at some instruction on the path that
- evaluates Y.
-
- 2. Y is live at some instruction on the path that
- evaluates X.
-
- 3. Either X or Y is not evaluated on the path to P
- (i.e. it is used uninitialized) and thus the
- conflict can be ignored.
-
- In cases #1 and #2 the conflict will be recorded when we
- scan the instruction that makes either X or Y become live. */
- record_conflicts (block_start_allocnos, ax);
-
-#ifdef EH_RETURN_DATA_REGNO
- if (bb_has_eh_pred (b))
- {
- unsigned int i;
-
- for (i = 0; ; ++i)
- {
- unsigned int regno = EH_RETURN_DATA_REGNO (i);
- if (regno == INVALID_REGNUM)
- break;
- record_one_conflict (regno);
- }
- }
-#endif
-
- /* Pseudos can't go in stack regs at the start of a basic block that
- is reached by an abnormal edge. Likewise for call clobbered regs,
- because caller-save, fixup_abnormal_edges and possibly the table
- driven EH machinery are not quite ready to handle such regs live
- across such edges. */
- {
- edge e;
- edge_iterator ei;
-
- FOR_EACH_EDGE (e, ei, b->preds)
- if (e->flags & EDGE_ABNORMAL)
- break;
-
- if (e != NULL)
- {
-#ifdef STACK_REGS
- EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, ax,
- {
- allocno[ax].no_stack_reg = 1;
- });
- for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++)
- record_one_conflict (ax);
-#endif
-
- /* No need to record conflicts for call clobbered regs if we have
- nonlocal labels around, as we don't ever try to allocate such
- regs in this case. */
- if (! current_function_has_nonlocal_label)
- for (ax = 0; ax < FIRST_PSEUDO_REGISTER; ax++)
- if (call_used_regs [ax])
- record_one_conflict (ax);
- }
- }
- }
-
- insn = BB_HEAD (b);
-
- /* Scan the code of this basic block, noting which allocnos
- and hard regs are born or die. When one is born,
- record a conflict with all others currently live. */
-
- while (1)
- {
- RTX_CODE code = GET_CODE (insn);
- rtx link;
-
- gcc_assert (VEC_empty (rtx, regs_set));
- if (code == INSN || code == CALL_INSN || code == JUMP_INSN)
- {
-#if 0
- int i = 0;
- for (link = REG_NOTES (insn);
- link && i < NUM_NO_CONFLICT_PAIRS;
- link = XEXP (link, 1))
- if (REG_NOTE_KIND (link) == REG_NO_CONFLICT)
- {
- no_conflict_pairs[i].allocno1
- = reg_allocno[REGNO (SET_DEST (PATTERN (insn)))];
- no_conflict_pairs[i].allocno2
- = reg_allocno[REGNO (XEXP (link, 0))];
- i++;
- }
-#endif /* 0 */
-
- /* Mark any registers clobbered by INSN as live,
- so they conflict with the inputs. */
-
- note_stores (PATTERN (insn), mark_reg_clobber, NULL);
-
-#ifdef AUTO_INC_DEC
- /* Auto-increment instructions clobber the base
- register. */
- for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
- if (REG_NOTE_KIND (link) == REG_INC)
- mark_reg_store (XEXP (link, 0), NULL_RTX, NULL);
-#endif
- /* Mark any registers dead after INSN as dead now. */
-
- for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
- if (REG_NOTE_KIND (link) == REG_DEAD)
- mark_reg_death (XEXP (link, 0));
-
- /* Mark any registers set in INSN as live,
- and mark them as conflicting with all other live regs.
- Clobbers are processed again, so they conflict with
- the registers that are set. */
-
- note_stores (PATTERN (insn), mark_reg_store, NULL);
-
- /* If INSN has multiple outputs, then any reg that dies here
- and is used inside of an output
- must conflict with the other outputs.
-
- It is unsafe to use !single_set here since it will ignore an
- unused output. Just because an output is unused does not mean
- the compiler can assume the side effect will not occur.
- Consider if REG appears in the address of an output and we
- reload the output. If we allocate REG to the same hard
- register as an unused output we could set the hard register
- before the output reload insn. */
- if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn))
- for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
- if (REG_NOTE_KIND (link) == REG_DEAD)
- {
- int used_in_output = 0;
- int i;
- rtx reg = XEXP (link, 0);
-
- for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
- {
- rtx set = XVECEXP (PATTERN (insn), 0, i);
- if (GET_CODE (set) == SET
- && !REG_P (SET_DEST (set))
- && !rtx_equal_p (reg, SET_DEST (set))
- && reg_overlap_mentioned_p (reg, SET_DEST (set)))
- used_in_output = 1;
- }
- if (used_in_output)
- mark_reg_conflicts (reg);
- }
-
- /* Mark any registers set in INSN and then never used. */
-
- while (!VEC_empty (rtx, regs_set))
- {
- rtx reg = VEC_pop (rtx, regs_set);
- rtx note = find_regno_note (insn, REG_UNUSED,
- REGNO (reg));
- if (note)
- mark_reg_death (XEXP (note, 0));
- }
- }
-
- if (insn == BB_END (b))
- break;
- insn = NEXT_INSN (insn);
- }
- }
-
- /* Clean up. */
- free (block_start_allocnos);
-}
-
/* Expand the preference information by looking for cases where one allocno
dies in an insn that sets an allocno. If those two allocnos don't conflict,
merge any preferences between those allocnos. */
@@ -975,8 +718,8 @@ expand_preferences (void)
if (REG_NOTE_KIND (link) == REG_DEAD
&& REG_P (XEXP (link, 0))
&& reg_allocno[REGNO (XEXP (link, 0))] >= 0
- && ! CONFLICTP (reg_allocno[REGNO (SET_DEST (set))],
- reg_allocno[REGNO (XEXP (link, 0))]))
+ && ! conflict_p (reg_allocno[REGNO (SET_DEST (set))],
+ reg_allocno[REGNO (XEXP (link, 0))]))
{
int a1 = reg_allocno[REGNO (SET_DEST (set))];
int a2 = reg_allocno[REGNO (XEXP (link, 0))];
@@ -999,6 +742,150 @@ expand_preferences (void)
allocno[a1].hard_reg_full_preferences);
}
}
+
+
+/* Try to set a preference for an allocno to a hard register.
+ We are passed DEST and SRC which are the operands of a SET. It is known
+ that SRC is a register. If SRC or the first operand of SRC is a register,
+ try to set a preference. If one of the two is a hard register and the other
+ is a pseudo-register, mark the preference.
+
+ Note that we are not as aggressive as local-alloc in trying to tie a
+ pseudo-register to a hard register. */
+
+static void
+set_preference (rtx dest, rtx src)
+{
+ unsigned int src_regno, dest_regno, end_regno;
+ /* Amount to add to the hard regno for SRC, or subtract from that for DEST,
+ to compensate for subregs in SRC or DEST. */
+ int offset = 0;
+ unsigned int i;
+ int copy = 1;
+
+ if (GET_RTX_FORMAT (GET_CODE (src))[0] == 'e')
+ src = XEXP (src, 0), copy = 0;
+
+ /* Get the reg number for both SRC and DEST.
+ If neither is a reg, give up. */
+
+ if (REG_P (src))
+ src_regno = REGNO (src);
+ else if (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src)))
+ {
+ src_regno = REGNO (SUBREG_REG (src));
+
+ if (REGNO (SUBREG_REG (src)) < FIRST_PSEUDO_REGISTER)
+ offset += subreg_regno_offset (REGNO (SUBREG_REG (src)),
+ GET_MODE (SUBREG_REG (src)),
+ SUBREG_BYTE (src),
+ GET_MODE (src));
+ else
+ offset += (SUBREG_BYTE (src)
+ / REGMODE_NATURAL_SIZE (GET_MODE (src)));
+ }
+ else
+ return;
+
+ if (REG_P (dest))
+ dest_regno = REGNO (dest);
+ else if (GET_CODE (dest) == SUBREG && REG_P (SUBREG_REG (dest)))
+ {
+ dest_regno = REGNO (SUBREG_REG (dest));
+
+ if (REGNO (SUBREG_REG (dest)) < FIRST_PSEUDO_REGISTER)
+ offset -= subreg_regno_offset (REGNO (SUBREG_REG (dest)),
+ GET_MODE (SUBREG_REG (dest)),
+ SUBREG_BYTE (dest),
+ GET_MODE (dest));
+ else
+ offset -= (SUBREG_BYTE (dest)
+ / REGMODE_NATURAL_SIZE (GET_MODE (dest)));
+ }
+ else
+ return;
+
+ /* Convert either or both to hard reg numbers. */
+
+ if (reg_renumber[src_regno] >= 0)
+ src_regno = reg_renumber[src_regno];
+
+ if (reg_renumber[dest_regno] >= 0)
+ dest_regno = reg_renumber[dest_regno];
+
+ /* Now if one is a hard reg and the other is a global pseudo
+ then give the other a preference. */
+
+ if (dest_regno < FIRST_PSEUDO_REGISTER && src_regno >= FIRST_PSEUDO_REGISTER
+ && reg_allocno[src_regno] >= 0)
+ {
+ dest_regno -= offset;
+ if (dest_regno < FIRST_PSEUDO_REGISTER)
+ {
+ if (copy)
+ SET_REGBIT (hard_reg_copy_preferences,
+ reg_allocno[src_regno], dest_regno);
+
+ SET_REGBIT (hard_reg_preferences,
+ reg_allocno[src_regno], dest_regno);
+ end_regno = end_hard_regno (GET_MODE (dest), dest_regno);
+ for (i = dest_regno; i < end_regno; i++)
+ SET_REGBIT (hard_reg_full_preferences, reg_allocno[src_regno], i);
+ }
+ }
+
+ if (src_regno < FIRST_PSEUDO_REGISTER && dest_regno >= FIRST_PSEUDO_REGISTER
+ && reg_allocno[dest_regno] >= 0)
+ {
+ src_regno += offset;
+ if (src_regno < FIRST_PSEUDO_REGISTER)
+ {
+ if (copy)
+ SET_REGBIT (hard_reg_copy_preferences,
+ reg_allocno[dest_regno], src_regno);
+
+ SET_REGBIT (hard_reg_preferences,
+ reg_allocno[dest_regno], src_regno);
+ end_regno = end_hard_regno (GET_MODE (src), src_regno);
+ for (i = src_regno; i < end_regno; i++)
+ SET_REGBIT (hard_reg_full_preferences, reg_allocno[dest_regno], i);
+ }
+ }
+}
+
+/* Helper function for set_preferences. */
+static void
+set_preferences_1 (rtx reg, const_rtx setter, void *data ATTRIBUTE_UNUSED)
+{
+ if (GET_CODE (reg) == SUBREG)
+ reg = SUBREG_REG (reg);
+
+ if (!REG_P (reg))
+ return;
+
+ gcc_assert (setter);
+ if (GET_CODE (setter) != CLOBBER)
+ set_preference (reg, SET_SRC (setter));
+}
+
+/* Scan all of the insns and initialize the preferences. */
+
+static void
+set_preferences (void)
+{
+ basic_block bb;
+ rtx insn;
+ FOR_EACH_BB (bb)
+ FOR_BB_INSNS_REVERSE (bb, insn)
+ {
+ if (!INSN_P (insn))
+ continue;
+
+ note_stores (PATTERN (insn), set_preferences_1, NULL);
+ }
+}
+
+
/* Prune the preferences for global registers to exclude registers that cannot
be used.
@@ -1050,14 +937,14 @@ prune_preferences (void)
these registers). */
HARD_REG_SET temp, temp2;
int allocno2;
+ adjacency_iter ai;
num = allocno_order[i];
CLEAR_HARD_REG_SET (temp);
CLEAR_HARD_REG_SET (temp2);
- EXECUTE_IF_SET_IN_ALLOCNO_SET (conflicts + num * allocno_row_words,
- allocno2,
+ FOR_EACH_CONFLICT (num, allocno2, ai)
{
if (allocno_to_order[allocno2] > i)
{
@@ -1068,7 +955,7 @@ prune_preferences (void)
IOR_HARD_REG_SET (temp2,
allocno[allocno2].hard_reg_full_preferences);
}
- });
+ }
AND_COMPL_HARD_REG_SET (temp, allocno[num].hard_reg_full_preferences);
IOR_HARD_REG_SET (temp, temp2);
@@ -1389,6 +1276,7 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere
{
int lim, j;
HARD_REG_SET this_reg;
+ adjacency_iter ai;
/* Yes. Record it as the hard register of this pseudo-reg. */
reg_renumber[allocno[num].reg] = best_reg;
@@ -1406,11 +1294,10 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere
}
/* For each other pseudo-reg conflicting with this one,
mark it as conflicting with the hard regs this one occupies. */
- lim = num;
- EXECUTE_IF_SET_IN_ALLOCNO_SET (conflicts + lim * allocno_row_words, j,
+ FOR_EACH_CONFLICT (num, j, ai)
{
IOR_HARD_REG_SET (allocno[j].hard_reg_conflicts, this_reg);
- });
+ }
}
}
@@ -1446,330 +1333,6 @@ retry_global_alloc (int regno, HARD_REG_SET forbidden_regs)
}
}
-/* Record a conflict between register REGNO
- and everything currently live.
- REGNO must not be a pseudo reg that was allocated
- by local_alloc; such numbers must be translated through
- reg_renumber before calling here. */
-
-static void
-record_one_conflict (int regno)
-{
- int j;
-
- if (regno < FIRST_PSEUDO_REGISTER)
- /* When a hard register becomes live,
- record conflicts with live pseudo regs. */
- EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, j,
- {
- SET_HARD_REG_BIT (allocno[j].hard_reg_conflicts, regno);
- });
- else
- /* When a pseudo-register becomes live,
- record conflicts first with hard regs,
- then with other pseudo regs. */
- {
- int ialloc = reg_allocno[regno];
- int ialloc_prod = ialloc * allocno_row_words;
-
- IOR_HARD_REG_SET (allocno[ialloc].hard_reg_conflicts, hard_regs_live);
- for (j = allocno_row_words - 1; j >= 0; j--)
- conflicts[ialloc_prod + j] |= allocnos_live[j];
- }
-}
-
-/* Record all allocnos currently live as conflicting
- with all hard regs currently live.
-
- ALLOCNO_VEC is a vector of LEN allocnos, all allocnos that
- are currently live. Their bits are also flagged in allocnos_live. */
-
-static void
-record_conflicts (int *allocno_vec, int len)
-{
- while (--len >= 0)
- IOR_HARD_REG_SET (allocno[allocno_vec[len]].hard_reg_conflicts,
- hard_regs_live);
-}
-
-/* If CONFLICTP (i, j) is true, make sure CONFLICTP (j, i) is also true. */
-static void
-mirror_conflicts (void)
-{
- int i, j;
- int rw = allocno_row_words;
- int rwb = rw * INT_BITS;
- INT_TYPE *p = conflicts;
- INT_TYPE *q0 = conflicts, *q1, *q2;
- unsigned INT_TYPE mask;
-
- for (i = max_allocno - 1, mask = 1; i >= 0; i--, mask <<= 1)
- {
- if (! mask)
- {
- mask = 1;
- q0++;
- }
- for (j = allocno_row_words - 1, q1 = q0; j >= 0; j--, q1 += rwb)
- {
- unsigned INT_TYPE word;
-
- for (word = (unsigned INT_TYPE) *p++, q2 = q1; word;
- word >>= 1, q2 += rw)
- {
- if (word & 1)
- *q2 |= mask;
- }
- }
- }
-}
-
-/* Handle the case where REG is set by the insn being scanned,
- during the forward scan to accumulate conflicts.
- Store a 1 in regs_live or allocnos_live for this register, record how many
- consecutive hardware registers it actually needs,
- and record a conflict with all other registers already live.
-
- Note that even if REG does not remain alive after this insn,
- we must mark it here as live, to ensure a conflict between
- REG and any other regs set in this insn that really do live.
- This is because those other regs could be considered after this.
-
- REG might actually be something other than a register;
- if so, we do nothing.
-
- SETTER is 0 if this register was modified by an auto-increment (i.e.,
- a REG_INC note was found for it). */
-
-static void
-mark_reg_store (rtx reg, const_rtx setter, void *data ATTRIBUTE_UNUSED)
-{
- int regno;
-
- if (GET_CODE (reg) == SUBREG)
- reg = SUBREG_REG (reg);
-
- if (!REG_P (reg))
- return;
-
- VEC_safe_push (rtx, heap, regs_set, reg);
-
- if (setter && GET_CODE (setter) != CLOBBER)
- set_preference (reg, SET_SRC (setter));
-
- regno = REGNO (reg);
-
- /* Either this is one of the max_allocno pseudo regs not allocated,
- or it is or has a hardware reg. First handle the pseudo-regs. */
- if (regno >= FIRST_PSEUDO_REGISTER)
- {
- if (reg_allocno[regno] >= 0)
- {
- SET_ALLOCNO_LIVE (reg_allocno[regno]);
- record_one_conflict (regno);
- }
- }
-
- if (reg_renumber[regno] >= 0)
- regno = reg_renumber[regno];
-
- /* Handle hardware regs (and pseudos allocated to hard regs). */
- if (regno < FIRST_PSEUDO_REGISTER && ! fixed_regs[regno])
- {
- int last = end_hard_regno (GET_MODE (reg), regno);
- while (regno < last)
- {
- record_one_conflict (regno);
- SET_HARD_REG_BIT (hard_regs_live, regno);
- regno++;
- }
- }
-}
-
-/* Like mark_reg_store except notice just CLOBBERs; ignore SETs. */
-
-static void
-mark_reg_clobber (rtx reg, const_rtx setter, void *data)
-{
- if (GET_CODE (setter) == CLOBBER)
- mark_reg_store (reg, setter, data);
-}
-
-/* Record that REG has conflicts with all the regs currently live.
- Do not mark REG itself as live. */
-
-static void
-mark_reg_conflicts (rtx reg)
-{
- int regno;
-
- if (GET_CODE (reg) == SUBREG)
- reg = SUBREG_REG (reg);
-
- if (!REG_P (reg))
- return;
-
- regno = REGNO (reg);
-
- /* Either this is one of the max_allocno pseudo regs not allocated,
- or it is or has a hardware reg. First handle the pseudo-regs. */
- if (regno >= FIRST_PSEUDO_REGISTER)
- {
- if (reg_allocno[regno] >= 0)
- record_one_conflict (regno);
- }
-
- if (reg_renumber[regno] >= 0)
- regno = reg_renumber[regno];
-
- /* Handle hardware regs (and pseudos allocated to hard regs). */
- if (regno < FIRST_PSEUDO_REGISTER && ! fixed_regs[regno])
- {
- int last = end_hard_regno (GET_MODE (reg), regno);
- while (regno < last)
- {
- record_one_conflict (regno);
- regno++;
- }
- }
-}
-
-/* Mark REG as being dead (following the insn being scanned now).
- Store a 0 in regs_live or allocnos_live for this register. */
-
-static void
-mark_reg_death (rtx reg)
-{
- int regno = REGNO (reg);
-
- /* Either this is one of the max_allocno pseudo regs not allocated,
- or it is a hardware reg. First handle the pseudo-regs. */
- if (regno >= FIRST_PSEUDO_REGISTER)
- {
- if (reg_allocno[regno] >= 0)
- CLEAR_ALLOCNO_LIVE (reg_allocno[regno]);
- }
-
- /* For pseudo reg, see if it has been assigned a hardware reg. */
- if (reg_renumber[regno] >= 0)
- regno = reg_renumber[regno];
-
- /* Handle hardware regs (and pseudos allocated to hard regs). */
- if (regno < FIRST_PSEUDO_REGISTER && ! fixed_regs[regno])
- /* Pseudo regs already assigned hardware regs are treated
- almost the same as explicit hardware regs. */
- remove_from_hard_reg_set (&hard_regs_live, GET_MODE (reg), regno);
-}
-
-/* Try to set a preference for an allocno to a hard register.
- We are passed DEST and SRC which are the operands of a SET. It is known
- that SRC is a register. If SRC or the first operand of SRC is a register,
- try to set a preference. If one of the two is a hard register and the other
- is a pseudo-register, mark the preference.
-
- Note that we are not as aggressive as local-alloc in trying to tie a
- pseudo-register to a hard register. */
-
-static void
-set_preference (rtx dest, rtx src)
-{
- unsigned int src_regno, dest_regno, end_regno;
- /* Amount to add to the hard regno for SRC, or subtract from that for DEST,
- to compensate for subregs in SRC or DEST. */
- int offset = 0;
- unsigned int i;
- int copy = 1;
-
- if (GET_RTX_FORMAT (GET_CODE (src))[0] == 'e')
- src = XEXP (src, 0), copy = 0;
-
- /* Get the reg number for both SRC and DEST.
- If neither is a reg, give up. */
-
- if (REG_P (src))
- src_regno = REGNO (src);
- else if (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src)))
- {
- src_regno = REGNO (SUBREG_REG (src));
-
- if (REGNO (SUBREG_REG (src)) < FIRST_PSEUDO_REGISTER)
- offset += subreg_regno_offset (REGNO (SUBREG_REG (src)),
- GET_MODE (SUBREG_REG (src)),
- SUBREG_BYTE (src),
- GET_MODE (src));
- else
- offset += (SUBREG_BYTE (src)
- / REGMODE_NATURAL_SIZE (GET_MODE (src)));
- }
- else
- return;
-
- if (REG_P (dest))
- dest_regno = REGNO (dest);
- else if (GET_CODE (dest) == SUBREG && REG_P (SUBREG_REG (dest)))
- {
- dest_regno = REGNO (SUBREG_REG (dest));
-
- if (REGNO (SUBREG_REG (dest)) < FIRST_PSEUDO_REGISTER)
- offset -= subreg_regno_offset (REGNO (SUBREG_REG (dest)),
- GET_MODE (SUBREG_REG (dest)),
- SUBREG_BYTE (dest),
- GET_MODE (dest));
- else
- offset -= (SUBREG_BYTE (dest)
- / REGMODE_NATURAL_SIZE (GET_MODE (dest)));
- }
- else
- return;
-
- /* Convert either or both to hard reg numbers. */
-
- if (reg_renumber[src_regno] >= 0)
- src_regno = reg_renumber[src_regno];
-
- if (reg_renumber[dest_regno] >= 0)
- dest_regno = reg_renumber[dest_regno];
-
- /* Now if one is a hard reg and the other is a global pseudo
- then give the other a preference. */
-
- if (dest_regno < FIRST_PSEUDO_REGISTER && src_regno >= FIRST_PSEUDO_REGISTER
- && reg_allocno[src_regno] >= 0)
- {
- dest_regno -= offset;
- if (dest_regno < FIRST_PSEUDO_REGISTER)
- {
- if (copy)
- SET_REGBIT (hard_reg_copy_preferences,
- reg_allocno[src_regno], dest_regno);
-
- SET_REGBIT (hard_reg_preferences,
- reg_allocno[src_regno], dest_regno);
- end_regno = end_hard_regno (GET_MODE (dest), dest_regno);
- for (i = dest_regno; i < end_regno; i++)
- SET_REGBIT (hard_reg_full_preferences, reg_allocno[src_regno], i);
- }
- }
-
- if (src_regno < FIRST_PSEUDO_REGISTER && dest_regno >= FIRST_PSEUDO_REGISTER
- && reg_allocno[dest_regno] >= 0)
- {
- src_regno += offset;
- if (src_regno < FIRST_PSEUDO_REGISTER)
- {
- if (copy)
- SET_REGBIT (hard_reg_copy_preferences,
- reg_allocno[dest_regno], src_regno);
-
- SET_REGBIT (hard_reg_preferences,
- reg_allocno[dest_regno], src_regno);
- end_regno = end_hard_regno (GET_MODE (src), src_regno);
- for (i = src_regno; i < end_regno; i++)
- SET_REGBIT (hard_reg_full_preferences, reg_allocno[dest_regno], i);
- }
- }
-}
-
/* Indicate that hard register number FROM was eliminated and replaced with
an offset from hard register number TO. The status of hard registers live
at the start of a basic block is updated by replacing a use of FROM with
@@ -1782,7 +1345,7 @@ mark_elimination (int from, int to)
FOR_EACH_BB (bb)
{
- regset r = DF_RA_LIVE_IN (bb);
+ regset r = DF_LIVE_IN (bb);
if (REGNO_REG_SET_P (r, from))
{
CLEAR_REGNO_REG_SET (r, from);
@@ -1791,174 +1354,239 @@ mark_elimination (int from, int to)
}
}
-/* Used for communication between the following functions. Holds the
- current life information. */
-static regset live_relevant_regs;
-
-/* Record in live_relevant_regs and REGS_SET that register REG became live.
- This is called via note_stores. */
static void
-reg_becomes_live (rtx reg, const_rtx setter ATTRIBUTE_UNUSED, void *regs_set)
+print_insn_chain (FILE *file, struct insn_chain *c)
{
- int regno;
-
- if (GET_CODE (reg) == SUBREG)
- reg = SUBREG_REG (reg);
-
- if (!REG_P (reg))
- return;
-
- regno = REGNO (reg);
- if (regno < FIRST_PSEUDO_REGISTER)
- {
- int nregs = hard_regno_nregs[regno][GET_MODE (reg)];
- while (nregs-- > 0)
- {
- if (GET_CODE (setter) == CLOBBER)
- CLEAR_REGNO_REG_SET (live_relevant_regs, regno);
- else
- SET_REGNO_REG_SET (live_relevant_regs, regno);
-
- if (!fixed_regs[regno])
- SET_REGNO_REG_SET ((regset) regs_set, regno);
- regno++;
- }
- }
- else if (reg_renumber[regno] >= 0)
- {
- if (GET_CODE (setter) == CLOBBER)
- CLEAR_REGNO_REG_SET (live_relevant_regs, regno);
- else
- SET_REGNO_REG_SET (live_relevant_regs, regno);
- SET_REGNO_REG_SET ((regset) regs_set, regno);
- }
+ fprintf (file, "insn=%d, ", INSN_UID(c->insn));
+ bitmap_print (file, &c->live_throughout, "live_throughout: ", ", ");
+ bitmap_print (file, &c->dead_or_set, "dead_or_set: ", "\n");
}
-/* Record in live_relevant_regs that register REGNO died. */
static void
-reg_dies (int regno, enum machine_mode mode, struct insn_chain *chain)
+print_insn_chains (FILE *file)
{
- if (regno < FIRST_PSEUDO_REGISTER)
- {
- int nregs = hard_regno_nregs[regno][mode];
- while (nregs-- > 0)
- {
- CLEAR_REGNO_REG_SET (live_relevant_regs, regno);
- if (! fixed_regs[regno])
- SET_REGNO_REG_SET (&chain->dead_or_set, regno);
- regno++;
- }
- }
- else
- {
- CLEAR_REGNO_REG_SET (live_relevant_regs, regno);
- if (reg_renumber[regno] >= 0)
- SET_REGNO_REG_SET (&chain->dead_or_set, regno);
- }
+ struct insn_chain *c;
+ for (c = reload_insn_chain; c ; c = c->next)
+ print_insn_chain (file, c);
}
-
/* Walk the insns of the current function and build reload_insn_chain,
and record register life information. */
-void
-build_insn_chain (rtx first)
+static void
+build_insn_chain (void)
{
+ unsigned int i;
struct insn_chain **p = &reload_insn_chain;
- struct insn_chain *prev = 0;
- basic_block b = ENTRY_BLOCK_PTR->next_bb;
+ basic_block bb;
+ struct insn_chain *c = NULL;
+ struct insn_chain *next = NULL;
+ bitmap live_relevant_regs = BITMAP_ALLOC (NULL);
+ bitmap elim_regset = BITMAP_ALLOC (NULL);
+ /* live_subregs is a vector used to keep accurate information about
+ which hardregs are live in multiword pseudos. live_subregs and
+ live_subregs_used are indexed by pseudo number. The live_subreg
+ entry for a particular pseudo is only used if the corresponding
+ element is non zero in live_subregs_used. The value in
+ live_subregs_used is number of bytes that the pseudo can
+ occupy. */
+ sbitmap *live_subregs = XCNEWVEC (sbitmap, max_regno);
+ int *live_subregs_used = XNEWVEC (int, max_regno);
- live_relevant_regs = ALLOC_REG_SET (&reg_obstack);
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (TEST_HARD_REG_BIT (eliminable_regset, i))
+ bitmap_set_bit (elim_regset, i);
- for (; first; first = NEXT_INSN (first))
+ FOR_EACH_BB_REVERSE (bb)
{
- struct insn_chain *c;
-
- if (first == BB_HEAD (b))
+ bitmap_iterator bi;
+ rtx insn;
+
+ CLEAR_REG_SET (live_relevant_regs);
+ memset (live_subregs_used, 0, max_regno * sizeof (int));
+
+ EXECUTE_IF_SET_IN_BITMAP (df_get_live_out (bb), 0, i, bi)
{
- unsigned i;
- bitmap_iterator bi;
-
- CLEAR_REG_SET (live_relevant_regs);
-
- EXECUTE_IF_SET_IN_BITMAP (df_get_live_top (b), 0, i, bi)
- {
- if (i < FIRST_PSEUDO_REGISTER
- ? ! TEST_HARD_REG_BIT (eliminable_regset, i)
- : reg_renumber[i] >= 0)
- SET_REGNO_REG_SET (live_relevant_regs, i);
- }
+ if (i >= FIRST_PSEUDO_REGISTER)
+ break;
+ bitmap_set_bit (live_relevant_regs, i);
}
- if (!NOTE_P (first) && !BARRIER_P (first))
+ EXECUTE_IF_SET_IN_BITMAP (df_get_live_out (bb), FIRST_PSEUDO_REGISTER, i, bi)
{
- c = new_insn_chain ();
- c->prev = prev;
- prev = c;
- *p = c;
- p = &c->next;
- c->insn = first;
- c->block = b->index;
-
- if (INSN_P (first))
- {
- rtx link;
-
- /* Mark the death of everything that dies in this instruction. */
-
- for (link = REG_NOTES (first); link; link = XEXP (link, 1))
- if (REG_NOTE_KIND (link) == REG_DEAD
- && REG_P (XEXP (link, 0)))
- reg_dies (REGNO (XEXP (link, 0)), GET_MODE (XEXP (link, 0)),
- c);
-
- COPY_REG_SET (&c->live_throughout, live_relevant_regs);
-
- /* Mark everything born in this instruction as live. */
-
- note_stores (PATTERN (first), reg_becomes_live,
- &c->dead_or_set);
- }
- else
- COPY_REG_SET (&c->live_throughout, live_relevant_regs);
+ if (reg_renumber[i] >= 0)
+ bitmap_set_bit (live_relevant_regs, i);
+ }
- if (INSN_P (first))
+ FOR_BB_INSNS_REVERSE (bb, insn)
+ {
+ if (!NOTE_P (insn) && !BARRIER_P (insn))
{
- rtx link;
+ unsigned int uid = INSN_UID (insn);
+ struct df_ref **def_rec;
+ struct df_ref **use_rec;
+
+ c = new_insn_chain ();
+ c->next = next;
+ next = c;
+ *p = c;
+ p = &c->prev;
+
+ c->insn = insn;
+ c->block = bb->index;
+
+ if (INSN_P (insn))
+ for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
+ {
+ struct df_ref *def = *def_rec;
+ unsigned int regno = DF_REF_REGNO (def);
+
+ /* Ignore may clobbers because these are generated
+ from calls. However, every other kind of def is
+ added to dead_or_set. */
+ if (!DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER))
+ {
+ if (regno < FIRST_PSEUDO_REGISTER)
+ {
+ if (! fixed_regs[regno])
+ bitmap_set_bit (&c->dead_or_set, regno);
+ }
+ else if (reg_renumber[regno] >= 0)
+ bitmap_set_bit (&c->dead_or_set, regno);
+ }
- /* Mark anything that is set in this insn and then unused as dying. */
+ if ((regno < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
+ && (!DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL)))
+ {
+ rtx reg = DF_REF_REG (def);
+ /* We can model subregs, but not if they are
+ wrapped in ZERO_EXTRACTS. */
+ if (GET_CODE (reg) == SUBREG
+ && !DF_REF_FLAGS_IS_SET (def, DF_REF_EXTRACT))
+ {
+ unsigned int start = SUBREG_BYTE (reg);
+ unsigned int last = start + GET_MODE_SIZE (GET_MODE (reg));
+
+ ra_init_live_subregs (bitmap_bit_p (live_relevant_regs, regno),
+ live_subregs, live_subregs_used,
+ regno, reg);
+ /* Ignore the paradoxical bits. */
+ if ((int)last > live_subregs_used[regno])
+ last = live_subregs_used[regno];
+
+ while (start < last)
+ {
+ RESET_BIT (live_subregs[regno], start);
+ start++;
+ }
+
+ if (sbitmap_empty_p (live_subregs[regno]))
+ {
+ live_subregs_used[regno] = 0;
+ bitmap_clear_bit (live_relevant_regs, regno);
+ }
+ else
+ /* Set live_relevant_regs here because
+ that bit has to be true to get us to
+ look at the live_subregs fields. */
+ bitmap_set_bit (live_relevant_regs, regno);
+ }
+ else
+ {
+ /* DF_REF_PARTIAL is generated for
+ subregs, STRICT_LOW_PART, and
+ ZERO_EXTRACT. We handle the subreg
+ case above so here we have to keep from
+ modeling the def as a killing def. */
+ if (!DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL))
+ {
+ bitmap_clear_bit (live_relevant_regs, regno);
+ live_subregs_used[regno] = 0;
+ }
+ }
+ }
+ }
+
+ bitmap_and_compl_into (live_relevant_regs, elim_regset);
+ bitmap_copy (&c->live_throughout, live_relevant_regs);
- for (link = REG_NOTES (first); link; link = XEXP (link, 1))
- if (REG_NOTE_KIND (link) == REG_UNUSED
- && REG_P (XEXP (link, 0)))
- reg_dies (REGNO (XEXP (link, 0)), GET_MODE (XEXP (link, 0)),
- c);
+ if (INSN_P (insn))
+ for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
+ {
+ struct df_ref *use = *use_rec;
+ unsigned int regno = DF_REF_REGNO (use);
+ rtx reg = DF_REF_REG (use);
+
+ /* DF_REF_READ_WRITE on a use means that this use
+ is fabricated from a def that is a partial set
+ to a multiword reg. Here, we only model the
+ subreg case that is not wrapped in ZERO_EXTRACT
+ precisely so we do not need to look at the
+ fabricated use. */
+ if (DF_REF_FLAGS_IS_SET (use, DF_REF_READ_WRITE)
+ && !DF_REF_FLAGS_IS_SET (use, DF_REF_EXTRACT)
+ && DF_REF_FLAGS_IS_SET (use, DF_REF_SUBREG))
+ continue;
+
+ /* Add the last use of each var to dead_or_set. */
+ if (!bitmap_bit_p (live_relevant_regs, regno))
+ {
+ if (regno < FIRST_PSEUDO_REGISTER)
+ {
+ if (! fixed_regs[regno])
+ bitmap_set_bit (&c->dead_or_set, regno);
+ }
+ else if (reg_renumber[regno] >= 0)
+ bitmap_set_bit (&c->dead_or_set, regno);
+ }
+
+ if (regno < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
+ {
+ if (GET_CODE (reg) == SUBREG
+ && !DF_REF_FLAGS_IS_SET (use, DF_REF_EXTRACT))
+ {
+ unsigned int start = SUBREG_BYTE (reg);
+ unsigned int last = start + GET_MODE_SIZE (GET_MODE (reg));
+
+ ra_init_live_subregs (bitmap_bit_p (live_relevant_regs, regno),
+ live_subregs, live_subregs_used,
+ regno, reg);
+
+ /* Ignore the paradoxical bits. */
+ if ((int)last > live_subregs_used[regno])
+ last = live_subregs_used[regno];
+
+ while (start < last)
+ {
+ SET_BIT (live_subregs[regno], start);
+ start++;
+ }
+ }
+ else
+ /* Resetting the live_subregs_used is
+ effectively saying do not use the subregs
+ because we are reading the whole
+ pseudo. */
+ live_subregs_used[regno] = 0;
+ bitmap_set_bit (live_relevant_regs, regno);
+ }
+ }
}
}
+ }
- if (first == BB_END (b))
- b = b->next_bb;
+ for (i = 0; i < (unsigned int)max_regno; i++)
+ if (live_subregs[i])
+ free (live_subregs[i]);
- /* Stop after we pass the end of the last basic block. Verify that
- no real insns are after the end of the last basic block.
+ reload_insn_chain = c;
+ *p = NULL;
- We may want to reorganize the loop somewhat since this test should
- always be the right exit test. Allow an ADDR_VEC or ADDR_DIF_VEC if
- the previous real insn is a JUMP_INSN. */
- if (b == EXIT_BLOCK_PTR)
- {
-#ifdef ENABLE_CHECKING
- for (first = NEXT_INSN (first); first; first = NEXT_INSN (first))
- gcc_assert (!INSN_P (first)
- || GET_CODE (PATTERN (first)) == USE
- || ((GET_CODE (PATTERN (first)) == ADDR_VEC
- || GET_CODE (PATTERN (first)) == ADDR_DIFF_VEC)
- && prev_real_insn (first) != 0
- && JUMP_P (prev_real_insn (first))));
-#endif
- break;
- }
- }
- FREE_REG_SET (live_relevant_regs);
- *p = 0;
+ free (live_subregs);
+ free (live_subregs_used);
+ BITMAP_FREE (live_relevant_regs);
+ BITMAP_FREE (elim_regset);
+
+ if (dump_file)
+ print_insn_chains (dump_file);
}
/* Print debugging trace information if -dg switch is given,
@@ -1968,6 +1596,7 @@ static void
dump_conflicts (FILE *file)
{
int i;
+ int regno;
int has_preferences;
int nregs;
nregs = 0;
@@ -1978,46 +1607,51 @@ dump_conflicts (FILE *file)
nregs++;
}
fprintf (file, ";; %d regs to allocate:", nregs);
- for (i = 0; i < max_allocno; i++)
- {
- int j;
- if (reg_renumber[allocno[allocno_order[i]].reg] >= 0)
- continue;
- fprintf (file, " %d", allocno[allocno_order[i]].reg);
- for (j = 0; j < max_regno; j++)
- if (reg_allocno[j] == allocno_order[i]
- && j != allocno[allocno_order[i]].reg)
- fprintf (file, "+%d", j);
- if (allocno[allocno_order[i]].size != 1)
- fprintf (file, " (%d)", allocno[allocno_order[i]].size);
- }
+ for (regno = 0; regno < max_regno; regno++)
+ if ((i = reg_allocno[regno]) >= 0)
+ {
+ int j;
+ if (reg_renumber[allocno[allocno_order[i]].reg] >= 0)
+ continue;
+ fprintf (file, " %d", allocno[allocno_order[i]].reg);
+ for (j = 0; j < max_regno; j++)
+ if (reg_allocno[j] == allocno_order[i]
+ && j != allocno[allocno_order[i]].reg)
+ fprintf (file, "+%d", j);
+ if (allocno[allocno_order[i]].size != 1)
+ fprintf (file, " (%d)", allocno[allocno_order[i]].size);
+ }
fprintf (file, "\n");
- for (i = 0; i < max_allocno; i++)
- {
- int j;
- fprintf (file, ";; %d conflicts:", allocno[i].reg);
- for (j = 0; j < max_allocno; j++)
- if (CONFLICTP (j, i))
- fprintf (file, " %d", allocno[j].reg);
- for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
- if (TEST_HARD_REG_BIT (allocno[i].hard_reg_conflicts, j))
- fprintf (file, " %d", j);
- fprintf (file, "\n");
-
- has_preferences = 0;
- for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
- if (TEST_HARD_REG_BIT (allocno[i].hard_reg_preferences, j))
- has_preferences = 1;
-
- if (! has_preferences)
- continue;
- fprintf (file, ";; %d preferences:", allocno[i].reg);
- for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
- if (TEST_HARD_REG_BIT (allocno[i].hard_reg_preferences, j))
- fprintf (file, " %d", j);
- fprintf (file, "\n");
- }
+ for (regno = 0; regno < max_regno; regno++)
+ if ((i = reg_allocno[regno]) >= 0)
+ {
+ int j;
+ adjacency_iter ai;
+ fprintf (file, ";; %d conflicts:", allocno[i].reg);
+ FOR_EACH_CONFLICT (i, j, ai)
+ {
+ fprintf (file, " %d", allocno[j].reg);
+ }
+ for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
+ if (TEST_HARD_REG_BIT (allocno[i].hard_reg_conflicts, j)
+ && !fixed_regs[j])
+ fprintf (file, " %d", j);
+ fprintf (file, "\n");
+
+ has_preferences = 0;
+ for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
+ if (TEST_HARD_REG_BIT (allocno[i].hard_reg_preferences, j))
+ has_preferences = 1;
+
+ if (!has_preferences)
+ continue;
+ fprintf (file, ";; %d preferences:", allocno[i].reg);
+ for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
+ if (TEST_HARD_REG_BIT (allocno[i].hard_reg_preferences, j))
+ fprintf (file, " %d", j);
+ fprintf (file, "\n");
+ }
fprintf (file, "\n");
}
@@ -2055,8 +1689,13 @@ rest_of_handle_global_alloc (void)
failure = global_alloc ();
else
{
+ /* There is just too much going on in the register allocators to
+ keep things up to date. At the end we have to rescan anyway
+ because things change when the reload_completed flag is set.
+ So we just turn off scanning and we will rescan by hand. */
+ df_set_flags (DF_NO_INSN_RESCAN);
compute_regsets (&eliminable_regset, &no_global_alloc_regs);
- build_insn_chain (get_insns ());
+ build_insn_chain ();
df_set_flags (DF_NO_INSN_RESCAN);
failure = reload (get_insns (), 0);
}
diff --git a/gcc/gthr-posix.h b/gcc/gthr-posix.h
index a290b6aab7c..5c00cd30862 100644
--- a/gcc/gthr-posix.h
+++ b/gcc/gthr-posix.h
@@ -47,6 +47,11 @@ typedef pthread_key_t __gthread_key_t;
typedef pthread_once_t __gthread_once_t;
typedef pthread_mutex_t __gthread_mutex_t;
typedef pthread_mutex_t __gthread_recursive_mutex_t;
+typedef pthread_cond_t __gthread_cond_t;
+
+/* POSIX like conditional variables are supported. Please look at comments
+ in gthr.h for details. */
+#define __GTHREAD_HAS_COND 1
#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
@@ -57,6 +62,7 @@ typedef pthread_mutex_t __gthread_recursive_mutex_t;
#else
#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
#endif
+#define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER
#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
# ifndef __gthrw_pragma
@@ -88,6 +94,8 @@ __gthrw3(pthread_mutex_lock)
__gthrw3(pthread_mutex_trylock)
__gthrw3(pthread_mutex_unlock)
__gthrw3(pthread_mutex_init)
+__gthrw3(pthread_cond_broadcast)
+__gthrw3(pthread_cond_wait)
#else
__gthrw(pthread_once)
__gthrw(pthread_getspecific)
@@ -98,6 +106,8 @@ __gthrw(pthread_mutex_lock)
__gthrw(pthread_mutex_trylock)
__gthrw(pthread_mutex_unlock)
__gthrw(pthread_mutex_init)
+__gthrw(pthread_cond_broadcast)
+__gthrw(pthread_cond_wait)
#endif
__gthrw(pthread_key_create)
@@ -110,20 +120,16 @@ __gthrw(pthread_mutexattr_destroy)
#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
/* Objective-C. */
#if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
-__gthrw3(pthread_cond_broadcast)
__gthrw3(pthread_cond_destroy)
__gthrw3(pthread_cond_init)
__gthrw3(pthread_cond_signal)
-__gthrw3(pthread_cond_wait)
__gthrw3(pthread_exit)
__gthrw3(pthread_mutex_destroy)
__gthrw3(pthread_self)
#else
-__gthrw(pthread_cond_broadcast)
__gthrw(pthread_cond_destroy)
__gthrw(pthread_cond_init)
__gthrw(pthread_cond_signal)
-__gthrw(pthread_cond_wait)
__gthrw(pthread_exit)
__gthrw(pthread_mutex_destroy)
__gthrw(pthread_self)
@@ -737,6 +743,25 @@ __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
return __gthread_mutex_unlock (mutex);
}
+static inline int
+__gthread_cond_broadcast (__gthread_cond_t *cond)
+{
+ return __gthrw_(pthread_cond_broadcast) (cond);
+}
+
+static inline int
+__gthread_cond_wait (__gthread_cond_t *cond, __gthread_mutex_t *mutex)
+{
+ return __gthrw_(pthread_cond_wait) (cond, mutex);
+}
+
+static inline int
+__gthread_cond_wait_recursive (__gthread_cond_t *cond,
+ __gthread_recursive_mutex_t *mutex)
+{
+ return __gthread_cond_wait (cond, mutex);
+}
+
#endif /* _LIBOBJC */
#endif /* ! GCC_GTHR_POSIX_H */
diff --git a/gcc/gthr-posix95.h b/gcc/gthr-posix95.h
index f0d1553193e..df250d2bf41 100644
--- a/gcc/gthr-posix95.h
+++ b/gcc/gthr-posix95.h
@@ -45,6 +45,11 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
typedef pthread_key_t __gthread_key_t;
typedef pthread_once_t __gthread_once_t;
typedef pthread_mutex_t __gthread_mutex_t;
+typedef pthread_cond_t __gthread_cond_t;
+
+/* POSIX like conditional variables are supported. Please look at comments
+ in gthr.h for details. */
+#define __GTHREAD_HAS_COND 1
typedef struct {
long depth;
@@ -55,6 +60,7 @@ typedef struct {
#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
+#define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER
#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
# define __gthrw(name) \
@@ -81,14 +87,14 @@ __gthrw(pthread_mutexattr_init)
__gthrw(pthread_mutexattr_destroy)
__gthrw(pthread_mutex_init)
+__gthrw(pthread_cond_broadcast)
+__gthrw(pthread_cond_wait)
#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
/* Objective-C. */
-__gthrw(pthread_cond_broadcast)
__gthrw(pthread_cond_destroy)
__gthrw(pthread_cond_init)
__gthrw(pthread_cond_signal)
-__gthrw(pthread_cond_wait)
__gthrw(pthread_exit)
__gthrw(pthread_mutex_destroy)
#ifdef _POSIX_PRIORITY_SCHEDULING
@@ -719,6 +725,25 @@ __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
return 0;
}
+static inline int
+__gthread_cond_broadcast (__gthread_cond_t *cond)
+{
+ return __gthrw_(pthread_cond_broadcast) (cond);
+}
+
+static inline int
+__gthread_cond_wait (__gthread_cond_t *cond, __gthread_mutex_t *mutex)
+{
+ return __gthrw_(pthread_cond_wait) (cond, mutex);
+}
+
+static inline int
+__gthread_cond_wait_recursive (__gthread_cond_t *cond,
+ __gthread_recursive_mutex_t *mutex)
+{
+ return __gthrw_(pthread_cond_wait) (cond, mutex->actual);
+}
+
#endif /* _LIBOBJC */
#endif /* ! GCC_GTHR_POSIX_H */
diff --git a/gcc/gthr.h b/gcc/gthr.h
index b9d164187c1..a37b9119922 100644
--- a/gcc/gthr.h
+++ b/gcc/gthr.h
@@ -81,6 +81,24 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
int __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex);
int __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex);
+ The following are supported in POSIX threads only. They are required to
+ fix a deadlock in static initialization inside libsupc++. The header file
+ gthr-posix.h defines a symbol __GTHREAD_HAS_COND to signify that these extra
+ features are supported.
+
+ Types:
+ __gthread_cond_t
+
+ Macros:
+ __GTHREAD_COND_INIT
+ __GTHREAD_COND_INIT_FUNCTION
+
+ Interface:
+ int __gthread_cond_broadcast (__gthread_cond_t *cond);
+ int __gthread_cond_wait (__gthread_cond_t *cond, __gthread_mutex_t *mutex);
+ int __gthread_cond_wait_recursive (__gthread_cond_t *cond,
+ __gthread_recursive_mutex_t *mutex);
+
All functions returning int should return zero on success or the error
number. If the operation is not supported, -1 is returned.
diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h
index 8e5222bad93..21030fdd2df 100644
--- a/gcc/hard-reg-set.h
+++ b/gcc/hard-reg-set.h
@@ -380,7 +380,7 @@ hard_reg_set_empty_p (const HARD_REG_SET x)
return x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 0;
}
-#else /* FIRST_PSEUDO_REGISTER > 3*HOST_BITS_PER_WIDEST_FAST_INT */
+#else /* FIRST_PSEUDO_REGISTER > 4*HOST_BITS_PER_WIDEST_FAST_INT */
#define CLEAR_HARD_REG_SET(TO) \
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
diff --git a/gcc/init-regs.c b/gcc/init-regs.c
index f84e26f697f..a9734a5dfae 100644
--- a/gcc/init-regs.c
+++ b/gcc/init-regs.c
@@ -117,7 +117,11 @@ initialize_uninitialized_regs (void)
}
if (optimize == 1)
- df_remove_problem (df_live);
+ {
+ if (dump_file)
+ df_dump (dump_file);
+ df_remove_problem (df_live);
+ }
BITMAP_FREE (already_genned);
}
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index bb22fdc36d0..4378b8f26d8 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,11 @@
+2007-10-03 Andrew Haley <aph@redhat.com>
+
+ PR java/33639
+ * class.c (mangled_classname): Detect and replace illegal
+ characters in assembly language symbols.
+ (gen_indirect_dispatch_tables): Call mangled_classname() on
+ the type.
+
2007-09-27 Jakub Jelinek <jakub@redhat.com>
* lang.c (java_print_error_function): Add third argument.
diff --git a/gcc/java/class.c b/gcc/java/class.c
index 82b71b4df18..75ee58aaedd 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -314,10 +314,63 @@ identifier_subst (const tree old_id,
tree
mangled_classname (const char *prefix, tree type)
{
+ tree result;
tree ident = TYPE_NAME (type);
if (TREE_CODE (ident) != IDENTIFIER_NODE)
ident = DECL_NAME (ident);
- return identifier_subst (ident, prefix, '.', '_', "");
+ result = identifier_subst (ident, prefix, '.', '_', "");
+
+ /* Replace any characters that aren't in the set [0-9a-zA-Z_$] with
+ "_0xXX". Class names containing such chracters are uncommon, but
+ they do sometimes occur in class files. Without this check,
+ these names cause assembly errors.
+
+ There is a possibility that a real class name could conflict with
+ the identifier we generate, but it is unlikely and will
+ immediately be detected as an assembler error. At some point we
+ should do something more elaborate (perhaps using the full
+ unicode mangling scheme) in order to prevent such a conflict. */
+ {
+ int i;
+ const int len = IDENTIFIER_LENGTH (result);
+ const char *p = IDENTIFIER_POINTER (result);
+ int illegal_chars = 0;
+
+ /* Make two passes over the identifier. The first pass is merely
+ to count illegal characters; we need to do this in order to
+ allocate a buffer. */
+ for (i = 0; i < len; i++)
+ {
+ char c = p[i];
+ illegal_chars += (! ISALNUM (c) && c != '_' && c != '$');
+ }
+
+ /* And the second pass, which is rarely executed, does the
+ rewriting. */
+ if (illegal_chars != 0)
+ {
+ char *buffer = alloca (illegal_chars * 4 + len + 1);
+ int j;
+
+ for (i = 0, j = 0; i < len; i++)
+ {
+ char c = p[i];
+ if (! ISALNUM (c) && c != '_' && c != '$')
+ {
+ buffer[j++] = '_';
+ sprintf (&buffer[j], "0x%02x", c);
+ j += 4;
+ }
+ else
+ buffer[j++] = c;
+ }
+
+ buffer[j] = 0;
+ result = get_identifier (buffer);
+ }
+ }
+
+ return result;
}
tree
@@ -389,7 +442,7 @@ while (0)
void
gen_indirect_dispatch_tables (tree type)
{
- const char *typename = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+ const char *typename = IDENTIFIER_POINTER (mangled_classname ("", type));
{
tree field = NULL;
char *buf = alloca (strlen (typename) + strlen ("_catch_classes_") + 1);
diff --git a/gcc/lambda-code.c b/gcc/lambda-code.c
index c5734375c29..84ad869a0ef 100644
--- a/gcc/lambda-code.c
+++ b/gcc/lambda-code.c
@@ -1639,7 +1639,7 @@ lle_to_gcc_expression (lambda_linear_expression lle,
/* Remove the induction variable defined at IV_STMT. */
-static void
+void
remove_iv (tree iv_stmt)
{
if (TREE_CODE (iv_stmt) == PHI_NODE)
@@ -1692,6 +1692,7 @@ void
lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
VEC(tree,heap) *old_ivs,
VEC(tree,heap) *invariants,
+ VEC(tree,heap) **remove_ivs,
lambda_loopnest new_loopnest,
lambda_trans_matrix transform,
struct obstack * lambda_obstack)
@@ -1861,7 +1862,7 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
}
/* Remove the now unused induction variable. */
- remove_iv (oldiv_stmt);
+ VEC_safe_push (tree, heap, *remove_ivs, oldiv_stmt);
}
VEC_free (tree, heap, new_ivs);
}
diff --git a/gcc/lambda.h b/gcc/lambda.h
index e7a75fdb66f..fc28d463e3c 100644
--- a/gcc/lambda.h
+++ b/gcc/lambda.h
@@ -206,8 +206,10 @@ lambda_loopnest gcc_loopnest_to_lambda_loopnest (struct loop *,
struct obstack *);
void lambda_loopnest_to_gcc_loopnest (struct loop *,
VEC(tree,heap) *, VEC(tree,heap) *,
+ VEC(tree,heap) **,
lambda_loopnest, lambda_trans_matrix,
struct obstack *);
+void remove_iv (tree);
static inline void lambda_vector_negate (lambda_vector, lambda_vector, int);
static inline void lambda_vector_mult_const (lambda_vector, lambda_vector, int, int);
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 6eca2f0497f..e0bfb67a305 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -41,7 +41,6 @@ extern void lhd_do_nothing_i (int);
extern void lhd_do_nothing_f (struct function *);
extern bool lhd_post_options (const char **);
extern alias_set_type lhd_get_alias_set (tree);
-extern tree lhd_return_tree (tree);
extern tree lhd_return_null_tree_v (void);
extern tree lhd_return_null_tree (tree);
extern tree lhd_return_null_const_tree (const_tree);
@@ -93,7 +92,6 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
#define LANG_HOOKS_MISSING_ARGUMENT hook_bool_constcharptr_size_t_false
#define LANG_HOOKS_POST_OPTIONS lhd_post_options
#define LANG_HOOKS_GET_ALIAS_SET lhd_get_alias_set
-#define LANG_HOOKS_EXPAND_CONSTANT lhd_return_tree
#define LANG_HOOKS_EXPAND_EXPR lhd_expand_expr
#define LANG_HOOKS_EXPAND_DECL lhd_expand_decl
#define LANG_HOOKS_FINISH_INCOMPLETE_DECL lhd_do_nothing_t
@@ -250,7 +248,6 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_PARSE_FILE, \
LANG_HOOKS_CLEAR_BINDING_STACK, \
LANG_HOOKS_GET_ALIAS_SET, \
- LANG_HOOKS_EXPAND_CONSTANT, \
LANG_HOOKS_EXPAND_EXPR, \
LANG_HOOKS_EXPAND_DECL, \
LANG_HOOKS_FINISH_INCOMPLETE_DECL, \
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 4682514508d..6a9a74dc70c 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -76,14 +76,6 @@ lhd_do_nothing_f (struct function * ARG_UNUSED (f))
{
}
-/* Do nothing (return the tree node passed). */
-
-tree
-lhd_return_tree (tree t)
-{
- return t;
-}
-
/* Do nothing (return NULL_TREE). */
tree
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 8a442753b1f..0efb13956d3 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -287,11 +287,6 @@ struct lang_hooks
Returns -1 if the language does nothing special for it. */
alias_set_type (*get_alias_set) (tree);
- /* Called with an expression that is to be processed as a constant.
- Returns either the same expression or a language-independent
- constant equivalent to its input. */
- tree (*expand_constant) (tree);
-
/* Called by expand_expr for language-specific tree codes.
Fourth argument is actually an enum expand_modifier. */
rtx (*expand_expr) (tree, rtx, enum machine_mode, int, rtx *);
diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c
index 83bf61ed782..63ba99c7936 100644
--- a/gcc/local-alloc.c
+++ b/gcc/local-alloc.c
@@ -1211,13 +1211,9 @@ update_equiv_regs (void)
if (!bitmap_empty_p (cleared_regs))
FOR_EACH_BB (bb)
{
- bitmap_and_compl_into (DF_RA_LIVE_IN (bb), cleared_regs);
- if (DF_RA_LIVE_TOP (bb))
- bitmap_and_compl_into (DF_RA_LIVE_TOP (bb), cleared_regs);
- bitmap_and_compl_into (DF_RA_LIVE_OUT (bb), cleared_regs);
+ bitmap_and_compl_into (DF_LIVE_IN (bb), cleared_regs);
+ bitmap_and_compl_into (DF_LIVE_OUT (bb), cleared_regs);
bitmap_and_compl_into (DF_LR_IN (bb), cleared_regs);
- if (DF_LR_TOP (bb))
- bitmap_and_compl_into (DF_LR_TOP (bb), cleared_regs);
bitmap_and_compl_into (DF_LR_OUT (bb), cleared_regs);
}
@@ -1277,6 +1273,7 @@ block_alloc (int b)
int max_uid = get_max_uid ();
int *qty_order;
int no_conflict_combined_regno = -1;
+ struct df_ref ** def_rec;
/* Count the instructions in the basic block. */
@@ -1299,7 +1296,19 @@ block_alloc (int b)
/* Initialize table of hardware registers currently live. */
- REG_SET_TO_HARD_REG_SET (regs_live, DF_LR_TOP (BASIC_BLOCK (b)));
+ REG_SET_TO_HARD_REG_SET (regs_live, DF_LR_IN (BASIC_BLOCK (b)));
+
+ /* This is conservative, as this would include registers that are
+ artificial-def'ed-but-not-used. However, artificial-defs are
+ rare, and such uninitialized use is rarer still, and the chance
+ of this having any performance impact is even less, while the
+ benefit is not having to compute and keep the TOP set around. */
+ for (def_rec = df_get_artificial_defs (b); *def_rec; def_rec++)
+ {
+ int regno = DF_REF_REGNO (*def_rec);
+ if (regno < FIRST_PSEUDO_REGISTER)
+ SET_HARD_REG_BIT (regs_live, regno);
+ }
/* This loop scans the instructions of the basic block
and assigns quantities to registers.
@@ -2502,6 +2511,49 @@ dump_local_alloc (FILE *file)
fprintf (file, ";; Register %d in %d.\n", i, reg_renumber[i]);
}
+#ifdef STACK_REGS
+static void
+find_stack_regs (void)
+{
+ bitmap stack_regs = BITMAP_ALLOC (NULL);
+ int i;
+ HARD_REG_SET stack_hard_regs, used;
+ basic_block bb;
+
+ /* Any register that MAY be allocated to a register stack (like the
+ 387) is treated poorly. Each such register is marked as being
+ live everywhere. This keeps the register allocator and the
+ subsequent passes from doing anything useful with these values.
+
+ FIXME: This seems like an incredibly poor idea. */
+
+ CLEAR_HARD_REG_SET (stack_hard_regs);
+ for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
+ SET_HARD_REG_BIT (stack_hard_regs, i);
+
+ for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+ {
+ COPY_HARD_REG_SET (used, reg_class_contents[reg_preferred_class (i)]);
+ IOR_HARD_REG_SET (used, reg_class_contents[reg_alternate_class (i)]);
+ AND_HARD_REG_SET (used, stack_hard_regs);
+ if (!hard_reg_set_empty_p (used))
+ bitmap_set_bit (stack_regs, i);
+ }
+
+ if (dump_file)
+ bitmap_print (dump_file, stack_regs, "stack regs:", "\n");
+
+ FOR_EACH_BB (bb)
+ {
+ bitmap_ior_into (DF_LIVE_IN (bb), stack_regs);
+ bitmap_and_into (DF_LIVE_IN (bb), DF_LR_IN (bb));
+ bitmap_ior_into (DF_LIVE_OUT (bb), stack_regs);
+ bitmap_and_into (DF_LIVE_OUT (bb), DF_LR_OUT (bb));
+ }
+ BITMAP_FREE (stack_regs);
+}
+#endif
+
/* Run old register allocator. Return TRUE if we must exit
rest_of_compilation upon return. */
static unsigned int
@@ -2512,26 +2564,22 @@ rest_of_handle_local_alloc (void)
df_note_add_problem ();
- if (optimize > 1)
- df_remove_problem (df_live);
- /* Create a new version of df that has the special version of UR if
- we are doing optimization. */
- if (optimize)
- df_urec_add_problem ();
+ if (optimize == 1)
+ {
+ df_live_add_problem ();
+ df_live_set_all_dirty ();
+ }
#ifdef ENABLE_CHECKING
df->changeable_flags |= DF_VERIFY_SCHEDULED;
#endif
df_analyze ();
+#ifdef STACK_REGS
+ if (optimize)
+ find_stack_regs ();
+#endif
regstat_init_n_sets_and_refs ();
regstat_compute_ri ();
- /* There is just too much going on in the register allocators to
- keep things up to date. At the end we have to rescan anyway
- because things change when the reload_completed flag is set.
- So we just turn off scanning and we will rescan by hand. */
- df_set_flags (DF_NO_INSN_RESCAN);
-
-
/* If we are not optimizing, then this is the only place before
register allocation where dataflow is done. And that is needed
to generate these warnings. */
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index 645aff67b95..39bba41c951 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -1379,7 +1379,7 @@ decompose_multiword_subregs (void)
int dup_num = recog_data.dup_num[i];
rtx *px = recog_data.operand_loc[dup_num];
- validate_change (insn, pl, *px, 1);
+ validate_unshare_change (insn, pl, *px, 1);
}
i = apply_change_group ();
diff --git a/gcc/passes.c b/gcc/passes.c
index 74f48a83401..25644bc8b5a 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -480,6 +480,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_mudflap_1);
NEXT_PASS (pass_lower_omp);
NEXT_PASS (pass_lower_cf);
+ NEXT_PASS (pass_refactor_eh);
NEXT_PASS (pass_lower_eh);
NEXT_PASS (pass_build_cfg);
NEXT_PASS (pass_lower_complex_O0);
diff --git a/gcc/ra-conflict.c b/gcc/ra-conflict.c
new file mode 100644
index 00000000000..27a9fcc81eb
--- /dev/null
+++ b/gcc/ra-conflict.c
@@ -0,0 +1,1228 @@
+/* Allocate registers for pseudo-registers that span basic blocks.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
+
+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/>. */
+
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "machmode.h"
+#include "hard-reg-set.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "flags.h"
+#include "regs.h"
+#include "function.h"
+#include "insn-config.h"
+#include "recog.h"
+#include "reload.h"
+#include "output.h"
+#include "toplev.h"
+#include "tree-pass.h"
+#include "timevar.h"
+#include "df.h"
+#include "vecprim.h"
+#include "ra.h"
+#include "sbitmap.h"
+#include "sparseset.h"
+
+/* Externs defined in regs.h. */
+
+int max_allocno;
+struct allocno *allocno;
+HOST_WIDEST_FAST_INT *conflicts;
+int *reg_allocno;
+int *partial_bitnum;
+int max_bitnum;
+alloc_pool adjacency_pool;
+adjacency_t **adjacency;
+
+typedef struct df_ref * df_ref_t;
+DEF_VEC_P(df_ref_t);
+DEF_VEC_ALLOC_P(df_ref_t,heap);
+
+/* Macros to determine the bit number within the triangular bit matrix for
+ the two allocnos Low and HIGH, with LOW strictly less than HIGH. */
+
+#define CONFLICT_BITNUM(I, J) \
+ (((I) < (J)) ? (partial_bitnum[I] + (J)) : (partial_bitnum[J] + (I)))
+
+#define CONFLICT_BITNUM_FAST(I, I_PARTIAL_BITNUM, J) \
+ (((I) < (J)) ? ((I_PARTIAL_BITNUM) + (J)) : (partial_bitnum[J] + (I)))
+
+bool
+conflict_p (int allocno1, int allocno2)
+{
+ int bitnum;
+ HOST_WIDEST_FAST_INT word, mask;
+
+#ifdef ENABLE_CHECKING
+ int blk1, blk2;
+
+ gcc_assert (allocno1 >= 0 && allocno1 < max_allocno);
+ gcc_assert (allocno2 >= 0 && allocno2 < max_allocno);
+
+ blk1 = regno_basic_block (allocno[allocno1].reg);
+ blk2 = regno_basic_block (allocno[allocno2].reg);
+ gcc_assert (blk1 == 0 || blk2 == 0 || blk1 == blk2);
+#endif
+
+ if (allocno1 == allocno2)
+ /* By definition, an allocno does not conflict with itself. */
+ return 0;
+
+ bitnum = CONFLICT_BITNUM (allocno1, allocno2);
+
+#ifdef ENABLE_CHECKING
+ gcc_assert (bitnum >= 0 && bitnum < max_bitnum);
+#endif
+
+ word = conflicts[bitnum / HOST_BITS_PER_WIDEST_FAST_INT];
+ mask = (HOST_WIDEST_FAST_INT) 1 << (bitnum % HOST_BITS_PER_WIDEST_FAST_INT);
+ return (word & mask) != 0;
+}
+
+/* Add conflict edges between ALLOCNO1 and ALLOCNO2. */
+
+static void
+set_conflict (int allocno1, int allocno2)
+{
+ int bitnum, index;
+ HOST_WIDEST_FAST_INT word, mask;
+
+#ifdef ENABLE_CHECKING
+ int blk1, blk2;
+
+ gcc_assert (allocno1 >= 0 && allocno1 < max_allocno);
+ gcc_assert (allocno2 >= 0 && allocno2 < max_allocno);
+
+ blk1 = regno_basic_block (allocno[allocno1].reg);
+ blk2 = regno_basic_block (allocno[allocno2].reg);
+ gcc_assert (blk1 == 0 || blk2 == 0 || blk1 == blk2);
+#endif
+
+ /* By definition, an allocno does not conflict with itself. */
+ if (allocno1 == allocno2)
+ return;
+
+ bitnum = CONFLICT_BITNUM (allocno1, allocno2);
+
+#ifdef ENABLE_CHECKING
+ gcc_assert (bitnum >= 0 && bitnum < max_bitnum);
+#endif
+
+ index = bitnum / HOST_BITS_PER_WIDEST_FAST_INT;
+ word = conflicts[index];
+ mask = (HOST_WIDEST_FAST_INT) 1 << (bitnum % HOST_BITS_PER_WIDEST_FAST_INT);
+
+ if ((word & mask) == 0)
+ {
+ conflicts[index] = word | mask;
+ add_neighbor (allocno1, allocno2);
+ add_neighbor (allocno2, allocno1);
+ }
+}
+
+/* Add conflict edges between ALLOCNO1 and all allocnos currently live. */
+
+static void
+set_conflicts (int allocno1, sparseset live)
+{
+ int i;
+ int bitnum, index;
+ HOST_WIDEST_FAST_INT word, mask;
+ int partial_bitnum_allocno1;
+
+#ifdef ENABLE_CHECKING
+ gcc_assert (allocno1 >= 0 && allocno1 < max_allocno);
+#endif
+
+ partial_bitnum_allocno1 = partial_bitnum[allocno1];
+
+ EXECUTE_IF_SET_IN_SPARSESET (live, i)
+ {
+ /* By definition, an allocno does not conflict with itself. */
+ if (allocno1 == i)
+ continue;
+
+#ifdef ENABLE_CHECKING
+ gcc_assert (i >= 0 && i < max_allocno);
+#endif
+
+ bitnum = CONFLICT_BITNUM_FAST (allocno1, partial_bitnum_allocno1, i);
+
+#ifdef ENABLE_CHECKING
+ gcc_assert (bitnum >= 0 && bitnum < max_bitnum);
+#endif
+
+ index = bitnum / HOST_BITS_PER_WIDEST_FAST_INT;
+ word = conflicts[index];
+ mask = (HOST_WIDEST_FAST_INT) 1 << (bitnum % HOST_BITS_PER_WIDEST_FAST_INT);
+
+ if ((word & mask) == 0)
+ {
+ conflicts[index] = word | mask;
+ add_neighbor (allocno1, i);
+ add_neighbor (i, allocno1);
+ }
+ }
+}
+
+
+/* Add a conflict between R1 and R2. */
+
+static void
+record_one_conflict_between_regnos (enum machine_mode mode1, int r1,
+ enum machine_mode mode2, int r2)
+{
+ int allocno1 = reg_allocno[r1];
+ int allocno2 = reg_allocno[r2];
+
+ if (dump_file)
+ fprintf (dump_file, " rocbr adding %d<=>%d\n", r1, r2);
+
+ if (allocno1 >= 0 && allocno2 >= 0)
+ set_conflict (allocno1, allocno2);
+ else if (allocno1 >= 0)
+ {
+ if (r2 < FIRST_PSEUDO_REGISTER)
+ add_to_hard_reg_set (&allocno[allocno1].hard_reg_conflicts, mode2, r2);
+ }
+ else if (allocno2 >= 0)
+ {
+ if (r1 < FIRST_PSEUDO_REGISTER)
+ add_to_hard_reg_set (&allocno[allocno2].hard_reg_conflicts, mode1, r1);
+ }
+
+ /* Now, recursively handle the reg_renumber cases. */
+ if (reg_renumber[r1] >= 0)
+ record_one_conflict_between_regnos (mode1, reg_renumber[r1], mode2, r2);
+
+ if (reg_renumber[r2] >= 0)
+ record_one_conflict_between_regnos (mode1, r1, mode2, reg_renumber[r2]);
+}
+
+
+/* Record a conflict between register REGNO and everything currently
+ live. REGNO must not be a pseudo reg that was allocated by
+ local_alloc; such numbers must be translated through reg_renumber
+ before calling here. */
+
+static void
+record_one_conflict (sparseset allocnos_live,
+ HARD_REG_SET *hard_regs_live, int regno)
+{
+ int i;
+
+ if (regno < FIRST_PSEUDO_REGISTER)
+ /* When a hard register becomes live, record conflicts with live
+ pseudo regs. */
+ EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
+ {
+ SET_HARD_REG_BIT (allocno[i].hard_reg_conflicts, regno);
+ if (dump_file)
+ fprintf (dump_file, " roc adding %d<=>%d\n", allocno[i].reg, regno);
+ }
+ else
+ /* When a pseudo-register becomes live, record conflicts first
+ with hard regs, then with other pseudo regs. */
+ {
+ int ialloc = reg_allocno[regno];
+
+ if (dump_file)
+ {
+ fprintf (dump_file, " roc adding %d<=>(", regno);
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (TEST_HARD_REG_BIT (*hard_regs_live, i)
+ && !TEST_HARD_REG_BIT (allocno[ialloc].hard_reg_conflicts, i))
+ fprintf (dump_file, "%d ", i);
+
+ EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
+ {
+ if (!conflict_p (ialloc, i))
+ fprintf (dump_file, "%d ", allocno[i].reg);
+ }
+ fprintf (dump_file, ")\n");
+ }
+
+ IOR_HARD_REG_SET (allocno[ialloc].hard_reg_conflicts, *hard_regs_live);
+ set_conflicts (ialloc, allocnos_live);
+ }
+}
+
+
+/* Handle the case where REG is set by the insn being scanned, during
+ the backward scan to accumulate conflicts. Record a conflict with
+ all other registers already live.
+
+ REG might actually be something other than a register; if so, we do
+ nothing. */
+
+static void
+mark_reg_store (sparseset allocnos_live,
+ HARD_REG_SET *hard_regs_live,
+ struct df_ref *ref)
+{
+ rtx reg = DF_REF_REG (ref);
+ unsigned int regno = DF_REF_REGNO (ref);
+ enum machine_mode mode = GET_MODE (reg);
+
+ /* Either this is one of the max_allocno pseudo regs not allocated,
+ or it is or has a hardware reg. First handle the pseudo-regs. */
+ if (regno >= FIRST_PSEUDO_REGISTER && reg_allocno[regno] >= 0)
+ record_one_conflict (allocnos_live, hard_regs_live, regno);
+
+ if (reg_renumber[regno] >= 0)
+ regno = reg_renumber[regno];
+
+ /* Handle hardware regs (and pseudos allocated to hard regs). */
+ if (regno < FIRST_PSEUDO_REGISTER && ! fixed_regs[regno])
+ {
+ unsigned int start = regno;
+ unsigned int last = end_hard_regno (mode, regno);
+ if ((GET_CODE (reg) == SUBREG) && !DF_REF_FLAGS_IS_SET (ref, DF_REF_EXTRACT))
+ {
+ start += subreg_regno_offset (regno, GET_MODE (SUBREG_REG (reg)),
+ SUBREG_BYTE (reg), GET_MODE (reg));
+ last = start + subreg_nregs_with_regno (regno, reg);
+ }
+
+ regno = start;
+ while (regno < last)
+ record_one_conflict (allocnos_live, hard_regs_live, regno++);
+ }
+}
+
+
+/* Return true if REGNO with MODE can be assigned to a register in
+ CL. */
+
+static bool
+may_overlap_class_p (enum machine_mode mode, unsigned int regno,
+ enum reg_class rc)
+{
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ {
+ enum reg_class pref_class = reg_preferred_class (regno);
+ enum reg_class alt_class = reg_alternate_class (regno);
+ return (reg_classes_intersect_p (rc, pref_class)
+ || reg_classes_intersect_p (rc, alt_class));
+ }
+ else
+ return in_hard_reg_set_p (reg_class_contents[rc], mode, regno);
+}
+
+
+/* SRC is an input operand to an instruction in which register DEST is
+ an output operand. SRC may be bound to a member of class SRC_CLASS
+ and DEST may be bound to an earlyclobbered register that overlaps
+ SRC_CLASS. If SRC is a register that might be allocated a member
+ of SRC_CLASS, add a conflict between it and DEST. */
+
+static void
+add_conflicts_for_earlyclobber (rtx dest, enum reg_class src_class, rtx src)
+{
+ if (GET_CODE (src) == SUBREG)
+ src = SUBREG_REG (src);
+ if (REG_P (src)
+ && may_overlap_class_p (GET_MODE (src), REGNO (src), src_class))
+ record_one_conflict_between_regnos (GET_MODE (src), REGNO (src),
+ GET_MODE (dest), REGNO (dest));
+}
+
+
+/* Look at the defs in INSN and determine if any of them are marked as
+ early clobber. If they are marked as early clobber, add a conflict
+ between any input operand that could be allocated to the same
+ register. */
+
+static void
+set_conflicts_for_earlyclobber (rtx insn)
+{
+ int alt;
+ int def;
+ int use;
+
+ extract_insn (insn);
+ preprocess_constraints ();
+
+ if (dump_file)
+ fprintf (dump_file, " starting early clobber conflicts.\n");
+
+ for (alt = 0; alt < recog_data.n_alternatives; alt++)
+ for (def = 0; def < recog_data.n_operands; def++)
+ if ((recog_op_alt[def][alt].earlyclobber)
+ && (recog_op_alt[def][alt].cl != NO_REGS))
+ {
+ rtx dreg = recog_data.operand[def];
+ enum machine_mode dmode = recog_data.operand_mode[def];
+ if (GET_CODE (dreg) == SUBREG)
+ dreg = SUBREG_REG (dreg);
+ if (REG_P (dreg)
+ && may_overlap_class_p (dmode, REGNO (dreg), recog_op_alt[def][alt].cl))
+
+ for (use = 0; use < recog_data.n_operands; use++)
+ if (use != def
+ && recog_data.operand_type[use] != OP_OUT
+ && reg_classes_intersect_p (recog_op_alt[def][alt].cl,
+ recog_op_alt[use][alt].cl))
+ {
+ add_conflicts_for_earlyclobber (dreg,
+ recog_op_alt[use][alt].cl,
+ recog_data.operand[use]);
+ /* Reload may end up swapping commutative operands,
+ so you have to take both orderings into account.
+ The constraints for the two operands can be
+ completely different. (Indeed, if the
+ constraints for the two operands are the same
+ for all alternatives, there's no point marking
+ them as commutative.) */
+ if (use < recog_data.n_operands + 1
+ && recog_data.constraints[use][0] == '%')
+ add_conflicts_for_earlyclobber (dreg,
+ recog_op_alt[use][alt].cl,
+ recog_data.operand[use + 1]);
+ }
+ }
+
+ if (dump_file)
+ fprintf (dump_file, " finished early clobber conflicts.\n");
+}
+
+
+/* Init LIVE_SUBREGS[ALLOCNUM] and LIVE_SUBREGS_USED[ALLOCNUM] using
+ REG to the the number of nregs, and INIT_VALUE to get the
+ initialization. ALLOCNUM need not be the regno of REG. */
+
+void
+ra_init_live_subregs (bool init_value,
+ sbitmap *live_subregs,
+ int *live_subregs_used,
+ int allocnum,
+ rtx reg)
+{
+ unsigned int regno = REGNO (SUBREG_REG (reg));
+ int size = GET_MODE_SIZE (GET_MODE (regno_reg_rtx[regno]));
+
+ gcc_assert (size > 0);
+
+ /* Been there, done that. */
+ if (live_subregs_used[allocnum])
+ return;
+
+ /* Create a new one with zeros. */
+ if (live_subregs[allocnum] == NULL)
+ live_subregs[allocnum] = sbitmap_alloc (size);
+
+ /* If the entire reg was live before blasting into subregs, we need
+ to init all of the subregs to ones else init to 0. */
+ if (init_value)
+ sbitmap_ones (live_subregs[allocnum]);
+ else
+ sbitmap_zero (live_subregs[allocnum]);
+
+ /* Set the number of bits that we really want. */
+ live_subregs_used[allocnum] = size;
+}
+
+
+/* Set REG to be not live in the sets ALLOCNOS_LIVE, LIVE_SUBREGS,
+ HARD_REGS_LIVE. If EXTRACT is false, assume that the entire reg is
+ set not live even if REG is a subreg. */
+
+inline static void
+clear_reg_in_live (sparseset allocnos_live,
+ sbitmap *live_subregs,
+ int *live_subregs_used,
+ HARD_REG_SET *hard_regs_live,
+ rtx reg,
+ bool extract)
+{
+ unsigned int regno = (GET_CODE (reg) == SUBREG)
+ ? REGNO (SUBREG_REG (reg)): REGNO (reg);
+ int allocnum = reg_allocno[regno];
+
+ if (allocnum >= 0)
+ {
+ if ((GET_CODE (reg) == SUBREG) && !extract)
+
+ {
+ unsigned int start = SUBREG_BYTE (reg);
+ unsigned int last = start + GET_MODE_SIZE (GET_MODE (reg));
+
+ ra_init_live_subregs (sparseset_bit_p (allocnos_live, allocnum),
+ live_subregs, live_subregs_used, allocnum, reg);
+
+ /* Ignore the paradoxical bits. */
+ if ((int)last > live_subregs_used[allocnum])
+ last = live_subregs_used[allocnum];
+
+ while (start < last)
+ {
+ RESET_BIT (live_subregs[allocnum], start);
+ start++;
+ }
+
+ if (sbitmap_empty_p (live_subregs[allocnum]))
+ {
+ live_subregs_used[allocnum] = 0;
+ sparseset_clear_bit (allocnos_live, allocnum);
+ }
+ else
+ /* Set the allocnos live here because that bit has to be
+ true to get us to look at the live_subregs fields. */
+ sparseset_set_bit (allocnos_live, allocnum);
+ }
+ else
+ {
+ /* Resetting the live_subregs_used is effectively saying do not use the
+ subregs because we are writing the whole pseudo. */
+ live_subregs_used[allocnum] = 0;
+ sparseset_clear_bit (allocnos_live, allocnum);
+ }
+ }
+
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ return;
+
+ /* Handle hardware regs (and pseudos allocated to hard regs). */
+ if (! fixed_regs[regno])
+ {
+ unsigned int start = regno;
+ if ((GET_CODE (reg) == SUBREG) && !extract)
+ {
+ unsigned int last;
+ start += SUBREG_BYTE (reg);
+ last = start + subreg_nregs_with_regno (regno, reg);
+ regno = start;
+
+ while (regno < last)
+ {
+ CLEAR_HARD_REG_BIT (*hard_regs_live, regno);
+ regno++;
+ }
+ }
+ else
+ remove_from_hard_reg_set (hard_regs_live, GET_MODE (reg), regno);
+ }
+}
+
+
+
+/* Set REG to be live in the sets ALLOCNOS_LIVE, LIVE_SUBREGS,
+ HARD_REGS_LIVE. If EXTRACT is false, assume that the entire reg is
+ set live even if REG is a subreg. */
+
+inline static void
+set_reg_in_live (sparseset allocnos_live,
+ sbitmap *live_subregs,
+ int *live_subregs_used,
+ HARD_REG_SET *hard_regs_live,
+ rtx reg,
+ bool extract)
+{
+ unsigned int regno = (GET_CODE (reg) == SUBREG)
+ ? REGNO (SUBREG_REG (reg)): REGNO (reg);
+ int allocnum = reg_allocno[regno];
+
+ if (allocnum >= 0)
+ {
+ if ((GET_CODE (reg) == SUBREG) && !extract)
+ {
+ unsigned int start = SUBREG_BYTE (reg);
+ unsigned int last = start + GET_MODE_SIZE (GET_MODE (reg));
+
+ ra_init_live_subregs (sparseset_bit_p (allocnos_live, allocnum),
+ live_subregs, live_subregs_used, allocnum, reg);
+
+ /* Ignore the paradoxical bits. */
+ if ((int)last > live_subregs_used[allocnum])
+ last = live_subregs_used[allocnum];
+
+ while (start < last)
+ {
+ SET_BIT (live_subregs[allocnum], start);
+ start++;
+ }
+ }
+ else
+ /* Resetting the live_subregs_used is effectively saying do not use the
+ subregs because we are writing the whole pseudo. */
+ live_subregs_used[allocnum] = 0;
+
+ sparseset_set_bit (allocnos_live, allocnum);
+ }
+
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ return;
+
+ /* Handle hardware regs (and pseudos allocated to hard regs). */
+ if (! fixed_regs[regno])
+ {
+ if ((GET_CODE (reg) == SUBREG) && !extract)
+ {
+ unsigned int start = regno;
+ unsigned int last;
+
+ start += subreg_regno_offset (regno, GET_MODE (SUBREG_REG (reg)),
+ SUBREG_BYTE (reg), GET_MODE (reg));
+ last = start + subreg_nregs_with_regno (regno, reg);
+ regno = start;
+
+ while (regno < last)
+ {
+ SET_HARD_REG_BIT (*hard_regs_live, regno);
+ regno++;
+ }
+ }
+ else
+ add_to_hard_reg_set (hard_regs_live, GET_MODE (reg), regno);
+ }
+}
+
+
+/* Add hard reg conflicts to RENUMBERS_LIVE assuming that pseudo in
+ allocno[ALLOCNUM] is allocated to a set of hard regs starting at
+ RENUMBER.
+
+ We are smart about the case where only subregs of REG have been
+ set, as indicated by LIVE_SUBREGS[ALLOCNUM] and
+ LIVE_SUBREGS_USED[ALLOCNUM]. See global_conflicts for description
+ of LIVE_SUBREGS and LIVE_SUBREGS_USED. */
+
+inline static void
+set_renumbers_live (HARD_REG_SET *renumbers_live,
+ sbitmap *live_subregs,
+ int *live_subregs_used,
+ int allocnum, int renumber)
+{
+ /* The width of the pseudo. */
+ int nbytes = live_subregs_used[allocnum];
+ int regno = allocno[allocnum].reg;
+ enum machine_mode mode = GET_MODE (regno_reg_rtx[regno]);
+
+ if (dump_file)
+ fprintf (dump_file, " set_renumbers_live %d->%d ",
+ regno, renumber);
+
+ if (nbytes > 0)
+ {
+ int i;
+ sbitmap live_subs = live_subregs[allocnum];
+
+ /* First figure out how many hard regs we are considering using. */
+ int target_nregs = hard_regno_nregs[renumber][mode];
+
+ /* Now figure out the number of bytes per hard reg. Note that
+ this may be different that what would be obtained by looking
+ at the mode in the pseudo. For instance, a complex number
+ made up of 2 32-bit parts gets mapped to 2 hard regs, even if
+ the hardregs are 64-bit floating point values. */
+ int target_width = nbytes / target_nregs;
+
+ if (dump_file)
+ fprintf (dump_file, "target_nregs=%d target_width=%d nbytes=%d",
+ target_nregs, target_width, nbytes);
+
+ for (i = 0; i < target_nregs; i++)
+ {
+ int j;
+ bool set = false;
+ for (j = 0; j < target_width; j++)
+ {
+ int reg_start = i * target_width;
+ if (reg_start + j >= nbytes)
+ break;
+ set |= TEST_BIT (live_subs, reg_start + j);
+ }
+
+ if (set)
+ SET_HARD_REG_BIT (*renumbers_live, renumber + i);
+ }
+ }
+ else
+ add_to_hard_reg_set (renumbers_live, mode, renumber);
+
+ if (dump_file)
+ fprintf (dump_file, "\n");
+}
+
+/* Dump out a REF with its reg_renumber range to FILE using
+ PREFIX. */
+
+static void
+dump_ref (FILE *file,
+ const char * prefix,
+ const char * suffix,
+ rtx reg,
+ unsigned int regno,
+ sbitmap *live_subregs,
+ int *live_subregs_used
+)
+{
+ int allocnum = reg_allocno[regno];
+
+ fprintf (file, "%s %d", prefix, regno);
+ if (allocnum >= 0
+ && live_subregs_used[allocnum] > 0)
+ {
+ int j;
+ char s = '[';
+
+ for (j = 0; j < live_subregs_used[allocnum]; j++)
+ if (TEST_BIT (live_subregs[allocnum], j))
+ {
+ fprintf (dump_file, "%c%d", s, j);
+ s = ',';
+ }
+ fprintf (dump_file, "]");
+ }
+
+ if (reg_renumber[regno] >= 0)
+ {
+ enum machine_mode mode = GET_MODE (reg);
+ unsigned int start;
+ unsigned int last;
+
+ regno = reg_renumber[regno];
+
+ start = regno;
+ last = end_hard_regno (mode, regno);
+ if (GET_CODE (reg) == SUBREG)
+ {
+ start += subreg_regno_offset (regno, GET_MODE (SUBREG_REG (reg)),
+ SUBREG_BYTE (reg), GET_MODE (reg));
+ last = start + subreg_nregs_with_regno (regno, reg);
+ }
+
+ if (start == last - 1)
+ fprintf (file, "(%d)", start);
+ else
+ fprintf (file, "(%d:%d..%d)", regno, start, last-1);
+ }
+ fprintf (file, suffix);
+}
+
+
+/* Scan the rtl code and record all conflicts and register preferences in the
+ conflict matrices and preference tables. */
+
+void
+global_conflicts (void)
+{
+ unsigned int i;
+ basic_block bb;
+ rtx insn;
+
+ /* Regs that have allocnos can be in either
+ hard_regs_live (if regno < FIRST_PSEUDO_REGISTER) or
+ allocnos_live (if regno >= FIRST_PSEUDO_REGISTER) or
+ both if local_alloc has preallocated it and reg_renumber >= 0. */
+
+ HARD_REG_SET hard_regs_live;
+ HARD_REG_SET renumbers_live;
+ sparseset allocnos_live;
+ bitmap live = BITMAP_ALLOC (NULL);
+ VEC (df_ref_t, heap) *clobbers = NULL;
+ VEC (df_ref_t, heap) *dying_regs = NULL;
+
+ /* live_subregs is a vector used to keep accurate information about
+ which hardregs are live in multiword pseudos. live_subregs and
+ live_subregs_used are indexed by reg_allocno. The live_subreg
+ entry for a particular pseudo is a bitmap with one bit per byte
+ of the register. It is only used if the corresponding element is
+ non zero in live_subregs_used. The value in live_subregs_used is
+ number of bytes that the pseudo can occupy. */
+ sbitmap *live_subregs = XCNEWVEC (sbitmap, max_allocno);
+ int *live_subregs_used = XNEWVEC (int, max_allocno);
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "fixed registers : ");
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (fixed_regs[i])
+ fprintf (dump_file, "%d ", i);
+ fprintf (dump_file, "\n");
+ }
+
+ allocnos_live = sparseset_alloc (max_allocno);
+
+ FOR_EACH_BB (bb)
+ {
+ bitmap_iterator bi;
+
+ bitmap_copy (live, DF_LIVE_OUT (bb));
+ df_simulate_artificial_refs_at_end (bb, live);
+
+ sparseset_clear (allocnos_live);
+ memset (live_subregs_used, 0, max_allocno * sizeof (int));
+ CLEAR_HARD_REG_SET (hard_regs_live);
+ CLEAR_HARD_REG_SET (renumbers_live);
+
+ /* Initialize allocnos_live and hard_regs_live for bottom of block. */
+ EXECUTE_IF_SET_IN_BITMAP (live, 0, i, bi)
+ {
+ if (i >= FIRST_PSEUDO_REGISTER)
+ break;
+ if (! fixed_regs[i])
+ SET_HARD_REG_BIT (hard_regs_live, i);
+ }
+
+ EXECUTE_IF_SET_IN_BITMAP (live, FIRST_PSEUDO_REGISTER, i, bi)
+ {
+ int allocnum = reg_allocno[i];
+
+ if (allocnum >= 0)
+ {
+ int renumber = reg_renumber[i];
+ rtx reg = regno_reg_rtx[i];
+
+ set_reg_in_live (allocnos_live, live_subregs, live_subregs_used,
+ &hard_regs_live, reg, false);
+ if (renumber >= 0 && renumber < FIRST_PSEUDO_REGISTER)
+ set_renumbers_live (&renumbers_live, live_subregs, live_subregs_used,
+ allocnum, renumber);
+ }
+ }
+
+ if (dump_file)
+ fprintf (dump_file, "\nstarting basic block %d\n\n", bb->index);
+
+ FOR_BB_INSNS_REVERSE (bb, insn)
+ {
+ unsigned int uid = INSN_UID (insn);
+ struct df_ref **def_rec;
+ struct df_ref **use_rec;
+
+ if (!INSN_P (insn))
+ continue;
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "insn = %d live = hardregs [", uid);
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (TEST_HARD_REG_BIT (hard_regs_live, i))
+ fprintf (dump_file, "%d ", i);
+
+ fprintf (dump_file, "] renumbered [");
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (TEST_HARD_REG_BIT (renumbers_live, i))
+ fprintf (dump_file, "%d ", i);
+
+ fprintf (dump_file, "] pseudos [");
+ EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
+ {
+ dump_ref (dump_file, " ", "", regno_reg_rtx[allocno[i].reg],
+ allocno[i].reg, live_subregs, live_subregs_used);
+ }
+ fprintf (dump_file, "]\n");
+ }
+
+ /* Add the defs into live. Most of them will already be
+ there, the ones that are missing are the unused ones and
+ the clobbers. We do this in order to make sure that
+ interferences are added between every def and everything
+ that is live across the insn. These defs will be removed
+ later. */
+ for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
+ {
+ struct df_ref *def = *def_rec;
+
+ /* FIXME: Ignoring may clobbers is technically the wrong
+ thing to do. However the old version of the this
+ code ignores may clobbers (and instead has many
+ places in the register allocator to handle these
+ constraints). It is quite likely that with a new
+ allocator, the correct thing to do is to not ignore
+ the constraints and then do not put in the large
+ number of special checks. */
+ if (!DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER))
+ {
+ rtx reg = DF_REF_REG (def);
+ set_reg_in_live (allocnos_live, live_subregs, live_subregs_used,
+ &hard_regs_live, reg,
+ DF_REF_FLAGS_IS_SET (def, DF_REF_EXTRACT));
+ if (dump_file)
+ dump_ref (dump_file, " adding def", "\n",
+ reg, DF_REF_REGNO (def), live_subregs, live_subregs_used);
+ }
+ }
+
+ /* Add the hardregs into renumbers_live to build the
+ interferences. Renumbers_live will be rebuilt in the
+ next step from scratch, so corrupting it here is no
+ problem. */
+ IOR_HARD_REG_SET (renumbers_live, hard_regs_live);
+
+ /* Add the interferences for the defs. */
+ for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
+ {
+ struct df_ref *def = *def_rec;
+ if (!DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER))
+ mark_reg_store (allocnos_live, &renumbers_live, def);
+ }
+
+ /* Remove the defs from the live sets. Leave the partial
+ and conditional defs in the set because they do not
+ kill. */
+ VEC_truncate (df_ref_t, clobbers, 0);
+ for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
+ {
+ struct df_ref *def = *def_rec;
+
+ if (!DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL))
+ {
+ rtx reg = DF_REF_REG (def);
+
+ clear_reg_in_live (allocnos_live, live_subregs, live_subregs_used,
+ &hard_regs_live, reg,
+ DF_REF_FLAGS_IS_SET (def, DF_REF_EXTRACT));
+ if (dump_file)
+ dump_ref (dump_file, " clearing def", "\n",
+ reg, DF_REF_REGNO (def), live_subregs, live_subregs_used);
+ }
+
+ if (DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER))
+ VEC_safe_push (df_ref_t, heap, clobbers, def);
+ }
+
+ /* Go thru all of the live pseudos and reset renumbers_live.
+ We must start from scratch here because there could have
+ been several pseudos alive that have the same
+ reg_renumber and if we see a clobber for one of them, we
+ cannot not want to kill the renumbers from the other
+ pseudos. */
+ CLEAR_HARD_REG_SET (renumbers_live);
+ EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
+ {
+ unsigned int regno = allocno[i].reg;
+ int renumber = reg_renumber[regno];
+
+ if (renumber >= 0 && renumber < FIRST_PSEUDO_REGISTER)
+ set_renumbers_live (&renumbers_live, live_subregs, live_subregs_used,
+ i, renumber);
+ }
+
+ /* Add the uses to the live sets. Keep track of the regs
+ that are dying inside the insn, this set will be useful
+ later. */
+ VEC_truncate (df_ref_t, dying_regs, 0);
+ for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
+ {
+ struct df_ref *use = *use_rec;
+ unsigned int regno = DF_REF_REGNO (use);
+ bool added = false;
+ int renumber = reg_renumber[regno];
+ int allocnum = reg_allocno[regno];
+ bool renumbering = false;
+ rtx reg = DF_REF_REG (use);
+
+ /* DF_REF_READ_WRITE on a use means that this use is
+ fabricated from a def that is a partial set to a
+ multiword reg. Here, we only model the subreg case
+ precisely so we do not need to look at the fabricated
+ use unless that set also happens to wrapped in a
+ ZERO_EXTRACT. */
+ if (DF_REF_FLAGS_IS_SET (use, DF_REF_READ_WRITE)
+ && (!DF_REF_FLAGS_IS_SET (use, DF_REF_EXTRACT))
+ && DF_REF_FLAGS_IS_SET (use, DF_REF_SUBREG))
+ continue;
+
+ if (dump_file)
+ dump_ref (dump_file, " seeing use", "\n",
+ reg, regno, live_subregs, live_subregs_used);
+
+ if (allocnum >= 0)
+ {
+ if (GET_CODE (reg) == SUBREG
+ && !DF_REF_FLAGS_IS_SET (use, DF_REF_EXTRACT))
+ {
+ unsigned int start = SUBREG_BYTE (reg);
+ unsigned int last = start + GET_MODE_SIZE (GET_MODE (reg));
+
+ ra_init_live_subregs (sparseset_bit_p (allocnos_live, allocnum),
+ live_subregs, live_subregs_used, allocnum, reg);
+
+ /* Ignore the paradoxical bits. */
+ if ((int)last > live_subregs_used[allocnum])
+ last = live_subregs_used[allocnum];
+
+ while (start < last)
+ {
+ if (!TEST_BIT (live_subregs[allocnum], start))
+ {
+ if (dump_file)
+ fprintf (dump_file, " dying pseudo subreg %d[%d]\n", regno, start);
+ SET_BIT (live_subregs[allocnum], start);
+
+ added = true;
+ }
+ start++;
+ }
+
+ sparseset_set_bit (allocnos_live, allocnum);
+ if (renumber >= 0 && renumber < FIRST_PSEUDO_REGISTER)
+ set_renumbers_live (&renumbers_live, live_subregs, live_subregs_used,
+ allocnum, renumber);
+ }
+
+ else if (!sparseset_bit_p (allocnos_live, allocnum))
+ {
+ if (dump_file)
+ fprintf (dump_file, " dying pseudo\n");
+
+ /* Resetting the live_subregs_used is
+ effectively saying do not use the subregs
+ because we are reading the whole pseudo. */
+ live_subregs_used[allocnum] = 0;
+ sparseset_set_bit (allocnos_live, allocnum);
+ if (renumber >= 0 && renumber < FIRST_PSEUDO_REGISTER)
+ set_renumbers_live (&renumbers_live, live_subregs, live_subregs_used,
+ allocnum, renumber);
+ added = true;
+ }
+ }
+
+ if (renumber >= 0 && renumber < FIRST_PSEUDO_REGISTER)
+ {
+ regno = renumber;
+ renumbering = true;
+ }
+
+ if (regno < FIRST_PSEUDO_REGISTER)
+ {
+ unsigned int start = regno;
+ unsigned int last;
+ if (GET_CODE (reg) == SUBREG)
+ {
+ start += subreg_regno_offset (regno, GET_MODE (SUBREG_REG (reg)),
+ SUBREG_BYTE (reg), GET_MODE (reg));
+ last = start + subreg_nregs_with_regno (regno, reg);
+ }
+ else
+ last = end_hard_regno (GET_MODE (reg), regno);
+
+ regno = start;
+ while (regno < last)
+ {
+ if ((!TEST_HARD_REG_BIT (hard_regs_live, regno))
+ && (!TEST_HARD_REG_BIT (renumbers_live, regno))
+ && ! fixed_regs[regno])
+ {
+ if (dump_file)
+ fprintf (dump_file, " dying hard reg %d\n", regno);
+ if (renumbering)
+ SET_HARD_REG_BIT (renumbers_live, regno);
+ else
+ SET_HARD_REG_BIT (hard_regs_live, regno);
+
+ added = true;
+ }
+ regno++;
+ }
+ }
+ if (added)
+ VEC_safe_push (df_ref_t, heap, dying_regs, use);
+ }
+
+ /* These three cases are all closely related, they all deal
+ with some set of outputs of the insn need to conflict
+ with some of the registers that are used by the insn but
+ die within the insn. If no registers die within the insn,
+ the tests can be skipped. */
+
+ if (VEC_length (df_ref_t, dying_regs) > 0)
+ {
+ int k;
+ /* There appears to be an ambiguity as to what a clobber
+ means in an insn. In some cases, the clobber happens
+ within the processing of the insn and in some cases
+ it happens at the end of processing the insn. There
+ is currently no way to distinguish these two cases so
+ this code causes real clobbers to interfere with
+ registers that die within an insn.
+
+ This is consistent with the prior version of
+ interference graph builder but is was discovered
+ while developing this version of the code, that on
+ some architectures such as the x86-64, the clobbers
+ only appear to happen at the end of the insn.
+ However, the ppc-32 contains clobbers for which these
+ interferences are necessary.
+
+ FIXME: We should consider either adding a new kind of
+ clobber, or adding a flag to the clobber distinguish
+ these two cases. */
+ for (k = VEC_length (df_ref_t, clobbers) - 1; k >= 0; k--)
+ {
+ struct df_ref *def = VEC_index (df_ref_t, clobbers, k);
+ int j;
+
+ for (j = VEC_length (df_ref_t, dying_regs) - 1; j >= 0; j--)
+ {
+ struct df_ref *use = VEC_index (df_ref_t, dying_regs, j);
+ record_one_conflict_between_regnos (GET_MODE (DF_REF_REG (def)),
+ DF_REF_REGNO (def),
+ GET_MODE (DF_REF_REG (use)),
+ DF_REF_REGNO (use));
+ }
+ }
+
+ /* Early clobbers, by definition, need to not only
+ clobber the registers that are live accross the insn
+ but need to clobber the registers that die within the
+ insn. The clobbering for registers live across the
+ insn is handled above. */
+ set_conflicts_for_earlyclobber (insn);
+
+ /* If INSN is a store with multiple outputs, then any
+ reg that dies here and is used inside of the address
+ of the output must conflict with the other outputs.
+
+ FIXME: There has been some discussion as to whether
+ this is right place to handle this issue. This is a
+ hold over from an early version global conflicts.
+
+ 1) There is some evidence that code only deals with a
+ bug that is only on the m68k. The conditions of this
+ test are such that this case only triggers for a very
+ peculiar insn, one that is a parallel where one of
+ the sets is a store and the other sets a reg that is
+ used in the address of the store. See
+ http://gcc.gnu.org/ml/gcc-patches/1998-12/msg00259.html
+
+ 2) The situation that this is addressing is a bug in
+ the part of reload that handles stores, adding this
+ conflict only hides the problem. (Of course no one
+ really wants to fix reload so it is understandable
+ why a bandaid was just added here.)
+
+ Just because an output is unused does not mean the
+ compiler can assume the side effect will not occur.
+ Consider if REG appears in the address of an output
+ and we reload the output. If we allocate REG to the
+ same hard register as an unused output we could set
+ the hard register before the output reload insn.
+
+ 3) This could actually be handled by making the other
+ (non store) operand of the insn be an early clobber.
+ This would insert the same conflict, even if it is
+ not technically an early clobber. */
+
+ /* It is unsafe to use !single_set here since it will ignore an
+ unused output. */
+ if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn))
+ {
+ int j;
+ for (j = VEC_length (df_ref_t, dying_regs) - 1; j >= 0; j--)
+ {
+ int used_in_output = 0;
+ struct df_ref *use = VEC_index (df_ref_t, dying_regs, j);
+ rtx reg = DF_REF_REG (use);
+ int uregno = DF_REF_REGNO (use);
+ enum machine_mode umode = GET_MODE (DF_REF_REG (use));
+ int k;
+
+ for (k = XVECLEN (PATTERN (insn), 0) - 1; k >= 0; k--)
+ {
+ rtx set = XVECEXP (PATTERN (insn), 0, k);
+ if (GET_CODE (set) == SET
+ && !REG_P (SET_DEST (set))
+ && !rtx_equal_p (reg, SET_DEST (set))
+ && reg_overlap_mentioned_p (reg, SET_DEST (set)))
+ used_in_output = 1;
+ }
+ if (used_in_output)
+ for (k = XVECLEN (PATTERN (insn), 0) - 1; k >= 0; k--)
+ {
+ rtx set = XVECEXP (PATTERN (insn), 0, k);
+ if (GET_CODE (set) == SET
+ && REG_P (SET_DEST (set))
+ && !rtx_equal_p (reg, SET_DEST (set)))
+ record_one_conflict_between_regnos (GET_MODE (SET_DEST (set)),
+ REGNO (SET_DEST (set)),
+ umode, uregno);
+ }
+ }
+ }
+ }
+ }
+
+ /* Add the renumbers live to the hard_regs_live for the next few
+ calls. All of this gets recomputed at the top of the loop so
+ there is no harm. */
+ IOR_HARD_REG_SET (hard_regs_live, renumbers_live);
+
+#ifdef EH_RETURN_DATA_REGNO
+ if (bb_has_eh_pred (bb))
+ {
+ unsigned int i;
+
+ for (i = 0; ; ++i)
+ {
+ unsigned int regno = EH_RETURN_DATA_REGNO (i);
+ if (regno == INVALID_REGNUM)
+ break;
+ record_one_conflict (allocnos_live, &hard_regs_live, regno);
+ }
+ }
+#endif
+
+ if (bb_has_abnormal_pred (bb))
+ {
+ unsigned int i;
+#ifdef STACK_REGS
+ /* Pseudos can't go in stack regs at the start of a basic block that
+ is reached by an abnormal edge. Likewise for call clobbered regs,
+ because caller-save, fixup_abnormal_edges and possibly the table
+ driven EH machinery are not quite ready to handle such regs live
+ across such edges. */
+ EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
+ {
+ allocno[i].no_stack_reg = 1;
+ }
+
+ for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
+ record_one_conflict (allocnos_live, &hard_regs_live, i);
+#endif
+
+ /* No need to record conflicts for call clobbered regs if we have
+ nonlocal labels around, as we don't ever try to allocate such
+ regs in this case. */
+ if (! current_function_has_nonlocal_label)
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (call_used_regs [i])
+ record_one_conflict (allocnos_live, &hard_regs_live, i);
+ }
+ }
+
+ for (i = 0; i < (unsigned int)max_allocno; i++)
+ if (live_subregs[i])
+ free (live_subregs[i]);
+
+ /* Clean up. */
+ free (allocnos_live);
+ free (live_subregs);
+ free (live_subregs_used);
+ VEC_free (df_ref_t, heap, dying_regs);
+ VEC_free (df_ref_t, heap, clobbers);
+ BITMAP_FREE (live);
+}
diff --git a/gcc/ra.h b/gcc/ra.h
new file mode 100644
index 00000000000..bd4af6d2daf
--- /dev/null
+++ b/gcc/ra.h
@@ -0,0 +1,223 @@
+/* Define per-register tables for data flow info and register allocation.
+ Copyright (C) 2007 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/>. */
+
+#ifndef GCC_RA_H
+#define GCC_RA_H
+
+#include "regs.h"
+
+struct allocno
+{
+ int reg;
+ /* Gives the number of consecutive hard registers needed by that
+ pseudo reg. */
+ int size;
+
+ /* Number of calls crossed by each allocno. */
+ int calls_crossed;
+
+ /* Number of calls that might throw crossed by each allocno. */
+ int throwing_calls_crossed;
+
+ /* Number of refs to each allocno. */
+ int n_refs;
+
+ /* Frequency of uses of each allocno. */
+ int freq;
+
+ /* Guess at live length of each allocno.
+ This is actually the max of the live lengths of the regs. */
+ int live_length;
+
+ /* Set of hard regs conflicting with allocno N. */
+
+ HARD_REG_SET hard_reg_conflicts;
+
+ /* Set of hard regs preferred by allocno N.
+ This is used to make allocnos go into regs that are copied to or from them,
+ when possible, to reduce register shuffling. */
+
+ HARD_REG_SET hard_reg_preferences;
+
+ /* Similar, but just counts register preferences made in simple copy
+ operations, rather than arithmetic. These are given priority because
+ we can always eliminate an insn by using these, but using a register
+ in the above list won't always eliminate an insn. */
+
+ HARD_REG_SET hard_reg_copy_preferences;
+
+ /* Similar to hard_reg_preferences, but includes bits for subsequent
+ registers when an allocno is multi-word. The above variable is used for
+ allocation while this is used to build reg_someone_prefers, below. */
+
+ HARD_REG_SET hard_reg_full_preferences;
+
+ /* Set of hard registers that some later allocno has a preference for. */
+
+ HARD_REG_SET regs_someone_prefers;
+
+#ifdef STACK_REGS
+ /* Set to true if allocno can't be allocated in the stack register. */
+ bool no_stack_reg;
+#endif
+};
+extern struct allocno *allocno;
+
+/* In ra-conflict.c */
+
+/* Number of pseudo-registers which are candidates for allocation. */
+
+extern int max_allocno;
+
+/* max_allocno by max_allocno compressed triangular bit matrix,
+ recording whether two allocnos conflict (can't go in the same
+ hardware register). */
+
+extern HOST_WIDEST_FAST_INT *conflicts;
+
+/* Indexed by (pseudo) reg number, gives the allocno, or -1
+ for pseudo registers which are not to be allocated. */
+
+extern int *reg_allocno;
+
+/* Precalculated partial bit number in the compressed triangular bit matrix.
+ For two allocnos, the final bit number is: partial_bitnum[LOW] + HIGH. */
+
+extern int *partial_bitnum;
+
+/* Size in bits of the compressed triangular bit matrix. */
+
+extern int max_bitnum;
+
+/* The pool to allocate the adjacency list elements from. */
+
+extern alloc_pool adjacency_pool;
+
+/* The maximum number of neighbors stored in the neighbors vector before
+ we have to chain in another vector. */
+
+#define ADJACENCY_VEC_LENGTH 30
+
+/* Conflict graph adjacency list. */
+
+typedef struct adjacency_list_d
+{
+ int neighbors[ADJACENCY_VEC_LENGTH];
+ unsigned int index;
+ struct adjacency_list_d *next;
+} adjacency_t;
+
+extern adjacency_t **adjacency;
+
+/* Add NEIGHBOR to ALLOC_NO's adjacency list. It is assumed the caller
+ has already determined that NEIGHBOR is not already neighbor by
+ checking the conflict bit matrix. */
+
+static inline void
+add_neighbor (int alloc_no, int neighbor)
+{
+ adjacency_t *adjlist = adjacency[alloc_no];
+
+ if (adjlist == NULL || adjlist->index == ADJACENCY_VEC_LENGTH)
+ {
+ adjacency_t *new = pool_alloc (adjacency_pool);
+ new->index = 0;
+ new->next = adjlist;
+ adjlist = new;
+ adjacency[alloc_no] = adjlist;
+ }
+
+ adjlist->neighbors[adjlist->index++] = neighbor;
+}
+
+/* Iterator for adjacency lists. */
+
+typedef struct adjacency_iterator_d
+{
+ adjacency_t *vec;
+ unsigned int idx;
+} adjacency_iter;
+
+/* Initialize a single adjacency list iterator. */
+
+static inline int
+adjacency_iter_init (adjacency_iter *ai, int allocno1)
+{
+ ai->vec = adjacency[allocno1];
+ ai->idx = 0;
+ return ai->vec != NULL;
+}
+
+/* Test whether we have visited all of the neighbors. */
+
+static inline int
+adjacency_iter_done (adjacency_iter *ai)
+{
+ return ai->idx > ai->vec->index;
+}
+
+/* Advance to the next neighbor in AI. */
+
+static inline int
+adjacency_iter_next (adjacency_iter *ai)
+{
+ unsigned int idx = ai->idx;
+ int neighbor = ai->vec->neighbors[idx++];
+ if (idx >= ai->vec->index && ai->vec->next != NULL)
+ {
+ ai->vec = ai->vec->next;
+ ai->idx = 0;
+ }
+ else
+ ai->idx = idx;
+ return neighbor;
+}
+
+/* Return the one basic block regno is used in. If regno is used
+ in more than one basic block or if it is unknown which block it
+ is used in, return 0. */
+
+static inline int
+regno_basic_block (int regno)
+{
+ int block = REG_BASIC_BLOCK (regno);
+ if (block < 0)
+ block = 0;
+ return block;
+}
+
+extern void global_conflicts (void);
+
+/* In global.c */
+
+/* Macro to visit all of IN_ALLOCNO's neighbors. Neighbors are
+ returned in OUT_ALLOCNO for each iteration of the loop. */
+
+#define FOR_EACH_CONFLICT(IN_ALLOCNO, OUT_ALLOCNO, ITER) \
+ if (!adjacency || !adjacency_iter_init (&(ITER), (IN_ALLOCNO))) \
+ ; \
+ else \
+ for ((OUT_ALLOCNO) = adjacency_iter_next (&(ITER)); \
+ !adjacency_iter_done (&(ITER)); \
+ (OUT_ALLOCNO) = adjacency_iter_next (&(ITER)))
+
+extern void ra_init_live_subregs (bool, sbitmap *, int *, int, rtx);
+extern bool conflict_p (int, int);
+
+#endif /* GCC_RA_H */
diff --git a/gcc/reload.c b/gcc/reload.c
index e88a82de7c4..c9c5fc5c5c0 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -1521,7 +1521,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
/* Check that we don't use a hardreg for an uninitialized
pseudo. See also find_dummy_reload(). */
&& (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
- || ! bitmap_bit_p (DF_RA_LIVE_OUT (ENTRY_BLOCK_PTR),
+ || ! bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR),
ORIGINAL_REGNO (XEXP (note, 0))))
&& ! refers_to_regno_for_reload_p (regno,
end_hard_regno (rel_mode,
@@ -2000,7 +2000,7 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
as they would clobber the other live pseudo using the same.
See also PR20973. */
&& (ORIGINAL_REGNO (in) < FIRST_PSEUDO_REGISTER
- || ! bitmap_bit_p (DF_RA_LIVE_OUT (ENTRY_BLOCK_PTR),
+ || ! bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR),
ORIGINAL_REGNO (in))))
{
unsigned int regno = REGNO (in) + in_offset;
diff --git a/gcc/reload1.c b/gcc/reload1.c
index b3906b46757..6656f3ff460 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -548,7 +548,7 @@ compute_use_by_pseudos (HARD_REG_SET *to, regset from)
if (r < 0)
{
/* reload_combine uses the information from
- DF_RA_LIVE_IN (BASIC_BLOCK), which might still
+ DF_LIVE_IN (BASIC_BLOCK), which might still
contain registers that have not actually been allocated
since they have an equivalence. */
gcc_assert (reload_completed);
@@ -1158,10 +1158,7 @@ reload (rtx first, int global)
if (! frame_pointer_needed)
FOR_EACH_BB (bb)
- {
- bitmap_clear_bit (df_get_live_in (bb), HARD_FRAME_POINTER_REGNUM);
- bitmap_clear_bit (df_get_live_top (bb), HARD_FRAME_POINTER_REGNUM);
- }
+ bitmap_clear_bit (df_get_live_in (bb), HARD_FRAME_POINTER_REGNUM);
/* Come here (with failure set nonzero) if we can't get enough spill
regs. */
diff --git a/gcc/rtl.h b/gcc/rtl.h
index c68662bbf3e..c02c4aafc8b 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1094,6 +1094,7 @@ extern bool subreg_offset_representable_p (unsigned int, enum machine_mode,
unsigned int, enum machine_mode);
extern unsigned int subreg_regno (const_rtx);
extern unsigned int subreg_nregs (const_rtx);
+extern unsigned int subreg_nregs_with_regno (unsigned int, const_rtx);
extern unsigned HOST_WIDE_INT nonzero_bits (const_rtx, enum machine_mode);
extern unsigned int num_sign_bit_copies (const_rtx, enum machine_mode);
extern bool constant_pool_constant_p (rtx);
@@ -2212,7 +2213,6 @@ extern void dump_global_regs (FILE *);
/* Yes, this ifdef is silly, but HARD_REG_SET is not always defined. */
extern void retry_global_alloc (int, HARD_REG_SET);
#endif
-extern void build_insn_chain (rtx);
/* In regclass.c */
extern int reg_classes_intersect_p (enum reg_class, enum reg_class);
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 03155e09e21..fecee88e6ed 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -3263,15 +3263,25 @@ subreg_regno (const_rtx x)
unsigned int
subreg_nregs (const_rtx x)
{
+ return subreg_nregs_with_regno (REGNO (SUBREG_REG (x)), x);
+}
+
+/* Return the number of registers that a subreg REG with REGNO
+ expression refers to. This is a copy of the rtlanal.c:subreg_nregs
+ changed so that the regno can be passed in. */
+
+unsigned int
+subreg_nregs_with_regno (unsigned int regno, const_rtx x)
+{
struct subreg_info info;
rtx subreg = SUBREG_REG (x);
- int regno = REGNO (subreg);
subreg_get_info (regno, GET_MODE (subreg), SUBREG_BYTE (x), GET_MODE (x),
&info);
return info.nregs;
}
+
struct parms_set_data
{
int nregs;
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 8e02612f481..0371339d540 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2562,6 +2562,13 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
&& (unsigned HOST_WIDE_INT) INTVAL (trueop0) == GET_MODE_MASK (mode)
&& ! side_effects_p (op1))
return op0;
+ canonicalize_shift:
+ if (SHIFT_COUNT_TRUNCATED && GET_CODE (op1) == CONST_INT)
+ {
+ val = INTVAL (op1) & (GET_MODE_BITSIZE (mode) - 1);
+ if (val != INTVAL (op1))
+ return simplify_gen_binary (code, mode, op0, GEN_INT (val));
+ }
break;
case ASHIFT:
@@ -2571,7 +2578,7 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
return op0;
if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
return op0;
- break;
+ goto canonicalize_shift;
case LSHIFTRT:
if (trueop1 == CONST0_RTX (mode))
@@ -2593,7 +2600,7 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
return simplify_gen_relational (EQ, mode, imode,
XEXP (op0, 0), const0_rtx);
}
- break;
+ goto canonicalize_shift;
case SMIN:
if (width <= HOST_BITS_PER_WIDE_INT
diff --git a/gcc/sparseset.c b/gcc/sparseset.c
new file mode 100644
index 00000000000..8d7cd9373bd
--- /dev/null
+++ b/gcc/sparseset.c
@@ -0,0 +1,232 @@
+/* SparseSet implementation.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Contributed by Peter Bergner <bergner@vnet.ibm.com>
+
+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/>. */
+
+#include "libiberty.h"
+#include "sparseset.h"
+
+
+/* Allocate and clear a n_elms SparseSet. */
+
+sparseset
+sparseset_alloc (SPARSESET_ELT_TYPE n_elms)
+{
+ unsigned int n_bytes = sizeof (struct sparseset_def)
+ + ((n_elms - 1) * 2 * sizeof (SPARSESET_ELT_TYPE));
+
+ sparseset set = (sparseset) xmalloc (n_bytes);
+ set->dense = &(set->elms[0]);
+ set->sparse = &(set->elms[n_elms]);
+ set->size = n_elms;
+ sparseset_clear (set);
+ return set;
+}
+
+/* Low level routine not meant for use outside of sparseset.[ch].
+ Assumes idx1 < s->members and idx2 < s->members. */
+
+static inline void
+sparseset_swap (sparseset s, SPARSESET_ELT_TYPE idx1, SPARSESET_ELT_TYPE idx2)
+{
+ SPARSESET_ELT_TYPE tmp = s->dense[idx2];
+ sparseset_insert_bit (s, s->dense[idx1], idx2);
+ sparseset_insert_bit (s, tmp, idx1);
+}
+
+/* Operation: S = S - {e}
+ Delete e from the set S if it is a member of S. */
+
+void
+sparseset_clear_bit (sparseset s, SPARSESET_ELT_TYPE e)
+{
+ if (sparseset_bit_p (s, e))
+ {
+ SPARSESET_ELT_TYPE idx = s->sparse[e];
+ SPARSESET_ELT_TYPE iter = s->iter;
+ SPARSESET_ELT_TYPE mem = s->members - 1;
+
+ /* If we are iterating over this set and we want to delete a
+ member we've already visited, then we swap the element we
+ want to delete with the element at the current iteration
+ index so that it plays well together with the code below
+ that actually removes the element. */
+ if (s->iterating && idx <= iter)
+ {
+ if (idx < iter)
+ {
+ sparseset_swap (s, idx, iter);
+ idx = iter;
+ }
+ s->iter_inc = 0;
+ }
+
+ /* Replace the element we want to delete with the last element
+ in the dense array and then decrement s->members, effectively
+ removing the element we want to delete. */
+ sparseset_insert_bit (s, s->dense[mem], idx);
+ s->members = mem;
+ }
+}
+
+/* Operation: D = S
+ Restrictions: none. */
+
+void
+sparseset_copy (sparseset d, sparseset s)
+{
+ SPARSESET_ELT_TYPE i;
+
+ if (d == s)
+ return;
+
+ sparseset_clear (d);
+ for (i = 0; i < s->members; i++)
+ sparseset_insert_bit (d, s->dense[i], i);
+ d->members = s->members;
+}
+
+/* Operation: D = A & B.
+ Restrictions: none. */
+
+void
+sparseset_and (sparseset d, sparseset a, sparseset b)
+{
+ SPARSESET_ELT_TYPE e;
+
+ if (a == b)
+ {
+ if (d != a)
+ sparseset_copy (d, a);
+ return;
+ }
+
+ if (d == a || d == b)
+ {
+ sparseset s = (d == a) ? b : a;
+
+ EXECUTE_IF_SET_IN_SPARSESET (d, e)
+ if (!sparseset_bit_p (s, e))
+ sparseset_clear_bit (d, e);
+ }
+ else
+ {
+ sparseset sml, lrg;
+
+ if (sparseset_cardinality (a) < sparseset_cardinality (b))
+ {
+ sml = a;
+ lrg = b;
+ }
+ else
+ {
+ sml = b;
+ lrg = a;
+ }
+
+ sparseset_clear (d);
+ EXECUTE_IF_SET_IN_SPARSESET (sml, e)
+ if (sparseset_bit_p (lrg, e))
+ sparseset_set_bit (d, e);
+ }
+}
+
+/* Operation: D = A & ~B.
+ Restrictions: D != B, unless D == A == B. */
+
+void
+sparseset_and_compl (sparseset d, sparseset a, sparseset b)
+{
+ SPARSESET_ELT_TYPE e;
+
+ if (a == b)
+ {
+ sparseset_clear (d);
+ return;
+ }
+
+ gcc_assert (d != b);
+
+ if (d == a)
+ {
+ if (sparseset_cardinality (d) < sparseset_cardinality (b))
+ {
+ EXECUTE_IF_SET_IN_SPARSESET (d, e)
+ if (sparseset_bit_p (b, e))
+ sparseset_clear_bit (d, e);
+ }
+ else
+ {
+ EXECUTE_IF_SET_IN_SPARSESET (b, e)
+ sparseset_clear_bit (d, e);
+ }
+ }
+ else
+ {
+ sparseset_clear (d);
+ EXECUTE_IF_SET_IN_SPARSESET (a, e)
+ if (!sparseset_bit_p (b, e))
+ sparseset_set_bit (d, e);
+ }
+}
+
+/* Operation: D = A | B.
+ Restrictions: none. */
+
+void
+sparseset_ior (sparseset d, sparseset a, sparseset b)
+{
+ SPARSESET_ELT_TYPE e;
+
+ if (a == b)
+ sparseset_copy (d, a);
+ else if (d == b)
+ {
+ EXECUTE_IF_SET_IN_SPARSESET (a, e)
+ sparseset_set_bit (d, e);
+ }
+ else
+ {
+ if (d != a)
+ sparseset_copy (d, a);
+ EXECUTE_IF_SET_IN_SPARSESET (b, e)
+ sparseset_set_bit (d, e);
+ }
+}
+
+/* Operation: A == B
+ Restrictions: none. */
+
+bool
+sparseset_equal_p (sparseset a, sparseset b)
+{
+ SPARSESET_ELT_TYPE e;
+
+ if (a == b)
+ return true;
+
+ if (sparseset_cardinality (a) != sparseset_cardinality (b))
+ return false;
+
+ EXECUTE_IF_SET_IN_SPARSESET (a, e)
+ if (!sparseset_bit_p (b, e))
+ return false;
+
+ return true;
+}
+
diff --git a/gcc/sparseset.h b/gcc/sparseset.h
new file mode 100644
index 00000000000..96ee19acdd7
--- /dev/null
+++ b/gcc/sparseset.h
@@ -0,0 +1,162 @@
+/* SparseSet implementation.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Contributed by Peter Bergner <bergner@vnet.ibm.com>
+
+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/>. */
+
+#ifndef GCC_SPARSESET_H
+#define GCC_SPARSESET_H
+
+#include "system.h"
+#include <assert.h>
+
+#define SPARSESET_ELT_BITS ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT)
+#define SPARSESET_ELT_TYPE unsigned int
+
+/* Data Structure used for the SparseSet representation. */
+
+typedef struct sparseset_def
+{
+ SPARSESET_ELT_TYPE *dense; /* Dense array. */
+ SPARSESET_ELT_TYPE *sparse; /* Sparse array. */
+ SPARSESET_ELT_TYPE members; /* Number of elements. */
+ SPARSESET_ELT_TYPE size; /* Maximum number of elements. */
+ SPARSESET_ELT_TYPE iter; /* Iterator index. */
+ unsigned char iter_inc; /* Iteration increment amount. */
+ bool iterating;
+ SPARSESET_ELT_TYPE elms[2]; /* Combined dense and sparse arrays. */
+} *sparseset;
+
+#define sparseset_free(MAP) free(MAP)
+extern sparseset sparseset_alloc (SPARSESET_ELT_TYPE n_elms);
+extern void sparseset_clear_bit (sparseset, SPARSESET_ELT_TYPE);
+extern void sparseset_copy (sparseset, sparseset);
+extern void sparseset_and (sparseset, sparseset, sparseset);
+extern void sparseset_and_compl (sparseset, sparseset, sparseset);
+extern void sparseset_ior (sparseset, sparseset, sparseset);
+extern bool sparseset_equal_p (sparseset, sparseset);
+
+/* Operation: S = {}
+ Clear the set of all elements. */
+
+static inline void
+sparseset_clear (sparseset s)
+{
+ s->members = 0;
+ s->iterating = false;
+}
+
+/* Return the number of elements currently in the set. */
+
+static inline SPARSESET_ELT_TYPE
+sparseset_cardinality (sparseset s)
+{
+ return s->members;
+}
+
+/* Return the maximum number of elements this set can hold. */
+
+static inline SPARSESET_ELT_TYPE
+sparseset_size (sparseset s)
+{
+ return s->size;
+}
+
+/* Return true if e is a member of the set S, otherwise return false. */
+
+static inline bool
+sparseset_bit_p (sparseset s, SPARSESET_ELT_TYPE e)
+{
+ SPARSESET_ELT_TYPE idx;
+
+ gcc_assert (e < s->size);
+
+ idx = s->sparse[e];
+
+ return idx < s->members && s->dense[idx] == e;
+}
+
+/* Low level insertion routine not meant for use outside of sparseset.[ch].
+ Assumes E is valid and not already a member of the set S. */
+
+static inline void
+sparseset_insert_bit (sparseset s, SPARSESET_ELT_TYPE e, SPARSESET_ELT_TYPE idx)
+{
+ s->sparse[e] = idx;
+ s->dense[idx] = e;
+}
+
+/* Operation: S = S + {e}
+ Insert E into the set S, if it isn't already a member. */
+
+static inline void
+sparseset_set_bit (sparseset s, SPARSESET_ELT_TYPE e)
+{
+ if (!sparseset_bit_p (s, e))
+ sparseset_insert_bit (s, e, s->members++);
+}
+
+/* Return and remove an arbitrary element from the set S. */
+
+static inline SPARSESET_ELT_TYPE
+sparseset_pop (sparseset s)
+{
+ SPARSESET_ELT_TYPE mem = s->members;
+
+ gcc_assert (mem != 0);
+
+ s->members = mem - 1;
+ return s->dense[mem];
+}
+
+static inline void
+sparseset_iter_init (sparseset s)
+{
+ s->iter = 0;
+ s->iter_inc = 1;
+ s->iterating = true;
+}
+
+static inline bool
+sparseset_iter_p (sparseset s)
+{
+ if (s->iterating && s->iter < s->members)
+ return true;
+ else
+ return s->iterating = false;
+}
+
+static inline SPARSESET_ELT_TYPE
+sparseset_iter_elm (sparseset s)
+{
+ return s->dense[s->iter];
+}
+
+static inline void
+sparseset_iter_next (sparseset s)
+{
+ s->iter += s->iter_inc;
+ s->iter_inc = 1;
+}
+
+#define EXECUTE_IF_SET_IN_SPARSESET(SPARSESET, ITER) \
+ for (sparseset_iter_init (SPARSESET); \
+ sparseset_iter_p (SPARSESET) \
+ && (((ITER) = sparseset_iter_elm (SPARSESET)) || 1); \
+ sparseset_iter_next (SPARSESET))
+
+#endif /* GCC_SPARSESET_H */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a346eb8b98b..0b1e91610d6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,272 @@
+2007-10-08 Alexandre Oliva <aoliva@redhat.com>
+
+ PR tree-optimization/33572
+ * g++.dg/torture/pr33572.C: Replace with complete test.
+
+2007-10-08 Tobias Schlüter <tobi@gcc.gnu.org>
+
+ PR fortran/33689
+ * gfortran.dg/spec_expr_5.f90: New.
+
+2007-10-08 Geoffrey Keating <geoffk@apple.com>
+
+ * gcc.dg/pragma-darwin-2.c: New.
+
+2007-10-08 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/33693
+ PR middle-end/33695
+ PR middle-end/33697
+ * gcc.dg/pr33693.c: New testcase.
+ * gcc.dg/pr33695.c: Likewise.
+ * gcc.dg/pr33697.c: Likewise.
+
+2007-10-08 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/33691
+ PR middle-end/33694
+ PR middle-end/33696
+ * gcc.dg/pr33691.c: New testcase.
+ * gcc.dg/pr33694.c: Likewise.
+ * gcc.dg/pr33696.c: Likewise.
+
+2007-10-07 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR libfortran/33683
+ * gfortran.dg/gamma_5.f90: New test case
+
+2007-10-07 Tobias Schlüter <tobi@gcc.gnu.org>
+
+ PR fortran/20851
+ * initialization_1.f90: Fix dg-error annotations.
+ * initialization_14.f90: New.
+ * initialization_7.f90: Fix dg-error annotations.
+ * initialization_9.f90: Likewise.
+
+2007-10-06 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ * gfortran.dg/error_recovery_4.f90: New test.
+
+2007-10-06 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * gfortran.dg/default_format_denormal_2.f90: New test.
+ * gfortran.dg/default_format_2.inc: New test.
+ * gfortran.dg/default_format_denormal_1.f90: New test.
+ * gfortran.dg/default_format_1.inc: New test.
+ * gfortran.dg/default_format_1.f90: Don't test for denormalized
+ numbers.
+ * gfortran.dg/default_format_2.f90: Don't test for denormalized
+ numbers.
+
+2007-10-06 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ * gfortran.dg/namelist_15.f90: Revise test.
+
+2007-10-06 Alexandre Oliva <aoliva@redhat.com>
+
+ PR tree-optimization/33655
+ * gcc.dg/torture/pr33655.c: New.
+
+2007-10-06 Alexandre Oliva <aoliva@redhat.com>
+
+ PR tree-optimization/33572
+ * g++.dg/torture/pr33572.C: New.
+
+2007-10-06 Tobias Schlüter <tobi@gcc.gnu.org>
+
+ PR fortran/25076
+ * gfortran.dg/forall_11.f90: New.
+
+2007-10-05 Michael Matz <matz@suse.de>
+
+ PR middle-end/33667
+ * gcc.dg/pr33667.c: New testcase.
+
+2007-10-05 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/33666
+ * gcc.dg/pr33666.c: New testcase.
+
+2007-10-05 Michael Matz <matz@suse.de>
+
+ PR inline-asm/33600
+ * gcc.target/i386/pr33600.c: New testcase.
+
+2007-10-05 Richard Guenther <rguenther@suse.de>
+
+ * g++.dg/tree-ssa/obj-type-ref.C: New testcase.
+
+2007-10-05 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ PR target/33635
+ * gcc.target/mips/pr33635-1.c: New test.
+
+2007-10-04 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libfortran/33253
+ * gfortran.dg/namelist_39.f90: Revise to use long names.
+
+2007-10-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR fortran/33646
+ * gfortran.dg/pr33646.f90: New file.
+
+2007-10-04 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/33529
+ * gfortran.dg/char_type_len_2.f90: Adjust error message.
+ * gfortran.dg/char_decl_2.f90: New test.
+
+2007-10-04 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/33641
+ * gcc.c-torture/compile/pr33641.c: New testcase.
+
+2007-10-04 Michael Matz <matz@suse.de>
+
+ PR rtl-optimization/33653
+ * gcc.dg/pr33653.c: New.
+
+2007-10-04 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/33627
+ * g++.dg/torture/pr33627.C: New testcase.
+
+2007-10-04 Tobias Schlüter <tobi@gcc.gnu.org>
+
+ PR fortran/33626
+ * gfortran.dg/parens_6.f90: New.
+
+2007-10-04 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/33646
+ PR fortran/33542
+ * gfortran.dg/ambiguous_specific_1.f90: Remove.
+
+2007-10-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * g++.dg/ext/gnu-inline-global-redecl.C: New.
+
+2007-10-03 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ PR target/33635
+ * gcc.target/mips/mips.exp (setup_mips_tests): Set mips_isa_rev
+ and mips_forced_be.
+ (dg-mips-options): Handle -EL and -mel. Make -mfp64 imply
+ -mhard-float and a suitable ISA. Improve handling of -mipsXrY
+ options.
+ * gcc.target/mips/fpr-moves-1.c: New test.
+ * gcc.target/mips/fpr-moves-2.c: Likewise.
+ * gcc.target/mips/fpr-moves-3.c: Likewise.
+ * gcc.target/mips/fpr-moves-4.c: Likewise.
+ * gcc.target/mips/fpr-moves-5.c: Likewise.
+ * gcc.target/mips/fpr-moves-6.c: Likewise.
+ * gcc.target/mips/mips32r2-mxhc1.c: Remove -march=mips32r2
+
+2007-10-03 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * gfortran.dg/default_format_1.f90: XFAIL on all darwin targets.
+
+2007-10-03 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * gfortran.dg/default_format_1.f90: XFAIL on ppc-darwin.
+ * gfortran.dg/default_format_2.f90: XFAIL on ppc-darwin.
+
+2007-10-03 Tobias Schlüter <tobi@gcc.gnu.org>
+
+ PR fortran/33198
+ * gfortran.dg/common_errors_1.f90: New.
+
+2007-10-03 Doug Kwan <dougkwan@google.com>
+ Richard Guenther <rguenther@suse.de>
+
+ PR debug/31899
+ * g++.dg/debug/using3.C: New testcase.
+
+2007-10-03 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libfortran/33253
+ * gfortran.dg/namelist_38.f90: New test.
+ * gfortran.dg/namelist_39.f90: New test.
+
+2007-10-03 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR libfortran/33469
+ * gfortran.dg/default_format_1.f90: New test.
+ * gfortran.dg/default_format_2.f90: New test.
+ * gfortran.dg/namelist_print_1.f: Adjust expected output.
+ * gfortran.dg/real_const_3.f90: Adjust expected output.
+
+2007-10-02 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * gcc.target/mips/mips.exp (setup_mips_tests): Set mips_abi to the
+ default ABI. Split mips_forced_abi into mips_forced_abi and
+ mips_forced_regs.
+ (is_gp32_flag): Return true for -mabi=32.
+ (is_gp64_flag): New function. Handle 64-bit -mabi options.
+ (dg-mips-options): Use is_gp64_flag instead of checking specifically
+ for -mgp64. Update after the mips_forced_abi split. Handle -mabi=*.
+ Don't force an ABI for -mgp32 or -mfp32 if the flags contain -mabi=*.
+ * gcc.target/mips/pr33256.c: Remove -mips3 requirement.
+ * gcc.target/mips/save-restore-1.c: Use -mabi=32 instead of -mgp32.
+ * gcc.target/mips/save-restore-2.c: Likewise.
+ * gcc.target/mips/save-restore-3.c: Likewise.
+ * gcc.target/mips/save-restore-4.c: Likewise.
+
+2007-10-02 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ PR middle-end/33617
+ * gcc.c-torture/compile/pr33617.c: New test.
+
+2007-10-02 Andreas Tobler <a.tobler@schweiz.org>
+
+ * gcc.target/powerpc/stabs-attrib-vect-darwin.c: Change options to use
+ -gstabs+ for extended options.
+
+2007-10-02 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/33542
+ * gfortran.dg/ambiguous_specific_1.f90: New test.
+
+2007-10-02 Revital Eres <eres@il.ibm.com>
+
+ * gcc.target/powerpc/paired-8.c: New test.
+ * gcc.target/powerpc/paired-9.c: New test.
+ * gcc.target/powerpc/paired-10.c: New test.
+
+2007-10-02 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/33566
+ * gfortran.dg/derived_comp_array_ref_5.f90: New test.
+
+2007-10-02 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/33554
+ * gfortran.dg/intent_out_2.f90: New test.
+
+2007-10-02 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/33550
+ * gfortran.dg/ambiguous_reference_1.f90: New test.
+
+2007-10-02 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/31154
+ PR fortran/31229
+ PR fortran/33334
+ * gfortran.dg/function_kinds_1.f90: New test.
+ * gfortran.dg/function_kinds_2.f90: New test.
+ * gfortran.dg/derived_function_interface_1.f90: Correct illegal
+ use association into interfaces.
+
+2007-10-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR testsuite/31828
+ gcc.dg/float-range-3.c (INFINITY): Define if not defined.
+ (overflow): Use INFINITY, not FP_INFINITE.
+ gcc.dg/float-range-4.c: Likewise.
+ gcc.dg/float-range-5.c: Likewise.
+
2007-10-01 Nick Clifton <nickc@redhat.com>
* gcc.c-torture/execute/20060102-1.c (f): Fix computation to work
diff --git a/gcc/testsuite/g++.dg/debug/using3.C b/gcc/testsuite/g++.dg/debug/using3.C
new file mode 100644
index 00000000000..df3e3dfa3a1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/using3.C
@@ -0,0 +1,8 @@
+// PR debug/31899
+
+namespace NS {
+ int x = 0;
+ int &ref = x;
+}
+
+using NS::ref;
diff --git a/gcc/testsuite/g++.dg/eh/init-temp1.C b/gcc/testsuite/g++.dg/eh/init-temp1.C
new file mode 100644
index 00000000000..29eae6972d6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/eh/init-temp1.C
@@ -0,0 +1,44 @@
+// PR c++/15764
+
+extern "C" void abort ();
+
+int counter = 0;
+int thrown;
+struct a {
+ ~a () { if (thrown++ == 0) throw 42; }
+};
+
+int f (a const&) { return 1; }
+int f (a const&, a const&) { return 1; }
+
+struct b {
+ b (...) { ++counter; }
+ ~b () { --counter; }
+};
+
+bool p;
+void g()
+{
+ if (p) throw 42;
+}
+
+int main () {
+ thrown = 0;
+ try {
+ b tmp(f (a(), a()));
+
+ g();
+ }
+ catch (...) {}
+
+ thrown = 0;
+ try {
+ b tmp(f (a()));
+
+ g();
+ }
+ catch (...) {}
+
+ if (counter != 0)
+ abort ();
+}
diff --git a/gcc/testsuite/g++.dg/ext/gnu-inline-global-redecl.C b/gcc/testsuite/g++.dg/ext/gnu-inline-global-redecl.C
new file mode 100644
index 00000000000..fc72d26fb8f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/gnu-inline-global-redecl.C
@@ -0,0 +1,19 @@
+/* Test __attribute__((gnu_inline)).
+
+ Check that we don't get out-of-line definitions for extern inline
+ gnu_inline functions, regardless of redeclaration.
+
+ */
+
+/* { dg-do link } */
+/* { dg-options "-O" } */ // such that static functions are optimized out
+
+#include "gnu-inline-common.h"
+
+decl(extern, fn)
+gnuindef(fn, 0)
+decl(extern, fn)
+
+int main () {
+ fn ();
+}
diff --git a/gcc/testsuite/g++.dg/ext/visibility/namespace2.C b/gcc/testsuite/g++.dg/ext/visibility/namespace2.C
new file mode 100644
index 00000000000..5e6e71f8f1f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/visibility/namespace2.C
@@ -0,0 +1,20 @@
+// PR c++/32470
+
+// { dg-require-visibility }
+// { dg-options "-fvisibility=hidden" }
+// { dg-final { scan-hidden "_ZN4Test4testEv" } }
+
+namespace std __attribute__((__visibility__("default"))) {
+ template<typename _CharT>
+ class basic_streambuf
+ {
+ friend void getline();
+ };
+ extern template class basic_streambuf<char>;
+}
+
+class Test
+{
+ void test();
+};
+void Test::test() { }
diff --git a/gcc/testsuite/g++.dg/init/ref15.C b/gcc/testsuite/g++.dg/init/ref15.C
new file mode 100644
index 00000000000..d3a94227fd0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/ref15.C
@@ -0,0 +1,32 @@
+// PR c++/20416. We correctly constructed the temporary S in foo(),
+// but incorrectly destroyed it every time foo() was called.
+// { dg-do run }
+extern "C" void abort (void);
+extern "C" void _exit (int);
+
+int c, exiting;
+struct S {
+ S() { ++c; }
+ S(const S &) { ++c; }
+ ~S()
+ {
+ if (!exiting) abort ();
+ _exit (0);
+ }
+};
+void
+foo (void)
+{
+ static const S &s = S();
+}
+int main ()
+{
+ if (c != 0)
+ abort ();
+ foo ();
+ foo ();
+ if (c != 1)
+ abort ();
+ exiting = 1;
+ return 1;
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr33572.C b/gcc/testsuite/g++.dg/torture/pr33572.C
new file mode 100644
index 00000000000..096db08ff4b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr33572.C
@@ -0,0 +1,17 @@
+// { dg-do run }
+#include <vector>
+#include <memory>
+
+struct Foo { virtual void f() {} };
+
+int main(int argc, char**)
+{
+ std::auto_ptr<Foo> foo;
+ if (argc) {
+ foo.reset(new Foo());
+ } else {
+ std::vector<int> v;
+ }
+ Foo* p = foo.release();
+ p->f();
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr33627.C b/gcc/testsuite/g++.dg/torture/pr33627.C
new file mode 100644
index 00000000000..a14e345517f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr33627.C
@@ -0,0 +1,57 @@
+/* { dg-do compile } */
+
+typedef unsigned int UT_uint32;
+typedef UT_uint32 PT_DocPosition;
+typedef UT_uint32 PT_BlockOffset;
+typedef enum _PTStruxType { PTX_Block } PTStruxType;
+typedef UT_uint32 PL_ListenerId;
+typedef const void * PL_StruxFmtHandle;
+class PX_ChangeRecord;
+class pf_Frag {
+ public:
+ typedef enum _PFType { PFT_Object } PFType;
+ inline PFType getType(void) const { }
+ inline pf_Frag * getNext(void) const { }
+ PT_DocPosition getPos(void) const { }
+};
+class pf_Fragments {
+ public:
+ pf_Frag * getFirst() const;
+};
+class pt_PieceTable {
+ bool getStruxOfTypeFromPosition(PL_ListenerId listenerId, PT_DocPosition docPos, PTStruxType pts, PL_StruxFmtHandle * psfh) const;
+ bool _tellAndMaybeAddListener(PL_ListenerId listenerId, bool bAdd);
+ pf_Fragments m_fragments;
+};
+class pf_Frag_Object : public pf_Frag
+{
+ public:
+ virtual bool createSpecialChangeRecord(PX_ChangeRecord ** ppcr, PT_DocPosition dpos, PT_BlockOffset blockOffset) const;
+};
+bool pt_PieceTable::_tellAndMaybeAddListener(PL_ListenerId listenerId, bool bAdd)
+{
+ PL_StruxFmtHandle sfh = 0;
+ PT_DocPosition sum = 0;
+ UT_uint32 blockOffset = 0;
+ for (pf_Frag * pf = m_fragments.getFirst(); (pf); pf=pf->getNext())
+ {
+ pf_Frag_Object * pfo = static_cast<pf_Frag_Object *> (pf);
+ PX_ChangeRecord * pcr = __null;
+ bool bStatus1 = false;
+ if(sfh != __null) {
+ bStatus1 = pfo->createSpecialChangeRecord(&pcr,sum,blockOffset);
+ if (!(bStatus1))
+ return (false);
+ }
+ else
+ {
+ PT_DocPosition pos = pf->getPos();
+ getStruxOfTypeFromPosition(listenerId,pos,PTX_Block,&sfh);
+ bStatus1 = pfo->createSpecialChangeRecord(&pcr,pos,blockOffset);
+ if (!(bStatus1))
+ return (false);
+ }
+ if (!(bStatus1))
+ return (false);
+ }
+}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/obj-type-ref.C b/gcc/testsuite/g++.dg/tree-ssa/obj-type-ref.C
new file mode 100644
index 00000000000..9854d32e899
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/obj-type-ref.C
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+/* This used to fail with type-checking enabled because we didn't
+ expect OBJ_TYPE_REF expressions. */
+
+class QObject {};
+class Pile : public QObject {
+public:
+ virtual void setVisible(void);
+};
+class Spider {
+ void dealRow();
+ Pile *redeals[5];
+ int m_redeal;
+};
+void Spider::dealRow()
+{
+ redeals[m_redeal++]->setVisible();
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr33617.c b/gcc/testsuite/gcc.c-torture/compile/pr33617.c
new file mode 100644
index 00000000000..0174fb60485
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr33617.c
@@ -0,0 +1,7 @@
+typedef float V8SF __attribute__ ((vector_size (32)));
+void bar (V8SF);
+void
+foo (float x)
+{
+ bar ((V8SF) { x, x, x, x, x, x, x, x });
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr33641.c b/gcc/testsuite/gcc.c-torture/compile/pr33641.c
new file mode 100644
index 00000000000..112f7032792
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr33641.c
@@ -0,0 +1,12 @@
+/* This failed with type checking enabled. */
+
+typedef enum { one, two } exp;
+extern exp pe;
+extern char pt[256];
+void psd (void (*f) (void *), void *p);
+static void rle (void *e) { }
+void
+foo (void)
+{
+ psd ((void (*)(void *)) (rle), (void *) (pt + pe));
+}
diff --git a/gcc/testsuite/gcc.dg/float-range-3.c b/gcc/testsuite/gcc.dg/float-range-3.c
index 6a224e16de9..7fa766f526e 100644
--- a/gcc/testsuite/gcc.dg/float-range-3.c
+++ b/gcc/testsuite/gcc.dg/float-range-3.c
@@ -3,17 +3,21 @@
/* { dg-options "-std=c99" } */
#include <math.h>
+#ifndef INFINITY
+#define INFINITY (__builtin_inff ())
+#endif
+
void overflow(void)
{
float f1 = 3.5E+38f; /* { dg-warning "floating constant exceeds range" } */
float f2 = -3.5E+38f; /* { dg-warning "floating constant exceeds range" } */
- float f3 = FP_INFINITE;
- float f4 = -FP_INFINITE;
+ float f3 = INFINITY;
+ float f4 = -INFINITY;
double d1 = 1.9E+308; /* { dg-warning "floating constant exceeds range" } */
double d2 = -1.9E+308; /* { dg-warning "floating constant exceeds range" } */
- double d3 = FP_INFINITE;
- double d4 = -FP_INFINITE;
+ double d3 = INFINITY;
+ double d4 = -INFINITY;
}
void underflow(void)
diff --git a/gcc/testsuite/gcc.dg/float-range-4.c b/gcc/testsuite/gcc.dg/float-range-4.c
index 5607719ac99..2ec38c43bf6 100644
--- a/gcc/testsuite/gcc.dg/float-range-4.c
+++ b/gcc/testsuite/gcc.dg/float-range-4.c
@@ -3,17 +3,21 @@
/* { dg-options "-Wno-overflow -std=c99" } */
#include <math.h>
+#ifndef INFINITY
+#define INFINITY (__builtin_inff ())
+#endif
+
void overflow(void)
{
float f1 = 3.5E+38f;
float f2 = -3.5E+38f;
- float f3 = FP_INFINITE;
- float f4 = -FP_INFINITE;
+ float f3 = INFINITY;
+ float f4 = -INFINITY;
double d1 = 1.9E+308;
double d2 = -1.9E+308;
- double d3 = FP_INFINITE;
- double d4 = -FP_INFINITE;
+ double d3 = INFINITY;
+ double d4 = -INFINITY;
}
void underflow(void)
diff --git a/gcc/testsuite/gcc.dg/float-range-5.c b/gcc/testsuite/gcc.dg/float-range-5.c
index c3a2a9ee271..49742e322bf 100644
--- a/gcc/testsuite/gcc.dg/float-range-5.c
+++ b/gcc/testsuite/gcc.dg/float-range-5.c
@@ -4,17 +4,21 @@
/* { dg-options "-pedantic-errors -std=c99" } */
#include <math.h>
+#ifndef INFINITY
+#define INFINITY (__builtin_inff ())
+#endif
+
void overflow(void)
{
float f1 = 3.5E+38f; /* { dg-warning "floating constant exceeds range" } */
float f2 = -3.5E+38f; /* { dg-warning "floating constant exceeds range" } */
- float f3 = FP_INFINITE;
- float f4 = -FP_INFINITE;
+ float f3 = INFINITY;
+ float f4 = -INFINITY;
double d1 = 1.9E+308; /* { dg-warning "floating constant exceeds range" } */
double d2 = -1.9E+308; /* { dg-warning "floating constant exceeds range" } */
- double d3 = FP_INFINITE;
- double d4 = -FP_INFINITE;
+ double d3 = INFINITY;
+ double d4 = -INFINITY;
}
void underflow(void)
diff --git a/gcc/testsuite/gcc.dg/pr33653.c b/gcc/testsuite/gcc.dg/pr33653.c
new file mode 100644
index 00000000000..91274c27e66
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr33653.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-shorten" } */
+
+void f (volatile char *p)
+{
+ char c = p[0];
+}
+
+/* { dg-final { scan-rtl-dump "mem/v" "shorten" } } */
+/* { dg-final { cleanup-rtl-dump "shorten" } } */
diff --git a/gcc/testsuite/gcc.dg/pr33666.c b/gcc/testsuite/gcc.dg/pr33666.c
new file mode 100644
index 00000000000..1f27b136d36
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr33666.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options { -std=c99 } } */
+
+/* This used to fail with type-checking enabled because we stripped
+ the inner conversion to unsigned int. */
+
+void __lock_get_list(void *dp)
+{
+ if (((__SIZE_TYPE__)dp + 1) & ~1ULL)
+ ;
+}
diff --git a/gcc/testsuite/gcc.dg/pr33667.c b/gcc/testsuite/gcc.dg/pr33667.c
new file mode 100644
index 00000000000..d3c039b51df
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr33667.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef unsigned int size_t;
+typedef unsigned char uint8_t;
+typedef unsigned short int uint16_t;
+typedef unsigned long long int uint64_t;
+struct magic {
+ uint8_t mask_op;
+ union {
+ uint64_t _mask;
+ } _u;
+ union VALUETYPE {
+ uint16_t h;
+ } value;
+};
+void cvt_16(union VALUETYPE *p, const struct magic *m)
+{
+ if (m->_u._mask)
+ p->h %= (uint16_t) m->_u._mask;
+}
diff --git a/gcc/testsuite/gcc.dg/pr33691.c b/gcc/testsuite/gcc.dg/pr33691.c
new file mode 100644
index 00000000000..93213610d28
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr33691.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+/* ICEd with type-checking enabled. */
+
+unsigned int mgaSetTexImages(int i)
+{
+ return ((i | 0x40) & 0xffffffc0);
+}
diff --git a/gcc/testsuite/gcc.dg/pr33693.c b/gcc/testsuite/gcc.dg/pr33693.c
new file mode 100644
index 00000000000..147c164c4b4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr33693.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+/* This used to ICE with type-checking enabled. */
+
+unsigned long modify_field (unsigned long mask, long fieldval)
+{
+ return (~fieldval & ~mask);
+}
diff --git a/gcc/testsuite/gcc.dg/pr33694.c b/gcc/testsuite/gcc.dg/pr33694.c
new file mode 100644
index 00000000000..eb7655e8585
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr33694.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+/* This used to ICE with type-checking enabled. */
+
+__SIZE_TYPE__ cnfs_mapcntl(long pagesize)
+{
+ return ~(__SIZE_TYPE__)(pagesize - 1);
+}
diff --git a/gcc/testsuite/gcc.dg/pr33695.c b/gcc/testsuite/gcc.dg/pr33695.c
new file mode 100644
index 00000000000..2d3ffbd6688
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr33695.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+/* We used to ICE with type-checking enabled. */
+
+unsigned int bfstages(int M, float *Utbl, int Ustride)
+{
+ return ((unsigned int) 1 << M) * Ustride;
+}
diff --git a/gcc/testsuite/gcc.dg/pr33696.c b/gcc/testsuite/gcc.dg/pr33696.c
new file mode 100644
index 00000000000..97bbfe8bf43
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr33696.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+/* This used to ICE with type-checking enabled. */
+
+typedef unsigned char uint8_t;
+typedef unsigned int uint_least32_t;
+extern int foo (long int __off);
+void write (uint_least32_t chunk_len)
+{
+ uint8_t tmp[4];
+ foo (-(long)chunk_len - sizeof(tmp));
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr33697.c b/gcc/testsuite/gcc.dg/pr33697.c
new file mode 100644
index 00000000000..8c5edb65853
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr33697.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+/* We used to ICE for this with type-checking enabled. */
+
+typedef signed short gint16;
+typedef unsigned short guint16;
+gint16 dissect_old_pflog(gint16 rnr)
+{
+ return (guint16) ((guint16) ((guint16)rnr >> 8) | (guint16) ((guint16)rnr << 8));
+}
diff --git a/gcc/testsuite/gcc.dg/pragma-darwin-2.c b/gcc/testsuite/gcc.dg/pragma-darwin-2.c
new file mode 100644
index 00000000000..4bbecef0120
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pragma-darwin-2.c
@@ -0,0 +1,24 @@
+/* Darwin (Mac OS X) pragma exercises. */
+
+/* { dg-do compile { target *-*-darwin* } } */
+
+/* The mark pragma is valid at any point in the program. Fortunately
+ the compiler only needs to ignore it. It's also followed only
+ by pp-tokens, not necessarily real C tokens. */
+
+void foo(void)
+{
+ if (1) {
+ ;
+ }
+ else if (1) {
+ ;
+ }
+#pragma mark "last case" "hi"
+ else if (1) {
+ ;
+ }
+}
+
+#pragma mark 802.11x 1_2_3
+#pragma mark •••• marker ••••
diff --git a/gcc/testsuite/gcc.dg/torture/pr33655.c b/gcc/testsuite/gcc.dg/torture/pr33655.c
new file mode 100644
index 00000000000..2f9da65aec4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr33655.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+typedef struct {
+ unsigned long attr;
+ int chars[2];
+} cchar_t;
+typedef struct _win_st {
+ cchar_t _bkgrnd;
+} WINDOW;
+void render_char(WINDOW *win, cchar_t ch)
+{
+ if ((ch).chars[0] == L' '
+ && (ch).chars[1] == L'\0')
+ win->_bkgrnd = ch;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr33576.c b/gcc/testsuite/gcc.dg/tree-ssa/pr33576.c
new file mode 100644
index 00000000000..2470762f7a7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr33576.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-linear" } */
+
+int a1[6][4][4];
+short b1[16];
+
+int c1;
+void CalculateQuantParam(void)
+{
+ int i, j, k, temp;
+
+ for(k=0; k<6; k++)
+ for(j=0; j<4; j++)
+ for(i=0; i<4; i++)
+ {
+ temp = (i<<2)+j;
+ a1[k][j][i] = c1/b1[temp];
+ }
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/pr33600.c b/gcc/testsuite/gcc.target/i386/pr33600.c
new file mode 100644
index 00000000000..a2ab91e57b9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr33600.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+int f(int n)
+{
+ int x;
+
+ asm("" : "=&c"(n), "=r"(x) : "1"(n), "0"(n));
+
+ return n;
+}
diff --git a/gcc/testsuite/gcc.target/mips/fpr-moves-1.c b/gcc/testsuite/gcc.target/mips/fpr-moves-1.c
new file mode 100644
index 00000000000..db2190d18dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fpr-moves-1.c
@@ -0,0 +1,26 @@
+/* { dg-mips-options "-mabi=32 -mhard-float -mips1 -O2 -EL" } */
+
+NOMIPS16 void
+foo (double d, double *x)
+{
+ *x = d;
+}
+
+NOMIPS16 double
+bar (double d)
+{
+ register double l1 asm ("$8") = d;
+ register double l2 asm ("$f20") = 0.0;
+ asm ("#foo" : "=d" (l1) : "d" (l1));
+ asm volatile ("#foo" :: "f" (l2));
+ return l1;
+}
+
+/* { dg-final { scan-assembler "\tswc1\t\\\$f12,0\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tswc1\t\\\$f13,4\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tmfc1\t\\\$8,\\\$f12\n" } } */
+/* { dg-final { scan-assembler "\tmfc1\t\\\$9,\\\$f13\n" } } */
+/* { dg-final { scan-assembler "\tmtc1\t\\\$0,\\\$f20\n" } } */
+/* { dg-final { scan-assembler "\tmtc1\t\\\$0,\\\$f21\n" } } */
+/* { dg-final { scan-assembler "\tmtc1\t\\\$8,\\\$f0\n" } } */
+/* { dg-final { scan-assembler "\tmtc1\t\\\$9,\\\$f1\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fpr-moves-2.c b/gcc/testsuite/gcc.target/mips/fpr-moves-2.c
new file mode 100644
index 00000000000..fe21ee2a1d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fpr-moves-2.c
@@ -0,0 +1,26 @@
+/* { dg-mips-options "-mabi=32 -mhard-float -mips1 -O2 -EB" } */
+
+NOMIPS16 void
+foo (double d, double *x)
+{
+ *x = d;
+}
+
+NOMIPS16 double
+bar (double d)
+{
+ register double l1 asm ("$8") = d;
+ register double l2 asm ("$f20") = 0.0;
+ asm ("#foo" : "=d" (l1) : "d" (l1));
+ asm volatile ("#foo" :: "f" (l2));
+ return l1;
+}
+
+/* { dg-final { scan-assembler "\tswc1\t\\\$f12,4\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tswc1\t\\\$f13,0\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tmfc1\t\\\$9,\\\$f12\n" } } */
+/* { dg-final { scan-assembler "\tmfc1\t\\\$8,\\\$f13\n" } } */
+/* { dg-final { scan-assembler "\tmtc1\t\\\$0,\\\$f20\n" } } */
+/* { dg-final { scan-assembler "\tmtc1\t\\\$0,\\\$f21\n" } } */
+/* { dg-final { scan-assembler "\tmtc1\t\\\$9,\\\$f0\n" } } */
+/* { dg-final { scan-assembler "\tmtc1\t\\\$8,\\\$f1\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fpr-moves-3.c b/gcc/testsuite/gcc.target/mips/fpr-moves-3.c
new file mode 100644
index 00000000000..a32c6874eaf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fpr-moves-3.c
@@ -0,0 +1,18 @@
+/* { dg-mips-options "-mabi=32 -mfp64 -O2 -EL" } */
+
+NOMIPS16 double
+foo (double d)
+{
+ register double l1 asm ("$8") = d;
+ register double l2 asm ("$f20") = 0.0;
+ asm ("#foo" : "=d" (l1) : "d" (l1));
+ asm volatile ("#foo" :: "f" (l2));
+ return l1;
+}
+
+/* { dg-final { scan-assembler "\tmfc1\t\\\$8,\\\$f12\n" } } */
+/* { dg-final { scan-assembler "\tmfhc1\t\\\$9,\\\$f12\n" } } */
+/* { dg-final { scan-assembler "\tmtc1\t\\\$0,\\\$f20\n" } } */
+/* { dg-final { scan-assembler "\tmthc1\t\\\$0,\\\$f20\n" } } */
+/* { dg-final { scan-assembler "\tmtc1\t\\\$8,\\\$f0\n" } } */
+/* { dg-final { scan-assembler "\tmthc1\t\\\$9,\\\$f0\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fpr-moves-4.c b/gcc/testsuite/gcc.target/mips/fpr-moves-4.c
new file mode 100644
index 00000000000..4f26f0694e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fpr-moves-4.c
@@ -0,0 +1,18 @@
+/* { dg-mips-options "-mabi=32 -mfp64 -O2 -EB" } */
+
+NOMIPS16 double
+foo (double d)
+{
+ register double l1 asm ("$8") = d;
+ register double l2 asm ("$f20") = 0.0;
+ asm ("#foo" : "=d" (l1) : "d" (l1));
+ asm volatile ("#foo" :: "f" (l2));
+ return l1;
+}
+
+/* { dg-final { scan-assembler "\tmfc1\t\\\$9,\\\$f12\n" } } */
+/* { dg-final { scan-assembler "\tmfhc1\t\\\$8,\\\$f12\n" } } */
+/* { dg-final { scan-assembler "\tmtc1\t\\\$0,\\\$f20\n" } } */
+/* { dg-final { scan-assembler "\tmthc1\t\\\$0,\\\$f20\n" } } */
+/* { dg-final { scan-assembler "\tmtc1\t\\\$9,\\\$f0\n" } } */
+/* { dg-final { scan-assembler "\tmthc1\t\\\$8,\\\$f0\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fpr-moves-5.c b/gcc/testsuite/gcc.target/mips/fpr-moves-5.c
new file mode 100644
index 00000000000..7159d381b85
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fpr-moves-5.c
@@ -0,0 +1,33 @@
+/* { dg-mips-options "-mabi=64 -mhard-float -O2 -EL" } */
+
+NOMIPS16 void
+foo (long double d, long double *x)
+{
+ *x = d;
+}
+
+NOMIPS16 long double
+bar (long double d, long double *x)
+{
+ register long double l1 asm ("$8") = d;
+ register long double l2 asm ("$10") = x[1];
+ register long double l3 asm ("$f20") = 0.0;
+ asm ("#foo" : "=d" (l1) : "d" (l1));
+ asm ("#foo" : "=d" (l2) : "d" (l2));
+ asm volatile ("#foo" :: "f" (l3));
+ x[1] = l1;
+ return l2;
+}
+
+/* { dg-final { scan-assembler "\tsdc1\t\\\$f12,0\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tsdc1\t\\\$f13,8\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tdmfc1\t\\\$8,\\\$f12\n" } } */
+/* { dg-final { scan-assembler "\tdmfc1\t\\\$9,\\\$f13\n" } } */
+/* { dg-final { scan-assembler "\tld\t\\\$10,16\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tld\t\\\$11,24\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tdmtc1\t\\\$0,\\\$f20\n" } } */
+/* { dg-final { scan-assembler "\tdmtc1\t\\\$0,\\\$f21\n" } } */
+/* { dg-final { scan-assembler "\tsd\t\\\$8,16\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tsd\t\\\$9,24\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tdmtc1\t\\\$10,\\\$f0\n" } } */
+/* { dg-final { scan-assembler "\tdmtc1\t\\\$11,\\\$f2\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fpr-moves-6.c b/gcc/testsuite/gcc.target/mips/fpr-moves-6.c
new file mode 100644
index 00000000000..048987a78de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fpr-moves-6.c
@@ -0,0 +1,34 @@
+/* { dg-mips-options "-mabi=64 -mhard-float -O2 -EB" } */
+
+NOMIPS16 void
+foo (long double d, long double *x)
+{
+ *x = d;
+}
+
+NOMIPS16 long double
+bar (long double d, long double *x)
+{
+ register long double l1 asm ("$8") = d;
+ register long double l2 asm ("$10") = x[1];
+ register long double l3 asm ("$f20") = 0.0;
+ asm ("#foo" : "=d" (l1) : "d" (l1));
+ asm ("#foo" : "=d" (l2) : "d" (l2));
+ asm volatile ("#foo" :: "f" (l3));
+ x[1] = l1;
+ return l2;
+}
+
+/* { dg-final { scan-assembler "\tsdc1\t\\\$f12,0\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tsdc1\t\\\$f13,8\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tdmfc1\t\\\$8,\\\$f12\n" } } */
+/* { dg-final { scan-assembler "\tdmfc1\t\\\$9,\\\$f13\n" } } */
+/* { dg-final { scan-assembler "\tld\t\\\$10,16\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tld\t\\\$11,24\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tdmtc1\t\\\$0,\\\$f20\n" } } */
+/* { dg-final { scan-assembler "\tdmtc1\t\\\$0,\\\$f21\n" } } */
+/* { dg-final { scan-assembler "\tsd\t\\\$8,16\\\(\\\$6\\\)\n" } } */
+/* { dg-final { scan-assembler "\tsd\t\\\$9,24\\\(\\\$6\\\)\n" } } */
+/* We currently move this through a temporary. */
+/* { dg-final { scan-assembler "\tdmtc1\t\\\$10,\\\$f0\n" { xfail mips*-*-* } } } */
+/* { dg-final { scan-assembler "\tdmtc1\t\\\$11,\\\$f2\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp
index 00fdb5ec23e..68c67d31287 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -29,30 +29,38 @@ load_lib gcc-dg.exp
# line (as opposed to being overridable defaults).
#
# $mips_isa: the ISA level specified by __mips
+# $mips_isa_rev: the ISA revision specified by __mips_isa_rev
# $mips_arch: the architecture specified by _MIPS_ARCH
# $mips_gp64: true if 64-bit output is selected
# $mips_fp64: true if 64-bit FPRs are selected
# $mips_float: "hard" or "soft"
+# $mips_abi: the ABI specified by _MIPS_SIM
#
# $mips_forced_isa: true if the command line uses -march=* or -mips*
-# $mips_forced_abi: true if the command line uses -mabi=* or -mgp*
+# $mips_forced_abi: true if the command line uses -mabi=*
+# $mips_forced_regs: true if the command line uses -mgp* or -mfp*
# $mips_forced_float: true if the command line uses -mhard/soft-float
+# $mips_forced_be true if the command line uses -EB or -meb
# $mips_forced_le true if the command line uses -EL or -mel
# $mips_forced_gp true if the command line forces a particular GP mode
# $mips_forced_no_er true if the command line contains -mno-explicit-relocs
proc setup_mips_tests {} {
global mips_isa
+ global mips_isa_rev
global mips_arch
global mips_gp64
global mips_fp64
global mips_float
+ global mips_abi
global mips_forced_isa
global mips_forced_abi
global mips_forced_float
+ global mips_forced_be
global mips_forced_le
global mips_forced_gp
global mips_forced_no_er
+ global mips_forced_regs
global compiler_flags
global tool
@@ -61,6 +69,11 @@ proc setup_mips_tests {} {
set f [open $src "w"]
puts $f {
int isa = __mips;
+ #ifdef __mips_isa_rev
+ int isa_rev = __mips_isa_rev;
+ #else
+ int isa_rev = 1;
+ #endif
const char *arch = _MIPS_ARCH;
#ifdef __mips64
int gp64 = 1;
@@ -73,20 +86,35 @@ proc setup_mips_tests {} {
#else
const char *float = "soft";
#endif
+ #if !defined _MIPS_SIM
+ const char *abi = "eabi";
+ #elif _MIPS_SIM=_ABIO32
+ const char *abi = "32";
+ #elif _MIPS_SIM=_ABIO64
+ const char *abi = "o64";
+ #elif _MIPS_SIM=_ABIN32
+ const char *abi = "n32";
+ #else
+ const char *abi = "64";
+ #endif
}
close $f
set output [${tool}_target_compile $src "" preprocess ""]
file delete $src
regexp {isa = ([^;]*)} $output dummy mips_isa
+ regexp {isa_rev = ([^;]*)} $output dummy mips_isa_rev
regexp {arch = "([^"]*)} $output dummy mips_arch
set mips_gp64 [regexp {gp64 = 1} $output]
set mips_fp64 [regexp {fp64 = 1} $output]
regexp {float = "([^"]*)} $output dummy mips_float
+ regexp {abi = "([^"]*)} $output dummy mips_abi
set mips_forced_isa [regexp -- {(-mips[1-5][[:>:]]|-mips32*|-mips64*|-march)} $compiler_flags]
- set mips_forced_abi [regexp -- {(-mgp|-mfp|-mabi)} $compiler_flags]
+ set mips_forced_abi [regexp -- {-mabi} $compiler_flags]
+ set mips_forced_regs [regexp -- {(-mgp|-mfp)} $compiler_flags]
set mips_forced_float [regexp -- {-m(hard|soft)-float} $compiler_flags]
+ set mips_forced_be [regexp -- {-(EB|meb)[[:>:]]} $compiler_flags]
set mips_forced_le [regexp -- {-(EL|mel)[[:>:]]} $compiler_flags]
set mips_forced_gp [regexp -- {-(G|m(|no-)((extern|local)-sdata|gpopt)|mabicalls|mrtp)} $compiler_flags]
set mips_forced_no_er [regexp -- {-mno-explicit-relocs} $compiler_flags]
@@ -99,11 +127,23 @@ proc is_gp32_flag {flag} {
-mips[12] -
-mips32* -
-march=mips32* -
+ -mabi=32 -
-mgp32 { return 1 }
default { return 0 }
}
}
+# Return true if command-line option FLAG forces 64-bit code.
+proc is_gp64_flag {flag} {
+ switch -glob -- $flag {
+ -mabi=64 -
+ -mabi=o64 -
+ -mabi=n32 -
+ -mgp64 { return 1 }
+ default { return 0 }
+ }
+}
+
# Like dg-options, but treats certain MIPS-specific options specially:
#
# -mgp32
@@ -116,6 +156,16 @@ proc is_gp32_flag {flag} {
# if the other flags don't do so. Skip the test if the multilib
# flags force a 32-bit ABI or a 32-bit architecture.
#
+# -mfp64
+# Force the use of 64-bit floating-point registers on a 32-bit target.
+# Also force -mhard-float and an architecture that supports such a
+# combination, unless these things are already specified by other
+# parts of the given flags.
+#
+# -mabi=*
+# Force a particular ABI. Skip the test if the multilib flags
+# force a specific ABI or a different register size.
+#
# -march=*
# -mips*
# Select the target architecture. Skip the test if the multilib
@@ -127,8 +177,9 @@ proc is_gp32_flag {flag} {
# multilib flags force a different selection.
#
# -EB
-# Select big-endian code. Skip the test if the multilib flags
-# force a little-endian target.
+# -EL
+# Select the given endianness. Skip the test if the multilib flags
+# force the opposite endianness.
#
# -G*
# -m(no-)extern-sdata
@@ -146,14 +197,18 @@ proc dg-mips-options {args} {
upvar dg-do-what do_what
global mips_isa
+ global mips_isa_rev
global mips_arch
global mips_gp64
global mips_fp64
global mips_float
+ global mips_abi
global mips_forced_isa
global mips_forced_abi
+ global mips_forced_regs
global mips_forced_float
+ global mips_forced_be
global mips_forced_le
global mips_forced_gp
global mips_forced_no_er
@@ -163,19 +218,35 @@ proc dg-mips-options {args} {
# First handle the -mgp* options. Add an architecture option if necessary.
foreach flag $flags {
+ if {$flag == "-mfp64"} {
+ if {!$mips_fp64 && $mips_forced_regs} {
+ set matches 0
+ } else {
+ if {[lsearch -regexp $flags {^-m(hard|soft)-float$}] < 0} {
+ append flags " -mhard-float"
+ }
+ if {[lsearch -regexp $flags {^(-mips|-march)}] < 0} {
+ append flags " -mips32r2"
+ }
+ }
+ }
+ }
+ foreach flag $flags {
if {[is_gp32_flag $flag]
&& ($mips_gp64
|| ($mips_fp64 && [lsearch $flags -mfp64] < 0)) } {
- if {$mips_forced_abi} {
+ if {$mips_forced_regs || $mips_forced_abi} {
set matches 0
- } else {
+ } elseif {[lsearch $flags "-mabi=*"] < 0} {
append flags " -mabi=32"
}
- } elseif {$flag == "-mgp64" && !$mips_gp64} {
- if {$mips_forced_abi} {
+ } elseif {[is_gp64_flag $flag] && !$mips_gp64} {
+ if {$mips_forced_regs || $mips_forced_abi} {
set matches 0
} else {
- append flags " -mabi=o64"
+ if {[lsearch $flags "-mabi=*"] < 0} {
+ append flags " -mabi=o64"
+ }
if {[lsearch -regexp $flags {^(-mips|-march)}] < 0} {
append flags " -mips3"
}
@@ -184,16 +255,20 @@ proc dg-mips-options {args} {
}
# Handle the other options.
foreach flag $flags {
- if {$flag == "-mfp64"} {
- if {$mips_isa < 33 || $mips_float != "hard"} {
+ if {[regexp -- {^-mabi=(.*)} $flag dummy abi]} {
+ if {$abi != $mips_abi && $mips_forced_abi} {
set matches 0
}
} elseif {[regexp -- {^-march=(.*)} $flag dummy arch]} {
if {$arch != $mips_arch && $mips_forced_isa} {
set matches 0
}
- } elseif {[regexp -- {^-mips(.*)} $flag dummy isa] && $isa != 16} {
- if {$isa != $mips_isa && $mips_forced_isa} {
+ } elseif {[regexp -- {^-mips(.*)} $flag dummy isa]} {
+ if {![regexp {(.*)r(.*)} $isa dummy isa isa_rev]} {
+ set isa_rev 1
+ }
+ if {($isa != $mips_isa || $isa_rev != $mips_isa_rev)
+ && $mips_forced_isa} {
set matches 0
}
} elseif {[regexp -- {^-m(hard|soft)-float} $flag dummy float]} {
@@ -204,6 +279,10 @@ proc dg-mips-options {args} {
if {$mips_forced_le} {
set matches 0
}
+ } elseif {[regexp -- {^-(EL|mel)$} $flag]} {
+ if {$mips_forced_be} {
+ set matches 0
+ }
} elseif {[regexp -- {^-(G|m(|no-)((extern|local)-sdata|gpopt))} $flag]} {
append flags " -mno-abicalls"
if {$mips_forced_gp} {
diff --git a/gcc/testsuite/gcc.target/mips/mips32r2-mxhc1.c b/gcc/testsuite/gcc.target/mips/mips32r2-mxhc1.c
index 7a3b12d55af..9257612cc17 100644
--- a/gcc/testsuite/gcc.target/mips/mips32r2-mxhc1.c
+++ b/gcc/testsuite/gcc.target/mips/mips32r2-mxhc1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-mips-options "-O -march=mips32r2 -mabi=32 -mfp64" } */
+/* { dg-mips-options "-O -mabi=32 -mfp64" } */
/* { dg-final { scan-assembler "mthc1" } } */
/* { dg-final { scan-assembler "mfhc1" } } */
diff --git a/gcc/testsuite/gcc.target/mips/pr33256.c b/gcc/testsuite/gcc.target/mips/pr33256.c
index d5db110fba5..e19c93291a2 100644
--- a/gcc/testsuite/gcc.target/mips/pr33256.c
+++ b/gcc/testsuite/gcc.target/mips/pr33256.c
@@ -1,6 +1,6 @@
/* GCC used to report an ICE for this test because we generated a LO_SUM
for an illegitimate constant. */
-/* { dg-mips-options "-mabi=64 -mips3 -msym32 -O2 -EB -mno-abicalls" } */
+/* { dg-mips-options "-mabi=64 -msym32 -O2 -EB -mno-abicalls" } */
extern unsigned long a[];
int b (int);
diff --git a/gcc/testsuite/gcc.target/mips/pr33635-1.c b/gcc/testsuite/gcc.target/mips/pr33635-1.c
new file mode 100644
index 00000000000..34251e47fdf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr33635-1.c
@@ -0,0 +1,13 @@
+/* { dg-mips-options "-mabi=64 -O2" } */
+
+NOMIPS16 long double __powitf2 (long double x, int m)
+{
+ long double y = x;
+ while (m >>= 1)
+ {
+ x = x * x;
+ if (m % 2)
+ y = y * x;
+ }
+ return y;
+}
diff --git a/gcc/testsuite/gcc.target/mips/save-restore-1.c b/gcc/testsuite/gcc.target/mips/save-restore-1.c
index 721d6012271..9c8017c7c65 100644
--- a/gcc/testsuite/gcc.target/mips/save-restore-1.c
+++ b/gcc/testsuite/gcc.target/mips/save-restore-1.c
@@ -1,6 +1,6 @@
/* Check that we can use the save instruction to save varargs. */
/* { dg-do compile { target mips16_attribute } } */
-/* { dg-mips-options "-mips32r2 -mgp32 -O2" } */
+/* { dg-mips-options "-mips32r2 -mabi=32 -O2" } */
/* { dg-add-options mips16_attribute } */
#include <stdarg.h>
diff --git a/gcc/testsuite/gcc.target/mips/save-restore-2.c b/gcc/testsuite/gcc.target/mips/save-restore-2.c
index b7f8c07e3c2..de082d331cd 100644
--- a/gcc/testsuite/gcc.target/mips/save-restore-2.c
+++ b/gcc/testsuite/gcc.target/mips/save-restore-2.c
@@ -1,6 +1,6 @@
/* Check that we can use the save instruction to save spilled arguments. */
/* { dg-do compile { target mips16_attribute } } */
-/* { dg-mips-options "-mips32r2 -mgp32 -O2" } */
+/* { dg-mips-options "-mips32r2 -mabi=32 -O2" } */
/* { dg-add-options mips16_attribute } */
MIPS16 void
diff --git a/gcc/testsuite/gcc.target/mips/save-restore-3.c b/gcc/testsuite/gcc.target/mips/save-restore-3.c
index 18b871f830a..674072dd7b0 100644
--- a/gcc/testsuite/gcc.target/mips/save-restore-3.c
+++ b/gcc/testsuite/gcc.target/mips/save-restore-3.c
@@ -1,7 +1,7 @@
/* Check that we can use the save instruction to save spilled arguments
when the argument save area is out of range of a direct load or store. */
/* { dg-do compile { target mips16_attribute } } */
-/* { dg-mips-options "-mips32r2 -mgp32 -O2" } */
+/* { dg-mips-options "-mips32r2 -mabi=32 -O2" } */
/* { dg-add-options mips16_attribute } */
void bar (int *);
diff --git a/gcc/testsuite/gcc.target/mips/save-restore-4.c b/gcc/testsuite/gcc.target/mips/save-restore-4.c
index 4a8f13634ed..13f1f0454ee 100644
--- a/gcc/testsuite/gcc.target/mips/save-restore-4.c
+++ b/gcc/testsuite/gcc.target/mips/save-restore-4.c
@@ -1,6 +1,6 @@
/* Check that we can use the save instruction to save $16, $17 and $31. */
/* { dg-do compile { target mips16_attribute } } */
-/* { dg-mips-options "-mips32r2 -mgp32 -O2" } */
+/* { dg-mips-options "-mips32r2 -mabi=32 -O2" } */
/* { dg-add-options mips16_attribute } */
void bar (void);
diff --git a/gcc/testsuite/gcc.target/powerpc/paired-10.c b/gcc/testsuite/gcc.target/powerpc/paired-10.c
new file mode 100644
index 00000000000..114f5f74bf9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/paired-10.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target powerpc-*-linux*paired* } } */
+/* { dg-options "-mpaired -m32 -ffinite-math-only " } */
+
+/* Test PowerPC PAIRED extensions. */
+
+#include <paired.h>
+
+static float out[2] __attribute__ ((aligned (8)));
+void
+test_api (float y, float x)
+{
+ vector float c = {x, y};
+ vector float b = {0.0, 8.0};
+ vector float a;
+
+ a = paired_sub (b, c);
+ paired_stx (a, 0, out);
+}
+
+
+int main ()
+{
+ test_api (6, 7);
+ return (0);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/paired-8.c b/gcc/testsuite/gcc.target/powerpc/paired-8.c
new file mode 100644
index 00000000000..03e4da29eb2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/paired-8.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target powerpc-*-linux*paired* } } */
+/* { dg-options "-mpaired -m32 -ffinite-math-only " } */
+
+/* Test PowerPC PAIRED extensions. */
+
+#include <paired.h>
+
+static float out[2] __attribute__ ((aligned (8)));
+void
+test_api (float x)
+{
+ vector float c = {x, x};
+ vector float b = {60.0, 88.0};
+ vector float a;
+
+ a = paired_sub (b, c);
+ paired_stx (a, 0, out);
+}
+
+
+int main ()
+{
+ test_api (6);
+ return (0);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/paired-9.c b/gcc/testsuite/gcc.target/powerpc/paired-9.c
new file mode 100644
index 00000000000..2d96cd4f7d3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/paired-9.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target powerpc-*-linux*paired* } } */
+/* { dg-options "-mpaired -m32 -ffinite-math-only " } */
+
+/* Test PowerPC PAIRED extensions. */
+
+#include <paired.h>
+
+static float out[2] __attribute__ ((aligned (8)));
+void
+test_api (float y, float x)
+{
+ vector float c = {x, 7.0};
+ vector float b = {0.0, 8.0};
+ vector float a;
+
+ a = paired_sub (b, c);
+ paired_stx (a, 0, out);
+}
+
+
+int main ()
+{
+ test_api (6, 7);
+ return (0);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/stabs-attrib-vect-darwin.c b/gcc/testsuite/gcc.target/powerpc/stabs-attrib-vect-darwin.c
index 4356a9828bf..3c52287b344 100644
--- a/gcc/testsuite/gcc.target/powerpc/stabs-attrib-vect-darwin.c
+++ b/gcc/testsuite/gcc.target/powerpc/stabs-attrib-vect-darwin.c
@@ -1,6 +1,6 @@
/* Test Attribute Vector associated with vector type stabs. */
/* { dg-do compile { target powerpc*-*-darwin* } } */
-/* { dg-options "-gstabs -fno-eliminate-unused-debug-types -faltivec" } */
+/* { dg-options "-gstabs+ -fno-eliminate-unused-debug-types -faltivec" } */
int main ()
{
diff --git a/gcc/testsuite/gfortran.dg/ambiguous_reference_1.f90 b/gcc/testsuite/gfortran.dg/ambiguous_reference_1.f90
new file mode 100644
index 00000000000..93b155ef56d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/ambiguous_reference_1.f90
@@ -0,0 +1,50 @@
+! { dg-do compile }
+! Tests the fix for PR33550, in which an ICE would occur, instead of
+! the abiguous reference error.
+!
+! Found at
+! http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/1abc1549a6a164f1/
+! by James Van Buskirk:
+!
+module M1
+ real x
+end module M1
+
+module M2
+ contains
+ subroutine y
+ end subroutine y
+end module M2
+
+module M3
+ use M2, x => y
+end module M3
+
+module M4
+ use M1
+ use M3
+end module M4
+
+module M5
+ use M4 ! 'x' is ambiguous here but is not referred to
+end module M5
+
+module M6
+ use M5 ! ditto
+end module M6
+
+program test
+ use M1
+ use M3
+ interface
+ function x(z) ! { dg-error "ambiguous reference" }
+ end function x ! { dg-error "Expecting END INTERFACE" }
+ end interface
+
+ write(*,*) 'Hello, world!'
+end program test
+
+function x(z)
+ x = z
+end function x
+! { dg-final { cleanup-modules "m1 m2 m3 m4 m5 m6" } }
diff --git a/gcc/testsuite/gfortran.dg/char_decl_2.f90 b/gcc/testsuite/gfortran.dg/char_decl_2.f90
new file mode 100644
index 00000000000..ffce6b158e2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/char_decl_2.f90
@@ -0,0 +1,4 @@
+! { dg-do run }
+ character (kind=kind("a")) :: u
+ if (kind(u) /= kind("a")) call abort
+ end
diff --git a/gcc/testsuite/gfortran.dg/char_length_2.f90 b/gcc/testsuite/gfortran.dg/char_length_2.f90
index dc2efb94f77..a519c540fd3 100644
--- a/gcc/testsuite/gfortran.dg/char_length_2.f90
+++ b/gcc/testsuite/gfortran.dg/char_length_2.f90
@@ -3,7 +3,7 @@
! CHARACTER lengths weren't reduced early enough for all checks of
! them to be meaningful. Furthermore negative string lengths weren't
! dealt with correctly.
-CHARACTER(len=0) :: c1 ! { dg-warning "CHARACTER variable has zero length" }
+CHARACTER(len=0) :: c1 ! This is OK.
CHARACTER(len=-1) :: c2 ! { dg-warning "CHARACTER variable has zero length" }
PARAMETER(I=-100)
CHARACTER(len=I) :: c3 ! { dg-warning "CHARACTER variable has zero length" }
diff --git a/gcc/testsuite/gfortran.dg/char_type_len_2.f90 b/gcc/testsuite/gfortran.dg/char_type_len_2.f90
index a5cb835b028..e4fab80205e 100644
--- a/gcc/testsuite/gfortran.dg/char_type_len_2.f90
+++ b/gcc/testsuite/gfortran.dg/char_type_len_2.f90
@@ -2,7 +2,9 @@
! PR31251 Non-integer character length leads to segfault
! Submitted by Jerry DeLisle <jvdelisle@gcc.gnu.org>
character(len=2.3) :: s ! { dg-error "must be of INTEGER type" }
- character(kind=1,len=4.3) : t ! { dg-error "must be of INTEGER type" }
- character(len=,,7.2,kind=1) : u ! { dg-error "Syntax error in CHARACTER declaration" }
- character(len=7,kind=2) : v ! ! { dg-error "Kind 2 is not a CHARACTER kind" }
+ character(kind=1,len=4.3) :: t ! { dg-error "must be of INTEGER type" }
+ character(len=,,7.2,kind=1) :: u ! { dg-error "Syntax error in CHARACTER declaration" }
+ character(len=7,kind=2) :: v ! ! { dg-error "Kind 2 is not supported for CHARACTER" }
+ character(kind=2) :: w ! ! { dg-error "Kind 2 is not supported for CHARACTER" }
+ character(kind=2,len=7) :: x ! ! { dg-error "Kind 2 is not supported for CHARACTER" }
end
diff --git a/gcc/testsuite/gfortran.dg/common_errors_1.f90 b/gcc/testsuite/gfortran.dg/common_errors_1.f90
new file mode 100644
index 00000000000..0d4e1beb3bf
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/common_errors_1.f90
@@ -0,0 +1,38 @@
+! { dg-do compile }
+! Tests a number of error messages relating to derived type objects
+! in common blocks. Originally due to PR 33198
+
+subroutine one
+type a
+ sequence
+ integer :: i = 1
+end type a
+type(a) :: t ! { dg-error "Derived type variable .t. in COMMON at ... may not have default initializer" }
+common /c/ t
+end
+
+subroutine first
+type a
+ integer :: i
+ integer :: j
+end type a
+type(a) :: t ! { dg-error "Derived type variable .t. in COMMON at ... has neither the SEQUENCE nor the BIND.C. attribute" }
+common /c/ t
+end
+
+subroutine prime
+type a
+ sequence
+ integer, allocatable :: i(:)
+ integer :: j
+end type a
+type(a) :: t ! { dg-error "Derived type variable .t. in COMMON at ... has an ultimate component that is allocatable" }
+common /c/ t
+end
+
+subroutine source
+parameter(x=0.) ! { dg-error "COMMON block .x. at ... is used as PARAMETER at ..." }
+common /x/ i ! { dg-error "COMMON block .x. at ... is used as PARAMETER at ..." }
+intrinsic sin
+common /sin/ j ! { dg-error "COMMON block .sin. at ... is also an intrinsic procedure" }
+end subroutine source
diff --git a/gcc/testsuite/gfortran.dg/default_format_1.f90 b/gcc/testsuite/gfortran.dg/default_format_1.f90
new file mode 100644
index 00000000000..b8dd0726d9e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/default_format_1.f90
@@ -0,0 +1,29 @@
+! { dg-do run }
+! Test XFAILed on Darwin because the system's printf() lacks
+! proper support for denormals.
+!
+! This tests that the default formats for formatted I/O of reals are
+! wide enough and have enough precision, by checking that values can
+! be written and read back.
+!
+include "default_format_1.inc"
+
+program main
+ use test_default_format
+
+ if (test (1.0_4, 0) /= 0) call abort
+ if (test (0.0_4, 0) /= 0) call abort
+ if (test (tiny(0.0_4), 1) /= 0) call abort
+ if (test (-tiny(0.0_4), -1) /= 0) call abort
+ if (test (huge(0.0_4), -1) /= 0) call abort
+ if (test (-huge(0.0_4), 1) /= 0) call abort
+
+ if (test (1.0_8, 0) /= 0) call abort
+ if (test (0.0_8, 0) /= 0) call abort
+ if (test (tiny(0.0_8), 1) /= 0) call abort
+ if (test (-tiny(0.0_8), -1) /= 0) call abort
+ if (test (huge(0.0_8), -1) /= 0) call abort
+ if (test (-huge(0.0_8), 1) /= 0) call abort
+end program main
+!
+! { dg-final { cleanup-modules "test_default_format" } }
diff --git a/gcc/testsuite/gfortran.dg/default_format_1.inc b/gcc/testsuite/gfortran.dg/default_format_1.inc
new file mode 100644
index 00000000000..e5d711cf015
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/default_format_1.inc
@@ -0,0 +1,74 @@
+module test_default_format
+ interface test
+ module procedure test_r4
+ module procedure test_r8
+ end interface test
+
+ integer, parameter :: count = 200
+
+contains
+ function test_r4 (start, towards) result (res)
+ integer, parameter :: k = 4
+ integer, intent(in) :: towards
+ real(k), intent(in) :: start
+
+ integer :: res, i
+ real(k) :: x, y
+ character(len=100) :: s
+
+ res = 0
+
+ if (towards >= 0) then
+ x = start
+ do i = 0, count
+ write (s,*) x
+ read (s,*) y
+ if (y /= x) res = res + 1
+ x = nearest(x,huge(x))
+ end do
+ end if
+
+ if (towards <= 0) then
+ x = start
+ do i = 0, count
+ write (s,*) x
+ read (s,*) y
+ if (y /= x) res = res + 1
+ x = nearest(x,-huge(x))
+ end do
+ end if
+ end function test_r4
+
+ function test_r8 (start, towards) result (res)
+ integer, parameter :: k = 8
+ integer, intent(in) :: towards
+ real(k), intent(in) :: start
+
+ integer :: res, i
+ real(k) :: x, y
+ character(len=100) :: s
+
+ res = 0
+
+ if (towards >= 0) then
+ x = start
+ do i = 0, count
+ write (s,*) x
+ read (s,*) y
+ if (y /= x) res = res + 1
+ x = nearest(x,huge(x))
+ end do
+ end if
+
+ if (towards <= 0) then
+ x = start
+ do i = 0, count
+ write (s,*) x
+ read (s,*) y
+ if (y /= x) res = res + 1
+ x = nearest(x,-huge(x))
+ end do
+ end if
+ end function test_r8
+
+end module test_default_format
diff --git a/gcc/testsuite/gfortran.dg/default_format_2.f90 b/gcc/testsuite/gfortran.dg/default_format_2.f90
new file mode 100644
index 00000000000..ab4feeeee15
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/default_format_2.f90
@@ -0,0 +1,23 @@
+! { dg-require-effective-target fortran_large_real }
+! { dg-do run { xfail powerpc*-apple-darwin* } }
+! Test XFAILed on powerpc-darwin because the system's printf() lacks
+! proper support for long doubles.
+!
+! This tests that the default formats for formatted I/O of reals are
+! wide enough and have enough precision, by checking that values can
+! be written and read back.
+!
+include "default_format_2.inc"
+
+program main
+ use test_default_format
+
+ if (test (1.0_kl, 0) /= 0) call abort
+ if (test (0.0_kl, 0) /= 0) call abort
+ if (test (tiny(0.0_kl), 1) /= 0) call abort
+ if (test (-tiny(0.0_kl), -1) /= 0) call abort
+ if (test (huge(0.0_kl), -1) /= 0) call abort
+ if (test (-huge(0.0_kl), 1) /= 0) call abort
+end program main
+!
+! { dg-final { cleanup-modules "test_default_format" } }
diff --git a/gcc/testsuite/gfortran.dg/default_format_2.inc b/gcc/testsuite/gfortran.dg/default_format_2.inc
new file mode 100644
index 00000000000..7306f0706e3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/default_format_2.inc
@@ -0,0 +1,43 @@
+module test_default_format
+ interface test
+ module procedure test_rl
+ end interface test
+
+ integer, parameter :: kl = selected_real_kind (precision (0.0_8) + 1)
+ integer, parameter :: count = 200
+
+contains
+
+ function test_rl (start, towards) result (res)
+ integer, parameter :: k = kl
+ integer, intent(in) :: towards
+ real(k), intent(in) :: start
+
+ integer :: res, i
+ real(k) :: x, y
+ character(len=100) :: s
+
+ res = 0
+
+ if (towards >= 0) then
+ x = start
+ do i = 0, count
+ write (s,*) x
+ read (s,*) y
+ if (y /= x) res = res + 1
+ x = nearest(x,huge(x))
+ end do
+ end if
+
+ if (towards <= 0) then
+ x = start
+ do i = 0, count
+ write (s,*) x
+ read (s,*) y
+ if (y /= x) res = res + 1
+ x = nearest(x,-huge(x))
+ end do
+ end if
+ end function test_rl
+
+end module test_default_format
diff --git a/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 b/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90
new file mode 100644
index 00000000000..5213b2ef729
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90
@@ -0,0 +1,21 @@
+! { dg-do run { xfail *-apple-darwin* } }
+! Test XFAILed on these platforms because the system's printf() lacks
+! proper support for denormals.
+!
+! This tests that the default formats for formatted I/O of reals are
+! wide enough and have enough precision, by checking that values can
+! be written and read back.
+!
+include "default_format_1.inc"
+
+program main
+ use test_default_format
+
+ if (test (tiny(0.0_4), -1) /= 0) call abort
+ if (test (-tiny(0.0_4), 1) /= 0) call abort
+
+ if (test (tiny(0.0_8), -1) /= 0) call abort
+ if (test (-tiny(0.0_8), 1) /= 0) call abort
+end program main
+!
+! { dg-final { cleanup-modules "test_default_format" } }
diff --git a/gcc/testsuite/gfortran.dg/default_format_denormal_2.f90 b/gcc/testsuite/gfortran.dg/default_format_denormal_2.f90
new file mode 100644
index 00000000000..93b5d93489c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/default_format_denormal_2.f90
@@ -0,0 +1,19 @@
+! { dg-require-effective-target fortran_large_real }
+! { dg-do run { xfail powerpc*-apple-darwin* } }
+! Test XFAILed on these platforms because the system's printf() lacks
+! proper support for denormalized long doubles.
+!
+! This tests that the default formats for formatted I/O of reals are
+! wide enough and have enough precision, by checking that values can
+! be written and read back.
+!
+include "default_format_2.inc"
+
+program main
+ use test_default_format
+
+ if (test (tiny(0.0_kl), -1) /= 0) call abort
+ if (test (-tiny(0.0_kl), 1) /= 0) call abort
+end program main
+!
+! { dg-final { cleanup-modules "test_default_format" } }
diff --git a/gcc/testsuite/gfortran.dg/derived_comp_array_ref_5.f90 b/gcc/testsuite/gfortran.dg/derived_comp_array_ref_5.f90
new file mode 100644
index 00000000000..3b0c279441f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/derived_comp_array_ref_5.f90
@@ -0,0 +1,36 @@
+! { dg-do compile }
+! Tests the fix for PR33566, in which the first variable array ref
+! to v1 would cause an incompatible ranks error and the second an ICE.
+!
+! Contributed by Mikael Morin <mikael.morin@tele2.fr>
+!
+ program test_vec
+
+ implicit none
+
+
+ integer :: i
+ real :: x
+
+ type vec3
+ real, dimension(3) :: coords
+ end type vec3
+
+ type(vec3),parameter :: v1 = vec3((/ 1.0, 2.0, 3.0 /))
+ type(vec3) :: v2
+
+ v2 = vec3((/ 1.0, 2.0, 3.0 /))
+
+
+ x = v1%coords(1)
+
+ do i=1,3
+ x = v1%coords(i) ! used to fail
+ x = v2%coords(i)
+ end do
+
+ i = 2
+
+ v2 = vec3 (v1%coords ((/i+1, i, i-1/))) ! also broken
+
+ end program test_vec
diff --git a/gcc/testsuite/gfortran.dg/derived_function_interface_1.f90 b/gcc/testsuite/gfortran.dg/derived_function_interface_1.f90
index 88acbb752bb..a9e404182f6 100644
--- a/gcc/testsuite/gfortran.dg/derived_function_interface_1.f90
+++ b/gcc/testsuite/gfortran.dg/derived_function_interface_1.f90
@@ -6,24 +6,28 @@
!
! Contributed by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
!
-type(foo) function ext_fun()
+module kinds
type foo
integer :: i
end type foo
+end module
+
+type(foo) function ext_fun()
+ use kinds
ext_fun%i = 1
end function ext_fun
- type foo
- integer :: i
- end type foo
+ use kinds
interface fun_interface
type(foo) function fun()
+ use kinds
end function fun
end interface
interface ext_fun_interface
type(foo) function ext_fun()
+ use kinds
end function ext_fun
end interface
@@ -38,3 +42,4 @@ contains
end function fun ! { dg-error "Expecting END PROGRAM" }
end ! { dg-warning "CONTAINS statement without FUNCTION or SUBROUTINE statement" }
+! { dg-final { cleanup-modules "kinds" } }
diff --git a/gcc/testsuite/gfortran.dg/error_recovery_4.f90 b/gcc/testsuite/gfortran.dg/error_recovery_4.f90
new file mode 100644
index 00000000000..31e0e3b9a31
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/error_recovery_4.f90
@@ -0,0 +1,5 @@
+! { dg-do compile }
+! PR33609 ICE on arithmetic overflow
+! Before patch, this segfaulted.
+print *, real(huge(1.0_8),4) ! { dg-error "Arithmetic overflow" }
+end
diff --git a/gcc/testsuite/gfortran.dg/forall_11.f90 b/gcc/testsuite/gfortran.dg/forall_11.f90
new file mode 100644
index 00000000000..4c556951c7e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/forall_11.f90
@@ -0,0 +1,33 @@
+! { dg-do compile }
+! PR 25076
+! We erroneously accepted it when a FORALL index was used in a triplet
+! specification within the same FORALL header
+INTEGER :: A(10,10)
+FORALL(I=1:10,J=I:10) ! { dg-error "FORALL index 'i' may not appear in triplet specification" }
+ A(I,J)=I+J
+ENDFORALL
+
+forall (i=1:10, j=1:i) ! { dg-error "FORALL index 'i' may not appear in triplet specification" }
+ a(i,j) = 5
+end forall
+
+forall (i=1:10, j=1:10:i) ! { dg-error "FORALL index 'i' may not appear in triplet specification" }
+ a(i,j) = i - j
+end forall
+
+forall (i=i:10) ! { dg-error "FORALL index 'i' may not appear in triplet specification" }
+ forall (j=1:j:i) ! { dg-error "FORALL index 'j' may not appear in triplet specification" }
+ a(i,j) = i*j
+ end forall
+end forall
+
+forall (i=1:10:i) ! { dg-error "FORALL index 'i' may not appear in triplet specification" }
+ a(1,i) = 2
+end forall
+
+forall (i=1:10)
+ forall (j=i:10)
+ a(i,j) = i*j
+ end forall
+end forall
+END
diff --git a/gcc/testsuite/gfortran.dg/function_kinds_1.f90 b/gcc/testsuite/gfortran.dg/function_kinds_1.f90
new file mode 100644
index 00000000000..f0140df0620
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/function_kinds_1.f90
@@ -0,0 +1,54 @@
+! { dg-do run }
+! Tests the fix for PR31229, PR31154 and PR33334, in which
+! the KIND and TYPE parameters in the function declarations
+! would cause errors.
+!
+! Contributed by Brooks Moses <brooks@gcc.gnu.org>
+! and Tobias Burnus <burnus@gcc.gnu.org>
+!
+module kinds
+ implicit none
+ integer, parameter :: dp = selected_real_kind(6)
+ type t
+ integer :: i
+ end type t
+ interface
+ real(dp) function y()
+ import
+ end function
+ end interface
+end module kinds
+
+type(t) function func() ! The legal bit of PR33334
+ use kinds
+ func%i = 5
+end function func
+
+real(dp) function another_dp_before_defined ()
+ use kinds
+ another_dp_before_defined = real (kind (4.0_DP))
+end function
+
+module mymodule;
+contains
+ REAL(2*DP) function declared_dp_before_defined()
+ use kinds, only: dp
+ real (dp) :: x
+ declared_dp_before_defined = 1.0_dp
+ x = 1.0_dp
+ declared_dp_before_defined = real (kind (x))
+ end function
+end module mymodule
+
+ use kinds
+ use mymodule
+ type(t), external :: func
+ type(t) :: z
+ if (kind (y ()) .ne. 4) call abort ()
+ if (kind (declared_dp_before_defined ()) .ne. 8) call abort ()
+ if (int (declared_dp_before_defined ()) .ne. 4) call abort ()
+ if (int (another_dp_before_defined ()) .ne. 4) call abort ()
+ z = func()
+ if (z%i .ne. 5) call abort ()
+end
+! { dg-final { cleanup-modules "kinds mymodule" } }
diff --git a/gcc/testsuite/gfortran.dg/function_kinds_2.f90 b/gcc/testsuite/gfortran.dg/function_kinds_2.f90
new file mode 100644
index 00000000000..f14453df9b2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/function_kinds_2.f90
@@ -0,0 +1,21 @@
+! Tests the fix for PR33334, in which the TYPE in the function
+! declaration cannot be legally accessed.
+!
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+!
+module types
+ implicit none
+ type t
+ integer :: i = 99
+ end type t
+end module
+
+module x
+ use types
+ interface
+ type(t) function bar() ! { dg-error "is not accessible" }
+ end function
+ end interface
+end module
+! { dg-final { cleanup-modules "types x" } }
+
diff --git a/gcc/testsuite/gfortran.dg/gamma_5.f90 b/gcc/testsuite/gfortran.dg/gamma_5.f90
new file mode 100644
index 00000000000..6945cfdc1c7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gamma_5.f90
@@ -0,0 +1,42 @@
+! { dg-do run }
+! PR 33683 - we used to pick up the wrong gamma function
+! from the library on some systems.
+program main
+ implicit none
+ integer, parameter :: n_max = 20
+ double precision, dimension(0:n_max) :: c
+ double precision :: pi
+ integer :: n
+ double precision :: td, xd
+ real :: ts,xs
+
+ pi = 4 * atan(1.d0)
+ c(0) = 1.
+ do n=1, n_max
+ c(n) = (2*n-1)*c(n-1)*0.5d0
+ end do
+
+ do n=1, n_max
+ xs = n + 0.5
+ xd = n + 0.5d0
+ td = c(n)*sqrt(pi)
+ ts = c(n)*sqrt(pi)
+ if (abs(gamma(xs)-ts)/ts > 2e-6) call abort
+ if (abs(gamma(xd)-td)/td > 5e-14) call abort
+ end do
+ call tst_s(2.3, gamma(2.3))
+ call tst_s(3.7, gamma(3.7))
+ call tst_s(5.5, gamma(5.5))
+ call tst_d(4.2d0, gamma(4.2d0))
+ call tst_d(8.1d0, gamma(8.1d0))
+contains
+ subroutine tst_s(a, b)
+ real :: a, b
+ if (abs(gamma(a) - b)/b > 1e-6) call abort
+ end subroutine tst_s
+
+ subroutine tst_d(a, b)
+ double precision :: a,b
+ if (abs(gamma(a) - b)/b > 5e-14) call abort
+ end subroutine tst_d
+end program main
diff --git a/gcc/testsuite/gfortran.dg/initialization_1.f90 b/gcc/testsuite/gfortran.dg/initialization_1.f90
index 637b3174e99..63035cc9dcd 100644
--- a/gcc/testsuite/gfortran.dg/initialization_1.f90
+++ b/gcc/testsuite/gfortran.dg/initialization_1.f90
@@ -24,10 +24,10 @@ contains
real :: z(2, 2)
! However, this gives a warning because it is an initialization expression.
- integer :: l1 = len (ch1) ! { dg-warning "assumed character length variable" }
+ integer :: l1 = len (ch1) ! { dg-warning "Assumed character length variable" }
! These are warnings because they are gfortran extensions.
- integer :: m3 = size (x, 1) ! { dg-error "assumed size array" }
+ integer :: m3 = size (x, 1) ! { dg-error "Assumed size array" }
integer :: m4(2) = shape (z)
! This does not depend on non-constant properties.
diff --git a/gcc/testsuite/gfortran.dg/initialization_14.f90 b/gcc/testsuite/gfortran.dg/initialization_14.f90
new file mode 100644
index 00000000000..4d5b6856cf0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/initialization_14.f90
@@ -0,0 +1,45 @@
+! { dg-do compile }
+! PR 20851
+! Dummy arguments are disallowed in initialization expressions in
+! elemental functions except as arguments to the intrinsic functions
+! BIT_SIZE, KIND, LEN, or to the numeric inquiry functions listed
+! in 13.11.8
+MODULE TT
+INTEGER M
+CONTAINS
+ ELEMENTAL REAL FUNCTION two(N)
+ INTEGER, INTENT(IN) :: N
+ INTEGER, DIMENSION(N) :: scr ! { dg-error "Dummy argument 'n' not allowed in expression" }
+ END FUNCTION
+
+ ELEMENTAL REAL FUNCTION twopointfive(N)
+ INTEGER, INTENT(IN) :: N
+ INTEGER, DIMENSION(MAX(N,2)) :: scr ! { dg-error "Dummy argument 'n' not allowed in expression" }
+ end FUNCTION twopointfive
+
+ REAL FUNCTION three(N)
+ INTEGER, INTENT(IN) :: N
+ INTEGER, DIMENSION(N) :: scr ! this time it's valid
+ END FUNCTION
+
+ ELEMENTAL REAL FUNCTION four(N)
+ INTEGER, INTENT(IN) :: N
+ INTEGER, DIMENSION(bit_size(N)) :: scr ! another valid variant
+ END FUNCTION
+
+ ELEMENTAL REAL FUNCTION gofourit(N)
+ INTEGER, INTENT(IN) :: N
+ INTEGER, DIMENSION(MIN(HUGE(N),1)) :: scr ! another valid variant
+ END FUNCTION
+
+ ELEMENTAL REAL FUNCTION fourplusone(N)
+ INTEGER, INTENT(IN) :: N
+ INTEGER, DIMENSION(M) :: scr ! another valid variant
+ END FUNCTION
+
+ ELEMENTAL REAL FUNCTION five(X)
+ real, intent(in) :: x
+ CHARACTER(LEN=PRECISION(X)) :: C ! valid again
+ END FUNCTION
+END MODULE
+END
diff --git a/gcc/testsuite/gfortran.dg/initialization_7.f90 b/gcc/testsuite/gfortran.dg/initialization_7.f90
index 7f5ee315cf2..8615181965d 100644
--- a/gcc/testsuite/gfortran.dg/initialization_7.f90
+++ b/gcc/testsuite/gfortran.dg/initialization_7.f90
@@ -6,7 +6,7 @@
subroutine probleme(p)
real(kind=8), dimension(:) :: p
- integer :: nx = size(p, 1) ! { dg-error "deferred array" }
+ integer :: nx = size(p, 1) ! { dg-error "Deferred array" }
integer :: nix
nix = nx
diff --git a/gcc/testsuite/gfortran.dg/initialization_9.f90 b/gcc/testsuite/gfortran.dg/initialization_9.f90
index 5a827706a9e..2341d40d6d9 100644
--- a/gcc/testsuite/gfortran.dg/initialization_9.f90
+++ b/gcc/testsuite/gfortran.dg/initialization_9.f90
@@ -5,7 +5,7 @@
integer function xstrcmp(s1)
character*(*), intent(in) :: s1
- integer :: n1 = len(s1) ! { dg-error "assumed character length variable" }
+ integer :: n1 = len(s1) ! { dg-error "Assumed character length variable" }
n1 = 1
return
end function xstrcmp
diff --git a/gcc/testsuite/gfortran.dg/intent_out_2.f90 b/gcc/testsuite/gfortran.dg/intent_out_2.f90
new file mode 100644
index 00000000000..4dc5191e9a2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_out_2.f90
@@ -0,0 +1,47 @@
+! { dg-do run }
+! Tests the fix for PR33554, in which the default initialization
+! of temp, in construct_temp, caused a segfault because it was
+! being done before the array offset and lower bound were
+! available.
+!
+! Contributed by Harald Anlauf <anlauf@gmx.de>
+!
+module gfcbug72
+ implicit none
+
+ type t_datum
+ character(len=8) :: mn = 'abcdefgh'
+ end type t_datum
+
+ type t_temp
+ type(t_datum) :: p
+ end type t_temp
+
+contains
+
+ subroutine setup ()
+ integer :: i
+ type (t_temp), pointer :: temp(:) => NULL ()
+
+ do i=1,2
+ allocate (temp (2))
+ call construct_temp (temp)
+ if (any (temp % p% mn .ne. 'ijklmnop')) call abort ()
+ deallocate (temp)
+ end do
+ end subroutine setup
+ !--
+ subroutine construct_temp (temp)
+ type (t_temp), intent(out) :: temp (:)
+ if (any (temp % p% mn .ne. 'abcdefgh')) call abort ()
+ temp(:)% p% mn = 'ijklmnop'
+ end subroutine construct_temp
+end module gfcbug72
+
+program test
+ use gfcbug72
+ implicit none
+ call setup ()
+end program test
+! { dg-final { cleanup-modules "gfcbug72" } }
+
diff --git a/gcc/testsuite/gfortran.dg/namelist_15.f90 b/gcc/testsuite/gfortran.dg/namelist_15.f90
index 233cf2275fc..e900e71d143 100644
--- a/gcc/testsuite/gfortran.dg/namelist_15.f90
+++ b/gcc/testsuite/gfortran.dg/namelist_15.f90
@@ -24,15 +24,19 @@ program namelist_15
write (10, '(A)') "&MYNML"
write (10, '(A)') " x = 3, 4, 'dd', 'ee', 'ff', 'gg',"
write (10, '(A)') " 4, 5, 'hh', 'ii', 'jj', 'kk',"
- write (10, '(A)') " x%i = , ,-3, -4"
- write (10, '(A)') " x(2)%m(1)%ch(2) ='q',"
- write (10, '(A)') " x(2)%m(2)%ch(1)(1) ='w',"
- write (10, '(A)') " x%m%ch(:)(2) = 'z','z','z','z','z','z','z','z',"
- write (10, '(A)') "&end"
+ write (10, '(A)') " x(1)%i = , ,"
+ write (10, '(A)') " x(2)%i = -3, -4"
+ write (10, '(A)') " x(2)%m(1)%ch(2)(1:1) ='q',"
+ write (10, '(A)') " x(2)%m(2)%ch(1)(1:1) ='w',"
+ write (10, '(A)') " x(1)%m(1)%ch(1:2)(2:2) = 'z','z',"
+ write (10, '(A)') " x(2)%m(1)%ch(1:2)(2:2) = 'z','z',"
+ write (10, '(A)') " x(1)%m(2)%ch(1:2)(2:2) = 'z','z',"
+ write (10, '(A)') " x(2)%m(2)%ch(1:2)(2:2) = 'z','z',"
+ write (10, '(A)') "/"
rewind (10)
read (10, nml = mynml, iostat = ier)
- if (ier .ne. 0) print *, 'First read.' !call abort ()
+ if (ier .ne. 0) call abort ()
close (10)
open (10, status = "scratch", delim='apostrophe')
@@ -40,7 +44,7 @@ program namelist_15
rewind (10)
read (10, nml = mynml, iostat = ier)
- if (ier .ne. 0) print *, 'Second read.' !call abort ()
+ if (ier .ne. 0) call abort ()
close(10)
if (.not. ((x(1)%i(1) == 3) .and. &
diff --git a/gcc/testsuite/gfortran.dg/namelist_38.f90 b/gcc/testsuite/gfortran.dg/namelist_38.f90
new file mode 100644
index 00000000000..5578654eea4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/namelist_38.f90
@@ -0,0 +1,36 @@
+! { dg-do run }
+! PR33253 namelist: reading back a string, also fixed writing with delimiters.
+! Test case modified from that of the PR by
+! Jerry DeLisle <jvdelisle@gcc.gnu.org>
+program main
+ implicit none
+ character(len=3) :: a
+ namelist /foo/ a
+
+ open(10, status="scratch", delim="quote")
+ a = 'a"a'
+ write(10,foo)
+ rewind 10
+ a = ""
+ read (10,foo) ! This gave a runtime error before the patch.
+ if (a.ne.'a"a') call abort
+ close (10)
+
+ open(10, status="scratch", delim="apostrophe")
+ a = "a'a"
+ write(10,foo)
+ rewind 10
+ a = ""
+ read (10,foo)
+ if (a.ne."a'a") call abort
+ close (10)
+
+ open(10, status="scratch", delim="none")
+ a = "a'a"
+ write(10,foo)
+ rewind 10
+ a = ""
+ read (10,foo)
+ if (a.ne."a'a") call abort
+ close (10)
+end program main
diff --git a/gcc/testsuite/gfortran.dg/namelist_39.f90 b/gcc/testsuite/gfortran.dg/namelist_39.f90
new file mode 100644
index 00000000000..f90198accfc
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/namelist_39.f90
@@ -0,0 +1,29 @@
+! { dg-do run }
+! PR33421 and PR33253 Weird quotation of namelist output of character arrays
+! Test case from Toon Moone, adapted by Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+! Long names used to test line_buffer feature is working.
+
+program test
+implicit none
+character(len=45) :: b01234567890123456789012345678901234567890123456789012345678901(3)
+namelist /nam/ b01234567890123456789012345678901234567890123456789012345678901
+b01234567890123456789012345678901234567890123456789012345678901 = 'x'
+open(99)
+write(99,'(4(a,/),a)') "&NAM", &
+ " b01234567890123456789012345678901234567890123456789012345678901(1)=' AAP NOOT MIES WIM ZUS JET',", &
+ " b01234567890123456789012345678901234567890123456789012345678901(2)='SURF.PRESSURE',", &
+ " b01234567890123456789012345678901234567890123456789012345678901(3)='APEKOOL',", &
+ " /"
+rewind(99)
+read(99,nml=nam)
+close(99)
+
+if (b01234567890123456789012345678901234567890123456789012345678901(1).ne.&
+ " AAP NOOT MIES WIM ZUS JET ") call abort
+if (b01234567890123456789012345678901234567890123456789012345678901(2).ne.&
+ "SURF.PRESSURE ") call abort
+if (b01234567890123456789012345678901234567890123456789012345678901(3).ne.&
+ "APEKOOL ") call abort
+end program test
+
diff --git a/gcc/testsuite/gfortran.dg/namelist_print_1.f b/gcc/testsuite/gfortran.dg/namelist_print_1.f
index dfd2841f022..5c0e7759088 100644
--- a/gcc/testsuite/gfortran.dg/namelist_print_1.f
+++ b/gcc/testsuite/gfortran.dg/namelist_print_1.f
@@ -9,5 +9,5 @@
namelist /mynml/ x
x = 1
! ( dg-output "^" }
- print mynml ! { dg-output "&MYNML(\n|\r\n|\r) X= 1.000000 , /(\n|\r\n|\r)" }
+ print mynml ! { dg-output "&MYNML(\n|\r\n|\r) X= 1.00000000 , /(\n|\r\n|\r)" }
end
diff --git a/gcc/testsuite/gfortran.dg/parens_6.f90 b/gcc/testsuite/gfortran.dg/parens_6.f90
new file mode 100644
index 00000000000..5a888a60056
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/parens_6.f90
@@ -0,0 +1,11 @@
+! { dg-do run }
+! PR fortran/33626
+! Types were not always propagated correctly
+ logical(kind=1) :: i, j
+ integer(kind=1) :: a, b
+ character*1 :: c, d
+ if (any( (/ kind(i .and. j), kind(.not. (i .and. j)), kind((a + b)), &
+ kind((42_1)), kind((j .and. i)), kind((.true._1)), &
+ kind(c // d), kind((c) // d), kind((c//d)) /) /= 1 )) call abort()
+ if (any( (/ len(c // d), len((c) // d), len ((c // d)) /) /= 2)) call abort()
+end
diff --git a/gcc/testsuite/gfortran.dg/pr33646.f90 b/gcc/testsuite/gfortran.dg/pr33646.f90
new file mode 100644
index 00000000000..13f65cb06a5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr33646.f90
@@ -0,0 +1,59 @@
+! { dg-do compile }
+! PR fortran/33646
+!
+!
+
+module BAR_MODULE
+ implicit none
+ private
+ public create_
+ interface create_
+ module procedure create
+ end interface
+ type system_type
+ integer(kind=kind(1)) :: max_memory_used
+ end type
+
+contains
+
+ subroutine create(self)
+ type(system_type) :: self
+ pointer :: self
+ allocate(self)
+ end subroutine
+
+end
+
+module FOO_MODULE
+ use BAR_MODULE
+ implicit none
+ private
+ public create_
+ interface create_
+ module procedure create
+ end interface
+
+ public create_copy_
+ interface create_copy_
+ module procedure create_copy
+ end interface
+contains
+
+ subroutine create(self)
+ character(*) :: self
+ pointer :: self
+ nullify(self)
+ allocate(self)
+
+ self = " "
+ end subroutine
+
+ subroutine create_copy(self,s)
+ character(*) :: self
+ pointer :: self
+ character(*) :: s
+ call create_(self)
+ end subroutine
+end
+
+! { dg-final { cleanup-modules "BAR_MODULE FOO_MODULE" } }
diff --git a/gcc/testsuite/gfortran.dg/real_const_3.f90 b/gcc/testsuite/gfortran.dg/real_const_3.f90
index 533b4af65f0..d6b2a968d8e 100644
--- a/gcc/testsuite/gfortran.dg/real_const_3.f90
+++ b/gcc/testsuite/gfortran.dg/real_const_3.f90
@@ -27,15 +27,15 @@ program main
end program main
!{ dg-output " \\+Infinity(\n|\r\n|\r)" }
-!{ dg-output " 0.000000 (\n|\r\n|\r)" }
-!{ dg-output " -Infinity(\n|\r\n|\r)" }
-!{ dg-output " NaN(\n|\r\n|\r)" }
-!{ dg-output " NaN(\n|\r\n|\r)" }
-!{ dg-output " -Infinity(\n|\r\n|\r)" }
-!{ dg-output " -Infinity(\n|\r\n|\r)" }
-!{ dg-output " \\+Infinity(\n|\r\n|\r)" }
-!{ dg-output " NaN(\n|\r\n|\r)" }
-!{ dg-output " \\( NaN, NaN\\)(\n|\r\n|\r)" }
-!{ dg-output " \\( NaN, NaN\\)(\n|\r\n|\r)" }
-!{ dg-output " \\( \\+Infinity, -Infinity\\)(\n|\r\n|\r)" }
-!{ dg-output " \\( 0.000000 , -0.000000 \\)(\n|\r\n|\r)" }
+!{ dg-output " 0.0000000 (\n|\r\n|\r)" }
+!{ dg-output " -Infinity(\n|\r\n|\r)" }
+!{ dg-output " NaN(\n|\r\n|\r)" }
+!{ dg-output " NaN(\n|\r\n|\r)" }
+!{ dg-output " -Infinity(\n|\r\n|\r)" }
+!{ dg-output " -Infinity(\n|\r\n|\r)" }
+!{ dg-output " \\+Infinity(\n|\r\n|\r)" }
+!{ dg-output " NaN(\n|\r\n|\r)" }
+!{ dg-output " \\( NaN, NaN\\)(\n|\r\n|\r)" }
+!{ dg-output " \\( NaN, NaN\\)(\n|\r\n|\r)" }
+!{ dg-output " \\( \\+Infinity, -Infinity\\)(\n|\r\n|\r)" }
+!{ dg-output " \\( 0.0000000 , -0.0000000 \\)(\n|\r\n|\r)" }
diff --git a/gcc/testsuite/gfortran.dg/repeat_2.f90 b/gcc/testsuite/gfortran.dg/repeat_2.f90
index bcb70e2131c..d71f1860aa3 100644
--- a/gcc/testsuite/gfortran.dg/repeat_2.f90
+++ b/gcc/testsuite/gfortran.dg/repeat_2.f90
@@ -22,10 +22,10 @@ end subroutine bar
program test
implicit none
- character(len=0), parameter :: s0 = "" ! { dg-warning "zero length" }
+ character(len=0), parameter :: s0 = ""
character(len=1), parameter :: s1 = "a"
character(len=2), parameter :: s2 = "ab"
- character(len=0) :: t0 ! { dg-warning "CHARACTER variable has zero length" }
+ character(len=0) :: t0
character(len=1) :: t1
character(len=2) :: t2
integer :: i
diff --git a/gcc/testsuite/gfortran.dg/repeat_4.f90 b/gcc/testsuite/gfortran.dg/repeat_4.f90
index 64d213a147f..e5b5acc60ce 100644
--- a/gcc/testsuite/gfortran.dg/repeat_4.f90
+++ b/gcc/testsuite/gfortran.dg/repeat_4.f90
@@ -3,10 +3,10 @@
! { dg-do compile }
program test
implicit none
- character(len=0), parameter :: s0 = "" ! { dg-warning "zero length" }
+ character(len=0), parameter :: s0 = ""
character(len=1), parameter :: s1 = "a"
character(len=2), parameter :: s2 = "ab"
- character(len=0) :: t0 ! { dg-warning "CHARACTER variable has zero length" }
+ character(len=0) :: t0
character(len=1) :: t1
character(len=2) :: t2
diff --git a/gcc/testsuite/gfortran.dg/spec_expr_5.f90 b/gcc/testsuite/gfortran.dg/spec_expr_5.f90
new file mode 100644
index 00000000000..819038348c2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/spec_expr_5.f90
@@ -0,0 +1,8 @@
+! { dg-do compile }
+! PR 33689
+! Wrongly rejected valid code due to non-trivial expression for array bound
+ subroutine grylmr()
+ integer, parameter :: lmaxd = 20
+ REAL, save :: c(0:(lmaxd+1)*(lmaxd+1))
+ end subroutine grylmr
+end
diff --git a/gcc/testsuite/gfortran.dg/zero_length_2.f90 b/gcc/testsuite/gfortran.dg/zero_length_2.f90
index 31b99f58fac..2cc3f2938ca 100644
--- a/gcc/testsuite/gfortran.dg/zero_length_2.f90
+++ b/gcc/testsuite/gfortran.dg/zero_length_2.f90
@@ -1,6 +1,6 @@
! { dg-do run }
character(len=1) :: s
- character(len=0) :: s0 ! { dg-warning "CHARACTER variable has zero length" }
+ character(len=0) :: s0
s = " "
s0 = ""
call bar ("")
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 40ec164073f..0d4d6d46e16 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -3747,7 +3747,6 @@ verify_gimple_expr (tree expr)
return true;
}
if (!POINTER_TYPE_P (TREE_TYPE (op0))
- || TREE_CODE (TREE_TYPE (op1)) != INTEGER_TYPE
|| !useless_type_conversion_p (type, TREE_TYPE (op0))
|| !useless_type_conversion_p (sizetype, TREE_TYPE (op1)))
{
@@ -3874,6 +3873,10 @@ verify_gimple_expr (tree expr)
didn't see a function declaration before the call. */
return false;
+ case OBJ_TYPE_REF:
+ /* FIXME. */
+ return false;
+
default:;
}
@@ -4046,12 +4049,14 @@ verify_gimple_stmt (tree stmt)
}
}
-/* Verify the GIMPLE statements inside the statement list STMTS. */
+/* Verify the GIMPLE statements inside the statement list STMTS.
+ Returns true if there were any errors. */
-void
-verify_gimple_1 (tree stmts)
+static bool
+verify_gimple_2 (tree stmts)
{
tree_stmt_iterator tsi;
+ bool err = false;
for (tsi = tsi_start (stmts); !tsi_end_p (tsi); tsi_next (&tsi))
{
@@ -4060,28 +4065,44 @@ verify_gimple_1 (tree stmts)
switch (TREE_CODE (stmt))
{
case BIND_EXPR:
- verify_gimple_1 (BIND_EXPR_BODY (stmt));
+ err |= verify_gimple_2 (BIND_EXPR_BODY (stmt));
break;
case TRY_CATCH_EXPR:
case TRY_FINALLY_EXPR:
- verify_gimple_1 (TREE_OPERAND (stmt, 0));
- verify_gimple_1 (TREE_OPERAND (stmt, 1));
+ err |= verify_gimple_2 (TREE_OPERAND (stmt, 0));
+ err |= verify_gimple_2 (TREE_OPERAND (stmt, 1));
break;
case CATCH_EXPR:
- verify_gimple_1 (CATCH_BODY (stmt));
+ err |= verify_gimple_2 (CATCH_BODY (stmt));
break;
case EH_FILTER_EXPR:
- verify_gimple_1 (EH_FILTER_FAILURE (stmt));
+ err |= verify_gimple_2 (EH_FILTER_FAILURE (stmt));
break;
default:
- if (verify_gimple_stmt (stmt))
- debug_generic_expr (stmt);
+ {
+ bool err2 = verify_gimple_stmt (stmt);
+ if (err2)
+ debug_generic_expr (stmt);
+ err |= err2;
+ }
}
}
+
+ return err;
+}
+
+
+/* Verify the GIMPLE statements inside the statement list STMTS. */
+
+void
+verify_gimple_1 (tree stmts)
+{
+ if (verify_gimple_2 (stmts))
+ internal_error ("verify_gimple failed");
}
/* Verify the GIMPLE statements inside the current function. */
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index f8aed147ccf..3ea582f7b84 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2093,3 +2093,159 @@ maybe_clean_or_replace_eh_stmt (tree old_stmt, tree new_stmt)
return false;
}
+
+/* Returns TRUE if oneh and twoh are exception handlers (op 1 of
+ TRY_CATCH_EXPR or TRY_FINALLY_EXPR that are similar enough to be
+ considered the same. Currently this only handles handlers consisting of
+ a single call, as that's the important case for C++: a destructor call
+ for a particular object showing up in multiple handlers. */
+
+static bool
+same_handler_p (tree oneh, tree twoh)
+{
+ tree_stmt_iterator i;
+ tree ones, twos;
+ int ai;
+
+ i = tsi_start (oneh);
+ if (!tsi_one_before_end_p (i))
+ return false;
+ ones = tsi_stmt (i);
+
+ i = tsi_start (twoh);
+ if (!tsi_one_before_end_p (i))
+ return false;
+ twos = tsi_stmt (i);
+
+ if (TREE_CODE (ones) != CALL_EXPR
+ || TREE_CODE (twos) != CALL_EXPR
+ || !operand_equal_p (CALL_EXPR_FN (ones), CALL_EXPR_FN (twos), 0)
+ || call_expr_nargs (ones) != call_expr_nargs (twos))
+ return false;
+
+ for (ai = 0; ai < call_expr_nargs (ones); ++ai)
+ if (!operand_equal_p (CALL_EXPR_ARG (ones, ai),
+ CALL_EXPR_ARG (twos, ai), 0))
+ return false;
+
+ return true;
+}
+
+/* Optimize
+ try { A() } finally { try { ~B() } catch { ~A() } }
+ try { ... } finally { ~A() }
+ into
+ try { A() } catch { ~B() }
+ try { ~B() ... } finally { ~A() }
+
+ This occurs frequently in C++, where A is a local variable and B is a
+ temporary used in the initializer for A. */
+
+static void
+optimize_double_finally (tree one, tree two)
+{
+ tree oneh;
+ tree_stmt_iterator i;
+
+ i = tsi_start (TREE_OPERAND (one, 1));
+ if (!tsi_one_before_end_p (i))
+ return;
+
+ oneh = tsi_stmt (i);
+ if (TREE_CODE (oneh) != TRY_CATCH_EXPR)
+ return;
+
+ if (same_handler_p (TREE_OPERAND (oneh, 1), TREE_OPERAND (two, 1)))
+ {
+ tree twoh;
+
+ tree b = TREE_OPERAND (oneh, 0);
+ TREE_OPERAND (one, 1) = b;
+ TREE_SET_CODE (one, TRY_CATCH_EXPR);
+
+ b = tsi_stmt (tsi_start (b));
+ twoh = TREE_OPERAND (two, 0);
+ /* same_handler_p only handles single-statement handlers,
+ so there must only be one statement. */
+ i = tsi_start (twoh);
+ tsi_link_before (&i, unshare_expr (b), TSI_SAME_STMT);
+ }
+}
+
+/* Perform EH refactoring optimizations that are simpler to do when code
+ flow has been lowered but EH structurs haven't. */
+
+static void
+refactor_eh_r (tree t)
+{
+ tailrecurse:
+ switch (TREE_CODE (t))
+ {
+ case TRY_FINALLY_EXPR:
+ case TRY_CATCH_EXPR:
+ refactor_eh_r (TREE_OPERAND (t, 0));
+ t = TREE_OPERAND (t, 1);
+ goto tailrecurse;
+
+ case CATCH_EXPR:
+ t = CATCH_BODY (t);
+ goto tailrecurse;
+
+ case EH_FILTER_EXPR:
+ t = EH_FILTER_FAILURE (t);
+ goto tailrecurse;
+
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i;
+ tree one = NULL_TREE, two = NULL_TREE;
+ /* Try to refactor double try/finally. */
+ for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
+ {
+ one = two;
+ two = tsi_stmt (i);
+ if (one && two
+ && TREE_CODE (one) == TRY_FINALLY_EXPR
+ && TREE_CODE (two) == TRY_FINALLY_EXPR)
+ optimize_double_finally (one, two);
+ if (one)
+ refactor_eh_r (one);
+ }
+ if (two)
+ {
+ t = two;
+ goto tailrecurse;
+ }
+ }
+ break;
+
+ default:
+ /* A type, a decl, or some kind of statement that we're not
+ interested in. Don't walk them. */
+ break;
+ }
+}
+
+static unsigned
+refactor_eh (void)
+{
+ refactor_eh_r (DECL_SAVED_TREE (current_function_decl));
+ return 0;
+}
+
+struct tree_opt_pass pass_refactor_eh =
+{
+ "ehopt", /* name */
+ NULL, /* gate */
+ refactor_eh, /* 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_flags_finish */
+ 0 /* letter */
+};
diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c
index fc77c0a89da..33974fb65b3 100644
--- a/gcc/tree-gimple.c
+++ b/gcc/tree-gimple.c
@@ -522,3 +522,47 @@ recalculate_side_effects (tree t)
gcc_unreachable ();
}
}
+
+/* Canonicalize a tree T for use in a COND_EXPR as conditional. Returns
+ a canonicalized tree that is valid for a COND_EXPR or NULL_TREE, if
+ we failed to create one. */
+
+tree
+canonicalize_cond_expr_cond (tree t)
+{
+ /* For (bool)x use x != 0. */
+ if (TREE_CODE (t) == NOP_EXPR
+ && TREE_TYPE (t) == boolean_type_node)
+ {
+ tree top0 = TREE_OPERAND (t, 0);
+ t = build2 (NE_EXPR, TREE_TYPE (t),
+ top0, build_int_cst (TREE_TYPE (top0), 0));
+ }
+ /* For !x use x == 0. */
+ else if (TREE_CODE (t) == TRUTH_NOT_EXPR)
+ {
+ tree top0 = TREE_OPERAND (t, 0);
+ t = build2 (EQ_EXPR, TREE_TYPE (t),
+ top0, build_int_cst (TREE_TYPE (top0), 0));
+ }
+ /* For cmp ? 1 : 0 use cmp. */
+ else if (TREE_CODE (t) == COND_EXPR
+ && COMPARISON_CLASS_P (TREE_OPERAND (t, 0))
+ && integer_onep (TREE_OPERAND (t, 1))
+ && integer_zerop (TREE_OPERAND (t, 2)))
+ {
+ tree top0 = TREE_OPERAND (t, 0);
+ t = build2 (TREE_CODE (top0), TREE_TYPE (t),
+ TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1));
+ }
+
+ /* A valid conditional for a COND_EXPR is either a gimple value
+ or a comparison with two gimple value operands. */
+ if (is_gimple_val (t)
+ || (COMPARISON_CLASS_P (t)
+ && is_gimple_val (TREE_OPERAND (t, 0))
+ && is_gimple_val (TREE_OPERAND (t, 1))))
+ return t;
+
+ return NULL_TREE;
+}
diff --git a/gcc/tree-gimple.h b/gcc/tree-gimple.h
index 09182d725cf..2493b6b2419 100644
--- a/gcc/tree-gimple.h
+++ b/gcc/tree-gimple.h
@@ -133,6 +133,7 @@ extern enum gimplify_status gimplify_va_arg_expr (tree *, tree *, tree *);
struct gimplify_omp_ctx;
extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree);
extern tree gimple_boolify (tree);
+extern tree canonicalize_cond_expr_cond (tree);
/* In omp-low.c. */
extern void diagnose_omp_structured_block_errors (tree);
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index a0b7b8cae95..a2f41d5f97f 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1027,9 +1027,11 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, int count_scal
across EH edges from basic block within inlined functions destinating
to landing pads in function we inline into.
- The function mark PHI_RESULT of such PHI nodes for renaming; it is
- safe the EH edges are abnormal and SSA_NAME_OCCURS_IN_ABNORMAL_PHI
- must be set. This means, that there will be no overlapping live ranges
+ The function fills in PHI_RESULTs of such PHI nodes if they refer
+ to gimple regs. Otherwise, the function mark PHI_RESULT of such
+ PHI nodes for renaming. For non-gimple regs, renaming is safe: the
+ EH edges are abnormal and SSA_NAME_OCCURS_IN_ABNORMAL_PHI must be
+ set, and this means that there will be no overlapping live ranges
for the underlying symbol.
This might change in future if we allow redirecting of EH edges and
@@ -1071,7 +1073,8 @@ update_ssa_across_abnormal_edges (basic_block bb, basic_block ret_bb,
}
re = find_edge (ret_bb, e->dest);
- gcc_assert (re);
+ if (!re)
+ continue;
gcc_assert ((re->flags & (EDGE_EH | EDGE_ABNORMAL))
== (e->flags & (EDGE_EH | EDGE_ABNORMAL)));
diff --git a/gcc/tree-loop-linear.c b/gcc/tree-loop-linear.c
index d04045ded4f..295993f1bf9 100644
--- a/gcc/tree-loop-linear.c
+++ b/gcc/tree-loop-linear.c
@@ -253,7 +253,10 @@ linear_transform_loops (void)
loop_iterator li;
VEC(tree,heap) *oldivs = NULL;
VEC(tree,heap) *invariants = NULL;
+ VEC(tree,heap) *remove_ivs = VEC_alloc (tree, heap, 3);
struct loop *loop_nest;
+ tree oldiv_stmt;
+ unsigned i;
FOR_EACH_LOOP (li, loop_nest, 0)
{
@@ -351,6 +354,7 @@ linear_transform_loops (void)
}
lambda_loopnest_to_gcc_loopnest (loop_nest, oldivs, invariants,
+ &remove_ivs,
after, trans, &lambda_obstack);
modified = true;
@@ -363,8 +367,12 @@ linear_transform_loops (void)
free_data_refs (datarefs);
}
+ for (i = 0; VEC_iterate (tree, remove_ivs, i, oldiv_stmt); i++)
+ remove_iv (oldiv_stmt);
+
VEC_free (tree, heap, oldivs);
VEC_free (tree, heap, invariants);
+ VEC_free (tree, heap, remove_ivs);
scev_reset ();
if (modified)
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index b19d3d05931..1f748e82635 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -246,6 +246,7 @@ extern struct tree_opt_pass pass_mudflap_1;
extern struct tree_opt_pass pass_mudflap_2;
extern struct tree_opt_pass pass_remove_useless_stmts;
extern struct tree_opt_pass pass_lower_cf;
+extern struct tree_opt_pass pass_refactor_eh;
extern struct tree_opt_pass pass_lower_eh;
extern struct tree_opt_pass pass_build_cfg;
extern struct tree_opt_pass pass_tree_profile;
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index ff7a52c1a76..21da0c0a298 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1275,7 +1275,7 @@ instantiate_element (struct sra_elt *elt)
elt->in_bitfld_block = 1;
elt->replacement = build3 (BIT_FIELD_REF, elt->type, var,
DECL_SIZE (var),
- BITS_BIG_ENDIAN
+ BYTES_BIG_ENDIAN
? size_binop (MINUS_EXPR,
TYPE_SIZE (elt->type),
DECL_SIZE (var))
@@ -2140,7 +2140,7 @@ sra_build_assignment (tree dst, tree src)
cst2 = size_binop (PLUS_EXPR, TREE_OPERAND (src, 1),
TREE_OPERAND (src, 2));
- if (BITS_BIG_ENDIAN)
+ if (BYTES_BIG_ENDIAN)
{
maxshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst);
minshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst2);
@@ -2168,7 +2168,7 @@ sra_build_assignment (tree dst, tree src)
list = NULL;
cst2 = size_binop (MINUS_EXPR, maxshift, minshift);
- if (tree_int_cst_equal (cst2, TYPE_SIZE (utype)))
+ if (TREE_INT_CST_LOW (cst2) == TYPE_PRECISION (utype))
{
unsignedp = true;
mask = NULL_TREE;
@@ -2322,7 +2322,7 @@ sra_build_bf_assignment (tree dst, tree src)
fold_convert (bitsizetype, TREE_OPERAND (dst, 1)),
cst);
- if (BITS_BIG_ENDIAN)
+ if (BYTES_BIG_ENDIAN)
{
maxshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst);
minshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst2);
@@ -2343,8 +2343,14 @@ sra_build_bf_assignment (tree dst, tree src)
utype = unsigned_type_for (type);
mask = build_int_cst_wide (utype, 1, 0);
- cst = int_const_binop (LSHIFT_EXPR, mask, maxshift, true);
- cst2 = int_const_binop (LSHIFT_EXPR, mask, minshift, true);
+ if (TREE_INT_CST_LOW (maxshift) == TYPE_PRECISION (utype))
+ cst = build_int_cst_wide (utype, 0, 0);
+ else
+ cst = int_const_binop (LSHIFT_EXPR, mask, maxshift, true);
+ if (integer_zerop (minshift))
+ cst2 = mask;
+ else
+ cst2 = int_const_binop (LSHIFT_EXPR, mask, minshift, true);
mask = int_const_binop (MINUS_EXPR, cst, cst2, true);
mask = fold_build1 (BIT_NOT_EXPR, utype, mask);
@@ -2408,7 +2414,7 @@ sra_build_bf_assignment (tree dst, tree src)
tmp2 = fold_build1 (BIT_NOT_EXPR, utype, mask);
tmp2 = int_const_binop (RSHIFT_EXPR, tmp2, minshift, true);
tmp2 = fold_convert (ut, tmp2);
- tmp2 = fold_build2 (BIT_AND_EXPR, utype, tmp3, tmp2);
+ tmp2 = fold_build2 (BIT_AND_EXPR, ut, tmp3, tmp2);
if (tmp3 != tmp2)
{
@@ -2508,13 +2514,13 @@ sra_build_elt_assignment (struct sra_elt *elt, tree src)
{
list = NULL;
- if (!INTEGRAL_TYPE_P (TREE_TYPE (src))
- || !TYPE_UNSIGNED (TREE_TYPE (src)))
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (src)))
src = fold_build1 (VIEW_CONVERT_EXPR,
lang_hooks.types.type_for_size
(TREE_INT_CST_LOW
(TYPE_SIZE (TREE_TYPE (src))),
1), src);
+ gcc_assert (TYPE_UNSIGNED (TREE_TYPE (src)));
tmp = make_rename_temp (TREE_TYPE (src), "SR");
stmt = build_gimple_modify_stmt (tmp, src);
@@ -2897,6 +2903,12 @@ bitfield_overlaps_p (tree blen, tree bpos, struct sra_elt *fld,
flen = fold_convert (bitsizetype, TREE_OPERAND (fld->element, 1));
fpos = fold_convert (bitsizetype, TREE_OPERAND (fld->element, 2));
}
+ else if (TREE_CODE (fld->element) == INTEGER_CST)
+ {
+ flen = fold_convert (bitsizetype, TYPE_SIZE (fld->type));
+ fpos = fold_convert (bitsizetype, fld->element);
+ fpos = size_binop (MULT_EXPR, flen, fpos);
+ }
else
gcc_unreachable ();
@@ -2971,16 +2983,20 @@ sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var,
if (fld->replacement)
{
- tree infld, invar, st;
+ tree infld, invar, st, type;
infld = fld->replacement;
+ type = TREE_TYPE (infld);
+ if (TYPE_PRECISION (type) != TREE_INT_CST_LOW (flen))
+ type = lang_hooks.types.type_for_size (TREE_INT_CST_LOW (flen), 1);
+
if (TREE_CODE (infld) == BIT_FIELD_REF)
{
fpos = size_binop (PLUS_EXPR, fpos, TREE_OPERAND (infld, 2));
infld = TREE_OPERAND (infld, 0);
}
- else if (BITS_BIG_ENDIAN && DECL_P (fld->element)
+ else if (BYTES_BIG_ENDIAN && DECL_P (fld->element)
&& !tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (infld)),
DECL_SIZE (fld->element)))
{
@@ -2990,10 +3006,7 @@ sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var,
DECL_SIZE (fld->element));
}
- infld = fold_build3 (BIT_FIELD_REF,
- lang_hooks.types.type_for_size
- (TREE_INT_CST_LOW (flen), 1),
- infld, flen, fpos);
+ infld = fold_build3 (BIT_FIELD_REF, type, infld, flen, fpos);
BIT_FIELD_REF_UNSIGNED (infld) = 1;
invar = size_binop (MINUS_EXPR, flp.field_pos, bpos);
@@ -3001,8 +3014,7 @@ sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var,
invar = size_binop (PLUS_EXPR, invar, flp.overlap_pos);
invar = size_binop (PLUS_EXPR, invar, vpos);
- invar = fold_build3 (BIT_FIELD_REF, TREE_TYPE (infld),
- var, flen, invar);
+ invar = fold_build3 (BIT_FIELD_REF, type, var, flen, invar);
BIT_FIELD_REF_UNSIGNED (invar) = 1;
if (to_var)
@@ -3431,7 +3443,7 @@ scalarize_ldst (struct sra_elt *elt, tree other,
{
tree_stmt_iterator tsi;
tree first, blist = NULL;
- bool thr = (bsi->bb->flags & EDGE_COMPLEX) != 0;
+ bool thr = tree_could_throw_p (stmt);
/* If the last statement of this BB created an EH edge
before scalarization, we have to locate the first
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 31cb70afd46..8afef1f74fe 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -326,46 +326,16 @@ combine_cond_expr_cond (enum tree_code code, tree type,
/* Require that we got a boolean type out if we put one in. */
gcc_assert (TREE_CODE (TREE_TYPE (t)) == TREE_CODE (type));
- /* For (bool)x use x != 0. */
- if (TREE_CODE (t) == NOP_EXPR
- && TREE_TYPE (t) == boolean_type_node)
- {
- tree top0 = TREE_OPERAND (t, 0);
- t = build2 (NE_EXPR, type,
- top0, build_int_cst (TREE_TYPE (top0), 0));
- }
- /* For !x use x == 0. */
- else if (TREE_CODE (t) == TRUTH_NOT_EXPR)
- {
- tree top0 = TREE_OPERAND (t, 0);
- t = build2 (EQ_EXPR, type,
- top0, build_int_cst (TREE_TYPE (top0), 0));
- }
- /* For cmp ? 1 : 0 use cmp. */
- else if (TREE_CODE (t) == COND_EXPR
- && COMPARISON_CLASS_P (TREE_OPERAND (t, 0))
- && integer_onep (TREE_OPERAND (t, 1))
- && integer_zerop (TREE_OPERAND (t, 2)))
- {
- tree top0 = TREE_OPERAND (t, 0);
- t = build2 (TREE_CODE (top0), type,
- TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1));
- }
+ /* Canonicalize the combined condition for use in a COND_EXPR. */
+ t = canonicalize_cond_expr_cond (t);
/* Bail out if we required an invariant but didn't get one. */
- if (invariant_only
- && !is_gimple_min_invariant (t))
+ if (!t
+ || (invariant_only
+ && !is_gimple_min_invariant (t)))
return NULL_TREE;
- /* A valid conditional for a COND_EXPR is either a gimple value
- or a comparison with two gimple value operands. */
- if (is_gimple_val (t)
- || (COMPARISON_CLASS_P (t)
- && is_gimple_val (TREE_OPERAND (t, 0))
- && is_gimple_val (TREE_OPERAND (t, 1))))
- return t;
-
- return NULL_TREE;
+ return t;
}
/* Propagate from the ssa name definition statements of COND_EXPR
diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c
index f52585ca20e..eef6f22d2a2 100644
--- a/gcc/tree-ssa-ifcombine.c
+++ b/gcc/tree-ssa-ifcombine.c
@@ -483,6 +483,9 @@ ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
/* Do it. */
t = fold_build2 (code, boolean_type_node,
TREE_OPERAND (ccond2, 0), TREE_OPERAND (ccond2, 1));
+ t = canonicalize_cond_expr_cond (t);
+ if (!t)
+ return false;
COND_EXPR_COND (inner_cond) = t;
update_stmt (inner_cond);
diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c
index 27fbaad9eb9..485786c5026 100644
--- a/gcc/tree-ssa-ter.c
+++ b/gcc/tree-ssa-ter.c
@@ -443,7 +443,7 @@ finished_with_expr (temp_expr_table_p tab, int version, bool free_expr)
}
-/* Create an expression entry fora replaceable expression. */
+/* Create an expression entry for a replaceable expression. */
static void
process_replaceable (temp_expr_table_p tab, tree stmt)
diff --git a/gcc/tree.h b/gcc/tree.h
index 62e5589731c..1241a3e4fef 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2695,8 +2695,7 @@ struct tree_memory_partition_tag GTY(())
(DECL_COMMON_CHECK (NODE)->decl_common.debug_expr_is_from)
/* Nonzero for a given ..._DECL node means that the name of this node should
- be ignored for symbolic debug purposes. Moreover, for a FUNCTION_DECL,
- the body of the function should also be ignored. */
+ be ignored for symbolic debug purposes. */
#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
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 9dece23fefe..e85824577f6 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -2985,15 +2985,7 @@ compare_constant (const tree t1, const tree t2)
return compare_constant (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
default:
- {
- tree nt1, nt2;
- nt1 = lang_hooks.expand_constant (t1);
- nt2 = lang_hooks.expand_constant (t2);
- if (nt1 != t1 || nt2 != t2)
- return compare_constant (nt1, nt2);
- else
- return 0;
- }
+ return 0;
}
gcc_unreachable ();
@@ -3061,12 +3053,7 @@ copy_constant (tree exp)
}
default:
- {
- tree t = lang_hooks.expand_constant (exp);
-
- gcc_assert (t != exp);
- return copy_constant (t);
- }
+ gcc_unreachable ();
}
}
@@ -3910,10 +3897,6 @@ compute_reloc_for_constant (tree exp)
int reloc = 0, reloc2;
tree tem;
- /* Give the front-end a chance to convert VALUE to something that
- looks more like a constant to the back-end. */
- exp = lang_hooks.expand_constant (exp);
-
switch (TREE_CODE (exp))
{
case ADDR_EXPR:
@@ -3978,10 +3961,6 @@ output_addressed_constants (tree exp)
{
tree tem;
- /* Give the front-end a chance to convert VALUE to something that
- looks more like a constant to the back-end. */
- exp = lang_hooks.expand_constant (exp);
-
switch (TREE_CODE (exp))
{
case ADDR_EXPR:
@@ -4055,10 +4034,6 @@ constructor_static_from_elts_p (const_tree ctor)
tree
initializer_constant_valid_p (tree value, tree endtype)
{
- /* Give the front-end a chance to convert VALUE to something that
- looks more like a constant to the back-end. */
- value = lang_hooks.expand_constant (value);
-
switch (TREE_CODE (value))
{
case CONSTRUCTOR:
@@ -4317,11 +4292,6 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
enum tree_code code;
unsigned HOST_WIDE_INT thissize;
- /* Some front-ends use constants other than the standard language-independent
- varieties, but which may still be output directly. Give the front-end a
- chance to convert EXP to a language-independent representation. */
- exp = lang_hooks.expand_constant (exp);
-
if (size == 0 || flag_syntax_only)
return;
@@ -4378,9 +4348,6 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
code = TREE_CODE (TREE_TYPE (exp));
thissize = int_size_in_bytes (TREE_TYPE (exp));
- /* Give the front end another chance to expand constants. */
- exp = lang_hooks.expand_constant (exp);
-
/* Allow a constructor with no elements for any data type.
This means to fill the space with zeros. */
if (TREE_CODE (exp) == CONSTRUCTOR
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index aaa37a4a503..ad4c411c2a7 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,32 @@
+2007-10-04 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libfortran/33253
+ * io/list_read.c (read_character): Use line_buffer to scan ahead for
+ object name or string when no delimiter is found.
+
+2007-10-04 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR libfortran/32021
+ * runtime/environ.c (init_mem, show_mem, init_round, show_round,
+ init_precision, show_precision, init_signal, show_signal): Remove.
+ (variable_table): Remove GFORTRAN_MEM_INIT, GFORTRAN_MEM_CHECK,
+ GFORTRAN_SIGHUP, GFORTRAN_SIGINT, GFORTRAN_FPU_ROUND and
+ GFORTRAN_FPU_PRECISION.
+ * libgfortran.h (options_t): Remove mem_check, fpu_round,
+ fpu_precision, sighup, sigint, allocate_init_flag and
+ allocate_init_value.
+
+2007-10-02 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libfortran/33253
+ * io/list_read.c (read_character): Use DELIM_APOSTROPHE and DELIM_QUOTE
+ and quote value in check of first character in string.
+
+2007-10-02 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/33469
+ * io/write.c (write_real): Widen the default formats.
+
2007-09-28 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libfortran/33400
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
index 0eb1845849d..88b83443bbd 100644
--- a/libgfortran/io/list_read.c
+++ b/libgfortran/io/list_read.c
@@ -895,9 +895,51 @@ read_character (st_parameter_dt *dtp, int length __attribute__ ((unused)))
default:
if (dtp->u.p.namelist_mode)
{
- unget_char (dtp,c);
- return;
+ if (dtp->u.p.current_unit->flags.delim == DELIM_APOSTROPHE
+ || dtp->u.p.current_unit->flags.delim == DELIM_QUOTE)
+ {
+ unget_char (dtp, c);
+ return;
+ }
+
+ /* Check to see if we are seeing a namelist object name by using the
+ line buffer and looking ahead for an '=' or '('. */
+ l_push_char (dtp, c);
+
+ int i;
+ for(i = 0; i < 63; i++)
+ {
+ c = next_char (dtp);
+ if (is_separator(c))
+ {
+ unget_char (dtp, c);
+ eat_separator (dtp);
+ c = next_char (dtp);
+ if (c != '=')
+ {
+ l_push_char (dtp, c);
+ dtp->u.p.item_count = 0;
+ dtp->u.p.line_buffer_enabled = 1;
+ goto get_string;
+ }
+ }
+
+ l_push_char (dtp, c);
+ if (c == '=' || c == '(')
+ {
+ dtp->u.p.item_count = 0;
+ dtp->u.p.nml_read_error = 1;
+ dtp->u.p.line_buffer_enabled = 1;
+ return;
+ }
+ }
+
+ /* The string is too long to be a valid object name so assume that it
+ is a string to be read in as a value. */
+ dtp->u.p.line_buffer_enabled = 1;
+ goto get_string;
}
+
push_char (dtp, c);
goto get_string;
}
@@ -1004,6 +1046,7 @@ read_character (st_parameter_dt *dtp, int length __attribute__ ((unused)))
unget_char (dtp, c);
eat_separator (dtp);
dtp->u.p.saved_type = BT_CHARACTER;
+ free_line (dtp);
}
else
{
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index 4792a222b9a..84b695fa883 100644
--- a/libgfortran/io/write.c
+++ b/libgfortran/io/write.c
@@ -698,18 +698,18 @@ write_real (st_parameter_dt *dtp, const char *source, int length)
switch (length)
{
case 4:
- f.u.real.w = 14;
- f.u.real.d = 7;
+ f.u.real.w = 15;
+ f.u.real.d = 8;
f.u.real.e = 2;
break;
case 8:
- f.u.real.w = 23;
- f.u.real.d = 15;
+ f.u.real.w = 25;
+ f.u.real.d = 17;
f.u.real.e = 3;
break;
case 10:
- f.u.real.w = 28;
- f.u.real.d = 19;
+ f.u.real.w = 29;
+ f.u.real.d = 20;
f.u.real.e = 4;
break;
case 16:
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index 6a702c4b351..8d80998423d 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -344,19 +344,13 @@ typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, GFC_LOGICAL_16) gfc_array_l16;
typedef struct
{
int stdin_unit, stdout_unit, stderr_unit, optional_plus;
- int allocate_init_flag, allocate_init_value;
int locus;
int separator_len;
const char *separator;
- int mem_check;
int use_stderr, all_unbuffered, default_recl;
-
- int fpu_round, fpu_precision, fpe;
-
- int sighup, sigint;
- int dump_core, backtrace;
+ int fpe, dump_core, backtrace;
}
options_t;
diff --git a/libgfortran/runtime/environ.c b/libgfortran/runtime/environ.c
index 62e4cfaf247..ae06abe0c45 100644
--- a/libgfortran/runtime/environ.c
+++ b/libgfortran/runtime/environ.c
@@ -201,78 +201,6 @@ show_boolean (variable * v)
}
-/* init_mem()-- Initialize environment variables that have to do with
- * how memory from an ALLOCATE statement is filled. A single flag
- * enables filling and a second variable gives the value that is used
- * to initialize the memory. */
-
-static void
-init_mem (variable * v)
-{
- int offset, n;
- char *p;
-
- p = getenv (v->name);
-
- options.allocate_init_flag = 0; /* The default */
-
- if (p == NULL)
- return;
-
- if (strcasecmp (p, "NONE") == 0)
- return;
-
- /* IEEE-754 Quiet Not-a-Number that will work for single and double
- * precision. Look for the 'f95' mantissa in debug dumps. */
-
- if (strcasecmp (p, "NaN") == 0)
- {
- options.allocate_init_flag = 1;
- options.allocate_init_value = 0xfff80f95;
- return;
- }
-
- /* Interpret the string as a hexadecimal constant */
-
- n = 0;
- while (*p)
- {
- if (!isxdigit (*p))
- {
- v->bad = 1;
- return;
- }
-
- offset = '0';
- if (islower (*p))
- offset = 'a';
- if (isupper (*p))
- offset = 'A';
-
- n = (n << 4) | (*p++ - offset);
- }
-
- options.allocate_init_flag = 1;
- options.allocate_init_value = n;
-}
-
-
-static void
-show_mem (variable * v)
-{
- char *p;
-
- p = getenv (v->name);
-
- st_printf ("%s ", var_source (v));
-
- if (options.allocate_init_flag)
- st_printf ("0x%x", options.allocate_init_value);
-
- st_printf ("\n");
-}
-
-
static void
init_sep (variable * v)
{
@@ -422,43 +350,6 @@ show_choice (variable * v, const choice * c)
}
-static void
-init_round (variable * v)
-{
- init_choice (v, rounding);
-}
-
-static void
-show_round (variable * v)
-{
- show_choice (v, rounding);
-}
-
-static void
-init_precision (variable * v)
-{
- init_choice (v, precision);
-}
-
-static void
-show_precision (variable * v)
-{
- show_choice (v, precision);
-}
-
-static void
-init_signal (variable * v)
-{
- init_choice (v, signal_choices);
-}
-
-static void
-show_signal (variable * v)
-{
- show_choice (v, signal_choices);
-}
-
-
static variable variable_table[] = {
{"GFORTRAN_STDIN_UNIT", GFC_STDIN_UNIT_NUMBER, &options.stdin_unit,
init_integer, show_integer,
@@ -504,34 +395,6 @@ static variable variable_table[] = {
"Separator to use when writing list output. May contain any number of "
"spaces\nand at most one comma. Default is a single space.", 0},
- /* Memory related controls */
-
- {"GFORTRAN_MEM_INIT", 0, NULL, init_mem, show_mem,
- "How to initialize allocated memory. Default value is NONE for no "
- "initialization\n(faster), NAN for a Not-a-Number with the mantissa "
- "0x40f95 or a custom\nhexadecimal value", 0},
-
- {"GFORTRAN_MEM_CHECK", 0, &options.mem_check, init_boolean, show_boolean,
- "Whether memory still allocated will be reported when the program ends.",
- 0},
-
- /* Signal handling (Unix). */
-
- {"GFORTRAN_SIGHUP", 0, &options.sighup, init_signal, show_signal,
- "Whether the program will IGNORE or ABORT on SIGHUP.", 0},
-
- {"GFORTRAN_SIGINT", 0, &options.sigint, init_signal, show_signal,
- "Whether the program will IGNORE or ABORT on SIGINT.", 0},
-
- /* Floating point control */
-
- {"GFORTRAN_FPU_ROUND", 0, &options.fpu_round, init_round, show_round,
- "Set floating point rounding. Values are NEAREST, UP, DOWN, ZERO.", 0},
-
- {"GFORTRAN_FPU_PRECISION", 0, &options.fpu_precision, init_precision,
- show_precision,
- "Precision of intermediate results. Values are 24, 53 and 64.", 0},
-
/* GFORTRAN_CONVERT_UNIT - Set the default data conversion for
unformatted I/O. */
{"GFORTRAN_CONVERT_UNIT", 0, 0, init_unformatted, show_string,
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 5ace7b1618d..90ea0bf8155 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,481 @@
+2007-10-08 Johannes Singler <singler@ira.uka.de>
+
+ * include/parallel/base.h: Added plus and multiplies functor
+ for differently typed objects.
+ * include/parallel/numeric: Use it.
+ * include/parallel/for_each_selectors.h: Allowed different types.
+ * include/parallel/partial_sum.h: Fixed return value.
+ * testsuite/26_numerics/accumulate/1.cc: Tests for accumulate.
+ * testsuite/26_numerics/inner_product/1.cc: Tests for inner_product.
+
+2007-10-08 Paolo Carlini <pcarlini@suse.de>
+
+ * include/bits/stl_move.h (_GLIBCXX_MOVE): Add.
+ * include/bits/stl_algobase.h: Adjust.
+ * include/bits/stl_pair.h: Likewise.
+
+ * include/bits/stl_algo.h: Minor formatting fixes.
+
+2007-10-08 Benjamin Kosnik <bkoz@redhat.com>
+
+ PR libstdc++/33489
+ * include/parallel/multiseq_selection.h: Remove default constructed
+ value_type.
+ * include/parallel/partition.h:
+ * include/parallel/partial_sum.h: Format.
+
+2007-10-08 Johannes Singler <singler@ira.uka.de>
+
+ * include/parallel/multiway_merge.h: Added reference to paper.
+ * include/parallel/multiseq_selection.h: Added reference to paper.
+ * include/parallel/workstealing.h: Added reference to paper.
+ * include/parallel/balanced_quicksort.h: Added reference to paper.
+ * include/parallel/tree.h: Added reference to paper.
+ * docs/html/parallel_mode.html: Added reference to MCSTL.
+ More documentation on compile-time settings and tuning.
+
+2007-10-08 Paolo Carlini <pcarlini@suse.de>
+
+ * include/std/utility (identity, move, forward): Move to...
+ * include/bits/stl_move.h: ... here.
+ * include/Makefile.am: Add.
+ * include/bits/stl_algobase.h: Include the latter.
+ * include/Makefile.in: Regenerate.
+ * testsuite/20_util/pair/moveable.cc: Remove dg-require-rvalref.
+
+2007-10-08 Chris Jefferson <chris@bubblescope.net>
+ Paolo Carlini <pcarlini@suse.de>
+
+ * include/bits/stl_pair.h (pair<>:pair(pair&&),
+ pair<>::operator=(pair&&)): Add.
+
+2007-10-07 Chris Jefferson <chris@bubblescope.net>
+ Paolo Carlini <pcarlini@suse.de>
+
+ * include/debug/list (list<>::list(list&&),
+ list<>::operator=(list&&)): Add.
+ (list<>::swap): Adjust.
+ (swap(list&&, list& __y), swap(list&, list&& __y)): Add.
+ * include/debug/vector (vector<>::vector(vector&&),
+ vector<>::operator=(vector&&)): Add.
+ (vector<>::swap): Adjust.
+ (swap(vector&&, vector& __y), swap(vector&, vector&& __y)): Add.
+ * include/debug/deque (deque<>::deque(deque&&),
+ deque<>::operator=(deque&&)): Add.
+ (deque<>::swap): Adjust.
+ (swap(deque&&, deque& __y), swap(deque&, deque&& __y)): Add.
+ * include/debug/set.h (set<>::set(set&&),
+ set<>::operator=(set&&)): Add.
+ (set<>::swap): Adjust.
+ (swap(set&&, set& __y), swap(set&, set&& __y)): Add.
+ * include/debug/map.h (map<>::map(map&&),
+ map<>::operator=(map&&)): Add.
+ (map<>::swap): Adjust.
+ (swap(map&&, map& __y), swap(map&, map&& __y)): Add.
+ * include/debug/multiset.h (multiset<>::multiset(multiset&&),
+ multiset<>::operator=(multiset&&)): Add.
+ (smultiet<>::swap): Adjust.
+ (swap(multiset&&, multiset& __y),
+ swap(multiset&, multiset&& __y)): Add.
+ * include/debug/multimap.h (multimap<>::multimap(multimap&&),
+ multimap<>::operator=(multimap&&)): Add.
+ (multimap<>::swap): Adjust.
+ (swap(multimap&&, multimap& __y),
+ swap(multimap&, multimap&& __y)): Add.
+
+2007-10-07 Paolo Carlini <pcarlini@suse.de>
+
+ * include/bits/stl_algobase.h (_GLIBCXX_MOVE): Add.
+ (swap, __iter_swap): Use it.
+ * testsuite/25_algorithms/rotate/moveable.cc: Remove
+ dg-require-rvalref.
+ * testsuite/25_algorithms/remove/moveable.cc: Likewise.
+ * testsuite/25_algorithms/partition/moveable.cc: Likewise.
+ * testsuite/25_algorithms/swap_ranges/moveable.cc: Likewise.
+ * testsuite/25_algorithms/reverse/moveable.cc: Likewise.
+ * testsuite/25_algorithms/unique/moveable.cc: Likewise.
+ * testsuite/25_algorithms/remove_if/moveable.cc: Likewise.
+
+ * include/bits/stl_algobase.h (lexicographical_compare):
+ Clean up.
+
+2007-10-07 Chris Jefferson <chris@bubblescope.net>
+ Paolo Carlini <pcarlini@suse.de>
+
+ * include/bits/stl_algo.h (remove, remove_if, unique,
+ __rotate(_RandomAccessIterator, _RandomAccessIterator,
+ _RandomAccessIterator, random_access_iterator_tag)): Use _GLIBCXX_MOVE.
+ (__rotate(_ForwardIterator, _ForwardIterator, _ForwardIterator,
+ forward_iterator_tag), __rotate(_BidirectionalIterator,
+ _BidirectionalIterator, _BidirectionalIterator,
+ bidirectional_iterator_tag), __partition(_ForwardIterator,
+ _ForwardIterator, _Predicate, forward_iterator_tag)): Use iter_swap.
+
+2007-10-06 Benjamin Kosnik <bkoz@redhat.com>
+
+ PR libstdc++/33678
+ * libsupc++/typeinfo (typeinfo): Revert ordering of virtual components.
+
+2007-10-06 Benjamin Kosnik <bkoz@redhat.com>
+
+ PR libstdc++/33487
+ * include/parallel/algorithmfwd.h (for_each, generate, generate_n,
+ transform, replace, replace_if, max_element, min_element, count,
+ count_if): Consistently construct overloads.
+ * include/parallel/numericfwd.h (accumulate, adjacent_difference,
+ inner_product): Same.
+ * include/parallel/algobase.h: Same.
+ * include/parallel/algo.h: Same.
+ * include/parallel/numeric: Same.
+
+ * include/bits/algorithmfwd.h: Correct find_end placement.
+
+ * docs/html/parallel_mode.html: Document some of the interface
+ conventions.
+
+ * include/parallel/search.h (calc_borders): Only use operator ==.
+
+ * include/parallel/algorithmfwd.h: Move __gnu_sequential bits to...
+ * include/parallel/tags.h: ...here, and use a using directive.
+
+ * include/parallel/random_shuffle.h: Include stl_numeric. Qualify
+ uses of partial_num with __gnu_sequential.
+
+ * include/parallel/tree.h: Formatting.
+
+2007-10-05 Benjamin Kosnik <bkoz@redhat.com>
+
+ Fixes for --disable-libstdcxx-pch.
+ * include/ext/rc_string_base.h: Include stl_iterator_base_funcs.h.
+ * include/ext/vstring_util.h: Include stl_iterator.h and
+ numeric_traits.h.
+ * include/tr1/functional: Include new.
+ * testsuite/util/testsuite_api.h: Include exception.
+ * testsuite/lib/libstdc++.exp (libstdc++_init): Set
+ PCH_CXXFLAGS via cxxpchflags.
+
+ * testsuite/25_algorithms/binary_search/requirements/
+ explicit_instantiation/2.cc: Same.: Fix includes.
+ * testsuite/25_algorithms/count_if/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/equal_range/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/find_end/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/find_first_of/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/find_if/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/for_each/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/includes/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/inplace_merge/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/lexicographical_compare/
+ requirements/explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/lower_bound/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/make_heap/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/max_element/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/max/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/merge/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/min_element/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/min/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/next_permutation/
+ requirements/explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/nth_element/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/partial_sort_copy/
+ requirements/explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/partial_sort/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/partition/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/pop_heap/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/prev_permutation/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/push_heap/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/random_shuffle/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/remove_copy_if/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/remove_if/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/replace_copy_if/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/replace_if/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/search_n/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/search/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/set_difference/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/set_intersection/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/set_symmetric_difference/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/set_union/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/sort_heap/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/sort/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/stable_partition/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/stable_sort/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/transform/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/unique_copy/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/unique/requirements/
+ explicit_instantiation/2.cc: Same.
+ * testsuite/25_algorithms/upper_bound/requirements/
+ explicit_instantiation/2.cc: Same.
+
+ * testsuite/25_algorithms/remove/requirements/
+ explicit_instantiation/pod.cc: Provide a hint to the compiler.
+
+2007-10-05 Paolo Carlini <pcarlini@suse.de>
+
+ * testsuite/23_containers/map/moveable.cc: Remove dg-require-rvalref.
+ * testsuite/23_containers/multimap/moveable.cc: Likewise.
+ * testsuite/23_containers/set/moveable.cc: Likewise.
+ * testsuite/23_containers/multiset/moveable.cc: Likewise.
+ * testsuite/23_containers/deque/moveable.cc: Likewise.
+ * testsuite/23_containers/list/moveable.cc: Likewise.
+ * testsuite/23_containers/vector/moveable.cc: Likewise.
+ * include/std/utility: Use _GLIBCXX_BEGIN_NAMESPACE.
+
+2007-10-05 Paolo Carlini <pcarlini@suse.de>
+ Chris Jefferson <chris@bubblescope.net>
+
+ * include/bits/stl_iterator.h (class move_iterator,
+ make_move_iterator): Add.
+
+2007-10-04 Doug Kwan <dougkwan@google.com>
+
+ * include/ext/concurrent.h (class __mutex,
+ class __recursive_mutex): Add new method gthread_mutex to access
+ inner gthread mutex.
+ [__GTHREAD_HAS_COND] (class __concurrence_broadcast_error,
+ class __concurrence_wait_error, class __cond): Add.
+ * libsupc++/guard.cc (recursive_push, recursive_pop): Delete.
+ (init_in_progress_flag, set_init_in_progress_flag): Add to
+ replace recursive_push and recursive_pop.
+ (throw_recursive_init_exception): Add.
+ (acquire, __cxa_guard_acquire, __cxa_guard_abort and
+ __cxa_guard_release): [__GTHREAD_HAS_COND] Use a conditional
+ for synchronization of static variable initialization.
+ The global mutex is only held briefly when guards are
+ accessed. [!__GTHREAD_HAS_COND] Fall back to the old code,
+ which deadlocks.
+ * testsuite/thread/guard.cc: Add new test. It deadlocks with the
+ old locking code in libstdc++-v3/libsup++/guard.cc.
+
+2007-10-04 Paolo Carlini <pcarlini@suse.de>
+
+ * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
+ Adjust dg-error line number.
+ * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc:
+ Likewise.
+ * testsuite/23_containers/vector/requirements/dr438/
+ constructor_1_neg.cc: Likewise.
+ * testsuite/23_containers/vector/requirements/dr438/
+ constructor_2_neg.cc: Likewise.
+ * testsuite/23_containers/deque/requirements/dr438/assign_neg.cc:
+ Adjust dg-error line number.
+ * testsuite/23_containers/deque/requirements/dr438/insert_neg.cc:
+ Likewise.
+ * testsuite/23_containers/deque/requirements/dr438/
+ constructor_1_neg.cc: Likewise.
+ * testsuite/23_containers/deque/requirements/dr438/
+ constructor_2_neg.cc: Likewise.
+ * testsuite/23_containers/list/requirements/dr438/assign_neg.cc:
+ Adjust dg-error line number.
+ * testsuite/23_containers/list/requirements/dr438/insert_neg.cc:
+ Likewise.
+ * testsuite/23_containers/list/requirements/dr438/
+ constructor_1_neg.cc: Likewise.
+ * testsuite/23_containers/list/requirements/dr438/
+ constructor_2_neg.cc: Likewise.
+
+2007-10-04 Chris Jefferson <chris@bubblescope.net>
+ Paolo Carlini <pcarlini@suse.de>
+
+ * include/bits/stl_list.h (list<>::list(list&&),
+ list<>::operator=(list&&)): Add.
+ (list<>::swap): Adjust.
+ (swap(list&&, list& __y), swap(list&, list&& __y)): Add.
+ * include/bits/stl_vector.h (vector<>::vector(vector&&),
+ vector<>::operator=(vector&&)): Add.
+ (vector<>::swap): Adjust.
+ (swap(vector&&, vector& __y), swap(vector&, vector&& __y)): Add.
+ * include/bits/stl_bvector.h (vector<>::vector(vector&&),
+ vector<>::operator=(vector&&)): Add.
+ (vector<>::swap): Adjust.
+ * include/bits/stl_deque.h (deque<>::deque(deque&&),
+ deque<>::operator=(deque&&)): Add.
+ (deque<>::swap): Adjust.
+ (swap(deque&&, deque& __y), swap(deque&, deque&& __y)): Add.
+ * include/bits/stl_set.h (set<>::set(set&&),
+ set<>::operator=(set&&)): Add.
+ (set<>::swap): Adjust.
+ (swap(set&&, set& __y), swap(set&, set&& __y)): Add.
+ * include/bits/stl_map.h (map<>::map(map&&),
+ map<>::operator=(map&&)): Add.
+ (map<>::swap): Adjust.
+ (swap(map&&, map& __y), swap(map&, map&& __y)): Add.
+ * include/bits/stl_multiset.h (multiset<>::multiset(multiset&&),
+ multiset<>::operator=(multiset&&)): Add.
+ (smultiet<>::swap): Adjust.
+ (swap(multiset&&, multiset& __y),
+ swap(multiset&, multiset&& __y)): Add.
+ * include/bits/stl_multimap.h (multimap<>::multimap(multimap&&),
+ multimap<>::operator=(multimap&&)): Add.
+ (multimap<>::swap): Adjust.
+ (swap(multimap&&, multimap& __y),
+ swap(multimap&, multimap&& __y)): Add.
+
+2007-10-04 Paolo Carlini <pcarlini@suse.de>
+
+ Avoid copying some allocator objects.
+ * include/bits/stl_list.h (_List_impl::_List_impl(),
+ _List_base::_List_base(), list<>::list()): Add.
+ * include/bits/stl_vector.h (_Vector_impl::_Vector_impl(),
+ _Vector_base::_Vector_base(), vector<>::vector()): Add.
+ * include/bits/stl_bvector.h (_Bvector_impl::_Bvector_impl(),
+ _Bvector_base::_Bvector_base(), vector<>::vector()): Add.
+ * include/bits/stl_deque.h (_Deque_impl::_Deque_impl(),
+ _Deque_base::_Deque_base(), deque<>::deque()): Add.
+ * include/bits/stl_tree.h (_Rb_tree_impl<>::_Rb_tree_impl(),
+ _Rb_tree_impl<>::_M_initialize): Add.
+ (_Rb_tree<>::_Rb_tree(const _Compare&, const allocator_type&),
+ _Rb_tree(const _Rb_tree&)): Adjust.
+ * include/bits/stl_set.h (set<>::set(),
+ set(_InputIterator, _InputIterator)): Use _M_t default constructor.
+ * include/bits/stl_map.h (map<>::map(), set(_InputIterator,
+ _InputIterator)): Use _M_t default constructor.
+ * include/bits/stl_multiset.h (multiset<>::multiset(),
+ multiset(_InputIterator, _InputIterator)): Use _M_t default
+ constructor.
+ * include/bits/stl_multimap.h (multimap<>::multimap(),
+ multimap(_InputIterator, _InputIterator)): Use _M_t default
+ constructor.
+
+2007-10-03 Chris Jefferson <chris@bubblescope.net>
+ Benjamin Kosnik <bkoz@redhat.com>
+
+ * testsuite/20_util/pair/moveable.cc: New. Merge from
+ libstdcxx_so_7-branch.
+ * testsuite/23_containers/deque/capacity/moveable.cc: Same.
+ * testsuite/23_containers/deque/cons/moveable.cc: Same.
+ * testsuite/23_containers/deque/modifiers/moveable.cc: Same.
+ * testsuite/23_containers/deque/moveable.cc: Same.
+ * testsuite/23_containers/list/moveable.cc: Same.
+ * testsuite/23_containers/map/moveable.cc: Same.
+ * testsuite/23_containers/multimap/moveable.cc: Same.
+ * testsuite/23_containers/multiset/moveable.cc: Same.
+ * testsuite/23_containers/set/moveable.cc: Same.
+ * testsuite/23_containers/vector/cons/moveable.cc: Same.
+ * testsuite/23_containers/vector/modifiers/moveable.cc: Same.
+ * testsuite/23_containers/vector/moveable.cc: Same.
+ * testsuite/23_containers/vector/resize/moveable.cc: Same.
+ * testsuite/25_algorithms/heap/moveable.cc: Same.
+ * testsuite/25_algorithms/nth_element/moveable.cc: Same.
+ * testsuite/25_algorithms/partial_sort/moveable.cc: Same.
+ * testsuite/25_algorithms/partition/moveable.cc: Same.
+ * testsuite/25_algorithms/remove_if/moveable.cc: Same.
+ * testsuite/25_algorithms/remove/moveable.cc: Same.
+ * testsuite/25_algorithms/reverse/moveable.cc: Same.
+ * testsuite/25_algorithms/rotate/moveable.cc: Same.
+ * testsuite/25_algorithms/sort/moveable.cc: Same.
+ * testsuite/25_algorithms/swap_ranges/moveable.cc: Same.
+ * testsuite/25_algorithms/unique/moveable.cc: Same.
+ * testsuite/util/testsuite_rvalref.h: New.
+
+ * testsuite/25_algorithms/equal/equal.cc: Move to...
+ * testsuite/25_algorithms/equal/no_operator_ne.cc: ...this.
+ * testsuite/25_algorithms/heap/heap.cc: Move to...
+ * testsuite/25_algorithms/heap/1.cc: ...this.
+ * testsuite/25_algorithms/lower_bound/lower_bound.cc: Move to...
+ * testsuite/25_algorithms/lower_bound/no_operator_ne.cc: ...this.
+ * testsuite/25_algorithms/partition/partition.cc: Move to...
+ * testsuite/25_algorithms/partition/1.cc: ...this.
+ * testsuite/25_algorithms/stable_partition/1.cc: ... and this.
+
+ * testsuite/25_algorithms/search/1.cc: Update from merge.
+ * testsuite/25_algorithms/search/check_type.cc: Same.
+
+ * testsuite/lib/dg-options.exp (dg-require-rvalref): New.
+ * testsuite/lib/libstdc++.exp (check_v3_target_rvalref): New.
+
+2007-10-03 Richard Sandiford <richard@codesourcery.com>
+
+ * acinclude.m4 (GLIBCXX_ENABLE_C99): Temporarily add
+ -fno-exceptions to CXXFLAGS. Use GCC_TRY_COMPILE_OR_LINK.
+ Make the tests assign results to volatile variables. Use -lm
+ for link tests in GCC_TRY_COMPILE_OR_LINK. Fall back to
+ compile-only tests if -lm is not available.
+ * configure: Regenerate.
+
+2007-10-03 Paolo Carlini <pcarlini@suse.de>
+
+ PR libstdc++/33613
+ * include/debug/functions.h (__check_partitioned): Rename to...
+ (__check_partioned_lower): ... this.
+ (__check_partioned_upper): Add.
+ * include/debug/macros.h (__glibcxx_check_partitioned): Rename to...
+ (__glibcxx_check_partitioned_lower): ... this, adjust.
+ (__glibcxx_check_partitioned_upper): Add.
+ * include/debug/debug.h (__glibcxx_requires_partitioned): Rename to...
+ (__glibcxx_requires_partitioned_lower): ... this, adjust.
+ (__glibcxx_requires_partitioned_upper): Add.
+ * include/bits/stl_algo.h (lower_bound, upper_bound, equal_range,
+ binary search): Use the above.
+ * testsuite/25_algorithms/lower_bound/33613.cc: New.
+ * testsuite/25_algorithms/upper_bound/33613.cc: Likewise.
+
+2007-10-03 Kazu Hirata <kazu@codesourcery.com>
+
+ Revert:
+ 2007-10-02 Richard Sandiford <richard@codesourcery.com>
+ * acinclude.m4 (GLIBCXX_ENABLE_C99): Temporarily add
+ -fno-exceptions to CXXFLAGS. Use GCC_TRY_COMPILE_OR_LINK.
+ Make the tests assign results to volatile variables.
+ * configure: Regenerate.
+
+2007-10-02 Richard Sandiford <richard@codesourcery.com>
+
+ * acinclude.m4 (GLIBCXX_ENABLE_C99): Temporarily add
+ -fno-exceptions to CXXFLAGS. Use GCC_TRY_COMPILE_OR_LINK.
+ Make the tests assign results to volatile variables.
+ * configure: Regenerate.
+
+2007-10-02 Benjamin Kosnik <bkoz@redhat.com>
+
+ * testsuite/25_algorithms/binary_search/2.cc: Split into...
+ * testsuite/25_algorithms/upper_bound/2.cc: ... this.
+ * testsuite/25_algorithms/lower_bound/2.cc: ... this.
+ * testsuite/25_algorithms/equal_range/2.cc: ... and this.
+
+2007-10-02 Chris Jefferson <chris@bubblescope.net>
+
+ * testsuite/25_algorithms/search/1.cc: Merge from
+ libstdcxx_so_7-branch.
+ * testsuite/25_algorithms/search/check_type.cc: Same.
+ * testsuite/25_algorithms/sort/vectorbool.cc: Same.
+
2007-09-30 Jonathan Wakely <jwakely.gcc@gmail.com>
* src/valarray-inst.cc, include/ext/atomicity.h,
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index c26225ee27c..4fb4af3879d 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -763,24 +763,45 @@ AC_DEFUN([GLIBCXX_ENABLE_C99], [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
+ # Use -fno-exceptions so that the C driver can link these tests without
+ # hitting undefined references to personality routines.
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ ac_save_LIBS="$LIBS"
+ ac_save_gcc_no_link="$gcc_no_link"
+
+ if test x$gcc_no_link != xyes; then
+ # Use -fno-exceptions to that the C driver can link these tests without
+ # hitting undefined references to personality routines.
+ CXXFLAGS="$CXXFLAGS -fno-exceptions"
+ AC_CHECK_LIB(m, sin, [
+ LIBS="$LIBS -lm"
+ ], [
+ # Use the default compile-only tests in GCC_TRY_COMPILE_OR_LINK
+ gcc_no_link=yes
+ ])
+ fi
+
# Check for the existence of <math.h> functions used if C99 is enabled.
AC_MSG_CHECKING([for ISO C99 support in <math.h>])
AC_CACHE_VAL(ac_c99_math, [
- AC_TRY_COMPILE([#include <math.h>],
- [fpclassify(0.0);
- isfinite(0.0);
- isinf(0.0);
- isnan(0.0);
- isnormal(0.0);
- signbit(0.0);
- isgreater(0.0,0.0);
- isgreaterequal(0.0,0.0);
- isless(0.0,0.0);
- islessequal(0.0,0.0);
- islessgreater(0.0,0.0);
- islessgreater(0.0,0.0);
- isunordered(0.0,0.0);
- ],[ac_c99_math=yes], [ac_c99_math=no])
+ GCC_TRY_COMPILE_OR_LINK(
+ [#include <math.h>
+ volatile double d1, d2;
+ volatile int i;],
+ [i = fpclassify(d1);
+ i = isfinite(d1);
+ i = isinf(d1);
+ i = isnan(d1);
+ i = isnormal(d1);
+ i = signbit(d1);
+ i = isgreater(d1, d2);
+ i = isgreaterequal(d1, d2);
+ i = isless(d1, d2);
+ i = islessequal(d1, d2);
+ i = islessgreater(d1, d2);
+ i = islessgreater(d1, d2);
+ i = isunordered(d1, d2);
+ ],[ac_c99_math=yes], [ac_c99_math=no])
])
AC_MSG_RESULT($ac_c99_math)
if test x"$ac_c99_math" = x"yes"; then
@@ -798,47 +819,54 @@ AC_DEFUN([GLIBCXX_ENABLE_C99], [
ac_c99_complex=no;
if test x"$ac_has_complex_h" = x"yes"; then
AC_MSG_CHECKING([for ISO C99 support in <complex.h>])
- AC_TRY_COMPILE([#include <complex.h>],
- [typedef __complex__ float float_type; float_type tmpf;
- cabsf(tmpf);
- cargf(tmpf);
- ccosf(tmpf);
- ccoshf(tmpf);
- cexpf(tmpf);
- clogf(tmpf);
- csinf(tmpf);
- csinhf(tmpf);
- csqrtf(tmpf);
- ctanf(tmpf);
- ctanhf(tmpf);
- cpowf(tmpf, tmpf);
- typedef __complex__ double double_type; double_type tmpd;
- cabs(tmpd);
- carg(tmpd);
- ccos(tmpd);
- ccosh(tmpd);
- cexp(tmpd);
- clog(tmpd);
- csin(tmpd);
- csinh(tmpd);
- csqrt(tmpd);
- ctan(tmpd);
- ctanh(tmpd);
- cpow(tmpd, tmpd);
- typedef __complex__ long double ld_type; ld_type tmpld;
- cabsl(tmpld);
- cargl(tmpld);
- ccosl(tmpld);
- ccoshl(tmpld);
- cexpl(tmpld);
- clogl(tmpld);
- csinl(tmpld);
- csinhl(tmpld);
- csqrtl(tmpld);
- ctanl(tmpld);
- ctanhl(tmpld);
- cpowl(tmpld, tmpld);
- ],[ac_c99_complex=yes], [ac_c99_complex=no])
+ GCC_TRY_COMPILE_OR_LINK(
+ [#include <complex.h>
+ typedef __complex__ float float_type;
+ typedef __complex__ double double_type;
+ typedef __complex__ long double ld_type;
+ volatile float_type tmpf;
+ volatile double_type tmpd;
+ volatile ld_type tmpld;
+ volatile float f;
+ volatile double d;
+ volatile long double ld;],
+ [f = cabsf(tmpf);
+ f = cargf(tmpf);
+ tmpf = ccosf(tmpf);
+ tmpf = ccoshf(tmpf);
+ tmpf = cexpf(tmpf);
+ tmpf = clogf(tmpf);
+ tmpf = csinf(tmpf);
+ tmpf = csinhf(tmpf);
+ tmpf = csqrtf(tmpf);
+ tmpf = ctanf(tmpf);
+ tmpf = ctanhf(tmpf);
+ tmpf = cpowf(tmpf, tmpf);
+ d = cabs(tmpd);
+ d = carg(tmpd);
+ tmpd = ccos(tmpd);
+ tmpd = ccosh(tmpd);
+ tmpd = cexp(tmpd);
+ tmpd = clog(tmpd);
+ tmpd = csin(tmpd);
+ tmpd = csinh(tmpd);
+ tmpd = csqrt(tmpd);
+ tmpd = ctan(tmpd);
+ tmpd = ctanh(tmpd);
+ tmpd = cpow(tmpd, tmpd);
+ ld = cabsl(tmpld);
+ ld = cargl(tmpld);
+ tmpld = ccosl(tmpld);
+ tmpld = ccoshl(tmpld);
+ tmpld = cexpl(tmpld);
+ tmpld = clogl(tmpld);
+ tmpld = csinl(tmpld);
+ tmpld = csinhl(tmpld);
+ tmpld = csqrtl(tmpld);
+ tmpld = ctanl(tmpld);
+ tmpld = ctanhl(tmpld);
+ tmpld = cpowl(tmpld, tmpld);
+ ],[ac_c99_complex=yes], [ac_c99_complex=no])
fi
AC_MSG_RESULT($ac_c99_complex)
if test x"$ac_c99_complex" = x"yes"; then
@@ -851,35 +879,43 @@ AC_DEFUN([GLIBCXX_ENABLE_C99], [
# Check for the existence in <stdio.h> of vscanf, et. al.
AC_MSG_CHECKING([for ISO C99 support in <stdio.h>])
AC_CACHE_VAL(ac_c99_stdio, [
- AC_TRY_COMPILE([#include <stdio.h>
- #include <stdarg.h>
- void foo(char* fmt, ...)
- {
- va_list args; va_start(args, fmt);
- vfscanf(stderr, "%i", args);
- vscanf("%i", args);
- vsnprintf(fmt, 0, "%i", args);
- vsscanf(fmt, "%i", args);
- }],
- [snprintf("12", 0, "%i");],
- [ac_c99_stdio=yes], [ac_c99_stdio=no])
+ GCC_TRY_COMPILE_OR_LINK(
+ [#include <stdio.h>
+ #include <stdarg.h>
+ void foo(char* fmt, ...)
+ {
+ va_list args; va_start(args, fmt);
+ vfscanf(stderr, "%i", args);
+ vscanf("%i", args);
+ vsnprintf(fmt, 0, "%i", args);
+ vsscanf(fmt, "%i", args);
+ }],
+ [snprintf("12", 0, "%i");],
+ [ac_c99_stdio=yes], [ac_c99_stdio=no])
])
AC_MSG_RESULT($ac_c99_stdio)
# Check for the existence in <stdlib.h> of lldiv_t, et. al.
AC_MSG_CHECKING([for ISO C99 support in <stdlib.h>])
AC_CACHE_VAL(ac_c99_stdlib, [
- AC_TRY_COMPILE([#include <stdlib.h>],
- [char* tmp;
- strtof("gnu", &tmp);
- strtold("gnu", &tmp);
- strtoll("gnu", &tmp, 10);
- strtoull("gnu", &tmp, 10);
- llabs(10);
- lldiv(10,1);
- atoll("10");
- _Exit(0);
- lldiv_t mydivt;],[ac_c99_stdlib=yes], [ac_c99_stdlib=no])
+ GCC_TRY_COMPILE_OR_LINK(
+ [#include <stdlib.h>
+ volatile float f;
+ volatile long double ld;
+ volatile unsigned long long ll;
+ lldiv_t mydivt;],
+ [char* tmp;
+ f = strtof("gnu", &tmp);
+ ld = strtold("gnu", &tmp);
+ ll = strtoll("gnu", &tmp, 10);
+ ll = strtoull("gnu", &tmp, 10);
+ ll = llabs(10);
+ mydivt = lldiv(10,1);
+ ll = mydivt.quot;
+ ll = mydivt.rem;
+ ll = atoll("10");
+ _Exit(0);
+ ],[ac_c99_stdlib=yes], [ac_c99_stdlib=no])
])
AC_MSG_RESULT($ac_c99_stdlib)
@@ -940,6 +976,9 @@ AC_DEFUN([GLIBCXX_ENABLE_C99], [
<complex.h>, <stdio.h>, and <stdlib.h> can be used or exposed.])
fi
+ gcc_no_link="$ac_save_gcc_no_link"
+ LIBS="$ac_save_LIBS"
+ CXXFLAGS="$ac_save_CXXFLAGS"
AC_LANG_RESTORE
fi
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index e42e1bbaf4f..d224ffc784e 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -15436,6 +15436,98 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+ # Use -fno-exceptions so that the C driver can link these tests without
+ # hitting undefined references to personality routines.
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ ac_save_LIBS="$LIBS"
+ ac_save_gcc_no_link="$gcc_no_link"
+
+ if test x$gcc_no_link != xyes; then
+ # Use -fno-exceptions to that the C driver can link these tests without
+ # hitting undefined references to personality routines.
+ CXXFLAGS="$CXXFLAGS -fno-exceptions"
+ echo "$as_me:$LINENO: checking for sin in -lm" >&5
+echo $ECHO_N "checking for sin in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_sin+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char sin ();
+int
+main ()
+{
+sin ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_m_sin=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_sin=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_sin" >&5
+echo "${ECHO_T}$ac_cv_lib_m_sin" >&6
+if test $ac_cv_lib_m_sin = yes; then
+
+ LIBS="$LIBS -lm"
+
+else
+
+ # Use the default compile-only tests in GCC_TRY_COMPILE_OR_LINK
+ gcc_no_link=yes
+
+fi
+
+ fi
+
# Check for the existence of <math.h> functions used if C99 is enabled.
echo "$as_me:$LINENO: checking for ISO C99 support in <math.h>" >&5
echo $ECHO_N "checking for ISO C99 support in <math.h>... $ECHO_C" >&6
@@ -15443,6 +15535,7 @@ echo $ECHO_N "checking for ISO C99 support in <math.h>... $ECHO_C" >&6
echo $ECHO_N "(cached) $ECHO_C" >&6
else
+ if test x$gcc_no_link = xyes; then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
@@ -15450,22 +15543,24 @@ cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <math.h>
+ volatile double d1, d2;
+ volatile int i;
int
main ()
{
-fpclassify(0.0);
- isfinite(0.0);
- isinf(0.0);
- isnan(0.0);
- isnormal(0.0);
- signbit(0.0);
- isgreater(0.0,0.0);
- isgreaterequal(0.0,0.0);
- isless(0.0,0.0);
- islessequal(0.0,0.0);
- islessgreater(0.0,0.0);
- islessgreater(0.0,0.0);
- isunordered(0.0,0.0);
+i = fpclassify(d1);
+ i = isfinite(d1);
+ i = isinf(d1);
+ i = isnan(d1);
+ i = isnormal(d1);
+ i = signbit(d1);
+ i = isgreater(d1, d2);
+ i = isgreaterequal(d1, d2);
+ i = isless(d1, d2);
+ i = islessequal(d1, d2);
+ i = islessgreater(d1, d2);
+ i = islessgreater(d1, d2);
+ i = isunordered(d1, d2);
;
return 0;
@@ -15501,6 +15596,74 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_c99_math=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ volatile double d1, d2;
+ volatile int i;
+int
+main ()
+{
+i = fpclassify(d1);
+ i = isfinite(d1);
+ i = isinf(d1);
+ i = isnan(d1);
+ i = isnormal(d1);
+ i = signbit(d1);
+ i = isgreater(d1, d2);
+ i = isgreaterequal(d1, d2);
+ i = isless(d1, d2);
+ i = islessequal(d1, d2);
+ i = islessgreater(d1, d2);
+ i = islessgreater(d1, d2);
+ i = isunordered(d1, d2);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_c99_math=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_c99_math=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
fi
@@ -15826,55 +15989,62 @@ done
if test x"$ac_has_complex_h" = x"yes"; then
echo "$as_me:$LINENO: checking for ISO C99 support in <complex.h>" >&5
echo $ECHO_N "checking for ISO C99 support in <complex.h>... $ECHO_C" >&6
- cat >conftest.$ac_ext <<_ACEOF
+ if test x$gcc_no_link = xyes; then
+ cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <complex.h>
+ typedef __complex__ float float_type;
+ typedef __complex__ double double_type;
+ typedef __complex__ long double ld_type;
+ volatile float_type tmpf;
+ volatile double_type tmpd;
+ volatile ld_type tmpld;
+ volatile float f;
+ volatile double d;
+ volatile long double ld;
int
main ()
{
-typedef __complex__ float float_type; float_type tmpf;
- cabsf(tmpf);
- cargf(tmpf);
- ccosf(tmpf);
- ccoshf(tmpf);
- cexpf(tmpf);
- clogf(tmpf);
- csinf(tmpf);
- csinhf(tmpf);
- csqrtf(tmpf);
- ctanf(tmpf);
- ctanhf(tmpf);
- cpowf(tmpf, tmpf);
- typedef __complex__ double double_type; double_type tmpd;
- cabs(tmpd);
- carg(tmpd);
- ccos(tmpd);
- ccosh(tmpd);
- cexp(tmpd);
- clog(tmpd);
- csin(tmpd);
- csinh(tmpd);
- csqrt(tmpd);
- ctan(tmpd);
- ctanh(tmpd);
- cpow(tmpd, tmpd);
- typedef __complex__ long double ld_type; ld_type tmpld;
- cabsl(tmpld);
- cargl(tmpld);
- ccosl(tmpld);
- ccoshl(tmpld);
- cexpl(tmpld);
- clogl(tmpld);
- csinl(tmpld);
- csinhl(tmpld);
- csqrtl(tmpld);
- ctanl(tmpld);
- ctanhl(tmpld);
- cpowl(tmpld, tmpld);
+f = cabsf(tmpf);
+ f = cargf(tmpf);
+ tmpf = ccosf(tmpf);
+ tmpf = ccoshf(tmpf);
+ tmpf = cexpf(tmpf);
+ tmpf = clogf(tmpf);
+ tmpf = csinf(tmpf);
+ tmpf = csinhf(tmpf);
+ tmpf = csqrtf(tmpf);
+ tmpf = ctanf(tmpf);
+ tmpf = ctanhf(tmpf);
+ tmpf = cpowf(tmpf, tmpf);
+ d = cabs(tmpd);
+ d = carg(tmpd);
+ tmpd = ccos(tmpd);
+ tmpd = ccosh(tmpd);
+ tmpd = cexp(tmpd);
+ tmpd = clog(tmpd);
+ tmpd = csin(tmpd);
+ tmpd = csinh(tmpd);
+ tmpd = csqrt(tmpd);
+ tmpd = ctan(tmpd);
+ tmpd = ctanh(tmpd);
+ tmpd = cpow(tmpd, tmpd);
+ ld = cabsl(tmpld);
+ ld = cargl(tmpld);
+ tmpld = ccosl(tmpld);
+ tmpld = ccoshl(tmpld);
+ tmpld = cexpl(tmpld);
+ tmpld = clogl(tmpld);
+ tmpld = csinl(tmpld);
+ tmpld = csinhl(tmpld);
+ tmpld = csqrtl(tmpld);
+ tmpld = ctanl(tmpld);
+ tmpld = ctanhl(tmpld);
+ tmpld = cpowl(tmpld, tmpld);
;
return 0;
@@ -15910,6 +16080,104 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_c99_complex=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <complex.h>
+ typedef __complex__ float float_type;
+ typedef __complex__ double double_type;
+ typedef __complex__ long double ld_type;
+ volatile float_type tmpf;
+ volatile double_type tmpd;
+ volatile ld_type tmpld;
+ volatile float f;
+ volatile double d;
+ volatile long double ld;
+int
+main ()
+{
+f = cabsf(tmpf);
+ f = cargf(tmpf);
+ tmpf = ccosf(tmpf);
+ tmpf = ccoshf(tmpf);
+ tmpf = cexpf(tmpf);
+ tmpf = clogf(tmpf);
+ tmpf = csinf(tmpf);
+ tmpf = csinhf(tmpf);
+ tmpf = csqrtf(tmpf);
+ tmpf = ctanf(tmpf);
+ tmpf = ctanhf(tmpf);
+ tmpf = cpowf(tmpf, tmpf);
+ d = cabs(tmpd);
+ d = carg(tmpd);
+ tmpd = ccos(tmpd);
+ tmpd = ccosh(tmpd);
+ tmpd = cexp(tmpd);
+ tmpd = clog(tmpd);
+ tmpd = csin(tmpd);
+ tmpd = csinh(tmpd);
+ tmpd = csqrt(tmpd);
+ tmpd = ctan(tmpd);
+ tmpd = ctanh(tmpd);
+ tmpd = cpow(tmpd, tmpd);
+ ld = cabsl(tmpld);
+ ld = cargl(tmpld);
+ tmpld = ccosl(tmpld);
+ tmpld = ccoshl(tmpld);
+ tmpld = cexpl(tmpld);
+ tmpld = clogl(tmpld);
+ tmpld = csinl(tmpld);
+ tmpld = csinhl(tmpld);
+ tmpld = csqrtl(tmpld);
+ tmpld = ctanl(tmpld);
+ tmpld = ctanhl(tmpld);
+ tmpld = cpowl(tmpld, tmpld);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_c99_complex=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_c99_complex=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
fi
echo "$as_me:$LINENO: result: $ac_c99_complex" >&5
echo "${ECHO_T}$ac_c99_complex" >&6
@@ -15928,6 +16196,7 @@ echo $ECHO_N "checking for ISO C99 support in <stdio.h>... $ECHO_C" >&6
echo $ECHO_N "(cached) $ECHO_C" >&6
else
+ if test x$gcc_no_link = xyes; then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
@@ -15935,15 +16204,15 @@ cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <stdio.h>
- #include <stdarg.h>
- void foo(char* fmt, ...)
- {
- va_list args; va_start(args, fmt);
- vfscanf(stderr, "%i", args);
- vscanf("%i", args);
- vsnprintf(fmt, 0, "%i", args);
- vsscanf(fmt, "%i", args);
- }
+ #include <stdarg.h>
+ void foo(char* fmt, ...)
+ {
+ va_list args; va_start(args, fmt);
+ vfscanf(stderr, "%i", args);
+ vscanf("%i", args);
+ vsnprintf(fmt, 0, "%i", args);
+ vsscanf(fmt, "%i", args);
+ }
int
main ()
{
@@ -15982,6 +16251,68 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_c99_stdio=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdio.h>
+ #include <stdarg.h>
+ void foo(char* fmt, ...)
+ {
+ va_list args; va_start(args, fmt);
+ vfscanf(stderr, "%i", args);
+ vscanf("%i", args);
+ vsnprintf(fmt, 0, "%i", args);
+ vsscanf(fmt, "%i", args);
+ }
+int
+main ()
+{
+snprintf("12", 0, "%i");
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_c99_stdio=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_c99_stdio=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
fi
@@ -15995,6 +16326,7 @@ echo $ECHO_N "checking for ISO C99 support in <stdlib.h>... $ECHO_C" >&6
echo $ECHO_N "(cached) $ECHO_C" >&6
else
+ if test x$gcc_no_link = xyes; then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
@@ -16002,19 +16334,25 @@ cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <stdlib.h>
+ volatile float f;
+ volatile long double ld;
+ volatile unsigned long long ll;
+ lldiv_t mydivt;
int
main ()
{
char* tmp;
- strtof("gnu", &tmp);
- strtold("gnu", &tmp);
- strtoll("gnu", &tmp, 10);
- strtoull("gnu", &tmp, 10);
- llabs(10);
- lldiv(10,1);
- atoll("10");
- _Exit(0);
- lldiv_t mydivt;
+ f = strtof("gnu", &tmp);
+ ld = strtold("gnu", &tmp);
+ ll = strtoll("gnu", &tmp, 10);
+ ll = strtoull("gnu", &tmp, 10);
+ ll = llabs(10);
+ mydivt = lldiv(10,1);
+ ll = mydivt.quot;
+ ll = mydivt.rem;
+ ll = atoll("10");
+ _Exit(0);
+
;
return 0;
}
@@ -16049,6 +16387,74 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_c99_stdlib=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+ volatile float f;
+ volatile long double ld;
+ volatile unsigned long long ll;
+ lldiv_t mydivt;
+int
+main ()
+{
+char* tmp;
+ f = strtof("gnu", &tmp);
+ ld = strtold("gnu", &tmp);
+ ll = strtoll("gnu", &tmp, 10);
+ ll = strtoull("gnu", &tmp, 10);
+ ll = llabs(10);
+ mydivt = lldiv(10,1);
+ ll = mydivt.quot;
+ ll = mydivt.rem;
+ ll = atoll("10");
+ _Exit(0);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_c99_stdlib=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_c99_stdlib=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
fi
@@ -16386,6 +16792,9 @@ _ACEOF
fi
+ gcc_no_link="$ac_save_gcc_no_link"
+ LIBS="$ac_save_LIBS"
+ CXXFLAGS="$ac_save_CXXFLAGS"
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -17305,7 +17714,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
# Fake what AC_TRY_COMPILE does. XXX Look at redoing this new-style.
cat > conftest.$ac_ext << EOF
-#line 17308 "configure"
+#line 17717 "configure"
int main()
{
// NB: _Atomic_word not necessarily int.
diff --git a/libstdc++-v3/docs/html/parallel_mode.html b/libstdc++-v3/docs/html/parallel_mode.html
index 74db8ca3771..0ada39b6de6 100644
--- a/libstdc++-v3/docs/html/parallel_mode.html
+++ b/libstdc++-v3/docs/html/parallel_mode.html
@@ -35,7 +35,7 @@ implementation of many algorithms the C++ Standard Library.
<p>
Several of the standard algorithms, for instance
-<code>std::search</code>, are made parallel using OpenMP
+<code>std::sort</code>, are made parallel using OpenMP
annotations. These parallel mode constructs and can be invoked by
explicit source declaration or by compiling existing sources with a
specific compiler flag.
@@ -43,7 +43,7 @@ specific compiler flag.
<h3 class="left"><a name="parallel">The libstdc++ parallel mode</a></h3>
-<p>The libstdc++ parallel mode performs parallization of algorithms,
+<p>The libstdc++ parallel mode performs parallelization of algorithms,
function objects, classes, and functions in the C++ Standard.</p>
<h4 class="left">Using the libstdc++ parallel mode</h4>
@@ -53,7 +53,7 @@ function objects, classes, and functions in the C++ Standard.</p>
will link in <code>libgomp</code>, the GNU OpenMP <a
href="http://gcc.gnu.org/onlinedocs/libgomp">implementation</a>,
whose presence is mandatory. In addition, hardware capable of atomic
- operations is de rigueur. Actually activating these atomic
+ operations is mandatory. Actually activating these atomic
operations may require explicit compiler flags on some targets
(like sparc and x86), such as <code>-march=i686</code>,
<code>-march=native</code> or <code>-mcpu=v9</code>.
@@ -113,6 +113,13 @@ function objects, classes, and functions in the C++ Standard.</p>
<li><code>std::unique_copy</code></li>
</ul>
+<p>The following library components in the includes
+<code>&lt;set&gt;</code> and <code>&lt;map&gt;</code> are included in the parallel mode:</p>
+<ul>
+ <li><code>std::(multi_)map/set&lt;T&gt;::(multi_)map/set(Iterator begin, Iterator end)</code> (bulk construction)</li>
+ <li><code>std::(multi_)map/set&lt;T&gt;::insert(Iterator begin, Iterator end)</code> (bulk insertion)</li>
+</ul>
+
<h4 class="left">Using the parallel algorithms without parallel mode</h4>
@@ -380,34 +387,151 @@ function objects, classes, and functions in the C++ Standard.</p>
<h4 class="left">Parallel mode semantics</h4>
-<p> Something about exception safety, interaction with threads,
-etc. Goal is to have the usual constraints of the STL with respect to
-exception safety and threads, but add in support for parallel
-computing.</p>
-<p> Something about compile-time settings and configuration, ie using
-<code>__gnu_parallel::Settings</code>. XXX Up in the air.</p>
+<p> The parallel mode STL algorithms are currently not exception-safe,
+i. e. user-defined functors must not throw exceptions.
+</p>
-<h4 class="left">Interface basics and relevant namespaces</h4>
+<p> Since the current GCC OpenMP implementation does not support
+OpenMP parallel regions in concurrent threads,
+it is not possible to call parallel STL algorithm in
+concurrent threads, either.
+It might work with other compilers, though.</p>
-<p> Two namespaces contain the parallel mode:
-<code>std::__parallel</code> and <code>__gnu_parallel</code>.
+
+<h4 class="left">Configuration and Tuning</h4>
+
+<p> Some algorithm variants can be enabled/disabled/selected at compile-time.
+See <a href="latest-doxygen/compiletime__settings_8h.html">
+<code>&lt;compiletime_settings.h&gt;</code></a> and
+See <a href="latest-doxygen/compiletime__settings_8h.html">
+<code>&lt;features.h&gt;</code></a> for details.
+</p>
+
+<p>
+To specify the number of threads to be used for an algorithm,
+use <code>omp_set_num_threads</code>.
+To force a function to execute sequentially,
+even though parallelism is switched on in general,
+add <code>__gnu_parallel::sequential_tag()</code>
+to the end of the argument list.
+</p>
+
+<p>
+Parallelism always incurs some overhead. Thus, it is not
+helpful to parallelize operations on very small sets of data.
+There are measures to avoid parallelizing stuff that is not worth it.
+For each algorithm, a minimum problem size can be stated,
+usually using the variable
+<code>__gnu_parallel::Settings::[algorithm]_minimal_n</code>.
+Please see <a href="latest-doxygen/settings_8h.html">
+<code>&lt;settings.h&gt;</code><a> for details.</p>
+
+
+
+<h4 class="left">Interface basics and general design</h4>
+
+<p>All parallel algorithms are intended to have signatures that are
+equivalent to the ISO C++ algorithms replaced. For instance, the
+<code>std::adjacent_find</code> function is declared as:
+
+<pre>
+namespace std
+{
+ template&lt;typename _FIter&gt;
+ _FIter
+ adjacent_find(_FIter, _FIter);
+}
+</pre>
+
+Which means that there should be something equivalent for the parallel
+version. Indeed, this is the case:
+
+<pre>
+namespace std
+{
+ namespace __parallel
+ {
+ template&lt;typename _FIter&gt;
+ _FIter
+ adjacent_find(_FIter, _FIter);
+
+ ...
+ }
+}
+</pre>
+
+<p>But.... why the elipses?
+</p>
+
+<p> The elipses in the example above represent additional overloads
+required for the parallel version of the function. These additional
+overloads are used to dispatch calls from the ISO C++ function
+signature to the appropriate parallel function (or sequential
+function, if no parallel functions are deemed worthy), based on either
+compile-time or run-time conditions.
+</p>
+
+<p> Compile-time conditions are referred to as "embarrassingly
+parallel," and are denoted with the appropriate dispatch object, ie
+one of <code>__gnu_parallel::sequential_tag</code>,
+<code>__gnu_parallel::parallel_tag</code>,
+<code>__gnu_parallel::balanced_tag</code>,
+<code>__gnu_parallel::unbalanced_tag</code>,
+<code>__gnu_parallel::omp_loop_tag</code>, or
+<code>__gnu_parallel::omp_loop_static_tag</code>.
+</p>
+
+<p> Run-time conditions depend on the hardware being used, the number
+of threads available, etc., and are denoted by the use of the enum
+<code>__gnu_parallel::parallelism</code>. Values of this enum include
+<code>__gnu_parallel::sequential</code>,
+<code>__gnu_parallel::parallel_unbalanced</code>,
+<code>__gnu_parallel::parallel_balanced</code>,
+<code>__gnu_parallel::parallel_omp_loop</code>,
+<code>__gnu_parallel::parallel_omp_loop_static</code>, or
+<code>__gnu_parallel::parallel_taskqueue</code>.
</p>
+<p> Putting all this together, the general view of overloads for the
+parallel algorithms look like this:
+<p>
+<ul>
+ <li>ISO C++ signature</li>
+ <li>ISO C++ signature + sequential_tag argument</li>
+ <li>ISO C++ signature + parallelism argument</li>
+</ul>
+
+<p> Please note that the implementation may use additional functions
+(designated with the <code>_switch</code> suffix) to dispatch from the
+ISO C++ signature to the correct parallel version. Also, some of the
+algorithms do not have support for run-time conditions, so the last
+overload is therefore missing.
+</p>
+
+
+<h4 class="left">Relevant namespaces</h4>
+
<p> One namespace contain versions of code that are explicitly sequential:
<code>__gnu_serial</code>.
</p>
-<p> Parallel implementations of the sequential standard components are
-defined in <code>namespace std::__parallel</code>. For instance,
-<code>std::transform</code> from &lt;algorithm&gt; has a parallel
-counterpart in <code>std::__parallel::transform</code> from
+<p> Two namespaces contain the parallel mode:
+<code>std::__parallel</code> and <code>__gnu_parallel</code>.
+</p>
+
+<p> Parallel implementations of standard components, including
+template helpers to select parallelism, are defined in <code>namespace
+std::__parallel</code>. For instance, <code>std::transform</code> from
+&lt;algorithm&gt; has a parallel counterpart in
+<code>std::__parallel::transform</code> from
&lt;parallel/algorithm&gt;. In addition, these parallel
-implementatations are injected into <code>namespace
-__gnu_parallel</code> with using declarations.
+implementations are injected into <code>namespace
+__gnu_parallel</code> with using declarations.
</p>
-<p> Support and infrastructure is in <code>namespace __gnu_parallel</code>.
+<p> Support and general infrastructure is in <code>namespace
+__gnu_parallel</code>.
</p>
<p> More information, and an organized index of types and functions
@@ -443,6 +567,16 @@ testsuite's Makefile.</p>
</p>
+<h4 class="left">References / Further Reading</h4>
+
+<p>
+Johannes Singler, Peter Sanders, Felix Putze. The Multi-Core Standard Template Library. Euro-Par 2007: Parallel Processing. (LNCS 4641)
+</p>
+
+<p>
+Leonor Frias, Johannes Singler: Parallelization of Bulk Operations for STL Dictionaries. Workshop on Highly Parallel Processing on a Chip (HPPC) 2007. (LNCS)
+</p>
+
<!-- ####################################################### -->
<hr />
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 017ffcb3901..2e2609c23d2 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -120,6 +120,7 @@ bits_headers = \
${bits_srcdir}/stl_list.h \
${bits_srcdir}/stl_map.h \
${bits_srcdir}/stl_auto_ptr.h \
+ ${bits_srcdir}/stl_move.h \
${bits_srcdir}/stl_multimap.h \
${bits_srcdir}/stl_multiset.h \
${bits_srcdir}/stl_numeric.h \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 0558c6658e9..d1db21d5509 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -369,6 +369,7 @@ bits_headers = \
${bits_srcdir}/stl_list.h \
${bits_srcdir}/stl_map.h \
${bits_srcdir}/stl_auto_ptr.h \
+ ${bits_srcdir}/stl_move.h \
${bits_srcdir}/stl_multimap.h \
${bits_srcdir}/stl_multiset.h \
${bits_srcdir}/stl_numeric.h \
diff --git a/libstdc++-v3/include/bits/algorithmfwd.h b/libstdc++-v3/include/bits/algorithmfwd.h
index 0b61864759c..0e304733121 100644
--- a/libstdc++-v3/include/bits/algorithmfwd.h
+++ b/libstdc++-v3/include/bits/algorithmfwd.h
@@ -148,7 +148,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
fill_n(_OIter, _Size, const _Tp&);
// find
- // find_end
+
+ template<typename _FIter1, typename _FIter2>
+ _FIter1
+ find_end(_FIter1, _FIter1, _FIter2, _FIter2);
+
+ template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
+ _FIter1
+ find_end(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
+
// find_first_of
// find_if
// for_each
@@ -391,14 +399,6 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_P)
template<typename _FIter1, typename _FIter2>
_FIter1
- find_end(_FIter1, _FIter1, _FIter2, _FIter2);
-
- template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
- _FIter1
- find_end(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
-
- template<typename _FIter1, typename _FIter2>
- _FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index 561609d6037..4f5bc2764b2 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -123,7 +123,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp)
{
// concept requirements
- __glibcxx_function_requires(_BinaryFunctionConcept<_Compare,bool,_Tp,_Tp>)
+ __glibcxx_function_requires(_BinaryFunctionConcept<_Compare, bool,
+ _Tp, _Tp>)
if (__comp(__a, __b))
if (__comp(__b, __c))
return __b;
@@ -515,7 +516,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
while (1)
{
_ForwardIterator1 __new_result
- = _GLIBCXX_STD_P::search(__first1, __last1, __first2, __last2, __comp);
+ = _GLIBCXX_STD_P::search(__first1, __last1, __first2,
+ __last2, __comp);
if (__new_result == __last1)
return __result;
else
@@ -548,7 +550,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_RevIterator1 __rlast1(__first1);
_RevIterator2 __rlast2(__first2);
- _RevIterator1 __rresult = _GLIBCXX_STD_P::search(_RevIterator1(__last1), __rlast1, _RevIterator2(__last2), __rlast2);
+ _RevIterator1 __rresult = _GLIBCXX_STD_P::search(_RevIterator1(__last1),
+ __rlast1,
+ _RevIterator2(__last2),
+ __rlast2);
if (__rresult == __rlast1)
return __last1;
@@ -788,9 +793,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__glibcxx_requires_valid_range(__first, __last);
__first = _GLIBCXX_STD_P::find(__first, __last, __value);
- _ForwardIterator __i = __first;
- return __first == __last ? __first
- : std::remove_copy(++__i, __last, __first, __value);
+ if(__first == __last)
+ return __first;
+ _ForwardIterator __result = __first;
+ ++__first;
+ for(; __first != __last; ++__first)
+ if(!(*__first == __value))
+ {
+ *__result = _GLIBCXX_MOVE(*__first);
+ ++__result;
+ }
+ return __result;
}
/**
@@ -822,10 +835,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__glibcxx_requires_valid_range(__first, __last);
__first = _GLIBCXX_STD_P::find_if(__first, __last, __pred);
- _ForwardIterator __i = __first;
- return __first == __last ? __first
- : std::remove_copy_if(++__i, __last,
- __first, __pred);
+ if(__first == __last)
+ return __first;
+ _ForwardIterator __result = __first;
+ ++__first;
+ for(; __first != __last; ++__first)
+ if(!__pred(*__first))
+ {
+ *__result = _GLIBCXX_MOVE(*__first);
+ ++__result;
+ }
+ return __result;
}
/**
@@ -862,7 +882,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
++__first;
while (++__first != __last)
if (!(*__dest == *__first))
- *++__dest = *__first;
+ *++__dest = _GLIBCXX_MOVE(*__first);
return ++__dest;
}
@@ -903,7 +923,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
++__first;
while (++__first != __last)
if (!bool(__binary_pred(*__dest, *__first)))
- *++__dest = *__first;
+ *++__dest = _GLIBCXX_MOVE(*__first);
return ++__dest;
}
@@ -1207,7 +1227,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_ForwardIterator __first2 = __middle;
do
{
- swap(*__first, *__first2);
+ std::iter_swap(__first, __first2);
++__first;
++__first2;
if (__first == __middle)
@@ -1219,7 +1239,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
while (__first2 != __last)
{
- swap(*__first, *__first2);
+ std::iter_swap(__first, __first2);
++__first;
++__first2;
if (__first == __middle)
@@ -1253,7 +1273,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
while (__first != __middle && __middle != __last)
{
- swap(*__first, *--__last);
+ std::iter_swap(__first, --__last);
++__first;
}
@@ -1301,7 +1321,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
for (_Distance __i = 0; __i < __d; __i++)
{
- _ValueType __tmp = *__first;
+ _ValueType __tmp = _GLIBCXX_MOVE(*__first);
_RandomAccessIterator __p = __first;
if (__k < __l)
@@ -1310,11 +1330,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
if (__p > __first + __l)
{
- *__p = *(__p - __l);
+ *__p = _GLIBCXX_MOVE(*(__p - __l));
__p -= __l;
}
- *__p = *(__p + __k);
+ *__p = _GLIBCXX_MOVE(*(__p + __k));
__p += __k;
}
}
@@ -1324,15 +1344,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
if (__p < __last - __k)
{
- *__p = *(__p + __k);
+ *__p = _GLIBCXX_MOVE(*(__p + __k));
__p += __k;
}
- *__p = * (__p - __l);
+ *__p = _GLIBCXX_MOVE(*(__p - __l));
__p -= __l;
}
}
- *__p = __tmp;
+ *__p = _GLIBCXX_MOVE(__tmp);
++__first;
}
}
@@ -1412,8 +1432,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
template<typename _ForwardIterator, typename _Predicate>
_ForwardIterator
__partition(_ForwardIterator __first, _ForwardIterator __last,
- _Predicate __pred,
- forward_iterator_tag)
+ _Predicate __pred, forward_iterator_tag)
{
if (__first == __last)
return __first;
@@ -1427,7 +1446,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
while (++__next != __last)
if (__pred(*__next))
{
- swap(*__first, *__next);
+ std::iter_swap(__first, __next);
++__first;
}
@@ -1442,8 +1461,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
template<typename _BidirectionalIterator, typename _Predicate>
_BidirectionalIterator
__partition(_BidirectionalIterator __first, _BidirectionalIterator __last,
- _Predicate __pred,
- bidirectional_iterator_tag)
+ _Predicate __pred, bidirectional_iterator_tag)
{
while (true)
{
@@ -2186,7 +2204,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>)
- __glibcxx_requires_partitioned(__first, __last, __val);
+ __glibcxx_requires_partitioned_lower(__first, __last, __val);
_DistanceType __len = std::distance(__first, __last);
_DistanceType __half;
@@ -2237,7 +2255,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
_ValueType, _Tp>)
- __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp);
+ __glibcxx_requires_partitioned_lower_pred(__first, __last,
+ __val, __comp);
_DistanceType __len = std::distance(__first, __last);
_DistanceType __half;
@@ -2283,7 +2302,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>)
- __glibcxx_requires_partitioned(__first, __last, __val);
+ __glibcxx_requires_partitioned_upper(__first, __last, __val);
_DistanceType __len = std::distance(__first, __last);
_DistanceType __half;
@@ -2334,7 +2353,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
_Tp, _ValueType>)
- __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp);
+ __glibcxx_requires_partitioned_upper_pred(__first, __last,
+ __val, __comp);
_DistanceType __len = std::distance(__first, __last);
_DistanceType __half;
@@ -2387,7 +2407,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_LessThanOpConcept<_ValueType, _Tp>)
__glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>)
- __glibcxx_requires_partitioned(__first, __last, __val);
+ __glibcxx_requires_partitioned_lower(__first, __last, __val);
+ __glibcxx_requires_partitioned_upper(__first, __last, __val);
_DistanceType __len = std::distance(__first, __last);
_DistanceType __half;
@@ -2451,7 +2472,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_ValueType, _Tp>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
_Tp, _ValueType>)
- __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp);
+ __glibcxx_requires_partitioned_lower_pred(__first, __last,
+ __val, __comp);
+ __glibcxx_requires_partitioned_upper_pred(__first, __last,
+ __val, __comp);
_DistanceType __len = std::distance(__first, __last);
_DistanceType __half;
@@ -2503,7 +2527,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// concept requirements
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_LessThanOpConcept<_Tp, _ValueType>)
- __glibcxx_requires_partitioned(__first, __last, __val);
+ __glibcxx_requires_partitioned_lower(__first, __last, __val);
+ __glibcxx_requires_partitioned_upper(__first, __last, __val);
_ForwardIterator __i = std::lower_bound(__first, __last, __val);
return __i != __last && !(__val < *__i);
@@ -2536,7 +2561,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
__glibcxx_function_requires(_BinaryPredicateConcept<_Compare,
_Tp, _ValueType>)
- __glibcxx_requires_partitioned_pred(__first, __last, __val, __comp);
+ __glibcxx_requires_partitioned_lower_pred(__first, __last,
+ __val, __comp);
+ __glibcxx_requires_partitioned_upper_pred(__first, __last,
+ __val, __comp);
_ForwardIterator __i = std::lower_bound(__first, __last, __val, __comp);
return __i != __last && !bool(__comp(__val, *__i));
@@ -2737,7 +2765,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
if (__len1 <= __len2 && __len1 <= __buffer_size)
{
_Pointer __buffer_end = std::copy(__first, __middle, __buffer);
- _GLIBCXX_STD_P::merge(__buffer, __buffer_end, __middle, __last, __first, __comp);
+ _GLIBCXX_STD_P::merge(__buffer, __buffer_end, __middle, __last,
+ __first, __comp);
}
else if (__len2 <= __buffer_size)
{
@@ -3048,7 +3077,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
std::__insertion_sort(__first, __last);
}
- template<typename _RandomAccessIterator, typename _Distance, typename _Compare>
+ template<typename _RandomAccessIterator, typename _Distance,
+ typename _Compare>
void
__chunk_insertion_sort(_RandomAccessIterator __first,
_RandomAccessIterator __last,
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index c6648b43b9d..64b13a5c2fb 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -73,6 +73,7 @@
#include <bits/stl_iterator.h>
#include <bits/concept_check.h>
#include <debug/debug.h>
+#include <bits/stl_move.h> // For _GLIBCXX_MOVE
_GLIBCXX_BEGIN_NAMESPACE(std)
@@ -92,9 +93,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// concept requirements
__glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
- _Tp __tmp = __a;
- __a = __b;
- __b = __tmp;
+ _Tp __tmp = _GLIBCXX_MOVE(__a);
+ __a = _GLIBCXX_MOVE(__b);
+ __b = _GLIBCXX_MOVE(__tmp);
}
// See http://gcc.gnu.org/ml/libstdc++/2004-08/msg00167.html: in a
@@ -109,9 +110,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
typedef typename iterator_traits<_ForwardIterator1>::value_type
_ValueType1;
- _ValueType1 __tmp = *__a;
- *__a = *__b;
- *__b = __tmp;
+ _ValueType1 __tmp = _GLIBCXX_MOVE(*__a);
+ *__a = _GLIBCXX_MOVE(*__b);
+ *__b = _GLIBCXX_MOVE(__tmp);
}
};
@@ -879,6 +880,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_P)
{
typedef typename iterator_traits<_II1>::iterator_category _Category1;
typedef typename iterator_traits<_II2>::iterator_category _Category2;
+ typedef __lc_rai<_Category1, _Category2> __rai_type;
// concept requirements
typedef typename iterator_traits<_II1>::value_type _ValueType1;
@@ -890,12 +892,8 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_P)
__glibcxx_requires_valid_range(__first1, __last1);
__glibcxx_requires_valid_range(__first2, __last2);
- __last1 = __lc_rai<_Category1, _Category2>::__newlast1(__first1,
- __last1,
- __first2,
- __last2);
- for (; __first1 != __last1
- && __lc_rai<_Category1, _Category2>::__cnd2(__first2, __last2);
+ __last1 = __rai_type::__newlast1(__first1, __last1, __first2, __last2);
+ for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2);
++__first1, ++__first2)
{
if (*__first1 < *__first2)
diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index a2a86f26f17..db9061b90fb 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -385,6 +385,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
_Bit_iterator _M_start;
_Bit_iterator _M_finish;
_Bit_type* _M_end_of_storage;
+
+ _Bvector_impl()
+ : _Bit_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage(0)
+ { }
+
_Bvector_impl(const _Bit_alloc_type& __a)
: _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0)
{ }
@@ -405,7 +410,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
get_allocator() const
{ return allocator_type(_M_get_Bit_allocator()); }
- _Bvector_base(const allocator_type& __a) : _M_impl(__a) { }
+ _Bvector_base()
+ : _M_impl() { }
+
+ _Bvector_base(const allocator_type& __a)
+ : _M_impl(__a) { }
~_Bvector_base()
{ this->_M_deallocate(); }
@@ -480,8 +489,11 @@ template<typename _Alloc>
using _Base::_M_get_Bit_allocator;
public:
+ vector()
+ : _Base() { }
+
explicit
- vector(const allocator_type& __a = allocator_type())
+ vector(const allocator_type& __a)
: _Base(__a) { }
explicit
@@ -501,6 +513,12 @@ template<typename _Alloc>
_M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start);
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ vector(vector&& __x)
+ : _Base(__x._M_get_Bit_allocator())
+ { this->swap(__x); }
+#endif
+
template<typename _InputIterator>
vector(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
@@ -527,6 +545,15 @@ template<typename _Alloc>
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ vector&
+ operator=(vector&& __x)
+ {
+ this->swap(__x);
+ return *this;
+ }
+#endif
+
// assign(), a generalized assignment member function. Two
// versions: one that takes a count, and one that takes a range.
// The range version is a member template, so we dispatch on whether
@@ -681,7 +708,11 @@ template<typename _Alloc>
}
void
- swap(vector<bool, _Alloc>& __x)
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(vector&& __x)
+#else
+ swap(vector& __x)
+#endif
{
std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h
index a0553961a5b..7a7b86e2d38 100644
--- a/libstdc++-v3/include/bits/stl_deque.h
+++ b/libstdc++-v3/include/bits/stl_deque.h
@@ -123,13 +123,14 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
_Deque_iterator(_Tp* __x, _Map_pointer __y)
: _M_cur(__x), _M_first(*__y),
- _M_last(*__y + _S_buffer_size()), _M_node(__y) {}
+ _M_last(*__y + _S_buffer_size()), _M_node(__y) { }
- _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
+ _Deque_iterator()
+ : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) { }
_Deque_iterator(const iterator& __x)
: _M_cur(__x._M_cur), _M_first(__x._M_first),
- _M_last(__x._M_last), _M_node(__x._M_node) {}
+ _M_last(__x._M_last), _M_node(__x._M_node) { }
reference
operator*() const
@@ -380,6 +381,10 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator;
typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
+ _Deque_base()
+ : _M_impl()
+ { _M_initialize_map(0); }
+
_Deque_base(const allocator_type& __a, size_t __num_elements)
: _M_impl(__a)
{ _M_initialize_map(__num_elements); }
@@ -406,6 +411,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
iterator _M_start;
iterator _M_finish;
+ _Deque_impl()
+ : _Tp_alloc_type(), _M_map(0), _M_map_size(0),
+ _M_start(), _M_finish()
+ { }
+
_Deque_impl(const _Tp_alloc_type& __a)
: _Tp_alloc_type(__a), _M_map(0), _M_map_size(0),
_M_start(), _M_finish()
@@ -679,14 +689,22 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
/**
* @brief Default constructor creates no elements.
*/
+ deque()
+ : _Base() { }
+
+ /**
+ * @brief Creates a %deque with no elements.
+ * @param a An allocator object.
+ */
explicit
- deque(const allocator_type& __a = allocator_type())
- : _Base(__a, 0) {}
+ deque(const allocator_type& __a)
+ : _Base(__a, 0) { }
/**
- * @brief Create a %deque with copies of an exemplar element.
+ * @brief Creates a %deque with copies of an exemplar element.
* @param n The number of elements to initially create.
* @param value An element to copy.
+ * @param a An allocator.
*
* This constructor fills the %deque with @a n copies of @a value.
*/
@@ -709,10 +727,24 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
this->_M_impl._M_start,
_M_get_Tp_allocator()); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief %Deque move constructor.
+ * @param x A %deque of identical element and allocator types.
+ *
+ * The newly-created %deque contains the exact contents of @a x.
+ * The contents of @a x are a valid, but unspecified %deque.
+ */
+ deque(deque&& __x)
+ : _Base(__x._M_get_Tp_allocator(), 0)
+ { this->swap(__x); }
+#endif
+
/**
* @brief Builds a %deque from a range.
* @param first An input iterator.
* @param last An input iterator.
+ * @param a An allocator object.
*
* Create a %deque consisting of copies of the elements from [first,
* last).
@@ -751,6 +783,22 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
deque&
operator=(const deque& __x);
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief %Deque move assignment operator.
+ * @param x A %deque of identical element and allocator types.
+ *
+ * The contents of @a x are moved into this deque (without copying).
+ * @a x is a valid, but unspecified %deque.
+ */
+ deque&
+ operator=(deque&& __x)
+ {
+ this->swap(__x);
+ return *this;
+ }
+#endif
+
/**
* @brief Assigns a given value to a %deque.
* @param n Number of elements to be assigned.
@@ -1194,7 +1242,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* std::swap(d1,d2) will feed to this function.
*/
void
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(deque&& __x)
+#else
swap(deque& __x)
+#endif
{
std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
@@ -1598,6 +1650,18 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y)
{ __x.swap(__y); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(deque<_Tp,_Alloc>&& __x, deque<_Tp,_Alloc>& __y)
+ { __x.swap(__y); }
+
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>&& __y)
+ { __x.swap(__y); }
+#endif
+
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _STL_DEQUE_H */
diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h
index d7c09260234..ac561eee351 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -826,4 +826,173 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
_GLIBCXX_END_NAMESPACE
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+
+_GLIBCXX_BEGIN_NAMESPACE(std)
+
+ // 24.4.3 Move iterators
+ /**
+ * @if maint
+ * Class template move_iterator is an iterator adapter with the same
+ * behavior as the underlying iterator except that its dereference
+ * operator implicitly converts the value returned by the underlying
+ * iterator's dereference operator to an rvalue reference. Some
+ * generic algorithms can be called with move iterators to replace
+ * copying with moving.
+ * @endif
+ */
+ template<typename _Iterator>
+ class move_iterator
+ {
+ protected:
+ _Iterator _M_current;
+
+ public:
+ typedef _Iterator iterator_type;
+ typedef typename iterator_traits<_Iterator>::difference_type
+ difference_type;
+ typedef typename iterator_traits<_Iterator>::pointer pointer;
+ typedef typename iterator_traits<_Iterator>::value_type value_type;
+ typedef typename iterator_traits<_Iterator>::iterator_category
+ iterator_category;
+ typedef value_type&& reference;
+
+ public:
+ move_iterator()
+ : _M_current() { }
+
+ explicit
+ move_iterator(iterator_type __i)
+ : _M_current(__i) { }
+
+ template<typename _Iter>
+ move_iterator(const move_iterator<_Iter>& __i)
+ : _M_current(__i.base()) { }
+
+ iterator_type
+ base() const
+ { return _M_current; }
+
+ reference
+ operator*() const
+ { return *_M_current; }
+
+ pointer
+ operator->() const
+ { return _M_current; }
+
+ move_iterator&
+ operator++()
+ {
+ ++_M_current;
+ return *this;
+ }
+
+ move_iterator
+ operator++(int)
+ {
+ move_iterator __tmp = *this;
+ ++_M_current;
+ return __tmp;
+ }
+
+ move_iterator&
+ operator--()
+ {
+ --_M_current;
+ return *this;
+ }
+
+ move_iterator
+ operator--(int)
+ {
+ move_iterator __tmp = *this;
+ --_M_current;
+ return __tmp;
+ }
+
+ move_iterator
+ operator+(difference_type __n) const
+ { return move_iterator(_M_current + __n); }
+
+ move_iterator&
+ operator+=(difference_type __n)
+ {
+ _M_current += __n;
+ return *this;
+ }
+
+ move_iterator
+ operator-(difference_type __n) const
+ { return move_iterator(_M_current - __n); }
+
+ move_iterator&
+ operator-=(difference_type __n)
+ {
+ _M_current -= __n;
+ return *this;
+ }
+
+ reference
+ operator[](difference_type __n) const
+ { return _M_current[__n]; }
+ };
+
+ template<typename _IteratorL, typename _IteratorR>
+ inline bool
+ operator==(const move_iterator<_IteratorL>& __x,
+ const move_iterator<_IteratorR>& __y)
+ { return __x.base() == __y.base(); }
+
+ template<typename _IteratorL, typename _IteratorR>
+ inline bool
+ operator!=(const move_iterator<_IteratorL>& __x,
+ const move_iterator<_IteratorR>& __y)
+ { return !(__x == __y); }
+
+ template<typename _IteratorL, typename _IteratorR>
+ inline bool
+ operator<(const move_iterator<_IteratorL>& __x,
+ const move_iterator<_IteratorR>& __y)
+ { return __x.base() < __y.base(); }
+
+ template<typename _IteratorL, typename _IteratorR>
+ inline bool
+ operator<=(const move_iterator<_IteratorL>& __x,
+ const move_iterator<_IteratorR>& __y)
+ { return !(__y < __x); }
+
+ template<typename _IteratorL, typename _IteratorR>
+ inline bool
+ operator>(const move_iterator<_IteratorL>& __x,
+ const move_iterator<_IteratorR>& __y)
+ { return __y < __x; }
+
+ template<typename _IteratorL, typename _IteratorR>
+ inline bool
+ operator>=(const move_iterator<_IteratorL>& __x,
+ const move_iterator<_IteratorR>& __y)
+ { return !(__x < __y); }
+
+ template<typename _IteratorL, typename _IteratorR>
+ inline typename move_iterator<_IteratorL>::difference_type
+ operator-(const move_iterator<_IteratorL>& __x,
+ const move_iterator<_IteratorR>& __y)
+ { return __x.base() - __y.base(); }
+
+ template<typename _Iterator>
+ inline move_iterator<_Iterator>
+ operator+(typename move_iterator<_Iterator>::difference_type __n,
+ const move_iterator<_Iterator>& __x)
+ { return __x + __n; }
+
+ template<typename _Iterator>
+ inline move_iterator<_Iterator>
+ make_move_iterator(const _Iterator& __i)
+ { return move_iterator<_Iterator>(__i); }
+
+_GLIBCXX_END_NAMESPACE
+
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
#endif
diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h
index dac02c8e616..2b690eb5486 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -305,6 +305,10 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
{
_List_node_base _M_node;
+ _List_impl()
+ : _Node_alloc_type(), _M_node()
+ { }
+
_List_impl(const _Node_alloc_type& __a)
: _Node_alloc_type(__a), _M_node()
{ }
@@ -339,6 +343,10 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
get_allocator() const
{ return allocator_type(_M_get_Node_allocator()); }
+ _List_base()
+ : _M_impl()
+ { _M_init(); }
+
_List_base(const allocator_type& __a)
: _M_impl(__a)
{ _M_init(); }
@@ -468,14 +476,22 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
/**
* @brief Default constructor creates no elements.
*/
+ list()
+ : _Base() { }
+
+ /**
+ * @brief Creates a %list with no elements.
+ * @param a An allocator object.
+ */
explicit
- list(const allocator_type& __a = allocator_type())
+ list(const allocator_type& __a)
: _Base(__a) { }
/**
- * @brief Create a %list with copies of an exemplar element.
+ * @brief Creates a %list with copies of an exemplar element.
* @param n The number of elements to initially create.
* @param value An element to copy.
+ * @param a An allocator object.
*
* This constructor fills the %list with @a n copies of @a value.
*/
@@ -496,10 +512,24 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
: _Base(__x._M_get_Node_allocator())
{ _M_initialize_dispatch(__x.begin(), __x.end(), __false_type()); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief %List move constructor.
+ * @param x A %list of identical element and allocator types.
+ *
+ * The newly-created %list contains the exact contents of @a x.
+ * The contents of @a x are a valid, but unspecified %list.
+ */
+ list(list&& __x)
+ : _Base(__x._M_get_Node_allocator())
+ { this->swap(__x); }
+#endif
+
/**
* @brief Builds a %list from a range.
* @param first An input iterator.
* @param last An input iterator.
+ * @param a An allocator object.
*
* Create a %list consisting of copies of the elements from
* [@a first,@a last). This is linear in N (where N is
@@ -533,6 +563,22 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
list&
operator=(const list& __x);
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief %List move assignment operator.
+ * @param x A %list of identical element and allocator types.
+ *
+ * The contents of @a x are moved into this %list (without copying).
+ * @a x is a valid, but unspecified %list
+ */
+ list&
+ operator=(list&& __x)
+ {
+ this->swap(__x);
+ return *this;
+ }
+#endif
+
/**
* @brief Assigns a given value to a %list.
* @param n Number of elements to be assigned.
@@ -887,7 +933,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* function.
*/
void
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(list&& __x)
+#else
swap(list& __x)
+#endif
{
_List_node_base::swap(this->_M_impl._M_node, __x._M_impl._M_node);
@@ -1256,7 +1306,18 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
{ __x.swap(__y); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(list<_Tp, _Alloc>&& __x, list<_Tp, _Alloc>& __y)
+ { __x.swap(__y); }
+
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>&& __y)
+ { __x.swap(__y); }
+#endif
+
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _STL_LIST_H */
-
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index e1429ef6956..f4545a02d4e 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -155,26 +155,42 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* @brief Default constructor creates no elements.
*/
map()
- : _M_t(_Compare(), allocator_type()) { }
+ : _M_t() { }
- // for some reason this was made a separate function
/**
- * @brief Default constructor creates no elements.
+ * @brief Creates a %map with no elements.
+ * @param comp A comparison object.
+ * @param a An allocator object.
*/
explicit
- map(const _Compare& __comp, const allocator_type& __a = allocator_type())
+ map(const _Compare& __comp,
+ const allocator_type& __a = allocator_type())
: _M_t(__comp, __a) { }
/**
- * @brief Map copy constructor.
+ * @brief %Map copy constructor.
* @param x A %map of identical element and allocator types.
*
- * The newly-created %map uses a copy of the allocation object used
- * by @a x.
+ * The newly-created %map uses a copy of the allocation object
+ * used by @a x.
*/
map(const map& __x)
: _M_t(__x._M_t) { }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief %Map move constructor.
+ * @param x A %map of identical element and allocator types.
+ *
+ * The newly-created %map contains the exact contents of @a x.
+ * The contents of @a x are a valid, but unspecified %map.
+ */
+ map(map&& __x)
+ : _M_t(__x._M_t.key_comp(),
+ __x._M_t._M_get_Node_allocator())
+ { this->swap(__x); }
+#endif
+
/**
* @brief Builds a %map from a range.
* @param first An input iterator.
@@ -184,9 +200,9 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* This is linear in N if the range is already sorted, and NlogN
* otherwise (where N is distance(first,last)).
*/
- template <typename _InputIterator>
+ template<typename _InputIterator>
map(_InputIterator __first, _InputIterator __last)
- : _M_t(_Compare(), allocator_type())
+ : _M_t()
{ _M_t._M_insert_unique(__first, __last); }
/**
@@ -200,9 +216,10 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* This is linear in N if the range is already sorted, and NlogN
* otherwise (where N is distance(first,last)).
*/
- template <typename _InputIterator>
+ template<typename _InputIterator>
map(_InputIterator __first, _InputIterator __last,
- const _Compare& __comp, const allocator_type& __a = allocator_type())
+ const _Compare& __comp,
+ const allocator_type& __a = allocator_type())
: _M_t(__comp, __a)
{ _M_t._M_insert_unique(__first, __last); }
@@ -216,7 +233,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*/
/**
- * @brief Map assignment operator.
+ * @brief %Map assignment operator.
* @param x A %map of identical element and allocator types.
*
* All the elements of @a x are copied, but unlike the copy constructor,
@@ -229,6 +246,22 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief %Map move assignment operator.
+ * @param x A %map of identical element and allocator types.
+ *
+ * The contents of @a x are moved into this map (without copying).
+ * @a x is a valid, but unspecified %map.
+ */
+ map&
+ operator=(map&& __x)
+ {
+ this->swap(__x);
+ return *this;
+ }
+#endif
+
/// Get a copy of the memory allocation object.
allocator_type
get_allocator() const
@@ -434,7 +467,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*
* Complexity similar to that of the range constructor.
*/
- template <typename _InputIterator>
+ template<typename _InputIterator>
void
insert(_InputIterator __first, _InputIterator __last)
{ _M_t._M_insert_unique(__first, __last); }
@@ -495,7 +528,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* that std::swap(m1,m2) will feed to this function.
*/
void
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(map&& __x)
+#else
swap(map& __x)
+#endif
{ _M_t.swap(__x._M_t); }
/**
@@ -656,15 +693,15 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
- template <typename _K1, typename _T1, typename _C1, typename _A1>
+ template<typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
- operator== (const map<_K1, _T1, _C1, _A1>&,
- const map<_K1, _T1, _C1, _A1>&);
+ operator==(const map<_K1, _T1, _C1, _A1>&,
+ const map<_K1, _T1, _C1, _A1>&);
- template <typename _K1, typename _T1, typename _C1, typename _A1>
+ template<typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
- operator< (const map<_K1, _T1, _C1, _A1>&,
- const map<_K1, _T1, _C1, _A1>&);
+ operator<(const map<_K1, _T1, _C1, _A1>&,
+ const map<_K1, _T1, _C1, _A1>&);
};
/**
@@ -677,7 +714,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* maps. Maps are considered equivalent if their sizes are equal,
* and if corresponding elements compare equal.
*/
- template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator==(const map<_Key, _Tp, _Compare, _Alloc>& __x,
const map<_Key, _Tp, _Compare, _Alloc>& __y)
@@ -694,47 +731,61 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*
* See std::lexicographical_compare() for how the determination is made.
*/
- template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator<(const map<_Key, _Tp, _Compare, _Alloc>& __x,
const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __x._M_t < __y._M_t; }
/// Based on operator==
- template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator!=(const map<_Key, _Tp, _Compare, _Alloc>& __x,
const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__x == __y); }
/// Based on operator<
- template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator>(const map<_Key, _Tp, _Compare, _Alloc>& __x,
const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __y < __x; }
/// Based on operator<
- template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator<=(const map<_Key, _Tp, _Compare, _Alloc>& __x,
const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__y < __x); }
/// Based on operator<
- template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator>=(const map<_Key, _Tp, _Compare, _Alloc>& __x,
const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__x < __y); }
/// See std::map::swap().
- template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline void
swap(map<_Key, _Tp, _Compare, _Alloc>& __x,
map<_Key, _Tp, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ inline void
+ swap(map<_Key, _Tp, _Compare, _Alloc>&& __x,
+ map<_Key, _Tp, _Compare, _Alloc>& __y)
+ { __x.swap(__y); }
+
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ inline void
+ swap(map<_Key, _Tp, _Compare, _Alloc>& __x,
+ map<_Key, _Tp, _Compare, _Alloc>&& __y)
+ { __x.swap(__y); }
+#endif
+
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _STL_MAP_H */
diff --git a/libstdc++-v3/include/bits/stl_move.h b/libstdc++-v3/include/bits/stl_move.h
new file mode 100644
index 00000000000..3c799e4a924
--- /dev/null
+++ b/libstdc++-v3/include/bits/stl_move.h
@@ -0,0 +1,67 @@
+// Move, forward and identity implementation for C++0x -*- C++ -*-
+
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/** @file stl_move.h
+ * This is an internal header file, included by other library headers.
+ * You should not attempt to use it directly.
+ */
+
+#ifndef _STL_MOVE_H
+#define _STL_MOVE_H 1
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#include <type_traits>
+
+_GLIBCXX_BEGIN_NAMESPACE(std)
+
+ // 20.2.2, forward/move
+ template<typename _Tp>
+ struct identity
+ {
+ typedef _Tp type;
+ };
+
+ template<typename _Tp>
+ inline _Tp&&
+ forward(typename std::identity<_Tp>::type&& __t)
+ { return __t; }
+
+ template<typename _Tp>
+ inline typename std::remove_reference<_Tp>::type&&
+ move(_Tp&& __t)
+ { return __t; }
+
+_GLIBCXX_END_NAMESPACE
+
+#define _GLIBCXX_MOVE(_Tp) std::move(_Tp)
+#else
+#define _GLIBCXX_MOVE(_Tp) _Tp
+#endif
+
+#endif /* _STL_MOVE_H */
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index 5730854ee69..864f4b21bbe 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -153,11 +153,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* @brief Default constructor creates no elements.
*/
multimap()
- : _M_t(_Compare(), allocator_type()) { }
+ : _M_t() { }
- // for some reason this was made a separate function
/**
- * @brief Default constructor creates no elements.
+ * @brief Creates a %multimap with no elements.
+ * @param comp A comparison object.
+ * @param a An allocator object.
*/
explicit
multimap(const _Compare& __comp,
@@ -168,12 +169,26 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* @brief %Multimap copy constructor.
* @param x A %multimap of identical element and allocator types.
*
- * The newly-created %multimap uses a copy of the allocation object used
- * by @a x.
+ * The newly-created %multimap uses a copy of the allocation object
+ * used by @a x.
*/
multimap(const multimap& __x)
: _M_t(__x._M_t) { }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief %Multimap move constructor.
+ * @param x A %multimap of identical element and allocator types.
+ *
+ * The newly-created %multimap contains the exact contents of @a x.
+ * The contents of @a x are a valid, but unspecified %multimap.
+ */
+ multimap(multimap&& __x)
+ : _M_t(__x._M_t.key_comp(),
+ __x._M_t._M_get_Node_allocator())
+ { this->swap(__x); }
+#endif
+
/**
* @brief Builds a %multimap from a range.
* @param first An input iterator.
@@ -183,10 +198,10 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* [first,last). This is linear in N if the range is already sorted,
* and NlogN otherwise (where N is distance(first,last)).
*/
- template <typename _InputIterator>
+ template<typename _InputIterator>
multimap(_InputIterator __first, _InputIterator __last)
- : _M_t(_Compare(), allocator_type())
- { _M_t._M_insert_equal(__first, __last); }
+ : _M_t()
+ { _M_t._M_insert_unique(__first, __last); }
/**
* @brief Builds a %multimap from a range.
@@ -199,7 +214,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* [first,last). This is linear in N if the range is already sorted,
* and NlogN otherwise (where N is distance(first,last)).
*/
- template <typename _InputIterator>
+ template<typename _InputIterator>
multimap(_InputIterator __first, _InputIterator __last,
const _Compare& __comp,
const allocator_type& __a = allocator_type())
@@ -229,6 +244,22 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief %Multimap move assignment operator.
+ * @param x A %multimap of identical element and allocator types.
+ *
+ * The contents of @a x are moved into this multimap (without copying).
+ * @a x is a valid, but unspecified multimap.
+ */
+ multimap&
+ operator=(multimap&& __x)
+ {
+ this->swap(__x);
+ return *this;
+ }
+#endif
+
/// Get a copy of the memory allocation object.
allocator_type
get_allocator() const
@@ -372,7 +403,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*
* Complexity similar to that of the range constructor.
*/
- template <typename _InputIterator>
+ template<typename _InputIterator>
void
insert(_InputIterator __first, _InputIterator __last)
{ _M_t._M_insert_equal(__first, __last); }
@@ -433,7 +464,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* std::swap(m1,m2) will feed to this function.
*/
void
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(multimap&& __x)
+#else
swap(multimap& __x)
+#endif
{ _M_t.swap(__x._M_t); }
/**
@@ -587,15 +622,15 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
- template <typename _K1, typename _T1, typename _C1, typename _A1>
+ template<typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
- operator== (const multimap<_K1, _T1, _C1, _A1>&,
- const multimap<_K1, _T1, _C1, _A1>&);
+ operator==(const multimap<_K1, _T1, _C1, _A1>&,
+ const multimap<_K1, _T1, _C1, _A1>&);
- template <typename _K1, typename _T1, typename _C1, typename _A1>
+ template<typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
- operator< (const multimap<_K1, _T1, _C1, _A1>&,
- const multimap<_K1, _T1, _C1, _A1>&);
+ operator<(const multimap<_K1, _T1, _C1, _A1>&,
+ const multimap<_K1, _T1, _C1, _A1>&);
};
/**
@@ -608,7 +643,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* multimaps. Multimaps are considered equivalent if their sizes are equal,
* and if corresponding elements compare equal.
*/
- template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator==(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
@@ -625,47 +660,61 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*
* See std::lexicographical_compare() for how the determination is made.
*/
- template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator<(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __x._M_t < __y._M_t; }
/// Based on operator==
- template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator!=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__x == __y); }
/// Based on operator<
- template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator>(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __y < __x; }
/// Based on operator<
- template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator<=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__y < __x); }
/// Based on operator<
- template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator>=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__x < __y); }
/// See std::multimap::swap().
- template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline void
swap(multimap<_Key, _Tp, _Compare, _Alloc>& __x,
multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ inline void
+ swap(multimap<_Key, _Tp, _Compare, _Alloc>&& __x,
+ multimap<_Key, _Tp, _Compare, _Alloc>& __y)
+ { __x.swap(__y); }
+
+ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+ inline void
+ swap(multimap<_Key, _Tp, _Compare, _Alloc>& __x,
+ multimap<_Key, _Tp, _Compare, _Alloc>&& __y)
+ { __x.swap(__y); }
+#endif
+
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _STL_MULTIMAP_H */
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index dab8d6f47f3..6e45b8fbcb4 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -86,8 +86,8 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* called (*_unique versus *_equal, same as the standard).
* @endif
*/
- template <class _Key, class _Compare = std::less<_Key>,
- class _Alloc = std::allocator<_Key> >
+ template <typename _Key, typename _Compare = std::less<_Key>,
+ typename _Alloc = std::allocator<_Key> >
class multiset
{
// concept requirements
@@ -130,13 +130,17 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
typedef typename _Rep_type::difference_type difference_type;
// allocation/deallocation
-
/**
* @brief Default constructor creates no elements.
*/
multiset()
- : _M_t(_Compare(), allocator_type()) { }
+ : _M_t() { }
+ /**
+ * @brief Creates a %multiset with no elements.
+ * @param comp Comparator to use.
+ * @param a An allocator object.
+ */
explicit
multiset(const _Compare& __comp,
const allocator_type& __a = allocator_type())
@@ -151,9 +155,9 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* [first,last). This is linear in N if the range is already sorted,
* and NlogN otherwise (where N is distance(first,last)).
*/
- template <class _InputIterator>
+ template<typename _InputIterator>
multiset(_InputIterator __first, _InputIterator __last)
- : _M_t(_Compare(), allocator_type())
+ : _M_t()
{ _M_t._M_insert_equal(__first, __last); }
/**
@@ -167,7 +171,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* [first,last). This is linear in N if the range is already sorted,
* and NlogN otherwise (where N is distance(first,last)).
*/
- template <class _InputIterator>
+ template<typename _InputIterator>
multiset(_InputIterator __first, _InputIterator __last,
const _Compare& __comp,
const allocator_type& __a = allocator_type())
@@ -181,9 +185,23 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* The newly-created %multiset uses a copy of the allocation object used
* by @a x.
*/
- multiset(const multiset<_Key,_Compare,_Alloc>& __x)
+ multiset(const multiset& __x)
: _M_t(__x._M_t) { }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief %Multiset move constructor.
+ * @param x A %multiset of identical element and allocator types.
+ *
+ * The newly-created %multiset contains the exact contents of @a x.
+ * The contents of @a x are a valid, but unspecified %multiset.
+ */
+ multiset(multiset&& __x)
+ : _M_t(__x._M_t.key_comp(),
+ __x._M_t._M_get_Node_allocator())
+ { this->swap(__x); }
+#endif
+
/**
* @brief %Multiset assignment operator.
* @param x A %multiset of identical element and allocator types.
@@ -191,13 +209,29 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* All the elements of @a x are copied, but unlike the copy constructor,
* the allocator object is not copied.
*/
- multiset<_Key,_Compare,_Alloc>&
- operator=(const multiset<_Key,_Compare,_Alloc>& __x)
+ multiset&
+ operator=(const multiset& __x)
{
_M_t = __x._M_t;
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief %Multiset move assignment operator.
+ * @param x A %multiset of identical element and allocator types.
+ *
+ * The contents of @a x are moved into this %multiset (without copying).
+ * @a x is a valid, but unspecified %multiset.
+ */
+ multiset&
+ operator=(multiset&& __x)
+ {
+ this->swap(__x);
+ return *this;
+ }
+#endif
+
// accessors:
/// Returns the comparison object.
@@ -276,7 +310,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* std::swap(s1,s2) will feed to this function.
*/
void
- swap(multiset<_Key, _Compare, _Alloc>& __x)
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(multiset&& __x)
+#else
+ swap(multiset& __x)
+#endif
{ _M_t.swap(__x._M_t); }
// insert/erase
@@ -327,7 +365,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*
* Complexity similar to that of the range constructor.
*/
- template <class _InputIterator>
+ template<typename _InputIterator>
void
insert(_InputIterator __first, _InputIterator __last)
{ _M_t._M_insert_equal(__first, __last); }
@@ -481,12 +519,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
- template <class _K1, class _C1, class _A1>
+ template<typename _K1, typename _C1, typename _A1>
friend bool
- operator== (const multiset<_K1, _C1, _A1>&,
- const multiset<_K1, _C1, _A1>&);
+ operator==(const multiset<_K1, _C1, _A1>&,
+ const multiset<_K1, _C1, _A1>&);
- template <class _K1, class _C1, class _A1>
+ template<typename _K1, typename _C1, typename _A1>
friend bool
operator< (const multiset<_K1, _C1, _A1>&,
const multiset<_K1, _C1, _A1>&);
@@ -503,7 +541,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* Multisets are considered equivalent if their sizes are equal, and if
* corresponding elements compare equal.
*/
- template <class _Key, class _Compare, class _Alloc>
+ template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator==(const multiset<_Key, _Compare, _Alloc>& __x,
const multiset<_Key, _Compare, _Alloc>& __y)
@@ -520,47 +558,61 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*
* See std::lexicographical_compare() for how the determination is made.
*/
- template <class _Key, class _Compare, class _Alloc>
+ template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator<(const multiset<_Key, _Compare, _Alloc>& __x,
const multiset<_Key, _Compare, _Alloc>& __y)
{ return __x._M_t < __y._M_t; }
/// Returns !(x == y).
- template <class _Key, class _Compare, class _Alloc>
+ template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator!=(const multiset<_Key, _Compare, _Alloc>& __x,
const multiset<_Key, _Compare, _Alloc>& __y)
{ return !(__x == __y); }
/// Returns y < x.
- template <class _Key, class _Compare, class _Alloc>
+ template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator>(const multiset<_Key,_Compare,_Alloc>& __x,
const multiset<_Key,_Compare,_Alloc>& __y)
{ return __y < __x; }
/// Returns !(y < x)
- template <class _Key, class _Compare, class _Alloc>
+ template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator<=(const multiset<_Key, _Compare, _Alloc>& __x,
const multiset<_Key, _Compare, _Alloc>& __y)
{ return !(__y < __x); }
/// Returns !(x < y)
- template <class _Key, class _Compare, class _Alloc>
+ template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator>=(const multiset<_Key, _Compare, _Alloc>& __x,
const multiset<_Key, _Compare, _Alloc>& __y)
{ return !(__x < __y); }
/// See std::multiset::swap().
- template <class _Key, class _Compare, class _Alloc>
+ template<typename _Key, typename _Compare, typename _Alloc>
inline void
swap(multiset<_Key, _Compare, _Alloc>& __x,
multiset<_Key, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Key, typename _Compare, typename _Alloc>
+ inline void
+ swap(multiset<_Key, _Compare, _Alloc>&& __x,
+ multiset<_Key, _Compare, _Alloc>& __y)
+ { __x.swap(__y); }
+
+ template<typename _Key, typename _Compare, typename _Alloc>
+ inline void
+ swap(multiset<_Key, _Compare, _Alloc>& __x,
+ multiset<_Key, _Compare, _Alloc>&& __y)
+ { __x.swap(__y); }
+#endif
+
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _STL_MULTISET_H */
diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
index bdc6723f748..68927d2c3e3 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -62,6 +62,8 @@
#ifndef _STL_PAIR_H
#define _STL_PAIR_H 1
+#include <bits/stl_move.h>
+
_GLIBCXX_BEGIN_NAMESPACE(std)
/// pair holds two objects of arbitrary type.
@@ -89,6 +91,20 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
template<class _U1, class _U2>
pair(const pair<_U1, _U2>& __p)
: first(__p.first), second(__p.second) { }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ pair(pair&& __p)
+ : first(std::move(__p.first)),
+ second(std::move(__p.second)) { }
+
+ pair&
+ operator=(pair&& __p)
+ {
+ first = std::move(__p.first);
+ second = std::move(__p.second);
+ return *this;
+ }
+#endif
};
/// Two pairs of the same type are equal iff their members are equal.
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index 3bddefc635d..2b51bfaa970 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -89,8 +89,8 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* called (*_unique versus *_equal, same as the standard).
* @endif
*/
- template<class _Key, class _Compare = std::less<_Key>,
- class _Alloc = std::allocator<_Key> >
+ template<typename _Key, typename _Compare = std::less<_Key>,
+ typename _Alloc = std::allocator<_Key> >
class set
{
// concept requirements
@@ -137,20 +137,21 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
//@}
// allocation/deallocation
- /// Default constructor creates no elements.
+ /**
+ * @brief Default constructor creates no elements.
+ */
set()
- : _M_t(_Compare(), allocator_type()) {}
+ : _M_t() { }
/**
- * @brief Default constructor creates no elements.
- *
+ * @brief Creates a %set with no elements.
* @param comp Comparator to use.
- * @param a Allocator to use.
+ * @param a An allocator object.
*/
explicit
set(const _Compare& __comp,
const allocator_type& __a = allocator_type())
- : _M_t(__comp, __a) {}
+ : _M_t(__comp, __a) { }
/**
* @brief Builds a %set from a range.
@@ -161,9 +162,9 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* This is linear in N if the range is already sorted, and NlogN
* otherwise (where N is distance(first,last)).
*/
- template<class _InputIterator>
+ template<typename _InputIterator>
set(_InputIterator __first, _InputIterator __last)
- : _M_t(_Compare(), allocator_type())
+ : _M_t()
{ _M_t._M_insert_unique(__first, __last); }
/**
@@ -177,7 +178,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* This is linear in N if the range is already sorted, and NlogN
* otherwise (where N is distance(first,last)).
*/
- template<class _InputIterator>
+ template<typename _InputIterator>
set(_InputIterator __first, _InputIterator __last,
const _Compare& __comp,
const allocator_type& __a = allocator_type())
@@ -185,29 +186,59 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
{ _M_t._M_insert_unique(__first, __last); }
/**
- * @brief Set copy constructor.
+ * @brief %Set copy constructor.
* @param x A %set of identical element and allocator types.
*
* The newly-created %set uses a copy of the allocation object used
* by @a x.
*/
- set(const set<_Key,_Compare,_Alloc>& __x)
+ set(const set& __x)
: _M_t(__x._M_t) { }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief %Set move constructor
+ * @param x A %set of identical element and allocator types.
+ *
+ * The newly-created %set contains the exact contents of @a x.
+ * The contents of @a x are a valid, but unspecified %set.
+ */
+ set(set&& __x)
+ : _M_t(__x._M_t.key_comp(),
+ __x._M_t._M_get_Node_allocator())
+ { this->swap(__x); }
+#endif
+
/**
- * @brief Set assignment operator.
+ * @brief %Set assignment operator.
* @param x A %set of identical element and allocator types.
*
* All the elements of @a x are copied, but unlike the copy constructor,
* the allocator object is not copied.
*/
- set<_Key,_Compare,_Alloc>&
- operator=(const set<_Key, _Compare, _Alloc>& __x)
+ set&
+ operator=(const set& __x)
{
_M_t = __x._M_t;
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief %Set move assignment operator.
+ * @param x A %set of identical element and allocator types.
+ *
+ * The contents of @a x are moved into this %set (without copying).
+ * @a x is a valid, but unspecified %set.
+ */
+ set&
+ operator=(set&& __x)
+ {
+ this->swap(__x);
+ return *this;
+ }
+#endif
+
// accessors:
/// Returns the comparison object with which the %set was constructed.
@@ -284,7 +315,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* std::swap(s1,s2) will feed to this function.
*/
void
- swap(set<_Key,_Compare,_Alloc>& __x)
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(set&& __x)
+#else
+ swap(set& __x)
+#endif
{ _M_t.swap(__x._M_t); }
// insert/erase
@@ -301,7 +336,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*
* Insertion requires logarithmic time.
*/
- std::pair<iterator,bool>
+ std::pair<iterator, bool>
insert(const value_type& __x)
{
std::pair<typename _Rep_type::iterator, bool> __p =
@@ -340,7 +375,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*
* Complexity similar to that of the range constructor.
*/
- template<class _InputIterator>
+ template<typename _InputIterator>
void
insert(_InputIterator __first, _InputIterator __last)
{ _M_t._M_insert_unique(__first, __last); }
@@ -497,13 +532,13 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
{ return _M_t.equal_range(__x); }
//@}
- template<class _K1, class _C1, class _A1>
+ template<typename _K1, typename _C1, typename _A1>
friend bool
- operator== (const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&);
+ operator==(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&);
- template<class _K1, class _C1, class _A1>
+ template<typename _K1, typename _C1, typename _A1>
friend bool
- operator< (const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&);
+ operator<(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&);
};
@@ -517,7 +552,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* Sets are considered equivalent if their sizes are equal, and if
* corresponding elements compare equal.
*/
- template<class _Key, class _Compare, class _Alloc>
+ template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator==(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y)
@@ -534,46 +569,58 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*
* See std::lexicographical_compare() for how the determination is made.
*/
- template<class _Key, class _Compare, class _Alloc>
+ template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator<(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y)
{ return __x._M_t < __y._M_t; }
/// Returns !(x == y).
- template<class _Key, class _Compare, class _Alloc>
+ template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator!=(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y)
{ return !(__x == __y); }
/// Returns y < x.
- template<class _Key, class _Compare, class _Alloc>
+ template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator>(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y)
{ return __y < __x; }
/// Returns !(y < x)
- template<class _Key, class _Compare, class _Alloc>
+ template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator<=(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y)
{ return !(__y < __x); }
/// Returns !(x < y)
- template<class _Key, class _Compare, class _Alloc>
+ template<typename _Key, typename _Compare, typename _Alloc>
inline bool
operator>=(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y)
{ return !(__x < __y); }
/// See std::set::swap().
- template<class _Key, class _Compare, class _Alloc>
+ template<typename _Key, typename _Compare, typename _Alloc>
inline void
swap(set<_Key, _Compare, _Alloc>& __x, set<_Key, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Key, typename _Compare, typename _Alloc>
+ inline void
+ swap(set<_Key, _Compare, _Alloc>&& __x, set<_Key, _Compare, _Alloc>& __y)
+ { __x.swap(__y); }
+
+ template<typename _Key, typename _Compare, typename _Alloc>
+ inline void
+ swap(set<_Key, _Compare, _Alloc>& __x, set<_Key, _Compare, _Alloc>&& __y)
+ { __x.swap(__y); }
+#endif
+
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _STL_SET_H */
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 8437c9a9952..1b9743f1b4e 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -400,16 +400,25 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_Rb_tree_node_base _M_header;
size_type _M_node_count; // Keeps track of size of tree.
- _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(),
- const _Key_compare& __comp = _Key_compare())
- : _Node_allocator(__a), _M_key_compare(__comp), _M_header(),
+ _Rb_tree_impl()
+ : _Node_allocator(), _M_key_compare(), _M_header(),
_M_node_count(0)
+ { _M_initialize(); }
+
+ _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a)
+ : _Node_allocator(__a), _M_key_compare(__comp), _M_header(),
+ _M_node_count(0)
+ { _M_initialize(); }
+
+ private:
+ void
+ _M_initialize()
{
this->_M_header._M_color = _S_red;
this->_M_header._M_parent = 0;
this->_M_header._M_left = &this->_M_header;
this->_M_header._M_right = &this->_M_header;
- }
+ }
};
// Specialization for _Comparison types that are not capable of
@@ -421,16 +430,25 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_Rb_tree_node_base _M_header;
size_type _M_node_count; // Keeps track of size of tree.
- _Rb_tree_impl(const _Node_allocator& __a = _Node_allocator(),
- const _Key_compare& __comp = _Key_compare())
+ _Rb_tree_impl()
+ : _Node_allocator(), _M_key_compare(), _M_header(),
+ _M_node_count(0)
+ { _M_initialize(); }
+
+ _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a)
: _Node_allocator(__a), _M_key_compare(__comp), _M_header(),
_M_node_count(0)
- {
+ { _M_initialize(); }
+
+ private:
+ void
+ _M_initialize()
+ {
this->_M_header._M_color = _S_red;
this->_M_header._M_parent = 0;
this->_M_header._M_left = &this->_M_header;
this->_M_header._M_right = &this->_M_header;
- }
+ }
};
_Rb_tree_impl<_Compare> _M_impl;
@@ -571,19 +589,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
public:
// allocation/deallocation
- _Rb_tree()
- { }
+ _Rb_tree() { }
- _Rb_tree(const _Compare& __comp)
- : _M_impl(allocator_type(), __comp)
- { }
+ _Rb_tree(const _Compare& __comp,
+ const allocator_type& __a = allocator_type())
+ : _M_impl(__comp, __a) { }
- _Rb_tree(const _Compare& __comp, const allocator_type& __a)
- : _M_impl(__a, __comp)
- { }
-
- _Rb_tree(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x)
- : _M_impl(__x._M_get_Node_allocator(), __x._M_impl._M_key_compare)
+ _Rb_tree(const _Rb_tree& __x)
+ : _M_impl(__x._M_impl._M_key_compare, __x._M_get_Node_allocator())
{
if (__x._M_root() != 0)
{
@@ -597,8 +610,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
~_Rb_tree()
{ _M_erase(_M_begin()); }
- _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
- operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x);
+ _Rb_tree&
+ operator=(const _Rb_tree& __x);
// Accessors.
_Compare
@@ -659,7 +672,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{ return get_allocator().max_size(); }
void
- swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t);
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(_Rb_tree&& __t);
+#else
+ swap(_Rb_tree& __t);
+#endif
// Insert/erase.
pair<iterator, bool>
@@ -1060,7 +1077,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
typename _Compare, typename _Alloc>
void
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&& __t)
+#else
swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t)
+#endif
{
if (_M_root() == 0)
{
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 93db4138bdd..2f3384d8cc1 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -84,6 +84,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
+
+ _Vector_impl()
+ : _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0)
+ { }
+
_Vector_impl(_Tp_alloc_type const& __a)
: _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
{ }
@@ -104,9 +109,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
get_allocator() const
{ return allocator_type(_M_get_Tp_allocator()); }
+ _Vector_base()
+ : _M_impl() { }
+
_Vector_base(const allocator_type& __a)
- : _M_impl(__a)
- { }
+ : _M_impl(__a) { }
_Vector_base(size_t __n, const allocator_type& __a)
: _M_impl(__a)
@@ -194,15 +201,22 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
/**
* @brief Default constructor creates no elements.
*/
+ vector()
+ : _Base() { }
+
+ /**
+ * @brief Creates a %vector with no elements.
+ * @param a An allocator object.
+ */
explicit
- vector(const allocator_type& __a = allocator_type())
- : _Base(__a)
- { }
+ vector(const allocator_type& __a)
+ : _Base(__a) { }
/**
- * @brief Create a %vector with copies of an exemplar element.
+ * @brief Creates a %vector with copies of an exemplar element.
* @param n The number of elements to initially create.
* @param value An element to copy.
+ * @param a An allocator.
*
* This constructor fills the %vector with @a n copies of @a value.
*/
@@ -229,10 +243,24 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
_M_get_Tp_allocator());
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief %Vector move constructor.
+ * @param x A %vector of identical element and allocator types.
+ *
+ * The newly-created %vector contains the exact contents of @a x.
+ * The contents of @a x are a valid, but unspecified %vector.
+ */
+ vector(vector&& __x)
+ : _Base(__x._M_get_Tp_allocator())
+ { this->swap(__x); }
+#endif
+
/**
* @brief Builds a %vector from a range.
* @param first An input iterator.
* @param last An input iterator.
+ * @param a An allocator.
*
* Create a %vector consisting of copies of the elements from
* [first,last).
@@ -275,6 +303,22 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
vector&
operator=(const vector& __x);
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief %Vector move assignment operator.
+ * @param x A %vector of identical element and allocator types.
+ *
+ * The contents of @a x are moved into this %vector (without copying).
+ * @a x is a valid, but unspecified %vector.
+ */
+ vector&
+ operator=(vector&& __x)
+ {
+ this->swap(__x);
+ return *this;
+ }
+#endif
+
/**
* @brief Assigns a given value to a %vector.
* @param n Number of elements to be assigned.
@@ -721,7 +765,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* std::swap(v1,v2) will feed to this function.
*/
void
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(vector&& __x)
+#else
swap(vector& __x)
+#endif
{
std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
@@ -1006,6 +1054,18 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
{ __x.swap(__y); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(vector<_Tp, _Alloc>&& __x, vector<_Tp, _Alloc>& __y)
+ { __x.swap(__y); }
+
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>&& __y)
+ { __x.swap(__y); }
+#endif
+
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _STL_VECTOR_H */
diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h
index d488f1587d8..46e4b6bf09e 100644
--- a/libstdc++-v3/include/debug/debug.h
+++ b/libstdc++-v3/include/debug/debug.h
@@ -69,8 +69,10 @@ namespace __gnu_debug
# define __glibcxx_requires_valid_range(_First,_Last)
# define __glibcxx_requires_sorted(_First,_Last)
# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred)
-# define __glibcxx_requires_partitioned(_First,_Last,_Value)
-# define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred)
+# define __glibcxx_requires_partitioned_lower(_First,_Last,_Value)
+# define __glibcxx_requires_partitioned_upper(_First,_Last,_Value)
+# define __glibcxx_requires_partitioned_lower_pred(_First,_Last,_Value,_Pred)
+# define __glibcxx_requires_partitioned_upper_pred(_First,_Last,_Value,_Pred)
# define __glibcxx_requires_heap(_First,_Last)
# define __glibcxx_requires_heap_pred(_First,_Last,_Pred)
# define __glibcxx_requires_nonempty()
@@ -123,10 +125,14 @@ namespace std
__glibcxx_check_sorted(_First,_Last)
# define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) \
__glibcxx_check_sorted_pred(_First,_Last,_Pred)
-# define __glibcxx_requires_partitioned(_First,_Last,_Value) \
- __glibcxx_check_partitioned(_First,_Last,_Value)
-# define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) \
- __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred)
+# define __glibcxx_requires_partitioned_lower(_First,_Last,_Value) \
+ __glibcxx_check_partitioned_lower(_First,_Last,_Value)
+# define __glibcxx_requires_partitioned_upper(_First,_Last,_Value) \
+ __glibcxx_check_partitioned_upper(_First,_Last,_Value)
+# define __glibcxx_requires_partitioned_lower_pred(_First,_Last,_Value,_Pred) \
+ __glibcxx_check_partitioned_lower_pred(_First,_Last,_Value,_Pred)
+# define __glibcxx_requires_partitioned_upper_pred(_First,_Last,_Value,_Pred) \
+ __glibcxx_check_partitioned_upper_pred(_First,_Last,_Value,_Pred)
# define __glibcxx_requires_heap(_First,_Last) \
__glibcxx_check_heap(_First,_Last)
# define __glibcxx_requires_heap_pred(_First,_Last,_Pred) \
diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque
index 2bf4a19cf8b..56db8ee2b00 100644
--- a/libstdc++-v3/include/debug/deque
+++ b/libstdc++-v3/include/debug/deque
@@ -1,6 +1,6 @@
// Debugging deque implementation -*- C++ -*-
-// Copyright (C) 2003, 2004, 2005
+// Copyright (C) 2003, 2004, 2005, 2006, 2007
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -84,20 +84,37 @@ namespace __debug
: _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a)
{ }
- deque(const deque<_Tp,_Allocator>& __x) : _Base(__x), _Safe_base() { }
+ deque(const deque& __x)
+ : _Base(__x), _Safe_base() { }
- deque(const _Base& __x) : _Base(__x), _Safe_base() { }
+ deque(const _Base& __x)
+ : _Base(__x), _Safe_base() { }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ deque(deque&& __x)
+ : _Base(__x), _Safe_base()
+ { this->_M_swap(__x); }
+#endif
~deque() { }
- deque<_Tp,_Allocator>&
- operator=(const deque<_Tp,_Allocator>& __x)
+ deque&
+ operator=(const deque& __x)
{
*static_cast<_Base*>(this) = __x;
this->_M_invalidate_all();
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ deque&
+ operator=(deque&& __x)
+ {
+ swap(__x);
+ return *this;
+ }
+#endif
+
template<class _InputIterator>
void
assign(_InputIterator __first, _InputIterator __last)
@@ -329,7 +346,11 @@ namespace __debug
}
void
- swap(deque<_Tp,_Allocator>& __x)
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(deque&& __x)
+#else
+ swap(deque& __x)
+#endif
{
_Base::swap(__x);
this->_M_swap(__x);
@@ -363,7 +384,8 @@ namespace __debug
template<typename _Tp, typename _Alloc>
inline bool
- operator<(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs)
+ operator<(const deque<_Tp, _Alloc>& __lhs,
+ const deque<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() < __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
@@ -380,13 +402,27 @@ namespace __debug
template<typename _Tp, typename _Alloc>
inline bool
- operator>(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs)
+ operator>(const deque<_Tp, _Alloc>& __lhs,
+ const deque<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() > __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline void
swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs)
{ __lhs.swap(__rhs); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(deque<_Tp, _Alloc>&& __lhs, deque<_Tp, _Alloc>& __rhs)
+ { __lhs.swap(__rhs); }
+
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>&& __rhs)
+ { __lhs.swap(__rhs); }
+#endif
+
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/debug/functions.h b/libstdc++-v3/include/debug/functions.h
index ee7037fad06..15c21541b28 100644
--- a/libstdc++-v3/include/debug/functions.h
+++ b/libstdc++-v3/include/debug/functions.h
@@ -266,8 +266,8 @@ namespace __gnu_debug
// Determine if a sequence is partitioned w.r.t. this element.
template<typename _ForwardIterator, typename _Tp>
inline bool
- __check_partitioned(_ForwardIterator __first, _ForwardIterator __last,
- const _Tp& __value)
+ __check_partitioned_lower(_ForwardIterator __first,
+ _ForwardIterator __last, const _Tp& __value)
{
while (__first != __last && *__first < __value)
++__first;
@@ -276,15 +276,41 @@ namespace __gnu_debug
return __first == __last;
}
+ template<typename _ForwardIterator, typename _Tp>
+ inline bool
+ __check_partitioned_upper(_ForwardIterator __first,
+ _ForwardIterator __last, const _Tp& __value)
+ {
+ while (__first != __last && !(__value < *__first))
+ ++__first;
+ while (__first != __last && __value < *__first)
+ ++__first;
+ return __first == __last;
+ }
+
// Determine if a sequence is partitioned w.r.t. this element.
template<typename _ForwardIterator, typename _Tp, typename _Pred>
inline bool
- __check_partitioned(_ForwardIterator __first, _ForwardIterator __last,
- const _Tp& __value, _Pred __pred)
+ __check_partitioned_lower(_ForwardIterator __first,
+ _ForwardIterator __last, const _Tp& __value,
+ _Pred __pred)
+ {
+ while (__first != __last && bool(__pred(*__first, __value)))
+ ++__first;
+ while (__first != __last && !bool(__pred(*__first, __value)))
+ ++__first;
+ return __first == __last;
+ }
+
+ template<typename _ForwardIterator, typename _Tp, typename _Pred>
+ inline bool
+ __check_partitioned_upper(_ForwardIterator __first,
+ _ForwardIterator __last, const _Tp& __value,
+ _Pred __pred)
{
- while (__first != __last && __pred(*__first, __value))
+ while (__first != __last && !bool(__pred(__value, *__first)))
++__first;
- while (__first != __last && !__pred(*__first, __value))
+ while (__first != __last && bool(__pred(__value, *__first)))
++__first;
return __first == __last;
}
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index 485df086551..f30917b2ce4 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -1,6 +1,6 @@
// Debugging list implementation -*- C++ -*-
-// Copyright (C) 2003, 2004, 2005, 2006
+// Copyright (C) 2003, 2004, 2005, 2006, 2007
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -113,9 +113,17 @@ namespace __debug
{ }
- list(const list& __x) : _Base(__x), _Safe_base() { }
+ list(const list& __x)
+ : _Base(__x), _Safe_base() { }
- list(const _Base& __x) : _Base(__x), _Safe_base() { }
+ list(const _Base& __x)
+ : _Base(__x), _Safe_base() { }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ list(list&& __x)
+ : _Base(__x), _Safe_base()
+ { this->_M_swap(__x); }
+#endif
~list() { }
@@ -127,6 +135,15 @@ namespace __debug
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ list&
+ operator=(list&& __x)
+ {
+ swap(__x);
+ return *this;
+ }
+#endif
+
template<class _InputIterator>
void
assign(_InputIterator __first, _InputIterator __last)
@@ -311,7 +328,11 @@ namespace __debug
}
void
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(list&& __x)
+#else
swap(list& __x)
+#endif
{
_Base::swap(__x);
this->_M_swap(__x);
@@ -502,38 +523,57 @@ namespace __debug
template<typename _Tp, typename _Alloc>
inline bool
- operator==(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
+ operator==(const list<_Tp, _Alloc>& __lhs,
+ const list<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() == __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
- operator!=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
+ operator!=(const list<_Tp, _Alloc>& __lhs,
+ const list<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() != __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
- operator<(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
+ operator<(const list<_Tp, _Alloc>& __lhs,
+ const list<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() < __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
- operator<=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
+ operator<=(const list<_Tp, _Alloc>& __lhs,
+ const list<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() <= __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
- operator>=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
+ operator>=(const list<_Tp, _Alloc>& __lhs,
+ const list<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() >= __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline bool
- operator>(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs)
+ operator>(const list<_Tp, _Alloc>& __lhs,
+ const list<_Tp, _Alloc>& __rhs)
{ return __lhs._M_base() > __rhs._M_base(); }
template<typename _Tp, typename _Alloc>
inline void
swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
{ __lhs.swap(__rhs); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(list<_Tp, _Alloc>&& __lhs, list<_Tp, _Alloc>& __rhs)
+ { __lhs.swap(__rhs); }
+
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>&& __rhs)
+ { __lhs.swap(__rhs); }
+#endif
+
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/debug/macros.h b/libstdc++-v3/include/debug/macros.h
index ce4091924b1..4f4a0ccc9bd 100644
--- a/libstdc++-v3/include/debug/macros.h
+++ b/libstdc++-v3/include/debug/macros.h
@@ -173,20 +173,41 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(_First, _Last, _Pred), \
/** Verify that the iterator range [_First, _Last) is partitioned
w.r.t. the value _Value. */
-#define __glibcxx_check_partitioned(_First,_Last,_Value) \
+#define __glibcxx_check_partitioned_lower(_First,_Last,_Value) \
__glibcxx_check_valid_range(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned(_First, _Last, \
+_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower(_First, _Last, \
_Value), \
_M_message(__gnu_debug::__msg_unpartitioned) \
._M_iterator(_First, #_First) \
._M_iterator(_Last, #_Last) \
._M_string(#_Value))
+#define __glibcxx_check_partitioned_upper(_First,_Last,_Value) \
+__glibcxx_check_valid_range(_First,_Last); \
+_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper(_First, _Last, \
+ _Value), \
+ _M_message(__gnu_debug::__msg_unpartitioned) \
+ ._M_iterator(_First, #_First) \
+ ._M_iterator(_Last, #_Last) \
+ ._M_string(#_Value))
+
+/** Verify that the iterator range [_First, _Last) is partitioned
+ w.r.t. the value _Value and predicate _Pred. */
+#define __glibcxx_check_partitioned_lower_pred(_First,_Last,_Value,_Pred) \
+__glibcxx_check_valid_range(_First,_Last); \
+_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower(_First, _Last, \
+ _Value, _Pred), \
+ _M_message(__gnu_debug::__msg_unpartitioned_pred) \
+ ._M_iterator(_First, #_First) \
+ ._M_iterator(_Last, #_Last) \
+ ._M_string(#_Pred) \
+ ._M_string(#_Value))
+
/** Verify that the iterator range [_First, _Last) is partitioned
w.r.t. the value _Value and predicate _Pred. */
-#define __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) \
+#define __glibcxx_check_partitioned_upper_pred(_First,_Last,_Value,_Pred) \
__glibcxx_check_valid_range(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned(_First, _Last, \
+_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper(_First, _Last, \
_Value, _Pred), \
_M_message(__gnu_debug::__msg_unpartitioned_pred) \
._M_iterator(_First, #_First) \
diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h
index d6195208664..5e1312a8ac3 100644
--- a/libstdc++-v3/include/debug/map.h
+++ b/libstdc++-v3/include/debug/map.h
@@ -1,6 +1,6 @@
// Debugging map implementation -*- C++ -*-
-// Copyright (C) 2003, 2004, 2005
+// Copyright (C) 2003, 2004, 2005, 2006, 2007
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -88,21 +88,37 @@ namespace __debug
: _Base(__gnu_debug::__check_valid_range(__first, __last), __last,
__comp, __a), _Safe_base() { }
- map(const map<_Key,_Tp,_Compare,_Allocator>& __x)
+ map(const map& __x)
: _Base(__x), _Safe_base() { }
- map(const _Base& __x) : _Base(__x), _Safe_base() { }
+ map(const _Base& __x)
+ : _Base(__x), _Safe_base() { }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ map(map&& __x)
+ : _Base(__x), _Safe_base()
+ { this->_M_swap(__x); }
+#endif
~map() { }
- map<_Key,_Tp,_Compare,_Allocator>&
- operator=(const map<_Key,_Tp,_Compare,_Allocator>& __x)
+ map&
+ operator=(const map& __x)
{
*static_cast<_Base*>(this) = __x;
this->_M_invalidate_all();
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ map&
+ operator=(map&& __x)
+ {
+ swap(__x);
+ return *this;
+ }
+#endif
+
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 133. map missing get_allocator()
using _Base::get_allocator;
@@ -210,7 +226,11 @@ namespace __debug
}
void
- swap(map<_Key,_Tp,_Compare,_Allocator>& __x)
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(map&& __x)
+#else
+ swap(map& __x)
+#endif
{
_Base::swap(__x);
this->_M_swap(__x);
@@ -287,47 +307,71 @@ namespace __debug
}
};
- template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
inline bool
- operator==(const map<_Key,_Tp,_Compare,_Allocator>& __lhs,
- const map<_Key,_Tp,_Compare,_Allocator>& __rhs)
+ operator==(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() == __rhs._M_base(); }
- template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
inline bool
- operator!=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs,
- const map<_Key,_Tp,_Compare,_Allocator>& __rhs)
+ operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() != __rhs._M_base(); }
- template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
inline bool
- operator<(const map<_Key,_Tp,_Compare,_Allocator>& __lhs,
- const map<_Key,_Tp,_Compare,_Allocator>& __rhs)
+ operator<(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() < __rhs._M_base(); }
- template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
inline bool
- operator<=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs,
- const map<_Key,_Tp,_Compare,_Allocator>& __rhs)
+ operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() <= __rhs._M_base(); }
- template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
inline bool
- operator>=(const map<_Key,_Tp,_Compare,_Allocator>& __lhs,
- const map<_Key,_Tp,_Compare,_Allocator>& __rhs)
+ operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() >= __rhs._M_base(); }
- template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
inline bool
- operator>(const map<_Key,_Tp,_Compare,_Allocator>& __lhs,
- const map<_Key,_Tp,_Compare,_Allocator>& __rhs)
+ operator>(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() > __rhs._M_base(); }
- template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
inline void
- swap(map<_Key,_Tp,_Compare,_Allocator>& __lhs,
- map<_Key,_Tp,_Compare,_Allocator>& __rhs)
+ swap(map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ __lhs.swap(__rhs); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline void
+ swap(map<_Key, _Tp, _Compare, _Allocator>&& __lhs,
+ map<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ { __lhs.swap(__rhs); }
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline void
+ swap(map<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ map<_Key, _Tp, _Compare, _Allocator>&& __rhs)
+ { __lhs.swap(__rhs); }
+#endif
+
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h
index 5e4962f9660..4f0b7935e59 100644
--- a/libstdc++-v3/include/debug/multimap.h
+++ b/libstdc++-v3/include/debug/multimap.h
@@ -1,6 +1,6 @@
// Debugging multimap implementation -*- C++ -*-
-// Copyright (C) 2003, 2004, 2005
+// Copyright (C) 2003, 2004, 2005, 2006, 2007
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -47,7 +47,8 @@ namespace __debug
typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
class multimap
: public _GLIBCXX_STD_D::multimap<_Key, _Tp, _Compare, _Allocator>,
- public __gnu_debug::_Safe_sequence<multimap<_Key,_Tp,_Compare,_Allocator> >
+ public __gnu_debug::_Safe_sequence<multimap<_Key, _Tp,
+ _Compare, _Allocator> >
{
typedef _GLIBCXX_STD_D::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<multimap> _Safe_base;
@@ -88,21 +89,37 @@ namespace __debug
: _Base(__gnu_debug::__check_valid_range(__first, __last), __last,
__comp, __a) { }
- multimap(const multimap<_Key,_Tp,_Compare,_Allocator>& __x)
+ multimap(const multimap& __x)
: _Base(__x), _Safe_base() { }
- multimap(const _Base& __x) : _Base(__x), _Safe_base() { }
+ multimap(const _Base& __x)
+ : _Base(__x), _Safe_base() { }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ multimap(multimap&& __x)
+ : _Base(__x), _Safe_base()
+ { this->_M_swap(__x); }
+#endif
~multimap() { }
- multimap<_Key,_Tp,_Compare,_Allocator>&
- operator=(const multimap<_Key,_Tp,_Compare,_Allocator>& __x)
+ multimap&
+ operator=(const multimap& __x)
{
*static_cast<_Base*>(this) = __x;
this->_M_invalidate_all();
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ multimap&
+ operator=(multimap&& __x)
+ {
+ swap(__x);
+ return *this;
+ }
+#endif
+
using _Base::get_allocator;
// iterators:
@@ -197,7 +214,11 @@ namespace __debug
}
void
- swap(multimap<_Key,_Tp,_Compare,_Allocator>& __x)
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(multimap&& __x)
+#else
+ swap(multimap& __x)
+#endif
{
_Base::swap(__x);
this->_M_swap(__x);
@@ -274,47 +295,71 @@ namespace __debug
}
};
- template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
inline bool
- operator==(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
- const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
+ operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() == __rhs._M_base(); }
- template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
inline bool
- operator!=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
- const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
+ operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() != __rhs._M_base(); }
- template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
inline bool
- operator<(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
- const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
+ operator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() < __rhs._M_base(); }
- template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
inline bool
- operator<=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
- const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
+ operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() <= __rhs._M_base(); }
- template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
inline bool
- operator>=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
- const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
+ operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() >= __rhs._M_base(); }
- template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
inline bool
- operator>(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
- const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
+ operator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() > __rhs._M_base(); }
- template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
inline void
- swap(multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
- multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
+ swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ __lhs.swap(__rhs); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline void
+ swap(multimap<_Key, _Tp, _Compare, _Allocator>&& __lhs,
+ multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
+ { __lhs.swap(__rhs); }
+
+ template<typename _Key, typename _Tp,
+ typename _Compare, typename _Allocator>
+ inline void
+ swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
+ multimap<_Key, _Tp, _Compare, _Allocator>&& __rhs)
+ { __lhs.swap(__rhs); }
+#endif
+
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h
index 2ca534a6599..5ec99452c4e 100644
--- a/libstdc++-v3/include/debug/multiset.h
+++ b/libstdc++-v3/include/debug/multiset.h
@@ -1,6 +1,6 @@
// Debugging multiset implementation -*- C++ -*-
-// Copyright (C) 2003, 2004, 2005
+// Copyright (C) 2003, 2004, 2005, 2006, 2007
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -86,21 +86,37 @@ namespace __debug
: _Base(__gnu_debug::__check_valid_range(__first, __last), __last,
__comp, __a) { }
- multiset(const multiset<_Key,_Compare,_Allocator>& __x)
+ multiset(const multiset& __x)
: _Base(__x), _Safe_base() { }
- multiset(const _Base& __x) : _Base(__x), _Safe_base() { }
+ multiset(const _Base& __x)
+ : _Base(__x), _Safe_base() { }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ multiset(multiset&& __x)
+ : _Base(__x), _Safe_base()
+ { this->_M_swap(__x); }
+#endif
~multiset() { }
- multiset<_Key,_Compare,_Allocator>&
- operator=(const multiset<_Key,_Compare,_Allocator>& __x)
+ multiset&
+ operator=(const multiset& __x)
{
*static_cast<_Base*>(this) = __x;
this->_M_invalidate_all();
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ multiset&
+ operator=(multiset&& __x)
+ {
+ swap(__x);
+ return *this;
+ }
+#endif
+
using _Base::get_allocator;
// iterators:
@@ -195,7 +211,11 @@ namespace __debug
}
void
- swap(multiset<_Key,_Compare,_Allocator>& __x)
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(multiset&& __x)
+#else
+ swap(multiset& __x)
+#endif
{
_Base::swap(__x);
this->_M_swap(__x);
@@ -282,45 +302,60 @@ namespace __debug
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
- operator==(const multiset<_Key,_Compare,_Allocator>& __lhs,
- const multiset<_Key,_Compare,_Allocator>& __rhs)
+ operator==(const multiset<_Key, _Compare, _Allocator>& __lhs,
+ const multiset<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() == __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
- operator!=(const multiset<_Key,_Compare,_Allocator>& __lhs,
- const multiset<_Key,_Compare,_Allocator>& __rhs)
+ operator!=(const multiset<_Key, _Compare, _Allocator>& __lhs,
+ const multiset<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() != __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
- operator<(const multiset<_Key,_Compare,_Allocator>& __lhs,
- const multiset<_Key,_Compare,_Allocator>& __rhs)
+ operator<(const multiset<_Key, _Compare, _Allocator>& __lhs,
+ const multiset<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() < __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
- operator<=(const multiset<_Key,_Compare,_Allocator>& __lhs,
- const multiset<_Key,_Compare,_Allocator>& __rhs)
+ operator<=(const multiset<_Key, _Compare, _Allocator>& __lhs,
+ const multiset<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() <= __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
- operator>=(const multiset<_Key,_Compare,_Allocator>& __lhs,
- const multiset<_Key,_Compare,_Allocator>& __rhs)
+ operator>=(const multiset<_Key, _Compare, _Allocator>& __lhs,
+ const multiset<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() >= __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
- operator>(const multiset<_Key,_Compare,_Allocator>& __lhs,
- const multiset<_Key,_Compare,_Allocator>& __rhs)
+ operator>(const multiset<_Key, _Compare, _Allocator>& __lhs,
+ const multiset<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() > __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
void
- swap(multiset<_Key,_Compare,_Allocator>& __x,
- multiset<_Key,_Compare,_Allocator>& __y)
+ swap(multiset<_Key, _Compare, _Allocator>& __x,
+ multiset<_Key, _Compare, _Allocator>& __y)
{ return __x.swap(__y); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Key, typename _Compare, typename _Allocator>
+ void
+ swap(multiset<_Key, _Compare, _Allocator>&& __x,
+ multiset<_Key, _Compare, _Allocator>& __y)
+ { return __x.swap(__y); }
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ void
+ swap(multiset<_Key, _Compare, _Allocator>& __x,
+ multiset<_Key, _Compare, _Allocator>&& __y)
+ { return __x.swap(__y); }
+#endif
+
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h
index d40d319855b..5610cab02a0 100644
--- a/libstdc++-v3/include/debug/set.h
+++ b/libstdc++-v3/include/debug/set.h
@@ -1,6 +1,6 @@
// Debugging set implementation -*- C++ -*-
-// Copyright (C) 2003, 2004, 2005
+// Copyright (C) 2003, 2004, 2005, 2006, 2007
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -49,7 +49,7 @@ namespace __debug
: public _GLIBCXX_STD_D::set<_Key,_Compare,_Allocator>,
public __gnu_debug::_Safe_sequence<set<_Key, _Compare, _Allocator> >
{
- typedef _GLIBCXX_STD_D::set<_Key,_Compare,_Allocator> _Base;
+ typedef _GLIBCXX_STD_D::set<_Key, _Compare, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<set> _Safe_base;
public:
@@ -86,21 +86,37 @@ namespace __debug
: _Base(__gnu_debug::__check_valid_range(__first, __last), __last,
__comp, __a) { }
- set(const set<_Key,_Compare,_Allocator>& __x)
+ set(const set& __x)
: _Base(__x), _Safe_base() { }
- set(const _Base& __x) : _Base(__x), _Safe_base() { }
+ set(const _Base& __x)
+ : _Base(__x), _Safe_base() { }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ set(set&& __x)
+ : _Base(__x), _Safe_base()
+ { this->_M_swap(__x); }
+#endif
~set() { }
- set<_Key,_Compare,_Allocator>&
- operator=(const set<_Key,_Compare,_Allocator>& __x)
+ set&
+ operator=(const set& __x)
{
*static_cast<_Base*>(this) = __x;
this->_M_invalidate_all();
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ set&
+ operator=(set&& __x)
+ {
+ swap(__x);
+ return *this;
+ }
+#endif
+
using _Base::get_allocator;
// iterators:
@@ -200,7 +216,11 @@ namespace __debug
}
void
- swap(set<_Key,_Compare,_Allocator>& __x)
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(set&& __x)
+#else
+ swap(set& __x)
+#endif
{
_Base::swap(__x);
this->_M_swap(__x);
@@ -287,45 +307,60 @@ namespace __debug
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
- operator==(const set<_Key,_Compare,_Allocator>& __lhs,
- const set<_Key,_Compare,_Allocator>& __rhs)
+ operator==(const set<_Key, _Compare, _Allocator>& __lhs,
+ const set<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() == __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
- operator!=(const set<_Key,_Compare,_Allocator>& __lhs,
- const set<_Key,_Compare,_Allocator>& __rhs)
+ operator!=(const set<_Key, _Compare, _Allocator>& __lhs,
+ const set<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() != __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
- operator<(const set<_Key,_Compare,_Allocator>& __lhs,
- const set<_Key,_Compare,_Allocator>& __rhs)
+ operator<(const set<_Key, _Compare, _Allocator>& __lhs,
+ const set<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() < __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
- operator<=(const set<_Key,_Compare,_Allocator>& __lhs,
- const set<_Key,_Compare,_Allocator>& __rhs)
+ operator<=(const set<_Key, _Compare, _Allocator>& __lhs,
+ const set<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() <= __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
- operator>=(const set<_Key,_Compare,_Allocator>& __lhs,
- const set<_Key,_Compare,_Allocator>& __rhs)
+ operator>=(const set<_Key, _Compare, _Allocator>& __lhs,
+ const set<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() >= __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
inline bool
- operator>(const set<_Key,_Compare,_Allocator>& __lhs,
- const set<_Key,_Compare,_Allocator>& __rhs)
+ operator>(const set<_Key, _Compare, _Allocator>& __lhs,
+ const set<_Key, _Compare, _Allocator>& __rhs)
{ return __lhs._M_base() > __rhs._M_base(); }
template<typename _Key, typename _Compare, typename _Allocator>
void
- swap(set<_Key,_Compare,_Allocator>& __x,
- set<_Key,_Compare,_Allocator>& __y)
+ swap(set<_Key, _Compare, _Allocator>& __x,
+ set<_Key, _Compare, _Allocator>& __y)
{ return __x.swap(__y); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Key, typename _Compare, typename _Allocator>
+ void
+ swap(set<_Key, _Compare, _Allocator>&& __x,
+ set<_Key, _Compare, _Allocator>& __y)
+ { return __x.swap(__y); }
+
+ template<typename _Key, typename _Compare, typename _Allocator>
+ void
+ swap(set<_Key, _Compare, _Allocator>& __x,
+ set<_Key, _Compare, _Allocator>&& __y)
+ { return __x.swap(__y); }
+#endif
+
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index 1365525fef2..91e515a8e9b 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -1,6 +1,6 @@
// Debugging vector implementation -*- C++ -*-
-// Copyright (C) 2003, 2004, 2005
+// Copyright (C) 2003, 2004, 2005, 2006, 2007
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -91,17 +91,26 @@ namespace __debug
_M_guaranteed_capacity(0)
{ _M_update_guaranteed_capacity(); }
- vector(const vector<_Tp,_Allocator>& __x)
+ vector(const vector& __x)
: _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { }
/// Construction from a release-mode vector
vector(const _Base& __x)
: _Base(__x), _Safe_base(), _M_guaranteed_capacity(__x.size()) { }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ vector(vector&& __x)
+ : _Base(__x), _Safe_base(), _M_guaranteed_capacity(this->size())
+ {
+ this->_M_swap(__x);
+ __x._M_guaranteed_capacity = 0;
+ }
+#endif
+
~vector() { }
- vector<_Tp,_Allocator>&
- operator=(const vector<_Tp,_Allocator>& __x)
+ vector&
+ operator=(const vector& __x)
{
static_cast<_Base&>(*this) = __x;
this->_M_invalidate_all();
@@ -109,6 +118,15 @@ namespace __debug
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ vector&
+ operator=(vector&& __x)
+ {
+ swap(__x);
+ return *this;
+ }
+#endif
+
template<typename _InputIterator>
void
assign(_InputIterator __first, _InputIterator __last)
@@ -335,7 +353,11 @@ namespace __debug
}
void
- swap(vector<_Tp,_Allocator>& __x)
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ swap(vector&& __x)
+#else
+ swap(vector& __x)
+#endif
{
_Base::swap(__x);
this->_M_swap(__x);
@@ -417,6 +439,19 @@ namespace __debug
inline void
swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
{ __lhs.swap(__rhs); }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs)
+ { __lhs.swap(__rhs); }
+
+ template<typename _Tp, typename _Alloc>
+ inline void
+ swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs)
+ { __lhs.swap(__rhs); }
+#endif
+
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/ext/concurrence.h b/libstdc++-v3/include/ext/concurrence.h
index 3556acfd3a4..765b93dbdc2 100644
--- a/libstdc++-v3/include/ext/concurrence.h
+++ b/libstdc++-v3/include/ext/concurrence.h
@@ -81,6 +81,22 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
{ return "__gnu_cxx::__concurrence_unlock_error"; }
};
+ class __concurrence_broadcast_error : public std::exception
+ {
+ public:
+ virtual char const*
+ what() const throw()
+ { return "__gnu_cxx::__concurrence_broadcast_error"; }
+ };
+
+ class __concurrence_wait_error : public std::exception
+ {
+ public:
+ virtual char const*
+ what() const throw()
+ { return "__gnu_cxx::__concurrence_wait_error"; }
+ };
+
// Substitute for concurrence_error object in the case of -fno-exceptions.
inline void
__throw_concurrence_lock_error()
@@ -102,6 +118,28 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
#endif
}
+#ifdef __GTHREAD_HAS_COND
+ inline void
+ __throw_concurrence_broadcast_error()
+ {
+#if __EXCEPTIONS
+ throw __concurrence_broadcast_error();
+#else
+ __builtin_abort();
+#endif
+ }
+
+ inline void
+ __throw_concurrence_wait_error()
+ {
+#if __EXCEPTIONS
+ throw __concurrence_wait_error();
+#else
+ __builtin_abort();
+#endif
+ }
+#endif
+
class __mutex
{
private:
@@ -147,6 +185,9 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
}
#endif
}
+
+ __gthread_mutex_t* gthread_mutex(void)
+ { return &_M_mutex; }
};
class __recursive_mutex
@@ -194,6 +235,9 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
}
#endif
}
+
+ __gthread_recursive_mutex_t* gthread_recursive_mutex(void)
+ { return &_M_mutex; }
};
/// @brief Scoped lock idiom.
@@ -218,6 +262,66 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
{ _M_device.unlock(); }
};
+#ifdef __GTHREAD_HAS_COND
+ class __cond
+ {
+ private:
+ __gthread_cond_t _M_cond;
+
+ __cond(const __cond&);
+ __cond& operator=(const __cond&);
+
+ public:
+ __cond()
+ {
+#if __GTHREADS
+ if (__gthread_active_p())
+ {
+#if defined __GTHREAD_COND_INIT
+ __gthread_cond_t __tmp = __GTHREAD_COND_INIT;
+ _M_cond = __tmp;
+#else
+ __GTHREAD_MUTEX_INIT_FUNCTION(&_M_cond);
+#endif
+ }
+#endif
+ }
+
+ void broadcast()
+ {
+#if __GTHREADS
+ if (__gthread_active_p())
+ {
+ if (__gthread_cond_broadcast(&_M_cond) != 0)
+ __throw_concurrence_broadcast_error();
+ }
+#endif
+ }
+
+ void wait(__mutex *mutex)
+ {
+#if __GTHREADS
+ {
+ if (__gthread_cond_wait(&_M_cond, mutex->gthread_mutex()) != 0)
+ __throw_concurrence_wait_error();
+ }
+#endif
+ }
+
+ void wait_recursive(__recursive_mutex *mutex)
+ {
+#if __GTHREADS
+ {
+ if (__gthread_cond_wait_recursive(&_M_cond,
+ mutex->gthread_recursive_mutex())
+ != 0)
+ __throw_concurrence_wait_error();
+ }
+#endif
+ }
+ };
+#endif
+
_GLIBCXX_END_NAMESPACE
#endif
diff --git a/libstdc++-v3/include/ext/rc_string_base.h b/libstdc++-v3/include/ext/rc_string_base.h
index 7c0934a3084..49128aa2f82 100644
--- a/libstdc++-v3/include/ext/rc_string_base.h
+++ b/libstdc++-v3/include/ext/rc_string_base.h
@@ -37,6 +37,7 @@
#define _RC_STRING_BASE_H 1
#include <ext/atomicity.h>
+#include <bits/stl_iterator_base_funcs.h>
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
diff --git a/libstdc++-v3/include/ext/vstring_util.h b/libstdc++-v3/include/ext/vstring_util.h
index 390ef37fb3d..ab7cf3c3467 100644
--- a/libstdc++-v3/include/ext/vstring_util.h
+++ b/libstdc++-v3/include/ext/vstring_util.h
@@ -44,6 +44,8 @@
#include <bits/functexcept.h>
#include <bits/localefwd.h>
#include <bits/ostream_insert.h>
+#include <bits/stl_iterator.h>
+#include <ext/numeric_traits.h>
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
diff --git a/libstdc++-v3/include/parallel/algo.h b/libstdc++-v3/include/parallel/algo.h
index dcda79090b4..71b7bff7395 100644
--- a/libstdc++-v3/include/parallel/algo.h
+++ b/libstdc++-v3/include/parallel/algo.h
@@ -71,23 +71,24 @@ namespace __parallel
// Sequential fallback
template<typename InputIterator, typename Function>
inline Function
- for_each(InputIterator begin, InputIterator end, Function f, __gnu_parallel::sequential_tag)
- {
- return _GLIBCXX_STD_P::for_each<InputIterator, Function>(begin, end, f);
- }
+ for_each(InputIterator begin, InputIterator end, Function f,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::for_each(begin, end, f); }
// Sequential fallback for input iterator case
template<typename InputIterator, typename Function, typename IteratorTag>
Function
- for_each_switch(InputIterator begin, InputIterator end, Function f, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
- {
- return for_each<InputIterator, Function>(begin, end, f, __gnu_parallel::sequential_tag());
- }
+ for_each_switch(InputIterator begin, InputIterator 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)
+ for_each_switch(RandomAccessIterator begin, RandomAccessIterator 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) >= __gnu_parallel::Settings::for_each_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
{
@@ -96,26 +97,37 @@ namespace __parallel
return __gnu_parallel::for_each_template_random_access(begin, end, f, functionality, __gnu_parallel::dummy_reduct(), true, dummy, -1, parallelism_tag);
}
else
- return for_each<RandomAccessIterator, Function>(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 = __gnu_parallel::parallel_balanced)
+ 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);
+ }
- return for_each_switch(begin, end, f, iterator_category(), parallelism_tag);
+ 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());
}
// Sequential fallback
template<typename InputIterator, typename T>
inline InputIterator
- find(InputIterator begin, InputIterator end, const T& val, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::find<InputIterator, T>(begin, end, val); }
+ find(InputIterator begin, InputIterator end, const T& val,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::find(begin, end, val); }
// Sequential fallback for input iterator case
template<typename InputIterator, typename T, typename IteratorTag>
@@ -128,7 +140,8 @@ namespace __parallel
RandomAccessIterator
find_switch(RandomAccessIterator begin, RandomAccessIterator end, const T& val, random_access_iterator_tag)
{
- typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
+ typedef iterator_traits<RandomAccessIterator> traits_type;
+ typedef typename traits_type::value_type value_type;
if (_GLIBCXX_PARALLEL_CONDITION(true))
{
@@ -152,26 +165,26 @@ namespace __parallel
// Sequential fallback
template<typename InputIterator, typename Predicate>
inline InputIterator
- find_if(InputIterator begin, InputIterator end, Predicate pred, __gnu_parallel::sequential_tag)
- {
- return _GLIBCXX_STD_P::find_if<InputIterator, Predicate>(begin, end, pred);
- }
+ find_if(InputIterator begin, InputIterator end, Predicate pred,
+ __gnu_parallel::sequential_tag)
+ { 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);
- }
+ find_if_switch(InputIterator begin, InputIterator 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)
+ find_if_switch(RandomAccessIterator begin, RandomAccessIterator end,
+ Predicate pred, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(true))
- return __gnu_parallel::find_template(begin, end, begin, pred, __gnu_parallel::find_if_selector()).first;
+ return __gnu_parallel::find_template(begin, end, begin, pred,
+ __gnu_parallel::find_if_selector()).first;
else
return _GLIBCXX_STD_P::find_if(begin, end, pred);
}
@@ -189,10 +202,10 @@ namespace __parallel
// Sequential fallback
template<typename InputIterator, typename ForwardIterator>
inline InputIterator
- find_first_of(InputIterator begin1, InputIterator end1, ForwardIterator begin2, ForwardIterator end2, __gnu_parallel::sequential_tag)
- {
- return _GLIBCXX_STD_P::find_first_of(begin1, end1, begin2, end2);
- }
+ find_first_of(InputIterator begin1, InputIterator end1,
+ ForwardIterator begin2, ForwardIterator end2,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::find_first_of(begin1, end1, begin2, end2); }
// Sequential fallback
template<typename InputIterator, typename ForwardIterator,
@@ -201,24 +214,26 @@ namespace __parallel
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);
- }
+ { 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)
+ ForwardIterator begin2, ForwardIterator end2,
+ IteratorTag1, IteratorTag2)
{
- return find_first_of(begin1, end1, begin2, end2, __gnu_parallel::sequential_tag());
+ 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)
+ ForwardIterator begin2, ForwardIterator 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;
}
@@ -228,36 +243,42 @@ namespace __parallel
inline
InputIterator
find_first_of_switch(InputIterator begin1, InputIterator end1,
- ForwardIterator begin2, ForwardIterator end2, BinaryPredicate comp, IteratorTag1, IteratorTag2)
+ ForwardIterator begin2, ForwardIterator end2,
+ BinaryPredicate comp, IteratorTag1, IteratorTag2)
{
- return find_first_of(begin1, end1, begin2, end2, comp, __gnu_parallel::sequential_tag());
+ 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)
+ 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;
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,
+ iteratori_category(), iteratorf_category());
}
// Public interface, insert default comparator
template<typename InputIterator, typename ForwardIterator>
InputIterator
- find_first_of(InputIterator begin1, InputIterator end1, ForwardIterator begin2, ForwardIterator end2)
+ find_first_of(InputIterator begin1, InputIterator end1,
+ ForwardIterator begin2, ForwardIterator 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;
- 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<valuei_type, valuef_type>());
}
// Sequential fallback
@@ -265,33 +286,29 @@ namespace __parallel
inline OutputIterator
unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out,
__gnu_parallel::sequential_tag)
- {
- return _GLIBCXX_STD_P::unique_copy<InputIterator, OutputIterator>(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<InputIterator, OutputIterator, Predicate>(begin1, end1, out, pred);
- }
+ { 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);
- }
+ unique_copy_switch(InputIterator begin, InputIterator 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>
RandomAccessOutputIterator
- unique_copy_switch(RandomAccessIterator begin, RandomAccessIterator last, RandomAccessOutputIterator out,
- Predicate pred, random_access_iterator_tag, random_access_iterator_tag)
+ unique_copy_switch(RandomAccessIterator begin, RandomAccessIterator 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) > __gnu_parallel::Settings::unique_copy_minimal_n))
return __gnu_parallel::parallel_unique_copy(begin, last, out, pred);
@@ -325,7 +342,8 @@ namespace __parallel
typedef typename iteratori_traits::iterator_category iteratori_category;
typedef typename iteratoro_traits::iterator_category iteratoro_category;
- return unique_copy_switch(begin1, end1, out, pred, iteratori_category(), iteratoro_category());
+ return unique_copy_switch(begin1, end1, out, pred, iteratori_category(),
+ iteratoro_category());
}
// Sequential fallback
@@ -334,9 +352,7 @@ namespace __parallel
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);
- }
+ { return _GLIBCXX_STD_P::set_union(begin1, end1, begin2, end2, out); }
// Sequential fallback
template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Predicate>
@@ -344,16 +360,15 @@ namespace __parallel
set_union(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 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,
+ 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);
@@ -363,9 +378,11 @@ namespace __parallel
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,
- random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag)
+ set_union_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
+ RandomAccessIterator2 begin2, RandomAccessIterator2 end2,
+ OutputRandomAccessIterator 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) >= __gnu_parallel::Settings::set_union_minimal_n || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) >= __gnu_parallel::Settings::set_union_minimal_n))
return __gnu_parallel::parallel_set_union(begin1, end1, begin2, end2, result, pred);
@@ -376,7 +393,8 @@ namespace __parallel
// Public interface
template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
inline OutputIterator
- set_union(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator out)
+ 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;
@@ -387,8 +405,10 @@ namespace __parallel
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());
+ return set_union_switch(begin1, end1, begin2, end2, out,
+ __gnu_parallel::less<value1_type, value2_type>(),
+ iteratori1_category(), iteratori2_category(),
+ iteratoro_category());
}
// Public interface
@@ -405,7 +425,8 @@ namespace __parallel
typedef typename iteratoro_traits::iterator_category iteratoro_category;
return set_union_switch(begin1, end1, begin2, end2, out, pred,
- iteratori1_category(), iteratori2_category(), iteratoro_category());
+ iteratori1_category(), iteratori2_category(),
+ iteratoro_category());
}
// Sequential fallback.
@@ -423,40 +444,46 @@ namespace __parallel
inline OutputIterator
set_intersection(InputIterator1 begin1, InputIterator1 end1,
InputIterator2 begin2, InputIterator2 end2,
- OutputIterator out, Predicate pred, __gnu_parallel::sequential_tag)
+ 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)
+ 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);
+ 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,
- random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag)
+ set_intersection_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, RandomAccessIterator2 begin2, RandomAccessIterator2 end2, OutputRandomAccessIterator 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) >= __gnu_parallel::Settings::set_union_minimal_n || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) >= __gnu_parallel::Settings::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)
+ 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;
@@ -467,8 +494,10 @@ namespace __parallel
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());
+ 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>
@@ -484,7 +513,8 @@ namespace __parallel
typedef typename iteratoro_traits::iterator_category iteratoro_category;
return set_intersection_switch(begin1, end1, begin2, end2, out, pred,
- iteratori1_category(), iteratori2_category(), iteratoro_category());
+ iteratori1_category(), iteratori2_category(),
+ iteratoro_category());
}
// Sequential fallback
@@ -495,7 +525,8 @@ namespace __parallel
InputIterator2 begin2, InputIterator2 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
@@ -506,7 +537,8 @@ namespace __parallel
InputIterator2 begin2, InputIterator2 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
@@ -514,17 +546,15 @@ namespace __parallel
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);
+ 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,
- random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag)
+ set_symmetric_difference_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, RandomAccessIterator2 begin2, RandomAccessIterator2 end2, OutputRandomAccessIterator 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) >= __gnu_parallel::Settings::set_symmetric_difference_minimal_n || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) >= __gnu_parallel::Settings::set_symmetric_difference_minimal_n))
return __gnu_parallel::parallel_set_symmetric_difference(begin1, end1, begin2, end2, result, pred);
@@ -546,15 +576,16 @@ namespace __parallel
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());
+ return set_symmetric_difference_switch(begin1, end1, begin2, end2, out,
+ __gnu_parallel::less<value1_type, value2_type>(),
+ iteratori1_category(), iteratori2_category(),
+ iteratoro_category());
}
// 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)
+ 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;
@@ -563,22 +594,26 @@ namespace __parallel
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());
+ return set_symmetric_difference_switch(begin1, end1, begin2, end2, out,
+ pred, iteratori1_category(),
+ iteratori2_category(), iteratoro_category());
}
// 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);
- }
+ 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); }
// 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, __gnu_parallel::sequential_tag)
+ set_difference(InputIterator1 begin1, InputIterator1 end1,
+ InputIterator2 begin2, InputIterator2 end2,
+ OutputIterator out, Predicate pred,
+ __gnu_parallel::sequential_tag)
{
return _GLIBCXX_STD_P::set_difference(begin1, end1, begin2, end2, out, pred);
}
@@ -587,8 +622,10 @@ namespace __parallel
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)
+ 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);
}
@@ -597,9 +634,7 @@ namespace __parallel
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,
- random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag)
+ set_difference_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, RandomAccessIterator2 begin2, RandomAccessIterator2 end2, OutputRandomAccessIterator 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) >= __gnu_parallel::Settings::set_difference_minimal_n || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) >= __gnu_parallel::Settings::set_difference_minimal_n))
return __gnu_parallel::parallel_set_difference(begin1, end1, begin2, end2, result, pred);
@@ -610,7 +645,9 @@ namespace __parallel
// Public interface
template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
inline OutputIterator
- set_difference(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator out)
+ 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;
@@ -621,15 +658,18 @@ namespace __parallel
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());
+ return set_difference_switch(begin1, end1, begin2, end2, out,
+ __gnu_parallel::less<value1_type, value2_type>(),
+ iteratori1_category(), iteratori2_category(),
+ iteratoro_category());
}
// 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)
+ 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;
@@ -639,31 +679,32 @@ namespace __parallel
typedef typename iteratoro_traits::iterator_category iteratoro_category;
return set_difference_switch(begin1, end1, begin2, end2, out, pred,
- iteratori1_category(), iteratori2_category(), iteratoro_category());
+ iteratori1_category(), iteratori2_category(),
+ iteratoro_category());
}
// Sequential fallback
template<typename ForwardIterator>
inline ForwardIterator
- adjacent_find(ForwardIterator begin, ForwardIterator end, __gnu_parallel::sequential_tag)
- {
- return _GLIBCXX_STD_P::adjacent_find<ForwardIterator>(begin, end);
- }
+ adjacent_find(ForwardIterator begin, ForwardIterator end,
+ __gnu_parallel::sequential_tag)
+ { 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<ForwardIterator, BinaryPredicate>(begin, end, binary_pred);
- }
+ adjacent_find(ForwardIterator begin, ForwardIterator 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, random_access_iterator_tag)
+ adjacent_find_switch(RandomAccessIterator begin, RandomAccessIterator end,
+ random_access_iterator_tag)
{
- typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
+ typedef iterator_traits<RandomAccessIterator> traits_type;
+ typedef typename traits_type::value_type value_type;
if (_GLIBCXX_PARALLEL_CONDITION(true))
{
@@ -674,138 +715,173 @@ namespace __parallel
return spot;
}
else
- return adjacent_find<RandomAccessIterator>(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<ForwardIterator>(begin, end, __gnu_parallel::sequential_tag());
- }
+ { return adjacent_find(begin, end, __gnu_parallel::sequential_tag()); }
// Public interface
template<typename ForwardIterator>
inline ForwardIterator
adjacent_find(ForwardIterator begin, ForwardIterator end)
{
- return adjacent_find_switch(begin, end, typename std::iterator_traits<ForwardIterator>::iterator_category());
+ typedef iterator_traits<ForwardIterator> traits_type;
+ typedef typename traits_type::iterator_category iterator_category;
+ return adjacent_find_switch(begin, end, iterator_category());
}
// Sequential fallback for input iterator case
template<typename ForwardIterator, typename BinaryPredicate, typename IteratorTag>
inline ForwardIterator
- adjacent_find_switch(ForwardIterator begin, ForwardIterator end, BinaryPredicate binary_pred, IteratorTag)
- {
- return adjacent_find<ForwardIterator, BinaryPredicate>(begin, end, binary_pred, __gnu_parallel::sequential_tag());
- }
+ adjacent_find_switch(ForwardIterator begin, ForwardIterator 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 binary_pred, random_access_iterator_tag)
+ adjacent_find_switch(RandomAccessIterator begin, RandomAccessIterator end,
+ BinaryPredicate pred, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(true))
- return __gnu_parallel::find_template(begin, end, begin, binary_pred, __gnu_parallel::adjacent_find_selector()).first;
+ return __gnu_parallel::find_template(begin, end, begin, pred,
+ __gnu_parallel::adjacent_find_selector()).first;
else
- return adjacent_find(begin, end, binary_pred, __gnu_parallel::sequential_tag());
+ 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 binary_pred)
+ adjacent_find(ForwardIterator begin, ForwardIterator end,
+ BinaryPredicate pred)
{
- return adjacent_find_switch<ForwardIterator, BinaryPredicate>(begin, end, binary_pred, typename std::iterator_traits<ForwardIterator>::iterator_category());
+ typedef iterator_traits<ForwardIterator> traits_type;
+ typedef typename traits_type::iterator_category iterator_category;
+ return adjacent_find_switch(begin, end, pred, iterator_category());
}
// Sequential fallback
template<typename InputIterator, typename T>
inline typename iterator_traits<InputIterator>::difference_type
- count(InputIterator begin, InputIterator end, const T& value, __gnu_parallel::sequential_tag)
- {
- return _GLIBCXX_STD_P::count<InputIterator, T>(begin, end, value);
- }
+ count(InputIterator begin, InputIterator end, const T& value,
+ __gnu_parallel::sequential_tag)
+ { 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)
+ count_switch(RandomAccessIterator begin, RandomAccessIterator end,
+ const T& value, random_access_iterator_tag,
+ __gnu_parallel::parallelism parallelism_tag
+ = __gnu_parallel::parallel_unbalanced)
{
- typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
- typedef typename iterator_traits<RandomAccessIterator>::difference_type difference_type;
+ 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;
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::count_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
+ if (_GLIBCXX_PARALLEL_CONDITION(static_cast<sequence_index_t>(end - begin) >= __gnu_parallel::Settings::count_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
{
- difference_type res = 0;
__gnu_parallel::count_selector<RandomAccessIterator, difference_type> functionality;
- __gnu_parallel::for_each_template_random_access(begin, end, value, functionality, std::plus<__gnu_parallel::sequence_index_t>(), res, res, -1, parallelism_tag);
+ difference_type 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;
}
else
- return count<RandomAccessIterator, T>(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>
typename iterator_traits<InputIterator>::difference_type
- count_switch(InputIterator begin, InputIterator end, const T& value, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
+ count_switch(InputIterator begin, InputIterator end, const T& 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)
{
- return count<InputIterator, T>(begin, end, value, __gnu_parallel::sequential_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);
}
- // 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 = __gnu_parallel::parallel_unbalanced)
+ count(InputIterator begin, InputIterator end, const T& value)
{
- return count_switch(begin, end, value, typename std::iterator_traits<InputIterator>::iterator_category(), parallelism_tag);
+ typedef iterator_traits<InputIterator> traits_type;
+ typedef typename traits_type::iterator_category iterator_category;
+ return count_switch(begin, end, value, iterator_category());
}
+
// Sequential fallback.
template<typename InputIterator, typename Predicate>
inline typename iterator_traits<InputIterator>::difference_type
- count_if(InputIterator begin, InputIterator end, Predicate pred, __gnu_parallel::sequential_tag)
- {
- return _GLIBCXX_STD_P::count_if(begin, end, pred);
- }
+ count_if(InputIterator begin, InputIterator end, Predicate pred,
+ __gnu_parallel::sequential_tag)
+ { 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)
+ count_if_switch(RandomAccessIterator begin, RandomAccessIterator end,
+ Predicate pred, random_access_iterator_tag,
+ __gnu_parallel::parallelism parallelism_tag
+ = __gnu_parallel::parallel_unbalanced)
{
- typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
- typedef typename iterator_traits<RandomAccessIterator>::difference_type difference_type;
+ 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;
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::count_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
+ if (_GLIBCXX_PARALLEL_CONDITION(static_cast<sequence_index_t>(end - begin) >= __gnu_parallel::Settings::count_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
{
difference_type res = 0;
__gnu_parallel::count_if_selector<RandomAccessIterator, difference_type> functionality;
- __gnu_parallel::for_each_template_random_access(begin, end, pred, functionality, std::plus<__gnu_parallel::sequence_index_t>(), res, res, -1, parallelism_tag);
+ __gnu_parallel::for_each_template_random_access(begin, end, pred, functionality, std::plus<sequence_index_t>(), res, res, -1, parallelism_tag);
return res;
}
else
- return count_if<RandomAccessIterator, Predicate>(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>
typename iterator_traits<InputIterator>::difference_type
- count_if_switch(InputIterator begin, InputIterator end, Predicate pred, IteratorTag, __gnu_parallel::parallelism)
+ count_if_switch(InputIterator begin, InputIterator 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)
{
- return count_if<InputIterator, Predicate>(begin, end, pred, __gnu_parallel::sequential_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);
}
- // 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 = __gnu_parallel::parallel_unbalanced)
+ count_if(InputIterator begin, InputIterator 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(), parallelism_tag);
+ return count_if_switch(begin, end, pred, iterator_category());
}
@@ -950,53 +1026,88 @@ namespace __parallel
return search_n_switch(begin, end, count, val, binary_pred, typename std::iterator_traits<ForwardIterator>::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);
- }
-
- // 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);
- }
+ transform(InputIterator begin, InputIterator 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 RandomAccessIterator3, typename UnaryOperation>
- RandomAccessIterator3
- transform1_switch(RandomAccessIterator1 begin, RandomAccessIterator1 end, RandomAccessIterator3 result, UnaryOperation unary_op, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
+ template<typename RandomAccessIterator1, typename RandomAccessIterator2, typename UnaryOperation>
+ RandomAccessIterator2
+ transform1_switch(RandomAccessIterator1 begin, RandomAccessIterator1 end, RandomAccessIterator2 result, UnaryOperation unary_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::transform_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
{
bool dummy = true;
- typedef __gnu_parallel::iterator_pair<RandomAccessIterator1, RandomAccessIterator3, random_access_iterator_tag> ip;
+ 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;
__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;
}
else
- return transform(begin, end, result, unary_op, __gnu_parallel::sequential_tag());
+ return transform(begin, end, result, unary_op,
+ __gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case.
- template<typename RandomAccessIterator1, typename RandomAccessIterator3, typename UnaryOperation, typename IteratorTag1, typename IteratorTag2>
- inline RandomAccessIterator3
- transform1_switch(RandomAccessIterator1 begin, RandomAccessIterator1 end, RandomAccessIterator3 result, UnaryOperation unary_op, IteratorTag1, IteratorTag2, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
+ 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,
+ __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)
{
- return _GLIBCXX_STD_P::transform(begin, end, result, 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;
+
+ return transform1_switch(begin, end, result, unary_op,
+ iteratori_category(), iteratoro_category(),
+ parallelism_tag);
+ }
+
+ template<typename InputIterator, typename OutputIterator, typename UnaryOperation>
+ inline OutputIterator
+ transform(InputIterator begin, InputIterator 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;
+
+ return transform1_switch(begin, end, result, unary_op,
+ iteratori_category(), iteratoro_category());
}
+ // 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);
+ }
+
// 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, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
+ transform2_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, RandomAccessIterator2 begin2, RandomAccessIterator3 result, BinaryOperation binary_op, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
{
if (_GLIBCXX_PARALLEL_CONDITION((end1 - begin1) >= __gnu_parallel::Settings::transform_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
{
@@ -1008,36 +1119,44 @@ namespace __parallel
return functionality.finish_iterator;
}
else
- return transform(begin1, end1, begin2, result, binary_op, __gnu_parallel::sequential_tag());
+ return transform(begin1, end1, begin2, result, binary_op,
+ __gnu_parallel::sequential_tag());
}
// Sequential fallback for input iterator case.
- template<typename RandomAccessIterator1, typename RandomAccessIterator2, typename RandomAccessIterator3, typename BinaryOperation, typename tag1, typename tag2, typename tag3>
- inline RandomAccessIterator3
- transform2_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, RandomAccessIterator2 begin2, RandomAccessIterator3 result, BinaryOperation binary_op, tag1, tag2, tag3, __gnu_parallel::parallelism)
+ 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 _GLIBCXX_STD_P::transform(begin1, end1, begin2, result, binary_op);
+ return transform(begin1, end1, begin2, result, binary_op,
+ __gnu_parallel::sequential_tag());
}
// Public interface.
- template<typename InputIterator, typename OutputIterator, typename UnaryOperation>
+ template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename BinaryOperation>
inline OutputIterator
- transform(InputIterator begin, InputIterator end, OutputIterator result,
- UnaryOperation unary_op, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
+ transform(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
+ OutputIterator result, BinaryOperation binary_op,
+ __gnu_parallel::parallelism parallelism_tag)
{
- typedef std::iterator_traits<InputIterator> iteratori_traits;
+ 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 iteratori_traits::iterator_category iteratori_category;
typedef typename iteratoro_traits::iterator_category iteratoro_category;
- return transform1_switch(begin, end, result, unary_op,
- iteratori_category(), iteratoro_category(), parallelism_tag);
+ return transform2_switch(begin1, end1, begin2, result, binary_op,
+ iteratori1_category(), iteratori2_category(),
+ iteratoro_category(), parallelism_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 = __gnu_parallel::parallel_balanced)
+ 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;
@@ -1046,54 +1165,87 @@ namespace __parallel
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);
+ iteratori1_category(), iteratori2_category(),
+ iteratoro_category());
}
// Sequential fallback
template<typename ForwardIterator, typename T>
inline void
- replace(ForwardIterator begin, ForwardIterator end, const T& old_value, const T& new_value, __gnu_parallel::sequential_tag)
+ 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); }
// Sequential fallback for input iterator case
template<typename ForwardIterator, typename T, typename IteratorTag>
void
- replace_switch(ForwardIterator begin, ForwardIterator end, const T& old_value, const T& new_value, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
- { replace(begin, end, old_value, new_value, __gnu_parallel::sequential_tag()); }
+ replace_switch(ForwardIterator begin, ForwardIterator end,
+ const T& old_value, const T& 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>
void
- replace_switch(RandomAccessIterator begin, RandomAccessIterator end, const T& old_value, const T& new_value, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag)
- { replace(begin, end, old_value, new_value, __gnu_parallel::sequential_tag()); }
+ replace_switch(RandomAccessIterator begin, RandomAccessIterator end,
+ const T& old_value, const T& new_value,
+ random_access_iterator_tag,
+ __gnu_parallel::parallelism parallelism_tag
+ = __gnu_parallel::parallel_balanced)
+ {
+ // XXX parallel version is where?
+ replace(begin, end, old_value, new_value,
+ __gnu_parallel::sequential_tag());
+ }
// Public interface
template<typename ForwardIterator, typename T>
inline void
- replace(ForwardIterator begin, ForwardIterator end, const T& old_value, const T& new_value, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
+ replace(ForwardIterator begin, ForwardIterator end, const T& old_value,
+ const T& 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);
+ }
+
+ template<typename ForwardIterator, typename T>
+ inline void
+ replace(ForwardIterator begin, ForwardIterator end, const T& old_value,
+ const T& new_value)
{
- replace_switch(begin, end, old_value, new_value, typename std::iterator_traits<ForwardIterator>::iterator_category(), 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());
}
// Sequential fallback
template<typename ForwardIterator, typename Predicate, typename T>
inline void
- replace_if(ForwardIterator begin, ForwardIterator end, Predicate pred, const T& new_value, __gnu_parallel::sequential_tag)
+ 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); }
// Sequential fallback for input iterator case
template<typename ForwardIterator, typename Predicate, typename T, typename IteratorTag>
void
- replace_if_switch(ForwardIterator begin, ForwardIterator end, Predicate pred, const T& new_value, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
+ replace_if_switch(ForwardIterator begin, ForwardIterator end, Predicate pred,
+ const T& 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>
void
- replace_if_switch(RandomAccessIterator begin, RandomAccessIterator end, Predicate pred, const T& new_value, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag)
+ replace_if_switch(RandomAccessIterator begin, RandomAccessIterator end,
+ Predicate pred, const T& new_value,
+ 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::replace_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
{
@@ -1102,38 +1254,54 @@ namespace __parallel
__gnu_parallel::for_each_template_random_access(begin, end, pred, functionality, __gnu_parallel::dummy_reduct(), true, dummy, -1, parallelism_tag);
}
else
- replace_if(begin, end, pred, new_value, __gnu_parallel::sequential_tag());
+ replace_if(begin, end, pred, new_value,
+ __gnu_parallel::sequential_tag());
}
// Public interface.
template<typename ForwardIterator, typename Predicate, typename T>
inline void
replace_if(ForwardIterator begin, ForwardIterator end,
- Predicate pred, const T& new_value, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
+ Predicate pred, const T& 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);
+ }
- replace_if_switch(begin, end, pred, new_value, iterator_category(), parallelism_tag);
+ template<typename ForwardIterator, typename Predicate, typename T>
+ inline void
+ replace_if(ForwardIterator begin, ForwardIterator end,
+ Predicate pred, const T& 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());
}
// Sequential fallback
template<typename ForwardIterator, typename Generator>
inline void
- generate(ForwardIterator begin, ForwardIterator end, Generator gen, __gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_P::generate<ForwardIterator, Generator>(begin, end, gen); }
+ generate(ForwardIterator begin, ForwardIterator end, Generator gen,
+ __gnu_parallel::sequential_tag)
+ { _GLIBCXX_STD_P::generate(begin, end, gen); }
// Sequential fallback for input iterator case.
template<typename ForwardIterator, typename Generator, typename IteratorTag>
void
- generate_switch(ForwardIterator begin, ForwardIterator end, Generator gen, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
+ generate_switch(ForwardIterator begin, ForwardIterator end, Generator gen,
+ IteratorTag)
{ generate(begin, end, gen, __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators.
template<typename RandomAccessIterator, typename Generator>
void
generate_switch(RandomAccessIterator begin, RandomAccessIterator end,
- Generator gen, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag)
+ 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) >= __gnu_parallel::Settings::generate_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
{
@@ -1149,53 +1317,82 @@ namespace __parallel
template<typename ForwardIterator, typename Generator>
inline void
generate(ForwardIterator begin, ForwardIterator end,
- Generator gen, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
+ 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);
}
+ template<typename ForwardIterator, typename Generator>
+ inline void
+ generate(ForwardIterator begin, ForwardIterator 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());
+ }
+
// Sequential fallback.
template<typename OutputIterator, typename Size, typename Generator>
inline OutputIterator
- generate_n(OutputIterator begin, Size n, Generator gen, __gnu_parallel::sequential_tag)
+ generate_n(OutputIterator begin, Size n, Generator gen,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::generate_n(begin, n, gen); }
// Sequential fallback for input iterator case.
template<typename OutputIterator, typename Size, typename Generator, typename IteratorTag>
OutputIterator
- generate_n_switch(OutputIterator begin, Size n, Generator gen, IteratorTag, __gnu_parallel::parallelism)
+ 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>
RandomAccessIterator
- generate_n_switch(RandomAccessIterator begin, Size n, Generator gen, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag)
- { return generate_n(begin, n, gen, __gnu_parallel::sequential_tag()); }
+ generate_n_switch(RandomAccessIterator begin, Size n, Generator gen,
+ random_access_iterator_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());
+ }
// Public interface.
template<typename OutputIterator, typename Size, typename Generator>
inline OutputIterator
- generate_n(OutputIterator begin, Size n, Generator gen, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
+ 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);
+ }
+
+ 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(), parallelism_tag);
+ return generate_n_switch(begin, n, gen, iterator_category());
}
// Sequential fallback.
template<typename RandomAccessIterator>
inline void
- random_shuffle(RandomAccessIterator begin, RandomAccessIterator end, __gnu_parallel::sequential_tag)
+ random_shuffle(RandomAccessIterator begin, RandomAccessIterator end,
+ __gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_P::random_shuffle(begin, end); }
// Sequential fallback.
template<typename RandomAccessIterator, typename RandomNumberGenerator>
inline void
- random_shuffle(RandomAccessIterator begin, RandomAccessIterator end, RandomNumberGenerator& rand, __gnu_parallel::sequential_tag)
+ random_shuffle(RandomAccessIterator begin, RandomAccessIterator end,
+ RandomNumberGenerator& rand, __gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_P::random_shuffle(begin, end, rand); }
@@ -1220,7 +1417,8 @@ namespace __parallel
// Parallel algorithm for random access iterators.
template<typename RandomAccessIterator, typename RandomNumberGenerator>
void
- random_shuffle(RandomAccessIterator begin, RandomAccessIterator end, RandomNumberGenerator& rand)
+ random_shuffle(RandomAccessIterator begin, RandomAccessIterator end,
+ RandomNumberGenerator& rand)
{
if (begin == end)
return;
@@ -1262,19 +1460,23 @@ namespace __parallel
inline ForwardIterator
partition(ForwardIterator begin, ForwardIterator end, Predicate pred)
{
- return partition_switch(begin, end, pred, typename std::iterator_traits<ForwardIterator>::iterator_category());
+ typedef iterator_traits<ForwardIterator> traits_type;
+ typedef typename traits_type::iterator_category iterator_category;
+ return partition_switch(begin, end, pred, iterator_category());
}
// Sequential fallback
template<typename RandomAccessIterator>
inline void
- sort(RandomAccessIterator begin, RandomAccessIterator end, __gnu_parallel::sequential_tag)
- { _GLIBCXX_STD_P::sort<RandomAccessIterator>(begin, end); }
+ sort(RandomAccessIterator begin, RandomAccessIterator end,
+ __gnu_parallel::sequential_tag)
+ { _GLIBCXX_STD_P::sort(begin, end); }
// Sequential fallback
template<typename RandomAccessIterator, typename Comparator>
inline void
- sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp, __gnu_parallel::sequential_tag)
+ sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp,
+ __gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_P::sort<RandomAccessIterator, Comparator>(begin, end, comp); }
// Public interface, insert default comparator
@@ -1299,25 +1501,23 @@ namespace __parallel
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::sort_minimal_n))
__gnu_parallel::parallel_sort(begin, end, comp, false);
else
- sort<RandomAccessIterator, Comparator>(begin, end, comp, __gnu_parallel::sequential_tag());
+ sort(begin, end, comp, __gnu_parallel::sequential_tag());
}
}
// Sequential fallback.
template<typename RandomAccessIterator>
inline void
- stable_sort(RandomAccessIterator begin, RandomAccessIterator end, __gnu_parallel::sequential_tag)
- {
- return _GLIBCXX_STD_P::stable_sort<RandomAccessIterator>(begin, end);
- }
+ 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<RandomAccessIterator, Comparator>(begin, end, comp);
- }
+ 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
@@ -1325,65 +1525,69 @@ namespace __parallel
{
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)
+ 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::sort_minimal_n))
__gnu_parallel::parallel_sort(begin, end, comp, true);
else
- stable_sort<RandomAccessIterator, Comparator>(begin, end, comp, __gnu_parallel::sequential_tag());
+ 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,
+ merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
+ InputIterator2 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,
+ merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
+ InputIterator2 end2, OutputIterator result, Comparator 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);
- }
+ { 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, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag)
+ merge_switch(InputIterator1 begin1, InputIterator1 end1,
+ InputIterator2 begin2, InputIterator2 end2,
+ OutputIterator result, Comparator 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) >= __gnu_parallel::Settings::merge_minimal_n || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) >= __gnu_parallel::Settings::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)
+ merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
+ InputIterator2 end2, OutputIterator result, Comparator comp)
{
typedef typename iterator_traits<InputIterator1>::value_type value_type;
@@ -1394,39 +1598,47 @@ namespace __parallel
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());
+ return merge_switch(begin1, end1, begin2, end2, result, comp,
+ iteratori1_category(), iteratori2_category(),
+ iteratoro_category());
}
// 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)
+ merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
+ InputIterator2 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;
- return merge(begin1, end1, begin2, end2, result, __gnu_parallel::less<value1_type, value2_type>());
+ return merge(begin1, end1, begin2, end2, result,
+ __gnu_parallel::less<value1_type, value2_type>());
}
// Sequential fallback
template<typename RandomAccessIterator>
inline void
- nth_element(RandomAccessIterator begin, RandomAccessIterator nth, RandomAccessIterator end, __gnu_parallel::sequential_tag)
+ nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
+ RandomAccessIterator end, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::nth_element(begin, nth, end); }
// Sequential fallback
template<typename RandomAccessIterator, typename Comparator>
void
- nth_element(RandomAccessIterator begin, RandomAccessIterator nth, RandomAccessIterator end, Comparator comp, __gnu_parallel::sequential_tag)
+ nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
+ RandomAccessIterator end, Comparator comp,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::nth_element(begin, nth, end, comp); }
// Public interface
template<typename RandomAccessIterator, typename Comparator>
inline void
- nth_element(RandomAccessIterator begin, RandomAccessIterator nth, RandomAccessIterator end, Comparator comp)
+ nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
+ RandomAccessIterator end, Comparator comp)
{
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::nth_element_minimal_n))
__gnu_parallel::parallel_nth_element(begin, nth, end, comp);
@@ -1437,28 +1649,34 @@ namespace __parallel
// Public interface, insert default comparator
template<typename RandomAccessIterator>
void
- nth_element(RandomAccessIterator begin, RandomAccessIterator nth, RandomAccessIterator end)
+ nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
+ RandomAccessIterator end)
{
- typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
+ typedef iterator_traits<RandomAccessIterator> traits_type;
+ typedef typename traits_type::value_type value_type;
nth_element(begin, nth, end, std::less<value_type>());
}
// Sequential fallback
- template<typename _RandomAccessIterator, typename _Compare>
+ template<typename RandomAccessIterator, typename _Compare>
void
- partial_sort(_RandomAccessIterator begin, _RandomAccessIterator middle, _RandomAccessIterator end, _Compare comp, __gnu_parallel::sequential_tag)
+ partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
+ RandomAccessIterator end, _Compare comp,
+ __gnu_parallel::sequential_tag)
{ _GLIBCXX_STD_P::partial_sort(begin, middle, end, comp); }
// Sequential fallback
- template<typename _RandomAccessIterator>
+ template<typename RandomAccessIterator>
void
- partial_sort(_RandomAccessIterator begin, _RandomAccessIterator middle, _RandomAccessIterator end, __gnu_parallel::sequential_tag)
+ partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
+ RandomAccessIterator 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 RandomAccessIterator, typename _Compare>
void
- partial_sort(_RandomAccessIterator begin, _RandomAccessIterator middle, _RandomAccessIterator end, _Compare comp)
+ partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
+ RandomAccessIterator end, _Compare comp)
{
if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::partial_sort_minimal_n))
__gnu_parallel::parallel_partial_sort(begin, middle, end, comp);
@@ -1467,44 +1685,44 @@ namespace __parallel
}
// Public interface, insert default comparator
- template<typename _RandomAccessIterator>
+ template<typename RandomAccessIterator>
void
- partial_sort(_RandomAccessIterator begin, _RandomAccessIterator middle, _RandomAccessIterator end)
+ partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
+ RandomAccessIterator end)
{
- typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+ typedef iterator_traits<RandomAccessIterator> traits_type;
+ typedef typename traits_type::value_type value_type;
partial_sort(begin, middle, end, std::less<value_type>());
}
// Sequential fallback
template<typename ForwardIterator>
inline ForwardIterator
- max_element(ForwardIterator begin, ForwardIterator end, __gnu_parallel::sequential_tag)
+ max_element(ForwardIterator begin, ForwardIterator end,
+ __gnu_parallel::sequential_tag)
{ 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, __gnu_parallel::sequential_tag)
+ max_element(ForwardIterator begin, ForwardIterator end, Comparator comp,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::max_element(begin, end, comp); }
// Sequential fallback for input iterator case
template<typename ForwardIterator, typename Comparator, typename IteratorTag>
ForwardIterator
- max_element_switch(ForwardIterator begin, ForwardIterator end, Comparator comp, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
+ max_element_switch(ForwardIterator begin, ForwardIterator end,
+ Comparator comp, IteratorTag)
{ 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 = __gnu_parallel::parallel_balanced)
- {
- typedef typename iterator_traits<ForwardIterator>::value_type value_type;
- return max_element(begin, end, std::less<value_type>(), parallelism_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)
+ max_element_switch(RandomAccessIterator begin, RandomAccessIterator end,
+ Comparator 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) >= __gnu_parallel::Settings::max_element_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
{
@@ -1514,49 +1732,78 @@ namespace __parallel
return res;
}
else
- return max_element(begin, end, __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)
+ {
+ typedef typename iterator_traits<ForwardIterator>::value_type value_type;
+ return max_element(begin, end, std::less<value_type>(), parallelism_tag);
+ }
+
+ template<typename ForwardIterator>
+ inline ForwardIterator
+ max_element(ForwardIterator begin, ForwardIterator end)
+ {
+ typedef typename iterator_traits<ForwardIterator>::value_type value_type;
+ return max_element(begin, end, std::less<value_type>());
}
// Public interface
template<typename ForwardIterator, typename Comparator>
inline ForwardIterator
- max_element(ForwardIterator begin, ForwardIterator end, Comparator comp, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
+ max_element(ForwardIterator begin, ForwardIterator end, Comparator 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);
+ }
+
+ template<typename ForwardIterator, typename Comparator>
+ inline ForwardIterator
+ max_element(ForwardIterator begin, ForwardIterator end, Comparator comp)
{
- return max_element_switch(begin, end, comp, typename std::iterator_traits<ForwardIterator>::iterator_category(), 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());
}
+
// Sequential fallback
template<typename ForwardIterator>
inline
ForwardIterator
- min_element(ForwardIterator begin, ForwardIterator end, __gnu_parallel::sequential_tag)
+ min_element(ForwardIterator begin, ForwardIterator end,
+ __gnu_parallel::sequential_tag)
{ 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, __gnu_parallel::sequential_tag)
+ min_element(ForwardIterator begin, ForwardIterator end, Comparator comp,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::min_element(begin, end, comp); }
- // Public interface
- template<typename ForwardIterator>
- inline ForwardIterator
- min_element(ForwardIterator begin, ForwardIterator end, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
- {
- typedef typename iterator_traits<ForwardIterator>::value_type value_type;
- return min_element(begin, end, std::less<value_type>(), parallelism_tag);
- }
-
// Sequential fallback for input iterator case
template<typename ForwardIterator, typename Comparator, typename IteratorTag>
ForwardIterator
- min_element_switch(ForwardIterator begin, ForwardIterator end, Comparator comp, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
+ min_element_switch(ForwardIterator begin, ForwardIterator end,
+ Comparator 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)
+ min_element_switch(RandomAccessIterator begin, RandomAccessIterator end,
+ Comparator 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) >= __gnu_parallel::Settings::min_element_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
{
@@ -1566,17 +1813,46 @@ namespace __parallel
return res;
}
else
- return min_element(begin, end, __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)
+ {
+ typedef typename iterator_traits<ForwardIterator>::value_type value_type;
+ return min_element(begin, end, std::less<value_type>(), parallelism_tag);
+ }
+
+ template<typename ForwardIterator>
+ inline ForwardIterator
+ min_element(ForwardIterator begin, ForwardIterator end)
+ {
+ typedef typename iterator_traits<ForwardIterator>::value_type value_type;
+ return min_element(begin, end, std::less<value_type>());
}
// Public interface
template<typename ForwardIterator, typename Comparator>
inline ForwardIterator
- min_element(ForwardIterator begin, ForwardIterator end, Comparator comp, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
+ min_element(ForwardIterator begin, ForwardIterator end, Comparator 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);
+ }
+
+ template<typename ForwardIterator, typename Comparator>
+ inline ForwardIterator
+ min_element(ForwardIterator begin, ForwardIterator end, Comparator comp)
{
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);
+ return min_element_switch(begin, end, comp, iterator_category());
}
} // end namespace
} // end namespace
diff --git a/libstdc++-v3/include/parallel/algobase.h b/libstdc++-v3/include/parallel/algobase.h
index 0bd8b39afcc..a345b0f695a 100644
--- a/libstdc++-v3/include/parallel/algobase.h
+++ b/libstdc++-v3/include/parallel/algobase.h
@@ -59,15 +59,15 @@ namespace __parallel
// Sequential fallback
template<typename InputIterator1, typename InputIterator2>
inline bool
- equal(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, __gnu_parallel::sequential_tag)
- {
- return _GLIBCXX_STD_P::equal<InputIterator1, InputIterator2>(begin1, end1, begin2);
- }
+ equal(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::equal(begin1, end1, begin2); }
// Sequential fallback
template<typename InputIterator1, typename InputIterator2, typename Predicate>
inline bool
- equal(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, Predicate pred, __gnu_parallel::sequential_tag)
+ equal(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
+ Predicate pred, __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::equal(begin1, end1, begin2, pred); }
// Public interface
@@ -79,7 +79,8 @@ namespace __parallel
// Public interface
template<typename InputIterator1, typename InputIterator2, typename Predicate>
inline bool
- equal(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, Predicate pred)
+ equal(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
+ Predicate pred)
{ return mismatch(begin1, end1, begin2, pred).first == end1; }
// NB: lexicographical_compare equires mismatch.
@@ -87,33 +88,36 @@ namespace __parallel
// 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<InputIterator1, InputIterator2>(begin1, end1, begin2);
- }
+ mismatch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 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)
+ mismatch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 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)
+ mismatch_switch(InputIterator1 begin1, InputIterator1 end1,
+ InputIterator2 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)
+ mismatch_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
+ RandomAccessIterator2 begin2, Predicate pred,
+ random_access_iterator_tag, random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(true))
{
- RandomAccessIterator1 res_first =
- __gnu_parallel::find_template(begin1, end1, begin2, pred, __gnu_parallel::mismatch_selector()).first;
- return make_pair(res_first, begin2 + (res_first - begin1));
+ RandomAccessIterator1 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);
@@ -131,7 +135,10 @@ namespace __parallel
typedef typename iterator1_traits::iterator_category iterator1_category;
typedef typename iterator2_traits::iterator_category iterator2_category;
- return mismatch_switch(begin1, end1, begin2, __gnu_parallel::equal_to<value1_type, value2_type>(), iterator1_category(), iterator2_category());
+ typedef __gnu_parallel::equal_to<value1_type, value2_type> equal_to_type;
+
+ return mismatch_switch(begin1, end1, begin2, equal_to_type(),
+ iterator1_category(), iterator2_category());
}
// Public interface
@@ -145,38 +152,52 @@ namespace __parallel
typedef typename iterator1_traits::iterator_category iterator1_category;
typedef typename iterator2_traits::iterator_category iterator2_category;
- return mismatch_switch(begin1, end1, begin2, pred, iterator1_category(), iterator2_category());
+ return mismatch_switch(begin1, end1, begin2, pred, iterator1_category(),
+ iterator2_category());
}
// Sequential fallback
template<typename InputIterator1, typename InputIterator2>
inline bool
- lexicographical_compare(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, __gnu_parallel::sequential_tag)
+ lexicographical_compare(InputIterator1 begin1, InputIterator1 end1,
+ InputIterator2 begin2, InputIterator2 end2,
+ __gnu_parallel::sequential_tag)
{
- return _GLIBCXX_STD_P::lexicographical_compare<InputIterator1, InputIterator2>(begin1, end1, begin2, end2);
+ return _GLIBCXX_STD_P::lexicographical_compare(begin1, end1, begin2, end2);
}
// Sequential fallback
template<typename InputIterator1, typename InputIterator2, typename Predicate>
inline bool
- lexicographical_compare(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, Predicate pred, __gnu_parallel::sequential_tag)
+ 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);
+ 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>
inline bool
- lexicographical_compare_switch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, Predicate pred, IteratorTag1, IteratorTag2)
+ 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);
+ 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>
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(RandomAccessIterator1 begin1,
+ RandomAccessIterator1 end1,
+ RandomAccessIterator2 begin2,
+ RandomAccessIterator2 end2, Predicate pred,
+ random_access_iterator_tag,
+ random_access_iterator_tag)
{
if (_GLIBCXX_PARALLEL_CONDITION(true))
{
@@ -192,7 +213,10 @@ namespace __parallel
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());
+ pair_type mm = mismatch_switch(begin1, end1, begin2,
+ equal_type(pred),
+ random_access_iterator_tag(),
+ random_access_iterator_tag());
// Less because shorter.
const bool lbs = mm.first == end1;
@@ -205,7 +229,10 @@ namespace __parallel
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());
+ pair_type mm = mismatch_switch(begin2, end2, begin1,
+ equal_type(pred),
+ random_access_iterator_tag(),
+ random_access_iterator_tag());
// Less because shorter.
const bool lbs = mm.first != end2;
@@ -234,7 +261,9 @@ namespace __parallel
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());
+ return lexicographical_compare_switch(begin1, end1, begin2, end2,
+ less_type(), iterator1_category(),
+ iterator2_category());
}
// Public interface
@@ -248,7 +277,9 @@ namespace __parallel
typedef iterator_traits<InputIterator2> traits2_type;
typedef typename traits2_type::iterator_category iterator2_category;
- return lexicographical_compare_switch(begin1, end1, begin2, end2, pred, iterator1_category(), iterator2_category());
+ return lexicographical_compare_switch(begin1, end1, begin2, end2, pred,
+ iterator1_category(),
+ iterator2_category());
}
} // end namespace
} // end namespace
diff --git a/libstdc++-v3/include/parallel/algorithmfwd.h b/libstdc++-v3/include/parallel/algorithmfwd.h
index aa3c5585b26..ad36de527e5 100644
--- a/libstdc++-v3/include/parallel/algorithmfwd.h
+++ b/libstdc++-v3/include/parallel/algorithmfwd.h
@@ -45,216 +45,245 @@ namespace std
namespace __parallel
{
template<typename _FIter>
- inline _FIter
- adjacent_find(_FIter, _FIter, __gnu_parallel::sequential_tag);
-
- template<typename _FIter, typename BinaryPredicate>
- inline _FIter
- adjacent_find(_FIter, _FIter, BinaryPredicate, __gnu_parallel::sequential_tag);
+ _FIter
+ adjacent_find(_FIter, _FIter);
template<typename _FIter>
- inline _FIter
- adjacent_find(_FIter, _FIter);
+ _FIter
+ adjacent_find(_FIter, _FIter, __gnu_parallel::sequential_tag);
- template<typename _FIter, typename BinaryPredicate>
- inline _FIter
- adjacent_find(_FIter, _FIter, BinaryPredicate);
+ template<typename _FIter, typename _IterTag>
+ _FIter
+ adjacent_find_switch(_FIter, _FIter, _IterTag);
template<typename _RAIter>
- _RAIter
- adjacent_find_switch(_RAIter, _RAIter, random_access_iterator_tag);
+ _RAIter
+ adjacent_find_switch(_RAIter, _RAIter, random_access_iterator_tag);
- template<typename _FIter, typename IteratorTag>
- inline _FIter
- adjacent_find_switch(_FIter, _FIter, IteratorTag);
- template<typename _FIter, typename BinaryPredicate, typename IteratorTag>
- inline _FIter
- adjacent_find_switch(_FIter, _FIter, BinaryPredicate, IteratorTag);
+ template<typename _FIter, typename _BiPredicate>
+ _FIter
+ adjacent_find(_FIter, _FIter, _BiPredicate);
- template<typename _RAIter, typename BinaryPredicate>
- _RAIter
- adjacent_find_switch(_RAIter, _RAIter, BinaryPredicate, random_access_iterator_tag);
+ template<typename _FIter, typename _BiPredicate>
+ _FIter
+ adjacent_find(_FIter, _FIter, _BiPredicate,
+ __gnu_parallel::sequential_tag);
+
+ template<typename _FIter, typename _BiPredicate, typename _IterTag>
+ _FIter
+ adjacent_find_switch(_FIter, _FIter, _BiPredicate, _IterTag);
+ template<typename _RAIter, typename _BiPredicate>
+ _RAIter
+ adjacent_find_switch(_RAIter, _RAIter, _BiPredicate,
+ random_access_iterator_tag);
+
+
+ template<typename _IIter, typename _Tp>
+ typename iterator_traits<_IIter>::difference_type
+ count(_IIter, _IIter, const _Tp&);
template<typename _IIter, typename T>
- inline typename iterator_traits<_IIter>::difference_type
- count(_IIter, _IIter, const T& value, __gnu_parallel::sequential_tag);
+ typename iterator_traits<_IIter>::difference_type
+ count(_IIter, _IIter, const T&, __gnu_parallel::sequential_tag);
template<typename _IIter, typename T>
- inline typename iterator_traits<_IIter>::difference_type
- count(_IIter, _IIter, const T& value, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_unbalanced);
+ typename iterator_traits<_IIter>::difference_type
+ count(_IIter, _IIter, const T&, __gnu_parallel::parallelism);
+
+ template<typename _IIter, typename T, typename _IterTag>
+ typename iterator_traits<_IIter>::difference_type
+ count_switch(_IIter, _IIter, const T&, _IterTag);
template<typename _RAIter, typename T>
- typename iterator_traits<_RAIter>::difference_type
- count_switch(_RAIter, _RAIter, const T& value, random_access_iterator_tag, __gnu_parallel::parallelism);
+ typename iterator_traits<_RAIter>::difference_type
+ count_switch(_RAIter, _RAIter, const T&, random_access_iterator_tag,
+ __gnu_parallel::parallelism);
- template<typename _IIter, typename T, typename IteratorTag>
- typename iterator_traits<_IIter>::difference_type
- count_switch(_IIter, _IIter, const T& value, IteratorTag, __gnu_parallel::parallelism);
+ template<typename _IIter, typename Predicate>
+ typename iterator_traits<_IIter>::difference_type
+ count_if(_IIter, _IIter, Predicate);
template<typename _IIter, typename Predicate>
- inline typename iterator_traits<_IIter>::difference_type
- count_if(_IIter, _IIter, Predicate, __gnu_parallel::sequential_tag);
+ typename iterator_traits<_IIter>::difference_type
+ count_if(_IIter, _IIter, Predicate, __gnu_parallel::sequential_tag);
template<typename _IIter, typename Predicate>
- inline typename iterator_traits<_IIter>::difference_type
- count_if(_IIter, _IIter, Predicate, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_unbalanced);
+ typename iterator_traits<_IIter>::difference_type
+ count_if(_IIter, _IIter, Predicate, __gnu_parallel::parallelism);
- template<typename _RAIter, typename Predicate>
- typename iterator_traits<_RAIter>::difference_type
- count_if_switch(_RAIter, _RAIter, Predicate, random_access_iterator_tag, __gnu_parallel::parallelism);
+ template<typename _IIter, typename Predicate, typename _IterTag>
+ typename iterator_traits<_IIter>::difference_type
+ count_if_switch(_IIter, _IIter, Predicate, _IterTag);
- template<typename _IIter, typename Predicate, typename IteratorTag>
- typename iterator_traits<_IIter>::difference_type
- count_if_switch(_IIter, _IIter, Predicate, IteratorTag, __gnu_parallel::parallelism);
+ template<typename _RAIter, typename Predicate>
+ typename iterator_traits<_RAIter>::difference_type
+ count_if_switch(_RAIter, _RAIter, Predicate, random_access_iterator_tag,
+ __gnu_parallel::parallelism);
// algobase.h
template<typename _IIter1, typename _IIter2>
- inline bool
+ bool
equal(_IIter1, _IIter1, _IIter2, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename Predicate>
- inline bool
+ bool
equal(_IIter1, _IIter1, _IIter2, Predicate, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2>
- inline bool
+ bool
equal(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename Predicate>
- inline bool
+ bool
equal(_IIter1, _IIter1, _IIter2, Predicate);
template<typename _IIter, typename T>
- inline _IIter
+ _IIter
find(_IIter, _IIter, const T&, __gnu_parallel::sequential_tag);
template<typename _IIter, typename T>
- inline _IIter
+ _IIter
find(_IIter, _IIter, const T& val);
- template<typename _IIter, typename T, typename IteratorTag>
- inline _IIter
- find_switch(_IIter, _IIter, const T&, IteratorTag);
+ template<typename _IIter, typename T, typename _IterTag>
+ _IIter
+ find_switch(_IIter, _IIter, const T&, _IterTag);
template<typename _RAIter, typename T>
_RAIter
find_switch(_RAIter, _RAIter, const T&, random_access_iterator_tag);
template<typename _IIter, typename Predicate>
- inline _IIter
+ _IIter
find_if(_IIter, _IIter, Predicate, __gnu_parallel::sequential_tag);
template<typename _IIter, typename Predicate>
- inline _IIter
+ _IIter
find_if(_IIter, _IIter, Predicate);
- template<typename _IIter, typename Predicate, typename IteratorTag>
- inline _IIter
- find_if_switch(_IIter, _IIter, Predicate, IteratorTag);
+ template<typename _IIter, typename Predicate, typename _IterTag>
+ _IIter
+ find_if_switch(_IIter, _IIter, Predicate, _IterTag);
template<typename _RAIter, typename Predicate>
_RAIter
find_if_switch(_RAIter, _RAIter, Predicate, random_access_iterator_tag);
template<typename _IIter, typename _FIter>
- inline _IIter
+ _IIter
find_first_of(_IIter, _IIter, _FIter, _FIter, __gnu_parallel::sequential_tag);
- template<typename _IIter, typename _FIter, typename BinaryPredicate>
- inline _IIter
- find_first_of(_IIter, _IIter, _FIter, _FIter, BinaryPredicate, __gnu_parallel::sequential_tag);
+ template<typename _IIter, typename _FIter, typename _BiPredicate>
+ _IIter
+ find_first_of(_IIter, _IIter, _FIter, _FIter, _BiPredicate, __gnu_parallel::sequential_tag);
- template<typename _IIter, typename _FIter, typename BinaryPredicate>
- inline _IIter
- find_first_of(_IIter, _IIter, _FIter, _FIter, BinaryPredicate);
+ template<typename _IIter, typename _FIter, typename _BiPredicate>
+ _IIter
+ find_first_of(_IIter, _IIter, _FIter, _FIter, _BiPredicate);
template<typename _IIter, typename _FIter>
_IIter
find_first_of(_IIter, _IIter, _FIter, _FIter);
- template<typename _IIter, typename _FIter, typename IteratorTag1, typename IteratorTag2>
- inline _IIter
- find_first_of_switch(_IIter, _IIter, _FIter, _FIter, IteratorTag1, IteratorTag2);
+ template<typename _IIter, typename _FIter, typename _IterTag1, typename _IterTag2>
+ _IIter
+ find_first_of_switch(_IIter, _IIter, _FIter, _FIter, _IterTag1, _IterTag2);
- template<typename _RAIter, typename _FIter, typename BinaryPredicate, typename IteratorTag>
- inline _RAIter
- find_first_of_switch(_RAIter, _RAIter, _FIter, _FIter, BinaryPredicate, random_access_iterator_tag, IteratorTag);
+ template<typename _RAIter, typename _FIter, typename _BiPredicate, typename _IterTag>
+ _RAIter
+ find_first_of_switch(_RAIter, _RAIter, _FIter, _FIter, _BiPredicate, random_access_iterator_tag, _IterTag);
- template<typename _IIter, typename _FIter, typename BinaryPredicate, typename IteratorTag1, typename IteratorTag2>
- inline _IIter
- find_first_of_switch(_IIter, _IIter, _FIter, _FIter, BinaryPredicate, IteratorTag1, IteratorTag2);
+ template<typename _IIter, typename _FIter, typename _BiPredicate, typename _IterTag1, typename _IterTag2>
+ _IIter
+ find_first_of_switch(_IIter, _IIter, _FIter, _FIter, _BiPredicate, _IterTag1, _IterTag2);
template<typename _IIter, typename Function>
- inline Function
- for_each(_IIter, _IIter, Function f, __gnu_parallel::sequential_tag);
+ Function
+ for_each(_IIter, _IIter, Function);
+
+ template<typename _IIter, typename Function>
+ Function
+ for_each(_IIter, _IIter, Function, __gnu_parallel::sequential_tag);
template<typename Iterator, typename Function>
- inline Function
- for_each(Iterator, Iterator, Function f, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
+ Function
+ for_each(Iterator, Iterator, Function, __gnu_parallel::parallelism);
- template<typename _IIter, typename Function, typename IteratorTag>
- Function
- for_each_switch(_IIter, _IIter, Function f, IteratorTag, __gnu_parallel::parallelism);
+ template<typename _IIter, typename Function, typename _IterTag>
+ Function
+ for_each_switch(_IIter, _IIter, Function, _IterTag);
template<typename _RAIter, typename Function>
- Function
- for_each_switch(_RAIter, _RAIter, Function f, random_access_iterator_tag, __gnu_parallel::parallelism);
+ Function
+ for_each_switch(_RAIter, _RAIter, Function, random_access_iterator_tag,
+ __gnu_parallel::parallelism);
+
template<typename _FIter, typename Generator>
- inline void
- generate(_FIter, _FIter, Generator, __gnu_parallel::sequential_tag);
+ void
+ generate(_FIter, _FIter, Generator);
template<typename _FIter, typename Generator>
- inline void
- generate(_FIter, _FIter, Generator, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
+ void
+ generate(_FIter, _FIter, Generator, __gnu_parallel::sequential_tag);
- template<typename _FIter, typename Generator, typename IteratorTag>
- void
- generate_switch(_FIter, _FIter, Generator, IteratorTag, __gnu_parallel::parallelism);
+ template<typename _FIter, typename Generator>
+ void
+ generate(_FIter, _FIter, Generator, __gnu_parallel::parallelism);
+
+ template<typename _FIter, typename Generator, typename _IterTag>
+ void
+ generate_switch(_FIter, _FIter, Generator, _IterTag);
template<typename _RAIter, typename Generator>
- void
- generate_switch(_RAIter, _RAIter, Generator, random_access_iterator_tag, __gnu_parallel::parallelism);
+ void
+ generate_switch(_RAIter, _RAIter, Generator, random_access_iterator_tag,
+ __gnu_parallel::parallelism);
template<typename _OIter, typename Size, typename Generator>
- inline _OIter
- generate_n(_OIter, Size, Generator, __gnu_parallel::sequential_tag);
+ _OIter
+ generate_n(_OIter, Size, Generator);
template<typename _OIter, typename Size, typename Generator>
- inline _OIter
- generate_n(_OIter, Size, Generator, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
+ _OIter
+ generate_n(_OIter, Size, Generator, __gnu_parallel::sequential_tag);
- template<typename _OIter, typename Size, typename Generator, typename IteratorTag>
- _OIter
- generate_n_switch(_OIter, Size, Generator, IteratorTag, __gnu_parallel::parallelism);
+ template<typename _OIter, typename Size, typename Generator>
+ _OIter
+ generate_n(_OIter, Size, Generator, __gnu_parallel::parallelism);
+
+ template<typename _OIter, typename Size, typename Generator, typename _IterTag>
+ _OIter
+ 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);
+ _RAIter
+ generate_n_switch(_RAIter, Size, Generator, random_access_iterator_tag,
+ __gnu_parallel::parallelism);
template<typename _IIter1, typename _IIter2>
- inline bool
+ bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename Predicate>
- inline bool
+ bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, Predicate, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2>
- inline bool
+ bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename Predicate>
- inline bool
+ bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, Predicate);
- template<typename _IIter1, typename _IIter2, typename Predicate, typename IteratorTag1, typename IteratorTag2>
- inline bool
- lexicographical_compare_switch(_IIter1, _IIter1, _IIter2, _IIter2, Predicate, IteratorTag1, IteratorTag2);
+ template<typename _IIter1, typename _IIter2, typename Predicate, typename _IterTag1, typename _IterTag2>
+ bool
+ lexicographical_compare_switch(_IIter1, _IIter1, _IIter2, _IIter2, Predicate, _IterTag1, _IterTag2);
template<typename _RAIter1, typename _RAIter2, typename Predicate>
bool
@@ -262,225 +291,286 @@ namespace __parallel
// algo.h
template<typename _IIter1, typename _IIter2>
- inline pair<_IIter1, _IIter2>
+ pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename Predicate>
- inline pair<_IIter1, _IIter2>
+ pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2, Predicate, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2>
- inline pair<_IIter1, _IIter2>
+ pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename Predicate>
- inline pair<_IIter1, _IIter2>
+ pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2, Predicate);
- template<typename _IIter1, typename _IIter2, typename Predicate, typename IteratorTag1, typename IteratorTag2>
- inline pair<_IIter1, _IIter2>
- mismatch_switch(_IIter1, _IIter1, _IIter2, Predicate, IteratorTag1, IteratorTag2);
+ template<typename _IIter1, typename _IIter2, typename Predicate, typename _IterTag1, typename _IterTag2>
+ pair<_IIter1, _IIter2>
+ 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);
template<typename _FIter1, typename _FIter2>
- inline _FIter1
+ _FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2, __gnu_parallel::sequential_tag);
template<typename _FIter1, typename _FIter2>
- inline _FIter1
+ _FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2);
- template<typename _FIter1, typename _FIter2, typename BinaryPredicate>
- inline _FIter1
- search(_FIter1, _FIter1, _FIter2, _FIter2, BinaryPredicate, __gnu_parallel::sequential_tag);
+ template<typename _FIter1, typename _FIter2, typename _BiPredicate>
+ _FIter1
+ search(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate, __gnu_parallel::sequential_tag);
- template<typename _FIter1, typename _FIter2, typename BinaryPredicate>
- inline _FIter1
- search(_FIter1, _FIter1, _FIter2, _FIter2, BinaryPredicate);
+ template<typename _FIter1, typename _FIter2, typename _BiPredicate>
+ _FIter1
+ search(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate);
template<typename _RAIter1, typename _RAIter2>
_RAIter1
search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, random_access_iterator_tag, random_access_iterator_tag);
- template<typename _FIter1, typename _FIter2, typename IteratorTag1, typename IteratorTag2>
- inline _FIter1
- search_switch(_FIter1, _FIter1, _FIter2, _FIter2, IteratorTag1, IteratorTag2);
+ template<typename _FIter1, typename _FIter2, typename _IterTag1, typename _IterTag2>
+ _FIter1
+ search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _IterTag1, _IterTag2);
- template<typename _RAIter1, typename _RAIter2, typename BinaryPredicate>
+ template<typename _RAIter1, typename _RAIter2, typename _BiPredicate>
_RAIter1
- search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, BinaryPredicate , 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 BinaryPredicate, typename IteratorTag1, typename IteratorTag2>
- inline _FIter1
- search_switch(_FIter1, _FIter1, _FIter2, _FIter2, BinaryPredicate, IteratorTag1, IteratorTag2);
+ template<typename _FIter1, typename _FIter2, typename _BiPredicate, typename _IterTag1, typename _IterTag2>
+ _FIter1
+ search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate, _IterTag1, _IterTag2);
template<typename _FIter, typename Integer, typename T>
- inline _FIter
+ _FIter
search_n(_FIter, _FIter, Integer, const T&, __gnu_parallel::sequential_tag);
- template<typename _FIter, typename Integer, typename T, typename BinaryPredicate>
- inline _FIter
- search_n(_FIter, _FIter, Integer, const T&, BinaryPredicate, __gnu_parallel::sequential_tag);
+ template<typename _FIter, typename Integer, typename T, typename _BiPredicate>
+ _FIter
+ search_n(_FIter, _FIter, Integer, const T&, _BiPredicate, __gnu_parallel::sequential_tag);
template<typename _FIter, typename Integer, typename T>
- inline _FIter
+ _FIter
search_n(_FIter, _FIter, Integer, const T& val);
- template<typename _FIter, typename Integer, typename T, typename BinaryPredicate>
- inline _FIter
- search_n(_FIter, _FIter, Integer, const T&, BinaryPredicate);
+ template<typename _FIter, typename Integer, typename T, typename _BiPredicate>
+ _FIter
+ search_n(_FIter, _FIter, Integer, const T&, _BiPredicate);
- template<typename _RAIter, typename Integer, typename T, typename BinaryPredicate>
+ template<typename _RAIter, typename Integer, typename T, typename _BiPredicate>
_RAIter
- search_n_switch(_RAIter, _RAIter, Integer, const T&, BinaryPredicate, random_access_iterator_tag);
+ search_n_switch(_RAIter, _RAIter, Integer, const T&, _BiPredicate, random_access_iterator_tag);
- template<typename _FIter, typename Integer, typename T, typename BinaryPredicate, typename IteratorTag>
- inline _FIter
- search_n_switch(_FIter, _FIter, Integer, const T&, BinaryPredicate, IteratorTag);
+ template<typename _FIter, typename Integer, typename T, typename _BiPredicate, typename _IterTag>
+ _FIter
+ search_n_switch(_FIter, _FIter, Integer, const T&, _BiPredicate, _IterTag);
template<typename _IIter, typename _OIter, typename UnaryOperation>
- inline _OIter
- transform(_IIter, _IIter, _OIter, UnaryOperation, __gnu_parallel::sequential_tag);
+ _OIter
+ transform(_IIter, _IIter, _OIter, UnaryOperation);
- template<typename _IIter1, typename _IIter2, typename _OIter, typename BinaryOperation>
- inline _OIter
- transform(_IIter1, _IIter1, _IIter2, _OIter, BinaryOperation binary_op, __gnu_parallel::sequential_tag);
+ template<typename _IIter, typename _OIter, typename UnaryOperation>
+ _OIter
+ transform(_IIter, _IIter, _OIter, UnaryOperation,
+ __gnu_parallel::sequential_tag);
template<typename _IIter, typename _OIter, typename UnaryOperation>
- inline _OIter
- transform(_IIter, _IIter, _OIter, UnaryOperation, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
+ _OIter
+ transform(_IIter, _IIter, _OIter, UnaryOperation,
+ __gnu_parallel::parallelism);
+
+ template<typename _IIter, typename _OIter, typename UnaryOperation, typename _IterTag1, typename _IterTag2>
+ _OIter
+ transform1_switch(_IIter, _IIter, _OIter, UnaryOperation,
+ _IterTag1, _IterTag2);
+
- template<typename _IIter1, typename _IIter2, typename _OIter, typename BinaryOperation>
- inline _OIter
- transform(_IIter1, _IIter1, _IIter2, _OIter, BinaryOperation binary_op, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
+ 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);
- template<typename _RAIter1, typename _RAIter3, typename UnaryOperation>
- _RAIter3
- transform1_switch(_RAIter1, _RAIter1, _RAIter3, UnaryOperation, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
- template<typename _RAIter1, typename _RAIter3, typename UnaryOperation, typename IteratorTag1, typename IteratorTag2>
- inline _RAIter3
- transform1_switch(_RAIter1, _RAIter1, _RAIter3, UnaryOperation, IteratorTag1, IteratorTag2, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
-
- template<typename _RAIter1, typename _RAIter2, typename _RAIter3, typename BinaryOperation>
- _RAIter3
- transform2_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter3, BinaryOperation binary_op, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
+ template<typename _IIter1, typename _IIter2, typename _OIter, typename _BiOperation>
+ _OIter
+ transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation);
+
+ template<typename _IIter1, typename _IIter2, typename _OIter, typename _BiOperation>
+ _OIter
+ transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation,
+ __gnu_parallel::sequential_tag);
+
+ template<typename _IIter1, typename _IIter2, typename _OIter, typename _BiOperation>
+ _OIter
+ transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation,
+ __gnu_parallel::parallelism);
+
+ template<typename _RAIter1, typename _RAIter2, typename _RAIter3, 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_tag);
+
+ template<typename _IIter1, typename _IIter2, typename _OIter, typename _BiOperation, typename tag1, typename tag2, typename tag3>
+ _OIter
+ transform2_switch(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation,
+ tag1, tag2, tag3);
- template<typename _RAIter1, typename _RAIter2, typename _RAIter3, typename BinaryOperation, typename tag1, typename tag2, typename tag3>
- inline _RAIter3
- transform2_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter3, BinaryOperation binary_op, tag1, tag2, tag3, __gnu_parallel::parallelism);
template<typename _FIter, typename T>
- inline void
- replace(_FIter, _FIter, const T&, const T&, __gnu_parallel::sequential_tag);
+ void
+ replace(_FIter, _FIter, const T&, const T&);
template<typename _FIter, typename T>
- inline void
- replace(_FIter, _FIter, const T&, const T&, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
+ void
+ replace(_FIter, _FIter, const T&, const T&,
+ __gnu_parallel::sequential_tag);
- template<typename _FIter, typename T, typename IteratorTag>
- void
- replace_switch(_FIter, _FIter, const T&, const T&, IteratorTag, __gnu_parallel::parallelism);
+ template<typename _FIter, typename T>
+ void
+ replace(_FIter, _FIter, const T&, const T&, __gnu_parallel::parallelism);
+
+ template<typename _FIter, typename T, typename _IterTag>
+ void
+ replace_switch(_FIter, _FIter, const T&, const T&, _IterTag);
template<typename _RAIter, typename T>
- void
- replace_switch(_RAIter, _RAIter, const T&, const T&, random_access_iterator_tag, __gnu_parallel::parallelism);
+ void
+ replace_switch(_RAIter, _RAIter, const T&, const T&,
+ random_access_iterator_tag, __gnu_parallel::parallelism);
template<typename _FIter, typename Predicate, typename T>
- inline void
- replace_if(_FIter, _FIter, Predicate, const T&, __gnu_parallel::sequential_tag);
+ void
+ replace_if(_FIter, _FIter, Predicate, const T&);
template<typename _FIter, typename Predicate, typename T>
- inline void
- replace_if(_FIter, _FIter, Predicate, const T&, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
-
- template<typename _FIter, typename Predicate, typename T, typename IteratorTag>
- void
- replace_if_switch(_FIter, _FIter, Predicate, const T&, IteratorTag, __gnu_parallel::parallelism);
+ void
+ replace_if(_FIter, _FIter, Predicate, const T&,
+ __gnu_parallel::sequential_tag);
+ template<typename _FIter, typename Predicate, typename T>
+ void
+ replace_if(_FIter, _FIter, Predicate, const T&,
+ __gnu_parallel::parallelism);
+
+ template<typename _FIter, typename Predicate, typename T, typename _IterTag>
+ void
+ replace_if_switch(_FIter, _FIter, Predicate, const T&, _IterTag);
+
template<typename _RAIter, typename Predicate, typename T>
- void
- replace_if_switch(_RAIter, _RAIter, Predicate, const T&, random_access_iterator_tag, __gnu_parallel::parallelism);
+ void
+ replace_if_switch(_RAIter, _RAIter, Predicate, const T&,
+ random_access_iterator_tag, __gnu_parallel::parallelism);
+
template<typename _FIter>
- inline _FIter
- max_element(_FIter, _FIter, __gnu_parallel::sequential_tag);
+ _FIter
+ max_element(_FIter, _FIter);
- template<typename _FIter, typename _Compare>
- inline _FIter
- max_element(_FIter, _FIter, _Compare, __gnu_parallel::sequential_tag);
+ template<typename _FIter>
+ _FIter
+ max_element(_FIter, _FIter, __gnu_parallel::sequential_tag);
template<typename _FIter>
- inline _FIter
- max_element(_FIter, _FIter, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
+ _FIter
+ max_element(_FIter, _FIter, __gnu_parallel::parallelism parallelism_tag);
template<typename _FIter, typename _Compare>
- inline _FIter
- max_element(_FIter, _FIter, _Compare, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
+ _FIter
+ max_element(_FIter, _FIter, _Compare);
- template<typename _FIter, typename _Compare, typename IteratorTag>
- _FIter
- max_element_switch(_FIter, _FIter, _Compare, IteratorTag, __gnu_parallel::parallelism);
+ template<typename _FIter, typename _Compare>
+ _FIter
+ max_element(_FIter, _FIter, _Compare, __gnu_parallel::sequential_tag);
+
+ template<typename _FIter, typename _Compare>
+ _FIter
+ max_element(_FIter, _FIter, _Compare, __gnu_parallel::parallelism);
+
+ template<typename _FIter, typename _Compare, typename _IterTag>
+ _FIter
+ 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);
+ _RAIter
+ max_element_switch(_RAIter, _RAIter, _Compare, random_access_iterator_tag,
+ __gnu_parallel::parallelism);
+
template<typename _IIter1, typename _IIter2, typename _OIter>
- inline _OIter
- merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag);
+ _OIter
+ merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter, typename _Compare>
- inline _OIter
- merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare, __gnu_parallel::sequential_tag);
+ _OIter
+ merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare,
+ __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter, typename _Compare>
- inline _OIter
- merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
+ _OIter
+ merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
- inline _OIter
- merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
+ _OIter
+ merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
- template<typename _IIter1, typename _IIter2, typename _OIter, typename _Compare, typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
- inline _OIter
- merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare, IteratorTag1, IteratorTag2, IteratorTag3);
+ template<typename _IIter1, typename _IIter2, typename _OIter, typename _Compare, typename _IterTag1, typename _IterTag2, typename _IterTag3>
+ _OIter
+ merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare,
+ _IterTag1, _IterTag2, _IterTag3);
template<typename _IIter1, typename _IIter2, typename _OIter, typename _Compare>
- _OIter
- merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag);
+ _OIter
+ merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare,
+ random_access_iterator_tag, random_access_iterator_tag,
+ random_access_iterator_tag);
+
template<typename _FIter>
- inline _FIter
- min_element(_FIter, _FIter, __gnu_parallel::sequential_tag);
+ _FIter
+ min_element(_FIter, _FIter);
- template<typename _FIter, typename _Compare>
- inline _FIter
- min_element(_FIter, _FIter, _Compare, __gnu_parallel::sequential_tag);
+ template<typename _FIter>
+ _FIter
+ min_element(_FIter, _FIter, __gnu_parallel::sequential_tag);
template<typename _FIter>
- inline _FIter
- min_element(_FIter, _FIter, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
+ _FIter
+ min_element(_FIter, _FIter, __gnu_parallel::parallelism parallelism_tag);
template<typename _FIter, typename _Compare>
- inline _FIter
- min_element(_FIter, _FIter, _Compare, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
+ _FIter
+ min_element(_FIter, _FIter, _Compare);
- template<typename _FIter, typename _Compare, typename IteratorTag>
- _FIter
- min_element_switch(_FIter, _FIter, _Compare, IteratorTag, __gnu_parallel::parallelism);
+ template<typename _FIter, typename _Compare>
+ _FIter
+ min_element(_FIter, _FIter, _Compare, __gnu_parallel::sequential_tag);
+
+ template<typename _FIter, typename _Compare>
+ _FIter
+ min_element(_FIter, _FIter, _Compare, __gnu_parallel::parallelism);
+
+ template<typename _FIter, typename _Compare, typename _IterTag>
+ _FIter
+ 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);
+ _RAIter
+ min_element_switch(_RAIter, _RAIter, _Compare, random_access_iterator_tag,
+ __gnu_parallel::parallelism);
template<typename _RAIter>
- inline void
+ void
nth_element(_RAIter, _RAIter, _RAIter, __gnu_parallel::sequential_tag);
template<typename _RAIter, typename _Compare>
@@ -488,7 +578,7 @@ namespace __parallel
nth_element(_RAIter, _RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag);
template<typename _RAIter, typename _Compare>
- inline void
+ void
nth_element(_RAIter, _RAIter, _RAIter, _Compare);
template<typename _RAIter>
@@ -512,31 +602,31 @@ namespace __parallel
partial_sort(_RAIter, _RAIter, _RAIter);
template<typename _FIter, typename Predicate>
- inline _FIter
+ _FIter
partition(_FIter, _FIter, Predicate, __gnu_parallel::sequential_tag);
template<typename _FIter, typename Predicate>
- inline _FIter
+ _FIter
partition(_FIter, _FIter, Predicate);
- template<typename _FIter, typename Predicate, typename IteratorTag>
- inline _FIter
- partition_switch(_FIter, _FIter, Predicate, IteratorTag);
+ template<typename _FIter, typename Predicate, typename _IterTag>
+ _FIter
+ partition_switch(_FIter, _FIter, Predicate, _IterTag);
template<typename _RAIter, typename Predicate>
_RAIter
partition_switch(_RAIter, _RAIter, Predicate, random_access_iterator_tag);
template<typename _RAIter>
- inline void
+ void
random_shuffle(_RAIter, _RAIter, __gnu_parallel::sequential_tag);
template<typename _RAIter, typename RandomNumberGenerator>
- inline void
+ void
random_shuffle(_RAIter, _RAIter, RandomNumberGenerator& rand, __gnu_parallel::sequential_tag);
template<typename _RAIter>
- inline void
+ void
random_shuffle(_RAIter, _RAIter);
template<typename _RAIter, typename RandomNumberGenerator>
@@ -544,72 +634,72 @@ namespace __parallel
random_shuffle(_RAIter, _RAIter, RandomNumberGenerator& rand);
template<typename _IIter1, typename _IIter2, typename _OIter>
- inline _OIter
+ _OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter, typename Predicate>
- inline _OIter
+ _OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter>
- inline _OIter
+ _OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter, typename Predicate>
- inline _OIter
+ _OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate);
- template<typename _IIter1, typename _IIter2, typename Predicate, typename _OIter, typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
- inline _OIter
- set_union_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate, IteratorTag1, IteratorTag2, IteratorTag3);
+ template<typename _IIter1, typename _IIter2, typename Predicate, typename _OIter, typename _IterTag1, typename _IterTag2, typename _IterTag3>
+ _OIter
+ set_union_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate, _IterTag1, _IterTag2, _IterTag3);
template<typename _RAIter1, typename _RAIter2, typename Output_RAIter, 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);
template<typename _IIter1, typename _IIter2, typename _OIter>
- inline _OIter
+ _OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter, typename Predicate>
- inline _OIter
+ _OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter>
- inline _OIter
+ _OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter, typename Predicate>
- inline _OIter
+ _OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate);
- template<typename _IIter1, typename _IIter2, typename Predicate, typename _OIter, typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
- inline _OIter
- set_intersection_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate, IteratorTag1, IteratorTag2, IteratorTag3);
+ template<typename _IIter1, typename _IIter2, typename Predicate, typename _OIter, typename _IterTag1, typename _IterTag2, typename _IterTag3>
+ _OIter
+ set_intersection_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate, _IterTag1, _IterTag2, _IterTag3);
template<typename _RAIter1, typename _RAIter2, typename Output_RAIter, 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);
template<typename _IIter1, typename _IIter2, typename _OIter>
- inline _OIter
+ _OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter, typename Predicate>
- inline _OIter
+ _OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter>
- inline _OIter
+ _OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter, typename Predicate>
- inline _OIter
+ _OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate);
- template<typename _IIter1, typename _IIter2, typename Predicate, typename _OIter, typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
- inline _OIter
- set_symmetric_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate, IteratorTag1, IteratorTag2, IteratorTag3);
+ template<typename _IIter1, typename _IIter2, typename Predicate, typename _OIter, typename _IterTag1, typename _IterTag2, typename _IterTag3>
+ _OIter
+ set_symmetric_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate, _IterTag1, _IterTag2, _IterTag3);
template<typename _RAIter1, typename _RAIter2, typename Output_RAIter, typename Predicate>
Output_RAIter
@@ -617,24 +707,24 @@ namespace __parallel
template<typename _IIter1, typename _IIter2, typename _OIter>
- inline _OIter
+ _OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter, typename Predicate>
- inline _OIter
+ _OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate, __gnu_parallel::sequential_tag);
template<typename _IIter1, typename _IIter2, typename _OIter>
- inline _OIter
+ _OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter, typename Predicate>
- inline _OIter
+ _OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate);
- template<typename _IIter1, typename _IIter2, typename Predicate, typename _OIter, typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
- inline _OIter
- set_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate, IteratorTag1, IteratorTag2, IteratorTag3);
+ template<typename _IIter1, typename _IIter2, typename Predicate, typename _OIter, typename _IterTag1, typename _IterTag2, typename _IterTag3>
+ _OIter
+ set_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, Predicate, _IterTag1, _IterTag2, _IterTag3);
template<typename _RAIter1, typename _RAIter2, typename Output_RAIter, typename Predicate>
Output_RAIter
@@ -642,15 +732,15 @@ namespace __parallel
template<typename _RAIter>
- inline void
+ void
sort(_RAIter, _RAIter, __gnu_parallel::sequential_tag);
template<typename _RAIter, typename _Compare>
- inline void
+ void
sort(_RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag);
template<typename _RAIter>
- inline void
+ void
sort(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
@@ -658,11 +748,11 @@ namespace __parallel
sort(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
- inline void
+ void
stable_sort(_RAIter, _RAIter, __gnu_parallel::sequential_tag);
template<typename _RAIter, typename _Compare>
- inline void
+ void
stable_sort(_RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag);
template<typename _RAIter>
@@ -674,46 +764,30 @@ namespace __parallel
stable_sort(_RAIter, _RAIter, _Compare);
template<typename _IIter, typename _OIter>
- inline _OIter
+ _OIter
unique_copy(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag);
template<typename _IIter, typename _OIter, typename Predicate>
- inline _OIter
+ _OIter
unique_copy(_IIter, _IIter, _OIter, Predicate, __gnu_parallel::sequential_tag);
template<typename _IIter, typename _OIter>
- inline _OIter
+ _OIter
unique_copy(_IIter, _IIter, _OIter);
template<typename _IIter, typename _OIter, typename Predicate>
- inline _OIter
+ _OIter
unique_copy(_IIter, _IIter, _OIter, Predicate);
- template<typename _IIter, typename _OIter, typename Predicate, typename IteratorTag1, typename IteratorTag2>
- inline _OIter
- unique_copy_switch(_IIter, _IIter, _OIter, Predicate, IteratorTag1, IteratorTag2);
+ template<typename _IIter, typename _OIter, typename Predicate, typename _IterTag1, typename _IterTag2>
+ _OIter
+ 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
-// NB: cannot use _GLIBCXX_STD_P directly here, as it is both scoped
-// (std::__norm) and unscoped (std::).
-namespace __gnu_sequential
-{
-#ifdef _GLIBCXX_PARALLEL
- using std::__norm::partition;
- using std::__norm::sort;
- using std::__norm::stable_sort;
- using std::__norm::random_shuffle;
-#else
- using std::partition;
- using std::sort;
- using std::stable_sort;
- using std::random_shuffle;
-#endif
-}
-
#endif
diff --git a/libstdc++-v3/include/parallel/balanced_quicksort.h b/libstdc++-v3/include/parallel/balanced_quicksort.h
index 881099cb37f..c28277039c5 100644
--- a/libstdc++-v3/include/parallel/balanced_quicksort.h
+++ b/libstdc++-v3/include/parallel/balanced_quicksort.h
@@ -32,6 +32,14 @@
* @brief Implementation of a dynamically load-balanced parallel quicksort.
*
* It works in-place and needs only logarithmic extra memory.
+ * The algorithm is similar to the one proposed in
+ *
+ * P. Tsigas and Y. Zhang.
+ * A simple, fast parallel implementation of quicksort and
+ * its performance evaluation on SUN enterprise 10000.
+ * In 11th Euromicro Conference on Parallel, Distributed and
+ * Network-Based Processing, page 372, 2003.
+ *
* This file is a GNU parallel extension to the Standard C++ Library.
*/
diff --git a/libstdc++-v3/include/parallel/base.h b/libstdc++-v3/include/parallel/base.h
index 12bba0455fc..0a86d8351fe 100644
--- a/libstdc++-v3/include/parallel/base.h
+++ b/libstdc++-v3/include/parallel/base.h
@@ -112,14 +112,6 @@ namespace __gnu_parallel
};
- /** @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>
- {
- bool operator()(const T1& t1, const T2& t2) const
- { return t1 == t2; }
- };
-
/** @brief Similar to std::binder1st, but giving the argument types explicitly. */
template<typename _Predicate, typename argument_type>
class unary_negate
@@ -190,6 +182,14 @@ namespace __gnu_parallel
{ return op(__x, 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>
+ {
+ 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>
@@ -212,6 +212,53 @@ namespace __gnu_parallel
{ return __x < __y; }
};
+
+ /** @brief Similar to std::plus, but allows two different types. */
+ template<typename _Tp1, typename _Tp2>
+ struct plus : public std::binary_function<_Tp1, _Tp2, _Tp1>
+ {
+ typedef typeof(*static_cast<_Tp1*>(NULL) + *static_cast<_Tp2*>(NULL)) 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>
+ {
+ typedef typeof(*static_cast<_Tp*>(NULL) + *static_cast<_Tp*>(NULL)) result;
+
+ result
+ operator()(const _Tp& __x, const _Tp& __y) const
+ { return __x + __y; }
+ };
+
+
+ /** @brief Similar to std::multiplies, but allows two different types. */
+ template<typename _Tp1, typename _Tp2>
+ struct multiplies : public std::binary_function<_Tp1, _Tp2, _Tp1>
+ {
+ typedef typeof(*static_cast<_Tp1*>(NULL) * *static_cast<_Tp2*>(NULL)) 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>
+ {
+ typedef typeof(*static_cast<_Tp*>(NULL) * *static_cast<_Tp*>(NULL)) result;
+
+ result
+ operator()(const _Tp& __x, const _Tp& __y) const
+ { return __x * __y; }
+ };
+
+
template<typename T, typename _DifferenceTp>
class pseudo_sequence;
diff --git a/libstdc++-v3/include/parallel/for_each_selectors.h b/libstdc++-v3/include/parallel/for_each_selectors.h
index f1d0abf255b..392cc6ac7ea 100644
--- a/libstdc++-v3/include/parallel/for_each_selectors.h
+++ b/libstdc++-v3/include/parallel/for_each_selectors.h
@@ -335,8 +335,8 @@ namespace __gnu_parallel
explicit accumulate_binop_reduct(BinOp& b) : binop(b) {}
- template<typename T>
- inline T operator()(T x, T 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/multiseq_selection.h b/libstdc++-v3/include/parallel/multiseq_selection.h
index 5b34173cff2..208f4098f56 100644
--- a/libstdc++-v3/include/parallel/multiseq_selection.h
+++ b/libstdc++-v3/include/parallel/multiseq_selection.h
@@ -32,6 +32,13 @@
* @brief Functions to find elements of a certain global rank in
* multiple sorted sequences. Also serves for splitting such
* sequence sets.
+ *
+ * The algorithm description can be found in
+ *
+ * P. J. Varman, S. D. Scheufler, B. R. Iyer, and G. R. Ricard.
+ * Merging Multiple Lists on Hierarchical-Memory Multiprocessors.
+ * Journal of Parallel and Distributed Computing, 12(2):171–177, 1991.
+ *
* This file is a GNU parallel extension to the Standard C++ Library.
*/
diff --git a/libstdc++-v3/include/parallel/multiway_merge.h b/libstdc++-v3/include/parallel/multiway_merge.h
index 2a6c38a5a4f..c940e4578dc 100644
--- a/libstdc++-v3/include/parallel/multiway_merge.h
+++ b/libstdc++-v3/include/parallel/multiway_merge.h
@@ -30,6 +30,13 @@
/** @file parallel/multiway_merge.h
* @brief Implementation of sequential and parallel multiway merge.
+ *
+ * Explanations on the high-speed merging routines in the appendix of
+ *
+ * P. Sanders.
+ * Fast priority queues for cached memory.
+ * ACM Journal of Experimental Algorithmics, 5, 2000.
+ *
* This file is a GNU parallel extension to the Standard C++ Library.
*/
diff --git a/libstdc++-v3/include/parallel/numeric b/libstdc++-v3/include/parallel/numeric
index 4d71b8f1588..21b8eea3fdd 100644
--- a/libstdc++-v3/include/parallel/numeric
+++ b/libstdc++-v3/include/parallel/numeric
@@ -59,10 +59,10 @@ namespace __parallel
// Sequential fallback.
template<typename InputIterator, typename T>
inline T
- accumulate(InputIterator begin, InputIterator end, T init, __gnu_parallel::sequential_tag)
+ accumulate(InputIterator begin, InputIterator end, T init,
+ __gnu_parallel::sequential_tag)
{ return _GLIBCXX_STD_P::accumulate(begin, end, init); }
- // Sequential fallback.
template<typename InputIterator, typename T, typename BinaryOperation>
inline T
accumulate(InputIterator begin, InputIterator end, T init,
@@ -72,29 +72,25 @@ namespace __parallel
// Sequential fallback for input iterator case.
template<typename InputIterator, typename T, typename IteratorTag>
inline T
- accumulate_switch(InputIterator begin, InputIterator end, T init, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
- { return accumulate(begin, end, init, __gnu_parallel::sequential_tag()); }
+ accumulate_switch(InputIterator begin, InputIterator end, T init, IteratorTag) { return accumulate(begin, end, init, __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 = __gnu_parallel::parallel_unbalanced)
- {
- return accumulate_switch(begin, end, init, std::plus<typename std::iterator_traits<InputIterator>::value_type>(), typename std::iterator_traits<InputIterator>::iterator_category(), parallelism_tag);
- }
-
- // Sequential fallback for input iterator case.
template<typename InputIterator, typename T, typename BinaryOperation, typename IteratorTag>
T
- accumulate_switch(InputIterator begin, InputIterator end, T init, BinaryOperation binary_op, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
+ accumulate_switch(InputIterator begin, InputIterator end, T init,
+ BinaryOperation binary_op, IteratorTag)
{
- return accumulate(begin, end, init, binary_op, __gnu_parallel::sequential_tag());
+ 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)
+ accumulate_switch(_RandomAccessIterator begin, _RandomAccessIterator end,
+ T 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::accumulate_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
{
@@ -104,38 +100,81 @@ namespace __parallel
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, typename BinaryOperation>
+ template<typename InputIterator, typename T>
inline T
- accumulate(InputIterator begin, InputIterator end, T init, BinaryOperation binary_op, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_unbalanced)
+ accumulate(InputIterator begin, InputIterator end, T init,
+ __gnu_parallel::parallelism parallelism_tag)
{
- return accumulate_switch(begin, end, init, binary_op, typename std::iterator_traits<InputIterator>::iterator_category(), 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;
+
+ return accumulate_switch(begin, end, init, __gnu_parallel::plus<T, value_type>(),
+ iterator_category(), parallelism_tag);
}
+ template<typename InputIterator, typename T>
+ inline T
+ accumulate(InputIterator begin, InputIterator end, T init)
+ {
+ typedef std::iterator_traits<InputIterator> iterator_traits;
+ typedef typename iterator_traits::value_type value_type;
+ typedef typename iterator_traits::iterator_category iterator_category;
- // Sequential fallback.
- template<typename InputIterator1, typename InputIterator2, typename T, typename BinaryFunction1, typename BinaryFunction2>
+ return accumulate_switch(begin, end, init, __gnu_parallel::plus<T, value_type>(),
+ iterator_category());
+ }
+
+ template<typename InputIterator, typename T, typename BinaryOperation>
inline T
- inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, BinaryFunction1 binary_op1, BinaryFunction2 binary_op2, __gnu_parallel::sequential_tag)
+ accumulate(InputIterator begin, InputIterator end, T init,
+ BinaryOperation binary_op,
+ __gnu_parallel::parallelism parallelism_tag)
{
- return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init, binary_op1, binary_op2);
+ 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);
}
+ template<typename InputIterator, typename T, typename BinaryOperation>
+ inline T
+ accumulate(InputIterator begin, InputIterator end, T 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());
+ }
+
+
// 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)
+ 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);
+ 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)
+ 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)
{
if (_GLIBCXX_PARALLEL_CONDITION((last1 - first1) >= __gnu_parallel::Settings::accumulate_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
{
@@ -145,20 +184,45 @@ namespace __parallel
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, __gnu_parallel::parallelism parallelism_tag)
+ 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)
{
- return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init, binary_op1, binary_op2);
+ typedef iterator_traits<InputIterator1> traits1_type;
+ typedef typename traits1_type::iterator_category iterator1_category;
+
+ typedef iterator_traits<InputIterator2> traits2_type;
+ typedef typename traits2_type::iterator_category iterator2_category;
+
+ return inner_product_switch(first1, last1, first2, init, binary_op1,
+ binary_op2, iterator1_category(),
+ iterator2_category(), 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, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_unbalanced)
+ inner_product(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, T init, BinaryFunction1 binary_op1,
+ BinaryFunction2 binary_op2)
{
typedef iterator_traits<InputIterator1> traits1_type;
typedef typename traits1_type::iterator_category iterator1_category;
@@ -166,18 +230,45 @@ namespace __parallel
typedef iterator_traits<InputIterator2> traits2_type;
typedef typename traits2_type::iterator_category iterator2_category;
- 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, iterator1_category(),
+ iterator2_category());
}
template<typename InputIterator1, typename InputIterator2, typename T>
inline T
- inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_unbalanced)
+ inner_product(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, T init,
+ __gnu_parallel::parallelism parallelism_tag)
{
- typedef iterator_traits<InputIterator1> traits_type;
- typedef typename traits_type::value_type value_type;
+ typedef iterator_traits<InputIterator1> traits_type1;
+ typedef typename traits_type1::value_type value_type1;
+ typedef iterator_traits<InputIterator2> 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>(),
+ parallelism_tag);
+ }
- return inner_product(first1, last1, first2, init, std::plus<value_type>(),
- std::multiplies<value_type>(), parallelism_tag);
+ template<typename InputIterator1, typename InputIterator2, typename T>
+ inline T
+ inner_product(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, T init)
+ {
+ typedef iterator_traits<InputIterator1> traits_type1;
+ typedef typename traits_type1::value_type value_type1;
+ typedef iterator_traits<InputIterator2> 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>());
}
// Sequential fallback.
@@ -262,16 +353,21 @@ namespace __parallel
inline OutputIterator
adjacent_difference_switch(InputIterator begin, InputIterator end,
OutputIterator result, BinaryOperation bin_op,
- IteratorTag1, IteratorTag2, __gnu_parallel::parallelism)
- { return adjacent_difference(begin, end, result, 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)
+ 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::adjacent_difference_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
{
@@ -284,7 +380,8 @@ namespace __parallel
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.
@@ -292,19 +389,29 @@ namespace __parallel
inline OutputIterator
adjacent_difference(InputIterator begin, InputIterator end,
OutputIterator result,
- __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
+ __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);
+ }
+
+ template<typename InputIterator, typename OutputIterator>
+ inline OutputIterator
+ adjacent_difference(InputIterator begin, InputIterator 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>());
}
- // Public interface.
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 = __gnu_parallel::parallel_balanced)
+ __gnu_parallel::parallelism parallelism_tag)
{
typedef iterator_traits<InputIterator> traitsi_type;
typedef typename traitsi_type::iterator_category iteratori_category;
@@ -316,6 +423,22 @@ namespace __parallel
iteratori_category(),
iteratoro_category(), parallelism_tag);
}
+
+ template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
+ inline OutputIterator
+ adjacent_difference(InputIterator begin, InputIterator end,
+ OutputIterator result, BinaryOperation binary_op)
+ {
+ typedef iterator_traits<InputIterator> traitsi_type;
+ typedef typename traitsi_type::iterator_category iteratori_category;
+
+ typedef iterator_traits<OutputIterator> traitso_type;
+ typedef typename traitso_type::iterator_category iteratoro_category;
+
+ return adjacent_difference_switch(begin, end, result, binary_op,
+ iteratori_category(),
+ iteratoro_category());
+ }
} // end namespace
} // end namespace
diff --git a/libstdc++-v3/include/parallel/numericfwd.h b/libstdc++-v3/include/parallel/numericfwd.h
index 75fa3505f97..4181132c13a 100644
--- a/libstdc++-v3/include/parallel/numericfwd.h
+++ b/libstdc++-v3/include/parallel/numericfwd.h
@@ -46,32 +46,50 @@ namespace __parallel
{
template<typename _IIter, typename T>
inline T
- accumulate(_IIter, _IIter, T, __gnu_parallel::sequential_tag);
+ accumulate(_IIter, _IIter, T);
- template<typename _IIter, typename T, typename _BinaryOper>
+ template<typename _IIter, typename T>
inline T
- accumulate(_IIter, _IIter, T, _BinaryOper, __gnu_parallel::sequential_tag);
+ accumulate(_IIter, _IIter, T, __gnu_parallel::sequential_tag);
template<typename _IIter, typename T>
inline T
- accumulate(_IIter, _IIter, T, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_unbalanced);
+ accumulate(_IIter, _IIter, T, __gnu_parallel::parallelism parallelism_tag);
+
+ template<typename _IIter, typename T, typename _Tag>
+ inline T
+ accumulate_switch(_IIter, _IIter, T, _Tag);
template<typename _IIter, typename T, typename _BinaryOper>
inline T
- accumulate(_IIter, _IIter, T, _BinaryOper, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_unbalanced);
+ accumulate(_IIter, _IIter, T, _BinaryOper);
- template<typename _IIter, typename T, typename _Tag>
+ template<typename _IIter, typename T, typename _BinaryOper>
inline T
- accumulate_switch(_IIter, _IIter, T, _Tag, __gnu_parallel::parallelism parallelism_tag);
+ accumulate(_IIter, _IIter, T, _BinaryOper, __gnu_parallel::sequential_tag);
+
+ template<typename _IIter, typename T, typename _BinaryOper>
+ inline T
+ accumulate(_IIter, _IIter, T, _BinaryOper,
+ __gnu_parallel::parallelism parallelism_tag);
template<typename _IIter, typename T, typename _BinaryOper, typename _Tag>
T
- accumulate_switch(_IIter, _IIter, T, _BinaryOper, _Tag, __gnu_parallel::parallelism parallelism_tag);
+ accumulate_switch(_IIter, _IIter, T, _BinaryOper, _Tag);
template<typename _RAIter, typename T, typename _BinaryOper>
T
- accumulate_switch(_RAIter, _RAIter, T, _BinaryOper, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag);
+ accumulate_switch(_RAIter, _RAIter, T, _BinaryOper,
+ random_access_iterator_tag, __gnu_parallel::parallelism);
+
+ template<typename _IIter, typename _OIter>
+ inline _OIter
+ adjacent_difference(_IIter, _IIter, _OIter);
+
+ template<typename _IIter, typename _OIter, typename _BinaryOper>
+ inline _OIter
+ adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper);
template<typename _IIter, typename _OIter>
inline _OIter
@@ -79,48 +97,68 @@ namespace __parallel
template<typename _IIter, typename _OIter, typename _BinaryOper>
inline _OIter
- adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::sequential_tag);
+ adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper,
+ __gnu_parallel::sequential_tag);
template<typename _IIter, typename _OIter>
inline _OIter
- adjacent_difference(_IIter, _IIter, _OIter, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
+ adjacent_difference(_IIter, _IIter, _OIter, __gnu_parallel::parallelism);
template<typename _IIter, typename _OIter, typename _BinaryOper>
inline _OIter
- adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced);
+ adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper,
+ __gnu_parallel::parallelism);
template<typename _IIter, typename _OIter, typename _BinaryOper, typename _Tag1, typename _Tag2>
inline _OIter
- adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2, __gnu_parallel::parallelism);
+ 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_tag);
+ adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper,
+ random_access_iterator_tag,
+ random_access_iterator_tag,
+ __gnu_parallel::parallelism);
- template<typename _IIter1, typename _IIter2, typename T, typename BinaryFunction1, typename BinaryFunction2>
+ template<typename _IIter1, typename _IIter2, typename T>
inline T
- inner_product(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2, __gnu_parallel::sequential_tag);
+ inner_product(_IIter1, _IIter1, _IIter2, T);
template<typename _IIter1, typename _IIter2, typename T>
inline T
inner_product(_IIter1, _IIter1, _IIter2, T, __gnu_parallel::sequential_tag);
+ template<typename _IIter1, typename _IIter2, typename T>
+ inline T
+ inner_product(_IIter1, _IIter1, _IIter2, T, __gnu_parallel::parallelism);
+
+
template<typename _IIter1, typename _IIter2, typename T, typename BinaryFunction1, typename BinaryFunction2>
inline T
- inner_product(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_unbalanced);
+ inner_product(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2);
- template<typename _IIter1, typename _IIter2, typename T>
+ template<typename _IIter1, typename _IIter2, typename T, typename BinaryFunction1, typename BinaryFunction2>
+ inline T
+ inner_product(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2,
+ __gnu_parallel::sequential_tag);
+
+ template<typename _IIter1, typename _IIter2, typename T, typename BinaryFunction1, typename BinaryFunction2>
inline T
- inner_product(_IIter1, _IIter1, _IIter2, T, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_unbalanced);
+ inner_product(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2,
+ __gnu_parallel::parallelism);
template<typename _RAIter1, typename _RAIter2, typename T, typename BinaryFunction1, typename BinaryFunction2>
T
- inner_product_switch(_RAIter1, _RAIter1, _RAIter2, T, BinaryFunction1, BinaryFunction2, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag);
+ inner_product_switch(_RAIter1, _RAIter1, _RAIter2, T, BinaryFunction1,
+ BinaryFunction2, random_access_iterator_tag,
+ random_access_iterator_tag,
+ __gnu_parallel::parallelism);
template<typename _IIter1, typename _IIter2, typename T, typename BinaryFunction1, typename BinaryFunction2, typename _Tag1, typename _Tag2>
inline T
- inner_product_switch(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2, _Tag1, _Tag2, __gnu_parallel::parallelism parallelism_tag);
+ inner_product_switch(_IIter1, _IIter1, _IIter2, T, BinaryFunction1,
+ BinaryFunction2, _Tag1, _Tag2);
template<typename _IIter, typename _OIter>
diff --git a/libstdc++-v3/include/parallel/partial_sum.h b/libstdc++-v3/include/parallel/partial_sum.h
index 5a1a43e31a4..fbba6860184 100644
--- a/libstdc++-v3/include/parallel/partial_sum.h
+++ b/libstdc++-v3/include/parallel/partial_sum.h
@@ -128,26 +128,34 @@ namespace __gnu_parallel
if (id == 0)
{
*result = *begin;
- parallel_partial_sum_basecase(begin + 1, begin + borders[1], result + 1, bin_op, *begin);
+ parallel_partial_sum_basecase(begin + 1, begin + borders[1],
+ result + 1, bin_op, *begin);
sums[0] = *(result + borders[1] - 1);
}
else
{
- sums[id] = std::accumulate(begin + borders[id] + 1, begin + borders[id + 1], *(begin + borders[id]), bin_op, __gnu_parallel::sequential_tag());
+ sums[id] = std::accumulate(begin + borders[id] + 1,
+ begin + borders[id + 1],
+ *(begin + borders[id]),
+ 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[id + 1], begin + borders[id + 2], result + borders[id + 1], bin_op, sums[id]);
+ parallel_partial_sum_basecase(begin + borders[id + 1],
+ begin + borders[id + 2],
+ result + borders[id + 1], bin_op,
+ sums[id]);
}
- delete[] sums;
+ delete [] sums;
return result + n;
}
@@ -182,7 +190,7 @@ namespace __gnu_parallel
default:
// Partial_sum algorithm not implemented.
_GLIBCXX_PARALLEL_ASSERT(0);
- return end;
+ return result + n;
}
}
}
diff --git a/libstdc++-v3/include/parallel/partition.h b/libstdc++-v3/include/parallel/partition.h
index 790685bf0a5..70bff8e0af0 100644
--- a/libstdc++-v3/include/parallel/partition.h
+++ b/libstdc++-v3/include/parallel/partition.h
@@ -70,7 +70,9 @@ namespace __gnu_parallel
// Shared.
_GLIBCXX_VOLATILE difference_type left = 0, right = n - 1;
- _GLIBCXX_VOLATILE difference_type leftover_left, leftover_right, leftnew, rightnew;
+ _GLIBCXX_VOLATILE difference_type leftover_left, leftover_right;
+ _GLIBCXX_VOLATILE difference_type leftnew, rightnew;
+
bool* reserved_left, * reserved_right;
reserved_left = new bool[max_num_threads];
@@ -299,7 +301,8 @@ namespace __gnu_parallel
*/
template<typename RandomAccessIterator, typename Comparator>
void
- parallel_nth_element(RandomAccessIterator begin, RandomAccessIterator nth, RandomAccessIterator end, Comparator comp)
+ parallel_nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
+ RandomAccessIterator end, Comparator comp)
{
typedef std::iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
@@ -308,7 +311,6 @@ namespace __gnu_parallel
_GLIBCXX_CALL(end - begin)
RandomAccessIterator split;
- value_type pivot;
random_number rng;
difference_type minimum_length = std::max<difference_type>(2, Settings::partition_minimal_n);
diff --git a/libstdc++-v3/include/parallel/random_shuffle.h b/libstdc++-v3/include/parallel/random_shuffle.h
index fa546512a40..7a0f9a164cf 100644
--- a/libstdc++-v3/include/parallel/random_shuffle.h
+++ b/libstdc++-v3/include/parallel/random_shuffle.h
@@ -39,12 +39,8 @@
#define _GLIBCXX_PARALLEL_RANDOM_SHUFFLE_H 1
#include <limits>
-
-#include <parallel/basic_iterator.h>
-#include <bits/stl_algo.h>
-
+#include <bits/stl_numeric.h>
#include <parallel/parallel.h>
-#include <parallel/base.h>
#include <parallel/random_number.h>
#include <parallel/timing.h>
@@ -125,15 +121,16 @@ namespace __gnu_parallel
* @param rng Random number generator to use.
*/
template<typename RandomNumberGenerator>
- inline int random_number_pow2(int logp, RandomNumberGenerator& rng)
- {
- return rng.genrand_bits(logp);
- }
+ inline int
+ 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>
- inline void parallel_random_shuffle_drs_pu(DRSSorterPU<RandomAccessIterator, RandomNumberGenerator>* pus)
+ inline void
+ parallel_random_shuffle_drs_pu(DRSSorterPU<RandomAccessIterator,
+ RandomNumberGenerator>* pus)
{
typedef std::iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
@@ -184,7 +181,9 @@ namespace __gnu_parallel
// 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++)
- partial_sum(sd->dist[s + 1], sd->dist[s + 1] + d->num_threads + 1, sd->dist[s + 1]);
+ __gnu_sequential::partial_sum(sd->dist[s + 1],
+ sd->dist[s + 1] + d->num_threads + 1,
+ sd->dist[s + 1]);
}
#pragma omp barrier
@@ -263,7 +262,8 @@ namespace __gnu_parallel
/** @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)
+ T
+ round_up_to_pow2(T x)
{
if (x <= 1)
return 1;
@@ -396,7 +396,9 @@ namespace __gnu_parallel
*/
template<typename RandomAccessIterator, typename RandomNumberGenerator>
inline void
- sequential_random_shuffle(RandomAccessIterator begin, RandomAccessIterator end, RandomNumberGenerator& rng)
+ sequential_random_shuffle(RandomAccessIterator begin,
+ RandomAccessIterator end,
+ RandomNumberGenerator& rng)
{
typedef std::iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
@@ -468,7 +470,7 @@ namespace __gnu_parallel
t.tic();
// Sum up bins.
- partial_sum(dist0, dist0 + num_bins + 1, dist0);
+ __gnu_sequential::partial_sum(dist0, dist0 + num_bins + 1, dist0);
for (int b = 0; b < num_bins + 1; b++)
dist1[b] = dist0[b];
@@ -503,7 +505,8 @@ namespace __gnu_parallel
*/
template<typename RandomAccessIterator, typename RandomNumberGenerator>
inline void
- parallel_random_shuffle(RandomAccessIterator begin, RandomAccessIterator end, RandomNumberGenerator rng = random_number())
+ parallel_random_shuffle(RandomAccessIterator begin, RandomAccessIterator end,
+ RandomNumberGenerator rng = random_number())
{
typedef std::iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::difference_type difference_type;
diff --git a/libstdc++-v3/include/parallel/search.h b/libstdc++-v3/include/parallel/search.h
index af6bd8541f6..91a049fcbe8 100644
--- a/libstdc++-v3/include/parallel/search.h
+++ b/libstdc++-v3/include/parallel/search.h
@@ -55,7 +55,8 @@ namespace __gnu_parallel
*/
template<typename RandomAccessIterator, typename _DifferenceTp>
void
- calc_borders(RandomAccessIterator elements, _DifferenceTp length, _DifferenceTp* off)
+ calc_borders(RandomAccessIterator elements, _DifferenceTp length,
+ _DifferenceTp* off)
{
typedef _DifferenceTp difference_type;
@@ -65,7 +66,7 @@ namespace __gnu_parallel
difference_type k = 0;
for (difference_type j = 2; j <= length; j++)
{
- while ((k >= 0) && (elements[k] != elements[j-1]))
+ while ((k >= 0) && !(elements[k] == elements[j-1]))
k = off[k];
off[j] = ++k;
}
diff --git a/libstdc++-v3/include/parallel/tags.h b/libstdc++-v3/include/parallel/tags.h
index 438b1647509..c3d33e882c6 100644
--- a/libstdc++-v3/include/parallel/tags.h
+++ b/libstdc++-v3/include/parallel/tags.h
@@ -49,7 +49,14 @@ namespace std
* @namespace __gnu_sequential
* @brief GNU sequential classes for public use.
*/
-namespace __gnu_sequential { }
+namespace __gnu_sequential
+{
+#ifdef _GLIBCXX_PARALLEL
+ using namespace std::__norm;
+#else
+ using namespace std;
+#endif
+}
/**
* @namespace __gnu_parallel
diff --git a/libstdc++-v3/include/parallel/tree.h b/libstdc++-v3/include/parallel/tree.h
index a89dc62cb7b..5b7b41c6ef9 100644
--- a/libstdc++-v3/include/parallel/tree.h
+++ b/libstdc++-v3/include/parallel/tree.h
@@ -30,6 +30,13 @@
/** @file parallel/tree.h
* @brief Parallel red-black tree operations.
+ *
+ * This implementation is described in
+ *
+ * Leonor Frias, Johannes Singler.
+ * Parallelization of Bulk Operations for STL Dictionaries.
+ * Workshop on Highly Parallel Processing on a Chip (HPPC) 2007.
+ *
* This file is a GNU parallel extension to the Standard C++ Library.
*/
@@ -159,7 +166,8 @@ namespace __gnu_parallel
* @param _Alloc Allocator for the elements */
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc = std::allocator<_Val> >
- class _Rb_tree : public std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>
+ class _Rb_tree
+ : public std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>
{
private:
/** @brief Sequential tree */
@@ -214,7 +222,8 @@ namespace __gnu_parallel
* @param a Allocator object with which to initialize the class comparator
*/
_Rb_tree(const _Compare& c, const _Alloc& a)
- : base_type(c, a), strictly_less(base_type::_M_impl._M_key_compare), less_equal(base_type::_M_impl._M_key_compare)
+ : base_type(c, a), strictly_less(base_type::_M_impl._M_key_compare),
+ less_equal(base_type::_M_impl._M_key_compare)
{ }
/** @brief Copy constructor.
@@ -224,7 +233,8 @@ namespace __gnu_parallel
* @param __x Parallel red-black instance to copy
*/
_Rb_tree(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x)
- : base_type(__x), strictly_less(base_type::_M_impl._M_key_compare), less_equal(base_type::_M_impl._M_key_compare)
+ : base_type(__x), strictly_less(base_type::_M_impl._M_key_compare),
+ less_equal(base_type::_M_impl._M_key_compare)
{ }
/** @brief Parallel replacement of the sequential
@@ -244,12 +254,14 @@ namespace __gnu_parallel
if (_GLIBCXX_PARALLEL_CONDITION(true))
if (base_type::_M_impl._M_node_count == 0)
{
- _M_bulk_insertion_construction(__first, __last, true, strictly_less);
+ _M_bulk_insertion_construction(__first, __last, true,
+ strictly_less);
_GLIBCXX_PARALLEL_ASSERT(rb_verify());
}
else
{
- _M_bulk_insertion_construction(__first, __last, false, strictly_less);
+ _M_bulk_insertion_construction(__first, __last, false,
+ strictly_less);
_GLIBCXX_PARALLEL_ASSERT(rb_verify());
}
else
@@ -293,8 +305,9 @@ namespace __gnu_parallel
class nodes_initializer
{
/** @brief Renaming of tree size_type */
-
- typedef typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type size_type;
+
+ typedef _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> tree_type;
+ typedef typename tree_type::size_type size_type;
public:
/** @brief mask[%i]= 0..01..1, where the number of 1s is %i+1 */
@@ -328,7 +341,8 @@ namespace __gnu_parallel
* @param _n Total number of (used) nodes
* @param _num_threads Number of threads into which divide the work
* @param _rank Helper object to mind potential gaps in @c r_init */
- nodes_initializer(const _Rb_tree_node_ptr* r, const size_type _n, const thread_index_t _num_threads, const ranker& _rank):
+ nodes_initializer(const _Rb_tree_node_ptr* r, const size_type _n,
+ const thread_index_t _num_threads, const ranker& _rank):
r_init(r),
n(_n),
num_threads(_num_threads),
@@ -352,24 +366,21 @@ namespace __gnu_parallel
/** @brief Query for tree height
* @return Tree height */
- int get_height() const
- {
- return height;
- }
+ int
+ get_height() const
+ { return height; }
/** @brief Query for the splitting point
* @return Splitting point */
- size_type get_shifted_splitting_point() const
- {
- return rank.get_shifted_rank(splitting_point, 0);
- }
+ size_type
+ get_shifted_splitting_point() const
+ { return rank.get_shifted_rank(splitting_point, 0); }
/** @brief Query for the tree root node
* @return Tree root node */
- _Rb_tree_node_ptr get_root() const
- {
- return r_init[rank.get_shifted_rank(rank_root,num_threads/2)];
- }
+ _Rb_tree_node_ptr
+ get_root() const
+ { return r_init[rank.get_shifted_rank(rank_root,num_threads/2)]; }
/** @brief Calculation of the parent position in the array of nodes
* @hideinitializer */
@@ -386,7 +397,8 @@ namespace __gnu_parallel
* @param iam Partition of the array in which the node is, where
* iam is in [0..num_threads)
* @sa link_complete */
- void link_incomplete(const _Rb_tree_node_ptr& r, const int iam) const
+ void
+ link_incomplete(const _Rb_tree_node_ptr& r, const int iam) const
{
size_type real_pos = rank.get_real_rank(&r-r_init, iam);
size_type l_s, r_s, p_s;
@@ -438,7 +450,8 @@ namespace __gnu_parallel
* iam is in [0..@c num_threads)
* @sa link_incomplete
*/
- void link_complete(const _Rb_tree_node_ptr& r, const int iam) const
+ void
+ link_complete(const _Rb_tree_node_ptr& r, const int iam) const
{
size_type real_pos = rank.get_real_rank(&r-r_init, iam);
size_type p_s;
@@ -477,20 +490,18 @@ namespace __gnu_parallel
* @param pos Rank in the actual incomplete tree
* @return Rank in the corresponding complete tree
* @sa complete_to_original */
- int original_to_complete(const int pos) const
- {
- return (pos << 1) - splitting_point;
- }
+ int
+ original_to_complete(const int pos) const
+ { return (pos << 1) - splitting_point; }
/** @brief Change of "base": Convert the rank if the tree was
complete into the corresponding rank in the actual tree
* @param pos Rank in the complete tree
* @return Rank in the actual incomplete tree
* @sa original_to_complete */
- int complete_to_original(const int pos) const
- {
- return (pos + splitting_point) >> 1;
- }
+ int
+ complete_to_original(const int pos) const
+ { return (pos + splitting_point) >> 1; }
/** @brief Calculate the rank in the complete tree of the parent
@@ -506,7 +517,10 @@ namespace __gnu_parallel
* @param parent_shift Rank in the complete tree of the parent
* of pos (out parameter)
*/
- void calculate_shifts_pos_level(const size_type pos, const int level, size_type& left_shift, size_type& right_shift, size_type& parent_shift) const
+ void
+ calculate_shifts_pos_level(const size_type pos, const int level,
+ size_type& left_shift, size_type& right_shift,
+ size_type& parent_shift) const
{
int stride = 1 << (level -1);
left_shift = pos - stride;
@@ -523,7 +537,8 @@ namespace __gnu_parallel
* @return Position of the first 0 bit in @c x (starting to
* count with 1)
*/
- int first_0_right(const size_type x) const
+ int
+ first_0_right(const size_type x) const
{
if ((x & 0x2) == 0)
return 1;
@@ -540,7 +555,8 @@ namespace __gnu_parallel
* whose first 0 bit must be calculated
* @param k_beg Position in which to start searching. By default is 2.
* @return Position of the first 0 bit in x (starting to count with 1) */
- int first_0_right_bs(const size_type x, int k_beg=2) const
+ int
+ first_0_right_bs(const size_type x, int k_beg=2) const
{
int k_end = sizeof(size_type)*8;
size_type not_x = x ^ mask[k_end-1];
@@ -566,7 +582,8 @@ namespace __gnu_parallel
class ranker_gaps
{
/** @brief Renaming of tree's size_type */
- typedef typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type size_type;
+ typedef _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> tree_type;
+ typedef typename tree_type::size_type size_type;
/** @brief Array containing the beginning ranks of all the
num_threads partitions just considering the valid nodes, not
@@ -594,7 +611,8 @@ namespace __gnu_parallel
* gaps at the beginning of each partition
* @param _num_threads Number of partitions (and threads that
* work on it) */
- ranker_gaps(const size_type* size_p, const size_type* shift_r, const thread_index_t _num_threads) :
+ ranker_gaps(const size_type* size_p, const size_type* shift_r,
+ const thread_index_t _num_threads) :
beg_shift_partition(size_p),
rank_shift(shift_r),
num_threads(_num_threads)
@@ -616,9 +634,7 @@ namespace __gnu_parallel
* been allocated for beg_partition array
*/
~ranker_gaps()
- {
- delete[] beg_partition;
- }
+ { delete[] beg_partition; }
/** @brief Convert a rank in the array of nodes considering
valid nodes and gaps, to the corresponding considering only
@@ -628,10 +644,9 @@ namespace __gnu_parallel
* @return Rank in the array of nodes considering only the valid nodes
* @sa get_shifted_rank
*/
- size_type get_real_rank(const size_type pos, const int index) const
- {
- return pos - rank_shift[index];
- }
+ size_type
+ get_real_rank(const size_type pos, const int index) const
+ { return pos - rank_shift[index]; }
/** @brief Inverse of get_real_rank: Convert a rank in the array
of nodes considering only valid nodes, to the corresponding
@@ -644,7 +659,8 @@ namespace __gnu_parallel
* @post 0 <= @c return <= number_of_elements
* @sa get_real_rank()
*/
- size_type get_shifted_rank(const size_type pos, const int index) const
+ size_type
+ get_shifted_rank(const size_type pos, const int index) const
{
// Heuristic.
if (beg_partition[index] <= pos and pos < beg_partition[index+1])
@@ -662,7 +678,8 @@ namespace __gnu_parallel
* if there were no gaps
* @return Rank in the array of nodes considering valid nodes and gaps
*/
- size_type get_shifted_rank_loop(const size_type pos, int index) const
+ size_type
+ get_shifted_rank_loop(const size_type pos, int index) const
{
while (pos >= beg_partition[index+1])
++index;
@@ -681,7 +698,8 @@ namespace __gnu_parallel
class ranker_no_gaps
{
/** @brief Renaming of tree's size_type */
- typedef typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type size_type;
+ typedef _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> tree_type;
+ typedef typename tree_type::size_type size_type;
public:
/** @brief Convert a rank in the array of nodes considering
@@ -693,10 +711,9 @@ namespace __gnu_parallel
* @param pos Rank in the array of nodes considering valid nodes and gaps
* @param index Partition which the rank belongs to, unused here
* @return Rank in the array of nodes considering only the valid nodes */
- size_type get_real_rank(const size_type pos, const int index) const
- {
- return pos;
- }
+ size_type
+ get_real_rank(const size_type pos, const int index) const
+ { return pos; }
/** @brief Inverse of get_real_rank: Convert a rank in the array
* of nodes considering only valid nodes, to the corresponding
@@ -708,10 +725,9 @@ namespace __gnu_parallel
* @param index Partition which the rank belongs to, unused here
* @return Rank in the array of nodes considering valid nodes and gaps
*/
- size_type get_shifted_rank(const size_type pos, const int index) const
- {
- return pos;
- }
+ size_type
+ get_shifted_rank(const size_type pos, const int index) const
+ { return pos; }
};
@@ -777,7 +793,8 @@ namespace __gnu_parallel
* the element pointed by the the class member @c prev */
void operator()(const _InputIterator it)
{
- if (sorted and it != prev and comp(_KeyOfValue()(*it),_KeyOfValue()(*prev)))
+ if (sorted and it != prev and comp(_KeyOfValue()(*it),
+ _KeyOfValue()(*prev)))
sorted = false;
prev = it;
}
@@ -840,8 +857,10 @@ namespace __gnu_parallel
{ return c(k, base_type::_S_key(r)); }
};
- /** @brief Helper comparator: compare a key with the key of a value pointed by an iterator
- * @param _Comparator Comparator for keys */
+ /** @brief Helper comparator: compare a key with the key of a
+ value pointed by an iterator
+ * @param _Comparator Comparator for keys
+ */
template<typename _Iterator, typename _Comparator>
struct compare_value_key
{
@@ -914,7 +933,8 @@ namespace __gnu_parallel
* @param Comparator Comparator for values
* @param _ValuePtr Pointer to values */
template<typename Comparator, typename _ValuePtr>
- class PtrComparator : public std::binary_function<_ValuePtr, _ValuePtr, bool>
+ class PtrComparator
+ : public std::binary_function<_ValuePtr, _ValuePtr, bool>
{
/** @brief Comparator for values */
Comparator comp;
@@ -1108,11 +1128,9 @@ namespace __gnu_parallel
* @param _par_problem Parent concatenation problem to solve
* when @c is_ready = READY_YES
*/
- concat_problem(const _Rb_tree_node_ptr _t, const int _black_h, concat_problem* _par_problem):
- t(_t),
- black_h(_black_h),
- is_ready(READY_NO),
- par_problem(_par_problem)
+ concat_problem(const _Rb_tree_node_ptr _t, const int _black_h,
+ concat_problem* _par_problem)
+ : t(_t), black_h(_black_h), is_ready(READY_NO), par_problem(_par_problem)
{
// The root of an insertion problem must be black.
if (t != NULL and t->_M_color == std::_S_red)
@@ -1131,7 +1149,8 @@ namespace __gnu_parallel
struct insertion_problem
{
/** @brief Renaming of _Rb_tree @c size_type */
- typedef typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type size_type;
+ typedef _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> tree_type;
+ typedef typename tree_type::size_type size_type;
/** @brief Root of the tree where the elements are to be inserted */
_Rb_tree_node_ptr t;
@@ -1166,8 +1185,10 @@ namespace __gnu_parallel
* @param _conc Concatenation problem to solve once the
* insertion problem is finished
*/
- insertion_problem(const size_type b, const size_type e, const int array_p, concat_problem* _conc)
- : t(_conc->t), pos_beg(b), pos_end(e), array_partition(array_p), conc(_conc)
+ insertion_problem(const size_type b, const size_type e,
+ const int array_p, concat_problem* _conc)
+ : t(_conc->t), pos_beg(b), pos_end(e), array_partition(array_p),
+ conc(_conc)
{
_GLIBCXX_PARALLEL_ASSERT(pos_beg <= pos_end);
@@ -1233,9 +1254,11 @@ namespace __gnu_parallel
}
if (is_construction)
- _M_sorted_bulk_construction(access, beg_partition, n, num_threads, strictly_less_or_less_equal);
+ _M_sorted_bulk_construction(access, beg_partition, n, num_threads,
+ strictly_less_or_less_equal);
else
- _M_sorted_bulk_insertion(access, beg_partition, n, num_threads, strictly_less_or_less_equal);
+ _M_sorted_bulk_insertion(access, beg_partition, n, num_threads,
+ strictly_less_or_less_equal);
}
t.tic("main work");
@@ -1262,7 +1285,10 @@ namespace __gnu_parallel
* @param is_construction If true, the tree was empty and so, this
* is constructed. Otherwise, the elements are added to an
* existing tree.
- * @param strictly_less_or_less_equal Comparator to deal transparently with repetitions with respect to the uniqueness of the wrapping container */
+ * @param strictly_less_or_less_equal Comparator to deal
+ * transparently with repetitions with respect to the uniqueness
+ * of the wrapping container
+ */
template<typename _InputIterator, typename StrictlyLessOrLessEqual>
void
_M_not_sorted_bulk_insertion_construction(_InputIterator* access,
@@ -1270,7 +1296,7 @@ namespace __gnu_parallel
const size_type n,
const thread_index_t num_threads,
const bool is_construction,
- StrictlyLessOrLessEqual strictly_less_or_less_equal)
+ StrictlyLessOrLessEqual strictly_less_or_less_equal)
{
// Copy entire elements. In the case of a map, we would be
// copying the pair. Therefore, the copy should be reconsidered
@@ -1360,7 +1386,8 @@ namespace __gnu_parallel
* @param black_h Black height of the resulting tree (out)
*/
static _Rb_tree_node_ptr
- simple_tree_construct(_Rb_tree_node_ptr* r_array, const size_type pos_beg, const size_type pos_end, int& black_h)
+ simple_tree_construct(_Rb_tree_node_ptr* r_array, const size_type pos_beg,
+ const size_type pos_end, int& black_h)
{
if (pos_beg == pos_end)
{
@@ -1416,7 +1443,8 @@ namespace __gnu_parallel
* going to be shared
*/
template<typename _Iterator>
- _Rb_tree_node_ptr* _M_unsorted_bulk_allocation_and_initialization(const _Iterator* access, const size_type* beg_partition, const size_type n, const thread_index_t num_threads)
+ _Rb_tree_node_ptr*
+ _M_unsorted_bulk_allocation_and_initialization(const _Iterator* access, const size_type* beg_partition, const size_type n, const thread_index_t num_threads)
{
_Rb_tree_node_ptr* r = static_cast<_Rb_tree_node_ptr*> (::operator new (sizeof(_Rb_tree_node_ptr)*(n+1)));
@@ -1471,7 +1499,8 @@ namespace __gnu_parallel
* of the wrapping container
*/
template<typename _Iterator, typename StrictlyLessOrLessEqual>
- _Rb_tree_node_ptr* _M_sorted_bulk_allocation_and_initialization(_Iterator* access, size_type* beg_partition, size_type* rank_shift, const size_type n, thread_index_t& num_threads, StrictlyLessOrLessEqual strictly_less_or_less_equal)
+ _Rb_tree_node_ptr*
+ _M_sorted_bulk_allocation_and_initialization(_Iterator* access, size_type* beg_partition, size_type* rank_shift, const size_type n, thread_index_t& num_threads, StrictlyLessOrLessEqual strictly_less_or_less_equal)
{
// Ghost node at the end to avoid extra comparisons in nodes_initializer.
_Rb_tree_node_ptr* r = static_cast<_Rb_tree_node_ptr*> (::operator new (sizeof(_Rb_tree_node_ptr)*(n+1)));
@@ -1598,7 +1627,8 @@ namespace __gnu_parallel
* of the wrapping container
*/
template<typename _Iterator, typename StrictlyLessOrLessEqual>
- _Rb_tree_node_ptr* _M_sorted_no_gapped_bulk_allocation_and_initialization(_Iterator* access, size_type* beg_partition, size_type& n, const thread_index_t num_threads, StrictlyLessOrLessEqual strictly_less_or_less_equal)
+ _Rb_tree_node_ptr*
+ _M_sorted_no_gapped_bulk_allocation_and_initialization(_Iterator* access, size_type* beg_partition, size_type& n, const thread_index_t num_threads, StrictlyLessOrLessEqual strictly_less_or_less_equal)
{
size_type* sums = static_cast<size_type*> (::operator new (sizeof(size_type)*n));
// Allocate and initialize the nodes
@@ -2260,7 +2290,8 @@ namespace __gnu_parallel
* @return Resulting tree after the elements have been inserted
*/
template<typename StrictlyLessOrLessEqual>
- _Rb_tree_node_ptr _M_bulk_insertion_merge(_Rb_tree_node_ptr* r_array, _Rb_tree_node_ptr t, const size_type pos_beg, const size_type pos_end, size_type& existing, int& black_h, StrictlyLessOrLessEqual strictly_less_or_less_equal)
+ _Rb_tree_node_ptr
+ _M_bulk_insertion_merge(_Rb_tree_node_ptr* r_array, _Rb_tree_node_ptr t, const size_type pos_beg, const size_type pos_end, size_type& existing, int& black_h, StrictlyLessOrLessEqual strictly_less_or_less_equal)
{
#ifndef NDEBUG
int count;
@@ -2333,7 +2364,8 @@ namespace __gnu_parallel
* of the wrapping container
*/
template<typename StrictlyLessOrLessEqual>
- void _M_bulk_insertion_merge_concatenate(_Rb_tree_node_ptr* r, insertion_problem& ip, size_type& existing, StrictlyLessOrLessEqual strictly_less_or_less_equal)
+ void
+ _M_bulk_insertion_merge_concatenate(_Rb_tree_node_ptr* r, insertion_problem& ip, size_type& existing, StrictlyLessOrLessEqual strictly_less_or_less_equal)
{
concat_problem* conc = ip.conc;
_GLIBCXX_PARALLEL_ASSERT(ip.pos_beg <= ip.pos_end);
@@ -2675,7 +2707,8 @@ namespace __gnu_parallel
static int
black_height(const _Rb_tree_node_ptr t)
{
- if (t == NULL) return 0;
+ if (t == NULL)
+ return 0;
int bh = black_height (static_cast<const _Rb_tree_node_ptr> (t->_M_left));
if (t->_M_color == std::_S_black)
++bh;
@@ -2719,7 +2752,8 @@ namespace __gnu_parallel
*/
template<typename S>
static _Rb_tree_node_ptr
- plant(const _Rb_tree_node_ptr root, const _Rb_tree_node_ptr l, const _Rb_tree_node_ptr r)
+ plant(const _Rb_tree_node_ptr root, const _Rb_tree_node_ptr l,
+ const _Rb_tree_node_ptr r)
{
S::left(root) = l;
S::right(root) = r;
@@ -2744,7 +2778,9 @@ namespace __gnu_parallel
* @post @c t is correct red-black tree with height @c black_h.
*/
void
- concatenate(_Rb_tree_node_ptr root, _Rb_tree_node_ptr l, _Rb_tree_node_ptr r, int black_h_l, int black_h_r, _Rb_tree_node_ptr& t, int& black_h) const
+ concatenate(_Rb_tree_node_ptr root, _Rb_tree_node_ptr l,
+ _Rb_tree_node_ptr r, int black_h_l, int black_h_r,
+ _Rb_tree_node_ptr& t, int& black_h) const
{
#ifndef NDEBUG
int count = 0, count1 = 0, count2 = 0;
@@ -2826,7 +2862,9 @@ namespace __gnu_parallel
*/
template<typename S>
static void
- concatenate(const _Rb_tree_node_ptr rt, _Rb_tree_node_ptr l, _Rb_tree_node_ptr r, int black_h_l, int black_h_r, _Rb_tree_node_ptr& t, int& black_h)
+ concatenate(const _Rb_tree_node_ptr rt, _Rb_tree_node_ptr l,
+ _Rb_tree_node_ptr r, int black_h_l, int black_h_r,
+ _Rb_tree_node_ptr& t, int& black_h)
{
_Rb_tree_node_base* root = l;
_Rb_tree_node_ptr parent = NULL;
@@ -2888,7 +2926,10 @@ namespace __gnu_parallel
* @return Black height of t */
template<typename StrictlyLessOrEqual>
int
- split(_Rb_tree_node_ptr t, const key_type& key, const key_type& prev_k, _Rb_tree_node_ptr& root, _Rb_tree_node_ptr& l, _Rb_tree_node_ptr& r, int& black_h_l, int& black_h_r, StrictlyLessOrEqual strictly_less_or_less_equal) const
+ split(_Rb_tree_node_ptr t, const key_type& key, const key_type& prev_k,
+ _Rb_tree_node_ptr& root, _Rb_tree_node_ptr& l, _Rb_tree_node_ptr& r,
+ int& black_h_l, int& black_h_r,
+ StrictlyLessOrEqual strictly_less_or_less_equal) const
{
if (t != NULL)
{
@@ -2936,7 +2977,11 @@ namespace __gnu_parallel
* @return Black height of t */
template<typename StrictlyLessOrEqual>
int
- split_not_null(const _Rb_tree_node_ptr t, const key_type& key, const key_type& prev_k, _Rb_tree_node_ptr& root, _Rb_tree_node_ptr& l, _Rb_tree_node_ptr& r, int& black_h_l, int& black_h_r, StrictlyLessOrEqual strictly_less_or_equal) const
+ split_not_null(const _Rb_tree_node_ptr t, const key_type& key,
+ const key_type& prev_k, _Rb_tree_node_ptr& root,
+ _Rb_tree_node_ptr& l, _Rb_tree_node_ptr& r, int& black_h_l,
+ int& black_h_r,
+ StrictlyLessOrEqual strictly_less_or_equal) const
{
_GLIBCXX_PARALLEL_ASSERT (t != NULL);
int black_h, b_h;
@@ -3039,7 +3084,8 @@ namespace __gnu_parallel
* @param black_h_r Black height of the right subtree.
* @return Black height of the original tree */
int
- extract_min(const _Rb_tree_node_ptr t, _Rb_tree_node_ptr& root, _Rb_tree_node_ptr& r, int& black_h_r) const
+ extract_min(const _Rb_tree_node_ptr t, _Rb_tree_node_ptr& root,
+ _Rb_tree_node_ptr& r, int& black_h_r) const
{
_GLIBCXX_PARALLEL_ASSERT (t != NULL);
int black_h, b_h;
@@ -3087,7 +3133,8 @@ namespace __gnu_parallel
* @param black_h_l Black height of the left subtree.
* @return Black height of the original tree */
int
- extract_max(const _Rb_tree_node_ptr t, _Rb_tree_node_ptr& root, _Rb_tree_node_ptr& l, int& black_h_l) const
+ extract_max(const _Rb_tree_node_ptr t, _Rb_tree_node_ptr& root,
+ _Rb_tree_node_ptr& l, int& black_h_l) const
{
_GLIBCXX_PARALLEL_ASSERT (t != NULL);
int black_h, b_h;
@@ -3138,7 +3185,9 @@ namespace __gnu_parallel
* @param black_h_r Black height of the right subtree.
* @return Black height of the original tree */
int
- split(const _Rb_tree_node_ptr t, const key_type& key, _Rb_tree_node_ptr& l, _Rb_tree_node_ptr& r, int& black_h_l, int& black_h_r) const
+ split(const _Rb_tree_node_ptr t, const key_type& key,
+ _Rb_tree_node_ptr& l, _Rb_tree_node_ptr& r, int& black_h_l,
+ int& black_h_r) const
{
if (t != NULL)
{
@@ -3197,7 +3246,9 @@ namespace __gnu_parallel
* @return Resulting tree after insertion */
template<typename StrictlyLessOrLessEqual>
_Rb_tree_node_ptr
- _M_insert_local(_Rb_tree_node_base* t, const _Rb_tree_node_ptr new_t, size_type& existing, int& black_h, StrictlyLessOrLessEqual strictly_less_or_less_equal)
+ _M_insert_local(_Rb_tree_node_base* t, const _Rb_tree_node_ptr new_t,
+ size_type& existing, int& black_h,
+ StrictlyLessOrLessEqual strictly_less_or_less_equal)
{
_GLIBCXX_PARALLEL_ASSERT(t != NULL);
if (_M_insert_local_top_down(t, new_t, NULL, NULL, true, strictly_less_or_less_equal))
@@ -3233,7 +3284,11 @@ namespace __gnu_parallel
*/
template<typename StrictlyLessOrLessEqual>
bool
- _M_insert_local_top_down(_Rb_tree_node_base* t, const _Rb_tree_node_ptr new_t, _Rb_tree_node_base* eq_t, _Rb_tree_node_base* parent, const bool is_left, StrictlyLessOrLessEqual strictly_less_or_less_equal) const
+ _M_insert_local_top_down(_Rb_tree_node_base* t,
+ const _Rb_tree_node_ptr new_t,
+ _Rb_tree_node_base* eq_t,
+ _Rb_tree_node_base* parent, const bool is_left,
+ StrictlyLessOrLessEqual strictly_less_or_less_equal) const
{
if (t != NULL)
{
@@ -3398,7 +3453,8 @@ namespace __gnu_parallel
* @return Tree correct.
*/
static bool
- rb_verify_tree(const typename base_type::_Const_Link_type __x, int& count, int& black_h)
+ rb_verify_tree(const typename base_type::_Const_Link_type __x, int& count,
+ int& black_h)
{
if (__x == NULL)
{
diff --git a/libstdc++-v3/include/parallel/workstealing.h b/libstdc++-v3/include/parallel/workstealing.h
index cc8f37e8d09..0b2102c45ed 100644
--- a/libstdc++-v3/include/parallel/workstealing.h
+++ b/libstdc++-v3/include/parallel/workstealing.h
@@ -31,6 +31,13 @@
/** @file parallel/workstealing.h
* @brief Parallelization of embarrassingly parallel execution by
* means of work-stealing.
+ *
+ * Work stealing is described in
+ *
+ * R. D. Blumofe and C. E. Leiserson.
+ * Scheduling multithreaded computations by work stealing.
+ * Journal of the ACM, 46(5):720–748, 1999.
+ *
* This file is a GNU parallel extension to the Standard C++ Library.
*/
diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility
index e9376dc8c70..67e4b7338e9 100644
--- a/libstdc++-v3/include/std/utility
+++ b/libstdc++-v3/include/std/utility
@@ -84,29 +84,7 @@
# undef _GLIBCXX_BEGIN_NAMESPACE_TR1
# undef _GLIBCXX_INCLUDE_AS_CXX0X
# endif
-
-#include <type_traits>
-
-namespace std
-{
- // 20.2.2, forward/move
- template<typename _Tp>
- struct identity
- {
- typedef _Tp type;
- };
-
- template<typename _Tp>
- inline _Tp&&
- forward(typename std::identity<_Tp>::type&& __t)
- { return __t; }
-
- template<typename _Tp>
- inline typename std::remove_reference<_Tp>::type&&
- move(_Tp&& __t)
- { return __t; }
-}
-
+# include <bits/stl_move.h>
#endif
#endif /* _GLIBCXX_UTILITY */
diff --git a/libstdc++-v3/include/tr1/functional b/libstdc++-v3/include/tr1/functional
index 78f6b925eee..190f61ae66b 100644
--- a/libstdc++-v3/include/tr1/functional
+++ b/libstdc++-v3/include/tr1/functional
@@ -45,6 +45,7 @@
#include <cmath>
#include <typeinfo>
+#include <new>
#include <tr1/tuple>
#include <tr1/type_traits>
#include <bits/stringfwd.h>
diff --git a/libstdc++-v3/libsupc++/guard.cc b/libstdc++-v3/libsupc++/guard.cc
index eb6421689b3..b714aec24eb 100644
--- a/libstdc++-v3/libsupc++/guard.cc
+++ b/libstdc++-v3/libsupc++/guard.cc
@@ -62,6 +62,28 @@ namespace
}
}
+namespace
+{
+ // A single conditional variable controlling all static initializations.
+ static __gnu_cxx::__cond* static_cond;
+
+ // using a fake type to avoid initializing a static class.
+ typedef char fake_cond_t[sizeof(__gnu_cxx::__cond)]
+ __attribute__ ((aligned(__alignof__(__gnu_cxx::__cond))));
+ fake_cond_t fake_cond;
+
+ static void init_static_cond()
+ { static_cond = new (&fake_cond) __gnu_cxx::__cond(); }
+
+ __gnu_cxx::__cond&
+ get_static_cond()
+ {
+ static __gthread_once_t once = __GTHREAD_ONCE_INIT;
+ __gthread_once(&once, init_static_cond);
+ return *static_cond;
+ }
+}
+
#ifndef _GLIBCXX_GUARD_TEST_AND_ACQUIRE
inline bool
__test_and_acquire (__cxxabiv1::__guard *g)
@@ -110,34 +132,87 @@ namespace __gnu_cxx
recursive_init_error::~recursive_init_error() throw() { }
}
+//
+// Here are C++ run-time routines for guarded initiailization of static
+// variables. There are 4 scenarios under which these routines are called:
+//
+// 1. Threads not supported (__GTHREADS not defined)
+// 2. Threads are supported but not enabled at run-time.
+// 3. Threads enabled at run-time but __gthreads_* are not fully POSIX.
+// 4. Threads enabled at run-time and __gthreads_* support all POSIX threads
+// primitives we need here.
+//
+// The old code supported scenarios 1-3 but was broken since it used a global
+// mutex for all threads and had the mutex locked during the whole duration of
+// initlization of a guarded static variable. The following created a dead-lock
+// with the old code.
+//
+// Thread 1 acquires the global mutex.
+// Thread 1 starts initializing static variable.
+// Thread 1 creates thread 2 during initialization.
+// Thread 2 attempts to acuqire mutex to initialize another variable.
+// Thread 2 blocks since thread 1 is locking the mutex.
+// Thread 1 waits for result from thread 2 and also blocks. A deadlock.
+//
+// The new code here can handle this situation and thus is more robust. Howere,
+// we need to use the POSIX thread conditional variable, which is not supported
+// in all platforms, notably older versions of Microsoft Windows. The gthr*.h
+// headers define a symbol __GTHREAD_HAS_COND for platforms that support POSIX
+// like conditional variables. For platforms that do not support conditional
+// variables, we need to fall back to the old code.
namespace __cxxabiv1
{
static inline int
- recursion_push (__guard* g)
- { return ((char *)g)[1]++; }
+ init_in_progress_flag(__guard* g)
+ { return ((char *)g)[1]; }
static inline void
- recursion_pop (__guard* g)
- { --((char *)g)[1]; }
+ set_init_in_progress_flag(__guard* g, int v)
+ { ((char *)g)[1] = v; }
- static int
- acquire (__guard *g)
+ static inline void
+ throw_recursive_init_exception()
{
- if (_GLIBCXX_GUARD_TEST (g))
- return 0;
-
- if (recursion_push (g))
- {
#ifdef __EXCEPTIONS
throw __gnu_cxx::recursive_init_error();
#else
// Use __builtin_trap so we don't require abort().
- __builtin_trap ();
+ __builtin_trap();
#endif
- }
+ }
+
+ // acuire() is a helper function used to acquire guard if thread support is
+ // not compiled in or is compiled in but not enabled at run-time.
+ static int
+ acquire(__guard *g)
+ {
+ // Quit if the object is already initialized.
+ if (_GLIBCXX_GUARD_TEST(g))
+ return 0;
+
+ if (init_in_progress_flag(g))
+ throw_recursive_init_exception();
+
+ set_init_in_progress_flag(g, 1);
return 1;
}
+ // Simple wrapper for exception safety.
+ struct mutex_wrapper
+ {
+#ifdef __GTHREADS
+ bool unlock;
+ mutex_wrapper() : unlock(true)
+ { get_static_mutex().lock(); }
+
+ ~mutex_wrapper()
+ {
+ if (unlock)
+ static_mutex->unlock();
+ }
+#endif
+ };
+
extern "C"
int __cxa_guard_acquire (__guard *g)
{
@@ -150,28 +225,39 @@ namespace __cxxabiv1
if (__gthread_active_p ())
{
- // Simple wrapper for exception safety.
- struct mutex_wrapper
- {
- bool unlock;
- mutex_wrapper() : unlock(true)
- { get_static_mutex().lock(); }
-
- ~mutex_wrapper()
- {
- if (unlock)
- static_mutex->unlock();
- }
- };
-
mutex_wrapper mw;
- if (acquire (g))
+
+ while (1) // When this loop is executing, mutex is locked.
{
- mw.unlock = false;
- return 1;
- }
+#ifdef __GTHREAD_HAS_COND
+ // The static is allready initialized.
+ if (_GLIBCXX_GUARD_TEST(g))
+ return 0; // The mutex will be unlocked via wrapper
- return 0;
+ if (init_in_progress_flag(g))
+ {
+ // The guarded static is currently being initialized by
+ // another thread, so we release mutex and wait for the
+ // conditional variable. We will lock the mutex again after
+ // this.
+ get_static_cond().wait_recursive(&get_static_mutex());
+ }
+ else
+ {
+ set_init_in_progress_flag(g, 1);
+ return 1; // The mutex will be unlocked via wrapper.
+ }
+#else
+ // This provides compatibility with older systems not supporting
+ // POSIX like conditional variables.
+ if (acquire(g))
+ {
+ mw.unlock = false;
+ return 1; // The mutex still locked.
+ }
+ return 0; // The mutex will be unlocked via wrapper.
+#endif
+ }
}
#endif
@@ -181,8 +267,24 @@ namespace __cxxabiv1
extern "C"
void __cxa_guard_abort (__guard *g)
{
- recursion_pop (g);
-#ifdef __GTHREADS
+#ifdef __GTHREAD_HAS_COND
+ if (__gthread_active_p())
+ {
+ mutex_wrapper mw;
+
+ set_init_in_progress_flag(g, 0);
+
+ // If we abort, we still need to wake up all other threads waiting for
+ // the conditional variable.
+ get_static_cond().broadcast();
+ return;
+ }
+#endif
+
+ set_init_in_progress_flag(g, 0);
+#if defined(__GTHREADS) && !defined(__GTHREAD_HAS_COND)
+ // This provides compatibility with older systems not supporting POSIX like
+ // conditional variables.
if (__gthread_active_p ())
static_mutex->unlock();
#endif
@@ -191,10 +293,26 @@ namespace __cxxabiv1
extern "C"
void __cxa_guard_release (__guard *g)
{
- recursion_pop (g);
+#ifdef __GTHREAD_HAS_COND
+ if (__gthread_active_p())
+ {
+ mutex_wrapper mw;
+
+ set_init_in_progress_flag(g, 0);
+ _GLIBCXX_GUARD_SET_AND_RELEASE(g);
+
+ get_static_cond().broadcast();
+ return;
+ }
+#endif
+
+ set_init_in_progress_flag(g, 0);
_GLIBCXX_GUARD_SET_AND_RELEASE (g);
-#ifdef __GTHREADS
- if (__gthread_active_p ())
+
+#if defined(__GTHREADS) && !defined(__GTHREAD_HAS_COND)
+ // This provides compatibility with older systems not supporting POSIX like
+ // conditional variables.
+ if (__gthread_active_p())
static_mutex->unlock();
#endif
}
diff --git a/libstdc++-v3/libsupc++/typeinfo b/libstdc++-v3/libsupc++/typeinfo
index cfcbbcc0896..773d2f5ca4a 100644
--- a/libstdc++-v3/libsupc++/typeinfo
+++ b/libstdc++-v3/libsupc++/typeinfo
@@ -127,7 +127,13 @@ namespace std
#endif
bool operator!=(const type_info& __arg) const
{ return !operator==(__arg); }
-
+
+ // Return true if this is a pointer type of some kind
+ virtual bool __is_pointer_p() const;
+
+ // Return true if this is a function type
+ virtual bool __is_function_p() const;
+
// Try and catch a thrown type. Store an adjusted pointer to the
// caught type in THR_OBJ. If THR_TYPE is not a pointer type, then
// THR_OBJ points to the thrown object. If THR_TYPE is a pointer
@@ -141,12 +147,6 @@ namespace std
virtual bool __do_upcast(const __cxxabiv1::__class_type_info *__target,
void **__obj_ptr) const;
- // Return true if this is a pointer type of some kind
- virtual bool __is_pointer_p() const;
-
- // Return true if this is a function type
- virtual bool __is_function_p() const;
-
protected:
const char *__name;
diff --git a/libstdc++-v3/testsuite/20_util/pair/moveable.cc b/libstdc++-v3/testsuite/20_util/pair/moveable.cc
new file mode 100644
index 00000000000..e84321040ea
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/pair/moveable.cc
@@ -0,0 +1,72 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on pair, and also vector. If the implementation
+// changes this test may begin to fail.
+
+#include <vector>
+#include <utility>
+#include <testsuite_hooks.h>
+
+bool test __attribute__((unused)) = true;
+
+void
+test1()
+{
+ std::pair<int,int> a(1,1),b(2,2);
+ a=std::move(b);
+ VERIFY(a.first == 2 && a.second == 2 && b.first == 2 && b.second == 2);
+ std::pair<int,int> c(std::move(a));
+ VERIFY(c.first == 2 && c.second == 2 && a.first == 2 && a.second == 2);
+}
+
+void
+test2()
+{
+ std::vector<int> v,w;
+ v.push_back(1);
+ w.push_back(2);
+ w.push_back(2);
+ std::pair<int, std::vector<int> > p = make_pair(1,v);
+ std::pair<int, std::vector<int> > q = make_pair(2,w);
+ p = std::move(q);
+ VERIFY(p.first == 2 && q.first == 2 &&
+ p.second.size() == 2 && q.second.size() == 1);
+ std::pair<int, std::vector<int> > r(std::move(p));
+ VERIFY(r.first == 2 && p.first == 2 &&
+ r.second.size() == 2 && p.second.size() == 0);
+}
+
+int
+main()
+{
+ test1();
+ test2();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/deque/capacity/moveable.cc b/libstdc++-v3/testsuite/23_containers/deque/capacity/moveable.cc
new file mode 100644
index 00000000000..109ab99eb9f
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/capacity/moveable.cc
@@ -0,0 +1,82 @@
+// { dg-require-rvalref "" }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <deque>
+#include <testsuite_hooks.h>
+#include <testsuite_rvalref.h>
+
+using namespace __gnu_test;
+
+// According to n1771, there should be two resizes, with and without
+// parameter. We only have one at present, whose second parameter defaults
+// to a default-constructed object.
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::deque<copycounter> a;
+ copycounter::copycount = 0;
+ a.resize(10);
+ a.resize(98);
+ a.resize(99);
+ a.resize(100);
+#ifndef _GLIBCXX_DEBUG
+ VERIFY( copycounter::copycount == 100 );
+#else
+ VERIFY( copycounter::copycount == 100 + 4 );
+#endif
+ a.resize(99);
+ a.resize(0);
+#ifndef _GLIBCXX_DEBUG
+ VERIFY( copycounter::copycount == 100 );
+#else
+ VERIFY( copycounter::copycount == 100 + 6 );
+#endif
+ a.resize(100);
+#ifndef _GLIBCXX_DEBUG
+ VERIFY( copycounter::copycount == 200 );
+#else
+ VERIFY( copycounter::copycount == 200 + 7 );
+#endif
+ a.clear();
+#ifndef _GLIBCXX_DEBUG
+ VERIFY( copycounter::copycount == 200 );
+#else
+ VERIFY( copycounter::copycount == 200 + 7 );
+#endif
+}
+
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/deque/cons/moveable.cc b/libstdc++-v3/testsuite/23_containers/deque/cons/moveable.cc
new file mode 100644
index 00000000000..1d93aeb6f79
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/cons/moveable.cc
@@ -0,0 +1,65 @@
+// { dg-do compile }
+// { dg-require-rvalref "" }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <deque>
+#include <iterator>
+#include <testsuite_iterators.h>
+#include <testsuite_rvalref.h>
+
+using namespace __gnu_test;
+typedef std::deque<rvalstruct> test_type;
+
+// Empty constructor doesn't require a copy constructor
+void
+test01()
+{ test_type d; }
+
+// Constructing from a range that returns rvalue references doesn't
+// require a copy constructor.
+void
+test02(rvalstruct* begin, rvalstruct* end)
+{
+ test_type d(std::make_move_iterator(begin), std::make_move_iterator(end));
+}
+
+// Constructing from a input iterator range that returns rvalue
+// references doesn't require a copy constructor either.
+void
+test03(input_iterator_wrapper<rvalstruct> begin,
+ input_iterator_wrapper<rvalstruct> end)
+{
+ test_type d(std::make_move_iterator(begin), std::make_move_iterator(end));
+}
+
+// Neither does destroying one.
+void
+test04(test_type* d)
+{ delete d; }
diff --git a/libstdc++-v3/testsuite/23_containers/deque/modifiers/moveable.cc b/libstdc++-v3/testsuite/23_containers/deque/modifiers/moveable.cc
new file mode 100644
index 00000000000..605067611d7
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/modifiers/moveable.cc
@@ -0,0 +1,144 @@
+// { dg-require-rvalref "" }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <deque>
+#include <testsuite_hooks.h>
+#include <testsuite_rvalref.h>
+
+using namespace __gnu_test;
+
+// Test deque::push_back makes no unneeded copies.
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::deque<copycounter> a;
+ copycounter c(1);
+ copycounter::copycount = 0;
+ for(int i = 0; i < 1000; ++i)
+ a.push_back(c);
+ VERIFY(copycounter::copycount == 1000);
+}
+
+// Test deque::push_front makes no unneeded copies.
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::deque<copycounter> a;
+ copycounter c(1);
+ copycounter::copycount = 0;
+ for(int i = 0; i < 1000; ++i)
+ a.push_front(c);
+ VERIFY(copycounter::copycount == 1000);
+}
+
+// Test deque::insert makes no unneeded copies.
+void
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::deque<copycounter> a(1000);
+ copycounter c(1);
+ copycounter::copycount = 0;
+ a.insert(a.begin(),c);
+ a.insert(a.end(),c);
+ for(int i = 0; i < 500; ++i)
+ a.insert(a.begin() + i, c);
+ VERIFY(copycounter::copycount == 502);
+}
+
+// Test deque::insert(iterator, count, value) makes no unneeded copies
+// when it has to also reallocate the deque's internal buffer.
+void
+test04()
+{
+ bool test __attribute__((unused)) = true;
+
+ copycounter c(1);
+ std::deque<copycounter> a(10, c);
+ copycounter::copycount = 0;
+ a.insert(a.begin(), 20, c);
+ VERIFY(copycounter::copycount == 20);
+ a.insert(a.end(), 50, c);
+ VERIFY(copycounter::copycount == 70);
+ // NOTE : These values are each one higher than might be expected, as
+ // deque::insert(iterator, count, value) copies the value it is given
+ // when it has to move elements in the deque in case that value is
+ // in the deque.
+
+ // Near the start
+ a.insert(a.begin() + 10, 100, c);
+ VERIFY(copycounter::copycount == 170 + 1);
+ // Near the end
+ a.insert(a.end() - 10, 1000, c);
+ VERIFY(copycounter::copycount == 1170 + 2);
+}
+
+// Test deque::insert(iterator, count, value) makes no unneeded copies
+// when it doesn't have to reallocate the deque's internal buffer.
+void
+test05()
+{
+ bool test __attribute__((unused)) = true;
+
+ copycounter c(1);
+ std::deque<copycounter> a(10, c);
+ copycounter::copycount = 0;
+ //a.reserve(1000);
+ a.insert(a.begin(), 20, c);
+ VERIFY(copycounter::copycount == 20 );
+ a.insert(a.end(), 50, c);
+ VERIFY(copycounter::copycount == 70 );
+
+ // NOTE : These values are each one higher than might be expected, as
+ // deque::insert(iterator, count, value) copies the value it is given
+ // when it has to move elements in the deque in case that value is
+ // in the deque.
+ // Near the start
+ a.insert(a.begin() + 10, 100, c);
+ VERIFY(copycounter::copycount == 170 + 1);
+ // Near the end
+ a.insert(a.end() - 10, 200, c);
+ VERIFY(copycounter::copycount == 370 + 2);
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+ test05();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/deque/moveable.cc b/libstdc++-v3/testsuite/23_containers/deque/moveable.cc
new file mode 100644
index 00000000000..ae532de9780
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/moveable.cc
@@ -0,0 +1,51 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on deque (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <deque>
+#include <utility>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::deque<int> a,b;
+ a.push_back(1);
+ b = std::move(a);
+ VERIFY( b.size() == 1 && b[0] == 1 && a.size() == 0 );
+
+ std::deque<int> c(std::move(b));
+ VERIFY( c.size() == 1 && c[0] == 1 );
+ VERIFY( b.size() == 0 );
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
index 0c47da04033..8fde473dc7a 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1297 }
+// { dg-error "no matching" "" { target *-*-* } 1349 }
// { dg-excess-errors "" }
#include <deque>
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
index fc0beffae3e..3124e19af27 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1232 }
+// { dg-error "no matching" "" { target *-*-* } 1284 }
// { dg-excess-errors "" }
#include <deque>
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
index 403f6473f6b..1f6115c5d3c 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1232 }
+// { dg-error "no matching" "" { target *-*-* } 1284 }
// { dg-excess-errors "" }
#include <deque>
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
index 2e2abc56c4b..9d6365932dd 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1377 }
+// { dg-error "no matching" "" { target *-*-* } 1429 }
// { dg-excess-errors "" }
#include <deque>
diff --git a/libstdc++-v3/testsuite/23_containers/list/moveable.cc b/libstdc++-v3/testsuite/23_containers/list/moveable.cc
new file mode 100644
index 00000000000..d3f1031f91f
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/list/moveable.cc
@@ -0,0 +1,51 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on list (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <list>
+#include <utility>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::list<int> a,b;
+ a.push_back(1);
+ b = std::move(a);
+ VERIFY( b.size() == 1 && *b.begin() == 1 && a.size() == 0 );
+
+ std::list<int> c(std::move(b));
+ VERIFY( c.size() == 1 && *c.begin() == 1 );
+ VERIFY( b.size() == 0 );
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
index 4ad1127b9e5..ccabf384ead 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1138 }
+// { dg-error "no matching" "" { target *-*-* } 1188 }
// { dg-excess-errors "" }
#include <list>
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
index 5df6fc8532c..0711505092f 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1107 }
+// { dg-error "no matching" "" { target *-*-* } 1157 }
// { dg-excess-errors "" }
#include <list>
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
index 6783727be7a..1e02ca8913e 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1107 }
+// { dg-error "no matching" "" { target *-*-* } 1157 }
// { dg-excess-errors "" }
#include <list>
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc
index c8f2026052e..04b3c2b95c2 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1107 }
+// { dg-error "no matching" "" { target *-*-* } 1157 }
// { dg-excess-errors "" }
#include <list>
diff --git a/libstdc++-v3/testsuite/23_containers/map/moveable.cc b/libstdc++-v3/testsuite/23_containers/map/moveable.cc
new file mode 100644
index 00000000000..52447083b2e
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/moveable.cc
@@ -0,0 +1,52 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on map (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <map>
+#include <utility>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::map<int, int> a,b;
+ a[2]=0;
+ b[1]=0;
+ b = std::move(a);
+ VERIFY(b.find(2) != b.end() && a.find(1) != a.end());
+
+ std::map<int, int> c(std::move(b));
+ VERIFY( c.find(2) != c.end());
+ VERIFY( b.find(2) == b.end());
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/moveable.cc b/libstdc++-v3/testsuite/23_containers/multimap/moveable.cc
new file mode 100644
index 00000000000..87796f496f3
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/moveable.cc
@@ -0,0 +1,52 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on multimap (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <map>
+#include <utility>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::multimap<int, int> a,b;
+ a.insert(std::make_pair(2,0));
+ b.insert(std::make_pair(1,0));
+ b = std::move(a);
+ VERIFY(b.find(2) != b.end() && a.find(1) != a.end());
+
+ std::multimap<int, int> c(std::move(b));
+ VERIFY( c.find(2) != c.end());
+ VERIFY( b.find(2) == b.end());
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/moveable.cc b/libstdc++-v3/testsuite/23_containers/multiset/moveable.cc
new file mode 100644
index 00000000000..c3ca111804d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/moveable.cc
@@ -0,0 +1,52 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on multiset (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <set>
+#include <utility>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::multiset<int> a,b;
+ a.insert(2);
+ b.insert(1);
+ b = std::move(a);
+ VERIFY(b.find(2) != b.end() && a.find(1) != a.end());
+
+ std::multiset<int> c(std::move(b));
+ VERIFY( c.find(2) != c.end());
+ VERIFY( b.find(2) == b.end());
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/moveable.cc b/libstdc++-v3/testsuite/23_containers/set/moveable.cc
new file mode 100644
index 00000000000..b85ae58ba06
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/moveable.cc
@@ -0,0 +1,52 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on set (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <set>
+#include <utility>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::set<int> a,b;
+ a.insert(2);
+ b.insert(1);
+ b = std::move(a);
+ VERIFY(b.find(2) != b.end() && a.find(1) != a.end());
+
+ std::set<int> c(std::move(b));
+ VERIFY( c.find(2) != c.end());
+ VERIFY( b.find(2) == b.end());
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/moveable.cc b/libstdc++-v3/testsuite/23_containers/vector/cons/moveable.cc
new file mode 100644
index 00000000000..7184a256f94
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/cons/moveable.cc
@@ -0,0 +1,65 @@
+// { dg-do compile }
+// { dg-require-rvalref "" }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <vector>
+#include <iterator>
+#include <testsuite_iterators.h>
+#include <testsuite_rvalref.h>
+
+using namespace __gnu_test;
+typedef std::vector<rvalstruct> test_type;
+
+// Empty constructor doesn't require a copy constructor
+void
+test01()
+{ test_type d; }
+
+// Constructing from a range that returns rvalue references doesn't
+// require a copy constructor.
+void
+test02(rvalstruct* begin, rvalstruct* end)
+{
+ test_type d(std::make_move_iterator(begin), std::make_move_iterator(end));
+}
+
+// Constructing from a input iterator range that returns rvalue
+// references doesn't require a copy constructor either.
+void
+test03(input_iterator_wrapper<rvalstruct> begin,
+ input_iterator_wrapper<rvalstruct> end)
+{
+ test_type d(std::make_move_iterator(begin), std::make_move_iterator(end));
+}
+
+// Neither does destroying one.
+void
+test04(test_type* d)
+{ delete d; }
diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable.cc
new file mode 100644
index 00000000000..ef4410a92b2
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/moveable.cc
@@ -0,0 +1,147 @@
+// { dg-require-rvalref "" }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <vector>
+#include <testsuite_hooks.h>
+#include <testsuite_rvalref.h>
+
+using namespace __gnu_test;
+
+// Test vector::push_back makes no unneeded copies.
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::vector<copycounter> a;
+ copycounter c(1);
+ copycounter::copycount = 0;
+ for(int i = 0; i < 10; ++i)
+ a.push_back(c);
+ VERIFY(copycounter::copycount == 10);
+
+ for(int i = 0; i < 100; ++i)
+ a.insert(a.begin() + i, c);
+ VERIFY(copycounter::copycount == 110);
+
+ for(int i = 0; i < 1000; ++i)
+ a.insert(a.end(), c);
+ VERIFY(copycounter::copycount == 1110);
+}
+
+// Test vector::insert(iterator, iterator, iterator) makes no unneeded copies
+// when it has to also reallocate the vector's internal buffer.
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ copycounter c(1);
+ std::vector<copycounter> a(10, c), b(100, c);
+ copycounter::copycount = 0;
+ a.insert(a.begin(), b.begin(), b.begin() + 20);
+ VERIFY(copycounter::copycount == 20);
+ a.insert(a.end(), b.begin(), b.begin() + 50);
+ VERIFY(copycounter::copycount == 70);
+ a.insert(a.begin() + 50, b.begin(), b.end());
+ VERIFY(copycounter::copycount == 170);
+}
+
+// Test vector::insert(iterator, iterator, iterator) makes no unneeded copies
+// when it doesn't have to reallocate the vector's internal buffer.
+void
+test03()
+{
+ bool test __attribute__((unused)) = true;
+
+ copycounter c(1);
+ std::vector<copycounter> a(10, c), b(100, c);
+ copycounter::copycount = 0;
+ a.reserve(1000);
+ VERIFY(copycounter::copycount == 0);
+ a.insert(a.begin(), b.begin(), b.begin() + 20);
+ VERIFY(copycounter::copycount == 20);
+ a.insert(a.end(), b.begin(), b.begin() + 50);
+ VERIFY(copycounter::copycount == 70);
+ a.insert(a.begin() + 50, b.begin(), b.end());
+ VERIFY(copycounter::copycount == 170);
+}
+
+// Test vector::insert(iterator, count, value) makes no unneeded copies
+// when it has to also reallocate the vector's internal buffer.
+void
+test04()
+{
+ bool test __attribute__((unused)) = true;
+
+ copycounter c(1);
+ std::vector<copycounter> a(10, c);
+ copycounter::copycount = 0;
+ a.insert(a.begin(), 20, c);
+ VERIFY(copycounter::copycount == 20 + 1);
+ a.insert(a.end(), 50, c);
+ VERIFY(copycounter::copycount == 70 + 2);
+ a.insert(a.begin() + 50, 100, c);
+ VERIFY(copycounter::copycount == 170 + 3);
+}
+
+// Test vector::insert(iterator, count, value) makes no unneeded copies
+// when it doesn't have to reallocate the vector's internal buffer.
+void
+test05()
+{
+ bool test __attribute__((unused)) = true;
+
+ copycounter c(1);
+ std::vector<copycounter> a(10, c);
+ copycounter::copycount = 0;
+ a.reserve(1000);
+ a.insert(a.begin(), 20, c);
+ // NOTE : These values are each one higher than might be expected, as
+ // vector::insert(iterator, count, value) copies the value it is given
+ // when it doesn't reallocate the buffer.
+ VERIFY(copycounter::copycount == 20 + 1);
+ a.insert(a.end(), 50, c);
+ VERIFY(copycounter::copycount == 70 + 2);
+ a.insert(a.begin() + 50, 100, c);
+ VERIFY(copycounter::copycount == 170 + 3);
+}
+
+
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+ test05();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/moveable.cc b/libstdc++-v3/testsuite/23_containers/vector/moveable.cc
new file mode 100644
index 00000000000..df825f3d007
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/moveable.cc
@@ -0,0 +1,71 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on vector (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <vector>
+#include <utility>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::vector<int> a,b;
+ a.push_back(1);
+ b = std::move(a);
+ VERIFY( b.size() == 1 && b[0] == 1 && a.size() == 0 );
+
+ std::vector<int> c(std::move(b));
+ VERIFY( c.size() == 1 && c[0] == 1 );
+ VERIFY( b.size() == 0 );
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::vector<bool> a,b;
+ a.push_back(1);
+ b = std::move(a);
+ VERIFY( b.size() == 1 && b[0] == 1 && a.size() == 0 );
+
+ std::vector<bool> c(std::move(b));
+ VERIFY( c.size() == 1 && c[0] == 1 );
+ VERIFY( b.size() == 0 );
+}
+
+int main(void)
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
index 609511f07ce..4239d4df3c5 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 847 }
+// { dg-error "no matching" "" { target *-*-* } 895 }
// { dg-excess-errors "" }
#include <vector>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
index 12aa0aea695..7faf1e2feb6 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 787 }
+// { dg-error "no matching" "" { target *-*-* } 835 }
// { dg-excess-errors "" }
#include <vector>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
index 1dd8d305e2e..66c0206044e 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 787 }
+// { dg-error "no matching" "" { target *-*-* } 835 }
// { dg-excess-errors "" }
#include <vector>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
index 707776debc9..6aae607479f 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 888 }
+// { dg-error "no matching" "" { target *-*-* } 936 }
// { dg-excess-errors "" }
#include <vector>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/resize/moveable.cc b/libstdc++-v3/testsuite/23_containers/vector/resize/moveable.cc
new file mode 100644
index 00000000000..84136f4e04d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/resize/moveable.cc
@@ -0,0 +1,85 @@
+// { dg-require-rvalref "" }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <vector>
+#include <testsuite_hooks.h>
+#include <testsuite_rvalref.h>
+
+using namespace __gnu_test;
+
+// According to n1771, there should be two resizes, with and without
+// parameter. We only have one at present, whose second parameter defaults
+// to a default-constructed object.
+// Also, the values are one higher than might be expected because internally
+// resize calls fill, which copies its input value in case it is already in
+// the vector when the vector isn't moved.
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::vector<copycounter> a;
+ copycounter::copycount = 0;
+ a.resize(10);
+ a.resize(98);
+ a.resize(99);
+ a.resize(100);
+#ifndef _GLIBCXX_DEBUG
+ VERIFY( copycounter::copycount == 100 + 4 );
+#else
+ VERIFY( copycounter::copycount == 100 + 4 + 4 );
+#endif
+ a.resize(99);
+ a.resize(0);
+#ifndef _GLIBCXX_DEBUG
+ VERIFY( copycounter::copycount == 100 + 4 );
+#else
+ VERIFY( copycounter::copycount == 100 + 4 + 6 );
+#endif
+ a.resize(100);
+#ifndef _GLIBCXX_DEBUG
+ VERIFY( copycounter::copycount == 200 + 5 );
+#else
+ VERIFY( copycounter::copycount == 200 + 5 + 7 );
+#endif
+ a.clear();
+#ifndef _GLIBCXX_DEBUG
+ VERIFY( copycounter::copycount == 200 + 5 );
+#else
+ VERIFY( copycounter::copycount == 200 + 5 + 7 );
+#endif
+}
+
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/binary_search/2.cc b/libstdc++-v3/testsuite/25_algorithms/binary_search/2.cc
index 66567f23afd..24c1d876245 100644
--- a/libstdc++-v3/testsuite/25_algorithms/binary_search/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/binary_search/2.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2007 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
@@ -36,120 +36,6 @@ struct gt
{ return x > y; }
};
-// Each test performs general-case, bookend, not-found condition,
-// and predicate functional checks.
-
-// 25.3.3.1 lower_bound, with and without comparison predicate
-void
-test01()
-{
- using std::lower_bound;
-
- const int first = A[0];
- const int last = A[N - 1];
-
- const int* p = lower_bound(A, A + N, 3);
- VERIFY(p == A + 2);
-
- const int* q = lower_bound(A, A + N, first);
- VERIFY(q == A + 0);
-
- const int* r = lower_bound(A, A + N, last);
- VERIFY(r == A + N - 1);
-
- const int* s = lower_bound(A, A + N, 4);
- VERIFY(s == A + 5);
-
- const int* t = lower_bound(C, C + N, 3, gt());
- VERIFY(t == C + 2);
-
- const int* u = lower_bound(C, C + N, first, gt());
- VERIFY(u == C + N - 1);
-
- const int* v = lower_bound(C, C + N, last, gt());
- VERIFY(v == C + 0);
-
- const int* w = lower_bound(C, C + N, 4, gt());
- VERIFY(w == C + 2);
-}
-
-// 25.3.3.2 upper_bound, with and without comparison predicate
-void
-test02()
-{
- using std::upper_bound;
-
- const int first = A[0];
- const int last = A[N - 1];
-
- const int* p = upper_bound(A, A + N, 3);
- VERIFY(p == A + 5);
-
- const int* q = upper_bound(A, A + N, first);
- VERIFY(q == A + 1);
-
- const int* r = upper_bound(A, A + N, last);
- VERIFY(r == A + N);
-
- const int* s = upper_bound(A, A + N, 4);
- VERIFY(s == A + 5);
-
- const int* t = upper_bound(C, C + N, 3, gt());
- VERIFY(t == C + 5);
-
- const int* u = upper_bound(C, C + N, first, gt());
- VERIFY(u == C + N);
-
- const int* v = upper_bound(C, C + N, last, gt());
- VERIFY(v == C + 1);
-
- const int* w = upper_bound(C, C + N, 4, gt());
- VERIFY(w == C + 2);
-}
-
-// 25.3.3.3 equal_range, with and without comparison predicate
-void
-test03()
-{
- using std::equal_range;
- typedef std::pair<const int*, const int*> Ipair;
-
- const int first = A[0];
- const int last = A[N - 1];
-
- Ipair p = equal_range(A, A + N, 3);
- VERIFY(p.first == A + 2);
- VERIFY(p.second == A + 5);
-
- Ipair q = equal_range(A, A + N, first);
- VERIFY(q.first == A + 0);
- VERIFY(q.second == A + 1);
-
- Ipair r = equal_range(A, A + N, last);
- VERIFY(r.first == A + N - 1);
- VERIFY(r.second == A + N);
-
- Ipair s = equal_range(A, A + N, 4);
- VERIFY(s.first == A + 5);
- VERIFY(s.second == A + 5);
-
- Ipair t = equal_range(C, C + N, 3, gt());
- VERIFY(t.first == C + 2);
- VERIFY(t.second == C + 5);
-
- Ipair u = equal_range(C, C + N, first, gt());
- VERIFY(u.first == C + N - 1);
- VERIFY(u.second == C + N);
-
- Ipair v = equal_range(C, C + N, last, gt());
- VERIFY(v.first == C + 0);
- VERIFY(v.second == C + 1);
-
- Ipair w = equal_range(C, C + N, 4, gt());
- VERIFY(w.first == C + 2);
- VERIFY(w.second == C + 2);
-}
-
// 25.3.3.4 binary_search, with and without comparison predicate
void
test04()
@@ -173,10 +59,6 @@ test04()
int
main()
{
- test01();
- test02();
- test03();
- test04();
-
+ test04();
return 0;
}
diff --git a/libstdc++-v3/testsuite/25_algorithms/binary_search/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/binary_search/requirements/explicit_instantiation/2.cc
index 3b770a7d9aa..0c9b5db1987 100644
--- a/libstdc++-v3/testsuite/25_algorithms/binary_search/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/binary_search/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/count_if/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/count_if/requirements/explicit_instantiation/2.cc
index f2fbe280f4d..434a3e822f6 100644
--- a/libstdc++-v3/testsuite/25_algorithms/count_if/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/count_if/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/equal/equal.cc b/libstdc++-v3/testsuite/25_algorithms/equal/no_operator_ne.cc
index 285baa6e211..285baa6e211 100644
--- a/libstdc++-v3/testsuite/25_algorithms/equal/equal.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/equal/no_operator_ne.cc
diff --git a/libstdc++-v3/testsuite/25_algorithms/equal_range/2.cc b/libstdc++-v3/testsuite/25_algorithms/equal_range/2.cc
new file mode 100644
index 00000000000..12f2b4e499b
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/equal_range/2.cc
@@ -0,0 +1,90 @@
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 25.3.3 [lib.alg.binary.search] Binary search algorithms.
+
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+bool test __attribute__((unused)) = true;
+
+const int A[] = {1, 2, 3, 3, 3, 5, 8};
+const int C[] = {8, 5, 3, 3, 3, 2, 1};
+const int N = sizeof(A) / sizeof(int);
+
+// A comparison, equalivalent to std::greater<int> without the
+// dependency on <functional>.
+struct gt
+{
+ bool
+ operator()(const int& x, const int& y) const
+ { return x > y; }
+};
+
+// Each test performs general-case, bookend, not-found condition,
+// and predicate functional checks.
+
+// 25.3.3.3 equal_range, with and without comparison predicate
+void
+test03()
+{
+ using std::equal_range;
+ typedef std::pair<const int*, const int*> Ipair;
+
+ const int first = A[0];
+ const int last = A[N - 1];
+
+ Ipair p = equal_range(A, A + N, 3);
+ VERIFY(p.first == A + 2);
+ VERIFY(p.second == A + 5);
+
+ Ipair q = equal_range(A, A + N, first);
+ VERIFY(q.first == A + 0);
+ VERIFY(q.second == A + 1);
+
+ Ipair r = equal_range(A, A + N, last);
+ VERIFY(r.first == A + N - 1);
+ VERIFY(r.second == A + N);
+
+ Ipair s = equal_range(A, A + N, 4);
+ VERIFY(s.first == A + 5);
+ VERIFY(s.second == A + 5);
+
+ Ipair t = equal_range(C, C + N, 3, gt());
+ VERIFY(t.first == C + 2);
+ VERIFY(t.second == C + 5);
+
+ Ipair u = equal_range(C, C + N, first, gt());
+ VERIFY(u.first == C + N - 1);
+ VERIFY(u.second == C + N);
+
+ Ipair v = equal_range(C, C + N, last, gt());
+ VERIFY(v.first == C + 0);
+ VERIFY(v.second == C + 1);
+
+ Ipair w = equal_range(C, C + N, 4, gt());
+ VERIFY(w.first == C + 2);
+ VERIFY(w.second == C + 2);
+}
+
+int
+main()
+{
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/equal_range/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/equal_range/requirements/explicit_instantiation/2.cc
index 756891bc947..88cd1811a56 100644
--- a/libstdc++-v3/testsuite/25_algorithms/equal_range/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/equal_range/requirements/explicit_instantiation/2.cc
@@ -31,6 +31,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/find_end/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/find_end/requirements/explicit_instantiation/2.cc
index d0b481894c7..8e4c3e6dc70 100644
--- a/libstdc++-v3/testsuite/25_algorithms/find_end/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/find_end/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/find_first_of/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/find_first_of/requirements/explicit_instantiation/2.cc
index 8fb55e7d793..c675764085e 100644
--- a/libstdc++-v3/testsuite/25_algorithms/find_first_of/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/find_first_of/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/find_if/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/find_if/requirements/explicit_instantiation/2.cc
index f2cf218f6c6..5ad6189c573 100644
--- a/libstdc++-v3/testsuite/25_algorithms/find_if/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/find_if/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/for_each/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/for_each/requirements/explicit_instantiation/2.cc
index 456b2b4e060..803074ceda0 100644
--- a/libstdc++-v3/testsuite/25_algorithms/for_each/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/for_each/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/heap/heap.cc b/libstdc++-v3/testsuite/25_algorithms/heap/1.cc
index 571a2936ed2..571a2936ed2 100644
--- a/libstdc++-v3/testsuite/25_algorithms/heap/heap.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/heap/1.cc
diff --git a/libstdc++-v3/testsuite/25_algorithms/heap/moveable.cc b/libstdc++-v3/testsuite/25_algorithms/heap/moveable.cc
new file mode 100644
index 00000000000..2477902b55b
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/heap/moveable.cc
@@ -0,0 +1,120 @@
+// { dg-require-rvalref "" }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without Pred the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.3.6 Heap operations [lib.alg.heap.operations]
+
+#undef _GLIBCXX_CONCEPT_CHECKS
+#define _GLIBCXX_TESTSUITE_ALLOW_RVALREF_ALIASING
+
+#include <algorithm>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+#include <testsuite_rvalref.h>
+
+using __gnu_test::test_container;
+using __gnu_test::random_access_iterator_wrapper;
+using __gnu_test::rvalstruct;
+
+typedef test_container<rvalstruct, random_access_iterator_wrapper> container;
+
+bool test __attribute__((unused)) = true;
+
+
+void
+check_make(int* array, int length)
+{
+ rvalstruct makeheap[9];
+ std::copy(array, array + length, makeheap);
+ container makecon(makeheap, makeheap + length);
+ std::make_heap(makecon.begin(), makecon.end());
+ VERIFY(std::__is_heap(makecon.begin(), makecon.end()));
+ for(int z = 0; z < length; ++z)
+ VERIFY(makeheap[z].valid);
+}
+
+void
+check_pop(int* array, int length)
+{
+ rvalstruct popheap[9];
+ std::copy(array, array + length, popheap);
+ container popcon(popheap, popheap + length);
+ std::pop_heap(popcon.begin(), popcon.end());
+ VERIFY(std::__is_heap(popheap, popheap + length - 1));
+ for(int z = 0; z < length; ++z)
+ VERIFY(popheap[z].val <= popheap[length-1].val && popheap[z].valid);
+}
+
+void
+check_sort(int* array, int length)
+{
+ rvalstruct sortheap[9];
+ std::copy(array, array + length, sortheap);
+ container sortcon(sortheap, sortheap + length);
+ std::sort_heap(sortcon.begin(), sortcon.end());
+ for(int z = 0; z < length - 1; ++z)
+ VERIFY(sortheap[z].val <= sortheap[z + 1].val && sortheap[z].valid);
+ VERIFY(sortheap[length - 1].valid);
+}
+
+void
+check_push(int* array, int pushval, int length)
+{
+ rvalstruct pushheap[10];
+ std::copy(array, array + length, pushheap);
+ pushheap[length] = pushval;
+ container pushcon(pushheap, pushheap + length);
+ std::push_heap(pushcon.begin(), pushcon.end());
+ VERIFY(std::__is_heap(pushheap, pushheap + length));
+ for(int z = 0; z < length ; ++z)
+ VERIFY(pushheap[z].valid);
+}
+
+
+void
+test01()
+{
+ int array[9];
+ for(int i = 1; i < 9; ++i)
+ {
+ for(int z = 0; z < i; ++z)
+ array[i] = i;
+ while(std::next_permutation(array, array + i))
+ {
+ check_make(array, i);
+ if(std::__is_heap(array, array + i))
+ {
+ check_pop(array, i);
+ check_sort(array, i);
+ for(int pushval = -1; pushval <= i; ++pushval)
+ {
+ check_push(array, pushval, i);
+ }
+ }
+ }
+ }
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/includes/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/includes/requirements/explicit_instantiation/2.cc
index 63f6d95d23a..e4dbe43aa8c 100644
--- a/libstdc++-v3/testsuite/25_algorithms/includes/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/includes/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/inplace_merge/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/inplace_merge/requirements/explicit_instantiation/2.cc
index 10656a9c029..c71c3e221b5 100644
--- a/libstdc++-v3/testsuite/25_algorithms/inplace_merge/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/inplace_merge/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/lexicographical_compare/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/lexicographical_compare/requirements/explicit_instantiation/2.cc
index 8a868ecb08b..c2c4deed40d 100644
--- a/libstdc++-v3/testsuite/25_algorithms/lexicographical_compare/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/lexicographical_compare/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/lower_bound/2.cc b/libstdc++-v3/testsuite/25_algorithms/lower_bound/2.cc
new file mode 100644
index 00000000000..2d1c911d472
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/lower_bound/2.cc
@@ -0,0 +1,81 @@
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 25.3.3 [lib.alg.binary.search] Binary search algorithms.
+
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+bool test __attribute__((unused)) = true;
+
+const int A[] = {1, 2, 3, 3, 3, 5, 8};
+const int C[] = {8, 5, 3, 3, 3, 2, 1};
+const int N = sizeof(A) / sizeof(int);
+
+// A comparison, equalivalent to std::greater<int> without the
+// dependency on <functional>.
+struct gt
+{
+ bool
+ operator()(const int& x, const int& y) const
+ { return x > y; }
+};
+
+// Each test performs general-case, bookend, not-found condition,
+// and predicate functional checks.
+
+// 25.3.3.1 lower_bound, with and without comparison predicate
+void
+test01()
+{
+ using std::lower_bound;
+
+ const int first = A[0];
+ const int last = A[N - 1];
+
+ const int* p = lower_bound(A, A + N, 3);
+ VERIFY(p == A + 2);
+
+ const int* q = lower_bound(A, A + N, first);
+ VERIFY(q == A + 0);
+
+ const int* r = lower_bound(A, A + N, last);
+ VERIFY(r == A + N - 1);
+
+ const int* s = lower_bound(A, A + N, 4);
+ VERIFY(s == A + 5);
+
+ const int* t = lower_bound(C, C + N, 3, gt());
+ VERIFY(t == C + 2);
+
+ const int* u = lower_bound(C, C + N, first, gt());
+ VERIFY(u == C + N - 1);
+
+ const int* v = lower_bound(C, C + N, last, gt());
+ VERIFY(v == C + 0);
+
+ const int* w = lower_bound(C, C + N, 4, gt());
+ VERIFY(w == C + 2);
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/lower_bound/33613.cc b/libstdc++-v3/testsuite/25_algorithms/lower_bound/33613.cc
new file mode 100644
index 00000000000..189464cb8d4
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/lower_bound/33613.cc
@@ -0,0 +1,36 @@
+// 2007-10-02 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// { dg-options "-D_GLIBCXX_DEBUG" }
+// { dg-do compile }
+
+// libstdc++/33613
+
+#include <algorithm>
+
+struct A { };
+struct B { };
+
+bool ab(A, B);
+
+void test01(A* a, B b)
+{
+ std::lower_bound(a, a, b, ab);
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/lower_bound/lower_bound.cc b/libstdc++-v3/testsuite/25_algorithms/lower_bound/no_operator_ne.cc
index b132cddfe76..b132cddfe76 100644
--- a/libstdc++-v3/testsuite/25_algorithms/lower_bound/lower_bound.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/lower_bound/no_operator_ne.cc
diff --git a/libstdc++-v3/testsuite/25_algorithms/lower_bound/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/lower_bound/requirements/explicit_instantiation/2.cc
index b7b62bd94b2..b4ba007c58c 100644
--- a/libstdc++-v3/testsuite/25_algorithms/lower_bound/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/lower_bound/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/make_heap/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/make_heap/requirements/explicit_instantiation/2.cc
index fa77fc5855c..6cec88af906 100644
--- a/libstdc++-v3/testsuite/25_algorithms/make_heap/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/make_heap/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/max/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/max/requirements/explicit_instantiation/2.cc
index 5987e95282a..c25b091c6e0 100644
--- a/libstdc++-v3/testsuite/25_algorithms/max/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/max/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/max_element/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/max_element/requirements/explicit_instantiation/2.cc
index c8bce1658cb..8bc4458142b 100644
--- a/libstdc++-v3/testsuite/25_algorithms/max_element/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/max_element/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/merge/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/merge/requirements/explicit_instantiation/2.cc
index 3d7c46ad70d..0ef0ca1a81c 100644
--- a/libstdc++-v3/testsuite/25_algorithms/merge/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/merge/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/min/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/min/requirements/explicit_instantiation/2.cc
index 03d0726229c..da30edb8827 100644
--- a/libstdc++-v3/testsuite/25_algorithms/min/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/min/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/min_element/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/min_element/requirements/explicit_instantiation/2.cc
index 5ab09b5448a..6c53c046b33 100644
--- a/libstdc++-v3/testsuite/25_algorithms/min_element/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/min_element/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/next_permutation/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/next_permutation/requirements/explicit_instantiation/2.cc
index c89eba09f08..fd6b3a92dac 100644
--- a/libstdc++-v3/testsuite/25_algorithms/next_permutation/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/next_permutation/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/nth_element/moveable.cc b/libstdc++-v3/testsuite/25_algorithms/nth_element/moveable.cc
new file mode 100644
index 00000000000..c521d382b2f
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/nth_element/moveable.cc
@@ -0,0 +1,76 @@
+// { dg-require-rvalref "" }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.3.2 [lib.alg.nth.element]
+
+#undef _GLIBCXX_CONCEPT_CHECKS
+
+#include <algorithm>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+#include <testsuite_rvalref.h>
+
+using __gnu_test::test_container;
+using __gnu_test::random_access_iterator_wrapper;
+using std::nth_element;
+using __gnu_test::rvalstruct;
+
+typedef test_container<rvalstruct, random_access_iterator_wrapper> Container;
+
+void
+test1()
+{
+ int intarray[] = {6, 5, 4, 3, 2, 1, 0};
+ rvalstruct array[7];
+ std::copy(intarray, intarray + 7, array);
+ Container con(array, array + 7);
+ nth_element(con.begin(), con.it(3), con.end());
+ for(int i = 0; i < 3; ++i)
+ VERIFY(array[i].val < 3);
+ for(int i = 4; i < 7; ++i)
+ VERIFY(array[i].val > 3);
+ for(int i = 0; i < 7; ++i)
+ VERIFY(array[i].valid);
+}
+
+void
+test2()
+{
+ int intarray[] = {0, 6, 1, 5, 2, 4, 3};
+ rvalstruct array[7];
+ std::copy(intarray, intarray + 7, array);
+ Container con(array,array + 7);
+ nth_element(con.begin(), con.it(3), con.end());
+ for(int i = 0; i < 3; ++i)
+ VERIFY(array[i].val < 3);
+ for(int i = 4; i < 7; ++i)
+ VERIFY(array[i].val > 3);
+ for(int i = 0; i < 7; ++i)
+ VERIFY(array[i].valid);
+}
+
+int
+main()
+{
+ test1();
+ test2();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/nth_element/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/nth_element/requirements/explicit_instantiation/2.cc
index 0d5a7efa12a..b40f0036c1c 100644
--- a/libstdc++-v3/testsuite/25_algorithms/nth_element/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/nth_element/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/partial_sort/moveable.cc b/libstdc++-v3/testsuite/25_algorithms/partial_sort/moveable.cc
new file mode 100644
index 00000000000..990da41f094
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/partial_sort/moveable.cc
@@ -0,0 +1,70 @@
+// { dg-require-rvalref "" }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.3.1.3 [lib.partial.sort]
+
+#undef _GLIBCXX_CONCEPT_CHECKS
+#define _GLIBCXX_TESTSUITE_ALLOW_RVALREF_ALIASING
+
+#include <algorithm>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+#include <testsuite_rvalref.h>
+
+using __gnu_test::test_container;
+using __gnu_test::random_access_iterator_wrapper;
+using __gnu_test::rvalstruct;
+using std::partial_sort;
+
+typedef test_container<rvalstruct, random_access_iterator_wrapper> Container;
+
+void
+test1()
+{
+ int intarray[] = {6, 5, 4, 3, 2, 1, 0};
+ rvalstruct array[7];
+ std::copy(intarray, intarray + 7, array);
+ Container con(array, array + 7);
+ partial_sort(con.begin(), con.it(3), con.end());
+ VERIFY(array[0].val == 0 && array[1].val == 1 && array[2].val == 2);
+ for(int i = 0; i < 7; ++i)
+ VERIFY(array[i].valid);
+}
+
+void
+test2()
+{
+ int intarray[] = {0, 6, 1, 5, 2, 4, 3};
+ rvalstruct array[7];
+ std::copy(intarray, intarray + 7, array);
+ Container con(array,array + 7);
+ partial_sort(con.begin(), con.it(3), con.end());
+ VERIFY(array[0].val == 0 && array[1].val == 1 && array[2].val == 2);
+ for(int i = 0; i < 7; ++i)
+ VERIFY(array[i].valid);
+}
+
+int
+main()
+{
+ test1();
+ test2();
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/partial_sort/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/partial_sort/requirements/explicit_instantiation/2.cc
index f2f3f7eec29..b53a9db081c 100644
--- a/libstdc++-v3/testsuite/25_algorithms/partial_sort/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/partial_sort/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/partial_sort_copy/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/partial_sort_copy/requirements/explicit_instantiation/2.cc
index 8a962ff5482..7f7628fa5b9 100644
--- a/libstdc++-v3/testsuite/25_algorithms/partial_sort_copy/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/partial_sort_copy/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/partition/partition.cc b/libstdc++-v3/testsuite/25_algorithms/partition/1.cc
index 66edb6f4748..b71ec23fbf0 100644
--- a/libstdc++-v3/testsuite/25_algorithms/partition/partition.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/partition/1.cc
@@ -50,24 +50,9 @@ test01()
for (const int* i = m; i < s1 + N; ++i) VERIFY(!pred(*i));
}
-// 25.2.12 stable_partition()
-void
-test02()
-{
- using std::stable_partition;
-
- int s1[N];
- std::copy(A, A + N, s1);
-
- stable_partition(s1, s1 + N, Pred());
- VERIFY(std::equal(s1, s1 + N, B));
-}
-
int
main()
{
test01();
- test02();
-
return 0;
}
diff --git a/libstdc++-v3/testsuite/25_algorithms/partition/moveable.cc b/libstdc++-v3/testsuite/25_algorithms/partition/moveable.cc
new file mode 100644
index 00000000000..a31e5277bfa
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/partition/moveable.cc
@@ -0,0 +1,89 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without Pred the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.2.12 [lib.alg.partitions] Partitions.
+
+#undef _GLIBCXX_CONCEPT_CHECKS
+
+#include <algorithm>
+#include <functional>
+#include <testsuite_hooks.h>
+#include <testsuite_rvalref.h>
+#include <testsuite_iterators.h>
+
+using __gnu_test::test_container;
+using __gnu_test::forward_iterator_wrapper;
+using __gnu_test::bidirectional_iterator_wrapper;
+using __gnu_test::rvalstruct;
+
+typedef test_container<rvalstruct, forward_iterator_wrapper> Fcontainer;
+typedef test_container<rvalstruct, bidirectional_iterator_wrapper> Bcontainer;
+
+bool test __attribute__((unused)) = true;
+
+const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
+const int B[] = {2, 4, 6, 8, 10, 12, 14, 16, 1, 3, 5, 7, 9, 11, 13, 15, 17};
+const int N = sizeof(A) / sizeof(int);
+
+struct Pred
+{
+ bool
+ operator()(const rvalstruct& x) const
+ { return (x.val % 2) == 0; }
+};
+
+// 25.2.12 partition()
+void
+test01()
+{
+ using std::partition;
+
+ rvalstruct farray[N];
+ rvalstruct barray[N];
+
+ std::copy(A, A + N, farray);
+ std::copy(A, A + N, barray);
+
+ Fcontainer fcon(farray, farray + N);
+ Bcontainer bcon(barray, barray + N);
+
+ Pred pred;
+
+ VERIFY(partition(fcon.begin(), fcon.end(), pred).ptr - farray == N/2);
+ for (const rvalstruct* i = farray; i < farray+N/2; ++i)
+ VERIFY(pred(*i));
+
+ for (const rvalstruct* i = farray+N/2; i < farray + N; ++i)
+ VERIFY(!pred(*i));
+
+ VERIFY(partition(bcon.begin(), bcon.end(), pred).ptr - barray == N/2);
+
+ for (const rvalstruct* i = barray; i < barray+N/2; ++i)
+ VERIFY(pred(*i));
+ for (const rvalstruct* i = barray+N/2; i < barray + N; ++i)
+ VERIFY(!pred(*i));
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/partition/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/partition/requirements/explicit_instantiation/2.cc
index 231411d5129..84fe246122e 100644
--- a/libstdc++-v3/testsuite/25_algorithms/partition/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/partition/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/pop_heap/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/pop_heap/requirements/explicit_instantiation/2.cc
index 06a7d0dcb40..4517c55f28c 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pop_heap/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pop_heap/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/prev_permutation/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/prev_permutation/requirements/explicit_instantiation/2.cc
index 6a888618642..d4dd5864bca 100644
--- a/libstdc++-v3/testsuite/25_algorithms/prev_permutation/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/prev_permutation/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/push_heap/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/push_heap/requirements/explicit_instantiation/2.cc
index 5e600423304..aaa4e77618a 100644
--- a/libstdc++-v3/testsuite/25_algorithms/push_heap/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/push_heap/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/random_shuffle/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/random_shuffle/requirements/explicit_instantiation/2.cc
index ad1faf620cc..55cc05d3514 100644
--- a/libstdc++-v3/testsuite/25_algorithms/random_shuffle/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/random_shuffle/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/remove/moveable.cc b/libstdc++-v3/testsuite/25_algorithms/remove/moveable.cc
new file mode 100644
index 00000000000..5a0e77e2e89
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/remove/moveable.cc
@@ -0,0 +1,67 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.2.4 remove
+
+#undef _GLIBCXX_CONCEPT_CHECKS
+
+#include <algorithm>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+#include <testsuite_rvalref.h>
+
+using __gnu_test::test_container;
+using __gnu_test::forward_iterator_wrapper;
+using __gnu_test::rvalstruct;
+
+typedef test_container<rvalstruct, forward_iterator_wrapper> Container;
+
+void
+test1()
+{
+ int intarray[] = {1};
+ rvalstruct array[1];
+ std::copy(intarray, intarray + 1, array);
+ Container con(array, array + 1);
+ rvalstruct remove_val0(0);
+ rvalstruct remove_val1(1);
+ VERIFY(std::remove(con.begin(), con.end(), remove_val0).ptr == array + 1);
+ VERIFY(std::remove(con.begin(), con.end(), remove_val1).ptr == array);
+}
+
+void
+test2()
+{
+ int intarray[] = {0, 1, 0, 1, 0, 0, 1, 1};
+ rvalstruct array[8];
+ std::copy(intarray, intarray + 8, array);
+ Container con(array, array + 8);
+ rvalstruct remove_val(1);
+ VERIFY(std::remove(con.begin(), con.end(), remove_val).ptr == array + 4);
+ VERIFY(array[0].val == 0 && array[1].val == 0 && array[2].val == 0 &&
+ array[3].val == 0);
+}
+
+int
+main()
+{
+ test1();
+ test2();
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/remove/requirements/explicit_instantiation/pod.cc b/libstdc++-v3/testsuite/25_algorithms/remove/requirements/explicit_instantiation/pod.cc
index 1bc1bcc4b77..ca538192dec 100644
--- a/libstdc++-v3/testsuite/25_algorithms/remove/requirements/explicit_instantiation/pod.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/remove/requirements/explicit_instantiation/pod.cc
@@ -39,6 +39,5 @@ namespace std
typedef pod_int value_type;
typedef value_type* iterator_type;
- template iterator_type remove(iterator_type, iterator_type,
- const value_type&);
+ template iterator_type remove<iterator_type, value_type>(iterator_type, iterator_type, const value_type&);
}
diff --git a/libstdc++-v3/testsuite/25_algorithms/remove_copy_if/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/remove_copy_if/requirements/explicit_instantiation/2.cc
index 4ac704793d2..af0426f7604 100644
--- a/libstdc++-v3/testsuite/25_algorithms/remove_copy_if/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/remove_copy_if/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/remove_if/moveable.cc b/libstdc++-v3/testsuite/25_algorithms/remove_if/moveable.cc
new file mode 100644
index 00000000000..db49433452f
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/remove_if/moveable.cc
@@ -0,0 +1,67 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.2.4 remove
+
+#undef _GLIBCXX_CONCEPT_CHECKS
+
+#include <algorithm>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+#include <testsuite_rvalref.h>
+
+using __gnu_test::test_container;
+using __gnu_test::forward_iterator_wrapper;
+using __gnu_test::rvalstruct;
+
+typedef test_container<rvalstruct, forward_iterator_wrapper> Container;
+
+bool equal1(rvalstruct& in) { return in.val == 1; }
+bool equal0(rvalstruct& in) { return in.val == 0; }
+
+void
+test1()
+{
+ int intarray[] = {1};
+ rvalstruct array[1];
+ std::copy(intarray, intarray + 1, array);
+ Container con(array, array + 1);
+ VERIFY(std::remove_if(con.begin(), con.end(), equal0).ptr == array + 1);
+ VERIFY(std::remove_if(con.begin(), con.end(), equal1).ptr == array);
+}
+
+void
+test2()
+{
+ int intarray[] = {0, 1, 0, 1, 0, 0, 1, 1};
+ rvalstruct array[8];
+ std::copy(intarray, intarray + 8, array);
+ Container con(array, array + 8);
+ VERIFY(std::remove_if(con.begin(), con.end(), equal1).ptr == array + 4);
+ VERIFY(array[0] == 0 && array[1] == 0 && array[2] == 0 &&
+ array[3] == 0);
+}
+
+int
+main()
+{
+ test1();
+ test2();
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/remove_if/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/remove_if/requirements/explicit_instantiation/2.cc
index 56e0375d124..654717fca32 100644
--- a/libstdc++-v3/testsuite/25_algorithms/remove_if/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/remove_if/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/replace_copy_if/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/replace_copy_if/requirements/explicit_instantiation/2.cc
index d84cb134789..8647bcec6c5 100644
--- a/libstdc++-v3/testsuite/25_algorithms/replace_copy_if/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/replace_copy_if/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/replace_if/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/replace_if/requirements/explicit_instantiation/2.cc
index 692caf318c9..b13fda1a9ff 100644
--- a/libstdc++-v3/testsuite/25_algorithms/replace_if/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/replace_if/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/reverse/moveable.cc b/libstdc++-v3/testsuite/25_algorithms/reverse/moveable.cc
new file mode 100644
index 00000000000..c01bf71339e
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/reverse/moveable.cc
@@ -0,0 +1,44 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.2.9 Reverse
+
+#undef _GLIBCXX_CONCEPT_CHECKS
+
+#include <algorithm>
+#include <testsuite_iterators.h>
+
+using __gnu_test::bidirectional_iterator_wrapper;
+
+class X
+{
+ X();
+ X(const X&);
+ void operator=(const X&);
+};
+
+void
+swap(X&, X&) { }
+
+void
+test1(bidirectional_iterator_wrapper<X>& begin,
+ bidirectional_iterator_wrapper<X>& end)
+{ std::reverse(begin, end); }
diff --git a/libstdc++-v3/testsuite/25_algorithms/rotate/moveable.cc b/libstdc++-v3/testsuite/25_algorithms/rotate/moveable.cc
new file mode 100644
index 00000000000..6d132cf02bc
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/rotate/moveable.cc
@@ -0,0 +1,78 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.2.10 rotate
+
+// Tests rotate when an moveable class is used
+
+#undef _GLIBCXX_CONCEPT_CHECKS
+
+#include <algorithm>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+#include <testsuite_rvalref.h>
+
+using __gnu_test::test_container;
+using __gnu_test::forward_iterator_wrapper;
+using __gnu_test::bidirectional_iterator_wrapper;
+using __gnu_test::random_access_iterator_wrapper;
+using __gnu_test::rvalstruct;
+
+typedef test_container<rvalstruct, forward_iterator_wrapper> Fcontainer;
+typedef test_container<rvalstruct, bidirectional_iterator_wrapper> Bcontainer;
+typedef test_container<rvalstruct, random_access_iterator_wrapper> Rcontainer;
+
+
+
+void
+test1()
+{
+ bool test __attribute__((unused)) = true;
+ int data[] = {1, 2, 3, 4, 5};
+ rvalstruct array[5];
+ std::copy(data, data + 5, array);
+ Fcontainer fcon(array, array + 5);
+ Bcontainer bcon(array, array + 5);
+ Rcontainer rcon(array, array + 5);
+
+ std::rotate(fcon.begin(), fcon.it(2), fcon.end());
+ VERIFY(array[0].val == 3 && array[1].val == 4 && array[2].val == 5 &&
+ array[3].val == 1 && array[4].val == 2);
+ for(int i=0;i<5;i++)
+ VERIFY(array[i].valid == true);
+
+ std::rotate(bcon.begin(), bcon.it(2), bcon.end());
+ VERIFY(array[0].val == 5 && array[1].val == 1 && array[2].val == 2 &&
+ array[3].val == 3 && array[4].val == 4);
+ for(int i=0;i<5;i++)
+ VERIFY(array[i].valid);
+
+ std::rotate(rcon.begin(), rcon.it(2), rcon.end());
+ VERIFY(array[0].val == 2 && array[1].val == 3 && array[2].val == 4 &&
+ array[3].val == 5 && array[4].val == 1);
+ for(int i=0;i<5;i++)
+ VERIFY(array[i].valid);
+}
+
+int
+main()
+{
+ test1();
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/search/1.cc b/libstdc++-v3/testsuite/25_algorithms/search/1.cc
index ec0763d6f06..ef00b58d010 100644
--- a/libstdc++-v3/testsuite/25_algorithms/search/1.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/search/1.cc
@@ -24,9 +24,11 @@
using __gnu_test::test_container;
using __gnu_test::forward_iterator_wrapper;
+using __gnu_test::random_access_iterator_wrapper;
using std::search;
typedef test_container<int, forward_iterator_wrapper> Container;
+typedef test_container<int, random_access_iterator_wrapper> RAcontainer;
int array1[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1};
int array2[] = {0, 0, 0};
@@ -101,6 +103,53 @@ test6()
== array3 + 6);
}
+bool
+lexstep(int* start, int length)
+{
+ int i = 0;
+ int carry = 1;
+ while(i < length && carry)
+ {
+ if(start[i] == 1)
+ start[i] = 0;
+ else
+ {
+ start[i] = 1;
+ carry = 0;
+ }
+ i++;
+ }
+ return !carry;
+}
+
+void test7()
+{
+ int array1[6];
+ int array2[6];
+ for(int length1 = 0; length1 < 6; length1++)
+ {
+ for(int length2 = 0; length2 < 6; length2++)
+ {
+ std::fill_n(array1, length1, 0);
+ while(lexstep(array1, length1))
+ {
+ std::fill_n(array2, length2, 0);
+ while(lexstep(array2, length2))
+ {
+ Container con1(array1, array1 + length1);
+ Container con2(array2, array2 + length2);
+ RAcontainer rcon1(array1, array1 + length1);
+ RAcontainer rcon2(array2, array2 + length2);
+ VERIFY(search(con1.begin(), con1.end(), con2.begin(),
+ con2.end()).ptr ==
+ search(rcon1.begin(), rcon1.end(), rcon2.begin(),
+ rcon2.end()).ptr);
+ }
+ }
+ }
+ }
+}
+
int
main()
{
@@ -110,4 +159,5 @@ main()
test4();
test5();
test6();
+ test7();
}
diff --git a/libstdc++-v3/testsuite/25_algorithms/search/check_type.cc b/libstdc++-v3/testsuite/25_algorithms/search/check_type.cc
index 4aaa87bea50..4762abdb0e3 100644
--- a/libstdc++-v3/testsuite/25_algorithms/search/check_type.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/search/check_type.cc
@@ -25,14 +25,33 @@
using __gnu_test::forward_iterator_wrapper;
-struct S1 { };
-struct S2 { };
+struct T1 { };
+struct T2 { };
+
+struct S1
+{
+ S1(T1) { }
+};
+
+struct S2 {
+ S2(T2) { }
+};
bool
operator==(const S1&, const S2&) {return true;}
-struct X1 { };
-struct X2 { };
+struct V1 { };
+struct V2 { };
+
+struct X1
+{
+ X1(V1) { };
+};
+
+struct X2
+{
+ X2(V2) { };
+};
bool
predicate(const X1&, const X2&) {return true;}
@@ -41,6 +60,14 @@ forward_iterator_wrapper<S1>
test1(forward_iterator_wrapper<S1>& s1, forward_iterator_wrapper<S2>& s2)
{ return std::search(s1, s1, s2, s2); }
+forward_iterator_wrapper<T1>
+test2(forward_iterator_wrapper<T1>& s1, forward_iterator_wrapper<T2>& s2)
+{ return std::search(s1, s1, s2, s2); }
+
forward_iterator_wrapper<X1>
-test2(forward_iterator_wrapper<X1>& x1, forward_iterator_wrapper<X2>& x2)
+test3(forward_iterator_wrapper<X1>& x1, forward_iterator_wrapper<X2>& x2)
+{ return std::search(x1, x1, x2, x2, predicate); }
+
+forward_iterator_wrapper<V1>
+test4(forward_iterator_wrapper<V1>& x1, forward_iterator_wrapper<V2>& x2)
{ return std::search(x1, x1, x2, x2, predicate); }
diff --git a/libstdc++-v3/testsuite/25_algorithms/search/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/search/requirements/explicit_instantiation/2.cc
index 2f526e840f3..062f3e56233 100644
--- a/libstdc++-v3/testsuite/25_algorithms/search/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/search/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/search_n/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/search_n/requirements/explicit_instantiation/2.cc
index 1338df98eda..8ff2badc157 100644
--- a/libstdc++-v3/testsuite/25_algorithms/search_n/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/search_n/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/set_difference/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/set_difference/requirements/explicit_instantiation/2.cc
index 238cfbc9561..0ed15900273 100644
--- a/libstdc++-v3/testsuite/25_algorithms/set_difference/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/set_difference/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/set_intersection/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/set_intersection/requirements/explicit_instantiation/2.cc
index 95cd2bcb38c..812daaa02d1 100644
--- a/libstdc++-v3/testsuite/25_algorithms/set_intersection/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/set_intersection/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/set_symmetric_difference/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/set_symmetric_difference/requirements/explicit_instantiation/2.cc
index 3df16097c71..8f753edafc1 100644
--- a/libstdc++-v3/testsuite/25_algorithms/set_symmetric_difference/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/set_symmetric_difference/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/set_union/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/set_union/requirements/explicit_instantiation/2.cc
index d89ddeb26a3..56fdda16b9c 100644
--- a/libstdc++-v3/testsuite/25_algorithms/set_union/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/set_union/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/sort/moveable.cc b/libstdc++-v3/testsuite/25_algorithms/sort/moveable.cc
new file mode 100644
index 00000000000..168374fa658
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/sort/moveable.cc
@@ -0,0 +1,64 @@
+// { dg-require-rvalref "" }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.3.1 algorithms, sort()
+
+#undef _GLIBCXX_CONCEPT_CHECKS
+#define _GLIBCXX_TESTSUITE_ALLOW_RVALREF_ALIASING
+
+#include <algorithm>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+#include <testsuite_rvalref.h>
+
+bool test __attribute__((unused)) = true;
+
+using __gnu_test::test_container;
+using __gnu_test::random_access_iterator_wrapper;
+using __gnu_test::rvalstruct;
+using std::partial_sort;
+
+typedef test_container<rvalstruct, random_access_iterator_wrapper> Container;
+
+
+const int A[] = {10, 20, 1, 11, 2, 12, 3, 13, 4, 14, 5, 15, 6, 16, 7,
+ 17, 8, 18, 9, 19};
+const int N = sizeof(A) / sizeof(int);
+
+// 25.3.1.1 sort()
+void
+test01()
+{
+ rvalstruct s1[N];
+ std::copy(A, A + N, s1);
+ Container con(s1, s1 + N);
+ std::sort(con.begin(), con.end());
+ VERIFY(s1[0].valid);
+ for(int i = 1; i < N; ++i)
+ VERIFY(s1[i].val>s1[i-1].val && s1[i].valid);
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/sort/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/sort/requirements/explicit_instantiation/2.cc
index 6142cf52ae0..7b417325187 100644
--- a/libstdc++-v3/testsuite/25_algorithms/sort/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/sort/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/sort/vectorbool.cc b/libstdc++-v3/testsuite/25_algorithms/sort/vectorbool.cc
new file mode 100644
index 00000000000..04d69f02f3e
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/sort/vectorbool.cc
@@ -0,0 +1,44 @@
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.3.1 algorithms, sort()
+
+#include <algorithm>
+#include <vector>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::vector<bool> b;
+ b.push_back(false);
+ b.push_back(true);
+ b.push_back(false);
+ b.push_back(true);
+ std::sort(b.begin(), b.end());
+ VERIFY( b[0] == false && b[1] == false && b[2] == true && b[3] == true );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/sort_heap/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/sort_heap/requirements/explicit_instantiation/2.cc
index f8c686f0e03..2b68d9444a5 100644
--- a/libstdc++-v3/testsuite/25_algorithms/sort_heap/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/sort_heap/requirements/explicit_instantiation/2.cc
@@ -31,6 +31,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/stable_partition/1.cc b/libstdc++-v3/testsuite/25_algorithms/stable_partition/1.cc
new file mode 100644
index 00000000000..29188f882ed
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/stable_partition/1.cc
@@ -0,0 +1,56 @@
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without Pred the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 25.2.12 [lib.alg.partitions] Partitions.
+
+#include <algorithm>
+#include <functional>
+#include <testsuite_hooks.h>
+
+bool test __attribute__((unused)) = true;
+
+const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
+const int B[] = {2, 4, 6, 8, 10, 12, 14, 16, 1, 3, 5, 7, 9, 11, 13, 15, 17};
+const int N = sizeof(A) / sizeof(int);
+
+struct Pred
+{
+ bool
+ operator()(const int& x) const
+ { return (x % 2) == 0; }
+};
+
+// 25.2.12 stable_partition()
+void
+test02()
+{
+ using std::stable_partition;
+
+ int s1[N];
+ std::copy(A, A + N, s1);
+
+ stable_partition(s1, s1 + N, Pred());
+ VERIFY(std::equal(s1, s1 + N, B));
+}
+
+int
+main()
+{
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/stable_partition/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/stable_partition/requirements/explicit_instantiation/2.cc
index 2eb8dbc8949..fafcf50cd68 100644
--- a/libstdc++-v3/testsuite/25_algorithms/stable_partition/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/stable_partition/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/stable_sort/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/stable_sort/requirements/explicit_instantiation/2.cc
index f08c7b26591..e5235f278e5 100644
--- a/libstdc++-v3/testsuite/25_algorithms/stable_sort/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/stable_sort/requirements/explicit_instantiation/2.cc
@@ -31,6 +31,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/swap_ranges/moveable.cc b/libstdc++-v3/testsuite/25_algorithms/swap_ranges/moveable.cc
new file mode 100644
index 00000000000..f1d842441a9
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/swap_ranges/moveable.cc
@@ -0,0 +1,44 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.2.4 Swap Ranges
+
+#undef _GLIBCXX_CONCEPT_CHECKS
+
+#include <algorithm>
+#include <testsuite_iterators.h>
+
+using __gnu_test::forward_iterator_wrapper;
+
+class X
+{
+ X();
+ X(const X&);
+ void operator=(const X&);
+};
+
+void
+swap(X&, X&) { }
+
+void
+test1(forward_iterator_wrapper<X>& begin, forward_iterator_wrapper<X>& end,
+ forward_iterator_wrapper<X>& begin2)
+{ std::swap_ranges(begin, end, begin2); }
diff --git a/libstdc++-v3/testsuite/25_algorithms/transform/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/transform/requirements/explicit_instantiation/2.cc
index 0262c5c1285..730b8fa898b 100644
--- a/libstdc++-v3/testsuite/25_algorithms/transform/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/transform/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/unique/moveable.cc b/libstdc++-v3/testsuite/25_algorithms/unique/moveable.cc
new file mode 100644
index 00000000000..13bcc1b22fd
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/unique/moveable.cc
@@ -0,0 +1,73 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 25.2.8 [lib.alg.unique] Unique
+
+#undef _GLIBCXX_CONCEPT_CHECKS
+
+#include <vector>
+#include <algorithm>
+#include <functional>
+#include <testsuite_hooks.h>
+#include <testsuite_iterators.h>
+#include <testsuite_rvalref.h>
+
+using __gnu_test::test_container;
+using __gnu_test::forward_iterator_wrapper;
+using __gnu_test::rvalstruct;
+
+typedef test_container<rvalstruct, forward_iterator_wrapper> Container;
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ int intarray1[] = {1, 4, 4, 6, 1, 2, 2, 3, 1, 6, 6, 6, 5, 7, 5, 4, 4};
+ int intarray2[] = {1, 1, 1, 2, 2, 1, 1, 7, 6, 6, 7, 8, 8, 8, 8, 9, 9};
+
+ const int N = sizeof(intarray1) / sizeof(int);
+
+ rvalstruct T1[N];
+ rvalstruct T2[N];
+
+ std::copy(intarray1,intarray1 + N, T1);
+ std::copy(intarray2,intarray2 + N, T2);
+
+ const int A1[] = {1, 4, 6, 1, 2, 3, 1, 6, 5, 7, 5, 4};
+ const int B1[] = {1, 2, 1, 7, 6, 7, 8, 9};
+
+ Container con(T1, T1 + N);
+
+ VERIFY(std::unique(con.begin(), con.end()).ptr - T1 == 12);
+ for(int i = 0; i < 12; ++i)
+ VERIFY(T1[i].val == A1[i]);
+
+ Container con2(T2, T2 + N);
+ VERIFY(std::unique(con2.begin(), con2.end()).ptr - T2 == 8);
+ for(int i = 0; i < 8; ++i)
+ VERIFY(T2[i].val == B1[i]);
+}
+
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/unique/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/unique/requirements/explicit_instantiation/2.cc
index ccc227869f1..7c1eeebbdba 100644
--- a/libstdc++-v3/testsuite/25_algorithms/unique/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/unique/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/unique_copy/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/unique_copy/requirements/explicit_instantiation/2.cc
index 3f45d541a08..dbed82a0013 100644
--- a/libstdc++-v3/testsuite/25_algorithms/unique_copy/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/unique_copy/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/25_algorithms/upper_bound/2.cc b/libstdc++-v3/testsuite/25_algorithms/upper_bound/2.cc
new file mode 100644
index 00000000000..1fac53cd730
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/upper_bound/2.cc
@@ -0,0 +1,81 @@
+// Copyright (C) 2001 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 25.3.3 [lib.alg.binary.search] Binary search algorithms.
+
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+bool test __attribute__((unused)) = true;
+
+const int A[] = {1, 2, 3, 3, 3, 5, 8};
+const int C[] = {8, 5, 3, 3, 3, 2, 1};
+const int N = sizeof(A) / sizeof(int);
+
+// A comparison, equalivalent to std::greater<int> without the
+// dependency on <functional>.
+struct gt
+{
+ bool
+ operator()(const int& x, const int& y) const
+ { return x > y; }
+};
+
+// Each test performs general-case, bookend, not-found condition,
+// and predicate functional checks.
+
+// 25.3.3.2 upper_bound, with and without comparison predicate
+void
+test02()
+{
+ using std::upper_bound;
+
+ const int first = A[0];
+ const int last = A[N - 1];
+
+ const int* p = upper_bound(A, A + N, 3);
+ VERIFY(p == A + 5);
+
+ const int* q = upper_bound(A, A + N, first);
+ VERIFY(q == A + 1);
+
+ const int* r = upper_bound(A, A + N, last);
+ VERIFY(r == A + N);
+
+ const int* s = upper_bound(A, A + N, 4);
+ VERIFY(s == A + 5);
+
+ const int* t = upper_bound(C, C + N, 3, gt());
+ VERIFY(t == C + 5);
+
+ const int* u = upper_bound(C, C + N, first, gt());
+ VERIFY(u == C + N);
+
+ const int* v = upper_bound(C, C + N, last, gt());
+ VERIFY(v == C + 1);
+
+ const int* w = upper_bound(C, C + N, 4, gt());
+ VERIFY(w == C + 2);
+}
+
+int
+main()
+{
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/upper_bound/33613.cc b/libstdc++-v3/testsuite/25_algorithms/upper_bound/33613.cc
new file mode 100644
index 00000000000..a178428d363
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/upper_bound/33613.cc
@@ -0,0 +1,36 @@
+// 2007-10-02 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// { dg-options "-D_GLIBCXX_DEBUG" }
+// { dg-do compile }
+
+// libstdc++/33613
+
+#include <algorithm>
+
+struct A { };
+struct B { };
+
+bool ba(B, A);
+
+void test01(A* a, B b)
+{
+ std::upper_bound(a, a, b, ba);
+}
diff --git a/libstdc++-v3/testsuite/25_algorithms/upper_bound/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/25_algorithms/upper_bound/requirements/explicit_instantiation/2.cc
index 192962c4913..66f80924471 100644
--- a/libstdc++-v3/testsuite/25_algorithms/upper_bound/requirements/explicit_instantiation/2.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/upper_bound/requirements/explicit_instantiation/2.cc
@@ -30,6 +30,7 @@
// the GNU General Public License.
#include <algorithm>
+#include <functional>
#include <testsuite_api.h>
namespace std
diff --git a/libstdc++-v3/testsuite/26_numerics/accumulate/1.cc b/libstdc++-v3/testsuite/26_numerics/accumulate/1.cc
new file mode 100644
index 00000000000..046532debef
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/accumulate/1.cc
@@ -0,0 +1,54 @@
+// Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 26.4.1 [lib.accumulate]
+
+#include <numeric>
+#include <testsuite_hooks.h>
+
+int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+const int NA = sizeof(A) / sizeof(int);
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ int res = std::accumulate(A, A + NA, 11);
+ VERIFY( res == 66 );
+}
+
+bool B[] = {true, false, true, true, false, true, false, true, true, false};
+const int NB = sizeof(B) / sizeof(bool);
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ int res = std::accumulate(B, B + NB, 100);
+ VERIFY( res == 106 );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/inner_product/1.cc b/libstdc++-v3/testsuite/26_numerics/inner_product/1.cc
new file mode 100644
index 00000000000..d63c1d91099
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/inner_product/1.cc
@@ -0,0 +1,56 @@
+// Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 26.4.2 [lib.inner_product]
+
+#include <numeric>
+#include <testsuite_hooks.h>
+
+int A1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+int A2[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
+const int NA = sizeof(A1) / sizeof(int);
+
+bool B1[] = {false, true, true, false, true, false, true, true, false, true};
+bool B2[] = {true, false, true, true, false, true, false, true, true, false};
+const int NB = sizeof(B1) / sizeof(bool);
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ int res = std::inner_product(A1, A1 + NA, A2, 31);
+ VERIFY( res == 983 );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ int res = std::inner_product(B1, B1 + NB, B2, 100);
+ VERIFY( res == 102 );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/lib/dg-options.exp b/libstdc++-v3/testsuite/lib/dg-options.exp
index a13fa74cf63..327b691fc0f 100644
--- a/libstdc++-v3/testsuite/lib/dg-options.exp
+++ b/libstdc++-v3/testsuite/lib/dg-options.exp
@@ -79,3 +79,12 @@ proc dg-require-time { args } {
}
return
}
+
+proc dg-require-rvalref { args } {
+ if { ![ check_v3_target_rvalref ] } {
+ upvar dg-do-what dg-do-what
+ set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
+ return
+ }
+ return
+}
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index 6603d71a01d..b482bf58d20 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -83,7 +83,7 @@ proc libstdc++_init { testfile } {
global env
global v3-sharedlib
global srcdir blddir objdir tool_root_dir
- global cc cxx cxxflags cxxldflags
+ global cc cxx cxxflags cxxpchflags cxxldflags
global includes
global gluefile wrap_flags
global ld_library_path
@@ -184,6 +184,7 @@ proc libstdc++_init { testfile } {
# Default settings.
set cxx [transform "g++"]
set cxxflags "-g -O2 -D_GLIBCXX_ASSERT -fmessage-length=0"
+ set cxxpchflags ""
set cxxldflags ""
set cc [transform "gcc"]
# Locate testsuite_hooks.h and other testsuite headers.
@@ -221,6 +222,7 @@ proc libstdc++_init { testfile } {
# If we find a testsuite_flags file, we're testing in the build dir.
set cxx [exec sh $flags_file --build-cxx]
set cxxflags [exec sh $flags_file --cxxflags]
+ set cxxpchflags [exec sh $flags_file --cxxpchflags]
set cxxldflags [exec sh $flags_file --cxxldflags]
set cc [exec sh $flags_file --build-cc]
set includes [exec sh $flags_file --build-includes]
@@ -237,23 +239,29 @@ proc libstdc++_init { testfile } {
# this check until $cxx and such have been initialized because we
# perform a test compilation. (Ideally, gcc --print-file-name would
# list PCH files, but it does not.)
- global PCH_CXXFLAGS
- if ![info exists PCH_CXXFLAGS] then {
+ if { $cxxpchflags != "" } {
set src "config[pid].cc"
set f [open $src "w"]
puts $f "int main () {}"
close $f
+ # Fixme: "additional_flags=$cxxpchflags" fails, but would be
+ # useful as then the requested variant of the pre-build PCH
+ # files could be tested to see if it works.
set lines [v3_target_compile $src "config[pid].o" object \
- "additional_flags=-include additional_flags=bits/stdtr1c++.h"]
- if {$lines == "" } {
-# set PCH_CXXFLAGS "-include bits/extc++.h"
-# set PCH_CXXFLAGS "-include bits/stdtr1c++.h"
- set PCH_CXXFLAGS "-include bits/stdc++.h"
- } else {
- set PCH_CXXFLAGS ""
- }
+ "additional_flags=-include additional_flags=bits/stdc++.h"]
+ if { $lines != "" } {
+ verbose -log "Requested PCH file: $cxxpchflags"
+ verbose -log "is not working, and will not be used."
+ set cxxpchflags ""
+ }
file delete $src
+ }
+ v3track cxxpchflags 2
+
+ global PCH_CXXFLAGS
+ if ![info exists PCH_CXXFLAGS] then {
+ set PCH_CXXFLAGS $cxxpchflags
v3track PCH_CXXFLAGS 2
}
@@ -762,6 +770,61 @@ proc check_v3_target_time { } {
return $et_time_saved
}
+proc check_v3_target_rvalref { } {
+ global et_rvalref_saved
+ global et_rvalref_target_name
+ global tool
+
+ if { ![info exists et_rvalref_target_name] } {
+ set et_rvalref_target_name ""
+ }
+
+ # If the target has changed since we set the cached value, clear it.
+ set current_target [current_target_name]
+ if { $current_target != $et_rvalref_target_name } {
+ verbose "check_v3_target_rvalref: `$et_rvalref_target_name'" 2
+ set et_rvalref_target_name $current_target
+ if [info exists et_rvalref_saved] {
+ verbose "check_v3_target_rvalref: removing cached result" 2
+ unset et_rvalref_saved
+ }
+ }
+
+ if [info exists et_rvalref_saved] {
+ verbose "check_v3_target_rvalref: using cached result" 2
+ } else {
+ set et_rvalref_saved 0
+
+ # Set up and compile a C++ test program that tries to use
+ # the library components of rval references
+ set src rvalref[pid].cc
+ set exe rvalref[pid].x
+
+ set f [open $src "w"]
+ puts $f "#include <iterator>"
+ puts $f "#include <utility>"
+ puts $f "using std::move;"
+ puts $f "using std::identity;"
+ puts $f "using std::forward;"
+ puts $f "using std::move_iterator;"
+ puts $f "using std::make_move_iterator;"
+ close $f
+
+ set lines [v3_target_compile $src $exe executable ""]
+ file delete $src
+
+ if [string match "" $lines] {
+ # No error message, compilation succeeded.
+ verbose "check_v3_target_rvalref: compilation succeeded" 2
+ remote_file build delete $exe
+ set et_rvalref_saved 1
+ } else {
+ verbose "check_v3_target_rvalref: compilation failed" 2
+ }
+ }
+ return $et_rvalref_saved
+}
+
proc check_v3_target_namedlocale { } {
global et_namedlocale_saved
global et_namedlocale_target_name
diff --git a/libstdc++-v3/testsuite/thread/guard.cc b/libstdc++-v3/testsuite/thread/guard.cc
new file mode 100644
index 00000000000..0e9e827003d
--- /dev/null
+++ b/libstdc++-v3/testsuite/thread/guard.cc
@@ -0,0 +1,67 @@
+//
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* } }
+// { dg-options "-pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-darwin* alpha*-*-osf* } }
+
+#include <cstdlib>
+#include <pthread.h>
+
+// This used to deadlock with the old libstdc++ because there is only one
+// global mutex guarding initialization of statics and it is held during by
+// the initializer thread of a static until the variable is completely
+// initialized. If the initializer thread creates and waits for another thread
+// which also initializes a static variable, there will be a deadlock because
+// the first thread is holding the mutex and waiting for the second thread,
+// which is blocked when it is acquiring the mutex.
+
+int
+get_bar (void)
+{
+ return 1;
+}
+
+void*
+do_something (void *arg)
+{
+ static int bar = get_bar ();
+ return NULL;
+}
+
+int
+get_foo (void)
+{
+ int status;
+ pthread_t new_thread;
+
+ if (pthread_create (&new_thread, NULL, do_something, NULL) != 0)
+ std::abort ();
+
+ if (pthread_join (new_thread, NULL) != 0)
+ std::abort ();
+
+ return 1;
+}
+
+int
+main (int argc, char **argv)
+{
+ static int foo = get_foo ();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/util/testsuite_api.h b/libstdc++-v3/testsuite/util/testsuite_api.h
index 3cd7c6177f7..ca0d716bd18 100644
--- a/libstdc++-v3/testsuite/util/testsuite_api.h
+++ b/libstdc++-v3/testsuite/util/testsuite_api.h
@@ -28,6 +28,7 @@
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
+#include <exception>
#include <testsuite_hooks.h>
#ifndef _TESTSUITE_API
diff --git a/libstdc++-v3/testsuite/util/testsuite_rvalref.h b/libstdc++-v3/testsuite/util/testsuite_rvalref.h
new file mode 100644
index 00000000000..ca947166d12
--- /dev/null
+++ b/libstdc++-v3/testsuite/util/testsuite_rvalref.h
@@ -0,0 +1,194 @@
+// -*- C++ -*-
+// Testing utilities for the rvalue reference.
+//
+// Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef _GLIBCXX_TESTSUITE_RVALREF_H
+#define _GLIBCXX_TESTSUITE_RVALREF_H 1
+
+#include <testsuite_hooks.h>
+
+namespace __gnu_test
+{
+
+ // This class is designed to test libstdc++'s template-based rvalue
+ // reference support. It should fail at compile-time if there is an attempt
+ // to copy it (although see note just below).
+ class rvalstruct
+ {
+ bool
+ operator=(const rvalstruct&);
+
+// Normally we don't define a copy constructor, as any use of it would
+// show an inefficency. In some cases we know it will be aliased away
+// by the compiler, but it still insists it is defined, so we provide
+// a way of making it public but not giving a body, so any usage would
+// instead fail at link-time.
+#ifdef _GLIBCXX_TESTSUITE_ALLOW_RVALREF_ALIASING
+ public:
+ rvalstruct(const rvalstruct&);
+#else
+ rvalstruct(const rvalstruct&);
+
+ public:
+#endif
+ int val;
+ bool valid;
+
+ rvalstruct() : valid(false)
+ { }
+
+ rvalstruct(int inval) : val(inval), valid(true)
+ { }
+
+ rvalstruct&
+ operator=(int newval)
+ {
+ VERIFY(valid == false);
+ val = newval;
+ valid = true;
+ }
+
+ rvalstruct(rvalstruct&& in)
+ {
+ VERIFY(in.valid == true);
+ val = in.val;
+ in.valid = false;
+ valid = true;
+ }
+
+ rvalstruct&
+ operator=(rvalstruct&& in)
+ {
+ VERIFY(in.valid == true);
+ val = in.val;
+ in.valid = false;
+ valid = true;
+ return *this;
+ }
+ };
+
+ bool
+ operator==(const rvalstruct& lhs, const rvalstruct& rhs)
+ { return lhs.val == rhs.val; }
+
+ bool
+ operator<(const rvalstruct& lhs, const rvalstruct& rhs)
+ { return lhs.val < rhs.val; }
+
+ void
+ swap(rvalstruct& lhs, rvalstruct& rhs)
+ {
+ VERIFY(lhs.valid && rhs.valid);
+ int temp = lhs.val;
+ lhs.val = rhs.val;
+ rhs.val = temp;
+ }
+
+ // This is a moveable class which copies how many times it is copied.
+ // This is mainly of use in the containers, where the an element inserted
+ // into a container has to be copied once to get there, but we want to check
+ // nothing else is copied.
+ struct copycounter
+ {
+ static int copycount;
+ int val;
+ bool valid;
+
+ copycounter() : val(0), valid(true)
+ { }
+
+ copycounter(int inval) : val(inval), valid(true)
+ { }
+
+ copycounter(const copycounter& in) : val(in.val), valid(true)
+ {
+ VERIFY(in.valid == true);
+ ++copycount;
+ }
+
+ copycounter(copycounter&& in)
+ {
+ VERIFY(in.valid == true);
+ val = in.val;
+ in.valid = false;
+ valid = true;
+ }
+
+ copycounter&
+ operator=(int newval)
+ {
+ val = newval;
+ valid = true;
+ }
+
+ bool
+ operator=(const copycounter& in)
+ {
+ VERIFY(in.valid == true);
+ ++copycount;
+ val = in.val;
+ valid = true;
+ }
+
+ copycounter&
+ operator=(copycounter&& in)
+ {
+ VERIFY(in.valid == true);
+ val = in.val;
+ in.valid = false;
+ valid = true;
+ return *this;
+ }
+
+ ~copycounter()
+ { valid = false; }
+ };
+
+ int copycounter::copycount = 0;
+
+ bool
+ operator==(const copycounter& lhs, const copycounter& rhs)
+ { return lhs.val == rhs.val; }
+
+ bool
+ operator<(const copycounter& lhs, const copycounter& rhs)
+ { return lhs.val < rhs.val; }
+
+ void
+ swap(copycounter& lhs, copycounter& rhs)
+ {
+ VERIFY(lhs.valid && rhs.valid);
+ int temp = lhs.val;
+ lhs.val = rhs.val;
+ rhs.val = temp;
+ }
+
+}; // namespace __gnu_test
+
+#endif // _GLIBCXX_TESTSUITE_TR1_H