diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-06-20 19:52:08 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-06-20 19:52:08 +0000 |
commit | 34bbbb0670a7df57036c2e158857ef655548bca5 (patch) | |
tree | a40370cacb124a35a15e8df7766262292b7f292e | |
parent | efff306159648aee52fe35120a1ee0270034bda0 (diff) | |
download | gcc-34bbbb0670a7df57036c2e158857ef655548bca5.tar.gz |
2011-06-20 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 175225 using svnmerge. Using
c_register_pragma_with_expansion_and_data is now possible...
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@175227 138bc75d-0d04-0410-961f-82ee72b054a4
517 files changed, 15090 insertions, 7142 deletions
diff --git a/ChangeLog b/ChangeLog index 33077a9f1aa..606f1e84906 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-06-13 Walter Lee <walt@tilera.com> + + * configure.ac (tilepro-*-*) New case. + (tilegx-*-*): Likewise. + * configure: Regenerate. + 2011-06-06 Jing Yu <jingyu@google.com> * configure.ac: Skip target-libiberty for diff --git a/ChangeLog.MELT b/ChangeLog.MELT index 86ad7a5949f..7bf9d85d3e3 100644 --- a/ChangeLog.MELT +++ b/ChangeLog.MELT @@ -1,4 +1,9 @@ +2011-06-20 Basile Starynkevitch <basile@starynkevitch.net> + + MELT branch merged with trunk rev 175225 using svnmerge. Using + c_register_pragma_with_expansion_and_data is now possible... + 2011-06-11 Basile Starynkevitch <basile@starynkevitch.net> MELT branch merged with trunk rev 174941 using svnmerge diff --git a/config/ChangeLog b/config/ChangeLog index ec4a0bef6c8..c3a1b8b4d19 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,3 +1,8 @@ +2011-06-15 Mike Stump <mikestump@comcast.net> + + PR target/49461 + * mh-darwin: Turn off -pie on darwin11 and later. + 2011-04-20 Eric Botcazou <ebotcazou@adacore.com> * bootstrap-lto.mk: Remove obsolete requirement. diff --git a/config/mh-darwin b/config/mh-darwin index 66f68b664a9..19bf26568b5 100644 --- a/config/mh-darwin +++ b/config/mh-darwin @@ -1,5 +1,7 @@ # The -mdynamic-no-pic ensures that the compiler executable is built without # position-independent-code -- the usual default on Darwin. This fix speeds # compiles by 3-5%. - BOOT_CFLAGS += -mdynamic-no-pic + +# Ensure we don't try and use -pie, as it is incompatible with pch. +BOOT_LDFLAGS += `case ${host} in *-*-darwin[1][1-9]*) echo -Wl,-no_pie ;; esac;` diff --git a/configure b/configure index 99d6e176532..0768acd65cb 100755 --- a/configure +++ b/configure @@ -3608,6 +3608,9 @@ case "${target}" in tic6x-*-*) noconfigdirs="$noconfigdirs gdb sim" ;; + tilepro-*-* | tilegx-*-*) + noconfigdirs="$noconfigdirs sim" + ;; v810-*-*) noconfigdirs="$noconfigdirs bfd binutils gas gdb ld opcodes target-libgloss" ;; diff --git a/configure.ac b/configure.ac index bcba55185e4..fc83c60a582 100644 --- a/configure.ac +++ b/configure.ac @@ -1054,6 +1054,9 @@ case "${target}" in tic6x-*-*) noconfigdirs="$noconfigdirs gdb sim" ;; + tilepro-*-* | tilegx-*-*) + noconfigdirs="$noconfigdirs sim" + ;; v810-*-*) noconfigdirs="$noconfigdirs bfd binutils gas gdb ld opcodes target-libgloss" ;; diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4857e927109..59300e5e821 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,1328 @@ +2011-06-20 Bernd Schmidt <bernds@codesourcery.com> + + * regrename.c (scan_rtx_reg): Handle the case where we write to an + open chain in a smaller mode without failing the entire block. + +2011-06-20 H.J. Lu <hongjiu.lu@intel.com> + + PR middle-end/47725 + * combine.c (cant_combine_insn_p): Don't check zero/sign + extended hard registers. + +2011-06-21 Alan Modra <amodra@gmail.com> + + * config/rs6000/rs6000.c (rs6000_cannot_force_const_mem): Match + CONST high part large-toc address. + (rs6000_tls_referenced_p): Make static. + * config/rs6000/rs6000-protos.h (rs6000_tls_referenced_p): Delete. + +2011-06-20 H.J. Lu <hongjiu.lu@intel.com> + + PR middle-end/47725 + * combine.c (cant_combine_insn_p): Check zero/sign extended + hard registers. + +2011-06-20 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org> + + PR target/49385 + * config/arm/thumb2.md (*thumb2_movhi_insn): Make sure atleast + one of the operands is a register. + +2011-06-20 Kai Tietz <ktietz@redhat.com> + + * fold-const.c (fold_binary_loc): Add missing + folding for truth-not operations in combination + with binary and. + +2011-06-20 Bernd Schmidt <bernds@codesourcery.com> + + * regrename.c (do_replace): Don't update notes. + +2011-06-20 Alan Modra <amodra@gmail.com> + + * config/rs6000/rs6000.c (create_TOC_reference): Wrap high part + of toc-relative address in CONST. + (rs6000_delegitimize_address): Recognize changed address. + (rs6000_legitimize_reload_address): Likewise. + (rs6000_emit_move): Don't force these constants to memory. + * config/rs6000/rs6000.md (tls_gd, tls_gd_high): Wrap high part of + toc-relative address in CONST. + (tls_ld, tls_ld_high, tls_got_dtprel, tls_got_dtprel_high): Likewise. + (tls_got_tprel, tls_got_tprel_high, largetoc_high): Likewise. + +2011-06-18 H.J. Lu <hongjiu.lu@intel.com> + + * longlong.h (count_leading_zeros): Use long long builtin for + x86-64. + (count_trailing_zeros): Likewise. + +2011-06-18 H.J. Lu <hongjiu.lu@intel.com> + + PR other/49325 + * acinclude.m4 (gcc_AC_INITFINI_ARRAY): Properly check if + .init_array can be used with .ctors on targets. + * configure: Regenerated. + +2011-06-18 Eric Botcazou <ebotcazou@adacore.com> + + * tree-sra.c (type_internals_preclude_sra_p) <ARRAY_TYPE>: Return true + if the element type is volatile. + +2011-06-18 Jan Hubicka <jh@suse.cz> + + * lto-symtab.c (lto_varpool_replace_node): Remove code handling + extra name aliases. + (lto_symtab_resolve_can_prevail_p): Likewise. + (lto_symtab_merge_cgraph_nodes): Update alias_of pointers. + * cgraphbuild.c (record_reference): Remove extra body alias code. + (mark_load): Likewise. + (mark_store): Likewise. + * cgraph.h (varpool_node): Remove extra_name filed; + add alias_of and extraname_alias. + (varpool_create_variable_alias, varpool_for_node_and_aliases): Declare. + (varpool_alias_aliased_node): New inline function. + (varpool_variable_node): New function. + * cgraphunit.c (handle_alias_pairs): Handle also variable aliases. + * ipa-ref.c (ipa_record_reference): Allow aliases on variables. + * lto-cgraph.c (lto_output_varpool_node): Update streaming. + (input_varpool_node): Likewise. + * lto-streamer-out.c (produce_symtab): Remove extra name aliases. + (varpool_externally_visible_p): Remove extra body alias code. + (function_and_variable_visibility): Likewise. + * tree-ssa-structalias.c (associate_varinfo_to_alias_1): New function. + (ipa_pta_execute): Use it. + * varpool.c (varpool_remove_node): Remove extra name alias code. + (varpool_mark_needed_node): Likewise. + (varpool_analyze_pending_decls): Analyze aliases. + (assemble_aliases): New functoin. + (varpool_assemble_decl): Use it. + (varpool_create_variable_alias): New function. + (varpool_extra_name_alias): Rewrite. + (varpool_for_node_and_aliases): New function. + +2011-06-18 Jakub Jelinek <jakub@redhat.com> + + PR target/49411 + * config/i386/i386.c (ix86_expand_multi_arg_builtins): If + last_arg_constant and last argument doesn't match its predicate, + for xop_vpermil2<mode>3 error out and for xop_rotl<mode>3 + if it is CONST_INT, mask it, otherwise expand using rotl<mode>3. + (ix86_expand_sse_pcmpestr, ix86_expand_sse_pcmpistr): Fix + spelling of error message. + * config/i386/sse.md (sse4a_extrqi, sse4a_insertqi, + vcvtps2ph, *vcvtps2ph, *vcvtps2ph_store, vcvtps2ph256): Use + const_0_to_255_operand instead of const_int_operand. + + Revert: + 2011-05-09 Uros Bizjak <ubizjak@gmail.com> + + * config/i386/sse.md (blendbits): Remove mode attribute. + (<sse4_1>_blend<ssemodesuffix><avxsizesuffix>): Use const_int_operand + instead of const_0_to_<blendbits>_operand for operand 3 predicate. + Check integer value of operand 3 in insn constraint. + +2011-06-17 Hans-Peter Nilsson <hp@axis.com> + + PR rtl-optimization/48542 + * reload.c (find_equiv_reg): Stop looking when finding a + setjmp-type call. + * reload1.c (reload_as_needed): Invalidate all reload + registers when crossing a setjmp-type call. + +2011-06-16 Jeff Law <law@redhat.com> + + * tree-ssa-threadupdate.c (struct redirection_data): New field + intermediate_edge. + (THREAD_TARGET2): Define. + (redirection_data_eq): Also check that the intermediate edge is + equal. + (lookup_redirection_data): Drop useless argument. Extract the + outgoing_edge and intermediate edge from E. Callers updated. + (copy_phi_args, update_destination_phis): New functions. + (fix_duplicate_block_edges): Likewise. + (create_edge_and_update_destination_phis): Duplicate all the edges + hung off e->aux. Use copy_phi_args. + (create_duplicates): Use fix_duplicate_block_edges. + (fixup_template_block): Likewise. + (redirect_edges): If necessary, redirect the joiner block's incoming + edge to the duplicate of the joiner block. + (thread_block): Don't muck up loops when threading through a joiner + block. + (thread_through_loop_header): Handle threading through a joiner + block. + (mark_threaded_blocks, register_jump_thread): Likewise. + * tree-flow.h (register_jump_thread): Add new argument. Callers + updated. + * tree-ssa-threadedge.c (phi_args_equal_on_edges): New function. + (thread_across_edge): Handle threading through a joiner block. + +2011-06-16 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/49343 + * tree-sra.c (build_ref_for_model): Use component_ref_field_offset to + calculate offset, provide 2nd operand for the new COMPONENT_REF. + +2011-06-16 Iain Sandoe <iains@gcc.gnu.org> + + * config/darwin-protos.h (machopic_select_rtx_section): Move to + inside RTX_CODE ifdef. + +2011-06-16 Tom de Vries <tom@codesourcery.com> + + PR target/45098 + * tree-ssa-loop-niter.c (infer_loop_bounds_from_pointer_arith): Disallow + NULL pointer for pointer arithmetic. + +2011-06-16 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org> + + PR target/49398 + Revert. + 2011-06-10 Wei Guozhi <carrot@google.com> + + PR target/45335 + * config/arm/ldmstm.md (ldm2_ia, stm2_ia, ldm2_ib, stm2_ib, ldm2_da, + stm2_da, ldm2_db, stm2_db): Add condition !arm_arch7 to these insns. + (ldrd, ldrd_reg1, ldrd_reg2 and peephole2): New insn patterns and + related peephole2. + (strd, strd_reg1, strd_reg2 and peephole2): New insn patterns and + related peephole2. + * config/arm/arm-protos.h (arm_check_ldrd_operands): New prototype. + (arm_legitimate_ldrd_p): New prototype. + (arm_output_ldrd): New prototype. + * config/arm/arm.c (arm_check_ldrd_operands): New function. + (arm_legitimate_ldrd_p): New function. + (arm_output_ldrd): New function. + +2011-06-16 Joern Rennecke <joern.rennecke@embecosm.com> + + PR middle-end/46500 + * doc/tm.texi.in: Update Copyright date. + * doc/tm.texi: Regenerate. + * targhooks.c (default_setup_incoming_varargs): Replace + CUMULATIVE_ARGS* argument type with cumulative_args_t. + (default_pretend_outgoing_varargs_named): Likewise. + (hook_pass_by_reference_must_pass_in_stack): Likewise. + (hook_callee_copies_named): Likewise. + (default_function_arg_advance): Likewise. + (default_function_arg): Likewise. + (default_function_incoming_arg): Likewise. + (hook_bool_CUMULATIVE_ARGS_false): Likewise. + (hook_bool_CUMULATIVE_ARGS_true): Likewise. + (hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false): Likewise. + (hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true): Likewise. + (hook_int_CUMULATIVE_ARGS_mode_tree_bool_0): Likewise. + * targhooks.h (default_setup_incoming_varargs): Likewise. + (default_pretend_outgoing_varargs_named): Likewise. + (hook_pass_by_reference_must_pass_in_stack): Likewise. + (hook_callee_copies_named): Likewise. + (default_function_arg_advance): Likewise. + (default_function_arg): Likewise. + (default_function_incoming_arg): Likewise. + (hook_bool_CUMULATIVE_ARGS_false): Likewise. + (hook_bool_CUMULATIVE_ARGS_true): Likewise. + (hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false): Likewise. + (hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true): Likewise. + (hook_int_CUMULATIVE_ARGS_mode_tree_bool_0): Likewise. + * target.def (pass_by_reference): Likewise. + (setup_incoming_varargs, strict_argument_naming): Likewise. + (pretend_outgoing_varargs_named, callee_copies): Likewise. + (arg_partial_bytes, function_arg_advance, function_arg): Likewise. + (function_incoming_arg): Likewise. + * target.h: Don't include "tm.h" . + (cumulative_args_t): New typedef. + [GCC_TM_H] (get_cumulative_args): New static inline function. + [GCC_TM_H] (pack_cumulative_args): Likewise. + * config/alpha/alpha.c (alpha_function_arg): Replace CUMULATIVE_ARGS* + argument type with cumulative_args_t. + (alpha_function_arg_advance, alpha_arg_partial_bytes): Likewise. + (alpha_pass_by_reference, alpha_setup_incoming_varargs): Likewise. + * config/frv/frv.c (frv_setup_incoming_varargs): Likewise. + (frv_arg_partial_bytes, frv_function_arg): Likewise. + (frv_function_incoming_arg, frv_function_arg_advance): Likewise. + (frv_function_arg_1): Likewise. + * config/s390/s390.c (s390_pass_by_reference): Likewise. + (s390_function_arg_advance, s390_function_arg): Likewise. + * config/m32c/m32c.c (m32c_function_arg): Likewise. + (m32c_pass_by_reference, m32c_function_arg_advance): Likewise. + (m32c_strict_argument_naming): Likewise. + * config/spu/spu.c (spu_pass_by_reference, spu_function_arg): Likewise. + (spu_function_arg_advance): Likewise. + (spu_setup_incoming_varargs): Likewise. Make static. + * config/spu/spu-protos.h (spu_setup_incoming_varargs): + Remove prototype. + * config/sparc/sparc.c (sparc_strict_argument_naming): Replace + CUMULATIVE_ARGS* argument type with cumulative_args_t. + (sparc_pass_by_reference, sparc_function_arg_advance): Likewise. + (sparc_function_arg, sparc_function_incoming_arg): Likewise. + (sparc_arg_partial_bytes, sparc_function_arg_1): Likewise. + * config/mep/mep.c (mep_setup_incoming_varargs): Likewise. + (mep_pass_by_reference, mep_function_arg): Likewise. + (mep_function_arg_advance): Likewise. + * config/m32r/m32r.c (m32r_setup_incoming_varargs): Likewise. + (m32r_pass_by_reference, m32r_arg_partial_bytes): Likewise. + (m32r_function_arg, m32r_function_arg_advance): Likewise. + * config/rx/rx.c (rx_function_arg, rx_function_arg_advance): Likewise. + * config/i386/i386.c (ix86_function_arg_advance): Likewise. + (ix86_function_arg, ix86_pass_by_reference): Likewise. + (ix86_setup_incoming_varargs): Likewise. + * config/sh/sh.c (sh_setup_incoming_varargs): Likewise. + (sh_strict_argument_naming): Likewise. + (sh_pretend_outgoing_varargs_named, sh_pass_by_reference): Likewise. + (sh_callee_copies, sh_arg_partial_bytes): Likewise. + (sh_function_arg_advance, sh_function_arg): Likewise. + * config/pdp11/pdp11.c (pdp11_function_arg): Likewise. + (pdp11_function_arg_advance): Likewise. + * config/microblaze/microblaze.c (microblaze_function_arg_advance): + Likewise. + (microblaze_function_arg, function_arg_partial_bytes): Likewise. + * config/avr/avr.c (avr_function_arg): Likewise. + (avr_function_arg_advance): Likewise. + * config/xtensa/xtensa.c (xtensa_function_arg_advance): Likewise. + (xtensa_function_arg, xtensa_function_incoming_arg): Likewise. + (xtensa_function_arg_1): Likewise. + * config/stormy16/stormy16.c (xstormy16_function_arg_advance): Likewise. + (xstormy16_function_arg): Likewise. + * config/fr30/fr30.c (fr30_setup_incoming_varargs): Likewise. + (fr30_arg_partial_bytes, fr30_function_arg): Likewise. + (fr30_function_arg_advance): Likewise. + * config/lm32/lm32.c (lm32_setup_incoming_varargs): Likewise. + (lm32_function_arg, lm32_function_arg_advance): Likewise. + * config/moxie/moxie.c (moxie_setup_incoming_varargs): Likewise. + (moxie_function_arg, moxie_function_arg_advance): Likewise. + (moxie_pass_by_reference, moxie_arg_partial_bytes): Likewise. + * config/cris/cris.c (cris_setup_incoming_varargs): Likewise. + (cris_pass_by_reference, cris_arg_partial_bytes): Likewise. + (cris_function_arg, cris_function_incoming_arg): Likewise. + (cris_function_arg_advance, cris_function_arg_1): Likewise. + * config/iq2000/iq2000.c (iq2000_setup_incoming_varargs): Likewise. + (iq2000_pass_by_reference, iq2000_arg_partial_bytes): Likewise. + (iq2000_function_arg, iq2000_function_arg_advance): Likewise. + * config/mn10300/mn10300.c (mn10300_pass_by_reference): Likewise. + (mn10300_function_arg, mn10300_function_arg_advance): Likewise. + (mn10300_arg_partial_bytes): Likewise. + * config/ia64/ia64.c (ia64_setup_incoming_varargs): Likewise. + (ia64_arg_partial_bytes, ia64_function_arg): Likewise. + (ia64_function_incoming_arg, ia64_function_arg_advance): Likewise. + (ia64_function_arg_1): Likewise. + * config/m68k/m68k.c (m68k_function_arg_advance): Likewise. + (m68k_function_arg): Likewise. + * config/rs6000/rs6000.c (rs6000_function_arg_advance): Likewise. + (rs6000_function_arg, setup_incoming_varargs): Likewise. + (rs6000_pass_by_reference, rs6000_arg_partial_bytes): Likewise. + * config/picochip/picochip.c (picochip_arg_partial_bytes): Likewise. + (picochip_function_arg, picochip_incoming_function_arg): Likewise. + (picochip_arg_advance): Likewise. + * config/mcore/mcore.c (mcore_setup_incoming_varargs): Likewise. + (mcore_arg_partial_bytes, mcore_function_arg): Likewise. + (mcore_function_arg_advance): Likewise. + * config/score/score.c (score_pass_by_reference): Likewise. + (score_function_arg_advance): Likewise. + (score_arg_partial_bytes): Likewise. Make static. + * config/score/score-protos.h (score_arg_partial_bytes): Don't declare. + * config/arm/arm.c (arm_arg_partial_bytes): Replace + CUMULATIVE_ARGS* argument type with cumulative_args_t. + (arm_function_arg, arm_function_arg_advance): Likewise. + (arm_setup_incoming_varargs, arm_pass_by_reference): Likewise. + * config/pa/pa.c (pa_pass_by_reference): Likewise. + (pa_arg_partial_bytes, pa_function_arg_advance): Likewise. + (pa_function_arg): Likewise. + * config/mips/mips.c (mips_strict_argument_naming): Likewise. + (mips_function_arg, mips_function_arg_advance): Likewise. + (mips_arg_partial_bytes, mips_pass_by_reference): Likewise. + (mips_callee_copies, mips_setup_incoming_varargs): Likewise. + * config/vax/vax.c (vax_function_arg): Likewise. + (vax_function_arg_advance): Likewise. + * config/h8300/h8300.c (h8300_function_arg): Likewise. + (h8300_function_arg_advance): Likewise. + * config/v850/v850.c (v850_pass_by_reference): Likewise. + (v850_strict_argument_naming, v850_function_arg): Likewise. + (v850_arg_partial_bytes, v850_function_arg_advance): Likewise. + (v850_setup_incoming_varargs): Likewise. + * config/mmix/mmix.c (mmix_setup_incoming_varargs): Likewise. + (mmix_function_arg_advance, mmix_function_incoming_arg): Likewise. + (mmix_function_arg, mmix_pass_by_reference): Likewise. + (mmix_function_arg_1): Replace const CUMULATIVE_ARGS* argument type + with const void *. + * config/bfin/bfin.c (setup_incoming_varargs): Replace + CUMULATIVE_ARGS* argument type with cumulative_args_t. + (bfin_function_arg_advance, bfin_function_arg): Likewise. + (bfin_arg_partial_bytes, bfin_pass_by_reference): Likewise. + * calls.c (emit_call_1): Change type of args_so_far to + cumulative_args_t. Changed all callers. + (initialize_argument_information): Likewise. + (expand_call, emit_library_call_value_1): Use pack_cumulative_args. + * dse.c (get_call_args): Likewise. + * expr.c (block_move_libcall_safe_for_call_parm): Likewise. + * function.c (pass_by_reference, reference_callee_copied): Likewise. + (struct assign_parm_data_all): Rename args_so_far to args_so_far_v. + New member args_so_far_v. Changed all users. + * var-tracking.c (prepare_call_arguments): Use pack_cumulative_args. + * config/iq2000/iq2000.c (iq2000_expand_prologue): Likewise. + * config/mips/mips.c (mips_output_args_xfer): Likewise. + * config/s390/s390.c (s390_call_saved_register_used): Likewise. + * config/sh/sh.c (sh_output_mi_thunk): Likewise. + * config/microblaze/microblaze.c (microblaze_expand_prologue): Likewise. + * config/m32r/m32r.c (m32r_return_in_memory): Adjust for changed + m32r_pass_by_reference. + +2011-06-16 Ira Rosen <ira.rosen@linaro.org> + + * tree-vectorizer.h (vect_recog_func_ptr): Change the first + argument to be a VEC of statements. + * tree-vect-loop.c (vect_determine_vectorization_factor): + Remove the assert that pattern statements have to have their + vector type set. + * tree-vect-patterns.c (vect_recog_widen_sum_pattern): + Change the first argument to be a VEC of statements. Update + documentation. + (vect_recog_dot_prod_pattern, vect_recog_pow_pattern): Likewise. + (vect_handle_widen_mult_by_const): New function. + (vect_recog_widen_mult_pattern): Change the first argument to + be a VEC of statements. Update documentation. Check that the + constant is INTEGER_CST. Support multiplication by a constant + that fits an intermediate type - call + vect_handle_widen_mult_by_const. + (vect_pattern_recog_1): Update vect_recog_func_ptr and its + call. Handle additional pattern statements if necessary. + +2011-06-16 Nick Clifton <nickc@redhat.com> + + PR target/49427 + * config.gcc: Set cpu_type to v850 for any V850 architecture. + (v850*-*-*): Delete explicit setting of tm_p_file, tmake_file, + md_file, extra_modes, out_file and extra_options are these are all + deduced from cpu_type. + +2011-06-16 Georg-Johann Lay <avr@gjlay.de> + + * config/avr/libgcc.S (__ashldi3, __ashrdi3, __lshrdi3): Set shift + truncation mask to 63. + +2011-06-16 Georg-Johann Lay <avr@gjlay.de> + + PR target/49313 + PR target/29524 + * longlong.h: Add AVR support: + (count_leading_zeros): New macro. + (count_trailing_zeros): New macro. + (COUNT_LEADING_ZEROS_0): New macro. + * config/avr/t-avr (LIB1ASMFUNCS): Add + _ffssi2, _ffshi2, _loop_ffsqi2, + _ctzsi2, _ctzhi2, _clzdi2, _clzsi2, _clzhi2, + _paritydi2, _paritysi2, _parityhi2, + _popcounthi2,_popcountsi2, _popcountdi2, _popcountqi2, + _bswapsi2, _bswapdi2, + _ashldi3, _ashrdi3, _lshrdi3 + (LIB2FUNCS_EXCLUDE): Add _clz. + * config/avr/libgcc.S (XCALL): Move up in file. + (XJMP): New C Macro. + (DEFUN): New asm macro. + (ENDF): New asm macro. + (__ffssi2): New function. + (__ffshi2): New function. + (__loop_ffsqi2): New function. + (__ctzsi2): New function. + (__ctzhi2): New function. + (__clzdi2): New function. + (__clzsi2): New function. + (__clzhi2): New function. + (__paritydi2): New function. + (__paritysi2): New function. + (__parityhi2): New function. + (__parityqi2): New function. + (__popcounthi2): New function. + (__popcountsi2): New function. + (__popcountdi2): New function. + (__popcountqi2): New function. + (__bswapsi2): New function. + (__bswapdi2): New function. + (__ashldi3): New function. + (__ashrdi3): New function. + (__lshrdi3): New function. + Fix suspicous lines. + +2011-06-16 Richard Guenther <rguenther@suse.de> + + * gimple.c (canonicalize_cond_expr_cond): (bool)x is not + the same as x != 0. + * fold-const.c (fold_binary_loc): Do not fold X & 1 != 0 to + (bool) X & 1. + * ipa-prop.c (ipa_analyze_indirect_call_uses): Also allow + equality compares against zero for the lower bit. + +2011-06-16 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/49419 + * tree-vrp.c (execute_vrp): Call init_range_assertions + before estimate_numbers_of_iterations, call + free_number_of_iterations_estimates before calling + remove_range_assertions. + +2011-06-16 Revital Eres <revital.eres@linaro.org> + + * modulo-sched.c (struct ps_insn): Remove row_rest_count field. + (struct partial_schedule): Add rows_length field. + (verify_partial_schedule): Check rows_length. + (ps_insert_empty_row): Handle rows_length. + (create_partial_schedule): Likewise. + (free_partial_schedule): Likewise. + (reset_partial_schedule): Likewise. + (create_ps_insn): Remove rest_count argument. + (remove_node_from_ps): Update rows_length. + (add_node_to_ps): Update rows_length and call create_ps_insn + without passing row_rest_count. + (rotate_partial_schedule): Update rows_length. + +2011-06-16 Revital Eres <revital.eres@linaro.org> + + * ddg.c (add_intra_loop_mem_dep): New function. + (build_intra_loop_deps): Call it. + +2011-06-13 Jeff Law <law@redhat.com> + + * df-problems.c (df_lr_local_compute): Manually CSE + PIC_OFFSET_TABLE_REGNUM. + * df-scan.c (df_get_regular_block_artificial_uses): Likewise. + (df_get_entry_block_def_set, df_get_exit_block_use_set): Likewise. + +2011-06-13 Jan Hubicka <jh@suse.cz> + + * cgraphunit.c (handle_alias_pairs): New function. + (cgraph_finalize_compilation_unit): Use it. + * ipa.c (cgraph_externally_visible_p): Remove hack marking asm names + as externally visible. + +2011-06-15 Richard Guenther <rguenther@suse.de> + + * expr.c (expand_expr_real_2): Reduce all integral types to + bitfield precision. + (expand_expr_real_1): Likewise. + +2011-06-15 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/48613 + * ipa-prop.c (ipa_prop_write_jump_functions): Return immediately if + ipa_node_params_vector is NULL. + +2011-06-15 Jakub Jelinek <jakub@redhat.com> + + PR debug/49382 + * dwarf2out.c (dw_loc_list_node): Add force field. + (add_var_loc_to_decl): For PARM_DECL, attempt to keep + the incoming location in the list, even if it is modified + before first real insn. + (output_loc_list): Emit empty ranges with force flag set. + (dw_loc_list): If first range of a PARM_DECL is empty, + set force flag. + +2011-06-15 Alexander Monakov <amonakov@ispras.ru> + + PR target/49349 + * sel-sched.c (find_place_for_bookkeeping): Add new parameter + (fence_to_rewind). Use it to notice when bookkeeping will be placed + above a fence. Update comments. + (generate_bookkeeping_insn): Rewind fence when bookkeeping code is + placed just above it. Do not allow NULL place_to_insert. + +2011-06-15 Ira Rosen <ira.rosen@linaro.org> + + * tree-vect-loop-manip.c (remove_dead_stmts_from_loop): Remove. + (slpeel_tree_peel_loop_to_edge): Don't call + remove_dead_stmts_from_loop. + * tree-vect-loop.c (vect_determine_vectorization_factor): Don't + remove irrelevant pattern statements. For irrelevant statements + check if it is the last statement of a detected pattern, use + corresponding pattern statement instead. + (destroy_loop_vec_info): No need to remove pattern statements, + only free stmt_vec_info. + (vect_transform_loop): For irrelevant statements check if it is + the last statement of a detected pattern, use corresponding + pattern statement instead. + * tree-vect-patterns.c (vect_pattern_recog_1): Don't insert + pattern statements. Set basic block for the new statement. + (vect_pattern_recog): Update documentation. + * tree-vect-stmts.c (vect_mark_stmts_to_be_vectorized): Scan + operands of pattern statements. + (vectorizable_call): Fix printing. In case of a pattern statement + use the lhs of the original statement when creating a dummy + statement to replace the original call. + (vect_analyze_stmt): For irrelevant statements check if it is + the last statement of a detected pattern, use corresponding + pattern statement instead. + * tree-vect-slp.c (vect_schedule_slp_instance): For pattern + statements use gsi of the original statement. + +2011-06-14 Joseph Myers <joseph@codesourcery.com> + + * target-def.h (TARGET_HAVE_NAMED_SECTIONS): Move to + common/common-target-def.h. + * target.def (default_target_flags, handle_option, + supports_split_stack, optimization_table, init_struct, + except_unwind_info, unwind_tables_default, have_named_sections): + Move to common/common-target.def. + * target.h (enum opt_levels, struct default_options): Move to + common/common-target.h. + * targhooks.c (default_except_unwind_info, + dwarf2_except_unwind_info, sjlj_except_unwind_info, + default_target_handle_option, empty_optimization_table): Move to + common/common-targhooks.c. + * targhooks.h (default_except_unwind_info, + dwarf2_except_unwind_info, sjlj_except_unwind_info, + default_target_handle_option, empty_optimization_table): Move to + common/common-targhooks.h. + * common/common-target-def.h: Include common/common-targhooks.h. + (TARGET_HAVE_NAMED_SECTIONS): Define if TARGET_ASM_NAMED_SECTION + defined. + * common/common-target.def (handle_option, option_init_struct, + option_optimization_table, default_target_flags, + except_unwind_info, supports_split_stack, unwind_tables_default, + have_named_sections): Move from target.def. + (HOOK_PREFIX): Undefine at end of file. + * common/common-target.h: Include input.h. + (enum opt_levels, struct default_options): Move from target.h. + * common/common-targhooks.c, common/common-targhooks.h: New. + * config.gcc (target_has_targetm_common): Default to yes. + (moxie*): Set target_has_targetm_common=no. + (hppa*-*-*): Don't set target_has_targetm_common=yes. + * doc/tm.texi: Regenerate. + * Makefile.in (COMMON_TARGET_H): Add $(INPUT_H). + (C_TARGET_DEF_H): Add common/common-targhooks.h. + (GCC_OBJS): Remove vec.o. + (OBJS): Remove hooks.o and vec.o. + (OBJS-libcommon-target): Add vec.o, hooks.o and + common/common-targhooks.o. + (c-family/c-common.o, c-family/c-cppbuiltin.o, lto-opts.o, tree.o, + tree-tailcall.o, opts.o, toplev.o, varasm.o, function.o, except.o, + expr.o, explow.o, dbxout.o, dwarf2out.o, cfgrtl.o, haifa-sched.o, + cfglayout.o, $(out_object_file), $(common_out_object_file)): + Update dependencies. + (common/common-targhooks.o): New. + * common/config/default-common.c: Include tm.h. Add FIXME + comment. + * common/config/pa/pa-common.c: Include more headers. Take + copyright dates from pa.c. + (pa_option_optimization_table, pa_handle_option, + TARGET_OPTION_OPTIMIZATION_TABLE, TARGET_DEFAULT_TARGET_FLAGS, + TARGET_HANDLE_OPTION): Move from pa.c. + * common/config/alpha/alpha-common.c, + common/config/arm/arm-common.c, common/config/avr/avr-common.c, + common/config/bfin/bfin-common.c, + common/config/cris/cris-common.c, + common/config/fr30/fr30-common.c, common/config/frv/frv-common.c, + common/config/h8300/h8300-common.c, + common/config/i386/i386-common.c, + common/config/ia64/ia64-common.c, + common/config/iq2000/iq2000-common.c, + common/config/lm32/lm32-common.c, + common/config/m32c/m32c-common.c, + common/config/m32r/m32r-common.c, + common/config/m68k/m68k-common.c, + common/config/mcore/mcore-common.c, + common/config/mep/mep-common.c, + common/config/microblaze/microblaze-common.c, + common/config/mips/mips-common.c, + common/config/mmix/mmix-common.c, + common/config/mn10300/mn10300-common.c, + common/config/pdp11/pdp11-common.c, + common/config/picochip/picochip-common.c, + common/config/rs6000/rs6000-common.c, + common/config/rx/rx-common.c, common/config/s390/s390-common.c, + common/config/score/score-common.c, common/config/sh/sh-common.c, + common/config/sparc/sparc-common.c, + common/config/spu/spu-common.c, common/config/v850/v850-common.c, + common/config/vax/vax-common.c, + common/config/xstormy16/xstormy16-common.c, + common/config/xtensa/xtensa-common.c: New. + * config/alpha/alpha.c: Include common/common-target.h. + (alpha_option_optimization_table, alpha_handle_option, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_HANDLE_OPTION, + TARGET_OPTION_OPTIMIZATION_TABLE): Move to alpha-common.c. + * config/arm/arm-protos.h (arm_except_unwind_info): Declare. + * config/arm/arm.c (arm_option_optimization_table, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_OPTION_OPTIMIZATION_TABLE, + TARGET_EXCEPT_UNWIND_INFO, arm_except_unwind_info): Move to + arm-common.c. + * config/avr/avr.c (avr_option_optimization_table, + TARGET_OPTION_OPTIMIZATION_TABLE, TARGET_EXCEPT_UNWIND_INFO): Move + to avr-common.c. + * config/bfin/bfin.c (struct bfin_cpu): Move to bfin.h. + (bfin_cpus, bfin_handle_option, TARGET_HANDLE_OPTION, + TARGET_DEFAULT_TARGET_FLAGS): Move to bfin-common.c. + * config/bfin/bfin.h struct bfin_cpu): Move from bfin.c. + * config/cris/cris.c (cris_option_optimization_table, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_HANDLE_OPTION, + TARGET_OPTION_OPTIMIZATION_TABLE, cris_handle_option): Move to + cris-common.c. + * config/fr30/fr30.c (fr30_option_optimization_table, + TARGET_EXCEPT_UNWIND_INFO, TARGET_OPTION_OPTIMIZATION_TABLE): Move + to fr30-common.c. + * config/frv/frv.c (frv_option_optimization_table, + MASK_DEFAULT_ALLOC_CC, TARGET_DEFAULT_TARGET_FLAGS, + TARGET_OPTION_OPTIMIZATION_TABLE): Move to frv-common.c. + * config/h8300/h8300.c (h8300_option_optimization_table, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_OPTION_OPTIMIZATION_TABLE, + TARGET_EXCEPT_UNWIND_INFO): Move to h8300-common.c. + * config/i386/i386-protos.h (ix86_handle_option): Declare. + * config/i386/i386.c: Include common/common-target.h. + (OPTION_MASK_ISA_MMX_SET, OPTION_MASK_ISA_3DNOW_SET, + OPTION_MASK_ISA_SSE_SET, OPTION_MASK_ISA_SSE2_SET, + OPTION_MASK_ISA_SSE3_SET, OPTION_MASK_ISA_SSSE3_SET, + OPTION_MASK_ISA_SSE4_1_SET, OPTION_MASK_ISA_SSE4_2_SET, + OPTION_MASK_ISA_AVX_SET, OPTION_MASK_ISA_FMA_SET, + OPTION_MASK_ISA_SSE4_SET, OPTION_MASK_ISA_SSE4A_SET, + OPTION_MASK_ISA_FMA4_SET, OPTION_MASK_ISA_XOP_SET, + OPTION_MASK_ISA_LWP_SET, OPTION_MASK_ISA_AES_SET, + OPTION_MASK_ISA_PCLMUL_SET, OPTION_MASK_ISA_ABM_SET, + OPTION_MASK_ISA_BMI_SET, OPTION_MASK_ISA_TBM_SET, + OPTION_MASK_ISA_POPCNT_SET, OPTION_MASK_ISA_CX16_SET, + OPTION_MASK_ISA_SAHF_SET, OPTION_MASK_ISA_MOVBE_SET, + OPTION_MASK_ISA_CRC32_SET, OPTION_MASK_ISA_FSGSBASE_SET, + OPTION_MASK_ISA_RDRND_SET, OPTION_MASK_ISA_F16C_SET, + OPTION_MASK_ISA_MMX_UNSET, OPTION_MASK_ISA_3DNOW_UNSET, + OPTION_MASK_ISA_3DNOW_A_UNSET, OPTION_MASK_ISA_SSE_UNSET, + OPTION_MASK_ISA_SSE2_UNSET, OPTION_MASK_ISA_SSE3_UNSET, + OPTION_MASK_ISA_SSSE3_UNSET, OPTION_MASK_ISA_SSE4_1_UNSET, + OPTION_MASK_ISA_SSE4_2_UNSET, OPTION_MASK_ISA_AVX_UNSET, + OPTION_MASK_ISA_FMA_UNSET, OPTION_MASK_ISA_SSE4_UNSET, + OPTION_MASK_ISA_SSE4A_UNSET, OPTION_MASK_ISA_FMA4_UNSET, + OPTION_MASK_ISA_XOP_UNSET, OPTION_MASK_ISA_LWP_UNSET, + OPTION_MASK_ISA_AES_UNSET, OPTION_MASK_ISA_PCLMUL_UNSET, + OPTION_MASK_ISA_ABM_UNSET, OPTION_MASK_ISA_BMI_UNSET, + OPTION_MASK_ISA_TBM_UNSET, OPTION_MASK_ISA_POPCNT_UNSET, + OPTION_MASK_ISA_CX16_UNSET, OPTION_MASK_ISA_SAHF_UNSET, + OPTION_MASK_ISA_MOVBE_UNSET, OPTION_MASK_ISA_CRC32_UNSET, + OPTION_MASK_ISA_FSGSBASE_UNSET, OPTION_MASK_ISA_RDRND_UNSET, + OPTION_MASK_ISA_F16C_UNSET, ix86_handle_option, + ix86_option_optimization_table, ix86_option_init_struct, + ix86_supports_split_stack, TARGET_DEFAULT_TARGET_FLAGS, + TARGET_HANDLE_OPTION, TARGET_OPTION_OPTIMIZATION_TABLE, + TARGET_OPTION_INIT_STRUCT, TARGET_SUPPORTS_SPLIT_STACK): Move to + i386-common.c. + * config/i386/t-i386 (i386.o): Update dependencies. + * config/ia64/ia64-protos.h (ia64_except_unwind_info): Declare. + * config/ia64/ia64.c (ia64_option_optimization_table, + TARGET_OPTION_OPTIMIZATION_TABLE, TARGET_EXCEPT_UNWIND_INFO, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_HANDLE_OPTION, + ia64_handle_option): Move to ia64-common.c. + * config/iq2000/iq2000.c (iq2000_option_optimization_table, + TARGET_OPTION_OPTIMIZATION_TABLE): Move to iq2000-common.c. + * config/lm32/lm32.c (lm32_option_optimization_table, + TARGET_OPTION_OPTIMIZATION_TABLE, TARGET_EXCEPT_UNWIND_INFO): Move + to lm32-common.c. + * config/m32c/m32c.c (TARGET_HAVE_NAMED_SECTIONS): Move to + m32c-common.c. + * config/m32r/m32r.c (m32r_option_optimization_table, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_HANDLE_OPTION, + TARGET_OPTION_OPTIMIZATION_TABLE, TARGET_EXCEPT_UNWIND_INFO, + m32r_handle_option): Move to m32r-common.c. + (m32r_memory_move_cost): Remove comment referring to + TARGET_HANDLE_OPTION. + * config/m68k/m68k.c (TARGET_HANDLE_OPTION, m68k_handle_option): + Move to m68k-common.c. + * config/mcore/mcore.c (mcore_option_optimization_table, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_OPTION_OPTIMIZATION_TABLE, + TARGET_EXCEPT_UNWIND_INFO): Move to mcore-common.c. + * config/mep/mep.c (mep_option_optimization_table, + mep_handle_option, TARGET_HANDLE_OPTION, + TARGET_OPTION_OPTIMIZATION_TABLE, TARGET_DEFAULT_TARGET_FLAGS): + Move to mep-common.c. + * config/microblaze/microblaze.c + (microblaze_option_optimization_table, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_OPTION_OPTIMIZATION_TABLE, + TARGET_EXCEPT_UNWIND_INFO): Move to microblaze-common.c. + * config/mips/mips.c (mips_handle_option, + mips_option_optimization_table, TARGET_OPTION_OPTIMIZATION_TABLE, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_HANDLE_OPTION): Move to + mips-common.c. + * config/mmix/mmix.c (mmix_option_optimization_table, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_OPTION_OPTIMIZATION_TABLE): + Move to mmix-common.c. + * config/mn10300/mn10300.c (mn10300_option_optimization_table, + mn10300_handle_option, TARGET_EXCEPT_UNWIND_INFO, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_HANDLE_OPTION, + TARGET_OPTION_OPTIMIZATION_TABLE): Move to mn10300-common.c. + * config/pa/pa.c: Include common/common-target.h. + (pa_option_optimization_table, TARGET_OPTION_OPTIMIZATION_TABLE, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_HANDLE_OPTION, + pa_handle_option): Move to pa-common.c. + (pa_option_override): Use targetm_common.except_unwind_info. + (pa_asm_output_mi_thunk, pa_function_section): Use + targetm_common.have_named_sections. + * config/pdp11/pdp11.c (pdp11_option_optimization_table, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_HANDLE_OPTION, + TARGET_OPTION_OPTIMIZATION_TABLE, TARGET_OPTION_INIT_STRUCT, + pdp11_handle_option, pdp11_option_init_struct): Move to + pdp11-common.c. + * config/picochip/picochip.c (picochip_option_optimization_table, + TARGET_HAVE_NAMED_SECTIONS, TARGET_OPTION_OPTIMIZATION_TABLE, + TARGET_EXCEPT_UNWIND_INFO): Move to picochip-common.c. + * config/rs6000/rs6000.c: Include common/common-target.h. + (rs6000_option_optimization_table, TARGET_HANDLE_OPTION, + TARGET_OPTION_INIT_STRUCT, TARGET_OPTION_OPTIMIZATION_TABLE, + TARGET_DEFAULT_TARGET_FLAGS, rs6000_option_init_struct, + rs6000_handle_option): Move to rs6000-common.c. + * config/rs6000/t-rs6000 (rs6000.o): Update dependencies. + * config/rx/rx.c (rx_handle_option, rx_option_optimization_table, + TARGET_HANDLE_OPTION, TARGET_OPTION_OPTIMIZATION_TABLE, + TARGET_EXCEPT_UNWIND_INFO): Move to rx-common.c. + * config/s390/s390.c (processor_flags_table, + s390_option_optimization_table, s390_option_init_struct, + s390_handle_option, TARGET_DEFAULT_TARGET_FLAGS, + TARGET_HANDLE_OPTION, TARGET_OPTION_OPTIMIZATION_TABLE, + TARGET_OPTION_INIT_STRUCT): Move to s390-common.c. + * config/s390/s390.h (processor_flags_table): Declare. + * config/score/score.c (score_option_optimization_table, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_HANDLE_OPTION, + TARGET_OPTION_OPTIMIZATION_TABLE, MASK_ALL_CPU_BITS, + score_handle_option): Move to score-common.c. + * config/sh/sh.c (sh_option_optimization_table, + TARGET_OPTION_OPTIMIZATION_TABLE, TARGET_OPTION_INIT_STRUCT, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_HANDLE_OPTION, + sh_handle_option, sh_option_init_struct): Move to sh-common.c. + * config/sparc/sparc.c: Include common/common-target.h. + (sparc_option_optimization_table, TARGET_DEFAULT_TARGET_FLAGS, + TARGET_OPTION_OPTIMIZATION_TABLE): Move to sparc-common.c. + * config/spu/spu.c (TARGET_DEFAULT_TARGET_FLAGS, + TARGET_OPTION_INIT_STRUCT, TARGET_EXCEPT_UNWIND_INFO, + spu_option_init_struct): Move to spu-common.c. + * config/stormy16/stormy16.c (xstorym16_option_optimization_table, + TARGET_OPTION_OPTIMIZATION_TABLE): Move to xstormy16-common.c. + * config/v850/v850.c (small_memory_physical_max, + v850_handle_memory_optionn v850_handle_option, + v850_option_optimization_table, TARGET_DEFAULT_TARGET_FLAGS, + TARGET_HANDLE_OPTION, TARGET_OPTION_OPTIMIZATION_TABLE): Move to + v850-common.c. + * config/vax/vax.c (TARGET_DEFAULT_TARGET_FLAGS): Move to + vax-common.c. + * config/xtensa/xtensa.c (xtensa_option_optimization_table, + TARGET_DEFAULT_TARGET_FLAGS, TARGET_OPTION_OPTIMIZATION_TABLE): + Move to xtensa-common.c. + * cfglayout.c: Include common/common-target.h. + (fixup_reorder_chain): Use targetm_common.have_named_sections. + * cfgrtl.c: Include common/common-target.h. + (force_nonfallthru_and_redirect, commit_one_edge_insertion): Use + targetm_common.have_named_sections. + * dbxout.c: Include common/common-target.h. + (dbxout_function_end): Use targetm_common.have_named_sections. + * defaults.h (STACK_OLD_CHECK_PROTECT, STACK_CHECK_PROTECT): Use + targetm_common.except_unwind_info. + * dwarf2out.c: Include common/common-target.h. + (dwarf2out_do_frame, dwarf2out_do_cfi_asm, + dwarf2out_begin_prologue, dwarf2out_frame_init, + dwarf2out_frame_finish, dwarf2out_assembly_start): Use + targetm_common.except_unwind_info. + * except.c: Include common/common-target.h. + (init_eh, finish_eh_generation, + output_one_function_exception_table): Use + targetm_common.except_unwind_info. + (switch_to_exception_section): Use + targetm_common.have_named_sections. + * explow.c: Include common/common-target.h. + * expr.c: Include common/common-target.h. + (build_personality_function): Use + targetm_common.except_unwind_info. + * function.c: Include common/common-target.h. + (expand_function_end): Use targetm_common.except_unwind_info. + * haifa-sched.c: Include common/common-target.h. + (sched_create_recovery_edges): Use + targetm_common.have_named_sections. + * lto-opts.c: Include common/common-target.h instead of target.h. + (lto_reissue_options): Use targetm_common.handle_option. + * opts.c: Include common/common-target.h. + (target_handle_option): Use targetm_common.handle_option. + (init_options_struct): Update comment referring to + targetm.target_option.optimization. Use + targetm_common.default_target_flags, + targetm_common.unwind_tables_default and + targetm_common.option_init_struct. + (default_options_optimization): Use + targetm_common.option_optimization_table. + (finish_options): Use targetm_common.except_unwind_info, + targetm_common.unwind_tables_default, + targetm_common.have_named_sections and + targetm_common.supports_split_stack. + * toplev.c: Include common/common-target.h. + (process_options): Use targetm_common.have_named_sections. + * tree-tailcall.c: Include common/common-target.h. + (suitable_for_tail_call_opt_p): Use + targetm_common.except_unwind_info. + * tree.c: Include common/common-target.h. + (build_common_builtin_nodes): Use + targetm_common.except_unwind_info. + * varasm.c: Include common/common-target.h. + (resolve_unique_section, hot_function_section, + default_function_section): Use targetm_common.have_named_sections. + +2011-06-14 Easwaran Raman <eraman@google.com> + + PR rtl-optimization/44194 + * dse.c: Include tree-flow.h + (insn_info): Add new field non_frame_wild_read. + (group_info): Add new fields escaped_n and escaped_p. + (kill_on_calls): New variable. + (get_group_info): Initialize gi->escaped_n and gi->escaped_p. + (dse_step0): Initialize kill_on_calls. + (can_escape): New function. + (set_usage_bits): Add additional parameter; record information + about escaped locations. + (record_store): Pass EXPR corresponding to MEM to + set_usage_bits. + (dse_step2_nospill): Set kill_on_calls based on + group->escaped_n and group->escaped_n. + (add_wild_read): Refactor into... + (reset_active_stores): ... New function, and + (free_read_records): ... New function. + (add_non_frame_wild_read): New function. + (scan_insn): Call add_non_frame_wild_read on non-const calls. + (scan_reads_nospill): Handle instructions with + non_frame_wild_read. + (dse_step5_nospill): Call scan_reads_nospill for instructions + marked as non_frame_wild_read. + (dse_step7): Free escaped_n, escaped_p and kill_on_calls + bitmaps. + +2011-06-14 Joseph Myers <joseph@codesourcery.com> + + * common/common-target-def.h, common/common-target.def, + common/common-target.h, common/config/default-common.c, + common/config/pa/pa-common.c: New files. + * Makefile.in (common_out_file, common_out_object_file, + COMMON_TARGET_H, COMMON_TARGET_DEF_H): New. + (OBJS-libcommon-target): Include $(common_out_object_file). + (prefix.o): Update dependencies. + ($(common_out_object_file), common/common-target-hooks-def.h, + s-common-target-hooks-def-h): New. + (s-tm-texi): Also check timestamp on common-target.def. + (build/genhooks.o): Update dependencies. + * config.gcc (common_out_file, target_has_targetm_common): Define. + * config/pa/som.h (ALWAYS_STRIP_DOTDOT): Replace with + TARGET_ALWAYS_STRIP_DOTDOT. + * configure.ac (common_out_object_file): Define. + (common_out_file, common_out_object_file): Substitute. + (common): Create directory. + * configure: Regenerate. + * doc/tm.texi.in (targetm_common): Document. + (TARGET_ALWAYS_STRIP_DOTDOT): Add @hook entry. + * doc/tm.texi: Regenerate. + * genhooks.c (hook_array): Also include common/common-target.def. + * prefix.c (tm.h): Don't include. + (common/common-target.h): Include. + (ALWAYS_STRIP_DOTDOT): Don't define. + (update_path): Use targetm_common.always_strip_dotdot instead of + ALWAYS_STRIP_DOTDOT. + * system.h (ALWAYS_STRIP_DOTDOT): Poison. + +2011-06-14 David Li <davidxl@google.com> + + * passes.c (execute_function_todo): Remove TODO_dump_func. + (execute_one_pass): Remove TODO_dump_func. + (execute_function_dump): New function. + * tree-vrp.c: Remove TODO_dump_func. + * regrename.c: Remove TODO_dump_func. + * fwprop.c: Remove TODO_dump_func. + * tree-into-ssa.c: Remove TODO_dump_func. + * tree-complex.c: Remove TODO_dump_func. + * tracer.c: Remove TODO_dump_func. + * tree-loop-distribution.c: Remove TODO_dump_func. + * postreload-gcse.c: Remove TODO_dump_func. + * postreload.c: Remove TODO_dump_func. + * tree-ssa-loop-ch.c: Remove TODO_dump_func. + * tree-tailcall.c: Remove TODO_dump_func. + * ipa-cp.c: Remove TODO_dump_func. + * final.c: Remove TODO_dump_func. + * tree-emutls.c: Remove TODO_dump_func. + * omp-low.c: Remove TODO_dump_func. + * tree-ssa-dse.c: Remove TODO_dump_func. + * tree-ssa-uncprop.c: Remove TODO_dump_func. + * auto-inc-dec.c: Remove TODO_dump_func. + * reorg.c: Remove TODO_dump_func. + * tree-ssa-copyrename.c: Remove TODO_dump_func. + * tree-ssa-ccp.c: Remove TODO_dump_func. + * compare-elim.c: Remove TODO_dump_func. + * mode-switching.c: Remove TODO_dump_func. + * modulo-sched.c: Remove TODO_dump_func. + * tree-call-cdce.c: Remove TODO_dump_func. + * cse.c: Remove TODO_dump_func. + * web.c: Remove TODO_dump_func. + * tree-stdarg.c: Remove TODO_dump_func. + * lto-streamer-out.c: Remove TODO_dump_func. + * tree-ssa-math-opts.c: Remove TODO_dump_func. + * tree-ssa-dom.c: Remove TODO_dump_func. + * tree-nrv.c: Remove TODO_dump_func. + * loop-init.c: Remove TODO_dump_func. + * gimple-low.c: Remove TODO_dump_func. + * ipa-inline.c: Remove TODO_dump_func. + * tree-ssa-sink.c: Remove TODO_dump_func. + * jump.c: Remove TODO_dump_func. + * ifcvt.c: Remove TODO_dump_func. + * tree-ssa-loop.c: Remove TODO_dump_func. + * recog.c: Remove TODO_dump_func. + * dse.c: Remove TODO_dump_func. + * tree-ssa-ifcombine.c: Remove TODO_dump_func. + * matrix-reorg.c: Remove TODO_dump_func. + * tree-eh.c: Remove TODO_dump_func. + * regmove.c: Remove TODO_dump_func. + * function.c: Remove TODO_dump_func. + * tree-vectorizer.c: Remove TODO_dump_func. + * ipa-split.c: Remove TODO_dump_func. + * gcse.c: Remove TODO_dump_func. + * tree-if-conv.c: Remove TODO_dump_func. + * init-regs.c: Remove TODO_dump_func. + * tree-ssa-phiopt.c: Remove TODO_dump_func. + * implicit-zee.c: Remove TODO_dump_func. + * lower-subreg.c: Remove TODO_dump_func. + * bt-load.c: Remove TODO_dump_func. + * tree-dfa.c: Remove TODO_dump_func. + * except.c: Remove TODO_dump_func. + * emit-rtl.c: Remove TODO_dump_func. + * store-motion.c: Remove TODO_dump_func. + * cfgexpand.c: Remove TODO_dump_func. + * tree-cfgcleanup.c: Remove TODO_dump_func. + * cfgcleanup.c: Remove TODO_dump_func. + * tree-ssa-pre.c: Remove TODO_dump_func. + * tree-sra.c: Remove TODO_dump_func. + * tree-mudflap.c: Remove TODO_dump_func. + * tree-ssa-copy.c: Remove TODO_dump_func. + * cfglayout.c: Remove TODO_dump_func. + * tree-ssa-forwprop.c: Remove TODO_dump_func. + * tree-ssa-dce.c: Remove TODO_dump_func. + * ira.c: Remove TODO_dump_func. + * tree-ssa.c: Remove TODO_dump_func. + * integrate.c: Remove TODO_dump_func. + * tree-optimize.c: Remove TODO_dump_func. + * tree-ssa-phiprop.c: Remove TODO_dump_func. + * tree-object-size.c: Remove TODO_dump_func. + * combine.c: Remove TODO_dump_func. + * bb-reorder.c: Remove TODO_dump_func. + * cprop.c: Remove TODO_dump_func. + * var-tracking.c: Remove TODO_dump_func. + * tree-profile.c: Remove TODO_dump_func. + * tree-vect-generic.c: Remove TODO_dump_func. + * reg-stack.c: Remove TODO_dump_func. + * sched-rgn.c: Remove TODO_dump_func. + * tree-ssa-structalias.c: Remove TODO_dump_func. + * tree-switch-conversion.c: Remove TODO_dump_func. + * tree-cfg.c: Remove TODO_dump_func. + * tree-ssa-reassoc.c: Remove TODO_dump_func. + * combine-stack-adj.c: Remove TODO_dump_func. + * dce.c: Remove TODO_dump_func. + * tree-ssanames.c: Remove TODO_dump_func. + * regcprop.c: Remove TODO_dump_func. + +2011-06-14 H.J. Lu <hongjiu.lu@intel.com> + + PR middle-end/47364 + * builtins.c (expand_builtin_strlen): Expand strlen to Pmode + and properly handle result not in Pmode. + +2011-06-14 Robert Millan <rmh@gnu.org> + + * config/i386/kfreebsd-gnu.h: Resync with `config/i386/linux.h'. + * config/kfreebsd-gnu.h (GNU_USER_DYNAMIC_LINKER): Resync with + `config/linux.h'. + + * config/i386/kfreebsd-gnu64.h: New file. + * config.gcc (x86_64-*-kfreebsd*-gnu): Replace `i386/kfreebsd-gnu.h' + with `i386/kfreebsd-gnu64.h'. + + * config/i386/linux64.h (GNU_USER_LINK_EMULATION32) + (GNU_USER_LINK_EMULATION64): New macros. + * config/i386/gnu-user64.h (LINK_SPEC): Rely on + `GNU_USER_LINK_EMULATION32' and `GNU_USER_LINK_EMULATION64' instead + of hardcoding `elf_i386' and `elf_x86_64'. + +2011-06-14 Nick Clifton <nickc@redhat.com> + + PR target/49403 + * config/v850/v850.c (v850_memory_move_cost): Add reg_class_t parameter. + + PR target/49402 + * config.gcc(v850*-*-*): Avoid duplication of v850.opt. + +2011-06-14 Jakub Jelinek <jakub@redhat.com> + + PR fortran/49103 + * tree.h (DECL_NONSHAREABLE): Define. + (struct tree_decl_common): Change decl_common_unused to + decl_nonshareable_flag. + * cfgexpand.c (expand_used_vars_for_block, clear_tree_used): + Ignore vars with DECL_NONSHAREABLE bit set. + * tree-cfg.c (gimple_duplicate_bb): Set DECL_NONSHAREABLE + on stores to automatic aggregate vars. + + PR rtl-optimization/49390 + Revert: + 2010-06-29 Bernd Schmidt <bernds@codesourcery.com> + + * cse.c (exp_equiv_p): For MEMs, if for_gcse, only compare + MEM_ALIAS_SET. + +2011-06-14 Zdenek Dvorak <ook@ucw.cz> + Tom de Vries <tom@codesourcery.com> + + PR target/45098 + * cfgloop.h (nb_iterations_upper_bound, nb_iterations_estimate): + Document changed semantics. + (max_stmt_executions, max_stmt_executions_int): Declare. + * tree-data-ref.c (estimated_loop_iterations) + (estimated_loop_iterations_int): Move functions... + * tree-ssa-loop-niter.c (estimated_loop_iterations) + (estimated_loop_iterations_int): here. + (record_estimate): Change nb_iterations_upper_bound and + nb_iterations_estimate semantics. + (max_stmt_executions, max_stmt_executions_int): New function. + * tree-data-ref.c (estimated_loop_iterations_tree): Rename to ... + (max_stmt_executions_tree): this. + (analyze_miv_subscript): Use max_stmt_executions_tree instead of + estimated_loop_iterations_tree. + tree-ssa-loop-ivopts.c (avg_loop_niter): Use + max_stmt_executions_int instead of estimated_loop_iterations_int. + * predict.c (predict_loops): Idem. + * tree-parloops.c (parallelize_loops): Idem. + * tree-data-ref.c (analyze_siv_subscript_cst_affine) + (compute_overlap_steps_for_affine_1_2, analyze_subscript_affine_affine) + (init_omega_for_ddr_1): Idem. + * tree-ssa-loop-prefetch.c (determine_loop_nest_reuse) + (loop_prefetch_arrays): Idem + * graphite-sese-to-poly.c (build_loop_iteration_domains): Use + max_stmt_executions instead of estimated_loop_iterations. + * tree-data-ref.c (estimated_loop_iterations_tree): Idem. + * tree-vrp.c (adjust_range_with_scev): Use estimated_loop_iterations + instead of nb_iterations_upper_bound. + +2011-06-13 Jan Hubicka <jh@suse.cz> + + * ipa.c (cgraph_address_taken_from_non_vtable_p): Check the ref type. + +2011-06-14 Richard Henderson <rth@redhat.com> + + PR debug/48459 + * dwarf2out.c (frame_pointer_fb_offset_valid): New. + (based_loc_descr): Assert it's true. + (compute_frame_pointer_to_fb_displacement): Set it, rather than + aborting immediately. + +2011-06-14 Sanjin Liu <scliu@faraday-tech.com> + Mingfeng Wu <mingfeng@faraday-tech.com> + + * doc/invoke.texi: Re-add missing -mcpu docs for Faraday cores. + +2011-06-13 Jan Hubicka <jh@suse.cz> + + * ipa-cp.c (ipcp_iterate_stage): Revert accidental commit. + +2011-06-13 Jan Hubicka <jh@suse.cz> + + * cgraph.c (cgraph_make_decl_local): Handle DECL_ONE_ONLY + similarly to DECL_COMDAT. + * cgraphunit.c (cgraph_analyze_function): Likewise. + * ipa.c (function_and_variable_visibility): Likewise. + +2011-06-13 Jan Hubicka <jh@suse.cz> + + * lto-streamer-out.c (lto_output_ts_binfo_tree_pointers): Do not output + BINFO_VIRTUALS when streaming for ltrans unit. + +2011-06-13 David Edelsohn <dje.gcc@gmail.com> + + * config/rs6000/rs6000.md (movdi_mfpgpr): Remove POWER mnemonic. + (movdi_internal64): Same. + +2011-06-13 Edmar Wienskoski <edmar@freescale.com> + + PR target/44618 + * config/rs6000/rs6000.md (save_gpregs_<mode>): Replaced pattern with + a set of similar patterns, where the MATCH_OPERAND for the function + argument is replaced with individual references to hardware registers. + (save_fpregs_<mode>): Ditto + (restore_gpregs_<mode>): Ditto + (return_and_restore_gpregs_<mode>): Ditto + (return_and_restore_fpregs_<mode>): Ditto + (return_and_restore_fpregs_aix_<mode>): Ditto + +2011-06-13 Jan Hubicka <jh@suse.cz> + + * ipa-utils.c (postorder_stack): New structure. + (ipa_reverse_postorder): Handle aliases. + +2011-06-13 Jan Hubicka <jh@suse.cz> + + * ipa-inline.c (reset_edge_caches): Walk aliases. + (update_caller_keys): Do not test inlinability of aliases. + * ipa-inline-analysis.c (do_estimate_edge_time): Look through alias. + (do_estimate_growth): Fix typo. + +2011-06-13 Jan Hubicka <jh@suse.cz> + + * ipa-inline-transform.c (+can_remove_node_now_p_1): Break out from... + (can_remove_node_now_p): ... here; handle same comdat groups. + (clone_inlined_nodes): Update use of can_remove_node_now_p add TODO. + (inline_call): Update use of can_remove_node_now_p. + +2011-06-13 Kaushik Phatak <kaushik.phatak@kpitcummins.com> + + * config/h8300/h8300.md (bsetqi_msx, bclrqi_msx, bnotqi_msx): Added + condition to disallow non-identical memory locations. + (*andqi3_2, andqi3_1, iorqi3_1, xorqi3_1): Reorder insn to give + preference to bit manipulation instructions. + +2011-06-13 Jan Hubicka <jh@suse.cz> + + * cgraph.c (cgraph_for_node_thunks_and_aliases, + cgraph_for_node_and_aliases): Fix thinko in recursive walking. + (nonremovable_p): New function. + (cgraph_can_remove_if_no_direct_calls_p): New function. + (used_from_object_file_p): New functoin. + (cgraph_will_be_removed_from_program_if_no_direct_calls): Look for + references from aliases. + * cgraph.h (cgraph_can_remove_if_no_direct_calls_p): Bring offline. + * ipa-inline.c (check_caller_edge): New function. + (want_inline_function_called_once_p): Use it; accept aliases called + once, too. + * ipa-inline-analysis.c (do_estimate_growth): Remove FIXME. + +2011-06-13 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org> + + PR target/48454 + * config/arm/neon.md (vec_pack_trunc): Set the lengths + correctly for the case with Quad vectors. + +2011-06-13 Jakub Jelinek <jakub@redhat.com> + Ira Rosen <ira.rosen@linaro.org> + + PR tree-optimization/49352 + * tree-vect-loop.c (vect_is_slp_reduction): Don't count debug uses at + all, make sure loop_use_stmt after the loop is a def stmt of a used + SSA_NAME that is the only one defined inside of the loop. Don't + check for COND_EXPR and GIMPLE_BINARY_RHS. + (vect_is_simple_reduction_1): Call vect_is_slp_reduction only if + check_reduction is true. + +2011-06-11 Jan Hubicka <jh@suse.cz> + + PR middle-end/49373 + * ipa.c (cgraph_externally_visible_p): Check resolution info. + +2011-06-11 Jan Hubicka <jh@suse.cz> + + PR middle-end/48836 + * ipa-inline-transform.c: Include tree-pass.h + (inline_transform): Set TODO_update_ssa_only_virtuals. + * Makefile.in (ipa-inline-transform.o): Add tree-pass.h. + +2011-06-11 Jan Hubicka <jh@suse.cz> + + PR middle-end/49378 + * ipa.c (cgraph_non_local_node_p_1, cgraph_local_node_p): Rule out + aliases and thunks. + +2011-06-12 Ira Rosen <ira.rosen@linaro.org> + + * tree-vect-data-refs.c (vect_peeling_hash_get_most_frequent): + Take number of iterations to peel into account for equally frequent + misalignment values. + +2011-06-11 Jan Hubicka <jh@suse.cz> + + * lto-streamer-out.c (produce_symtab): Stream out the newly represented + aliases. + +2011-06-11 Jan Hubicka <jh@suse.cz> + + * ipa-prop.c (ipa_make_edge_direct_to_target): Fix code setting varying + args. + (ipa_update_after_lto_read): Likewise. + (ipa_write_node_info): Do not sream call_with_var_arguments. + (ipa_read_node_info): Likewise. + +2011-06-11 Jan Hubicka <jh@suse.cz> + + * ipa.c (cgraph_comdat_can_be_unshared_p): Fix pasto. + +2011-06-11 Jan Hubicka <jh@suse.cz> + + * lto-symtab.c (lto_cgraph_replace_node): Kill same body alias code. + (lto_symtab_resolve_can_prevail_p): Likewise. + (lto_symtab_merge_cgraph_nodes): Update merging of aliases. + * cgraph.c (same_body_aliases_done): New global var. + (cgraph_same_body_alias_1): Rename to ... + (cgraph_create_function_alias): ... this one; reorg to new + representation. + (cgraph_same_body_alias): Use cgraph_create_function_alias; + record references when asked to. + (cgraph_add_thunk): Fix formating. + (cgraph_get_node): Kill same body alias code. + (cgraph_node_for_asm): Likewise. + (cgraph_remove_same_body_alias): Remove. + (cgraph_remove_node): Kill same body alias code. + (cgraph_mark_address_taken_node): Mark also the aliased function + as having address taken. + (dump_cgraph_node): Dump same body aliases. + (cgraph_for_node_thunks_and_aliases): Update for new alias + representation. + (cgraph_for_node_and_aliases): Likewise. + * cgraph.h (same_body): Kll pointer. + (same_body_alias): Update comment. + (same_body_aliases_done): Declare. + (cgraph_remove_same_body_alias): Remove declaration. + (cgraph_create_function_alias): Declare. + (cgraph_process_same_body_aliases): Declare. + (cgraph_function_with_gimple_body_p): Check for alias. + (cgraph_can_remove_if_no_direct_calls_p): Look for aliases. + (cgraph_alias_aliased_node): New function. + (cgraph_function_node): Update for new aliases. + (cgraph_function_or_thunk_node): Likewise. + * ipa-inline-transform.c (can_remove_node_now_p): Look for aliases. + (inline_call): Remove dead aliases. + * cgraphunit.c (cgraph_decide_is_function_needed): Disable assembler + name hack for same body aliases. + (clone_of_p): Look through aliases. + (verify_cgraph_node): Verify aliases. + (cgraph_analyze_function): Analyze aliases; fixup C++ bugs. + (cgraph_process_same_body_aliases): New function. + (process_function_and_variable_attributes): Disable weakref warning on + alias. + (cgraph_analyze_functions): Handle aliases. + (cgraph_mark_functions_to_output): Handle aliases same way as thunks. + (assemble_thunks): Rename to ... + (assemble_thunks_and_aliases): ... this one; handle aliases, too. + (cgraph_expand_function): Remove alias output code. + (cgraph_output_in_order): Skip aliases. + (cgraph_preserve_function_body_p): Aliases don't need preserving. + * ipa-ref.c (ipa_ref_use_name): Add alias reference. + (ipa_record_reference): Do not assert on alias references. + (ipa_ref_has_aliases_p): New function. + * ipa-ref.h (enum ipa_ref_use): Add IPA_REF_ALIAS. + (ipa_ref_has_aliases_p): Declare. + * lto-cgraph.c (lto_output_node): Handle aliases. + (input_node): Likewise. + * lto-streamer-out.c (lto_output): Skip aliases. + (produce_symtab): Kill same_body_alias code. + * ipa-utils.c (ipa_reverse_postorder): Add FIXME. + (ipa_reverse_postorder): Use cgraph_only_called_directly_or_aliased_p. + * ipa-inline.c (update_caller_keys): Walk aliases. + (inline_small_functions): Fix thinko in previous patch. + * ipa.c (cgraph_externally_visible_p): Do not walk aliases. + (function_and_variable_visibility): Do not walk same body aliases. + * tree-ssa-structalias.c (associate_varinfo_to_alias): New function. + (ipa_pta_execute): Use it. + +2011-06-11 Uros Bizjak <ubizjak@gmail.com> + + * config/i386/sse.md (vec_dupv4sf): Correct mode of forced register. + (*vec_dupv2df): Rename from vec_dupv2df. + (vec_dupv2df): New expander. + +2011-06-11 Uros Bizjak <ubizjak@gmail.com> + + * config/i386/sse.md (AVX_VEC_DUP_MODE): Rename from AVX256MODE24P. + +2011-06-11 Uros Bizjak <ubizjak@gmail.com> + + * config/i386/i386.md: Use default value in "isa" attribute. + * config/i386/sse.md: Ditto. + * config/i386/mmx.md: Ditto. + 2011-06-10 Wei Guozhi <carrot@google.com> PR target/45335 @@ -44,19 +1369,20 @@ 2011-06-10 Jan Hubicka <jh@suse.cz> * opts.c (default_options): Enlist OPT_finline_functions_called_once. - * common.opt (flag_inline_functions_called_once):Do not initialize to 1. + * common.opt (flag_inline_functions_called_once): Do not + initialize to 1. 2011-06-10 Jan Hubicka <jh@suse.cz> * ipa-cp.c (ipcp_versionable_function_p): Thunks are not versionable. - (ipcp_initialize_node_lattices): Do not deal with aliases; Do not try to - propagate through thunks. + (ipcp_initialize_node_lattices): Do not deal with aliases; + Do not try to propagate through thunks. (ipcp_change_tops_to_bottom): Do not deal with aliases. 2011-06-10 Jan Hubicka <jh@suse.cz> - * ipa-prop.c (ipa_write_node_info): Stream jump functions for indirect - calls. + * ipa-prop.c (ipa_write_node_info): Stream jump functions + for indirect calls. (ipa_read_node_info): Likewise. 2011-06-10 Bill Schmidt <wschmidt@linux.vnet.ibm.com> @@ -68,7 +1394,7 @@ (gimple_expand_builtin_pow): Minor cleanup. (gimple_expand_builtin_cabs): New. (execute_cse_sincos): Add case for BUILT_IN_CABS. - + 2011-06-10 Jan Hubicka <jh@suse.cz> * ipa-cp.c (ipcp_versionable_function_p): Aliases are not versionable. @@ -145,9 +1471,8 @@ 2011-06-10 Richard Guenther <rguenther@suse.de> - * tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): - Scan stmts forward when combining, visit inserted stmts when - a stmt was changed. + * tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): Scan stmts + forward when combining, visit inserted stmts when a stmt was changed. 2011-06-10 Paolo Carlini <paolo.carlini@oracle.com> @@ -163,7 +1488,7 @@ when a value is actually passed in regs. 2011-06-10 Eric Botcazou <ebotcazou@adacore.com> - Laurent Rougé <laurent.rouge@menta.fr> + Laurent Rougé <laurent.rouge@menta.fr> * doc/invoke.texi (SPARC options): Add -mflat. * config/sparc/sparc.opt: Likewise. @@ -267,8 +1592,7 @@ 2011-06-10 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org> Richard Earnshaw <rearnsha@arm.com> - * config/arm/arm.c (const_ok_for_op): Check to see - if mvn can be used. + * config/arm/arm.c (const_ok_for_op): Check to see if mvn can be used. * config/arm/vfp.md (*arm_movdi_vfp): Delete. (*thumb2_movdi_vfp): Delete. (*arm_movdi_vfp_cortexa8): Delete. @@ -317,17 +1641,23 @@ (cgraph_for_node_thunks_and_aliases): New function. (cgraph_for_node_and_aliases): New function. (cgraph_make_node_local_1): Break out from ... - (cgraph_make_node_local) ... here; use cgraph_for_node_thunks_and_aliases. + (cgraph_make_node_local) ... here; use + cgraph_for_node_thunks_and_aliases. (cgraph_set_nothrow_flag_1): Break out from ... - (cgraph_set_nothrow_flag) ... here; use cgraph_for_node_thunks_and_aliases. + (cgraph_set_nothrow_flag) ... here; + use cgraph_for_node_thunks_and_aliases. (cgraph_set_const_flag_1): Break out from ... - (cgraph_set_const_flag) ... here; use cgraph_for_node_thunks_and_aliases. + (cgraph_set_const_flag) ... here; + use cgraph_for_node_thunks_and_aliases. (cgraph_set_pure_flag_1): Break out from ... - (cgraph_set_pure_flag) ... here; use cgraph_for_node_thunks_and_aliases. + (cgraph_set_pure_flag) ... here; + use cgraph_for_node_thunks_and_aliases. (cgraph_propagate_frequency_1): Break out from ... - (cgraph_propagate_frequency) ... here; use cgraph_for_node_thunks_and_aliases. + (cgraph_propagate_frequency) ... here; use + cgraph_for_node_thunks_and_aliases. (cgraph_used_from_object_file_p): Do not care about aliases. - (cgraph_not_only_called_directly_p_1, cgraph_only_called_directly_p): New functions. + (cgraph_not_only_called_directly_p_1, cgraph_only_called_directly_p): + New functions. (collect_callers_of_node_1, collect_callers_of_node): New functions. 2011-06-10 Hans-Peter Nilsson <hp@axis.com> @@ -348,16 +1678,14 @@ 2011-06-10 Hans-Peter Nilsson <hp@axis.com> PR rtl-optimization/49154 - * ira-costs.c (setup_regno_cost_classes_by_mode): If there - already is a matching slot in the hashtable, assign it to - classes_ptr. + * ira-costs.c (setup_regno_cost_classes_by_mode): If there already + is a matching slot in the hashtable, assign it to classes_ptr. PR rtl-optimization/49154 * doc/tm.texi.in (Register Classes): Document rule for the narrowest register classes. * doc/tm.texi: Regenerate. ->>>>>>> .r174929 2011-06-09 Kaz Kojima <kkojima@gcc.gnu.org> PR target/49307 @@ -898,7 +2226,7 @@ * config/ia64/unwind-ia64.c: Likewise. * config/xtensa/unwind-dw2-xtensa.c: Likewise. -2011-06-03 Jack Howarth <howarth@bromo.med.uc.edu> +2011-06-03 Jack Howarth <howarth@bromo.med.uc.edu> * varpool.c (varpool_extra_name_alias): Return NULL, not false. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index ab7989c3752..8157ec938d6 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20110611 +20110620 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 4d091bb0db4..75980939ed6 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -480,6 +480,8 @@ TM_MULTILIB_CONFIG=@TM_MULTILIB_CONFIG@ TM_MULTILIB_EXCEPTIONS_CONFIG=@TM_MULTILIB_EXCEPTIONS_CONFIG@ out_file=$(srcdir)/config/@out_file@ out_object_file=@out_object_file@ +common_out_file=$(srcdir)/common/config/@common_out_file@ +common_out_object_file=@common_out_object_file@ md_file=$(srcdir)/config/@md_file@ tm_file_list=@tm_file_list@ tm_include_list=@tm_include_list@ @@ -888,15 +890,19 @@ VEC_H = vec.h statistics.h EXCEPT_H = except.h $(HASHTAB_H) vecprim.h vecir.h TARGET_DEF = target.def target-hooks-macros.h C_TARGET_DEF = c-family/c-target.def target-hooks-macros.h +COMMON_TARGET_DEF = common/common-target.def target-hooks-macros.h TARGET_H = $(TM_H) target.h $(TARGET_DEF) insn-modes.h C_TARGET_H = c-family/c-target.h $(C_TARGET_DEF) +COMMON_TARGET_H = common/common-target.h $(INPUT_H) $(COMMON_TARGET_DEF) MACHMODE_H = machmode.h mode-classes.def insn-modes.h HOOKS_H = hooks.h $(MACHMODE_H) HOSTHOOKS_DEF_H = hosthooks-def.h $(HOOKS_H) LANGHOOKS_DEF_H = langhooks-def.h $(HOOKS_H) TARGET_DEF_H = target-def.h target-hooks-def.h $(HOOKS_H) targhooks.h C_TARGET_DEF_H = c-family/c-target-def.h c-family/c-target-hooks-def.h \ - $(TREE_H) $(C_COMMON_H) $(HOOKS_H) + $(TREE_H) $(C_COMMON_H) $(HOOKS_H) common/common-targhooks.h +COMMON_TARGET_DEF_H = common/common-target-def.h \ + common/common-target-hooks-def.h $(HOOKS_H) RTL_BASE_H = rtl.h rtl.def $(MACHMODE_H) reg-notes.def insn-notes.def \ $(INPUT_H) $(REAL_H) statistics.h $(VEC_H) $(FIXED_VALUE_H) alias.h \ $(HASHTAB_H) @@ -1168,7 +1174,7 @@ CXX_TARGET_OBJS=@cxx_target_objs@ FORTRAN_TARGET_OBJS=@fortran_target_objs@ # Object files for gcc driver. -GCC_OBJS = gcc.o vec.o ggc-none.o +GCC_OBJS = gcc.o ggc-none.o # Language-specific object files shared by all C-family front ends. C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \ @@ -1288,7 +1294,6 @@ OBJS = \ graphite-sese-to-poly.o \ gtype-desc.o \ haifa-sched.o \ - hooks.o \ hwint.o \ ifcvt.o \ implicit-zee.o \ @@ -1480,7 +1485,6 @@ OBJS = \ var-tracking.o \ varasm.o \ varpool.o \ - vec.o \ vmsdbgout.o \ web.o \ xcoffout.o \ @@ -1494,7 +1498,8 @@ OBJS-libcommon = diagnostic.o pretty-print.o intl.o input.o version.o # Objects in libcommon-target.a, used by drivers and by the core # compiler and containing target-dependent code. -OBJS-libcommon-target = prefix.o opts-common.o options.o +OBJS-libcommon-target = $(common_out_object_file) prefix.o opts-common.o \ + options.o vec.o hooks.o common/common-targhooks.o # This lists all host objects for the front ends. ALL_HOST_FRONTEND_OBJS = $(C_OBJS) \ @@ -2147,11 +2152,11 @@ c-family/c-common.o : c-family/c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ intl.h $(OPTS_H) $(CPPLIB_H) $(TREE_INLINE_H) $(HASHTAB_H) \ $(BUILTINS_DEF) $(CGRAPH_H) $(BASIC_BLOCK_H) $(TARGET_DEF_H) \ $(LIBFUNCS_H) \ - gt-c-family-c-common.h + gt-c-family-c-common.h $(COMMON_TARGET_H) c-family/c-cppbuiltin.o : c-family/c-cppbuiltin.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) $(TREE_H) version.h $(C_COMMON_H) $(C_PRAGMA_H) \ - $(FLAGS_H) output.h $(TREE_H) $(TARGET_H) \ + $(FLAGS_H) output.h $(TREE_H) $(TARGET_H) $(COMMON_TARGET_H) \ $(TM_P_H) debug.h $(CPP_ID_DATA_H) cppbuiltin.h $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ $< $(OUTPUT_OPTION) @@ -2234,8 +2239,8 @@ incpath.o: incpath.c incpath.h $(CONFIG_H) $(SYSTEM_H) $(CPPLIB_H) \ intl.h prefix.h coretypes.h $(TM_H) cppdefault.h $(TARGET_H) \ $(MACHMODE_H) -prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) prefix.h \ - Makefile $(BASEVER) +prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h prefix.h \ + $(COMMON_TARGET_H) Makefile $(BASEVER) $(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ -DPREFIX=\"$(prefix)\" -DBASEVER=$(BASEVER_s) \ -c $(srcdir)/prefix.c $(OUTPUT_OPTION) @@ -2392,7 +2397,7 @@ lto-symtab.o: lto-symtab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(LTO_STREAMER_H) $(LINKER_PLUGIN_API_H) gt-lto-symtab.h lto-opts.o: lto-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ $(HASHTAB_H) $(GGC_H) $(BITMAP_H) $(FLAGS_H) $(OPTS_H) $(OPTIONS_H) \ - $(TARGET_H) $(DIAGNOSTIC_H) $(LTO_STREAMER_H) + $(COMMON_TARGET_H) $(DIAGNOSTIC_H) $(LTO_STREAMER_H) lto-streamer.o: lto-streamer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TREE_H) $(GIMPLE_H) $(BITMAP_H) $(LTO_STREAMER_H) $(FLAGS_H) \ $(TREE_FLOW_H) $(DIAGNOSTIC_CORE_H) $(LTO_SYMTAB_H) toplev.h $(DIAGNOSTIC_CORE_H) @@ -2406,7 +2411,8 @@ tree.o: tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ langhooks.h gt-tree.h $(TREE_INLINE_H) tree-iterator.h \ $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(OBSTACK_H) pointer-set.h \ tree-pass.h $(LANGHOOKS_DEF_H) $(DIAGNOSTIC_H) $(CGRAPH_H) $(TIMEVAR_H) \ - $(EXCEPT_H) debug.h intl.h tree-diagnostic.h tree-pretty-print.h + $(EXCEPT_H) debug.h intl.h tree-diagnostic.h tree-pretty-print.h \ + $(COMMON_TARGET_H) tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h toplev.h $(SPLAY_TREE_H) $(TREE_DUMP_H) \ tree-iterator.h $(TREE_PASS_H) $(DIAGNOSTIC_H) @@ -2571,7 +2577,8 @@ tree-cfgcleanup.o : tree-cfgcleanup.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ tree-tailcall.o : tree-tailcall.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_P_H) $(FUNCTION_H) $(TM_H) coretypes.h \ $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(EXCEPT_H) $(TREE_PASS_H) $(FLAGS_H) langhooks.h \ - $(BASIC_BLOCK_H) $(DBGCNT_H) gimple-pretty-print.h $(TARGET_H) + $(BASIC_BLOCK_H) $(DBGCNT_H) gimple-pretty-print.h $(TARGET_H) \ + $(COMMON_TARGET_H) tree-ssa-sink.o : tree-ssa-sink.c $(TREE_FLOW_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \ $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(FLAGS_H) alloc-pool.h \ @@ -2845,7 +2852,7 @@ diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ version.h $(INPUT_H) intl.h $(DIAGNOSTIC_H) diagnostic.def opts.o : opts.c $(OPTS_H) $(OPTIONS_H) $(DIAGNOSTIC_CORE_H) $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) $(RTL_H) \ - $(DIAGNOSTIC_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \ + $(DIAGNOSTIC_H) $(INSN_ATTR_H) intl.h $(TARGET_H) $(COMMON_TARGET_H) \ $(FLAGS_H) $(PARAMS_H) opts-diagnostic.h opts-global.o : opts-global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(DIAGNOSTIC_H) $(OPTS_H) $(FLAGS_H) $(GGC_H) $(TREE_H) langhooks.h \ @@ -2858,6 +2865,8 @@ targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ $(MACHMODE_H) $(TARGET_DEF_H) $(TARGET_H) $(GGC_H) gt-targhooks.h \ $(OPTABS_H) $(RECOG_H) reload.h hard-reg-set.h intl.h $(OPTS_H) \ tree-ssa-alias.h $(TREE_FLOW_H) +common/common-targhooks.o : common/common-targhooks.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(INPUT_H) $(TM_H) $(COMMON_TARGET_H) common/common-targhooks.h #### added for MELT http://gcc.gnu.org/wiki/MiddleEndLispTranslator @@ -2923,7 +2932,7 @@ toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(CGRAPH_H) $(COVERAGE_H) alloc-pool.h $(GGC_H) $(INTEGRATE_H) \ $(OPTS_H) params.def tree-mudflap.h $(TREE_PASS_H) $(GIMPLE_H) \ tree-ssa-alias.h $(PLUGIN_H) realmpfr.h tree-diagnostic.h \ - tree-pretty-print.h opts-diagnostic.h + tree-pretty-print.h opts-diagnostic.h $(COMMON_TARGET_H) $(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ -DTARGET_NAME=\"$(target_noncanonical)\" \ -c $(srcdir)/toplev.c $(OUTPUT_OPTION) @@ -2970,13 +2979,13 @@ varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ output.h $(DIAGNOSTIC_CORE_H) xcoffout.h debug.h $(GGC_H) $(TM_P_H) \ $(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h $(BASIC_BLOCK_H) \ $(CFGLAYOUT_H) $(CGRAPH_H) targhooks.h tree-mudflap.h \ - tree-iterator.h pointer-set.h + tree-iterator.h pointer-set.h $(COMMON_TARGET_H) function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_H) \ $(TREE_H) $(CFGLAYOUT_H) $(GIMPLE_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) \ $(OPTABS_H) $(LIBFUNCS_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \ output.h $(EXCEPT_H) $(HASHTAB_H) $(GGC_H) $(TM_P_H) langhooks.h \ gt-function.h $(TARGET_H) $(BASIC_BLOCK_H) $(INTEGRATE_H) $(PREDICT_H) \ - $(TREE_PASS_H) $(DF_H) $(TIMEVAR_H) vecprim.h + $(TREE_PASS_H) $(DF_H) $(TIMEVAR_H) vecprim.h $(COMMON_TARGET_H) statistics.o : statistics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TREE_PASS_H) $(TREE_DUMP_H) $(HASHTAB_H) statistics.h $(FUNCTION_H) stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ @@ -2991,14 +3000,15 @@ except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ dwarf2asm.h dwarf2out.h toplev.h $(DIAGNOSTIC_CORE_H) $(HASHTAB_H) intl.h $(GGC_H) \ gt-except.h $(CGRAPH_H) $(INTEGRATE_H) $(DIAGNOSTIC_H) $(DWARF2_H) \ $(TARGET_H) $(TM_P_H) $(TREE_PASS_H) $(TIMEVAR_H) $(TREE_FLOW_H) \ - tree-pretty-print.h sbitmap.h + tree-pretty-print.h sbitmap.h $(COMMON_TARGET_H) expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) $(EXPR_H) $(OPTABS_H) \ $(LIBFUNCS_H) $(INSN_ATTR_H) insn-config.h $(RECOG_H) output.h \ typeclass.h hard-reg-set.h toplev.h $(DIAGNOSTIC_CORE_H) hard-reg-set.h $(EXCEPT_H) \ reload.h langhooks.h intl.h $(TM_P_H) $(TARGET_H) \ tree-iterator.h gt-expr.h $(MACHMODE_H) $(TIMEVAR_H) $(TREE_FLOW_H) \ - $(TREE_PASS_H) $(DF_H) $(DIAGNOSTIC_H) vecprim.h $(SSAEXPAND_H) + $(TREE_PASS_H) $(DF_H) $(DIAGNOSTIC_H) vecprim.h $(SSAEXPAND_H) \ + $(COMMON_TARGET_H) dojump.o : dojump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H) $(INSN_ATTR_H) insn-config.h \ langhooks.h $(GGC_H) gt-dojump.h vecprim.h $(BASIC_BLOCK_H) output.h @@ -3021,7 +3031,7 @@ expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_ explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ $(FLAGS_H) hard-reg-set.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \ $(DIAGNOSTIC_CORE_H) $(EXCEPT_H) $(FUNCTION_H) $(GGC_H) $(TM_P_H) langhooks.h gt-explow.h \ - $(TARGET_H) output.h + $(TARGET_H) $(COMMON_TARGET_H) output.h optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) insn-config.h $(EXPR_H) $(OPTABS_H) $(LIBFUNCS_H) \ $(RECOG_H) reload.h $(DIAGNOSTIC_CORE_H) $(GGC_H) $(TM_P_H) \ @@ -3030,7 +3040,7 @@ dbxout.o : dbxout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(RTL_H) $(FLAGS_H) $(REGS_H) debug.h $(TM_P_H) $(TARGET_H) $(FUNCTION_H) \ langhooks.h insn-config.h reload.h $(GSTAB_H) xcoffout.h output.h dbxout.h \ toplev.h $(DIAGNOSTIC_CORE_H) $(GGC_H) $(OBSTACK_H) $(EXPR_H) $(CGRAPH_H) \ - gt-dbxout.h + gt-dbxout.h $(COMMON_TARGET_H) debug.o : debug.c debug.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) sdbout.o : sdbout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) debug.h \ $(TREE_H) $(GGC_H) $(RTL_H) $(REGS_H) $(FLAGS_H) insn-config.h \ @@ -3042,7 +3052,8 @@ dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(LIBFUNCS_H) toplev.h $(DIAGNOSTIC_CORE_H) dwarf2out.h reload.h \ $(GGC_H) $(EXCEPT_H) dwarf2asm.h $(TM_P_H) langhooks.h $(HASHTAB_H) \ gt-dwarf2out.h $(TARGET_H) $(CGRAPH_H) $(MD5_H) $(INPUT_H) $(FUNCTION_H) \ - $(GIMPLE_H) $(TREE_PASS_H) $(TREE_FLOW_H) $(CFGLAYOUT_H) tree-pretty-print.h + $(GIMPLE_H) $(TREE_PASS_H) $(TREE_FLOW_H) $(CFGLAYOUT_H) \ + tree-pretty-print.h $(COMMON_TARGET_H) dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(FLAGS_H) $(RTL_H) $(TREE_H) output.h dwarf2asm.h $(TM_P_H) $(GGC_H) \ gt-dwarf2asm.h $(DWARF2_H) $(SPLAY_TREE_H) $(TARGET_H) @@ -3141,7 +3152,7 @@ ipa-inline-transform.o : ipa-inline-transform.c $(CONFIG_H) $(SYSTEM_H) coretype $(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \ $(DIAGNOSTIC_H) $(PARAMS_H) $(TIMEVAR_H) $(TREE_PASS_H) \ $(HASHTAB_H) $(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(IPA_PROP_H) \ - gimple-pretty-print.h ipa-inline.h $(LTO_STREAMER_H) + gimple-pretty-print.h ipa-inline.h $(LTO_STREAMER_H) tree-pass.h ipa-utils.o : ipa-utils.c $(IPA_UTILS_H) $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \ pointer-set.h $(GGC_H) $(GIMPLE_H) $(SPLAY_TREE_H) \ @@ -3320,7 +3331,7 @@ cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_H) \ output.h $(FUNCTION_H) $(EXCEPT_H) $(TM_P_H) $(INSN_ATTR_H) \ insn-config.h $(EXPR_H) \ $(CFGLAYOUT_H) $(CFGLOOP_H) $(OBSTACK_H) $(TARGET_H) $(TREE_H) \ - $(TREE_PASS_H) $(DF_H) $(GGC_H) + $(TREE_PASS_H) $(DF_H) $(GGC_H) $(COMMON_TARGET_H) cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(BASIC_BLOCK_H) hard-reg-set.h insn-config.h $(RECOG_H) $(TM_P_H) \ $(TIMEVAR_H) $(OBSTACK_H) $(DIAGNOSTIC_CORE_H) vecprim.h sbitmap.h $(BITMAP_H) @@ -3483,7 +3494,7 @@ modulo-sched.o : modulo-sched.c $(DDG_H) $(CONFIG_H) $(CONFIG_H) $(SYSTEM_H) \ haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(FUNCTION_H) \ $(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) $(TM_P_H) $(TARGET_H) output.h \ - $(PARAMS_H) $(DBGCNT_H) $(CFGLOOP_H) ira.h $(EMIT_RTL_H) + $(PARAMS_H) $(DBGCNT_H) $(CFGLOOP_H) ira.h $(EMIT_RTL_H) $(COMMON_TARGET_H) sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ $(FUNCTION_H) $(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) cselib.h \ @@ -3557,7 +3568,7 @@ cfglayout.o : cfglayout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(TREE_H) insn-config.h $(BASIC_BLOCK_H) hard-reg-set.h output.h \ $(FUNCTION_H) $(CFGLAYOUT_H) $(CFGLOOP_H) $(TARGET_H) gt-cfglayout.h \ $(GGC_H) alloc-pool.h $(FLAGS_H) $(OBSTACK_H) $(TREE_PASS_H) vecprim.h \ - $(DF_H) $(EMIT_RTL_H) + $(DF_H) $(EMIT_RTL_H) $(COMMON_TARGET_H) timevar.o : timevar.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TIMEVAR_H) $(FLAGS_H) intl.h toplev.h $(DIAGNOSTIC_CORE_H) $(RTL_H) timevar.def regcprop.o : regcprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ @@ -3594,10 +3605,16 @@ $(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \ output.h $(INSN_ATTR_H) $(SYSTEM_H) toplev.h $(DIAGNOSTIC_CORE_H) \ $(TARGET_H) $(LIBFUNCS_H) $(TARGET_DEF_H) $(FUNCTION_H) $(SCHED_INT_H) \ $(TM_P_H) $(EXPR_H) langhooks.h $(GGC_H) $(OPTABS_H) $(REAL_H) \ - tm-constrs.h $(GIMPLE_H) $(DF_H) cselib.h + tm-constrs.h $(GIMPLE_H) $(DF_H) cselib.h $(COMMON_TARGET_H) $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ $(out_file) $(OUTPUT_OPTION) +$(common_out_object_file): $(common_out_file) $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(COMMON_TARGET_H) $(COMMON_TARGET_DEF_H) \ + $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(OPTS_H) $(TM_H) $(TM_P_H) $(MACHMODE_H) + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ + $< $(OUTPUT_OPTION) + # Build auxiliary files that support ecoff format. mips-tfile: mips-tfile.o $(LIBDEPS) $(LINKER) $(LINKERFLAGS) $(LDFLAGS) -o $@ \ @@ -3797,6 +3814,15 @@ s-c-target-hooks-def-h: build/genhooks$(build_exeext) c-family/c-target-hooks-def.h $(STAMP) s-c-target-hooks-def-h +common/common-target-hooks-def.h: s-common-target-hooks-def-h; @true + +s-common-target-hooks-def-h: build/genhooks$(build_exeext) + $(RUN_GEN) build/genhooks$(build_exeext) "Common Target Hook" \ + > tmp-common-target-hooks-def.h + $(SHELL) $(srcdir)/../move-if-change tmp-common-target-hooks-def.h \ + common/common-target-hooks-def.h + $(STAMP) s-common-target-hooks-def-h + # check if someone mistakenly only changed tm.texi. # We use a different pathname here to avoid a circular dependency. s-tm-texi: $(srcdir)/doc/../doc/tm.texi @@ -3819,6 +3845,7 @@ s-tm-texi: build/genhooks$(build_exeext) $(srcdir)/doc/tm.texi.in elif test $(srcdir)/doc/tm.texi -nt $(srcdir)/doc/tm.texi.in \ && ( test $(srcdir)/doc/tm.texi -nt $(srcdir)/target.def \ || test $(srcdir)/doc/tm.texi -nt $(srcdir)/c-family/c-target.def \ + || test $(srcdir)/doc/tm.texi -nt $(srcdir)/common/common-target.def \ ); then \ echo >&2 ; \ echo You should edit $(srcdir)/doc/tm.texi.in rather than $(srcdir)/doc/tm.texi . >&2 ; \ @@ -4053,7 +4080,7 @@ build/genpreds.o : genpreds.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ build/genrecog.o : genrecog.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h build/genhooks.o : genhooks.c $(TARGET_DEF) $(C_TARGET_DEF) \ - $(BCONFIG_H) $(SYSTEM_H) errors.h + $(COMMON_TARGET_DEF) $(BCONFIG_H) $(SYSTEM_H) errors.h # Compile the programs that generate insn-* from the machine description. # They are compiled with $(COMPILER_FOR_BUILD), and associated libraries, diff --git a/gcc/acinclude.m4 b/gcc/acinclude.m4 index 3eec559e8f5..ff386825880 100644 --- a/gcc/acinclude.m4 +++ b/gcc/acinclude.m4 @@ -375,13 +375,115 @@ AC_DEFUN([gcc_AC_INITFINI_ARRAY], [], [ AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support, gcc_cv_initfini_array, [dnl - AC_RUN_IFELSE([AC_LANG_SOURCE([ + if test "x${build}" = "x${target}" && test "x${build}" = "x${host}"; then + AC_RUN_IFELSE([AC_LANG_SOURCE([ +#ifdef __ia64__ +/* We turn on .preinit_array/.init_array/.fini_array support for ia64 + if it can be used. */ static int x = -1; int main (void) { return x; } int foo (void) { x = 0; } -int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;])], +int (*fp) (void) __attribute__ ((section (".init_array"))) = foo; +#else +extern void abort (); +static int count; + +static void +init1005 () +{ + if (count != 0) + abort (); + count = 1005; +} +void (*const init_array1005[]) () + __attribute__ ((section (".init_array.01005"), aligned (sizeof (void *)))) + = { init1005 }; +static void +fini1005 () +{ + if (count != 1005) + abort (); +} +void (*const fini_array1005[]) () + __attribute__ ((section (".fini_array.01005"), aligned (sizeof (void *)))) + = { fini1005 }; + +static void +ctor1007 () +{ + if (count != 1005) + abort (); + count = 1007; +} +void (*const ctors1007[]) () + __attribute__ ((section (".ctors.64528"), aligned (sizeof (void *)))) + = { ctor1007 }; +static void +dtor1007 () +{ + if (count != 1007) + abort (); + count = 1005; +} +void (*const dtors1007[]) () + __attribute__ ((section (".dtors.64528"), aligned (sizeof (void *)))) + = { dtor1007 }; + +static void +init65530 () +{ + if (count != 1007) + abort (); + count = 65530; +} +void (*const init_array65530[]) () + __attribute__ ((section (".init_array.65530"), aligned (sizeof (void *)))) + = { init65530 }; +static void +fini65530 () +{ + if (count != 65530) + abort (); + count = 1007; +} +void (*const fini_array65530[]) () + __attribute__ ((section (".fini_array.65530"), aligned (sizeof (void *)))) + = { fini65530 }; + +static void +ctor65535 () +{ + if (count != 65530) + abort (); + count = 65535; +} +void (*const ctors65535[]) () + __attribute__ ((section (".ctors"), aligned (sizeof (void *)))) + = { ctor65535 }; +static void +dtor65535 () +{ + if (count != 65535) + abort (); + count = 65530; +} +void (*const dtors65535[]) () + __attribute__ ((section (".dtors"), aligned (sizeof (void *)))) + = { dtor65535 }; + +int +main () +{ + return 0; +} +#endif +])], [gcc_cv_initfini_array=yes], [gcc_cv_initfini_array=no], - [gcc_cv_initfini_array=no])]) + [gcc_cv_initfini_array=no]) + else + AC_MSG_CHECKING(cross compile... guessing) + gcc_cv_initfini_array=no + fi]) enable_initfini_array=$gcc_cv_initfini_array ]) if test $enable_initfini_array = yes; then diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index bab86659a0f..c27f132e0c4 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,42 @@ +2011-06-18 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.c (gnat_to_gnu_component_type): Use GNAT_TYPE + local variable throughout. Remove useless call to Base_Type. + (gnat_to_gnu_field): Use GNAT_FIELD_TYPE local variable throughout. + Take it also into account for the volatileness of the field. Set the + TREE_SIDE_EFFECTS flag as well in this case. Reorder some warnings. + +2011-06-18 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/trans.c (Identifier_to_gnu): Don't set TREE_THIS_NOTRAP + on a dereference built for a by-ref object if it has an address clause. + +2011-06-18 Eric Botcazou <ebotcazou@adacore.com> + + * einfo.ads (Address_Taken): Document use for the second argument of + Asm_Input and Asm_Output attributes. + * sem_attr.adb (Analyze_Attribute) <Attribute_Asm_Input>: If the second + argument is an entity name, then set Address_Taken on it. + <Attribute_Asm_Output>: Likewise. + * gcc-interface/trans.c (lvalue_required_for_attribute_p): Handle the + Attr_Asm_Input and Attr_Asm_Output attributes explicitly. + (gnat_to_gnu) <N_Code_Statement>: If an operand is going to end up in + memory and is a CONST_DECL, retrieve its corresponding VAR_DECL. + +2011-06-16 Joern Rennecke <joern.rennecke@embecosm.com> + + PR middle-end/46500 + * gcc-interface/decl.c (gnat_to_gnu_param): Use pack_cumulative_args. + +2011-06-14 Joseph Myers <joseph@codesourcery.com> + + * gcc-interface/Make-lang.in (gnatbind$(exeext)): Use ggc-none.o. + (ada/utils.o): Update dependencies. + * gcc-interface/Makefile.in (EXTRA_GNATTOOLS_OBJS): Add + ../../../libcpp/libcpp.a. + * gcc-interface/utils.c: Include common/common-target.h. + (process_attributes): Use targetm_common.have_named_sections. + 2011-06-07 Richard Guenther <rguenther@suse.de> * gcc-interface/misc.c (gnat_init): Do not set size_type_node or call diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads index 051688ae376..577b208f436 100644 --- a/gcc/ada/einfo.ads +++ b/gcc/ada/einfo.ads @@ -380,9 +380,11 @@ package Einfo is -- Address_Taken (Flag104) -- Present in all entities. Set if the Address or Unrestricted_Access -- attribute is applied directly to the entity, i.e. the entity is the --- entity of the prefix of the attribute reference. Used by Gigi to --- make sure that the address can be meaningfully taken, and also in --- the case of subprograms to control output of certain warnings. +-- entity of the prefix of the attribute reference. Also set if the +-- entity is the second argument of an Asm_Input or Asm_Output attribute, +-- as the construct may entail taking its address. Used by Gigi to make +-- sure that the address can be meaningfully taken, and also in the case +-- of subprograms to control output of certain warnings. -- Aft_Value (synthesized) -- Applies to fixed and decimal types. Computes a universal integer diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in index 53f9f8d3f1a..2e73363298b 100644 --- a/gcc/ada/gcc-interface/Make-lang.in +++ b/gcc/ada/gcc-interface/Make-lang.in @@ -479,8 +479,8 @@ gnat1$(exeext): $(TARGET_ADA_SRCS) $(GNAT1_OBJS) $(ADA_BACKEND) libcommon-target $(GCC_LINK) -o $@ $(GNAT1_OBJS) $(ADA_BACKEND) libcommon-target.a $(LIBS) $(SYSLIBS) $(BACKENDLIBS) $(CFLAGS) $(RM) stamp-gnatlib2-rts stamp-tools -gnatbind$(exeext): ada/b_gnatb.o $(CONFIG_H) $(GNATBIND_OBJS) libcommon-target.a $(LIBDEPS) - $(GCC_LINK) -o $@ ada/b_gnatb.o $(GNATBIND_OBJS) libcommon-target.a $(LIBS) $(SYSLIBS) $(CFLAGS) +gnatbind$(exeext): ada/b_gnatb.o $(CONFIG_H) $(GNATBIND_OBJS) ggc-none.o libcommon-target.a $(LIBDEPS) + $(GCC_LINK) -o $@ ada/b_gnatb.o $(GNATBIND_OBJS) ggc-none.o libcommon-target.a $(LIBS) $(SYSLIBS) $(CFLAGS) # use cross-gcc gnat-cross: force @@ -1237,7 +1237,8 @@ ada/trans.o : ada/gcc-interface/trans.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ ada/utils.o : ada/gcc-interface/utils.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TREE_H) $(FLAGS_H) toplev.h $(RTL_H) output.h debug.h convert.h \ - $(TARGET_H) function.h langhooks.h $(CGRAPH_H) $(DIAGNOSTIC_H) \ + $(TARGET_H) $(COMMON_TARGET_H) function.h langhooks.h \ + $(CGRAPH_H) $(DIAGNOSTIC_H) \ $(TREE_DUMP_H) $(TREE_INLINE_H) tree-iterator.h \ ada/gcc-interface/ada.h ada/types.h ada/atree.h ada/elists.h ada/namet.h \ ada/nlists.h ada/stringt.h ada/uintp.h ada/fe.h ada/sinfo.h ada/einfo.h \ diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in index 0b58c1889f4..3c998d47d3a 100644 --- a/gcc/ada/gcc-interface/Makefile.in +++ b/gcc/ada/gcc-interface/Makefile.in @@ -180,7 +180,8 @@ LIBINTL_DEP = @LIBINTL_DEP@ SYSLIBS = @GNAT_LIBEXC@ # List of extra object files linked in with various programs. -EXTRA_GNATTOOLS_OBJS = ../../libcommon-target.a ../../libcommon.a +EXTRA_GNATTOOLS_OBJS = ../../libcommon-target.a ../../libcommon.a \ + ../../../libcpp/libcpp.a # List extra gnattools EXTRA_GNATTOOLS = diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 2ded33bbdcd..1f9083a454e 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -5229,7 +5229,8 @@ static tree gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition, bool debug_info_p) { - tree gnu_type = gnat_to_gnu_type (Component_Type (gnat_array)); + const Entity_Id gnat_type = Component_Type (gnat_array); + tree gnu_type = gnat_to_gnu_type (gnat_type); tree gnu_comp_size; /* Try to get a smaller form of the component if needed. */ @@ -5237,7 +5238,7 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition, || Has_Component_Size_Clause (gnat_array)) && !Is_Bit_Packed_Array (gnat_array) && !Has_Aliased_Components (gnat_array) - && !Strict_Alignment (Component_Type (gnat_array)) + && !Strict_Alignment (gnat_type) && TREE_CODE (gnu_type) == RECORD_TYPE && !TYPE_FAT_POINTER_P (gnu_type) && host_integerp (TYPE_SIZE (gnu_type), 1)) @@ -5301,7 +5302,7 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition, debug_info_p, gnat_array); } - if (Has_Volatile_Components (Base_Type (gnat_array))) + if (Has_Volatile_Components (gnat_array)) gnu_type = build_qualified_type (gnu_type, TYPE_QUALS (gnu_type) | TYPE_QUAL_VOLATILE); @@ -5452,7 +5453,7 @@ gnat_to_gnu_param (Entity_Id gnat_param, Mechanism_Type mech, passed by reference. Pass them by explicit reference, this will generate more debuggable code at -O0. */ if (TYPE_IS_FAT_POINTER_P (gnu_param_type) - && targetm.calls.pass_by_reference (NULL, + && targetm.calls.pass_by_reference (pack_cumulative_args (NULL), TYPE_MODE (gnu_param_type), gnu_param_type, true)) @@ -6716,12 +6717,16 @@ static tree gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed, bool definition, bool debug_info_p) { + const Entity_Id gnat_field_type = Etype (gnat_field); + tree gnu_field_type = gnat_to_gnu_type (gnat_field_type); tree gnu_field_id = get_entity_name (gnat_field); - tree gnu_field_type = gnat_to_gnu_type (Etype (gnat_field)); tree gnu_field, gnu_size, gnu_pos; + bool is_volatile + = (Treat_As_Volatile (gnat_field) || Treat_As_Volatile (gnat_field_type)); bool needs_strict_alignment - = (Is_Aliased (gnat_field) || Strict_Alignment (Etype (gnat_field)) - || Treat_As_Volatile (gnat_field)); + = (is_volatile + || Is_Aliased (gnat_field) + || Strict_Alignment (gnat_field_type)); /* If this field requires strict alignment, we cannot pack it because it would very likely be under-aligned in the record. */ @@ -6737,7 +6742,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed, gnu_size = validate_size (Esize (gnat_field), gnu_field_type, gnat_field, FIELD_DECL, false, true); else if (packed == 1) - gnu_size = validate_size (RM_Size (Etype (gnat_field)), gnu_field_type, + gnu_size = validate_size (RM_Size (gnat_field_type), gnu_field_type, gnat_field, FIELD_DECL, false, true); else gnu_size = NULL_TREE; @@ -6829,7 +6834,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed, if (gnu_size && !operand_equal_p (gnu_size, TYPE_SIZE (gnu_field_type), 0)) { - if (Is_Atomic (gnat_field) || Is_Atomic (Etype (gnat_field))) + if (Is_Atomic (gnat_field) || Is_Atomic (gnat_field_type)) post_error_ne_tree ("atomic field& must be natural size of type{ (^)}", Last_Bit (Component_Clause (gnat_field)), gnat_field, @@ -6841,7 +6846,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed, Last_Bit (Component_Clause (gnat_field)), gnat_field, TYPE_SIZE (gnu_field_type)); - else if (Strict_Alignment (Etype (gnat_field))) + else if (Strict_Alignment (gnat_field_type)) post_error_ne_tree ("size of & with aliased or tagged components not ^ bits", Last_Bit (Component_Clause (gnat_field)), gnat_field, @@ -6854,19 +6859,19 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed, (TRUNC_MOD_EXPR, gnu_pos, bitsize_int (TYPE_ALIGN (gnu_field_type))))) { - if (Is_Aliased (gnat_field)) + if (is_volatile) post_error_ne_num - ("position of aliased field& must be multiple of ^ bits", + ("position of volatile field& must be multiple of ^ bits", First_Bit (Component_Clause (gnat_field)), gnat_field, TYPE_ALIGN (gnu_field_type)); - else if (Treat_As_Volatile (gnat_field)) + else if (Is_Aliased (gnat_field)) post_error_ne_num - ("position of volatile field& must be multiple of ^ bits", + ("position of aliased field& must be multiple of ^ bits", First_Bit (Component_Clause (gnat_field)), gnat_field, TYPE_ALIGN (gnu_field_type)); - else if (Strict_Alignment (Etype (gnat_field))) + else if (Strict_Alignment (gnat_field_type)) post_error_ne_num ("position of & with aliased or tagged components not multiple of ^ bits", First_Bit (Component_Clause (gnat_field)), gnat_field, @@ -6901,7 +6906,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed, if (TREE_CODE (gnu_field_type) == RECORD_TYPE && !gnu_size && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_field_type)) - && !Is_Constrained (Underlying_Type (Etype (gnat_field)))) + && !Is_Constrained (Underlying_Type (gnat_field_type))) { gnu_size = max_size (TYPE_SIZE (gnu_field_type), true); packed = 0; @@ -6953,7 +6958,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed, = create_field_decl (gnu_field_id, gnu_field_type, gnu_record_type, gnu_size, gnu_pos, packed, Is_Aliased (gnat_field)); Sloc_to_locus (Sloc (gnat_field), &DECL_SOURCE_LOCATION (gnu_field)); - TREE_THIS_VOLATILE (gnu_field) = Treat_As_Volatile (gnat_field); + TREE_THIS_VOLATILE (gnu_field) = TREE_SIDE_EFFECTS (gnu_field) = is_volatile; if (Ekind (gnat_field) == E_Discriminant) DECL_DISCRIMINANT_NUMBER (gnu_field) diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index ca47e9347de..bf533bdf332 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -706,6 +706,8 @@ lvalue_required_for_attribute_p (Node_Id gnat_node) case Attr_First_Bit: case Attr_Last_Bit: case Attr_Bit: + case Attr_Asm_Input: + case Attr_Asm_Output: default: return 1; } @@ -1016,7 +1018,8 @@ Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p) else { gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result); - if (TREE_CODE (gnu_result) == INDIRECT_REF) + if (TREE_CODE (gnu_result) == INDIRECT_REF + && No (Address_Clause (gnat_temp))) TREE_THIS_NOTRAP (gnu_result) = 1; } @@ -5489,9 +5492,15 @@ gnat_to_gnu (Node_Id gnat_node) mark it addressable. Note that we don't test allows_mem like in the input case below; this is modelled on the C front-end. */ - if (!allows_reg - && !gnat_mark_addressable (output)) - output = error_mark_node; + if (!allows_reg) + { + STRIP_NOPS (output); + if (TREE_CODE (output) == CONST_DECL + && DECL_CONST_CORRESPONDING_VAR (output)) + output = DECL_CONST_CORRESPONDING_VAR (output); + if (!gnat_mark_addressable (output)) + output = error_mark_node; + } } else output = error_mark_node; @@ -5511,9 +5520,15 @@ gnat_to_gnu (Node_Id gnat_node) { /* If the operand is going to end up in memory, mark it addressable. */ - if (!allows_reg && allows_mem - && !gnat_mark_addressable (input)) - input = error_mark_node; + if (!allows_reg && allows_mem) + { + STRIP_NOPS (input); + if (TREE_CODE (input) == CONST_DECL + && DECL_CONST_CORRESPONDING_VAR (input)) + input = DECL_CONST_CORRESPONDING_VAR (input); + if (!gnat_mark_addressable (input)) + input = error_mark_node; + } } else input = error_mark_node; diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 0f2a331f809..e7496321702 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -36,6 +36,7 @@ #include "debug.h" #include "convert.h" #include "target.h" +#include "common/common-target.h" #include "langhooks.h" #include "cgraph.h" #include "diagnostic.h" @@ -1720,7 +1721,7 @@ process_attributes (tree decl, struct attrib *attr_list) break; case ATTR_LINK_SECTION: - if (targetm.have_named_sections) + if (targetm_common.have_named_sections) { DECL_SECTION_NAME (decl) = build_string (IDENTIFIER_LENGTH (attr_list->name), diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb index b7b4f2f6319..b2c7a835674 100644 --- a/gcc/ada/sem_attr.adb +++ b/gcc/ada/sem_attr.adb @@ -2243,6 +2243,13 @@ package body Sem_Attr is when Attribute_Asm_Input => Check_Asm_Attribute; + + -- The back-end may need to take the address of E2 + + if Is_Entity_Name (E2) then + Set_Address_Taken (Entity (E2)); + end if; + Set_Etype (N, RTE (RE_Asm_Input_Operand)); ---------------- @@ -2263,6 +2270,13 @@ package body Sem_Attr is end if; Note_Possible_Modification (E2, Sure => True); + + -- The back-end may need to take the address of E2 + + if Is_Entity_Name (E2) then + Set_Address_Taken (Entity (E2)); + end if; + Set_Etype (N, RTE (RE_Asm_Output_Operand)); --------------- diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c index cb905428d92..dbd12e72f21 100644 --- a/gcc/auto-inc-dec.c +++ b/gcc/auto-inc-dec.c @@ -1523,7 +1523,6 @@ struct rtl_opt_pass pass_inc_dec = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_df_finish, /* todo_flags_finish */ } }; diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c index e4996144761..6d2aedbb63a 100644 --- a/gcc/bb-reorder.c +++ b/gcc/bb-reorder.c @@ -2117,7 +2117,7 @@ struct rtl_opt_pass pass_duplicate_computed_gotos = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_rtl_sharing,/* todo_flags_finish */ + TODO_verify_rtl_sharing,/* todo_flags_finish */ } }; @@ -2260,7 +2260,7 @@ struct rtl_opt_pass pass_reorder_blocks = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_rtl_sharing,/* todo_flags_finish */ + TODO_verify_rtl_sharing, /* todo_flags_finish */ } }; @@ -2300,6 +2300,6 @@ struct rtl_opt_pass pass_partition_blocks = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_rtl_sharing/* todo_flags_finish */ + TODO_verify_rtl_sharing /* todo_flags_finish */ } }; diff --git a/gcc/bt-load.c b/gcc/bt-load.c index d8063d2e24e..d8aab567166 100644 --- a/gcc/bt-load.c +++ b/gcc/bt-load.c @@ -1519,7 +1519,6 @@ struct rtl_opt_pass pass_branch_target_load_optimize1 = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_rtl_sharing | TODO_ggc_collect, /* todo_flags_finish */ } @@ -1569,7 +1568,6 @@ struct rtl_opt_pass pass_branch_target_load_optimize2 = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_ggc_collect, /* todo_flags_finish */ } }; diff --git a/gcc/builtins.c b/gcc/builtins.c index 7b24a0ce703..cf975e578a7 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -2939,9 +2939,16 @@ expand_builtin_strlen (tree exp, rtx target, /* Now that we are assured of success, expand the source. */ start_sequence (); - pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL); + pat = expand_expr (src, src_reg, Pmode, EXPAND_NORMAL); if (pat != src_reg) - emit_move_insn (src_reg, pat); + { +#ifdef POINTERS_EXTEND_UNSIGNED + if (GET_MODE (pat) != Pmode) + pat = convert_to_mode (Pmode, pat, + POINTERS_EXTEND_UNSIGNED); +#endif + emit_move_insn (src_reg, pat); + } pat = get_insns (); end_sequence (); diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 7a6e7fa5676..afa31de9a58 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,28 @@ + +2011-06-20 Pierre Vittet <piervit@pvittet.com> + + * c-pragma.h (pragma_handler_1arg, pragma_handler_2arg): New + handler. + (gen_pragma_handler): New union. + (internal_pragma_handler): New type. + (c_register_pragma_with_data) + (c_register_pragma_with_expansion_and_data): New functions. + + * c-pragma.c (registered_pragmas, c_register_pragma_1) + (c_register_pragma, c_register_pragma_with_expansion) + (c_invoke_pragma_handler): Changed to work with + internal_pragma_handler. + (c_register_pragma_with_data) + (c_register_pragma_with_expansion_and_data): New functions. + +2011-06-14 Joseph Myers <joseph@codesourcery.com> + + * c-common.c: Include common/common-target.h. + (handle_section_attribute): Use + targetm_common.have_named_sections. + * c-cppbuiltin.c: Include common/common-target.h. + (c_cpp_builtins): Use targetm_common.except_unwind_info. + 2011-06-10 Richard Guenther <rguenther@suse.de> * c-pretty-print.c (pp_c_type_specifier): Use pp_c_identifier diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 37a5f1e45d4..e5849efc2ae 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "obstack.h" #include "cpplib.h" #include "target.h" +#include "common/common-target.h" #include "langhooks.h" #include "tree-inline.h" #include "toplev.h" @@ -6563,7 +6564,7 @@ handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args, { tree decl = *node; - if (targetm.have_named_sections) + if (targetm_common.have_named_sections) { user_defined_section_attribute = true; diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index bc75e02d28a..9f0918daed6 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "debug.h" /* For dwarf2out_do_cfi_asm. */ #include "tm_p.h" /* For TARGET_CPU_CPP_BUILTINS & friends. */ #include "target.h" +#include "common/common-target.h" #include "cpp-id-data.h" #include "cppbuiltin.h" @@ -626,7 +627,7 @@ c_cpp_builtins (cpp_reader *pfile) 1000 + flag_abi_version); /* libgcc needs to know this. */ - if (targetm.except_unwind_info (&global_options) == UI_SJLJ) + if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) cpp_define (pfile, "__USING_SJLJ_EXCEPTIONS__"); /* limits.h and stdint.h need to know these. */ diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c index fa8771ec09f..93735aa2523 100644 --- a/gcc/c-family/c-pragma.c +++ b/gcc/c-family/c-pragma.c @@ -1147,12 +1147,11 @@ handle_pragma_float_const_decimal64 (cpp_reader *ARG_UNUSED (dummy)) } } -/* A vector of registered pragma callbacks. */ +/* A vector of registered pragma callbacks, which is never freed. */ +DEF_VEC_O (internal_pragma_handler); +DEF_VEC_ALLOC_O (internal_pragma_handler, heap); -DEF_VEC_O (pragma_handler); -DEF_VEC_ALLOC_O (pragma_handler, heap); - -static VEC(pragma_handler, heap) *registered_pragmas; +static VEC(internal_pragma_handler, heap) *registered_pragmas; typedef struct { @@ -1216,7 +1215,7 @@ c_pp_lookup_pragma (unsigned int id, const char **space, const char **name) static void c_register_pragma_1 (const char *space, const char *name, - pragma_handler handler, bool allow_expansion) + internal_pragma_handler ihandler, bool allow_expansion) { unsigned id; @@ -1235,8 +1234,9 @@ c_register_pragma_1 (const char *space, const char *name, } else { - VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler); - id = VEC_length (pragma_handler, registered_pragmas); + VEC_safe_push (internal_pragma_handler, heap, registered_pragmas, + &ihandler); + id = VEC_length (internal_pragma_handler, registered_pragmas); id += PRAGMA_FIRST_EXTERNAL - 1; /* The C++ front end allocates 6 bits in cp_token; the C front end @@ -1248,28 +1248,95 @@ c_register_pragma_1 (const char *space, const char *name, allow_expansion, false); } +/* Register a C pragma handler, using a space and a name. It disallows pragma + expansion (if you want it, use c_register_pragma_with_expansion instead). */ +void +c_register_pragma (const char *space, const char *name, + pragma_handler_1arg handler) +{ + internal_pragma_handler ihandler; + + ihandler.handler.handler_1arg = handler; + ihandler.extra_data = false; + ihandler.data = NULL; + c_register_pragma_1 (space, name, ihandler, false); +} + +/* Register a C pragma handler, using a space and a name, it also carries an + extra data field which can be used by the handler. It disallows pragma + expansion (if you want it, use c_register_pragma_with_expansion_and_data + instead). */ void -c_register_pragma (const char *space, const char *name, pragma_handler handler) +c_register_pragma_with_data (const char *space, const char *name, + pragma_handler_2arg handler, void * data) { - c_register_pragma_1 (space, name, handler, false); + internal_pragma_handler ihandler; + + ihandler.handler.handler_2arg = handler; + ihandler.extra_data = true; + ihandler.data = data; + c_register_pragma_1 (space, name, ihandler, false); } +/* Register a C pragma handler, using a space and a name. It allows pragma + expansion as in the following example: + + #define NUMBER 10 + #pragma count (NUMBER) + + Name expansion is still disallowed. */ void c_register_pragma_with_expansion (const char *space, const char *name, - pragma_handler handler) + pragma_handler_1arg handler) { - c_register_pragma_1 (space, name, handler, true); + internal_pragma_handler ihandler; + + ihandler.handler.handler_1arg = handler; + ihandler.extra_data = false; + ihandler.data = NULL; + c_register_pragma_1 (space, name, ihandler, true); +} + +/* Register a C pragma handler, using a space and a name, it also carries an + extra data field which can be used by the handler. It allows pragma + expansion as in the following example: + + #define NUMBER 10 + #pragma count (NUMBER) + + Name expansion is still disallowed. */ +void +c_register_pragma_with_expansion_and_data (const char *space, const char *name, + pragma_handler_2arg handler, + void *data) +{ + internal_pragma_handler ihandler; + + ihandler.handler.handler_2arg = handler; + ihandler.extra_data = true; + ihandler.data = data; + c_register_pragma_1 (space, name, ihandler, true); } void c_invoke_pragma_handler (unsigned int id) { - pragma_handler handler; + internal_pragma_handler *ihandler; + pragma_handler_1arg handler_1arg; + pragma_handler_2arg handler_2arg; id -= PRAGMA_FIRST_EXTERNAL; - handler = *VEC_index (pragma_handler, registered_pragmas, id); - - handler (parse_in); + ihandler = VEC_index (internal_pragma_handler, registered_pragmas, id); + if (ihandler->extra_data) + { + handler_2arg = ihandler->handler.handler_2arg; + handler_2arg (parse_in, ihandler->data); + } + else + { + handler_1arg = ihandler->handler.handler_1arg; + handler_1arg (parse_in); + } } /* Set up front-end pragmas. */ @@ -1308,7 +1375,8 @@ init_pragma (void) c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64", handle_pragma_float_const_decimal64); - c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname); + c_register_pragma_with_expansion (0, "redefine_extname", + handle_pragma_redefine_extname); c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix); c_register_pragma_with_expansion (0, "message", handle_pragma_message); diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h index cec9cd17616..d231c256e46 100644 --- a/gcc/c-family/c-pragma.h +++ b/gcc/c-family/c-pragma.h @@ -84,10 +84,40 @@ extern bool pop_visibility (int); extern void init_pragma (void); /* Front-end wrappers for pragma registration. */ -typedef void (*pragma_handler)(struct cpp_reader *); -extern void c_register_pragma (const char *, const char *, pragma_handler); -extern void c_register_pragma_with_expansion (const char *, const char *, - pragma_handler); +typedef void (*pragma_handler_1arg)(struct cpp_reader *); +/* A second pragma handler, which adds a void * argument allowing to pass extra + data to the handler. */ +typedef void (*pragma_handler_2arg)(struct cpp_reader *, void *); + +/* This union allows to abstract the different handlers. */ +union gen_pragma_handler { + pragma_handler_1arg handler_1arg; + pragma_handler_2arg handler_2arg; +}; +/* Internally used to keep the data of the handler. */ +struct internal_pragma_handler_d { + union gen_pragma_handler handler; + /* Permits to know if handler is a pragma_handler_1arg (extra_data is false) + or a pragma_handler_2arg (extra_data is true). */ + bool extra_data; + /* A data field which can be used when extra_data is true. */ + void * data; +}; +typedef struct internal_pragma_handler_d internal_pragma_handler; + +extern void c_register_pragma (const char *space, const char *name, + pragma_handler_1arg handler); +extern void c_register_pragma_with_data (const char *space, const char *name, + pragma_handler_2arg handler, + void *data); + +extern void c_register_pragma_with_expansion (const char *space, + const char *name, + pragma_handler_1arg handler); +extern void c_register_pragma_with_expansion_and_data (const char *space, + const char *name, + pragma_handler_2arg handler, + void *data); extern void c_invoke_pragma_handler (unsigned int); extern void maybe_apply_pragma_weak (tree); diff --git a/gcc/calls.c b/gcc/calls.c index feb98d21c00..3d9a03f3632 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -125,7 +125,7 @@ static int stack_arg_under_construction; static void emit_call_1 (rtx, tree, tree, tree, HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT, rtx, rtx, int, rtx, int, - CUMULATIVE_ARGS *); + cumulative_args_t); static void precompute_register_parameters (int, struct arg_data *, int *); static int store_one_arg (struct arg_data *, rtx, int, int, int); static void store_unaligned_arguments_into_pseudos (struct arg_data *, int); @@ -136,7 +136,7 @@ static int compute_argument_block_size (int, struct args_size *, tree, tree, int static void initialize_argument_information (int, struct arg_data *, struct args_size *, int, tree, tree, - tree, tree, CUMULATIVE_ARGS *, int, + tree, tree, cumulative_args_t, int, rtx *, int *, int *, int *, bool *, bool); static void compute_argument_addresses (struct arg_data *, rtx, int); @@ -252,7 +252,7 @@ emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNU HOST_WIDE_INT struct_value_size ATTRIBUTE_UNUSED, rtx next_arg_reg ATTRIBUTE_UNUSED, rtx valreg, int old_inhibit_defer_pop, rtx call_fusage, int ecf_flags, - CUMULATIVE_ARGS *args_so_far ATTRIBUTE_UNUSED) + cumulative_args_t args_so_far ATTRIBUTE_UNUSED) { rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size); rtx call_insn, call, funmem; @@ -261,7 +261,7 @@ emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNU = targetm.calls.return_pops_args (fndecl, funtype, stack_size); #ifdef CALL_POPS_ARGS - n_popped += CALL_POPS_ARGS (* args_so_far); + n_popped += CALL_POPS_ARGS (*get_cumulative_args (args_so_far)); #endif /* Ensure address is valid. SYMBOL_REF is already valid, so no need, @@ -967,12 +967,13 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, int n_named_args ATTRIBUTE_UNUSED, tree exp, tree struct_value_addr_value, tree fndecl, tree fntype, - CUMULATIVE_ARGS *args_so_far, + cumulative_args_t args_so_far, int reg_parm_stack_space, rtx *old_stack_level, int *old_pending_adj, int *must_preallocate, int *ecf_flags, bool *may_tailcall, bool call_from_thunk_p) { + CUMULATIVE_ARGS *args_so_far_pnt = get_cumulative_args (args_so_far); location_t loc = EXPR_LOCATION (exp); /* 1 if scanning parms front to back, -1 if scanning back to front. */ int inc; @@ -1064,14 +1065,14 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, with those made by function.c. */ /* See if this argument should be passed by invisible reference. */ - if (pass_by_reference (args_so_far, TYPE_MODE (type), + if (pass_by_reference (args_so_far_pnt, TYPE_MODE (type), type, argpos < n_named_args)) { bool callee_copies; tree base; callee_copies - = reference_callee_copied (args_so_far, TYPE_MODE (type), + = reference_callee_copied (args_so_far_pnt, TYPE_MODE (type), type, argpos < n_named_args); /* If we're compiling a thunk, pass through invisible references @@ -2005,7 +2006,8 @@ expand_call (tree exp, rtx target, int ignore) /* Size of arguments before any adjustments (such as rounding). */ int unadjusted_args_size; /* Data on reg parms scanned so far. */ - CUMULATIVE_ARGS args_so_far; + CUMULATIVE_ARGS args_so_far_v; + cumulative_args_t args_so_far; /* Nonzero if a reg parm has been scanned. */ int reg_parm_seen; /* Nonzero if this is an indirect function call. */ @@ -2243,7 +2245,8 @@ expand_call (tree exp, rtx target, int ignore) calling convention than normal calls. The fourth argument in INIT_CUMULATIVE_ARGS tells the backend if this is an indirect call or not. */ - INIT_CUMULATIVE_ARGS (args_so_far, funtype, NULL_RTX, fndecl, n_named_args); + INIT_CUMULATIVE_ARGS (args_so_far_v, funtype, NULL_RTX, fndecl, n_named_args); + args_so_far = pack_cumulative_args (&args_so_far_v); /* Now possibly adjust the number of named args. Normally, don't include the last named arg if anonymous args follow. @@ -2264,10 +2267,10 @@ expand_call (tree exp, rtx target, int ignore) registers, so we must force them into memory. */ if (type_arg_types != 0 - && targetm.calls.strict_argument_naming (&args_so_far)) + && targetm.calls.strict_argument_naming (args_so_far)) ; else if (type_arg_types != 0 - && ! targetm.calls.pretend_outgoing_varargs_named (&args_so_far)) + && ! targetm.calls.pretend_outgoing_varargs_named (args_so_far)) /* Don't include the last named arg. */ --n_named_args; else @@ -2283,7 +2286,7 @@ expand_call (tree exp, rtx target, int ignore) initialize_argument_information (num_actuals, args, &args_size, n_named_args, exp, structure_value_addr_value, fndecl, fntype, - &args_so_far, reg_parm_stack_space, + args_so_far, reg_parm_stack_space, &old_stack_level, &old_pending_adj, &must_preallocate, &flags, &try_tail_call, CALL_FROM_THUNK_P (exp)); @@ -2873,12 +2876,12 @@ expand_call (tree exp, rtx target, int ignore) /* Set up next argument register. For sibling calls on machines with register windows this should be the incoming register. */ if (pass == 0) - next_arg_reg = targetm.calls.function_incoming_arg (&args_so_far, + next_arg_reg = targetm.calls.function_incoming_arg (args_so_far, VOIDmode, void_type_node, true); else - next_arg_reg = targetm.calls.function_arg (&args_so_far, + next_arg_reg = targetm.calls.function_arg (args_so_far, VOIDmode, void_type_node, true); @@ -2893,7 +2896,7 @@ expand_call (tree exp, rtx target, int ignore) emit_call_1 (funexp, exp, fndecl, funtype, unadjusted_args_size, adjusted_args_size.constant, struct_value_size, next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage, - flags, & args_so_far); + flags, args_so_far); /* If the call setup or the call itself overlaps with anything of the argument setup we probably clobbered our call address. @@ -3324,7 +3327,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, int inc; int count; rtx argblock = 0; - CUMULATIVE_ARGS args_so_far; + CUMULATIVE_ARGS args_so_far_v; + cumulative_args_t args_so_far; struct arg { rtx value; @@ -3436,10 +3440,11 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, memset (argvec, 0, (nargs + 1) * sizeof (struct arg)); #ifdef INIT_CUMULATIVE_LIBCALL_ARGS - INIT_CUMULATIVE_LIBCALL_ARGS (args_so_far, outmode, fun); + INIT_CUMULATIVE_LIBCALL_ARGS (args_so_far_v, outmode, fun); #else - INIT_CUMULATIVE_ARGS (args_so_far, NULL_TREE, fun, 0, nargs); + INIT_CUMULATIVE_ARGS (args_so_far_v, NULL_TREE, fun, 0, nargs); #endif + args_so_far = pack_cumulative_args (&args_so_far_v); args_size.constant = 0; args_size.var = 0; @@ -3466,9 +3471,9 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, argvec[count].mode = Pmode; argvec[count].partial = 0; - argvec[count].reg = targetm.calls.function_arg (&args_so_far, + argvec[count].reg = targetm.calls.function_arg (args_so_far, Pmode, NULL_TREE, true); - gcc_assert (targetm.calls.arg_partial_bytes (&args_so_far, Pmode, + gcc_assert (targetm.calls.arg_partial_bytes (args_so_far, Pmode, NULL_TREE, 1) == 0); locate_and_pad_parm (Pmode, NULL_TREE, @@ -3483,7 +3488,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, || reg_parm_stack_space > 0) args_size.constant += argvec[count].locate.size.constant; - targetm.calls.function_arg_advance (&args_so_far, Pmode, (tree) 0, true); + targetm.calls.function_arg_advance (args_so_far, Pmode, (tree) 0, true); count++; } @@ -3504,11 +3509,11 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, && !(CONSTANT_P (val) && targetm.legitimate_constant_p (mode, val))) val = force_operand (val, NULL_RTX); - if (pass_by_reference (&args_so_far, mode, NULL_TREE, 1)) + if (pass_by_reference (&args_so_far_v, mode, NULL_TREE, 1)) { rtx slot; int must_copy - = !reference_callee_copied (&args_so_far, mode, NULL_TREE, 1); + = !reference_callee_copied (&args_so_far_v, mode, NULL_TREE, 1); /* If this was a CONST function, it is now PURE since it now reads memory. */ @@ -3543,11 +3548,11 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, mode = promote_function_mode (NULL_TREE, mode, &unsigned_p, NULL_TREE, 0); argvec[count].mode = mode; argvec[count].value = convert_modes (mode, GET_MODE (val), val, unsigned_p); - argvec[count].reg = targetm.calls.function_arg (&args_so_far, mode, + argvec[count].reg = targetm.calls.function_arg (args_so_far, mode, NULL_TREE, true); argvec[count].partial - = targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL_TREE, 1); + = targetm.calls.arg_partial_bytes (args_so_far, mode, NULL_TREE, 1); locate_and_pad_parm (mode, NULL_TREE, #ifdef STACK_PARMS_IN_REG_PARM_AREA @@ -3564,7 +3569,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, || reg_parm_stack_space > 0) args_size.constant += argvec[count].locate.size.constant; - targetm.calls.function_arg_advance (&args_so_far, mode, (tree) 0, true); + targetm.calls.function_arg_advance (args_so_far, mode, (tree) 0, true); } /* If this machine requires an external definition for library @@ -3876,10 +3881,10 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, build_function_type (tfom, NULL_TREE), original_args_size.constant, args_size.constant, struct_value_size, - targetm.calls.function_arg (&args_so_far, + targetm.calls.function_arg (args_so_far, VOIDmode, void_type_node, true), valreg, - old_inhibit_defer_pop + 1, call_fusage, flags, & args_so_far); + old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far); /* For calls to `setjmp', etc., inform function.c:setjmp_warnings that it should complain if nonvolatile values are live. For diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index c36af89a137..f51e57f5b70 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -2989,8 +2989,6 @@ struct rtl_opt_pass pass_jump2 = 0, /* properties_provided */ 0, /* properties_destroyed */ TODO_ggc_collect, /* todo_flags_start */ - TODO_dump_func | TODO_verify_rtl_sharing,/* todo_flags_finish */ + TODO_verify_rtl_sharing, /* todo_flags_finish */ } }; - - diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index b22ba71375f..efd3ed93c36 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -1098,7 +1098,9 @@ expand_used_vars_for_block (tree block, bool toplevel) /* Expand all variables at this level. */ for (t = BLOCK_VARS (block); t ; t = DECL_CHAIN (t)) - if (TREE_USED (t)) + if (TREE_USED (t) + && ((TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != RESULT_DECL) + || !DECL_NONSHAREABLE (t))) expand_one_var (t, toplevel, true); this_sv_num = stack_vars_num; @@ -1131,6 +1133,8 @@ clear_tree_used (tree block) for (t = BLOCK_VARS (block); t ; t = DECL_CHAIN (t)) /* if (!TREE_STATIC (t) && !DECL_EXTERNAL (t)) */ + if ((TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != RESULT_DECL) + || !DECL_NONSHAREABLE (t)) TREE_USED (t) = 0; for (t = BLOCK_SUBBLOCKS (block); t ; t = BLOCK_CHAIN (t)) @@ -4269,7 +4273,6 @@ struct rtl_opt_pass pass_expand = PROP_ssa | PROP_trees, /* properties_destroyed */ TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts, /* todo_flags_start */ - TODO_dump_func - | TODO_ggc_collect /* todo_flags_finish */ + TODO_ggc_collect /* todo_flags_finish */ } }; diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c index 548e21f7f4f..d320fcc5dbd 100644 --- a/gcc/cfglayout.c +++ b/gcc/cfglayout.c @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "cfglayout.h" #include "cfgloop.h" #include "target.h" +#include "common/common-target.h" #include "ggc.h" #include "alloc-pool.h" #include "flags.h" @@ -378,7 +379,7 @@ struct rtl_opt_pass pass_into_cfg_layout_mode = PROP_cfglayout, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -397,7 +398,7 @@ struct rtl_opt_pass pass_outof_cfg_layout_mode = 0, /* properties_provided */ PROP_cfglayout, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -912,7 +913,7 @@ fixup_reorder_chain (void) section boundaries). */ BB_COPY_PARTITION (src_bb, single_pred (bb)); if (flag_reorder_blocks_and_partition - && targetm.have_named_sections + && targetm_common.have_named_sections && JUMP_P (BB_END (bb)) && !any_condjump_p (BB_END (bb)) && (EDGE_SUCC (bb, 0)->flags & EDGE_CROSSING)) diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 0ff44de67d3..510bc10bd4a 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -143,11 +143,13 @@ struct GTY ((chain_next ("%h.next"))) loop { computes and caches the computed information in this field. */ tree nb_iterations; - /* An integer guaranteed to bound the number of iterations of the loop - from above. */ + /* An integer guaranteed to be greater or equal to nb_iterations. Only + valid if any_upper_bound is true. */ double_int nb_iterations_upper_bound; - /* An integer giving the expected number of iterations of the loop. */ + /* An integer giving an estimate on nb_iterations. Unlike + nb_iterations_upper_bound, there is no guarantee that it is at least + nb_iterations. */ double_int nb_iterations_estimate; bool any_upper_bound; @@ -278,7 +280,9 @@ extern rtx doloop_condition_get (rtx); void estimate_numbers_of_iterations_loop (struct loop *, bool); HOST_WIDE_INT estimated_loop_iterations_int (struct loop *, bool); +HOST_WIDE_INT max_stmt_executions_int (struct loop *, bool); bool estimated_loop_iterations (struct loop *, bool, double_int *); +bool max_stmt_executions (struct loop *, bool, double_int *); /* Loop manipulation. */ extern bool can_duplicate_loop_p (const struct loop *loop); diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 482568c921e..7eb4362341b 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1,6 +1,6 @@ /* Control flow graph manipulation code for GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see #include "cfglayout.h" #include "expr.h" #include "target.h" +#include "common/common-target.h" #include "cfgloop.h" #include "ggc.h" #include "tree-pass.h" @@ -1224,7 +1225,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target) BB_COPY_PARTITION (jump_block, e->src); if (flag_reorder_blocks_and_partition - && targetm.have_named_sections + && targetm_common.have_named_sections && JUMP_P (BB_END (jump_block)) && !any_condjump_p (BB_END (jump_block)) && (EDGE_SUCC (jump_block, 0)->flags & EDGE_CROSSING)) @@ -1524,7 +1525,7 @@ commit_one_edge_insertion (edge e) after = BB_END (bb); if (flag_reorder_blocks_and_partition - && targetm.have_named_sections + && targetm_common.have_named_sections && e->src != ENTRY_BLOCK_PTR && BB_PARTITION (e->src) == BB_COLD_PARTITION && !(e->flags & EDGE_CROSSING) diff --git a/gcc/cgraph.c b/gcc/cgraph.c index f5fd150baac..86e72072eab 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -208,6 +208,9 @@ static GTY(()) struct cgraph_node *free_nodes; Do not GTY((delete)) this list so UIDs gets reliably recycled. */ static GTY(()) struct cgraph_edge *free_edges; +/* Did procss_same_body_aliases run? */ +bool same_body_aliases_done; + /* Macros to access the next item in the list of free cgraph nodes and edges. */ #define NEXT_FREE_NODE(NODE) (NODE)->next @@ -542,33 +545,23 @@ cgraph_get_create_node (tree decl) /* Mark ALIAS as an alias to DECL. DECL_NODE is cgraph node representing the function body is associated with (not neccesarily cgraph_node (DECL). */ -static struct cgraph_node * -cgraph_same_body_alias_1 (struct cgraph_node *decl_node, tree alias, tree decl) +struct cgraph_node * +cgraph_create_function_alias (tree alias, tree decl) { - struct cgraph_node key, *alias_node, **slot; + struct cgraph_node *alias_node; gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); gcc_assert (TREE_CODE (alias) == FUNCTION_DECL); - - key.decl = alias; - - slot = (struct cgraph_node **) htab_find_slot (cgraph_hash, &key, INSERT); - - /* If the cgraph_node has been already created, fail. */ - if (*slot) - return NULL; - - alias_node = cgraph_allocate_node (); - alias_node->decl = alias; - alias_node->same_body_alias = 1; - alias_node->same_body = decl_node; - alias_node->previous = NULL; - if (decl_node->same_body) - decl_node->same_body->previous = alias_node; - alias_node->next = decl_node->same_body; + alias_node = cgraph_get_create_node (alias); + gcc_assert (!alias_node->local.finalized); alias_node->thunk.alias = decl; - decl_node->same_body = alias_node; - *slot = alias_node; + alias_node->local.finalized = true; + alias_node->alias = 1; + + if ((TREE_PUBLIC (alias) && !DECL_COMDAT (alias) && !DECL_EXTERNAL (alias)) + || (DECL_VIRTUAL_P (alias) + && (DECL_COMDAT (alias) || DECL_EXTERNAL (alias)))) + cgraph_mark_reachable_node (alias_node); return alias_node; } @@ -578,16 +571,24 @@ cgraph_same_body_alias_1 (struct cgraph_node *decl_node, tree alias, tree decl) and cgraph_get_node (ALIAS) transparently returns cgraph_get_node (DECL). */ struct cgraph_node * -cgraph_same_body_alias (struct cgraph_node *decl_node, tree alias, tree decl) +cgraph_same_body_alias (struct cgraph_node *decl_node ATTRIBUTE_UNUSED, tree alias, tree decl) { + struct cgraph_node *n; #ifndef ASM_OUTPUT_DEF /* If aliases aren't supported by the assembler, fail. */ return NULL; #endif + /* Langhooks can create same body aliases of symbols not defined. + Those are useless. Drop them on the floor. */ + if (cgraph_global_info_ready) + return NULL; - /*gcc_assert (!assembler_name_hash);*/ - - return cgraph_same_body_alias_1 (decl_node, alias, decl); + n = cgraph_create_function_alias (alias, decl); + n->same_body_alias = true; + if (same_body_aliases_done) + ipa_record_reference (n, NULL, cgraph_get_node (decl), NULL, IPA_REF_ALIAS, + NULL); + return n; } /* Add thunk alias into callgraph. The alias declaration is ALIAS and it @@ -633,6 +634,7 @@ cgraph_add_thunk (struct cgraph_node *decl_node ATTRIBUTE_UNUSED, || (DECL_VIRTUAL_P (decl) && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl)))) cgraph_mark_reachable_node (node); + return node; } @@ -678,11 +680,7 @@ cgraph_get_node (const_tree decl) NO_INSERT); if (slot && *slot) - { - node = *slot; - if (node->same_body_alias) - node = node->same_body; - } + node = *slot; return node; } @@ -745,21 +743,6 @@ cgraph_node_for_asm (tree asmname) so lets hope for the best. */ if (!*slot) *slot = node; - if (node->same_body) - { - struct cgraph_node *alias; - - for (alias = node->same_body; alias; alias = alias->next) - { - hashval_t hash; - name = DECL_ASSEMBLER_NAME (alias->decl); - hash = decl_assembler_name_hash (name); - slot = htab_find_slot_with_hash (assembler_name_hash, name, - hash, INSERT); - if (!*slot) - *slot = alias; - } - } } } @@ -770,8 +753,6 @@ cgraph_node_for_asm (tree asmname) if (slot) { node = (struct cgraph_node *) *slot; - if (node->same_body_alias) - node = node->same_body; return node; } return NULL; @@ -1432,44 +1413,6 @@ cgraph_release_function_body (struct cgraph_node *node) DECL_INITIAL (node->decl) = error_mark_node; } -/* Remove same body alias node. */ - -void -cgraph_remove_same_body_alias (struct cgraph_node *node) -{ - void **slot; - int uid = node->uid; - - gcc_assert (node->same_body_alias); - if (node->previous) - node->previous->next = node->next; - else - node->same_body->same_body = node->next; - if (node->next) - node->next->previous = node->previous; - node->next = NULL; - node->previous = NULL; - slot = htab_find_slot (cgraph_hash, node, NO_INSERT); - if (*slot == node) - htab_clear_slot (cgraph_hash, slot); - if (assembler_name_hash) - { - tree name = DECL_ASSEMBLER_NAME (node->decl); - slot = htab_find_slot_with_hash (assembler_name_hash, name, - decl_assembler_name_hash (name), - NO_INSERT); - if (slot && *slot == node) - htab_clear_slot (assembler_name_hash, slot); - } - - /* Clear out the node to NULL all pointers and add the node to the free - list. */ - memset (node, 0, sizeof(*node)); - node->uid = uid; - NEXT_FREE_NODE (node) = free_nodes; - free_nodes = node; -} - /* Remove the node from cgraph. */ void @@ -1631,9 +1574,6 @@ cgraph_remove_node (struct cgraph_node *node) } } - while (node->same_body) - cgraph_remove_same_body_alias (node->same_body); - if (node->same_comdat_group) { struct cgraph_node *prev; @@ -1747,6 +1687,14 @@ cgraph_mark_address_taken_node (struct cgraph_node *node) { gcc_assert (!node->global.inlined_to); cgraph_mark_reachable_node (node); + /* FIXME: address_taken flag is used both as a shortcut for testing whether + IPA_REF_ADDR reference exists (and thus it should be set on node + representing alias we take address of) and as a test whether address + of the object was taken (and thus it should be set on node alias is + referring to). We should remove the first use and the remove the + following set. */ + node->address_taken = 1; + node = cgraph_function_or_thunk_node (node, NULL); node->address_taken = 1; } @@ -1902,6 +1850,15 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) (int)node->thunk.virtual_value, (int)node->thunk.virtual_offset_p); } + if (node->alias && node->thunk.alias) + { + fprintf (f, " alias of %s", + lang_hooks.decl_printable_name (node->thunk.alias, 2)); + if (DECL_ASSEMBLER_NAME_SET_P (node->thunk.alias)) + fprintf (f, " (asm: %s)", + IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->thunk.alias))); + fprintf (f, "\n"); + } fprintf (f, " called by: "); @@ -1952,19 +1909,6 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) if (indirect_calls_count) fprintf (f, " has %i outgoing edges for indirect calls.\n", indirect_calls_count); - - if (node->same_body) - { - struct cgraph_node *n; - fprintf (f, " aliases:"); - for (n = node->same_body; n; n = n->next) - { - fprintf (f, " %s/%i", cgraph_node_name (n), n->uid); - if (DECL_ASSEMBLER_NAME_SET_P (n->decl)) - fprintf (f, " (asm: %s)", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl))); - } - fprintf (f, "\n"); - } } @@ -2543,7 +2487,7 @@ cgraph_make_decl_local (tree decl) DECL_COMMON (decl) = 0; else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); - if (DECL_COMDAT (decl)) + if (DECL_ONE_ONLY (decl) || DECL_COMDAT (decl)) { /* It is possible that we are linking against library defining same COMDAT function. To avoid conflict we need to rename our local name of the @@ -2614,18 +2558,28 @@ cgraph_for_node_thunks_and_aliases (struct cgraph_node *node, bool include_overwritable) { struct cgraph_edge *e; - struct cgraph_node *alias; + int i; + struct ipa_ref *ref; if (callback (node, data)) return true; - for (alias = node->same_body; alias; alias = alias->next) - if (callback (alias, data)) - return true; for (e = node->callers; e; e = e->next_caller) if (e->caller->thunk.thunk_p && (include_overwritable - || cgraph_function_body_availability (e->caller) > AVAIL_OVERWRITABLE)) - cgraph_for_node_thunks_and_aliases (e->caller, callback, data, include_overwritable); + || cgraph_function_body_availability (e->caller))) + if (cgraph_for_node_thunks_and_aliases (e->caller, callback, data, + include_overwritable)) + return true; + for (i = 0; ipa_ref_list_refering_iterate (&node->ref_list, i, ref); i++) + if (ref->use == IPA_REF_ALIAS) + { + struct cgraph_node *alias = ipa_ref_refering_node (ref); + if (include_overwritable + || cgraph_function_body_availability (alias) > AVAIL_OVERWRITABLE) + if (cgraph_for_node_thunks_and_aliases (alias, callback, data, + include_overwritable)) + return true; + } return false; } @@ -2637,15 +2591,23 @@ bool cgraph_for_node_and_aliases (struct cgraph_node *node, bool (*callback) (struct cgraph_node *, void *), void *data, - bool include_overwritable ATTRIBUTE_UNUSED) + bool include_overwritable) { - struct cgraph_node *alias; + int i; + struct ipa_ref *ref; if (callback (node, data)) return true; - for (alias = node->same_body; alias; alias = alias->next) - if (callback (alias, data)) - return true; + for (i = 0; ipa_ref_list_refering_iterate (&node->ref_list, i, ref); i++) + if (ref->use == IPA_REF_ALIAS) + { + struct cgraph_node *alias = ipa_ref_refering_node (ref); + if (include_overwritable + || cgraph_function_body_availability (alias) > AVAIL_OVERWRITABLE) + if (cgraph_for_node_and_aliases (alias, callback, data, + include_overwritable)) + return true; + } return false; } @@ -2944,6 +2906,36 @@ cgraph_can_remove_if_no_direct_calls_and_refs_p (struct cgraph_node *node) return true; } +/* Worker for cgraph_can_remove_if_no_direct_calls_p. */ + +static bool +nonremovable_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) +{ + return !cgraph_can_remove_if_no_direct_calls_and_refs_p (node); +} + +/* Return true when function NODE and its aliases can be removed from callgraph + if all direct calls are eliminated. */ + +bool +cgraph_can_remove_if_no_direct_calls_p (struct cgraph_node *node) +{ + /* Extern inlines can always go, we will use the external definition. */ + if (DECL_EXTERNAL (node->decl)) + return true; + if (node->address_taken) + return false; + return !cgraph_for_node_and_aliases (node, nonremovable_p, NULL, true); +} + +/* Worker for cgraph_can_remove_if_no_direct_calls_p. */ + +static bool +used_from_object_file_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) +{ + return cgraph_used_from_object_file_p (node); +} + /* Return true when function NODE can be expected to be removed from program when direct calls in this compilation unit are removed. @@ -2962,7 +2954,7 @@ bool cgraph_will_be_removed_from_program_if_no_direct_calls (struct cgraph_node *node) { gcc_assert (!node->global.inlined_to); - if (cgraph_used_from_object_file_p (node)) + if (cgraph_for_node_and_aliases (node, used_from_object_file_p, NULL, true)) return false; if (!in_lto_p && !flag_whole_program) return cgraph_only_called_directly_p (node); diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 055ab4884ef..dd08febaf12 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -165,9 +165,6 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node { struct cgraph_node *prev_sibling_clone; struct cgraph_node *clones; struct cgraph_node *clone_of; - /* For normal nodes pointer to the list of alias and thunk nodes, - in alias/thunk nodes pointer to the normal node. */ - struct cgraph_node *same_body; /* Circular list of nodes in the same comdat group if non-NULL. */ struct cgraph_node *same_comdat_group; /* For functions with many calls sites it holds map from call expression @@ -236,8 +233,7 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node { unsigned process : 1; /* Set for aliases once they got through assemble_alias. */ unsigned alias : 1; - /* Set for alias and thunk nodes, same_body points to the node they are alias - of and they are linked through the next/previous pointers. */ + /* Set for aliases created as C++ same body aliases. */ unsigned same_body_alias : 1; /* How commonly executed the node is. Initialized during branch probabilities pass. */ @@ -384,13 +380,12 @@ DEF_VEC_ALLOC_P(cgraph_edge_p,heap); struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) varpool_node { tree decl; + /* For aliases points to declaration DECL is alias of. */ + tree alias_of; /* Pointer to the next function in varpool_nodes. */ struct varpool_node *next, *prev; /* Pointer to the next function in varpool_nodes_queue. */ struct varpool_node *next_needed, *prev_needed; - /* For normal nodes a pointer to the first extra name alias. For alias - nodes a pointer to the normal node. */ - struct varpool_node *extra_name; /* Circular list of nodes in the same comdat group if non-NULL. */ struct varpool_node *same_comdat_group; struct ipa_ref_list ref_list; @@ -419,6 +414,7 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) varpool_node { /* Set for aliases once they got through assemble_alias. Also set for extra name aliases in varpool_extra_name_alias. */ unsigned alias : 1; + unsigned extra_name_alias : 1; /* Set when variable is used from other LTRANS partition. */ unsigned used_from_other_partition : 1; /* Set when variable is available in the other LTRANS partition. @@ -463,6 +459,7 @@ extern GTY(()) struct cgraph_node *cgraph_new_nodes; extern GTY(()) struct cgraph_asm_node *cgraph_asm_nodes; extern GTY(()) int cgraph_order; +extern bool same_body_aliases_done; /* In cgraph.c */ void dump_cgraph (FILE *); @@ -488,7 +485,6 @@ struct cgraph_node * cgraph_get_create_node (tree); struct cgraph_node * cgraph_same_body_alias (struct cgraph_node *, tree, tree); struct cgraph_node * cgraph_add_thunk (struct cgraph_node *, tree, tree, bool, HOST_WIDE_INT, HOST_WIDE_INT, tree, tree); -void cgraph_remove_same_body_alias (struct cgraph_node *); struct cgraph_node *cgraph_node_for_asm (tree); struct cgraph_edge *cgraph_edge (struct cgraph_node *, gimple); void cgraph_set_call_stmt (struct cgraph_edge *, gimple); @@ -508,6 +504,7 @@ struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *, struct cgraph_node * cgraph_clone_node (struct cgraph_node *, tree, gcov_type, int, bool, VEC(cgraph_edge_p,heap) *, bool); +struct cgraph_node *cgraph_create_function_alias (tree, tree); void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *); void cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *, @@ -538,6 +535,7 @@ bool cgraph_will_be_removed_from_program_if_no_direct_calls (struct cgraph_node *node); bool cgraph_can_remove_if_no_direct_calls_and_refs_p (struct cgraph_node *node); +bool cgraph_can_remove_if_no_direct_calls_p (struct cgraph_node *node); bool resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution); bool cgraph_used_from_object_file_p (struct cgraph_node *); bool varpool_used_from_object_file_p (struct varpool_node *); @@ -577,6 +575,7 @@ void tree_function_versioning (tree, tree, VEC (ipa_replace_map_p,gc)*, bool, bi bitmap, basic_block); void record_references_in_initializer (tree, bool); bool cgraph_process_new_functions (void); +void cgraph_process_same_body_aliases (void); bool cgraph_decide_is_function_needed (struct cgraph_node *, tree); @@ -666,9 +665,13 @@ bool varpool_analyze_pending_decls (void); void varpool_remove_unreferenced_decls (void); void varpool_empty_needed_queue (void); struct varpool_node * varpool_extra_name_alias (tree, tree); +struct varpool_node * varpool_create_variable_alias (tree, tree); const char * varpool_node_name (struct varpool_node *node); void varpool_reset_queue (void); bool const_value_known_p (tree); +bool varpool_for_node_and_aliases (struct varpool_node *, + bool (*) (struct varpool_node *, void *), + void *, bool); /* Walk all reachable static variables. */ #define FOR_EACH_STATIC_VARIABLE(node) \ @@ -746,7 +749,7 @@ cgraph_next_defined_function (struct cgraph_node *node) static inline bool cgraph_function_with_gimple_body_p (struct cgraph_node *node) { - return node->analyzed && !node->thunk.thunk_p; + return node->analyzed && !node->thunk.thunk_p && !node->alias; } /* Return first function with body defined. */ @@ -928,19 +931,6 @@ cgraph_only_called_directly_or_aliased_p (struct cgraph_node *node) if all direct calls are eliminated. */ static inline bool -cgraph_can_remove_if_no_direct_calls_p (struct cgraph_node *node) -{ - /* Extern inlines can always go, we will use the external definition. */ - if (DECL_EXTERNAL (node->decl)) - return true; - return (!node->address_taken - && cgraph_can_remove_if_no_direct_calls_and_refs_p (node)); -} - -/* Return true when function NODE can be removed from callgraph - if all direct calls are eliminated. */ - -static inline bool varpool_can_remove_if_no_refs (struct varpool_node *node) { return (!node->force_output && !node->used_from_other_partition @@ -968,6 +958,34 @@ htab_t constant_pool_htab (void); /* FIXME: inappropriate dependency of cgraph on IPA. */ #include "ipa-ref-inline.h" +/* Return node that alias N is aliasing. */ + +static inline struct cgraph_node * +cgraph_alias_aliased_node (struct cgraph_node *n) +{ + struct ipa_ref *ref; + + ipa_ref_list_reference_iterate (&n->ref_list, 0, ref); + gcc_checking_assert (ref->use == IPA_REF_ALIAS); + if (ref->refered_type == IPA_REF_CGRAPH) + return ipa_ref_node (ref); + return NULL; +} + +/* Return node that alias N is aliasing. */ + +static inline struct varpool_node * +varpool_alias_aliased_node (struct varpool_node *n) +{ + struct ipa_ref *ref; + + ipa_ref_list_reference_iterate (&n->ref_list, 0, ref); + gcc_checking_assert (ref->use == IPA_REF_ALIAS); + if (ref->refered_type == IPA_REF_CGRAPH) + return ipa_ref_varpool_node (ref); + return NULL; +} + /* Given NODE, walk the alias chain to return the function NODE is alias of. Walk through thunk, too. When AVAILABILITY is non-NULL, get minimal availablity in the chain. */ @@ -979,11 +997,13 @@ cgraph_function_node (struct cgraph_node *node, enum availability *availability) *availability = cgraph_function_body_availability (node); while (node) { - if (node->thunk.thunk_p) + if (node->alias && node->analyzed) + node = cgraph_alias_aliased_node (node); + else if (node->thunk.thunk_p) node = node->callees->callee; else return node; - if (availability) + if (node && availability) { enum availability a; a = cgraph_function_body_availability (node); @@ -991,6 +1011,8 @@ cgraph_function_node (struct cgraph_node *node, enum availability *availability) *availability = a; } } + if (*availability) + *availability = AVAIL_NOT_AVAILABLE; return NULL; } @@ -1003,7 +1025,50 @@ cgraph_function_or_thunk_node (struct cgraph_node *node, enum availability *avai { if (availability) *availability = cgraph_function_body_availability (node); - return node; + while (node) + { + if (node->alias && node->analyzed) + node = cgraph_alias_aliased_node (node); + else + return node; + if (node && availability) + { + enum availability a; + a = cgraph_function_body_availability (node); + if (a < *availability) + *availability = a; + } + } + if (*availability) + *availability = AVAIL_NOT_AVAILABLE; + return NULL; +} + +/* Given NODE, walk the alias chain to return the function NODE is alias of. + Do not walk through thunks. + When AVAILABILITY is non-NULL, get minimal availablity in the chain. */ + +static inline struct varpool_node * +varpool_variable_node (struct varpool_node *node, enum availability *availability) +{ + if (availability) + *availability = cgraph_variable_initializer_availability (node); + while (node) + { + if (node->alias && node->analyzed) + node = varpool_alias_aliased_node (node); + else + return node; + if (node && availability) + { + enum availability a; + a = cgraph_variable_initializer_availability (node); + if (a < *availability) + *availability = a; + } + } + if (*availability) + *availability = AVAIL_NOT_AVAILABLE; return NULL; } diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c index 961804b415e..8bf88300593 100644 --- a/gcc/cgraphbuild.c +++ b/gcc/cgraphbuild.c @@ -87,8 +87,6 @@ record_reference (tree *tp, int *walk_subtrees, void *data) if (lang_hooks.callgraph.analyze_expr) lang_hooks.callgraph.analyze_expr (&decl, walk_subtrees); varpool_mark_needed_node (vnode); - if (vnode->alias && vnode->extra_name) - vnode = vnode->extra_name; ipa_record_reference (NULL, ctx->varpool_node, NULL, vnode, IPA_REF_ADDR, NULL); @@ -261,8 +259,6 @@ mark_address (gimple stmt, tree addr, void *data) if (lang_hooks.callgraph.analyze_expr) lang_hooks.callgraph.analyze_expr (&addr, &walk_subtrees); varpool_mark_needed_node (vnode); - if (vnode->alias && vnode->extra_name) - vnode = vnode->extra_name; ipa_record_reference ((struct cgraph_node *)data, NULL, NULL, vnode, IPA_REF_ADDR, stmt); @@ -296,8 +292,6 @@ mark_load (gimple stmt, tree t, void *data) if (lang_hooks.callgraph.analyze_expr) lang_hooks.callgraph.analyze_expr (&t, &walk_subtrees); varpool_mark_needed_node (vnode); - if (vnode->alias && vnode->extra_name) - vnode = vnode->extra_name; ipa_record_reference ((struct cgraph_node *)data, NULL, NULL, vnode, IPA_REF_LOAD, stmt); @@ -320,8 +314,6 @@ mark_store (gimple stmt, tree t, void *data) if (lang_hooks.callgraph.analyze_expr) lang_hooks.callgraph.analyze_expr (&t, &walk_subtrees); varpool_mark_needed_node (vnode); - if (vnode->alias && vnode->extra_name) - vnode = vnode->extra_name; ipa_record_reference ((struct cgraph_node *)data, NULL, NULL, vnode, IPA_REF_STORE, stmt); diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index dd247eb231d..6683d2a5df3 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -167,6 +167,7 @@ cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl) the name later after finalizing the function and the fact is noticed in assemble_name then. This is arguably a bug. */ if (DECL_ASSEMBLER_NAME_SET_P (decl) + && (!node->thunk.thunk_p && !node->same_body_alias) && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) return true; @@ -391,6 +392,8 @@ cgraph_mark_if_needed (tree decl) static bool clone_of_p (struct cgraph_node *node, struct cgraph_node *node2) { + node = cgraph_function_or_thunk_node (node, NULL); + node2 = cgraph_function_or_thunk_node (node2, NULL); while (node != node2 && node2) node2 = node2->clone_of; return node2 != NULL; @@ -619,6 +622,36 @@ verify_cgraph_node (struct cgraph_node *node) while (n != node); } + if (node->analyzed && node->alias) + { + bool ref_found = false; + int i; + struct ipa_ref *ref; + + if (node->callees) + { + error ("Alias has call edges"); + error_found = true; + } + for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++) + if (ref->use != IPA_REF_ALIAS) + { + error ("Alias has non-alias refernece"); + error_found = true; + } + else if (ref_found) + { + error ("Alias has more than one alias reference"); + error_found = true; + } + else + ref_found = true; + if (!ref_found) + { + error ("Analyzed alias has no reference"); + error_found = true; + } + } if (node->analyzed && node->thunk.thunk_p) { if (!node->callees) @@ -669,19 +702,17 @@ verify_cgraph_node (struct cgraph_node *node) } if (!e->indirect_unknown_callee) { - if (e->callee->same_body_alias) - { - error ("edge points to same body alias:"); - debug_tree (e->callee->decl); - error_found = true; - } - else if (!e->callee->global.inlined_to - && decl - && cgraph_get_node (decl) - && (e->callee->former_clone_of - != cgraph_get_node (decl)->decl) - && !clone_of_p (cgraph_get_node (decl), - e->callee)) + if (!e->callee->global.inlined_to + && decl + && cgraph_get_node (decl) + && (e->callee->former_clone_of + != cgraph_get_node (decl)->decl) + /* IPA-CP sometimes redirect edge to clone and then back to the former + function. This ping-pong has to go, eventaully. */ + && (cgraph_function_or_thunk_node (cgraph_get_node (decl), NULL) + != cgraph_function_or_thunk_node (e->callee, NULL)) + && !clone_of_p (cgraph_get_node (decl), + e->callee)) { error ("edge points to wrong declaration:"); debug_tree (e->callee->decl); @@ -781,7 +812,53 @@ cgraph_analyze_function (struct cgraph_node *node) tree save = current_function_decl; tree decl = node->decl; - if (node->thunk.thunk_p) + if (node->alias && node->thunk.alias) + { + struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias); + if (!VEC_length (ipa_ref_t, node->ref_list.references)) + ipa_record_reference (node, NULL, tgt, NULL, IPA_REF_ALIAS, NULL); + if (node->same_body_alias) + { + DECL_VIRTUAL_P (node->decl) = DECL_VIRTUAL_P (node->thunk.alias); + DECL_DECLARED_INLINE_P (node->decl) + = DECL_DECLARED_INLINE_P (node->thunk.alias); + DECL_DISREGARD_INLINE_LIMITS (node->decl) + = DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias); + } + + /* Fixup visibility nonsences C++ frontend produce on same body aliases. */ + if (TREE_PUBLIC (node->decl) && node->same_body_alias) + { + DECL_EXTERNAL (node->decl) = DECL_EXTERNAL (node->thunk.alias); + if (DECL_ONE_ONLY (node->thunk.alias)) + { + DECL_COMDAT (node->decl) = DECL_COMDAT (node->thunk.alias); + DECL_COMDAT_GROUP (node->decl) = DECL_COMDAT_GROUP (node->thunk.alias); + if (DECL_ONE_ONLY (node->thunk.alias) && !node->same_comdat_group) + { + struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias); + node->same_comdat_group = tgt; + if (!tgt->same_comdat_group) + tgt->same_comdat_group = node; + else + { + struct cgraph_node *n; + for (n = tgt->same_comdat_group; + n->same_comdat_group != tgt; + n = n->same_comdat_group) + ; + n->same_comdat_group = node; + } + } + } + } + cgraph_mark_reachable_node (cgraph_alias_aliased_node (node)); + if (node->address_taken) + cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node)); + if (cgraph_decide_is_function_needed (node, node->decl)) + cgraph_mark_needed_node (node); + } + else if (node->thunk.thunk_p) { cgraph_create_edge (node, cgraph_get_node (node->thunk.alias), NULL, 0, CGRAPH_FREQ_BASE); @@ -809,6 +886,26 @@ cgraph_analyze_function (struct cgraph_node *node) current_function_decl = save; } +/* C++ frontend produce same body aliases all over the place, even before PCH + gets streamed out. It relies on us linking the aliases with their function + in order to do the fixups, but ipa-ref is not PCH safe. Consequentely we + first produce aliases without links, but once C++ FE is sure he won't sream + PCH we build the links via this function. */ + +void +cgraph_process_same_body_aliases (void) +{ + struct cgraph_node *node; + for (node = cgraph_nodes; node; node = node->next) + if (node->same_body_alias + && !VEC_length (ipa_ref_t, node->ref_list.references)) + { + struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias); + ipa_record_reference (node, NULL, tgt, NULL, IPA_REF_ALIAS, NULL); + } + same_body_aliases_done = true; +} + /* Process attributes common for vars and functions. */ static void @@ -880,7 +977,7 @@ process_function_and_variable_attributes (struct cgraph_node *first, cgraph_mark_needed_node (node); } if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)) - && node->local.finalized) + && (node->local.finalized && !node->alias)) { warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes, "%<weakref%> attribute ignored" @@ -979,6 +1076,7 @@ cgraph_analyze_functions (void) weak alias attribute to kill its body. See gcc.c-torture/compile/20011119-1.c */ if (!DECL_STRUCT_FUNCTION (decl) + && (!node->alias || !node->thunk.alias) && !node->thunk.thunk_p) { cgraph_reset_node (node); @@ -1046,11 +1144,13 @@ cgraph_analyze_functions (void) next = node->next; if (node->local.finalized && !gimple_has_body_p (decl) + && (!node->alias || !node->thunk.alias) && !node->thunk.thunk_p) cgraph_reset_node (node); if (!node->reachable - && (gimple_has_body_p (decl) || node->thunk.thunk_p)) + && (gimple_has_body_p (decl) || node->thunk.thunk_p + || (node->alias && node->thunk.alias))) { if (cgraph_dump_file) fprintf (cgraph_dump_file, " %s", cgraph_node_name (node)); @@ -1060,6 +1160,7 @@ cgraph_analyze_functions (void) else node->next_needed = NULL; gcc_assert (!node->local.finalized || node->thunk.thunk_p + || node->alias || gimple_has_body_p (decl)); gcc_assert (node->analyzed == node->local.finalized); } @@ -1074,6 +1175,64 @@ cgraph_analyze_functions (void) ggc_collect (); } +/* Translate the ugly representation of aliases as alias pairs into nice + representation in callgraph. We don't handle all cases yet, + unforutnately. */ + +static void +handle_alias_pairs (void) +{ + alias_pair *p; + unsigned i; + struct cgraph_node *target_node; + struct cgraph_node *src_node; + struct varpool_node *target_vnode; + + for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);) + { + if (TREE_CODE (p->decl) == FUNCTION_DECL + && !lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) + && (target_node = cgraph_node_for_asm (p->target)) != NULL) + { + src_node = cgraph_get_node (p->decl); + if (src_node && src_node->local.finalized) + cgraph_reset_node (src_node); + /* Normally EXTERNAL flag is used to mark external inlines, + however for aliases it seems to be allowed to use it w/o + any meaning. See gcc.dg/attr-alias-3.c + However for weakref we insist on EXTERNAL flag being set. + See gcc.dg/attr-alias-5.c */ + if (DECL_EXTERNAL (p->decl)) + DECL_EXTERNAL (p->decl) = 0; + cgraph_create_function_alias (p->decl, target_node->decl); + VEC_unordered_remove (alias_pair, alias_pairs, i); + } + else if (TREE_CODE (p->decl) == VAR_DECL + && !lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) + && (target_vnode = varpool_node_for_asm (p->target)) != NULL) + { + /* Normally EXTERNAL flag is used to mark external inlines, + however for aliases it seems to be allowed to use it w/o + any meaning. See gcc.dg/attr-alias-3.c + However for weakref we insist on EXTERNAL flag being set. + See gcc.dg/attr-alias-5.c */ + if (DECL_EXTERNAL (p->decl)) + DECL_EXTERNAL (p->decl) = 0; + varpool_create_variable_alias (p->decl, target_vnode->decl); + VEC_unordered_remove (alias_pair, alias_pairs, i); + } + else + { + if (dump_file) + fprintf (dump_file, "Unhandled alias %s->%s\n", + IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p->decl)), + IDENTIFIER_POINTER (p->target)); + + i++; + } + } +} + /* Analyze the whole compilation unit once it is parsed completely. */ @@ -1099,6 +1258,7 @@ cgraph_finalize_compilation_unit (void) /* Mark alias targets necessary and emit diagnostics. */ finish_aliases_1 (); + handle_alias_pairs (); if (!quiet_flag) { @@ -1115,6 +1275,7 @@ cgraph_finalize_compilation_unit (void) /* Mark alias targets necessary and emit diagnostics. */ finish_aliases_1 (); + handle_alias_pairs (); /* Gimplify and lower thunks. */ cgraph_analyze_functions (); @@ -1157,9 +1318,11 @@ cgraph_mark_functions_to_output (void) outside the current compilation unit. */ if (node->analyzed && !node->thunk.thunk_p + && !node->alias && !node->global.inlined_to && (!cgraph_only_called_directly_p (node) - || (e && node->reachable)) + || ((e || ipa_ref_has_aliases_p (&node->ref_list)) + && node->reachable)) && !TREE_ASM_WRITTEN (decl) && !DECL_EXTERNAL (decl)) { @@ -1170,7 +1333,7 @@ cgraph_mark_functions_to_output (void) for (next = node->same_comdat_group; next != node; next = next->same_comdat_group) - if (!next->thunk.thunk_p) + if (!next->thunk.thunk_p && !next->alias) next->process = 1; } } @@ -1190,6 +1353,7 @@ cgraph_mark_functions_to_output (void) are inside partition, we can end up not removing the body since we no longer have analyzed node pointing to it. */ && !node->in_other_partition + && !node->alias && !DECL_EXTERNAL (decl)) { dump_cgraph_node (stderr, node); @@ -1219,7 +1383,7 @@ cgraph_mark_functions_to_output (void) && !DECL_EXTERNAL (decl)) { dump_cgraph_node (stderr, node); - internal_error ("failed to reclaim unneeded function"); + internal_error ("failed to reclaim unneeded functionin same comdat group"); } } #endif @@ -1569,23 +1733,35 @@ assemble_thunk (struct cgraph_node *node) } -/* Assemble thunks asociated to NODE. */ + +/* Assemble thunks and aliases asociated to NODE. */ static void -assemble_thunks (struct cgraph_node *node) +assemble_thunks_and_aliases (struct cgraph_node *node) { struct cgraph_edge *e; + int i; + struct ipa_ref *ref; + for (e = node->callers; e;) if (e->caller->thunk.thunk_p) { struct cgraph_node *thunk = e->caller; e = e->next_caller; - assemble_thunks (thunk); + assemble_thunks_and_aliases (thunk); assemble_thunk (thunk); } else e = e->next_caller; + for (i = 0; ipa_ref_list_refering_iterate (&node->ref_list, i, ref); i++) + if (ref->use == IPA_REF_ALIAS) + { + struct cgraph_node *alias = ipa_ref_refering_node (ref); + assemble_alias (alias->decl, + DECL_ASSEMBLER_NAME (alias->thunk.alias)); + assemble_thunks_and_aliases (alias); + } } /* Expand function specified by NODE. */ @@ -1600,27 +1776,7 @@ cgraph_expand_function (struct cgraph_node *node) announce_function (decl); node->process = 0; - if (node->same_body) - { - struct cgraph_node *alias, *next; - bool saved_alias = node->alias; - for (alias = node->same_body; - alias && alias->next; alias = alias->next) - ; - /* Walk aliases in the order they were created; it is possible that - thunks refers to the aliases made earlier. */ - for (; alias; alias = next) - { - next = alias->previous; - if (!alias->thunk.thunk_p) - assemble_alias (alias->decl, - DECL_ASSEMBLER_NAME (alias->thunk.alias)); - } - node->alias = saved_alias; - cgraph_process_new_functions (); - } - - assemble_thunks (node); + assemble_thunks_and_aliases (node); gcc_assert (node->lowered); /* Generate RTL for the body of DECL. */ @@ -1736,7 +1892,7 @@ cgraph_output_in_order (void) for (pf = cgraph_nodes; pf; pf = pf->next) { - if (pf->process && !pf->thunk.thunk_p) + if (pf->process && !pf->thunk.thunk_p && !pf->alias) { i = pf->order; gcc_assert (nodes[i].kind == ORDER_UNDEFINED); @@ -1810,7 +1966,7 @@ bool cgraph_preserve_function_body_p (struct cgraph_node *node) { gcc_assert (cgraph_global_info_ready); - gcc_assert (!node->same_body_alias); + gcc_assert (!node->alias && !node->thunk.thunk_p); /* Look if there is any clone around. */ if (node->clones) diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c index 76c175cd552..d267b701f1f 100644 --- a/gcc/combine-stack-adj.c +++ b/gcc/combine-stack-adj.c @@ -584,7 +584,6 @@ struct rtl_opt_pass pass_stack_adjustments = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_ggc_collect, /* todo_flags_finish */ } }; diff --git a/gcc/combine.c b/gcc/combine.c index 5b68bab12d7..56fb44eaf42 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -13944,7 +13944,6 @@ struct rtl_opt_pass pass_combine = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_df_finish | TODO_verify_rtl_sharing | TODO_ggc_collect, /* todo_flags_finish */ } diff --git a/gcc/common/common-target-def.h b/gcc/common/common-target-def.h new file mode 100644 index 00000000000..ea16beef5ea --- /dev/null +++ b/gcc/common/common-target-def.h @@ -0,0 +1,25 @@ +/* Default initializers for common target hooks. + Copyright (C) 2011 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#ifdef TARGET_ASM_NAMED_SECTION +#define TARGET_HAVE_NAMED_SECTIONS true +#endif + +#include "common/common-target-hooks-def.h" +#include "hooks.h" +#include "common/common-targhooks.h" diff --git a/gcc/common/common-target.def b/gcc/common/common-target.def new file mode 100644 index 00000000000..ab89758221a --- /dev/null +++ b/gcc/common/common-target.def @@ -0,0 +1,101 @@ +/* Target hook definitions for common hooks. + Copyright (C) 2011 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +/* See target-hooks-macros.h for details of macros that should be + provided by the including file, and how to use them here. */ +#include "target-hooks-macros.h" + +#undef HOOK_TYPE +#define HOOK_TYPE "Common Target Hook" + +HOOK_VECTOR (TARGETM_COMMON_INITIALIZER, gcc_targetm_common) + +#undef HOOK_PREFIX +#define HOOK_PREFIX "TARGET_" + +/* Handle target switch DECODED for options structures OPTS and + OPTS_SET, at location LOC. Return true if the switch was valid. */ +DEFHOOK +(handle_option, + "", + bool, (struct gcc_options *opts, struct gcc_options *opts_set, + const struct cl_decoded_option *decoded, + location_t loc), + default_target_handle_option) + +DEFHOOK +(option_init_struct, +"Set target-dependent initial values of fields in @var{opts}.", + void, (struct gcc_options *opts), + hook_void_gcc_optionsp) + +/* Set default optimizations for the target. */ +DEFHOOKPOD +(option_optimization_table, + "", + const struct default_options *, empty_optimization_table) + +/* The initial value of target_flags. */ +DEFHOOKPOD +(default_target_flags, + "", + int, 0) + +/* Determine the type of unwind info to emit for exceptions. */ +DEFHOOK +(except_unwind_info, + "", + enum unwind_info_type, (struct gcc_options *opts), + default_except_unwind_info) + +DEFHOOK +(supports_split_stack, + "Whether this target supports splitting the stack when the options\ + described in @var{opts} have been passed. This is called\ + after options have been parsed, so the target may reject splitting\ + the stack in some configurations. The default version of this hook\ + returns false. If @var{report} is true, this function may issue a warning\ + or error; if @var{report} is false, it must simply return a value", + bool, (bool report, struct gcc_options *opts), + hook_bool_bool_gcc_optionsp_false) + +/* Leave the boolean fields at the end. */ + +/* True if unwinding tables should be generated by default. */ +DEFHOOKPOD +(unwind_tables_default, + "", + bool, false) + +/* True if arbitrary sections are supported. */ +DEFHOOKPOD +(have_named_sections, + "", + bool, false) + +DEFHOOKPOD +(always_strip_dotdot, + "True if @file{..} components should always be removed from directory names\ + computed relative to GCC's internal directories, false (default) if such\ + components should be preserved and directory names containing them passed\ + to other tools such as the linker.", + bool, false) + +HOOK_VECTOR_END (C90_EMPTY_HACK) + +#undef HOOK_PREFIX diff --git a/gcc/common/common-target.h b/gcc/common/common-target.h new file mode 100644 index 00000000000..cd2d47c38bb --- /dev/null +++ b/gcc/common/common-target.h @@ -0,0 +1,72 @@ +/* Data structure definitions for common hooks. + Copyright (C) 2010, 2011 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! */ + +#ifndef GCC_COMMON_TARGET_H +#define GCC_COMMON_TARGET_H + +#include "input.h" + +/* Sets of optimization levels at which an option may be enabled by + default_options_optimization. */ +enum opt_levels +{ + OPT_LEVELS_NONE, /* No levels (mark end of array). */ + OPT_LEVELS_ALL, /* All levels (used by targets to disable options + enabled in target-independent code). */ + OPT_LEVELS_0_ONLY, /* -O0 only. */ + OPT_LEVELS_1_PLUS, /* -O1 and above, including -Os. */ + OPT_LEVELS_1_PLUS_SPEED_ONLY, /* -O1 and above, but not -Os. */ + OPT_LEVELS_2_PLUS, /* -O2 and above, including -Os. */ + OPT_LEVELS_2_PLUS_SPEED_ONLY, /* -O2 and above, but not -Os. */ + OPT_LEVELS_3_PLUS, /* -O3 and above. */ + OPT_LEVELS_3_PLUS_AND_SIZE, /* -O3 and above and -Os. */ + OPT_LEVELS_SIZE, /* -Os only. */ + OPT_LEVELS_FAST /* -Ofast only. */ +}; + +/* Description of options to enable by default at given levels. */ +struct default_options +{ + /* The levels at which to enable the option. */ + enum opt_levels levels; + + /* The option index and argument or enabled/disabled sense of the + option, as passed to handle_generated_option. If ARG is NULL and + the option allows a negative form, the option is considered to be + passed in negative form when the optimization level is not one of + those in LEVELS (in order to handle changes to the optimization + level with the "optimize" attribute). */ + size_t opt_index; + const char *arg; + int value; +}; + +#define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME; +#define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS; +#define DEFHOOK_UNDOC DEFHOOK +#define HOOKSTRUCT(FRAGMENT) FRAGMENT + +#include "common-target.def" + +extern struct gcc_targetm_common targetm_common; + +#endif /* GCC_C_TARGET_H */ diff --git a/gcc/common/common-targhooks.c b/gcc/common/common-targhooks.c new file mode 100644 index 00000000000..d959cf98bee --- /dev/null +++ b/gcc/common/common-targhooks.c @@ -0,0 +1,85 @@ +/* Default common target hook functions. + Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "input.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-targhooks.h" + +/* Determine the exception handling mechanism for the target. */ + +enum unwind_info_type +default_except_unwind_info (struct gcc_options *opts ATTRIBUTE_UNUSED) +{ + /* Obey the configure switch to turn on sjlj exceptions. */ +#ifdef CONFIG_SJLJ_EXCEPTIONS + if (CONFIG_SJLJ_EXCEPTIONS) + return UI_SJLJ; +#endif + + /* ??? Change all users to the hook, then poison this. */ +#ifdef DWARF2_UNWIND_INFO + if (DWARF2_UNWIND_INFO) + return UI_DWARF2; +#endif + + return UI_SJLJ; +} + +/* To be used by targets that force dwarf2 unwind enabled. */ + +enum unwind_info_type +dwarf2_except_unwind_info (struct gcc_options *opts ATTRIBUTE_UNUSED) +{ + /* Obey the configure switch to turn on sjlj exceptions. */ +#ifdef CONFIG_SJLJ_EXCEPTIONS + if (CONFIG_SJLJ_EXCEPTIONS) + return UI_SJLJ; +#endif + + return UI_DWARF2; +} + +/* To be used by targets that force sjlj unwind enabled. */ + +enum unwind_info_type +sjlj_except_unwind_info (struct gcc_options *opts ATTRIBUTE_UNUSED) +{ + return UI_SJLJ; +} + +/* Default version of TARGET_HANDLE_OPTION. */ + +bool +default_target_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED, + location_t loc ATTRIBUTE_UNUSED) +{ + return true; +} + +const struct default_options empty_optimization_table[] = + { + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; diff --git a/gcc/common/common-targhooks.h b/gcc/common/common-targhooks.h new file mode 100644 index 00000000000..dab70ded8d8 --- /dev/null +++ b/gcc/common/common-targhooks.h @@ -0,0 +1,35 @@ +/* Default common target hook functions. + Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_COMMON_TARGHOOKS_H +#define GCC_COMMON_TARGHOOKS_H + +extern enum unwind_info_type default_except_unwind_info (struct gcc_options *); +extern enum unwind_info_type dwarf2_except_unwind_info (struct gcc_options *); +extern enum unwind_info_type sjlj_except_unwind_info (struct gcc_options *); + +extern bool default_target_handle_option (struct gcc_options *, + struct gcc_options *, + const struct cl_decoded_option *, + location_t); + +extern const struct default_options empty_optimization_table[]; + +#endif diff --git a/gcc/common/config/alpha/alpha-common.c b/gcc/common/config/alpha/alpha-common.c new file mode 100644 index 00000000000..fcf5369034d --- /dev/null +++ b/gcc/common/config/alpha/alpha-common.c @@ -0,0 +1,81 @@ +/* Common hooks for DEC Alpha. + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "diagnostic-core.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options alpha_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +/* Implement TARGET_HANDLE_OPTION. */ + +static bool +alpha_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc) +{ + size_t code = decoded->opt_index; + const char *arg = decoded->arg; + int value = decoded->value; + + switch (code) + { + case OPT_mfp_regs: + if (value == 0) + opts->x_target_flags |= MASK_SOFT_FP; + break; + + case OPT_mieee: + case OPT_mieee_with_inexact: + opts->x_target_flags |= MASK_IEEE_CONFORMANT; + break; + + case OPT_mtls_size_: + if (value != 16 && value != 32 && value != 64) + error_at (loc, "bad value %qs for -mtls-size switch", arg); + break; + } + + return true; +} + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS \ + (TARGET_DEFAULT | TARGET_CPU_DEFAULT | TARGET_DEFAULT_EXPLICIT_RELOCS) +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION alpha_handle_option + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE alpha_option_optimization_table + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/arm/arm-common.c b/gcc/common/config/arm/arm-common.c new file mode 100644 index 00000000000..b8348bfb9f2 --- /dev/null +++ b/gcc/common/config/arm/arm-common.c @@ -0,0 +1,76 @@ +/* Common hooks for ARM. + Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tm_p.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Set default optimization options. */ +static const struct default_options arm_option_optimization_table[] = + { + /* Enable section anchors by default at -O1 or higher. */ + { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 }, + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +/* Implement TARGET_EXCEPT_UNWIND_INFO. */ + +enum unwind_info_type +arm_except_unwind_info (struct gcc_options *opts) +{ + /* Honor the --enable-sjlj-exceptions configure switch. */ +#ifdef CONFIG_SJLJ_EXCEPTIONS + if (CONFIG_SJLJ_EXCEPTIONS) + return UI_SJLJ; +#endif + + /* If not using ARM EABI unwind tables... */ + if (ARM_UNWIND_INFO) + { + /* For simplicity elsewhere in this file, indicate that all unwind + info is disabled if we're not emitting unwind tables. */ + if (!opts->x_flag_exceptions && !opts->x_flag_unwind_tables) + return UI_NONE; + else + return UI_TARGET; + } + + /* ... we use sjlj exceptions for backwards compatibility. */ + return UI_SJLJ; +} + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_SCHED_PROLOG) + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE arm_option_optimization_table + +#undef TARGET_EXCEPT_UNWIND_INFO +#define TARGET_EXCEPT_UNWIND_INFO arm_except_unwind_info + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/avr/avr-common.c b/gcc/common/config/avr/avr-common.c new file mode 100644 index 00000000000..0ede1172e55 --- /dev/null +++ b/gcc/common/config/avr/avr-common.c @@ -0,0 +1,41 @@ +/* Common hooks for ATMEL AVR. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, + 2009, 2010, 2011 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options avr_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE avr_option_optimization_table + +#undef TARGET_EXCEPT_UNWIND_INFO +#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/bfin/bfin-common.c b/gcc/common/config/bfin/bfin-common.c new file mode 100644 index 00000000000..715a1aee6f9 --- /dev/null +++ b/gcc/common/config/bfin/bfin-common.c @@ -0,0 +1,390 @@ +/* Common hooks for Blackfin. + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "diagnostic-core.h" +#include "tm.h" +#include "machmode.h" +#include "tm_p.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +EXPORTED_CONST struct bfin_cpu bfin_cpus[] = +{ + + {"bf512", BFIN_CPU_BF512, 0x0002, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf512", BFIN_CPU_BF512, 0x0001, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf512", BFIN_CPU_BF512, 0x0000, + WA_SPECULATIVE_LOADS | WA_05000074}, + + {"bf514", BFIN_CPU_BF514, 0x0002, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf514", BFIN_CPU_BF514, 0x0001, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf514", BFIN_CPU_BF514, 0x0000, + WA_SPECULATIVE_LOADS | WA_05000074}, + + {"bf516", BFIN_CPU_BF516, 0x0002, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf516", BFIN_CPU_BF516, 0x0001, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf516", BFIN_CPU_BF516, 0x0000, + WA_SPECULATIVE_LOADS | WA_05000074}, + + {"bf518", BFIN_CPU_BF518, 0x0002, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf518", BFIN_CPU_BF518, 0x0001, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf518", BFIN_CPU_BF518, 0x0000, + WA_SPECULATIVE_LOADS | WA_05000074}, + + {"bf522", BFIN_CPU_BF522, 0x0002, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf522", BFIN_CPU_BF522, 0x0001, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, + {"bf522", BFIN_CPU_BF522, 0x0000, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, + + {"bf523", BFIN_CPU_BF523, 0x0002, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf523", BFIN_CPU_BF523, 0x0001, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, + {"bf523", BFIN_CPU_BF523, 0x0000, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, + + {"bf524", BFIN_CPU_BF524, 0x0002, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf524", BFIN_CPU_BF524, 0x0001, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, + {"bf524", BFIN_CPU_BF524, 0x0000, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, + + {"bf525", BFIN_CPU_BF525, 0x0002, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf525", BFIN_CPU_BF525, 0x0001, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, + {"bf525", BFIN_CPU_BF525, 0x0000, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, + + {"bf526", BFIN_CPU_BF526, 0x0002, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf526", BFIN_CPU_BF526, 0x0001, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, + {"bf526", BFIN_CPU_BF526, 0x0000, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, + + {"bf527", BFIN_CPU_BF527, 0x0002, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf527", BFIN_CPU_BF527, 0x0001, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, + {"bf527", BFIN_CPU_BF527, 0x0000, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, + + {"bf531", BFIN_CPU_BF531, 0x0006, + WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074}, + {"bf531", BFIN_CPU_BF531, 0x0005, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315 + | WA_LOAD_LCREGS | WA_05000074}, + {"bf531", BFIN_CPU_BF531, 0x0004, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + {"bf531", BFIN_CPU_BF531, 0x0003, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + + {"bf532", BFIN_CPU_BF532, 0x0006, + WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074}, + {"bf532", BFIN_CPU_BF532, 0x0005, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315 + | WA_LOAD_LCREGS | WA_05000074}, + {"bf532", BFIN_CPU_BF532, 0x0004, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + {"bf532", BFIN_CPU_BF532, 0x0003, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + + {"bf533", BFIN_CPU_BF533, 0x0006, + WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074}, + {"bf533", BFIN_CPU_BF533, 0x0005, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315 + | WA_LOAD_LCREGS | WA_05000074}, + {"bf533", BFIN_CPU_BF533, 0x0004, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + {"bf533", BFIN_CPU_BF533, 0x0003, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + + {"bf534", BFIN_CPU_BF534, 0x0003, + WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074}, + {"bf534", BFIN_CPU_BF534, 0x0002, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + {"bf534", BFIN_CPU_BF534, 0x0001, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + + {"bf536", BFIN_CPU_BF536, 0x0003, + WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074}, + {"bf536", BFIN_CPU_BF536, 0x0002, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + {"bf536", BFIN_CPU_BF536, 0x0001, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + + {"bf537", BFIN_CPU_BF537, 0x0003, + WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074}, + {"bf537", BFIN_CPU_BF537, 0x0002, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + {"bf537", BFIN_CPU_BF537, 0x0001, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + + {"bf538", BFIN_CPU_BF538, 0x0005, + WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074}, + {"bf538", BFIN_CPU_BF538, 0x0004, + WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074}, + {"bf538", BFIN_CPU_BF538, 0x0003, + WA_SPECULATIVE_LOADS | WA_RETS + | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074}, + {"bf538", BFIN_CPU_BF538, 0x0002, + WA_SPECULATIVE_LOADS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + + {"bf539", BFIN_CPU_BF539, 0x0005, + WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074}, + {"bf539", BFIN_CPU_BF539, 0x0004, + WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074}, + {"bf539", BFIN_CPU_BF539, 0x0003, + WA_SPECULATIVE_LOADS | WA_RETS + | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074}, + {"bf539", BFIN_CPU_BF539, 0x0002, + WA_SPECULATIVE_LOADS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + + {"bf542m", BFIN_CPU_BF542M, 0x0003, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + + {"bf542", BFIN_CPU_BF542, 0x0004, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf542", BFIN_CPU_BF542, 0x0002, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf542", BFIN_CPU_BF542, 0x0001, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf542", BFIN_CPU_BF542, 0x0000, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS + | WA_05000074}, + + {"bf544m", BFIN_CPU_BF544M, 0x0003, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + + {"bf544", BFIN_CPU_BF544, 0x0004, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf544", BFIN_CPU_BF544, 0x0002, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf544", BFIN_CPU_BF544, 0x0001, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf544", BFIN_CPU_BF544, 0x0000, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS + | WA_05000074}, + + {"bf547m", BFIN_CPU_BF547M, 0x0003, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + + {"bf547", BFIN_CPU_BF547, 0x0004, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf547", BFIN_CPU_BF547, 0x0002, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf547", BFIN_CPU_BF547, 0x0001, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf547", BFIN_CPU_BF547, 0x0000, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS + | WA_05000074}, + + {"bf548m", BFIN_CPU_BF548M, 0x0003, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + + {"bf548", BFIN_CPU_BF548, 0x0004, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf548", BFIN_CPU_BF548, 0x0002, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf548", BFIN_CPU_BF548, 0x0001, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf548", BFIN_CPU_BF548, 0x0000, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS + | WA_05000074}, + + {"bf549m", BFIN_CPU_BF549M, 0x0003, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + + {"bf549", BFIN_CPU_BF549, 0x0004, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf549", BFIN_CPU_BF549, 0x0002, + WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf549", BFIN_CPU_BF549, 0x0001, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074}, + {"bf549", BFIN_CPU_BF549, 0x0000, + WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS + | WA_05000074}, + + {"bf561", BFIN_CPU_BF561, 0x0005, WA_RETS + | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074}, + {"bf561", BFIN_CPU_BF561, 0x0003, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + {"bf561", BFIN_CPU_BF561, 0x0002, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS + | WA_05000074}, + + {"bf592", BFIN_CPU_BF592, 0x0001, + WA_SPECULATIVE_LOADS | WA_05000074}, + {"bf592", BFIN_CPU_BF592, 0x0000, + WA_SPECULATIVE_LOADS | WA_05000074}, + + {NULL, BFIN_CPU_UNKNOWN, 0, 0} +}; + +/* Implement TARGET_HANDLE_OPTION. */ + +static bool +bfin_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc) +{ + size_t code = decoded->opt_index; + const char *arg = decoded->arg; + int value = decoded->value; + + switch (code) + { + case OPT_mshared_library_id_: + if (value > MAX_LIBRARY_ID) + error_at (loc, "-mshared-library-id=%s is not between 0 and %d", + arg, MAX_LIBRARY_ID); + return true; + + case OPT_mcpu_: + { + const char *p, *q; + int i; + + i = 0; + while ((p = bfin_cpus[i].name) != NULL) + { + if (strncmp (arg, p, strlen (p)) == 0) + break; + i++; + } + + if (p == NULL) + { + error_at (loc, "-mcpu=%s is not valid", arg); + return false; + } + + opts->x_bfin_cpu_type = bfin_cpus[i].type; + + q = arg + strlen (p); + + if (*q == '\0') + { + opts->x_bfin_si_revision = bfin_cpus[i].si_revision; + opts->x_bfin_workarounds |= bfin_cpus[i].workarounds; + } + else if (strcmp (q, "-none") == 0) + opts->x_bfin_si_revision = -1; + else if (strcmp (q, "-any") == 0) + { + opts->x_bfin_si_revision = 0xffff; + while (bfin_cpus[i].type == opts->x_bfin_cpu_type) + { + opts->x_bfin_workarounds |= bfin_cpus[i].workarounds; + i++; + } + } + else + { + unsigned int si_major, si_minor; + int rev_len, n; + + rev_len = strlen (q); + + if (sscanf (q, "-%u.%u%n", &si_major, &si_minor, &n) != 2 + || n != rev_len + || si_major > 0xff || si_minor > 0xff) + { + invalid_silicon_revision: + error_at (loc, "-mcpu=%s has invalid silicon revision", arg); + return false; + } + + opts->x_bfin_si_revision = (si_major << 8) | si_minor; + + while (bfin_cpus[i].type == opts->x_bfin_cpu_type + && bfin_cpus[i].si_revision != opts->x_bfin_si_revision) + i++; + + if (bfin_cpus[i].type != opts->x_bfin_cpu_type) + goto invalid_silicon_revision; + + opts->x_bfin_workarounds |= bfin_cpus[i].workarounds; + } + + return true; + } + + default: + return true; + } +} + +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION bfin_handle_option + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/cris/cris-common.c b/gcc/common/config/cris/cris-common.c new file mode 100644 index 00000000000..e4d30a868b2 --- /dev/null +++ b/gcc/common/config/cris/cris-common.c @@ -0,0 +1,105 @@ +/* Common hooks for CRIS. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, + 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ + +static const struct default_options cris_option_optimization_table[] = + { + { OPT_LEVELS_2_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +/* TARGET_HANDLE_OPTION worker. We just store the values into local + variables here. Checks for correct semantics are in + cris_option_override. */ + +static bool +cris_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc ATTRIBUTE_UNUSED) +{ + size_t code = decoded->opt_index; + + switch (code) + { + case OPT_metrax100: + opts->x_target_flags + |= (MASK_SVINTO + + MASK_ETRAX4_ADD + + MASK_ALIGN_BY_32); + break; + + case OPT_mno_etrax100: + opts->x_target_flags + &= ~(MASK_SVINTO + + MASK_ETRAX4_ADD + + MASK_ALIGN_BY_32); + break; + + case OPT_m32_bit: + case OPT_m32bit: + opts->x_target_flags + |= (MASK_STACK_ALIGN + + MASK_CONST_ALIGN + + MASK_DATA_ALIGN + + MASK_ALIGN_BY_32); + break; + + case OPT_m16_bit: + case OPT_m16bit: + opts->x_target_flags + |= (MASK_STACK_ALIGN + + MASK_CONST_ALIGN + + MASK_DATA_ALIGN); + break; + + case OPT_m8_bit: + case OPT_m8bit: + opts->x_target_flags + &= ~(MASK_STACK_ALIGN + + MASK_CONST_ALIGN + + MASK_DATA_ALIGN); + break; + + default: + break; + } + + return true; +} + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | CRIS_SUBTARGET_DEFAULT) +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION cris_handle_option +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE cris_option_optimization_table + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/default-common.c b/gcc/common/config/default-common.c new file mode 100644 index 00000000000..0f6251e3dc7 --- /dev/null +++ b/gcc/common/config/default-common.c @@ -0,0 +1,36 @@ +/* Default common target hooks initializer. + Copyright (C) 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" /* For TARGET_ASM_NAMED_SECTION used in default for + TARGET_HAVE_NAMED_SECTIONS. */ +#include "common/common-target.h" +#include "common/common-target-def.h" + +/* FIXME: Do not include tm.h or tm_p.h here; if it is useful for a target to + define some macros for the initializer in a header without defining + targetm_common itself (for example, because of interactions with + some hooks depending on the target OS and others on the target + architecture), create a separate tm_common.h for only the relevant + definitions. */ + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/fr30/fr30-common.c b/gcc/common/config/fr30/fr30-common.c new file mode 100644 index 00000000000..d8cc320630e --- /dev/null +++ b/gcc/common/config/fr30/fr30-common.c @@ -0,0 +1,41 @@ +/* Common hooks for FR30. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009, + 2010, 2011 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options fr30_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_EXCEPT_UNWIND_INFO +#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE fr30_option_optimization_table + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/frv/frv-common.c b/gcc/common/config/frv/frv-common.c new file mode 100644 index 00000000000..d72f1d59196 --- /dev/null +++ b/gcc/common/config/frv/frv-common.c @@ -0,0 +1,55 @@ +/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, + 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Allow us to easily change the default for -malloc-cc. */ +#ifndef DEFAULT_NO_ALLOC_CC +#define MASK_DEFAULT_ALLOC_CC MASK_ALLOC_CC +#else +#define MASK_DEFAULT_ALLOC_CC 0 +#endif + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options frv_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS \ + (MASK_DEFAULT_ALLOC_CC \ + | MASK_COND_MOVE \ + | MASK_SCC \ + | MASK_COND_EXEC \ + | MASK_VLIW_BRANCH \ + | MASK_MULTI_CE \ + | MASK_NESTED_CE) +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE frv_option_optimization_table + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/h8300/h8300-common.c b/gcc/common/config/h8300/h8300-common.c new file mode 100644 index 00000000000..d5833f6bd78 --- /dev/null +++ b/gcc/common/config/h8300/h8300-common.c @@ -0,0 +1,49 @@ +/* Common hooks for Renesas H8/300. + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ + +static const struct default_options h8300_option_optimization_table[] = + { + /* Basic block reordering is only beneficial on targets with cache + and/or variable-cycle branches where (cycle count taken != + cycle count not taken). */ + { OPT_LEVELS_ALL, OPT_freorder_blocks, NULL, 0 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE h8300_option_optimization_table + +#undef TARGET_EXCEPT_UNWIND_INFO +#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c new file mode 100644 index 00000000000..1fd33bd39f8 --- /dev/null +++ b/gcc/common/config/i386/i386-common.c @@ -0,0 +1,638 @@ +/* IA-32 common hooks. + Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "diagnostic-core.h" +#include "tm.h" +#include "tm_p.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Define a set of ISAs which are available when a given ISA is + enabled. MMX and SSE ISAs are handled separately. */ + +#define OPTION_MASK_ISA_MMX_SET OPTION_MASK_ISA_MMX +#define OPTION_MASK_ISA_3DNOW_SET \ + (OPTION_MASK_ISA_3DNOW | OPTION_MASK_ISA_MMX_SET) + +#define OPTION_MASK_ISA_SSE_SET OPTION_MASK_ISA_SSE +#define OPTION_MASK_ISA_SSE2_SET \ + (OPTION_MASK_ISA_SSE2 | OPTION_MASK_ISA_SSE_SET) +#define OPTION_MASK_ISA_SSE3_SET \ + (OPTION_MASK_ISA_SSE3 | OPTION_MASK_ISA_SSE2_SET) +#define OPTION_MASK_ISA_SSSE3_SET \ + (OPTION_MASK_ISA_SSSE3 | OPTION_MASK_ISA_SSE3_SET) +#define OPTION_MASK_ISA_SSE4_1_SET \ + (OPTION_MASK_ISA_SSE4_1 | OPTION_MASK_ISA_SSSE3_SET) +#define OPTION_MASK_ISA_SSE4_2_SET \ + (OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_SSE4_1_SET) +#define OPTION_MASK_ISA_AVX_SET \ + (OPTION_MASK_ISA_AVX | OPTION_MASK_ISA_SSE4_2_SET) +#define OPTION_MASK_ISA_FMA_SET \ + (OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_AVX_SET) + +/* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same + as -msse4.2. */ +#define OPTION_MASK_ISA_SSE4_SET OPTION_MASK_ISA_SSE4_2_SET + +#define OPTION_MASK_ISA_SSE4A_SET \ + (OPTION_MASK_ISA_SSE4A | OPTION_MASK_ISA_SSE3_SET) +#define OPTION_MASK_ISA_FMA4_SET \ + (OPTION_MASK_ISA_FMA4 | OPTION_MASK_ISA_SSE4A_SET \ + | OPTION_MASK_ISA_AVX_SET) +#define OPTION_MASK_ISA_XOP_SET \ + (OPTION_MASK_ISA_XOP | OPTION_MASK_ISA_FMA4_SET) +#define OPTION_MASK_ISA_LWP_SET \ + OPTION_MASK_ISA_LWP + +/* AES and PCLMUL need SSE2 because they use xmm registers */ +#define OPTION_MASK_ISA_AES_SET \ + (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2_SET) +#define OPTION_MASK_ISA_PCLMUL_SET \ + (OPTION_MASK_ISA_PCLMUL | OPTION_MASK_ISA_SSE2_SET) + +#define OPTION_MASK_ISA_ABM_SET \ + (OPTION_MASK_ISA_ABM | OPTION_MASK_ISA_POPCNT) + +#define OPTION_MASK_ISA_BMI_SET OPTION_MASK_ISA_BMI +#define OPTION_MASK_ISA_TBM_SET OPTION_MASK_ISA_TBM +#define OPTION_MASK_ISA_POPCNT_SET OPTION_MASK_ISA_POPCNT +#define OPTION_MASK_ISA_CX16_SET OPTION_MASK_ISA_CX16 +#define OPTION_MASK_ISA_SAHF_SET OPTION_MASK_ISA_SAHF +#define OPTION_MASK_ISA_MOVBE_SET OPTION_MASK_ISA_MOVBE +#define OPTION_MASK_ISA_CRC32_SET OPTION_MASK_ISA_CRC32 + +#define OPTION_MASK_ISA_FSGSBASE_SET OPTION_MASK_ISA_FSGSBASE +#define OPTION_MASK_ISA_RDRND_SET OPTION_MASK_ISA_RDRND +#define OPTION_MASK_ISA_F16C_SET \ + (OPTION_MASK_ISA_F16C | OPTION_MASK_ISA_AVX_SET) + +/* Define a set of ISAs which aren't available when a given ISA is + disabled. MMX and SSE ISAs are handled separately. */ + +#define OPTION_MASK_ISA_MMX_UNSET \ + (OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_3DNOW_UNSET) +#define OPTION_MASK_ISA_3DNOW_UNSET \ + (OPTION_MASK_ISA_3DNOW | OPTION_MASK_ISA_3DNOW_A_UNSET) +#define OPTION_MASK_ISA_3DNOW_A_UNSET OPTION_MASK_ISA_3DNOW_A + +#define OPTION_MASK_ISA_SSE_UNSET \ + (OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_SSE2_UNSET) +#define OPTION_MASK_ISA_SSE2_UNSET \ + (OPTION_MASK_ISA_SSE2 | OPTION_MASK_ISA_SSE3_UNSET) +#define OPTION_MASK_ISA_SSE3_UNSET \ + (OPTION_MASK_ISA_SSE3 \ + | OPTION_MASK_ISA_SSSE3_UNSET \ + | OPTION_MASK_ISA_SSE4A_UNSET ) +#define OPTION_MASK_ISA_SSSE3_UNSET \ + (OPTION_MASK_ISA_SSSE3 | OPTION_MASK_ISA_SSE4_1_UNSET) +#define OPTION_MASK_ISA_SSE4_1_UNSET \ + (OPTION_MASK_ISA_SSE4_1 | OPTION_MASK_ISA_SSE4_2_UNSET) +#define OPTION_MASK_ISA_SSE4_2_UNSET \ + (OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_AVX_UNSET ) +#define OPTION_MASK_ISA_AVX_UNSET \ + (OPTION_MASK_ISA_AVX | OPTION_MASK_ISA_FMA_UNSET \ + | OPTION_MASK_ISA_FMA4_UNSET | OPTION_MASK_ISA_F16C_UNSET) +#define OPTION_MASK_ISA_FMA_UNSET OPTION_MASK_ISA_FMA + +/* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same + as -mno-sse4.1. */ +#define OPTION_MASK_ISA_SSE4_UNSET OPTION_MASK_ISA_SSE4_1_UNSET + +#define OPTION_MASK_ISA_SSE4A_UNSET \ + (OPTION_MASK_ISA_SSE4A | OPTION_MASK_ISA_FMA4_UNSET) + +#define OPTION_MASK_ISA_FMA4_UNSET \ + (OPTION_MASK_ISA_FMA4 | OPTION_MASK_ISA_XOP_UNSET) +#define OPTION_MASK_ISA_XOP_UNSET OPTION_MASK_ISA_XOP +#define OPTION_MASK_ISA_LWP_UNSET OPTION_MASK_ISA_LWP + +#define OPTION_MASK_ISA_AES_UNSET OPTION_MASK_ISA_AES +#define OPTION_MASK_ISA_PCLMUL_UNSET OPTION_MASK_ISA_PCLMUL +#define OPTION_MASK_ISA_ABM_UNSET OPTION_MASK_ISA_ABM +#define OPTION_MASK_ISA_BMI_UNSET OPTION_MASK_ISA_BMI +#define OPTION_MASK_ISA_TBM_UNSET OPTION_MASK_ISA_TBM +#define OPTION_MASK_ISA_POPCNT_UNSET OPTION_MASK_ISA_POPCNT +#define OPTION_MASK_ISA_CX16_UNSET OPTION_MASK_ISA_CX16 +#define OPTION_MASK_ISA_SAHF_UNSET OPTION_MASK_ISA_SAHF +#define OPTION_MASK_ISA_MOVBE_UNSET OPTION_MASK_ISA_MOVBE +#define OPTION_MASK_ISA_CRC32_UNSET OPTION_MASK_ISA_CRC32 + +#define OPTION_MASK_ISA_FSGSBASE_UNSET OPTION_MASK_ISA_FSGSBASE +#define OPTION_MASK_ISA_RDRND_UNSET OPTION_MASK_ISA_RDRND +#define OPTION_MASK_ISA_F16C_UNSET OPTION_MASK_ISA_F16C + +/* Implement TARGET_HANDLE_OPTION. */ + +bool +ix86_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc) +{ + size_t code = decoded->opt_index; + int value = decoded->value; + + switch (code) + { + case OPT_mmmx: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_MMX_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_MMX_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_MMX_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_MMX_UNSET; + } + return true; + + case OPT_m3dnow: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_3DNOW_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_3DNOW_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_3DNOW_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_3DNOW_UNSET; + } + return true; + + case OPT_m3dnowa: + return false; + + case OPT_msse: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE_UNSET; + } + return true; + + case OPT_msse2: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE2_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE2_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE2_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE2_UNSET; + } + return true; + + case OPT_msse3: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE3_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE3_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE3_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE3_UNSET; + } + return true; + + case OPT_mssse3: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSSE3_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSSE3_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSSE3_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSSE3_UNSET; + } + return true; + + case OPT_msse4_1: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE4_1_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_1_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE4_1_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_1_UNSET; + } + return true; + + case OPT_msse4_2: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE4_2_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_2_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE4_2_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_2_UNSET; + } + return true; + + case OPT_mavx: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX_UNSET; + } + return true; + + case OPT_mfma: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_FMA_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_FMA_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_FMA_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_FMA_UNSET; + } + return true; + + case OPT_msse4: + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE4_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_SET; + return true; + + case OPT_mno_sse4: + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE4_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_UNSET; + return true; + + case OPT_msse4a: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE4A_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4A_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE4A_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4A_UNSET; + } + return true; + + case OPT_mfma4: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_FMA4_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_FMA4_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_FMA4_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_FMA4_UNSET; + } + return true; + + case OPT_mxop: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_XOP_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_XOP_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_XOP_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_XOP_UNSET; + } + return true; + + case OPT_mlwp: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_LWP_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_LWP_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_LWP_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_LWP_UNSET; + } + return true; + + case OPT_mabm: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_ABM_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_ABM_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_ABM_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_ABM_UNSET; + } + return true; + + case OPT_mbmi: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_BMI_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_BMI_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_BMI_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_BMI_UNSET; + } + return true; + + case OPT_mtbm: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_TBM_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_TBM_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_TBM_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_TBM_UNSET; + } + return true; + + case OPT_mpopcnt: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_POPCNT_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_POPCNT_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_POPCNT_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_POPCNT_UNSET; + } + return true; + + case OPT_msahf: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SAHF_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SAHF_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SAHF_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SAHF_UNSET; + } + return true; + + case OPT_mcx16: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_CX16_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_CX16_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_CX16_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_CX16_UNSET; + } + return true; + + case OPT_mmovbe: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_MOVBE_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVBE_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_MOVBE_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVBE_UNSET; + } + return true; + + case OPT_mcrc32: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_CRC32_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_CRC32_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_CRC32_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_CRC32_UNSET; + } + return true; + + case OPT_maes: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AES_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AES_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AES_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AES_UNSET; + } + return true; + + case OPT_mpclmul: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_PCLMUL_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_PCLMUL_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_PCLMUL_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_PCLMUL_UNSET; + } + return true; + + case OPT_mfsgsbase: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_FSGSBASE_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_FSGSBASE_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_FSGSBASE_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_FSGSBASE_UNSET; + } + return true; + + case OPT_mrdrnd: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_RDRND_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_RDRND_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_RDRND_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_RDRND_UNSET; + } + return true; + + case OPT_mf16c: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_F16C_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_F16C_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_F16C_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_F16C_UNSET; + } + return true; + + /* Comes from final.c -- no real reason to change it. */ +#define MAX_CODE_ALIGN 16 + + case OPT_malign_loops_: + warning_at (loc, 0, "-malign-loops is obsolete, use -falign-loops"); + if (value > MAX_CODE_ALIGN) + error_at (loc, "-malign-loops=%d is not between 0 and %d", + value, MAX_CODE_ALIGN); + else + opts->x_align_loops = 1 << value; + return true; + + case OPT_malign_jumps_: + warning_at (loc, 0, "-malign-jumps is obsolete, use -falign-jumps"); + if (value > MAX_CODE_ALIGN) + error_at (loc, "-malign-jumps=%d is not between 0 and %d", + value, MAX_CODE_ALIGN); + else + opts->x_align_jumps = 1 << value; + return true; + + case OPT_malign_functions_: + warning_at (loc, 0, + "-malign-functions is obsolete, use -falign-functions"); + if (value > MAX_CODE_ALIGN) + error_at (loc, "-malign-functions=%d is not between 0 and %d", + value, MAX_CODE_ALIGN); + else + opts->x_align_functions = 1 << value; + return true; + + case OPT_mbranch_cost_: + if (value > 5) + { + error_at (loc, "-mbranch-cost=%d is not between 0 and 5", value); + opts->x_ix86_branch_cost = 5; + } + return true; + + default: + return true; + } +} + +static const struct default_options ix86_option_optimization_table[] = + { + /* Turn off -fschedule-insns by default. It tends to make the + problem with not enough registers even worse. */ + { OPT_LEVELS_ALL, OPT_fschedule_insns, NULL, 0 }, + +#ifdef SUBTARGET_OPTIMIZATION_OPTIONS + SUBTARGET_OPTIMIZATION_OPTIONS, +#endif + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +/* Implement TARGET_OPTION_INIT_STRUCT. */ + +static void +ix86_option_init_struct (struct gcc_options *opts) +{ + if (TARGET_MACHO) + /* The Darwin libraries never set errno, so we might as well + avoid calling them when that's the only reason we would. */ + opts->x_flag_errno_math = 0; + + opts->x_flag_pcc_struct_return = 2; + opts->x_flag_asynchronous_unwind_tables = 2; + opts->x_flag_vect_cost_model = 1; +} + +/* On the x86 -fsplit-stack and -fstack-protector both use the same + field in the TCB, so they can not be used together. */ + +static bool +ix86_supports_split_stack (bool report ATTRIBUTE_UNUSED, + struct gcc_options *opts ATTRIBUTE_UNUSED) +{ + bool ret = true; + +#ifndef TARGET_THREAD_SPLIT_STACK_OFFSET + if (report) + error ("%<-fsplit-stack%> currently only supported on GNU/Linux"); + ret = false; +#else + if (!HAVE_GAS_CFI_PERSONALITY_DIRECTIVE) + { + if (report) + error ("%<-fsplit-stack%> requires " + "assembler support for CFI directives"); + ret = false; + } +#endif + + return ret; +} + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS \ + (TARGET_DEFAULT \ + | TARGET_SUBTARGET_DEFAULT \ + | TARGET_TLS_DIRECT_SEG_REFS_DEFAULT) + +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION ix86_handle_option + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE ix86_option_optimization_table +#undef TARGET_OPTION_INIT_STRUCT +#define TARGET_OPTION_INIT_STRUCT ix86_option_init_struct + +#undef TARGET_SUPPORTS_SPLIT_STACK +#define TARGET_SUPPORTS_SPLIT_STACK ix86_supports_split_stack + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/ia64/ia64-common.c b/gcc/common/config/ia64/ia64-common.c new file mode 100644 index 00000000000..8c86ff49e68 --- /dev/null +++ b/gcc/common/config/ia64/ia64-common.c @@ -0,0 +1,97 @@ +/* Common hooks for IA64. + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, + 2009, 2010, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "diagnostic-core.h" +#include "tm.h" +#include "tm_p.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Implement overriding of the optimization options. */ +static const struct default_options ia64_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, +#ifdef SUBTARGET_OPTIMIZATION_OPTIONS + SUBTARGET_OPTIMIZATION_OPTIONS, +#endif + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +/* Implement TARGET_HANDLE_OPTION. */ + +static bool +ia64_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc) +{ + size_t code = decoded->opt_index; + const char *arg = decoded->arg; + int value = decoded->value; + + switch (code) + { + case OPT_mtls_size_: + if (value != 14 && value != 22 && value != 64) + error_at (loc, "bad value %<%s%> for -mtls-size= switch", arg); + return true; + + default: + return true; + } +} + +/* Implement TARGET_EXCEPT_UNWIND_INFO. */ + +enum unwind_info_type +ia64_except_unwind_info (struct gcc_options *opts) +{ + /* Honor the --enable-sjlj-exceptions configure switch. */ +#ifdef CONFIG_UNWIND_EXCEPTIONS + if (CONFIG_UNWIND_EXCEPTIONS) + return UI_SJLJ; +#endif + + /* For simplicity elsewhere in this file, indicate that all unwind + info is disabled if we're not emitting unwind tables. */ + if (!opts->x_flag_exceptions && !opts->x_flag_unwind_tables) + return UI_NONE; + + return UI_TARGET; +} + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE ia64_option_optimization_table + +#undef TARGET_EXCEPT_UNWIND_INFO +#define TARGET_EXCEPT_UNWIND_INFO ia64_except_unwind_info + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | TARGET_CPU_DEFAULT) +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION ia64_handle_option + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/iq2000/iq2000-common.c b/gcc/common/config/iq2000/iq2000-common.c new file mode 100644 index 00000000000..4eb32be6148 --- /dev/null +++ b/gcc/common/config/iq2000/iq2000-common.c @@ -0,0 +1,38 @@ +/* Common hooks for Vitesse IQ2000. + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options iq2000_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE iq2000_option_optimization_table + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/lm32/lm32-common.c b/gcc/common/config/lm32/lm32-common.c new file mode 100644 index 00000000000..a8f674dbce2 --- /dev/null +++ b/gcc/common/config/lm32/lm32-common.c @@ -0,0 +1,41 @@ +/* Common hooks for Lattice Mico32. + + Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options lm32_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE lm32_option_optimization_table + +#undef TARGET_EXCEPT_UNWIND_INFO +#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/m32c/m32c-common.c b/gcc/common/config/m32c/m32c-common.c new file mode 100644 index 00000000000..8bda8cd5dfb --- /dev/null +++ b/gcc/common/config/m32c/m32c-common.c @@ -0,0 +1,31 @@ +/* Common hooks for R8C/M16C/M32C. + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" + +#undef TARGET_HAVE_NAMED_SECTIONS +#define TARGET_HAVE_NAMED_SECTIONS true + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/m32r/m32r-common.c b/gcc/common/config/m32r/m32r-common.c new file mode 100644 index 00000000000..99dca2d2035 --- /dev/null +++ b/gcc/common/config/m32r/m32r-common.c @@ -0,0 +1,76 @@ +/* Common hooks for Renesas M32R. + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, + 2005, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +static const struct default_options m32r_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_1_PLUS, OPT_fregmove, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +/* Implement TARGET_HANDLE_OPTION. */ + +static bool +m32r_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc ATTRIBUTE_UNUSED) +{ + size_t code = decoded->opt_index; + int value = decoded->value; + + switch (code) + { + case OPT_m32r: + opts->x_target_flags &= ~(MASK_M32R2 | MASK_M32RX); + return true; + + case OPT_mno_flush_func: + opts->x_m32r_cache_flush_func = NULL; + return true; + + case OPT_mflush_trap_: + return value <= 15; + + default: + return true; + } +} + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS TARGET_CPU_DEFAULT +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION m32r_handle_option +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE m32r_option_optimization_table + +#undef TARGET_EXCEPT_UNWIND_INFO +#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/m68k/m68k-common.c b/gcc/common/config/m68k/m68k-common.c new file mode 100644 index 00000000000..3a81b678a24 --- /dev/null +++ b/gcc/common/config/m68k/m68k-common.c @@ -0,0 +1,76 @@ +/* Common hooks for Motorola 68000 family. + Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "diagnostic-core.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Implement TARGET_HANDLE_OPTION. */ + +static bool +m68k_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc) +{ + size_t code = decoded->opt_index; + const char *arg = decoded->arg; + int value = decoded->value; + + switch (code) + { + case OPT_m68020_40: + opts->x_m68k_tune_option = u68020_40; + opts->x_m68k_cpu_option = m68020; + return true; + + case OPT_m68020_60: + opts->x_m68k_tune_option = u68020_60; + opts->x_m68k_cpu_option = m68020; + return true; + + case OPT_mshared_library_id_: + if (value > MAX_LIBRARY_ID) + error_at (loc, "-mshared-library-id=%s is not between 0 and %d", + arg, MAX_LIBRARY_ID); + else + { + char *tmp; + asprintf (&tmp, "%d", (value * -4) - 4); + opts->x_m68k_library_id_string = tmp; + } + return true; + + default: + return true; + } +} + +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION m68k_handle_option + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/mcore/mcore-common.c b/gcc/common/config/mcore/mcore-common.c new file mode 100644 index 00000000000..66633bfa17c --- /dev/null +++ b/gcc/common/config/mcore/mcore-common.c @@ -0,0 +1,54 @@ +/* Common hooks for Motorola MCore. + Copyright (C) 1993, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, + 2009, 2010, 2011 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" + +/* What options are we going to default to specific settings when + -O* happens; the user can subsequently override these settings. + + Omitting the frame pointer is a very good idea on the MCore. + Scheduling isn't worth anything on the current MCore implementation. */ + +static const struct default_options mcore_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_ffunction_cse, NULL, 0 }, + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_ALL, OPT_fcaller_saves, NULL, 0 }, + { OPT_LEVELS_ALL, OPT_fschedule_insns, NULL, 0 }, + { OPT_LEVELS_ALL, OPT_fschedule_insns2, NULL, 0 }, + { OPT_LEVELS_SIZE, OPT_mhardlit, NULL, 0 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE mcore_option_optimization_table + +#undef TARGET_EXCEPT_UNWIND_INFO +#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/mep/mep-common.c b/gcc/common/config/mep/mep-common.c new file mode 100644 index 00000000000..d15e03b3539 --- /dev/null +++ b/gcc/common/config/mep/mep-common.c @@ -0,0 +1,91 @@ +/* Common hooks for Toshiba Media Processor. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +static const struct default_options mep_option_optimization_table[] = + { + /* The first scheduling pass often increases register pressure and + tends to result in more spill code. Only run it when + specifically asked. */ + { OPT_LEVELS_ALL, OPT_fschedule_insns, NULL, 0 }, + + /* Using $fp doesn't gain us much, even when debugging is + important. */ + { OPT_LEVELS_ALL, OPT_fomit_frame_pointer, NULL, 1 }, + + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +static bool +mep_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc ATTRIBUTE_UNUSED) +{ + size_t code = decoded->opt_index; + + switch (code) + { + case OPT_mall_opts: + opts->x_target_flags |= MEP_ALL_OPTS; + break; + + case OPT_mno_opts: + opts->x_target_flags &= ~ MEP_ALL_OPTS; + break; + + case OPT_mcop64: + opts->x_target_flags |= MASK_COP; + opts->x_target_flags |= MASK_64BIT_CR_REGS; + break; + + case OPT_mivc2: + opts->x_target_flags |= MASK_COP; + opts->x_target_flags |= MASK_64BIT_CR_REGS; + opts->x_target_flags |= MASK_VLIW; + opts->x_target_flags |= MASK_OPT_VL64; + opts->x_target_flags |= MASK_IVC2; + + /* Remaining handling of this option deferred. */ + break; + + default: + break; + } + return TRUE; +} + +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION mep_handle_option +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE mep_option_optimization_table +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/microblaze/microblaze-common.c b/gcc/common/config/microblaze/microblaze-common.c new file mode 100644 index 00000000000..4de1bebb55b --- /dev/null +++ b/gcc/common/config/microblaze/microblaze-common.c @@ -0,0 +1,43 @@ +/* Common hooks for Xilinx MicroBlaze. + Copyright 2009, 2010, 2011 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options microblaze_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE microblaze_option_optimization_table + +#undef TARGET_EXCEPT_UNWIND_INFO +#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/mips/mips-common.c b/gcc/common/config/mips/mips-common.c new file mode 100644 index 00000000000..53a326dcfeb --- /dev/null +++ b/gcc/common/config/mips/mips-common.c @@ -0,0 +1,74 @@ +/* Common hooks for MIPS. + Copyright (C) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Implement TARGET_HANDLE_OPTION. */ + +static bool +mips_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc ATTRIBUTE_UNUSED) +{ + size_t code = decoded->opt_index; + + switch (code) + { + case OPT_mno_flush_func: + opts->x_mips_cache_flush_func = NULL; + return true; + + default: + return true; + } +} + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options mips_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE mips_option_optimization_table + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS \ + (TARGET_DEFAULT \ + | TARGET_CPU_DEFAULT \ + | TARGET_ENDIAN_DEFAULT \ + | TARGET_FP_EXCEPTIONS_DEFAULT \ + | MASK_CHECK_ZERO_DIV \ + | MASK_FUSED_MADD) +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION mips_handle_option + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/mmix/mmix-common.c b/gcc/common/config/mmix/mmix-common.c new file mode 100644 index 00000000000..d73ca6d132d --- /dev/null +++ b/gcc/common/config/mmix/mmix-common.c @@ -0,0 +1,44 @@ +/* Common hooks for MMIX. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, + 2010, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" + +/* TARGET_OPTION_OPTIMIZATION_TABLE. */ + +static const struct default_options mmix_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fregmove, NULL, 1 }, + { OPT_LEVELS_2_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE mmix_option_optimization_table + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/mn10300/mn10300-common.c b/gcc/common/config/mn10300/mn10300-common.c new file mode 100644 index 00000000000..312f0ebf03e --- /dev/null +++ b/gcc/common/config/mn10300/mn10300-common.c @@ -0,0 +1,79 @@ +/* Common hooks for Matsushita MN10300 series. + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, + 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options mn10300_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +/* Implement TARGET_HANDLE_OPTION. */ + +static bool +mn10300_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc ATTRIBUTE_UNUSED) +{ + size_t code = decoded->opt_index; + int value = decoded->value; + + switch (code) + { + case OPT_mam33: + opts->x_mn10300_processor = value ? PROCESSOR_AM33 : PROCESSOR_MN10300; + return true; + + case OPT_mam33_2: + opts->x_mn10300_processor = (value + ? PROCESSOR_AM33_2 + : MIN (PROCESSOR_AM33, PROCESSOR_DEFAULT)); + return true; + + case OPT_mam34: + opts->x_mn10300_processor = (value ? PROCESSOR_AM34 : PROCESSOR_DEFAULT); + return true; + + default: + return true; + } +} + +#undef TARGET_EXCEPT_UNWIND_INFO +#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS MASK_MULT_BUG | MASK_PTR_A0D0 | MASK_ALLOW_LIW | MASK_ALLOW_SETLB +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION mn10300_handle_option +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE mn10300_option_optimization_table + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/pa/pa-common.c b/gcc/common/config/pa/pa-common.c new file mode 100644 index 00000000000..faa54ac042f --- /dev/null +++ b/gcc/common/config/pa/pa-common.c @@ -0,0 +1,80 @@ +/* HPPA common hooks. + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options pa_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +/* Implement TARGET_HANDLE_OPTION. */ + +static bool +pa_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc ATTRIBUTE_UNUSED) +{ + size_t code = decoded->opt_index; + + switch (code) + { + case OPT_mnosnake: + case OPT_mpa_risc_1_0: + case OPT_march_1_0: + opts->x_target_flags &= ~(MASK_PA_11 | MASK_PA_20); + return true; + + case OPT_msnake: + case OPT_mpa_risc_1_1: + case OPT_march_1_1: + opts->x_target_flags &= ~MASK_PA_20; + opts->x_target_flags |= MASK_PA_11; + return true; + + case OPT_mpa_risc_2_0: + case OPT_march_2_0: + opts->x_target_flags |= MASK_PA_11 | MASK_PA_20; + return true; + + default: + return true; + } +} + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE pa_option_optimization_table +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | TARGET_CPU_DEFAULT) +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION pa_handle_option + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/pdp11/pdp11-common.c b/gcc/common/config/pdp11/pdp11-common.c new file mode 100644 index 00000000000..a288a8ef53a --- /dev/null +++ b/gcc/common/config/pdp11/pdp11-common.c @@ -0,0 +1,79 @@ +/* Common hooks for pdp11. + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2004, 2005, + 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ + +static const struct default_options pdp11_option_optimization_table[] = + { + { OPT_LEVELS_3_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +/* Implement TARGET_HANDLE_OPTION. */ + +static bool +pdp11_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc ATTRIBUTE_UNUSED) +{ + size_t code = decoded->opt_index; + + switch (code) + { + case OPT_m10: + opts->x_target_flags &= ~(MASK_40 | MASK_45); + return true; + + default: + return true; + } +} + +/* Implement TARGET_OPTION_INIT_STRUCT. */ + +static void +pdp11_option_init_struct (struct gcc_options *opts) +{ + opts->x_flag_finite_math_only = 0; + opts->x_flag_trapping_math = 0; + opts->x_flag_signaling_nans = 0; +} + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS \ + (MASK_FPU | MASK_45 | TARGET_UNIX_ASM_DEFAULT) +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION pdp11_handle_option +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE pdp11_option_optimization_table +#undef TARGET_OPTION_INIT_STRUCT +#define TARGET_OPTION_INIT_STRUCT pdp11_option_init_struct + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/picochip/picochip-common.c b/gcc/common/config/picochip/picochip-common.c new file mode 100644 index 00000000000..286ee452076 --- /dev/null +++ b/gcc/common/config/picochip/picochip-common.c @@ -0,0 +1,43 @@ +/* Common hooks for picoChip. + Copyright (C) 2001, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options picochip_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_HAVE_NAMED_SECTIONS +#define TARGET_HAVE_NAMED_SECTIONS 1 + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE picochip_option_optimization_table + +#undef TARGET_EXCEPT_UNWIND_INFO +#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/rs6000/rs6000-common.c b/gcc/common/config/rs6000/rs6000-common.c new file mode 100644 index 00000000000..0482c07d7a9 --- /dev/null +++ b/gcc/common/config/rs6000/rs6000-common.c @@ -0,0 +1,326 @@ +/* Common hooks for IBM RS/6000. + Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "diagnostic-core.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options rs6000_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +/* Implement TARGET_OPTION_INIT_STRUCT. */ + +static void +rs6000_option_init_struct (struct gcc_options *opts) +{ + if (DEFAULT_ABI == ABI_DARWIN) + /* The Darwin libraries never set errno, so we might as well + avoid calling them when that's the only reason we would. */ + opts->x_flag_errno_math = 0; + + /* Enable section anchors by default. */ + if (!TARGET_MACHO) + opts->x_flag_section_anchors = 1; +} + +/* If not otherwise specified by a target, make 'long double' equivalent to + 'double'. */ + +#ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE +#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64 +#endif + +/* Implement TARGET_HANDLE_OPTION. */ + +static bool +rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set, + const struct cl_decoded_option *decoded, + location_t loc) +{ + enum fpu_type_t fpu_type = FPU_NONE; + char *p, *q; + size_t code = decoded->opt_index; + const char *arg = decoded->arg; + int value = decoded->value; + + switch (code) + { + case OPT_mno_power: + opts->x_target_flags &= ~(MASK_POWER | MASK_POWER2 + | MASK_MULTIPLE | MASK_STRING); + opts_set->x_target_flags |= (MASK_POWER | MASK_POWER2 + | MASK_MULTIPLE | MASK_STRING); + break; + case OPT_mno_powerpc: + opts->x_target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT + | MASK_PPC_GFXOPT | MASK_POWERPC64); + opts_set->x_target_flags |= (MASK_POWERPC | MASK_PPC_GPOPT + | MASK_PPC_GFXOPT | MASK_POWERPC64); + break; + case OPT_mfull_toc: + opts->x_target_flags &= ~MASK_MINIMAL_TOC; + opts->x_TARGET_NO_FP_IN_TOC = 0; + opts->x_TARGET_NO_SUM_IN_TOC = 0; + opts_set->x_target_flags |= MASK_MINIMAL_TOC; +#ifdef TARGET_USES_SYSV4_OPT + /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be + just the same as -mminimal-toc. */ + opts->x_target_flags |= MASK_MINIMAL_TOC; + opts_set->x_target_flags |= MASK_MINIMAL_TOC; +#endif + break; + +#ifdef TARGET_USES_SYSV4_OPT + case OPT_mtoc: + /* Make -mtoc behave like -mminimal-toc. */ + opts->x_target_flags |= MASK_MINIMAL_TOC; + opts_set->x_target_flags |= MASK_MINIMAL_TOC; + break; +#endif + +#ifdef TARGET_USES_AIX64_OPT + case OPT_maix64: +#else + case OPT_m64: +#endif + opts->x_target_flags |= MASK_POWERPC64 | MASK_POWERPC; + opts->x_target_flags |= ~opts_set->x_target_flags & MASK_PPC_GFXOPT; + opts_set->x_target_flags |= MASK_POWERPC64 | MASK_POWERPC; + break; + +#ifdef TARGET_USES_AIX64_OPT + case OPT_maix32: +#else + case OPT_m32: +#endif + opts->x_target_flags &= ~MASK_POWERPC64; + opts_set->x_target_flags |= MASK_POWERPC64; + break; + + case OPT_mminimal_toc: + if (value == 1) + { + opts->x_TARGET_NO_FP_IN_TOC = 0; + opts->x_TARGET_NO_SUM_IN_TOC = 0; + } + break; + + case OPT_mpower: + if (value == 1) + { + opts->x_target_flags |= (MASK_MULTIPLE | MASK_STRING); + opts_set->x_target_flags |= (MASK_MULTIPLE | MASK_STRING); + } + break; + + case OPT_mpower2: + if (value == 1) + { + opts->x_target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING); + opts_set->x_target_flags |= (MASK_POWER + | MASK_MULTIPLE + | MASK_STRING); + } + break; + + case OPT_mpowerpc_gpopt: + case OPT_mpowerpc_gfxopt: + if (value == 1) + { + opts->x_target_flags |= MASK_POWERPC; + opts_set->x_target_flags |= MASK_POWERPC; + } + break; + + case OPT_mdebug_: + p = ASTRDUP (arg); + opts->x_rs6000_debug = 0; + + while ((q = strtok (p, ",")) != NULL) + { + unsigned mask = 0; + bool invert; + + p = NULL; + if (*q == '!') + { + invert = true; + q++; + } + else + invert = false; + + if (! strcmp (q, "all")) + mask = MASK_DEBUG_ALL; + else if (! strcmp (q, "stack")) + mask = MASK_DEBUG_STACK; + else if (! strcmp (q, "arg")) + mask = MASK_DEBUG_ARG; + else if (! strcmp (q, "reg")) + mask = MASK_DEBUG_REG; + else if (! strcmp (q, "addr")) + mask = MASK_DEBUG_ADDR; + else if (! strcmp (q, "cost")) + mask = MASK_DEBUG_COST; + else if (! strcmp (q, "target")) + mask = MASK_DEBUG_TARGET; + else + error_at (loc, "unknown -mdebug-%s switch", q); + + if (invert) + opts->x_rs6000_debug &= ~mask; + else + opts->x_rs6000_debug |= mask; + } + break; + +#ifdef TARGET_USES_SYSV4_OPT + case OPT_mrelocatable: + if (value == 1) + { + opts->x_target_flags |= MASK_MINIMAL_TOC; + opts_set->x_target_flags |= MASK_MINIMAL_TOC; + opts->x_TARGET_NO_FP_IN_TOC = 1; + } + break; + + case OPT_mrelocatable_lib: + if (value == 1) + { + opts->x_target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC; + opts_set->x_target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC; + opts->x_TARGET_NO_FP_IN_TOC = 1; + } + else + { + opts->x_target_flags &= ~MASK_RELOCATABLE; + opts_set->x_target_flags |= MASK_RELOCATABLE; + } + break; +#endif + + case OPT_mabi_altivec: + /* Enabling the AltiVec ABI turns off the SPE ABI. */ + opts->x_rs6000_spe_abi = 0; + break; + + case OPT_mabi_spe: + opts->x_rs6000_altivec_abi = 0; + break; + + case OPT_mlong_double_: + if (value != 64 && value != 128) + { + error_at (loc, "unknown switch -mlong-double-%s", arg); + opts->x_rs6000_long_double_type_size + = RS6000_DEFAULT_LONG_DOUBLE_SIZE; + return false; + } + break; + + case OPT_msingle_float: + if (!TARGET_SINGLE_FPU) + warning_at (loc, 0, + "-msingle-float option equivalent to -mhard-float"); + /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */ + opts->x_rs6000_double_float = 0; + opts->x_target_flags &= ~MASK_SOFT_FLOAT; + opts_set->x_target_flags |= MASK_SOFT_FLOAT; + break; + + case OPT_mdouble_float: + /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */ + opts->x_rs6000_single_float = 1; + opts->x_target_flags &= ~MASK_SOFT_FLOAT; + opts_set->x_target_flags |= MASK_SOFT_FLOAT; + break; + + case OPT_msimple_fpu: + if (!TARGET_SINGLE_FPU) + warning_at (loc, 0, "-msimple-fpu option ignored"); + break; + + case OPT_mhard_float: + /* -mhard_float implies -msingle-float and -mdouble-float. */ + opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1; + break; + + case OPT_msoft_float: + /* -msoft_float implies -mnosingle-float and -mnodouble-float. */ + opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0; + break; + + case OPT_mfpu_: + fpu_type = (enum fpu_type_t) value; + if (fpu_type != FPU_NONE) + { + /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on + HARD_FLOAT. */ + opts->x_target_flags &= ~MASK_SOFT_FLOAT; + opts_set->x_target_flags |= MASK_SOFT_FLOAT; + opts->x_rs6000_xilinx_fpu = 1; + if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL) + opts->x_rs6000_single_float = 1; + if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL) + opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1; + if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE) + opts->x_rs6000_simple_fpu = 1; + } + else + { + /* -mfpu=none is equivalent to -msoft-float. */ + opts->x_target_flags |= MASK_SOFT_FLOAT; + opts_set->x_target_flags |= MASK_SOFT_FLOAT; + opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0; + } + break; + + case OPT_mrecip: + opts->x_rs6000_recip_name = (value) ? "default" : "none"; + break; + } + return true; +} + +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION rs6000_handle_option + +#undef TARGET_OPTION_INIT_STRUCT +#define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS \ + (TARGET_DEFAULT) + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/rx/rx-common.c b/gcc/common/config/rx/rx-common.c new file mode 100644 index 00000000000..259f9bb4f6e --- /dev/null +++ b/gcc/common/config/rx/rx-common.c @@ -0,0 +1,86 @@ +/* Common hooks for Renesas RX. + Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "diagnostic-core.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Extra processing for target specific command line options. */ + +static bool +rx_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc) +{ + size_t code = decoded->opt_index; + int value = decoded->value; + + switch (code) + { + case OPT_mint_register_: + /* Make sure that the -mint-register option is in range. Other + handling in rx_option_override. */ + return value >= 0 && value <= 4; + break; + + case OPT_mmax_constant_size_: + /* Make sure that the -mmax-constant_size option is in range. */ + return value >= 0 && value <= 4; + + case OPT_mcpu_: + if ((enum rx_cpu_types) value == RX200) + opts->x_target_flags |= MASK_NO_USE_FPU; + break; + + case OPT_fpu: + if (opts->x_rx_cpu_type == RX200) + error_at (loc, "the RX200 cpu does not have FPU hardware"); + break; + + default: + break; + } + + return true; +} + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options rx_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION rx_handle_option + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE rx_option_optimization_table + +#undef TARGET_EXCEPT_UNWIND_INFO +#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/s390/s390-common.c b/gcc/common/config/s390/s390-common.c new file mode 100644 index 00000000000..98b5c283aaa --- /dev/null +++ b/gcc/common/config/s390/s390-common.c @@ -0,0 +1,127 @@ +/* Common hooks for IBM S/390 and zSeries. + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "diagnostic-core.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +EXPORTED_CONST int processor_flags_table[] = + { + /* g5 */ PF_IEEE_FLOAT, + /* g6 */ PF_IEEE_FLOAT, + /* z900 */ PF_IEEE_FLOAT | PF_ZARCH, + /* z990 */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT, + /* z9-109 */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT + | PF_EXTIMM, + /* z9-ec */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT + | PF_EXTIMM | PF_DFP, + /* z10 */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT + | PF_EXTIMM | PF_DFP | PF_Z10, + /* z196 */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT + | PF_EXTIMM | PF_DFP | PF_Z10 | PF_Z196 + }; + +/* Change optimizations to be performed, depending on the + optimization level. */ + +static const struct default_options s390_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + + /* ??? There are apparently still problems with -fcaller-saves. */ + { OPT_LEVELS_ALL, OPT_fcaller_saves, NULL, 0 }, + + /* Use MVCLE instructions to decrease code size if requested. */ + { OPT_LEVELS_SIZE, OPT_mmvcle, NULL, 1 }, + + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +/* Implement TARGET_OPTION_INIT_STRUCT. */ + +static void +s390_option_init_struct (struct gcc_options *opts) +{ + /* By default, always emit DWARF-2 unwind info. This allows debugging + without maintaining a stack frame back-chain. */ + opts->x_flag_asynchronous_unwind_tables = 1; +} + +/* Implement TARGET_HANDLE_OPTION. */ + +static bool +s390_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc) +{ + size_t code = decoded->opt_index; + const char *arg = decoded->arg; + int value = decoded->value; + + switch (code) + { + case OPT_march_: + opts->x_s390_arch_flags = processor_flags_table[value]; + opts->x_s390_arch_string = arg; + return true; + + case OPT_mstack_guard_: + if (exact_log2 (value) == -1) + error_at (loc, "stack guard value must be an exact power of 2"); + return true; + + case OPT_mstack_size_: + if (exact_log2 (value) == -1) + error_at (loc, "stack size must be an exact power of 2"); + return true; + + case OPT_mtune_: + opts->x_s390_tune_flags = processor_flags_table[value]; + return true; + + case OPT_mwarn_framesize_: + return sscanf (arg, HOST_WIDE_INT_PRINT_DEC, + &opts->x_s390_warn_framesize) == 1; + + default: + return true; + } +} + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT) + +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION s390_handle_option + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE s390_option_optimization_table + +#undef TARGET_OPTION_INIT_STRUCT +#define TARGET_OPTION_INIT_STRUCT s390_option_init_struct + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/score/score-common.c b/gcc/common/config/score/score-common.c new file mode 100644 index 00000000000..756e5b312e1 --- /dev/null +++ b/gcc/common/config/score/score-common.c @@ -0,0 +1,75 @@ +/* Common hooks for Sunplus S+CORE. + Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options score_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT + +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION score_handle_option + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE score_option_optimization_table + +#define MASK_ALL_CPU_BITS (MASK_SCORE7 | MASK_SCORE7D) + +/* Implement TARGET_HANDLE_OPTION. */ +static bool +score_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc ATTRIBUTE_UNUSED) +{ + size_t code = decoded->opt_index; + int value = decoded->value; + + switch (code) + { + case OPT_mscore7d: + opts->x_target_flags &= ~(MASK_ALL_CPU_BITS); + opts->x_target_flags |= MASK_SCORE7 | MASK_SCORE7D; + return true; + + case OPT_march_: + opts->x_target_flags &= ~(MASK_ALL_CPU_BITS); + opts->x_target_flags |= value; + return true; + + default: + return true; + } +} + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/sh/sh-common.c b/gcc/common/config/sh/sh-common.c new file mode 100644 index 00000000000..8677fd49174 --- /dev/null +++ b/gcc/common/config/sh/sh-common.c @@ -0,0 +1,208 @@ +/* Common hooks for Renesas / SuperH SH. + Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, + 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Set default optimization options. */ +static const struct default_options sh_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_1_PLUS_SPEED_ONLY, OPT_mdiv_, "inv:minlat", 1 }, + { OPT_LEVELS_SIZE, OPT_mdiv_, SH_DIV_STR_FOR_SIZE, 1 }, + { OPT_LEVELS_0_ONLY, OPT_mdiv_, "", 1 }, + { OPT_LEVELS_SIZE, OPT_mcbranchdi, NULL, 0 }, + /* We can't meaningfully test TARGET_SHMEDIA here, because -m + options haven't been parsed yet, hence we'd read only the + default. sh_target_reg_class will return NO_REGS if this is + not SHMEDIA, so it's OK to always set + flag_branch_target_load_optimize. */ + { OPT_LEVELS_2_PLUS, OPT_fbranch_target_load_optimize, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +/* Implement TARGET_HANDLE_OPTION. */ + +static bool +sh_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc ATTRIBUTE_UNUSED) +{ + size_t code = decoded->opt_index; + + switch (code) + { + case OPT_m1: + opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH1; + return true; + + case OPT_m2: + opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH2; + return true; + + case OPT_m2a: + opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH2A; + return true; + + case OPT_m2a_nofpu: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH2A_NOFPU; + return true; + + case OPT_m2a_single: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH2A_SINGLE; + return true; + + case OPT_m2a_single_only: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH2A_SINGLE_ONLY; + return true; + + case OPT_m2e: + opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH2E; + return true; + + case OPT_m3: + opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH3; + return true; + + case OPT_m3e: + opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH3E; + return true; + + case OPT_m4: + case OPT_m4_100: + case OPT_m4_200: + case OPT_m4_300: + opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4; + return true; + + case OPT_m4_nofpu: + case OPT_m4_100_nofpu: + case OPT_m4_200_nofpu: + case OPT_m4_300_nofpu: + case OPT_m4_340: + case OPT_m4_400: + case OPT_m4_500: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4_NOFPU; + return true; + + case OPT_m4_single: + case OPT_m4_100_single: + case OPT_m4_200_single: + case OPT_m4_300_single: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4_SINGLE; + return true; + + case OPT_m4_single_only: + case OPT_m4_100_single_only: + case OPT_m4_200_single_only: + case OPT_m4_300_single_only: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4_SINGLE_ONLY; + return true; + + case OPT_m4a: + opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4A; + return true; + + case OPT_m4a_nofpu: + case OPT_m4al: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4A_NOFPU; + return true; + + case OPT_m4a_single: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4A_SINGLE; + return true; + + case OPT_m4a_single_only: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4A_SINGLE_ONLY; + return true; + + case OPT_m5_32media: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH5_32MEDIA; + return true; + + case OPT_m5_32media_nofpu: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH5_32MEDIA_NOFPU; + return true; + + case OPT_m5_64media: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH5_64MEDIA; + return true; + + case OPT_m5_64media_nofpu: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH5_64MEDIA_NOFPU; + return true; + + case OPT_m5_compact: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH5_COMPACT; + return true; + + case OPT_m5_compact_nofpu: + opts->x_target_flags + = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH5_COMPACT_NOFPU; + return true; + + default: + return true; + } +} + +/* Implement TARGET_OPTION_INIT_STRUCT. */ +static void +sh_option_init_struct (struct gcc_options *opts) +{ + /* We can't meaningfully test TARGET_SH2E / TARGET_IEEE + here, so leave it to TARGET_OPTION_OVERRIDE to set + flag_finite_math_only. We set it to 2 here so we know if the user + explicitly requested this to be on or off. */ + opts->x_flag_finite_math_only = 2; +} + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE sh_option_optimization_table +#undef TARGET_OPTION_INIT_STRUCT +#define TARGET_OPTION_INIT_STRUCT sh_option_init_struct +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION sh_handle_option + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/sparc/sparc-common.c b/gcc/common/config/sparc/sparc-common.c new file mode 100644 index 00000000000..fe2ee6d2dbe --- /dev/null +++ b/gcc/common/config/sparc/sparc-common.c @@ -0,0 +1,42 @@ +/* Common hooks for SPARC. + Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options sparc_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE sparc_option_optimization_table + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/spu/spu-common.c b/gcc/common/config/spu/spu-common.c new file mode 100644 index 00000000000..d4a9f3c7cd9 --- /dev/null +++ b/gcc/common/config/spu/spu-common.c @@ -0,0 +1,44 @@ +/* Common hooks for SPU. + Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + + This file is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) + any later version. + + This file is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +static void +spu_option_init_struct (struct gcc_options *opts) +{ + /* With so many registers this is better on by default. */ + opts->x_flag_rename_registers = 1; +} + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT) + +#undef TARGET_OPTION_INIT_STRUCT +#define TARGET_OPTION_INIT_STRUCT spu_option_init_struct + +#undef TARGET_EXCEPT_UNWIND_INFO +#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/v850/v850-common.c b/gcc/common/config/v850/v850-common.c new file mode 100644 index 00000000000..0e2d81760ea --- /dev/null +++ b/gcc/common/config/v850/v850-common.c @@ -0,0 +1,133 @@ +/* Common hooks for NEC V850 series. + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "diagnostic-core.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" + +/* Information about the various small memory areas. */ +static const int small_memory_physical_max[(int) SMALL_MEMORY_max] = +{ + 256, + 65536, + 32768, +}; + +/* Set the maximum size of small memory area TYPE to the value given + by SIZE in structure OPTS (option text OPT passed at location LOC). */ + +static void +v850_handle_memory_option (enum small_memory_type type, + struct gcc_options *opts, const char *opt, + int size, location_t loc) +{ + if (size > small_memory_physical_max[type]) + error_at (loc, "value passed in %qs is too large", opt); + else + opts->x_small_memory_max[type] = size; +} + +/* Implement TARGET_HANDLE_OPTION. */ + +static bool +v850_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc) +{ + size_t code = decoded->opt_index; + int value = decoded->value; + + switch (code) + { + case OPT_mspace: + opts->x_target_flags |= MASK_EP | MASK_PROLOG_FUNCTION; + return true; + + case OPT_mv850: + opts->x_target_flags &= ~(MASK_CPU ^ MASK_V850); + return true; + + case OPT_mv850e: + case OPT_mv850e1: + case OPT_mv850es: + opts->x_target_flags &= ~(MASK_CPU ^ MASK_V850E); + return true; + + case OPT_mv850e2: + opts->x_target_flags &= ~(MASK_CPU ^ MASK_V850E2); + return true; + + case OPT_mv850e2v3: + opts->x_target_flags &= ~(MASK_CPU ^ MASK_V850E2V3); + return true; + + case OPT_mtda_: + v850_handle_memory_option (SMALL_MEMORY_TDA, opts, + decoded->orig_option_with_args_text, + value, loc); + return true; + + case OPT_msda_: + v850_handle_memory_option (SMALL_MEMORY_SDA, opts, + decoded->orig_option_with_args_text, + value, loc); + return true; + + case OPT_mzda_: + v850_handle_memory_option (SMALL_MEMORY_ZDA, opts, + decoded->orig_option_with_args_text, + value, loc); + return true; + + default: + return true; + } +} + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ + +static const struct default_options v850_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + /* Note - we no longer enable MASK_EP when optimizing. This is + because of a hardware bug which stops the SLD and SST instructions + from correctly detecting some hazards. If the user is sure that + their hardware is fixed or that their program will not encounter + the conditions that trigger the bug then they can enable -mep by + hand. */ + { OPT_LEVELS_1_PLUS, OPT_mprolog_function, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS (MASK_DEFAULT | MASK_APP_REGS) +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION v850_handle_option +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE v850_option_optimization_table + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/vax/vax-common.c b/gcc/common/config/vax/vax-common.c new file mode 100644 index 00000000000..11b1a4e833a --- /dev/null +++ b/gcc/common/config/vax/vax-common.c @@ -0,0 +1,32 @@ +/* Common hooks for VAX. + Copyright (C) 1987, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, + 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/xstormy16/xstormy16-common.c b/gcc/common/config/xstormy16/xstormy16-common.c new file mode 100644 index 00000000000..23850c205ba --- /dev/null +++ b/gcc/common/config/xstormy16/xstormy16-common.c @@ -0,0 +1,38 @@ +/* Common hooks for Xstormy16. + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options xstorym16_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE xstorym16_option_optimization_table + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/common/config/xtensa/xtensa-common.c b/gcc/common/config/xtensa/xtensa-common.c new file mode 100644 index 00000000000..4770f45c1ab --- /dev/null +++ b/gcc/common/config/xtensa/xtensa-common.c @@ -0,0 +1,47 @@ +/* Common hooks for Tensilica's Xtensa architecture. + Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ + +static const struct default_options xtensa_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + /* Reordering blocks for Xtensa is not a good idea unless the + compiler understands the range of conditional branches. + Currently all branch relaxation for Xtensa is handled in the + assembler, so GCC cannot do a good job of reordering blocks. + Do not enable reordering unless it is explicitly requested. */ + { OPT_LEVELS_ALL, OPT_freorder_blocks, NULL, 0 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT) +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE xtensa_option_optimization_table + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/compare-elim.c b/gcc/compare-elim.c index c3eecfa280b..e5b2088292e 100644 --- a/gcc/compare-elim.c +++ b/gcc/compare-elim.c @@ -636,7 +636,6 @@ struct rtl_opt_pass pass_compare_elim_after_reload = TODO_df_finish | TODO_df_verify | TODO_verify_rtl_sharing - | TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } }; diff --git a/gcc/config.gcc b/gcc/config.gcc index 5d88d1bf60d..2cf92d2fefb 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -96,6 +96,9 @@ # out_file The name of the machine description C support # file, if different from "$cpu_type/$cpu_type.c". # +# common_out_file The name of the source file for code shared between +# the compiler proper and the driver. +# # md_file The name of the machine-description file, if # different from "$cpu_type/$cpu_type.md". # @@ -192,8 +195,12 @@ # # target_has_targetcm Set to yes or no depending on whether the target # has its own definition of targetcm. +# +# target_has_targetm_common Set to yes or no depending on whether the +# target has its own definition of targetm_common. out_file= +common_out_file= tmake_file= extra_headers= user_headers_inc_next_pre= @@ -210,6 +217,7 @@ c_target_objs= cxx_target_objs= fortran_target_objs= target_has_targetcm=no +target_has_targetm_common=yes tm_defines= xm_defines= libgcc_tm_file= @@ -321,6 +329,7 @@ frv*) cpu_type=frv extra_options="${extra_options} g.opt" ;; moxie*) cpu_type=moxie + target_has_targetm_common=no ;; fido-*-*) cpu_type=m68k @@ -421,6 +430,9 @@ sh[123456789lbe]*-*-* | sh-*-*) cpu_type=sh need_64bit_hwint=yes ;; +v850*-*-*) + cpu_type=v850 + ;; xtensa*-*-*) extra_options="${extra_options} fused-madd.opt" ;; @@ -1267,7 +1279,7 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu | x86_64-*-knetbsd*-gnu) x86_64-*-linux*) tm_file="${tm_file} linux.h i386/linux64.h" default_gnu_indirect_function=glibc-2011 ;; - x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h i386/kfreebsd-gnu.h" ;; + x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h i386/kfreebsd-gnu64.h" ;; x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;; esac tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules" @@ -2579,12 +2591,6 @@ v850*-*-*) ;; esac tm_file="dbxelf.h elfos.h newlib-stdint.h v850/v850.h" - tm_p_file=v850/v850-protos.h - tmake_file=v850/t-v850 - md_file=v850/v850.md - extra_modes=v850/v850-modes.def - out_file=v850/v850.c - extra_options="${extra_options} v850/v850.opt" if test x$stabs = xyes then tm_file="${tm_file} dbx.h" @@ -2667,6 +2673,14 @@ if [ "$target_has_targetcm" = "no" ]; then cxx_target_objs="$cxx_target_objs default-c.o" fi +if [ "$common_out_file" = "" ]; then + if [ "$target_has_targetm_common" = "yes" ]; then + common_out_file="$cpu_type/$cpu_type-common.c" + else + common_out_file="default-common.c" + fi +fi + # Support for --with-cpu and related options (and a few unrelated options, # too). case ${with_cpu} in diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index adef2c639ea..ffe9fc0bce4 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "target.h" #include "target-def.h" +#include "common/common-target.h" #include "debug.h" #include "langhooks.h" #include "splay-tree.h" @@ -199,46 +200,6 @@ static void alpha_write_linkage (FILE *, const char *, tree); static bool vms_valid_pointer_mode (enum machine_mode); #endif -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options alpha_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -alpha_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc) -{ - size_t code = decoded->opt_index; - const char *arg = decoded->arg; - int value = decoded->value; - - switch (code) - { - case OPT_mfp_regs: - if (value == 0) - opts->x_target_flags |= MASK_SOFT_FP; - break; - - case OPT_mieee: - case OPT_mieee_with_inexact: - opts->x_target_flags |= MASK_IEEE_CONFORMANT; - break; - - case OPT_mtls_size_: - if (value != 16 && value != 32 && value != 64) - error_at (loc, "bad value %qs for -mtls-size switch", arg); - break; - } - - return true; -} - #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING /* Implement TARGET_MANGLE_TYPE. */ @@ -5419,9 +5380,10 @@ alpha_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) and the rest are pushed. */ static rtx -alpha_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +alpha_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int basereg; int num_args; @@ -5480,9 +5442,10 @@ alpha_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, (TYPE is null for libcalls where that information may not be available.) */ static void -alpha_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +alpha_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); bool onstack = targetm.calls.must_pass_in_stack (mode, type); int increment = onstack ? 6 : ALPHA_ARG_SIZE (mode, type, named); @@ -5496,12 +5459,13 @@ alpha_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, } static int -alpha_arg_partial_bytes (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +alpha_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { int words = 0; + CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED = get_cumulative_args (cum_v); #if TARGET_ABI_OPEN_VMS if (cum->num_args < 6 @@ -5576,7 +5540,7 @@ alpha_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED) /* Return true if TYPE should be passed by invisible reference. */ static bool -alpha_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, +alpha_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) @@ -5914,13 +5878,14 @@ escapes: variable number of arguments. */ static void -alpha_setup_incoming_varargs (CUMULATIVE_ARGS *pcum, enum machine_mode mode, +alpha_setup_incoming_varargs (cumulative_args_t pcum, enum machine_mode mode, tree type, int *pretend_size, int no_rtl) { - CUMULATIVE_ARGS cum = *pcum; + CUMULATIVE_ARGS cum = *get_cumulative_args (pcum); /* Skip the current argument. */ - targetm.calls.function_arg_advance (&cum, mode, type, true); + targetm.calls.function_arg_advance (pack_cumulative_args (&cum), mode, type, + true); #if TARGET_ABI_OPEN_VMS /* For VMS, we allocate space for all 6 arg registers plus a count. @@ -9932,18 +9897,9 @@ alpha_conditional_register_usage (void) #undef TARGET_RELAXED_ORDERING #define TARGET_RELAXED_ORDERING true -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS \ - (TARGET_DEFAULT | TARGET_CPU_DEFAULT | TARGET_DEFAULT_EXPLICIT_RELOCS) -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION alpha_handle_option - #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE alpha_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE alpha_option_optimization_table - #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING #undef TARGET_MANGLE_TYPE #define TARGET_MANGLE_TYPE alpha_mangle_type diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 9132b6d0910..2fd75fb3bd6 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -23,6 +23,7 @@ #ifndef GCC_ARM_PROTOS_H #define GCC_ARM_PROTOS_H +extern enum unwind_info_type arm_except_unwind_info (struct gcc_options *); extern int use_return_insn (int, rtx); extern enum reg_class arm_regno_class (int); extern void arm_load_pic_register (unsigned long); @@ -153,9 +154,6 @@ extern const char *arm_output_memory_barrier (rtx *); extern const char *arm_output_sync_insn (rtx, rtx *); extern unsigned int arm_sync_loop_insns (rtx , rtx *); extern int arm_attr_length_push_multi(rtx, rtx); -extern bool arm_check_ldrd_operands (rtx, rtx, rtx, rtx); -extern bool arm_legitimate_ldrd_p (rtx, rtx, rtx, rtx, bool); -extern int arm_output_ldrd (rtx, rtx, rtx, rtx, rtx, bool); #if defined TREE_CODE extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index efc2bcb1ee5..547acc8f926 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -166,11 +166,11 @@ static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int); static tree arm_builtin_decl (unsigned, bool); static void emit_constant_insn (rtx cond, rtx pattern); static rtx emit_set_insn (rtx, rtx); -static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, +static int arm_arg_partial_bytes (cumulative_args_t, enum machine_mode, tree, bool); -static rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx arm_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static void arm_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void arm_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); static unsigned int arm_function_arg_boundary (enum machine_mode, const_tree); static rtx aapcs_allocate_return_reg (enum machine_mode, const_tree, @@ -188,9 +188,9 @@ static void arm_encode_section_info (tree, rtx, int); static void arm_file_end (void); static void arm_file_start (void); -static void arm_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, +static void arm_setup_incoming_varargs (cumulative_args_t, enum machine_mode, tree, int *, int); -static bool arm_pass_by_reference (CUMULATIVE_ARGS *, +static bool arm_pass_by_reference (cumulative_args_t, enum machine_mode, const_tree, bool); static bool arm_promote_prototypes (const_tree); static bool arm_default_short_enums (void); @@ -204,7 +204,6 @@ static bool arm_output_ttype (rtx); static void arm_asm_emit_except_personality (rtx); static void arm_asm_init_sections (void); #endif -static enum unwind_info_type arm_except_unwind_info (struct gcc_options *); static void arm_dwarf_handle_frame_unspec (const char *, rtx, int); static rtx arm_dwarf_register_span (rtx); @@ -303,15 +302,6 @@ static const struct attribute_spec arm_attribute_table[] = #endif { NULL, 0, 0, false, false, false, NULL, false } }; - -/* Set default optimization options. */ -static const struct default_options arm_option_optimization_table[] = - { - /* Enable section anchors by default at -O1 or higher. */ - { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 }, - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; /* Initialize the GCC target structure. */ #if TARGET_DLLIMPORT_DECL_ATTRIBUTES @@ -351,12 +341,8 @@ static const struct default_options arm_option_optimization_table[] = #undef TARGET_ASM_FUNCTION_EPILOGUE #define TARGET_ASM_FUNCTION_EPILOGUE arm_output_function_epilogue -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_SCHED_PROLOG) #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE arm_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE arm_option_optimization_table #undef TARGET_COMP_TYPE_ATTRIBUTES #define TARGET_COMP_TYPE_ATTRIBUTES arm_comp_type_attributes @@ -516,9 +502,6 @@ static const struct default_options arm_option_optimization_table[] = #define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections #endif /* ARM_UNWIND_INFO */ -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO arm_except_unwind_info - #undef TARGET_DWARF_HANDLE_FRAME_UNSPEC #define TARGET_DWARF_HANDLE_FRAME_UNSPEC arm_dwarf_handle_frame_unspec @@ -4406,9 +4389,10 @@ arm_needs_doubleword_align (enum machine_mode mode, const_tree type) indeed make it pass in the stack if necessary). */ static rtx -arm_function_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode, +arm_function_arg (cumulative_args_t pcum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v); int nregs; /* Handle the special case quickly. Pick an arbitrary value for op2 of @@ -4466,9 +4450,10 @@ arm_function_arg_boundary (enum machine_mode mode, const_tree type) } static int -arm_arg_partial_bytes (CUMULATIVE_ARGS *pcum, enum machine_mode mode, +arm_arg_partial_bytes (cumulative_args_t pcum_v, enum machine_mode mode, tree type, bool named) { + CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v); int nregs = pcum->nregs; if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL) @@ -4493,9 +4478,11 @@ arm_arg_partial_bytes (CUMULATIVE_ARGS *pcum, enum machine_mode mode, (TYPE is null for libcalls where that information may not be available.) */ static void -arm_function_arg_advance (CUMULATIVE_ARGS *pcum, enum machine_mode mode, +arm_function_arg_advance (cumulative_args_t pcum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v); + if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL) { aapcs_layout_arg (pcum, mode, type, named); @@ -4529,7 +4516,7 @@ arm_function_arg_advance (CUMULATIVE_ARGS *pcum, enum machine_mode mode, extension to the ARM ABI. */ static bool -arm_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +arm_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type, bool named ATTRIBUTE_UNUSED) { @@ -21950,12 +21937,13 @@ arm_output_load_gr (rtx *operands) that way. */ static void -arm_setup_incoming_varargs (CUMULATIVE_ARGS *pcum, +arm_setup_incoming_varargs (cumulative_args_t pcum_v, enum machine_mode mode, tree type, int *pretend_size, int second_time ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v); int nregs; cfun->machine->uses_anonymous_args = 1; @@ -22848,33 +22836,6 @@ arm_asm_init_sections (void) } #endif /* ARM_UNWIND_INFO */ -/* Implement TARGET_EXCEPT_UNWIND_INFO. */ - -static enum unwind_info_type -arm_except_unwind_info (struct gcc_options *opts) -{ - /* Honor the --enable-sjlj-exceptions configure switch. */ -#ifdef CONFIG_SJLJ_EXCEPTIONS - if (CONFIG_SJLJ_EXCEPTIONS) - return UI_SJLJ; -#endif - - /* If not using ARM EABI unwind tables... */ - if (ARM_UNWIND_INFO) - { - /* For simplicity elsewhere in this file, indicate that all unwind - info is disabled if we're not emitting unwind tables. */ - if (!opts->x_flag_exceptions && !opts->x_flag_unwind_tables) - return UI_NONE; - else - return UI_TARGET; - } - - /* ... we use sjlj exceptions for backwards compatibility. */ - return UI_SJLJ; -} - - /* Handle UNSPEC DWARF call frame instructions. These are needed for dynamic stack alignment. */ @@ -23853,234 +23814,4 @@ arm_attr_length_push_multi(rtx parallel_op, rtx first_op) return 4; } -/* Check the validity of operands in an ldrd/strd instruction. */ -bool -arm_check_ldrd_operands (rtx reg1, rtx reg2, rtx off1, rtx off2) -{ - HOST_WIDE_INT offset1 = 0; - HOST_WIDE_INT offset2 = 0; - int regno1 = REGNO (reg1); - int regno2 = REGNO (reg2); - HOST_WIDE_INT max_offset = 1020; - - if (TARGET_ARM) - max_offset = 255; - - if (off1 != NULL_RTX) - offset1 = INTVAL (off1); - if (off2 != NULL_RTX) - offset2 = INTVAL (off2); - - /* The offset range of LDRD is [-max_offset, max_offset]. Here we check if - both offsets lie in the range [-max_offset, max_offset+4]. If one of the - offsets is max_offset+4, the following condition - ((offset1 + 4) == offset2) - will ensure offset1 to be max_offset, suitable for instruction LDRD. */ - if ((offset1 > (max_offset + 4)) || (offset1 < -max_offset) - || ((offset1 & 3) != 0)) - return false; - if ((offset2 > (max_offset + 4)) || (offset2 < -max_offset) - || ((offset2 & 3) != 0)) - return false; - - if ((offset1 + 4) == offset2) - { - if (TARGET_THUMB2) - return true; - - /* TARGET_ARM */ - if (((regno1 & 1) == 0) && ((regno1 + 1) == regno2)) /* ldrd */ - return true; - - if ((regno1 < regno2) && ((offset1 <= 4) && (offset1 >= -8))) /* ldm */ - return true; - } - if ((offset2 + 4) == offset1) - { - if (TARGET_THUMB2) - return true; - - /* TARGET_ARM */ - if (((regno2 & 1) == 0) && ((regno2 + 1) == regno1)) /* ldrd */ - return true; - - if ((regno2 < regno1) && ((offset2 <= 4) && (offset2 >= -8))) /* ldm */ - return true; - } - - return false; -} - -/* Check if the two memory accesses can be merged to an ldrd/strd instruction. - That is they use the same base register, and the gap between constant - offsets should be 4. */ -bool -arm_legitimate_ldrd_p (rtx reg1, rtx reg2, rtx mem1, rtx mem2, bool ldrd) -{ - rtx base1, base2; - rtx offset1 = NULL_RTX; - rtx offset2 = NULL_RTX; - rtx addr1 = XEXP (mem1, 0); - rtx addr2 = XEXP (mem2, 0); - - if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2)) - return false; - - if (REG_P (addr1)) - base1 = addr1; - else if (GET_CODE (addr1) == PLUS) - { - base1 = XEXP (addr1, 0); - offset1 = XEXP (addr1, 1); - if (!REG_P (base1) || (GET_CODE (offset1) != CONST_INT)) - return false; - } - else - return false; - - if (REG_P (addr2)) - base2 = addr2; - else if (GET_CODE (addr2) == PLUS) - { - base2 = XEXP (addr2, 0); - offset2 = XEXP (addr2, 1); - if (!REG_P (base2) || (GET_CODE (offset2) != CONST_INT)) - return false; - } - else - return false; - - if (base1 != base2) - return false; - - if (ldrd && ((reg1 == reg2) || (reg1 == base1))) - return false; - - return arm_check_ldrd_operands (reg1, reg2, offset1, offset2); -} - -/* Output instructions for ldrd and count the number of bytes has been - outputted. Do not actually output instructions if EMIT_P is false. */ -int -arm_output_ldrd (rtx reg1, rtx reg2, rtx base, rtx off1, rtx off2, bool emit_p) -{ - int length = 0; - rtx operands[5]; - HOST_WIDE_INT offset1 = 0; - HOST_WIDE_INT offset2 = 0; - - if (off1 != NULL_RTX) - offset1 = INTVAL (off1); - else - off1 = GEN_INT (0); - if (off2 != NULL_RTX) - offset2 = INTVAL (off2); - else - off2 = GEN_INT (0); - if (offset1 > offset2) - { - rtx tmp; - HOST_WIDE_INT t = offset1; offset1 = offset2; offset2 = t; - tmp = off1; off1 = off2; off2 = tmp; - tmp = reg1; reg1 = reg2; reg2 = tmp; - } - - operands[0] = reg1; - operands[1] = reg2; - operands[2] = base; - operands[3] = off1; - operands[4] = off2; - - if (TARGET_THUMB2) - { - if (fix_cm3_ldrd && (base == reg1)) - { - if (offset1 <= -256) - { - if (emit_p) - output_asm_insn ("sub\t%2, %2, %n3", operands); - length = 4; - - if (emit_p) - output_asm_insn ("ldr\t%1, [%2, #4]", operands); - if (low_register_operand (reg2, SImode) - && low_register_operand (base, SImode)) - length += 2; - else - length += 4; - - if (emit_p) - output_asm_insn ("ldr\t%0, [%2]", operands); - if (low_register_operand (base, SImode)) - length += 2; - else - length += 4; - } - else - { - if (emit_p) - output_asm_insn ("ldr\t%1, [%2, %4]", operands); - if (low_register_operand (reg2, SImode) && (offset2 >= 0) - && low_register_operand (base, SImode) && (offset2 < 128)) - length += 2; - else - length += 4; - - if (emit_p) - output_asm_insn ("ldr\t%0, [%2, %3]", operands); - if (low_register_operand (base, SImode) - && (offset1 >= 0) && (offset1 < 128)) - length += 2; - else - length += 4; - } - } - else - { - if (emit_p) - output_asm_insn ("ldrd\t%0, %1, [%2, %3]", operands); - length = 4; - } - } - else /* TARGET_ARM */ - { - if ((REGNO (reg2) == (REGNO (reg1) + 1)) && ((REGNO (reg1) & 1) == 0)) - { - if (emit_p) - output_asm_insn ("ldrd\t%0, %1, [%2, %3]", operands); - length = 4; - } - else - { - if (emit_p) - { - switch (offset1) - { - case -8: - output_asm_insn ("ldm%(db%)\t%2, {%0, %1}", operands); - break; - - case -4: - output_asm_insn ("ldm%(da%)\t%2, {%0, %1}", operands); - break; - - case 0: - output_asm_insn ("ldm%(ia%)\t%2, {%0, %1}", operands); - break; - - case 4: - output_asm_insn ("ldm%(ib%)\t%2, {%0, %1}", operands); - break; - - default: - gcc_unreachable (); - } - } - length = 4; - } - } - - return length; -} - #include "gt-arm.h" diff --git a/gcc/config/arm/ldmstm.md b/gcc/config/arm/ldmstm.md index d5451ab48b2..5db4a326996 100644 --- a/gcc/config/arm/ldmstm.md +++ b/gcc/config/arm/ldmstm.md @@ -852,7 +852,7 @@ (set (match_operand:SI 2 "arm_hard_register_operand" "") (mem:SI (plus:SI (match_dup 3) (const_int 4))))])] - "TARGET_32BIT && !arm_arch7 && XVECLEN (operands[0], 0) == 2" + "TARGET_32BIT && XVECLEN (operands[0], 0) == 2" "ldm%(ia%)\t%3, {%1, %2}" [(set_attr "type" "load2") (set_attr "predicable" "yes")]) @@ -901,7 +901,7 @@ (match_operand:SI 1 "arm_hard_register_operand" "")) (set (mem:SI (plus:SI (match_dup 3) (const_int 4))) (match_operand:SI 2 "arm_hard_register_operand" ""))])] - "TARGET_32BIT && !arm_arch7 && XVECLEN (operands[0], 0) == 2" + "TARGET_32BIT && XVECLEN (operands[0], 0) == 2" "stm%(ia%)\t%3, {%1, %2}" [(set_attr "type" "store2") (set_attr "predicable" "yes")]) @@ -939,7 +939,7 @@ (set (match_operand:SI 2 "arm_hard_register_operand" "") (mem:SI (plus:SI (match_dup 3) (const_int 8))))])] - "TARGET_ARM && !arm_arch7 && XVECLEN (operands[0], 0) == 2" + "TARGET_ARM && XVECLEN (operands[0], 0) == 2" "ldm%(ib%)\t%3, {%1, %2}" [(set_attr "type" "load2") (set_attr "predicable" "yes")]) @@ -965,7 +965,7 @@ (match_operand:SI 1 "arm_hard_register_operand" "")) (set (mem:SI (plus:SI (match_dup 3) (const_int 8))) (match_operand:SI 2 "arm_hard_register_operand" ""))])] - "TARGET_ARM && !arm_arch7 && XVECLEN (operands[0], 0) == 2" + "TARGET_ARM && XVECLEN (operands[0], 0) == 2" "stm%(ib%)\t%3, {%1, %2}" [(set_attr "type" "store2") (set_attr "predicable" "yes")]) @@ -990,7 +990,7 @@ (const_int -4)))) (set (match_operand:SI 2 "arm_hard_register_operand" "") (mem:SI (match_dup 3)))])] - "TARGET_ARM && !arm_arch7 && XVECLEN (operands[0], 0) == 2" + "TARGET_ARM && XVECLEN (operands[0], 0) == 2" "ldm%(da%)\t%3, {%1, %2}" [(set_attr "type" "load2") (set_attr "predicable" "yes")]) @@ -1015,7 +1015,7 @@ (match_operand:SI 1 "arm_hard_register_operand" "")) (set (mem:SI (match_dup 3)) (match_operand:SI 2 "arm_hard_register_operand" ""))])] - "TARGET_ARM && !arm_arch7 && XVECLEN (operands[0], 0) == 2" + "TARGET_ARM && XVECLEN (operands[0], 0) == 2" "stm%(da%)\t%3, {%1, %2}" [(set_attr "type" "store2") (set_attr "predicable" "yes")]) @@ -1041,7 +1041,7 @@ (set (match_operand:SI 2 "arm_hard_register_operand" "") (mem:SI (plus:SI (match_dup 3) (const_int -4))))])] - "TARGET_32BIT && !arm_arch7 && XVECLEN (operands[0], 0) == 2" + "TARGET_32BIT && XVECLEN (operands[0], 0) == 2" "ldm%(db%)\t%3, {%1, %2}" [(set_attr "type" "load2") (set_attr "predicable" "yes")]) @@ -1067,7 +1067,7 @@ (match_operand:SI 1 "arm_hard_register_operand" "")) (set (mem:SI (plus:SI (match_dup 3) (const_int -4))) (match_operand:SI 2 "arm_hard_register_operand" ""))])] - "TARGET_32BIT && !arm_arch7 && XVECLEN (operands[0], 0) == 2" + "TARGET_32BIT && XVECLEN (operands[0], 0) == 2" "stm%(db%)\t%3, {%1, %2}" [(set_attr "type" "store2") (set_attr "predicable" "yes")]) @@ -1189,207 +1189,3 @@ FAIL; }) -(define_insn "*ldrd" - [(set (match_operand:SI 0 "arm_hard_register_operand" "") - (mem:SI (plus:SI (match_operand:SI 2 "s_register_operand" "rk") - (match_operand:SI 3 "const_int_operand" "")))) - (set (match_operand:SI 1 "arm_hard_register_operand" "") - (mem:SI (plus:SI (match_dup 2) - (match_operand:SI 4 "const_int_operand" ""))))] - "TARGET_32BIT && arm_arch7 - && arm_check_ldrd_operands (operands[0], operands[1], - operands[3], operands[4])" - "* - arm_output_ldrd (operands[0], operands[1], - operands[2], operands[3], operands[4], true); - return \"\"; - " - [(set (attr "length") - (symbol_ref ("arm_output_ldrd (operands[0], operands[1], operands[2], - operands[3], operands[4], false)")))] -) - -(define_insn "*ldrd_reg1" - [(set (match_operand:SI 0 "arm_hard_register_operand" "") - (mem:SI (match_operand:SI 2 "s_register_operand" "rk"))) - (set (match_operand:SI 1 "arm_hard_register_operand" "") - (mem:SI (plus:SI (match_dup 2) - (match_operand:SI 3 "const_int_operand" ""))))] - "TARGET_32BIT && arm_arch7 - && arm_check_ldrd_operands (operands[0], operands[1], NULL_RTX, operands[3])" - "* - arm_output_ldrd (operands[0], operands[1], - operands[2], NULL_RTX, operands[3], true); - return \"\"; - " - [(set (attr "length") - (symbol_ref ("arm_output_ldrd (operands[0], operands[1], operands[2], - NULL_RTX, operands[3], false)")))] -) - -(define_insn "*ldrd_reg2" - [(set (match_operand:SI 0 "arm_hard_register_operand" "") - (mem:SI (plus:SI (match_operand:SI 2 "s_register_operand" "rk") - (match_operand:SI 3 "const_int_operand" "")))) - (set (match_operand:SI 1 "arm_hard_register_operand" "") - (mem:SI (match_dup 2)))] - "TARGET_32BIT && arm_arch7 - && arm_check_ldrd_operands (operands[0], operands[1], operands[3], NULL_RTX)" - "* - arm_output_ldrd (operands[0], operands[1], - operands[2], operands[3], NULL_RTX, true); - return \"\"; - " - [(set (attr "length") - (symbol_ref ("arm_output_ldrd (operands[0], operands[1], operands[2], - operands[3], NULL_RTX, false)")))] -) - -(define_peephole2 - [(set (match_operand:SI 0 "arm_general_register_operand" "") - (match_operand:SI 2 "memory_operand" "")) - (set (match_operand:SI 1 "arm_general_register_operand" "") - (match_operand:SI 3 "memory_operand" ""))] - "TARGET_32BIT && arm_arch7 - && arm_legitimate_ldrd_p (operands[0], operands[1], - operands[2], operands[3], true)" - [(parallel [(set (match_operand:SI 0 "arm_general_register_operand" "") - (match_operand:SI 2 "memory_operand" "")) - (set (match_operand:SI 1 "arm_general_register_operand" "") - (match_operand:SI 3 "memory_operand" ""))])] - "" -) - -(define_insn "*strd" - [(set (mem:SI (plus:SI (match_operand:SI 2 "s_register_operand" "rk") - (match_operand:SI 3 "const_int_operand" ""))) - (match_operand:SI 0 "arm_hard_register_operand" "")) - (set (mem:SI (plus:SI (match_dup 2) - (match_operand:SI 4 "const_int_operand" ""))) - (match_operand:SI 1 "arm_hard_register_operand" ""))] - "TARGET_32BIT && arm_arch7 - && arm_check_ldrd_operands (operands[0], operands[1], - operands[3], operands[4])" - "* - { - HOST_WIDE_INT offset1 = INTVAL (operands[3]); - HOST_WIDE_INT offset2 = INTVAL (operands[4]); - if (offset1 > offset2) - { - rtx tmp = operands[0]; operands[0] = operands[1]; operands[1] = tmp; - tmp = operands[3]; operands[3] = operands[4]; operands[4] = tmp; - offset1 = INTVAL (operands[3]); - offset2 = INTVAL (operands[4]); - } - if (TARGET_THUMB2) - return \"strd\\t%0, %1, [%2, %3]\"; - else /* TARGET_ARM */ - { - if ((REGNO (operands[1]) == (REGNO (operands[0]) + 1)) - && ((REGNO (operands[0]) & 1) == 0)) - return \"strd\\t%0, %1, [%2, %3]\"; - else if (offset1 == -8) - return \"stm%(db%)\\t%2, {%0, %1}\"; - else /* offset1 == 4 */ - return \"stm%(ib%)\\t%2, {%0, %1}\"; - } - }" - [(set_attr "length" "4")] -) - -(define_insn "*strd_reg1" - [(set (mem:SI (match_operand:SI 2 "s_register_operand" "rk")) - (match_operand:SI 0 "arm_hard_register_operand" "")) - (set (mem:SI (plus:SI (match_dup 2) - (match_operand:SI 3 "const_int_operand" ""))) - (match_operand:SI 1 "arm_hard_register_operand" ""))] - "TARGET_32BIT && arm_arch7 - && arm_check_ldrd_operands (operands[0], operands[1], NULL_RTX, operands[3])" - "* - { - HOST_WIDE_INT offset2 = INTVAL (operands[3]); - if (TARGET_THUMB2) - { - if (offset2 == 4) - return \"strd\\t%0, %1, [%2]\"; - else - return \"strd\\t%1, %0, [%2, %3]\"; - } - else /* TARGET_ARM */ - { - if (offset2 == 4) - { - if ((REGNO (operands[1]) == (REGNO (operands[0]) + 1)) - && ((REGNO (operands[0]) & 1) == 0)) - return \"strd\\t%0, %1, [%2]\"; - else - return \"stm%(ia%)\\t%2, {%0, %1}\"; - } - else /* offset2 == -4 */ - { - if ((REGNO (operands[0]) == (REGNO (operands[1]) + 1)) - && ((REGNO (operands[1]) & 1) == 0)) - return \"strd\\t%1, %0, [%2, %3]\"; - else - return \"stm%(da%)\\t%2, {%1, %0}\"; - } - } - }" - [(set_attr "length" "4")] -) - -(define_insn "*strd_reg2" - [(set (mem:SI (plus:SI (match_operand:SI 2 "s_register_operand" "rk") - (match_operand:SI 3 "const_int_operand" ""))) - (match_operand:SI 0 "arm_hard_register_operand" "")) - (set (mem:SI (match_dup 2)) - (match_operand:SI 1 "arm_hard_register_operand" ""))] - "TARGET_32BIT && arm_arch7 - && arm_check_ldrd_operands (operands[0], operands[1], operands[3], NULL_RTX)" - "* - { - HOST_WIDE_INT offset1 = INTVAL (operands[3]); - if (TARGET_THUMB2) - { - if (offset1 == -4) - return \"strd\\t%0, %1, [%2, %3]\"; - else - return \"strd\\t%1, %0, [%2]\"; - } - else /* TARGET_ARM */ - { - if (offset1 == -4) - { - if ((REGNO (operands[1]) == (REGNO (operands[0]) + 1)) - && ((REGNO (operands[0]) & 1) == 0)) - return \"strd\\t%0, %1, [%2, %3]\"; - else - return \"stm%(da%)\\t%2, {%0, %1}\"; - } - else - { - if ((REGNO (operands[0]) == (REGNO (operands[1]) + 1)) - && ((REGNO (operands[1]) & 1) == 0)) - return \"strd\\t%1, %0, [%2]\"; - else - return \"stm%(ia%)\\t%2, {%1, %0}\"; - } - } - }" - [(set_attr "length" "4")] -) - -(define_peephole2 - [(set (match_operand:SI 2 "memory_operand" "") - (match_operand:SI 0 "arm_general_register_operand" "")) - (set (match_operand:SI 3 "memory_operand" "") - (match_operand:SI 1 "arm_general_register_operand" ""))] - "TARGET_32BIT && arm_arch7 - && arm_legitimate_ldrd_p (operands[0], operands[1], - operands[2], operands[3], false)" - [(parallel [(set (match_operand:SI 2 "memory_operand" "") - (match_operand:SI 0 "arm_general_register_operand" "")) - (set (match_operand:SI 3 "memory_operand" "") - (match_operand:SI 1 "arm_general_register_operand" ""))])] - "" -) diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 8c31c48b495..a8c1b878670 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -5580,8 +5580,9 @@ (truncate:<V_narrow> (match_operand:VN 2 "register_operand" "w"))))] "TARGET_NEON" - "vmovn.i<V_sz_elem>\t%e0, %q1\n\tvmovn.i<V_sz_elem>\t%f0, %q2" - [(set_attr "neon_type" "neon_shift_1")] + "vmovn.i<V_sz_elem>\t%e0, %q1\;vmovn.i<V_sz_elem>\t%f0, %q2" + [(set_attr "neon_type" "neon_shift_1") + (set_attr "length" "8")] ) ;; For the non-quad case. diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md index 26dcbdde83e..9a11012641d 100644 --- a/gcc/config/arm/thumb2.md +++ b/gcc/config/arm/thumb2.md @@ -207,7 +207,9 @@ (define_insn "*thumb2_movhi_insn" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r") (match_operand:HI 1 "general_operand" "rI,n,r,m"))] - "TARGET_THUMB2" + "TARGET_THUMB2 + && (register_operand (operands[0], HImode) + || register_operand (operands[1], HImode))" "@ mov%?\\t%0, %1\\t%@ movhi movw%?\\t%0, %L1\\t%@ movhi diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index aadfd244b68..e46ccd3c6a5 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -102,9 +102,9 @@ static unsigned int avr_case_values_threshold (void); static bool avr_frame_pointer_required_p (void); static bool avr_can_eliminate (const int, const int); static bool avr_class_likely_spilled_p (reg_class_t c); -static rtx avr_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx avr_function_arg (cumulative_args_t , enum machine_mode, const_tree, bool); -static void avr_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void avr_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); static void avr_help (void); static bool avr_function_ok_for_sibcall (tree, tree); @@ -156,13 +156,6 @@ static const struct attribute_spec avr_attribute_table[] = false }, { NULL, 0, 0, false, false, false, NULL, false } }; - -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options avr_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP @@ -254,18 +247,12 @@ static const struct default_options avr_option_optimization_table[] = #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE avr_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE avr_option_optimization_table - #undef TARGET_CANNOT_MODIFY_JUMPS_P #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p #undef TARGET_HELP #define TARGET_HELP avr_help -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info - #undef TARGET_FUNCTION_OK_FOR_SIBCALL #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall @@ -1756,9 +1743,10 @@ avr_num_arg_regs (enum machine_mode mode, const_tree type) in a register, and which register. */ static rtx -avr_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +avr_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int bytes = avr_num_arg_regs (mode, type); if (cum->nregs && bytes <= cum->nregs) @@ -1771,9 +1759,10 @@ avr_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, in the argument list. */ static void -avr_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +avr_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int bytes = avr_num_arg_regs (mode, type); cum->nregs -= bytes; diff --git a/gcc/config/avr/libgcc.S b/gcc/config/avr/libgcc.S index 2e8d9514a79..1988de91d1c 100644 --- a/gcc/config/avr/libgcc.S +++ b/gcc/config/avr/libgcc.S @@ -52,6 +52,26 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #endif .endm +#if defined (__AVR_HAVE_JMP_CALL__) +#define XCALL call +#define XJMP jmp +#else +#define XCALL rcall +#define XJMP rjmp +#endif + +.macro DEFUN name +.global \name +.func \name +\name: +.endm + +.macro ENDF name +.size \name, .-\name +.endfunc +.endm + + /* Note: mulqi3, mulhi3 are open-coded on the enhanced core. */ #if !defined (__AVR_HAVE_MUL__) /******************************************************* @@ -779,12 +799,6 @@ __do_clear_bss: /* __do_global_ctors and __do_global_dtors are only necessary if there are any constructors/destructors. */ -#if defined (__AVR_HAVE_JMP_CALL__) -#define XCALL call -#else -#define XCALL rcall -#endif - #ifdef L_ctors .section .init6,"ax",@progbits .global __do_global_ctors @@ -897,3 +911,393 @@ __tablejump_elpm__: .endfunc #endif /* defined (L_tablejump_elpm) */ + +/********************************** + * Find first set Bit (ffs) + **********************************/ + +#if defined (L_ffssi2) +;; find first set bit +;; r25:r24 = ffs32 (r25:r22) +;; clobbers: r22, r26 +DEFUN __ffssi2 + clr r26 + tst r22 + brne 1f + subi r26, -8 + or r22, r23 + brne 1f + subi r26, -8 + or r22, r24 + brne 1f + subi r26, -8 + or r22, r25 + brne 1f + ret +1: mov r24, r22 + XJMP __loop_ffsqi2 +ENDF __ffssi2 +#endif /* defined (L_ffssi2) */ + +#if defined (L_ffshi2) +;; find first set bit +;; r25:r24 = ffs16 (r25:r24) +;; clobbers: r26 +DEFUN __ffshi2 + clr r26 + cpse r24, __zero_reg__ +1: XJMP __loop_ffsqi2 + ldi r26, 8 + or r24, r25 + brne 1b + ret +ENDF __ffshi2 +#endif /* defined (L_ffshi2) */ + +#if defined (L_loop_ffsqi2) +;; Helper for ffshi2, ffssi2 +;; r25:r24 = r26 + zero_extend16 (ffs8(r24)) +;; r24 must be != 0 +;; clobbers: r26 +DEFUN __loop_ffsqi2 + inc r26 + lsr r24 + brcc __loop_ffsqi2 + mov r24, r26 + clr r25 + ret +ENDF __loop_ffsqi2 +#endif /* defined (L_loop_ffsqi2) */ + + +/********************************** + * Count trailing Zeros (ctz) + **********************************/ + +#if defined (L_ctzsi2) +;; count trailing zeros +;; r25:r24 = ctz32 (r25:r22) +;; ctz(0) = 32 +DEFUN __ctzsi2 + XCALL __ffssi2 + dec r24 + sbrc r24, 7 + ldi r24, 32 + ret +ENDF __ctzsi2 +#endif /* defined (L_ctzsi2) */ + +#if defined (L_ctzhi2) +;; count trailing zeros +;; r25:r24 = ctz16 (r25:r24) +;; ctz(0) = 16 +DEFUN __ctzhi2 + XCALL __ffshi2 + dec r24 + sbrc r24, 7 + ldi r24, 16 + ret +ENDF __ctzhi2 +#endif /* defined (L_ctzhi2) */ + + +/********************************** + * Count leading Zeros (clz) + **********************************/ + +#if defined (L_clzdi2) +;; count leading zeros +;; r25:r24 = clz64 (r25:r18) +;; clobbers: r22, r23, r26 +DEFUN __clzdi2 + XCALL __clzsi2 + sbrs r24, 5 + ret + mov_l r22, r18 + mov_h r23, r19 + mov_l r24, r20 + mov_h r25, r21 + XCALL __clzsi2 + subi r24, -32 + ret +ENDF __clzdi2 +#endif /* defined (L_clzdi2) */ + +#if defined (L_clzsi2) +;; count leading zeros +;; r25:r24 = clz32 (r25:r22) +;; clobbers: r26 +DEFUN __clzsi2 + XCALL __clzhi2 + sbrs r24, 4 + ret + mov_l r24, r22 + mov_h r25, r23 + XCALL __clzhi2 + subi r24, -16 + ret +ENDF __clzsi2 +#endif /* defined (L_clzsi2) */ + +#if defined (L_clzhi2) +;; count leading zeros +;; r25:r24 = clz16 (r25:r24) +;; clobbers: r26 +DEFUN __clzhi2 + clr r26 + tst r25 + brne 1f + subi r26, -8 + or r25, r24 + brne 1f + ldi r24, 16 + ret +1: cpi r25, 16 + brsh 3f + subi r26, -3 + swap r25 +2: inc r26 +3: lsl r25 + brcc 2b + mov r24, r26 + clr r25 + ret +ENDF __clzhi2 +#endif /* defined (L_clzhi2) */ + + +/********************************** + * Parity + **********************************/ + +#if defined (L_paritydi2) +;; r25:r24 = parity64 (r25:r18) +;; clobbers: __tmp_reg__ +DEFUN __paritydi2 + eor r24, r18 + eor r24, r19 + eor r24, r20 + eor r24, r21 + XJMP __paritysi2 +ENDF __paritydi2 +#endif /* defined (L_paritydi2) */ + +#if defined (L_paritysi2) +;; r25:r24 = parity32 (r25:r22) +;; clobbers: __tmp_reg__ +DEFUN __paritysi2 + eor r24, r22 + eor r24, r23 + XJMP __parityhi2 +ENDF __paritysi2 +#endif /* defined (L_paritysi2) */ + +#if defined (L_parityhi2) +;; r25:r24 = parity16 (r25:r24) +;; clobbers: __tmp_reg__ +DEFUN __parityhi2 + eor r24, r25 +;; FALLTHRU +ENDF __parityhi2 + +;; r25:r24 = parity8 (r24) +;; clobbers: __tmp_reg__ +DEFUN __parityqi2 + ;; parity is in r24[0..7] + mov __tmp_reg__, r24 + swap __tmp_reg__ + eor r24, __tmp_reg__ + ;; parity is in r24[0..3] + subi r24, -4 + andi r24, -5 + subi r24, -6 + ;; parity is in r24[0,3] + sbrc r24, 3 + inc r24 + ;; parity is in r24[0] + andi r24, 1 + clr r25 + ret +ENDF __parityqi2 +#endif /* defined (L_parityhi2) */ + + +/********************************** + * Population Count + **********************************/ + +#if defined (L_popcounthi2) +;; population count +;; r25:r24 = popcount16 (r25:r24) +;; clobbers: r30, __tmp_reg__ +DEFUN __popcounthi2 + XCALL __popcountqi2 + mov r30, r24 + mov r24, r25 + XCALL __popcountqi2 + add r24, r30 + clr r25 + ret +ENDF __popcounthi2 +#endif /* defined (L_popcounthi2) */ + +#if defined (L_popcountsi2) +;; population count +;; r25:r24 = popcount32 (r25:r22) +;; clobbers: r26, r30, __tmp_reg__ +DEFUN __popcountsi2 + XCALL __popcounthi2 + mov r26, r24 + mov_l r24, r22 + mov_h r25, r23 + XCALL __popcounthi2 + add r24, r26 + ret +ENDF __popcountsi2 +#endif /* defined (L_popcountsi2) */ + +#if defined (L_popcountdi2) +;; population count +;; r25:r24 = popcount64 (r25:r18) +;; clobbers: r22, r23, r26, r27, r30, __tmp_reg__ +DEFUN __popcountdi2 + XCALL __popcountsi2 + mov r27, r24 + mov_l r22, r18 + mov_h r23, r19 + mov_l r24, r20 + mov_h r25, r21 + XCALL __popcountsi2 + add r24, r27 + ret +ENDF __popcountdi2 +#endif /* defined (L_popcountdi2) */ + +#if defined (L_popcountqi2) +;; population count +;; r24 = popcount8 (r24) +;; clobbers: __tmp_reg__ +DEFUN __popcountqi2 + mov __tmp_reg__, r24 + andi r24, 1 + lsr __tmp_reg__ + lsr __tmp_reg__ + adc r24, __zero_reg__ + lsr __tmp_reg__ + adc r24, __zero_reg__ + lsr __tmp_reg__ + adc r24, __zero_reg__ + lsr __tmp_reg__ + adc r24, __zero_reg__ + lsr __tmp_reg__ + adc r24, __zero_reg__ + lsr __tmp_reg__ + adc r24, __tmp_reg__ + ret +ENDF __popcountqi2 +#endif /* defined (L_popcountqi2) */ + + +/********************************** + * Swap bytes + **********************************/ + +;; swap two registers with different register number +.macro bswap a, b + eor \a, \b + eor \b, \a + eor \a, \b +.endm + +#if defined (L_bswapsi2) +;; swap bytes +;; r25:r22 = bswap32 (r25:r22) +DEFUN __bswapsi2 + bswap r22, r25 + bswap r23, r24 + ret +ENDF __bswapsi2 +#endif /* defined (L_bswapsi2) */ + +#if defined (L_bswapdi2) +;; swap bytes +;; r25:r18 = bswap64 (r25:r18) +DEFUN __bswapdi2 + bswap r18, r25 + bswap r19, r24 + bswap r20, r23 + bswap r21, r22 + ret +ENDF __bswapdi2 +#endif /* defined (L_bswapdi2) */ + + +/********************************** + * 64-bit shifts + **********************************/ + +#if defined (L_ashrdi3) +;; Arithmetic shift right +;; r25:r18 = ashr64 (r25:r18, r17:r16) +DEFUN __ashrdi3 + push r16 + andi r16, 63 + breq 2f +1: asr r25 + ror r24 + ror r23 + ror r22 + ror r21 + ror r20 + ror r19 + ror r18 + dec r16 + brne 1b +2: pop r16 + ret +ENDF __ashrdi3 +#endif /* defined (L_ashrdi3) */ + +#if defined (L_lshrdi3) +;; Logic shift right +;; r25:r18 = lshr64 (r25:r18, r17:r16) +DEFUN __lshrdi3 + push r16 + andi r16, 63 + breq 2f +1: lsr r25 + ror r24 + ror r23 + ror r22 + ror r21 + ror r20 + ror r19 + ror r18 + dec r16 + brne 1b +2: pop r16 + ret +ENDF __lshrdi3 +#endif /* defined (L_lshrdi3) */ + +#if defined (L_ashldi3) +;; Shift left +;; r25:r18 = ashl64 (r25:r18, r17:r16) +DEFUN __ashldi3 + push r16 + andi r16, 63 + breq 2f +1: lsl r18 + rol r19 + rol r20 + rol r21 + rol r22 + rol r23 + rol r24 + rol r25 + dec r16 + brne 1b +2: pop r16 + ret +ENDF __ashldi3 +#endif /* defined (L_ashldi3) */ diff --git a/gcc/config/avr/t-avr b/gcc/config/avr/t-avr index 18769ebb23d..4186178dbd2 100644 --- a/gcc/config/avr/t-avr +++ b/gcc/config/avr/t-avr @@ -24,12 +24,10 @@ driver-avr.o: $(srcdir)/config/avr/driver-avr.c \ avr-devices.o: $(srcdir)/config/avr/avr-devices.c \ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< - avr-c.o: $(srcdir)/config/avr/avr-c.c \ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(C_COMMON_H) $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< - LIB1ASMSRC = avr/libgcc.S @@ -52,7 +50,30 @@ LIB1ASMFUNCS = \ _copy_data \ _clear_bss \ _ctors \ - _dtors + _dtors \ + _ffssi2 \ + _ffshi2 \ + _loop_ffsqi2 \ + _ctzsi2 \ + _ctzhi2 \ + _clzdi2 \ + _clzsi2 \ + _clzhi2 \ + _paritydi2 \ + _paritysi2 \ + _parityhi2 \ + _popcounthi2 \ + _popcountsi2 \ + _popcountdi2 \ + _popcountqi2 \ + _bswapsi2 \ + _bswapdi2 \ + _ashldi3 \ + _ashrdi3 \ + _lshrdi3 + +LIB2FUNCS_EXCLUDE = \ + _clz # We do not have the DF type. # Most of the C functions in libgcc2 use almost all registers, @@ -216,8 +237,8 @@ MULTILIB_MATCHES = \ mmcu?avr51=mmcu?at90can128 \ mmcu?avr51=mmcu?at90usb1286 \ mmcu?avr51=mmcu?at90usb1287 \ - mmcu?avr6=mmcu?atmega2560 \ - mmcu?avr6=mmcu?atmega2561 + mmcu?avr6=mmcu?atmega2560 \ + mmcu?avr6=mmcu?atmega2561 MULTILIB_EXCEPTIONS = diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 2af0afe6db5..72fc42383ee 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -86,270 +86,6 @@ const char *byte_reg_names[] = BYTE_REGISTER_NAMES; static int arg_regs[] = FUNCTION_ARG_REGISTERS; static int ret_regs[] = FUNCTION_RETURN_REGISTERS; -struct bfin_cpu -{ - const char *name; - bfin_cpu_t type; - int si_revision; - unsigned int workarounds; -}; - -static const struct bfin_cpu bfin_cpus[] = -{ - - {"bf512", BFIN_CPU_BF512, 0x0002, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf512", BFIN_CPU_BF512, 0x0001, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf512", BFIN_CPU_BF512, 0x0000, - WA_SPECULATIVE_LOADS | WA_05000074}, - - {"bf514", BFIN_CPU_BF514, 0x0002, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf514", BFIN_CPU_BF514, 0x0001, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf514", BFIN_CPU_BF514, 0x0000, - WA_SPECULATIVE_LOADS | WA_05000074}, - - {"bf516", BFIN_CPU_BF516, 0x0002, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf516", BFIN_CPU_BF516, 0x0001, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf516", BFIN_CPU_BF516, 0x0000, - WA_SPECULATIVE_LOADS | WA_05000074}, - - {"bf518", BFIN_CPU_BF518, 0x0002, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf518", BFIN_CPU_BF518, 0x0001, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf518", BFIN_CPU_BF518, 0x0000, - WA_SPECULATIVE_LOADS | WA_05000074}, - - {"bf522", BFIN_CPU_BF522, 0x0002, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf522", BFIN_CPU_BF522, 0x0001, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, - {"bf522", BFIN_CPU_BF522, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, - - {"bf523", BFIN_CPU_BF523, 0x0002, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf523", BFIN_CPU_BF523, 0x0001, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, - {"bf523", BFIN_CPU_BF523, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, - - {"bf524", BFIN_CPU_BF524, 0x0002, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf524", BFIN_CPU_BF524, 0x0001, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, - {"bf524", BFIN_CPU_BF524, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, - - {"bf525", BFIN_CPU_BF525, 0x0002, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf525", BFIN_CPU_BF525, 0x0001, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, - {"bf525", BFIN_CPU_BF525, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, - - {"bf526", BFIN_CPU_BF526, 0x0002, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf526", BFIN_CPU_BF526, 0x0001, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, - {"bf526", BFIN_CPU_BF526, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, - - {"bf527", BFIN_CPU_BF527, 0x0002, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf527", BFIN_CPU_BF527, 0x0001, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, - {"bf527", BFIN_CPU_BF527, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074}, - - {"bf531", BFIN_CPU_BF531, 0x0006, - WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074}, - {"bf531", BFIN_CPU_BF531, 0x0005, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315 - | WA_LOAD_LCREGS | WA_05000074}, - {"bf531", BFIN_CPU_BF531, 0x0004, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - {"bf531", BFIN_CPU_BF531, 0x0003, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - - {"bf532", BFIN_CPU_BF532, 0x0006, - WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074}, - {"bf532", BFIN_CPU_BF532, 0x0005, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315 - | WA_LOAD_LCREGS | WA_05000074}, - {"bf532", BFIN_CPU_BF532, 0x0004, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - {"bf532", BFIN_CPU_BF532, 0x0003, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - - {"bf533", BFIN_CPU_BF533, 0x0006, - WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074}, - {"bf533", BFIN_CPU_BF533, 0x0005, - WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315 - | WA_LOAD_LCREGS | WA_05000074}, - {"bf533", BFIN_CPU_BF533, 0x0004, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - {"bf533", BFIN_CPU_BF533, 0x0003, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - - {"bf534", BFIN_CPU_BF534, 0x0003, - WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074}, - {"bf534", BFIN_CPU_BF534, 0x0002, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - {"bf534", BFIN_CPU_BF534, 0x0001, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - - {"bf536", BFIN_CPU_BF536, 0x0003, - WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074}, - {"bf536", BFIN_CPU_BF536, 0x0002, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - {"bf536", BFIN_CPU_BF536, 0x0001, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - - {"bf537", BFIN_CPU_BF537, 0x0003, - WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074}, - {"bf537", BFIN_CPU_BF537, 0x0002, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - {"bf537", BFIN_CPU_BF537, 0x0001, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - - {"bf538", BFIN_CPU_BF538, 0x0005, - WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074}, - {"bf538", BFIN_CPU_BF538, 0x0004, - WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074}, - {"bf538", BFIN_CPU_BF538, 0x0003, - WA_SPECULATIVE_LOADS | WA_RETS - | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074}, - {"bf538", BFIN_CPU_BF538, 0x0002, - WA_SPECULATIVE_LOADS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - - {"bf539", BFIN_CPU_BF539, 0x0005, - WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074}, - {"bf539", BFIN_CPU_BF539, 0x0004, - WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074}, - {"bf539", BFIN_CPU_BF539, 0x0003, - WA_SPECULATIVE_LOADS | WA_RETS - | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074}, - {"bf539", BFIN_CPU_BF539, 0x0002, - WA_SPECULATIVE_LOADS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - - {"bf542m", BFIN_CPU_BF542M, 0x0003, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - - {"bf542", BFIN_CPU_BF542, 0x0004, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf542", BFIN_CPU_BF542, 0x0002, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf542", BFIN_CPU_BF542, 0x0001, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf542", BFIN_CPU_BF542, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS - | WA_05000074}, - - {"bf544m", BFIN_CPU_BF544M, 0x0003, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - - {"bf544", BFIN_CPU_BF544, 0x0004, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf544", BFIN_CPU_BF544, 0x0002, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf544", BFIN_CPU_BF544, 0x0001, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf544", BFIN_CPU_BF544, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS - | WA_05000074}, - - {"bf547m", BFIN_CPU_BF547M, 0x0003, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - - {"bf547", BFIN_CPU_BF547, 0x0004, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf547", BFIN_CPU_BF547, 0x0002, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf547", BFIN_CPU_BF547, 0x0001, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf547", BFIN_CPU_BF547, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS - | WA_05000074}, - - {"bf548m", BFIN_CPU_BF548M, 0x0003, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - - {"bf548", BFIN_CPU_BF548, 0x0004, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf548", BFIN_CPU_BF548, 0x0002, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf548", BFIN_CPU_BF548, 0x0001, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf548", BFIN_CPU_BF548, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS - | WA_05000074}, - - {"bf549m", BFIN_CPU_BF549M, 0x0003, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - - {"bf549", BFIN_CPU_BF549, 0x0004, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf549", BFIN_CPU_BF549, 0x0002, - WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf549", BFIN_CPU_BF549, 0x0001, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074}, - {"bf549", BFIN_CPU_BF549, 0x0000, - WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS - | WA_05000074}, - - {"bf561", BFIN_CPU_BF561, 0x0005, WA_RETS - | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074}, - {"bf561", BFIN_CPU_BF561, 0x0003, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - {"bf561", BFIN_CPU_BF561, 0x0002, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS - | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS - | WA_05000074}, - - {"bf592", BFIN_CPU_BF592, 0x0001, - WA_SPECULATIVE_LOADS | WA_05000074}, - {"bf592", BFIN_CPU_BF592, 0x0000, - WA_SPECULATIVE_LOADS | WA_05000074}, - - {NULL, BFIN_CPU_UNKNOWN, 0, 0} -}; - int splitting_for_sched, splitting_loops; static void @@ -824,7 +560,7 @@ expand_epilogue_reg_restore (rtx spreg, bool saveall, bool is_inthandler) - now, the vastart pointer can access all arguments from the stack. */ static void -setup_incoming_varargs (CUMULATIVE_ARGS *cum, +setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, int *pretend_size, int no_rtl) @@ -840,7 +576,7 @@ setup_incoming_varargs (CUMULATIVE_ARGS *cum, if they are in the first 3 words. We assume at least 1 named argument exists, so we never generate [ARGP] = R0 here. */ - for (i = cum->words + 1; i < max_arg_registers; i++) + for (i = get_cumulative_args (cum)->words + 1; i < max_arg_registers; i++) { mem = gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, (i * UNITS_PER_WORD))); @@ -1911,9 +1647,10 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, (TYPE is null for libcalls where that information may not be available.) */ static void -bfin_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +bfin_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int count, bytes, words; bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode); @@ -1950,9 +1687,10 @@ bfin_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, (otherwise it is an extra parameter matching an ellipsis). */ static rtx -bfin_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +bfin_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode); @@ -1979,13 +1717,13 @@ bfin_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, stack. */ static int -bfin_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, +bfin_arg_partial_bytes (cumulative_args_t cum, enum machine_mode mode, tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { int bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode); - int bytes_left = cum->nregs * UNITS_PER_WORD; + int bytes_left = get_cumulative_args (cum)->nregs * UNITS_PER_WORD; if (bytes == -1) return 0; @@ -2000,7 +1738,7 @@ bfin_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, /* Variable sized types are passed by reference. */ static bool -bfin_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +bfin_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type, bool named ATTRIBUTE_UNUSED) { @@ -2572,101 +2310,6 @@ bfin_class_likely_spilled_p (reg_class_t rclass) return false; } -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -bfin_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc) -{ - size_t code = decoded->opt_index; - const char *arg = decoded->arg; - int value = decoded->value; - - switch (code) - { - case OPT_mshared_library_id_: - if (value > MAX_LIBRARY_ID) - error_at (loc, "-mshared-library-id=%s is not between 0 and %d", - arg, MAX_LIBRARY_ID); - return true; - - case OPT_mcpu_: - { - const char *p, *q; - int i; - - i = 0; - while ((p = bfin_cpus[i].name) != NULL) - { - if (strncmp (arg, p, strlen (p)) == 0) - break; - i++; - } - - if (p == NULL) - { - error_at (loc, "-mcpu=%s is not valid", arg); - return false; - } - - opts->x_bfin_cpu_type = bfin_cpus[i].type; - - q = arg + strlen (p); - - if (*q == '\0') - { - opts->x_bfin_si_revision = bfin_cpus[i].si_revision; - opts->x_bfin_workarounds |= bfin_cpus[i].workarounds; - } - else if (strcmp (q, "-none") == 0) - opts->x_bfin_si_revision = -1; - else if (strcmp (q, "-any") == 0) - { - opts->x_bfin_si_revision = 0xffff; - while (bfin_cpus[i].type == opts->x_bfin_cpu_type) - { - opts->x_bfin_workarounds |= bfin_cpus[i].workarounds; - i++; - } - } - else - { - unsigned int si_major, si_minor; - int rev_len, n; - - rev_len = strlen (q); - - if (sscanf (q, "-%u.%u%n", &si_major, &si_minor, &n) != 2 - || n != rev_len - || si_major > 0xff || si_minor > 0xff) - { - invalid_silicon_revision: - error_at (loc, "-mcpu=%s has invalid silicon revision", arg); - return false; - } - - opts->x_bfin_si_revision = (si_major << 8) | si_minor; - - while (bfin_cpus[i].type == opts->x_bfin_cpu_type - && bfin_cpus[i].si_revision != opts->x_bfin_si_revision) - i++; - - if (bfin_cpus[i].type != opts->x_bfin_cpu_type) - goto invalid_silicon_revision; - - opts->x_bfin_workarounds |= bfin_cpus[i].workarounds; - } - - return true; - } - - default: - return true; - } -} - static struct machine_function * bfin_init_machine_status (void) { @@ -6700,15 +6343,9 @@ bfin_conditional_register_usage (void) #undef TARGET_VECTOR_MODE_SUPPORTED_P #define TARGET_VECTOR_MODE_SUPPORTED_P bfin_vector_mode_supported_p -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION bfin_handle_option - #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE bfin_option_override -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT - #undef TARGET_SECONDARY_RELOAD #define TARGET_SECONDARY_RELOAD bfin_secondary_reload diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h index 4f21a1c8a32..635c61b243a 100644 --- a/gcc/config/bfin/bfin.h +++ b/gcc/config/bfin/bfin.h @@ -1169,4 +1169,14 @@ extern int splitting_for_sched, splitting_loops; #define TARGET_SUPPORTS_SYNC_CALLS 0 #endif +struct bfin_cpu +{ + const char *name; + bfin_cpu_t type; + int si_revision; + unsigned int workarounds; +}; + +extern const struct bfin_cpu bfin_cpus[]; + #endif /* _BFIN_CONFIG */ diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index 159b31bf7f4..54a0f266cac 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -98,7 +98,7 @@ static struct machine_function * cris_init_machine_status (void); static rtx cris_struct_value_rtx (tree, int); -static void cris_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, +static void cris_setup_incoming_varargs (cumulative_args_t, enum machine_mode, tree type, int *, int); static int cris_initial_frame_pointer_offset (void); @@ -125,20 +125,18 @@ static int cris_register_move_cost (enum machine_mode, reg_class_t, reg_class_t) static int cris_memory_move_cost (enum machine_mode, reg_class_t, bool); static bool cris_rtx_costs (rtx, int, int, int *, bool); static int cris_address_cost (rtx, bool); -static bool cris_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, +static bool cris_pass_by_reference (cumulative_args_t, enum machine_mode, const_tree, bool); -static int cris_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, +static int cris_arg_partial_bytes (cumulative_args_t, enum machine_mode, tree, bool); -static rtx cris_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx cris_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static rtx cris_function_incoming_arg (CUMULATIVE_ARGS *, +static rtx cris_function_incoming_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static void cris_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void cris_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); static tree cris_md_asm_clobbers (tree, tree, tree); -static bool cris_handle_option (struct gcc_options *, struct gcc_options *, - const struct cl_decoded_option *, location_t); static void cris_option_override (void); static bool cris_frame_pointer_required (void); @@ -156,14 +154,6 @@ int cris_max_stackframe = 0; /* This is the parsed result of the "-march=" option, if given. */ int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION; -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ - -static const struct default_options cris_option_optimization_table[] = - { - { OPT_LEVELS_2_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t" #undef TARGET_ASM_ALIGNED_SI_OP @@ -232,17 +222,11 @@ static const struct default_options cris_option_optimization_table[] = #define TARGET_FUNCTION_ARG_ADVANCE cris_function_arg_advance #undef TARGET_MD_ASM_CLOBBERS #define TARGET_MD_ASM_CLOBBERS cris_md_asm_clobbers -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | CRIS_SUBTARGET_DEFAULT) -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION cris_handle_option #undef TARGET_FRAME_POINTER_REQUIRED #define TARGET_FRAME_POINTER_REQUIRED cris_frame_pointer_required #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE cris_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE cris_option_optimization_table #undef TARGET_ASM_TRAMPOLINE_TEMPLATE #define TARGET_ASM_TRAMPOLINE_TEMPLATE cris_asm_trampoline_template @@ -2324,66 +2308,6 @@ cris_asm_output_case_end (FILE *stream, int num, rtx table) (TARGET_PDEBUG ? "; default" : "")); } -/* TARGET_HANDLE_OPTION worker. We just store the values into local - variables here. Checks for correct semantics are in - cris_option_override. */ - -static bool -cris_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc ATTRIBUTE_UNUSED) -{ - size_t code = decoded->opt_index; - - switch (code) - { - case OPT_metrax100: - opts->x_target_flags - |= (MASK_SVINTO - + MASK_ETRAX4_ADD - + MASK_ALIGN_BY_32); - break; - - case OPT_mno_etrax100: - opts->x_target_flags - &= ~(MASK_SVINTO - + MASK_ETRAX4_ADD - + MASK_ALIGN_BY_32); - break; - - case OPT_m32_bit: - case OPT_m32bit: - opts->x_target_flags - |= (MASK_STACK_ALIGN - + MASK_CONST_ALIGN - + MASK_DATA_ALIGN - + MASK_ALIGN_BY_32); - break; - - case OPT_m16_bit: - case OPT_m16bit: - opts->x_target_flags - |= (MASK_STACK_ALIGN - + MASK_CONST_ALIGN - + MASK_DATA_ALIGN); - break; - - case OPT_m8_bit: - case OPT_m8bit: - opts->x_target_flags - &= ~(MASK_STACK_ALIGN - + MASK_CONST_ALIGN - + MASK_DATA_ALIGN); - break; - - default: - break; - } - - return true; -} - /* The TARGET_OPTION_OVERRIDE worker. As is the norm, this also parses -mfoo=bar type parameters. */ @@ -3752,12 +3676,14 @@ cris_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED, /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */ static void -cris_setup_incoming_varargs (CUMULATIVE_ARGS *ca, +cris_setup_incoming_varargs (cumulative_args_t ca_v, enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, int *pretend_arg_size, int second_time) { + CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v); + if (ca->regs < CRIS_MAX_ARGS_IN_REGS) { int stdarg_regs = CRIS_MAX_ARGS_IN_REGS - ca->regs; @@ -3775,7 +3701,7 @@ cris_setup_incoming_varargs (CUMULATIVE_ARGS *ca, For cris, we pass <= 8 bytes by value, others by reference. */ static bool -cris_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, +cris_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { @@ -3833,10 +3759,10 @@ cris_function_value_regno_p (const unsigned int regno) } static int -cris_arg_partial_bytes (CUMULATIVE_ARGS *ca, enum machine_mode mode, +cris_arg_partial_bytes (cumulative_args_t ca, enum machine_mode mode, tree type, bool named ATTRIBUTE_UNUSED) { - if (ca->regs == CRIS_MAX_ARGS_IN_REGS - 1 + if (get_cumulative_args (ca)->regs == CRIS_MAX_ARGS_IN_REGS - 1 && !targetm.calls.must_pass_in_stack (mode, type) && CRIS_FUNCTION_ARG_SIZE (mode, type) > 4 && CRIS_FUNCTION_ARG_SIZE (mode, type) <= 8) @@ -3846,11 +3772,13 @@ cris_arg_partial_bytes (CUMULATIVE_ARGS *ca, enum machine_mode mode, } static rtx -cris_function_arg_1 (const CUMULATIVE_ARGS *ca, +cris_function_arg_1 (cumulative_args_t ca_v, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named, bool incoming) { + const CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v); + if ((!incoming || named) && ca->regs < CRIS_MAX_ARGS_IN_REGS) return gen_rtx_REG (mode, CRIS_FIRST_ARG_REG + ca->regs); else @@ -3861,7 +3789,7 @@ cris_function_arg_1 (const CUMULATIVE_ARGS *ca, The void_type_node is sent as a "closing" call. */ static rtx -cris_function_arg (CUMULATIVE_ARGS *ca, enum machine_mode mode, +cris_function_arg (cumulative_args_t ca, enum machine_mode mode, const_tree type, bool named) { return cris_function_arg_1 (ca, mode, type, named, false); @@ -3875,7 +3803,7 @@ cris_function_arg (CUMULATIVE_ARGS *ca, enum machine_mode mode, void_type_node TYPE parameter. */ static rtx -cris_function_incoming_arg (CUMULATIVE_ARGS *ca, enum machine_mode mode, +cris_function_incoming_arg (cumulative_args_t ca, enum machine_mode mode, const_tree type, bool named) { return cris_function_arg_1 (ca, mode, type, named, true); @@ -3884,9 +3812,11 @@ cris_function_incoming_arg (CUMULATIVE_ARGS *ca, enum machine_mode mode, /* Worker function for TARGET_FUNCTION_ARG_ADVANCE. */ static void -cris_function_arg_advance (CUMULATIVE_ARGS *ca, enum machine_mode mode, +cris_function_arg_advance (cumulative_args_t ca_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v); + ca->regs += (3 + CRIS_FUNCTION_ARG_SIZE (mode, type)) / 4; } diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h index 150230df367..21092af66e2 100644 --- a/gcc/config/darwin-protos.h +++ b/gcc/config/darwin-protos.h @@ -40,6 +40,8 @@ extern rtx machopic_legitimize_pic_address (rtx, enum machine_mode, rtx); extern void machopic_asm_out_constructor (rtx, int); extern void machopic_asm_out_destructor (rtx, int); +extern section *machopic_select_rtx_section (enum machine_mode, rtx, + unsigned HOST_WIDE_INT); #endif /* RTX_CODE */ #ifdef TREE_CODE @@ -54,8 +56,6 @@ extern void machopic_finish (FILE *); extern int machopic_reloc_rw_mask (void); extern section *machopic_select_section (tree, int, unsigned HOST_WIDE_INT); -extern section *machopic_select_rtx_section (enum machine_mode, rtx, - unsigned HOST_WIDE_INT); extern section *darwin_function_section (tree, enum node_frequency, bool, bool); extern void darwin_function_switched_text_sections (FILE *, tree, bool); diff --git a/gcc/config/fr30/fr30.c b/gcc/config/fr30/fr30.c index 74585b5dc0c..e6a3712a3f9 100644 --- a/gcc/config/fr30/fr30.c +++ b/gcc/config/fr30/fr30.c @@ -1,6 +1,6 @@ /* FR30 specific functions. Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009, - 2010 Free Software Foundation, Inc. + 2010, 2011 Free Software Foundation, Inc. Contributed by Cygnus Solutions. This file is part of GCC. @@ -114,14 +114,14 @@ static struct fr30_frame_info current_frame_info; /* Zero structure to initialize current_frame_info. */ static struct fr30_frame_info zero_frame_info; -static void fr30_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, +static void fr30_setup_incoming_varargs (cumulative_args_t, enum machine_mode, tree, int *, int); static bool fr30_must_pass_in_stack (enum machine_mode, const_tree); -static int fr30_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, +static int fr30_arg_partial_bytes (cumulative_args_t, enum machine_mode, tree, bool); -static rtx fr30_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx fr30_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static void fr30_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void fr30_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); static bool fr30_frame_pointer_required (void); static rtx fr30_function_value (const_tree, const_tree, bool); @@ -150,13 +150,6 @@ static int fr30_num_arg_regs (enum machine_mode, const_tree); #if UNITS_PER_WORD == 4 #define WORD_ALIGN(SIZE) (((SIZE) + 3) & ~3) #endif - -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options fr30_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP @@ -198,12 +191,6 @@ static const struct default_options fr30_option_optimization_table[] = #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT fr30_trampoline_init -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info - -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE fr30_option_optimization_table - struct gcc_target targetm = TARGET_INITIALIZER; @@ -467,12 +454,14 @@ fr30_expand_epilogue (void) ARG_REGS_USED_SO_FAR has *not* been updated for the last named argument which has type TYPE and mode MODE, and we rely on this fact. */ void -fr30_setup_incoming_varargs (CUMULATIVE_ARGS *arg_regs_used_so_far, +fr30_setup_incoming_varargs (cumulative_args_t arg_regs_used_so_far_v, enum machine_mode mode, tree type ATTRIBUTE_UNUSED, int *pretend_size, int second_time ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *arg_regs_used_so_far + = get_cumulative_args (arg_regs_used_so_far_v); int size; /* All BLKmode values are passed by reference. */ @@ -480,9 +469,10 @@ fr30_setup_incoming_varargs (CUMULATIVE_ARGS *arg_regs_used_so_far, /* ??? This run-time test as well as the code inside the if statement is probably unnecessary. */ - if (targetm.calls.strict_argument_naming (arg_regs_used_so_far)) + if (targetm.calls.strict_argument_naming (arg_regs_used_so_far_v)) /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named arg must not be treated as an anonymous arg. */ + /* ??? This is a pointer increment, which makes no sense. */ arg_regs_used_so_far += fr30_num_arg_regs (mode, type); size = FR30_NUM_ARG_REGS - (* arg_regs_used_so_far); @@ -782,9 +772,11 @@ fr30_num_arg_regs (enum machine_mode mode, const_tree type) parameters to the function. */ static int -fr30_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, +fr30_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode, tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + /* Unnamed arguments, i.e. those that are prototyped as ... are always passed on the stack. Also check here to see if all the argument registers are full. */ @@ -804,9 +796,11 @@ fr30_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, } static rtx -fr30_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +fr30_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + if (!named || fr30_must_pass_in_stack (mode, type) || *cum >= FR30_NUM_ARG_REGS) @@ -824,10 +818,10 @@ fr30_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, the stack. The compiler knows how to track the amount of stack space used for arguments without any special help. */ static void -fr30_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +fr30_function_arg_advance (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named) { - *cum += named * fr30_num_arg_regs (mode, type); + *get_cumulative_args (cum) += named * fr30_num_arg_regs (mode, type); } /*}}}*/ diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index c16a9056eb8..cbd04f1c6ff 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -359,7 +359,7 @@ static void frv_init_libfuncs (void); static bool frv_in_small_data_p (const_tree); static void frv_asm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree); -static void frv_setup_incoming_varargs (CUMULATIVE_ARGS *, +static void frv_setup_incoming_varargs (cumulative_args_t, enum machine_mode, tree, int *, int); static rtx frv_expand_builtin_saveregs (void); @@ -380,13 +380,13 @@ static void frv_output_const_unspec (FILE *, static bool frv_function_ok_for_sibcall (tree, tree); static rtx frv_struct_value_rtx (tree, int); static bool frv_must_pass_in_stack (enum machine_mode mode, const_tree type); -static int frv_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, +static int frv_arg_partial_bytes (cumulative_args_t, enum machine_mode, tree, bool); -static rtx frv_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx frv_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static rtx frv_function_incoming_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx frv_function_incoming_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static void frv_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void frv_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); static unsigned int frv_function_arg_boundary (enum machine_mode, const_tree); @@ -400,20 +400,6 @@ static bool frv_can_eliminate (const int, const int); static void frv_conditional_register_usage (void); static void frv_trampoline_init (rtx, tree, rtx); static bool frv_class_likely_spilled_p (reg_class_t); - -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options frv_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - -/* Allow us to easily change the default for -malloc-cc. */ -#ifndef DEFAULT_NO_ALLOC_CC -#define MASK_DEFAULT_ALLOC_CC MASK_ALLOC_CC -#else -#define MASK_DEFAULT_ALLOC_CC 0 -#endif /* Initialize the GCC target structure. */ #undef TARGET_PRINT_OPERAND @@ -428,19 +414,8 @@ static const struct default_options frv_option_optimization_table[] = #define TARGET_ASM_FUNCTION_EPILOGUE frv_function_epilogue #undef TARGET_ASM_INTEGER #define TARGET_ASM_INTEGER frv_assemble_integer -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS \ - (MASK_DEFAULT_ALLOC_CC \ - | MASK_COND_MOVE \ - | MASK_SCC \ - | MASK_COND_EXEC \ - | MASK_VLIW_BRANCH \ - | MASK_MULTI_CE \ - | MASK_NESTED_CE) #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE frv_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE frv_option_optimization_table #undef TARGET_INIT_BUILTINS #define TARGET_INIT_BUILTINS frv_init_builtins #undef TARGET_EXPAND_BUILTIN @@ -2135,12 +2110,14 @@ frv_initial_elimination_offset (int from, int to) /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */ static void -frv_setup_incoming_varargs (CUMULATIVE_ARGS *cum, +frv_setup_incoming_varargs (cumulative_args_t cum_v, enum machine_mode mode, tree type ATTRIBUTE_UNUSED, int *pretend_size, int second_time) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + if (TARGET_DEBUG_ARG) fprintf (stderr, "setup_vararg: words = %2d, mode = %4s, pretend_size = %d, second_time = %d\n", @@ -3127,10 +3104,12 @@ frv_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED, } static rtx -frv_function_arg_1 (const CUMULATIVE_ARGS *cum, enum machine_mode mode, +frv_function_arg_1 (cumulative_args_t cum_v, enum machine_mode mode, const_tree type ATTRIBUTE_UNUSED, bool named, bool incoming ATTRIBUTE_UNUSED) { + const CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + enum machine_mode xmode = (mode == BLKmode) ? SImode : mode; int arg_num = *cum; rtx ret; @@ -3164,14 +3143,14 @@ frv_function_arg_1 (const CUMULATIVE_ARGS *cum, enum machine_mode mode, } static rtx -frv_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +frv_function_arg (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named) { return frv_function_arg_1 (cum, mode, type, named, false); } static rtx -frv_function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +frv_function_incoming_arg (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named) { return frv_function_arg_1 (cum, mode, type, named, true); @@ -3188,11 +3167,13 @@ frv_function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, for arguments without any special help. */ static void -frv_function_arg_advance (CUMULATIVE_ARGS *cum, +frv_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type ATTRIBUTE_UNUSED, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + enum machine_mode xmode = (mode == BLKmode) ? SImode : mode; int bytes = GET_MODE_SIZE (xmode); int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; @@ -3224,13 +3205,14 @@ frv_function_arg_advance (CUMULATIVE_ARGS *cum, the called function. */ static int -frv_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, +frv_arg_partial_bytes (cumulative_args_t cum, enum machine_mode mode, tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { + enum machine_mode xmode = (mode == BLKmode) ? SImode : mode; int bytes = GET_MODE_SIZE (xmode); int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; - int arg_num = *cum; + int arg_num = *get_cumulative_args (cum); int ret; ret = ((arg_num <= LAST_ARG_REGNUM && arg_num + words > LAST_ARG_REGNUM+1) diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index 28c232e3bc1..bf87417bc8b 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -309,17 +309,6 @@ enum h8_cpu H8_S }; -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ - -static const struct default_options h8300_option_optimization_table[] = - { - /* Basic block reordering is only beneficial on targets with cache - and/or variable-cycle branches where (cycle count taken != - cycle count not taken). */ - { OPT_LEVELS_ALL, OPT_freorder_blocks, NULL, 0 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - /* Initialize various cpu specific globals at start up. */ static void @@ -1042,9 +1031,11 @@ h8300_pr_saveall (struct cpp_reader *pfile ATTRIBUTE_UNUSED) case the first 3 arguments are passed in registers. */ static rtx -h8300_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +h8300_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + static const char *const hand_list[] = { "__main", "__cmpsi2", @@ -1113,9 +1104,11 @@ h8300_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, (TYPE is null for libcalls where that information may not be available.) */ static void -h8300_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +h8300_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + cum->nbytes += (mode != BLKmode ? (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD : (int_size_in_bytes (type) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD); @@ -5987,9 +5980,6 @@ h8300_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt) #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P h8300_legitimate_address_p -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT - #undef TARGET_CAN_ELIMINATE #define TARGET_CAN_ELIMINATE h8300_can_eliminate @@ -6002,12 +5992,6 @@ h8300_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt) #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE h8300_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE h8300_option_optimization_table - -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info - #undef TARGET_MODE_DEPENDENT_ADDRESS_P #define TARGET_MODE_DEPENDENT_ADDRESS_P h8300_mode_dependent_address_p diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index 4797460610e..db56e20cbbe 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -1767,7 +1767,8 @@ [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU") (and:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0") (match_operand:QI 2 "single_zero_operand" "Y0")))] - "TARGET_H8300SX" + "TARGET_H8300SX + && rtx_equal_p(operands[0], operands[1])" "bclr\\t%W2,%0" [(set_attr "length" "8")]) @@ -1800,29 +1801,31 @@ "TARGET_H8300SX" "bclr\\t%W2,%0" [(set_attr "length" "8")]) + (define_insn "*andqi3_2" - [(set (match_operand:QI 0 "bit_operand" "=rQ,r") - (and:QI (match_operand:QI 1 "bit_operand" "%0,WU") - (match_operand:QI 2 "h8300_src_operand" "rQi,IP1>X")))] + [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r") + (and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU") + (match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))] "TARGET_H8300SX" "@ - and %X2,%X0 - bfld %2,%1,%R0" - [(set_attr "length" "*,8") - (set_attr "length_table" "logicb,*") - (set_attr "cc" "set_znv,none_0hit")]) + bclr\\t %W2,%R0 + and %X2,%X0 + bfld %2,%1,%R0" + [(set_attr "length" "8,*,8") + (set_attr "length_table" "*,logicb,*") + (set_attr "cc" "none_0hit,set_znv,none_0hit")]) (define_insn "andqi3_1" - [(set (match_operand:QI 0 "bit_operand" "=r,U") + [(set (match_operand:QI 0 "bit_operand" "=U,r") (and:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "h8300_src_operand" "rn,n")))] + (match_operand:QI 2 "h8300_src_operand" "Y0,rn")))] "register_operand (operands[0], QImode) || single_zero_operand (operands[2], QImode)" "@ - and %X2,%X0 - bclr %W2,%R0" + bclr %W2,%R0 + and %X2,%X0" [(set_attr "length" "2,8") - (set_attr "cc" "set_znv,none_0hit")]) + (set_attr "cc" "none_0hit,set_znv")]) (define_expand "andqi3" [(set (match_operand:QI 0 "register_operand" "") @@ -1903,11 +1906,13 @@ ;; ---------------------------------------------------------------------- ;; OR INSTRUCTIONS ;; ---------------------------------------------------------------------- + (define_insn "bsetqi_msx" [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU") (ior:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0") (match_operand:QI 2 "single_one_operand" "Y2")))] - "TARGET_H8300SX" + "TARGET_H8300SX + && rtx_equal_p(operands[0], operands[1])" "bset\\t%V2,%0" [(set_attr "length" "8")]) @@ -1942,17 +1947,18 @@ [(set_attr "length" "8")]) (define_insn "iorqi3_1" - [(set (match_operand:QI 0 "bit_operand" "=rQ,U") + [(set (match_operand:QI 0 "bit_operand" "=U,rQ") (ior:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "h8300_src_operand" "rQi,n")))] + (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))] "TARGET_H8300SX || register_operand (operands[0], QImode) || single_one_operand (operands[2], QImode)" "@ - or\\t%X2,%X0 - bset\\t%V2,%R0" - [(set_attr "length" "*,8") - (set_attr "length_table" "logicb,*") - (set_attr "cc" "set_znv,none_0hit")]) + bset\\t%V2,%R0 + or\\t%X2,%X0" + [(set_attr "length" "8,*") + (set_attr "length_table" "*,logicb") + (set_attr "cc" "none_0hit,set_znv")]) + (define_expand "iorqi3" [(set (match_operand:QI 0 "register_operand" "") @@ -1982,7 +1988,8 @@ [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU") (xor:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0") (match_operand:QI 2 "single_one_operand" "Y2")))] - "TARGET_H8300SX" + "TARGET_H8300SX + && rtx_equal_p(operands[0], operands[1])" "bnot\\t%V2,%0" [(set_attr "length" "8")]) @@ -2017,17 +2024,18 @@ [(set_attr "length" "8")]) (define_insn "xorqi3_1" - [(set (match_operand:QI 0 "bit_operand" "=r,U") + [(set (match_operand:QI 0 "bit_operand" "=U,r") (xor:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "h8300_src_operand" "rQi,n")))] + (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))] "TARGET_H8300SX || register_operand (operands[0], QImode) || single_one_operand (operands[2], QImode)" "@ - xor\\t%X2,%X0 - bnot\\t%V2,%R0" - [(set_attr "length" "*,8") - (set_attr "length_table" "logicb,*") - (set_attr "cc" "set_znv,none_0hit")]) + bnot\\t%V2,%R0 + xor\\t%X2,%X0" + [(set_attr "length" "8,*") + (set_attr "length_table" "*,logicb") + (set_attr "cc" "none_0hit,set_znv")]) + (define_expand "xorqi3" [(set (match_operand:QI 0 "register_operand" "") diff --git a/gcc/config/i386/gnu-user64.h b/gcc/config/i386/gnu-user64.h index 3ece0faa6df..b069975ef19 100644 --- a/gcc/config/i386/gnu-user64.h +++ b/gcc/config/i386/gnu-user64.h @@ -69,7 +69,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see %{!mno-sse2avx:%{mavx:-msse2avx}} %{msse2avx:%{!mavx:-msse2avx}}" #undef LINK_SPEC -#define LINK_SPEC "%{" SPEC_64 ":-m elf_x86_64} %{" SPEC_32 ":-m elf_i386} \ +#define LINK_SPEC "%{" SPEC_64 ":-m " GNU_USER_LINK_EMULATION64 "} \ + %{" SPEC_32 ":-m " GNU_USER_LINK_EMULATION32 "} \ %{shared:-shared} \ %{!shared: \ %{!static: \ diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 5643153ac39..83f39dcc784 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GCC for IA-32. Copyright (C) 1988, 1992, 1994, 1995, 1996, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -19,6 +19,12 @@ 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/>. */ +/* In i386-common.c. */ +extern bool ix86_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc); + /* Functions in i386.c */ extern bool ix86_target_stack_probe (void); extern bool ix86_can_use_return_insn_p (void); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 7b266b93f83..6029010d904 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include "ggc.h" #include "target.h" #include "target-def.h" +#include "common/common-target.h" #include "langhooks.h" #include "cgraph.h" #include "gimple.h" @@ -2461,120 +2462,6 @@ static enum calling_abi ix86_function_abi (const_tree); static int ix86_tune_defaulted; static int ix86_arch_specified; -/* Define a set of ISAs which are available when a given ISA is - enabled. MMX and SSE ISAs are handled separately. */ - -#define OPTION_MASK_ISA_MMX_SET OPTION_MASK_ISA_MMX -#define OPTION_MASK_ISA_3DNOW_SET \ - (OPTION_MASK_ISA_3DNOW | OPTION_MASK_ISA_MMX_SET) - -#define OPTION_MASK_ISA_SSE_SET OPTION_MASK_ISA_SSE -#define OPTION_MASK_ISA_SSE2_SET \ - (OPTION_MASK_ISA_SSE2 | OPTION_MASK_ISA_SSE_SET) -#define OPTION_MASK_ISA_SSE3_SET \ - (OPTION_MASK_ISA_SSE3 | OPTION_MASK_ISA_SSE2_SET) -#define OPTION_MASK_ISA_SSSE3_SET \ - (OPTION_MASK_ISA_SSSE3 | OPTION_MASK_ISA_SSE3_SET) -#define OPTION_MASK_ISA_SSE4_1_SET \ - (OPTION_MASK_ISA_SSE4_1 | OPTION_MASK_ISA_SSSE3_SET) -#define OPTION_MASK_ISA_SSE4_2_SET \ - (OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_SSE4_1_SET) -#define OPTION_MASK_ISA_AVX_SET \ - (OPTION_MASK_ISA_AVX | OPTION_MASK_ISA_SSE4_2_SET) -#define OPTION_MASK_ISA_FMA_SET \ - (OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_AVX_SET) - -/* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same - as -msse4.2. */ -#define OPTION_MASK_ISA_SSE4_SET OPTION_MASK_ISA_SSE4_2_SET - -#define OPTION_MASK_ISA_SSE4A_SET \ - (OPTION_MASK_ISA_SSE4A | OPTION_MASK_ISA_SSE3_SET) -#define OPTION_MASK_ISA_FMA4_SET \ - (OPTION_MASK_ISA_FMA4 | OPTION_MASK_ISA_SSE4A_SET \ - | OPTION_MASK_ISA_AVX_SET) -#define OPTION_MASK_ISA_XOP_SET \ - (OPTION_MASK_ISA_XOP | OPTION_MASK_ISA_FMA4_SET) -#define OPTION_MASK_ISA_LWP_SET \ - OPTION_MASK_ISA_LWP - -/* AES and PCLMUL need SSE2 because they use xmm registers */ -#define OPTION_MASK_ISA_AES_SET \ - (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2_SET) -#define OPTION_MASK_ISA_PCLMUL_SET \ - (OPTION_MASK_ISA_PCLMUL | OPTION_MASK_ISA_SSE2_SET) - -#define OPTION_MASK_ISA_ABM_SET \ - (OPTION_MASK_ISA_ABM | OPTION_MASK_ISA_POPCNT) - -#define OPTION_MASK_ISA_BMI_SET OPTION_MASK_ISA_BMI -#define OPTION_MASK_ISA_TBM_SET OPTION_MASK_ISA_TBM -#define OPTION_MASK_ISA_POPCNT_SET OPTION_MASK_ISA_POPCNT -#define OPTION_MASK_ISA_CX16_SET OPTION_MASK_ISA_CX16 -#define OPTION_MASK_ISA_SAHF_SET OPTION_MASK_ISA_SAHF -#define OPTION_MASK_ISA_MOVBE_SET OPTION_MASK_ISA_MOVBE -#define OPTION_MASK_ISA_CRC32_SET OPTION_MASK_ISA_CRC32 - -#define OPTION_MASK_ISA_FSGSBASE_SET OPTION_MASK_ISA_FSGSBASE -#define OPTION_MASK_ISA_RDRND_SET OPTION_MASK_ISA_RDRND -#define OPTION_MASK_ISA_F16C_SET \ - (OPTION_MASK_ISA_F16C | OPTION_MASK_ISA_AVX_SET) - -/* Define a set of ISAs which aren't available when a given ISA is - disabled. MMX and SSE ISAs are handled separately. */ - -#define OPTION_MASK_ISA_MMX_UNSET \ - (OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_3DNOW_UNSET) -#define OPTION_MASK_ISA_3DNOW_UNSET \ - (OPTION_MASK_ISA_3DNOW | OPTION_MASK_ISA_3DNOW_A_UNSET) -#define OPTION_MASK_ISA_3DNOW_A_UNSET OPTION_MASK_ISA_3DNOW_A - -#define OPTION_MASK_ISA_SSE_UNSET \ - (OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_SSE2_UNSET) -#define OPTION_MASK_ISA_SSE2_UNSET \ - (OPTION_MASK_ISA_SSE2 | OPTION_MASK_ISA_SSE3_UNSET) -#define OPTION_MASK_ISA_SSE3_UNSET \ - (OPTION_MASK_ISA_SSE3 \ - | OPTION_MASK_ISA_SSSE3_UNSET \ - | OPTION_MASK_ISA_SSE4A_UNSET ) -#define OPTION_MASK_ISA_SSSE3_UNSET \ - (OPTION_MASK_ISA_SSSE3 | OPTION_MASK_ISA_SSE4_1_UNSET) -#define OPTION_MASK_ISA_SSE4_1_UNSET \ - (OPTION_MASK_ISA_SSE4_1 | OPTION_MASK_ISA_SSE4_2_UNSET) -#define OPTION_MASK_ISA_SSE4_2_UNSET \ - (OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_AVX_UNSET ) -#define OPTION_MASK_ISA_AVX_UNSET \ - (OPTION_MASK_ISA_AVX | OPTION_MASK_ISA_FMA_UNSET \ - | OPTION_MASK_ISA_FMA4_UNSET | OPTION_MASK_ISA_F16C_UNSET) -#define OPTION_MASK_ISA_FMA_UNSET OPTION_MASK_ISA_FMA - -/* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same - as -mno-sse4.1. */ -#define OPTION_MASK_ISA_SSE4_UNSET OPTION_MASK_ISA_SSE4_1_UNSET - -#define OPTION_MASK_ISA_SSE4A_UNSET \ - (OPTION_MASK_ISA_SSE4A | OPTION_MASK_ISA_FMA4_UNSET) - -#define OPTION_MASK_ISA_FMA4_UNSET \ - (OPTION_MASK_ISA_FMA4 | OPTION_MASK_ISA_XOP_UNSET) -#define OPTION_MASK_ISA_XOP_UNSET OPTION_MASK_ISA_XOP -#define OPTION_MASK_ISA_LWP_UNSET OPTION_MASK_ISA_LWP - -#define OPTION_MASK_ISA_AES_UNSET OPTION_MASK_ISA_AES -#define OPTION_MASK_ISA_PCLMUL_UNSET OPTION_MASK_ISA_PCLMUL -#define OPTION_MASK_ISA_ABM_UNSET OPTION_MASK_ISA_ABM -#define OPTION_MASK_ISA_BMI_UNSET OPTION_MASK_ISA_BMI -#define OPTION_MASK_ISA_TBM_UNSET OPTION_MASK_ISA_TBM -#define OPTION_MASK_ISA_POPCNT_UNSET OPTION_MASK_ISA_POPCNT -#define OPTION_MASK_ISA_CX16_UNSET OPTION_MASK_ISA_CX16 -#define OPTION_MASK_ISA_SAHF_UNSET OPTION_MASK_ISA_SAHF -#define OPTION_MASK_ISA_MOVBE_UNSET OPTION_MASK_ISA_MOVBE -#define OPTION_MASK_ISA_CRC32_UNSET OPTION_MASK_ISA_CRC32 - -#define OPTION_MASK_ISA_FSGSBASE_UNSET OPTION_MASK_ISA_FSGSBASE -#define OPTION_MASK_ISA_RDRND_UNSET OPTION_MASK_ISA_RDRND -#define OPTION_MASK_ISA_F16C_UNSET OPTION_MASK_ISA_F16C - /* Vectorization library interface and handlers. */ static tree (*ix86_veclib_handler) (enum built_in_function, tree, tree); @@ -2656,427 +2543,6 @@ ix86_using_red_zone (void) { return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI; } - -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -ix86_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc) -{ - size_t code = decoded->opt_index; - int value = decoded->value; - - switch (code) - { - case OPT_mmmx: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_MMX_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_MMX_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_MMX_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_MMX_UNSET; - } - return true; - - case OPT_m3dnow: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_3DNOW_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_3DNOW_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_3DNOW_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_3DNOW_UNSET; - } - return true; - - case OPT_m3dnowa: - return false; - - case OPT_msse: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE_UNSET; - } - return true; - - case OPT_msse2: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE2_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE2_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE2_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE2_UNSET; - } - return true; - - case OPT_msse3: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE3_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE3_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE3_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE3_UNSET; - } - return true; - - case OPT_mssse3: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSSE3_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSSE3_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSSE3_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSSE3_UNSET; - } - return true; - - case OPT_msse4_1: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE4_1_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_1_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE4_1_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_1_UNSET; - } - return true; - - case OPT_msse4_2: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE4_2_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_2_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE4_2_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_2_UNSET; - } - return true; - - case OPT_mavx: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX_UNSET; - } - return true; - - case OPT_mfma: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_FMA_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_FMA_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_FMA_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_FMA_UNSET; - } - return true; - - case OPT_msse4: - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE4_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_SET; - return true; - - case OPT_mno_sse4: - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE4_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4_UNSET; - return true; - - case OPT_msse4a: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SSE4A_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4A_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SSE4A_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE4A_UNSET; - } - return true; - - case OPT_mfma4: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_FMA4_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_FMA4_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_FMA4_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_FMA4_UNSET; - } - return true; - - case OPT_mxop: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_XOP_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_XOP_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_XOP_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_XOP_UNSET; - } - return true; - - case OPT_mlwp: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_LWP_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_LWP_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_LWP_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_LWP_UNSET; - } - return true; - - case OPT_mabm: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_ABM_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_ABM_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_ABM_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_ABM_UNSET; - } - return true; - - case OPT_mbmi: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_BMI_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_BMI_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_BMI_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_BMI_UNSET; - } - return true; - - case OPT_mtbm: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_TBM_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_TBM_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_TBM_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_TBM_UNSET; - } - return true; - - case OPT_mpopcnt: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_POPCNT_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_POPCNT_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_POPCNT_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_POPCNT_UNSET; - } - return true; - - case OPT_msahf: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_SAHF_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SAHF_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_SAHF_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_SAHF_UNSET; - } - return true; - - case OPT_mcx16: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_CX16_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_CX16_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_CX16_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_CX16_UNSET; - } - return true; - - case OPT_mmovbe: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_MOVBE_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVBE_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_MOVBE_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVBE_UNSET; - } - return true; - - case OPT_mcrc32: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_CRC32_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_CRC32_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_CRC32_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_CRC32_UNSET; - } - return true; - - case OPT_maes: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AES_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AES_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AES_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AES_UNSET; - } - return true; - - case OPT_mpclmul: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_PCLMUL_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_PCLMUL_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_PCLMUL_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_PCLMUL_UNSET; - } - return true; - - case OPT_mfsgsbase: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_FSGSBASE_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_FSGSBASE_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_FSGSBASE_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_FSGSBASE_UNSET; - } - return true; - - case OPT_mrdrnd: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_RDRND_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_RDRND_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_RDRND_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_RDRND_UNSET; - } - return true; - - case OPT_mf16c: - if (value) - { - opts->x_ix86_isa_flags |= OPTION_MASK_ISA_F16C_SET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_F16C_SET; - } - else - { - opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_F16C_UNSET; - opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_F16C_UNSET; - } - return true; - - /* Comes from final.c -- no real reason to change it. */ -#define MAX_CODE_ALIGN 16 - - case OPT_malign_loops_: - warning_at (loc, 0, "-malign-loops is obsolete, use -falign-loops"); - if (value > MAX_CODE_ALIGN) - error_at (loc, "-malign-loops=%d is not between 0 and %d", - value, MAX_CODE_ALIGN); - else - opts->x_align_loops = 1 << value; - return true; - - case OPT_malign_jumps_: - warning_at (loc, 0, "-malign-jumps is obsolete, use -falign-jumps"); - if (value > MAX_CODE_ALIGN) - error_at (loc, "-malign-jumps=%d is not between 0 and %d", - value, MAX_CODE_ALIGN); - else - opts->x_align_jumps = 1 << value; - return true; - - case OPT_malign_functions_: - warning_at (loc, 0, - "-malign-functions is obsolete, use -falign-functions"); - if (value > MAX_CODE_ALIGN) - error_at (loc, "-malign-functions=%d is not between 0 and %d", - value, MAX_CODE_ALIGN); - else - opts->x_align_functions = 1 << value; - return true; - - case OPT_mbranch_cost_: - if (value > 5) - { - error_at (loc, "-mbranch-cost=%d is not between 0 and 5", value); - opts->x_ix86_branch_cost = 5; - } - return true; - - default: - return true; - } -} /* Return a string that documents the current -m options. The caller is responsible for freeing the string. */ @@ -5092,35 +4558,6 @@ x86_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED, ASM_OUTPUT_SKIP (file, size ? size : 1); } -static const struct default_options ix86_option_optimization_table[] = - { - /* Turn off -fschedule-insns by default. It tends to make the - problem with not enough registers even worse. */ -#ifdef INSN_SCHEDULING - { OPT_LEVELS_ALL, OPT_fschedule_insns, NULL, 0 }, -#endif - -#ifdef SUBTARGET_OPTIMIZATION_OPTIONS - SUBTARGET_OPTIMIZATION_OPTIONS, -#endif - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - -/* Implement TARGET_OPTION_INIT_STRUCT. */ - -static void -ix86_option_init_struct (struct gcc_options *opts) -{ - if (TARGET_MACHO) - /* The Darwin libraries never set errno, so we might as well - avoid calling them when that's the only reason we would. */ - opts->x_flag_errno_math = 0; - - opts->x_flag_pcc_struct_return = 2; - opts->x_flag_asynchronous_unwind_tables = 2; - opts->x_flag_vect_cost_model = 1; -} - /* Decide whether we must probe the stack before any space allocation on this target. It's essentially TARGET_STACK_PROBE except when -fstack-check causes the stack to be already probed differently. */ @@ -6901,9 +6338,10 @@ function_arg_advance_ms_64 (CUMULATIVE_ARGS *cum, HOST_WIDE_INT bytes, may not be available.) */ static void -ix86_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +ix86_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); HOST_WIDE_INT bytes, words; if (mode == BLKmode) @@ -7148,9 +6586,10 @@ function_arg_ms_64 (const CUMULATIVE_ARGS *cum, enum machine_mode mode, ellipsis). */ static rtx -ix86_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode omode, +ix86_function_arg (cumulative_args_t cum_v, enum machine_mode omode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); enum machine_mode mode = omode; HOST_WIDE_INT bytes, words; rtx arg; @@ -7192,10 +6631,12 @@ ix86_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode omode, appropriate for passing a pointer to that type. */ static bool -ix86_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +ix86_pass_by_reference (cumulative_args_t cum_v ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + /* See Windows x64 Software Convention. */ if (TARGET_64BIT && (cum ? cum->call_abi : ix86_abi) == MS_ABI) { @@ -7943,10 +7384,11 @@ setup_incoming_varargs_ms_64 (CUMULATIVE_ARGS *cum) } static void -ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, +ix86_setup_incoming_varargs (cumulative_args_t cum_v, enum machine_mode mode, tree type, int *pretend_size ATTRIBUTE_UNUSED, int no_rtl) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); CUMULATIVE_ARGS next_cum; tree fntype; @@ -7963,7 +7405,8 @@ ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, For stdargs, we do want to skip the last named argument. */ next_cum = *cum; if (stdarg_p (fntype)) - ix86_function_arg_advance (&next_cum, mode, type, true); + ix86_function_arg_advance (pack_cumulative_args (&next_cum), mode, type, + true); if (cum->call_abi == MS_ABI) setup_incoming_varargs_ms_64 (&next_cum); @@ -9142,32 +8585,6 @@ ix86_builtin_setjmp_frame_value (void) return stack_realign_fp ? hard_frame_pointer_rtx : virtual_stack_vars_rtx; } -/* On the x86 -fsplit-stack and -fstack-protector both use the same - field in the TCB, so they can not be used together. */ - -static bool -ix86_supports_split_stack (bool report ATTRIBUTE_UNUSED, - struct gcc_options *opts ATTRIBUTE_UNUSED) -{ - bool ret = true; - -#ifndef TARGET_THREAD_SPLIT_STACK_OFFSET - if (report) - error ("%<-fsplit-stack%> currently only supported on GNU/Linux"); - ret = false; -#else - if (!HAVE_GAS_CFI_PERSONALITY_DIRECTIVE) - { - if (report) - error ("%<-fsplit-stack%> requires " - "assembler support for CFI directives"); - ret = false; - } -#endif - - return ret; -} - /* When using -fsplit-stack, the allocation routines set a field in the TCB to the bottom of the stack plus this much space, measured in bytes. */ @@ -26149,16 +25566,61 @@ ix86_expand_multi_arg_builtin (enum insn_code icode, tree exp, rtx target, int adjust = (comparison_p) ? 1 : 0; enum machine_mode mode = insn_data[icode].operand[i+adjust+1].mode; - if (last_arg_constant && i == nargs-1) + if (last_arg_constant && i == nargs - 1) { - if (!CONST_INT_P (op)) + if (!insn_data[icode].operand[i + 1].predicate (op, mode)) { - error ("last argument must be an immediate"); - return gen_reg_rtx (tmode); + enum insn_code new_icode = icode; + switch (icode) + { + case CODE_FOR_xop_vpermil2v2df3: + case CODE_FOR_xop_vpermil2v4sf3: + case CODE_FOR_xop_vpermil2v4df3: + case CODE_FOR_xop_vpermil2v8sf3: + error ("the last argument must be a 2-bit immediate"); + return gen_reg_rtx (tmode); + case CODE_FOR_xop_rotlv2di3: + new_icode = CODE_FOR_rotlv2di3; + goto xop_rotl; + case CODE_FOR_xop_rotlv4si3: + new_icode = CODE_FOR_rotlv4si3; + goto xop_rotl; + case CODE_FOR_xop_rotlv8hi3: + new_icode = CODE_FOR_rotlv8hi3; + goto xop_rotl; + case CODE_FOR_xop_rotlv16qi3: + new_icode = CODE_FOR_rotlv16qi3; + xop_rotl: + if (CONST_INT_P (op)) + { + int mask = GET_MODE_BITSIZE (GET_MODE_INNER (tmode)) - 1; + op = GEN_INT (INTVAL (op) & mask); + gcc_checking_assert + (insn_data[icode].operand[i + 1].predicate (op, mode)); + } + else + { + gcc_checking_assert + (nargs == 2 + && insn_data[new_icode].operand[0].mode == tmode + && insn_data[new_icode].operand[1].mode == tmode + && insn_data[new_icode].operand[2].mode == mode + && insn_data[new_icode].operand[0].predicate + == insn_data[icode].operand[0].predicate + && insn_data[new_icode].operand[1].predicate + == insn_data[icode].operand[1].predicate); + icode = new_icode; + goto non_constant; + } + break; + default: + gcc_unreachable (); + } } } else { + non_constant: if (VECTOR_MODE_P (mode)) op = safe_vector_operand (op, mode); @@ -26483,7 +25945,7 @@ ix86_expand_sse_pcmpestr (const struct builtin_description *d, if (!insn_data[d->icode].operand[6].predicate (op4, modeimm)) { - error ("the fifth argument must be a 8-bit immediate"); + error ("the fifth argument must be an 8-bit immediate"); return const0_rtx; } @@ -26578,7 +26040,7 @@ ix86_expand_sse_pcmpistr (const struct builtin_description *d, if (!insn_data[d->icode].operand[4].predicate (op2, modeimm)) { - error ("the third argument must be a 8-bit immediate"); + error ("the third argument must be an 8-bit immediate"); return const0_rtx; } @@ -35297,21 +34759,8 @@ ix86_autovectorize_vector_sizes (void) #undef TARGET_ASM_FILE_START #define TARGET_ASM_FILE_START x86_file_start -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS \ - (TARGET_DEFAULT \ - | TARGET_SUBTARGET_DEFAULT \ - | TARGET_TLS_DIRECT_SEG_REFS_DEFAULT) - -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION ix86_handle_option - #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE ix86_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE ix86_option_optimization_table -#undef TARGET_OPTION_INIT_STRUCT -#define TARGET_OPTION_INIT_STRUCT ix86_option_init_struct #undef TARGET_REGISTER_MOVE_COST #define TARGET_REGISTER_MOVE_COST ix86_register_move_cost @@ -35412,9 +34861,6 @@ ix86_autovectorize_vector_sizes (void) #define TARGET_STACK_PROTECT_FAIL ix86_stack_protect_fail #endif -#undef TARGET_SUPPORTS_SPLIT_STACK -#define TARGET_SUPPORTS_SPLIT_STACK ix86_supports_split_stack - #undef TARGET_FUNCTION_VALUE #define TARGET_FUNCTION_VALUE ix86_function_value diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index b01435ce2c3..204cb4fa9c8 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -2151,7 +2151,7 @@ [(set (attr "isa") (if_then_else (eq_attr "alternative" "9,10,11,12") (const_string "noavx") - (const_string "base"))) + (const_string "*"))) (set (attr "type") (cond [(eq_attr "alternative" "0,1") (const_string "multi") @@ -12700,7 +12700,7 @@ (if_then_else (match_operand:MODEF 3 "mult_operator" "") (const_string "fmul") (const_string "fop")))) - (set_attr "isa" "base,noavx,avx") + (set_attr "isa" "*,noavx,avx") (set_attr "prefix" "orig,orig,vex") (set_attr "mode" "<MODE>")]) @@ -12760,7 +12760,7 @@ (const_string "fdiv") ] (const_string "fop"))) - (set_attr "isa" "base,base,noavx,avx") + (set_attr "isa" "*,*,noavx,avx") (set_attr "prefix" "orig,orig,orig,vex") (set_attr "mode" "<MODE>")]) diff --git a/gcc/config/i386/kfreebsd-gnu.h b/gcc/config/i386/kfreebsd-gnu.h index 52ee09b0931..b8c509a502d 100644 --- a/gcc/config/i386/kfreebsd-gnu.h +++ b/gcc/config/i386/kfreebsd-gnu.h @@ -1,5 +1,5 @@ /* Definitions for Intel 386 running kFreeBSD-based GNU systems with ELF format - Copyright (C) 2004, 2007, 2011 + Copyright (C) 2011 Free Software Foundation, Inc. Contributed by Robert Millan. @@ -19,11 +19,5 @@ 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/>. */ -#undef GNU_USER_LINK_EMULATION #define GNU_USER_LINK_EMULATION "elf_i386_fbsd" - -#undef GNU_USER_DYNAMIC_LINKER32 -#define GNU_USER_DYNAMIC_LINKER32 "/lib/ld.so.1" - -#undef GNU_USER_DYNAMIC_LINKER64 -#define GNU_USER_DYNAMIC_LINKER64 "/lib/ld-kfreebsd-x86-64.so.1" +#define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1" diff --git a/gcc/config/i386/kfreebsd-gnu64.h b/gcc/config/i386/kfreebsd-gnu64.h new file mode 100644 index 00000000000..c3798a5c591 --- /dev/null +++ b/gcc/config/i386/kfreebsd-gnu64.h @@ -0,0 +1,26 @@ +/* Definitions for AMD x86-64 running kFreeBSD-based GNU systems with ELF format + Copyright (C) 2011 + Free Software Foundation, Inc. + Contributed by Robert Millan. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#define GNU_USER_LINK_EMULATION32 "elf_i386_fbsd" +#define GNU_USER_LINK_EMULATION64 "elf_x86_64_fbsd" + +#define GLIBC_DYNAMIC_LINKER32 "/lib/ld.so.1" +#define GLIBC_DYNAMIC_LINKER64 "/lib/ld-kfreebsd-x86-64.so.1" diff --git a/gcc/config/i386/linux64.h b/gcc/config/i386/linux64.h index 9bf7eab04af..5d332246cb5 100644 --- a/gcc/config/i386/linux64.h +++ b/gcc/config/i386/linux64.h @@ -24,5 +24,8 @@ a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ +#define GNU_USER_LINK_EMULATION32 "elf_i386" +#define GNU_USER_LINK_EMULATION64 "elf_x86_64" + #define GLIBC_DYNAMIC_LINKER32 "/lib/ld-linux.so.2" #define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2" diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index f56fb227b1a..f3b949ef02a 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -85,7 +85,19 @@ %vmovq\t{%1, %0|%0, %1} %vmovd\t{%1, %0|%0, %1} %vmovd\t{%1, %0|%0, %1}" - [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,ssemov") + [(set (attr "type") + (cond [(eq_attr "alternative" "0,1") + (const_string "imov") + (eq_attr "alternative" "2") + (const_string "mmx") + (eq_attr "alternative" "3,4,5") + (const_string "mmxmov") + (eq_attr "alternative" "6,7") + (const_string "ssecvt") + (eq_attr "alternative" "8") + (const_string "sselog1") + ] + (const_string "ssemov"))) (set_attr "unit" "*,*,*,*,*,*,mmx,mmx,*,*,*,*,*") (set_attr "prefix_rep" "*,*,*,*,*,*,1,1,*,1,*,*,*") (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,1,1,1") @@ -125,8 +137,20 @@ [(set (attr "isa") (if_then_else (eq_attr "alternative" "9,10,11,12") (const_string "noavx") - (const_string "base"))) - (set_attr "type" "mmx,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov,*,*") + (const_string "*"))) + (set (attr "type") + (cond [(eq_attr "alternative" "0") + (const_string "mmx") + (eq_attr "alternative" "1,2,3") + (const_string "mmxmov") + (eq_attr "alternative" "4,5") + (const_string "ssecvt") + (eq_attr "alternative" "6,9") + (const_string "sselog1") + (eq_attr "alternative" "13,14") + (const_string "multi") + ] + (const_string "ssemov"))) (set_attr "unit" "*,*,*,*,mmx,mmx,*,*,*,*,*,*,*,*,*") (set (attr "prefix_rep") (if_then_else @@ -179,7 +203,19 @@ %vmovlps\t{%1, %0|%0, %1} %vmovd\t{%1, %0|%0, %1} %vmovd\t{%1, %0|%0, %1}" - [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov") + [(set (attr "type") + (cond [(eq_attr "alternative" "0,1") + (const_string "imov") + (eq_attr "alternative" "2") + (const_string "mmx") + (eq_attr "alternative" "3,4,5") + (const_string "mmxmov") + (eq_attr "alternative" "6,7") + (const_string "ssecvt") + (eq_attr "alternative" "9") + (const_string "sselog1") + ] + (const_string "ssemov"))) (set_attr "unit" "*,*,*,*,*,*,mmx,mmx,*,*,*,*,*,*") (set_attr "prefix_rep" "*,*,*,*,*,*,1,1,*,*,*,*,*,*") (set (attr "length_vex") @@ -214,7 +250,19 @@ %vmovlps\t{%1, %0|%0, %1} # #" - [(set_attr "type" "mmx,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*") + [(set (attr "type") + (cond [(eq_attr "alternative" "0") + (const_string "mmx") + (eq_attr "alternative" "1,2,3") + (const_string "mmxmov") + (eq_attr "alternative" "4,5") + (const_string "ssecvt") + (eq_attr "alternative" "6") + (const_string "sselog1") + (eq_attr "alternative" "10,11") + (const_string "multi") + ] + (const_string "ssemov"))) (set_attr "unit" "*,*,*,*,mmx,mmx,*,*,*,*,*,*") (set_attr "prefix_rep" "*,*,*,*,1,1,*,*,*,*,*,*") (set (attr "prefix") @@ -228,8 +276,8 @@ [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "") (match_operand:MMXMODE 1 "general_operand" ""))] "!TARGET_64BIT && reload_completed - && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0])) - && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" + && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]) + || MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))" [(const_int 0)] "ix86_split_long_move (operands); DONE;") diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index b3982af5ec0..7abee333ef2 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -185,10 +185,13 @@ ;; Mix-n-match (define_mode_iterator AVX256MODE2P [V8SI V8SF V4DF]) -(define_mode_iterator AVX256MODE24P [V8SI V8SF V4DI V4DF]) (define_mode_iterator FMAMODE [SF DF V4SF V2DF V8SF V4DF]) +;; Mapping of immediate bits for blend instructions +(define_mode_attr blendbits + [(V8SF "255") (V4SF "15") (V4DF "15") (V2DF "3")]) + ;; Patterns whose name begins with "sse{,2,3}_" are invoked by intrinsics. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2792,7 +2795,7 @@ movlps\t{%H2, %0|%0, %H2} vmovlps\t{%H2, %1, %0|%0, %1, %H2} %vmovhps\t{%2, %0|%0, %2}" - [(set_attr "isa" "noavx,avx,noavx,avx,base") + [(set_attr "isa" "noavx,avx,noavx,avx,*") (set_attr "type" "ssemov") (set_attr "prefix" "orig,vex,orig,vex,maybe_vex") (set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")]) @@ -2837,7 +2840,7 @@ movhps\t{%2, %0|%0, %2} vmovhps\t{%2, %1, %0|%0, %1, %2} %vmovlps\t{%2, %H0|%H0, %2}" - [(set_attr "isa" "noavx,avx,noavx,avx,base") + [(set_attr "isa" "noavx,avx,noavx,avx,*") (set_attr "type" "ssemov") (set_attr "prefix" "orig,vex,orig,vex,maybe_vex") (set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")]) @@ -3200,7 +3203,7 @@ movlhps\t{%2, %0|%0, %2} vmovlhps\t{%2, %1, %0|%0, %1, %2} %vmovlps\t{%2, %H0|%H0, %2}" - [(set_attr "isa" "noavx,avx,noavx,avx,base") + [(set_attr "isa" "noavx,avx,noavx,avx,*") (set_attr "type" "ssemov") (set_attr "prefix" "orig,vex,orig,vex,maybe_vex") (set_attr "mode" "V2SF,V2SF,V4SF,V4SF,V2SF")]) @@ -3253,7 +3256,7 @@ movlps\t{%2, %0|%0, %2} vmovlps\t{%2, %1, %0|%0, %1, %2} %vmovlps\t{%2, %0|%0, %2}" - [(set_attr "isa" "noavx,avx,noavx,avx,base") + [(set_attr "isa" "noavx,avx,noavx,avx,*") (set_attr "type" "sselog,sselog,ssemov,ssemov,ssemov") (set_attr "length_immediate" "1,1,*,*,*") (set_attr "prefix" "orig,vex,orig,vex,maybe_vex") @@ -3281,7 +3284,7 @@ "TARGET_SSE" { if (!TARGET_AVX) - operands[1] = force_reg (V4SFmode, operands[1]); + operands[1] = force_reg (SFmode, operands[1]); }) (define_insn "*vec_dupv4sf_avx" @@ -3324,7 +3327,7 @@ %vmovss\t{%1, %0|%0, %1} punpckldq\t{%2, %0|%0, %2} movd\t{%1, %0|%0, %1}" - [(set_attr "isa" "noavx,avx,noavx,avx,base,base,base") + [(set_attr "isa" "noavx,avx,noavx,avx,*,*,*") (set_attr "type" "sselog,sselog,sselog,sselog,ssemov,mmxcvt,mmxmov") (set_attr "prefix_data16" "*,*,1,*,*,*,*") (set_attr "prefix_extra" "*,*,1,1,*,*,*") @@ -3378,11 +3381,11 @@ ;; see comment above inline_secondary_memory_needed function in i386.c (define_insn "vec_set<mode>_0" [(set (match_operand:VI4F_128 0 "nonimmediate_operand" - "=Y4,Y2,Y2,x,x,x,Y4 ,x ,m,m,m") + "=Y4,Y2,Y2,x,x,x,Y4 ,x ,m,m ,m") (vec_merge:VI4F_128 (vec_duplicate:VI4F_128 (match_operand:<ssescalarmode> 2 "general_operand" - " Y4,m ,*r,m,x,x,*rm,*rm,x,*r,fF")) + " Y4,m ,*r,m,x,x,*rm,*rm,x,fF,*r")) (match_operand:VI4F_128 1 "vector_move_operand" " C ,C ,C ,C,0,x,0 ,x ,0,0 ,0") (const_int 1)))] @@ -3399,8 +3402,16 @@ # # #" - [(set_attr "isa" "base,base,base,noavx,noavx,avx,noavx,avx,base,base,base") - (set_attr "type" "sselog,ssemov,ssemov,ssemov,ssemov,ssemov,sselog,sselog,*,*,*") + [(set_attr "isa" "*,*,*,noavx,noavx,avx,noavx,avx,*,*,*") + (set (attr "type") + (cond [(eq_attr "alternative" "0,6,7") + (const_string "sselog") + (eq_attr "alternative" "9") + (const_string "fmov") + (eq_attr "alternative" "10") + (const_string "imov") + ] + (const_string "ssemov"))) (set_attr "prefix_extra" "*,*,*,*,*,*,1,1,*,*,*") (set_attr "length_immediate" "*,*,*,*,*,*,1,1,*,*,*") (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,orig,orig,vex,orig,vex,*,*,*") @@ -3820,7 +3831,7 @@ movlpd\t{%H1, %0|%0, %H1} vmovlpd\t{%H1, %2, %0|%0, %2, %H1} %vmovhpd\t{%1, %0|%0, %1}" - [(set_attr "isa" "noavx,avx,base,noavx,avx,base") + [(set_attr "isa" "noavx,avx,*,noavx,avx,*") (set_attr "type" "sselog,sselog,sselog,ssemov,ssemov,ssemov") (set_attr "prefix_data16" "*,*,*,1,*,1") (set_attr "prefix" "orig,vex,maybe_vex,orig,vex,maybe_vex") @@ -3922,7 +3933,7 @@ movhpd\t{%2, %0|%0, %2} vmovhpd\t{%2, %1, %0|%0, %1, %2} %vmovlpd\t{%2, %H0|%H0, %2}" - [(set_attr "isa" "noavx,avx,base,noavx,avx,base") + [(set_attr "isa" "noavx,avx,*,noavx,avx,*") (set_attr "type" "sselog,sselog,sselog,ssemov,ssemov,ssemov") (set_attr "prefix_data16" "*,*,*,1,*,1") (set_attr "prefix" "orig,vex,maybe_vex,orig,vex,maybe_vex") @@ -4128,7 +4139,7 @@ # # #" - [(set_attr "isa" "base,noavx,avx,base,base,base") + [(set_attr "isa" "*,noavx,avx,*,*,*") (set_attr "type" "ssemov,sselog1,sselog1,ssemov,fmov,imov") (set (attr "prefix_data16") (if_then_else @@ -4148,6 +4159,20 @@ [(set (match_dup 0) (match_dup 1))] "operands[1] = adjust_address (operands[1], DFmode, 8);") +(define_insn "*vec_extractv2df_1_sse" + [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x") + (vec_select:DF + (match_operand:V2DF 1 "nonimmediate_operand" "x,x,o") + (parallel [(const_int 1)])))] + "!TARGET_SSE2 && TARGET_SSE + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + movhps\t{%1, %0|%0, %1} + movhlps\t{%1, %0|%0, %1} + movlps\t{%H1, %0|%0, %H1}" + [(set_attr "type" "ssemov") + (set_attr "mode" "V2SF,V4SF,V2SF")]) + ;; Avoid combining registers from different units in a single alternative, ;; see comment above inline_secondary_memory_needed function in i386.c (define_insn "sse2_storelpd" @@ -4184,6 +4209,20 @@ DONE; }) +(define_insn "*vec_extractv2df_0_sse" + [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x") + (vec_select:DF + (match_operand:V2DF 1 "nonimmediate_operand" "x,x,m") + (parallel [(const_int 0)])))] + "!TARGET_SSE2 && TARGET_SSE + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + movlps\t{%1, %0|%0, %1} + movaps\t{%1, %0|%0, %1} + movlps\t{%1, %0|%0, %1}" + [(set_attr "type" "ssemov") + (set_attr "mode" "V2SF,V4SF,V2SF")]) + (define_expand "sse2_loadhpd_exp" [(set (match_operand:V2DF 0 "nonimmediate_operand" "") (vec_concat:V2DF @@ -4225,7 +4264,7 @@ # # #" - [(set_attr "isa" "noavx,avx,noavx,avx,base,base,base") + [(set_attr "isa" "noavx,avx,noavx,avx,*,*,*") (set_attr "type" "ssemov,ssemov,sselog,sselog,ssemov,fmov,imov") (set_attr "prefix_data16" "1,*,*,*,*,*,*") (set_attr "prefix" "orig,vex,orig,vex,*,*,*") @@ -4285,8 +4324,16 @@ # # #" - [(set_attr "isa" "base,noavx,avx,noavx,avx,noavx,noavx,avx,base,base,base") - (set_attr "type" "ssemov,ssemov,ssemov,ssemov,ssemov,sselog,ssemov,ssemov,ssemov,fmov,imov") + [(set_attr "isa" "*,noavx,avx,noavx,avx,noavx,noavx,avx,*,*,*") + (set (attr "type") + (cond [(eq_attr "alternative" "5") + (const_string "sselog") + (eq_attr "alternative" "9") + (const_string "fmov") + (eq_attr "alternative" "10") + (const_string "imov") + ] + (const_string "ssemov"))) (set_attr "prefix_data16" "*,1,*,*,*,*,1,*,*,*,*") (set_attr "length_immediate" "*,*,*,*,*,1,*,*,*,*,*") (set_attr "prefix" "maybe_vex,orig,vex,orig,vex,orig,orig,vex,*,*,*") @@ -4301,36 +4348,6 @@ [(set (match_dup 0) (match_dup 1))] "operands[0] = adjust_address (operands[0], DFmode, 8);") -;; Not sure these two are ever used, but it doesn't hurt to have -;; them. -aoliva -(define_insn "*vec_extractv2df_1_sse" - [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x") - (vec_select:DF - (match_operand:V2DF 1 "nonimmediate_operand" "x,x,o") - (parallel [(const_int 1)])))] - "!TARGET_SSE2 && TARGET_SSE - && !(MEM_P (operands[0]) && MEM_P (operands[1]))" - "@ - movhps\t{%1, %0|%0, %1} - movhlps\t{%1, %0|%0, %1} - movlps\t{%H1, %0|%0, %H1}" - [(set_attr "type" "ssemov") - (set_attr "mode" "V2SF,V4SF,V2SF")]) - -(define_insn "*vec_extractv2df_0_sse" - [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x") - (vec_select:DF - (match_operand:V2DF 1 "nonimmediate_operand" "x,x,m") - (parallel [(const_int 0)])))] - "!TARGET_SSE2 && TARGET_SSE - && !(MEM_P (operands[0]) && MEM_P (operands[1]))" - "@ - movlps\t{%1, %0|%0, %1} - movaps\t{%1, %0|%0, %1} - movlps\t{%1, %0|%0, %1}" - [(set_attr "type" "ssemov") - (set_attr "mode" "V2SF,V4SF,V2SF")]) - (define_insn "sse2_movsd" [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,x,m,x,x,x,o") (vec_merge:V2DF @@ -4348,8 +4365,12 @@ movhps\t{%H1, %0|%0, %H1} vmovhps\t{%H1, %2, %0|%0, %2, %H1} %vmovhps\t{%1, %H0|%H0, %1}" - [(set_attr "isa" "noavx,avx,noavx,avx,base,noavx,noavx,avx,base") - (set_attr "type" "ssemov,ssemov,ssemov,ssemov,ssemov,sselog,ssemov,ssemov,ssemov") + [(set_attr "isa" "noavx,avx,noavx,avx,*,noavx,noavx,avx,*") + (set (attr "type") + (if_then_else + (eq_attr "alternative" "5") + (const_string "sselog") + (const_string "ssemov"))) (set (attr "prefix_data16") (if_then_else (and (eq_attr "alternative" "2,4") @@ -4360,6 +4381,16 @@ (set_attr "prefix" "orig,vex,orig,vex,maybe_vex,orig,orig,vex,maybe_vex") (set_attr "mode" "DF,DF,V1DF,V1DF,V1DF,V2DF,V1DF,V1DF,V1DF")]) +(define_expand "vec_dupv2df" + [(set (match_operand:V2DF 0 "register_operand" "") + (vec_duplicate:V2DF + (match_operand:DF 1 "nonimmediate_operand" "")))] + "TARGET_SSE2" +{ + if (!TARGET_SSE3) + operands[1] = force_reg (DFmode, operands[1]); +}) + (define_insn "*vec_dupv2df_sse3" [(set (match_operand:V2DF 0 "register_operand" "=x") (vec_duplicate:V2DF @@ -4370,7 +4401,7 @@ (set_attr "prefix" "maybe_vex") (set_attr "mode" "DF")]) -(define_insn "vec_dupv2df" +(define_insn "*vec_dupv2df" [(set (match_operand:V2DF 0 "register_operand" "=x") (vec_duplicate:V2DF (match_operand:DF 1 "register_operand" "0")))] @@ -4404,8 +4435,12 @@ %vmovsd\t{%1, %0|%0, %1} movlhps\t{%2, %0|%0, %2} movhps\t{%2, %0|%0, %2}" - [(set_attr "isa" "noavx,avx,noavx,avx,base,noavx,noavx") - (set_attr "type" "sselog,sselog,ssemov,ssemov,ssemov,ssemov,ssemov") + [(set_attr "isa" "noavx,avx,noavx,avx,*,noavx,noavx") + (set (attr "type") + (if_then_else + (eq_attr "alternative" "0,1") + (const_string "sselog") + (const_string "ssemov"))) (set_attr "prefix_data16" "*,*,1,*,*,*,*") (set_attr "prefix" "orig,vex,orig,vex,maybe_vex,orig,orig") (set_attr "mode" "V2DF,V2DF,V1DF,V1DF,DF,V4SF,V2SF")]) @@ -6305,7 +6340,7 @@ movss\t{%2, %0|%0, %2} movss\t{%2, %0|%0, %2} vmovss\t{%2, %1, %0|%0, %1, %2}" - [(set_attr "isa" "base,base,noavx,noavx,avx") + [(set_attr "isa" "*,*,noavx,noavx,avx") (set_attr "type" "ssemov") (set_attr "prefix" "maybe_vex,maybe_vex,orig,orig,vex") (set_attr "mode" "TI,TI,V4SF,SF,SF")]) @@ -6393,7 +6428,7 @@ vpsrldq\t{$8, %1, %0|%0, %1, 8} %vmovq\t{%H1, %0|%0, %H1} mov{q}\t{%H1, %0|%0, %H1}" - [(set_attr "isa" "base,noavx,avx,base,base") + [(set_attr "isa" "*,noavx,avx,*,*") (set_attr "type" "ssemov,sseishft1,sseishft1,ssemov,imov") (set_attr "length_immediate" "*,1,1,*,*") (set_attr "memory" "*,none,none,*,*") @@ -6414,7 +6449,7 @@ %vmovq\t{%H1, %0|%0, %H1} movhlps\t{%1, %0|%0, %1} movlps\t{%H1, %0|%0, %H1}" - [(set_attr "isa" "base,noavx,avx,base,noavx,noavx") + [(set_attr "isa" "*,noavx,avx,*,noavx,noavx") (set_attr "type" "ssemov,sseishft1,sseishft1,ssemov,ssemov,ssemov") (set_attr "length_immediate" "*,1,1,*,*,*") (set_attr "memory" "*,none,none,*,*,*") @@ -6456,7 +6491,7 @@ punpcklqdq\t%0, %0 vpunpcklqdq\t{%d1, %0|%0, %d1} %vmovddup\t{%1, %0|%0, %1}" - [(set_attr "isa" "noavx,avx,base") + [(set_attr "isa" "noavx,avx,*") (set_attr "type" "sselog1") (set_attr "prefix" "orig,vex,maybe_vex") (set_attr "mode" "TI,TI,DF")]) @@ -6486,7 +6521,7 @@ %vmovd\t{%1, %0|%0, %1} punpckldq\t{%2, %0|%0, %2} movd\t{%1, %0|%0, %1}" - [(set_attr "isa" "noavx,avx,noavx,avx,base,base,base") + [(set_attr "isa" "noavx,avx,noavx,avx,*,*,*") (set_attr "type" "sselog,sselog,sselog,sselog,ssemov,mmxcvt,mmxmov") (set_attr "prefix_extra" "1,1,*,*,*,*,*") (set_attr "length_immediate" "1,1,*,*,*,*,*") @@ -6561,7 +6596,7 @@ vpunpcklqdq\t{%2, %1, %0|%0, %1, %2} movhps\t{%2, %0|%0, %2} vmovhps\t{%2, %1, %0|%0, %1, %2}" - [(set_attr "isa" "noavx,avx,base,base,base,noavx,avx,noavx,avx") + [(set_attr "isa" "noavx,avx,*,*,*,noavx,avx,noavx,avx") (set (attr "type") (if_then_else (eq_attr "alternative" "0,1,5,6") @@ -6592,7 +6627,7 @@ movlhps\t{%2, %0|%0, %2} movhps\t{%2, %0|%0, %2} vmovhps\t{%2, %1, %0|%0, %1, %2}" - [(set_attr "isa" "base,base,noavx,avx,noavx,noavx,avx") + [(set_attr "isa" "*,*,noavx,avx,noavx,noavx,avx") (set_attr "type" "ssemov,ssemov,sselog,sselog,ssemov,ssemov,ssemov") (set_attr "prefix" "maybe_vex,orig,orig,vex,orig,orig,vex") (set_attr "mode" "TI,TI,TI,TI,V4SF,V2SF,V2SF")]) @@ -7676,8 +7711,8 @@ (define_insn "sse4a_extrqi" [(set (match_operand:V2DI 0 "register_operand" "=x") (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0") - (match_operand 2 "const_int_operand" "") - (match_operand 3 "const_int_operand" "")] + (match_operand 2 "const_0_to_255_operand" "") + (match_operand 3 "const_0_to_255_operand" "")] UNSPEC_EXTRQI))] "TARGET_SSE4A" "extrq\t{%3, %2, %0|%0, %2, %3}" @@ -7701,8 +7736,8 @@ [(set (match_operand:V2DI 0 "register_operand" "=x") (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0") (match_operand:V2DI 2 "register_operand" "x") - (match_operand 3 "const_int_operand" "") - (match_operand 4 "const_int_operand" "")] + (match_operand 3 "const_0_to_255_operand" "") + (match_operand 4 "const_0_to_255_operand" "")] UNSPEC_INSERTQI))] "TARGET_SSE4A" "insertq\t{%4, %3, %2, %0|%0, %2, %3, %4}" @@ -7735,9 +7770,8 @@ (vec_merge:VF (match_operand:VF 2 "nonimmediate_operand" "xm,xm") (match_operand:VF 1 "register_operand" "0,x") - (match_operand:SI 3 "const_int_operand" "")))] - "TARGET_SSE4_1 - && IN_RANGE (INTVAL (operands[3]), 0, (1 << GET_MODE_NUNITS (<MODE>mode))-1)" + (match_operand:SI 3 "const_0_to_<blendbits>_operand" "")))] + "TARGET_SSE4_1" "@ blend<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3} vblend<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}" @@ -9735,9 +9769,13 @@ (set_attr "prefix" "vex") (set_attr "mode" "OI")]) +;; Modes handled by AVX vec_dup patterns. +(define_mode_iterator AVX_VEC_DUP_MODE + [V8SI V8SF V4DI V4DF]) + (define_insn "vec_dup<mode>" - [(set (match_operand:AVX256MODE24P 0 "register_operand" "=x,x") - (vec_duplicate:AVX256MODE24P + [(set (match_operand:AVX_VEC_DUP_MODE 0 "register_operand" "=x,x") + (vec_duplicate:AVX_VEC_DUP_MODE (match_operand:<ssescalarmode> 1 "nonimmediate_operand" "m,?x")))] "TARGET_AVX" "@ @@ -9749,12 +9787,14 @@ (set_attr "mode" "V8SF")]) (define_split - [(set (match_operand:AVX256MODE24P 0 "register_operand" "") - (vec_duplicate:AVX256MODE24P + [(set (match_operand:AVX_VEC_DUP_MODE 0 "register_operand" "") + (vec_duplicate:AVX_VEC_DUP_MODE (match_operand:<ssescalarmode> 1 "register_operand" "")))] "TARGET_AVX && reload_completed" - [(set (match_dup 2) (vec_duplicate:<ssehalfvecmode> (match_dup 1))) - (set (match_dup 0) (vec_concat:AVX256MODE24P (match_dup 2) (match_dup 2)))] + [(set (match_dup 2) + (vec_duplicate:<ssehalfvecmode> (match_dup 1))) + (set (match_dup 0) + (vec_concat:AVX_VEC_DUP_MODE (match_dup 2) (match_dup 2)))] "operands[2] = gen_rtx_REG (<ssehalfvecmode>mode, REGNO (operands[0]));") (define_insn "avx_vbroadcastf128_<mode>" @@ -10290,7 +10330,7 @@ [(set (match_operand:V8HI 0 "register_operand" "") (vec_concat:V8HI (unspec:V4HI [(match_operand:V4SF 1 "register_operand" "") - (match_operand:SI 2 "immediate_operand" "")] + (match_operand:SI 2 "const_0_to_255_operand" "")] UNSPEC_VCVTPS2PH) (match_dup 3)))] "TARGET_F16C" @@ -10300,7 +10340,7 @@ [(set (match_operand:V8HI 0 "register_operand" "=x") (vec_concat:V8HI (unspec:V4HI [(match_operand:V4SF 1 "register_operand" "x") - (match_operand:SI 2 "immediate_operand" "N")] + (match_operand:SI 2 "const_0_to_255_operand" "N")] UNSPEC_VCVTPS2PH) (match_operand:V4HI 3 "const0_operand" "")))] "TARGET_F16C" @@ -10312,7 +10352,7 @@ (define_insn "*vcvtps2ph_store" [(set (match_operand:V4HI 0 "memory_operand" "=m") (unspec:V4HI [(match_operand:V4SF 1 "register_operand" "x") - (match_operand:SI 2 "immediate_operand" "N")] + (match_operand:SI 2 "const_0_to_255_operand" "N")] UNSPEC_VCVTPS2PH))] "TARGET_F16C" "vcvtps2ph\t{%2, %1, %0|%0, %1, %2}" @@ -10323,7 +10363,7 @@ (define_insn "vcvtps2ph256" [(set (match_operand:V8HI 0 "nonimmediate_operand" "=xm") (unspec:V8HI [(match_operand:V8SF 1 "register_operand" "x") - (match_operand:SI 2 "immediate_operand" "N")] + (match_operand:SI 2 "const_0_to_255_operand" "N")] UNSPEC_VCVTPS2PH))] "TARGET_F16C" "vcvtps2ph\t{%2, %1, %0|%0, %1, %2}" diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386 index a43843351a0..d51006561ac 100644 --- a/gcc/config/i386/t-i386 +++ b/gcc/config/i386/t-i386 @@ -24,7 +24,7 @@ i386.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(GGC_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h $(CGRAPH_H) \ $(TREE_GIMPLE_H) $(DWARF2_H) $(DF_H) tm-constrs.h $(PARAMS_H) \ i386-builtin-types.inc debug.h dwarf2out.h sbitmap.h $(FIBHEAP_H) \ - $(OPTS_H) $(DIAGNOSTIC_H) + $(OPTS_H) $(DIAGNOSTIC_H) $(COMMON_TARGET_H) i386-c.o: $(srcdir)/config/i386/i386-c.c \ $(srcdir)/config/i386/i386-protos.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \ diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h index 627271e8d7d..893ed886103 100644 --- a/gcc/config/ia64/ia64-protos.h +++ b/gcc/config/ia64/ia64-protos.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler for IA-64. - Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2007, 2010 + Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2007, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -18,6 +18,9 @@ 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/>. */ +/* Shared between the driver and cc1. */ +extern enum unwind_info_type ia64_except_unwind_info (struct gcc_options *); + /* Functions defined in ia64.c */ extern int bundling_p; diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index b8ffc14debd..78d2441a32c 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -195,17 +195,17 @@ static void ia64_option_override (void); static void ia64_option_default_params (void); static bool ia64_can_eliminate (const int, const int); static enum machine_mode hfa_element_mode (const_tree, bool); -static void ia64_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, +static void ia64_setup_incoming_varargs (cumulative_args_t, enum machine_mode, tree, int *, int); -static int ia64_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, +static int ia64_arg_partial_bytes (cumulative_args_t, enum machine_mode, tree, bool); -static rtx ia64_function_arg_1 (const CUMULATIVE_ARGS *, enum machine_mode, +static rtx ia64_function_arg_1 (cumulative_args_t, enum machine_mode, const_tree, bool, bool); -static rtx ia64_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx ia64_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static rtx ia64_function_incoming_arg (CUMULATIVE_ARGS *, +static rtx ia64_function_incoming_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static void ia64_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void ia64_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); static unsigned int ia64_function_arg_boundary (enum machine_mode, const_tree); @@ -221,8 +221,6 @@ static int ia64_memory_move_cost (enum machine_mode mode, reg_class_t, static bool ia64_rtx_costs (rtx, int, int, int *, bool); static int ia64_unspec_may_trap_p (const_rtx, unsigned); static void fix_range (const char *); -static bool ia64_handle_option (struct gcc_options *, struct gcc_options *, - const struct cl_decoded_option *, location_t); static struct machine_function * ia64_init_machine_status (void); static void emit_insn_group_barriers (FILE *); static void emit_all_insn_group_barriers (FILE *); @@ -253,7 +251,6 @@ static void ia64_asm_emit_except_personality (rtx); static void ia64_asm_init_sections (void); static enum unwind_info_type ia64_debug_unwind_info (void); -static enum unwind_info_type ia64_except_unwind_info (struct gcc_options *); static struct bundle_state *get_free_bundle_state (void); static void free_bundle_state (struct bundle_state *); @@ -348,16 +345,6 @@ static const struct attribute_spec ia64_attribute_table[] = { NULL, 0, 0, false, false, false, NULL, false } }; -/* Implement overriding of the optimization options. */ -static const struct default_options ia64_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, -#ifdef SUBTARGET_OPTIMIZATION_OPTIONS - SUBTARGET_OPTIMIZATION_OPTIONS, -#endif - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - /* Initialize the GCC target structure. */ #undef TARGET_ATTRIBUTE_TABLE #define TARGET_ATTRIBUTE_TABLE ia64_attribute_table @@ -390,8 +377,6 @@ static const struct default_options ia64_option_optimization_table[] = #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE ia64_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE ia64_option_optimization_table #undef TARGET_OPTION_DEFAULT_PARAMS #define TARGET_OPTION_DEFAULT_PARAMS ia64_option_default_params @@ -580,8 +565,6 @@ static const struct default_options ia64_option_optimization_table[] = #undef TARGET_DEBUG_UNWIND_INFO #define TARGET_DEBUG_UNWIND_INFO ia64_debug_unwind_info -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO ia64_except_unwind_info #undef TARGET_SCALAR_MODE_SUPPORTED_P #define TARGET_SCALAR_MODE_SUPPORTED_P ia64_scalar_mode_supported_p @@ -593,11 +576,6 @@ static const struct default_options ia64_option_optimization_table[] = #undef TARGET_RELAXED_ORDERING #define TARGET_RELAXED_ORDERING true -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | TARGET_CPU_DEFAULT) -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION ia64_handle_option - #undef TARGET_LEGITIMATE_CONSTANT_P #define TARGET_LEGITIMATE_CONSTANT_P ia64_legitimate_constant_p @@ -4179,14 +4157,14 @@ ia64_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain) We generate the actual spill instructions during prologue generation. */ static void -ia64_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, +ia64_setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode, tree type, int * pretend_size, int second_time ATTRIBUTE_UNUSED) { - CUMULATIVE_ARGS next_cum = *cum; + CUMULATIVE_ARGS next_cum = *get_cumulative_args (cum); /* Skip the current argument. */ - ia64_function_arg_advance (&next_cum, mode, type, 1); + ia64_function_arg_advance (pack_cumulative_args (&next_cum), mode, type, 1); if (next_cum.words < MAX_ARGUMENT_SLOTS) { @@ -4334,9 +4312,11 @@ ia64_function_arg_offset (const CUMULATIVE_ARGS *cum, registers. */ static rtx -ia64_function_arg_1 (const CUMULATIVE_ARGS *cum, enum machine_mode mode, +ia64_function_arg_1 (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named, bool incoming) { + const CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + int basereg = (incoming ? GR_ARG_FIRST : AR_ARG_FIRST); int words = ia64_function_arg_words (type, mode); int offset = ia64_function_arg_offset (cum, type, words); @@ -4527,7 +4507,7 @@ ia64_function_arg_1 (const CUMULATIVE_ARGS *cum, enum machine_mode mode, /* Implement TARGET_FUNCION_ARG target hook. */ static rtx -ia64_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +ia64_function_arg (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named) { return ia64_function_arg_1 (cum, mode, type, named, false); @@ -4536,7 +4516,7 @@ ia64_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, /* Implement TARGET_FUNCION_INCOMING_ARG target hook. */ static rtx -ia64_function_incoming_arg (CUMULATIVE_ARGS *cum, +ia64_function_incoming_arg (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named) { @@ -4548,9 +4528,11 @@ ia64_function_incoming_arg (CUMULATIVE_ARGS *cum, in memory. */ static int -ia64_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, +ia64_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode, tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + int words = ia64_function_arg_words (type, mode); int offset = ia64_function_arg_offset (cum, type, words); @@ -4589,9 +4571,10 @@ ia64_arg_type (enum machine_mode mode) ia64_function_arg. */ static void -ia64_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +ia64_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int words = ia64_function_arg_words (type, mode); int offset = ia64_function_arg_offset (cum, type, words); enum machine_mode hfa_mode = VOIDmode; @@ -5641,30 +5624,6 @@ fix_range (const char *const_str) } } -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -ia64_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc) -{ - size_t code = decoded->opt_index; - const char *arg = decoded->arg; - int value = decoded->value; - - switch (code) - { - case OPT_mtls_size_: - if (value != 14 && value != 22 && value != 64) - error_at (loc, "bad value %<%s%> for -mtls-size= switch", arg); - return true; - - default: - return true; - } -} - /* Implement TARGET_OPTION_OVERRIDE. */ static void @@ -10095,25 +10054,6 @@ ia64_debug_unwind_info (void) { return UI_TARGET; } - -/* Implement TARGET_EXCEPT_UNWIND_INFO. */ - -static enum unwind_info_type -ia64_except_unwind_info (struct gcc_options *opts) -{ - /* Honor the --enable-sjlj-exceptions configure switch. */ -#ifdef CONFIG_UNWIND_EXCEPTIONS - if (CONFIG_UNWIND_EXCEPTIONS) - return UI_SJLJ; -#endif - - /* For simplicity elsewhere in this file, indicate that all unwind - info is disabled if we're not emitting unwind tables. */ - if (!opts->x_flag_exceptions && !opts->x_flag_unwind_tables) - return UI_NONE; - - return UI_TARGET; -} enum ia64_builtins { diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c index aa63674c470..916acf28408 100644 --- a/gcc/config/iq2000/iq2000.c +++ b/gcc/config/iq2000/iq2000.c @@ -148,20 +148,20 @@ static section *iq2000_select_rtx_section (enum machine_mode, rtx, static void iq2000_init_builtins (void); static rtx iq2000_expand_builtin (tree, rtx, rtx, enum machine_mode, int); static bool iq2000_return_in_memory (const_tree, const_tree); -static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *, +static void iq2000_setup_incoming_varargs (cumulative_args_t, enum machine_mode, tree, int *, int); static bool iq2000_rtx_costs (rtx, int, int, int *, bool); static int iq2000_address_cost (rtx, bool); static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT); static rtx iq2000_legitimize_address (rtx, rtx, enum machine_mode); -static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, +static bool iq2000_pass_by_reference (cumulative_args_t, enum machine_mode, const_tree, bool); -static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, +static int iq2000_arg_partial_bytes (cumulative_args_t, enum machine_mode, tree, bool); -static rtx iq2000_function_arg (CUMULATIVE_ARGS *, +static rtx iq2000_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static void iq2000_function_arg_advance (CUMULATIVE_ARGS *, +static void iq2000_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); static unsigned int iq2000_function_arg_boundary (enum machine_mode, const_tree); @@ -176,13 +176,6 @@ static void iq2000_print_operand (FILE *, rtx, int); static void iq2000_print_operand_address (FILE *, rtx); static bool iq2000_print_operand_punct_valid_p (unsigned char code); -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options iq2000_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - #undef TARGET_INIT_BUILTINS #define TARGET_INIT_BUILTINS iq2000_init_builtins #undef TARGET_EXPAND_BUILTIN @@ -191,8 +184,6 @@ static const struct default_options iq2000_option_optimization_table[] = #define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE iq2000_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE iq2000_option_optimization_table #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS iq2000_rtx_costs #undef TARGET_ADDRESS_COST @@ -1138,9 +1129,11 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, position in CUM. */ static void -iq2000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +iq2000_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + if (TARGET_DEBUG_D_MODE) { fprintf (stderr, @@ -1207,9 +1200,10 @@ iq2000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */ static rtx -iq2000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +iq2000_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); rtx ret; int regbase = -1; int bias = 0; @@ -1383,10 +1377,12 @@ iq2000_function_arg_boundary (enum machine_mode mode, const_tree type) } static int -iq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, +iq2000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode, tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1) { if (TARGET_DEBUG_D_MODE) @@ -1888,7 +1884,8 @@ iq2000_expand_prologue (void) int i; tree next_arg; tree cur_arg; - CUMULATIVE_ARGS args_so_far; + CUMULATIVE_ARGS args_so_far_v; + cumulative_args_t args_so_far; int store_args_on_stack = (iq2000_can_use_return_insn ()); /* If struct value address is treated as the first argument. */ @@ -1912,7 +1909,8 @@ iq2000_expand_prologue (void) variable arguments. This is only needed if store_args_on_stack is true. */ - INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0); + INIT_CUMULATIVE_ARGS (args_so_far_v, fntype, NULL_RTX, 0, 0); + args_so_far = pack_cumulative_args (&args_so_far_v); regno = GP_ARG_FIRST; for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg) @@ -1927,10 +1925,10 @@ iq2000_expand_prologue (void) passed_mode = Pmode; } - entry_parm = iq2000_function_arg (&args_so_far, passed_mode, + entry_parm = iq2000_function_arg (args_so_far, passed_mode, passed_type, true); - iq2000_function_arg_advance (&args_so_far, passed_mode, + iq2000_function_arg_advance (args_so_far, passed_mode, passed_type, true); next_arg = DECL_CHAIN (cur_arg); @@ -1973,7 +1971,7 @@ iq2000_expand_prologue (void) iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of adjustments to be made as the next_arg_reg variable, so we split up the insns, and emit them separately. */ - next_arg_reg = iq2000_function_arg (&args_so_far, VOIDmode, + next_arg_reg = iq2000_function_arg (args_so_far, VOIDmode, void_type_node, true); if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL) { @@ -2247,9 +2245,10 @@ iq2000_function_value_regno_p (const unsigned int regno) /* Return true when an argument must be passed by reference. */ static bool -iq2000_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode, +iq2000_pass_by_reference (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int size; /* We must pass by reference if we would be both passing in registers @@ -2263,7 +2262,8 @@ iq2000_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode, CUMULATIVE_ARGS temp; temp = *cum; - if (iq2000_function_arg (&temp, mode, type, named) != 0) + if (iq2000_function_arg (pack_cumulative_args (&temp), mode, type, named) + != 0) return 1; } @@ -2844,11 +2844,12 @@ iq2000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */ static void -iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *cum, +iq2000_setup_incoming_varargs (cumulative_args_t cum_v, enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, int * pretend_size, int no_rtl) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); unsigned int iq2000_off = ! cum->last_arg_fp; unsigned int iq2000_fp_off = cum->last_arg_fp; diff --git a/gcc/config/kfreebsd-gnu.h b/gcc/config/kfreebsd-gnu.h index 4cc1dc290a8..0317c8dd2a8 100644 --- a/gcc/config/kfreebsd-gnu.h +++ b/gcc/config/kfreebsd-gnu.h @@ -19,7 +19,6 @@ 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/>. */ -#undef GNU_USER_TARGET_OS_CPP_BUILTINS #define GNU_USER_TARGET_OS_CPP_BUILTINS() \ do \ { \ @@ -31,5 +30,6 @@ along with GCC; see the file COPYING3. If not see } \ while (0) -#undef GNU_USER_DYNAMIC_LINKER -#define GNU_USER_DYNAMIC_LINKER "/lib/ld.so.1" +#define GNU_USER_DYNAMIC_LINKER GLIBC_DYNAMIC_LINKER +#define GNU_USER_DYNAMIC_LINKER32 GLIBC_DYNAMIC_LINKER32 +#define GNU_USER_DYNAMIC_LINKER64 GLIBC_DYNAMIC_LINKER64 diff --git a/gcc/config/lm32/lm32.c b/gcc/config/lm32/lm32.c index ac368c84bac..e9800e7f55e 100644 --- a/gcc/config/lm32/lm32.c +++ b/gcc/config/lm32/lm32.c @@ -1,7 +1,7 @@ /* Subroutines used for code generation on the Lattice Mico32 architecture. Contributed by Jon Beniston <jon@beniston.com> - Copyright (C) 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -65,7 +65,7 @@ static rtx emit_add (rtx dest, rtx src0, rtx src1); static void expand_save_restore (struct lm32_frame_info *info, int op); static void stack_adjust (HOST_WIDE_INT amount); static bool lm32_in_small_data_p (const_tree); -static void lm32_setup_incoming_varargs (CUMULATIVE_ARGS * cum, +static void lm32_setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode, tree type, int *pretend_size, int no_rtl); static bool lm32_rtx_costs (rtx x, int code, int outer_code, int *total, @@ -75,25 +75,16 @@ static bool lm32_legitimate_address_p (enum machine_mode mode, rtx x, bool strict); static HOST_WIDE_INT lm32_compute_frame_size (int size); static void lm32_option_override (void); -static rtx lm32_function_arg (CUMULATIVE_ARGS * cum, +static rtx lm32_function_arg (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named); -static void lm32_function_arg_advance (CUMULATIVE_ARGS * cum, +static void lm32_function_arg_advance (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named); static bool lm32_legitimate_constant_p (enum machine_mode, rtx); -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options lm32_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE lm32_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE lm32_option_optimization_table #undef TARGET_ADDRESS_COST #define TARGET_ADDRESS_COST hook_int_rtx_bool_0 #undef TARGET_RTX_COSTS @@ -118,8 +109,6 @@ static const struct default_options lm32_option_optimization_table[] = #define TARGET_CAN_ELIMINATE lm32_can_eliminate #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P lm32_legitimate_address_p -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info #undef TARGET_LEGITIMATE_CONSTANT_P #define TARGET_LEGITIMATE_CONSTANT_P lm32_legitimate_constant_p @@ -634,9 +623,11 @@ lm32_print_operand_address (FILE * file, rtx addr) (otherwise it is an extra parameter matching an ellipsis). */ static rtx -lm32_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +lm32_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + if (mode == VOIDmode) /* Compute operand 2 of the call insn. */ return GEN_INT (0); @@ -651,10 +642,10 @@ lm32_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, } static void -lm32_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +lm32_function_arg_advance (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { - *cum += LM32_NUM_REGS2 (mode, type); + *get_cumulative_args (cum) += LM32_NUM_REGS2 (mode, type); } HOST_WIDE_INT @@ -687,9 +678,10 @@ lm32_compute_initial_elimination_offset (int from, int to) } static void -lm32_setup_incoming_varargs (CUMULATIVE_ARGS * cum, enum machine_mode mode, +lm32_setup_incoming_varargs (cumulative_args_t cum_v, enum machine_mode mode, tree type, int *pretend_size, int no_rtl) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int first_anon_arg; tree fntype; diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index 3770fefb6da..0336d0ea587 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -73,15 +73,15 @@ static struct machine_function *m32c_init_machine_status (void); static void m32c_insert_attributes (tree, tree *); static bool m32c_legitimate_address_p (enum machine_mode, rtx, bool); static bool m32c_addr_space_legitimate_address_p (enum machine_mode, rtx, bool, addr_space_t); -static rtx m32c_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx m32c_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static bool m32c_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, +static bool m32c_pass_by_reference (cumulative_args_t, enum machine_mode, const_tree, bool); -static void m32c_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void m32c_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); static unsigned int m32c_function_arg_boundary (enum machine_mode, const_tree); static int m32c_pushm_popm (Push_Pop_Type); -static bool m32c_strict_argument_naming (CUMULATIVE_ARGS *); +static bool m32c_strict_argument_naming (cumulative_args_t); static rtx m32c_struct_value_rtx (tree, int); static rtx m32c_subreg (enum machine_mode, rtx, enum machine_mode, int); static int need_to_save (int); @@ -1536,9 +1536,11 @@ m32c_push_rounding (int n) #undef TARGET_FUNCTION_ARG #define TARGET_FUNCTION_ARG m32c_function_arg static rtx -m32c_function_arg (CUMULATIVE_ARGS * ca, +m32c_function_arg (cumulative_args_t ca_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v); + /* Can return a reg, parallel, or 0 for stack */ rtx rv = NULL_RTX; #if DEBUG0 @@ -1587,7 +1589,7 @@ m32c_function_arg (CUMULATIVE_ARGS * ca, #undef TARGET_PASS_BY_REFERENCE #define TARGET_PASS_BY_REFERENCE m32c_pass_by_reference static bool -m32c_pass_by_reference (CUMULATIVE_ARGS * ca ATTRIBUTE_UNUSED, +m32c_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) @@ -1617,11 +1619,13 @@ m32c_init_cumulative_args (CUMULATIVE_ARGS * ca, #undef TARGET_FUNCTION_ARG_ADVANCE #define TARGET_FUNCTION_ARG_ADVANCE m32c_function_arg_advance static void -m32c_function_arg_advance (CUMULATIVE_ARGS * ca, +m32c_function_arg_advance (cumulative_args_t ca_v, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v); + if (ca->force_mem) ca->force_mem = 0; else @@ -1783,7 +1787,7 @@ m32c_epilogue_uses (int regno ATTRIBUTE_UNUSED) #undef TARGET_STRICT_ARGUMENT_NAMING #define TARGET_STRICT_ARGUMENT_NAMING m32c_strict_argument_naming static bool -m32c_strict_argument_naming (CUMULATIVE_ARGS * ca ATTRIBUTE_UNUSED) +m32c_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED) { return 1; } @@ -2549,11 +2553,6 @@ m32c_address_cost (rtx addr, bool speed ATTRIBUTE_UNUSED) /* Defining the Output Assembler Language */ -/* The Overall Framework of an Assembler File */ - -#undef TARGET_HAVE_NAMED_SECTIONS -#define TARGET_HAVE_NAMED_SECTIONS true - /* Output of Data */ /* We may have 24 bit sizes, which is the native address size. diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c index 1580f47edd1..577345e9c98 100644 --- a/gcc/config/m32r/m32r.c +++ b/gcc/config/m32r/m32r.c @@ -56,8 +56,6 @@ static char m32r_punct_chars[256]; #define LIT_NAME_P(NAME) ((NAME)[0] == '*' && (NAME)[1] == '.') /* Forward declaration. */ -static bool m32r_handle_option (struct gcc_options *, struct gcc_options *, - const struct cl_decoded_option *, location_t); static void m32r_option_override (void); static void init_reg_tables (void); static void block_move_call (rtx, rtx, rtx); @@ -83,18 +81,18 @@ static bool m32r_return_in_memory (const_tree, const_tree); static rtx m32r_function_value (const_tree, const_tree, bool); static rtx m32r_libcall_value (enum machine_mode, const_rtx); static bool m32r_function_value_regno_p (const unsigned int); -static void m32r_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, +static void m32r_setup_incoming_varargs (cumulative_args_t, enum machine_mode, tree, int *, int); static void init_idents (void); static bool m32r_rtx_costs (rtx, int, int, int *, bool speed); static int m32r_memory_move_cost (enum machine_mode, reg_class_t, bool); -static bool m32r_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, +static bool m32r_pass_by_reference (cumulative_args_t, enum machine_mode, const_tree, bool); -static int m32r_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, +static int m32r_arg_partial_bytes (cumulative_args_t, enum machine_mode, tree, bool); -static rtx m32r_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx m32r_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static void m32r_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void m32r_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); static bool m32r_can_eliminate (const int, const int); static void m32r_conditional_register_usage (void); @@ -112,13 +110,6 @@ static const struct attribute_spec m32r_attribute_table[] = false }, { NULL, 0, 0, false, false, false, NULL, false } }; - -static const struct default_options m32r_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_1_PLUS, OPT_fregmove, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; /* Initialize the GCC target structure. */ #undef TARGET_ATTRIBUTE_TABLE @@ -156,14 +147,8 @@ static const struct default_options m32r_option_optimization_table[] = #undef TARGET_SCHED_ISSUE_RATE #define TARGET_SCHED_ISSUE_RATE m32r_issue_rate -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS TARGET_CPU_DEFAULT -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION m32r_handle_option #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE m32r_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE m32r_option_optimization_table #undef TARGET_ENCODE_SECTION_INFO #define TARGET_ENCODE_SECTION_INFO m32r_encode_section_info @@ -215,40 +200,8 @@ static const struct default_options m32r_option_optimization_table[] = #undef TARGET_LEGITIMATE_CONSTANT_P #define TARGET_LEGITIMATE_CONSTANT_P m32r_legitimate_constant_p -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info - struct gcc_target targetm = TARGET_INITIALIZER; -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -m32r_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc ATTRIBUTE_UNUSED) -{ - size_t code = decoded->opt_index; - int value = decoded->value; - - switch (code) - { - case OPT_m32r: - opts->x_target_flags &= ~(MASK_M32R2 | MASK_M32RX); - return true; - - case OPT_mno_flush_func: - opts->x_m32r_cache_flush_func = NULL; - return true; - - case OPT_mflush_trap_: - return value <= 15; - - default: - return true; - } -} - /* Called by m32r_option_override to initialize various things. */ void @@ -695,7 +648,7 @@ memreg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) /* Return nonzero if TYPE must be passed by indirect reference. */ static bool -m32r_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, +m32r_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { @@ -1185,9 +1138,11 @@ gen_split_move_double (rtx operands[]) static int -m32r_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, +m32r_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode, tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + int words; unsigned int size = (((mode == BLKmode && type) @@ -1243,10 +1198,12 @@ m32r_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, and the rest are pushed. */ static rtx -m32r_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +m32r_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + return (PASS_IN_REG_P (*cum, mode, type) ? gen_rtx_REG (mode, ROUND_ADVANCE_CUM (*cum, mode, type)) : NULL_RTX); @@ -1257,9 +1214,11 @@ m32r_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, (TYPE is null for libcalls where that information may not be available.) */ static void -m32r_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +m32r_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + *cum = (ROUND_ADVANCE_CUM (*cum, mode, type) + ROUND_ADVANCE_ARG (mode, type)); } @@ -1269,7 +1228,9 @@ m32r_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, static bool m32r_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) { - return m32r_pass_by_reference (NULL, TYPE_MODE (type), type, false); + cumulative_args_t dummy = pack_cumulative_args (NULL); + + return m32r_pass_by_reference (dummy, TYPE_MODE (type), type, false); } /* Worker function for TARGET_FUNCTION_VALUE. */ @@ -1309,7 +1270,7 @@ m32r_function_value_regno_p (const unsigned int regno) and mode MODE, and we rely on this fact. */ static void -m32r_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, +m32r_setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode, tree type, int *pretend_size, int no_rtl) { int first_anon_arg; @@ -1320,7 +1281,7 @@ m32r_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, /* All BLKmode values are passed by reference. */ gcc_assert (mode != BLKmode); - first_anon_arg = (ROUND_ADVANCE_CUM (*cum, mode, type) + first_anon_arg = (ROUND_ADVANCE_CUM (*get_cumulative_args (cum), mode, type) + ROUND_ADVANCE_ARG (mode, type)); if (first_anon_arg < M32R_MAX_PARM_REGS) @@ -1380,10 +1341,7 @@ m32r_issue_rate (void) } /* Cost functions. */ - -/* Implement TARGET_HANDLE_OPTION. - - Memory is 3 times as expensive as registers. +/* Memory is 3 times as expensive as registers. ??? Is that the right way to look at it? */ static int diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index fd27ee43a14..c0621c1fce1 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -135,8 +135,6 @@ static int m68k_sched_first_cycle_multipass_dfa_lookahead (void); static bool m68k_can_eliminate (const int, const int); static void m68k_conditional_register_usage (void); static bool m68k_legitimate_address_p (enum machine_mode, rtx, bool); -static bool m68k_handle_option (struct gcc_options *, struct gcc_options *, - const struct cl_decoded_option *, location_t); static void m68k_option_override (void); static rtx find_addr_reg (rtx); static const char *singlemove_string (rtx *); @@ -159,9 +157,9 @@ static void m68k_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; static void m68k_trampoline_init (rtx, tree, rtx); static int m68k_return_pops_args (tree, tree, int); static rtx m68k_delegitimize_address (rtx); -static void m68k_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void m68k_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); -static rtx m68k_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx m68k_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); static bool m68k_cannot_force_const_mem (enum machine_mode mode, rtx x); @@ -234,9 +232,6 @@ static bool m68k_cannot_force_const_mem (enum machine_mode mode, rtx x); #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \ m68k_sched_first_cycle_multipass_dfa_lookahead -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION m68k_handle_option - #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE m68k_option_override @@ -430,47 +425,6 @@ const char *m68k_symbolic_jump; enum M68K_SYMBOLIC_CALL m68k_symbolic_call_var; -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -m68k_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc) -{ - size_t code = decoded->opt_index; - const char *arg = decoded->arg; - int value = decoded->value; - - switch (code) - { - case OPT_m68020_40: - opts->x_m68k_tune_option = u68020_40; - opts->x_m68k_cpu_option = m68020; - return true; - - case OPT_m68020_60: - opts->x_m68k_tune_option = u68020_60; - opts->x_m68k_cpu_option = m68020; - return true; - - case OPT_mshared_library_id_: - if (value > MAX_LIBRARY_ID) - error_at (loc, "-mshared-library-id=%s is not between 0 and %d", - arg, MAX_LIBRARY_ID); - else - { - char *tmp; - asprintf (&tmp, "%d", (value * -4) - 4); - opts->x_m68k_library_id_string = tmp; - } - return true; - - default: - return true; - } -} - /* Implement TARGET_OPTION_OVERRIDE. */ static void @@ -1418,7 +1372,7 @@ m68k_ok_for_sibcall_p (tree decl, tree exp) /* On the m68k all args are always pushed. */ static rtx -m68k_function_arg (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +m68k_function_arg (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) @@ -1427,9 +1381,11 @@ m68k_function_arg (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, } static void -m68k_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +m68k_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + *cum += (mode != BLKmode ? (GET_MODE_SIZE (mode) + 3) & ~3 : (int_size_in_bytes (type) + 3) & ~3); diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c index 32ff5fddf96..8a822bd185c 100644 --- a/gcc/config/mcore/mcore.c +++ b/gcc/config/mcore/mcore.c @@ -1,6 +1,6 @@ /* Output routines for Motorola MCore processor Copyright (C) 1993, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, - 2009, 2010 Free Software Foundation, Inc. + 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -96,7 +96,7 @@ static int calc_live_regs (int *); static int try_constant_tricks (long, HOST_WIDE_INT *, HOST_WIDE_INT *); static const char * output_inline_const (enum machine_mode, rtx *); static void layout_mcore_frame (struct mcore_frame *); -static void mcore_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); +static void mcore_setup_incoming_varargs (cumulative_args_t, enum machine_mode, tree, int *, int); static cond_type is_cond_candidate (rtx); static rtx emit_new_cond_insn (rtx, int); static rtx conditionalize_block (rtx); @@ -124,13 +124,13 @@ static int mcore_ior_cost (rtx); static bool mcore_rtx_costs (rtx, int, int, int *, bool); static void mcore_external_libcall (rtx); static bool mcore_return_in_memory (const_tree, const_tree); -static int mcore_arg_partial_bytes (CUMULATIVE_ARGS *, +static int mcore_arg_partial_bytes (cumulative_args_t, enum machine_mode, tree, bool); -static rtx mcore_function_arg (CUMULATIVE_ARGS *, +static rtx mcore_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static void mcore_function_arg_advance (CUMULATIVE_ARGS *, +static void mcore_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); static unsigned int mcore_function_arg_boundary (enum machine_mode, @@ -152,23 +152,6 @@ static const struct attribute_spec mcore_attribute_table[] = false }, { NULL, 0, 0, false, false, false, NULL, false } }; - -/* What options are we going to default to specific settings when - -O* happens; the user can subsequently override these settings. - - Omitting the frame pointer is a very good idea on the MCore. - Scheduling isn't worth anything on the current MCore implementation. */ - -static const struct default_options mcore_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_ffunction_cse, NULL, 0 }, - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_ALL, OPT_fcaller_saves, NULL, 0 }, - { OPT_LEVELS_ALL, OPT_fschedule_insns, NULL, 0 }, - { OPT_LEVELS_ALL, OPT_fschedule_insns2, NULL, 0 }, - { OPT_LEVELS_SIZE, OPT_mhardlit, NULL, 0 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; /* Initialize the GCC target structure. */ #undef TARGET_ASM_EXTERNAL_LIBCALL @@ -199,8 +182,6 @@ static const struct default_options mcore_option_optimization_table[] = #define TARGET_ASM_UNIQUE_SECTION mcore_unique_section #undef TARGET_ASM_FUNCTION_RODATA_SECTION #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT #undef TARGET_ENCODE_SECTION_INFO #define TARGET_ENCODE_SECTION_INFO mcore_encode_section_info #undef TARGET_STRIP_NAME_ENCODING @@ -242,11 +223,6 @@ static const struct default_options mcore_option_optimization_table[] = #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE mcore_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE mcore_option_optimization_table - -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info #undef TARGET_LEGITIMATE_CONSTANT_P #define TARGET_LEGITIMATE_CONSTANT_P mcore_legitimate_constant_p @@ -1935,11 +1911,13 @@ mcore_initial_elimination_offset (int from, int to) /* Keep track of some information about varargs for the prolog. */ static void -mcore_setup_incoming_varargs (CUMULATIVE_ARGS *args_so_far, +mcore_setup_incoming_varargs (cumulative_args_t args_so_far_v, enum machine_mode mode, tree type, int * ptr_pretend_size ATTRIBUTE_UNUSED, int second_time ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *args_so_far = get_cumulative_args (args_so_far_v); + current_function_anonymous_args = 1; /* We need to know how many argument registers are used before @@ -2807,7 +2785,7 @@ mcore_function_value (const_tree valtype, const_tree func) its data type forbids. */ static rtx -mcore_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +mcore_function_arg (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named) { int arg_reg; @@ -2818,7 +2796,7 @@ mcore_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, if (targetm.calls.must_pass_in_stack (mode, type)) return 0; - arg_reg = ROUND_REG (*cum, mode); + arg_reg = ROUND_REG (*get_cumulative_args (cum), mode); if (arg_reg < NPARM_REGS) return handle_structs_in_regs (mode, type, FIRST_PARM_REG + arg_reg); @@ -2827,9 +2805,11 @@ mcore_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, } static void -mcore_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +mcore_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + *cum = (ROUND_REG (*cum, mode) + (int)named * mcore_num_arg_regs (mode, type)); } @@ -2852,10 +2832,10 @@ mcore_function_arg_boundary (enum machine_mode mode, the function. */ static int -mcore_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, +mcore_arg_partial_bytes (cumulative_args_t cum, enum machine_mode mode, tree type, bool named) { - int reg = ROUND_REG (*cum, mode); + int reg = ROUND_REG (*get_cumulative_args (cum), mode); if (named == 0) return 0; diff --git a/gcc/config/mep/mep.c b/gcc/config/mep/mep.c index 9b185994a18..a946c9350aa 100644 --- a/gcc/config/mep/mep.c +++ b/gcc/config/mep/mep.c @@ -213,17 +213,15 @@ static rtx mep_make_bundle (rtx, rtx); static void mep_bundle_insns (rtx); static bool mep_rtx_cost (rtx, int, int, int *, bool); static int mep_address_cost (rtx, bool); -static void mep_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, +static void mep_setup_incoming_varargs (cumulative_args_t, enum machine_mode, tree, int *, int); -static bool mep_pass_by_reference (CUMULATIVE_ARGS * cum, enum machine_mode, +static bool mep_pass_by_reference (cumulative_args_t cum, enum machine_mode, const_tree, bool); -static rtx mep_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx mep_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static void mep_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void mep_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); static bool mep_vector_mode_supported_p (enum machine_mode); -static bool mep_handle_option (struct gcc_options *, struct gcc_options *, - const struct cl_decoded_option *, location_t); static rtx mep_allocate_initial_value (rtx); static void mep_asm_init_sections (void); static int mep_comp_type_attributes (const_tree, const_tree); @@ -296,21 +294,6 @@ mep_conditional_register_usage (void) global_regs[i] = 1; } - -static const struct default_options mep_option_optimization_table[] = - { - /* The first scheduling pass often increases register pressure and - tends to result in more spill code. Only run it when - specifically asked. */ - { OPT_LEVELS_ALL, OPT_fschedule_insns, NULL, 0 }, - - /* Using $fp doesn't gain us much, even when debugging is - important. */ - { OPT_LEVELS_ALL, OPT_fomit_frame_pointer, NULL, 1 }, - - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - static void mep_option_override (void) { @@ -3511,12 +3494,12 @@ mep_final_prescan_insn (rtx insn, rtx *operands ATTRIBUTE_UNUSED, /* Function args in registers. */ static void -mep_setup_incoming_varargs (CUMULATIVE_ARGS *cum, +mep_setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, int *pretend_size, int second_time ATTRIBUTE_UNUSED) { - int nsave = 4 - (cum->nregs + 1); + int nsave = 4 - (get_cumulative_args (cum)->nregs + 1); if (nsave > 0) cfun->machine->arg_regs_to_save = nsave; @@ -3787,10 +3770,12 @@ mep_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype, first arg. For varargs, we copy $1..$4 to the stack. */ static rtx -mep_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +mep_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + /* VOIDmode is a signal for the backend to pass data to the call expander via the second operand to the call pattern. We use this to determine whether to use "jsr" or "jsrv". */ @@ -3811,7 +3796,7 @@ mep_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, } static bool -mep_pass_by_reference (CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED, +mep_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) @@ -3827,18 +3812,19 @@ mep_pass_by_reference (CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED, return true; if (size <= 4) return false; - if (TARGET_IVC2 && cum->nregs < 4 && type != NULL_TREE && VECTOR_TYPE_P (type)) + if (TARGET_IVC2 && get_cumulative_args (cum)->nregs < 4 + && type != NULL_TREE && VECTOR_TYPE_P (type)) return false; return true; } static void -mep_function_arg_advance (CUMULATIVE_ARGS *pcum, +mep_function_arg_advance (cumulative_args_t pcum, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { - pcum->nregs += 1; + get_cumulative_args (pcum)->nregs += 1; } bool @@ -7312,45 +7298,6 @@ mep_address_cost (rtx addr ATTRIBUTE_UNUSED, bool ATTRIBUTE_UNUSED speed_p) return 1; } -static bool -mep_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc ATTRIBUTE_UNUSED) -{ - size_t code = decoded->opt_index; - - switch (code) - { - case OPT_mall_opts: - opts->x_target_flags |= MEP_ALL_OPTS; - break; - - case OPT_mno_opts: - opts->x_target_flags &= ~ MEP_ALL_OPTS; - break; - - case OPT_mcop64: - opts->x_target_flags |= MASK_COP; - opts->x_target_flags |= MASK_64BIT_CR_REGS; - break; - - case OPT_mivc2: - opts->x_target_flags |= MASK_COP; - opts->x_target_flags |= MASK_64BIT_CR_REGS; - opts->x_target_flags |= MASK_VLIW; - opts->x_target_flags |= MASK_OPT_VL64; - opts->x_target_flags |= MASK_IVC2; - - /* Remaining handling of this option deferred. */ - break; - - default: - break; - } - return TRUE; -} - static void mep_asm_init_sections (void) { @@ -7450,14 +7397,8 @@ mep_asm_init_sections (void) #define TARGET_FUNCTION_ARG_ADVANCE mep_function_arg_advance #undef TARGET_VECTOR_MODE_SUPPORTED_P #define TARGET_VECTOR_MODE_SUPPORTED_P mep_vector_mode_supported_p -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION mep_handle_option #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE mep_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE mep_option_optimization_table -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT #undef TARGET_ALLOCATE_INITIAL_VALUE #define TARGET_ALLOCATE_INITIAL_VALUE mep_allocate_initial_value #undef TARGET_ASM_INIT_SECTIONS diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c index 1cec425b15d..288b86fc10f 100644 --- a/gcc/config/microblaze/microblaze.c +++ b/gcc/config/microblaze/microblaze.c @@ -1091,9 +1091,12 @@ init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype, /* Advance the argument to the next argument position. */ static void -microblaze_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode, +microblaze_function_arg_advance (cumulative_args_t cum_v, + enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + cum->arg_number++; switch (mode) { @@ -1146,10 +1149,12 @@ microblaze_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode, or 0 if the argument is to be passed on the stack. */ static rtx -microblaze_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, +microblaze_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + rtx ret; int regbase = -1; int *arg_words = &cum->arg_words; @@ -1197,9 +1202,11 @@ microblaze_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, /* Return number of bytes of argument to put in registers. */ static int -function_arg_partial_bytes (CUMULATIVE_ARGS * cum, enum machine_mode mode, +function_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode, tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + if ((mode == BLKmode || GET_MODE_CLASS (mode) != MODE_COMPLEX_INT || GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT) @@ -1416,13 +1423,6 @@ microblaze_option_override (void) } } -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options microblaze_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - /* Return true if FUNC is an interrupt function as specified by the "interrupt_handler" attribute. */ @@ -2227,7 +2227,8 @@ microblaze_expand_prologue (void) int i; tree next_arg; tree cur_arg; - CUMULATIVE_ARGS args_so_far; + CUMULATIVE_ARGS args_so_far_v; + cumulative_args_t args_so_far; rtx mem_rtx, reg_rtx; /* If struct value address is treated as the first argument, make it so. */ @@ -2245,7 +2246,8 @@ microblaze_expand_prologue (void) /* Determine the last argument, and get its name. */ - INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0); + INIT_CUMULATIVE_ARGS (args_so_far_v, fntype, NULL_RTX, 0, 0); + args_so_far = pack_cumulative_args (&args_so_far_v); regno = GP_ARG_FIRST; for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg) @@ -2260,7 +2262,7 @@ microblaze_expand_prologue (void) passed_mode = Pmode; } - entry_parm = targetm.calls.function_arg (&args_so_far, passed_mode, + entry_parm = targetm.calls.function_arg (args_so_far, passed_mode, passed_type, true); if (entry_parm) @@ -2281,7 +2283,7 @@ microblaze_expand_prologue (void) break; } - targetm.calls.function_arg_advance (&args_so_far, passed_mode, + targetm.calls.function_arg_advance (args_so_far, passed_mode, passed_type, true); next_arg = TREE_CHAIN (cur_arg); @@ -2296,7 +2298,7 @@ microblaze_expand_prologue (void) /* Split parallel insn into a sequence of insns. */ - next_arg_reg = targetm.calls.function_arg (&args_so_far, VOIDmode, + next_arg_reg = targetm.calls.function_arg (args_so_far, VOIDmode, void_type_node, true); if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL) { @@ -2996,9 +2998,6 @@ microblaze_legitimate_constant_p (enum machine_mode mode, rtx x) #define TARGET_ASM_FUNCTION_END_PROLOGUE \ microblaze_function_end_prologue -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT - #undef TARGET_ARG_PARTIAL_BYTES #define TARGET_ARG_PARTIAL_BYTES function_arg_partial_bytes @@ -3044,12 +3043,6 @@ microblaze_legitimate_constant_p (enum machine_mode mode, rtx x) #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE microblaze_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE microblaze_option_optimization_table - -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info - #undef TARGET_LEGITIMATE_CONSTANT_P #define TARGET_LEGITIMATE_CONSTANT_P microblaze_legitimate_constant_p diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 39042386930..f4010da3657 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -4715,7 +4715,7 @@ mips_arg_regno (const struct mips_arg_info *info, bool hard_float_p) /* Implement TARGET_STRICT_ARGUMENT_NAMING. */ static bool -mips_strict_argument_naming (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED) +mips_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED) { return !TARGET_OLDABI; } @@ -4723,9 +4723,10 @@ mips_strict_argument_naming (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED) /* Implement TARGET_FUNCTION_ARG. */ static rtx -mips_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +mips_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); struct mips_arg_info info; /* We will be called with a mode of VOIDmode after the last argument @@ -4849,9 +4850,10 @@ mips_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, /* Implement TARGET_FUNCTION_ARG_ADVANCE. */ static void -mips_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +mips_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); struct mips_arg_info info; mips_get_arg_info (&info, cum, mode, type, named); @@ -4885,12 +4887,12 @@ mips_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, /* Implement TARGET_ARG_PARTIAL_BYTES. */ static int -mips_arg_partial_bytes (CUMULATIVE_ARGS *cum, +mips_arg_partial_bytes (cumulative_args_t cum, enum machine_mode mode, tree type, bool named) { struct mips_arg_info info; - mips_get_arg_info (&info, cum, mode, type, named); + mips_get_arg_info (&info, get_cumulative_args (cum), mode, type, named); return info.stack_words > 0 ? info.reg_words * UNITS_PER_WORD : 0; } @@ -4969,7 +4971,7 @@ mips_pad_reg_upward (enum machine_mode mode, tree type) /* Return nonzero when an argument must be passed by reference. */ static bool -mips_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +mips_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { @@ -4996,7 +4998,7 @@ mips_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, /* Implement TARGET_CALLEE_COPIES. */ static bool -mips_callee_copies (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +mips_callee_copies (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named) { @@ -5263,7 +5265,7 @@ mips_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED) /* Implement TARGET_SETUP_INCOMING_VARARGS. */ static void -mips_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, +mips_setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode, tree type, int *pretend_size ATTRIBUTE_UNUSED, int no_rtl) { @@ -5273,8 +5275,9 @@ mips_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, /* The caller has advanced CUM up to, but not beyond, the last named argument. Advance a local copy of CUM past the last "real" named argument, to find out how many registers are left over. */ - local_cum = *cum; - mips_function_arg_advance (&local_cum, mode, type, true); + local_cum = *get_cumulative_args (cum); + mips_function_arg_advance (pack_cumulative_args (&local_cum), mode, type, + true); /* Found out how many registers we need to save. */ gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs; @@ -5925,7 +5928,7 @@ mips_output_args_xfer (int fp_code, char direction) else mips_output_64bit_xfer (direction, gparg, fparg); - mips_function_arg_advance (&cum, mode, NULL, true); + mips_function_arg_advance (pack_cumulative_args (&cum), mode, NULL, true); } } @@ -15302,27 +15305,6 @@ mips_set_tune (const struct mips_cpu_info *info) } } -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -mips_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc ATTRIBUTE_UNUSED) -{ - size_t code = decoded->opt_index; - - switch (code) - { - case OPT_mno_flush_func: - opts->x_mips_cache_flush_func = NULL; - return true; - - default: - return true; - } -} - /* Implement TARGET_OPTION_OVERRIDE. */ static void @@ -15697,13 +15679,6 @@ mips_option_override (void) mips_set_mips16_mode (false); } -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options mips_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - /* Swap the register information for registers I and I + 1, which currently have the wrong endianness. Note that the registers' fixedness and call-clobberedness might have been set on the @@ -16216,8 +16191,6 @@ mips_shift_truncation_mask (enum machine_mode mode) #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE mips_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE mips_option_optimization_table #undef TARGET_LEGITIMIZE_ADDRESS #define TARGET_LEGITIMIZE_ADDRESS mips_legitimize_address @@ -16254,17 +16227,6 @@ mips_shift_truncation_mask (enum machine_mode mode) #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \ mips_small_register_classes_for_mode_p -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS \ - (TARGET_DEFAULT \ - | TARGET_CPU_DEFAULT \ - | TARGET_ENDIAN_DEFAULT \ - | TARGET_FP_EXCEPTIONS_DEFAULT \ - | MASK_CHECK_ZERO_DIV \ - | MASK_FUSED_MADD) -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION mips_handle_option - #undef TARGET_FUNCTION_OK_FOR_SIBCALL #define TARGET_FUNCTION_OK_FOR_SIBCALL mips_function_ok_for_sibcall diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c index 80f0d8439a4..13234219578 100644 --- a/gcc/config/mmix/mmix.c +++ b/gcc/config/mmix/mmix.c @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for MMIX. Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, - 2010 + 2010, 2011 Free Software Foundation, Inc. Contributed by Hans-Peter Nilsson (hp@bitrange.com) @@ -135,7 +135,7 @@ static void mmix_reorg (void); static void mmix_asm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree); static void mmix_setup_incoming_varargs - (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); + (cumulative_args_t, enum machine_mode, tree, int *, int); static void mmix_file_start (void); static void mmix_file_end (void); static bool mmix_rtx_costs (rtx, int, int, int *, bool); @@ -143,33 +143,24 @@ static rtx mmix_struct_value_rtx (tree, int); static enum machine_mode mmix_promote_function_mode (const_tree, enum machine_mode, int *, const_tree, int); -static void mmix_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void mmix_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); -static rtx mmix_function_arg_1 (const CUMULATIVE_ARGS *, enum machine_mode, +static rtx mmix_function_arg_1 (const cumulative_args_t, enum machine_mode, const_tree, bool, bool); -static rtx mmix_function_incoming_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx mmix_function_incoming_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static rtx mmix_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx mmix_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); static rtx mmix_function_value (const_tree, const_tree, bool); static rtx mmix_libcall_value (enum machine_mode, const_rtx); static bool mmix_function_value_regno_p (const unsigned int); -static bool mmix_pass_by_reference (CUMULATIVE_ARGS *, +static bool mmix_pass_by_reference (cumulative_args_t, enum machine_mode, const_tree, bool); static bool mmix_frame_pointer_required (void); static void mmix_asm_trampoline_template (FILE *); static void mmix_trampoline_init (rtx, tree, rtx); static void mmix_conditional_register_usage (void); -/* TARGET_OPTION_OPTIMIZATION_TABLE. */ - -static const struct default_options mmix_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fregmove, NULL, 1 }, - { OPT_LEVELS_2_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - /* Target structure macros. Listed by node. See `Using and Porting GCC' for a general description. */ @@ -248,8 +239,6 @@ static const struct default_options mmix_option_optimization_table[] = #define TARGET_PASS_BY_REFERENCE mmix_pass_by_reference #undef TARGET_CALLEE_COPIES #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P mmix_legitimate_address_p @@ -266,8 +255,6 @@ static const struct default_options mmix_option_optimization_table[] = #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE mmix_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE mmix_option_optimization_table struct gcc_target targetm = TARGET_INITIALIZER; @@ -640,9 +627,10 @@ mmix_initial_elimination_offset (int fromreg, int toreg) } static void -mmix_function_arg_advance (CUMULATIVE_ARGS *argsp, enum machine_mode mode, +mmix_function_arg_advance (cumulative_args_t argsp_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *argsp = get_cumulative_args (argsp_v); int arg_size = MMIX_FUNCTION_ARG_SIZE (mode, type); argsp->regs = ((targetm.calls.must_pass_in_stack (mode, type) @@ -656,12 +644,14 @@ mmix_function_arg_advance (CUMULATIVE_ARGS *argsp, enum machine_mode mode, /* Helper function for mmix_function_arg and mmix_function_incoming_arg. */ static rtx -mmix_function_arg_1 (const CUMULATIVE_ARGS *argsp, +mmix_function_arg_1 (const cumulative_args_t argsp_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED, bool incoming) { + CUMULATIVE_ARGS *argsp = get_cumulative_args (argsp_v); + /* Last-argument marker. */ if (type == void_type_node) return (argsp->regs < MMIX_MAX_ARGS_IN_REGS) @@ -688,7 +678,7 @@ mmix_function_arg_1 (const CUMULATIVE_ARGS *argsp, one that must go on stack. */ static rtx -mmix_function_arg (CUMULATIVE_ARGS *argsp, +mmix_function_arg (cumulative_args_t argsp, enum machine_mode mode, const_tree type, bool named) @@ -697,7 +687,7 @@ mmix_function_arg (CUMULATIVE_ARGS *argsp, } static rtx -mmix_function_incoming_arg (CUMULATIVE_ARGS *argsp, +mmix_function_incoming_arg (cumulative_args_t argsp, enum machine_mode mode, const_tree type, bool named) @@ -709,9 +699,11 @@ mmix_function_incoming_arg (CUMULATIVE_ARGS *argsp, everything that goes by value. */ static bool -mmix_pass_by_reference (CUMULATIVE_ARGS *argsp, enum machine_mode mode, +mmix_pass_by_reference (cumulative_args_t argsp_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *argsp = get_cumulative_args (argsp_v); + /* FIXME: Check: I'm not sure the must_pass_in_stack check is necessary. */ if (targetm.calls.must_pass_in_stack (mode, type)) @@ -974,12 +966,14 @@ mmix_function_profiler (FILE *stream ATTRIBUTE_UNUSED, can parse all arguments in registers, to improve performance. */ static void -mmix_setup_incoming_varargs (CUMULATIVE_ARGS *args_so_farp, +mmix_setup_incoming_varargs (cumulative_args_t args_so_farp_v, enum machine_mode mode, tree vartype, int *pretend_sizep, int second_time ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *args_so_farp = get_cumulative_args (args_so_farp_v); + /* The last named variable has been handled, but args_so_farp has not been advanced for it. */ if (args_so_farp->regs + 1 < MMIX_MAX_ARGS_IN_REGS) diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c index f9052d55541..24a07d87d55 100644 --- a/gcc/config/mn10300/mn10300.c +++ b/gcc/config/mn10300/mn10300.c @@ -68,13 +68,6 @@ enum processor_type mn10300_tune_cpu = PROCESSOR_DEFAULT; || df_regs_ever_live_p (16) \ || df_regs_ever_live_p (17))) -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options mn10300_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - #define CC_FLAG_Z 1 #define CC_FLAG_N 2 #define CC_FLAG_C 4 @@ -83,38 +76,6 @@ static const struct default_options mn10300_option_optimization_table[] = static int cc_flags_for_mode(enum machine_mode); static int cc_flags_for_code(enum rtx_code); -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -mn10300_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc ATTRIBUTE_UNUSED) -{ - size_t code = decoded->opt_index; - int value = decoded->value; - - switch (code) - { - case OPT_mam33: - opts->x_mn10300_processor = value ? PROCESSOR_AM33 : PROCESSOR_MN10300; - return true; - - case OPT_mam33_2: - opts->x_mn10300_processor = (value - ? PROCESSOR_AM33_2 - : MIN (PROCESSOR_AM33, PROCESSOR_DEFAULT)); - return true; - - case OPT_mam34: - opts->x_mn10300_processor = (value ? PROCESSOR_AM34 : PROCESSOR_DEFAULT); - return true; - - default: - return true; - } -} - /* Implement TARGET_OPTION_OVERRIDE. */ static void @@ -1531,7 +1492,7 @@ mn10300_va_start (tree valist, rtx nextarg) /* Return true when a parameter should be passed by reference. */ static bool -mn10300_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +mn10300_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { @@ -1549,9 +1510,10 @@ mn10300_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, from a function. If the result is NULL_RTX, the argument is pushed. */ static rtx -mn10300_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +mn10300_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); rtx result = NULL_RTX; int size; @@ -1597,9 +1559,11 @@ mn10300_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, (TYPE is null for libcalls where that information may not be available.) */ static void -mn10300_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +mn10300_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + cum->nbytes += (mode != BLKmode ? (GET_MODE_SIZE (mode) + 3) & ~3 : (int_size_in_bytes (type) + 3) & ~3); @@ -1609,9 +1573,10 @@ mn10300_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, partially in registers and partially in memory. */ static int -mn10300_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, +mn10300_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode, tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int size; /* We only support using 2 data registers as argument registers. */ @@ -3320,9 +3285,6 @@ mn10300_reorg (void) #undef TARGET_MACHINE_DEPENDENT_REORG #define TARGET_MACHINE_DEPENDENT_REORG mn10300_reorg -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info - #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t" @@ -3346,14 +3308,8 @@ mn10300_reorg (void) #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA mn10300_asm_output_addr_const_extra -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS MASK_MULT_BUG | MASK_PTR_A0D0 | MASK_ALLOW_LIW | MASK_ALLOW_SETLB -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION mn10300_handle_option #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE mn10300_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE mn10300_option_optimization_table #undef TARGET_ENCODE_SECTION_INFO #define TARGET_ENCODE_SECTION_INFO mn10300_encode_section_info diff --git a/gcc/config/moxie/moxie.c b/gcc/config/moxie/moxie.c index 53b73d15fcc..d70eaac3015 100644 --- a/gcc/config/moxie/moxie.c +++ b/gcc/config/moxie/moxie.c @@ -1,5 +1,5 @@ /* Target Code for moxie - Copyright (C) 2008, 2009, 2010 Free Software Foundation + Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation Contributed by Anthony Green. This file is part of GCC. @@ -370,11 +370,12 @@ moxie_initial_elimination_offset (int from, int to) /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */ static void -moxie_setup_incoming_varargs (CUMULATIVE_ARGS *cum, +moxie_setup_incoming_varargs (cumulative_args_t cum_v, enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, int *pretend_size, int no_rtl) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int regno; int regs = 8 - *cum; @@ -409,10 +410,12 @@ moxie_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2) NULL_RTX if there's no more space. */ static rtx -moxie_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +moxie_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + if (*cum < 8) return gen_rtx_REG (mode, *cum); else @@ -424,9 +427,11 @@ moxie_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, : (unsigned) int_size_in_bytes (TYPE)) static void -moxie_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +moxie_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + *cum = (*cum < MOXIE_R6 ? *cum + ((3 + MOXIE_FUNCTION_ARG_SIZE (mode, type)) / 4) : *cum); @@ -436,7 +441,7 @@ moxie_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, passed by reference. */ static bool -moxie_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +moxie_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { @@ -459,16 +464,17 @@ moxie_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, that fit in argument passing registers. */ static int -moxie_arg_partial_bytes (CUMULATIVE_ARGS *cum, +moxie_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode, tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int bytes_left, size; if (*cum >= 8) return 0; - if (moxie_pass_by_reference (cum, mode, type, named)) + if (moxie_pass_by_reference (cum_v, mode, type, named)) size = 4; else if (type) { diff --git a/gcc/config/moxie/moxie.md b/gcc/config/moxie/moxie.md index 64f8395cb7b..5167223e255 100644 --- a/gcc/config/moxie/moxie.md +++ b/gcc/config/moxie/moxie.md @@ -308,7 +308,7 @@ (match_operand:SI 1 "general_operand" "") (match_operand:SI 2 "general_operand" ""))) (set (pc) - (if_then_else (match_operator:CC 0 "comparison_operator" + (if_then_else (match_operator 0 "comparison_operator" [(reg:CC CC_REG) (const_int 0)]) (label_ref (match_operand 3 "" "")) (pc)))] diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index e512a33c070..2a54bdde266 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include "predict.h" #include "tm_p.h" #include "target.h" +#include "common/common-target.h" #include "target-def.h" #include "langhooks.h" #include "df.h" @@ -88,8 +89,6 @@ hppa_fpstore_bypass_p (rtx out_insn, rtx in_insn) static void pa_option_override (void); static void copy_reg_pointer (rtx, rtx); static void fix_range (const char *); -static bool pa_handle_option (struct gcc_options *, struct gcc_options *, - const struct cl_decoded_option *, location_t); static int hppa_register_move_cost (enum machine_mode mode, reg_class_t, reg_class_t); static int hppa_address_cost (rtx, bool); @@ -159,13 +158,13 @@ static void pa_hpux_file_end (void); static void pa_hpux_init_libfuncs (void); #endif static rtx pa_struct_value_rtx (tree, int); -static bool pa_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, +static bool pa_pass_by_reference (cumulative_args_t, enum machine_mode, const_tree, bool); -static int pa_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, +static int pa_arg_partial_bytes (cumulative_args_t, enum machine_mode, tree, bool); -static void pa_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void pa_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); -static rtx pa_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx pa_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); static unsigned int pa_function_arg_boundary (enum machine_mode, const_tree); static struct machine_function * pa_init_machine_status (void); @@ -224,21 +223,11 @@ struct GTY(()) deferred_plabel static GTY((length ("n_deferred_plabels"))) struct deferred_plabel * deferred_plabels; static size_t n_deferred_plabels = 0; - -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options pa_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - /* Initialize the GCC target structure. */ #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE pa_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE pa_option_optimization_table #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" @@ -310,11 +299,6 @@ static const struct default_options pa_option_optimization_table[] = #define TARGET_ASM_DESTRUCTOR pa_asm_out_destructor #endif -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | TARGET_CPU_DEFAULT) -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION pa_handle_option - #undef TARGET_INIT_BUILTINS #define TARGET_INIT_BUILTINS pa_init_builtins @@ -476,41 +460,6 @@ fix_range (const char *const_str) target_flags |= MASK_DISABLE_FPREGS; } -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -pa_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc ATTRIBUTE_UNUSED) -{ - size_t code = decoded->opt_index; - - switch (code) - { - case OPT_mnosnake: - case OPT_mpa_risc_1_0: - case OPT_march_1_0: - opts->x_target_flags &= ~(MASK_PA_11 | MASK_PA_20); - return true; - - case OPT_msnake: - case OPT_mpa_risc_1_1: - case OPT_march_1_1: - opts->x_target_flags &= ~MASK_PA_20; - opts->x_target_flags |= MASK_PA_11; - return true; - - case OPT_mpa_risc_2_0: - case OPT_march_2_0: - opts->x_target_flags |= MASK_PA_11 | MASK_PA_20; - return true; - - default: - return true; - } -} - /* Implement the TARGET_OPTION_OVERRIDE hook. */ static void @@ -538,7 +487,7 @@ pa_option_override (void) call frame information. There is no benefit in using this optimization on PA8000 and later processors. */ if (pa_cpu >= PROCESSOR_8000 - || (targetm.except_unwind_info (&global_options) == UI_DWARF2 + || (targetm_common.except_unwind_info (&global_options) == UI_DWARF2 && flag_exceptions) || flag_unwind_tables) target_flags &= ~MASK_JUMP_IN_DELAY; @@ -5999,7 +5948,7 @@ pa_eh_return_handler_rtx (void) or updates the ABI. */ static bool -pa_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, +pa_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { @@ -8205,7 +8154,7 @@ pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta, && !(flag_pic && TREE_PUBLIC (function)) && (TARGET_GAS || last_address < 262132)) || (!TARGET_LONG_CALLS && !TARGET_SOM && !TARGET_PORTABLE_RUNTIME - && ((targetm.have_named_sections + && ((targetm_common.have_named_sections && DECL_SECTION_NAME (thunk_fndecl) != NULL /* The GNU 64-bit linker has rather poor stub management. So, we use a long branch from thunks that aren't in @@ -8216,11 +8165,12 @@ pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta, || ((DECL_SECTION_NAME (thunk_fndecl) == DECL_SECTION_NAME (function)) && last_address < 262132))) - || (targetm.have_named_sections + || (targetm_common.have_named_sections && DECL_SECTION_NAME (thunk_fndecl) == NULL && DECL_SECTION_NAME (function) == NULL && last_address < 262132) - || (!targetm.have_named_sections && last_address < 262132)))) + || (!targetm_common.have_named_sections + && last_address < 262132)))) { if (!val_14) output_asm_insn ("addil L'%2,%%r26", xoperands); @@ -9436,9 +9386,10 @@ pa_function_value_regno_p (const unsigned int regno) (TYPE is null for libcalls where that information may not be available.) */ static void -pa_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +pa_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int arg_size = FUNCTION_ARG_SIZE (mode, type); cum->nargs_prototype--; @@ -9457,9 +9408,10 @@ pa_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, ??? We might want to restructure this so that it looks more like other ports. */ static rtx -pa_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +pa_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int max_arg_words = (TARGET_64BIT ? 8 : 4); int alignment = 0; int arg_size; @@ -9667,9 +9619,10 @@ pa_function_arg_boundary (enum machine_mode mode, const_tree type) then this routine should return zero. */ static int -pa_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, +pa_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode, tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); unsigned int max_arg_words = 8; unsigned int offset = 0; @@ -10264,7 +10217,7 @@ pa_function_section (tree decl, enum node_frequency freq, bool startup, bool exit) { /* Put functions in text section if target doesn't have named sections. */ - if (!targetm.have_named_sections) + if (!targetm_common.have_named_sections) return text_section; /* Force nested functions into the same section as the containing diff --git a/gcc/config/pa/som.h b/gcc/config/pa/som.h index 73095e5e041..e8a47cced1c 100644 --- a/gcc/config/pa/som.h +++ b/gcc/config/pa/som.h @@ -1,5 +1,5 @@ /* Definitions for SOM assembler support. - Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005, 2007, 2010 + Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005, 2007, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -269,7 +269,8 @@ do { \ must be removed from library prefixes to prevent binaries from depending on the location of the GCC tool directory. The downside is GCC cannot be moved after installation using a symlink. */ -#define ALWAYS_STRIP_DOTDOT 1 +#undef TARGET_ALWAYS_STRIP_DOTDOT +#define TARGET_ALWAYS_STRIP_DOTDOT true /* If GAS supports weak, we can support weak when we have working linker support for secondary definitions and are generating code for GAS. diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c index fc0c92b8d02..870b9471518 100644 --- a/gcc/config/pdp11/pdp11.c +++ b/gcc/config/pdp11/pdp11.c @@ -139,9 +139,6 @@ decode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED, /* This is where the condition code register lives. */ /* rtx cc0_reg_rtx; - no longer needed? */ -static bool pdp11_handle_option (struct gcc_options *, struct gcc_options *, - const struct cl_decoded_option *, location_t); -static void pdp11_option_init_struct (struct gcc_options *); static const char *singlemove_string (rtx *); static bool pdp11_assemble_integer (rtx, unsigned int, int); static void pdp11_output_function_prologue (FILE *, HOST_WIDE_INT); @@ -152,20 +149,12 @@ static rtx pdp11_function_value (const_tree, const_tree, bool); static rtx pdp11_libcall_value (enum machine_mode, const_rtx); static bool pdp11_function_value_regno_p (const unsigned int); static void pdp11_trampoline_init (rtx, tree, rtx); -static rtx pdp11_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx pdp11_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static void pdp11_function_arg_advance (CUMULATIVE_ARGS *, +static void pdp11_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); static void pdp11_conditional_register_usage (void); static bool pdp11_legitimate_constant_p (enum machine_mode, rtx); - -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ - -static const struct default_options pdp11_option_optimization_table[] = - { - { OPT_LEVELS_3_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; /* Initialize the GCC target structure. */ #undef TARGET_ASM_BYTE_OP @@ -187,16 +176,6 @@ static const struct default_options pdp11_option_optimization_table[] = #undef TARGET_ASM_CLOSE_PAREN #define TARGET_ASM_CLOSE_PAREN "]" -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS \ - (MASK_FPU | MASK_45 | TARGET_UNIX_ASM_DEFAULT) -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION pdp11_handle_option -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE pdp11_option_optimization_table -#undef TARGET_OPTION_INIT_STRUCT -#define TARGET_OPTION_INIT_STRUCT pdp11_option_init_struct - #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS pdp11_rtx_costs @@ -248,37 +227,6 @@ static const struct default_options pdp11_option_optimization_table[] = #undef TARGET_LEGITIMATE_CONSTANT_P #define TARGET_LEGITIMATE_CONSTANT_P pdp11_legitimate_constant_p -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -pdp11_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc ATTRIBUTE_UNUSED) -{ - size_t code = decoded->opt_index; - - switch (code) - { - case OPT_m10: - opts->x_target_flags &= ~(MASK_40 | MASK_45); - return true; - - default: - return true; - } -} - -/* Implement TARGET_OPTION_INIT_STRUCT. */ - -static void -pdp11_option_init_struct (struct gcc_options *opts) -{ - opts->x_flag_finite_math_only = 0; - opts->x_flag_trapping_math = 0; - opts->x_flag_signaling_nans = 0; -} - /* stream is a stdio stream to output the code to. size is an int: how many units of temporary storage to allocate. @@ -1865,7 +1813,7 @@ pdp11_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) (otherwise it is an extra parameter matching an ellipsis). */ static rtx -pdp11_function_arg (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +pdp11_function_arg (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) @@ -1880,9 +1828,11 @@ pdp11_function_arg (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, may not be available.) */ static void -pdp11_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +pdp11_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + *cum += (mode != BLKmode ? GET_MODE_SIZE (mode) : int_size_in_bytes (type)); diff --git a/gcc/config/picochip/picochip.c b/gcc/config/picochip/picochip.c index f755020b2f6..c3a7046763a 100644 --- a/gcc/config/picochip/picochip.c +++ b/gcc/config/picochip/picochip.c @@ -1,5 +1,5 @@ /* Subroutines used for code generation on picoChip processors. - Copyright (C) 2001, 2008, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2001, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Contributed by Picochip Ltd. (http://www.picochip.com) Maintained by Daniel Towner (daniel.towner@picochip.com) and Hariharan Sandanagobalane (hariharan@picochip.com) @@ -77,16 +77,16 @@ void picochip_asm_file_end (void); void picochip_init_libfuncs (void); void picochip_reorg (void); -int picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum, +int picochip_arg_partial_bytes (cumulative_args_t p_cum, enum machine_mode mode, tree type, bool named); -rtx picochip_function_arg (CUMULATIVE_ARGS * p_cum, +rtx picochip_function_arg (cumulative_args_t p_cum, enum machine_mode mode, const_tree type, bool named); -rtx picochip_incoming_function_arg (CUMULATIVE_ARGS * p_cum, +rtx picochip_incoming_function_arg (cumulative_args_t p_cum, enum machine_mode mode, const_tree type, bool named); -void picochip_arg_advance (CUMULATIVE_ARGS * p_cum, enum machine_mode mode, +void picochip_arg_advance (cumulative_args_t p_cum, enum machine_mode mode, const_tree type, bool named); unsigned int picochip_function_arg_boundary (enum machine_mode mode, const_tree type); @@ -192,13 +192,6 @@ static struct recog_data picochip_saved_recog_data; /* Determine which ALU to use for the instruction in picochip_current_prescan_insn. */ static char picochip_get_vliw_alu_id (void); - -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options picochip_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; /* Initialize the GCC target structure. */ @@ -250,9 +243,6 @@ static const struct default_options picochip_option_optimization_table[] = #undef TARGET_ASM_NAMED_SECTION #define TARGET_ASM_NAMED_SECTION picochip_asm_named_section -#undef TARGET_HAVE_NAMED_SECTIONS -#define TARGET_HAVE_NAMED_SECTIONS 1 - #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS 1 @@ -330,12 +320,6 @@ static const struct default_options picochip_option_optimization_table[] = #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE picochip_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE picochip_option_optimization_table - -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info - /* The 2nd scheduling pass option is switched off, and a machine dependent reorganisation ensures that it is run later on, after the second jump optimisation. */ @@ -837,9 +821,10 @@ picochip_compute_arg_size (const_tree type, enum machine_mode mode) /* Determine where the next outgoing arg should be placed. */ rtx -picochip_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +picochip_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int reg = 0; int type_align_in_units = 0; int type_size_in_units; @@ -935,7 +920,7 @@ picochip_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, passed in registers, which are then pushed onto the stack by the function prologue). */ rtx -picochip_incoming_function_arg (CUMULATIVE_ARGS *cum, +picochip_incoming_function_arg (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named) { @@ -969,7 +954,7 @@ picochip_function_arg_boundary (enum machine_mode mode, /* Compute partial registers. */ int -picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum, enum machine_mode mode, +picochip_arg_partial_bytes (cumulative_args_t p_cum, enum machine_mode mode, tree type, bool named ATTRIBUTE_UNUSED) { int type_align_in_units = 0; @@ -977,7 +962,7 @@ picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum, enum machine_mode mode, int new_offset = 0; int offset_overflow = 0; - unsigned cum = *((unsigned *) p_cum); + unsigned cum = *get_cumulative_args (p_cum); /* VOIDmode is passed when computing the second argument to a `call' pattern. This can be ignored. */ @@ -1025,9 +1010,10 @@ picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum, enum machine_mode mode, /* Advance the cumulative args counter CUM. */ void -picochip_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +picochip_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int type_align_in_units = 0; int type_size_in_units; int new_offset = 0; diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index b7b60c0485f..36f2a4c124a 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -171,7 +171,6 @@ extern unsigned int rs6000_dbx_register_number (unsigned int); extern void rs6000_emit_epilogue (int); extern void rs6000_emit_eh_reg_restore (rtx, rtx); extern const char * output_isel (rtx *); -extern bool rs6000_tls_referenced_p (rtx); extern void rs6000_aix_asm_output_dwarf_table_ref (char *); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 4827c26f19d..cea1650ac61 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -48,6 +48,7 @@ #include "tm_p.h" #include "target.h" #include "target-def.h" +#include "common/common-target.h" #include "langhooks.h" #include "reload.h" #include "cfglayout.h" @@ -1044,11 +1045,7 @@ static rtx altivec_expand_vec_set_builtin (tree); static rtx altivec_expand_vec_ext_builtin (tree, rtx); static int get_element_number (tree, tree); static void rs6000_option_override (void); -static void rs6000_option_init_struct (struct gcc_options *); static void rs6000_option_default_params (void); -static bool rs6000_handle_option (struct gcc_options *, struct gcc_options *, - const struct cl_decoded_option *, - location_t); static int rs6000_loop_align_max_skip (rtx); static int first_altivec_reg_to_save (void); static unsigned int compute_vrsave_mask (void); @@ -1084,19 +1081,19 @@ static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *, rtx[], int *); static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool); static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int); -static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void rs6000_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); -static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx rs6000_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); static unsigned int rs6000_function_arg_boundary (enum machine_mode, const_tree); static void rs6000_move_block_from_reg (int regno, rtx x, int nregs); -static void setup_incoming_varargs (CUMULATIVE_ARGS *, +static void setup_incoming_varargs (cumulative_args_t, enum machine_mode, tree, int *, int); -static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, +static bool rs6000_pass_by_reference (cumulative_args_t, enum machine_mode, const_tree, bool); -static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, +static int rs6000_arg_partial_bytes (cumulative_args_t, enum machine_mode, tree, bool); static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree); #if TARGET_MACHO @@ -1290,13 +1287,6 @@ static const struct attribute_spec rs6000_attribute_table[] = #endif { NULL, 0, 0, false, false, false, NULL, false } }; - -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options rs6000_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; #ifndef MASK_STRICT_ALIGN #define MASK_STRICT_ALIGN 0 @@ -1532,32 +1522,19 @@ static const struct default_options rs6000_option_optimization_table[] = #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION rs6000_handle_option - #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE rs6000_option_override -#undef TARGET_OPTION_INIT_STRUCT -#define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct - #undef TARGET_OPTION_DEFAULT_PARAMS #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table - #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \ rs6000_builtin_vectorized_function -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS \ - (TARGET_DEFAULT) - #ifndef TARGET_MACHO #undef TARGET_STACK_PROTECT_FAIL #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail @@ -3701,21 +3678,6 @@ rs6000_preferred_simd_mode (enum machine_mode mode) return word_mode; } -/* Implement TARGET_OPTION_INIT_STRUCT. */ - -static void -rs6000_option_init_struct (struct gcc_options *opts) -{ - if (DEFAULT_ABI == ABI_DARWIN) - /* The Darwin libraries never set errno, so we might as well - avoid calling them when that's the only reason we would. */ - opts->x_flag_errno_math = 0; - - /* Enable section anchors by default. */ - if (!TARGET_MACHO) - opts->x_flag_section_anchors = 1; -} - /* Implement TARGET_OPTION_DEFAULT_PARAMS. */ static void @@ -4051,259 +4013,6 @@ rs6000_builtin_vectorized_function (tree fndecl, tree type_out, return NULL_TREE; } - - -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set, - const struct cl_decoded_option *decoded, - location_t loc) -{ - enum fpu_type_t fpu_type = FPU_NONE; - char *p, *q; - size_t code = decoded->opt_index; - const char *arg = decoded->arg; - int value = decoded->value; - - switch (code) - { - case OPT_mno_power: - opts->x_target_flags &= ~(MASK_POWER | MASK_POWER2 - | MASK_MULTIPLE | MASK_STRING); - opts_set->x_target_flags |= (MASK_POWER | MASK_POWER2 - | MASK_MULTIPLE | MASK_STRING); - break; - case OPT_mno_powerpc: - opts->x_target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT - | MASK_PPC_GFXOPT | MASK_POWERPC64); - opts_set->x_target_flags |= (MASK_POWERPC | MASK_PPC_GPOPT - | MASK_PPC_GFXOPT | MASK_POWERPC64); - break; - case OPT_mfull_toc: - opts->x_target_flags &= ~MASK_MINIMAL_TOC; - opts->x_TARGET_NO_FP_IN_TOC = 0; - opts->x_TARGET_NO_SUM_IN_TOC = 0; - opts_set->x_target_flags |= MASK_MINIMAL_TOC; -#ifdef TARGET_USES_SYSV4_OPT - /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be - just the same as -mminimal-toc. */ - opts->x_target_flags |= MASK_MINIMAL_TOC; - opts_set->x_target_flags |= MASK_MINIMAL_TOC; -#endif - break; - -#ifdef TARGET_USES_SYSV4_OPT - case OPT_mtoc: - /* Make -mtoc behave like -mminimal-toc. */ - opts->x_target_flags |= MASK_MINIMAL_TOC; - opts_set->x_target_flags |= MASK_MINIMAL_TOC; - break; -#endif - -#ifdef TARGET_USES_AIX64_OPT - case OPT_maix64: -#else - case OPT_m64: -#endif - opts->x_target_flags |= MASK_POWERPC64 | MASK_POWERPC; - opts->x_target_flags |= ~opts_set->x_target_flags & MASK_PPC_GFXOPT; - opts_set->x_target_flags |= MASK_POWERPC64 | MASK_POWERPC; - break; - -#ifdef TARGET_USES_AIX64_OPT - case OPT_maix32: -#else - case OPT_m32: -#endif - opts->x_target_flags &= ~MASK_POWERPC64; - opts_set->x_target_flags |= MASK_POWERPC64; - break; - - case OPT_mminimal_toc: - if (value == 1) - { - opts->x_TARGET_NO_FP_IN_TOC = 0; - opts->x_TARGET_NO_SUM_IN_TOC = 0; - } - break; - - case OPT_mpower: - if (value == 1) - { - opts->x_target_flags |= (MASK_MULTIPLE | MASK_STRING); - opts_set->x_target_flags |= (MASK_MULTIPLE | MASK_STRING); - } - break; - - case OPT_mpower2: - if (value == 1) - { - opts->x_target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING); - opts_set->x_target_flags |= (MASK_POWER - | MASK_MULTIPLE - | MASK_STRING); - } - break; - - case OPT_mpowerpc_gpopt: - case OPT_mpowerpc_gfxopt: - if (value == 1) - { - opts->x_target_flags |= MASK_POWERPC; - opts_set->x_target_flags |= MASK_POWERPC; - } - break; - - case OPT_mdebug_: - p = ASTRDUP (arg); - opts->x_rs6000_debug = 0; - - while ((q = strtok (p, ",")) != NULL) - { - unsigned mask = 0; - bool invert; - - p = NULL; - if (*q == '!') - { - invert = true; - q++; - } - else - invert = false; - - if (! strcmp (q, "all")) - mask = MASK_DEBUG_ALL; - else if (! strcmp (q, "stack")) - mask = MASK_DEBUG_STACK; - else if (! strcmp (q, "arg")) - mask = MASK_DEBUG_ARG; - else if (! strcmp (q, "reg")) - mask = MASK_DEBUG_REG; - else if (! strcmp (q, "addr")) - mask = MASK_DEBUG_ADDR; - else if (! strcmp (q, "cost")) - mask = MASK_DEBUG_COST; - else if (! strcmp (q, "target")) - mask = MASK_DEBUG_TARGET; - else - error_at (loc, "unknown -mdebug-%s switch", q); - - if (invert) - opts->x_rs6000_debug &= ~mask; - else - opts->x_rs6000_debug |= mask; - } - break; - -#ifdef TARGET_USES_SYSV4_OPT - case OPT_mrelocatable: - if (value == 1) - { - opts->x_target_flags |= MASK_MINIMAL_TOC; - opts_set->x_target_flags |= MASK_MINIMAL_TOC; - opts->x_TARGET_NO_FP_IN_TOC = 1; - } - break; - - case OPT_mrelocatable_lib: - if (value == 1) - { - opts->x_target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC; - opts_set->x_target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC; - opts->x_TARGET_NO_FP_IN_TOC = 1; - } - else - { - opts->x_target_flags &= ~MASK_RELOCATABLE; - opts_set->x_target_flags |= MASK_RELOCATABLE; - } - break; -#endif - - case OPT_mabi_altivec: - /* Enabling the AltiVec ABI turns off the SPE ABI. */ - opts->x_rs6000_spe_abi = 0; - break; - - case OPT_mabi_spe: - opts->x_rs6000_altivec_abi = 0; - break; - - case OPT_mlong_double_: - if (value != 64 && value != 128) - { - error_at (loc, "unknown switch -mlong-double-%s", arg); - opts->x_rs6000_long_double_type_size - = RS6000_DEFAULT_LONG_DOUBLE_SIZE; - return false; - } - break; - - case OPT_msingle_float: - if (!TARGET_SINGLE_FPU) - warning_at (loc, 0, - "-msingle-float option equivalent to -mhard-float"); - /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */ - opts->x_rs6000_double_float = 0; - opts->x_target_flags &= ~MASK_SOFT_FLOAT; - opts_set->x_target_flags |= MASK_SOFT_FLOAT; - break; - - case OPT_mdouble_float: - /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */ - opts->x_rs6000_single_float = 1; - opts->x_target_flags &= ~MASK_SOFT_FLOAT; - opts_set->x_target_flags |= MASK_SOFT_FLOAT; - break; - - case OPT_msimple_fpu: - if (!TARGET_SINGLE_FPU) - warning_at (loc, 0, "-msimple-fpu option ignored"); - break; - - case OPT_mhard_float: - /* -mhard_float implies -msingle-float and -mdouble-float. */ - opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1; - break; - - case OPT_msoft_float: - /* -msoft_float implies -mnosingle-float and -mnodouble-float. */ - opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0; - break; - - case OPT_mfpu_: - fpu_type = (enum fpu_type_t) value; - if (fpu_type != FPU_NONE) - { - /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on - HARD_FLOAT. */ - opts->x_target_flags &= ~MASK_SOFT_FLOAT; - opts_set->x_target_flags |= MASK_SOFT_FLOAT; - opts->x_rs6000_xilinx_fpu = 1; - if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL) - opts->x_rs6000_single_float = 1; - if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL) - opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1; - if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE) - opts->x_rs6000_simple_fpu = 1; - } - else - { - /* -mfpu=none is equivalent to -msoft-float. */ - opts->x_target_flags |= MASK_SOFT_FLOAT; - opts_set->x_target_flags |= MASK_SOFT_FLOAT; - opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0; - } - break; - - case OPT_mrecip: - opts->x_rs6000_recip_name = (value) ? "default" : "none"; - break; - } - return true; -} /* Default CPU string for rs6000*_file_start functions. */ static const char *rs6000_default_cpu; @@ -6094,12 +5803,13 @@ rs6000_delegitimize_address (rtx orig_x) || TARGET_MINIMAL_TOC || TARGET_CMODEL != CMODEL_SMALL)) || (TARGET_CMODEL != CMODEL_SMALL - && GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG - && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER - && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH + && GET_CODE (XEXP (x, 0)) == CONST + && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS + && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == REG + && REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0)) == TOC_REGISTER + && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == HIGH && rtx_equal_p (XEXP (x, 1), - XEXP (XEXP (XEXP (x, 0), 1), 0))))) + XEXP (XEXP (XEXP (XEXP (x, 0), 0), 1), 0))))) { y = XVECEXP (y, 0, 0); if (offset != NULL_RTX) @@ -6335,7 +6045,7 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model) /* Return 1 if X contains a thread-local symbol. */ -bool +static bool rs6000_tls_referenced_p (rtx x) { if (! TARGET_HAVE_TLS) @@ -6349,6 +6059,11 @@ rs6000_tls_referenced_p (rtx x) static bool rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) { + if (GET_CODE (x) == CONST + && GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH) + return true; + return rs6000_tls_referenced_p (x); } @@ -6438,11 +6153,12 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, && GET_CODE (XEXP (x, 0)) == PLUS && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER - && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST + && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == HIGH && GET_CODE (XEXP (x, 1)) == CONST && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL - && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1))) + && rtx_equal_p (XEXP (XEXP (XEXP (XEXP (x, 0), 1), 0), 0), XEXP (x, 1))) { push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, @@ -7488,6 +7204,11 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) } else if (mode == Pmode && CONSTANT_P (operands[1]) + && GET_CODE (operands[1]) != HIGH + && !(TARGET_CMODEL != CMODEL_SMALL + && GET_CODE (operands[1]) == CONST + && GET_CODE (XEXP (operands[1], 0)) == PLUS + && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == HIGH) && ((GET_CODE (operands[1]) != CONST_INT && ! easy_fp_constant (operands[1], mode)) || (GET_CODE (operands[1]) == CONST_INT @@ -7495,7 +7216,6 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2))) || (GET_CODE (operands[0]) == REG && FP_REGNO_P (REGNO (operands[0])))) - && GET_CODE (operands[1]) != HIGH && ! legitimate_constant_pool_address_p (operands[1], mode, false) && ! toc_relative_expr_p (operands[1]) @@ -8331,10 +8051,11 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode, } static void -rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +rs6000_function_arg_advance (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named) { - rs6000_function_arg_advance_1 (cum, mode, type, named, 0); + rs6000_function_arg_advance_1 (get_cumulative_args (cum), mode, type, named, + 0); } static rtx @@ -8698,9 +8419,10 @@ rs6000_mixed_function_arg (enum machine_mode mode, const_tree type, itself. */ static rtx -rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); enum rs6000_abi abi = DEFAULT_ABI; /* Return a marker to indicate whether CR1 needs to set or clear the @@ -8970,9 +8692,10 @@ rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, returns the number of bytes used by the first element of the PARALLEL. */ static int -rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, +rs6000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode, tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int ret = 0; int align_words; @@ -9033,7 +8756,7 @@ rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, reference. */ static bool -rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { @@ -9133,7 +8856,7 @@ rs6000_move_block_from_reg (int regno, rtx x, int nregs) stack and set PRETEND_SIZE to the length of the registers pushed. */ static void -setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, +setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode, tree type, int *pretend_size ATTRIBUTE_UNUSED, int no_rtl) { @@ -9144,7 +8867,7 @@ setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, alias_set_type set; /* Skip the last named argument. */ - next_cum = *cum; + next_cum = *get_cumulative_args (cum); rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0); if (DEFAULT_ABI == ABI_V4) @@ -19351,7 +19074,9 @@ create_TOC_reference (rtx symbol, rtx largetoc_reg) tocreg = gen_rtx_REG (Pmode, TOC_REGISTER); if (TARGET_CMODEL != CMODEL_SMALL) { - rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel)); + rtx hi = gen_rtx_CONST (Pmode, + gen_rtx_PLUS (Pmode, tocreg, + gen_rtx_HIGH (Pmode, tocrel))); if (largetoc_reg != NULL) { emit_move_insn (largetoc_reg, hi); diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 586e9e4a83b..e70598d9f3e 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -10133,7 +10133,7 @@ li %0,%1 lis %0,%v1 # - {cal|la} %0,%a1 + la %0,%a1 fmr %0,%1 lfd%U1%X1 %0,%1 stfd%U0%X0 %1,%0 @@ -10158,7 +10158,7 @@ li %0,%1 lis %0,%v1 # - {cal|la} %0,%a1 + la %0,%a1 fmr %0,%1 lfd%U1%X1 %0,%1 stfd%U0%X0 %1,%0 @@ -11523,9 +11523,10 @@ "addi %0,%1,%2@got@tlsgd" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 3) - (plus:TLSmode (match_dup 1) - (high:TLSmode - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)))) + (const:TLSmode + (plus:TLSmode (match_dup 1) + (high:TLSmode + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD))))) (set (match_dup 0) (lo_sum:TLSmode (match_dup 3) (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)))] @@ -11540,10 +11541,11 @@ (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD))))] + (const:TLSmode + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGD)))))] "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%2@got@tlsgd@ha" [(set_attr "length" "4")]) @@ -11658,9 +11660,10 @@ "addi %0,%1,%&@got@tlsld" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 2) - (plus:TLSmode (match_dup 1) - (high:TLSmode - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))) + (const:TLSmode + (plus:TLSmode (match_dup 1) + (high:TLSmode + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD))))) (set (match_dup 0) (lo_sum:TLSmode (match_dup 2) (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))] @@ -11675,9 +11678,10 @@ (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (high:TLSmode - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD))))] + (const:TLSmode + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))))] "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%&@got@tlsld@ha" [(set_attr "length" "4")]) @@ -11753,9 +11757,10 @@ "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 3) - (plus:TLSmode (match_dup 1) - (high:TLSmode - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL)))) + (const:TLSmode + (plus:TLSmode (match_dup 1) + (high:TLSmode + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL))))) (set (match_dup 0) (lo_sum:TLSmode (match_dup 3) (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL)))] @@ -11770,10 +11775,11 @@ (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTDTPREL))))] + (const:TLSmode + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTDTPREL)))))] "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%2@got@dtprel@ha" [(set_attr "length" "4")]) @@ -11823,9 +11829,10 @@ "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 3) - (plus:TLSmode (match_dup 1) - (high:TLSmode - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL)))) + (const:TLSmode + (plus:TLSmode (match_dup 1) + (high:TLSmode + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL))))) (set (match_dup 0) (lo_sum:TLSmode (match_dup 3) (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL)))] @@ -11840,10 +11847,11 @@ (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTTPREL))))] + (const:TLSmode + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTTPREL)))))] "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%2@got@tprel@ha" [(set_attr "length" "4")]) @@ -12157,8 +12165,9 @@ ;; Largetoc support (define_insn "largetoc_high" [(set (match_operand:DI 0 "gpc_reg_operand" "=b") - (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b") - (high:DI (match_operand:DI 2 "" ""))))] + (const:DI + (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b") + (high:DI (match_operand:DI 2 "" "")))))] "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" "{cau|addis} %0,%1,%2@ha") @@ -15889,25 +15898,88 @@ "{stm|stmw} %2,%1" [(set_attr "type" "store_ux")]) -(define_insn "*save_gpregs_<mode>" +; The following comment applies to: +; save_gpregs_* +; save_fpregs_* +; restore_gpregs* +; return_and_restore_gpregs* +; return_and_restore_fpregs* +; return_and_restore_fpregs_aix* +; +; The out-of-line save / restore functions expects one input argument. +; Since those are not standard call_insn's, we must avoid using +; MATCH_OPERAND for that argument. That way the register rename +; optimization will not try to rename this register. +; Each pattern is repeated for each possible register number used in +; various ABIs (r11, r1, and for some functions r12) + +(define_insn "*save_gpregs_<mode>_r11" [(match_parallel 0 "any_parallel_operand" [(clobber (reg:P 65)) (use (match_operand:P 1 "symbol_ref_operand" "s")) - (use (match_operand:P 2 "gpc_reg_operand" "r")) - (set (match_operand:P 3 "memory_operand" "=m") - (match_operand:P 4 "gpc_reg_operand" "r"))])] + (use (reg:P 11)) + (set (match_operand:P 2 "memory_operand" "=m") + (match_operand:P 3 "gpc_reg_operand" "r"))])] "" "bl %1" [(set_attr "type" "branch") (set_attr "length" "4")]) -(define_insn "*save_fpregs_<mode>" +(define_insn "*save_gpregs_<mode>_r12" [(match_parallel 0 "any_parallel_operand" [(clobber (reg:P 65)) (use (match_operand:P 1 "symbol_ref_operand" "s")) - (use (match_operand:P 2 "gpc_reg_operand" "r")) - (set (match_operand:DF 3 "memory_operand" "=m") - (match_operand:DF 4 "gpc_reg_operand" "d"))])] + (use (reg:P 12)) + (set (match_operand:P 2 "memory_operand" "=m") + (match_operand:P 3 "gpc_reg_operand" "r"))])] + "" + "bl %1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*save_gpregs_<mode>_r1" + [(match_parallel 0 "any_parallel_operand" + [(clobber (reg:P 65)) + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (use (reg:P 1)) + (set (match_operand:P 2 "memory_operand" "=m") + (match_operand:P 3 "gpc_reg_operand" "r"))])] + "" + "bl %1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*save_fpregs_<mode>_r11" + [(match_parallel 0 "any_parallel_operand" + [(clobber (reg:P 65)) + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (use (reg:P 11)) + (set (match_operand:DF 2 "memory_operand" "=m") + (match_operand:DF 3 "gpc_reg_operand" "d"))])] + "" + "bl %1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*save_fpregs_<mode>_r12" + [(match_parallel 0 "any_parallel_operand" + [(clobber (reg:P 65)) + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (use (reg:P 12)) + (set (match_operand:DF 2 "memory_operand" "=m") + (match_operand:DF 3 "gpc_reg_operand" "d"))])] + "" + "bl %1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*save_fpregs_<mode>_r1" + [(match_parallel 0 "any_parallel_operand" + [(clobber (reg:P 65)) + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (use (reg:P 1)) + (set (match_operand:DF 2 "memory_operand" "=m") + (match_operand:DF 3 "gpc_reg_operand" "d"))])] "" "bl %1" [(set_attr "type" "branch") @@ -16005,52 +16077,156 @@ ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible... -(define_insn "*restore_gpregs_<mode>" +; The following comment applies to: +; save_gpregs_* +; save_fpregs_* +; restore_gpregs* +; return_and_restore_gpregs* +; return_and_restore_fpregs* +; return_and_restore_fpregs_aix* +; +; The out-of-line save / restore functions expects one input argument. +; Since those are not standard call_insn's, we must avoid using +; MATCH_OPERAND for that argument. That way the register rename +; optimization will not try to rename this register. +; Each pattern is repeated for each possible register number used in +; various ABIs (r11, r1, and for some functions r12) + +(define_insn "*restore_gpregs_<mode>_r11" + [(match_parallel 0 "any_parallel_operand" + [(clobber (match_operand:P 1 "register_operand" "=l")) + (use (match_operand:P 2 "symbol_ref_operand" "s")) + (use (reg:P 11)) + (set (match_operand:P 3 "gpc_reg_operand" "=r") + (match_operand:P 4 "memory_operand" "m"))])] + "" + "bl %2" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*restore_gpregs_<mode>_r12" [(match_parallel 0 "any_parallel_operand" [(clobber (match_operand:P 1 "register_operand" "=l")) (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (match_operand:P 3 "gpc_reg_operand" "r")) - (set (match_operand:P 4 "gpc_reg_operand" "=r") - (match_operand:P 5 "memory_operand" "m"))])] + (use (reg:P 12)) + (set (match_operand:P 3 "gpc_reg_operand" "=r") + (match_operand:P 4 "memory_operand" "m"))])] "" "bl %2" [(set_attr "type" "branch") (set_attr "length" "4")]) -(define_insn "*return_and_restore_gpregs_<mode>" +(define_insn "*restore_gpregs_<mode>_r1" + [(match_parallel 0 "any_parallel_operand" + [(clobber (match_operand:P 1 "register_operand" "=l")) + (use (match_operand:P 2 "symbol_ref_operand" "s")) + (use (reg:P 1)) + (set (match_operand:P 3 "gpc_reg_operand" "=r") + (match_operand:P 4 "memory_operand" "m"))])] + "" + "bl %2" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*return_and_restore_gpregs_<mode>_r11" + [(match_parallel 0 "any_parallel_operand" + [(return) + (clobber (match_operand:P 1 "register_operand" "=l")) + (use (match_operand:P 2 "symbol_ref_operand" "s")) + (use (reg:P 11)) + (set (match_operand:P 3 "gpc_reg_operand" "=r") + (match_operand:P 4 "memory_operand" "m"))])] + "" + "b %2" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*return_and_restore_gpregs_<mode>_r12" + [(match_parallel 0 "any_parallel_operand" + [(return) + (clobber (match_operand:P 1 "register_operand" "=l")) + (use (match_operand:P 2 "symbol_ref_operand" "s")) + (use (reg:P 12)) + (set (match_operand:P 3 "gpc_reg_operand" "=r") + (match_operand:P 4 "memory_operand" "m"))])] + "" + "b %2" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*return_and_restore_gpregs_<mode>_r1" + [(match_parallel 0 "any_parallel_operand" + [(return) + (clobber (match_operand:P 1 "register_operand" "=l")) + (use (match_operand:P 2 "symbol_ref_operand" "s")) + (use (reg:P 1)) + (set (match_operand:P 3 "gpc_reg_operand" "=r") + (match_operand:P 4 "memory_operand" "m"))])] + "" + "b %2" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*return_and_restore_fpregs_<mode>_r11" + [(match_parallel 0 "any_parallel_operand" + [(return) + (clobber (match_operand:P 1 "register_operand" "=l")) + (use (match_operand:P 2 "symbol_ref_operand" "s")) + (use (reg:P 11)) + (set (match_operand:DF 3 "gpc_reg_operand" "=d") + (match_operand:DF 4 "memory_operand" "m"))])] + "" + "b %2" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*return_and_restore_fpregs_<mode>_r12" [(match_parallel 0 "any_parallel_operand" [(return) (clobber (match_operand:P 1 "register_operand" "=l")) (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (match_operand:P 3 "gpc_reg_operand" "r")) - (set (match_operand:P 4 "gpc_reg_operand" "=r") - (match_operand:P 5 "memory_operand" "m"))])] + (use (reg:P 12)) + (set (match_operand:DF 3 "gpc_reg_operand" "=d") + (match_operand:DF 4 "memory_operand" "m"))])] "" "b %2" [(set_attr "type" "branch") (set_attr "length" "4")]) -(define_insn "*return_and_restore_fpregs_<mode>" +(define_insn "*return_and_restore_fpregs_<mode>_r1" [(match_parallel 0 "any_parallel_operand" [(return) (clobber (match_operand:P 1 "register_operand" "=l")) (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (match_operand:P 3 "gpc_reg_operand" "r")) - (set (match_operand:DF 4 "gpc_reg_operand" "=d") - (match_operand:DF 5 "memory_operand" "m"))])] + (use (reg:P 1)) + (set (match_operand:DF 3 "gpc_reg_operand" "=d") + (match_operand:DF 4 "memory_operand" "m"))])] + "" + "b %2" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*return_and_restore_fpregs_aix_<mode>_r11" + [(match_parallel 0 "any_parallel_operand" + [(return) + (use (match_operand:P 1 "register_operand" "l")) + (use (match_operand:P 2 "symbol_ref_operand" "s")) + (use (reg:P 11)) + (set (match_operand:DF 3 "gpc_reg_operand" "=d") + (match_operand:DF 4 "memory_operand" "m"))])] "" "b %2" [(set_attr "type" "branch") (set_attr "length" "4")]) -(define_insn "*return_and_restore_fpregs_aix_<mode>" +(define_insn "*return_and_restore_fpregs_aix_<mode>_r1" [(match_parallel 0 "any_parallel_operand" [(return) (use (match_operand:P 1 "register_operand" "l")) (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (match_operand:P 3 "gpc_reg_operand" "r")) - (set (match_operand:DF 4 "gpc_reg_operand" "=d") - (match_operand:DF 5 "memory_operand" "m"))])] + (use (reg:P 1)) + (set (match_operand:DF 3 "gpc_reg_operand" "=d") + (match_operand:DF 4 "memory_operand" "m"))])] "" "b %2" [(set_attr "type" "branch") diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000 index 588572cb008..5204f589d5d 100644 --- a/gcc/config/rs6000/t-rs6000 +++ b/gcc/config/rs6000/t-rs6000 @@ -27,7 +27,7 @@ rs6000.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(OBSTACK_H) $(TREE_H) $(EXPR_H) $(OPTABS_H) except.h function.h \ output.h $(BASIC_BLOCK_H) $(INTEGRATE_H) toplev.h $(GGC_H) $(HASHTAB_H) \ $(TM_P_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h reload.h gt-rs6000.h \ - cfglayout.h cfgloop.h $(OPTS_H) + cfglayout.h cfgloop.h $(OPTS_H) $(COMMON_TARGET_H) rs6000-c.o: $(srcdir)/config/rs6000/rs6000-c.c \ $(srcdir)/config/rs6000/rs6000-protos.h \ diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c index 70d41593fb1..ddc4dec63d1 100644 --- a/gcc/config/rx/rx.c +++ b/gcc/config/rx/rx.c @@ -832,11 +832,11 @@ rx_function_arg_size (enum machine_mode mode, const_tree type) variable parameter list. */ static rtx -rx_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, +rx_function_arg (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named) { unsigned int next_reg; - unsigned int bytes_so_far = *cum; + unsigned int bytes_so_far = *get_cumulative_args (cum); unsigned int size; unsigned int rounded_size; @@ -870,10 +870,10 @@ rx_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, } static void -rx_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode, +rx_function_arg_advance (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { - *cum += rx_function_arg_size (mode, type); + *get_cumulative_args (cum) += rx_function_arg_size (mode, type); } static unsigned int @@ -2283,46 +2283,6 @@ const struct attribute_spec rx_attribute_table[] = { NULL, 0, 0, false, false, false, NULL, false } }; -/* Extra processing for target specific command line options. */ - -static bool -rx_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc) -{ - size_t code = decoded->opt_index; - int value = decoded->value; - - switch (code) - { - case OPT_mint_register_: - /* Make sure that the -mint-register option is in range. Other - handling in rx_option_override. */ - return value >= 0 && value <= 4; - break; - - case OPT_mmax_constant_size_: - /* Make sure that the -mmax-constant_size option is in range. */ - return value >= 0 && value <= 4; - - case OPT_mcpu_: - if ((enum rx_cpu_types) value == RX200) - opts->x_target_flags |= MASK_NO_USE_FPU; - break; - - case OPT_fpu: - if (opts->x_rx_cpu_type == RX200) - error_at (loc, "the RX200 cpu does not have FPU hardware"); - break; - - default: - break; - } - - return true; -} - /* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE. */ static void @@ -2405,13 +2365,6 @@ rx_option_override (void) align_labels = 3; } -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options rx_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - static bool rx_allocate_stack_slots_for_args (void) @@ -3027,9 +2980,6 @@ rx_adjust_insn_length (rtx insn, int current_length) #undef TARGET_SET_CURRENT_FUNCTION #define TARGET_SET_CURRENT_FUNCTION rx_set_current_function -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION rx_handle_option - #undef TARGET_ASM_INTEGER #define TARGET_ASM_INTEGER rx_assemble_integer @@ -3069,18 +3019,12 @@ rx_adjust_insn_length (rtx insn, int current_length) #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE rx_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE rx_option_optimization_table - #undef TARGET_PROMOTE_FUNCTION_MODE #define TARGET_PROMOTE_FUNCTION_MODE rx_promote_function_mode #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE rx_override_options_after_change -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info - #undef TARGET_FLAGS_REGNUM #define TARGET_FLAGS_REGNUM CC_REG diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index e86755b37d9..a91f4c1107c 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -55,22 +55,6 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "opts.h" -static const int processor_flags_table[] = - { - /* g5 */ PF_IEEE_FLOAT, - /* g6 */ PF_IEEE_FLOAT, - /* z900 */ PF_IEEE_FLOAT | PF_ZARCH, - /* z990 */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT, - /* z9-109 */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT - | PF_EXTIMM, - /* z9-ec */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT - | PF_EXTIMM | PF_DFP, - /* z10 */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT - | PF_EXTIMM | PF_DFP | PF_Z10, - /* z196 */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT - | PF_EXTIMM | PF_DFP | PF_Z10 | PF_Z196 - }; - /* Define the specific costs for a given cpu. */ struct processor_costs @@ -1519,74 +1503,6 @@ s390_init_machine_status (void) return ggc_alloc_cleared_machine_function (); } -/* Change optimizations to be performed, depending on the - optimization level. */ - -static const struct default_options s390_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - - /* ??? There are apparently still problems with -fcaller-saves. */ - { OPT_LEVELS_ALL, OPT_fcaller_saves, NULL, 0 }, - - /* Use MVCLE instructions to decrease code size if requested. */ - { OPT_LEVELS_SIZE, OPT_mmvcle, NULL, 1 }, - - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - -/* Implement TARGET_OPTION_INIT_STRUCT. */ - -static void -s390_option_init_struct (struct gcc_options *opts) -{ - /* By default, always emit DWARF-2 unwind info. This allows debugging - without maintaining a stack frame back-chain. */ - opts->x_flag_asynchronous_unwind_tables = 1; -} - -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -s390_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc) -{ - size_t code = decoded->opt_index; - const char *arg = decoded->arg; - int value = decoded->value; - - switch (code) - { - case OPT_march_: - opts->x_s390_arch_flags = processor_flags_table[value]; - opts->x_s390_arch_string = arg; - return true; - - case OPT_mstack_guard_: - if (exact_log2 (value) == -1) - error_at (loc, "stack guard value must be an exact power of 2"); - return true; - - case OPT_mstack_size_: - if (exact_log2 (value) == -1) - error_at (loc, "stack size must be an exact power of 2"); - return true; - - case OPT_mtune_: - opts->x_s390_tune_flags = processor_flags_table[value]; - return true; - - case OPT_mwarn_framesize_: - return sscanf (arg, HOST_WIDE_INT_PRINT_DEC, - &opts->x_s390_warn_framesize) == 1; - - default: - return true; - } -} - static void s390_option_override (void) { @@ -8595,7 +8511,7 @@ s390_function_arg_integer (enum machine_mode mode, const_tree type) reference. */ static bool -s390_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, +s390_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { @@ -8623,9 +8539,11 @@ s390_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, matching an ellipsis). */ static void -s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +s390_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + if (s390_function_arg_float (mode, type)) { cum->fprs += 1; @@ -8659,9 +8577,11 @@ s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, are pushed to the stack. */ static rtx -s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +s390_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + if (s390_function_arg_float (mode, type)) { if (cum->fprs + 1 > FP_ARG_NUM_REG) @@ -9706,14 +9626,16 @@ s390_valid_pointer_mode (enum machine_mode mode) static bool s390_call_saved_register_used (tree call_expr) { - CUMULATIVE_ARGS cum; + CUMULATIVE_ARGS cum_v; + cumulative_args_t cum; tree parameter; enum machine_mode mode; tree type; rtx parm_rtx; int reg, i; - INIT_CUMULATIVE_ARGS (cum, NULL, NULL, 0, 0); + INIT_CUMULATIVE_ARGS (cum_v, NULL, NULL, 0, 0); + cum = pack_cumulative_args (&cum_v); for (i = 0; i < call_expr_nargs (call_expr); i++) { @@ -9731,15 +9653,15 @@ s390_call_saved_register_used (tree call_expr) mode = TYPE_MODE (type); gcc_assert (mode); - if (pass_by_reference (&cum, mode, type, true)) + if (pass_by_reference (&cum_v, mode, type, true)) { mode = Pmode; type = build_pointer_type (type); } - parm_rtx = s390_function_arg (&cum, mode, type, 0); + parm_rtx = s390_function_arg (cum, mode, type, 0); - s390_function_arg_advance (&cum, mode, type, 0); + s390_function_arg_advance (cum, mode, type, 0); if (!parm_rtx) continue; @@ -10688,21 +10610,9 @@ s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop) #undef TARGET_ASM_CLOSE_PAREN #define TARGET_ASM_CLOSE_PAREN "" -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT) - -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION s390_handle_option - #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE s390_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE s390_option_optimization_table - -#undef TARGET_OPTION_INIT_STRUCT -#define TARGET_OPTION_INIT_STRUCT s390_option_init_struct - #undef TARGET_ENCODE_SECTION_INFO #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 47e0b1a5662..afd22ad883b 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -904,4 +904,6 @@ do { \ /* Reads can reuse write prefetches, used by tree-ssa-prefetch-loops.c. */ #define READ_CAN_USE_WRITE_PREFETCH 1 + +extern const int processor_flags_table[]; #endif diff --git a/gcc/config/score/score-protos.h b/gcc/config/score/score-protos.h index 385532940d2..3a96eabd176 100644 --- a/gcc/config/score/score-protos.h +++ b/gcc/config/score/score-protos.h @@ -1,5 +1,6 @@ /* score-protos.h for Sunplus S+CORE processor - Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. This file is part of GCC. @@ -63,9 +64,6 @@ extern enum reg_class score_preferred_reload_class (rtx x, extern HOST_WIDE_INT score_initial_elimination_offset (int from, int to); extern void score_print_operand (FILE *file, rtx op, int letter); extern void score_print_operand_address (FILE *file, rtx addr); -extern int score_arg_partial_bytes (CUMULATIVE_ARGS *cum, - enum machine_mode mode, - tree type, bool named); extern int score_symbolic_constant_p (rtx x, enum score_symbol_type *symbol_type); extern void score_movsicc (rtx *ops); diff --git a/gcc/config/score/score.c b/gcc/config/score/score.c index 1c745f06193..a9b6013bda2 100644 --- a/gcc/config/score/score.c +++ b/gcc/config/score/score.c @@ -53,13 +53,6 @@ static void score_option_override (void); -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options score_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - #undef TARGET_ASM_FILE_START #define TARGET_ASM_FILE_START score_asm_file_start @@ -72,18 +65,9 @@ static const struct default_options score_option_optimization_table[] = #undef TARGET_ASM_FUNCTION_EPILOGUE #define TARGET_ASM_FUNCTION_EPILOGUE score_function_epilogue -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT - -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION score_handle_option - #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE score_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE score_option_optimization_table - #undef TARGET_LEGITIMIZE_ADDRESS #define TARGET_LEGITIMIZE_ADDRESS score_legitimize_address @@ -168,7 +152,7 @@ score_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED) /* Return nonzero when an argument must be passed by reference. */ static bool -score_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +score_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { @@ -279,35 +263,6 @@ score_asm_file_end (void) gcc_unreachable (); } -#define MASK_ALL_CPU_BITS (MASK_SCORE7 | MASK_SCORE7D) - -/* Implement TARGET_HANDLE_OPTION. */ -static bool -score_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc ATTRIBUTE_UNUSED) -{ - size_t code = decoded->opt_index; - int value = decoded->value; - - switch (code) - { - case OPT_mscore7d: - opts->x_target_flags &= ~(MASK_ALL_CPU_BITS); - opts->x_target_flags |= MASK_SCORE7 | MASK_SCORE7D; - return true; - - case OPT_march_: - opts->x_target_flags &= ~(MASK_ALL_CPU_BITS); - opts->x_target_flags |= value; - return true; - - default: - return true; - } -} - /* Implement TARGET_OPTION_OVERRIDE hook. */ static void score_option_override (void) @@ -397,33 +352,34 @@ score_init_cumulative_args (CUMULATIVE_ARGS *cum, /* Implement TARGET_FUNCTION_ARG_ADVANCE hook. */ static void -score_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +score_function_arg_advance (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named) { if (TARGET_SCORE7 || TARGET_SCORE7D) - score7_function_arg_advance (cum, mode, type, named); + score7_function_arg_advance (get_cumulative_args (cum), mode, type, named); else gcc_unreachable (); } /* Implement TARGET_ARG_PARTIAL_BYTES macro. */ int -score_arg_partial_bytes (CUMULATIVE_ARGS *cum, +score_arg_partial_bytes (cumulative_args_t cum, enum machine_mode mode, tree type, bool named) { if (TARGET_SCORE7 || TARGET_SCORE7D) - return score7_arg_partial_bytes (cum, mode, type, named); + return score7_arg_partial_bytes (get_cumulative_args (cum), mode, type, + named); else gcc_unreachable (); } /* Implement TARGET_FUNCTION_ARG hook. */ static rtx -score_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +score_function_arg (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named) { if (TARGET_SCORE7 || TARGET_SCORE7D) - return score7_function_arg (cum, mode, type, named); + return score7_function_arg (get_cumulative_args (cum), mode, type, named); else gcc_unreachable (); } diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index f81172545a4..327a236a9e3 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -168,8 +168,6 @@ int assembler_dialect; static bool shmedia_space_reserved_for_target_registers; -static bool sh_handle_option (struct gcc_options *, struct gcc_options *, - const struct cl_decoded_option *, location_t); static void split_branches (rtx); static int branch_dest (rtx); static void force_into (rtx, rtx); @@ -184,7 +182,6 @@ static int noncall_uses_reg (rtx, rtx, rtx *); static rtx gen_block_redirect (rtx, int, int); static void sh_reorg (void); static void sh_option_override (void); -static void sh_option_init_struct (struct gcc_options *); static void sh_option_default_params (void); static void output_stack_adjust (int, rtx, int, HARD_REG_SET *, bool); static rtx frame_insn (rtx); @@ -276,9 +273,9 @@ static bool sh_function_value_regno_p (const unsigned int); static rtx sh_libcall_value (enum machine_mode, const_rtx); static bool sh_return_in_memory (const_tree, const_tree); static rtx sh_builtin_saveregs (void); -static void sh_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); -static bool sh_strict_argument_naming (CUMULATIVE_ARGS *); -static bool sh_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *); +static void sh_setup_incoming_varargs (cumulative_args_t, enum machine_mode, tree, int *, int); +static bool sh_strict_argument_naming (cumulative_args_t); +static bool sh_pretend_outgoing_varargs_named (cumulative_args_t); static tree sh_build_builtin_va_list (void); static void sh_va_start (tree, rtx); static tree sh_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *); @@ -288,15 +285,15 @@ static enum machine_mode sh_promote_function_mode (const_tree type, int *punsignedp, const_tree funtype, int for_return); -static bool sh_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, +static bool sh_pass_by_reference (cumulative_args_t, enum machine_mode, const_tree, bool); -static bool sh_callee_copies (CUMULATIVE_ARGS *, enum machine_mode, +static bool sh_callee_copies (cumulative_args_t, enum machine_mode, const_tree, bool); -static int sh_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, +static int sh_arg_partial_bytes (cumulative_args_t, enum machine_mode, tree, bool); -static void sh_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void sh_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); -static rtx sh_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx sh_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); static bool sh_scalar_mode_supported_p (enum machine_mode); static int sh_dwarf_calling_convention (const_tree); @@ -329,23 +326,6 @@ static const struct attribute_spec sh_attribute_table[] = sh2a_handle_function_vector_handler_attribute, false }, { NULL, 0, 0, false, false, false, NULL, false } }; - -/* Set default optimization options. */ -static const struct default_options sh_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_1_PLUS_SPEED_ONLY, OPT_mdiv_, "inv:minlat", 1 }, - { OPT_LEVELS_SIZE, OPT_mdiv_, SH_DIV_STR_FOR_SIZE, 1 }, - { OPT_LEVELS_0_ONLY, OPT_mdiv_, "", 1 }, - { OPT_LEVELS_SIZE, OPT_mcbranchdi, NULL, 0 }, - /* We can't meaningfully test TARGET_SHMEDIA here, because -m - options haven't been parsed yet, hence we'd read only the - default. sh_target_reg_class will return NO_REGS if this is - not SHMEDIA, so it's OK to always set - flag_branch_target_load_optimize. */ - { OPT_LEVELS_2_PLUS, OPT_fbranch_target_load_optimize, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; /* Initialize the GCC target structure. */ #undef TARGET_ATTRIBUTE_TABLE @@ -365,10 +345,6 @@ static const struct default_options sh_option_optimization_table[] = #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE sh_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE sh_option_optimization_table -#undef TARGET_OPTION_INIT_STRUCT -#define TARGET_OPTION_INIT_STRUCT sh_option_init_struct #undef TARGET_OPTION_DEFAULT_PARAMS #define TARGET_OPTION_DEFAULT_PARAMS sh_option_default_params @@ -395,11 +371,6 @@ static const struct default_options sh_option_optimization_table[] = #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION sh_handle_option - #undef TARGET_REGISTER_MOVE_COST #define TARGET_REGISTER_MOVE_COST sh_register_move_cost @@ -607,157 +578,7 @@ static const struct default_options sh_option_optimization_table[] = struct gcc_target targetm = TARGET_INITIALIZER; -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -sh_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc ATTRIBUTE_UNUSED) -{ - size_t code = decoded->opt_index; - - switch (code) - { - case OPT_m1: - opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH1; - return true; - - case OPT_m2: - opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH2; - return true; - - case OPT_m2a: - opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH2A; - return true; - - case OPT_m2a_nofpu: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH2A_NOFPU; - return true; - - case OPT_m2a_single: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH2A_SINGLE; - return true; - - case OPT_m2a_single_only: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH2A_SINGLE_ONLY; - return true; - - case OPT_m2e: - opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH2E; - return true; - - case OPT_m3: - opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH3; - return true; - - case OPT_m3e: - opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH3E; - return true; - - case OPT_m4: - case OPT_m4_100: - case OPT_m4_200: - case OPT_m4_300: - opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4; - return true; - - case OPT_m4_nofpu: - case OPT_m4_100_nofpu: - case OPT_m4_200_nofpu: - case OPT_m4_300_nofpu: - case OPT_m4_340: - case OPT_m4_400: - case OPT_m4_500: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4_NOFPU; - return true; - - case OPT_m4_single: - case OPT_m4_100_single: - case OPT_m4_200_single: - case OPT_m4_300_single: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4_SINGLE; - return true; - - case OPT_m4_single_only: - case OPT_m4_100_single_only: - case OPT_m4_200_single_only: - case OPT_m4_300_single_only: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4_SINGLE_ONLY; - return true; - - case OPT_m4a: - opts->x_target_flags = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4A; - return true; - - case OPT_m4a_nofpu: - case OPT_m4al: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4A_NOFPU; - return true; - - case OPT_m4a_single: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4A_SINGLE; - return true; - - case OPT_m4a_single_only: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH4A_SINGLE_ONLY; - return true; - - case OPT_m5_32media: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH5_32MEDIA; - return true; - - case OPT_m5_32media_nofpu: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH5_32MEDIA_NOFPU; - return true; - - case OPT_m5_64media: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH5_64MEDIA; - return true; - - case OPT_m5_64media_nofpu: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH5_64MEDIA_NOFPU; - return true; - - case OPT_m5_compact: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH5_COMPACT; - return true; - - case OPT_m5_compact_nofpu: - opts->x_target_flags - = (opts->x_target_flags & ~MASK_ARCH) | SELECT_SH5_COMPACT_NOFPU; - return true; - - default: - return true; - } -} -/* Implement TARGET_OPTION_INIT_STRUCT. */ -static void -sh_option_init_struct (struct gcc_options *opts) -{ - /* We can't meaningfully test TARGET_SH2E / TARGET_IEEE - here, so leave it to TARGET_OPTION_OVERRIDE to set - flag_finite_math_only. We set it to 2 here so we know if the user - explicitly requested this to be on or off. */ - opts->x_flag_finite_math_only = 2; -} - /* Implement TARGET_OPTION_DEFAULT_PARAMS. */ static void sh_option_default_params (void) @@ -8361,9 +8182,11 @@ shcompact_byref (const CUMULATIVE_ARGS *cum, enum machine_mode mode, } static bool -sh_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode, +sh_pass_by_reference (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + if (targetm.calls.must_pass_in_stack (mode, type)) return true; @@ -8383,21 +8206,22 @@ sh_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode, } static bool -sh_callee_copies (CUMULATIVE_ARGS *cum, enum machine_mode mode, +sh_callee_copies (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { /* ??? How can it possibly be correct to return true only on the caller side of the equation? Is there someplace else in the sh backend that's magically producing the copies? */ - return (cum->outgoing + return (get_cumulative_args (cum)->outgoing && ((mode == BLKmode ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode)) % SH_MIN_ALIGN_FOR_CALLEE_COPY == 0)); } static int -sh_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, +sh_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode, tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int words = 0; if (!TARGET_SH5 @@ -8437,9 +8261,11 @@ sh_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, its data type forbids. */ static rtx -sh_function_arg (CUMULATIVE_ARGS *ca, enum machine_mode mode, +sh_function_arg (cumulative_args_t ca_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v); + if (! TARGET_SH5 && mode == VOIDmode) return GEN_INT (ca->renesas_abi ? 1 : 0); @@ -8525,9 +8351,11 @@ sh_function_arg (CUMULATIVE_ARGS *ca, enum machine_mode mode, available.) */ static void -sh_function_arg_advance (CUMULATIVE_ARGS *ca, enum machine_mode mode, +sh_function_arg_advance (cumulative_args_t ca_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v); + if (ca->force_mem) ca->force_mem = 0; else if (TARGET_SH5) @@ -8753,7 +8581,7 @@ sh_return_in_memory (const_tree type, const_tree fndecl) later. Fortunately, we already have two flags that are part of struct function that tell if a function uses varargs or stdarg. */ static void -sh_setup_incoming_varargs (CUMULATIVE_ARGS *ca, +sh_setup_incoming_varargs (cumulative_args_t ca, enum machine_mode mode, tree type, int *pretend_arg_size, @@ -8764,7 +8592,7 @@ sh_setup_incoming_varargs (CUMULATIVE_ARGS *ca, { int named_parm_regs, anon_parm_regs; - named_parm_regs = (ROUND_REG (*ca, mode) + named_parm_regs = (ROUND_REG (*get_cumulative_args (ca), mode) + (mode == BLKmode ? ROUND_ADVANCE (int_size_in_bytes (type)) : ROUND_ADVANCE (GET_MODE_SIZE (mode)))); @@ -8775,14 +8603,16 @@ sh_setup_incoming_varargs (CUMULATIVE_ARGS *ca, } static bool -sh_strict_argument_naming (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED) +sh_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED) { return TARGET_SH5; } static bool -sh_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *ca) +sh_pretend_outgoing_varargs_named (cumulative_args_t ca_v) { + CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v); + return ! (TARGET_HITACHI || ca->renesas_abi) && ! TARGET_SH5; } @@ -11747,9 +11577,10 @@ sh_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, { tree ptype = build_pointer_type (TREE_TYPE (funtype)); - sh_function_arg_advance (&cum, Pmode, ptype, true); + sh_function_arg_advance (pack_cumulative_args (&cum), Pmode, ptype, true); } - this_rtx = sh_function_arg (&cum, Pmode, ptr_type_node, true); + this_rtx + = sh_function_arg (pack_cumulative_args (&cum), Pmode, ptr_type_node, true); /* For SHcompact, we only have r0 for a scratch register: r1 is the static chain pointer (even if you can't have nested virtual functions diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 0de98c67974..fe28d55ee43 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see #include "debug.h" #include "target.h" #include "target-def.h" +#include "common/common-target.h" #include "cfglayout.h" #include "gimple.h" #include "langhooks.h" @@ -435,7 +436,7 @@ static rtx sparc_struct_value_rtx (tree, int); static enum machine_mode sparc_promote_function_mode (const_tree, enum machine_mode, int *, const_tree, int); static bool sparc_return_in_memory (const_tree, const_tree); -static bool sparc_strict_argument_naming (CUMULATIVE_ARGS *); +static bool sparc_strict_argument_naming (cumulative_args_t); static void sparc_va_start (tree, rtx); static tree sparc_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *); static bool sparc_vector_mode_supported_p (enum machine_mode); @@ -445,19 +446,19 @@ static rtx sparc_legitimize_pic_address (rtx, rtx); static rtx sparc_legitimize_address (rtx, rtx, enum machine_mode); static rtx sparc_delegitimize_address (rtx); static bool sparc_mode_dependent_address_p (const_rtx); -static bool sparc_pass_by_reference (CUMULATIVE_ARGS *, +static bool sparc_pass_by_reference (cumulative_args_t, enum machine_mode, const_tree, bool); -static void sparc_function_arg_advance (CUMULATIVE_ARGS *, +static void sparc_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); -static rtx sparc_function_arg_1 (const CUMULATIVE_ARGS *, +static rtx sparc_function_arg_1 (cumulative_args_t, enum machine_mode, const_tree, bool, bool); -static rtx sparc_function_arg (CUMULATIVE_ARGS *, +static rtx sparc_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static rtx sparc_function_incoming_arg (CUMULATIVE_ARGS *, +static rtx sparc_function_incoming_arg (cumulative_args_t, enum machine_mode, const_tree, bool); static unsigned int sparc_function_arg_boundary (enum machine_mode, const_tree); -static int sparc_arg_partial_bytes (CUMULATIVE_ARGS *, +static int sparc_arg_partial_bytes (cumulative_args_t, enum machine_mode, tree, bool); static void sparc_dwarf_handle_frame_unspec (const char *, rtx, int); static void sparc_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; @@ -494,13 +495,6 @@ enum cmodel sparc_cmodel; char sparc_hard_reg_printed[8]; -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options sparc_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - /* Initialize the GCC target structure. */ /* The default is to use .half rather than .short for aligned HI objects. */ @@ -633,12 +627,8 @@ static const struct default_options sparc_option_optimization_table[] = #undef TARGET_RELAXED_ORDERING #define TARGET_RELAXED_ORDERING SPARC_RELAXED_ORDERING -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE sparc_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE sparc_option_optimization_table #if TARGET_GNU_TLS && defined(HAVE_AS_SPARC_UA_PCREL) #undef TARGET_ASM_OUTPUT_DWARF_DTPREL @@ -5439,7 +5429,7 @@ sparc_promote_function_mode (const_tree type, /* Handle the TARGET_STRICT_ARGUMENT_NAMING target hook. */ static bool -sparc_strict_argument_naming (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED) +sparc_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED) { return TARGET_ARCH64 ? true : false; } @@ -6085,9 +6075,11 @@ function_arg_vector_value (int size, int regno) TARGET_FUNCTION_INCOMING_ARG. */ static rtx -sparc_function_arg_1 (const CUMULATIVE_ARGS *cum, enum machine_mode mode, +sparc_function_arg_1 (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named, bool incoming_p) { + const CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + int regbase = (incoming_p ? SPARC_INCOMING_INT_ARG_FIRST : SPARC_OUTGOING_INT_ARG_FIRST); @@ -6221,7 +6213,7 @@ sparc_function_arg_1 (const CUMULATIVE_ARGS *cum, enum machine_mode mode, /* Handle the TARGET_FUNCTION_ARG target hook. */ static rtx -sparc_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +sparc_function_arg (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named) { return sparc_function_arg_1 (cum, mode, type, named, false); @@ -6230,7 +6222,7 @@ sparc_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, /* Handle the TARGET_FUNCTION_INCOMING_ARG target hook. */ static rtx -sparc_function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +sparc_function_incoming_arg (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named) { return sparc_function_arg_1 (cum, mode, type, named, true); @@ -6259,14 +6251,14 @@ sparc_function_arg_boundary (enum machine_mode mode, const_tree type) mode] will be split between that reg and memory. */ static int -sparc_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, +sparc_arg_partial_bytes (cumulative_args_t cum, enum machine_mode mode, tree type, bool named) { int slotno, regno, padding; /* We pass false for incoming_p here, it doesn't matter. */ - slotno = function_arg_slotno (cum, mode, type, named, false, - ®no, &padding); + slotno = function_arg_slotno (get_cumulative_args (cum), mode, type, named, + false, ®no, &padding); if (slotno == -1) return 0; @@ -6317,7 +6309,7 @@ sparc_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, Specify whether to pass the argument by reference. */ static bool -sparc_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +sparc_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { @@ -6370,9 +6362,10 @@ sparc_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, TYPE is null for libcalls where that information may not be available. */ static void -sparc_function_arg_advance (struct sparc_args *cum, enum machine_mode mode, +sparc_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int regno, padding; /* We pass false for incoming_p here, it doesn't matter. */ diff --git a/gcc/config/spu/spu-protos.h b/gcc/config/spu/spu-protos.h index 6774ad9c2bc..cb5cc241539 100644 --- a/gcc/config/spu/spu-protos.h +++ b/gcc/config/spu/spu-protos.h @@ -55,9 +55,6 @@ extern int spu_constant_address_p (rtx x); extern bool spu_legitimate_constant_p (enum machine_mode, rtx); extern int spu_initial_elimination_offset (int from, int to); extern rtx spu_function_value (const_tree type, const_tree func); -extern void spu_setup_incoming_varargs (int *cum, enum machine_mode mode, - tree type, int *pretend_size, - int no_rtl); extern int spu_expand_mov (rtx * ops, enum machine_mode mode); extern int spu_split_load (rtx * ops); extern int spu_split_store (rtx * ops); diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c index 9e62f16414c..0da736c8be1 100644 --- a/gcc/config/spu/spu.c +++ b/gcc/config/spu/spu.c @@ -149,7 +149,6 @@ char regs_ever_allocated[FIRST_PSEUDO_REGISTER]; /* Prototypes and external defs. */ static void spu_option_override (void); -static void spu_option_init_struct (struct gcc_options *opts); static void spu_option_default_params (void); static void spu_init_builtins (void); static tree spu_builtin_decl (unsigned, bool); @@ -188,11 +187,13 @@ static tree spu_handle_vector_attribute (tree * node, tree name, tree args, int flags, bool *no_add_attrs); static int spu_naked_function_p (tree func); -static bool spu_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode, +static bool spu_pass_by_reference (cumulative_args_t cum, + enum machine_mode mode, const_tree type, bool named); -static rtx spu_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +static rtx spu_function_arg (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named); -static void spu_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +static void spu_function_arg_advance (cumulative_args_t cum, + enum machine_mode mode, const_tree type, bool named); static tree spu_build_builtin_va_list (void); static void spu_va_start (tree, rtx); @@ -413,6 +414,10 @@ static const struct attribute_spec spu_attribute_table[] = #undef TARGET_EXPAND_BUILTIN_VA_START #define TARGET_EXPAND_BUILTIN_VA_START spu_va_start +static void spu_setup_incoming_varargs (cumulative_args_t cum, + enum machine_mode mode, + tree type, int *pretend_size, + int no_rtl); #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS spu_setup_incoming_varargs @@ -422,9 +427,6 @@ static const struct attribute_spec spu_attribute_table[] = #undef TARGET_GIMPLIFY_VA_ARG_EXPR #define TARGET_GIMPLIFY_VA_ARG_EXPR spu_gimplify_va_arg_expr -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT) - #undef TARGET_INIT_LIBFUNCS #define TARGET_INIT_LIBFUNCS spu_init_libfuncs @@ -485,15 +487,9 @@ static const struct attribute_spec spu_attribute_table[] = #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE spu_option_override -#undef TARGET_OPTION_INIT_STRUCT -#define TARGET_OPTION_INIT_STRUCT spu_option_init_struct - #undef TARGET_OPTION_DEFAULT_PARAMS #define TARGET_OPTION_DEFAULT_PARAMS spu_option_default_params -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info - #undef TARGET_CONDITIONAL_REGISTER_USAGE #define TARGET_CONDITIONAL_REGISTER_USAGE spu_conditional_register_usage @@ -512,13 +508,6 @@ static const struct attribute_spec spu_attribute_table[] = struct gcc_target targetm = TARGET_INITIALIZER; -static void -spu_option_init_struct (struct gcc_options *opts) -{ - /* With so many registers this is better on by default. */ - opts->x_flag_rename_registers = 1; -} - /* Implement TARGET_OPTION_DEFAULT_PARAMS. */ static void spu_option_default_params (void) @@ -4056,10 +4045,11 @@ spu_function_value (const_tree type, const_tree func ATTRIBUTE_UNUSED) } static rtx -spu_function_arg (CUMULATIVE_ARGS *cum, +spu_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int byte_size; if (*cum >= MAX_REGISTER_ARGS) @@ -4092,9 +4082,11 @@ spu_function_arg (CUMULATIVE_ARGS *cum, } static void -spu_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode, +spu_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + *cum += (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST ? 1 : mode == BLKmode @@ -4106,7 +4098,7 @@ spu_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode, /* Variable sized types are passed by reference. */ static bool -spu_pass_by_reference (CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED, +spu_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type, bool named ATTRIBUTE_UNUSED) { @@ -4299,8 +4291,8 @@ spu_gimplify_va_arg_expr (tree valist, tree type, gimple_seq * pre_p, to the first unnamed parameters. If the first unnamed parameter is in the stack then save no registers. Set pretend_args_size to the amount of space needed to save the registers. */ -void -spu_setup_incoming_varargs (CUMULATIVE_ARGS * cum, enum machine_mode mode, +static void +spu_setup_incoming_varargs (cumulative_args_t cum, enum machine_mode mode, tree type, int *pretend_size, int no_rtl) { if (!no_rtl) @@ -4308,11 +4300,11 @@ spu_setup_incoming_varargs (CUMULATIVE_ARGS * cum, enum machine_mode mode, rtx tmp; int regno; int offset; - int ncum = *cum; + int ncum = *get_cumulative_args (cum); /* cum currently points to the last named argument, we want to start at the next argument. */ - spu_function_arg_advance (&ncum, mode, type, true); + spu_function_arg_advance (pack_cumulative_args (&ncum), mode, type, true); offset = -STACK_POINTER_OFFSET; for (regno = ncum; regno < MAX_REGISTER_ARGS; regno++) diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c index 6edc2c1873b..97965280cb9 100644 --- a/gcc/config/stormy16/stormy16.c +++ b/gcc/config/stormy16/stormy16.c @@ -1201,9 +1201,11 @@ xstormy16_function_profiler (void) the word count. */ static void -xstormy16_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +xstormy16_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + /* If an argument would otherwise be passed partially in registers, and partially on the stack, the whole of it is passed on the stack. */ @@ -1215,9 +1217,11 @@ xstormy16_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, } static rtx -xstormy16_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +xstormy16_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + if (mode == VOIDmode) return const0_rtx; if (targetm.calls.must_pass_in_stack (mode, type) @@ -2602,13 +2606,6 @@ xstormy16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) return (size == -1 || size > UNITS_PER_WORD * NUM_ARGUMENT_REGISTERS); } -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ -static const struct default_options xstorym16_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t" #undef TARGET_ASM_ALIGNED_SI_OP @@ -2682,9 +2679,6 @@ static const struct default_options xstorym16_option_optimization_table[] = #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT xstormy16_trampoline_init -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE xstorym16_option_optimization_table - struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-stormy16.h" diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c index cb31f9aa381..5074ebe417f 100644 --- a/gcc/config/v850/v850.c +++ b/gcc/config/v850/v850.c @@ -50,14 +50,6 @@ static void v850_print_operand_address (FILE *, rtx); -/* Information about the various small memory areas. */ -static const int small_memory_physical_max[(int) SMALL_MEMORY_max] = -{ - 256, - 65536, - 32768, -}; - /* Names of the various data areas used on the v850. */ tree GHS_default_section_names [(int) COUNT_OF_GHS_SECTION_KINDS]; tree GHS_current_section_names [(int) COUNT_OF_GHS_SECTION_KINDS]; @@ -81,98 +73,11 @@ static GTY(()) section * tdata_section; static GTY(()) section * zdata_section; static GTY(()) section * zbss_section; -/* Set the maximum size of small memory area TYPE to the value given - by SIZE in structure OPTS (option text OPT passed at location LOC). */ - -static void -v850_handle_memory_option (enum small_memory_type type, - struct gcc_options *opts, const char *opt, - int size, location_t loc) -{ - if (size > small_memory_physical_max[type]) - error_at (loc, "value passed in %qs is too large", opt); - else - opts->x_small_memory_max[type] = size; -} - -/* Implement TARGET_HANDLE_OPTION. */ - -static bool -v850_handle_option (struct gcc_options *opts, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded, - location_t loc) -{ - size_t code = decoded->opt_index; - int value = decoded->value; - - switch (code) - { - case OPT_mspace: - opts->x_target_flags |= MASK_EP | MASK_PROLOG_FUNCTION; - return true; - - case OPT_mv850: - opts->x_target_flags &= ~(MASK_CPU ^ MASK_V850); - return true; - - case OPT_mv850e: - case OPT_mv850e1: - case OPT_mv850es: - opts->x_target_flags &= ~(MASK_CPU ^ MASK_V850E); - return true; - - case OPT_mv850e2: - opts->x_target_flags &= ~(MASK_CPU ^ MASK_V850E2); - return true; - - case OPT_mv850e2v3: - opts->x_target_flags &= ~(MASK_CPU ^ MASK_V850E2V3); - return true; - - case OPT_mtda_: - v850_handle_memory_option (SMALL_MEMORY_TDA, opts, - decoded->orig_option_with_args_text, - value, loc); - return true; - - case OPT_msda_: - v850_handle_memory_option (SMALL_MEMORY_SDA, opts, - decoded->orig_option_with_args_text, - value, loc); - return true; - - case OPT_mzda_: - v850_handle_memory_option (SMALL_MEMORY_ZDA, opts, - decoded->orig_option_with_args_text, - value, loc); - return true; - - default: - return true; - } -} - -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ - -static const struct default_options v850_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - /* Note - we no longer enable MASK_EP when optimizing. This is - because of a hardware bug which stops the SLD and SST instructions - from correctly detecting some hazards. If the user is sure that - their hardware is fixed or that their program will not encounter - the conditions that trigger the bug then they can enable -mep by - hand. */ - { OPT_LEVELS_1_PLUS, OPT_mprolog_function, NULL, 1 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - /* Handle the TARGET_PASS_BY_REFERENCE target hook. Specify whether to pass the argument by reference. */ static bool -v850_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +v850_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { @@ -189,7 +94,7 @@ v850_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, /* Implementing the Varargs Macros. */ static bool -v850_strict_argument_naming (CUMULATIVE_ARGS * ca ATTRIBUTE_UNUSED) +v850_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED) { return !TARGET_GHS ? true : false; } @@ -199,9 +104,10 @@ v850_strict_argument_naming (CUMULATIVE_ARGS * ca ATTRIBUTE_UNUSED) is NULL_RTX, the argument will be pushed. */ static rtx -v850_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, +v850_function_arg (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); rtx result = NULL_RTX; int size, align; @@ -260,9 +166,10 @@ v850_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, /* Return the number of bytes which must be put into registers for values which are part in registers and part in memory. */ static int -v850_arg_partial_bytes (CUMULATIVE_ARGS * cum, enum machine_mode mode, +v850_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode, tree type, bool named) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int size, align; if (TARGET_GHS && !named) @@ -301,9 +208,11 @@ v850_arg_partial_bytes (CUMULATIVE_ARGS * cum, enum machine_mode mode, (TYPE is null for libcalls where that information may not be available.) */ static void -v850_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +v850_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + cum->nbytes += (((type && int_size_in_bytes (type) > 8 ? GET_MODE_SIZE (Pmode) : (mode != BLKmode @@ -3059,13 +2968,13 @@ v850_function_value (const_tree valtype, /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */ static void -v850_setup_incoming_varargs (CUMULATIVE_ARGS *ca, +v850_setup_incoming_varargs (cumulative_args_t ca, enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, int *pretend_arg_size ATTRIBUTE_UNUSED, int second_time ATTRIBUTE_UNUSED) { - ca->anonymous_args = (!TARGET_GHS ? 1 : 0); + get_cumulative_args (ca)->anonymous_args = (!TARGET_GHS ? 1 : 0); } /* Worker function for TARGET_CAN_ELIMINATE. */ @@ -3141,7 +3050,9 @@ v850_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) } static int -v850_memory_move_cost (enum machine_mode mode, bool in) +v850_memory_move_cost (enum machine_mode mode, + reg_class_t reg_class ATTRIBUTE_UNUSED, + bool in) { switch (GET_MODE_SIZE (mode)) { @@ -3214,11 +3125,6 @@ static const struct attribute_spec v850_attribute_table[] = #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS (MASK_DEFAULT | MASK_APP_REGS) -#undef TARGET_HANDLE_OPTION -#define TARGET_HANDLE_OPTION v850_handle_option - #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS v850_rtx_costs @@ -3274,9 +3180,6 @@ static const struct attribute_spec v850_attribute_table[] = #undef TARGET_STRICT_ARGUMENT_NAMING #define TARGET_STRICT_ARGUMENT_NAMING v850_strict_argument_naming -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE v850_option_optimization_table - #undef TARGET_LEGITIMATE_CONSTANT_P #define TARGET_LEGITIMATE_CONSTANT_P v850_legitimate_constant_p diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index cc8c3f67e94..7c7070c9016 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -1,6 +1,6 @@ /* Subroutines for insn-output.c for VAX. Copyright (C) 1987, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, - 2004, 2005, 2006, 2007, 2008, 2009, 2010 + 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -56,9 +56,9 @@ static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, static int vax_address_cost_1 (rtx); static int vax_address_cost (rtx, bool); static bool vax_rtx_costs (rtx, int, int, int *, bool); -static rtx vax_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx vax_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static void vax_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void vax_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); static rtx vax_struct_value_rtx (tree, int); static rtx vax_builtin_setjmp_frame_value (void); @@ -86,9 +86,6 @@ static int vax_return_pops_args (tree, tree, int); #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT - #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS vax_rtx_costs #undef TARGET_ADDRESS_COST @@ -2109,7 +2106,7 @@ vax_return_pops_args (tree fundecl ATTRIBUTE_UNUSED, /* On the VAX all args are pushed. */ static rtx -vax_function_arg (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, +vax_function_arg (cumulative_args_t cum ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) @@ -2122,9 +2119,11 @@ vax_function_arg (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, may not be available.) */ static void -vax_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +vax_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); + *cum += (mode != BLKmode ? (GET_MODE_SIZE (mode) + 3) & ~3 : (int_size_in_bytes (type) + 3) & ~3); diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index fe5798ec9ae..ef246a0aeec 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -144,11 +144,11 @@ static tree xtensa_build_builtin_va_list (void); static bool xtensa_return_in_memory (const_tree, const_tree); static tree xtensa_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *); -static void xtensa_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, +static void xtensa_function_arg_advance (cumulative_args_t, enum machine_mode, const_tree, bool); -static rtx xtensa_function_arg (CUMULATIVE_ARGS *, enum machine_mode, +static rtx xtensa_function_arg (cumulative_args_t, enum machine_mode, const_tree, bool); -static rtx xtensa_function_incoming_arg (CUMULATIVE_ARGS *, +static rtx xtensa_function_incoming_arg (cumulative_args_t, enum machine_mode, const_tree, bool); static rtx xtensa_function_value (const_tree, const_tree, bool); static rtx xtensa_libcall_value (enum machine_mode, const_rtx); @@ -177,20 +177,6 @@ static bool xtensa_legitimate_constant_p (enum machine_mode, rtx); static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER; - -/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ - -static const struct default_options xtensa_option_optimization_table[] = - { - { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, - /* Reordering blocks for Xtensa is not a good idea unless the - compiler understands the range of conditional branches. - Currently all branch relaxation for Xtensa is handled in the - assembler, so GCC cannot do a good job of reordering blocks. - Do not enable reordering unless it is explicitly requested. */ - { OPT_LEVELS_ALL, OPT_freorder_blocks, NULL, 0 }, - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; /* This macro generates the assembly code for function exit, @@ -210,9 +196,6 @@ static const struct default_options xtensa_option_optimization_table[] = #undef TARGET_ASM_SELECT_RTX_SECTION #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT) - #undef TARGET_LEGITIMIZE_ADDRESS #define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address #undef TARGET_MODE_DEPENDENT_ADDRESS_P @@ -304,8 +287,6 @@ static const struct default_options xtensa_option_optimization_table[] = #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE xtensa_option_override -#undef TARGET_OPTION_OPTIMIZATION_TABLE -#define TARGET_OPTION_OPTIMIZATION_TABLE xtensa_option_optimization_table #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA xtensa_output_addr_const_extra @@ -2080,13 +2061,13 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, int incoming) /* Advance the argument to the next argument position. */ static void -xtensa_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, +xtensa_function_arg_advance (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { int words, max; int *arg_words; - arg_words = &cum->arg_words; + arg_words = &get_cumulative_args (cum)->arg_words; max = MAX_ARGS_IN_REGISTERS; words = (((mode != BLKmode) @@ -2107,9 +2088,10 @@ xtensa_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, if this is an incoming argument to the current function. */ static rtx -xtensa_function_arg_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode, +xtensa_function_arg_1 (cumulative_args_t cum_v, enum machine_mode mode, const_tree type, bool incoming_p) { + CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int regbase, words, max; int *arg_words; int regno; @@ -2142,7 +2124,7 @@ xtensa_function_arg_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode, /* Implement TARGET_FUNCTION_ARG. */ static rtx -xtensa_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +xtensa_function_arg (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { return xtensa_function_arg_1 (cum, mode, type, false); @@ -2151,7 +2133,7 @@ xtensa_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, /* Implement TARGET_FUNCTION_INCOMING_ARG. */ static rtx -xtensa_function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, +xtensa_function_incoming_arg (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named ATTRIBUTE_UNUSED) { return xtensa_function_arg_1 (cum, mode, type, true); diff --git a/gcc/configure b/gcc/configure index cc4843188d8..10c24cc94c9 100755 --- a/gcc/configure +++ b/gcc/configure @@ -624,6 +624,8 @@ tm_defines tm_include_list tm_file_list thread_file +common_out_object_file +common_out_file out_object_file out_file objc_boehm_gc @@ -10457,16 +10459,114 @@ $as_echo_n "checking for .preinit_array/.init_array/.fini_array support... " >&6 if test "${gcc_cv_initfini_array+set}" = set; then : $as_echo_n "(cached) " >&6 else + if test "x${build}" = "x${target}" && test "x${build}" = "x${host}"; then if test "$cross_compiling" = yes; then : gcc_cv_initfini_array=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#ifdef __ia64__ +/* We turn on .preinit_array/.init_array/.fini_array support for ia64 + if it can be used. */ static int x = -1; int main (void) { return x; } int foo (void) { x = 0; } int (*fp) (void) __attribute__ ((section (".init_array"))) = foo; +#else +extern void abort (); +static int count; + +static void +init1005 () +{ + if (count != 0) + abort (); + count = 1005; +} +void (*const init_array1005) () + __attribute__ ((section (".init_array.01005"), aligned (sizeof (void *)))) + = { init1005 }; +static void +fini1005 () +{ + if (count != 1005) + abort (); +} +void (*const fini_array1005) () + __attribute__ ((section (".fini_array.01005"), aligned (sizeof (void *)))) + = { fini1005 }; + +static void +ctor1007 () +{ + if (count != 1005) + abort (); + count = 1007; +} +void (*const ctors1007) () + __attribute__ ((section (".ctors.64528"), aligned (sizeof (void *)))) + = { ctor1007 }; +static void +dtor1007 () +{ + if (count != 1007) + abort (); + count = 1005; +} +void (*const dtors1007) () + __attribute__ ((section (".dtors.64528"), aligned (sizeof (void *)))) + = { dtor1007 }; + +static void +init65530 () +{ + if (count != 1007) + abort (); + count = 65530; +} +void (*const init_array65530) () + __attribute__ ((section (".init_array.65530"), aligned (sizeof (void *)))) + = { init65530 }; +static void +fini65530 () +{ + if (count != 65530) + abort (); + count = 1007; +} +void (*const fini_array65530) () + __attribute__ ((section (".fini_array.65530"), aligned (sizeof (void *)))) + = { fini65530 }; + +static void +ctor65535 () +{ + if (count != 65530) + abort (); + count = 65535; +} +void (*const ctors65535) () + __attribute__ ((section (".ctors"), aligned (sizeof (void *)))) + = { ctor65535 }; +static void +dtor65535 () +{ + if (count != 65535) + abort (); + count = 65530; +} +void (*const dtors65535) () + __attribute__ ((section (".dtors"), aligned (sizeof (void *)))) + = { dtor65535 }; + +int +main () +{ + return 0; +} +#endif + _ACEOF if ac_fn_c_try_run "$LINENO"; then : gcc_cv_initfini_array=yes @@ -10477,6 +10577,11 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking cross compile... guessing" >&5 +$as_echo_n "checking cross compile... guessing... " >&6; } + gcc_cv_initfini_array=no + fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_initfini_array" >&5 $as_echo "$gcc_cv_initfini_array" >&6; } @@ -11217,6 +11322,7 @@ done tmake_file="${tmake_file_}" out_object_file=`basename $out_file .c`.o +common_out_object_file=`basename $common_out_file .c`.o tm_file_list="options.h" tm_include_list="options.h insn-constants.h" @@ -17517,7 +17623,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 17520 "configure" +#line 17626 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -17623,7 +17729,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 17626 "configure" +#line 17732 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -26394,6 +26500,8 @@ fi + + # Echo link setup. if test x${build} = x${host} ; then if test x${host} = x${target} ; then @@ -27951,7 +28059,7 @@ case ${CONFIG_HEADERS} in echo > cstamp-h ;; esac # Make sure all the subdirs exist. -for d in $subdirs doc build c-family +for d in $subdirs doc build common c-family do test -d $d || mkdir $d done diff --git a/gcc/configure.ac b/gcc/configure.ac index 70b3dbc6223..5f3641b3198 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -1628,6 +1628,7 @@ done tmake_file="${tmake_file_}" out_object_file=`basename $out_file .c`.o +common_out_object_file=`basename $common_out_file .c`.o tm_file_list="options.h" tm_include_list="options.h insn-constants.h" @@ -4877,6 +4878,8 @@ AC_SUBST(md_file) AC_SUBST(objc_boehm_gc) AC_SUBST(out_file) AC_SUBST(out_object_file) +AC_SUBST(common_out_file) +AC_SUBST(common_out_object_file) AC_SUBST(thread_file) AC_SUBST(tm_file_list) AC_SUBST(tm_include_list) @@ -5081,7 +5084,7 @@ case ${CONFIG_HEADERS} in echo > cstamp-h ;; esac # Make sure all the subdirs exist. -for d in $subdirs doc build c-family +for d in $subdirs doc build common c-family do test -d $d || mkdir $d done diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9f429b51c58..eff4c8ee81e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,159 @@ +2011-06-20 Jason Merrill <jason@redhat.com> + + PR c++/47080 + * call.c (rejection_reason_code): Add rr_explicit_conversion. + (print_z_candidate): Handle it. + (explicit_conversion_rejection): New. + (build_user_type_conversion_1): Reject an explicit conversion + function that requires more than a qualification conversion. + + PR c++/47635 + * decl.c (grokdeclarator): Don't set ctype to an ENUMERAL_TYPE. + + PR c++/48138 + * tree.c (strip_typedefs): Use build_aligned_type. + + PR c++/49205 + * call.c (sufficient_parms_p): Allow parameter packs too. + + PR c++/43321 + * semantics.c (describable_type): Remove. + * cp-tree.h: Likewise. + * decl.c (cp_finish_decl): Don't call it. + * init.c (build_new): Likewise. + * parser.c (cp_parser_omp_for_loop): Likewise. + * pt.c (tsubst_decl): Likewise. + (do_auto_deduction): If we fail in a template, try again + at instantiation time. + + PR c++/43831 + * parser.c (cp_parser_lambda_introducer): Complain about redundant + captures. + * semantics.c (add_capture): Likewise. + (register_capture_members): Clear IDENTIFIER_MARKED. + +2011-06-17 Jason Merrill <jason@redhat.com> + + PR c++/49458 + * call.c (convert_class_to_reference_1): Allow binding function + lvalue to rvalue reference. + + PR c++/43912 + Generate proxy VAR_DECLs for better lambda debug info. + * cp-tree.h (FUNCTION_NEEDS_BODY_BLOCK): Add lambda operator(). + (LAMBDA_EXPR_PENDING_PROXIES): New. + (struct tree_lambda_expr): Add pending_proxies. + * name-lookup.c (pushdecl_maybe_friend_1): Handle capture shadowing. + (qualify_lookup): Use is_lambda_ignored_entity. + * parser.c (cp_parser_lambda_expression): Don't adjust field names. + Call insert_pending_capture_proxies. + (cp_parser_lambda_introducer): Use this_identifier. + (cp_parser_lambda_declarator_opt): Call the object parameter + of the op() "__closure" instead of "this". + (cp_parser_lambda_body): Call build_capture_proxy. + * semantics.c (build_capture_proxy, is_lambda_ignored_entity): New. + (insert_pending_capture_proxies, insert_capture_proxy): New. + (is_normal_capture_proxy, is_capture_proxy): New. + (add_capture): Add __ to field names here, return capture proxy. + (add_default_capture): Use this_identifier, adjust to expect + add_capture to return a capture proxy. + (outer_lambda_capture_p, thisify_lambda_field): Remove. + (finish_id_expression, lambda_expr_this_capture): Adjust. + (build_lambda_expr): Initialize LAMBDA_EXPR_PENDING_PROXIES. + * pt.c (tsubst_copy_and_build): Check that LAMBDA_EXPR_PENDING_PROXIES + is null. + + * name-lookup.c (pushdecl_maybe_friend_1): Do check for shadowing + of artificial locals. + + * parser.c (cp_parser_lambda_expression): Clear + LAMBDA_EXPR_THIS_CAPTURE after parsing. + * pt.c (tsubst_copy_and_build): Make sure it isn't set. + + * cp-tree.h (struct tree_lambda_expr): Change common to typed. + Move non-pointers to end of struct. + + * pt.c (tsubst_decl): Handle DECL_VALUE_EXPR on reference. + * decl.c (check_initializer): Handle DECL_VALUE_EXPR_P. + + * semantics.c (finish_non_static_data_member): Preserve dereference + in template. + +2011-06-16 Jason Merrill <jason@redhat.com> + + PR c++/44160 + * parser.c (cp_parser_lambda_body): Share code between + simple and complex cases instead of using cp_parser_function_body. + + PR c++/45378 + * decl.c (check_initializer): Check narrowing. + + PR c++/49229 + * pt.c (tsubst_decl) [FUNCTION_DECL]: Handle substitution failure. + + PR c++/49251 + * semantics.c (finish_id_expression): Mark even dependent + variables as used. + + PR c++/49420 + * error.c (dump_template_argument): Don't try to omit default + template args from an argument pack. + +2011-06-15 H.J. Lu <hongjiu.lu@intel.com> + + PR c++/49412 + * decl.c (get_dso_handle_node): Mark __dso_handle hidden if + assembler supports hidden visibility. + +2011-06-14 Jason Merrill <jason@redhat.com> + + PR c++/49107 + * cp-tree.h (DEFERRED_NOEXCEPT_SPEC_P): Handle overload. + * method.c (defaulted_late_check): Only maybe_instantiate_noexcept + if the declaration had an exception-specifier. + (process_subob_fn): Don't maybe_instantiate_noexcept. + * pt.c (maybe_instantiate_noexcept): Handle overload. + * typeck2.c (nothrow_spec_p_uninst): New. + (merge_exception_specifiers): Add 'fn' parm. Build up overload. + * typeck.c (merge_types): Adjust. + + * pt.c (deduction_tsubst_fntype): Don't save input_location. + (maybe_instantiate_noexcept): Likewise. + +2011-06-14 Joseph Myers <joseph@codesourcery.com> + + * Make-lang.in (cp/method.o): Update dependencies. + * method.c: Include common/common-target.h. + (use_thunk): Use targetm_common.have_named_sections. + +2011-06-14 Steve Ellcey <sje@cup.hp.com> + + * decl.c (cxx_init_decl_processing): Use ptr_mode instead of Pmode. + +2011-06-14 Jason Merrill <jason@redhat.com> + + * error.c (type_to_string): Print typedef-stripped version too. + + PR c++/49117 + * call.c (perform_implicit_conversion_flags): Print source type as + well as expression. + + PR c++/49389 + * typeck2.c (build_m_component_ref): Preserve rvalueness. + + PR c++/49369 + * class.c (build_base_path): Fix cv-quals in unevaluated context. + + PR c++/49290 + * semantics.c (cxx_fold_indirect_ref): Local, more permissive copy + of fold_indirect_ref_1. + (cxx_eval_indirect_ref): Use it. + +2011-06-11 Jan Hubicka <jh@suse.cz> + + * decl2.c (cp_write_global_declarations): Process aliases; look trhough + same body aliases. + 2011-06-10 Paolo Carlini <paolo.carlini@oracle.com> PR c++/41769 diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 45efd67d8cd..c47132280bf 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -292,7 +292,8 @@ cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \ $(EXCEPT_H) $(TARGET_H) cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h \ - $(TM_P_H) $(TARGET_H) $(DIAGNOSTIC_H) gt-cp-method.h $(GIMPLE_H) + $(TM_P_H) $(TARGET_H) $(DIAGNOSTIC_H) gt-cp-method.h $(GIMPLE_H) \ + $(COMMON_TARGET_H) cp/cvt.o: cp/cvt.c $(CXX_TREE_H) $(TM_H) cp/decl.h $(FLAGS_H) \ convert.h $(TARGET_H) intl.h cp/search.o: cp/search.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h \ diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 4ee0eafe81d..e9d6e7ea354 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -429,6 +429,7 @@ struct candidate_warning { enum rejection_reason_code { rr_none, rr_arity, + rr_explicit_conversion, rr_arg_conversion, rr_bad_arg_conversion }; @@ -534,15 +535,16 @@ null_ptr_cst_p (tree t) return false; } -/* Returns nonzero if PARMLIST consists of only default parms and/or - ellipsis. */ +/* Returns nonzero if PARMLIST consists of only default parms, + ellipsis, and/or undeduced parameter packs. */ bool sufficient_parms_p (const_tree parmlist) { for (; parmlist && parmlist != void_list_node; parmlist = TREE_CHAIN (parmlist)) - if (!TREE_PURPOSE (parmlist)) + if (!TREE_PURPOSE (parmlist) + && !PACK_EXPANSION_P (TREE_VALUE (parmlist))) return false; return true; } @@ -607,6 +609,16 @@ bad_arg_conversion_rejection (tree first_arg, int n_arg, tree from, tree to) return r; } +static struct rejection_reason * +explicit_conversion_rejection (tree from, tree to) +{ + struct rejection_reason *r = alloc_rejection (rr_explicit_conversion); + r->u.conversion.n_arg = 0; + r->u.conversion.from_type = from; + r->u.conversion.to_type = to; + return r; +} + /* Dynamically allocate a conversion. */ static conversion * @@ -1362,6 +1374,8 @@ convert_class_to_reference_1 (tree reference_type, tree s, tree expr, int flags) /* Don't allow binding of lvalues to rvalue references. */ if (TYPE_REF_IS_RVALUE (reference_type) + /* Function lvalues are OK, though. */ + && TREE_CODE (TREE_TYPE (reference_type)) != FUNCTION_TYPE && !TYPE_REF_IS_RVALUE (TREE_TYPE (TREE_TYPE (cand->fn)))) cand->second_conv->bad_p = true; } @@ -3150,6 +3164,12 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate) case rr_bad_arg_conversion: print_conversion_rejection (loc, &r->u.bad_conversion); break; + case rr_explicit_conversion: + inform (loc, " return type %qT of explicit conversion function " + "cannot be converted to %qT with a qualification " + "conversion", r->u.conversion.from_type, + r->u.conversion.to_type); + break; case rr_none: default: /* This candidate didn't have any issues or we failed to @@ -3426,9 +3446,10 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) for (cand = candidates; cand != old_candidates; cand = cand->next) { + tree rettype = TREE_TYPE (TREE_TYPE (cand->fn)); conversion *ics = implicit_conversion (totype, - TREE_TYPE (TREE_TYPE (cand->fn)), + rettype, 0, /*c_cast_p=*/false, convflags); @@ -3450,14 +3471,23 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) if (!ics) { - tree rettype = TREE_TYPE (TREE_TYPE (cand->fn)); cand->viable = 0; cand->reason = arg_conversion_rejection (NULL_TREE, -1, rettype, totype); } + else if (DECL_NONCONVERTING_P (cand->fn) + && ics->rank > cr_exact) + { + /* 13.3.1.5: For direct-initialization, those explicit + conversion functions that are not hidden within S and + yield type T or a type that can be converted to type T + with a qualification conversion (4.4) are also candidate + functions. */ + cand->viable = -1; + cand->reason = explicit_conversion_rejection (rettype, totype); + } else if (cand->viable == 1 && ics->bad_p) { - tree rettype = TREE_TYPE (TREE_TYPE (cand->fn)); cand->viable = -1; cand->reason = bad_arg_conversion_rejection (NULL_TREE, -1, @@ -5510,7 +5540,18 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, for (; t; t = convs->u.next) { - if (t->kind == ck_user || !t->bad_p) + if (t->kind == ck_user && t->cand->reason) + { + permerror (input_location, "invalid user-defined conversion " + "from %qT to %qT", TREE_TYPE (expr), totype); + print_z_candidate ("candidate is:", t->cand); + expr = convert_like_real (t, expr, fn, argnum, 1, + /*issue_conversion_warnings=*/false, + /*c_cast_p=*/false, + complain); + return cp_convert (totype, expr); + } + else if (t->kind == ck_user || !t->bad_p) { expr = convert_like_real (t, expr, fn, argnum, 1, /*issue_conversion_warnings=*/false, @@ -8296,7 +8337,8 @@ perform_implicit_conversion_flags (tree type, tree expr, tsubst_flags_t complain else if (invalid_nonstatic_memfn_p (expr, complain)) /* We gave an error. */; else - error ("could not convert %qE to %qT", expr, type); + error ("could not convert %qE from %qT to %qT", expr, + TREE_TYPE (expr), type); } expr = error_mark_node; } diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 69627cb6cb5..09444fb49ec 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -289,6 +289,12 @@ build_base_path (enum tree_code code, offset = BINFO_OFFSET (binfo); fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo); + /* TARGET_TYPE has been extracted from BINFO, and, is therefore always + cv-unqualified. Extract the cv-qualifiers from EXPR so that the + expression returned matches the input. */ + target_type = cp_build_qualified_type + (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr)))); + ptr_target_type = build_pointer_type (target_type); /* Do we need to look in the vtable for the real offset? */ virtual_access = (v_binfo && fixed_type_p <= 0); @@ -297,7 +303,7 @@ build_base_path (enum tree_code code, source type is incomplete and the pointer value doesn't matter. */ if (cp_unevaluated_operand != 0) { - expr = build_nop (build_pointer_type (target_type), expr); + expr = build_nop (ptr_target_type, expr); if (!want_pointer) expr = build_indirect_ref (EXPR_LOCATION (expr), expr, RO_NULL); return expr; @@ -312,18 +318,7 @@ build_base_path (enum tree_code code, field, because other parts of the compiler know that such expressions are always non-NULL. */ if (!virtual_access && integer_zerop (offset)) - { - tree class_type; - /* TARGET_TYPE has been extracted from BINFO, and, is - therefore always cv-unqualified. Extract the - cv-qualifiers from EXPR so that the expression returned - matches the input. */ - class_type = TREE_TYPE (TREE_TYPE (expr)); - target_type - = cp_build_qualified_type (target_type, - cp_type_quals (class_type)); - return build_nop (build_pointer_type (target_type), expr); - } + return build_nop (ptr_target_type, expr); null_test = error_mark_node; } @@ -407,9 +402,6 @@ build_base_path (enum tree_code code, offset = v_offset; } - target_type = cp_build_qualified_type - (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr)))); - ptr_target_type = build_pointer_type (target_type); if (want_pointer) target_type = ptr_target_type; diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index ce1141735a7..12c01cb15f5 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -442,6 +442,8 @@ DEFTREECODE (TRAIT_EXPR, "trait_expr", tcc_exceptional, 0) none. LAMBDA_EXPR_CAPTURE_LIST holds the capture-list, including `this'. LAMBDA_EXPR_THIS_CAPTURE goes straight to the capture of `this', if it exists. + LAMBDA_EXPR_PENDING_PROXIES is a vector of capture proxies which need to + be pushed once scope returns to the lambda. LAMBDA_EXPR_MUTABLE_P signals whether this lambda was declared mutable. LAMBDA_EXPR_RETURN_TYPE holds the return type, if it was specified. */ DEFTREECODE (LAMBDA_EXPR, "lambda_expr", tcc_exceptional, 0) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 06b5926faa8..904e44c77b1 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -268,7 +268,8 @@ typedef struct ptrmem_cst * ptrmem_cst_t; #define BIND_EXPR_BODY_BLOCK(NODE) \ TREE_LANG_FLAG_3 (BIND_EXPR_CHECK (NODE)) #define FUNCTION_NEEDS_BODY_BLOCK(NODE) \ - (DECL_CONSTRUCTOR_P (NODE) || DECL_DESTRUCTOR_P (NODE)) + (DECL_CONSTRUCTOR_P (NODE) || DECL_DESTRUCTOR_P (NODE) \ + || LAMBDA_FUNCTION_P (NODE)) #define STATEMENT_LIST_NO_SCOPE(NODE) \ TREE_LANG_FLAG_0 (STATEMENT_LIST_CHECK (NODE)) @@ -514,7 +515,8 @@ struct GTY (()) tree_default_arg { (((struct tree_deferred_noexcept *)DEFERRED_NOEXCEPT_CHECK (NODE))->args) #define DEFERRED_NOEXCEPT_SPEC_P(NODE) \ ((NODE) && (TREE_PURPOSE (NODE)) \ - && TREE_CODE (TREE_PURPOSE (NODE)) == DEFERRED_NOEXCEPT) + && (TREE_CODE (TREE_PURPOSE (NODE)) == DEFERRED_NOEXCEPT \ + || is_overloaded_fn (TREE_PURPOSE (NODE)))) struct GTY (()) tree_deferred_noexcept { struct tree_base base; @@ -624,7 +626,8 @@ enum cp_lambda_default_capture_mode_type { #define LAMBDA_EXPR_CAPTURE_LIST(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->capture_list) -/* The node in the capture-list that holds the 'this' capture. */ +/* During parsing of the lambda, the node in the capture-list that holds + the 'this' capture. */ #define LAMBDA_EXPR_THIS_CAPTURE(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->this_capture) @@ -659,15 +662,21 @@ enum cp_lambda_default_capture_mode_type { #define LAMBDA_EXPR_DISCRIMINATOR(NODE) \ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->discriminator) +/* During parsing of the lambda, a vector of capture proxies which need + to be pushed once we're done processing a nested lambda. */ +#define LAMBDA_EXPR_PENDING_PROXIES(NODE) \ + (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->pending_proxies) + struct GTY (()) tree_lambda_expr { - struct tree_common common; - location_t locus; - enum cp_lambda_default_capture_mode_type default_capture_mode; + struct tree_typed typed; tree capture_list; tree this_capture; tree return_type; tree extra_scope; + VEC(tree,gc)* pending_proxies; + location_t locus; + enum cp_lambda_default_capture_mode_type default_capture_mode; int discriminator; }; @@ -1792,7 +1801,10 @@ struct GTY((variable_size)) lang_type { this type can raise. Each TREE_VALUE is a _TYPE. The TREE_VALUE will be NULL_TREE to indicate a throw specification of `()', or no exceptions allowed. For a noexcept specification, TREE_VALUE - is NULL_TREE and TREE_PURPOSE is the constant-expression. */ + is NULL_TREE and TREE_PURPOSE is the constant-expression. For + a deferred noexcept-specification, TREE_PURPOSE is a DEFERRED_NOEXCEPT + (for templates) or an OVERLOAD list of functions (for implicitly + declared functions). */ #define TYPE_RAISES_EXCEPTIONS(NODE) TYPE_LANG_SLOT_1 (NODE) /* For FUNCTION_TYPE or METHOD_TYPE, return 1 iff it is declared `throw()' @@ -5433,7 +5445,6 @@ extern bool cxx_omp_create_clause_info (tree, tree, bool, bool, bool); extern tree baselink_for_fns (tree); extern void finish_static_assert (tree, tree, location_t, bool); -extern tree describable_type (tree); extern tree finish_decltype_type (tree, bool, tsubst_flags_t); extern tree finish_trait_expr (enum cp_trait_kind, tree, tree); extern tree build_lambda_expr (void); @@ -5445,10 +5456,15 @@ extern tree lambda_function (tree); extern void apply_lambda_return_type (tree, tree); extern tree add_capture (tree, tree, tree, bool, bool); extern tree add_default_capture (tree, tree, tree); +extern tree build_capture_proxy (tree); +extern void insert_pending_capture_proxies (void); +extern bool is_capture_proxy (tree); +extern bool is_normal_capture_proxy (tree); extern void register_capture_members (tree); extern tree lambda_expr_this_capture (tree); extern tree nonlambda_method_basetype (void); extern void maybe_add_lambda_conv_op (tree); +extern bool is_lambda_ignored_entity (tree); /* in tree.c */ extern int cp_tree_operand_length (const_tree); @@ -5698,7 +5714,7 @@ extern tree build_x_arrow (tree); extern tree build_m_component_ref (tree, tree); extern tree build_functional_cast (tree, tree, tsubst_flags_t); extern tree add_exception_specifier (tree, tree, int); -extern tree merge_exception_specifiers (tree, tree); +extern tree merge_exception_specifiers (tree, tree, tree); /* in mangle.c */ extern void init_mangle (void); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f4988f910de..263ab3fdafe 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3672,7 +3672,7 @@ cxx_init_decl_processing (void) TYPE_SIZE_UNIT (nullptr_type_node) = size_int (GET_MODE_SIZE (ptr_mode)); TYPE_UNSIGNED (nullptr_type_node) = 1; TYPE_PRECISION (nullptr_type_node) = GET_MODE_BITSIZE (ptr_mode); - SET_TYPE_MODE (nullptr_type_node, Pmode); + SET_TYPE_MODE (nullptr_type_node, ptr_mode); record_builtin_type (RID_MAX, "decltype(nullptr)", nullptr_type_node); nullptr_node = build_int_cst (nullptr_type_node, 0); } @@ -5387,6 +5387,14 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) type. */ TREE_TYPE (decl) = type = complete_type (TREE_TYPE (decl)); + if (DECL_HAS_VALUE_EXPR_P (decl)) + { + /* A variable with DECL_HAS_VALUE_EXPR_P set is just a placeholder, + it doesn't have storage to be initialized. */ + gcc_assert (init == NULL_TREE); + return NULL_TREE; + } + if (type == error_mark_node) /* We will have already complained. */ return NULL_TREE; @@ -5464,7 +5472,11 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) init = error_mark_node; } else - init = reshape_init (type, init, tf_warning_or_error); + { + init = reshape_init (type, init, tf_warning_or_error); + if (cxx_dialect >= cxx0x && SCALAR_TYPE_P (type)) + check_narrowing (type, init); + } } /* If DECL has an array type without a specific bound, deduce the @@ -5932,13 +5944,10 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, d_init = build_x_compound_expr_from_list (d_init, ELK_INIT, tf_warning_or_error); d_init = resolve_nondeduced_context (d_init); - if (describable_type (d_init)) - { - type = TREE_TYPE (decl) = do_auto_deduction (type, d_init, - auto_node); - if (type == error_mark_node) - return; - } + type = TREE_TYPE (decl) = do_auto_deduction (type, d_init, + auto_node); + if (type == error_mark_node) + return; } if (!ensure_literal_type_for_constexpr_object (decl)) @@ -6435,6 +6444,11 @@ get_dso_handle_node (void) dso_handle_node = declare_global_var (get_identifier ("__dso_handle"), ptr_type_node); +#ifdef HAVE_GAS_HIDDEN + DECL_VISIBILITY (dso_handle_node) = VISIBILITY_HIDDEN; + DECL_VISIBILITY_SPECIFIED (dso_handle_node) = 1; +#endif + return dso_handle_node; } @@ -8324,10 +8338,15 @@ grokdeclarator (const cp_declarator *declarator, else if (TYPE_P (qualifying_scope)) { ctype = qualifying_scope; - if (innermost_code != cdk_function - && current_class_type - && !UNIQUELY_DERIVED_FROM_P (ctype, - current_class_type)) + if (!MAYBE_CLASS_TYPE_P (ctype)) + { + error ("%q#T is not a class or a namespace", ctype); + ctype = NULL_TREE; + } + else if (innermost_code != cdk_function + && current_class_type + && !UNIQUELY_DERIVED_FROM_P (ctype, + current_class_type)) { error ("type %qT is not derived from type %qT", ctype, current_class_type); @@ -9336,7 +9355,7 @@ grokdeclarator (const cp_declarator *declarator, would not have exited the loop above. */ if (declarator && declarator->u.id.qualifying_scope - && TYPE_P (declarator->u.id.qualifying_scope)) + && MAYBE_CLASS_TYPE_P (declarator->u.id.qualifying_scope)) { tree t; @@ -10142,13 +10161,6 @@ grokdeclarator (const cp_declarator *declarator, "declared out of global scope", name); } - if (ctype != NULL_TREE - && TREE_CODE (ctype) != NAMESPACE_DECL && !MAYBE_CLASS_TYPE_P (ctype)) - { - error ("%q#T is not a class or a namespace", ctype); - ctype = NULL_TREE; - } - if (ctype == NULL_TREE) { if (virtualp) @@ -13043,7 +13055,8 @@ finish_destructor_body (void) /* Do the necessary processing for the beginning of a function body, which in this case includes member-initializers, but not the catch clauses of a function-try-block. Currently, this means opening a binding level - for the member-initializers (in a ctor) and member cleanups (in a dtor). */ + for the member-initializers (in a ctor), member cleanups (in a dtor), + and capture proxies (in a lambda operator()). */ tree begin_function_body (void) diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 82d0b11e040..d2f075dab0a 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3672,6 +3672,8 @@ cp_write_global_declarations (void) if (pch_file) c_common_write_pch (); + cgraph_process_same_body_aliases (); + /* Handle -fdump-ada-spec[-slim] */ if (dump_enabled_p (TDI_ada)) { @@ -3869,6 +3871,8 @@ cp_write_global_declarations (void) struct cgraph_node *node, *next; node = cgraph_get_node (decl); + if (node->same_body_alias) + node = cgraph_alias_aliased_node (node); cgraph_for_node_and_aliases (node, clear_decl_external, NULL, true); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 96796c206d9..7c90ec45c17 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -147,7 +147,9 @@ static void dump_template_argument (tree arg, int flags) { if (ARGUMENT_PACK_P (arg)) - dump_template_argument_list (ARGUMENT_PACK_ARGS (arg), flags); + dump_template_argument_list (ARGUMENT_PACK_ARGS (arg), + /* No default args in argument packs. */ + flags|TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS); else if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL) dump_type (arg, flags & ~TFF_CLASS_KEY_OR_ENUM); else @@ -2632,6 +2634,15 @@ type_to_string (tree typ, int verbose) reinit_cxx_pp (); dump_type (typ, flags); + if (typ && TYPE_P (typ) && typ != TYPE_CANONICAL (typ) + && !uses_template_parms (typ)) + { + tree aka = strip_typedefs (typ); + pp_string (cxx_pp, " {aka"); + pp_cxx_whitespace (cxx_pp); + dump_type (aka, flags); + pp_character (cxx_pp, '}'); + } return pp_formatted_text (cxx_pp); } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 3b926657c5e..140e064b659 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2600,8 +2600,7 @@ build_new (VEC(tree,gc) **placement, tree type, tree nelts, { tree d_init = VEC_index (tree, *init, 0); d_init = resolve_nondeduced_context (d_init); - if (describable_type (d_init)) - type = do_auto_deduction (type, d_init, auto_node); + type = do_auto_deduction (type, d_init, auto_node); } } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 918870056db..48b9c74e78e 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "toplev.h" #include "tm_p.h" #include "target.h" +#include "common/common-target.h" #include "tree-pass.h" #include "diagnostic.h" #include "cgraph.h" @@ -353,7 +354,7 @@ use_thunk (tree thunk_fndecl, bool emit_p) push_to_top_level (); if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function) - && targetm.have_named_sections) + && targetm_common.have_named_sections) { resolve_unique_section (function, 0, flag_function_sections); @@ -923,10 +924,8 @@ process_subob_fn (tree fn, bool move_p, tree *spec_p, bool *trivial_p, if (spec_p) { - tree raises; - maybe_instantiate_noexcept (fn); - raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)); - *spec_p = merge_exception_specifiers (*spec_p, raises); + tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)); + *spec_p = merge_exception_specifiers (*spec_p, raises, fn); } if (!trivial_fn_p (fn)) @@ -1560,15 +1559,16 @@ defaulted_late_check (tree fn) it had been implicitly declared. */ if (DECL_DEFAULTED_IN_CLASS_P (fn)) { - tree eh_spec; - maybe_instantiate_noexcept (fn); - eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn)); - if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)) - && !comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)), - eh_spec, ce_normal)) - error ("function %q+D defaulted on its first declaration " - "with an exception-specification that differs from " - "the implicit declaration %q#D", fn, implicit_fn); + tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn)); + if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))) + { + maybe_instantiate_noexcept (fn); + if (!comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)), + eh_spec, ce_normal)) + error ("function %q+D defaulted on its first declaration " + "with an exception-specification that differs from " + "the implicit declaration %q#D", fn, implicit_fn); + } TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec); if (DECL_DECLARED_CONSTEXPR_P (implicit_fn)) /* Hmm...should we do this for out-of-class too? Should it be OK to diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 7f0f6153998..953edd57f22 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -1022,11 +1022,6 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend) || (TREE_CODE (oldlocal) == TYPE_DECL && (!DECL_ARTIFICIAL (oldlocal) || TREE_CODE (x) == TYPE_DECL))) - /* Don't check the `this' parameter or internally generated - vars unless it's an implicit typedef (see - create_implicit_typedef in decl.c). */ - && (!DECL_ARTIFICIAL (oldlocal) - || DECL_IMPLICIT_TYPEDEF_P (oldlocal)) /* Don't check for internally generated vars unless it's an implicit typedef (see create_implicit_typedef in decl.c). */ @@ -1094,6 +1089,10 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend) if (TREE_CODE (oldlocal) == PARM_DECL) warning_at (input_location, OPT_Wshadow, "declaration of %q#D shadows a parameter", x); + else if (is_capture_proxy (oldlocal)) + warning_at (input_location, OPT_Wshadow, + "declaration of %qD shadows a lambda capture", + x); else warning_at (input_location, OPT_Wshadow, "declaration of %qD shadows a previous local", @@ -2066,7 +2065,12 @@ push_using_decl (tree scope, tree name) } /* Same as pushdecl, but define X in binding-level LEVEL. We rely on the - caller to set DECL_CONTEXT properly. */ + caller to set DECL_CONTEXT properly. + + Note that this must only be used when X will be the new innermost + binding for its name, as we tack it onto the front of IDENTIFIER_BINDING + without checking to see if the current IDENTIFIER_BINDING comes from a + closer binding level than LEVEL. */ static tree pushdecl_with_scope_1 (tree x, cxx_scope *level, bool is_friend) @@ -4002,13 +4006,8 @@ qualify_lookup (tree val, int flags) return true; if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES)) return false; - /* In unevaluated context, look past normal capture fields. */ - if (cp_unevaluated_operand && TREE_CODE (val) == FIELD_DECL - && DECL_NORMAL_CAPTURE_P (val)) - return false; - /* None of the lookups that use qualify_lookup want the op() from the - lambda; they want the one from the enclosing class. */ - if (TREE_CODE (val) == FUNCTION_DECL && LAMBDA_FUNCTION_P (val)) + /* Look through lambda things that we shouldn't be able to see. */ + if (is_lambda_ignored_entity (val)) return false; return true; } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 961f9feb800..856a8a7b67c 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7396,26 +7396,9 @@ cp_parser_lambda_expression (cp_parser* parser) for (elt = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr); elt; elt = next) { - tree field = TREE_PURPOSE (elt); - char *buf; - next = TREE_CHAIN (elt); TREE_CHAIN (elt) = newlist; newlist = elt; - - /* Also add __ to the beginning of the field name so that code - outside the lambda body can't see the captured name. We could - just remove the name entirely, but this is more useful for - debugging. */ - if (field == LAMBDA_EXPR_THIS_CAPTURE (lambda_expr)) - /* The 'this' capture already starts with __. */ - continue; - - buf = (char *) alloca (IDENTIFIER_LENGTH (DECL_NAME (field)) + 3); - buf[1] = buf[0] = '_'; - memcpy (buf + 2, IDENTIFIER_POINTER (DECL_NAME (field)), - IDENTIFIER_LENGTH (DECL_NAME (field)) + 1); - DECL_NAME (field) = get_identifier (buf); } LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) = newlist; } @@ -7430,6 +7413,14 @@ cp_parser_lambda_expression (cp_parser* parser) pop_deferring_access_checks (); + /* This field is only used during parsing of the lambda. */ + LAMBDA_EXPR_THIS_CAPTURE (lambda_expr) = NULL_TREE; + + /* This lambda shouldn't have any proxies left at this point. */ + gcc_assert (LAMBDA_EXPR_PENDING_PROXIES (lambda_expr) == NULL); + /* And now that we're done, push proxies for an enclosing lambda. */ + insert_pending_capture_proxies (); + if (ok) return build_lambda_object (lambda_expr); else @@ -7494,9 +7485,13 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) /* Possibly capture `this'. */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_THIS)) { + location_t loc = cp_lexer_peek_token (parser->lexer)->location; + if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_COPY) + pedwarn (loc, 0, "explicit by-copy capture of %<this%> redundant " + "with by-copy capture default"); cp_lexer_consume_token (parser->lexer); add_capture (lambda_expr, - /*id=*/get_identifier ("__this"), + /*id=*/this_identifier, /*initializer=*/finish_this_expr(), /*by_reference_p=*/false, explicit_init_p); @@ -7577,6 +7572,21 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) capture_init_expr = unqualified_name_lookup_error (capture_init_expr); + if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE + && !explicit_init_p) + { + if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_COPY + && capture_kind == BY_COPY) + pedwarn (capture_token->location, 0, "explicit by-copy capture " + "of %qD redundant with by-copy capture default", + capture_id); + if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_REFERENCE + && capture_kind == BY_REFERENCE) + pedwarn (capture_token->location, 0, "explicit by-reference " + "capture of %qD redundant with by-reference capture " + "default", capture_id); + } + add_capture (lambda_expr, capture_id, capture_init_expr, @@ -7698,6 +7708,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) { DECL_INITIALIZED_IN_CLASS_P (fco) = 1; DECL_ARTIFICIAL (fco) = 1; + /* Give the object parameter a different name. */ + DECL_NAME (DECL_ARGUMENTS (fco)) = get_identifier ("__closure"); } finish_member_declaration (fco); @@ -7731,6 +7743,8 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) tree fco = lambda_function (lambda_expr); tree body; bool done = false; + tree compound_stmt; + tree cap; /* Let the front end know that we are going to be defining this function. */ @@ -7741,6 +7755,16 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) start_lambda_scope (fco); body = begin_function_body (); + if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE)) + goto out; + + /* Push the proxies for any explicit captures. */ + for (cap = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr); cap; + cap = TREE_CHAIN (cap)) + build_capture_proxy (TREE_PURPOSE (cap)); + + compound_stmt = begin_compound_stmt (0); + /* 5.1.1.4 of the standard says: If a lambda-expression does not include a trailing-return-type, it is as if the trailing-return-type denotes the following type: @@ -7757,11 +7781,9 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) in the body. Since we used void as the placeholder return type, parsing the body as usual will give such desired behavior. */ if (!LAMBDA_EXPR_RETURN_TYPE (lambda_expr) - && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE) - && cp_lexer_peek_nth_token (parser->lexer, 2)->keyword == RID_RETURN - && cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_SEMICOLON) + && cp_lexer_peek_nth_token (parser->lexer, 1)->keyword == RID_RETURN + && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SEMICOLON) { - tree compound_stmt; tree expr = NULL_TREE; cp_id_kind idk = CP_ID_KIND_NONE; @@ -7769,7 +7791,6 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) statement. */ cp_parser_parse_tentatively (parser); - cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE); cp_parser_require_keyword (parser, RID_RETURN, RT_RETURN); expr = cp_parser_expression (parser, /*cast_p=*/false, &idk); @@ -7781,10 +7802,8 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) { apply_lambda_return_type (lambda_expr, lambda_return_type (expr)); - compound_stmt = begin_compound_stmt (0); /* Will get error here if type not deduced yet. */ finish_return_stmt (expr); - finish_compound_stmt (compound_stmt); done = true; } @@ -7794,12 +7813,16 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) { if (!LAMBDA_EXPR_RETURN_TYPE (lambda_expr)) LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda_expr) = true; - /* TODO: does begin_compound_stmt want BCS_FN_BODY? - cp_parser_compound_stmt does not pass it. */ - cp_parser_function_body (parser); + while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL)) + cp_parser_label_declaration (parser); + cp_parser_statement_seq_opt (parser, NULL_TREE); + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda_expr) = false; } + finish_compound_stmt (compound_stmt); + + out: finish_function_body (body); finish_lambda_scope (); @@ -24481,7 +24504,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) &is_direct_init, &is_non_constant_init); - if (auto_node && describable_type (init)) + if (auto_node) { TREE_TYPE (decl) = do_auto_deduction (TREE_TYPE (decl), init, diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 814a08f6a4e..6f15101d6e9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9548,6 +9548,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (t))), args, complain, in_decl); + if (argvec == error_mark_node) + RETURN (error_mark_node); /* Check to see if we already have this specialization. */ hash = hash_tmpl_and_args (gen_tmpl, argvec); @@ -10059,6 +10061,11 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) tree ve = DECL_VALUE_EXPR (t); ve = tsubst_expr (ve, args, complain, in_decl, /*constant_expression_p=*/false); + if (REFERENCE_REF_P (ve)) + { + gcc_assert (TREE_CODE (type) == REFERENCE_TYPE); + ve = TREE_OPERAND (ve, 0); + } SET_DECL_VALUE_EXPR (r, ve); } } @@ -10115,11 +10122,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) if (auto_node && init) { init = resolve_nondeduced_context (init); - if (describable_type (init)) - { - type = do_auto_deduction (type, init, auto_node); - TREE_TYPE (r) = type; - } + TREE_TYPE (r) = type + = do_auto_deduction (type, init, auto_node); } } else @@ -13491,10 +13495,10 @@ tsubst_copy_and_build (tree t, = (LAMBDA_EXPR_DISCRIMINATOR (t)); LAMBDA_EXPR_CAPTURE_LIST (r) = RECUR (LAMBDA_EXPR_CAPTURE_LIST (t)); - LAMBDA_EXPR_THIS_CAPTURE (r) - = RECUR (LAMBDA_EXPR_THIS_CAPTURE (t)); LAMBDA_EXPR_EXTRA_SCOPE (r) = RECUR (LAMBDA_EXPR_EXTRA_SCOPE (t)); + gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (t) == NULL_TREE + && LAMBDA_EXPR_PENDING_PROXIES (t) == NULL); /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set. */ determine_visibility (TYPE_NAME (type)); @@ -13635,7 +13639,6 @@ deduction_tsubst_fntype (tree fn, tree targs) { static bool excessive_deduction_depth; static int deduction_depth; - location_t save_loc = input_location; struct pending_template *old_last_pend = last_pending_template; tree fntype = TREE_TYPE (fn); @@ -13659,7 +13662,6 @@ deduction_tsubst_fntype (tree fn, tree targs) r = tsubst (fntype, targs, tf_none, NULL_TREE); pop_deduction_access_scope (fn); --deduction_depth; - input_location = save_loc; if (excessive_deduction_depth) { @@ -17356,29 +17358,49 @@ always_instantiate_p (tree decl) void maybe_instantiate_noexcept (tree fn) { - tree fntype = TREE_TYPE (fn); - tree spec = TYPE_RAISES_EXCEPTIONS (fntype); - tree noex = NULL_TREE; - location_t saved_loc = input_location; - tree clone; + tree fntype, spec, noex, clone; + + if (DECL_CLONED_FUNCTION_P (fn)) + fn = DECL_CLONED_FUNCTION (fn); + fntype = TREE_TYPE (fn); + spec = TYPE_RAISES_EXCEPTIONS (fntype); if (!DEFERRED_NOEXCEPT_SPEC_P (spec)) return; + noex = TREE_PURPOSE (spec); - push_tinst_level (fn); - push_access_scope (fn); - input_location = DECL_SOURCE_LOCATION (fn); - noex = tsubst_copy_and_build (DEFERRED_NOEXCEPT_PATTERN (noex), - DEFERRED_NOEXCEPT_ARGS (noex), - tf_warning_or_error, fn, /*function_p=*/false, - /*integral_constant_expression_p=*/true); - input_location = saved_loc; - pop_access_scope (fn); - pop_tinst_level (); - spec = build_noexcept_spec (noex, tf_warning_or_error); - if (spec == error_mark_node) - spec = noexcept_false_spec; + if (TREE_CODE (noex) == DEFERRED_NOEXCEPT) + { + push_tinst_level (fn); + push_access_scope (fn); + input_location = DECL_SOURCE_LOCATION (fn); + noex = tsubst_copy_and_build (DEFERRED_NOEXCEPT_PATTERN (noex), + DEFERRED_NOEXCEPT_ARGS (noex), + tf_warning_or_error, fn, /*function_p=*/false, + /*integral_constant_expression_p=*/true); + pop_access_scope (fn); + pop_tinst_level (); + spec = build_noexcept_spec (noex, tf_warning_or_error); + if (spec == error_mark_node) + spec = noexcept_false_spec; + } + else + { + /* This is an implicitly declared function, so NOEX is a list of + other functions to evaluate and merge. */ + tree elt; + spec = noexcept_true_spec; + for (elt = noex; elt; elt = OVL_NEXT (elt)) + { + tree fn = OVL_CURRENT (elt); + tree subspec; + maybe_instantiate_noexcept (fn); + subspec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)); + spec = merge_exception_specifiers (spec, subspec, NULL_TREE); + } + } + TREE_TYPE (fn) = build_exception_variant (fntype, spec); FOR_EACH_CLONE (clone, fn) @@ -19277,6 +19299,12 @@ do_auto_deduction (tree type, tree init, tree auto_node) tree decl; int val; + if (processing_template_decl + && (TREE_TYPE (init) == NULL_TREE + || BRACE_ENCLOSED_INITIALIZER_P (init))) + /* Not enough information to try this yet. */ + return type; + /* The name of the object being declared shall not appear in the initializer expression. */ decl = cp_walk_tree_without_duplicates (&init, contains_auto_r, type); @@ -19306,6 +19334,9 @@ do_auto_deduction (tree type, tree init, tree auto_node) DEDUCE_CALL, LOOKUP_NORMAL); if (val > 0) { + if (processing_template_decl) + /* Try again at instantiation time. */ + return type; if (type && type != error_mark_node) /* If type is error_mark_node a diagnostic must have been emitted by now. Also, having a mention to '<type error>' diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 481318e963d..cfe3959462e 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -54,7 +54,6 @@ along with GCC; see the file COPYING3. If not see static tree maybe_convert_cond (tree); static tree finalize_nrv_r (tree *, int *, void *); static tree capture_decltype (tree); -static tree thisify_lambda_field (tree); /* Deferred Access Checking Overview @@ -1557,7 +1556,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) tree type = TREE_TYPE (decl); if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); + /* Quals on the object don't matter. */; else { /* Set the cv qualifiers. */ @@ -1572,7 +1571,8 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) type = cp_build_qualified_type (type, quals); } - return build_min (COMPONENT_REF, type, object, decl, NULL_TREE); + return (convert_from_reference + (build_min (COMPONENT_REF, type, object, decl, NULL_TREE))); } /* If PROCESSING_TEMPLATE_DECL is nonzero here, then QUALIFYING_SCOPE is also non-null. Wrap this in a SCOPE_REF @@ -2829,18 +2829,6 @@ outer_automatic_var_p (tree decl) && DECL_CONTEXT (decl) != current_function_decl); } -/* Returns true iff DECL is a capture field from a lambda that is not our - immediate context. */ - -static bool -outer_lambda_capture_p (tree decl) -{ - return (TREE_CODE (decl) == FIELD_DECL - && LAMBDA_TYPE_P (DECL_CONTEXT (decl)) - && (!current_class_type - || !DERIVED_FROM_P (DECL_CONTEXT (decl), current_class_type))); -} - /* ID_EXPRESSION is a representation of parsed, but unprocessed, id-expression. (See cp_parser_id_expression for details.) SCOPE, if non-NULL, is the type or namespace used to explicitly qualify @@ -2945,8 +2933,7 @@ finish_id_expression (tree id_expression, /* Disallow uses of local variables from containing functions, except within lambda-expressions. */ - if ((outer_automatic_var_p (decl) - || outer_lambda_capture_p (decl)) + if (outer_automatic_var_p (decl) /* It's not a use (3.2) if we're in an unevaluated context. */ && !cp_unevaluated_operand) { @@ -2966,13 +2953,6 @@ finish_id_expression (tree id_expression, if (decl_constant_var_p (decl)) return integral_constant_value (decl); - if (TYPE_P (context)) - { - /* Implicit capture of an explicit capture. */ - context = lambda_function (context); - initializer = thisify_lambda_field (decl); - } - /* If we are in a lambda function, we can move out until we hit 1. the context, 2. a non-lambda function, or @@ -3196,7 +3176,10 @@ finish_id_expression (tree id_expression, (or an instantiation thereof). */ if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) - return convert_from_reference (decl); + { + mark_used (decl); + return convert_from_reference (decl); + } /* The same is true for FIELD_DECL, but we also need to make sure that the syntax is correct. */ else if (TREE_CODE (decl) == FIELD_DECL) @@ -4820,65 +4803,6 @@ finish_static_assert (tree condition, tree message, location_t location, } } -/* Returns the type of EXPR for cases where we can determine it even though - EXPR is a type-dependent expression. */ - -tree -describable_type (tree expr) -{ - tree type = NULL_TREE; - - if (! type_dependent_expression_p (expr) - && ! type_unknown_p (expr)) - { - type = unlowered_expr_type (expr); - if (real_lvalue_p (expr)) - type = build_reference_type (type); - } - - if (type) - return type; - - switch (TREE_CODE (expr)) - { - case VAR_DECL: - case PARM_DECL: - case RESULT_DECL: - case FUNCTION_DECL: - return TREE_TYPE (expr); - break; - - case NEW_EXPR: - case CONST_DECL: - case TEMPLATE_PARM_INDEX: - case CAST_EXPR: - case STATIC_CAST_EXPR: - case REINTERPRET_CAST_EXPR: - case CONST_CAST_EXPR: - case DYNAMIC_CAST_EXPR: - type = TREE_TYPE (expr); - break; - - case INDIRECT_REF: - { - tree ptrtype = describable_type (TREE_OPERAND (expr, 0)); - if (ptrtype && POINTER_TYPE_P (ptrtype)) - type = build_reference_type (TREE_TYPE (ptrtype)); - } - break; - - default: - if (TREE_CODE_CLASS (TREE_CODE (expr)) == tcc_constant) - type = TREE_TYPE (expr); - break; - } - - if (type && type_uses_auto (type)) - return NULL_TREE; - else - return type; -} - /* Implements the C++0x decltype keyword. Returns the type of EXPR, suitable for use as a type-specifier. @@ -6755,28 +6679,16 @@ cxx_eval_vec_init (const constexpr_call *call, tree t, because we're dealing with things like ADDR_EXPR of INTEGER_CST which don't really make sense outside of constant expression evaluation. Also we want to allow folding to COMPONENT_REF, which could cause trouble - with TBAA in fold_indirect_ref_1. */ + with TBAA in fold_indirect_ref_1. + + Try to keep this function synced with fold_indirect_ref_1. */ static tree -cxx_eval_indirect_ref (const constexpr_call *call, tree t, - bool allow_non_constant, bool addr, - bool *non_constant_p) +cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) { - tree orig_op0 = TREE_OPERAND (t, 0); - tree op0 = cxx_eval_constant_expression (call, orig_op0, allow_non_constant, - /*addr*/false, non_constant_p); - tree type, sub, subtype, r; - bool empty_base; - - /* Don't VERIFY_CONSTANT here. */ - if (*non_constant_p) - return t; + tree sub, subtype; - type = TREE_TYPE (t); sub = op0; - r = NULL_TREE; - empty_base = false; - STRIP_NOPS (sub); subtype = TREE_TYPE (sub); gcc_assert (POINTER_TYPE_P (subtype)); @@ -6786,16 +6698,52 @@ cxx_eval_indirect_ref (const constexpr_call *call, tree t, tree op = TREE_OPERAND (sub, 0); tree optype = TREE_TYPE (op); + /* *&CONST_DECL -> to the value of the const decl. */ + if (TREE_CODE (op) == CONST_DECL) + return DECL_INITIAL (op); + /* *&p => p; make sure to handle *&"str"[cst] here. */ if (same_type_ignoring_top_level_qualifiers_p (optype, type)) - r = op; + { + tree fop = fold_read_from_constant_string (op); + if (fop) + return fop; + else + return op; + } + /* *(foo *)&fooarray => fooarray[0] */ + else if (TREE_CODE (optype) == ARRAY_TYPE + && (same_type_ignoring_top_level_qualifiers_p + (type, TREE_TYPE (optype)))) + { + tree type_domain = TYPE_DOMAIN (optype); + tree min_val = size_zero_node; + if (type_domain && TYPE_MIN_VALUE (type_domain)) + min_val = TYPE_MIN_VALUE (type_domain); + return build4_loc (loc, ARRAY_REF, type, op, min_val, + NULL_TREE, NULL_TREE); + } + /* *(foo *)&complexfoo => __real__ complexfoo */ + else if (TREE_CODE (optype) == COMPLEX_TYPE + && (same_type_ignoring_top_level_qualifiers_p + (type, TREE_TYPE (optype)))) + return fold_build1_loc (loc, REALPART_EXPR, type, op); + /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */ + else if (TREE_CODE (optype) == VECTOR_TYPE + && (same_type_ignoring_top_level_qualifiers_p + (type, TREE_TYPE (optype)))) + { + tree part_width = TYPE_SIZE (type); + tree index = bitsize_int (0); + return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, index); + } /* Also handle conversion to an empty base class, which is represented with a NOP_EXPR. */ - else if (!addr && is_empty_class (type) + else if (is_empty_class (type) && CLASS_TYPE_P (optype) && DERIVED_FROM_P (type, optype)) { - r = op; - empty_base = true; + *empty_base = true; + return op; } /* *(foo *)&struct_with_foo_field => COMPONENT_REF */ else if (RECORD_OR_UNION_TYPE_P (optype)) @@ -6807,7 +6755,7 @@ cxx_eval_indirect_ref (const constexpr_call *call, tree t, && (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field), type))) { - r = fold_build3 (COMPONENT_REF, type, op, field, NULL_TREE); + return fold_build3 (COMPONENT_REF, type, op, field, NULL_TREE); break; } } @@ -6825,8 +6773,49 @@ cxx_eval_indirect_ref (const constexpr_call *call, tree t, op00 = TREE_OPERAND (op00, 0); op00type = TREE_TYPE (op00); + /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */ + if (TREE_CODE (op00type) == VECTOR_TYPE + && (same_type_ignoring_top_level_qualifiers_p + (type, TREE_TYPE (op00type)))) + { + HOST_WIDE_INT offset = tree_low_cst (op01, 0); + tree part_width = TYPE_SIZE (type); + unsigned HOST_WIDE_INT part_widthi = tree_low_cst (part_width, 0)/BITS_PER_UNIT; + unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT; + tree index = bitsize_int (indexi); + + if (offset/part_widthi <= TYPE_VECTOR_SUBPARTS (op00type)) + return fold_build3_loc (loc, + BIT_FIELD_REF, type, op00, + part_width, index); + + } + /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */ + else if (TREE_CODE (op00type) == COMPLEX_TYPE + && (same_type_ignoring_top_level_qualifiers_p + (type, TREE_TYPE (op00type)))) + { + tree size = TYPE_SIZE_UNIT (type); + if (tree_int_cst_equal (size, op01)) + return fold_build1_loc (loc, IMAGPART_EXPR, type, op00); + } + /* ((foo *)&fooarray)[1] => fooarray[1] */ + else if (TREE_CODE (op00type) == ARRAY_TYPE + && (same_type_ignoring_top_level_qualifiers_p + (type, TREE_TYPE (op00type)))) + { + tree type_domain = TYPE_DOMAIN (op00type); + tree min_val = size_zero_node; + if (type_domain && TYPE_MIN_VALUE (type_domain)) + min_val = TYPE_MIN_VALUE (type_domain); + op01 = size_binop_loc (loc, EXACT_DIV_EXPR, op01, + TYPE_SIZE_UNIT (type)); + op01 = size_binop_loc (loc, PLUS_EXPR, op01, min_val); + return build4_loc (loc, ARRAY_REF, type, op00, op01, + NULL_TREE, NULL_TREE); + } /* ((foo *)&struct_with_foo_field)[1] => COMPONENT_REF */ - if (RECORD_OR_UNION_TYPE_P (op00type)) + else if (RECORD_OR_UNION_TYPE_P (op00type)) { tree field = TYPE_FIELDS (op00type); for (; field; field = DECL_CHAIN (field)) @@ -6835,32 +6824,71 @@ cxx_eval_indirect_ref (const constexpr_call *call, tree t, && (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field), type))) { - r = fold_build3 (COMPONENT_REF, type, op00, + return fold_build3 (COMPONENT_REF, type, op00, field, NULL_TREE); break; } } } } + /* *(foo *)fooarrptreturn> (*fooarrptr)[0] */ + else if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE + && (same_type_ignoring_top_level_qualifiers_p + (type, TREE_TYPE (TREE_TYPE (subtype))))) + { + tree type_domain; + tree min_val = size_zero_node; + sub = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL); + if (!sub) + sub = build1_loc (loc, INDIRECT_REF, TREE_TYPE (subtype), sub); + type_domain = TYPE_DOMAIN (TREE_TYPE (sub)); + if (type_domain && TYPE_MIN_VALUE (type_domain)) + min_val = TYPE_MIN_VALUE (type_domain); + return build4_loc (loc, ARRAY_REF, type, sub, min_val, NULL_TREE, + NULL_TREE); + } - /* Let build_fold_indirect_ref handle the cases it does fine with. */ - if (r == NULL_TREE) - r = build_fold_indirect_ref (op0); - if (TREE_CODE (r) != INDIRECT_REF) + return NULL_TREE; +} + +static tree +cxx_eval_indirect_ref (const constexpr_call *call, tree t, + bool allow_non_constant, bool addr, + bool *non_constant_p) +{ + tree orig_op0 = TREE_OPERAND (t, 0); + tree op0 = cxx_eval_constant_expression (call, orig_op0, allow_non_constant, + /*addr*/false, non_constant_p); + bool empty_base = false; + tree r; + + /* Don't VERIFY_CONSTANT here. */ + if (*non_constant_p) + return t; + + r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), op0, + &empty_base); + + if (r) r = cxx_eval_constant_expression (call, r, allow_non_constant, addr, non_constant_p); - else if (TREE_CODE (sub) == ADDR_EXPR - || TREE_CODE (sub) == POINTER_PLUS_EXPR) + else { - gcc_assert (!same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t))); - /* FIXME Mike Miller wants this to be OK. */ - if (!allow_non_constant) - error ("accessing value of %qE through a %qT glvalue in a " - "constant expression", build_fold_indirect_ref (sub), - TREE_TYPE (t)); - *non_constant_p = true; - return t; + tree sub = op0; + STRIP_NOPS (sub); + if (TREE_CODE (sub) == ADDR_EXPR + || TREE_CODE (sub) == POINTER_PLUS_EXPR) + { + gcc_assert (!same_type_ignoring_top_level_qualifiers_p + (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t))); + /* FIXME Mike Miller wants this to be OK. */ + if (!allow_non_constant) + error ("accessing value of %qE through a %qT glvalue in a " + "constant expression", build_fold_indirect_ref (sub), + TREE_TYPE (t)); + *non_constant_p = true; + return t; + } } /* If we're pulling out the value of an empty base, make sure @@ -6873,7 +6901,7 @@ cxx_eval_indirect_ref (const constexpr_call *call, tree t, TREE_CONSTANT (r) = true; } - if (TREE_CODE (r) == INDIRECT_REF && TREE_OPERAND (r, 0) == orig_op0) + if (r == NULL_TREE) return t; return r; } @@ -8014,6 +8042,7 @@ build_lambda_expr (void) LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) = CPLD_NONE; LAMBDA_EXPR_CAPTURE_LIST (lambda) = NULL_TREE; LAMBDA_EXPR_THIS_CAPTURE (lambda) = NULL_TREE; + LAMBDA_EXPR_PENDING_PROXIES (lambda) = NULL; LAMBDA_EXPR_RETURN_TYPE (lambda) = NULL_TREE; LAMBDA_EXPR_MUTABLE_P (lambda) = false; return lambda; @@ -8291,6 +8320,135 @@ capture_decltype (tree decl) return type; } +/* Returns true iff DECL is a lambda capture proxy variable created by + build_capture_proxy. */ + +bool +is_capture_proxy (tree decl) +{ + return (TREE_CODE (decl) == VAR_DECL + && DECL_HAS_VALUE_EXPR_P (decl) + && !DECL_ANON_UNION_VAR_P (decl) + && LAMBDA_FUNCTION_P (DECL_CONTEXT (decl))); +} + +/* Returns true iff DECL is a capture proxy for a normal capture + (i.e. without explicit initializer). */ + +bool +is_normal_capture_proxy (tree decl) +{ + tree val; + + if (!is_capture_proxy (decl)) + /* It's not a capture proxy. */ + return false; + + /* It is a capture proxy, is it a normal capture? */ + val = DECL_VALUE_EXPR (decl); + gcc_assert (TREE_CODE (val) == COMPONENT_REF); + val = TREE_OPERAND (val, 1); + return DECL_NORMAL_CAPTURE_P (val); +} + +/* VAR is a capture proxy created by build_capture_proxy; add it to the + current function, which is the operator() for the appropriate lambda. */ + +static inline void +insert_capture_proxy (tree var) +{ + cxx_scope *b; + int skip; + tree stmt_list; + + /* Put the capture proxy in the extra body block so that it won't clash + with a later local variable. */ + b = current_binding_level; + for (skip = 0; ; ++skip) + { + cxx_scope *n = b->level_chain; + if (n->kind == sk_function_parms) + break; + b = n; + } + pushdecl_with_scope (var, b, false); + + /* And put a DECL_EXPR in the STATEMENT_LIST for the same block. */ + var = build_stmt (DECL_SOURCE_LOCATION (var), DECL_EXPR, var); + stmt_list = VEC_index (tree, stmt_list_stack, + VEC_length (tree, stmt_list_stack) - 1 - skip); + gcc_assert (stmt_list); + append_to_statement_list_force (var, &stmt_list); +} + +/* We've just finished processing a lambda; if the containing scope is also + a lambda, insert any capture proxies that were created while processing + the nested lambda. */ + +void +insert_pending_capture_proxies (void) +{ + tree lam; + VEC(tree,gc) *proxies; + unsigned i; + + if (!current_function_decl || !LAMBDA_FUNCTION_P (current_function_decl)) + return; + + lam = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (current_function_decl)); + proxies = LAMBDA_EXPR_PENDING_PROXIES (lam); + for (i = 0; i < VEC_length (tree, proxies); ++i) + { + tree var = VEC_index (tree, proxies, i); + insert_capture_proxy (var); + } + release_tree_vector (LAMBDA_EXPR_PENDING_PROXIES (lam)); + LAMBDA_EXPR_PENDING_PROXIES (lam) = NULL; +} + +/* MEMBER is a capture field in a lambda closure class. Now that we're + inside the operator(), build a placeholder var for future lookups and + debugging. */ + +tree +build_capture_proxy (tree member) +{ + tree var, object, fn, closure, name, lam; + + closure = DECL_CONTEXT (member); + fn = lambda_function (closure); + lam = CLASSTYPE_LAMBDA_EXPR (closure); + + /* The proxy variable forwards to the capture field. */ + object = build_fold_indirect_ref (DECL_ARGUMENTS (fn)); + object = finish_non_static_data_member (member, object, NULL_TREE); + if (REFERENCE_REF_P (object)) + object = TREE_OPERAND (object, 0); + + /* Remove the __ inserted by add_capture. */ + name = get_identifier (IDENTIFIER_POINTER (DECL_NAME (member)) + 2); + + var = build_decl (input_location, VAR_DECL, name, TREE_TYPE (object)); + SET_DECL_VALUE_EXPR (var, object); + DECL_HAS_VALUE_EXPR_P (var) = 1; + DECL_ARTIFICIAL (var) = 1; + TREE_USED (var) = 1; + DECL_CONTEXT (var) = fn; + + if (name == this_identifier) + { + gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (lam) == member); + LAMBDA_EXPR_THIS_CAPTURE (lam) = var; + } + + if (fn == current_function_decl) + insert_capture_proxy (var); + else + VEC_safe_push (tree, gc, LAMBDA_EXPR_PENDING_PROXIES (lam), var); + + return var; +} + /* From an ID and INITIALIZER, create a capture (by reference if BY_REFERENCE_P is true), add it to the capture-list for LAMBDA, and return it. */ @@ -8299,8 +8457,8 @@ tree add_capture (tree lambda, tree id, tree initializer, bool by_reference_p, bool explicit_init_p) { - tree type; - tree member; + char *buf; + tree type, member, name; type = lambda_capture_field_type (initializer); if (by_reference_p) @@ -8310,8 +8468,32 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p, error ("cannot capture %qE by reference", initializer); } + /* 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 + unset because template instantiation uses the name to find + instantiated fields. */ + buf = (char *) alloca (IDENTIFIER_LENGTH (id) + 3); + buf[1] = buf[0] = '_'; + memcpy (buf + 2, IDENTIFIER_POINTER (id), + IDENTIFIER_LENGTH (id) + 1); + name = get_identifier (buf); + + /* If TREE_TYPE isn't set, we're still in the introducer, so check + for duplicates. */ + if (!TREE_TYPE (lambda)) + { + if (IDENTIFIER_MARKED (name)) + { + pedwarn (input_location, 0, + "already captured %qD in lambda expression", id); + return NULL_TREE; + } + IDENTIFIER_MARKED (name) = true; + } + /* Make member variable. */ - member = build_lang_decl (FIELD_DECL, id, type); + member = build_lang_decl (FIELD_DECL, name, type); + if (!explicit_init_p) /* Normal captures are invisible to name lookup but uses are replaced with references to the capture field; we implement this by only @@ -8320,6 +8502,9 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p, always visible. */ DECL_NORMAL_CAPTURE_P (member) = true; + if (id == this_identifier) + LAMBDA_EXPR_THIS_CAPTURE (lambda) = member; + /* Add it to the appropriate closure class if we've started it. */ if (current_class_type && current_class_type == TREE_TYPE (lambda)) finish_member_declaration (member); @@ -8327,41 +8512,26 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p, LAMBDA_EXPR_CAPTURE_LIST (lambda) = tree_cons (member, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda)); - if (id == get_identifier ("__this")) - { - if (LAMBDA_EXPR_CAPTURES_THIS_P (lambda)) - error ("already captured %<this%> in lambda expression"); - LAMBDA_EXPR_THIS_CAPTURE (lambda) = member; - } - - return member; + if (TREE_TYPE (lambda)) + return build_capture_proxy (member); + /* For explicit captures we haven't started the function yet, so we wait + and build the proxy from cp_parser_lambda_body. */ + return NULL_TREE; } /* Register all the capture members on the list CAPTURES, which is the LAMBDA_EXPR_CAPTURE_LIST for the lambda after the introducer. */ -void register_capture_members (tree captures) +void +register_capture_members (tree captures) { - if (captures) - { - register_capture_members (TREE_CHAIN (captures)); - finish_member_declaration (TREE_PURPOSE (captures)); - } -} - -/* Given a FIELD_DECL decl belonging to a closure type, return a - COMPONENT_REF of it relative to the 'this' parameter of the op() for - that type. */ + if (captures == NULL_TREE) + return; -static tree -thisify_lambda_field (tree decl) -{ - tree context = lambda_function (DECL_CONTEXT (decl)); - tree object = cp_build_indirect_ref (DECL_ARGUMENTS (context), - RO_NULL, - tf_warning_or_error); - return finish_non_static_data_member (decl, object, - /*qualifying_scope*/NULL_TREE); + register_capture_members (TREE_CHAIN (captures)); + /* We set this in add_capture to avoid duplicates. */ + IDENTIFIER_MARKED (DECL_NAME (TREE_PURPOSE (captures))) = false; + finish_member_declaration (TREE_PURPOSE (captures)); } /* Similar to add_capture, except this works on a stack of nested lambdas. @@ -8371,9 +8541,9 @@ thisify_lambda_field (tree decl) tree add_default_capture (tree lambda_stack, tree id, tree initializer) { - bool this_capture_p = (id == get_identifier ("__this")); + bool this_capture_p = (id == this_identifier); - tree member = NULL_TREE; + tree var = NULL_TREE; tree saved_class_type = current_class_type; @@ -8386,7 +8556,7 @@ add_default_capture (tree lambda_stack, tree id, tree initializer) tree lambda = TREE_VALUE (node); current_class_type = TREE_TYPE (lambda); - member = add_capture (lambda, + var = add_capture (lambda, id, initializer, /*by_reference_p=*/ @@ -8394,12 +8564,12 @@ add_default_capture (tree lambda_stack, tree id, tree initializer) && (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) == CPLD_REFERENCE)), /*explicit_init_p=*/false); - initializer = thisify_lambda_field (member); + initializer = convert_from_reference (var); } current_class_type = saved_class_type; - return member; + return var; } /* Return the capture pertaining to a use of 'this' in LAMBDA, in the form of an @@ -8432,8 +8602,7 @@ lambda_expr_this_capture (tree lambda) if (LAMBDA_EXPR_THIS_CAPTURE (lambda)) { /* An outer lambda has already captured 'this'. */ - tree cap = LAMBDA_EXPR_THIS_CAPTURE (lambda); - init = thisify_lambda_field (cap); + init = LAMBDA_EXPR_THIS_CAPTURE (lambda); break; } @@ -8455,7 +8624,7 @@ lambda_expr_this_capture (tree lambda) if (init) this_capture = add_default_capture (lambda_stack, - /*id=*/get_identifier ("__this"), + /*id=*/this_identifier, init); } @@ -8469,9 +8638,7 @@ lambda_expr_this_capture (tree lambda) /* To make sure that current_class_ref is for the lambda. */ gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)) == TREE_TYPE (lambda)); - result = finish_non_static_data_member (this_capture, - NULL_TREE, - /*qualifying_scope=*/NULL_TREE); + result = this_capture; /* If 'this' is captured, each use of 'this' is transformed into an access to the corresponding unnamed data member of the closure @@ -8644,4 +8811,28 @@ maybe_add_lambda_conv_op (tree type) if (nested) pop_function_context (); } + +/* Returns true iff VAL is a lambda-related declaration which should + be ignored by unqualified lookup. */ + +bool +is_lambda_ignored_entity (tree val) +{ + /* In unevaluated context, look past normal capture proxies. */ + if (cp_unevaluated_operand && is_normal_capture_proxy (val)) + return true; + + /* Always ignore lambda fields, their names are only for debugging. */ + if (TREE_CODE (val) == FIELD_DECL + && CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (val))) + return true; + + /* None of the lookups that use qualify_lookup want the op() from the + lambda; they want the one from the enclosing class. */ + if (TREE_CODE (val) == FUNCTION_DECL && LAMBDA_FUNCTION_P (val)) + return true; + + return false; +} + #include "gt-cp-semantics.h" diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 5b988e9e0a1..31005084b3c 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1167,6 +1167,16 @@ strip_typedefs (tree t) if (!result) result = TYPE_MAIN_VARIANT (t); + if (TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (result) + || TYPE_ALIGN (t) != TYPE_ALIGN (result)) + { + gcc_assert (TYPE_USER_ALIGN (t)); + if (TYPE_ALIGN (t) == TYPE_ALIGN (result)) + result = build_variant_type_copy (result); + else + result = build_aligned_type (result, TYPE_ALIGN (t)); + TYPE_USER_ALIGN (result) = true; + } if (TYPE_ATTRIBUTES (t)) result = cp_build_type_attribute_variant (result, TYPE_ATTRIBUTES (t)); return cp_build_qualified_type (result, cp_type_quals (t)); @@ -3363,9 +3373,8 @@ cp_fix_function_decl_p (tree decl) /* Don't fix same_body aliases. Although they don't have their own CFG, they share it with what they alias to. */ - if (!node - || node->decl == decl - || !node->same_body) + if (!node || !node->alias + || !VEC_length (ipa_ref_t, node->ref_list.references)) return true; } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 1bed291617e..7af76b1be76 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -830,7 +830,8 @@ merge_types (tree t1, tree t2) gcc_assert (type_memfn_quals (t1) == type_memfn_quals (t2)); rval = apply_memfn_quals (rval, type_memfn_quals (t1)); raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1), - TYPE_RAISES_EXCEPTIONS (t2)); + TYPE_RAISES_EXCEPTIONS (t2), + NULL_TREE); t1 = build_exception_variant (rval, raises); break; } @@ -841,7 +842,8 @@ merge_types (tree t1, tree t2) is just the main variant of this. */ tree basetype = class_of_this_parm (t2); tree raises = merge_exception_specifiers (TYPE_RAISES_EXCEPTIONS (t1), - TYPE_RAISES_EXCEPTIONS (t2)); + TYPE_RAISES_EXCEPTIONS (t2), + NULL_TREE); tree t3; /* If this was a member function type, get back to the @@ -2679,8 +2681,7 @@ build_x_indirect_ref (tree expr, ref_operator errorstring, if (processing_template_decl) { - /* Retain the type if we know the operand is a pointer so that - describable_type doesn't make auto deduction break. */ + /* Retain the type if we know the operand is a pointer. */ if (TREE_TYPE (expr) && POINTER_TYPE_P (TREE_TYPE (expr))) return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr); if (type_dependent_expression_p (expr)) diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index fa64d1d7253..6d6267e8d72 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1551,6 +1551,7 @@ build_m_component_ref (tree datum, tree component) if (TYPE_PTRMEM_P (ptrmem_type)) { + bool is_lval = real_lvalue_p (datum); tree ptype; /* Compute the type of the field, as described in [expr.ref]. @@ -1573,7 +1574,11 @@ build_m_component_ref (tree datum, tree component) datum = build2 (POINTER_PLUS_EXPR, ptype, fold_convert (ptype, datum), build_nop (sizetype, component)); - return cp_build_indirect_ref (datum, RO_NULL, tf_warning_or_error); + datum = cp_build_indirect_ref (datum, RO_NULL, tf_warning_or_error); + /* If the object expression was an rvalue, return an rvalue. */ + if (!is_lval) + datum = move (datum); + return datum; } else return build2 (OFFSET_REF, type, datum, component); @@ -1766,12 +1771,24 @@ add_exception_specifier (tree list, tree spec, int complain) return list; } +/* Like nothrow_spec_p, but don't abort on deferred noexcept. */ + +static bool +nothrow_spec_p_uninst (const_tree spec) +{ + if (DEFERRED_NOEXCEPT_SPEC_P (spec)) + return false; + return nothrow_spec_p (spec); +} + /* Combine the two exceptions specifier lists LIST and ADD, and return - their union. */ + their union. If FN is non-null, it's the source of ADD. */ tree -merge_exception_specifiers (tree list, tree add) +merge_exception_specifiers (tree list, tree add, tree fn) { + tree noex, orig_list; + /* No exception-specifier or noexcept(false) are less strict than anything else. Prefer the newer variant (LIST). */ if (!list || list == noexcept_false_spec) @@ -1779,37 +1796,51 @@ merge_exception_specifiers (tree list, tree add) else if (!add || add == noexcept_false_spec) return add; - /* We need to instantiate deferred noexcept before we get here. */ - gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (list) - && !DEFERRED_NOEXCEPT_SPEC_P (add)); - - /* For merging noexcept(true) and throw(), take the more recent one (LIST). - Any other noexcept-spec should only be merged with an equivalent one. - So the !TREE_VALUE code below is correct for all cases. */ - if (!TREE_VALUE (add)) + /* noexcept(true) and throw() are stricter than anything else. + As above, prefer the more recent one (LIST). */ + if (nothrow_spec_p_uninst (add)) return list; - else if (!TREE_VALUE (list)) + + noex = TREE_PURPOSE (list); + if (DEFERRED_NOEXCEPT_SPEC_P (add)) + { + /* If ADD is a deferred noexcept, we must have been called from + process_subob_fn. For implicitly declared functions, we build up + a list of functions to consider at instantiation time. */ + if (noex == boolean_true_node) + noex = NULL_TREE; + gcc_assert (fn && (!noex || is_overloaded_fn (noex))); + noex = build_overload (fn, noex); + } + else if (nothrow_spec_p_uninst (list)) return add; else + gcc_checking_assert (!TREE_PURPOSE (add) + || cp_tree_equal (noex, TREE_PURPOSE (add))); + + /* Combine the dynamic-exception-specifiers, if any. */ + orig_list = list; + for (; add && TREE_VALUE (add); add = TREE_CHAIN (add)) { - tree orig_list = list; + tree spec = TREE_VALUE (add); + tree probe; - for (; add; add = TREE_CHAIN (add)) + for (probe = orig_list; probe && TREE_VALUE (probe); + probe = TREE_CHAIN (probe)) + if (same_type_p (TREE_VALUE (probe), spec)) + break; + if (!probe) { - tree spec = TREE_VALUE (add); - tree probe; - - for (probe = orig_list; probe; probe = TREE_CHAIN (probe)) - if (same_type_p (TREE_VALUE (probe), spec)) - break; - if (!probe) - { - spec = build_tree_list (NULL_TREE, spec); - TREE_CHAIN (spec) = list; - list = spec; - } + spec = build_tree_list (NULL_TREE, spec); + TREE_CHAIN (spec) = list; + list = spec; } } + + /* Keep the noexcept-specifier at the beginning of the list. */ + if (noex != TREE_PURPOSE (list)) + list = tree_cons (noex, TREE_VALUE (list), TREE_CHAIN (list)); + return list; } diff --git a/gcc/cprop.c b/gcc/cprop.c index b7b17b19387..83193b9d6b4 100644 --- a/gcc/cprop.c +++ b/gcc/cprop.c @@ -1878,8 +1878,6 @@ struct rtl_opt_pass pass_rtl_cprop = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_verify_flow | TODO_ggc_collect /* todo_flags_finish */ } }; - diff --git a/gcc/cse.c b/gcc/cse.c index cfa2b00216c..8a31cd1a3da 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -2669,16 +2669,26 @@ exp_equiv_p (const_rtx x, const_rtx y, int validate, bool for_gcse) case MEM: if (for_gcse) { - /* Can't merge two expressions in different alias sets, since we - can decide that the expression is transparent in a block when - it isn't, due to it being set with the different alias set. */ - if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y)) - return 0; - /* A volatile mem should not be considered equivalent to any other. */ if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y)) return 0; + + /* Can't merge two expressions in different alias sets, since we + can decide that the expression is transparent in a block when + it isn't, due to it being set with the different alias set. + + Also, can't merge two expressions with different MEM_ATTRS. + They could e.g. be two different entities allocated into the + same space on the stack (see e.g. PR25130). In that case, the + MEM addresses can be the same, even though the two MEMs are + absolutely not equivalent. + + But because really all MEM attributes should be the same for + equivalent MEMs, we just use the invariant that MEMs that have + the same attributes share the same mem_attrs data structure. */ + if (MEM_ATTRS (x) != MEM_ATTRS (y)) + return 0; } break; @@ -7414,7 +7424,6 @@ struct rtl_opt_pass pass_cse = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_ggc_collect | TODO_verify_flow, /* todo_flags_finish */ } @@ -7477,7 +7486,6 @@ struct rtl_opt_pass pass_cse2 = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_ggc_collect | TODO_verify_flow /* todo_flags_finish */ } @@ -7538,7 +7546,6 @@ struct rtl_opt_pass pass_cse_after_global_opts = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_ggc_collect | TODO_verify_flow /* todo_flags_finish */ } diff --git a/gcc/dbxout.c b/gcc/dbxout.c index 9160fb3ded9..8c59b459438 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -88,6 +88,7 @@ along with GCC; see the file COPYING3. If not see #include "debug.h" #include "function.h" #include "target.h" +#include "common/common-target.h" #include "langhooks.h" #include "obstack.h" #include "expr.h" @@ -951,7 +952,7 @@ dbxout_function_end (tree decl ATTRIBUTE_UNUSED) named sections. */ if (!use_gnu_debug_info_extensions || NO_DBX_FUNCTION_END - || !targetm.have_named_sections) + || !targetm_common.have_named_sections) return; /* By convention, GCC will mark the end of a function with an N_FUN diff --git a/gcc/dce.c b/gcc/dce.c index 997432501d3..ae2ff478597 100644 --- a/gcc/dce.c +++ b/gcc/dce.c @@ -786,7 +786,6 @@ struct rtl_opt_pass pass_ud_rtl_dce = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_df_finish | TODO_verify_rtl_sharing | TODO_ggc_collect /* todo_flags_finish */ } @@ -1138,7 +1137,6 @@ struct rtl_opt_pass pass_fast_rtl_dce = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_df_finish | TODO_verify_rtl_sharing | TODO_ggc_collect /* todo_flags_finish */ } diff --git a/gcc/ddg.c b/gcc/ddg.c index b8ae375f153..d06bdbb5448 100644 --- a/gcc/ddg.c +++ b/gcc/ddg.c @@ -390,6 +390,33 @@ insns_may_alias_p (rtx insn1, rtx insn2) &PATTERN (insn2)); } +/* Given two nodes, analyze their RTL insns and add intra-loop mem deps + to ddg G. */ +static void +add_intra_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to) +{ + + if ((from->cuid == to->cuid) + || !insns_may_alias_p (from->insn, to->insn)) + /* Do not create edge if memory references have disjoint alias sets + or 'to' and 'from' are the same instruction. */ + return; + + if (mem_write_insn_p (from->insn)) + { + if (mem_read_insn_p (to->insn)) + create_ddg_dep_no_link (g, from, to, + DEBUG_INSN_P (to->insn) + ? ANTI_DEP : TRUE_DEP, MEM_DEP, 0); + else + create_ddg_dep_no_link (g, from, to, + DEBUG_INSN_P (to->insn) + ? ANTI_DEP : OUTPUT_DEP, MEM_DEP, 0); + } + else if (!mem_read_insn_p (to->insn)) + create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 0); +} + /* Given two nodes, analyze their RTL insns and add inter-loop mem deps to ddg G. */ static void @@ -477,10 +504,22 @@ build_intra_loop_deps (ddg_ptr g) if (DEBUG_INSN_P (j_node->insn)) continue; if (mem_access_insn_p (j_node->insn)) - /* Don't bother calculating inter-loop dep if an intra-loop dep - already exists. */ + { + /* Don't bother calculating inter-loop dep if an intra-loop dep + already exists. */ if (! TEST_BIT (dest_node->successors, j)) add_inter_loop_mem_dep (g, dest_node, j_node); + /* If -fmodulo-sched-allow-regmoves + is set certain anti-dep edges are not created. + It might be that these anti-dep edges are on the + path from one memory instruction to another such that + removing these edges could cause a violation of the + memory dependencies. Thus we add intra edges between + every two memory instructions in this case. */ + if (flag_modulo_sched_allow_regmoves + && !TEST_BIT (dest_node->predecessors, j)) + add_intra_loop_mem_dep (g, j_node, dest_node); + } } } } diff --git a/gcc/defaults.h b/gcc/defaults.h index 815ddd243f8..5e84cb8cd78 100644 --- a/gcc/defaults.h +++ b/gcc/defaults.h @@ -1,6 +1,6 @@ /* Definitions of various defaults for tm.h macros. Copyright (C) 1992, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2007, 2008, 2009, 2010 + 2005, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Contributed by Ron Guilmette (rfg@monkeys.com) @@ -1288,9 +1288,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #ifdef STACK_CHECK_PROTECT #define STACK_OLD_CHECK_PROTECT STACK_CHECK_PROTECT #else -#define STACK_OLD_CHECK_PROTECT \ - (targetm.except_unwind_info (&global_options) == UI_SJLJ \ - ? 75 * UNITS_PER_WORD \ +#define STACK_OLD_CHECK_PROTECT \ + (targetm_common.except_unwind_info (&global_options) == UI_SJLJ \ + ? 75 * UNITS_PER_WORD \ : 8 * 1024) #endif @@ -1298,9 +1298,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see overflow detection. The default value conveys an estimate of the amount of stack required to propagate an exception. */ #ifndef STACK_CHECK_PROTECT -#define STACK_CHECK_PROTECT \ - (targetm.except_unwind_info (&global_options) == UI_SJLJ \ - ? 75 * UNITS_PER_WORD \ +#define STACK_CHECK_PROTECT \ + (targetm_common.except_unwind_info (&global_options) == UI_SJLJ \ + ? 75 * UNITS_PER_WORD \ : 12 * 1024) #endif diff --git a/gcc/df-problems.c b/gcc/df-problems.c index e5b88e3d2dc..59bed8bd667 100644 --- a/gcc/df-problems.c +++ b/gcc/df-problems.c @@ -906,6 +906,7 @@ df_lr_local_compute (bitmap all_blocks ATTRIBUTE_UNUSED) blocks within infinite loops. */ if (!reload_completed) { + unsigned int pic_offset_table_regnum = PIC_OFFSET_TABLE_REGNUM; /* Any reference to any pseudo before reload is a potential reference of the frame pointer. */ bitmap_set_bit (&df->hardware_regs_used, FRAME_POINTER_REGNUM); @@ -919,9 +920,9 @@ df_lr_local_compute (bitmap all_blocks ATTRIBUTE_UNUSED) /* Any constant, or pseudo with constant equivalences, may require reloading from memory using the pic register. */ - if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM - && fixed_regs[PIC_OFFSET_TABLE_REGNUM]) - bitmap_set_bit (&df->hardware_regs_used, PIC_OFFSET_TABLE_REGNUM); + if (pic_offset_table_regnum != INVALID_REGNUM + && fixed_regs[pic_offset_table_regnum]) + bitmap_set_bit (&df->hardware_regs_used, pic_offset_table_regnum); } EXECUTE_IF_SET_IN_BITMAP (df_lr->out_of_date_transfer_functions, 0, bb_index, bi) diff --git a/gcc/df-scan.c b/gcc/df-scan.c index 42b4b145c02..7179051f0b8 100644 --- a/gcc/df-scan.c +++ b/gcc/df-scan.c @@ -3625,6 +3625,8 @@ df_get_regular_block_artificial_uses (bitmap regular_block_artificial_uses) live everywhere -- which might not already be the case for blocks within infinite loops. */ { + unsigned int picreg = PIC_OFFSET_TABLE_REGNUM; + /* Any reference to any pseudo before reload is a potential reference of the frame pointer. */ bitmap_set_bit (regular_block_artificial_uses, FRAME_POINTER_REGNUM); @@ -3642,9 +3644,9 @@ df_get_regular_block_artificial_uses (bitmap regular_block_artificial_uses) /* Any constant, or pseudo with constant equivalences, may require reloading from memory using the pic register. */ - if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM - && fixed_regs[PIC_OFFSET_TABLE_REGNUM]) - bitmap_set_bit (regular_block_artificial_uses, PIC_OFFSET_TABLE_REGNUM); + if (picreg != INVALID_REGNUM + && fixed_regs[picreg]) + bitmap_set_bit (regular_block_artificial_uses, picreg); } /* The all-important stack pointer must always be live. */ bitmap_set_bit (regular_block_artificial_uses, STACK_POINTER_REGNUM); @@ -3779,6 +3781,10 @@ df_get_entry_block_def_set (bitmap entry_block_defs) /* These registers are live everywhere. */ if (!reload_completed) { +#ifdef PIC_OFFSET_TABLE_REGNUM + unsigned int picreg = PIC_OFFSET_TABLE_REGNUM; +#endif + #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM /* Pseudos with argument area equivalences may require reloading via the argument pointer. */ @@ -3789,9 +3795,9 @@ df_get_entry_block_def_set (bitmap entry_block_defs) #ifdef PIC_OFFSET_TABLE_REGNUM /* Any constant, or pseudo with constant equivalences, may require reloading from memory using the pic register. */ - if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM - && fixed_regs[PIC_OFFSET_TABLE_REGNUM]) - bitmap_set_bit (entry_block_defs, PIC_OFFSET_TABLE_REGNUM); + if (picreg != INVALID_REGNUM + && fixed_regs[picreg]) + bitmap_set_bit (entry_block_defs, picreg); #endif } @@ -3889,6 +3895,7 @@ static void df_get_exit_block_use_set (bitmap exit_block_uses) { unsigned int i; + unsigned int picreg = PIC_OFFSET_TABLE_REGNUM; bitmap_clear (exit_block_uses); @@ -3913,9 +3920,9 @@ df_get_exit_block_use_set (bitmap exit_block_uses) Assume the pic register is not in use, or will be handled by other means, if it is not fixed. */ if (!PIC_OFFSET_TABLE_REG_CALL_CLOBBERED - && (unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM - && fixed_regs[PIC_OFFSET_TABLE_REGNUM]) - bitmap_set_bit (exit_block_uses, PIC_OFFSET_TABLE_REGNUM); + && picreg != INVALID_REGNUM + && fixed_regs[picreg]) + bitmap_set_bit (exit_block_uses, picreg); /* Mark all global registers, and all registers used by the epilogue as being live at the end of the function since they diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 7faa38afc5e..b6f6cc4cd37 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -10271,7 +10271,9 @@ assembly code. Permissible names are: @samp{arm2}, @samp{arm250}, @samp{cortex-m4}, @samp{cortex-m3}, @samp{cortex-m1}, @samp{cortex-m0}, -@samp{xscale}, @samp{iwmmxt}, @samp{iwmmxt2}, @samp{ep9312}. +@samp{xscale}, @samp{iwmmxt}, @samp{iwmmxt2}, @samp{ep9312}, +@samp{fa526}, @samp{fa626}, +@samp{fa606te}, @samp{fa626te}, @samp{fmp626}, @samp{fa726te}. @item -mtune=@var{name} @opindex mtune diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index b32ff89bc8e..fec5d55df24 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -99,6 +99,16 @@ initializer @code{TARGETCM_INITIALIZER} in themselves, they should set @code{target_has_targetcm=yes} in @file{config.gcc}; otherwise a default definition is used. +Similarly, there is a @code{targetm_common} variable for hooks that +are shared between the compiler driver and the compilers proper, +documented as ``Common Target Hook''. This is declared in +@file{common/common-target.h}, the initializer +@code{TARGETM_COMMON_INITIALIZER} in +@file{common/common-target-def.h}. If targets initialize +@code{targetm_common} themselves, they should set +@code{target_has_targetm_common=yes} in @file{config.gcc}; otherwise a +default definition is used. + @node Driver @section Controlling the Compilation Driver, @file{gcc} @cindex driver @@ -383,6 +393,10 @@ directories from linking commands. Do not give it a nonzero value if removing duplicate search directories changes the linker's semantics. @end defmac +@deftypevr {Common Target Hook} bool TARGET_ALWAYS_STRIP_DOTDOT +True if @file{..} components should always be removed from directory names computed relative to GCC's internal directories, false (default) if such components should be preserved and directory names containing them passed to other tools such as the linker. +@end deftypevr + @defmac MULTILIB_DEFAULTS Define this macro as a C expression for the initializer of an array of string to tell the driver program which options are defaults for this @@ -664,7 +678,7 @@ This variable is declared in @file{options.h}, which is included before any target-specific headers. @end deftypevar -@deftypevr {Target Hook} int TARGET_DEFAULT_TARGET_FLAGS +@deftypevr {Common Target Hook} int TARGET_DEFAULT_TARGET_FLAGS This variable specifies the initial value of @code{target_flags}. Its default setting is 0. @end deftypevr @@ -672,7 +686,7 @@ Its default setting is 0. @cindex optional hardware or system features @cindex features, optional, in system conventions -@deftypefn {Target Hook} bool TARGET_HANDLE_OPTION (struct gcc_options *@var{opts}, struct gcc_options *@var{opts_set}, const struct cl_decoded_option *@var{decoded}, unsigned int @var{loc}) +@deftypefn {Common Target Hook} bool TARGET_HANDLE_OPTION (struct gcc_options *@var{opts}, struct gcc_options *@var{opts_set}, const struct cl_decoded_option *@var{decoded}, location_t @var{loc}) This hook is called whenever the user specifies one of the target-specific options described by the @file{.opt} definition files (@pxref{Options}). It has the opportunity to do some option-specific @@ -730,7 +744,7 @@ used to alter option flag variables which only exist in those frontends. @end defmac -@deftypevr {Target Hook} {const struct default_options *} TARGET_OPTION_OPTIMIZATION_TABLE +@deftypevr {Common Target Hook} {const struct default_options *} TARGET_OPTION_OPTIMIZATION_TABLE Some machines may desire to change what optimizations are performed for various optimization levels. This variable, if defined, describes options to enable at particular sets of optimization levels. These @@ -744,7 +758,7 @@ options are changed via @code{#pragma GCC optimize} or by using the @code{optimize} attribute. @end deftypevr -@deftypefn {Target Hook} void TARGET_OPTION_INIT_STRUCT (struct gcc_options *@var{opts}) +@deftypefn {Common Target Hook} void TARGET_OPTION_INIT_STRUCT (struct gcc_options *@var{opts}) Set target-dependent initial values of fields in @var{opts}. @end deftypefn @@ -3954,7 +3968,7 @@ This section describes the macros which let you control how various types of arguments are passed in registers or how they are arranged in the stack. -@deftypefn {Target Hook} rtx TARGET_FUNCTION_ARG (CUMULATIVE_ARGS *@var{ca}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named}) +@deftypefn {Target Hook} rtx TARGET_FUNCTION_ARG (cumulative_args_t @var{ca}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named}) Return an RTX indicating whether a function argument is passed in a register and if so, which register. @@ -4014,7 +4028,7 @@ definition that is usually appropriate, refer to @file{expr.h} for additional documentation. @end deftypefn -@deftypefn {Target Hook} rtx TARGET_FUNCTION_INCOMING_ARG (CUMULATIVE_ARGS *@var{ca}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named}) +@deftypefn {Target Hook} rtx TARGET_FUNCTION_INCOMING_ARG (cumulative_args_t @var{ca}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named}) Define this hook if the target machine has ``register windows'', so that the register in which a function sees an arguments is not necessarily the same as the one in which the caller passed the @@ -4030,7 +4044,7 @@ If @code{TARGET_FUNCTION_INCOMING_ARG} is not defined, @code{TARGET_FUNCTION_ARG} serves both purposes. @end deftypefn -@deftypefn {Target Hook} int TARGET_ARG_PARTIAL_BYTES (CUMULATIVE_ARGS *@var{cum}, enum machine_mode @var{mode}, tree @var{type}, bool @var{named}) +@deftypefn {Target Hook} int TARGET_ARG_PARTIAL_BYTES (cumulative_args_t @var{cum}, enum machine_mode @var{mode}, tree @var{type}, bool @var{named}) This target hook returns the number of bytes at the beginning of an argument that must be put in registers. The value must be zero for arguments that are passed entirely in registers or that are entirely @@ -4049,7 +4063,7 @@ register to be used by the caller for this argument; likewise @code{TARGET_FUNCTION_INCOMING_ARG}, for the called function. @end deftypefn -@deftypefn {Target Hook} bool TARGET_PASS_BY_REFERENCE (CUMULATIVE_ARGS *@var{cum}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named}) +@deftypefn {Target Hook} bool TARGET_PASS_BY_REFERENCE (cumulative_args_t @var{cum}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named}) This target hook should return @code{true} if an argument at the position indicated by @var{cum} should be passed by reference. This predicate is queried after target independent reasons for being @@ -4061,7 +4075,7 @@ The pointer is passed in whatever way is appropriate for passing a pointer to that type. @end deftypefn -@deftypefn {Target Hook} bool TARGET_CALLEE_COPIES (CUMULATIVE_ARGS *@var{cum}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named}) +@deftypefn {Target Hook} bool TARGET_CALLEE_COPIES (cumulative_args_t @var{cum}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named}) The function argument described by the parameters to this hook is known to be passed by reference. The hook should return true if the function argument should be copied by the callee instead of copied @@ -4140,7 +4154,7 @@ argument @var{libname} exists for symmetry with @c --mew 5feb93 i switched the order of the sentences. --mew 10feb93 @end defmac -@deftypefn {Target Hook} void TARGET_FUNCTION_ARG_ADVANCE (CUMULATIVE_ARGS *@var{ca}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named}) +@deftypefn {Target Hook} void TARGET_FUNCTION_ARG_ADVANCE (cumulative_args_t @var{ca}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named}) This hook updates the summarizer variable pointed to by @var{ca} to advance past an argument in the argument list. The values @var{mode}, @var{type} and @var{named} describe that argument. Once this is done, @@ -4951,7 +4965,7 @@ The default version of this hook invokes a function called normally defined in @file{libgcc2.c}. @end deftypefn -@deftypefn {Target Hook} bool TARGET_SUPPORTS_SPLIT_STACK (bool @var{report}, struct gcc_options *@var{opts}) +@deftypefn {Common Target Hook} bool TARGET_SUPPORTS_SPLIT_STACK (bool @var{report}, struct gcc_options *@var{opts}) Whether this target supports splitting the stack when the options described in @var{opts} have been passed. This is called after options have been parsed, so the target may reject splitting the stack in some configurations. The default version of this hook returns false. If @var{report} is true, this function may issue a warning or error; if @var{report} is false, it must simply return a value @end deftypefn @@ -5031,7 +5045,7 @@ return value of this function should be an RTX that contains the value to use as the return of @code{__builtin_saveregs}. @end deftypefn -@deftypefn {Target Hook} void TARGET_SETUP_INCOMING_VARARGS (CUMULATIVE_ARGS *@var{args_so_far}, enum machine_mode @var{mode}, tree @var{type}, int *@var{pretend_args_size}, int @var{second_time}) +@deftypefn {Target Hook} void TARGET_SETUP_INCOMING_VARARGS (cumulative_args_t @var{args_so_far}, enum machine_mode @var{mode}, tree @var{type}, int *@var{pretend_args_size}, int @var{second_time}) This target hook offers an alternative to using @code{__builtin_saveregs} and defining the hook @code{TARGET_EXPAND_BUILTIN_SAVEREGS}. Use it to store the anonymous @@ -5065,7 +5079,7 @@ end of the source file. The hook @code{TARGET_SETUP_INCOMING_VARARGS} should not generate any instructions in this case. @end deftypefn -@deftypefn {Target Hook} bool TARGET_STRICT_ARGUMENT_NAMING (CUMULATIVE_ARGS *@var{ca}) +@deftypefn {Target Hook} bool TARGET_STRICT_ARGUMENT_NAMING (cumulative_args_t @var{ca}) Define this hook to return @code{true} if the location where a function argument is passed depends on whether or not it is a named argument. @@ -5080,7 +5094,7 @@ except the last are treated as named. You need not define this hook if it always returns @code{false}. @end deftypefn -@deftypefn {Target Hook} bool TARGET_PRETEND_OUTGOING_VARARGS_NAMED (CUMULATIVE_ARGS *@var{ca}) +@deftypefn {Target Hook} bool TARGET_PRETEND_OUTGOING_VARARGS_NAMED (cumulative_args_t @var{ca}) If you need to conditionally change ABIs so that one works with @code{TARGET_SETUP_INCOMING_VARARGS}, but the other works like neither @code{TARGET_SETUP_INCOMING_VARARGS} nor @code{TARGET_STRICT_ARGUMENT_NAMING} was @@ -7341,7 +7355,7 @@ Return NULL if function should go to default text section. Used by the target to emit any assembler directives or additional labels needed when a function is partitioned between different sections. Output should be written to @var{file}. The function decl is available as @var{decl} and the new section is `cold' if @var{new_is_cold} is @code{true}. @end deftypefn -@deftypevr {Target Hook} bool TARGET_HAVE_NAMED_SECTIONS +@deftypevr {Common Target Hook} bool TARGET_HAVE_NAMED_SECTIONS This flag is true if the target supports @code{TARGET_ASM_NAMED_SECTION}. It must not be modified by command-line option processing. @end deftypevr @@ -8856,7 +8870,7 @@ Otherwise, if your target supports this information (if it defines or @code{OBJECT_FORMAT_ELF}), GCC will provide a default definition of 1. @end defmac -@deftypefn {Target Hook} {enum unwind_info_type} TARGET_EXCEPT_UNWIND_INFO (struct gcc_options *@var{opts}) +@deftypefn {Common Target Hook} {enum unwind_info_type} TARGET_EXCEPT_UNWIND_INFO (struct gcc_options *@var{opts}) This hook defines the mechanism that will be used for exception handling by the target. If the target has ABI specified unwind tables, the hook should return @code{UI_TARGET}. If the target is to use the @@ -8882,7 +8896,7 @@ The default implementation of the hook first honors the must define this hook so that @var{opts} is used correctly. @end deftypefn -@deftypevr {Target Hook} bool TARGET_UNWIND_TABLES_DEFAULT +@deftypevr {Common Target Hook} bool TARGET_UNWIND_TABLES_DEFAULT This variable should be set to @code{true} if the target ABI requires unwinding tables even when exceptions are not used. It must not be modified by command-line option processing. diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 667b1ef24bb..3ea77c52e93 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -99,6 +99,16 @@ initializer @code{TARGETCM_INITIALIZER} in themselves, they should set @code{target_has_targetcm=yes} in @file{config.gcc}; otherwise a default definition is used. +Similarly, there is a @code{targetm_common} variable for hooks that +are shared between the compiler driver and the compilers proper, +documented as ``Common Target Hook''. This is declared in +@file{common/common-target.h}, the initializer +@code{TARGETM_COMMON_INITIALIZER} in +@file{common/common-target-def.h}. If targets initialize +@code{targetm_common} themselves, they should set +@code{target_has_targetm_common=yes} in @file{config.gcc}; otherwise a +default definition is used. + @node Driver @section Controlling the Compilation Driver, @file{gcc} @cindex driver @@ -383,6 +393,8 @@ directories from linking commands. Do not give it a nonzero value if removing duplicate search directories changes the linker's semantics. @end defmac +@hook TARGET_ALWAYS_STRIP_DOTDOT + @defmac MULTILIB_DEFAULTS Define this macro as a C expression for the initializer of an array of string to tell the driver program which options are defaults for this diff --git a/gcc/dse.c b/gcc/dse.c index dee4c76d430..3646b0420e3 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see #include "dbgcnt.h" #include "target.h" #include "params.h" +#include "tree-flow.h" /* This file contains three techniques for performing Dead Store Elimination (dse). @@ -326,6 +327,11 @@ struct insn_info contains a wild read, the use_rec will be null. */ bool wild_read; + /* This is true only for CALL instructions which could potentially read + any non-frame memory location. This field is used by the global + algorithm. */ + bool non_frame_wild_read; + /* This field is only used for the processing of const functions. These functions cannot read memory, but they can read the stack because that is where they may get their parms. We need to be @@ -501,6 +507,11 @@ struct group_info deleted. */ bitmap store1_n, store1_p, store2_n, store2_p; + /* These bitmaps keep track of offsets in this group escape this function. + An offset escapes if it corresponds to a named variable whose + addressable flag is set. */ + bitmap escaped_n, escaped_p; + /* The positions in this bitmap have the same assignments as the in, out, gen and kill bitmaps. This bitmap is all zeros except for the positions that are occupied by stores for this group. */ @@ -588,6 +599,9 @@ static int spill_deleted; static bitmap all_blocks; +/* Locations that are killed by calls in the global phase. */ +static bitmap kill_on_calls; + /* The number of bits used in the global bitmaps. */ static unsigned int current_position; @@ -692,6 +706,8 @@ get_group_info (rtx base) gi->store1_p = BITMAP_ALLOC (NULL); gi->store2_n = BITMAP_ALLOC (NULL); gi->store2_p = BITMAP_ALLOC (NULL); + gi->escaped_p = BITMAP_ALLOC (NULL); + gi->escaped_n = BITMAP_ALLOC (NULL); gi->group_kill = BITMAP_ALLOC (NULL); gi->process_globally = false; gi->offset_map_size_n = 0; @@ -714,6 +730,8 @@ get_group_info (rtx base) gi->store1_p = BITMAP_ALLOC (NULL); gi->store2_n = BITMAP_ALLOC (NULL); gi->store2_p = BITMAP_ALLOC (NULL); + gi->escaped_p = BITMAP_ALLOC (NULL); + gi->escaped_n = BITMAP_ALLOC (NULL); gi->group_kill = BITMAP_ALLOC (NULL); gi->process_globally = false; gi->frame_related = @@ -739,6 +757,7 @@ dse_step0 (void) spill_deleted = 0; scratch = BITMAP_ALLOC (NULL); + kill_on_calls = BITMAP_ALLOC (NULL); rtx_store_info_pool = create_alloc_pool ("rtx_store_info_pool", @@ -881,31 +900,48 @@ delete_dead_store_insn (insn_info_t insn_info) insn_info->wild_read = false; } +/* Check if EXPR can possibly escape the current function scope. */ +static bool +can_escape (tree expr) +{ + tree base; + if (!expr) + return true; + base = get_base_address (expr); + if (DECL_P (base) + && !may_be_aliased (base)) + return false; + return true; +} /* Set the store* bitmaps offset_map_size* fields in GROUP based on OFFSET and WIDTH. */ static void -set_usage_bits (group_info_t group, HOST_WIDE_INT offset, HOST_WIDE_INT width) +set_usage_bits (group_info_t group, HOST_WIDE_INT offset, HOST_WIDE_INT width, + tree expr) { HOST_WIDE_INT i; - + bool expr_escapes = can_escape (expr); if (offset > -MAX_OFFSET && offset + width < MAX_OFFSET) for (i=offset; i<offset+width; i++) { bitmap store1; bitmap store2; + bitmap escaped; int ai; if (i < 0) { store1 = group->store1_n; store2 = group->store2_n; + escaped = group->escaped_n; ai = -i; } else { store1 = group->store1_p; store2 = group->store2_p; + escaped = group->escaped_p; ai = i; } @@ -924,18 +960,25 @@ set_usage_bits (group_info_t group, HOST_WIDE_INT offset, HOST_WIDE_INT width) group->offset_map_size_p = ai; } } + if (expr_escapes) + bitmap_set_bit (escaped, ai); } } +static void +reset_active_stores (void) +{ + active_local_stores = NULL; + active_local_stores_len = 0; +} -/* Set the BB_INFO so that the last insn is marked as a wild read. */ +/* Free all READ_REC of the LAST_INSN of BB_INFO. */ static void -add_wild_read (bb_info_t bb_info) +free_read_records (bb_info_t bb_info) { insn_info_t insn_info = bb_info->last_insn; read_info_t *ptr = &insn_info->read_rec; - while (*ptr) { read_info_t next = (*ptr)->next; @@ -943,15 +986,34 @@ add_wild_read (bb_info_t bb_info) { pool_free (read_info_pool, *ptr); *ptr = next; - } + } else - ptr = &(*ptr)->next; + ptr = &(*ptr)->next; } +} + +/* Set the BB_INFO so that the last insn is marked as a wild read. */ + +static void +add_wild_read (bb_info_t bb_info) +{ + insn_info_t insn_info = bb_info->last_insn; insn_info->wild_read = true; - active_local_stores = NULL; - active_local_stores_len = 0; + free_read_records (bb_info); + reset_active_stores (); } +/* Set the BB_INFO so that the last insn is marked as a wild read of + non-frame locations. */ + +static void +add_non_frame_wild_read (bb_info_t bb_info) +{ + insn_info_t insn_info = bb_info->last_insn; + insn_info->non_frame_wild_read = true; + free_read_records (bb_info); + reset_active_stores (); +} /* Return true if X is a constant or one of the registers that behave as a constant over the life of a function. This is equivalent to @@ -1355,9 +1417,10 @@ record_store (rtx body, bb_info_t bb_info) group_info_t group = VEC_index (group_info_t, rtx_group_vec, group_id); + tree expr = MEM_EXPR (mem); store_info = (store_info_t) pool_alloc (rtx_store_info_pool); - set_usage_bits (group, offset, width); + set_usage_bits (group, offset, width, expr); if (dump_file) fprintf (dump_file, " processing const base store gid=%d[%d..%d)\n", @@ -2258,11 +2321,13 @@ check_mem_read_use (rtx *loc, void *data) static bool get_call_args (rtx call_insn, tree fn, rtx *args, int nargs) { - CUMULATIVE_ARGS args_so_far; + CUMULATIVE_ARGS args_so_far_v; + cumulative_args_t args_so_far; tree arg; int idx; - INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (fn), NULL_RTX, 0, 3); + INIT_CUMULATIVE_ARGS (args_so_far_v, TREE_TYPE (fn), NULL_RTX, 0, 3); + args_so_far = pack_cumulative_args (&args_so_far_v); arg = TYPE_ARG_TYPES (TREE_TYPE (fn)); for (idx = 0; @@ -2271,7 +2336,7 @@ get_call_args (rtx call_insn, tree fn, rtx *args, int nargs) { enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg)); rtx reg, link, tmp; - reg = targetm.calls.function_arg (&args_so_far, mode, NULL_TREE, true); + reg = targetm.calls.function_arg (args_so_far, mode, NULL_TREE, true); if (!reg || !REG_P (reg) || GET_MODE (reg) != mode || GET_MODE_CLASS (mode) != MODE_INT) return false; @@ -2305,7 +2370,7 @@ get_call_args (rtx call_insn, tree fn, rtx *args, int nargs) if (tmp) args[idx] = tmp; - targetm.calls.function_arg_advance (&args_so_far, mode, NULL_TREE, true); + targetm.calls.function_arg_advance (args_so_far, mode, NULL_TREE, true); } if (arg != void_list_node || idx != nargs) return false; @@ -2474,8 +2539,9 @@ scan_insn (bb_info_t bb_info, rtx insn) } else - /* Every other call, including pure functions, may read memory. */ - add_wild_read (bb_info); + /* Every other call, including pure functions, may read any memory + that is not relative to the frame. */ + add_non_frame_wild_read (bb_info); return; } @@ -2788,7 +2854,6 @@ dse_step2_nospill (void) /* Position 0 is unused because 0 is used in the maps to mean unused. */ current_position = 1; - FOR_EACH_VEC_ELT (group_info_t, rtx_group_vec, i, group) { bitmap_iterator bi; @@ -2804,12 +2869,16 @@ dse_step2_nospill (void) EXECUTE_IF_SET_IN_BITMAP (group->store2_n, 0, j, bi) { bitmap_set_bit (group->group_kill, current_position); + if (bitmap_bit_p (group->escaped_n, j)) + bitmap_set_bit (kill_on_calls, current_position); group->offset_map_n[j] = current_position++; group->process_globally = true; } EXECUTE_IF_SET_IN_BITMAP (group->store2_p, 0, j, bi) { bitmap_set_bit (group->group_kill, current_position); + if (bitmap_bit_p (group->escaped_p, j)) + bitmap_set_bit (kill_on_calls, current_position); group->offset_map_p[j] = current_position++; group->process_globally = true; } @@ -3040,7 +3109,21 @@ scan_reads_nospill (insn_info_t insn_info, bitmap gen, bitmap kill) bitmap_and_compl_into (gen, group->group_kill); } } - + if (insn_info->non_frame_wild_read) + { + /* Kill all non-frame related stores. Kill all stores of variables that + escape. */ + if (kill) + bitmap_ior_into (kill, kill_on_calls); + bitmap_and_compl_into (gen, kill_on_calls); + FOR_EACH_VEC_ELT (group_info_t, rtx_group_vec, i, group) + if (group->process_globally && !group->frame_related) + { + if (kill) + bitmap_ior_into (kill, group->group_kill); + bitmap_and_compl_into (gen, group->group_kill); + } + } while (read_info) { FOR_EACH_VEC_ELT (group_info_t, rtx_group_vec, i, group) @@ -3564,10 +3647,13 @@ dse_step5_nospill (void) fprintf (dump_file, "wild read\n"); bitmap_clear (v); } - else if (insn_info->read_rec) + else if (insn_info->read_rec + || insn_info->non_frame_wild_read) { - if (dump_file) + if (dump_file && !insn_info->non_frame_wild_read) fprintf (dump_file, "regular read\n"); + else if (dump_file) + fprintf (dump_file, "non-frame wild read\n"); scan_reads_nospill (insn_info, v, NULL); } } @@ -3716,6 +3802,8 @@ dse_step7 (bool global_done) BITMAP_FREE (group->store1_p); BITMAP_FREE (group->store2_n); BITMAP_FREE (group->store2_p); + BITMAP_FREE (group->escaped_n); + BITMAP_FREE (group->escaped_p); BITMAP_FREE (group->group_kill); } @@ -3746,6 +3834,7 @@ dse_step7 (bool global_done) VEC_free (group_info_t, heap, rtx_group_vec); BITMAP_FREE (all_blocks); BITMAP_FREE (scratch); + BITMAP_FREE (kill_on_calls); free_alloc_pool (rtx_store_info_pool); free_alloc_pool (read_info_pool); @@ -3853,7 +3942,6 @@ struct rtl_opt_pass pass_rtl_dse1 = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_df_finish | TODO_verify_rtl_sharing | TODO_ggc_collect /* todo_flags_finish */ } @@ -3874,7 +3962,6 @@ struct rtl_opt_pass pass_rtl_dse2 = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_df_finish | TODO_verify_rtl_sharing | TODO_ggc_collect /* todo_flags_finish */ } diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 776066b275c..71ba002cb85 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -85,6 +85,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pretty-print.h" #include "debug.h" #include "target.h" +#include "common/common-target.h" #include "langhooks.h" #include "hashtab.h" #include "cgraph.h" @@ -154,7 +155,7 @@ dwarf2out_do_frame (void) return true; if ((flag_unwind_tables || flag_exceptions) - && targetm.except_unwind_info (&global_options) == UI_DWARF2) + && targetm_common.except_unwind_info (&global_options) == UI_DWARF2) return true; return false; @@ -190,7 +191,7 @@ dwarf2out_do_cfi_asm (void) dwarf2 unwind info for exceptions, then emit .debug_frame by hand. */ if (!HAVE_GAS_CFI_SECTIONS_DIRECTIVE && !flag_unwind_tables && !flag_exceptions - && targetm.except_unwind_info (&global_options) != UI_DWARF2) + && targetm_common.except_unwind_info (&global_options) != UI_DWARF2) return false; saved_do_cfi_asm = true; @@ -4081,7 +4082,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, call-site information. We must emit this label if it might be used. */ if (!do_frame && (!flag_exceptions - || targetm.except_unwind_info (&global_options) != UI_TARGET)) + || targetm_common.except_unwind_info (&global_options) != UI_TARGET)) return; fnsec = function_section (current_function_decl); @@ -4244,7 +4245,7 @@ dwarf2out_frame_init (void) dwarf2out_def_cfa (NULL, STACK_POINTER_REGNUM, INCOMING_FRAME_SP_OFFSET); if (targetm.debug_unwind_info () == UI_DWARF2 - || targetm.except_unwind_info (&global_options) == UI_DWARF2) + || targetm_common.except_unwind_info (&global_options) == UI_DWARF2) initial_return_save (INCOMING_RETURN_ADDR_RTX); } @@ -4257,7 +4258,7 @@ dwarf2out_frame_finish (void) /* Output another copy for the unwinder. */ if ((flag_unwind_tables || flag_exceptions) - && targetm.except_unwind_info (&global_options) == UI_DWARF2) + && targetm_common.except_unwind_info (&global_options) == UI_DWARF2) output_call_frame_info (1); } @@ -4466,6 +4467,9 @@ typedef struct GTY(()) dw_loc_list_struct { /* True if this list has been replaced by dw_loc_next. */ bool replaced; bool emitted; + /* True if the range should be emitted even if begin and end + are the same. */ + bool force; } dw_loc_list_node; static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT); @@ -6471,6 +6475,7 @@ static GTY(()) VEC(tree,gc) *generic_type_instances; /* Offset from the "steady-state frame pointer" to the frame base, within the current function. */ static HOST_WIDE_INT frame_pointer_fb_offset; +static bool frame_pointer_fb_offset_valid; static VEC (dw_die_ref, heap) *base_types; @@ -8619,7 +8624,30 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label) else temp = (var_loc_list *) *slot; - if (temp->last) + /* For PARM_DECLs try to keep around the original incoming value, + even if that means we'll emit a zero-range .debug_loc entry. */ + if (temp->last + && temp->first == temp->last + && TREE_CODE (decl) == PARM_DECL + && GET_CODE (temp->first->loc) == NOTE + && NOTE_VAR_LOCATION_DECL (temp->first->loc) == decl + && DECL_INCOMING_RTL (decl) + && NOTE_VAR_LOCATION_LOC (temp->first->loc) + && GET_CODE (NOTE_VAR_LOCATION_LOC (temp->first->loc)) + == GET_CODE (DECL_INCOMING_RTL (decl)) + && prev_real_insn (temp->first->loc) == NULL_RTX + && (bitsize != -1 + || !rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->first->loc), + NOTE_VAR_LOCATION_LOC (loc_note)) + || (NOTE_VAR_LOCATION_STATUS (temp->first->loc) + != NOTE_VAR_LOCATION_STATUS (loc_note)))) + { + loc = ggc_alloc_cleared_var_loc_node (); + temp->first->next = loc; + temp->last = loc; + loc->loc = construct_piece_list (loc_note, bitpos, bitsize); + } + else if (temp->last) { struct var_loc_node *last = temp->last, *unused = NULL; rtx *piece_loc = NULL, last_loc_note; @@ -8665,7 +8693,9 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label) } else { - gcc_assert (temp->first == temp->last); + gcc_assert (temp->first == temp->last + || (temp->first->next == temp->last + && TREE_CODE (decl) == PARM_DECL)); memset (temp->last, '\0', sizeof (*temp->last)); temp->last->loc = construct_piece_list (loc_note, bitpos, bitsize); return temp->last; @@ -11392,7 +11422,7 @@ output_loc_list (dw_loc_list_ref list_head) { unsigned long size; /* Don't output an entry that starts and ends at the same address. */ - if (strcmp (curr->begin, curr->end) == 0) + if (strcmp (curr->begin, curr->end) == 0 && !curr->force) continue; if (!have_multiple_function_sections) { @@ -13613,6 +13643,7 @@ based_loc_descr (rtx reg, HOST_WIDE_INT offset, return new_reg_loc_descr (base_reg, offset); } + gcc_assert (frame_pointer_fb_offset_valid); offset += frame_pointer_fb_offset; return new_loc_descr (DW_OP_fbreg, offset, 0); } @@ -16087,6 +16118,11 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address) } *listp = new_loc_list (descr, node->label, endname, secname); + if (TREE_CODE (decl) == PARM_DECL + && node == loc_list->first + && GET_CODE (node->loc) == NOTE + && strcmp (node->label, endname) == 0) + (*listp)->force = true; listp = &(*listp)->dw_loc_next; if (range_across_switch) @@ -18336,14 +18372,20 @@ compute_frame_pointer_to_fb_displacement (HOST_WIDE_INT offset) elim = XEXP (elim, 0); } - gcc_assert ((SUPPORTS_STACK_ALIGNMENT - && (elim == hard_frame_pointer_rtx - || elim == stack_pointer_rtx)) - || elim == (frame_pointer_needed - ? hard_frame_pointer_rtx - : stack_pointer_rtx)); - frame_pointer_fb_offset = -offset; + + /* ??? AVR doesn't set up valid eliminations when there is no stack frame + in which to eliminate. This is because it's stack pointer isn't + directly accessible as a register within the ISA. To work around + this, assume that while we cannot provide a proper value for + frame_pointer_fb_offset, we won't need one either. */ + frame_pointer_fb_offset_valid + = ((SUPPORTS_STACK_ALIGNMENT + && (elim == hard_frame_pointer_rtx + || elim == stack_pointer_rtx)) + || elim == (frame_pointer_needed + ? hard_frame_pointer_rtx + : stack_pointer_rtx)); } /* Generate a DW_AT_name attribute given some string value to be included as @@ -23530,7 +23572,7 @@ dwarf2out_assembly_start (void) if (HAVE_GAS_CFI_SECTIONS_DIRECTIVE && dwarf2out_do_cfi_asm () && (!(flag_unwind_tables || flag_exceptions) - || targetm.except_unwind_info (&global_options) != UI_DWARF2)) + || targetm_common.except_unwind_info (&global_options) != UI_DWARF2)) fprintf (asm_out_file, "\t.cfi_sections\t.debug_frame\n"); } diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index f760a1bdc14..f010ac6f5ab 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -2413,7 +2413,7 @@ struct rtl_opt_pass pass_unshare_all_rtl = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_rtl_sharing /* todo_flags_finish */ + TODO_verify_rtl_sharing /* todo_flags_finish */ } }; diff --git a/gcc/except.c b/gcc/except.c index 1e5c291055f..bb16036d361 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -1,6 +1,6 @@ /* Implements exception handling. Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Contributed by Mike Stump <mrs@cygnus.com>. @@ -136,6 +136,7 @@ along with GCC; see the file COPYING3. If not see #include "ggc.h" #include "tm_p.h" #include "target.h" +#include "common/common-target.h" #include "langhooks.h" #include "cgraph.h" #include "diagnostic.h" @@ -209,7 +210,7 @@ init_eh (void) /* Create the SjLj_Function_Context structure. This should match the definition in unwind-sjlj.c. */ - if (targetm.except_unwind_info (&global_options) == UI_SJLJ) + if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) { tree f_jbuf, f_per, f_lsda, f_prev, f_cs, f_data, tmp; @@ -1395,13 +1396,13 @@ finish_eh_generation (void) basic_block bb; /* Construct the landing pads. */ - if (targetm.except_unwind_info (&global_options) == UI_SJLJ) + if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) sjlj_build_landing_pads (); else dw2_build_landing_pads (); break_superblocks (); - if (targetm.except_unwind_info (&global_options) == UI_SJLJ + if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ /* Kludge for Alpha/Tru64 (see alpha_gp_save_rtx). */ || single_succ_edge (ENTRY_BLOCK_PTR)->insns.r) commit_edge_insertions (); @@ -1468,7 +1469,7 @@ struct rtl_opt_pass pass_rtl_eh = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -1910,7 +1911,7 @@ struct rtl_opt_pass pass_set_nothrow_function_flags = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -2645,7 +2646,7 @@ gate_convert_to_eh_region_ranges (void) /* Nothing to do for SJLJ exceptions or if no regions created. */ if (cfun->eh->region_tree == NULL) return false; - if (targetm.except_unwind_info (&global_options) == UI_SJLJ) + if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) return false; return true; } @@ -2665,7 +2666,7 @@ struct rtl_opt_pass pass_convert_to_eh_region_ranges = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -2834,7 +2835,7 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname)) { /* Compute the section and cache it into exception_section, unless it depends on the function name. */ - if (targetm.have_named_sections) + if (targetm_common.have_named_sections) { int flags; @@ -2984,7 +2985,7 @@ output_one_function_exception_table (int section) eh_data_format_name (tt_format)); #ifndef HAVE_AS_LEB128 - if (targetm.except_unwind_info (&global_options) == UI_SJLJ) + if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) call_site_len = sjlj_size_of_call_site_table (); else call_site_len = dw2_size_of_call_site_table (section); @@ -3051,14 +3052,14 @@ output_one_function_exception_table (int section) dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label, "Call-site table length"); ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label); - if (targetm.except_unwind_info (&global_options) == UI_SJLJ) + if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) sjlj_output_call_site_table (); else dw2_output_call_site_table (cs_format, section); ASM_OUTPUT_LABEL (asm_out_file, cs_end_label); #else dw2_asm_output_data_uleb128 (call_site_len, "Call-site table length"); - if (targetm.except_unwind_info (&global_options) == UI_SJLJ) + if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) sjlj_output_call_site_table (); else dw2_output_call_site_table (cs_format, section); diff --git a/gcc/explow.c b/gcc/explow.c index 7387dad98df..c7d81838033 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "recog.h" #include "langhooks.h" #include "target.h" +#include "common/common-target.h" #include "output.h" static rtx break_out_memory_refs (rtx); diff --git a/gcc/expr.c b/gcc/expr.c index 971432c19af..bb6e3f14a8a 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "tree-flow.h" #include "target.h" +#include "common/common-target.h" #include "timevar.h" #include "df.h" #include "diagnostic.h" @@ -1227,23 +1228,25 @@ block_move_libcall_safe_for_call_parm (void) /* If any argument goes in memory, then it might clobber an outgoing argument. */ { - CUMULATIVE_ARGS args_so_far; + CUMULATIVE_ARGS args_so_far_v; + cumulative_args_t args_so_far; tree fn, arg; fn = emit_block_move_libcall_fn (false); - INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (fn), NULL_RTX, 0, 3); + INIT_CUMULATIVE_ARGS (args_so_far_v, TREE_TYPE (fn), NULL_RTX, 0, 3); + args_so_far = pack_cumulative_args (&args_so_far_v); arg = TYPE_ARG_TYPES (TREE_TYPE (fn)); for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg)) { enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg)); - rtx tmp = targetm.calls.function_arg (&args_so_far, mode, + rtx tmp = targetm.calls.function_arg (args_so_far, mode, NULL_TREE, true); if (!tmp || !REG_P (tmp)) return false; - if (targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL, 1)) + if (targetm.calls.arg_partial_bytes (args_so_far, mode, NULL, 1)) return false; - targetm.calls.function_arg_advance (&args_so_far, mode, + targetm.calls.function_arg_advance (args_so_far, mode, NULL_TREE, true); } } @@ -7264,7 +7267,7 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, /* An operation in what may be a bit-field type needs the result to be reduced to the precision of the bit-field type, which is narrower than that of the type's mode. */ - reduce_bit_field = (TREE_CODE (type) == INTEGER_TYPE + reduce_bit_field = (INTEGRAL_TYPE_P (type) && GET_MODE_PRECISION (mode) > TYPE_PRECISION (type)); if (reduce_bit_field && modifier == EXPAND_STACK_PARM) @@ -8333,7 +8336,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, result to be reduced to the precision of the bit-field type, which is narrower than that of the type's mode. */ reduce_bit_field = (!ignore - && TREE_CODE (type) == INTEGER_TYPE + && INTEGRAL_TYPE_P (type) && GET_MODE_PRECISION (mode) > TYPE_PRECISION (type)); /* If we are going to ignore this result, we need only do something @@ -10298,7 +10301,7 @@ build_personality_function (const char *lang) tree decl, type; char *name; - switch (targetm.except_unwind_info (&global_options)) + switch (targetm_common.except_unwind_info (&global_options)) { case UI_NONE: return NULL; diff --git a/gcc/final.c b/gcc/final.c index 748042abf10..cb4a83d08ee 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -837,7 +837,7 @@ struct rtl_opt_pass pass_compute_alignments = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_rtl_sharing + TODO_verify_rtl_sharing | TODO_ggc_collect /* todo_flags_finish */ } }; @@ -4337,7 +4337,7 @@ struct rtl_opt_pass pass_shorten_branches = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; diff --git a/gcc/fold-const.c b/gcc/fold-const.c index e1a497eda96..e48aae9f4ce 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -10866,13 +10866,19 @@ fold_binary_loc (location_t loc, if (operand_equal_p (arg0, arg1, 0)) return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0)); - /* ~X & X is always zero. */ - if (TREE_CODE (arg0) == BIT_NOT_EXPR + /* ~X & X, (X == 0) & X, and !X & X are always zero. */ + if ((TREE_CODE (arg0) == BIT_NOT_EXPR + || TREE_CODE (arg0) == TRUTH_NOT_EXPR + || (TREE_CODE (arg0) == EQ_EXPR + && integer_zerop (TREE_OPERAND (arg0, 1)))) && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)) return omit_one_operand_loc (loc, type, integer_zero_node, arg1); - /* X & ~X is always zero. */ - if (TREE_CODE (arg1) == BIT_NOT_EXPR + /* X & ~X , X & (X == 0), and X & !X are always zero. */ + if ((TREE_CODE (arg1) == BIT_NOT_EXPR + || TREE_CODE (arg1) == TRUTH_NOT_EXPR + || (TREE_CODE (arg1) == EQ_EXPR + && integer_zerop (TREE_OPERAND (arg1, 1)))) && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)) return omit_one_operand_loc (loc, type, integer_zero_node, arg0); @@ -10933,6 +10939,14 @@ fold_binary_loc (location_t loc, build_int_cst (TREE_TYPE (tem), 1)), build_int_cst (TREE_TYPE (tem), 0)); } + /* Fold !X & 1 as X == 0. */ + if (TREE_CODE (arg0) == TRUTH_NOT_EXPR + && integer_onep (arg1)) + { + tem = TREE_OPERAND (arg0, 0); + return fold_build2_loc (loc, EQ_EXPR, type, tem, + build_int_cst (TREE_TYPE (tem), 0)); + } /* Fold (X ^ Y) & Y as ~X & Y. */ if (TREE_CODE (arg0) == BIT_XOR_EXPR @@ -12357,14 +12371,6 @@ fold_binary_loc (location_t loc, } } - /* If this is an NE comparison of zero with an AND of one, remove the - comparison since the AND will give the correct value. */ - if (code == NE_EXPR - && integer_zerop (arg1) - && TREE_CODE (arg0) == BIT_AND_EXPR - && integer_onep (TREE_OPERAND (arg0, 1))) - return fold_convert_loc (loc, type, arg0); - /* If we have (A & C) == C where C is a power of 2, convert this into (A & C) != 0. Similarly for NE_EXPR. */ if (TREE_CODE (arg0) == BIT_AND_EXPR diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index dbfaa7cd5dd..08c666ac4a6 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,50 @@ +2011-06-18 Janus Weil <janus@gcc.gnu.org> + + PR fortran/49400 + * decl.c (gfc_match_procedure): Allow PROCEDURE declarations inside + BLOCK constructs. + +2011-06-17 Janus Weil <janus@gcc.gnu.org> + + PR fortran/48699 + * check.c (gfc_check_move_alloc): If 'TO' argument is polymorphic, + make sure the vtab is present. + +2011-06-16 Janus Weil <janus@gcc.gnu.org> + + PR fortran/49074 + * interface.c (gfc_extend_assign): Propagate the locus from the + assignment to the type-bound procedure call. + +2011-06-16 Janus Weil <janus@gcc.gnu.org> + + PR fortran/49417 + * module.c (mio_component): Make sure the 'class_ok' attribute is set + for use-associated CLASS components. + * parse.c (parse_derived): Check for 'class_ok' attribute. + * resolve.c (resolve_fl_derived): Ditto. + +2011-06-13 Thomas Koenig <tkoenig@gcc.gnu.org> + + * frontend-passes.c (remove_trim): New function. + (optimize_assignment): Use it. + (optimize_comparison): Likewise. Return correct status + for previous change. + +2011-06-12 Tobias Burnus + + PR fortran/49324 + * trans-expr.c (gfc_trans_assignment_1): Tell + gfc_trans_scalar_assign to also deep-copy RHS nonvariables + with allocatable components. + * trans-array.c (gfc_conv_expr_descriptor): Ditto. + +2011-05-11 Thomas Koenig <tkoenig@gcc.gnu.org> + + * frontend-passes.c (optimize_assignment): Follow chains + of concatenation operators to the end for removing trailing + TRIMS for assignments. + 2011-06-10 Daniel Carrera <dcarrera@gmail.com> * trans-decl.c (gfc_build_builtin_function_decls): diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index 11789673115..972b290c987 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -2672,6 +2672,10 @@ gfc_check_move_alloc (gfc_expr *from, gfc_expr *to) return FAILURE; } + /* CLASS arguments: Make sure the vtab is present. */ + if (to->ts.type == BT_CLASS) + gfc_find_derived_vtab (from->ts.u.derived); + return SUCCESS; } diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 7098368e56e..661bb14486f 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -4970,6 +4970,7 @@ gfc_match_procedure (void) case COMP_MODULE: case COMP_SUBROUTINE: case COMP_FUNCTION: + case COMP_BLOCK: m = match_procedure_decl (); break; case COMP_INTERFACE: diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index f100e1fb811..4d8c77a1269 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -486,6 +486,35 @@ optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op) return false; } +/* Remove unneeded TRIMs at the end of expressions. */ + +static bool +remove_trim (gfc_expr *rhs) +{ + bool ret; + + ret = false; + + /* Check for a // b // trim(c). Looping is probably not + necessary because the parser usually generates + (// (// a b ) trim(c) ) , but better safe than sorry. */ + + while (rhs->expr_type == EXPR_OP + && rhs->value.op.op == INTRINSIC_CONCAT) + rhs = rhs->value.op.op2; + + while (rhs->expr_type == EXPR_FUNCTION && rhs->value.function.isym + && rhs->value.function.isym->id == GFC_ISYM_TRIM) + { + strip_function_call (rhs); + /* Recursive call to catch silly stuff like trim ( a // trim(b)). */ + remove_trim (rhs); + ret = true; + } + + return ret; +} + /* Optimizations for an assignment. */ static void @@ -499,16 +528,7 @@ optimize_assignment (gfc_code * c) /* Optimize away a = trim(b), where a is a character variable. */ if (lhs->ts.type == BT_CHARACTER) - { - if (rhs->expr_type == EXPR_FUNCTION && - rhs->value.function.isym && - rhs->value.function.isym->id == GFC_ISYM_TRIM) - { - strip_function_call (rhs); - optimize_assignment (c); - return; - } - } + remove_trim (rhs); if (lhs->rank > 0 && gfc_check_dependency (lhs, rhs, true) == 0) optimize_binop_array_assignment (c, &rhs, false); @@ -631,36 +651,17 @@ optimize_comparison (gfc_expr *e, gfc_intrinsic_op op) /* Strip off unneeded TRIM calls from string comparisons. */ - change = false; + change = remove_trim (op1); - if (op1->expr_type == EXPR_FUNCTION - && op1->value.function.isym - && op1->value.function.isym->id == GFC_ISYM_TRIM) - { - strip_function_call (op1); - change = true; - } - - if (op2->expr_type == EXPR_FUNCTION - && op2->value.function.isym - && op2->value.function.isym->id == GFC_ISYM_TRIM) - { - strip_function_call (op2); - change = true; - } - - if (change) - { - optimize_comparison (e, op); - return true; - } + if (remove_trim (op2)) + change = true; /* An expression of type EXPR_CONSTANT is only valid for scalars. */ /* TODO: A scalar constant may be acceptable in some cases (the scalarizer handles them well). However, there are also cases that need a non-scalar argument. For example the any intrinsic. See PR 45380. */ if (e->rank > 0) - return false; + return change; /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */ @@ -690,7 +691,7 @@ optimize_comparison (gfc_expr *e, gfc_intrinsic_op op) && op2_left->expr_type == EXPR_CONSTANT && op1_left->value.character.length != op2_left->value.character.length) - return false; + return change; else { free (op1_left); @@ -779,7 +780,7 @@ optimize_comparison (gfc_expr *e, gfc_intrinsic_op op) } } - return false; + return change; } /* Optimize a trim function by replacing it with an equivalent substring diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index 46f9d146ce7..e787187ba80 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -3242,6 +3242,7 @@ gfc_extend_assign (gfc_code *c, gfc_namespace *ns) c->expr1 = gfc_get_expr (); build_compcall_for_operator (c->expr1, actual, tb_base, tbo, gname); c->expr1->value.compcall.assign = 1; + c->expr1->where = c->loc; c->expr2 = NULL; c->op = EXEC_COMPCALL; diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c index 533246d0c8d..89281a5c17c 100644 --- a/gcc/fortran/module.c +++ b/gcc/fortran/module.c @@ -2403,6 +2403,8 @@ mio_component (gfc_component *c, int vtype) mio_array_spec (&c->as); mio_symbol_attribute (&c->attr); + if (c->ts.type == BT_CLASS) + c->attr.class_ok = 1; c->attr.access = MIO_NAME (gfc_access) (c->attr.access, access_types); if (!vtype) diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index 6013931d355..5ce5c1e042a 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -2120,13 +2120,15 @@ endType: { /* Look for allocatable components. */ if (c->attr.allocatable - || (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.allocatable) + || (c->ts.type == BT_CLASS && c->attr.class_ok + && CLASS_DATA (c)->attr.allocatable) || (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.alloc_comp)) sym->attr.alloc_comp = 1; /* Look for pointer components. */ if (c->attr.pointer - || (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.class_pointer) + || (c->ts.type == BT_CLASS && c->attr.class_ok + && CLASS_DATA (c)->attr.class_pointer) || (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.pointer_comp)) sym->attr.pointer_comp = 1; diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index b2c31892eb4..cec45cab44d 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -11789,7 +11789,8 @@ resolve_fl_derived (gfc_symbol *sym) return FAILURE; } - if (c->ts.type == BT_CLASS && CLASS_DATA (c)->attr.class_pointer + if (c->ts.type == BT_CLASS && c->attr.class_ok + && CLASS_DATA (c)->attr.class_pointer && CLASS_DATA (c)->ts.u.derived->components == NULL && !CLASS_DATA (c)->ts.u.derived->attr.zero_comp) { @@ -11800,9 +11801,10 @@ resolve_fl_derived (gfc_symbol *sym) } /* C437. */ - if (c->ts.type == BT_CLASS - && !(CLASS_DATA (c)->attr.class_pointer - || CLASS_DATA (c)->attr.allocatable)) + if (c->ts.type == BT_CLASS && c->attr.flavor != FL_PROCEDURE + && (!c->attr.class_ok + || !(CLASS_DATA (c)->attr.class_pointer + || CLASS_DATA (c)->attr.allocatable))) { gfc_error ("Component '%s' with CLASS at %L must be allocatable " "or pointer", c->name, &c->loc); diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index c7aeadb3c8b..baf9060fe6b 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -5808,7 +5808,8 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss) lse.string_length = rse.string_length; tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, - expr->expr_type == EXPR_VARIABLE, true); + expr->expr_type == EXPR_VARIABLE + || expr->expr_type == EXPR_ARRAY, true); gfc_add_expr_to_block (&block, tmp); /* Finish the copying loops. */ diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index da4af1ae28d..73832657838 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -6155,8 +6155,8 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag, tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, l_is_temp || init_flag, - expr_is_variable (expr2) || scalar_to_array, - dealloc); + expr_is_variable (expr2) || scalar_to_array + || expr2->expr_type == EXPR_ARRAY, dealloc); gfc_add_expr_to_block (&body, tmp); if (lss == gfc_ss_terminator) diff --git a/gcc/function.c b/gcc/function.c index 30cc9ff2b4f..5be018afde7 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -57,6 +57,7 @@ along with GCC; see the file COPYING3. If not see #include "integrate.h" #include "langhooks.h" #include "target.h" +#include "common/common-target.h" #include "cfglayout.h" #include "gimple.h" #include "tree-pass.h" @@ -1955,7 +1956,7 @@ struct rtl_opt_pass pass_instantiate_virtual_regs = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -2127,7 +2128,8 @@ pass_by_reference (CUMULATIVE_ARGS *ca, enum machine_mode mode, } } - return targetm.calls.pass_by_reference (ca, mode, type, named_arg); + return targetm.calls.pass_by_reference (pack_cumulative_args (ca), mode, + type, named_arg); } /* Return true if TYPE, which is passed by reference, should be callee @@ -2139,7 +2141,8 @@ reference_callee_copied (CUMULATIVE_ARGS *ca, enum machine_mode mode, { if (type && TREE_ADDRESSABLE (type)) return false; - return targetm.calls.callee_copies (ca, mode, type, named_arg); + return targetm.calls.callee_copies (pack_cumulative_args (ca), mode, type, + named_arg); } /* Structures to communicate between the subroutines of assign_parms. @@ -2148,7 +2151,10 @@ reference_callee_copied (CUMULATIVE_ARGS *ca, enum machine_mode mode, struct assign_parm_data_all { - CUMULATIVE_ARGS args_so_far; + /* When INIT_CUMULATIVE_ARGS gets revamped, allocating CUMULATIVE_ARGS + should become a job of the target or otherwise encapsulated. */ + CUMULATIVE_ARGS args_so_far_v; + cumulative_args_t args_so_far; struct args_size stack_args_size; tree function_result_decl; tree orig_fnargs; @@ -2188,11 +2194,12 @@ assign_parms_initialize_all (struct assign_parm_data_all *all) fntype = TREE_TYPE (current_function_decl); #ifdef INIT_CUMULATIVE_INCOMING_ARGS - INIT_CUMULATIVE_INCOMING_ARGS (all->args_so_far, fntype, NULL_RTX); + INIT_CUMULATIVE_INCOMING_ARGS (all->args_so_far_v, fntype, NULL_RTX); #else - INIT_CUMULATIVE_ARGS (all->args_so_far, fntype, NULL_RTX, + INIT_CUMULATIVE_ARGS (all->args_so_far_v, fntype, NULL_RTX, current_function_decl, -1); #endif + all->args_so_far = pack_cumulative_args (&all->args_so_far_v); #ifdef REG_PARM_STACK_SPACE all->reg_parm_stack_space = REG_PARM_STACK_SPACE (current_function_decl); @@ -2313,7 +2320,7 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm, data->named_arg = 1; /* No variadic parms. */ else if (DECL_CHAIN (parm)) data->named_arg = 1; /* Not the last non-variadic parm. */ - else if (targetm.calls.strict_argument_naming (&all->args_so_far)) + else if (targetm.calls.strict_argument_naming (all->args_so_far)) data->named_arg = 1; /* Only variadic ones are unnamed. */ else data->named_arg = 0; /* Treat as variadic. */ @@ -2349,7 +2356,7 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm, passed_type = TREE_TYPE (first_field (passed_type)); /* See if this arg was passed by invisible reference. */ - if (pass_by_reference (&all->args_so_far, passed_mode, + if (pass_by_reference (&all->args_so_far_v, passed_mode, passed_type, data->named_arg)) { passed_type = nominal_type = build_pointer_type (passed_type); @@ -2378,7 +2385,7 @@ assign_parms_setup_varargs (struct assign_parm_data_all *all, { int varargs_pretend_bytes = 0; - targetm.calls.setup_incoming_varargs (&all->args_so_far, + targetm.calls.setup_incoming_varargs (all->args_so_far, data->promoted_mode, data->passed_type, &varargs_pretend_bytes, no_rtl); @@ -2407,7 +2414,7 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all, return; } - entry_parm = targetm.calls.function_incoming_arg (&all->args_so_far, + entry_parm = targetm.calls.function_incoming_arg (all->args_so_far, data->promoted_mode, data->passed_type, data->named_arg); @@ -2431,10 +2438,10 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all, #endif if (!in_regs && !data->named_arg) { - if (targetm.calls.pretend_outgoing_varargs_named (&all->args_so_far)) + if (targetm.calls.pretend_outgoing_varargs_named (all->args_so_far)) { rtx tem; - tem = targetm.calls.function_incoming_arg (&all->args_so_far, + tem = targetm.calls.function_incoming_arg (all->args_so_far, data->promoted_mode, data->passed_type, true); in_regs = tem != NULL; @@ -2451,7 +2458,7 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all, { int partial; - partial = targetm.calls.arg_partial_bytes (&all->args_so_far, + partial = targetm.calls.arg_partial_bytes (all->args_so_far, data->promoted_mode, data->passed_type, data->named_arg); @@ -3387,7 +3394,7 @@ assign_parms (tree fndecl) set_decl_incoming_rtl (parm, data.entry_parm, false); /* Update info on where next arg arrives in registers. */ - targetm.calls.function_arg_advance (&all.args_so_far, data.promoted_mode, + targetm.calls.function_arg_advance (all.args_so_far, data.promoted_mode, data.passed_type, data.named_arg); assign_parm_adjust_stack_rtl (&data); @@ -3497,7 +3504,7 @@ assign_parms (tree fndecl) /* For stdarg.h function, save info about regs and stack space used by the named args. */ - crtl->args.info = all.args_so_far; + crtl->args.info = all.args_so_far_v; /* Set the rtx used for the function return value. Put this in its own variable so any optimizers that need this information don't have @@ -3586,7 +3593,7 @@ gimplify_parameters (void) continue; /* Update info on where next arg arrives in registers. */ - targetm.calls.function_arg_advance (&all.args_so_far, data.promoted_mode, + targetm.calls.function_arg_advance (all.args_so_far, data.promoted_mode, data.passed_type, data.named_arg); /* ??? Once upon a time variable_size stuffed parameter list @@ -3605,7 +3612,7 @@ gimplify_parameters (void) if (data.passed_pointer) { tree type = TREE_TYPE (data.passed_type); - if (reference_callee_copied (&all.args_so_far, TYPE_MODE (type), + if (reference_callee_copied (&all.args_so_far_v, TYPE_MODE (type), type, data.named_arg)) { tree local, t; @@ -4968,7 +4975,7 @@ expand_function_end (void) /* Output the label for the actual return from the function. */ emit_label (return_label); - if (targetm.except_unwind_info (&global_options) == UI_SJLJ) + if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) { /* Let except.c know where it should emit the call to unregister the function context for sjlj exceptions. */ @@ -5127,7 +5134,7 @@ expand_function_end (void) may trap are not moved into the epilogue by scheduling, because we don't always emit unwind information for the epilogue. */ if (cfun->can_throw_non_call_exceptions - && targetm.except_unwind_info (&global_options) != UI_SJLJ) + && targetm_common.except_unwind_info (&global_options) != UI_SJLJ) emit_insn (gen_blockage ()); /* If stack protection is enabled for this function, check the guard. */ @@ -5949,7 +5956,6 @@ struct rtl_opt_pass pass_thread_prologue_and_epilogue = 0, /* properties_provided */ 0, /* properties_destroyed */ TODO_verify_flow, /* todo_flags_start */ - TODO_dump_func | TODO_df_verify | TODO_df_finish | TODO_verify_rtl_sharing | TODO_ggc_collect /* todo_flags_finish */ @@ -6151,7 +6157,7 @@ struct rtl_opt_pass pass_match_asm_constraints = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; diff --git a/gcc/fwprop.c b/gcc/fwprop.c index b2fd9556bbb..444a539cf79 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -1473,8 +1473,7 @@ struct rtl_opt_pass pass_rtl_fwprop = 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_flow - | TODO_verify_rtl_sharing - | TODO_dump_func /* todo_flags_finish */ + | TODO_verify_rtl_sharing /* todo_flags_finish */ } }; @@ -1521,7 +1520,6 @@ struct rtl_opt_pass pass_rtl_fwprop_addr = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func /* todo_flags_finish */ + TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */ } }; diff --git a/gcc/gcse.c b/gcc/gcse.c index 41fff7ab86b..c371f827d22 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -3772,7 +3772,6 @@ struct rtl_opt_pass pass_rtl_pre = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_verify_flow | TODO_ggc_collect /* todo_flags_finish */ } }; @@ -3793,10 +3792,8 @@ struct rtl_opt_pass pass_rtl_hoist = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_verify_flow | TODO_ggc_collect /* todo_flags_finish */ } }; #include "gt-gcse.h" - diff --git a/gcc/genhooks.c b/gcc/genhooks.c index d70c4fe8b89..789744ce228 100644 --- a/gcc/genhooks.c +++ b/gcc/genhooks.c @@ -34,6 +34,7 @@ static struct hook_desc hook_array[] = { { "*", #TYPE, HOOK_PREFIX #NAME, #PARAMS, #INIT, HOOK_TYPE }, #include "target.def" #include "c-family/c-target.def" +#include "common/common-target.def" #undef DEFHOOK }; diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index 3afa0b2582d..5c05f842c4c 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -203,7 +203,7 @@ struct gimple_opt_pass pass_lower_cf = PROP_gimple_lcf, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; diff --git a/gcc/gimple.c b/gcc/gimple.c index 6a9b58d6023..fd9757908f0 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -3139,16 +3139,8 @@ canonicalize_cond_expr_cond (tree t) && truth_value_p (TREE_CODE (TREE_OPERAND (t, 0)))) t = TREE_OPERAND (t, 0); - /* For (bool)x use x != 0. */ - if (CONVERT_EXPR_P (t) - && TREE_CODE (TREE_TYPE (t)) == BOOLEAN_TYPE) - { - tree top0 = TREE_OPERAND (t, 0); - t = build2 (NE_EXPR, TREE_TYPE (t), - top0, build_int_cst (TREE_TYPE (top0), 0)); - } /* For !x use x == 0. */ - else if (TREE_CODE (t) == TRUTH_NOT_EXPR) + if (TREE_CODE (t) == TRUTH_NOT_EXPR) { tree top0 = TREE_OPERAND (t, 0); t = build2 (EQ_EXPR, TREE_TYPE (t), diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 11abbbcd421..20385d1ea8e 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,17 @@ +2011-06-14 Joseph Myers <joseph@codesourcery.com> + + * Make-lang.in (go/go-lang.o, go/go-backend.o): Update + dependencies. + * go-backend.c: Include common/common-target.h. + (go_write_export_data): Use targetm_common.have_named_sections. + * go-lang.c: Include common/common-target.h. + (go_langhook_init_options_struct): Use + targetm_common.supports_split_stack. + +2011-06-13 Ian Lance Taylor <iant@google.com> + + * Make-lang.in (go/expressions.o): Depend on $(GO_RUNTIME_H). + 2011-06-10 Ian Lance Taylor <iant@google.com> * go-gcc.cc: Include "toplev.h". diff --git a/gcc/go/Make-lang.in b/gcc/go/Make-lang.in index 61a0f3c875a..26c16194d7f 100644 --- a/gcc/go/Make-lang.in +++ b/gcc/go/Make-lang.in @@ -224,13 +224,14 @@ GO_IMPORT_H = go/gofrontend/import.h go/gofrontend/export.h GO_RUNTIME_H = go/gofrontend/runtime.h go/gofrontend/runtime.def go/go-backend.o: go/go-backend.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(RTL_H) $(TREE_H) $(TM_P_H) output.h $(TARGET_H) + $(TM_H) $(RTL_H) $(TREE_H) $(TM_P_H) output.h $(TARGET_H) \ + $(COMMON_TARGET_H) go/go-lang.o: go/go-lang.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(OPTS_H) \ $(TREE_H) $(GIMPLE_H) $(GGC_H) $(TOPLEV_H) debug.h options.h \ $(FLAGS_H) convert.h $(DIAGNOSTIC_H) langhooks.h \ $(LANGHOOKS_DEF_H) $(EXCEPT_H) $(TARGET_H) $(GO_C_H) \ - gt-go-go-lang.h gtype-go.h + gt-go-go-lang.h gtype-go.h $(COMMON_TARGET_H) $(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ -DDEFAULT_TARGET_VERSION=\"$(version)\" \ -DDEFAULT_TARGET_MACHINE=\"$(target_noncanonical)\" \ @@ -255,7 +256,7 @@ go/expressions.o: go/gofrontend/expressions.cc $(GO_SYSTEM_H) $(TOPLEV_H) \ intl.h $(TREE_H) $(GIMPLE_H) tree-iterator.h convert.h $(REAL_H) \ realmpfr.h $(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) \ go/gofrontend/export.h $(GO_IMPORT_H) $(GO_STATEMENTS_H) $(GO_LEX_H) \ - go/gofrontend/backend.h $(GO_EXPRESSIONS_H) + $(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_EXPRESSIONS_H) go/go.o: go/gofrontend/go.cc $(GO_SYSTEM_H) $(GO_C_H) $(GO_LEX_H) \ $(GO_PARSE_H) go/gofrontend/backend.h $(GO_GOGO_H) go/go-dump.o: go/gofrontend/go-dump.cc $(GO_SYSTEM_H) $(GO_C_H) \ diff --git a/gcc/go/go-backend.c b/gcc/go/go-backend.c index 60a97db7df4..62102a2e08b 100644 --- a/gcc/go/go-backend.c +++ b/gcc/go/go-backend.c @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "output.h" #include "target.h" +#include "common/common-target.h" #include "go-c.h" @@ -103,7 +104,7 @@ go_write_export_data (const char *bytes, unsigned int size) if (sec == NULL) { - gcc_assert (targetm.have_named_sections); + gcc_assert (targetm_common.have_named_sections); sec = get_section (".go_export", SECTION_DEBUG, NULL); } diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c index 4687c6e19ba..576e35f7551 100644 --- a/gcc/go/go-lang.c +++ b/gcc/go/go-lang.c @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks-def.h" #include "except.h" #include "target.h" +#include "common/common-target.h" #include <mpfr.h> @@ -143,7 +144,7 @@ go_langhook_init_options_struct (struct gcc_options *opts) opts->frontend_set_flag_errno_math = true; /* We turn on stack splitting if we can. */ - if (targetm.supports_split_stack (false, opts)) + if (targetm_common.supports_split_stack (false, opts)) opts->x_flag_split_stack = 1; /* Exceptions are used to handle recovering from panics. */ diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 00af2962068..bd437c4ce4c 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -33,6 +33,7 @@ extern "C" #include "import.h" #include "statements.h" #include "lex.h" +#include "runtime.h" #include "backend.h" #include "expressions.h" @@ -3592,7 +3593,7 @@ class Unsafe_type_conversion_expression : public Expression void do_determine_type(const Type_context*) - { } + { this->expr_->determine_type_no_context(); } Expression* do_copy() @@ -6739,6 +6740,12 @@ class Builtin_call_expression : public Call_expression static Type* complex_type(Type*); + Expression* + lower_make(); + + bool + check_int_value(Expression*); + // A pointer back to the general IR structure. This avoids a global // variable, or passing it around everywhere. Gogo* gogo_; @@ -6859,6 +6866,9 @@ Find_call_expression::expression(Expression** pexpr) Expression* Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function, int) { + if (this->classification() == EXPRESSION_ERROR) + return this; + if (this->is_varargs() && this->code_ != BUILTIN_APPEND) { this->report_error(_("invalid use of %<...%> with builtin function")); @@ -6885,36 +6895,7 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function, int) } } else if (this->code_ == BUILTIN_MAKE) - { - const Expression_list* args = this->args(); - if (args == NULL || args->size() < 1) - this->report_error(_("not enough arguments")); - else - { - Expression* arg = args->front(); - if (!arg->is_type_expression()) - { - error_at(arg->location(), "expected type"); - this->set_is_error(); - } - else - { - Expression_list* newargs; - if (args->size() == 1) - newargs = NULL; - else - { - newargs = new Expression_list(); - Expression_list::const_iterator p = args->begin(); - ++p; - for (; p != args->end(); ++p) - newargs->push_back(*p); - } - return Expression::make_make(arg->type(), newargs, - this->location()); - } - } - } + return this->lower_make(); else if (this->is_constant()) { // We can only lower len and cap if there are no function calls @@ -6999,6 +6980,170 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function, int) return this; } +// Lower a make expression. + +Expression* +Builtin_call_expression::lower_make() +{ + source_location loc = this->location(); + + const Expression_list* args = this->args(); + if (args == NULL || args->size() < 1) + { + this->report_error(_("not enough arguments")); + return Expression::make_error(this->location()); + } + + Expression_list::const_iterator parg = args->begin(); + + Expression* first_arg = *parg; + if (!first_arg->is_type_expression()) + { + error_at(first_arg->location(), "expected type"); + this->set_is_error(); + return Expression::make_error(this->location()); + } + Type* type = first_arg->type(); + + bool is_slice = false; + bool is_map = false; + bool is_chan = false; + if (type->is_open_array_type()) + is_slice = true; + else if (type->map_type() != NULL) + is_map = true; + else if (type->channel_type() != NULL) + is_chan = true; + else + { + this->report_error(_("invalid type for make function")); + return Expression::make_error(this->location()); + } + + ++parg; + Expression* len_arg; + if (parg == args->end()) + { + if (is_slice) + { + this->report_error(_("length required when allocating a slice")); + return Expression::make_error(this->location()); + } + + mpz_t zval; + mpz_init_set_ui(zval, 0); + len_arg = Expression::make_integer(&zval, NULL, loc); + mpz_clear(zval); + } + else + { + len_arg = *parg; + if (!this->check_int_value(len_arg)) + { + this->report_error(_("bad size for make")); + return Expression::make_error(this->location()); + } + ++parg; + } + + Expression* cap_arg = NULL; + if (is_slice && parg != args->end()) + { + cap_arg = *parg; + if (!this->check_int_value(cap_arg)) + { + this->report_error(_("bad capacity when making slice")); + return Expression::make_error(this->location()); + } + ++parg; + } + + if (parg != args->end()) + { + this->report_error(_("too many arguments to make")); + return Expression::make_error(this->location()); + } + + source_location type_loc = first_arg->location(); + Expression* type_arg; + if (is_slice || is_chan) + type_arg = Expression::make_type_descriptor(type, type_loc); + else if (is_map) + type_arg = Expression::make_map_descriptor(type->map_type(), type_loc); + else + go_unreachable(); + + Expression* call; + if (is_slice) + { + if (cap_arg == NULL) + call = Runtime::make_call(Runtime::MAKESLICE1, loc, 2, type_arg, + len_arg); + else + call = Runtime::make_call(Runtime::MAKESLICE2, loc, 3, type_arg, + len_arg, cap_arg); + } + else if (is_map) + call = Runtime::make_call(Runtime::MAKEMAP, loc, 2, type_arg, len_arg); + else if (is_chan) + call = Runtime::make_call(Runtime::MAKECHAN, loc, 2, type_arg, len_arg); + else + go_unreachable(); + + return Expression::make_unsafe_cast(type, call, loc); +} + +// Return whether an expression has an integer value. Report an error +// if not. This is used when handling calls to the predeclared make +// function. + +bool +Builtin_call_expression::check_int_value(Expression* e) +{ + if (e->type()->integer_type() != NULL) + return true; + + // Check for a floating point constant with integer value. + mpfr_t fval; + mpfr_init(fval); + + Type* dummy; + if (e->float_constant_value(fval, &dummy) && mpfr_integer_p(fval)) + { + mpz_t ival; + mpz_init(ival); + + bool ok = false; + + mpfr_clear_overflow(); + mpfr_clear_erangeflag(); + mpfr_get_z(ival, fval, GMP_RNDN); + if (!mpfr_overflow_p() + && !mpfr_erangeflag_p() + && mpz_sgn(ival) >= 0) + { + Named_type* ntype = Type::lookup_integer_type("int"); + Integer_type* inttype = ntype->integer_type(); + mpz_t max; + mpz_init_set_ui(max, 1); + mpz_mul_2exp(max, max, inttype->bits() - 1); + ok = mpz_cmp(ival, max) < 0; + mpz_clear(max); + } + mpz_clear(ival); + + if (ok) + { + mpfr_clear(fval); + return true; + } + } + + mpfr_clear(fval); + + return false; +} + // Return the type of the real or imag functions, given the type of // the argument. We need to map complex to float, complex64 to // float32, and complex128 to float64, so it has to be done by name. @@ -10684,107 +10829,6 @@ Expression::make_allocation(Type* type, source_location location) return new Allocation_expression(type, location); } -// Implement the builtin function make. - -class Make_expression : public Expression -{ - public: - Make_expression(Type* type, Expression_list* args, source_location location) - : Expression(EXPRESSION_MAKE, location), - type_(type), args_(args) - { } - - protected: - int - do_traverse(Traverse* traverse); - - Type* - do_type() - { return this->type_; } - - void - do_determine_type(const Type_context*); - - void - do_check_types(Gogo*); - - Expression* - do_copy() - { - return new Make_expression(this->type_, this->args_->copy(), - this->location()); - } - - tree - do_get_tree(Translate_context*); - - private: - // The type we are making. - Type* type_; - // The arguments to pass to the make routine. - Expression_list* args_; -}; - -// Traversal. - -int -Make_expression::do_traverse(Traverse* traverse) -{ - if (this->args_ != NULL - && this->args_->traverse(traverse) == TRAVERSE_EXIT) - return TRAVERSE_EXIT; - if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT) - return TRAVERSE_EXIT; - return TRAVERSE_CONTINUE; -} - -// Set types of arguments. - -void -Make_expression::do_determine_type(const Type_context*) -{ - if (this->args_ != NULL) - { - Type_context context(Type::lookup_integer_type("int"), false); - for (Expression_list::const_iterator pe = this->args_->begin(); - pe != this->args_->end(); - ++pe) - (*pe)->determine_type(&context); - } -} - -// Check types for a make expression. - -void -Make_expression::do_check_types(Gogo*) -{ - if (this->type_->channel_type() == NULL - && this->type_->map_type() == NULL - && (this->type_->array_type() == NULL - || this->type_->array_type()->length() != NULL)) - this->report_error(_("invalid type for make function")); - else if (!this->type_->check_make_expression(this->args_, this->location())) - this->set_is_error(); -} - -// Return a tree for a make expression. - -tree -Make_expression::do_get_tree(Translate_context* context) -{ - return this->type_->make_expression_tree(context, this->args_, - this->location()); -} - -// Make a make expression. - -Expression* -Expression::make_make(Type* type, Expression_list* args, - source_location location) -{ - return new Make_expression(type, args, location); -} - // Construct a struct. class Struct_construction_expression : public Expression @@ -11747,7 +11791,7 @@ Map_construction_expression::do_get_tree(Translate_context* context) valaddr = build_fold_addr_expr(tmp); } - tree descriptor = gogo->map_descriptor(mt); + tree descriptor = mt->map_descriptor_pointer(gogo, loc); tree type_tree = type_to_tree(this->type_->get_backend(gogo)); if (type_tree == error_mark_node) @@ -12771,6 +12815,50 @@ Expression::make_struct_field_offset(Struct_type* type, return new Struct_field_offset_expression(type, field); } +// An expression which evaluates to a pointer to the map descriptor of +// a map type. + +class Map_descriptor_expression : public Expression +{ + public: + Map_descriptor_expression(Map_type* type, source_location location) + : Expression(EXPRESSION_MAP_DESCRIPTOR, location), + type_(type) + { } + + protected: + Type* + do_type() + { return Type::make_pointer_type(Map_type::make_map_descriptor_type()); } + + void + do_determine_type(const Type_context*) + { } + + Expression* + do_copy() + { return this; } + + tree + do_get_tree(Translate_context* context) + { + return this->type_->map_descriptor_pointer(context->gogo(), + this->location()); + } + + private: + // The type for which this is the descriptor. + Map_type* type_; +}; + +// Make a map descriptor expression. + +Expression* +Expression::make_map_descriptor(Map_type* type, source_location location) +{ + return new Map_descriptor_expression(type, location); +} + // An expression which evaluates to the address of an unnamed label. class Label_addr_expression : public Expression diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 13f4fb419f8..271b1bbbe36 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -78,7 +78,6 @@ class Expression EXPRESSION_FIELD_REFERENCE, EXPRESSION_INTERFACE_FIELD_REFERENCE, EXPRESSION_ALLOCATION, - EXPRESSION_MAKE, EXPRESSION_TYPE_GUARD, EXPRESSION_CONVERSION, EXPRESSION_UNSAFE_CONVERSION, @@ -92,6 +91,7 @@ class Expression EXPRESSION_TYPE_DESCRIPTOR, EXPRESSION_TYPE_INFO, EXPRESSION_STRUCT_FIELD_OFFSET, + EXPRESSION_MAP_DESCRIPTOR, EXPRESSION_LABEL_ADDR }; @@ -236,10 +236,6 @@ class Expression static Expression* make_allocation(Type*, source_location); - // Make a call to the builtin function make. - static Expression* - make_make(Type*, Expression_list*, source_location); - // Make a type guard expression. static Expression* make_type_guard(Expression*, Type*, source_location); @@ -276,8 +272,8 @@ class Expression static Receive_expression* make_receive(Expression* channel, source_location); - // Make an expression which evaluates to the type descriptor of a - // type. + // Make an expression which evaluates to the address of the type + // descriptor for TYPE. static Expression* make_type_descriptor(Type* type, source_location); @@ -304,6 +300,11 @@ class Expression static Expression* make_struct_field_offset(Struct_type*, const Struct_field*); + // Make an expression which evaluates to the address of the map + // descriptor for TYPE. + static Expression* + make_map_descriptor(Map_type* type, source_location); + // Make an expression which evaluates to the address of an unnamed // label. static Expression* diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc index 0c5cb671c05..94d1c4dd1db 100644 --- a/gcc/go/gofrontend/gogo-tree.cc +++ b/gcc/go/gofrontend/gogo-tree.cc @@ -1974,141 +1974,6 @@ Gogo::slice_constructor(tree slice_type_tree, tree values, tree count, return build_constructor(slice_type_tree, init); } -// Build a map descriptor for a map of type MAPTYPE. - -tree -Gogo::map_descriptor(Map_type* maptype) -{ - if (this->map_descriptors_ == NULL) - this->map_descriptors_ = new Map_descriptors(10); - - std::pair<const Map_type*, tree> val(maptype, NULL); - std::pair<Map_descriptors::iterator, bool> ins = - this->map_descriptors_->insert(val); - Map_descriptors::iterator p = ins.first; - if (!ins.second) - { - if (p->second == error_mark_node) - return error_mark_node; - go_assert(p->second != NULL_TREE && DECL_P(p->second)); - return build_fold_addr_expr(p->second); - } - - Type* keytype = maptype->key_type(); - Type* valtype = maptype->val_type(); - - std::string mangled_name = ("__go_map_" + maptype->mangled_name(this)); - - tree id = get_identifier_from_string(mangled_name); - - // Get the type of the map descriptor. This is __go_map_descriptor - // in libgo/map.h. - - tree struct_type = this->map_descriptor_type(); - - // The map entry type is a struct with three fields. This struct is - // specific to MAPTYPE. Build it. - - tree map_entry_type = make_node(RECORD_TYPE); - - Btype* bkey_type = keytype->get_backend(this); - Btype* bval_type = valtype->get_backend(this); - map_entry_type = Gogo::builtin_struct(NULL, "__map", map_entry_type, 3, - "__next", - build_pointer_type(map_entry_type), - "__key", - type_to_tree(bkey_type), - "__val", - type_to_tree(bval_type)); - if (map_entry_type == error_mark_node) - { - p->second = error_mark_node; - return error_mark_node; - } - - tree map_entry_key_field = DECL_CHAIN(TYPE_FIELDS(map_entry_type)); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(map_entry_key_field)), - "__key") == 0); - - tree map_entry_val_field = DECL_CHAIN(map_entry_key_field); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(map_entry_val_field)), - "__val") == 0); - - // Initialize the entries. - - tree map_descriptor_field = TYPE_FIELDS(struct_type); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(map_descriptor_field)), - "__map_descriptor") == 0); - tree entry_size_field = DECL_CHAIN(map_descriptor_field); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(entry_size_field)), - "__entry_size") == 0); - tree key_offset_field = DECL_CHAIN(entry_size_field); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(key_offset_field)), - "__key_offset") == 0); - tree val_offset_field = DECL_CHAIN(key_offset_field); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(val_offset_field)), - "__val_offset") == 0); - - VEC(constructor_elt, gc)* descriptor = VEC_alloc(constructor_elt, gc, 6); - - constructor_elt* elt = VEC_quick_push(constructor_elt, descriptor, NULL); - elt->index = map_descriptor_field; - elt->value = maptype->type_descriptor_pointer(this, BUILTINS_LOCATION); - - elt = VEC_quick_push(constructor_elt, descriptor, NULL); - elt->index = entry_size_field; - elt->value = TYPE_SIZE_UNIT(map_entry_type); - - elt = VEC_quick_push(constructor_elt, descriptor, NULL); - elt->index = key_offset_field; - elt->value = byte_position(map_entry_key_field); - - elt = VEC_quick_push(constructor_elt, descriptor, NULL); - elt->index = val_offset_field; - elt->value = byte_position(map_entry_val_field); - - tree constructor = build_constructor(struct_type, descriptor); - - tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL, id, struct_type); - TREE_STATIC(decl) = 1; - TREE_USED(decl) = 1; - TREE_READONLY(decl) = 1; - TREE_CONSTANT(decl) = 1; - DECL_INITIAL(decl) = constructor; - make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl)); - resolve_unique_section(decl, 1, 0); - - rest_of_decl_compilation(decl, 1, 0); - - go_preserve_from_gc(decl); - p->second = decl; - - return build_fold_addr_expr(decl); -} - -// Return a tree for the type of a map descriptor. This is struct -// __go_map_descriptor in libgo/runtime/map.h. This is the same for -// all map types. - -tree -Gogo::map_descriptor_type() -{ - static tree struct_type; - Type* tdt = Type::make_type_descriptor_type(); - tree dtype = type_to_tree(tdt->get_backend(this)); - dtype = build_qualified_type(dtype, TYPE_QUAL_CONST); - return Gogo::builtin_struct(&struct_type, "__go_map_descriptor", NULL_TREE, - 4, - "__map_descriptor", - build_pointer_type(dtype), - "__entry_size", - sizetype, - "__key_offset", - sizetype, - "__val_offset", - sizetype); -} - // Build an interface method table for a type: a list of function // pointers, one for each interface method. This is used for // interfaces. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 484d1a11e8f..194cacafcaf 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -29,7 +29,6 @@ Gogo::Gogo(Backend* backend, int int_type_size, int pointer_size) imports_(), imported_unsafe_(false), packages_(), - map_descriptors_(NULL), init_functions_(), need_init_fn_(false), init_fn_name_(), @@ -2596,6 +2595,7 @@ Gogo::convert_named_types() Array_type::make_array_type_descriptor_type(); Array_type::make_slice_type_descriptor_type(); Map_type::make_map_type_descriptor_type(); + Map_type::make_map_descriptor_type(); Channel_type::make_chan_type_descriptor_type(); Interface_type::make_interface_type_descriptor_type(); Type::convert_builtin_named_types(this); diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 972369fe6fb..cc349afd064 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -473,16 +473,6 @@ class Gogo slice_constructor(tree slice_type_tree, tree values, tree count, tree capacity); - // Build a map descriptor. - tree - map_descriptor(Map_type*); - - // Return a tree for the type of a map descriptor. This is struct - // __go_map_descriptor in libgo/runtime/map.h. This is the same for - // all map types. - tree - map_descriptor_type(); - // Build required interface method tables. void build_interface_method_tables(); @@ -599,10 +589,6 @@ class Gogo // Type used to map special names in the sys package. typedef std::map<std::string, std::string> Sys_names; - // Hash table mapping map types to map descriptor decls. - typedef Unordered_map_hash(const Map_type*, tree, Type_hash_identical, - Type_identical) Map_descriptors; - // The backend generator. Backend* backend_; // The package we are compiling. @@ -619,8 +605,6 @@ class Gogo // Mapping from package names we have seen to packages. This does // not include the package we are compiling. Packages packages_; - // Mapping from map types to map descriptors. - Map_descriptors* map_descriptors_; // The functions named "init", if there are any. std::vector<Named_object*> init_functions_; // Whether we need a magic initialization function. diff --git a/gcc/go/gofrontend/runtime.cc b/gcc/go/gofrontend/runtime.cc index 204f14751b5..2ecfbf5b155 100644 --- a/gcc/go/gofrontend/runtime.cc +++ b/gcc/go/gofrontend/runtime.cc @@ -64,6 +64,8 @@ enum Runtime_function_type RFT_FUNC_PTR, // Pointer to Go type descriptor. RFT_TYPE, + // Pointer to map descriptor. + RFT_MAPDESCRIPTOR, NUMBER_OF_RUNTIME_FUNCTION_TYPES }; @@ -175,6 +177,10 @@ runtime_function_type(Runtime_function_type bft) case RFT_TYPE: t = Type::make_type_descriptor_ptr_type(); break; + + case RFT_MAPDESCRIPTOR: + t = Type::make_pointer_type(Map_type::make_map_descriptor_type()); + break; } runtime_function_types[bft] = t; @@ -225,6 +231,11 @@ convert_to_runtime_function_type(Runtime_function_type bft, Expression* e, case RFT_TYPE: go_assert(e->type() == Type::make_type_descriptor_ptr_type()); return e; + + case RFT_MAPDESCRIPTOR: + go_assert(e->type()->points_to() + == Map_type::make_map_descriptor_type()); + return e; } } diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def index 6e7a807a88e..219ccb8bd90 100644 --- a/gcc/go/gofrontend/runtime.def +++ b/gcc/go/gofrontend/runtime.def @@ -65,8 +65,14 @@ DEF_GO_RUNTIME(STRING_TO_INT_ARRAY, "__go_string_to_int_array", P1(STRING), R1(SLICE)) +// Make a slice. +DEF_GO_RUNTIME(MAKESLICE1, "__go_make_slice1", P2(TYPE, UINTPTR), R1(SLICE)) +DEF_GO_RUNTIME(MAKESLICE2, "__go_make_slice2", P3(TYPE, UINTPTR, UINTPTR), + R1(SLICE)) + + // Make a map. -DEF_GO_RUNTIME(NEW_MAP, "__go_new_map", P2(TYPE, UINTPTR), R1(MAP)) +DEF_GO_RUNTIME(MAKEMAP, "__go_new_map", P2(MAPDESCRIPTOR, UINTPTR), R1(MAP)) // Build a map from a composite literal. DEF_GO_RUNTIME(CONSTRUCT_MAP, "__go_construct_map", @@ -103,7 +109,7 @@ DEF_GO_RUNTIME(MAPITERNEXT, "runtime.mapiternext", P1(MAPITER), R0()) // Make a channel. -DEF_GO_RUNTIME(NEW_CHANNEL, "__go_new_channel", P2(UINTPTR, UINTPTR), R1(CHAN)) +DEF_GO_RUNTIME(MAKECHAN, "__go_new_channel", P2(TYPE, UINTPTR), R1(CHAN)) // Get the length of a channel (the number of unread values). DEF_GO_RUNTIME(CHAN_LEN, "__go_chan_len", P1(CHAN), R1(INT)) diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 15e35c2b29d..4b2ceeb4560 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -768,68 +768,6 @@ Type::hash_string(const std::string& s, unsigned int h) return h; } -// Default check for the expression passed to make. Any type which -// may be used with make implements its own version of this. - -bool -Type::do_check_make_expression(Expression_list*, source_location) -{ - go_unreachable(); -} - -// Return whether an expression has an integer value. Report an error -// if not. This is used when handling calls to the predeclared make -// function. - -bool -Type::check_int_value(Expression* e, const char* errmsg, - source_location location) -{ - if (e->type()->integer_type() != NULL) - return true; - - // Check for a floating point constant with integer value. - mpfr_t fval; - mpfr_init(fval); - - Type* dummy; - if (e->float_constant_value(fval, &dummy) && mpfr_integer_p(fval)) - { - mpz_t ival; - mpz_init(ival); - - bool ok = false; - - mpfr_clear_overflow(); - mpfr_clear_erangeflag(); - mpfr_get_z(ival, fval, GMP_RNDN); - if (!mpfr_overflow_p() - && !mpfr_erangeflag_p() - && mpz_sgn(ival) >= 0) - { - Named_type* ntype = Type::lookup_integer_type("int"); - Integer_type* inttype = ntype->integer_type(); - mpz_t max; - mpz_init_set_ui(max, 1); - mpz_mul_2exp(max, max, inttype->bits() - 1); - ok = mpz_cmp(ival, max) < 0; - mpz_clear(max); - } - mpz_clear(ival); - - if (ok) - { - mpfr_clear(fval); - return true; - } - } - - mpfr_clear(fval); - - error_at(location, "%s", errmsg); - return false; -} - // A hash table mapping unnamed types to the backend representation of // those types. @@ -912,16 +850,6 @@ Type::get_btype_without_hash(Gogo* gogo) return this->btype_; } -// Any type which supports the builtin make function must implement -// this. - -tree -Type::do_make_expression_tree(Translate_context*, Expression_list*, - source_location) -{ - go_unreachable(); -} - // Return a pointer to the type descriptor for this type. tree @@ -1366,6 +1294,8 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind, Expression_list* vals = new Expression_list(); vals->reserve(9); + if (!this->has_pointer()) + runtime_type_kind |= RUNTIME_TYPE_KIND_NO_POINTERS; Struct_field_list::const_iterator p = fields->begin(); go_assert(p->field_name() == "Kind"); mpz_t iv; @@ -4341,43 +4271,6 @@ Array_type::do_hash_for_method(Gogo* gogo) const return this->element_type_->hash_for_method(gogo) + 1; } -// See if the expression passed to make is suitable. The first -// argument is required, and gives the length. An optional second -// argument is permitted for the capacity. - -bool -Array_type::do_check_make_expression(Expression_list* args, - source_location location) -{ - go_assert(this->length_ == NULL); - if (args == NULL || args->empty()) - { - error_at(location, "length required when allocating a slice"); - return false; - } - else if (args->size() > 2) - { - error_at(location, "too many expressions passed to make"); - return false; - } - else - { - if (!Type::check_int_value(args->front(), - _("bad length when making slice"), location)) - return false; - - if (args->size() > 1) - { - if (!Type::check_int_value(args->back(), - _("bad capacity when making slice"), - location)) - return false; - } - - return true; - } -} - // Get a tree for the length of a fixed array. The length may be // computed using a function call, so we must only evaluate it once. @@ -4491,129 +4384,6 @@ Array_type::get_backend_length(Gogo* gogo) return tree_to_expr(this->get_length_tree(gogo)); } -// Handle the builtin make function for a slice. - -tree -Array_type::do_make_expression_tree(Translate_context* context, - Expression_list* args, - source_location location) -{ - go_assert(this->length_ == NULL); - - Gogo* gogo = context->gogo(); - tree type_tree = type_to_tree(this->get_backend(gogo)); - if (type_tree == error_mark_node) - return error_mark_node; - - tree values_field = TYPE_FIELDS(type_tree); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(values_field)), - "__values") == 0); - - tree count_field = DECL_CHAIN(values_field); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(count_field)), - "__count") == 0); - - tree element_type_tree = type_to_tree(this->element_type_->get_backend(gogo)); - if (element_type_tree == error_mark_node) - return error_mark_node; - tree element_size_tree = TYPE_SIZE_UNIT(element_type_tree); - - // The first argument is the number of elements, the optional second - // argument is the capacity. - go_assert(args != NULL && args->size() >= 1 && args->size() <= 2); - - tree length_tree = args->front()->get_tree(context); - if (length_tree == error_mark_node) - return error_mark_node; - if (!DECL_P(length_tree)) - length_tree = save_expr(length_tree); - if (!INTEGRAL_TYPE_P(TREE_TYPE(length_tree))) - length_tree = convert_to_integer(TREE_TYPE(count_field), length_tree); - - tree bad_index = Expression::check_bounds(length_tree, - TREE_TYPE(count_field), - NULL_TREE, location); - - length_tree = fold_convert_loc(location, TREE_TYPE(count_field), length_tree); - tree capacity_tree; - if (args->size() == 1) - capacity_tree = length_tree; - else - { - capacity_tree = args->back()->get_tree(context); - if (capacity_tree == error_mark_node) - return error_mark_node; - if (!DECL_P(capacity_tree)) - capacity_tree = save_expr(capacity_tree); - if (!INTEGRAL_TYPE_P(TREE_TYPE(capacity_tree))) - capacity_tree = convert_to_integer(TREE_TYPE(count_field), - capacity_tree); - - bad_index = Expression::check_bounds(capacity_tree, - TREE_TYPE(count_field), - bad_index, location); - - tree chktype = (((TYPE_SIZE(TREE_TYPE(capacity_tree)) - > TYPE_SIZE(TREE_TYPE(length_tree))) - || ((TYPE_SIZE(TREE_TYPE(capacity_tree)) - == TYPE_SIZE(TREE_TYPE(length_tree))) - && TYPE_UNSIGNED(TREE_TYPE(capacity_tree)))) - ? TREE_TYPE(capacity_tree) - : TREE_TYPE(length_tree)); - tree chk = fold_build2_loc(location, LT_EXPR, boolean_type_node, - fold_convert_loc(location, chktype, - capacity_tree), - fold_convert_loc(location, chktype, - length_tree)); - if (bad_index == NULL_TREE) - bad_index = chk; - else - bad_index = fold_build2_loc(location, TRUTH_OR_EXPR, boolean_type_node, - bad_index, chk); - - capacity_tree = fold_convert_loc(location, TREE_TYPE(count_field), - capacity_tree); - } - - tree size_tree = fold_build2_loc(location, MULT_EXPR, sizetype, - element_size_tree, - fold_convert_loc(location, sizetype, - capacity_tree)); - - tree chk = fold_build2_loc(location, TRUTH_AND_EXPR, boolean_type_node, - fold_build2_loc(location, GT_EXPR, - boolean_type_node, - fold_convert_loc(location, - sizetype, - capacity_tree), - size_zero_node), - fold_build2_loc(location, LT_EXPR, - boolean_type_node, - size_tree, element_size_tree)); - if (bad_index == NULL_TREE) - bad_index = chk; - else - bad_index = fold_build2_loc(location, TRUTH_OR_EXPR, boolean_type_node, - bad_index, chk); - - tree space = context->gogo()->allocate_memory(this->element_type_, - size_tree, location); - - space = fold_convert(TREE_TYPE(values_field), space); - - if (bad_index != NULL_TREE && bad_index != boolean_false_node) - { - tree crash = Gogo::runtime_error(RUNTIME_ERROR_MAKE_SLICE_OUT_OF_BOUNDS, - location); - space = build2(COMPOUND_EXPR, TREE_TYPE(space), - build3(COND_EXPR, void_type_node, - bad_index, crash, NULL_TREE), - space); - } - - return gogo->slice_constructor(type_tree, space, length_tree, capacity_tree); -} - // Return a tree for a pointer to the values in ARRAY. tree @@ -4962,28 +4732,6 @@ Map_type::do_hash_for_method(Gogo* gogo) const + 2); } -// Check that a call to the builtin make function is valid. For a map -// the optional argument is the number of spaces to preallocate for -// values. - -bool -Map_type::do_check_make_expression(Expression_list* args, - source_location location) -{ - if (args != NULL && !args->empty()) - { - if (!Type::check_int_value(args->front(), _("bad size when making map"), - location)) - return false; - else if (args->size() > 1) - { - error_at(location, "too many arguments when making map"); - return false; - } - } - return true; -} - // Get the backend representation for a map type. A map type is // represented as a pointer to a struct. The struct is __go_map in // libgo/map.h. @@ -5024,61 +4772,6 @@ Map_type::do_get_backend(Gogo* gogo) return backend_map_type; } -// Return an expression for a newly allocated map. - -tree -Map_type::do_make_expression_tree(Translate_context* context, - Expression_list* args, - source_location location) -{ - tree bad_index = NULL_TREE; - - tree expr_tree; - if (args == NULL || args->empty()) - expr_tree = size_zero_node; - else - { - expr_tree = args->front()->get_tree(context); - if (expr_tree == error_mark_node) - return error_mark_node; - if (!DECL_P(expr_tree)) - expr_tree = save_expr(expr_tree); - if (!INTEGRAL_TYPE_P(TREE_TYPE(expr_tree))) - expr_tree = convert_to_integer(sizetype, expr_tree); - bad_index = Expression::check_bounds(expr_tree, sizetype, bad_index, - location); - } - - tree map_type = type_to_tree(this->get_backend(context->gogo())); - - static tree new_map_fndecl; - tree ret = Gogo::call_builtin(&new_map_fndecl, - location, - "__go_new_map", - 2, - map_type, - TREE_TYPE(TYPE_FIELDS(TREE_TYPE(map_type))), - context->gogo()->map_descriptor(this), - sizetype, - expr_tree); - if (ret == error_mark_node) - return error_mark_node; - // This can panic if the capacity is out of range. - TREE_NOTHROW(new_map_fndecl) = 0; - - if (bad_index == NULL_TREE) - return ret; - else - { - tree crash = Gogo::runtime_error(RUNTIME_ERROR_MAKE_MAP_OUT_OF_BOUNDS, - location); - return build2(COMPOUND_EXPR, TREE_TYPE(ret), - build3(COND_EXPR, void_type_node, - bad_index, crash, NULL_TREE), - ret); - } -} - // The type of a map type descriptor. Type* @@ -5136,6 +4829,129 @@ Map_type::do_type_descriptor(Gogo* gogo, Named_type* name) return Expression::make_struct_composite_literal(mtdt, vals, bloc); } +// A mapping from map types to map descriptors. + +Map_type::Map_descriptors Map_type::map_descriptors; + +// Build a map descriptor for this type. Return a pointer to it. + +tree +Map_type::map_descriptor_pointer(Gogo* gogo, source_location location) +{ + Bvariable* bvar = this->map_descriptor(gogo); + tree var_tree = var_to_tree(bvar); + if (var_tree == error_mark_node) + return error_mark_node; + return build_fold_addr_expr_loc(location, var_tree); +} + +// Build a map descriptor for this type. + +Bvariable* +Map_type::map_descriptor(Gogo* gogo) +{ + std::pair<Map_type*, Bvariable*> val(this, NULL); + std::pair<Map_type::Map_descriptors::iterator, bool> ins = + Map_type::map_descriptors.insert(val); + if (!ins.second) + return ins.first->second; + + Type* key_type = this->key_type_; + Type* val_type = this->val_type_; + + // The map entry type is a struct with three fields. Build that + // struct so that we can get the offsets of the key and value within + // a map entry. The first field should technically be a pointer to + // this type itself, but since we only care about field offsets we + // just use pointer to bool. + Type* pbool = Type::make_pointer_type(Type::make_boolean_type()); + Struct_type* map_entry_type = + Type::make_builtin_struct_type(3, + "__next", pbool, + "__key", key_type, + "__val", val_type); + + Type* map_descriptor_type = Map_type::make_map_descriptor_type(); + + const Struct_field_list* fields = + map_descriptor_type->struct_type()->fields(); + + Expression_list* vals = new Expression_list(); + vals->reserve(4); + + source_location bloc = BUILTINS_LOCATION; + + Struct_field_list::const_iterator p = fields->begin(); + + go_assert(p->field_name() == "__map_descriptor"); + vals->push_back(Expression::make_type_descriptor(this, bloc)); + + ++p; + go_assert(p->field_name() == "__entry_size"); + Expression::Type_info type_info = Expression::TYPE_INFO_SIZE; + vals->push_back(Expression::make_type_info(map_entry_type, type_info)); + + Struct_field_list::const_iterator pf = map_entry_type->fields()->begin(); + ++pf; + go_assert(pf->field_name() == "__key"); + + ++p; + go_assert(p->field_name() == "__key_offset"); + vals->push_back(Expression::make_struct_field_offset(map_entry_type, &*pf)); + + ++pf; + go_assert(pf->field_name() == "__val"); + + ++p; + go_assert(p->field_name() == "__val_offset"); + vals->push_back(Expression::make_struct_field_offset(map_entry_type, &*pf)); + + ++p; + go_assert(p == fields->end()); + + Expression* initializer = + Expression::make_struct_composite_literal(map_descriptor_type, vals, bloc); + + std::string mangled_name = "__go_map_" + this->mangled_name(gogo); + Btype* map_descriptor_btype = map_descriptor_type->get_backend(gogo); + Bvariable* bvar = gogo->backend()->immutable_struct(mangled_name, true, + map_descriptor_btype, + bloc); + + Translate_context context(gogo, NULL, NULL, NULL); + context.set_is_const(); + Bexpression* binitializer = tree_to_expr(initializer->get_tree(&context)); + + gogo->backend()->immutable_struct_set_init(bvar, mangled_name, true, + map_descriptor_btype, bloc, + binitializer); + + ins.first->second = bvar; + return bvar; +} + +// Build the type of a map descriptor. This must match the struct +// __go_map_descriptor in libgo/runtime/map.h. + +Type* +Map_type::make_map_descriptor_type() +{ + static Type* ret; + if (ret == NULL) + { + Type* ptdt = Type::make_type_descriptor_ptr_type(); + Type* uintptr_type = Type::lookup_integer_type("uintptr"); + Struct_type* sf = + Type::make_builtin_struct_type(4, + "__map_descriptor", ptdt, + "__entry_size", uintptr_type, + "__key_offset", uintptr_type, + "__val_offset", uintptr_type); + ret = Type::make_builtin_named_type("__go_map_descriptor", sf); + } + return ret; +} + // Reflection string for a map. void @@ -5219,29 +5035,6 @@ Channel_type::is_identical(const Channel_type* t, && this->may_receive_ == t->may_receive_); } -// Check whether the parameters for a call to the builtin function -// make are OK for a channel. A channel can take an optional single -// parameter which is the buffer size. - -bool -Channel_type::do_check_make_expression(Expression_list* args, - source_location location) -{ - if (args != NULL && !args->empty()) - { - if (!Type::check_int_value(args->front(), - _("bad buffer size when making channel"), - location)) - return false; - else if (args->size() > 1) - { - error_at(location, "too many arguments when making channel"); - return false; - } - } - return true; -} - // Return the tree for a channel type. A channel is a pointer to a // __go_channel struct. The __go_channel struct is defined in // libgo/runtime/channel.h. @@ -5260,66 +5053,6 @@ Channel_type::do_get_backend(Gogo* gogo) return backend_channel_type; } -// Handle the builtin function make for a channel. - -tree -Channel_type::do_make_expression_tree(Translate_context* context, - Expression_list* args, - source_location location) -{ - Gogo* gogo = context->gogo(); - tree channel_type = type_to_tree(this->get_backend(gogo)); - - Type* ptdt = Type::make_type_descriptor_ptr_type(); - tree element_type_descriptor = - this->element_type_->type_descriptor_pointer(gogo, location); - - tree bad_index = NULL_TREE; - - tree expr_tree; - if (args == NULL || args->empty()) - expr_tree = size_zero_node; - else - { - expr_tree = args->front()->get_tree(context); - if (expr_tree == error_mark_node) - return error_mark_node; - if (!DECL_P(expr_tree)) - expr_tree = save_expr(expr_tree); - if (!INTEGRAL_TYPE_P(TREE_TYPE(expr_tree))) - expr_tree = convert_to_integer(sizetype, expr_tree); - bad_index = Expression::check_bounds(expr_tree, sizetype, bad_index, - location); - } - - static tree new_channel_fndecl; - tree ret = Gogo::call_builtin(&new_channel_fndecl, - location, - "__go_new_channel", - 2, - channel_type, - type_to_tree(ptdt->get_backend(gogo)), - element_type_descriptor, - sizetype, - expr_tree); - if (ret == error_mark_node) - return error_mark_node; - // This can panic if the capacity is out of range. - TREE_NOTHROW(new_channel_fndecl) = 0; - - if (bad_index == NULL_TREE) - return ret; - else - { - tree crash = Gogo::runtime_error(RUNTIME_ERROR_MAKE_CHAN_OUT_OF_BOUNDS, - location); - return build2(COMPOUND_EXPR, TREE_TYPE(ret), - build3(COND_EXPR, void_type_node, - bad_index, crash, NULL_TREE), - ret); - } -} - // Build a type descriptor for a channel type. Type* diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index fc35431f6ad..9947a2ca749 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -78,6 +78,8 @@ static const int RUNTIME_TYPE_KIND_STRING = 24; static const int RUNTIME_TYPE_KIND_STRUCT = 25; static const int RUNTIME_TYPE_KIND_UNSAFE_POINTER = 26; +static const int RUNTIME_TYPE_KIND_NO_POINTERS = (1 << 7); + // To build the complete list of methods for a named type we need to // gather all methods from anonymous fields. Those methods may // require an arbitrary set of indirections and field offsets. There @@ -811,13 +813,6 @@ class Type is_unexported_field_or_method(Gogo*, const Type*, const std::string&, std::vector<const Named_type*>*); - // This type was passed to the builtin function make. ARGS are the - // arguments passed to make after the type; this may be NULL if - // there were none. Issue any required errors. - bool - check_make_expression(Expression_list* args, source_location location) - { return this->do_check_make_expression(args, location); } - // Convert the builtin named types. static void convert_builtin_named_types(Gogo*); @@ -826,12 +821,6 @@ class Type Btype* get_backend(Gogo*); - // Return a tree for a make expression applied to this type. - tree - make_expression_tree(Translate_context* context, Expression_list* args, - source_location location) - { return this->do_make_expression_tree(context, args, location); } - // Build a type descriptor entry for this type. Return a pointer to // it. The location is the location which causes us to need the // entry. @@ -878,16 +867,9 @@ class Type virtual unsigned int do_hash_for_method(Gogo*) const; - virtual bool - do_check_make_expression(Expression_list* args, source_location); - virtual Btype* do_get_backend(Gogo*) = 0; - virtual tree - do_make_expression_tree(Translate_context*, Expression_list*, - source_location); - virtual Expression* do_type_descriptor(Gogo*, Named_type* name) = 0; @@ -901,10 +883,6 @@ class Type virtual void do_export(Export*) const; - // Return whether an expression is an integer. - static bool - check_int_value(Expression*, const char*, source_location); - // Return whether a method expects a pointer as the receiver. static bool method_expects_pointer(const Named_object*); @@ -2083,16 +2061,9 @@ class Array_type : public Type unsigned int do_hash_for_method(Gogo*) const; - bool - do_check_make_expression(Expression_list*, source_location); - Btype* do_get_backend(Gogo*); - tree - do_make_expression_tree(Translate_context*, Expression_list*, - source_location); - Expression* do_type_descriptor(Gogo*, Named_type*); @@ -2157,6 +2128,15 @@ class Map_type : public Type static Type* make_map_type_descriptor_type(); + static Type* + make_map_descriptor_type(); + + // Build a map descriptor for this type. Return a pointer to it. + // The location is the location which causes us to need the + // descriptor. + tree + map_descriptor_pointer(Gogo* gogo, source_location); + protected: int do_traverse(Traverse*); @@ -2171,16 +2151,9 @@ class Map_type : public Type unsigned int do_hash_for_method(Gogo*) const; - bool - do_check_make_expression(Expression_list*, source_location); - Btype* do_get_backend(Gogo*); - tree - do_make_expression_tree(Translate_context*, Expression_list*, - source_location); - Expression* do_type_descriptor(Gogo*, Named_type*); @@ -2194,6 +2167,14 @@ class Map_type : public Type do_export(Export*) const; private: + // Mapping from map types to map descriptors. + typedef Unordered_map_hash(const Map_type*, Bvariable*, Type_hash_identical, + Type_identical) Map_descriptors; + static Map_descriptors map_descriptors; + + Bvariable* + map_descriptor(Gogo*); + // The key type. Type* key_type_; // The value type. @@ -2252,16 +2233,9 @@ class Channel_type : public Type unsigned int do_hash_for_method(Gogo*) const; - bool - do_check_make_expression(Expression_list*, source_location); - Btype* do_get_backend(Gogo*); - tree - do_make_expression_tree(Translate_context*, Expression_list*, - source_location); - Expression* do_type_descriptor(Gogo*, Named_type*); @@ -2594,18 +2568,9 @@ class Named_type : public Type unsigned int do_hash_for_method(Gogo*) const; - bool - do_check_make_expression(Expression_list* args, source_location location) - { return this->type_->check_make_expression(args, location); } - Btype* do_get_backend(Gogo*); - tree - do_make_expression_tree(Translate_context* context, Expression_list* args, - source_location location) - { return this->type_->make_expression_tree(context, args, location); } - Expression* do_type_descriptor(Gogo*, Named_type*); @@ -2734,18 +2699,9 @@ class Forward_declaration_type : public Type do_hash_for_method(Gogo* gogo) const { return this->real_type()->hash_for_method(gogo); } - bool - do_check_make_expression(Expression_list* args, source_location location) - { return this->base()->check_make_expression(args, location); } - Btype* do_get_backend(Gogo* gogo); - tree - do_make_expression_tree(Translate_context* context, Expression_list* args, - source_location location) - { return this->base()->make_expression_tree(context, args, location); } - Expression* do_type_descriptor(Gogo*, Named_type*); diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c index 7474be016c3..7e23c9d69de 100644 --- a/gcc/graphite-sese-to-poly.c +++ b/gcc/graphite-sese-to-poly.c @@ -1092,7 +1092,7 @@ build_loop_iteration_domains (scop_p scop, struct loop *loop, scan_tree_for_params (SCOP_REGION (scop), nb_iters, ub_expr, one); mpz_clear (one); - if (estimated_loop_iterations (loop, true, &nit)) + if (max_stmt_executions (loop, true, &nit)) add_upper_bounds_from_estimated_nit (scop, nit, dim, ub_expr); /* loop_i <= expr_nb_iters */ diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 0cb329077bb..407b626d60d 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -141,6 +141,7 @@ along with GCC; see the file COPYING3. If not see #include "recog.h" #include "sched-int.h" #include "target.h" +#include "common/common-target.h" #include "output.h" #include "params.h" #include "vecprim.h" @@ -4503,7 +4504,7 @@ sched_create_recovery_edges (basic_block first_bb, basic_block rec, { /* Rewritten from cfgrtl.c. */ if (flag_reorder_blocks_and_partition - && targetm.have_named_sections) + && targetm_common.have_named_sections) { /* We don't need the same note for the check because any_condjump_p (check) == true. */ diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index b34aee27379..239f498cb8a 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -4368,7 +4368,7 @@ struct rtl_opt_pass pass_rtl_ifcvt = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -4405,7 +4405,6 @@ struct rtl_opt_pass pass_if_after_combine = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } }; @@ -4442,7 +4441,6 @@ struct rtl_opt_pass pass_if_after_reload = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } }; diff --git a/gcc/implicit-zee.c b/gcc/implicit-zee.c index 2e4b58b4e48..db422482c90 100644 --- a/gcc/implicit-zee.c +++ b/gcc/implicit-zee.c @@ -988,7 +988,6 @@ struct rtl_opt_pass pass_implicit_zee = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_ggc_collect | - TODO_dump_func | TODO_verify_rtl_sharing, /* todo_flags_finish */ } }; diff --git a/gcc/init-regs.c b/gcc/init-regs.c index b4dd5e9a1fb..594b6e6388b 100644 --- a/gcc/init-regs.c +++ b/gcc/init-regs.c @@ -153,7 +153,6 @@ struct rtl_opt_pass pass_initialize_regs = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_df_finish /* todo_flags_finish */ } }; diff --git a/gcc/integrate.c b/gcc/integrate.c index af103e5fece..3a79183b155 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -325,7 +325,7 @@ struct rtl_opt_pass pass_initial_value_sets = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index ec0c83af3c1..a7fecf26fbf 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -836,7 +836,7 @@ ipcp_iterate_stage (void) /* Some lattices have changed from IPA_TOP to IPA_BOTTOM. This change should be propagated. */ { - /*gcc_assert (n_cloning_candidates);*/ + gcc_assert (n_cloning_candidates); ipcp_propagate_stage (); } if (dump_file) @@ -1583,7 +1583,7 @@ struct ipa_opt_pass_d pass_ipa_cp = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_cgraph | TODO_dump_func | + TODO_dump_cgraph | TODO_remove_functions | TODO_ggc_collect /* todo_flags_finish */ }, ipcp_generate_summary, /* generate_summary */ diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 473f554e4ae..b008f05c972 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -2079,7 +2079,7 @@ do_estimate_edge_time (struct cgraph_edge *edge) struct inline_edge_summary *es = inline_edge_summary (edge); gcc_checking_assert (edge->inline_failed); - estimate_node_size_and_time (edge->callee, + estimate_node_size_and_time (cgraph_function_or_thunk_node (edge->callee, NULL), evaluate_conditions_for_edge (edge, true), &size, &time); @@ -2226,11 +2226,10 @@ do_estimate_growth (struct cgraph_node *node) else { if (!DECL_EXTERNAL (node->decl) - && !cgraph_will_be_removed_from_program_if_no_direct_calls (node)) + && cgraph_will_be_removed_from_program_if_no_direct_calls (node)) d.growth -= info->size; /* COMDAT functions are very often not shared across multiple units since they - come from various template instantiations. Take this into account. - FIXME: allow also COMDATs with COMDAT aliases. */ + come from various template instantiations. Take this into account. */ else if (DECL_COMDAT (node->decl) && cgraph_can_remove_if_no_direct_calls_p (node)) d.growth -= (info->size diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index c5f32a34b76..2e1375437d5 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include "ipa-prop.h" #include "ipa-inline.h" #include "tree-inline.h" +#include "tree-pass.h" int ncalls_inlined; int nfunctions_inlined; @@ -82,12 +83,13 @@ update_noncloned_frequencies (struct cgraph_node *node, copy of function was removed. */ static bool -can_remove_node_now_p (struct cgraph_node *node) +can_remove_node_now_p_1 (struct cgraph_node *node) { /* FIXME: When address is taken of DECL_EXTERNAL function we still can remove its offline copy, but we would need to keep unanalyzed node in the callgraph so references can point to it. */ return (!node->address_taken + && !ipa_ref_has_aliases_p (&node->ref_list) && cgraph_can_remove_if_no_direct_calls_p (node) /* Inlining might enable more devirtualizing, so we want to remove those only after all devirtualizable virtual calls are processed. @@ -96,15 +98,34 @@ can_remove_node_now_p (struct cgraph_node *node) && (!DECL_VIRTUAL_P (node->decl) || (!DECL_COMDAT (node->decl) && !DECL_EXTERNAL (node->decl))) - /* Don't reuse if more than one function shares a comdat group. - If the other function(s) are needed, we need to emit even - this function out of line. */ - && !node->same_comdat_group /* During early inlining some unanalyzed cgraph nodes might be in the callgraph and they might reffer the function in question. */ && !cgraph_new_nodes); } +/* We are going to eliminate last direct call to NODE (or alias of it) via edge E. + Verify that the NODE can be removed from unit and if it is contained in comdat + group that the whole comdat group is removable. */ + +static bool +can_remove_node_now_p (struct cgraph_node *node, struct cgraph_edge *e) +{ + struct cgraph_node *next; + if (!can_remove_node_now_p_1 (node)) + return false; + + /* When we see same comdat group, we need to be sure that all + items can be removed. */ + if (!node->same_comdat_group) + return true; + for (next = node->same_comdat_group; + next != node; next = next->same_comdat_group) + if (node->callers && node->callers != e + && !can_remove_node_now_p_1 (node)) + return false; + return true; +} + /* E is expected to be an edge being inlined. Clone destination node of the edge and redirect it to the new clone. @@ -126,8 +147,15 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, /* Recursive inlining never wants the master clone to be overwritten. */ && update_original - && can_remove_node_now_p (e->callee)) + && can_remove_node_now_p (e->callee, e)) { + /* TODO: When callee is in a comdat group, we could remove all of it, + including all inline clones inlined into it. That would however + need small function inlining to register edge removal hook to + maintain the priority queue. + + For now we keep the ohter functions in the group in program until + cgraph_remove_unreachable_functions gets rid of them. */ gcc_assert (!e->callee->global.inlined_to); if (e->callee->analyzed && !DECL_EXTERNAL (e->callee->decl)) { @@ -192,7 +220,22 @@ inline_call (struct cgraph_edge *e, bool update_original, /* If aliases are involved, redirect edge to the actual destination and possibly remove the aliases. */ if (e->callee != callee) - cgraph_redirect_edge_callee (e, callee); + { + struct cgraph_node *alias = e->callee, *next_alias; + cgraph_redirect_edge_callee (e, callee); + while (alias && alias != callee) + { + if (!alias->callers + && can_remove_node_now_p (alias, e)) + { + next_alias = cgraph_alias_aliased_node (alias); + cgraph_remove_node (alias); + alias = next_alias; + } + else + break; + } + } clone_inlined_nodes (e, true, update_original, overall_size); @@ -322,6 +365,8 @@ inline_transform (struct cgraph_node *node) cgraph_redirect_edge_call_stmt_to_callee (e); if (!e->inline_failed || warn_inline) inline_p = true; + /* Redirecting edges might lead to a need for vops to be recomputed. */ + todo |= TODO_update_ssa_only_virtuals; } if (inline_p) diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 6733e9ae356..ff1041ba493 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -643,6 +643,16 @@ want_inline_self_recursive_call_p (struct cgraph_edge *edge, return want_inline; } +/* Return true when NODE has caller other than EDGE. + Worker for cgraph_for_node_and_aliases. */ + +static bool +check_caller_edge (struct cgraph_node *node, void *edge) +{ + return (node->callers + && node->callers != edge); +} + /* Decide if NODE is called once inlining it would eliminate need for the offline copy of function. */ @@ -650,24 +660,26 @@ want_inline_self_recursive_call_p (struct cgraph_edge *edge, static bool want_inline_function_called_once_p (struct cgraph_node *node) { - if (node->alias) - return false; + struct cgraph_node *function = cgraph_function_or_thunk_node (node, NULL); /* Already inlined? */ - if (node->global.inlined_to) + if (function->global.inlined_to) return false; /* Zero or more then one callers? */ if (!node->callers || node->callers->next_caller) return false; + /* Maybe other aliases has more direct calls. */ + if (cgraph_for_node_and_aliases (node, check_caller_edge, node->callers, true)) + return false; /* Recursive call makes no sense to inline. */ - if (node->callers->caller == node) + if (cgraph_edge_recursive_p (node->callers)) return false; /* External functions are not really in the unit, so inlining them when called once would just increase the program size. */ - if (DECL_EXTERNAL (node->decl)) + if (DECL_EXTERNAL (function->decl)) return false; /* Offline body must be optimized out. */ - if (!cgraph_will_be_removed_from_program_if_no_direct_calls (node)) + if (!cgraph_will_be_removed_from_program_if_no_direct_calls (function)) return false; if (!can_inline_edge_p (node->callers, true)) return false; @@ -917,6 +929,8 @@ reset_edge_caches (struct cgraph_node *node) struct cgraph_edge *edge; struct cgraph_edge *e = node->callees; struct cgraph_node *where = node; + int i; + struct ipa_ref *ref; if (where->global.inlined_to) where = where->global.inlined_to; @@ -927,6 +941,9 @@ reset_edge_caches (struct cgraph_node *node) for (edge = where->callers; edge; edge = edge->next_caller) if (edge->inline_failed) reset_edge_growth_cache (edge); + for (i = 0; ipa_ref_list_refering_iterate (&where->ref_list, i, ref); i++) + if (ref->use == IPA_REF_ALIAS) + reset_edge_caches (ipa_ref_refering_node (ref)); if (!e) return; @@ -965,14 +982,23 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, struct cgraph_edge *check_inlinablity_for) { struct cgraph_edge *edge; + int i; + struct ipa_ref *ref; - if (!inline_summary (node)->inlinable + if ((!node->alias && !inline_summary (node)->inlinable) || cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE || node->global.inlined_to) return; if (!bitmap_set_bit (updated_nodes, node->uid)) return; + for (i = 0; ipa_ref_list_refering_iterate (&node->ref_list, i, ref); i++) + if (ref->use == IPA_REF_ALIAS) + { + struct cgraph_node *alias = ipa_ref_refering_node (ref); + update_caller_keys (heap, alias, updated_nodes, check_inlinablity_for); + } + for (edge = node->callers; edge; edge = edge->next_caller) if (edge->inline_failed) { @@ -1451,7 +1477,7 @@ inline_small_functions (void) where = edge->caller; while (where->global.inlined_to) { - if (where->decl == edge->callee->decl) + if (where->decl == callee->decl) outer_node = where, depth++; where = where->callers->caller; } @@ -1938,7 +1964,7 @@ struct gimple_opt_pass pass_early_inline = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -1972,7 +1998,7 @@ struct ipa_opt_pass_d pass_ipa_inline = 0, /* properties_provided */ 0, /* properties_destroyed */ TODO_remove_functions, /* todo_flags_finish */ - TODO_dump_cgraph | TODO_dump_func + TODO_dump_cgraph | TODO_remove_functions | TODO_ggc_collect /* todo_flags_finish */ }, inline_generate_summary, /* generate_summary */ diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index c4eccbc7fa0..10c11d41ae6 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -1347,7 +1347,8 @@ ipa_analyze_indirect_call_uses (struct cgraph_node *node, if (!branch || gimple_code (branch) != GIMPLE_COND) return; - if (gimple_cond_code (branch) != NE_EXPR + if ((gimple_cond_code (branch) != NE_EXPR + && gimple_cond_code (branch) != EQ_EXPR) || !integer_zerop (gimple_cond_rhs (branch))) return; @@ -1719,6 +1720,7 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target, tree delta) fprintf (dump_file, "\n"); } } + callee = cgraph_function_or_thunk_node (callee, NULL); if (ipa_get_cs_argument_count (IPA_EDGE_REF (ie)) != ipa_get_param_count (IPA_NODE_REF (callee))) @@ -2815,7 +2817,6 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node) lto_output_uleb128_stream (ob->main_stream, node_ref); bp = bitpack_create (ob->main_stream); - bp_pack_value (&bp, info->called_with_var_arguments, 1); gcc_assert (info->uses_analysis_done || ipa_get_param_count (info) == 0); gcc_assert (!info->node_enqueued); @@ -2858,7 +2859,6 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node, ipa_initialize_node_params (node); bp = lto_input_bitpack (ib); - info->called_with_var_arguments = bp_unpack_value (&bp, 1); if (ipa_get_param_count (info) != 0) info->uses_analysis_done = true; info->node_enqueued = false; @@ -2901,12 +2901,15 @@ void ipa_prop_write_jump_functions (cgraph_node_set set) { struct cgraph_node *node; - struct output_block *ob = create_output_block (LTO_section_jump_functions); + struct output_block *ob; unsigned int count = 0; cgraph_node_set_iterator csi; - ob->cgraph_node = NULL; + if (!ipa_node_params_vector) + return; + ob = create_output_block (LTO_section_jump_functions); + ob->cgraph_node = NULL; for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi)) { node = csi_node (csi); @@ -3015,9 +3018,12 @@ ipa_update_after_lto_read (void) if (node->analyzed) for (cs = node->callees; cs; cs = cs->next_callee) { + struct cgraph_node *callee; + + callee = cgraph_function_or_thunk_node (cs->callee, NULL); if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) - != ipa_get_param_count (IPA_NODE_REF (cs->callee))) - ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee)); + != ipa_get_param_count (IPA_NODE_REF (callee))) + ipa_set_called_with_variable_arg (IPA_NODE_REF (callee)); } } diff --git a/gcc/ipa-ref.c b/gcc/ipa-ref.c index db70e6e96af..8520bca33ac 100644 --- a/gcc/ipa-ref.c +++ b/gcc/ipa-ref.c @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "cgraph.h" -static const char *ipa_ref_use_name[] = {"read","write","addr"}; +static const char *ipa_ref_use_name[] = {"read","write","addr","alias"}; /* Return ipa reference from REFERING_NODE or REFERING_VARPOOL_NODE to REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type @@ -46,6 +46,7 @@ ipa_record_reference (struct cgraph_node *refering_node, gcc_assert ((!refering_node) ^ (!refering_varpool_node)); gcc_assert ((!refered_node) ^ (!refered_varpool_node)); gcc_assert (!stmt || refering_node); + gcc_assert (use_type != IPA_REF_ALIAS || !stmt); list = (refering_node ? &refering_node->ref_list : &refering_varpool_node->ref_list); @@ -67,13 +68,13 @@ ipa_record_reference (struct cgraph_node *refering_node, { ref->refering.varpool_node = refering_varpool_node; ref->refering_type = IPA_REF_VARPOOL; - gcc_assert (use_type == IPA_REF_ADDR); + gcc_assert (use_type == IPA_REF_ADDR || use_type == IPA_REF_ALIAS); } if (refered_node) { ref->refered.cgraph_node = refered_node; ref->refered_type = IPA_REF_CGRAPH; - gcc_assert (use_type == IPA_REF_ADDR); + gcc_assert (use_type == IPA_REF_ADDR || use_type == IPA_REF_ALIAS); } else { @@ -241,3 +242,15 @@ ipa_ref_cannot_lead_to_return (struct ipa_ref *ref) { return cgraph_node_cannot_return (ipa_ref_refering_node (ref)); } + +/* Return true if list contains an alias. */ +bool +ipa_ref_has_aliases_p (struct ipa_ref_list *ref_list) +{ + struct ipa_ref *ref; + int i; + for (i = 0; ipa_ref_list_refering_iterate (ref_list, i, ref); i++) + if (ref->use == IPA_REF_ALIAS) + return true; + return false; +} diff --git a/gcc/ipa-ref.h b/gcc/ipa-ref.h index 2be73536f8e..2fdb6ba4158 100644 --- a/gcc/ipa-ref.h +++ b/gcc/ipa-ref.h @@ -27,7 +27,8 @@ enum GTY(()) ipa_ref_use { IPA_REF_LOAD, IPA_REF_STORE, - IPA_REF_ADDR + IPA_REF_ADDR, + IPA_REF_ALIAS }; /* Type of refering or refered type. */ @@ -89,4 +90,4 @@ void ipa_dump_refering (FILE *, struct ipa_ref_list *); void ipa_clone_references (struct cgraph_node *, struct varpool_node *, struct ipa_ref_list *); void ipa_clone_refering (struct cgraph_node *, struct varpool_node *, struct ipa_ref_list *); bool ipa_ref_cannot_lead_to_return (struct ipa_ref *); - +bool ipa_ref_has_aliases_p (struct ipa_ref_list *); diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 2e672874024..7413d81aeee 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -1432,7 +1432,7 @@ struct gimple_opt_pass pass_split_functions = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -1473,6 +1473,6 @@ struct gimple_opt_pass pass_feedback_split_functions = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c index ae207369d18..0a462ef25b5 100644 --- a/gcc/ipa-utils.c +++ b/gcc/ipa-utils.c @@ -233,8 +233,16 @@ ipa_free_postorder_info (void) } } +struct postorder_stack +{ + struct cgraph_node *node; + struct cgraph_edge *edge; + int ref; +}; + /* Fill array order with all nodes with output flag set in the reverse - topological order. Return the number of elements in the array. */ + topological order. Return the number of elements in the array. + FIXME: While walking, consider aliases, too. */ int ipa_reverse_postorder (struct cgraph_node **order) @@ -242,11 +250,12 @@ ipa_reverse_postorder (struct cgraph_node **order) struct cgraph_node *node, *node2; int stack_size = 0; int order_pos = 0; - struct cgraph_edge *edge, last; + struct cgraph_edge *edge; int pass; + struct ipa_ref *ref; - struct cgraph_node **stack = - XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); + struct postorder_stack *stack = + XCNEWVEC (struct postorder_stack, cgraph_n_nodes); /* We have to deal with cycles nicely, so use a depth first traversal output algorithm. Ignore the fact that some functions won't need @@ -260,47 +269,51 @@ ipa_reverse_postorder (struct cgraph_node **order) && (pass || (!node->address_taken && !node->global.inlined_to + && !node->alias && !node->thunk.thunk_p && !cgraph_only_called_directly_p (node)))) { - node2 = node; - if (!node->callers) - node->aux = &last; - else - node->aux = node->callers; - while (node2) + stack_size = 0; + stack[stack_size].node = node; + stack[stack_size].edge = node->callers; + stack[stack_size].ref = 0; + node->aux = (void *)(size_t)1; + while (stack_size >= 0) { - while (node2->aux != &last) + while (true) { - edge = (struct cgraph_edge *) node2->aux; - if (edge->next_caller) - node2->aux = edge->next_caller; - else - node2->aux = &last; - /* Break possible cycles involving always-inline - functions by ignoring edges from always-inline - functions to non-always-inline functions. */ - if (DECL_DISREGARD_INLINE_LIMITS (edge->caller->decl) - && !DECL_DISREGARD_INLINE_LIMITS (edge->callee->decl)) - continue; - if (!edge->caller->aux) + node2 = NULL; + while (stack[stack_size].edge && !node2) { - if (!edge->caller->callers) - edge->caller->aux = &last; - else - edge->caller->aux = edge->caller->callers; - stack[stack_size++] = node2; + edge = stack[stack_size].edge; node2 = edge->caller; - break; + stack[stack_size].edge = edge->next_caller; + /* Break possible cycles involving always-inline + functions by ignoring edges from always-inline + functions to non-always-inline functions. */ + if (DECL_DISREGARD_INLINE_LIMITS (edge->caller->decl) + && !DECL_DISREGARD_INLINE_LIMITS + (cgraph_function_node (edge->callee, NULL)->decl)) + node2 = NULL; + } + for (;ipa_ref_list_refering_iterate (&stack[stack_size].node->ref_list, + stack[stack_size].ref, + ref) && !node2; + stack[stack_size].ref++) + { + if (ref->use == IPA_REF_ALIAS) + node2 = ipa_ref_refering_node (ref); + } + if (!node2) + break; + if (!node2->aux) + { + stack[++stack_size].node = node2; + stack[stack_size].edge = node2->callers; + stack[stack_size].ref = 0; + node2->aux = (void *)(size_t)1; } } - if (node2->aux == &last) - { - order[order_pos++] = node2; - if (stack_size) - node2 = stack[--stack_size]; - else - node2 = NULL; - } + order[order_pos++] = stack[stack_size--].node; } } free (stack); diff --git a/gcc/ipa.c b/gcc/ipa.c index 7822cfde371..260cc26cc6f 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -119,7 +119,9 @@ process_references (struct ipa_ref_list *list, static bool cgraph_non_local_node_p_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) { + /* FIXME: Aliases can be local, but i386 gets thunks wrong then. */ return !(cgraph_only_called_directly_or_aliased_p (node) + && !ipa_ref_has_aliases_p (&node->ref_list) && node->analyzed && !DECL_EXTERNAL (node->decl) && !node->local.externally_visible @@ -132,7 +134,13 @@ cgraph_non_local_node_p_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED static bool cgraph_local_node_p (struct cgraph_node *node) { - return !cgraph_for_node_and_aliases (cgraph_function_or_thunk_node (node, NULL), + struct cgraph_node *n = cgraph_function_or_thunk_node (node, NULL); + + /* FIXME: thunks can be considered local, but we need prevent i386 + from attempting to change calling convention of them. */ + if (n->thunk.thunk_p) + return false; + return !cgraph_for_node_and_aliases (n, cgraph_non_local_node_p_1, NULL, true); } @@ -535,14 +543,15 @@ cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node) int i; struct ipa_ref *ref; for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++) - { - struct varpool_node *node; - if (ref->refered_type == IPA_REF_CGRAPH) - return true; - node = ipa_ref_varpool_node (ref); - if (!DECL_VIRTUAL_P (node->decl)) - return true; - } + if (ref->use == IPA_REF_ADDR) + { + struct varpool_node *node; + if (ref->refered_type == IPA_REF_CGRAPH) + return true; + node = ipa_ref_varpool_node (ref); + if (!DECL_VIRTUAL_P (node->decl)) + return true; + } return false; } @@ -571,7 +580,7 @@ cgraph_comdat_can_be_unshared_p (struct cgraph_node *node) address taken. */ for (next = node->same_comdat_group; next != node; next = next->same_comdat_group) - if (cgraph_address_taken_from_non_vtable_p (node) + if (cgraph_address_taken_from_non_vtable_p (next) && !DECL_VIRTUAL_P (next->decl)) return false; } @@ -581,9 +590,9 @@ cgraph_comdat_can_be_unshared_p (struct cgraph_node *node) /* Return true when function NODE should be considered externally visible. */ static bool -cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program, bool aliased) +cgraph_externally_visible_p (struct cgraph_node *node, + bool whole_program, bool aliased) { - struct cgraph_node *alias; if (!node->local.finalized) return false; if (!DECL_COMDAT (node->decl) @@ -603,14 +612,6 @@ cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program, bool if (DECL_BUILT_IN (node->decl)) return true; - /* FIXME: We get wrong symbols with asm aliases in callgraph and LTO. - This is because very little of code knows that assembler name needs to - mangled. Avoid touching declarations with user asm name set to mask - some of the problems. */ - if (DECL_ASSEMBLER_NAME_SET_P (node->decl) - && IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl))[0]=='*') - return true; - /* If linker counts on us, we must preserve the function. */ if (cgraph_used_from_object_file_p (node)) return true; @@ -621,6 +622,8 @@ cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program, bool if (TARGET_DLLIMPORT_DECL_ATTRIBUTES && lookup_attribute ("dllexport", DECL_ATTRIBUTES (node->decl))) return true; + if (node->resolution == LDPR_PREVAILING_DEF_IRONLY) + return false; /* When doing LTO or whole program, we can bring COMDAT functoins static. This improves code quality and we know we will duplicate them at most twice (in the case that we are not using plugin and link with object file @@ -630,18 +633,6 @@ cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program, bool && cgraph_comdat_can_be_unshared_p (node)) return false; - /* See if we have linker information about symbol not being used or - if we need to make guess based on the declaration. - - Even if the linker clams the symbol is unused, never bring internal - symbols that are declared by user as used or externally visible. - This is needed for i.e. references from asm statements. */ - for (alias = node->same_body; alias; alias = alias->next) - if (alias->resolution != LDPR_PREVAILING_DEF_IRONLY) - break; - if (!alias && node->resolution == LDPR_PREVAILING_DEF_IRONLY) - return false; - /* When doing link time optimizations, hidden symbols become local. */ if (in_lto_p && (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN @@ -664,7 +655,6 @@ cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program, bool static bool varpool_externally_visible_p (struct varpool_node *vnode, bool aliased) { - struct varpool_node *alias; if (!DECL_COMDAT (vnode->decl) && !TREE_PUBLIC (vnode->decl)) return false; @@ -677,14 +667,6 @@ varpool_externally_visible_p (struct varpool_node *vnode, bool aliased) if (varpool_used_from_object_file_p (vnode)) return true; - /* FIXME: We get wrong symbols with asm aliases in callgraph and LTO. - This is because very little of code knows that assembler name needs to - mangled. Avoid touching declarations with user asm name set to mask - some of the problems. */ - if (DECL_ASSEMBLER_NAME_SET_P (vnode->decl) - && IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (vnode->decl))[0]=='*') - return true; - if (DECL_PRESERVE_P (vnode->decl)) return true; if (lookup_attribute ("externally_visible", @@ -703,11 +685,6 @@ varpool_externally_visible_p (struct varpool_node *vnode, bool aliased) This is needed for i.e. references from asm statements. */ if (varpool_used_from_object_file_p (vnode)) return true; - for (alias = vnode->extra_name; alias; alias = alias->next) - if (alias->resolution != LDPR_PREVAILING_DEF_IRONLY) - break; - if (!alias && vnode->resolution == LDPR_PREVAILING_DEF_IRONLY) - return false; /* As a special case, the COMDAT virutal tables can be unshared. In LTO mode turn vtables into static variables. The variable is readonly, @@ -791,13 +768,7 @@ function_and_variable_visibility (bool whole_program) { if (!node->analyzed) continue; - /* Weakrefs alias symbols from other compilation unit. In the case - the destination of weakref became available because of LTO, we must - mark it as needed. */ - if (in_lto_p - && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) - && !node->needed) - cgraph_mark_needed_node (node); + cgraph_mark_needed_node (node); gcc_assert (node->needed); pointer_set_insert (aliased_nodes, node); if (dump_file) @@ -807,13 +778,7 @@ function_and_variable_visibility (bool whole_program) else if ((vnode = varpool_node_for_asm (p->target)) != NULL && !DECL_EXTERNAL (vnode->decl)) { - /* Weakrefs alias symbols from other compilation unit. In the case - the destination of weakref became available because of LTO, we must - mark it as needed. */ - if (in_lto_p - && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) - && !vnode->needed) - varpool_mark_needed_node (vnode); + varpool_mark_needed_node (vnode); gcc_assert (vnode->needed); pointer_set_insert (aliased_vnodes, vnode); if (dump_file) @@ -881,12 +846,9 @@ function_and_variable_visibility (bool whole_program) if (!node->local.externally_visible && node->analyzed && !DECL_EXTERNAL (node->decl)) { - struct cgraph_node *alias; gcc_assert (whole_program || in_lto_p || !TREE_PUBLIC (node->decl)); cgraph_make_decl_local (node->decl); node->resolution = LDPR_PREVAILING_DEF_IRONLY; - for (alias = node->same_body; alias; alias = alias->next) - cgraph_make_decl_local (alias->decl); if (node->same_comdat_group) /* cgraph_externally_visible_p has already checked all other nodes in the group and they will all be made local. We need to @@ -900,8 +862,7 @@ function_and_variable_visibility (bool whole_program) { struct cgraph_node *decl_node = node; - while (decl_node->thunk.thunk_p) - decl_node = decl_node->callees->callee; + decl_node = cgraph_function_node (decl_node->callees->callee, NULL); /* Thunks have the same visibility as function they are attached to. For some reason C++ frontend don't seem to care. I.e. in @@ -910,9 +871,9 @@ function_and_variable_visibility (bool whole_program) We also need to arrange the thunk into the same comdat group as the function it reffers to. */ - if (DECL_COMDAT (decl_node->decl)) + if (DECL_ONE_ONLY (decl_node->decl)) { - DECL_COMDAT (node->decl) = 1; + DECL_COMDAT (node->decl) = DECL_COMDAT (decl_node->decl); DECL_COMDAT_GROUP (node->decl) = DECL_COMDAT_GROUP (decl_node->decl); if (DECL_ONE_ONLY (decl_node->decl) && !node->same_comdat_group) { @@ -933,9 +894,9 @@ function_and_variable_visibility (bool whole_program) if (DECL_EXTERNAL (decl_node->decl)) DECL_EXTERNAL (node->decl) = 1; } - node->local.local = cgraph_local_node_p (node); - } + for (node = cgraph_nodes; node; node = node->next) + node->local.local = cgraph_local_node_p (node); for (vnode = varpool_nodes; vnode; vnode = vnode->next) { /* weak flag makes no sense on local variables. */ diff --git a/gcc/ira.c b/gcc/ira.c index 222d48eb1c4..5cfe5c0fa6b 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -3806,7 +3806,6 @@ struct rtl_opt_pass pass_ira = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } }; diff --git a/gcc/jump.c b/gcc/jump.c index 1c64b85d408..f337eb3add0 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -156,7 +156,7 @@ struct rtl_opt_pass pass_cleanup_barriers = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; diff --git a/gcc/longlong.h b/gcc/longlong.h index 1bab76db33a..7d11e10646e 100644 --- a/gcc/longlong.h +++ b/gcc/longlong.h @@ -1,6 +1,6 @@ /* longlong.h -- definitions for mixed size 32/64 bit arithmetic. Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -250,6 +250,12 @@ UDItype __umulsidi3 (USItype, USItype); #define COUNT_LEADING_ZEROS_0 32 #endif +#if defined (__AVR__) && W_TYPE_SIZE == 32 +#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clzl (X)) +#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzl (X)) +#define COUNT_LEADING_ZEROS_0 32 +#endif /* defined (__AVR__) && W_TYPE_SIZE == 32 */ + #if defined (__CRIS__) && __CRIS_arch_version >= 3 #define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) #if __CRIS_arch_version >= 8 @@ -430,8 +436,8 @@ UDItype __umulsidi3 (USItype, USItype); : "0" ((UDItype) (n0)), \ "1" ((UDItype) (n1)), \ "rm" ((UDItype) (dv))) -#define count_leading_zeros(count, x) ((count) = __builtin_clzl (x)) -#define count_trailing_zeros(count, x) ((count) = __builtin_ctzl (x)) +#define count_leading_zeros(count, x) ((count) = __builtin_clzll (x)) +#define count_trailing_zeros(count, x) ((count) = __builtin_ctzll (x)) #define UMUL_TIME 40 #define UDIV_TIME 40 #endif /* x86_64 */ diff --git a/gcc/loop-init.c b/gcc/loop-init.c index bd4af30c5c5..9184a148c40 100644 --- a/gcc/loop-init.c +++ b/gcc/loop-init.c @@ -158,7 +158,6 @@ struct rtl_opt_pass pass_loop2 = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } }; @@ -192,7 +191,7 @@ struct rtl_opt_pass pass_rtl_loop_init = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_rtl_sharing /* todo_flags_finish */ + TODO_verify_rtl_sharing /* todo_flags_finish */ } }; @@ -228,8 +227,7 @@ struct rtl_opt_pass pass_rtl_loop_done = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_verify_flow - | TODO_verify_rtl_sharing - | TODO_dump_func /* todo_flags_finish */ + | TODO_verify_rtl_sharing /* todo_flags_finish */ } }; @@ -265,8 +263,7 @@ struct rtl_opt_pass pass_rtl_move_loop_invariants = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_verify | - TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func /* todo_flags_finish */ + TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */ } }; @@ -301,7 +298,7 @@ struct rtl_opt_pass pass_rtl_unswitch = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_rtl_sharing, /* todo_flags_finish */ + TODO_verify_rtl_sharing, /* todo_flags_finish */ } }; @@ -349,7 +346,7 @@ struct rtl_opt_pass pass_rtl_unroll_and_peel_loops = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_rtl_sharing, /* todo_flags_finish */ + TODO_verify_rtl_sharing, /* todo_flags_finish */ } }; @@ -390,7 +387,6 @@ struct rtl_opt_pass pass_rtl_doloop = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_rtl_sharing /* todo_flags_finish */ + TODO_verify_rtl_sharing /* todo_flags_finish */ } }; - diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c index 2119c0902b3..85aa29891bf 100644 --- a/gcc/lower-subreg.c +++ b/gcc/lower-subreg.c @@ -1370,7 +1370,6 @@ struct rtl_opt_pass pass_lower_subreg = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_ggc_collect | TODO_verify_flow /* todo_flags_finish */ } @@ -1392,7 +1391,6 @@ struct rtl_opt_pass pass_lower_subreg2 = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_ggc_collect | TODO_verify_flow /* todo_flags_finish */ } diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index 3b1115b53f6..9d9cb4366a0 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -504,7 +504,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, || referenced_from_other_partition_p (&node->ref_list, set, vset)), 1); bp_pack_value (&bp, node->lowered, 1); bp_pack_value (&bp, in_other_partition, 1); - bp_pack_value (&bp, node->alias, 1); + bp_pack_value (&bp, node->alias && !boundary_p, 1); bp_pack_value (&bp, node->frequency, 2); bp_pack_value (&bp, node->only_called_at_startup, 1); bp_pack_value (&bp, node->only_called_at_exit, 1); @@ -523,32 +523,15 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, node->thunk.fixed_offset); lto_output_uleb128_stream (ob->main_stream, node->thunk.virtual_value); - lto_output_fn_decl_index (ob->decl_state, ob->main_stream, - node->thunk.alias); } - - if (node->same_body) + if ((node->alias || node->thunk.thunk_p) && !boundary_p) { - struct cgraph_node *alias; - unsigned long alias_count = 1; - for (alias = node->same_body; alias->next; alias = alias->next) - alias_count++; - lto_output_uleb128_stream (ob->main_stream, alias_count); - do - { - lto_output_fn_decl_index (ob->decl_state, ob->main_stream, - alias->decl); - lto_output_fn_decl_index (ob->decl_state, ob->main_stream, - alias->thunk.alias); - gcc_assert (cgraph_get_node (alias->thunk.alias) == node); - lto_output_enum (ob->main_stream, ld_plugin_symbol_resolution, - LDPR_NUM_KNOWN, alias->resolution); - alias = alias->previous; - } - while (alias); + lto_output_int_in_range (ob->main_stream, 0, 1, + node->thunk.alias != NULL); + if (node->thunk.alias != NULL) + lto_output_fn_decl_index (ob->decl_state, ob->main_stream, + node->thunk.alias); } - else - lto_output_uleb128_stream (ob->main_stream, 0); } /* Output the varpool NODE to OB. @@ -561,8 +544,6 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node { bool boundary_p = !varpool_node_in_set_p (node, vset) && node->analyzed; struct bitpack_d bp; - struct varpool_node *alias; - int count = 0; int ref; lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->decl); @@ -571,7 +552,7 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node bp_pack_value (&bp, node->force_output, 1); bp_pack_value (&bp, node->finalized, 1); bp_pack_value (&bp, node->alias, 1); - gcc_assert (!node->alias || !node->extra_name); + bp_pack_value (&bp, node->alias_of != NULL, 1); gcc_assert (node->finalized || !node->analyzed); gcc_assert (node->needed); /* Constant pool initializers can be de-unified into individual ltrans units. @@ -590,11 +571,9 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node set, vset), 1); bp_pack_value (&bp, boundary_p, 1); /* in_other_partition. */ } - /* Also emit any extra name aliases. */ - for (alias = node->extra_name; alias; alias = alias->next) - count++; - bp_pack_value (&bp, count != 0, 1); lto_output_bitpack (&bp); + if (node->alias_of) + lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->alias_of); if (node->same_comdat_group && !boundary_p) { ref = lto_varpool_encoder_lookup (varpool_encoder, node->same_comdat_group); @@ -605,17 +584,6 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node lto_output_sleb128_stream (ob->main_stream, ref); lto_output_enum (ob->main_stream, ld_plugin_symbol_resolution, LDPR_NUM_KNOWN, node->resolution); - - if (count) - { - lto_output_uleb128_stream (ob->main_stream, count); - for (alias = node->extra_name; alias; alias = alias->next) - { - lto_output_var_decl_index (ob->decl_state, ob->main_stream, alias->decl); - lto_output_enum (ob->main_stream, ld_plugin_symbol_resolution, - LDPR_NUM_KNOWN, alias->resolution); - } - } } /* Output the varpool NODE to OB. @@ -797,7 +765,7 @@ compute_ltrans_boundary (struct lto_out_decl_state *state, for (vsi = vsi_start (vset); !vsi_end_p (vsi); vsi_next (&vsi)) { struct varpool_node *vnode = vsi_node (vsi); - gcc_assert (!vnode->alias); + gcc_assert (!vnode->alias || vnode->alias_of); lto_varpool_encoder_encode (varpool_encoder, vnode); lto_set_varpool_encoder_encode_initializer (varpool_encoder, vnode); add_references (encoder, varpool_encoder, &vnode->ref_list); @@ -997,7 +965,6 @@ input_node (struct lto_file_decl_data *file_data, struct bitpack_d bp; unsigned decl_index; int ref = LCC_NOT_FOUND, ref2 = LCC_NOT_FOUND; - unsigned long same_body_count = 0; int clone_ref; clone_ref = lto_input_sleb128 (ib); @@ -1043,31 +1010,20 @@ input_node (struct lto_file_decl_data *file_data, int type = lto_input_uleb128 (ib); HOST_WIDE_INT fixed_offset = lto_input_uleb128 (ib); HOST_WIDE_INT virtual_value = lto_input_uleb128 (ib); - tree real_alias; - decl_index = lto_input_uleb128 (ib); - real_alias = lto_file_decl_data_get_fn_decl (file_data, decl_index); node->thunk.fixed_offset = fixed_offset; node->thunk.this_adjusting = (type & 2); node->thunk.virtual_value = virtual_value; node->thunk.virtual_offset_p = (type & 4); - node->thunk.alias = real_alias; } - - same_body_count = lto_input_uleb128 (ib); - while (same_body_count-- > 0) + if (node->thunk.thunk_p || node->alias) { - tree alias_decl, real_alias; - struct cgraph_node *alias; - - decl_index = lto_input_uleb128 (ib); - alias_decl = lto_file_decl_data_get_fn_decl (file_data, decl_index); - decl_index = lto_input_uleb128 (ib); - real_alias = lto_file_decl_data_get_fn_decl (file_data, decl_index); - alias = cgraph_same_body_alias (node, alias_decl, real_alias); - gcc_assert (alias); - alias->resolution = lto_input_enum (ib, ld_plugin_symbol_resolution, - LDPR_NUM_KNOWN); + if (lto_input_int_in_range (ib, "alias nonzero flag", 0, 1)) + { + decl_index = lto_input_uleb128 (ib); + node->thunk.alias = lto_file_decl_data_get_fn_decl (file_data, + decl_index); + } } return node; } @@ -1083,9 +1039,8 @@ input_varpool_node (struct lto_file_decl_data *file_data, tree var_decl; struct varpool_node *node; struct bitpack_d bp; - bool aliases_p; - int count; int ref = LCC_NOT_FOUND; + bool non_null_aliasof; decl_index = lto_input_uleb128 (ib); var_decl = lto_file_decl_data_get_var_decl (file_data, decl_index); @@ -1097,6 +1052,7 @@ input_varpool_node (struct lto_file_decl_data *file_data, node->force_output = bp_unpack_value (&bp, 1); node->finalized = bp_unpack_value (&bp, 1); node->alias = bp_unpack_value (&bp, 1); + non_null_aliasof = bp_unpack_value (&bp, 1); node->analyzed = node->finalized; node->used_from_other_partition = bp_unpack_value (&bp, 1); node->in_other_partition = bp_unpack_value (&bp, 1); @@ -1105,27 +1061,19 @@ input_varpool_node (struct lto_file_decl_data *file_data, DECL_EXTERNAL (node->decl) = 1; TREE_STATIC (node->decl) = 0; } - aliases_p = bp_unpack_value (&bp, 1); if (node->finalized) varpool_mark_needed_node (node); + if (non_null_aliasof) + { + decl_index = lto_input_uleb128 (ib); + node->alias_of = lto_file_decl_data_get_var_decl (file_data, decl_index); + } ref = lto_input_sleb128 (ib); /* Store a reference for now, and fix up later to be a pointer. */ node->same_comdat_group = (struct varpool_node *) (intptr_t) ref; node->resolution = lto_input_enum (ib, ld_plugin_symbol_resolution, LDPR_NUM_KNOWN); - if (aliases_p) - { - count = lto_input_uleb128 (ib); - for (; count > 0; count --) - { - tree decl = lto_file_decl_data_get_var_decl (file_data, - lto_input_uleb128 (ib)); - struct varpool_node *alias; - alias = varpool_extra_name_alias (decl, var_decl); - alias->resolution = lto_input_enum (ib, ld_plugin_symbol_resolution, - LDPR_NUM_KNOWN); - } - } + return node; } diff --git a/gcc/lto-opts.c b/gcc/lto-opts.c index 3cff0ee7430..296739ed738 100644 --- a/gcc/lto-opts.c +++ b/gcc/lto-opts.c @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "opts.h" #include "options.h" -#include "target.h" +#include "common/common-target.h" #include "diagnostic.h" #include "lto-streamer.h" @@ -405,8 +405,8 @@ lto_reissue_options (void) { struct cl_decoded_option decoded; generate_option (o->code, o->arg, o->value, CL_TARGET, &decoded); - targetm.handle_option (&global_options, &global_options_set, - &decoded, UNKNOWN_LOCATION); + targetm_common.handle_option (&global_options, &global_options_set, + &decoded, UNKNOWN_LOCATION); } else if (o->type == CL_COMMON) gcc_assert (flag_var); diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index 02ac9583ace..19b0ae8bb1e 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -1117,7 +1117,11 @@ lto_output_ts_binfo_tree_pointers (struct output_block *ob, tree expr, lto_output_tree_or_ref (ob, BINFO_OFFSET (expr), ref_p); lto_output_tree_or_ref (ob, BINFO_VTABLE (expr), ref_p); - lto_output_tree_or_ref (ob, BINFO_VIRTUALS (expr), ref_p); + /* BINFO_VIRTUALS is used to drive type based devirtualizatoin. It often links + together large portions of programs making it harder to partition. Becuase + devirtualization is interesting before inlining, only, there is no real + need to ship it into ltrans partition. */ + lto_output_tree_or_ref (ob, flag_wpa ? NULL : BINFO_VIRTUALS (expr), ref_p); lto_output_tree_or_ref (ob, BINFO_VPTR_FIELD (expr), ref_p); output_uleb128 (ob, VEC_length (tree, BINFO_BASE_ACCESSES (expr))); @@ -2253,6 +2257,7 @@ lto_output (cgraph_node_set set, varpool_node_set vset) { node = lto_cgraph_encoder_deref (encoder, i); if (lto_cgraph_encoder_encode_body_p (encoder, node) + && !node->alias && !node->thunk.thunk_p) { #ifdef ENABLE_CHECKING @@ -2297,7 +2302,7 @@ struct ipa_opt_pass_d pass_ipa_lto_gimple_out = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ }, NULL, /* generate_summary */ lto_output, /* write_summary */ @@ -2551,8 +2556,8 @@ produce_symtab (struct output_block *ob, struct lto_streamer_cache_d *cache = ob->writer_cache; char *section_name = lto_get_section_name (LTO_section_symtab, NULL, NULL); struct pointer_set_t *seen; - struct cgraph_node *node, *alias; - struct varpool_node *vnode, *valias; + struct cgraph_node *node; + struct varpool_node *vnode; struct lto_output_stream stream; lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder; lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder; @@ -2581,11 +2586,9 @@ produce_symtab (struct output_block *ob, if (DECL_COMDAT (node->decl) && cgraph_comdat_can_be_unshared_p (node)) continue; - if (node->alias || node->global.inlined_to) + if ((node->alias && !node->thunk.alias) || node->global.inlined_to) continue; write_symbol (cache, &stream, node->decl, seen, false); - for (alias = node->same_body; alias; alias = alias->next) - write_symbol (cache, &stream, alias->decl, seen, true); } for (i = 0; i < lto_cgraph_encoder_size (encoder); i++) { @@ -2595,11 +2598,9 @@ produce_symtab (struct output_block *ob, if (DECL_COMDAT (node->decl) && cgraph_comdat_can_be_unshared_p (node)) continue; - if (node->alias || node->global.inlined_to) + if ((node->alias && !node->thunk.alias) || node->global.inlined_to) continue; write_symbol (cache, &stream, node->decl, seen, false); - for (alias = node->same_body; alias; alias = alias->next) - write_symbol (cache, &stream, alias->decl, seen, true); } /* Write all variables. */ @@ -2616,11 +2617,9 @@ produce_symtab (struct output_block *ob, && vnode->finalized && DECL_VIRTUAL_P (vnode->decl)) continue; - if (vnode->alias) + if (vnode->alias && !vnode->alias_of) continue; write_symbol (cache, &stream, vnode->decl, seen, false); - for (valias = vnode->extra_name; valias; valias = valias->next) - write_symbol (cache, &stream, valias->decl, seen, true); } for (i = 0; i < lto_varpool_encoder_size (varpool_encoder); i++) { @@ -2632,11 +2631,9 @@ produce_symtab (struct output_block *ob, && vnode->finalized && DECL_VIRTUAL_P (vnode->decl)) continue; - if (vnode->alias) + if (vnode->alias && !vnode->alias_of) continue; write_symbol (cache, &stream, vnode->decl, seen, false); - for (valias = vnode->extra_name; valias; valias = valias->next) - write_symbol (cache, &stream, valias->decl, seen, true); } /* Write all aliases. */ diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c index af8106de94f..2bbf064ee7d 100644 --- a/gcc/lto-symtab.c +++ b/gcc/lto-symtab.c @@ -209,7 +209,6 @@ lto_cgraph_replace_node (struct cgraph_node *node, struct cgraph_node *prevailing_node) { struct cgraph_edge *e, *next; - bool no_aliases_please = false; bool compatible_p; if (cgraph_dump_file) @@ -223,13 +222,6 @@ lto_cgraph_replace_node (struct cgraph_node *node, (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl))))); } - if (prevailing_node->same_body_alias) - { - if (prevailing_node->thunk.thunk_p) - no_aliases_please = true; - prevailing_node = prevailing_node->same_body; - } - /* Merge node flags. */ if (node->needed) cgraph_mark_needed_node (prevailing_node); @@ -259,36 +251,8 @@ lto_cgraph_replace_node (struct cgraph_node *node, /* Redirect incomming references. */ ipa_clone_refering (prevailing_node, NULL, &node->ref_list); - /* If we have aliases, redirect them to the prevailing node. */ - if (!node->same_body_alias && node->same_body) - { - struct cgraph_node *alias, *last; - /* We prevail aliases/tunks by a thunk. This is doable but - would need thunk combination. Hopefully no ABI changes will - every be crazy enough. */ - gcc_assert (!no_aliases_please); - - for (alias = node->same_body; alias; alias = alias->next) - { - last = alias; - gcc_assert (alias->same_body_alias); - alias->same_body = prevailing_node; - } - last->next = prevailing_node->same_body; - /* Node with aliases is prevailed by alias. - We could handle this, but combining thunks together will be tricky. - Hopefully this does not happen. */ - if (prevailing_node->same_body) - prevailing_node->same_body->previous = last; - prevailing_node->same_body = node->same_body; - node->same_body = NULL; - } - /* Finally remove the replaced node. */ - if (node->same_body_alias) - cgraph_remove_same_body_alias (node); - else - cgraph_remove_node (node); + cgraph_remove_node (node); } /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging @@ -304,32 +268,9 @@ lto_varpool_replace_node (struct varpool_node *vnode, gcc_assert (!vnode->analyzed || prevailing_node->analyzed); varpool_mark_needed_node (prevailing_node); } - /* Relink aliases. */ - if (vnode->extra_name && !vnode->alias) - { - struct varpool_node *alias, *last; - for (alias = vnode->extra_name; - alias; alias = alias->next) - { - last = alias; - alias->extra_name = prevailing_node; - } - - if (prevailing_node->extra_name) - { - last->next = prevailing_node->extra_name; - prevailing_node->extra_name->prev = last; - } - prevailing_node->extra_name = vnode->extra_name; - vnode->extra_name = NULL; - } gcc_assert (!vnode->finalized || prevailing_node->finalized); gcc_assert (!vnode->analyzed || prevailing_node->analyzed); - /* When replacing by an alias, the references goes to the original - variable. */ - if (prevailing_node->alias && prevailing_node->extra_name) - prevailing_node = prevailing_node->extra_name; ipa_clone_refering (NULL, prevailing_node, &vnode->ref_list); /* Be sure we can garbage collect the initializer. */ @@ -472,18 +413,13 @@ lto_symtab_resolve_can_prevail_p (lto_symtab_entry_t e) /* For functions we need a non-discarded body. */ if (TREE_CODE (e->decl) == FUNCTION_DECL) - return (e->node - && (e->node->analyzed - || (e->node->same_body_alias && e->node->same_body->analyzed))); + return (e->node && e->node->analyzed); - /* A variable should have a size. */ else if (TREE_CODE (e->decl) == VAR_DECL) { if (!e->vnode) return false; - if (e->vnode->finalized) - return true; - return e->vnode->alias && e->vnode->extra_name->finalized; + return e->vnode->finalized; } gcc_unreachable (); @@ -816,20 +752,18 @@ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED) void lto_symtab_merge_cgraph_nodes (void) { - struct cgraph_node *node, *alias, *next; + struct cgraph_node *node; + struct varpool_node *vnode; lto_symtab_maybe_init_hash_table (); htab_traverse (lto_symtab_identifiers, lto_symtab_merge_cgraph_nodes_1, NULL); for (node = cgraph_nodes; node; node = node->next) - { - if (node->thunk.thunk_p) - node->thunk.alias = lto_symtab_prevailing_decl (node->thunk.alias); - for (alias = node->same_body; alias; alias = next) - { - next = alias->next; - alias->thunk.alias = lto_symtab_prevailing_decl (alias->thunk.alias); - } - } + if ((node->thunk.thunk_p || node->alias) + && node->thunk.alias) + node->thunk.alias = lto_symtab_prevailing_decl (node->thunk.alias); + for (vnode = varpool_nodes; vnode; vnode = vnode->next) + if (vnode->alias_of) + vnode->alias_of = lto_symtab_prevailing_decl (vnode->alias_of); } /* Given the decl DECL, return the prevailing decl with the same name. */ diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 44265df529f..27bc01563e3 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,18 @@ +2011-06-11 Jan Hubicka <jh@suse.cz> + + PR lto/48246 + * lto.c (lto_1_to_1_map): Don't create empty partitions. + (lto_balanced_map): Likewise. + +2011-06-11 Jan Hubicka <jh@suse.cz> + + * lto.c (add_cgraph_node_to_partition_1): Break out from ... + (add_cgraph_node_to_partition) ... here; walk aliases. + (lto_1_to_1_map): Remove same body alias code. + (promote_fn): Likewise. + (lto_promote_cross_file_statics): Update comment. + + 2011-06-07 Diego Novillo <dnovillo@google.com> * lto.c (uniquify_nodes): Move code to register decls to diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 6e49ee77b59..4323c4fa6f4 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -1319,7 +1319,7 @@ add_references_to_partition (ltrans_partition part, struct ipa_ref_list *refs) for (i = 0; ipa_ref_list_reference_iterate (refs, i, ref); i++) { if (ref->refered_type == IPA_REF_CGRAPH - && DECL_COMDAT (ipa_ref_node (ref)->decl) + && DECL_COMDAT (cgraph_function_node (ipa_ref_node (ref), NULL)->decl) && !cgraph_node_in_set_p (ipa_ref_node (ref), part->cgraph_set)) add_cgraph_node_to_partition (part, ipa_ref_node (ref)); else @@ -1330,6 +1330,34 @@ add_references_to_partition (ltrans_partition part, struct ipa_ref_list *refs) } } +/* Worker for add_cgraph_node_to_partition. */ + +static bool +add_cgraph_node_to_partition_1 (struct cgraph_node *node, void *data) +{ + ltrans_partition part = (ltrans_partition) data; + + /* non-COMDAT aliases of COMDAT functions needs to be output just once. */ + if (!DECL_COMDAT (node->decl) + && !node->global.inlined_to + && node->aux) + { + gcc_assert (node->thunk.thunk_p || node->alias); + return false; + } + + if (node->aux) + { + node->in_other_partition = 1; + if (cgraph_dump_file) + fprintf (cgraph_dump_file, "Node %s/%i now used in multiple partitions\n", + cgraph_node_name (node), node->uid); + } + node->aux = (void *)((size_t)node->aux + 1); + cgraph_node_set_add (part->cgraph_set, node); + return false; +} + /* Add NODE to partition as well as the inline callees and referred comdats into partition PART. */ static void @@ -1337,42 +1365,34 @@ add_cgraph_node_to_partition (ltrans_partition part, struct cgraph_node *node) { struct cgraph_edge *e; cgraph_node_set_iterator csi; + struct cgraph_node *n; + + /* We always decide on functions, not associated thunks and aliases. */ + node = cgraph_function_node (node, NULL); /* If NODE is already there, we have nothing to do. */ csi = cgraph_node_set_find (part->cgraph_set, node); if (!csi_end_p (csi)) return; + cgraph_for_node_thunks_and_aliases (node, add_cgraph_node_to_partition_1, part, true); + part->insns += inline_summary (node)->self_size; - if (node->aux) - { - node->in_other_partition = 1; - if (cgraph_dump_file) - fprintf (cgraph_dump_file, "Node %s/%i now used in multiple partitions\n", - cgraph_node_name (node), node->uid); - } - node->aux = (void *)((size_t)node->aux + 1); cgraph_node_set_add (part->cgraph_set, node); - /* Thunks always must go along with function they reffer to. */ - if (node->thunk.thunk_p) - add_cgraph_node_to_partition (part, node->callees->callee); - for (e = node->callers; e; e = e->next_caller) - if (e->caller->thunk.thunk_p) - add_cgraph_node_to_partition (part, e->caller); - for (e = node->callees; e; e = e->next_callee) - if ((!e->inline_failed || DECL_COMDAT (e->callee->decl)) + if ((!e->inline_failed + || DECL_COMDAT (cgraph_function_node (e->callee, NULL)->decl)) && !cgraph_node_in_set_p (e->callee, part->cgraph_set)) add_cgraph_node_to_partition (part, e->callee); add_references_to_partition (part, &node->ref_list); - if (node->same_comdat_group - && !cgraph_node_in_set_p (node->same_comdat_group, part->cgraph_set)) - add_cgraph_node_to_partition (part, node->same_comdat_group); + if (node->same_comdat_group) + for (n = node->same_comdat_group; n != node; n = n->same_comdat_group) + add_cgraph_node_to_partition (part, n); } /* Add VNODE to partition as well as comdat references partition PART. */ @@ -1496,11 +1516,11 @@ lto_1_to_1_map (void) for (node = cgraph_nodes; node; node = node->next) { - if (!partition_cgraph_node_p (node)) + if (!partition_cgraph_node_p (node) + || node->aux) continue; file_data = node->local.lto_file_data; - gcc_assert (!node->same_body_alias); if (file_data) { @@ -1526,13 +1546,13 @@ lto_1_to_1_map (void) npartitions++; } - if (!node->aux) - add_cgraph_node_to_partition (partition, node); + add_cgraph_node_to_partition (partition, node); } for (vnode = varpool_nodes; vnode; vnode = vnode->next) { - if (!partition_varpool_node_p (vnode)) + if (!partition_varpool_node_p (vnode) + || vnode->aux) continue; file_data = vnode->lto_file_data; slot = pointer_map_contains (pmap, file_data); @@ -1546,8 +1566,7 @@ lto_1_to_1_map (void) npartitions++; } - if (!vnode->aux) - add_varpool_node_to_partition (partition, vnode); + add_varpool_node_to_partition (partition, vnode); } for (node = cgraph_nodes; node; node = node->next) node->aux = NULL; @@ -1656,8 +1675,9 @@ lto_balanced_map (void) for (i = 0; i < n_nodes; i++) { - if (!order[i]->aux) - add_cgraph_node_to_partition (partition, order[i]); + if (order[i]->aux) + continue; + add_cgraph_node_to_partition (partition, order[i]); total_size -= inline_summary (order[i])->size; /* Once we added a new node to the partition, we also want to add @@ -1837,6 +1857,8 @@ lto_balanced_map (void) } i = best_i; /* When we are finished, avoid creating empty partition. */ + while (i < n_nodes - 1 && order[i + 1]->aux) + i++; if (i == n_nodes - 1) break; partition = new_partition (""); @@ -1900,17 +1922,6 @@ promote_fn (struct cgraph_node *node) TREE_PUBLIC (node->decl) = 1; DECL_VISIBILITY (node->decl) = VISIBILITY_HIDDEN; DECL_VISIBILITY_SPECIFIED (node->decl) = true; - if (node->same_body) - { - struct cgraph_node *alias; - for (alias = node->same_body; - alias; alias = alias->next) - { - TREE_PUBLIC (alias->decl) = 1; - DECL_VISIBILITY (alias->decl) = VISIBILITY_HIDDEN; - DECL_VISIBILITY_SPECIFIED (alias->decl) = true; - } - } if (cgraph_dump_file) fprintf (cgraph_dump_file, "Promoting function as hidden: %s/%i\n", @@ -1944,8 +1955,8 @@ lto_promote_cross_file_statics (void) set = part->cgraph_set; vset = part->varpool_set; - /* If node has either address taken (and we have no clue from where) - or it is called from other partition, it needs to be globalized. */ + /* If node called or referred to from other partition, it needs to be + globalized. */ for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi)) { struct cgraph_node *node = csi_node (csi); diff --git a/gcc/matrix-reorg.c b/gcc/matrix-reorg.c index 6f75d3320c1..dfc189632d5 100644 --- a/gcc/matrix-reorg.c +++ b/gcc/matrix-reorg.c @@ -2390,6 +2390,6 @@ struct simple_ipa_opt_pass pass_ipa_matrix_reorg = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_cgraph | TODO_dump_func /* todo_flags_finish */ + TODO_dump_cgraph /* todo_flags_finish */ } }; diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c index d4c7b24b981..9b11842781c 100644 --- a/gcc/mode-switching.c +++ b/gcc/mode-switching.c @@ -772,6 +772,6 @@ struct rtl_opt_pass pass_mode_switching = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c index 327c09aefed..e9749b23a6f 100644 --- a/gcc/modulo-sched.c +++ b/gcc/modulo-sched.c @@ -134,8 +134,6 @@ struct ps_insn ps_insn_ptr next_in_row, prev_in_row; - /* The number of nodes in the same row that come after this node. */ - int row_rest_count; }; /* Holds the partial schedule as an array of II rows. Each entry of the @@ -149,6 +147,12 @@ struct partial_schedule /* rows[i] points to linked list of insns scheduled in row i (0<=i<ii). */ ps_insn_ptr *rows; + /* rows_length[i] holds the number of instructions in the row. + It is used only (as an optimization) to back off quickly from + trying to schedule a node in a full row; that is, to avoid running + through futile DFA state transitions. */ + int *rows_length; + /* The earliest absolute cycle of an insn in the partial schedule. */ int min_cycle; @@ -1908,6 +1912,7 @@ ps_insert_empty_row (partial_schedule_ptr ps, int split_row, int ii = ps->ii; int new_ii = ii + 1; int row; + int *rows_length_new; verify_partial_schedule (ps, sched_nodes); @@ -1922,9 +1927,11 @@ ps_insert_empty_row (partial_schedule_ptr ps, int split_row, rotate_partial_schedule (ps, PS_MIN_CYCLE (ps)); rows_new = (ps_insn_ptr *) xcalloc (new_ii, sizeof (ps_insn_ptr)); + rows_length_new = (int *) xcalloc (new_ii, sizeof (int)); for (row = 0; row < split_row; row++) { rows_new[row] = ps->rows[row]; + rows_length_new[row] = ps->rows_length[row]; ps->rows[row] = NULL; for (crr_insn = rows_new[row]; crr_insn; crr_insn = crr_insn->next_in_row) @@ -1945,6 +1952,7 @@ ps_insert_empty_row (partial_schedule_ptr ps, int split_row, for (row = split_row; row < ii; row++) { rows_new[row + 1] = ps->rows[row]; + rows_length_new[row + 1] = ps->rows_length[row]; ps->rows[row] = NULL; for (crr_insn = rows_new[row + 1]; crr_insn; crr_insn = crr_insn->next_in_row) @@ -1966,6 +1974,8 @@ ps_insert_empty_row (partial_schedule_ptr ps, int split_row, + (SMODULO (ps->max_cycle, ii) >= split_row ? 1 : 0); free (ps->rows); ps->rows = rows_new; + free (ps->rows_length); + ps->rows_length = rows_length_new; ps->ii = new_ii; gcc_assert (ps->min_cycle >= 0); @@ -2041,16 +2051,23 @@ verify_partial_schedule (partial_schedule_ptr ps, sbitmap sched_nodes) ps_insn_ptr crr_insn; for (row = 0; row < ps->ii; row++) - for (crr_insn = ps->rows[row]; crr_insn; crr_insn = crr_insn->next_in_row) - { - ddg_node_ptr u = crr_insn->node; - - gcc_assert (TEST_BIT (sched_nodes, u->cuid)); - /* ??? Test also that all nodes of sched_nodes are in ps, perhaps by - popcount (sched_nodes) == number of insns in ps. */ - gcc_assert (SCHED_TIME (u) >= ps->min_cycle); - gcc_assert (SCHED_TIME (u) <= ps->max_cycle); - } + { + int length = 0; + + for (crr_insn = ps->rows[row]; crr_insn; crr_insn = crr_insn->next_in_row) + { + ddg_node_ptr u = crr_insn->node; + + length++; + gcc_assert (TEST_BIT (sched_nodes, u->cuid)); + /* ??? Test also that all nodes of sched_nodes are in ps, perhaps by + popcount (sched_nodes) == number of insns in ps. */ + gcc_assert (SCHED_TIME (u) >= ps->min_cycle); + gcc_assert (SCHED_TIME (u) <= ps->max_cycle); + } + + gcc_assert (ps->rows_length[row] == length); + } } @@ -2456,6 +2473,7 @@ create_partial_schedule (int ii, ddg_ptr g, int history) { partial_schedule_ptr ps = XNEW (struct partial_schedule); ps->rows = (ps_insn_ptr *) xcalloc (ii, sizeof (ps_insn_ptr)); + ps->rows_length = (int *) xcalloc (ii, sizeof (int)); ps->ii = ii; ps->history = history; ps->min_cycle = INT_MAX; @@ -2494,6 +2512,7 @@ free_partial_schedule (partial_schedule_ptr ps) return; free_ps_insns (ps); free (ps->rows); + free (ps->rows_length); free (ps); } @@ -2511,6 +2530,8 @@ reset_partial_schedule (partial_schedule_ptr ps, int new_ii) ps->rows = (ps_insn_ptr *) xrealloc (ps->rows, new_ii * sizeof (ps_insn_ptr)); memset (ps->rows, 0, new_ii * sizeof (ps_insn_ptr)); + ps->rows_length = (int *) xrealloc (ps->rows_length, new_ii * sizeof (int)); + memset (ps->rows_length, 0, new_ii * sizeof (int)); ps->ii = new_ii; ps->min_cycle = INT_MAX; ps->max_cycle = INT_MIN; @@ -2539,14 +2560,13 @@ print_partial_schedule (partial_schedule_ptr ps, FILE *dump) /* Creates an object of PS_INSN and initializes it to the given parameters. */ static ps_insn_ptr -create_ps_insn (ddg_node_ptr node, int rest_count, int cycle) +create_ps_insn (ddg_node_ptr node, int cycle) { ps_insn_ptr ps_i = XNEW (struct ps_insn); ps_i->node = node; ps_i->next_in_row = NULL; ps_i->prev_in_row = NULL; - ps_i->row_rest_count = rest_count; ps_i->cycle = cycle; return ps_i; @@ -2579,6 +2599,8 @@ remove_node_from_ps (partial_schedule_ptr ps, ps_insn_ptr ps_i) if (ps_i->next_in_row) ps_i->next_in_row->prev_in_row = ps_i->prev_in_row; } + + ps->rows_length[row] -= 1; free (ps_i); return true; } @@ -2735,17 +2757,12 @@ add_node_to_ps (partial_schedule_ptr ps, ddg_node_ptr node, int cycle, sbitmap must_precede, sbitmap must_follow) { ps_insn_ptr ps_i; - int rest_count = 1; int row = SMODULO (cycle, ps->ii); - if (ps->rows[row] - && ps->rows[row]->row_rest_count >= issue_rate) + if (ps->rows_length[row] >= issue_rate) return NULL; - if (ps->rows[row]) - rest_count += ps->rows[row]->row_rest_count; - - ps_i = create_ps_insn (node, rest_count, cycle); + ps_i = create_ps_insn (node, cycle); /* Finds and inserts PS_I according to MUST_FOLLOW and MUST_PRECEDE. */ @@ -2755,6 +2772,7 @@ add_node_to_ps (partial_schedule_ptr ps, ddg_node_ptr node, int cycle, return NULL; } + ps->rows_length[row] += 1; return ps_i; } @@ -2910,11 +2928,16 @@ rotate_partial_schedule (partial_schedule_ptr ps, int start_cycle) for (i = 0; i < backward_rotates; i++) { ps_insn_ptr first_row = ps->rows[0]; + int first_row_length = ps->rows_length[0]; for (row = 0; row < last_row; row++) - ps->rows[row] = ps->rows[row+1]; + { + ps->rows[row] = ps->rows[row + 1]; + ps->rows_length[row] = ps->rows_length[row + 1]; + } ps->rows[last_row] = first_row; + ps->rows_length[last_row] = first_row_length; } ps->max_cycle -= start_cycle; @@ -2969,12 +2992,10 @@ struct rtl_opt_pass pass_sms = 0, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ - TODO_dump_func, /* todo_flags_start */ + 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_flow | TODO_verify_rtl_sharing - | TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } }; - diff --git a/gcc/omp-low.c b/gcc/omp-low.c index e4bf141b908..99dedf9369c 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -5553,7 +5553,7 @@ struct gimple_opt_pass pass_expand_omp = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -6730,7 +6730,7 @@ struct gimple_opt_pass pass_lower_omp = PROP_gimple_lomp, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; diff --git a/gcc/opts.c b/gcc/opts.c index 712425eb928..e9b433454c7 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "opts-diagnostic.h" #include "insn-attr.h" /* For INSN_SCHEDULING and DELAY_SLOTS. */ #include "target.h" +#include "common/common-target.h" /* Parse the -femit-struct-debug-detailed option value and set the flag variables. */ @@ -231,7 +232,7 @@ target_handle_option (struct gcc_options *opts, { gcc_assert (dc == global_dc); gcc_assert (kind == DK_UNSPECIFIED); - return targetm.handle_option (opts, opts_set, decoded, loc); + return targetm_common.handle_option (opts, opts_set, decoded, loc); } /* Add comma-separated strings to a char_p vector. */ @@ -295,15 +296,15 @@ init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set) is set after target options have been processed. */ opts->x_flag_short_enums = 2; - /* Initialize target_flags before targetm.target_option.optimization + /* Initialize target_flags before default_options_optimization so the latter can modify it. */ - opts->x_target_flags = targetm.default_target_flags; + opts->x_target_flags = targetm_common.default_target_flags; /* Some targets have ABI-specified unwind tables. */ - opts->x_flag_unwind_tables = targetm.unwind_tables_default; + opts->x_flag_unwind_tables = targetm_common.unwind_tables_default; /* Some targets have other target-specific initialization. */ - targetm.target_option.init_struct (opts); + targetm_common.option_init_struct (opts); } /* If indicated by the optimization level LEVEL (-Os if SIZE is set, @@ -596,7 +597,7 @@ default_options_optimization (struct gcc_options *opts, /* Allow default optimizations to be specified on a per-machine basis. */ maybe_default_options (opts, opts_set, - targetm.target_option.optimization_table, + targetm_common.option_optimization_table, opts->x_optimize, opts->x_optimize_size, opts->x_optimize_fast, lang_mask, handlers, loc, dc); } @@ -700,7 +701,7 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, generating unwind info. If opts->x_flag_exceptions is turned on we need to turn off the partitioning optimization. */ - ui_except = targetm.except_unwind_info (opts); + ui_except = targetm_common.except_unwind_info (opts); if (opts->x_flag_exceptions && opts->x_flag_reorder_blocks_and_partition @@ -717,7 +718,7 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, optimization. */ if (opts->x_flag_unwind_tables - && !targetm.unwind_tables_default + && !targetm_common.unwind_tables_default && opts->x_flag_reorder_blocks_and_partition && (ui_except == UI_SJLJ || ui_except == UI_TARGET)) { @@ -733,9 +734,9 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, support named sections. */ if (opts->x_flag_reorder_blocks_and_partition - && (!targetm.have_named_sections + && (!targetm_common.have_named_sections || (opts->x_flag_unwind_tables - && targetm.unwind_tables_default + && targetm_common.unwind_tables_default && (ui_except == UI_SJLJ || ui_except == UI_TARGET)))) { inform (loc, @@ -795,7 +796,7 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, opts->x_flag_split_stack = 0; else if (opts->x_flag_split_stack) { - if (!targetm.supports_split_stack (true, opts)) + if (!targetm_common.supports_split_stack (true, opts)) { error_at (loc, "%<-fsplit-stack%> is not supported by " "this compiler configuration"); diff --git a/gcc/passes.c b/gcc/passes.c index ca3fb6fb0d0..a56d86404c6 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -1602,6 +1602,37 @@ do_per_function_toporder (void (*callback) (void *data), void *data) nnodes = 0; } +/* Helper function to perform function body dump. */ + +static void +execute_function_dump (void *data ATTRIBUTE_UNUSED) +{ + if (dump_file && current_function_decl) + { + if (cfun->curr_properties & PROP_trees) + dump_function_to_file (current_function_decl, dump_file, dump_flags); + else + { + if (dump_flags & TDF_SLIM) + print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags); + else if ((cfun->curr_properties & PROP_cfg) + && (dump_flags & TDF_BLOCKS)) + print_rtl_with_bb (dump_file, get_insns ()); + else + print_rtl (dump_file, get_insns ()); + + if ((cfun->curr_properties & PROP_cfg) + && graph_dump_format != no_graph + && (dump_flags & TDF_GRAPH)) + print_rtl_graph_with_bb (dump_file_name, get_insns ()); + } + + /* Flush the file. If verification fails, we won't be able to + close the file before aborting. */ + fflush (dump_file); + } +} + /* Perform all TODO actions that ought to be done on each function. */ static void @@ -1648,31 +1679,6 @@ execute_function_todo (void *data) if (flags & TODO_remove_unused_locals) remove_unused_locals (); - if ((flags & TODO_dump_func) && dump_file && current_function_decl) - { - if (cfun->curr_properties & PROP_trees) - dump_function_to_file (current_function_decl, dump_file, dump_flags); - else - { - if (dump_flags & TDF_SLIM) - print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags); - else if ((cfun->curr_properties & PROP_cfg) - && (dump_flags & TDF_BLOCKS)) - print_rtl_with_bb (dump_file, get_insns ()); - else - print_rtl (dump_file, get_insns ()); - - if ((cfun->curr_properties & PROP_cfg) - && graph_dump_format != no_graph - && (dump_flags & TDF_GRAPH)) - print_rtl_graph_with_bb (dump_file_name, get_insns ()); - } - - /* Flush the file. If verification fails, we won't be able to - close the file before aborting. */ - fflush (dump_file); - } - if (flags & TODO_rebuild_frequencies) rebuild_frequencies (); @@ -1898,6 +1904,7 @@ execute_one_ipa_transform_pass (struct cgraph_node *node, execute_todo (todo_after); verify_interpass_invariants (); + do_per_function (execute_function_dump, NULL); pass_fini_dump_file (pass); current_pass = NULL; @@ -2050,6 +2057,7 @@ execute_one_pass (struct opt_pass *pass) /* Run post-pass cleanup and verification. */ execute_todo (todo_after | pass->todo_flags_finish); verify_interpass_invariants (); + do_per_function (execute_function_dump, NULL); if (pass->type == IPA_PASS) { struct cgraph_node *node; @@ -2194,7 +2202,7 @@ ipa_write_summaries (void) vset = varpool_node_set_new (); for (vnode = varpool_nodes; vnode; vnode = vnode->next) - if (vnode->needed && !vnode->alias) + if (vnode->needed && (!vnode->alias || vnode->alias_of)) varpool_node_set_add (vset, vnode); ipa_write_summaries_1 (set, vset); diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog index cb258afea9b..53ca29ca46d 100644 --- a/gcc/po/ChangeLog +++ b/gcc/po/ChangeLog @@ -1,3 +1,7 @@ +2011-06-14 Joseph Myers <joseph@codesourcery.com> + + * exgettext: Handle common/ directory and subdirectories. + 2011-05-23 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> * EXCLUDES: Remove gthr-gnat.c, gthr-gnat.h. diff --git a/gcc/po/exgettext b/gcc/po/exgettext index 7642dc56aad..a7bbf185a04 100644 --- a/gcc/po/exgettext +++ b/gcc/po/exgettext @@ -72,6 +72,9 @@ pottmp=$pwd/$T/tmp.pot # Locate files to scan. We scan the following directories: # $srcdir # $srcdir/c-family +# $srcdir/common +# $srcdir/common/config +# $srcdir/common/config/* # $srcdir/config # $srcdir/config/* # all subdirectories of $srcdir containing a config-lang.in file, and @@ -91,7 +94,8 @@ echo "scanning for keywords, %e and %n strings..." >&2 ( cd $srcdir lang_subdirs=`echo */config-lang.in */*/config-lang.in | sed -e 's|/config-lang\.in||g'` - { for dir in "" c-family/ config/ config/*/ \ + { for dir in "" c-family/ common/ common/config/ common/config/*/ \ + config/ config/*/ \ `find $lang_subdirs -type d -print | fgrep -v .svn | sort | sed -e 's|$|/|'` do for glob in '*.c' '*.cc' '*.h' '*.def' do eval echo $dir$glob diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c index bc55ead744f..e05e4450d0e 100644 --- a/gcc/postreload-gcse.c +++ b/gcc/postreload-gcse.c @@ -1344,8 +1344,7 @@ struct rtl_opt_pass pass_gcse2 = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_rtl_sharing + TODO_verify_rtl_sharing | TODO_verify_flow | TODO_ggc_collect /* todo_flags_finish */ } }; - diff --git a/gcc/postreload.c b/gcc/postreload.c index 0f3e5c24658..e5c6ce7cdbc 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -2287,6 +2287,6 @@ struct rtl_opt_pass pass_postreload_cse = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; diff --git a/gcc/predict.c b/gcc/predict.c index 870526bc6b3..f5e2449f636 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -994,7 +994,7 @@ predict_loops (void) the loop, use it to predict this exit. */ else if (n_exits == 1) { - nitercst = estimated_loop_iterations_int (loop, false); + nitercst = max_stmt_executions_int (loop, false); if (nitercst < 0) continue; if (nitercst > max) diff --git a/gcc/prefix.c b/gcc/prefix.c index 90261ae6ffe..369ede70309 100644 --- a/gcc/prefix.c +++ b/gcc/prefix.c @@ -1,6 +1,6 @@ /* Utility to update paths from internal to external forms. Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2007 Free Software Foundation, Inc. + 2007, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -67,11 +67,11 @@ License along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" -#include "tm.h" #if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY) #include <windows.h> #endif #include "prefix.h" +#include "common/common-target.h" static const char *std_prefix = PREFIX; @@ -271,10 +271,6 @@ update_path (const char *path, const char *key) else result = xstrdup (path); -#ifndef ALWAYS_STRIP_DOTDOT -#define ALWAYS_STRIP_DOTDOT 0 -#endif - p = result; while (1) { @@ -289,7 +285,8 @@ update_path (const char *path, const char *key) && (p != result && IS_DIR_SEPARATOR (p[-1]))) { *p = 0; - if (!ALWAYS_STRIP_DOTDOT && access (result, X_OK) == 0) + if (!targetm_common.always_strip_dotdot + && access (result, X_OK) == 0) { *p = '.'; break; diff --git a/gcc/recog.c b/gcc/recog.c index afe985e2f27..0c26c0d90f0 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -3694,7 +3694,7 @@ struct rtl_opt_pass pass_peephole2 = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -3720,7 +3720,7 @@ struct rtl_opt_pass pass_split_all_insns = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -3750,7 +3750,7 @@ struct rtl_opt_pass pass_split_after_reload = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -3794,7 +3794,7 @@ struct rtl_opt_pass pass_split_before_regstack = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -3832,8 +3832,7 @@ struct rtl_opt_pass pass_split_before_sched2 = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_verify_flow | - TODO_dump_func /* todo_flags_finish */ + TODO_verify_flow /* todo_flags_finish */ } }; @@ -3864,6 +3863,6 @@ struct rtl_opt_pass pass_split_for_shorten_branches = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_rtl_sharing /* todo_flags_finish */ + TODO_verify_rtl_sharing /* todo_flags_finish */ } }; diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index dcde8920d7e..896a68f3fc7 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -3352,7 +3352,6 @@ struct rtl_opt_pass pass_stack_regs_run = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } }; diff --git a/gcc/regcprop.c b/gcc/regcprop.c index bf34115f1dc..911f59eb083 100644 --- a/gcc/regcprop.c +++ b/gcc/regcprop.c @@ -1188,7 +1188,7 @@ struct rtl_opt_pass pass_cprop_hardreg = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_df_finish + TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */ } }; diff --git a/gcc/regmove.c b/gcc/regmove.c index afa7ee7aa77..89dbd592103 100644 --- a/gcc/regmove.c +++ b/gcc/regmove.c @@ -1382,7 +1382,6 @@ struct rtl_opt_pass pass_regmove = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } }; diff --git a/gcc/regrename.c b/gcc/regrename.c index c2292efba90..b83c7258fb7 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -432,7 +432,6 @@ do_replace (struct du_head *head, int reg) { struct du_chain *chain; unsigned int base_regno = head->regno; - bool found_note = false; gcc_assert (! DEBUG_INSN_P (head->first->insn)); @@ -446,46 +445,15 @@ do_replace (struct du_head *head, int reg) INSN_VAR_LOCATION_LOC (chain->insn) = gen_rtx_UNKNOWN_VAR_LOC (); else { - rtx note; - *chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg); if (regno >= FIRST_PSEUDO_REGISTER) ORIGINAL_REGNO (*chain->loc) = regno; REG_ATTRS (*chain->loc) = attr; REG_POINTER (*chain->loc) = reg_ptr; - - for (note = REG_NOTES (chain->insn); note; note = XEXP (note, 1)) - { - enum reg_note kind = REG_NOTE_KIND (note); - if (kind == REG_DEAD || kind == REG_UNUSED) - { - rtx reg = XEXP (note, 0); - gcc_assert (HARD_REGISTER_P (reg)); - - if (REGNO (reg) == base_regno) - { - found_note = true; - if (kind == REG_DEAD - && reg_set_p (*chain->loc, chain->insn)) - remove_note (chain->insn, note); - else - XEXP (note, 0) = *chain->loc; - break; - } - } - } } df_insn_rescan (chain->insn); } - if (!found_note) - { - /* If the chain's first insn is the same as the last, we should have - found a REG_UNUSED note. */ - gcc_assert (head->first->insn != head->last->insn); - if (!reg_set_p (*head->last->loc, head->last->insn)) - add_reg_note (head->last->insn, REG_DEAD, *head->last->loc); - } } @@ -753,25 +721,34 @@ scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl, enum scan_actions action, In either case, we remove this element from open_chains. */ if ((action == terminate_dead || action == terminate_write) - && superset) + && (superset || subset)) { unsigned nregs; head->terminated = 1; + if (subset && !superset) + head->cannot_rename = 1; head->next_chain = closed_chains; closed_chains = head; bitmap_clear_bit (&open_chains_set, head->id); nregs = head->nregs; while (nregs-- > 0) - CLEAR_HARD_REG_BIT (live_in_chains, head->regno + nregs); + { + CLEAR_HARD_REG_BIT (live_in_chains, head->regno + nregs); + if (subset && !superset + && (head->regno + nregs < this_regno + || head->regno + nregs >= this_regno + this_nregs)) + SET_HARD_REG_BIT (live_hard_regs, head->regno + nregs); + } *p = next; if (dump_file) fprintf (dump_file, - "Closing chain %s (%d) at insn %d (%s)\n", + "Closing chain %s (%d) at insn %d (%s%s)\n", reg_names[head->regno], head->id, INSN_UID (insn), - scan_actions_name[(int) action]); + scan_actions_name[(int) action], + superset ? ", superset" : subset ? ", subset" : ""); } else if (action == terminate_dead || action == terminate_write) { @@ -1453,7 +1430,6 @@ struct rtl_opt_pass pass_regrename = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; - diff --git a/gcc/reload.c b/gcc/reload.c index 27d57877501..3ad46b991ad 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -6791,6 +6791,15 @@ find_equiv_reg (rtx goal, rtx insn, enum reg_class rclass, int other, || num > PARAM_VALUE (PARAM_MAX_RELOAD_SEARCH_INSNS)) return 0; + /* Don't reuse register contents from before a setjmp-type + function call; on the second return (from the longjmp) it + might have been clobbered by a later reuse. It doesn't + seem worthwhile to actually go and see if it is actually + reused even if that information would be readily available; + just don't reuse it across the setjmp call. */ + if (CALL_P (p) && find_reg_note (p, REG_SETJMP, NULL_RTX)) + return 0; + if (NONJUMP_INSN_P (p) /* If we don't want spill regs ... */ && (! (reload_reg_p != 0 diff --git a/gcc/reload1.c b/gcc/reload1.c index e65503b9fa5..a87e6ad08d6 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -4844,6 +4844,13 @@ reload_as_needed (int live_known) { AND_COMPL_HARD_REG_SET (reg_reloaded_valid, call_used_reg_set); AND_COMPL_HARD_REG_SET (reg_reloaded_valid, reg_reloaded_call_part_clobbered); + + /* If this is a call to a setjmp-type function, we must not + reuse any reload reg contents across the call; that will + just be clobbered by other uses of the register in later + code, before the longjmp. */ + if (find_reg_note (insn, REG_SETJMP, NULL_RTX)) + CLEAR_HARD_REG_SET (reg_reloaded_valid); } } diff --git a/gcc/reorg.c b/gcc/reorg.c index 443917df568..28b6c7d6271 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -4086,7 +4086,6 @@ struct rtl_opt_pass pass_delay_slots = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } }; @@ -4121,7 +4120,6 @@ struct rtl_opt_pass pass_machine_reorg = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } }; diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c index 248b870a75a..e510980816e 100644 --- a/gcc/sched-rgn.c +++ b/gcc/sched-rgn.c @@ -3551,7 +3551,6 @@ struct rtl_opt_pass pass_sched = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_verify_flow | TODO_ggc_collect /* todo_flags_finish */ } @@ -3573,7 +3572,6 @@ struct rtl_opt_pass pass_sched2 = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_verify_flow | TODO_ggc_collect /* todo_flags_finish */ } diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index 8a39d80d250..92ba2222502 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -4663,9 +4663,10 @@ create_block_for_bookkeeping (edge e1, edge e2) } /* Return insn after which we must insert bookkeeping code for path(s) incoming - into E2->dest, except from E1->src. */ + into E2->dest, except from E1->src. If the returned insn immediately + precedes a fence, assign that fence to *FENCE_TO_REWIND. */ static insn_t -find_place_for_bookkeeping (edge e1, edge e2) +find_place_for_bookkeeping (edge e1, edge e2, fence_t *fence_to_rewind) { insn_t place_to_insert; /* Find a basic block that can hold bookkeeping. If it can be found, do not @@ -4707,9 +4708,14 @@ find_place_for_bookkeeping (edge e1, edge e2) sel_print ("Pre-existing bookkeeping block is %i\n", book_block->index); } - /* If basic block ends with a jump, insert bookkeeping code right before it. */ + *fence_to_rewind = NULL; + /* If basic block ends with a jump, insert bookkeeping code right before it. + Notice if we are crossing a fence when taking PREV_INSN. */ if (INSN_P (place_to_insert) && control_flow_insn_p (place_to_insert)) - place_to_insert = PREV_INSN (place_to_insert); + { + *fence_to_rewind = flist_lookup (fences, place_to_insert); + place_to_insert = PREV_INSN (place_to_insert); + } return place_to_insert; } @@ -4784,21 +4790,23 @@ generate_bookkeeping_insn (expr_t c_expr, edge e1, edge e2) insn_t join_point, place_to_insert, new_insn; int new_seqno; bool need_to_exchange_data_sets; + fence_t fence_to_rewind; if (sched_verbose >= 4) sel_print ("Generating bookkeeping insn (%d->%d)\n", e1->src->index, e2->dest->index); join_point = sel_bb_head (e2->dest); - place_to_insert = find_place_for_bookkeeping (e1, e2); - if (!place_to_insert) - return NULL; + place_to_insert = find_place_for_bookkeeping (e1, e2, &fence_to_rewind); new_seqno = find_seqno_for_bookkeeping (place_to_insert, join_point); need_to_exchange_data_sets = sel_bb_empty_p (BLOCK_FOR_INSN (place_to_insert)); new_insn = emit_bookkeeping_insn (place_to_insert, c_expr, new_seqno); + if (fence_to_rewind) + FENCE_INSN (fence_to_rewind) = new_insn; + /* When inserting bookkeeping insn in new block, av sets should be following: old basic block (that now holds bookkeeping) data sets are the same as was before generation of bookkeeping, and new basic block diff --git a/gcc/store-motion.c b/gcc/store-motion.c index f6a021eb778..c8beb24ed64 100644 --- a/gcc/store-motion.c +++ b/gcc/store-motion.c @@ -1258,8 +1258,6 @@ struct rtl_opt_pass pass_rtl_store_motion = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func | TODO_verify_flow | TODO_ggc_collect /* todo_flags_finish */ } }; - diff --git a/gcc/system.h b/gcc/system.h index d95b9505443..6b8fde2dcad 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -759,7 +759,7 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; LABEL_ALIGN_MAX_SKIP LOOP_ALIGN_MAX_SKIP \ LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP JUMP_ALIGN_MAX_SKIP \ CAN_DEBUG_WITHOUT_FP UNLIKELY_EXECUTED_TEXT_SECTION_NAME \ - HOT_TEXT_SECTION_NAME LEGITIMATE_CONSTANT_P + HOT_TEXT_SECTION_NAME LEGITIMATE_CONSTANT_P ALWAYS_STRIP_DOTDOT /* Target macros only used for code built for the target, that have moved to libgcc-tm.h or have never been present elsewhere. */ diff --git a/gcc/target-def.h b/gcc/target-def.h index bf3a8cb8ea2..86095122208 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -1,6 +1,6 @@ /* Default initializers for a generic GCC target. - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + 2011 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -78,10 +78,6 @@ # endif #endif -#ifdef TARGET_ASM_NAMED_SECTION -#define TARGET_HAVE_NAMED_SECTIONS true -#endif - #ifndef TARGET_TERMINATE_DW2_EH_FRAME_INFO #ifdef EH_FRAME_SECTION_NAME #define TARGET_TERMINATE_DW2_EH_FRAME_INFO false diff --git a/gcc/target.def b/gcc/target.def index 3215bd3ddcf..94c434ff360 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -1012,12 +1012,6 @@ HOOK_VECTOR_END (vectorize) #undef HOOK_PREFIX #define HOOK_PREFIX "TARGET_" -/* The initial value of target_flags. */ -DEFHOOKPOD -(default_target_flags, - "", - int, 0) - /* Allow target specific overriding of option settings after options have been changed by an attribute or pragma or when it is reset at the end of the code affected by an attribute or pragma. */ @@ -1027,16 +1021,6 @@ DEFHOOK void, (void), hook_void_void) -/* Handle target switch DECODED for options structures OPTS and - OPTS_SET, at location LOC. Return true if the switch was valid. */ -DEFHOOK -(handle_option, - "", - bool, (struct gcc_options *opts, struct gcc_options *opts_set, - const struct cl_decoded_option *decoded, - unsigned int /*location_t*/ loc), - default_target_handle_option) - /* Display extra, target specific information in response to a --target-help switch. */ DEFHOOK @@ -1876,17 +1860,6 @@ DEFHOOK tree, (void), default_external_stack_protect_fail) -DEFHOOK -(supports_split_stack, - "Whether this target supports splitting the stack when the options\ - described in @var{opts} have been passed. This is called\ - after options have been parsed, so the target may reject splitting\ - the stack in some configurations. The default version of this hook\ - returns false. If @var{report} is true, this function may issue a warning\ - or error; if @var{report} is false, it must simply return a value", - bool, (bool report, struct gcc_options *opts), - hook_bool_bool_gcc_optionsp_false) - /* Returns NULL if target supports the insn within a doloop block, otherwise it returns an error message. */ DEFHOOK @@ -1951,7 +1924,7 @@ DEFHOOK (pass_by_reference, "", bool, - (CUMULATIVE_ARGS *cum, enum machine_mode mode, const_tree type, bool named), + (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named), hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false) DEFHOOK @@ -1964,14 +1937,14 @@ DEFHOOK DEFHOOK (setup_incoming_varargs, "", - void, (CUMULATIVE_ARGS *args_so_far, enum machine_mode mode, tree type, + void, (cumulative_args_t args_so_far, enum machine_mode mode, tree type, int *pretend_args_size, int second_time), default_setup_incoming_varargs) DEFHOOK (strict_argument_naming, "", - bool, (CUMULATIVE_ARGS *ca), + bool, (cumulative_args_t ca), hook_bool_CUMULATIVE_ARGS_false) /* Returns true if we should use @@ -1980,7 +1953,7 @@ DEFHOOK DEFHOOK (pretend_outgoing_varargs_named, "", - bool, (CUMULATIVE_ARGS *ca), + bool, (cumulative_args_t ca), default_pretend_outgoing_varargs_named) /* Given a complex type T, return true if a parameter of type T @@ -2007,7 +1980,7 @@ DEFHOOK (callee_copies, "", bool, - (CUMULATIVE_ARGS *cum, enum machine_mode mode, const_tree type, bool named), + (cumulative_args_t cum, enum machine_mode mode, const_tree type, bool named), hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false) /* Return zero for arguments passed entirely on the stack or entirely @@ -2016,7 +1989,7 @@ DEFHOOK DEFHOOK (arg_partial_bytes, "", - int, (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, bool named), + int, (cumulative_args_t cum, enum machine_mode mode, tree type, bool named), hook_int_CUMULATIVE_ARGS_mode_tree_bool_0) /* Update the state in CA to advance past an argument in the @@ -2026,7 +1999,7 @@ DEFHOOK (function_arg_advance, "", void, - (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type, bool named), + (cumulative_args_t ca, enum machine_mode mode, const_tree type, bool named), default_function_arg_advance) /* Return zero if the argument described by the state of CA should @@ -2036,7 +2009,7 @@ DEFHOOK DEFHOOK (function_arg, "", - rtx, (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type, + rtx, (cumulative_args_t ca, enum machine_mode mode, const_tree type, bool named), default_function_arg) @@ -2045,7 +2018,7 @@ DEFHOOK DEFHOOK (function_incoming_arg, "", - rtx, (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type, + rtx, (cumulative_args_t ca, enum machine_mode mode, const_tree type, bool named), default_function_incoming_arg) @@ -2579,12 +2552,6 @@ DEFHOOK void, (void), hook_void_void) -/* Set default optimizations for the target. */ -DEFHOOKPOD -(optimization_table, - "", - const struct default_options *, empty_optimization_table) - DEFHOOK (default_params, "Set target-dependent default values for @option{--param} settings, using\ @@ -2592,12 +2559,6 @@ DEFHOOK void, (void), hook_void_void) -DEFHOOK -(init_struct, -"Set target-dependent initial values of fields in @var{opts}.", - void, (struct gcc_options *opts), - hook_void_gcc_optionsp) - /* Function to determine if one function can inline another function. */ #undef HOOK_PREFIX #define HOOK_PREFIX "TARGET_" @@ -2625,27 +2586,8 @@ DEFHOOK enum unwind_info_type, (void), default_debug_unwind_info) -/* Determine the type of unwind info to emit for exceptions. */ -DEFHOOK -(except_unwind_info, - "", - enum unwind_info_type, (struct gcc_options *opts), - default_except_unwind_info) - /* Leave the boolean fields at the end. */ -/* True if unwinding tables should be generated by default. */ -DEFHOOKPOD -(unwind_tables_default, - "", - bool, false) - -/* True if arbitrary sections are supported. */ -DEFHOOKPOD -(have_named_sections, - "", - bool, false) - /* True if we can create zeroed data by switching to a BSS section and then using ASM_OUTPUT_SKIP to allocate the space. */ DEFHOOKPOD diff --git a/gcc/target.h b/gcc/target.h index eae0b76a899..12fd9b085a0 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -1,5 +1,6 @@ /* Data structure definitions for a generic GCC target. - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + 2011 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it @@ -49,9 +50,24 @@ #ifndef GCC_TARGET_H #define GCC_TARGET_H -#include "tm.h" #include "insn-modes.h" +#ifdef ENABLE_CHECKING + +typedef struct { void *magic; void *p; } cumulative_args_t; + +#else /* !ENABLE_CHECKING */ + +/* When using a GCC build compiler, we could use + __attribute__((transparent_union)) to get cumulative_args_t function + arguments passed like scalars where the ABI would mandate a less + efficient way of argument passing otherwise. However, that would come + at the cost of less type-safe !ENABLE_CHECKING compilation. */ + +typedef union { void *p; } cumulative_args_t; + +#endif /* !ENABLE_CHECKING */ + /* Types used by the record_gcc_switches() target function. */ typedef enum { @@ -131,41 +147,6 @@ enum vect_cost_for_stmt vec_perm }; -/* Sets of optimization levels at which an option may be enabled by - default_options_optimization. */ -enum opt_levels -{ - OPT_LEVELS_NONE, /* No levels (mark end of array). */ - OPT_LEVELS_ALL, /* All levels (used by targets to disable options - enabled in target-independent code). */ - OPT_LEVELS_0_ONLY, /* -O0 only. */ - OPT_LEVELS_1_PLUS, /* -O1 and above, including -Os. */ - OPT_LEVELS_1_PLUS_SPEED_ONLY, /* -O1 and above, but not -Os. */ - OPT_LEVELS_2_PLUS, /* -O2 and above, including -Os. */ - OPT_LEVELS_2_PLUS_SPEED_ONLY, /* -O2 and above, but not -Os. */ - OPT_LEVELS_3_PLUS, /* -O3 and above. */ - OPT_LEVELS_3_PLUS_AND_SIZE, /* -O3 and above and -Os. */ - OPT_LEVELS_SIZE, /* -Os only. */ - OPT_LEVELS_FAST /* -Ofast only. */ -}; - -/* Description of options to enable by default at given levels. */ -struct default_options -{ - /* The levels at which to enable the option. */ - enum opt_levels levels; - - /* The option index and argument or enabled/disabled sense of the - option, as passed to handle_generated_option. If ARG is NULL and - the option allows a negative form, the option is considered to be - passed in negative form when the optimization level is not one of - those in LEVELS (in order to handle changes to the optimization - level with the "optimize" attribute). */ - size_t opt_index; - const char *arg; - int value; -}; - /* The target structure. This holds all the backend hooks. */ #define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME; #define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS; @@ -176,4 +157,32 @@ struct default_options extern struct gcc_target targetm; +#ifdef GCC_TM_H + +#ifndef CUMULATIVE_ARGS_MAGIC +#define CUMULATIVE_ARGS_MAGIC ((void *) &targetm.calls) +#endif + +static inline CUMULATIVE_ARGS * +get_cumulative_args (cumulative_args_t arg) +{ +#ifdef ENABLE_CHECKING + gcc_assert (arg.magic == CUMULATIVE_ARGS_MAGIC); +#endif /* ENABLE_CHECKING */ + return (CUMULATIVE_ARGS *) arg.p; +} + +static inline cumulative_args_t +pack_cumulative_args (CUMULATIVE_ARGS *arg) +{ + cumulative_args_t ret; + +#ifdef ENABLE_CHECKING + ret.magic = CUMULATIVE_ARGS_MAGIC; +#endif /* ENABLE_CHECKING */ + ret.p = (void *) arg; + return ret; +} +#endif /* GCC_TM_H */ + #endif /* GCC_TARGET_H */ diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 48d19a05416..bcb8a12bc4e 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -170,7 +170,7 @@ default_expand_builtin_saveregs (void) } void -default_setup_incoming_varargs (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, +default_setup_incoming_varargs (cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, int *pretend_arg_size ATTRIBUTE_UNUSED, @@ -189,13 +189,13 @@ default_builtin_setjmp_frame_value (void) /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns false. */ bool -hook_bool_CUMULATIVE_ARGS_false (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED) +hook_bool_CUMULATIVE_ARGS_false (cumulative_args_t ca ATTRIBUTE_UNUSED) { return false; } bool -default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED) +default_pretend_outgoing_varargs_named (cumulative_args_t ca ATTRIBUTE_UNUSED) { return (targetm.calls.setup_incoming_varargs != default_setup_incoming_varargs); @@ -253,7 +253,7 @@ default_mode_rep_extended (enum machine_mode mode ATTRIBUTE_UNUSED, /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns true. */ bool -hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS * a ATTRIBUTE_UNUSED) +hook_bool_CUMULATIVE_ARGS_true (cumulative_args_t a ATTRIBUTE_UNUSED) { return true; } @@ -302,7 +302,7 @@ default_cxx_get_cookie_size (tree type) of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK. */ bool -hook_pass_by_reference_must_pass_in_stack (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED, +hook_pass_by_reference_must_pass_in_stack (cumulative_args_t c ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named_arg ATTRIBUTE_UNUSED) { @@ -313,7 +313,7 @@ hook_pass_by_reference_must_pass_in_stack (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED, version of the hook is true for all named arguments. */ bool -hook_callee_copies_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, +hook_callee_copies_named (cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named) { @@ -555,7 +555,7 @@ default_builtin_reciprocal (unsigned int fn ATTRIBUTE_UNUSED, bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false ( - CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { @@ -564,7 +564,7 @@ hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false ( bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true ( - CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { @@ -573,7 +573,7 @@ hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true ( int hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 ( - CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, + cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) { @@ -581,7 +581,7 @@ hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 ( } void -default_function_arg_advance (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, +default_function_arg_advance (cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) @@ -590,7 +590,7 @@ default_function_arg_advance (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, } rtx -default_function_arg (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, +default_function_arg (cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) @@ -599,7 +599,7 @@ default_function_arg (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, } rtx -default_function_incoming_arg (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, +default_function_incoming_arg (cumulative_args_t ca ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) @@ -1323,48 +1323,6 @@ default_debug_unwind_info (void) return UI_NONE; } -/* Determine the exception handling mechanism for the target. */ - -enum unwind_info_type -default_except_unwind_info (struct gcc_options *opts ATTRIBUTE_UNUSED) -{ - /* Obey the configure switch to turn on sjlj exceptions. */ -#ifdef CONFIG_SJLJ_EXCEPTIONS - if (CONFIG_SJLJ_EXCEPTIONS) - return UI_SJLJ; -#endif - - /* ??? Change all users to the hook, then poison this. */ -#ifdef DWARF2_UNWIND_INFO - if (DWARF2_UNWIND_INFO) - return UI_DWARF2; -#endif - - return UI_SJLJ; -} - -/* To be used by targets that force dwarf2 unwind enabled. */ - -enum unwind_info_type -dwarf2_except_unwind_info (struct gcc_options *opts ATTRIBUTE_UNUSED) -{ - /* Obey the configure switch to turn on sjlj exceptions. */ -#ifdef CONFIG_SJLJ_EXCEPTIONS - if (CONFIG_SJLJ_EXCEPTIONS) - return UI_SJLJ; -#endif - - return UI_DWARF2; -} - -/* To be used by targets that force sjlj unwind enabled. */ - -enum unwind_info_type -sjlj_except_unwind_info (struct gcc_options *opts ATTRIBUTE_UNUSED) -{ - return UI_SJLJ; -} - /* To be used by targets where reg_raw_mode doesn't return the right mode for registers used in apply_builtin_return and apply_builtin_arg. */ @@ -1483,20 +1441,4 @@ default_pch_valid_p (const void *data_p, size_t len) return NULL; } -/* Default version of TARGET_HANDLE_OPTION. */ - -bool -default_target_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED, - struct gcc_options *opts_set ATTRIBUTE_UNUSED, - const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED, - location_t loc ATTRIBUTE_UNUSED) -{ - return true; -} - -const struct default_options empty_optimization_table[] = - { - { OPT_LEVELS_NONE, 0, NULL, 0 } - }; - #include "gt-targhooks.h" diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 93f86bfe4b0..ce89d32afca 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -35,9 +35,9 @@ extern enum machine_mode default_cc_modes_compatible (enum machine_mode, extern bool default_return_in_memory (const_tree, const_tree); extern rtx default_expand_builtin_saveregs (void); -extern void default_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); +extern void default_setup_incoming_varargs (cumulative_args_t, enum machine_mode, tree, int *, int); extern rtx default_builtin_setjmp_frame_value (void); -extern bool default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *); +extern bool default_pretend_outgoing_varargs_named (cumulative_args_t); extern enum machine_mode default_eh_return_filter_mode (void); extern enum machine_mode default_libgcc_cmp_return_mode (void); @@ -58,9 +58,9 @@ extern tree default_cxx_guard_type (void); extern tree default_cxx_get_cookie_size (tree); extern bool hook_pass_by_reference_must_pass_in_stack - (CUMULATIVE_ARGS *, enum machine_mode mode, const_tree, bool); + (cumulative_args_t, enum machine_mode mode, const_tree, bool); extern bool hook_callee_copies_named - (CUMULATIVE_ARGS *ca, enum machine_mode, const_tree, bool); + (cumulative_args_t ca, enum machine_mode, const_tree, bool); extern void default_print_operand (FILE *, rtx, int); extern void default_print_operand_address (FILE *, rtx); @@ -96,23 +96,23 @@ extern unsigned int default_autovectorize_vector_sizes (void); /* These are here, and not in hooks.[ch], because not all users of hooks.h include tm.h, and thus we don't have CUMULATIVE_ARGS. */ -extern bool hook_bool_CUMULATIVE_ARGS_false (CUMULATIVE_ARGS *); -extern bool hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS *); +extern bool hook_bool_CUMULATIVE_ARGS_false (cumulative_args_t); +extern bool hook_bool_CUMULATIVE_ARGS_true (cumulative_args_t); extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false - (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); + (cumulative_args_t, enum machine_mode, const_tree, bool); extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true - (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); + (cumulative_args_t, enum machine_mode, const_tree, bool); extern int hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 - (CUMULATIVE_ARGS *, enum machine_mode, tree, bool); + (cumulative_args_t, enum machine_mode, tree, bool); extern const char *hook_invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree); extern void default_function_arg_advance - (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); + (cumulative_args_t, enum machine_mode, const_tree, bool); extern rtx default_function_arg - (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); + (cumulative_args_t, enum machine_mode, const_tree, bool); extern rtx default_function_incoming_arg - (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); + (cumulative_args_t, enum machine_mode, const_tree, bool); extern unsigned int default_function_arg_boundary (enum machine_mode, const_tree); extern bool hook_bool_const_rtx_commutative_p (const_rtx, int); @@ -163,9 +163,6 @@ extern reg_class_t default_preferred_rename_class (reg_class_t rclass); extern bool default_class_likely_spilled_p (reg_class_t); extern enum unwind_info_type default_debug_unwind_info (void); -extern enum unwind_info_type default_except_unwind_info (struct gcc_options *); -extern enum unwind_info_type dwarf2_except_unwind_info (struct gcc_options *); -extern enum unwind_info_type sjlj_except_unwind_info (struct gcc_options *); extern int default_label_align_after_barrier_max_skip (rtx); extern int default_loop_align_max_skip (rtx); @@ -175,12 +172,5 @@ 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 const struct default_options empty_optimization_table[]; - -extern bool default_target_handle_option (struct gcc_options *, - struct gcc_options *, - const struct cl_decoded_option *, - location_t); - extern void *default_get_pch_validity (size_t *); extern const char *default_pch_valid_p (const void *, size_t); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ffbc9f37466..7939b52153b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,318 @@ +2011-06-20 Janis Johnson <janisjo@codesourcery.com> + + * lib/scandump.exp (scan-dump, scan-dump-times, scan-dump-not, + scan-dump-dem, scan-dump-dem-not): Treat a missing dump file as + unresolved and report the reason to the log file. + + * lib/scanasm.exp (object-size): Move argument processing earlier + to report errors before verifying that the file exists. Report + problems detected at runtime as unresolved instead of error and + report their reasons to the log file. + +2011-06-20 Jason Merrill <jason@redhat.com> + + PR c++/47080 + * g++.dg/cpp0x/explicit6.C: New. + + PR c++/47635 + * g++.dg/cpp0x/enum20.C: New. + + PR c++/48138 + * g++.dg/ext/attr-aligned01.C: New. + + PR c++/49205 + * g++.dg/cpp0x/variadic-default.C: New. + + PR c++/43321 + * g++.dg/cpp0x/auto26.C: New. + + PR c++/43831 + * g++.dg/cpp0x/lambda/lambda-capture-reduncancy.C: New. + +2011-06-20 Kai Tietz <ktietz@redhat.com> + + * gcc.dg/binop-notand1.c: New test. + * gcc.dg/binop-notand2.c: New test. + * gcc.dg/binop-notand3.c: New test. + * gcc.dg/binop-notand4.c: New test. + * gcc.dg/binop-notand5.c: New test. + * gcc.dg/binop-notand6.c: New test. + +2011-06-18 Jakub Jelinek <jakub@redhat.com> + + PR testsuite/49432 + * obj-c++.dg/invalid-type-1.mm: Adjust for new error wording. + +2011-06-18 Janus Weil <janus@gcc.gnu.org> + + PR fortran/49400 + * gfortran.dg/proc_ptr_31.f90: New. + +2011-06-18 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/volatile6.adb: New test. + * gnat.dg/volatile7.adb: Likewise. + * gnat.dg/volatile8.adb: Likewise. + * gnat.dg/volatile9.adb: Likewise. + +2011-06-18 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/constant3.adb: New test. + +2011-06-18 Janne Blomqvist <jb@gcc.gnu.org> + + PR libfortran/48296 + * gfortran.dg/read_list_eof_1.f90: New test. + +2011-06-18 Jakub Jelinek <jakub@redhat.com> + + PR target/49411 + * gcc.target/i386/testimm-1.c: New test. + * gcc.target/i386/testimm-2.c: New test. + * gcc.target/i386/testimm-3.c: New test. + * gcc.target/i386/testimm-4.c: New test. + * gcc.target/i386/testimm-5.c: New test. + * gcc.target/i386/testimm-6.c: New test. + * gcc.target/i386/testimm-7.c: New test. + * gcc.target/i386/testimm-8.c: New test. + * gcc.target/i386/xop-vpermil2px-2.c: New test. + * gcc.target/i386/xop-rotate1-int.c: New test. + * gcc.target/i386/xop-rotate2-int.c: New test. + +2011-06-17 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp0x/rv-func2.C: New. + + * g++.dg/debug/dwarf2/lambda1.C: New. + * g++.dg/warn/Wshadow-6.C: Adjust. + +2011-06-17 Janus Weil <janus@gcc.gnu.org> + + PR fortran/48699 + * gfortran.dg/move_alloc_5.f90: New. + +2011-06-17 Hans-Peter Nilsson <hp@axis.com> + + PR rtl-optimization/48542 + * gcc.dg/torture/pr48542.c: New test. + +2011-06-16 Jason Merrill <jason@redhat.com> + + PR c++/44160 + * g++.dg/cpp0x/lambda/lambda-__func__.C: New. + + PR c++/45378 + * g++.dg/cpp0x/initlist52.C New. + + PR c++/45399 + * c-c++-common/raw-string-12.c: New. + + PR c++/49229 + * g++.dg/cpp0x/sfinae26.C: New. + + PR c++/49251 + * g++.dg/cpp0x/variadic113.C: New. + + PR c++/49420 + * g++.dg/cpp0x/variadic112.C: New. + +2011-06-16 Jeff Law <law@redhat.com> + + * gcc.dg/builtin-object-size-1.c: Update to handle chances from + improved jump threading. + * gcc.dg/builtin-object-size-2.c: Likewise. + * gcc.dg/tree-ssa/20030728-1.c: Likewise. + +2011-06-16 Janus Weil <janus@gcc.gnu.org> + + PR fortran/49074 + * gfortran.dg/typebound_assignment_3.f03: New. + +2011-06-16 Steve Ellcey <sje@cup.hp.com> + + PR testsuite/48727 + * g++.dg/opt/devirt2.C: Change xfail rule to target. + +2011-06-16 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/49343 + * gnat.dg/discr31.ad[sb]: New test. + +2011-06-16 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * gcc.dg/debug/pr49032.c: Prune mips-tfile warning. + +2011-06-16 Tom de Vries <tom@codesourcery.com> + + PR target/45098 + * gcc.target/arm/ivopts-3.c: Update test. + * gcc.target/arm/ivopts-5.c: Same. + +2011-06-16 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org> + + Revert + 2011-06-10 Wei Guozhi <carrot@google.com> + + PR target/45335 + * gcc.target/arm/pr45335.c: New test. + * gcc.target/arm/pr45335-2.c: New test. + * gcc.target/arm/pr45335-3.c: New test. + * gcc.target/arm/pr40457-1.c: Add another possible output "ldrd". + * gcc.target/arm/pr40457-2.c: Changed to store 3 words. + * gcc.target/arm/pr40457-3.c: Changed to store 3 words. + +2011-06-16 Ira Rosen <ira.rosen@linaro.org> + + * gcc.dg/vect/vect-widen-mult-half-u8.c: New test. + +2011-06-16 Janus Weil <janus@gcc.gnu.org> + + PR fortran/49417 + * gfortran.dg/class_43.f03: New. + +2011-06-16 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/49419 + * gcc.c-torture/execute/pr49419.c: New test. + +2011-06-16 Revital Eres <revital.eres@linaro.org> + + * gcc.dg/sms-9.c: New file. + +2011-06-15 Easwaran Raman <eraman@google.com> + + PR rtl-optimization/49414 + * gcc.dg/pr44194-1.c: Restrict test to 64-bit targets. + +2011-06-14 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp0x/noexcept13.C: New. + +2011-06-14 Easwaran Raman <eraman@google.com> + + PR rtl-optimization/44194 + * gcc.dg/pr44194-1.c: New test. + * gcc.dg/pr44194-2.c: New test. + +2011-06-14 Janis Johnson <janisjo@codesourcery.com> + + * gcc.target/arm/pr45701-1.c: Ignore warnings about conflicting switches. + * gcc.target/arm/pr45701-2.c: Likewise. + * gcc.target/arm/thumb-branch1.c: Likewise. + +2011-06-14 Steve Ellcey <sje@cup.hp.com> + + PR testsuite/48727 + * g++.dg/opt/devirt2.C: Fix scan rules for ia64*-*-hpux* and hppa*-*-*. + +2011-06-14 Janis Johnson <janisjo@codesourcery.com> + + * gcc.target/arm/pr45701-1.c: Require thumb support. + * gcc.target/arm/pr45701-2.c: Likewise. + * gcc.target/arm/thumb-branch1.c: Likewise. + + * gcc.target/arm/mla-1.c: Ignore warnings about conflicting switches. + * gcc.target/arm/pr39839.c: Likewise. + * gcc.target/arm/pr40657-2.c: Likewise. + * gcc.target/arm/pr40956.c: Likewise. + * gcc.target/arm/pr41679.c: Likewise. + * gcc.target/arm/pr42235.c: Likewise. + * gcc.target/arm/pr42495.c: Likewise. + * gcc.target/arm/pr42505.c: Likewise. + * gcc.target/arm/pr42574.c: Likewise. + * gcc.target/arm/pr46883.c: Likewise. + * gcc.target/arm/pr46934.c: Likewise. + * gcc.target/arm/xor-and.c: Likewise. + +2011-06-14 Jason Merrill <jason@redhat.com> + + * g++.dg/other/error23.C: Adjust error message. + * g++.dg/other/error32.C: Likewise. + + PR c++/49389 + * g++.dg/cpp0x/rv-dotstar.C: New. + + PR c++/49369 + * g++.dg/cpp0x/decltype30.C: New. + + * g++.dg/cpp0x/constexpr-array-ptr7.C: New. + +2011-06-14 Jakub Jelinek <jakub@redhat.com> + + PR fortran/49103 + * gfortran.dg/pr49103.f90: New test. + +2011-06-14 Tom de Vries <tom@codesourcery.com> + + PR target/45098 + * gcc.target/arm/ivopts-3.c: New test. + * gcc.target/arm/ivopts-4.c: New test. + * gcc.target/arm/ivopts-5.c: New test. + +2011-06-14 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/49390 + * gcc.c-torture/execute/pr49390.c: New test. + +2011-06-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * g++.dg/torture/pr48954.C: Use dg-require-effective-target lto. + +2011-06-14 Georg-Johann Lay <avr@gjlay.de> + + * gcc.c-torture/execute/cmpsi-2.c: Undo 172757. + * gcc.c-torture/execute/cmpsi-2.x: New file. + * gcc.c-torture/execute/pr45262.c: Undo 172757. + * gcc.c-torture/execute/pr45262.x: New file. + * gcc.c-torture/compile/pr46534.c: Skip for AVR. + * gcc.c-torture/compile/pr49029.c: Add dg-require-effective-target + int32plus + * gcc.c-torture/compile/pr49163.c: Ditto. + +2011-06-14 Ira Rosen <ira.rosen@linaro.org> + + * gcc.dg/vect/vect-16.c: Rename to... + * gcc.dg/vect/no-fast-math-vect16.c: ...this. + * gcc.dg/vect/vect-peel-3.c: Adjust misalignment values + for double-word vectors. + * gcc.dg/vect/vect-peel-4.c: Likewise. + * gcc.dg/vect/bb-slp-10.c: Replace vect_hw_misalign with + vect_element_align. + * gcc.dg/vect/vect.exp: Run no-fast-math-* tests with + -fno-fast-math. + +2011-06-13 Edmar Wienskoski <edmar@freescale.com> + + PR target/44618 + * gcc.target/powerpc/outofline_rnreg.c: New testcase. + +2011-06-13 H.J. Lu <hongjiu.lu@intel.com> + + * gcc.dg/h8300-bit-insn-ice2.c: Remove duplicated lines. + +2011-06-13 Kaushik Phatak <kaushik.phatak@kpitcummins.com> + + * gcc.dg/h8300-bit-insn-ice2.c: New testcase. + +2011-06-13 Thomas Koenig <tkoenig@gcc.gnu.org> + + * gfortran.dg/trim_optimize_8.f90: New test case. + +2011-06-13 Jakub Jelinek <jakub@redhat.com> + Ira Rosen <ira.rosen@linaro.org> + + PR tree-optimization/49352 + * gcc.dg/vect/pr49352.c: New test. + +2011-06-12 Tobias Burnus + + PR fortran/49324 + * gfortran.dg/alloc_comp_assign_11.f90: New. + +2011-05-11 Thomas Koenig <tkoenig@gcc.gnu.org> + + * gfortran.dg/trim_optimize_7.f90: New test. + 2011-06-10 Wei Guozhi <carrot@google.com> PR target/45335 diff --git a/gcc/testsuite/c-c++-common/raw-string-12.c b/gcc/testsuite/c-c++-common/raw-string-12.c Binary files differnew file mode 100644 index 00000000000..5bdf3b9d8f8 --- /dev/null +++ b/gcc/testsuite/c-c++-common/raw-string-12.c diff --git a/gcc/testsuite/g++.dg/cpp0x/auto26.C b/gcc/testsuite/g++.dg/cpp0x/auto26.C new file mode 100644 index 00000000000..6e55aa451ac --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/auto26.C @@ -0,0 +1,21 @@ +// PR c++/43321 +// { dg-options -std=c++0x } + +template <class T> +void f(T t) +{ + auto *p = t; +} + +template <class T> +void g(const T& tr) +{ + auto p = *tr; +} + +int main() +{ + int b; + f(&b); + g(&b); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array-ptr7.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-array-ptr7.C new file mode 100644 index 00000000000..44775c0703c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-array-ptr7.C @@ -0,0 +1,20 @@ +// PR c++/49290 +// { dg-options -std=c++0x } + +typedef unsigned T; +struct S +{ + constexpr T foo (void); + unsigned s1[16]; +}; + +constexpr T +S::foo () +{ + return *(T *) (s1 + 10); +} + +constexpr S s = { 0,1,2,3,4,5,6,7,8,9,10 }; + +#define SA(X) static_assert ((X), #X) +SA(s.foo() == 10); diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype30.C b/gcc/testsuite/g++.dg/cpp0x/decltype30.C new file mode 100644 index 00000000000..b23c9a94d8f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype30.C @@ -0,0 +1,17 @@ +// PR c++/49369 +// { dg-options -std=c++0x } + +template <class,class> struct assert_same; +template <class T> struct assert_same<T,T> {}; + +struct B { + int member; +}; + +struct C: B { + void method() const; +}; + +void C::method() const { + assert_same<decltype((B::member)), const int&> a; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/enum20.C b/gcc/testsuite/g++.dg/cpp0x/enum20.C new file mode 100644 index 00000000000..e5dc186e4af --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum20.C @@ -0,0 +1,5 @@ +// PR c++/47635 +// { dg-options -std=c++0x } + +enum A { }; +void A::f() { } // { dg-error "not a class" } diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit6.C b/gcc/testsuite/g++.dg/cpp0x/explicit6.C new file mode 100644 index 00000000000..0d620be0803 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/explicit6.C @@ -0,0 +1,11 @@ +// PR c++/47080 +// { dg-options -std=c++0x } + +struct A { + explicit operator int(); // { dg-message "qualification conversion" } +}; + +int main() { + bool b((A())); // { dg-error "invalid user-defined" } + !A(); // { dg-error "" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist52.C b/gcc/testsuite/g++.dg/cpp0x/initlist52.C new file mode 100644 index 00000000000..22bc2873c7c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist52.C @@ -0,0 +1,7 @@ +// PR c++/45378 +// { dg-options -std=c++0x } + +int main() +{ + int x { 22.2 }; // { dg-error "narrowing" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-__func__.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-__func__.C new file mode 100644 index 00000000000..1cc7bb65833 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-__func__.C @@ -0,0 +1,9 @@ +// PR c++/44160 +// { dg-options -std=c++0x } +// { dg-do link } + +int main() +{ + const char *p = []() { return __func__; }(); + return p == 0; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-capture-redundancy.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-capture-redundancy.C new file mode 100644 index 00000000000..51e55a7aa4c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-capture-redundancy.C @@ -0,0 +1,12 @@ +// FDIS 5.1.2/8 +// { dg-options "-pedantic-errors -std=c++0x" } + +struct S2 { void f(int i); }; +void S2::f(int i) { + [&, i]{ }; // OK + [&, &i]{ }; // { dg-error "" } i preceded by & when & is the default + [=, i]{ }; // { dg-error "" } i not preceded by & when = is the default + [=, this]{ }; // { dg-error "" } this when = is the default + [i, i]{ }; // { dg-error "" } i repeated + [this, this]{ }; // { dg-error "" } i repeated +} diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept13.C b/gcc/testsuite/g++.dg/cpp0x/noexcept13.C new file mode 100644 index 00000000000..7d51c82b549 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept13.C @@ -0,0 +1,78 @@ +// PR c++/49107 +// { dg-options -std=c++0x } + +namespace std +{ + template<typename _Tp> _Tp&& declval() noexcept; + + struct true_type { static const bool value = true; }; + struct false_type { static const bool value = false; }; + + template<typename _Tp, typename _Arg> + struct __is_direct_constructible_impl + { + template<typename _Tp2, typename _Arg2, typename + = decltype(::new _Tp2(declval<_Arg2>()))> + static true_type __test(int); + + template<typename, typename> + static false_type __test(...); + + typedef decltype(__test<_Tp, _Arg>(0)) type; + }; + + template<typename _Tp, typename _Arg> + struct __is_direct_constructible_new_safe + : public __is_direct_constructible_impl<_Tp, _Arg>::type + { }; + + template<class _T1, class _T2> + struct pair + { + pair() = default; + constexpr pair(const pair&) = default; + + pair(pair&& __p) + noexcept(__is_direct_constructible_new_safe<_T2,_T2&&>::value); + }; +} + +template <class R_> +struct Vector3 +{ + typedef typename R_::Ray_3 Ray_3; + Vector3() {} + explicit Vector3(const Ray_3& r); +}; + +template < class R_ > class LineC3 +{ + typedef typename R_::Vector_3 Vector_3; + std::pair<int, Vector_3> x; +}; + +template < class R_ > class RayH3 +{ + typedef typename R_::Vector_3 Vector_3; + std::pair<int, Vector_3> x; +}; + +template <typename Kernel > +struct Homogeneous_base +{ + typedef LineC3<Kernel> Line_3; + typedef RayH3<Kernel> Ray_3; +}; + +template < typename RT_> +struct Simple_homogeneous +: public Homogeneous_base< Simple_homogeneous<RT_> > +{ + typedef Vector3<Simple_homogeneous<RT_> > Vector_3; +}; + +int main() +{ + typedef Simple_homogeneous<double> R; + R::Line_3 l3; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-dotstar.C b/gcc/testsuite/g++.dg/cpp0x/rv-dotstar.C new file mode 100644 index 00000000000..65aac8da2a1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/rv-dotstar.C @@ -0,0 +1,13 @@ +// PR c++/49389 +// { dg-options -std=c++0x } + +template<class T> T&& val(); + +struct A {}; + +typedef decltype(val<A>().*val<int A::*>()) type; + +template<class> struct assert_type; +template<> struct assert_type<int&&> {}; + +assert_type<type> test; diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-func2.C b/gcc/testsuite/g++.dg/cpp0x/rv-func2.C new file mode 100644 index 00000000000..b792342dada --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/rv-func2.C @@ -0,0 +1,10 @@ +// PR c++/49458 +// { dg-options -std=c++0x } + +typedef void ftype(); + +struct A { + operator ftype&(void); +}; + +ftype &&frvref = A(); diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae26.C b/gcc/testsuite/g++.dg/cpp0x/sfinae26.C new file mode 100644 index 00000000000..5b8cdd9f545 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae26.C @@ -0,0 +1,38 @@ +// PR c++/49229 +// { dg-options -std=c++0x } + +extern void* enabler; + +template<bool, class = void> +struct enable_if {}; + +template<class T> +struct enable_if<true, T> { + typedef T type; +}; + +template<class... Bn> +struct and_; + +template<class B1> +struct and_<B1> : B1 {}; + +template<class, class> +struct is_same { + static constexpr bool value = false; +}; + +template<class T> +struct is_same<T, T> { + static constexpr bool value = true; +}; + +template<class... T> +struct S { + template<class... U, + typename enable_if<and_<is_same<T, U>...>::value>::type*& = enabler + > + S(U...){} // # +}; + +S<bool> s(0); // { dg-error "no match" } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-default.C b/gcc/testsuite/g++.dg/cpp0x/variadic-default.C new file mode 100644 index 00000000000..2625e259f78 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-default.C @@ -0,0 +1,12 @@ +// PR c++/49205 +// { dg-options -std=c++0x } + +#include <initializer_list> + +struct A { + template<typename ...T> A(T...); + A(std::initializer_list<short>); + A(std::initializer_list<long>); +}; + +A a{}; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic112.C b/gcc/testsuite/g++.dg/cpp0x/variadic112.C new file mode 100644 index 00000000000..1640657d950 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic112.C @@ -0,0 +1,19 @@ +// PR c++/49420 +// { dg-options -std=c++0x } + +struct A { }; + +template <class T> struct B +{ + typedef typename T::type type ; // { dg-error "no type" } +}; + +template <typename Array, typename... Args> +typename B<Array>::type +get(const Array& a, Args... args); + +int main() +{ + A a; + int x = get(a, 1, 2, 3); // { dg-error "no match" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic113.C b/gcc/testsuite/g++.dg/cpp0x/variadic113.C new file mode 100644 index 00000000000..3f1bb2ad04a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic113.C @@ -0,0 +1,20 @@ +// PR c++/49251 +// { dg-options "-std=c++0x -Wunused-parameter" } + +struct A {}; +template <int> int f(A); + +template< int... Indices > +struct indices {}; + +template< class... Args > +void sink( Args&&... ) {} + +template< class T, int... Indices > +void unpack_test( T && t, indices<Indices...> ) { + sink( f<Indices>(t)... ); +} + +int main() { + unpack_test( A(), indices<>() ); +} diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/lambda1.C b/gcc/testsuite/g++.dg/debug/dwarf2/lambda1.C new file mode 100644 index 00000000000..ee24eca22a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/lambda1.C @@ -0,0 +1,35 @@ +// PR c++/43912 +// { dg-options "-g -std=c++0x -dA -fno-merge-debug-strings -gno-strict-dwarf" } + +// Check for the local alias variables that point to the members of the closure. +// { dg-final { scan-assembler-times "DW_TAG_variable\[^.\]*\.ascii \"j.0\"" 4 } } +// { dg-final { scan-assembler-times "DW_TAG_variable\[^.\]*\.ascii \"this.0\"" 2 } } + +struct A +{ + int i; + int f() + { + int j; + [&]() { j = i; }(); + return j; + } +}; + +template <class T> +struct B +{ + int i; + int f() + { + int j; + [&]() { j = i; }(); + return j; + } +}; + +int main() +{ + A().f(); + B<int>().f(); +} diff --git a/gcc/testsuite/g++.dg/ext/attr-aligned01.C b/gcc/testsuite/g++.dg/ext/attr-aligned01.C new file mode 100644 index 00000000000..a051c6e98d3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-aligned01.C @@ -0,0 +1,20 @@ +// PR c++/48138 +// { dg-options -std=c++0x } + +#define ALIGNED(x) __attribute__((aligned(x))) +#define SA(X) static_assert ((X),#X) + +template<typename T> +void type_alignment(const T&) { + struct { char c; T t; } s; + SA((char*)&s.t - (char*)&s.c == 8); +} + +int main() { + typedef char unaligned[15]; + typedef char aligned[15] ALIGNED(8); + + aligned z; + type_alignment(z); + type_alignment<unaligned ALIGNED(8)>(z); +} diff --git a/gcc/testsuite/g++.dg/opt/devirt2.C b/gcc/testsuite/g++.dg/opt/devirt2.C index 087dd179115..e6dd7d62114 100644 --- a/gcc/testsuite/g++.dg/opt/devirt2.C +++ b/gcc/testsuite/g++.dg/opt/devirt2.C @@ -1,6 +1,10 @@ // { dg-do compile } // { dg-options "-O2" } -// { dg-final { scan-assembler-times "xyzzy" 2 } } +// The IA64 and HPPA compilers generate external declarations in addition +// to the call so those scans need to be more specific. +// { dg-final { scan-assembler-times "xyzzy" 2 { target { ! { hppa*-*-* ia64*-*-hpux* } } } } } +// { dg-final { scan-assembler-times "br\[^\n\]*xyzzy" 2 { target ia64*-*-hpux* } } } +// { dg-final { scan-assembler-times "xyzzy\[^\n\]*,%r" 2 { target hppa*-*-* } } } struct S { S(); virtual void xyzzy(); }; struct R { int a; S s; R(); }; diff --git a/gcc/testsuite/g++.dg/other/error23.C b/gcc/testsuite/g++.dg/other/error23.C index 0ff1915cf2c..959fe4075e6 100644 --- a/gcc/testsuite/g++.dg/other/error23.C +++ b/gcc/testsuite/g++.dg/other/error23.C @@ -2,4 +2,4 @@ // { dg-do compile } int v __attribute ((vector_size (8))); -bool b = !(v - v); // { dg-error "could not convert .\\(__vector.2. int\\)\\{0, 0\\}. to .bool.|in argument to unary" } +bool b = !(v - v); // { dg-error "could not convert .\\(__vector.2. int\\)\\{0, 0\\}. from .__vector.2. int. to .bool.|in argument to unary" } diff --git a/gcc/testsuite/g++.dg/other/error32.C b/gcc/testsuite/g++.dg/other/error32.C index 35c64c4eab9..56d3b7aec8b 100644 --- a/gcc/testsuite/g++.dg/other/error32.C +++ b/gcc/testsuite/g++.dg/other/error32.C @@ -3,6 +3,6 @@ void foo() { - if (throw 0) // { dg-error "could not convert .\\<throw-expression\\>. to .bool." } + if (throw 0) // { dg-error "could not convert .\\<throw-expression\\>. from .void. to .bool." } ; } diff --git a/gcc/testsuite/g++.dg/torture/pr48954.C b/gcc/testsuite/g++.dg/torture/pr48954.C index 1af03289b24..bdd1200049f 100644 --- a/gcc/testsuite/g++.dg/torture/pr48954.C +++ b/gcc/testsuite/g++.dg/torture/pr48954.C @@ -1,5 +1,7 @@ /* { dg-do compile } */ /* { dg-options "-O2 -flto -fno-early-inlining -fkeep-inline-functions" } */ +/* { dg-require-effective-target lto } */ + struct A { virtual void foo () = 0; diff --git a/gcc/testsuite/g++.dg/warn/Wshadow-6.C b/gcc/testsuite/g++.dg/warn/Wshadow-6.C index 9b13e3ae79e..fdc37df31b4 100644 --- a/gcc/testsuite/g++.dg/warn/Wshadow-6.C +++ b/gcc/testsuite/g++.dg/warn/Wshadow-6.C @@ -33,7 +33,19 @@ void f2(struct S i, int j) { void f3(int i) { [=]{ - int j = i; - int i; // { dg-warning "shadows a member of" } + int j = i; // { dg-warning "shadowed declaration" } + int i; // { dg-warning "shadows a lambda capture" } + i = 1; }; } + +template <class T> +void f4(int i) { + [=]{ + int j = i; // { dg-warning "shadowed declaration" } + int i; // { dg-warning "shadows a lambda capture" } + i = 1; + }; +} + +template void f4<int>(int); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr46534.c b/gcc/testsuite/gcc.c-torture/compile/pr46534.c index dc3c967cc2a..67c8ad21ebf 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr46534.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr46534.c @@ -1,4 +1,4 @@ -/* { dg-skip-if "too big" { pdp11-*-* } { "*" } { "" } } */ +/* { dg-skip-if "too big" { avr-*-* pdp11-*-* } { "*" } { "" } } */ /* PR middle-end/46534 */ extern int printf (const char *, ...); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr49029.c b/gcc/testsuite/gcc.c-torture/compile/pr49029.c index ebe81b31b28..71199d44515 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr49029.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr49029.c @@ -1,4 +1,5 @@ /* PR middle-end/49029 */ +/* { dg-require-effective-target int32plus } */ struct S { volatile unsigned f : 11; signed g : 30; } __attribute__((packed)); struct T { volatile struct S h; } __attribute__((packed)) a; void foo (int); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr49163.c b/gcc/testsuite/gcc.c-torture/compile/pr49163.c index f14ab1531e6..4f3b056053e 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr49163.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr49163.c @@ -1,4 +1,5 @@ /* PR target/49163 */ +/* { dg-require-effective-target int32plus } */ struct S1 { unsigned f0:18; diff --git a/gcc/testsuite/gcc.c-torture/execute/cmpsi-2.c b/gcc/testsuite/gcc.c-torture/execute/cmpsi-2.c index 4378b719e83..62832a9bffc 100644 --- a/gcc/testsuite/gcc.c-torture/execute/cmpsi-2.c +++ b/gcc/testsuite/gcc.c-torture/execute/cmpsi-2.c @@ -1,5 +1,3 @@ -/* { dg-require-effective-target int32plus } */ - #define F 140 #define T 13 diff --git a/gcc/testsuite/gcc.c-torture/execute/cmpsi-2.x b/gcc/testsuite/gcc.c-torture/execute/cmpsi-2.x new file mode 100644 index 00000000000..121fcfecc2c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/cmpsi-2.x @@ -0,0 +1,7 @@ +load_lib target-supports.exp + +if { [check_effective_target_int16] } { + return 1 +} + +return 0; diff --git a/gcc/testsuite/gcc.c-torture/execute/pr45262.c b/gcc/testsuite/gcc.c-torture/execute/pr45262.c index e94f4ff29ec..72e186bf287 100644 --- a/gcc/testsuite/gcc.c-torture/execute/pr45262.c +++ b/gcc/testsuite/gcc.c-torture/execute/pr45262.c @@ -1,5 +1,4 @@ /* PR middle-end/45262 */ -/* { dg-require-effective-target int32plus } */ extern void abort (void); diff --git a/gcc/testsuite/gcc.c-torture/execute/pr45262.x b/gcc/testsuite/gcc.c-torture/execute/pr45262.x new file mode 100644 index 00000000000..121fcfecc2c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr45262.x @@ -0,0 +1,7 @@ +load_lib target-supports.exp + +if { [check_effective_target_int16] } { + return 1 +} + +return 0; diff --git a/gcc/testsuite/gcc.c-torture/execute/pr49390.c b/gcc/testsuite/gcc.c-torture/execute/pr49390.c new file mode 100644 index 00000000000..dfcdea16fc0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr49390.c @@ -0,0 +1,88 @@ +/* PR rtl-optimization/49390 */ + +struct S { unsigned int s1; unsigned int s2; }; +struct T { unsigned int t1; struct S t2; }; +struct U { unsigned short u1; unsigned short u2; }; +struct V { struct U v1; struct T v2; }; +struct S a; +char *b; +union { char b[64]; struct V v; } u; +volatile int v; +extern void abort (void); + +__attribute__((noinline, noclone)) void +foo (int x, void *y, unsigned int z, unsigned int w) +{ + if (x != 4 || y != (void *) &u.v.v2) + abort (); + v = z + w; + v = 16384; +} + +__attribute__((noinline, noclone)) void +bar (struct S x) +{ + v = x.s1; + v = x.s2; +} + +__attribute__((noinline, noclone)) int +baz (struct S *x) +{ + v = x->s1; + v = x->s2; + v = 0; + return v + 1; +} + +__attribute__((noinline, noclone)) void +test (struct S *c) +{ + struct T *d; + struct S e = a; + unsigned int f, g; + if (c == 0) + c = &e; + else + { + if (c->s2 % 8192 <= 15 || (8192 - c->s2 % 8192) <= 31) + foo (1, 0, c->s1, c->s2); + } + if (!baz (c)) + return; + g = (((struct U *) b)->u2 & 2) ? 32 : __builtin_offsetof (struct V, v2); + f = c->s2 % 8192; + if (f == 0) + { + e.s2 += g; + f = g; + } + else if (f < g) + { + foo (2, 0, c->s1, c->s2); + return; + } + if ((((struct U *) b)->u2 & 1) && f == g) + { + bar (*c); + foo (3, 0, c->s1, c->s2); + return; + } + d = (struct T *) (b + c->s2 % 8192); + if (d->t2.s1 >= c->s1 && (d->t2.s1 != c->s1 || d->t2.s2 >= c->s2)) + foo (4, d, c->s1, c->s2); + return; +} + +int +main () +{ + struct S *c = 0; + asm ("" : "+r" (c) : "r" (&a)); + u.v.v2.t2.s1 = 8192; + b = u.b; + test (c); + if (v != 16384) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr49419.c b/gcc/testsuite/gcc.c-torture/execute/pr49419.c new file mode 100644 index 00000000000..fddc1646202 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr49419.c @@ -0,0 +1,38 @@ +/* PR tree-optimization/49419 */ + +extern void abort (void); + +struct S { int w, x, y; } *t; + +int +foo (int n, int f, int *s, int m) +{ + int x, i, a; + if (n == -1) + return 0; + for (x = n, i = 0; t[x].w == f && i < m; i++) + x = t[x].x; + if (i == m) + abort (); + a = i + 1; + for (x = n; i > 0; i--) + { + s[i] = t[x].y; + x = t[x].x; + } + s[0] = x; + return a; +} + +int +main (void) +{ + int s[3], i; + struct S buf[3] = { { 1, 1, 2 }, { 0, 0, 0 }, { 0, 0, 0 } }; + t = buf; + if (foo (0, 1, s, 3) != 2) + abort (); + if (s[0] != 1 || s[1] != 2) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/binop-notand1.c b/gcc/testsuite/gcc.dg/binop-notand1.c new file mode 100644 index 00000000000..cadf7e532c5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/binop-notand1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int +foo (int a, int b) +{ + return (a & !a) | (b & !b); +} + +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/binop-notand2.c b/gcc/testsuite/gcc.dg/binop-notand2.c new file mode 100644 index 00000000000..0076d4be7a1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/binop-notand2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int +foo (int a) +{ + return (!a & 1) != (a == 0); +} + +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/binop-notand3.c b/gcc/testsuite/gcc.dg/binop-notand3.c new file mode 100644 index 00000000000..5f8e32ff8fa --- /dev/null +++ b/gcc/testsuite/gcc.dg/binop-notand3.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int +foo (int a) +{ + return (!a & 1) != ((a == 0) & 1); +} + +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/binop-notand4.c b/gcc/testsuite/gcc.dg/binop-notand4.c new file mode 100644 index 00000000000..1c3fefd61e9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/binop-notand4.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int +foo (int a, int b) +{ + return (!a & a) | (b & !b); +} + +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/binop-notand5.c b/gcc/testsuite/gcc.dg/binop-notand5.c new file mode 100644 index 00000000000..463f19b04da --- /dev/null +++ b/gcc/testsuite/gcc.dg/binop-notand5.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int +foo (int a, int b) +{ + return (a & (a == 0)) | (b & !b); +} + +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/binop-notand6.c b/gcc/testsuite/gcc.dg/binop-notand6.c new file mode 100644 index 00000000000..e1882aca679 --- /dev/null +++ b/gcc/testsuite/gcc.dg/binop-notand6.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int +foo (int a, int b) +{ + return (a & !a) | (b & (b == 0)); +} + +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-1.c b/gcc/testsuite/gcc.dg/builtin-object-size-1.c index 404b7117f88..13ebeb15b25 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-1.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-1.c @@ -64,7 +64,11 @@ test1 (void *q, int x) r = malloc (30); else r = calloc (2, 16); - if (__builtin_object_size (r, 0) != 2 * 16) + /* We may duplicate this test onto the two exit paths. On one path + the size will be 32, the other it will be 30. If we don't duplicate + this test, then the size will be 32. */ + if (__builtin_object_size (r, 0) != 2 * 16 + && __builtin_object_size (r, 0) != 30) abort (); if (x < 20) r = malloc (30); diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-2.c b/gcc/testsuite/gcc.dg/builtin-object-size-2.c index 34f16759d68..21aff5a958d 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-2.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-2.c @@ -60,7 +60,11 @@ test1 (void *q, int x) r = malloc (30); else r = calloc (2, 16); - if (__builtin_object_size (r, 1) != 2 * 16) + /* We may duplicate this test onto the two exit paths. On one path + the size will be 32, the other it will be 30. If we don't duplicate + this test, then the size will be 32. */ + if (__builtin_object_size (r, 1) != 2 * 16 + && __builtin_object_size (r, 1) != 30) abort (); if (x < 20) r = malloc (30); diff --git a/gcc/testsuite/gcc.dg/debug/pr49032.c b/gcc/testsuite/gcc.dg/debug/pr49032.c index 3985040d712..9074c756452 100644 --- a/gcc/testsuite/gcc.dg/debug/pr49032.c +++ b/gcc/testsuite/gcc.dg/debug/pr49032.c @@ -1,5 +1,7 @@ /* PR debug/49032 */ /* { dg-do link } */ +/* Prune mips-tfile warning on alpha*-dec-osf* with -gcoff* -O*. */ +/* { dg-prune-output "warning, s not found in .*symbol tables" } */ static int s = 42; diff --git a/gcc/testsuite/gcc.dg/h8300-bit-insn-ice2.c b/gcc/testsuite/gcc.dg/h8300-bit-insn-ice2.c new file mode 100644 index 00000000000..8b5f628759b --- /dev/null +++ b/gcc/testsuite/gcc.dg/h8300-bit-insn-ice2.c @@ -0,0 +1,15 @@ +/* { dg-skip-if "" { "h8300*-*-*" } "*" "-msx*" } */ +/* { dg-options "-O2" } */ +/* ICE for bit instruction generation using 16-bit const */ + +#define MSTPCRA (*(volatile unsigned char*)0xFFFFC9) +#define MSTPCRA2 (*(volatile unsigned char*)0xFFFDC8) + +int +main (void) +{ + MSTPCRA = MSTPCRA2 & ~0x01; + MSTPCRA = MSTPCRA2 ^ ~0xFE; + MSTPCRA = MSTPCRA2 | ~0xFE; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr44194-1.c b/gcc/testsuite/gcc.dg/pr44194-1.c new file mode 100644 index 00000000000..4804d83c203 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr44194-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-rtl-dse1" } */ +/* { dg-require-effective-target lp64 } */ +/* Restricting to 64-bit targets since 32-bit targets return + structures in memory. */ + +#include <stdint.h> + +struct ints { int a, b, c; } foo(); +void bar(int a, int b); + +void func() { + struct ints s = foo(); + bar(s.a, s.b); +} +/* { dg-final { scan-rtl-dump "global deletions = 2" "dse1" } } */ +/* { dg-final { cleanup-rtl-dump "dse1" } } */ diff --git a/gcc/testsuite/gcc.dg/pr44194-2.c b/gcc/testsuite/gcc.dg/pr44194-2.c new file mode 100644 index 00000000000..3548542c40f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr44194-2.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-rtl-dse1" } */ +#include <stdint.h> + +struct ints { int a, b, c; } foo(); +void bar(int a, int b); + +void func() { + volatile struct ints s = foo(); + bar(s.a, s.b); +} +/* { dg-final { scan-rtl-dump "global deletions = 0" "dse1" } } */ +/* { dg-final { cleanup-rtl-dump "dse1" } } */ diff --git a/gcc/testsuite/gcc.dg/sms-9.c b/gcc/testsuite/gcc.dg/sms-9.c new file mode 100644 index 00000000000..9d1f8814257 --- /dev/null +++ b/gcc/testsuite/gcc.dg/sms-9.c @@ -0,0 +1,60 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fmodulo-sched -fno-auto-inc-dec -O2 -fmodulo-sched-allow-regmoves" } */ + +#include <stdlib.h> +#include <stdarg.h> + +struct df_ref_info +{ + unsigned int *begin; + unsigned int *count; +}; + +extern void *memset (void *s, int c, __SIZE_TYPE__ n); + + +__attribute__ ((noinline)) +int +df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info, + int num, unsigned int start) +{ + unsigned int m = num; + unsigned int offset = 77; + unsigned int r; + + for (r = start; r < m; r++) + { + ref_info->begin[r] = offset; + offset += ref_info->count[r]; + ref_info->count[r] = 0; + } + + return offset; +} + +int +main () +{ + struct df_ref_info temp; + int num = 100; + unsigned int start = 5; + int i, offset; + + temp.begin = malloc (100 * sizeof (unsigned int)); + temp.count = malloc (100 * sizeof (unsigned int)); + + memset (temp.begin, 0, sizeof (unsigned int) * num); + memset (temp.count, 0, sizeof (unsigned int) * num); + + for (i = 0; i < num; i++) + temp.count[i] = i + 1; + + offset = df_reorganize_refs_by_reg_by_insn (&temp, num, start); + + if (offset != 5112) + abort (); + + free (temp.begin); + free (temp.count); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr48542.c b/gcc/testsuite/gcc.dg/torture/pr48542.c new file mode 100644 index 00000000000..e3e49489f7d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr48542.c @@ -0,0 +1,57 @@ +/* { dg-do run } */ +/* The return-address was clobbered. */ +#include <stdlib.h> +#include <setjmp.h> + +jmp_buf env; +extern void sub(void); +extern void sub3(void); +int called; +__attribute__ ((__noinline__)) +int sjtest() +{ + int i; + if (setjmp(env)) + return 99; + + for (i = 0; i < 10; i++) + sub(); + + longjmp(env, 1); +} + +__attribute__ ((__noinline__)) +void sub(void) +{ + called++; +} + +int called3; +__attribute__ ((__noinline__)) +int sjtest3() +{ + int i; + if (setjmp(env)) + return 42; + + for (i = 0; i < 10; i++) + sub3(); + return 0; +} + +__attribute__ ((__noinline__)) +void sub3(void) +{ + called3++; + if (called3 == 10) + longjmp (env, 1); +} + +int main(void) +{ + if (sjtest() != 99 || called != 10) + abort(); + if (sjtest3() != 42 || called3 != 10) + abort(); + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c index f884736a1c9..93a7979c56f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c @@ -41,7 +41,9 @@ objects_must_conflict_p (t1, t2) return foo (t2 ? get_alias_set (t2) : 0); } -/* There should be two assignments of variables to the value zero. */ -/* { dg-final { scan-rtl-dump-times "PART.. = 0" 2 "expand"} } */ +/* There should be one assignment of variables to the value zero. There + used to be two assignments, but improvements in threading allowed the + second to be propagated into all its uses and eliminated. */ +/* { dg-final { scan-rtl-dump-times "PART.. = 0" 1 "expand"} } */ /* { dg-final { cleanup-rtl-dump "expand" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-10.c b/gcc/testsuite/gcc.dg/vect/bb-slp-10.c index 014f80f8a7e..f127c7f11ef 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-10.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-10.c @@ -49,7 +49,7 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "unsupported alignment in basic block." 1 "slp" { xfail vect_hw_misalign } } } */ -/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_hw_misalign } } } */ +/* { dg-final { scan-tree-dump-times "unsupported alignment in basic block." 1 "slp" { xfail vect_element_align } } } */ +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_element_align } } } */ /* { dg-final { cleanup-tree-dump "slp" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-16.c b/gcc/testsuite/gcc.dg/vect/no-fast-math-vect16.c index 69837052904..69837052904 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-16.c +++ b/gcc/testsuite/gcc.dg/vect/no-fast-math-vect16.c diff --git a/gcc/testsuite/gcc.dg/vect/pr49352.c b/gcc/testsuite/gcc.dg/vect/pr49352.c new file mode 100644 index 00000000000..26f364b0cd4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr49352.c @@ -0,0 +1,14 @@ +/* PR tree-optimization/49352 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -fcompare-debug" } */ + +int +foo (int *x, int *y, int n) +{ + int i, j; + int dot = 0; + for (i = 0; i < n; i++) + for (j = 0; j < 2; j++) + dot += *(x++) * *(y++); + return dot; +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-peel-3.c b/gcc/testsuite/gcc.dg/vect/vect-peel-3.c index bc8adb46008..5049b40b106 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-peel-3.c +++ b/gcc/testsuite/gcc.dg/vect/vect-peel-3.c @@ -4,9 +4,7 @@ #include "tree-vect.h" #define N 128 -#define RES 21888 - -/* unaligned store. */ +#define RES 21640 int ib[N+10]; int ia[N+10]; @@ -18,11 +16,11 @@ int main1 () int i, suma = 0, sumb = 0, sumc = 0; /* ib and ic have same misalignment, we peel to align them. */ - for (i = 1; i <= N; i++) + for (i = 0; i <= N; i++) { suma += ia[i]; - sumb += ib[i+6]; - sumc += ic[i+2]; + sumb += ib[i+5]; + sumc += ic[i+1]; } /* check results: */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-peel-4.c b/gcc/testsuite/gcc.dg/vect/vect-peel-4.c index a71d4c4eba0..a52075e34ac 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-peel-4.c +++ b/gcc/testsuite/gcc.dg/vect/vect-peel-4.c @@ -16,13 +16,13 @@ int main1 () /* Don't peel keeping one load and the store aligned. */ for (i = 0; i <= N; i++) { - ia[i] = ib[i] + ib[i+6]; + ia[i] = ib[i] + ib[i+5]; } /* check results: */ for (i = 1; i <= N; i++) { - if (ia[i] != ib[i] + ib[i+6]) + if (ia[i] != ib[i] + ib[i+5]) abort (); } diff --git a/gcc/testsuite/gcc.dg/vect/vect-widen-mult-half-u8.c b/gcc/testsuite/gcc.dg/vect/vect-widen-mult-half-u8.c new file mode 100644 index 00000000000..39078dfc4f3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-widen-mult-half-u8.c @@ -0,0 +1,59 @@ +/* { dg-require-effective-target vect_int } */ + +#include "tree-vect.h" +#include <stdlib.h> + +#define N 32 +#define COEF 32470 + +unsigned char in[N]; +int out[N]; + +__attribute__ ((noinline)) void +foo () +{ + int i; + + for (i = 0; i < N; i++) + out[i] = in[i] * COEF; +} + +__attribute__ ((noinline)) void +bar () +{ + int i; + + for (i = 0; i < N; i++) + out[i] = COEF * in[i]; +} + +int main (void) +{ + int i; + + for (i = 0; i < N; i++) + { + in[i] = i; + __asm__ volatile (""); + } + + foo (); + + for (i = 0; i < N; i++) + if (out[i] != in[i] * COEF) + abort (); + + bar (); + + for (i = 0; i < N; i++) + if (out[i] != in[i] * COEF) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_widen_mult_hi_to_si } } } */ +/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */ +/* { dg-final { scan-tree-dump-times "pattern recognized" 2 "vect" { target vect_widen_mult_hi_to_si_pattern } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect.exp b/gcc/testsuite/gcc.dg/vect/vect.exp index e0821d0f514..fd92da8707c 100644 --- a/gcc/testsuite/gcc.dg/vect/vect.exp +++ b/gcc/testsuite/gcc.dg/vect/vect.exp @@ -107,6 +107,12 @@ lappend DEFAULT_VECTCFLAGS "-ffast-math" dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/fast-math-*.\[cS\]]] \ "" $DEFAULT_VECTCFLAGS +# -fno-fast-math tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-fast-math" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-fast-math-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + # -fno-math-errno tests set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS lappend DEFAULT_VECTCFLAGS "-fno-math-errno" diff --git a/gcc/testsuite/gcc.target/arm/ivopts-3.c b/gcc/testsuite/gcc.target/arm/ivopts-3.c new file mode 100644 index 00000000000..a2e7f76c9e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/ivopts-3.c @@ -0,0 +1,20 @@ +/* { dg-do assemble } */ +/* { dg-options "-Os -mthumb -fdump-tree-ivopts -save-temps" } */ + +extern unsigned int foo2 (short*) __attribute__((pure)); + +unsigned int +tr3 (short array[], unsigned int n) +{ + int sum = 0; + unsigned int x; + for (x = 0; x < n; ++x) + sum += foo2 (&array[x]); + return sum; +} + +/* { dg-final { scan-tree-dump-times "PHI <ivtmp" 1 "ivopts"} } */ +/* { dg-final { scan-tree-dump-times "PHI <x" 0 "ivopts"} } */ +/* { dg-final { scan-tree-dump-times ", x" 0 "ivopts"} } */ +/* { dg-final { object-size text <= 30 { target arm_thumb2_ok } } } */ +/* { dg-final { cleanup-tree-dump "ivopts" } } */ diff --git a/gcc/testsuite/gcc.target/arm/ivopts-4.c b/gcc/testsuite/gcc.target/arm/ivopts-4.c new file mode 100644 index 00000000000..8ae0518bdb6 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/ivopts-4.c @@ -0,0 +1,21 @@ +/* { dg-do assemble } */ +/* { dg-options "-mthumb -Os -fdump-tree-ivopts -save-temps" } */ + +extern unsigned int foo (int*) __attribute__((pure)); + +unsigned int +tr2 (int array[], int n) +{ + unsigned int sum = 0; + int x; + if (n > 0) + for (x = 0; x < n; x++) + sum += foo (&array[x]); + return sum; +} + +/* { dg-final { scan-tree-dump-times "PHI <ivtmp" 1 "ivopts"} } */ +/* { dg-final { scan-tree-dump-times "PHI <x" 0 "ivopts"} } */ +/* { dg-final { scan-tree-dump-times ", x" 0 "ivopts"} } */ +/* { dg-final { object-size text <= 36 { target arm_thumb2_ok } } } */ +/* { dg-final { cleanup-tree-dump "ivopts" } } */ diff --git a/gcc/testsuite/gcc.target/arm/ivopts-5.c b/gcc/testsuite/gcc.target/arm/ivopts-5.c new file mode 100644 index 00000000000..5624872559f --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/ivopts-5.c @@ -0,0 +1,20 @@ +/* { dg-do assemble } */ +/* { dg-options "-Os -mthumb -fdump-tree-ivopts -save-temps" } */ + +extern unsigned int foo (int*) __attribute__((pure)); + +unsigned int +tr1 (int array[], unsigned int n) +{ + int sum = 0; + unsigned int x; + for (x = 0; x < n; ++x) + sum += foo (&array[x]); + return sum; +} + +/* { dg-final { scan-tree-dump-times "PHI <ivtmp" 1 "ivopts"} } */ +/* { dg-final { scan-tree-dump-times "PHI <x" 0 "ivopts"} } */ +/* { dg-final { scan-tree-dump-times ", x" 0 "ivopts"} } */ +/* { dg-final { object-size text <= 30 { target arm_thumb2_ok } } } */ +/* { dg-final { cleanup-tree-dump "ivopts" } } */ diff --git a/gcc/testsuite/gcc.target/arm/mla-1.c b/gcc/testsuite/gcc.target/arm/mla-1.c index f39dcff974b..6d5ee73b261 100644 --- a/gcc/testsuite/gcc.target/arm/mla-1.c +++ b/gcc/testsuite/gcc.target/arm/mla-1.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O2 -march=armv5te" } */ +/* { dg-prune-output "switch .* conflicts with" } */ int diff --git a/gcc/testsuite/gcc.target/arm/pr39839.c b/gcc/testsuite/gcc.target/arm/pr39839.c index 31e865af2f5..b5628a93daf 100644 --- a/gcc/testsuite/gcc.target/arm/pr39839.c +++ b/gcc/testsuite/gcc.target/arm/pr39839.c @@ -1,5 +1,6 @@ /* { dg-options "-mthumb -Os -march=armv5te -mthumb-interwork -fpic" } */ /* { dg-require-effective-target arm_thumb1_ok } */ +/* { dg-prune-output "switch .* conflicts with" } */ /* { dg-final { scan-assembler-not "str\[\\t \]*r.,\[\\t \]*.sp," } } */ struct S diff --git a/gcc/testsuite/gcc.target/arm/pr40457-1.c b/gcc/testsuite/gcc.target/arm/pr40457-1.c index 5ad4ff12a24..815fd38f097 100644 --- a/gcc/testsuite/gcc.target/arm/pr40457-1.c +++ b/gcc/testsuite/gcc.target/arm/pr40457-1.c @@ -7,4 +7,4 @@ int bar(int* p) return x; } -/* { dg-final { scan-assembler "ldm|ldrd" } } */ +/* { dg-final { scan-assembler "ldm" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr40457-2.c b/gcc/testsuite/gcc.target/arm/pr40457-2.c index c2c665e7b6c..187f7bf7f84 100644 --- a/gcc/testsuite/gcc.target/arm/pr40457-2.c +++ b/gcc/testsuite/gcc.target/arm/pr40457-2.c @@ -5,7 +5,6 @@ void foo(int* p) { p[0] = 1; p[1] = 0; - p[2] = 2; } /* { dg-final { scan-assembler "stm" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr40457-3.c b/gcc/testsuite/gcc.target/arm/pr40457-3.c index 5e54124254f..9bd5a17befe 100644 --- a/gcc/testsuite/gcc.target/arm/pr40457-3.c +++ b/gcc/testsuite/gcc.target/arm/pr40457-3.c @@ -5,7 +5,6 @@ void foo(int* p) { p[0] = 1; p[1] = 0; - p[2] = 2; } /* { dg-final { scan-assembler "stm" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr40657-2.c b/gcc/testsuite/gcc.target/arm/pr40657-2.c index 31d48376730..da3328d4730 100644 --- a/gcc/testsuite/gcc.target/arm/pr40657-2.c +++ b/gcc/testsuite/gcc.target/arm/pr40657-2.c @@ -1,5 +1,6 @@ /* { dg-options "-Os -march=armv4t -mthumb" } */ /* { dg-require-effective-target arm_thumb1_ok } */ +/* { dg-prune-output "switch .* conflicts with" } */ /* { dg-final { scan-assembler-not "sub\[\\t \]*sp,\[\\t \]*sp" } } */ /* { dg-final { scan-assembler-not "add\[\\t \]*sp,\[\\t \]*sp" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr40956.c b/gcc/testsuite/gcc.target/arm/pr40956.c index 5719b726a60..332b9d66d48 100644 --- a/gcc/testsuite/gcc.target/arm/pr40956.c +++ b/gcc/testsuite/gcc.target/arm/pr40956.c @@ -1,6 +1,7 @@ /* { dg-options "-mthumb -Os -fpic -march=armv5te" } */ /* { dg-require-effective-target arm_thumb1_ok } */ /* { dg-require-effective-target fpic } */ +/* { dg-prune-output "switch .* conflicts with" } */ /* Make sure the constant "0" is loaded into register only once. */ /* { dg-final { scan-assembler-times "mov\[\\t \]*r., #0" 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr41679.c b/gcc/testsuite/gcc.target/arm/pr41679.c index 8b248985fe0..5ca565a6225 100644 --- a/gcc/testsuite/gcc.target/arm/pr41679.c +++ b/gcc/testsuite/gcc.target/arm/pr41679.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-march=armv5te -g -O2" } */ +/* { dg-prune-output "switch .* conflicts with" } */ extern int a; extern char b; diff --git a/gcc/testsuite/gcc.target/arm/pr42235.c b/gcc/testsuite/gcc.target/arm/pr42235.c index 478abcc0765..df2d338226b 100644 --- a/gcc/testsuite/gcc.target/arm/pr42235.c +++ b/gcc/testsuite/gcc.target/arm/pr42235.c @@ -1,5 +1,6 @@ /* { dg-options "-mthumb -O2 -march=armv5te" } */ /* { dg-require-effective-target arm_thumb1_ok } */ +/* { dg-prune-output "switch .* conflicts with" } */ /* { dg-final { scan-assembler-not "add\[\\t \]*r.,\[\\t \]*r.,\[\\t \]*\#1" } } */ /* { dg-final { scan-assembler-not "add\[\\t \]*r.,\[\\t \]*\#1" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr42495.c b/gcc/testsuite/gcc.target/arm/pr42495.c index f65f3c14637..854c1c25ddb 100644 --- a/gcc/testsuite/gcc.target/arm/pr42495.c +++ b/gcc/testsuite/gcc.target/arm/pr42495.c @@ -1,6 +1,7 @@ /* { dg-options "-mthumb -Os -fpic -march=armv5te -fdump-rtl-hoist" } */ /* { dg-require-effective-target arm_thumb1_ok } */ /* { dg-require-effective-target fpic } */ +/* { dg-prune-output "switch .* conflicts with" } */ /* Make sure all calculations of gObj's address get hoisted to one location. */ /* { dg-final { scan-rtl-dump "PRE/HOIST: end of bb .* copying expression" "hoist" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr42505.c b/gcc/testsuite/gcc.target/arm/pr42505.c index 60902c35d27..4a357fab370 100644 --- a/gcc/testsuite/gcc.target/arm/pr42505.c +++ b/gcc/testsuite/gcc.target/arm/pr42505.c @@ -1,5 +1,6 @@ /* { dg-options "-mthumb -Os -march=armv5te" } */ /* { dg-require-effective-target arm_thumb1_ok } */ +/* { dg-prune-output "switch .* conflicts with" } */ /* { dg-final { scan-assembler-not "str\[\\t \]*r.,\[\\t \]*.sp," } } */ struct A { diff --git a/gcc/testsuite/gcc.target/arm/pr42574.c b/gcc/testsuite/gcc.target/arm/pr42574.c index 6bb42331dad..d91517cff9f 100644 --- a/gcc/testsuite/gcc.target/arm/pr42574.c +++ b/gcc/testsuite/gcc.target/arm/pr42574.c @@ -1,6 +1,7 @@ /* { dg-options "-mthumb -Os -fpic -march=armv5te" } */ /* { dg-require-effective-target arm_thumb1_ok } */ /* { dg-require-effective-target fpic } */ +/* { dg-prune-output "switch .* conflicts with" } */ /* Make sure the address of glob.c is calculated only once and using a logical shift for the offset (200<<1). */ /* { dg-final { scan-assembler-times "lsl" 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr45701-1.c b/gcc/testsuite/gcc.target/arm/pr45701-1.c index f94f5784b3e..3280485ba24 100644 --- a/gcc/testsuite/gcc.target/arm/pr45701-1.c +++ b/gcc/testsuite/gcc.target/arm/pr45701-1.c @@ -1,5 +1,7 @@ /* { dg-do compile } */ +/* { dg-skip-if "" { ! { arm_thumb1_ok || arm_thumb2_ok } } } */ /* { dg-options "-march=armv7-a -mthumb -Os" } */ +/* { dg-prune-output "switch .* conflicts with" } */ /* { dg-final { scan-assembler "push\t\{r3" } } */ /* { dg-final { scan-assembler-not "r8" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr45701-2.c b/gcc/testsuite/gcc.target/arm/pr45701-2.c index 68d51781a94..c666636813a 100644 --- a/gcc/testsuite/gcc.target/arm/pr45701-2.c +++ b/gcc/testsuite/gcc.target/arm/pr45701-2.c @@ -1,5 +1,7 @@ /* { dg-do compile } */ +/* { dg-skip-if "" { ! { arm_thumb1_ok || arm_thumb2_ok } } } */ /* { dg-options "-march=armv7-a -mthumb -Os" } */ +/* { dg-prune-output "switch .* conflicts with" } */ /* { dg-final { scan-assembler "push\t\{r3" } } */ /* { dg-final { scan-assembler-not "r8" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr46883.c b/gcc/testsuite/gcc.target/arm/pr46883.c index c85b902d5f4..ba143270ea0 100644 --- a/gcc/testsuite/gcc.target/arm/pr46883.c +++ b/gcc/testsuite/gcc.target/arm/pr46883.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O1 -march=armv5te" } */ +/* { dg-prune-output "switch .* conflicts with" } */ void bar (unsigned char *q, unsigned short *data16s, int len) { diff --git a/gcc/testsuite/gcc.target/arm/pr46934.c b/gcc/testsuite/gcc.target/arm/pr46934.c index 22b8aa83846..cbb692f3a24 100644 --- a/gcc/testsuite/gcc.target/arm/pr46934.c +++ b/gcc/testsuite/gcc.target/arm/pr46934.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-options "-march=armv5te -mthumb -Os" } */ /* { dg-require-effective-target arm_thumb1_ok } */ +/* { dg-prune-output "switch .* conflicts with" } */ int caller (unsigned int reg_type) { diff --git a/gcc/testsuite/gcc.target/arm/thumb-branch1.c b/gcc/testsuite/gcc.target/arm/thumb-branch1.c index c479d162c99..eac2e796351 100644 --- a/gcc/testsuite/gcc.target/arm/thumb-branch1.c +++ b/gcc/testsuite/gcc.target/arm/thumb-branch1.c @@ -1,5 +1,7 @@ /* { dg-do compile } */ +/* { dg-skip-if "" { ! { arm_thumb1_ok || arm_thumb2_ok } } } */ /* { dg-options "-Os -mthumb -march=armv5te" } */ +/* { dg-prune-output "switch .* conflicts with" } */ int returnbool(int a, int b) { diff --git a/gcc/testsuite/gcc.target/arm/xor-and.c b/gcc/testsuite/gcc.target/arm/xor-and.c index 4b0f79013fc..53dff85f8f7 100644 --- a/gcc/testsuite/gcc.target/arm/xor-and.c +++ b/gcc/testsuite/gcc.target/arm/xor-and.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O -march=armv6" } */ +/* { dg-prune-output "switch .* conflicts with" } */ unsigned short foo (unsigned short x) { diff --git a/gcc/testsuite/gcc.target/i386/testimm-1.c b/gcc/testsuite/gcc.target/i386/testimm-1.c new file mode 100644 index 00000000000..57276192e11 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/testimm-1.c @@ -0,0 +1,94 @@ +/* PR target/49411 */ +/* { dg-do compile } */ +/* { dg-options "-O0 -mf16c -maes -mpclmul" } */ + +#include <x86intrin.h> + +__m128i i1, i2, i3, i4; +__m128 a1, a2, a3, a4; +__m128d d1, d2, d3, d4; +__m256i l1, l2, l3, l4; +__m256 b1, b2, b3, b4; +__m256d e1, e2, e3, e4; +__m64 m1, m2, m3, m4; +int k1, k2, k3, k4; +float f1, f2, f3, f4; + +void +test8bit (void) +{ + i1 = _mm_cmpistrm (i2, i3, 256); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistri (i2, i3, 256); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistra (i2, i3, 256); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistrc (i2, i3, 256); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistro (i2, i3, 256); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistrs (i2, i3, 256); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistrz (i2, i3, 256); /* { dg-error "the third argument must be an 8-bit immediate" } */ + i1 = _mm_cmpestrm (i2, k2, i3, k3, 256);/* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestri (i2, k2, i3, k3, 256);/* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestra (i2, k2, i3, k3, 256);/* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestrc (i2, k2, i3, k3, 256);/* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestro (i2, k2, i3, k3, 256);/* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestrs (i2, k2, i3, k3, 256);/* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestrz (i2, k2, i3, k3, 256);/* { dg-error "the fifth argument must be an 8-bit immediate" } */ + b1 = _mm256_blend_ps (b2, b3, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + k1 = _cvtss_sh (f1, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm256_cvtps_ph (b2, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + b1 = _mm256_dp_ps (b2, b3, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + e1 = _mm256_permute2f128_pd (e2, e3, 256);/* { dg-error "the last argument must be an 8-bit immediate" } */ + b1 = _mm256_permute2f128_ps (b2, b3, 256);/* { dg-error "the last argument must be an 8-bit immediate" } */ + l1 = _mm256_permute2f128_si256 (l2, l3, 256);/* { dg-error "the last argument must be an 8-bit immediate" } */ + b1 = _mm256_permute_ps (b2, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_aeskeygenassist_si128 (i2, 256);/* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_blend_epi16 (i2, i3, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_clmulepi64_si128 (i2, i3, 256);/* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_cvtps_ph (a1, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + d1 = _mm_dp_pd (d2, d3, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + a1 = _mm_dp_ps (a2, a3, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + a1 = _mm_insert_ps (a2, a3, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_mpsadbw_epu8 (i2, i3, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + a1 = _mm_permute_ps (a2, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_slli_si128 (i2, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_srli_si128 (i2, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ +} + +void +test5bit (void) +{ + d1 = _mm_cmp_sd (d2, d3, 32); /* { dg-error "the last argument must be a 5-bit immediate" } */ + a1 = _mm_cmp_ss (a2, a3, 32); /* { dg-error "the last argument must be a 5-bit immediate" } */ + d1 = _mm_cmp_pd (d2, d3, 32); /* { dg-error "the last argument must be a 5-bit immediate" } */ + a1 = _mm_cmp_ps (a2, a3, 32); /* { dg-error "the last argument must be a 5-bit immediate" } */ + e1 = _mm256_cmp_pd (e2, e3, 32); /* { dg-error "the last argument must be a 5-bit immediate" } */ + b1 = _mm256_cmp_ps (b2, b3, 32); /* { dg-error "the last argument must be a 5-bit immediate" } */ +} + +void +test4bit (void) +{ + d1 = _mm_round_pd (d2, 16); /* { dg-error "the last argument must be a 4-bit immediate" } */ + d1 = _mm_round_sd (d2, d3, 16); /* { dg-error "the last argument must be a 4-bit immediate" } */ + a1 = _mm_round_ps (a2, 16); /* { dg-error "the last argument must be a 4-bit immediate" } */ + a1 = _mm_round_ss (a2, a2, 16); /* { dg-error "the last argument must be a 4-bit immediate" } */ + a1 = _mm_blend_ps (a2, a3, 16); /* { dg-error "the last argument must be a 4-bit immediate" } */ + e1 = _mm256_blend_pd (e2, e3, 16); /* { dg-error "the last argument must be a 4-bit immediate" } */ + e1 = _mm256_round_pd (e2, 16); /* { dg-error "the last argument must be a 4-bit immediate" } */ + b1 = _mm256_round_ps (b2, 16); /* { dg-error "the last argument must be a 4-bit immediate" } */ +} + +void +test2bit (void) +{ + d1 = _mm_blend_pd (d2, d3, 4); /* { dg-error "the last argument must be a 2-bit immediate" } */ +} + +void +test1bit (void) +{ + d1 = _mm256_extractf128_pd (e2, 2); /* { dg-error "the last argument must be a 1-bit immediate" } */ + a1 = _mm256_extractf128_ps (b2, 2); /* { dg-error "the last argument must be a 1-bit immediate" } */ + i1 = _mm256_extractf128_si256 (l2, 2); /* { dg-error "the last argument must be a 1-bit immediate" } */ + e1 = _mm256_insertf128_pd (e2, d1, 2); /* { dg-error "the last argument must be a 1-bit immediate" } */ + b1 = _mm256_insertf128_ps (b2, a1, 2); /* { dg-error "the last argument must be a 1-bit immediate" } */ + l1 = _mm256_insertf128_si256 (l2, i1, 2);/* { dg-error "the last argument must be a 1-bit immediate" } */ +} diff --git a/gcc/testsuite/gcc.target/i386/testimm-2.c b/gcc/testsuite/gcc.target/i386/testimm-2.c new file mode 100644 index 00000000000..3d508092067 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/testimm-2.c @@ -0,0 +1,94 @@ +/* PR target/49411 */ +/* { dg-do compile } */ +/* { dg-options "-O0 -mf16c -maes -mpclmul" } */ + +#include <x86intrin.h> + +__m128i i1, i2, i3, i4; +__m128 a1, a2, a3, a4; +__m128d d1, d2, d3, d4; +__m256i l1, l2, l3, l4; +__m256 b1, b2, b3, b4; +__m256d e1, e2, e3, e4; +__m64 m1, m2, m3, m4; +int k1, k2, k3, k4; +float f1, f2, f3, f4; + +void +test8bit (void) +{ + i1 = _mm_cmpistrm (i2, i3, -10); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistri (i2, i3, -10); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistra (i2, i3, -10); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistrc (i2, i3, -10); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistro (i2, i3, -10); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistrs (i2, i3, -10); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistrz (i2, i3, -10); /* { dg-error "the third argument must be an 8-bit immediate" } */ + i1 = _mm_cmpestrm (i2, k2, i3, k3, -10);/* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestri (i2, k2, i3, k3, -10);/* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestra (i2, k2, i3, k3, -10);/* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestrc (i2, k2, i3, k3, -10);/* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestro (i2, k2, i3, k3, -10);/* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestrs (i2, k2, i3, k3, -10);/* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestrz (i2, k2, i3, k3, -10);/* { dg-error "the fifth argument must be an 8-bit immediate" } */ + b1 = _mm256_blend_ps (b2, b3, -10); /* { dg-error "the last argument must be an 8-bit immediate" } */ + k1 = _cvtss_sh (f1, -10); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm256_cvtps_ph (b2, -10); /* { dg-error "the last argument must be an 8-bit immediate" } */ + b1 = _mm256_dp_ps (b2, b3, -10); /* { dg-error "the last argument must be an 8-bit immediate" } */ + e1 = _mm256_permute2f128_pd (e2, e3, -10);/* { dg-error "the last argument must be an 8-bit immediate" } */ + b1 = _mm256_permute2f128_ps (b2, b3, -10);/* { dg-error "the last argument must be an 8-bit immediate" } */ + l1 = _mm256_permute2f128_si256 (l2, l3, -10);/* { dg-error "the last argument must be an 8-bit immediate" } */ + b1 = _mm256_permute_ps (b2, -10); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_aeskeygenassist_si128 (i2, -10);/* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_blend_epi16 (i2, i3, -10); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_clmulepi64_si128 (i2, i3, -10);/* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_cvtps_ph (a1, -10); /* { dg-error "the last argument must be an 8-bit immediate" } */ + d1 = _mm_dp_pd (d2, d3, -10); /* { dg-error "the last argument must be an 8-bit immediate" } */ + a1 = _mm_dp_ps (a2, a3, -10); /* { dg-error "the last argument must be an 8-bit immediate" } */ + a1 = _mm_insert_ps (a2, a3, -10); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_mpsadbw_epu8 (i2, i3, -10); /* { dg-error "the last argument must be an 8-bit immediate" } */ + a1 = _mm_permute_ps (a2, -10); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_slli_si128 (i2, -10); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_srli_si128 (i2, -10); /* { dg-error "the last argument must be an 8-bit immediate" } */ +} + +void +test5bit (void) +{ + d1 = _mm_cmp_sd (d2, d3, -7); /* { dg-error "the last argument must be a 5-bit immediate" } */ + a1 = _mm_cmp_ss (a2, a3, -7); /* { dg-error "the last argument must be a 5-bit immediate" } */ + d1 = _mm_cmp_pd (d2, d3, -7); /* { dg-error "the last argument must be a 5-bit immediate" } */ + a1 = _mm_cmp_ps (a2, a3, -7); /* { dg-error "the last argument must be a 5-bit immediate" } */ + e1 = _mm256_cmp_pd (e2, e3, -7); /* { dg-error "the last argument must be a 5-bit immediate" } */ + b1 = _mm256_cmp_ps (b2, b3, -7); /* { dg-error "the last argument must be a 5-bit immediate" } */ +} + +void +test4bit (void) +{ + d1 = _mm_round_pd (d2, -7); /* { dg-error "the last argument must be a 4-bit immediate" } */ + d1 = _mm_round_sd (d2, d3, -7); /* { dg-error "the last argument must be a 4-bit immediate" } */ + a1 = _mm_round_ps (a2, -7); /* { dg-error "the last argument must be a 4-bit immediate" } */ + a1 = _mm_round_ss (a2, a2, -7); /* { dg-error "the last argument must be a 4-bit immediate" } */ + a1 = _mm_blend_ps (a2, a3, -7); /* { dg-error "the last argument must be a 4-bit immediate" } */ + e1 = _mm256_blend_pd (e2, e3, -7); /* { dg-error "the last argument must be a 4-bit immediate" } */ + e1 = _mm256_round_pd (e2, -7); /* { dg-error "the last argument must be a 4-bit immediate" } */ + b1 = _mm256_round_ps (b2, -7); /* { dg-error "the last argument must be a 4-bit immediate" } */ +} + +void +test2bit (void) +{ + d1 = _mm_blend_pd (d2, d3, -1); /* { dg-error "the last argument must be a 2-bit immediate" } */ +} + +void +test1bit (void) +{ + d1 = _mm256_extractf128_pd (e2, -1); /* { dg-error "the last argument must be a 1-bit immediate" } */ + a1 = _mm256_extractf128_ps (b2, -1); /* { dg-error "the last argument must be a 1-bit immediate" } */ + i1 = _mm256_extractf128_si256 (l2, -1); /* { dg-error "the last argument must be a 1-bit immediate" } */ + e1 = _mm256_insertf128_pd (e2, d1, -1); /* { dg-error "the last argument must be a 1-bit immediate" } */ + b1 = _mm256_insertf128_ps (b2, a1, -1); /* { dg-error "the last argument must be a 1-bit immediate" } */ + l1 = _mm256_insertf128_si256 (l2, i1, -1);/* { dg-error "the last argument must be a 1-bit immediate" } */ +} diff --git a/gcc/testsuite/gcc.target/i386/testimm-3.c b/gcc/testsuite/gcc.target/i386/testimm-3.c new file mode 100644 index 00000000000..3e4fea7fedd --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/testimm-3.c @@ -0,0 +1,94 @@ +/* PR target/49411 */ +/* { dg-do compile } */ +/* { dg-options "-O0 -mf16c -maes -mpclmul" } */ + +#include <x86intrin.h> + +__m128i i1, i2, i3, i4; +__m128 a1, a2, a3, a4; +__m128d d1, d2, d3, d4; +__m256i l1, l2, l3, l4; +__m256 b1, b2, b3, b4; +__m256d e1, e2, e3, e4; +__m64 m1, m2, m3, m4; +int k1, k2, k3, k4; +float f1, f2, f3, f4; + +void +test8bit (void) +{ + i1 = _mm_cmpistrm (i2, i3, k4); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistri (i2, i3, k4); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistra (i2, i3, k4); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistrc (i2, i3, k4); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistro (i2, i3, k4); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistrs (i2, i3, k4); /* { dg-error "the third argument must be an 8-bit immediate" } */ + k1 = _mm_cmpistrz (i2, i3, k4); /* { dg-error "the third argument must be an 8-bit immediate" } */ + i1 = _mm_cmpestrm (i2, k2, i3, k3, k4); /* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestri (i2, k2, i3, k3, k4); /* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestra (i2, k2, i3, k3, k4); /* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestrc (i2, k2, i3, k3, k4); /* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestro (i2, k2, i3, k3, k4); /* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestrs (i2, k2, i3, k3, k4); /* { dg-error "the fifth argument must be an 8-bit immediate" } */ + k1 = _mm_cmpestrz (i2, k2, i3, k3, k4); /* { dg-error "the fifth argument must be an 8-bit immediate" } */ + b1 = _mm256_blend_ps (b2, b3, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + k1 = _cvtss_sh (f1, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm256_cvtps_ph (b2, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + b1 = _mm256_dp_ps (b2, b3, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + e1 = _mm256_permute2f128_pd (e2, e3, k4);/* { dg-error "the last argument must be an 8-bit immediate" } */ + b1 = _mm256_permute2f128_ps (b2, b3, k4);/* { dg-error "the last argument must be an 8-bit immediate" } */ + l1 = _mm256_permute2f128_si256 (l2, l3, k4);/* { dg-error "the last argument must be an 8-bit immediate" } */ + b1 = _mm256_permute_ps (b2, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_aeskeygenassist_si128 (i2, k4);/* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_blend_epi16 (i2, i3, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_clmulepi64_si128 (i2, i3, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_cvtps_ph (a1, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + d1 = _mm_dp_pd (d2, d3, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + a1 = _mm_dp_ps (a2, a3, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + a1 = _mm_insert_ps (a2, a3, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_mpsadbw_epu8 (i2, i3, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + a1 = _mm_permute_ps (a2, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_slli_si128 (i2, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_srli_si128 (i2, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ +} + +void +test5bit (void) +{ + d1 = _mm_cmp_sd (d2, d3, k4); /* { dg-error "the last argument must be a 5-bit immediate" } */ + a1 = _mm_cmp_ss (a2, a3, k4); /* { dg-error "the last argument must be a 5-bit immediate" } */ + d1 = _mm_cmp_pd (d2, d3, k4); /* { dg-error "the last argument must be a 5-bit immediate" } */ + a1 = _mm_cmp_ps (a2, a3, k4); /* { dg-error "the last argument must be a 5-bit immediate" } */ + e1 = _mm256_cmp_pd (e2, e3, k4); /* { dg-error "the last argument must be a 5-bit immediate" } */ + b1 = _mm256_cmp_ps (b2, b3, k4); /* { dg-error "the last argument must be a 5-bit immediate" } */ +} + +void +test4bit (void) +{ + d1 = _mm_round_pd (d2, k4); /* { dg-error "the last argument must be a 4-bit immediate" } */ + d1 = _mm_round_sd (d2, d3, k4); /* { dg-error "the last argument must be a 4-bit immediate" } */ + a1 = _mm_round_ps (a2, k4); /* { dg-error "the last argument must be a 4-bit immediate" } */ + a1 = _mm_round_ss (a2, a2, k4); /* { dg-error "the last argument must be a 4-bit immediate" } */ + a1 = _mm_blend_ps (a2, a3, k4); /* { dg-error "the last argument must be a 4-bit immediate" } */ + e1 = _mm256_blend_pd (e2, e3, k4); /* { dg-error "the last argument must be a 4-bit immediate" } */ + e1 = _mm256_round_pd (e2, k4); /* { dg-error "the last argument must be a 4-bit immediate" } */ + b1 = _mm256_round_ps (b2, k4); /* { dg-error "the last argument must be a 4-bit immediate" } */ +} + +void +test2bit (void) +{ + d1 = _mm_blend_pd (d2, d3, k4); /* { dg-error "the last argument must be a 2-bit immediate" } */ +} + +void +test1bit (void) +{ + d1 = _mm256_extractf128_pd (e2, k4); /* { dg-error "the last argument must be a 1-bit immediate" } */ + a1 = _mm256_extractf128_ps (b2, k4); /* { dg-error "the last argument must be a 1-bit immediate" } */ + i1 = _mm256_extractf128_si256 (l2, k4); /* { dg-error "the last argument must be a 1-bit immediate" } */ + e1 = _mm256_insertf128_pd (e2, d1, k4); /* { dg-error "the last argument must be a 1-bit immediate" } */ + b1 = _mm256_insertf128_ps (b2, a1, k4); /* { dg-error "the last argument must be a 1-bit immediate" } */ + l1 = _mm256_insertf128_si256 (l2, i1, k4);/* { dg-error "the last argument must be a 1-bit immediate" } */ +} diff --git a/gcc/testsuite/gcc.target/i386/testimm-4.c b/gcc/testsuite/gcc.target/i386/testimm-4.c new file mode 100644 index 00000000000..2eaf4133886 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/testimm-4.c @@ -0,0 +1,97 @@ +/* PR target/49411 */ +/* { dg-do assemble } */ +/* { dg-options "-O0 -mf16c -maes -mpclmul" } */ +/* { dg-require-effective-target f16c } */ +/* { dg-require-effective-target vaes } */ +/* { dg-require-effective-target vpclmul } */ + +#include <x86intrin.h> + +__m128i i1, i2, i3, i4; +__m128 a1, a2, a3, a4; +__m128d d1, d2, d3, d4; +__m256i l1, l2, l3, l4; +__m256 b1, b2, b3, b4; +__m256d e1, e2, e3, e4; +__m64 m1, m2, m3, m4; +int k1, k2, k3, k4; +float f1, f2, f3, f4; + +void +test8bit (void) +{ + i1 = _mm_cmpistrm (i2, i3, 255); + k1 = _mm_cmpistri (i2, i3, 255); + k1 = _mm_cmpistra (i2, i3, 255); + k1 = _mm_cmpistrc (i2, i3, 255); + k1 = _mm_cmpistro (i2, i3, 255); + k1 = _mm_cmpistrs (i2, i3, 255); + k1 = _mm_cmpistrz (i2, i3, 255); + i1 = _mm_cmpestrm (i2, k2, i3, k3, 255); + k1 = _mm_cmpestri (i2, k2, i3, k3, 255); + k1 = _mm_cmpestra (i2, k2, i3, k3, 255); + k1 = _mm_cmpestrc (i2, k2, i3, k3, 255); + k1 = _mm_cmpestro (i2, k2, i3, k3, 255); + k1 = _mm_cmpestrs (i2, k2, i3, k3, 255); + k1 = _mm_cmpestrz (i2, k2, i3, k3, 255); + b1 = _mm256_blend_ps (b2, b3, 255); + k1 = _cvtss_sh (f1, 255); + i1 = _mm256_cvtps_ph (b2, 255); + b1 = _mm256_dp_ps (b2, b3, 255); + e1 = _mm256_permute2f128_pd (e2, e3, 255); + b1 = _mm256_permute2f128_ps (b2, b3, 255); + l1 = _mm256_permute2f128_si256 (l2, l3, 255); + b1 = _mm256_permute_ps (b2, 255); + i1 = _mm_aeskeygenassist_si128 (i2, 255); + i1 = _mm_blend_epi16 (i2, i3, 255); + i1 = _mm_clmulepi64_si128 (i2, i3, 255); + i1 = _mm_cvtps_ph (a1, 255); + d1 = _mm_dp_pd (d2, d3, 255); + a1 = _mm_dp_ps (a2, a3, 255); + a1 = _mm_insert_ps (a2, a3, 255); + i1 = _mm_mpsadbw_epu8 (i2, i3, 255); + a1 = _mm_permute_ps (a2, 255); + i1 = _mm_slli_si128 (i2, 255); + i1 = _mm_srli_si128 (i2, 255); +} + +void +test5bit (void) +{ + d1 = _mm_cmp_sd (d2, d3, 31); + a1 = _mm_cmp_ss (a2, a3, 31); + d1 = _mm_cmp_pd (d2, d3, 31); + a1 = _mm_cmp_ps (a2, a3, 31); + e1 = _mm256_cmp_pd (e2, e3, 31); + b1 = _mm256_cmp_ps (b2, b3, 31); +} + +void +test4bit (void) +{ + d1 = _mm_round_pd (d2, 15); + d1 = _mm_round_sd (d2, d3, 15); + a1 = _mm_round_ps (a2, 15); + a1 = _mm_round_ss (a2, a2, 15); + a1 = _mm_blend_ps (a2, a3, 15); + e1 = _mm256_blend_pd (e2, e3, 15); + e1 = _mm256_round_pd (e2, 15); + b1 = _mm256_round_ps (b2, 15); +} + +void +test2bit (void) +{ + d1 = _mm_blend_pd (d2, d3, 3); +} + +void +test1bit (void) +{ + d1 = _mm256_extractf128_pd (e2, 1); + a1 = _mm256_extractf128_ps (b2, 1); + i1 = _mm256_extractf128_si256 (l2, 1); + e1 = _mm256_insertf128_pd (e2, d1, 1); + b1 = _mm256_insertf128_ps (b2, a1, 1); + l1 = _mm256_insertf128_si256 (l2, i1, 1); +} diff --git a/gcc/testsuite/gcc.target/i386/testimm-5.c b/gcc/testsuite/gcc.target/i386/testimm-5.c new file mode 100644 index 00000000000..67c152834f6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/testimm-5.c @@ -0,0 +1,8 @@ +/* PR target/49411 */ +/* { dg-do assemble } */ +/* { dg-options "-O2 -mf16c -maes -mpclmul" } */ +/* { dg-require-effective-target f16c } */ +/* { dg-require-effective-target vaes } */ +/* { dg-require-effective-target vpclmul } */ + +#include "testimm-4.c" diff --git a/gcc/testsuite/gcc.target/i386/testimm-6.c b/gcc/testsuite/gcc.target/i386/testimm-6.c new file mode 100644 index 00000000000..087a6ffa5d0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/testimm-6.c @@ -0,0 +1,41 @@ +/* PR target/49411 */ +/* { dg-do compile } */ +/* { dg-options "-O0 -mxop" } */ + +#include <x86intrin.h> + +__m128i i1, i2, i3, i4; +__m128 a1, a2, a3, a4; +__m128d d1, d2, d3, d4; +__m256i l1, l2, l3, l4; +__m256 b1, b2, b3, b4; +__m256d e1, e2, e3, e4; +__m64 m1, m2, m3, m4; +int k1, k2, k3, k4; +float f1, f2, f3, f4; + +void +test2bit (void) +{ + d1 = _mm_permute2_pd (d2, d3, i1, 17); /* { dg-error "the last argument must be a 2-bit immediate" } */ + e1 = _mm256_permute2_pd (e2, e3, l1, 17); /* { dg-error "the last argument must be a 2-bit immediate" } */ + a1 = _mm_permute2_ps (a2, a3, i1, 17); /* { dg-error "the last argument must be a 2-bit immediate" } */ + b1 = _mm256_permute2_ps (b2, b3, l1, 17); /* { dg-error "the last argument must be a 2-bit immediate" } */ + d1 = _mm_permute2_pd (d2, d3, i1, k4); /* { dg-error "the last argument must be a 2-bit immediate" } */ + e1 = _mm256_permute2_pd (e2, e3, l1, k4); /* { dg-error "the last argument must be a 2-bit immediate" } */ + a1 = _mm_permute2_ps (a2, a3, i1, k4); /* { dg-error "the last argument must be a 2-bit immediate" } */ + b1 = _mm256_permute2_ps (b2, b3, l1, k4); /* { dg-error "the last argument must be a 2-bit immediate" } */ +} + +void +test2args (void) +{ + i1 = _mm_extracti_si64 (i2, 256, 0); /* { dg-error "the next to last argument must be an 8-bit immediate" } */ + i1 = _mm_extracti_si64 (i2, 0, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_inserti_si64 (i2, i3, 256, 0); /* { dg-error "the next to last argument must be an 8-bit immediate" } */ + i2 = _mm_inserti_si64 (i2, i3, 0, 256); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_extracti_si64 (i2, k4, 0); /* { dg-error "the next to last argument must be an 8-bit immediate" } */ + i1 = _mm_extracti_si64 (i2, 0, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ + i1 = _mm_inserti_si64 (i2, i3, k4, 0); /* { dg-error "the next to last argument must be an 8-bit immediate" } */ + i2 = _mm_inserti_si64 (i2, i3, 0, k4); /* { dg-error "the last argument must be an 8-bit immediate" } */ +} diff --git a/gcc/testsuite/gcc.target/i386/testimm-7.c b/gcc/testsuite/gcc.target/i386/testimm-7.c new file mode 100644 index 00000000000..9b16fc7f0e2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/testimm-7.c @@ -0,0 +1,46 @@ +/* PR target/49411 */ +/* { dg-do assemble } */ +/* { dg-options "-O0 -mxop" } */ +/* { dg-require-effective-target xop } */ + +#include <x86intrin.h> + +__m128i i1, i2, i3, i4; +__m128 a1, a2, a3, a4; +__m128d d1, d2, d3, d4; +__m256i l1, l2, l3, l4; +__m256 b1, b2, b3, b4; +__m256d e1, e2, e3, e4; +__m64 m1, m2, m3, m4; +int k1, k2, k3, k4; +float f1, f2, f3, f4; + +void +test2bit (void) +{ + d1 = _mm_permute2_pd (d2, d3, i1, 3); + e1 = _mm256_permute2_pd (e2, e3, l1, 3); + a1 = _mm_permute2_ps (a2, a3, i1, 3); + b1 = _mm256_permute2_ps (b2, b3, l1, 3); + d1 = _mm_permute2_pd (d2, d3, i1, 0); + e1 = _mm256_permute2_pd (e2, e3, l1, 0); + a1 = _mm_permute2_ps (a2, a3, i1, 0); + b1 = _mm256_permute2_ps (b2, b3, l1, 0); +} + +void +test2args (void) +{ + i1 = _mm_extracti_si64 (i2, 255, 0); + i1 = _mm_extracti_si64 (i2, 0, 255); + i1 = _mm_inserti_si64 (i2, i3, 255, 0); + i2 = _mm_inserti_si64 (i2, i3, 0, 255); + i1 = _mm_extracti_si64 (i2, 255, 255); + i1 = _mm_extracti_si64 (i2, 255, 255); + i1 = _mm_inserti_si64 (i2, i3, 255, 255); + i2 = _mm_inserti_si64 (i2, i3, 255, 255); + i1 = _mm_extracti_si64 (i2, 0, 0); + i1 = _mm_extracti_si64 (i2, 0, 0); + i1 = _mm_inserti_si64 (i2, i3, 0, 0); + i2 = _mm_inserti_si64 (i2, i3, 0, 0); +} diff --git a/gcc/testsuite/gcc.target/i386/testimm-8.c b/gcc/testsuite/gcc.target/i386/testimm-8.c new file mode 100644 index 00000000000..5169763fe61 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/testimm-8.c @@ -0,0 +1,6 @@ +/* PR target/49411 */ +/* { dg-do assemble } */ +/* { dg-options "-O2 -mxop" } */ +/* { dg-require-effective-target xop } */ + +#include "testimm-7.c" diff --git a/gcc/testsuite/gcc.target/i386/xop-rotate1-int.c b/gcc/testsuite/gcc.target/i386/xop-rotate1-int.c new file mode 100644 index 00000000000..a58cd726b2b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/xop-rotate1-int.c @@ -0,0 +1,63 @@ +/* PR target/49411 */ +/* { dg-do run } */ +/* { dg-require-effective-target xop } */ +/* { dg-options "-O2 -mxop" } */ + +#include "xop-check.h" + +#include <x86intrin.h> + +extern void abort (void); + +union +{ + __m128i v; + unsigned char c[16]; + unsigned short s[8]; + unsigned int i[4]; + unsigned long long l[2]; +} a, b, c, d; + +#define TEST1(F, N, S, SS) \ +do { \ + for (i = 0; i < sizeof (a.F) / sizeof (a.F[0]); i++) \ + a.F[i] = i * 17; \ + s = _mm_set1_epi##SS (N); \ + b.v = _mm_roti_epi##S (a.v, N); \ + c.v = _mm_rot_epi##S (a.v, s); \ + for (i = 0; i < sizeof (a.F) / sizeof (a.F[0]); i++) \ + { \ + int mask = __CHAR_BIT__ * sizeof (a.F[i]) - 1; \ + d.F[i] = a.F[i] << (N & mask); \ + if (N & mask) \ + d.F[i] |= a.F[i] >> (mask + 1 - (N & mask)); \ + if (b.F[i] != c.F[i] || b.F[i] != d.F[i]) \ + abort (); \ + } \ +} while (0) +#define TEST(N) \ + TEST1 (c, N, 8, 8); \ + TEST1 (s, N, 16, 16); \ + TEST1 (i, N, 32, 32); \ + TEST1 (l, N, 64, 64x) + +volatile int n; + +static void +xop_test (void) +{ + unsigned int i; + __m128i s; + +#ifndef NON_CONST + TEST (5); + TEST (-5); + TEST (0); + TEST (31); +#else + n = 5; TEST (n); + n = -5; TEST (n); + n = 0; TEST (n); + n = 31; TEST (n); +#endif +} diff --git a/gcc/testsuite/gcc.target/i386/xop-rotate2-int.c b/gcc/testsuite/gcc.target/i386/xop-rotate2-int.c new file mode 100644 index 00000000000..634a51a8442 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/xop-rotate2-int.c @@ -0,0 +1,7 @@ +/* PR target/49411 */ +/* { dg-do run } */ +/* { dg-require-effective-target xop } */ +/* { dg-options "-O2 -mxop" } */ + +#define NON_CONST 1 +#include "xop-rotate1-int.c" diff --git a/gcc/testsuite/gcc.target/powerpc/outofline_rnreg.c b/gcc/testsuite/gcc.target/powerpc/outofline_rnreg.c new file mode 100644 index 00000000000..a80a46f4022 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/outofline_rnreg.c @@ -0,0 +1,15 @@ +/* Test that registers used by out of line restore functions does not get renamed. + AIX, and 64 bit targets uses r1, which rnreg stays away from. + Linux 32 bits targets uses r11, which is susceptible to be renamed */ +/* { dg-do compile } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-options "-Os -frename-registers -fdump-rtl-rnreg" } */ +/* "* renamed" or "* no available better choice" results are not acceptable */ +/* { dg-final { scan-rtl-dump-not "Register 11 in insn *" "rnreg" { target powerpc*-*-linux* } } } */ +/* { dg-final { cleanup-rtl-dump "rnreg" } } */ +int +calc (int j) +{ + if (j<=1) return 1; + return calc(j-1)*(j+1); +} diff --git a/gcc/testsuite/gfortran.dg/alloc_comp_assign_11.f90 b/gcc/testsuite/gfortran.dg/alloc_comp_assign_11.f90 new file mode 100644 index 00000000000..2d2b85b841f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/alloc_comp_assign_11.f90 @@ -0,0 +1,41 @@ +! { dg-do run } +! +! PR fortran/49324 +! +! Check that with array constructors a deep copy is done +! +implicit none +type t + integer, allocatable :: A(:) +end type t + +type(t) :: x, y +type(t), allocatable :: z(:), z2(:) + +allocate (x%A(2)) +allocate (y%A(1)) +x%A(:) = 11 +y%A(:) = 22 + +allocate (z(2)) + +z = [ x, y ] +!print *, z(1)%a, z(2)%a, x%A, y%A +if (any (z(1)%a /= 11) .or. z(2)%a(1) /= 22 .or. any (x%A /= 11) & + .or. y%A(1) /= 22) & + call abort() + +x%A(:) = 444 +y%A(:) = 555 + +!print *, z(1)%a, z(2)%a, x%A, y%A +if (any (z(1)%a /= 11) .or. z(2)%a(1) /= 22 .or. any (x%A /= 444) & + .or. y%A(1) /= 555) & + call abort() + +z(:) = [ x, y ] +!print *, z(1)%a, z(2)%a, x%A, y%A +if (any (z(1)%a /= 444) .or. z(2)%a(1) /= 555 .or. any (x%A /= 444) & + .or. y%A(1) /= 555) & + call abort() +end diff --git a/gcc/testsuite/gfortran.dg/class_43.f03 b/gcc/testsuite/gfortran.dg/class_43.f03 new file mode 100644 index 00000000000..86aa0e3c143 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/class_43.f03 @@ -0,0 +1,14 @@ +! { dg-do compile } +! +! PR 49417: [4.6/4.7 Regression] [OOP] ICE on invalid CLASS component declaration +! +! Contributed by Andrew Benson <abenson@its.caltech.edu> + + type :: nodeWrapper + end type nodeWrapper + + type, extends(nodeWrapper) :: treeNode + class(nodeWrapper) :: subComponent ! { dg-error "must be allocatable or pointer" } + end type treeNode + +end diff --git a/gcc/testsuite/gfortran.dg/move_alloc_5.f90 b/gcc/testsuite/gfortran.dg/move_alloc_5.f90 new file mode 100644 index 00000000000..b2759de2c1d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/move_alloc_5.f90 @@ -0,0 +1,24 @@ +! { dg-do run } +! +! PR 48699: [4.6/4.7 Regression] [OOP] MOVE_ALLOC inside SELECT TYPE +! +! Contributed by Salvatore Filippone <sfilippone@uniroma2.it> + +program testmv1 + + type bar + end type + + type, extends(bar) :: bar2 + end type + + class(bar), allocatable :: sm + type(bar2), allocatable :: sm2 + + allocate (sm2) + call move_alloc (sm2,sm) + + if (allocated(sm2)) call abort() + if (.not. allocated(sm)) call abort() + +end program diff --git a/gcc/testsuite/gfortran.dg/pr49103.f90 b/gcc/testsuite/gfortran.dg/pr49103.f90 new file mode 100644 index 00000000000..e744c9bbe7f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr49103.f90 @@ -0,0 +1,19 @@ +! PR fortran/49103 +! { dg-do run } + integer :: a(2), b(2), i, j + open (10, status='scratch') + do j = 1, 2 + a = (/ 0, 0 /) + b = (/ 1, 1 /) + do i = 1, 2 + write (10, *) a + write (10, *) b + end do + end do + rewind (10) + do i = 0, 7 + read (10, *) a + if (any (a .ne. mod (i, 2))) call abort + end do + close (10) +end diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_31.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_31.f90 new file mode 100644 index 00000000000..691c77d1d0b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/proc_ptr_31.f90 @@ -0,0 +1,10 @@ +! { dg-do compile } +! +! PR 49400: [F08] Proc-pointer declaration in BLOCK construct +! +! Contributed by Tobias Burnus <burnus@gcc.gnu.org> + + block + procedure(real),pointer :: p + end block +end diff --git a/gcc/testsuite/gfortran.dg/read_list_eof_1.f90 b/gcc/testsuite/gfortran.dg/read_list_eof_1.f90 new file mode 100644 index 00000000000..775346e4a75 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/read_list_eof_1.f90 @@ -0,0 +1,22 @@ +! { dg-do run } +! PR 49296 List formatted read of file without EOR marker (\n). +program read_list_eof_1 + implicit none + character(len=100) :: s + call genfil () + open (unit=20, file='read.dat', form='FORMATTED', action='READ', & + status='OLD') + read (20, fmt=*) s + close (20, status='delete') + if (trim(s) /= "a") then + call abort () + end if + +contains + subroutine genfil + open(10, file='read.dat', form='unformatted', action='write', & + status='replace', access='stream') + write(10) 'a' + close(10) + end subroutine genfil +end program read_list_eof_1 diff --git a/gcc/testsuite/gfortran.dg/trim_optimize_7.f90 b/gcc/testsuite/gfortran.dg/trim_optimize_7.f90 new file mode 100644 index 00000000000..26663c04d27 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/trim_optimize_7.f90 @@ -0,0 +1,19 @@ +! { dg-do run } +! { dg-options "-O -fdump-tree-original" } +! Check that trailing trims are also removed from assignment of +! expressions involving concatenations of strings . +program main + character(2) :: a,b,c + character(8) :: d + a = 'a ' + b = 'b ' + c = 'c ' + d = a // b // a // trim(c) ! This should be optimized away. + if (d /= 'a b a c ') call abort + d = a // trim(b) // c // a ! This shouldn't. + if (d /= 'a bc a ') call abort + d = a // b // a // trim(trim(c)) ! This should also be optimized away. + if (d /= 'a b a c ') call abort +end +! { dg-final { scan-tree-dump-times "string_len_trim" 1 "original" } } +! { dg-final { cleanup-tree-dump "original" } } diff --git a/gcc/testsuite/gfortran.dg/trim_optimize_8.f90 b/gcc/testsuite/gfortran.dg/trim_optimize_8.f90 new file mode 100644 index 00000000000..60dfd193a48 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/trim_optimize_8.f90 @@ -0,0 +1,14 @@ +! { dg-do compile } +! { dg-options "-O -fdump-tree-original" } +! Check that trailing trims are also removed from assignment of +! expressions involving concatenations of strings . +program main + character(2) :: a,b + character(8) :: d + a = 'a ' + b = 'b ' + if (trim(a // trim(b)) /= 'a b ') call abort + if (trim (trim(a) // trim(b)) /= 'ab ') call abort +end +! { dg-final { scan-tree-dump-times "string_len_trim" 1 "original" } } +! { dg-final { cleanup-tree-dump "original" } } diff --git a/gcc/testsuite/gfortran.dg/typebound_assignment_3.f03 b/gcc/testsuite/gfortran.dg/typebound_assignment_3.f03 new file mode 100644 index 00000000000..ce84a3957d0 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/typebound_assignment_3.f03 @@ -0,0 +1,30 @@ +! { dg-do compile } +! +! PR 49074: [OOP] Defined assignment w/ CLASS arrays: Incomplete error message +! +! Contribute by Jerry DeLisle <jvdelisle@gcc.gnu.org> + +module foo + + type bar + contains + generic :: assignment (=) => assgn + procedure :: assgn + end type + +contains + + elemental subroutine assgn (a, b) + class (bar), intent (inout) :: a + class (bar), intent (in) :: b + end subroutine + +end module + + + use foo + type (bar) :: foobar(2) + foobar = bar() ! { dg-error "currently not implemented" } +end + +! { dg-final { cleanup-modules "foo" } } diff --git a/gcc/testsuite/gnat.dg/constant3.adb b/gcc/testsuite/gnat.dg/constant3.adb new file mode 100644 index 00000000000..5ca1792fbd2 --- /dev/null +++ b/gcc/testsuite/gnat.dg/constant3.adb @@ -0,0 +1,21 @@ +-- { dg-do compile } +-- { dg-options "-O" } + +with System.Machine_code; use System.Machine_code; + +procedure Constant3 is + + c : Integer := -1; + r : Integer; + + procedure Conv (res : out Integer; v : Integer) is + v1 : constant Integer := v; + begin + Asm ("", Integer'Asm_output ("=m", res), Integer'Asm_input("m", v1)); + end; + + pragma Inline_Always (Conv); + +begin + Conv (r, c); +end; diff --git a/gcc/testsuite/gnat.dg/discr31.adb b/gcc/testsuite/gnat.dg/discr31.adb new file mode 100644 index 00000000000..0fe02cc2131 --- /dev/null +++ b/gcc/testsuite/gnat.dg/discr31.adb @@ -0,0 +1,12 @@ +-- { dg-do compile } +-- { dg-options "-O" } + +package body Discr31 is + + function Log_Item(Packet : in Packet_Data_Type) return Log_Item_Type is + None : Log_Item_Type(0); + begin + return None; + end; + +end Discr31; diff --git a/gcc/testsuite/gnat.dg/discr31.ads b/gcc/testsuite/gnat.dg/discr31.ads new file mode 100644 index 00000000000..ffc76b45943 --- /dev/null +++ b/gcc/testsuite/gnat.dg/discr31.ads @@ -0,0 +1,14 @@ +package Discr31 is + + type Byte_List_Type is array(Positive range <>) of Integer; + + type Log_Item_Type(Last : Natural) is record + Data : Byte_List_Type(1 .. Last) := (others => 0); + Link : Natural := 0; + end record; + + type Packet_Data_Type is access Log_Item_Type; + + function Log_Item(Packet : in Packet_Data_Type) return Log_Item_Type; + +end Discr31; diff --git a/gcc/testsuite/gnat.dg/volatile6.adb b/gcc/testsuite/gnat.dg/volatile6.adb new file mode 100644 index 00000000000..aeaacb028f7 --- /dev/null +++ b/gcc/testsuite/gnat.dg/volatile6.adb @@ -0,0 +1,20 @@ +-- { dg-do compile } +-- { dg-options "-O2 -fdump-tree-optimized" } + +function Volatile6 return Integer is + + type Vol is new Integer; + pragma Volatile (Vol); + + V : Vol := 0; + +begin + for J in 1 .. 10 loop + V := V + 1; + end loop; + + return Integer (V); +end; + +-- { dg-final { scan-tree-dump "goto" "optimized" } } +-- { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gnat.dg/volatile7.adb b/gcc/testsuite/gnat.dg/volatile7.adb new file mode 100644 index 00000000000..d0eb48ffee6 --- /dev/null +++ b/gcc/testsuite/gnat.dg/volatile7.adb @@ -0,0 +1,24 @@ +-- { dg-do compile } +-- { dg-options "-O2 -fdump-tree-optimized" } + +function Volatile7 return Integer is + + type Vol is new Integer; + pragma Volatile (Vol); + + type R is record + X : Vol := 0; + end record; + + V : R; + +begin + for J in 1 .. 10 loop + V.X := V.X + 1; + end loop; + + return Integer (V.X); +end; + +-- { dg-final { scan-tree-dump "goto" "optimized" } } +-- { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gnat.dg/volatile8.adb b/gcc/testsuite/gnat.dg/volatile8.adb new file mode 100644 index 00000000000..83f7488580e --- /dev/null +++ b/gcc/testsuite/gnat.dg/volatile8.adb @@ -0,0 +1,22 @@ +-- { dg-do compile } +-- { dg-options "-O2 -fdump-tree-optimized" } + +function Volatile8 return Integer is + + type Vol is new Integer; + pragma Volatile (Vol); + + type A is array (1..4) of Vol; + + V : A := (others => 0); + +begin + for J in 1 .. 10 loop + V(1) := V(1) + 1; + end loop; + + return Integer (V(1)); +end; + +-- { dg-final { scan-tree-dump "goto" "optimized" } } +-- { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gnat.dg/volatile9.adb b/gcc/testsuite/gnat.dg/volatile9.adb new file mode 100644 index 00000000000..52b55aee23a --- /dev/null +++ b/gcc/testsuite/gnat.dg/volatile9.adb @@ -0,0 +1,20 @@ +-- { dg-do compile } +-- { dg-options "-O2 -fdump-tree-optimized" } + +function Volatile9 return Integer is + + type A is array (1..4) of Integer; + pragma Volatile_Components (A); + + V : A := (others => 0); + +begin + for J in 1 .. 10 loop + V(1) := V(1) + 1; + end loop; + + return V(1); +end; + +-- { dg-final { scan-tree-dump "goto" "optimized" } } +-- { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp index 1388bd2c482..80014d0195c 100644 --- a/gcc/testsuite/lib/scanasm.exp +++ b/gcc/testsuite/lib/scanasm.exp @@ -350,11 +350,35 @@ proc object-size { args } { upvar 2 name testcase set testcase [lindex $testcase 0] + + set what [lindex $args 0] + set where [lsearch { text data bss total } $what] + if { $where == -1 } { + error "object-size: illegal argument: $what" + return + } + set cmp [lindex $args 1] + if { [lsearch { < > <= >= == != } $cmp] == -1 } { + error "object-size: illegal argument: $cmp" + return + } + set with [lindex $args 2] + if ![string is integer $with ] { + error "object-size: illegal argument: $with" + return + } + set output_file "[file rootname [file tail $testcase]].o" + if ![file_on_host exists $output_file] { + verbose -log "$testcase: $output_file does not exist" + unresolved "$testcase object-size $what $cmp $with" + return + } set output [remote_exec host "$size" "$output_file"] set status [lindex $output 0] if { $status != 0 } { - error "object-size: $size failed" + verbose -log "$testcase object-size: $size failed" + unresolved "$testcase object-size $what $cmp $with" return } @@ -363,37 +387,21 @@ proc object-size { args } { set line0 [lindex $lines 0] if ![regexp {^\s*text\s+data\s+bss\s+dec\s+hex\s+filename\s*$} $line0] { - error "object-size: $size did not produce expected first line: $line0" + verbose -log "$testcase object-size: $size did not produce expected first line: $line0" + unresolved "$testcase object-size $what $cmp $with" return } set line1 [lindex $lines 1] if ![regexp {^\s*\d+\s+\d+\s+\d+\s+\d+\s+[\da-fA-F]+\s+} $line1] { - error "object-size: $size did not produce expected second line: $line1" + verbose -log "$testcase object-size: $size did not produce expected second line: $line1" + unresolved "$testcase object-size $what $cmp $with" return } - set what [lindex $args 0] - set where [lsearch { text data bss total } $what] - if { $where == -1 } { - error "object-size: illegal argument: $what" - return - } set actual [lindex $line1 $where] verbose -log "$what size is $actual" - set cmp [lindex $args 1] - if { [lsearch { < > <= >= == != } $cmp] == -1 } { - error "object-size: illegal argument: $cmp" - return - } - - set with [lindex $args 2] - if ![string is integer $with ] { - error "object-size: illegal argument: $with" - return - } - if [expr $actual $cmp $with] { pass "$testcase object-size $what $cmp $with" } else { diff --git a/gcc/testsuite/lib/scandump.exp b/gcc/testsuite/lib/scandump.exp index 7800bdebb55..3f2ad2d7315 100644 --- a/gcc/testsuite/lib/scandump.exp +++ b/gcc/testsuite/lib/scandump.exp @@ -55,7 +55,8 @@ proc scan-dump { args } { set src [file tail [lindex $testcase 0]] set output_file "[glob -nocomplain $src.[lindex $args 2]]" if { $output_file == "" } { - fail "$testname: dump file does not exist" + verbose -log "$testcase: dump file does not exist" + unresolved "$testname" return } @@ -97,7 +98,8 @@ proc scan-dump-times { args } { set src [file tail [lindex $testcase 0]] set output_file "[glob -nocomplain $src.[lindex $args 3]]" if { $output_file == "" } { - fail "$testname: dump file does not exist" + verbose -log "$testcase: dump file does not exist" + unresolved "$testname" return } @@ -139,7 +141,8 @@ proc scan-dump-not { args } { set src [file tail [lindex $testcase 0]] set output_file "[glob -nocomplain $src.[lindex $args 2]]" if { $output_file == "" } { - fail "$testname: dump file does not exist" + verbose -log "$testcase: dump file does not exist" + unresolved "$testname" return } @@ -190,7 +193,8 @@ proc scan-dump-dem { args } { set src [file tail [lindex $testcase 0]] set output_file "[glob -nocomplain $src.[lindex $args 2]]" if { $output_file == "" } { - fail "$testname: dump file does not exist" + verbose -log "$testcase: dump file does not exist" + unresolved "$testname" return } @@ -241,7 +245,8 @@ proc scan-dump-dem-not { args } { set src [file tail [lindex $testcase 0]] set output_file "[glob -nocomplain $src.[lindex $args 2]]" if { $output_file == "" } { - fail "$testname: dump file does not exist" + verbose -log "$testcase: dump file does not exist" + unresolved "$testname" return } diff --git a/gcc/testsuite/obj-c++.dg/invalid-type-1.mm b/gcc/testsuite/obj-c++.dg/invalid-type-1.mm index 2d6ba68de1e..ace144f0b2b 100644 --- a/gcc/testsuite/obj-c++.dg/invalid-type-1.mm +++ b/gcc/testsuite/obj-c++.dg/invalid-type-1.mm @@ -18,8 +18,8 @@ id <MyProtocol> object; /* This is fine. */ AClass <MyProtocol> *object1; /* This is fine. */ -Integer <MyProtocol> *object2; /* { dg-error ".Integer. is not a template" } */ +Integer <MyProtocol> *object2; /* { dg-error ".Integer {aka int}. is not a template" } */ /* { dg-error ".MyProtocol. was not declared in this scope" "" { target *-*-* } 21 } */ -Integer <NonExistingProtocol> *object3; /* { dg-error ".Integer. is not a template" } */ +Integer <NonExistingProtocol> *object3; /* { dg-error ".Integer {aka int}. is not a template" } */ /* { dg-error ".NonExistingProtocol. was not declared in this scope" "" { target *-*-* } 24 } */ diff --git a/gcc/toplev.c b/gcc/toplev.c index ffc10d9bf84..488e1497a02 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see #include "integrate.h" #include "debug.h" #include "target.h" +#include "common/common-target.h" #include "langhooks.h" #include "cfglayout.h" #include "cfgloop.h" @@ -1530,7 +1531,7 @@ process_options (void) fatal_error ("can%'t open %s: %m", aux_info_file_name); } - if (! targetm.have_named_sections) + if (!targetm_common.have_named_sections) { if (flag_function_sections) { diff --git a/gcc/tracer.c b/gcc/tracer.c index 918ed784537..d3523b985b1 100644 --- a/gcc/tracer.c +++ b/gcc/tracer.c @@ -393,8 +393,7 @@ struct gimple_opt_pass pass_tracer = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func - | TODO_update_ssa + TODO_update_ssa | TODO_verify_ssa /* todo_flags_finish */ } }; diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c index 25476e61a09..8307edbce61 100644 --- a/gcc/tree-call-cdce.c +++ b/gcc/tree-call-cdce.c @@ -928,6 +928,6 @@ struct gimple_opt_pass pass_call_cdce = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + TODO_verify_ssa /* todo_flags_finish */ } }; diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 85fece45d43..349f56ecf74 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -261,8 +261,7 @@ struct gimple_opt_pass pass_build_cfg = PROP_cfg, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_verify_stmts | TODO_cleanup_cfg - | TODO_dump_func /* todo_flags_finish */ + TODO_verify_stmts | TODO_cleanup_cfg /* todo_flags_finish */ } }; @@ -5090,6 +5089,7 @@ gimple_duplicate_bb (basic_block bb) { def_operand_p def_p; ssa_op_iter op_iter; + tree lhs; stmt = gsi_stmt (gsi); if (gimple_code (stmt) == GIMPLE_LABEL) @@ -5103,6 +5103,24 @@ gimple_duplicate_bb (basic_block bb) maybe_duplicate_eh_stmt (copy, stmt); gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt); + /* When copying around a stmt writing into a local non-user + aggregate, make sure it won't share stack slot with other + vars. */ + lhs = gimple_get_lhs (stmt); + if (lhs && TREE_CODE (lhs) != SSA_NAME) + { + tree base = get_base_address (lhs); + if (base + && (TREE_CODE (base) == VAR_DECL + || TREE_CODE (base) == RESULT_DECL) + && DECL_IGNORED_P (base) + && !TREE_STATIC (base) + && !DECL_EXTERNAL (base) + && (TREE_CODE (base) != VAR_DECL + || !DECL_HAS_VALUE_EXPR_P (base))) + DECL_NONSHAREABLE (base) = 1; + } + /* Create new names for all the definitions created by COPY and add replacement mappings for each new name. */ FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_ALL_DEFS) @@ -7234,7 +7252,7 @@ struct gimple_opt_pass pass_split_crit_edges = PROP_no_crit_edges, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_flow /* todo_flags_finish */ + TODO_verify_flow /* todo_flags_finish */ } }; diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index ad8e4777a05..1036e1e98f3 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -1054,7 +1054,7 @@ struct gimple_opt_pass pass_merge_phi = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ + TODO_ggc_collect /* todo_flags_finish */ | TODO_verify_ssa } }; diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c index ec2b438ca47..1b2a588ee2e 100644 --- a/gcc/tree-complex.c +++ b/gcc/tree-complex.c @@ -1623,8 +1623,7 @@ struct gimple_opt_pass pass_lower_complex = PROP_gimple_lcx, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func - | TODO_ggc_collect + TODO_ggc_collect | TODO_update_ssa | TODO_verify_stmts /* todo_flags_finish */ } @@ -1654,8 +1653,7 @@ struct gimple_opt_pass pass_lower_complex_O0 = PROP_gimple_lcx, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func - | TODO_ggc_collect + TODO_ggc_collect | TODO_update_ssa | TODO_verify_stmts /* todo_flags_finish */ } diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 7b28b8d9914..ebabf61c4db 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -1621,66 +1621,18 @@ analyze_ziv_subscript (tree chrec_a, fprintf (dump_file, ")\n"); } -/* Sets NIT to the estimated number of executions of the statements in - LOOP. If CONSERVATIVE is true, we must be sure that NIT is at least as - large as the number of iterations. If we have no reliable estimate, - the function returns false, otherwise returns true. */ - -bool -estimated_loop_iterations (struct loop *loop, bool conservative, - double_int *nit) -{ - estimate_numbers_of_iterations_loop (loop, true); - if (conservative) - { - if (!loop->any_upper_bound) - return false; - - *nit = loop->nb_iterations_upper_bound; - } - else - { - if (!loop->any_estimate) - return false; - - *nit = loop->nb_iterations_estimate; - } - - return true; -} - -/* Similar to estimated_loop_iterations, but returns the estimate only - if it fits to HOST_WIDE_INT. If this is not the case, or the estimate - on the number of iterations of LOOP could not be derived, returns -1. */ - -HOST_WIDE_INT -estimated_loop_iterations_int (struct loop *loop, bool conservative) -{ - double_int nit; - HOST_WIDE_INT hwi_nit; - - if (!estimated_loop_iterations (loop, conservative, &nit)) - return -1; - - if (!double_int_fits_in_shwi_p (nit)) - return -1; - hwi_nit = double_int_to_shwi (nit); - - return hwi_nit < 0 ? -1 : hwi_nit; -} - -/* Similar to estimated_loop_iterations, but returns the estimate as a tree, +/* Similar to max_stmt_executions_int, but returns the bound as a tree, and only if it fits to the int type. If this is not the case, or the - estimate on the number of iterations of LOOP could not be derived, returns + bound on the number of iterations of LOOP could not be derived, returns chrec_dont_know. */ static tree -estimated_loop_iterations_tree (struct loop *loop, bool conservative) +max_stmt_executions_tree (struct loop *loop) { double_int nit; tree type; - if (!estimated_loop_iterations (loop, conservative, &nit)) + if (!max_stmt_executions (loop, true, &nit)) return chrec_dont_know; type = lang_hooks.types.type_for_size (INT_TYPE_SIZE, true); @@ -1763,7 +1715,7 @@ analyze_siv_subscript_cst_affine (tree chrec_a, /* Perform weak-zero siv test to see if overlap is outside the loop bounds. */ - numiter = estimated_loop_iterations_int (loop, false); + numiter = max_stmt_executions_int (loop, true); if (numiter >= 0 && compare_tree_int (tmp, numiter) > 0) @@ -1841,7 +1793,7 @@ analyze_siv_subscript_cst_affine (tree chrec_a, /* Perform weak-zero siv test to see if overlap is outside the loop bounds. */ - numiter = estimated_loop_iterations_int (loop, false); + numiter = max_stmt_executions_int (loop, true); if (numiter >= 0 && compare_tree_int (tmp, numiter) > 0) @@ -2022,10 +1974,9 @@ compute_overlap_steps_for_affine_1_2 (tree chrec_a, tree chrec_b, step_z = int_cst_value (CHREC_RIGHT (chrec_b)); niter_x = - estimated_loop_iterations_int (get_chrec_loop (CHREC_LEFT (chrec_a)), - false); - niter_y = estimated_loop_iterations_int (get_chrec_loop (chrec_a), false); - niter_z = estimated_loop_iterations_int (get_chrec_loop (chrec_b), false); + max_stmt_executions_int (get_chrec_loop (CHREC_LEFT (chrec_a)), true); + niter_y = max_stmt_executions_int (get_chrec_loop (chrec_a), true); + niter_z = max_stmt_executions_int (get_chrec_loop (chrec_b), true); if (niter_x < 0 || niter_y < 0 || niter_z < 0) { @@ -2350,10 +2301,8 @@ analyze_subscript_affine_affine (tree chrec_a, HOST_WIDE_INT niter, niter_a, niter_b; affine_fn ova, ovb; - niter_a = estimated_loop_iterations_int (get_chrec_loop (chrec_a), - false); - niter_b = estimated_loop_iterations_int (get_chrec_loop (chrec_b), - false); + niter_a = max_stmt_executions_int (get_chrec_loop (chrec_a), true); + niter_b = max_stmt_executions_int (get_chrec_loop (chrec_b), true); niter = MIN (niter_a, niter_b); step_a = int_cst_value (CHREC_RIGHT (chrec_a)); step_b = int_cst_value (CHREC_RIGHT (chrec_b)); @@ -2460,10 +2409,10 @@ analyze_subscript_affine_affine (tree chrec_a, if (i1 > 0 && j1 > 0) { - HOST_WIDE_INT niter_a = estimated_loop_iterations_int - (get_chrec_loop (chrec_a), false); - HOST_WIDE_INT niter_b = estimated_loop_iterations_int - (get_chrec_loop (chrec_b), false); + HOST_WIDE_INT niter_a = max_stmt_executions_int + (get_chrec_loop (chrec_a), true); + HOST_WIDE_INT niter_b = max_stmt_executions_int + (get_chrec_loop (chrec_b), true); HOST_WIDE_INT niter = MIN (niter_a, niter_b); /* (X0, Y0) is a solution of the Diophantine equation: @@ -2740,8 +2689,7 @@ analyze_miv_subscript (tree chrec_a, in the same order. */ *overlaps_a = conflict_fn (1, affine_fn_cst (integer_zero_node)); *overlaps_b = conflict_fn (1, affine_fn_cst (integer_zero_node)); - *last_conflicts = estimated_loop_iterations_tree - (get_chrec_loop (chrec_a), true); + *last_conflicts = max_stmt_executions_tree (get_chrec_loop (chrec_a)); dependence_stats.num_miv_dependent++; } @@ -3754,7 +3702,7 @@ init_omega_for_ddr_1 (struct data_reference *dra, struct data_reference *drb, for (i = 0; i <= DDR_INNER_LOOP (ddr) && VEC_iterate (loop_p, DDR_LOOP_NEST (ddr), i, loopi); i++) { - HOST_WIDE_INT nbi = estimated_loop_iterations_int (loopi, false); + HOST_WIDE_INT nbi = max_stmt_executions_int (loopi, true); /* 0 <= loop_x */ ineq = omega_add_zero_geq (pb, omega_black); diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 9791bccecae..62d4bfe3fb8 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -113,8 +113,8 @@ struct gimple_opt_pass pass_referenced_vars = PROP_gimple_leh | PROP_cfg, /* properties_required */ PROP_referenced_vars, /* properties_provided */ 0, /* properties_destroyed */ - TODO_dump_func, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0, /* todo_flags_start */ + 0 /* todo_flags_finish */ } }; @@ -1000,4 +1000,3 @@ stmt_references_abnormal_ssa_name (gimple stmt) return false; } - diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index e87c32e798b..5831d34826c 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -2052,7 +2052,7 @@ struct gimple_opt_pass pass_lower_eh = PROP_gimple_leh, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -2865,7 +2865,7 @@ struct gimple_opt_pass pass_refactor_eh = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -3071,7 +3071,7 @@ struct gimple_opt_pass pass_lower_resx = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_flow /* todo_flags_finish */ + TODO_verify_flow /* todo_flags_finish */ } }; @@ -3272,7 +3272,7 @@ struct gimple_opt_pass pass_lower_eh_dispatch = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_flow /* todo_flags_finish */ + TODO_verify_flow /* todo_flags_finish */ } }; @@ -4015,7 +4015,7 @@ struct gimple_opt_pass pass_cleanup_eh = { 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c index 11240477b97..e1a1c1d56cc 100644 --- a/gcc/tree-emutls.c +++ b/gcc/tree-emutls.c @@ -783,7 +783,7 @@ ipa_lower_emutls (void) VEC_free (tree, heap, access_vars); free_varpool_node_set (tls_vars); - return TODO_dump_func | TODO_ggc_collect | TODO_verify_all; + return TODO_ggc_collect | TODO_verify_all; } /* If the target supports TLS natively, we need do nothing here. */ diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index ab5c80cdde0..a864e169eb7 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -808,7 +808,7 @@ bool may_be_nonaddressable_p (tree expr); /* In tree-ssa-threadupdate.c. */ extern bool thread_through_all_blocks (bool); -extern void register_jump_thread (edge, edge); +extern void register_jump_thread (edge, edge, edge); /* In gimplify.c */ tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree); diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index bf1c8cdbc47..4fde3a37a48 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -1808,7 +1808,7 @@ struct gimple_opt_pass pass_if_conversion = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_stmts | TODO_verify_flow + TODO_verify_stmts | TODO_verify_flow /* todo_flags_finish */ } }; diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 74386e44411..f138e5b72c9 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -2413,8 +2413,7 @@ struct gimple_opt_pass pass_build_ssa = PROP_ssa, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func - | TODO_update_ssa_only_virtuals + TODO_update_ssa_only_virtuals | TODO_verify_ssa | TODO_remove_unused_locals /* todo_flags_finish */ } diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 1d6944eef96..ae17755a9d6 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -1313,6 +1313,6 @@ struct gimple_opt_pass pass_loop_distribution = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c index 40120b0dd4f..bcd77e27bd9 100644 --- a/gcc/tree-mudflap.c +++ b/gcc/tree-mudflap.c @@ -1389,7 +1389,7 @@ struct gimple_opt_pass pass_mudflap_1 = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -1409,7 +1409,7 @@ struct gimple_opt_pass pass_mudflap_2 = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_verify_flow | TODO_verify_stmts - | TODO_dump_func | TODO_update_ssa /* todo_flags_finish */ + | TODO_update_ssa /* todo_flags_finish */ } }; diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c index 32e422e5e20..982fcc8fc11 100644 --- a/gcc/tree-nrv.c +++ b/gcc/tree-nrv.c @@ -288,7 +288,7 @@ struct gimple_opt_pass pass_nrv = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ + TODO_ggc_collect /* todo_flags_finish */ } }; diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index 41118d25b2e..674f72e9031 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -1282,6 +1282,6 @@ struct gimple_opt_pass pass_object_sizes = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + TODO_verify_ssa /* todo_flags_finish */ } }; diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index c46cf6c5458..411886cacb6 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -208,8 +208,7 @@ struct gimple_opt_pass pass_cleanup_cfg_post_optimizing = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ - | TODO_remove_unused_locals + TODO_remove_unused_locals /* todo_flags_finish */ } }; diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index 9a11f80d4b0..9d2ea1a05f6 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -2134,7 +2134,7 @@ parallelize_loops (void) /* FIXME: the check for vector phi nodes could be removed. */ || loop_has_vector_phi_nodes (loop)) continue; - estimated = estimated_loop_iterations_int (loop, false); + estimated = max_stmt_executions_int (loop, false); /* FIXME: Bypass this check as graphite doesn't update the count and frequency correctly now. */ if (!flag_loop_parallelize_all diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index 3bc4d5c532c..cd9b49d4304 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.c @@ -591,7 +591,7 @@ struct simple_ipa_opt_pass pass_ipa_tree_profile = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 8ad84beb655..322abb570a4 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -671,8 +671,7 @@ type_internals_preclude_sra_p (tree type) && int_bit_position (fld) % BITS_PER_UNIT != 0)) return true; - if (AGGREGATE_TYPE_P (ft) - && type_internals_preclude_sra_p (ft)) + if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft)) return true; } @@ -681,10 +680,13 @@ type_internals_preclude_sra_p (tree type) case ARRAY_TYPE: et = TREE_TYPE (type); - if (AGGREGATE_TYPE_P (et)) - return type_internals_preclude_sra_p (et); - else - return false; + if (TYPE_VOLATILE (et)) + return true; + + if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et)) + return true; + + return false; default: return false; @@ -1421,12 +1423,16 @@ build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset, { if (TREE_CODE (model->expr) == COMPONENT_REF) { - tree t, exp_type; - offset -= int_bit_position (TREE_OPERAND (model->expr, 1)); + tree t, exp_type, fld = TREE_OPERAND (model->expr, 1); + tree cr_offset = component_ref_field_offset (model->expr); + + gcc_assert (cr_offset && host_integerp (cr_offset, 1)); + offset -= TREE_INT_CST_LOW (cr_offset) * BITS_PER_UNIT; + offset -= TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld)); exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0)); t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after); - return fold_build3_loc (loc, COMPONENT_REF, model->type, t, - TREE_OPERAND (model->expr, 1), NULL_TREE); + return fold_build3_loc (loc, COMPONENT_REF, model->type, t, fld, + TREE_OPERAND (model->expr, 2)); } else return build_ref_for_offset (loc, base, offset, model->type, @@ -3093,8 +3099,7 @@ struct gimple_opt_pass pass_sra_early = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func - | TODO_update_ssa + TODO_update_ssa | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ } @@ -3115,8 +3120,7 @@ struct gimple_opt_pass pass_sra = 0, /* properties_provided */ 0, /* properties_destroyed */ TODO_update_address_taken, /* todo_flags_start */ - TODO_dump_func - | TODO_update_ssa + TODO_update_ssa | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ } @@ -4589,8 +4593,6 @@ struct gimple_opt_pass pass_early_ipa_sra = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_dump_cgraph /* todo_flags_finish */ + TODO_dump_cgraph /* todo_flags_finish */ } }; - - diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 2caec4c5679..11bfb767f4c 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1953,7 +1953,7 @@ struct gimple_opt_pass pass_ccp = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa + TODO_verify_ssa | TODO_verify_stmts | TODO_ggc_collect/* todo_flags_finish */ } }; @@ -2256,8 +2256,7 @@ struct gimple_opt_pass pass_fold_builtins = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func - | TODO_verify_ssa + TODO_verify_ssa | TODO_update_ssa /* todo_flags_finish */ } }; diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c index 211d7de23c4..4c6d9927bbd 100644 --- a/gcc/tree-ssa-copy.c +++ b/gcc/tree-ssa-copy.c @@ -848,7 +848,6 @@ struct gimple_opt_pass pass_copy_prop = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_cleanup_cfg - | TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa | TODO_update_ssa /* todo_flags_finish */ diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c index ae4fb5fba39..88a156bab76 100644 --- a/gcc/tree-ssa-copyrename.c +++ b/gcc/tree-ssa-copyrename.c @@ -399,6 +399,6 @@ struct gimple_opt_pass pass_rename_ssa_copies = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + TODO_verify_ssa /* todo_flags_finish */ } }; diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index b13ef59af49..6b778765e92 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -1527,7 +1527,7 @@ struct gimple_opt_pass pass_dce = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + TODO_verify_ssa /* todo_flags_finish */ } }; @@ -1546,7 +1546,7 @@ struct gimple_opt_pass pass_dce_loop = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + TODO_verify_ssa /* todo_flags_finish */ } }; @@ -1565,7 +1565,7 @@ struct gimple_opt_pass pass_cd_dce = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa + TODO_verify_ssa | TODO_verify_flow /* todo_flags_finish */ } }; diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 2e9498efdcc..f41d7eca562 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -816,8 +816,7 @@ struct gimple_opt_pass pass_dominator = TODO_cleanup_cfg | TODO_update_ssa | TODO_verify_ssa - | TODO_verify_flow - | TODO_dump_func /* todo_flags_finish */ + | TODO_verify_flow /* todo_flags_finish */ } }; @@ -2969,7 +2968,6 @@ struct gimple_opt_pass pass_phi_only_cprop = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_cleanup_cfg - | TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa | TODO_verify_stmts diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index 6d51dabced6..285d08c66c6 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -352,9 +352,7 @@ struct gimple_opt_pass pass_dse = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func - | TODO_ggc_collect + TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ } }; - diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 77a6264d560..86f45021229 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -2437,10 +2437,8 @@ struct gimple_opt_pass pass_forwprop = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func - | TODO_ggc_collect + TODO_ggc_collect | TODO_update_ssa | TODO_verify_ssa /* todo_flags_finish */ } }; - diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c index 9063bfdcd55..459c60a3057 100644 --- a/gcc/tree-ssa-ifcombine.c +++ b/gcc/tree-ssa-ifcombine.c @@ -663,8 +663,7 @@ struct gimple_opt_pass pass_tree_ifcombine = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func - | TODO_ggc_collect + TODO_ggc_collect | TODO_update_ssa | TODO_verify_ssa /* todo_flags_finish */ } diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c index c58cb5f8bba..57e71b44c28 100644 --- a/gcc/tree-ssa-loop-ch.c +++ b/gcc/tree-ssa-loop-ch.c @@ -278,7 +278,6 @@ struct gimple_opt_pass pass_ch = 0, /* todo_flags_start */ TODO_cleanup_cfg | TODO_verify_ssa - | TODO_verify_flow - | TODO_dump_func /* todo_flags_finish */ + | TODO_verify_flow /* todo_flags_finish */ } }; diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 10fd7dc48c7..3717639f0d2 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -115,7 +115,7 @@ along with GCC; see the file COPYING3. If not see static inline HOST_WIDE_INT avg_loop_niter (struct loop *loop) { - HOST_WIDE_INT niter = estimated_loop_iterations_int (loop, false); + HOST_WIDE_INT niter = max_stmt_executions_int (loop, false); if (niter == -1) return AVG_LOOP_NITER (loop); diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 230593ad264..cf2f4556395 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -2568,18 +2568,17 @@ record_estimate (struct loop *loop, tree bound, double_int i_bound, } /* Update the number of iteration estimates according to the bound. - If at_stmt is an exit, then every statement in the loop is - executed at most BOUND + 1 times. If it is not an exit, then - some of the statements before it could be executed BOUND + 2 - times, if an exit of LOOP is before stmt. */ + If at_stmt is an exit or dominates the single exit from the loop, + then the loop latch is executed at most BOUND times, otherwise + it can be executed BOUND + 1 times. */ exit = single_exit (loop); if (is_exit || (exit != NULL && dominated_by_p (CDI_DOMINATORS, exit->src, gimple_bb (at_stmt)))) - delta = double_int_one; + delta = double_int_zero; else - delta = double_int_two; + delta = double_int_one; i_bound = double_int_add (i_bound, delta); /* If an overflow occurred, ignore the result. */ @@ -2876,6 +2875,16 @@ infer_loop_bounds_from_pointer_arith (struct loop *loop, gimple stmt) low = lower_bound_in_type (type, type); high = upper_bound_in_type (type, type); + /* In C, pointer arithmetic p + 1 cannot use a NULL pointer, and p - 1 cannot + produce a NULL pointer. The contrary would mean NULL points to an object, + while NULL is supposed to compare unequal with the address of all objects. + Furthermore, p + 1 cannot produce a NULL pointer and p - 1 cannot use a + NULL pointer since that would mean wrapping, which we assume here not to + happen. So, we can exclude NULL from the valid range of pointer + arithmetic. */ + if (flag_delete_null_pointer_checks && int_cst_value (low) == 0) + low = build_int_cstu (TREE_TYPE (low), TYPE_ALIGN_UNIT (TREE_TYPE (type))); + record_nonwrapping_iv (loop, base, step, stmt, low, high, false, true); } @@ -3042,6 +3051,93 @@ estimate_numbers_of_iterations_loop (struct loop *loop, bool use_undefined_p) loop->nb_iterations_estimate = loop->nb_iterations_upper_bound; } +/* Sets NIT to the estimated number of executions of the latch of the + LOOP. If CONSERVATIVE is true, we must be sure that NIT is at least as + large as the number of iterations. If we have no reliable estimate, + the function returns false, otherwise returns true. */ + +bool +estimated_loop_iterations (struct loop *loop, bool conservative, + double_int *nit) +{ + estimate_numbers_of_iterations_loop (loop, true); + if (conservative) + { + if (!loop->any_upper_bound) + return false; + + *nit = loop->nb_iterations_upper_bound; + } + else + { + if (!loop->any_estimate) + return false; + + *nit = loop->nb_iterations_estimate; + } + + return true; +} + +/* Similar to estimated_loop_iterations, but returns the estimate only + if it fits to HOST_WIDE_INT. If this is not the case, or the estimate + on the number of iterations of LOOP could not be derived, returns -1. */ + +HOST_WIDE_INT +estimated_loop_iterations_int (struct loop *loop, bool conservative) +{ + double_int nit; + HOST_WIDE_INT hwi_nit; + + if (!estimated_loop_iterations (loop, conservative, &nit)) + return -1; + + if (!double_int_fits_in_shwi_p (nit)) + return -1; + hwi_nit = double_int_to_shwi (nit); + + return hwi_nit < 0 ? -1 : hwi_nit; +} + +/* Returns an upper bound on the number of executions of statements + in the LOOP. For statements before the loop exit, this exceeds + the number of execution of the latch by one. */ + +HOST_WIDE_INT +max_stmt_executions_int (struct loop *loop, bool conservative) +{ + HOST_WIDE_INT nit = estimated_loop_iterations_int (loop, conservative); + HOST_WIDE_INT snit; + + if (nit == -1) + return -1; + + snit = (HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) nit + 1); + + /* If the computation overflows, return -1. */ + return snit < 0 ? -1 : snit; +} + +/* Sets NIT to the estimated number of executions of the latch of the + LOOP, plus one. If CONSERVATIVE is true, we must be sure that NIT is at + least as large as the number of iterations. If we have no reliable + estimate, the function returns false, otherwise returns true. */ + +bool +max_stmt_executions (struct loop *loop, bool conservative, double_int *nit) +{ + double_int nit_minus_one; + + if (!estimated_loop_iterations (loop, conservative, nit)) + return false; + + nit_minus_one = *nit; + + *nit = double_int_add (*nit, double_int_one); + + return double_int_ucmp (*nit, nit_minus_one) > 0; +} + /* Records estimates on numbers of iterations of loops. */ void diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c index d920ec6eb07..9d9d249d2c2 100644 --- a/gcc/tree-ssa-loop-prefetch.c +++ b/gcc/tree-ssa-loop-prefetch.c @@ -1549,7 +1549,7 @@ determine_loop_nest_reuse (struct loop *loop, struct mem_ref_group *refs, continue; aloop = VEC_index (loop_p, vloops, i); - vol = estimated_loop_iterations_int (aloop, false); + vol = max_stmt_executions_int (aloop, false); if (vol < 0) vol = expected_loop_iterations (aloop); volume *= vol; @@ -1801,7 +1801,7 @@ loop_prefetch_arrays (struct loop *loop) return false; ahead = (PREFETCH_LATENCY + time - 1) / time; - est_niter = estimated_loop_iterations_int (loop, false); + est_niter = max_stmt_executions_int (loop, false); /* Prefetching is not likely to be profitable if the trip count to ahead ratio is too small. */ diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c index c7efc7c0f6e..1a9c2be7376 100644 --- a/gcc/tree-ssa-loop.c +++ b/gcc/tree-ssa-loop.c @@ -60,7 +60,7 @@ struct gimple_opt_pass pass_tree_loop = 0, /* properties_provided */ 0, /* properties_destroyed */ TODO_ggc_collect, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa | TODO_ggc_collect /* todo_flags_finish */ + TODO_verify_ssa | TODO_ggc_collect /* todo_flags_finish */ } }; @@ -95,7 +95,7 @@ struct gimple_opt_pass pass_tree_loop_init = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -131,7 +131,7 @@ struct gimple_opt_pass pass_lim = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -167,7 +167,7 @@ struct gimple_opt_pass pass_tree_unswitch = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_ggc_collect | TODO_dump_func /* todo_flags_finish */ + TODO_ggc_collect /* todo_flags_finish */ } }; @@ -203,8 +203,7 @@ struct gimple_opt_pass pass_predcom = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func - | TODO_update_ssa_only_virtuals /* todo_flags_finish */ + TODO_update_ssa_only_virtuals /* todo_flags_finish */ } }; @@ -240,7 +239,7 @@ struct gimple_opt_pass pass_vectorize = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_update_ssa + TODO_update_ssa | TODO_ggc_collect /* todo_flags_finish */ } }; @@ -308,7 +307,7 @@ struct gimple_opt_pass pass_graphite_transforms = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -345,7 +344,7 @@ struct gimple_opt_pass pass_check_data_deps = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -381,7 +380,7 @@ struct gimple_opt_pass pass_iv_canon = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -408,7 +407,7 @@ struct gimple_opt_pass pass_scev_cprop = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_cleanup_cfg + TODO_cleanup_cfg | TODO_update_ssa_only_virtuals /* todo_flags_finish */ } @@ -480,8 +479,7 @@ struct gimple_opt_pass pass_complete_unroll = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func - | TODO_ggc_collect /* todo_flags_finish */ + TODO_ggc_collect /* todo_flags_finish */ } }; @@ -528,7 +526,6 @@ struct gimple_opt_pass pass_complete_unrolli = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_verify_flow - | TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } }; @@ -567,7 +564,7 @@ struct gimple_opt_pass pass_parallelize_loops = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -603,7 +600,7 @@ struct gimple_opt_pass pass_loop_prefetch = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; @@ -640,7 +637,7 @@ struct gimple_opt_pass pass_iv_optimize = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_update_ssa | TODO_ggc_collect /* todo_flags_finish */ + TODO_update_ssa | TODO_ggc_collect /* todo_flags_finish */ } }; @@ -671,7 +668,6 @@ struct gimple_opt_pass pass_tree_loop_done = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_cleanup_cfg - | TODO_verify_flow - | TODO_dump_func /* todo_flags_finish */ + | TODO_verify_flow /* todo_flags_finish */ } }; diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index bffd7f26c43..bc7919a39ad 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -645,7 +645,7 @@ struct gimple_opt_pass pass_cse_reciprocals = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_update_ssa | TODO_verify_ssa + TODO_update_ssa | TODO_verify_ssa | TODO_verify_stmts /* todo_flags_finish */ } }; @@ -1491,7 +1491,7 @@ struct gimple_opt_pass pass_cse_sincos = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_update_ssa | TODO_verify_ssa + TODO_update_ssa | TODO_verify_ssa | TODO_verify_stmts /* todo_flags_finish */ } }; @@ -1918,7 +1918,7 @@ execute_optimize_bswap (void) statistics_counter_event (cfun, "64-bit bswap implementations found", bswap_stats.found_64bit); - return (changed ? TODO_dump_func | TODO_update_ssa | TODO_verify_ssa + return (changed ? TODO_update_ssa | TODO_verify_ssa | TODO_verify_stmts : 0); } @@ -2471,7 +2471,6 @@ struct gimple_opt_pass pass_optimize_widening_mul = 0, /* todo_flags_start */ TODO_verify_ssa | TODO_verify_stmts - | TODO_dump_func | TODO_update_ssa /* todo_flags_finish */ } }; diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 6b15ae09488..79e8e015fda 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -1588,8 +1588,7 @@ struct gimple_opt_pass pass_phiopt = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func - | TODO_ggc_collect + TODO_ggc_collect | TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts /* todo_flags_finish */ @@ -1617,8 +1616,7 @@ struct gimple_opt_pass pass_cselim = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func - | TODO_ggc_collect + TODO_ggc_collect | TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts /* todo_flags_finish */ diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c index a38e6962f95..30644372564 100644 --- a/gcc/tree-ssa-phiprop.c +++ b/gcc/tree-ssa-phiprop.c @@ -426,8 +426,7 @@ struct gimple_opt_pass pass_phiprop = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func - | TODO_ggc_collect + TODO_ggc_collect | TODO_update_ssa | TODO_verify_ssa /* todo_flags_finish */ } diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 27e84c22c5c..7c54d2a074f 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -4978,7 +4978,7 @@ struct gimple_opt_pass pass_pre = 0, /* properties_provided */ 0, /* properties_destroyed */ TODO_rebuild_alias, /* todo_flags_start */ - TODO_update_ssa_only_virtuals | TODO_dump_func | TODO_ggc_collect + TODO_update_ssa_only_virtuals | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ } }; @@ -5013,6 +5013,6 @@ struct gimple_opt_pass pass_fre = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ + TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ } }; diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 987ec650778..d8f9e2ecf61 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -2299,8 +2299,6 @@ struct gimple_opt_pass pass_reassoc = 0, /* todo_flags_start */ TODO_verify_ssa | TODO_verify_flow - | TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } }; - diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c index 4dc5ae44a27..5107238093d 100644 --- a/gcc/tree-ssa-sink.c +++ b/gcc/tree-ssa-sink.c @@ -639,7 +639,6 @@ struct gimple_opt_pass pass_sink_code = TODO_update_ssa | TODO_verify_ssa | TODO_verify_flow - | TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } }; diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index ce0d8d0653d..6f076dcd3e7 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -6634,7 +6634,7 @@ struct gimple_opt_pass pass_build_alias = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_rebuild_alias | TODO_dump_func /* todo_flags_finish */ + TODO_rebuild_alias /* todo_flags_finish */ } }; @@ -6656,7 +6656,7 @@ struct gimple_opt_pass pass_build_ealias = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_rebuild_alias | TODO_dump_func /* todo_flags_finish */ + TODO_rebuild_alias /* todo_flags_finish */ } }; @@ -6675,6 +6675,26 @@ gate_ipa_pta (void) struct pt_solution ipa_escaped_pt = { true, false, false, false, false, false, false, NULL }; +/* Associate node with varinfo DATA. Worker for + cgraph_for_node_and_aliases. */ +static bool +associate_varinfo_to_alias (struct cgraph_node *node, void *data) +{ + if (node->alias || node->thunk.thunk_p) + insert_vi_for_tree (node->decl, (varinfo_t)data); + return false; +} + +/* Associate node with varinfo DATA. Worker for + varpool_for_node_and_aliases. */ +static bool +associate_varinfo_to_alias_1 (struct varpool_node *node, void *data) +{ + if (node->alias) + insert_vi_for_tree (node->decl, (varinfo_t)data); + return false; +} + /* Execute the driver for IPA PTA. */ static unsigned int ipa_pta_execute (void) @@ -6690,35 +6710,28 @@ ipa_pta_execute (void) /* Build the constraints. */ for (node = cgraph_nodes; node; node = node->next) { - struct cgraph_node *alias; varinfo_t vi; - /* Nodes without a body are not interesting. Especially do not visit clones at this point for now - we get duplicate decls there for inline clones at least. */ - if (!gimple_has_body_p (node->decl) + if (!cgraph_function_with_gimple_body_p (node) || node->clone_of) continue; vi = create_function_info_for (node->decl, - alias_get_name (node->decl)); - - /* Associate the varinfo node with all aliases. */ - for (alias = node->same_body; alias; alias = alias->next) - insert_vi_for_tree (alias->decl, vi); + alias_get_name (node->decl)); + cgraph_for_node_and_aliases (node, associate_varinfo_to_alias, vi, true); } /* Create constraints for global variables and their initializers. */ for (var = varpool_nodes; var; var = var->next) { - struct varpool_node *alias; varinfo_t vi; + if (var->alias) + continue; vi = get_vi_for_tree (var->decl); - - /* Associate the varinfo node with all aliases. */ - for (alias = var->extra_name; alias; alias = alias->next) - insert_vi_for_tree (alias->decl, vi); + varpool_for_node_and_aliases (var, associate_varinfo_to_alias_1, vi, true); } if (dump_file) @@ -6737,7 +6750,7 @@ ipa_pta_execute (void) tree old_func_decl; /* Nodes without a body are not interesting. */ - if (!gimple_has_body_p (node->decl) + if (!cgraph_function_with_gimple_body_p (node) || node->clone_of) continue; @@ -6846,7 +6859,7 @@ ipa_pta_execute (void) struct cgraph_edge *e; /* Nodes without a body are not interesting. */ - if (!gimple_has_body_p (node->decl) + if (!cgraph_function_with_gimple_body_p (node) || node->clone_of) continue; diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index 24e63977c29..a485b211e59 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -1,5 +1,5 @@ /* SSA Jump Threading - Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Contributed by Jeff Law <law@redhat.com> @@ -652,6 +652,27 @@ thread_around_empty_block (edge taken_edge, return NULL; } +/* E1 and E2 are edges into the same basic block. Return TRUE if the + PHI arguments associated with those edges are equal or there are no + PHI arguments, otherwise return FALSE. */ + +static bool +phi_args_equal_on_edges (edge e1, edge e2) +{ + gimple_stmt_iterator gsi; + int indx1 = e1->dest_idx; + int indx2 = e2->dest_idx; + + for (gsi = gsi_start_phis (e1->dest); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple phi = gsi_stmt (gsi); + + if (!operand_equal_p (gimple_phi_arg_def (phi, indx1), + gimple_phi_arg_def (phi, indx2), 0)) + return false; + } + return true; +} /* We are exiting E->src, see if E->dest ends with a conditional jump which has a known value when reached via E. @@ -770,11 +791,73 @@ thread_across_edge (gimple dummy_cond, } remove_temporary_equivalences (stack); - register_jump_thread (e, taken_edge); + register_jump_thread (e, taken_edge, NULL); return; } } + /* We were unable to determine what out edge from E->dest is taken. However, + we might still be able to thread through successors of E->dest. This + often occurs when E->dest is a joiner block which then fans back out + based on redundant tests. + + If so, we'll copy E->dest and redirect the appropriate predecessor to + the copy. Within the copy of E->dest, we'll thread one or more edges + to points deeper in the CFG. + + This is a stopgap until we have a more structured approach to path + isolation. */ + { + edge e2, e3, taken_edge; + edge_iterator ei; + bool found = false; + bitmap visited = BITMAP_ALLOC (NULL); + + /* Look at each successor of E->dest to see if we can thread through it. */ + FOR_EACH_EDGE (taken_edge, ei, e->dest->succs) + { + /* Avoid threading to any block we have already visited. */ + bitmap_clear (visited); + bitmap_set_bit (visited, taken_edge->dest->index); + bitmap_set_bit (visited, e->dest->index); + + /* Record whether or not we were able to thread through a successor + of E->dest. */ + found = false; + e3 = taken_edge; + do + { + e2 = thread_around_empty_block (e3, + dummy_cond, + handle_dominating_asserts, + simplify, + visited); + if (e2) + { + e3 = e2; + found = true; + } + } + while (e2); + + /* If we were able to thread through a successor of E->dest, then + record the jump threading opportunity. */ + if (found) + { + edge tmp; + /* If there is already an edge from the block to be duplicated + (E2->src) to the final target (E3->dest), then make sure that + the PHI args associated with the edges E2 and E3 are the + same. */ + tmp = find_edge (taken_edge->src, e3->dest); + if (!tmp || phi_args_equal_on_edges (tmp, e3)) + register_jump_thread (e, taken_edge, e3); + } + + } + BITMAP_FREE (visited); + } + fail: remove_temporary_equivalences (stack); } diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index c6e34051c9c..e0335dc8c10 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -1,6 +1,6 @@ /* Thread edges through blocks and update the control flow and SSA graphs. - Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Free Software Foundation, - Inc. + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 201 + Free Software Foundation, Inc. This file is part of GCC. @@ -121,6 +121,8 @@ struct redirection_data its single successor. */ edge outgoing_edge; + edge intermediate_edge; + /* A list of incoming edges which we want to thread to OUTGOING_EDGE->dest. */ struct el *incoming_edges; @@ -153,6 +155,7 @@ static VEC(edge,heap) *threaded_edges; threading is attached to the AUX field for the incoming edge. Use these macros to access the underlying structure attached to the AUX field. */ #define THREAD_TARGET(E) ((edge *)(E)->aux)[0] +#define THREAD_TARGET2(E) ((edge *)(E)->aux)[1] /* Jump threading statistics. */ @@ -231,8 +234,10 @@ redirection_data_eq (const void *p1, const void *p2) { edge e1 = ((const struct redirection_data *)p1)->outgoing_edge; edge e2 = ((const struct redirection_data *)p2)->outgoing_edge; + edge e3 = ((const struct redirection_data *)p1)->intermediate_edge; + edge e4 = ((const struct redirection_data *)p2)->intermediate_edge; - return e1 == e2; + return e1 == e2 && e3 == e4; } /* Given an outgoing edge E lookup and return its entry in our hash table. @@ -242,7 +247,7 @@ redirection_data_eq (const void *p1, const void *p2) edges associated with E in the hash table. */ static struct redirection_data * -lookup_redirection_data (edge e, edge incoming_edge, enum insert_option insert) +lookup_redirection_data (edge e, enum insert_option insert) { void **slot; struct redirection_data *elt; @@ -250,7 +255,9 @@ lookup_redirection_data (edge e, edge incoming_edge, enum insert_option insert) /* Build a hash table element so we can see if E is already in the table. */ elt = XNEW (struct redirection_data); - elt->outgoing_edge = e; + elt->intermediate_edge = THREAD_TARGET2 (e) ? THREAD_TARGET (e) : NULL; + elt->outgoing_edge = THREAD_TARGET2 (e) ? THREAD_TARGET2 (e) + : THREAD_TARGET (e); elt->dup_block = NULL; elt->incoming_edges = NULL; @@ -270,7 +277,7 @@ lookup_redirection_data (edge e, edge incoming_edge, enum insert_option insert) { *slot = (void *)elt; elt->incoming_edges = XNEW (struct el); - elt->incoming_edges->e = incoming_edge; + elt->incoming_edges->e = e; elt->incoming_edges->next = NULL; return elt; } @@ -290,7 +297,7 @@ lookup_redirection_data (edge e, edge incoming_edge, enum insert_option insert) { struct el *el = XNEW (struct el); el->next = elt->incoming_edges; - el->e = incoming_edge; + el->e = e; elt->incoming_edges = el; } @@ -298,6 +305,41 @@ lookup_redirection_data (edge e, edge incoming_edge, enum insert_option insert) } } +/* For each PHI in BB, copy the argument associated with SRC_E to TGT_E. */ + +static void +copy_phi_args (basic_block bb, edge src_e, edge tgt_e) +{ + gimple_stmt_iterator gsi; + int src_indx = src_e->dest_idx; + + for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple phi = gsi_stmt (gsi); + source_location locus = gimple_phi_arg_location (phi, src_indx); + add_phi_arg (phi, gimple_phi_arg_def (phi, src_indx), tgt_e, locus); + } +} + +/* We have recently made a copy of ORIG_BB, including its outgoing + 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. */ + +static void +update_destination_phis (basic_block orig_bb, basic_block new_bb) +{ + edge_iterator ei; + edge e; + + FOR_EACH_EDGE (e, ei, orig_bb->succs) + { + edge e2 = find_edge (new_bb, e->dest); + copy_phi_args (e->dest, e, e2); + } +} + /* Given a duplicate block and its single destination (both stored in RD). Create an edge between the duplicate and its single destination. @@ -310,7 +352,6 @@ create_edge_and_update_destination_phis (struct redirection_data *rd, basic_block bb) { edge e = make_edge (bb, rd->outgoing_edge->dest, EDGE_FALLTHRU); - gimple_stmt_iterator gsi; rescan_loop_exit (e, true, false); e->probability = REG_BR_PROB_BASE; @@ -318,8 +359,9 @@ create_edge_and_update_destination_phis (struct redirection_data *rd, if (rd->outgoing_edge->aux) { - e->aux = (edge *) XNEWVEC (edge, 1); + e->aux = (edge *) XNEWVEC (edge, 2); THREAD_TARGET(e) = THREAD_TARGET (rd->outgoing_edge); + THREAD_TARGET2(e) = THREAD_TARGET2 (rd->outgoing_edge); } else { @@ -330,17 +372,43 @@ 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. */ - for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) + copy_phi_args (e->dest, rd->outgoing_edge, e); +} + +/* Wire up the outgoing edges from the duplicate block and + update any PHIs as needed. */ +static void +fix_duplicate_block_edges (struct redirection_data *rd, + struct local_info *local_info) +{ + /* If we were threading through an joiner block, then we want + to keep its control statement and redirect an outgoing edge. + Else we want to remove the control statement & edges, then create + a new outgoing edge. In both cases we may need to update PHIs. */ + if (THREAD_TARGET2 (rd->incoming_edges->e) == rd->outgoing_edge) { - gimple phi = gsi_stmt (gsi); - source_location locus; - int indx = rd->outgoing_edge->dest_idx; + edge victim; + edge e2; + edge e = rd->incoming_edges->e; + + /* This updates the PHIs at the destination of the duplicate + block. */ + update_destination_phis (local_info->bb, rd->dup_block); - locus = gimple_phi_arg_location (phi, indx); - add_phi_arg (phi, gimple_phi_arg_def (phi, indx), e, locus); + /* Find the edge from the duplicate block to the block we're + threading through. That's the edge we want to redirect. */ + victim = find_edge (rd->dup_block, THREAD_TARGET (e)->dest); + e2 = redirect_edge_and_branch (victim, THREAD_TARGET2 (e)->dest); + + /* This updates the PHI at the target of the threaded edge. */ + copy_phi_args (e2->dest, THREAD_TARGET2 (e), e2); + } + else + { + remove_ctrl_stmt_and_useless_edges (rd->dup_block, NULL); + create_edge_and_update_destination_phis (rd, rd->dup_block); } } - /* Hash table traversal callback routine to create duplicate blocks. */ static int @@ -365,9 +433,8 @@ create_duplicates (void **slot, void *data) create_block_for_threading (local_info->template_block, rd); /* Go ahead and wire up outgoing edges and update PHIs for the duplicate - block. */ - remove_ctrl_stmt_and_useless_edges (rd->dup_block, NULL); - create_edge_and_update_destination_phis (rd, rd->dup_block); + block. */ + fix_duplicate_block_edges (rd, local_info); } /* Keep walking the hash table. */ @@ -384,12 +451,16 @@ fixup_template_block (void **slot, void *data) struct redirection_data *rd = (struct redirection_data *) *slot; struct local_info *local_info = (struct local_info *)data; - /* If this is the template block, then create its outgoing edges - and halt the hash table traversal. */ + /* If this is the template block halt the traversal after updating + it appropriately. + + If we were threading through an joiner block, then we want + to keep its control statement and redirect an outgoing edge. + Else we want to remove the control statement & edges, then create + a new outgoing edge. In both cases we may need to update PHIs. */ if (rd->dup_block && rd->dup_block == local_info->template_block) { - remove_ctrl_stmt_and_useless_edges (rd->dup_block, NULL); - create_edge_and_update_destination_phis (rd, rd->dup_block); + fix_duplicate_block_edges (rd, local_info); return 0; } @@ -419,8 +490,18 @@ redirect_edges (void **slot, void *data) free (el); thread_stats.num_threaded_edges++; + /* If we are threading through a joiner block, then we have to + find the edge we want to redirect and update some PHI nodes. */ + if (THREAD_TARGET2 (e)) + { + edge e2; - if (rd->dup_block) + /* We want to redirect the incoming edge to the joiner block (E) + to instead reach the duplicate of the joiner block. */ + e2 = redirect_edge_and_branch (e, rd->dup_block); + flush_pending_stmts (e2); + } + else if (rd->dup_block) { edge e2; @@ -546,14 +627,18 @@ thread_block (basic_block bb, bool noloop_only) if (e->aux == NULL) continue; - e2 = THREAD_TARGET (e); + if (THREAD_TARGET2 (e)) + e2 = THREAD_TARGET2 (e); + else + e2 = THREAD_TARGET (e); if (!e2 /* If NOLOOP_ONLY is true, we only allow threading through the header of a loop to exit edges. */ || (noloop_only && bb == bb->loop_father->header - && (!loop_exit_edge_p (bb->loop_father, e2)))) + && (!loop_exit_edge_p (bb->loop_father, e2) + || THREAD_TARGET2 (e)))) continue; if (e->dest == e2->src) @@ -562,7 +647,7 @@ thread_block (basic_block bb, bool noloop_only) /* Insert the outgoing edge into the hash table if it is not already in the hash table. */ - lookup_redirection_data (e2, e, INSERT); + lookup_redirection_data (e, INSERT); } /* We do not update dominance info. */ @@ -817,6 +902,8 @@ thread_through_loop_header (struct loop *loop, bool may_peel_loop_headers) if (latch->aux) { + if (THREAD_TARGET2 (latch)) + goto fail; tgt_edge = THREAD_TARGET (latch); tgt_bb = tgt_edge->dest; } @@ -840,6 +927,8 @@ thread_through_loop_header (struct loop *loop, bool may_peel_loop_headers) goto fail; } + if (THREAD_TARGET2 (e)) + goto fail; tgt_edge = THREAD_TARGET (e); atgt_bb = tgt_edge->dest; if (!tgt_bb) @@ -967,13 +1056,14 @@ mark_threaded_blocks (bitmap threaded_blocks) edge e; edge_iterator ei; - for (i = 0; i < VEC_length (edge, threaded_edges); i += 2) + for (i = 0; i < VEC_length (edge, threaded_edges); i += 3) { edge e = VEC_index (edge, threaded_edges, i); - edge *x = (edge *) XNEWVEC (edge, 1); + edge *x = (edge *) XNEWVEC (edge, 2); e->aux = x; THREAD_TARGET (e) = VEC_index (edge, threaded_edges, i + 1); + THREAD_TARGET2 (e) = VEC_index (edge, threaded_edges, i + 2); bitmap_set_bit (tmp, e->dest->index); } @@ -1085,7 +1175,7 @@ thread_through_all_blocks (bool may_peel_loop_headers) after fixing the SSA graph. */ void -register_jump_thread (edge e, edge e2) +register_jump_thread (edge e, edge e2, edge e3) { /* This can occur if we're jumping to a constant address or or something similar. Just get out now. */ @@ -1102,4 +1192,5 @@ register_jump_thread (edge e, edge e2) VEC_safe_push (edge, heap, threaded_edges, e); VEC_safe_push (edge, heap, threaded_edges, e2); + VEC_safe_push (edge, heap, threaded_edges, e3); } diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c index 30aa4c7755d..6f603ffc895 100644 --- a/gcc/tree-ssa-uncprop.c +++ b/gcc/tree-ssa-uncprop.c @@ -596,7 +596,6 @@ struct gimple_opt_pass pass_uncprop = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + TODO_verify_ssa /* todo_flags_finish */ } }; - diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index f0bbf3b9823..e4d931f862a 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -2277,7 +2277,6 @@ struct gimple_opt_pass pass_update_address_taken = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_update_address_taken - | TODO_dump_func /* todo_flags_finish */ + TODO_update_address_taken /* todo_flags_finish */ } }; diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index 06cdbee2c60..42eb9243252 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -366,6 +366,6 @@ struct gimple_opt_pass pass_release_ssa_names = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c index 46fc339a55a..3e890163d01 100644 --- a/gcc/tree-stdarg.c +++ b/gcc/tree-stdarg.c @@ -963,6 +963,6 @@ struct gimple_opt_pass pass_stdarg = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + 0 /* todo_flags_finish */ } }; diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index c7a6f817ea5..4fb3e8a6971 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -1028,7 +1028,7 @@ struct gimple_opt_pass pass_convert_switch = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_update_ssa | TODO_dump_func + TODO_update_ssa | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ } }; diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index 6a2308028bb..87fc566ddee 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -1,5 +1,5 @@ /* Tail call optimization on trees. - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "dbgcnt.h" #include "target.h" +#include "common/common-target.h" /* The file implements the tail recursion elimination. It is also used to analyze the tail calls in general, passing the results to the rtl level @@ -152,7 +153,7 @@ suitable_for_tail_call_opt_p (void) /* If we are using sjlj exceptions, we may need to add a call to _Unwind_SjLj_Unregister at exit of the function. Which means that we cannot do any sibcall transformations. */ - if (targetm.except_unwind_info (&global_options) == UI_SJLJ + if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ && current_function_has_exception_handlers ()) return false; @@ -1092,7 +1093,7 @@ struct gimple_opt_pass pass_tail_recursion = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + TODO_verify_ssa /* todo_flags_finish */ } }; @@ -1111,6 +1112,6 @@ struct gimple_opt_pass pass_tail_calls = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + TODO_verify_ssa /* todo_flags_finish */ } }; diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 5023710f1e5..c98eb13b225 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -1248,7 +1248,9 @@ vect_peeling_hash_get_most_frequent (void **slot, void *data) vect_peel_info elem = (vect_peel_info) *slot; vect_peel_extended_info max = (vect_peel_extended_info) data; - if (elem->count > max->peel_info.count) + if (elem->count > max->peel_info.count + || (elem->count == max->peel_info.count + && max->peel_info.npeel > elem->npeel)) { max->peel_info.npeel = elem->npeel; max->peel_info.count = elem->count; diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c index 41e21b4dd05..afcd63de88e 100644 --- a/gcc/tree-vect-generic.c +++ b/gcc/tree-vect-generic.c @@ -658,7 +658,7 @@ struct gimple_opt_pass pass_lower_vector = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_update_ssa /* todo_flags_finish */ + TODO_update_ssa /* todo_flags_finish */ | TODO_verify_ssa | TODO_verify_stmts | TODO_verify_flow } @@ -679,7 +679,7 @@ struct gimple_opt_pass pass_lower_vector_ssa = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_update_ssa /* todo_flags_finish */ + TODO_update_ssa /* todo_flags_finish */ | TODO_verify_ssa | TODO_verify_stmts | TODO_verify_flow } diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index 89b45745364..a120fb153aa 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -1105,35 +1105,6 @@ set_prologue_iterations (basic_block bb_before_first_loop, first_niters = PHI_RESULT (newphi); } - -/* Remove dead assignments from loop NEW_LOOP. */ - -static void -remove_dead_stmts_from_loop (struct loop *new_loop) -{ - basic_block *bbs = get_loop_body (new_loop); - unsigned i; - for (i = 0; i < new_loop->num_nodes; ++i) - { - gimple_stmt_iterator gsi; - for (gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi);) - { - gimple stmt = gsi_stmt (gsi); - if (is_gimple_assign (stmt) - && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME - && has_zero_uses (gimple_assign_lhs (stmt))) - { - gsi_remove (&gsi, true); - release_defs (stmt); - } - else - gsi_next (&gsi); - } - } - free (bbs); -} - - /* Function slpeel_tree_peel_loop_to_edge. Peel the first (last) iterations of LOOP into a new prolog (epilog) loop @@ -1445,13 +1416,6 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, BITMAP_FREE (definitions); delete_update_ssa (); - /* Remove all pattern statements from the loop copy. They will confuse - the expander if DCE is disabled. - ??? The pattern recognizer should be split into an analysis and - a transformation phase that is then run only on the loop that is - going to be transformed. */ - remove_dead_stmts_from_loop (new_loop); - adjust_vec_debug_stmts (); return new_loop; diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 8ff5ad04b33..27305f3db66 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -244,7 +244,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) { tree vf_vectype; - gimple stmt = gsi_stmt (si); + gimple stmt = gsi_stmt (si), pattern_stmt; stmt_info = vinfo_for_stmt (stmt); if (vect_print_dump_info (REPORT_DETAILS)) @@ -258,20 +258,26 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) /* Skip stmts which do not need to be vectorized. */ if (!STMT_VINFO_RELEVANT_P (stmt_info) && !STMT_VINFO_LIVE_P (stmt_info)) - { - if (is_pattern_stmt_p (stmt_info)) + { + if (STMT_VINFO_IN_PATTERN_P (stmt_info) + && (pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info)) + && (STMT_VINFO_RELEVANT_P (vinfo_for_stmt (pattern_stmt)) + || STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_stmt)))) { - /* We are not going to vectorize this pattern statement, - therefore, remove it. */ - gimple_stmt_iterator tmp_gsi = gsi_for_stmt (stmt); - STMT_VINFO_RELATED_STMT (stmt_info) = NULL; - gsi_remove (&tmp_gsi, true); - free_stmt_vec_info (stmt); + stmt = pattern_stmt; + stmt_info = vinfo_for_stmt (pattern_stmt); + if (vect_print_dump_info (REPORT_DETAILS)) + { + fprintf (vect_dump, "==> examining pattern statement: "); + print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); + } + } + else + { + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "skip."); + continue; } - - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "skip."); - continue; } if (gimple_get_lhs (stmt) == NULL_TREE) @@ -305,9 +311,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) } else { - gcc_assert (!STMT_VINFO_DATA_REF (stmt_info) - && !is_pattern_stmt_p (stmt_info)); - + gcc_assert (!STMT_VINFO_DATA_REF (stmt_info)); scalar_type = TREE_TYPE (gimple_get_lhs (stmt)); if (vect_print_dump_info (REPORT_DETAILS)) { @@ -828,25 +832,17 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts) if (stmt_info) { - /* Check if this is a "pattern stmt" (introduced by the - vectorizer during the pattern recognition pass). */ - bool remove_stmt_p = false; - gimple orig_stmt = STMT_VINFO_RELATED_STMT (stmt_info); - if (orig_stmt) - { - stmt_vec_info orig_stmt_info = vinfo_for_stmt (orig_stmt); - if (orig_stmt_info - && STMT_VINFO_IN_PATTERN_P (orig_stmt_info)) - remove_stmt_p = true; - } + /* Check if this statement has a related "pattern stmt" + (introduced by the vectorizer during the pattern recognition + pass). Free pattern's stmt_vec_info. */ + if (STMT_VINFO_IN_PATTERN_P (stmt_info) + && vinfo_for_stmt (STMT_VINFO_RELATED_STMT (stmt_info))) + free_stmt_vec_info (STMT_VINFO_RELATED_STMT (stmt_info)); /* Free stmt_vec_info. */ free_stmt_vec_info (stmt); - - /* Remove dead "pattern stmts". */ - if (remove_stmt_p) - gsi_remove (&si, true); } + gsi_next (&si); } } @@ -1710,12 +1706,12 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt) struct loop *loop = (gimple_bb (phi))->loop_father; struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info); enum tree_code code; - gimple current_stmt = NULL, use_stmt = NULL, first, next_stmt; + gimple current_stmt = NULL, loop_use_stmt = NULL, first, next_stmt; stmt_vec_info use_stmt_info, current_stmt_info; tree lhs; imm_use_iterator imm_iter; use_operand_p use_p; - int nloop_uses, size = 0, nuses; + int nloop_uses, size = 0; bool found = false; if (loop != vect_loop) @@ -1726,66 +1722,68 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt) while (1) { nloop_uses = 0; - nuses = 0; FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) { - use_stmt = USE_STMT (use_p); - nuses++; + gimple use_stmt = USE_STMT (use_p); if (is_gimple_debug (use_stmt)) continue; + use_stmt = USE_STMT (use_p); + /* Check if we got back to the reduction phi. */ - if (gimple_code (use_stmt) == GIMPLE_PHI - && use_stmt == phi) + if (use_stmt == phi) { + loop_use_stmt = use_stmt; found = true; break; } if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)) && vinfo_for_stmt (use_stmt) - && !is_pattern_stmt_p (vinfo_for_stmt (use_stmt)) - && use_stmt != first_stmt) - nloop_uses++; + && !STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (use_stmt))) + { + loop_use_stmt = use_stmt; + nloop_uses++; + } if (nloop_uses > 1) return false; } - /* We reached a statement with no uses. */ - if (nuses == 0) - return false; - if (found) break; + /* We reached a statement with no loop uses. */ + if (nloop_uses == 0) + return false; + /* This is a loop exit phi, and we haven't reached the reduction phi. */ - if (gimple_code (use_stmt) == GIMPLE_PHI) + if (gimple_code (loop_use_stmt) == GIMPLE_PHI) return false; - if (!is_gimple_assign (use_stmt) - || code != gimple_assign_rhs_code (use_stmt) - || !flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))) + if (!is_gimple_assign (loop_use_stmt) + || code != gimple_assign_rhs_code (loop_use_stmt) + || !flow_bb_inside_loop_p (loop, gimple_bb (loop_use_stmt))) return false; /* Insert USE_STMT into reduction chain. */ - use_stmt_info = vinfo_for_stmt (use_stmt); + use_stmt_info = vinfo_for_stmt (loop_use_stmt); if (current_stmt) { current_stmt_info = vinfo_for_stmt (current_stmt); - GROUP_NEXT_ELEMENT (current_stmt_info) = use_stmt; + GROUP_NEXT_ELEMENT (current_stmt_info) = loop_use_stmt; GROUP_FIRST_ELEMENT (use_stmt_info) = GROUP_FIRST_ELEMENT (current_stmt_info); } else - GROUP_FIRST_ELEMENT (use_stmt_info) = use_stmt; + GROUP_FIRST_ELEMENT (use_stmt_info) = loop_use_stmt; - lhs = gimple_assign_lhs (use_stmt); - current_stmt = use_stmt; + lhs = gimple_assign_lhs (loop_use_stmt); + current_stmt = loop_use_stmt; size++; } - if (!found || use_stmt != phi || size < 2) + if (!found || loop_use_stmt != phi || size < 2) return false; /* Swap the operands, if needed, to make the reduction operand be the second @@ -1794,75 +1792,70 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt) next_stmt = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt)); while (next_stmt) { - if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS) + if (gimple_assign_rhs2 (next_stmt) == lhs) { - if (gimple_assign_rhs2 (next_stmt) == lhs) + tree op = gimple_assign_rhs1 (next_stmt); + gimple def_stmt = NULL; + + if (TREE_CODE (op) == SSA_NAME) + def_stmt = SSA_NAME_DEF_STMT (op); + + /* Check that the other def is either defined in the loop + ("vect_internal_def"), or it's an induction (defined by a + loop-header phi-node). */ + if (def_stmt + && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) + && (is_gimple_assign (def_stmt) + || is_gimple_call (def_stmt) + || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) + == vect_induction_def + || (gimple_code (def_stmt) == GIMPLE_PHI + && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) + == vect_internal_def + && !is_loop_header_bb_p (gimple_bb (def_stmt))))) { - tree op = gimple_assign_rhs1 (next_stmt); - gimple def_stmt = NULL; - - if (TREE_CODE (op) == SSA_NAME) - def_stmt = SSA_NAME_DEF_STMT (op); - - /* Check that the other def is either defined in the loop - ("vect_internal_def"), or it's an induction (defined by a - loop-header phi-node). */ - if (code == COND_EXPR - || (def_stmt - && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) - && (is_gimple_assign (def_stmt) - || is_gimple_call (def_stmt) - || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) + lhs = gimple_assign_lhs (next_stmt); + next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt)); + continue; + } + + return false; + } + else + { + tree op = gimple_assign_rhs2 (next_stmt); + gimple def_stmt = NULL; + + if (TREE_CODE (op) == SSA_NAME) + def_stmt = SSA_NAME_DEF_STMT (op); + + /* Check that the other def is either defined in the loop + ("vect_internal_def"), or it's an induction (defined by a + loop-header phi-node). */ + if (def_stmt + && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) + && (is_gimple_assign (def_stmt) + || is_gimple_call (def_stmt) + || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) == vect_induction_def - || (gimple_code (def_stmt) == GIMPLE_PHI - && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) + || (gimple_code (def_stmt) == GIMPLE_PHI + && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) == vect_internal_def - && !is_loop_header_bb_p (gimple_bb (def_stmt)))))) + && !is_loop_header_bb_p (gimple_bb (def_stmt))))) + { + if (vect_print_dump_info (REPORT_DETAILS)) { - lhs = gimple_assign_lhs (next_stmt); - next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt)); - continue; + fprintf (vect_dump, "swapping oprnds: "); + print_gimple_stmt (vect_dump, next_stmt, 0, TDF_SLIM); } - return false; + swap_tree_operands (next_stmt, + gimple_assign_rhs1_ptr (next_stmt), + gimple_assign_rhs2_ptr (next_stmt)); + mark_symbols_for_renaming (next_stmt); } else - { - tree op = gimple_assign_rhs2 (next_stmt); - gimple def_stmt = NULL; - - if (TREE_CODE (op) == SSA_NAME) - def_stmt = SSA_NAME_DEF_STMT (op); - - /* Check that the other def is either defined in the loop - ("vect_internal_def"), or it's an induction (defined by a - loop-header phi-node). */ - if (code == COND_EXPR - || (def_stmt - && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) - && (is_gimple_assign (def_stmt) - || is_gimple_call (def_stmt) - || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) - == vect_induction_def - || (gimple_code (def_stmt) == GIMPLE_PHI - && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) - == vect_internal_def - && !is_loop_header_bb_p (gimple_bb (def_stmt)))))) - { - if (vect_print_dump_info (REPORT_DETAILS)) - { - fprintf (vect_dump, "swapping oprnds: "); - print_gimple_stmt (vect_dump, next_stmt, 0, TDF_SLIM); - } - - swap_tree_operands (next_stmt, - gimple_assign_rhs1_ptr (next_stmt), - gimple_assign_rhs2_ptr (next_stmt)); - mark_symbols_for_renaming (next_stmt); - } - else - return false; - } + return false; } lhs = gimple_assign_lhs (next_stmt); @@ -2273,7 +2266,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi, } /* Try to find SLP reduction chain. */ - if (vect_is_slp_reduction (loop_info, phi, def_stmt)) + if (check_reduction && vect_is_slp_reduction (loop_info, phi, def_stmt)) { if (vect_print_dump_info (REPORT_DETAILS)) report_vect_op (def_stmt, "reduction: detected reduction chain: "); @@ -5134,7 +5127,7 @@ vect_transform_loop (loop_vec_info loop_vinfo) for (si = gsi_start_bb (bb); !gsi_end_p (si);) { - gimple stmt = gsi_stmt (si); + gimple stmt = gsi_stmt (si), pattern_stmt; bool is_store; if (vect_print_dump_info (REPORT_DETAILS)) @@ -5159,14 +5152,25 @@ vect_transform_loop (loop_vec_info loop_vinfo) if (!STMT_VINFO_RELEVANT_P (stmt_info) && !STMT_VINFO_LIVE_P (stmt_info)) - { - gsi_next (&si); - continue; + { + if (STMT_VINFO_IN_PATTERN_P (stmt_info) + && (pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info)) + && (STMT_VINFO_RELEVANT_P (vinfo_for_stmt (pattern_stmt)) + || STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_stmt)))) + { + stmt = pattern_stmt; + stmt_info = vinfo_for_stmt (stmt); + } + else + { + gsi_next (&si); + continue; + } } gcc_assert (STMT_VINFO_VECTYPE (stmt_info)); - nunits = - (unsigned int) TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info)); + nunits = (unsigned int) TYPE_VECTOR_SUBPARTS ( + STMT_VINFO_VECTYPE (stmt_info)); if (!STMT_SLP_TYPE (stmt_info) && nunits != (unsigned int) vectorization_factor && vect_print_dump_info (REPORT_DETAILS)) diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index f0add8c6074..ce941425e0c 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -39,10 +39,13 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-core.h" /* Pattern recognition functions */ -static gimple vect_recog_widen_sum_pattern (gimple *, tree *, tree *); -static gimple vect_recog_widen_mult_pattern (gimple *, tree *, tree *); -static gimple vect_recog_dot_prod_pattern (gimple *, tree *, tree *); -static gimple vect_recog_pow_pattern (gimple *, tree *, tree *); +static gimple vect_recog_widen_sum_pattern (VEC (gimple, heap) **, tree *, + tree *); +static gimple vect_recog_widen_mult_pattern (VEC (gimple, heap) **, tree *, + tree *); +static gimple vect_recog_dot_prod_pattern (VEC (gimple, heap) **, tree *, + tree *); +static gimple vect_recog_pow_pattern (VEC (gimple, heap) **, tree *, tree *); static vect_recog_func_ptr vect_vect_recog_func_ptrs[NUM_PATTERNS] = { vect_recog_widen_mult_pattern, vect_recog_widen_sum_pattern, @@ -142,9 +145,9 @@ vect_recog_temp_ssa_var (tree type, gimple stmt) Input: - * LAST_STMT: A stmt from which the pattern search begins. In the example, - when this function is called with S7, the pattern {S3,S4,S5,S6,S7} will be - detected. + * STMTS: Contains a stmt from which the pattern search begins. In the + example, when this function is called with S7, the pattern {S3,S4,S5,S6,S7} + will be detected. Output: @@ -165,12 +168,13 @@ vect_recog_temp_ssa_var (tree type, gimple stmt) inner-loop nested in an outer-loop that us being vectorized). */ static gimple -vect_recog_dot_prod_pattern (gimple *last_stmt, tree *type_in, tree *type_out) +vect_recog_dot_prod_pattern (VEC (gimple, heap) **stmts, tree *type_in, + tree *type_out) { - gimple stmt; + gimple stmt, last_stmt = VEC_index (gimple, *stmts, 0); tree oprnd0, oprnd1; tree oprnd00, oprnd01; - stmt_vec_info stmt_vinfo = vinfo_for_stmt (*last_stmt); + stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt); tree type, half_type; gimple pattern_stmt; tree prod_type; @@ -178,10 +182,10 @@ vect_recog_dot_prod_pattern (gimple *last_stmt, tree *type_in, tree *type_out) struct loop *loop = LOOP_VINFO_LOOP (loop_info); tree var; - if (!is_gimple_assign (*last_stmt)) + if (!is_gimple_assign (last_stmt)) return NULL; - type = gimple_expr_type (*last_stmt); + type = gimple_expr_type (last_stmt); /* Look for the following pattern DX = (TYPE1) X; @@ -207,7 +211,7 @@ vect_recog_dot_prod_pattern (gimple *last_stmt, tree *type_in, tree *type_out) /* Starting from LAST_STMT, follow the defs of its uses in search of the above pattern. */ - if (gimple_assign_rhs_code (*last_stmt) != PLUS_EXPR) + if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR) return NULL; if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo)) @@ -228,12 +232,12 @@ vect_recog_dot_prod_pattern (gimple *last_stmt, tree *type_in, tree *type_out) if (STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_reduction_def) return NULL; - oprnd0 = gimple_assign_rhs1 (*last_stmt); - oprnd1 = gimple_assign_rhs2 (*last_stmt); + oprnd0 = gimple_assign_rhs1 (last_stmt); + oprnd1 = gimple_assign_rhs2 (last_stmt); if (!types_compatible_p (TREE_TYPE (oprnd0), type) || !types_compatible_p (TREE_TYPE (oprnd1), type)) return NULL; - stmt = *last_stmt; + stmt = last_stmt; if (widened_name_p (oprnd0, stmt, &half_type, &def_stmt, true)) { @@ -244,7 +248,7 @@ vect_recog_dot_prod_pattern (gimple *last_stmt, tree *type_in, tree *type_out) half_type = type; } - /* So far so good. Since *last_stmt was detected as a (summation) reduction, + /* So far so good. Since last_stmt was detected as a (summation) reduction, we know that oprnd1 is the reduction variable (defined by a loop-header phi), and oprnd0 is an ssa-name defined by a stmt in the loop body. Left to check that oprnd0 is defined by a (widen_)mult_expr */ @@ -319,11 +323,80 @@ vect_recog_dot_prod_pattern (gimple *last_stmt, tree *type_in, tree *type_out) /* We don't allow changing the order of the computation in the inner-loop when doing outer-loop vectorization. */ - gcc_assert (!nested_in_vect_loop_p (loop, *last_stmt)); + gcc_assert (!nested_in_vect_loop_p (loop, last_stmt)); return pattern_stmt; } + +/* Handle two cases of multiplication by a constant. The first one is when + the constant, CONST_OPRND, fits the type (HALF_TYPE) of the second + operand (OPRND). In that case, we can peform widen-mult from HALF_TYPE to + TYPE. + + Otherwise, if the type of the result (TYPE) is at least 4 times bigger than + HALF_TYPE, and CONST_OPRND fits an intermediate type (2 times smaller than + TYPE), we can perform widen-mult from the intermediate type to TYPE and + replace a_T = (TYPE) a_t; with a_it - (interm_type) a_t; */ + +static bool +vect_handle_widen_mult_by_const (tree const_oprnd, tree *oprnd, + VEC (gimple, heap) **stmts, tree type, + tree *half_type, gimple def_stmt) +{ + tree new_type, new_oprnd, tmp; + gimple new_stmt; + + if (int_fits_type_p (const_oprnd, *half_type)) + { + /* CONST_OPRND is a constant of HALF_TYPE. */ + *oprnd = gimple_assign_rhs1 (def_stmt); + return true; + } + + if (TYPE_PRECISION (type) < (TYPE_PRECISION (*half_type) * 4) + || !vinfo_for_stmt (def_stmt)) + return false; + + /* TYPE is 4 times bigger than HALF_TYPE, try widen-mult for + a type 2 times bigger than HALF_TYPE. */ + new_type = build_nonstandard_integer_type (TYPE_PRECISION (type) / 2, + TYPE_UNSIGNED (type)); + if (!int_fits_type_p (const_oprnd, new_type)) + return false; + + /* Use NEW_TYPE for widen_mult. */ + if (STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt))) + { + new_stmt = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)); + /* Check if the already created pattern stmt is what we need. */ + if (!is_gimple_assign (new_stmt) + || gimple_assign_rhs_code (new_stmt) != NOP_EXPR + || TREE_TYPE (gimple_assign_lhs (new_stmt)) != new_type) + return false; + + *oprnd = gimple_assign_lhs (new_stmt); + } + else + { + /* Create a_T = (NEW_TYPE) a_t; */ + *oprnd = gimple_assign_rhs1 (def_stmt); + tmp = create_tmp_var (new_type, NULL); + add_referenced_var (tmp); + new_oprnd = make_ssa_name (tmp, NULL); + new_stmt = gimple_build_assign_with_ops (NOP_EXPR, new_oprnd, *oprnd, + NULL_TREE); + SSA_NAME_DEF_STMT (new_oprnd) = new_stmt; + STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)) = new_stmt; + VEC_safe_push (gimple, heap, *stmts, def_stmt); + *oprnd = new_oprnd; + } + + *half_type = new_type; + return true; +} + + /* Function vect_recog_widen_mult_pattern Try to find the following pattern: @@ -361,11 +434,30 @@ vect_recog_dot_prod_pattern (gimple *last_stmt, tree *type_in, tree *type_out) S3 a_T = (TYPE) a_t; S5 prod_T = a_T * CONST; - Input: + A special case of multiplication by constants is when 'TYPE' is 4 times + bigger than 'type', but CONST fits an intermediate type 2 times smaller + than 'TYPE'. In that case we create an additional pattern stmt for S3 + to create a variable of the intermediate type, and perform widen-mult + on the intermediate type as well: + + type a_t; + interm_type a_it; + TYPE a_T, prod_T, prod_T'; + + S1 a_t = ; + S3 a_T = (TYPE) a_t; + '--> a_it = (interm_type) a_t; + S5 prod_T = a_T * CONST; + '--> prod_T' = a_it w* CONST; + + Input/Output: - * LAST_STMT: A stmt from which the pattern search begins. In the example, - when this function is called with S5, the pattern {S3,S4,S5,(S6)} is - detected. + * STMTS: Contains a stmt from which the pattern search begins. In the + example, when this function is called with S5, the pattern {S3,S4,S5,(S6)} + is detected. In case of unsigned widen-mult, the original stmt (S5) is + replaced with S6 in STMTS. In case of multiplication by a constant + of an intermediate type (the last case above), STMTS also contains S3 + (inserted before S5). Output: @@ -379,10 +471,10 @@ vect_recog_dot_prod_pattern (gimple *last_stmt, tree *type_in, tree *type_out) */ static gimple -vect_recog_widen_mult_pattern (gimple *last_stmt, - tree *type_in, - tree *type_out) +vect_recog_widen_mult_pattern (VEC (gimple, heap) **stmts, + tree *type_in, tree *type_out) { + gimple last_stmt = VEC_pop (gimple, *stmts); gimple def_stmt0, def_stmt1; tree oprnd0, oprnd1; tree type, half_type0, half_type1; @@ -395,27 +487,27 @@ vect_recog_widen_mult_pattern (gimple *last_stmt, VEC (tree, heap) *dummy_vec; bool op0_ok, op1_ok; - if (!is_gimple_assign (*last_stmt)) + if (!is_gimple_assign (last_stmt)) return NULL; - type = gimple_expr_type (*last_stmt); + type = gimple_expr_type (last_stmt); /* Starting from LAST_STMT, follow the defs of its uses in search of the above pattern. */ - if (gimple_assign_rhs_code (*last_stmt) != MULT_EXPR) + if (gimple_assign_rhs_code (last_stmt) != MULT_EXPR) return NULL; - oprnd0 = gimple_assign_rhs1 (*last_stmt); - oprnd1 = gimple_assign_rhs2 (*last_stmt); + oprnd0 = gimple_assign_rhs1 (last_stmt); + oprnd1 = gimple_assign_rhs2 (last_stmt); if (!types_compatible_p (TREE_TYPE (oprnd0), type) || !types_compatible_p (TREE_TYPE (oprnd1), type)) return NULL; /* Check argument 0. */ - op0_ok = widened_name_p (oprnd0, *last_stmt, &half_type0, &def_stmt0, false); + op0_ok = widened_name_p (oprnd0, last_stmt, &half_type0, &def_stmt0, false); /* Check argument 1. */ - op1_ok = widened_name_p (oprnd1, *last_stmt, &half_type1, &def_stmt1, false); + op1_ok = widened_name_p (oprnd1, last_stmt, &half_type1, &def_stmt1, false); /* In case of multiplication by a constant one of the operands may not match the pattern, but not both. */ @@ -429,29 +521,21 @@ vect_recog_widen_mult_pattern (gimple *last_stmt, } else if (!op0_ok) { - if (CONSTANT_CLASS_P (oprnd0) + if (TREE_CODE (oprnd0) == INTEGER_CST && TREE_CODE (half_type1) == INTEGER_TYPE - && tree_int_cst_lt (oprnd0, TYPE_MAXVAL (half_type1)) - && tree_int_cst_lt (TYPE_MINVAL (half_type1), oprnd0)) - { - /* OPRND0 is a constant of HALF_TYPE1. */ - half_type0 = half_type1; - oprnd1 = gimple_assign_rhs1 (def_stmt1); - } + && vect_handle_widen_mult_by_const (oprnd0, &oprnd1, stmts, type, + &half_type1, def_stmt1)) + half_type0 = half_type1; else return NULL; } else if (!op1_ok) { - if (CONSTANT_CLASS_P (oprnd1) + if (TREE_CODE (oprnd1) == INTEGER_CST && TREE_CODE (half_type0) == INTEGER_TYPE - && tree_int_cst_lt (oprnd1, TYPE_MAXVAL (half_type0)) - && tree_int_cst_lt (TYPE_MINVAL (half_type0), oprnd1)) - { - /* OPRND1 is a constant of HALF_TYPE0. */ - half_type1 = half_type0; - oprnd0 = gimple_assign_rhs1 (def_stmt0); - } + && vect_handle_widen_mult_by_const (oprnd1, &oprnd0, stmts, type, + &half_type0, def_stmt0)) + half_type1 = half_type0; else return NULL; } @@ -461,7 +545,7 @@ vect_recog_widen_mult_pattern (gimple *last_stmt, Use unsigned TYPE as the type for WIDEN_MULT_EXPR. */ if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (half_type0)) { - tree lhs = gimple_assign_lhs (*last_stmt), use_lhs; + tree lhs = gimple_assign_lhs (last_stmt), use_lhs; imm_use_iterator imm_iter; use_operand_p use_p; int nuses = 0; @@ -489,7 +573,7 @@ vect_recog_widen_mult_pattern (gimple *last_stmt, return NULL; type = use_type; - *last_stmt = use_stmt; + last_stmt = use_stmt; } if (!types_compatible_p (half_type0, half_type1)) @@ -504,7 +588,7 @@ vect_recog_widen_mult_pattern (gimple *last_stmt, vectype_out = get_vectype_for_scalar_type (type); if (!vectype || !vectype_out - || !supportable_widening_operation (WIDEN_MULT_EXPR, *last_stmt, + || !supportable_widening_operation (WIDEN_MULT_EXPR, last_stmt, vectype_out, vectype, &dummy, &dummy, &dummy_code, &dummy_code, &dummy_int, &dummy_vec)) @@ -522,6 +606,7 @@ vect_recog_widen_mult_pattern (gimple *last_stmt, if (vect_print_dump_info (REPORT_DETAILS)) print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM); + VEC_safe_push (gimple, heap, *stmts, last_stmt); return pattern_stmt; } @@ -553,16 +638,18 @@ vect_recog_widen_mult_pattern (gimple *last_stmt, */ static gimple -vect_recog_pow_pattern (gimple *last_stmt, tree *type_in, tree *type_out) +vect_recog_pow_pattern (VEC (gimple, heap) **stmts, tree *type_in, + tree *type_out) { + gimple last_stmt = VEC_index (gimple, *stmts, 0); tree fn, base, exp = NULL; gimple stmt; tree var; - if (!is_gimple_call (*last_stmt) || gimple_call_lhs (*last_stmt) == NULL) + if (!is_gimple_call (last_stmt) || gimple_call_lhs (last_stmt) == NULL) return NULL; - fn = gimple_call_fndecl (*last_stmt); + fn = gimple_call_fndecl (last_stmt); if (fn == NULL_TREE || DECL_BUILT_IN_CLASS (fn) != BUILT_IN_NORMAL) return NULL; @@ -572,8 +659,8 @@ vect_recog_pow_pattern (gimple *last_stmt, tree *type_in, tree *type_out) case BUILT_IN_POWI: case BUILT_IN_POWF: case BUILT_IN_POW: - base = gimple_call_arg (*last_stmt, 0); - exp = gimple_call_arg (*last_stmt, 1); + base = gimple_call_arg (last_stmt, 0); + exp = gimple_call_arg (last_stmt, 1); if (TREE_CODE (exp) != REAL_CST && TREE_CODE (exp) != INTEGER_CST) return NULL; @@ -665,21 +752,22 @@ vect_recog_pow_pattern (gimple *last_stmt, tree *type_in, tree *type_out) inner-loop nested in an outer-loop that us being vectorized). */ static gimple -vect_recog_widen_sum_pattern (gimple *last_stmt, tree *type_in, tree *type_out) +vect_recog_widen_sum_pattern (VEC (gimple, heap) **stmts, tree *type_in, + tree *type_out) { - gimple stmt; + gimple stmt, last_stmt = VEC_index (gimple, *stmts, 0); tree oprnd0, oprnd1; - stmt_vec_info stmt_vinfo = vinfo_for_stmt (*last_stmt); + stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt); tree type, half_type; gimple pattern_stmt; loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo); struct loop *loop = LOOP_VINFO_LOOP (loop_info); tree var; - if (!is_gimple_assign (*last_stmt)) + if (!is_gimple_assign (last_stmt)) return NULL; - type = gimple_expr_type (*last_stmt); + type = gimple_expr_type (last_stmt); /* Look for the following pattern DX = (TYPE) X; @@ -691,25 +779,25 @@ vect_recog_widen_sum_pattern (gimple *last_stmt, tree *type_in, tree *type_out) /* Starting from LAST_STMT, follow the defs of its uses in search of the above pattern. */ - if (gimple_assign_rhs_code (*last_stmt) != PLUS_EXPR) + if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR) return NULL; if (STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_reduction_def) return NULL; - oprnd0 = gimple_assign_rhs1 (*last_stmt); - oprnd1 = gimple_assign_rhs2 (*last_stmt); + oprnd0 = gimple_assign_rhs1 (last_stmt); + oprnd1 = gimple_assign_rhs2 (last_stmt); if (!types_compatible_p (TREE_TYPE (oprnd0), type) || !types_compatible_p (TREE_TYPE (oprnd1), type)) return NULL; - /* So far so good. Since *last_stmt was detected as a (summation) reduction, + /* So far so good. Since last_stmt was detected as a (summation) reduction, we know that oprnd1 is the reduction variable (defined by a loop-header phi), and oprnd0 is an ssa-name defined by a stmt in the loop body. Left to check that oprnd0 is defined by a cast from type 'type' to type 'TYPE'. */ - if (!widened_name_p (oprnd0, *last_stmt, &half_type, &stmt, true)) + if (!widened_name_p (oprnd0, last_stmt, &half_type, &stmt, true)) return NULL; oprnd0 = gimple_assign_rhs1 (stmt); @@ -730,7 +818,7 @@ vect_recog_widen_sum_pattern (gimple *last_stmt, tree *type_in, tree *type_out) /* We don't allow changing the order of the computation in the inner-loop when doing outer-loop vectorization. */ - gcc_assert (!nested_in_vect_loop_p (loop, *last_stmt)); + gcc_assert (!nested_in_vect_loop_p (loop, last_stmt)); return pattern_stmt; } @@ -760,7 +848,7 @@ vect_recog_widen_sum_pattern (gimple *last_stmt, tree *type_in, tree *type_out) static void vect_pattern_recog_1 ( - gimple (* vect_recog_func) (gimple *, tree *, tree *), + gimple (* vect_recog_func) (VEC (gimple, heap) **, tree *, tree *), gimple_stmt_iterator si) { gimple stmt = gsi_stmt (si), pattern_stmt; @@ -772,12 +860,14 @@ vect_pattern_recog_1 ( enum tree_code code; int i; gimple next; + VEC (gimple, heap) *stmts_to_replace = VEC_alloc (gimple, heap, 1); - pattern_stmt = (* vect_recog_func) (&stmt, &type_in, &type_out); + VEC_quick_push (gimple, stmts_to_replace, stmt); + pattern_stmt = (* vect_recog_func) (&stmts_to_replace, &type_in, &type_out); if (!pattern_stmt) return; - si = gsi_for_stmt (stmt); + stmt = VEC_last (gimple, stmts_to_replace); stmt_info = vinfo_for_stmt (stmt); loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); @@ -831,9 +921,9 @@ vect_pattern_recog_1 ( } /* Mark the stmts that are involved in the pattern. */ - gsi_insert_before (&si, pattern_stmt, GSI_SAME_STMT); set_vinfo_for_stmt (pattern_stmt, new_stmt_vec_info (pattern_stmt, loop_vinfo, NULL)); + gimple_set_bb (pattern_stmt, gimple_bb (stmt)); pattern_stmt_info = vinfo_for_stmt (pattern_stmt); STMT_VINFO_RELATED_STMT (pattern_stmt_info) = stmt; @@ -847,6 +937,35 @@ vect_pattern_recog_1 ( FOR_EACH_VEC_ELT (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo), i, next) if (next == stmt) VEC_ordered_remove (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo), i); + + /* In case of widen-mult by a constant, it is possible that an additional + pattern stmt is created and inserted in STMTS_TO_REPLACE. We create a + stmt_info for it, and mark the relevant statements. */ + for (i = 0; VEC_iterate (gimple, stmts_to_replace, i, stmt) + && (unsigned) i < (VEC_length (gimple, stmts_to_replace) - 1); + i++) + { + stmt_info = vinfo_for_stmt (stmt); + pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info); + if (vect_print_dump_info (REPORT_DETAILS)) + { + fprintf (vect_dump, "additional pattern stmt: "); + print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM); + } + + set_vinfo_for_stmt (pattern_stmt, + new_stmt_vec_info (pattern_stmt, loop_vinfo, NULL)); + gimple_set_bb (pattern_stmt, gimple_bb (stmt)); + pattern_stmt_info = vinfo_for_stmt (pattern_stmt); + + STMT_VINFO_RELATED_STMT (pattern_stmt_info) = stmt; + STMT_VINFO_DEF_TYPE (pattern_stmt_info) + = STMT_VINFO_DEF_TYPE (stmt_info); + STMT_VINFO_VECTYPE (pattern_stmt_info) = STMT_VINFO_VECTYPE (stmt_info); + STMT_VINFO_IN_PATTERN_P (stmt_info) = true; + } + + VEC_free (gimple, heap, stmts_to_replace); } @@ -856,8 +975,8 @@ vect_pattern_recog_1 ( LOOP_VINFO - a struct_loop_info of a loop in which we want to look for computation idioms. - Output - for each computation idiom that is detected we insert a new stmt - that provides the same functionality and that can be vectorized. We + Output - for each computation idiom that is detected we create a new stmt + that provides the same functionality and that can be vectorized. We also record some information in the struct_stmt_info of the relevant stmts, as explained below: @@ -872,52 +991,48 @@ vect_pattern_recog_1 ( S5: ... = ..use(a_0).. - - - Say the sequence {S1,S2,S3,S4} was detected as a pattern that can be - represented by a single stmt. We then: - - create a new stmt S6 that will replace the pattern. - - insert the new stmt S6 before the last stmt in the pattern + represented by a single stmt. We then: + - create a new stmt S6 equivalent to the pattern (the stmt is not + inserted into the code) - fill in the STMT_VINFO fields as follows: in_pattern_p related_stmt vec_stmt S1: a_i = .... - - - S2: a_2 = ..use(a_i).. - - - S3: a_1 = ..use(a_2).. - - - - > S6: a_new = .... - S4 - S4: a_0 = ..use(a_1).. true S6 - + '---> S6: a_new = .... - S4 - S5: ... = ..use(a_0).. - - - (the last stmt in the pattern (S4) and the new pattern stmt (S6) point - to each other through the RELATED_STMT field). + to each other through the RELATED_STMT field). S6 will be marked as relevant in vect_mark_stmts_to_be_vectorized instead of S4 because it will replace all its uses. Stmts {S1,S2,S3} will remain irrelevant unless used by stmts other than S4. If vectorization succeeds, vect_transform_stmt will skip over {S1,S2,S3} - (because they are marked as irrelevant). It will vectorize S6, and record + (because they are marked as irrelevant). It will vectorize S6, and record a pointer to the new vector stmt VS6 both from S6 (as usual), and also - from S4. We do that so that when we get to vectorizing stmts that use the + from S4. We do that so that when we get to vectorizing stmts that use the def of S4 (like S5 that uses a_0), we'll know where to take the relevant - vector-def from. S4 will be skipped, and S5 will be vectorized as usual: + vector-def from. S4 will be skipped, and S5 will be vectorized as usual: in_pattern_p related_stmt vec_stmt S1: a_i = .... - - - S2: a_2 = ..use(a_i).. - - - S3: a_1 = ..use(a_2).. - - - > VS6: va_new = .... - - - - S6: a_new = .... - S4 VS6 S4: a_0 = ..use(a_1).. true S6 VS6 + '---> S6: a_new = .... - S4 VS6 > VS5: ... = ..vuse(va_new).. - - - S5: ... = ..use(a_0).. - - - - DCE could then get rid of {S1,S2,S3,S4,S5,S6} (if their defs are not used + DCE could then get rid of {S1,S2,S3,S4,S5} (if their defs are not used elsewhere), and we'll end up with: VS6: va_new = .... - VS5: ... = ..vuse(va_new).. - - If vectorization does not succeed, DCE will clean S6 away (its def is - not used), and we'll end up with the original sequence. -*/ + VS5: ... = ..vuse(va_new).. */ void vect_pattern_recog (loop_vec_info loop_vinfo) @@ -927,7 +1042,7 @@ vect_pattern_recog (loop_vec_info loop_vinfo) unsigned int nbbs = loop->num_nodes; gimple_stmt_iterator si; unsigned int i, j; - gimple (* vect_recog_func_ptr) (gimple *, tree *, tree *); + gimple (* vect_recog_func_ptr) (VEC (gimple, heap) **, tree *, tree *); if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "=== vect_pattern_recog ==="); diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index b060935971e..efedf66e2ec 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -2546,6 +2546,8 @@ vect_schedule_slp_instance (slp_tree node, slp_instance instance, && STMT_VINFO_STRIDED_ACCESS (stmt_info) && !REFERENCE_CLASS_P (gimple_get_lhs (stmt))) si = gsi_for_stmt (SLP_INSTANCE_FIRST_LOAD_STMT (instance)); + else if (is_pattern_stmt_p (stmt_info)) + si = gsi_for_stmt (STMT_VINFO_RELATED_STMT (stmt_info)); else si = gsi_for_stmt (stmt); diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 1b2ed20040d..6a5ba22d42a 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -605,15 +605,49 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) break; } - FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE) - { - tree op = USE_FROM_PTR (use_p); - if (!process_use (stmt, op, loop_vinfo, live_p, relevant, &worklist)) - { - VEC_free (gimple, heap, worklist); - return false; - } - } + if (is_pattern_stmt_p (vinfo_for_stmt (stmt))) + { + /* Pattern statements are not inserted into the code, so + FOR_EACH_PHI_OR_STMT_USE optimizes their operands out, and we + have to scan the RHS or function arguments instead. */ + if (is_gimple_assign (stmt)) + { + for (i = 1; i < gimple_num_ops (stmt); i++) + { + tree op = gimple_op (stmt, i); + if (!process_use (stmt, op, loop_vinfo, live_p, relevant, + &worklist)) + { + VEC_free (gimple, heap, worklist); + return false; + } + } + } + else if (is_gimple_call (stmt)) + { + for (i = 0; i < gimple_call_num_args (stmt); i++) + { + tree arg = gimple_call_arg (stmt, i); + if (!process_use (stmt, arg, loop_vinfo, live_p, relevant, + &worklist)) + { + VEC_free (gimple, heap, worklist); + return false; + } + } + } + } + else + FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE) + { + tree op = USE_FROM_PTR (use_p); + if (!process_use (stmt, op, loop_vinfo, live_p, relevant, + &worklist)) + { + VEC_free (gimple, heap, worklist); + return false; + } + } } /* while worklist */ VEC_free (gimple, heap, worklist); @@ -1406,6 +1440,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt) VEC(tree, heap) *vargs = NULL; enum { NARROW, NONE, WIDEN } modifier; size_t i, nargs; + tree lhs; /* FORNOW: unsupported in basic block SLP. */ gcc_assert (loop_vinfo); @@ -1543,7 +1578,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt) /** Transform. **/ if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "transform operation."); + fprintf (vect_dump, "transform call."); /* Handle def. */ scalar_dest = gimple_call_lhs (stmt); @@ -1662,8 +1697,11 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt) rhs of the statement with something harmless. */ type = TREE_TYPE (scalar_dest); - new_stmt = gimple_build_assign (gimple_call_lhs (stmt), - build_zero_cst (type)); + if (is_pattern_stmt_p (stmt_info)) + lhs = gimple_call_lhs (STMT_VINFO_RELATED_STMT (stmt_info)); + else + lhs = gimple_call_lhs (stmt); + new_stmt = gimple_build_assign (lhs, build_zero_cst (type)); set_vinfo_for_stmt (new_stmt, stmt_info); set_vinfo_for_stmt (stmt, NULL); STMT_VINFO_STMT (stmt_info) = new_stmt; @@ -4846,10 +4884,26 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node) if (!STMT_VINFO_RELEVANT_P (stmt_info) && !STMT_VINFO_LIVE_P (stmt_info)) { - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "irrelevant."); + gimple pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info); + if (STMT_VINFO_IN_PATTERN_P (stmt_info) + && (STMT_VINFO_RELEVANT_P (vinfo_for_stmt (pattern_stmt)) + || STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_stmt)))) + { + stmt = pattern_stmt; + stmt_info = vinfo_for_stmt (pattern_stmt); + if (vect_print_dump_info (REPORT_DETAILS)) + { + fprintf (vect_dump, "==> examining pattern statement: "); + print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); + } + } + else + { + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "irrelevant."); - return true; + return true; + } } switch (STMT_VINFO_DEF_TYPE (stmt_info)) diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index ed73deef66c..77fb0344ad5 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -292,7 +292,6 @@ struct gimple_opt_pass pass_slp_vectorize = 0, /* todo_flags_start */ TODO_ggc_collect | TODO_verify_ssa - | TODO_dump_func | TODO_update_ssa | TODO_verify_stmts /* todo_flags_finish */ } diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index b87452ab080..3f3350320fd 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -896,7 +896,7 @@ extern void vect_slp_transform_bb (basic_block); /* Pattern recognition functions. Additional pattern recognition functions can (and will) be added in the future. */ -typedef gimple (* vect_recog_func_ptr) (gimple *, tree *, tree *); +typedef gimple (* vect_recog_func_ptr) (VEC (gimple, heap) **, tree *, tree *); #define NUM_PATTERNS 4 void vect_pattern_recog (loop_vec_info); diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index f40d0d4c890..c049c5d426b 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -3403,44 +3403,42 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tmax = TYPE_MAX_VALUE (type); /* Try to use estimated number of iterations for the loop to constrain the - final value in the evolution. - We are interested in the number of executions of the latch, while - nb_iterations_upper_bound includes the last execution of the exit test. */ + final value in the evolution. */ if (TREE_CODE (step) == INTEGER_CST - && loop->any_upper_bound - && !double_int_zero_p (loop->nb_iterations_upper_bound) && is_gimple_val (init) && (TREE_CODE (init) != SSA_NAME || get_value_range (init)->type == VR_RANGE)) { - value_range_t maxvr = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }; - double_int dtmp; - bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (step)); - int overflow = 0; - - dtmp = double_int_mul_with_sign (tree_to_double_int (step), - double_int_sub ( - loop->nb_iterations_upper_bound, - double_int_one), - unsigned_p, &overflow); - /* If the multiplication overflowed we can't do a meaningful - adjustment. Likewise if the result doesn't fit in the type - of the induction variable. For a signed type we have to - check whether the result has the expected signedness which - is that of the step as nb_iterations_upper_bound is unsigned. */ - if (!overflow - && double_int_fits_to_tree_p (TREE_TYPE (init), dtmp) - && (unsigned_p - || ((dtmp.high ^ TREE_INT_CST_HIGH (step)) >= 0))) - { - tem = double_int_to_tree (TREE_TYPE (init), dtmp); - extract_range_from_binary_expr (&maxvr, PLUS_EXPR, - TREE_TYPE (init), init, tem); - /* Likewise if the addition did. */ - if (maxvr.type == VR_RANGE) + double_int nit; + + if (estimated_loop_iterations (loop, true, &nit)) + { + value_range_t maxvr = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }; + double_int dtmp; + bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (step)); + int overflow = 0; + + dtmp = double_int_mul_with_sign (tree_to_double_int (step), nit, + unsigned_p, &overflow); + /* If the multiplication overflowed we can't do a meaningful + adjustment. Likewise if the result doesn't fit in the type + of the induction variable. For a signed type we have to + check whether the result has the expected signedness which + is that of the step as number of iterations is unsigned. */ + if (!overflow + && double_int_fits_to_tree_p (TREE_TYPE (init), dtmp) + && (unsigned_p + || ((dtmp.high ^ TREE_INT_CST_HIGH (step)) >= 0))) { - tmin = maxvr.min; - tmax = maxvr.max; + tem = double_int_to_tree (TREE_TYPE (init), dtmp); + extract_range_from_binary_expr (&maxvr, PLUS_EXPR, + TREE_TYPE (init), init, tem); + /* Likewise if the addition did. */ + if (maxvr.type == VR_RANGE) + { + tmin = maxvr.min; + tmax = maxvr.max; + } } } } @@ -7730,14 +7728,14 @@ execute_vrp (void) rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); scev_initialize (); + insert_range_assertions (); + /* Estimate number of iterations - but do not use undefined behavior for this. We can't do this lazily as other functions may compute this using undefined behavior. */ free_numbers_of_iterations_estimates (); estimate_numbers_of_iterations (false); - insert_range_assertions (); - to_remove_edges = VEC_alloc (edge, heap, 10); to_update_switch_stmts = VEC_alloc (switch_update, heap, 5); threadedge_initialize_values (); @@ -7746,6 +7744,8 @@ execute_vrp (void) ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node); vrp_finalize (); + free_numbers_of_iterations_estimates (); + /* ASSERT_EXPRs must be removed before finalizing jump threads as finalizing jump threads calls the CFG cleanup code which does not properly handle ASSERT_EXPRs. */ @@ -7818,7 +7818,6 @@ struct gimple_opt_pass pass_vrp = | TODO_update_ssa | TODO_verify_ssa | TODO_verify_flow - | TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ } }; diff --git a/gcc/tree.c b/gcc/tree.c index 21e7a2bced1..73126cf30d6 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "filenames.h" #include "output.h" #include "target.h" +#include "common/common-target.h" #include "langhooks.h" #include "tree-inline.h" #include "tree-iterator.h" @@ -9476,7 +9477,7 @@ build_common_builtin_nodes (void) ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE); local_define_builtin ("__builtin_unwind_resume", ftype, BUILT_IN_UNWIND_RESUME, - ((targetm.except_unwind_info (&global_options) + ((targetm_common.except_unwind_info (&global_options) == UI_SJLJ) ? "_Unwind_SjLj_Resume" : "_Unwind_Resume"), ECF_NORETURN); diff --git a/gcc/tree.h b/gcc/tree.h index 30c77d8b8ef..f55574dd5f1 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1398,6 +1398,10 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, #define DECL_READ_P(NODE) \ (TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL)->decl_common.decl_read_flag) +#define DECL_NONSHAREABLE(NODE) \ + (TREE_CHECK2 (NODE, VAR_DECL, \ + RESULT_DECL)->decl_common.decl_nonshareable_flag) + /* In a CALL_EXPR, means that the call is the jump from a thunk to the thunked-to function. */ #define CALL_FROM_THUNK_P(NODE) (CALL_EXPR_CHECK (NODE)->base.protected_flag) @@ -2887,8 +2891,9 @@ struct GTY(()) tree_decl_common { being set. */ unsigned decl_read_flag : 1; - /* Padding so that 'off_align' can be on a 32-bit boundary. */ - unsigned decl_common_unused : 1; + /* In VAR_DECL or RESULT_DECL set when significant code movement precludes + attempting to share the stack slot with some other variable. */ + unsigned decl_nonshareable_flag : 1; /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs. */ unsigned int off_align : 8; diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 0ddc8d7619e..a8574d21c30 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -5589,9 +5589,11 @@ prepare_call_arguments (basic_block bb, rtx insn) rtx this_arg = NULL_RTX; tree type = NULL_TREE, t, fndecl = NULL_TREE; tree obj_type_ref = NULL_TREE; - CUMULATIVE_ARGS args_so_far; + CUMULATIVE_ARGS args_so_far_v; + cumulative_args_t args_so_far; - memset (&args_so_far, 0, sizeof (args_so_far)); + memset (&args_so_far_v, 0, sizeof (args_so_far_v)); + args_so_far = pack_cumulative_args (&args_so_far_v); if (GET_CODE (call) == PARALLEL) call = XVECEXP (call, 0, 0); if (GET_CODE (call) == SET) @@ -5639,11 +5641,11 @@ prepare_call_arguments (basic_block bb, rtx insn) tree struct_addr = build_pointer_type (TREE_TYPE (type)); enum machine_mode mode = TYPE_MODE (struct_addr); rtx reg; - INIT_CUMULATIVE_ARGS (args_so_far, type, NULL_RTX, fndecl, + INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl, nargs + 1); - reg = targetm.calls.function_arg (&args_so_far, mode, + reg = targetm.calls.function_arg (args_so_far, mode, struct_addr, true); - targetm.calls.function_arg_advance (&args_so_far, mode, + targetm.calls.function_arg_advance (args_so_far, mode, struct_addr, true); if (reg == NULL_RTX) { @@ -5658,14 +5660,14 @@ prepare_call_arguments (basic_block bb, rtx insn) } else #endif - INIT_CUMULATIVE_ARGS (args_so_far, type, NULL_RTX, fndecl, + INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl, nargs); if (obj_type_ref && TYPE_ARG_TYPES (type) != void_list_node) { enum machine_mode mode; t = TYPE_ARG_TYPES (type); mode = TYPE_MODE (TREE_VALUE (t)); - this_arg = targetm.calls.function_arg (&args_so_far, mode, + this_arg = targetm.calls.function_arg (args_so_far, mode, TREE_VALUE (t), true); if (this_arg && !REG_P (this_arg)) this_arg = NULL_RTX; @@ -5745,12 +5747,12 @@ prepare_call_arguments (basic_block bb, rtx insn) tree argtype = TREE_VALUE (t); enum machine_mode mode = TYPE_MODE (argtype); rtx reg; - if (pass_by_reference (&args_so_far, mode, argtype, true)) + if (pass_by_reference (&args_so_far_v, mode, argtype, true)) { argtype = build_pointer_type (argtype); mode = TYPE_MODE (argtype); } - reg = targetm.calls.function_arg (&args_so_far, mode, + reg = targetm.calls.function_arg (args_so_far, mode, argtype, true); if (TREE_CODE (argtype) == REFERENCE_TYPE && INTEGRAL_TYPE_P (TREE_TYPE (argtype)) @@ -5804,7 +5806,7 @@ prepare_call_arguments (basic_block bb, rtx insn) } } } - targetm.calls.function_arg_advance (&args_so_far, mode, + targetm.calls.function_arg_advance (args_so_far, mode, argtype, true); t = TREE_CHAIN (t); } @@ -9131,6 +9133,6 @@ struct rtl_opt_pass pass_variable_tracking = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_rtl_sharing/* todo_flags_finish */ + TODO_verify_rtl_sharing /* todo_flags_finish */ } }; diff --git a/gcc/varasm.c b/gcc/varasm.c index a0a0582be76..cfdf8d7d13e 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "debug.h" #include "target.h" +#include "common/common-target.h" #include "targhooks.h" #include "tree-mudflap.h" #include "cgraph.h" @@ -416,7 +417,7 @@ resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED, int flag_function_or_data_sections) { if (DECL_SECTION_NAME (decl) == NULL_TREE - && targetm.have_named_sections + && targetm_common.have_named_sections && (flag_function_or_data_sections || DECL_ONE_ONLY (decl))) { @@ -464,7 +465,7 @@ hot_function_section (tree decl) { if (decl != NULL_TREE && DECL_SECTION_NAME (decl) != NULL_TREE - && targetm.have_named_sections) + && targetm_common.have_named_sections) return get_named_section (decl, NULL, 0); else return text_section; @@ -536,7 +537,7 @@ default_function_section (tree decl, enum node_frequency freq, #endif if (!flag_reorder_functions - || !targetm.have_named_sections) + || !targetm_common.have_named_sections) return NULL; /* Startup code should go to startup subsection unless it is unlikely executed (this happens especially with function splitting diff --git a/gcc/varpool.c b/gcc/varpool.c index 43ee2290389..d223779a5c1 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -131,7 +131,7 @@ varpool_node (tree decl) struct varpool_node key, *node, **slot; gcc_assert (TREE_CODE (decl) == VAR_DECL - && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))); + && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || in_lto_p)); if (!varpool_hash) varpool_hash = htab_create_ggc (10, hash_varpool_node, @@ -162,25 +162,14 @@ varpool_remove_node (struct varpool_node *node) gcc_assert (*slot == node); htab_clear_slot (varpool_hash, slot); gcc_assert (!varpool_assembled_nodes_queue); - if (!node->alias) - while (node->extra_name) - varpool_remove_node (node->extra_name); if (node->next) node->next->prev = node->prev; if (node->prev) node->prev->next = node->next; else { - if (node->alias && node->extra_name) - { - gcc_assert (node->extra_name->extra_name == node); - node->extra_name->extra_name = node->next; - } - else - { - gcc_assert (varpool_nodes == node); - varpool_nodes = node->next; - } + gcc_assert (varpool_nodes == node); + varpool_nodes = node->next; } if (varpool_first_unanalyzed_node == node) varpool_first_unanalyzed_node = node->next_needed; @@ -311,8 +300,6 @@ varpool_enqueue_needed_node (struct varpool_node *node) void varpool_mark_needed_node (struct varpool_node *node) { - if (node->alias && node->extra_name) - node = node->extra_name; if (!node->needed && node->finalized && !TREE_ASM_WRITTEN (node->decl)) varpool_enqueue_needed_node (node); @@ -473,7 +460,40 @@ varpool_analyze_pending_decls (void) already informed about increased alignment. */ align_variable (decl, 0); } - if (DECL_INITIAL (decl)) + if (node->alias && node->alias_of) + { + struct varpool_node *tgt = varpool_node (node->alias_of); + if (!VEC_length (ipa_ref_t, node->ref_list.references)) + ipa_record_reference (NULL, node, NULL, tgt, IPA_REF_ALIAS, NULL); + /* C++ FE sometimes change linkage flags after producing same body aliases. */ + if (node->extra_name_alias) + { + DECL_WEAK (node->decl) = DECL_WEAK (node->alias_of); + TREE_PUBLIC (node->decl) = TREE_PUBLIC (node->alias_of); + DECL_VISIBILITY (node->decl) = DECL_VISIBILITY (node->alias_of); + if (TREE_PUBLIC (node->decl)) + { + DECL_COMDAT (node->decl) = DECL_COMDAT (node->alias_of); + DECL_COMDAT_GROUP (node->decl) = DECL_COMDAT_GROUP (node->alias_of); + if (DECL_ONE_ONLY (node->alias_of) && !node->same_comdat_group) + { + node->same_comdat_group = tgt; + if (!tgt->same_comdat_group) + tgt->same_comdat_group = node; + else + { + struct varpool_node *n; + for (n = tgt->same_comdat_group; + n->same_comdat_group != tgt; + n = n->same_comdat_group) + ; + n->same_comdat_group = node; + } + } + } + } + } + else if (DECL_INITIAL (decl)) record_references_in_initializer (decl, analyzed); if (node->same_comdat_group) { @@ -488,6 +508,23 @@ varpool_analyze_pending_decls (void) return changed; } +/* Assemble thunks and aliases asociated to NODE. */ + +static void +assemble_aliases (struct varpool_node *node) +{ + int i; + struct ipa_ref *ref; + for (i = 0; ipa_ref_list_refering_iterate (&node->ref_list, i, ref); i++) + if (ref->use == IPA_REF_ALIAS) + { + struct varpool_node *alias = ipa_ref_refering_varpool_node (ref); + assemble_alias (alias->decl, + DECL_ASSEMBLER_NAME (alias->alias_of)); + assemble_aliases (alias); + } +} + /* Output one variable, if necessary. Return whether we output it. */ bool varpool_assemble_decl (struct varpool_node *node) @@ -503,25 +540,13 @@ varpool_assemble_decl (struct varpool_node *node) assemble_variable (decl, 0, 1, 0); if (TREE_ASM_WRITTEN (decl)) { - struct varpool_node *alias; - node->next_needed = varpool_assembled_nodes_queue; node->prev_needed = NULL; if (varpool_assembled_nodes_queue) varpool_assembled_nodes_queue->prev_needed = node; varpool_assembled_nodes_queue = node; node->finalized = 1; - - /* Also emit any extra name aliases. */ - for (alias = node->extra_name; alias; alias = alias->next) - { - /* Update linkage fields in case they've changed. */ - DECL_WEAK (alias->decl) = DECL_WEAK (decl); - TREE_PUBLIC (alias->decl) = TREE_PUBLIC (decl); - DECL_VISIBILITY (alias->decl) = DECL_VISIBILITY (decl); - assemble_alias (alias->decl, DECL_ASSEMBLER_NAME (decl)); - } - + assemble_aliases (node); return true; } } @@ -670,38 +695,36 @@ add_new_static_var (tree type) Extra name aliases are output whenever DECL is output. */ struct varpool_node * -varpool_extra_name_alias (tree alias, tree decl) +varpool_create_variable_alias (tree alias, tree decl) { - struct varpool_node key, *alias_node, *decl_node, **slot; - -#ifndef ASM_OUTPUT_DEF - /* If aliases aren't supported by the assembler, fail. */ - return NULL; -#endif + struct varpool_node *alias_node; gcc_assert (TREE_CODE (decl) == VAR_DECL); gcc_assert (TREE_CODE (alias) == VAR_DECL); - /* Make sure the hash table has been created. */ - decl_node = varpool_node (decl); - - key.decl = alias; + alias_node = varpool_node (alias); + alias_node->alias = 1; + alias_node->finalized = 1; + alias_node->alias_of = decl; + if (decide_is_variable_needed (alias_node, alias) + || alias_node->needed) + varpool_mark_needed_node (alias_node); + return alias_node; +} - slot = (struct varpool_node **) htab_find_slot (varpool_hash, &key, INSERT); +/* Attempt to mark ALIAS as an alias to DECL. Return TRUE if successful. + Extra name aliases are output whenever DECL is output. */ - /* If the varpool_node has been already created, fail. */ - if (*slot) - return NULL; +struct varpool_node * +varpool_extra_name_alias (tree alias, tree decl) +{ + struct varpool_node *alias_node; - alias_node = ggc_alloc_cleared_varpool_node (); - alias_node->decl = alias; - alias_node->alias = 1; - alias_node->extra_name = decl_node; - alias_node->next = decl_node->extra_name; - ipa_empty_ref_list (&alias_node->ref_list); - if (decl_node->extra_name) - decl_node->extra_name->prev = alias_node; - decl_node->extra_name = alias_node; - *slot = alias_node; +#ifndef ASM_OUTPUT_DEF + /* If aliases aren't supported by the assembler, fail. */ + return NULL; +#endif + alias_node = varpool_create_variable_alias (alias, decl); + alias_node->extra_name_alias = true; return alias_node; } @@ -711,17 +734,38 @@ varpool_extra_name_alias (tree alias, tree decl) bool varpool_used_from_object_file_p (struct varpool_node *node) { - struct varpool_node *alias; - if (!TREE_PUBLIC (node->decl)) return false; if (resolution_used_from_other_file_p (node->resolution)) return true; - for (alias = node->extra_name; alias; alias = alias->next) - if (TREE_PUBLIC (alias->decl) - && resolution_used_from_other_file_p (alias->resolution)) - return true; return false; } +/* Call calback on NODE and aliases asociated to NODE. + When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are + skipped. */ + +bool +varpool_for_node_and_aliases (struct varpool_node *node, + bool (*callback) (struct varpool_node *, void *), + void *data, + bool include_overwritable) +{ + int i; + struct ipa_ref *ref; + + if (callback (node, data)) + return true; + for (i = 0; ipa_ref_list_refering_iterate (&node->ref_list, i, ref); i++) + if (ref->use == IPA_REF_ALIAS) + { + struct varpool_node *alias = ipa_ref_refering_varpool_node (ref); + if (include_overwritable + || cgraph_variable_initializer_availability (alias) > AVAIL_OVERWRITABLE) + if (varpool_for_node_and_aliases (alias, callback, data, + include_overwritable)) + return true; + } + return false; +} #include "gt-varpool.h" diff --git a/gcc/web.c b/gcc/web.c index e08a9687785..9044fc68d04 100644 --- a/gcc/web.c +++ b/gcc/web.c @@ -437,8 +437,6 @@ struct rtl_opt_pass pass_web = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_df_finish | TODO_verify_rtl_sharing | - TODO_dump_func /* todo_flags_finish */ + TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */ } }; - diff --git a/include/ChangeLog b/include/ChangeLog index 7ad246e44a7..fa0dfac51f3 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2011-06-13 Jan Kratochvil <jan.kratochvil@redhat.com> + + * demangle.h (DMGL_RET_POSTFIX): Extend the comment. + (DMGL_RET_DROP): New. + 2011-04-30 Jakub Jelinek <jakub@redhat.com> * dwarf2.h (DW_OP_GNU_const_type, DW_OP_GNU_regval_type, diff --git a/include/demangle.h b/include/demangle.h index c0624559ee2..53f6c54f524 100644 --- a/include/demangle.h +++ b/include/demangle.h @@ -45,7 +45,13 @@ extern "C" { #define DMGL_VERBOSE (1 << 3) /* Include implementation details. */ #define DMGL_TYPES (1 << 4) /* Also try to demangle type encodings. */ #define DMGL_RET_POSTFIX (1 << 5) /* Print function return types (when - present) after function signature */ + present) after function signature. + It applies only to the toplevel + function type. */ +#define DMGL_RET_DROP (1 << 6) /* Suppress printing function return + types, even if present. It applies + only to the toplevel function type. + */ #define DMGL_AUTO (1 << 8) #define DMGL_GNU (1 << 9) diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index e1c01c13660..e36edfa981d 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,8 @@ +2011-06-16 Jason Merrill <jason@redhat.com> + + PR c++/45399 + * lex.c (lex_raw_string): Don't check for embedded NUL. + 2011-06-06 Dodji Seketeli <dodji@redhat.com> PR preprocessor/48532 diff --git a/libcpp/lex.c b/libcpp/lex.c index 6c3be711504..d29f36d436d 100644 --- a/libcpp/lex.c +++ b/libcpp/lex.c @@ -1270,7 +1270,6 @@ static void lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base, const uchar *cur) { - source_location saw_NUL = 0; const uchar *raw_prefix; unsigned int raw_prefix_len = 0; enum cpp_ttype type; @@ -1476,16 +1475,9 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base, cur = base = pfile->buffer->cur; note = &pfile->buffer->notes[pfile->buffer->cur_note]; } - else if (c == '\0' && !saw_NUL) - LINEMAP_POSITION_FOR_COLUMN (saw_NUL, pfile->line_table, - CPP_BUF_COLUMN (pfile->buffer, cur)); } break_outer_loop: - if (saw_NUL && !pfile->state.skipping) - cpp_error_with_line (pfile, CPP_DL_WARNING, saw_NUL, 0, - "null character(s) preserved in literal"); - pfile->buffer->cur = cur; if (first_buff == NULL) create_literal (pfile, token, base, cur - base, type); diff --git a/libffi/ChangeLog b/libffi/ChangeLog index e9cacff7505..e66932e9e90 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,11 @@ +2011-06-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * testsuite/libffi.call/huge_struct.c (test_large_fn): Use PRIu8, + PRId8 instead of %hhu, %hhd. + * testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRId8, + PRIu8): Define. + [__sgi__] (PRId8, PRIu8): Define. + 2011-04-29 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> * src/alpha/osf.S (UA_SI, FDE_ENCODING, FDE_ENCODE, FDE_ARANGE): diff --git a/libffi/testsuite/libffi.call/ffitest.h b/libffi/testsuite/libffi.call/ffitest.h index 59ef032ea51..0e95e164f6e 100644 --- a/libffi/testsuite/libffi.call/ffitest.h +++ b/libffi/testsuite/libffi.call/ffitest.h @@ -67,6 +67,8 @@ #define PRIdLL "ld" #undef PRIuLL #define PRIuLL "lu" +#define PRId8 "hd" +#define PRIu8 "hu" #define PRId64 "ld" #define PRIu64 "lu" #define PRIuPTR "lu" @@ -81,6 +83,8 @@ #if defined(__sgi) /* IRIX 6.5 <inttypes.h> provides all definitions, but only for C99 compilations. */ +#define PRId8 "hhd" +#define PRIu8 "hhu" #if (_MIPS_SZLONG == 32) #define PRId64 "lld" #define PRIu64 "llu" diff --git a/libffi/testsuite/libffi.call/huge_struct.c b/libffi/testsuite/libffi.call/huge_struct.c index 602437ade59..e04e1d58a40 100644 --- a/libffi/testsuite/libffi.call/huge_struct.c +++ b/libffi/testsuite/libffi.call/huge_struct.c @@ -129,14 +129,14 @@ test_large_fn( ui64_4 + 4, si64_4 + 4, f_4 + 4, d_4 + 4, ld_4 + 4, (char*)((intptr_t)p_4 + 4), ui8_5 + 5, si8_5 + 5}; - printf("%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %hhu %hhd: " - "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %hhu %hhd\n", + printf("%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 ": " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n", ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, (unsigned long)p_1, ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, (unsigned long)p_2, ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, (unsigned long)p_3, @@ -296,10 +296,10 @@ main(int argc __UNUSED__, const char** argv __UNUSED__) ffi_call(&cif, FFI_FN(test_large_fn), &retVal, argValues); // { dg-output "1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } - printf("res: %hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %hhu %hhd\n", + printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n", retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f, retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l, retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r, @@ -324,10 +324,10 @@ main(int argc __UNUSED__, const char** argv __UNUSED__) ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, ui8, si8); // { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } - printf("res: %hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " - "%hhu %hhd %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %hhu %hhd\n", + printf("res: %" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx " + "%" PRIu8 " %" PRId8 " %hu %hd %u %d %" PRIu64 " %" PRId64 " %.0f %.0f %.0Lf %#lx %" PRIu8 " %" PRId8 "\n", retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f, retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, (unsigned long)retVal.l, retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r, diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 06c7613dd89..0f2384ea5de 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,17 @@ +2011-06-16 Georg-Johann Lay <avr@gjlay.de> + + PR target/49313 + PR target/29524 + * config/avr/t-avr: Fix line endings. + (intfuncs16): Remove _ffsXX2, _clzXX2, _ctzXX2, _popcountXX2, + _parityXX2. + +2011-06-14 Olivier Hainque <hainque@adacore.com> + Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * config/mips/irix6-unwind.h: New file. + * config.host (mips-sgi-irix6.5*): Set md_unwind_header. + 2011-06-10 Eric Botcazou <ebotcazou@adacore.com> * config/sparc/linux-unwind.h (STACK_BIAS): Define. diff --git a/libgcc/config.host b/libgcc/config.host index c2b5dbca75c..6ea74900c86 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -456,6 +456,7 @@ microblaze*-*-*) mips-sgi-irix6.5*) tmake_file="mips/t-irix6 t-crtfm t-slibgcc mips/t-slibgcc-irix" extra_parts="crtbegin.o crtend.o crtfastmath.o irix-crti.o irix-crtn.o" + md_unwind_header=mips/irix6-unwind.h ;; mips*-*-netbsd*) # NetBSD/mips, either endian. ;; diff --git a/libgcc/config/avr/t-avr b/libgcc/config/avr/t-avr index ee570724171..7c8783ee212 100644 --- a/libgcc/config/avr/t-avr +++ b/libgcc/config/avr/t-avr @@ -1,19 +1,17 @@ -# Extra 16-bit integer functions.
-intfuncs16 = _absvXX2 _addvXX3 _subvXX3 _mulvXX3 _negvXX2 _ffsXX2 _clzXX2 \
- _ctzXX2 _popcountXX2 _parityXX2
-hiintfuncs16 = $(subst XX,hi,$(intfuncs16))
-siintfuncs16 = $(subst XX,si,$(intfuncs16))
-
-iter-items := $(hiintfuncs16)
-iter-labels := $(siintfuncs16)
-iter-sizes := $(patsubst %,2,$(siintfuncs16)) $(patsubst %,2,$(hiintfuncs16))
-
-
-include $(srcdir)/empty.mk $(patsubst %,$(srcdir)/siditi-object.mk,$(iter-items))
-libgcc-objects += $(patsubst %,%$(objext),$(hiintfuncs16))
-
-ifeq ($(enable_shared),yes)
-libgcc-s-objects += $(patsubst %,%_s$(objext),$(hiintfuncs16))
-endif
-
-
+# Extra 16-bit integer functions. +intfuncs16 = _absvXX2 _addvXX3 _subvXX3 _mulvXX3 _negvXX2 + +hiintfuncs16 = $(subst XX,hi,$(intfuncs16)) +siintfuncs16 = $(subst XX,si,$(intfuncs16)) + +iter-items := $(hiintfuncs16) +iter-labels := $(siintfuncs16) +iter-sizes := $(patsubst %,2,$(siintfuncs16)) $(patsubst %,2,$(hiintfuncs16)) + + +include $(srcdir)/empty.mk $(patsubst %,$(srcdir)/siditi-object.mk,$(iter-items)) +libgcc-objects += $(patsubst %,%$(objext),$(hiintfuncs16)) + +ifeq ($(enable_shared),yes) +libgcc-s-objects += $(patsubst %,%_s$(objext),$(hiintfuncs16)) +endif diff --git a/libgcc/config/mips/irix6-unwind.h b/libgcc/config/mips/irix6-unwind.h new file mode 100644 index 00000000000..e862560fe34 --- /dev/null +++ b/libgcc/config/mips/irix6-unwind.h @@ -0,0 +1,180 @@ +/* DWARF2 EH unwinding support for MIPS IRIX 6. + Copyright (C) 2011 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +/* Do code reading to identify a signal frame, and set the frame + state data appropriately. See unwind-dw2.c for the structs. */ + +/* This code was developed-for and only tested-in limited ABI + configurations. Characterize that. */ + +#if defined (_ABIN32) || defined (_ABI64) +#define SUPPORTED_ABI 1 +#else +#define SUPPORTED_ABI 0 +#endif + +#include <signal.h> + +#define MD_FALLBACK_FRAME_STATE_FOR mips_fallback_frame_state + +/* Look at the code around RA to see if it matches a sighandler caller with a + sigcontext_t * argument (SA_SIGINFO cleared). Return that pointer argument + if it does match, or 0 otherwise. */ + +static sigcontext_t * +sigcontext_for (unsigned int *ra, void *cfa) +{ + /* IRIX 6.5, mono-threaded application. We're lucky enough to be able + to expect a short very sighandler specific sequence around. + + <_sigtramp+124>: li v0,1088 (SYS_sigreturn) + <_sigtramp+128>: syscall */ + + if ( ra[6] == 0x24020440 + && ra[7] == 0x0000000c) + return (sigcontext_t *)(cfa + 0x30); + + /* IRIX 6.5 variants, multi-threaded application, pthreads. Nothing really + sighandler specific handy, so match a fairly long constant sequence. */ + +#if _MIPS_SIM == _ABIN32 + /* + <sig_fixup_mask+40>: sd s0,0(sp) + <sig_fixup_mask+44>: sll ra,a0,0x2 + <sig_fixup_mask+48>: addiu t9,t9,-28584/-28456/-28448 + <sig_fixup_mask+52>: lw s0,3804(at) + <sig_fixup_mask+56>: addu t9,t9,ra + <sig_fixup_mask+60>: lw t9,0(t9) + <sig_fixup_mask+64>: ld at,3696(at) + <sig_fixup_mask+68>: ld s2,88(s0) + <sig_fixup_mask+72>: jalr t9 + <sig_fixup_mask+76>: sd at,88(s0) */ + if ( ra[-10] == 0xffb00000 + && ra[ -9] == 0x0004f880 + && (ra[-8] == 0x27399058 + || ra[-8] == 0x273990d8 + || ra[-8] == 0x273990e0) + && ra[ -7] == 0x8c300edc + && ra[ -6] == 0x033fc821 + && ra[ -5] == 0x8f390000 + && ra[ -4] == 0xdc210e70 + && ra[ -3] == 0xde120058 + && ra[ -2] == 0x0320f809 + && ra[ -1] == 0xfe010058) + +#elif _MIPS_SIM == _ABI64 + /* + <sig_fixup_mask+44>: sd s0,0(sp) + <sig_fixup_mask+48>: daddu t9,t9,ra + <sig_fixup_mask+52>: dsll ra,a0,0x3 + <sig_fixup_mask+56>: ld s0,3880(at) + <sig_fixup_mask+60>: daddu t9,t9,ra + <sig_fixup_mask+64>: ld t9,0(t9) + <sig_fixup_mask+68>: ld at,3696(at) + <sig_fixup_mask+72>: ld s2,152(s0) + <sig_fixup_mask+76>: jalr t9 + <sig_fixup_mask+80>: sd at,152(s0) */ + if ( ra[-10] == 0xffb00000 + && ra[ -9] == 0x033fc82d + && ra[ -8] == 0x0004f8f8 + && ra[ -7] == 0xdc300f28 + && ra[ -6] == 0x033fc82d + && ra[ -5] == 0xdf390000 + && ra[ -4] == 0xdc210e70 + && ra[ -3] == 0xde120098 + && ra[ -2] == 0x0320f809 + && ra[ -1] == 0xfe010098) +#endif + return (sigcontext_t *)(cfa + 0x60); + + return 0; +} + +#define SIGCTX_GREG_ADDR(REGNO,SIGCTX) \ + ((void *) &(SIGCTX)->sc_regs[REGNO]) + +#define SIGCTX_FPREG_ADDR(REGNO,SIGCTX) \ + ((void *) &(SIGCTX)->sc_fpregs[REGNO]) + +static _Unwind_Reason_Code +mips_fallback_frame_state (struct _Unwind_Context *context, + _Unwind_FrameState *fs) +{ + /* Return address and CFA of the frame we're attempting to unwind through, + possibly a signal handler. */ + void *ctx_ra = (void *)context->ra; + void *ctx_cfa = (void *)context->cfa; + + /* CFA of the intermediate abstract kernel frame between the interrupted + code and the signal handler, if we're indeed unwinding through a signal + handler. */ + void *k_cfa; + + /* Pointer to the sigcontext_t structure pushed by the kernel when we're + unwinding through a signal handler setup with SA_SIGINFO cleared. */ + sigcontext_t *sigctx; + int i; + + if (! SUPPORTED_ABI) + return _URC_END_OF_STACK; + + sigctx = sigcontext_for (ctx_ra, ctx_cfa); + + if (sigctx == 0) + return _URC_END_OF_STACK; + + /* The abstract kernel frame's CFA is extactly the stack pointer + value at the interruption point. */ + k_cfa = *(void **)SIGCTX_GREG_ADDR (CTX_SP, sigctx); + + /* State the rules to compute the CFA we have the value of: use the + previous CFA and offset by the difference between the two. See + uw_update_context_1 for the supporting details. */ + fs->regs.cfa_how = CFA_REG_OFFSET; + fs->regs.cfa_reg = __builtin_dwarf_sp_column (); + fs->regs.cfa_offset = k_cfa - ctx_cfa; + + /* Fill the internal frame_state structure with information stating where + each register of interest can be found from the CFA. */ + for (i = 0; i <= 31; i ++) + { + fs->regs.reg[i].how = REG_SAVED_OFFSET; + fs->regs.reg[i].loc.offset = SIGCTX_GREG_ADDR (i, sigctx) - k_cfa; + } + + for (i = 0; i <= 31; i ++) + { + fs->regs.reg[32+i].how = REG_SAVED_OFFSET; + fs->regs.reg[32+i].loc.offset = SIGCTX_FPREG_ADDR (i, sigctx) - k_cfa; + } + + /* State the rules to find the kernel's code "return address", which is the + address of the active instruction when the signal was caught. */ + fs->retaddr_column = DWARF_FRAME_RETURN_COLUMN; + fs->regs.reg[fs->retaddr_column].how = REG_SAVED_OFFSET; + fs->regs.reg[fs->retaddr_column].loc.offset = (void *)&sigctx->sc_pc - k_cfa; + fs->signal_frame = 1; + + return _URC_NO_REASON; +} diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index bcd62f52c32..b0f0666a3b5 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,34 @@ +2011-06-18 Janne Blomqvist <jb@gcc.gnu.org> + + PR libfortran/49296 + * io/list_read.c (read_character): Accept EOF as a separator when + reading string. + +2011-06-17 Daniel Carrera <dcarrera@gmail.com> + + * caf/single.c (_gfortran_caf_register): Store the address + of all static coarrays in a linked list. + (_gfortran_caf_finalize): Free memory of staic coarrays. + * caf/mpi.c (_gfortran_caf_register): Store the address + of all static coarrays in a linked list. Initialize MPI + if necessary. + (_gfortran_caf_finalize): Free memory of staic coarrays. + (_gfortran_caf_init): Check if MPI is already initialized + before initializing again. + * caf/libcaf.h: Add a type to caf_register_t to distinguish + static coarrays and add the type caf_static_t to make the + linked list of static coarrays. + +2011-06-11 Janne Blomqvist <jb@gcc.gnu.org> + + * io/unix.c (buf_seek): Return error if file is not seekable. + (buf_tell): Call buf_seek. + +2011-06-11 Janne Blomqvist <jb@gcc.gnu.org> + + * io/unix.c (fd_to_stream): Figure out if a fd is seekable by + trying lseek(). + 2011-06-10 Daniel Carrera <dcarrera@gmail.com> * caf/mpi.c (_gfortran_caf_sync_all, diff --git a/libgfortran/caf/libcaf.h b/libgfortran/caf/libcaf.h index 9c20c4e9d78..4177985536d 100644 --- a/libgfortran/caf/libcaf.h +++ b/libgfortran/caf/libcaf.h @@ -38,14 +38,22 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define STAT_LOCKED_OTHER_IMAGE 2 #define STAT_STOPPED_IMAGE 3 - +/* Describes what type of array we are registerring. */ typedef enum caf_register_t { - CAF_REGTYPE_COARRAY, + CAF_REGTYPE_COARRAY_STATIC, + CAF_REGTYPE_COARRAY_ALLOC, CAF_REGTYPE_LOCK, - CAF_REGTYPE_LOCK_COMP + CAF_REGTYPE_LOCK_COMP } caf_register_t; +/* Linked list of static coarrays registered. */ +typedef struct caf_static_t { + void **token; + struct caf_static_t *prev; +} +caf_static_t; + void _gfortran_caf_init (int *, char ***, int *, int *); void _gfortran_caf_finalize (void); diff --git a/libgfortran/caf/mpi.c b/libgfortran/caf/mpi.c index e64670ea8cb..83f39f6f88c 100644 --- a/libgfortran/caf/mpi.c +++ b/libgfortran/caf/mpi.c @@ -42,6 +42,8 @@ static int caf_mpi_initialized; static int caf_this_image; static int caf_num_images; +caf_static_t *caf_static_list = NULL; + /* Initialize coarray program. This routine assumes that no other MPI initialization happened before; otherwise MPI_Initialized @@ -52,16 +54,23 @@ static int caf_num_images; void _gfortran_caf_init (int *argc, char ***argv, int *this_image, int *num_images) { - /* caf_mpi_initialized is only true if the main program is not written in - Fortran. */ - MPI_Initialized (&caf_mpi_initialized); - if (!caf_mpi_initialized) - MPI_Init (argc, argv); + if (caf_num_images == 0) + { + /* caf_mpi_initialized is only true if the main program is + not written in Fortran. */ + MPI_Initialized (&caf_mpi_initialized); + if (!caf_mpi_initialized) + MPI_Init (argc, argv); + + MPI_Comm_size (MPI_COMM_WORLD, &caf_num_images); + MPI_Comm_rank (MPI_COMM_WORLD, &caf_this_image); + caf_this_image++; + } - MPI_Comm_rank (MPI_COMM_WORLD, &caf_this_image); - *this_image = ++caf_this_image; - MPI_Comm_size (MPI_COMM_WORLD, &caf_num_images); - *num_images = caf_num_images; + if (this_image) + *this_image = caf_this_image; + if (num_images) + *num_images = caf_num_images; } @@ -70,18 +79,43 @@ _gfortran_caf_init (int *argc, char ***argv, int *this_image, int *num_images) void _gfortran_caf_finalize (void) { + while (caf_static_list != NULL) + { + free(caf_static_list->token[caf_this_image-1]); + caf_static_list = caf_static_list->prev; + } + if (!caf_mpi_initialized) MPI_Finalize (); } void * -_gfortran_caf_register (ptrdiff_t size, - caf_register_t type __attribute__ ((unused)), +_gfortran_caf_register (ptrdiff_t size, caf_register_t type, void **token) { - *token = NULL; - return malloc (size); + void *local; + + /* Start MPI if not already started. */ + if (caf_num_images == 0) + _gfortran_caf_init (NULL, NULL, NULL, NULL); + + /* Token contains only a list of pointers. */ + local = malloc (size); + token = malloc (sizeof (void*) * caf_num_images); + + /* token[img-1] is the address of the token in image "img". */ + MPI_Allgather (&local, sizeof (void*), MPI_BYTE, + token, sizeof (void*), MPI_BYTE, MPI_COMM_WORLD); + + if (type == CAF_REGTYPE_COARRAY_STATIC) + { + caf_static_t *tmp = malloc (sizeof (caf_static_t)); + tmp->prev = caf_static_list; + tmp->token = token; + caf_static_list = tmp; + } + return local; } diff --git a/libgfortran/caf/single.c b/libgfortran/caf/single.c index 4c46e47d35c..53927977d52 100644 --- a/libgfortran/caf/single.c +++ b/libgfortran/caf/single.c @@ -35,6 +35,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see Note: For performance reasons -fcoarry=single should be used rather than this library. */ +/* Global variables. */ +caf_static_t *caf_static_list = NULL; + void _gfortran_caf_init (int *argc __attribute__ ((unused)), @@ -49,16 +52,32 @@ _gfortran_caf_init (int *argc __attribute__ ((unused)), void _gfortran_caf_finalize (void) { + while (caf_static_list != NULL) + { + free(caf_static_list->token[0]); + caf_static_list = caf_static_list->prev; + } } void * -_gfortran_caf_register (ptrdiff_t size, - caf_register_t type __attribute__ ((unused)), +_gfortran_caf_register (ptrdiff_t size, caf_register_t type, void **token) { - *token = NULL; - return malloc (size); + void *local; + + local = malloc (size); + token = malloc (sizeof (void*) * 1); + token[0] = local; + + if (type == CAF_REGTYPE_COARRAY_STATIC) + { + caf_static_t *tmp = malloc (sizeof (caf_static_t)); + tmp->prev = caf_static_list; + tmp->token = token; + caf_static_list = tmp; + } + return local; } @@ -78,6 +97,7 @@ _gfortran_caf_sync_all (int *stat, *stat = 0; } + void _gfortran_caf_sync_images (int count __attribute__ ((unused)), int images[] __attribute__ ((unused)), diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index 38a92e1ba40..baf2f54041a 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -1022,7 +1022,7 @@ read_character (st_parameter_dt *dtp, int length __attribute__ ((unused))) for (;;) { if ((c = next_char (dtp)) == EOF) - goto eof; + goto done_eof; switch (c) { case '"': @@ -1068,26 +1068,26 @@ read_character (st_parameter_dt *dtp, int length __attribute__ ((unused))) invalid. */ done: c = next_char (dtp); - eof: - if (is_separator (c) || c == '!') + done_eof: + if (is_separator (c) || c == '!' || c == EOF) { unget_char (dtp, c); eat_separator (dtp); dtp->u.p.saved_type = BT_CHARACTER; free_line (dtp); } - else + else { free_saved (dtp); - if (c == EOF) - { - hit_eof (dtp); - return; - } snprintf (message, MSGLEN, "Invalid string input in item %d", dtp->u.p.item_count); generate_error (&dtp->common, LIBERROR_READ_VALUE, message); } + return; + + eof: + free_saved (dtp); + hit_eof (dtp); } diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index c257766d653..25cb559db01 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -560,6 +560,11 @@ buf_write (unix_stream * s, const void * buf, ssize_t nbyte) static gfc_offset buf_seek (unix_stream * s, gfc_offset offset, int whence) { + if (s->file_length == -1) + { + errno = ESPIPE; + return -1; + } switch (whence) { case SEEK_SET: @@ -585,7 +590,7 @@ buf_seek (unix_stream * s, gfc_offset offset, int whence) static gfc_offset buf_tell (unix_stream * s) { - return s->logical_offset; + return buf_seek (s, 0, SEEK_CUR); } static int @@ -952,15 +957,15 @@ fd_to_stream (int fd) if (S_ISREG (statbuf.st_mode)) s->file_length = statbuf.st_size; - else if (S_ISBLK (statbuf.st_mode)) + else { - /* Hopefully more portable than ioctl(fd, BLKGETSIZE64, &size)? */ - gfc_offset cur = lseek (fd, 0, SEEK_CUR); + /* Some character special files are seekable but most are not, + so figure it out by trying to seek. On Linux, /dev/null is + an example of such a special file. */ s->file_length = lseek (fd, 0, SEEK_END); - lseek (fd, cur, SEEK_SET); + if (s->file_length > 0) + lseek (fd, 0, SEEK_SET); } - else - s->file_length = -1; if (!(S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode)) || options.all_unbuffered diff --git a/libgo/Makefile.am b/libgo/Makefile.am index c98a17637d3..761a11ad265 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -381,6 +381,7 @@ runtime_files = \ runtime/go-interface-eface-compare.c \ runtime/go-interface-val-compare.c \ runtime/go-lock-os-thread.c \ + runtime/go-make-slice.c \ runtime/go-map-delete.c \ runtime/go-map-index.c \ runtime/go-map-len.c \ diff --git a/libgo/Makefile.in b/libgo/Makefile.in index ac5de78dca4..8637ec41b7d 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -184,18 +184,18 @@ am__libgo_la_SOURCES_DIST = runtime/go-append.c runtime/go-assert.c \ runtime/go-interface-compare.c \ runtime/go-interface-eface-compare.c \ runtime/go-interface-val-compare.c runtime/go-lock-os-thread.c \ - runtime/go-map-delete.c runtime/go-map-index.c \ - runtime/go-map-len.c runtime/go-map-range.c \ - runtime/go-nanotime.c runtime/go-new-channel.c \ - runtime/go-new-map.c runtime/go-new.c runtime/go-note.c \ - runtime/go-panic.c runtime/go-panic-defer.c runtime/go-print.c \ - runtime/go-rec-big.c runtime/go-rec-nb-big.c \ - runtime/go-rec-nb-small.c runtime/go-rec-small.c \ - runtime/go-recover.c runtime/go-reflect.c \ - runtime/go-reflect-call.c runtime/go-reflect-chan.c \ - runtime/go-reflect-map.c runtime/go-rune.c \ - runtime/go-runtime-error.c runtime/go-sched.c \ - runtime/go-select.c runtime/go-semacquire.c \ + runtime/go-make-slice.c runtime/go-map-delete.c \ + runtime/go-map-index.c runtime/go-map-len.c \ + runtime/go-map-range.c runtime/go-nanotime.c \ + runtime/go-new-channel.c runtime/go-new-map.c runtime/go-new.c \ + runtime/go-note.c runtime/go-panic.c runtime/go-panic-defer.c \ + runtime/go-print.c runtime/go-rec-big.c \ + runtime/go-rec-nb-big.c runtime/go-rec-nb-small.c \ + runtime/go-rec-small.c runtime/go-recover.c \ + runtime/go-reflect.c runtime/go-reflect-call.c \ + runtime/go-reflect-chan.c runtime/go-reflect-map.c \ + runtime/go-rune.c runtime/go-runtime-error.c \ + runtime/go-sched.c runtime/go-select.c runtime/go-semacquire.c \ runtime/go-send-big.c runtime/go-send-nb-big.c \ runtime/go-send-nb-small.c runtime/go-send-small.c \ runtime/go-setenv.c runtime/go-signal.c runtime/go-strcmp.c \ @@ -227,25 +227,25 @@ am__objects_3 = go-append.lo go-assert.lo go-assert-interface.lo \ go-gomaxprocs.lo go-int-array-to-string.lo go-int-to-string.lo \ go-interface-compare.lo go-interface-eface-compare.lo \ go-interface-val-compare.lo go-lock-os-thread.lo \ - go-map-delete.lo go-map-index.lo go-map-len.lo go-map-range.lo \ - go-nanotime.lo go-new-channel.lo go-new-map.lo go-new.lo \ - go-note.lo go-panic.lo go-panic-defer.lo go-print.lo \ - go-rec-big.lo go-rec-nb-big.lo go-rec-nb-small.lo \ - go-rec-small.lo go-recover.lo go-reflect.lo go-reflect-call.lo \ - go-reflect-chan.lo go-reflect-map.lo go-rune.lo \ - go-runtime-error.lo go-sched.lo go-select.lo go-semacquire.lo \ - go-send-big.lo go-send-nb-big.lo go-send-nb-small.lo \ - go-send-small.lo go-setenv.lo go-signal.lo go-strcmp.lo \ - go-string-to-byte-array.lo go-string-to-int-array.lo \ - go-strplus.lo go-strslice.lo go-trampoline.lo go-type-eface.lo \ - go-type-error.lo go-type-identity.lo go-type-interface.lo \ - go-type-string.lo go-typedesc-equal.lo go-typestring.lo \ - go-unreflect.lo go-unsafe-new.lo go-unsafe-newarray.lo \ - go-unsafe-pointer.lo go-unwind.lo cpuprof.lo mcache.lo \ - mcentral.lo $(am__objects_1) mfinal.lo mfixalloc.lo mgc0.lo \ - mheap.lo msize.lo proc.lo thread.lo $(am__objects_2) chan.lo \ - iface.lo malloc.lo map.lo mprof.lo reflect.lo sigqueue.lo \ - string.lo + go-make-slice.lo go-map-delete.lo go-map-index.lo \ + go-map-len.lo go-map-range.lo go-nanotime.lo go-new-channel.lo \ + go-new-map.lo go-new.lo go-note.lo go-panic.lo \ + go-panic-defer.lo go-print.lo go-rec-big.lo go-rec-nb-big.lo \ + go-rec-nb-small.lo go-rec-small.lo go-recover.lo go-reflect.lo \ + go-reflect-call.lo go-reflect-chan.lo go-reflect-map.lo \ + go-rune.lo go-runtime-error.lo go-sched.lo go-select.lo \ + go-semacquire.lo go-send-big.lo go-send-nb-big.lo \ + go-send-nb-small.lo go-send-small.lo go-setenv.lo go-signal.lo \ + go-strcmp.lo go-string-to-byte-array.lo \ + go-string-to-int-array.lo go-strplus.lo go-strslice.lo \ + go-trampoline.lo go-type-eface.lo go-type-error.lo \ + go-type-identity.lo go-type-interface.lo go-type-string.lo \ + go-typedesc-equal.lo go-typestring.lo go-unreflect.lo \ + go-unsafe-new.lo go-unsafe-newarray.lo go-unsafe-pointer.lo \ + go-unwind.lo cpuprof.lo mcache.lo mcentral.lo $(am__objects_1) \ + mfinal.lo mfixalloc.lo mgc0.lo mheap.lo msize.lo proc.lo \ + thread.lo $(am__objects_2) chan.lo iface.lo malloc.lo map.lo \ + mprof.lo reflect.lo sigqueue.lo string.lo am_libgo_la_OBJECTS = $(am__objects_3) libgo_la_OBJECTS = $(am_libgo_la_OBJECTS) libgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ @@ -800,6 +800,7 @@ runtime_files = \ runtime/go-interface-eface-compare.c \ runtime/go-interface-val-compare.c \ runtime/go-lock-os-thread.c \ + runtime/go-make-slice.c \ runtime/go-map-delete.c \ runtime/go-map-index.c \ runtime/go-map-len.c \ @@ -2309,6 +2310,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-interface-val-compare.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-lock-os-thread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-make-slice.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-map-delete.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-map-index.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-map-len.Plo@am__quote@ @@ -2610,6 +2612,13 @@ go-lock-os-thread.lo: runtime/go-lock-os-thread.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-lock-os-thread.lo `test -f 'runtime/go-lock-os-thread.c' || echo '$(srcdir)/'`runtime/go-lock-os-thread.c +go-make-slice.lo: runtime/go-make-slice.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-make-slice.lo -MD -MP -MF $(DEPDIR)/go-make-slice.Tpo -c -o go-make-slice.lo `test -f 'runtime/go-make-slice.c' || echo '$(srcdir)/'`runtime/go-make-slice.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-make-slice.Tpo $(DEPDIR)/go-make-slice.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-make-slice.c' object='go-make-slice.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-make-slice.lo `test -f 'runtime/go-make-slice.c' || echo '$(srcdir)/'`runtime/go-make-slice.c + go-map-delete.lo: runtime/go-map-delete.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-map-delete.lo -MD -MP -MF $(DEPDIR)/go-map-delete.Tpo -c -o go-map-delete.lo `test -f 'runtime/go-map-delete.c' || echo '$(srcdir)/'`runtime/go-map-delete.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-map-delete.Tpo $(DEPDIR)/go-map-delete.Plo diff --git a/libgo/runtime/go-make-slice.c b/libgo/runtime/go-make-slice.c new file mode 100644 index 00000000000..cd2d55bd538 --- /dev/null +++ b/libgo/runtime/go-make-slice.c @@ -0,0 +1,57 @@ +/* go-make-slice.c -- make a slice. + + Copyright 2011 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 <stdint.h> + +#include "go-alloc.h" +#include "go-assert.h" +#include "go-panic.h" +#include "go-type.h" +#include "array.h" +#include "runtime.h" +#include "malloc.h" + +struct __go_open_array +__go_make_slice2 (const struct __go_type_descriptor *td, uintptr_t len, + uintptr_t cap) +{ + const struct __go_slice_type* std; + int ilen; + int icap; + uintptr_t size; + struct __go_open_array ret; + unsigned int flag; + + __go_assert (td->__code == GO_SLICE); + std = (const struct __go_slice_type *) td; + + ilen = (int) len; + if (ilen < 0 || (uintptr_t) ilen != len) + __go_panic_msg ("makeslice: len out of range"); + + icap = (int) cap; + if (cap < len + || (uintptr_t) icap != cap + || cap > (uintptr_t) -1U / std->__element_type->__size) + __go_panic_msg ("makeslice: cap out of range"); + + ret.__count = ilen; + ret.__capacity = icap; + + size = cap * std->__element_type->__size; + flag = ((std->__element_type->__code & GO_NO_POINTERS) != 0 + ? FlagNoPointers + : 0); + ret.__values = runtime_mallocgc (size, flag, 1, 1); + + return ret; +} + +struct __go_open_array +__go_make_slice1 (const struct __go_type_descriptor *td, uintptr_t len) +{ + return __go_make_slice2 (td, len, len); +} diff --git a/libgo/runtime/go-map-delete.c b/libgo/runtime/go-map-delete.c index ec851e531d2..7a3a7b83d92 100644 --- a/libgo/runtime/go-map-delete.c +++ b/libgo/runtime/go-map-delete.c @@ -18,7 +18,7 @@ __go_map_delete (struct __go_map *map, const void *key) { const struct __go_map_descriptor *descriptor; const struct __go_type_descriptor *key_descriptor; - size_t key_offset; + uintptr_t key_offset; _Bool (*equalfn) (const void*, const void*, size_t); size_t key_hash; size_t key_size; diff --git a/libgo/runtime/go-map-index.c b/libgo/runtime/go-map-index.c index 02a0f73f224..a387c4b98bc 100644 --- a/libgo/runtime/go-map-index.c +++ b/libgo/runtime/go-map-index.c @@ -18,7 +18,7 @@ __go_map_rehash (struct __go_map *map) { const struct __go_map_descriptor *descriptor; const struct __go_type_descriptor *key_descriptor; - size_t key_offset; + uintptr_t key_offset; size_t key_size; size_t (*hashfn) (const void *, size_t); uintptr_t old_bucket_count; @@ -78,7 +78,7 @@ __go_map_index (struct __go_map *map, const void *key, _Bool insert) { const struct __go_map_descriptor *descriptor; const struct __go_type_descriptor *key_descriptor; - size_t key_offset; + uintptr_t key_offset; _Bool (*equalfn) (const void*, const void*, size_t); size_t key_hash; size_t key_size; diff --git a/libgo/runtime/go-new-channel.c b/libgo/runtime/go-new-channel.c index e440e873652..0c6f39185de 100644 --- a/libgo/runtime/go-new-channel.c +++ b/libgo/runtime/go-new-channel.c @@ -13,17 +13,26 @@ #include "channel.h" struct __go_channel* -__go_new_channel (const struct __go_type_descriptor *element_type, +__go_new_channel (const struct __go_type_descriptor *channel_type, uintptr_t entries) { + const struct __go_channel_type *ctd; + const struct __go_type_descriptor *element_type; uintptr_t element_size; + int ientries; struct __go_channel* ret; size_t alloc_size; int i; + __go_assert (channel_type->__code == GO_CHAN); + ctd = (const struct __go_channel_type *) channel_type; + element_type = ctd->__element_type; + element_size = element_type->__size; - if ((uintptr_t) (int) entries != entries + ientries = (int) entries; + if (ientries < 0 + || (uintptr_t) ientries != entries || entries > (uintptr_t) -1 / element_size) __go_panic_msg ("chan size out of range"); diff --git a/libgo/runtime/go-new-map.c b/libgo/runtime/go-new-map.c index 3a471299b22..05ac8a1a40c 100644 --- a/libgo/runtime/go-new-map.c +++ b/libgo/runtime/go-new-map.c @@ -106,9 +106,11 @@ __go_map_next_prime (uintptr_t n) struct __go_map * __go_new_map (const struct __go_map_descriptor *descriptor, uintptr_t entries) { + int ientries; struct __go_map *ret; - if ((uintptr_t) (int) entries != entries) + ientries = (int) entries; + if (ientries < 0 || (uintptr_t) ientries != entries) __go_panic_msg ("map size out of range"); if (entries == 0) diff --git a/libgo/runtime/go-reflect-call.c b/libgo/runtime/go-reflect-call.c index a769142c3df..27177e2fc73 100644 --- a/libgo/runtime/go-reflect-call.c +++ b/libgo/runtime/go-reflect-call.c @@ -161,7 +161,7 @@ go_complex_to_ffi (ffi_type *float_type) static ffi_type * go_type_to_ffi (const struct __go_type_descriptor *descriptor) { - switch (descriptor->__code) + switch (descriptor->__code & GO_CODE_MASK) { case GO_BOOL: if (sizeof (_Bool) == 1) diff --git a/libgo/runtime/go-reflect-chan.c b/libgo/runtime/go-reflect-chan.c index d568024b3df..61e360212f0 100644 --- a/libgo/runtime/go-reflect-chan.c +++ b/libgo/runtime/go-reflect-chan.c @@ -26,9 +26,6 @@ makechan (const struct __go_type_descriptor *typ, uint32_t size) struct __go_channel *channel; void *ret; - __go_assert (typ->__code == GO_CHAN); - typ = ((const struct __go_channel_type *) typ)->__element_type; - channel = __go_new_channel (typ, size); ret = __go_alloc (sizeof (void *)); diff --git a/libgo/runtime/go-reflect.c b/libgo/runtime/go-reflect.c index bf13a11fae2..af7d5e8968f 100644 --- a/libgo/runtime/go-reflect.c +++ b/libgo/runtime/go-reflect.c @@ -57,7 +57,7 @@ extern const struct __go_type_descriptor ptr_struct_descriptor const struct __go_type_descriptor * get_descriptor (int code) { - switch (code) + switch (code & GO_CODE_MASK) { case GO_BOOL: return &ptr_bool_descriptor; diff --git a/libgo/runtime/go-type.h b/libgo/runtime/go-type.h index e048141e93e..6e2193982d6 100644 --- a/libgo/runtime/go-type.h +++ b/libgo/runtime/go-type.h @@ -53,13 +53,17 @@ #define GO_STRUCT 25 #define GO_UNSAFE_POINTER 26 +#define GO_NO_POINTERS (1 << 7) + +#define GO_CODE_MASK 0x7f + /* For each Go type the compiler constructs one of these structures. This is used for type reflectin, interfaces, maps, and reference counting. */ struct __go_type_descriptor { - /* The type code for this type, a value in enum __go_type_codes. + /* The type code for this type, one of the type kind values above. This is used by unsafe.Reflect and unsafe.Typeof to determine the type descriptor to return for this type itself. It is also used by reflect.toType when mapping to a reflect Type structure. */ diff --git a/libgo/runtime/map.h b/libgo/runtime/map.h index 40c31f82315..0c587bb2afa 100644 --- a/libgo/runtime/map.h +++ b/libgo/runtime/map.h @@ -22,15 +22,15 @@ struct __go_map_descriptor key_type key; value_type value; This is the size of that struct. */ - size_t __entry_size; + uintptr_t __entry_size; /* The offset of the key field in a map entry struct. */ - size_t __key_offset; + uintptr_t __key_offset; /* The offset of the value field in a map entry struct (the value field immediately follows the key field, but there may be some bytes inserted for alignment). */ - size_t __val_offset; + uintptr_t __val_offset; }; struct __go_map diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 0e88ea3cc9e..7453b09ed0b 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,32 @@ +2011-06-20 Jason Merrill <jason@redhat.com> + + PR c++/37089 + * cp-demangle.c (d_print_comp): Handle reference smashing. + * testsuite/demangle-expected: Test it. + +2011-06-13 Jan Kratochvil <jan.kratochvil@redhat.com> + + * cp-demangle.c (d_print_comp) <DEMANGLE_COMPONENT_FUNCTION_TYPE>: + Suppress d_print_mod for DMGL_RET_POSTFIX. + * testsuite/demangle-expected: New testcases for --ret-postfix. + +2011-06-13 Jan Kratochvil <jan.kratochvil@redhat.com> + + * cp-demangle.c (d_print_comp) <DEMANGLE_COMPONENT_FUNCTION_TYPE>: Do + not pass DMGL_RET_POSTFIX or DMGL_RET_DROP. Support DMGL_RET_DROP. + * testsuite/demangle-expected: New testcases for --ret-drop. + * testsuite/test-demangle.c: Document --ret-drop in a comment. + (main): New variable ret_drop, fill it, call cplus_demangle with it. + +2011-06-13 Jan Kratochvil <jan.kratochvil@redhat.com> + + * cp-demangle.c (struct d_print_info): Remove field options. + (d_print_init): Remove parameter options. + (cplus_demangle_print_callback): Update all the callers. + (d_print_comp, d_print_mod_list, d_print_mod, d_print_function_type) + (d_print_array_type, d_print_expr_op, d_print_cast, d_print_subexpr): + Add parameter options, update all the callers. + 2011-04-20 Jim Meyering <meyering@redhat.com> * cp-demint.c (cplus_demangle_v3_components): Remove useless diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 7e951cc7842..d664e5f29ba 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -278,8 +278,6 @@ struct d_growable_string enum { D_PRINT_BUFFER_LENGTH = 256 }; struct d_print_info { - /* The options passed to the demangler. */ - int options; /* Fixed-length allocated buffer for demangled data, flushed to the callback with a NUL termination once full. */ char buf[D_PRINT_BUFFER_LENGTH]; @@ -436,7 +434,7 @@ static void d_growable_string_callback_adapter (const char *, size_t, void *); static void -d_print_init (struct d_print_info *, int, demangle_callbackref, void *); +d_print_init (struct d_print_info *, demangle_callbackref, void *); static inline void d_print_error (struct d_print_info *); @@ -454,32 +452,32 @@ static inline void d_append_string (struct d_print_info *, const char *); static inline char d_last_char (struct d_print_info *); static void -d_print_comp (struct d_print_info *, const struct demangle_component *); +d_print_comp (struct d_print_info *, int, const struct demangle_component *); static void d_print_java_identifier (struct d_print_info *, const char *, int); static void -d_print_mod_list (struct d_print_info *, struct d_print_mod *, int); +d_print_mod_list (struct d_print_info *, int, struct d_print_mod *, int); static void -d_print_mod (struct d_print_info *, const struct demangle_component *); +d_print_mod (struct d_print_info *, int, const struct demangle_component *); static void -d_print_function_type (struct d_print_info *, +d_print_function_type (struct d_print_info *, int, const struct demangle_component *, struct d_print_mod *); static void -d_print_array_type (struct d_print_info *, +d_print_array_type (struct d_print_info *, int, const struct demangle_component *, struct d_print_mod *); static void -d_print_expr_op (struct d_print_info *, const struct demangle_component *); +d_print_expr_op (struct d_print_info *, int, const struct demangle_component *); static void -d_print_cast (struct d_print_info *, const struct demangle_component *); +d_print_cast (struct d_print_info *, int, const struct demangle_component *); static int d_demangle_callback (const char *, int, demangle_callbackref, void *); @@ -3293,10 +3291,9 @@ d_growable_string_callback_adapter (const char *s, size_t l, void *opaque) /* Initialize a print information structure. */ static void -d_print_init (struct d_print_info *dpi, int options, - demangle_callbackref callback, void *opaque) +d_print_init (struct d_print_info *dpi, demangle_callbackref callback, + void *opaque) { - dpi->options = options; dpi->len = 0; dpi->last_char = '\0'; dpi->templates = NULL; @@ -3392,9 +3389,9 @@ cplus_demangle_print_callback (int options, { struct d_print_info dpi; - d_print_init (&dpi, options, callback, opaque); + d_print_init (&dpi, callback, opaque); - d_print_comp (&dpi, dc); + d_print_comp (&dpi, options, dc); d_print_flush (&dpi); @@ -3537,7 +3534,7 @@ d_pack_length (const struct demangle_component *dc) if needed. */ static void -d_print_subexpr (struct d_print_info *dpi, +d_print_subexpr (struct d_print_info *dpi, int options, const struct demangle_component *dc) { int simple = 0; @@ -3546,7 +3543,7 @@ d_print_subexpr (struct d_print_info *dpi, simple = 1; if (!simple) d_append_char (dpi, '('); - d_print_comp (dpi, dc); + d_print_comp (dpi, options, dc); if (!simple) d_append_char (dpi, ')'); } @@ -3554,9 +3551,13 @@ d_print_subexpr (struct d_print_info *dpi, /* Subroutine to handle components. */ static void -d_print_comp (struct d_print_info *dpi, +d_print_comp (struct d_print_info *dpi, int options, const struct demangle_component *dc) { + /* Magic variable to let reference smashing skip over the next modifier + without needing to modify *dc. */ + const struct demangle_component *mod_inner = NULL; + if (dc == NULL) { d_print_error (dpi); @@ -3568,7 +3569,7 @@ d_print_comp (struct d_print_info *dpi, switch (dc->type) { case DEMANGLE_COMPONENT_NAME: - if ((dpi->options & DMGL_JAVA) == 0) + if ((options & DMGL_JAVA) == 0) d_append_buffer (dpi, dc->u.s_name.s, dc->u.s_name.len); else d_print_java_identifier (dpi, dc->u.s_name.s, dc->u.s_name.len); @@ -3576,12 +3577,12 @@ d_print_comp (struct d_print_info *dpi, case DEMANGLE_COMPONENT_QUAL_NAME: case DEMANGLE_COMPONENT_LOCAL_NAME: - d_print_comp (dpi, d_left (dc)); - if ((dpi->options & DMGL_JAVA) == 0) + d_print_comp (dpi, options, d_left (dc)); + if ((options & DMGL_JAVA) == 0) d_append_string (dpi, "::"); else d_append_char (dpi, '.'); - d_print_comp (dpi, d_right (dc)); + d_print_comp (dpi, options, d_right (dc)); return; case DEMANGLE_COMPONENT_TYPED_NAME: @@ -3671,7 +3672,7 @@ d_print_comp (struct d_print_info *dpi, } } - d_print_comp (dpi, d_right (dc)); + d_print_comp (dpi, options, d_right (dc)); if (typed_name->type == DEMANGLE_COMPONENT_TEMPLATE) dpi->templates = dpt.next; @@ -3684,7 +3685,7 @@ d_print_comp (struct d_print_info *dpi, if (! adpm[i].printed) { d_append_char (dpi, ' '); - d_print_mod (dpi, adpm[i].mod); + d_print_mod (dpi, options, adpm[i].mod); } } @@ -3707,7 +3708,7 @@ d_print_comp (struct d_print_info *dpi, dcl = d_left (dc); - if ((dpi->options & DMGL_JAVA) != 0 + if ((options & DMGL_JAVA) != 0 && dcl->type == DEMANGLE_COMPONENT_NAME && dcl->u.s_name.len == 6 && strncmp (dcl->u.s_name.s, "JArray", 6) == 0) @@ -3715,16 +3716,16 @@ d_print_comp (struct d_print_info *dpi, /* Special-case Java arrays, so that JArray<TYPE> appears instead as TYPE[]. */ - d_print_comp (dpi, d_right (dc)); + d_print_comp (dpi, options, d_right (dc)); d_append_string (dpi, "[]"); } else { - d_print_comp (dpi, dcl); + d_print_comp (dpi, options, dcl); if (d_last_char (dpi) == '<') d_append_char (dpi, ' '); d_append_char (dpi, '<'); - d_print_comp (dpi, d_right (dc)); + d_print_comp (dpi, options, d_right (dc)); /* Avoid generating two consecutive '>' characters, to avoid the C++ syntactic ambiguity. */ if (d_last_char (dpi) == '>') @@ -3759,7 +3760,7 @@ d_print_comp (struct d_print_info *dpi, hold_dpt = dpi->templates; dpi->templates = hold_dpt->next; - d_print_comp (dpi, a); + d_print_comp (dpi, options, a); dpi->templates = hold_dpt; @@ -3767,79 +3768,79 @@ d_print_comp (struct d_print_info *dpi, } case DEMANGLE_COMPONENT_CTOR: - d_print_comp (dpi, dc->u.s_ctor.name); + d_print_comp (dpi, options, dc->u.s_ctor.name); return; case DEMANGLE_COMPONENT_DTOR: d_append_char (dpi, '~'); - d_print_comp (dpi, dc->u.s_dtor.name); + d_print_comp (dpi, options, dc->u.s_dtor.name); return; case DEMANGLE_COMPONENT_VTABLE: d_append_string (dpi, "vtable for "); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; case DEMANGLE_COMPONENT_VTT: d_append_string (dpi, "VTT for "); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE: d_append_string (dpi, "construction vtable for "); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); d_append_string (dpi, "-in-"); - d_print_comp (dpi, d_right (dc)); + d_print_comp (dpi, options, d_right (dc)); return; case DEMANGLE_COMPONENT_TYPEINFO: d_append_string (dpi, "typeinfo for "); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; case DEMANGLE_COMPONENT_TYPEINFO_NAME: d_append_string (dpi, "typeinfo name for "); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; case DEMANGLE_COMPONENT_TYPEINFO_FN: d_append_string (dpi, "typeinfo fn for "); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; case DEMANGLE_COMPONENT_THUNK: d_append_string (dpi, "non-virtual thunk to "); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; case DEMANGLE_COMPONENT_VIRTUAL_THUNK: d_append_string (dpi, "virtual thunk to "); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; case DEMANGLE_COMPONENT_COVARIANT_THUNK: d_append_string (dpi, "covariant return thunk to "); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; case DEMANGLE_COMPONENT_JAVA_CLASS: d_append_string (dpi, "java Class for "); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; case DEMANGLE_COMPONENT_GUARD: d_append_string (dpi, "guard variable for "); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; case DEMANGLE_COMPONENT_REFTEMP: d_append_string (dpi, "reference temporary for "); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; case DEMANGLE_COMPONENT_HIDDEN_ALIAS: d_append_string (dpi, "hidden alias for "); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; case DEMANGLE_COMPONENT_SUB_STD: @@ -3866,22 +3867,43 @@ d_print_comp (struct d_print_info *dpi, break; if (pdpm->mod->type == dc->type) { - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; } } } } + goto modifier; + + case DEMANGLE_COMPONENT_REFERENCE: + case DEMANGLE_COMPONENT_RVALUE_REFERENCE: + { + /* Handle reference smashing: & + && = &. */ + const struct demangle_component *sub = d_left (dc); + if (sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM) + { + struct demangle_component *a = d_lookup_template_argument (dpi, sub); + if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST) + a = d_index_template_argument (a, dpi->pack_index); + sub = a; + } + + if (sub->type == DEMANGLE_COMPONENT_REFERENCE + || sub->type == dc->type) + dc = sub; + else if (sub->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE) + mod_inner = d_left (sub); + } /* Fall through. */ + case DEMANGLE_COMPONENT_RESTRICT_THIS: case DEMANGLE_COMPONENT_VOLATILE_THIS: case DEMANGLE_COMPONENT_CONST_THIS: case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: case DEMANGLE_COMPONENT_POINTER: - case DEMANGLE_COMPONENT_REFERENCE: - case DEMANGLE_COMPONENT_RVALUE_REFERENCE: case DEMANGLE_COMPONENT_COMPLEX: case DEMANGLE_COMPONENT_IMAGINARY: + modifier: { /* We keep a list of modifiers on the stack. */ struct d_print_mod dpm; @@ -3892,12 +3914,15 @@ d_print_comp (struct d_print_info *dpi, dpm.printed = 0; dpm.templates = dpi->templates; - d_print_comp (dpi, d_left (dc)); + if (!mod_inner) + mod_inner = d_left (dc); + + d_print_comp (dpi, options, mod_inner); /* If the modifier didn't get printed by the type, print it now. */ if (! dpm.printed) - d_print_mod (dpi, dc); + d_print_mod (dpi, options, dc); dpi->modifiers = dpm.next; @@ -3905,7 +3930,7 @@ d_print_comp (struct d_print_info *dpi, } case DEMANGLE_COMPONENT_BUILTIN_TYPE: - if ((dpi->options & DMGL_JAVA) == 0) + if ((options & DMGL_JAVA) == 0) d_append_buffer (dpi, dc->u.s_builtin.type->name, dc->u.s_builtin.type->len); else @@ -3914,16 +3939,21 @@ d_print_comp (struct d_print_info *dpi, return; case DEMANGLE_COMPONENT_VENDOR_TYPE: - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; case DEMANGLE_COMPONENT_FUNCTION_TYPE: { - if ((dpi->options & DMGL_RET_POSTFIX) != 0) - d_print_function_type (dpi, dc, dpi->modifiers); + if ((options & DMGL_RET_POSTFIX) != 0) + d_print_function_type (dpi, + options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP), + dc, dpi->modifiers); /* Print return type if present */ - if (d_left (dc) != NULL) + if (d_left (dc) != NULL && (options & DMGL_RET_POSTFIX) != 0) + d_print_comp (dpi, options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP), + d_left (dc)); + else if (d_left (dc) != NULL && (options & DMGL_RET_DROP) == 0) { struct d_print_mod dpm; @@ -3935,7 +3965,8 @@ d_print_comp (struct d_print_info *dpi, dpm.printed = 0; dpm.templates = dpi->templates; - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP), + d_left (dc)); dpi->modifiers = dpm.next; @@ -3944,12 +3975,14 @@ d_print_comp (struct d_print_info *dpi, /* In standard prefix notation, there is a space between the return type and the function signature. */ - if ((dpi->options & DMGL_RET_POSTFIX) == 0) + if ((options & DMGL_RET_POSTFIX) == 0) d_append_char (dpi, ' '); } - if ((dpi->options & DMGL_RET_POSTFIX) == 0) - d_print_function_type (dpi, dc, dpi->modifiers); + if ((options & DMGL_RET_POSTFIX) == 0) + d_print_function_type (dpi, + options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP), + dc, dpi->modifiers); return; } @@ -4002,7 +4035,7 @@ d_print_comp (struct d_print_info *dpi, pdpm = pdpm->next; } - d_print_comp (dpi, d_right (dc)); + d_print_comp (dpi, options, d_right (dc)); dpi->modifiers = hold_modifiers; @@ -4012,10 +4045,10 @@ d_print_comp (struct d_print_info *dpi, while (i > 1) { --i; - d_print_mod (dpi, adpm[i].mod); + d_print_mod (dpi, options, adpm[i].mod); } - d_print_array_type (dpi, dc, dpi->modifiers); + d_print_array_type (dpi, options, dc, dpi->modifiers); return; } @@ -4031,12 +4064,12 @@ d_print_comp (struct d_print_info *dpi, dpm.printed = 0; dpm.templates = dpi->templates; - d_print_comp (dpi, d_right (dc)); + d_print_comp (dpi, options, d_right (dc)); /* If the modifier didn't get printed by the type, print it now. */ if (! dpm.printed) - d_print_mod (dpi, dc); + d_print_mod (dpi, options, dc); dpi->modifiers = dpm.next; @@ -4050,7 +4083,7 @@ d_print_comp (struct d_print_info *dpi, if (dc->u.s_fixed.length->u.s_builtin.type != &cplus_demangle_builtin_types['i'-'a']) { - d_print_comp (dpi, dc->u.s_fixed.length); + d_print_comp (dpi, options, dc->u.s_fixed.length); d_append_char (dpi, ' '); } if (dc->u.s_fixed.accum) @@ -4062,7 +4095,7 @@ d_print_comp (struct d_print_info *dpi, case DEMANGLE_COMPONENT_ARGLIST: case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST: if (d_left (dc) != NULL) - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); if (d_right (dc) != NULL) { size_t len; @@ -4074,7 +4107,7 @@ d_print_comp (struct d_print_info *dpi, d_append_string (dpi, ", "); len = dpi->len; flush_count = dpi->flush_count; - d_print_comp (dpi, d_right (dc)); + d_print_comp (dpi, options, d_right (dc)); /* If that didn't print anything (which can happen with empty template argument packs), remove the comma and space. */ if (dpi->flush_count == flush_count && dpi->len == len) @@ -4097,24 +4130,24 @@ d_print_comp (struct d_print_info *dpi, case DEMANGLE_COMPONENT_EXTENDED_OPERATOR: d_append_string (dpi, "operator "); - d_print_comp (dpi, dc->u.s_extended_operator.name); + d_print_comp (dpi, options, dc->u.s_extended_operator.name); return; case DEMANGLE_COMPONENT_CAST: d_append_string (dpi, "operator "); - d_print_cast (dpi, dc); + d_print_cast (dpi, options, dc); return; case DEMANGLE_COMPONENT_UNARY: if (d_left (dc)->type != DEMANGLE_COMPONENT_CAST) - d_print_expr_op (dpi, d_left (dc)); + d_print_expr_op (dpi, options, d_left (dc)); else { d_append_char (dpi, '('); - d_print_cast (dpi, d_left (dc)); + d_print_cast (dpi, options, d_left (dc)); d_append_char (dpi, ')'); } - d_print_subexpr (dpi, d_right (dc)); + d_print_subexpr (dpi, options, d_right (dc)); return; case DEMANGLE_COMPONENT_BINARY: @@ -4132,18 +4165,18 @@ d_print_comp (struct d_print_info *dpi, && d_left (dc)->u.s_operator.op->name[0] == '>') d_append_char (dpi, '('); - d_print_subexpr (dpi, d_left (d_right (dc))); + d_print_subexpr (dpi, options, d_left (d_right (dc))); if (strcmp (d_left (dc)->u.s_operator.op->code, "ix") == 0) { d_append_char (dpi, '['); - d_print_comp (dpi, d_right (d_right (dc))); + d_print_comp (dpi, options, d_right (d_right (dc))); d_append_char (dpi, ']'); } else { if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0) - d_print_expr_op (dpi, d_left (dc)); - d_print_subexpr (dpi, d_right (d_right (dc))); + d_print_expr_op (dpi, options, d_left (dc)); + d_print_subexpr (dpi, options, d_right (d_right (dc))); } if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR @@ -4165,11 +4198,11 @@ d_print_comp (struct d_print_info *dpi, d_print_error (dpi); return; } - d_print_subexpr (dpi, d_left (d_right (dc))); - d_print_expr_op (dpi, d_left (dc)); - d_print_subexpr (dpi, d_left (d_right (d_right (dc)))); + d_print_subexpr (dpi, options, d_left (d_right (dc))); + d_print_expr_op (dpi, options, d_left (dc)); + d_print_subexpr (dpi, options, d_left (d_right (d_right (dc)))); d_append_string (dpi, " : "); - d_print_subexpr (dpi, d_right (d_right (d_right (dc)))); + d_print_subexpr (dpi, options, d_right (d_right (d_right (dc)))); return; case DEMANGLE_COMPONENT_TRINARY_ARG1: @@ -4200,7 +4233,7 @@ d_print_comp (struct d_print_info *dpi, { if (dc->type == DEMANGLE_COMPONENT_LITERAL_NEG) d_append_char (dpi, '-'); - d_print_comp (dpi, d_right (dc)); + d_print_comp (dpi, options, d_right (dc)); switch (tp) { default: @@ -4250,13 +4283,13 @@ d_print_comp (struct d_print_info *dpi, } d_append_char (dpi, '('); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); d_append_char (dpi, ')'); if (dc->type == DEMANGLE_COMPONENT_LITERAL_NEG) d_append_char (dpi, '-'); if (tp == D_PRINT_FLOAT) d_append_char (dpi, '['); - d_print_comp (dpi, d_right (dc)); + d_print_comp (dpi, options, d_right (dc)); if (tp == D_PRINT_FLOAT) d_append_char (dpi, ']'); } @@ -4268,12 +4301,12 @@ d_print_comp (struct d_print_info *dpi, case DEMANGLE_COMPONENT_JAVA_RESOURCE: d_append_string (dpi, "java resource "); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); return; case DEMANGLE_COMPONENT_COMPOUND_NAME: - d_print_comp (dpi, d_left (dc)); - d_print_comp (dpi, d_right (dc)); + d_print_comp (dpi, options, d_left (dc)); + d_print_comp (dpi, options, d_right (dc)); return; case DEMANGLE_COMPONENT_CHARACTER: @@ -4282,7 +4315,7 @@ d_print_comp (struct d_print_info *dpi, case DEMANGLE_COMPONENT_DECLTYPE: d_append_string (dpi, "decltype ("); - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); d_append_char (dpi, ')'); return; @@ -4296,7 +4329,7 @@ d_print_comp (struct d_print_info *dpi, /* d_find_pack won't find anything if the only packs involved in this expansion are function parameter packs; in that case, just print the pattern and "...". */ - d_print_subexpr (dpi, d_left (dc)); + d_print_subexpr (dpi, options, d_left (dc)); d_append_string (dpi, "..."); return; } @@ -4306,7 +4339,7 @@ d_print_comp (struct d_print_info *dpi, for (i = 0; i < len; ++i) { dpi->pack_index = i; - d_print_comp (dpi, dc); + d_print_comp (dpi, options, dc); if (i < len-1) d_append_string (dpi, ", "); } @@ -4321,17 +4354,17 @@ d_print_comp (struct d_print_info *dpi, case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS: d_append_string (dpi, "global constructors keyed to "); - d_print_comp (dpi, dc->u.s_binary.left); + d_print_comp (dpi, options, dc->u.s_binary.left); return; case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS: d_append_string (dpi, "global destructors keyed to "); - d_print_comp (dpi, dc->u.s_binary.left); + d_print_comp (dpi, options, dc->u.s_binary.left); return; case DEMANGLE_COMPONENT_LAMBDA: d_append_string (dpi, "{lambda("); - d_print_comp (dpi, dc->u.s_unary_num.sub); + d_print_comp (dpi, options, dc->u.s_unary_num.sub); d_append_string (dpi, ")#"); d_append_num (dpi, dc->u.s_unary_num.num + 1); d_append_char (dpi, '}'); @@ -4405,7 +4438,7 @@ d_print_java_identifier (struct d_print_info *dpi, const char *name, int len) qualifiers on this after printing a function. */ static void -d_print_mod_list (struct d_print_info *dpi, +d_print_mod_list (struct d_print_info *dpi, int options, struct d_print_mod *mods, int suffix) { struct d_print_template *hold_dpt; @@ -4419,7 +4452,7 @@ d_print_mod_list (struct d_print_info *dpi, || mods->mod->type == DEMANGLE_COMPONENT_VOLATILE_THIS || mods->mod->type == DEMANGLE_COMPONENT_CONST_THIS))) { - d_print_mod_list (dpi, mods->next, suffix); + d_print_mod_list (dpi, options, mods->next, suffix); return; } @@ -4430,13 +4463,13 @@ d_print_mod_list (struct d_print_info *dpi, if (mods->mod->type == DEMANGLE_COMPONENT_FUNCTION_TYPE) { - d_print_function_type (dpi, mods->mod, mods->next); + d_print_function_type (dpi, options, mods->mod, mods->next); dpi->templates = hold_dpt; return; } else if (mods->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE) { - d_print_array_type (dpi, mods->mod, mods->next); + d_print_array_type (dpi, options, mods->mod, mods->next); dpi->templates = hold_dpt; return; } @@ -4452,10 +4485,10 @@ d_print_mod_list (struct d_print_info *dpi, hold_modifiers = dpi->modifiers; dpi->modifiers = NULL; - d_print_comp (dpi, d_left (mods->mod)); + d_print_comp (dpi, options, d_left (mods->mod)); dpi->modifiers = hold_modifiers; - if ((dpi->options & DMGL_JAVA) == 0) + if ((options & DMGL_JAVA) == 0) d_append_string (dpi, "::"); else d_append_char (dpi, '.'); @@ -4475,23 +4508,23 @@ d_print_mod_list (struct d_print_info *dpi, || dc->type == DEMANGLE_COMPONENT_CONST_THIS) dc = d_left (dc); - d_print_comp (dpi, dc); + d_print_comp (dpi, options, dc); dpi->templates = hold_dpt; return; } - d_print_mod (dpi, mods->mod); + d_print_mod (dpi, options, mods->mod); dpi->templates = hold_dpt; - d_print_mod_list (dpi, mods->next, suffix); + d_print_mod_list (dpi, options, mods->next, suffix); } /* Print a modifier. */ static void -d_print_mod (struct d_print_info *dpi, +d_print_mod (struct d_print_info *dpi, int options, const struct demangle_component *mod) { switch (mod->type) @@ -4510,11 +4543,11 @@ d_print_mod (struct d_print_info *dpi, return; case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL: d_append_char (dpi, ' '); - d_print_comp (dpi, d_right (mod)); + d_print_comp (dpi, options, d_right (mod)); return; case DEMANGLE_COMPONENT_POINTER: /* There is no pointer symbol in Java. */ - if ((dpi->options & DMGL_JAVA) == 0) + if ((options & DMGL_JAVA) == 0) d_append_char (dpi, '*'); return; case DEMANGLE_COMPONENT_REFERENCE: @@ -4532,22 +4565,22 @@ d_print_mod (struct d_print_info *dpi, case DEMANGLE_COMPONENT_PTRMEM_TYPE: if (d_last_char (dpi) != '(') d_append_char (dpi, ' '); - d_print_comp (dpi, d_left (mod)); + d_print_comp (dpi, options, d_left (mod)); d_append_string (dpi, "::*"); return; case DEMANGLE_COMPONENT_TYPED_NAME: - d_print_comp (dpi, d_left (mod)); + d_print_comp (dpi, options, d_left (mod)); return; case DEMANGLE_COMPONENT_VECTOR_TYPE: d_append_string (dpi, " __vector("); - d_print_comp (dpi, d_left (mod)); + d_print_comp (dpi, options, d_left (mod)); d_append_char (dpi, ')'); return; default: /* Otherwise, we have something that won't go back on the modifier stack, so we can just print it. */ - d_print_comp (dpi, mod); + d_print_comp (dpi, options, mod); return; } } @@ -4555,7 +4588,7 @@ d_print_mod (struct d_print_info *dpi, /* Print a function type, except for the return type. */ static void -d_print_function_type (struct d_print_info *dpi, +d_print_function_type (struct d_print_info *dpi, int options, const struct demangle_component *dc, struct d_print_mod *mods) { @@ -4615,7 +4648,7 @@ d_print_function_type (struct d_print_info *dpi, hold_modifiers = dpi->modifiers; dpi->modifiers = NULL; - d_print_mod_list (dpi, mods, 0); + d_print_mod_list (dpi, options, mods, 0); if (need_paren) d_append_char (dpi, ')'); @@ -4623,11 +4656,11 @@ d_print_function_type (struct d_print_info *dpi, d_append_char (dpi, '('); if (d_right (dc) != NULL) - d_print_comp (dpi, d_right (dc)); + d_print_comp (dpi, options, d_right (dc)); d_append_char (dpi, ')'); - d_print_mod_list (dpi, mods, 1); + d_print_mod_list (dpi, options, mods, 1); dpi->modifiers = hold_modifiers; } @@ -4635,7 +4668,7 @@ d_print_function_type (struct d_print_info *dpi, /* Print an array type, except for the element type. */ static void -d_print_array_type (struct d_print_info *dpi, +d_print_array_type (struct d_print_info *dpi, int options, const struct demangle_component *dc, struct d_print_mod *mods) { @@ -4669,7 +4702,7 @@ d_print_array_type (struct d_print_info *dpi, if (need_paren) d_append_string (dpi, " ("); - d_print_mod_list (dpi, mods, 0); + d_print_mod_list (dpi, options, mods, 0); if (need_paren) d_append_char (dpi, ')'); @@ -4681,7 +4714,7 @@ d_print_array_type (struct d_print_info *dpi, d_append_char (dpi, '['); if (d_left (dc) != NULL) - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); d_append_char (dpi, ']'); } @@ -4689,24 +4722,24 @@ d_print_array_type (struct d_print_info *dpi, /* Print an operator in an expression. */ static void -d_print_expr_op (struct d_print_info *dpi, +d_print_expr_op (struct d_print_info *dpi, int options, const struct demangle_component *dc) { if (dc->type == DEMANGLE_COMPONENT_OPERATOR) d_append_buffer (dpi, dc->u.s_operator.op->name, dc->u.s_operator.op->len); else - d_print_comp (dpi, dc); + d_print_comp (dpi, options, dc); } /* Print a cast. */ static void -d_print_cast (struct d_print_info *dpi, +d_print_cast (struct d_print_info *dpi, int options, const struct demangle_component *dc) { if (d_left (dc)->type != DEMANGLE_COMPONENT_TEMPLATE) - d_print_comp (dpi, d_left (dc)); + d_print_comp (dpi, options, d_left (dc)); else { struct d_print_mod *hold_dpm; @@ -4724,14 +4757,14 @@ d_print_cast (struct d_print_info *dpi, dpi->templates = &dpt; dpt.template_decl = d_left (dc); - d_print_comp (dpi, d_left (d_left (dc))); + d_print_comp (dpi, options, d_left (d_left (dc))); dpi->templates = dpt.next; if (d_last_char (dpi) == '<') d_append_char (dpi, ' '); d_append_char (dpi, '<'); - d_print_comp (dpi, d_right (d_left (dc))); + d_print_comp (dpi, options, d_right (d_left (dc))); /* Avoid generating two consecutive '>' characters, to avoid the C++ syntactic ambiguity. */ if (d_last_char (dpi) == '>') diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index 5ce0377b13b..bbd418c8b9e 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -3957,8 +3957,38 @@ decltype (({parm#1}.(operator-))()) h<A>(A) _Z1fDn f(decltype(nullptr)) --format=gnu-v3 +_Z1fIRiEvOT_b +void f<int&>(int&, bool) +--format=gnu-v3 _ZN5aaaaa6bbbbbb5cccccIN23ddddddddddddddddddddddd3eeeENS2_4ffff16ggggggggggggggggENS0_9hhhhhhhhhES6_S6_S6_S6_S6_S6_S6_EE aaaaa::bbbbbb::ccccc<ddddddddddddddddddddddd::eee, ddddddddddddddddddddddd::ffff::gggggggggggggggg, aaaaa::bbbbbb::hhhhhhhhh, aaaaa::bbbbbb::hhhhhhhhh, aaaaa::bbbbbb::hhhhhhhhh, aaaaa::bbbbbb::hhhhhhhhh, aaaaa::bbbbbb::hhhhhhhhh, aaaaa::bbbbbb::hhhhhhhhh, aaaaa::bbbbbb::hhhhhhhhh, aaaaa::bbbbbb::hhhhhhhhh> +--format=gnu-v3 +_Z5outerIsEcPFilE +char outer<short>(int (*)(long)) +--format=gnu-v3 +_Z5outerPFsiEl +outer(short (*)(int), long) +--format=gnu-v3 +_Z6outer2IsEPFilES1_ +int (*outer2<short>(int (*)(long)))(long) +--format=gnu-v3 --ret-postfix +_Z5outerIsEcPFilE +outer<short>(int (*)(long))char +--format=gnu-v3 --ret-postfix +_Z5outerPFsiEl +outer(short (*)(int), long) +--format=gnu-v3 --ret-postfix +_Z6outer2IsEPFilES1_ +outer2<short>(int (*)(long))int (*)(long) +--format=gnu-v3 --ret-drop +_Z5outerIsEcPFilE +outer<short>(int (*)(long)) +--format=gnu-v3 --ret-drop +_Z5outerPFsiEl +outer(short (*)(int), long) +--format=gnu-v3 --ret-drop +_Z6outer2IsEPFilES1_ +outer2<short>(int (*)(long)) # # Ada (GNAT) tests. # @@ -4091,4 +4121,4 @@ DFA # http://sourceware.org/bugzilla/show_bug.cgi?id=11572 --format=auto _ZN3Psi7VariantIIcPKcEE5visitIIRZN11VariantTest9TestVisit11test_methodEvEUlS2_E0_RZNS6_11test_methodEvEUlcE1_RZNS6_11test_methodEvEUlNS_4NoneEE_EEENS_13VariantDetail19SelectVisitorResultIIDpT_EE4typeEDpOSG_ -Psi::VariantDetail::SelectVisitorResult<VariantTest::TestVisit::test_method()::{lambda(char const*)#2}&, VariantTest::TestVisit::test_method()::{lambda(char)#3}&, VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&>::type Psi::Variant<char, char const*>::visit<VariantTest::TestVisit::test_method()::{lambda(char const*)#2}&, VariantTest::TestVisit::test_method()::{lambda(char)#3}&, VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&>((VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&&&)...) +Psi::VariantDetail::SelectVisitorResult<VariantTest::TestVisit::test_method()::{lambda(char const*)#2}&, VariantTest::TestVisit::test_method()::{lambda(char)#3}&, VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&>::type Psi::Variant<char, char const*>::visit<VariantTest::TestVisit::test_method()::{lambda(char const*)#2}&, VariantTest::TestVisit::test_method()::{lambda(char)#3}&, VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&>((VariantTest::TestVisit::test_method()::{lambda(Psi::None)#1}&)...) diff --git a/libiberty/testsuite/test-demangle.c b/libiberty/testsuite/test-demangle.c index 1c982d6ef20..11d9729999b 100644 --- a/libiberty/testsuite/test-demangle.c +++ b/libiberty/testsuite/test-demangle.c @@ -159,6 +159,7 @@ exp: %s\n", output is an integer representing ctor_kind. --is-v3-dtor Likewise, but for dtors. --ret-postfix Passes the DMGL_RET_POSTFIX option + --ret-drop Passes the DMGL_RET_DROP option For compatibility, just in case it matters, the options line may be empty, to mean --format=auto. If it doesn't start with --, then it @@ -174,7 +175,7 @@ main(argc, argv) int no_params; int is_v3_ctor; int is_v3_dtor; - int ret_postfix; + int ret_postfix, ret_drop; struct line format; struct line input; struct line expect; @@ -209,6 +210,7 @@ main(argc, argv) no_params = 0; ret_postfix = 0; + ret_drop = 0; is_v3_ctor = 0; is_v3_dtor = 0; if (format.data[0] == '\0') @@ -265,6 +267,8 @@ main(argc, argv) is_v3_dtor = 1; else if (strcmp (opt, "--ret-postfix") == 0) ret_postfix = 1; + else if (strcmp (opt, "--ret-drop") == 0) + ret_drop = 1; else { printf ("FAIL at line %d: unrecognized option %s\n", @@ -307,9 +311,9 @@ main(argc, argv) cplus_demangle_set_style (style); - result = cplus_demangle (inp, - DMGL_PARAMS|DMGL_ANSI|DMGL_TYPES - |(ret_postfix ? DMGL_RET_POSTFIX : 0)); + result = cplus_demangle (inp, (DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES + | (ret_postfix ? DMGL_RET_POSTFIX : 0) + | (ret_drop ? DMGL_RET_DROP : 0))); if (result ? strcmp (result, expect.data) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 4ca6cf4c4e0..c800bf3aac0 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,26 @@ +2011-06-17 Jack Howarth <howarth@bromo.med.uc.edu> + + PR target/49461 + * libjava/configure.ac (SYSTEMSPEC): Pass -no_pie for darwin11. + * libjava/configure: Regenerate. + +2011-06-17 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + PR libgcj/49315 + * include/solaris-signal.h: Rename to ... + * include/posix-signal.h: ... this. + (SA_FLAGS): Define. + (SIGNAL_HANDLER): Handle non-SA_SIGINFO case. + (sa_signal_handler): Define. + (_INIT_SIG_HANDLER): New macro. + (INIT_SEGV, INIT_FPE): Use it. + * configure.ac (SIGNAL_HANDLER): Use it on alpha*-dec-osf*, + mips-sgi-irix*, *-*-solaris2* + * configure: Regenerate. + * include/aix-signal.h: Refer to AIX. + * configure.host (alpha*-dec-osf*): Enable can_unwind_signal. + (mips-sgi-irix6*): Likewise. + 2011-05-31 H.J. Lu <hongjiu.lu@intel.com> PR libgcj/49193 diff --git a/libjava/configure b/libjava/configure index 7681b12fdf8..4c3ab55746b 100755 --- a/libjava/configure +++ b/libjava/configure @@ -19788,9 +19788,14 @@ case "${host}" in SYSTEMSPEC="-lunicows $SYSTEMSPEC" fi ;; - *-*-darwin[912]*) + *-*-darwin9*) SYSTEMSPEC="%{!Zdynamiclib:%{!Zbundle:-allow_stack_execute}}" ;; + *-*-darwin[12]*) + # Something is incompatible with pie, would be nice to fix it and + # remove -no_pie. PR49461 + SYSTEMSPEC="-no_pie %{!Zdynamiclib:%{!Zbundle:-allow_stack_execute}}" + ;; *) SYSTEMSPEC= ;; @@ -24215,12 +24220,12 @@ SYSDEP_SOURCES= SIGNAL_HANDLER_AUX= case "${host}" in + alpha*-dec-osf* | mips-sgi-irix* | *-*-solaris2*) + SIGNAL_HANDLER=include/posix-signal.h + ;; i?86-*-linux*) SIGNAL_HANDLER=include/i386-signal.h ;; - *-*-solaris2*) - SIGNAL_HANDLER=include/solaris-signal.h - ;; # ia64-*) # SYSDEP_SOURCES=sysdep/ia64.c # test -d sysdep || mkdir sysdep diff --git a/libjava/configure.ac b/libjava/configure.ac index 4cfd49fd56f..5f673ea7cfd 100644 --- a/libjava/configure.ac +++ b/libjava/configure.ac @@ -898,9 +898,14 @@ case "${host}" in SYSTEMSPEC="-lunicows $SYSTEMSPEC" fi ;; - *-*-darwin[[912]]*) + *-*-darwin9*) SYSTEMSPEC="%{!Zdynamiclib:%{!Zbundle:-allow_stack_execute}}" ;; + *-*-darwin[[12]]*) + # Something is incompatible with pie, would be nice to fix it and + # remove -no_pie. PR49461 + SYSTEMSPEC="-no_pie %{!Zdynamiclib:%{!Zbundle:-allow_stack_execute}}" + ;; *) SYSTEMSPEC= ;; @@ -1727,12 +1732,12 @@ SYSDEP_SOURCES= SIGNAL_HANDLER_AUX= case "${host}" in + alpha*-dec-osf* | mips-sgi-irix* | *-*-solaris2*) + SIGNAL_HANDLER=include/posix-signal.h + ;; i?86-*-linux*) SIGNAL_HANDLER=include/i386-signal.h ;; - *-*-solaris2*) - SIGNAL_HANDLER=include/solaris-signal.h - ;; # ia64-*) # SYSDEP_SOURCES=sysdep/ia64.c # test -d sysdep || mkdir sysdep diff --git a/libjava/configure.host b/libjava/configure.host index 9d4f2b6a1db..fab8c603a81 100644 --- a/libjava/configure.host +++ b/libjava/configure.host @@ -274,7 +274,10 @@ EOF rm -f conftest conftest.c fi ;; - i[34567]86*-kfreebsd*-gnu | x86_64*-kfreebsd*-gnu) + alpha*-dec-osf*) + can_unwind_signal=yes + ;; + i[34567]86*-kfreebsd*-gnu | x86_64*-kfreebsd*-gnu) libgcj_ld_symbolic='-Wl,-Bsymbolic' slow_pthread_self= ;; @@ -283,6 +286,7 @@ EOF DIVIDESPEC=-f%{m32:no-}%{!m32:%{!m64:no-}}%{m64:}use-divide-subroutine ;; mips-sgi-irix6* ) + can_unwind_signal=yes sysdeps_dir=mips ;; arm*-linux* ) diff --git a/libjava/include/aix-signal.h b/libjava/include/aix-signal.h index abf37229235..896aa8e5503 100644 --- a/libjava/include/aix-signal.h +++ b/libjava/include/aix-signal.h @@ -1,7 +1,7 @@ /* aix-signal.h - Catch runtime signals and turn them into exceptions, - on a Darwin system. */ + on a AIX system. */ -/* Copyright (C) 2008 Free Software Foundation +/* Copyright (C) 2008, 2011 Free Software Foundation This file is part of libgcj. diff --git a/libjava/include/posix-signal.h b/libjava/include/posix-signal.h new file mode 100644 index 00000000000..726fde3a66e --- /dev/null +++ b/libjava/include/posix-signal.h @@ -0,0 +1,60 @@ +// posix-signal.h - Catch runtime signals and turn them into exceptions. + +/* Copyright (C) 1998, 1999, 2000, 2009, 2011 Free Software Foundation + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +#ifndef JAVA_SIGNAL_H +#define JAVA_SIGNAL_H 1 + +#include <signal.h> + +#define HANDLE_SEGV 1 +#define HANDLE_FPE 1 + +/* Different implementations of MD_FALLBACK_FRAME_STATE_FOR either require + SA_SIGINFO being set or fail if so. Cf. gcc/ada/init.c + (__gnat_install_handler) for details. */ + +#if (defined __alpha__ && defined __osf__) \ + || (defined __sun__ && defined __svr4__) +#define SA_FLAGS SA_NODEFER | SA_SIGINFO +#elif defined __sgi__ +#define SA_FLAGS SA_NODEFER +#else +#error Must define SA_FLAGS. +#endif + +#if SA_FLAGS & SA_SIGINFO +#define SIGNAL_HANDLER(_name) \ +static void _Jv_##_name (int, \ + siginfo_t *_si __attribute__ ((__unused__)), \ + void *_uc __attribute__ ((__unused__))) +#define sa_signal_handler sa_sigaction +#else +#define SIGNAL_HANDLER(_name) \ +static void _Jv_##_name (int) +#define sa_signal_handler sa_handler +#endif + +#define MAKE_THROW_FRAME(_exception) + +#define _INIT_SIG_HANDLER(_SIG, _ACTION) \ +do \ + { \ + struct sigaction act; \ + act.sa_signal_handler = _Jv_##_ACTION; \ + act.sa_flags = SA_FLAGS; \ + sigemptyset (&act.sa_mask); \ + sigaction(_SIG, &act, NULL); \ + } \ +while (0) + +#define INIT_SEGV _INIT_SIG_HANDLER (SIGSEGV, catch_segv) +#define INIT_FPE _INIT_SIG_HANDLER (SIGFPE, catch_fpe) + +#endif /* JAVA_SIGNAL_H */ diff --git a/libjava/include/solaris-signal.h b/libjava/include/solaris-signal.h deleted file mode 100644 index a936afe067f..00000000000 --- a/libjava/include/solaris-signal.h +++ /dev/null @@ -1,48 +0,0 @@ -// sparc-signal.h - Catch runtime signals and turn them into exceptions. - -/* Copyright (C) 1998, 1999, 2000, 2009 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ - -#ifndef JAVA_SIGNAL_H -#define JAVA_SIGNAL_H 1 - -#include <signal.h> - -#define HANDLE_SEGV 1 -#define HANDLE_FPE 1 - -#define SIGNAL_HANDLER(_name) \ -static void _Jv_##_name (int, \ - siginfo_t *_si __attribute__ ((__unused__)), \ - void *_uc __attribute__ ((__unused__))) - -#define MAKE_THROW_FRAME(_exception) - -#define INIT_SEGV \ -do \ - { \ - struct sigaction act; \ - act.sa_sigaction = _Jv_catch_segv; \ - act.sa_flags = SA_SIGINFO | SA_NODEFER; \ - sigemptyset (&act.sa_mask); \ - sigaction (SIGSEGV, &act, NULL); \ - } \ -while (0) - -#define INIT_FPE \ -do \ - { \ - struct sigaction act; \ - act.sa_sigaction = _Jv_catch_fpe; \ - act.sa_flags = SA_SIGINFO | SA_NODEFER; \ - sigemptyset (&act.sa_mask); \ - sigaction (SIGFPE, &act, NULL); \ - } \ -while (0) - -#endif /* JAVA_SIGNAL_H */ diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index f96b961c2f5..42f951478e7 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,95 @@ +2011-06-20 Daniel Krugler <daniel.kruegler@googlemail.com> + Paolo Carlini <paolo.carlini@oracle.com> + + * include/std/tuple (__conv_types, __one_by_one_convertible, + __all_convertible): Add. + (tuple): Use the latter. + (tuple<_T1>): Remove. + * testsuite/20_util/uses_allocator/cons_neg.cc: Adjust dg-error + line number. + * testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Likewise. + +2011-06-14 Jonathan Wakely <jwakely.gcc@gmail.com> + + * include/bits/ptr_traits.h (pointer_traits<T*>::pointer_to): Use + noexcept. + +2011-06-14 Paolo Carlini <paolo.carlini@oracle.com> + + * include/std/valarray (~valarray): Use noexcept. + * include/bits/unique_ptr.h (~unique_ptr): Likewise. + * testsuite/26_numerics/valarray/noexcept_move_construct.cc: New. + * testsuite/20_util/shared_ptr/cons/noexcept_move_construct.cc: + Likewise. + * testsuite/20_util/unique_ptr/cons/noexcept_move_construct.cc: + Likewise. + * testsuite/20_util/weak_ptr/cons/noexcept_move_construct.cc: + Likewise. + +2011-06-14 Paolo Carlini <paolo.carlini@oracle.com> + + * include/std/functional: Use noexcept. + * include/bits/stl_tempbuf.h: Likewise. + +2011-06-12 François Dumont <francois.cppdevs@free.fr> + Paolo Carlini <paolo.carlini@oracle.com> + + * include/bits/allocator.h (__shrink_to_fit): Rename to + __shrink_to_fit_aux, fix. + * include/bits/stl_vector.h (_M_shrink_to_fit): Declare. + (shrink_to_fit): Use the latter. + * include/debug/vector (shrink_to_fit): Likewise. + * include/bits/vector.tcc (_M_shrink_to_fit): Define. + * include/bits/stl_deque.h (_M_shrink_to_fit): Declare. + (shrink_to_fit): Use the latter. + * include/debug/deque (shrink_to_fit): Likewise. + * include/bits/deque.tcc (_M_shrink_to_fit): Define. + * include/bits/vector.tcc (vector<bool>::_M_reallocate): Add. + * include/bits/stl_bvector.h (_M_shrink_to_fit): Declare. + (shrink_to_fit): Use the latter. + (reserve): Use _M_reallocate, move inline. + (_Bvector_base<>::_S_nword): Add, use it throughout. + * include/debug/string (shrink_to_fit): Redo. + * include/ext/vstring.h (shrink_to_fit): Optimize. + * include/bits/basic_string.h (shrink_to_fit): Likewise. + * testsuite/21_strings/debug/shrink_to_fit.cc: New. + * testsuite/23_containers/vector/debug/shrink_to_fit.cc: Likewise. + * testsuite/23_containers/vector/debug/bool/shrink_to_fit.cc: + Likewise. + * testsuite/23_containers/vector/bool/capacity/shrink_to_fit.cc: + Likewise. + * testsuite/23_containers/deque/debug/shrink_to_fit.cc: Likewise. + +2011-06-11 Jonathan Wakely <jwakely.gcc@gmail.com> + + * testsuite/tr1/6_containers/tuple/creation_functions/tie2.cc: Fix for + C++0x mode. + * testsuite/25_algorithms/sort/35588.cc: Likewise. + * testsuite/26_numerics/headers/complex/synopsis.cc: Likewise. + +2011-06-11 Jonathan Wakely <jwakely.gcc@gmail.com> + + * include/ext/extptr_allocator.h (construct, destroy): Fix for C++0x + mode by overloading to take allocator's pointer type. + * testsuite/23_containers/vector/ext_pointer/types/2.cc: New. + * testsuite/23_containers/vector/ext_pointer/explicit_instantiation/ + 2.cc: New. + +2011-06-11 Jonathan Wakely <jwakely.gcc@gmail.com> + + * testsuite/20_util/allocator_traits/requirements/ + explicit_instantiation.cc: Add another instantiation. + +2011-06-11 Jonathan Wakely <jwakely.gcc@gmail.com> + + * testsuite/20_util/allocator_traits/requirements/typedefs.cc: Check + for allocator_type and value_type. + +2011-06-11 Jonathan Wakely <jwakely.gcc@gmail.com> + + * testsuite/30_threads/packaged_task/uses_allocator.cc: New. + * testsuite/30_threads/promise/uses_allocator.cc: Likewise. + 2011-06-10 Paolo Carlini <paolo.carlini@oracle.com> * include/ext/throw_allocator.h: Use noexcept. diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h index 7067fa09bd4..680195082da 100644 --- a/libstdc++-v3/include/bits/allocator.h +++ b/libstdc++-v3/include/bits/allocator.h @@ -184,18 +184,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; #ifdef __GXX_EXPERIMENTAL_CXX0X__ + template<typename _Tp, bool + = __or_<is_copy_constructible<typename _Tp::value_type>, + is_nothrow_move_constructible<typename _Tp::value_type>>::value> + struct __shrink_to_fit_aux + { static bool _S_do_it(_Tp&) { return false; } }; + template<typename _Tp> - bool - __shrink_to_fit(_Tp& __v) + struct __shrink_to_fit_aux<_Tp, true> { - __try - { - _Tp(__v).swap(__v); - return true; - } - __catch(...) - { return false; } - } + static bool + _S_do_it(_Tp& __c) + { + __try + { + _Tp(__make_move_if_noexcept_iterator(__c.begin()), + __make_move_if_noexcept_iterator(__c.end())).swap(__c); + return true; + } + __catch(...) + { return false; } + } + }; template<typename _Alloc, typename _Tp> class __alloctr_rebind_helper diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 9279a38cf4c..1022ce08e5a 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -753,10 +753,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void shrink_to_fit() { - __try - { reserve(0); } - __catch(...) - { } + if (capacity() > size()) + { + __try + { reserve(0); } + __catch(...) + { } + } } #endif diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc index 389fc80d945..fab79157cdb 100644 --- a/libstdc++-v3/include/bits/deque.tcc +++ b/libstdc++-v3/include/bits/deque.tcc @@ -325,6 +325,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } } } + + template <typename _Tp, typename _Alloc> + bool + deque<_Tp, _Alloc>:: + _M_shrink_to_fit() + { + const difference_type __front_capacity + = (this->_M_impl._M_start._M_cur - this->_M_impl._M_start._M_first); + if (__front_capacity == 0) + return false; + + const difference_type __back_capacity + = (this->_M_impl._M_finish._M_last - this->_M_impl._M_finish._M_cur); + if (__front_capacity + __back_capacity < _S_buffer_size()) + return false; + + return std::__shrink_to_fit_aux<deque>::_S_do_it(*this); + } #endif template <typename _Tp, typename _Alloc> diff --git a/libstdc++-v3/include/bits/ptr_traits.h b/libstdc++-v3/include/bits/ptr_traits.h index c83beadb149..a4dae82524e 100644 --- a/libstdc++-v3/include/bits/ptr_traits.h +++ b/libstdc++-v3/include/bits/ptr_traits.h @@ -211,7 +211,7 @@ _GLIBCXX_HAS_NESTED_TYPE(difference_type) * @return @c addressof(r) */ static pointer - pointer_to(typename __ptrtr_not_void<element_type>::__type& __r) + pointer_to(typename __ptrtr_not_void<element_type>::__type& __r) noexcept { return std::addressof(__r); } }; diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h index 30e7b2d9675..22443f4a4c1 100644 --- a/libstdc++-v3/include/bits/stl_bvector.h +++ b/libstdc++-v3/include/bits/stl_bvector.h @@ -443,8 +443,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Bit_type* _M_allocate(size_t __n) - { return _M_impl.allocate((__n + int(_S_word_bit) - 1) - / int(_S_word_bit)); } + { return _M_impl.allocate(_S_nword(__n)); } void _M_deallocate() @@ -453,6 +452,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_impl.deallocate(_M_impl._M_start._M_p, _M_impl._M_end_of_storage - _M_impl._M_start._M_p); } + + static size_t + _S_nword(size_t __n) + { return (__n + int(_S_word_bit) - 1) / int(_S_word_bit); } }; _GLIBCXX_END_NAMESPACE_CONTAINER @@ -511,6 +514,7 @@ template<typename _Alloc> protected: using _Base::_M_allocate; using _Base::_M_deallocate; + using _Base::_S_nword; using _Base::_M_get_Bit_allocator; public: @@ -724,7 +728,13 @@ template<typename _Alloc> { _M_range_check(__n); return (*this)[__n]; } void - reserve(size_type __n); + reserve(size_type __n) + { + if (__n > max_size()) + __throw_length_error(__N("vector::reserve")); + if (capacity() < __n) + _M_reallocate(__n); + } reference front() @@ -844,7 +854,7 @@ template<typename _Alloc> #ifdef __GXX_EXPERIMENTAL_CXX0X__ void shrink_to_fit() - { std::__shrink_to_fit(*this); } + { _M_shrink_to_fit(); } #endif void @@ -875,13 +885,19 @@ template<typename _Alloc> _M_initialize(size_type __n) { _Bit_type* __q = this->_M_allocate(__n); - this->_M_impl._M_end_of_storage = (__q - + ((__n + int(_S_word_bit) - 1) - / int(_S_word_bit))); + this->_M_impl._M_end_of_storage = __q + _S_nword(__n); this->_M_impl._M_start = iterator(__q, 0); this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); } + void + _M_reallocate(size_type __n); + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + bool + _M_shrink_to_fit(); +#endif + // Check whether it's an integral type. If so, it's not an iterator. // _GLIBCXX_RESOLVE_LIB_DEFECTS diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index fab63f130c8..6d7a18ca343 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -1196,7 +1196,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /** A non-binding request to reduce memory use. */ void shrink_to_fit() - { std::__shrink_to_fit(*this); } + { _M_shrink_to_fit(); } #endif /** @@ -1847,6 +1847,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // Called by resize(sz). void _M_default_append(size_type __n); + + bool + _M_shrink_to_fit(); #endif //@{ diff --git a/libstdc++-v3/include/bits/stl_tempbuf.h b/libstdc++-v3/include/bits/stl_tempbuf.h index a99dac93095..c4b0ddd5715 100644 --- a/libstdc++-v3/include/bits/stl_tempbuf.h +++ b/libstdc++-v3/include/bits/stl_tempbuf.h @@ -1,6 +1,7 @@ // Temporary buffer implementation -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, +// 2010, 2011 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -83,7 +84,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template<typename _Tp> pair<_Tp*, ptrdiff_t> - get_temporary_buffer(ptrdiff_t __len) + get_temporary_buffer(ptrdiff_t __len) _GLIBCXX_NOEXCEPT { const ptrdiff_t __max = __gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_Tp); diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 4f617861e8f..929bcbe7ba1 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -646,7 +646,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /** A non-binding request to reduce capacity() to size(). */ void shrink_to_fit() - { std::__shrink_to_fit(*this); } + { _M_shrink_to_fit(); } #endif /** @@ -1229,6 +1229,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // Called by resize(n). void _M_default_append(size_type __n); + + bool + _M_shrink_to_fit(); #endif // Called by insert(p,x) diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h index ec9c3c0b5c3..a6f457ee59e 100644 --- a/libstdc++-v3/include/bits/unique_ptr.h +++ b/libstdc++-v3/include/bits/unique_ptr.h @@ -166,7 +166,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif // Destructor. - ~unique_ptr() { reset(); } + ~unique_ptr() noexcept { reset(); } // Assignment. unique_ptr& diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index 5b6a8d791ae..fd576dbd2df 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -509,6 +509,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } } } + + template<typename _Tp, typename _Alloc> + bool + vector<_Tp, _Alloc>:: + _M_shrink_to_fit() + { + if (capacity() == size()) + return false; + return std::__shrink_to_fit_aux<vector>::_S_do_it(*this); + } #endif template<typename _Tp, typename _Alloc> @@ -609,24 +619,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // vector<bool> - template<typename _Alloc> void vector<bool, _Alloc>:: - reserve(size_type __n) + _M_reallocate(size_type __n) { - if (__n > this->max_size()) - __throw_length_error(__N("vector::reserve")); - if (this->capacity() < __n) - { - _Bit_type* __q = this->_M_allocate(__n); - this->_M_impl._M_finish = _M_copy_aligned(begin(), end(), - iterator(__q, 0)); - this->_M_deallocate(); - this->_M_impl._M_start = iterator(__q, 0); - this->_M_impl._M_end_of_storage = (__q + (__n + int(_S_word_bit) - 1) - / int(_S_word_bit)); - } + _Bit_type* __q = this->_M_allocate(__n); + this->_M_impl._M_finish = _M_copy_aligned(begin(), end(), + iterator(__q, 0)); + this->_M_deallocate(); + this->_M_impl._M_start = iterator(__q, 0); + this->_M_impl._M_end_of_storage = __q + _S_nword(__n); } template<typename _Alloc> @@ -654,9 +657,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_finish = std::copy(__position, end(), __i + difference_type(__n)); this->_M_deallocate(); - this->_M_impl._M_end_of_storage = (__q + ((__len - + int(_S_word_bit) - 1) - / int(_S_word_bit))); + this->_M_impl._M_end_of_storage = __q + _S_nword(__len); this->_M_impl._M_start = iterator(__q, 0); } } @@ -689,10 +690,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER __i = std::copy(__first, __last, __i); this->_M_impl._M_finish = std::copy(__position, end(), __i); this->_M_deallocate(); - this->_M_impl._M_end_of_storage = (__q - + ((__len - + int(_S_word_bit) - 1) - / int(_S_word_bit))); + this->_M_impl._M_end_of_storage = __q + _S_nword(__len); this->_M_impl._M_start = iterator(__q, 0); } } @@ -720,13 +718,29 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER *__i++ = __x; this->_M_impl._M_finish = std::copy(__position, end(), __i); this->_M_deallocate(); - this->_M_impl._M_end_of_storage = (__q + ((__len - + int(_S_word_bit) - 1) - / int(_S_word_bit))); + this->_M_impl._M_end_of_storage = __q + _S_nword(__len); this->_M_impl._M_start = iterator(__q, 0); } } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template<typename _Alloc> + bool + vector<bool, _Alloc>:: + _M_shrink_to_fit() + { + if (capacity() - size() < int(_S_word_bit)) + return false; + __try + { + _M_reallocate(size()); + return true; + } + __catch(...) + { return false; } + } +#endif + _GLIBCXX_END_NAMESPACE_CONTAINER } // namespace std diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque index 749fc2e6cab..5b6bdeb544a 100644 --- a/libstdc++-v3/include/debug/deque +++ b/libstdc++-v3/include/debug/deque @@ -277,7 +277,12 @@ namespace __debug #endif #ifdef __GXX_EXPERIMENTAL_CXX0X__ - using _Base::shrink_to_fit; + void + shrink_to_fit() + { + if (_Base::_M_shrink_to_fit()) + this->_M_invalidate_all(); + } #endif using _Base::empty; diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string index b6d2b4b34ea..9e0ad61bdef 100644 --- a/libstdc++-v3/include/debug/string +++ b/libstdc++-v3/include/debug/string @@ -237,7 +237,20 @@ namespace __gnu_debug { this->resize(__n, _CharT()); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ - using _Base::shrink_to_fit; + void + shrink_to_fit() + { + if (capacity() > size()) + { + __try + { + reserve(0); + this->_M_invalidate_all(); + } + __catch(...) + { } + } + } #endif using _Base::capacity; diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector index 6072515dac3..1b80974d38c 100644 --- a/libstdc++-v3/include/debug/vector +++ b/libstdc++-v3/include/debug/vector @@ -280,7 +280,15 @@ namespace __debug #endif #ifdef __GXX_EXPERIMENTAL_CXX0X__ - using _Base::shrink_to_fit; + void + shrink_to_fit() + { + if (_Base::_M_shrink_to_fit()) + { + _M_guaranteed_capacity = _Base::capacity(); + this->_M_invalidate_all(); + } + } #endif size_type diff --git a/libstdc++-v3/include/ext/extptr_allocator.h b/libstdc++-v3/include/ext/extptr_allocator.h index 96aea72cc88..21b1282dbc1 100644 --- a/libstdc++-v3/include/ext/extptr_allocator.h +++ b/libstdc++-v3/include/ext/extptr_allocator.h @@ -107,10 +107,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION construct(_Up* __p, _Args&&... __args) { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } + template<typename... _Args> + void + construct(pointer __p, _Args&&... __args) + { construct(__p.get(), std::forward<_Args>(__args)...); } + template<typename _Up> void destroy(_Up* __p) { __p->~_Up(); } + + void destroy(pointer __p) + { destroy(__p.get()); } + #else void construct(pointer __p, const _Tp& __val) diff --git a/libstdc++-v3/include/ext/vstring.h b/libstdc++-v3/include/ext/vstring.h index a84336861a7..b0b3e2efa53 100644 --- a/libstdc++-v3/include/ext/vstring.h +++ b/libstdc++-v3/include/ext/vstring.h @@ -465,10 +465,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void shrink_to_fit() { - __try - { this->reserve(0); } - __catch(...) - { } + if (capacity() > size()) + { + __try + { this->reserve(0); } + __catch(...) + { } + } } #endif diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 0126510ce24..85df22017f6 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -437,28 +437,28 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) public: typedef _Tp type; - reference_wrapper(_Tp& __indata) + reference_wrapper(_Tp& __indata) noexcept : _M_data(std::__addressof(__indata)) { } reference_wrapper(_Tp&&) = delete; - reference_wrapper(const reference_wrapper<_Tp>& __inref): - _M_data(__inref._M_data) + reference_wrapper(const reference_wrapper<_Tp>& __inref) noexcept + : _M_data(__inref._M_data) { } reference_wrapper& - operator=(const reference_wrapper<_Tp>& __inref) + operator=(const reference_wrapper<_Tp>& __inref) noexcept { _M_data = __inref._M_data; return *this; } - operator _Tp&() const + operator _Tp&() const noexcept { return this->get(); } _Tp& - get() const + get() const noexcept { return *_M_data; } template<typename... _Args> @@ -473,13 +473,13 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) /// Denotes a reference should be taken to a variable. template<typename _Tp> inline reference_wrapper<_Tp> - ref(_Tp& __t) + ref(_Tp& __t) noexcept { return reference_wrapper<_Tp>(__t); } /// Denotes a const reference should be taken to a variable. template<typename _Tp> inline reference_wrapper<const _Tp> - cref(const _Tp& __t) + cref(const _Tp& __t) noexcept { return reference_wrapper<const _Tp>(__t); } template<typename _Tp> @@ -491,13 +491,13 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) /// Partial specialization. template<typename _Tp> inline reference_wrapper<_Tp> - ref(reference_wrapper<_Tp> __t) + ref(reference_wrapper<_Tp> __t) noexcept { return ref(__t.get()); } /// Partial specialization. template<typename _Tp> inline reference_wrapper<const _Tp> - cref(reference_wrapper<_Tp> __t) + cref(reference_wrapper<_Tp> __t) noexcept { return cref(__t.get()); } // @} group functors @@ -1913,13 +1913,15 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) * @brief Default construct creates an empty function call wrapper. * @post @c !(bool)*this */ - function() : _Function_base() { } + function() noexcept + : _Function_base() { } /** * @brief Creates an empty function call wrapper. * @post @c !(bool)*this */ - function(nullptr_t) : _Function_base() { } + function(nullptr_t) noexcept + : _Function_base() { } /** * @brief %Function copy constructor. @@ -2050,7 +2052,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) /// @overload template<typename _Functor> typename enable_if<!is_integral<_Functor>::value, function&>::type - operator=(reference_wrapper<_Functor> __f) + operator=(reference_wrapper<_Functor> __f) noexcept { function(__f).swap(*this); return *this; @@ -2093,7 +2095,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) * * This function will not throw an %exception. */ - explicit operator bool() const + explicit operator bool() const noexcept { return !_M_empty(); } // [3.7.2.4] function invocation @@ -2119,7 +2121,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) * * This function will not throw an %exception. */ - const type_info& target_type() const; + const type_info& target_type() const noexcept; /** * @brief Access the stored target function object. @@ -2130,10 +2132,10 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) * * This function will not throw an %exception. */ - template<typename _Functor> _Functor* target(); + template<typename _Functor> _Functor* target() noexcept; /// @overload - template<typename _Functor> const _Functor* target() const; + template<typename _Functor> const _Functor* target() const noexcept; #endif private: @@ -2187,7 +2189,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) template<typename _Res, typename... _ArgTypes> const type_info& function<_Res(_ArgTypes...)>:: - target_type() const + target_type() const noexcept { if (_M_manager) { @@ -2203,7 +2205,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) template<typename _Functor> _Functor* function<_Res(_ArgTypes...)>:: - target() + target() noexcept { if (typeid(_Functor) == target_type() && _M_manager) { @@ -2222,7 +2224,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) template<typename _Functor> const _Functor* function<_Res(_ArgTypes...)>:: - target() const + target() const noexcept { if (typeid(_Functor) == target_type() && _M_manager) { @@ -2246,13 +2248,13 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) */ template<typename _Res, typename... _Args> inline bool - operator==(const function<_Res(_Args...)>& __f, nullptr_t) + operator==(const function<_Res(_Args...)>& __f, nullptr_t) noexcept { return !static_cast<bool>(__f); } /// @overload template<typename _Res, typename... _Args> inline bool - operator==(nullptr_t, const function<_Res(_Args...)>& __f) + operator==(nullptr_t, const function<_Res(_Args...)>& __f) noexcept { return !static_cast<bool>(__f); } /** @@ -2264,13 +2266,13 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) */ template<typename _Res, typename... _Args> inline bool - operator!=(const function<_Res(_Args...)>& __f, nullptr_t) + operator!=(const function<_Res(_Args...)>& __f, nullptr_t) noexcept { return static_cast<bool>(__f); } /// @overload template<typename _Res, typename... _Args> inline bool - operator!=(nullptr_t, const function<_Res(_Args...)>& __f) + operator!=(nullptr_t, const function<_Res(_Args...)>& __f) noexcept { return static_cast<bool>(__f); } // [20.7.15.2.7] specialized algorithms diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 10272ccb1b2..d058c676be6 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -69,6 +69,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __add_r_ref<_Tp&> { typedef _Tp& type; }; + // To work around c++/49225 aka c++/48322. + template<typename...> + struct __conv_types { }; + + template<typename _Tuple1, typename _Tuple2> + struct __one_by_one_convertible + : public false_type { }; + + template<typename _Tp, typename _Up> + struct __one_by_one_convertible<__conv_types<_Tp>, __conv_types<_Up>> + : public is_convertible<_Tp, _Up>::type { }; + + template<typename _T1, typename... _TR, typename _U1, typename... _UR> + struct __one_by_one_convertible<__conv_types<_T1, _TR...>, + __conv_types<_U1, _UR...>> + : public __and_<is_convertible<_T1, _U1>, + __one_by_one_convertible<__conv_types<_TR...>, + __conv_types<_UR...>>>::type + { }; + + template<typename _Tuple1, typename _Tuple2> + struct __all_convertible; + + template<typename... _TTypes, typename... _UTypes> + struct __all_convertible<__conv_types<_TTypes...>, + __conv_types<_UTypes...>> + : public __one_by_one_convertible<__conv_types<_TTypes...>, + __conv_types<_UTypes...>>::type { }; + template<std::size_t _Idx, typename _Head, bool _IsEmpty> struct _Head_base; @@ -359,8 +388,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename... _UElements, typename = typename enable_if<__and_<integral_constant<bool, sizeof...(_UElements) == sizeof...(_Elements)>, - __and_<is_convertible<_UElements, - _Elements>...>>::value>::type> + __all_convertible<__conv_types<_UElements...>, + __conv_types<_Elements...>> + >::value>::type> explicit tuple(_UElements&&... __elements) : _Inherited(std::forward<_UElements>(__elements)...) { } @@ -371,8 +401,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename... _UElements, typename = typename enable_if<__and_<integral_constant<bool, sizeof...(_UElements) == sizeof...(_Elements)>, - __and_<is_convertible<const _UElements&, - _Elements>...>>::value>::type> + __all_convertible<__conv_types<const _UElements&...>, + __conv_types<_Elements...>> + >::value>::type> tuple(const tuple<_UElements...>& __in) : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) { } @@ -380,8 +411,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename... _UElements, typename = typename enable_if<__and_<integral_constant<bool, sizeof...(_UElements) == sizeof...(_Elements)>, - __and_<is_convertible<_UElements, - _Elements>...>>::value>::type> + __all_convertible<__conv_types<_UElements...>, + __conv_types<_Elements...>> + >::value>::type> tuple(tuple<_UElements...>&& __in) : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } @@ -628,111 +660,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _Inherited::_M_swap(__in); } }; - /// tuple (1-element). - // TODO: Should be simply removed when c++/49225 is fixed, worst case - // together with a different way to constrain the constructors - // of the primary template. - template<typename _T1> - class tuple<_T1> : public _Tuple_impl<0, _T1> - { - typedef _Tuple_impl<0, _T1> _Inherited; - - public: - constexpr tuple() - : _Inherited() { } - - explicit - constexpr tuple(const _T1& __a1) - : _Inherited(__a1) { } - - template<typename _U1, typename = typename - enable_if<is_convertible<_U1, _T1>::value>::type> - explicit - tuple(_U1&& __a1) - : _Inherited(std::forward<_U1>(__a1)) { } - - constexpr tuple(const tuple&) = default; - tuple(tuple&&) = default; - - template<typename _U1, typename = typename - enable_if<is_convertible<const _U1&, _T1>::value>::type> - tuple(const tuple<_U1>& __in) - : _Inherited(static_cast<const _Tuple_impl<0, _U1>&>(__in)) { } - - template<typename _U1, typename = typename - enable_if<is_convertible<_U1, _T1>::value>::type> - tuple(tuple<_U1>&& __in) - : _Inherited(static_cast<_Tuple_impl<0, _U1>&&>(__in)) { } - - // allocator-extended constructors - - template<typename _Alloc> - tuple(allocator_arg_t __tag, const _Alloc& __a) - : _Inherited(__tag, __a) { } - - template<typename _Alloc> - tuple(allocator_arg_t __tag, const _Alloc& __a, const _T1& __a1) - : _Inherited(__tag, __a, __a1) { } - - // TODO: constrain for is_uses_allocator_constructible<_T1, _U1&&, _Alloc> - template<typename _Alloc, typename _U1> - tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1) - : _Inherited(__tag, __a, std::forward<_U1>(__a1)) { } - - template<typename _Alloc> - tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) - : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } - - template<typename _Alloc> - tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) - : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } - - template<typename _Alloc, typename _U1> - tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_U1>& __in) - : _Inherited(__tag, __a, static_cast<const _Tuple_impl<0, _U1>&>(__in)) - { } - - template<typename _Alloc, typename _U1> - tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1>&& __in) - : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1>&&>(__in)) { } - - tuple& - operator=(const tuple& __in) - { - static_cast<_Inherited&>(*this) = __in; - return *this; - } - - tuple& - operator=(tuple&& __in) - noexcept(is_nothrow_move_assignable<_Inherited>::value) - { - static_cast<_Inherited&>(*this) = std::move(__in); - return *this; - } - - template<typename _U1> - tuple& - operator=(const tuple<_U1>& __in) - { - static_cast<_Inherited&>(*this) = __in; - return *this; - } - - template<typename _U1> - tuple& - operator=(tuple<_U1>&& __in) - { - static_cast<_Inherited&>(*this) = std::move(__in); - return *this; - } - - void - swap(tuple& __in) - noexcept(noexcept(__in._M_swap(__in))) - { _Inherited::_M_swap(__in); } - }; - /// Gives the type of the ith element of a given tuple type. template<std::size_t __i, typename _Tp> diff --git a/libstdc++-v3/include/std/valarray b/libstdc++-v3/include/std/valarray index de6886858c0..e66333e9af2 100644 --- a/libstdc++-v3/include/std/valarray +++ b/libstdc++-v3/include/std/valarray @@ -165,7 +165,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<class _Dom> valarray(const _Expr<_Dom, _Tp>& __e); - ~valarray(); + ~valarray() _GLIBCXX_NOEXCEPT; // _lib.valarray.assign_ assignment: /** @@ -697,7 +697,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> inline - valarray<_Tp>::~valarray() + valarray<_Tp>::~valarray() _GLIBCXX_NOEXCEPT { std::__valarray_destroy_elements(_M_data, _M_data + _M_size); std::__valarray_release_memory(_M_data); diff --git a/libstdc++-v3/testsuite/20_util/allocator_traits/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/allocator_traits/requirements/explicit_instantiation.cc index 13d3135cb14..f7346966790 100644 --- a/libstdc++-v3/testsuite/20_util/allocator_traits/requirements/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/20_util/allocator_traits/requirements/explicit_instantiation.cc @@ -22,8 +22,21 @@ #include <memory> +typedef short test_type; + +template<typename T> + struct minimal_allocator + { + typedef T value_type; + minimal_allocator(); + template <typename U> + minimal_allocator(const minimal_allocator<U>&); + T* allocate(std::size_t); + void deallocate(T*, std::size_t); + }; + namespace std { - typedef short test_type; template struct allocator_traits<std::allocator<test_type>>; + template struct allocator_traits<minimal_allocator<test_type>>; } diff --git a/libstdc++-v3/testsuite/20_util/allocator_traits/requirements/typedefs.cc b/libstdc++-v3/testsuite/20_util/allocator_traits/requirements/typedefs.cc index 346824ffc2b..89f57f44792 100644 --- a/libstdc++-v3/testsuite/20_util/allocator_traits/requirements/typedefs.cc +++ b/libstdc++-v3/testsuite/20_util/allocator_traits/requirements/typedefs.cc @@ -29,6 +29,8 @@ void test01() { // Check for required typedefs typedef std::allocator_traits<T> test_type; + typedef typename test_type::allocator_type allocator_type; + typedef typename test_type::value_type value_type; typedef typename test_type::pointer pointer; typedef typename test_type::const_pointer const_pointer; typedef typename test_type::void_pointer void_pointer; diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/noexcept_move_construct.cc new file mode 100644 index 00000000000..640a54bafdb --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/noexcept_move_construct.cc @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2011-06-14 Paolo Carlini <paolo.carlini@oracle.com> +// +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <memory> + +typedef std::shared_ptr<int> sptype; + +static_assert(std::is_nothrow_move_constructible<sptype>::value, "Error"); diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/noexcept_move_construct.cc new file mode 100644 index 00000000000..c5de14f52f4 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/noexcept_move_construct.cc @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2011-06-14 Paolo Carlini <paolo.carlini@oracle.com> +// +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <memory> + +typedef std::unique_ptr<int> uptype; + +static_assert(std::is_nothrow_move_constructible<uptype>::value, "Error"); diff --git a/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc b/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc index 73a0d0f7029..ad998356c83 100644 --- a/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc +++ b/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc @@ -44,4 +44,4 @@ void test01() tuple<Type> t(allocator_arg, a, 1); } -// { dg-error "no matching function" "" { target *-*-* } 112 } +// { dg-error "no matching function" "" { target *-*-* } 141 } diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc index ace80cf79c0..df18712f73b 100644 --- a/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc +++ b/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc @@ -51,7 +51,7 @@ main() // { dg-warning "note" "" { target *-*-* } 485 } // { dg-warning "note" "" { target *-*-* } 479 } // { dg-warning "note" "" { target *-*-* } 469 } -// { dg-warning "note" "" { target *-*-* } 887 } +// { dg-warning "note" "" { target *-*-* } 814 } // { dg-warning "note" "" { target *-*-* } 1056 } // { dg-warning "note" "" { target *-*-* } 1050 } // { dg-warning "note" "" { target *-*-* } 342 } diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/cons/noexcept_move_construct.cc new file mode 100644 index 00000000000..4e9a90df63d --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/weak_ptr/cons/noexcept_move_construct.cc @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2011-06-14 Paolo Carlini <paolo.carlini@oracle.com> +// +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <memory> + +typedef std::weak_ptr<int> wptype; + +static_assert(std::is_nothrow_move_constructible<wptype>::value, "Error"); diff --git a/libstdc++-v3/testsuite/21_strings/debug/shrink_to_fit.cc b/libstdc++-v3/testsuite/21_strings/debug/shrink_to_fit.cc new file mode 100644 index 00000000000..e2c85be268c --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/debug/shrink_to_fit.cc @@ -0,0 +1,39 @@ +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. +// +// { dg-options "-std=gnu++0x" } +// { dg-do run { xfail *-*-* } } + +#include <debug/string> + +void test01() +{ + using __gnu_debug::string; + string s; + s.reserve(2); + s.push_back('a'); + string::iterator it = s.begin(); + s.shrink_to_fit(); + // Following line should assert + *it = 'z'; +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/deque/debug/shrink_to_fit.cc b/libstdc++-v3/testsuite/23_containers/deque/debug/shrink_to_fit.cc new file mode 100644 index 00000000000..4cce4bd3739 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/deque/debug/shrink_to_fit.cc @@ -0,0 +1,51 @@ +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. +// +// { dg-require-debug-mode "" } +// { dg-options "-std=gnu++0x" } +// { dg-do run { xfail *-*-* } } + +#include <deque> + +void test01() +{ + using std::deque; + deque<int> d; + // Lets generate a hole at the begining of the deque: + d.push_back(0); + d.push_back(1); + d.pop_front(); + deque<int>::iterator it; + do + { + d.push_back(2); + it = d.begin(); + auto old_abegin = &*d.begin(); + d.shrink_to_fit(); + if (&*d.begin() != old_abegin) + break; + } + while (true); + // Following line should assert + *it = 2; +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/shrink_to_fit.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/shrink_to_fit.cc new file mode 100644 index 00000000000..c3ae90e981a --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/bool/capacity/shrink_to_fit.cc @@ -0,0 +1,40 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <vector> +#include <testsuite_hooks.h> + +void test01() +{ + bool test __attribute__((unused)) = true; + + std::vector<bool> vb(__CHAR_BIT__ * sizeof(unsigned long) + 1); + vb.pop_back(); + + auto old_capacity = vb.capacity(); + vb.shrink_to_fit(); + VERIFY( vb.capacity() < old_capacity ); + VERIFY( vb.size() == vb.capacity() ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/bool/shrink_to_fit.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/bool/shrink_to_fit.cc new file mode 100644 index 00000000000..8206e0e567b --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/debug/bool/shrink_to_fit.cc @@ -0,0 +1,42 @@ +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. +// +// { dg-require-debug-mode "" } +// { dg-options "-std=gnu++0x" } +// { dg-do run { xfail *-*-* } } + +#include <vector> + +void test01() +{ + using std::vector; + + vector<bool> vb(__CHAR_BIT__ * sizeof(unsigned long) + 1); + vb.pop_back(); + + vector<bool>::iterator it = vb.begin(); + vb.shrink_to_fit(); + + // Following line should assert + *it = true; +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/shrink_to_fit.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/shrink_to_fit.cc new file mode 100644 index 00000000000..969c79a283e --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/debug/shrink_to_fit.cc @@ -0,0 +1,40 @@ +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. +// +// { dg-require-debug-mode "" } +// { dg-options "-std=gnu++0x" } +// { dg-do run { xfail *-*-* } } + +#include <vector> + +void test01() +{ + using std::vector; + vector<int> v; + v.reserve(2); + v.push_back(0); + vector<int>::iterator it = v.begin(); + v.shrink_to_fit(); + // Following line should assert + *it = 1; +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/ext_pointer/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/23_containers/vector/ext_pointer/explicit_instantiation/2.cc new file mode 100644 index 00000000000..974f2c4bb5c --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/ext_pointer/explicit_instantiation/2.cc @@ -0,0 +1,28 @@ +// Test for Container using non-standard pointer types. + +// Copyright (C) 2011 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + + +#include <vector> +#include <ext/extptr_allocator.h> + +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +template class std::vector<int, __gnu_cxx::_ExtPtr_allocator<int> >; diff --git a/libstdc++-v3/testsuite/23_containers/vector/ext_pointer/types/2.cc b/libstdc++-v3/testsuite/23_containers/vector/ext_pointer/types/2.cc new file mode 100644 index 00000000000..929e7d57cde --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/ext_pointer/types/2.cc @@ -0,0 +1,63 @@ +// Test for Container using non-standard pointer types. + +// Copyright (C) 2011 +// Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + + +// { dg-options "-std=gnu++0x" } + +// This is a copy of vector/types/1.cc with altered allocator. +// The operator+()s in this test initially failed the test - +// they stress the accurate recognition, by the compiler, +// of _Pointer_adapter's own pointer arithmetic functions, +// which have to match perfectly on the int type to get +// chosen by the compiler when it sees: _Pointer_adapter<T> + int, etc. + +#include <vector> +#include <ext/extptr_allocator.h> + +namespace N +{ + struct X { }; + + template<typename T> + X operator+(T, std::size_t) + { return X(); } + + template<typename T> + X operator-(T, T) + { return X(); } +} + +int main() +{ + std::vector<N::X, __gnu_cxx::_ExtPtr_allocator<N::X> > v(5); + const std::vector<N::X, __gnu_cxx::_ExtPtr_allocator<N::X> > w(1); + + v[0]; + w[0]; + v.size(); + v.capacity(); + v.resize(1); + v.insert(v.begin(), N::X()); + v.insert(v.begin(), 1, N::X()); + v.insert(v.begin(), w.begin(), w.end()); + v = w; + + return 0; +} diff --git a/libstdc++-v3/testsuite/26_numerics/valarray/noexcept_move_construct.cc b/libstdc++-v3/testsuite/26_numerics/valarray/noexcept_move_construct.cc new file mode 100644 index 00000000000..3d7fdc382e6 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/valarray/noexcept_move_construct.cc @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2011-06-14 Paolo Carlini <paolo.carlini@oracle.com> +// +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <valarray> + +typedef std::valarray<int> vtype; + +static_assert(std::is_nothrow_move_constructible<vtype>::value, "Error"); diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/uses_allocator.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/uses_allocator.cc new file mode 100644 index 00000000000..f6fb2aef9f9 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/uses_allocator.cc @@ -0,0 +1,32 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } +// { dg-require-atomic-builtins "" } + +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + + +#include <future> +#include <memory> + +using std::uses_allocator; +using std::allocator; +using std::packaged_task; +static_assert( uses_allocator<packaged_task<int()>, allocator<int>>::value, + "packaged_task supports uses-allocator construction" ); diff --git a/libstdc++-v3/testsuite/30_threads/promise/uses_allocator.cc b/libstdc++-v3/testsuite/30_threads/promise/uses_allocator.cc new file mode 100644 index 00000000000..385058d7246 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/promise/uses_allocator.cc @@ -0,0 +1,32 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } +// { dg-require-atomic-builtins "" } + +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + + +#include <future> +#include <memory> + +using std::uses_allocator; +using std::allocator; +using std::promise; +static_assert( uses_allocator<promise<int>, allocator<int>>::value, + "promise supports uses-allocator construction" ); |