diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-09-20 08:46:22 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-09-20 08:46:22 +0000 |
commit | 174dbf0e0917406ff2f40a280850f2088efff3ce (patch) | |
tree | 88cb35c7468c9c304817d3b3d751c6deb686b8cd | |
parent | b7a5110162a3b114887dabb7bc1b7413d2b04b72 (diff) | |
download | gcc-174dbf0e0917406ff2f40a280850f2088efff3ce.tar.gz |
2013-09-20 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 202766 using svnmerge.py
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@202768 138bc75d-0d04-0410-961f-82ee72b054a4
210 files changed, 7184 insertions, 3703 deletions
diff --git a/ChangeLog b/ChangeLog index 5db944c9d4a..b281021925b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-09-19 Dodji Seketeli <dodji@redhat.com> + + * MAINTAINERS (diagnostic messages): Add myself as diagnostics + maintainer. + 2013-09-12 DJ Delorie <dj@redhat.com> * MAINTAINERS: Add Nick Clifton and DJ Delorie as msp430 diff --git a/ChangeLog.MELT b/ChangeLog.MELT index 012573e7cba..2543ffb2ee3 100644 --- a/ChangeLog.MELT +++ b/ChangeLog.MELT @@ -1,4 +1,8 @@ +2013-09-20 Basile Starynkevitch <basile@starynkevitch.net> + + MELT branch merged with trunk rev 202766 using svnmerge.py + 2013-09-16 Basile Starynkevitch <basile@starynkevitch.net> MELT branch merged with trunk rev 202619 using svnmerge.py diff --git a/MAINTAINERS b/MAINTAINERS index 886816c5214..4a369d7f5bb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -213,6 +213,7 @@ config.sub/config.guess Ben Elliston config-patches@gnu.org basic block reordering Jason Eckhardt jle@rice.edu i18n Philipp Thomas pth@suse.de i18n Joseph Myers joseph@codesourcery.com +diagnostic messages Dodji Seketeli dodji@redhat.com build machinery (*.in) Paolo Bonzini bonzini@gnu.org build machinery (*.in) DJ Delorie dj@redhat.com build machinery (*.in) Nathanael Nerode neroden@gcc.gnu.org diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 373bd8fc5cd..f02617bf926 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,644 @@ +2013-09-20 Marek Polacek <polacek@redhat.com> + + PR other/58467 + * doc/extend.texi: Document that attribute used is meant to be used + on variables with static storage duration. + +2013-09-19 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/58472 + * tree-vect-stmts.c (vectorizable_store, vectorizable_load): For + simd_lane_access set inv_p = false. + * omp-low.c (lower_rec_input_clauses): Set TREE_NO_WARNING on + the simduid magic VAR_DECL. + +2013-09-19 Jan Hubicka <jh@suse.cz> + + * i386.c (generic_memcpy, generic_memset): Fix 32bit template. + +2013-09-17 Jeff Law <law@redhat.com> + + * tree-ssa-dom.c (record_temporary_equivalences): New function + split out of dom_opt_dom_walker::after_dom_children. + (dom_opt_dom_walker::thread_across_edge): Move common code + in here from dom_opt_dom_walker::after_dom_children. + (dom_opt_dom_walker::after_dom_children): Corresponding simplifictions. + +2013-09-19 Jan Hubicka <jh@suse.cz> + + * i386.h (TARGET_GENERIC32, TARGET_GENERIC64): Remove. + (TARGET_GENERIC): Use PROCESOR_GENERIC + (enum processor_type): Unify generic32 and 64. + * i386.md (cpu): Likewise. + * x86-tune.def (use_leave): Enable for generic32. + (avoid_vector_decode, slow_imul_imm32_mem, slow_imul_imm8): Likewise. + * athlon.md: Change generic64 to generic in all occurences. + * i386-c.c (ix86_target_macros_internal): Unify generic64 and 32. + (ix86_target_macros_internal): Likewise. + * driver-i386.c (host_detect_local_cpu): Likewise. + * i386.c (generic64_memcpy, generic64_memset, generic64_cost): Rename to .. + (generic_memcpy, generic_memset, generic_cost): This one. + (generic32_memcpy, generic32_memset, generic32_cost): Remove. + (m_GENERIC32, m_GENERIC64): Remove. + (m_GENERIC): Turn into one flag. + (processor_target): Unify generic tunnings. + (ix86_option_override_internal): Replace generic32/64 by generic. + (ix86_issue_rate): Likewise. + (ix86_adjust_cost): Likewise. + +2013-09-19 Jan Hubicka <jh@suse.cz> + + * cgraph.c (cgraph_create_edge_1): Avoid uninitialized read + of speculative flag. + +2013-09-19 Jakub Jelinek <jakub@redhat.com> + + * omp-low.c (expand_omp_sections): Always pass len - 1 to + GOMP_sections_start, even if !exit_reachable. + +2013-09-18 Vladimir Makarov <vmakarov@redhat.com> + + * lra-constraints.c (need_for_all_save_p): Use macro + HARD_REGNO_CALL_PART_CLOBBERED. + * lra-lives.c (check_pseudos_live_through_calls): Use the macro to + set up pseudo conflict hard regs. + +2013-09-18 Michael Meissner <meissner@linux.vnet.ibm.com> + + PR target/58452 + * config/rs6000/paired.md (movmisalignv2sf): Fix to allow memory + operands. + +2013-09-18 Vladimir Makarov <vmakarov@redhat.com> + + PR rtl-optimization/58438 + * lra.c (lra): Clear lra_optional_reload_pseudos in upper loop. + * lra-constraints.c (undo_optional_reloads): Keep optional reloads + from previous subpasses. + +2013-09-18 Richard Earnshaw <rearnsha@arm.com> + + * arm.c (arm_get_frame_offsets): Validate architecture supports + LDRD/STRD before accepting the tuning preference. + (arm_expand_prologue): Likewise. + (arm_expand_epilogue): Likewise. + +2013-09-18 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58417 + * tree-chrec.c (chrec_fold_plus_1): Assert that we do not + have chrecs with symbols defined in the loop as operands. + (chrec_fold_multiply): Likewise. + * tree-scalar-evolution.c (interpret_rhs_expr): Instantiate + parameters before folding binary operations. + (struct instantiate_cache_entry_hasher): Remove. + (struct instantiate_cache_type): Use a pointer-map. + (instantiate_cache_type::instantiate_cache_type): New function. + (instantiate_cache_type::get): Likewise. + (instantiate_cache_type::set): Likewise. + (instantiate_cache_type::~instantiate_cache_type): Adjust. + (get_instantiated_value_entry): Likewise. + (global_cache): New global. + (instantiate_scev_r, instantiate_scev_poly, instantiate_scev_binary, + instantiate_array_ref, instantiate_scev_convert, instantiate_scev_3, + instantiate_scev_2, instantiate_scev_1): Do not pass along cache. + (instantiate_scev_name): Adjust. + (instantiate_scev): Construct global instead of local cache. + (resolve_mixers): Likewise. + +2013-09-18 Daniel Morris <danielm@ecoscentric.com> + Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/58458 + * doc/implement-cxx.texi: Fix references to the C++ standards. + +2013-09-18 Jakub Jelinek <jakub@redhat.com> + + * omp-low.c (copy_var_decl): Copy DECL_ATTRIBUTES. + * tree-vect-data-refs.c (vect_analyze_data_refs): For + simd_lane_access drs, update also DR_ALIGNED_TO. + +2013-09-18 Marek Polacek <polacek@redhat.com> + + PR sanitizer/58411 + * doc/extend.texi: Document no_sanitize_undefined attribute. + * builtins.c (fold_builtin_0): Don't sanitize function if it has the + no_sanitize_undefined attribute. + +2013-09-18 Nick Clifton <nickc@redhat.com> + + * config/msp430/msp430.h (ASM_SPEC): Pass -md on to the assembler. + (ASM_DECLARE_FUNCTION_NAME): Define. + +2013-09-17 Trevor Saunders <tsaunders@mozilla.com> + + * compare-elim.c (find_comparison_dom_walker): New class + (find_comparisons_in_bb): Rename to + find_comparison_dom_walker::before_dom_children + (find_comparisons): Adjust + * domwalk.c (walk_dominator_tree): Rename to dom_walker::walk, and + adjust. + (init_walk_dominator_tree, fini_walk_dominator_tree): Remove + * domwalk.h (dom_walk_data): Convert it To a class dom_walker. + (init_walk_dominator_tree): Remove declaration. + (fini_walk_dominator_tree): Remove declaration. + * fwprop.c (single_def_use_dom_walker): New class + (single_def_use_enter_block): Convert to + single_def_use_dom_walker::before_dom_children. + (single_def_use_leave_block): Convert to + single_def_use_dom_walker::after_dom_children. + (build_single_def_use_links): Adjust. + * gimple-ssa-strength-reduction.c (find_candidates_dom_walker): New + class. + (find_candidates_in_block): Convert to + find_candidates_dom_walker::before_dom_children. + (execute_strength_reduction): Adjust. + * graphite-sese-to-poly.c (struct bsc, build_sese_conditions): Remove. + (sese_dom_walker): New class. + (sese_dom_walker::sese_dom_walker): New constructor. + (sese_dom_walker::~sese_dom_walker): New destructor. + (build_sese_conditions_before): Convert to + sese_dom_walker::before_dom_children. + (build_sese_conditions_after): Convert to + sese_dom_walker::after_dom_children. + (build_poly_scop): Adjust + * tree-into-ssa.c (rewrite_dom_walker): New class + (rewrite_enter_block): Convert to + rewrite_dom_walker::before_dom_children. + (rewrite_leave_block): Convert to + rewrite_dom_walker::after_dom_children. + (rewrite_update_dom_walker): New class. + (rewrite_update_enter_block): Convert to + rewrite_update_dom_walker::before_dom_children. + (rewrite_update_leave_block): Convert to + rewrite_update_dom_walker::after_dom_children. + (rewrite_blocks, rewrite_into_ssa): Adjust. + (mark_def_dom_walker): New class. + (mark_def_dom_walker::mark_def_dom_walker): New constructor. + (mark_def_dom_walker::~mark_def_dom_walker): New destructor. + (mark_def_sites_blocks): Convert to + mark_def_dom_walker::before_dom_children. + (mark_def_site_blocks): Remove. + * tree-ssa-dom.c (dom_opt_dom_walker): New class. + (tree_ssa_dominator_optimize): Adjust. + (dom_thread_across_edge): Convert to method + dom_opt_dom_walker::thread_across_edge. + (dom_opt_enter_block): Convert to member function + dom_opt_dom_walker::before_dom_children. + (dom_opt_leave_block): Convert to member function + dom_opt_dom_walker::after_dom_children. + * tree-ssa-dse.c (dse_dom_walker): New class. + (dse_enter_block): Convert to member function + dse_dom_walker::before_dom_children. + (tree_ssa_dse): Adjust. + * tree-ssa-loop-im.c (invariantness_dom_walker): New class. + (determine_invariantness_stmt): Convert to method + invariantness_dom_walker::before_dom_children. + (determine_invariantness): Remove + (move_computations_dom_walker): New class. + (move_computations_stmt): Convert to method + move_computations_dom_walker::before_dom_children. + (move_computations, tree_ssa_lim): Adjust. + * tree-ssa-phiopt.c (nontrapping_dom_walker): new class + (nt_init_block): Make method + notrappping_dom_walker::before_dom_children. + (nt_fini_block): Make + method nontrapping_dom_walker::after_dom_children. + (get_non_trapping): Adjust. + * tree-ssa-pre.c (eliminate_dom_walker): New class. + (eliminate_bb): Make method eliminate_dom_walker::before_dom_children. + (eliminate_leave_block): Make method. + eliminate_dom_walker::after_dom_children. + (eliminate): Adjust + * tree-ssa-strlen.c (strlen_dom_walker): New class. + (strlen_enter_block): Make method + strlen_dom_walker::before_dom_children. + (strlen_leave_block): Make + method strlen_dom_walker::after_dom_children. + (tree_ssa_strlen): Adjust. + * tree-ssa-uncprop.c (uncprop_dom_walker): New class. + (tree_ssa_uncprop): Adjust. + (uncprop_leave_block): Make method + uncprop_dom_walker::after_dom_children. + (uncprop_leave_block): Make method + uncprop_dom_walker::before_dom_children. + +2013-09-18 Bin Cheng <bin.cheng@arm.com> + + * config/arm/arm.c (thumb1_reorg): Search for flag setting insn + before branch in same basic block. Check both src and dest of + the move insn. + +2013-09-17 Nick Clifton <nickc@redhat.com> + + * config/rl78/rl78-real.md (bf): New pattern. + (bt): New pattern. + * config/rl78/rl78.c (rl78_print_operand_1): Handle %B. + (rl78_print_operand): Do not put a # before a %B. + * config/rl78/rl78.opt: Tweak doc strings. + +2013-09-17 DJ Delorie <dj@redhat.com> + + * config/rl78/constraints.md (Wcv): Allow up to $r31. + * config/rl78/rl78.c (rl78_asm_file_start: Likewise. + (rl78_option_override): Likewise, if -mallregs. + (is_virtual_register): Likewise. + * config/rl78/rl78.h (reg_class): Extend VREGS to $r31. + (REGNO_OK_FOR_BASE_P): Likewise. + * config/rl78/rl78.opt (-mallregs): New. + +2013-09-17 Nick Clifton <nickc@redhat.com> + + * config/rl78/rl78.c (need_to_save): Change return type to bool. + For interrupt functions: save all call clobbered registers if the + interrupt handler is not a leaf function. + (rl78_expand_prologue): Always recompute the frame information. + For interrupt functions: only select bank 0 if one of the bank 0 + registers is going to be psuhed. + +2013-09-17 DJ Delorie <dj@redhat.com> + + * config/rl78/constraints.md: For each W* constraint, rename to C* + and create a W* constraint that checks for an optional ES: prefix + pattern also. + * config/rl78/rl78.md (UNS_ES_ADDR): New. + (es_addr): New. Used to wrap far addresses. + * config/rl78/rl78-protos.h (rl78_es_addr): New. + (rl78_es_base): New. + * config/rl78/rl78.c (rl78_as_legitimate_address): Accept "unspec" + wrapped far addresses. + (rl78_print_operand_1): Unwrap far addresses before processing. + (rl78_lo16): Wrap far addresses in unspecs. + (rl78_es_addr): New. + (rl78_es_base): New. + (insn_ok_now): Check for not-yet-wrapped far addresses. + (transcode_memory_rtx): Properly re-wrap far addresses. + +2013-09-17 Sebastian Huber <sebastian.huber@embedded-brains.de> + + * config/sparc/t-rtems: Add leon3 multilibs. + +2013-09-17 Cong Hou <congh@google.com> + + * tree-vect-patterns.c (vect_recog_dot_prod_pattern): Fix a bug + when checking the dot production pattern. The type of rhs operand + of multiply is now checked correctly. + +2013-09-17 Jeff Law <law@redhat.com> + + * tree-ssa-dom.c (cprop_into_successor_phis): Also propagate + edge implied equivalences into successor phis. + * tree-ssa-threadupdate.c (phi_args_equal_on_edges): Moved into + here from tree-ssa-threadedge.c. + (mark_threaded_blocks): When threading through a joiner, if both + successors of the joiner's clone reach the same block, verify the + PHI arguments are equal. If not, cancel the jump threading request. + * tree-ssa-threadedge.c (phi_args_equal_on_edges): Moved into + tree-ssa-threadupdate.c + (thread_across_edge): Don't check PHI argument equality when + threading through joiner block here. + +2013-09-17 Andrew MacLeod <amacleod@redhat.com> + + * tree-flow.h (ssa_undefined_value_p): Remove prototype. + * tree-ssa.c (ssa_undefined_value_p): Move pass independent parts here. + (warn_uninit, warn_uninitialized_vars, execute_early_warn_uninitialized, + make_pass_early_warn_uninitialized): Move to tree-ssa-uninit.c. + * tree-ssa-uninit.c (ssa_undefined_value_p): Move to tree-ssa.c + (has_undefined_value_p): New. Pass dependant parts of + ssa_undefined_value_p. + (uninit_undefined_value_p): Use has_undefined_value_p. + (warn_uninit, warn_uninitialized_vars, execute_early_warn_uninitialized, + make_pass_early_warn_uninitialized): Move from tree-ssa.c + * tree-ssa.h: Adjust prototypes + +2013-09-17 Jan Hubicka <jh@suse.cz> + + PR middle-end/58332 + * cif-code.def (FUNCTION_NOT_OPTIMIZED): New CIF code. + * ipa-inline.c (can_inline_edge_p): Do not downgrade + FUNCTION_NOT_OPTIMIZED. + * ipa-inline-analysis.c (compute_inline_parameters): Function + not optimized is not inlinable unless it is alwaysinline. + (inline_analyze_function): Force calls in not optimized + function not inlinable. + +2013-09-17 Jan Hubicka <jh@suse.cz> + + PR middle-end/58329 + * ipa-devirt.c (ipa_devirt): Be ready for symtab_nonoverwritable_alias + to return NULL. + * ipa.c (function_and_variable_visibility): Likewise. + * ipa-profile.c (ipa_profile): Likewise. + +2013-09-17 Bernd Edlinger <bernd.edlinger@hotmail.de> + + PR ipa/58398 + * cgraph.c (cgraph_function_body_availability): Check for ifunc + attribute, and don't inline the resolver in this case. + +2013-09-17 Teresa Johnson <tejohnson@google.com> + + * coverage.c (get_coverage_counts): Add missing newline. + +2013-09-17 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + PR tree-optimization/58088 + * fold-const.c (mask_with_trailing_zeros): New function. + (fold_binary_loc): Make sure we don't recurse infinitely + when the X in (X & C1) | C2 is a tree of the form (Y * K1) & K2. + Use mask_with_trailing_zeros where appropriate. + +2013-09-17 Yuri Rumyantsev <ysrumyan@gmail.com> + + * config/i386/i386.c (distance_agu_use_in_bb) : Proper initialization + of 'prev' var to get better distance estimation. + +2013-09-17 Eric Botcazou <ebotcazou@adacore.com> + + * tree-inline.h (struct copy_body_data): Add transform_parameter. + * tree-inline.c (is_parameter_of): New predicate. + (remap_gimple_op_r): Do not propagate TREE_THIS_NOTRAP on MEM_REF if + a parameter has been remapped. + (copy_tree_body_r): Likewise on INDIRECT_REF and MEM_REF. + (optimize_inline_calls): Initialize transform_parameter. + (copy_gimple_seq_and_replace_locals): Likewise. + (tree_function_versioning): Likewise. + (maybe_inline_call_in_expr): Likewise. + +2013-09-17 Nick Clifton <nickc@redhat.com> + + * config/msp430/msp430-protos.h: Add prototypes for new functions. + * config/msp430/msp430.c (msp430_preserve_reg_p): Add support for + interrupt handlers. + (is_attr_func): New function. + (msp430_is_interrupt_func): New function. + (is_naked_func): New function. + (is_reentrant_func): New function. + (is_critical_func): New function. + (msp430_start_function): Add annotations for function attributes. + (msp430_attr): New function. + (msp430_attribute_table): New. + (msp430_function_section): New function. + (TARGET_ASM_FUNCTION_SECTION): Define. + (msp430_builtin): New enum. + (msp430_init_builtins): New function. + (msp430_builtin_devl): New function. + (msp430_expand_builtin): New function. + (TARGET_INIT_BUILTINS): Define. + (TARGET_EXPAND_BUILTINS): Define. + (TARGET_BUILTIN_DECL): Define. + (msp430_expand_prologue): Add support for naked, interrupt, + critical and reentrant functions. + (msp430_expand_epilogue): Likewise. + (msp430_print_operand): Handle 'O' character. + * config/msp430/msp430.h (TARGET_CPU_CPP_BUILTINS): Define + NO_TRAMPOLINES. + * config/msp430/msp430.md (unspec): Add UNS_DINT, UNS_EINT, + UNS_PUSH_INTR, UNS_POP_INTR, UNS_BIC_SR, UNS_BIS_SR. + (pushm): Use a 'n' rather than an 'i' constraint. + (msp_return): Add generation of the interrupt return instruction. + (disable_interrupts): New pattern. + (enable_interrupts): New pattern. + (push_intr_state): New pattern. + (pop_intr_state): New pattern. + (bic_SR): New pattern. + (bis_SR): New pattern. + * doc/extend.texi: Document MSP430 function attributes and builtin + functions. + +2013-09-17 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58432 + * tree-loop-distribution.c (tree_loop_distribution): Also + scan PHIs for outside loop uses and seed a partition from them. + +2013-09-17 Bin Cheng <bin.cheng@arm.com> + + * gimple-ssa-strength-reduction.c (backtrace_base_for_ref): New. + (restructure_reference): Call backtrace_base_for_ref. + +2013-09-17 Alan Modra <amodra@gmail.com> + + PR target/57589 + * config/rs6000/driver-rs6000.c (elf_platform): Revert 2013-06-11 patch. + +2013-09-16 DJ Delorie <dj@redhat.com> + + * config/rl78/rl78.c (rl78_asm_file_start): Specify alternate + vregs location for RL78/G10. + (rl78_expand_prologue): Avoid SEL on G10. + (rl78_expand_epilogue): Likewise. + (rl78_peep_movhi_p): Can't move a constant to memory in HImode. + * config/rl78/rl78.h (TARGET_CPU_CPP_BUILTINS): Define + __RL78_G10__ when appropriate. + (ASM_SPEC): Pass -mg10 along to the assembler. + * config/rl78/rl78.md (sel_rb): Disable for G10. + * config/rl78/rl78.opt: Add -mg10 option. + * config/rl78/t-rl78: Add -mg10 multilib. + +2013-09-16 Xinliang David Li <davidxl@google.com> + + * tree-if-conv.c (main_tree_if_conversion): Check new flag. + * omp-low.c (omp_max_vf): Ditto. + (expand_omp_simd): Ditto. + * tree-vectorizer.c (vectorize_loops): Ditto. + (gate_vect_slp): Ditto. + (gate_increase_alignment): Ditto. + * tree-ssa-pre.c (inhibit_phi_insertion): Ditto. + * tree-ssa-loop.c (gate_tree_vectorize): Ditto. + (gate_tree_vectorize): Name change. + (tree_vectorize): Ditto. + (pass_vectorize::gate): Call new function. + (pass_vectorize::execute): Ditto. + opts.c: O3 default setting change. + (finish_options): Check new flag. + * doc/invoke.texi: Document new flags. + * common.opt: New flags. + +2013-09-16 Andreas Schwab <schwab@linux-m68k.org> + + * doc/tm.texi.in (Cond Exec Macros): Remove node. + (Condition Code): Don't reference it. + * doc/tm.texi: Regenerate. + +2013-09-16 Vladimir Makarov <vmakarov@redhat.com> + + PR middle-end/58418 + * lra-constraints.c (undo_optional_reloads): Consider all optional + reload even if it did not get a hard reg. + +2013-09-16 Teresa Johnson <tejohnson@google.com> + + * dumpfile.c (dump_loc): Remove newline emission. + * tree-vect-data-refs.c (vect_lanes_optab_supported_p): Add newline + emission to dump_printf_loc calls where missing. + (vect_mark_for_runtime_alias_test): Ditto. + (vect_analyze_data_ref_dependence): Ditto. + (vect_analyze_data_ref_dependences): Ditto. + (vect_slp_analyze_data_ref_dependence): Ditto. + (vect_slp_analyze_data_ref_dependences): Ditto. + (vect_compute_data_ref_alignment): Ditto. + (vect_update_misalignment_for_peel): Ditto. + (vect_verify_datarefs_alignment): Ditto. + (vector_alignment_reachable_p): Ditto. + (vect_get_data_access_cost): Ditto. + (vect_enhance_data_refs_alignment): Ditto. + (vect_find_same_alignment_drs): Ditto. + (vect_analyze_data_refs_alignment): Ditto. + (vect_analyze_group_access): Ditto. + (vect_analyze_data_ref_access): Ditto. + (vect_analyze_data_ref_accesses): Ditto. + (vect_prune_runtime_alias_test_list): Ditto. + (vect_analyze_data_refs): Ditto. + (vect_create_addr_base_for_vector_ref): Ditto. + (vect_create_data_ref_ptr): Ditto. + (vect_grouped_store_supported): Ditto. + (vect_grouped_load_supported): Ditto. + * value-prof.c (check_counter): Ditto. + (check_ic_target): Ditto. + * tree-vect-patterns.c (vect_recog_dot_prod_pattern): Ditto. + (vect_recog_widen_mult_pattern): Ditto. + (vect_recog_widen_sum_pattern): Ditto. + (vect_recog_over_widening_pattern): Ditto. + (vect_recog_widen_shift_pattern): Ditto. + (vect_recog_rotate_pattern): Ditto. + (vect_recog_vector_vector_shift_pattern): Ditto. + (vect_recog_divmod_pattern): Ditto. + (vect_recog_mixed_size_cond_pattern): Ditto. + (vect_recog_bool_pattern): Ditto. + (vect_pattern_recog_1): Ditto. + (vect_pattern_recog): Ditto. + * tree-vect-loop.c (vect_determine_vectorization_factor): Ditto. + (vect_is_simple_iv_evolution): Ditto. + (vect_analyze_scalar_cycles_1): Ditto. + (vect_get_loop_niters): Ditto. + (vect_analyze_loop_1): Ditto. + (vect_analyze_loop_form): Ditto. + (vect_analyze_loop_operations): Ditto. + (vect_analyze_loop_2): Ditto. + (vect_analyze_loop): Ditto. + (report_vect_op): Ditto. + (vect_is_slp_reduction): Ditto. + (vect_is_simple_reduction_1): Ditto. + (vect_get_known_peeling_cost): Ditto. + (vect_estimate_min_profitable_iters): Ditto. + (vect_model_reduction_cost): Ditto. + (vect_model_induction_cost): Ditto. + (get_initial_def_for_induction): Ditto. + (vect_create_epilog_for_reduction): Ditto. + (vectorizable_reduction): Ditto. + (vectorizable_induction): Ditto. + (vectorizable_live_operation): Ditto. + (vect_loop_kill_debug_uses): Ditto. + (vect_transform_loop): Ditto. + * tree-vect-stmts.c (vect_mark_relevant): Ditto. + (vect_stmt_relevant_p): Ditto. + (process_use): Ditto. + (vect_mark_stmts_to_be_vectorized): Ditto. + (vect_model_simple_cost): Ditto. + (vect_model_promotion_demotion_cost): Ditto. + (vect_model_store_cost): Ditto. + (vect_get_store_cost): Ditto. + (vect_model_load_cost): Ditto. + (vect_get_load_cost): Ditto. + (vect_init_vector_1): Ditto. + (vect_get_vec_def_for_operand): Ditto. + (vect_finish_stmt_generation): Ditto. + (vectorizable_call): Ditto. + (vectorizable_conversion): Ditto. + (vectorizable_assignment): Ditto. + (vectorizable_shift): Ditto. + (vectorizable_operation): Ditto. + (vectorizable_store): Ditto. + (vectorizable_load): Ditto. + (vectorizable_condition): Ditto. + (vect_analyze_stmt): Ditto. + (vect_transform_stmt): Ditto. + (vect_is_simple_use): Ditto. + * tree-vect-loop-manip.c (slpeel_make_loop_iterate_ntimes): Ditto. + (vect_can_advance_ivs_p): Ditto. + (vect_update_ivs_after_vectorizer): Ditto. + (vect_do_peeling_for_loop_bound): Ditto. + (vect_gen_niters_for_prolog_loop): Ditto. + (vect_update_inits_of_drs): Ditto. + (vect_create_cond_for_alias_checks): Ditto. + * tree-vect-slp.c (vect_get_and_check_slp_defs): Ditto. + (vect_build_slp_tree_1): Ditto. + (vect_supported_load_permutation_p): Ditto. + (vect_analyze_slp_instance): Ditto. + (vect_analyze_slp): Ditto. + (vect_make_slp_decision): Ditto. + (vect_detect_hybrid_slp): Ditto. + (vect_bb_vectorization_profitable_p): Ditto. + (vect_slp_analyze_bb_1): Ditto. + (vect_update_slp_costs_according_to_vf): Ditto. + (vect_get_mask_element): Ditto. + (vect_transform_slp_perm_load): Ditto. + (vect_schedule_slp_instance): Ditto. + (vect_schedule_slp): Ditto. + (vect_slp_transform_bb): Ditto. + * profile.c (read_profile_edge_counts): Ditto. + (compute_branch_probabilities): Ditto. + * coverage.c (get_coverage_counts): Ditto. + +2013-09-16 Diego Novillo <dnovillo@google.com> + + * tree-core.h: Add missing comment lines from refactoring + of tree.h. + +2013-09-16 Jan Hubicka <jh@suse.cz> + + * gimple-fold.c (can_refer_decl_in_current_unit_p): Do not accept + abstract functions; for static functions check the presence + of body. + +2013-09-16 James Greenhalgh <james.greenhalgh@arm.com> + + * config/aarch64/aarch64-simd-builtins.def (fma): New. + * config/aarch64/aarch64-simd.md + (aarch64_mla_elt<mode>): New. + (aarch64_mla_elt_<vswap_width_name><mode>): Likewise. + (aarch64_mls_elt<mode>): Likewise. + (aarch64_mls_elt_<vswap_width_name><mode>): Likewise. + (aarch64_fma4_elt<mode>): Likewise. + (aarch64_fma4_elt_<vswap_width_name><mode>): Likewise. + (aarch64_fma4_elt_to_128v2df): Likewise. + (aarch64_fma4_elt_to_64df): Likewise. + (fnma<mode>4): Likewise. + (aarch64_fnma4_elt<mode>): Likewise. + (aarch64_fnma4_elt_<vswap_width_name><mode>): Likewise. + (aarch64_fnma4_elt_to_128v2df): Likewise. + (aarch64_fnma4_elt_to_64df): Likewise. + * config/aarch64/iterators.md (VDQSF): New. + * config/aarch64/arm_neon.h + (vfm<as><sdq>_lane<q>_f<32, 64>): Convert to C implementation. + (vml<sa><q>_lane<q>_<fsu><16, 32, 64>): Likewise. + +2013-09-16 James Greenhalgh <james.greenhalgh@arm.com> + + * config/aarch64/aarch64-simd.md (aarch64_mul3_elt<mode>): New. + (aarch64_mul3_elt_<vswap_width_name><mode>): Likewise. + (aarch64_mul3_elt_to_128df): Likewise. + (aarch64_mul3_elt_to_64v2df): Likewise. + * config/aarch64/iterators.md (VEL): Also handle DFmode. + (VMUL): New. + (VMUL_CHANGE_NLANES) Likewise. + (h_con): Likewise. + (f): Likewise. + * config/aarch64/arm_neon.h + (vmul<q>_lane<q>_<suf><16,32,64>): Convert to C implementation. + +2013-09-16 James Greenhalgh <james.greenhalgh@arm.com> + + * config/aarch64/arm_neon.h + (vcvtx_high_f32_f64): Fix parameters. + +2013-09-16 Jan-Benedict Glaw <jbglaw@lug-owl.de> + Uros Bizjak <ubizjak@gmail.com> + + * config/alpha.c: Include tree-ssanames.h. + 2013-09-16 Richard Biener <rguenther@suse.de> * tree-loop-distribution.c (enum rdg_dep_type): Add control_dd. @@ -35,7 +676,8 @@ PR target/48094 * config/darwin.c (darwin_objc2_section): Note if ObjC Metadata is - seen. (darwin_objc1_section): Likewise. + seen. + (darwin_objc1_section): Likewise. (darwin_file_end): Emit Image Info section when required. 2013-09-14 Jan Hubicka <jh@suse.cz> @@ -54,13 +696,13 @@ 2013-09-14 Iain Sandoe <iain@codesourcery.com> PR target/58269 - config/i386/i386.c (ix86_function_arg_regno_p): Make Darwin use the + * config/i386/i386.c (ix86_function_arg_regno_p): Make Darwin use the xmm register set described in the psABI. 2013-09-13 Evgeny Gavrin <e.gavrin@samsung.com> - * dwarf2out.c (should_emit_struct_debug): Add check - for type_decl variable is not NULL. + * dwarf2out.c (should_emit_struct_debug): Add check + for type_decl variable is not NULL. 2013-09-13 Jacek Caban <jacek@codeweavers.com> @@ -252,12 +894,13 @@ tree-flow-inline.h. * tree-flow.h (_edge_var_map, edge_var_map_vector): Move to tree-ssa.h. Move prototypes belonging to tree-ssa.c. - * tree-flow-inline.h (redirect_edge_var_map_def, + * tree-flow-inline.h (redirect_edge_var_map_def, redirect_edge_var_map_result, redirect_edge_var_map_location): Move to tree-ssa.h. * gimple.h: Adjust prototypes. - * tree-ssa.c (useless_type_conversion_p, types_compatible_p): Move to... - * gimple.c (useless_type_conversion_p, types_compatible_p): Here. + * tree-ssa.c (useless_type_conversion_p, types_compatible_p): Move + to... + * gimple.c (useless_type_conversion_p, types_compatible_p): Here. * tree.h: Move prototype to tree-ssa.h. * gengtype.c (open_base_files): Replace tree-flow.h with tree-ssa.h. * Makefile.in: (TREE_SSA_H, TREE_FLOW_H): Adjust dependencies. @@ -267,11 +910,12 @@ ggc-page.c, gimple-fold.c, gimple-iterator.c, gimple-low.c, gimple-pretty-print.c, gimple-ssa-strength-reduction.c, gimple-streamer-in.c, gimple-streamer-out.c, gimple.c, gimplify.c, - graphite-blocking.c, graphite-clast-to-gimple.c, graphite-dependences.c, - graphite-interchange.c, graphite-optimize-isl.c, graphite-poly.c, - graphite-scop-detection.c, graphite-sese-to-poly.c, graphite.c, - ipa-cp.c, ipa-inline-analysis.c, ipa-inline-transform.c, ipa-inline.c, - ipa-prop.c, ipa-pure-const.c, ipa-reference.c, ipa-split.c, ipa-utils.c, + graphite-blocking.c, graphite-clast-to-gimple.c, + graphite-dependences.c, graphite-interchange.c, + graphite-optimize-isl.c, graphite-poly.c, graphite-scop-detection.c, + graphite-sese-to-poly.c, graphite.c, ipa-cp.c, ipa-inline-analysis.c, + ipa-inline-transform.c, ipa-inline.c, ipa-prop.c, ipa-pure-const.c, + ipa-reference.c, ipa-split.c, ipa-utils.c, loop-init.c, lto-cgraph.c, lto-section-in.c, lto-section-out.c, lto-streamer-in.c, lto-streamer-out.c, lto-streamer.c, omp-low.c, passes.c, predict.c, print-tree.c, profile.c, sese.c, targhooks.c, @@ -563,12 +1207,11 @@ * lra.c (lra): Clear lra_optional_reload_pseudos before every constraint pass. - * lra-constraints.c (curr_insn_transform): Switch on optional - reloads. Check destination too to check move insn. + * lra-constraints.c (curr_insn_transform): Switch on optional reloads. + Check destination too to check move insn. (undo_optional_reloads): Add check that the original peudo did not - changed its allocation and the optional reload was inherited on - last inheritance pass. Break loop after deciding to keep optional - reload. + changed its allocation and the optional reload was inherited on last + inheritance pass. Break loop after deciding to keep optional reload. (lra_undo_inheritance): Add check that inherited pseudo still in memory. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index ea8e2bcb3e4..0f54f2b0175 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20130916 +20130920 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index c18f05489ac..6b0ba092134 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,25 @@ +2013-09-18 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/58264 + * gcc-interface/trans.c (Attribute_to_gnu): Define GNAT_PREFIX local + variable and use it throughout. + <Attr_Length>: Note whether the prefix is the dereference of a pointer + to unconstrained array and, in this case, capture the result for both + Attr_First and Attr_Last. + +2013-09-18 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Abstract_State>: New. + +2013-09-18 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/trans.c (gigi): Remove dead code. + +2013-09-18 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/trans.c (Subprogram_Body_to_gnu): Pop the stack of + return variables for subprograms using the CICO mechanism. + 2013-09-13 Dominique Dhumieres <dominiq@lps.ens.fr> * gcc-interface/Makefile.in: Fix darwin Filter to match on $target_os, diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 26342e2a012..456d7ab7ad9 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -4812,6 +4812,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) saved = true; break; + case E_Abstract_State: + /* This is a SPARK annotation that only reaches here when compiling in + ASIS mode and has no characteristics to annotate. */ + gcc_assert (type_annotate_only); + return error_mark_node; + default: gcc_unreachable (); } diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 4048e0aefe9..7e56f22c3f0 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -290,9 +290,6 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED, tree int64_type = gnat_type_for_size (64, 0); struct elab_info *info; int i; -#ifdef ORDINARY_MAP_INSTANCE - struct line_map *map; -#endif max_gnat_nodes = max_gnat_node; @@ -307,10 +304,6 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED, type_annotate_only = (gigi_operating_mode == 1); - /* ??? Disable the generation of the SCO instance table until after the - back-end supports instance based debug info discriminators. */ - Generate_SCO_Instance_Table = False; - for (i = 0; i < number_file; i++) { /* Use the identifier table to make a permanent copy of the filename as @@ -330,11 +323,6 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED, /* We create the line map for a source file at once, with a fixed number of columns chosen to avoid jumping over the next power of 2. */ linemap_add (line_table, LC_ENTER, 0, filename, 1); -#ifdef ORDINARY_MAP_INSTANCE - map = LINEMAPS_ORDINARY_MAP_AT (line_table, i); - if (flag_debug_instances) - ORDINARY_MAP_INSTANCE (map) = file_info_ptr[i].Instance; -#endif linemap_line_start (line_table, file_info_ptr[i].Num_Source_Lines, 252); linemap_position_for_column (line_table, 252 - 1); linemap_add (line_table, LC_LEAVE, 0, NULL, 0); @@ -1403,6 +1391,7 @@ Pragma_to_gnu (Node_Id gnat_node) static tree Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) { + const Node_Id gnat_prefix = Prefix (gnat_node); tree gnu_prefix, gnu_type, gnu_expr; tree gnu_result_type, gnu_result = error_mark_node; bool prefix_unused = false; @@ -1412,13 +1401,13 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) parameter types might be incomplete types coming from a limited with. */ if (Ekind (Etype (gnat_node)) == E_Access_Subprogram_Type && Is_Dispatch_Table_Entity (Etype (gnat_node)) - && Nkind (Prefix (gnat_node)) == N_Identifier - && Is_Subprogram (Entity (Prefix (gnat_node))) - && Is_Public (Entity (Prefix (gnat_node))) - && !present_gnu_tree (Entity (Prefix (gnat_node)))) - gnu_prefix = get_minimal_subprog_decl (Entity (Prefix (gnat_node))); + && Nkind (gnat_prefix) == N_Identifier + && Is_Subprogram (Entity (gnat_prefix)) + && Is_Public (Entity (gnat_prefix)) + && !present_gnu_tree (Entity (gnat_prefix))) + gnu_prefix = get_minimal_subprog_decl (Entity (gnat_prefix)); else - gnu_prefix = gnat_to_gnu (Prefix (gnat_node)); + gnu_prefix = gnat_to_gnu (gnat_prefix); gnu_type = TREE_TYPE (gnu_prefix); /* If the input is a NULL_EXPR, make a new one. */ @@ -1561,8 +1550,8 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) since it can use a special calling convention on some platforms, which cannot be propagated to the access type. */ else if (attribute == Attr_Access - && Nkind (Prefix (gnat_node)) == N_Identifier - && is_cplusplus_method (Entity (Prefix (gnat_node)))) + && Nkind (gnat_prefix) == N_Identifier + && is_cplusplus_method (Entity (gnat_prefix))) post_error ("access to C++ constructor or member function not allowed", gnat_node); @@ -1673,13 +1662,12 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) /* If this is a dereference and we have a special dynamic constrained subtype on the prefix, use it to compute the size; otherwise, use the designated subtype. */ - if (Nkind (Prefix (gnat_node)) == N_Explicit_Dereference) + if (Nkind (gnat_prefix) == N_Explicit_Dereference) { - Node_Id gnat_deref = Prefix (gnat_node); Node_Id gnat_actual_subtype - = Actual_Designated_Subtype (gnat_deref); + = Actual_Designated_Subtype (gnat_prefix); tree gnu_ptr_type - = TREE_TYPE (gnat_to_gnu (Prefix (gnat_deref))); + = TREE_TYPE (gnat_to_gnu (Prefix (gnat_prefix))); if (TYPE_IS_FAT_OR_THIN_POINTER_P (gnu_ptr_type) && Present (gnat_actual_subtype)) @@ -1740,7 +1728,6 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) align = DECL_ALIGN (TREE_OPERAND (gnu_prefix, 1)) / BITS_PER_UNIT; else { - Node_Id gnat_prefix = Prefix (gnat_node); Entity_Id gnat_type = Etype (gnat_prefix); unsigned int double_align; bool is_capped_double, align_clause; @@ -1812,28 +1799,38 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) : 1), i; struct parm_attr_d *pa = NULL; Entity_Id gnat_param = Empty; + bool unconstrained_ptr_deref = false; /* Make sure any implicit dereference gets done. */ gnu_prefix = maybe_implicit_deref (gnu_prefix); gnu_prefix = maybe_unconstrained_array (gnu_prefix); - /* We treat unconstrained array In parameters specially. */ - if (!Is_Constrained (Etype (Prefix (gnat_node)))) - { - Node_Id gnat_prefix = Prefix (gnat_node); - - /* This is the direct case. */ - if (Nkind (gnat_prefix) == N_Identifier - && Ekind (Entity (gnat_prefix)) == E_In_Parameter) - gnat_param = Entity (gnat_prefix); - - /* This is the indirect case. Note that we need to be sure that - the access value cannot be null as we'll hoist the load. */ - if (Nkind (gnat_prefix) == N_Explicit_Dereference - && Nkind (Prefix (gnat_prefix)) == N_Identifier - && Ekind (Entity (Prefix (gnat_prefix))) == E_In_Parameter - && Can_Never_Be_Null (Entity (Prefix (gnat_prefix)))) - gnat_param = Entity (Prefix (gnat_prefix)); + /* We treat unconstrained array In parameters specially. We also note + whether we are dereferencing a pointer to unconstrained array. */ + if (!Is_Constrained (Etype (gnat_prefix))) + switch (Nkind (gnat_prefix)) + { + case N_Identifier: + /* This is the direct case. */ + if (Ekind (Entity (gnat_prefix)) == E_In_Parameter) + gnat_param = Entity (gnat_prefix); + break; + + case N_Explicit_Dereference: + /* This is the indirect case. Note that we need to be sure that + the access value cannot be null as we'll hoist the load. */ + if (Nkind (Prefix (gnat_prefix)) == N_Identifier + && Ekind (Entity (Prefix (gnat_prefix))) == E_In_Parameter) + { + if (Can_Never_Be_Null (Entity (Prefix (gnat_prefix)))) + gnat_param = Entity (Prefix (gnat_prefix)); + } + else + unconstrained_ptr_deref = true; + break; + + default: + break; } /* If the prefix is the view conversion of a constrained array to an @@ -1968,22 +1965,54 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) { gnu_result = build1 (SAVE_EXPR, TREE_TYPE (gnu_result), gnu_result); - if (attribute == Attr_First) - pa->first = gnu_result; - else if (attribute == Attr_Last) - pa->last = gnu_result; - else - pa->length = gnu_result; + switch (attribute) + { + case Attr_First: + pa->first = gnu_result; + break; + + case Attr_Last: + pa->last = gnu_result; + break; + + case Attr_Length: + case Attr_Range_Length: + pa->length = gnu_result; + break; + + default: + gcc_unreachable (); + } } - /* Set the source location onto the predicate of the condition in the - 'Length case but do not do it if the expression is cached to avoid - messing up the debug info. */ - else if ((attribute == Attr_Range_Length || attribute == Attr_Length) - && TREE_CODE (gnu_result) == COND_EXPR - && EXPR_P (TREE_OPERAND (gnu_result, 0))) - set_expr_location_from_node (TREE_OPERAND (gnu_result, 0), - gnat_node); + /* Otherwise, evaluate it each time it is referenced. */ + else + switch (attribute) + { + case Attr_First: + case Attr_Last: + /* If we are dereferencing a pointer to unconstrained array, we + need to capture the value because the pointed-to bounds may + subsequently be released. */ + if (unconstrained_ptr_deref) + gnu_result + = build1 (SAVE_EXPR, TREE_TYPE (gnu_result), gnu_result); + break; + + case Attr_Length: + case Attr_Range_Length: + /* Set the source location onto the predicate of the condition + but not if the expression is cached to avoid messing up the + debug info. */ + if (TREE_CODE (gnu_result) == COND_EXPR + && EXPR_P (TREE_OPERAND (gnu_result, 0))) + set_expr_location_from_node (TREE_OPERAND (gnu_result, 0), + gnat_node); + break; + + default: + gcc_unreachable (); + } break; } @@ -2156,8 +2185,8 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) case Attr_Mechanism_Code: { + Entity_Id gnat_obj = Entity (gnat_prefix); int code; - Entity_Id gnat_obj = Entity (Prefix (gnat_node)); prefix_unused = true; gnu_result_type = get_unpadded_type (Etype (gnat_node)); @@ -2192,10 +2221,11 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) it has a side-effect. But don't do it if the prefix is just an entity name. However, if an access check is needed, we must do it. See second example in AARM 11.6(5.e). */ - if (prefix_unused && TREE_SIDE_EFFECTS (gnu_prefix) - && !Is_Entity_Name (Prefix (gnat_node))) - gnu_result = build_compound_expr (TREE_TYPE (gnu_result), gnu_prefix, - gnu_result); + if (prefix_unused + && TREE_SIDE_EFFECTS (gnu_prefix) + && !Is_Entity_Name (gnat_prefix)) + gnu_result + = build_compound_expr (TREE_TYPE (gnu_result), gnu_prefix, gnu_result); *gnu_result_type_p = gnu_result_type; return gnu_result; @@ -3605,6 +3635,8 @@ Subprogram_Body_to_gnu (Node_Id gnat_node) { tree gnu_retval; + gnu_return_var_stack->pop (); + add_stmt (gnu_result); add_stmt (build1 (LABEL_EXPR, void_type_node, gnu_return_label_stack->last ())); diff --git a/gcc/builtins.c b/gcc/builtins.c index 0ab6d9b5d70..d19ca68baba 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -10313,7 +10313,10 @@ fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED) return fold_builtin_classify_type (NULL_TREE); case BUILT_IN_UNREACHABLE: - if (flag_sanitize & SANITIZE_UNREACHABLE) + if (flag_sanitize & SANITIZE_UNREACHABLE + && (current_function_decl == NULL + || !lookup_attribute ("no_sanitize_undefined", + DECL_ATTRIBUTES (current_function_decl)))) return ubsan_instrument_unreachable (loc); break; diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 3061b4a896d..1772ba56b49 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,10 @@ +2013-09-18 Marek Polacek <polacek@redhat.com> + + PR sanitizer/58411 + * c-common.c (handle_no_sanitize_undefined_attribute): New function. + Declare it. + (struct attribute_spec c_common_att): Add no_sanitize_undefined. + 2013-09-14 Iain Sandoe <iain@codesourcery.com> PR target/48094 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 62aa9fcec2b..8ecb70cfa7c 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -311,6 +311,8 @@ static tree handle_no_sanitize_address_attribute (tree *, tree, tree, int, bool *); static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree, int, bool *); +static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int, + bool *); static tree handle_noinline_attribute (tree *, tree, tree, int, bool *); static tree handle_noclone_attribute (tree *, tree, tree, int, bool *); static tree handle_leaf_attribute (tree *, tree, tree, int, bool *); @@ -722,6 +724,9 @@ const struct attribute_spec c_common_attribute_table[] = { "no_sanitize_address", 0, 0, true, false, false, handle_no_sanitize_address_attribute, false }, + { "no_sanitize_undefined", 0, 0, true, false, false, + handle_no_sanitize_undefined_attribute, + false }, { "warning", 1, 1, true, false, false, handle_error_attribute, false }, { "error", 1, 1, true, false, false, @@ -6575,6 +6580,22 @@ handle_no_address_safety_analysis_attribute (tree *node, tree name, tree, int, return NULL_TREE; } +/* Handle a "no_sanitize_undefined" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int, + bool *no_add_attrs) +{ + if (TREE_CODE (*node) != FUNCTION_DECL) + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + /* Handle a "noinline" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 8b0cc2f5170..81b2018e8c0 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,15 @@ +2013-09-18 Marek Polacek <polacek@redhat.com> + + PR sanitize/58443 + * c-typeck.c (build_binary_op): Properly honor -fsanitize options. + Remove unnecessary check. + +2013-09-18 Marek Polacek <polacek@redhat.com> + + PR sanitizer/58411 + * c-typeck.c (build_binary_op): Don't sanitize function if it has the + no_sanitize_undefined attribute. + 2013-09-13 Kai Tietz <ktietz@redhat.com> PR target/57848 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index e52533ecd6d..7ecafe4894c 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -10496,8 +10496,10 @@ build_binary_op (location_t location, enum tree_code code, return error_mark_node; } - if (flag_sanitize & SANITIZE_UNDEFINED + if ((flag_sanitize & (SANITIZE_SHIFT | SANITIZE_DIVIDE)) && current_function_decl != 0 + && !lookup_attribute ("no_sanitize_undefined", + DECL_ATTRIBUTES (current_function_decl)) && (doing_div_or_mod || doing_shift)) { /* OP0 and/or OP1 might have side-effects. */ @@ -10505,9 +10507,9 @@ build_binary_op (location_t location, enum tree_code code, op1 = c_save_expr (op1); op0 = c_fully_fold (op0, false, NULL); op1 = c_fully_fold (op1, false, NULL); - if (doing_div_or_mod) + if (doing_div_or_mod && (flag_sanitize & SANITIZE_DIVIDE)) instrument_expr = ubsan_instrument_division (location, op0, op1); - else if (doing_shift) + else if (doing_shift && (flag_sanitize & SANITIZE_SHIFT)) instrument_expr = ubsan_instrument_shift (location, code, op0, op1); } @@ -10535,7 +10537,7 @@ build_binary_op (location_t location, enum tree_code code, ret = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, ret); protected_set_expr_location (ret, location); - if ((flag_sanitize & SANITIZE_UNDEFINED) && instrument_expr != NULL) + if (instrument_expr != NULL) ret = fold_build2 (COMPOUND_EXPR, TREE_TYPE (ret), instrument_expr, ret); diff --git a/gcc/cgraph.c b/gcc/cgraph.c index ebc48bf8aec..722f8ca97e9 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -870,12 +870,12 @@ cgraph_create_edge_1 (struct cgraph_node *caller, struct cgraph_node *callee, edge->call_stmt_cannot_inline_p = true; else edge->call_stmt_cannot_inline_p = false; - if (call_stmt && caller->call_site_hash) - cgraph_add_edge_to_call_site_hash (edge); edge->indirect_info = NULL; edge->indirect_inlining_edge = 0; edge->speculative = false; + if (call_stmt && caller->call_site_hash) + cgraph_add_edge_to_call_site_hash (edge); return edge; } @@ -2048,6 +2048,8 @@ cgraph_function_body_availability (struct cgraph_node *node) avail = AVAIL_LOCAL; else if (node->symbol.alias && node->symbol.weakref) cgraph_function_or_thunk_node (node, &avail); + else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (node->symbol.decl))) + avail = AVAIL_OVERWRITABLE; else if (!node->symbol.externally_visible) avail = AVAIL_AVAILABLE; /* Inline functions are safe to be analyzed even if their symbol can diff --git a/gcc/cif-code.def b/gcc/cif-code.def index d1c49417325..e71123dc609 100644 --- a/gcc/cif-code.def +++ b/gcc/cif-code.def @@ -37,6 +37,9 @@ DEFCIFCODE(UNSPECIFIED , "") functions that have not been rejected for inlining yet. */ DEFCIFCODE(FUNCTION_NOT_CONSIDERED, N_("function not considered for inlining")) +/* Caller is compiled with optimizations disabled. */ +DEFCIFCODE(FUNCTION_NOT_OPTIMIZED, N_("caller is not optimized")) + /* Inlining failed owing to unavailable function body. */ DEFCIFCODE(BODY_NOT_AVAILABLE, N_("function body not available")) diff --git a/gcc/compare-elim.c b/gcc/compare-elim.c index e907376c577..19cf524b1f9 100644 --- a/gcc/compare-elim.c +++ b/gcc/compare-elim.c @@ -243,13 +243,21 @@ find_flags_uses_in_insn (struct comparison *cmp, rtx insn) cmp->missing_uses = true; } +class find_comparison_dom_walker : public dom_walker +{ +public: + find_comparison_dom_walker (cdi_direction direction) + : dom_walker(direction) {} + + virtual void before_dom_children (basic_block); +}; + /* Identify comparison instructions within BB. If the flags from the last compare in the BB is live at the end of the block, install the compare - in BB->AUX. Called via walk_dominators_tree. */ + in BB->AUX. Called via dom_walker.walk (). */ -static void -find_comparisons_in_bb (struct dom_walk_data *data ATTRIBUTE_UNUSED, - basic_block bb) +void +find_comparison_dom_walker::before_dom_children (basic_block bb) { struct comparison *last_cmp; rtx insn, next, last_clobber; @@ -403,17 +411,10 @@ find_comparisons_in_bb (struct dom_walk_data *data ATTRIBUTE_UNUSED, static void find_comparisons (void) { - struct dom_walk_data data; - - memset (&data, 0, sizeof(data)); - data.dom_direction = CDI_DOMINATORS; - data.before_dom_children = find_comparisons_in_bb; - calculate_dominance_info (CDI_DOMINATORS); - init_walk_dominator_tree (&data); - walk_dominator_tree (&data, ENTRY_BLOCK_PTR); - fini_walk_dominator_tree (&data); + find_comparison_dom_walker (CDI_DOMINATORS) + .walk (cfun->cfg->x_entry_block_ptr); clear_aux_for_blocks (); free_dominance_info (CDI_DOMINATORS); diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def index 4046d7a7001..35897f39395 100644 --- a/gcc/config/aarch64/aarch64-simd-builtins.def +++ b/gcc/config/aarch64/aarch64-simd-builtins.def @@ -359,3 +359,6 @@ /* Implemented by aarch64_st1<VALL:mode>. */ BUILTIN_VALL (STORE1, st1, 0) + /* Implemented by fma<mode>4. */ + BUILTIN_VDQF (TERNOP, fma, 4) + diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 9805197a22b..f13cd5b7cdb 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -582,6 +582,59 @@ (set_attr "simd_mode" "<MODE>")] ) +(define_insn "*aarch64_mul3_elt<mode>" + [(set (match_operand:VMUL 0 "register_operand" "=w") + (mult:VMUL + (vec_duplicate:VMUL + (vec_select:<VEL> + (match_operand:VMUL 1 "register_operand" "<h_con>") + (parallel [(match_operand:SI 2 "immediate_operand")]))) + (match_operand:VMUL 3 "register_operand" "w")))] + "TARGET_SIMD" + "<f>mul\\t%0.<Vtype>, %3.<Vtype>, %1.<Vetype>[%2]" + [(set_attr "simd_type" "simd_<f>mul_elt") + (set_attr "simd_mode" "<MODE>")] +) + +(define_insn "*aarch64_mul3_elt_<vswap_width_name><mode>" + [(set (match_operand:VMUL_CHANGE_NLANES 0 "register_operand" "=w") + (mult:VMUL_CHANGE_NLANES + (vec_duplicate:VMUL_CHANGE_NLANES + (vec_select:<VEL> + (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>") + (parallel [(match_operand:SI 2 "immediate_operand")]))) + (match_operand:VMUL_CHANGE_NLANES 3 "register_operand" "w")))] + "TARGET_SIMD" + "<f>mul\\t%0.<Vtype>, %3.<Vtype>, %1.<Vetype>[%2]" + [(set_attr "simd_type" "simd_<f>mul_elt") + (set_attr "simd_mode" "<MODE>")] +) + +(define_insn "*aarch64_mul3_elt_to_128df" + [(set (match_operand:V2DF 0 "register_operand" "=w") + (mult:V2DF + (vec_duplicate:V2DF + (match_operand:DF 2 "register_operand" "w")) + (match_operand:V2DF 1 "register_operand" "w")))] + "TARGET_SIMD" + "fmul\\t%0.2d, %1.2d, %2.d[0]" + [(set_attr "simd_type" "simd_fmul_elt") + (set_attr "simd_mode" "V2DF")] +) + +(define_insn "*aarch64_mul3_elt_to_64v2df" + [(set (match_operand:DF 0 "register_operand" "=w") + (mult:DF + (vec_select:DF + (match_operand:V2DF 1 "register_operand" "w") + (parallel [(match_operand:SI 2 "immediate_operand")])) + (match_operand:DF 3 "register_operand" "w")))] + "TARGET_SIMD" + "fmul\\t%0.2d, %3.2d, %1.d[%2]" + [(set_attr "simd_type" "simd_fmul_elt") + (set_attr "simd_mode" "V2DF")] +) + (define_insn "neg<mode>2" [(set (match_operand:VDQ 0 "register_operand" "=w") (neg:VDQ (match_operand:VDQ 1 "register_operand" "w")))] @@ -1017,6 +1070,38 @@ (set_attr "simd_mode" "<MODE>")] ) +(define_insn "*aarch64_mla_elt<mode>" + [(set (match_operand:VDQHS 0 "register_operand" "=w") + (plus:VDQHS + (mult:VDQHS + (vec_duplicate:VDQHS + (vec_select:<VEL> + (match_operand:VDQHS 1 "register_operand" "<h_con>") + (parallel [(match_operand:SI 2 "immediate_operand")]))) + (match_operand:VDQHS 3 "register_operand" "w")) + (match_operand:VDQHS 4 "register_operand" "0")))] + "TARGET_SIMD" + "mla\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]" + [(set_attr "simd_type" "simd_mla") + (set_attr "simd_mode" "<MODE>")] +) + +(define_insn "*aarch64_mla_elt_<vswap_width_name><mode>" + [(set (match_operand:VDQHS 0 "register_operand" "=w") + (plus:VDQHS + (mult:VDQHS + (vec_duplicate:VDQHS + (vec_select:<VEL> + (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>") + (parallel [(match_operand:SI 2 "immediate_operand")]))) + (match_operand:VDQHS 3 "register_operand" "w")) + (match_operand:VDQHS 4 "register_operand" "0")))] + "TARGET_SIMD" + "mla\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]" + [(set_attr "simd_type" "simd_mla") + (set_attr "simd_mode" "<MODE>")] +) + (define_insn "aarch64_mls<mode>" [(set (match_operand:VQ_S 0 "register_operand" "=w") (minus:VQ_S (match_operand:VQ_S 1 "register_operand" "0") @@ -1028,6 +1113,38 @@ (set_attr "simd_mode" "<MODE>")] ) +(define_insn "*aarch64_mls_elt<mode>" + [(set (match_operand:VDQHS 0 "register_operand" "=w") + (minus:VDQHS + (match_operand:VDQHS 4 "register_operand" "0") + (mult:VDQHS + (vec_duplicate:VDQHS + (vec_select:<VEL> + (match_operand:VDQHS 1 "register_operand" "<h_con>") + (parallel [(match_operand:SI 2 "immediate_operand")]))) + (match_operand:VDQHS 3 "register_operand" "w"))))] + "TARGET_SIMD" + "mls\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]" + [(set_attr "simd_type" "simd_mla") + (set_attr "simd_mode" "<MODE>")] +) + +(define_insn "*aarch64_mls_elt_<vswap_width_name><mode>" + [(set (match_operand:VDQHS 0 "register_operand" "=w") + (minus:VDQHS + (match_operand:VDQHS 4 "register_operand" "0") + (mult:VDQHS + (vec_duplicate:VDQHS + (vec_select:<VEL> + (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>") + (parallel [(match_operand:SI 2 "immediate_operand")]))) + (match_operand:VDQHS 3 "register_operand" "w"))))] + "TARGET_SIMD" + "mls\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]" + [(set_attr "simd_type" "simd_mla") + (set_attr "simd_mode" "<MODE>")] +) + ;; Max/Min operations. (define_insn "<su><maxmin><mode>3" [(set (match_operand:VQ_S 0 "register_operand" "=w") @@ -1430,6 +1547,137 @@ (set_attr "simd_mode" "<MODE>")] ) +(define_insn "*aarch64_fma4_elt<mode>" + [(set (match_operand:VDQF 0 "register_operand" "=w") + (fma:VDQF + (vec_duplicate:VDQF + (vec_select:<VEL> + (match_operand:VDQF 1 "register_operand" "<h_con>") + (parallel [(match_operand:SI 2 "immediate_operand")]))) + (match_operand:VDQF 3 "register_operand" "w") + (match_operand:VDQF 4 "register_operand" "0")))] + "TARGET_SIMD" + "fmla\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]" + [(set_attr "simd_type" "simd_fmla_elt") + (set_attr "simd_mode" "<MODE>")] +) + +(define_insn "*aarch64_fma4_elt_<vswap_width_name><mode>" + [(set (match_operand:VDQSF 0 "register_operand" "=w") + (fma:VDQSF + (vec_duplicate:VDQSF + (vec_select:<VEL> + (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>") + (parallel [(match_operand:SI 2 "immediate_operand")]))) + (match_operand:VDQSF 3 "register_operand" "w") + (match_operand:VDQSF 4 "register_operand" "0")))] + "TARGET_SIMD" + "fmla\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]" + [(set_attr "simd_type" "simd_fmla_elt") + (set_attr "simd_mode" "<MODE>")] +) + +(define_insn "*aarch64_fma4_elt_to_128df" + [(set (match_operand:V2DF 0 "register_operand" "=w") + (fma:V2DF + (vec_duplicate:V2DF + (match_operand:DF 1 "register_operand" "w")) + (match_operand:V2DF 2 "register_operand" "w") + (match_operand:V2DF 3 "register_operand" "0")))] + "TARGET_SIMD" + "fmla\\t%0.2d, %2.2d, %1.2d[0]" + [(set_attr "simd_type" "simd_fmla_elt") + (set_attr "simd_mode" "V2DF")] +) + +(define_insn "*aarch64_fma4_elt_to_64v2df" + [(set (match_operand:DF 0 "register_operand" "=w") + (fma:DF + (vec_select:DF + (match_operand:V2DF 1 "register_operand" "w") + (parallel [(match_operand:SI 2 "immediate_operand")])) + (match_operand:DF 3 "register_operand" "w") + (match_operand:DF 4 "register_operand" "0")))] + "TARGET_SIMD" + "fmla\\t%0.2d, %3.2d, %1.2d[%2]" + [(set_attr "simd_type" "simd_fmla_elt") + (set_attr "simd_mode" "V2DF")] +) + +(define_insn "fnma<mode>4" + [(set (match_operand:VDQF 0 "register_operand" "=w") + (fma:VDQF + (match_operand:VDQF 1 "register_operand" "w") + (neg:VDQF + (match_operand:VDQF 2 "register_operand" "w")) + (match_operand:VDQF 3 "register_operand" "0")))] + "TARGET_SIMD" + "fmls\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>" + [(set_attr "simd_type" "simd_fmla") + (set_attr "simd_mode" "<MODE>")] +) + +(define_insn "*aarch64_fnma4_elt<mode>" + [(set (match_operand:VDQF 0 "register_operand" "=w") + (fma:VDQF + (neg:VDQF + (match_operand:VDQF 3 "register_operand" "w")) + (vec_duplicate:VDQF + (vec_select:<VEL> + (match_operand:VDQF 1 "register_operand" "<h_con>") + (parallel [(match_operand:SI 2 "immediate_operand")]))) + (match_operand:VDQF 4 "register_operand" "0")))] + "TARGET_SIMD" + "fmls\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]" + [(set_attr "simd_type" "simd_fmla_elt") + (set_attr "simd_mode" "<MODE>")] +) + +(define_insn "*aarch64_fnma4_elt_<vswap_width_name><mode>" + [(set (match_operand:VDQSF 0 "register_operand" "=w") + (fma:VDQSF + (neg:VDQSF + (match_operand:VDQSF 3 "register_operand" "w")) + (vec_duplicate:VDQSF + (vec_select:<VEL> + (match_operand:<VSWAP_WIDTH> 1 "register_operand" "<h_con>") + (parallel [(match_operand:SI 2 "immediate_operand")]))) + (match_operand:VDQSF 4 "register_operand" "0")))] + "TARGET_SIMD" + "fmls\\t%0.<Vtype>, %3.<Vtype>, %1.<Vtype>[%2]" + [(set_attr "simd_type" "simd_fmla_elt") + (set_attr "simd_mode" "<MODE>")] +) + +(define_insn "*aarch64_fnma4_elt_to_128df" + [(set (match_operand:V2DF 0 "register_operand" "=w") + (fma:V2DF + (neg:V2DF + (match_operand:V2DF 2 "register_operand" "w")) + (vec_duplicate:V2DF + (match_operand:DF 1 "register_operand" "w")) + (match_operand:V2DF 3 "register_operand" "0")))] + "TARGET_SIMD" + "fmls\\t%0.2d, %2.2d, %1.2d[0]" + [(set_attr "simd_type" "simd_fmla_elt") + (set_attr "simd_mode" "V2DF")] +) + +(define_insn "*aarch64_fnma4_elt_to_64v2df" + [(set (match_operand:DF 0 "register_operand" "=w") + (fma:DF + (vec_select:DF + (match_operand:V2DF 1 "register_operand" "w") + (parallel [(match_operand:SI 2 "immediate_operand")])) + (neg:DF + (match_operand:DF 3 "register_operand" "w")) + (match_operand:DF 4 "register_operand" "0")))] + "TARGET_SIMD" + "fmls\\t%0.2d, %3.2d, %1.2d[%2]" + [(set_attr "simd_type" "simd_fmla_elt") + (set_attr "simd_mode" "V2DF")] +) + ;; Vector versions of the floating-point frint patterns. ;; Expands to btrunc, ceil, floor, nearbyint, rint, round. (define_insn "<frint_pattern><mode>2" diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h index c7e882a3d23..cb5860206a1 100644 --- a/gcc/config/aarch64/arm_neon.h +++ b/gcc/config/aarch64/arm_neon.h @@ -5756,12 +5756,12 @@ vcvtx_f32_f64 (float64x2_t a) } __extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -vcvtx_high_f32_f64 (float64x2_t a) +vcvtx_high_f32_f64 (float32x2_t a, float64x2_t b) { float32x4_t result; __asm__ ("fcvtxn2 %0.4s,%1.2d" : "=w"(result) - : "w"(a) + : "w" (b), "0"(a) : /* No clobbers */); return result; } @@ -6100,33 +6100,6 @@ vfma_f32 (float32x2_t a, float32x2_t b, float32x2_t c) return result; } -#define vfma_lane_f32(a, b, c, d) \ - __extension__ \ - ({ \ - float32x2_t c_ = (c); \ - float32x2_t b_ = (b); \ - float32x2_t a_ = (a); \ - float32x2_t result; \ - __asm__ ("fmla %0.2s,%2.2s,%3.s[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vfmad_lane_f64(a, b, c) \ - __extension__ \ - ({ \ - float64x2_t b_ = (b); \ - float64_t a_ = (a); \ - float64_t result; \ - __asm__ ("fmla %d0,%d1,%2.d[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - __extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) vfmaq_f32 (float32x4_t a, float32x4_t b, float32x4_t c) { @@ -6149,47 +6122,6 @@ vfmaq_f64 (float64x2_t a, float64x2_t b, float64x2_t c) return result; } -#define vfmaq_lane_f32(a, b, c, d) \ - __extension__ \ - ({ \ - float32x4_t c_ = (c); \ - float32x4_t b_ = (b); \ - float32x4_t a_ = (a); \ - float32x4_t result; \ - __asm__ ("fmla %0.4s,%2.4s,%3.s[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vfmaq_lane_f64(a, b, c, d) \ - __extension__ \ - ({ \ - float64x2_t c_ = (c); \ - float64x2_t b_ = (b); \ - float64x2_t a_ = (a); \ - float64x2_t result; \ - __asm__ ("fmla %0.2d,%2.2d,%3.d[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vfmas_lane_f32(a, b, c) \ - __extension__ \ - ({ \ - float32x4_t b_ = (b); \ - float32_t a_ = (a); \ - float32_t result; \ - __asm__ ("fmla %s0,%s1,%2.s[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) vfma_n_f32 (float32x2_t a, float32x2_t b, float32_t c) { @@ -6234,19 +6166,6 @@ vfms_f32 (float32x2_t a, float32x2_t b, float32x2_t c) return result; } -#define vfmsd_lane_f64(a, b, c) \ - __extension__ \ - ({ \ - float64x2_t b_ = (b); \ - float64_t a_ = (a); \ - float64_t result; \ - __asm__ ("fmls %d0,%d1,%2.d[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - __extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) vfmsq_f32 (float32x4_t a, float32x4_t b, float32x4_t c) { @@ -6269,19 +6188,6 @@ vfmsq_f64 (float64x2_t a, float64x2_t b, float64x2_t c) return result; } -#define vfmss_lane_f32(a, b, c) \ - __extension__ \ - ({ \ - float32x4_t b_ = (b); \ - float32_t a_ = (a); \ - float32_t result; \ - __asm__ ("fmls %s0,%s1,%2.s[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) vget_high_f32 (float32x4_t a) { @@ -7122,133 +7028,6 @@ vld1q_dup_u64 (const uint64_t * a) result; \ }) -#define vmla_lane_f32(a, b, c, d) \ - __extension__ \ - ({ \ - float32x2_t c_ = (c); \ - float32x2_t b_ = (b); \ - float32x2_t a_ = (a); \ - float32x2_t result; \ - float32x2_t t1; \ - __asm__ ("fmul %1.2s, %3.2s, %4.s[%5]; fadd %0.2s, %0.2s, %1.2s" \ - : "=w"(result), "=w"(t1) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmla_lane_s16(a, b, c, d) \ - __extension__ \ - ({ \ - int16x4_t c_ = (c); \ - int16x4_t b_ = (b); \ - int16x4_t a_ = (a); \ - int16x4_t result; \ - __asm__ ("mla %0.4h, %2.4h, %3.h[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmla_lane_s32(a, b, c, d) \ - __extension__ \ - ({ \ - int32x2_t c_ = (c); \ - int32x2_t b_ = (b); \ - int32x2_t a_ = (a); \ - int32x2_t result; \ - __asm__ ("mla %0.2s, %2.2s, %3.s[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmla_lane_u16(a, b, c, d) \ - __extension__ \ - ({ \ - uint16x4_t c_ = (c); \ - uint16x4_t b_ = (b); \ - uint16x4_t a_ = (a); \ - uint16x4_t result; \ - __asm__ ("mla %0.4h, %2.4h, %3.h[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmla_lane_u32(a, b, c, d) \ - __extension__ \ - ({ \ - uint32x2_t c_ = (c); \ - uint32x2_t b_ = (b); \ - uint32x2_t a_ = (a); \ - uint32x2_t result; \ - __asm__ ("mla %0.2s, %2.2s, %3.s[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmla_laneq_s16(a, b, c, d) \ - __extension__ \ - ({ \ - int16x8_t c_ = (c); \ - int16x4_t b_ = (b); \ - int16x4_t a_ = (a); \ - int16x4_t result; \ - __asm__ ("mla %0.4h, %2.4h, %3.h[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmla_laneq_s32(a, b, c, d) \ - __extension__ \ - ({ \ - int32x4_t c_ = (c); \ - int32x2_t b_ = (b); \ - int32x2_t a_ = (a); \ - int32x2_t result; \ - __asm__ ("mla %0.2s, %2.2s, %3.s[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmla_laneq_u16(a, b, c, d) \ - __extension__ \ - ({ \ - uint16x8_t c_ = (c); \ - uint16x4_t b_ = (b); \ - uint16x4_t a_ = (a); \ - uint16x4_t result; \ - __asm__ ("mla %0.4h, %2.4h, %3.h[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmla_laneq_u32(a, b, c, d) \ - __extension__ \ - ({ \ - uint32x4_t c_ = (c); \ - uint32x2_t b_ = (b); \ - uint32x2_t a_ = (a); \ - uint32x2_t result; \ - __asm__ ("mla %0.2s, %2.2s, %3.s[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) vmla_n_f32 (float32x2_t a, float32x2_t b, float32_t c) { @@ -7815,133 +7594,6 @@ vmlal_u32 (uint64x2_t a, uint32x2_t b, uint32x2_t c) return result; } -#define vmlaq_lane_f32(a, b, c, d) \ - __extension__ \ - ({ \ - float32x4_t c_ = (c); \ - float32x4_t b_ = (b); \ - float32x4_t a_ = (a); \ - float32x4_t result; \ - float32x4_t t1; \ - __asm__ ("fmul %1.4s, %3.4s, %4.s[%5]; fadd %0.4s, %0.4s, %1.4s" \ - : "=w"(result), "=w"(t1) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmlaq_lane_s16(a, b, c, d) \ - __extension__ \ - ({ \ - int16x8_t c_ = (c); \ - int16x8_t b_ = (b); \ - int16x8_t a_ = (a); \ - int16x8_t result; \ - __asm__ ("mla %0.8h, %2.8h, %3.h[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmlaq_lane_s32(a, b, c, d) \ - __extension__ \ - ({ \ - int32x4_t c_ = (c); \ - int32x4_t b_ = (b); \ - int32x4_t a_ = (a); \ - int32x4_t result; \ - __asm__ ("mla %0.4s, %2.4s, %3.s[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmlaq_lane_u16(a, b, c, d) \ - __extension__ \ - ({ \ - uint16x8_t c_ = (c); \ - uint16x8_t b_ = (b); \ - uint16x8_t a_ = (a); \ - uint16x8_t result; \ - __asm__ ("mla %0.8h, %2.8h, %3.h[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmlaq_lane_u32(a, b, c, d) \ - __extension__ \ - ({ \ - uint32x4_t c_ = (c); \ - uint32x4_t b_ = (b); \ - uint32x4_t a_ = (a); \ - uint32x4_t result; \ - __asm__ ("mla %0.4s, %2.4s, %3.s[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmlaq_laneq_s16(a, b, c, d) \ - __extension__ \ - ({ \ - int16x8_t c_ = (c); \ - int16x8_t b_ = (b); \ - int16x8_t a_ = (a); \ - int16x8_t result; \ - __asm__ ("mla %0.8h, %2.8h, %3.h[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmlaq_laneq_s32(a, b, c, d) \ - __extension__ \ - ({ \ - int32x4_t c_ = (c); \ - int32x4_t b_ = (b); \ - int32x4_t a_ = (a); \ - int32x4_t result; \ - __asm__ ("mla %0.4s, %2.4s, %3.s[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmlaq_laneq_u16(a, b, c, d) \ - __extension__ \ - ({ \ - uint16x8_t c_ = (c); \ - uint16x8_t b_ = (b); \ - uint16x8_t a_ = (a); \ - uint16x8_t result; \ - __asm__ ("mla %0.8h, %2.8h, %3.h[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmlaq_laneq_u32(a, b, c, d) \ - __extension__ \ - ({ \ - uint32x4_t c_ = (c); \ - uint32x4_t b_ = (b); \ - uint32x4_t a_ = (a); \ - uint32x4_t result; \ - __asm__ ("mla %0.4s, %2.4s, %3.s[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - __extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) vmlaq_n_f32 (float32x4_t a, float32x4_t b, float32_t c) { @@ -8076,77 +7728,6 @@ vmlaq_u32 (uint32x4_t a, uint32x4_t b, uint32x4_t c) return result; } -#define vmls_lane_f32(a, b, c, d) \ - __extension__ \ - ({ \ - float32x2_t c_ = (c); \ - float32x2_t b_ = (b); \ - float32x2_t a_ = (a); \ - float32x2_t result; \ - float32x2_t t1; \ - __asm__ ("fmul %1.2s, %3.2s, %4.s[%5]; fsub %0.2s, %0.2s, %1.2s" \ - : "=w"(result), "=w"(t1) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmls_lane_s16(a, b, c, d) \ - __extension__ \ - ({ \ - int16x4_t c_ = (c); \ - int16x4_t b_ = (b); \ - int16x4_t a_ = (a); \ - int16x4_t result; \ - __asm__ ("mls %0.4h,%2.4h,%3.h[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmls_lane_s32(a, b, c, d) \ - __extension__ \ - ({ \ - int32x2_t c_ = (c); \ - int32x2_t b_ = (b); \ - int32x2_t a_ = (a); \ - int32x2_t result; \ - __asm__ ("mls %0.2s,%2.2s,%3.s[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmls_lane_u16(a, b, c, d) \ - __extension__ \ - ({ \ - uint16x4_t c_ = (c); \ - uint16x4_t b_ = (b); \ - uint16x4_t a_ = (a); \ - uint16x4_t result; \ - __asm__ ("mls %0.4h,%2.4h,%3.h[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmls_lane_u32(a, b, c, d) \ - __extension__ \ - ({ \ - uint32x2_t c_ = (c); \ - uint32x2_t b_ = (b); \ - uint32x2_t a_ = (a); \ - uint32x2_t result; \ - __asm__ ("mls %0.2s,%2.2s,%3.s[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) vmls_n_f32 (float32x2_t a, float32x2_t b, float32_t c) { @@ -8713,148 +8294,6 @@ vmlsl_u32 (uint64x2_t a, uint32x2_t b, uint32x2_t c) return result; } -#define vmlsq_lane_f32(a, b, c, d) \ - __extension__ \ - ({ \ - float32x4_t c_ = (c); \ - float32x4_t b_ = (b); \ - float32x4_t a_ = (a); \ - float32x4_t result; \ - float32x4_t t1; \ - __asm__ ("fmul %1.4s, %3.4s, %4.s[%5]; fsub %0.4s, %0.4s, %1.4s" \ - : "=w"(result), "=w"(t1) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmlsq_lane_s16(a, b, c, d) \ - __extension__ \ - ({ \ - int16x8_t c_ = (c); \ - int16x8_t b_ = (b); \ - int16x8_t a_ = (a); \ - int16x8_t result; \ - __asm__ ("mls %0.8h,%2.8h,%3.h[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmlsq_lane_s32(a, b, c, d) \ - __extension__ \ - ({ \ - int32x4_t c_ = (c); \ - int32x4_t b_ = (b); \ - int32x4_t a_ = (a); \ - int32x4_t result; \ - __asm__ ("mls %0.4s,%2.4s,%3.s[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmlsq_lane_u16(a, b, c, d) \ - __extension__ \ - ({ \ - uint16x8_t c_ = (c); \ - uint16x8_t b_ = (b); \ - uint16x8_t a_ = (a); \ - uint16x8_t result; \ - __asm__ ("mls %0.8h,%2.8h,%3.h[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmlsq_lane_u32(a, b, c, d) \ - __extension__ \ - ({ \ - uint32x4_t c_ = (c); \ - uint32x4_t b_ = (b); \ - uint32x4_t a_ = (a); \ - uint32x4_t result; \ - __asm__ ("mls %0.4s,%2.4s,%3.s[%4]" \ - : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmlsq_laneq_f32(__a, __b, __c, __d) \ - __extension__ \ - ({ \ - float32x4_t __c_ = (__c); \ - float32x4_t __b_ = (__b); \ - float32x4_t __a_ = (__a); \ - float32x4_t __result; \ - float32x4_t __t1; \ - __asm__ ("fmul %1.4s, %3.4s, %4.s[%5]; fsub %0.4s, %0.4s, %1.4s" \ - : "=w"(__result), "=w"(__t1) \ - : "0"(__a_), "w"(__b_), "w"(__c_), "i"(__d) \ - : /* No clobbers */); \ - __result; \ - }) - -#define vmlsq_laneq_s16(__a, __b, __c, __d) \ - __extension__ \ - ({ \ - int16x8_t __c_ = (__c); \ - int16x8_t __b_ = (__b); \ - int16x8_t __a_ = (__a); \ - int16x8_t __result; \ - __asm__ ("mls %0.8h, %2.8h, %3.h[%4]" \ - : "=w"(__result) \ - : "0"(__a_), "w"(__b_), "x"(__c_), "i"(__d) \ - : /* No clobbers */); \ - __result; \ - }) - -#define vmlsq_laneq_s32(__a, __b, __c, __d) \ - __extension__ \ - ({ \ - int32x4_t __c_ = (__c); \ - int32x4_t __b_ = (__b); \ - int32x4_t __a_ = (__a); \ - int32x4_t __result; \ - __asm__ ("mls %0.4s, %2.4s, %3.s[%4]" \ - : "=w"(__result) \ - : "0"(__a_), "w"(__b_), "w"(__c_), "i"(__d) \ - : /* No clobbers */); \ - __result; \ - }) - -#define vmlsq_laneq_u16(__a, __b, __c, __d) \ - __extension__ \ - ({ \ - uint16x8_t __c_ = (__c); \ - uint16x8_t __b_ = (__b); \ - uint16x8_t __a_ = (__a); \ - uint16x8_t __result; \ - __asm__ ("mls %0.8h, %2.8h, %3.h[%4]" \ - : "=w"(__result) \ - : "0"(__a_), "w"(__b_), "x"(__c_), "i"(__d) \ - : /* No clobbers */); \ - __result; \ - }) - -#define vmlsq_laneq_u32(__a, __b, __c, __d) \ - __extension__ \ - ({ \ - uint32x4_t __c_ = (__c); \ - uint32x4_t __b_ = (__b); \ - uint32x4_t __a_ = (__a); \ - uint32x4_t __result; \ - __asm__ ("mls %0.4s, %2.4s, %3.s[%4]" \ - : "=w"(__result) \ - : "0"(__a_), "w"(__b_), "w"(__c_), "i"(__d) \ - : /* No clobbers */); \ - __result; \ - }) - __extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) vmlsq_n_f32 (float32x4_t a, float32x4_t b, float32_t c) { @@ -9501,136 +8940,6 @@ vmovq_n_u64 (uint64_t a) return result; } -#define vmul_lane_f32(a, b, c) \ - __extension__ \ - ({ \ - float32x2_t b_ = (b); \ - float32x2_t a_ = (a); \ - float32x2_t result; \ - __asm__ ("fmul %0.2s,%1.2s,%2.s[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmul_lane_s16(a, b, c) \ - __extension__ \ - ({ \ - int16x4_t b_ = (b); \ - int16x4_t a_ = (a); \ - int16x4_t result; \ - __asm__ ("mul %0.4h,%1.4h,%2.h[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmul_lane_s32(a, b, c) \ - __extension__ \ - ({ \ - int32x2_t b_ = (b); \ - int32x2_t a_ = (a); \ - int32x2_t result; \ - __asm__ ("mul %0.2s,%1.2s,%2.s[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmul_lane_u16(a, b, c) \ - __extension__ \ - ({ \ - uint16x4_t b_ = (b); \ - uint16x4_t a_ = (a); \ - uint16x4_t result; \ - __asm__ ("mul %0.4h,%1.4h,%2.h[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmul_lane_u32(a, b, c) \ - __extension__ \ - ({ \ - uint32x2_t b_ = (b); \ - uint32x2_t a_ = (a); \ - uint32x2_t result; \ - __asm__ ("mul %0.2s, %1.2s, %2.s[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmul_laneq_f32(a, b, c) \ - __extension__ \ - ({ \ - float32x4_t b_ = (b); \ - float32x2_t a_ = (a); \ - float32x2_t result; \ - __asm__ ("fmul %0.2s, %1.2s, %2.s[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmul_laneq_s16(a, b, c) \ - __extension__ \ - ({ \ - int16x8_t b_ = (b); \ - int16x4_t a_ = (a); \ - int16x4_t result; \ - __asm__ ("mul %0.4h, %1.4h, %2.h[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmul_laneq_s32(a, b, c) \ - __extension__ \ - ({ \ - int32x4_t b_ = (b); \ - int32x2_t a_ = (a); \ - int32x2_t result; \ - __asm__ ("mul %0.2s, %1.2s, %2.s[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmul_laneq_u16(a, b, c) \ - __extension__ \ - ({ \ - uint16x8_t b_ = (b); \ - uint16x4_t a_ = (a); \ - uint16x4_t result; \ - __asm__ ("mul %0.4h, %1.4h, %2.h[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmul_laneq_u32(a, b, c) \ - __extension__ \ - ({ \ - uint32x4_t b_ = (b); \ - uint32x2_t a_ = (a); \ - uint32x2_t result; \ - __asm__ ("mul %0.2s, %1.2s, %2.s[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) vmul_n_f32 (float32x2_t a, float32_t b) { @@ -10149,162 +9458,6 @@ vmull_u32 (uint32x2_t a, uint32x2_t b) return result; } -#define vmulq_lane_f32(a, b, c) \ - __extension__ \ - ({ \ - float32x2_t b_ = (b); \ - float32x4_t a_ = (a); \ - float32x4_t result; \ - __asm__ ("fmul %0.4s, %1.4s, %2.s[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmulq_lane_f64(a, b, c) \ - __extension__ \ - ({ \ - float64x1_t b_ = (b); \ - float64x2_t a_ = (a); \ - float64x2_t result; \ - __asm__ ("fmul %0.2d,%1.2d,%2.d[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmulq_lane_s16(a, b, c) \ - __extension__ \ - ({ \ - int16x4_t b_ = (b); \ - int16x8_t a_ = (a); \ - int16x8_t result; \ - __asm__ ("mul %0.8h,%1.8h,%2.h[%3]" \ - : "=w"(result) \ - : "w"(a_), "x"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmulq_lane_s32(a, b, c) \ - __extension__ \ - ({ \ - int32x2_t b_ = (b); \ - int32x4_t a_ = (a); \ - int32x4_t result; \ - __asm__ ("mul %0.4s,%1.4s,%2.s[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmulq_lane_u16(a, b, c) \ - __extension__ \ - ({ \ - uint16x4_t b_ = (b); \ - uint16x8_t a_ = (a); \ - uint16x8_t result; \ - __asm__ ("mul %0.8h,%1.8h,%2.h[%3]" \ - : "=w"(result) \ - : "w"(a_), "x"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmulq_lane_u32(a, b, c) \ - __extension__ \ - ({ \ - uint32x2_t b_ = (b); \ - uint32x4_t a_ = (a); \ - uint32x4_t result; \ - __asm__ ("mul %0.4s, %1.4s, %2.s[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmulq_laneq_f32(a, b, c) \ - __extension__ \ - ({ \ - float32x4_t b_ = (b); \ - float32x4_t a_ = (a); \ - float32x4_t result; \ - __asm__ ("fmul %0.4s, %1.4s, %2.s[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmulq_laneq_f64(a, b, c) \ - __extension__ \ - ({ \ - float64x2_t b_ = (b); \ - float64x2_t a_ = (a); \ - float64x2_t result; \ - __asm__ ("fmul %0.2d,%1.2d,%2.d[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmulq_laneq_s16(a, b, c) \ - __extension__ \ - ({ \ - int16x8_t b_ = (b); \ - int16x8_t a_ = (a); \ - int16x8_t result; \ - __asm__ ("mul %0.8h, %1.8h, %2.h[%3]" \ - : "=w"(result) \ - : "w"(a_), "x"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmulq_laneq_s32(a, b, c) \ - __extension__ \ - ({ \ - int32x4_t b_ = (b); \ - int32x4_t a_ = (a); \ - int32x4_t result; \ - __asm__ ("mul %0.4s, %1.4s, %2.s[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmulq_laneq_u16(a, b, c) \ - __extension__ \ - ({ \ - uint16x8_t b_ = (b); \ - uint16x8_t a_ = (a); \ - uint16x8_t result; \ - __asm__ ("mul %0.8h, %1.8h, %2.h[%3]" \ - : "=w"(result) \ - : "w"(a_), "x"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - -#define vmulq_laneq_u32(a, b, c) \ - __extension__ \ - ({ \ - uint32x4_t b_ = (b); \ - uint32x4_t a_ = (a); \ - uint32x4_t result; \ - __asm__ ("mul %0.4s, %1.4s, %2.s[%3]" \ - : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ - : /* No clobbers */); \ - result; \ - }) - __extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) vmulq_n_f32 (float32x4_t a, float32_t b) { @@ -19900,6 +19053,210 @@ vdupd_laneq_u64 (uint64x2_t __a, const int __b) return __aarch64_vgetq_lane_u64 (__a, __b); } +/* vfma_lane */ + +__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +vfma_lane_f32 (float32x2_t __a, float32x2_t __b, + float32x2_t __c, const int __lane) +{ + return __builtin_aarch64_fmav2sf (__b, + __aarch64_vdup_lane_f32 (__c, __lane), + __a); +} + +__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +vfma_lane_f64 (float64_t __a, float64_t __b, + float64_t __c, const int __lane) +{ + return __builtin_fma (__b, __c, __a); +} + +__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +vfmad_lane_f64 (float64_t __a, float64_t __b, + float64_t __c, const int __lane) +{ + return __builtin_fma (__b, __c, __a); +} + +__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +vfmas_lane_f32 (float32_t __a, float32_t __b, + float32x2_t __c, const int __lane) +{ + return __builtin_fmaf (__b, __aarch64_vget_lane_f32 (__c, __lane), __a); +} + +/* vfma_laneq */ + +__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +vfma_laneq_f32 (float32x2_t __a, float32x2_t __b, + float32x4_t __c, const int __lane) +{ + return __builtin_aarch64_fmav2sf (__b, + __aarch64_vdup_laneq_f32 (__c, __lane), + __a); +} + +__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +vfma_laneq_f64 (float64_t __a, float64_t __b, + float64x2_t __c, const int __lane) +{ + return __builtin_fma (__b, __aarch64_vgetq_lane_f64 (__c, __lane), __a); +} + +__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +vfmad_laneq_f64 (float64_t __a, float64_t __b, + float64x2_t __c, const int __lane) +{ + return __builtin_fma (__b, __aarch64_vgetq_lane_f64 (__c, __lane), __a); +} + +__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +vfmas_laneq_f32 (float32_t __a, float32_t __b, + float32x4_t __c, const int __lane) +{ + return __builtin_fmaf (__b, __aarch64_vgetq_lane_f32 (__c, __lane), __a); +} + +/* vfmaq_lane */ + +__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +vfmaq_lane_f32 (float32x4_t __a, float32x4_t __b, + float32x2_t __c, const int __lane) +{ + return __builtin_aarch64_fmav4sf (__b, + __aarch64_vdupq_lane_f32 (__c, __lane), + __a); +} + +__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +vfmaq_lane_f64 (float64x2_t __a, float64x2_t __b, + float64_t __c, const int __lane) +{ + return __builtin_aarch64_fmav2df (__b, vdupq_n_f64 (__c), __a); +} + +/* vfmaq_laneq */ + +__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +vfmaq_laneq_f32 (float32x4_t __a, float32x4_t __b, + float32x4_t __c, const int __lane) +{ + return __builtin_aarch64_fmav4sf (__b, + __aarch64_vdupq_laneq_f32 (__c, __lane), + __a); +} + +__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +vfmaq_laneq_f64 (float64x2_t __a, float64x2_t __b, + float64x2_t __c, const int __lane) +{ + return __builtin_aarch64_fmav2df (__b, + __aarch64_vdupq_laneq_f64 (__c, __lane), + __a); +} + +/* vfms_lane */ + +__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +vfms_lane_f32 (float32x2_t __a, float32x2_t __b, + float32x2_t __c, const int __lane) +{ + return __builtin_aarch64_fmav2sf (-__b, + __aarch64_vdup_lane_f32 (__c, __lane), + __a); +} + +__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +vfms_lane_f64 (float64_t __a, float64_t __b, + float64_t __c, const int __lane) +{ + return __builtin_fma (-__b, __c, __a); +} + +__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +vfmsd_lane_f64 (float64_t __a, float64_t __b, + float64_t __c, const int __lane) +{ + return __builtin_fma (-__b, __c, __a); +} + +__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +vfmss_lane_f32 (float32_t __a, float32_t __b, + float32x2_t __c, const int __lane) +{ + return __builtin_fmaf (-__b, __aarch64_vget_lane_f32 (__c, __lane), __a); +} + +/* vfms_laneq */ + +__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +vfms_laneq_f32 (float32x2_t __a, float32x2_t __b, + float32x4_t __c, const int __lane) +{ + return __builtin_aarch64_fmav2sf (-__b, + __aarch64_vdup_laneq_f32 (__c, __lane), + __a); +} + +__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +vfms_laneq_f64 (float64_t __a, float64_t __b, + float64x2_t __c, const int __lane) +{ + return __builtin_fma (-__b, __aarch64_vgetq_lane_f64 (__c, __lane), __a); +} + +__extension__ static __inline float64_t __attribute__ ((__always_inline__)) +vfmsd_laneq_f64 (float64_t __a, float64_t __b, + float64x2_t __c, const int __lane) +{ + return __builtin_fma (-__b, __aarch64_vgetq_lane_f64 (__c, __lane), __a); +} + +__extension__ static __inline float32_t __attribute__ ((__always_inline__)) +vfmss_laneq_f32 (float32_t __a, float32_t __b, + float32x4_t __c, const int __lane) +{ + return __builtin_fmaf (-__b, __aarch64_vgetq_lane_f32 (__c, __lane), __a); +} + +/* vfmsq_lane */ + +__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +vfmsq_lane_f32 (float32x4_t __a, float32x4_t __b, + float32x2_t __c, const int __lane) +{ + return __builtin_aarch64_fmav4sf (-__b, + __aarch64_vdupq_lane_f32 (__c, __lane), + __a); +} + +__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +vfmsq_lane_f64 (float64x2_t __a, float64x2_t __b, + float64_t __c, const int __lane) +{ + return __builtin_aarch64_fmav2df (-__b, vdupq_n_f64 (__c), __a); +} + +/* vfmsq_laneq */ + +__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +vfmsq_laneq_f32 (float32x4_t __a, float32x4_t __b, + float32x4_t __c, const int __lane) +{ + return __builtin_aarch64_fmav4sf (-__b, + __aarch64_vdupq_laneq_f32 (__c, __lane), + __a); +} + +__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +vfmsq_laneq_f64 (float64x2_t __a, float64x2_t __b, + float64x2_t __c, const int __lane) +{ + return __builtin_aarch64_fmav2df (-__b, + __aarch64_vdupq_laneq_f64 (__c, __lane), + __a); +} + /* vld1 */ __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) @@ -21417,6 +20774,156 @@ vmlaq_f64 (float64x2_t a, float64x2_t b, float64x2_t c) return a + b * c; } +/* vmla_lane */ + +__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +vmla_lane_f32 (float32x2_t __a, float32x2_t __b, + float32x2_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vget_lane_f32 (__c, __lane))); +} + +__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) +vmla_lane_s16 (int16x4_t __a, int16x4_t __b, + int16x4_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vget_lane_s16 (__c, __lane))); +} + +__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) +vmla_lane_s32 (int32x2_t __a, int32x2_t __b, + int32x2_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vget_lane_s32 (__c, __lane))); +} + +__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) +vmla_lane_u16 (uint16x4_t __a, uint16x4_t __b, + uint16x4_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vget_lane_u16 (__c, __lane))); +} + +__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +vmla_lane_u32 (uint32x2_t __a, uint32x2_t __b, + uint32x2_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vget_lane_u32 (__c, __lane))); +} + +/* vmla_laneq */ + +__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +vmla_laneq_f32 (float32x2_t __a, float32x2_t __b, + float32x4_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vgetq_lane_f32 (__c, __lane))); +} + +__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) +vmla_laneq_s16 (int16x4_t __a, int16x4_t __b, + int16x8_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vgetq_lane_s16 (__c, __lane))); +} + +__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) +vmla_laneq_s32 (int32x2_t __a, int32x2_t __b, + int32x4_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vgetq_lane_s32 (__c, __lane))); +} + +__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) +vmla_laneq_u16 (uint16x4_t __a, uint16x4_t __b, + uint16x8_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vgetq_lane_u16 (__c, __lane))); +} + +__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +vmla_laneq_u32 (uint32x2_t __a, uint32x2_t __b, + uint32x4_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vgetq_lane_u32 (__c, __lane))); +} + +/* vmlaq_lane */ + +__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +vmlaq_lane_f32 (float32x4_t __a, float32x4_t __b, + float32x2_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vget_lane_f32 (__c, __lane))); +} + +__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) +vmlaq_lane_s16 (int16x8_t __a, int16x8_t __b, + int16x4_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vget_lane_s16 (__c, __lane))); +} + +__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) +vmlaq_lane_s32 (int32x4_t __a, int32x4_t __b, + int32x2_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vget_lane_s32 (__c, __lane))); +} + +__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) +vmlaq_lane_u16 (uint16x8_t __a, uint16x8_t __b, + uint16x4_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vget_lane_u16 (__c, __lane))); +} + +__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +vmlaq_lane_u32 (uint32x4_t __a, uint32x4_t __b, + uint32x2_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vget_lane_u32 (__c, __lane))); +} + + /* vmlaq_laneq */ + +__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +vmlaq_laneq_f32 (float32x4_t __a, float32x4_t __b, + float32x4_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vgetq_lane_f32 (__c, __lane))); +} + +__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) +vmlaq_laneq_s16 (int16x8_t __a, int16x8_t __b, + int16x8_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vgetq_lane_s16 (__c, __lane))); +} + +__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) +vmlaq_laneq_s32 (int32x4_t __a, int32x4_t __b, + int32x4_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vgetq_lane_s32 (__c, __lane))); +} + +__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) +vmlaq_laneq_u16 (uint16x8_t __a, uint16x8_t __b, + uint16x8_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vgetq_lane_u16 (__c, __lane))); +} + +__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +vmlaq_laneq_u32 (uint32x4_t __a, uint32x4_t __b, + uint32x4_t __c, const int __lane) +{ + return (__a + (__b * __aarch64_vgetq_lane_u32 (__c, __lane))); +} + +/* vmls */ + __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) vmls_f32 (float32x2_t a, float32x2_t b, float32x2_t c) { @@ -21435,6 +20942,305 @@ vmlsq_f64 (float64x2_t a, float64x2_t b, float64x2_t c) return a - b * c; } +/* vmls_lane */ + +__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +vmls_lane_f32 (float32x2_t __a, float32x2_t __b, + float32x2_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vget_lane_f32 (__c, __lane))); +} + +__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) +vmls_lane_s16 (int16x4_t __a, int16x4_t __b, + int16x4_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vget_lane_s16 (__c, __lane))); +} + +__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) +vmls_lane_s32 (int32x2_t __a, int32x2_t __b, + int32x2_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vget_lane_s32 (__c, __lane))); +} + +__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) +vmls_lane_u16 (uint16x4_t __a, uint16x4_t __b, + uint16x4_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vget_lane_u16 (__c, __lane))); +} + +__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +vmls_lane_u32 (uint32x2_t __a, uint32x2_t __b, + uint32x2_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vget_lane_u32 (__c, __lane))); +} + +/* vmls_laneq */ + +__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +vmls_laneq_f32 (float32x2_t __a, float32x2_t __b, + float32x4_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vgetq_lane_f32 (__c, __lane))); +} + +__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) +vmls_laneq_s16 (int16x4_t __a, int16x4_t __b, + int16x8_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vgetq_lane_s16 (__c, __lane))); +} + +__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) +vmls_laneq_s32 (int32x2_t __a, int32x2_t __b, + int32x4_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vgetq_lane_s32 (__c, __lane))); +} + +__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) +vmls_laneq_u16 (uint16x4_t __a, uint16x4_t __b, + uint16x8_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vgetq_lane_u16 (__c, __lane))); +} + +__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +vmls_laneq_u32 (uint32x2_t __a, uint32x2_t __b, + uint32x4_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vgetq_lane_u32 (__c, __lane))); +} + +/* vmlsq_lane */ + +__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +vmlsq_lane_f32 (float32x4_t __a, float32x4_t __b, + float32x2_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vget_lane_f32 (__c, __lane))); +} + +__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) +vmlsq_lane_s16 (int16x8_t __a, int16x8_t __b, + int16x4_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vget_lane_s16 (__c, __lane))); +} + +__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) +vmlsq_lane_s32 (int32x4_t __a, int32x4_t __b, + int32x2_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vget_lane_s32 (__c, __lane))); +} + +__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) +vmlsq_lane_u16 (uint16x8_t __a, uint16x8_t __b, + uint16x4_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vget_lane_u16 (__c, __lane))); +} + +__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +vmlsq_lane_u32 (uint32x4_t __a, uint32x4_t __b, + uint32x2_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vget_lane_u32 (__c, __lane))); +} + + /* vmlsq_laneq */ + +__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +vmlsq_laneq_f32 (float32x4_t __a, float32x4_t __b, + float32x4_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vgetq_lane_f32 (__c, __lane))); +} + +__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) +vmlsq_laneq_s16 (int16x8_t __a, int16x8_t __b, + int16x8_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vgetq_lane_s16 (__c, __lane))); +} + +__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) +vmlsq_laneq_s32 (int32x4_t __a, int32x4_t __b, + int32x4_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vgetq_lane_s32 (__c, __lane))); +} +__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) +vmlsq_laneq_u16 (uint16x8_t __a, uint16x8_t __b, + uint16x8_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vgetq_lane_u16 (__c, __lane))); +} + +__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +vmlsq_laneq_u32 (uint32x4_t __a, uint32x4_t __b, + uint32x4_t __c, const int __lane) +{ + return (__a - (__b * __aarch64_vgetq_lane_u32 (__c, __lane))); +} + +/* vmul_lane */ + +__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +vmul_lane_f32 (float32x2_t __a, float32x2_t __b, const int __lane) +{ + return __a * __aarch64_vget_lane_f32 (__b, __lane); +} + +__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) +vmul_lane_f64 (float64x1_t __a, float64x1_t __b, const int __lane) +{ + return __a * __b; +} + +__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) +vmul_lane_s16 (int16x4_t __a, int16x4_t __b, const int __lane) +{ + return __a * __aarch64_vget_lane_s16 (__b, __lane); +} + +__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) +vmul_lane_s32 (int32x2_t __a, int32x2_t __b, const int __lane) +{ + return __a * __aarch64_vget_lane_s32 (__b, __lane); +} + +__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) +vmul_lane_u16 (uint16x4_t __a, uint16x4_t __b, const int __lane) +{ + return __a * __aarch64_vget_lane_u16 (__b, __lane); +} + +__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +vmul_lane_u32 (uint32x2_t __a, uint32x2_t __b, const int __lane) +{ + return __a * __aarch64_vget_lane_u32 (__b, __lane); +} + +/* vmul_laneq */ + +__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +vmul_laneq_f32 (float32x2_t __a, float32x4_t __b, const int __lane) +{ + return __a * __aarch64_vgetq_lane_f32 (__b, __lane); +} + +__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) +vmul_laneq_f64 (float64x1_t __a, float64x2_t __b, const int __lane) +{ + return __a * __aarch64_vgetq_lane_f64 (__b, __lane); +} + +__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) +vmul_laneq_s16 (int16x4_t __a, int16x8_t __b, const int __lane) +{ + return __a * __aarch64_vgetq_lane_s16 (__b, __lane); +} + +__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) +vmul_laneq_s32 (int32x2_t __a, int32x4_t __b, const int __lane) +{ + return __a * __aarch64_vgetq_lane_s32 (__b, __lane); +} + +__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) +vmul_laneq_u16 (uint16x4_t __a, uint16x8_t __b, const int __lane) +{ + return __a * __aarch64_vgetq_lane_u16 (__b, __lane); +} + +__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +vmul_laneq_u32 (uint32x2_t __a, uint32x4_t __b, const int __lane) +{ + return __a * __aarch64_vgetq_lane_u32 (__b, __lane); +} + +/* vmulq_lane */ + +__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +vmulq_lane_f32 (float32x4_t __a, float32x2_t __b, const int __lane) +{ + return __a * __aarch64_vget_lane_f32 (__b, __lane); +} + +__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +vmulq_lane_f64 (float64x2_t __a, float64x1_t __b, const int __lane) +{ + return __a * __b; +} + +__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) +vmulq_lane_s16 (int16x8_t __a, int16x4_t __b, const int __lane) +{ + return __a * __aarch64_vget_lane_s16 (__b, __lane); +} + +__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) +vmulq_lane_s32 (int32x4_t __a, int32x2_t __b, const int __lane) +{ + return __a * __aarch64_vget_lane_s32 (__b, __lane); +} + +__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) +vmulq_lane_u16 (uint16x8_t __a, uint16x4_t __b, const int __lane) +{ + return __a * __aarch64_vget_lane_u16 (__b, __lane); +} + +__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +vmulq_lane_u32 (uint32x4_t __a, uint32x2_t __b, const int __lane) +{ + return __a * __aarch64_vget_lane_u32 (__b, __lane); +} + +/* vmulq_laneq */ + +__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +vmulq_laneq_f32 (float32x4_t __a, float32x4_t __b, const int __lane) +{ + return __a * __aarch64_vgetq_lane_f32 (__b, __lane); +} + +__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +vmulq_laneq_f64 (float64x2_t __a, float64x2_t __b, const int __lane) +{ + return __a * __aarch64_vgetq_lane_f64 (__b, __lane); +} + +__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) +vmulq_laneq_s16 (int16x8_t __a, int16x8_t __b, const int __lane) +{ + return __a * __aarch64_vgetq_lane_s16 (__b, __lane); +} + +__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) +vmulq_laneq_s32 (int32x4_t __a, int32x4_t __b, const int __lane) +{ + return __a * __aarch64_vgetq_lane_s32 (__b, __lane); +} + +__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) +vmulq_laneq_u16 (uint16x8_t __a, uint16x8_t __b, const int __lane) +{ + return __a * __aarch64_vgetq_lane_u16 (__b, __lane); +} + +__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +vmulq_laneq_u32 (uint32x4_t __a, uint32x4_t __b, const int __lane) +{ + return __a * __aarch64_vgetq_lane_u32 (__b, __lane); +} + /* vqabs */ __extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index ffe125b5583..ec8d813fa3f 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -89,6 +89,9 @@ ;; Vector Float modes. (define_mode_iterator VDQF [V2SF V4SF V2DF]) +;; Vector single Float modes. +(define_mode_iterator VDQSF [V2SF V4SF]) + ;; Modes suitable to use as the return type of a vcond expression. (define_mode_iterator VDQF_COND [V2SF V2SI V4SF V4SI V2DF V2DI]) @@ -169,6 +172,12 @@ ;; Double scalar modes (define_mode_iterator DX [DI DF]) +;; Modes available for <f>mul lane operations. +(define_mode_iterator VMUL [V4HI V8HI V2SI V4SI V2SF V4SF V2DF]) + +;; Modes available for <f>mul lane operations changing lane count. +(define_mode_iterator VMUL_CHANGE_NLANES [V4HI V8HI V2SI V4SI V2SF V4SF]) + ;; ------------------------------------------------------------------ ;; Unspec enumerations for Advance SIMD. These could well go into ;; aarch64.md but for their use in int_iterators here. @@ -358,7 +367,7 @@ (V2SI "SI") (V4SI "SI") (DI "DI") (V2DI "DI") (V2SF "SF") (V4SF "SF") - (V2DF "DF") + (V2DF "DF") (DF "DF") (SI "SI") (HI "HI") (QI "QI")]) @@ -541,6 +550,22 @@ (V2SF "to_128") (V4SF "to_64") (DF "to_128") (V2DF "to_64")]) +;; For certain vector-by-element multiplication instructions we must +;; constrain the HI cases to use only V0-V15. This is covered by +;; the 'x' constraint. All other modes may use the 'w' constraint. +(define_mode_attr h_con [(V2SI "w") (V4SI "w") + (V4HI "x") (V8HI "x") + (V2SF "w") (V4SF "w") + (V2DF "w") (DF "w")]) + +;; Defined to 'f' for types whose element type is a float type. +(define_mode_attr f [(V8QI "") (V16QI "") + (V4HI "") (V8HI "") + (V2SI "") (V4SI "") + (DI "") (V2DI "") + (V2SF "f") (V4SF "f") + (V2DF "f") (DF "f")]) + ;; ------------------------------------------------------------------- ;; Code Iterators ;; ------------------------------------------------------------------- diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index a8fb92964eb..a05c42ad4b7 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see #include "splay-tree.h" #include "gimple.h" #include "tree-flow.h" +#include "tree-ssanames.h" #include "tree-stdarg.h" #include "tm-constrs.h" #include "df.h" diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index f9027ddd2e7..2166001a1ec 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -14265,9 +14265,10 @@ thumb1_reorg (void) FOR_EACH_BB (bb) { - rtx set, dest, src; - rtx pat, op0; + rtx dest, src; + rtx pat, op0, set = NULL; rtx prev, insn = BB_END (bb); + bool insn_clobbered = false; while (insn != BB_HEAD (bb) && DEBUG_INSN_P (insn)) insn = PREV_INSN (insn); @@ -14276,13 +14277,29 @@ thumb1_reorg (void) if (INSN_CODE (insn) != CODE_FOR_cbranchsi4_insn) continue; - /* Find the first non-note insn before INSN in basic block BB. */ + /* Get the register with which we are comparing. */ + pat = PATTERN (insn); + op0 = XEXP (XEXP (SET_SRC (pat), 0), 0); + + /* Find the first flag setting insn before INSN in basic block BB. */ gcc_assert (insn != BB_HEAD (bb)); - prev = PREV_INSN (insn); - while (prev != BB_HEAD (bb) && (NOTE_P (prev) || DEBUG_INSN_P (prev))) - prev = PREV_INSN (prev); + for (prev = PREV_INSN (insn); + (!insn_clobbered + && prev != BB_HEAD (bb) + && (NOTE_P (prev) + || DEBUG_INSN_P (prev) + || ((set = single_set (prev)) != NULL + && get_attr_conds (prev) == CONDS_NOCOND))); + prev = PREV_INSN (prev)) + { + if (reg_set_p (op0, prev)) + insn_clobbered = true; + } + + /* Skip if op0 is clobbered by insn other than prev. */ + if (insn_clobbered) + continue; - set = single_set (prev); if (!set) continue; @@ -14292,12 +14309,9 @@ thumb1_reorg (void) || !low_register_operand (src, SImode)) continue; - pat = PATTERN (insn); - op0 = XEXP (XEXP (SET_SRC (pat), 0), 0); /* Rewrite move into subtract of 0 if its operand is compared with ZERO - in INSN. Don't need to check dest since cprop_hardreg pass propagates - src into INSN. */ - if (REGNO (op0) == REGNO (src)) + in INSN. Both src and dest of the move insn are checked. */ + if (REGNO (op0) == REGNO (src) || REGNO (op0) == REGNO (dest)) { dest = copy_rtx (dest); src = copy_rtx (src); @@ -17955,7 +17969,8 @@ arm_get_frame_offsets (void) if (! any_sibcall_could_use_r3 () && arm_size_return_regs () <= 12 && (offsets->saved_regs_mask & (1 << 3)) == 0 - && (TARGET_THUMB2 || !current_tune->prefer_ldrd_strd)) + && (TARGET_THUMB2 + || !(TARGET_LDRD && current_tune->prefer_ldrd_strd))) { reg = 3; } @@ -18380,7 +18395,8 @@ arm_expand_prologue (void) } } - if (current_tune->prefer_ldrd_strd + if (TARGET_LDRD + && current_tune->prefer_ldrd_strd && !optimize_function_for_size_p (cfun)) { if (TARGET_THUMB2) @@ -24649,7 +24665,8 @@ arm_expand_epilogue (bool really_return) } else { - if (current_tune->prefer_ldrd_strd + if (TARGET_LDRD + && current_tune->prefer_ldrd_strd && !optimize_function_for_size_p (cfun)) { if (TARGET_THUMB2) diff --git a/gcc/config/i386/athlon.md b/gcc/config/i386/athlon.md index d872b8f434c..8bbde33dc1c 100644 --- a/gcc/config/i386/athlon.md +++ b/gcc/config/i386/athlon.md @@ -151,11 +151,11 @@ ;; Jump instructions are executed in the branch unit completely transparent to us (define_insn_reservation "athlon_branch" 0 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (eq_attr "type" "ibr")) "athlon-direct,athlon-ieu") (define_insn_reservation "athlon_call" 0 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (eq_attr "type" "call,callv")) "athlon-vector,athlon-ieu") (define_insn_reservation "athlon_call_amdfam10" 0 @@ -166,15 +166,15 @@ ;; Latency of push operation is 3 cycles, but ESP value is available ;; earlier (define_insn_reservation "athlon_push" 2 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (eq_attr "type" "push")) "athlon-direct,athlon-agu,athlon-store") (define_insn_reservation "athlon_pop" 4 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (eq_attr "type" "pop")) "athlon-vector,athlon-load,athlon-ieu") (define_insn_reservation "athlon_pop_k8" 3 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (eq_attr "type" "pop")) "athlon-double,(athlon-ieu+athlon-load)") (define_insn_reservation "athlon_pop_amdfam10" 3 @@ -186,13 +186,13 @@ (eq_attr "type" "leave")) "athlon-vector,(athlon-ieu+athlon-load)") (define_insn_reservation "athlon_leave_k8" 3 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (eq_attr "type" "leave")) "athlon-double,(athlon-ieu+athlon-load)") ;; Lea executes in AGU unit with 2 cycles latency. (define_insn_reservation "athlon_lea" 2 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (eq_attr "type" "lea")) "athlon-direct,athlon-agu,nothing") ;; Lea executes in AGU unit with 1 cycle latency on AMDFAM10 @@ -209,13 +209,13 @@ "athlon-vector,athlon-ieu0,athlon-mult,nothing,nothing,athlon-ieu0") ;; ??? Widening multiply is vector or double. (define_insn_reservation "athlon_imul_k8_DI" 4 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "imul") (and (eq_attr "mode" "DI") (eq_attr "memory" "none,unknown")))) "athlon-direct0,athlon-ieu0,athlon-mult,nothing,athlon-ieu0") (define_insn_reservation "athlon_imul_k8" 3 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "imul") (eq_attr "memory" "none,unknown"))) "athlon-direct0,athlon-ieu0,athlon-mult,athlon-ieu0") @@ -231,13 +231,13 @@ (eq_attr "memory" "load,both"))) "athlon-vector,athlon-load,athlon-ieu,athlon-mult,nothing,nothing,athlon-ieu") (define_insn_reservation "athlon_imul_mem_k8_DI" 7 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "imul") (and (eq_attr "mode" "DI") (eq_attr "memory" "load,both")))) "athlon-vector,athlon-load,athlon-ieu,athlon-mult,nothing,athlon-ieu") (define_insn_reservation "athlon_imul_mem_k8" 6 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "imul") (eq_attr "memory" "load,both"))) "athlon-vector,athlon-load,athlon-ieu,athlon-mult,athlon-ieu") @@ -251,12 +251,12 @@ ;; Using the same heuristics for amdfam10 as K8 with idiv (define_insn_reservation "athlon_idiv" 6 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (and (eq_attr "type" "idiv") (eq_attr "memory" "none,unknown"))) "athlon-vector,(athlon-ieu0*6+(athlon-fpsched,athlon-fvector))") (define_insn_reservation "athlon_idiv_mem" 9 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (and (eq_attr "type" "idiv") (eq_attr "memory" "load,both"))) "athlon-vector,((athlon-load,athlon-ieu0*6)+(athlon-fpsched,athlon-fvector))") @@ -264,13 +264,13 @@ ;; as idiv to create smaller automata. This probably does not matter much. ;; Using the same heuristics for amdfam10 as K8 with idiv (define_insn_reservation "athlon_str" 6 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (and (eq_attr "type" "str") (eq_attr "memory" "load,both,store"))) "athlon-vector,athlon-load,athlon-ieu0*6") (define_insn_reservation "athlon_idirect" 1 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "athlon_decode" "direct") (and (eq_attr "unit" "integer,unknown") (eq_attr "memory" "none,unknown")))) @@ -282,7 +282,7 @@ (eq_attr "memory" "none,unknown")))) "athlon-direct,athlon-ieu") (define_insn_reservation "athlon_ivector" 2 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "athlon_decode" "vector") (and (eq_attr "unit" "integer,unknown") (eq_attr "memory" "none,unknown")))) @@ -295,13 +295,13 @@ "athlon-vector,athlon-ieu,athlon-ieu") (define_insn_reservation "athlon_idirect_loadmov" 3 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (and (eq_attr "type" "imov") (eq_attr "memory" "load"))) "athlon-direct,athlon-load") (define_insn_reservation "athlon_idirect_load" 4 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "athlon_decode" "direct") (and (eq_attr "unit" "integer,unknown") (eq_attr "memory" "load")))) @@ -313,7 +313,7 @@ (eq_attr "memory" "load")))) "athlon-direct,athlon-load,athlon-ieu") (define_insn_reservation "athlon_ivector_load" 6 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "athlon_decode" "vector") (and (eq_attr "unit" "integer,unknown") (eq_attr "memory" "load")))) @@ -326,13 +326,13 @@ "athlon-vector,athlon-load,athlon-ieu,athlon-ieu") (define_insn_reservation "athlon_idirect_movstore" 1 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (and (eq_attr "type" "imov") (eq_attr "memory" "store"))) "athlon-direct,athlon-agu,athlon-store") (define_insn_reservation "athlon_idirect_both" 4 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "athlon_decode" "direct") (and (eq_attr "unit" "integer,unknown") (eq_attr "memory" "both")))) @@ -349,7 +349,7 @@ athlon-store") (define_insn_reservation "athlon_ivector_both" 6 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "athlon_decode" "vector") (and (eq_attr "unit" "integer,unknown") (eq_attr "memory" "both")))) @@ -368,7 +368,7 @@ athlon-store") (define_insn_reservation "athlon_idirect_store" 1 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "athlon_decode" "direct") (and (eq_attr "unit" "integer,unknown") (eq_attr "memory" "store")))) @@ -383,7 +383,7 @@ athlon-store") (define_insn_reservation "athlon_ivector_store" 2 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "athlon_decode" "vector") (and (eq_attr "unit" "integer,unknown") (eq_attr "memory" "store")))) @@ -405,7 +405,7 @@ (eq_attr "mode" "XF")))) "athlon-vector,athlon-fpload2,athlon-fvector*9") (define_insn_reservation "athlon_fldxf_k8" 13 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "fmov") (and (eq_attr "memory" "load") (eq_attr "mode" "XF")))) @@ -417,7 +417,7 @@ (eq_attr "memory" "load"))) "athlon-direct,athlon-fpload,athlon-fany") (define_insn_reservation "athlon_fld_k8" 2 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))) "athlon-direct,athlon-fploadk8,athlon-fstore") @@ -429,7 +429,7 @@ (eq_attr "mode" "XF")))) "athlon-vector,(athlon-fpsched+athlon-agu),(athlon-store2+(athlon-fvector*7))") (define_insn_reservation "athlon_fstxf_k8" 8 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "fmov") (and (eq_attr "memory" "store,both") (eq_attr "mode" "XF")))) @@ -440,16 +440,16 @@ (eq_attr "memory" "store,both"))) "athlon-direct,(athlon-fpsched+athlon-agu),(athlon-fstore+athlon-store)") (define_insn_reservation "athlon_fst_k8" 2 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))) "athlon-direct,(athlon-fpsched+athlon-agu),(athlon-fstore+athlon-store)") (define_insn_reservation "athlon_fist" 4 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (eq_attr "type" "fistp,fisttp")) "athlon-direct,(athlon-fpsched+athlon-agu),(athlon-fstore+athlon-store)") (define_insn_reservation "athlon_fmov" 2 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (eq_attr "type" "fmov")) "athlon-direct,athlon-fpsched,athlon-faddmul") (define_insn_reservation "athlon_fadd_load" 4 @@ -458,12 +458,12 @@ (eq_attr "memory" "load"))) "athlon-direct,athlon-fpload,athlon-fadd") (define_insn_reservation "athlon_fadd_load_k8" 6 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "fop") (eq_attr "memory" "load"))) "athlon-direct,athlon-fploadk8,athlon-fadd") (define_insn_reservation "athlon_fadd" 4 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (eq_attr "type" "fop")) "athlon-direct,athlon-fpsched,athlon-fadd") (define_insn_reservation "athlon_fmul_load" 4 @@ -472,16 +472,16 @@ (eq_attr "memory" "load"))) "athlon-direct,athlon-fpload,athlon-fmul") (define_insn_reservation "athlon_fmul_load_k8" 6 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "fmul") (eq_attr "memory" "load"))) "athlon-direct,athlon-fploadk8,athlon-fmul") (define_insn_reservation "athlon_fmul" 4 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (eq_attr "type" "fmul")) "athlon-direct,athlon-fpsched,athlon-fmul") (define_insn_reservation "athlon_fsgn" 2 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (eq_attr "type" "fsgn")) "athlon-direct,athlon-fpsched,athlon-fmul") (define_insn_reservation "athlon_fdiv_load" 24 @@ -490,7 +490,7 @@ (eq_attr "memory" "load"))) "athlon-direct,athlon-fpload,athlon-fmul") (define_insn_reservation "athlon_fdiv_load_k8" 13 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "fdiv") (eq_attr "memory" "load"))) "athlon-direct,athlon-fploadk8,athlon-fmul") @@ -499,16 +499,16 @@ (eq_attr "type" "fdiv")) "athlon-direct,athlon-fpsched,athlon-fmul") (define_insn_reservation "athlon_fdiv_k8" 11 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (eq_attr "type" "fdiv")) "athlon-direct,athlon-fpsched,athlon-fmul") (define_insn_reservation "athlon_fpspc_load" 103 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (and (eq_attr "type" "fpspc") (eq_attr "memory" "load"))) "athlon-vector,athlon-fpload,athlon-fvector") (define_insn_reservation "athlon_fpspc" 100 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (eq_attr "type" "fpspc")) "athlon-vector,athlon-fpsched,athlon-fvector") (define_insn_reservation "athlon_fcmov_load" 7 @@ -521,12 +521,12 @@ (eq_attr "type" "fcmov")) "athlon-vector,athlon-fpsched,athlon-fvector") (define_insn_reservation "athlon_fcmov_load_k8" 17 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "fcmov") (eq_attr "memory" "load"))) "athlon-vector,athlon-fploadk8,athlon-fvector") (define_insn_reservation "athlon_fcmov_k8" 15 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (eq_attr "type" "fcmov")) "athlon-vector,athlon-fpsched,athlon-fvector") ;; fcomi is vector decoded by uses only one pipe. @@ -537,13 +537,13 @@ (eq_attr "memory" "load")))) "athlon-vector,athlon-fpload,athlon-fadd") (define_insn_reservation "athlon_fcomi_load_k8" 5 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "fcmp") (and (eq_attr "athlon_decode" "vector") (eq_attr "memory" "load")))) "athlon-vector,athlon-fploadk8,athlon-fadd") (define_insn_reservation "athlon_fcomi" 3 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (and (eq_attr "athlon_decode" "vector") (eq_attr "type" "fcmp"))) "athlon-vector,athlon-fpsched,athlon-fadd") @@ -553,18 +553,18 @@ (eq_attr "memory" "load"))) "athlon-direct,athlon-fpload,athlon-fadd") (define_insn_reservation "athlon_fcom_load_k8" 4 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "fcmp") (eq_attr "memory" "load"))) "athlon-direct,athlon-fploadk8,athlon-fadd") (define_insn_reservation "athlon_fcom" 2 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (eq_attr "type" "fcmp")) "athlon-direct,athlon-fpsched,athlon-fadd") ;; Never seen by the scheduler because we still don't do post reg-stack ;; scheduling. ;(define_insn_reservation "athlon_fxch" 2 -; (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") +; (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") ; (eq_attr "type" "fxch")) ; "athlon-direct,athlon-fpsched,athlon-fany") @@ -580,13 +580,13 @@ (and (eq_attr "type" "ssemov") (match_operand:DF 1 "memory_operand"))) "athlon-direct,athlon-fploadk8,athlon-fstore") -(define_insn_reservation "athlon_movsd_load_generic64" 2 - (and (eq_attr "cpu" "generic64") +(define_insn_reservation "athlon_movsd_load_generic" 2 + (and (eq_attr "cpu" "generic") (and (eq_attr "type" "ssemov") (match_operand:DF 1 "memory_operand"))) "athlon-double,athlon-fploadk8,(athlon-fstore+athlon-fmul)") (define_insn_reservation "athlon_movaps_load_k8" 2 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (and (eq_attr "type" "ssemov") (and (eq_attr "mode" "V4SF,V2DF,TI") (eq_attr "memory" "load")))) @@ -604,7 +604,7 @@ (eq_attr "memory" "load")))) "athlon-vector,athlon-fpload,(athlon-fany*2)") (define_insn_reservation "athlon_movss_load_k8" 1 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (and (eq_attr "type" "ssemov") (and (eq_attr "mode" "SF,DI") (eq_attr "memory" "load")))) @@ -615,7 +615,7 @@ (eq_attr "memory" "load"))) "athlon-direct,athlon-fpload,athlon-fany") (define_insn_reservation "athlon_mmxsseld_k8" 2 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (and (eq_attr "type" "mmxmov,ssemov") (eq_attr "memory" "load"))) "athlon-direct,athlon-fploadk8,athlon-fstore") @@ -637,19 +637,19 @@ (eq_attr "memory" "load"))) "athlon-direct,athlon-fploadk8, athlon-fany") (define_insn_reservation "athlon_mmxssest" 3 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (and (eq_attr "type" "mmxmov,ssemov") (and (eq_attr "mode" "V4SF,V2DF,TI") (eq_attr "memory" "store,both")))) "athlon-vector,(athlon-fpsched+athlon-agu),((athlon-fstore+athlon-store2)*2)") (define_insn_reservation "athlon_mmxssest_k8" 3 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (and (eq_attr "type" "mmxmov,ssemov") (and (eq_attr "mode" "V4SF,V2DF,TI") (eq_attr "memory" "store,both")))) "athlon-double,(athlon-fpsched+athlon-agu),((athlon-fstore+athlon-store2)*2)") (define_insn_reservation "athlon_mmxssest_short" 2 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "type" "mmxmov,ssemov") (eq_attr "memory" "store,both"))) "athlon-direct,(athlon-fpsched+athlon-agu),(athlon-fstore+athlon-store)") @@ -673,7 +673,7 @@ (eq_attr "memory" "store,both"))) "athlon-direct,(athlon-fpsched+athlon-agu),(athlon-fstore+athlon-store)") (define_insn_reservation "athlon_movaps_k8" 2 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (and (eq_attr "type" "ssemov") (eq_attr "mode" "V4SF,V2DF,TI"))) "athlon-double,athlon-fpsched,((athlon-faddmul+athlon-faddmul) | (athlon-faddmul, athlon-faddmul))") @@ -683,25 +683,25 @@ (eq_attr "mode" "V4SF,V2DF,TI"))) "athlon-vector,athlon-fpsched,(athlon-faddmul+athlon-faddmul)") (define_insn_reservation "athlon_mmxssemov" 2 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (eq_attr "type" "mmxmov,ssemov")) "athlon-direct,athlon-fpsched,athlon-faddmul") (define_insn_reservation "athlon_mmxmul_load" 4 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "type" "mmxmul") (eq_attr "memory" "load"))) "athlon-direct,athlon-fpload,athlon-fmul") (define_insn_reservation "athlon_mmxmul" 3 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (eq_attr "type" "mmxmul")) "athlon-direct,athlon-fpsched,athlon-fmul") (define_insn_reservation "athlon_mmx_load" 3 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "unit" "mmx") (eq_attr "memory" "load"))) "athlon-direct,athlon-fpload,athlon-faddmul") (define_insn_reservation "athlon_mmx" 2 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (eq_attr "unit" "mmx")) "athlon-direct,athlon-fpsched,athlon-faddmul") ;; SSE operations are handled by the i387 unit as well. The latency @@ -713,7 +713,7 @@ (eq_attr "memory" "load"))) "athlon-vector,athlon-fpload2,(athlon-fmul*2)") (define_insn_reservation "athlon_sselog_load_k8" 5 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (and (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1") (eq_attr "memory" "load"))) "athlon-double,athlon-fpload2k8,(athlon-fmul*2)") @@ -727,7 +727,7 @@ (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1")) "athlon-vector,athlon-fpsched,athlon-fmul*2") (define_insn_reservation "athlon_sselog_k8" 3 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1")) "athlon-double,athlon-fpsched,athlon-fmul") (define_insn_reservation "athlon_sselog_amdfam10" 2 @@ -743,13 +743,13 @@ (eq_attr "memory" "load")))) "athlon-direct,athlon-fpload,athlon-fadd") (define_insn_reservation "athlon_ssecmp_load_k8" 4 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "ssecmp") (and (eq_attr "mode" "SF,DF,DI,TI") (eq_attr "memory" "load")))) "athlon-direct,athlon-fploadk8,athlon-fadd") (define_insn_reservation "athlon_ssecmp" 2 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (and (eq_attr "type" "ssecmp") (eq_attr "mode" "SF,DF,DI,TI"))) "athlon-direct,athlon-fpsched,athlon-fadd") @@ -759,7 +759,7 @@ (eq_attr "memory" "load"))) "athlon-vector,athlon-fpload2,(athlon-fadd*2)") (define_insn_reservation "athlon_ssecmpvector_load_k8" 5 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (and (eq_attr "type" "ssecmp") (eq_attr "memory" "load"))) "athlon-double,athlon-fpload2k8,(athlon-fadd*2)") @@ -773,7 +773,7 @@ (eq_attr "type" "ssecmp")) "athlon-vector,athlon-fpsched,(athlon-fadd*2)") (define_insn_reservation "athlon_ssecmpvector_k8" 3 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (eq_attr "type" "ssecmp")) "athlon-double,athlon-fpsched,(athlon-fadd*2)") (define_insn_reservation "athlon_ssecmpvector_amdfam10" 2 @@ -786,7 +786,7 @@ (eq_attr "memory" "load"))) "athlon-vector,athlon-fpload,athlon-fadd") (define_insn_reservation "athlon_ssecomi_load_k8" 6 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (and (eq_attr "type" "ssecomi") (eq_attr "memory" "load"))) "athlon-vector,athlon-fploadk8,athlon-fadd") @@ -796,7 +796,7 @@ (eq_attr "memory" "load"))) "athlon-direct,athlon-fploadk8,athlon-fadd") (define_insn_reservation "athlon_ssecomi" 4 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (eq_attr "type" "ssecomi")) "athlon-vector,athlon-fpsched,athlon-fadd") (define_insn_reservation "athlon_ssecomi_amdfam10" 3 @@ -811,13 +811,13 @@ (eq_attr "memory" "load")))) "athlon-direct,athlon-fpload,athlon-fadd") (define_insn_reservation "athlon_sseadd_load_k8" 6 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "sseadd,sseadd1") (and (eq_attr "mode" "SF,DF,DI") (eq_attr "memory" "load")))) "athlon-direct,athlon-fploadk8,athlon-fadd") (define_insn_reservation "athlon_sseadd" 4 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (and (eq_attr "type" "sseadd,sseadd1") (eq_attr "mode" "SF,DF,DI"))) "athlon-direct,athlon-fpsched,athlon-fadd") @@ -827,7 +827,7 @@ (eq_attr "memory" "load"))) "athlon-vector,athlon-fpload2,(athlon-fadd*2)") (define_insn_reservation "athlon_sseaddvector_load_k8" 7 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (and (eq_attr "type" "sseadd,sseadd1") (eq_attr "memory" "load"))) "athlon-double,athlon-fpload2k8,(athlon-fadd*2)") @@ -841,7 +841,7 @@ (eq_attr "type" "sseadd,sseadd1")) "athlon-vector,athlon-fpsched,(athlon-fadd*2)") (define_insn_reservation "athlon_sseaddvector_k8" 5 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (eq_attr "type" "sseadd,sseadd1")) "athlon-double,athlon-fpsched,(athlon-fadd*2)") (define_insn_reservation "athlon_sseaddvector_amdfam10" 4 @@ -855,7 +855,7 @@ ;; cvtss2sd (define_insn_reservation "athlon_ssecvt_cvtss2sd_load_k8" 4 - (and (eq_attr "cpu" "k8,athlon,generic64") + (and (eq_attr "cpu" "k8,athlon,generic") (and (eq_attr "type" "ssecvt") (and (eq_attr "athlon_decode" "direct") (and (eq_attr "mode" "DF") @@ -869,7 +869,7 @@ (eq_attr "memory" "load"))))) "athlon-double,athlon-fploadk8,(athlon-faddmul+athlon-fstore)") (define_insn_reservation "athlon_ssecvt_cvtss2sd" 2 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "type" "ssecvt") (and (eq_attr "athlon_decode" "direct") (eq_attr "mode" "DF")))) @@ -882,7 +882,7 @@ "athlon-vector,athlon-fpsched,athlon-faddmul,(athlon-fstore*2)") ;; cvtps2pd. Model same way the other double decoded FP conversions. (define_insn_reservation "athlon_ssecvt_cvtps2pd_load_k8" 5 - (and (eq_attr "cpu" "k8,athlon,generic64") + (and (eq_attr "cpu" "k8,athlon,generic") (and (eq_attr "type" "ssecvt") (and (eq_attr "athlon_decode" "double") (and (eq_attr "mode" "V2DF,V4SF,TI") @@ -896,7 +896,7 @@ (eq_attr "memory" "load"))))) "athlon-direct,athlon-fploadk8,athlon-fstore") (define_insn_reservation "athlon_ssecvt_cvtps2pd_k8" 3 - (and (eq_attr "cpu" "k8,athlon,generic64") + (and (eq_attr "cpu" "k8,athlon,generic") (and (eq_attr "type" "ssecvt") (and (eq_attr "athlon_decode" "double") (eq_attr "mode" "V2DF,V4SF,TI")))) @@ -932,7 +932,7 @@ (eq_attr "memory" "load"))))) "athlon-vector,athlon-fpload,(athlon-fstore*2)") (define_insn_reservation "athlon_sseicvt_cvtsi2ss_load_k8" 9 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (and (eq_attr "type" "sseicvt") (and (eq_attr "athlon_decode" "double") (and (eq_attr "mode" "SF,DF") @@ -947,7 +947,7 @@ "athlon-double,athlon-fploadk8,(athlon-faddmul+athlon-fstore)") ;; cvtsi2sd reg,reg is double decoded (vector on Athlon) (define_insn_reservation "athlon_sseicvt_cvtsi2sd_k8" 11 - (and (eq_attr "cpu" "k8,athlon,generic64") + (and (eq_attr "cpu" "k8,athlon,generic") (and (eq_attr "type" "sseicvt") (and (eq_attr "athlon_decode" "double") (and (eq_attr "mode" "SF,DF") @@ -962,7 +962,7 @@ "athlon-vector,athlon-fploadk8,(athlon-faddmul+athlon-fstore)") ;; cvtsi2ss reg, reg is doublepath (define_insn_reservation "athlon_sseicvt_cvtsi2ss" 14 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "type" "sseicvt") (and (eq_attr "athlon_decode" "vector") (and (eq_attr "mode" "SF,DF") @@ -977,7 +977,7 @@ "athlon-vector,athlon-fploadk8,(athlon-faddmul+athlon-fstore)") ;; cvtsd2ss mem,reg is doublepath, troughput unknown, latency 9 (define_insn_reservation "athlon_ssecvt_cvtsd2ss_load_k8" 9 - (and (eq_attr "cpu" "k8,athlon,generic64") + (and (eq_attr "cpu" "k8,athlon,generic") (and (eq_attr "type" "ssecvt") (and (eq_attr "athlon_decode" "double") (and (eq_attr "mode" "SF") @@ -992,7 +992,7 @@ "athlon-double,athlon-fploadk8,(athlon-faddmul+athlon-fstore)") ;; cvtsd2ss reg,reg is vectorpath, troughput unknown, latency 12 (define_insn_reservation "athlon_ssecvt_cvtsd2ss" 12 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "type" "ssecvt") (and (eq_attr "athlon_decode" "vector") (and (eq_attr "mode" "SF") @@ -1006,7 +1006,7 @@ (eq_attr "memory" "none"))))) "athlon-vector,athlon-fpsched,athlon-faddmul,(athlon-fstore*2)") (define_insn_reservation "athlon_ssecvt_cvtpd2ps_load_k8" 8 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "type" "ssecvt") (and (eq_attr "athlon_decode" "vector") (and (eq_attr "mode" "V4SF,V2DF,TI") @@ -1022,7 +1022,7 @@ ;; cvtpd2ps mem,reg is vectorpath, troughput unknown, latency 10 ;; ??? Why it is fater than cvtsd2ss? (define_insn_reservation "athlon_ssecvt_cvtpd2ps" 8 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "type" "ssecvt") (and (eq_attr "athlon_decode" "vector") (and (eq_attr "mode" "V4SF,V2DF,TI") @@ -1037,7 +1037,7 @@ "athlon-double,athlon-fpsched,(athlon-faddmul+athlon-fstore)") ;; cvtsd2si mem,reg is doublepath, troughput 1, latency 9 (define_insn_reservation "athlon_secvt_cvtsX2si_load" 9 - (and (eq_attr "cpu" "athlon,k8,generic64") + (and (eq_attr "cpu" "athlon,k8,generic") (and (eq_attr "type" "sseicvt") (and (eq_attr "athlon_decode" "vector") (and (eq_attr "mode" "SI,DI") @@ -1059,7 +1059,7 @@ (eq_attr "memory" "none"))))) "athlon-vector,athlon-fpsched,athlon-fvector") (define_insn_reservation "athlon_ssecvt_cvtsX2si_k8" 9 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (and (eq_attr "type" "sseicvt") (and (eq_attr "athlon_decode" "double") (and (eq_attr "mode" "SI,DI") @@ -1097,13 +1097,13 @@ (eq_attr "memory" "load")))) "athlon-direct,athlon-fpload,athlon-fmul") (define_insn_reservation "athlon_ssemul_load_k8" 6 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "ssemul") (and (eq_attr "mode" "SF,DF") (eq_attr "memory" "load")))) "athlon-direct,athlon-fploadk8,athlon-fmul") (define_insn_reservation "athlon_ssemul" 4 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (and (eq_attr "type" "ssemul") (eq_attr "mode" "SF,DF"))) "athlon-direct,athlon-fpsched,athlon-fmul") @@ -1113,7 +1113,7 @@ (eq_attr "memory" "load"))) "athlon-vector,athlon-fpload2,(athlon-fmul*2)") (define_insn_reservation "athlon_ssemulvector_load_k8" 7 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (and (eq_attr "type" "ssemul") (eq_attr "memory" "load"))) "athlon-double,athlon-fpload2k8,(athlon-fmul*2)") @@ -1127,7 +1127,7 @@ (eq_attr "type" "ssemul")) "athlon-vector,athlon-fpsched,(athlon-fmul*2)") (define_insn_reservation "athlon_ssemulvector_k8" 5 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (eq_attr "type" "ssemul")) "athlon-double,athlon-fpsched,(athlon-fmul*2)") (define_insn_reservation "athlon_ssemulvector_amdfam10" 4 @@ -1142,13 +1142,13 @@ (eq_attr "memory" "load")))) "athlon-direct,athlon-fpload,athlon-fmul*17") (define_insn_reservation "athlon_ssediv_load_k8" 22 - (and (eq_attr "cpu" "k8,generic64,amdfam10") + (and (eq_attr "cpu" "k8,generic,amdfam10") (and (eq_attr "type" "ssediv") (and (eq_attr "mode" "SF,DF") (eq_attr "memory" "load")))) "athlon-direct,athlon-fploadk8,athlon-fmul*17") (define_insn_reservation "athlon_ssediv" 20 - (and (eq_attr "cpu" "athlon,k8,generic64,amdfam10") + (and (eq_attr "cpu" "athlon,k8,generic,amdfam10") (and (eq_attr "type" "ssediv") (eq_attr "mode" "SF,DF"))) "athlon-direct,athlon-fpsched,athlon-fmul*17") @@ -1158,7 +1158,7 @@ (eq_attr "memory" "load"))) "athlon-vector,athlon-fpload2,athlon-fmul*34") (define_insn_reservation "athlon_ssedivvector_load_k8" 35 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (and (eq_attr "type" "ssediv") (eq_attr "memory" "load"))) "athlon-double,athlon-fpload2k8,athlon-fmul*34") @@ -1172,7 +1172,7 @@ (eq_attr "type" "ssediv")) "athlon-vector,athlon-fmul*34") (define_insn_reservation "athlon_ssedivvector_k8" 39 - (and (eq_attr "cpu" "k8,generic64") + (and (eq_attr "cpu" "k8,generic") (eq_attr "type" "ssediv")) "athlon-double,athlon-fmul*34") (define_insn_reservation "athlon_ssedivvector_amdfam10" 20 diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c index 4cb9907b5ed..823f92da8c3 100644 --- a/gcc/config/i386/driver-i386.c +++ b/gcc/config/i386/driver-i386.c @@ -578,13 +578,13 @@ const char *host_detect_local_cpu (int argc, const char **argv) case 6: if (model > 9) /* Use the default detection procedure. */ - processor = PROCESSOR_GENERIC32; + processor = PROCESSOR_GENERIC; else if (model == 9) cpu = "c3-2"; else if (model >= 6) cpu = "c3"; else - processor = PROCESSOR_GENERIC32; + processor = PROCESSOR_GENERIC; break; case 5: if (has_3dnow) @@ -592,11 +592,11 @@ const char *host_detect_local_cpu (int argc, const char **argv) else if (has_mmx) cpu = "winchip2-c6"; else - processor = PROCESSOR_GENERIC32; + processor = PROCESSOR_GENERIC; break; default: /* We have no idea. */ - processor = PROCESSOR_GENERIC32; + processor = PROCESSOR_GENERIC; } } } @@ -618,7 +618,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) break; default: /* We have no idea. */ - processor = PROCESSOR_GENERIC32; + processor = PROCESSOR_GENERIC; } } diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c index 14349be0af5..2e764e79987 100644 --- a/gcc/config/i386/i386-c.c +++ b/gcc/config/i386/i386-c.c @@ -156,8 +156,7 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, /* use PROCESSOR_max to not set/unset the arch macro. */ case PROCESSOR_max: break; - case PROCESSOR_GENERIC32: - case PROCESSOR_GENERIC64: + case PROCESSOR_GENERIC: gcc_unreachable (); } @@ -248,8 +247,7 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, case PROCESSOR_SLM: def_or_undef (parse_in, "__tune_slm__"); break; - case PROCESSOR_GENERIC32: - case PROCESSOR_GENERIC64: + case PROCESSOR_GENERIC: break; /* use PROCESSOR_max to not set/unset the tune macro. */ case PROCESSOR_max: diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index bba214712a0..46c37d800d2 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1644,18 +1644,21 @@ struct processor_costs slm_cost = { 1, /* cond_not_taken_branch_cost. */ }; -/* Generic64 should produce code tuned for Nocona and K8. */ +/* Generic should produce code tuned for Core-i7 (and newer chips) + and btver1 (and newer chips). */ -static stringop_algs generic64_memcpy[2] = { - DUMMY_STRINGOP_ALGS, +static stringop_algs generic_memcpy[2] = { + {libcall, {{32, loop, false}, {8192, rep_prefix_4_byte, false}, + {-1, libcall, false}}}, {libcall, {{32, loop, false}, {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; -static stringop_algs generic64_memset[2] = { - DUMMY_STRINGOP_ALGS, +static stringop_algs generic_memset[2] = { + {libcall, {{32, loop, false}, {8192, rep_prefix_4_byte, false}, + {-1, libcall, false}}}, {libcall, {{32, loop, false}, {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; static const -struct processor_costs generic64_cost = { +struct processor_costs generic_cost = { COSTS_N_INSNS (1), /* cost of an add instruction */ /* On all chips taken into consideration lea is 2 cycles and more. With this cost however our current implementation of synth_mult results in @@ -1713,8 +1716,8 @@ struct processor_costs generic64_cost = { COSTS_N_INSNS (8), /* cost of FABS instruction. */ COSTS_N_INSNS (8), /* cost of FCHS instruction. */ COSTS_N_INSNS (40), /* cost of FSQRT instruction. */ - generic64_memcpy, - generic64_memset, + generic_memcpy, + generic_memset, 1, /* scalar_stmt_cost. */ 1, /* scalar load_cost. */ 1, /* scalar_store_cost. */ @@ -1814,83 +1817,6 @@ struct processor_costs core_cost = { 1, /* cond_not_taken_branch_cost. */ }; -/* Generic32 should produce code tuned for PPro, Pentium4, Nocona, - Athlon and K8. */ -static stringop_algs generic32_memcpy[2] = { - {libcall, {{32, loop, false}, {8192, rep_prefix_4_byte, false}, - {-1, libcall, false}}}, - DUMMY_STRINGOP_ALGS}; -static stringop_algs generic32_memset[2] = { - {libcall, {{32, loop, false}, {8192, rep_prefix_4_byte, false}, - {-1, libcall, false}}}, - DUMMY_STRINGOP_ALGS}; -static const -struct processor_costs generic32_cost = { - COSTS_N_INSNS (1), /* cost of an add instruction */ - COSTS_N_INSNS (1) + 1, /* cost of a lea instruction */ - COSTS_N_INSNS (1), /* variable shift costs */ - COSTS_N_INSNS (1), /* constant shift costs */ - {COSTS_N_INSNS (3), /* cost of starting multiply for QI */ - COSTS_N_INSNS (4), /* HI */ - COSTS_N_INSNS (3), /* SI */ - COSTS_N_INSNS (4), /* DI */ - COSTS_N_INSNS (2)}, /* other */ - 0, /* cost of multiply per each bit set */ - {COSTS_N_INSNS (18), /* cost of a divide/mod for QI */ - COSTS_N_INSNS (26), /* HI */ - COSTS_N_INSNS (42), /* SI */ - COSTS_N_INSNS (74), /* DI */ - COSTS_N_INSNS (74)}, /* other */ - COSTS_N_INSNS (1), /* cost of movsx */ - COSTS_N_INSNS (1), /* cost of movzx */ - 8, /* "large" insn */ - 17, /* MOVE_RATIO */ - 4, /* cost for loading QImode using movzbl */ - {4, 4, 4}, /* cost of loading integer registers - in QImode, HImode and SImode. - Relative to reg-reg move (2). */ - {4, 4, 4}, /* cost of storing integer registers */ - 4, /* cost of reg,reg fld/fst */ - {12, 12, 12}, /* cost of loading fp registers - in SFmode, DFmode and XFmode */ - {6, 6, 8}, /* cost of storing fp registers - in SFmode, DFmode and XFmode */ - 2, /* cost of moving MMX register */ - {8, 8}, /* cost of loading MMX registers - in SImode and DImode */ - {8, 8}, /* cost of storing MMX registers - in SImode and DImode */ - 2, /* cost of moving SSE register */ - {8, 8, 8}, /* cost of loading SSE registers - in SImode, DImode and TImode */ - {8, 8, 8}, /* cost of storing SSE registers - in SImode, DImode and TImode */ - 5, /* MMX or SSE register to integer */ - 32, /* size of l1 cache. */ - 256, /* size of l2 cache. */ - 64, /* size of prefetch block */ - 6, /* number of parallel prefetches */ - 3, /* Branch cost */ - COSTS_N_INSNS (8), /* cost of FADD and FSUB insns. */ - COSTS_N_INSNS (8), /* cost of FMUL instruction. */ - COSTS_N_INSNS (20), /* cost of FDIV instruction. */ - COSTS_N_INSNS (8), /* cost of FABS instruction. */ - COSTS_N_INSNS (8), /* cost of FCHS instruction. */ - COSTS_N_INSNS (40), /* cost of FSQRT instruction. */ - generic32_memcpy, - generic32_memset, - 1, /* scalar_stmt_cost. */ - 1, /* scalar load_cost. */ - 1, /* scalar_store_cost. */ - 1, /* vec_stmt_cost. */ - 1, /* vec_to_scalar_cost. */ - 1, /* scalar_to_vec_cost. */ - 1, /* vec_align_load_cost. */ - 2, /* vec_unalign_load_cost. */ - 1, /* vec_store_cost. */ - 3, /* cond_taken_branch_cost. */ - 1, /* cond_not_taken_branch_cost. */ -}; /* Set by -mtune. */ const struct processor_costs *ix86_tune_cost = &pentium_cost; @@ -1929,12 +1855,7 @@ const struct processor_costs *ix86_cost = &pentium_cost; #define m_BTVER (m_BTVER1 | m_BTVER2) #define m_AMD_MULTIPLE (m_ATHLON_K8 | m_AMDFAM10 | m_BDVER | m_BTVER) -#define m_GENERIC32 (1<<PROCESSOR_GENERIC32) -#define m_GENERIC64 (1<<PROCESSOR_GENERIC64) - -/* Generic instruction choice should be common subset of supported CPUs - (PPro/PENT4/NOCONA/CORE2/Athlon/K8). */ -#define m_GENERIC (m_GENERIC32 | m_GENERIC64) +#define m_GENERIC (1<<PROCESSOR_GENERIC) const char* ix86_tune_feature_names[X86_TUNE_LAST] = { #undef DEF_TUNE @@ -2384,8 +2305,7 @@ static const struct ptt processor_target_table[PROCESSOR_max] = {&core_cost, 16, 10, 16, 10, 16}, /* Core avx2 */ {&core_cost, 16, 10, 16, 10, 16}, - {&generic32_cost, 16, 7, 16, 7, 16}, - {&generic64_cost, 16, 10, 16, 10, 16}, + {&generic_cost, 16, 10, 16, 10, 16}, {&amdfam10_cost, 32, 24, 32, 7, 32}, {&bdver1_cost, 16, 10, 16, 7, 11}, {&bdver2_cost, 16, 10, 16, 7, 11}, @@ -3182,7 +3102,7 @@ ix86_option_override_internal (bool main_args_p) | PTA_XOP | PTA_LWP | PTA_BMI | PTA_TBM | PTA_F16C | PTA_FMA | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT | PTA_FSGSBASE}, - {"btver1", PROCESSOR_BTVER1, CPU_GENERIC64, + {"btver1", PROCESSOR_BTVER1, CPU_GENERIC, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 | PTA_SSE4A |PTA_ABM | PTA_CX16 | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE}, @@ -3193,9 +3113,7 @@ ix86_option_override_internal (bool main_args_p) | PTA_BMI | PTA_F16C | PTA_MOVBE | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT}, - {"generic32", PROCESSOR_GENERIC32, CPU_PENTIUMPRO, - PTA_HLE /* flags are only used for -march switch. */ }, - {"generic64", PROCESSOR_GENERIC64, CPU_GENERIC64, + {"generic", PROCESSOR_GENERIC, CPU_GENERIC, PTA_64BIT | PTA_HLE /* flags are only used for -march switch. */ }, }; @@ -3295,16 +3213,12 @@ ix86_option_override_internal (bool main_args_p) -mtune=native, as it was changed by the driver. */ || !strcmp (ix86_tune_string, "native")) { - if (TARGET_64BIT) - ix86_tune_string = "generic64"; - else - ix86_tune_string = "generic32"; + ix86_tune_string = "generic"; } /* If this call is for setting the option attribute, allow the - generic32/generic64 that was previously set. */ + generic that was previously set. */ else if (!main_args_p - && (!strcmp (ix86_tune_string, "generic32") - || !strcmp (ix86_tune_string, "generic64"))) + && !strcmp (ix86_tune_string, "generic")) ; else if (!strncmp (ix86_tune_string, "generic", 7)) error ("bad value (%s) for %stune=%s %s", @@ -3330,10 +3244,7 @@ ix86_option_override_internal (bool main_args_p) || !strcmp (ix86_tune_string, "x86-64") || !strcmp (ix86_tune_string, "i686")) { - if (TARGET_64BIT) - ix86_tune_string = "generic64"; - else - ix86_tune_string = "generic32"; + ix86_tune_string = "generic"; } } @@ -3630,20 +3541,6 @@ ix86_option_override_internal (bool main_args_p) "instruction set"); } } - else - { - /* Adjust tuning when compiling for 32-bit ABI. */ - switch (ix86_tune) - { - case PROCESSOR_GENERIC64: - ix86_tune = PROCESSOR_GENERIC32; - ix86_schedule = CPU_PENTIUMPRO; - break; - - default: - break; - } - } /* Intel CPUs have always interpreted SSE prefetch instructions as NOPs; so, we can enable SSE prefetch instructions even when -mtune (rather than -march) points us to a processor that has them. @@ -17469,13 +17366,23 @@ distance_agu_use_in_bb (unsigned int regno, rtx insn, int distance, rtx start, bool *found, bool *redefined) { - basic_block bb = start ? BLOCK_FOR_INSN (start) : NULL; + basic_block bb = NULL; rtx next = start; rtx prev = NULL; *found = false; *redefined = false; + if (start != NULL_RTX) + { + bb = BLOCK_FOR_INSN (start); + if (start != BB_HEAD (bb)) + /* If insn and start belong to the same bb, set prev to insn, + so the call to increase_distance will increase the distance + between insns by 1. */ + prev = insn; + } + while (next && next != insn && distance < LEA_SEARCH_THRESHOLD) @@ -24493,8 +24400,7 @@ ix86_issue_rate (void) case PROCESSOR_K8: case PROCESSOR_AMDFAM10: case PROCESSOR_NOCONA: - case PROCESSOR_GENERIC32: - case PROCESSOR_GENERIC64: + case PROCESSOR_GENERIC: case PROCESSOR_BDVER1: case PROCESSOR_BDVER2: case PROCESSOR_BDVER3: @@ -24758,8 +24664,7 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost) case PROCESSOR_BTVER1: case PROCESSOR_BTVER2: case PROCESSOR_ATOM: - case PROCESSOR_GENERIC32: - case PROCESSOR_GENERIC64: + case PROCESSOR_GENERIC: memory = get_attr_memory (insn); /* Show ability of reorder buffer to hide latency of load by executing diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 709d3edfef3..440844e7735 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -251,9 +251,7 @@ extern const struct processor_costs ix86_size_cost; #define TARGET_CORE2 (ix86_tune == PROCESSOR_CORE2) #define TARGET_COREI7 (ix86_tune == PROCESSOR_COREI7) #define TARGET_HASWELL (ix86_tune == PROCESSOR_HASWELL) -#define TARGET_GENERIC32 (ix86_tune == PROCESSOR_GENERIC32) -#define TARGET_GENERIC64 (ix86_tune == PROCESSOR_GENERIC64) -#define TARGET_GENERIC (TARGET_GENERIC32 || TARGET_GENERIC64) +#define TARGET_GENERIC (ix86_tune == PROCESSOR_GENERIC) #define TARGET_AMDFAM10 (ix86_tune == PROCESSOR_AMDFAM10) #define TARGET_BDVER1 (ix86_tune == PROCESSOR_BDVER1) #define TARGET_BDVER2 (ix86_tune == PROCESSOR_BDVER2) @@ -2141,8 +2139,7 @@ enum processor_type PROCESSOR_CORE2, PROCESSOR_COREI7, PROCESSOR_HASWELL, - PROCESSOR_GENERIC32, - PROCESSOR_GENERIC64, + PROCESSOR_GENERIC, PROCESSOR_AMDFAM10, PROCESSOR_BDVER1, PROCESSOR_BDVER2, diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 013673ab9ba..e009bc96fc2 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -349,7 +349,7 @@ ;; Processor type. (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7, - atom,slm,generic64,amdfam10,bdver1,bdver2,bdver3,btver1,btver2" + atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,btver1,btver2" (const (symbol_ref "ix86_schedule"))) ;; A basic instruction type. Refinements due to arguments to be diff --git a/gcc/config/i386/x86-tune.def b/gcc/config/i386/x86-tune.def index 0edc07247c8..fc19df19d79 100644 --- a/gcc/config/i386/x86-tune.def +++ b/gcc/config/i386/x86-tune.def @@ -23,7 +23,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see tradeoff. We can't enable it for 32bit generic because it does not work well with PPro base chips. */ DEF_TUNE (X86_TUNE_USE_LEAVE, "use_leave", - m_386 | m_CORE_ALL | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC64) + m_386 | m_CORE_ALL | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC) DEF_TUNE (X86_TUNE_PUSH_MEMORY, "push_memory", m_386 | m_P4_NOCONA | m_CORE_ALL | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC) @@ -49,10 +49,7 @@ DEF_TUNE (X86_TUNE_MOVX, "movx", register stalls on Generic32 compilation setting as well. However in current implementation the partial register stalls are not eliminated very well - they can be introduced via subregs synthesized by combine - and can happen in caller/callee saving sequences. Because this option - pays back little on PPro based chips and is in conflict with partial reg - dependencies used by Athlon/P4 based chips, it is better to leave it off - for generic32 for now. */ + and can happen in caller/callee saving sequences. */ DEF_TUNE (X86_TUNE_PARTIAL_REG_STALL, "partial_reg_stall", m_PPRO) DEF_TUNE (X86_TUNE_PARTIAL_FLAG_REG_STALL, "partial_flag_reg_stall", m_CORE_ALL | m_GENERIC) @@ -163,7 +160,7 @@ DEF_TUNE (X86_TUNE_EXT_80387_CONSTANTS, "ext_80387_constants", m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE | m_ATHLON_K8 | m_GENERIC) DEF_TUNE (X86_TUNE_AVOID_VECTOR_DECODE, "avoid_vector_decode", - m_CORE_ALL | m_K8 | m_GENERIC64) + m_CORE_ALL | m_K8 | m_GENERIC) /* X86_TUNE_PROMOTE_HIMODE_IMUL: Modern CPUs have same latency for HImode and SImode multiply, but 386 and 486 do HImode multiply faster. */ DEF_TUNE (X86_TUNE_PROMOTE_HIMODE_IMUL, "promote_himode_imul", @@ -171,11 +168,11 @@ DEF_TUNE (X86_TUNE_PROMOTE_HIMODE_IMUL, "promote_himode_imul", /* X86_TUNE_SLOW_IMUL_IMM32_MEM: Imul of 32-bit constant and memory is vector path on AMD machines. */ DEF_TUNE (X86_TUNE_SLOW_IMUL_IMM32_MEM, "slow_imul_imm32_mem", - m_CORE_ALL | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC64) + m_CORE_ALL | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC) /* X86_TUNE_SLOW_IMUL_IMM8: Imul of 8-bit constant is vector path on AMD machines. */ DEF_TUNE (X86_TUNE_SLOW_IMUL_IMM8, "slow_imul_imm8", - m_CORE_ALL | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC64) + m_CORE_ALL | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC) /* X86_TUNE_MOVE_M1_VIA_OR: On pentiums, it is faster to load -1 via OR than a MOV. */ DEF_TUNE (X86_TUNE_MOVE_M1_VIA_OR, "move_m1_via_or", m_PENT) diff --git a/gcc/config/msp430/constraints.md b/gcc/config/msp430/constraints.md index baacf923bd3..ea53481bfdb 100644 --- a/gcc/config/msp430/constraints.md +++ b/gcc/config/msp430/constraints.md @@ -70,5 +70,3 @@ (match_test ("IN_RANGE (INTVAL (XEXP (XEXP (op, 0), 1)), -1 << 15, (1 << 15)-1)")))) (match_code "reg" "0") ))) - - diff --git a/gcc/config/msp430/msp430-protos.h b/gcc/config/msp430/msp430-protos.h index df90d95c36e..f116855ecae 100644 --- a/gcc/config/msp430/msp430-protos.h +++ b/gcc/config/msp430/msp430-protos.h @@ -21,6 +21,7 @@ #ifndef GCC_MSP430_PROTOS_H #define GCC_MSP430_PROTOS_H +rtx msp430_eh_return_stackadj_rtx (void); void msp430_expand_eh_return (rtx); void msp430_expand_epilogue (int); void msp430_expand_helper (rtx *operands, const char *, bool); @@ -32,13 +33,14 @@ int msp430_hard_regno_nregs (int, enum machine_mode); rtx msp430_incoming_return_addr_rtx (void); void msp430_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int); int msp430_initial_elimination_offset (int, int); +bool msp430_is_interrupt_func (void); const char * msp430x_logical_shift_right (rtx); +bool msp430_modes_tieable_p (enum machine_mode, enum machine_mode); void msp430_output_labelref (FILE *, const char *); void msp430_register_pragmas (void); rtx msp430_return_addr_rtx (int); void msp430_split_movsi (rtx *); rtx msp430_subreg (enum machine_mode, rtx, enum machine_mode, int); -rtx msp430_eh_return_stackadj_rtx (void); -bool msp430_modes_tieable_p (enum machine_mode, enum machine_mode); +void msp430_start_function (FILE *, const char *, tree); #endif /* GCC_MSP430_PROTOS_H */ diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index 2e6705dad9b..9384d32457a 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -120,7 +120,7 @@ msp430_option_override (void) msp430x = true; if (TARGET_LARGE && !msp430x) - error ("-mlarge requires a 430X-compatible -mcpu="); + error ("-mlarge requires a 430X-compatible -mmcu="); if (flag_exceptions || flag_non_call_exceptions || flag_unwind_tables || flag_asynchronous_unwind_tables) @@ -208,10 +208,9 @@ msp430_can_eliminate (const int from_reg ATTRIBUTE_UNUSED, /* Implements INITIAL_ELIMINATION_OFFSET. */ int -msp430_initial_elimination_offset (int from ATTRIBUTE_UNUSED, - int to ATTRIBUTE_UNUSED) +msp430_initial_elimination_offset (int from, int to) { - int rv = 0; /* as if arg to arg */ + int rv = 0; /* As if arg to arg. */ msp430_compute_frame_info (); @@ -763,6 +762,10 @@ static bool msp430_rtx_costs (rtx x ATTRIBUTE_UNUSED, | | | PC from call | (2 bytes for 430, 4 for TARGET_LARGE) | | + +--------------------+ + | SR if this func has| + | been called via an | + | interrupt. | +--------------------+ <-- SP before prologue, also AP | | | Saved Regs | (2 bytes per reg for 430, 4 per for TARGET_LARGE) @@ -806,6 +809,12 @@ msp430_preserve_reg_p (int regno) if (fixed_regs [regno]) return false; + /* Interrupt handlers save all registers they use, even + ones which are call saved. If they call other functions + then *every* register is saved. */ + if (msp430_is_interrupt_func ()) + return ! crtl->is_leaf || df_regs_ever_live_p (regno); + if (!call_used_regs [regno] && df_regs_ever_live_p (regno)) return true; @@ -825,7 +834,7 @@ msp430_compute_frame_info (void) cfun->machine->framesize_locals = get_frame_size (); cfun->machine->framesize_outgoing = crtl->outgoing_args_size; - for (i = 0; i < 16; i ++) + for (i = 0; i < ARG_POINTER_REGNUM; i ++) if (msp430_preserve_reg_p (i)) { cfun->machine->need_to_save [i] = 1; @@ -842,6 +851,38 @@ msp430_compute_frame_info (void) + cfun->machine->framesize_outgoing); } +static inline bool +is_attr_func (const char * attr) +{ + return lookup_attribute (attr, DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE; +} + +/* Returns true if the current function has the "interrupt" attribute. */ + +bool +msp430_is_interrupt_func (void) +{ + return is_attr_func ("interrupt"); +} + +static inline bool +is_naked_func (void) +{ + return is_attr_func ("naked"); +} + +static inline bool +is_reentrant_func (void) +{ + return is_attr_func ("reentrant"); +} + +static inline bool +is_critical_func (void) +{ + return is_attr_func ("critical"); +} + #undef TARGET_ASM_FUNCTION_PROLOGUE #define TARGET_ASM_FUNCTION_PROLOGUE msp430_start_function @@ -851,6 +892,21 @@ msp430_start_function (FILE *outfile, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED) int r, n; fprintf (outfile, "; start of function\n"); + + if (DECL_ATTRIBUTES (current_function_decl) != NULL_TREE) + { + fprintf (outfile, "; attributes: "); + if (is_naked_func ()) + fprintf (outfile, "naked "); + if (msp430_is_interrupt_func ()) + fprintf (outfile, "interrupt "); + if (is_reentrant_func ()) + fprintf (outfile, "reentrant "); + if (is_critical_func ()) + fprintf (outfile, "critical "); + fprintf (outfile, "\n"); + } + fprintf (outfile, "; framesize_regs: %d\n", cfun->machine->framesize_regs); fprintf (outfile, "; framesize_locals: %d\n", cfun->machine->framesize_locals); fprintf (outfile, "; framesize_outgoing: %d\n", cfun->machine->framesize_outgoing); @@ -860,7 +916,7 @@ msp430_start_function (FILE *outfile, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED) n = 0; fprintf (outfile, "; saved regs:"); - for (r = 0; r < 16; r++) + for (r = 0; r < ARG_POINTER_REGNUM; r++) if (cfun->machine->need_to_save [r]) { fprintf (outfile, " %s", reg_names [r]); @@ -899,6 +955,215 @@ increment_stack (HOST_WIDE_INT amount) } } +/* Verify MSP430 specific attributes. */ + +static tree +msp430_attr (tree * node, + tree name, + tree args, + int flags ATTRIBUTE_UNUSED, + bool * no_add_attrs) +{ + gcc_assert (DECL_P (* node)); + + if (args != NULL) + { + tree value = TREE_VALUE (args); + + switch (TREE_CODE (value)) + { + case STRING_CST: + if ( strcmp (TREE_STRING_POINTER (value), "reset") + && strcmp (TREE_STRING_POINTER (value), "nmi") + && strcmp (TREE_STRING_POINTER (value), "watchdog")) + /* Allow the attribute to be added - the linker script + being used may still recognise this name. */ + warning (OPT_Wattributes, + "unrecognised interrupt vector argument of %qE attribute", + name); + break; + + case INTEGER_CST: + if (TREE_INT_CST_LOW (value) > 31) + /* Allow the attribute to be added - the linker script + being used may still recognise this value. */ + warning (OPT_Wattributes, + "numeric argument of %qE attribute must be in range 0..31", + name); + break; + + default: + warning (OPT_Wattributes, + "argument of %qE attribute is not a string constant or number", + name); + *no_add_attrs = true; + break; + } + } + + if (TREE_CODE (* node) != FUNCTION_DECL) + { + warning (OPT_Wattributes, + "%qE attribute only applies to functions", + name); + * no_add_attrs = true; + } + + /* FIXME: We ought to check that the interrupt handler + attribute has been applied to a void function. */ + /* FIXME: We should check that reentrant and critical + functions are not naked and that critical functions + are not reentrant. */ + + return NULL_TREE; +} + +#undef TARGET_ATTRIBUTE_TABLE +#define TARGET_ATTRIBUTE_TABLE msp430_attribute_table + +/* Table of MSP430-specific attributes. */ +const struct attribute_spec msp430_attribute_table[] = +{ + /* Name min_len decl_req, fn_type_req, affects_type_identity + max_len, type_req, handler. */ + { "interrupt", 0, 1, true, false, false, msp430_attr, false }, + { "naked", 0, 0, true, false, false, msp430_attr, false }, + { "reentrant", 0, 0, true, false, false, msp430_attr, false }, + { "critical", 0, 0, true, false, false, msp430_attr, false }, + { NULL, 0, 0, false, false, false, NULL, false } +}; + +void +msp430_start_function (FILE *file, const char *name, tree decl) +{ + tree int_attr; + + int_attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl)); + if (int_attr != NULL_TREE) + { + tree intr_vector = TREE_VALUE (int_attr); + + if (intr_vector != NULL_TREE) + { + char buf[101]; + + intr_vector = TREE_VALUE (intr_vector); + + /* The interrupt attribute has a vector value. Turn this into a + section name, switch to that section and put the address of + the current function into that vector slot. Note msp430_attr() + has already verified the vector name for us. */ + if (TREE_CODE (intr_vector) == STRING_CST) + sprintf (buf, "__interrupt_vector_%.80s", + TREE_STRING_POINTER (intr_vector)); + else /* TREE_CODE (intr_vector) == INTEGER_CST */ + sprintf (buf, "__interrupt_vector_%u", + (unsigned int) TREE_INT_CST_LOW (intr_vector)); + + switch_to_section (get_section (buf, SECTION_CODE, decl)); + fputs ("\t.word\t", file); + assemble_name (file, name); + fputc ('\n', file); + fputc ('\t', file); + } + } + + switch_to_section (function_section (decl)); + ASM_OUTPUT_FUNCTION_LABEL (file, name, decl); +} + +static section * +msp430_function_section (tree decl, enum node_frequency freq, bool startup, bool exit) +{ + /* In large mode we must make sure that interrupt handlers are put into + low memory as the vector table only accepts 16-bit addresses. */ + if (TARGET_LARGE + && lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl))) + return get_section (".lowtext", SECTION_CODE | SECTION_WRITE , decl); + + /* Otherwise, use the default function section. */ + return default_function_section (decl, freq, startup, exit); +} + +#undef TARGET_ASM_FUNCTION_SECTION +#define TARGET_ASM_FUNCTION_SECTION msp430_function_section + +enum msp430_builtin +{ + MSP430_BUILTIN_BIC_SR, + MSP430_BUILTIN_BIS_SR, + MSP430_BUILTIN_max +}; + +static GTY(()) tree msp430_builtins [(int) MSP430_BUILTIN_max]; + +static void +msp430_init_builtins (void) +{ + tree void_ftype_int = build_function_type_list (void_type_node, integer_type_node, NULL); + + msp430_builtins[MSP430_BUILTIN_BIC_SR] = + add_builtin_function ( "__bic_SR_register_on_exit", void_ftype_int, + MSP430_BUILTIN_BIC_SR, BUILT_IN_MD, NULL, NULL_TREE); + + msp430_builtins[MSP430_BUILTIN_BIS_SR] = + add_builtin_function ( "__bis_SR_register_on_exit", void_ftype_int, + MSP430_BUILTIN_BIS_SR, BUILT_IN_MD, NULL, NULL_TREE); +} + +static tree +msp430_builtin_decl (unsigned code, bool initialize ATTRIBUTE_UNUSED) +{ + switch (code) + { + case MSP430_BUILTIN_BIC_SR: + case MSP430_BUILTIN_BIS_SR: + return msp430_builtins[code]; + default: + return error_mark_node; + } +} + +static rtx +msp430_expand_builtin (tree exp, + rtx target ATTRIBUTE_UNUSED, + rtx subtarget ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + int ignore ATTRIBUTE_UNUSED) +{ + tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); + unsigned int fcode = DECL_FUNCTION_CODE (fndecl); + rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0)); + + if (! msp430_is_interrupt_func ()) + { + error ("MSP430 builtin functions only work inside interrupt handlers"); + return NULL_RTX; + } + + if (! REG_P (arg1) && ! CONSTANT_P (arg1)) + arg1 = force_reg (mode, arg1); + + switch (fcode) + { + case MSP430_BUILTIN_BIC_SR: emit_insn (gen_bic_SR (arg1)); break; + case MSP430_BUILTIN_BIS_SR: emit_insn (gen_bis_SR (arg1)); break; + default: + internal_error ("bad builtin code"); + break; + } + return NULL_RTX; +} + +#undef TARGET_INIT_BUILTINS +#define TARGET_INIT_BUILTINS msp430_init_builtins + +#undef TARGET_EXPAND_BUILTIN +#define TARGET_EXPAND_BUILTIN msp430_expand_builtin + +#undef TARGET_BUILTIN_DECL +#define TARGET_BUILTIN_DECL msp430_builtin_decl + void msp430_expand_prologue (void) { @@ -911,8 +1176,19 @@ msp430_expand_prologue (void) rtx sp = stack_pointer_rtx; rtx p; + if (is_naked_func ()) + return; + emit_insn (gen_prologue_start_marker ()); + if (is_critical_func ()) + { + emit_insn (gen_push_intr_state ()); + emit_insn (gen_disable_interrupts ()); + } + else if (is_reentrant_func ()) + emit_insn (gen_disable_interrupts ()); + if (!cfun->machine->computed) msp430_compute_frame_info (); @@ -1009,6 +1285,9 @@ msp430_expand_epilogue (int is_eh) int fs; int helper_n = 0; + if (is_naked_func ()) + return; + if (cfun->machine->need_to_save [10]) { /* Check for a helper function. */ @@ -1070,6 +1349,9 @@ msp430_expand_epilogue (int is_eh) i += count - 1; } else if (i == 11 - helper_n + && ! msp430_is_interrupt_func () + && ! is_reentrant_func () + && ! is_critical_func () && crtl->args.pretend_args_size == 0 /* Calling the helper takes as many bytes as the POP;RET sequence. */ && helper_n != 1 @@ -1092,7 +1374,12 @@ msp430_expand_epilogue (int is_eh) if (crtl->args.pretend_args_size) emit_insn (gen_swap_and_shrink ()); - + + if (is_critical_func ()) + emit_insn (gen_pop_intr_state ()); + else if (is_reentrant_func ()) + emit_insn (gen_enable_interrupts ()); + emit_jump_insn (gen_msp_return ()); } @@ -1131,12 +1418,15 @@ msp430_expand_eh_return (rtx eh_handler) } /* This is a list of MD patterns that implement fixed-count shifts. */ -static struct { +static struct +{ const char *name; int count; int need_430x; rtx (*genfunc)(rtx,rtx); -} const_shift_helpers[] = { +} + const_shift_helpers[] = +{ #define CSH(N,C,X,G) { "__mspabi_"N, C, X, gen_##G } CSH ("slli", 1, 1, slli_1), @@ -1329,7 +1619,6 @@ msp430_split_movsi (rtx *operands) } - /* The MSPABI specifies the names of various helper functions, many of which are compatible with GCC's helpers. This table maps the GCC name to the MSPABI name. */ @@ -1600,6 +1889,15 @@ msp430_print_operand (FILE * file, rtx op, int letter) if (TARGET_LARGE) fprintf (file, "A"); return; + + case 'O': + /* Computes the offset to the top of the stack for the current frame. + This has to be done here rather than in, say, msp430_expand_builtin() + because builtins are expanded before the frame layout is determined. */ + fprintf (file, "%d", + msp430_initial_elimination_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM) + - 2); + return ; } switch (GET_CODE (op)) diff --git a/gcc/config/msp430/msp430.h b/gcc/config/msp430/msp430.h index bf3b15c0efb..f5289b551e3 100644 --- a/gcc/config/msp430/msp430.h +++ b/gcc/config/msp430/msp430.h @@ -1,5 +1,5 @@ /* GCC backend definitions for the TI MSP430 Processor - Copyright (C) 2012 Free Software Foundation, Inc. + Copyright (C) 2012-2013 Free Software Foundation, Inc. Contributed by Red Hat. This file is part of GCC. @@ -29,6 +29,7 @@ extern bool msp430x; #define TARGET_CPU_CPP_BUILTINS() \ do \ { \ + builtin_define ("NO_TRAMPOLINES"); \ builtin_define ("__MSP430__"); \ if (msp430x) \ { \ @@ -53,6 +54,7 @@ extern bool msp430x; "%{mmcu=msp430x:-mmcu=msp430X;mmcu=*:-mmcu=%*} " /* Pass the MCU type on to the assembler. */ \ "%{mrelax=-mQ} " /* Pass the relax option on to the assembler. */ \ "%{mlarge:-ml} " /* Tell the assembler if we are building for the LARGE pointer model. */ \ + "%{!msim:-md} %{msim:%{mlarge:-md}}" /* Copy data from ROM to RAM if necessary. */ \ "%{ffunction-sections:-gdwarf-sections}" /* If function sections are being created then create DWARF line number sections as well. */ /* Enable linker section garbage collection by default, unless we @@ -281,7 +283,8 @@ enum reg_class -typedef struct { +typedef struct +{ /* These two are the current argument status. */ char reg_used[4]; #define CA_FIRST_REG 12 @@ -397,3 +400,7 @@ typedef struct { ) #define ACCUMULATE_OUTGOING_ARGS 1 + +#undef ASM_DECLARE_FUNCTION_NAME +#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ + msp430_start_function ((FILE), (NAME), (DECL)) diff --git a/gcc/config/msp430/msp430.md b/gcc/config/msp430/msp430.md index 4324503a1b7..a258867e532 100644 --- a/gcc/config/msp430/msp430.md +++ b/gcc/config/msp430/msp430.md @@ -38,6 +38,13 @@ UNS_GROW_AND_SWAP UNS_SWAP_AND_SHRINK + + UNS_DINT + UNS_EINT + UNS_PUSH_INTR + UNS_POP_INTR + UNS_BIC_SR + UNS_BIS_SR ]) (include "predicates.md") @@ -78,7 +85,7 @@ (define_insn "pushm" [(unspec_volatile [(match_operand 0 "register_operand" "r") - (match_operand 1 "immediate_operand" "i")] UNS_PUSHM)] + (match_operand 1 "immediate_operand" "n")] UNS_PUSHM)] "" "PUSHM%B0\t%1, %0" ) @@ -950,7 +957,7 @@ (define_insn "msp_return" [(return)] "" - { return TARGET_LARGE ? "RETA" : "RET"; } + { return msp430_is_interrupt_func () ? "RETI" : (TARGET_LARGE ? "RETA" : "RET"); } ) ;; This pattern is NOT, as expected, a return pattern. It's called @@ -1102,7 +1109,6 @@ CMP%X0.W\t%1, %2 { J%R0\t%l3" ) - (define_insn "*bitbranch<mode>4" [(set (pc) (if_then_else (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm") @@ -1158,7 +1164,7 @@ ) ;;------------------------------------------------------------ -;; zero-extend versions of the above +;; zero-extract versions of the above (define_insn "*bitbranch<mode>4_z" [(set (pc) (if_then_else @@ -1227,3 +1233,42 @@ "NOP" ) +(define_insn "disable_interrupts" + [(unspec_volatile [(const_int 0)] UNS_DINT)] + "" + "DINT" + ) + +(define_insn "enable_interrupts" + [(unspec_volatile [(const_int 0)] UNS_EINT)] + "" + "EINT" + ) + +(define_insn "push_intr_state" + [(unspec_volatile [(const_int 0)] UNS_PUSH_INTR)] + "" + "PUSH\tSR" + ) + +(define_insn "pop_intr_state" + [(unspec_volatile [(const_int 0)] UNS_POP_INTR)] + "" + "POP\tSR" + ) + +;; Clear bits in the copy of the status register that is currently +;; saved on the stack at the top of the interrupt handler. +(define_insn "bic_SR" + [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIC_SR)] + "" + "BIC.W\t%0, %O0(SP)" + ) + +;; Set bits in the copy of the status register that is currently +;; saved on the stack at the top of the interrupt handler. +(define_insn "bis_SR" + [(unspec_volatile [(match_operand 0 "nonmemory_operand" "ir")] UNS_BIS_SR)] + "" + "BIS.W\t%0, %O0(SP)" + ) diff --git a/gcc/config/rl78/constraints.md b/gcc/config/rl78/constraints.md index 1edb58d8068..bb0e40c6a32 100644 --- a/gcc/config/rl78/constraints.md +++ b/gcc/config/rl78/constraints.md @@ -203,17 +203,24 @@ ; All the memory addressing schemes the RL78 supports ; of the form W {register} {bytes of offset} ; or W {register} {register} +; Additionally, the Cxx forms are the same as the Wxx forms, but without +; the ES: override. ; absolute address -(define_memory_constraint "Wab" +(define_memory_constraint "Cab" "[addr]" (and (match_code "mem") (ior (match_test "CONSTANT_P (XEXP (op, 0))") (match_test "GET_CODE (XEXP (op, 0)) == PLUS && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF")) ) ) +(define_memory_constraint "Wab" + "es:[addr]" + (match_test "rl78_es_addr (op) && satisfies_constraint_Cab (rl78_es_base (op)) + || satisfies_constraint_Cab (op)") + ) -(define_memory_constraint "Wbc" +(define_memory_constraint "Cbc" "word16[BC]" (and (match_code "mem") (ior @@ -225,29 +232,49 @@ (match_test "uword_operand (XEXP (XEXP (op, 0), 1), VOIDmode)")))) ) ) +(define_memory_constraint "Wbc" + "es:word16[BC]" + (match_test "rl78_es_addr (op) && satisfies_constraint_Cbc (rl78_es_base (op)) + || satisfies_constraint_Cbc (op)") + ) -(define_memory_constraint "Wde" +(define_memory_constraint "Cde" "[DE]" (and (match_code "mem") (and (match_code "reg" "0") (match_test "REGNO (XEXP (op, 0)) == DE_REG"))) ) +(define_memory_constraint "Wde" + "es:[DE]" + (match_test "rl78_es_addr (op) && satisfies_constraint_Cde (rl78_es_base (op)) + || satisfies_constraint_Cde (op)") + ) -(define_memory_constraint "Wca" +(define_memory_constraint "Cca" "[AX..HL] for calls" (and (match_code "mem") (and (match_code "reg" "0") (match_test "REGNO (XEXP (op, 0)) <= HL_REG"))) ) +(define_memory_constraint "Wca" + "es:[AX..HL] for calls" + (match_test "rl78_es_addr (op) && satisfies_constraint_Cca (rl78_es_base (op)) + || satisfies_constraint_Cca (op)") + ) -(define_memory_constraint "Wcv" - "[AX..HL,r8-r23] for calls" +(define_memory_constraint "Ccv" + "[AX..HL,r8-r31] for calls" (and (match_code "mem") (and (match_code "reg" "0") - (match_test "REGNO (XEXP (op, 0)) < 24"))) + (match_test "REGNO (XEXP (op, 0)) < 31"))) + ) +(define_memory_constraint "Wcv" + "es:[AX..HL,r8-r23] for calls" + (match_test "rl78_es_addr (op) && satisfies_constraint_Ccv (rl78_es_base (op)) + || satisfies_constraint_Ccv (op)") ) -(define_memory_constraint "Wd2" +(define_memory_constraint "Cd2" "word16[DE]" (and (match_code "mem") (ior @@ -259,15 +286,25 @@ (match_test "uword_operand (XEXP (XEXP (op, 0), 1), VOIDmode)")))) ) ) +(define_memory_constraint "Wd2" + "es:word16[DE]" + (match_test "rl78_es_addr (op) && satisfies_constraint_Cd2 (rl78_es_base (op)) + || satisfies_constraint_Cd2 (op)") + ) -(define_memory_constraint "Whl" +(define_memory_constraint "Chl" "[HL]" (and (match_code "mem") (and (match_code "reg" "0") (match_test "REGNO (XEXP (op, 0)) == HL_REG"))) ) +(define_memory_constraint "Whl" + "es:[HL]" + (match_test "rl78_es_addr (op) && satisfies_constraint_Chl (rl78_es_base (op)) + || satisfies_constraint_Chl (op)") + ) -(define_memory_constraint "Wh1" +(define_memory_constraint "Ch1" "byte8[HL]" (and (match_code "mem") (and (match_code "plus" "0") @@ -275,14 +312,24 @@ (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == HL_REG")) (match_test "ubyte_operand (XEXP (XEXP (op, 0), 1), VOIDmode)")))) ) +(define_memory_constraint "Wh1" + "es:byte8[HL]" + (match_test "rl78_es_addr (op) && satisfies_constraint_Ch1 (rl78_es_base (op)) + || satisfies_constraint_Ch1 (op)") + ) -(define_memory_constraint "Whb" +(define_memory_constraint "Chb" "[HL+B]" (and (match_code "mem") (match_test "rl78_hl_b_c_addr_p (XEXP (op, 0))")) ) +(define_memory_constraint "Whb" + "es:[HL+B]" + (match_test "rl78_es_addr (op) && satisfies_constraint_Chb (rl78_es_base (op)) + || satisfies_constraint_Chb (op)") + ) -(define_memory_constraint "Ws1" +(define_memory_constraint "Cs1" "word8[SP]" (and (match_code "mem") (ior @@ -294,6 +341,11 @@ (match_test "ubyte_operand (XEXP (XEXP (op, 0), 1), VOIDmode)")))) ) ) +(define_memory_constraint "Ws1" + "es:word8[SP]" + (match_test "rl78_es_addr (op) && satisfies_constraint_Cs1 (rl78_es_base (op)) + || satisfies_constraint_Cs1 (op)") + ) (define_memory_constraint "Wfr" "ES/CS far pointer" diff --git a/gcc/config/rl78/rl78-protos.h b/gcc/config/rl78/rl78-protos.h index 580609da2f9..1f30e637b72 100644 --- a/gcc/config/rl78/rl78-protos.h +++ b/gcc/config/rl78/rl78-protos.h @@ -42,3 +42,6 @@ void rl78_register_pragmas (void); bool rl78_regno_mode_code_ok_for_base_p (int, enum machine_mode, addr_space_t, int, int); void rl78_setup_peep_movhi (rtx *); bool rl78_virt_insns_ok (void); + +bool rl78_es_addr (rtx); +rtx rl78_es_base (rtx); diff --git a/gcc/config/rl78/rl78-real.md b/gcc/config/rl78/rl78-real.md index 409abcc4a2a..90b380a54e4 100644 --- a/gcc/config/rl78/rl78-real.md +++ b/gcc/config/rl78/rl78-real.md @@ -459,3 +459,58 @@ [(set (match_dup 0) (reg:HI AX_REG))] ) +;; Bit test and branch insns. + +;; NOTE: These patterns will work for bits in other places, not just A. + +(define_insn "bf" + [(set (pc) + (if_then_else (eq (and (reg:QI A_REG) + (match_operand 0 "immediate_operand" "n")) + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc)))] + "" + "bf\tA.%B0, $%1" +) + +(define_insn "bt" + [(set (pc) + (if_then_else (ne (and (reg:QI A_REG) + (match_operand 0 "immediate_operand" "n")) + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc)))] + "" + "bt\tA.%B0, $%1" +) + +;; NOTE: These peepholes are fragile. They rely upon GCC generating +;; a specific sequence on insns, based upon examination of test code. +;; Improvements to GCC or using code other than the test code can result +;; in the peephole not matching and the optimization being missed. + +(define_peephole2 + [(set (match_operand:QI 1 "register_operand") (reg:QI A_REG)) + (set (match_dup 1) (and:QI (match_dup 1) (match_operand 2 "immediate_operand"))) + (set (pc) (if_then_else (eq (match_dup 1) (const_int 0)) + (label_ref (match_operand 3 "")) + (pc)))] + "peep2_regno_dead_p (3, REGNO (operands[1])) + && exact_log2 (INTVAL (operands[2])) >= 0" + [(set (pc) (if_then_else (eq (and (reg:QI A_REG) (match_dup 2)) (const_int 0)) + (label_ref (match_dup 3)) (pc)))] + ) + +(define_peephole2 + [(set (match_operand:QI 1 "register_operand") (reg:QI A_REG)) + (set (match_dup 1) (and:QI (match_dup 1) (match_operand 2 "immediate_operand"))) + (set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) + (label_ref (match_operand 3 "")) + (pc)))] + "peep2_regno_dead_p (3, REGNO (operands[1])) + && exact_log2 (INTVAL (operands[2])) >= 0" + [(set (pc) (if_then_else (ne (and (reg:QI A_REG) (match_dup 2)) (const_int 0)) + (label_ref (match_dup 3)) (pc)))] + ) + diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c index 3f13955d896..5902e1ecd8f 100644 --- a/gcc/config/rl78/rl78.c +++ b/gcc/config/rl78/rl78.c @@ -259,10 +259,21 @@ rl78_asm_file_start (void) { int i; - for (i = 0; i < 8; i++) + if (TARGET_G10) { - fprintf (asm_out_file, "r%d\t=\t0x%x\n", 8 + i, 0xffef0 + i); - fprintf (asm_out_file, "r%d\t=\t0x%x\n", 16 + i, 0xffee8 + i); + /* The memory used is 0xffec8 to 0xffedf; real registers are in + 0xffee0 to 0xffee7. */ + for (i = 8; i < 32; i++) + fprintf (asm_out_file, "r%d\t=\t0x%x\n", i, 0xffec0 + i); + } + else + { + for (i = 0; i < 8; i++) + { + fprintf (asm_out_file, "r%d\t=\t0x%x\n", 8 + i, 0xffef0 + i); + fprintf (asm_out_file, "r%d\t=\t0x%x\n", 16 + i, 0xffee8 + i); + fprintf (asm_out_file, "r%d\t=\t0x%x\n", 24 + i, 0xffee0 + i); + } } opt_pass *rl78_devirt_pass = make_pass_rl78_devirt (g); @@ -299,6 +310,13 @@ rl78_option_override (void) flag_split_wide_types = 0; init_machine_status = rl78_init_machine_status; + + if (TARGET_ALLREGS) + { + int i; + for (i=24; i<32; i++) + fixed_regs[i] = 0; + } } /* Most registers are 8 bits. Some are 16 bits because, for example, @@ -530,34 +548,39 @@ rl78_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to ATTRIBUTE_UNUS return true; } -/* Returns nonzero if the given register needs to be saved by the +/* Returns true if the given register needs to be saved by the current function. */ -static int -need_to_save (int regno) +static bool +need_to_save (unsigned int regno) { if (is_interrupt_func (cfun->decl)) { - if (regno < 8) - return 1; /* don't know what devirt will need */ + /* We don't need to save registers that have + been reserved for interrupt handlers. */ if (regno > 23) - return 0; /* don't need to save interrupt registers */ - if (crtl->is_leaf) - { - return df_regs_ever_live_p (regno); - } - else - return 1; + return false; + + /* If the handler is a non-leaf function then it may call + non-interrupt aware routines which will happily clobber + any call_used registers, so we have to preserve them. */ + if (!crtl->is_leaf && call_used_regs[regno]) + return true; + + /* Otherwise we only have to save a register, call_used + or not, if it is used by this handler. */ + return df_regs_ever_live_p (regno); } + if (regno == FRAME_POINTER_REGNUM && frame_pointer_needed) - return 1; + return true; if (fixed_regs[regno]) - return 0; + return false; if (crtl->calls_eh_return) - return 1; + return true; if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) - return 1; - return 0; + return true; + return false; } /* We use this to wrap all emitted insns in the prologue. */ @@ -848,6 +871,10 @@ rl78_as_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x, { rtx base, index, addend; + if (GET_CODE (x) == UNSPEC + && XINT (x, 1) == UNS_ES_ADDR) + x = XVECEXP (x, 0, 1); + if (as == ADDR_SPACE_GENERIC && GET_MODE (x) == SImode) return false; @@ -1012,25 +1039,38 @@ rl78_expand_prologue (void) if (rl78_is_naked_func ()) return; - if (!cfun->machine->computed) - rl78_compute_frame_info (); + /* Always re-compute the frame info - the register usage may have changed. */ + rl78_compute_frame_info (); if (flag_stack_usage_info) current_function_static_stack_size = cfun->machine->framesize; - if (is_interrupt_func (cfun->decl)) - emit_insn (gen_sel_rb (GEN_INT (0))); + if (is_interrupt_func (cfun->decl) && !TARGET_G10) + for (i = 0; i < 4; i++) + if (cfun->machine->need_to_push [i]) + { + /* Select Bank 0 if we are using any registers from Bank 0. */ + emit_insn (gen_sel_rb (GEN_INT (0))); + break; + } for (i = 0; i < 16; i++) if (cfun->machine->need_to_push [i]) { - int need_bank = i/4; - if (need_bank != rb) + if (TARGET_G10) { - emit_insn (gen_sel_rb (GEN_INT (need_bank))); - rb = need_bank; + emit_move_insn (gen_rtx_REG (HImode, 0), gen_rtx_REG (HImode, i*2)); + F (emit_insn (gen_push (gen_rtx_REG (HImode, 0)))); } - F (emit_insn (gen_push (gen_rtx_REG (HImode, i*2)))); + else { + int need_bank = i/4; + if (need_bank != rb) + { + emit_insn (gen_sel_rb (GEN_INT (need_bank))); + rb = need_bank; + } + F (emit_insn (gen_push (gen_rtx_REG (HImode, i*2)))); + } } if (rb != 0) emit_insn (gen_sel_rb (GEN_INT (0))); @@ -1085,14 +1125,22 @@ rl78_expand_epilogue (void) for (i = 15; i >= 0; i--) if (cfun->machine->need_to_push [i]) { - int need_bank = i / 4; - - if (need_bank != rb) + if (TARGET_G10) + { + emit_insn (gen_pop (gen_rtx_REG (HImode, 0))); + emit_move_insn (gen_rtx_REG (HImode, i*2), gen_rtx_REG (HImode, 0)); + } + else { - emit_insn (gen_sel_rb (GEN_INT (need_bank))); - rb = need_bank; + int need_bank = i / 4; + + if (need_bank != rb) + { + emit_insn (gen_sel_rb (GEN_INT (need_bank))); + rb = need_bank; + } + emit_insn (gen_pop (gen_rtx_REG (HImode, i * 2))); } - emit_insn (gen_pop (gen_rtx_REG (HImode, i * 2))); } if (rb != 0) @@ -1238,6 +1286,7 @@ rl78_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED, s - shift count mod 8 S - shift count mod 16 r - reverse shift count (8-(count mod 8)) + B - bit position h - bottom HI of an SI H - top HI of an SI @@ -1265,7 +1314,10 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter) else { if (rl78_far_p (op)) - fprintf (file, "es:"); + { + fprintf (file, "es:"); + op = gen_rtx_MEM (GET_MODE (op), XVECEXP (XEXP (op, 0), 0, 1)); + } if (letter == 'H') { op = adjust_address (op, HImode, 2); @@ -1361,6 +1413,8 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter) fprintf (file, "%ld", INTVAL (op) & 0xffff); else if (letter == 'e') fprintf (file, "%ld", (INTVAL (op) >> 16) & 0xff); + else if (letter == 'B') + fprintf (file, "%d", exact_log2 (INTVAL (op))); else if (letter == 'E') fprintf (file, "%ld", (INTVAL (op) >> 24) & 0xff); else if (letter == 'm') @@ -1554,7 +1608,7 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter) static void rl78_print_operand (FILE * file, rtx op, int letter) { - if (CONSTANT_P (op) && letter != 'u' && letter != 's' && letter != 'r' && letter != 'S') + if (CONSTANT_P (op) && letter != 'u' && letter != 's' && letter != 'r' && letter != 'S' && letter != 'B') fprintf (file, "#"); rl78_print_operand_1 (file, op, letter); } @@ -1630,6 +1684,16 @@ rl78_peep_movhi_p (rtx *operands) fprintf (stderr, "\033[0m"); #endif + /* You can move a constant to memory as QImode, but not HImode. */ + if (GET_CODE (operands[0]) == MEM + && GET_CODE (operands[1]) != REG) + { +#if DEBUG_PEEP + fprintf (stderr, "no peep: move constant to memory\n"); +#endif + return false; + } + if (rtx_equal_p (operands[0], operands[3])) { #if DEBUG_PEEP @@ -1812,6 +1876,8 @@ re-run regmove, but that has not yet been attempted. */ #define DEBUG_ALLOC 0 +#define OP(x) (*recog_data.operand_loc[x]) + /* This array is used to hold knowledge about the contents of the real registers (A ... H), the memory-based registers (r8 ... r31) and the first NUM_STACK_LOCS words on the stack. We use this to @@ -2037,6 +2103,31 @@ already_contains (rtx loc, rtx value) return true; } +bool +rl78_es_addr (rtx addr) +{ + if (GET_CODE (addr) == MEM) + addr = XEXP (addr, 0); + if (GET_CODE (addr) != UNSPEC) + return false; + if (XINT (addr, 1) != UNS_ES_ADDR) + return false; + return true; +} + +rtx +rl78_es_base (rtx addr) +{ + if (GET_CODE (addr) == MEM) + addr = XEXP (addr, 0); + addr = XVECEXP (addr, 0, 1); + if (GET_CODE (addr) == CONST + && GET_CODE (XEXP (addr, 0)) == ZERO_EXTRACT) + addr = XEXP (XEXP (addr, 0), 0); + /* Mode doesn't matter here. */ + return gen_rtx_MEM (HImode, addr); +} + /* Rescans an insn to see if it's recognized again. This is done carefully to ensure that all the constraint information is accurate for the newly matched insn. */ @@ -2044,6 +2135,7 @@ static bool insn_ok_now (rtx insn) { rtx pattern = PATTERN (insn); + int i; INSN_CODE (insn) = -1; @@ -2060,6 +2152,14 @@ insn_ok_now (rtx insn) if (SET_P (pattern)) record_content (SET_DEST (pattern), SET_SRC (pattern)); + /* We need to detect far addresses that haven't been + converted to es/lo16 format. */ + for (i=0; i<recog_data.n_operands; i++) + if (GET_CODE (OP(i)) == MEM + && GET_MODE (XEXP (OP(i), 0)) == SImode + && GET_CODE (XEXP (OP(i), 0)) != UNSPEC) + return false; + return true; } } @@ -2120,15 +2220,13 @@ insn_ok_now (rtx insn) #define DE gen_rtx_REG (HImode, 4) #define HL gen_rtx_REG (HImode, 6) -#define OP(x) (*recog_data.operand_loc[x]) - /* Returns TRUE if R is a virtual register. */ static bool is_virtual_register (rtx r) { return (GET_CODE (r) == REG && REGNO (r) >= 8 - && REGNO (r) < 24); + && REGNO (r) < 32); } /* In all these alloc routines, we expect the following: the insn @@ -2160,14 +2258,20 @@ EM2 (int line ATTRIBUTE_UNUSED, rtx r) static rtx rl78_lo16 (rtx addr) { + rtx r; + if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST) { - rtx r = gen_rtx_ZERO_EXTRACT (HImode, addr, GEN_INT (16), GEN_INT (0)); + r = gen_rtx_ZERO_EXTRACT (HImode, addr, GEN_INT (16), GEN_INT (0)); r = gen_rtx_CONST (HImode, r); - return r; } - return rl78_subreg (HImode, addr, SImode, 0); + else + r = rl78_subreg (HImode, addr, SImode, 0); + + r = gen_es_addr (r); + + return r; } /* Return a suitable RTX for the high half's lower byte of a __far address. */ @@ -2271,6 +2375,7 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) { rtx base, index, addendr; int addend = 0; + int need_es = 0; if (! MEM_P (m)) return m; @@ -2287,6 +2392,7 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) record_content (A, NULL_RTX); m = change_address (m, GET_MODE (m), rl78_lo16 (XEXP (m, 0))); + need_es = 1; } characterize_address (XEXP (m, 0), & base, & index, & addendr); @@ -2346,7 +2452,10 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) fprintf (stderr, "\033[33m"); debug_rtx (m); #endif - m = change_address (m, GET_MODE (m), base); + if (need_es) + m = change_address (m, GET_MODE (m), gen_es_addr (base)); + else + m = change_address (m, GET_MODE (m), base); #if DEBUG_ALLOC debug_rtx (m); fprintf (stderr, "\033[0m"); diff --git a/gcc/config/rl78/rl78.h b/gcc/config/rl78/rl78.h index 00d2b83b9f5..2dfa1da7d46 100644 --- a/gcc/config/rl78/rl78.h +++ b/gcc/config/rl78/rl78.h @@ -32,6 +32,8 @@ builtin_define ("__RL78_MUL_RL78__"); \ if (RL78_MUL_G13) \ builtin_define ("__RL78_MUL_G13__"); \ + if (TARGET_G10) \ + builtin_define ("__RL78_G10__"); \ } \ while (0) @@ -44,6 +46,7 @@ #undef ASM_SPEC #define ASM_SPEC "\ %{mrelax:-relax} \ +%{mg10} \ " #undef LINK_SPEC @@ -262,7 +265,7 @@ enum reg_class { 0x00000300, 0x00000000 }, /* R8 - HImode */ \ { 0x00000c00, 0x00000000 }, /* R10 - HImode */ \ { 0xff000000, 0x00000000 }, /* INT - HImode */ \ - { 0x007fff00, 0x00000000 }, /* Virtual registers. */ \ + { 0xff7fff00, 0x00000000 }, /* Virtual registers. */ \ { 0xff7fffff, 0x00000002 }, /* General registers. */ \ { 0x04000000, 0x00000004 }, /* PSW. */ \ { 0xff7fffff, 0x0000001f } /* All registers. */ \ @@ -349,7 +352,7 @@ enum reg_class && reg_renumber[(REGNO)] <= (MAX))) #ifdef REG_OK_STRICT -#define REGNO_OK_FOR_BASE_P(regno) REGNO_IN_RANGE (regno, 16, 23) +#define REGNO_OK_FOR_BASE_P(regno) REGNO_IN_RANGE (regno, 16, 31) #else #define REGNO_OK_FOR_BASE_P(regno) 1 #endif diff --git a/gcc/config/rl78/rl78.md b/gcc/config/rl78/rl78.md index 314c37e5c6d..e1cbbb03eae 100644 --- a/gcc/config/rl78/rl78.md +++ b/gcc/config/rl78/rl78.md @@ -45,6 +45,7 @@ (UNS_RETB 3) (UNS_SET_RB 10) + (UNS_ES_ADDR 11) (UNS_TRAMPOLINE_INIT 20) (UNS_TRAMPOLINE_UNINIT 21) @@ -432,3 +433,11 @@ ; end of mulsi macro" [(set_attr "valloc" "macax")] ) + +(define_expand "es_addr" + [(unspec:SI [(reg:QI ES_REG) + (match_operand:HI 0 "" "") + ] UNS_ES_ADDR)] + "" + "" +) diff --git a/gcc/config/rl78/rl78.opt b/gcc/config/rl78/rl78.opt index 1538b897c57..ebcf903126d 100644 --- a/gcc/config/rl78/rl78.opt +++ b/gcc/config/rl78/rl78.opt @@ -23,7 +23,7 @@ HeaderInclude config/rl78/rl78-opts.h msim -Target +Target Report Use the simulator runtime. mmul= @@ -42,6 +42,14 @@ Enum(rl78_mul_types) String(rl78) Value(MUL_RL78) EnumValue Enum(rl78_mul_types) String(g13) Value(MUL_G13) +mallregs +Target Mask(ALLREGS) Report Optimization +Use all registers, reserving none for interrupt handlers. + mrelax -Target -Enable assembler and linker relaxation. +Target Report Optimization +Enable assembler and linker relaxation. Enabled by default at -Os. + +mg10 +Target Mask(G10) Report +Target the RL78/G10 series diff --git a/gcc/config/rl78/t-rl78 b/gcc/config/rl78/t-rl78 index ed7ee74448b..30705b3e5e5 100644 --- a/gcc/config/rl78/t-rl78 +++ b/gcc/config/rl78/t-rl78 @@ -20,3 +20,8 @@ rl78-c.o: $(srcdir)/config/rl78/rl78-c.c $(RTL_H) $(TREE_H) $(CONFIG_H) $(TM_H) $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< + +# Enable multilibs: + +MULTILIB_OPTIONS = mg10 +MULTILIB_DIRNAMES = g10 diff --git a/gcc/config/rs6000/driver-rs6000.c b/gcc/config/rs6000/driver-rs6000.c index 1a173d0b1cc..e608dce184c 100644 --- a/gcc/config/rs6000/driver-rs6000.c +++ b/gcc/config/rs6000/driver-rs6000.c @@ -167,7 +167,7 @@ elf_platform (void) if (fd != -1) { - static char buf[1024]; + char buf[1024]; ElfW(auxv_t) *av; ssize_t n; diff --git a/gcc/config/rs6000/paired.md b/gcc/config/rs6000/paired.md index 24397b23960..5cb8cf006cc 100644 --- a/gcc/config/rs6000/paired.md +++ b/gcc/config/rs6000/paired.md @@ -462,8 +462,8 @@ }") (define_expand "movmisalignv2sf" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (match_operand:V2SF 1 "gpc_reg_operand" "f"))] + [(set (match_operand:V2SF 0 "nonimmediate_operand" "") + (match_operand:V2SF 1 "any_operand" ""))] "TARGET_PAIRED_FLOAT" { paired_expand_vector_move (operands); diff --git a/gcc/config/sparc/t-rtems b/gcc/config/sparc/t-rtems index 63d021770b5..f1a3d845e32 100644 --- a/gcc/config/sparc/t-rtems +++ b/gcc/config/sparc/t-rtems @@ -17,6 +17,6 @@ # <http://www.gnu.org/licenses/>. # -MULTILIB_OPTIONS = msoft-float mcpu=v8 -MULTILIB_DIRNAMES = soft v8 +MULTILIB_OPTIONS = msoft-float mcpu=v8/mcpu=leon3 +MULTILIB_DIRNAMES = soft v8 leon3 MULTILIB_MATCHES = msoft-float=mno-fpu diff --git a/gcc/coverage.c b/gcc/coverage.c index d662e8d0946..9bc23c4bd9f 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -347,9 +347,9 @@ get_coverage_counts (unsigned counter, unsigned expected, if (!warned++ && dump_enabled_p ()) dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location, (flag_guess_branch_prob - ? "file %s not found, execution counts estimated" + ? "file %s not found, execution counts estimated\n" : "file %s not found, execution counts assumed to " - "be zero"), + "be zero\n"), da_file_name); return NULL; } @@ -379,20 +379,20 @@ get_coverage_counts (unsigned counter, unsigned expected, dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location, "use -Wno-error=coverage-mismatch to tolerate " "the mismatch but performance may drop if the " - "function is hot"); + "function is hot\n"); if (!seen_error () && !warned++) { dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location, - "coverage mismatch ignored"); - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location, - flag_guess_branch_prob - ? G_("execution counts estimated") - : G_("execution counts assumed to be zero")); + "coverage mismatch ignored\n"); + dump_printf (MSG_OPTIMIZED_LOCATIONS, + flag_guess_branch_prob + ? G_("execution counts estimated\n") + : G_("execution counts assumed to be zero\n")); if (!flag_guess_branch_prob) - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location, - "this can result in poorly optimized code"); + dump_printf (MSG_OPTIMIZED_LOCATIONS, + "this can result in poorly optimized code\n"); } } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5fbc78c1c2a..5ee1f9173b0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,26 @@ +2013-09-18 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/58457 + * class.c (instantiate_type): Loosen a bit the gcc_assert. + +2013-09-18 Marek Polacek <polacek@redhat.com> + + PR sanitize/58443 + * typeck.c (cp_build_binary_op): Properly honor -fsanitize options. + Remove unnecessary check. + +2013-09-18 Marek Polacek <polacek@redhat.com> + + PR sanitizer/58411 + * typeck.c (cp_build_binary_op): Don't sanitize function if it has the + no_sanitize_undefined attribute. + +2013-09-17 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/58435 + * pt.c (tsubst, [BOUND_TEMPLATE_TEMPLATE_PARM]): Take into account + the cp_type_quals (r) too. + 2013-09-16 Adam Butcher <adam@jessamine.co.uk> * cp-tree.h (type_uses_auto_or_concept): Declare. @@ -11,7 +34,8 @@ (is_auto_or_concept): New function. (type_uses_auto_or_concept): New function. * parser.h (struct cp_parser): Add fully_implicit_function_template_p. - * parser.c (cp_parser_new): Initialize fully_implicit_function_template_p. + * parser.c (cp_parser_new): Initialize + fully_implicit_function_template_p. (cp_parser_new): Initialize fully_implicit_function_template_p. (cp_parser_lambda_expression): Copy and restore value of fully_implicit_function_template_p as per other parser fields. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 3d34b92cfb1..9e0229fcba3 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -7627,7 +7627,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags) dependent on overload resolution. */ gcc_assert (TREE_CODE (rhs) == ADDR_EXPR || TREE_CODE (rhs) == COMPONENT_REF - || really_overloaded_fn (rhs) + || is_overloaded_fn (rhs) || (flag_ms_extensions && TREE_CODE (rhs) == FUNCTION_DECL)); /* This should really only be used when attempting to distinguish diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c2e251aaf85..e0b71108fcf 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11540,7 +11540,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /*entering_scope=*/0, complain); return cp_build_qualified_type_real - (r, cp_type_quals (t), complain); + (r, cp_type_quals (t) | cp_type_quals (r), complain); } else /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 6c48f242dd7..bcb87825a1e 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4884,9 +4884,11 @@ cp_build_binary_op (location_t location, if (build_type == NULL_TREE) build_type = result_type; - if ((flag_sanitize & SANITIZE_UNDEFINED) + if ((flag_sanitize & (SANITIZE_SHIFT | SANITIZE_DIVIDE)) && !processing_template_decl && current_function_decl != 0 + && !lookup_attribute ("no_sanitize_undefined", + DECL_ATTRIBUTES (current_function_decl)) && (doing_div_or_mod || doing_shift)) { /* OP0 and/or OP1 might have side-effects. */ @@ -4896,7 +4898,7 @@ cp_build_binary_op (location_t location, tf_none)); op1 = maybe_constant_value (fold_non_dependent_expr_sfinae (op1, tf_none)); - if (doing_div_or_mod) + if (doing_div_or_mod && (flag_sanitize & SANITIZE_DIVIDE)) { /* For diagnostics we want to use the promoted types without shorten_binary_op. So convert the arguments to the @@ -4910,7 +4912,7 @@ cp_build_binary_op (location_t location, } instrument_expr = ubsan_instrument_division (location, cop0, cop1); } - else if (doing_shift) + else if (doing_shift && (flag_sanitize & SANITIZE_SHIFT)) instrument_expr = ubsan_instrument_shift (location, code, op0, op1); } @@ -4924,7 +4926,7 @@ cp_build_binary_op (location_t location, && !TREE_OVERFLOW_P (op1)) overflow_warning (location, result); - if ((flag_sanitize & SANITIZE_UNDEFINED) && instrument_expr != NULL) + if (instrument_expr != NULL) result = fold_build2 (COMPOUND_EXPR, TREE_TYPE (result), instrument_expr, result); diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index cb48220c071..edf0e2851bc 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -30,7 +30,7 @@ extensions, accepted by GCC in C90 mode and in C++. * Constructing Calls:: Dispatching a call to another function. * Typeof:: @code{typeof}: referring to the type of an expression. * Conditionals:: Omitting the middle operand of a @samp{?:} expression. -* __int128:: 128-bit integers---@code{__int128}. +* __int128:: 128-bit integers---@code{__int128}. * Long Long:: Double-word integers---@code{long long int}. * Complex:: Data types for complex numbers. * Floating Types:: Additional Floating Types. @@ -2136,6 +2136,7 @@ attributes are currently defined for functions on all targets: @code{warn_unused_result}, @code{nonnull}, @code{gnu_inline}, @code{externally_visible}, @code{hot}, @code{cold}, @code{artificial}, @code{no_sanitize_address}, @code{no_address_safety_analysis}, +@code{no_sanitize_undefined}, @code{error} and @code{warning}. Several other attributes are defined for functions on particular target systems. Other attributes, including @code{section} are @@ -2813,7 +2814,7 @@ least version 2.20.1), and GNU C library (at least version 2.11.1). @item interrupt @cindex interrupt handler functions Use this attribute on the ARM, AVR, CR16, Epiphany, M32C, M32R/D, m68k, MeP, MIPS, -RL78, RX and Xstormy16 ports to indicate that the specified function is an +MSP430, RL78, RX and Xstormy16 ports to indicate that the specified function is an interrupt handler. The compiler generates function entry and exit sequences suitable for use in an interrupt handler when this attribute is present. With Epiphany targets it may also generate a special section with @@ -2844,6 +2845,35 @@ Permissible values for this parameter are: @code{IRQ}, @code{FIQ}, On ARMv7-M the interrupt type is ignored, and the attribute means the function may be called with a word-aligned stack pointer. +Note, for the MSP430 you can provide an argument to the interrupt +attribute which specifies a name or number. If the argument is a +number it indicates the slot in the interrupt vector table (0 - 31) to +which this handler should be assigned. If the argument is a name it +is treated as a symbolic name for the vector slot. These names should +match up with appropriate entries in the linker script. By default +the names @code{watchdog} for vector 26, @code{nmi} for vector 30 and +@code{reset} for vector 31 are recognised. + +You can also use the following function attributes to modify how +normal functions interact with interrupt functions: + +@table @code +@item critical +@cindex @code{critical} attribute +Critical functions disable interrupts upon entry and restore the +previous interrupt state upon exit. Critical functions cannot also +have the @code{naked} or @code{reentrant} attributes. They can have +the @code{interrupt} attribute. + +@item reentrant +@cindex @code{reentrant} attribute +Reentrant functions disable interrupts upon entry and enable them +upon exit. Reentrant functions cannot also have the @code{naked} +or @code{critical} attributes. They can have the @code{interrupt} +attribute. + +@end table + On Epiphany targets one or more optional parameters can be added like this: @smallexample @@ -3143,7 +3173,7 @@ and newer. @item naked @cindex function without a prologue/epilogue code -Use this attribute on the ARM, AVR, MCORE, RL78, RX and SPU ports to indicate that +Use this attribute on the ARM, AVR, MCORE, MSP430, RL78, RX and SPU ports to indicate that the specified function does not need prologue/epilogue sequences generated by the compiler. It is up to the programmer to provide these sequences. The only statements that can be safely included in naked functions are @@ -3471,6 +3501,12 @@ The @code{no_address_safety_analysis} is a deprecated alias of the @code{no_sanitize_address} attribute, new code should use @code{no_sanitize_address}. +@item no_sanitize_undefined +@cindex @code{no_sanitize_undefined} function attribute +The @code{no_sanitize_undefined} attribute on functions is used +to inform the compiler that it should not check for undefined behavior +in the function when compiling with the @option{-fsanitize=undefined} option. + @item regparm (@var{number}) @cindex @code{regparm} attribute @cindex functions that are passed arguments in registers on the 386 @@ -4855,8 +4891,9 @@ to be possibly unused. GCC does not produce a warning for this variable. @item used -This attribute, attached to a variable, means that the variable must be -emitted even if it appears that the variable is not referenced. +This attribute, attached to a variable with the static storage, means that +the variable must be emitted even if it appears that the variable is not +referenced. When applied to a static data member of a C++ class template, the attribute also means that the member is instantiated if the @@ -8844,6 +8881,7 @@ instructions, but allow the compiler to schedule those calls. * MIPS Paired-Single Support:: * MIPS Loongson Built-in Functions:: * Other MIPS Built-in Functions:: +* MSP430 Built-in Functions:: * picoChip Built-in Functions:: * PowerPC Built-in Functions:: * PowerPC AltiVec/VSX Built-in Functions:: @@ -11853,6 +11891,26 @@ GCC defines the preprocessor macro @code{___GCC_HAVE_BUILTIN_MIPS_CACHE} when this function is available. @end table +@node MSP430 Built-in Functions +@subsection MSP430 Built-in Functions + +GCC provides a couple of special builtin functions to aid in the +writing of interrupt handlers in C. + +@table @code +@item __bic_SR_register_on_exit (int @var{mask}) +This clears the indicated bits in the saved copy of the status register +currently residing on the stack. This only works inside interrupt +handlers and the changes to the status register will only take affect +once the handler returns. + +@item __bis_SR_register_on_exit (int @var{mask}) +This sets the indicated bits in the saved copy of the status register +currently residing on the stack. This only works inside interrupt +handlers and the changes to the status register will only take affect +once the handler returns. +@end table + @node picoChip Built-in Functions @subsection picoChip Built-in Functions diff --git a/gcc/doc/implement-cxx.texi b/gcc/doc/implement-cxx.texi index e9236cab6f4..43a8a597ab6 100644 --- a/gcc/doc/implement-cxx.texi +++ b/gcc/doc/implement-cxx.texi @@ -9,8 +9,8 @@ A conforming implementation of ISO C++ is required to document its choice of behavior in each of the areas that are designated ``implementation defined''. The following lists all such areas, -along with the section numbers from the ISO/IEC 14822:1998 and ISO/IEC -14822:2003 standards. Some areas are only implementation-defined in +along with the section numbers from the ISO/IEC 14882:1998 and ISO/IEC +14882:2003 standards. Some areas are only implementation-defined in one version of the standard. Some choices depend on the externally determined ABI for the platform diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 2ef28254680..497f237f08a 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -419,10 +419,11 @@ Objective-C and Objective-C++ Dialects}. -ftree-loop-if-convert-stores -ftree-loop-im @gol -ftree-phiprop -ftree-loop-distribution -ftree-loop-distribute-patterns @gol -ftree-loop-ivcanon -ftree-loop-linear -ftree-loop-optimize @gol +-ftree-loop-vectorize @gol -ftree-parallelize-loops=@var{n} -ftree-pre -ftree-partial-pre -ftree-pta @gol -ftree-reassoc -ftree-sink -ftree-slsr -ftree-sra @gol --ftree-switch-conversion -ftree-tail-merge @gol --ftree-ter -ftree-vect-loop-version -ftree-vectorize -ftree-vrp @gol +-ftree-switch-conversion -ftree-tail-merge -ftree-ter @gol +-ftree-vect-loop-version -ftree-vectorize -ftree-vrp @gol -funit-at-a-time -funroll-all-loops -funroll-loops @gol -funsafe-loop-optimizations -funsafe-math-optimizations -funswitch-loops @gol -fvariable-expansion-in-unroller -fvect-cost-model -fvpt -fweb @gol @@ -6756,8 +6757,8 @@ invoking @option{-O2} on programs that use computed gotos. Optimize yet more. @option{-O3} turns on all optimizations specified by @option{-O2} and also turns on the @option{-finline-functions}, @option{-funswitch-loops}, @option{-fpredictive-commoning}, -@option{-fgcse-after-reload}, @option{-ftree-vectorize}, -@option{-fvect-cost-model}, +@option{-fgcse-after-reload}, @option{-ftree-loop-vectorize}, +@option{-ftree-slp-vectorize}, @option{-fvect-cost-model}, @option{-ftree-partial-pre} and @option{-fipa-cp-clone} options. @item -O0 @@ -8016,8 +8017,13 @@ higher. @item -ftree-vectorize @opindex ftree-vectorize +Perform vectorization on trees. This flag enables @option{-ftree-loop-vectorize} +and @option{-ftree-slp-vectorize} if not explicitly specified. + +@item -ftree-loop-vectorize +@opindex ftree-loop-vectorize Perform loop vectorization on trees. This flag is enabled by default at -@option{-O3}. +@option{-O3} and when @option{-ftree-vectorize} is enabled. @item -ftree-slp-vectorize @opindex ftree-slp-vectorize diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index a7ab95ad9e2..8d220f31b51 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -5896,7 +5896,6 @@ interested in most macros in this section. @menu * CC0 Condition Codes:: Old style representation of condition codes. * MODE_CC Condition Codes:: Modern representation of condition codes. -* Cond Exec Macros:: Macros to control conditional execution. @end menu @node CC0 Condition Codes @@ -6106,15 +6105,6 @@ same. If they are, it returns that mode. If they are different, it returns @code{VOIDmode}. @end deftypefn -@node Cond Exec Macros -@subsection Macros to control conditional execution -@findex conditional execution -@findex predication - -There is one macro that may need to be defined for targets -supporting conditional execution, independent of how they -represent conditional branches. - @node Costs @section Describing Relative Costs of Operations @cindex costs of instructions diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index fdc392556f3..863e843af3d 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -4496,7 +4496,6 @@ interested in most macros in this section. @menu * CC0 Condition Codes:: Old style representation of condition codes. * MODE_CC Condition Codes:: Modern representation of condition codes. -* Cond Exec Macros:: Macros to control conditional execution. @end menu @node CC0 Condition Codes @@ -4662,15 +4661,6 @@ like: @hook TARGET_CC_MODES_COMPATIBLE -@node Cond Exec Macros -@subsection Macros to control conditional execution -@findex conditional execution -@findex predication - -There is one macro that may need to be defined for targets -supporting conditional execution, independent of how they -represent conditional branches. - @node Costs @section Describing Relative Costs of Operations @cindex costs of instructions diff --git a/gcc/domwalk.c b/gcc/domwalk.c index 8c1ddc69490..bffa4aa4851 100644 --- a/gcc/domwalk.c +++ b/gcc/domwalk.c @@ -144,23 +144,17 @@ cmp_bb_postorder (const void *a, const void *b) } /* Recursively walk the dominator tree. - - WALK_DATA contains a set of callbacks to perform pass-specific - actions during the dominator walk as well as a stack of block local - data maintained during the dominator walk. - BB is the basic block we are currently visiting. */ void -walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb) +dom_walker::walk (basic_block bb) { - void *bd = NULL; basic_block dest; basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks * 2); int sp = 0; int *postorder, postorder_num; - if (walk_data->dom_direction == CDI_DOMINATORS) + if (dom_direction_ == CDI_DOMINATORS) { postorder = XNEWVEC (int, n_basic_blocks); postorder_num = inverted_post_order_compute (postorder); @@ -177,37 +171,9 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb) || bb == ENTRY_BLOCK_PTR || bb == EXIT_BLOCK_PTR) { - /* Callback to initialize the local data structure. */ - if (walk_data->initialize_block_local_data) - { - bool recycled; - - /* First get some local data, reusing any local data - pointer we may have saved. */ - if (walk_data->free_block_data.length () > 0) - { - bd = walk_data->free_block_data.pop (); - recycled = 1; - } - else - { - bd = xcalloc (1, walk_data->block_local_data_size); - recycled = 0; - } - - /* Push the local data into the local data stack. */ - walk_data->block_data_stack.safe_push (bd); - - /* Call the initializer. */ - walk_data->initialize_block_local_data (walk_data, bb, - recycled); - - } - - /* Callback for operations to execute before we have walked the - dominator children, but before we walk statements. */ - if (walk_data->before_dom_children) - (*walk_data->before_dom_children) (walk_data, bb); + /* Callback for subclasses to do custom things before we have walked + the dominator children, but before we walk statements. */ + before_dom_children (bb); /* Mark the current BB to be popped out of the recursion stack once children are processed. */ @@ -215,10 +181,10 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb) worklist[sp++] = NULL; int saved_sp = sp; - for (dest = first_dom_son (walk_data->dom_direction, bb); - dest; dest = next_dom_son (walk_data->dom_direction, dest)) + for (dest = first_dom_son (dom_direction_, bb); + dest; dest = next_dom_son (dom_direction_, dest)) worklist[sp++] = dest; - if (walk_data->dom_direction == CDI_DOMINATORS) + if (dom_direction_ == CDI_DOMINATORS) switch (sp - saved_sp) { case 0: @@ -235,48 +201,19 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb) --sp; bb = worklist[--sp]; - /* Callback for operations to execute after we have walked the - dominator children, but before we walk statements. */ - if (walk_data->after_dom_children) - (*walk_data->after_dom_children) (walk_data, bb); - - if (walk_data->initialize_block_local_data) - { - /* And finally pop the record off the block local data stack. */ - bd = walk_data->block_data_stack.pop (); - /* And save the block data so that we can re-use it. */ - walk_data->free_block_data.safe_push (bd); - } + /* Callback allowing subclasses to do custom things after we have + walked dominator children, but before we walk statements. */ + after_dom_children (bb); } if (sp) bb = worklist[--sp]; else break; } - if (walk_data->dom_direction == CDI_DOMINATORS) + if (dom_direction_ == CDI_DOMINATORS) { free (bb_postorder); bb_postorder = NULL; } free (worklist); } - -void -init_walk_dominator_tree (struct dom_walk_data *walk_data) -{ - walk_data->free_block_data.create (0); - walk_data->block_data_stack.create (0); -} - -void -fini_walk_dominator_tree (struct dom_walk_data *walk_data) -{ - if (walk_data->initialize_block_local_data) - { - while (walk_data->free_block_data.length () > 0) - free (walk_data->free_block_data.pop ()); - } - - walk_data->free_block_data.release (); - walk_data->block_data_stack.release (); -} diff --git a/gcc/domwalk.h b/gcc/domwalk.h index 54b7f3c86d9..b33d70eda23 100644 --- a/gcc/domwalk.h +++ b/gcc/domwalk.h @@ -18,57 +18,35 @@ 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/>. */ -typedef void *void_p; - -/* This is the main data structure for the dominator walker. It provides - the callback hooks as well as a convenient place to hang block local - data and pass-global data. */ - -struct dom_walk_data +#ifndef GCC_DOM_WALK_H +#define GCC_DOM_WALK_H + +/** + * This is the main class for the dominator walker. It is expected that + * consumers will have a custom class inheriting from it, which will over ride + * at least one of before_dom_children and after_dom_children to implement the + * custom behavior. + */ +class dom_walker { - /* This is the direction of the dominator tree we want to walk. i.e., - if it is set to CDI_DOMINATORS, then we walk the dominator tree, - if it is set to CDI_POST_DOMINATORS, then we walk the post - dominator tree. */ - ENUM_BITFIELD (cdi_direction) dom_direction : 2; - - /* Function to initialize block local data. +public: + dom_walker (cdi_direction direction) : dom_direction_ (direction) {} - Note that the dominator walker infrastructure may provide a new - fresh, and zero'd block local data structure, or it may re-use an - existing block local data structure. - - If the block local structure has items such as virtual arrays, then - that allows your optimizer to re-use those arrays rather than - creating new ones. */ - void (*initialize_block_local_data) (struct dom_walk_data *, - basic_block, bool); + /* Walk the dominator tree. */ + void walk (basic_block); /* Function to call before the recursive walk of the dominator children. */ - void (*before_dom_children) (struct dom_walk_data *, basic_block); + virtual void before_dom_children (basic_block) {} /* Function to call after the recursive walk of the dominator children. */ - void (*after_dom_children) (struct dom_walk_data *, basic_block); - - /* Global data for a walk through the dominator tree. */ - void *global_data; + virtual void after_dom_children (basic_block) {} - /* Stack of any data we need to keep on a per-block basis. - - If you have no local data, then BLOCK_DATA_STACK will be NULL. */ - vec<void_p> block_data_stack; - - /* Size of the block local data. If this is zero, then it is assumed - you have no local data and thus no BLOCK_DATA_STACK as well. */ - size_t block_local_data_size; - - /* From here below are private data. Please do not use this - information/data outside domwalk.c. */ - - /* Stack of available block local structures. */ - vec<void_p> free_block_data; +private: + /* This is the direction of the dominator tree we want to walk. i.e., + if it is set to CDI_DOMINATORS, then we walk the dominator tree, + if it is set to CDI_POST_DOMINATORS, then we walk the post + dominator tree. */ + const ENUM_BITFIELD (cdi_direction) dom_direction_ : 2; }; -void walk_dominator_tree (struct dom_walk_data *, basic_block); -void init_walk_dominator_tree (struct dom_walk_data *); -void fini_walk_dominator_tree (struct dom_walk_data *); +#endif diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c index 6ac15ddf6f3..dc87ab35e8c 100644 --- a/gcc/dumpfile.c +++ b/gcc/dumpfile.c @@ -262,10 +262,10 @@ dump_loc (int dump_kind, FILE *dfile, source_location loc) if (dump_kind) { if (LOCATION_LOCUS (loc) > BUILTINS_LOCATION) - fprintf (dfile, "\n%s:%d:%d: note: ", LOCATION_FILE (loc), + fprintf (dfile, "%s:%d:%d: note: ", LOCATION_FILE (loc), LOCATION_LINE (loc), LOCATION_COLUMN (loc)); else if (current_function_decl) - fprintf (dfile, "\n%s:%d:%d: note: ", + fprintf (dfile, "%s:%d:%d: note: ", DECL_SOURCE_FILE (current_function_decl), DECL_SOURCE_LINE (current_function_decl), DECL_SOURCE_COLUMN (current_function_decl)); diff --git a/gcc/fold-const.c b/gcc/fold-const.c index c70437b5ea1..d23c1737ed3 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -9942,6 +9942,24 @@ exact_inverse (tree type, tree cst) } } +/* Mask out the tz least significant bits of X of type TYPE where + tz is the number of trailing zeroes in Y. */ +static double_int +mask_with_tz (tree type, double_int x, double_int y) +{ + int tz = y.trailing_zeros (); + + if (tz > 0) + { + double_int mask; + + mask = ~double_int::mask (tz); + mask = mask.ext (TYPE_PRECISION (type), TYPE_UNSIGNED (type)); + return mask & x; + } + return x; +} + /* Fold a binary expression of code CODE and type TYPE with operands OP0 and OP1. LOC is the location of the resulting expression. Return the folded expression if folding is successful. Otherwise, @@ -11266,6 +11284,8 @@ fold_binary_loc (location_t loc, { double_int c1, c2, c3, msk; int width = TYPE_PRECISION (type), w; + bool try_simplify = true; + c1 = tree_to_double_int (TREE_OPERAND (arg0, 1)); c2 = tree_to_double_int (arg1); @@ -11300,7 +11320,21 @@ fold_binary_loc (location_t loc, break; } } - if (c3 != c1) + + /* If X is a tree of the form (Y * K1) & K2, this might conflict + with that optimization from the BIT_AND_EXPR optimizations. + This could end up in an infinite recursion. */ + if (TREE_CODE (TREE_OPERAND (arg0, 0)) == MULT_EXPR + && TREE_CODE (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1)) + == INTEGER_CST) + { + tree t = TREE_OPERAND (TREE_OPERAND (arg0, 0), 1); + double_int masked = mask_with_tz (type, c3, tree_to_double_int (t)); + + try_simplify = (masked != c1); + } + + if (try_simplify && c3 != c1) return fold_build2_loc (loc, BIT_IOR_EXPR, type, fold_build2_loc (loc, BIT_AND_EXPR, type, TREE_OPERAND (arg0, 0), @@ -11690,22 +11724,16 @@ fold_binary_loc (location_t loc, && TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) { - int arg1tz - = tree_to_double_int (TREE_OPERAND (arg0, 1)).trailing_zeros (); - if (arg1tz > 0) - { - double_int arg1mask, masked; - arg1mask = ~double_int::mask (arg1tz); - arg1mask = arg1mask.ext (TYPE_PRECISION (type), - TYPE_UNSIGNED (type)); - masked = arg1mask & tree_to_double_int (arg1); - if (masked.is_zero ()) - return omit_two_operands_loc (loc, type, build_zero_cst (type), - arg0, arg1); - else if (masked != tree_to_double_int (arg1)) - return fold_build2_loc (loc, code, type, op0, - double_int_to_tree (type, masked)); - } + double_int masked + = mask_with_tz (type, tree_to_double_int (arg1), + tree_to_double_int (TREE_OPERAND (arg0, 1))); + + if (masked.is_zero ()) + return omit_two_operands_loc (loc, type, build_zero_cst (type), + arg0, arg1); + else if (masked != tree_to_double_int (arg1)) + return fold_build2_loc (loc, code, type, op0, + double_int_to_tree (type, masked)); } /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M, diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 0f73dfe5f90..0e4d688f975 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,28 @@ +2013-09-20 Janus Weil <janus@gcc.gnu.org> + + PR fortran/58099 + * expr.c (gfc_check_pointer_assign): Remove second call to + 'gfc_compare_interfaces' with swapped arguments. + * interface.c (gfc_compare_interfaces): Symmetrize the call to + 'check_result_characteristics' by calling it with swapped arguments. + +2013-09-18 Tobias Burnus <burnus@net-b.de> + + * expr.c (gfc_check_assign_symbol): Free lvalue.ref. + +2013-09-18 Tobias Burnus <burnus@net-b.de> + + PR fortran/43366 + * primary.c (gfc_variable_attr): Also handle codimension. + * resolve.c (resolve_ordinary_assign): Add invalid-diagnostic for + polymorphic assignment. + +2013-09-16 Tobias Burnus <burnus@net-b.de> + + PR fortran/58356 + * class.c (generate_finalization_wrapper): Init proc_tree if + not yet resolved. + 2013-09-16 Tobias Burnus <burnus@net-b.de> PR fortran/57697 diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c index 629b052fb32..7117e836156 100644 --- a/gcc/fortran/class.c +++ b/gcc/fortran/class.c @@ -1881,6 +1881,8 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns, for (fini = derived->f2k_derived->finalizers; fini; fini = fini->next) { + if (!fini->proc_tree) + fini->proc_tree = gfc_find_sym_in_symtree (fini->proc_sym); if (fini->proc_tree->n.sym->attr.elemental) { fini_elem = fini; diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index 61f0f8275cc..b2af32816e5 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -3581,14 +3581,6 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue) return false; } - if (!gfc_compare_interfaces (s2, s1, name, 0, 1, - err, sizeof(err), NULL, NULL)) - { - gfc_error ("Interface mismatch in procedure pointer assignment " - "at %L: %s", &rvalue->where, err); - return false; - } - return true; } @@ -3824,6 +3816,7 @@ gfc_check_assign_symbol (gfc_symbol *sym, gfc_component *comp, gfc_expr *rvalue) r = gfc_check_assign (&lvalue, rvalue, 1); free (lvalue.symtree); + free (lvalue.ref); if (!r) return r; diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index aa88b3c3fa6..b8786440fbe 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -1416,7 +1416,8 @@ gfc_compare_interfaces (gfc_symbol *s1, gfc_symbol *s2, const char *name2, if (s1->attr.function && s2->attr.function) { /* If both are functions, check result characteristics. */ - if (!check_result_characteristics (s1, s2, errmsg, err_len)) + if (!check_result_characteristics (s1, s2, errmsg, err_len) + || !check_result_characteristics (s2, s1, errmsg, err_len)) return 0; } diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c index 1276abb3aa7..80d45eaea12 100644 --- a/gcc/fortran/primary.c +++ b/gcc/fortran/primary.c @@ -2134,7 +2134,7 @@ check_substring: symbol_attribute gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts) { - int dimension, pointer, allocatable, target; + int dimension, codimension, pointer, allocatable, target; symbol_attribute attr; gfc_ref *ref; gfc_symbol *sym; @@ -2149,12 +2149,14 @@ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts) if (sym->ts.type == BT_CLASS && sym->attr.class_ok) { dimension = CLASS_DATA (sym)->attr.dimension; + codimension = CLASS_DATA (sym)->attr.codimension; pointer = CLASS_DATA (sym)->attr.class_pointer; allocatable = CLASS_DATA (sym)->attr.allocatable; } else { dimension = attr.dimension; + codimension = attr.codimension; pointer = attr.pointer; allocatable = attr.allocatable; } @@ -2209,11 +2211,13 @@ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts) if (comp->ts.type == BT_CLASS) { + codimension = CLASS_DATA (comp)->attr.codimension; pointer = CLASS_DATA (comp)->attr.class_pointer; allocatable = CLASS_DATA (comp)->attr.allocatable; } else { + codimension = comp->attr.codimension; pointer = comp->attr.pointer; allocatable = comp->attr.allocatable; } @@ -2228,6 +2232,7 @@ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts) } attr.dimension = dimension; + attr.codimension = codimension; attr.pointer = pointer; attr.allocatable = allocatable; attr.target = target; diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index fbd9a6a2472..d33fe49b661 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -9014,6 +9014,7 @@ resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns) int rlen = 0; int n; gfc_ref *ref; + symbol_attribute attr; if (gfc_extend_assign (code, ns)) { @@ -9178,14 +9179,35 @@ resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns) gfc_current_ns->proc_name->attr.implicit_pure = 0; } - /* F03:7.4.1.2. */ - /* FIXME: Valid in Fortran 2008, unless the LHS is both polymorphic - and coindexed; cf. F2008, 7.2.1.2 and PR 43366. */ - if (lhs->ts.type == BT_CLASS) + /* F2008, 7.2.1.2. */ + attr = gfc_expr_attr (lhs); + if (lhs->ts.type == BT_CLASS && attr.allocatable) + { + if (attr.codimension) + { + gfc_error ("Assignment to polymorphic coarray at %L is not " + "permitted", &lhs->where); + return false; + } + if (!gfc_notify_std (GFC_STD_F2008, "Assignment to an allocatable " + "polymorphic variable at %L", &lhs->where)) + return false; + if (!gfc_option.flag_realloc_lhs) + { + gfc_error ("Assignment to an allocatable polymorphic variable at %L " + "requires -frealloc-lhs", &lhs->where); + return false; + } + /* See PR 43366. */ + gfc_error ("Assignment to an allocatable polymorphic variable at %L " + "is not yet supported", &lhs->where); + return false; + } + else if (lhs->ts.type == BT_CLASS) { - gfc_error ("Variable must not be polymorphic in intrinsic assignment at " - "%L - check that there is a matching specific subroutine " - "for '=' operator", &lhs->where); + gfc_error ("Nonallocatable variable must not be polymorphic in intrinsic " + "assignment at %L - check that there is a matching specific " + "subroutine for '=' operator", &lhs->where); return false; } diff --git a/gcc/fwprop.c b/gcc/fwprop.c index 8fe02ac2a43..137011d3324 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -205,10 +205,17 @@ process_uses (df_ref *use_rec, int top_flag) } } +class single_def_use_dom_walker : public dom_walker +{ +public: + single_def_use_dom_walker (cdi_direction direction) + : dom_walker (direction) {} + virtual void before_dom_children (basic_block); + virtual void after_dom_children (basic_block); +}; -static void -single_def_use_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, - basic_block bb) +void +single_def_use_dom_walker::before_dom_children (basic_block bb) { int bb_index = bb->index; struct df_md_bb_info *md_bb_info = df_md_get_bb_info (bb_index); @@ -245,9 +252,8 @@ single_def_use_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, /* Pop the definitions created in this basic block when leaving its dominated parts. */ -static void -single_def_use_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, - basic_block bb ATTRIBUTE_UNUSED) +void +single_def_use_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED) { df_ref saved_def; while ((saved_def = reg_defs_stack.pop ()) != NULL) @@ -269,8 +275,6 @@ single_def_use_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, static void build_single_def_use_links (void) { - struct dom_walk_data walk_data; - /* We use the multiple definitions problem to compute our restricted use-def chains. */ df_set_flags (DF_EQ_NOTES); @@ -291,14 +295,8 @@ build_single_def_use_links (void) /* Walk the dominator tree looking for single reaching definitions dominating the uses. This is similar to how SSA form is built. */ - walk_data.dom_direction = CDI_DOMINATORS; - walk_data.initialize_block_local_data = NULL; - walk_data.before_dom_children = single_def_use_enter_block; - walk_data.after_dom_children = single_def_use_leave_block; - - init_walk_dominator_tree (&walk_data); - walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); - fini_walk_dominator_tree (&walk_data); + single_def_use_dom_walker (CDI_DOMINATORS) + .walk (cfun->cfg->x_entry_block_ptr); BITMAP_FREE (local_lr); BITMAP_FREE (local_md); diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 98c3a153f3f..51713e64655 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -60,6 +60,24 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl) struct cgraph_node *node; symtab_node snode; + if (DECL_ABSTRACT (decl)) + return false; + + /* We are concerned only about static/external vars and functions. */ + if ((!TREE_STATIC (decl) && !DECL_EXTERNAL (decl)) + || (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)) + return true; + + /* Static objects can be referred only if they was not optimized out yet. */ + if (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) + { + snode = symtab_get_node (decl); + if (!snode) + return false; + node = dyn_cast <cgraph_node> (snode); + return !node || !node->global.inlined_to; + } + /* We will later output the initializer, so we can refer to it. So we are concerned only when DECL comes from initializer of external var. */ @@ -69,10 +87,6 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl) || (flag_ltrans && symtab_get_node (from_decl)->symbol.in_other_partition)) return true; - /* We are concerned only about static/external vars and functions. */ - if ((!TREE_STATIC (decl) && !DECL_EXTERNAL (decl)) - || (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)) - return true; /* We are folding reference from external vtable. The vtable may reffer to a symbol keyed to other compilation unit. The other compilation unit may be in separate DSO and the symbol may be hidden. */ diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c index 7f1c9ecdbb8..8d48adde01d 100644 --- a/gcc/gimple-ssa-strength-reduction.c +++ b/gcc/gimple-ssa-strength-reduction.c @@ -750,6 +750,57 @@ slsr_process_phi (gimple phi, bool speed) add_cand_for_stmt (phi, c); } +/* Given PBASE which is a pointer to tree, look up the defining + statement for it and check whether the candidate is in the + form of: + + X = B + (1 * S), S is integer constant + X = B + (i * S), S is integer one + + If so, set PBASE to the candidate's base_expr and return double + int (i * S). + Otherwise, just return double int zero. */ + +static double_int +backtrace_base_for_ref (tree *pbase) +{ + tree base_in = *pbase; + slsr_cand_t base_cand; + + STRIP_NOPS (base_in); + if (TREE_CODE (base_in) != SSA_NAME) + return tree_to_double_int (integer_zero_node); + + base_cand = base_cand_from_table (base_in); + + while (base_cand && base_cand->kind != CAND_PHI) + { + if (base_cand->kind == CAND_ADD + && base_cand->index.is_one () + && TREE_CODE (base_cand->stride) == INTEGER_CST) + { + /* X = B + (1 * S), S is integer constant. */ + *pbase = base_cand->base_expr; + return tree_to_double_int (base_cand->stride); + } + else if (base_cand->kind == CAND_ADD + && TREE_CODE (base_cand->stride) == INTEGER_CST + && integer_onep (base_cand->stride)) + { + /* X = B + (i * S), S is integer one. */ + *pbase = base_cand->base_expr; + return base_cand->index; + } + + if (base_cand->next_interp) + base_cand = lookup_cand (base_cand->next_interp); + else + base_cand = NULL; + } + + return tree_to_double_int (integer_zero_node); +} + /* Look for the following pattern: *PBASE: MEM_REF (T1, C1) @@ -767,7 +818,14 @@ slsr_process_phi (gimple phi, bool speed) *PBASE: T1 *POFFSET: MULT_EXPR (T2, C3) - *PINDEX: C1 + (C2 * C3) + C4 */ + *PINDEX: C1 + (C2 * C3) + C4 + + When T2 is recorded by a CAND_ADD in the form of (T2' + C5), it + will be further restructured to: + + *PBASE: T1 + *POFFSET: MULT_EXPR (T2', C3) + *PINDEX: C1 + (C2 * C3) + C4 + (C5 * C3) */ static bool restructure_reference (tree *pbase, tree *poffset, double_int *pindex, @@ -777,7 +835,7 @@ restructure_reference (tree *pbase, tree *poffset, double_int *pindex, double_int index = *pindex; double_int bpu = double_int::from_uhwi (BITS_PER_UNIT); tree mult_op0, mult_op1, t1, t2, type; - double_int c1, c2, c3, c4; + double_int c1, c2, c3, c4, c5; if (!base || !offset @@ -823,11 +881,12 @@ restructure_reference (tree *pbase, tree *poffset, double_int *pindex, } c4 = index.udiv (bpu, FLOOR_DIV_EXPR); + c5 = backtrace_base_for_ref (&t2); *pbase = t1; - *poffset = fold_build2 (MULT_EXPR, sizetype, t2, + *poffset = fold_build2 (MULT_EXPR, sizetype, fold_convert (sizetype, t2), double_int_to_tree (sizetype, c3)); - *pindex = c1 + c2 * c3 + c4; + *pindex = c1 + c2 * c3 + c4 + c5 * c3; *ptype = type; return true; @@ -1512,11 +1571,18 @@ slsr_process_copy (gimple gs, tree rhs1, bool speed) add_cand_for_stmt (gs, c); } +class find_candidates_dom_walker : public dom_walker +{ +public: + find_candidates_dom_walker (cdi_direction direction) + : dom_walker (direction) {} + virtual void before_dom_children (basic_block); +}; + /* Find strength-reduction candidates in block BB. */ -static void -find_candidates_in_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, - basic_block bb) +void +find_candidates_dom_walker::before_dom_children (basic_block bb) { bool speed = optimize_bb_for_speed_p (bb); gimple_stmt_iterator gsi; @@ -3429,8 +3495,6 @@ analyze_candidates_and_replace (void) static unsigned execute_strength_reduction (void) { - struct dom_walk_data walk_data; - /* Create the obstack where candidates will reside. */ gcc_obstack_init (&cand_obstack); @@ -3450,18 +3514,10 @@ execute_strength_reduction (void) back edges, and this gives us dominator information as well. */ loop_optimizer_init (AVOID_CFG_MODIFICATIONS); - /* Set up callbacks for the generic dominator tree walker. */ - walk_data.dom_direction = CDI_DOMINATORS; - walk_data.initialize_block_local_data = NULL; - walk_data.before_dom_children = find_candidates_in_block; - walk_data.after_dom_children = NULL; - walk_data.global_data = NULL; - walk_data.block_local_data_size = 0; - init_walk_dominator_tree (&walk_data); - /* Walk the CFG in predominator order looking for strength reduction candidates. */ - walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); + find_candidates_dom_walker (CDI_DOMINATORS) + .walk (cfun->cfg->x_entry_block_ptr); if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -3472,8 +3528,6 @@ execute_strength_reduction (void) /* Analyze costs and make appropriate replacements. */ analyze_candidates_and_replace (); - /* Free resources. */ - fini_walk_dominator_tree (&walk_data); loop_optimizer_finalize (); base_cand_map.dispose (); obstack_free (&chain_obstack, NULL); diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 0b010334229..99edb4b8031 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -7752,8 +7752,6 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const return false; if (arg_type->is_abstract()) return false; - if (arg_type->named_type() != NULL) - arg_type->named_type()->convert(this->gogo_); unsigned int ret; if (this->code_ == BUILTIN_SIZEOF) diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc index 69797f93342..7813cc18822 100644 --- a/gcc/go/gofrontend/gogo-tree.cc +++ b/gcc/go/gofrontend/gogo-tree.cc @@ -1009,6 +1009,16 @@ Named_object::get_id(Gogo* gogo) else package_name = this->package_->package_name(); + // Note that this will be misleading if this is an unexported + // method generated for an embedded imported type. In that case + // the unexported method should have the package name of the + // package from which it is imported, but we are going to give + // it our package name. Fixing this would require knowing the + // package name, but we only know the package path. It might be + // better to use package paths here anyhow. This doesn't affect + // the assembler code, because we always set that name in + // Function::get_or_make_decl anyhow. FIXME. + decl_name = package_name + '.' + Gogo::unpack_hidden_name(this->name_); Function_type* fntype; @@ -1317,7 +1327,21 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no, tree id) || this->type_->is_method()) { TREE_PUBLIC(decl) = 1; - std::string asm_name = gogo->pkgpath_symbol(); + std::string pkgpath = gogo->pkgpath_symbol(); + if (this->type_->is_method() + && Gogo::is_hidden_name(no->name()) + && Gogo::hidden_name_pkgpath(no->name()) != gogo->pkgpath()) + { + // This is a method we created for an unexported + // method of an imported embedded type. We need to + // use the pkgpath of the imported package to avoid + // a possible name collision. See bug478 for a test + // case. + pkgpath = Gogo::hidden_name_pkgpath(no->name()); + pkgpath = Gogo::pkgpath_for_symbol(pkgpath); + } + + std::string asm_name = pkgpath; asm_name.append(1, '.'); asm_name.append(Gogo::unpack_hidden_name(no->name())); if (this->type_->is_method()) diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index be8ec5939f3..17cbb6b9b49 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -2367,7 +2367,7 @@ Shortcuts::convert_shortcut(Block* enclosing, Expression** pshortcut) Block* retblock = new Block(enclosing, loc); retblock->set_end_location(loc); - Temporary_statement* ts = Statement::make_temporary(Type::lookup_bool_type(), + Temporary_statement* ts = Statement::make_temporary(shortcut->type(), left, loc); retblock->add_statement(ts); diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 9ce329d5503..32f827dd316 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -2288,9 +2288,7 @@ Type::is_backend_type_size_known(Gogo* gogo) } case TYPE_NAMED: - // Begin converting this type to the backend representation. - // This will create a placeholder if necessary. - this->get_backend(gogo); + this->named_type()->convert(gogo); return this->named_type()->is_named_backend_type_size_known(); case TYPE_FORWARD: @@ -4229,6 +4227,11 @@ Struct_field::is_embedded_builtin(Gogo* gogo) const Struct_type::Identical_structs Struct_type::identical_structs; +// A hash table used to merge method sets for identical unnamed +// structs. + +Struct_type::Struct_method_tables Struct_type::struct_method_tables; + // Traversal. int @@ -4693,9 +4696,24 @@ Struct_type::interface_method_table(Gogo* gogo, const Interface_type* interface, bool is_pointer) { + std::pair<Struct_type*, Struct_type::Struct_method_table_pair*> + val(this, NULL); + std::pair<Struct_type::Struct_method_tables::iterator, bool> ins = + Struct_type::struct_method_tables.insert(val); + + Struct_method_table_pair* smtp; + if (!ins.second) + smtp = ins.first->second; + else + { + smtp = new Struct_method_table_pair(); + smtp->first = NULL; + smtp->second = NULL; + ins.first->second = smtp; + } + return Type::interface_method_table(gogo, this, interface, is_pointer, - &this->interface_method_tables_, - &this->pointer_interface_method_tables_); + &smtp->first, &smtp->second); } // Convert struct fields to the backend representation. This is not diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index d207fe5a375..d8a3080f586 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -2041,8 +2041,7 @@ class Struct_type : public Type public: Struct_type(Struct_field_list* fields, Location location) : Type(TYPE_STRUCT), - fields_(fields), location_(location), all_methods_(NULL), - interface_method_tables_(NULL), pointer_interface_method_tables_(NULL) + fields_(fields), location_(location), all_methods_(NULL) { } // Return the field NAME. This only looks at local fields, not at @@ -2200,6 +2199,16 @@ class Struct_type : public Type static Identical_structs identical_structs; + // Used to manage method tables for identical unnamed structs. + typedef std::pair<Interface_method_tables*, Interface_method_tables*> + Struct_method_table_pair; + + typedef Unordered_map_hash(Struct_type*, Struct_method_table_pair*, + Type_hash_identical, Type_identical) + Struct_method_tables; + + static Struct_method_tables struct_method_tables; + // Used to avoid infinite loops in field_reference_depth. struct Saw_named_type { @@ -2218,13 +2227,6 @@ class Struct_type : public Type Location location_; // If this struct is unnamed, a list of methods. Methods* all_methods_; - // A mapping from interfaces to the associated interface method - // tables for this type. Only used if this struct is unnamed. - Interface_method_tables* interface_method_tables_; - // A mapping from interfaces to the associated interface method - // tables for pointers to this type. Only used if this struct is - // unnamed. - Interface_method_tables* pointer_interface_method_tables_; }; // The type of an array. diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c index 1527603a99f..49856914782 100644 --- a/gcc/graphite-sese-to-poly.c +++ b/gcc/graphite-sese-to-poly.c @@ -1191,14 +1191,6 @@ add_conditions_to_constraints (scop_p scop) add_conditions_to_domain (pbb); } -/* Structure used to pass data to dom_walk. */ - -struct bsc -{ - vec<gimple> *conditions, *cases; - sese region; -}; - /* Returns a COND_EXPR statement when BB has a single predecessor, the edge between BB and its predecessor is not a loop exit edge, and the last statement of the single predecessor is a COND_EXPR. */ @@ -1224,20 +1216,43 @@ single_pred_cond_non_loop_exit (basic_block bb) return NULL; } +class sese_dom_walker : public dom_walker +{ +public: + sese_dom_walker (cdi_direction, sese); + ~sese_dom_walker (); + + virtual void before_dom_children (basic_block); + virtual void after_dom_children (basic_block); + +private: + vec<gimple> conditions_, cases_; + sese region_; +}; + +sese_dom_walker::sese_dom_walker (cdi_direction direction, sese region) + : dom_walker (direction), region_ (region) +{ + conditions_.create (3); + cases_.create (3); +} + +sese_dom_walker::~sese_dom_walker () +{ + conditions_.release (); + cases_.release (); +} + /* Call-back for dom_walk executed before visiting the dominated blocks. */ -static void -build_sese_conditions_before (struct dom_walk_data *dw_data, - basic_block bb) +void +sese_dom_walker::before_dom_children (basic_block bb) { - struct bsc *data = (struct bsc *) dw_data->global_data; - vec<gimple> *conditions = data->conditions; - vec<gimple> *cases = data->cases; gimple_bb_p gbb; gimple stmt; - if (!bb_in_sese_p (bb, data->region)) + if (!bb_in_sese_p (bb, region_)) return; stmt = single_pred_cond_non_loop_exit (bb); @@ -1246,75 +1261,39 @@ build_sese_conditions_before (struct dom_walk_data *dw_data, { edge e = single_pred_edge (bb); - conditions->safe_push (stmt); + conditions_.safe_push (stmt); if (e->flags & EDGE_TRUE_VALUE) - cases->safe_push (stmt); + cases_.safe_push (stmt); else - cases->safe_push (NULL); + cases_.safe_push (NULL); } gbb = gbb_from_bb (bb); if (gbb) { - GBB_CONDITIONS (gbb) = conditions->copy (); - GBB_CONDITION_CASES (gbb) = cases->copy (); + GBB_CONDITIONS (gbb) = conditions_.copy (); + GBB_CONDITION_CASES (gbb) = cases_.copy (); } } /* Call-back for dom_walk executed after visiting the dominated blocks. */ -static void -build_sese_conditions_after (struct dom_walk_data *dw_data, - basic_block bb) +void +sese_dom_walker::after_dom_children (basic_block bb) { - struct bsc *data = (struct bsc *) dw_data->global_data; - vec<gimple> *conditions = data->conditions; - vec<gimple> *cases = data->cases; - - if (!bb_in_sese_p (bb, data->region)) + if (!bb_in_sese_p (bb, region_)) return; if (single_pred_cond_non_loop_exit (bb)) { - conditions->pop (); - cases->pop (); + conditions_.pop (); + cases_.pop (); } } -/* Record all conditions in REGION. */ - -static void -build_sese_conditions (sese region) -{ - struct dom_walk_data walk_data; - vec<gimple> conditions; - conditions.create (3); - vec<gimple> cases; - cases.create (3); - struct bsc data; - - data.conditions = &conditions; - data.cases = &cases; - data.region = region; - - walk_data.dom_direction = CDI_DOMINATORS; - walk_data.initialize_block_local_data = NULL; - walk_data.before_dom_children = build_sese_conditions_before; - walk_data.after_dom_children = build_sese_conditions_after; - walk_data.global_data = &data; - walk_data.block_local_data_size = 0; - - init_walk_dominator_tree (&walk_data); - walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region)); - fini_walk_dominator_tree (&walk_data); - - conditions.release (); - cases.release (); -} - /* Add constraints on the possible values of parameter P from the type of P. */ @@ -3179,7 +3158,8 @@ build_poly_scop (scop_p scop) rewrite_commutative_reductions_out_of_ssa (scop); build_sese_loop_nests (region); - build_sese_conditions (region); + /* Record all conditions in REGION. */ + sese_dom_walker (CDI_DOMINATORS, region).walk (cfun->cfg->x_entry_block_ptr); find_scop_parameters (scop); max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS); diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index 1be19f89d05..85bc5b0652b 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -1098,7 +1098,13 @@ ipa_devirt (void) cgraph_node_name (likely_target), likely_target->symbol.order); if (!symtab_can_be_discarded ((symtab_node) likely_target)) - likely_target = cgraph (symtab_nonoverwritable_alias ((symtab_node)likely_target)); + { + cgraph_node *alias; + alias = cgraph (symtab_nonoverwritable_alias + ((symtab_node)likely_target)); + if (alias) + likely_target = alias; + } nconverted++; update = true; cgraph_turn_edge_to_speculative diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index eaf64d35853..ba6221e41fd 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -2664,7 +2664,11 @@ compute_inline_parameters (struct cgraph_node *node, bool early) info->stack_frame_offset = 0; /* Can this function be inlined at all? */ - info->inlinable = tree_inlinable_function_p (node->symbol.decl); + if (!optimize && !lookup_attribute ("always_inline", + DECL_ATTRIBUTES (node->symbol.decl))) + info->inlinable = false; + else + info->inlinable = tree_inlinable_function_p (node->symbol.decl); /* Type attributes can use parameter indices to describe them. */ if (TYPE_ATTRIBUTES (TREE_TYPE (node->symbol.decl))) @@ -3678,6 +3682,22 @@ inline_analyze_function (struct cgraph_node *node) if (optimize && !node->thunk.thunk_p) inline_indirect_intraprocedural_analysis (node); compute_inline_parameters (node, false); + if (!optimize) + { + struct cgraph_edge *e; + for (e = node->callees; e; e = e->next_callee) + { + if (e->inline_failed == CIF_FUNCTION_NOT_CONSIDERED) + e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED; + e->call_stmt_cannot_inline_p = true; + } + for (e = node->indirect_calls; e; e = e->next_callee) + { + if (e->inline_failed == CIF_FUNCTION_NOT_CONSIDERED) + e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED; + e->call_stmt_cannot_inline_p = true; + } + } pop_cfun (); } diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 266c0486728..3672e57e471 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -275,7 +275,8 @@ can_inline_edge_p (struct cgraph_edge *e, bool report, } else if (e->call_stmt_cannot_inline_p) { - e->inline_failed = CIF_MISMATCHED_ARGUMENTS; + if (e->inline_failed != CIF_FUNCTION_NOT_OPTIMIZED) + e->inline_failed = CIF_MISMATCHED_ARGUMENTS; inlinable = false; } /* Don't inline if the functions have different EH personalities. */ diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c index 2b22333d1b9..424e4a6b6fe 100644 --- a/gcc/ipa-profile.c +++ b/gcc/ipa-profile.c @@ -625,7 +625,13 @@ ipa_profile (void) of N2. Speculate on the local alias to allow inlining. */ if (!symtab_can_be_discarded ((symtab_node) n2)) - n2 = cgraph (symtab_nonoverwritable_alias ((symtab_node)n2)); + { + cgraph_node *alias; + alias = cgraph (symtab_nonoverwritable_alias + ((symtab_node)n2)); + if (alias) + n2 = alias; + } nconverted++; cgraph_turn_edge_to_speculative (e, n2, diff --git a/gcc/ipa.c b/gcc/ipa.c index 91d63eb9f85..67b3bc0f07c 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -998,7 +998,7 @@ function_and_variable_visibility (bool whole_program) { struct cgraph_node *alias = cgraph (symtab_nonoverwritable_alias ((symtab_node) node)); - if (alias != node) + if (alias && alias != node) { while (node->callers) { diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 479d2cbc22d..f9652c773cd 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -4335,7 +4335,9 @@ need_for_call_save_p (int regno) return (usage_insns[regno].calls_num < calls_num && (overlaps_hard_reg_set_p (call_used_reg_set, - PSEUDO_REGNO_MODE (regno), reg_renumber[regno]))); + PSEUDO_REGNO_MODE (regno), reg_renumber[regno]) + || HARD_REGNO_CALL_PART_CLOBBERED (reg_renumber[regno], + PSEUDO_REGNO_MODE (regno)))); } /* Global registers occurring in the current EBB. */ @@ -5454,43 +5456,44 @@ undo_optional_reloads (void) bitmap_initialize (&removed_optional_reload_pseudos, ®_obstack); bitmap_copy (&removed_optional_reload_pseudos, &lra_optional_reload_pseudos); EXECUTE_IF_SET_IN_BITMAP (&lra_optional_reload_pseudos, 0, regno, bi) - if (reg_renumber[regno] >= 0) - { - keep_p = false; - if (reg_renumber[lra_reg_info[regno].restore_regno] >= 0) + { + keep_p = false; + /* Keep optional reloads from previous subpasses. */ + if (lra_reg_info[regno].restore_regno < 0 /* If the original pseudo changed its allocation, just removing the optional pseudo is dangerous as the original pseudo will have longer live range. */ - keep_p = true; - else - EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi2) - { - insn = lra_insn_recog_data[uid]->insn; - if ((set = single_set (insn)) == NULL_RTX) - continue; - src = SET_SRC (set); - dest = SET_DEST (set); - if (! REG_P (src) || ! REG_P (dest)) - continue; - if (REGNO (dest) == regno - /* Ignore insn for optional reloads itself. */ - && lra_reg_info[regno].restore_regno != (int) REGNO (src) - /* Check only inheritance on last inheritance pass. */ - && (int) REGNO (src) >= new_regno_start - /* Check that the optional reload was inherited. */ - && bitmap_bit_p (&lra_inheritance_pseudos, REGNO (src))) - { - keep_p = true; - break; - } - } - if (keep_p) + || reg_renumber[lra_reg_info[regno].restore_regno] >= 0) + keep_p = true; + else if (reg_renumber[regno] >= 0) + EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi2) { - bitmap_clear_bit (&removed_optional_reload_pseudos, regno); - if (lra_dump_file != NULL) - fprintf (lra_dump_file, "Keep optional reload reg %d\n", regno); + insn = lra_insn_recog_data[uid]->insn; + if ((set = single_set (insn)) == NULL_RTX) + continue; + src = SET_SRC (set); + dest = SET_DEST (set); + if (! REG_P (src) || ! REG_P (dest)) + continue; + if (REGNO (dest) == regno + /* Ignore insn for optional reloads itself. */ + && lra_reg_info[regno].restore_regno != (int) REGNO (src) + /* Check only inheritance on last inheritance pass. */ + && (int) REGNO (src) >= new_regno_start + /* Check that the optional reload was inherited. */ + && bitmap_bit_p (&lra_inheritance_pseudos, REGNO (src))) + { + keep_p = true; + break; + } } - } + if (keep_p) + { + bitmap_clear_bit (&removed_optional_reload_pseudos, regno); + if (lra_dump_file != NULL) + fprintf (lra_dump_file, "Keep optional reload reg %d\n", regno); + } + } change_p = ! bitmap_empty_p (&removed_optional_reload_pseudos); bitmap_initialize (&insn_bitmap, ®_obstack); EXECUTE_IF_SET_IN_BITMAP (&removed_optional_reload_pseudos, 0, regno, bi) diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index 6eaeb2d7779..f3bad974a87 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -457,11 +457,17 @@ lra_setup_reload_pseudo_preferenced_hard_reg (int regno, static inline void check_pseudos_live_through_calls (int regno) { + int hr; + if (! sparseset_bit_p (pseudos_live_through_calls, regno)) return; sparseset_clear_bit (pseudos_live_through_calls, regno); IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, call_used_reg_set); + + for (hr = 0; hr < FIRST_PSEUDO_REGISTER; hr++) + if (HARD_REGNO_CALL_PART_CLOBBERED (hr, PSEUDO_REGNO_MODE (regno))) + SET_HARD_REG_BIT (lra_reg_info[regno].conflict_hard_regs, hr); #ifdef ENABLE_CHECKING lra_reg_info[regno].call_p = true; #endif diff --git a/gcc/lra.c b/gcc/lra.c index df457f5bc9e..f5aab173927 100644 --- a/gcc/lra.c +++ b/gcc/lra.c @@ -2315,7 +2315,6 @@ lra (FILE *f) { for (;;) { - bitmap_clear (&lra_optional_reload_pseudos); /* We should try to assign hard registers to scratches even if there were no RTL transformations in lra_constraints. */ @@ -2367,6 +2366,9 @@ lra (FILE *f) lra_clear_live_ranges (); } } + /* Don't clear optional reloads bitmap until all constraints are + satisfied as we need to differ them from regular reloads. */ + bitmap_clear (&lra_optional_reload_pseudos); bitmap_clear (&lra_subreg_reload_pseudos); bitmap_clear (&lra_inheritance_pseudos); bitmap_clear (&lra_split_regs); diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 1783b46cae5..fa9aca49a3a 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -853,6 +853,7 @@ copy_var_decl (tree var, tree name, tree type) TREE_NO_WARNING (copy) = TREE_NO_WARNING (var); TREE_USED (copy) = 1; DECL_SEEN_IN_BIND_EXPR_P (copy) = 1; + DECL_ATTRIBUTES (copy) = DECL_ATTRIBUTES (var); return copy; } @@ -2305,8 +2306,9 @@ omp_max_vf (void) { if (!optimize || optimize_debug - || (!flag_tree_vectorize - && global_options_set.x_flag_tree_vectorize)) + || (!flag_tree_loop_vectorize + && (global_options_set.x_flag_tree_loop_vectorize + || global_options_set.x_flag_tree_vectorize))) return 1; int vs = targetm.vectorize.autovectorize_vector_sizes (); @@ -2773,6 +2775,9 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, if (lane) { tree uid = create_tmp_var (ptr_type_node, "simduid"); + /* Don't want uninit warnings on simduid, it is always uninitialized, + but we use it not for the value, but for the DECL_UID only. */ + TREE_NO_WARNING (uid) = 1; gimple g = gimple_build_call_internal (IFN_GOMP_SIMD_LANE, 1, uid); gimple_call_set_lhs (g, lane); @@ -5684,10 +5689,11 @@ expand_omp_simd (struct omp_region *region, struct omp_for_data *fd) loop->simduid = OMP_CLAUSE__SIMDUID__DECL (simduid); cfun->has_simduid_loops = true; } - /* If not -fno-tree-vectorize, hint that we want to vectorize + /* If not -fno-tree-loop-vectorize, hint that we want to vectorize the loop. */ - if ((flag_tree_vectorize - || !global_options_set.x_flag_tree_vectorize) + if ((flag_tree_loop_vectorize + || (!global_options_set.x_flag_tree_loop_vectorize + && !global_options_set.x_flag_tree_vectorize)) && loop->safelen > 1) { loop->force_vect = true; @@ -5866,8 +5872,7 @@ expand_omp_sections (struct omp_region *region) { /* If we are not inside a combined parallel+sections region, call GOMP_sections_start. */ - t = build_int_cst (unsigned_type_node, - exit_reachable ? len - 1 : len); + t = build_int_cst (unsigned_type_node, len - 1); u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START); stmt = gimple_build_call (u, 1, t); } diff --git a/gcc/opts.c b/gcc/opts.c index 6b6652d89ca..944834c4438 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -498,7 +498,8 @@ static const struct default_options default_options_table[] = { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 }, { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 }, { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 }, - { OPT_LEVELS_3_PLUS, OPT_ftree_vectorize, NULL, 1 }, + { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 }, + { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 }, { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model, NULL, 1 }, { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 }, { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 }, @@ -826,7 +827,8 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, /* Set PARAM_MAX_STORES_TO_SINK to 0 if either vectorization or if-conversion is disabled. */ - if (!opts->x_flag_tree_vectorize || !opts->x_flag_tree_loop_if_convert) + if ((!opts->x_flag_tree_loop_vectorize && !opts->x_flag_tree_slp_vectorize) + || !opts->x_flag_tree_loop_if_convert) maybe_set_param_value (PARAM_MAX_STORES_TO_SINK, 0, opts->x_param_values, opts_set->x_param_values); @@ -1660,8 +1662,12 @@ common_handle_option (struct gcc_options *opts, opts->x_flag_unswitch_loops = value; if (!opts_set->x_flag_gcse_after_reload) opts->x_flag_gcse_after_reload = value; - if (!opts_set->x_flag_tree_vectorize) - opts->x_flag_tree_vectorize = value; + if (!opts_set->x_flag_tree_loop_vectorize + && !opts_set->x_flag_tree_vectorize) + opts->x_flag_tree_loop_vectorize = value; + if (!opts_set->x_flag_tree_slp_vectorize + && !opts_set->x_flag_tree_vectorize) + opts->x_flag_tree_slp_vectorize = value; if (!opts_set->x_flag_vect_cost_model) opts->x_flag_vect_cost_model = value; if (!opts_set->x_flag_tree_loop_distribute_patterns) @@ -1691,6 +1697,12 @@ common_handle_option (struct gcc_options *opts, opts->x_flag_ipa_reference = false; break; + case OPT_ftree_vectorize: + if (!opts_set->x_flag_tree_loop_vectorize) + opts->x_flag_tree_loop_vectorize = value; + if (!opts_set->x_flag_tree_slp_vectorize) + opts->x_flag_tree_slp_vectorize = value; + break; case OPT_fshow_column: dc->show_column = value; break; diff --git a/gcc/profile.c b/gcc/profile.c index 7e8bb0861e6..94a3f07c6f3 100644 --- a/gcc/profile.c +++ b/gcc/profile.c @@ -434,7 +434,8 @@ read_profile_edge_counts (gcov_type *exec_counts) static bool informed = 0; if (dump_enabled_p () && !informed) dump_printf_loc (MSG_NOTE, input_location, - "corrupted profile info: edge count exceeds maximal count"); + "corrupted profile info: edge count" + " exceeds maximal count\n"); informed = 1; } else @@ -696,7 +697,7 @@ compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum) { informed = 1; dump_printf_loc (MSG_NOTE, input_location, - "correcting inconsistent profile data"); + "correcting inconsistent profile data\n"); } correct_negative_edge_counts (); /* Set bb counts to the sum of the outgoing edge counts */ diff --git a/gcc/symtab.c b/gcc/symtab.c index 8dc61d0c7af..62fe166bd61 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -1083,6 +1083,10 @@ symtab_nonoverwritable_alias (symtab_node node) (void *)&new_node, true); if (new_node) return new_node; +#ifndef ASM_OUTPUT_DEF + /* If aliases aren't supported by the assembler, fail. */ + return NULL; +#endif /* Otherwise create a new one. */ new_decl = copy_node (node->symbol.decl); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6b9b3bc205b..203fd13ddb0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,153 @@ +2013-09-20 Janus Weil <janus@gcc.gnu.org> + + PR fortran/58099 + * gfortran.dg/proc_ptr_43.f90: New. + +2013-09-18 Tobias Burnus <burnus@net-b.de> + + PR fortran/57697 + * gfortran.dg/defined_assignment_11.f90: New. + +2013-09-18 Vladimir Makarov <vmakarov@redhat.com> + + PR rtl-optimization/58438 + * g++.dg/pr58438.C: New test. + +2013-09-18 Tobias Burnus <burnus@net-b.de> + + PR fortran/43366 + * gfortran.dg/class_39.f03: Update dg-error. + * gfortran.dg/class_5.f03: Ditto. + * gfortran.dg/class_53.f90: Ditto. + * gfortran.dg/realloc_on_assign_20.f90: New. + * gfortran.dg/realloc_on_assign_21.f90: New. + * gfortran.dg/realloc_on_assign_22.f90: New. + +2013-09-18 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/58457 + * g++.dg/parse/using4.C: New. + +2013-09-18 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * gcc.c-torture/execute/pr58419.c (b): Change type to signed char. + +2013-09-18 Marek Polacek <polacek@redhat.com> + + PR sanitize/58443 + * g++.dg/ubsan/div-by-zero-1.C: Use the integer-divide-by-zero option + instead of the shift option. + * c-c++-common/ubsan/pr58443-1.c: New test. + * c-c++-common/ubsan/pr58443-3.c: New test. + * c-c++-common/ubsan/pr58443-2.c: New test. + +2013-09-18 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58417 + * gcc.dg/torture/pr58417.c: New testcase. + +2013-09-18 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/array_bounds_test2.adb: New test. + +2013-09-18 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * g++.dg/debug/dwarf2/omp-fesdr.C: Check for fopenmp effective target. + * gcc.dg/debug/dwarf2/omp-fesdr.c: Likewise. + +2013-09-18 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/in_out_parameter4.adb: New test. + +2013-09-18 Marek Polacek <polacek@redhat.com> + + PR sanitizer/58411 + * c-c++-common/ubsan/attrib-1.c: New test. + +2013-09-17 Cong Hou <congh@google.com> + + * gcc.dg/vect/vect-reduc-dot-s16c.c: Add a test case with dot product + on two arrays with short and int types. This should not be recognized + as a dot product pattern. + +2013-09-17 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/58435 + * pt.c (tsubst, [BOUND_TEMPLATE_TEMPLATE_PARM]): Take into account + the cp_type_quals (r) too. + +2013-09-17 Jan Hubicka <jh@suse.cz> + + PR middle-end/58332 + * gcc.c-torture/compile/pr58332.c: New testcase. + +2013-09-17 Jeff Law <law@redhat.com> + + * gcc.c-torture/execute/pr58387.c: New test. + +2013-09-17 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + PR tree-optimization/58088 + * gcc.c-torture/compile/pr58088.c: New test. + +2013-09-17 Nick Clifton <nickc@redhat.com> + + * lib/target-supports.exp (check_effective_target_trampolines): + Add MSP430 to the list of targets that do not support + trampolines. + (check_profiling_available): Add MSP430 to the list of targets + that do not support profiling. + (check_effective_target_tls_runtime): Add MSP430 to the list of + targets that do not support TLS. + +2013-09-17 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/opt27.adb: New test. + * gnat.dg/opt27_pkg.ad[sb]: New helper. + +2013-09-17 Andreas Schwab <schwab@suse.de> + + * gcc.dg/tree-ssa/ldist-22.c (main): Return zero. + +2013-09-17 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58432 + * gcc.dg/pr58432.c: New testcase. + +2013-09-17 Bin Cheng <bin.cheng@arm.com> + + * gcc.dg/tree-ssa/slsr-39.c: New test. + +2013-09-16 Xinliang David Li <davidxl@google.com> + + * gcc.misc-tests/help.exp: Optimizer help change. + +2013-09-16 Jeff Law <law@redhat.com> + + * gcc.c-torture/execute/pr58419.c: New test. + * gcc.c-torture/execute/pr58431.c: New test. + +2013-09-16 Tobias Burnus <burnus@net-b.de> + + PR fortran/58356 + * gfortran.dg/finalize_19.f90: New. + +2013-09-16 Vladimir Makarov <vmakarov@redhat.com> + + * gcc.target/i386/pr58418.c: New. + +2013-09-16 James Greenhalgh <james.greenhalgh@arm.com> + + * gcc.target/aarch64/fmla-intrinsic.c: New. + * gcc.target/aarch64/mla-intrinsic.c: Likewise. + * gcc.target/aarch64/fmls-intrinsic.c: Likewise. + * gcc.target/aarch64/mls-intrinsic.c: Likewise. + +2013-09-16 James Greenhalgh <james.greenhalgh@arm.com> + + * gcc.target/aarch64/mul_intrinsic_1.c: New. + * gcc.target/aarch64/fmul_intrinsic_1.c: Likewise. + 2013-09-16 Richard Biener <rguenther@suse.de> * gcc.dg/tree-ssa/ldist-22.c: New testcase. diff --git a/gcc/testsuite/c-c++-common/ubsan/attrib-1.c b/gcc/testsuite/c-c++-common/ubsan/attrib-1.c new file mode 100644 index 00000000000..2e9141ca040 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/attrib-1.c @@ -0,0 +1,33 @@ +/* PR sanitizer/58411 */ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=undefined -w" } */ + +__attribute__((no_sanitize_undefined)) int +f1 (int i) +{ + return 16 << i; +} + +int f2 (int i); +int f2 (int i) __attribute__((no_sanitize_undefined)); +int f2 (int i) __attribute__((no_sanitize_undefined)); +int f2 (int i); + +int +f2 (int i) +{ + return 1 / i; +} + +void f3 (void); +__typeof (f3) f3 __attribute__((__no_sanitize_undefined__)); + +void +f3 (void) +{ + __builtin_unreachable (); +} + +/* { dg-final { scan-assembler-not "__ubsan_handle_shift_out_of_bounds" } } */ +/* { dg-final { scan-assembler-not "__ubsan_handle_divrem_overflow" } } */ +/* { dg-final { scan-assembler-not "__ubsan_handle_builtin_unreachable" } } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/pr58443-1.c b/gcc/testsuite/c-c++-common/ubsan/pr58443-1.c new file mode 100644 index 00000000000..76f1dda07a5 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/pr58443-1.c @@ -0,0 +1,11 @@ +/* PR sanitizer/58443 */ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=shift,unreachable -w" } */ + +int +foo (int u, int o) +{ + return u / o; +} + +/* { dg-final { scan-assembler-not "__ubsan_handle_divrem_overflow" } } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/pr58443-2.c b/gcc/testsuite/c-c++-common/ubsan/pr58443-2.c new file mode 100644 index 00000000000..a135758a86f --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/pr58443-2.c @@ -0,0 +1,11 @@ +/* PR sanitizer/58443 */ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=unreachable,integer-divide-by-zero -w" } */ + +int +foo (int u, int o) +{ + return u >> o; +} + +/* { dg-final { scan-assembler-not "__ubsan_handle_shift_out_of_bounds" } } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/pr58443-3.c b/gcc/testsuite/c-c++-common/ubsan/pr58443-3.c new file mode 100644 index 00000000000..5696a62dffa --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/pr58443-3.c @@ -0,0 +1,18 @@ +/* PR sanitizer/58443 */ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=undefined -w" } */ + +int +foo (int u, int o) +{ + return u >> o; +} + +int +bar (int u, int o) +{ + return u / o; +} + +/* { dg-final { scan-assembler "__ubsan_handle_divrem_overflow" } } */ +/* { dg-final { scan-assembler "__ubsan_handle_shift_out_of_bounds" } } */ diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-38.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-38.C new file mode 100644 index 00000000000..bc98737b849 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-38.C @@ -0,0 +1,41 @@ +// PR c++/58435 +// { dg-do compile { target c++11 } } + +template<typename T, typename U> +struct same { static const bool value = false; }; +template<typename T> +struct same<T, T> { static const bool value = true; }; + +template <template <typename> class F, typename T> struct apply +{ typedef F<T> type; }; +template <template <typename> class F, typename T> struct applyc +{ typedef const F<T> type; }; +template <template <typename> class F, typename T> struct applyv +{ typedef volatile F<T> type; }; +template <template <typename> class F, typename T> struct applycv +{ typedef const volatile F<T> type; }; + +template <typename T> using map = T; +template <typename T> using mapc = const T; +template <typename T> using mapv = volatile T; +template <typename T> using mapcv = const volatile T; + +static_assert(same<apply<map, int>::type, int>::value, ""); +static_assert(same<apply<mapc, int>::type, const int>::value, ""); +static_assert(same<apply<mapv, int>::type, volatile int>::value, ""); +static_assert(same<apply<mapcv, int>::type, const volatile int>::value, ""); + +static_assert(same<applyc<map, int>::type, const int>::value, ""); +static_assert(same<applyc<mapc, int>::type, const int>::value, ""); +static_assert(same<applyc<mapv, int>::type, const volatile int>::value, ""); +static_assert(same<applyc<mapcv, int>::type, const volatile int>::value, ""); + +static_assert(same<applyv<map, int>::type, volatile int>::value, ""); +static_assert(same<applyv<mapc, int>::type, const volatile int>::value, ""); +static_assert(same<applyv<mapv, int>::type, volatile int>::value, ""); +static_assert(same<applyv<mapcv, int>::type, const volatile int>::value, ""); + +static_assert(same<applycv<map, int>::type, const volatile int>::value, ""); +static_assert(same<applycv<mapc, int>::type, const volatile int>::value, ""); +static_assert(same<applycv<mapv, int>::type, const volatile int>::value, ""); +static_assert(same<applycv<mapcv, int>::type, const volatile int>::value, ""); diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/omp-fesdr.C b/gcc/testsuite/g++.dg/debug/dwarf2/omp-fesdr.C index 005acdf0865..b3b65e91888 100644 --- a/gcc/testsuite/g++.dg/debug/dwarf2/omp-fesdr.C +++ b/gcc/testsuite/g++.dg/debug/dwarf2/omp-fesdr.C @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target fopenmp } */ /* { dg-options "-g -fopenmp -gdwarf-2 -femit-struct-debug-reduced" } */ struct aa diff --git a/gcc/testsuite/g++.dg/parse/using4.C b/gcc/testsuite/g++.dg/parse/using4.C new file mode 100644 index 00000000000..2abe399f8dc --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/using4.C @@ -0,0 +1,20 @@ +// PR c++/58457 + +struct allocator +{ + void operator delete (void*); + void* operator new (__SIZE_TYPE__, void*); +}; + +struct type : public allocator +{ + type() {} + using allocator::operator new; + using allocator::operator delete; +}; + +int main() +{ + new (0) type; + return 0; +} diff --git a/gcc/testsuite/g++.dg/pr58438.C b/gcc/testsuite/g++.dg/pr58438.C new file mode 100644 index 00000000000..4c62cb26ce8 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr58438.C @@ -0,0 +1,45 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-march=amdfam10 -O3 -fprofile-generate" } */ +enum gimple_code {}; +struct A { + gimple_code code; +}; +struct B { + A gsbase; +}; +int **a; +int b, d, e, f, g, h, i, j, k, l, m, n, o; +gimple_code c, p; +class C { + virtual unsigned m_fn1(); +}; +B q; +static int fn1() { + int r; + if (k) + i = 0; + for (; i; j++) { + b = c <= 0; + if (b) + n = *a[0]; + b = p && c; + if (b) + r = *a[0]; + b = q.gsbase.code && c; + if (b) + o = *a[0]; + m = o; + if (e || 1 & r || d || l) + return 0; + } +} + +class D : C { + unsigned m_fn1() { + fn1(); + for (; h; g++) + for (;; f++) + ; + } +}; +void fn2() { new D; } diff --git a/gcc/testsuite/g++.dg/ubsan/div-by-zero-1.C b/gcc/testsuite/g++.dg/ubsan/div-by-zero-1.C index d7d2c8f1565..88acfa1517e 100644 --- a/gcc/testsuite/g++.dg/ubsan/div-by-zero-1.C +++ b/gcc/testsuite/g++.dg/ubsan/div-by-zero-1.C @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fsanitize=shift -w" } */ +/* { dg-options "-fsanitize=integer-divide-by-zero -w" } */ void foo (int i) diff --git a/gcc/testsuite/gcc.c-torture/compile/pr58088.c b/gcc/testsuite/gcc.c-torture/compile/pr58088.c new file mode 100644 index 00000000000..07a9c68a7ff --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr58088.c @@ -0,0 +1,5 @@ +int +bar (int i) +{ + return 1 | ((i * 2) & 254); +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr58332.c b/gcc/testsuite/gcc.c-torture/compile/pr58332.c new file mode 100644 index 00000000000..22c586cb866 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr58332.c @@ -0,0 +1,2 @@ +static inline int foo (int x) { return x + 1; } +__attribute__ ((__optimize__ (0))) int bar (void) { return foo (100); } diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58387.c b/gcc/testsuite/gcc.c-torture/execute/pr58387.c new file mode 100644 index 00000000000..74c32dfaf10 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr58387.c @@ -0,0 +1,11 @@ +extern void abort(void); + +int a = -1; + +int main () +{ + int b = a == 0 ? 0 : -a; + if (b < 1) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58419.c b/gcc/testsuite/gcc.c-torture/execute/pr58419.c new file mode 100644 index 00000000000..69cc0401dc1 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr58419.c @@ -0,0 +1,36 @@ +int printf(const char *, ...); + +int a, g, i, k, *p; +signed char b; +char e; +short c, h; +static short *d = &c; + +char +foo (int p1, int p2) +{ + return p1 - p2; +} + +int +bar () +{ + short *q = &c; + *q = 1; + *p = 0; + return 0; +} + +int +main () +{ + for (b = -22; b >= -29; b--) + { + short *l = &h; + char *m = &e; + *l = a; + g = foo (*m = k && *d, 1 > i) || bar (); + } + getpid(); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58431.c b/gcc/testsuite/gcc.c-torture/execute/pr58431.c new file mode 100644 index 00000000000..1a992c5fc8d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr58431.c @@ -0,0 +1,33 @@ +char a, h; +int b, d, e, g, j, k; +volatile int c; +short i; + +int +main () +{ + int m; + + m = i ^= 1; + for (b = 0; b < 1; b++) + { + char o = m; + g = k; + j = j || c; + if (a != o) + for (; d < 1; d++) + ; + else + { + char *p = &h; + *p = 1; + for (; e; e++) + ; + } + } + + if (h != 0) + __builtin_abort(); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/omp-fesdr.c b/gcc/testsuite/gcc.dg/debug/dwarf2/omp-fesdr.c index 005acdf0865..d7b03192be2 100644 --- a/gcc/testsuite/gcc.dg/debug/dwarf2/omp-fesdr.c +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/omp-fesdr.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target fopenmp } */ /* { dg-options "-g -fopenmp -gdwarf-2 -femit-struct-debug-reduced" } */ struct aa diff --git a/gcc/testsuite/gcc.dg/pr58432.c b/gcc/testsuite/gcc.dg/pr58432.c new file mode 100644 index 00000000000..22a720f142f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr58432.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-profiling "-fprofile-generate" } */ +/* { dg-options "-O3 -fprofile-generate" } */ + +struct { + int prefix; + int dir_idx; +} *a; +int b; +void fn1() { + int *c, *d; + for (; b; b++) + if (d[b]) { + c[b] = d[b]; + a[0].dir_idx = 0; + } +} diff --git a/gcc/testsuite/gcc.dg/torture/pr58417.c b/gcc/testsuite/gcc.dg/torture/pr58417.c new file mode 100644 index 00000000000..5cb0ddb0275 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr58417.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ + +long long arr[6] = {0, 1, 2, 3, 4, 5}; +extern void abort (void); +void __attribute__((noinline,noclone)) +foo (long long sum) +{ + asm (""); +} +int main() +{ + int i, n = 5; + long long sum = 0, prevsum = 0; + + for(i = 1; i <= n; i++) + { + foo (sum); + sum = (i - 1) * arr[i] - prevsum; + prevsum += arr[i]; + } + + if (sum != 10) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-22.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-22.c index f6fff77f3fe..afc792f6503 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ldist-22.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-22.c @@ -25,7 +25,7 @@ int main() abort (); if (a[0] != 0 || a[101] != 0) abort (); - return; + return 0; } /* { dg-final { scan-tree-dump "generated memset zero" "ldist" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-39.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-39.c new file mode 100644 index 00000000000..8cc279857c2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-39.c @@ -0,0 +1,26 @@ +/* Verify straight-line strength reduction for back-tracing + CAND_ADD for T2 in: + + *PBASE: T1 + *POFFSET: MULT_EXPR (T2, C3) + *PINDEX: C1 + (C2 * C3) + C4 */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-slsr" } */ + +typedef int arr_2[50][50]; + +void foo (arr_2 a2, int v1) +{ + int i, j; + + i = v1 + 5; + j = i; + a2 [i] [j++] = i; + a2 [i] [j++] = i; + a2 [i] [i-1] += 1; + return; +} + +/* { dg-final { scan-tree-dump-times "MEM" 4 "slsr" } } */ +/* { dg-final { cleanup-tree-dump "slsr" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16c.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16c.c new file mode 100644 index 00000000000..8ba823b044c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16c.c @@ -0,0 +1,73 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 +#define DOT 43680 + +signed short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed int Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +/* (short, int)->int->int dot product. + Not detected as a dot-product pattern. */ + +__attribute__ ((noinline)) int +foo (int len) +{ + int i; + int result = 0; + + for (i = 0; i < len; i++) + { + result += (X[i] * Y[i]); + } + return result; +} + + +/* (int, short)->int->int dot product. + Not detected as a dot-product pattern. */ + +__attribute__ ((noinline)) int +bar (int len) +{ + int i; + int result = 0; + + for (i = 0; i < len; i++) + { + result += (Y[i] * X[i]); + } + return result; +} + +int +main (void) +{ + int i; + int dot; + + check_vect (); + + for (i = 0; i < N; i++) + { + X[i] = i; + Y[i] = N - i; + __asm__ volatile (""); + } + + dot = foo (N); + if (dot != DOT) + abort (); + + dot = bar (N); + if (dot != DOT) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.misc-tests/help.exp b/gcc/testsuite/gcc.misc-tests/help.exp index 7ad53926a53..20153d12496 100644 --- a/gcc/testsuite/gcc.misc-tests/help.exp +++ b/gcc/testsuite/gcc.misc-tests/help.exp @@ -55,11 +55,11 @@ check_for_options c "--help=target,optimizers" "" "" "" check_for_options c "--help=warnings,^joined,^undocumented" "" "" "" check_for_options c "-Q -O2 --help=optimizers" { -O --ftree-vectorize[^\n]*disabled +-ftree-loop-vectorize[^\n]*disabled } " -g " "" check_for_options c "-Q -O3 --help=optimizers" { -O --ftree-vectorize[^\n]*enabled +-ftree-loop-vectorize[^\n]*enabled } " -g " "" # Try repeated --help=. check_for_options c "--help=params --help=optimizers" { diff --git a/gcc/testsuite/gcc.target/aarch64/fmla_intrinsic_1.c b/gcc/testsuite/gcc.target/aarch64/fmla_intrinsic_1.c new file mode 100644 index 00000000000..0bf1b86b79e --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/fmla_intrinsic_1.c @@ -0,0 +1,116 @@ +/* { dg-do run } */ +/* { dg-options "-O3 --save-temps" } */ + +#include <arm_neon.h> + +#define DELTA 0.0001 + +extern double fabs (double); + +extern void abort (void); + +#define TEST_VMLA(q1, q2, size, in1_lanes, in2_lanes) \ +static void \ +test_vfma##q1##_lane##q2##_f##size (float##size##_t * res, \ + const float##size##_t *in1, \ + const float##size##_t *in2) \ +{ \ + float##size##x##in1_lanes##_t a = vld1##q1##_f##size (res); \ + float##size##x##in1_lanes##_t b = vld1##q1##_f##size (in1); \ + float##size##x##in2_lanes##_t c; \ + if (in2_lanes > 1) \ + { \ + c = vld1##q2##_f##size (in2); \ + a = vfma##q1##_lane##q2##_f##size (a, b, c, 1); \ + } \ + else \ + { \ + c = vld1##q2##_f##size (in2 + 1); \ + a = vfma##q1##_lane##q2##_f##size (a, b, c, 0); \ + } \ + vst1##q1##_f##size (res, a); \ +} + +#define BUILD_VARS(width, n_lanes, n_half_lanes) \ +TEST_VMLA ( , , width, n_half_lanes, n_half_lanes) \ +TEST_VMLA (q, , width, n_lanes, n_half_lanes) \ +TEST_VMLA ( , q, width, n_half_lanes, n_lanes) \ +TEST_VMLA (q, q, width, n_lanes, n_lanes) \ + +BUILD_VARS (32, 4, 2) +BUILD_VARS (64, 2, 1) + +#define POOL2 {0.0, 1.0} +#define POOL4 {0.0, 1.0, 2.0, 3.0} +#define EMPTY2 {0.0, 0.0} +#define EMPTY4 {0.0, 0.0, 0.0, 0.0} + +#define BUILD_TEST(size, lanes) \ +static void \ +test_f##size (void) \ +{ \ + int i; \ + float##size##_t pool[lanes] = POOL##lanes; \ + float##size##_t res[lanes] = EMPTY##lanes; \ + float##size##_t res2[lanes] = EMPTY##lanes; \ + float##size##_t res3[lanes] = EMPTY##lanes; \ + float##size##_t res4[lanes] = EMPTY##lanes; \ + \ + /* Forecfully avoid optimization. */ \ + asm volatile ("" : : : "memory"); \ + test_vfma_lane_f##size (res, pool, pool); \ + for (i = 0; i < lanes / 2; i++) \ + if (fabs (res[i] - pool[i]) > DELTA) \ + abort (); \ + \ + /* Forecfully avoid optimization. */ \ + asm volatile ("" : : : "memory"); \ + test_vfmaq_lane_f##size (res2, pool, pool); \ + for (i = 0; i < lanes; i++) \ + if (fabs (res2[i] - pool[i]) > DELTA) \ + abort (); \ + \ + /* Forecfully avoid optimization. */ \ + asm volatile ("" : : : "memory"); \ + test_vfma_laneq_f##size (res3, pool, pool); \ + for (i = 0; i < lanes / 2; i++) \ + if (fabs (res3[i] - pool[i]) > DELTA) \ + abort (); \ + \ + /* Forecfully avoid optimization. */ \ + asm volatile ("" : : : "memory"); \ + test_vfmaq_laneq_f##size (res4, pool, pool); \ + for (i = 0; i < lanes; i++) \ + if (fabs (res4[i] - pool[i]) > DELTA) \ + abort (); \ +} + +BUILD_TEST (32, 4) +BUILD_TEST (64, 2) + +int +main (int argc, char **argv) +{ + test_f32 (); + test_f64 (); + return 0; +} + +/* vfma_laneq_f32. + vfma_lane_f32. */ +/* { dg-final { scan-assembler-times "fmla\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s\\\[\[0-9\]+\\\]" 2 } } */ + +/* vfmaq_lane_f32. + vfmaq_laneq_f32. */ +/* { dg-final { scan-assembler-times "fmla\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s\\\[\[0-9\]+\\\]" 2 } } */ + +/* vfma_lane_f64. */ +/* { dg-final { scan-assembler-times "fmadd\\td\[0-9\]+\, d\[0-9\]+\, d\[0-9\]+\, d\[0-9\]+" 1 } } */ + +/* vfmaq_lane_f64. + vfma_laneq_f64. + vfmaq_laneq_f64. */ +/* { dg-final { scan-assembler-times "fmla\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d\\\[\[0-9\]+\\\]" 3 } } */ + +/* { dg-final { cleanup-saved-temps } } */ + diff --git a/gcc/testsuite/gcc.target/aarch64/fmls_intrinsic_1.c b/gcc/testsuite/gcc.target/aarch64/fmls_intrinsic_1.c new file mode 100644 index 00000000000..8cc2942f8f1 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/fmls_intrinsic_1.c @@ -0,0 +1,117 @@ +/* { dg-do run } */ +/* { dg-options "-O3 --save-temps" } */ + +#include <arm_neon.h> + +#define DELTA 0.0001 + +extern double fabs (double); + +extern void abort (void); + +#define TEST_VMLS(q1, q2, size, in1_lanes, in2_lanes) \ +static void \ +test_vfms##q1##_lane##q2##_f##size (float##size##_t * res, \ + const float##size##_t *in1, \ + const float##size##_t *in2) \ +{ \ + float##size##x##in1_lanes##_t a = vld1##q1##_f##size (res); \ + float##size##x##in1_lanes##_t b = vld1##q1##_f##size (in1); \ + float##size##x##in2_lanes##_t c; \ + if (in2_lanes > 1) \ + { \ + c = vld1##q2##_f##size (in2); \ + a = vfms##q1##_lane##q2##_f##size (a, b, c, 1); \ + } \ + else \ + { \ + c = vld1##q2##_f##size (in2 + 1); \ + a = vfms##q1##_lane##q2##_f##size (a, b, c, 0); \ + } \ + vst1##q1##_f##size (res, a); \ +} + +#define BUILD_VARS(width, n_lanes, n_half_lanes) \ +TEST_VMLS ( , , width, n_half_lanes, n_half_lanes) \ +TEST_VMLS (q, , width, n_lanes, n_half_lanes) \ +TEST_VMLS ( , q, width, n_half_lanes, n_lanes) \ +TEST_VMLS (q, q, width, n_lanes, n_lanes) \ + +BUILD_VARS (32, 4, 2) +BUILD_VARS (64, 2, 1) + +#define POOL2 {0.0, 1.0} +#define POOL4 {0.0, 1.0, 2.0, 3.0} +#define EMPTY2 {0.0, 0.0} +#define EMPTY4 {0.0, 0.0, 0.0, 0.0} + +#define BUILD_TEST(size, lanes) \ +static void \ +test_f##size (void) \ +{ \ + int i; \ + float##size##_t pool[lanes] = POOL##lanes; \ + float##size##_t res[lanes] = EMPTY##lanes; \ + float##size##_t res2[lanes] = EMPTY##lanes; \ + float##size##_t res3[lanes] = EMPTY##lanes; \ + float##size##_t res4[lanes] = EMPTY##lanes; \ + \ + /* Forecfully avoid optimization. */ \ + asm volatile ("" : : : "memory"); \ + test_vfms_lane_f##size (res, pool, pool); \ + asm volatile ("" : :"Q" (res) : "memory"); \ + for (i = 0; i < lanes / 2; i++) \ + if (fabs (res[i] + pool[i]) > DELTA) \ + abort (); \ + \ + /* Forecfully avoid optimization. */ \ + test_vfmsq_lane_f##size (res2, pool, pool); \ + asm volatile ("" : :"Q" (res2) : "memory"); \ + for (i = 0; i < lanes; i++) \ + if (fabs (res2[i] + pool[i]) > DELTA) \ + abort (); \ + \ + /* Forecfully avoid optimization. */ \ + test_vfms_laneq_f##size (res3, pool, pool); \ + asm volatile ("" : :"Q" (res3) : "memory"); \ + for (i = 0; i < lanes / 2; i++) \ + if (fabs (res3[i] + pool[i]) > DELTA) \ + abort (); \ + \ + /* Forecfully avoid optimization. */ \ + test_vfmsq_laneq_f##size (res4, pool, pool); \ + asm volatile ("" : :"Q" (res4) : "memory"); \ + for (i = 0; i < lanes; i++) \ + if (fabs (res4[i] + pool[i]) > DELTA) \ + abort (); \ +} + +BUILD_TEST (32, 4) +BUILD_TEST (64, 2) + +int +main (int argc, char **argv) +{ + test_f32 (); + test_f64 (); + return 0; +} + +/* vfms_laneq_f32. + vfms_lane_f32. */ +/* { dg-final { scan-assembler-times "fmls\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.2s\\\[\[0-9\]+\\\]" 2 } } */ + +/* vfmsq_lane_f32. + vfmsq_laneq_f32. */ +/* { dg-final { scan-assembler-times "fmls\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s\\\[\[0-9\]+\\\]" 2 } } */ + +/* vfms_lane_f64. */ +/* { dg-final { scan-assembler-times "fmsub\\td\[0-9\]+\, d\[0-9\]+\, d\[0-9\]+\, d\[0-9\]+" 1 } } */ + +/* vfmsq_lane_f64. + vfms_laneq_f64. + vfmsq_laneq_f64. */ +/* { dg-final { scan-assembler-times "fmls\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d\\\[\[0-9\]+\\\]" 3 } } */ + +/* { dg-final { cleanup-saved-temps } } */ + diff --git a/gcc/testsuite/gcc.target/aarch64/fmul_intrinsic_1.c b/gcc/testsuite/gcc.target/aarch64/fmul_intrinsic_1.c new file mode 100644 index 00000000000..f6e32f4bf77 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/fmul_intrinsic_1.c @@ -0,0 +1,116 @@ +/* { dg-do run } */ +/* { dg-options "-O3 --save-temps" } */ + +#include <arm_neon.h> + +#define DELTA 0.0001 +extern void abort (void); +extern double fabs (double); + +#define TEST_VMUL(q1, q2, size, in1_lanes, in2_lanes) \ +static void \ +test_vmul##q1##_lane##q2##_f##size (float##size##_t * res, \ + const float##size##_t *in1, \ + const float##size##_t *in2) \ +{ \ + float##size##x##in1_lanes##_t a = vld1##q1##_f##size (res); \ + float##size##x##in1_lanes##_t b = vld1##q1##_f##size (in1); \ + float##size##x##in2_lanes##_t c; \ + if (in2_lanes > 1) \ + { \ + c = vld1##q2##_f##size (in2); \ + a = vmul##q1##_lane##q2##_f##size (b, c, 1); \ + } \ + else \ + { \ + c = vld1##q2##_f##size (in2 + 1); \ + a = vmul##q1##_lane##q2##_f##size (b, c, 0); \ + } \ + vst1##q1##_f##size (res, a); \ +} + +#define BUILD_VARS(width, n_lanes, n_half_lanes) \ +TEST_VMUL ( , , width, n_half_lanes, n_half_lanes) \ +TEST_VMUL (q, , width, n_lanes, n_half_lanes) \ +TEST_VMUL ( , q, width, n_half_lanes, n_lanes) \ +TEST_VMUL (q, q, width, n_lanes, n_lanes) + +BUILD_VARS (32, 4, 2) +BUILD_VARS (64, 2, 1) + +#define POOL2 {0.0, 1.0} +#define POOL4 {0.0, 1.0, 2.0, 3.0} +#define EMPTY2 {0.0, 0.0} +#define EMPTY4 {0.0, 0.0, 0.0, 0.0} + +#define BUILD_TEST(size, lanes) \ +static void \ +test_f##size (void) \ +{ \ + int i; \ + float##size##_t pool[lanes] = POOL##lanes; \ + float##size##_t res[lanes] = EMPTY##lanes; \ + float##size##_t res2[lanes] = EMPTY##lanes; \ + float##size##_t res3[lanes] = EMPTY##lanes; \ + float##size##_t res4[lanes] = EMPTY##lanes; \ + \ + /* Avoid constant folding the multiplication. */ \ + asm volatile ("" : : : "memory"); \ + test_vmul_lane_f##size (res, pool, pool); \ + /* Avoid fusing multiplication and subtraction. */ \ + asm volatile ("" : :"Q" (res) : "memory"); \ + for (i = 0; i < lanes / 2; i++) \ + if (fabs (res[i] - pool[i]) > DELTA) \ + abort (); \ + \ + test_vmulq_lane_f##size (res2, pool, pool); \ + /* Avoid fusing multiplication and subtraction. */ \ + asm volatile ("" : :"Q" (res2) : "memory"); \ + for (i = 0; i < lanes; i++) \ + if (fabs (res2[i] - pool[i]) > DELTA) \ + abort (); \ + \ + test_vmul_laneq_f##size (res3, pool, pool); \ + /* Avoid fusing multiplication and subtraction. */ \ + asm volatile ("" : :"Q" (res3) : "memory"); \ + for (i = 0; i < lanes / 2; i++) \ + if (fabs (res3[i] - pool[i]) > DELTA) \ + abort (); \ + \ + test_vmulq_laneq_f##size (res4, pool, pool); \ + /* Avoid fusing multiplication and subtraction. */ \ + asm volatile ("" : :"Q" (res4) : "memory"); \ + for (i = 0; i < lanes; i++) \ + if (fabs (res4[i] - pool[i]) > DELTA) \ + abort (); \ +} + +BUILD_TEST (32, 4) +BUILD_TEST (64, 2) + +int +main (int argc, char **argv) +{ + test_f32 (); + test_f64 (); + return 0; +} + +/* vmul_laneq_f32. + vmul_lane_f32. */ +/* { dg-final { scan-assembler-times "fmul\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.s\\\[\[0-9\]+\\\]" 2 } } */ + +/* vmulq_lane_f32. + vmulq_laneq_f32. */ +/* { dg-final { scan-assembler-times "fmul\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.s\\\[\[0-9\]+\\\]" 2 } } */ + +/* vmul_lane_f64. */ +/* { dg-final { scan-assembler-times "fmul\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 1 } } */ + +/* vmul_laneq_f64. + vmulq_lane_f64. + vmulq_laneq_f64. */ +/* { dg-final { scan-assembler-times "fmul\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.d\\\[\[0-9\]+\\\]" 3 } } */ + +/* { dg-final { cleanup-saved-temps } } */ + diff --git a/gcc/testsuite/gcc.target/aarch64/mla_intrinsic_1.c b/gcc/testsuite/gcc.target/aarch64/mla_intrinsic_1.c new file mode 100644 index 00000000000..fce41387354 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mla_intrinsic_1.c @@ -0,0 +1,84 @@ +/* { dg-do run } */ +/* { dg-options "-O3 --save-temps" } */ + +#include <arm_neon.h> + +extern void abort (void); + +#define MAPs(size, xx) int##size##xx##_t +#define MAPu(size, xx) uint##size##xx##_t + + +#define TEST_VMLA(q, su, size, in1_lanes, in2_lanes) \ +static void \ +test_vmlaq_lane##q##_##su##size (MAP##su (size, ) * res, \ + const MAP##su(size, ) *in1, \ + const MAP##su(size, ) *in2) \ +{ \ + MAP##su (size, x##in1_lanes) a = vld1q_##su##size (res); \ + MAP##su (size, x##in1_lanes) b = vld1q_##su##size (in1); \ + MAP##su (size, x##in2_lanes) c = vld1##q##_##su##size (in2); \ + a = vmlaq_lane##q##_##su##size (a, b, c, 1); \ + vst1q_##su##size (res, a); \ +} + +#define BUILD_VARS(width, n_lanes, n_half_lanes) \ +TEST_VMLA (, s, width, n_lanes, n_half_lanes) \ +TEST_VMLA (q, s, width, n_lanes, n_lanes) \ +TEST_VMLA (, u, width, n_lanes, n_half_lanes) \ +TEST_VMLA (q, u, width, n_lanes, n_lanes) \ + +BUILD_VARS (32, 4, 2) +BUILD_VARS (16, 8, 4) + +#define POOL4 {0, 1, 2, 3} +#define POOL8 {0, 1, 2, 3, 4, 5, 6, 7} +#define EMPTY4 {0, 0, 0, 0} +#define EMPTY8 {0, 0, 0, 0, 0, 0, 0, 0} + +#define BUILD_TEST(su, size, lanes) \ +static void \ +test_##su##size (void) \ +{ \ + int i; \ + MAP##su (size,) pool[lanes] = POOL##lanes; \ + MAP##su (size,) res[lanes] = EMPTY##lanes; \ + MAP##su (size,) res2[lanes] = EMPTY##lanes; \ + \ + /* Forecfully avoid optimization. */ \ + asm volatile ("" : : : "memory"); \ + test_vmlaq_lane_##su##size (res, pool, pool); \ + for (i = 0; i < lanes; i++) \ + if (res[i] != pool[i]) \ + abort (); \ + \ + /* Forecfully avoid optimization. */ \ + asm volatile ("" : : : "memory"); \ + test_vmlaq_laneq_##su##size (res2, pool, pool); \ + for (i = 0; i < lanes; i++) \ + if (res2[i] != pool[i]) \ + abort (); \ +} + +#undef BUILD_VARS +#define BUILD_VARS(size, lanes) \ +BUILD_TEST (s, size, lanes) \ +BUILD_TEST (u, size, lanes) + +BUILD_VARS (32, 4) +BUILD_VARS (16, 8) + +int +main (int argc, char **argv) +{ + test_s32 (); + test_u32 (); + test_s16 (); + test_u16 (); + return 0; +} + +/* { dg-final { scan-assembler-times "mla\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s\\\[\[0-9\]+\\\]" 4 } } */ +/* { dg-final { scan-assembler-times "mla\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h\\\[\[0-9\]+\\\]" 4 } } */ +/* { dg-final { cleanup-saved-temps } } */ + diff --git a/gcc/testsuite/gcc.target/aarch64/mls_intrinsic_1.c b/gcc/testsuite/gcc.target/aarch64/mls_intrinsic_1.c new file mode 100644 index 00000000000..8bf95b641c8 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mls_intrinsic_1.c @@ -0,0 +1,89 @@ +/* { dg-do run } */ +/* { dg-options "-O3 --save-temps" } */ + +#include <arm_neon.h> + +extern void abort (void); + +#define MAPs(size, xx) int##size##xx##_t +#define MAPu(size, xx) uint##size##xx##_t + + +#define TEST_VMLS(q, su, size, in1_lanes, in2_lanes) \ +static void \ +test_vmlsq_lane##q##_##su##size (MAP##su (size, ) * res, \ + const MAP##su(size, ) *in1, \ + const MAP##su(size, ) *in2) \ +{ \ + MAP##su (size, x##in1_lanes) a = vld1q_##su##size (res); \ + MAP##su (size, x##in1_lanes) b = vld1q_##su##size (in1); \ + MAP##su (size, x##in2_lanes) c = vld1##q##_##su##size (in2); \ + a = vmlsq_lane##q##_##su##size (a, b, c, 1); \ + vst1q_##su##size (res, a); \ +} + +#define BUILD_VARS(width, n_lanes, n_half_lanes) \ +TEST_VMLS (, s, width, n_lanes, n_half_lanes) \ +TEST_VMLS (q, s, width, n_lanes, n_lanes) \ +TEST_VMLS (, u, width, n_lanes, n_half_lanes) \ +TEST_VMLS (q, u, width, n_lanes, n_lanes) \ + +BUILD_VARS (32, 4, 2) +BUILD_VARS (16, 8, 4) + +#define MAP_OPs + +#define MAP_OPu - + +#define POOL4 {0, 1, 2, 3} +#define POOL8 {0, 1, 2, 3, 4, 5, 6, 7} +#define EMPTY4s {0, 0, 0, 0} +#define EMPTY8s {0, 0, 0, 0, 0, 0, 0, 0} +#define EMPTY4u {0, 2, 4, 6} +#define EMPTY8u {0, 2, 4, 6, 8, 10, 12, 14} + +#define BUILD_TEST(su, size, lanes) \ +static void \ +test_##su##size (void) \ +{ \ + int i; \ + MAP##su (size,) pool[lanes] = POOL##lanes; \ + MAP##su (size,) res[lanes] = EMPTY##lanes##su; \ + MAP##su (size,) res2[lanes] = EMPTY##lanes##su; \ + \ + /* Forecfully avoid optimization. */ \ + asm volatile ("" : : : "memory"); \ + test_vmlsq_lane_##su##size (res, pool, pool); \ + for (i = 0; i < lanes; i++) \ + if (res[i] MAP_OP##su pool[i] != 0) \ + abort (); \ + \ + /* Forecfully avoid optimization. */ \ + asm volatile ("" : : : "memory"); \ + test_vmlsq_laneq_##su##size (res2, pool, pool); \ + for (i = 0; i < lanes; i++) \ + if (res2[i] MAP_OP##su pool[i] != 0) \ + abort (); \ +} + +#undef BUILD_VARS +#define BUILD_VARS(size, lanes) \ +BUILD_TEST (s, size, lanes) \ +BUILD_TEST (u, size, lanes) + +BUILD_VARS (32, 4) +BUILD_VARS (16, 8) + +int +main (int argc, char **argv) +{ + test_s32 (); + test_u32 (); + test_s16 (); + test_u16 (); + return 0; +} + +/* { dg-final { scan-assembler-times "mls\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.4s\\\[\[0-9\]+\\\]" 4 } } */ +/* { dg-final { scan-assembler-times "mls\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.8h\\\[\[0-9\]+\\\]" 4 } } */ +/* { dg-final { cleanup-saved-temps } } */ + diff --git a/gcc/testsuite/gcc.target/aarch64/mul_intrinsic_1.c b/gcc/testsuite/gcc.target/aarch64/mul_intrinsic_1.c new file mode 100644 index 00000000000..dabe10e15e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/mul_intrinsic_1.c @@ -0,0 +1,83 @@ +/* { dg-do run } */ +/* { dg-options "-O3 --save-temps" } */ + +#include <arm_neon.h> + +extern void abort (void); + +#define MAPs(size, xx) int##size##xx##_t +#define MAPu(size, xx) uint##size##xx##_t + + +#define TEST_VMUL(q, su, size, in1_lanes, in2_lanes) \ +static void \ +test_vmulq_lane##q##_##su##size (MAP##su (size, ) * res, \ + const MAP##su(size, ) *in1, \ + const MAP##su(size, ) *in2) \ +{ \ + MAP##su (size, x##in1_lanes) a = vld1q_##su##size (in1); \ + MAP##su (size, x##in2_lanes) b = vld1##q##_##su##size (in2); \ + a = vmulq_lane##q##_##su##size (a, b, 1); \ + vst1q_##su##size (res, a); \ +} + +#define BUILD_VARS(width, n_lanes, n_half_lanes) \ +TEST_VMUL (, s, width, n_lanes, n_half_lanes) \ +TEST_VMUL (q, s, width, n_lanes, n_lanes) \ +TEST_VMUL (, u, width, n_lanes, n_half_lanes) \ +TEST_VMUL (q, u, width, n_lanes, n_lanes) \ + +BUILD_VARS (32, 4, 2) +BUILD_VARS (16, 8, 4) + +#define POOL4 {0, 1, 2, 3} +#define POOL8 {0, 1, 2, 3, 4, 5, 6, 7} +#define EMPTY4 {0, 0, 0, 0} +#define EMPTY8 {0, 0, 0, 0, 0, 0, 0, 0} + +#define BUILD_TEST(su, size, lanes) \ +static void \ +test_##su##size (void) \ +{ \ + int i; \ + MAP##su (size,) pool[lanes] = POOL##lanes; \ + MAP##su (size,) res[lanes] = EMPTY##lanes; \ + MAP##su (size,) res2[lanes] = EMPTY##lanes; \ + \ + /* Forecfully avoid optimization. */ \ + asm volatile ("" : : : "memory"); \ + test_vmulq_lane_##su##size (res, pool, pool); \ + for (i = 0; i < lanes; i++) \ + if (res[i] != pool[i]) \ + abort (); \ + \ + /* Forecfully avoid optimization. */ \ + asm volatile ("" : : : "memory"); \ + test_vmulq_laneq_##su##size (res2, pool, pool); \ + for (i = 0; i < lanes; i++) \ + if (res2[i] != pool[i]) \ + abort (); \ +} + +#undef BUILD_VARS +#define BUILD_VARS(size, lanes) \ +BUILD_TEST (s, size, lanes) \ +BUILD_TEST (u, size, lanes) + +BUILD_VARS (32, 4) +BUILD_VARS (16, 8) + +int +main (int argc, char **argv) +{ + test_s32 (); + test_u32 (); + test_s16 (); + test_u16 (); + return 0; +} + +/* { dg-final { scan-assembler-times "mul\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.s\\\[\[0-9\]+\\\]" 4 } } */ +/* { dg-final { scan-assembler-times "mul\\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.h\\\[\[0-9\]+\\\]" 4 } } */ +/* { dg-final { cleanup-saved-temps } } */ + diff --git a/gcc/testsuite/gcc.target/i386/pr58418.c b/gcc/testsuite/gcc.target/i386/pr58418.c new file mode 100644 index 00000000000..27634c9c2f7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr58418.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern void abort (void); +int a, b, *c = &b, d = -1, e, f, *g, *h = &f, **i = &g, j; + +unsigned int +foo (unsigned int p) +{ + return p == 0 ? 0 : 1 / p; +} + +static int * +bar () +{ + *c = *h = foo (d) & (-9 < d); + for (e = 0; e; e++) + ; + return 0; +} + +int +main () +{ + for (; j; j++) + for (;; a--) + ; + *i = bar (); + if (f != 0) + abort (); + return 0; +} diff --git a/gcc/testsuite/gfortran.dg/class_39.f03 b/gcc/testsuite/gfortran.dg/class_39.f03 index 6fe762ba35d..c29a3b06a63 100644 --- a/gcc/testsuite/gfortran.dg/class_39.f03 +++ b/gcc/testsuite/gfortran.dg/class_39.f03 @@ -8,6 +8,6 @@ end type T contains class(T) function add() ! { dg-error "must be dummy, allocatable or pointer" } - add = 1 ! { dg-error "Variable must not be polymorphic in intrinsic assignment" } + add = 1 ! { dg-error "Nonallocatable variable must not be polymorphic in intrinsic assignment" } end function end diff --git a/gcc/testsuite/gfortran.dg/class_5.f03 b/gcc/testsuite/gfortran.dg/class_5.f03 index 087d745aec7..0307cae4f89 100644 --- a/gcc/testsuite/gfortran.dg/class_5.f03 +++ b/gcc/testsuite/gfortran.dg/class_5.f03 @@ -20,7 +20,7 @@ x = t2(45,478) allocate(t2 :: cp) - cp = x ! { dg-error "Variable must not be polymorphic" } + cp = x ! { dg-error "Nonallocatable variable must not be polymorphic" } select type (cp) type is (t2) @@ -28,4 +28,3 @@ end select end -
\ No newline at end of file diff --git a/gcc/testsuite/gfortran.dg/class_53.f90 b/gcc/testsuite/gfortran.dg/class_53.f90 index 0a8c9620808..83f55712d0b 100644 --- a/gcc/testsuite/gfortran.dg/class_53.f90 +++ b/gcc/testsuite/gfortran.dg/class_53.f90 @@ -13,6 +13,6 @@ end type type(arr_t) :: this class(arr_t) :: elem ! { dg-error "must be dummy, allocatable or pointer" } -elem = this ! { dg-error "Variable must not be polymorphic in intrinsic assignment" } +elem = this ! { dg-error "Nonallocatable variable must not be polymorphic in intrinsic assignment" } end diff --git a/gcc/testsuite/gfortran.dg/defined_assignment_11.f90 b/gcc/testsuite/gfortran.dg/defined_assignment_11.f90 new file mode 100644 index 00000000000..ec297d5492a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/defined_assignment_11.f90 @@ -0,0 +1,43 @@ +! { dg-do run } +! +! PR fortran/57697 +! +! Further test of typebound defined assignment +! +module m0 + implicit none + type :: component + integer :: i = 42 + integer, allocatable :: b + contains + procedure :: assign0 + generic :: assignment(=) => assign0 + end type + type, extends(component) :: comp2 + real :: aa + end type comp2 + type parent + type(component) :: foo + real :: cc + end type + type p2 + type(parent) :: x + end type p2 +contains + elemental subroutine assign0(lhs,rhs) + class(component), intent(INout) :: lhs + class(component), intent(in) :: rhs + lhs%i = 20 + end subroutine +end module + +program main + use m0 + implicit none + type(p2), allocatable :: left + type(p2) :: right +! print *, right%x%foo%i + left = right +! print *, left%x%foo%i + if (left%x%foo%i /= 20) call abort() +end diff --git a/gcc/testsuite/gfortran.dg/finalize_19.f90 b/gcc/testsuite/gfortran.dg/finalize_19.f90 new file mode 100644 index 00000000000..1eeb6af658e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/finalize_19.f90 @@ -0,0 +1,21 @@ +! { dg-do compile } +! +! PR fortran/58356 +! +! Contributed by Andrew Benson +! +module ct + type :: cfl + contains + final :: cfld + end type cfl + type, extends(cfl) :: cfde + contains + end type cfde +contains + subroutine cfld(self) + implicit none + type(cfl), intent(inout) :: self + return + end subroutine cfld +end module ct diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_43.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_43.f90 new file mode 100644 index 00000000000..b1f77a06ec6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/proc_ptr_43.f90 @@ -0,0 +1,19 @@ +! { dg-do compile } +! +! PR 58099: [4.8/4.9 Regression] [F03] over-zealous procedure-pointer error checking +! +! Contributed by Daniel Price <daniel.price@monash.edu> + + implicit none + procedure(real), pointer :: wfunc + + wfunc => w_cubic + +contains + + pure real function w_cubic(q2) + real, intent(in) :: q2 + w_cubic = 0. + end function + +end diff --git a/gcc/testsuite/gfortran.dg/realloc_on_assign_20.f90 b/gcc/testsuite/gfortran.dg/realloc_on_assign_20.f90 new file mode 100644 index 00000000000..d4cfaf841c6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/realloc_on_assign_20.f90 @@ -0,0 +1,13 @@ +! { dg-do compile } +! { dg-options "-std=f2003" } +! +! PR fortran/43366 +! +! Invalid assignment to an allocatable polymorphic var. +! +type t +end type t +class(t), allocatable :: var + +var = t() ! { dg-error "Fortran 2008: Assignment to an allocatable polymorphic variable" } +end diff --git a/gcc/testsuite/gfortran.dg/realloc_on_assign_21.f90 b/gcc/testsuite/gfortran.dg/realloc_on_assign_21.f90 new file mode 100644 index 00000000000..fd8f9aca939 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/realloc_on_assign_21.f90 @@ -0,0 +1,13 @@ +! { dg-do compile } +! { dg-options "-fno-realloc-lhs" } +! +! PR fortran/43366 +! +! Invalid assignment to an allocatable polymorphic var. +! +type t +end type t +class(t), allocatable :: var + +var = t() ! { dg-error "Assignment to an allocatable polymorphic variable at .1. requires -frealloc-lhs" } +end diff --git a/gcc/testsuite/gfortran.dg/realloc_on_assign_22.f90 b/gcc/testsuite/gfortran.dg/realloc_on_assign_22.f90 new file mode 100644 index 00000000000..f759c6aca00 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/realloc_on_assign_22.f90 @@ -0,0 +1,13 @@ +! { dg-do compile } +! { dg-options "-fcoarray=single" } +! +! PR fortran/43366 +! +! Invalid assignment to an allocatable polymorphic var. +! +type t +end type t +class(t), allocatable :: caf[:] + +caf = t() ! { dg-error "Assignment to polymorphic coarray at .1. is not permitted" } +end diff --git a/gcc/testsuite/gnat.dg/array_bounds_test2.adb b/gcc/testsuite/gnat.dg/array_bounds_test2.adb new file mode 100644 index 00000000000..43e1ed3ced0 --- /dev/null +++ b/gcc/testsuite/gnat.dg/array_bounds_test2.adb @@ -0,0 +1,25 @@ +-- { dg-do run } + +with Ada.Unchecked_Deallocation; + +procedure Array_Bounds_Test2 is + + type String_Ptr_T is access String; + procedure Free is new Ada.Unchecked_Deallocation (String, String_Ptr_T); + String_Data : String_Ptr_T := new String'("Hello World"); + + function Peek return String_Ptr_T is + begin + return String_Data; + end Peek; + +begin + declare + Corrupted_String : String := Peek.all; + begin + Free(String_Data); + if Corrupted_String'First /= 1 then + raise Program_Error; + end if; + end; +end; diff --git a/gcc/testsuite/gnat.dg/in_out_parameter4.adb b/gcc/testsuite/gnat.dg/in_out_parameter4.adb new file mode 100644 index 00000000000..4f5cc218198 --- /dev/null +++ b/gcc/testsuite/gnat.dg/in_out_parameter4.adb @@ -0,0 +1,30 @@ +-- { dg-do run } +-- { dg-options "-gnat12 -gnatVa" } + +procedure In_Out_Parameter4 is + + type Enum is (E_Undetermined, E_Down, E_Up); + subtype Status_T is Enum range E_Down .. E_Up; + + function Recurse (Val : in out Integer) return Status_T is + + Result : Status_T; + + procedure Dummy (I : in out Integer) is begin null; end; + + begin + if Val > 500 then + Val := Val - 1; + Result := Recurse (Val); + return Result; + else + return E_UP; + end if; + end; + + Val : Integer := 501; + S : Status_T; + +begin + S := Recurse (Val); +end; diff --git a/gcc/testsuite/gnat.dg/opt27.adb b/gcc/testsuite/gnat.dg/opt27.adb new file mode 100644 index 00000000000..be1980076a4 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt27.adb @@ -0,0 +1,29 @@ +-- { dg-do run }
+-- { dg-options "-O" }
+
+with Opt27_Pkg;
+
+procedure Opt27 is
+
+ type Rec_T is record
+ A, B, C, D, E : Integer;
+ end record;
+
+ package List is new Opt27_Pkg (Rec_T);
+
+ My_List : List.List_T;
+
+ function Is_Match (Element : Rec_T; Template : Integer) return Boolean is
+ begin
+ return (Element.C = Template);
+ end;
+
+ function Find_Int is new List.Find_Elem (Integer, Is_Match);
+
+ Node : List.Node_T := Find_Int (10, My_List);
+
+begin
+ if not List.Is_Null (Node) then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/opt27_pkg.adb b/gcc/testsuite/gnat.dg/opt27_pkg.adb new file mode 100644 index 00000000000..17ffb731db2 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt27_pkg.adb @@ -0,0 +1,32 @@ +package body Opt27_Pkg is + + type Node_Rec_T is record + Element : Element_T; + Left : Node_T; + Right : Node_T; + end record; + + function Is_Null (Node : in Node_T) return Boolean is + begin + return (Node = null); + end Is_Null; + + function Find_Elem (Template : Template_T; List : List_T) return Node_T is + Element_Found : Boolean := False; + Node_Walker : Node_T := null; + begin + Node_Walker := List.First_Node; + + while not Element_Found and (Node_Walker /= null) loop + + if Is_Match (Node_Walker.Element, Template) then + Element_Found := True; + else + Node_Walker := Node_Walker.Right; + end if; + end loop; + + return Node_Walker; + end; + +end Opt27_Pkg; diff --git a/gcc/testsuite/gnat.dg/opt27_pkg.ads b/gcc/testsuite/gnat.dg/opt27_pkg.ads new file mode 100644 index 00000000000..01b3a909c6d --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt27_pkg.ads @@ -0,0 +1,33 @@ +generic + + type Element_T is private; + +package Opt27_Pkg is + + type Node_T is private; + + type List_T is private; + + function Is_Null (Node : in Node_T) return Boolean; + + generic + + type Template_T is private; + + with function Is_Match + (Element : in Element_T; + Template : in Template_T) return Boolean is <>; + + function Find_Elem (Template : Template_T; List : List_T) return Node_T; + +private + + type Node_Rec_T; + type Node_T is access Node_Rec_T; + + type List_T is record + First_Node : Node_T := null; + Last_Node : Node_T := null; + end record; + +end Opt27_Pkg; diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 0905821587b..e6e9d7795f0 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -435,9 +435,10 @@ proc check_effective_target_trampolines { } { return 0 } if { [istarget avr-*-*] + || [istarget msp430-*-*] || [istarget hppa2.0w-hp-hpux11.23] - || [istarget hppa64-hp-hpux11.23] } { - return 0; + || [istarget hppa64-hp-hpux11.23] } { + return 0; } return 1 } @@ -535,6 +536,7 @@ proc check_profiling_available { test_what } { || [istarget mmix-*-*] || [istarget mn10300-*-elf*] || [istarget moxie-*-elf*] + || [istarget msp430-*-*] || [istarget picochip-*-*] || [istarget powerpc-*-eabi*] || [istarget powerpc-*-elf] @@ -652,6 +654,11 @@ proc check_effective_target_tls_emulated {} { # Return 1 if TLS executables can run correctly, 0 otherwise. proc check_effective_target_tls_runtime {} { + # MSP430 runtime does not have TLS support, but just + # running the test below is insufficient to show this. + if { [istarget msp430-*-*] } { + return 0 + } return [check_runtime tls_runtime { __thread int thr = 0; int main (void) { return thr; } @@ -2222,7 +2229,7 @@ proc check_effective_target_arm_v8_vfp_ok {} { # options. proc check_effective_target_arm_hard_vfp_ok { } { - if { [check_effective_target_arm32] + if { [check_effective_target_arm32] && ! [check-flags [list "" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" }]] } { return [check_no_compiler_messages arm_hard_vfp_ok executable { int main() { return 0;} diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c index 1ec8f536060..16df51bbbef 100644 --- a/gcc/tree-chrec.c +++ b/gcc/tree-chrec.c @@ -268,9 +268,14 @@ chrec_fold_plus_1 (enum tree_code code, tree type, switch (TREE_CODE (op0)) { case POLYNOMIAL_CHREC: + gcc_checking_assert + (!chrec_contains_symbols_defined_in_loop (op0, CHREC_VARIABLE (op0))); switch (TREE_CODE (op1)) { case POLYNOMIAL_CHREC: + gcc_checking_assert + (!chrec_contains_symbols_defined_in_loop (op1, + CHREC_VARIABLE (op1))); return chrec_fold_plus_poly_poly (code, type, op0, op1); CASE_CONVERT: @@ -298,6 +303,9 @@ chrec_fold_plus_1 (enum tree_code code, tree type, switch (TREE_CODE (op1)) { case POLYNOMIAL_CHREC: + gcc_checking_assert + (!chrec_contains_symbols_defined_in_loop (op1, + CHREC_VARIABLE (op1))); if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR) return build_polynomial_chrec (CHREC_VARIABLE (op1), @@ -396,9 +404,14 @@ chrec_fold_multiply (tree type, switch (TREE_CODE (op0)) { case POLYNOMIAL_CHREC: + gcc_checking_assert + (!chrec_contains_symbols_defined_in_loop (op0, CHREC_VARIABLE (op0))); switch (TREE_CODE (op1)) { case POLYNOMIAL_CHREC: + gcc_checking_assert + (!chrec_contains_symbols_defined_in_loop (op1, + CHREC_VARIABLE (op1))); return chrec_fold_multiply_poly_poly (type, op0, op1); CASE_CONVERT: @@ -431,6 +444,9 @@ chrec_fold_multiply (tree type, switch (TREE_CODE (op1)) { case POLYNOMIAL_CHREC: + gcc_checking_assert + (!chrec_contains_symbols_defined_in_loop (op1, + CHREC_VARIABLE (op1))); return build_polynomial_chrec (CHREC_VARIABLE (op1), chrec_fold_multiply (type, CHREC_LEFT (op1), op0), diff --git a/gcc/tree-core.h b/gcc/tree-core.h index b1bc56ae29f..69777dc2796 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -780,6 +780,9 @@ struct GTY(()) tree_base { OMP_CLAUSE_PRIVATE_DEBUG in OMP_CLAUSE_PRIVATE + OMP_CLAUSE_LINEAR_NO_COPYIN in + OMP_CLAUSE_LINEAR + TRANSACTION_EXPR_RELAXED in TRANSACTION_EXPR @@ -800,6 +803,9 @@ struct GTY(()) tree_base { OMP_CLAUSE_PRIVATE_OUTER_REF in OMP_CLAUSE_PRIVATE + OMP_CLAUSE_LINEAR_NO_COPYOUT in + OMP_CLAUSE_LINEAR + TYPE_REF_IS_RVALUE in REFERENCE_TYPE @@ -935,6 +941,9 @@ struct GTY(()) tree_base { DECL_NONLOCAL_FRAME in VAR_DECL + + TYPE_FINAL_P in + RECORD_TYPE, UNION_TYPE and QUAL_UNION_TYPE */ struct GTY(()) tree_typed { @@ -1197,8 +1206,7 @@ struct GTY(()) tree_decl_common { unsigned lang_flag_7 : 1; unsigned lang_flag_8 : 1; - /* In LABEL_DECL, this is DECL_ERROR_ISSUED. - In VAR_DECL and PARM_DECL, this is DECL_REGISTER. */ + /* In VAR_DECL and PARM_DECL, this is DECL_REGISTER. */ unsigned decl_flag_0 : 1; /* In FIELD_DECL, this is DECL_BIT_FIELD In VAR_DECL and FUNCTION_DECL, this is DECL_EXTERNAL. @@ -1403,6 +1411,9 @@ struct GTY(()) tree_statement_list struct tree_statement_list_node *tail; }; + +/* Optimization options used by a function. */ + struct GTY(()) tree_optimization_option { struct tree_common common; @@ -1418,6 +1429,8 @@ struct GTY(()) tree_optimization_option { struct target_optabs *GTY ((skip)) base_optabs; }; +/* Target options used by a function. */ + struct GTY(()) tree_target_option { struct tree_common common; @@ -1563,6 +1576,8 @@ struct GTY(()) tree_map_base { tree from; }; +/* Map from a tree to another tree. */ + struct GTY(()) tree_map { struct tree_map_base base; unsigned int hash; diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 9c5d979872d..2f64abc2bbd 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -421,9 +421,6 @@ extern bool gimple_seq_may_fallthru (gimple_seq); extern bool gimple_stmt_may_fallthru (gimple); extern bool gimple_check_call_matching_types (gimple, tree, bool); -/* In tree-ssa-uninit.c */ -extern bool ssa_undefined_value_p (tree); - /* In tree-into-ssa.c */ void update_ssa (unsigned); void delete_update_ssa (void); diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 07650971ab3..4851023d27f 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -1789,7 +1789,7 @@ main_tree_if_conversion (void) FOR_EACH_LOOP (li, loop, 0) if (flag_tree_loop_if_convert == 1 || flag_tree_loop_if_convert_stores == 1 - || flag_tree_vectorize + || flag_tree_loop_vectorize || loop->force_vect) changed |= tree_if_conversion (loop); @@ -1815,7 +1815,7 @@ main_tree_if_conversion (void) static bool gate_tree_if_conversion (void) { - return (((flag_tree_vectorize || cfun->has_force_vect_loops) + return (((flag_tree_loop_vectorize || cfun->has_force_vect_loops) && flag_tree_loop_if_convert != 0) || flag_tree_loop_if_convert == 1 || flag_tree_loop_if_convert_stores == 1); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index ebfd34c6dcd..ebb4b918813 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -751,6 +751,20 @@ copy_gimple_bind (gimple stmt, copy_body_data *id) return new_bind; } +/* Return true if DECL is a parameter or a SSA_NAME for a parameter. */ + +static bool +is_parm (tree decl) +{ + if (TREE_CODE (decl) == SSA_NAME) + { + decl = SSA_NAME_VAR (decl); + if (!decl) + return false; + } + + return (TREE_CODE (decl) == PARM_DECL); +} /* Remap the GIMPLE operand pointed to by *TP. DATA is really a 'struct walk_stmt_info *'. DATA->INFO is a 'copy_body_data *'. @@ -840,20 +854,24 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data) if (TREE_CODE (*tp) == MEM_REF) { - tree ptr = TREE_OPERAND (*tp, 0); - tree type = remap_type (TREE_TYPE (*tp), id); - tree old = *tp; - /* We need to re-canonicalize MEM_REFs from inline substitutions that can happen when a pointer argument is an ADDR_EXPR. Recurse here manually to allow that. */ + tree ptr = TREE_OPERAND (*tp, 0); + tree type = remap_type (TREE_TYPE (*tp), id); + tree old = *tp; walk_tree (&ptr, remap_gimple_op_r, data, NULL); - *tp = fold_build2 (MEM_REF, type, - ptr, TREE_OPERAND (*tp, 1)); - TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old); + *tp = fold_build2 (MEM_REF, type, ptr, TREE_OPERAND (*tp, 1)); TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old); TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old); TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old); + /* We cannot propagate the TREE_THIS_NOTRAP flag if we have + remapped a parameter as the property might be valid only + for the parameter itself. */ + if (TREE_THIS_NOTRAP (old) + && (!is_parm (TREE_OPERAND (old, 0)) + || (!id->transform_parameter && is_parm (ptr)))) + TREE_THIS_NOTRAP (*tp) = 1; *walk_subtrees = 0; return NULL; } @@ -1043,45 +1061,44 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data) /* Get rid of *& from inline substitutions that can happen when a pointer argument is an ADDR_EXPR. */ tree decl = TREE_OPERAND (*tp, 0); - tree *n; - - n = (tree *) pointer_map_contains (id->decl_map, decl); + tree *n = (tree *) pointer_map_contains (id->decl_map, decl); if (n) { - tree new_tree; - tree old; /* If we happen to get an ADDR_EXPR in n->value, strip it manually here as we'll eventually get ADDR_EXPRs which lie about their types pointed to. In this case build_fold_indirect_ref wouldn't strip the INDIRECT_REF, but we absolutely rely on that. As fold_indirect_ref does other useful transformations, try that first, though. */ - tree type = TREE_TYPE (TREE_TYPE (*n)); - if (id->do_not_unshare) - new_tree = *n; - else - new_tree = unshare_expr (*n); - old = *tp; - *tp = gimple_fold_indirect_ref (new_tree); + tree type = TREE_TYPE (*tp); + tree ptr = id->do_not_unshare ? *n : unshare_expr (*n); + tree old = *tp; + *tp = gimple_fold_indirect_ref (ptr); if (! *tp) { - if (TREE_CODE (new_tree) == ADDR_EXPR) + if (TREE_CODE (ptr) == ADDR_EXPR) { - *tp = fold_indirect_ref_1 (EXPR_LOCATION (new_tree), - type, new_tree); + *tp + = fold_indirect_ref_1 (EXPR_LOCATION (ptr), type, ptr); /* ??? We should either assert here or build a VIEW_CONVERT_EXPR instead of blindly leaking incompatible types to our IL. */ if (! *tp) - *tp = TREE_OPERAND (new_tree, 0); + *tp = TREE_OPERAND (ptr, 0); } else { - *tp = build1 (INDIRECT_REF, type, new_tree); + *tp = build1 (INDIRECT_REF, type, ptr); TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old); TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old); TREE_READONLY (*tp) = TREE_READONLY (old); - TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old); + /* We cannot propagate the TREE_THIS_NOTRAP flag if we + have remapped a parameter as the property might be + valid only for the parameter itself. */ + if (TREE_THIS_NOTRAP (old) + && (!is_parm (TREE_OPERAND (old, 0)) + || (!id->transform_parameter && is_parm (ptr)))) + TREE_THIS_NOTRAP (*tp) = 1; } } *walk_subtrees = 0; @@ -1090,20 +1107,24 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data) } else if (TREE_CODE (*tp) == MEM_REF) { - tree ptr = TREE_OPERAND (*tp, 0); - tree type = remap_type (TREE_TYPE (*tp), id); - tree old = *tp; - /* We need to re-canonicalize MEM_REFs from inline substitutions that can happen when a pointer argument is an ADDR_EXPR. Recurse here manually to allow that. */ + tree ptr = TREE_OPERAND (*tp, 0); + tree type = remap_type (TREE_TYPE (*tp), id); + tree old = *tp; walk_tree (&ptr, copy_tree_body_r, data, NULL); - *tp = fold_build2 (MEM_REF, type, - ptr, TREE_OPERAND (*tp, 1)); - TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old); + *tp = fold_build2 (MEM_REF, type, ptr, TREE_OPERAND (*tp, 1)); TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old); TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old); TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old); + /* We cannot propagate the TREE_THIS_NOTRAP flag if we have + remapped a parameter as the property might be valid only + for the parameter itself. */ + if (TREE_THIS_NOTRAP (old) + && (!is_parm (TREE_OPERAND (old, 0)) + || (!id->transform_parameter && is_parm (ptr)))) + TREE_THIS_NOTRAP (*tp) = 1; *walk_subtrees = 0; return NULL; } @@ -4452,6 +4473,7 @@ optimize_inline_calls (tree fn) id.transform_call_graph_edges = CB_CGE_DUPLICATE; id.transform_new_cfg = false; id.transform_return_to_modify = true; + id.transform_parameter = true; id.transform_lang_insert_block = NULL; id.statements_to_fold = pointer_set_create (); @@ -4757,6 +4779,7 @@ copy_gimple_seq_and_replace_locals (gimple_seq seq) id.transform_call_graph_edges = CB_CGE_DUPLICATE; id.transform_new_cfg = false; id.transform_return_to_modify = false; + id.transform_parameter = false; id.transform_lang_insert_block = NULL; /* Walk the tree once to find local labels. */ @@ -5216,6 +5239,7 @@ tree_function_versioning (tree old_decl, tree new_decl, = update_clones ? CB_CGE_MOVE_CLONES : CB_CGE_MOVE; id.transform_new_cfg = true; id.transform_return_to_modify = false; + id.transform_parameter = false; id.transform_lang_insert_block = NULL; old_entry_block = ENTRY_BLOCK_PTR_FOR_FUNCTION @@ -5440,6 +5464,7 @@ maybe_inline_call_in_expr (tree exp) id.transform_call_graph_edges = CB_CGE_DUPLICATE; id.transform_new_cfg = false; id.transform_return_to_modify = true; + id.transform_parameter = true; id.transform_lang_insert_block = NULL; /* Make sure not to unshare trees behind the front-end's back diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h index 620ec977768..a78e4b69f0e 100644 --- a/gcc/tree-inline.h +++ b/gcc/tree-inline.h @@ -97,6 +97,10 @@ typedef struct copy_body_data by manipulating the CFG rather than a statement. */ bool transform_return_to_modify; + /* True if the parameters of the source function are transformed. + Only true for inlining. */ + bool transform_parameter; + /* True if this statement will need to be regimplified. */ bool regimplify; diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 726744d5003..384d3b33cff 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -1399,14 +1399,22 @@ rewrite_add_phi_arguments (basic_block bb) } } +class rewrite_dom_walker : public dom_walker +{ +public: + rewrite_dom_walker (cdi_direction direction) : dom_walker (direction) {} + + virtual void before_dom_children (basic_block); + virtual void after_dom_children (basic_block); +}; + /* SSA Rewriting Step 1. Initialization, create a block local stack of reaching definitions for new SSA names produced in this block (BLOCK_DEFS). Register new definitions for every PHI node in the block. */ -static void -rewrite_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, - basic_block bb) +void +rewrite_dom_walker::before_dom_children (basic_block bb) { gimple_stmt_iterator gsi; @@ -1444,9 +1452,8 @@ rewrite_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, /* Called after visiting all the statements in basic block BB and all of its dominator children. Restore CURRDEFS to its original value. */ -static void -rewrite_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, - basic_block bb ATTRIBUTE_UNUSED) +void +rewrite_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED) { /* Restore CURRDEFS to its original state. */ while (block_defs_stack.length () > 0) @@ -2065,15 +2072,22 @@ rewrite_update_phi_arguments (basic_block bb) } } +class rewrite_update_dom_walker : public dom_walker +{ +public: + rewrite_update_dom_walker (cdi_direction direction) : dom_walker (direction) {} + + virtual void before_dom_children (basic_block); + virtual void after_dom_children (basic_block); +}; /* Initialization of block data structures for the incremental SSA update pass. Create a block local stack of reaching definitions for new SSA names produced in this block (BLOCK_DEFS). Register new definitions for every PHI node in the block. */ -static void -rewrite_update_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, - basic_block bb) +void +rewrite_update_dom_walker::before_dom_children (basic_block bb) { bool is_abnormal_phi; gimple_stmt_iterator gsi; @@ -2146,9 +2160,8 @@ rewrite_update_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, unwinding must be done in the opposite order to what is done in register_new_update_set. */ -static void -rewrite_update_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, - basic_block bb ATTRIBUTE_UNUSED) +void +rewrite_update_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED) { while (block_defs_stack.length () > 0) { @@ -2183,41 +2196,20 @@ rewrite_update_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, static void rewrite_blocks (basic_block entry, enum rewrite_mode what) { - struct dom_walk_data walk_data; - /* Rewrite all the basic blocks in the program. */ timevar_push (TV_TREE_SSA_REWRITE_BLOCKS); - /* Setup callbacks for the generic dominator tree walker. */ - memset (&walk_data, 0, sizeof (walk_data)); - - walk_data.dom_direction = CDI_DOMINATORS; + block_defs_stack.create (10); + /* Recursively walk the dominator tree rewriting each statement in + each basic block. */ if (what == REWRITE_ALL) - { - walk_data.before_dom_children = rewrite_enter_block; - walk_data.after_dom_children = rewrite_leave_block; - } + rewrite_dom_walker (CDI_DOMINATORS).walk (entry); else if (what == REWRITE_UPDATE) - { - walk_data.before_dom_children = rewrite_update_enter_block; - walk_data.after_dom_children = rewrite_update_leave_block; - } + rewrite_update_dom_walker (CDI_DOMINATORS).walk (entry); else gcc_unreachable (); - block_defs_stack.create (10); - - /* Initialize the dominator walker. */ - init_walk_dominator_tree (&walk_data); - - /* Recursively walk the dominator tree rewriting each statement in - each basic block. */ - walk_dominator_tree (&walk_data, entry); - - /* Finalize the dominator walker. */ - fini_walk_dominator_tree (&walk_data); - /* Debugging dumps. */ if (dump_file && (dump_flags & TDF_STATS)) { @@ -2231,69 +2223,44 @@ rewrite_blocks (basic_block entry, enum rewrite_mode what) timevar_pop (TV_TREE_SSA_REWRITE_BLOCKS); } - -/* Block processing routine for mark_def_sites. Clear the KILLS bitmap - at the start of each block, and call mark_def_sites for each statement. */ - -static void -mark_def_sites_block (struct dom_walk_data *walk_data, basic_block bb) +class mark_def_dom_walker : public dom_walker { - struct mark_def_sites_global_data *gd; - bitmap kills; - gimple_stmt_iterator gsi; - - gd = (struct mark_def_sites_global_data *) walk_data->global_data; - kills = gd->kills; - - bitmap_clear (kills); - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - mark_def_sites (bb, gsi_stmt (gsi), kills); -} - - -/* Mark the definition site blocks for each variable, so that we know - where the variable is actually live. - - The INTERESTING_BLOCKS global will be filled in with all the blocks - that should be processed by the renamer. It is assumed that the - caller has already initialized and zeroed it. */ - -static void -mark_def_site_blocks (void) -{ - struct dom_walk_data walk_data; - struct mark_def_sites_global_data mark_def_sites_global_data; +public: + mark_def_dom_walker (cdi_direction direction); + ~mark_def_dom_walker (); - /* Setup callbacks for the generic dominator tree walker to find and - mark definition sites. */ - walk_data.dom_direction = CDI_DOMINATORS; - walk_data.initialize_block_local_data = NULL; - walk_data.before_dom_children = mark_def_sites_block; - walk_data.after_dom_children = NULL; + virtual void before_dom_children (basic_block); +private: /* Notice that this bitmap is indexed using variable UIDs, so it must be large enough to accommodate all the variables referenced in the function, not just the ones we are renaming. */ - mark_def_sites_global_data.kills = BITMAP_ALLOC (NULL); - walk_data.global_data = &mark_def_sites_global_data; + bitmap kills_; +}; - /* We do not have any local data. */ - walk_data.block_local_data_size = 0; +mark_def_dom_walker::mark_def_dom_walker (cdi_direction direction) + : dom_walker (direction), kills_ (BITMAP_ALLOC (NULL)) +{ +} - /* Initialize the dominator walker. */ - init_walk_dominator_tree (&walk_data); +mark_def_dom_walker::~mark_def_dom_walker () +{ + BITMAP_FREE (kills_); +} - /* Recursively walk the dominator tree. */ - walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); +/* Block processing routine for mark_def_sites. Clear the KILLS bitmap + at the start of each block, and call mark_def_sites for each statement. */ - /* Finalize the dominator walker. */ - fini_walk_dominator_tree (&walk_data); +void +mark_def_dom_walker::before_dom_children (basic_block bb) +{ + gimple_stmt_iterator gsi; - /* We no longer need this bitmap, clear and free it. */ - BITMAP_FREE (mark_def_sites_global_data.kills); + bitmap_clear (kills_); + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + mark_def_sites (bb, gsi_stmt (gsi), kills_); } - /* Initialize internal data needed during renaming. */ static void @@ -2331,8 +2298,7 @@ fini_ssa_renamer (void) insert PHI nodes and rename the function in dominator tree order. - 2- Find and mark all the blocks that define variables - (mark_def_site_blocks). + 2- Find and mark all the blocks that define variables. 3- Insert PHI nodes at dominance frontiers (insert_phi_nodes). @@ -2370,7 +2336,7 @@ rewrite_into_ssa (void) compute_dominance_frontiers (dfs); /* 2- Find and mark definition sites. */ - mark_def_site_blocks (); + mark_def_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr); /* 3- Insert PHI nodes at dominance frontiers of definition blocks. */ insert_phi_nodes (dfs); diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index e3e4e12b025..7482d8c68bc 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -1676,6 +1676,17 @@ tree_loop_distribution (void) for (i = 0; i < loop->num_nodes; ++i) { gimple_stmt_iterator gsi; + for (gsi = gsi_start_phis (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple phi = gsi_stmt (gsi); + if (virtual_operand_p (gimple_phi_result (phi))) + continue; + /* Distribute stmts which have defs that are used outside of + the loop. */ + if (!stmt_has_scalar_dependences_outside_loop (loop, phi)) + continue; + work_list.safe_push (phi); + } for (gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple stmt = gsi_stmt (gsi); diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index a55447d2c96..f15f91c31a4 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -1648,6 +1648,8 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt, chrec2 = analyze_scalar_evolution (loop, rhs2); chrec1 = chrec_convert (type, chrec1, at_stmt); chrec2 = chrec_convert (TREE_TYPE (rhs2), chrec2, at_stmt); + chrec1 = instantiate_parameters (loop, chrec1); + chrec2 = instantiate_parameters (loop, chrec2); res = chrec_fold_plus (type, chrec1, chrec2); } else @@ -1661,6 +1663,7 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt, { chrec2 = analyze_scalar_evolution (loop, offset); chrec2 = chrec_convert (TREE_TYPE (offset), chrec2, at_stmt); + chrec2 = instantiate_parameters (loop, chrec2); res = chrec_fold_plus (type, res, chrec2); } @@ -1671,6 +1674,7 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt, unitpos = size_int (bitpos / BITS_PER_UNIT); chrec3 = analyze_scalar_evolution (loop, unitpos); chrec3 = chrec_convert (TREE_TYPE (unitpos), chrec3, at_stmt); + chrec3 = instantiate_parameters (loop, chrec3); res = chrec_fold_plus (type, res, chrec3); } } @@ -1683,6 +1687,8 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt, chrec2 = analyze_scalar_evolution (loop, rhs2); chrec1 = chrec_convert (type, chrec1, at_stmt); chrec2 = chrec_convert (TREE_TYPE (rhs2), chrec2, at_stmt); + chrec1 = instantiate_parameters (loop, chrec1); + chrec2 = instantiate_parameters (loop, chrec2); res = chrec_fold_plus (type, chrec1, chrec2); break; @@ -1691,6 +1697,8 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt, chrec2 = analyze_scalar_evolution (loop, rhs2); chrec1 = chrec_convert (type, chrec1, at_stmt); chrec2 = chrec_convert (type, chrec2, at_stmt); + chrec1 = instantiate_parameters (loop, chrec1); + chrec2 = instantiate_parameters (loop, chrec2); res = chrec_fold_plus (type, chrec1, chrec2); break; @@ -1699,6 +1707,8 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt, chrec2 = analyze_scalar_evolution (loop, rhs2); chrec1 = chrec_convert (type, chrec1, at_stmt); chrec2 = chrec_convert (type, chrec2, at_stmt); + chrec1 = instantiate_parameters (loop, chrec1); + chrec2 = instantiate_parameters (loop, chrec2); res = chrec_fold_minus (type, chrec1, chrec2); break; @@ -1706,6 +1716,7 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt, chrec1 = analyze_scalar_evolution (loop, rhs1); chrec1 = chrec_convert (type, chrec1, at_stmt); /* TYPE may be integer, real or complex, so use fold_convert. */ + chrec1 = instantiate_parameters (loop, chrec1); res = chrec_fold_multiply (type, chrec1, fold_convert (type, integer_minus_one_node)); break; @@ -1714,6 +1725,7 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt, /* Handle ~X as -1 - X. */ chrec1 = analyze_scalar_evolution (loop, rhs1); chrec1 = chrec_convert (type, chrec1, at_stmt); + chrec1 = instantiate_parameters (loop, chrec1); res = chrec_fold_minus (type, fold_convert (type, integer_minus_one_node), chrec1); @@ -1724,6 +1736,8 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt, chrec2 = analyze_scalar_evolution (loop, rhs2); chrec1 = chrec_convert (type, chrec1, at_stmt); chrec2 = chrec_convert (type, chrec2, at_stmt); + chrec1 = instantiate_parameters (loop, chrec1); + chrec2 = instantiate_parameters (loop, chrec2); res = chrec_fold_multiply (type, chrec1, chrec2); break; @@ -2057,78 +2071,56 @@ struct instantiate_cache_entry tree chrec; }; -struct instantiate_cache_entry_hasher : typed_noop_remove <uintptr_t> -{ - typedef uintptr_t value_type; - typedef instantiate_cache_entry compare_type; - static inline hashval_t hash (const value_type *); - static inline bool equal (const value_type *, const compare_type *); -}; - struct instantiate_cache_type { - hash_table <instantiate_cache_entry_hasher> htab; + pointer_map<unsigned> *map; vec<instantiate_cache_entry> entries; + instantiate_cache_type () : map (NULL), entries(vNULL) {} ~instantiate_cache_type (); + tree get (unsigned slot) { return entries[slot].chrec; } + void set (unsigned slot, tree chrec) { entries[slot].chrec = chrec; } }; instantiate_cache_type::~instantiate_cache_type () { - if (htab.is_created ()) + if (map != NULL) { - htab.dispose (); + delete map; entries.release (); } } -static instantiate_cache_type *ctbl; - -inline hashval_t -instantiate_cache_entry_hasher::hash (const value_type *idx) -{ - instantiate_cache_entry *elt - = &ctbl->entries[reinterpret_cast <uintptr_t> (idx) - 2]; - return SSA_NAME_VERSION (elt->name); -} - -inline bool -instantiate_cache_entry_hasher::equal (const value_type *idx1, - const compare_type *elt2) -{ - compare_type *elt1 = &ctbl->entries[reinterpret_cast <uintptr_t> (idx1) - 2]; - return elt1->name == elt2->name; -} - -/* Returns from CACHE a pointer to the cached chrec for NAME. */ +/* Returns from CACHE the slot number of the cached chrec for NAME. */ -static tree * +static unsigned get_instantiated_value_entry (instantiate_cache_type &cache, tree name) { - struct instantiate_cache_entry e; - uintptr_t **slot; - - if (!cache.htab.is_created ()) + if (!cache.map) { - cache.htab.create (10); + cache.map = new pointer_map<unsigned>; cache.entries.create (10); } - ctbl = &cache; - - e.name = name; - slot = cache.htab.find_slot_with_hash (&e, SSA_NAME_VERSION (name), INSERT); - if (!*slot) + bool existed_p; + unsigned *slot = cache.map->insert (name, &existed_p); + if (!existed_p) { + struct instantiate_cache_entry e; + e.name = name; e.chrec = chrec_not_analyzed_yet; + *slot = cache.entries.length (); cache.entries.safe_push (e); - *slot = reinterpret_cast <uintptr_t *> - ((uintptr_t) cache.entries.length () + 1); } - return &cache.entries[reinterpret_cast <uintptr_t> (*slot) - 2].chrec; + return *slot; } +/* Cache to avoid infinite recursion when instantiating an SSA name. + Live during the outermost instantiate_scev or resolve_mixers call. */ +static instantiate_cache_type *global_cache; + + /* Return the closed_loop_phi node for VAR. If there is none, return NULL_TREE. */ @@ -2160,7 +2152,7 @@ loop_closed_phi_def (tree var) } static tree instantiate_scev_r (basic_block, struct loop *, struct loop *, - tree, bool, instantiate_cache_type &, int); + tree, bool, int); /* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW and EVOLUTION_LOOP, that were left under a symbolic form. @@ -2180,7 +2172,7 @@ static tree instantiate_scev_name (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, - bool fold_conversions, instantiate_cache_type &cache, + bool fold_conversions, int size_expr) { tree res; @@ -2203,13 +2195,12 @@ instantiate_scev_name (basic_block instantiate_below, | a_2 -> {0, +, 1, +, a_2}_1 */ - tree *si; - si = get_instantiated_value_entry (cache, chrec); - if (*si != chrec_not_analyzed_yet) - return *si; + unsigned si = get_instantiated_value_entry (*global_cache, chrec); + if (global_cache->get (si) != chrec_not_analyzed_yet) + return global_cache->get (si); /* On recursion return chrec_dont_know. */ - *si = chrec_dont_know; + global_cache->set (si, chrec_dont_know); def_loop = find_common_loop (evolution_loop, def_bb->loop_father); @@ -2242,7 +2233,7 @@ instantiate_scev_name (basic_block instantiate_below, res = compute_overall_effect_of_inner_loop (loop, res); res = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, res, - fold_conversions, cache, size_expr); + fold_conversions, size_expr); } else if (!dominated_by_p (CDI_DOMINATORS, instantiate_below, gimple_bb (SSA_NAME_DEF_STMT (res)))) @@ -2259,11 +2250,11 @@ instantiate_scev_name (basic_block instantiate_below, else res = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, res, - fold_conversions, cache, size_expr); + fold_conversions, size_expr); } /* Store the correct value to the cache. */ - *si = res; + global_cache->set (si, res); return res; } @@ -2284,21 +2275,19 @@ instantiate_scev_name (basic_block instantiate_below, static tree instantiate_scev_poly (basic_block instantiate_below, struct loop *evolution_loop, struct loop *, - tree chrec, - bool fold_conversions, instantiate_cache_type &cache, - int size_expr) + tree chrec, bool fold_conversions, int size_expr) { tree op1; tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, get_chrec_loop (chrec), - CHREC_LEFT (chrec), fold_conversions, cache, + CHREC_LEFT (chrec), fold_conversions, size_expr); if (op0 == chrec_dont_know) return chrec_dont_know; op1 = instantiate_scev_r (instantiate_below, evolution_loop, get_chrec_loop (chrec), - CHREC_RIGHT (chrec), fold_conversions, cache, + CHREC_RIGHT (chrec), fold_conversions, size_expr); if (op1 == chrec_dont_know) return chrec_dont_know; @@ -2332,20 +2321,16 @@ instantiate_scev_binary (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, enum tree_code code, tree type, tree c0, tree c1, - bool fold_conversions, - instantiate_cache_type &cache, - int size_expr) + bool fold_conversions, int size_expr) { tree op1; tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, - c0, fold_conversions, cache, - size_expr); + c0, fold_conversions, size_expr); if (op0 == chrec_dont_know) return chrec_dont_know; op1 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, - c1, fold_conversions, cache, - size_expr); + c1, fold_conversions, size_expr); if (op1 == chrec_dont_know) return chrec_dont_know; @@ -2392,15 +2377,13 @@ instantiate_scev_binary (basic_block instantiate_below, static tree instantiate_array_ref (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, - tree chrec, - bool fold_conversions, instantiate_cache_type &cache, - int size_expr) + tree chrec, bool fold_conversions, int size_expr) { tree res; tree index = TREE_OPERAND (chrec, 1); tree op1 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, index, - fold_conversions, cache, size_expr); + fold_conversions, size_expr); if (op1 == chrec_dont_know) return chrec_dont_know; @@ -2431,14 +2414,12 @@ instantiate_array_ref (basic_block instantiate_below, static tree instantiate_scev_convert (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, - tree chrec, - tree type, tree op, - bool fold_conversions, - instantiate_cache_type &cache, int size_expr) + tree chrec, tree type, tree op, + bool fold_conversions, int size_expr) { tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, op, - fold_conversions, cache, size_expr); + fold_conversions, size_expr); if (op0 == chrec_dont_know) return chrec_dont_know; @@ -2483,12 +2464,11 @@ instantiate_scev_not (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, enum tree_code code, tree type, tree op, - bool fold_conversions, instantiate_cache_type &cache, - int size_expr) + bool fold_conversions, int size_expr) { tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, op, - fold_conversions, cache, size_expr); + fold_conversions, size_expr); if (op0 == chrec_dont_know) return chrec_dont_know; @@ -2533,25 +2513,24 @@ static tree instantiate_scev_3 (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, - bool fold_conversions, instantiate_cache_type &cache, - int size_expr) + bool fold_conversions, int size_expr) { tree op1, op2; tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, TREE_OPERAND (chrec, 0), - fold_conversions, cache, size_expr); + fold_conversions, size_expr); if (op0 == chrec_dont_know) return chrec_dont_know; op1 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, TREE_OPERAND (chrec, 1), - fold_conversions, cache, size_expr); + fold_conversions, size_expr); if (op1 == chrec_dont_know) return chrec_dont_know; op2 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, TREE_OPERAND (chrec, 2), - fold_conversions, cache, size_expr); + fold_conversions, size_expr); if (op2 == chrec_dont_know) return chrec_dont_know; @@ -2582,19 +2561,18 @@ static tree instantiate_scev_2 (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, - bool fold_conversions, instantiate_cache_type &cache, - int size_expr) + bool fold_conversions, int size_expr) { tree op1; tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, TREE_OPERAND (chrec, 0), - fold_conversions, cache, size_expr); + fold_conversions, size_expr); if (op0 == chrec_dont_know) return chrec_dont_know; op1 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, TREE_OPERAND (chrec, 1), - fold_conversions, cache, size_expr); + fold_conversions, size_expr); if (op1 == chrec_dont_know) return chrec_dont_know; @@ -2623,12 +2601,11 @@ static tree instantiate_scev_1 (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, - bool fold_conversions, instantiate_cache_type &cache, - int size_expr) + bool fold_conversions, int size_expr) { tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop, TREE_OPERAND (chrec, 0), - fold_conversions, cache, size_expr); + fold_conversions, size_expr); if (op0 == chrec_dont_know) return chrec_dont_know; @@ -2657,8 +2634,7 @@ static tree instantiate_scev_r (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, - bool fold_conversions, instantiate_cache_type &cache, - int size_expr) + bool fold_conversions, int size_expr) { /* Give up if the expression is larger than the MAX that we allow. */ if (size_expr++ > PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE)) @@ -2674,12 +2650,12 @@ instantiate_scev_r (basic_block instantiate_below, case SSA_NAME: return instantiate_scev_name (instantiate_below, evolution_loop, inner_loop, chrec, - fold_conversions, cache, size_expr); + fold_conversions, size_expr); case POLYNOMIAL_CHREC: return instantiate_scev_poly (instantiate_below, evolution_loop, inner_loop, chrec, - fold_conversions, cache, size_expr); + fold_conversions, size_expr); case POINTER_PLUS_EXPR: case PLUS_EXPR: @@ -2690,13 +2666,13 @@ instantiate_scev_r (basic_block instantiate_below, TREE_CODE (chrec), chrec_type (chrec), TREE_OPERAND (chrec, 0), TREE_OPERAND (chrec, 1), - fold_conversions, cache, size_expr); + fold_conversions, size_expr); CASE_CONVERT: return instantiate_scev_convert (instantiate_below, evolution_loop, inner_loop, chrec, TREE_TYPE (chrec), TREE_OPERAND (chrec, 0), - fold_conversions, cache, size_expr); + fold_conversions, size_expr); case NEGATE_EXPR: case BIT_NOT_EXPR: @@ -2704,7 +2680,7 @@ instantiate_scev_r (basic_block instantiate_below, inner_loop, chrec, TREE_CODE (chrec), TREE_TYPE (chrec), TREE_OPERAND (chrec, 0), - fold_conversions, cache, size_expr); + fold_conversions, size_expr); case ADDR_EXPR: case SCEV_NOT_KNOWN: @@ -2716,7 +2692,7 @@ instantiate_scev_r (basic_block instantiate_below, case ARRAY_REF: return instantiate_array_ref (instantiate_below, evolution_loop, inner_loop, chrec, - fold_conversions, cache, size_expr); + fold_conversions, size_expr); default: break; @@ -2730,17 +2706,17 @@ instantiate_scev_r (basic_block instantiate_below, case 3: return instantiate_scev_3 (instantiate_below, evolution_loop, inner_loop, chrec, - fold_conversions, cache, size_expr); + fold_conversions, size_expr); case 2: return instantiate_scev_2 (instantiate_below, evolution_loop, inner_loop, chrec, - fold_conversions, cache, size_expr); + fold_conversions, size_expr); case 1: return instantiate_scev_1 (instantiate_below, evolution_loop, inner_loop, chrec, - fold_conversions, cache, size_expr); + fold_conversions, size_expr); case 0: return chrec; @@ -2764,7 +2740,6 @@ instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop, tree chrec) { tree res; - instantiate_cache_type cache; if (dump_file && (dump_flags & TDF_SCEV)) { @@ -2776,8 +2751,21 @@ instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop, fprintf (dump_file, ")\n"); } + bool destr = false; + if (!global_cache) + { + global_cache = new instantiate_cache_type; + destr = true; + } + res = instantiate_scev_r (instantiate_below, evolution_loop, - NULL, chrec, false, cache, 0); + NULL, chrec, false, 0); + + if (destr) + { + delete global_cache; + global_cache = NULL; + } if (dump_file && (dump_flags & TDF_SCEV)) { @@ -2797,9 +2785,22 @@ instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop, tree resolve_mixers (struct loop *loop, tree chrec) { - instantiate_cache_type cache; + bool destr = false; + if (!global_cache) + { + global_cache = new instantiate_cache_type; + destr = true; + } + tree ret = instantiate_scev_r (block_before_loop (loop), loop, NULL, - chrec, true, cache, 0); + chrec, true, 0); + + if (destr) + { + delete global_cache; + global_cache = NULL; + } + return ret; } diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index e02a56662b9..f5613862dcf 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -244,9 +244,6 @@ static void record_equivalences_from_phis (basic_block); static void record_equivalences_from_incoming_edge (basic_block); static void eliminate_redundant_computations (gimple_stmt_iterator *); static void record_equivalences_from_stmt (gimple, int); -static void dom_thread_across_edge (struct dom_walk_data *, edge); -static void dom_opt_leave_block (struct dom_walk_data *, basic_block); -static void dom_opt_enter_block (struct dom_walk_data *, basic_block); static void remove_local_expressions_from_table (void); static void restore_vars_to_original_value (void); static edge single_incoming_edge_ignoring_loop_edges (basic_block); @@ -773,6 +770,21 @@ free_all_edge_infos (void) } } +class dom_opt_dom_walker : public dom_walker +{ +public: + dom_opt_dom_walker (cdi_direction direction) + : dom_walker (direction), dummy_cond_ (NULL) {} + + virtual void before_dom_children (basic_block); + virtual void after_dom_children (basic_block); + +private: + void thread_across_edge (edge); + + gimple dummy_cond_; +}; + /* Jump threading, redundancy elimination and const/copy propagation. This pass may expose new symbols that need to be renamed into SSA. For @@ -782,8 +794,6 @@ free_all_edge_infos (void) static unsigned int tree_ssa_dominator_optimize (void) { - struct dom_walk_data walk_data; - memset (&opt_stats, 0, sizeof (opt_stats)); /* Create our hash tables. */ @@ -792,20 +802,6 @@ tree_ssa_dominator_optimize (void) const_and_copies_stack.create (20); need_eh_cleanup = BITMAP_ALLOC (NULL); - /* Setup callbacks for the generic dominator tree walker. */ - walk_data.dom_direction = CDI_DOMINATORS; - walk_data.initialize_block_local_data = NULL; - walk_data.before_dom_children = dom_opt_enter_block; - walk_data.after_dom_children = dom_opt_leave_block; - /* Right now we only attach a dummy COND_EXPR to the global data pointer. - When we attach more stuff we'll need to fill this out with a real - structure. */ - walk_data.global_data = NULL; - walk_data.block_local_data_size = 0; - - /* Now initialize the dominator walker. */ - init_walk_dominator_tree (&walk_data); - calculate_dominance_info (CDI_DOMINATORS); cfg_altered = false; @@ -824,7 +820,7 @@ tree_ssa_dominator_optimize (void) mark_dfs_back_edges (); /* Recursively walk the dominator tree optimizing statements. */ - walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); + dom_opt_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr); { gimple_stmt_iterator gsi; @@ -897,9 +893,6 @@ tree_ssa_dominator_optimize (void) /* Delete our main hashtable. */ avail_exprs.dispose (); - /* And finalize the dominator walker. */ - fini_walk_dominator_tree (&walk_data); - /* Free asserted bitmaps and stacks. */ BITMAP_FREE (need_eh_cleanup); @@ -1077,25 +1070,65 @@ simplify_stmt_for_jump_threading (gimple stmt, return lookup_avail_expr (stmt, false); } +static void +record_temporary_equivalences (edge e) +{ + int i; + struct edge_info *edge_info = (struct edge_info *) e->aux; + + /* If we have info associated with this edge, record it into + our equivalence tables. */ + if (edge_info) + { + cond_equivalence *eq; + tree lhs = edge_info->lhs; + tree rhs = edge_info->rhs; + + /* If we have a simple NAME = VALUE equivalence, record it. */ + if (lhs && TREE_CODE (lhs) == SSA_NAME) + record_const_or_copy (lhs, rhs); + + /* If we have 0 = COND or 1 = COND equivalences, record them + into our expression hash tables. */ + for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i) + record_cond (eq); + } +} + /* Wrapper for common code to attempt to thread an edge. For example, it handles lazily building the dummy condition and the bookkeeping when jump threading is successful. */ -static void -dom_thread_across_edge (struct dom_walk_data *walk_data, edge e) +void +dom_opt_dom_walker::thread_across_edge (edge e) { - if (! walk_data->global_data) - { - gimple dummy_cond = + if (! dummy_cond_) + dummy_cond_ = gimple_build_cond (NE_EXPR, integer_zero_node, integer_zero_node, NULL, NULL); - walk_data->global_data = dummy_cond; - } - thread_across_edge ((gimple) walk_data->global_data, e, false, - &const_and_copies_stack, - simplify_stmt_for_jump_threading); + /* Push a marker on both stacks so we can unwind the tables back to their + current state. */ + avail_exprs_stack.safe_push (NULL); + const_and_copies_stack.safe_push (NULL_TREE); + + /* Traversing E may result in equivalences we can utilize. */ + record_temporary_equivalences (e); + + /* With all the edge equivalences in the tables, go ahead and attempt + to thread through E->dest. */ + ::thread_across_edge (dummy_cond_, e, false, + &const_and_copies_stack, + simplify_stmt_for_jump_threading); + + /* And restore the various tables to their state before + we threaded this edge. + + XXX The code in tree-ssa-threadedge.c will restore the state of + the const_and_copies table. We we just have to restore the expression + table. */ + remove_local_expressions_from_table (); } /* PHI nodes can create equivalences too. @@ -1235,7 +1268,7 @@ record_equivalences_from_incoming_edge (basic_block bb) /* If the conversion widens the original value and the constant is in the range of the type of OLD_RHS, - then convert the constant and record the equivalence. + then convert the constant and record the equivalence. Note that int_fits_type_p does not check the precision if the upper and lower bounds are OK. */ @@ -1642,6 +1675,28 @@ cprop_into_successor_phis (basic_block bb) if (gsi_end_p (gsi)) continue; + /* We may have an equivalence associated with this edge. While + we can not propagate it into non-dominated blocks, we can + propagate them into PHIs in non-dominated blocks. */ + + /* Push the unwind marker so we can reset the const and copies + table back to its original state after processing this edge. */ + const_and_copies_stack.safe_push (NULL_TREE); + + /* Extract and record any simple NAME = VALUE equivalences. + + Don't bother with [01] = COND equivalences, they're not useful + here. */ + struct edge_info *edge_info = (struct edge_info *) e->aux; + if (edge_info) + { + tree lhs = edge_info->lhs; + tree rhs = edge_info->rhs; + + if (lhs && TREE_CODE (lhs) == SSA_NAME) + record_const_or_copy (lhs, rhs); + } + indx = e->dest_idx; for ( ; !gsi_end_p (gsi); gsi_next (&gsi)) { @@ -1667,6 +1722,8 @@ cprop_into_successor_phis (basic_block bb) && may_propagate_copy (orig_val, new_val)) propagate_value (orig_p, new_val); } + + restore_vars_to_original_value (); } } @@ -1840,9 +1897,8 @@ record_edge_info (basic_block bb) } } -static void -dom_opt_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, - basic_block bb) +void +dom_opt_dom_walker::before_dom_children (basic_block bb) { gimple_stmt_iterator gsi; @@ -1879,8 +1935,8 @@ dom_opt_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, any finalization actions in preparation for leaving this node in the dominator tree. */ -static void -dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb) +void +dom_opt_dom_walker::after_dom_children (basic_block bb) { gimple last; @@ -1892,10 +1948,7 @@ dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb) && (single_succ_edge (bb)->flags & EDGE_ABNORMAL) == 0 && potentially_threadable_block (single_succ (bb))) { - /* Push a marker on the stack, which thread_across_edge expects - and will remove. */ - const_and_copies_stack.safe_push (NULL_TREE); - dom_thread_across_edge (walk_data, single_succ_edge (bb)); + thread_across_edge (single_succ_edge (bb)); } else if ((last = last_stmt (bb)) && gimple_code (last) == GIMPLE_COND @@ -1910,79 +1963,15 @@ dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb) /* Only try to thread the edge if it reaches a target block with more than one predecessor and more than one successor. */ if (potentially_threadable_block (true_edge->dest)) - { - struct edge_info *edge_info; - unsigned int i; - - /* Push a marker onto the available expression stack so that we - unwind any expressions related to the TRUE arm before processing - the false arm below. */ - avail_exprs_stack.safe_push (NULL); - const_and_copies_stack.safe_push (NULL_TREE); - - edge_info = (struct edge_info *) true_edge->aux; - - /* If we have info associated with this edge, record it into - our equivalence tables. */ - if (edge_info) - { - cond_equivalence *eq; - tree lhs = edge_info->lhs; - tree rhs = edge_info->rhs; - - /* If we have a simple NAME = VALUE equivalence, record it. */ - if (lhs && TREE_CODE (lhs) == SSA_NAME) - record_const_or_copy (lhs, rhs); - - /* If we have 0 = COND or 1 = COND equivalences, record them - into our expression hash tables. */ - for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i) - record_cond (eq); - } - - dom_thread_across_edge (walk_data, true_edge); - - /* And restore the various tables to their state before - we threaded this edge. */ - remove_local_expressions_from_table (); - } + thread_across_edge (true_edge); /* Similarly for the ELSE arm. */ if (potentially_threadable_block (false_edge->dest)) - { - struct edge_info *edge_info; - unsigned int i; - - const_and_copies_stack.safe_push (NULL_TREE); - edge_info = (struct edge_info *) false_edge->aux; - - /* If we have info associated with this edge, record it into - our equivalence tables. */ - if (edge_info) - { - cond_equivalence *eq; - tree lhs = edge_info->lhs; - tree rhs = edge_info->rhs; - - /* If we have a simple NAME = VALUE equivalence, record it. */ - if (lhs && TREE_CODE (lhs) == SSA_NAME) - record_const_or_copy (lhs, rhs); - - /* If we have 0 = COND or 1 = COND equivalences, record them - into our expression hash tables. */ - for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i) - record_cond (eq); - } + thread_across_edge (false_edge); - /* Now thread the edge. */ - dom_thread_across_edge (walk_data, false_edge); - - /* No need to remove local expressions from our tables - or restore vars to their original value as that will - be done immediately below. */ - } } + /* These remove expressions local to BB from the tables. */ remove_local_expressions_from_table (); restore_vars_to_original_value (); } diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index ee4298ec9dd..d0669504325 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -68,7 +68,6 @@ static bitmap need_eh_cleanup; static bool gate_dse (void); static unsigned int tree_ssa_dse (void); -static void dse_enter_block (struct dom_walk_data *, basic_block); /* A helper of dse_optimize_stmt. @@ -292,9 +291,16 @@ dse_optimize_stmt (gimple_stmt_iterator *gsi) } } -static void -dse_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, - basic_block bb) +class dse_dom_walker : public dom_walker +{ +public: + dse_dom_walker (cdi_direction direction) : dom_walker (direction) {} + + virtual void before_dom_children (basic_block); +}; + +void +dse_dom_walker::before_dom_children (basic_block bb) { gimple_stmt_iterator gsi; @@ -313,8 +319,6 @@ dse_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, static unsigned int tree_ssa_dse (void) { - struct dom_walk_data walk_data; - need_eh_cleanup = BITMAP_ALLOC (NULL); renumber_gimple_stmt_uids (); @@ -328,22 +332,7 @@ tree_ssa_dse (void) /* Dead store elimination is fundamentally a walk of the post-dominator tree and a backwards walk of statements within each block. */ - walk_data.dom_direction = CDI_POST_DOMINATORS; - walk_data.initialize_block_local_data = NULL; - walk_data.before_dom_children = dse_enter_block; - walk_data.after_dom_children = NULL; - - walk_data.block_local_data_size = 0; - walk_data.global_data = NULL; - - /* Initialize the dominator walker. */ - init_walk_dominator_tree (&walk_data); - - /* Recursively walk the dominator tree. */ - walk_dominator_tree (&walk_data, EXIT_BLOCK_PTR); - - /* Finalize the dominator walker. */ - fini_walk_dominator_tree (&walk_data); + dse_dom_walker (CDI_POST_DOMINATORS).walk (cfun->cfg->x_exit_block_ptr); /* Removal of stores may make some EH edges dead. Purge such edges from the CFG as needed. */ diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index 20d805ac40a..c12ed7fb590 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -1040,14 +1040,25 @@ rewrite_bittest (gimple_stmt_iterator *bsi) return stmt; } +/* For each statement determines the outermost loop in that it is invariant, + - statements on whose motion it depends and the cost of the computation. + - This information is stored to the LIM_DATA structure associated with + - each statement. */ +class invariantness_dom_walker : public dom_walker +{ +public: + invariantness_dom_walker (cdi_direction direction) + : dom_walker (direction) {} + + virtual void before_dom_children (basic_block); +}; /* Determine the outermost loops in that statements in basic block BB are invariant, and record them to the LIM_DATA associated with the statements. - Callback for walk_dominator_tree. */ + Callback for dom_walker. */ -static void -determine_invariantness_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED, - basic_block bb) +void +invariantness_dom_walker::before_dom_children (basic_block bb) { enum move_pos pos; gimple_stmt_iterator bsi; @@ -1177,32 +1188,23 @@ determine_invariantness_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED, } } -/* For each statement determines the outermost loop in that it is invariant, - statements on whose motion it depends and the cost of the computation. - This information is stored to the LIM_DATA structure associated with - each statement. */ - -static void -determine_invariantness (void) +class move_computations_dom_walker : public dom_walker { - struct dom_walk_data walk_data; +public: + move_computations_dom_walker (cdi_direction direction) + : dom_walker (direction), todo_ (0) {} - memset (&walk_data, 0, sizeof (struct dom_walk_data)); - walk_data.dom_direction = CDI_DOMINATORS; - walk_data.before_dom_children = determine_invariantness_stmt; + virtual void before_dom_children (basic_block); - init_walk_dominator_tree (&walk_data); - walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); - fini_walk_dominator_tree (&walk_data); -} + unsigned int todo_; +}; /* Hoist the statements in basic block BB out of the loops prescribed by data stored in LIM_DATA structures associated with each statement. Callback for walk_dominator_tree. */ -static void -move_computations_stmt (struct dom_walk_data *dw_data, - basic_block bb) +void +move_computations_dom_walker::before_dom_children (basic_block bb) { struct loop *level; gimple_stmt_iterator bsi; @@ -1266,7 +1268,7 @@ move_computations_stmt (struct dom_walk_data *dw_data, gimple_phi_result (stmt), t, arg0, arg1); SSA_NAME_DEF_STMT (gimple_phi_result (stmt)) = new_stmt; - *((unsigned int *)(dw_data->global_data)) |= TODO_cleanup_cfg; + todo_ |= TODO_cleanup_cfg; } gsi_insert_on_edge (loop_preheader_edge (level), new_stmt); remove_phi_node (&bsi, false); @@ -1337,23 +1339,14 @@ move_computations_stmt (struct dom_walk_data *dw_data, static unsigned int move_computations (void) { - struct dom_walk_data walk_data; - unsigned int todo = 0; - - memset (&walk_data, 0, sizeof (struct dom_walk_data)); - walk_data.global_data = &todo; - walk_data.dom_direction = CDI_DOMINATORS; - walk_data.before_dom_children = move_computations_stmt; - - init_walk_dominator_tree (&walk_data); - walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); - fini_walk_dominator_tree (&walk_data); + move_computations_dom_walker walker (CDI_DOMINATORS); + walker.walk (cfun->cfg->x_entry_block_ptr); gsi_commit_edge_inserts (); if (need_ssa_update_p (cfun)) rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); - return todo; + return walker.todo_; } /* Checks whether the statement defining variable *INDEX can be hoisted @@ -2632,7 +2625,8 @@ tree_ssa_lim (void) /* For each statement determine the outermost loop in that it is invariant and cost for computing the invariant. */ - determine_invariantness (); + invariantness_dom_walker (CDI_DOMINATORS) + .walk (cfun->cfg->x_entry_block_ptr); /* Execute store motion. Force the necessary invariants to be moved out of the loops as well. */ diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c index f97a94643b3..cb3eec8dd38 100644 --- a/gcc/tree-ssa-loop.c +++ b/gcc/tree-ssa-loop.c @@ -303,7 +303,7 @@ make_pass_predcom (gcc::context *ctxt) /* Loop autovectorization. */ static unsigned int -tree_vectorize (void) +tree_loop_vectorize (void) { if (number_of_loops (cfun) <= 1) return 0; @@ -312,9 +312,9 @@ tree_vectorize (void) } static bool -gate_tree_vectorize (void) +gate_tree_loop_vectorize (void) { - return flag_tree_vectorize || cfun->has_force_vect_loops; + return flag_tree_loop_vectorize || cfun->has_force_vect_loops; } namespace { @@ -342,8 +342,8 @@ public: {} /* opt_pass methods: */ - bool gate () { return gate_tree_vectorize (); } - unsigned int execute () { return tree_vectorize (); } + bool gate () { return gate_tree_loop_vectorize (); } + unsigned int execute () { return tree_loop_vectorize (); } }; // class pass_vectorize diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index ec13ed9c0fd..39d04ab2801 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -1264,9 +1264,6 @@ struct ssa_names_hasher : typed_free_remove <name_to_bb> Hash entries with phase < nt_call_phase are invalid. */ static unsigned int nt_call_phase; -/* The set of MEM_REFs which can't trap. */ -static struct pointer_set_t *nontrap_set; - /* The hash function. */ inline hashval_t @@ -1378,9 +1375,22 @@ nonfreeing_call_p (gimple call) return false; } +class nontrapping_dom_walker : public dom_walker +{ +public: + nontrapping_dom_walker (cdi_direction direction, pointer_set_t *ps) + : dom_walker (direction), nontrapping_ (ps) {} + + virtual void before_dom_children (basic_block); + virtual void after_dom_children (basic_block); + +private: + pointer_set_t *nontrapping_; +}; + /* Called by walk_dominator_tree, when entering the block BB. */ -static void -nt_init_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb) +void +nontrapping_dom_walker::before_dom_children (basic_block bb) { edge e; edge_iterator ei; @@ -1406,15 +1416,15 @@ nt_init_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb) nt_call_phase++; else if (gimple_assign_single_p (stmt) && !gimple_has_volatile_ops (stmt)) { - add_or_mark_expr (bb, gimple_assign_lhs (stmt), nontrap_set, true); - add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), nontrap_set, false); + add_or_mark_expr (bb, gimple_assign_lhs (stmt), nontrapping_, true); + add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), nontrapping_, false); } } } /* Called by walk_dominator_tree, when basic block BB is exited. */ -static void -nt_fini_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb) +void +nontrapping_dom_walker::after_dom_children (basic_block bb) { /* This BB isn't on the path to dominator root anymore. */ bb->aux = (void*)2; @@ -1427,28 +1437,16 @@ nt_fini_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb) static struct pointer_set_t * get_non_trapping (void) { - struct pointer_set_t *nontrap; - struct dom_walk_data walk_data; - nt_call_phase = 0; - nontrap = pointer_set_create (); + pointer_set_t *nontrap = pointer_set_create (); seen_ssa_names.create (128); /* We're going to do a dominator walk, so ensure that we have dominance information. */ calculate_dominance_info (CDI_DOMINATORS); - /* Setup callbacks for the generic dominator tree walker. */ - nontrap_set = nontrap; - walk_data.dom_direction = CDI_DOMINATORS; - walk_data.initialize_block_local_data = NULL; - walk_data.before_dom_children = nt_init_block; - walk_data.after_dom_children = nt_fini_block; - walk_data.global_data = NULL; - walk_data.block_local_data_size = 0; - - init_walk_dominator_tree (&walk_data); - walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); - fini_walk_dominator_tree (&walk_data); + nontrapping_dom_walker (CDI_DOMINATORS, nontrap) + .walk (cfun->cfg->x_entry_block_ptr); + seen_ssa_names.dispose (); clear_aux_for_blocks (); diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 1a9f0cce08c..c53ec44913a 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -3026,7 +3026,7 @@ inhibit_phi_insertion (basic_block bb, pre_expr expr) unsigned i; /* If we aren't going to vectorize we don't inhibit anything. */ - if (!flag_tree_vectorize) + if (!flag_tree_loop_vectorize) return false; /* Otherwise we inhibit the insertion when the address of the @@ -4051,10 +4051,19 @@ eliminate_insert (gimple_stmt_iterator *gsi, tree val) return res; } +class eliminate_dom_walker : public dom_walker +{ +public: + eliminate_dom_walker (cdi_direction direction) : dom_walker (direction) {} + + virtual void before_dom_children (basic_block); + virtual void after_dom_children (basic_block); +}; + /* Perform elimination for the basic-block B during the domwalk. */ -static void -eliminate_bb (dom_walk_data *, basic_block b) +void +eliminate_dom_walker::before_dom_children (basic_block b) { gimple_stmt_iterator gsi; gimple stmt; @@ -4403,8 +4412,8 @@ eliminate_bb (dom_walk_data *, basic_block b) /* Make no longer available leaders no longer available. */ -static void -eliminate_leave_block (dom_walk_data *, basic_block) +void +eliminate_dom_walker::after_dom_children (basic_block) { tree entry; while ((entry = el_avail_stack.pop ()) != NULL_TREE) @@ -4416,7 +4425,6 @@ eliminate_leave_block (dom_walk_data *, basic_block) static unsigned int eliminate (void) { - struct dom_walk_data walk_data; gimple_stmt_iterator gsi; gimple stmt; unsigned i; @@ -4430,15 +4438,7 @@ eliminate (void) el_avail.create (0); el_avail_stack.create (0); - walk_data.dom_direction = CDI_DOMINATORS; - walk_data.initialize_block_local_data = NULL; - walk_data.before_dom_children = eliminate_bb; - walk_data.after_dom_children = eliminate_leave_block; - walk_data.global_data = NULL; - walk_data.block_local_data_size = 0; - init_walk_dominator_tree (&walk_data); - walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); - fini_walk_dominator_tree (&walk_data); + eliminate_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr); el_avail.release (); el_avail_stack.release (); diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 8d6126764e4..c30ab33ef28 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -1926,12 +1926,20 @@ do_invalidate (basic_block dombb, gimple phi, bitmap visited, int *count) } } +class strlen_dom_walker : public dom_walker +{ +public: + strlen_dom_walker (cdi_direction direction) : dom_walker (direction) {} + + virtual void before_dom_children (basic_block); + virtual void after_dom_children (basic_block); +}; + /* Callback for walk_dominator_tree. Attempt to optimize various string ops by remembering string lenths pointed by pointer SSA_NAMEs. */ -static void -strlen_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, - basic_block bb) +void +strlen_dom_walker::before_dom_children (basic_block bb) { gimple_stmt_iterator gsi; basic_block dombb = get_immediate_dominator (CDI_DOMINATORS, bb); @@ -2014,9 +2022,8 @@ strlen_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, /* Callback for walk_dominator_tree. Free strinfo vector if it is owned by the current bb, clear bb->aux. */ -static void -strlen_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, - basic_block bb) +void +strlen_dom_walker::after_dom_children (basic_block bb) { if (bb->aux) { @@ -2040,8 +2047,6 @@ strlen_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, static unsigned int tree_ssa_strlen (void) { - struct dom_walk_data walk_data; - ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names); max_stridx = 1; strinfo_pool = create_alloc_pool ("strinfo_struct pool", @@ -2051,21 +2056,7 @@ tree_ssa_strlen (void) /* String length optimization is implemented as a walk of the dominator tree and a forward walk of statements within each block. */ - walk_data.dom_direction = CDI_DOMINATORS; - walk_data.initialize_block_local_data = NULL; - walk_data.before_dom_children = strlen_enter_block; - walk_data.after_dom_children = strlen_leave_block; - walk_data.block_local_data_size = 0; - walk_data.global_data = NULL; - - /* Initialize the dominator walker. */ - init_walk_dominator_tree (&walk_data); - - /* Recursively walk the dominator tree. */ - walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); - - /* Finalize the dominator walker. */ - fini_walk_dominator_tree (&walk_data); + strlen_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr); ssa_ver_to_stridx.release (); free_alloc_pool (strinfo_pool); diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index 42474f16bb8..47db2804117 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -841,28 +841,6 @@ thread_around_empty_blocks (edge taken_edge, return false; } -/* 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. @@ -1021,18 +999,9 @@ thread_across_edge (gimple dummy_cond, 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, path[path.length () - 1]->dest); - if (!tmp || phi_args_equal_on_edges (tmp, path[path.length () - 1])) - { - propagate_threaded_block_debug_into (path[path.length () - 1]->dest, - taken_edge->dest); - register_jump_thread (path, true); - } + propagate_threaded_block_debug_into (path[path.length () - 1]->dest, + taken_edge->dest); + register_jump_thread (path, true); } path.release(); diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index d75526643b0..413112814d6 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -1147,6 +1147,28 @@ fail: return false; } +/* 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; +} + /* Walk through the registered jump threads and convert them into a form convenient for this pass. @@ -1219,6 +1241,46 @@ mark_threaded_blocks (bitmap threaded_blocks) } } + /* If we have a joiner block (J) which has two successors S1 and S2 and + we are threading though S1 and the final destination of the thread + is S2, then we must verify that any PHI nodes in S2 have the same + PHI arguments for the edge J->S2 and J->S1->...->S2. + + We used to detect this prior to registering the jump thread, but + that prohibits propagation of edge equivalences into non-dominated + PHI nodes as the equivalency test might occur before propagation. + + This works for now, but will need improvement as part of the FSA + optimization. + + Note since we've moved the thread request data to the edges, + we have to iterate on those rather than the threaded_edges vector. */ + EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi) + { + bb = BASIC_BLOCK (i); + FOR_EACH_EDGE (e, ei, bb->preds) + { + if (e->aux) + { + bool have_joiner = THREAD_TARGET2 (e) != NULL; + + if (have_joiner) + { + basic_block joiner = e->dest; + edge final_edge = THREAD_TARGET2 (e); + basic_block final_dest = final_edge->dest; + edge e2 = find_edge (joiner, final_dest); + + if (e2 && !phi_args_equal_on_edges (e2, final_edge)) + { + free (e->aux); + e->aux = NULL; + } + } + } + } + } + /* If optimizing for size, only thread through block if we don't have to duplicate it or it's an otherwise empty redirection block. */ diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c index 8439df164dd..a13ccf01135 100644 --- a/gcc/tree-ssa-uncprop.c +++ b/gcc/tree-ssa-uncprop.c @@ -259,11 +259,6 @@ associate_equivalences_with_edges (void) so with each value we have a list of SSA_NAMEs that have the same value. */ -/* As we enter each block we record the value for any edge equivalency - leading to this block. If no such edge equivalency exists, then we - record NULL. These equivalences are live until we leave the dominator - subtree rooted at the block where we record the equivalency. */ -static vec<tree> equiv_stack; /* Main structure for recording equivalences into our hash table. */ struct equiv_hash_elt @@ -316,8 +311,6 @@ val_ssa_equiv_hasher::remove (value_type *elt) able to reuse tree-vn for this code. */ static hash_table <val_ssa_equiv_hasher> val_ssa_equiv; -static void uncprop_enter_block (struct dom_walk_data *, basic_block); -static void uncprop_leave_block (struct dom_walk_data *, basic_block); static void uncprop_into_successor_phis (basic_block); /* Remove the most recently recorded equivalency for VALUE. */ @@ -361,47 +354,54 @@ record_equiv (tree value, tree equivalence) an_equiv_elt_p->equivalences.safe_push (equivalence); } +class uncprop_dom_walker : public dom_walker +{ +public: + uncprop_dom_walker (cdi_direction direction) + : dom_walker (direction) + { + equiv_stack_.create (2); + } + ~uncprop_dom_walker () + { + equiv_stack_.release (); + } + + virtual void before_dom_children (basic_block); + virtual void after_dom_children (basic_block); + +private: + +/* As we enter each block we record the value for any edge equivalency + leading to this block. If no such edge equivalency exists, then we + record NULL. These equivalences are live until we leave the dominator + subtree rooted at the block where we record the equivalency. */ + vec<tree> equiv_stack_; +}; + /* Main driver for un-cprop. */ static unsigned int tree_ssa_uncprop (void) { - struct dom_walk_data walk_data; basic_block bb; associate_equivalences_with_edges (); /* Create our global data structures. */ val_ssa_equiv.create (1024); - equiv_stack.create (2); /* We're going to do a dominator walk, so ensure that we have dominance information. */ calculate_dominance_info (CDI_DOMINATORS); - /* Setup callbacks for the generic dominator tree walker. */ - walk_data.dom_direction = CDI_DOMINATORS; - walk_data.initialize_block_local_data = NULL; - walk_data.before_dom_children = uncprop_enter_block; - walk_data.after_dom_children = uncprop_leave_block; - walk_data.global_data = NULL; - walk_data.block_local_data_size = 0; - - /* Now initialize the dominator walker. */ - init_walk_dominator_tree (&walk_data); - /* Recursively walk the dominator tree undoing unprofitable constant/copy propagations. */ - walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); - - /* Finalize and clean up. */ - fini_walk_dominator_tree (&walk_data); + uncprop_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr); - /* EQUIV_STACK should already be empty at this point, so we just - need to empty elements out of the hash table, free EQUIV_STACK, - and cleanup the AUX field on the edges. */ + /* we just need to empty elements out of the hash table, and cleanup the + AUX field on the edges. */ val_ssa_equiv.dispose (); - equiv_stack.release (); FOR_EACH_BB (bb) { edge e; @@ -424,12 +424,11 @@ tree_ssa_uncprop (void) any finalization actions in preparation for leaving this node in the dominator tree. */ -static void -uncprop_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, - basic_block bb ATTRIBUTE_UNUSED) +void +uncprop_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED) { /* Pop the topmost value off the equiv stack. */ - tree value = equiv_stack.pop (); + tree value = equiv_stack_.pop (); /* If that value was non-null, then pop the topmost equivalency off its equivalency stack. */ @@ -547,9 +546,8 @@ single_incoming_edge_ignoring_loop_edges (basic_block bb) return retval; } -static void -uncprop_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, - basic_block bb) +void +uncprop_dom_walker::before_dom_children (basic_block bb) { basic_block parent; edge e; @@ -568,13 +566,13 @@ uncprop_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, struct edge_equivalency *equiv = (struct edge_equivalency *) e->aux; record_equiv (equiv->rhs, equiv->lhs); - equiv_stack.safe_push (equiv->rhs); + equiv_stack_.safe_push (equiv->rhs); recorded = true; } } if (!recorded) - equiv_stack.safe_push (NULL_TREE); + equiv_stack_.safe_push (NULL_TREE); uncprop_into_successor_phis (bb); } diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index ae30e244a1c..bd46ddfb18e 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -74,46 +74,173 @@ get_mask_first_set_bit (unsigned mask) } #define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask) - /* Return true if T, an SSA_NAME, has an undefined value. */ - -bool -ssa_undefined_value_p (tree t) +static bool +has_undefined_value_p (tree t) { - tree var = SSA_NAME_VAR (t); - - if (!var) - ; - /* Parameters get their initial value from the function entry. */ - else if (TREE_CODE (var) == PARM_DECL) - return false; - /* When returning by reference the return address is actually a hidden - parameter. */ - else if (TREE_CODE (var) == RESULT_DECL && DECL_BY_REFERENCE (var)) - return false; - /* Hard register variables get their initial value from the ether. */ - else if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var)) - return false; - - /* The value is undefined iff its definition statement is empty. */ - return (gimple_nop_p (SSA_NAME_DEF_STMT (t)) + return (ssa_undefined_value_p (t) || (possibly_undefined_names && pointer_set_contains (possibly_undefined_names, t))); } -/* Like ssa_undefined_value_p, but don't return true if TREE_NO_WARNING + + +/* Like has_undefined_value_p, but don't return true if TREE_NO_WARNING is set on SSA_NAME_VAR. */ static inline bool -uninit_undefined_value_p (tree t) -{ - if (!ssa_undefined_value_p (t)) +uninit_undefined_value_p (tree t) { + if (!has_undefined_value_p (t)) return false; if (SSA_NAME_VAR (t) && TREE_NO_WARNING (SSA_NAME_VAR (t))) return false; return true; } +/* Emit warnings for uninitialized variables. This is done in two passes. + + The first pass notices real uses of SSA names with undefined values. + Such uses are unconditionally uninitialized, and we can be certain that + such a use is a mistake. This pass is run before most optimizations, + so that we catch as many as we can. + + The second pass follows PHI nodes to find uses that are potentially + uninitialized. In this case we can't necessarily prove that the use + is really uninitialized. This pass is run after most optimizations, + so that we thread as many jumps and possible, and delete as much dead + code as possible, in order to reduce false positives. We also look + again for plain uninitialized variables, since optimization may have + changed conditionally uninitialized to unconditionally uninitialized. */ + +/* Emit a warning for EXPR based on variable VAR at the point in the + program T, an SSA_NAME, is used being uninitialized. The exact + warning text is in MSGID and LOCUS may contain a location or be null. + WC is the warning code. */ + +static void +warn_uninit (enum opt_code wc, tree t, + tree expr, tree var, const char *gmsgid, void *data) +{ + gimple context = (gimple) data; + location_t location, cfun_loc; + expanded_location xloc, floc; + + if (!has_undefined_value_p (t)) + return; + + /* TREE_NO_WARNING either means we already warned, or the front end + wishes to suppress the warning. */ + if ((context + && (gimple_no_warning_p (context) + || (gimple_assign_single_p (context) + && TREE_NO_WARNING (gimple_assign_rhs1 (context))))) + || TREE_NO_WARNING (expr)) + return; + + location = (context != NULL && gimple_has_location (context)) + ? gimple_location (context) + : DECL_SOURCE_LOCATION (var); + location = linemap_resolve_location (line_table, location, + LRK_SPELLING_LOCATION, + NULL); + cfun_loc = DECL_SOURCE_LOCATION (cfun->decl); + xloc = expand_location (location); + floc = expand_location (cfun_loc); + if (warning_at (location, wc, gmsgid, expr)) + { + TREE_NO_WARNING (expr) = 1; + + if (location == DECL_SOURCE_LOCATION (var)) + return; + if (xloc.file != floc.file + || linemap_location_before_p (line_table, + location, cfun_loc) + || linemap_location_before_p (line_table, + cfun->function_end_locus, + location)) + inform (DECL_SOURCE_LOCATION (var), "%qD was declared here", var); + } +} + +static unsigned int +warn_uninitialized_vars (bool warn_possibly_uninitialized) +{ + gimple_stmt_iterator gsi; + basic_block bb; + + FOR_EACH_BB (bb) + { + bool always_executed = dominated_by_p (CDI_POST_DOMINATORS, + single_succ (ENTRY_BLOCK_PTR), bb); + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + use_operand_p use_p; + ssa_op_iter op_iter; + tree use; + + if (is_gimple_debug (stmt)) + continue; + + /* We only do data flow with SSA_NAMEs, so that's all we + can warn about. */ + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE) + { + use = USE_FROM_PTR (use_p); + if (always_executed) + warn_uninit (OPT_Wuninitialized, use, + SSA_NAME_VAR (use), SSA_NAME_VAR (use), + "%qD is used uninitialized in this function", + stmt); + else if (warn_possibly_uninitialized) + warn_uninit (OPT_Wmaybe_uninitialized, use, + SSA_NAME_VAR (use), SSA_NAME_VAR (use), + "%qD may be used uninitialized in this function", + stmt); + } + + /* For memory the only cheap thing we can do is see if we + have a use of the default def of the virtual operand. + ??? Note that at -O0 we do not have virtual operands. + ??? Not so cheap would be to use the alias oracle via + walk_aliased_vdefs, if we don't find any aliasing vdef + warn as is-used-uninitialized, if we don't find an aliasing + vdef that kills our use (stmt_kills_ref_p), warn as + may-be-used-uninitialized. But this walk is quadratic and + so must be limited which means we would miss warning + opportunities. */ + use = gimple_vuse (stmt); + if (use + && gimple_assign_single_p (stmt) + && !gimple_vdef (stmt) + && SSA_NAME_IS_DEFAULT_DEF (use)) + { + tree rhs = gimple_assign_rhs1 (stmt); + tree base = get_base_address (rhs); + + /* Do not warn if it can be initialized outside this function. */ + if (TREE_CODE (base) != VAR_DECL + || DECL_HARD_REGISTER (base) + || is_global_var (base)) + continue; + + if (always_executed) + warn_uninit (OPT_Wuninitialized, use, + gimple_assign_rhs1 (stmt), base, + "%qE is used uninitialized in this function", + stmt); + else if (warn_possibly_uninitialized) + warn_uninit (OPT_Wmaybe_uninitialized, use, + gimple_assign_rhs1 (stmt), base, + "%qE may be used uninitialized in this function", + stmt); + } + } + } + + return 0; +} + /* Checks if the operand OPND of PHI is defined by another phi with one operand defined by this PHI, but the rest operands are all defined. If yes, @@ -2084,3 +2211,65 @@ make_pass_late_warn_uninitialized (gcc::context *ctxt) { return new pass_late_warn_uninitialized (ctxt); } + + +static unsigned int +execute_early_warn_uninitialized (void) +{ + /* Currently, this pass runs always but + execute_late_warn_uninitialized only runs with optimization. With + optimization we want to warn about possible uninitialized as late + as possible, thus don't do it here. However, without + optimization we need to warn here about "may be uninitialized". + */ + calculate_dominance_info (CDI_POST_DOMINATORS); + + warn_uninitialized_vars (/*warn_possibly_uninitialized=*/!optimize); + + /* Post-dominator information can not be reliably updated. Free it + after the use. */ + + free_dominance_info (CDI_POST_DOMINATORS); + return 0; +} + + +namespace { + +const pass_data pass_data_early_warn_uninitialized = +{ + GIMPLE_PASS, /* type */ + "*early_warn_uninitialized", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_gate */ + true, /* has_execute */ + TV_TREE_UNINIT, /* tv_id */ + PROP_ssa, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_early_warn_uninitialized : public gimple_opt_pass +{ +public: + pass_early_warn_uninitialized(gcc::context *ctxt) + : gimple_opt_pass(pass_data_early_warn_uninitialized, ctxt) + {} + + /* opt_pass methods: */ + bool gate () { return gate_warn_uninitialized (); } + unsigned int execute () { return execute_early_warn_uninitialized (); } + +}; // class pass_early_warn_uninitialized + +} // anon namespace + +gimple_opt_pass * +make_pass_early_warn_uninitialized (gcc::context *ctxt) +{ + return new pass_early_warn_uninitialized (ctxt); +} + + diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 461bb52e821..8146e1fed1d 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1193,6 +1193,31 @@ tree_ssa_strip_useless_type_conversions (tree exp) } +/* Return true if T, an SSA_NAME, has an undefined value. */ + +bool +ssa_undefined_value_p (tree t) +{ + tree var = SSA_NAME_VAR (t); + + if (!var) + ; + /* Parameters get their initial value from the function entry. */ + else if (TREE_CODE (var) == PARM_DECL) + return false; + /* When returning by reference the return address is actually a hidden + parameter. */ + else if (TREE_CODE (var) == RESULT_DECL && DECL_BY_REFERENCE (var)) + return false; + /* Hard register variables get their initial value from the ether. */ + else if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var)) + return false; + + /* The value is undefined iff its definition statement is empty. */ + return gimple_nop_p (SSA_NAME_DEF_STMT (t)); +} + + /* Internal helper for walk_use_def_chains. VAR, FN and DATA are as described in walk_use_def_chains. @@ -1301,215 +1326,6 @@ walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data, } } - -/* Emit warnings for uninitialized variables. This is done in two passes. - - The first pass notices real uses of SSA names with undefined values. - Such uses are unconditionally uninitialized, and we can be certain that - such a use is a mistake. This pass is run before most optimizations, - so that we catch as many as we can. - - The second pass follows PHI nodes to find uses that are potentially - uninitialized. In this case we can't necessarily prove that the use - is really uninitialized. This pass is run after most optimizations, - so that we thread as many jumps and possible, and delete as much dead - code as possible, in order to reduce false positives. We also look - again for plain uninitialized variables, since optimization may have - changed conditionally uninitialized to unconditionally uninitialized. */ - -/* Emit a warning for EXPR based on variable VAR at the point in the - program T, an SSA_NAME, is used being uninitialized. The exact - warning text is in MSGID and LOCUS may contain a location or be null. - WC is the warning code. */ - -void -warn_uninit (enum opt_code wc, tree t, - tree expr, tree var, const char *gmsgid, void *data) -{ - gimple context = (gimple) data; - location_t location, cfun_loc; - expanded_location xloc, floc; - - if (!ssa_undefined_value_p (t)) - return; - - /* TREE_NO_WARNING either means we already warned, or the front end - wishes to suppress the warning. */ - if ((context - && (gimple_no_warning_p (context) - || (gimple_assign_single_p (context) - && TREE_NO_WARNING (gimple_assign_rhs1 (context))))) - || TREE_NO_WARNING (expr)) - return; - - location = (context != NULL && gimple_has_location (context)) - ? gimple_location (context) - : DECL_SOURCE_LOCATION (var); - location = linemap_resolve_location (line_table, location, - LRK_SPELLING_LOCATION, - NULL); - cfun_loc = DECL_SOURCE_LOCATION (cfun->decl); - xloc = expand_location (location); - floc = expand_location (cfun_loc); - if (warning_at (location, wc, gmsgid, expr)) - { - TREE_NO_WARNING (expr) = 1; - - if (location == DECL_SOURCE_LOCATION (var)) - return; - if (xloc.file != floc.file - || linemap_location_before_p (line_table, - location, cfun_loc) - || linemap_location_before_p (line_table, - cfun->function_end_locus, - location)) - inform (DECL_SOURCE_LOCATION (var), "%qD was declared here", var); - } -} - -unsigned int -warn_uninitialized_vars (bool warn_possibly_uninitialized) -{ - gimple_stmt_iterator gsi; - basic_block bb; - - FOR_EACH_BB (bb) - { - bool always_executed = dominated_by_p (CDI_POST_DOMINATORS, - single_succ (ENTRY_BLOCK_PTR), bb); - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple stmt = gsi_stmt (gsi); - use_operand_p use_p; - ssa_op_iter op_iter; - tree use; - - if (is_gimple_debug (stmt)) - continue; - - /* We only do data flow with SSA_NAMEs, so that's all we - can warn about. */ - FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE) - { - use = USE_FROM_PTR (use_p); - if (always_executed) - warn_uninit (OPT_Wuninitialized, use, - SSA_NAME_VAR (use), SSA_NAME_VAR (use), - "%qD is used uninitialized in this function", - stmt); - else if (warn_possibly_uninitialized) - warn_uninit (OPT_Wmaybe_uninitialized, use, - SSA_NAME_VAR (use), SSA_NAME_VAR (use), - "%qD may be used uninitialized in this function", - stmt); - } - - /* For memory the only cheap thing we can do is see if we - have a use of the default def of the virtual operand. - ??? Note that at -O0 we do not have virtual operands. - ??? Not so cheap would be to use the alias oracle via - walk_aliased_vdefs, if we don't find any aliasing vdef - warn as is-used-uninitialized, if we don't find an aliasing - vdef that kills our use (stmt_kills_ref_p), warn as - may-be-used-uninitialized. But this walk is quadratic and - so must be limited which means we would miss warning - opportunities. */ - use = gimple_vuse (stmt); - if (use - && gimple_assign_single_p (stmt) - && !gimple_vdef (stmt) - && SSA_NAME_IS_DEFAULT_DEF (use)) - { - tree rhs = gimple_assign_rhs1 (stmt); - tree base = get_base_address (rhs); - - /* Do not warn if it can be initialized outside this function. */ - if (TREE_CODE (base) != VAR_DECL - || DECL_HARD_REGISTER (base) - || is_global_var (base)) - continue; - - if (always_executed) - warn_uninit (OPT_Wuninitialized, use, - gimple_assign_rhs1 (stmt), base, - "%qE is used uninitialized in this function", - stmt); - else if (warn_possibly_uninitialized) - warn_uninit (OPT_Wmaybe_uninitialized, use, - gimple_assign_rhs1 (stmt), base, - "%qE may be used uninitialized in this function", - stmt); - } - } - } - - return 0; -} - -static unsigned int -execute_early_warn_uninitialized (void) -{ - /* Currently, this pass runs always but - execute_late_warn_uninitialized only runs with optimization. With - optimization we want to warn about possible uninitialized as late - as possible, thus don't do it here. However, without - optimization we need to warn here about "may be uninitialized". - */ - calculate_dominance_info (CDI_POST_DOMINATORS); - - warn_uninitialized_vars (/*warn_possibly_uninitialized=*/!optimize); - - /* Post-dominator information can not be reliably updated. Free it - after the use. */ - - free_dominance_info (CDI_POST_DOMINATORS); - return 0; -} - -static bool -gate_warn_uninitialized (void) -{ - return warn_uninitialized != 0; -} - -namespace { - -const pass_data pass_data_early_warn_uninitialized = -{ - GIMPLE_PASS, /* type */ - "*early_warn_uninitialized", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_gate */ - true, /* has_execute */ - TV_TREE_UNINIT, /* tv_id */ - PROP_ssa, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_early_warn_uninitialized : public gimple_opt_pass -{ -public: - pass_early_warn_uninitialized(gcc::context *ctxt) - : gimple_opt_pass(pass_data_early_warn_uninitialized, ctxt) - {} - - /* opt_pass methods: */ - bool gate () { return gate_warn_uninitialized (); } - unsigned int execute () { return execute_early_warn_uninitialized (); } - -}; // class pass_early_warn_uninitialized - -} // anon namespace - -gimple_opt_pass * -make_pass_early_warn_uninitialized (gcc::context *ctxt) -{ - return new pass_early_warn_uninitialized (ctxt); -} - /* If necessary, rewrite the base of the reference tree *TP from a MEM_REF to a plain or converted symbol. */ diff --git a/gcc/tree-ssa.h b/gcc/tree-ssa.h index 457fd6bf5e7..1808b1c447a 100644 --- a/gcc/tree-ssa.h +++ b/gcc/tree-ssa.h @@ -58,8 +58,7 @@ extern tree tree_ssa_strip_useless_type_conversions (tree); typedef bool (*walk_use_def_chains_fn) (tree, gimple, void *); extern void walk_use_def_chains (tree, walk_use_def_chains_fn, void *, bool); -extern void warn_uninit (enum opt_code, tree, tree, tree, const char *, void *); -extern unsigned int warn_uninitialized_vars (bool); +extern bool ssa_undefined_value_p (tree); extern void execute_update_addresses_taken (void); /* Given an edge_var_map V, return the PHI arg definition. */ diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 1b29c79a241..98055ae01f8 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -59,8 +59,8 @@ vect_lanes_optab_supported_p (const char *name, convert_optab optab, if (array_mode == BLKmode) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "no array mode for %s[" HOST_WIDE_INT_PRINT_DEC "]", + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "no array mode for %s[" HOST_WIDE_INT_PRINT_DEC "]\n", GET_MODE_NAME (mode), count); return false; } @@ -69,14 +69,14 @@ vect_lanes_optab_supported_p (const char *name, convert_optab optab, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "cannot use %s<%s><%s>", name, + "cannot use %s<%s><%s>\n", name, GET_MODE_NAME (array_mode), GET_MODE_NAME (mode)); return false; } if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "can use %s<%s><%s>", name, GET_MODE_NAME (array_mode), + "can use %s<%s><%s>\n", name, GET_MODE_NAME (array_mode), GET_MODE_NAME (mode)); return true; @@ -182,13 +182,15 @@ vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo) dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (DDR_A (ddr))); dump_printf (MSG_NOTE, " and "); dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (DDR_B (ddr))); + dump_printf (MSG_NOTE, "\n"); } if (optimize_loop_nest_for_size_p (loop)) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "versioning not supported when optimizing for size."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "versioning not supported when optimizing" + " for size.\n"); return false; } @@ -196,8 +198,8 @@ vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo) if (loop->inner) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "versioning not yet supported for outer-loops."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "versioning not yet supported for outer-loops.\n"); return false; } @@ -207,9 +209,9 @@ vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo) || TREE_CODE (DR_STEP (DDR_B (ddr))) != INTEGER_CST) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "versioning not yet supported for non-constant " - "step"); + "step\n"); return false; } @@ -276,6 +278,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, dump_printf (MSG_MISSED_OPTIMIZATION, " and "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb)); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return true; } @@ -290,6 +293,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, dump_printf (MSG_MISSED_OPTIMIZATION, " and "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb)); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Add to list of ddrs that need to be tested at run-time. */ @@ -321,18 +325,20 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, dump_printf (MSG_MISSED_OPTIMIZATION, " and "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb)); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return true; } if (dump_enabled_p ()) { - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "versioning for alias required: " "bad dist vector for "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dra)); dump_printf (MSG_MISSED_OPTIMIZATION, " and "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb)); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Add to list of ddrs that need to be tested at run-time. */ return !vect_mark_for_runtime_alias_test (ddr, loop_vinfo); @@ -345,17 +351,18 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "dependence distance = %d.", dist); + "dependence distance = %d.\n", dist); if (dist == 0) { if (dump_enabled_p ()) { - dump_printf_loc (MSG_NOTE, vect_location, - "dependence distance == 0 between "); + dump_printf_loc (MSG_NOTE, vect_location, + "dependence distance == 0 between "); dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra)); dump_printf (MSG_NOTE, " and "); dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb)); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* When we perform grouped accesses and perform implicit CSE @@ -383,7 +390,8 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "READ_WRITE dependence in interleaving."); + "READ_WRITE dependence in interleaving." + "\n"); return true; } } @@ -398,7 +406,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, distance is negative. */ if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "dependence distance negative."); + "dependence distance negative.\n"); continue; } @@ -410,8 +418,8 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, *max_vf = abs (dist); if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "adjusting maximal vectorization factor to %i", - *max_vf); + "adjusting maximal vectorization factor to %i\n", + *max_vf); } if (abs (dist) >= *max_vf) @@ -420,18 +428,19 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, vectorization is concerned, in this case. */ if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "dependence distance >= VF."); + "dependence distance >= VF.\n"); continue; } if (dump_enabled_p ()) { dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized, possible dependence " - "between data-refs "); + "not vectorized, possible dependence " + "between data-refs "); dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra)); dump_printf (MSG_NOTE, " and "); dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb)); + dump_printf (MSG_NOTE, "\n"); } return true; @@ -454,7 +463,7 @@ vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo, int *max_vf) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_analyze_data_ref_dependences ==="); + "=== vect_analyze_data_ref_dependences ===\n"); if (!compute_all_dependences (LOOP_VINFO_DATAREFS (loop_vinfo), &LOOP_VINFO_DDRS (loop_vinfo), @@ -515,6 +524,7 @@ vect_slp_analyze_data_ref_dependence (struct data_dependence_relation *ddr) dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dra)); dump_printf (MSG_MISSED_OPTIMIZATION, " and "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb)); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* We do not vectorize basic blocks with write-write dependencies. */ @@ -536,6 +546,7 @@ vect_slp_analyze_data_ref_dependence (struct data_dependence_relation *ddr) dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra)); dump_printf (MSG_NOTE, " and "); dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb)); + dump_printf (MSG_NOTE, "\n"); } /* Do not vectorize basic blocks with write-write dependences. */ @@ -600,7 +611,7 @@ vect_slp_analyze_data_ref_dependences (bb_vec_info bb_vinfo) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_slp_analyze_data_ref_dependences ==="); + "=== vect_slp_analyze_data_ref_dependences ===\n"); if (!compute_all_dependences (BB_VINFO_DATAREFS (bb_vinfo), &BB_VINFO_DDRS (bb_vinfo), @@ -643,7 +654,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vect_compute_data_ref_alignment:"); + "vect_compute_data_ref_alignment:\n"); if (loop_vinfo) loop = LOOP_VINFO_LOOP (loop_vinfo); @@ -676,7 +687,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "inner step divides the vector-size."); + "inner step divides the vector-size.\n"); misalign = STMT_VINFO_DR_INIT (stmt_info); aligned_to = STMT_VINFO_DR_ALIGNED_TO (stmt_info); base_addr = STMT_VINFO_DR_BASE_ADDRESS (stmt_info); @@ -685,7 +696,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "inner step doesn't divide the vector-size."); + "inner step doesn't divide the vector-size.\n"); misalign = NULL_TREE; } } @@ -703,8 +714,8 @@ vect_compute_data_ref_alignment (struct data_reference *dr) if (dr_step % GET_MODE_SIZE (TYPE_MODE (vectype)) != 0) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "SLP: step doesn't divide the vector-size."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "SLP: step doesn't divide the vector-size.\n"); misalign = NULL_TREE; } } @@ -718,8 +729,9 @@ vect_compute_data_ref_alignment (struct data_reference *dr) if (dump_enabled_p ()) { dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Unknown alignment for access: "); + "Unknown alignment for access: "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, base); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return true; } @@ -748,8 +760,9 @@ vect_compute_data_ref_alignment (struct data_reference *dr) if (dump_enabled_p ()) { dump_printf_loc (MSG_NOTE, vect_location, - "can't force alignment of ref: "); + "can't force alignment of ref: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, ref); + dump_printf (MSG_NOTE, "\n"); } return true; } @@ -761,6 +774,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr) { dump_printf_loc (MSG_NOTE, vect_location, "force alignment of "); dump_generic_expr (MSG_NOTE, TDF_SLIM, ref); + dump_printf (MSG_NOTE, "\n"); } ((dataref_aux *)dr->aux)->base_decl = base; @@ -788,7 +802,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr) /* Negative or overflowed misalignment value. */ if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "unexpected misalign value"); + "unexpected misalign value\n"); return false; } @@ -799,6 +813,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "misalign = %d bytes of ref ", DR_MISALIGNMENT (dr)); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, ref); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return true; @@ -895,7 +910,7 @@ vect_update_misalignment_for_peel (struct data_reference *dr, } if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "Setting misalignment to -1."); + dump_printf_loc (MSG_NOTE, vect_location, "Setting misalignment to -1.\n"); SET_DR_MISALIGNMENT (dr, -1); } @@ -953,12 +968,13 @@ vect_verify_datarefs_alignment (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dr)); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } if (supportable_dr_alignment != dr_aligned && dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Vectorizing an unaligned access."); + "Vectorizing an unaligned access.\n"); } return true; } @@ -1015,16 +1031,16 @@ vector_alignment_reachable_p (struct data_reference *dr) int_cst_value (TYPE_SIZE_UNIT (TREE_TYPE (vectype))); if (dump_enabled_p ()) { - dump_printf_loc (MSG_NOTE, vect_location, - "data size =" HOST_WIDE_INT_PRINT_DEC, elmsize); - dump_printf (MSG_NOTE, - ". misalignment = %d. ", DR_MISALIGNMENT (dr)); + dump_printf_loc (MSG_NOTE, vect_location, + "data size =" HOST_WIDE_INT_PRINT_DEC, elmsize); + dump_printf (MSG_NOTE, + ". misalignment = %d.\n", DR_MISALIGNMENT (dr)); } if (DR_MISALIGNMENT (dr) % elmsize) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "data size does not divide the misalignment.\n"); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "data size does not divide the misalignment.\n"); return false; } } @@ -1034,8 +1050,8 @@ vector_alignment_reachable_p (struct data_reference *dr) tree type = TREE_TYPE (DR_REF (dr)); bool is_packed = not_size_aligned (DR_REF (dr)); if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Unknown misalignment, is_packed = %d",is_packed); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Unknown misalignment, is_packed = %d\n",is_packed); if ((TYPE_USER_ALIGN (type) && !is_packed) || targetm.vectorize.vector_alignment_reachable (type, is_packed)) return true; @@ -1071,7 +1087,7 @@ vect_get_data_access_cost (struct data_reference *dr, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "vect_get_data_access_cost: inside_cost = %d, " - "outside_cost = %d.", *inside_cost, *outside_cost); + "outside_cost = %d.\n", *inside_cost, *outside_cost); } @@ -1346,7 +1362,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_enhance_data_refs_alignment ==="); + "=== vect_enhance_data_refs_alignment ===\n"); /* While cost model enhancements are expected in the future, the high level view of the code at this time is as follows: @@ -1515,8 +1531,8 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) if (!aligned_access_p (dr)) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "vector alignment may not be reachable"); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "vector alignment may not be reachable\n"); break; } } @@ -1652,7 +1668,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Try peeling by %d", npeel); + "Try peeling by %d\n", npeel); } /* Ensure that all data refs can be vectorized after the peel. */ @@ -1725,9 +1741,9 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) if (dump_enabled_p ()) { dump_printf_loc (MSG_NOTE, vect_location, - "Alignment of access forced using peeling."); + "Alignment of access forced using peeling.\n"); dump_printf_loc (MSG_NOTE, vect_location, - "Peeling for alignment will be applied."); + "Peeling for alignment will be applied.\n"); } /* We've delayed passing the inside-loop peeling costs to the target cost model until we were sure peeling would happen. @@ -1847,13 +1863,13 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) dr = STMT_VINFO_DATA_REF (stmt_info); SET_DR_MISALIGNMENT (dr, 0); if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "Alignment of access forced using versioning."); + dump_printf_loc (MSG_NOTE, vect_location, + "Alignment of access forced using versioning.\n"); } if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "Versioning for alignment will be applied."); + dump_printf_loc (MSG_NOTE, vect_location, + "Versioning for alignment will be applied.\n"); /* Peeling and versioning can't be done together at this time. */ gcc_assert (! (do_peeling && do_versioning)); @@ -1919,7 +1935,7 @@ vect_find_same_alignment_drs (struct data_dependence_relation *ddr, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "dependence distance = %d.", dist); + "dependence distance = %d.\n", dist); /* Same loop iteration. */ if (dist == 0 @@ -1930,13 +1946,14 @@ vect_find_same_alignment_drs (struct data_dependence_relation *ddr, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b).safe_push (dra); if (dump_enabled_p ()) { - dump_printf_loc (MSG_NOTE, vect_location, - "accesses have the same alignment."); + dump_printf_loc (MSG_NOTE, vect_location, + "accesses have the same alignment.\n"); dump_printf (MSG_NOTE, - "dependence distance modulo vf == 0 between "); + "dependence distance modulo vf == 0 between "); dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra)); dump_printf (MSG_NOTE, " and "); dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb)); + dump_printf (MSG_NOTE, "\n"); } } } @@ -1954,7 +1971,7 @@ vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo, { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_analyze_data_refs_alignment ==="); + "=== vect_analyze_data_refs_alignment ===\n"); /* Mark groups of data references with same alignment using data dependence information. */ @@ -1971,9 +1988,9 @@ vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo, if (!vect_compute_data_refs_alignment (loop_vinfo, bb_vinfo)) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: can't calculate alignment " - "for data ref."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: can't calculate alignment " + "for data ref.\n"); return false; } @@ -2025,25 +2042,26 @@ vect_analyze_group_access (struct data_reference *dr) GROUP_SIZE (vinfo_for_stmt (stmt)) = groupsize; if (dump_enabled_p ()) { - dump_printf_loc (MSG_NOTE, vect_location, - "Detected single element interleaving "); + dump_printf_loc (MSG_NOTE, vect_location, + "Detected single element interleaving "); dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dr)); dump_printf (MSG_NOTE, " step "); dump_generic_expr (MSG_NOTE, TDF_SLIM, step); + dump_printf (MSG_NOTE, "\n"); } if (loop_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Data access with gaps requires scalar " - "epilogue loop"); + "Data access with gaps requires scalar " + "epilogue loop\n"); if (loop->inner) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "Peeling for outer loop is not" - " supported"); + " supported\n"); return false; } @@ -2056,8 +2074,9 @@ vect_analyze_group_access (struct data_reference *dr) if (dump_enabled_p ()) { dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not consecutive access "); - dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + "not consecutive access "); + dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } if (bb_vinfo) @@ -2094,8 +2113,8 @@ vect_analyze_group_access (struct data_reference *dr) if (DR_IS_WRITE (data_ref)) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Two store stmts share the same dr."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Two store stmts share the same dr.\n"); return false; } @@ -2124,8 +2143,8 @@ vect_analyze_group_access (struct data_reference *dr) if (DR_IS_WRITE (data_ref)) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "interleaved store with gaps"); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "interleaved store with gaps\n"); return false; } @@ -2155,9 +2174,11 @@ vect_analyze_group_access (struct data_reference *dr) { if (dump_enabled_p ()) { - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "interleaving size is greater than step for "); - dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dr)); + dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, + DR_REF (dr)); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -2178,8 +2199,8 @@ vect_analyze_group_access (struct data_reference *dr) else { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "interleaved store with gaps"); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "interleaved store with gaps\n"); return false; } } @@ -2196,6 +2217,7 @@ vect_analyze_group_access (struct data_reference *dr) dump_printf (MSG_MISSED_OPTIMIZATION, " size "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, TYPE_SIZE_UNIT (scalar_type)); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -2205,8 +2227,8 @@ vect_analyze_group_access (struct data_reference *dr) GROUP_SIZE (vinfo_for_stmt (stmt)) = groupsize; if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "Detected interleaving of size %d", (int)groupsize); + dump_printf_loc (MSG_NOTE, vect_location, + "Detected interleaving of size %d\n", (int)groupsize); /* SLP: create an SLP data structure for every interleaving group of stores for further analysis in vect_analyse_slp. */ @@ -2223,13 +2245,13 @@ vect_analyze_group_access (struct data_reference *dr) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Data access with gaps requires scalar " - "epilogue loop"); + "Data access with gaps requires scalar " + "epilogue loop\n"); if (loop->inner) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Peeling for outer loop is not supported"); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Peeling for outer loop is not supported\n"); return false; } @@ -2261,8 +2283,8 @@ vect_analyze_data_ref_access (struct data_reference *dr) if (loop_vinfo && !step) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "bad data-ref access in loop"); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "bad data-ref access in loop\n"); return false; } @@ -2274,7 +2296,7 @@ vect_analyze_data_ref_access (struct data_reference *dr) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "zero step in inner loop of nest"); + "zero step in inner loop of nest\n"); return false; } return DR_IS_READ (dr); @@ -2292,7 +2314,7 @@ vect_analyze_data_ref_access (struct data_reference *dr) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "zero step in outer loop."); + "zero step in outer loop.\n"); if (DR_IS_READ (dr)) return true; else @@ -2318,7 +2340,7 @@ vect_analyze_data_ref_access (struct data_reference *dr) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "grouped access in outer loop."); + "grouped access in outer loop.\n"); return false; } @@ -2482,7 +2504,7 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_analyze_data_ref_accesses ==="); + "=== vect_analyze_data_ref_accesses ===\n"); if (loop_vinfo) datarefs = LOOP_VINFO_DATAREFS (loop_vinfo); @@ -2567,6 +2589,7 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra)); dump_printf (MSG_NOTE, " and "); dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb)); + dump_printf (MSG_NOTE, "\n"); } /* Link the found element into the group list. */ @@ -2586,8 +2609,8 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) && !vect_analyze_data_ref_access (dr)) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: complicated access pattern."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: complicated access pattern.\n"); if (bb_vinfo) { @@ -2617,7 +2640,7 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_prune_runtime_alias_test_list ==="); + "=== vect_prune_runtime_alias_test_list ===\n"); for (i = 0; i < ddrs.length (); ) { @@ -2636,14 +2659,19 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo) if (dump_enabled_p ()) { dump_printf_loc (MSG_NOTE, vect_location, - "found equal ranges "); - dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (DDR_A (ddr_i))); + "found equal ranges "); + dump_generic_expr (MSG_NOTE, TDF_SLIM, + DR_REF (DDR_A (ddr_i))); dump_printf (MSG_NOTE, ", "); - dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (DDR_B (ddr_i))); + dump_generic_expr (MSG_NOTE, TDF_SLIM, + DR_REF (DDR_B (ddr_i))); dump_printf (MSG_NOTE, " and "); - dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (DDR_A (ddr_j))); + dump_generic_expr (MSG_NOTE, TDF_SLIM, + DR_REF (DDR_A (ddr_j))); dump_printf (MSG_NOTE, ", "); - dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (DDR_B (ddr_j))); + dump_generic_expr (MSG_NOTE, TDF_SLIM, + DR_REF (DDR_B (ddr_j))); + dump_printf (MSG_NOTE, "\n"); } found = true; break; @@ -2663,9 +2691,9 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) { - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "disable versioning for alias - max number of " - "generated checks exceeded."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "disable versioning for alias - max number of " + "generated checks exceeded.\n"); } LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo).truncate (0); @@ -2908,9 +2936,9 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, (loop, &LOOP_VINFO_DATAREFS (loop_vinfo))) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: loop contains function calls" - " or data references that cannot be analyzed"); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: loop contains function calls" + " or data references that cannot be analyzed\n"); return false; } @@ -2957,7 +2985,7 @@ again: { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: unhandled data-ref "); + "not vectorized: unhandled data-ref\n"); return false; } @@ -3039,6 +3067,8 @@ again: { DR_OFFSET (newdr) = ssize_int (0); DR_STEP (newdr) = step; + DR_ALIGNED_TO (newdr) + = size_int (BIGGEST_ALIGNMENT); dr = newdr; simd_lane_access = true; } @@ -3060,10 +3090,11 @@ again: { if (dump_enabled_p ()) { - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not vectorized: data ref analysis " "failed "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } if (bb_vinfo) @@ -3078,7 +3109,7 @@ again: if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not vectorized: base addr of dr is a " - "constant"); + "constant\n"); if (bb_vinfo) break; @@ -3095,6 +3126,7 @@ again: dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not vectorized: volatile type "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } if (bb_vinfo) @@ -3111,6 +3143,7 @@ again: "not vectorized: statement can throw an " "exception "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } if (bb_vinfo) @@ -3130,6 +3163,7 @@ again: "not vectorized: statement is bitfield " "access "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } if (bb_vinfo) @@ -3149,8 +3183,9 @@ again: if (dump_enabled_p ()) { dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: dr in a call "); + "not vectorized: dr in a call "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } if (bb_vinfo) @@ -3190,6 +3225,7 @@ again: dump_printf_loc (MSG_NOTE, vect_location, "analyze in outer-loop: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, inner_base); + dump_printf (MSG_NOTE, "\n"); } outer_base = get_inner_reference (inner_base, &pbitsize, &pbitpos, @@ -3209,7 +3245,7 @@ again: &base_iv, false)) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "failed: evolution of base is not affine.\n"); return false; } @@ -3232,7 +3268,7 @@ again: &offset_iv, false)) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "evolution of offset is not affine.\n"); return false; } @@ -3275,6 +3311,7 @@ again: dump_printf (MSG_NOTE, "\n\touter aligned to: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, STMT_VINFO_DR_ALIGNED_TO (stmt_info)); + dump_printf (MSG_NOTE, "\n"); } } @@ -3286,6 +3323,7 @@ again: "not vectorized: more than one data ref " "in stmt: "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } if (bb_vinfo) @@ -3311,12 +3349,13 @@ again: { if (dump_enabled_p ()) { - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not vectorized: no vectype for stmt: "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); dump_printf (MSG_MISSED_OPTIMIZATION, " scalar_type: "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_DETAILS, scalar_type); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } if (bb_vinfo) @@ -3338,6 +3377,7 @@ again: dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); dump_generic_expr (MSG_NOTE, TDF_SLIM, STMT_VINFO_VECTYPE (stmt_info)); + dump_printf (MSG_NOTE, "\n"); } } @@ -3365,6 +3405,7 @@ again: "not vectorized: not suitable for gather " "load "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -3384,6 +3425,7 @@ again: "not vectorized: not suitable for strided " "load "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -3569,6 +3611,7 @@ vect_create_addr_base_for_vector_ref (gimple stmt, { dump_printf_loc (MSG_NOTE, vect_location, "created "); dump_generic_expr (MSG_NOTE, TDF_SLIM, addr_base); + dump_printf (MSG_NOTE, "\n"); } return addr_base; @@ -3700,6 +3743,7 @@ vect_create_data_ref_ptr (gimple stmt, tree aggr_type, struct loop *at_loop, else dump_printf (MSG_NOTE, " vectorizing a pointer ref: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_BASE_OBJECT (dr)); + dump_printf (MSG_NOTE, "\n"); } /* (1) Create the new aggregate-pointer variable. @@ -4005,7 +4049,7 @@ vect_grouped_store_supported (tree vectype, unsigned HOST_WIDE_INT count) if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "the size of the group of accesses" - " is not a power of 2"); + " is not a power of 2\n"); return false; } @@ -4030,7 +4074,7 @@ vect_grouped_store_supported (tree vectype, unsigned HOST_WIDE_INT count) if (dump_enabled_p ()) dump_printf (MSG_MISSED_OPTIMIZATION, - "interleave op not supported by target."); + "interleave op not supported by target.\n"); return false; } @@ -4452,7 +4496,7 @@ vect_grouped_load_supported (tree vectype, unsigned HOST_WIDE_INT count) if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "the size of the group of accesses" - " is not a power of 2"); + " is not a power of 2\n"); return false; } @@ -4475,7 +4519,7 @@ vect_grouped_load_supported (tree vectype, unsigned HOST_WIDE_INT count) if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "extract even/odd not supported by target"); + "extract even/odd not supported by target\n"); return false; } diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index fac42b12113..bd77473e9a3 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -683,6 +683,7 @@ slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters) dump_printf (MSG_NOTE, "\nloop at %s:%d: ", LOC_FILE (loop_loc), LOC_LINE (loop_loc)); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, cond_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } loop->nb_iterations = niters; } @@ -1552,7 +1553,7 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo) /* Analyze phi functions of the loop header. */ if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "vect_can_advance_ivs_p:"); + dump_printf_loc (MSG_NOTE, vect_location, "vect_can_advance_ivs_p:\n"); for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { tree evolution_part; @@ -1562,6 +1563,7 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo) { dump_printf_loc (MSG_NOTE, vect_location, "Analyze phi: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0); + dump_printf (MSG_NOTE, "\n"); } /* Skip virtual phi's. The data dependences that are associated with @@ -1571,7 +1573,7 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "virtual phi. skip."); + "virtual phi. skip.\n"); continue; } @@ -1581,7 +1583,7 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "reduc phi. skip."); + "reduc phi. skip.\n"); continue; } @@ -1593,7 +1595,7 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) dump_printf (MSG_MISSED_OPTIMIZATION, - "No access function or evolution."); + "No access function or evolution.\n"); return false; } @@ -1682,6 +1684,7 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters, dump_printf_loc (MSG_NOTE, vect_location, "vect_update_ivs_after_vectorizer: phi: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0); + dump_printf (MSG_NOTE, "\n"); } /* Skip virtual phi's. */ @@ -1689,7 +1692,7 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "virtual phi. skip."); + "virtual phi. skip.\n"); continue; } @@ -1699,7 +1702,7 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "reduc phi. skip."); + "reduc phi. skip.\n"); continue; } @@ -1762,7 +1765,7 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_do_peeling_for_loop_bound ==="); + "=== vect_do_peeling_for_loop_bound ===\n"); initialize_original_copy_tables (); @@ -1881,7 +1884,7 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters, int if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "known peeling = %d.", npeel); + "known peeling = %d.\n", npeel); iters = build_int_cst (niters_type, npeel); *bound = LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo); @@ -1938,6 +1941,7 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters, int dump_printf_loc (MSG_NOTE, vect_location, "niters for prolog loop: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, iters); + dump_printf (MSG_NOTE, "\n"); } var = create_tmp_var (niters_type, "prolog_loop_niters"); @@ -1993,7 +1997,7 @@ vect_update_inits_of_drs (loop_vec_info loop_vinfo, tree niters) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_update_inits_of_dr ==="); + "=== vect_update_inits_of_dr ===\n"); FOR_EACH_VEC_ELT (datarefs, i, dr) vect_update_init_of_dr (dr, niters); @@ -2338,6 +2342,7 @@ vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo, tree * cond_expr) dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dr_a)); dump_printf (MSG_NOTE, " and "); dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dr_b)); + dump_printf (MSG_NOTE, "\n"); } seg_a_min = addr_base_a; diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 1290f1550b0..2871ba1ce75 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -188,7 +188,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_determine_vectorization_factor ==="); + "=== vect_determine_vectorization_factor ===\n"); for (i = 0; i < nbbs; i++) { @@ -202,6 +202,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) { dump_printf_loc (MSG_NOTE, vect_location, "==> examining phi: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0); + dump_printf (MSG_NOTE, "\n"); } gcc_assert (stmt_info); @@ -216,6 +217,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) dump_printf_loc (MSG_NOTE, vect_location, "get vectype for scalar type: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, scalar_type); + dump_printf (MSG_NOTE, "\n"); } vectype = get_vectype_for_scalar_type (scalar_type); @@ -228,6 +230,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) "data-type "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, scalar_type); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -237,11 +240,13 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) { dump_printf_loc (MSG_NOTE, vect_location, "vectype: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, vectype); + dump_printf (MSG_NOTE, "\n"); } nunits = TYPE_VECTOR_SUBPARTS (vectype); if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "nunits = %d", nunits); + dump_printf_loc (MSG_NOTE, vect_location, "nunits = %d\n", + nunits); if (!vectorization_factor || (nunits > vectorization_factor)) @@ -265,6 +270,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) dump_printf_loc (MSG_NOTE, vect_location, "==> examining statement: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); + dump_printf (MSG_NOTE, "\n"); } gcc_assert (stmt_info); @@ -286,12 +292,13 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) dump_printf_loc (MSG_NOTE, vect_location, "==> examining pattern statement: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); + dump_printf (MSG_NOTE, "\n"); } } else { if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "skip."); + dump_printf_loc (MSG_NOTE, vect_location, "skip.\n"); gsi_next (&si); continue; } @@ -336,6 +343,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) "==> examining pattern def stmt: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_def_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } stmt = pattern_def_stmt; @@ -359,6 +367,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) "not vectorized: irregular stmt."); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -370,6 +379,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not vectorized: vector stmt in loop:"); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -394,6 +404,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) dump_printf_loc (MSG_NOTE, vect_location, "get vectype for scalar type: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, scalar_type); + dump_printf (MSG_NOTE, "\n"); } vectype = get_vectype_for_scalar_type (scalar_type); if (!vectype) @@ -405,6 +416,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) "data-type "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, scalar_type); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -415,6 +427,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) { dump_printf_loc (MSG_NOTE, vect_location, "vectype: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, vectype); + dump_printf (MSG_NOTE, "\n"); } } @@ -428,6 +441,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) dump_printf_loc (MSG_NOTE, vect_location, "get vectype for scalar type: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, scalar_type); + dump_printf (MSG_NOTE, "\n"); } vf_vectype = get_vectype_for_scalar_type (scalar_type); if (!vf_vectype) @@ -438,6 +452,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) "not vectorized: unsupported data-type "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, scalar_type); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -455,6 +470,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) dump_printf (MSG_MISSED_OPTIMIZATION, " and "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, vf_vectype); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -463,11 +479,12 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) { dump_printf_loc (MSG_NOTE, vect_location, "vectype: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, vf_vectype); + dump_printf (MSG_NOTE, "\n"); } nunits = TYPE_VECTOR_SUBPARTS (vf_vectype); if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "nunits = %d", nunits); + dump_printf_loc (MSG_NOTE, vect_location, "nunits = %d\n", nunits); if (!vectorization_factor || (nunits > vectorization_factor)) vectorization_factor = nunits; @@ -482,13 +499,13 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) /* TODO: Analyze cost. Decide if worth while to vectorize. */ if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "vectorization factor = %d", + dump_printf_loc (MSG_NOTE, vect_location, "vectorization factor = %d\n", vectorization_factor); if (vectorization_factor <= 1) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: unsupported data-type"); + "not vectorized: unsupported data-type\n"); return false; } LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor; @@ -530,6 +547,7 @@ vect_is_simple_iv_evolution (unsigned loop_nb, tree access_fn, tree * init, dump_generic_expr (MSG_NOTE, TDF_SLIM, step_expr); dump_printf (MSG_NOTE, ", init: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, init_expr); + dump_printf (MSG_NOTE, "\n"); } *init = init_expr; @@ -547,7 +565,7 @@ vect_is_simple_iv_evolution (unsigned loop_nb, tree access_fn, tree * init, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "step unknown."); + "step unknown.\n"); return false; } @@ -573,7 +591,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_analyze_scalar_cycles ==="); + "=== vect_analyze_scalar_cycles ===\n"); /* First - identify all inductions. Reduction detection assumes that all the inductions have been identified, therefore, this order must not be @@ -589,6 +607,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop) { dump_printf_loc (MSG_NOTE, vect_location, "Analyze phi: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0); + dump_printf (MSG_NOTE, "\n"); } /* Skip virtual phi's. The data dependences that are associated with @@ -608,6 +627,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop) dump_printf_loc (MSG_NOTE, vect_location, "Access function of PHI: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, access_fn); + dump_printf (MSG_NOTE, "\n"); } STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_vinfo) = evolution_part_in_loop_num (access_fn, loop->num); @@ -625,7 +645,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop) gcc_assert (STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_vinfo) != NULL_TREE); if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "Detected induction."); + dump_printf_loc (MSG_NOTE, vect_location, "Detected induction.\n"); STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_induction_def; } @@ -643,6 +663,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop) { dump_printf_loc (MSG_NOTE, vect_location, "Analyze phi: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0); + dump_printf (MSG_NOTE, "\n"); } gcc_assert (!virtual_operand_p (def) @@ -657,7 +678,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Detected double reduction."); + "Detected double reduction.\n"); STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_double_reduction_def; STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) = @@ -669,7 +690,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Detected vectorizable nested cycle."); + "Detected vectorizable nested cycle.\n"); STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_nested_cycle; STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) = @@ -679,7 +700,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Detected reduction."); + "Detected reduction.\n"); STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_reduction_def; STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) = @@ -693,7 +714,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop) else if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Unknown def-use cycle pattern."); + "Unknown def-use cycle pattern.\n"); } worklist.release (); @@ -755,7 +776,7 @@ vect_get_loop_niters (struct loop *loop, tree *number_of_iterations) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== get_loop_niters ==="); + "=== get_loop_niters ===\n"); niters = number_of_exit_cond_executions (loop); if (niters != NULL_TREE @@ -767,6 +788,7 @@ vect_get_loop_niters (struct loop *loop, tree *number_of_iterations) { dump_printf_loc (MSG_NOTE, vect_location, "==> get_loop_niters:"); dump_generic_expr (MSG_NOTE, TDF_SLIM, *number_of_iterations); + dump_printf (MSG_NOTE, "\n"); } } @@ -996,7 +1018,7 @@ vect_analyze_loop_1 (struct loop *loop) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "===== analyze_loop_nest_1 ====="); + "===== analyze_loop_nest_1 =====\n"); /* Check the CFG characteristics of the loop (nesting, entry/exit, etc. */ @@ -1005,7 +1027,7 @@ vect_analyze_loop_1 (struct loop *loop) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "bad inner-loop form."); + "bad inner-loop form.\n"); return NULL; } @@ -1031,7 +1053,7 @@ vect_analyze_loop_form (struct loop *loop) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_analyze_loop_form ==="); + "=== vect_analyze_loop_form ===\n"); /* Different restrictions apply when we are considering an inner-most loop, vs. an outer (nested) loop. @@ -1055,7 +1077,7 @@ vect_analyze_loop_form (struct loop *loop) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: control flow in loop."); + "not vectorized: control flow in loop.\n"); return NULL; } @@ -1063,7 +1085,7 @@ vect_analyze_loop_form (struct loop *loop) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: empty loop."); + "not vectorized: empty loop.\n"); return NULL; } } @@ -1093,7 +1115,7 @@ vect_analyze_loop_form (struct loop *loop) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: multiple nested loops."); + "not vectorized: multiple nested loops.\n"); return NULL; } @@ -1103,7 +1125,7 @@ vect_analyze_loop_form (struct loop *loop) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: Bad inner loop."); + "not vectorized: Bad inner loop.\n"); return NULL; } @@ -1111,8 +1133,9 @@ vect_analyze_loop_form (struct loop *loop) LOOP_VINFO_NITERS (inner_loop_vinfo))) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: inner-loop count not invariant."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: inner-loop count not" + " invariant.\n"); destroy_loop_vec_info (inner_loop_vinfo, true); return NULL; } @@ -1121,7 +1144,7 @@ vect_analyze_loop_form (struct loop *loop) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: control flow in loop."); + "not vectorized: control flow in loop.\n"); destroy_loop_vec_info (inner_loop_vinfo, true); return NULL; } @@ -1136,15 +1159,15 @@ vect_analyze_loop_form (struct loop *loop) || single_exit (innerloop)->dest != EDGE_PRED (loop->latch, 0)->src) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: unsupported outerloop form."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: unsupported outerloop form.\n"); destroy_loop_vec_info (inner_loop_vinfo, true); return NULL; } if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Considering outer-loop vectorization."); + "Considering outer-loop vectorization.\n"); } if (!single_exit (loop) @@ -1154,10 +1177,10 @@ vect_analyze_loop_form (struct loop *loop) { if (!single_exit (loop)) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: multiple exits."); + "not vectorized: multiple exits.\n"); else if (EDGE_COUNT (loop->header->preds) != 2) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: too many incoming edges."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: too many incoming edges.\n"); } if (inner_loop_vinfo) destroy_loop_vec_info (inner_loop_vinfo, true); @@ -1173,7 +1196,7 @@ vect_analyze_loop_form (struct loop *loop) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: latch block not empty."); + "not vectorized: latch block not empty.\n"); if (inner_loop_vinfo) destroy_loop_vec_info (inner_loop_vinfo, true); return NULL; @@ -1187,13 +1210,13 @@ vect_analyze_loop_form (struct loop *loop) { split_loop_exit_edge (e); if (dump_enabled_p ()) - dump_printf (MSG_NOTE, "split exit edge."); + dump_printf (MSG_NOTE, "split exit edge.\n"); } else { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: abnormal loop exit edge."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: abnormal loop exit edge.\n"); if (inner_loop_vinfo) destroy_loop_vec_info (inner_loop_vinfo, true); return NULL; @@ -1204,8 +1227,8 @@ vect_analyze_loop_form (struct loop *loop) if (!loop_cond) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: complicated exit condition."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: complicated exit condition.\n"); if (inner_loop_vinfo) destroy_loop_vec_info (inner_loop_vinfo, true); return NULL; @@ -1214,9 +1237,9 @@ vect_analyze_loop_form (struct loop *loop) if (!number_of_iterations) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not vectorized: number of iterations cannot be " - "computed."); + "computed.\n"); if (inner_loop_vinfo) destroy_loop_vec_info (inner_loop_vinfo, true); return NULL; @@ -1226,7 +1249,7 @@ vect_analyze_loop_form (struct loop *loop) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Infinite number of iterations."); + "Infinite number of iterations.\n"); if (inner_loop_vinfo) destroy_loop_vec_info (inner_loop_vinfo, true); return NULL; @@ -1239,13 +1262,14 @@ vect_analyze_loop_form (struct loop *loop) dump_printf_loc (MSG_NOTE, vect_location, "Symbolic number of iterations is "); dump_generic_expr (MSG_NOTE, TDF_DETAILS, number_of_iterations); + dump_printf (MSG_NOTE, "\n"); } } else if (TREE_INT_CST_LOW (number_of_iterations) == 0) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: number of iterations = 0."); + "not vectorized: number of iterations = 0.\n"); if (inner_loop_vinfo) destroy_loop_vec_info (inner_loop_vinfo, true); return NULL; @@ -1293,7 +1317,7 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_analyze_loop_operations ==="); + "=== vect_analyze_loop_operations ===\n"); gcc_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo)); vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo); @@ -1329,7 +1353,7 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor; if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Updating vectorization factor to %d ", + "Updating vectorization factor to %d\n", vectorization_factor); } @@ -1347,6 +1371,7 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) { dump_printf_loc (MSG_NOTE, vect_location, "examining phi: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0); + dump_printf (MSG_NOTE, "\n"); } /* Inner-loop loop-closed exit phi in outer-loop vectorization @@ -1363,9 +1388,9 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) != vect_double_reduction_def) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "Unsupported loop-closed phi in " - "outer-loop."); + "outer-loop.\n"); return false; } @@ -1406,7 +1431,7 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) /* FORNOW: not yet supported. */ if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: value used after loop."); + "not vectorized: value used after loop.\n"); return false; } @@ -1415,8 +1440,8 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) { /* A scalar-dependence cycle that we don't support. */ if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: scalar dependence cycle."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: scalar dependence cycle.\n"); return false; } @@ -1431,10 +1456,11 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) { if (dump_enabled_p ()) { - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not vectorized: relevant phi not " "supported: "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, phi, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -1458,18 +1484,18 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "All the computation can be taken out of the loop."); + "All the computation can be taken out of the loop.\n"); if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not vectorized: redundant loop. no profit to " - "vectorize."); + "vectorize.\n"); return false; } if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) && dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "vectorization_factor = %d, niters = " - HOST_WIDE_INT_PRINT_DEC, vectorization_factor, + HOST_WIDE_INT_PRINT_DEC "\n", vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo)); if ((LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) @@ -1479,11 +1505,11 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: iteration count too small."); + "not vectorized: iteration count too small.\n"); if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not vectorized: iteration count smaller than " - "vectorization factor."); + "vectorization factor.\n"); return false; } @@ -1501,11 +1527,11 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: vectorization not profitable."); + "not vectorized: vectorization not profitable.\n"); if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not vectorized: vector version will never be " - "profitable."); + "profitable.\n"); return false; } @@ -1527,12 +1553,12 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: vectorization not profitable."); + "not vectorized: vectorization not profitable.\n"); if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "not vectorized: iteration count smaller than user " "specified loop bound parameter or minimum profitable " - "iterations (whichever is more conservative)."); + "iterations (whichever is more conservative).\n"); return false; } @@ -1543,13 +1569,13 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not vectorized: estimated iteration count too " - "small."); + "small.\n"); if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "not vectorized: estimated iteration count smaller " "than specified loop bound parameter or minimum " "profitable iterations (whichever is more " - "conservative)."); + "conservative).\n"); return false; } @@ -1558,19 +1584,19 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) || LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo)) { if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "epilog loop required."); + dump_printf_loc (MSG_NOTE, vect_location, "epilog loop required.\n"); if (!vect_can_advance_ivs_p (loop_vinfo)) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: can't create epilog loop 1."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: can't create epilog loop 1.\n"); return false; } if (!slpeel_can_duplicate_loop_p (loop, single_exit (loop))) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: can't create epilog loop 2."); + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: can't create epilog loop 2.\n"); return false; } } @@ -1603,7 +1629,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "bad data references."); + "bad data references.\n"); return false; } @@ -1615,7 +1641,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "bad data access."); + "bad data access.\n"); return false; } @@ -1633,7 +1659,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "unexpected pattern."); + "unexpected pattern.\n"); return false; } @@ -1648,7 +1674,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "bad data dependence."); + "bad data dependence.\n"); return false; } @@ -1657,14 +1683,14 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "can't determine vectorization factor."); + "can't determine vectorization factor.\n"); return false; } if (max_vf < LOOP_VINFO_VECT_FACTOR (loop_vinfo)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "bad data dependence."); + "bad data dependence.\n"); return false; } @@ -1676,7 +1702,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "bad data alignment."); + "bad data alignment.\n"); return false; } @@ -1689,7 +1715,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "too long list of versioning for alias " - "run-time tests."); + "run-time tests.\n"); return false; } @@ -1701,7 +1727,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "bad data alignment."); + "bad data alignment.\n"); return false; } @@ -1726,7 +1752,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "bad operation or unsupported loop bound."); + "bad operation or unsupported loop bound.\n"); return false; } @@ -1750,7 +1776,7 @@ vect_analyze_loop (struct loop *loop) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "===== analyze_loop_nest ====="); + "===== analyze_loop_nest =====\n"); if (loop_outer (loop) && loop_vec_info_for_loop (loop_outer (loop)) @@ -1758,7 +1784,7 @@ vect_analyze_loop (struct loop *loop) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "outer-loop already vectorized."); + "outer-loop already vectorized.\n"); return NULL; } @@ -1770,7 +1796,7 @@ vect_analyze_loop (struct loop *loop) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "bad loop form."); + "bad loop form.\n"); return NULL; } @@ -1851,6 +1877,7 @@ report_vect_op (int msg_type, gimple stmt, const char *msg) { dump_printf_loc (msg_type, vect_location, "%s", msg); dump_gimple_stmt (msg_type, TDF_SLIM, stmt, 0); + dump_printf (msg_type, "\n"); } @@ -2026,6 +2053,7 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt) { dump_printf_loc (MSG_NOTE, vect_location, "swapping oprnds: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, next_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } swap_tree_operands (next_stmt, @@ -2126,7 +2154,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "intermediate value used outside loop."); + "intermediate value used outside loop.\n"); return NULL; } @@ -2138,7 +2166,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "reduction used in loop."); + "reduction used in loop.\n"); return NULL; } } @@ -2150,6 +2178,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "reduction: not ssa_name: "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, loop_arg); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return NULL; } @@ -2159,14 +2188,17 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "reduction: no def_stmt."); + "reduction: no def_stmt.\n"); return NULL; } if (!is_gimple_assign (def_stmt) && gimple_code (def_stmt) != GIMPLE_PHI) { if (dump_enabled_p ()) - dump_gimple_stmt (MSG_NOTE, TDF_SLIM, def_stmt, 0); + { + dump_gimple_stmt (MSG_NOTE, TDF_SLIM, def_stmt, 0); + dump_printf (MSG_NOTE, "\n"); + } return NULL; } @@ -2195,7 +2227,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "reduction used in loop."); + "reduction used in loop.\n"); return NULL; } } @@ -2211,7 +2243,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "unsupported phi node definition."); + "unsupported phi node definition.\n"); return NULL; } @@ -2334,6 +2366,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi, dump_generic_expr (MSG_NOTE, TDF_SLIM, TREE_TYPE (op4)); } + dump_printf (MSG_NOTE, "\n"); } return NULL; @@ -2591,7 +2624,7 @@ vect_get_known_peeling_cost (loop_vec_info loop_vinfo, int peel_iters_prologue, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "cost model: epilogue peel iters set to vf/2 " - "because loop iterations are unknown ."); + "because loop iterations are unknown .\n"); /* If peeled iterations are known but number of scalar loop iterations are unknown, count a taken branch per peeled loop. */ @@ -2649,7 +2682,7 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, /* Cost model disabled. */ if (!flag_vect_cost_model) { - dump_printf_loc (MSG_NOTE, vect_location, "cost model disabled."); + dump_printf_loc (MSG_NOTE, vect_location, "cost model disabled.\n"); *ret_min_profitable_niters = 0; *ret_min_profitable_estimate = 0; return; @@ -2707,14 +2740,14 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, { peel_iters_prologue = vf/2; dump_printf (MSG_NOTE, "cost model: " - "prologue peel iters set to vf/2."); + "prologue peel iters set to vf/2.\n"); /* If peeling for alignment is unknown, loop bound of main loop becomes unknown. */ peel_iters_epilogue = vf/2; dump_printf (MSG_NOTE, "cost model: " "epilogue peel iters set to vf/2 because " - "peeling for alignment is unknown."); + "peeling for alignment is unknown.\n"); /* If peeled iterations are unknown, count a taken branch and a not taken branch per peeled loop. Even if scalar loop iterations are known, @@ -2884,7 +2917,8 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "cost model: the vector iteration cost = %d " "divided by the scalar iteration cost = %d " - "is greater or equal to the vectorization factor = %d.", + "is greater or equal to the vectorization factor = %d" + ".\n", vec_inside_cost, scalar_single_iter_cost, vf); *ret_min_profitable_niters = -1; *ret_min_profitable_estimate = -1; @@ -2910,9 +2944,10 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, peel_iters_prologue); dump_printf (MSG_NOTE, " epilogue iterations: %d\n", peel_iters_epilogue); - dump_printf (MSG_NOTE, + dump_printf (MSG_NOTE, " Calculated minimum iters for profitability: %d\n", min_profitable_iters); + dump_printf (MSG_NOTE, "\n"); } min_profitable_iters = @@ -2925,7 +2960,8 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - " Runtime profitability threshold = %d\n", min_profitable_iters); + " Runtime profitability threshold = %d\n", + min_profitable_iters); *ret_min_profitable_niters = min_profitable_iters; @@ -3014,6 +3050,7 @@ vect_model_reduction_cost (stmt_vec_info stmt_info, enum tree_code reduc_code, "unsupported data-type "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, TREE_TYPE (reduction_op)); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -3082,7 +3119,7 @@ vect_model_reduction_cost (stmt_vec_info stmt_info, enum tree_code reduc_code, if (dump_enabled_p ()) dump_printf (MSG_NOTE, "vect_model_reduction_cost: inside_cost = %d, " - "prologue_cost = %d, epilogue_cost = %d .", inside_cost, + "prologue_cost = %d, epilogue_cost = %d .\n", inside_cost, prologue_cost, epilogue_cost); return true; @@ -3111,7 +3148,7 @@ vect_model_induction_cost (stmt_vec_info stmt_info, int ncopies) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "vect_model_induction_cost: inside_cost = %d, " - "prologue_cost = %d .", inside_cost, prologue_cost); + "prologue_cost = %d .\n", inside_cost, prologue_cost); } @@ -3258,6 +3295,7 @@ get_initial_def_for_induction (gimple iv_phi) dump_printf_loc (MSG_NOTE, vect_location, "created new init_stmt: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, init_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } constant_p = false; } @@ -3426,6 +3464,7 @@ get_initial_def_for_induction (gimple iv_phi) dump_printf_loc (MSG_NOTE, vect_location, "vector of inductions after inner-loop:"); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, new_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } } } @@ -3439,6 +3478,7 @@ get_initial_def_for_induction (gimple iv_phi) dump_printf (MSG_NOTE, "\n"); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, SSA_NAME_DEF_STMT (vec_def), 0); + dump_printf (MSG_NOTE, "\n"); } STMT_VINFO_VEC_STMT (phi_info) = induction_phi; @@ -3846,6 +3886,7 @@ vect_create_epilog_for_reduction (vec<tree> vect_defs, gimple stmt, dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0); dump_printf (MSG_NOTE, "\n"); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, SSA_NAME_DEF_STMT (def), 0); + dump_printf (MSG_NOTE, "\n"); } phi = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (phi)); @@ -4042,7 +4083,7 @@ vect_create_epilog_for_reduction (vec<tree> vect_defs, gimple stmt, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Reduce using direct vector reduction."); + "Reduce using direct vector reduction.\n"); vec_dest = vect_create_destination_var (scalar_dest, vectype); tmp = build1 (reduc_code, vectype, new_phi_result); @@ -4093,7 +4134,7 @@ vect_create_epilog_for_reduction (vec<tree> vect_defs, gimple stmt, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Reduce using vector shifts"); + "Reduce using vector shifts\n"); vec_dest = vect_create_destination_var (scalar_dest, vectype); new_temp = new_phi_result; @@ -4134,7 +4175,7 @@ vect_create_epilog_for_reduction (vec<tree> vect_defs, gimple stmt, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Reduce using scalar code. "); + "Reduce using scalar code.\n"); vec_size_in_bits = tree_low_cst (TYPE_SIZE (vectype), 1); FOR_EACH_VEC_ELT (new_phis, i, new_phi) @@ -4225,7 +4266,7 @@ vect_create_epilog_for_reduction (vec<tree> vect_defs, gimple stmt, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "extract scalar result"); + "extract scalar result\n"); if (BYTES_BIG_ENDIAN) bitpos = size_binop (MULT_EXPR, @@ -4464,6 +4505,7 @@ vect_finalize_reduction: dump_printf_loc (MSG_NOTE, vect_location, "created double reduction phi node: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, vect_phi, 0); + dump_printf (MSG_NOTE, "\n"); } vect_phi_res = PHI_RESULT (vect_phi); @@ -4819,7 +4861,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "unsupported condition in reduction"); + "unsupported condition in reduction\n"); return false; } @@ -4835,7 +4877,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, not vectorizable_reduction. */ if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "unsupported shift or rotation."); + "unsupported shift or rotation.\n"); return false; } @@ -4845,7 +4887,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "no optab."); + "no optab.\n"); return false; } @@ -4853,7 +4895,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, if (optab_handler (optab, vec_mode) == CODE_FOR_nothing) { if (dump_enabled_p ()) - dump_printf (MSG_NOTE, "op not supported by target."); + dump_printf (MSG_NOTE, "op not supported by target.\n"); if (GET_MODE_SIZE (vec_mode) != UNITS_PER_WORD || LOOP_VINFO_VECT_FACTOR (loop_vinfo) @@ -4861,7 +4903,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, return false; if (dump_enabled_p ()) - dump_printf (MSG_NOTE, "proceeding using word mode."); + dump_printf (MSG_NOTE, "proceeding using word mode.\n"); } /* Worthwhile without SIMD support? */ @@ -4871,7 +4913,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not worthwhile without SIMD support."); + "not worthwhile without SIMD support.\n"); return false; } @@ -4952,7 +4994,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "no optab for reduction."); + "no optab for reduction.\n"); epilog_reduc_code = ERROR_MARK; } @@ -4962,7 +5004,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "reduc op not supported by target."); + "reduc op not supported by target.\n"); epilog_reduc_code = ERROR_MARK; } @@ -4973,7 +5015,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "no reduc code for scalar code."); + "no reduc code for scalar code.\n"); return false; } @@ -4983,7 +5025,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "multiple types in double reduction"); + "multiple types in double reduction\n"); return false; } @@ -5002,7 +5044,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "invalid types in dot-prod"); + "invalid types in dot-prod\n"); return false; } @@ -5019,7 +5061,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, /** Transform. **/ if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "transform reduction."); + dump_printf_loc (MSG_NOTE, vect_location, "transform reduction.\n"); /* FORNOW: Multiple types are not supported for condition. */ if (code == COND_EXPR) @@ -5306,7 +5348,7 @@ vectorizable_induction (gimple phi, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "multiple types in nested loop."); + "multiple types in nested loop.\n"); return false; } @@ -5329,9 +5371,9 @@ vectorizable_induction (gimple phi, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, && !STMT_VINFO_LIVE_P (exit_phi_vinfo))) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "inner-loop induction only used outside " - "of the outer vectorized loop."); + "of the outer vectorized loop.\n"); return false; } } @@ -5354,7 +5396,7 @@ vectorizable_induction (gimple phi, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, STMT_VINFO_TYPE (stmt_info) = induc_vec_info_type; if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vectorizable_induction ==="); + "=== vectorizable_induction ===\n"); vect_model_induction_cost (stmt_info, ncopies); return true; } @@ -5362,7 +5404,7 @@ vectorizable_induction (gimple phi, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, /** Transform. **/ if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "transform induction phi."); + dump_printf_loc (MSG_NOTE, vect_location, "transform induction phi.\n"); vec_def = get_initial_def_for_induction (phi); *vec_stmt = SSA_NAME_DEF_STMT (vec_def); @@ -5462,7 +5504,7 @@ vectorizable_live_operation (gimple stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "use not simple."); + "use not simple.\n"); return false; } @@ -5501,7 +5543,7 @@ vect_loop_kill_debug_uses (struct loop *loop, gimple stmt) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "killing debug use"); + "killing debug use\n"); gimple_debug_bind_reset_value (ustmt); update_stmt (ustmt); @@ -5542,7 +5584,7 @@ vect_transform_loop (loop_vec_info loop_vinfo) gcov_type expected_iterations = expected_loop_iterations_unbounded (loop); if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "=== vec_transform_loop ==="); + dump_printf_loc (MSG_NOTE, vect_location, "=== vec_transform_loop ===\n"); /* If profile is inprecise, we have chance to fix it up. */ if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)) @@ -5561,7 +5603,8 @@ vect_transform_loop (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Profitability threshold is %d loop iterations.", th); + "Profitability threshold is %d loop iterations.\n", + th); check_profitability = true; } @@ -5628,6 +5671,7 @@ vect_transform_loop (loop_vec_info loop_vinfo) dump_printf_loc (MSG_NOTE, vect_location, "------>vectorizing phi: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0); + dump_printf (MSG_NOTE, "\n"); } stmt_info = vinfo_for_stmt (phi); if (!stmt_info) @@ -5643,12 +5687,12 @@ vect_transform_loop (loop_vec_info loop_vinfo) if ((TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info)) != (unsigned HOST_WIDE_INT) vectorization_factor) && dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "multiple-types."); + dump_printf_loc (MSG_NOTE, vect_location, "multiple-types.\n"); if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def) { if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "transform phi."); + dump_printf_loc (MSG_NOTE, vect_location, "transform phi.\n"); vect_transform_stmt (phi, NULL, NULL, NULL, NULL); } } @@ -5678,6 +5722,7 @@ vect_transform_loop (loop_vec_info loop_vinfo) dump_printf_loc (MSG_NOTE, vect_location, "------>vectorizing statement: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); + dump_printf (MSG_NOTE, "\n"); } stmt_info = vinfo_for_stmt (stmt); @@ -5752,6 +5797,7 @@ vect_transform_loop (loop_vec_info loop_vinfo) "stmt: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_def_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } stmt = pattern_def_stmt; @@ -5776,7 +5822,7 @@ vect_transform_loop (loop_vec_info loop_vinfo) /* For SLP VF is set according to unrolling factor, and not to vector size, hence for SLP this print is not valid. */ dump_printf_loc (MSG_NOTE, vect_location, - "multiple-types."); + "multiple-types.\n"); /* SLP. Schedule all the SLP instances when the first SLP stmt is reached. */ @@ -5788,7 +5834,7 @@ vect_transform_loop (loop_vec_info loop_vinfo) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== scheduling SLP instances ==="); + "=== scheduling SLP instances ===\n"); vect_schedule_slp (loop_vinfo, NULL); } @@ -5807,7 +5853,7 @@ vect_transform_loop (loop_vec_info loop_vinfo) /* -------- vectorize statement ------------ */ if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "transform statement."); + dump_printf_loc (MSG_NOTE, vect_location, "transform statement.\n"); grouped_store = false; is_store = vect_transform_stmt (stmt, &si, &grouped_store, NULL, NULL); @@ -5870,5 +5916,6 @@ vect_transform_loop (loop_vec_info loop_vinfo) if (loop->inner) dump_printf_loc (MSG_NOTE, vect_location, "OUTER LOOP VECTORIZED\n"); + dump_printf (MSG_NOTE, "\n"); } } diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index e078f2dd132..0a4e812fd82 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -397,7 +397,7 @@ vect_recog_dot_prod_pattern (vec<gimple> *stmts, tree *type_in, || !promotion) return NULL; oprnd00 = gimple_assign_rhs1 (def_stmt); - if (!type_conversion_p (oprnd0, stmt, true, &half_type1, &def_stmt, + if (!type_conversion_p (oprnd1, stmt, true, &half_type1, &def_stmt, &promotion) || !promotion) return NULL; @@ -422,6 +422,7 @@ vect_recog_dot_prod_pattern (vec<gimple> *stmts, tree *type_in, dump_printf_loc (MSG_NOTE, vect_location, "vect_recog_dot_prod_pattern: detected: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } /* We don't allow changing the order of the computation in the inner-loop @@ -682,7 +683,7 @@ vect_recog_widen_mult_pattern (vec<gimple> *stmts, /* Pattern detected. */ if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vect_recog_widen_mult_pattern: detected: "); + "vect_recog_widen_mult_pattern: detected:\n"); /* Check target support */ vectype = get_vectype_for_scalar_type (half_type0); @@ -921,6 +922,7 @@ vect_recog_widen_sum_pattern (vec<gimple> *stmts, tree *type_in, dump_printf_loc (MSG_NOTE, vect_location, "vect_recog_widen_sum_pattern: detected: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } /* We don't allow changing the order of the computation in the inner-loop @@ -1226,6 +1228,7 @@ vect_recog_over_widening_pattern (vec<gimple> *stmts, dump_printf_loc (MSG_NOTE, vect_location, "created pattern stmt: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } type = gimple_expr_type (stmt); @@ -1294,6 +1297,7 @@ vect_recog_over_widening_pattern (vec<gimple> *stmts, dump_printf_loc (MSG_NOTE, vect_location, "vect_recog_over_widening_pattern: detected: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } return pattern_stmt; @@ -1427,7 +1431,7 @@ vect_recog_widen_shift_pattern (vec<gimple> *stmts, /* Pattern detected. */ if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vect_recog_widen_shift_pattern: detected: "); + "vect_recog_widen_shift_pattern: detected:\n"); /* Check target support. */ vectype = get_vectype_for_scalar_type (half_type0); @@ -1694,7 +1698,7 @@ vect_recog_rotate_pattern (vec<gimple> *stmts, tree *type_in, tree *type_out) /* Pattern detected. */ if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vect_recog_rotate_pattern: detected: "); + "vect_recog_rotate_pattern: detected:\n"); /* Pattern supported. Create a stmt to be used to replace the pattern. */ var = vect_recog_temp_ssa_var (type, NULL); @@ -1824,7 +1828,7 @@ vect_recog_vector_vector_shift_pattern (vec<gimple> *stmts, /* Pattern detected. */ if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vect_recog_vector_vector_shift_pattern: detected: "); + "vect_recog_vector_vector_shift_pattern: detected:\n"); /* Pattern supported. Create a stmt to be used to replace the pattern. */ var = vect_recog_temp_ssa_var (TREE_TYPE (oprnd0), NULL); @@ -1942,7 +1946,7 @@ vect_recog_divmod_pattern (vec<gimple> *stmts, /* Pattern detected. */ if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vect_recog_divmod_pattern: detected: "); + "vect_recog_divmod_pattern: detected:\n"); cond = build2 (LT_EXPR, boolean_type_node, oprnd0, build_int_cst (itype, 0)); @@ -2291,6 +2295,7 @@ vect_recog_divmod_pattern (vec<gimple> *stmts, dump_printf_loc (MSG_NOTE, vect_location, "vect_recog_divmod_pattern: detected: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } stmts->safe_push (last_stmt); @@ -2456,7 +2461,7 @@ vect_recog_mixed_size_cond_pattern (vec<gimple> *stmts, tree *type_in, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vect_recog_mixed_size_cond_pattern: detected: "); + "vect_recog_mixed_size_cond_pattern: detected:\n"); return pattern_stmt; } @@ -2849,7 +2854,7 @@ vect_recog_bool_pattern (vec<gimple> *stmts, tree *type_in, stmts->safe_push (last_stmt); if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vect_recog_bool_pattern: detected: "); + "vect_recog_bool_pattern: detected:\n"); return pattern_stmt; } @@ -2895,7 +2900,7 @@ vect_recog_bool_pattern (vec<gimple> *stmts, tree *type_in, stmts->safe_push (last_stmt); if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vect_recog_bool_pattern: detected: "); + "vect_recog_bool_pattern: detected:\n"); return pattern_stmt; } else @@ -3048,6 +3053,7 @@ vect_pattern_recog_1 (vect_recog_func_ptr vect_recog_func, dump_printf_loc (MSG_NOTE, vect_location, "pattern recognized: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } /* Mark the stmts that are involved in the pattern. */ @@ -3074,6 +3080,7 @@ vect_pattern_recog_1 (vect_recog_func_ptr vect_recog_func, dump_printf_loc (MSG_NOTE, vect_location, "additional pattern stmt: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } vect_mark_pattern_stmts (stmt, pattern_stmt, NULL_TREE); @@ -3173,7 +3180,7 @@ vect_pattern_recog (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_pattern_recog ==="); + "=== vect_pattern_recog ===\n"); if (loop_vinfo) { diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index cf41a030f2a..8ed0fc58c59 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -257,6 +257,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "Build SLP failed: can't find def for "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, oprnd); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; @@ -283,6 +284,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, "Build SLP failed: some of the stmts" " are in a pattern, and others are not "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, oprnd); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; @@ -295,7 +297,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Unsupported pattern."); + "Unsupported pattern.\n"); return false; } @@ -312,7 +314,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, default: if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "unsupported defining stmt: "); + "unsupported defining stmt:\n"); return false; } } @@ -342,7 +344,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Build SLP failed: different types "); + "Build SLP failed: different types\n"); return false; } @@ -367,6 +369,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "Build SLP failed: illegal type of def "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, def); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; @@ -415,6 +418,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, { dump_printf_loc (MSG_NOTE, vect_location, "Build SLP for "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); + dump_printf (MSG_NOTE, "\n"); } /* Fail to vectorize statements marked as unvectorizable. */ @@ -425,6 +429,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "Build SLP failed: unvectorizable statement "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Fatal mismatch. */ matches[0] = false; @@ -440,6 +445,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, "Build SLP failed: not GIMPLE_ASSIGN nor " "GIMPLE_CALL "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Fatal mismatch. */ matches[0] = false; @@ -457,6 +463,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, "Build SLP failed: condition is not " "comparison "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Fatal mismatch. */ matches[0] = false; @@ -473,6 +480,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, "Build SLP failed: unsupported data-type "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, scalar_type); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Fatal mismatch. */ matches[0] = false; @@ -501,6 +509,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "Build SLP failed: unsupported call type "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Fatal mismatch. */ matches[0] = false; @@ -538,7 +547,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Build SLP failed: no optab."); + "Build SLP failed: no optab.\n"); /* Fatal mismatch. */ matches[0] = false; return false; @@ -549,7 +558,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "Build SLP failed: " - "op not supported by target."); + "op not supported by target.\n"); /* Fatal mismatch. */ matches[0] = false; return false; @@ -588,6 +597,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, "Build SLP failed: different operation " "in stmt "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Mismatch. */ continue; @@ -602,6 +612,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, "Build SLP failed: different shift " "arguments in "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Mismatch. */ continue; @@ -622,6 +633,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, "Build SLP failed: different calls in "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Mismatch. */ continue; @@ -661,6 +673,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, "loads have gaps "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Fatal mismatch. */ matches[0] = false; @@ -685,6 +698,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, "the SLP group size "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Fatal mismatch. */ matches[0] = false; @@ -707,6 +721,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, "interleaving chains in one node "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Mismatch. */ continue; @@ -731,6 +746,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, "unaligned load "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Fatal mismatch. */ matches[0] = false; @@ -749,6 +765,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "Build SLP failed: not grouped load "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* FORNOW: Not grouped loads are not supported. */ @@ -769,6 +786,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, "Build SLP failed: operation"); dump_printf (MSG_MISSED_OPTIMIZATION, " unsupported "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Fatal mismatch. */ matches[0] = false; @@ -790,6 +808,7 @@ vect_build_slp_tree_1 (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, " operation"); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } /* Mismatch. */ continue; @@ -1076,6 +1095,7 @@ vect_supported_load_permutation_p (slp_instance slp_instn) else for (i = 0; i < group_size; ++i) dump_printf (MSG_NOTE, "%d ", i); + dump_printf (MSG_NOTE, "\n"); } /* In case of reduction every load permutation is allowed, since the order @@ -1187,6 +1207,7 @@ vect_supported_load_permutation_p (slp_instance slp_instn) "unsupported unaligned load "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, first_load, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -1449,6 +1470,7 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "Build SLP failed: unsupported data-type "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, scalar_type); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; @@ -1465,9 +1487,9 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, if (unrolling_factor != 1 && !loop_vinfo) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "Build SLP failed: unrolling required in basic" - " block SLP"); + " block SLP\n"); return false; } @@ -1514,9 +1536,9 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, if (unrolling_factor != 1 && !loop_vinfo) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "Build SLP failed: unrolling required in basic" - " block SLP"); + " block SLP\n"); vect_free_slp_tree (node); loads.release (); return false; @@ -1567,10 +1589,11 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, { if (dump_enabled_p ()) { - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "Build SLP failed: unsupported load " "permutation "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } vect_free_slp_instance (new_instance); return false; @@ -1618,7 +1641,7 @@ vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) bool ok = false; if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "=== vect_analyze_slp ==="); + dump_printf_loc (MSG_NOTE, vect_location, "=== vect_analyze_slp ===\n"); if (loop_vinfo) { @@ -1638,7 +1661,7 @@ vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Failed to SLP the basic block."); + "Failed to SLP the basic block.\n"); return false; } @@ -1680,7 +1703,8 @@ vect_make_slp_decision (loop_vec_info loop_vinfo) int decided_to_slp = 0; if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "=== vect_make_slp_decision ==="); + dump_printf_loc (MSG_NOTE, vect_location, "=== vect_make_slp_decision ===" + "\n"); FOR_EACH_VEC_ELT (slp_instances, i, instance) { @@ -1699,7 +1723,7 @@ vect_make_slp_decision (loop_vec_info loop_vinfo) if (decided_to_slp && dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Decided to SLP %d instances. Unrolling factor %d", + "Decided to SLP %d instances. Unrolling factor %d\n", decided_to_slp, unrolling_factor); return (decided_to_slp > 0); @@ -1763,7 +1787,8 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo) slp_instance instance; if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "=== vect_detect_hybrid_slp ==="); + dump_printf_loc (MSG_NOTE, vect_location, "=== vect_detect_hybrid_slp ===" + "\n"); FOR_EACH_VEC_ELT (slp_instances, i, instance) vect_detect_hybrid_slp_stmts (SLP_INSTANCE_TREE (instance)); @@ -2016,7 +2041,7 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo) vec_inside_cost); dump_printf (MSG_NOTE, " Vector prologue cost: %d\n", vec_prologue_cost); dump_printf (MSG_NOTE, " Vector epilogue cost: %d\n", vec_epilogue_cost); - dump_printf (MSG_NOTE, " Scalar cost of basic block: %d", scalar_cost); + dump_printf (MSG_NOTE, " Scalar cost of basic block: %d\n", scalar_cost); } /* Vectorization is profitable if its cost is less than the cost of scalar @@ -2135,7 +2160,7 @@ vect_slp_analyze_bb_1 (basic_block bb) if (!vect_slp_analyze_operations (bb_vinfo)) { if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not vectorized: bad operation in basic block.\n"); destroy_bb_vec_info (bb_vinfo); @@ -2239,7 +2264,7 @@ vect_update_slp_costs_according_to_vf (loop_vec_info loop_vinfo) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_update_slp_costs_according_to_vf ==="); + "=== vect_update_slp_costs_according_to_vf ===\n"); FOR_EACH_VEC_ELT (slp_instances, i, instance) { @@ -2739,9 +2764,10 @@ vect_get_mask_element (gimple stmt, int first_mask_element, int m, { if (dump_enabled_p ()) { - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "permutation requires at least two vectors "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; @@ -2761,6 +2787,7 @@ vect_get_mask_element (gimple stmt, int first_mask_element, int m, "permutation requires at " "least three vectors "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; @@ -2828,6 +2855,7 @@ vect_transform_slp_perm_load (slp_tree node, vec<tree> dr_chain, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "no vect permute for "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -2998,6 +3026,7 @@ vect_schedule_slp_instance (slp_tree node, slp_instance instance, dump_printf_loc (MSG_NOTE,vect_location, "------>vectorizing SLP node starting from: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); + dump_printf (MSG_NOTE, "\n"); } /* Loads should be inserted before the first load. */ @@ -3104,7 +3133,7 @@ vect_schedule_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) instance, vf); if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vectorizing stmts using SLP."); + "vectorizing stmts using SLP.\n"); } FOR_EACH_VEC_ELT (slp_instances, i, instance) @@ -3168,6 +3197,7 @@ vect_slp_transform_bb (basic_block bb) dump_printf_loc (MSG_NOTE, vect_location, "------>SLPing statement: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); + dump_printf (MSG_NOTE, "\n"); } stmt_info = vinfo_for_stmt (stmt); diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index e03ccda1dc8..fcea4d0654b 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -191,7 +191,7 @@ vect_mark_relevant (vec<gimple> *worklist, gimple stmt, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "mark relevant %d, live %d.", relevant, live_p); + "mark relevant %d, live %d.\n", relevant, live_p); /* If this stmt is an original stmt in a pattern, we might need to mark its related pattern stmt instead of the original stmt. However, such stmts @@ -248,7 +248,7 @@ vect_mark_relevant (vec<gimple> *worklist, gimple stmt, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "last stmt in pattern. don't mark" - " relevant/live."); + " relevant/live.\n"); stmt_info = vinfo_for_stmt (pattern_stmt); gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt); save_relevant = STMT_VINFO_RELEVANT (stmt_info); @@ -266,7 +266,7 @@ vect_mark_relevant (vec<gimple> *worklist, gimple stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "already marked relevant/live."); + "already marked relevant/live.\n"); return; } @@ -311,7 +311,7 @@ vect_stmt_relevant_p (gimple stmt, loop_vec_info loop_vinfo, { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vec_stmt_relevant_p: stmt has vdefs."); + "vec_stmt_relevant_p: stmt has vdefs.\n"); *relevant = vect_used_in_scope; } @@ -325,7 +325,7 @@ vect_stmt_relevant_p (gimple stmt, loop_vec_info loop_vinfo, { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vec_stmt_relevant_p: used out of loop."); + "vec_stmt_relevant_p: used out of loop.\n"); if (is_gimple_debug (USE_STMT (use_p))) continue; @@ -438,7 +438,7 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: unsupported use in stmt."); + "not vectorized: unsupported use in stmt.\n"); return false; } @@ -449,7 +449,7 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p, if (!flow_bb_inside_loop_p (loop, def_bb)) { if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "def_stmt is out of loop."); + dump_printf_loc (MSG_NOTE, vect_location, "def_stmt is out of loop.\n"); return true; } @@ -468,7 +468,7 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p, { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "reduc-stmt defining reduc-phi in the same nest."); + "reduc-stmt defining reduc-phi in the same nest.\n"); if (STMT_VINFO_IN_PATTERN_P (dstmt_vinfo)) dstmt_vinfo = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (dstmt_vinfo)); gcc_assert (STMT_VINFO_RELEVANT (dstmt_vinfo) < vect_used_by_reduction); @@ -488,7 +488,7 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p, { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "outer-loop def-stmt defining inner-loop stmt."); + "outer-loop def-stmt defining inner-loop stmt.\n"); switch (relevant) { @@ -526,7 +526,7 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p, { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "inner-loop def-stmt defining outer-loop stmt."); + "inner-loop def-stmt defining outer-loop stmt.\n"); switch (relevant) { @@ -590,7 +590,7 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_mark_stmts_to_be_vectorized ==="); + "=== vect_mark_stmts_to_be_vectorized ===\n"); worklist.create (64); @@ -605,6 +605,7 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) { dump_printf_loc (MSG_NOTE, vect_location, "init: phi relevant? "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0); + dump_printf (MSG_NOTE, "\n"); } if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p)) @@ -617,6 +618,7 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) { dump_printf_loc (MSG_NOTE, vect_location, "init: stmt relevant? "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); + dump_printf (MSG_NOTE, "\n"); } if (vect_stmt_relevant_p (stmt, loop_vinfo, &relevant, &live_p)) @@ -635,6 +637,7 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) { dump_printf_loc (MSG_NOTE, vect_location, "worklist: examine stmt: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); + dump_printf (MSG_NOTE, "\n"); } /* Examine the USEs of STMT. For each USE, mark the stmt that defines it @@ -678,7 +681,7 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) default: if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "unsupported use of reduction."); + "unsupported use of reduction.\n"); worklist.release (); return false; } @@ -693,7 +696,7 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "unsupported use of nested cycle."); + "unsupported use of nested cycle.\n"); worklist.release (); return false; @@ -708,7 +711,7 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "unsupported use of double reduction."); + "unsupported use of double reduction.\n"); worklist.release (); return false; @@ -832,7 +835,7 @@ vect_model_simple_cost (stmt_vec_info stmt_info, int ncopies, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "vect_model_simple_cost: inside_cost = %d, " - "prologue_cost = %d .", inside_cost, prologue_cost); + "prologue_cost = %d .\n", inside_cost, prologue_cost); } @@ -878,7 +881,7 @@ vect_model_promotion_demotion_cost (stmt_vec_info stmt_info, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "vect_model_promotion_demotion_cost: inside_cost = %d, " - "prologue_cost = %d .", inside_cost, prologue_cost); + "prologue_cost = %d .\n", inside_cost, prologue_cost); } /* Function vect_cost_group_size @@ -961,7 +964,7 @@ vect_model_store_cost (stmt_vec_info stmt_info, int ncopies, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vect_model_store_cost: strided group_size = %d .", + "vect_model_store_cost: strided group_size = %d .\n", group_size); } @@ -971,7 +974,7 @@ vect_model_store_cost (stmt_vec_info stmt_info, int ncopies, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "vect_model_store_cost: inside_cost = %d, " - "prologue_cost = %d .", inside_cost, prologue_cost); + "prologue_cost = %d .\n", inside_cost, prologue_cost); } @@ -995,7 +998,7 @@ vect_get_store_cost (struct data_reference *dr, int ncopies, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vect_model_store_cost: aligned."); + "vect_model_store_cost: aligned.\n"); break; } @@ -1008,7 +1011,7 @@ vect_get_store_cost (struct data_reference *dr, int ncopies, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "vect_model_store_cost: unaligned supported by " - "hardware."); + "hardware.\n"); break; } @@ -1018,7 +1021,7 @@ vect_get_store_cost (struct data_reference *dr, int ncopies, if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "vect_model_store_cost: unsupported access."); + "vect_model_store_cost: unsupported access.\n"); break; } @@ -1076,8 +1079,8 @@ vect_model_load_cost (stmt_vec_info stmt_info, int ncopies, stmt_info, 0, vect_body); if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "vect_model_load_cost: strided group_size = %d .", + dump_printf_loc (MSG_NOTE, vect_location, + "vect_model_load_cost: strided group_size = %d .\n", group_size); } @@ -1102,7 +1105,7 @@ vect_model_load_cost (stmt_vec_info stmt_info, int ncopies, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "vect_model_load_cost: inside_cost = %d, " - "prologue_cost = %d .", inside_cost, prologue_cost); + "prologue_cost = %d .\n", inside_cost, prologue_cost); } @@ -1128,7 +1131,7 @@ vect_get_load_cost (struct data_reference *dr, int ncopies, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vect_model_load_cost: aligned."); + "vect_model_load_cost: aligned.\n"); break; } @@ -1142,7 +1145,7 @@ vect_get_load_cost (struct data_reference *dr, int ncopies, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "vect_model_load_cost: unaligned supported by " - "hardware."); + "hardware.\n"); break; } @@ -1161,17 +1164,17 @@ vect_get_load_cost (struct data_reference *dr, int ncopies, stmt_info, 0, vect_body); if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "vect_model_load_cost: explicit realign"); + dump_printf_loc (MSG_NOTE, vect_location, + "vect_model_load_cost: explicit realign\n"); break; } case dr_explicit_realign_optimized: { if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, + dump_printf_loc (MSG_NOTE, vect_location, "vect_model_load_cost: unaligned software " - "pipelined."); + "pipelined.\n"); /* Unaligned software pipeline has a load of an address, an initial load, and possibly a mask operation to "prime" the loop. However, @@ -1198,7 +1201,8 @@ vect_get_load_cost (struct data_reference *dr, int ncopies, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vect_model_load_cost: explicit realign optimized"); + "vect_model_load_cost: explicit realign optimized" + "\n"); break; } @@ -1209,7 +1213,7 @@ vect_get_load_cost (struct data_reference *dr, int ncopies, if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "vect_model_load_cost: unsupported access."); + "vect_model_load_cost: unsupported access.\n"); break; } @@ -1262,6 +1266,7 @@ vect_init_vector_1 (gimple stmt, gimple new_stmt, gimple_stmt_iterator *gsi) dump_printf_loc (MSG_NOTE, vect_location, "created new init_stmt: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, new_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } } @@ -1344,6 +1349,7 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def) dump_printf_loc (MSG_NOTE, vect_location, "vect_get_vec_def_for_operand: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, op); + dump_printf (MSG_NOTE, "\n"); } is_simple_use = vect_is_simple_use (op, stmt, loop_vinfo, NULL, @@ -1357,6 +1363,7 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def) dump_printf_loc (MSG_NOTE, vect_location, "def = "); loc_printed = 1; dump_generic_expr (MSG_NOTE, TDF_SLIM, def); + dump_printf (MSG_NOTE, "\n"); } if (def_stmt) { @@ -1365,6 +1372,7 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def) else dump_printf_loc (MSG_NOTE, vect_location, " def_stmt = "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, def_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } } @@ -1383,7 +1391,7 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def) /* Create 'vect_cst_ = {cst,cst,...,cst}' */ if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Create vector_cst. nunits = %d", nunits); + "Create vector_cst. nunits = %d\n", nunits); return vect_init_vector (stmt, op, vector_type, NULL); } @@ -1399,7 +1407,7 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def) /* Create 'vec_inv = {inv,inv,..,inv}' */ if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "Create vector_inv."); + dump_printf_loc (MSG_NOTE, vect_location, "Create vector_inv.\n"); return vect_init_vector (stmt, def, vector_type, NULL); } @@ -1666,6 +1674,7 @@ vect_finish_stmt_generation (gimple stmt, gimple vec_stmt, { dump_printf_loc (MSG_NOTE, vect_location, "add new stmt: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, vec_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } gimple_set_location (vec_stmt, gimple_location (stmt)); @@ -1775,7 +1784,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "argument types differ."); + "argument types differ.\n"); return false; } if (!rhs_type) @@ -1786,7 +1795,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "use not simple."); + "use not simple.\n"); return false; } @@ -1797,7 +1806,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "argument vector types differ."); + "argument vector types differ.\n"); return false; } } @@ -1814,6 +1823,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "no vectype for scalar type "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, rhs_type); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; @@ -1855,7 +1865,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "function is not vectorizable."); + "function is not vectorizable.\n"); return false; } } @@ -1877,7 +1887,8 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { STMT_VINFO_TYPE (stmt_info) = call_vec_info_type; if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "=== vectorizable_call ==="); + dump_printf_loc (MSG_NOTE, vect_location, "=== vectorizable_call ===" + "\n"); vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL); return true; } @@ -1885,7 +1896,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, /** Transform. **/ if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "transform call."); + dump_printf_loc (MSG_NOTE, vect_location, "transform call.\n"); /* Handle def. */ scalar_dest = gimple_call_lhs (stmt); @@ -2408,7 +2419,8 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "type conversion to/from bit-precision unsupported."); + "type conversion to/from bit-precision unsupported." + "\n"); return false; } @@ -2418,7 +2430,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "use not simple."); + "use not simple.\n"); return false; } if (op_type == binary_op) @@ -2440,7 +2452,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "use not simple."); + "use not simple.\n"); return false; } } @@ -2458,6 +2470,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "no vectype for scalar type "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, rhs_type); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; @@ -2499,7 +2512,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, unsupported: if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "conversion not supported by target."); + "conversion not supported by target.\n"); return false; case WIDEN: @@ -2598,7 +2611,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vectorizable_conversion ==="); + "=== vectorizable_conversion ===\n"); if (code == FIX_TRUNC_EXPR || code == FLOAT_EXPR) { STMT_VINFO_TYPE (stmt_info) = type_conversion_vec_info_type; @@ -2621,7 +2634,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, /** Transform. **/ if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "transform conversion. ncopies = %d.", ncopies); + "transform conversion. ncopies = %d.\n", ncopies); if (op_type == binary_op) { @@ -2967,7 +2980,7 @@ vectorizable_assignment (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "use not simple."); + "use not simple.\n"); return false; } @@ -2997,7 +3010,7 @@ vectorizable_assignment (gimple stmt, gimple_stmt_iterator *gsi, if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "type conversion to/from bit-precision " - "unsupported."); + "unsupported.\n"); return false; } @@ -3006,14 +3019,14 @@ vectorizable_assignment (gimple stmt, gimple_stmt_iterator *gsi, STMT_VINFO_TYPE (stmt_info) = assignment_vec_info_type; if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vectorizable_assignment ==="); + "=== vectorizable_assignment ===\n"); vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL); return true; } /** Transform. **/ if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "transform assignment."); + dump_printf_loc (MSG_NOTE, vect_location, "transform assignment.\n"); /* Handle def. */ vec_dest = vect_create_destination_var (scalar_dest, vectype); @@ -3162,7 +3175,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "bit-precision shifts not supported."); + "bit-precision shifts not supported.\n"); return false; } @@ -3172,7 +3185,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "use not simple."); + "use not simple.\n"); return false; } /* If op0 is an external or constant def use a vector type with @@ -3185,7 +3198,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "no vectype for scalar type "); + "no vectype for scalar type\n"); return false; } @@ -3200,7 +3213,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "use not simple."); + "use not simple.\n"); return false; } @@ -3245,7 +3258,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "operand mode requires invariant argument."); + "operand mode requires invariant argument.\n"); return false; } @@ -3255,7 +3268,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, optab = optab_for_tree_code (code, vectype, optab_vector); if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vector/vector shift/rotate found."); + "vector/vector shift/rotate found.\n"); if (!op1_vectype) op1_vectype = get_same_sized_vectype (TREE_TYPE (op1), vectype_out); @@ -3265,7 +3278,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "unusable type for last operand in" - " vector/vector shift/rotate."); + " vector/vector shift/rotate.\n"); return false; } } @@ -3279,7 +3292,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vector/scalar shift/rotate found."); + "vector/scalar shift/rotate found.\n"); } else { @@ -3292,7 +3305,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "vector/vector shift/rotate found."); + "vector/vector shift/rotate found.\n"); /* Unlike the other binary operators, shifts/rotates have the rhs being int, instead of the same type as the lhs, @@ -3310,7 +3323,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "unusable type for last operand in" - " vector/vector shift/rotate."); + " vector/vector shift/rotate.\n"); return false; } if (vec_stmt && !slp_node) @@ -3329,7 +3342,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "no optab."); + "no optab.\n"); return false; } vec_mode = TYPE_MODE (vectype); @@ -3338,14 +3351,15 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "op not supported by target."); + "op not supported by target.\n"); /* Check only during analysis. */ if (GET_MODE_SIZE (vec_mode) != UNITS_PER_WORD || (vf < vect_min_worthwhile_factor (code) && !vec_stmt)) return false; if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "proceeding using word mode."); + dump_printf_loc (MSG_NOTE, vect_location, + "proceeding using word mode.\n"); } /* Worthwhile without SIMD support? Check only during analysis. */ @@ -3355,7 +3369,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not worthwhile without SIMD support."); + "not worthwhile without SIMD support.\n"); return false; } @@ -3363,7 +3377,8 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, { STMT_VINFO_TYPE (stmt_info) = shift_vec_info_type; if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "=== vectorizable_shift ==="); + dump_printf_loc (MSG_NOTE, vect_location, + "=== vectorizable_shift ===\n"); vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL); return true; } @@ -3372,7 +3387,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "transform binary/unary operation."); + "transform binary/unary operation.\n"); /* Handle def. */ vec_dest = vect_create_destination_var (scalar_dest, vectype); @@ -3394,7 +3409,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "operand 1 using scalar mode."); + "operand 1 using scalar mode.\n"); vec_oprnd1 = op1; vec_oprnds1.create (slp_node ? slp_node->vec_stmts_size : 1); vec_oprnds1.quick_push (vec_oprnd1); @@ -3525,7 +3540,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "num. args = %d (not unary/binary/ternary op).", + "num. args = %d (not unary/binary/ternary op).\n", op_type); return false; } @@ -3544,7 +3559,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "bit-precision arithmetic not supported."); + "bit-precision arithmetic not supported.\n"); return false; } @@ -3554,7 +3569,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "use not simple."); + "use not simple.\n"); return false; } /* If op0 is an external or constant def use a vector type with @@ -3571,6 +3586,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi, "no vectype for scalar type "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, TREE_TYPE (op0)); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; @@ -3589,7 +3605,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "use not simple."); + "use not simple.\n"); return false; } } @@ -3601,7 +3617,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "use not simple."); + "use not simple.\n"); return false; } } @@ -3643,7 +3659,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "no optab."); + "no optab.\n"); return false; } icode = (int) optab_handler (optab, vec_mode); @@ -3653,13 +3669,14 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "op not supported by target."); + "op not supported by target.\n"); /* Check only during analysis. */ if (GET_MODE_SIZE (vec_mode) != UNITS_PER_WORD || (!vec_stmt && vf < vect_min_worthwhile_factor (code))) return false; if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "proceeding using word mode."); + dump_printf_loc (MSG_NOTE, vect_location, + "proceeding using word mode.\n"); } /* Worthwhile without SIMD support? Check only during analysis. */ @@ -3669,7 +3686,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not worthwhile without SIMD support."); + "not worthwhile without SIMD support.\n"); return false; } @@ -3678,7 +3695,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi, STMT_VINFO_TYPE (stmt_info) = op_vec_info_type; if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vectorizable_operation ==="); + "=== vectorizable_operation ===\n"); vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL); return true; } @@ -3687,7 +3704,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "transform binary/unary operation."); + "transform binary/unary operation.\n"); /* Handle def. */ vec_dest = vect_create_destination_var (scalar_dest, vectype); @@ -3897,7 +3914,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "multiple types in nested loop."); + "multiple types in nested loop.\n"); return false; } @@ -3932,7 +3949,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "use not simple."); + "use not simple.\n"); return false; } @@ -3953,7 +3970,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "negative step for store."); + "negative step for store.\n"); return false; } @@ -3984,7 +4001,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "use not simple."); + "use not simple.\n"); return false; } next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt)); @@ -4048,7 +4065,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "transform store. ncopies = %d", ncopies); + "transform store. ncopies = %d\n", ncopies); dr_chain.create (group_size); oprnds.create (group_size); @@ -4165,6 +4182,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr)); dataref_offset = build_int_cst (reference_alias_ptr_type (DR_REF (first_dr)), 0); + inv_p = false; } else dataref_ptr @@ -4459,7 +4477,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "multiple types in nested loop."); + "multiple types in nested loop.\n"); return false; } @@ -4500,7 +4518,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Aligned load, but unsupported type."); + "Aligned load, but unsupported type.\n"); return false; } @@ -4536,7 +4554,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "gather index use not simple."); + "gather index use not simple.\n"); return false; } } @@ -4552,7 +4570,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "multiple types with negative step."); + "multiple types with negative step.\n"); return false; } @@ -4562,7 +4580,8 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "negative step for group load not supported"); + "negative step for group load not supported" + "\n"); return false; } alignment_support_scheme = vect_supportable_dr_alignment (dr, false); @@ -4571,14 +4590,15 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "negative step but alignment required."); + "negative step but alignment required.\n"); return false; } if (!perm_mask_for_reverse (vectype)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "negative step and reversing not supported."); + "negative step and reversing not supported." + "\n"); return false; } } @@ -4593,7 +4613,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "transform load. ncopies = %d", ncopies); + "transform load. ncopies = %d\n", ncopies); /** Transform. **/ @@ -5058,6 +5078,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr)); dataref_offset = build_int_cst (reference_alias_ptr_type (DR_REF (first_dr)), 0); + inv_p = false; } else dataref_ptr @@ -5444,7 +5465,7 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "value used after loop."); + "value used after loop.\n"); return false; } @@ -5654,13 +5675,14 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node) { dump_printf_loc (MSG_NOTE, vect_location, "==> examining statement: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); + dump_printf (MSG_NOTE, "\n"); } if (gimple_has_volatile_ops (stmt)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: stmt has volatile operands"); + "not vectorized: stmt has volatile operands\n"); return false; } @@ -5696,12 +5718,13 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node) dump_printf_loc (MSG_NOTE, vect_location, "==> examining pattern statement: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); + dump_printf (MSG_NOTE, "\n"); } } else { if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "irrelevant."); + dump_printf_loc (MSG_NOTE, vect_location, "irrelevant.\n"); return true; } @@ -5718,6 +5741,7 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node) dump_printf_loc (MSG_NOTE, vect_location, "==> examining pattern statement: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); + dump_printf (MSG_NOTE, "\n"); } if (!vect_analyze_stmt (pattern_stmt, need_to_vectorize, node)) @@ -5742,6 +5766,7 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node) dump_printf_loc (MSG_NOTE, vect_location, "==> examining pattern def statement: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_def_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } if (!vect_analyze_stmt (pattern_def_stmt, @@ -5781,6 +5806,7 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node) dump_printf_loc (MSG_NOTE, vect_location, "get vectype for scalar type: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, scalar_type); + dump_printf (MSG_NOTE, "\n"); } vectype = get_vectype_for_scalar_type (scalar_type); @@ -5792,6 +5818,7 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node) "not SLPed: unsupported data-type "); dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, scalar_type); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; } @@ -5800,6 +5827,7 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node) { dump_printf_loc (MSG_NOTE, vect_location, "vectype: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, vectype); + dump_printf (MSG_NOTE, "\n"); } STMT_VINFO_VECTYPE (stmt_info) = vectype; @@ -5846,6 +5874,7 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node) "not vectorized: relevant stmt not "); dump_printf (MSG_MISSED_OPTIMIZATION, "supported: "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; @@ -5868,6 +5897,7 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node) "not vectorized: live stmt not "); dump_printf (MSG_MISSED_OPTIMIZATION, "supported: "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } return false; @@ -5964,7 +5994,7 @@ vect_transform_stmt (gimple stmt, gimple_stmt_iterator *gsi, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "stmt not supported."); + "stmt not supported.\n"); gcc_unreachable (); } } @@ -5989,7 +6019,7 @@ vect_transform_stmt (gimple stmt, gimple_stmt_iterator *gsi, if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "Record the vdef for outer-loop vectorization."); + "Record the vdef for outer-loop vectorization.\n"); /* Find the relevant loop-exit phi-node, and reord the vec_stmt there (to be used when vectorizing outer-loop stmts that use the DEF of @@ -6303,6 +6333,7 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo, dump_printf_loc (MSG_NOTE, vect_location, "vect_is_simple_use: operand "); dump_generic_expr (MSG_NOTE, TDF_SLIM, operand); + dump_printf (MSG_NOTE, "\n"); } if (CONSTANT_CLASS_P (operand)) @@ -6321,7 +6352,7 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo, if (TREE_CODE (operand) == PAREN_EXPR) { if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "non-associatable copy."); + dump_printf_loc (MSG_NOTE, vect_location, "non-associatable copy.\n"); operand = TREE_OPERAND (operand, 0); } @@ -6329,7 +6360,7 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not ssa-name."); + "not ssa-name.\n"); return false; } @@ -6338,7 +6369,7 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "no def_stmt."); + "no def_stmt.\n"); return false; } @@ -6346,6 +6377,7 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo, { dump_printf_loc (MSG_NOTE, vect_location, "def_stmt: "); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, *def_stmt, 0); + dump_printf (MSG_NOTE, "\n"); } /* Empty stmt is expected only in case of a function argument. @@ -6376,12 +6408,12 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo, { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "Unsupported pattern."); + "Unsupported pattern.\n"); return false; } if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "type of def: %d.", *dt); + dump_printf_loc (MSG_NOTE, vect_location, "type of def: %d.\n", *dt); switch (gimple_code (*def_stmt)) { @@ -6401,7 +6433,7 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo, default: if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "unsupported defining stmt: "); + "unsupported defining stmt:\n"); return false; } diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index 205d1b27a76..638c19b72ee 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -341,7 +341,7 @@ vectorize_loops (void) than all previously defined loops. This fact allows us to run only over initial loops skipping newly generated ones. */ FOR_EACH_LOOP (li, loop, 0) - if ((flag_tree_vectorize && optimize_loop_nest_for_speed_p (loop)) + if ((flag_tree_loop_vectorize && optimize_loop_nest_for_speed_p (loop)) || loop->force_vect) { loop_vec_info loop_vinfo; @@ -486,10 +486,7 @@ execute_vect_slp (void) static bool gate_vect_slp (void) { - /* Apply SLP either if the vectorizer is on and the user didn't specify - whether to run SLP or not, or if the SLP flag was set by the user. */ - return ((flag_tree_vectorize != 0 && flag_tree_slp_vectorize != 0) - || flag_tree_slp_vectorize == 1); + return flag_tree_slp_vectorize != 0; } namespace { @@ -579,7 +576,7 @@ increase_alignment (void) static bool gate_increase_alignment (void) { - return flag_section_anchors && flag_tree_vectorize; + return flag_section_anchors && flag_tree_loop_vectorize; } diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 37b68901b3e..160a416d4d3 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -589,7 +589,7 @@ check_counter (gimple stmt, const char * name, dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus, "correcting inconsistent value profile: %s " "profiler overall count (%d) does not match BB " - "count (%d)", name, (int)*all, (int)bb_count); + "count (%d)\n", name, (int)*all, (int)bb_count); *all = bb_count; if (*count > *all) *count = *all; @@ -1275,7 +1275,7 @@ check_ic_target (gimple call_stmt, struct cgraph_node *target) locus = gimple_location (call_stmt); if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus, - "Skipping target %s with mismatching types for icall ", + "Skipping target %s with mismatching types for icall\n", cgraph_node_name (target)); return false; } diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 518a26c9470..5f503617658 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,19 @@ +2013-09-17 Jacek Caban <jacek@codeweavers.com> + + * config/i386/gthr-win32.c: CreateSemaphoreW instead of + CreateSemaphoreA. + * config/i386/gthr-win32.h: Likewise. + +2013-09-16 DJ Delorie <dj@redhat.com> + + * config/rl78/vregs.h: Add G10 register definitions. + * config/rl78/lib2mul.c: Enable for RL78/G10. + * config/rl78/lib2div.c: Likewise. + * config/rl78/lshrsi3.S: Use vregs.h. + * config/rl78/cmpsi2.S: Likewise. + * config/rl78/trampoline.S: Likewise. + * config/rl78/mulsi2.S: Likewise. Disable for RL78/G10. + 2013-09-14 DJ Delorie <dj@redhat.com> Nick Clifton <nickc@redhat.com> diff --git a/libgcc/config/i386/gthr-win32.c b/libgcc/config/i386/gthr-win32.c index f6f661a0217..f3230317929 100644 --- a/libgcc/config/i386/gthr-win32.c +++ b/libgcc/config/i386/gthr-win32.c @@ -147,7 +147,7 @@ void __gthr_win32_mutex_init_function (__gthread_mutex_t *mutex) { mutex->counter = -1; - mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); + mutex->sema = CreateSemaphoreW (NULL, 0, 65535, NULL); } void @@ -195,7 +195,7 @@ __gthr_win32_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex) mutex->counter = -1; mutex->depth = 0; mutex->owner = 0; - mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); + mutex->sema = CreateSemaphoreW (NULL, 0, 65535, NULL); } int diff --git a/libgcc/config/i386/gthr-win32.h b/libgcc/config/i386/gthr-win32.h index d2e729a00f6..1e437fc6498 100644 --- a/libgcc/config/i386/gthr-win32.h +++ b/libgcc/config/i386/gthr-win32.h @@ -635,7 +635,7 @@ static inline void __gthread_mutex_init_function (__gthread_mutex_t *__mutex) { __mutex->counter = -1; - __mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); + __mutex->sema = CreateSemaphoreW (NULL, 0, 65535, NULL); } static inline void @@ -697,7 +697,7 @@ __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) __mutex->counter = -1; __mutex->depth = 0; __mutex->owner = 0; - __mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL); + __mutex->sema = CreateSemaphoreW (NULL, 0, 65535, NULL); } static inline int diff --git a/libgcc/config/rl78/cmpsi2.S b/libgcc/config/rl78/cmpsi2.S index d815793daba..7fdc76a03f6 100644 --- a/libgcc/config/rl78/cmpsi2.S +++ b/libgcc/config/rl78/cmpsi2.S @@ -21,8 +21,7 @@ ; <http://www.gnu.org/licenses/>. -; clobberable -r8 = 0xffef0 +#include "vregs.h" .text diff --git a/libgcc/config/rl78/lib2div.c b/libgcc/config/rl78/lib2div.c index 4b5033ef970..b37f55a94ac 100644 --- a/libgcc/config/rl78/lib2div.c +++ b/libgcc/config/rl78/lib2div.c @@ -34,7 +34,7 @@ typedef int word_type __attribute__ ((mode (__word__))); #define C3B(a,b,c) a##b##c #define C3(a,b,c) C3B(a,b,c) -#if 0 +#ifdef __RL78_G10__ #define UINT_TYPE uint32_type #define SINT_TYPE sint32_type diff --git a/libgcc/config/rl78/lib2mul.c b/libgcc/config/rl78/lib2mul.c index 6460f9e69db..fee50817722 100644 --- a/libgcc/config/rl78/lib2mul.c +++ b/libgcc/config/rl78/lib2mul.c @@ -30,12 +30,25 @@ typedef unsigned int uint08_type __attribute__ ((mode (QI))); #define C3B(a,b,c) a##b##c #define C3(a,b,c) C3B(a,b,c) +#ifdef __RL78_G10__ + +#define UINT_TYPE uint32_type +#define BITS_MINUS_1 31 +#define NAME_MODE si + +#include "rl78-mul.h" + +#undef UINT_TYPE +#undef BITS_MINUS_1 +#undef NAME_MODE #define UINT_TYPE uint16_type #define BITS_MINUS_1 15 #define NAME_MODE hi -/*#include "rl78-mul.h"*/ +#include "rl78-mul.h" + +#endif #undef UINT_TYPE #undef BITS_MINUS_1 diff --git a/libgcc/config/rl78/lshrsi3.S b/libgcc/config/rl78/lshrsi3.S index 1ee7325143f..8bd997897aa 100644 --- a/libgcc/config/rl78/lshrsi3.S +++ b/libgcc/config/rl78/lshrsi3.S @@ -20,22 +20,7 @@ ; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ; <http://www.gnu.org/licenses/>. -r8 = 0xffef0 -r16 = 0xffee8 -r9 = 0xffef1 -r17 = 0xffee9 -r10 = 0xffef2 -r18 = 0xffeea -r11 = 0xffef3 -r19 = 0xffeeb -r12 = 0xffef4 -r20 = 0xffeec -r13 = 0xffef5 -r21 = 0xffeed -r14 = 0xffef6 -r22 = 0xffeee -r15 = 0xffef7 -r23 = 0xffeef +#include "vregs.h" .text .global ___lshrsi3 diff --git a/libgcc/config/rl78/mulsi3.S b/libgcc/config/rl78/mulsi3.S index 012e87e285f..1ce45ba3402 100644 --- a/libgcc/config/rl78/mulsi3.S +++ b/libgcc/config/rl78/mulsi3.S @@ -22,35 +22,12 @@ ;; 32x32=32 multiply -; real -; GAS defines r0..r7 as aliases for real registers; we want the saddr -; forms here. -r_0 = 0xffef8 -r_1 = 0xffef9 -r_2 = 0xffefa -r_3 = 0xffefb -r_4 = 0xffefc -r_5 = 0xffefd -r_6 = 0xffefe -r_7 = 0xffeff -; clobberable -r8 = 0xffef0 -r9 = 0xffef1 -r10 = 0xffef2 -r11 = 0xffef3 -r12 = 0xffef4 -r13 = 0xffef5 -r14 = 0xffef6 -r15 = 0xffef7 -; preserved -r16 = 0xffee8 -r17 = 0xffee9 -r18 = 0xffeea -r19 = 0xffeeb -r20 = 0xffeec -r21 = 0xffeed -r22 = 0xffeee -r23 = 0xffeef +#include "vregs.h" + +; the G10 only has one register bank, so cannot use these optimized +; versions. Use the C version instead. + +#ifndef __RL78_G10__ ;---------------------------------------------------------------------- @@ -221,3 +198,5 @@ ___mulhi3: .Lmul_hi_done: ret + +#endif diff --git a/libgcc/config/rl78/trampoline.S b/libgcc/config/rl78/trampoline.S index b15b0d361e2..59d429eb589 100644 --- a/libgcc/config/rl78/trampoline.S +++ b/libgcc/config/rl78/trampoline.S @@ -32,9 +32,7 @@ */ -r8 = 0xffef0 -r10 = 0xffef2 -r14 = 0xffef6 +#include "vregs.h" .data .p2align 1 diff --git a/libgcc/config/rl78/vregs.h b/libgcc/config/rl78/vregs.h index f223be53ef8..fa488fabcb1 100644 --- a/libgcc/config/rl78/vregs.h +++ b/libgcc/config/rl78/vregs.h @@ -11,6 +11,29 @@ r_5 = 0xffefd r_6 = 0xffefe r_7 = 0xffeff +#ifdef __RL78_G10__ + +; clobberable +r8 = 0xffec8 +r9 = 0xffec9 +r10 = 0xffeca +r11 = 0xffecb +r12 = 0xffecc +r13 = 0xffecd +r14 = 0xffece +r15 = 0xffecf +; preserved +r16 = 0xffed0 +r17 = 0xffed1 +r18 = 0xffed2 +r19 = 0xffed3 +r20 = 0xffed4 +r21 = 0xffed5 +r22 = 0xffed6 +r23 = 0xffed7 + +#else + ; clobberable r8 = 0xffef0 r9 = 0xffef1 @@ -30,3 +53,4 @@ r21 = 0xffeed r22 = 0xffeee r23 = 0xffeef +#endif diff --git a/libgo/go/reflect/value.go b/libgo/go/reflect/value.go index 45a08587973..69a87031e56 100644 --- a/libgo/go/reflect/value.go +++ b/libgo/go/reflect/value.go @@ -611,7 +611,13 @@ func methodReceiver(op string, v Value, methodIndex int) (t *rtype, fn unsafe.Po } fn = unsafe.Pointer(&m.tfn) t = m.mtyp - rcvr = v.iword() + // Can't call iword here, because it checks v.kind, + // and that is always Func. + if v.flag&flagIndir != 0 && (v.typ.Kind() == Ptr || v.typ.Kind() == UnsafePointer) { + rcvr = loadIword(v.val, v.typ.size) + } else { + rcvr = iword(v.val) + } } return } diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 6687169f1ce..67ce62795b0 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,7 @@ +2013-09-19 Jakub Jelinek <jakub@redhat.com> + + * testsuite/libgomp.c/sections-2.c: New test. + 2013-06-28 Marcus Shawcroft <marcus.shawcroft@arm.com> * testsuite/libgomp.fortran/strassen.f90: diff --git a/libgomp/testsuite/libgomp.c/sections-2.c b/libgomp/testsuite/libgomp.c/sections-2.c new file mode 100644 index 00000000000..38216befe0b --- /dev/null +++ b/libgomp/testsuite/libgomp.c/sections-2.c @@ -0,0 +1,29 @@ +/* { dg-do run } */ + +#include <stdlib.h> +#include <unistd.h> + +__attribute__((noinline, noclone, noreturn)) +void +foo () +{ + sleep (4); + exit (0); +} + +int +main () +{ + #pragma omp parallel + { + #pragma omp sections + { + foo (); + #pragma omp section + foo (); + #pragma omp section + foo (); + } + } + return 0; +} diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 96891056ac7..e2c846f98e9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,151 @@ +2013-09-19 Marc Glisse <marc.glisse@inria.fr> + + PR libstdc++/58338 + * include/bits/stl_tree.h (_Rb_tree_node_base) [_S_minimum, _S_maximum]: + Mark as noexcept. + (_Rb_tree_iterator) [_Rb_tree_iterator, operator*, operator->, + operator++, operator--, operator==, operator!=]: Likewise. + (_Rb_tree_const_iterator) [_Rb_tree_const_iterator, _M_const_cast, + operator*, operator->, operator++, operator--, operator==, operator!=]: + Likewise. + (operator==(const _Rb_tree_iterator&, const _Rb_tree_const_iterator&), + operator!=(const _Rb_tree_iterator&, const _Rb_tree_const_iterator&)): + Likewise. + (_Rb_tree) [_M_put_node, _M_destroy_node, _M_root, _M_leftmost, + _M_rightmost, _M_begin, _M_end, _S_left, _S_right, _S_minimum, + _S_maximum]: Likewise. + * include/debug/string (basic_string) [basic_string(const _Allocator&), + shrink_to_fit, operator[], pop_back]: Likewise. + * include/ext/vstring.h (__versa_string) [_M_limit, _M_disjunct, + _M_ibegin, _M_iend, __versa_string(const _Alloc&), + operator=(__versa_string&&), shrink_to_fit, operator[], front, + back, assign(__versa_string&&), swap]: Likewise. + (__versa_string) [__versa_string(), __versa_string(const _Alloc&)]: + Merge. + +2013-09-18 Marc Glisse <marc.glisse@inria.fr> + + PR libstdc++/58338 + * include/bits/stl_iterator.h (__normal_iterator) [__normal_iterator, + _M_const_cast, operator*, operator->, operator++, operator--, + operator[], operator+=, operator+, operator-=, operator-, base]: + Mark as noexcept. + (operator==(const __normal_iterator&, const __normal_iterator&), + operator!=(const __normal_iterator&, const __normal_iterator&), + operator<(const __normal_iterator&, const __normal_iterator&), + operator>(const __normal_iterator&, const __normal_iterator&), + operator<=(const __normal_iterator&, const __normal_iterator&), + operator>=(const __normal_iterator&, const __normal_iterator&), + operator-(const __normal_iterator&, const __normal_iterator&), + operator+(difference_type, const __normal_iterator&)): Likewise. + * include/bits/stl_list.h (list) [splice, _M_check_equal_allocators]: + Likewise. + (list::_M_check_equal_allocators): Abort instead of throwing. + * include/debug/array (array) [operator[], front, back]: Mark as + noexcept. + * include/profile/array (array) [operator[], front, back]: Likewise. + * include/std/array (array) [operator[], front, back]: Likewise. + * include/debug/list (list::splice): Likewise. + * include/profile/list (list::splice): Likewise. + * testsuite/23_containers/list/operations/5.cc: Remove file. + * testsuite/23_containers/list/operations/5.h: Likewise. + +2013-09-18 Tim Shen <timshen91@gmail.com> + + * include/bits/regex.h: Add friend classes. + (match_results<>::position, regex_iterator<>::operator++): + Implement position specification in regex_iterator. + (regex_match<>, regex_search<>): + Move match_results initializations to these function. Remove `todo`. + * include/bits/regex_compiler.tcc: + (_Compiler<>::_M_quantifier): Fix greedy/ungreedy of interval matching. + * include/bits/regex_constants.h: + Fix indentation. Change match_flag_type to enum type. + * include/bits/regex_executor.h: + Merge identical code to the base class _Executor. + Support flags in regex_constants. + * include/bits/regex_executor.tcc: Likewise. + * include/bits/regex_scanner.h: Add comments. + * include/bits/regex_scanner.tcc: Same. + * testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc: + Add a testcase. + * testsuite/28_regex/algorithms/regex_search/ecma/flags.cc: New. + * testsuite/28_regex/iterators/regex_iterator/char/ + string_position_01.cc: Remove `xfail`. + * testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc: + Remove `xfail` and make the case really work. + +2013-09-18 Paolo Carlini <paolo.carlini@oracle.com> + + * testsuite/performance/25_algorithms/search_n.cc: Fix typo. + +2013-09-18 Marc Glisse <marc.glisse@inria.fr> + + PR libstdc++/58338 + * include/bits/list.tcc (_List_base::_M_clear, list::erase): Mark as + noexcept. + * include/bits/stl_list.h (_List_iterator) [_List_iterator, + _M_const_cast, operator*, operator->, operator++, operator--, + operator==, operator!=]: Likewise. + (_List_const_iterator) [_List_const_iterator, _M_const_cast, operator*, + operator->, operator++, operator--, operator==, operator!=]: Likewise. + (operator==(const _List_iterator&, const _List_const_iterator&), + operator!=(const _List_iterator&, const _List_const_iterator&)): + Likewise. + (_List_impl) [_List_impl(const _Node_alloc_type&), + _List_impl(_Node_alloc_type&&)]: Likewise. + (_List_base) [_M_put_node, _List_base(const _Node_alloc_type&), + _List_base(_List_base&&), _M_clear, _M_init]: Likewise. + (list) [list(), list(const allocator_type&)]: Merge. + (list) [list(const allocator_type&), front, back, pop_front, pop_back, + erase, _M_erase]: Mark as noexcept. + * include/debug/list (list) [list(const _Allocator&), front, back, + pop_front, pop_back, _M_erase, erase]: Likewise. + * include/profile/list (list) [list(const _Allocator&), front, back, + pop_front, pop_back, erase]: Likewise. + * testsuite/23_containers/list/requirements/dr438/assign_neg.cc: + Adjust line number. + * testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc: + Likewise. + * testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc: + Likewise. + * testsuite/23_containers/list/requirements/dr438/insert_neg.cc: + Likewise. + +2013-09-17 Marc Glisse <marc.glisse@inria.fr> + + PR libstdc++/58338 + * include/bits/stl_vector.h (vector::vector(), + vector::vector(const allocator_type&)): Merge. + (_Vector_impl::_Vector_impl(_Tp_alloc_type const&), + _Vector_impl::_Vector_impl(_Tp_alloc_type&&), + _Vector_impl::_M_swap_data, + _Vector_base::_Vector_base(const allocator_type&), + _Vector_base::_Vector_base(allocator_type&&), + _Vector_base::_Vector_base(_Vector_base&&), _Vector_base::~_Vector_base, + vector::vector(const allocator_type&), vector::operator[], + vector::operator[] const, vector::front, vector::front const, + vector::back, vector::back const, vector::pop_back, + vector::_M_erase_at_end): Mark as noexcept. + * include/debug/vector (vector::vector(const _Allocator&), + vector::operator[], vector::operator[] const, vector::front, + vector::front const, vector::back, vector::back const, vector::pop_back, + _M_requires_reallocation, _M_update_guaranteed_capacity, + _M_invalidate_after_nth): Mark as noexcept. + * include/profile/vector (vector::vector(const _Allocator&), + vector::operator[], vector::operator[] const, vector::front, + vector::front const, vector::back, vector::back const): Mark as + noexcept. + (vector::vector(vector&&, const _Allocator&)): Remove wrong noexcept. + * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc: + Adjust line number. + * testsuite/23_containers/vector/requirements/dr438/ + constructor_1_neg.cc: Likewise. + * testsuite/23_containers/vector/requirements/dr438/ + constructor_2_neg.cc: Likewise. + * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc: + Likewise. + 2013-09-14 Tim Shen <timshen91@gmail.com> * include/bits/regex.h (regex_match<>, regex_search<>): diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc index 4d8ce2351e8..718dcec1e09 100644 --- a/libstdc++-v3/include/bits/list.tcc +++ b/libstdc++-v3/include/bits/list.tcc @@ -63,7 +63,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp, typename _Alloc> void _List_base<_Tp, _Alloc>:: - _M_clear() + _M_clear() _GLIBCXX_NOEXCEPT { typedef _List_node<_Tp> _Node; _Node* __cur = static_cast<_Node*>(_M_impl._M_node._M_next); @@ -145,7 +145,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>:: #if __cplusplus >= 201103L - erase(const_iterator __position) + erase(const_iterator __position) noexcept #else erase(iterator __position) #endif diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h index 659bee13120..9d1438aab23 100644 --- a/libstdc++-v3/include/bits/regex.h +++ b/libstdc++-v3/include/bits/regex.h @@ -1004,6 +1004,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const basic_regex<_Cp, _Rp>&, regex_constants::match_flag_type); + template<typename, typename, typename, typename> + friend class __detail::_Executor; + + template<typename, typename, typename, typename> + friend class __detail::_DFSExecutor; + + template<typename, typename, typename, typename> + friend class __detail::_BFSExecutor; + flag_type _M_flags; _Rx_traits _M_traits; _AutomatonPtr _M_automaton; @@ -1783,21 +1792,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ explicit match_results(const _Alloc& __a = _Alloc()) - : _Base_type(__a) + : _Base_type(__a), _M_in_iterator(false) { } /** * @brief Copy constructs a %match_results. */ match_results(const match_results& __rhs) - : _Base_type(__rhs) + : _Base_type(__rhs), _M_in_iterator(false) { } /** * @brief Move constructs a %match_results. */ match_results(match_results&& __rhs) noexcept - : _Base_type(std::move(__rhs)) + : _Base_type(std::move(__rhs)), _M_in_iterator(false) { } /** @@ -1905,8 +1914,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION difference_type position(size_type __sub = 0) const { - return __sub < size() ? std::distance(this->prefix().first, - (*this)[__sub].first) : -1; + // [28.12.1.4.5] + if (_M_in_iterator) + return __sub < size() ? std::distance(_M_begin, + (*this)[__sub].first) : -1; + else + return __sub < size() ? std::distance(this->prefix().first, + (*this)[__sub].first) : -1; } /** @@ -2106,6 +2120,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename, typename, typename, typename> friend class __detail::_BFSExecutor; + template<typename, typename, typename> + friend class regex_iterator; + template<typename _Bp, typename _Ap, typename _Ch_type, typename _Rx_traits> friend bool @@ -2121,6 +2138,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const basic_regex<_Ch_type, _Rx_traits>&, regex_constants::match_flag_type); + + _Bi_iter _M_begin; + bool _M_in_iterator; }; typedef match_results<const char*> cmatch; @@ -2200,8 +2220,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @retval false Otherwise. * * @throws an exception of type regex_error. - * - * @todo Implement this function. */ template<typename _Bi_iter, typename _Alloc, typename _Ch_type, typename _Rx_traits> @@ -2215,6 +2233,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__re._M_automaton == nullptr) return false; + + auto __size = __re._M_automaton->_M_sub_count(); + __size += 2; + __m.resize(__size); + for (decltype(__size) __i = 0; __i < __size; ++__i) + __m.at(__i).matched = false; + if (__detail::__get_executor(__s, __e, __m, __re, __flags)->_M_match()) { for (auto __it : __m) @@ -2360,8 +2385,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * undefined. * * @throws an exception of type regex_error. - * - * @todo Implement this function. */ template<typename _Bi_iter, typename _Alloc, typename _Ch_type, typename _Rx_traits> @@ -2374,6 +2397,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__re._M_automaton == nullptr) return false; + + auto __size = __re._M_automaton->_M_sub_count(); + __size += 2; + __m.resize(__size); + for (decltype(__size) __i = 0; __i < __size; ++__i) + __m.at(__i).matched = false; + if (__detail::__get_executor(__first, __last, __m, __re, __flags) ->_M_search()) { @@ -2677,7 +2707,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: operator++() { - // FIXME: In all cases in which the call to regex_search returns true, + // In all cases in which the call to regex_search returns true, // match.prefix().first shall be equal to the previous value of // match[0].second, and for each index i in the half-open range // [0, match.size()) for which match[i].matched is true, @@ -2697,12 +2727,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags | regex_constants::match_not_null | regex_constants::match_continuous)) - return *this; + { + _M_match._M_in_iterator = true; + _M_match._M_begin = _M_begin; + return *this; + } else ++__start; } _M_flags |= regex_constants::match_prev_avail; - if (!regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags)) + if (regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags)) + { + _M_match._M_in_iterator = true; + _M_match._M_begin = _M_begin; + } + else _M_match = value_type(); } return *this; diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc index 8dc779b68e1..7f9a19af2d9 100644 --- a/libstdc++-v3/include/bits/regex_compiler.tcc +++ b/libstdc++-v3/include/bits/regex_compiler.tcc @@ -28,7 +28,7 @@ * Do not attempt to use it directly. @headername{regex} */ -// TODO make comments doxygen format. +// FIXME make comments doxygen format. // This compiler refers to "Regular Expression Matching Can Be Simple And Fast" // (http://swtch.com/~rsc/regexp/regexp1.html"), @@ -223,16 +223,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__n < 0) __throw_regex_error(regex_constants::error_badbrace); auto __end = _M_nfa._M_insert_dummy(); + // _M_alt is the "match more" branch, and _M_next is the + // "match less" one. Switch _M_alt and _M_next of all created + // nodes. This is a hacking but IMO works well. + std::stack<_StateIdT> __stack; for (int __i = 0; __i < __n; ++__i) { auto __tmp = __r._M_clone(); - __e._M_append - (_StateSeqT(_M_nfa, - _M_nfa._M_insert_alt(__tmp._M_start, - __end, __neg), - __tmp._M_end)); + auto __alt = _M_nfa._M_insert_alt(__tmp._M_start, + __end, __neg); + __stack.push(__alt); + __e._M_append(_StateSeqT(_M_nfa, __alt, __tmp._M_end)); } __e._M_append(__end); + while (!__stack.empty()) + { + auto& __tmp = _M_nfa[__stack.top()]; + __stack.pop(); + swap(__tmp._M_next, __tmp._M_alt); + } } else // {3,} { diff --git a/libstdc++-v3/include/bits/regex_constants.h b/libstdc++-v3/include/bits/regex_constants.h index 10b962ad21a..94c25e531b3 100644 --- a/libstdc++-v3/include/bits/regex_constants.h +++ b/libstdc++-v3/include/bits/regex_constants.h @@ -52,19 +52,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ //@{ enum __syntax_option - { - _S_icase, - _S_nosubs, - _S_optimize, - _S_collate, - _S_ECMAScript, - _S_basic, - _S_extended, - _S_awk, - _S_grep, - _S_egrep, - _S_syntax_last - }; + { + _S_icase, + _S_nosubs, + _S_optimize, + _S_collate, + _S_ECMAScript, + _S_basic, + _S_extended, + _S_awk, + _S_grep, + _S_egrep, + _S_syntax_last + }; /** * @brief This is a bitmask type indicating how to interpret the regex. @@ -211,20 +211,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION //@{ enum __match_flag - { - _S_not_bol, - _S_not_eol, - _S_not_bow, - _S_not_eow, - _S_any, - _S_not_null, - _S_continuous, - _S_prev_avail, - _S_sed, - _S_no_copy, - _S_first_only, - _S_match_flag_last - }; + { + _S_not_bol, + _S_not_eol, + _S_not_bow, + _S_not_eow, + _S_any, + _S_not_null, + _S_continuous, + _S_prev_avail, + _S_sed, + _S_no_copy, + _S_first_only, + _S_match_flag_last + }; /** * @brief This is a bitmask type indicating regex matching rules. @@ -233,110 +233,148 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * perform bitwise operations on these values and expect the right thing to * happen. */ - typedef std::bitset<_S_match_flag_last> match_flag_type; + enum match_flag_type : unsigned int + { + /** + * The default matching rules. + */ + match_default = 0, - /** - * The default matching rules. - */ - constexpr match_flag_type match_default = 0; + /** + * The first character in the sequence [first, last) is treated as though it + * is not at the beginning of a line, so the character (^) in the regular + * expression shall not match [first, first). + */ + match_not_bol = 1 << _S_not_bol, - /** - * The first character in the sequence [first, last) is treated as though it - * is not at the beginning of a line, so the character (^) in the regular - * expression shall not match [first, first). - */ - constexpr match_flag_type match_not_bol = 1 << _S_not_bol; + /** + * The last character in the sequence [first, last) is treated as though it + * is not at the end of a line, so the character ($) in the regular + * expression shall not match [last, last). + */ + match_not_eol = 1 << _S_not_eol, - /** - * The last character in the sequence [first, last) is treated as though it - * is not at the end of a line, so the character ($) in the regular - * expression shall not match [last, last). - */ - constexpr match_flag_type match_not_eol = 1 << _S_not_eol; + /** + * The expression \\b is not matched against the sub-sequence + * [first,first). + */ + match_not_bow = 1 << _S_not_bow, - /** - * The expression \\b is not matched against the sub-sequence - * [first,first). - */ - constexpr match_flag_type match_not_bow = 1 << _S_not_bow; + /** + * The expression \\b should not be matched against the sub-sequence + * [last,last). + */ + match_not_eow = 1 << _S_not_eow, - /** - * The expression \\b should not be matched against the sub-sequence - * [last,last). - */ - constexpr match_flag_type match_not_eow = 1 << _S_not_eow; + /** + * If more than one match is possible then any match is an acceptable + * result. + */ + match_any = 1 << _S_any, - /** - * If more than one match is possible then any match is an acceptable - * result. - */ - constexpr match_flag_type match_any = 1 << _S_any; + /** + * The expression does not match an empty sequence. + */ + match_not_null = 1 << _S_not_null, - /** - * The expression does not match an empty sequence. - */ - constexpr match_flag_type match_not_null = 1 << _S_not_null; + /** + * The expression only matches a sub-sequence that begins at first . + */ + match_continuous = 1 << _S_continuous, - /** - * The expression only matches a sub-sequence that begins at first . - */ - constexpr match_flag_type match_continuous = 1 << _S_continuous; + /** + * --first is a valid iterator position. When this flag is set then the + * flags match_not_bol and match_not_bow are ignored by the regular + * expression algorithms 28.11 and iterators 28.12. + */ + match_prev_avail = 1 << _S_prev_avail, - /** - * --first is a valid iterator position. When this flag is set then the - * flags match_not_bol and match_not_bow are ignored by the regular - * expression algorithms 28.11 and iterators 28.12. - */ - constexpr match_flag_type match_prev_avail = 1 << _S_prev_avail; + /** + * When a regular expression match is to be replaced by a new string, the + * new string is constructed using the rules used by the ECMAScript replace + * function in ECMA- 262 [Ecma International, ECMAScript Language + * Specification, Standard Ecma-262, third edition, 1999], part 15.5.4.11 + * String.prototype.replace. In addition, during search and replace + * operations all non-overlapping occurrences of the regular expression + * are located and replaced, and sections of the input that did not match + * the expression are copied unchanged to the output string. + * + * Format strings (from ECMA-262 [15.5.4.11]): + * @li $$ The dollar-sign itself ($) + * @li $& The matched substring. + * @li $` The portion of @a string that precedes the matched substring. + * This would be match_results::prefix(). + * @li $' The portion of @a string that follows the matched substring. + * This would be match_results::suffix(). + * @li $n The nth capture, where n is in [1,9] and $n is not followed by a + * decimal digit. If n <= match_results::size() and the nth capture + * is undefined, use the empty string instead. If n > + * match_results::size(), the result is implementation-defined. + * @li $nn The nnth capture, where nn is a two-digit decimal number on + * [01, 99]. If nn <= match_results::size() and the nth capture is + * undefined, use the empty string instead. If + * nn > match_results::size(), the result is implementation-defined. + */ + format_default = 0, - /** - * When a regular expression match is to be replaced by a new string, the - * new string is constructed using the rules used by the ECMAScript replace - * function in ECMA- 262 [Ecma International, ECMAScript Language - * Specification, Standard Ecma-262, third edition, 1999], part 15.5.4.11 - * String.prototype.replace. In addition, during search and replace - * operations all non-overlapping occurrences of the regular expression - * are located and replaced, and sections of the input that did not match - * the expression are copied unchanged to the output string. - * - * Format strings (from ECMA-262 [15.5.4.11]): - * @li $$ The dollar-sign itself ($) - * @li $& The matched substring. - * @li $` The portion of @a string that precedes the matched substring. - * This would be match_results::prefix(). - * @li $' The portion of @a string that follows the matched substring. - * This would be match_results::suffix(). - * @li $n The nth capture, where n is in [1,9] and $n is not followed by a - * decimal digit. If n <= match_results::size() and the nth capture - * is undefined, use the empty string instead. If n > - * match_results::size(), the result is implementation-defined. - * @li $nn The nnth capture, where nn is a two-digit decimal number on - * [01, 99]. If nn <= match_results::size() and the nth capture is - * undefined, use the empty string instead. If - * nn > match_results::size(), the result is implementation-defined. - */ - constexpr match_flag_type format_default = 0; + /** + * When a regular expression match is to be replaced by a new string, the + * new string is constructed using the rules used by the POSIX sed utility + * in IEEE Std 1003.1- 2001 [IEEE, Information Technology -- Portable + * Operating System Interface (POSIX), IEEE Standard 1003.1-2001]. + */ + format_sed = 1 << _S_sed, - /** - * When a regular expression match is to be replaced by a new string, the - * new string is constructed using the rules used by the POSIX sed utility - * in IEEE Std 1003.1- 2001 [IEEE, Information Technology -- Portable - * Operating System Interface (POSIX), IEEE Standard 1003.1-2001]. - */ - constexpr match_flag_type format_sed = 1 << _S_sed; + /** + * During a search and replace operation, sections of the character + * container sequence being searched that do not match the regular + * expression shall not be copied to the output string. + */ + format_no_copy = 1 << _S_no_copy, - /** - * During a search and replace operation, sections of the character - * container sequence being searched that do not match the regular - * expression shall not be copied to the output string. - */ - constexpr match_flag_type format_no_copy = 1 << _S_no_copy; + /** + * When specified during a search and replace operation, only the first + * occurrence of the regular expression shall be replaced. + */ + format_first_only = 1 << _S_first_only, + }; - /** - * When specified during a search and replace operation, only the first - * occurrence of the regular expression shall be replaced. - */ - constexpr match_flag_type format_first_only = 1 << _S_first_only; + constexpr inline match_flag_type + operator&(match_flag_type __a, match_flag_type __b) + { + return (match_flag_type)(static_cast<unsigned int>(__a) + & static_cast<unsigned int>(__b)); + } + + constexpr inline match_flag_type + operator|(match_flag_type __a, match_flag_type __b) + { + return (match_flag_type)(static_cast<unsigned int>(__a) + | static_cast<unsigned int>(__b)); + } + + constexpr inline match_flag_type + operator^(match_flag_type __a, match_flag_type __b) + { + return (match_flag_type)(static_cast<unsigned int>(__a) + ^ static_cast<unsigned int>(__b)); + } + + constexpr inline match_flag_type + operator~(match_flag_type __a) + { return (match_flag_type)(~static_cast<unsigned int>(__a)); } + + inline match_flag_type& + operator&=(match_flag_type& __a, match_flag_type __b) + { return __a = __a & __b; } + + inline match_flag_type& + operator|=(match_flag_type& __a, match_flag_type __b) + { return __a = __a | __b; } + + inline match_flag_type& + operator^=(match_flag_type& __a, match_flag_type __b) + { return __a = __a ^ __b; } //@} diff --git a/libstdc++-v3/include/bits/regex_executor.h b/libstdc++-v3/include/bits/regex_executor.h index 3df33e03024..b8e9266f910 100644 --- a/libstdc++-v3/include/bits/regex_executor.h +++ b/libstdc++-v3/include/bits/regex_executor.h @@ -28,7 +28,11 @@ * Do not attempt to use it directly. @headername{regex} */ -// TODO: convert comments to doxygen format. +// FIXME convert comments to doxygen format. + +// TODO Put _DFSExecutor and _BFSExecutor into one class. They are becoming +// much more similar. Also, make grouping seperated. The +// regex_constants::nosubs enables much more simpler execution. namespace std _GLIBCXX_VISIBILITY(default) { @@ -57,55 +61,107 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION class _Executor { public: + typedef basic_regex<_CharT, _TraitsT> _RegexT; typedef match_results<_BiIter, _Alloc> _ResultsT; typedef std::vector<sub_match<_BiIter>, _Alloc> _ResultsVec; typedef regex_constants::match_flag_type _FlagT; + typedef typename _TraitsT::char_class_type _ClassT; - virtual - ~_Executor() + public: + _Executor(_BiIter __begin, + _BiIter __end, + _ResultsT& __results, + const _RegexT& __re, + _FlagT __flags) + : _M_begin(__begin), + _M_end(__end), + _M_results(__results), + _M_re(__re), + _M_flags(__flags) { } // Set matched when string exactly match the pattern. - virtual bool - _M_match() = 0; + bool + _M_match() + { + _M_match_mode = true; + _M_init(_M_begin); + return _M_main(); + } // Set matched when some prefix of the string matches the pattern. - virtual bool - _M_search() = 0; - - protected: - typedef typename _NFA<_CharT, _TraitsT>::_SizeT _SizeT; - typedef typename _TraitsT::char_class_type _ClassT; + bool + _M_search_from_first() + { + _M_match_mode = false; + _M_init(_M_begin); + return _M_main(); + } - _Executor(_BiIter __begin, - _BiIter __end, - _ResultsT& __results, - _FlagT __flags, - _SizeT __size, - const _TraitsT& __traits) - : _M_current(__begin), _M_begin(__begin), _M_end(__end), - _M_results(__results), _M_flags(__flags), _M_traits(__traits) + bool + _M_search() { - __size += 2; - _M_results.resize(__size); - for (_SizeT __i = 0; __i < __size; ++__i) - _M_results[__i].matched = false; + if (_M_flags & regex_constants::match_continuous) + return _M_search_from_first(); + auto __cur = _M_begin; + do + { + _M_match_mode = false; + _M_init(__cur); + if (_M_main()) + return true; + } + // Continue when __cur == _M_end + while (__cur++ != _M_end); + return false; } bool - _M_is_word(_CharT __ch) + _M_is_word(_CharT __ch) const { static const _CharT __s = 'w'; - return _M_traits.isctype(__ch, - _M_traits.lookup_classname(&__s, &__s+1)); + return _M_re._M_traits.isctype + (__ch, _M_re._M_traits.lookup_classname(&__s, &__s+1)); + } + + bool + _M_at_begin() const + { + return _M_current == _M_begin + && !(_M_flags & (regex_constants::match_not_bol + | regex_constants::match_prev_avail)); } + bool + _M_at_end() const + { + return _M_current == _M_end + && !(_M_flags & regex_constants::match_not_eol); + } + + bool + _M_word_boundry(_State<_CharT, _TraitsT> __state) const; + + bool + _M_lookahead(_State<_CharT, _TraitsT> __state) const; + + public: + virtual void + _M_init(_BiIter __cur) = 0; + + virtual void + _M_set_start(_StateIdT __start) = 0; + + virtual bool + _M_main() = 0; + _BiIter _M_current; const _BiIter _M_begin; const _BiIter _M_end; - _ResultsVec& _M_results; - const _TraitsT& _M_traits; - _FlagT _M_flags; + const _RegexT& _M_re; + _ResultsT& _M_results; + const _FlagT _M_flags; + bool _M_match_mode; }; // A _DFSExecutor perform a DFS on given NFA and input string. At the very @@ -128,61 +184,46 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: typedef _Executor<_BiIter, _Alloc, _CharT, _TraitsT> _BaseT; - typedef _NFA<_CharT, _TraitsT> _RegexT; + typedef _NFA<_CharT, _TraitsT> _NFAT; + typedef typename _BaseT::_RegexT _RegexT; typedef typename _BaseT::_ResultsT _ResultsT; typedef typename _BaseT::_ResultsVec _ResultsVec; - typedef regex_constants::match_flag_type _FlagT; + typedef typename _BaseT::_FlagT _FlagT; + public: _DFSExecutor(_BiIter __begin, _BiIter __end, _ResultsT& __results, - const _RegexT& __nfa, - const _TraitsT& __traits, + const _RegexT& __re, _FlagT __flags) - : _BaseT(__begin, __end, __results, __flags, __nfa._M_sub_count(), - __traits), - _M_traits(__traits), _M_nfa(__nfa), _M_cur_results(this->_M_results), - _M_start_state(__nfa._M_start()) + : _BaseT(__begin, __end, __results, __re, __flags), + _M_nfa(*std::static_pointer_cast<_NFA<_CharT, _TraitsT>> + (__re._M_automaton)), + _M_start_state(_M_nfa._M_start()) { } - bool - _M_match() + private: + void + _M_init(_BiIter __cur) { - this->_M_current = this->_M_begin; - return _M_dfs<true>(_M_start_state); + _M_cur_results.resize(_M_nfa._M_sub_count() + 2); + this->_M_current = __cur; } - bool - _M_search_from_first() - { - this->_M_current = this->_M_begin; - return _M_dfs<false>(_M_start_state); - } + void + _M_set_start(_StateIdT __start) + { _M_start_state = __start; } bool - _M_search() - { - auto __cur = this->_M_begin; - do - { - this->_M_current = __cur; - if (_M_dfs<false>(_M_start_state)) - return true; - } - // Continue when __cur == _M_end - while (__cur++ != this->_M_end); - return false; - } + _M_main() + { return _M_dfs(this->_M_start_state); } - private: - template<bool __match_mode> - bool - _M_dfs(_StateIdT __i); + bool + _M_dfs(_StateIdT __start); // To record current solution. _ResultsVec _M_cur_results; - const _TraitsT& _M_traits; - const _RegexT& _M_nfa; + const _NFAT& _M_nfa; _StateIdT _M_start_state; }; @@ -206,47 +247,57 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: typedef _Executor<_BiIter, _Alloc, _CharT, _TraitsT> _BaseT; - typedef _NFA<_CharT, _TraitsT> _RegexT; + typedef _NFA<_CharT, _TraitsT> _NFAT; + typedef typename _BaseT::_RegexT _RegexT; typedef typename _BaseT::_ResultsT _ResultsT; + typedef typename _BaseT::_ResultsVec _ResultsVec; + typedef typename _BaseT::_FlagT _FlagT; // Here's a solution for greedy/ungreedy mode in BFS approach. We need to // carefully work out how to compare to conflict matching states. // // A matching state is a pair(where, when); `where` is a NFA node; `when` - // is a _BiIter, indicating which char is the next to be mathed one. Two - // matching states conflict means that they have equivalent `where` and - // `when`. + // is a _BiIter, indicating which char is the next to be matched. Two + // matching states conflict if they have equivalent `where` and `when`. // - // Now since we need to drop one and keep another, because at most one of - // them could be the final optimal solution. This behavior is affected by + // Now we need to drop one and keep another, because at most one of them + // could be the final optimal solution. This behavior is affected by // greedy policy. // // The definition of `greedy`: // For the sequence of quantifiers in NFA sorted by there start position, - // now maintain a vector in a matching state, with equal length to + // now maintain a vector in every matching state, with equal length to // quantifier seq, recording repeating times of every quantifier. Now to // compare two matching states, we just lexically compare these two // vectors. To win the compare(to survive), one matching state needs to // make its greedy quantifier count larger, and ungreedy quantifiers // count smaller. // - // In the implementation, we recorded negtive numbers for greedy - // quantifiers and positive numbers of ungreedy ones. Now a simple + // In the implementation, we recorded negtive counts for greedy + // quantifiers and positive counts of ungreedy ones. Now the implicit // operator<() for lexicographical_compare will emit the answer. // // When two vectors equal, it means the `where`, `when` and quantifier - // counts are identical, it indicates the same answer, so just return + // counts are identical, and indicates the same solution; so just return // false. struct _ResultsEntry - : private _BaseT::_ResultsVec + : private _ResultsVec { public: _ResultsEntry(unsigned int __res_sz, unsigned int __sz) - : _BaseT::_ResultsVec(__res_sz), _M_quant_keys(__sz) + : _ResultsVec(__res_sz), _M_quant_keys(__sz) { } + void + resize(unsigned int __n) + { _ResultsVec::resize(__n); } + + unsigned int + size() + { return _ResultsVec::size(); } + sub_match<_BiIter>& operator[](unsigned int __idx) - { return this->_BaseT::_ResultsVec::operator[](__idx); } + { return _ResultsVec::operator[](__idx); } bool operator<(const _ResultsEntry& __rhs) const @@ -263,75 +314,47 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_inc(unsigned int __idx, bool __neg) { _M_quant_keys[__idx] += __neg ? 1 : -1; } - typename _BaseT::_ResultsVec + _ResultsVec _M_get() { return *this; } public: std::vector<int> _M_quant_keys; }; - typedef std::unique_ptr<_ResultsEntry> _ResultsPtr; - typedef regex_constants::match_flag_type _FlagT; + public: _BFSExecutor(_BiIter __begin, _BiIter __end, _ResultsT& __results, - const _RegexT& __nfa, - const _TraitsT& __traits, + const _RegexT& __re, _FlagT __flags) - : _BaseT(__begin, __end, __results, __flags, __nfa._M_sub_count(), - __traits), - _M_nfa(__nfa), - _M_cur_results(nullptr), - _M_start_state(__nfa._M_start()) + : _BaseT(__begin, __end, __results, __re, __flags), + _M_nfa(*std::static_pointer_cast<_NFA<_CharT, _TraitsT>> + (__re._M_automaton)), + _M_start_state(_M_nfa._M_start()) { } - bool - _M_match() - { - _M_init(this->_M_begin); - return _M_main_loop<true>(); - } - - bool - _M_search_from_first() - { - _M_init(this->_M_begin); - return _M_main_loop<false>(); - } - - bool - _M_search() - { - auto __cur = this->_M_begin; - do - { - _M_init(__cur); - if (_M_main_loop<false>()) - return true; - } - // Continue when __cur == _M_end - while (__cur++ != this->_M_end); - return false; - } - private: void _M_init(_BiIter __cur) { - _GLIBCXX_DEBUG_ASSERT(_M_start_state != _S_invalid_state_id); + _GLIBCXX_DEBUG_ASSERT(this->_M_start_state != _S_invalid_state_id); this->_M_current = __cur; _M_covered.clear(); - _M_covered[_M_start_state] = - _ResultsPtr(new _ResultsEntry(this->_M_results.size(), + _ResultsVec& __res(this->_M_results); + _M_covered[this->_M_start_state] = + _ResultsPtr(new _ResultsEntry(__res.size(), _M_nfa._M_quant_count)); _M_e_closure(); } - template<bool __match_mode> - bool - _M_main_loop(); + void + _M_set_start(_StateIdT __start) + { _M_start_state = __start; } + + bool + _M_main(); void _M_e_closure(); @@ -345,10 +368,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::map<_StateIdT, _ResultsPtr> _M_covered; // To record global optimal solution. _ResultsPtr _M_cur_results; - const _RegexT& _M_nfa; + const _NFAT& _M_nfa; _StateIdT _M_start_state; }; + template<typename _BiIter, typename _Alloc, + typename _CharT, typename _TraitsT> + std::unique_ptr<_Executor<_BiIter, _Alloc, _CharT, _TraitsT>> + __get_executor(_BiIter __b, + _BiIter __e, + match_results<_BiIter, _Alloc>& __m, + const basic_regex<_CharT, _TraitsT>& __re, + regex_constants::match_flag_type __flags); + //@} regex-detail _GLIBCXX_END_NAMESPACE_VERSION } // namespace __detail diff --git a/libstdc++-v3/include/bits/regex_executor.tcc b/libstdc++-v3/include/bits/regex_executor.tcc index b110c5dc2f0..af2455b8a4e 100644 --- a/libstdc++-v3/include/bits/regex_executor.tcc +++ b/libstdc++-v3/include/bits/regex_executor.tcc @@ -36,7 +36,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _BiIter, typename _Alloc, typename _CharT, typename _TraitsT> - template<bool __match_mode> bool _DFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>:: _M_dfs(_StateIdT __i) { @@ -44,9 +43,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // This is not that certain. Need deeper investigate. return false; auto& __current = this->_M_current; - auto& __begin = this->_M_begin; - auto& __end = this->_M_end; - auto& __results = _M_cur_results; const auto& __state = _M_nfa[__i]; bool __ret = false; switch (__state._M_opcode) @@ -54,129 +50,115 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION case _S_opcode_alternative: // Greedy or not, this is a question ;) if (!__state._M_neg) - __ret = _M_dfs<__match_mode>(__state._M_alt) - || _M_dfs<__match_mode>(__state._M_next); + __ret = _M_dfs(__state._M_alt) + || _M_dfs(__state._M_next); else - __ret = _M_dfs<__match_mode>(__state._M_next) - || _M_dfs<__match_mode>(__state._M_alt); + __ret = _M_dfs(__state._M_next) + || _M_dfs(__state._M_alt); break; case _S_opcode_subexpr_begin: // Here's the critical part: if there's nothing changed since last // visit, do NOT continue. This prevents the executor from get into // infinite loop when use "()*" to match "". // - // Every change on __results will be roll back after the recursion - // step finished. - if (!__results[__state._M_subexpr].matched - || __results[__state._M_subexpr].first != __current) + // Every change on _M_cur_results will be roll back after the + // recursion step finished. + if (!_M_cur_results[__state._M_subexpr].matched + || _M_cur_results[__state._M_subexpr].first != __current) { auto __back = __current; - __results[__state._M_subexpr].first = __current; - __ret = _M_dfs<__match_mode>(__state._M_next); - __results[__state._M_subexpr].first = __back; + _M_cur_results[__state._M_subexpr].first = __current; + __ret = _M_dfs(__state._M_next); + _M_cur_results[__state._M_subexpr].first = __back; } break; case _S_opcode_subexpr_end: - if (__results[__state._M_subexpr].second != __current - || __results[__state._M_subexpr].matched != true) + if (_M_cur_results[__state._M_subexpr].second != __current + || _M_cur_results[__state._M_subexpr].matched != true) { - auto __back = __results[__state._M_subexpr]; - __results[__state._M_subexpr].second = __current; - __results[__state._M_subexpr].matched = true; - __ret = _M_dfs<__match_mode>(__state._M_next); - __results[__state._M_subexpr] = __back; + auto __back = _M_cur_results[__state._M_subexpr]; + _M_cur_results[__state._M_subexpr].second = __current; + _M_cur_results[__state._M_subexpr].matched = true; + __ret = _M_dfs(__state._M_next); + _M_cur_results[__state._M_subexpr] = __back; } else - __ret = _M_dfs<__match_mode>(__state._M_next); + __ret = _M_dfs(__state._M_next); break; case _S_opcode_line_begin_assertion: - if (__current == __begin) - __ret = _M_dfs<__match_mode>(__state._M_next); + if (this->_M_at_begin()) + __ret = _M_dfs(__state._M_next); break; case _S_opcode_line_end_assertion: - if (__current == __end) - __ret = _M_dfs<__match_mode>(__state._M_next); + if (this->_M_at_end()) + __ret = _M_dfs(__state._M_next); break; - // By definition. case _S_opcode_word_boundry: - { - bool __ans = false; - if (__current == __begin && this->_M_is_word(*__current)) - __ans = true; - else if (__current == __end && this->_M_is_word(*__current)) - __ans = true; - else - { - auto __pre = __current; - --__pre; - if (this->_M_is_word(*__current) - != this->_M_is_word(*__pre)) - __ans = true; - } - if (__ans == !__state._M_neg) - __ret = _M_dfs<__match_mode>(__state._M_next); - } + if (this->_M_word_boundry(__state) == !__state._M_neg) + __ret = _M_dfs(__state._M_next); break; // Here __state._M_alt offers a single start node for a sub-NFA. // We recursivly invoke our algorithm to match the sub-NFA. case _S_opcode_subexpr_lookahead: - { - _ResultsT __m; - // FIXME Here's not necessarily a DFSExecutor. But we need to - // refactor the whole NFA to a recursive tree structure first. - _DFSExecutor __sub(this->_M_current, - this->_M_end, - __m, - this->_M_nfa, - this->_M_traits, - this->_M_flags); - __sub._M_start_state = __state._M_alt; - if (__sub._M_search_from_first() == !__state._M_neg) - __ret = _M_dfs<__match_mode>(__state._M_next); - } + if (this->_M_lookahead(__state) == !__state._M_neg) + __ret = _M_dfs(__state._M_next); break; case _S_opcode_match: - if (__current != __end && __state._M_matches(*__current)) + if (__current != this->_M_end && __state._M_matches(*__current)) { ++__current; - __ret = _M_dfs<__match_mode>(__state._M_next); + __ret = _M_dfs(__state._M_next); --__current; } break; - // First fetch the matched result from __results as __submatch; + // First fetch the matched result from _M_cur_results as __submatch; // then compare it with // (__current, __current + (__submatch.second - __submatch.first)) // If matched, keep going; else just return to try another state. case _S_opcode_backref: { - auto& __submatch = __results[__state._M_backref_index]; + auto& __submatch = _M_cur_results[__state._M_backref_index]; if (!__submatch.matched) break; auto __last = __current; for (auto __tmp = __submatch.first; - __last != __end && __tmp != __submatch.second; + __last != this->_M_end && __tmp != __submatch.second; ++__tmp) ++__last; - if (_M_traits.transform(__submatch.first, __submatch.second) - == _M_traits.transform(__current, __last)) + if (this->_M_re._M_traits.transform(__submatch.first, + __submatch.second) + == this->_M_re._M_traits.transform(__current, __last)) if (__last != __current) { auto __backup = __current; __current = __last; - __ret = _M_dfs<__match_mode>(__state._M_next); + __ret = _M_dfs(__state._M_next); __current = __backup; } else - __ret = _M_dfs<__match_mode>(__state._M_next); + __ret = _M_dfs(__state._M_next); } break; case _S_opcode_accept: - if (__match_mode) - __ret = __current == __end; + if (this->_M_match_mode) + __ret = __current == this->_M_end; else __ret = true; + if (__current == this->_M_begin + && (this->_M_flags & regex_constants::match_not_null)) + __ret = false; if (__ret) - this->_M_results = __results; + { + _ResultsVec& __res(this->_M_results); + if (this->_M_re.flags() & regex_constants::nosubs) + { + _M_cur_results.resize(3); // truncate + __res.resize(3); + } + for (unsigned int __i = 0; __i < _M_cur_results.size(); ++__i) + if (_M_cur_results[__i].matched) + __res[__i] = _M_cur_results[__i]; + } break; default: _GLIBCXX_DEBUG_ASSERT(false); @@ -186,23 +168,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _BiIter, typename _Alloc, typename _CharT, typename _TraitsT> - template<bool __match_mode> bool _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>:: - _M_main_loop() + _M_main() { bool __ret = false; + if (!this->_M_match_mode + && !(this->_M_flags & regex_constants::match_not_null)) + __ret = _M_includes_some() || __ret; while (this->_M_current != this->_M_end) { - if (!__match_mode) - // To keep regex_search greedy, no "return true" here. - __ret = _M_includes_some() || __ret; _M_move(); ++this->_M_current; _M_e_closure(); + if (!this->_M_match_mode) + // To keep regex_search greedy, no "return true" here. + __ret = _M_includes_some() || __ret; } - __ret = _M_includes_some() || __ret; + if (this->_M_match_mode) + __ret = _M_includes_some(); if (__ret) - this->_M_results = _M_cur_results->_M_get(); + { + _ResultsVec& __res(this->_M_results); + if (this->_M_re.flags() & regex_constants::nosubs) + { + // truncate + _M_cur_results->resize(3); + __res.resize(3); + } + for (unsigned int __i = 0; __i < _M_cur_results->size(); ++__i) + if ((*_M_cur_results)[__i].matched) + __res[__i] = (*_M_cur_results)[__i]; + } return __ret; } @@ -211,11 +207,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>:: _M_e_closure() { - auto& __current = this->_M_current; std::queue<_StateIdT> __q; std::vector<bool> __in_q(_M_nfa.size(), false); - auto& __begin = this->_M_begin; - auto& __end = this->_M_end; + auto& __current = this->_M_current; for (auto& __it : _M_covered) { @@ -292,46 +286,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } break; case _S_opcode_line_begin_assertion: - if (__current == __begin) + if (this->_M_at_begin()) __add_visited_state(__state._M_next); break; case _S_opcode_line_end_assertion: - if (__current == __end) + if (this->_M_at_end()) __add_visited_state(__state._M_next); break; case _S_opcode_word_boundry: - { - bool __ans = false; - if (__current == __begin && this->_M_is_word(*__current)) - __ans = true; - else if (__current == __end && this->_M_is_word(*__current)) - __ans = true; - else - { - auto __pre = __current; - --__pre; - if (this->_M_is_word(*__current) - != this->_M_is_word(*__pre)) - __ans = true; - } - if (__ans == !__state._M_neg) - __add_visited_state(__state._M_next); - } + if (this->_M_word_boundry(__state) == !__state._M_neg) + __add_visited_state(__state._M_next); break; case _S_opcode_subexpr_lookahead: - { - _ResultsT __m; - // Same comment as in DFS. - _BFSExecutor __sub(this->_M_current, - this->_M_end, - __m, - this->_M_nfa, - this->_M_traits, - this->_M_flags); - __sub._M_start_state = __state._M_alt; - if (__sub._M_search_from_first() == !__state._M_neg) - __add_visited_state(__state._M_next); - } + if (this->_M_lookahead(__state) == !__state._M_neg) + __add_visited_state(__state._M_next); break; case _S_opcode_match: break; @@ -395,6 +363,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __succ; } + // Return whether now is at some word boundry. + template<typename _BiIter, typename _Alloc, + typename _CharT, typename _TraitsT> + bool _Executor<_BiIter, _Alloc, _CharT, _TraitsT>:: + _M_word_boundry(_State<_CharT, _TraitsT> __state) const + { + // By definition. + bool __ans = false; + auto __pre = _M_current; + --__pre; + if (!(_M_at_begin() && _M_at_end())) + if (_M_at_begin()) + __ans = _M_is_word(*_M_current) + && !(_M_flags & regex_constants::match_not_bow); + else if (_M_at_end()) + __ans = _M_is_word(*__pre) + && !(_M_flags & regex_constants::match_not_eow); + else + __ans = _M_is_word(*_M_current) + != _M_is_word(*__pre); + return __ans; + } + + // Return whether now match the given sub-NFA. + template<typename _BiIter, typename _Alloc, + typename _CharT, typename _TraitsT> + bool _Executor<_BiIter, _Alloc, _CharT, _TraitsT>:: + _M_lookahead(_State<_CharT, _TraitsT> __state) const + { + auto __sub = __get_executor(this->_M_current, + this->_M_end, + this->_M_results, + this->_M_re, + this->_M_flags); + __sub->_M_set_start(__state._M_alt); + return __sub->_M_search_from_first(); + } + template<typename _BiIter, typename _Alloc, typename _CharT, typename _TraitsT> std::unique_ptr<_Executor<_BiIter, _Alloc, _CharT, _TraitsT>> @@ -411,10 +417,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto __p = std::static_pointer_cast<_NFA<_CharT, _TraitsT>> (__re._M_automaton); if (__p->_M_has_backref) - return _ExecutorPtr(new _DFSExecutorT(__b, __e, __m, *__p, - __re._M_traits, __flags)); - return _ExecutorPtr(new _BFSExecutorT(__b, __e, __m, *__p, - __re._M_traits, __flags)); + return _ExecutorPtr(new _DFSExecutorT(__b, __e, __m, __re, __flags)); + return _ExecutorPtr(new _BFSExecutorT(__b, __e, __m, __re, __flags)); } _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/bits/regex_scanner.h b/libstdc++-v3/include/bits/regex_scanner.h index 824d6ce1081..09a18f634a0 100644 --- a/libstdc++-v3/include/bits/regex_scanner.h +++ b/libstdc++-v3/include/bits/regex_scanner.h @@ -68,7 +68,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_token_backref, _S_token_subexpr_begin, _S_token_subexpr_no_group_begin, - _S_token_subexpr_lookahead_begin, + _S_token_subexpr_lookahead_begin, // neg if _M_value[0] == 'n' _S_token_subexpr_end, _S_token_bracket_begin, _S_token_bracket_neg_begin, @@ -86,7 +86,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_token_ungreedy, _S_token_line_begin, _S_token_line_end, - _S_token_word_bound, + _S_token_word_bound, // neg if _M_value[0] == 'n' _S_token_comma, _S_token_dup_count, _S_token_eof, @@ -174,7 +174,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _StringT _M_value; bool _M_at_bracket_start; public: - // TODO: make them static when this file is stable. + // FIXME: make them static when this file is stable. const std::map<char, _TokenT> _M_token_map; const std::map<char, char> _M_ecma_escape_map; const std::map<char, char> _M_awk_escape_map; diff --git a/libstdc++-v3/include/bits/regex_scanner.tcc b/libstdc++-v3/include/bits/regex_scanner.tcc index 4b66157278b..abdbcc64f1f 100644 --- a/libstdc++-v3/include/bits/regex_scanner.tcc +++ b/libstdc++-v3/include/bits/regex_scanner.tcc @@ -28,7 +28,7 @@ * Do not attempt to use it directly. @headername{regex} */ -// TODO make comments doxygen format. +// FIXME make comments doxygen format. // N3376 specified 6 regex styles: ECMAScript, basic, extended, grep, egrep // and awk diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index cde442fb249..1f555a4ef28 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -721,22 +721,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef typename __traits_type::reference reference; typedef typename __traits_type::pointer pointer; - _GLIBCXX_CONSTEXPR __normal_iterator() : _M_current(_Iterator()) { } + _GLIBCXX_CONSTEXPR __normal_iterator() _GLIBCXX_NOEXCEPT + : _M_current(_Iterator()) { } explicit - __normal_iterator(const _Iterator& __i) : _M_current(__i) { } + __normal_iterator(const _Iterator& __i) _GLIBCXX_NOEXCEPT + : _M_current(__i) { } // Allow iterator to const_iterator conversion template<typename _Iter> __normal_iterator(const __normal_iterator<_Iter, typename __enable_if< (std::__are_same<_Iter, typename _Container::pointer>::__value), - _Container>::__type>& __i) + _Container>::__type>& __i) _GLIBCXX_NOEXCEPT : _M_current(__i.base()) { } #if __cplusplus >= 201103L __normal_iterator<typename _Container::pointer, _Container> - _M_const_cast() const + _M_const_cast() const noexcept { using _PTraits = std::pointer_traits<typename _Container::pointer>; return __normal_iterator<typename _Container::pointer, _Container> @@ -751,59 +753,59 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Forward iterator requirements reference - operator*() const + operator*() const _GLIBCXX_NOEXCEPT { return *_M_current; } pointer - operator->() const + operator->() const _GLIBCXX_NOEXCEPT { return _M_current; } __normal_iterator& - operator++() + operator++() _GLIBCXX_NOEXCEPT { ++_M_current; return *this; } __normal_iterator - operator++(int) + operator++(int) _GLIBCXX_NOEXCEPT { return __normal_iterator(_M_current++); } // Bidirectional iterator requirements __normal_iterator& - operator--() + operator--() _GLIBCXX_NOEXCEPT { --_M_current; return *this; } __normal_iterator - operator--(int) + operator--(int) _GLIBCXX_NOEXCEPT { return __normal_iterator(_M_current--); } // Random access iterator requirements reference - operator[](difference_type __n) const + operator[](difference_type __n) const _GLIBCXX_NOEXCEPT { return _M_current[__n]; } __normal_iterator& - operator+=(difference_type __n) + operator+=(difference_type __n) _GLIBCXX_NOEXCEPT { _M_current += __n; return *this; } __normal_iterator - operator+(difference_type __n) const + operator+(difference_type __n) const _GLIBCXX_NOEXCEPT { return __normal_iterator(_M_current + __n); } __normal_iterator& - operator-=(difference_type __n) + operator-=(difference_type __n) _GLIBCXX_NOEXCEPT { _M_current -= __n; return *this; } __normal_iterator - operator-(difference_type __n) const + operator-(difference_type __n) const _GLIBCXX_NOEXCEPT { return __normal_iterator(_M_current - __n); } const _Iterator& - base() const + base() const _GLIBCXX_NOEXCEPT { return _M_current; } }; @@ -820,24 +822,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline bool operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() == __rhs.base(); } template<typename _Iterator, typename _Container> inline bool operator==(const __normal_iterator<_Iterator, _Container>& __lhs, const __normal_iterator<_Iterator, _Container>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() == __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Container> inline bool operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() != __rhs.base(); } template<typename _Iterator, typename _Container> inline bool operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, const __normal_iterator<_Iterator, _Container>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() != __rhs.base(); } // Random access iterator requirements @@ -845,48 +851,56 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline bool operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() < __rhs.base(); } template<typename _Iterator, typename _Container> inline bool operator<(const __normal_iterator<_Iterator, _Container>& __lhs, const __normal_iterator<_Iterator, _Container>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() < __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Container> inline bool operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() > __rhs.base(); } template<typename _Iterator, typename _Container> inline bool operator>(const __normal_iterator<_Iterator, _Container>& __lhs, const __normal_iterator<_Iterator, _Container>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() > __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Container> inline bool operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() <= __rhs.base(); } template<typename _Iterator, typename _Container> inline bool operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, const __normal_iterator<_Iterator, _Container>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() <= __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Container> inline bool operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() >= __rhs.base(); } template<typename _Iterator, typename _Container> inline bool operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, const __normal_iterator<_Iterator, _Container>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() >= __rhs.base(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -898,7 +912,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // DR 685. inline auto operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) + const __normal_iterator<_IteratorR, _Container>& __rhs) noexcept -> decltype(__lhs.base() - __rhs.base()) #else inline typename __normal_iterator<_IteratorL, _Container>::difference_type @@ -911,12 +925,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline typename __normal_iterator<_Iterator, _Container>::difference_type operator-(const __normal_iterator<_Iterator, _Container>& __lhs, const __normal_iterator<_Iterator, _Container>& __rhs) + _GLIBCXX_NOEXCEPT { return __lhs.base() - __rhs.base(); } template<typename _Iterator, typename _Container> inline __normal_iterator<_Iterator, _Container> operator+(typename __normal_iterator<_Iterator, _Container>::difference_type __n, const __normal_iterator<_Iterator, _Container>& __i) + _GLIBCXX_NOEXCEPT { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index 5e8312dc6ff..71ef819176c 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -133,35 +133,35 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typedef _Tp* pointer; typedef _Tp& reference; - _List_iterator() + _List_iterator() _GLIBCXX_NOEXCEPT : _M_node() { } explicit - _List_iterator(__detail::_List_node_base* __x) + _List_iterator(__detail::_List_node_base* __x) _GLIBCXX_NOEXCEPT : _M_node(__x) { } _Self - _M_const_cast() const + _M_const_cast() const _GLIBCXX_NOEXCEPT { return *this; } // Must downcast from _List_node_base to _List_node to get to _M_data. reference - operator*() const + operator*() const _GLIBCXX_NOEXCEPT { return static_cast<_Node*>(_M_node)->_M_data; } pointer - operator->() const + operator->() const _GLIBCXX_NOEXCEPT { return std::__addressof(static_cast<_Node*>(_M_node)->_M_data); } _Self& - operator++() + operator++() _GLIBCXX_NOEXCEPT { _M_node = _M_node->_M_next; return *this; } _Self - operator++(int) + operator++(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _M_node->_M_next; @@ -169,14 +169,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } _Self& - operator--() + operator--() _GLIBCXX_NOEXCEPT { _M_node = _M_node->_M_prev; return *this; } _Self - operator--(int) + operator--(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _M_node->_M_prev; @@ -184,11 +184,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } bool - operator==(const _Self& __x) const + operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node == __x._M_node; } bool - operator!=(const _Self& __x) const + operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node != __x._M_node; } // The only member points to the %list element. @@ -213,39 +213,40 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typedef const _Tp* pointer; typedef const _Tp& reference; - _List_const_iterator() + _List_const_iterator() _GLIBCXX_NOEXCEPT : _M_node() { } explicit _List_const_iterator(const __detail::_List_node_base* __x) + _GLIBCXX_NOEXCEPT : _M_node(__x) { } - _List_const_iterator(const iterator& __x) + _List_const_iterator(const iterator& __x) _GLIBCXX_NOEXCEPT : _M_node(__x._M_node) { } iterator - _M_const_cast() const + _M_const_cast() const _GLIBCXX_NOEXCEPT { return iterator(const_cast<__detail::_List_node_base*>(_M_node)); } // Must downcast from List_node_base to _List_node to get to // _M_data. reference - operator*() const + operator*() const _GLIBCXX_NOEXCEPT { return static_cast<_Node*>(_M_node)->_M_data; } pointer - operator->() const + operator->() const _GLIBCXX_NOEXCEPT { return std::__addressof(static_cast<_Node*>(_M_node)->_M_data); } _Self& - operator++() + operator++() _GLIBCXX_NOEXCEPT { _M_node = _M_node->_M_next; return *this; } _Self - operator++(int) + operator++(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _M_node->_M_next; @@ -253,14 +254,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } _Self& - operator--() + operator--() _GLIBCXX_NOEXCEPT { _M_node = _M_node->_M_prev; return *this; } _Self - operator--(int) + operator--(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _M_node->_M_prev; @@ -268,11 +269,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } bool - operator==(const _Self& __x) const + operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node == __x._M_node; } bool - operator!=(const _Self& __x) const + operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node != __x._M_node; } // The only member points to the %list element. @@ -282,13 +283,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Val> inline bool operator==(const _List_iterator<_Val>& __x, - const _List_const_iterator<_Val>& __y) + const _List_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT { return __x._M_node == __y._M_node; } template<typename _Val> inline bool operator!=(const _List_iterator<_Val>& __x, - const _List_const_iterator<_Val>& __y) + const _List_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT { return __x._M_node != __y._M_node; } @@ -324,12 +325,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _Node_alloc_type(), _M_node() { } - _List_impl(const _Node_alloc_type& __a) + _List_impl(const _Node_alloc_type& __a) _GLIBCXX_NOEXCEPT : _Node_alloc_type(__a), _M_node() { } #if __cplusplus >= 201103L - _List_impl(_Node_alloc_type&& __a) + _List_impl(_Node_alloc_type&& __a) _GLIBCXX_NOEXCEPT : _Node_alloc_type(std::move(__a)), _M_node() { } #endif @@ -342,7 +343,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { return _M_impl._Node_alloc_type::allocate(1); } void - _M_put_node(_List_node<_Tp>* __p) + _M_put_node(_List_node<_Tp>* __p) _GLIBCXX_NOEXCEPT { _M_impl._Node_alloc_type::deallocate(__p, 1); } public: @@ -368,12 +369,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _M_impl() { _M_init(); } - _List_base(const _Node_alloc_type& __a) + _List_base(const _Node_alloc_type& __a) _GLIBCXX_NOEXCEPT : _M_impl(__a) { _M_init(); } #if __cplusplus >= 201103L - _List_base(_List_base&& __x) + _List_base(_List_base&& __x) noexcept : _M_impl(std::move(__x._M_get_Node_allocator())) { _M_init(); @@ -386,10 +387,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { _M_clear(); } void - _M_clear(); + _M_clear() _GLIBCXX_NOEXCEPT; void - _M_init() + _M_init() _GLIBCXX_NOEXCEPT { this->_M_impl._M_node._M_next = &this->_M_impl._M_node; this->_M_impl._M_node._M_prev = &this->_M_impl._M_node; @@ -526,17 +527,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // [23.2.2.1] construct/copy/destroy // (assign() and get_allocator() are also listed in this section) /** - * @brief Default constructor creates no elements. - */ - list() - : _Base() { } - - /** * @brief Creates a %list with no elements. * @param __a An allocator object. */ explicit - list(const allocator_type& __a) + list(const allocator_type& __a = allocator_type()) _GLIBCXX_NOEXCEPT : _Base(_Node_alloc_type(__a)) { } #if __cplusplus >= 201103L @@ -932,7 +927,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * element of the %list. */ reference - front() + front() _GLIBCXX_NOEXCEPT { return *begin(); } /** @@ -940,7 +935,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * element of the %list. */ const_reference - front() const + front() const _GLIBCXX_NOEXCEPT { return *begin(); } /** @@ -948,7 +943,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * of the %list. */ reference - back() + back() _GLIBCXX_NOEXCEPT { iterator __tmp = end(); --__tmp; @@ -960,7 +955,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * element of the %list. */ const_reference - back() const + back() const _GLIBCXX_NOEXCEPT { const_iterator __tmp = end(); --__tmp; @@ -1006,7 +1001,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * called. */ void - pop_front() + pop_front() _GLIBCXX_NOEXCEPT { this->_M_erase(begin()); } /** @@ -1046,7 +1041,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * is needed, it should be retrieved before pop_back() is called. */ void - pop_back() + pop_back() _GLIBCXX_NOEXCEPT { this->_M_erase(iterator(this->_M_impl._M_node._M_prev)); } #if __cplusplus >= 201103L @@ -1231,7 +1226,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ iterator #if __cplusplus >= 201103L - erase(const_iterator __position); + erase(const_iterator __position) noexcept; #else erase(iterator __position); #endif @@ -1256,7 +1251,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ iterator #if __cplusplus >= 201103L - erase(const_iterator __first, const_iterator __last) + erase(const_iterator __first, const_iterator __last) noexcept #else erase(iterator __first, iterator __last) #endif @@ -1314,7 +1309,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ void #if __cplusplus >= 201103L - splice(const_iterator __position, list&& __x) + splice(const_iterator __position, list&& __x) noexcept #else splice(iterator __position, list& __x) #endif @@ -1330,7 +1325,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER #if __cplusplus >= 201103L void - splice(const_iterator __position, list& __x) + splice(const_iterator __position, list& __x) noexcept { splice(__position, std::move(__x)); } #endif @@ -1346,7 +1341,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * inserts it into the current list before @a __position. */ void - splice(const_iterator __position, list&& __x, const_iterator __i) + splice(const_iterator __position, list&& __x, const_iterator __i) noexcept #else /** * @brief Insert element from another %list. @@ -1385,7 +1380,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * inserts it into the current list before @a __position. */ void - splice(const_iterator __position, list& __x, const_iterator __i) + splice(const_iterator __position, list& __x, const_iterator __i) noexcept { splice(__position, std::move(__x), __i); } #endif @@ -1405,7 +1400,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ void splice(const_iterator __position, list&& __x, const_iterator __first, - const_iterator __last) + const_iterator __last) noexcept #else /** * @brief Insert range from another %list. @@ -1451,7 +1446,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ void splice(const_iterator __position, list& __x, const_iterator __first, - const_iterator __last) + const_iterator __last) noexcept { splice(__position, std::move(__x), __first, __last); } #endif @@ -1687,7 +1682,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // Erases element at position given. void - _M_erase(iterator __position) + _M_erase(iterator __position) _GLIBCXX_NOEXCEPT { __position._M_node->_M_unhook(); _Node* __n = static_cast<_Node*>(__position._M_node); @@ -1701,11 +1696,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // To implement the splice (and merge) bits of N1599. void - _M_check_equal_allocators(list& __x) + _M_check_equal_allocators(list& __x) _GLIBCXX_NOEXCEPT { if (std::__alloc_neq<typename _Base::_Node_alloc_type>:: _S_do_it(_M_get_Node_allocator(), __x._M_get_Node_allocator())) - __throw_runtime_error(__N("list::_M_check_equal_allocators")); + __builtin_abort(); } }; diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index 91bf4df4511..5ed3760633e 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -99,28 +99,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Base_ptr _M_right; static _Base_ptr - _S_minimum(_Base_ptr __x) + _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT { while (__x->_M_left != 0) __x = __x->_M_left; return __x; } static _Const_Base_ptr - _S_minimum(_Const_Base_ptr __x) + _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT { while (__x->_M_left != 0) __x = __x->_M_left; return __x; } static _Base_ptr - _S_maximum(_Base_ptr __x) + _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT { while (__x->_M_right != 0) __x = __x->_M_right; return __x; } static _Const_Base_ptr - _S_maximum(_Const_Base_ptr __x) + _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT { while (__x->_M_right != 0) __x = __x->_M_right; return __x; @@ -167,31 +167,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; typedef _Rb_tree_node<_Tp>* _Link_type; - _Rb_tree_iterator() + _Rb_tree_iterator() _GLIBCXX_NOEXCEPT : _M_node() { } explicit - _Rb_tree_iterator(_Link_type __x) + _Rb_tree_iterator(_Link_type __x) _GLIBCXX_NOEXCEPT : _M_node(__x) { } reference - operator*() const + operator*() const _GLIBCXX_NOEXCEPT { return static_cast<_Link_type>(_M_node)->_M_value_field; } pointer - operator->() const + operator->() const _GLIBCXX_NOEXCEPT { return std::__addressof(static_cast<_Link_type> (_M_node)->_M_value_field); } _Self& - operator++() + operator++() _GLIBCXX_NOEXCEPT { _M_node = _Rb_tree_increment(_M_node); return *this; } _Self - operator++(int) + operator++(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _Rb_tree_increment(_M_node); @@ -199,14 +199,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } _Self& - operator--() + operator--() _GLIBCXX_NOEXCEPT { _M_node = _Rb_tree_decrement(_M_node); return *this; } _Self - operator--(int) + operator--(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _Rb_tree_decrement(_M_node); @@ -214,11 +214,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } bool - operator==(const _Self& __x) const + operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node == __x._M_node; } bool - operator!=(const _Self& __x) const + operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node != __x._M_node; } _Base_ptr _M_node; @@ -240,39 +240,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr; typedef const _Rb_tree_node<_Tp>* _Link_type; - _Rb_tree_const_iterator() + _Rb_tree_const_iterator() _GLIBCXX_NOEXCEPT : _M_node() { } explicit - _Rb_tree_const_iterator(_Link_type __x) + _Rb_tree_const_iterator(_Link_type __x) _GLIBCXX_NOEXCEPT : _M_node(__x) { } - _Rb_tree_const_iterator(const iterator& __it) + _Rb_tree_const_iterator(const iterator& __it) _GLIBCXX_NOEXCEPT : _M_node(__it._M_node) { } iterator - _M_const_cast() const + _M_const_cast() const _GLIBCXX_NOEXCEPT { return iterator(static_cast<typename iterator::_Link_type> (const_cast<typename iterator::_Base_ptr>(_M_node))); } reference - operator*() const + operator*() const _GLIBCXX_NOEXCEPT { return static_cast<_Link_type>(_M_node)->_M_value_field; } pointer - operator->() const + operator->() const _GLIBCXX_NOEXCEPT { return std::__addressof(static_cast<_Link_type> (_M_node)->_M_value_field); } _Self& - operator++() + operator++() _GLIBCXX_NOEXCEPT { _M_node = _Rb_tree_increment(_M_node); return *this; } _Self - operator++(int) + operator++(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _Rb_tree_increment(_M_node); @@ -280,14 +280,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } _Self& - operator--() + operator--() _GLIBCXX_NOEXCEPT { _M_node = _Rb_tree_decrement(_M_node); return *this; } _Self - operator--(int) + operator--(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _Rb_tree_decrement(_M_node); @@ -295,11 +295,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } bool - operator==(const _Self& __x) const + operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node == __x._M_node; } bool - operator!=(const _Self& __x) const + operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node != __x._M_node; } _Base_ptr _M_node; @@ -308,13 +308,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Val> inline bool operator==(const _Rb_tree_iterator<_Val>& __x, - const _Rb_tree_const_iterator<_Val>& __y) + const _Rb_tree_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT { return __x._M_node == __y._M_node; } template<typename _Val> inline bool operator!=(const _Rb_tree_iterator<_Val>& __x, - const _Rb_tree_const_iterator<_Val>& __y) + const _Rb_tree_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT { return __x._M_node != __y._M_node; } void @@ -370,7 +370,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _M_impl._Node_allocator::allocate(1); } void - _M_put_node(_Link_type __p) + _M_put_node(_Link_type __p) _GLIBCXX_NOEXCEPT { _M_impl._Node_allocator::deallocate(__p, 1); } #if __cplusplus < 201103L @@ -416,7 +416,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } void - _M_destroy_node(_Link_type __p) + _M_destroy_node(_Link_type __p) noexcept { _M_get_Node_allocator().destroy(__p); _M_put_node(__p); @@ -474,46 +474,46 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION protected: _Base_ptr& - _M_root() + _M_root() _GLIBCXX_NOEXCEPT { return this->_M_impl._M_header._M_parent; } _Const_Base_ptr - _M_root() const + _M_root() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_header._M_parent; } _Base_ptr& - _M_leftmost() + _M_leftmost() _GLIBCXX_NOEXCEPT { return this->_M_impl._M_header._M_left; } _Const_Base_ptr - _M_leftmost() const + _M_leftmost() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_header._M_left; } _Base_ptr& - _M_rightmost() + _M_rightmost() _GLIBCXX_NOEXCEPT { return this->_M_impl._M_header._M_right; } _Const_Base_ptr - _M_rightmost() const + _M_rightmost() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_header._M_right; } _Link_type - _M_begin() + _M_begin() _GLIBCXX_NOEXCEPT { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } _Const_Link_type - _M_begin() const + _M_begin() const _GLIBCXX_NOEXCEPT { return static_cast<_Const_Link_type> (this->_M_impl._M_header._M_parent); } _Link_type - _M_end() + _M_end() _GLIBCXX_NOEXCEPT { return static_cast<_Link_type>(&this->_M_impl._M_header); } _Const_Link_type - _M_end() const + _M_end() const _GLIBCXX_NOEXCEPT { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); } static const_reference @@ -525,19 +525,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _KeyOfValue()(_S_value(__x)); } static _Link_type - _S_left(_Base_ptr __x) + _S_left(_Base_ptr __x) _GLIBCXX_NOEXCEPT { return static_cast<_Link_type>(__x->_M_left); } static _Const_Link_type - _S_left(_Const_Base_ptr __x) + _S_left(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT { return static_cast<_Const_Link_type>(__x->_M_left); } static _Link_type - _S_right(_Base_ptr __x) + _S_right(_Base_ptr __x) _GLIBCXX_NOEXCEPT { return static_cast<_Link_type>(__x->_M_right); } static _Const_Link_type - _S_right(_Const_Base_ptr __x) + _S_right(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT { return static_cast<_Const_Link_type>(__x->_M_right); } static const_reference @@ -549,19 +549,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _KeyOfValue()(_S_value(__x)); } static _Base_ptr - _S_minimum(_Base_ptr __x) + _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT { return _Rb_tree_node_base::_S_minimum(__x); } static _Const_Base_ptr - _S_minimum(_Const_Base_ptr __x) + _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT { return _Rb_tree_node_base::_S_minimum(__x); } static _Base_ptr - _S_maximum(_Base_ptr __x) + _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT { return _Rb_tree_node_base::_S_maximum(__x); } static _Const_Base_ptr - _S_maximum(_Const_Base_ptr __x) + _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT { return _Rb_tree_node_base::_S_maximum(__x); } public: diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 726693918a3..03850b5e28f 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -87,18 +87,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0) { } - _Vector_impl(_Tp_alloc_type const& __a) + _Vector_impl(_Tp_alloc_type const& __a) _GLIBCXX_NOEXCEPT : _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) { } #if __cplusplus >= 201103L - _Vector_impl(_Tp_alloc_type&& __a) + _Vector_impl(_Tp_alloc_type&& __a) noexcept : _Tp_alloc_type(std::move(__a)), _M_start(0), _M_finish(0), _M_end_of_storage(0) { } #endif - void _M_swap_data(_Vector_impl& __x) + void _M_swap_data(_Vector_impl& __x) _GLIBCXX_NOEXCEPT { std::swap(_M_start, __x._M_start); std::swap(_M_finish, __x._M_finish); @@ -124,7 +124,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Vector_base() : _M_impl() { } - _Vector_base(const allocator_type& __a) + _Vector_base(const allocator_type& __a) _GLIBCXX_NOEXCEPT : _M_impl(__a) { } _Vector_base(size_t __n) @@ -136,10 +136,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { _M_create_storage(__n); } #if __cplusplus >= 201103L - _Vector_base(_Tp_alloc_type&& __a) + _Vector_base(_Tp_alloc_type&& __a) noexcept : _M_impl(std::move(__a)) { } - _Vector_base(_Vector_base&& __x) + _Vector_base(_Vector_base&& __x) noexcept : _M_impl(std::move(__x._M_get_Tp_allocator())) { this->_M_impl._M_swap_data(__x._M_impl); } @@ -156,7 +156,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } #endif - ~_Vector_base() + ~_Vector_base() _GLIBCXX_NOEXCEPT { _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); } @@ -243,17 +243,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // [23.2.4.1] construct/copy/destroy // (assign() and get_allocator() are also listed in this section) /** - * @brief Default constructor creates no elements. - */ - vector() - : _Base() { } - - /** * @brief Creates a %vector with no elements. * @param __a An allocator object. */ explicit - vector(const allocator_type& __a) + vector(const allocator_type& __a = allocator_type()) _GLIBCXX_NOEXCEPT : _Base(__a) { } #if __cplusplus >= 201103L @@ -767,7 +761,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * see at().) */ reference - operator[](size_type __n) + operator[](size_type __n) _GLIBCXX_NOEXCEPT { return *(this->_M_impl._M_start + __n); } /** @@ -782,7 +776,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * see at().) */ const_reference - operator[](size_type __n) const + operator[](size_type __n) const _GLIBCXX_NOEXCEPT { return *(this->_M_impl._M_start + __n); } protected: @@ -836,7 +830,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * element of the %vector. */ reference - front() + front() _GLIBCXX_NOEXCEPT { return *begin(); } /** @@ -844,7 +838,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * element of the %vector. */ const_reference - front() const + front() const _GLIBCXX_NOEXCEPT { return *begin(); } /** @@ -852,7 +846,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * element of the %vector. */ reference - back() + back() _GLIBCXX_NOEXCEPT { return *(end() - 1); } /** @@ -860,7 +854,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * last element of the %vector. */ const_reference - back() const + back() const _GLIBCXX_NOEXCEPT { return *(end() - 1); } // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -934,7 +928,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * called. */ void - pop_back() + pop_back() _GLIBCXX_NOEXCEPT { --this->_M_impl._M_finish; _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); @@ -1415,7 +1409,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // Called by erase(q1,q2), clear(), resize(), _M_fill_assign, // _M_assign_aux. void - _M_erase_at_end(pointer __pos) + _M_erase_at_end(pointer __pos) _GLIBCXX_NOEXCEPT { std::_Destroy(__pos, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish = __pos; diff --git a/libstdc++-v3/include/debug/array b/libstdc++-v3/include/debug/array index bce10cf3f12..d3eea853856 100644 --- a/libstdc++-v3/include/debug/array +++ b/libstdc++-v3/include/debug/array @@ -147,7 +147,7 @@ namespace __debug // Element access. reference - operator[](size_type __n) + operator[](size_type __n) noexcept { __glibcxx_check_subscript(__n); return _AT_Type::_S_ref(_M_elems, __n); @@ -180,14 +180,14 @@ namespace __debug } reference - front() + front() noexcept { __glibcxx_check_nonempty(); return *begin(); } constexpr const_reference - front() const + front() const noexcept { return _Nm ? _AT_Type::_S_ref(_M_elems, 0) : (_GLIBCXX_THROW_OR_ABORT(_Array_check_nonempty<_Nm>()), @@ -195,14 +195,14 @@ namespace __debug } reference - back() + back() noexcept { __glibcxx_check_nonempty(); return _Nm ? *(end() - 1) : *end(); } constexpr const_reference - back() const + back() const noexcept { return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1) : (_GLIBCXX_THROW_OR_ABORT(_Array_check_nonempty<_Nm>()), diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list index fd00b0148a9..89c26e425ae 100644 --- a/libstdc++-v3/include/debug/list +++ b/libstdc++-v3/include/debug/list @@ -70,7 +70,7 @@ namespace __debug // 23.2.2.1 construct/copy/destroy: explicit - list(const _Allocator& __a = _Allocator()) + list(const _Allocator& __a = _Allocator()) _GLIBCXX_NOEXCEPT : _Base(__a) { } #if __cplusplus >= 201103L @@ -320,28 +320,28 @@ namespace __debug // element access: reference - front() + front() _GLIBCXX_NOEXCEPT { __glibcxx_check_nonempty(); return _Base::front(); } const_reference - front() const + front() const _GLIBCXX_NOEXCEPT { __glibcxx_check_nonempty(); return _Base::front(); } reference - back() + back() _GLIBCXX_NOEXCEPT { __glibcxx_check_nonempty(); return _Base::back(); } const_reference - back() const + back() const _GLIBCXX_NOEXCEPT { __glibcxx_check_nonempty(); return _Base::back(); @@ -355,7 +355,7 @@ namespace __debug #endif void - pop_front() + pop_front() _GLIBCXX_NOEXCEPT { __glibcxx_check_nonempty(); this->_M_invalidate_if(_Equal(_Base::begin())); @@ -369,7 +369,7 @@ namespace __debug #endif void - pop_back() + pop_back() _GLIBCXX_NOEXCEPT { __glibcxx_check_nonempty(); this->_M_invalidate_if(_Equal(--_Base::end())); @@ -455,7 +455,7 @@ namespace __debug private: _Base_iterator #if __cplusplus >= 201103L - _M_erase(_Base_const_iterator __position) + _M_erase(_Base_const_iterator __position) noexcept #else _M_erase(_Base_iterator __position) #endif @@ -467,7 +467,7 @@ namespace __debug public: iterator #if __cplusplus >= 201103L - erase(const_iterator __position) + erase(const_iterator __position) noexcept #else erase(iterator __position) #endif @@ -478,7 +478,7 @@ namespace __debug iterator #if __cplusplus >= 201103L - erase(const_iterator __first, const_iterator __last) + erase(const_iterator __first, const_iterator __last) noexcept #else erase(iterator __first, iterator __last) #endif @@ -515,7 +515,7 @@ namespace __debug // 23.2.2.4 list operations: void #if __cplusplus >= 201103L - splice(const_iterator __position, list&& __x) + splice(const_iterator __position, list&& __x) noexcept #else splice(iterator __position, list& __x) #endif @@ -529,13 +529,13 @@ namespace __debug #if __cplusplus >= 201103L void - splice(const_iterator __position, list& __x) + splice(const_iterator __position, list& __x) noexcept { splice(__position, std::move(__x)); } #endif void #if __cplusplus >= 201103L - splice(const_iterator __position, list&& __x, const_iterator __i) + splice(const_iterator __position, list&& __x, const_iterator __i) noexcept #else splice(iterator __position, list& __x, iterator __i) #endif @@ -561,14 +561,14 @@ namespace __debug #if __cplusplus >= 201103L void - splice(const_iterator __position, list& __x, const_iterator __i) + splice(const_iterator __position, list& __x, const_iterator __i) noexcept { splice(__position, std::move(__x), __i); } #endif void #if __cplusplus >= 201103L splice(const_iterator __position, list&& __x, const_iterator __first, - const_iterator __last) + const_iterator __last) noexcept #else splice(iterator __position, list& __x, iterator __first, iterator __last) @@ -608,7 +608,7 @@ namespace __debug #if __cplusplus >= 201103L void splice(const_iterator __position, list& __x, - const_iterator __first, const_iterator __last) + const_iterator __first, const_iterator __last) noexcept { splice(__position, std::move(__x), __first, __last); } #endif diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string index 9e856c1ee8c..925575e662a 100644 --- a/libstdc++-v3/include/debug/string +++ b/libstdc++-v3/include/debug/string @@ -70,6 +70,7 @@ namespace __gnu_debug // 21.3.1 construct/copy/destroy: explicit basic_string(const _Allocator& __a = _Allocator()) + _GLIBCXX_NOEXCEPT : _Base(__a) { } @@ -238,7 +239,7 @@ namespace __gnu_debug #if __cplusplus >= 201103L void - shrink_to_fit() + shrink_to_fit() noexcept { if (capacity() > size()) { @@ -267,7 +268,7 @@ namespace __gnu_debug // 21.3.4 element access: const_reference - operator[](size_type __pos) const + operator[](size_type __pos) const _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), _M_message(__gnu_debug::__msg_subscript_oob) @@ -278,7 +279,7 @@ namespace __gnu_debug } reference - operator[](size_type __pos) + operator[](size_type __pos) _GLIBCXX_NOEXCEPT { #ifdef _GLIBCXX_DEBUG_PEDANTIC __glibcxx_check_subscript(__pos); @@ -582,7 +583,7 @@ namespace __gnu_debug #if __cplusplus >= 201103L void - pop_back() + pop_back() noexcept { __glibcxx_check_nonempty(); _Base::pop_back(); diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector index 7b28177c2a0..e5b80649b9a 100644 --- a/libstdc++-v3/include/debug/vector +++ b/libstdc++-v3/include/debug/vector @@ -76,7 +76,7 @@ namespace __debug // 23.2.4.1 construct/copy/destroy: explicit - vector(const _Allocator& __a = _Allocator()) + vector(const _Allocator& __a = _Allocator()) _GLIBCXX_NOEXCEPT : _Base(__a), _M_guaranteed_capacity(0) { } #if __cplusplus >= 201103L @@ -341,14 +341,14 @@ namespace __debug // element access: reference - operator[](size_type __n) + operator[](size_type __n) _GLIBCXX_NOEXCEPT { __glibcxx_check_subscript(__n); return _M_base()[__n]; } const_reference - operator[](size_type __n) const + operator[](size_type __n) const _GLIBCXX_NOEXCEPT { __glibcxx_check_subscript(__n); return _M_base()[__n]; @@ -357,28 +357,28 @@ namespace __debug using _Base::at; reference - front() + front() _GLIBCXX_NOEXCEPT { __glibcxx_check_nonempty(); return _Base::front(); } const_reference - front() const + front() const _GLIBCXX_NOEXCEPT { __glibcxx_check_nonempty(); return _Base::front(); } reference - back() + back() _GLIBCXX_NOEXCEPT { __glibcxx_check_nonempty(); return _Base::back(); } const_reference - back() const + back() const _GLIBCXX_NOEXCEPT { __glibcxx_check_nonempty(); return _Base::back(); @@ -419,7 +419,7 @@ namespace __debug #endif void - pop_back() + pop_back() _GLIBCXX_NOEXCEPT { __glibcxx_check_nonempty(); this->_M_invalidate_if(_Equal(--_Base::end())); @@ -630,18 +630,18 @@ namespace __debug size_type _M_guaranteed_capacity; bool - _M_requires_reallocation(size_type __elements) + _M_requires_reallocation(size_type __elements) _GLIBCXX_NOEXCEPT { return __elements > this->capacity(); } void - _M_update_guaranteed_capacity() + _M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT { if (this->size() > _M_guaranteed_capacity) _M_guaranteed_capacity = this->size(); } void - _M_invalidate_after_nth(difference_type __n) + _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT { typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth; this->_M_invalidate_if(_After_nth(__n, _Base::begin())); diff --git a/libstdc++-v3/include/ext/vstring.h b/libstdc++-v3/include/ext/vstring.h index 85322130cf9..bd93c803c23 100644 --- a/libstdc++-v3/include/ext/vstring.h +++ b/libstdc++-v3/include/ext/vstring.h @@ -98,7 +98,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // NB: _M_limit doesn't check for a bad __pos value. size_type - _M_limit(size_type __pos, size_type __off) const + _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT { const bool __testoff = __off < this->size() - __pos; return __testoff ? __off : this->size() - __pos; @@ -106,7 +106,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // True if _Rep and source do not overlap. bool - _M_disjunct(const _CharT* __s) const + _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPT { return (std::less<const _CharT*>()(__s, this->_M_data()) || std::less<const _CharT*>()(this->_M_data() @@ -116,11 +116,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // For the internal use we have functions similar to `begin'/`end' // but they do not call _M_leak. iterator - _M_ibegin() const + _M_ibegin() const _GLIBCXX_NOEXCEPT { return iterator(this->_M_data()); } iterator - _M_iend() const + _M_iend() const _GLIBCXX_NOEXCEPT { return iterator(this->_M_data() + this->_M_length()); } public: @@ -129,16 +129,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // arguments, per 17.4.4.4 para. 2 item 2. /** - * @brief Default constructor creates an empty string. - */ - __versa_string() - : __vstring_base() { } - - /** * @brief Construct an empty string using allocator @a a. */ explicit - __versa_string(const _Alloc& __a) + __versa_string(const _Alloc& __a = _Alloc()) _GLIBCXX_NOEXCEPT : __vstring_base(__a) { } // NB: per LWG issue 42, semantics different from IS: @@ -269,7 +263,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * copying). @a __str is a valid, but unspecified string. */ __versa_string& - operator=(__versa_string&& __str) + operator=(__versa_string&& __str) noexcept { // NB: DR 1204. this->swap(__str); @@ -470,7 +464,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L /// A non-binding request to reduce capacity() to size(). void - shrink_to_fit() + shrink_to_fit() noexcept { if (capacity() > size()) { @@ -538,7 +532,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * see at().) */ const_reference - operator[] (size_type __pos) const + operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT { _GLIBCXX_DEBUG_ASSERT(__pos <= this->size()); return this->_M_data()[__pos]; @@ -555,7 +549,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * see at().) Unshares the string. */ reference - operator[](size_type __pos) + operator[](size_type __pos) _GLIBCXX_NOEXCEPT { // Allow pos == size() both in C++98 mode, as v3 extension, // and in C++11 mode. @@ -611,7 +605,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * element of the %string. */ reference - front() + front() _GLIBCXX_NOEXCEPT { return operator[](0); } /** @@ -619,7 +613,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * element of the %string. */ const_reference - front() const + front() const _GLIBCXX_NOEXCEPT { return operator[](0); } /** @@ -627,7 +621,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * element of the %string. */ reference - back() + back() _GLIBCXX_NOEXCEPT { return operator[](this->size() - 1); } /** @@ -635,7 +629,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * last element of the %string. */ const_reference - back() const + back() const _GLIBCXX_NOEXCEPT { return operator[](this->size() - 1); } #endif @@ -814,7 +808,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @a __str is a valid, but unspecified string. */ __versa_string& - assign(__versa_string&& __str) + assign(__versa_string&& __str) noexcept { this->swap(__str); return *this; @@ -1631,7 +1625,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * constant time. */ void - swap(__versa_string& __s) + swap(__versa_string& __s) _GLIBCXX_NOEXCEPT { this->_M_swap(__s); } // String operations: diff --git a/libstdc++-v3/include/profile/array b/libstdc++-v3/include/profile/array index bd6da6ca396..33bdc952096 100644 --- a/libstdc++-v3/include/profile/array +++ b/libstdc++-v3/include/profile/array @@ -127,7 +127,7 @@ namespace __profile // Element access. reference - operator[](size_type __n) + operator[](size_type __n) noexcept { return _AT_Type::_S_ref(_M_elems, __n); } constexpr const_reference @@ -153,19 +153,19 @@ namespace __profile } reference - front() + front() noexcept { return *begin(); } constexpr const_reference - front() const + front() const noexcept { return _AT_Type::_S_ref(_M_elems, 0); } reference - back() + back() noexcept { return _Nm ? *(end() - 1) : *end(); } constexpr const_reference - back() const + back() const noexcept { return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1) : _AT_Type::_S_ref(_M_elems, 0); diff --git a/libstdc++-v3/include/profile/list b/libstdc++-v3/include/profile/list index ac09aa3db26..6168c61ed18 100644 --- a/libstdc++-v3/include/profile/list +++ b/libstdc++-v3/include/profile/list @@ -65,7 +65,7 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> > // 23.2.2.1 construct/copy/destroy: explicit - list(const _Allocator& __a = _Allocator()) + list(const _Allocator& __a = _Allocator()) _GLIBCXX_NOEXCEPT : _Base(__a) { __profcxx_list_construct(this); // list2slist @@ -276,22 +276,22 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> > // element access: reference - front() + front() _GLIBCXX_NOEXCEPT { return _Base::front(); } const_reference - front() const + front() const _GLIBCXX_NOEXCEPT { return _Base::front(); } reference - back() + back() _GLIBCXX_NOEXCEPT { __profcxx_list_rewind(this); return _Base::back(); } const_reference - back() const + back() const _GLIBCXX_NOEXCEPT { __profcxx_list_rewind(this); return _Base::back(); @@ -311,7 +311,7 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> > #endif void - pop_front() + pop_front() _GLIBCXX_NOEXCEPT { __profcxx_list_operation(this); _Base::pop_front(); @@ -324,7 +324,7 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> > #endif void - pop_back() + pop_back() _GLIBCXX_NOEXCEPT { iterator __victim = end(); --__victim; @@ -411,7 +411,7 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> > iterator #if __cplusplus >= 201103L - erase(const_iterator __position) + erase(const_iterator __position) noexcept #else erase(iterator __position) #endif @@ -419,7 +419,7 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> > iterator #if __cplusplus >= 201103L - erase(const_iterator __position, const_iterator __last) + erase(const_iterator __position, const_iterator __last) noexcept #else erase(iterator __position, iterator __last) #endif @@ -440,7 +440,7 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> > // 23.2.2.4 list operations: void #if __cplusplus >= 201103L - splice(const_iterator __position, list&& __x) + splice(const_iterator __position, list&& __x) noexcept #else splice(iterator __position, list& __x) #endif @@ -448,7 +448,7 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> > #if __cplusplus >= 201103L void - splice(const_iterator __position, list& __x) + splice(const_iterator __position, list& __x) noexcept { this->splice(__position, std::move(__x)); } void @@ -458,7 +458,7 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> > void #if __cplusplus >= 201103L - splice(const_iterator __position, list&& __x, const_iterator __i) + splice(const_iterator __position, list&& __x, const_iterator __i) noexcept #else splice(iterator __position, list& __x, iterator __i) #endif @@ -474,7 +474,7 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> > void #if __cplusplus >= 201103L splice(const_iterator __position, list&& __x, const_iterator __first, - const_iterator __last) + const_iterator __last) noexcept #else splice(iterator __position, list& __x, iterator __first, iterator __last) @@ -490,7 +490,7 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> > #if __cplusplus >= 201103L void splice(const_iterator __position, list& __x, - const_iterator __first, const_iterator __last) + const_iterator __first, const_iterator __last) noexcept { this->splice(__position, std::move(__x), __first, __last); } #endif diff --git a/libstdc++-v3/include/profile/vector b/libstdc++-v3/include/profile/vector index 3ef04ff0a7c..8f79df7f07c 100644 --- a/libstdc++-v3/include/profile/vector +++ b/libstdc++-v3/include/profile/vector @@ -78,7 +78,7 @@ namespace __profile // 23.2.4.1 construct/copy/destroy: explicit - vector(const _Allocator& __a = _Allocator()) + vector(const _Allocator& __a = _Allocator()) _GLIBCXX_NOEXCEPT : _Base(__a) { __profcxx_vector_construct(this, this->capacity()); @@ -156,7 +156,7 @@ namespace __profile __profcxx_vector_construct2(this); } - vector(vector&& __x, const _Allocator& __a) noexcept + vector(vector&& __x, const _Allocator& __a) : _Base(std::move(__x), __a) { __profcxx_vector_construct(this, this->capacity()); @@ -292,13 +292,13 @@ namespace __profile // element access: reference - operator[](size_type __n) + operator[](size_type __n) _GLIBCXX_NOEXCEPT { __profcxx_vector_invalid_operator(this); return _M_base()[__n]; } const_reference - operator[](size_type __n) const + operator[](size_type __n) const _GLIBCXX_NOEXCEPT { __profcxx_vector_invalid_operator(this); return _M_base()[__n]; @@ -307,25 +307,25 @@ namespace __profile using _Base::at; reference - front() + front() _GLIBCXX_NOEXCEPT { return _Base::front(); } const_reference - front() const + front() const _GLIBCXX_NOEXCEPT { return _Base::front(); } reference - back() + back() _GLIBCXX_NOEXCEPT { return _Base::back(); } const_reference - back() const + back() const _GLIBCXX_NOEXCEPT { return _Base::back(); } diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index 0d2a71c8cbc..86e8aee14ba 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -169,7 +169,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // Element access. reference - operator[](size_type __n) + operator[](size_type __n) noexcept { return _AT_Type::_S_ref(_M_elems, __n); } constexpr const_reference @@ -195,19 +195,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } reference - front() + front() noexcept { return *begin(); } constexpr const_reference - front() const + front() const noexcept { return _AT_Type::_S_ref(_M_elems, 0); } reference - back() + back() noexcept { return _Nm ? *(end() - 1) : *end(); } constexpr const_reference - back() const + back() const noexcept { return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1) : _AT_Type::_S_ref(_M_elems, 0); diff --git a/libstdc++-v3/testsuite/23_containers/list/operations/5.cc b/libstdc++-v3/testsuite/23_containers/list/operations/5.cc deleted file mode 100644 index fbb55b3ea3c..00000000000 --- a/libstdc++-v3/testsuite/23_containers/list/operations/5.cc +++ /dev/null @@ -1,31 +0,0 @@ -// 2006-01-19 Paolo Carlini <pcarlini@suse.de> - -// Copyright (C) 2006-2013 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 "5.h" -#include <list> - -int main() -{ - typedef int value_type; - typedef __gnu_test::uneq_allocator<value_type> allocator_type; - typedef std::list<value_type, allocator_type> list_type; - - operations05<list_type>(); - return 0; -} diff --git a/libstdc++-v3/testsuite/23_containers/list/operations/5.h b/libstdc++-v3/testsuite/23_containers/list/operations/5.h deleted file mode 100644 index 755ddd9eb1d..00000000000 --- a/libstdc++-v3/testsuite/23_containers/list/operations/5.h +++ /dev/null @@ -1,134 +0,0 @@ -// 2006-01-19 Paolo Carlini <pcarlini@suse.de> - -// Copyright (C) 2006-2013 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/>. - -// 23.2.2.4 list operations [lib.list.ops] - -#include <stdexcept> -#include <testsuite_hooks.h> -#include <testsuite_allocator.h> - -// Check the splice (and merge) bits of N1599. -template<typename _Tp> -void -operations05() -{ - bool test __attribute__((unused)) = true; - - typedef _Tp list_type; - typedef typename list_type::allocator_type allocator_type; - - const int data1[] = {1, 2, 3, 4, 5}; - const int data2[] = {6, 7, 8, 9, 10}; - const size_t N1 = sizeof(data1) / sizeof(int); - const size_t N2 = sizeof(data2) / sizeof(int); - - allocator_type alloc01(1), alloc02(2); - - list_type l01(data1, data1 + N1, alloc01); - const list_type l01_ref = l01; - - list_type l02(data2, data2 + N2, alloc02); - const list_type l02_ref = l02; - - bool catched = false; - - try - { - l01.splice(l01.begin(), l02); - } - catch(std::runtime_error&) - { - catched = true; - } - catch(...) - { - VERIFY( false ); - } - VERIFY( catched ); - VERIFY( l01 == l01_ref ); - VERIFY( l02 == l02_ref ); - - catched = false; - try - { - l01.splice(l01.begin(), l02, l02.begin()); - } - catch(std::runtime_error&) - { - catched = true; - } - catch(...) - { - VERIFY( false ); - } - VERIFY( catched ); - VERIFY( l01 == l01_ref ); - VERIFY( l02 == l02_ref ); - - catched = false; - try - { - l01.splice(l01.begin(), l02, l02.begin(), l02.end()); - } - catch(std::runtime_error&) - { - catched = true; - } - catch(...) - { - VERIFY( false ); - } - VERIFY( catched ); - VERIFY( l01 == l01_ref ); - VERIFY( l02 == l02_ref ); - - catched = false; - try - { - l01.merge(l02); - } - catch(std::runtime_error&) - { - catched = true; - } - catch(...) - { - VERIFY( false ); - } - VERIFY( catched ); - VERIFY( l01 == l01_ref ); - VERIFY( l02 == l02_ref ); - - catched = false; - try - { - l01.merge(l02, std::less<int>()); - } - catch(std::runtime_error&) - { - catched = true; - } - catch(...) - { - VERIFY( false ); - } - VERIFY( catched ); - VERIFY( l01 == l01_ref ); - VERIFY( l02 == l02_ref ); -} diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc index 80cf1033d27..dd315f67a31 100644 --- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1651 } +// { dg-error "no matching" "" { target *-*-* } 1646 } #include <list> diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc index 333849252b1..9454c741a68 100644 --- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1603 } +// { dg-error "no matching" "" { target *-*-* } 1598 } #include <list> diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc index fdf4fe9387f..9723db98a48 100644 --- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1603 } +// { dg-error "no matching" "" { target *-*-* } 1598 } #include <list> #include <utility> diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc index 3c33584e8de..fdc2f11d6e2 100644 --- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1603 } +// { dg-error "no matching" "" { target *-*-* } 1598 } #include <list> diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc index f7353ab325c..388e57182cc 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1308 } +// { dg-error "no matching" "" { target *-*-* } 1302 } #include <vector> diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc index f404a7009da..68cfab064f8 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1234 } +// { dg-error "no matching" "" { target *-*-* } 1228 } #include <vector> diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc index 070295676a5..35c03286a26 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1234 } +// { dg-error "no matching" "" { target *-*-* } 1228 } #include <vector> #include <utility> diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc index 95af05795ce..6ab70388b83 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1349 } +// { dg-error "no matching" "" { target *-*-* } 1343 } #include <vector> diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc index 82e99058743..3064b3b26e4 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc @@ -1,5 +1,4 @@ // { dg-options "-std=gnu++11" } -// { dg-do run { xfail *-*-* } } // // 2013-09-14 Tim Shen <timshen91@gmail.com> @@ -54,22 +53,37 @@ test01() string sol[] = { "This", + "", "is", + "", "a", + "", "regular", + "", "expression", + "", }; regex re("\\b\\w*\\b"); int i = 0; for (auto it = sregex_iterator(s.begin(), s.end(), re); - it != sregex_iterator() && i < 5; + it != sregex_iterator(); ++it) { string s((*it)[0].first, (*it)[0].second); VERIFY(s == sol[i++]); } - VERIFY(i == 5); + VERIFY(i == 10); + + { + cmatch m; + regex re("(?=(as)df)as(df)"); + regex_search("asdf", m, re); + VERIFY(m.size() == 3); + VERIFY(m[0].matched && string(m[0].first, m[0].second) == "asdf"); + VERIFY(m[1].matched && string(m[1].first, m[1].second) == "as"); + VERIFY(m[2].matched && string(m[2].first, m[2].second) == "df"); + } } int diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/flags.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/flags.cc new file mode 100644 index 00000000000..4be406cb072 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/flags.cc @@ -0,0 +1,71 @@ +// { dg-options "-std=gnu++11" } + +// +// 2013-09-18 Tim Shen <timshen91@gmail.com> +// +// Copyright (C) 2013 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/>. + +// 28.11.3 regex_search +// Tests ECMAScript flags. + +#include <regex> +#include <testsuite_hooks.h> + +using namespace std; + +void +test01() +{ + bool test __attribute__((unused)) = true; + + cmatch m; + regex re("((as)(df))", regex_constants::ECMAScript | regex_constants::nosubs); + VERIFY(regex_search("asdf", m, re)); + VERIFY(m.size() == 1); + VERIFY(m[0].matched && string(m[0].first, m[0].second) == "asdf"); + + VERIFY( regex_search("a", regex("^a"))); + VERIFY(!regex_search("a", regex("^a"), regex_constants::match_not_bol)); + VERIFY( regex_search("a", regex("a$"))); + VERIFY(!regex_search("a", regex("a$"), regex_constants::match_not_eol)); + VERIFY( regex_search("a", regex("\\ba"))); + VERIFY(!regex_search("a", regex("\\ba"), regex_constants::match_not_bow)); + VERIFY( regex_search("a", regex("a\\b"))); + VERIFY(!regex_search("a", regex("a\\b"), regex_constants::match_not_eow)); + VERIFY( regex_search("", regex(""))); + VERIFY(!regex_search("", regex(""), regex_constants::match_not_null)); + VERIFY( regex_search("", regex("^$"))); + VERIFY(!regex_search("", regex("^$"), regex_constants::match_not_null)); + VERIFY( regex_search("aaa", m, regex("a*?"), + regex_constants::match_not_null)); + VERIFY(m[0].matched && string(m[0].first, m[0].second) == "a"); + VERIFY( regex_search("asdf", regex("sdf"))); + VERIFY(!regex_search("asdf", regex("sdf"), + regex_constants::match_continuous)); + VERIFY( regex_search(" a"+1, regex("\\ba"), + regex_constants::match_prev_avail)); + VERIFY( regex_search("ba"+1, regex("\\Ba"), + regex_constants::match_prev_avail)); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_position_01.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_position_01.cc index 75ef0584b8a..978565021cc 100644 --- a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_position_01.cc +++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/char/string_position_01.cc @@ -1,5 +1,4 @@ // { dg-options "-std=gnu++11" } -// { dg-do run { xfail *-*-* } } // // 2013-07-25 Tim Shen <timshen91@gmail.com> diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc index cd2c68e33ee..9cb96f7a162 100644 --- a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc +++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc @@ -1,6 +1,5 @@ // { dg-options "-std=gnu++11" } // { dg-require-namedlocale "en_US.UTF-8" } -// { dg-do run { xfail *-*-* } } // // 2013-09-05 Tim Shen <timshen91@gmail.com> @@ -42,13 +41,19 @@ test01() re2.assign(L"([[:lower:]]{0,1}[[:space:]]{0,1}[[:upper:]]{0,1})"); - std::wsregex_iterator p(str2.begin(), str2.end(), re2); - auto a = p; - ++p; - VERIFY(a != p); - //for (std::wsregex_iterator p(str2.begin(), str2.end(), re2); - // p != std::wsregex_iterator{}; ++p) - // std::wcout << (*p)[1] << std::endl; + std::wstring sol[] = + { + L"ä\u2009Ä", + L"\u2009", + L"ö\u2009Ö", + L"\u2009", + L"ü\u2009Ü", + L"", + }; + int i = 0; + for (std::wsregex_iterator p(str2.begin(), str2.end(), re2); + p != std::wsregex_iterator{}; ++p) + VERIFY(std::wstring((*p)[1].first, (*p)[1].second) == sol[i++]); } int diff --git a/libstdc++-v3/testsuite/performance/25_algorithms/search_n.cc b/libstdc++-v3/testsuite/performance/25_algorithms/search_n.cc index 183045b618c..79d0eea9417 100644 --- a/libstdc++-v3/testsuite/performance/25_algorithms/search_n.cc +++ b/libstdc++-v3/testsuite/performance/25_algorithms/search_n.cc @@ -57,7 +57,7 @@ main(void) for(int i = 0; i < 100; i++) search_n(rcon.begin(), rcon.end(), 10, 1); stop_counters(time, resource); - report_performance(__FILE__, "random acess iterator", time, resource); + report_performance(__FILE__, "random access iterator", time, resource); clear_counters(time, resource); } |