aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Stump <mikestump@comcast.net>2014-05-05 18:05:00 +0000
committerMike Stump <mikestump@comcast.net>2014-05-05 18:05:00 +0000
commit91a1c2cb28bceefdee4a97613c31a7ae1c583ff1 (patch)
tree7342177f89c95ba43e316bb8c9608761ddca7866
parentaf7eaf53540cb1051615d6314e18744d9480ced2 (diff)
Merge in trunk.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/wide-int@210075 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog172
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/c-family/ChangeLog9
-rw-r--r--gcc/c-family/c.opt5
-rw-r--r--gcc/c/ChangeLog83
-rw-r--r--gcc/c/c-decl.c3
-rw-r--r--gcc/c/c-parser.c45
-rw-r--r--gcc/c/c-tree.h2
-rw-r--r--gcc/c/c-typeck.c227
-rw-r--r--gcc/config/aarch64/aarch64.c3
-rw-r--r--gcc/config/arc/arc.c3
-rw-r--r--gcc/config/arm/arm.h2
-rw-r--r--gcc/config/avr/avr.c4
-rw-r--r--gcc/config/mips/mips.c8
-rw-r--r--gcc/config/mips/mips.h78
-rw-r--r--gcc/config/nds32/nds32.h2
-rw-r--r--gcc/config/picochip/picochip-protos.h4
-rw-r--r--gcc/config/picochip/picochip.c4
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def4
-rw-r--r--gcc/config/rs6000/rs6000.c18
-rw-r--r--gcc/config/rs6000/rs6000.h7
-rw-r--r--gcc/config/s390/s390.c11
-rw-r--r--gcc/config/sh/sh-mem.cc295
-rw-r--r--gcc/config/sh/sh.c94
-rw-r--r--gcc/config/sh/sh.h55
-rw-r--r--gcc/config/sh/sh_optimize_sett_clrt.cc10
-rw-r--r--gcc/cp/ChangeLog32
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c2
-rw-r--r--gcc/cp/decl2.c19
-rw-r--r--gcc/cp/lambda.c24
-rw-r--r--gcc/cp/pt.c40
-rw-r--r--gcc/cp/semantics.c5
-rw-r--r--gcc/cp/typeck.c7
-rw-r--r--gcc/defaults.h4
-rw-r--r--gcc/doc/invoke.texi18
-rw-r--r--gcc/doc/tm.texi8
-rw-r--r--gcc/doc/tm.texi.in6
-rw-r--r--gcc/final.c4
-rw-r--r--gcc/fold-const.c33
-rw-r--r--gcc/fortran/ChangeLog42
-rw-r--r--gcc/fortran/gfortran.h1
-rw-r--r--gcc/fortran/parse.c10
-rw-r--r--gcc/fortran/resolve.c2
-rw-r--r--gcc/fortran/trans-decl.c100
-rw-r--r--gcc/fortran/trans-expr.c96
-rw-r--r--gcc/fortran/trans-intrinsic.c41
-rw-r--r--gcc/fortran/trans-stmt.c5
-rw-r--r--gcc/fortran/trans-types.c15
-rw-r--r--gcc/fortran/trans.h6
-rw-r--r--gcc/gimplify.c21
-rw-r--r--gcc/go/ChangeLog14
-rw-r--r--gcc/go/Make-lang.in1
-rw-r--r--gcc/go/go-backend.c9
-rw-r--r--gcc/go/go-c.h5
-rw-r--r--gcc/go/go-lang.c70
-rw-r--r--gcc/go/gofrontend/expressions.cc75
-rw-r--r--gcc/go/gofrontend/gogo-tree.cc122
-rw-r--r--gcc/go/gofrontend/gogo.cc9
-rw-r--r--gcc/hwint.h2
-rw-r--r--gcc/ira-color.c27
-rw-r--r--gcc/lra-constraints.c150
-rw-r--r--gcc/omp-low.c18
-rw-r--r--gcc/passes.c10
-rw-r--r--gcc/po/ChangeLog11
-rw-r--r--gcc/po/sv.po40
-rw-r--r--gcc/po/zh_CN.po2
-rw-r--r--gcc/target.def12
-rw-r--r--gcc/targhooks.c9
-rw-r--r--gcc/targhooks.h1
-rw-r--r--gcc/testsuite/ChangeLog148
-rw-r--r--gcc/testsuite/c-c++-common/pr43395.c30
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/deleted4.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/deleted5.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/deleted6.C9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const3.C38
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr58419.c9
-rw-r--r--gcc/testsuite/gcc.dg/declspec-13.c24
-rw-r--r--gcc/testsuite/gcc.dg/hoist-register-pressure-1.c14
-rw-r--r--gcc/testsuite/gcc.dg/hoist-register-pressure-2.c14
-rw-r--r--gcc/testsuite/gcc.dg/hoist-register-pressure-3.c14
-rw-r--r--gcc/testsuite/gcc.dg/pr25801.c44
-rw-r--r--gcc/testsuite/gcc.dg/pr29467.c13
-rw-r--r--gcc/testsuite/gcc.dg/pr43245.c18
-rw-r--r--gcc/testsuite/gcc.dg/pr56989.c19
-rw-r--r--gcc/testsuite/gcc.dg/pr60257.c37
-rw-r--r--gcc/testsuite/gcc.dg/pr60784.c25
-rw-r--r--gcc/testsuite/gcc.dg/pr60915.c7
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr61010.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/cond-reduc-1.c19
-rw-r--r--gcc/testsuite/gcc.dg/vect/cond-reduc-2.c19
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpf32_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpp16_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpp8_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpqf32_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpqp16_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpqp8_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpqs16_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpqs32_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpqs8_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpqu16_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpqu32_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpqu8_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzps16_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzps32_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzps8_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpu16_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpu32_1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/simd/vuzpu8_1.c12
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pack02.c4
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pack03.c4
-rw-r--r--gcc/testsuite/gcc.target/s390/leaf-profile.c10
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_usage_24_c.c5
-rw-r--r--gcc/testsuite/gfortran.dg/c_f_pointer_logical_driver.c8
-rw-r--r--gcc/testsuite/gfortran.dg/coarray/codimension.f9049
-rw-r--r--gcc/testsuite/gfortran.dg/coarray_lib_this_image_1.f9027
-rw-r--r--gcc/testsuite/gfortran.dg/coarray_lib_this_image_2.f9027
-rw-r--r--gcc/testsuite/gfortran.dg/coarray_lib_token_4.f904
-rw-r--r--gcc/testsuite/gfortran.dg/coarray_poly_4.f9023
-rw-r--r--gcc/testsuite/gfortran.dg/coarray_poly_5.f9014
-rw-r--r--gcc/testsuite/gfortran.dg/coarray_poly_6.f9022
-rw-r--r--gcc/testsuite/gfortran.dg/coarray_poly_7.f9022
-rw-r--r--gcc/testsuite/gfortran.dg/coarray_poly_8.f9022
-rw-r--r--gcc/testsuite/go.test/go-test.exp6
-rw-r--r--gcc/tree-if-conv.c153
-rw-r--r--gcc/tree-ssa-threadupdate.c93
127 files changed, 2564 insertions, 957 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e3ae8dcfc81..87d71416a78 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,175 @@
+2014-05-05 Richard Biener <rguenther@suse.de>
+
+ * passes.c (execute_function_todo): Move TODO_verify_flow under
+ the TODO_verify_ul umbrella.
+
+2014-05-05 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/61010
+ * fold-const.c (fold_binary_loc): Consistently avoid
+ canonicalizing X & CST away from a CST that is the mask
+ of a mode.
+
+2014-05-05 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+
+ * config/picochip/picochip-protos.h (picochip_regno_nregs): Change
+ int argument to enum machine_mode.
+ (picochip_class_max_nregs): Ditto.
+ * config/picochip/picochip.c (picochip_regno_nregs): Ditto.
+ (picochip_class_max_nregs): Ditto.
+
+2014-05-05 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * target.def: Add new target hook.
+ * doc/tm.texi: Regenerate.
+ * targhooks.h (default_keep_leaf_when_profiled): Add prototype.
+ * targhooks.c (default_keep_leaf_when_profiled): New function.
+
+ * config/s390/s390.c (s390_keep_leaf_when_profiled): New function.
+ (TARGET_KEEP_LEAF_WHEN_PROFILED): Define.
+
+2014-05-05 Bin Cheng <bin.cheng@arm.com>
+
+ PR tree-optimization/60363
+ * gcc/tree-ssa-threadupdate.c (get_value_locus_in_path): New.
+ (copy_phi_args): New parameters. Call get_value_locus_in_path.
+ (update_destination_phis): New parameter.
+ (create_edge_and_update_destination_phis): Ditto.
+ (ssa_fix_duplicate_block_edges): Pass new arguments.
+ (thread_single_edge): Ditto.
+
+2014-05-04 Peter Bergner <bergner@vnet.ibm.com>
+
+ * config/rs6000/rs6000.h (RS6000_BTM_HARD_FLOAT): New define.
+ (RS6000_BTM_COMMON): Add RS6000_BTM_HARD_FLOAT.
+ (TARGET_EXTRA_BUILTINS): Add TARGET_HARD_FLOAT.
+ * config/rs6000/rs6000-builtin.def (BU_MISC_1):
+ Use RS6000_BTM_HARD_FLOAT.
+ (BU_MISC_2): Likewise.
+ * config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Handle
+ RS6000_BTM_HARD_FLOAT.
+ (rs6000_option_override_internal): Enforce -mhard-float if -mhard-dfp
+ is explicitly used.
+ (rs6000_invalid_builtin): Add hard floating builtin support.
+ (rs6000_expand_builtin): Relax the gcc_assert to allow the new
+ hard float builtins.
+ (rs6000_builtin_mask_names): Add RS6000_BTM_HARD_FLOAT.
+
+2014-05-03 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/sh_optimize_sett_clrt.cc (sh_optimize_sett_clrt::execute):
+ Add missing function* argument.
+
+2014-05-03 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * lra-constraints.c (valid_address_p): Move earlier in file.
+ Add a constraint argument to the address_info version.
+ (satisfies_memory_constraint_p): New function.
+ (satisfies_address_constraint_p): Likewise.
+ (process_alt_operands, curr_insn_transform): Use them.
+ (process_address): Pass the constraint to valid_address_p when
+ checking address operands.
+
+2014-05-03 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mips/mips.c (mips_isa_rev): New variable.
+ (mips_set_architecture): Set it.
+ * config/mips/mips.h (TARGET_CPU_CPP_BUILTINS): Set __mips_isa_rev
+ from mips_isa_rev.
+ (ISA_HAS_MUL3, ISA_HAS_FP_CONDMOVE, ISA_HAS_8CC, ISA_HAS_FP4)
+ (ISA_HAS_PAIRED_SINGLE, ISA_HAS_MADD_MSUB, ISA_HAS_FP_RECIP_RSQRT)
+ (ISA_HAS_CLZ_CLO, ISA_HAS_ROR, ISA_HAS_WSBH, ISA_HAS_PREFETCH)
+ (ISA_HAS_SEB_SEH, ISA_HAS_EXT_INS, ISA_HAS_MXHC1)
+ (ISA_HAS_HILO_INTERLOCKS, ISA_HAS_SYNCI, MIN_FPRS_PER_FMT): Reexpress
+ conditions in terms of mips_isa_rev.
+ (mips_isa_rev): Declare.
+
+2014-05-03 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/sh-mem.cc: Use tabs instead of spaces.
+ (prob_unlikely, prob_likely): Make variables const.
+
+2014-05-03 Denis Chertykov <chertykov@gmail.com>
+
+ * config/avr/avr.c (avr_adjust_insn_length): Handle JUMP_TABLE_DATA.
+
+2014-05-03 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/sh.h (SH_ASM_SPEC): Handle m1, m2*, m3* and m4* cases.
+
+2014-05-03 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/sh.h (ROUND_ADVANCE): Delete macro.
+ (ROUND_REG, PASS_IN_REG_P): Move and rename macros to ...
+ * config/sh/sh.c (sh_round_reg, sh_pass_in_reg_p): ... these new
+ functions.
+ (sh_arg_partial_bytes, sh_function_arg, sh_function_arg_advance,
+ sh_setup_incoming_varargs): Replace usage of PASS_IN_REG_P with
+ sh_pass_in_reg_p.
+ Replace usage of ROUND_REG with sh_round_reg.
+ Use CEIL instead of ROUND_ADVANCE.
+
+2014-05-03 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/61026
+ * config/sh/sh.c: Include stdlib headers before everything else.
+
+2014-05-02 Jakub Jelinek <jakub@redhat.com>
+
+ * gimplify.c (gimplify_adjust_omp_clauses_1): Handle
+ GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE.
+ (gimplify_adjust_omp_clauses): Simd region is never
+ directly nested in combined parallel. Instead, for linear
+ with copyin/copyout, if in combined for simd loop, make decl
+ firstprivate/lastprivate on OMP_FOR.
+ * omp-low.c (expand_omp_for_generic, expand_omp_for_static_nochunk,
+ expand_omp_for_static_chunk): When setting endvar, also set
+ fd->loop.v to the same value.
+
+2014-05-02 Richard Sandiford <rsandifo@linux.vnet.ibm.com>
+
+ * hwint.h (zext_hwi): Fix signed overflow for prec == 63.
+
+2014-05-02 Alan Lawrence <alan.lawrence@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_expand_vec_perm_1): Tidy bit-flip
+ expression.
+
+2014-05-02 Marek Polacek <polacek@redhat.com>
+
+ * doc/invoke.texi: Describe -fsanitize=float-divide-by-zero.
+
+2014-02-26 Kito Cheng <kito@0xlab.org>
+
+ * defaults.h (HONOR_REG_ALLOC_ORDER): Change HONOR_REG_ALLOC_ORDER
+ to a C expression marco.
+ * ira-color.c (HONOR_REG_ALLOC_ORDER) : Ditto.
+ * config/arm/arm.h (HONOR_REG_ALLOC_ORDER): Ditto.
+ * config/nds32/nds32.h (HONOR_REG_ALLOC_ORDER): Ditto.
+ * doc/tm.texi (HONOR_REG_ALLOC_ORDER): Update document for
+ HONOR_REG_ALLOC_ORDER.
+ * doc/tm.texi.in (HONOR_REG_ALLOC_ORDER): Ditto.
+
+2014-05-01 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+
+ * config/arc/arc.c (TARGET_LRA_P): Undef before redefine.
+
+2014-05-01 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+
+ * config/arc/arc.c (arc_select_cc_mode): Fix typo.
+
+2014-05-01 Yuri Rumyantsev <ysrumyan@gmail.com>
+
+ * tree-if-conv.c (is_cond_scalar_reduction): New function.
+ (convert_scalar_cond_reduction): Likewise.
+ (predicate_scalar_phi): Add recognition and transformation
+ of simple conditioanl reduction to be vectorizable.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/43245
+ * doc/invoke.texi: Document -Wdiscarded-qualifiers.
+
2014-04-30 Alan Lawrence <alan.lawrence@arm.com>
* config/aarch64/arm_neon.h (vuzp1_f32, vuzp1_p8, vuzp1_p16, vuzp1_s8,
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 5907e7a3156..d43065abe47 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20140430
+20140505
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 47bb11438ad..3c9732395d3 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,12 @@
+2014-05-02 Marek Polacek <polacek@redhat.com>
+
+ * c.opt (Wsizeof-pointer-memaccess): Describe option.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/43245
+ * c.opt (Wdiscarded-qualifiers): Add.
+
2014-04-30 Marek Polacek <polacek@redhat.com>
* c-ubsan.c (ubsan_instrument_division): Handle REAL_TYPEs. Perform
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 94447082fb5..7aa9e23c10e 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -355,6 +355,10 @@ Wdeprecated
C C++ ObjC ObjC++ Var(warn_deprecated) Init(1) Warning
Warn if a deprecated compiler feature, class, method, or field is used
+Wdiscarded-qualifiers
+C ObjC Var(warn_discarded_qualifiers) Init(1) Warning
+Warn if type qualifiers on pointers are discarded
+
Wdiv-by-zero
C ObjC C++ ObjC++ Var(warn_div_by_zero) Init(1) Warning
Warn about compile-time integer division by zero
@@ -512,6 +516,7 @@ Warn about missing fields in struct initializers
Wsizeof-pointer-memaccess
C ObjC C++ ObjC++ Var(warn_sizeof_pointer_memaccess) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
+Warn about suspicious length parameters to certain string functions if the argument uses sizeof
Wsuggest-attribute=format
C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index bf61610e37c..e408fef274d 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,81 @@
+2014-05-02 Marek Polacek <polacek@redhat.com>
+
+ PR c/25801
+ * c-typeck.c (c_size_in_bytes): Update comment. Don't call error.
+ Return size_one_node when the type is not complete.
+ (pointer_diff): Remove comment.
+ (build_unary_op): Improve error messages.
+
+2014-05-02 Marek Polacek <polacek@redhat.com>
+
+ * c-typeck.c (c_finish_return): Separate warning_at calls.
+
+2014-05-02 Marek Polacek <polacek@redhat.com>
+
+ * c-tree.h (error_init): Remove declaration.
+ (pedwarn_init): Likewise.
+ * c-typeck.c (error_init): Make static and move above.
+ (pedwarn_init): Likewise.
+ (warning_init): Move above.
+ (maybe_warn_string_init): Likewise.
+
+2014-05-01 Jeff Law <law@redhat.com>
+
+ Revert:
+
+ 2014-04-24 Prathamesh Kulkarni <bilbotheelffriend@gmail.com>
+ * c-parser.c (c_parser_sizeof_expression): Reorganize slightly to
+ avoid goto.
+
+2014-05-02 Marek Polacek <polacek@redhat.com>
+
+ PR c/60784
+ * c-typeck.c (push_init_level): Set constructor_designated to
+ p->designated for structures.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/60915
+ * c-parser.c (c_parser_declaration_or_fndef): Give better error if
+ function-definition has an attribute after the declarator.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/60257
+ * c-typeck.c (warning_init): Add location_t parameter. Call
+ warning_at instead of warning.
+ (push_init_level): Pass input_location to warning_init.
+ (add_pending_init): Add location_t parameter. Pass loc to
+ warning_init.
+ (set_nonincremental_init): Pass input_location to add_pending_init.
+ (set_nonincremental_init_from_string): Likewise.
+ (output_init_element): Pass loc to warning_init and to
+ add_pending_init.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/43395
+ * c-typeck.c (c_finish_return): Distinguish between label and variable
+ when warning about returning local address.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/29467
+ * c-decl.c (declspecs_add_type): Pedwarn if boolean types are used
+ in C89 mode.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/43245
+ * c-typeck.c (convert_for_assignment): Pass OPT_Wdiscarded_qualifiers
+ instead of 0 to WARN_FOR_QUALIFIERS.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/56989
+ * c-typeck.c (default_conversion): Use better location for
+ error call.
+
2014-04-30 Marek Polacek <polacek@redhat.com>
* c-typeck.c (build_binary_op): Call ubsan_instrument_division
@@ -39,11 +117,6 @@
(process_init_element): Add location_t parameter. Pass loc to
output_init_element.
-2014-04-24 Prathamesh Kulkarni <bilbotheelffriend@gmail.com>
-
- * c-parser.c (c_parser_sizeof_expression): Reorganize slightly to
- avoid goto.
-
2014-04-24 Jakub Jelinek <jakub@redhat.com>
* c-parser.c (c_parser_omp_atomic): Allow seq_cst before
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 90808eda618..3abf6b98574 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -9565,6 +9565,9 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
}
return specs;
case RID_BOOL:
+ if (!flag_isoc99 && !in_system_header_at (loc))
+ pedwarn (loc, OPT_Wpedantic,
+ "ISO C90 does not support boolean types");
if (specs->long_p)
error_at (loc,
("both %<long%> and %<_Bool%> in "
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 41ae77b541e..6e8f33bdac1 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -1688,7 +1688,19 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
if (c_parser_next_token_is_keyword (parser, RID_ASM))
asm_name = c_parser_simple_asm_expr (parser);
if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
- postfix_attrs = c_parser_attributes (parser);
+ {
+ postfix_attrs = c_parser_attributes (parser);
+ if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
+ {
+ /* This means there is an attribute specifier after
+ the declarator in a function definition. Provide
+ some more information for the user. */
+ error_at (here, "attributes should be specified before the "
+ "declarator in a function definition");
+ c_parser_skip_to_end_of_block_or_statement (parser);
+ return;
+ }
+ }
if (c_parser_next_token_is (parser, CPP_EQ))
{
tree d;
@@ -6517,29 +6529,30 @@ c_parser_sizeof_expression (c_parser *parser)
return ret;
}
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
- expr = c_parser_postfix_expression_after_paren_type (parser,
- type_name,
- expr_loc);
- else
{
- /* sizeof ( type-name ). */
- c_inhibit_evaluation_warnings--;
- in_sizeof--;
- return c_expr_sizeof_type (expr_loc, type_name);
+ expr = c_parser_postfix_expression_after_paren_type (parser,
+ type_name,
+ expr_loc);
+ goto sizeof_expr;
}
+ /* sizeof ( type-name ). */
+ c_inhibit_evaluation_warnings--;
+ in_sizeof--;
+ return c_expr_sizeof_type (expr_loc, type_name);
}
else
{
expr_loc = c_parser_peek_token (parser)->location;
expr = c_parser_unary_expression (parser);
+ sizeof_expr:
+ c_inhibit_evaluation_warnings--;
+ in_sizeof--;
+ mark_exp_read (expr.value);
+ if (TREE_CODE (expr.value) == COMPONENT_REF
+ && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
+ error_at (expr_loc, "%<sizeof%> applied to a bit-field");
+ return c_expr_sizeof_expr (expr_loc, expr);
}
- c_inhibit_evaluation_warnings--;
- in_sizeof--;
- mark_exp_read (expr.value);
- if (TREE_CODE (expr.value) == COMPONENT_REF
- && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
- error_at (expr_loc, "%<sizeof%> applied to a bit-field");
- return c_expr_sizeof_expr (expr_loc, expr);
}
/* Parse an alignof expression. */
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 53768d619b7..a6e73279125 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -602,8 +602,6 @@ extern tree build_compound_expr (location_t, tree, tree);
extern tree c_cast_expr (location_t, struct c_type_name *, tree);
extern tree build_c_cast (location_t, tree, tree);
extern void store_init_value (location_t, tree, tree, tree);
-extern void error_init (const char *);
-extern void pedwarn_init (location_t, int opt, const char *);
extern void maybe_warn_string_init (tree, struct c_expr);
extern void start_init (tree, tree, int);
extern void finish_init (void);
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 11825a9218e..7d2df6b1d12 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -101,14 +101,15 @@ static void push_string (const char *);
static void push_member_name (tree);
static int spelling_length (void);
static char *print_spelling (char *);
-static void warning_init (int, const char *);
+static void warning_init (location_t, int, const char *);
static tree digest_init (location_t, tree, tree, tree, bool, bool, int);
static void output_init_element (location_t, tree, tree, bool, tree, tree, int,
bool, struct obstack *);
static void output_pending_init_elements (int, struct obstack *);
static int set_designator (int, struct obstack *);
static void push_range_stack (tree, struct obstack *);
-static void add_pending_init (tree, tree, tree, bool, struct obstack *);
+static void add_pending_init (location_t, tree, tree, tree, bool,
+ struct obstack *);
static void set_nonincremental_init (struct obstack *);
static void set_nonincremental_init_from_string (tree, struct obstack *);
static tree find_init_member (tree, struct obstack *);
@@ -1754,22 +1755,20 @@ type_lists_compatible_p (const_tree args1, const_tree args2,
}
}
-/* Compute the size to increment a pointer by. */
+/* Compute the size to increment a pointer by. When a function type or void
+ type or incomplete type is passed, size_one_node is returned.
+ This function does not emit any diagnostics; the caller is responsible
+ for that. */
static tree
c_size_in_bytes (const_tree type)
{
enum tree_code code = TREE_CODE (type);
- if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
+ if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK
+ || !COMPLETE_TYPE_P (type))
return size_one_node;
- if (!COMPLETE_OR_VOID_TYPE_P (type))
- {
- error ("arithmetic on pointer to an incomplete type");
- return size_one_node;
- }
-
/* Convert in case a char is more than one unit. */
return size_binop_loc (input_location, CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
size_int (TYPE_PRECISION (char_type_node)
@@ -2108,7 +2107,8 @@ default_conversion (tree exp)
if (code == VOID_TYPE)
{
- error ("void value not ignored as it ought to be");
+ error_at (EXPR_LOC_OR_LOC (exp, input_location),
+ "void value not ignored as it ought to be");
return error_mark_node;
}
@@ -3529,7 +3529,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (orig_op1))))
error_at (loc, "arithmetic on pointer to an incomplete type");
- /* This generates an error if op0 is pointer to incomplete type. */
op1 = c_size_in_bytes (target_type);
if (pointer_to_zero_sized_aggr_p (TREE_TYPE (orig_op1)))
@@ -4003,16 +4002,18 @@ build_unary_op (location_t location,
if (typecode == POINTER_TYPE)
{
- /* If pointer target is an undefined struct,
+ /* If pointer target is an incomplete type,
we just cannot know how to do the arithmetic. */
if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (argtype)))
{
if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
error_at (location,
- "increment of pointer to unknown structure");
+ "increment of pointer to an incomplete type %qT",
+ TREE_TYPE (argtype));
else
error_at (location,
- "decrement of pointer to unknown structure");
+ "decrement of pointer to an incomplete type %qT",
+ TREE_TYPE (argtype));
}
else if (TREE_CODE (TREE_TYPE (argtype)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (argtype)) == VOID_TYPE)
@@ -5539,6 +5540,72 @@ convert_to_anonymous_field (location_t location, tree type, tree rhs)
return ret;
}
+/* Issue an error message for a bad initializer component.
+ GMSGID identifies the message.
+ The component name is taken from the spelling stack. */
+
+static void
+error_init (const char *gmsgid)
+{
+ char *ofwhat;
+
+ /* The gmsgid may be a format string with %< and %>. */
+ error (gmsgid);
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
+ if (*ofwhat)
+ error ("(near initialization for %qs)", ofwhat);
+}
+
+/* Issue a pedantic warning for a bad initializer component. OPT is
+ the option OPT_* (from options.h) controlling this warning or 0 if
+ it is unconditionally given. GMSGID identifies the message. The
+ component name is taken from the spelling stack. */
+
+static void
+pedwarn_init (location_t location, int opt, const char *gmsgid)
+{
+ char *ofwhat;
+
+ /* The gmsgid may be a format string with %< and %>. */
+ pedwarn (location, opt, gmsgid);
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
+ if (*ofwhat)
+ pedwarn (location, opt, "(near initialization for %qs)", ofwhat);
+}
+
+/* Issue a warning for a bad initializer component.
+
+ OPT is the OPT_W* value corresponding to the warning option that
+ controls this warning. GMSGID identifies the message. The
+ component name is taken from the spelling stack. */
+
+static void
+warning_init (location_t loc, int opt, const char *gmsgid)
+{
+ char *ofwhat;
+
+ /* The gmsgid may be a format string with %< and %>. */
+ warning_at (loc, opt, gmsgid);
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
+ if (*ofwhat)
+ warning_at (loc, opt, "(near initialization for %qs)", ofwhat);
+}
+
+/* If TYPE is an array type and EXPR is a parenthesized string
+ constant, warn if pedantic that EXPR is being used to initialize an
+ object of type TYPE. */
+
+void
+maybe_warn_string_init (tree type, struct c_expr expr)
+{
+ if (pedantic
+ && TREE_CODE (type) == ARRAY_TYPE
+ && TREE_CODE (expr.value) == STRING_CST
+ && expr.original_code != STRING_CST)
+ pedwarn_init (input_location, OPT_Wpedantic,
+ "array initialized from parenthesized string constant");
+}
+
/* Convert value RHS to type TYPE as preparation for an assignment to
an lvalue of type TYPE. If ORIGTYPE is not NULL_TREE, it is the
original type of RHS; this differs from TREE_TYPE (RHS) for enum
@@ -5850,7 +5917,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
vice-versa. */
if (TYPE_QUALS_NO_ADDR_SPACE (ttl)
& ~TYPE_QUALS_NO_ADDR_SPACE (ttr))
- WARN_FOR_QUALIFIERS (location, 0,
+ WARN_FOR_QUALIFIERS (location, OPT_Wdiscarded_qualifiers,
G_("passing argument %d of %qE "
"makes %q#v qualified function "
"pointer from unqualified"),
@@ -5866,7 +5933,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
}
else if (TYPE_QUALS_NO_ADDR_SPACE (ttr)
& ~TYPE_QUALS_NO_ADDR_SPACE (ttl))
- WARN_FOR_QUALIFIERS (location, 0,
+ WARN_FOR_QUALIFIERS (location, OPT_Wdiscarded_qualifiers,
G_("passing argument %d of %qE discards "
"%qv qualifier from pointer target type"),
G_("assignment discards %qv qualifier "
@@ -6047,7 +6114,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
if (TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttr)
& ~TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttl))
{
- WARN_FOR_QUALIFIERS (location, 0,
+ WARN_FOR_QUALIFIERS (location, OPT_Wdiscarded_qualifiers,
G_("passing argument %d of %qE discards "
"%qv qualifier from pointer target type"),
G_("assignment discards %qv qualifier "
@@ -6084,7 +6151,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
where an ordinary one is wanted, but not vice-versa. */
if (TYPE_QUALS_NO_ADDR_SPACE (ttl)
& ~TYPE_QUALS_NO_ADDR_SPACE (ttr))
- WARN_FOR_QUALIFIERS (location, 0,
+ WARN_FOR_QUALIFIERS (location, OPT_Wdiscarded_qualifiers,
G_("passing argument %d of %qE makes "
"%q#v qualified function pointer "
"from unqualified"),
@@ -6404,72 +6471,6 @@ print_spelling (char *buffer)
return buffer;
}
-/* Issue an error message for a bad initializer component.
- GMSGID identifies the message.
- The component name is taken from the spelling stack. */
-
-void
-error_init (const char *gmsgid)
-{
- char *ofwhat;
-
- /* The gmsgid may be a format string with %< and %>. */
- error (gmsgid);
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
- if (*ofwhat)
- error ("(near initialization for %qs)", ofwhat);
-}
-
-/* Issue a pedantic warning for a bad initializer component. OPT is
- the option OPT_* (from options.h) controlling this warning or 0 if
- it is unconditionally given. GMSGID identifies the message. The
- component name is taken from the spelling stack. */
-
-void
-pedwarn_init (location_t location, int opt, const char *gmsgid)
-{
- char *ofwhat;
-
- /* The gmsgid may be a format string with %< and %>. */
- pedwarn (location, opt, gmsgid);
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
- if (*ofwhat)
- pedwarn (location, opt, "(near initialization for %qs)", ofwhat);
-}
-
-/* Issue a warning for a bad initializer component.
-
- OPT is the OPT_W* value corresponding to the warning option that
- controls this warning. GMSGID identifies the message. The
- component name is taken from the spelling stack. */
-
-static void
-warning_init (int opt, const char *gmsgid)
-{
- char *ofwhat;
-
- /* The gmsgid may be a format string with %< and %>. */
- warning (opt, gmsgid);
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
- if (*ofwhat)
- warning (opt, "(near initialization for %qs)", ofwhat);
-}
-
-/* If TYPE is an array type and EXPR is a parenthesized string
- constant, warn if pedantic that EXPR is being used to initialize an
- object of type TYPE. */
-
-void
-maybe_warn_string_init (tree type, struct c_expr expr)
-{
- if (pedantic
- && TREE_CODE (type) == ARRAY_TYPE
- && TREE_CODE (expr.value) == STRING_CST
- && expr.original_code != STRING_CST)
- pedwarn_init (input_location, OPT_Wpedantic,
- "array initialized from parenthesized string constant");
-}
-
/* Digest the parser output INIT as an initializer for type TYPE.
Return a C expression of type TYPE to represent the initial value.
@@ -7267,6 +7268,9 @@ push_init_level (int implicit, struct obstack * braced_init_obstack)
push_member_name (constructor_fields);
constructor_depth++;
}
+ /* If upper initializer is designated, then mark this as
+ designated too to prevent bogus warnings. */
+ constructor_designated = p->designated;
}
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
@@ -7298,7 +7302,8 @@ push_init_level (int implicit, struct obstack * braced_init_obstack)
if (implicit == 1 && warn_missing_braces && !missing_braces_mentioned)
{
missing_braces_mentioned = 1;
- warning_init (OPT_Wmissing_braces, "missing braces around initializer");
+ warning_init (input_location, OPT_Wmissing_braces,
+ "missing braces around initializer");
}
if (TREE_CODE (constructor_type) == RECORD_TYPE
@@ -7359,7 +7364,7 @@ push_init_level (int implicit, struct obstack * braced_init_obstack)
else
{
if (constructor_type != error_mark_node)
- warning_init (0, "braces around scalar initializer");
+ warning_init (input_location, 0, "braces around scalar initializer");
constructor_fields = constructor_type;
constructor_unfilled_fields = constructor_type;
}
@@ -7774,8 +7779,8 @@ set_init_label (tree fieldname, struct obstack * braced_init_obstack)
existing initializer. */
static void
-add_pending_init (tree purpose, tree value, tree origtype, bool implicit,
- struct obstack * braced_init_obstack)
+add_pending_init (location_t loc, tree purpose, tree value, tree origtype,
+ bool implicit, struct obstack *braced_init_obstack)
{
struct init_node *p, **q, *r;
@@ -7796,9 +7801,12 @@ add_pending_init (tree purpose, tree value, tree origtype, bool implicit,
if (!implicit)
{
if (TREE_SIDE_EFFECTS (p->value))
- warning_init (0, "initialized field with side-effects overwritten");
+ warning_init (loc, 0,
+ "initialized field with side-effects "
+ "overwritten");
else if (warn_override_init)
- warning_init (OPT_Woverride_init, "initialized field overwritten");
+ warning_init (loc, OPT_Woverride_init,
+ "initialized field overwritten");
}
p->value = value;
p->origtype = origtype;
@@ -7823,9 +7831,12 @@ add_pending_init (tree purpose, tree value, tree origtype, bool implicit,
if (!implicit)
{
if (TREE_SIDE_EFFECTS (p->value))
- warning_init (0, "initialized field with side-effects overwritten");
+ warning_init (loc, 0,
+ "initialized field with side-effects "
+ "overwritten");
else if (warn_override_init)
- warning_init (OPT_Woverride_init, "initialized field overwritten");
+ warning_init (loc, OPT_Woverride_init,
+ "initialized field overwritten");
}
p->value = value;
p->origtype = origtype;
@@ -8014,10 +8025,8 @@ set_nonincremental_init (struct obstack * braced_init_obstack)
return;
FOR_EACH_CONSTRUCTOR_ELT (constructor_elements, ix, index, value)
- {
- add_pending_init (index, value, NULL_TREE, true,
- braced_init_obstack);
- }
+ add_pending_init (input_location, index, value, NULL_TREE, true,
+ braced_init_obstack);
constructor_elements = NULL;
if (TREE_CODE (constructor_type) == RECORD_TYPE)
{
@@ -8112,7 +8121,7 @@ set_nonincremental_init_from_string (tree str,
value = wide_int_to_tree (type,
wide_int::from_array (val, 2,
HOST_BITS_PER_WIDE_INT * 2));
- add_pending_init (purpose, value, NULL_TREE, true,
+ add_pending_init (input_location, purpose, value, NULL_TREE, true,
braced_init_obstack);
}
@@ -8278,7 +8287,7 @@ output_init_element (location_t loc, tree value, tree origtype,
if (checktype != error_mark_node
&& (TYPE_MAIN_VARIANT (checktype)
!= TYPE_MAIN_VARIANT (DECL_BIT_FIELD_TYPE (field))))
- warning_init (OPT_Wc___compat,
+ warning_init (loc, OPT_Wc___compat,
"enum conversion in initialization is invalid in C++");
}
@@ -8314,7 +8323,7 @@ output_init_element (location_t loc, tree value, tree origtype,
&& tree_int_cst_lt (field, constructor_unfilled_index))
set_nonincremental_init (braced_init_obstack);
- add_pending_init (field, value, origtype, implicit,
+ add_pending_init (loc, field, value, origtype, implicit,
braced_init_obstack);
return;
}
@@ -8341,7 +8350,7 @@ output_init_element (location_t loc, tree value, tree origtype,
}
}
- add_pending_init (field, value, origtype, implicit,
+ add_pending_init (loc, field, value, origtype, implicit,
braced_init_obstack);
return;
}
@@ -8351,10 +8360,11 @@ output_init_element (location_t loc, tree value, tree origtype,
if (!implicit)
{
if (TREE_SIDE_EFFECTS (constructor_elements->last ().value))
- warning_init (0,
+ warning_init (loc, 0,
"initialized field with side-effects overwritten");
else if (warn_override_init)
- warning_init (OPT_Woverride_init, "initialized field overwritten");
+ warning_init (loc, OPT_Woverride_init,
+ "initialized field overwritten");
}
/* We can have just one union field set. */
@@ -9263,9 +9273,14 @@ c_finish_return (location_t loc, tree retval, tree origtype)
&& !DECL_EXTERNAL (inner)
&& !TREE_STATIC (inner)
&& DECL_CONTEXT (inner) == current_function_decl)
- warning_at (loc,
- OPT_Wreturn_local_addr, "function returns address "
- "of local variable");
+ {
+ if (TREE_CODE (inner) == LABEL_DECL)
+ warning_at (loc, OPT_Wreturn_local_addr,
+ "function returns address of label");
+ else
+ warning_at (loc, OPT_Wreturn_local_addr,
+ "function returns address of local variable");
+ }
break;
default:
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index d3d7d1e60d6..6a6fb032647 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -8180,8 +8180,9 @@ aarch64_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
unsigned i, nelt = d->nelt;
rtx x;
+ gcc_assert (nelt == (nelt & -nelt));
for (i = 0; i < nelt; ++i)
- d->perm[i] = (d->perm[i] + nelt) & (2 * nelt - 1);
+ d->perm[i] ^= nelt; /* Keep the same index, but in the other vector. */
x = d->op0;
d->op0 = d->op1;
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 58d95d832c5..113395bd5de 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -552,6 +552,7 @@ static void arc_finalize_pic (void);
#define TARGET_INSN_LENGTH_PARAMETERS arc_insn_length_parameters
+#undef TARGET_LRA_P
#define TARGET_LRA_P arc_lra_p
#define TARGET_REGISTER_PRIORITY arc_register_priority
/* Stores with scaled offsets have different displacement ranges. */
@@ -996,7 +997,7 @@ arc_select_cc_mode (enum rtx_code op, rtx x, rtx y)
if (GET_MODE_CLASS (mode) == MODE_INT
&& y == const0_rtx
&& (op == EQ || op == NE
- || ((op == LT || op == GE) && GET_MODE_SIZE (GET_MODE (x)) <= 4))))
+ || ((op == LT || op == GE) && GET_MODE_SIZE (GET_MODE (x)) <= 4)))
return CC_ZNmode;
/* add.f for if (a+b) */
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 3a9e3ebbb3e..96f3efeb246 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1152,7 +1152,7 @@ extern int arm_regs_in_sequence[];
/* Tell IRA to use the order we define rather than messing it up with its
own cost calculations. */
-#define HONOR_REG_ALLOC_ORDER
+#define HONOR_REG_ALLOC_ORDER 1
/* Interrupt functions can only use registers that have already been
saved by the prologue, even if they would normally be
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 0fa7f6633e2..9f87adaee00 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -7778,8 +7778,8 @@ avr_adjust_insn_length (rtx insn, int len)
the length need not/must not be adjusted for these insns.
It is easier to state this in an insn attribute "adjust_len" than
to clutter up code here... */
-
- if (-1 == recog_memoized (insn))
+
+ if (JUMP_TABLE_DATA_P (insn) || recog_memoized (insn) == -1)
{
return len;
}
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 45256e99250..29d0ac16102 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -585,6 +585,10 @@ const struct mips_cpu_info *mips_tune_info;
/* The ISA level associated with mips_arch. */
int mips_isa;
+/* The ISA revision level. This is 0 for MIPS I to V and N for
+ MIPS{32,64}rN. */
+int mips_isa_rev;
+
/* The architecture selected by -mipsN, or null if -mipsN wasn't used. */
static const struct mips_cpu_info *mips_isa_option_info;
@@ -16900,6 +16904,10 @@ mips_set_architecture (const struct mips_cpu_info *info)
mips_arch_info = info;
mips_arch = info->cpu;
mips_isa = info->isa;
+ if (mips_isa < 32)
+ mips_isa_rev = 0;
+ else
+ mips_isa_rev = (mips_isa & 31) + 1;
}
}
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index b25865b6dfb..6200ffc4e2c 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -441,27 +441,26 @@ struct mips_cpu_info {
else if (ISA_MIPS32) \
{ \
builtin_define ("__mips=32"); \
- builtin_define ("__mips_isa_rev=1"); \
builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS32"); \
} \
else if (ISA_MIPS32R2) \
{ \
builtin_define ("__mips=32"); \
- builtin_define ("__mips_isa_rev=2"); \
builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS32"); \
} \
else if (ISA_MIPS64) \
{ \
builtin_define ("__mips=64"); \
- builtin_define ("__mips_isa_rev=1"); \
builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \
} \
else if (ISA_MIPS64R2) \
{ \
builtin_define ("__mips=64"); \
- builtin_define ("__mips_isa_rev=2"); \
builtin_define ("_MIPS_ISA=_MIPS_ISA_MIPS64"); \
} \
+ if (mips_isa_rev > 0) \
+ builtin_define_with_int_value ("__mips_isa_rev", \
+ mips_isa_rev); \
\
switch (mips_abi) \
{ \
@@ -816,10 +815,7 @@ struct mips_cpu_info {
|| TARGET_MIPS7000 \
|| TARGET_MIPS9000 \
|| TARGET_MAD \
- || ISA_MIPS32 \
- || ISA_MIPS32R2 \
- || ISA_MIPS64 \
- || ISA_MIPS64R2) \
+ || mips_isa_rev >= 1) \
&& !TARGET_MIPS16)
/* ISA has a three-operand multiplication instruction. */
@@ -850,10 +846,7 @@ struct mips_cpu_info {
/* ISA has the floating-point conditional move instructions introduced
in mips4. */
#define ISA_HAS_FP_CONDMOVE ((ISA_MIPS4 \
- || ISA_MIPS32 \
- || ISA_MIPS32R2 \
- || ISA_MIPS64 \
- || ISA_MIPS64R2) \
+ || mips_isa_rev >= 1) \
&& !TARGET_MIPS5500 \
&& !TARGET_MIPS16)
@@ -870,20 +863,15 @@ struct mips_cpu_info {
/* ISA has the mips4 FP condition code instructions: FP-compare to CC,
branch on CC, and move (both FP and non-FP) on CC. */
-#define ISA_HAS_8CC (ISA_MIPS4 \
- || ISA_MIPS32 \
- || ISA_MIPS32R2 \
- || ISA_MIPS64 \
- || ISA_MIPS64R2)
+#define ISA_HAS_8CC (ISA_MIPS4 || mips_isa_rev >= 1)
/* This is a catch all for other mips4 instructions: indexed load, the
FP madd and msub instructions, and the FP recip and recip sqrt
instructions. Note that this macro should only be used by other
ISA_HAS_* macros. */
#define ISA_HAS_FP4 ((ISA_MIPS4 \
- || ISA_MIPS32R2 \
|| ISA_MIPS64 \
- || ISA_MIPS64R2) \
+ || mips_isa_rev >= 2) \
&& !TARGET_MIPS16)
/* ISA has floating-point indexed load and store instructions
@@ -891,17 +879,14 @@ struct mips_cpu_info {
#define ISA_HAS_LXC1_SXC1 ISA_HAS_FP4
/* ISA has paired-single instructions. */
-#define ISA_HAS_PAIRED_SINGLE (ISA_MIPS32R2 || ISA_MIPS64 || ISA_MIPS64R2)
+#define ISA_HAS_PAIRED_SINGLE (ISA_MIPS64 || mips_isa_rev >= 2)
/* ISA has conditional trap instructions. */
#define ISA_HAS_COND_TRAP (!ISA_MIPS1 \
&& !TARGET_MIPS16)
/* ISA has integer multiply-accumulate instructions, madd and msub. */
-#define ISA_HAS_MADD_MSUB (ISA_MIPS32 \
- || ISA_MIPS32R2 \
- || ISA_MIPS64 \
- || ISA_MIPS64R2)
+#define ISA_HAS_MADD_MSUB (mips_isa_rev >= 1)
/* Integer multiply-accumulate instructions should be generated. */
#define GENERATE_MADD_MSUB (TARGET_IMADD && !TARGET_MIPS16)
@@ -928,19 +913,14 @@ struct mips_cpu_info {
(((ISA_HAS_FP4 \
&& ((MODE) == SFmode \
|| ((TARGET_FLOAT64 \
- || ISA_MIPS32R2 \
- || ISA_MIPS64R2) \
+ || mips_isa_rev >= 2) \
&& (MODE) == DFmode))) \
|| (TARGET_SB1 \
&& (MODE) == V2SFmode)) \
&& !TARGET_MIPS16)
/* ISA has count leading zeroes/ones instruction (not implemented). */
-#define ISA_HAS_CLZ_CLO ((ISA_MIPS32 \
- || ISA_MIPS32R2 \
- || ISA_MIPS64 \
- || ISA_MIPS64R2) \
- && !TARGET_MIPS16)
+#define ISA_HAS_CLZ_CLO (mips_isa_rev >= 1 && !TARGET_MIPS16)
/* ISA has three operand multiply instructions that put
the high part in an accumulator: mulhi or mulhiu. */
@@ -978,8 +958,7 @@ struct mips_cpu_info {
&& !TARGET_MIPS16)
/* ISA has the "ror" (rotate right) instructions. */
-#define ISA_HAS_ROR ((ISA_MIPS32R2 \
- || ISA_MIPS64R2 \
+#define ISA_HAS_ROR ((mips_isa_rev >= 2 \
|| TARGET_MIPS5400 \
|| TARGET_MIPS5500 \
|| TARGET_SR71K \
@@ -988,17 +967,13 @@ struct mips_cpu_info {
/* ISA has the WSBH (word swap bytes within halfwords) instruction.
64-bit targets also provide DSBH and DSHD. */
-#define ISA_HAS_WSBH ((ISA_MIPS32R2 || ISA_MIPS64R2) \
- && !TARGET_MIPS16)
+#define ISA_HAS_WSBH (mips_isa_rev >= 2 && !TARGET_MIPS16)
/* ISA has data prefetch instructions. This controls use of 'pref'. */
#define ISA_HAS_PREFETCH ((ISA_MIPS4 \
|| TARGET_LOONGSON_2EF \
|| TARGET_MIPS5900 \
- || ISA_MIPS32 \
- || ISA_MIPS32R2 \
- || ISA_MIPS64 \
- || ISA_MIPS64R2) \
+ || mips_isa_rev >= 1) \
&& !TARGET_MIPS16)
/* ISA has data indexed prefetch instructions. This controls use of
@@ -1013,19 +988,13 @@ struct mips_cpu_info {
#define ISA_HAS_TRUNC_W (!ISA_MIPS1)
/* ISA includes the MIPS32r2 seb and seh instructions. */
-#define ISA_HAS_SEB_SEH ((ISA_MIPS32R2 \
- || ISA_MIPS64R2) \
- && !TARGET_MIPS16)
+#define ISA_HAS_SEB_SEH (mips_isa_rev >= 2 && !TARGET_MIPS16)
/* ISA includes the MIPS32/64 rev 2 ext and ins instructions. */
-#define ISA_HAS_EXT_INS ((ISA_MIPS32R2 \
- || ISA_MIPS64R2) \
- && !TARGET_MIPS16)
+#define ISA_HAS_EXT_INS (mips_isa_rev >= 2 && !TARGET_MIPS16)
/* ISA has instructions for accessing top part of 64-bit fp regs. */
-#define ISA_HAS_MXHC1 (TARGET_FLOAT64 \
- && (ISA_MIPS32R2 \
- || ISA_MIPS64R2))
+#define ISA_HAS_MXHC1 (TARGET_FLOAT64 && mips_isa_rev >= 2)
/* ISA has lwxs instruction (load w/scaled index address. */
#define ISA_HAS_LWXS ((TARGET_SMARTMIPS || TARGET_MICROMIPS) \
@@ -1078,18 +1047,13 @@ struct mips_cpu_info {
MIPS64 and later ISAs to have the interlocks, plus any specific
earlier-ISA CPUs for which CPU documentation declares that the
instructions are really interlocked. */
-#define ISA_HAS_HILO_INTERLOCKS (ISA_MIPS32 \
- || ISA_MIPS32R2 \
- || ISA_MIPS64 \
- || ISA_MIPS64R2 \
+#define ISA_HAS_HILO_INTERLOCKS (mips_isa_rev >= 1 \
|| TARGET_MIPS5500 \
|| TARGET_MIPS5900 \
|| TARGET_LOONGSON_2EF)
/* ISA includes synci, jr.hb and jalr.hb. */
-#define ISA_HAS_SYNCI ((ISA_MIPS32R2 \
- || ISA_MIPS64R2) \
- && !TARGET_MIPS16)
+#define ISA_HAS_SYNCI (mips_isa_rev >= 2 && !TARGET_MIPS16)
/* ISA includes sync. */
#define ISA_HAS_SYNC ((mips_isa >= 2 || TARGET_MIPS3900) && !TARGET_MIPS16)
@@ -1349,8 +1313,7 @@ struct mips_cpu_info {
/* The number of consecutive floating-point registers needed to store the
smallest format supported by the FPU. */
#define MIN_FPRS_PER_FMT \
- (ISA_MIPS32 || ISA_MIPS32R2 || ISA_MIPS64 || ISA_MIPS64R2 \
- ? 1 : MAX_FPRS_PER_FMT)
+ (mips_isa_rev >= 1 ? 1 : MAX_FPRS_PER_FMT)
/* The largest size of value that can be held in floating-point
registers and moved with a single instruction. */
@@ -2958,6 +2921,7 @@ extern const char *mips_hi_relocs[];
extern enum processor mips_arch; /* which cpu to codegen for */
extern enum processor mips_tune; /* which cpu to schedule for */
extern int mips_isa; /* architectural level */
+extern int mips_isa_rev;
extern const struct mips_cpu_info *mips_arch_info;
extern const struct mips_cpu_info *mips_tune_info;
extern unsigned int mips_base_compression_flags;
diff --git a/gcc/config/nds32/nds32.h b/gcc/config/nds32/nds32.h
index 38847e5697c..8f966ec1475 100644
--- a/gcc/config/nds32/nds32.h
+++ b/gcc/config/nds32/nds32.h
@@ -553,7 +553,7 @@ enum nds32_builtins
/* Tell IRA to use the order we define rather than messing it up with its
own cost calculations. */
-#define HONOR_REG_ALLOC_ORDER
+#define HONOR_REG_ALLOC_ORDER 1
/* The number of consecutive hard regs needed starting at
reg "regno" for holding a value of mode "mode". */
diff --git a/gcc/config/picochip/picochip-protos.h b/gcc/config/picochip/picochip-protos.h
index 1f548f8f257..4d8dfd6b298 100644
--- a/gcc/config/picochip/picochip-protos.h
+++ b/gcc/config/picochip/picochip-protos.h
@@ -53,8 +53,8 @@ extern bool ok_to_peephole_ldw(rtx opnd0, rtx opnd1, rtx opnd2, rtx opnd3);
extern rtx gen_min_reg(rtx opnd1,rtx opnd2);
-extern int picochip_regno_nregs (int regno, int mode);
-extern int picochip_class_max_nregs (int klass, int mode);
+extern int picochip_regno_nregs (int regno, enum machine_mode mode);
+extern int picochip_class_max_nregs (int klass, enum machine_mode mode);
extern void picochip_order_regs_for_local_alloc (void);
diff --git a/gcc/config/picochip/picochip.c b/gcc/config/picochip/picochip.c
index 2476f7344f8..8738564d3fc 100644
--- a/gcc/config/picochip/picochip.c
+++ b/gcc/config/picochip/picochip.c
@@ -1229,7 +1229,7 @@ picochip_arg_area_byte_offset (void)
}
int
-picochip_regno_nregs (int regno ATTRIBUTE_UNUSED, int mode)
+picochip_regno_nregs (int regno ATTRIBUTE_UNUSED, enum machine_mode mode)
{
/* Special case - only one register needed. */
@@ -1249,7 +1249,7 @@ picochip_regno_nregs (int regno ATTRIBUTE_UNUSED, int mode)
}
int
-picochip_class_max_nregs (int reg_class, int mode)
+picochip_class_max_nregs (int reg_class, enum machine_mode mode)
{
int size = ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 16793f501e7..8e15bdf1619 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -626,7 +626,7 @@
#define BU_MISC_1(ENUM, NAME, ATTR, ICODE) \
RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
"__builtin_" NAME, /* NAME */ \
- RS6000_BTM_ALWAYS, /* MASK */ \
+ RS6000_BTM_HARD_FLOAT, /* MASK */ \
(RS6000_BTC_ ## ATTR /* ATTR */ \
| RS6000_BTC_UNARY), \
CODE_FOR_ ## ICODE) /* ICODE */
@@ -634,7 +634,7 @@
#define BU_MISC_2(ENUM, NAME, ATTR, ICODE) \
RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
"__builtin_" NAME, /* NAME */ \
- RS6000_BTM_ALWAYS, /* MASK */ \
+ RS6000_BTM_HARD_FLOAT, /* MASK */ \
(RS6000_BTC_ ## ATTR /* ATTR */ \
| RS6000_BTC_BINARY), \
CODE_FOR_ ## ICODE) /* ICODE */
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 0c983f9a105..e4a68347f57 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3039,7 +3039,8 @@ rs6000_builtin_mask_calculate (void)
| ((TARGET_P8_VECTOR) ? RS6000_BTM_P8_VECTOR : 0)
| ((TARGET_CRYPTO) ? RS6000_BTM_CRYPTO : 0)
| ((TARGET_HTM) ? RS6000_BTM_HTM : 0)
- | ((TARGET_DFP) ? RS6000_BTM_DFP : 0));
+ | ((TARGET_DFP) ? RS6000_BTM_DFP : 0)
+ | ((TARGET_HARD_FLOAT) ? RS6000_BTM_HARD_FLOAT : 0));
}
/* Override command line options. Mostly we process the processor type and
@@ -3396,6 +3397,13 @@ rs6000_option_override_internal (bool global_init_p)
rs6000_isa_flags &= ~OPTION_MASK_VSX_TIMODE;
}
+ if (TARGET_DFP && !TARGET_HARD_FLOAT)
+ {
+ if (rs6000_isa_flags_explicit & OPTION_MASK_DFP)
+ error ("-mhard-dfp requires -mhard-float");
+ rs6000_isa_flags &= ~OPTION_MASK_DFP;
+ }
+
/* The quad memory instructions only works in 64-bit mode. In 32-bit mode,
silently turn off quad memory mode. */
if ((TARGET_QUAD_MEMORY || TARGET_QUAD_MEMORY_ATOMIC) && !TARGET_POWERPC64)
@@ -13551,6 +13559,8 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode)
error ("Builtin function %s requires the -mhard-dfp option", name);
else if ((fnmask & RS6000_BTM_P8_VECTOR) != 0)
error ("Builtin function %s requires the -mpower8-vector option", name);
+ else if ((fnmask & RS6000_BTM_HARD_FLOAT) != 0)
+ error ("Builtin function %s requires the -mhard-float option", name);
else
error ("Builtin function %s is not supported with the current options",
name);
@@ -13739,7 +13749,10 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
return ret;
}
- gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
+ unsigned attr = rs6000_builtin_info[uns_fcode].attr & RS6000_BTC_TYPE_MASK;
+ gcc_assert (attr == RS6000_BTC_UNARY
+ || attr == RS6000_BTC_BINARY
+ || attr == RS6000_BTC_TERNARY);
/* Handle simple unary operations. */
d = bdesc_1arg;
@@ -31304,6 +31317,7 @@ static struct rs6000_opt_mask const rs6000_builtin_mask_names[] =
{ "crypto", RS6000_BTM_CRYPTO, false, false },
{ "htm", RS6000_BTM_HTM, false, false },
{ "hard-dfp", RS6000_BTM_DFP, false, false },
+ { "hard-float", RS6000_BTM_HARD_FLOAT, false, false },
};
/* Option variables that we want to support inside attribute((target)) and
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 2e677d5936e..f979905f1da 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -624,7 +624,8 @@ extern int rs6000_vector_align[];
|| TARGET_CMPB /* ISA 2.05 */ \
|| TARGET_POPCNTD /* ISA 2.06 */ \
|| TARGET_ALTIVEC \
- || TARGET_VSX)))
+ || TARGET_VSX \
+ || TARGET_HARD_FLOAT)))
/* E500 cores only support plain "sync", not lwsync. */
#define TARGET_NO_LWSYNC (rs6000_cpu == PROCESSOR_PPC8540 \
@@ -2517,6 +2518,7 @@ extern int frame_pointer_needed;
#define RS6000_BTM_POPCNTD MASK_POPCNTD /* Target supports ISA 2.06. */
#define RS6000_BTM_CELL MASK_FPRND /* Target is cell powerpc. */
#define RS6000_BTM_DFP MASK_DFP /* Decimal floating point. */
+#define RS6000_BTM_HARD_FLOAT MASK_SOFT_FLOAT /* Hardware floating point. */
#define RS6000_BTM_COMMON (RS6000_BTM_ALTIVEC \
| RS6000_BTM_VSX \
@@ -2529,7 +2531,8 @@ extern int frame_pointer_needed;
| RS6000_BTM_HTM \
| RS6000_BTM_POPCNTD \
| RS6000_BTM_CELL \
- | RS6000_BTM_DFP)
+ | RS6000_BTM_DFP \
+ | RS6000_BTM_HARD_FLOAT)
/* Define builtin enum index. */
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 7183f2c2867..6c22c0604c3 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -10158,6 +10158,14 @@ s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
return const0_rtx;
}
+/* We call mcount before the function prologue. So a profiled leaf
+ function should stay a leaf function. */
+
+static bool
+s390_keep_leaf_when_profiled ()
+{
+ return true;
+}
/* Output assembly code for the trampoline template to
stdio stream FILE.
@@ -12161,6 +12169,9 @@ s390_option_override (void)
#undef TARGET_LIBCALL_VALUE
#define TARGET_LIBCALL_VALUE s390_libcall_value
+#undef TARGET_KEEP_LEAF_WHEN_PROFILED
+#define TARGET_KEEP_LEAF_WHEN_PROFILED s390_keep_leaf_when_profiled
+
#undef TARGET_FIXED_CONDITION_CODE_REGS
#define TARGET_FIXED_CONDITION_CODE_REGS s390_fixed_condition_code_regs
diff --git a/gcc/config/sh/sh-mem.cc b/gcc/config/sh/sh-mem.cc
index 1b84f9b63b7..0e38913b929 100644
--- a/gcc/config/sh/sh-mem.cc
+++ b/gcc/config/sh/sh-mem.cc
@@ -179,8 +179,8 @@ expand_block_move (rtx *operands)
return false;
}
-static int prob_unlikely = REG_BR_PROB_BASE / 10;
-static int prob_likely = REG_BR_PROB_BASE / 4;
+static const int prob_unlikely = REG_BR_PROB_BASE / 10;
+static const int prob_likely = REG_BR_PROB_BASE / 4;
/* Emit code to perform a strcmp.
@@ -226,7 +226,7 @@ sh_expand_cmpstr (rtx *operands)
emit_move_insn (tmp3, addr2);
emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr, 4));
- /*start long loop. */
+ /* start long loop. */
emit_label (L_loop_long);
emit_move_insn (tmp2, tmp3);
@@ -335,7 +335,7 @@ sh_expand_cmpnstr (rtx *operands)
rtx len = force_reg (SImode, operands[3]);
int constp = CONST_INT_P (operands[3]);
- /* Loop on a register count. */
+ /* Loop on a register count. */
if (constp)
{
rtx tmp0 = gen_reg_rtx (SImode);
@@ -350,134 +350,134 @@ sh_expand_cmpnstr (rtx *operands)
int witers = bytes / 4;
if (witers > 1)
- {
- addr1 = adjust_automodify_address (addr1, SImode, s1_addr, 0);
- addr2 = adjust_automodify_address (addr2, SImode, s2_addr, 0);
-
- emit_move_insn (tmp0, const0_rtx);
-
- if (align < 4)
- {
- emit_insn (gen_iorsi3 (tmp1, s1_addr, s2_addr));
- emit_insn (gen_tstsi_t (GEN_INT (3), tmp1));
- jump = emit_jump_insn (gen_branch_false (L_loop_byte));
- add_int_reg_note (jump, REG_BR_PROB, prob_likely);
- }
-
- /* word count. Do we have iterations ? */
- emit_insn (gen_lshrsi3 (lenw, len, GEN_INT (2)));
-
- /*start long loop. */
- emit_label (L_loop_long);
-
- /* tmp2 is aligned, OK to load. */
- emit_move_insn (tmp2, addr2);
- emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr,
- GET_MODE_SIZE (SImode)));
-
- /* tmp1 is aligned, OK to load. */
- emit_move_insn (tmp1, addr1);
- emit_move_insn (s1_addr, plus_constant (Pmode, s1_addr,
- GET_MODE_SIZE (SImode)));
-
- /* Is there a 0 byte ? */
- emit_insn (gen_andsi3 (tmp3, tmp2, tmp1));
-
- emit_insn (gen_cmpstr_t (tmp0, tmp3));
- jump = emit_jump_insn (gen_branch_true (L_end_loop_long));
- add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
-
- emit_insn (gen_cmpeqsi_t (tmp1, tmp2));
- jump = emit_jump_insn (gen_branch_false (L_end_loop_long));
- add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
-
- if (TARGET_SH2)
- emit_insn (gen_dect (lenw, lenw));
- else
- {
- emit_insn (gen_addsi3 (lenw, lenw, GEN_INT (-1)));
- emit_insn (gen_tstsi_t (lenw, lenw));
- }
-
- jump = emit_jump_insn (gen_branch_false (L_loop_long));
- add_int_reg_note (jump, REG_BR_PROB, prob_likely);
-
- int sbytes = bytes % 4;
-
- /* end loop. Reached max iterations. */
- if (! sbytes)
- {
- jump = emit_jump_insn (gen_jump_compact (L_return));
- emit_barrier_after (jump);
- }
- else
- {
- /* Remaining bytes to check. */
-
- addr1 = adjust_automodify_address (addr1, QImode, s1_addr, 0);
- addr2 = adjust_automodify_address (addr2, QImode, s2_addr, 0);
-
- while (sbytes--)
- {
- emit_insn (gen_extendqisi2 (tmp1, addr1));
- emit_insn (gen_extendqisi2 (tmp2, addr2));
-
- emit_insn (gen_cmpeqsi_t (tmp2, const0_rtx));
- jump = emit_jump_insn (gen_branch_true (L_end_loop_byte));
- add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
-
- emit_insn (gen_cmpeqsi_t (tmp1, tmp2));
- if (flag_delayed_branch)
- emit_insn (gen_zero_extendqisi2 (tmp2,
- gen_lowpart (QImode,
- tmp2)));
- jump = emit_jump_insn (gen_branch_false (L_end_loop_byte));
- add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
-
- addr1 = adjust_address (addr1, QImode,
- GET_MODE_SIZE (QImode));
- addr2 = adjust_address (addr2, QImode,
- GET_MODE_SIZE (QImode));
- }
-
- jump = emit_jump_insn (gen_jump_compact( L_end_loop_byte));
- emit_barrier_after (jump);
- }
-
- emit_label (L_end_loop_long);
-
- /* Found last word. Restart it byte per byte. */
-
- emit_move_insn (s1_addr, plus_constant (Pmode, s1_addr,
- -GET_MODE_SIZE (SImode)));
- emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr,
- -GET_MODE_SIZE (SImode)));
-
- /* fall thru. */
- }
+ {
+ addr1 = adjust_automodify_address (addr1, SImode, s1_addr, 0);
+ addr2 = adjust_automodify_address (addr2, SImode, s2_addr, 0);
+
+ emit_move_insn (tmp0, const0_rtx);
+
+ if (align < 4)
+ {
+ emit_insn (gen_iorsi3 (tmp1, s1_addr, s2_addr));
+ emit_insn (gen_tstsi_t (GEN_INT (3), tmp1));
+ jump = emit_jump_insn (gen_branch_false (L_loop_byte));
+ add_int_reg_note (jump, REG_BR_PROB, prob_likely);
+ }
+
+ /* word count. Do we have iterations ? */
+ emit_insn (gen_lshrsi3 (lenw, len, GEN_INT (2)));
+
+ /* start long loop. */
+ emit_label (L_loop_long);
+
+ /* tmp2 is aligned, OK to load. */
+ emit_move_insn (tmp2, addr2);
+ emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr,
+ GET_MODE_SIZE (SImode)));
+
+ /* tmp1 is aligned, OK to load. */
+ emit_move_insn (tmp1, addr1);
+ emit_move_insn (s1_addr, plus_constant (Pmode, s1_addr,
+ GET_MODE_SIZE (SImode)));
+
+ /* Is there a 0 byte ? */
+ emit_insn (gen_andsi3 (tmp3, tmp2, tmp1));
+
+ emit_insn (gen_cmpstr_t (tmp0, tmp3));
+ jump = emit_jump_insn (gen_branch_true (L_end_loop_long));
+ add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
+
+ emit_insn (gen_cmpeqsi_t (tmp1, tmp2));
+ jump = emit_jump_insn (gen_branch_false (L_end_loop_long));
+ add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
+
+ if (TARGET_SH2)
+ emit_insn (gen_dect (lenw, lenw));
+ else
+ {
+ emit_insn (gen_addsi3 (lenw, lenw, GEN_INT (-1)));
+ emit_insn (gen_tstsi_t (lenw, lenw));
+ }
+
+ jump = emit_jump_insn (gen_branch_false (L_loop_long));
+ add_int_reg_note (jump, REG_BR_PROB, prob_likely);
+
+ int sbytes = bytes % 4;
+
+ /* end loop. Reached max iterations. */
+ if (sbytes == 0)
+ {
+ jump = emit_jump_insn (gen_jump_compact (L_return));
+ emit_barrier_after (jump);
+ }
+ else
+ {
+ /* Remaining bytes to check. */
+
+ addr1 = adjust_automodify_address (addr1, QImode, s1_addr, 0);
+ addr2 = adjust_automodify_address (addr2, QImode, s2_addr, 0);
+
+ while (sbytes--)
+ {
+ emit_insn (gen_extendqisi2 (tmp1, addr1));
+ emit_insn (gen_extendqisi2 (tmp2, addr2));
+
+ emit_insn (gen_cmpeqsi_t (tmp2, const0_rtx));
+ jump = emit_jump_insn (gen_branch_true (L_end_loop_byte));
+ add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
+
+ emit_insn (gen_cmpeqsi_t (tmp1, tmp2));
+ if (flag_delayed_branch)
+ emit_insn (gen_zero_extendqisi2 (tmp2,
+ gen_lowpart (QImode,
+ tmp2)));
+ jump = emit_jump_insn (gen_branch_false (L_end_loop_byte));
+ add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
+
+ addr1 = adjust_address (addr1, QImode,
+ GET_MODE_SIZE (QImode));
+ addr2 = adjust_address (addr2, QImode,
+ GET_MODE_SIZE (QImode));
+ }
+
+ jump = emit_jump_insn (gen_jump_compact( L_end_loop_byte));
+ emit_barrier_after (jump);
+ }
+
+ emit_label (L_end_loop_long);
+
+ /* Found last word. Restart it byte per byte. */
+
+ emit_move_insn (s1_addr, plus_constant (Pmode, s1_addr,
+ -GET_MODE_SIZE (SImode)));
+ emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr,
+ -GET_MODE_SIZE (SImode)));
+
+ /* fall thru. */
+ }
addr1 = adjust_automodify_address (addr1, QImode, s1_addr, 0);
addr2 = adjust_automodify_address (addr2, QImode, s2_addr, 0);
while (bytes--)
- {
- emit_insn (gen_extendqisi2 (tmp1, addr1));
- emit_insn (gen_extendqisi2 (tmp2, addr2));
-
- emit_insn (gen_cmpeqsi_t (tmp2, const0_rtx));
- jump = emit_jump_insn (gen_branch_true (L_end_loop_byte));
- add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
-
- emit_insn (gen_cmpeqsi_t (tmp1, tmp2));
- if (flag_delayed_branch)
- emit_insn (gen_zero_extendqisi2 (tmp2,
- gen_lowpart (QImode, tmp2)));
- jump = emit_jump_insn (gen_branch_false (L_end_loop_byte));
- add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
-
- addr1 = adjust_address (addr1, QImode, GET_MODE_SIZE (QImode));
- addr2 = adjust_address (addr2, QImode, GET_MODE_SIZE (QImode));
- }
+ {
+ emit_insn (gen_extendqisi2 (tmp1, addr1));
+ emit_insn (gen_extendqisi2 (tmp2, addr2));
+
+ emit_insn (gen_cmpeqsi_t (tmp2, const0_rtx));
+ jump = emit_jump_insn (gen_branch_true (L_end_loop_byte));
+ add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
+
+ emit_insn (gen_cmpeqsi_t (tmp1, tmp2));
+ if (flag_delayed_branch)
+ emit_insn (gen_zero_extendqisi2 (tmp2,
+ gen_lowpart (QImode, tmp2)));
+ jump = emit_jump_insn (gen_branch_false (L_end_loop_byte));
+ add_int_reg_note (jump, REG_BR_PROB, prob_unlikely);
+
+ addr1 = adjust_address (addr1, QImode, GET_MODE_SIZE (QImode));
+ addr2 = adjust_address (addr2, QImode, GET_MODE_SIZE (QImode));
+ }
jump = emit_jump_insn (gen_jump_compact( L_end_loop_byte));
emit_barrier_after (jump);
@@ -529,7 +529,7 @@ sh_expand_cmpnstr (rtx *operands)
return true;
}
-/* Emit code to perform a strlen
+/* Emit code to perform a strlen.
OPERANDS[0] is the destination.
OPERANDS[1] is the string.
@@ -635,7 +635,7 @@ sh_expand_strlen (rtx *operands)
return true;
}
-/* Emit code to perform a memset
+/* Emit code to perform a memset.
OPERANDS[0] is the destination.
OPERANDS[1] is the size;
@@ -652,13 +652,12 @@ sh_expand_setmem (rtx *operands)
rtx dest_addr = copy_addr_to_reg (XEXP (dest, 0));
rtx val = force_reg (SImode, operands[2]);
int align = INTVAL (operands[3]);
- int count = 0;
rtx len = force_reg (SImode, operands[1]);
if (! CONST_INT_P (operands[1]))
return;
- count = INTVAL (operands[1]);
+ int count = INTVAL (operands[1]);
if (CONST_INT_P (operands[2])
&& (INTVAL (operands[2]) == 0 || INTVAL (operands[2]) == -1) && count > 8)
@@ -666,13 +665,13 @@ sh_expand_setmem (rtx *operands)
rtx lenw = gen_reg_rtx (SImode);
if (align < 4)
- {
- emit_insn (gen_tstsi_t (GEN_INT (3), dest_addr));
- jump = emit_jump_insn (gen_branch_false (L_loop_byte));
- add_int_reg_note (jump, REG_BR_PROB, prob_likely);
- }
+ {
+ emit_insn (gen_tstsi_t (GEN_INT (3), dest_addr));
+ jump = emit_jump_insn (gen_branch_false (L_loop_byte));
+ add_int_reg_note (jump, REG_BR_PROB, prob_likely);
+ }
- /* word count. Do we have iterations ? */
+ /* word count. Do we have iterations ? */
emit_insn (gen_lshrsi3 (lenw, len, GEN_INT (2)));
dest = adjust_automodify_address (dest, SImode, dest_addr, 0);
@@ -683,14 +682,14 @@ sh_expand_setmem (rtx *operands)
if (TARGET_SH2)
emit_insn (gen_dect (lenw, lenw));
else
- {
- emit_insn (gen_addsi3 (lenw, lenw, GEN_INT (-1)));
- emit_insn (gen_tstsi_t (lenw, lenw));
- }
+ {
+ emit_insn (gen_addsi3 (lenw, lenw, GEN_INT (-1)));
+ emit_insn (gen_tstsi_t (lenw, lenw));
+ }
emit_move_insn (dest, val);
emit_move_insn (dest_addr, plus_constant (Pmode, dest_addr,
- GET_MODE_SIZE (SImode)));
+ GET_MODE_SIZE (SImode)));
jump = emit_jump_insn (gen_branch_false (L_loop_word));
@@ -702,11 +701,11 @@ sh_expand_setmem (rtx *operands)
val = gen_lowpart (QImode, val);
while (count--)
- {
- emit_move_insn (dest, val);
- emit_move_insn (dest_addr, plus_constant (Pmode, dest_addr,
- GET_MODE_SIZE (QImode)));
- }
+ {
+ emit_move_insn (dest, val);
+ emit_move_insn (dest_addr, plus_constant (Pmode, dest_addr,
+ GET_MODE_SIZE (QImode)));
+ }
jump = emit_jump_insn (gen_jump_compact (L_return));
emit_barrier_after (jump);
@@ -734,6 +733,4 @@ sh_expand_setmem (rtx *operands)
add_int_reg_note (jump, REG_BR_PROB, prob_likely);
emit_label (L_return);
-
- return;
}
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 6d909c79ef7..26a5d79f137 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -19,6 +19,10 @@ 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 <sstream>
+#include <vector>
+#include <algorithm>
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
@@ -70,10 +74,6 @@ along with GCC; see the file COPYING3. If not see
#include "pass_manager.h"
#include "context.h"
-#include <sstream>
-#include <vector>
-#include <algorithm>
-
int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch;
/* These are some macros to abstract register modes. */
@@ -8809,6 +8809,54 @@ sh_callee_copies (cumulative_args_t cum, enum machine_mode mode,
% SH_MIN_ALIGN_FOR_CALLEE_COPY == 0));
}
+/* Round a register number up to a proper boundary for an arg of mode
+ MODE.
+ The SH doesn't care about double alignment, so we only
+ round doubles to even regs when asked to explicitly. */
+static int
+sh_round_reg (const CUMULATIVE_ARGS& cum, machine_mode mode)
+{
+ /* FIXME: This used to be a macro and has been copy pasted into this
+ function as is. Make this more readable. */
+ return
+ (((TARGET_ALIGN_DOUBLE
+ || ((TARGET_SH4 || TARGET_SH2A_DOUBLE)
+ && (mode == DFmode || mode == DCmode)
+ && cum.arg_count[(int) SH_ARG_FLOAT] < NPARM_REGS (mode)))
+ && GET_MODE_UNIT_SIZE (mode) > UNITS_PER_WORD)
+ ? (cum.arg_count[(int) GET_SH_ARG_CLASS (mode)]
+ + (cum.arg_count[(int) GET_SH_ARG_CLASS (mode)] & 1))
+ : cum.arg_count[(int) GET_SH_ARG_CLASS (mode)]);
+}
+
+/* Return true if arg of the specified mode should be be passed in a register
+ or false otherwise. */
+static bool
+sh_pass_in_reg_p (const CUMULATIVE_ARGS& cum, machine_mode mode,
+ const_tree type)
+{
+ /* FIXME: This used to be a macro and has been copy pasted into this
+ function as is. Make this more readable. */
+ return
+ ((type == 0
+ || (! TREE_ADDRESSABLE (type)
+ && (! (TARGET_HITACHI || cum.renesas_abi)
+ || ! (AGGREGATE_TYPE_P (type)
+ || (!TARGET_FPU_ANY
+ && (GET_MODE_CLASS (mode) == MODE_FLOAT
+ && GET_MODE_SIZE (mode) > GET_MODE_SIZE (SFmode)))))))
+ && ! cum.force_mem
+ && (TARGET_SH2E
+ ? ((mode) == BLKmode
+ ? ((cum.arg_count[(int) SH_ARG_INT] * UNITS_PER_WORD
+ + int_size_in_bytes (type))
+ <= NPARM_REGS (SImode) * UNITS_PER_WORD)
+ : ((sh_round_reg (cum, mode)
+ + HARD_REGNO_NREGS (BASE_ARG_REG (mode), mode))
+ <= NPARM_REGS (mode)))
+ : sh_round_reg (cum, mode) < NPARM_REGS (mode)));
+}
+
static int
sh_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
tree type, bool named ATTRIBUTE_UNUSED)
@@ -8817,14 +8865,14 @@ sh_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode,
int words = 0;
if (!TARGET_SH5
- && PASS_IN_REG_P (*cum, mode, type)
+ && sh_pass_in_reg_p (*cum, mode, type)
&& !(TARGET_SH4 || TARGET_SH2A_DOUBLE)
- && (ROUND_REG (*cum, mode)
+ && (sh_round_reg (*cum, mode)
+ (mode != BLKmode
- ? ROUND_ADVANCE (GET_MODE_SIZE (mode))
- : ROUND_ADVANCE (int_size_in_bytes (type)))
+ ? CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD)
+ : CEIL (int_size_in_bytes (type), UNITS_PER_WORD))
> NPARM_REGS (mode)))
- words = NPARM_REGS (mode) - ROUND_REG (*cum, mode);
+ words = NPARM_REGS (mode) - sh_round_reg (*cum, mode);
else if (!TARGET_SHCOMPACT
&& SH5_WOULD_BE_PARTIAL_NREGS (*cum, mode, type, named))
@@ -8861,23 +8909,23 @@ sh_function_arg (cumulative_args_t ca_v, enum machine_mode mode,
return GEN_INT (ca->renesas_abi ? 1 : 0);
if (! TARGET_SH5
- && PASS_IN_REG_P (*ca, mode, type)
+ && sh_pass_in_reg_p (*ca, mode, type)
&& (named || ! (TARGET_HITACHI || ca->renesas_abi)))
{
int regno;
if (mode == SCmode && TARGET_SH4 && TARGET_LITTLE_ENDIAN
- && (! FUNCTION_ARG_SCmode_WART || (ROUND_REG (*ca, mode) & 1)))
+ && (! FUNCTION_ARG_SCmode_WART || (sh_round_reg (*ca, mode) & 1)))
{
rtx r1 = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (SFmode,
BASE_ARG_REG (mode)
- + (ROUND_REG (*ca, mode) ^ 1)),
+ + (sh_round_reg (*ca, mode) ^ 1)),
const0_rtx);
rtx r2 = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (SFmode,
BASE_ARG_REG (mode)
- + ((ROUND_REG (*ca, mode) + 1) ^ 1)),
+ + ((sh_round_reg (*ca, mode) + 1) ^ 1)),
GEN_INT (4));
return gen_rtx_PARALLEL(SCmode, gen_rtvec(2, r1, r2));
}
@@ -8890,7 +8938,7 @@ sh_function_arg (cumulative_args_t ca_v, enum machine_mode mode,
&& mode == SFmode)
return gen_rtx_REG (mode, ca->free_single_fp_reg);
- regno = (BASE_ARG_REG (mode) + ROUND_REG (*ca, mode))
+ regno = (BASE_ARG_REG (mode) + sh_round_reg (*ca, mode))
^ (mode == SFmode && TARGET_SH4
&& TARGET_LITTLE_ENDIAN
&& ! TARGET_HITACHI && ! ca->renesas_abi);
@@ -9070,20 +9118,20 @@ sh_function_arg_advance (cumulative_args_t ca_v, enum machine_mode mode,
register, because the next SF value will use it, and not the
SF that follows the DF. */
if (mode == DFmode
- && ROUND_REG (*ca, DFmode) != ROUND_REG (*ca, SFmode))
+ && sh_round_reg (*ca, DFmode) != sh_round_reg (*ca, SFmode))
{
- ca->free_single_fp_reg = (ROUND_REG (*ca, SFmode)
+ ca->free_single_fp_reg = (sh_round_reg (*ca, SFmode)
+ BASE_ARG_REG (mode));
}
}
if (! ((TARGET_SH4 || TARGET_SH2A) || ca->renesas_abi)
- || PASS_IN_REG_P (*ca, mode, type))
+ || sh_pass_in_reg_p (*ca, mode, type))
(ca->arg_count[(int) GET_SH_ARG_CLASS (mode)]
- = (ROUND_REG (*ca, mode)
+ = (sh_round_reg (*ca, mode)
+ (mode == BLKmode
- ? ROUND_ADVANCE (int_size_in_bytes (type))
- : ROUND_ADVANCE (GET_MODE_SIZE (mode)))));
+ ? CEIL (int_size_in_bytes (type), UNITS_PER_WORD)
+ : CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD))));
}
/* The Renesas calling convention doesn't quite fit into this scheme since
@@ -9178,10 +9226,10 @@ sh_setup_incoming_varargs (cumulative_args_t ca,
{
int named_parm_regs, anon_parm_regs;
- named_parm_regs = (ROUND_REG (*get_cumulative_args (ca), mode)
+ named_parm_regs = (sh_round_reg (*get_cumulative_args (ca), mode)
+ (mode == BLKmode
- ? ROUND_ADVANCE (int_size_in_bytes (type))
- : ROUND_ADVANCE (GET_MODE_SIZE (mode))));
+ ? CEIL (int_size_in_bytes (type), UNITS_PER_WORD)
+ : CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD)));
anon_parm_regs = NPARM_REGS (SImode) - named_parm_regs;
if (anon_parm_regs > 0)
*pretend_arg_size = anon_parm_regs * 4;
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 8c30e5c14bd..00ee0edffda 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -267,9 +267,25 @@ extern int code_for_indirect_jump_scratch;
#define SUBTARGET_ASM_RELAX_SPEC "%{m4*:-isa=sh4-up}"
#endif
+/* Define which ISA type to pass to the assembler.
+ For SH4 we pass SH4A to allow using some instructions that are available
+ on some SH4 variants, but officially are part of the SH4A ISA. */
#define SH_ASM_SPEC \
"%(subtarget_asm_endian_spec) %{mrelax:-relax %(subtarget_asm_relax_spec)} \
%(subtarget_asm_isa_spec) %(subtarget_asm_spec) \
+%{m1:--isa=sh} \
+%{m2:--isa=sh2} \
+%{m2e:--isa=sh2e} \
+%{m3:--isa=sh3} \
+%{m3e:--isa=sh3e} \
+%{m4:--isa=sh4a} \
+%{m4-single:--isa=sh4a} \
+%{m4-single-only:--isa=sh4a} \
+%{m4-nofpu:--isa=sh4a-nofpu} \
+%{m4a:--isa=sh4a} \
+%{m4a-single:--isa=sh4a} \
+%{m4a-single-only:--isa=sh4a} \
+%{m4a-nofpu:--isa=sh4a-nofpu} \
%{m2a:--isa=sh2a} \
%{m2a-single:--isa=sh2a} \
%{m2a-single-only:--isa=sh2a} \
@@ -1361,24 +1377,6 @@ struct sh_args {
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
? SH_ARG_FLOAT : SH_ARG_INT)
-#define ROUND_ADVANCE(SIZE) \
- (((SIZE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
-/* Round a register number up to a proper boundary for an arg of mode
- MODE.
-
- The SH doesn't care about double alignment, so we only
- round doubles to even regs when asked to explicitly. */
-#define ROUND_REG(CUM, MODE) \
- (((TARGET_ALIGN_DOUBLE \
- || ((TARGET_SH4 || TARGET_SH2A_DOUBLE) \
- && ((MODE) == DFmode || (MODE) == DCmode) \
- && (CUM).arg_count[(int) SH_ARG_FLOAT] < NPARM_REGS (MODE))) \
- && GET_MODE_UNIT_SIZE ((MODE)) > UNITS_PER_WORD) \
- ? ((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)] \
- + ((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)] & 1)) \
- : (CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)])
-
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0.
@@ -1394,27 +1392,6 @@ struct sh_args {
#define INIT_CUMULATIVE_LIBCALL_ARGS(CUM, MODE, LIBNAME) \
sh_init_cumulative_args (& (CUM), NULL_TREE, (LIBNAME), NULL_TREE, 0, (MODE))
-/* Return boolean indicating arg of mode MODE will be passed in a reg.
- This macro is only used in this file. */
-#define PASS_IN_REG_P(CUM, MODE, TYPE) \
- (((TYPE) == 0 \
- || (! TREE_ADDRESSABLE ((TYPE)) \
- && (! (TARGET_HITACHI || (CUM).renesas_abi) \
- || ! (AGGREGATE_TYPE_P (TYPE) \
- || (!TARGET_FPU_ANY \
- && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- && GET_MODE_SIZE (MODE) > GET_MODE_SIZE (SFmode))))))) \
- && ! (CUM).force_mem \
- && (TARGET_SH2E \
- ? ((MODE) == BLKmode \
- ? (((CUM).arg_count[(int) SH_ARG_INT] * UNITS_PER_WORD \
- + int_size_in_bytes (TYPE)) \
- <= NPARM_REGS (SImode) * UNITS_PER_WORD) \
- : ((ROUND_REG((CUM), (MODE)) \
- + HARD_REGNO_NREGS (BASE_ARG_REG (MODE), (MODE))) \
- <= NPARM_REGS (MODE))) \
- : ROUND_REG ((CUM), (MODE)) < NPARM_REGS (MODE)))
-
/* By accident we got stuck with passing SCmode on SH4 little endian
in two registers that are nominally successive - which is different from
two single SFmode values, where we take endianness translation into
diff --git a/gcc/config/sh/sh_optimize_sett_clrt.cc b/gcc/config/sh/sh_optimize_sett_clrt.cc
index 5b1afcd961b..84ad2999de7 100644
--- a/gcc/config/sh/sh_optimize_sett_clrt.cc
+++ b/gcc/config/sh/sh_optimize_sett_clrt.cc
@@ -79,8 +79,8 @@ class sh_optimize_sett_clrt : public rtl_opt_pass
public:
sh_optimize_sett_clrt (gcc::context* ctx, const char* name);
virtual ~sh_optimize_sett_clrt (void);
- virtual bool gate (function *);
- virtual unsigned int execute (void);
+ virtual bool gate (function*);
+ virtual unsigned int execute (function* fun);
private:
static const pass_data default_pass_data;
@@ -161,13 +161,13 @@ sh_optimize_sett_clrt::~sh_optimize_sett_clrt (void)
}
bool
-sh_optimize_sett_clrt::gate (function *)
+sh_optimize_sett_clrt::gate (function*)
{
return optimize > 0;
}
unsigned int
-sh_optimize_sett_clrt::execute (void)
+sh_optimize_sett_clrt::execute (function* fun)
{
unsigned int ccr0 = INVALID_REGNUM;
unsigned int ccr1 = INVALID_REGNUM;
@@ -205,7 +205,7 @@ sh_optimize_sett_clrt::execute (void)
// Look for insns that set the ccreg to a constant value and see if it can
// be optimized.
basic_block bb;
- FOR_EACH_BB_REVERSE_FN (bb, cfun)
+ FOR_EACH_BB_REVERSE_FN (bb, fun)
for (rtx next_i, i = NEXT_INSN (BB_HEAD (bb));
i != NULL_RTX && i != BB_END (bb); i = next_i)
{
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c078e0685cc..374cd0f6a5e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,35 @@
+2014-05-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58582
+ * decl.c (grokfndecl): Check duplicate_decls return value for
+ error_mark_node.
+ * pt.c (instantiate_decl): A deleted function is defined.
+
+2014-05-02 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (vague_linkage_p): Local statics have vague linkage.
+
+ PR c++/60992
+ * lambda.c (lambda_capture_field_type): Wrap anything dependent
+ other than 'this'.
+ (add_capture): Check for VLA before calling it.
+ * semantics.c (is_this_parameter): Accept any 'this' parameter, not
+ just the current one. Make non-static.
+ * cp-tree.h: Declare it.
+ * pt.c (tsubst_copy) [VAR_DECL]: Also build a new VAR_DECL if
+ the operand was static or constant.
+
+2014-05-02 Marek Polacek <polacek@redhat.com>
+
+ * typeck.c (maybe_warn_about_returning_address_of_local): Separate
+ warning_at calls.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/43395
+ * typeck.c (maybe_warn_about_returning_address_of_local): Distinguish
+ between label and variable when warning about returning local address.
+
2014-04-30 Jason Merrill <jason@redhat.com>
PR c++/60980
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 55ecc4e5b5f..34d3d203336 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5773,6 +5773,7 @@ extern bool is_sub_constant_expr (tree);
extern bool reduced_constant_expression_p (tree);
extern void explain_invalid_constexpr_fn (tree);
extern vec<tree> cx_error_context (void);
+extern bool is_this_parameter (tree);
enum {
BCS_NO_SCOPE = 1,
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index bfd5395128a..01a36252b2e 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7823,6 +7823,8 @@ grokfndecl (tree ctype,
decl, ctype);
return NULL_TREE;
}
+ if (ok == error_mark_node)
+ return NULL_TREE;
return old_decl;
}
}
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 918ea2fc6d0..71402181af6 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1804,12 +1804,19 @@ vague_linkage_p (tree decl)
/* Unfortunately, import_export_decl has not always been called
before the function is processed, so we cannot simply check
DECL_COMDAT. */
- return (DECL_COMDAT (decl)
- || (((TREE_CODE (decl) == FUNCTION_DECL
- && DECL_DECLARED_INLINE_P (decl))
- || (DECL_LANG_SPECIFIC (decl)
- && DECL_TEMPLATE_INSTANTIATION (decl)))
- && TREE_PUBLIC (decl)));
+ if (DECL_COMDAT (decl)
+ || (((TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DECLARED_INLINE_P (decl))
+ || (DECL_LANG_SPECIFIC (decl)
+ && DECL_TEMPLATE_INSTANTIATION (decl)))
+ && TREE_PUBLIC (decl)))
+ return true;
+ else if (DECL_FUNCTION_SCOPE_P (decl))
+ /* A local static in an inline effectively has vague linkage. */
+ return (TREE_STATIC (decl)
+ && vague_linkage_p (DECL_CONTEXT (decl)));
+ else
+ return false;
}
/* Determine whether or not we want to specifically import or export CTYPE,
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 0b8b46a8144..5ba6f141b72 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -216,8 +216,8 @@ lambda_capture_field_type (tree expr, bool explicit_init_p)
}
else
type = non_reference (unlowered_expr_type (expr));
- if (!type || WILDCARD_TYPE_P (type) || type_uses_auto (type)
- || DECL_PACK_P (expr))
+ if (type_dependent_expression_p (expr)
+ && !is_this_parameter (tree_strip_nop_conversions (expr)))
{
type = cxx_make_type (DECLTYPE_TYPE);
DECLTYPE_TYPE_EXPR (type) = expr;
@@ -455,7 +455,7 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
if (TREE_CODE (initializer) == TREE_LIST)
initializer = build_x_compound_expr_from_list (initializer, ELK_INIT,
tf_warning_or_error);
- type = lambda_capture_field_type (initializer, explicit_init_p);
+ type = TREE_TYPE (initializer);
if (array_of_runtime_bound_p (type))
{
vla = true;
@@ -482,15 +482,19 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
"variable size", TREE_TYPE (type));
type = error_mark_node;
}
- else if (by_reference_p)
+ else
{
- type = build_reference_type (type);
- if (!real_lvalue_p (initializer))
- error ("cannot capture %qE by reference", initializer);
+ type = lambda_capture_field_type (initializer, explicit_init_p);
+ if (by_reference_p)
+ {
+ type = build_reference_type (type);
+ if (!real_lvalue_p (initializer))
+ error ("cannot capture %qE by reference", initializer);
+ }
+ else
+ /* Capture by copy requires a complete type. */
+ type = complete_type (type);
}
- else
- /* Capture by copy requires a complete type. */
- type = complete_type (type);
/* Add __ to the beginning of the field name so that user code
won't find the field with name lookup. We can't just leave the name
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 48cc2a9e9cf..7e7f6d89f0d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -12629,13 +12629,17 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
}
else
{
- /* This can happen for a variable used in a late-specified
- return type of a local lambda. Just make a dummy decl
- since it's only used for its type. */
- if (cp_unevaluated_operand)
- return tsubst_decl (t, args, complain);
- gcc_assert (errorcount || sorrycount);
- return error_mark_node;
+ /* This can happen for a variable used in a
+ late-specified return type of a local lambda, or for a
+ local static or constant. Building a new VAR_DECL
+ should be OK in all those cases. */
+ r = tsubst_decl (t, args, complain);
+ if (decl_constant_var_p (r))
+ /* A use of a local constant must decay to its value. */
+ return integral_constant_value (r);
+ gcc_assert (cp_unevaluated_operand || TREE_STATIC (r)
+ || errorcount || sorrycount);
+ return r;
}
}
}
@@ -19616,7 +19620,8 @@ instantiate_decl (tree d, int defer_ok,
if (TREE_CODE (d) == FUNCTION_DECL)
pattern_defined = (DECL_SAVED_TREE (code_pattern) != NULL_TREE
- || DECL_DEFAULTED_OUTSIDE_CLASS_P (code_pattern));
+ || DECL_DEFAULTED_OUTSIDE_CLASS_P (code_pattern)
+ || DECL_DELETED_FN (code_pattern));
else
pattern_defined = ! DECL_IN_AGGR_P (code_pattern);
@@ -19858,14 +19863,17 @@ instantiate_decl (tree d, int defer_ok,
tf_warning_or_error, tmpl,
/*integral_constant_expression_p=*/false);
- /* Set the current input_location to the end of the function
- so that finish_function knows where we are. */
- input_location
- = DECL_STRUCT_FUNCTION (code_pattern)->function_end_locus;
-
- /* Remember if we saw an infinite loop in the template. */
- current_function_infinite_loop
- = DECL_STRUCT_FUNCTION (code_pattern)->language->infinite_loop;
+ if (DECL_STRUCT_FUNCTION (code_pattern))
+ {
+ /* Set the current input_location to the end of the function
+ so that finish_function knows where we are. */
+ input_location
+ = DECL_STRUCT_FUNCTION (code_pattern)->function_end_locus;
+
+ /* Remember if we saw an infinite loop in the template. */
+ current_function_infinite_loop
+ = DECL_STRUCT_FUNCTION (code_pattern)->language->infinite_loop;
+ }
}
/* We don't need the local specializations any more. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 3f8ca44904e..4afb821de06 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -8155,10 +8155,11 @@ maybe_initialize_constexpr_call_table (void)
/* Return true if T designates the implied `this' parameter. */
-static inline bool
+bool
is_this_parameter (tree t)
{
- return t == current_class_ptr;
+ return (TREE_CODE (t) == PARM_DECL
+ && DECL_NAME (t) == this_identifier);
}
/* We have an expression tree T that represents a call, either CALL_EXPR
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 729e22eadc5..7b28a9a5869 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -8309,9 +8309,12 @@ maybe_warn_about_returning_address_of_local (tree retval)
if (TREE_CODE (valtype) == REFERENCE_TYPE)
warning (OPT_Wreturn_local_addr, "reference to local variable %q+D returned",
whats_returned);
- else
- warning (OPT_Wreturn_local_addr, "address of local variable %q+D returned",
+ else if (TREE_CODE (whats_returned) == LABEL_DECL)
+ warning (OPT_Wreturn_local_addr, "address of label %q+D returned",
whats_returned);
+ else
+ warning (OPT_Wreturn_local_addr, "address of local variable %q+D "
+ "returned", whats_returned);
return;
}
}
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 5becc455e4c..8d89a751b75 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -1093,6 +1093,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define LOCAL_REGNO(REGNO) 0
#endif
+#ifndef HONOR_REG_ALLOC_ORDER
+#define HONOR_REG_ALLOC_ORDER 0
+#endif
+
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
the stack pointer does not matter. The value is tested only in
functions that have frame pointers. */
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index cc6d405f168..3fe9d5f302c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -242,6 +242,7 @@ Objective-C and Objective-C++ Dialects}.
-Wchar-subscripts -Wclobbered -Wcomment -Wconditionally-supported @gol
-Wconversion -Wcoverage-mismatch -Wdate-time -Wdelete-incomplete -Wno-cpp @gol
-Wno-deprecated -Wno-deprecated-declarations -Wdisabled-optimization @gol
+-Wno-discarded-qualifiers @gol
-Wno-div-by-zero -Wdouble-promotion -Wempty-body -Wenum-compare @gol
-Wno-endif-labels -Werror -Werror=* @gol
-Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol
@@ -4182,6 +4183,15 @@ This option is only active when @option{-ftree-vrp} is active
(default for @option{-O2} and above). It warns about subscripts to arrays
that are always out of bounds. This warning is enabled by @option{-Wall}.
+@item -Wno-discarded-qualifiers
+@opindex Wno-discarded-qualifiers
+@opindex Wdiscarded-qualifiers
+Do not warn if type qualifiers on pointers are being discarded.
+Typically, the compiler will warn if a @code{const char *} variable is
+passed to a function that takes @code{char *} parameter. This option
+can be used to suppress such a warning. This warning is only supported
+for C.
+
@item -Wno-div-by-zero
@opindex Wno-div-by-zero
@opindex Wdiv-by-zero
@@ -5383,6 +5393,14 @@ While @option{-ftrapv} causes traps for signed overflows to be emitted,
@option{-fsanitize=undefined} gives a diagnostic message.
This currently works only for the C family of languages.
+@item -fsanitize=float-divide-by-zero
+@opindex fsanitize=float-divide-by-zero
+
+Detect floating-point division by zero. Unlike other similar options,
+@option{-fsanitize=float-divide-by-zero} is not enabled by
+@option{-fsanitize=undefined}, since floating-point division by zero can
+be a legitimate way of obtaining infinities and NaNs.
+
@item -fsanitize-recover
@opindex fsanitize-recover
By default @option{-fsanitize=undefined} sanitization (and its suboptions
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 46b5cb528d4..e01cbd953f8 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -2044,8 +2044,8 @@ Normally, IRA tries to estimate the costs for saving a register in the
prologue and restoring it in the epilogue. This discourages it from
using call-saved registers. If a machine wants to ensure that IRA
allocates registers in the order given by REG_ALLOC_ORDER even if some
-call-saved registers appear earlier than call-used ones, this macro
-should be defined.
+call-saved registers appear earlier than call-used ones, then define this
+macro as a C expression to nonzero. Default is 0.
@end defmac
@defmac IRA_HARD_REGNO_ADD_COST_MULTIPLIER (@var{regno})
@@ -4953,6 +4953,10 @@ Define this macro if the code for function profiling should come before
the function prologue. Normally, the profiling code comes after.
@end defmac
+@deftypefn {Target Hook} bool TARGET_KEEP_LEAF_WHEN_PROFILED (void)
+This target hook returns true if the target wants the leaf flag for the current function to stay true even if it calls mcount. This might make sense for targets using the leaf flag only to determine whether a stack frame needs to be generated or not and for which the call to mcount is generated before the function prologue.
+@end deftypefn
+
@node Tail Calls
@subsection Permitting tail calls
@cindex tail calls
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index de7aa92df37..bbb032e217f 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -1849,8 +1849,8 @@ Normally, IRA tries to estimate the costs for saving a register in the
prologue and restoring it in the epilogue. This discourages it from
using call-saved registers. If a machine wants to ensure that IRA
allocates registers in the order given by REG_ALLOC_ORDER even if some
-call-saved registers appear earlier than call-used ones, this macro
-should be defined.
+call-saved registers appear earlier than call-used ones, then define this
+macro as a C expression to nonzero. Default is 0.
@end defmac
@defmac IRA_HARD_REGNO_ADD_COST_MULTIPLIER (@var{regno})
@@ -3963,6 +3963,8 @@ Define this macro if the code for function profiling should come before
the function prologue. Normally, the profiling code comes after.
@end defmac
+@hook TARGET_KEEP_LEAF_WHEN_PROFILED
+
@node Tail Calls
@subsection Permitting tail calls
@cindex tail calls
diff --git a/gcc/final.c b/gcc/final.c
index 0497834b977..d3e0bba015e 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -4255,7 +4255,9 @@ leaf_function_p (void)
{
rtx insn;
- if (crtl->profile || profile_arc_flag)
+ /* Some back-ends (e.g. s390) want leaf functions to stay leaf
+ functions even if they call mcount. */
+ if (crtl->profile && !targetm.keep_leaf_when_profiled ())
return 0;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index a67c34d4d39..831aaba683c 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -11334,7 +11334,6 @@ fold_binary_loc (location_t loc,
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
{
int width = TYPE_PRECISION (type), w;
- bool try_simplify = true;
wide_int c1 = TREE_OPERAND (arg0, 1);
wide_int c2 = arg1;
@@ -11368,20 +11367,7 @@ fold_binary_loc (location_t loc,
}
}
- /* If X is a tree of the form (Y * K1) & K2, this might conflict
- with that optimization from the BIT_AND_EXPR optimizations.
- This could end up in an infinite recursion. */
- if (TREE_CODE (TREE_OPERAND (arg0, 0)) == MULT_EXPR
- && TREE_CODE (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1))
- == INTEGER_CST)
- {
- tree t = TREE_OPERAND (TREE_OPERAND (arg0, 0), 1);
- wide_int masked = mask_with_tz (type, c3, t);
-
- try_simplify = (masked != c1);
- }
-
- if (try_simplify && c3 != c1)
+ if (c3 != c1)
return fold_build2_loc (loc, BIT_IOR_EXPR, type,
fold_build2_loc (loc, BIT_AND_EXPR, type,
TREE_OPERAND (arg0, 0),
@@ -11770,14 +11756,23 @@ fold_binary_loc (location_t loc,
&& TREE_CODE (arg0) == MULT_EXPR
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
{
- wide_int masked = mask_with_tz (type, arg1, TREE_OPERAND (arg0, 1));
+ wide_int warg1 = arg1;
+ wide_int masked = mask_with_tz (type, warg1, TREE_OPERAND (arg0, 1));
if (masked == 0)
return omit_two_operands_loc (loc, type, build_zero_cst (type),
arg0, arg1);
- else if (masked != arg1)
- return fold_build2_loc (loc, code, type, op0,
- wide_int_to_tree (type, masked));
+ else if (masked != warg1)
+ {
+ /* Avoid the transform if arg1 is a mask of some
+ mode which allows further optimizations. */
+ int pop = wi::popcount (warg1);
+ if (!(pop >= BITS_PER_UNIT
+ && exact_log2 (pop) != -1
+ && wi::mask (pop, false, warg1.get_precision ()) == warg1))
+ return fold_build2_loc (loc, code, type, op0,
+ wide_int_to_tree (type, masked));
+ }
}
/* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 5cf25134e30..b991dc0b115 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,4 +1,44 @@
-2014-03-27 Thomas Koenig <tkoenig@gcc.gnu.org>
+2014-04-30 Tobias Burnus <burnus@net-b.de>
+
+ * trans-decl.c (create_function_arglist): Add hidden coarray arguments
+ also for polymorphic coarrays.
+ * trans-expr.c (gfc_conv_procedure_call): Pass hidden coarray arguments
+ also for polymorphic coarrays.
+
+2014-04-30 Tobias Burnus <burnus@net-b.de>
+
+ * resolve.c (resolve_function): Don't do
+ assumed-size check for lcobound/ucobound.
+ * trans-types.c (gfc_build_array_type): Only build an array
+ descriptor with codimensions for allocatable coarrays.
+
+2014-04-30 Tobias Burnus <burnus@net-b.de>
+
+ * gfortran.h (gfc_init_coarray_decl): Remove.
+ * parse.c (translate_all_program_units): Remove call to it.
+ (gfc_parse_file): Update call.
+ * trans.h (gfor_fndecl_caf_this_image,
+ gfor_fndecl_caf_num_images): Add.
+ (gfort_gvar_caf_num_images,
+ gfort_gvar_caf_this_image): Remove.
+ * trans-decl.c (gfor_fndecl_caf_this_image,
+ gfor_fndecl_caf_num_images): Add.
+ (gfort_gvar_caf_num_images,
+ gfort_gvar_caf_this_image): Remove.
+ (gfc_build_builtin_function_decls): Init new decl.
+ (gfc_init_coarray_dec): Remove.
+ (create_main_function): Change calls.
+ * trans-intrinsic.c (trans_this_image, trans_image_index,
+ conv_intrinsic_cobound): Generate call to new library function
+ instead of to a static variable.
+ * trans-stmt.c (gfc_trans_sync): Ditto.
+
+2014-04-30 Tobias Burnus <burnus@net-b.de>
+
+ * trans-expr.c (get_tree_for_caf_expr): Fix handling of polymorphic
+ and derived-type coarrays.
+
+2014-04-27 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/59604
PR fortran/58003
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index f0eed809ab8..0707b58bd2b 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -2948,7 +2948,6 @@ bool gfc_convert_to_structure_constructor (gfc_expr *, gfc_symbol *,
/* trans.c */
void gfc_generate_code (gfc_namespace *);
void gfc_generate_module_code (gfc_namespace *);
-void gfc_init_coarray_decl (bool);
/* trans-intrinsic.c */
bool gfc_inline_intrinsic_function_p (gfc_expr *);
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 0faf47a0041..77667150176 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -4495,19 +4495,13 @@ clean_up_modules (gfc_gsymbol *gsym)
/* Translate all the program units. This could be in a different order
to resolution if there are forward references in the file. */
static void
-translate_all_program_units (gfc_namespace *gfc_global_ns_list,
- bool main_in_tu)
+translate_all_program_units (gfc_namespace *gfc_global_ns_list)
{
int errors;
gfc_current_ns = gfc_global_ns_list;
gfc_get_errors (NULL, &errors);
- /* If the main program is in the translation unit and we have
- -fcoarray=libs, generate the static variables. */
- if (gfc_option.coarray == GFC_FCOARRAY_LIB && main_in_tu)
- gfc_init_coarray_decl (true);
-
/* We first translate all modules to make sure that later parts
of the program can use the decl. Then we translate the nonmodules. */
@@ -4729,7 +4723,7 @@ prog_units:
}
/* Do the translation. */
- translate_all_program_units (gfc_global_ns_list, seen_program);
+ translate_all_program_units (gfc_global_ns_list);
gfc_end_source_files ();
return true;
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 38755fef6a2..15c94635f49 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -2942,6 +2942,8 @@ resolve_function (gfc_expr *expr)
else if (expr->value.function.actual != NULL
&& expr->value.function.isym != NULL
&& GENERIC_ID != GFC_ISYM_LBOUND
+ && GENERIC_ID != GFC_ISYM_LCOBOUND
+ && GENERIC_ID != GFC_ISYM_UCOBOUND
&& GENERIC_ID != GFC_ISYM_LEN
&& GENERIC_ID != GFC_ISYM_LOC
&& GENERIC_ID != GFC_ISYM_C_LOC
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 7bf0fb1b57a..bd1ebab46b2 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -121,6 +121,8 @@ tree gfor_fndecl_associated;
/* Coarray run-time library function decls. */
tree gfor_fndecl_caf_init;
tree gfor_fndecl_caf_finalize;
+tree gfor_fndecl_caf_this_image;
+tree gfor_fndecl_caf_num_images;
tree gfor_fndecl_caf_register;
tree gfor_fndecl_caf_deregister;
tree gfor_fndecl_caf_critical;
@@ -130,11 +132,6 @@ tree gfor_fndecl_caf_sync_images;
tree gfor_fndecl_caf_error_stop;
tree gfor_fndecl_caf_error_stop_str;
-/* Coarray global variables for num_images/this_image. */
-
-tree gfort_gvar_caf_num_images;
-tree gfort_gvar_caf_this_image;
-
/* Math functions. Many other math functions are handled in
trans-intrinsic.c. */
@@ -2237,9 +2234,12 @@ create_function_arglist (gfc_symbol * sym)
/* Coarrays which are descriptorless or assumed-shape pass with
-fcoarray=lib the token and the offset as hidden arguments. */
- if (f->sym->attr.codimension
- && gfc_option.coarray == GFC_FCOARRAY_LIB
- && !f->sym->attr.allocatable)
+ if (gfc_option.coarray == GFC_FCOARRAY_LIB
+ && ((f->sym->ts.type != BT_CLASS && f->sym->attr.codimension
+ && !f->sym->attr.allocatable)
+ || (f->sym->ts.type == BT_CLASS
+ && CLASS_DATA (f->sym)->attr.codimension
+ && !CLASS_DATA (f->sym)->attr.allocatable)))
{
tree caf_type;
tree token;
@@ -2247,13 +2247,18 @@ create_function_arglist (gfc_symbol * sym)
gcc_assert (f->sym->backend_decl != NULL_TREE
&& !sym->attr.is_bind_c);
- caf_type = TREE_TYPE (f->sym->backend_decl);
+ caf_type = f->sym->ts.type == BT_CLASS
+ ? TREE_TYPE (CLASS_DATA (f->sym)->backend_decl)
+ : TREE_TYPE (f->sym->backend_decl);
token = build_decl (input_location, PARM_DECL,
create_tmp_var_name ("caf_token"),
build_qualified_type (pvoid_type_node,
TYPE_QUAL_RESTRICT));
- if (f->sym->as->type == AS_ASSUMED_SHAPE)
+ if ((f->sym->ts.type != BT_CLASS
+ && f->sym->as->type != AS_DEFERRED)
+ || (f->sym->ts.type == BT_CLASS
+ && CLASS_DATA (f->sym)->as->type != AS_DEFERRED))
{
gcc_assert (DECL_LANG_SPECIFIC (f->sym->backend_decl) == NULL
|| GFC_DECL_TOKEN (f->sym->backend_decl) == NULL_TREE);
@@ -2278,7 +2283,10 @@ create_function_arglist (gfc_symbol * sym)
create_tmp_var_name ("caf_offset"),
gfc_array_index_type);
- if (f->sym->as->type == AS_ASSUMED_SHAPE)
+ if ((f->sym->ts.type != BT_CLASS
+ && f->sym->as->type != AS_DEFERRED)
+ || (f->sym->ts.type == BT_CLASS
+ && CLASS_DATA (f->sym)->as->type != AS_DEFERRED))
{
gcc_assert (GFC_DECL_CAF_OFFSET (f->sym->backend_decl)
== NULL_TREE);
@@ -3247,6 +3255,14 @@ gfc_build_builtin_function_decls (void)
gfor_fndecl_caf_finalize = gfc_build_library_function_decl (
get_identifier (PREFIX("caf_finalize")), void_type_node, 0);
+ gfor_fndecl_caf_this_image = gfc_build_library_function_decl (
+ get_identifier (PREFIX("caf_this_image")), integer_type_node,
+ 1, integer_type_node);
+
+ gfor_fndecl_caf_num_images = gfc_build_library_function_decl (
+ get_identifier (PREFIX("caf_num_images")), integer_type_node,
+ 2, integer_type_node, boolean_type_node);
+
gfor_fndecl_caf_register = gfc_build_library_function_decl_with_spec (
get_identifier (PREFIX("caf_register")), "...WWW", pvoid_type_node, 6,
size_type_node, integer_type_node, ppvoid_type_node, pint_type,
@@ -5105,59 +5121,6 @@ add_argument_checking (stmtblock_t *block, gfc_symbol *sym)
}
-/* Generate the _gfortran_caf_this_image and _gfortran_caf_num_images
- global variables for -fcoarray=lib. They are placed into the translation
- unit of the main program. Make sure that in one TU (the one of the main
- program), the first call to gfc_init_coarray_decl is done with true.
- Otherwise, expect link errors. */
-
-void
-gfc_init_coarray_decl (bool main_tu)
-{
- if (gfc_option.coarray != GFC_FCOARRAY_LIB)
- return;
-
- if (gfort_gvar_caf_this_image || gfort_gvar_caf_num_images)
- return;
-
- push_cfun (cfun);
-
- gfort_gvar_caf_this_image
- = build_decl (input_location, VAR_DECL,
- get_identifier (PREFIX("caf_this_image")),
- integer_type_node);
- DECL_ARTIFICIAL (gfort_gvar_caf_this_image) = 1;
- TREE_USED (gfort_gvar_caf_this_image) = 1;
- TREE_PUBLIC (gfort_gvar_caf_this_image) = 1;
- TREE_READONLY (gfort_gvar_caf_this_image) = 0;
-
- if (main_tu)
- TREE_STATIC (gfort_gvar_caf_this_image) = 1;
- else
- DECL_EXTERNAL (gfort_gvar_caf_this_image) = 1;
-
- pushdecl_top_level (gfort_gvar_caf_this_image);
-
- gfort_gvar_caf_num_images
- = build_decl (input_location, VAR_DECL,
- get_identifier (PREFIX("caf_num_images")),
- integer_type_node);
- DECL_ARTIFICIAL (gfort_gvar_caf_num_images) = 1;
- TREE_USED (gfort_gvar_caf_num_images) = 1;
- TREE_PUBLIC (gfort_gvar_caf_num_images) = 1;
- TREE_READONLY (gfort_gvar_caf_num_images) = 0;
-
- if (main_tu)
- TREE_STATIC (gfort_gvar_caf_num_images) = 1;
- else
- DECL_EXTERNAL (gfort_gvar_caf_num_images) = 1;
-
- pushdecl_top_level (gfort_gvar_caf_num_images);
-
- pop_cfun ();
-}
-
-
static void
create_main_function (tree fndecl)
{
@@ -5237,7 +5200,7 @@ create_main_function (tree fndecl)
/* Call some libgfortran initialization routines, call then MAIN__(). */
- /* Call _gfortran_caf_init (*argc, ***argv, *this_image, *num_images). */
+ /* Call _gfortran_caf_init (*argc, ***argv). */
if (gfc_option.coarray == GFC_FCOARRAY_LIB)
{
tree pint_type, pppchar_type;
@@ -5245,12 +5208,9 @@ create_main_function (tree fndecl)
pppchar_type
= build_pointer_type (build_pointer_type (pchar_type_node));
- gfc_init_coarray_decl (true);
- tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_init, 4,
+ tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_init, 2,
gfc_build_addr_expr (pint_type, argc),
- gfc_build_addr_expr (pppchar_type, argv),
- gfc_build_addr_expr (pint_type, gfort_gvar_caf_this_image),
- gfc_build_addr_expr (pint_type, gfort_gvar_caf_num_images));
+ gfc_build_addr_expr (pppchar_type, argv));
gfc_add_expr_to_block (&body, tmp);
}
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index b2290c0ac01..5a501227863 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -1387,25 +1387,42 @@ gfc_get_expr_charlen (gfc_expr *e)
static tree
get_tree_for_caf_expr (gfc_expr *expr)
{
- tree caf_decl = NULL_TREE;
- gfc_ref *ref;
+ tree caf_decl;
+ bool found;
+ gfc_ref *ref;
- gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
- if (expr->symtree->n.sym->attr.codimension)
- caf_decl = expr->symtree->n.sym->backend_decl;
+ gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
- for (ref = expr->ref; ref; ref = ref->next)
- if (ref->type == REF_COMPONENT)
- {
+ caf_decl = expr->symtree->n.sym->backend_decl;
+ gcc_assert (caf_decl);
+ if (expr->symtree->n.sym->ts.type == BT_CLASS)
+ caf_decl = gfc_class_data_get (caf_decl);
+ if (expr->symtree->n.sym->attr.codimension)
+ return caf_decl;
+
+ /* The following code assumes that the coarray is a component reachable via
+ only scalar components/variables; the Fortran standard guarantees this. */
+
+ for (ref = expr->ref; ref; ref = ref->next)
+ if (ref->type == REF_COMPONENT)
+ {
gfc_component *comp = ref->u.c.component;
- if (comp->attr.pointer || comp->attr.allocatable)
- caf_decl = NULL_TREE;
- if (comp->attr.codimension)
- caf_decl = comp->backend_decl;
- }
- gcc_assert (caf_decl != NULL_TREE);
- return caf_decl;
+ if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
+ caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
+ caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
+ TREE_TYPE (comp->backend_decl), caf_decl,
+ comp->backend_decl, NULL_TREE);
+ if (comp->ts.type == BT_CLASS)
+ caf_decl = gfc_class_data_get (caf_decl);
+ if (comp->attr.codimension)
+ {
+ found = true;
+ break;
+ }
+ }
+ gcc_assert (found && caf_decl);
+ return caf_decl;
}
@@ -4768,19 +4785,24 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
/* For descriptorless coarrays and assumed-shape coarray dummies, we
pass the token and the offset as additional arguments. */
- if (fsym && fsym->attr.codimension
- && gfc_option.coarray == GFC_FCOARRAY_LIB
- && !fsym->attr.allocatable
- && e == NULL)
+ if (fsym && e == NULL && gfc_option.coarray == GFC_FCOARRAY_LIB
+ && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
+ && !fsym->attr.allocatable)
+ || (fsym->ts.type == BT_CLASS
+ && CLASS_DATA (fsym)->attr.codimension
+ && !CLASS_DATA (fsym)->attr.allocatable)))
{
/* Token and offset. */
vec_safe_push (stringargs, null_pointer_node);
vec_safe_push (stringargs, build_int_cst (gfc_array_index_type, 0));
gcc_assert (fsym->attr.optional);
}
- else if (fsym && fsym->attr.codimension
- && !fsym->attr.allocatable
- && gfc_option.coarray == GFC_FCOARRAY_LIB)
+ else if (fsym && gfc_option.coarray == GFC_FCOARRAY_LIB
+ && ((fsym->ts.type != BT_CLASS && fsym->attr.codimension
+ && !fsym->attr.allocatable)
+ || (fsym->ts.type == BT_CLASS
+ && CLASS_DATA (fsym)->attr.codimension
+ && !CLASS_DATA (fsym)->attr.allocatable)))
{
tree caf_decl, caf_type;
tree offset, tmp2;
@@ -4822,22 +4844,30 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
tmp = caf_decl;
}
- if (fsym->as->type == AS_ASSUMED_SHAPE
- || (fsym->as->type == AS_ASSUMED_RANK && !fsym->attr.pointer
- && !fsym->attr.allocatable))
+ tmp2 = fsym->ts.type == BT_CLASS
+ ? gfc_class_data_get (parmse.expr) : parmse.expr;
+ if ((fsym->ts.type != BT_CLASS
+ && (fsym->as->type == AS_ASSUMED_SHAPE
+ || fsym->as->type == AS_ASSUMED_RANK))
+ || (fsym->ts.type == BT_CLASS
+ && (CLASS_DATA (fsym)->as->type == AS_ASSUMED_SHAPE
+ || CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)))
{
- gcc_assert (POINTER_TYPE_P (TREE_TYPE (parmse.expr)));
- gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE
- (TREE_TYPE (parmse.expr))));
- tmp2 = build_fold_indirect_ref_loc (input_location, parmse.expr);
+ if (fsym->ts.type == BT_CLASS)
+ gcc_assert (!POINTER_TYPE_P (TREE_TYPE (tmp2)));
+ else
+ {
+ gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
+ tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
+ }
+ gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)));
tmp2 = gfc_conv_descriptor_data_get (tmp2);
}
- else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (parmse.expr)))
- tmp2 = gfc_conv_descriptor_data_get (parmse.expr);
+ else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
+ tmp2 = gfc_conv_descriptor_data_get (tmp2);
else
{
- gcc_assert (POINTER_TYPE_P (TREE_TYPE (parmse.expr)));
- tmp2 = parmse.expr;
+ gcc_assert (POINTER_TYPE_P (TREE_TYPE (tmp2)));
}
tmp = fold_build2_loc (input_location, MINUS_EXPR,
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index c96ba56f071..c166c4f0bcf 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -938,13 +938,13 @@ trans_this_image (gfc_se * se, gfc_expr *expr)
/* The case -fcoarray=single is handled elsewhere. */
gcc_assert (gfc_option.coarray != GFC_FCOARRAY_SINGLE);
- gfc_init_coarray_decl (false);
-
/* Argument-free version: THIS_IMAGE(). */
if (expr->value.function.actual->expr == NULL)
{
+ tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1,
+ integer_zero_node);
se->expr = fold_convert (gfc_get_int_type (gfc_default_integer_kind),
- gfort_gvar_caf_this_image);
+ tmp);
return;
}
@@ -1036,9 +1036,10 @@ trans_this_image (gfc_se * se, gfc_expr *expr)
*/
/* this_image () - 1. */
- tmp = fold_convert (type, gfort_gvar_caf_this_image);
- tmp = fold_build2_loc (input_location, MINUS_EXPR, type, tmp,
- build_int_cst (type, 1));
+ tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1,
+ integer_zero_node);
+ tmp = fold_build2_loc (input_location, MINUS_EXPR, type,
+ fold_convert (type, tmp), build_int_cst (type, 1));
if (corank == 1)
{
/* sub(1) = m + lcobound(corank). */
@@ -1241,8 +1242,10 @@ trans_image_index (gfc_se * se, gfc_expr *expr)
num_images = build_int_cst (type, 1);
else
{
- gfc_init_coarray_decl (false);
- num_images = fold_convert (type, gfort_gvar_caf_num_images);
+ tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images, 2,
+ integer_zero_node,
+ build_int_cst (integer_type_node, -1));
+ num_images = fold_convert (type, tmp);
}
tmp = gfc_create_var (type, NULL);
@@ -1261,9 +1264,10 @@ trans_image_index (gfc_se * se, gfc_expr *expr)
static void
trans_num_images (gfc_se * se)
{
- gfc_init_coarray_decl (false);
- se->expr = fold_convert (gfc_get_int_type (gfc_default_integer_kind),
- gfort_gvar_caf_num_images);
+ tree tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images, 2,
+ integer_zero_node,
+ build_int_cst (integer_type_node, -1));
+ se->expr = fold_convert (gfc_get_int_type (gfc_default_integer_kind), tmp);
}
@@ -1596,13 +1600,13 @@ conv_intrinsic_cobound (gfc_se * se, gfc_expr * expr)
{
tree cosize;
- gfc_init_coarray_decl (false);
cosize = gfc_conv_descriptor_cosize (desc, arg->expr->rank, corank);
-
+ tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
+ 2, integer_zero_node,
+ build_int_cst (integer_type_node, -1));
tmp = fold_build2_loc (input_location, MINUS_EXPR,
gfc_array_index_type,
- fold_convert (gfc_array_index_type,
- gfort_gvar_caf_num_images),
+ fold_convert (gfc_array_index_type, tmp),
build_int_cst (gfc_array_index_type, 1));
tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
gfc_array_index_type, tmp,
@@ -1613,11 +1617,12 @@ conv_intrinsic_cobound (gfc_se * se, gfc_expr * expr)
else if (gfc_option.coarray != GFC_FCOARRAY_SINGLE)
{
/* ubound = lbound + num_images() - 1. */
- gfc_init_coarray_decl (false);
+ tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
+ 2, integer_zero_node,
+ build_int_cst (integer_type_node, -1));
tmp = fold_build2_loc (input_location, MINUS_EXPR,
gfc_array_index_type,
- fold_convert (gfc_array_index_type,
- gfort_gvar_caf_num_images),
+ fold_convert (gfc_array_index_type, tmp),
build_int_cst (gfc_array_index_type, 1));
resbound = fold_build2_loc (input_location, PLUS_EXPR,
gfc_array_index_type, resbound, tmp);
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 00c99fcfb5b..212a2586d2a 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -784,8 +784,11 @@ gfc_trans_sync (gfc_code *code, gfc_exec_op type)
else
{
tree cond2;
+ tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
+ 2, integer_zero_node,
+ build_int_cst (integer_type_node, -1));
cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
- images, gfort_gvar_caf_num_images);
+ images, tmp);
cond2 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
images,
build_int_cst (TREE_TYPE (images), 1));
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index 9f735e19f9a..77d0e785e0b 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -1298,7 +1298,14 @@ gfc_build_array_type (tree type, gfc_array_spec * as,
{
tree lbound[GFC_MAX_DIMENSIONS];
tree ubound[GFC_MAX_DIMENSIONS];
- int n;
+ int n, corank;
+
+ /* Assumed-shape arrays do not have codimension information stored in the
+ descriptor. */
+ corank = as->corank;
+ if (as->type == AS_ASSUMED_SHAPE ||
+ (as->type == AS_ASSUMED_RANK && akind == GFC_ARRAY_ALLOCATABLE))
+ corank = 0;
if (as->type == AS_ASSUMED_RANK)
for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
@@ -1317,14 +1324,14 @@ gfc_build_array_type (tree type, gfc_array_spec * as,
ubound[n] = gfc_conv_array_bound (as->upper[n]);
}
- for (n = as->rank; n < as->rank + as->corank; n++)
+ for (n = as->rank; n < as->rank + corank; n++)
{
if (as->type != AS_DEFERRED && as->lower[n] == NULL)
lbound[n] = gfc_index_one_node;
else
lbound[n] = gfc_conv_array_bound (as->lower[n]);
- if (n < as->rank + as->corank - 1)
+ if (n < as->rank + corank - 1)
ubound[n] = gfc_conv_array_bound (as->upper[n]);
}
@@ -1336,7 +1343,7 @@ gfc_build_array_type (tree type, gfc_array_spec * as,
: GFC_ARRAY_ASSUMED_RANK;
return gfc_get_array_type_bounds (type, as->rank == -1
? GFC_MAX_DIMENSIONS : as->rank,
- as->corank, lbound,
+ corank, lbound,
ubound, 0, akind, restricted);
}
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index f8d29ecf2ec..13b0a000544 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -699,6 +699,8 @@ extern GTY(()) tree gfor_fndecl_associated;
/* Coarray run-time library function decls. */
extern GTY(()) tree gfor_fndecl_caf_init;
extern GTY(()) tree gfor_fndecl_caf_finalize;
+extern GTY(()) tree gfor_fndecl_caf_this_image;
+extern GTY(()) tree gfor_fndecl_caf_num_images;
extern GTY(()) tree gfor_fndecl_caf_register;
extern GTY(()) tree gfor_fndecl_caf_deregister;
extern GTY(()) tree gfor_fndecl_caf_critical;
@@ -708,10 +710,6 @@ extern GTY(()) tree gfor_fndecl_caf_sync_images;
extern GTY(()) tree gfor_fndecl_caf_error_stop;
extern GTY(()) tree gfor_fndecl_caf_error_stop_str;
-/* Coarray global variables for num_images/this_image. */
-extern GTY(()) tree gfort_gvar_caf_num_images;
-extern GTY(()) tree gfort_gvar_caf_this_image;
-
/* Math functions. Many other math functions are handled in
trans-intrinsic.c. */
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 008a2528644..37c3778624f 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -6273,9 +6273,17 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
OMP_CLAUSE_CHAIN (clause) = nc;
}
}
+ if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
+ {
+ tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
+ OMP_CLAUSE_DECL (nc) = decl;
+ OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
+ OMP_CLAUSE_CHAIN (nc) = *list_p;
+ OMP_CLAUSE_CHAIN (clause) = nc;
+ lang_hooks.decls.omp_finish_clause (nc);
+ }
*list_p = clause;
lang_hooks.decls.omp_finish_clause (clause);
-
return 0;
}
@@ -6314,18 +6322,17 @@ gimplify_adjust_omp_clauses (tree *list_p)
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
&& ctx->outer_context
&& !(OMP_CLAUSE_LINEAR_NO_COPYIN (c)
- && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
- && !is_global_var (decl))
+ && OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
{
- if (ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
+ if (ctx->outer_context->combined_loop
+ && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
{
n = splay_tree_lookup (ctx->outer_context->variables,
(splay_tree_key) decl);
if (n == NULL
|| (n->value & GOVD_DATA_SHARE_CLASS) == 0)
{
- int flags = OMP_CLAUSE_LINEAR_NO_COPYIN (c)
- ? GOVD_LASTPRIVATE : GOVD_SHARED;
+ int flags = GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE;
if (n == NULL)
omp_add_variable (ctx->outer_context, decl,
flags | GOVD_SEEN);
@@ -6333,7 +6340,7 @@ gimplify_adjust_omp_clauses (tree *list_p)
n->value |= flags | GOVD_SEEN;
}
}
- else
+ else if (!is_global_var (decl))
omp_notice_variable (ctx->outer_context, decl, true);
}
}
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index 8d86e746d6e..a468beed742 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,5 +1,19 @@
2014-04-30 Chris Manghane <cmang@google.com>
+ * go-backend.c: #include "diagnostics.h".
+ (saw_errors): New function.
+ * go-c.h (saw_errors): Declare.
+ * Make-lang.in (GO_OBJS): Remove go/gogo-tree.o.
+
+2014-04-30 Chris Manghane <cmang@google.com>
+
+ * go-lang.c (go_langhook_type_for_size): Do it here, rather than
+ calling into Go frontend.
+ (go_langhook_type_for_mode): Likewise.
+ * go-c.h (go_type_for_size, go_type_for_mode): Don't declare.
+
+2014-04-30 Chris Manghane <cmang@google.com>
+
* go-gcc.cc: #include "langhooks.h".
(Gcc_backend::Gcc_backend): Add constructor.
(Gcc_backend::lookup_function): New function.
diff --git a/gcc/go/Make-lang.in b/gcc/go/Make-lang.in
index abcae66a21f..bbd26dc2110 100644
--- a/gcc/go/Make-lang.in
+++ b/gcc/go/Make-lang.in
@@ -60,7 +60,6 @@ GO_OBJS = \
go/go-linemap.o \
go/go-optimize.o \
go/go.o \
- go/gogo-tree.o \
go/gogo.o \
go/import.o \
go/import-archive.o \
diff --git a/gcc/go/go-backend.c b/gcc/go/go-backend.c
index de33601db52..3f1a9f93b71 100644
--- a/gcc/go/go-backend.c
+++ b/gcc/go/go-backend.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "output.h" /* for assemble_string */
#include "target.h"
#include "common/common-target.h"
+#include "diagnostic.h"
#include "go-c.h"
@@ -48,6 +49,14 @@ along with GCC; see the file COPYING3. If not see
/* This file holds all the cases where the Go frontend needs
information from gcc's backend. */
+/* Return whether or not GCC has reported any errors. */
+
+bool
+saw_errors (void)
+{
+ return errorcount != 0 || sorrycount != 0;
+}
+
/* Return the alignment in bytes of a struct field of type T. */
unsigned int
diff --git a/gcc/go/go-c.h b/gcc/go/go-c.h
index cf0fbfb0a3f..cb10f2b7be7 100644
--- a/gcc/go/go-c.h
+++ b/gcc/go/go-c.h
@@ -41,14 +41,13 @@ extern void go_parse_input_files (const char**, unsigned int,
bool require_return_statement);
extern void go_write_globals (void);
-extern tree go_type_for_size (unsigned int bits, int unsignedp);
-extern tree go_type_for_mode (enum machine_mode, int unsignedp);
-
/* Functions defined in the GCC interface called by the Go frontend
proper. */
extern void go_preserve_from_gc (tree);
+extern bool saw_errors (void);
+
extern const char *go_localize_identifier (const char*);
extern unsigned int go_field_alignment (tree);
diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c
index c0f2f1f3884..3599aa85e54 100644
--- a/gcc/go/go-lang.c
+++ b/gcc/go/go-lang.c
@@ -288,7 +288,38 @@ go_langhook_parse_file (void)
static tree
go_langhook_type_for_size (unsigned int bits, int unsignedp)
{
- return go_type_for_size (bits, unsignedp);
+ tree type;
+ if (unsignedp)
+ {
+ if (bits == INT_TYPE_SIZE)
+ type = unsigned_type_node;
+ else if (bits == CHAR_TYPE_SIZE)
+ type = unsigned_char_type_node;
+ else if (bits == SHORT_TYPE_SIZE)
+ type = short_unsigned_type_node;
+ else if (bits == LONG_TYPE_SIZE)
+ type = long_unsigned_type_node;
+ else if (bits == LONG_LONG_TYPE_SIZE)
+ type = long_long_unsigned_type_node;
+ else
+ type = make_unsigned_type(bits);
+ }
+ else
+ {
+ if (bits == INT_TYPE_SIZE)
+ type = integer_type_node;
+ else if (bits == CHAR_TYPE_SIZE)
+ type = signed_char_type_node;
+ else if (bits == SHORT_TYPE_SIZE)
+ type = short_integer_type_node;
+ else if (bits == LONG_TYPE_SIZE)
+ type = long_integer_type_node;
+ else if (bits == LONG_LONG_TYPE_SIZE)
+ type = long_long_integer_type_node;
+ else
+ type = make_signed_type(bits);
+ }
+ return type;
}
static tree
@@ -309,9 +340,40 @@ go_langhook_type_for_mode (enum machine_mode mode, int unsignedp)
return NULL_TREE;
}
- type = go_type_for_mode (mode, unsignedp);
- if (type)
- return type;
+ // FIXME: This static_cast should be in machmode.h.
+ enum mode_class mc = static_cast<enum mode_class>(GET_MODE_CLASS(mode));
+ if (mc == MODE_INT)
+ return go_langhook_type_for_size(GET_MODE_BITSIZE(mode), unsignedp);
+ else if (mc == MODE_FLOAT)
+ {
+ switch (GET_MODE_BITSIZE (mode))
+ {
+ case 32:
+ return float_type_node;
+ case 64:
+ return double_type_node;
+ default:
+ // We have to check for long double in order to support
+ // i386 excess precision.
+ if (mode == TYPE_MODE(long_double_type_node))
+ return long_double_type_node;
+ }
+ }
+ else if (mc == MODE_COMPLEX_FLOAT)
+ {
+ switch (GET_MODE_BITSIZE (mode))
+ {
+ case 64:
+ return complex_float_type_node;
+ case 128:
+ return complex_double_type_node;
+ default:
+ // We have to check for long double in order to support
+ // i386 excess precision.
+ if (mode == TYPE_MODE(complex_long_double_type_node))
+ return complex_long_double_type_node;
+ }
+ }
#if HOST_BITS_PER_WIDE_INT >= 64
/* The middle-end and some backends rely on TImode being supported
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 27562639176..69af48c9d35 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -6736,12 +6736,9 @@ Bound_method_expression::do_get_tree(Translate_context* context)
Expression* ret = Expression::make_struct_composite_literal(st, vals, loc);
ret = Expression::make_heap_expression(ret, loc);
- tree ret_tree = ret->get_tree(context);
-
- Expression* nil_check = NULL;
-
// See whether the expression or any embedded pointers are nil.
+ Expression* nil_check = NULL;
Expression* expr = this->expr_;
if (this->method_->field_indexes() != NULL)
{
@@ -6764,26 +6761,19 @@ Bound_method_expression::do_get_tree(Translate_context* context)
nil_check = Expression::make_binary(OPERATOR_OROR, nil_check, n, loc);
}
+ Bexpression* bme = tree_to_expr(ret->get_tree(context));
if (nil_check != NULL)
{
- tree nil_check_tree = nil_check->get_tree(context);
- Expression* crash_expr =
- context->gogo()->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE, loc);
- tree crash = crash_expr->get_tree(context);
- if (ret_tree == error_mark_node
- || nil_check_tree == error_mark_node
- || crash == error_mark_node)
- return error_mark_node;
-
- ret_tree = fold_build2_loc(loc.gcc_location(), COMPOUND_EXPR,
- TREE_TYPE(ret_tree),
- build3_loc(loc.gcc_location(), COND_EXPR,
- void_type_node, nil_check_tree,
- crash, NULL_TREE),
- ret_tree);
+ Gogo* gogo = context->gogo();
+ Expression* crash =
+ gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE, loc);
+ Bexpression* bcrash = tree_to_expr(crash->get_tree(context));
+ Btype* btype = ret->type()->get_backend(gogo);
+ Bexpression* bcheck = tree_to_expr(nil_check->get_tree(context));
+ bme = gogo->backend()->conditional_expression(btype, bcheck, bcrash,
+ bme, loc);
}
-
- return ret_tree;
+ return expr_to_tree(bme);
}
// Dump ast representation of a bound method expression.
@@ -13798,30 +13788,31 @@ class Heap_expression : public Expression
tree
Heap_expression::do_get_tree(Translate_context* context)
{
- tree expr_tree = this->expr_->get_tree(context);
- if (expr_tree == error_mark_node || TREE_TYPE(expr_tree) == error_mark_node)
+ if (this->expr_->is_error_expression() || this->expr_->type()->is_error())
return error_mark_node;
- Expression* alloc =
- Expression::make_allocation(this->expr_->type(), this->location());
-
+ Location loc = this->location();
Gogo* gogo = context->gogo();
- Btype* btype = this->expr_->type()->get_backend(gogo);
- size_t expr_size = gogo->backend()->type_size(btype);
- tree space = alloc->get_tree(context);
- if (expr_size == 0)
- return space;
-
- space = save_expr(space);
- tree ref = build_fold_indirect_ref_loc(this->location().gcc_location(),
- space);
- TREE_THIS_NOTRAP(ref) = 1;
- tree ret = build2(COMPOUND_EXPR,
- type_to_tree(this->type()->get_backend(gogo)),
- build2(MODIFY_EXPR, void_type_node, ref, expr_tree),
- space);
- SET_EXPR_LOCATION(ret, this->location().gcc_location());
- return ret;
+ Btype* btype = this->type()->get_backend(gogo);
+ Expression* alloc = Expression::make_allocation(this->expr_->type(), loc);
+ Bexpression* space = tree_to_expr(alloc->get_tree(context));
+
+ Bstatement* decl;
+ Named_object* fn = context->function();
+ go_assert(fn != NULL);
+ Bfunction* fndecl = fn->func_value()->get_or_make_decl(gogo, fn);
+ Bvariable* space_temp =
+ gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
+ space, true, loc, &decl);
+ space = gogo->backend()->var_expression(space_temp, loc);
+ Bexpression* ref = gogo->backend()->indirect_expression(space, true, loc);
+
+ Bexpression* bexpr = tree_to_expr(this->expr_->get_tree(context));
+ Bstatement* assn = gogo->backend()->assignment_statement(ref, bexpr, loc);
+ decl = gogo->backend()->compound_statement(decl, assn);
+ space = gogo->backend()->var_expression(space_temp, loc);
+ Bexpression* ret = gogo->backend()->compound_expression(decl, space, loc);
+ return expr_to_tree(ret);
}
// Dump ast representation for a heap expression.
diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc
deleted file mode 100644
index 5b9a8180287..00000000000
--- a/gcc/go/gofrontend/gogo-tree.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// gogo-tree.cc -- convert Go frontend Gogo IR to gcc trees.
-
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "go-system.h"
-
-#include "toplev.h"
-#include "tree.h"
-#include "stringpool.h"
-#include "stor-layout.h"
-#include "varasm.h"
-#include "gimple-expr.h"
-#include "gimplify.h"
-#include "tree-iterator.h"
-#include "cgraph.h"
-#include "langhooks.h"
-#include "convert.h"
-#include "output.h"
-#include "diagnostic.h"
-#include "go-c.h"
-
-#include "types.h"
-#include "expressions.h"
-#include "statements.h"
-#include "runtime.h"
-#include "backend.h"
-#include "gogo.h"
-
-// Whether we have seen any errors.
-
-bool
-saw_errors()
-{
- return errorcount != 0 || sorrycount != 0;
-}
-
-// Return the integer type to use for a size.
-
-GO_EXTERN_C
-tree
-go_type_for_size(unsigned int bits, int unsignedp)
-{
- const char* name;
- switch (bits)
- {
- case 8:
- name = unsignedp ? "uint8" : "int8";
- break;
- case 16:
- name = unsignedp ? "uint16" : "int16";
- break;
- case 32:
- name = unsignedp ? "uint32" : "int32";
- break;
- case 64:
- name = unsignedp ? "uint64" : "int64";
- break;
- default:
- if (bits == POINTER_SIZE && unsignedp)
- name = "uintptr";
- else
- return NULL_TREE;
- }
- Type* type = Type::lookup_integer_type(name);
- return type_to_tree(type->get_backend(go_get_gogo()));
-}
-
-// Return the type to use for a mode.
-
-GO_EXTERN_C
-tree
-go_type_for_mode(enum machine_mode mode, int unsignedp)
-{
- // FIXME: This static_cast should be in machmode.h.
- enum mode_class mc = static_cast<enum mode_class>(GET_MODE_CLASS(mode));
- if (mc == MODE_INT)
- return go_type_for_size(GET_MODE_BITSIZE(mode), unsignedp);
- else if (mc == MODE_FLOAT)
- {
- Type* type;
- switch (GET_MODE_BITSIZE (mode))
- {
- case 32:
- type = Type::lookup_float_type("float32");
- break;
- case 64:
- type = Type::lookup_float_type("float64");
- break;
- default:
- // We have to check for long double in order to support
- // i386 excess precision.
- if (mode == TYPE_MODE(long_double_type_node))
- return long_double_type_node;
- return NULL_TREE;
- }
- return type_to_tree(type->get_backend(go_get_gogo()));
- }
- else if (mc == MODE_COMPLEX_FLOAT)
- {
- Type *type;
- switch (GET_MODE_BITSIZE (mode))
- {
- case 64:
- type = Type::lookup_complex_type("complex64");
- break;
- case 128:
- type = Type::lookup_complex_type("complex128");
- break;
- default:
- // We have to check for long double in order to support
- // i386 excess precision.
- if (mode == TYPE_MODE(complex_long_double_type_node))
- return complex_long_double_type_node;
- return NULL_TREE;
- }
- return type_to_tree(type->get_backend(go_get_gogo()));
- }
- else
- return NULL_TREE;
-}
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 995a4f2d2da..ab54f8491e3 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -1147,8 +1147,6 @@ Gogo::write_globals()
Bstatement* var_init_stmt = NULL;
if (!var->has_pre_init())
{
- Bexpression* var_binit = var->get_init(this, NULL);
-
// If the backend representation of the variable initializer is
// constant, we can just set the initial value using
// global_var_set_init instead of during the init() function.
@@ -1168,6 +1166,13 @@ Gogo::write_globals()
init_cast->is_immutable() && !var_type->has_pointer();
}
+ // Non-constant variable initializations might need to create
+ // temporary variables, which will need the initialization
+ // function as context.
+ if (!is_constant_initializer && init_fndecl == NULL)
+ init_fndecl = this->initialization_function_decl();
+ Bexpression* var_binit = var->get_init(this, init_fndecl);
+
if (var_binit == NULL)
;
else if (is_constant_initializer)
diff --git a/gcc/hwint.h b/gcc/hwint.h
index 229fb94b565..ac9c9a295b4 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -344,7 +344,7 @@ zext_hwi (unsigned HOST_WIDE_INT src, unsigned int prec)
else
{
gcc_checking_assert (prec < HOST_BITS_PER_WIDE_INT);
- return src & (((HOST_WIDE_INT) 1 << prec) - 1);
+ return src & (((unsigned HOST_WIDE_INT) 1 << prec) - 1);
}
}
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index 1f4c96e9a89..28a6d40eb1d 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -1599,7 +1599,6 @@ check_hard_reg_p (ira_allocno_t a, int hard_regno,
}
return j == nregs;
}
-#ifndef HONOR_REG_ALLOC_ORDER
/* Return number of registers needed to be saved and restored at
function prologue/epilogue if we allocate HARD_REGNO to hold value
@@ -1618,7 +1617,6 @@ calculate_saved_nregs (int hard_regno, enum machine_mode mode)
nregs++;
return nregs;
}
-#endif
/* Choose a hard register for allocno A. If RETRY_P is TRUE, it means
that the function called from function
@@ -1653,11 +1651,9 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
enum reg_class aclass;
enum machine_mode mode;
static int costs[FIRST_PSEUDO_REGISTER], full_costs[FIRST_PSEUDO_REGISTER];
-#ifndef HONOR_REG_ALLOC_ORDER
int saved_nregs;
enum reg_class rclass;
int add_cost;
-#endif
#ifdef STACK_REGS
bool no_stack_reg_p;
#endif
@@ -1823,19 +1819,20 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
continue;
cost = costs[i];
full_cost = full_costs[i];
-#ifndef HONOR_REG_ALLOC_ORDER
- if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
- /* We need to save/restore the hard register in
- epilogue/prologue. Therefore we increase the cost. */
+ if (!HONOR_REG_ALLOC_ORDER)
{
- rclass = REGNO_REG_CLASS (hard_regno);
- add_cost = ((ira_memory_move_cost[mode][rclass][0]
- + ira_memory_move_cost[mode][rclass][1])
- * saved_nregs / hard_regno_nregs[hard_regno][mode] - 1);
- cost += add_cost;
- full_cost += add_cost;
+ if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0)
+ /* We need to save/restore the hard register in
+ epilogue/prologue. Therefore we increase the cost. */
+ {
+ rclass = REGNO_REG_CLASS (hard_regno);
+ add_cost = ((ira_memory_move_cost[mode][rclass][0]
+ + ira_memory_move_cost[mode][rclass][1])
+ * saved_nregs / hard_regno_nregs[hard_regno][mode] - 1);
+ cost += add_cost;
+ full_cost += add_cost;
+ }
}
-#endif
if (min_cost > cost)
min_cost = cost;
if (min_full_cost > full_cost)
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index aac50876d21..f59bf555544 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -317,6 +317,94 @@ in_mem_p (int regno)
return get_reg_class (regno) == NO_REGS;
}
+/* Return 1 if ADDR is a valid memory address for mode MODE in address
+ space AS, and check that each pseudo has the proper kind of hard
+ reg. */
+static int
+valid_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx addr, addr_space_t as)
+{
+#ifdef GO_IF_LEGITIMATE_ADDRESS
+ lra_assert (ADDR_SPACE_GENERIC_P (as));
+ GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
+ return 0;
+
+ win:
+ return 1;
+#else
+ return targetm.addr_space.legitimate_address_p (mode, addr, 0, as);
+#endif
+}
+
+/* Return whether address AD is valid. If CONSTRAINT is null,
+ check for general addresses, otherwise check the extra constraint
+ CONSTRAINT. */
+static bool
+valid_address_p (struct address_info *ad, const char *constraint = 0)
+{
+ /* Some ports do not check displacements for eliminable registers,
+ so we replace them temporarily with the elimination target. */
+ rtx saved_base_reg = NULL_RTX;
+ rtx saved_index_reg = NULL_RTX;
+ rtx *base_term = strip_subreg (ad->base_term);
+ rtx *index_term = strip_subreg (ad->index_term);
+ if (base_term != NULL)
+ {
+ saved_base_reg = *base_term;
+ lra_eliminate_reg_if_possible (base_term);
+ if (ad->base_term2 != NULL)
+ *ad->base_term2 = *ad->base_term;
+ }
+ if (index_term != NULL)
+ {
+ saved_index_reg = *index_term;
+ lra_eliminate_reg_if_possible (index_term);
+ }
+ bool ok_p = (constraint
+#ifdef EXTRA_CONSTRAINT_STR
+ ? EXTRA_CONSTRAINT_STR (*ad->outer, constraint[0], constraint)
+#else
+ ? false
+#endif
+ : valid_address_p (ad->mode, *ad->outer, ad->as));
+ if (saved_base_reg != NULL_RTX)
+ {
+ *base_term = saved_base_reg;
+ if (ad->base_term2 != NULL)
+ *ad->base_term2 = *ad->base_term;
+ }
+ if (saved_index_reg != NULL_RTX)
+ *index_term = saved_index_reg;
+ return ok_p;
+}
+
+#ifdef EXTRA_CONSTRAINT_STR
+/* Return true if, after elimination, OP satisfies extra memory constraint
+ CONSTRAINT. */
+static bool
+satisfies_memory_constraint_p (rtx op, const char *constraint)
+{
+ struct address_info ad;
+
+ if (!MEM_P (op))
+ return false;
+
+ decompose_mem_address (&ad, op);
+ return valid_address_p (&ad, constraint);
+}
+
+/* Return true if, after elimination, OP satisfies extra address constraint
+ CONSTRAINT. */
+static bool
+satisfies_address_constraint_p (rtx op, const char *constraint)
+{
+ struct address_info ad;
+
+ decompose_lea_address (&ad, &op);
+ return valid_address_p (&ad, constraint);
+}
+#endif
+
/* Initiate equivalences for LRA. As we keep original equivalences
before any elimination, we need to make copies otherwise any change
in insns might change the equivalences. */
@@ -1941,7 +2029,7 @@ process_alt_operands (int only_alternative)
#ifdef EXTRA_CONSTRAINT_STR
if (EXTRA_MEMORY_CONSTRAINT (c, p))
{
- if (EXTRA_CONSTRAINT_STR (op, c, p))
+ if (satisfies_memory_constraint_p (op, p))
win = true;
else if (spilled_pseudo_p (op))
win = true;
@@ -1960,7 +2048,7 @@ process_alt_operands (int only_alternative)
}
if (EXTRA_ADDRESS_CONSTRAINT (c, p))
{
- if (EXTRA_CONSTRAINT_STR (op, c, p))
+ if (satisfies_address_constraint_p (op, p))
win = true;
/* If we didn't already win, we can reload
@@ -2576,60 +2664,6 @@ process_alt_operands (int only_alternative)
return ok_p;
}
-/* Return 1 if ADDR is a valid memory address for mode MODE in address
- space AS, and check that each pseudo has the proper kind of hard
- reg. */
-static int
-valid_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
- rtx addr, addr_space_t as)
-{
-#ifdef GO_IF_LEGITIMATE_ADDRESS
- lra_assert (ADDR_SPACE_GENERIC_P (as));
- GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
- return 0;
-
- win:
- return 1;
-#else
- return targetm.addr_space.legitimate_address_p (mode, addr, 0, as);
-#endif
-}
-
-/* Return whether address AD is valid. */
-
-static bool
-valid_address_p (struct address_info *ad)
-{
- /* Some ports do not check displacements for eliminable registers,
- so we replace them temporarily with the elimination target. */
- rtx saved_base_reg = NULL_RTX;
- rtx saved_index_reg = NULL_RTX;
- rtx *base_term = strip_subreg (ad->base_term);
- rtx *index_term = strip_subreg (ad->index_term);
- if (base_term != NULL)
- {
- saved_base_reg = *base_term;
- lra_eliminate_reg_if_possible (base_term);
- if (ad->base_term2 != NULL)
- *ad->base_term2 = *ad->base_term;
- }
- if (index_term != NULL)
- {
- saved_index_reg = *index_term;
- lra_eliminate_reg_if_possible (index_term);
- }
- bool ok_p = valid_address_p (ad->mode, *ad->outer, ad->as);
- if (saved_base_reg != NULL_RTX)
- {
- *base_term = saved_base_reg;
- if (ad->base_term2 != NULL)
- *ad->base_term2 = *ad->base_term;
- }
- if (saved_index_reg != NULL_RTX)
- *index_term = saved_index_reg;
- return ok_p;
-}
-
/* Make reload base reg + disp from address AD. Return the new pseudo. */
static rtx
base_plus_disp_to_reg (struct address_info *ad)
@@ -2832,7 +2866,7 @@ process_address (int nop, rtx *before, rtx *after)
EXTRA_CONSTRAINT_STR for the validation. */
if (constraint[0] != 'p'
&& EXTRA_ADDRESS_CONSTRAINT (constraint[0], constraint)
- && EXTRA_CONSTRAINT_STR (op, constraint[0], constraint))
+ && valid_address_p (&ad, constraint))
return change_p;
#endif
@@ -3539,7 +3573,7 @@ curr_insn_transform (void)
break;
#ifdef EXTRA_CONSTRAINT_STR
if (EXTRA_MEMORY_CONSTRAINT (c, constraint)
- && EXTRA_CONSTRAINT_STR (tem, c, constraint))
+ && satisfies_memory_constraint_p (tem, constraint))
break;
#endif
}
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index a0f024a76ef..453f580a838 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -5582,6 +5582,12 @@ expand_omp_for_generic (struct omp_region *region,
{
stmt = gimple_build_assign (endvar, iend);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+ if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (iend)))
+ stmt = gimple_build_assign (fd->loop.v, iend);
+ else
+ stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, iend,
+ NULL_TREE);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
}
if (fd->collapse > 1)
expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
@@ -5998,6 +6004,12 @@ expand_omp_for_static_nochunk (struct omp_region *region,
{
stmt = gimple_build_assign (endvar, e);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+ if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
+ stmt = gimple_build_assign (fd->loop.v, e);
+ else
+ stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, e,
+ NULL_TREE);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
}
if (fd->collapse > 1)
expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
@@ -6383,6 +6395,12 @@ expand_omp_for_static_chunk (struct omp_region *region,
{
stmt = gimple_build_assign (endvar, e);
gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
+ if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
+ stmt = gimple_build_assign (fd->loop.v, e);
+ else
+ stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, e,
+ NULL_TREE);
+ gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
}
if (fd->collapse > 1)
expand_omp_for_init_vars (fd, &si, counts, inner_stmt, startvar);
diff --git a/gcc/passes.c b/gcc/passes.c
index dbff5875a5d..30c849fce39 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -1783,11 +1783,11 @@ execute_function_todo (function *fn, void *data)
/* IPA passes leave stmts to be fixed up, so make sure to
not verify SSA operands whose verifier will choke on that. */
verify_ssa (true, !from_ipa_pass);
- }
- if (flags & TODO_verify_flow)
- verify_flow_info ();
- if (flags & TODO_verify_il)
- {
+ /* IPA passes leave basic-blocks unsplit, so make sure to
+ not trip on that. */
+ if ((cfun->curr_properties & PROP_cfg)
+ && !from_ipa_pass)
+ verify_flow_info ();
if (current_loops
&& loops_state_satisfies_p (LOOP_CLOSED_SSA))
verify_loop_closed_ssa (false);
diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog
index ceb363e355d..a25a90eb438 100644
--- a/gcc/po/ChangeLog
+++ b/gcc/po/ChangeLog
@@ -1,3 +1,14 @@
+2014-05-01 Jeff Law <law@redhat.com>
+
+ * Revert:
+ 2014-04-24 Jincheng Miao <jincheng.miao@gmail.com>
+
+ * zh_CN.po: Fix typo for -mfentry.
+
+2014-05-01 Joseph Myers <joseph@codesourcery.com>
+
+ * sv.po: Update.
+
2014-04-24 Jincheng Miao <jincheng.miao@gmail.com>
* zh_CN.po: Fix typo for -mfentry.
diff --git a/gcc/po/sv.po b/gcc/po/sv.po
index 0bae3b6f757..b38f7081181 100644
--- a/gcc/po/sv.po
+++ b/gcc/po/sv.po
@@ -16,7 +16,7 @@ msgstr ""
"Project-Id-Version: gcc 4.9-b20140202\n"
"Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n"
"POT-Creation-Date: 2014-02-02 17:35+0000\n"
-"PO-Revision-Date: 2014-03-30 20:23+0200\n"
+"PO-Revision-Date: 2014-04-11 20:56+0200\n"
"Last-Translator: Göran Uddeborg <goeran@uddeborg.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
"Language: sv\n"
@@ -1493,7 +1493,7 @@ msgstr "attributen för optimeringsnivåer stämmer inte"
#: cif-code.def:125
msgid "callee refers to comdat-local symbols"
-msgstr "den anropade referarar till comdat-lokala symboler"
+msgstr "den anropade refererar till comdat-lokala symboler"
#. The remainder are real diagnostic types.
#: diagnostic.def:33
@@ -6065,7 +6065,7 @@ msgstr "Varna för missbruk av pragman"
#: c-family/c.opt:653
msgid "Warn about __TIME__, __DATE__ and __TIMESTAMP__ usage"
-msgstr "Warn för använding av __TIME__, __DATE__ och __TIMESTAMP__"
+msgstr "Varna för användning av __TIME__, __DATE__ och __TIMESTAMP__"
#: c-family/c.opt:657
msgid "Warn if a property for an Objective-C object has no assign semantics specified"
@@ -12220,7 +12220,7 @@ msgstr "-dumpdir <kat>\tAnge katalognamn att användas för dumpar"
#: common.opt:811
msgid "Aggressively optimize loops using language constraints"
-msgstr "Optimera aggresivt slingor med användning av språkbegränsningar"
+msgstr "Optimera aggressivt slingor med användning av språkbegränsningar"
#: common.opt:815
msgid "Align the start of functions"
@@ -13449,7 +13449,7 @@ msgstr "okänd kostnadsmodell för vektorisering %qs"
#: common.opt:2332
msgid "Enables the dynamic vectorizer cost model. Preserved for backward compatibility."
-msgstr "Aktivera den dynamiska kostnadsmodellen för vekoriseraren. Bevarad för bakåtkompatibilitet."
+msgstr "Aktivera den dynamiska kostnadsmodellen för vektoriseraren. Bevarad för bakåtkompatibilitet."
#: common.opt:2336
msgid "Enables the unlimited vectorizer cost model. Preserved for backward compatibility."
@@ -19151,7 +19151,7 @@ msgstr "längden stämmer inte i uttryck"
#: c/c-array-notation.c:721 cp/cp-array-notation.c:610
#, gcc-internal-format
msgid "rank mismatch between %qE and %qE"
-msgstr "ordingen stämmer inte mellan %qE och %qE"
+msgstr "ordningen stämmer inte mellan %qE och %qE"
#. Here the original expression is printed as a "heads-up"
#. to the programmer. This is because since there is no
@@ -25782,7 +25782,7 @@ msgstr "felaktig DISPOSE-konstruktion: %d"
msgid "too much stack space to dispose of: %d"
msgstr "för mycket stackutrymme att göra av med: %d"
-# Förmodligen en felstavning i orginalet, men tills jag vet säkert
+# Förmodligen en felstavning i originalet, men tills jag vet säkert
# behåller jag den
#: config/v850/v850.c:2788
#, gcc-internal-format, gfc-internal-format
@@ -28130,7 +28130,7 @@ msgstr "den andra matchen är här"
#: c/c-parser.c:6884
#, gcc-internal-format
msgid "%<_Generic%> selector of type %qT is not compatible with any association"
-msgstr "%<_Generic%>-väljare av typ %qT är inte kompatiblem med någon association"
+msgstr "%<_Generic%>-väljare av typ %qT är inte kompatibel med någon association"
#: c/c-parser.c:7039 c/c-parser.c:7519 c/c-parser.c:7538
#, gcc-internal-format
@@ -28185,7 +28185,7 @@ msgstr "-fcilkplus måste vara aktiverat för att använda %<_Cilk_spawn%>"
#: c/c-parser.c:7505 cp/parser.c:5807
#, gcc-internal-format
msgid "consecutive %<_Cilk_spawn%> keywords are not permitted"
-msgstr "konsektiva %<_Cilk_spawn%>-nyckelord är inte tillåtet"
+msgstr "konsekutiva %<_Cilk_spawn%>-nyckelord är inte tillåtet"
#: c/c-parser.c:7573
#, gcc-internal-format
@@ -31055,7 +31055,7 @@ msgstr "%qD kan inte vara en skalär när %qD inte är det"
#: cp/cp-array-notation.c:849 cp/cp-array-notation.c:855
#, gcc-internal-format
msgid "rank mismatch with controlling expression of parent if-statement"
-msgstr "ordingen stämmer inte med det styrande uttrycket i förälder-if-satsen"
+msgstr "ordningen stämmer inte med det styrande uttrycket i förälder-if-satsen"
#: cp/cp-array-notation.c:1250
#, gcc-internal-format
@@ -31090,7 +31090,7 @@ msgstr "startindex och längdfält är nödvändiga för att använda vektornota
#: cp/cp-array-notation.c:1422
#, gcc-internal-format
msgid "array notation cannot be used with function type"
-msgstr "vektornotation kan inte användas användas med en funktionstyp"
+msgstr "vektornotation kan inte användas med en funktionstyp"
#: cp/cp-array-notation.c:1432
#, gcc-internal-format
@@ -31100,7 +31100,7 @@ msgstr "ordningen på en vektornotations trippels startindex är inte noll"
#: cp/cp-array-notation.c:1438
#, gcc-internal-format
msgid "rank of an array notation triplet%'s length is not zero"
-msgstr "ordingen på en vektornotations trippels längd är inte noll"
+msgstr "ordningen på en vektornotations trippels längd är inte noll"
#: cp/cp-array-notation.c:1443
#, gcc-internal-format
@@ -31450,7 +31450,7 @@ msgstr "standardtypkonvertering kan inte härleda mallargumentet för %qD"
#: cp/cvt.c:1659
#, gcc-internal-format
msgid "ambiguous default type conversion from %qT"
-msgstr "tvetydig standartypkonvertering från %qT"
+msgstr "tvetydig standardtypkonvertering från %qT"
#: cp/cvt.c:1661
#, gcc-internal-format
@@ -33747,7 +33747,7 @@ msgstr "%qD är redan definierad i klassen %qT"
#: cp/decl.c:14531 cp/decl2.c:4673
#, gcc-internal-format
msgid "use of %qD before deduction of %<auto%>"
-msgstr "använding av %qD före härledning av %<auto%>"
+msgstr "användning av %qD före härledning av %<auto%>"
#: cp/decl2.c:322
#, gcc-internal-format
@@ -36027,7 +36027,7 @@ msgstr "användning av %<auto%> i lambdaparameterdeklarationer är endast tillgÃ
#: cp/parser.c:14516
#, gcc-internal-format
msgid "use of %<auto%> in parameter declaration only available with -std=c++1y or -std=gnu++1y"
-msgstr "använding av %<auto%> i parameterdeklarationer är endast tillgängligt med -std=c++1y eller -std=gnu++1y"
+msgstr "användning av %<auto%> i parameterdeklarationer är endast tillgängligt med -std=c++1y eller -std=gnu++1y"
#: cp/parser.c:14521
#, gcc-internal-format
@@ -37288,7 +37288,7 @@ msgstr " men %d behövs"
#: cp/pt.c:4861
#, gcc-internal-format
msgid "template arguments to %qD do not match original template %qD"
-msgstr "mallargument till %qD stämmer inte med orginalmallen %qD"
+msgstr "mallargument till %qD stämmer inte med originalmallen %qD"
#: cp/pt.c:4865
#, gcc-internal-format
@@ -38326,7 +38326,7 @@ msgstr "det går inte att applicera %<offsetof%> på destrueraren %<~%T%>"
#: cp/semantics.c:3800
#, gcc-internal-format
msgid "second operand of %<offsetof%> is neither a single identifier nor a sequence of member accesses and array references"
-msgstr "andra operanden till %<offsetof%> är varken en ensam idientifierare eller en sekvens av medlemsåtkomster och vektorreferenser"
+msgstr "andra operanden till %<offsetof%> är varken en ensam identifierare eller en sekvens av medlemsåtkomster och vektorreferenser"
#: cp/semantics.c:3808
#, gcc-internal-format
@@ -48120,7 +48120,7 @@ msgstr "Variabeln â€%s†vid %L av TYPE(C_PTR) eller TYPE(C_FUNPTR) fÃ¥r inte
#: fortran/resolve.c:13229
#, gcc-internal-format, gfc-internal-format
msgid "Variable '%s' at %L with coarray component shall be a nonpointer, nonallocatable scalar, which is not a coarray"
-msgstr "Variabeln â€%s†vid %L med co-vektorkomponent skall vara en skalär som inte är en pekare eller allokerbar och inte en co-vaktor"
+msgstr "Variabeln â€%s†vid %L med co-vektorkomponent skall vara en skalär som inte är en pekare eller allokerbar och inte en co-vektor"
#: fortran/resolve.c:13244
#, gcc-internal-format, gfc-internal-format
@@ -49576,12 +49576,12 @@ msgstr "tidigare definition här"
#: lto/lto-symtab.c:404
#, gcc-internal-format
msgid "type of %qD does not match original declaration"
-msgstr "typen på %qD stämmer inte med orginaldeklarationen"
+msgstr "typen på %qD stämmer inte med originaldeklarationen"
#: lto/lto-symtab.c:412
#, gcc-internal-format
msgid "alignment of %qD is bigger than original declaration"
-msgstr "justering av %qD är större än orginaldeklarationen"
+msgstr "justering av %qD är större än originaldeklarationen"
#: lto/lto-symtab.c:418 lto/lto-symtab.c:517
#, gcc-internal-format
diff --git a/gcc/po/zh_CN.po b/gcc/po/zh_CN.po
index 237e93033d8..7edfcb45770 100644
--- a/gcc/po/zh_CN.po
+++ b/gcc/po/zh_CN.po
@@ -24308,7 +24308,7 @@ msgstr "堆栈探针目å‰éœ€è¦æ¡†æž¶æŒ‡é’ˆæˆ– %saccumulate-outgoing-args%s æ¥
#: config/i386/i386.c:4108
#, gcc-internal-format
msgid "-mfentry isn%'t supported for 32-bit in combination with -fpic"
-msgstr "-mfentry 在 32 ä½ä¸‹ä¸èƒ½å’Œ -fpic åŒæ—¶ä½¿ç”¨"
+msgstr "-mfentry 在 32 ä½ä¸‹ä¸èƒ½å’Œ -pic åŒæ—¶ä½¿ç”¨"
#: config/i386/i386.c:4115
#, gcc-internal-format
diff --git a/gcc/target.def b/gcc/target.def
index 465dbe2d569..288d1d172b1 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2658,6 +2658,18 @@ The default version of this hook use the target macro\n\
bool, (void),
default_profile_before_prologue)
+/* Return true if a leaf function should stay leaf even with profiling
+ enabled. */
+DEFHOOK
+(keep_leaf_when_profiled,
+ "This target hook returns true if the target wants the leaf flag for\
+ the current function to stay true even if it calls mcount. This might\
+ make sense for targets using the leaf flag only to determine whether a\
+ stack frame needs to be generated or not and for which the call to\
+ mcount is generated before the function prologue.",
+ bool, (void),
+ default_keep_leaf_when_profiled)
+
/* Modify and return the identifier of a DECL's external name,
originally identified by ID, as required by the target,
(eg, append @nn to windows32 stdcall function names).
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index d844790d027..3df93d39432 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1447,6 +1447,15 @@ default_get_reg_raw_mode (int regno)
return reg_raw_mode[regno];
}
+/* Return true if a leaf function should stay leaf even with profiling
+ enabled. */
+
+bool
+default_keep_leaf_when_profiled ()
+{
+ return false;
+}
+
/* Return true if the state of option OPTION should be stored in PCH files
and checked by default_pch_valid_p. Store the option's current state
in STATE if so. */
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index ac57201f93f..4be33f8696c 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -195,6 +195,7 @@ extern int default_jump_align_max_skip (rtx);
extern section * default_function_section(tree decl, enum node_frequency freq,
bool startup, bool exit);
extern enum machine_mode default_get_reg_raw_mode (int);
+extern bool default_keep_leaf_when_profiled ();
extern void *default_get_pch_validity (size_t *);
extern const char *default_pch_valid_p (const void *, size_t);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 00ae0d12f54..1c9d4d31c66 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,151 @@
+2014-05-05 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/61010
+ * gcc.dg/torture/pr61010.c: New testcase.
+
+2014-05-05 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * gcc.target/s390/leaf-profile.c: New testcase.
+
+2014-05-05 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * gcc.dg/hoist-register-pressure-1.c: Replace int with long.
+ Disable asm scan for s390.
+ * gcc.dg/hoist-register-pressure-2.c: Likewise.
+ * gcc.dg/hoist-register-pressure-3.c: Likewise.
+
+2014-05-05 Bin Cheng <bin.cheng@arm.com>
+
+ PR tree-optimization/60363
+ * gcc.dg/tree-ssa/ssa-dom-thread-4.c: Revert XFAIL test.
+
+2014-05-04 Peter Bergner <bergner@vnet.ibm.com>
+
+ * gcc.target/powerpc/pack02.c (dg-options): Add -mhard-float.
+ (dg-require-effective-target): Change target to powerpc_fprs.
+ * gcc.target/powerpc/pack03.c (dg-options): Add -mhard-dfp.
+ (dg-require-effective-target): Change target to dfprt.
+
+2014-05-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58582
+ * g++.dg/cpp0x/deleted4.C: New.
+ * g++.dg/cpp0x/deleted5.C: Likewise.
+ * g++.dg/cpp0x/deleted6.C: Likewise.
+
+2014-05-03 Dominique d'Humieres <dominiq@lps.ens.fr>
+
+ PR fortran/61025
+ * gfortran.dg/coarray_lib_this_image_1.f90: Adjust the dg-final
+ regexps for -m32.
+ * gfortran.dg/coarray_lib_this_image_2.f90: Likewise.
+ * gfortran.dg/coarray_poly_6.f90: Likewise.
+ * gfortran.dg/coarray_poly_7.f90: Likewise.
+ * gfortran.dg/coarray_poly_8.f90: Likewise.
+
+2014-05-02 Marek Polacek <polacek@redhat.com>
+
+ PR c/25801
+ * gcc.dg/pr25801.c: New test.
+
+2014-05-02 Marek Polacek <polacek@redhat.com>
+
+ PR c/60784
+ * gcc.dg/pr60784.c: New test.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/60915
+ * gcc.dg/pr60915.c: New test.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/60257
+ * gcc.dg/pr60257.c: New test.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/43395
+ * c-c++-common/pr43395.c: New test.
+
+2014-05-01 Yuri Rumyantsev <ysrumyan@gmail.com>
+
+ * gcc.dg/cond-reduc-1.c: New test.
+ * gcc.dg/cond-reduc-2.c: Likewise.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/29467
+ * gcc.dg/pr29467.c: New test.
+ * gcc.dg/declspec-13.c: Renumber some dg-warnings. Add dg-warnings
+ about boolean types.
+ * gfortran.dg/bind_c_usage_24_c.c: Include <stdbool.h>. Change _Bool
+ to bool.
+ * gfortran.dg/c_f_pointer_logical_driver.c: Change _Bool to bool.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/43245
+ * gcc.dg/pr43245.c: New test.
+
+2014-05-01 Marek Polacek <polacek@redhat.com>
+
+ PR c/56989
+ * gcc.dg/pr56989.c: New test.
+
+2014-04-30 Ian Lance Taylor <iant@google.com>
+
+ * go.test/go-test.exp (go-gc-tests): For rundir, pass extra files
+ in go_compile_args rather than in argument to go-torture-execute.
+
+2014-04-30 Soundararajan Dhakshinamoorthy <sounderarajan.d@atmel.com>
+
+ * gcc.c-torture/execute/pr58419.c: Use dummy no-inline function
+ instead of getpid.
+
+2014-04-30 Tobias Burnus <burnus@net-b.de>
+
+ * gfortran.dg/coarray_poly_6.f90
+ * gfortran.dg/coarray_poly_7.f90
+ * gfortran.dg/coarray_poly_8.f90
+
+2014-04-30 Tobias Burnus <burnus@net-b.de>
+
+ * gfortran.dg/coarray_lib_this_image_2.f90: Update dump.
+ * gfortran.dg/coarray_lib_token_4.f90: Ditto.
+ * gfortran.dg/coarray/codimension.f90: New.
+
+2014-04-30 Tobias Burnus <burnus@net-b.de>
+
+ * gfortran.dg/coarray_lib_this_image_1.f90: New.
+ * gfortran.dg/coarray_lib_this_image_2.f90: New.
+
+2014-04-30 Tobias Burnus <burnus@net-b.de>
+
+ * gfortran.dg/coarray_poly_4.f90: New.
+ * gfortran.dg/coarray_poly_5.f90: New.
+
+2014-04-30 Alan Lawrence <alan.lawrence@arm.com>
+
+ * gcc.target/arm/simd/vuzpqf32_1.c: New file.
+ * gcc.target/arm/simd/vuzpqp16_1.c: New file.
+ * gcc.target/arm/simd/vuzpqp8_1.c: New file.
+ * gcc.target/arm/simd/vuzpqs16_1.c: New file.
+ * gcc.target/arm/simd/vuzpqs32_1.c: New file.
+ * gcc.target/arm/simd/vuzpqs8_1.c: New file.
+ * gcc.target/arm/simd/vuzpqu16_1.c: New file.
+ * gcc.target/arm/simd/vuzpqu32_1.c: New file.
+ * gcc.target/arm/simd/vuzpqu8_1.c: New file.
+ * gcc.target/arm/simd/vuzpf32_1.c: New file.
+ * gcc.target/arm/simd/vuzpp16_1.c: New file.
+ * gcc.target/arm/simd/vuzpp8_1.c: New file.
+ * gcc.target/arm/simd/vuzps16_1.c: New file.
+ * gcc.target/arm/simd/vuzps32_1.c: New file.
+ * gcc.target/arm/simd/vuzps8_1.c: New file.
+ * gcc.target/arm/simd/vuzpu16_1.c: New file.
+ * gcc.target/arm/simd/vuzpu32_1.c: New file.
+ * gcc.target/arm/simd/vuzpu8_1.c: New file.
+
2014-04-30 Alan Lawrence <alan.lawrence@arm.com>
* gcc.target/aarch64/vuzps32_1.c: Expect zip1/2 insn rather than uzp1/2.
diff --git a/gcc/testsuite/c-c++-common/pr43395.c b/gcc/testsuite/c-c++-common/pr43395.c
new file mode 100644
index 00000000000..92f048d53a6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr43395.c
@@ -0,0 +1,30 @@
+/* PR c/43395 */
+/* { dg-do compile } */
+
+void *
+foo (void)
+{
+lab:
+ return &&lab;
+/* { dg-warning "function returns address of label" "" { target c } 8 } */
+/* { dg-warning "address of label" "" { target c++ } 7 } */
+}
+
+void *
+bar (void)
+{
+ __label__ lab;
+lab:
+ return &&lab;
+/* { dg-warning "function returns address of label" "" { target c } 18 } */
+/* { dg-warning "address of label" "" { target c++ } 17 } */
+}
+
+void *
+baz (void)
+{
+ int i;
+ return &i;
+/* { dg-warning "function returns address of local variable" "" { target c } 27 } */
+/* { dg-warning "address of local variable" "" { target c++ } 26 } */
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/deleted4.C b/gcc/testsuite/g++.dg/cpp0x/deleted4.C
new file mode 100644
index 00000000000..22439d45708
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/deleted4.C
@@ -0,0 +1,11 @@
+// PR c++/58582
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+ template<int> void foo() = delete;
+};
+
+template<int> void A::foo() { int i; } // { dg-error "redefinition" }
+
+template void A::foo<0>();
diff --git a/gcc/testsuite/g++.dg/cpp0x/deleted5.C b/gcc/testsuite/g++.dg/cpp0x/deleted5.C
new file mode 100644
index 00000000000..51010efda78
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/deleted5.C
@@ -0,0 +1,11 @@
+// PR c++/58582
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+ template<int> void foo() = delete;
+};
+
+template<int> void A::foo() {} // { dg-error "redefinition" }
+
+template void A::foo<0>();
diff --git a/gcc/testsuite/g++.dg/cpp0x/deleted6.C b/gcc/testsuite/g++.dg/cpp0x/deleted6.C
new file mode 100644
index 00000000000..af25b505db7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/deleted6.C
@@ -0,0 +1,9 @@
+// PR c++/58582
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+ template<int> void foo() = delete;
+};
+
+template void A::foo<0>();
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const3.C
new file mode 100644
index 00000000000..a1ffaddc4a7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const3.C
@@ -0,0 +1,38 @@
+// PR c++/60992
+// { dg-do compile { target c++11 } }
+
+struct ScopeGuardGenerator { };
+
+struct FF
+{
+ template < class F, class ... Ts >
+ void
+ operator () (F & ...)
+ {
+ const int n = sizeof ... (Ts) + 1;
+ void *mutexes[n];
+ auto _on_scope_exit_var_0 =
+ ScopeGuardGenerator () + [&mutexes] { };
+ }
+};
+
+template < class F >
+int operator+ (ScopeGuardGenerator, F) { return 1; }
+
+struct D
+{
+ template < class T0, class T1, class T2, class ... T >
+ void
+ operator () (T0, T1, const T2 & t2, T & ... t)
+ {
+ base (t2, t ...);
+ }
+ FF base;
+};
+
+D run_with_locks;
+
+void Fn ()
+{
+ run_with_locks ([] { }, 0, 0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58419.c b/gcc/testsuite/gcc.c-torture/execute/pr58419.c
index 69cc0401dc1..78bf437eb6b 100644
--- a/gcc/testsuite/gcc.c-torture/execute/pr58419.c
+++ b/gcc/testsuite/gcc.c-torture/execute/pr58419.c
@@ -1,4 +1,9 @@
-int printf(const char *, ...);
+__attribute__((__noinline__))
+void
+dummy ()
+{
+ asm volatile("");
+}
int a, g, i, k, *p;
signed char b;
@@ -31,6 +36,6 @@ main ()
*l = a;
g = foo (*m = k && *d, 1 > i) || bar ();
}
- getpid();
+ dummy();
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/declspec-13.c b/gcc/testsuite/gcc.dg/declspec-13.c
index a325c0d8831..3b4e315ef35 100644
--- a/gcc/testsuite/gcc.dg/declspec-13.c
+++ b/gcc/testsuite/gcc.dg/declspec-13.c
@@ -36,43 +36,53 @@ long double long x3; /* { dg-error "both 'long long' and 'double' in declaration
short long x4; /* { dg-error "both 'long' and 'short' in declaration specifiers" } */
void long x5; /* { dg-error "both 'long' and 'void' in declaration specifiers" } */
_Bool long x6; /* { dg-error "both 'long' and '_Bool' in declaration specifiers" } */
+/* { dg-warning "ISO C90 does not support boolean types" "C90" { target *-*-* } 38 } */
char long x7; /* { dg-error "both 'long' and 'char' in declaration specifiers" } */
float long x8; /* { dg-error "both 'long' and 'float' in declaration specifiers" } */
long short x9; /* { dg-error "both 'long' and 'short' in declaration specifiers" } */
void short x10; /* { dg-error "both 'short' and 'void' in declaration specifiers" } */
_Bool short x11; /* { dg-error "both 'short' and '_Bool' in declaration specifiers" } */
+/* { dg-warning "ISO C90 does not support boolean types" "C90" { target *-*-* } 44 } */
char short x12; /* { dg-error "both 'short' and 'char' in declaration specifiers" } */
float short x13; /* { dg-error "both 'short' and 'float' in declaration specifiers" } */
double short x14; /* { dg-error "both 'short' and 'double' in declaration specifiers" } */
unsigned signed x15; /* { dg-error "both 'signed' and 'unsigned' in declaration specifiers" } */
void signed x16; /* { dg-error "both 'signed' and 'void' in declaration specifiers" } */
_Bool signed x17; /* { dg-error "both 'signed' and '_Bool' in declaration specifiers" } */
+/* { dg-warning "ISO C90 does not support boolean types" "C90" { target *-*-* } 51 } */
float signed x18; /* { dg-error "both 'signed' and 'float' in declaration specifiers" } */
double signed x19; /* { dg-error "both 'signed' and 'double' in declaration specifiers" } */
signed unsigned x20; /* { dg-error "both 'signed' and 'unsigned' in declaration specifiers" } */
void unsigned x21; /* { dg-error "both 'unsigned' and 'void' in declaration specifiers" } */
_Bool unsigned x22; /* { dg-error "both 'unsigned' and '_Bool' in declaration specifiers" } */
+/* { dg-warning "ISO C90 does not support boolean types" "C90" { target *-*-* } 57 } */
float unsigned x23; /* { dg-error "both 'unsigned' and 'float' in declaration specifiers" } */
double unsigned x24; /* { dg-error "both 'unsigned' and 'double' in declaration specifiers" } */
void _Complex x25; /* { dg-error "both 'complex' and 'void' in declaration specifiers" } */
-/* { dg-warning "ISO C90 does not support complex types" "C90" { target *-*-* } 57 } */
+/* { dg-warning "ISO C90 does not support complex types" "C90" { target *-*-* } 61 } */
_Bool _Complex x26; /* { dg-error "both 'complex' and '_Bool' in declaration specifiers" } */
-/* { dg-warning "ISO C90 does not support complex types" "C90" { target *-*-* } 59 } */
+/* { dg-warning "ISO C90 does not support complex types" "C90" { target *-*-* } 63 } */
+/* { dg-warning "ISO C90 does not support boolean types" "C90" { target *-*-* } 63 } */
long void x27; /* { dg-error "both 'long' and 'void' in declaration specifiers" } */
short void x28; /* { dg-error "both 'short' and 'void' in declaration specifiers" } */
signed void x29; /* { dg-error "both 'signed' and 'void' in declaration specifiers" } */
unsigned void x30; /* { dg-error "both 'unsigned' and 'void' in declaration specifiers" } */
_Complex void x31; /* { dg-error "both 'complex' and 'void' in declaration specifiers" } */
-/* { dg-warning "ISO C90 does not support complex types" "C90" { target *-*-* } 66 } */
-/* { dg-warning "ISO C does not support plain 'complex' meaning 'double complex'" "complex" { target *-*-* } 66 } */
+/* { dg-warning "ISO C90 does not support complex types" "C90" { target *-*-* } 71 } */
+/* { dg-warning "ISO C does not support plain 'complex' meaning 'double complex'" "complex" { target *-*-* } 71 } */
long _Bool x32; /* { dg-error "both 'long' and '_Bool' in declaration specifiers" } */
+/* { dg-warning "ISO C90 does not support boolean types" "C90" { target *-*-* } 74 } */
short _Bool x33; /* { dg-error "both 'short' and '_Bool' in declaration specifiers" } */
+/* { dg-warning "ISO C90 does not support boolean types" "C90" { target *-*-* } 76 } */
signed _Bool x34; /* { dg-error "both 'signed' and '_Bool' in declaration specifiers" } */
+/* { dg-warning "ISO C90 does not support boolean types" "C90" { target *-*-* } 78 } */
unsigned _Bool x35; /* { dg-error "both 'unsigned' and '_Bool' in declaration specifiers" } */
+/* { dg-warning "ISO C90 does not support boolean types" "C90" { target *-*-* } 80 } */
_Complex _Bool x36; /* { dg-error "both 'complex' and '_Bool' in declaration specifiers" } */
-/* { dg-warning "ISO C90 does not support complex types" "C90" { target *-*-* } 73 } */
-/* { dg-warning "ISO C does not support plain 'complex' meaning 'double complex'" "complex" { target *-*-* } 73 } */
+/* { dg-warning "ISO C90 does not support complex types" "C90" { target *-*-* } 82 } */
+/* { dg-warning "ISO C90 does not support boolean types" "C90" { target *-*-* } 82 } */
+/* { dg-warning "ISO C does not support plain 'complex' meaning 'double complex'" "complex" { target *-*-* } 82 } */
long char x37; /* { dg-error "both 'long' and 'char' in declaration specifiers" } */
short char x38; /* { dg-error "both 'short' and 'char' in declaration specifiers" } */
long float x39; /* { dg-error "both 'long' and 'float' in declaration specifiers" } */
@@ -80,7 +90,7 @@ short float x40; /* { dg-error "both 'short' and 'float' in declaration specifie
signed float x41; /* { dg-error "both 'signed' and 'float' in declaration specifiers" } */
unsigned float x42; /* { dg-error "both 'unsigned' and 'float' in declaration specifiers" } */
long long double x43; /* { dg-error "both 'long long' and 'double' in declaration specifiers" } */
-/* { dg-warning "ISO C90 does not support 'long long'" "C90" { target *-*-* } 82 } */
+/* { dg-warning "ISO C90 does not support 'long long'" "C90" { target *-*-* } 92 } */
short double x44; /* { dg-error "both 'short' and 'double' in declaration specifiers" } */
signed double x45; /* { dg-error "both 'signed' and 'double' in declaration specifiers" } */
unsigned double x46; /* { dg-error "both 'unsigned' and 'double' in declaration specifiers" } */
diff --git a/gcc/testsuite/gcc.dg/hoist-register-pressure-1.c b/gcc/testsuite/gcc.dg/hoist-register-pressure-1.c
index f5b5302b3c5..4aabcb78daf 100644
--- a/gcc/testsuite/gcc.dg/hoist-register-pressure-1.c
+++ b/gcc/testsuite/gcc.dg/hoist-register-pressure-1.c
@@ -1,14 +1,18 @@
/* { dg-options "-Os -fdump-rtl-hoist" } */
-/* { dg-final { scan-rtl-dump "PRE/HOIST: end of bb .* copying expression" "hoist" { target { nonpic } } } } */
+/* The rtl hoist pass requires that the expression to be hoisted can
+ be assigned without clobbering cc. For a PLUS rtx on S/390 this
+ requires a load address instruction which is fine on 64 bit but
+ cannot be used on 31 bit since it does a 31 bit add only. */
+/* { dg-final { scan-rtl-dump "PRE/HOIST: end of bb .* copying expression" "hoist" { target { { ! s390-*-* } && nonpic } } } } */
/* { dg-final { cleanup-rtl-dump "hoist" } } */
#define BUF 100
-int a[BUF];
+long a[BUF];
-void com (int);
-void bar (int);
+void com (long);
+void bar (long);
-int foo (int x, int y, int z)
+long foo (long x, long y, long z)
{
/* "x+y" won't be hoisted if "-fira-hoist-pressure" is disabled,
because its rtx_cost is too small. */
diff --git a/gcc/testsuite/gcc.dg/hoist-register-pressure-2.c b/gcc/testsuite/gcc.dg/hoist-register-pressure-2.c
index 30408f318c4..f1c927ec434 100644
--- a/gcc/testsuite/gcc.dg/hoist-register-pressure-2.c
+++ b/gcc/testsuite/gcc.dg/hoist-register-pressure-2.c
@@ -1,14 +1,18 @@
/* { dg-options "-Os -fdump-rtl-hoist" } */
-/* { dg-final { scan-rtl-dump "PRE/HOIST: end of bb .* copying expression" "hoist" } } */
+/* The rtl hoist pass requires that the expression to be hoisted can
+ be assigned without clobbering cc. For a PLUS rtx on S/390 this
+ requires a load address instruction which is fine on 64 bit but
+ cannot be used on 31 bit since it does a 31 bit add only. */
+/* { dg-final { scan-rtl-dump "PRE/HOIST: end of bb .* copying expression" "hoist" { target { ! s390-*-* } } } } */
/* { dg-final { cleanup-rtl-dump "hoist" } } */
#define BUF 100
-int a[BUF];
+long a[BUF];
-void com (int);
-void bar (int);
+void com (long);
+void bar (long);
-int foo (int x, int y, int z)
+long foo (long x, long y, long z)
{
/* "x+y" won't be hoisted if "-fira-hoist-pressure" is disabled,
because its rtx_cost is too small. */
diff --git a/gcc/testsuite/gcc.dg/hoist-register-pressure-3.c b/gcc/testsuite/gcc.dg/hoist-register-pressure-3.c
index b050f89823f..24abaa6ade4 100644
--- a/gcc/testsuite/gcc.dg/hoist-register-pressure-3.c
+++ b/gcc/testsuite/gcc.dg/hoist-register-pressure-3.c
@@ -1,14 +1,18 @@
/* { dg-options "-Os -fdump-rtl-hoist" } */
-/* { dg-final { scan-rtl-dump "PRE/HOIST: end of bb .* copying expression" "hoist" } } */
+/* The rtl hoist pass requires that the expression to be hoisted can
+ be assigned without clobbering cc. For a PLUS rtx on S/390 this
+ requires a load address instruction which is fine on 64 bit but
+ cannot be used on 31 bit since it does a 31 bit add only. */
+/* { dg-final { scan-rtl-dump "PRE/HOIST: end of bb .* copying expression" "hoist" { target { ! s390-*-* } } } } */
/* { dg-final { cleanup-rtl-dump "hoist" } } */
#define BUF 100
-int a[BUF];
+long a[BUF];
-void com (int);
-void bar (int);
+void com (long);
+void bar (long);
-int foo (int x, int y, int z)
+long foo (long x, long y, long z)
{
/* "x+y" won't be hoisted if "-fira-hoist-pressure" is disabled,
because its rtx_cost is too small. */
diff --git a/gcc/testsuite/gcc.dg/pr25801.c b/gcc/testsuite/gcc.dg/pr25801.c
new file mode 100644
index 00000000000..10b53d33e19
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr25801.c
@@ -0,0 +1,44 @@
+/* PR c/25801 */
+/* { dg-do compile } */
+/* { dg-options "-std=c99" } */
+
+int (*a)[];
+struct S *s;
+union U *u;
+enum E *e;
+
+void
+f (void)
+{
+ a++; /* { dg-error "increment of pointer to an incomplete type" } */
+ ++a; /* { dg-error "increment of pointer to an incomplete type" } */
+ a--; /* { dg-error "decrement of pointer to an incomplete type" } */
+ --a; /* { dg-error "decrement of pointer to an incomplete type" } */
+ a += 1; /* { dg-error "invalid use of array with unspecified bounds" } */
+ a -= 1; /* { dg-error "invalid use of array with unspecified bounds" } */
+ a - a; /* { dg-error "arithmetic on pointer to an incomplete type" } */
+
+ s++; /* { dg-error "increment of pointer to an incomplete type" } */
+ ++s; /* { dg-error "increment of pointer to an incomplete type" } */
+ s--; /* { dg-error "decrement of pointer to an incomplete type" } */
+ --s; /* { dg-error "decrement of pointer to an incomplete type" } */
+ s += 1; /* { dg-error "invalid use of undefined type" } */
+ s -= 1; /* { dg-error "invalid use of undefined type" } */
+ s - s; /* { dg-error "arithmetic on pointer to an incomplete type" } */
+
+ u++; /* { dg-error "increment of pointer to an incomplete type" } */
+ ++u; /* { dg-error "increment of pointer to an incomplete type" } */
+ u--; /* { dg-error "decrement of pointer to an incomplete type" } */
+ --u; /* { dg-error "decrement of pointer to an incomplete type" } */
+ u += 1; /* { dg-error "invalid use of undefined type" } */
+ u -= 1; /* { dg-error "invalid use of undefined type" } */
+ u - u; /* { dg-error "arithmetic on pointer to an incomplete type" } */
+
+ e++; /* { dg-error "increment of pointer to an incomplete type" } */
+ ++e; /* { dg-error "increment of pointer to an incomplete type" } */
+ e--; /* { dg-error "decrement of pointer to an incomplete type" } */
+ --e; /* { dg-error "decrement of pointer to an incomplete type" } */
+ e += 1; /* { dg-error "invalid use of undefined type" } */
+ e -= 1; /* { dg-error "invalid use of undefined type" } */
+ e - e; /* { dg-error "arithmetic on pointer to an incomplete type" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr29467.c b/gcc/testsuite/gcc.dg/pr29467.c
new file mode 100644
index 00000000000..eaf09c2344d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr29467.c
@@ -0,0 +1,13 @@
+/* PR c/29467 */
+/* { dg-do compile } */
+/* { dg-options "-std=c89 -Wpedantic" } */
+
+_Bool b; /* { dg-warning "ISO C90 does not support boolean types" } */
+typedef _Bool B; /* { dg-warning "ISO C90 does not support boolean types" } */
+static _Bool sb; /* { dg-warning "ISO C90 does not support boolean types" } */
+
+_Bool /* { dg-warning "ISO C90 does not support boolean types" } */
+foo (_Bool bp) /* { dg-warning "ISO C90 does not support boolean types" } */
+{
+ _Bool bl; /* { dg-warning "ISO C90 does not support boolean types" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr43245.c b/gcc/testsuite/gcc.dg/pr43245.c
new file mode 100644
index 00000000000..85490ffaa82
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr43245.c
@@ -0,0 +1,18 @@
+/* PR c/43245 */
+/* { dg-do compile } */
+/* { dg-options "-Wno-discarded-qualifiers" } */
+
+void
+foo (char *p)
+{
+}
+
+char *
+bar (void)
+{
+ const char *s = "foo";
+ char *s1 = s;
+ s1 = s;
+ foo (s);
+ return s;
+}
diff --git a/gcc/testsuite/gcc.dg/pr56989.c b/gcc/testsuite/gcc.dg/pr56989.c
new file mode 100644
index 00000000000..beb980678b2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr56989.c
@@ -0,0 +1,19 @@
+/* PR c/56989 */
+/* { dg-do compile } */
+
+extern void voidf (void);
+extern int intf (void);
+
+int
+f (void)
+{
+ if (intf () < 0
+ || voidf () < 0) /* { dg-error "10:void value not ignored as it ought to be" } */
+ return 1;
+
+ if (voidf () < 0 /* { dg-error "7:void value not ignored as it ought to be" } */
+ || intf () < 0)
+ return 1;
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr60257.c b/gcc/testsuite/gcc.dg/pr60257.c
new file mode 100644
index 00000000000..46c29b0543f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr60257.c
@@ -0,0 +1,37 @@
+/* PR c/60257 */
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat -Woverride-init" } */
+/* { dg-prune-output ".*near initialization for.*" } */
+
+enum E1 { A };
+enum E2 { B };
+
+struct S
+{
+ enum E1 e: 3;
+};
+
+struct S s[] =
+{
+ { B } /* { dg-warning "5:enum conversion in initialization is invalid in C\[+\]\[+\]" } */
+};
+
+union U {
+ int i;
+ long long int l;
+};
+
+struct R {
+ int a;
+};
+
+void
+foo (int i)
+{
+ union U u = { .i = ++i, .l = 1 }; /* { dg-warning "32:initialized field with side-effects overwritten" } */
+ union U u2 = { .i = 1, .l = 3 }; /* { dg-warning "31:initialized field overwritten" } */
+ int a[] = { i++, [0] = 1 }; /* { dg-warning "26:initialized field with side-effects overwritten" } */
+ int a2[] = { i, [0] = 1 }; /* { dg-warning "25:initialized field overwritten" } */
+ struct R r = { 1, .a = 2 }; /* { dg-warning "26:initialized field overwritten" } */
+ struct R r2 = { ++i, .a = 2 }; /* { dg-warning "29:initialized field with side-effects overwritten" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr60784.c b/gcc/testsuite/gcc.dg/pr60784.c
new file mode 100644
index 00000000000..82b512f7c2e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr60784.c
@@ -0,0 +1,25 @@
+/* PR c/60784 */
+/* { dg-do compile } */
+/* { dg-options "-Wextra -std=c99" } */
+
+struct A { int i, j; };
+struct B { struct A a; } b1 = { .a.i = 1, .a.j = 1 };
+struct B b2 = { .a.i = 1 };
+
+struct C { struct { int a, b; }; } c1 = { .a = 4, .b = 2 };
+struct C c2 = { .a = 4, .b = 2 };
+
+struct D { struct A a; };
+struct E { struct D d; };
+struct F { struct E e; } f1 = { .e.d.a.i = 8 };
+struct F f2 = { .e.d.a.i = 8, .e.d.a.j = 3 };
+
+struct G {
+ struct {
+ struct {
+ struct {
+ int a, b, c, d, e, f;
+ };
+ };
+ };
+} g = { .b = 2 };
diff --git a/gcc/testsuite/gcc.dg/pr60915.c b/gcc/testsuite/gcc.dg/pr60915.c
new file mode 100644
index 00000000000..2ed0a5f10fe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr60915.c
@@ -0,0 +1,7 @@
+/* PR c/60915 */
+/* { dg-do compile } */
+
+void /* { dg-error "attributes should be specified before the declarator in a function definition" } */
+foo (void) __attribute__((__visibility__("default")))
+{
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr61010.c b/gcc/testsuite/gcc.dg/torture/pr61010.c
new file mode 100644
index 00000000000..ed5653982cb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr61010.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+int main (void)
+{
+ int a = 0;
+ unsigned b = (a * 64 & 192) | 63U;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c
index e85a24420ee..cafdf13909e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c
@@ -75,6 +75,6 @@ bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b,
-> "kill_elt->indx == b_elt->indx" in the second condition,
skipping the known-true "b_elt && kill_elt" in the second
condition. */
-/* { dg-final { scan-tree-dump-times "Threaded" 4 "dom1" { target logical_op_short_circuit xfail logical_op_short_circuit } } } */
+/* { dg-final { scan-tree-dump-times "Threaded" 4 "dom1" { target logical_op_short_circuit } } } */
/* { dg-final { cleanup-tree-dump "dom1" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/cond-reduc-1.c b/gcc/testsuite/gcc.dg/vect/cond-reduc-1.c
new file mode 100644
index 00000000000..981f6b06480
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/cond-reduc-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+#define N 512
+int a[N];
+int foo()
+{
+ int i, res = 0;
+ for (i=0; i<N; i++)
+ {
+ if (a[i] != 0)
+ res += 1;
+ }
+ return res;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/cond-reduc-2.c b/gcc/testsuite/gcc.dg/vect/cond-reduc-2.c
new file mode 100644
index 00000000000..c329861c63c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/cond-reduc-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+#define N 512
+int a[N], b[N];
+void foo(int k)
+{
+ int i, res = 0;
+ for (i=0; i<N; i++)
+ {
+ if (b[i] != 0)
+ res += b[i];
+ }
+ a[k] = sum;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpf32_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpf32_1.c
new file mode 100644
index 00000000000..723c86a16be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpf32_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpf32' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpf32.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.32\[ \t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpp16_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpp16_1.c
new file mode 100644
index 00000000000..c7ad757b55e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpp16_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpp16' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpp16.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.16\[ \t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpp8_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpp8_1.c
new file mode 100644
index 00000000000..670b5506779
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpp8_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpp8' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpp8.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.8\[ \t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpqf32_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpqf32_1.c
new file mode 100644
index 00000000000..53147f1a43e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpqf32_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpQf32' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpqf32.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.32\[ \t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpqp16_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpqp16_1.c
new file mode 100644
index 00000000000..feef15af27e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpqp16_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpQp16' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpqp16.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.16\[ \t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpqp8_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpqp8_1.c
new file mode 100644
index 00000000000..db98f353354
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpqp8_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpQp8' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpqp8.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.8\[ \t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpqs16_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpqs16_1.c
new file mode 100644
index 00000000000..808d562732b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpqs16_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpQs16' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpqs16.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.16\[ \t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpqs32_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpqs32_1.c
new file mode 100644
index 00000000000..7adf5f9b91f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpqs32_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpQs32' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpqs32.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.32\[ \t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpqs8_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpqs8_1.c
new file mode 100644
index 00000000000..9d0256a632a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpqs8_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpQs8' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpqs8.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.8\[ \t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpqu16_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpqu16_1.c
new file mode 100644
index 00000000000..23106edf529
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpqu16_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpQu16' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpqu16.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.16\[ \t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpqu32_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpqu32_1.c
new file mode 100644
index 00000000000..0002fdfcbd9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpqu32_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpQu32' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpqu32.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.32\[ \t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpqu8_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpqu8_1.c
new file mode 100644
index 00000000000..f8d19dc5582
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpqu8_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpQu8' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpqu8.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.8\[ \t\]+\[qQ\]\[0-9\]+, ?\[qQ\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzps16_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzps16_1.c
new file mode 100644
index 00000000000..6e3f2eb118b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzps16_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzps16' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzps16.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.16\[ \t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzps32_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzps32_1.c
new file mode 100644
index 00000000000..372c3938754
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzps32_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzps32' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzps32.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.32\[ \t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzps8_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzps8_1.c
new file mode 100644
index 00000000000..3338477778e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzps8_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzps8' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzps8.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.8\[ \t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpu16_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpu16_1.c
new file mode 100644
index 00000000000..378b5a9df91
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpu16_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpu16' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpu16.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.16\[ \t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpu32_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpu32_1.c
new file mode 100644
index 00000000000..ebb0d6b5fa6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpu32_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpu32' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpu32.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.32\[ \t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/arm/simd/vuzpu8_1.c b/gcc/testsuite/gcc.target/arm/simd/vuzpu8_1.c
new file mode 100644
index 00000000000..82719a503c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/simd/vuzpu8_1.c
@@ -0,0 +1,12 @@
+/* Test the `vuzpu8' ARM Neon intrinsic. */
+
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-save-temps -O1 -fno-inline" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+#include "../../aarch64/simd/vuzpu8.x"
+
+/* { dg-final { scan-assembler-times "vuzp\.8\[ \t\]+\[dD\]\[0-9\]+, ?\[dD\]\[0-9\]+!?\(?:\[ \t\]+@\[a-zA-Z0-9 \]+\)?\n" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pack02.c b/gcc/testsuite/gcc.target/powerpc/pack02.c
index 74b6cd04dcc..584d6c29205 100644
--- a/gcc/testsuite/gcc.target/powerpc/pack02.c
+++ b/gcc/testsuite/gcc.target/powerpc/pack02.c
@@ -1,8 +1,8 @@
/* { dg-do run { target { powerpc*-*-linux* } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
-/* { dg-require-effective-target vsx_hw } */
-/* { dg-options "-O2" } */
+/* { dg-require-effective-target powerpc_fprs } */
+/* { dg-options "-O2 -mhard-float" } */
#include <stddef.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.target/powerpc/pack03.c b/gcc/testsuite/gcc.target/powerpc/pack03.c
index 59f0e74ba9c..bc582f232d6 100644
--- a/gcc/testsuite/gcc.target/powerpc/pack03.c
+++ b/gcc/testsuite/gcc.target/powerpc/pack03.c
@@ -1,8 +1,8 @@
/* { dg-do run { target { powerpc*-*-linux* } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
-/* { dg-require-effective-target vsx_hw } */
-/* { dg-options "-O2" } */
+/* { dg-require-effective-target dfprt } */
+/* { dg-options "-O2 -mhard-dfp" } */
#include <stddef.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.target/s390/leaf-profile.c b/gcc/testsuite/gcc.target/s390/leaf-profile.c
new file mode 100644
index 00000000000..60477400757
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/leaf-profile.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z900 -pg" } */
+
+int
+foo ()
+{
+}
+/* Make sure no stack frame is generated. */
+/* { dg-final { scan-assembler-not "ahi" { target s390-*-* } } } */
+/* { dg-final { scan-assembler-not "aghi" { target s390x-*-* } } } */
diff --git a/gcc/testsuite/gfortran.dg/bind_c_usage_24_c.c b/gcc/testsuite/gfortran.dg/bind_c_usage_24_c.c
index ffc90b728b5..65754f3415d 100644
--- a/gcc/testsuite/gfortran.dg/bind_c_usage_24_c.c
+++ b/gcc/testsuite/gfortran.dg/bind_c_usage_24_c.c
@@ -1,11 +1,12 @@
/* Compiled and linked by bind_c.f90. */
#include <stdlib.h>
+#include <stdbool.h>
-void subtest (_Bool, int *);
+void subtest (bool, int *);
void
-c_proc (_Bool present, int *val)
+c_proc (bool present, int *val)
{
int val2;
if (!present && val)
diff --git a/gcc/testsuite/gfortran.dg/c_f_pointer_logical_driver.c b/gcc/testsuite/gfortran.dg/c_f_pointer_logical_driver.c
index e3044c92e43..a05449dc181 100644
--- a/gcc/testsuite/gfortran.dg/c_f_pointer_logical_driver.c
+++ b/gcc/testsuite/gfortran.dg/c_f_pointer_logical_driver.c
@@ -4,13 +4,13 @@
#define NUM_ELEMS 10
-void test_scalar(_Bool *my_c_bool_ptr);
-void test_array(_Bool *my_bool_array, int num_elems);
+void test_scalar(bool *my_c_bool_ptr);
+void test_array(bool *my_bool_array, int num_elems);
int main(int argc, char **argv)
{
- _Bool my_bool = true;
- _Bool my_bool_array[NUM_ELEMS];
+ bool my_bool = true;
+ bool my_bool_array[NUM_ELEMS];
int i;
test_scalar(&my_bool);
diff --git a/gcc/testsuite/gfortran.dg/coarray/codimension.f90 b/gcc/testsuite/gfortran.dg/coarray/codimension.f90
new file mode 100644
index 00000000000..706048f33ef
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray/codimension.f90
@@ -0,0 +1,49 @@
+! { dg-do run }
+!
+! Based on coarray_lib_token_4.f90 but checking whether the bounds
+! are correctly handled.
+!
+program test_caf
+ implicit none
+ integer, allocatable :: A(:)[:]
+ integer, save :: B(3)[*]
+ integer :: i
+
+ allocate (A(3)[*])
+ A = [1, 2, 3 ]
+ B = [9, 7, 4 ]
+ call foo (A, A, test=1)
+ call foo (A(2:3), B, test=2)
+ call foo (B, A, test=3)
+contains
+ subroutine foo(x, y, test)
+ integer :: x(:)[*]
+ integer, contiguous :: y(:)[*]
+ integer :: test
+ integer :: i, j
+ call bar (x)
+ call expl (y)
+ i = lcobound(x, dim=1)
+ j = ucobound(x, dim=1)
+ if (i /= 1 .or. j /= num_images()) call abort()
+ i = lcobound(y, dim=1)
+ j = ucobound(y, dim=1)
+ if (i /= 1 .or. j /= num_images()) call abort()
+ end subroutine foo
+
+ subroutine bar(y)
+ integer :: y(:)[*]
+ integer :: i, j
+ i = lcobound(y, dim=1)
+ j = ucobound(y, dim=1)
+ if (i /= 1 .or. j /= num_images()) call abort()
+ end subroutine bar
+
+ subroutine expl(z)
+ integer :: z(*)[*]
+ integer :: i, j
+ i = lcobound(z, dim=1)
+ j = ucobound(z, dim=1)
+ if (i /= 1 .or. j /= num_images()) call abort()
+ end subroutine expl
+end program test_caf
diff --git a/gcc/testsuite/gfortran.dg/coarray_lib_this_image_1.f90 b/gcc/testsuite/gfortran.dg/coarray_lib_this_image_1.f90
new file mode 100644
index 00000000000..2fcaacde394
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray_lib_this_image_1.f90
@@ -0,0 +1,27 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib -fdump-tree-original" }
+!
+
+ implicit none
+ real :: x(2)[*]
+ call bar(x)
+contains
+ subroutine bar(x)
+ integer :: mylcobound, myucobound, mylbound, mythis_image
+ real :: x(2)[5:*]
+ mylcobound = lcobound(x,dim=1)
+ myucobound = ucobound(x,dim=1)
+ mylbound = lbound(x,dim=1)
+ mythis_image = this_image()
+ end subroutine bar
+end
+
+! { dg-final { scan-tree-dump-times "bar \\(real\\(kind=4\\)\\\[2\\\] \\* restrict x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) caf_offset..\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "mylcobound = 5;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "parm...dim\\\[1\\\].lbound = 5;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "myucobound =\[^\n\r\]* parm...dim\\\[1\\\].lbound \\+ \[^\n\r]*_gfortran_caf_num_images \\(0, -1\\).? \\+ -?\[0-9\]+\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "mylbound = 1;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "mythis_image = _gfortran_caf_this_image \\(0\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "bar \\(x, caf_token.., 0\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "_gfortran_caf_init \\(&argc, &argv\\);" 1 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/coarray_lib_this_image_2.f90 b/gcc/testsuite/gfortran.dg/coarray_lib_this_image_2.f90
new file mode 100644
index 00000000000..4afabaadff5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray_lib_this_image_2.f90
@@ -0,0 +1,27 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib -fdump-tree-original" }
+!
+
+ implicit none
+ real :: x(2)[*]
+ call bar(x)
+contains
+ subroutine bar(x)
+ integer :: mylcobound, myucobound, mylbound, mythis_image
+ real :: x(:)[5:*]
+ mylcobound = lcobound(x,dim=1)
+ myucobound = ucobound(x,dim=1)
+ mylbound = lbound(x,dim=1)
+ mythis_image = this_image()
+ end subroutine bar
+end
+
+! { dg-final { scan-tree-dump-times "bar \\(struct array1_real\\(kind=4\\) & restrict x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) caf_offset..\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "mylcobound = 5;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "parm...dim\\\[1\\\].lbound = 5;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "myucobound =\[^\n\r\]* parm...dim\\\[1\\\].lbound \\+ \[^\n\r\]*_gfortran_caf_num_images \\(0, -1\\).? \\+ -?\[0-9\]+\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "mylbound = parm...dim\\\[0\\\].stride >= 0 && parm...dim\\\[0\\\].ubound >= parm...dim\\\[0\\\].lbound \\|\\| parm...dim\\\[0\\\].stride < 0 \\?\[^\n\r\]* parm...dim\\\[0\\\].lbound : 1;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "mythis_image = _gfortran_caf_this_image \\(0\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "bar \\(&parm.\[0-9\]+, caf_token.\[0-9\]+, \\(integer\\(kind=\[48\]\\)\\) parm.\[0-9\]+.data - \\(integer\\(kind=\[48\]\\)\\) x\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "_gfortran_caf_init \\(&argc, &argv\\);" 1 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/coarray_lib_token_4.f90 b/gcc/testsuite/gfortran.dg/coarray_lib_token_4.f90
index 43da9f4c909..9e445f4a0de 100644
--- a/gcc/testsuite/gfortran.dg/coarray_lib_token_4.f90
+++ b/gcc/testsuite/gfortran.dg/coarray_lib_token_4.f90
@@ -35,9 +35,9 @@ end program test_caf
! { dg-final { scan-tree-dump-times "expl \\(integer\\(kind=4\\).0:. . restrict z, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } }
!
-! { dg-final { scan-tree-dump-times "bar \\(struct array2_integer\\(kind=4\\) & restrict y, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "bar \\(struct array1_integer\\(kind=4\\) & restrict y, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } }
!
-! { dg-final { scan-tree-dump-times "foo \\(struct array2_integer\\(kind=4\\) & restrict x, struct array2_integer\\(kind=4\\) & restrict y, integer\\(kind=4\\) & restrict test, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "foo \\(struct array1_integer\\(kind=4\\) & restrict x, struct array1_integer\\(kind=4\\) & restrict y, integer\\(kind=4\\) & restrict test, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+, void . restrict caf_token.\[0-9\]+, integer\\(kind=.\\) caf_offset.\[0-9\]+\\)" 1 "original" } }
!
! { dg-final { scan-tree-dump-times "bar \\(&parm.\[0-9\]+, caf_token.\[0-9\]+, \\(\\(integer\\(kind=.\\)\\) parm.\[0-9\]+.data - \\(integer\\(kind=.\\)\\) x.\[0-9\]+\\) \\+ caf_offset.\[0-9\]+\\);" 1 "original" } }
!
diff --git a/gcc/testsuite/gfortran.dg/coarray_poly_4.f90 b/gcc/testsuite/gfortran.dg/coarray_poly_4.f90
new file mode 100644
index 00000000000..ceb1c858301
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray_poly_4.f90
@@ -0,0 +1,23 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib -fdump-tree-original" }
+
+subroutine test(i)
+type t
+ real, allocatable :: x[:]
+end type t
+
+interface
+ subroutine sub(y)
+ import
+ real :: y[*]
+ end subroutine sub
+end interface
+
+integer :: i
+type(t), save :: var
+allocate(var%x[*])
+call sub(var%x)
+end subroutine test
+
+! { dg-final { scan-tree-dump-times "sub \\(\\(real\\(kind=4\\) \\*\\) var.x.data, var.x.token, 0\\);" 1 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/coarray_poly_5.f90 b/gcc/testsuite/gfortran.dg/coarray_poly_5.f90
new file mode 100644
index 00000000000..29c9c8c3140
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray_poly_5.f90
@@ -0,0 +1,14 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib -fdump-tree-original" }
+
+subroutine test(x)
+type t
+ real, allocatable :: x[:]
+end type t
+
+class(t) :: x
+allocate(x%x[*])
+end subroutine test
+
+! { dg-final { scan-tree-dump-times "x->_data->x.data = _gfortran_caf_register \\(4, 1, &x->_data->x.token, 0B, 0B, 0\\);" 1 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/coarray_poly_6.f90 b/gcc/testsuite/gfortran.dg/coarray_poly_6.f90
new file mode 100644
index 00000000000..3fff5e0d59d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray_poly_6.f90
@@ -0,0 +1,22 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib -fdump-tree-original" }
+!
+ implicit none
+ type t
+ end type t
+ class(t), allocatable :: y[:]
+ call bar()
+ call foo(y)
+contains
+ subroutine bar(x)
+ class(t), optional :: x[*]
+ end subroutine bar
+ subroutine foo(x)
+ class(t) :: x[*]
+ end subroutine foo
+end
+! { dg-final { scan-tree-dump-times "foo \\(struct __class_MAIN___T_0_1t & restrict x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) caf_offset..\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "bar \\(struct __class_MAIN___T_0_1t \\* x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) caf_offset..\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "bar \\(0B, 0B, 0\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "foo \\(&class.., y._data._data.token, \\(integer\\(kind=\[48\]\\)\\) class..._data.data - \\(integer\\(kind=\[48\]\\)\\) y._data._data.data\\);" 1 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/coarray_poly_7.f90 b/gcc/testsuite/gfortran.dg/coarray_poly_7.f90
new file mode 100644
index 00000000000..b50319a0f36
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray_poly_7.f90
@@ -0,0 +1,22 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib -fdump-tree-original" }
+!
+ implicit none
+ type t
+ end type t
+ class(t), allocatable :: y(:)[:]
+ call bar()
+ call foo(y)
+contains
+ subroutine bar(x)
+ class(t), optional :: x(:)[*]
+ end subroutine bar
+ subroutine foo(x)
+ class(t) :: x(:)[*]
+ end subroutine foo
+end
+! { dg-final { scan-tree-dump-times "foo \\(struct __class_MAIN___T_1_1t & restrict x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) caf_offset..\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "bar \\(struct __class_MAIN___T_1_1t \\* x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) caf_offset..\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "bar \\(0B, 0B, 0\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "foo \\(&class.., y._data._data.token, \\(integer\\(kind=\[48\]\\)\\) class..._data.data - \\(integer\\(kind=\[48\]\\)\\) y._data._data.data\\);" 1 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/coarray_poly_8.f90 b/gcc/testsuite/gfortran.dg/coarray_poly_8.f90
new file mode 100644
index 00000000000..7775605732c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray_poly_8.f90
@@ -0,0 +1,22 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib -fdump-tree-original" }
+!
+ implicit none
+ type t
+ end type t
+ class(t), allocatable :: y(:)[:]
+ call bar()
+ call foo(y)
+contains
+ subroutine bar(x)
+ class(t), optional :: x(2)[*]
+ end subroutine bar
+ subroutine foo(x)
+ class(t) :: x(2)[*]
+ end subroutine foo
+end
+! { dg-final { scan-tree-dump-times "foo \\(struct __class_MAIN___T_1_1t & restrict x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) caf_offset..\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "bar \\(struct __class_MAIN___T_1_1t \\* x, void \\* restrict caf_token.., integer\\(kind=\[48\]\\) caf_offset..\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "bar \\(0B, 0B, 0\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "foo \\(&class.., y._data._data.token, \\(integer\\(kind=\[48\]\\)\\) class..._data.data - \\(integer\\(kind=\[48\]\\)\\) y._data._data.data\\);" 1 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/go.test/go-test.exp b/gcc/testsuite/go.test/go-test.exp
index 1bbbd8742e2..4400d405d06 100644
--- a/gcc/testsuite/go.test/go-test.exp
+++ b/gcc/testsuite/go.test/go-test.exp
@@ -676,8 +676,10 @@ proc go-gc-tests { } {
lappend del "[file rootname [file tail [lindex $p 1]]].o"
}
set dg-do-what-default "link"
- set go_compile_args $del
- go-torture-execute [lrange $last 1 end]
+ set go_compile_args ""
+ append go_compile_args [lrange $last 2 end]
+ append go_compile_args $del
+ go-torture-execute [lindex $last 1]
foreach f $del {
file delete $f
}
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 21a9f05c78b..5b08669f456 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -1386,6 +1386,144 @@ find_phi_replacement_condition (basic_block bb, tree *cond,
return first_edge->src;
}
+/* Returns true if def-stmt for phi argument ARG is simple increment/decrement
+ which is in predicated basic block.
+ In fact, the following PHI pattern is searching:
+ loop-header:
+ reduc_1 = PHI <..., reduc_2>
+ ...
+ if (...)
+ reduc_3 = ...
+ reduc_2 = PHI <reduc_1, reduc_3>
+
+ REDUC, OP0 and OP1 contain reduction stmt and its operands. */
+
+static bool
+is_cond_scalar_reduction (gimple phi, gimple *reduc,
+ tree *op0, tree *op1)
+{
+ tree lhs, r_op1, r_op2;
+ tree arg_0, arg_1;
+ gimple stmt;
+ gimple header_phi = NULL;
+ enum tree_code reduction_op;
+ struct loop *loop = gimple_bb (phi)->loop_father;
+ edge latch_e = loop_latch_edge (loop);
+
+ arg_0 = PHI_ARG_DEF (phi, 0);
+ arg_1 = PHI_ARG_DEF (phi, 1);
+ if (TREE_CODE (arg_0) != SSA_NAME || TREE_CODE (arg_1) != SSA_NAME)
+ return false;
+
+ if (gimple_code (SSA_NAME_DEF_STMT (arg_0)) == GIMPLE_PHI)
+ {
+ lhs = arg_1;
+ header_phi = SSA_NAME_DEF_STMT (arg_0);
+ stmt = SSA_NAME_DEF_STMT (arg_1);
+ }
+ else if (gimple_code (SSA_NAME_DEF_STMT (arg_1)) == GIMPLE_PHI)
+ {
+ lhs = arg_0;
+ header_phi = SSA_NAME_DEF_STMT (arg_1);
+ stmt = SSA_NAME_DEF_STMT (arg_0);
+ }
+ else
+ return false;
+ if (gimple_bb (header_phi) != loop->header)
+ return false;
+
+ if (PHI_ARG_DEF_FROM_EDGE (header_phi, latch_e) != PHI_RESULT (phi))
+ return false;
+
+ if (gimple_code (stmt) != GIMPLE_ASSIGN
+ || gimple_has_volatile_ops (stmt))
+ return false;
+
+ if (!is_predicated (gimple_bb (stmt)))
+ return false;
+
+ if (!has_single_use (lhs))
+ return false;
+
+ reduction_op = gimple_assign_rhs_code (stmt);
+ if (reduction_op != PLUS_EXPR && reduction_op != MINUS_EXPR)
+ return false;
+ r_op1 = gimple_assign_rhs1 (stmt);
+ r_op2 = gimple_assign_rhs2 (stmt);
+
+ /* Make R_OP1 to hold reduction variable. */
+ if (r_op2 == PHI_RESULT (header_phi)
+ && reduction_op == PLUS_EXPR)
+ {
+ tree tmp = r_op1;
+ r_op1 = r_op2;
+ r_op2 = tmp;
+ }
+ else if (r_op1 != PHI_RESULT (header_phi))
+ return false;
+
+ *op0 = r_op1; *op1 = r_op2;
+ *reduc = stmt;
+ return true;
+}
+
+/* Converts conditional scalar reduction into unconditional form, e.g.
+ bb_4
+ if (_5 != 0) goto bb_5 else goto bb_6
+ end_bb_4
+ bb_5
+ res_6 = res_13 + 1;
+ end_bb_5
+ bb_6
+ # res_2 = PHI <res_13(4), res_6(5)>
+ end_bb_6
+
+ will be converted into sequence
+ _ifc__1 = _5 != 0 ? 1 : 0;
+ res_2 = res_13 + _ifc__1;
+ Argument SWAP tells that arguments of conditional expression should be
+ swapped.
+ Returns rhs of resulting PHI assignment. */
+
+static tree
+convert_scalar_cond_reduction (gimple reduc, gimple_stmt_iterator *gsi,
+ tree cond, tree op0, tree op1, bool swap)
+{
+ gimple_stmt_iterator stmt_it;
+ gimple new_assign;
+ tree rhs;
+ tree rhs1 = gimple_assign_rhs1 (reduc);
+ tree tmp = make_temp_ssa_name (TREE_TYPE (rhs1), NULL, "_ifc_");
+ tree c;
+ tree zero = build_zero_cst (TREE_TYPE (rhs1));
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Found cond scalar reduction.\n");
+ print_gimple_stmt (dump_file, reduc, 0, TDF_SLIM);
+ }
+
+ /* Build cond expression using COND and constant operand
+ of reduction rhs. */
+ c = fold_build_cond_expr (TREE_TYPE (rhs1),
+ unshare_expr (cond),
+ swap ? zero : op1,
+ swap ? op1 : zero);
+
+ /* Create assignment stmt and insert it at GSI. */
+ new_assign = gimple_build_assign (tmp, c);
+ gsi_insert_before (gsi, new_assign, GSI_SAME_STMT);
+ /* Build rhs for unconditional increment/decrement. */
+ rhs = fold_build2 (gimple_assign_rhs_code (reduc),
+ TREE_TYPE (rhs1), op0, tmp);
+
+ /* Delete original reduction stmt. */
+ stmt_it = gsi_for_stmt (reduc);
+ gsi_remove (&stmt_it, true);
+ release_defs (reduc);
+ return rhs;
+}
+
/* Replace a scalar PHI node with a COND_EXPR using COND as condition.
This routine does not handle PHI nodes with more than two
arguments.
@@ -1428,6 +1566,9 @@ predicate_scalar_phi (gimple phi, tree cond,
else
{
tree arg_0, arg_1;
+ tree op0, op1;
+ gimple reduc;
+
/* Use condition that is not TRUTH_NOT_EXPR in conditional modify expr. */
if (EDGE_PRED (bb, 1)->src == true_bb)
{
@@ -1439,10 +1580,14 @@ predicate_scalar_phi (gimple phi, tree cond,
arg_0 = gimple_phi_arg_def (phi, 0);
arg_1 = gimple_phi_arg_def (phi, 1);
}
-
- /* Build new RHS using selected condition and arguments. */
- rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
- arg_0, arg_1);
+ if (is_cond_scalar_reduction (phi, &reduc, &op0, &op1))
+ /* Convert reduction stmt into vectorizable form. */
+ rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1,
+ true_bb != gimple_bb (reduc));
+ else
+ /* Build new RHS using selected condition and arguments. */
+ rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
+ arg_0, arg_1);
}
new_stmt = gimple_build_assign (res, rhs);
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index f458d6a9985..0a24a5cc0ec 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -403,10 +403,59 @@ copy_phi_arg_into_existing_phi (edge src_e, edge tgt_e)
}
}
-/* For each PHI in BB, copy the argument associated with SRC_E to TGT_E. */
+/* Given ssa_name DEF, backtrack jump threading PATH from node IDX
+ to see if it has constant value in a flow sensitive manner. Set
+ LOCUS to location of the constant phi arg and return the value.
+ Return DEF directly if either PATH or idx is ZERO. */
+
+static tree
+get_value_locus_in_path (tree def, vec<jump_thread_edge *> *path,
+ basic_block bb, int idx, source_location *locus)
+{
+ tree arg;
+ gimple def_phi;
+ basic_block def_bb;
+
+ if (path == NULL || idx == 0)
+ return def;
+
+ def_phi = SSA_NAME_DEF_STMT (def);
+ if (gimple_code (def_phi) != GIMPLE_PHI)
+ return def;
+
+ def_bb = gimple_bb (def_phi);
+ /* Don't propagate loop invariants into deeper loops. */
+ if (!def_bb || bb_loop_depth (def_bb) < bb_loop_depth (bb))
+ return def;
+
+ /* Backtrack jump threading path from IDX to see if def has constant
+ value. */
+ for (int j = idx - 1; j >= 0; j--)
+ {
+ edge e = (*path)[j]->e;
+ if (e->dest == def_bb)
+ {
+ arg = gimple_phi_arg_def (def_phi, e->dest_idx);
+ if (is_gimple_min_invariant (arg))
+ {
+ *locus = gimple_phi_arg_location (def_phi, e->dest_idx);
+ return arg;
+ }
+ break;
+ }
+ }
+
+ return def;
+}
+
+/* For each PHI in BB, copy the argument associated with SRC_E to TGT_E.
+ Try to backtrack jump threading PATH from node IDX to see if the arg
+ has constant value, copy constant value instead of argument itself
+ if yes. */
static void
-copy_phi_args (basic_block bb, edge src_e, edge tgt_e)
+copy_phi_args (basic_block bb, edge src_e, edge tgt_e,
+ vec<jump_thread_edge *> *path, int idx)
{
gimple_stmt_iterator gsi;
int src_indx = src_e->dest_idx;
@@ -414,8 +463,14 @@ copy_phi_args (basic_block bb, edge src_e, edge tgt_e)
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple phi = gsi_stmt (gsi);
+ tree def = gimple_phi_arg_def (phi, src_indx);
source_location locus = gimple_phi_arg_location (phi, src_indx);
- add_phi_arg (phi, gimple_phi_arg_def (phi, src_indx), tgt_e, locus);
+
+ if (TREE_CODE (def) == SSA_NAME
+ && !virtual_operand_p (gimple_phi_result (phi)))
+ def = get_value_locus_in_path (def, path, bb, idx, &locus);
+
+ add_phi_arg (phi, def, tgt_e, locus);
}
}
@@ -423,10 +478,13 @@ copy_phi_args (basic_block bb, edge src_e, edge tgt_e)
edges. The copy is NEW_BB. Every PHI node in every direct successor of
ORIG_BB has a new argument associated with edge from NEW_BB to the
successor. Initialize the PHI argument so that it is equal to the PHI
- argument associated with the edge from ORIG_BB to the successor. */
+ argument associated with the edge from ORIG_BB to the successor.
+ PATH and IDX are used to check if the new PHI argument has constant
+ value in a flow sensitive manner. */
static void
-update_destination_phis (basic_block orig_bb, basic_block new_bb)
+update_destination_phis (basic_block orig_bb, basic_block new_bb,
+ vec<jump_thread_edge *> *path, int idx)
{
edge_iterator ei;
edge e;
@@ -434,7 +492,7 @@ update_destination_phis (basic_block orig_bb, basic_block new_bb)
FOR_EACH_EDGE (e, ei, orig_bb->succs)
{
edge e2 = find_edge (new_bb, e->dest);
- copy_phi_args (e->dest, e, e2);
+ copy_phi_args (e->dest, e, e2, path, idx);
}
}
@@ -443,11 +501,13 @@ update_destination_phis (basic_block orig_bb, basic_block new_bb)
destination.
Add an additional argument to any PHI nodes at the single
- destination. */
+ destination. IDX is the start node in jump threading path
+ we start to check to see if the new PHI argument has constant
+ value along the jump threading path. */
static void
create_edge_and_update_destination_phis (struct redirection_data *rd,
- basic_block bb)
+ basic_block bb, int idx)
{
edge e = make_edge (bb, rd->path->last ()->e->dest, EDGE_FALLTHRU);
@@ -476,7 +536,7 @@ create_edge_and_update_destination_phis (struct redirection_data *rd,
from the duplicate block, then we will need to add a new argument
to them. The argument should have the same value as the argument
associated with the outgoing edge stored in RD. */
- copy_phi_args (e->dest, rd->path->last ()->e, e);
+ copy_phi_args (e->dest, rd->path->last ()->e, e, rd->path, idx);
}
/* Look through PATH beginning at START and return TRUE if there are
@@ -501,6 +561,7 @@ void
ssa_fix_duplicate_block_edges (struct redirection_data *rd,
ssa_local_info_t *local_info)
{
+ bool multi_incomings = (rd->incoming_edges->next != NULL);
edge e = rd->incoming_edges->e;
vec<jump_thread_edge *> *path = THREAD_PATH (e);
@@ -516,8 +577,10 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd,
edge e2;
/* This updates the PHIs at the destination of the duplicate
- block. */
- update_destination_phis (local_info->bb, rd->dup_blocks[count]);
+ block. Pass 0 instead of i if we are threading a path which
+ has multiple incoming edges. */
+ update_destination_phis (local_info->bb, rd->dup_blocks[count],
+ path, multi_incomings ? 0 : i);
/* Find the edge from the duplicate block to the block we're
threading through. That's the edge we want to redirect. */
@@ -535,7 +598,8 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd,
case), then the PHIs in the target already have the correct
arguments. */
if (e2 == victim)
- copy_phi_args (e2->dest, path->last ()->e, e2);
+ copy_phi_args (e2->dest, path->last ()->e, e2,
+ path, multi_incomings ? 0 : i);
}
else
{
@@ -567,7 +631,8 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd,
else if ((*path)[i]->type == EDGE_COPY_SRC_BLOCK)
{
remove_ctrl_stmt_and_useless_edges (rd->dup_blocks[count], NULL);
- create_edge_and_update_destination_phis (rd, rd->dup_blocks[count]);
+ create_edge_and_update_destination_phis (rd, rd->dup_blocks[count],
+ multi_incomings ? 0 : i);
if (count == 1)
single_succ_edge (rd->dup_blocks[1])->aux = NULL;
count++;
@@ -989,7 +1054,7 @@ thread_single_edge (edge e)
create_block_for_threading (bb, &rd, 0);
remove_ctrl_stmt_and_useless_edges (rd.dup_blocks[0], NULL);
- create_edge_and_update_destination_phis (&rd, rd.dup_blocks[0]);
+ create_edge_and_update_destination_phis (&rd, rd.dup_blocks[0], 0);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Threaded jump %d --> %d to %d\n",