]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Merge in trunk.
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 5 May 2014 18:05:00 +0000 (18:05 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 5 May 2014 18:05:00 +0000 (18:05 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@210075 138bc75d-0d04-0410-961f-82ee72b054a4

127 files changed:
gcc/ChangeLog
gcc/DATESTAMP
gcc/c-family/ChangeLog
gcc/c-family/c.opt
gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/c/c-parser.c
gcc/c/c-tree.h
gcc/c/c-typeck.c
gcc/config/aarch64/aarch64.c
gcc/config/arc/arc.c
gcc/config/arm/arm.h
gcc/config/avr/avr.c
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/nds32/nds32.h
gcc/config/picochip/picochip-protos.h
gcc/config/picochip/picochip.c
gcc/config/rs6000/rs6000-builtin.def
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/s390/s390.c
gcc/config/sh/sh-mem.cc
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/sh/sh_optimize_sett_clrt.cc
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/lambda.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/defaults.h
gcc/doc/invoke.texi
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/final.c
gcc/fold-const.c
gcc/fortran/ChangeLog
gcc/fortran/gfortran.h
gcc/fortran/parse.c
gcc/fortran/resolve.c
gcc/fortran/trans-decl.c
gcc/fortran/trans-expr.c
gcc/fortran/trans-intrinsic.c
gcc/fortran/trans-stmt.c
gcc/fortran/trans-types.c
gcc/fortran/trans.h
gcc/gimplify.c
gcc/go/ChangeLog
gcc/go/Make-lang.in
gcc/go/go-backend.c
gcc/go/go-c.h
gcc/go/go-lang.c
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/gogo-tree.cc [deleted file]
gcc/go/gofrontend/gogo.cc
gcc/hwint.h
gcc/ira-color.c
gcc/lra-constraints.c
gcc/omp-low.c
gcc/passes.c
gcc/po/ChangeLog
gcc/po/sv.po
gcc/po/zh_CN.po
gcc/target.def
gcc/targhooks.c
gcc/targhooks.h
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr43395.c [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/deleted4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/deleted5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/deleted6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const3.C [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pr58419.c
gcc/testsuite/gcc.dg/declspec-13.c
gcc/testsuite/gcc.dg/hoist-register-pressure-1.c
gcc/testsuite/gcc.dg/hoist-register-pressure-2.c
gcc/testsuite/gcc.dg/hoist-register-pressure-3.c
gcc/testsuite/gcc.dg/pr25801.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr29467.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr43245.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr56989.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr60257.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr60784.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr60915.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr61010.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c
gcc/testsuite/gcc.dg/vect/cond-reduc-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/cond-reduc-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpf32_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpp16_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpp8_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpqf32_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpqp16_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpqp8_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpqs16_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpqs32_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpqs8_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpqu16_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpqu32_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpqu8_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzps16_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzps32_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzps8_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpu16_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpu32_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/simd/vuzpu8_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/pack02.c
gcc/testsuite/gcc.target/powerpc/pack03.c
gcc/testsuite/gcc.target/s390/leaf-profile.c [new file with mode: 0644]
gcc/testsuite/gfortran.dg/bind_c_usage_24_c.c
gcc/testsuite/gfortran.dg/c_f_pointer_logical_driver.c
gcc/testsuite/gfortran.dg/coarray/codimension.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/coarray_lib_this_image_1.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/coarray_lib_this_image_2.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/coarray_lib_token_4.f90
gcc/testsuite/gfortran.dg/coarray_poly_4.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/coarray_poly_5.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/coarray_poly_6.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/coarray_poly_7.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/coarray_poly_8.f90 [new file with mode: 0644]
gcc/testsuite/go.test/go-test.exp
gcc/tree-if-conv.c
gcc/tree-ssa-threadupdate.c

index e3ae8dcfc81eec33e33c32a52d5d0f740f6267c3..87d71416a7853fef71377ccdcbd603e1725f9240 100644 (file)
@@ -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,
index 5907e7a31563ecae76231a1eccd08df466edc6f9..d43065abe47075ee98b2e07c575b50db0fbad0c9 100644 (file)
@@ -1 +1 @@
-20140430
+20140505
index 47bb11438ad997dbca72276e6f48c23b0e0b502c..3c9732395d361e2852980c76c95b3219e2e4c55e 100644 (file)
@@ -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
index 94447082fb54173b83269259d3473281771d1023..7aa9e23c10e4977ed4d7e37f5948557f1734d79f 100644 (file)
@@ -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
index bf61610e37cb2c7a7ecef29700186734f41d75c7..e408fef274d881173e1dec059ca728cdc269ee20 100644 (file)
@@ -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
        (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
index 90808eda618f6beefc61f3cd2330ecc1ce02d197..3abf6b985741657270dc8514844a8062e1fddc64 100644 (file)
@@ -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 "
index 41ae77b541e51f39fd1121236d58813800d7ac1c..6e8f33bdac1461ece539a68845f67e784e04ccc4 100644 (file)
@@ -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.  */
index 53768d619b7c0f525ac244691b7d90a479ef71f4..a6e732791254a83d6c9227b7e97af7da5a60705d 100644 (file)
@@ -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);
index 11825a9218ed70adf656ab061cf1226cf3eef337..7d2df6b1d1293bbf87fa921c07c43f6a5da267d9 100644 (file)
@@ -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,
     }
 }
 \f
-/* 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);
+}
+\f
+/* 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);
-}
-\f
-/* 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:
index d3d7d1e60d67879544810c828a04fddabe1cfe8c..6a6fb032647d1d6cdb0e6b12c516a8ddcb2c5fb3 100644 (file)
@@ -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;
index 58d95d832c529caa6c188cf191db3265ea1de72c..113395bd5de08e55eb8d9f660db9abfd330f4fad 100644 (file)
@@ -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) */
index 3a9e3ebbb3e55588c5f42118d7d839eddae7289e..96f3efeb2460c1e61cc70e8cb4850714943c33e0 100644 (file)
@@ -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
index 0fa7f6633e2fa2d73a6e1d870eeb598183cb2a6f..9f87adaee00587ef01daa832c291740fa432f777 100644 (file)
@@ -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;
     }
index 45256e99250f2307e997a50dfb445dc55acab510..29d0ac16102cf1b278d7758410923f7e2e51e158 100644 (file)
@@ -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;
     }
 }
 
index b25865b6dfb61a08249f678ef74406e52d65a04a..6200ffc4e2c86bd71183b68064094730d33af952 100644 (file)
@@ -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;
index 38847e5697c7ad9da436e4d952652d46f92c9d6a..8f966ec1475ebb11c635cc989a7f16aaff3cbf9d 100644 (file)
@@ -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".  */
index 1f548f8f257b05ec51b51e9bc69c4deed337ca0a..4d8dfd6b298a877eb7bd8b399a04f457339e5481 100644 (file)
@@ -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);
 
index 2476f7344f81ee2d697e2dc64c0407c5705cfa10..8738564d3fcf21d463cf1a509a2597693c5e1de9 100644 (file)
@@ -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);
 
index 16793f501e722cdf4609a525d83a8105e9d5a011..8e15bdf1619d41f327e1cfd9d72e25d57b26d8fa 100644 (file)
 #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 */
 #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 */
index 0c983f9a10593caaf13ef005e6603d086928258d..e4a68347f57bfdd8e8790b27537405bfdc673b6c 100644 (file)
@@ -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
index 2e677d5936e54abda3c8f44d22c60f6a313f0707..f979905f1da74736664f9e0d8b24a34a5e64dbc2 100644 (file)
@@ -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.  */
 
index 7183f2c286777f769987b49c4f9128991fc294f2..6c22c0604c3d445217f3b7bed8e941dd5291eee3 100644 (file)
@@ -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
 
index 1b84f9b63b7766d304b6d14612a9238f8367f7ad..0e38913b929b5bc15f7847c587a3228de8b7e209 100644 (file)
@@ -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;
 }
index 6d909c79ef78b7fae7dd0dc93541087bcb1fd616..26a5d79f137baf3f1483bf9aafe9f5f8796b19dd 100644 (file)
@@ -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;
index 8c30e5c14bd3dd1855b30793baa26047df7a0bbd..00ee0edffdaa210d7c74ea316fa7718387ccd8c1 100644 (file)
@@ -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
index 5b1afcd961bf189e4978ed37dba47b04fd4ebd82..84ad2999de7814dce3ede48af1562384a51e3854 100644 (file)
@@ -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)
       {
index c078e0685cc29bf57a7b839e84cdb96a67b6e524..374cd0f6a5e9e32519d8df04fe308049fbebac4e 100644 (file)
@@ -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
index 55ecc4e5b5f970f56c4b23485b843ae2fadafd1c..34d3d2033362ab1ea44aa77b377c0a7d73f70bf9 100644 (file)
@@ -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,
index bfd5395128ac1dd39c29c8e55297319dc6298d60..01a36252b2edf992ebd160e21656954ffb808707 100644 (file)
@@ -7823,6 +7823,8 @@ grokfndecl (tree ctype,
                     decl, ctype);
              return NULL_TREE;
            }
+         if (ok == error_mark_node)
+           return NULL_TREE;
          return old_decl;
        }
     }
index 918ea2fc6d08d5eac4455ef9e0ba22f36669c254..71402181af6160207aa7479d4eed1291f5568fc5 100644 (file)
@@ -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,
index 0b8b46a8144d127a8eae89f53333d09033f6ffe3..5ba6f141b72dd601ba68fbd5ad4dac9b5d3a5eb7 100644 (file)
@@ -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
index 48cc2a9e9cf8ad2db4e37521a1c9a89c832e6518..7e7f6d89f0dcfe28d98be2df8d6066df08e62756 100644 (file)
@@ -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.  */
index 3f8ca44904e59378c6f3aafbeb2670890d90aadb..4afb821de06ebfd78b61b3a68e795a47ed9bfa20 100644 (file)
@@ -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
index 729e22eadc57dc262759fbcd9880df4424acc008..7b28a9a58695b919c89e1cee9a388337ef8c4812 100644 (file)
@@ -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;
     }
 }
index 5becc455e4cf6c1a88c6c439605974d94372fa08..8d89a751b7521777ae5ad9f16025be395ddb6e80 100644 (file)
@@ -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.  */
index cc6d405f1685b4e16c312bdd2613394309b94339..3fe9d5f302cc80da2ed383e857feac4b8489d433 100644 (file)
@@ -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
index 46b5cb528d49fb3e3fc3df8d4616aaf55f3d3500..e01cbd953f86d5a81995ca9057cb89877f08f275 100644 (file)
@@ -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
index de7aa92df37d6d808d050b70600d768215af341f..bbb032e217fa95683c361772428954f4bcfd6059 100644 (file)
@@ -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
index 0497834b977f166dc527e4b37c00234a161ddee2..d3e0bba015e0576b3fd16c3d48bb360ea06d4f40 100644 (file)
@@ -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))
index a67c34d4d39e569acd6dfc7be98b31a5ce6761b3..831aaba683c046ac70b72b7408e5501e9863aa90 100644 (file)
@@ -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,
index 5cf25134e30787ed3646ac6977536dec3924fca9..b991dc0b115ca0c56be10e1843d1927e28e2508f 100644 (file)
@@ -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
index f0eed809ab8a4e32f5be47c9247db5193d520d0a..0707b58bd2b62d54dc27a98af86b484f12cbf71c 100644 (file)
@@ -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 *);
index 0faf47a00412e01103ae64377e81067dca955f7c..77667150176216ad0ee4fe2a0475bf6dfcd27a21 100644 (file)
@@ -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;
index 38755fef6a27ee1db5fec00f8c4f20e6794dbaf6..15c94635f49acb0d6eb186ae73fa53062d7c6f88 100644 (file)
@@ -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
index 7bf0fb1b57a3a59317f3ae3a650677da8ca06f6d..bd1ebab46b268eddbc1974fa79147a306961907c 100644 (file)
@@ -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);
     }
 
index b2290c0ac01d8d734be225e8d286d9cdbe5301ad..5a501227863e8a22c2990e91310277a672cf4be4 100644 (file)
@@ -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,
index c96ba56f071169d5c85e1c3dd6cc6f0784b5aafc..c166c4f0bcfa14d19c2391a8d395f68e6e79cbc2 100644 (file)
@@ -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);
index 00c99fcfb5beacdc871e35c559505c55659726b6..212a2586d2acae0e0f1fd98b2ae67a5f861750ed 100644 (file)
@@ -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));
index 9f735e19f9a601e400dbbd88bf30827628371d67..77d0e785e0be36d52606e875b7787dbe9d63e5b2 100644 (file)
@@ -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);
 }
 \f
index f8d29ecf2ec4767d90df56307838843208dcf2dc..13b0a0005442138960541374d0a3d41a59d512d4 100644 (file)
@@ -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.  */
index 008a2528644aa87b0f5be028aaf94f64634ab9c4..37c3778624f2f1bd1cd386325450820b14c104cf 100644 (file)
@@ -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);
                }
            }
index 8d86e746d6e54b76380da1d770d78e514242843d..a468beed742ba8aa8f7a0f9f3027b86eca5b37c0 100644 (file)
@@ -1,3 +1,17 @@
+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".
index abcae66a21f554069796a24a2b3b26b77b4c7860..bbd26dc21108aa74c4679141da5646d48ee42051 100644 (file)
@@ -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 \
index de33601db520e4669ac5f0398222afecf319b91f..3f1a9f93b7136c00170167dfae6ce1a6864ed388 100644 (file)
@@ -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
index cf0fbfb0a3f30da0641a9ef35e37eedf944b5278..cb10f2b7be712f76fa1c4f34093992fb10fd1e94 100644 (file)
@@ -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);
index c0f2f1f3884343f1d231ff1a13db59546abdf1f9..3599aa85e54588a33888d69b6dc6efd89cd6dcee 100644 (file)
@@ -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
index 275626391767ebf0db179c8d18816f7d01b6ccef..69af48c9d355c0196f183093bbdcd4e0016743bc 100644 (file)
@@ -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 (file)
index 5b9a818..0000000
+++ /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;
-}
index 995a4f2d2da32b53f39ed90446d8bd4573e70c21..ab54f8491e3c56a17b422b97eef25eaae55cfe0a 100644 (file)
@@ -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)
index 229fb94b5655b670374dd69b51338c488563612b..ac9c9a295b43bbe1b3a2b1bfebd64a66987dbe41 100644 (file)
@@ -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);
     }
 }
 
index 1f4c96e9a8971c1871fb40b2195bac9165e3b13c..28a6d40eb1d658c30a95c2893ecc79b8980487fb 100644 (file)
@@ -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)
index aac50876d21a5c9be55803d9022892861984bf47..f59bf555544331af605cc095b5e8fc022ec0cc2b 100644 (file)
@@ -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
              }
index a0f024a76ef75be27685532a58d65a49d1e2a92a..453f580a838109ede54bc0c8bc208b8f16e9d3be 100644 (file)
@@ -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);
index dbff5875a5d90070dc6ddb253b997d47292091bc..30c849fce3906304317c35c5ebbf3ebe18404d31 100644 (file)
@@ -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);
index ceb363e355df4d39c69e7683edfc0f636ffa05d0..a25a90eb43858c92d50f5170df1831d9745110a6 100644 (file)
@@ -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.
index 0bae3b6f75726a148cfedefeeca8ea210e1fc082..b38f70811812a39fc04ab35952f0ed7e69f2f875 100644 (file)
@@ -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
index 237e93033d8cbd91e1ca7e4af9cbfab165e987bc..7edfcb45770096a97874e0d9ee18365abfb9336a 100644 (file)
@@ -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
index 465dbe2d569e4c92fcba94da51f1e8a7d57d7437..288d1d172b18075c25681f446b5daa2b92f4c680 100644 (file)
@@ -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).
index d844790d027f0c53b53af3ac574e2e566660e5f2..3df93d3943225815173f207a0b3d8f7944c4c5b1 100644 (file)
@@ -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.  */
index ac57201f93ffb6cd185e7f971a19c517437ba782..4be33f8696c44d0a9862cd3a40c24b0f09027b54 100644 (file)
@@ -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);
index 00ae0d12f54d8cbb28ba40132cf544d1aa49ae2e..1c9d4d31c662b1d7aceb102e795c7ba4baf5f703 100644 (file)
@@ -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 (file)
index 0000000..92f048d
--- /dev/null
@@ -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 (file)
index 0000000..22439d4
--- /dev/null
@@ -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 (file)
index 0000000..51010ef
--- /dev/null
@@ -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 (file)
index 0000000..af25b50
--- /dev/null
@@ -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 (file)
index 0000000..a1ffadd
--- /dev/null
@@ -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);
+}
index 69cc0401dc1d044ea831409d5243d7fc7aa21ec6..78bf437eb6b8f1881f271ca9c1f6e3c02c7a4dd4 100644 (file)
@@ -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;
 }
index a325c0d883196b7c49cfc80972b879e7ffef9877..3b4e315ef356f9a59159a8f0ac06bfeb91258205 100644 (file)
@@ -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" } */
index f5b5302b3c5f028038ad4aab6b607cc39194f0d4..4aabcb78daf72423709a877a38a9c7f3c0f7853a 100644 (file)
@@ -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.  */
index 30408f318c4d070de59bc61c504d8a725030f133..f1c927ec434ad66e677eb3d19e3d0eb2b2e68ab8 100644 (file)
@@ -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.  */
index b050f89823fa3685842d22d30e1398dd94ca9a8c..24abaa6ade4c8552386e3ea5e83da76358ef0383 100644 (file)
@@ -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 (file)
index 0000000..10b53d3
--- /dev/null
@@ -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 (file)
index 0000000..eaf09c2
--- /dev/null
@@ -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 (file)
index 0000000..85490ff
--- /dev/null
@@ -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 (file)
index 0000000..beb9806
--- /dev/null
@@ -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 (file)
index 0000000..46c29b0
--- /dev/null
@@ -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 (file)
index 0000000..82b512f
--- /dev/null
@@ -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 (file)
index 0000000..2ed0a5f
--- /dev/null
@@ -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 (file)
index 0000000..ed56539
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+int main (void)
+{
+  int a = 0;
+  unsigned b = (a * 64 & 192) | 63U;
+  return 0;
+}
index e85a24420eed13c7b944bc6b0e8eabbefecf4b2b..cafdf13909e9eee7b6d88713e1467ed3c4cdfbbb 100644 (file)
@@ -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 (file)
index 0000000..981f6b0
--- /dev/null
@@ -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 (file)
index 0000000..c329861
--- /dev/null
@@ -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 (file)
index 0000000..723c86a
--- /dev/null
@@ -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 (file)
index 0000000..c7ad757
--- /dev/null
@@ -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 (file)
index 0000000..670b550
--- /dev/null
@@ -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 (file)
index 0000000..53147f1
--- /dev/null
@@ -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 (file)
index 0000000..feef15a
--- /dev/null
@@ -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 (file)
index 0000000..db98f35
--- /dev/null
@@ -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 (file)
index 0000000..808d562
--- /dev/null
@@ -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 (file)
index 0000000..7adf5f9
--- /dev/null
@@ -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 (file)
index 0000000..9d0256a
--- /dev/null
@@ -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 (file)
index 0000000..23106ed
--- /dev/null
@@ -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 (file)
index 0000000..0002fdf
--- /dev/null
@@ -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 (file)
index 0000000..f8d19dc
--- /dev/null
@@ -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 (file)
index 0000000..6e3f2eb
--- /dev/null
@@ -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 (file)
index 0000000..372c393
--- /dev/null
@@ -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 (file)
index 0000000..3338477
--- /dev/null
@@ -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 (file)
index 0000000..378b5a9
--- /dev/null
@@ -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 (file)
index 0000000..ebb0d6b
--- /dev/null
@@ -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 (file)
index 0000000..82719a5
--- /dev/null
@@ -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 } } */
index 74b6cd04dcca00ab9b89a67ce498771710e6528e..584d6c292055831221f76666221fd4e9745040ca 100644 (file)
@@ -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>
index 59f0e74ba9c7e36b51a405c636e6aad192ae8e14..bc582f232d69ec0f83c042437ee139a78efa5c45 100644 (file)
@@ -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 (file)
index 0000000..6047740
--- /dev/null
@@ -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-*-* } } } */
index ffc90b728b5e1f1f241da8f20ba397d87d35ceda..65754f3415d7ba3a43afc17fcd565375969e31c7 100644 (file)
@@ -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)
index e3044c92e436e11ef9c6599b2780ca5d849f27c1..a05449dc1810d5d2e2116b819335a82d3dfa8921 100644 (file)
@@ -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 (file)
index 0000000..706048f
--- /dev/null
@@ -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 (file)
index 0000000..2fcaacd
--- /dev/null
@@ -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 (file)
index 0000000..4afabaa
--- /dev/null
@@ -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" } }
index 43da9f4c909096d25d9edf6adc33952d27decc09..9e445f4a0dea05182a34cc5451af425bb5006e7b 100644 (file)
@@ -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 (file)
index 0000000..ceb1c85
--- /dev/null
@@ -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 (file)
index 0000000..29c9c8c
--- /dev/null
@@ -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 (file)
index 0000000..3fff5e0
--- /dev/null
@@ -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 (file)
index 0000000..b50319a
--- /dev/null
@@ -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 (file)
index 0000000..7775605
--- /dev/null
@@ -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" } }
index 1bbbd8742e23566ebc9fdfdd6c03af21034e0646..4400d405d0606d62c39c97bcfcf424ebddc176b2 100644 (file)
@@ -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
                }
index 21a9f05c78bfa0f62b0ca651addb7d27f715f627..5b08669f456d8cd23e5e578e864e4d3e5ff964b2 100644 (file)
@@ -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);
index f458d6a99856f917ce81ed098e8800e57a44ed38..0a24a5cc0ec690c97f22686358c5c3186be0dd00 100644 (file)
@@ -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",