diff options
801 files changed, 34554 insertions, 10748 deletions
diff --git a/ChangeLog b/ChangeLog index 1c74171eb2e..24cc78cc661 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * libtool.m4 (_LT_ENABLE_LOCK <ld -m flags>): Remove non-canonical + ppc host match. Support little-endian powerpc linux hosts. + +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 + maintainers. + 2013-09-03 Richard Biener <rguenther@suse.de> * configure.ac: Also allow ISL 0.12. diff --git a/MAINTAINERS b/MAINTAINERS index cc89c2ce01d..4a369d7f5bb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -87,6 +87,8 @@ mmix port Hans-Peter Nilsson hp@bitrange.com mn10300 port Jeff Law law@redhat.com mn10300 port Alexandre Oliva aoliva@redhat.com moxie port Anthony Green green@moxielogic.com +msp430 port DJ Delorie dj@redhat.com +msp430 port Nick Clifton nickc@redhat.com nds32 port Chung-Ju Wu jasonwucj@gmail.com nds32 port Shiva Chen shiva0217@gmail.com pdp11 port Paul Koning ni1d@arrl.net @@ -178,7 +180,7 @@ libobjc Nicola Pero nicola.pero@meta-innovation.com libobjc Andrew Pinski pinskia@gmail.com libquadmath Tobias Burnus burnus@net-b.de libquadmath Jakub Jelinek jakub@redhat.com -libvtv Caroline Tice cmtice@google.com +libvtv Caroline Tice cmtice@google.com loop discovery Michael Hayes m.hayes@elec.canterbury.ac.nz soft-fp Joseph Myers joseph@codesourcery.com scheduler (+ haifa) Jim Wilson wilson@tuliptree.org @@ -193,7 +195,6 @@ debugging code Jim Wilson wilson@tuliptree.org dwarf debugging code Jason Merrill jason@redhat.com dwarf debugging code Cary Coutant ccoutant@google.com c++ runtime libs Paolo Carlini paolo.carlini@oracle.com -c++ runtime libs Gabriel Dos Reis gdr@integrable-solutions.net c++ runtime libs Ulrich Drepper drepper@gmail.com c++ runtime libs Benjamin De Kosnik bkoz@gnu.org c++ runtime libs Loren J. Rittle ljrittle@acm.org @@ -212,7 +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 Gabriel Dos Reis gdr@integrable-solutions.net +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/boehm-gc/ChangeLog b/boehm-gc/ChangeLog index 0cd4dbec4d5..cb097bcce68 100644 --- a/boehm-gc/ChangeLog +++ b/boehm-gc/ChangeLog @@ -1,4 +1,8 @@ -2013-09-04 Matthias Klose <doko@ubuntu.com> +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + +2013-09-04 Matthias Klose <doko@ubuntu.com> * Makefile.am (libgcjgc_la_LIBADD): Add EXTRA_TEST_LIBS. * Makefile.in: Regenerate. diff --git a/boehm-gc/configure b/boehm-gc/configure index 6020e9884eb..025003cac13 100755 --- a/boehm-gc/configure +++ b/boehm-gc/configure @@ -6770,7 +6770,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -6795,7 +6795,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -6814,7 +6817,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -11312,7 +11318,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11315 "configure" +#line 11321 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11418,7 +11424,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11421 "configure" +#line 11427 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/contrib/ChangeLog b/contrib/ChangeLog index d99dc3417bb..931bb87bc24 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,3 +1,7 @@ +2013-09-12 DJ Delorie <dj@redhat.com> + + * config-list.mk: Add msp430-elf. + 2013-08-31 Diego Novillo <dnovillo@google.com> * testsuite-management/x86_64-unknown-linux-gnu.xfail: Update. diff --git a/contrib/config-list.mk b/contrib/config-list.mk index 9a141c26be5..85ca6ad13e0 100644 --- a/contrib/config-list.mk +++ b/contrib/config-list.mk @@ -44,6 +44,7 @@ LIST = aarch64-elf aarch64-linux-gnu \ mipsel-elf mips64-elf mips64vr-elf mips64orion-elf mips-rtems \ mips-wrs-vxworks mipstx39-elf mmix-knuth-mmixware mn10300-elf moxie-elf \ moxie-uclinux moxie-rtems pdp11-aout picochip-elfOPT-enable-obsolete \ + msp430-elf \ powerpc-darwin8 \ powerpc-darwin7 powerpc64-darwin powerpc-freebsd6 powerpc-netbsd \ powerpc-eabispe powerpc-eabisimaltivec powerpc-eabisim ppc-elf \ diff --git a/fixincludes/ChangeLog b/fixincludes/ChangeLog index 4a9d22997ff..d6424db2364 100644 --- a/fixincludes/ChangeLog +++ b/fixincludes/ChangeLog @@ -1,3 +1,7 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2013-09-02 David Edelsohn <dje.gcc@gmail.com> * inclhack.def (aix_assert): New fix. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index abf8182b09d..d4f56a4773b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,2853 @@ +2013-09-20 Martin Husemann <martin@NetBSD.org> + + PR target/56875 + * config/vax/vax.c (vax_output_int_move): Use D format specifier. + * config/vax/vax.md (ashldi3, <unnamed>): Ditto. + +2013-09-20 Richard Biener <rguenther@suse.de> + + PR middle-end/58484 + * tree-scalar-evolution.c (struct scev_info_str): Shrink by + remembering SSA name version and block index. + (new_scev_info_str): Adjust. + (hash_scev_info): Likewise. Also hash the block index. + (eq_scev_info): Adjust. + (find_var_scev_info): Likewise. + (struct instantiate_cache_entry): Remove. + (struct instantiate_cache_type): Use a htab to map name, block + to chrec. + (instantiate_cache_type::~instantiate_cache_type): Adjust. + (get_instantiated_value_entry): Likewise. + (hash_idx_scev_info, eq_idx_scev_info): New functions. + (instantiate_scev_name): Adjust. + +2013-09-20 Jeff Law <law@redhat.com> + + * tree-ssa-dom.c (record_temporary_equivalences): Add comment. + +2013-09-20 Yufeng Zhang <yufeng.zhang@arm.com> + + * config/aarch64/aarch64-builtins.c (aarch64_simd_expand_args): + Call aarch64_simd_expand_args to update op[argc]. + +2013-09-20 Basile Starynkevitch <basile@starynkevitch.net> + + * plugin.c (parse_plugin_arg_opt): Accept equal sign inside + plugin argument. + +2013-09-20 Basile Starynkevitch <basile@starynkevitch.net> + + * gengtype.c (file_rules): Added rule for *.cc files. + (get_output_file_with_visibility): Give fatal message when no + rules found. + +2013-09-20 Renlin Li <renlin.li@arm.com> + + * config/aarch64/aarch64.c (aarch64_expand_prologue): Use plus_constant. + (aarch64_expand_epilogue): Likewise. + (aarch64_legitimize_reload_address): Likewise. + +2013-09-20 Bernd Edlinger <bernd.edlinger@hotmail.de> + + PR middle-end/57748 + * expr.c (expand_assignment): Remove misalignp code path. + +2013-09-20 Marek Polacek <polacek@redhat.com> + + PR sanitizer/58413 + * ubsan.c (get_ubsan_type_info_for_type): Use TYPE_SIZE instead of + TYPE_PRECISION. Add asserts. + +2013-09-20 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58453 + * tree-loop-distribution.c (distribute_loop): Apply the cost + model for -ftree-loop-distribute-patterns, too. + +2013-09-20 Richard Biener <rguenther@suse.de> + + PR middle-end/58473 + * tree-chrec.h (build_polynomial_chrec): Use gcc_checking_assert, + make type comparison less strict. + +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + * aclocal.m4: Regenerate. + +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. + (dot_rdg_1): Handle control_dd. + (create_edge_for_control_dependence): New function. + (create_rdg_edges): Add control dependences if asked for. + (build_rdg): Likewise. + (generate_loops_for_partition): If there are not necessary + control stmts remove all their dependencies. + (collect_condition_stmts, rdg_flag_loop_exits): Remove. + (distribute_loop): Pass on control dependences. + (tree_loop_distribution): Compute control dependences and remove + restriction on number of loop nodes. + +2013-09-16 Jakub Jelinek <jakub@redhat.com> + + * ipa-prop.c (ipa_compute_jump_functions_for_edge): Return early + for internal calls. + +2013-09-16 Richard Sandiford <rdsandiford@googlemail.com> + + * cse.c (try_const_anchors): Punt on CC modes. + +2013-09-15 Jan-Benedict Glaw <jbglaw@lug-owl.de> + + * config/vax/constraints.md (T): Add missing CONSTANT_P check. + +2013-09-14 John David Anglin <danglin@gcc.gnu.org> + + PR target/58382 + * config/pa/pa.c (pa_expand_prologue): Change mode in gen_rtx_POST_INC + calls to word_mode. + +2013-09-14 Iain Sandoe <iain@codesourcery.com> + + PR target/48094 + * config/darwin.c (darwin_objc2_section): Note if ObjC Metadata is + seen. + (darwin_objc1_section): Likewise. + (darwin_file_end): Emit Image Info section when required. + +2013-09-14 Jan Hubicka <jh@suse.cz> + + * tree-into-ssa.c (gate_into_ssa): New. + (pass_data_build_ssa): Use it. + * cgraph.h (expand_thunk): Update prototype. + * cgraphunit.c (analyze_function): Expand thunks early. + (expand_thunk): Fix DECL_CONTEXT of reust_decl; + build proper cgraph; set in_ssa_p; clear bogus TREE_ASM_WRITTEN; + set lowered flag; do not add new function. + (assemble_thunks_and_aliases): Update. + * tree-ssa.c (gate_init_datastructures): New gate. + (pass_data_init_datastructures): Use it. + +2013-09-14 Iain Sandoe <iain@codesourcery.com> + + PR target/58269 + * 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. + +2013-09-13 Jacek Caban <jacek@codeweavers.com> + + * config.gcc: Use new winnt-c.c target hooks + * config/t-winnt: New file + * config/winnt-c.c: New file + * doc/tm.texi.in: Document new hook + * doc/tm.texi: Regenerated + +2013-09-13 Jan Hubicka <jh@suse.cz> + + PR middle-end/58094 + * ipa-inline.c (check_callers): New function. + (check_caller_edge): Remove. + (want_inline_function_to_all_callers_p): Also permit alises that are + called dirrectly. + (inline_to_all_callers): Terminate the walk when devirtualization + introduce new calls. + +2013-09-13 Jan Hubicka <jh@suse.cz> + + * ipa-inline-analysis.c (struct growth_data): Add node. + (do_estimate_growth_1): Fix detection of recursion. + +2013-09-13 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/58392 + * tree-cfg.c (move_sese_region_to_fn): Rename loop variable + to avoid shadowing of outer loop variable. If + saved_cfun->has_simduid_loops or saved_cfun->has_force_vect_loops, + replace_by_duplicate_decl simduid of loops that have it set and + set dest_cfun->has_simduid_loops and/or + dest_cfun->has_force_vect_loops. + * omp-low.c (build_outer_var_ref): Call maybe_lookup_decl_in_outer_ctx + instead of maybe_lookup_decl. + * tree-inline.c (copy_loops): Change blocks_to_copy argument to id. + Use id->blocks_to_copy instead of blocks_to_copy. Adjust recursive + call. Copy over force_vect and copy and remap simduid. Set + cfun->has_simduid_loops and/or cfun->has_force_vect_loops. + (copy_cfg_body): Remove blocks_to_copy argument. Use + id->blocks_to_copy instead of blocks_to_copy. Adjust copy_loops + caller. Don't set cfun->has_simduid_loops and/or + cfun->has_force_vect_loops here. + (copy_body): Remove blocks_to_copy argument. Adjust copy_cfg_body + caller. + (expand_call_inline, tree_function_versioning): Adjust copy_body + callers. + +2013-09-13 Martin Jambor <mjambor@suse.cz> + + PR bootstrap/58388 + * ipa-prop.c (try_make_edge_direct_simple_call): Be less strict in + the assert if the edge was a speculative one. + +2013-09-13 Richard Biener <rguenther@suse.de> + + * tree-data-ref.h (known_dependences_p): Move here ... + * tree-loop-distribution.c (known_dependences_p): ... from here. + (dump_rdg_component, debug_rdg_component): Remove. + (dump_rdg): Adjust. + (generate_loops_for_partition): Use gimple_uid instead of + relying on matching stmt visit order. + (rdg_build_partitions): Take starting stmt vector. + (ldist_gen): Merge into ... + (distribute_loop): ... this function. Do not compute starting + vertices vector. + * tree-cfg.c (gimple_duplicate_bb): Copy UID for PHIs. + +2013-09-13 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * config/arm/arm.md (arm_cmpsi_insn): Split rI alternative. + Set type attribute correctly. Set predicable_short_it attribute. + (cmpsi_shiftsi): Remove %? from output template. + +2013-09-13 Richard Biener <rguenther@suse.de> + + * tree-loop-distribution.c (struct rdg_component, + rdg_defs_used_in_other_loops_p, free_rdg_components, + rdg_build_components): Remove. + (stmts_from_loop): Do not record virtual PHIs. + (generate_loops_for_partition): Skip virtual PHIs. + (build_rdg_partition_for_component): Rename to ... + (build_rdg_partition_for_vertex): ... this and adjust. + (rdg_build_partitions): Take a vector of starting vertices + instead of components. Remove unnecessary leftover handling. + (ldist_gen): Do not build components or record other stores. + (distribute_loop): Do not distribute loops containing stmts + with side-effects. + +2013-09-13 Christian Bruel <christian.bruel@st.com> + + PR target/58314 + * config/sh/sh.md (mov<mode>_reg_reg): Allow memory reloads. + +2013-09-13 Kai Tietz <ktietz@redhat.com> + + * config.gcc: Separate cases for mingw and cygwin targets, + and add 64-bit cygwin target case. + + * config/i386/winnt-cxx.c (i386_pe_type_dllexport_p): Don't + dll-export inline-functions. + * config/i386/winnt.c (i386_pe_determine_dllexport_p): Likewise. + + +2013-09-13 Jeff Law <law@redhat.com> + + PR middle-end/58387 + Revert: + 2013-09-06 Jeff Law <law@redhat.com> + + * tree-ssa-dom.c (cprop_into_successor_phis): Also propagate + edge implied equivalences into successor phis. + +2013-09-12 DJ Delorie <dj@redhat.com> + + * config/rl78/rl78-virt.md: Change from | to \; for asm line + separators. + +2013-09-12 Brooks Moses <bmoses@google.com> + + PR driver/42955 + * Makefile.in: Do not install driver binaries in $(target)/bin. + +2013-09-12 DJ Delorie <dj@redhat.com> + + * config/rl78/rl78.opt (mrelax): New. + * config/rl78/rl78.h (ASM_SPEC): New, pass on -mrelax to gas. + * config/rl78/rl78.h (LINK_SPEC): New, pass on -mrelax to ld. + + * config/rl78/rl78.c (rl78_expand_prologue): Use AX to copy + between SP and FP. + (rl78_expand_epilogue): Likewise. + +2013-09-12 Vladimir Makarov <vmakarov@redhat.com> + + PR middle-end/58335 + * lra-eliminations.c (remove_reg_equal_offset_note): New. + (eliminate_regs_in_insn): Rewrite frame pointer to hard frame + pointer elimination with using remove_reg_equal_offset_note. + +2013-09-12 DJ Delorie <dj@redhat.com> + + * config/msp430/: New port. + * config.gcc (msp430): Added. + * doc/invoke.texi: Document MSP430 options. + * doc/install.texi: Document msp430-elf + * doc/md.texi: Document msp430-elf + * doc/contrib.texi: Document msp430-elf + + * cfgexpand.c (expand_debug_expr): Avoid sign-extending SImode to + PSImode. + +2013-09-12 Martin Jambor <mjambor@suse.cz> + + PR ipa/58389 + * ipa-prop.c (remove_described_reference): Give up if the edge in the + reference descriptor is NULL. + (ipa_edge_removal_hook): If owning a reference descriptor, set its + edge to NULL. + +2013-09-12 Andrew MacLeod <amacleod@redhat.com> + + * tree-flow.h (FREE_SSANAMES): Move to tree-ssanames.c + (SSANAMES, MODIFIED_NORETURN_CALLS, DEFAULT_DEFS, ptr_info_def, + num_ssa_names, ssa_name): Move to tree-ssanames.h + prototypes. + * tree-flow-inline.h (make_ssa_name, copy_ssa_name, duplicate_ssa_name, + make_temp_ssa_name): move to tree-ssanames.h + * tree-ssa-alias.h: Move prototype. + * tree-ssa.h: Include tree-ssanames.h. + * tree-ssanames.c (FREE_SSANAMES): Move to here. + * tree-ssanames.h: New. Move items from tree-flow*.h + * Makefile.in (tree-ssanames.h): Add to tree-ssanames.o and GTFILES. + +2013-09-12 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58404 + * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Also + propagate non-invariant addresses into dereferences wrapped + in component references. + +2013-09-12 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58402 + * passes.def: Move pass_late_warn_uninitialized later. + +2013-09-12 Andrew MacLeod <amacleod@redhat.com> + + * tree-ssa.h: New. Move content from tree-flow.h and + 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, + 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.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. + * alias.c, asan.c, builtins.c, calls.c, cfgexpand.c, cfghooks.c, + cfgloop.c, cfgloopmanip.c, cgraph.c, cgraphbuild.c, cgraphclones.c, + cgraphunit.c, dse.c, except.c, expr.c, final.c, fold-const.c, + 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, + 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, + tracer.c, trans-mem.c, tree-call-cdce.c, tree-cfg.c, tree-cfgcleanup.c, + tree-chrec.c, tree-complex.c, tree-data-ref.c, tree-dfa.c, tree-eh.c, + tree-emutls.c, tree-if-conv.c, tree-inline.c, tree-into-ssa.c, + tree-loop-distribution.c, tree-mudflap.c, tree-nested.c, tree-nrv.c, + tree-object-size.c, tree-optimize.c, tree-outof-ssa.c, tree-parloops.c, + tree-phinodes.c, tree-predcom.c, tree-pretty-print.c, tree-profile.c, + tree-scalar-evolution.c, tree-sra.c, tree-ssa*.c, tree-stdarg.c, + tree-streamer-in.c, tree-switch-conversion.c, tree-tailcall.c, + tree-vect-data-refs.c, tree-vect-generic.c, tree-vect-loop-manip.c, + tree-vect-loop.c, tree-vect-patterns.c, tree-vect-slp.c, + tree-vect-stmts.c, tree-vectorizer.c, tree-vrp.c, tsan.c, + value-prof.c, var-tracking.c, + varpool.c, vtable-verify.c: Replace tree-flow.h with tree-ssa.h + +2013-09-12 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58396 + * tree-loop-distribution.c (create_rdg_edges): Free unused DDRs. + (build_rdg): Take a loop-nest parameter, fix memleaks. + (distribute_loop): Compute loop-nest here and pass it to build_rdg. + +2013-09-12 Yuri Rumyantsev <ysrumyan@gmail.com> + + * config/i386/x86-tune.def: Turn on X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE + for SLM. + +2013-09-12 Cameron McInally <cameron.mcinally@nyu.edu> + + * doc/extend.texi: Fix errors in x86 FMA builtin naming. + The FMA instruction names should have a 'v' prefix. + +2013-09-12 Richard Biener <rguenther@suse.de> + + * tree-loop-distribution.c (dot_rdg_1): Make graph prettier. + (dot_rdg): Use popen instead of system in optional code. + (remaining_stmts, upstream_mem_writes): Remove global bitmaps. + (already_processed_vertex_p): Adjust. + (has_anti_or_output_dependence, predecessor_has_mem_write, + mark_nodes_having_upstream_mem_writes, has_upstream_mem_writes, + rdg_flag_uses): Remove. + (rdg_flag_vertex): Simplify. + (rdg_flag_vertex_and_dependent): Rely on a correct RDG and + remove recursion. + (build_rdg_partition_for_component): Process the first vertex + of a component only. + (ldist_gen): Do not compute remaining_stmts or upstream_mem_writes. + +2013-09-12 Alan Modra <amodra@gmail.com> + + * config/rs6000/rs6000.c (toc_relative_expr_p): Use add_cint_operand. + +2013-09-11 DJ Delorie <dj@redhat.com> + Nick Clifton <nickc@redhat.com> + + * config/rl78/predicates.md (rl78_cmp_operator_signed): New. + (rl78_stack_based_mem): New. + * config/rl78/constraints.md (Iv08): New. + (Iv16): New. + (Iv24): New. + (Is09): New. + (Is17): New. + (Is25): New. + (ISsi): New. + (IShi): New. + (ISqi): New. + * config/rl78/rl78-expand.md (movqi): Reject more SUBREG operands. + (movhi): Likewise. + (movsi): Change from expand to insn-and-split. + (ashrsi3): Clobber AX. + (lshrsi3): New. + (ashlsi3): New. + (cbranchsi4): New. + * config/rl78/rl78.md (CC_REG): Fix. + (addsi3): Allow memory and immediate operands. + (addsi3_internal): Split into... + (addsi3_internal_virt): ...new, and ... + (addsi3_internal_real): ...new. + (subsi): New. + (subsi3_internal_virt): New. + (subsi3_internal_real): New. + (mulsi3): Add memory operand. + (mulsi3_rl78): Likewise. + (mulsi3_g13): Likewise. + * config/rl78/rl78-real.md (cbranchqi4_real_signed): New. + (cbranchqi4_real): Add more constraint options. + (cbranchhi4_real): Expand pattern. + (cbranchhi4_real_signed): New. + (cbranchhi4_real_inverted): New. + (cbranchsi4_real_lt): New. + (cbranchsi4_real_ge): New. + (cbranchsi4_real_signed): New. + (cbranchsi4_real): New. + (peephole2): New. + * config/rl78/rl78-virt.md (ashrsi3_virt): Add custom cases for + constant shifts. + (lshrsi3_virt): Likewise. + (ashlsi3_virt): Likewise. + (cbranchqi4_virt_signed): New. + (cbranchhi4_virt_signed): New. + (cbranchsi4_virt): New. + * config/rl78/rl78.c: Whitespace fixes throughout. + (move_elim_pass): New. + (pass_data_rl78_move_elim): New. + (pass_rl78_move_elim): New. + (make_pass_rl78_move_elim): New. + (rl78_devirt_info): Run devirt earlier. + (rl78_move_elim_info): New. + (rl78_asm_file_start): Register it. + (rl78_split_movsi): New. + (rl78_as_legitimate_address): Allow virtual base registers when + appropriate. + (rl78_addr_space_convert): Remove spurious debug stuff. + (rl78_print_operand_1): Add z,s,S,r,E modifiers. + (rl78_print_operand): More cases for not printing '#'. + (rl78_expand_compare): Remove most of the logic. + (content_memory): New. + (clear_content_memory): New. + (get_content_index): New. + (get_content_name): New. + (display_content_memory): New. + (update_content): New. + (record_content): New. + (already_contains): New. + (insn_ok_now): Re-recog insns with virtual registers. + (add_postponed_content_update): New. + (process_postponed_content_update): New. + (gen_and_emit_move): New. + (transcode_memory_rtx): Record new location content. + Use gen_and_emit_move. + (force_into_acc): New. + (move_to_acc): Use gen_and_emit_move. + (move_from_acc): Likewise. + (move_acc_to_reg): Likewise. + (move_to_x): Likewise. + (move_to_hl): Likewise. + (move_to_de): Likewise. + (rl78_alloc_physical_registers_op1): Record location content. + (has_constraint): New. + (rl78_alloc_physical_registers_op2): Record location content. + Optimize use of HL. + (rl78_alloc_physical_registers_ro1): Likewise. + (rl78_alloc_physical_registers_cmp): Likewise. + (rl78_alloc_physical_registers_umul): Likewise. + (rl78_alloc_address_registers_macax): New. + (rl78_alloc_physical_registers): Initialize and set location + content memory as needed. + (rl78_reorg): Make sure split2 is called. + (rl78_rtx_costs): New. + +2013-09-11 Richard Sandiford <rdsandiford@googlemail.com> + + * simplify-rtx.c (simplify_unary_operation_1): Use simplify_gen_binary + for (not (neg ...)) and (neg (not ...)) cases. + +2013-09-11 Richard Biener <rguenther@suse.de> + + PR middle-end/58377 + * passes.def: Split critical edges before late uninit warning passes. + * tree-cfg.c (pass_split_crit_edges): Implement clone method. + +2013-09-11 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/58385 + * fold-const.c (build_range_check): If both low and high are NULL, + use omit_one_operand_loc to preserve exp side-effects. + +2013-09-11 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * config/arm/arm.md (arm_shiftsi3): New alternative l/l/M. + +2013-09-11 Richard Biener <rguenther@suse.de> + + * tree-data-ref.c (dump_rdg_vertex, debug_rdg_vertex, + dump_rdg_component, debug_rdg_component, dump_rdg, debug_rdg, + dot_rdg_1, dot_rdg, rdg_vertex_for_stmt, create_rdg_edge_for_ddr, + create_rdg_edges_for_scalar, create_rdg_edges, create_rdg_vertices, + stmts_from_loop, known_dependences_p, build_empty_rdg, + build_rdg, free_rdg, rdg_defs_used_in_other_loops_p): Move ... + * tree-loop-distribution.c: ... here. + * tree-data-ref.h (struct rdg_vertex, RDGV_STMT, RDGV_DATAREFS, + RDGV_HAS_MEM_WRITE, RDGV_HAS_MEM_READS, RDG_STMT, RDG_DATAREFS, + RDG_MEM_WRITE_STMT, RDG_MEM_READS_STMT, enum rdg_dep_type, + struct rdg_edge, RDGE_TYPE, RDGE_LEVEL, RDGE_RELATION): Move ... + * tree-loop-distribution.c: ... here. + * tree-loop-distribution.c: Include gimple-pretty-print.h. + (struct partition_s): Add loops member. + (partition_alloc, partition_free, rdg_flag_uses, rdg_flag_vertex, + rdg_flag_vertex_and_dependent, rdg_flag_loop_exits, + build_rdg_partition_for_component, rdg_build_partitions): Adjust. + +2013-09-11 Alexander Ivchenko <alexander.ivchenko@intel.com> + Maxim Kuznetsov <maxim.kuznetsov@intel.com> + Sergey Lega <sergey.s.lega@intel.com> + Anna Tikhonova <anna.tikhonova@intel.com> + Ilya Tocar <ilya.tocar@intel.com> + Andrey Turetskiy <andrey.turetskiy@intel.com> + Ilya Verbin <ilya.verbin@intel.com> + Kirill Yukhin <kirill.yukhin@intel.com> + Michael Zolotukhin <michael.v.zolotukhin@intel.com> + + * config/i386/constraints.md (k): New. + (Yk): Ditto. + * config/i386/i386.c (const regclass_map): Add new mask registers. + (dbx_register_map): Ditto. + (dbx64_register_map): Ditto. + (svr4_dbx_register_map): Ditto. + (ix86_conditional_register_usage): Squash mask registers if AVX512F is + disabled. + (ix86_preferred_reload_class): Disable constants for mask registers. + (ix86_secondary_reload): Do spill of mask register using 32-bit insn. + (ix86_hard_regno_mode_ok): Support new mask registers. + (x86_order_regs_for_local_alloc): Ditto. + * config/i386/i386.h (FIRST_PSEUDO_REGISTER): Update. + (FIXED_REGISTERS): Add new mask registers. + (CALL_USED_REGISTERS): Ditto. + (REG_ALLOC_ORDER): Ditto. + (VALID_MASK_REG_MODE): New. + (FIRST_MASK_REG): Ditto. + (LAST_MASK_REG): Ditto. + (reg_class): Add MASK_EVEX_REGS, MASK_REGS. + (MAYBE_MASK_CLASS_P): New. + (REG_CLASS_NAMES): Add MASK_EVEX_REGS, MASK_REGS. + (REG_CLASS_CONTENTS): Ditto. + (MASK_REGNO_P): New. + (ANY_MASK_REG_P): Ditto. + (HI_REGISTER_NAMES): Add new mask registers. + * config/i386/i386.md (MASK0_REG, MASK1_REG, MASK2_REG, MASK3_REG, + MASK4_REG, MASK5_REG, MASK6_REG, MASK7_REG): Constants for new + mask registers. + (attribute "type"): Add mskmov, msklog. + (attribute "length_immediate"): Support them. + (attribute "memory"): Ditto. + (attribute "prefix_0f"): Ditto. + (*movhi_internal): Support new mask registers. + (*movqi_internal): Ditto. + (define_split): Split out clobber pattern is a logic + insn on mask registers. + (*k<logic><mode>): New. + (*andhi_1): Extend to support mask regs. + (*andqi_1): Extend to support mask regs. + (kandn<mode>): New. + (define_split): Split and-not to and and not if operands + are not mask regs. + (*<code><mode>_1): Separate HI mode to new pattern... + (*<code>hi_1): This. + (*<code>qi_1): Extend to support mask regs. + (kxnor<mode>): New. + (kortestzhi): Ditto. + (kortestchi): Ditto. + (kunpckhi): Ditto. + (*one_cmpl<mode>2_1): Remove HImode and handle it... + (*one_cmplhi2_1): ...Here, now with mask registers support. + (*one_cmplqi2_1): Support new mask registers. + (HI/QImode arithmetics splitter): Don't split if mask registers + are used. + (HI/QImode not splitter): Ditto. + * config/i386/predicated.md (mask_reg_operand): New. + (general_reg_operand): Ditto. + +2013-09-11 Alexander Ivchenko <alexander.ivchenko@intel.com> + + * doc/invoke.texi: Document fxsr, xsave and xsaveopt options. + * doc/extend.texi: Document fxsr, xsave and xsaveopt builtins. + +2013-09-10 Jeff Law <law@redhat.com> + + PR tree-optimization/58380 + * tree-ssa-threadupdate.c (thread_block): Recognize another case + of threading through a buried loop header. + + * tree-ssa-threadedge.c (thread_around_empty_blocks): Correct + return value for single successor case. + +2013-09-10 Jan Hubicka <jh@suse.cz> + + * ipa-devirt.c (ipa_devirt): Enable with LTO. + +2013-09-10 Richard Earnshaw <rearnsha@arm.com> + + PR target/58361 + * arm/vfp.md (combine_vcvt_f32_<FCVTI32typename>): Fix pattern to + support conditional execution. + (combine_vcvt_f64_<FCVTI32typename>): Likewise. + +2013-09-10 Vladimir Makarov <vmakarov@redhat.com> + + * 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. + (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. + (lra_undo_inheritance): Add check that inherited pseudo still in + memory. + +2013-09-10 James Greenhalgh <james.greenhalgh@arm.com> + + * config/aarch64/aarch64.md (generic_sched): New. + * config/aarch64/aarch64-generic.md (load): Make conditional + on generic_sched attribute. + (nonload): Likewise. + +2013-09-10 Jan Hubicka <jh@suse.cz> + + * lto-cgraph.c: Include ipa-utils.h. + (compute_ltrans_boundary): Also add possible targets into the boundary. + +2013-09-10 Jan Hubicka <jh@suse.cz> + + * gimple-fold.c (gimple_get_virt_method_for_binfo): Pass real + VAR_DECL of vtable rather than full expression. + +2013-09-10 Jan Hubicka <jh@suse.cz> + Paolo Carlini <paolo.carlini@oracle.com> + + * cgraphunit.c (analyze_functions): Save input_location, set it + to UNKNOWN_LOCATION and restore it at the end. + +2013-09-10 Martin Jambor <mjambor@suse.cz> + + * ipa-cp.c (propagate_constants_topo): Do not ignore SCC + represented by a thunk. + +2013-09-10 Jeff Law <law@redhat.com> + + PR tree-optimization/58343 + * tree-ssa-threadupdate.c (thread_block): Identify and disable + jump threading requests through loop headers buried in the middle + of a jump threading path. + + * tree-ssa-threadedge.c (thread_around_empty_blocks): Fix thinko + in return value/type. + +2013-09-10 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/58365 + * cfgcleanup.c (merge_memattrs): Also clear MEM_READONLY_P + resp. MEM_NOTRAP_P if they differ, or set MEM_VOLATILE_P if + it differs. + +2013-09-10 Richard Biener <rguenther@suse.de> + + * tree-data-ref.h (build_rdg): Drop all parameters but loop. + * tree-data-ref.c (create_rdg_vertices): Collect all data + references, signal failure to the caller, use data-ref API. + (build_rdg): Compute data references only once. Maintain lifetime + of data references and data dependences from within RDG. + (free_rdg): Free dependence relations. + * tree-loop-distribution.c (rdg_flag_uses): Drop weird code + inventing extra dependences. + (distribute_loop): Update for RDG API changes. + +2013-09-10 Kai Tietz <ktietz@redhat.com> + + * doc/invoke.texi (fms-extensions): Document changed + behavior for ms-abi targets. + * config/i386/i386.c (ix86_option_override_internal): + Set default value of option -fms-extension for ms-abi targets. + +2013-09-10 Michael Zolotukhin <michael.v.zolotukhin@gmail.com> + + * config/i386/i386.c (ix86_expand_movmem): Fix epilogue generation. + +2013-09-10 Alan Modra <amodra@gmail.com> + + PR target/58330 + * config/rs6000/rs6000.md (bswapdi2_64bit): Disable for volatile mems. + +2013-09-10 Alan Modra <amodra@gmail.com> + + * config/rs6000/predicates.md (add_cint_operand): New. + (reg_or_add_cint_operand, small_toc_ref): Use add_cint_operand. + * config/rs6000/rs6000.md (largetoc_high_plus): Restrict offset + using add_cint_operand. + (largetoc_high_plus_aix): Likewise. + +2013-09-09 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/58364 + * tree-ssa-reassoc.c (init_range_entry): For BIT_NOT_EXPR on + BOOLEAN_TYPE, only invert in_p and continue with arg0 if + the current range can't be an unconditional true or false. + +2013-09-09 James Greenhalgh <james.greenhalgh@arm.com> + + * config/aarch64/arm_neon.h (vrsqrte_f64): Fix parameter type. + +2013-09-09 Uros Bizjak <ubizjak@gmail.com> + + * ipa-prop.c (ipa_modify_call_arguments): Initialize deref_align. + +2013-09-09 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/43452 + * doc/invoke.texi (-Wdelete-incomplete): Document it. + +2013-09-09 Ian Bolton <ian.bolton@arm.com> + + * config/aarch64/aarch64.c (aarch64_preferred_reload_class): Return + NO_REGS for immediate that can't be moved directly into FP_REGS. + +2013-09-09 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * config/aarch64/aarch64.c (aarch64_select_cc_mode): Return CC_SWP for + comparison with negated operand. + * config/aarch64/aarch64.md (compare_neg<mode>): Match canonical + RTL form. + +2013-09-09 Richard Biener <rguenther@suse.de> + + PR middle-end/58326 + * cfgloopmanip.c (fix_bb_placements): When fixing the placement + of a subloop record all its block as affecting loop-closed SSA form. + +2013-09-09 Richard Sandiford <rdsandiford@googlemail.com> + + * expmed.c (lshift_value): Take an unsigned HOST_WIDE_INT instead + of an rtx/bitpos pair. + (store_fixed_bit_field): Update accordingly. + +2013-09-09 Richard Sandiford <rdsandiford@googlemail.com> + + * asan.c (asan_emit_stack_protection): Use gen_int_mode instead of + GEN_INT. + * builtins.c (expand_errno_check): Likewise. + * dwarf2cfi.c (init_return_column_size): Likewise. + * except.c (sjlj_mark_call_sites): Likewise. + * expr.c (move_by_pieces_1, store_by_pieces_2): Likewise. + * lra-constraints.c (emit_inc): Likewise. + * ree.c (combine_set_extension): Likewise. + * regmove.c (fixup_match_2): Likewise. + * reload1.c (inc_for_reload): Likewise. + +2013-09-09 Richard Sandiford <rdsandiford@googlemail.com> + + * combine.c (simplify_set, expand_field_assignment, extract_left_shift) + (force_to_mode, simplify_shift_const_1, simplify_comparison): + Use gen_int_mode with the mode of the associated simplify_* call. + * explow.c (probe_stack_range, anti_adjust_stack_and_probe): Likewise. + * expmed.c (expand_shift_1): Likewise. + * function.c (instantiate_virtual_regs_in_insn): Likewise. + * loop-iv.c (iv_number_of_iterations): Likewise. + * loop-unroll.c (unroll_loop_runtime_iterations): Likewise. + * simplify-rtx.c (simplify_binary_operation_1): Likewise. + +2013-09-09 Richard Sandiford <rdsandiford@googlemail.com> + + * asan.c (asan_clear_shadow): Use gen_int_mode with the mode + of the associated expand_* call. + (asan_emit_stack_protection): Likewise. + * builtins.c (round_trampoline_addr): Likewise. + * explow.c (allocate_dynamic_stack_space, probe_stack_range): Likewise. + * expmed.c (expand_smod_pow2, expand_sdiv_pow2, expand_divmod) + (emit_store_flag): Likewise. + * expr.c (emit_move_resolve_push, push_block, emit_single_push_insn_1) + (emit_push_insn, optimize_bitfield_assignment_op, expand_expr_real_1): + Likewise. + * function.c (instantiate_virtual_regs_in_insn): Likewise. + * ifcvt.c (noce_try_store_flag_constants): Likewise. + * loop-unroll.c (unroll_loop_runtime_iterations): Likewise. + * modulo-sched.c (generate_prolog_epilog): Likewise. + * optabs.c (expand_binop, widen_leading, expand_doubleword_clz) + (expand_ctz, expand_ffs, expand_unop): Likewise. + +2013-09-09 Richard Sandiford <rdsandiford@googlemail.com> + + * alias.c (addr_side_effect_eval): Use gen_int_mode with the mode + of the associated gen_rtx_* call. + * caller-save.c (init_caller_save): Likewise. + * combine.c (find_split_point, make_extraction): Likewise. + (make_compound_operation): Likewise. + * dwarf2out.c (mem_loc_descriptor): Likewise. + * explow.c (plus_constant, probe_stack_range): Likewise. + * expmed.c (expand_mult_const): Likewise. + * expr.c (emit_single_push_insn_1, do_tablejump): Likewise. + * reload1.c (init_reload): Likewise. + * valtrack.c (cleanup_auto_inc_dec): Likewise. + * var-tracking.c (adjust_mems): Likewise. + * modulo-sched.c (sms_schedule): Likewise, but use gen_rtx_GT + rather than gen_rtx_fmt_ee. + +2013-09-09 Jan Hubicka <jh@suse.cz> + + PR middle-end/58294 + * value-prof.c (gimple_ic): Copy also abnormal edges. + +2013-09-09 Richard Sandiford <rdsandiford@googlemail.com> + + * asan.c (asan_shadow_cst): Use gen_int_mode. + +2013-09-08 Jan Hubicka <jh@suse.cz> + + * ipa-profile.c: Add toplevel comment. + (ipa_propagate_frequency_1): Be more conservative when profile is read. + (contains_hot_call_p): New function. + (ipa_propagate_frequency): Set frequencies based on counts when + profile is read. + * predict.c (compute_function_frequency): Use PROFILE_READ gueard for + profile; do not tamper with profile after inlining if it is read. + +2013-09-08 Jan Hubicka <jh@suse.cz> + + * ipa-prop.c (try_make_edge_direct_simple_call): Do not special case + speculative edges. + +2013-09-08 Jan Hubicka <jh@suse.cz> + + * ipa.c (walk_polymorphic_call_targets): Fix redirection before IPA + summary generation. + +2013-09-08 Jeff Law <law@redhat.com> + + PR bootstrap/58340 + * tree-ssa-threadedge.c (thread_across_edge): Fix initialization + of 'found'. + +2013-09-08 Andi Kleen <ak@linux.intel.com> + + * tree-inline.c (estimate_num_insns): Limit asm cost to 1000. + +2013-09-08 Jan Hubicka <jh@suse.cz> + + * ipa.c (walk_polymorphic_call_targets): Fix inliner summary update. + +2013-09-08 Richard Sandiford <rdsandiford@googlemail.com> + + * ira.c (update_equiv_regs): Only call set_paradoxical_subreg + for non-debug insns. + * lra.c (new_insn_reg): Take the containing insn as a parameter. + Only modify lra_reg_info[].biggest_mode if it's non-debug insn. + (collect_non_operand_hard_regs, add_regs_to_insn_regno_info): Update + accordingly. + +2013-09-08 Jan Hubicka <jh@suse.cz> + + * cgraphunit.c (walk_polymorphic_call_targets): Permit 0 possible + targets and devirtualize to BUILT_IN_UNREACHABLE. + * timevar.def (TV_IPA_UNREACHABLE): New timevar. + * ipa.c (walk_polymorphic_call_targets): New function. + (symtab_remove_unreachable_nodes): Use it; do not keep all virtual + functions; use the new timevar. + * ipa-devirt.c (maybe_record_node): Do not insert static nodes that + was removed from the program. + (record_binfo): If BINFO corresponds to an anonymous namespace, we may + not consider it in the walk when its vtable is dead. + (possible_polymorphic_call_targets_1): Pass anonymous flag to + record_binfo. + (devirt_variable_node_removal_hook): New function. + (possible_polymorphic_call_targets): Also register + devirt_variable_node_removal_hook. + (ipa_devirt): Do not do non-speculative devirtualization. + (gate_ipa_devirt): One execute if devirtualizing speculatively. + +2013-09-08 Jan Hubicka <jh@suse.cz> + + * cgraph.h (varpool_node_hook, varpool_node_hook_list, + varpool_add_node_removal_hook, varpool_add_variable_insertion_hook, + varpool_remove_variable_insertion_hook): Declare. + * varpool.c (varpool_node_hook_list): New structure. + (first_varpool_node_removal_hook, + first_varpool_variable_insertion_hook): New variables. + (varpool_add_node_removal_hook, varpool_remove_node_removal_hook, + varpool_call_node_removal_hooks, varpool_add_variable_insertion_hook, + varpool_remove_variable_insertion_hook, + varpool_call_variable_insertion_hooks): New functions. + (varpool_remove_node): Use it. + +2013-09-08 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/54941 + * diagnostic.c (diagnostic_build_prefix): When s.file is + "<built-in>" don't output line and column numbers. + +2013-09-06 Jan Hubicka <jh@suse.cz> + + * cgraphunit.c (expand_thunk): Get body before touching arguments. + * lto-streamer-out.c: Stream thunks, too. + * lto-streamer-in.c (input_function): Pop cfun here + (lto_read_body): Instead of here. + +2013-09-06 Caroline Tice <cmtice@google.com> + + * doc/install.texi: Add documentation for the --enable-vtable-verify + and the --disable-libvtv configure options. + +2013-09-06 Jeff Law <law@redhat.com> + + * tree-ssa-dom.c (cprop_into_successor_phis): Also propagate + edge implied equivalences into successor phis. + +2013-09-06 Joern Rennecke <joern.rennecke@embecosm.com> + + * resource.c (mark_referenced_resources): Handle COND_EXEC. + +2013-09-06 Claudiu Zissulescu <claziss@synopsys.com> + + * resource.c (mark_target_live_regs): Compute resources taking + into account if a call is predicated or not. + +2013-09-06 Eric Botcazou <ebotcazou@adacore.com> + + * toplev.c (output_stack_usage): Be prepared for suffixes created by + the compiler in the function names. + +2013-09-06 Jan Hubicka <jh@suse.cz> + + PR middle-end/58094 + * ipa-inline.c (has_caller_p): New function. + (want_inline_function_to_all_callers_p): Use it. + (sum_callers, inline_to_all_callers): Break out from ... + (ipa_inline): ... here. + +2013-09-06 Jan Hubicka <jh@suse.cz> + + * config/i386/i386.c (ix86_hard_regno_mode_ok): AVX modes are valid + only when AVX is enabled. + +2013-09-06 James Greenhalgh <james.greenhalgh@arm.com> + + * config/aarch64/aarch64.md + (*movtf_aarch64): Use neon_<ls>dm_2 as type where v8type + is fpsimd_<load/store>2. + (load_pair<mode>): Likewise. + (store_pair<mode>): Likewise. + +2013-09-06 James Greenhalgh <james.greenhalgh@arm.com> + + * config/arm/types.md (type): Add "mrs" type. + * config/aarch64/aarch64.md + (aarch64_load_tp_hard): Make type "mrs". + * config/arm/arm.md + (load_tp_hard): Make type "mrs". + * config/arm/cortex-a15.md: Update with new attributes. + * config/arm/cortex-a5.md: Update with new attributes. + * config/arm/cortex-a53.md: Update with new attributes. + * config/arm/cortex-a7.md: Update with new attributes. + * config/arm/cortex-a8.md: Update with new attributes. + * config/arm/cortex-a9.md: Update with new attributes. + * config/arm/cortex-m4.md: Update with new attributes. + * config/arm/cortex-r4.md: Update with new attributes. + * config/arm/fa526.md: Update with new attributes. + * config/arm/fa606te.md: Update with new attributes. + * config/arm/fa626te.md: Update with new attributes. + * config/arm/fa726te.md: Update with new attributes. + +2013-09-06 James Greenhalgh <james.greenhalgh@arm.com> + + * config/aarch64/aarch64.md + (*movti_aarch64): Use "multiple" for type where v8type is "move2". + (*movtf_aarch64): Likewise. + * config/arm/arm.md + (thumb1_movdi_insn): Use "multiple" for type where more than one + instruction is used for a move. + (*arm32_movhf): Likewise. + (*thumb_movdf_insn): Likewise. + +2013-09-06 James Greenhalgh <james.greenhalgh@arm.com> + + * config/arm/types.md (type): Rename fcpys to fmov. + * config/arm/vfp.md + (*arm_movsi_vfp): Rename type fcpys as fmov. + (*thumb2_movsi_vfp): Likewise + (*movhf_vfp_neon): Likewise + (*movhf_vfp): Likewise + (*movsf_vfp): Likewise + (*thumb2_movsf_vfp): Likewise + (*movsfcc_vfp): Likewise + (*thumb2_movsfcc_vfp): Likewise + * config/aarch64/aarch64-simd.md + (move_lo_quad_<mode>): Replace type mov_reg with fmovs. + * config/aarch64/aarch64.md + (*movsi_aarch64): Replace type mov_reg with fmovs. + (*movdi_aarch64): Likewise + (*movsf_aarch64): Likewise + (*movdf_aarch64): Likewise + * config/arm/arm.c + (cortexa7_older_only): Rename TYPE_FCPYS to TYPE_FMOV. + * config/arm/iwmmxt.md + (*iwmmxt_movsi_insn): Rename type fcpys as fmov. + * config/arm/arm1020e.md: Update with new attributes. + * config/arm/cortex-a15-neon.md: Update with new attributes. + * config/arm/cortex-a5.md: Update with new attributes. + * config/arm/cortex-a53.md: Update with new attributes. + * config/arm/cortex-a7.md: Update with new attributes. + * config/arm/cortex-a8-neon.md: Update with new attributes. + * config/arm/cortex-a9.md: Update with new attributes. + * config/arm/cortex-m4-fpu.md: Update with new attributes. + * config/arm/cortex-r4f.md: Update with new attributes. + * config/arm/marvell-pj4.md: Update with new attributes. + * config/arm/vfp11.md: Update with new attributes. + +2013-09-06 James Greenhalgh <james.greenhalgh@arm.com> + + * config/aarch64/aarch64.md + (*madd<mode>): Fix type attribute. + (*maddsi_uxtw): Likewise. + (*msub<mode>): Likewise. + (*msubsi_uxtw): Likewise. + (<su_optab>maddsidi4): Likewise. + (<su_optab>msubsidi4): Likewise. + +2013-09-06 James Greenhalgh <james.greenhalgh@arm.com> + + * config/arm/types.md: Split fdiv<sd> as fsqrt<sd>, fdiv<sd>. + * config/arm/arm.md (core_cycles): Remove fdiv. + * config/arm/vfp.md: + (*sqrtsf2_vfp): Update for attribute changes. + (*sqrtdf2_vfp): Likewise. + * config/aarch64/aarch64.md: + (sqrt<mode>2): Update for attribute changes. + * config/arm/arm1020e.md: Update with new attributes. + * config/arm/cortex-a15-neon.md: Update with new attributes. + * config/arm/cortex-a5.md: Update with new attributes. + * config/arm/cortex-a53.md: Update with new attributes. + * config/arm/cortex-a7.md: Update with new attributes. + * config/arm/cortex-a8-neon.md: Update with new attributes. + * config/arm/cortex-a9.md: Update with new attributes. + * config/arm/cortex-m4-fpu.md: Update with new attributes. + * config/arm/cortex-r4f.md: Update with new attributes. + * config/arm/marvell-pj4.md: Update with new attributes. + * config/arm/vfp11.md: Update with new attributes. + +2013-09-06 James Greenhalgh <james.greenhalgh@arm.com> + + * config/arm/types.md + (type): Split f_cvt as f_cvt, f_cvtf2i, f_cvti2f. + * config/aarch64/aarch64.md + (l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2): Update with + new attributes. + (fix_trunc<GPF:mode><GPI:mode>2): Likewise. + (fixuns_trunc<GPF:mode><GPI:mode>2): Likewise. + (float<GPI:mode><GPF:mode>2): Likewise. + * config/arm/vfp.md + (*truncsisf2_vfp): Update with new attributes. + (*truncsidf2_vfp): Likewise. + (fixuns_truncsfsi2): Likewise. + (fixuns_truncdfsi2): Likewise. + (*floatsisf2_vfp): Likewise. + (*floatsidf2_vfp): Likewise. + (floatunssisf2): Likewise. + (floatunssidf2): Likewise. + (*combine_vcvt_f32_<FCVTI32typename>): Likewise. + (*combine_vcvt_f64_<FCVTI32typename>): Likewise. + * config/arm/arm1020e.md: Update with new attributes. + * config/arm/cortex-a15-neon.md: Update with new attributes. + * config/arm/cortex-a5.md: Update with new attributes. + * config/arm/cortex-a53.md: Update with new attributes. + * config/arm/cortex-a7.md: Update with new attributes. + * config/arm/cortex-a8-neon.md: Update with new attributes. + * config/arm/cortex-a9.md: Update with new attributes. + * config/arm/cortex-m4-fpu.md: Update with new attributes. + * config/arm/cortex-r4f.md: Update with new attributes. + * config/arm/marvell-pj4.md: Update with new attributes. + * config/arm/vfp11.md: Update with new attributes. + +2013-09-06 James Greenhalgh <james.greenhalgh@arm.com> + + * config/aarch64/arm_neon.h + (vqtbl<1,2,3,4><q>_s8): Fix control vector parameter type. + (vqtbx<1,2,3,4><q>_s8): Likewise. + +2013-09-06 James Greenhalgh <james.greenhalgh@arm.com> + + * config/arm/types.md: Add "no_insn", "multiple" and "untyped" types. + * config/arm/arm-fixed.md: Add type attribute to all insn patterns. + (add<mode>3): Add type attribute. + (add<mode>3): Likewise. + (usadd<mode>3): Likewise. + (ssadd<mode>3): Likewise. + (sub<mode>3): Likewise. + (sub<mode>3): Likewise. + (ussub<mode>3): Likewise. + (sssub<mode>3): Likewise. + (ssmulsa3): Likewise. + (usmulusa3): Likewise. + (arm_usatsihi): Likewise. + * config/arm/vfp.md + (*movdi_vfp): Add types for all instructions. + (*movdi_vfp_cortexa8): Likewise. + (*movhf_vfp_neon): Likewise. + (*movhf_vfp): Likewise. + (*movdf_vfp): Likewise. + (*thumb2_movdf_vfp): Likewise. + (*thumb2_movdfcc_vfp): Likewise. + * config/arm/arm.md: Add type attribute to all insn patterns. + (*thumb1_adddi3): Add type attribute. + (*arm_adddi3): Likewise. + (*adddi_sesidi_di): Likewise. + (*adddi_zesidi_di): Likewise. + (*thumb1_addsi3): Likewise. + (addsi3_compare0): Likewise. + (*addsi3_compare0_scratch): Likewise. + (*compare_negsi_si): Likewise. + (cmpsi2_addneg): Likewise. + (*addsi3_carryin_<optab>): Likewise. + (*addsi3_carryin_alt2_<optab>): Likewise. + (*addsi3_carryin_clobercc_<optab>): Likewise. + (*subsi3_carryin): Likewise. + (*subsi3_carryin_const): Likewise. + (*subsi3_carryin_compare): Likewise. + (*subsi3_carryin_compare_const): Likewise. + (*arm_subdi3): Likewise. + (*thumb_subdi3): Likewise. + (*subdi_di_zesidi): Likewise. + (*subdi_di_sesidi): Likewise. + (*subdi_zesidi_di): Likewise. + (*subdi_sesidi_di): Likewise. + (*subdi_zesidi_ze): Likewise. + (thumb1_subsi3_insn): Likewise. + (*arm_subsi3_insn): Likewise. + (*anddi3_insn): Likewise. + (*anddi_zesidi_di): Likewise. + (*anddi_sesdi_di): Likewise. + (*ne_zeroextracts): Likewise. + (*ne_zeroextracts): Likewise. + (*ite_ne_zeroextr): Likewise. + (*ite_ne_zeroextr): Likewise. + (*anddi_notdi_di): Likewise. + (*anddi_notzesidi): Likewise. + (*anddi_notsesidi): Likewise. + (andsi_notsi_si): Likewise. + (thumb1_bicsi3): Likewise. + (*iordi3_insn): Likewise. + (*iordi_zesidi_di): Likewise. + (*iordi_sesidi_di): Likewise. + (*thumb1_iorsi3_insn): Likewise. + (*xordi3_insn): Likewise. + (*xordi_zesidi_di): Likewise. + (*xordi_sesidi_di): Likewise. + (*arm_xorsi3): Likewise. + (*andsi_iorsi3_no): Likewise. + (*smax_0): Likewise. + (*smax_m1): Likewise. + (*arm_smax_insn): Likewise. + (*smin_0): Likewise. + (*arm_smin_insn): Likewise. + (*arm_umaxsi3): Likewise. + (*arm_uminsi3): Likewise. + (*minmax_arithsi): Likewise. + (*minmax_arithsi_): Likewise. + (*satsi_<SAT:code>): Likewise. + (arm_ashldi3_1bit): Likewise. + (arm_ashrdi3_1bit): Likewise. + (arm_lshrdi3_1bit): Likewise. + (*arm_negdi2): Likewise. + (*thumb1_negdi2): Likewise. + (*arm_negsi2): Likewise. + (*thumb1_negsi2): Likewise. + (*negdi_extendsid): Likewise. + (*negdi_zero_extend): Likewise. + (*arm_abssi2): Likewise. + (*thumb1_abssi2): Likewise. + (*arm_neg_abssi2): Likewise. + (*thumb1_neg_abss): Likewise. + (one_cmpldi2): Likewise. + (extend<mode>di2): Likewise. + (*compareqi_eq0): Likewise. + (*arm_extendhisi2addsi): Likewise. + (*arm_movdi): Likewise. + (*thumb1_movdi_insn): Likewise. + (*arm_movt): Likewise. + (*thumb1_movsi_insn): Likewise. + (pic_add_dot_plus_four): Likewise. + (pic_add_dot_plus_eight): Likewise. + (tls_load_dot_plus_eight): Likewise. + (*thumb1_movhi_insn): Likewise. + (*thumb1_movsf_insn): Likewise. + (*movdf_soft_insn): Likewise. + (*thumb_movdf_insn): Likewise. + (cbranchsi4_insn): Likewise. + (cbranchsi4_scratch): Likewise. + (*negated_cbranchsi4): Likewise. + (*tbit_cbranch): Likewise. + (*tlobits_cbranch): Likewise. + (*tstsi3_cbranch): Likewise. + (*cbranchne_decr1): Likewise. + (*addsi3_cbranch): Likewise. + (*addsi3_cbranch_scratch): Likewise. + (*arm_cmpdi_insn): Likewise. + (*arm_cmpdi_unsig): Likewise. + (*arm_cmpdi_zero): Likewise. + (*thumb_cmpdi_zero): Likewise. + (*deleted_compare): Likewise. + (*mov_scc): Likewise. + (*mov_negscc): Likewise. + (*mov_notscc): Likewise. + (*cstoresi_eq0_thumb1_insn): Likewise. + (cstoresi_nltu_thumb1): Likewise. + (cstoresi_ltu_thu): Likewise. + (thumb1_addsi3_addgeu): Likewise. + (*arm_jump): Likewise. + (*thumb_jump): Likewise. + (*check_arch2): Likewise. + (arm_casesi_internal): Likewise. + (thumb1_casesi_dispatch): Likewise. + (*arm_indirect_jump): Likewise. + (*thumb1_indirect_jump): Likewise. + (nop): Likewise. + (*and_scc): Likewise. + (*ior_scc): Likewise. + (*compare_scc): Likewise. + (*cond_move): Likewise. + (*cond_arith): Likewise. + (*cond_sub): Likewise. + (*cmp_ite0): Likewise. + (*cmp_ite1): Likewise. + (*cmp_and): Likewise. + (*cmp_ior): Likewise. + (*ior_scc_scc): Likewise. + (*ior_scc_scc_cmp): Likewise. + (*and_scc_scc): Likewise. + (*and_scc_scc_cmp): Likewise. + (*and_scc_scc_nod): Likewise. + (*negscc): Likewise. + (movcond_addsi): Likewise. + (movcond): Likewise. + (*ifcompare_plus_move): Likewise. + (*if_plus_move): Likewise. + (*ifcompare_move_plus): Likewise. + (*if_move_plus): Likewise. + (*ifcompare_arith_arith): Likewise. + (*if_arith_arith): Likewise. + (*ifcompare_arith_move): Likewise. + (*if_arith_move): Likewise. + (*ifcompare_move_arith): Likewise. + (*if_move_arith): Likewise. + (*ifcompare_move_not): Likewise. + (*if_move_not): Likewise. + (*ifcompare_not_move): Likewise. + (*if_not_move): Likewise. + (*ifcompare_shift_move): Likewise. + (*if_shift_move): Likewise. + (*ifcompare_move_shift): Likewise. + (*if_move_shift): Likewise. + (*ifcompare_shift_shift): Likewise. + (*ifcompare_not_arith): Likewise. + (*ifcompare_arith_not): Likewise. + (*if_arith_not): Likewise. + (*ifcompare_neg_move): Likewise. + (*if_neg_move): Likewise. + (*ifcompare_move_neg): Likewise. + (*if_move_neg): Likewise. + (prologue_thumb1_interwork): Likewise. + (*cond_move_not): Likewise. + (*sign_extract_onebit): Likewise. + (*not_signextract_onebit): Likewise. + (stack_tie): Likewise. + (align_4): Likewise. + (align_8): Likewise. + (consttable_end): Likewise. + (consttable_1): Likewise. + (consttable_2): Likewise. + (consttable_4): Likewise. + (consttable_8): Likewise. + (consttable_16): Likewise. + (*thumb1_tablejump): Likewise. + (prefetch): Likewise. + (force_register_use): Likewise. + (thumb_eh_return): Likewise. + (load_tp_hard): Likewise. + (load_tp_soft): Likewise. + (tlscall): Likewise. + (*arm_movtas_ze): Likewise. + (*arm_rev): Likewise. + (*arm_revsh): Likewise. + (*arm_rev16): Likewise. + * config/arm/thumb2.md + (*thumb2_smaxsi3): Likewise. + (*thumb2_sminsi3): Likewise. + (*thumb32_umaxsi3): Likewise. + (*thumb2_uminsi3): Likewise. + (*thumb2_negdi2): Likewise. + (*thumb2_abssi2): Likewise. + (*thumb2_neg_abss): Likewise. + (*thumb2_movsi_insn): Likewise. + (tls_load_dot_plus_four): Likewise. + (*thumb2_movhi_insn): Likewise. + (*thumb2_mov_scc): Likewise. + (*thumb2_mov_negs): Likewise. + (*thumb2_mov_negs): Likewise. + (*thumb2_mov_nots): Likewise. + (*thumb2_mov_nots): Likewise. + (*thumb2_movsicc_): Likewise. + (*thumb2_movsfcc_soft_insn): Likewise. + (*thumb2_indirect_jump): Likewise. + (*thumb2_and_scc): Likewise. + (*thumb2_ior_scc): Likewise. + (*thumb2_ior_scc_strict_it): Likewise. + (*thumb2_cond_move): Likewise. + (*thumb2_cond_arith): Likewise. + (*thumb2_cond_ari): Likewise. + (*thumb2_cond_sub): Likewise. + (*thumb2_negscc): Likewise. + (*thumb2_movcond): Likewise. + (thumb2_casesi_internal): Likewise. + (thumb2_casesi_internal_pic): Likewise. + (*thumb2_alusi3_short): Likewise. + (*thumb2_mov<mode>_shortim): Likewise. + (*thumb2_addsi_short): Likewise. + (*thumb2_subsi_short): Likewise. + (thumb2_addsi3_compare0): Likewise. + (*thumb2_cbz): Likewise. + (*thumb2_cbnz): Likewise. + (*thumb2_one_cmplsi2_short): Likewise. + (*thumb2_negsi2_short): Likewise. + (*orsi_notsi_si): Likewise. + * config/arm/arm1020e.md: Update with new attributes. + * config/arm/arm1026ejs.md: Update with new attributes. + * config/arm/arm1136jfs.md: Update with new attributes. + * config/arm/arm926ejs.md: Update with new attributes. + * config/arm/cortex-a15.md: Update with new attributes. + * config/arm/cortex-a5.md: Update with new attributes. + * config/arm/cortex-a53.md: Update with new attributes. + * config/arm/cortex-a7.md: Update with new attributes. + * config/arm/cortex-a8.md: Update with new attributes. + * config/arm/cortex-a9.md: Update with new attributes. + * config/arm/cortex-m4.md: Update with new attributes. + * config/arm/cortex-r4.md: Update with new attributes. + * config/arm/fa526.md: Update with new attributes. + * config/arm/fa606te.md: Update with new attributes. + * config/arm/fa626te.md: Update with new attributes. + * config/arm/fa726te.md: Update with new attributes. + +2013-09-06 James Greenhalgh <james.greenhalgh@arm.com> + + * config/aarch64/aarch64-simd.md + (aarch64_sqdml<SBINQOPS:as>l_n<mode>_internal): Use + <vwx> iterator to ensure correct register choice. + (aarch64_sqdml<SBINQOPS:as>l2_n<mode>_internal): Likewise. + (aarch64_sqdmull_n<mode>): Likewise. + (aarch64_sqdmull2_n<mode>_internal): Likewise. + * config/aarch64/arm_neon.h + (vml<as><q>_lane<q>_<su>16): Use 'x' constraint for element vector. + (vml<as><q>_n_<su>16): Likewise. + (vml<as>l_high_lane<q>_<su>16): Likewise. + (vml<as>l_high_n_<su>16): Likewise. + (vml<as>l_lane<q>_<su>16): Likewise. + (vml<as>l_n_<su>16): Likewise. + (vmul<q>_lane<q>_<su>16): Likewise. + (vmul<q>_n_<su>16): Likewise. + (vmull_lane<q>_<su>16): Likewise. + (vmull_n_<su>16): Likewise. + (vmull_high_lane<q>_<su>16): Likewise. + (vmull_high_n_<su>16): Likewise. + (vqrdmulh<q>_n_s16): Likewise. + +2013-09-06 Tejas Belagod <tejas.belagod@arm.com> + + * config/aarch64/arm_neon.h: Fix all vdup<bhsd_lane<q> intrinsics to + have the correct lane parameter. + +2013-09-06 Richard Biener <rguenther@suse.de> + + * cfganal.c (control_dependences::~control_dependences): + Properly free all of the vector. + +2013-09-06 Kirill Yukhin <kirill.yukhin@intel.com> + + PR target/58269 + * config/i386/i386.c (ix86_conditional_register_usage): + Proper initialize extended SSE registers. + +2013-09-06 Jan Hubicka <jh@suse.cz> + + PR tree-optimization/58311 + * ipa-devirt.c (gate_ipa_devirt): Only execute when optimizing. + +2013-09-06 Jan Hubicka <jh@suse.cz> + + * Makefile.in (tree-sra.o): Update dependencies. + * tree-sra.c: Include ipa-utils.h + (scan_function): Use recursive_call_p. + (has_caller_p): New function. + (cgraph_for_node_and_aliases): Count also callers of aliases. + +2013-09-06 Jan Hubicka <jh@suse.cz> + + PR middle-end/58094 + * cgraph.h (symtab_semantically_equivalent_p): Declare. + * tree-tailcall.c: Include ipa-utils.h. + (find_tail_calls): Use it. + * ipa-pure-const.c (check_call): Likewise. + * ipa-utils.c (recursive_call_p): New function. + * ipa-utils.h (recursive_call_p): Dclare. + * symtab.c (symtab_nonoverwritable_alias): Fix formatting. + (symtab_semantically_equivalent_p): New function. + * Makefile.in (tree-tailcall.o): Update dependencies. + +2013-09-06 Eric Botcazou <ebotcazou@adacore.com> + + * ipa-split.c (split_function): Set DECL_NO_INLINE_WARNING_P on the + non-inlinable part. + +2013-09-06 Richard Biener <rguenther@suse.de> + + * lto-streamer.h (lto_global_var_decls): Remove. + * Makefile.in (OBJS): Remove lto-symtab.o. + (lto-symtab.o): Remove. + (GTFILES): Remove lto-symtab.c + * lto-symtab.c: Move to lto/ + +2013-09-06 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * config/s390/s390.md (UNSPEC_FPINT_FLOOR, UNSPEC_FPINT_BTRUNC) + (UNSPEC_FPINT_ROUND, UNSPEC_FPINT_CEIL, UNSPEC_FPINT_NEARBYINT) + (UNSPEC_FPINT_RINT): New constant definitions. + (FPINT, fpint_name, fpint_roundingmode): New integer iterator + definition with 2 attributes. + ("<FPINT:fpint_name><BFP:mode>2", "rint<BFP:mode>2") + ("<FPINT:fpint_name><DFP:mode>2", "rint<DFP:mode>2"): New pattern + definitions. + +2013-09-06 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * config/s390/s390.md: Add "bcr_flush" value to mnemonic attribute. + ("mem_thread_fence_1"): Use bcr 14,0 for z196 and later. + Set the mnemonic attribute to "bcr_flush". Set the "z196prop" + attribute to "z196_alone". + * config/s390/2827.md: Add "bcr_flush" to "ooo_groupalone" and + "zEC12_simple". + +2013-09-06 Richard Biener <rguenther@suse.de> + + * basic-block.h (class control_dependences): New. + * tree-ssa-dce.c (control_dependence_map): Remove. + (cd): New global. + (EXECUTE_IF_CONTROL_DEPENDENT): Remove. + (set_control_dependence_map_bit, clear_control_dependence_bitmap, + find_pdom, find_control_dependence, find_all_control_dependences): + Move to cfganal.c. + (mark_control_dependent_edges_necessary, + find_obviously_necessary_stmts, propagate_necessity, tree_dce_init, + tree_dce_done, perform_tree_ssa_dce): Adjust. + * cfganal.c (set_control_dependence_map_bit, + clear_control_dependence_bitmap, find_pdom, find_control_dependence, + find_all_control_dependences): Move from tree-ssa-dce.c and + implement as methods of control_dependences class. + (control_dependences::control_dependences): New. + (control_dependences::~control_dependences): Likewise. + (control_dependences::get_edges_dependent_on): Likewise. + (control_dependences::get_edge): Likewise. + +2013-09-04 Jan Hubicka <jh@suse.cz> + + * tree.c (types_same_for_odr): Drop overactive check. + * ipa-devirt.c (hash_type_name): Likewise. + +2013-09-04 Jan Hubicka <jh@suse.cz> + + * cgraphunit.c (walk_polymorphic_call_targets): Break out from ... + (analyze_functions): ... here. + +2013-09-04 Jan Hubicka <jh@suse.cz> + + PR middle-end/58201 + * cgraphunit.c (analyze_functions): Clear AUX fields + after processing; initialize assembler name has. + +2013-09-05 Jeff Law <law@redhat.com> + + * tree-ssa-threadedge.c (thread_around_empty_blocks): Renamed + from thread_around_empty_block. Record threading path into PATH. + Recurse if threading through the initial block is successful. + (thread_across_edge): Corresponding changes to slightly simplify. + +2013-09-05 James Greenhalgh <james.greenhalgh@arm.com> + + * config/aarch64/aarch64.md + (type): Remove frecpe, frecps, frecpx. + (aarch64_frecp<FRECP:frecp_suffix><mode>): Move to aarch64-simd.md, + fix to be a TARGET_SIMD instruction. + (aarch64_frecps): Remove. + * config/aarch64/aarch64-simd.md + (aarch64_frecp<FRECP:frecp_suffix><mode>): New, moved from aarch64.md + (aarch64_frecps<mode>): Handle all float/vector of float modes. + +2013-09-05 James Greenhalgh <james.greenhalgh@arm.com> + Sofiane Naci <sofiane.naci@arm.com> + + * config/arm/types.md (define_attr "type"): Expand "arlo_imm" + into "adr", "alu_imm", "alus_imm", "logic_imm", "logics_imm". + Expand "arlo_reg" into "adc_reg", "adc_imm", "adcs_reg", "adcs_imm", + "alu_ext", "alu_reg", "alus_ext", "alus_reg", "bfm", "csel", + "logic_reg", "logics_reg", "rev". Expand "arlo_shift" into + "alu_shift_imm", "alus_shift_imm", "logic_shift_imm", + "logics_shift_imm". Expand "arlo_shift_reg" into "alu_shift_reg", + "alus_shift_reg", "logic_shift_reg", "logics_shift_reg". Expand "clz" + into "clz, "rbit". Rename "shift" to "shift_imm". + * config/arm/arm.md (define_attr "core_cycles"): Update for attribute + changes. Update for attribute changes all occurrences of arlo_* and + shift* types. + * config/arm/arm-fixed.md: Update for attribute changes + all occurrences of arlo_* types. + * config/arm/thumb2.md: Update for attribute changes all occurrences + of arlo_* types. + * config/arm/arm.c (xscale_sched_adjust_cost): (rtx insn, rtx + (cortexa7_older_only): Likewise. + (cortexa7_younger): Likewise. + * config/arm/arm1020e.md (1020alu_op): Update for attribute changes. + (1020alu_shift_op): Likewise. + (1020alu_shift_reg_op): Likewise. + * config/arm/arm1026ejs.md (alu_op): Update for attribute changes. + (alu_shift_op): Likewise. + (alu_shift_reg_op): Likewise. + * config/arm/arm1136jfs.md (11_alu_op): Update for attribute changes. + (11_alu_shift_op): Likewise. + (11_alu_shift_reg_op): Likewise. + * config/arm/arm926ejs.md (9_alu_op): Update for attribute changes. + (9_alu_shift_reg_op): Likewise. + * config/arm/cortex-a15.md (cortex_a15_alu): Update for + attribute changes. + (cortex_a15_alu_shift): Likewise. + (cortex_a15_alu_shift_reg): Likewise. + * config/arm/cortex-a5.md (cortex_a5_alu): Update for + attribute changes. + (cortex_a5_alu_shift): Likewise. + * config/arm/cortex-a53.md (cortex_a53_alu): Update for + attribute changes. + (cortex_a53_alu_shift): Likewise. + * config/arm/cortex-a7.md (cortex_a7_alu_imm): Update for + attribute changes. + (cortex_a7_alu_reg): Likewise. + (cortex_a7_alu_shift): Likewise. + * config/arm/cortex-a8.md (cortex_a8_alu): Update for + attribute changes. + (cortex_a8_alu_shift): Likewise. + (cortex_a8_alu_shift_reg): Likewise. + * config/arm/cortex-a9.md (cortex_a9_dp): Update for attribute changes. + (cortex_a9_dp_shift): Likewise. + * config/arm/cortex-m4.md (cortex_m4_alu): Update for + attribute changes. + * config/arm/cortex-r4.md + (cortex_r4_alu): Update for attribute changes. + (cortex_r4_mov): Likewise. + (cortex_r4_alu_shift_reg): Likewise. + * config/arm/fa526.md (526_alu_op): Update for attribute changes. + (526_alu_shift_op): Likewise. + * config/arm/fa606te.md (606te_alu_op): Update for attribute changes. + * config/arm/fa626te.md (626te_alu_op): Update for attribute changes. + (626te_alu_shift_op): Likewise. + * config/arm/fa726te.md (726te_alu_op): Update for attribute changes. + (726te_alu_shift_op): Likewise. + (726te_alu_shift_reg_op): Likewise. + * config/arm/fmp626.md (mp626_alu_op): Update for attribute changes. + (mp626_alu_shift_op): Likewise. + * config/arm/marvell-pj4.md (pj4_alu): Update for attribute changes. + (pj4_alu_conds): Likewise. + (pj4_shift): Likewise. + (pj4_shift_conds): Likewise. + (pj4_alu_shift): Likewise. + (pj4_alu_shift_conds): Likewise. + * config/aarch64/aarch64.md: Update for attribute change + all occurrences of arlo_* and shift* types. + +2013-09-05 Mike Stump <mikestump@comcast.net> + + * tree.h: Move documentation for tree_function_decl to tree-core.h + with the declaration. + +2013-09-05 Peter Bergner <bergner@vnet.ibm.com> + + PR target/58139 + * reginfo.c (choose_hard_reg_mode): Scan through all mode classes + looking for widest mode. + +2013-09-05 Eric Botcazou <ebotcazou@adacore.com> + + * config.gcc (*-*-vxworks*): Do not override an existing extra_objs. + +2013-09-05 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58137 + * tree-vect-stmts.c (get_vectype_for_scalar_type_and_size): + Do not create vectors of pointers. + * tree-vect-loop.c (get_initial_def_for_induction): Use proper + types for the components of the vector initializer. + * tree-cfg.c (verify_gimple_assign_binary): Remove special-casing + allowing pointer vectors with PLUS_EXPR/MINUS_EXPR. + +2013-09-05 Martin Jambor <mjambor@suse.cz> + + * ipa-prop.c (remove_described_reference): Accept missing references, + return false if that hppens, otherwise return true. + (cgraph_node_for_jfunc): New function. + (try_decrement_rdesc_refcount): Likewise. + (try_make_edge_direct_simple_call): Use them. + (ipa_edge_removal_hook): Remove references from rdescs. + (ipa_edge_duplication_hook): Clone rdescs and their references + when the new edge has the same caller as the old one. + * cgraph.c (cgraph_resolve_speculation): Remove speculative + reference before removing any edges. + +2013-09-05 Richard Earnshaw <rearnsha@arm.com> + + * arm.c (thumb2_emit_strd_push): Rewrite to use pre-decrement on + initial store. + * thumb2.md (thumb2_storewb_parisi): New pattern. + +2013-09-05 Yufeng Zhang <yufeng.zhang@arm.com> + + * config/aarch64/aarch64-option-extensions.def: Add + AARCH64_OPT_EXTENSION of 'crc'. + * config/aarch64/aarch64.h (AARCH64_FL_CRC): New define. + (AARCH64_ISA_CRC): Ditto. + * doc/invoke.texi (-march and -mcpu feature modifiers): Add + description of the CRC extension. + +2013-09-05 Alexander Ivchenko <alexander.ivchenko@intel.com> + + * config/rs6000/linux64.h: Define OPTION_BIONIC and OPTION_UCLIBC. + * config/rs6000/linux.h: Ditto. + * alpha/linux.h: Ditto. + * config/bfin/uclinux.h: Define TARGET_LIBC_HAS_FUNCTION as + no_c99_libc_has_function. + * config/c6x/uclinux-elf.h: Ditto. + * config/lm32/uclinux-elf.h: Ditto. + * config/m68k/uclinux.h: Ditto. + * config/moxie/uclinux.h: Ditto. + * config.gcc (bfin*-linux-uclibc*): Add t-linux-android to tmake_file. + (crisv32-*-linux*, cris-*-linux*): Ditto. + * config/bfin/bfin.c: Include "tm_p.h". + +2013-09-05 Richard Biener <rguenther@suse.de> + + * tree-vect-loop.c (vect_analyze_loop_operations): Properly + check for a definition without a basic-block. + +2013-09-05 James Greenhalgh <james.greenhalgh@arm.com> + Sofiane Naci <sofiane.naci@arm.com> + + * config/aarch64/aarch64.md + (*movti_aarch64): Rename r_2_f and f_2_r. + (*movsf_aarch64): Likewise. + (*movdf_aarch64): Likewise. + (*movtf_aarch64): Likewise. + (aarch64_movdi_<mode>low): Likewise. + (aarch64_movdi_<mode>high): Likewise. + (aarch64_mov<mode>high_di): Likewise. + (aarch64_mov<mode>low_di): Likewise. + (aarch64_movtilow_tilow): Likewise. + * config/arm/arm.md (attribute "neon_type"): Delete. Move attribute + values to config/arm/types.md + (attribute "conds"): Update for attribute change. + (anddi3_insn): Likewise. + (iordi3_insn): Likewise. + (xordi3_insn): Likewise. + (one_cmpldi2): Likewise. + * config/arm/types.md (type): Add Neon types. + * config/arm/neon.md (neon_mov<mode>): Remove "neon_type" attribute, + use "type" attribute. + (movmisalign<mode>_neon_store): Likewise. + (movmisalign<mode>_neon_load): Likewise. + (vec_set<mode>_internal): Likewise. + (vec_setv2di_internal): Likewise. + (vec_extract<mode>): Likewise. + (vec_extractv2di): Likewise. + (add<mode>3_neon): Likewise. + (adddi3_neon): Likewise. + (sub<mode>3_neon): Likewise. + (subdi3_neon): Likewise. + (mul<mode>3_neon): Likewise. + (mul<mode>3add<mode>_neon): Likewise. + (mul<mode>3neg<mode>add<mode>_neon): Likewise. + (fma<VCVTF:mode>4)): Likewise. + (fma<VCVTF:mode>4_intrinsic): Likewise. + (fmsub<VCVTF:mode>4)): Likewise. + (fmsub<VCVTF:mode>4_intrinsic): Likewise. + (neon_vrint<NEON_VRINT:nvrint_variant><VCVTF:mode>): Likewise. + (ior<mode>3): Likewise. + (and<mode>3): Likewise. + (anddi3_neon): Likewise. + (orn<mode>3_neon): Likewise. + (orndi3_neon): Likewise. + (bic<mode>3_neon): Likewise. + (bicdi3_neon): Likewise. + (xor<mode>3): Likewise. + (one_cmpl<mode>2): Likewise. + (abs<mode>2): Likewise. + (neg<mode>2): Likewise. + (umin<mode>3_neon): Likewise. + (umax<mode>3_neon): Likewise. + (smin<mode>3_neon): Likewise. + (smax<mode>3_neon): Likewise. + (vashl<mode>3): Likewise. + (vashr<mode>3_imm): Likewise. + (vlshr<mode>3_imm): Likewise. + (ashl<mode>3_signed): Likewise. + (ashl<mode>3_unsigned): Likewise. + (neon_load_count): Likewise. + (ashldi3_neon_noclobber): Likewise. + (signed_shift_di3_neon): Likewise. + (unsigned_shift_di3_neon): Likewise. + (ashrdi3_neon_imm_noclobber): Likewise. + (lshrdi3_neon_imm_noclobber): Likewise. + (widen_ssum<mode>3): Likewise. + (widen_usum<mode>3): Likewise. + (quad_halves_<code>v4si): Likewise. + (quad_halves_<code>v4sf): Likewise. + (quad_halves_<code>v8hi): Likewise. + (quad_halves_<code>v16qi): Likewise. + (reduc_splus_v2di): Likewise. + (neon_vpadd_internal<mode>): Likewise. + (neon_vpsmin<mode>): Likewise. + (neon_vpsmax<mode>): Likewise. + (neon_vpumin<mode>): Likewise. + (neon_vpumax<mode>): Likewise. + (ss_add<mode>_neon): Likewise. + (us_add<mode>_neon): Likewise. + (ss_sub<mode>_neon): Likewise. + (us_sub<mode>_neon): Likewise. + (neon_vadd<mode>_unspec): Likewise. + (neon_vaddl<mode>): Likewise. + (neon_vaddw<mode>): Likewise. + (neon_vhadd<mode>): Likewise. + (neon_vqadd<mode>): Likewise. + (neon_vaddhn<mode>): Likewise. + (neon_vmul<mode>): Likewise. + (neon_vmla<mode>): Likewise. + (neon_vmlal<mode>): Likewise. + (neon_vmls<mode>): Likewise. + (neon_vmlsl<mode>): Likewise. + (neon_vqdmulh<mode>): Likewise. + (neon_vqdmlal<mode>): Likewise. + (neon_vqdmlsl<mode>): Likewise. + (neon_vmull<mode>): Likewise. + (neon_vqdmull<mode>): Likewise. + (neon_vsub<mode>_unspec): Likewise. + (neon_vsubl<mode>): Likewise. + (neon_vsubw<mode>): Likewise. + (neon_vqsub<mode>): Likewise. + (neon_vhsub<mode>): Likewise. + (neon_vsubhn<mode>): Likewise. + (neon_vceq<mode>): Likewise. + (neon_vcge<mode>): Likewise. + (neon_vcgeu<mode>): Likewise. + (neon_vcgt<mode>): Likewise. + (neon_vcgtu<mode>): Likewise. + (neon_vcle<mode>): Likewise. + (neon_vclt<mode>): Likewise. + (neon_vcage<mode>): Likewise. + (neon_vcagt<mode>): Likewise. + (neon_vtst<mode>): Likewise. + (neon_vabd<mode>): Likewise. + (neon_vabdl<mode>): Likewise. + (neon_vaba<mode>): Likewise. + (neon_vabal<mode>): Likewise. + (neon_vmax<mode>): Likewise. + (neon_vmin<mode>): Likewise. + (neon_vpaddl<mode>): Likewise. + (neon_vpadal<mode>): Likewise. + (neon_vpmax<mode>): Likewise. + (neon_vpmin<mode>): Likewise. + (neon_vrecps<mode>): Likewise. + (neon_vrsqrts<mode>): Likewise. + (neon_vqabs<mode>): Likewise. + (neon_vqneg<mode>): Likewise. + (neon_vcls<mode>): Likewise. + (clz<mode>2): Likewise. + (popcount<mode>2): Likewise. + (neon_vrecpe): Likewise. + (neon_vrsqrte): Likewise. + (neon_vget_lane<mode>_sext_internal): Likewise. + (neon_vget_lane<mode>_zext_internal): Likewise. + (neon_vdup_n<mode>): Likewise. + (neon_vdup_nv2di): Likewise. + (neon_vdpu_lane<mode>_internal): Likewise. + (neon_vswp<mode>): Likewise. + (float<mode><V_cvtto>2): Likewise. + (floatuns<mode><V_cvtto>2): Likewise. + (fix_trunc<mode><V_cvtto>)2): Likewise + (fixuns_trunc<mode><V_cvtto)2): Likewise. + (neon_vcvt<mode>): Likewise. + (neon_vcvtv4sfv4hf): Likewise. + (neon_vcvtv4hfv4sf): Likewise. + (neon_vcvt_n<mode>): Likewise. + (neon_vmovn<mode>): Likewise. + (neon_vqmovn<mode>): Likewise. + (neon_vqmovun<mode>): Likewise. + (neon_vmovl<mode>): Likewise. + (neon_vmul_lane<mode>): Likewise. + (neon_vmull_lane<mode>): Likewise. + (neon_vqdmull_lane<mode>): Likewise. + (neon_vqdmulh_lane<mode>): Likewise. + (neon_vmla_lane<mode>): Likewise. + (neon_vmlal_lane<mode>): Likewise. + (neon_vqdmlal_lane<mode>): Likewise. + (neon_vmls_lane<mode>): Likewise. + (neon_vmlsl_lane<mode>): Likewise. + (neon_vqdmlsl_lane<mode>): Likewise. + (neon_vext<mode>): Likewise. + (neon_vrev64<mode>): Likewise. + (neon_vrev32<mode>): Likewise. + (neon_vrev16<mode>): Likewise. + (neon_vbsl<mode>_internal): Likewise. + (neon_vshl<mode>): Likewise. + (neon_vqshl<mode>): Likewise. + (neon_vshr_n<mode>): Likewise. + (neon_vshrn_n<mode>): Likewise. + (neon_vqshrn_n<mode>): Likewise. + (neon_vqshrun_n<mode>): Likewise. + (neon_vshl_n<mode>): Likewise. + (neon_vqshl_n<mode>): Likewise. + (neon_vqshlu_n<mode>): Likewise. + (neon_vshll_n<mode>): Likewise. + (neon_vsra_n<mode>): Likewise. + (neon_vsri_n<mode>): Likewise. + (neon_vsli_n<mode>): Likewise. + (neon_vtbl1v8qi): Likewise. + (neon_vtbl2v8qi): Likewise. + (neon_vtbl3v8qi): Likewise. + (neon_vtbl4v8qi): Likewise. + (neon_vtbx1v8qi): Likewise. + (neon_vtbx2v8qi): Likewise. + (neon_vtbx3v8qi): Likewise. + (neon_vtbx4v8qi): Likewise. + (neon_vtrn<mode>_internal): Likewise. + (neon_vzip<mode>_internal): Likewise. + (neon_vuzp<mode>_internal): Likewise. + (neon_vld1<mode>): Likewise. + (neon_vld1_lane<mode>): Likewise. + (neon_vld1_dup<mode>): Likewise. + (neon_vld1_dupv2di): Likewise. + (neon_vst1<mode>): Likewise. + (neon_vst1_lane<mode>): Likewise. + (neon_vld2<mode>): Likewise. + (neon_vld2_lane<mode>): Likewise. + (neon_vld2_dup<mode>): Likewise. + (neon_vst2<mode>): Likewise. + (neon_vst2_lane<mode>): Likewise. + (neon_vld3<mode>): Likewise. + (neon_vld3qa<mode>): Likewise. + (neon_vld3qb<mode>): Likewise. + (neon_vld3_lane<mode>): Likewise. + (neon_vld3_dup<mode>): Likewise. + (neon_vst3<mode>): Likewise. + (neon_vst3qa<mode>): Likewise. + (neon_vst3qb<mode>): Likewise. + (neon_vst3_lane<mode>): Likewise. + (neon_vld4<mode>): Likewise. + (neon_vld4qa<mode>): Likewise. + (neon_vld4qb<mode>): Likewise. + (neon_vld4_lane<mode>): Likewise. + (neon_vld4_dup<mode>): Likewise. + (neon_vst4<mode>): Likewise. + (neon_vst4qa<mode>): Likewise. + (neon_vst4qb<mode>): Likewise. + (neon_vst4_lane<mode>): Likewise. + (neon_vec_unpack<US>_lo_<mode>): Likewise. + (neon_vec_unpack<US>_hi_<mode>): Likewise. + (neon_vec_<US>mult_lo_<mode>): Likewise. + (neon_vec_<US>mult_hi_<mode>): Likewise. + (neon_vec_<US>shiftl_<mode>): Likewise. + (neon_unpack<US>_<mode>): Likewise. + (neon_vec_<US>mult_<mode>): Likewise. + (vec_pack_trunc_<mode>): Likewise. + (neon_vec_pack_trunk_<mode>): Likewise. + (neon_vabd<mode>_2): Likewise. + (neon_vabd<mode>_3): Likewise. + * config/arm/vfp.md (arm_movsi_vfp): Update for attribute changes. + (thumb2_movsi_vfp): Likewise. + (movdi_vfp): Likewise. + (movdi_vfp_cortexa8): Likewise. + (movhf_vfp_neon): Likewise. + (movhf_vfp): Likewiwse. + (movsf_vfp): Likewiwse. + (thumb2_movsf_vfp): Likewiwse. + (movdf_vfp): Likewise. + (thumb2_movdf_vfp): Likewise. + (movsfcc_vfp): Likewise. + (thumb2_movsfcc_vfp): Likewise. + (movdfcc_vfp): Likewise. + (thumb2_movdfcc_vfp): Likewise. + * config/arm/arm.c (cortexa7_older_only): Update for attribute change. + * config/arm/arm1020e.md (v10_c2v): Update for attribute change. + (v10_v2c): Likewise. + * config/arm/cortex-a15-neon.md (cortex_a15_neon_int_1): Update for + attribute change. + (cortex_a15_neon_int_2): Likewise. + (cortex_a15_neon_int_3): Likewise. + (cortex_a15_neon_int_4): Likewise. + (cortex_a15_neon_int_5): Likewise. + (cortex_a15_neon_vqneg_vqabs): Likewise. + (cortex_a15_neon_vmov): Likewise. + (cortex_a15_neon_vaba): Likewise. + (cortex_a15_neon_vaba_qqq): Likewise. + (cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long): Likewise. + (cortex_a15_neon_mul_qqq_8_16_32_ddd_32): Likewise. + (cortex_a15_neon_mul_qdd_64_32_long_qqd_16_ddd_32_\ + scalar_64_32_long_scalar): Likewise. + (cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long): Likewise. + (cortex_a15_neon_mla_qqq_8_16): Likewise. + (cortex_a15_neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_\ + lotype_qdd_64_32_long): Likewise. + (cortex_a15_neon_mla_qqq_32_qqd_32_scalar): Likewise. + (cortex_a15_neon_mul_ddd_16_scalar_32_16_long_scalar): Likewise. + (cortex_a15_neon_mul_qqd_32_scalar): Likewise. + (cortex_a15_neon_mla_ddd_16_scalar_qdd_32_16_long_scalar): Likewise. + (cortex_a15_neon_shift_1): Likewise. + (cortex_a15_neon_shift_2): Likewise. + (cortex_a15_neon_shift_3): Likewise. + (cortex_a15_neon_vshl_ddd): Likewise. + (cortex_a15_neon_vqshl_vrshl_vqrshl_qqq): Likewise. + (cortex_a15_neon_vsra_vrsra): Likewise. + (cortex_a15_neon_fp_vadd_ddd_vabs_dd): Likewise. + (cortex_a15_neon_fp_vadd_qqq_vabs_qq): Likewise. + (cortex_a15_neon_fp_vmul_ddd): Likewise. + (cortex_a15_neon_fp_vmul_qqd): Likewise. + (cortex_a15_neon_fp_vmla_ddd): Likewise. + (cortex_a15_neon_fp_vmla_qqq): Likewise. + (cortex_a15_neon_fp_vmla_ddd_scalar): Likewise. + (cortex_a15_neon_fp_vmla_qqq_scalar): Likewise. + (cortex_a15_neon_fp_vrecps_vrsqrts_ddd): Likewise. + (cortex_a15_neon_fp_vrecps_vrsqrts_qqq): Likewise. + (cortex_a15_neon_bp_simple): Likewise. + (cortex_a15_neon_bp_2cycle): Likewise. + (cortex_a15_neon_bp_3cycle): Likewise. + (cortex_a15_neon_vld1_1_2_regs): Likewise. + (cortex_a15_neon_vld1_3_4_regs): Likewise. + (cortex_a15_neon_vld2_2_regs_vld1_vld2_all_lanes): Likewise. + (cortex_a15_neon_vld2_4_regs): Likewise. + (cortex_a15_neon_vld3_vld4): Likewise. + (cortex_a15_neon_vst1_1_2_regs_vst2_2_regs): Likewise. + (cortex_a15_neon_vst1_3_4_regs): Likewise. + (cortex_a15_neon_vst2_4_regs_vst3_vst4): Likewise. + (cortex_a15_neon_vst3_vst4): Likewise. + (cortex_a15_neon_vld1_vld2_lane): Likewise. + (cortex_a15_neon_vld3_vld4_lane" 10 + (cortex_a15_neon_vst1_vst2_lane): Likewise. + (cortex_a15_neon_vst3_vst4_lane): Likewise. + (cortex_a15_neon_vld3_vld4_all_lanes): Likewise. + (cortex_a15_neon_ldm_2): Likewise.0 + (cortex_a15_neon_stm_2): Likewise. + (cortex_a15_neon_mcr): Likewise. + (cortex_a15_neon_mcr_2_mcrr): Likewise. + (cortex_a15_neon_mrc): Likewise. + (cortex_a15_neon_mrrc): Likewise. + * config/arm/cortex-a15.md (cortex_a15_alu): Update for attribute + change. + (cortex_a15_alu_shift): Likewise. + (cortex_a15_alu_shift_reg): Likewise. + (cortex_a15_mult32): Likewise. + (cortex_a15_mult64): Likewise. + (cortex_a15_block): Likewise. + (cortex_a15_branch): Likewise. + (cortex_a15_load1): Likewise. + (cortex_a15_load3): Likewise. + (cortex_a15_store1): Likewise. + (cortex_a15_store3): Likewise. + (cortex_a15_call): Likewise. + * config/arm/cortex-a5.md (cortex_a5_r2f): Update for attribute change. + (cortex_a5_f2r): Likewise. + * config/arm/cortex-a53.md (cortex_a53_r2f): Update for attribute + change. + (cortex_a53_f2r): Likewise. + * config/arm/cortex-a7.md + (cortex_a7_branch): Update for attribute change. + (cortex_a7_call): Likewise. + (cortex_a7_alu_imm): Likewise. + (cortex_a7_alu_reg): Likewise. + (cortex_a7_alu_shift): Likewise. + (cortex_a7_mul): Likewise. + (cortex_a7_load1): Likewise. + (cortex_a7_store1): Likewise. + (cortex_a7_load2): Likewise. + (cortex_a7_store2): Likewise. + (cortex_a7_load3): Likewise. + (cortex_a7_store3): Likewise. + (cortex_a7_load4): Likewise. + (cortex_a7_store4): Likewise. + (cortex_a7_fpalu): Likewise. + (cortex_a7_fconst): Likewise. + (cortex_a7_fpmuls): Likewise. + (cortex_a7_neon_mul): Likewise. + (cortex_a7_fpmacs): Likewise. + (cortex_a7_neon_mla: Likewise. + (cortex_a7_fpmuld: Likewise. + (cortex_a7_fpmacd: Likewise. + (cortex_a7_fpfmad: Likewise. + (cortex_a7_fdivs: Likewise. + (cortex_a7_fdivd: Likewise. + (cortex_a7_r2f: Likewise. + (cortex_a7_f2r: Likewise. + (cortex_a7_f_flags: Likewise. + (cortex_a7_f_loads: Likewise. + (cortex_a7_f_loadd: Likewise. + (cortex_a7_f_stores: Likewise. + (cortex_a7_f_stored: Likewise. + (cortex_a7_neon): Likewise. + * config/arm/cortex-a8-neon.md + (cortex_a8_neon_mrc): Update for attribute change. + (cortex_a8_neon_mrrc): Likewise. + (cortex_a8_neon_int_1): Likewise. + (cortex_a8_neon_int_2): Likewise. + (cortex_a8_neon_int_3): Likewise. + (cortex_a8_neon_int_4): Likewise. + (cortex_a8_neon_int_5): Likewise. + (cortex_a8_neon_vqneg_vqabs): Likewise. + (cortex_a8_neon_vmov): Likewise. + (cortex_a8_neon_vaba): Likewise. + (cortex_a8_neon_vaba_qqq): Likewise. + (cortex_a8_neon_vsma): Likewise. + (cortex_a8_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long): Likewise. + (cortex_a8_neon_mul_qqq_8_16_32_ddd_32): Likewise. + (cortex_a8_neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_\ + long_scalar): Likewise. + (cortex_a8_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long): Likewise. + (cortex_a8_neon_mla_qqq_8_16): Likewise. + (cortex_a8_neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_\ + long_scalar_qdd_64_32_long): Likewise. + (cortex_a8_neon_mla_qqq_32_qqd_32_scalar): Likewise. + (cortex_a8_neon_mul_ddd_16_scalar_32_16_long_scalar): Likewise. + (cortex_a8_neon_mul_qqd_32_scalar): Likewise. + (cortex_a8_neon_mla_ddd_16_scalar_qdd_32_16_long_scalar): Likewise. + (cortex_a8_neon_shift_1): Likewise. + (cortex_a8_neon_shift_2): Likewise. + (cortex_a8_neon_shift_3): Likewise. + (cortex_a8_neon_vshl_ddd): Likewise. + (cortex_a8_neon_vqshl_vrshl_vqrshl_qqq): Likewise. + (cortex_a8_neon_vsra_vrsra): Likewise. + (cortex_a8_neon_fp_vadd_ddd_vabs_dd): Likewise. + (cortex_a8_neon_fp_vadd_qqq_vabs_qq): Likewise. + (cortex_a8_neon_fp_vsum): Likewise. + (cortex_a8_neon_fp_vmul_ddd): Likewise. + (cortex_a8_neon_fp_vmul_qqd): Likewise. + (cortex_a8_neon_fp_vmla_ddd): Likewise. + (cortex_a8_neon_fp_vmla_qqq): Likewise. + (cortex_a8_neon_fp_vmla_ddd_scalar): Likewise. + (cortex_a8_neon_fp_vmla_qqq_scalar): Likewise. + (cortex_a8_neon_fp_vrecps_vrsqrts_ddd): Likewise. + (cortex_a8_neon_fp_vrecps_vrsqrts_qqq): Likewise. + (cortex_a8_neon_bp_simple): Likewise. + (cortex_a8_neon_bp_2cycle): Likewise. + (cortex_a8_neon_bp_3cycle): Likewise. + (cortex_a8_neon_ldr): Likewise. + (cortex_a8_neon_str): Likewise. + (cortex_a8_neon_vld1_1_2_regs): Likewise. + (cortex_a8_neon_vld1_3_4_regs): Likewise. + (cortex_a8_neon_vld2_2_regs_vld1_vld2_all_lanes): Likewise. + (cortex_a8_neon_vld2_4_regs): Likewise. + (cortex_a8_neon_vld3_vld4): Likewise. + (cortex_a8_neon_vst1_1_2_regs_vst2_2_regs): Likewise. + (cortex_a8_neon_vst1_3_4_regs): Likewise. + (cortex_a8_neon_vst2_4_regs_vst3_vst4): Likewise. + (cortex_a8_neon_vst3_vst4): Likewise. + (cortex_a8_neon_vld1_vld2_lane): Likewise. + (cortex_a8_neon_vld3_vld4_lane): Likewise. + (cortex_a8_neon_vst1_vst2_lane): Likewise. + (cortex_a8_neon_vst3_vst4_lane): Likewise. + (cortex_a8_neon_vld3_vld4_all_lanes): Likewise. + (cortex_a8_neon_mcr): Likewise. + (cortex_a8_neon_mcr_2_mcrr): Likewise. + * config/arm/cortex-a8.md (cortex_a8_alu): Update for attribute change. + * config/arm/cortex-a9-neon.md (ca9_neon_mrc): Update for attribute + change. + (ca9_neon_mrrc): Likewise. + (cortex_a9_neon_int_1): Likewise. + (cortex_a9_neon_int_2): Likewise. + (cortex_a9_neon_int_3): Likewise. + (cortex_a9_neon_int_4): Likewise. + (cortex_a9_neon_int_5): Likewise. + (cortex_a9_neon_vqneg_vqabs): Likewise. + (cortex_a9_neon_vmov): Likewise. + (cortex_a9_neon_vaba): Likewise. + (cortex_a9_neon_vaba_qqq): Likewise. + (cortex_a9_neon_vsma): Likewise. + (cortex_a9_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long): Likewise. + (cortex_a9_neon_mul_qqq_8_16_32_ddd_32): Likewise. + (cortex_a9_neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_\ + long_scalar): Likewise. + (cortex_a9_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long): Likewise. + (cortex_a9_neon_mla_qqq_8_16): Likewise. + (cortex_a9_neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_\ + long_scalar_qdd_64_32_long): Likewise. + (cortex_a9_neon_mla_qqq_32_qqd_32_scalar): Likewise. + (cortex_a9_neon_mul_ddd_16_scalar_32_16_long_scalar): Likewise. + (cortex_a9_neon_mul_qqd_32_scalar): Likewise. + (cortex_a9_neon_mla_ddd_16_scalar_qdd_32_16_long_scalar): Likewise. + (cortex_a9_neon_shift_1): Likewise. + (cortex_a9_neon_shift_2): Likewise. + (cortex_a9_neon_shift_3): Likewise. + (cortex_a9_neon_vshl_ddd): Likewise. + (cortex_a9_neon_vqshl_vrshl_vqrshl_qqq): Likewise. + (cortex_a9_neon_vsra_vrsra): Likewise. + (cortex_a9_neon_fp_vadd_ddd_vabs_dd): Likewise. + (cortex_a9_neon_fp_vadd_qqq_vabs_qq): Likewise. + (cortex_a9_neon_fp_vsum): Likewise. + (cortex_a9_neon_fp_vmul_ddd): Likewise. + (cortex_a9_neon_fp_vmul_qqd): Likewise. + (cortex_a9_neon_fp_vmla_ddd): Likewise. + (cortex_a9_neon_fp_vmla_qqq): Likewise. + (cortex_a9_neon_fp_vmla_ddd_scalar): Likewise. + (cortex_a9_neon_fp_vmla_qqq_scalar): Likewise. + (cortex_a9_neon_fp_vrecps_vrsqrts_ddd): Likewise. + (cortex_a9_neon_fp_vrecps_vrsqrts_qqq): Likewise. + (cortex_a9_neon_bp_simple): Likewise. + (cortex_a9_neon_bp_2cycle): Likewise. + (cortex_a9_neon_bp_3cycle): Likewise. + (cortex_a9_neon_ldr): Likewise. + (cortex_a9_neon_str): Likewise. + (cortex_a9_neon_vld1_1_2_regs): Likewise. + (cortex_a9_neon_vld1_3_4_regs): Likewise. + (cortex_a9_neon_vld2_2_regs_vld1_vld2_all_lanes): Likewise. + (cortex_a9_neon_vld2_4_regs): Likewise. + (cortex_a9_neon_vld3_vld4): Likewise. + (cortex_a9_neon_vst1_1_2_regs_vst2_2_regs): Likewise. + (cortex_a9_neon_vst1_3_4_regs): Likewise. + (cortex_a9_neon_vst2_4_regs_vst3_vst4): Likewise. + (cortex_a9_neon_vst3_vst4): Likewise. + (cortex_a9_neon_vld1_vld2_lane): Likewise. + (cortex_a9_neon_vld3_vld4_lane): Likewise. + (cortex_a9_neon_vst1_vst2_lane): Likewise. + (cortex_a9_neon_vst3_vst4_lane): Likewise. + (cortex_a9_neon_vld3_vld4_all_lanes): Likewise. + (cortex_a9_neon_mcr): Likewise. + (cortex_a9_neon_mcr_2_mcrr): Likewise. + * config/arm/cortex-a9.md (cortex_a9_dp): Update for attribute change. + (cortex_a9_fps): Likewise. + * config/arm/cortex-m4-fpu.md (cortex_m4_vmov_2): Update for attribute + change. + (cortex_m4_fmuls): Likewise. + * config/arm/cortex-r4f.md (cortex_r4_mcr): Update for attribute + change. + (cortex_r4_mrc): Likewise. + * config/arm/iterators.md: Update comment referring to neon_type. + * config/arm/iwmmxt.md (iwmmxt_arm_movdi): Update for attribute change. + (iwmmxt_movsi_insn): Likewise. + * config/arm/marvell-pj4.md (pj4_vfp_to_core): Update for + attribute change. + (pj4_core_to_vfp): Likewise. + * config/arm/neon-schedgen.ml (emit_insn_reservations): Update for + attribute change. + * config/arm/vfp11.md (vfp_fload): Update for attribute change. + (vfp_fstore): Likewise. + * doc/md.texi: Change references to neon_type to refer to type. + +2013-09-04 Dodji Seketeli <dodji@redhat.com> + + * tree.h (DECL_BUILT_IN): Fix typo in comment. + +2013-09-04 David Edelsohn <dje.gcc@gmail.com> + + * config/rs6000/rs6000.h (ASM_OUTPUT_DEF_FROM_DECLS): Only emit + lglobl if not weak. + +2013-09-04 Easwaran Raman <eraman@google.com> + + PR middle-end/57370 + * tree-ssa-reassoc.c (get_stmt_uid_with_default): New function, + (build_and_add_sum): Use it. + (appears_later_in_bb): Simplify code. + 2013-09-04 Teresa Johnson <tejohnson@google.com> * dumpfile.c (dump_finish): Don't close stderr/stdout. @@ -190,19 +3040,20 @@ cgraph_propagate_frequency_1, cgraph_propagate_frequency): Move to ipa-profile.c; replace cgraph_ by ipa_ prefix. * cgraph.h (cgraph_propagate_frequency): Remove. - * ipa-inline-analysis.c: Include ipa-utils.h; drop duplicated cfgloop.h. + * ipa-inline-analysis.c: Include ipa-utils.h; + drop duplicated cfgloop.h. (inline_update_callee_summaries): Update. * ipa-profile.c: New file. * ipa-utils.h (ipa_propagate_frequency): Declare. * ipa.c: Do not include pointer-set.h, hash-table.h, lto-streamer.h, - data-streamer.h, value-prof.h + data-streamer.h, value-prof.h. (symtab_remove_unreachable_nodes): Update profile. (struct histogram_entry, histogram, histogram_pool, histogram_hash, account_time_size, cmp_counts, dump_histogram, ipa_profile_generate_summary, ipa_profile_write_summary, ipa_profile_read_summary, ipa_profile, gate_ipa_profile, pass_data_ipa_profile, pass_ipa_profile, make_pass_ipa_profile): - Move to ipa-profile.c + Move to ipa-profile.c. 2013-09-01 John David Anglin <danglin@gcc.gnu.org> @@ -224,7 +3075,7 @@ value range profiling is available. * passes.def (pass_ipa_devirt): Add. * timever.def (TV_IPA_DEVIRT): New timevar. - * tree-pass.h (make_pass_ipa_devirt): + * tree-pass.h (make_pass_ipa_devirt): 2013-09-01 Iain Sandoe <iain@codesourcery.com> @@ -987,13 +3838,13 @@ 2013-08-23 Kirill Yukhin <kirill.yukhin@intel.com> - * gcc/config/i386/predicates.md (ext_sse_reg_operand): New. - * gcc/config/i386/i386.md (*movti_internal): Use + * config/i386/predicates.md (ext_sse_reg_operand): New. + * config/i386/i386.md (*movti_internal): Use predicate to determine if EVEX is needed. (*movsi_internal): Ditto. (*movdf_internal): Ditto. (*movsf_internal): Ditto. - * gcc/config/i386/mmx.md (*mov<mode>_internal): Ditto. + * config/i386/mmx.md (*mov<mode>_internal): Ditto. 2013-08-23 Jakub Jelinek <jakub@redhat.com> @@ -4941,7 +7792,7 @@ (ix86_save_reg): If the function contains a nonlocal label, save the PIC base reg. * config/darwin-protos.h (machopic_should_output_picbase_label): New. - * gcc/config/darwin.c (emitted_pic_label_num): New GTY. + * config/darwin.c (emitted_pic_label_num): New GTY. (update_pic_label_number_if_needed): New. (machopic_output_function_base_name): Adjust for nonlocal receiver case. @@ -7242,6 +10093,11 @@ (symtab_alias_ultimate_target): Simplify. * varpool.c (varpool_create_variable_alias): Set weakref flag. +2013-06-11 Tom de Vries <tom@codesourcery.com> + + * genautomata.c (gen_regexp_sequence): Handle els_num == -1. Handle + sequence_vect == NULL. + 2013-06-11 DJ Delorie <dj@redhat.com> * config/rl78/rl78.c (TARGET_UNWIND_WORD_MODE): Define. @@ -8295,11 +11151,11 @@ * config/i386/driver-i386.c (host_detect_local_cpu): Check movbe. - * gcc/config/i386/i386-c.c (ix86_target_macros_internal): New case + * config/i386/i386-c.c (ix86_target_macros_internal): New case PROCESSOR_SLM. (ix86_target_macros_internal): Likewise. - * gcc/config/i386/i386.c (slm_cost): New cost. + * config/i386/i386.c (slm_cost): New cost. (m_SLM): New macro flag. (initial_ix86_tune_features): Set m_SLM. (x86_accumulate_outgoing_args): Likewise. @@ -9133,7 +11989,7 @@ constraints.md instead of rs6000.h. Reorder w* constraints. Add wm, wn, wr documentation. - * gcc/config/rs6000/constraints.md (wm): New constraint for VSX + * config/rs6000/constraints.md (wm): New constraint for VSX registers if direct move instructions are enabled. (wn): New constraint for no registers. (wq): New constraint for quad word even GPR registers. @@ -9141,7 +11997,7 @@ (wv): New constraint if power8 vector instructions are enabled. (wQ): New constraint for quad word memory locations. - * gcc/config/rs6000/predicates.md (const_0_to_15_operand): New + * config/rs6000/predicates.md (const_0_to_15_operand): New constraint for 0..15 for crypto instructions. (gpc_reg_operand): If VSX allow registers in VSX registers as well as GPR and floating point registers. @@ -9154,17 +12010,17 @@ (quad_memory_operand): New predicate for quad memory operations. (reg_or_indexed_operand): New predicate for direct move support. - * gcc/config/rs6000/rs6000-cpus.def (ISA_2_5_MASKS_EMBEDDED): + * config/rs6000/rs6000-cpus.def (ISA_2_5_MASKS_EMBEDDED): Inherit from ISA_2_4_MASKS, not ISA_2_2_MASKS. (ISA_2_7_MASKS_SERVER): New mask for ISA 2.07 (i.e. power8). (POWERPC_MASKS): Add power8 options. (power8 cpu): Use ISA_2_7_MASKS_SERVER instead of specifying the various options. - * gcc/config/rs6000/rs6000-c.c (rs6000_target_modify_macros): + * config/rs6000/rs6000-c.c (rs6000_target_modify_macros): Define _ARCH_PWR8 and __POWER8_VECTOR__ for power8. - * gcc/config/rs6000/rs6000.opt (-mvsx-timode): Add documentation. + * config/rs6000/rs6000.opt (-mvsx-timode): Add documentation. (-mpower8-fusion): New power8 options. (-mpower8-fusion-sign): Likewise. (-mpower8-vector): Likewise. @@ -9172,8 +12028,7 @@ (-mdirect-move): Likewise. (-mquad-memory): Likewise. - * gcc/config/rs6000/rs6000.c (power8_cost): Initial definition for - power8. + * config/rs6000/rs6000.c (power8_cost): Initial definition for power8. (rs6000_hard_regno_mode_ok): Make PTImode only match even GPR registers. (rs6000_debug_reg_print): Print the base register class if -mdebug=reg. @@ -14296,21 +17151,20 @@ 2013-03-27 Alexander Ivchenko <alexander.ivchenko@intel.com> - * gcc/target.def (TARGET_HAS_IFUNC_P): New target hook. - * gcc/doc/tm.texi.in (TARGET_HAS_IFUNC_P): New. - * gcc/doc/tm.texi: Regenerate. - * gcc/targhooks.h (default_has_ifunc_p): New. - * gcc/targhooks.c (default_has_ifunc_p): Ditto. - * gcc/config/linux-protos.h: New file. - * gcc/config/linux-android.h (TARGET_HAS_IFUNC_P): Using version of - this hook for linux which disables support of indirect functions in - android. - * gcc/config/linux-android.c: New file. - * gcc/config/t-linux-android.c: Ditto. - * gcc/config.gcc: Added new object file linux-android.o. - * gcc/config/i386/i386.c (ix86_get_function_versions_dispatcher): + * target.def (TARGET_HAS_IFUNC_P): New target hook. + * doc/tm.texi.in (TARGET_HAS_IFUNC_P): New. + * doc/tm.texi: Regenerate. + * targhooks.h (default_has_ifunc_p): New. + * targhooks.c (default_has_ifunc_p): Ditto. + * config/linux-protos.h: New file. + * config/linux-android.h (TARGET_HAS_IFUNC_P): Using version of this + hook for linux which disables support of indirect functions in android. + * config/linux-android.c: New file. + * config/t-linux-android.c: Ditto. + * config.gcc: Added new object file linux-android.o. + * config/i386/i386.c (ix86_get_function_versions_dispatcher): Using TARGET_HAS_IFUNC hook instead of HAVE_GNU_INDIRECT_FUNCTION. - * gcc/varasm.c (do_assemble_alias): Likewise. + * varasm.c (do_assemble_alias): Likewise. * configure.ac: Define HAVE_GNU_INDIRECT_FUNCTION as zero if the target doesn't support indirect functions. * configure: Regenerate. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index c0a48555176..0f54f2b0175 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20130904 +20130920 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 1a775f467d6..b8d8a35e52e 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -947,6 +947,7 @@ TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \ $(BITMAP_H) sbitmap.h $(BASIC_BLOCK_H) $(GIMPLE_H) \ $(HASHTAB_H) $(CGRAPH_H) $(IPA_REFERENCE_H) \ tree-ssa-alias.h wide-int.h +TREE_SSA_H = tree-ssa.h $(TREE_FLOW_H) TREE_HASHER_H = tree-hasher.h $(HASH_TABLE_H) $(TREE_FLOW_H) TREE_SSA_LIVE_H = tree-ssa-live.h $(PARTITION_H) SSAEXPAND_H = ssaexpand.h $(TREE_SSA_LIVE_H) @@ -1320,7 +1321,6 @@ OBJS = \ lto-streamer-out.o \ lto-section-in.o \ lto-section-out.o \ - lto-symtab.o \ lto-opts.o \ lto-compress.o \ mcf.o \ @@ -2134,13 +2134,13 @@ gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(HASHTAB_H) $(SPLAY_TREE_H) $(OBSTACK_H) $(BITMAP_H) \ $(INPUT_H) $(TREE_H) $(RTL_H) $(FUNCTION_H) insn-config.h $(EXPR_H) \ hard-reg-set.h $(BASIC_BLOCK_H) cselib.h $(INSN_ADDR_H) $(OPTABS_H) \ - $(LIBFUNCS_H) debug.h $(GGC_H) $(CGRAPH_H) $(TREE_FLOW_H) reload.h \ + $(LIBFUNCS_H) debug.h $(GGC_H) $(CGRAPH_H) $(TREE_SSA_H) reload.h \ $(CPP_ID_DATA_H) tree-chrec.h $(EXCEPT_H) output.h \ $(CFGLOOP_H) $(TARGET_H) $(IPA_PROP_H) $(LTO_STREAMER_H) \ target-globals.h trans-mem.o : trans-mem.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(HASH_TABLE_H) \ - $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) $(TREE_PASS_H) $(TREE_INLINE_H) \ + $(TREE_H) $(GIMPLE_H) $(TREE_SSA_H) $(TREE_PASS_H) $(TREE_INLINE_H) \ $(DIAGNOSTIC_CORE_H) $(DEMANGLE_H) output.h $(TRANS_MEM_H) \ $(PARAMS_H) $(TARGET_H) langhooks.h \ $(GIMPLE_PRETTY_PRINT_H) $(CFGLOOP_H) \ @@ -2152,7 +2152,7 @@ ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ ggc-page.o: ggc-page.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ $(FLAGS_H) $(DIAGNOSTIC_CORE_H) $(GGC_H) $(TIMEVAR_H) $(TM_P_H) $(PARAMS_H) \ - $(TREE_FLOW_H) $(PLUGIN_H) $(GGC_INTERNAL_H) + $(TREE_SSA_H) $(PLUGIN_H) $(GGC_INTERNAL_H) ggc-none.o: ggc-none.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \ $(BCONFIG_H) @@ -2177,15 +2177,15 @@ data-streamer-out.o: data-streamer-out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ data-streamer.o: data-streamer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(DATA_STREAMER_H) gimple-streamer-in.o: gimple-streamer-in.c $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(GIMPLE_STREAMER_H) $(TREE_FLOW_H) $(DATA_STREAMER_H) \ + coretypes.h $(GIMPLE_STREAMER_H) $(TREE_SSA_H) $(DATA_STREAMER_H) \ $(TREE_STREAMER_H) $(DIAGNOSTIC_H) gimple-streamer-out.o: gimple-streamer-out.c $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(GIMPLE_STREAMER_H) $(DATA_STREAMER_H) $(TREE_FLOW_H) \ + coretypes.h $(GIMPLE_STREAMER_H) $(DATA_STREAMER_H) $(TREE_SSA_H) \ $(LTO_STREAMER_H) $(TREE_STREAMER_H) tree-streamer.o: tree-streamer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TREE_STREAMER_H) $(STREAMER_HOOKS_H) tree-streamer-in.o: tree-streamer-in.c $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(DIAGNOSTIC_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_STREAMER_H) \ + coretypes.h $(DIAGNOSTIC_H) $(TREE_H) $(TREE_SSA_H) $(TREE_STREAMER_H) \ $(DATA_STREAMER_H) $(STREAMER_HOOKS_H) $(LTO_STREAMER_H) tree-streamer-out.o: tree-streamer-out.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(DIAGNOSTIC_H) $(TREE_STREAMER_H) $(DATA_STREAMER_H) \ @@ -2198,7 +2198,7 @@ lto-cgraph.o: lto-cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TREE_FLOW_H) $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_CORE_H) \ $(EXCEPT_H) $(TIMEVAR_H) pointer-set.h $(LTO_STREAMER_H) \ $(GCOV_IO_H) $(DATA_STREAMER_H) $(TREE_STREAMER_H) $(TREE_PASS_H) \ - profile.h $(CONTEXT_H) $(PASS_MANAGER_H) + profile.h $(CONTEXT_H) $(PASS_MANAGER_H) ipa-utils.h lto-streamer-in.o: lto-streamer-in.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) toplev.h $(DIAGNOSTIC_CORE_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) \ input.h $(HASHTAB_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TREE_PASS_H) \ @@ -2223,15 +2223,12 @@ lto-section-out.o : lto-section-out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(EXCEPT_H) pointer-set.h \ $(BITMAP_H) langhooks.h $(LTO_STREAMER_H) lto-compress.h \ $(DATA_STREAMER_H) -lto-symtab.o: lto-symtab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TREE_H) $(GIMPLE_H) $(GGC_H) $(HASHTAB_H) \ - $(LTO_STREAMER_H) $(LINKER_PLUGIN_API_H) lto-opts.o: lto-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ $(HASHTAB_H) $(GGC_H) $(BITMAP_H) $(FLAGS_H) $(OPTS_H) $(OPTIONS_H) \ $(COMMON_TARGET_H) $(DIAGNOSTIC_H) $(LTO_STREAMER_H) lto-streamer.o: lto-streamer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TREE_H) $(GIMPLE_H) $(BITMAP_H) $(LTO_STREAMER_H) $(FLAGS_H) \ - $(TREE_FLOW_H) $(DIAGNOSTIC_CORE_H) $(LTO_SYMTAB_H) toplev.h \ + $(TREE_SSA_H) $(DIAGNOSTIC_CORE_H) $(LTO_SYMTAB_H) toplev.h \ $(DIAGNOSTIC_CORE_H) $(STREAMER_HOOKS_H) langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TIMEVAR_H) \ $(TREE_H) toplev.h $(DIAGNOSTIC_CORE_H) $(TREE_INLINE_H) $(RTL_H) insn-config.h \ @@ -2240,13 +2237,13 @@ langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TIMEVAR_ test-dump.o : test-dump.c $(CONFIG_H) $(SYSTEM_H) $(CORETYPES_H) \ $(BITMAP_H) sbitmap.h sreal.h $(TREE_H) $(CXX_PARSER_H) $(DWARF2OUT_H) \ $(GIMPLE_PRETTY_PRINT_H) $(BASIC_BLOCK_H) insn-config.h $(LRA_INT.H) \ - $(SEL_SCHED_DUMP_H) $(IRA_INT_H) $(TREE_DATA_REF_H) $(TREE_FLOW_H) \ + $(SEL_SCHED_DUMP_H) $(IRA_INT_H) $(TREE_DATA_REF_H) $(TREE_SSA_H) \ $(TREE_SSA_LIVE_H) tree-ssa-alias.h $(OMEGA_H) $(RTL_H) tree.o: tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ all-tree.def $(FLAGS_H) $(FUNCTION_H) $(PARAMS_H) \ toplev.h $(DIAGNOSTIC_CORE_H) $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) \ langhooks.h gt-tree.h $(TREE_INLINE_H) tree-iterator.h \ - $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(OBSTACK_H) pointer-set.h \ + $(BASIC_BLOCK_H) $(TREE_SSA_H) $(OBSTACK_H) pointer-set.h \ $(TREE_PASS_H) $(LANGHOOKS_DEF_H) $(DIAGNOSTIC_H) $(CGRAPH_H) \ $(EXCEPT_H) debug.h intl.h tree-diagnostic.h $(TREE_PRETTY_PRINT_H) \ $(COMMON_TARGET_H) wide-int.h @@ -2257,12 +2254,12 @@ tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(RTL_H) $(FLAGS_H) $(PARAMS_H) $(INPUT_H) insn-config.h \ $(HASHTAB_H) langhooks.h $(TREE_INLINE_H) $(CGRAPH_H) \ intl.h $(FUNCTION_H) $(GIMPLE_H) $(CFGLOOP_H) \ - debug.h $(DIAGNOSTIC_H) $(EXCEPT_H) $(TREE_FLOW_H) tree-iterator.h tree-mudflap.h \ + debug.h $(DIAGNOSTIC_H) $(EXCEPT_H) $(TREE_SSA_H) tree-iterator.h tree-mudflap.h \ $(IPA_PROP_H) value-prof.h $(TREE_PASS_H) $(TARGET_H) \ $(TREE_PRETTY_PRINT_H) print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ $(TM_H) $(TREE_H) $(GGC_H) langhooks.h tree-iterator.h \ - $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(GIMPLE_PRETTY_PRINT_H) $(TREE_DUMP_H) \ + $(DIAGNOSTIC_H) $(TREE_SSA_H) $(GIMPLE_PRETTY_PRINT_H) $(TREE_DUMP_H) \ wide-int-print.h stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(PARAMS_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) $(RTL_H) \ @@ -2270,14 +2267,14 @@ stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(DIAGNOSTIC_CORE_H) $(CGRAPH_H) $(TREE_INLINE_H) $(TREE_DUMP_H) $(GIMPLE_H) asan.o : asan.c asan.h $(CONFIG_H) $(SYSTEM_H) $(GIMPLE_H) \ output.h coretypes.h $(GIMPLE_PRETTY_PRINT_H) $(CFGLOOP_H) \ - tree-iterator.h $(TREE_FLOW_H) $(TREE_PASS_H) \ + tree-iterator.h $(TREE_SSA_H) $(TREE_PASS_H) \ $(TARGET_H) $(EXPR_H) $(OPTABS_H) $(TM_P_H) langhooks.h \ $(HASH_TABLE_H) alloc-pool.h tsan.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \ $(GIMPLE_H) $(DIAGNOSTIC_H) langhooks.h \ $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(CGRAPH_H) $(GGC_H) \ $(BASIC_BLOCK_H) $(FLAGS_H) $(FUNCTION_H) \ - $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) tree-iterator.h \ + $(TM_P_H) $(TREE_SSA_H) $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) tree-iterator.h \ intl.h cfghooks.h output.h options.h $(C_COMMON_H) tsan.h asan.h \ tree-ssa-propagate.h ubsan.o : ubsan.c ubsan.h $(CONFIG_H) $(SYSTEM_H) $(GIMPLE_H) \ @@ -2286,130 +2283,130 @@ ubsan.o : ubsan.c ubsan.h $(CONFIG_H) $(SYSTEM_H) $(GIMPLE_H) \ tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \ $(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(BITMAP_H) \ $(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \ - $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) $(TREE_DUMP_H) $(HASH_TABLE_H) \ + $(TREE_H) $(TREE_SSA_H) $(TREE_INLINE_H) $(TREE_DUMP_H) $(HASH_TABLE_H) \ $(GIMPLE_H) $(FUNCTION_H) tree-ssa-sccvn.h \ $(CGRAPH_H) $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H) tree-ssa-structalias.o: tree-ssa-structalias.c $(SYSTEM_H) $(CONFIG_H) \ coretypes.h $(HASH_TABLE_H) $(TM_H) $(GGC_H) $(OBSTACK_H) $(BITMAP_H) \ $(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) \ - $(DIAGNOSTIC_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) \ + $(DIAGNOSTIC_H) $(TREE_H) $(TREE_SSA_H) $(TREE_INLINE_H) \ $(GIMPLE_H) $(HASH_TABLE_H) $(FUNCTION_H) $(CGRAPH_H) \ $(TREE_PASS_H) alloc-pool.h $(SPLAY_TREE_H) $(PARAMS_H) \ $(CGRAPH_H) $(ALIAS_H) pointer-set.h -tree-ssa-uninit.o : tree-ssa-uninit.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-ssa-uninit.o : tree-ssa-uninit.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_P_H) $(DIAGNOSTIC_H) \ $(FUNCTION_H) $(TM_H) coretypes.h \ $(TREE_PASS_H) $(BASIC_BLOCK_H) $(BITMAP_H) \ $(FLAGS_H) $(HASHTAB_H) pointer-set.h \ $(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H) -tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-ssa.o : tree-ssa.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(HASH_TABLE_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(DIAGNOSTIC_H) \ toplev.h $(FUNCTION_H) $(TM_H) coretypes.h \ langhooks.h $(TREE_PASS_H) $(BASIC_BLOCK_H) $(BITMAP_H) \ $(FLAGS_H) $(GGC_H) $(HASHTAB_H) pointer-set.h \ $(GIMPLE_H) $(TREE_INLINE_H) $(TARGET_H) \ $(GIMPLE_PRETTY_PRINT_H) $(CFGLOOP_H) -tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-into-ssa.o : tree-into-ssa.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_P_H) $(DIAGNOSTIC_CORE_H) \ $(FUNCTION_H) $(TM_H) coretypes.h \ langhooks.h domwalk.h $(TREE_PASS_H) $(PARAMS_H) $(BASIC_BLOCK_H) \ $(BITMAP_H) $(CFGLOOP_H) $(FLAGS_H) $(HASH_TABLE_H) \ $(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H) -tree-ssa-ter.o : tree-ssa-ter.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-ssa-ter.o : tree-ssa-ter.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) \ $(TREE_SSA_LIVE_H) $(BITMAP_H) $(FLAGS_H) \ $(GIMPLE_PRETTY_PRINT_H) -tree-ssa-coalesce.o : tree-ssa-coalesce.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-coalesce.o : tree-ssa-coalesce.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) \ $(TREE_SSA_LIVE_H) $(BITMAP_H) $(FLAGS_H) $(HASH_TABLE_H) \ $(TREE_PRETTY_PRINT_H) -tree-outof-ssa.o : tree-outof-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-outof-ssa.o : tree-outof-ssa.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) \ $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) $(BITMAP_H) $(GGC_H) \ $(EXPR_H) $(SSAEXPAND_H) $(GIMPLE_PRETTY_PRINT_H) tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \ - $(TREE_FLOW_H) $(TREE_PASS_H) domwalk.h $(FLAGS_H) \ + $(TREE_SSA_H) $(TREE_PASS_H) domwalk.h $(FLAGS_H) \ $(GIMPLE_PRETTY_PRINT_H) langhooks.h tree-ssa-forwprop.o : tree-ssa-forwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \ - $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \ + $(TREE_SSA_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \ langhooks.h $(FLAGS_H) $(GIMPLE_H) $(GIMPLE_PRETTY_PRINT_H) $(EXPR_H) \ $(OPTABS_H) tree-ssa-propagate.h tree-ssa-phiprop.o : tree-ssa-phiprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \ - $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \ + $(TREE_SSA_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \ langhooks.h $(FLAGS_H) $(GIMPLE_PRETTY_PRINT_H) tree-ssa-ifcombine.o : tree-ssa-ifcombine.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) $(TREE_H) $(BASIC_BLOCK_H) \ - $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \ + $(TREE_SSA_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \ $(TREE_PRETTY_PRINT_H) tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(HASH_TABLE_H) $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \ - $(TREE_FLOW_H) $(TREE_PASS_H) langhooks.h $(FLAGS_H) \ + $(TREE_SSA_H) $(TREE_PASS_H) langhooks.h $(FLAGS_H) \ $(DIAGNOSTIC_H) pointer-set.h domwalk.h $(CFGLOOP_H) \ $(TREE_DATA_REF_H) $(TREE_PRETTY_PRINT_H) $(GIMPLE_PRETTY_PRINT_H) \ insn-config.h $(EXPR_H) $(OPTABS_H) $(SCEV_H) tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TREE_H) $(FUNCTION_H) $(BASIC_BLOCK_H) $(FLAGS_H) \ - $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_PASS_H) \ + $(DIAGNOSTIC_H) $(TREE_SSA_H) $(TREE_PASS_H) \ langhooks.h $(TREE_PRETTY_PRINT_H) -tree-ssa-copy.o : tree-ssa-copy.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-ssa-copy.o : tree-ssa-copy.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_P_H) $(GGC_H) $(DIAGNOSTIC_H) \ $(FUNCTION_H) $(TM_H) coretypes.h $(SCEV_H) \ $(BASIC_BLOCK_H) $(TREE_PASS_H) langhooks.h tree-ssa-propagate.h \ $(FLAGS_H) $(CFGLOOP_H) $(GIMPLE_PRETTY_PRINT_H) -tree-ssa-propagate.o : tree-ssa-propagate.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-propagate.o : tree-ssa-propagate.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(TM_P_H) \ $(DIAGNOSTIC_H) $(FUNCTION_H) $(TM_H) coretypes.h $(DUMPFILE_H) \ $(BASIC_BLOCK_H) langhooks.h \ tree-ssa-propagate.h $(VEC_H) value-prof.h gt-tree-ssa-propagate.h $(FLAGS_H) \ $(GIMPLE_H) $(GIMPLE_PRETTY_PRINT_H) -tree-ssa-dom.o : tree-ssa-dom.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-ssa-dom.o : tree-ssa-dom.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(HASH_TABLE_H) $(TREE_H) $(TM_P_H) $(DIAGNOSTIC_H) \ $(FUNCTION_H) $(TM_H) coretypes.h \ $(BASIC_BLOCK_H) domwalk.h $(TREE_PASS_H) $(FLAGS_H) langhooks.h \ tree-ssa-propagate.h $(CFGLOOP_H) $(PARAMS_H) \ $(GIMPLE_PRETTY_PRINT_H) -tree-ssa-uncprop.o : tree-ssa-uncprop.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-uncprop.o : tree-ssa-uncprop.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(HASH_TABLE_H) $(TREE_H) $(TM_P_H) \ $(DIAGNOSTIC_H) $(FUNCTION_H) $(TM_H) coretypes.h \ $(BASIC_BLOCK_H) domwalk.h $(TREE_PASS_H) $(FLAGS_H) \ tree-ssa-propagate.h -tree-ssa-threadedge.o : tree-ssa-threadedge.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-threadedge.o : tree-ssa-threadedge.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) coretypes.h $(DUMPFILE_H) $(TM_H) $(TREE_H) $(FLAGS_H) \ $(TM_P_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \ - $(FUNCTION_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TREE_FLOW_H) \ + $(FUNCTION_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TREE_SSA_H) \ tree-ssa-propagate.h langhooks.h \ $(PARAMS_H) -tree-ssa-threadupdate.o : tree-ssa-threadupdate.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-threadupdate.o : tree-ssa-threadupdate.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(HASH_TABLE_H) \ $(DIAGNOSTIC_H) $(FUNCTION_H) $(TM_H) coretypes.h $(DUMPFILE_H) \ $(BASIC_BLOCK_H) $(FLAGS_H) $(CFGLOOP_H) tree-ssanames.o : tree-ssanames.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_PASS_H) + $(TM_H) $(TREE_H) $(TREE_SSA_H) $(TREE_PASS_H) tree-ssanames.h tree-phinodes.o : tree-phinodes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(TREE_H) $(GGC_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \ + $(TM_H) $(TREE_H) $(GGC_H) $(BASIC_BLOCK_H) $(TREE_SSA_H) \ gt-tree-phinodes.h $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) domwalk.o : domwalk.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(BASIC_BLOCK_H) domwalk.h sbitmap.h -tree-ssa-live.o : tree-ssa-live.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-ssa-live.o : tree-ssa-live.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) $(TIMEVAR_H) \ $(TREE_SSA_LIVE_H) $(BITMAP_H) debug.h $(FLAGS_H) $(HASH_TABLE_H) \ $(GIMPLE_PRETTY_PRINT_H) $(GIMPLE_H) -tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(FUNCTION_H) \ $(TREE_PASS_H) $(TM_H) coretypes.h $(TREE_SSA_LIVE_H) \ $(BASIC_BLOCK_H) $(BITMAP_H) $(FLAGS_H) $(HASHTAB_H) langhooks.h \ $(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_H) -tree-ssa-pre.o : tree-ssa-pre.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-pre.o : tree-ssa-pre.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) \ $(TM_H) coretypes.h $(TREE_PASS_H) $(FLAGS_H) langhooks.h \ $(CFGLOOP_H) alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASH_TABLE_H) \ $(GIMPLE_H) $(TREE_INLINE_H) tree-iterator.h tree-ssa-sccvn.h $(PARAMS_H) \ $(DBGCNT_H) tree-scalar-evolution.h $(GIMPLE_PRETTY_PRINT_H) domwalk.h \ $(IPA_PROP_H) -tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) \ $(TM_H) coretypes.h $(DUMPFILE_H) $(FLAGS_H) $(CFGLOOP_H) \ alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASH_TABLE_H) $(GIMPLE_H) \ @@ -2418,31 +2415,31 @@ tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \ gimple-ssa-strength-reduction.o : gimple-ssa-strength-reduction.c $(CONFIG_H) \ $(SYSTEM_H) coretypes.h $(TREE_H) $(GIMPLE_H) $(BASIC_BLOCK_H) \ $(HASH_TABLE_H) $(TREE_PASS_H) $(CFGLOOP_H) $(TREE_PRETTY_PRINT_H) \ - $(GIMPLE_PRETTY_PRINT_H) alloc-pool.h $(TREE_FLOW_H) domwalk.h \ + $(GIMPLE_PRETTY_PRINT_H) alloc-pool.h $(TREE_SSA_H) domwalk.h \ pointer-set.h expmed.h wide-int-print.h tree-vrp.o : tree-vrp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ - $(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_CORE_H) $(GGC_H) \ + $(TREE_SSA_H) $(TREE_PASS_H) $(DIAGNOSTIC_CORE_H) $(GGC_H) \ $(BASIC_BLOCK_H) tree-ssa-propagate.h $(FLAGS_H) $(TREE_DUMP_H) \ $(CFGLOOP_H) $(SCEV_H) intl.h \ $(GIMPLE_PRETTY_PRINT_H) gimple-fold.h $(OPTABS_H) $(EXPR_H) -tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) $(HASH_TABLE_H) \ +tree-cfg.o : tree-cfg.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) $(HASH_TABLE_H) \ $(TREE_H) $(TM_P_H) $(GGC_H) $(FLAGS_H) $(TARGET_H) \ $(DIAGNOSTIC_CORE_H) $(FUNCTION_H) $(TM_H) coretypes.h \ $(TREE_DUMP_H) $(EXCEPT_H) $(CFGLOOP_H) $(TREE_PASS_H) \ $(BASIC_BLOCK_H) wide-int.h wide-int-print.h \ value-prof.h tree-ssa-propagate.h $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H) -tree-cfgcleanup.o : tree-cfgcleanup.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-cfgcleanup.o : tree-cfgcleanup.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_P_H) $(GGC_H) $(FLAGS_H) \ $(DIAGNOSTIC_CORE_H) $(FUNCTION_H) $(TM_H) coretypes.h \ $(EXCEPT_H) langhooks.h $(CFGLOOP_H) $(TREE_PASS_H) \ $(BASIC_BLOCK_H) $(HASHTAB_H) \ tree-ssa-propagate.h $(SCEV_H) -tree-tailcall.o : tree-tailcall.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-tailcall.o : tree-tailcall.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_P_H) $(FUNCTION_H) $(TM_H) coretypes.h \ $(EXCEPT_H) $(TREE_PASS_H) $(FLAGS_H) langhooks.h \ $(BASIC_BLOCK_H) $(DBGCNT_H) $(GIMPLE_PRETTY_PRINT_H) $(TARGET_H) \ - $(COMMON_TARGET_H) $(CFGLOOP_H) -tree-ssa-sink.o : tree-ssa-sink.c $(TREE_FLOW_H) $(CONFIG_H) \ + $(COMMON_TARGET_H) $(CFGLOOP_H) ipa-utils.h +tree-ssa-sink.o : tree-ssa-sink.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) \ $(TM_H) coretypes.h $(TREE_PASS_H) $(FLAGS_H) alloc-pool.h \ $(BASIC_BLOCK_H) $(BITMAP_H) $(CFGLOOP_H) $(HASHTAB_H) \ @@ -2451,59 +2448,59 @@ tree-ssa-sink.o : tree-ssa-sink.c $(TREE_FLOW_H) $(CONFIG_H) \ tree-nested.o: tree-nested.c $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \ $(TM_P_H) $(FUNCTION_H) $(TREE_DUMP_H) $(TREE_INLINE_H) \ tree-iterator.h $(GIMPLE_H) $(CGRAPH_H) $(EXPR_H) langhooks.h \ - gt-tree-nested.h coretypes.h $(TREE_FLOW_H) pointer-set.h + gt-tree-nested.h coretypes.h $(TREE_SSA_H) pointer-set.h tree-if-conv.o: tree-if-conv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ - $(TREE_H) $(FLAGS_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \ + $(TREE_H) $(FLAGS_H) $(BASIC_BLOCK_H) $(TREE_SSA_H) \ $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \ $(DBGCNT_H) $(GIMPLE_PRETTY_PRINT_H) tree-iterator.o : tree-iterator.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ coretypes.h $(GGC_H) tree-iterator.h $(GIMPLE_H) gt-tree-iterator.h -tree-dfa.o : tree-dfa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-dfa.o : tree-dfa.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_P_H) $(GGC_H) $(DIAGNOSTIC_H) \ $(TREE_INLINE_H) $(HASHTAB_H) pointer-set.h $(FLAGS_H) $(FUNCTION_H) \ convert.h $(TM_H) coretypes.h langhooks.h \ $(TREE_PASS_H) $(PARAMS_H) $(CGRAPH_H) $(BASIC_BLOCK_H) $(GIMPLE_H) \ $(TREE_PRETTY_PRINT_H) -tree-ssa-operands.o : tree-ssa-operands.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-operands.o : tree-ssa-operands.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \ $(FLAGS_H) $(FUNCTION_H) $(TM_H) $(TIMEVAR_H) coretypes.h $(DUMPFILE_H) \ langhooks.h $(IPA_REFERENCE_H) $(GIMPLE_PRETTY_PRINT_H) -tree-eh.o : tree-eh.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-eh.o : tree-eh.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_H) $(FLAGS_H) $(FUNCTION_H) $(EXCEPT_H) langhooks.h \ $(HASH_TABLE_H) $(GGC_H) $(TREE_PASS_H) coretypes.h pointer-set.h \ $(TREE_INLINE_H) tree-iterator.h toplev.h \ $(DIAGNOSTIC_CORE_H) $(TARGET_H) $(CFGLOOP_H) tree-ssa-loop.o : tree-ssa-loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \ - $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_PASS_H) \ + $(DIAGNOSTIC_H) $(TREE_SSA_H) $(TREE_PASS_H) \ $(CFGLOOP_H) $(FLAGS_H) $(TREE_INLINE_H) $(SCEV_H) $(DIAGNOSTIC_CORE_H) $(TREE_VECTORIZER_H) -tree-ssa-loop-unswitch.o : tree-ssa-loop-unswitch.c $(TREE_FLOW_H) \ +tree-ssa-loop-unswitch.o : tree-ssa-loop-unswitch.c $(TREE_SSA_H) \ $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) \ $(PARAMS_H) $(DIAGNOSTIC_H) $(TM_H) \ coretypes.h $(TREE_PASS_H) $(BASIC_BLOCK_H) \ $(TREE_INLINE_H) -tree-ssa-address.o : tree-ssa-address.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-address.o : tree-ssa-address.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) \ $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) \ $(FLAGS_H) $(TREE_INLINE_H) $(RECOG_H) insn-config.h \ $(EXPR_H) gt-tree-ssa-address.h $(GGC_H) tree-affine.h $(TARGET_H) \ $(TREE_PRETTY_PRINT_H) expmed.h wide-int-print.h -tree-ssa-loop-niter.o : tree-ssa-loop-niter.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-loop-niter.o : tree-ssa-loop-niter.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(PARAMS_H) \ $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) \ $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(TREE_DATA_REF_H) \ $(BASIC_BLOCK_H) $(GGC_H) intl.h $(GIMPLE_PRETTY_PRINT_H) $(TREE_PASS_H) \ wide-int-print.h -tree-ssa-loop-ivcanon.o : tree-ssa-loop-ivcanon.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-loop-ivcanon.o : tree-ssa-loop-ivcanon.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(PARAMS_H) \ $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h \ $(FLAGS_H) $(TREE_PASS_H) $(SCEV_H) $(BASIC_BLOCK_H) $(TARGET_H) \ $(GIMPLE_PRETTY_PRINT_H) -tree-ssa-loop-ch.o : tree-ssa-loop-ch.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-loop-ch.o : tree-ssa-loop-ch.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(TREE_INLINE_H) \ $(DIAGNOSTIC_H) $(TM_H) coretypes.h \ $(TREE_PASS_H) $(FLAGS_H) $(BASIC_BLOCK_H) -tree-ssa-loop-prefetch.o: tree-ssa-loop-prefetch.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-loop-prefetch.o: tree-ssa-loop-prefetch.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(EXPR_H) \ $(DIAGNOSTIC_H) $(TM_H) coretypes.h \ $(TREE_PASS_H) $(RECOG_H) insn-config.h $(HASHTAB_H) \ @@ -2511,10 +2508,10 @@ tree-ssa-loop-prefetch.o: tree-ssa-loop-prefetch.c $(TREE_FLOW_H) $(CONFIG_H) \ $(DIAGNOSTIC_CORE_H) langhooks.h $(TREE_INLINE_H) $(TREE_DATA_REF_H) \ $(OPTABS_H) $(TREE_PRETTY_PRINT_H) tree-predcom.o: tree-predcom.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_P_H) \ - $(CFGLOOP_H) $(TREE_FLOW_H) $(GGC_H) $(TREE_DATA_REF_H) \ + $(CFGLOOP_H) $(TREE_SSA_H) $(GGC_H) $(TREE_DATA_REF_H) \ $(PARAMS_H) $(DIAGNOSTIC_H) $(TREE_PASS_H) $(TM_H) coretypes.h \ tree-affine.h $(TREE_INLINE_H) $(TREE_PRETTY_PRINT_H) wide-int-print.h -tree-ssa-loop-ivopts.o : tree-ssa-loop-ivopts.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-loop-ivopts.o : tree-ssa-loop-ivopts.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(EXPR_H) \ $(DIAGNOSTIC_H) $(TM_H) coretypes.h \ $(TREE_PASS_H) $(GGC_H) $(RECOG_H) insn-config.h $(HASH_TABLE_H) $(SCEV_H) \ @@ -2525,21 +2522,21 @@ tree-affine.o : tree-affine.c tree-affine.h $(CONFIG_H) pointer-set.h \ $(SYSTEM_H) $(TREE_H) $(GIMPLE_H) \ coretypes.h $(DUMPFILE_H) $(FLAGS_H) \ $(TREE_PRETTY_PRINT_H) wide-int-print.h wide-int.h -tree-ssa-loop-manip.o : tree-ssa-loop-manip.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-loop-manip.o : tree-ssa-loop-manip.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) coretypes.h $(DUMPFILE_H) $(TM_H) $(TREE_H) \ - $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) \ + $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TREE_SSA_H) \ $(CFGLOOP_H) $(TREE_PASS_H) \ $(SCEV_H) $(PARAMS_H) $(TREE_INLINE_H) langhooks.h -tree-ssa-loop-im.o : tree-ssa-loop-im.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-loop-im.o : tree-ssa-loop-im.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(HASH_TABLE_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h \ $(PARAMS_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h \ $(TREE_PASS_H) $(FLAGS_H) $(BASIC_BLOCK_H) \ pointer-set.h tree-affine.h tree-ssa-propagate.h $(GIMPLE_PRETTY_PRINT_H) tree-ssa-math-opts.o : tree-ssa-math-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(FLAGS_H) $(TREE_H) $(TREE_FLOW_H) \ + $(TM_H) $(FLAGS_H) $(TREE_H) $(TREE_SSA_H) \ $(TREE_PASS_H) alloc-pool.h $(BASIC_BLOCK_H) $(TARGET_H) \ $(DIAGNOSTIC_H) $(RTL_H) $(EXPR_H) $(OPTABS_H) $(GIMPLE_PRETTY_PRINT_H) -tree-ssa-alias.o : tree-ssa-alias.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-ssa-alias.o : tree-ssa-alias.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_P_H) $(GGC_H) $(TREE_INLINE_H) $(FLAGS_H) \ $(FUNCTION_H) $(TIMEVAR_H) convert.h $(TM_H) coretypes.h $(DUMPFILE_H) \ langhooks.h \ @@ -2547,13 +2544,13 @@ tree-ssa-alias.o : tree-ssa-alias.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(GIMPLE_H) $(VEC_H) $(TARGET_H) \ pointer-set.h alloc-pool.h \ $(TREE_PRETTY_PRINT_H) -tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(HASH_TABLE_H) $(TREE_H) $(DIAGNOSTIC_H) \ $(TM_H) coretypes.h $(TREE_PASS_H) $(FLAGS_H) \ tree-iterator.h $(BASIC_BLOCK_H) $(GIMPLE_H) $(TREE_INLINE_H) \ $(VEC_H) langhooks.h alloc-pool.h pointer-set.h $(CFGLOOP_H) \ $(TARGET_H) $(GIMPLE_PRETTY_PRINT_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) -tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ +tree-optimize.o : tree-optimize.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_P_H) $(GGC_H) \ $(DIAGNOSTIC_H) $(BASIC_BLOCK_H) $(FLAGS_H) $(TM_H) \ coretypes.h toplev.h $(DIAGNOSTIC_CORE_H) $(FUNCTION_H) langhooks.h \ @@ -2563,24 +2560,24 @@ tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GIMPLE_H) \ $(DIAGNOSTIC_H) $(TREE_INLINE_H) langhooks.h \ - $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \ + $(LANGHOOKS_DEF_H) $(TREE_SSA_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \ coretypes.h $(EXCEPT_H) $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) \ $(GGC_H) gt-gimplify.h $(HASHTAB_H) $(TARGET_H) $(DIAGNOSTIC_CORE_H) $(OPTABS_H) \ $(SPLAY_TREE_H) $(VEC_H) tree-iterator.h $(TREE_PASS_H) $(TREE_PRETTY_PRINT_H) gimple-iterator.o : gimple-iterator.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) value-prof.h -gimple-fold.o : gimple-fold.c $(TREE_FLOW_H) $(CONFIG_H) coretypes.h \ + $(TREE_H) $(GIMPLE_H) $(TREE_SSA_H) value-prof.h +gimple-fold.o : gimple-fold.c $(TREE_SSA_H) $(CONFIG_H) coretypes.h \ $(DUMPFILE_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(GGC_H) \ $(FUNCTION_H) $(TM_H) $(BASIC_BLOCK_H) langhooks.h \ tree-ssa-propagate.h $(FLAGS_H) $(TARGET_H) gimple-fold.h gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h \ - $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(TM_H) coretypes.h \ + $(LANGHOOKS_DEF_H) $(TREE_SSA_H) $(TM_H) coretypes.h \ $(EXCEPT_H) $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(TREE_PASS_H) \ $(HASHTAB_H) $(DIAGNOSTIC_CORE_H) tree-iterator.h langhooks.h omp-low.o : omp-low.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(RTL_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h $(DIAGNOSTIC_CORE_H) \ - $(TREE_FLOW_H) $(FLAGS_H) $(EXPR_H) $(DIAGNOSTIC_CORE_H) \ + $(TREE_SSA_H) $(FLAGS_H) $(EXPR_H) $(DIAGNOSTIC_CORE_H) \ $(TREE_PASS_H) $(GGC_H) $(EXCEPT_H) $(SPLAY_TREE_H) $(OPTABS_H) \ $(CFGLOOP_H) tree-iterator.h $(TARGET_H) gt-omp-low.h tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \ @@ -2588,108 +2585,108 @@ tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \ omega.o : omega.c $(OMEGA_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ $(TREE_H) $(DIAGNOSTIC_CORE_H) tree-chrec.o : tree-chrec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ - $(TREE_PRETTY_PRINT_H) $(CFGLOOP_H) $(TREE_FLOW_H) $(SCEV_H) \ + $(TREE_PRETTY_PRINT_H) $(CFGLOOP_H) $(TREE_SSA_H) $(SCEV_H) \ $(PARAMS_H) tree-scalar-evolution.o : tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(DUMPFILE_H) $(HASH_TABLE_H) $(GIMPLE_PRETTY_PRINT_H) \ - $(TREE_FLOW_H) $(CFGLOOP_H) $(SCEV_H) $(PARAMS_H) gt-tree-scalar-evolution.h + $(TREE_SSA_H) $(CFGLOOP_H) $(SCEV_H) $(PARAMS_H) gt-tree-scalar-evolution.h tree-data-ref.o : tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(DUMPFILE_H) \ - $(GIMPLE_PRETTY_PRINT_H) $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ + $(GIMPLE_PRETTY_PRINT_H) $(TREE_SSA_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ langhooks.h tree-affine.h $(PARAMS_H) sese.o : sese.c sese.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_PRETTY_PRINT_H) \ - $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H) value-prof.h + $(TREE_SSA_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H) value-prof.h graphite.o : graphite.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DIAGNOSTIC_CORE_H) \ - $(TREE_FLOW_H) $(TREE_DUMP_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) sese.h \ + $(TREE_SSA_H) $(TREE_DUMP_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) sese.h \ $(DBGCNT_H) $(GRAPHITE_HTAB_H) graphite-poly.h graphite-scop-detection.h \ graphite-clast-to-gimple.h graphite-sese-to-poly.h graphite-blocking.o : graphite-blocking.c $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(DUMPFILE_H) $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ + coretypes.h $(DUMPFILE_H) $(TREE_SSA_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ sese.h graphite-poly.h graphite-clast-to-gimple.o : graphite-clast-to-gimple.c $(CONFIG_H) \ - $(SYSTEM_H) coretypes.h $(DIAGNOSTIC_CORE_H) $(TREE_FLOW_H) $(TREE_PASS_H) \ + $(SYSTEM_H) coretypes.h $(DIAGNOSTIC_CORE_H) $(TREE_SSA_H) $(TREE_PASS_H) \ $(CFGLOOP_H) $(TREE_DATA_REF_H) sese.h $(GRAPHITE_HTAB_H) \ graphite-poly.h graphite-clast-to-gimple.h graphite-dependences.o : graphite-dependences.c $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(TREE_FLOW_H) $(TREE_PASS_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ + coretypes.h $(TREE_SSA_H) $(TREE_PASS_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ sese.h $(GRAPHITE_HTAB_H) graphite-poly.h graphite-interchange.o : graphite-interchange.c $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(DUMPFILE_H) $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ + coretypes.h $(DUMPFILE_H) $(TREE_SSA_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ sese.h graphite-poly.h graphite-poly.o : graphite-poly.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(DUMPFILE_H) $(DIAGNOSTIC_CORE_H) $(TREE_FLOW_H) $(GIMPLE_PRETTY_PRINT_H) \ + $(DUMPFILE_H) $(DIAGNOSTIC_CORE_H) $(TREE_SSA_H) $(GIMPLE_PRETTY_PRINT_H) \ $(CFGLOOP_H) $(TREE_DATA_REF_H) sese.h graphite-poly.h graphite-scop-detection.o : graphite-scop-detection.c $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H) \ + coretypes.h $(TREE_SSA_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H) \ sese.h graphite-poly.h graphite-scop-detection.h graphite-sese-to-poly.o : graphite-sese-to-poly.c $(CONFIG_H) \ - $(SYSTEM_H) coretypes.h $(TREE_FLOW_H) $(TREE_PASS_H) $(CFGLOOP_H) \ + $(SYSTEM_H) coretypes.h $(TREE_SSA_H) $(TREE_PASS_H) $(CFGLOOP_H) \ $(TREE_DATA_REF_H) domwalk.h sese.h graphite-poly.h \ graphite-sese-to-poly.h graphite-optimize-isl.o : graphite-optimize-isl.c $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(DUMPFILE_H) $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ + coretypes.h $(DUMPFILE_H) $(TREE_SSA_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ $(SCEV_H) sese.h graphite-poly.h tree-vect-loop.o: tree-vect-loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(GGC_H) $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(DUMPFILE_H) \ + $(TM_H) $(GGC_H) $(TREE_H) $(BASIC_BLOCK_H) $(TREE_SSA_H) $(DUMPFILE_H) \ $(CFGLOOP_H) $(EXPR_H) $(RECOG_H) $(OPTABS_H) \ $(DIAGNOSTIC_CORE_H) $(SCEV_H) $(TREE_VECTORIZER_H) \ $(GIMPLE_PRETTY_PRINT_H) $(TARGET_H) $(TREE_DATA_REF_H) tree-vect-loop-manip.o: tree-vect-loop-manip.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(DUMPFILE_H) $(TM_H) $(GGC_H) $(TREE_H) $(BASIC_BLOCK_H) \ - $(TREE_FLOW_H) $(CFGLOOP_H) $(DIAGNOSTIC_CORE_H) \ + $(TREE_SSA_H) $(CFGLOOP_H) $(DIAGNOSTIC_CORE_H) \ $(SCEV_H) $(TREE_VECTORIZER_H) langhooks.h $(GIMPLE_PRETTY_PRINT_H) tree-vect-patterns.o: tree-vect-patterns.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(DUMPFILE_H) \ $(TM_H) $(GGC_H) $(TREE_H) $(TARGET_H) $(BASIC_BLOCK_H) \ - $(TREE_FLOW_H) $(CFGLOOP_H) $(EXPR_H) $(OPTABS_H) $(PARAMS_H) \ + $(TREE_SSA_H) $(CFGLOOP_H) $(EXPR_H) $(OPTABS_H) $(PARAMS_H) \ $(TREE_DATA_REF_H) $(TREE_VECTORIZER_H) $(RECOG_H) $(DIAGNOSTIC_CORE_H) \ $(GIMPLE_PRETTY_PRINT_H) tree-vect-slp.o: tree-vect-slp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(DUMPFILE_H) $(TM_H) $(GGC_H) $(TREE_H) $(TARGET_H) $(BASIC_BLOCK_H) \ - $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(CFGLOOP_H) \ + $(DIAGNOSTIC_H) $(TREE_SSA_H) $(CFGLOOP_H) \ $(EXPR_H) $(RECOG_H) $(OPTABS_H) $(TREE_VECTORIZER_H) \ $(GIMPLE_PRETTY_PRINT_H) $(TREE_DATA_REF_H) langhooks.h tree-vect-stmts.o: tree-vect-stmts.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(DUMPFILE_H) $(TM_H) $(GGC_H) $(TREE_H) $(TARGET_H) \ - $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(CFGLOOP_H) \ + $(BASIC_BLOCK_H) $(TREE_SSA_H) $(CFGLOOP_H) \ $(EXPR_H) $(RECOG_H) $(OPTABS_H) $(TREE_VECTORIZER_H) \ langhooks.h $(GIMPLE_PRETTY_PRINT_H) tree-vect-data-refs.o: tree-vect-data-refs.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(DUMPFILE_H) $(TM_H) $(GGC_H) $(TREE_H) $(TARGET_H) \ - $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(CFGLOOP_H) \ + $(BASIC_BLOCK_H) $(TREE_SSA_H) $(CFGLOOP_H) \ $(EXPR_H) $(OPTABS_H) $(SCEV_H) $(TREE_VECTORIZER_H) \ $(DIAGNOSTIC_CORE_H) $(TM_P_H) $(GIMPLE_PRETTY_PRINT_H) tree-vectorizer.o: tree-vectorizer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(DUMPFILE_H) $(TM_H) $(GGC_H) $(TREE_H) $(TREE_FLOW_H) \ + $(DUMPFILE_H) $(TM_H) $(GGC_H) $(TREE_H) $(TREE_SSA_H) \ $(CFGLOOP_H) $(TREE_PASS_H) $(TREE_VECTORIZER_H) \ $(TREE_PRETTY_PRINT_H) $(DBGCNT_H) vtable-verify.o: vtable-verify.c vtable-verify.h $(CONFIG_H) \ $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) cp/cp-tree.h $(TM_P_H) \ - $(BASIC_BLOCK_H) output.h $(TREE_FLOW_H) $(TREE_DUMP_H) $(TREE_PASS_H) \ + $(BASIC_BLOCK_H) output.h $(TREE_SSA_H) $(TREE_DUMP_H) $(TREE_PASS_H) \ $(TIMEVAR_H) $(CFGLOOP_H) $(FLAGS_H) $(TREE_INLINE_H) $(SCEV_H) \ $(DIAGNOSTIC_CORE_H) $(GIMPLE_PRETTY_PRINT_H) toplev.h langhooks.h \ gt-vtable-verify.h tree-loop-distribution.o: tree-loop-distribution.c $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H) + coretypes.h $(TREE_SSA_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H) tree-parloops.o: tree-parloops.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TREE_FLOW_H) $(TREE_HASHER_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ + $(TREE_SSA_H) $(TREE_HASHER_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ $(GIMPLE_PRETTY_PRINT_H) $(HASH_TABLE_H) \ $(TREE_PASS_H) langhooks.h gt-tree-parloops.h $(TREE_VECTORIZER_H) tree-stdarg.o: tree-stdarg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ - $(TREE_H) $(FUNCTION_H) $(TREE_FLOW_H) $(TREE_PASS_H) \ + $(TREE_H) $(FUNCTION_H) $(TREE_SSA_H) $(TREE_PASS_H) \ tree-stdarg.h $(TARGET_H) langhooks.h $(GIMPLE_PRETTY_PRINT_H) tree-object-size.o: tree-object-size.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(TREE_H) $(DIAGNOSTIC_CORE_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) \ + $(TM_H) $(TREE_H) $(DIAGNOSTIC_CORE_H) $(DIAGNOSTIC_H) $(TREE_SSA_H) \ $(TREE_PASS_H) tree-ssa-propagate.h $(GIMPLE_PRETTY_PRINT_H) internal-fn.o : internal-fn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(INTERNAL_FN_H) $(TREE_H) $(EXPR_H) $(OPTABS_H) $(GIMPLE_H) gimple.o : gimple.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ $(GGC_H) $(GIMPLE_H) $(DIAGNOSTIC_CORE_H) $(DIAGNOSTIC_H) gt-gimple.h \ - $(TREE_FLOW_H) value-prof.h $(FLAGS_H) $(DEMANGLE_H) \ + $(TREE_SSA_H) value-prof.h $(FLAGS_H) $(DEMANGLE_H) \ $(TARGET_H) $(ALIAS_H) gimple-pretty-print.o : gimple-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(DUMPFILE_H) \ - $(TREE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) $(TREE_FLOW_H) \ + $(TREE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) $(TREE_SSA_H) \ $(TM_H) $(GIMPLE_H) value-prof.h \ $(TRANS_MEM_H) $(GIMPLE_PRETTY_PRINT_H) tree-mudflap.o : tree-mudflap.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ @@ -2697,13 +2694,13 @@ tree-mudflap.o : tree-mudflap.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ $(DEMANGLE_H) $(HASHTAB_H) langhooks.h tree-mudflap.h \ $(TM_H) coretypes.h $(TREE_PASS_H) $(CGRAPH_H) $(GGC_H) \ gt-tree-mudflap.h $(BASIC_BLOCK_H) $(FLAGS_H) $(FUNCTION_H) \ - $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) tree-iterator.h + $(TM_P_H) $(TREE_SSA_H) $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) tree-iterator.h tree-nomudflap.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \ $(C_TREE_H) $(C_COMMON_H) $(GIMPLE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) \ output.h langhooks.h tree-mudflap.h $(TM_H) coretypes.h \ $(GGC_H) gt-tree-mudflap.h $(TREE_PASS_H) $(DIAGNOSTIC_CORE_H) tree-pretty-print.o : tree-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \ - $(TREE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) $(TREE_FLOW_H) \ + $(TREE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) $(TREE_SSA_H) \ $(TM_H) coretypes.h $(DUMPFILE_H) tree-iterator.h $(SCEV_H) langhooks.h \ value-prof.h output.h $(TREE_PRETTY_PRINT_H) wide-int-print.h tree-diagnostic.o : tree-diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ @@ -2713,7 +2710,7 @@ tree-diagnostic.o : tree-diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(FLAGS_H) $(DIAGNOSTIC_CORE_H) $(HASH_TABLE_H) $(EXPR_H) \ $(RTL_H) $(GGC_H) $(TM_P_H) langhooks.h $(MD5_H) intl.h $(TARGET_H) \ - $(GIMPLE_H) realmpfr.h $(TREE_FLOW_H) + $(GIMPLE_H) realmpfr.h $(TREE_SSA_H) diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ version.h $(DEMANGLE_H) $(INPUT_H) intl.h $(BACKTRACE_H) $(DIAGNOSTIC_H) \ diagnostic.def diagnostic-color.h @@ -2732,7 +2729,7 @@ targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ $(EXPR_H) $(TM_H) $(RTL_H) $(TM_P_H) $(FUNCTION_H) output.h $(DIAGNOSTIC_CORE_H) \ $(MACHMODE_H) $(TARGET_DEF_H) $(TARGET_H) $(GGC_H) gt-targhooks.h \ $(OPTABS_H) $(RECOG_H) $(REGS_H) reload.h hard-reg-set.h intl.h $(OPTS_H) \ - tree-ssa-alias.h $(TREE_FLOW_H) + tree-ssa-alias.h $(TREE_SSA_H) common/common-targhooks.o : common/common-targhooks.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(INPUT_H) $(TM_H) $(COMMON_TARGET_H) common/common-targhooks.h wide-int.o: wide-int.cc $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) wide-int.h @@ -2776,7 +2773,7 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(PARAMS_H) $(TM_P_H) reload.h $(TARGET_H) \ langhooks.h insn-flags.h $(CFGLOOP_H) \ hosthooks.h $(CGRAPH_H) $(COVERAGE_H) $(TREE_PASS_H) $(TREE_DUMP_H) \ - $(GGC_H) $(OPTS_H) $(TREE_FLOW_H) $(TREE_INLINE_H) \ + $(GGC_H) $(OPTS_H) $(TREE_SSA_H) $(TREE_INLINE_H) \ gt-passes.h $(DF_H) $(PREDICT_H) $(LTO_STREAMER_H) \ $(PLUGIN_H) $(IPA_UTILS_H) pass-instances.def \ $(CONTEXT_H) $(PASS_MANAGER_H) @@ -2835,14 +2832,14 @@ except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ dwarf2asm.h $(DWARF2OUT_H) toplev.h $(DIAGNOSTIC_CORE_H) $(HASH_TABLE_H) \ intl.h $(GGC_H) \ gt-except.h $(CGRAPH_H) $(DIAGNOSTIC_H) $(DWARF2_H) \ - $(TARGET_H) $(TM_P_H) $(TREE_PASS_H) $(TREE_FLOW_H) \ + $(TARGET_H) $(TM_P_H) $(TREE_PASS_H) $(TREE_SSA_H) \ $(TREE_PRETTY_PRINT_H) sbitmap.h $(COMMON_TARGET_H) $(CFGLOOP_H) expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) $(EXPR_H) $(OPTABS_H) \ $(LIBFUNCS_H) $(INSN_ATTR_H) insn-config.h $(RECOG_H) output.h \ typeclass.h hard-reg-set.h toplev.h $(DIAGNOSTIC_CORE_H) hard-reg-set.h $(EXCEPT_H) \ reload.h langhooks.h intl.h $(TM_P_H) $(TARGET_H) \ - tree-iterator.h gt-expr.h $(MACHMODE_H) $(TIMEVAR_H) $(TREE_FLOW_H) \ + tree-iterator.h gt-expr.h $(MACHMODE_H) $(TIMEVAR_H) $(TREE_SSA_H) \ $(TREE_PASS_H) $(DF_H) $(DIAGNOSTIC_H) $(SSAEXPAND_H) \ $(PARAMS_H) $(COMMON_TARGET_H) target-globals.h dojump.o : dojump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TM_P_H) \ @@ -2855,12 +2852,12 @@ builtins.o : builtins.c builtins.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ hard-reg-set.h $(DIAGNOSTIC_CORE_H) hard-reg-set.h $(EXCEPT_H) \ $(TM_P_H) $(PREDICT_H) $(LIBFUNCS_H) langhooks.h $(BASIC_BLOCK_H) \ tree-mudflap.h realmpfr.h $(BUILTINS_DEF) $(MACHMODE_H) \ - $(DIAGNOSTIC_CORE_H) $(TREE_FLOW_H) value-prof.h ubsan.h + $(DIAGNOSTIC_CORE_H) $(TREE_SSA_H) value-prof.h ubsan.h calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) $(EXPR_H) $(OPTABS_H) langhooks.h $(TARGET_H) \ $(LIBFUNCS_H) $(REGS_H) $(DIAGNOSTIC_CORE_H) output.h \ $(FUNCTION_H) $(TIMEVAR_H) $(TM_P_H) $(CGRAPH_H) $(EXCEPT_H) sbitmap.h \ - $(DBGCNT_H) $(TREE_FLOW_H) + $(DBGCNT_H) $(TREE_SSA_H) expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ $(FLAGS_H) insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \ $(DIAGNOSTIC_CORE_H) $(TM_P_H) langhooks.h $(DF_H) $(TARGET_H) \ @@ -2889,7 +2886,7 @@ dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ toplev.h $(DIAGNOSTIC_CORE_H) $(DWARF2OUT_H) reload.h \ $(GGC_H) $(EXCEPT_H) dwarf2asm.h $(TM_P_H) langhooks.h $(HASH_TABLE_H) \ gt-dwarf2out.h $(TARGET_H) $(CGRAPH_H) $(MD5_H) $(INPUT_H) $(FUNCTION_H) \ - $(GIMPLE_H) ira.h lra.h $(TREE_FLOW_H) \ + $(GIMPLE_H) ira.h lra.h $(TREE_SSA_H) \ $(TREE_PRETTY_PRINT_H) $(COMMON_TARGET_H) $(OPTS_H) dwarf2cfi.o : dwarf2cfi.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(HASH_TABLE_H) \ $(TM_H) version.h $(RTL_H) $(EXPR_H) $(REGS_H) $(FUNCTION_H) output.h \ @@ -2933,13 +2930,13 @@ cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ $(TM_H) $(TREE_H) $(TIMEVAR_H) \ langhooks.h toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \ gt-cgraph.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \ - $(TREE_INLINE_H) $(TREE_FLOW_H) cif-code.def \ + $(TREE_INLINE_H) $(TREE_SSA_H) cif-code.def \ value-prof.h $(EXCEPT_H) $(IPA_UTILS_H) $(DIAGNOSTIC_CORE_H) \ $(IPA_INLINE_H) $(LTO_STREAMER_H) $(CFGLOOP_H) $(GIMPLE_PRETTY_PRINT_H) cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(GGC_H) \ $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \ - $(TREE_FLOW_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) \ + $(TREE_SSA_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) \ $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(IPA_PROP_H) \ gt-cgraphunit.h tree-iterator.h $(COVERAGE_H) $(TREE_DUMP_H) \ $(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) $(IPA_UTILS_H) $(CFGLOOP_H) \ @@ -2948,19 +2945,19 @@ cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ cgraphclones.o : cgraphclones.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(GGC_H) \ $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \ - $(TREE_FLOW_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) $(TREE_DUMP_H) \ + $(TREE_SSA_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) $(TREE_DUMP_H) \ $(PARAMS_H) $(RTL_H) $(IPA_PROP_H) \ tree-iterator.h $(COVERAGE_H) \ $(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) $(IPA_UTILS_H) \ $(LTO_STREAMER_H) $(EXCEPT_H) $(GCC_PLUGIN_H) gt-cgraphclones.h cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \ - $(TREE_FLOW_H) $(TREE_PASS_H) $(IPA_UTILS_H) $(EXCEPT_H) \ + $(TREE_SSA_H) $(TREE_PASS_H) $(IPA_UTILS_H) $(EXCEPT_H) \ $(IPA_INLINE_H) varpool.o : varpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(CGRAPH_H) langhooks.h $(DIAGNOSTIC_CORE_H) $(HASHTAB_H) \ $(GGC_H) $(TIMEVAR_H) debug.h $(TARGET_H) output.h $(GIMPLE_H) \ - $(TREE_FLOW_H) + $(TREE_SSA_H) ipa.o : ipa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) \ $(TREE_PASS_H) $(GIMPLE_H) $(TARGET_H) $(GGC_H) pointer-set.h \ $(IPA_UTILS_H) tree-inline.h profile.h $(PARAMS_H) @@ -2975,52 +2972,52 @@ ipa-devirt.o : ipa-devirt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH $(DIAGNOSTIC_H) ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(DIAGNOSTIC_H) \ - $(TREE_FLOW_H) $(TM_H) $(TREE_PASS_H) $(FLAGS_H) $(TREE_H) \ + $(TREE_SSA_H) $(TM_H) $(TREE_PASS_H) $(FLAGS_H) $(TREE_H) \ $(TREE_INLINE_H) $(GIMPLE_H) \ $(GIMPLE_PRETTY_PRINT_H) $(LTO_STREAMER_H) \ $(DATA_STREAMER_H) $(TREE_STREAMER_H) $(PARAMS_H) ipa-ref.o : ipa-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) $(TREE_H) $(TARGET_H) \ - $(TREE_FLOW_H) $(TM_H) $(TREE_PASS_H) $(FLAGS_H) $(TREE_H) $(GGC_H) \ + $(TREE_SSA_H) $(TM_H) $(TREE_PASS_H) $(FLAGS_H) $(TREE_H) $(GGC_H) \ $(IPA_UTILS_H) ipa-cp.o : ipa-cp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TREE_H) $(TARGET_H) $(GIMPLE_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_FLOW_H) \ + $(TREE_H) $(TARGET_H) $(GIMPLE_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_SSA_H) \ $(TREE_PASS_H) $(FLAGS_H) $(DIAGNOSTIC_H) \ $(TREE_INLINE_H) $(PARAMS_H) $(TREE_PRETTY_PRINT_H) $(IPA_INLINE_H) ipa-split.o : ipa-split.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TREE_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_FLOW_H) \ + $(TREE_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_SSA_H) \ $(TREE_PASS_H) $(FLAGS_H) $(DIAGNOSTIC_H) $(TREE_DUMP_H) $(CFGLOOP_H) \ $(TREE_INLINE_H) $(PARAMS_H) $(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) ipa-inline.o : ipa-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \ $(DIAGNOSTIC_H) $(FIBHEAP_H) $(PARAMS_H) $(TREE_PASS_H) \ - $(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(RTL_H) $(IPA_PROP_H) \ + $(COVERAGE_H) $(GGC_H) $(TREE_SSA_H) $(RTL_H) $(IPA_PROP_H) \ $(EXCEPT_H) $(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) $(TARGET_H) \ $(IPA_UTILS_H) sreal.h ipa-inline-analysis.o : ipa-inline-analysis.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \ $(DIAGNOSTIC_H) $(PARAMS_H) $(TREE_PASS_H) $(CFGLOOP_H) \ - $(HASHTAB_H) $(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(IPA_PROP_H) \ + $(HASHTAB_H) $(COVERAGE_H) $(GGC_H) $(TREE_SSA_H) $(IPA_PROP_H) \ $(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) $(LTO_STREAMER_H) $(DATA_STREAMER_H) \ $(TREE_STREAMER_H) ipa-utils.h tree-scalar-evolution.h $(CFGLOOP_H) \ alloc-pool.h ipa-inline-transform.o : ipa-inline-transform.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \ $(TREE_PASS_H) \ - $(HASHTAB_H) $(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(IPA_PROP_H) \ + $(HASHTAB_H) $(COVERAGE_H) $(GGC_H) $(TREE_SSA_H) $(IPA_PROP_H) \ $(TREE_PASS_H) ipa-utils.o : ipa-utils.c $(IPA_UTILS_H) $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(DUMPFILE_H) $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) \ + coretypes.h $(DUMPFILE_H) $(TM_H) $(TREE_H) $(TREE_SSA_H) $(TREE_INLINE_H) \ langhooks.h pointer-set.h $(GGC_H) $(GIMPLE_H) $(SPLAY_TREE_H) \ $(CGRAPH_H) $(FLAGS_H) $(DIAGNOSTIC_H) ipa-reference.o : ipa-reference.c $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \ + coretypes.h $(TM_H) $(TREE_H) $(TREE_SSA_H) $(TREE_INLINE_H) langhooks.h \ pointer-set.h $(GGC_H) $(IPA_REFERENCE_H) $(IPA_UTILS_H) $(SPLAY_TREE_H) \ $(GIMPLE_H) $(CGRAPH_H) $(FLAGS_H) $(TREE_PASS_H) \ $(DIAGNOSTIC_H) $(FUNCTION_H) $(LTO_STREAMER_H) \ $(DIAGNOSTIC_CORE_H) $(DATA_STREAMER_H) ipa-pure-const.o : ipa-pure-const.c $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \ + coretypes.h $(TM_H) $(TREE_H) $(TREE_SSA_H) $(TREE_INLINE_H) langhooks.h \ pointer-set.h $(GGC_H) $(IPA_UTILS_H) $(TARGET_H) \ $(GIMPLE_H) $(CGRAPH_H) $(FLAGS_H) $(TREE_PASS_H) \ $(DIAGNOSTIC_H) $(CFGLOOP_H) $(SCEV_H) $(LTO_STREAMER_H) \ @@ -3052,7 +3049,7 @@ dse.o : dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(TM_P_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ $(RECOG_H) $(EXPR_H) $(DF_H) cselib.h $(DBGCNT_H) \ $(TREE_PASS_H) alloc-pool.h $(ALIAS_H) $(OPTABS_H) $(TARGET_H) \ - $(BITMAP_H) $(PARAMS_H) $(TREE_FLOW_H) $(HASH_TABLE_H) + $(BITMAP_H) $(PARAMS_H) $(TREE_SSA_H) $(HASH_TABLE_H) fwprop.o : fwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(DIAGNOSTIC_CORE_H) insn-config.h $(RECOG_H) $(FLAGS_H) $(OBSTACK_H) $(BASIC_BLOCK_H) \ $(DF_H) alloc-pool.h $(TREE_PASS_H) $(TARGET_H) \ @@ -3095,14 +3092,14 @@ mode-switching.o : mode-switching.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(INSN_ATTR_H) $(RECOG_H) $(BASIC_BLOCK_H) $(TM_P_H) $(FUNCTION_H) \ $(TREE_PASS_H) $(DF_H) $(TARGET_H) $(EMIT_RTL_H) tree-ssa-dce.o : tree-ssa-dce.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ - $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TM_H) \ + $(TREE_SSA_H) $(DIAGNOSTIC_H) $(TM_H) \ coretypes.h $(TREE_PASS_H) $(FLAGS_H) $(BASIC_BLOCK_H) \ $(GGC_H) $(GIMPLE_H) $(CFGLOOP_H) $(SCEV_H) $(GIMPLE_PRETTY_PRINT_H) tree-call-cdce.o : tree-call-cdce.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ - $(TREE_FLOW_H) $(TM_H) \ + $(TREE_SSA_H) $(TM_H) \ coretypes.h $(TREE_PASS_H) $(FLAGS_H) $(BASIC_BLOCK_H) \ $(GIMPLE_H) $(GIMPLE_PRETTY_PRINT_H) -tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_H) \ +tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_SSA_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(TM_P_H) \ $(DIAGNOSTIC_H) $(FUNCTION_H) $(TM_H) coretypes.h \ $(BASIC_BLOCK_H) $(TREE_PASS_H) langhooks.h $(PARAMS_H) \ @@ -3110,27 +3107,27 @@ tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_H) \ $(DIAGNOSTIC_CORE_H) $(HASH_TABLE_H) \ $(DBGCNT_H) $(GIMPLE_PRETTY_PRINT_H) gimple-fold.h wide-int-print.h tree-ssa-strlen.o : tree-ssa-strlen.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TREE_FLOW_H) $(TREE_PASS_H) domwalk.h alloc-pool.h tree-ssa-propagate.h \ + $(TREE_SSA_H) $(TREE_PASS_H) domwalk.h alloc-pool.h tree-ssa-propagate.h \ $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H) $(EXPR_H) $(HASH_TABLE_H) tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h alloc-pool.h \ - $(HASH_TABLE_H) $(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) \ + $(HASH_TABLE_H) $(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_SSA_H) \ $(IPA_PROP_H) $(DIAGNOSTIC_H) statistics.h \ $(PARAMS_H) $(TARGET_H) $(FLAGS_H) \ - $(DBGCNT_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H) + $(DBGCNT_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H) ipa-utils.h tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \ - $(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \ + $(TREE_H) $(TM_P_H) $(TREE_SSA_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \ $(TM_H) coretypes.h $(GIMPLE_H) $(CFGLOOP_H) \ $(TREE_PASS_H) $(FLAGS_H) $(EXPR_H) $(BASIC_BLOCK_H) \ $(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H) \ $(GIMPLE_PRETTY_PRINT_H) langhooks.h $(OPTABS_H) tree-complex.o : tree-complex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ - $(TM_H) $(FLAGS_H) $(TREE_FLOW_H) $(TREE_HASHER_H) $(GIMPLE_H) \ + $(TM_H) $(FLAGS_H) $(TREE_SSA_H) $(TREE_HASHER_H) $(GIMPLE_H) \ $(CFGLOOP_H) tree-iterator.h $(TREE_PASS_H) tree-ssa-propagate.h tree-emutls.o : tree-emutls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ - $(GIMPLE_H) $(TREE_PASS_H) $(TREE_FLOW_H) $(CGRAPH_H) langhooks.h \ + $(GIMPLE_H) $(TREE_PASS_H) $(TREE_SSA_H) $(CGRAPH_H) langhooks.h \ $(TARGET_H) $(TARGET_DEF_H) tree-iterator.h tree-vect-generic.o : tree-vect-generic.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ - $(TM_H) $(TREE_FLOW_H) $(GIMPLE_H) tree-iterator.h $(TREE_PASS_H) \ + $(TM_H) $(TREE_SSA_H) $(GIMPLE_H) tree-iterator.h $(TREE_PASS_H) \ $(FLAGS_H) $(OPTABS_H) $(MACHMODE_H) $(EXPR_H) \ langhooks.h $(FLAGS_H) $(DIAGNOSTIC_H) gt-tree-vect-generic.h $(GGC_H) \ coretypes.h insn-codes.h $(DIAGNOSTIC_H) $(TARGET_H) @@ -3157,25 +3154,25 @@ valtrack.o : valtrack.c $(VALTRACK_H) $(CONFIG_H) $(SYSTEM_H) \ var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(TREE_H) hard-reg-set.h insn-config.h reload.h $(FLAGS_H) \ $(BASIC_BLOCK_H) bitmap.h alloc-pool.h $(FIBHEAP_H) $(HASH_TABLE_H) \ - $(REGS_H) $(EXPR_H) $(TREE_PASS_H) $(TREE_FLOW_H) \ + $(REGS_H) $(EXPR_H) $(TREE_PASS_H) $(TREE_SSA_H) \ cselib.h $(TARGET_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) $(DIAGNOSTIC_H) \ pointer-set.h $(RECOG_H) $(TM_P_H) $(TREE_PRETTY_PRINT_H) $(ALIAS_H) profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) $(REGS_H) $(EXPR_H) $(FUNCTION_H) $(BASIC_BLOCK_H) \ - $(DIAGNOSTIC_CORE_H) $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h \ + $(DIAGNOSTIC_CORE_H) $(COVERAGE_H) $(TREE_SSA_H) value-prof.h \ $(CFGLOOP_H) profile.h mcf.o : mcf.c profile.h $(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h \ $(DUMPFILE_H) $(BASIC_BLOCK_H) langhooks.h $(GCOV_IO_H) $(TREE_H) tree-profile.o : tree-profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TARGET_H) $(TREE_H) $(FLAGS_H) $(FUNCTION_H) \ $(BASIC_BLOCK_H) $(DIAGNOSTIC_CORE_H) $(COVERAGE_H) $(TREE_H) value-prof.h \ - $(TREE_PASS_H) $(TREE_FLOW_H) gt-tree-profile.h $(CGRAPH_H) + $(TREE_PASS_H) $(TREE_SSA_H) gt-tree-profile.h $(CGRAPH_H) value-prof.o : value-prof.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ $(TM_H) \ $(BASIC_BLOCK_H) hard-reg-set.h profile.h value-prof.h $(EXPR_H) $(FLAGS_H) \ $(RECOG_H) insn-config.h $(OPTABS_H) $(REGS_H) $(GGC_H) $(DIAGNOSTIC_H) \ - $(TREE_H) $(COVERAGE_H) $(RTL_H) $(GCOV_IO_H) $(TREE_FLOW_H) \ + $(TREE_H) $(COVERAGE_H) $(RTL_H) $(GCOV_IO_H) $(TREE_SSA_H) \ tree-flow-inline.h $(TIMEVAR_H) $(DIAGNOSTIC_CORE_H) pointer-set.h \ $(GIMPLE_PRETTY_PRINT_H) $(DATA_STREAMER_H) loop-doloop.o : loop-doloop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ @@ -3192,8 +3189,8 @@ cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ $(GGC_H) $(OBSTACK_H) alloc-pool.h $(HASH_TABLE_H) $(CFGLOOP_H) $(TREE_H) \ $(BASIC_BLOCK_H) cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ - $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TIMEVAR_H) toplev.h $(DIAGNOSTIC_CORE_H) $(CFGLOOP_H) $(PRETTY_PRINT_H) -cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(TREE_H) $(BASIC_BLOCK_H) $(TREE_SSA_H) $(TIMEVAR_H) toplev.h $(DIAGNOSTIC_CORE_H) $(CFGLOOP_H) $(PRETTY_PRINT_H) +cfgexpand.o : cfgexpand.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(FUNCTION_H) $(TM_H) \ coretypes.h $(EXCEPT_H) langhooks.h $(TREE_PASS_H) $(RTL_H) \ $(DIAGNOSTIC_H) toplev.h $(DIAGNOSTIC_CORE_H) $(BASIC_BLOCK_H) $(FLAGS_H) debug.h $(PARAMS_H) \ @@ -3219,7 +3216,7 @@ cfgcleanup.o : cfgcleanup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ cfgloop.o : cfgloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) coretypes.h \ $(DUMPFILE_H) $(TM_H) \ $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(FLAGS_H) $(FUNCTION_H) \ - $(OBSTACK_H) toplev.h $(DIAGNOSTIC_CORE_H) $(TREE_FLOW_H) $(TREE_H) pointer-set.h \ + $(OBSTACK_H) toplev.h $(DIAGNOSTIC_CORE_H) $(TREE_SSA_H) $(TREE_H) pointer-set.h \ $(GGC_H) cfgloopanal.o : cfgloopanal.c coretypes.h $(DUMPFILE_H) $(CONFIG_H) \ $(SYSTEM_H) $(RTL_H) \ @@ -3238,11 +3235,11 @@ loop-invariant.o : loop-invariant.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(OBSTACK_H) $(HASH_TABLE_H) $(EXCEPT_H) $(PARAMS_H) $(REGS_H) ira.h cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \ $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) \ - coretypes.h $(TM_H) $(OBSTACK_H) $(TREE_FLOW_H) + coretypes.h $(TM_H) $(OBSTACK_H) $(TREE_SSA_H) loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(GGC_H) \ $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) \ coretypes.h $(TM_H) $(OBSTACK_H) $(TREE_PASS_H) $(FLAGS_H) \ - $(REGS_H) $(DF_H) $(TREE_FLOW_H) + $(REGS_H) $(DF_H) $(TREE_SSA_H) loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(DUMPFILE_H) \ $(RTL_H) $(TM_H) $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(PARAMS_H) \ @@ -3315,7 +3312,7 @@ alias.o : alias.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \ $(ALIAS_H) $(EMIT_RTL_H) $(GGC_H) $(FUNCTION_H) cselib.h $(TREE_H) $(TM_P_H) \ langhooks.h $(TARGET_H) gt-alias.h $(TIMEVAR_H) $(CGRAPH_H) \ $(SPLAY_TREE_H) $(DF_H) \ - tree-ssa-alias.h pointer-set.h $(TREE_FLOW_H) + tree-ssa-alias.h pointer-set.h $(TREE_SSA_H) stack-ptr-mod.o : stack-ptr-mod.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TREE_H) $(RTL_H) $(REGS_H) $(EXPR_H) $(TREE_PASS_H) \ $(BASIC_BLOCK_H) $(FLAGS_H) output.h $(DF_H) @@ -3455,7 +3452,7 @@ final.o : final.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_H) \ $(EXCEPT_H) debug.h xcoffout.h toplev.h $(DIAGNOSTIC_CORE_H) reload.h $(DWARF2OUT_H) \ $(TREE_PASS_H) $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H) $(EXPR_H) \ dbxout.h $(CGRAPH_H) $(COVERAGE_H) \ - $(DF_H) $(GGC_H) $(CFGLOOP_H) $(PARAMS_H) $(TREE_FLOW_H) \ + $(DF_H) $(GGC_H) $(CFGLOOP_H) $(PARAMS_H) $(TREE_SSA_H) \ $(TARGET_DEF_H) $(TREE_PRETTY_PRINT_H) wide-int-print.h recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_H) \ $(FUNCTION_H) $(BASIC_BLOCK_H) $(REGS_H) $(RECOG_H) $(EXPR_H) \ @@ -3473,7 +3470,7 @@ predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ hard-reg-set.h $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(FUNCTION_H) $(EXCEPT_H) \ $(TM_P_H) $(PREDICT_H) sreal.h $(PARAMS_H) $(TARGET_H) $(CFGLOOP_H) \ $(COVERAGE_H) $(SCEV_H) $(GGC_H) predict.def \ - $(TREE_FLOW_H) $(TREE_PASS_H) $(EXPR_H) pointer-set.h + $(TREE_SSA_H) $(TREE_PASS_H) $(EXPR_H) pointer-set.h lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(DIAGNOSTIC_CORE_H) \ $(RTL_H) $(GGC_H) gt-lists.h bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ @@ -3484,7 +3481,7 @@ bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ tracer.o : tracer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(BASIC_BLOCK_H) hard-reg-set.h \ $(FLAGS_H) $(PARAMS_H) $(COVERAGE_H) $(FIBHEAP_H) \ - $(TREE_PASS_H) $(TREE_FLOW_H) $(TREE_INLINE_H) $(CFGLOOP_H) + $(TREE_PASS_H) $(TREE_SSA_H) $(TREE_INLINE_H) $(CFGLOOP_H) timevar.o : timevar.c $(CONFIG_H) $(SYSTEM_H) $(TIMEVAR_H) regcprop.o : regcprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \ @@ -3848,8 +3845,8 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \ $(srcdir)/cgraphclones.c \ $(srcdir)/tree-ssa-propagate.c \ $(srcdir)/tree-phinodes.c \ - $(srcdir)/lto-symtab.c \ $(srcdir)/tree-ssa-alias.h \ + $(srcdir)/tree-ssanames.h \ $(srcdir)/ipa-prop.h \ $(srcdir)/trans-mem.c \ $(srcdir)/lto-streamer.h \ @@ -4702,7 +4699,7 @@ PLUGIN_HEADERS = $(TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(host_xm_file_list) $(host_xm_include_list) $(xm_include_list) \ intl.h $(PLUGIN_VERSION_H) $(DIAGNOSTIC_H) ${C_TREE_H} \ $(C_COMMON_H) c-family/c-objc.h $(C_PRETTY_PRINT_H) \ - tree-iterator.h $(PLUGIN_H) $(TREE_FLOW_H) langhooks.h incpath.h debug.h \ + tree-iterator.h $(PLUGIN_H) $(TREE_SSA_H) langhooks.h incpath.h debug.h \ $(EXCEPT_H) tree-ssa-sccvn.h real.h output.h $(IPA_UTILS_H) \ $(C_PRAGMA_H) $(CPPLIB_H) $(FUNCTION_H) \ cppdefault.h flags.h $(MD5_H) params.def params.h prefix.h tree-inline.h \ @@ -4784,20 +4781,14 @@ install-common: native lang.install-common installdirs fi # Install the driver program as $(target_noncanonical)-gcc, -# $(target_noncanonical)-gcc-$(version) -# and also as either gcc (if native) or $(gcc_tooldir)/bin/gcc. +# $(target_noncanonical)-gcc-$(version), and also as gcc if native. install-driver: installdirs xgcc$(exeext) -rm -f $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext) -$(INSTALL_PROGRAM) xgcc$(exeext) $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext) -rm -f $(DESTDIR)$(bindir)/$(target_noncanonical)-gcc-$(version)$(exeext) -( cd $(DESTDIR)$(bindir) && \ $(LN) $(GCC_INSTALL_NAME)$(exeext) $(target_noncanonical)-gcc-$(version)$(exeext) ) - -if [ -f gcc-cross$(exeext) ] ; then \ - if [ -d $(DESTDIR)$(gcc_tooldir)/bin/. ] ; then \ - rm -f $(DESTDIR)$(gcc_tooldir)/bin/gcc$(exeext); \ - $(INSTALL_PROGRAM) gcc-cross$(exeext) $(DESTDIR)$(gcc_tooldir)/bin/gcc$(exeext); \ - else true; fi; \ - else \ + -if [ ! -f gcc-cross$(exeext) ] ; then \ rm -f $(DESTDIR)$(bindir)/$(target_noncanonical)-gcc-tmp$(exeext); \ ( cd $(DESTDIR)$(bindir) && \ $(LN) $(GCC_INSTALL_NAME)$(exeext) $(target_noncanonical)-gcc-tmp$(exeext) && \ diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4 index 1f3ce9d6935..a992c3a96ed 100644 --- a/gcc/aclocal.m4 +++ b/gcc/aclocal.m4 @@ -99,6 +99,11 @@ m4_define([AC_PROG_CC], [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) ]) +m4_include([../libtool.m4]) +m4_include([../ltoptions.m4]) +m4_include([../ltsugar.m4]) +m4_include([../ltversion.m4]) +m4_include([../lt~obsolete.m4]) m4_include([../config/acx.m4]) m4_include([../config/codeset.m4]) m4_include([../config/dfp.m4]) @@ -114,9 +119,4 @@ m4_include([../config/picflag.m4]) m4_include([../config/progtest.m4]) m4_include([../config/stdint.m4]) m4_include([../config/warnings.m4]) -m4_include([../libtool.m4]) -m4_include([../ltoptions.m4]) -m4_include([../ltsugar.m4]) -m4_include([../ltversion.m4]) -m4_include([../lt~obsolete.m4]) m4_include([acinclude.m4]) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 61fd991bef2..6b0ba092134 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,387 @@ +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, + not $target_cpu. + +2013-09-11 Thomas Schwinge <thomas@codesourcery.com> + Olivier Hainque <hainque@adacore.com> + + * gcc-interface/Makefile.in: Import target_cpu, target_vendor, + target_os and their host_ counterparts. Remove host_canonical and + target_cpu_default, unused. Remove local ad-hoc computations of + "host", "targ", "arch", "osys" and "manu". Replace uses of these by + uses of the now imported family, hence back to filters against + canonical values. Remove filters on e500 for target_cpu, expected to + be canonicalized into powerpc. Invert the logic filtering on 64bit + sparc for VxWorks. Simplify the filtering logic for bareboard tools + target pairs, now using straight elf/eabi filters on the target_os + part only. + +2013-09-10 Ed Schonberg <schonberg@adacore.com> + + * sem_ch3.adb (Replace_Anonymoous_Access_To_Protected_Subprogram): If + the return type is itself an access to function, recurse to emit + another anonymous type. + * gcc-interface/Make-lang.in: Update dependencies. + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * err_vars.ads (Warning_Doc_Switch): Ignored in VMS mode. + * errout.adb (Warning_Doc_Switch): Ignored in VMS mode. + * errout.ads (Warning_Doc_Switch): Ignored in VMS mode. + * inline.ads (Warnings): New component in Pending_Body_Info. + * sem_ch12.adb (Pending_Body_Info): Save and restore warnings + at instantiation point. + * warnsw.adb (Save_Warnings): New function (Restore_Warnings): + New procedure Remove special handling of Warning_Doc_Switch, + cleaner to handle the VMS case in errout, than to introduce + undocumented oddities here. + * warnsw.ads (Warning_Record) : New type. + (Save_Warnings): New function. + (Restore_Warnings): New procedure. + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * sinput.adb (Check_For_BOM): Avoid reading past end of file. + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * errout.adb (Error_Msg_Ada_2012_Feature): New procedure. + * errout.ads (Error_Msg_Ada_2012_Feature): New procedure. + * inline.ads: Save/Restore Ada_Version_Pragma. + * opt.adb: Save/Restore Ada_Version_Pragma. + * opt.ads (Ada_Version_Pragma): New variable. + * par-ch11.adb, par-ch12.adb, par-ch13.adb, par-ch4.adb, par-ch5.adb, + par-ch6.adb, par-ch8.adb, par-prag.adb: Use Error_Msg_Ada_2012_Feature. + * prj.adb: Initialize Ada_Version_Pragma. + * sem_attr.adb: Use Error_Msg_Ada_2012_Feature. + * sem_ch12.adb, sem_ch8.adb: Save/restore Ada_Version_Pragma. + * sem_prag.adb (Analyze_Pragma, cases Ada_xx): Set Ada_Version_Pragma. + * switch-c.adb: Initialize Ada_Version_Pragma. + * sem_ch12.adb: Minor reformatting. + +2013-09-10 Ed Schonberg <schonberg@adacore.com> + + * sem_ch3.adb (Process_Subtype): Discard constraint on access + to class-wide type. Such constraints are not supported and are + considered a language pathology. + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * gnatbind.adb: Correct starting date in --version string. + * gnatdll.adb: Use Check_Version_And_Help_G to implement --help + and --version. + * gnatkr.adb: Use Check_Version_And_Help_G to implement --help + and --version. + * gnatlink.adb: Correct starting date in --version string. + * gnatls.adb: Correct starting date in --version string. + * make.adb: Correct starting date in --version string. + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * switch-c.adb: Minor reformatting. + * atree.ads (Original_Nodes): Add documentation on ASIS usage. + * sinfo.ads: Add section on ASIS mode (documentation only). + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * sem_prag.adb (Analyze_Pragma, case Warnings): Don't allow + REASON parameter in compiler units (bootstrap issues). + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * gnat1drv.adb (Adjust_Global_Switches): Output warning if + -gnateE specified for a target that does not support it. + +2013-09-10 Ed Schonberg <schonberg@adacore.com> + + * sem_prag.adb (Analyze_Pragma, case SPARK_Mode): Handle properly + a subprogram body without previous spec. + +2013-09-10 Gary Dismukes <dismukes@adacore.com> + + * sem_ch4.adb: Minor typo fixes. + +2013-09-10 Hristian Kirtchev <kirtchev@adacore.com> + + * aspects.adb (Aspects_On_Body_OK): New routine. + * aspects.ads: Modify type Aspect_Expression to include + the Optional_XXX variants. Update the contents of + table Aspect_Argument. Add table Aspect_On_Body_OK. + (Aspects_On_Body_OK): New routine. + * par-ch13.adb (Get_Aspect_Specifications): Account for optional + names and expressions when parsing an aspect. + * sem_ch6.adb: Add with and use clause for Aspects. + (Analyze_Subprogram_Body_Helper): Do not emit an error when + analyzing a body with aspects that can be applied simultaneously + to both spec and body. + * sem_ch13.adb (Analyze_Aspect_Specifications): Insert the + corresponding pragma of an aspect that applies to a subprogram + body in the declarative part. + (Make_Aitem_Pragma): Do not generate a pragma with an empty argument + list. + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * switch-c.adb: Diagnose -gnatc given after -gnatRm. + * gnat_ugn.texi: Add documentation for -gnatRm. + * usage.adb: Minor reorganization (put style entries in proper + order) Document -gnatRm switch. + * sinfo.ads: Minor comment fix. + +2013-09-10 Sergey Rybin <rybin@adacore.com frybin> + + * tree_io.ads: Update ASIS_Version_Number. + +2013-09-10 Ed Schonberg <schonberg@adacore.com> + + * sem_ch3.adb (Access_Subprogram_Declaration): Check whether the + designated type can appear in a parameterless call. + * sem_ch4.adb (Analyze_Call): Do not insert an explicit dereference + in the case of an indirect call through an access function that + returns an array type. + (Analyze_One_Call): Handle properly legal parameterless calls + whose result is indexed, in constructs of the for F.all (I) + * sem_ch6.ads (May_Need_Actuals): Make public, for use on access + to subprogram types. + * sem_res.adb (Resolve_Call): If the call is indirect, there is + no entity to set on the name in the call. + +2013-09-10 Hristian Kirtchev <kirtchev@adacore.com> + + * aspects.adb: Add entries in the Has_Aspect_Specifications_Flag + table for package body and body stubs. + (Move_Or_Merge_Aspects): New routine. + (Remove_Aspects): New routine. + * aspects.ads (Move_Aspects): Update comment on usage. + (Move_Or_Merge_Aspects): New routine. + (Remove_Aspects): New routine. + * par-ch3.adb: Update the grammar of private_type_declaration, + private_extension_declaration, object_renaming_declaration, + and exception_renaming_declaration. + (P_Subprogram): Parse the + aspect specifications that apply to a body stub. + * par-ch6.adb: Update the grammar of subprogram_body_stub and + generic_instantiation. + * par-ch7.adb: Update the grammar of package_declaration, + package_specification, package_body, package_renaming_declaration, + package_body_stub. + (P_Package): Parse the aspect specifications + that apply to a body, a body stub and package renaming. + * par-ch9.adb: Update the grammar of entry_declaration, + protected_body, protected_body_stub, task_body, + and task_body_stub. + (P_Protected): Add local variable + Aspect_Sloc. Add local constant Dummy_Node. Parse the aspect + specifications that apply to a protected body and a protected + body stub. + (P_Task): Add local variable Aspect_Sloc. Add local + constant Dummy_Node. Parse the aspect specifications that apply + to a task body and a task body stub. + * par-ch12.adb: Update the grammar of + generic_renaming_declaration. + (P_Generic): Parse the aspect + specifications that apply to a generic renaming. + * sem_ch6.adb (Analyze_Subprogram_Body_Helper): Do not emit + an error when analyzing aspects that apply to a body stub. Such + aspects are relocated to the proper body. + * sem_ch7.adb (Analyze_Package_Body_Helper): Analyze the aspect + specifications that apply to a body. + * sem_ch9.adb (Analyze_Protected_Body): Warn about user-defined + aspects not being supported on protected bodies. Remove the + aspect specifications. (Analyze_Single_Protected_Declaration): + Analyze the aspects that apply to a single protected declaration. + (Analyze_Task_Body): Warn about user-defined aspects not being + supported on task bodies. Remove the aspect specifications. + * sem_ch10.adb: Add with and use clause for Aspects. + (Analyze_Package_Body_Stub): Propagate the aspect specifications + from the stub to the proper body. + * sem_ch13.adb (Analyze_Aspect_Specifications): Insert the + corresponding pragma of an aspect that applies to a body in the + declarations of the body. + * sinfo.ads: Update the gramma of expression_function, + private_type_declaration, private_extension_declaration, + object_renaming_declaration, exception_renaming_declaration, + package_renaming_declaration, subprogram_renaming_declaration, + generic_renaming_declaration, entry_declaration, + subprogram_body_stub, package_body_stub, task_body_stub, + generic_subprogram_declaration. + +2013-09-10 Hristian Kirtchev <kirtchev@adacore.com> + + * sem_prag.adb (Analyze_Pragma): Add processing + for aspect/pragma SPARK_Mode when it applies to a [library-level] + subprogram or package [body]. + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * gnat_ugn.texi: Document that -gnatc and -gnatR cannot be + given together. + * switch-c.adb (Scan_Front_End_Switches): Give error if both + -gnatR and -gnatc given. + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * g-table.ads, g-table.adb (For_Each): New generic procedure + (Sort_Table): New generic procedure. + +2013-09-10 Thomas Quinot <quinot@adacore.com> + + * adaint.c (__gnat_is_executable_file_attr): Should be true + for an executable regular file only only (not for a directory + that has the executable permission). + +2013-09-10 Ed Schonberg <schonberg@adacore.com> + + * sem_res.adb: Further work on operator calls in ASIS. + +2013-09-10 Yannick Moy <moy@adacore.com> + + * sinfo.ads, sem_prag.ads, sem_ch13.adb: Minor correction and comment + update. + +2013-09-10 Thomas Quinot <quinot@adacore.com> + + * aspects.ads, sem_ch13.adb: Minor reformatting. + * adaint.c (__gnat_set_close_on_exec): Add comment documenting + that this routine is shared between OS_Lib and Sockets. + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * exp_prag.adb (Expand_Pragma_Check): Ignore pragma if Is_Ignored set. + * sem_ch13.adb (Make_Aitem_Pragma): Set Is_Checked if needed. + * sem_prag.adb (Check_Kind): Moved from spec (Analyze_Pragma): + Make sure Is_Ignored/Is_Checked are set right (Analyze_Pragma, + case Check): Ditto (Check_Applicable_Policy): Handle + Statement_Assertion case Throughout, set and check the Is_Checked + flag as appropriate. + * sem_prag.ads (Check_Kind): Moved to body. + * sinfo.ads, sinfo.adb (Is_Checked): New flag. + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * aspects.ads (Delay_Type): New type (Aspect_Delay): New table. + * einfo.adb (Has_Delayed_Rep_Aspects): New flag + (May_Inherit_Delayed_Rep_Aspects): New flag (Rep_Clause): Removed + (use Get_Attribute_Representation_Clause). + * einfo.ads (Has_Delayed_Rep_Aspects): New flag + (May_Inherit_Delayed_Rep_Aspects): New flag + * freeze.adb: Minor reformatting + * sem_ch13.adb (Analyze_Aspect_Speficifications): Redo + handling of delayed evaluation, including optimizing some cases + and avoiding delays. + (Analyze_Aspects_At_Freeze_Point): Now + handled inheriting delayed rep aspects for type derivation case. + (Inherit_Delayed_Rep_Aspects): New procedure + * sem_ch13.ads (Analyze_Aspects_At_Freeze_Point): Now handled + inheriting delayed rep aspects for type derivation case. + * sem_ch3.adb (Build_Derived_Type): Set + May_Inherit_Derived_Rep_Aspects if parent type flag + Has_Delayed_Rep_Aspects is set + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * errout.adb (Finalize): Don't delete real errors with specific + warning control. + +2013-09-10 Ed Schonberg <schonberg@adacore.com> + + * exp_ch9.adb (Expand_N_Timed_Entry_Call, + Expand_N_Conditional_Entry_Call, Expand_N_Asynchronous_Select): + Handle properly a trigger that is a call to a primitive operation + of a type that implements a limited interface, if the type itself + is not limited. + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * sem_ch3.adb, sinfo.ads, exp_ch9.adb, sem_prag.adb, sem_ch12.adb, + exp_ch4.adb, sprint.adb: Minor reformatting. + +2013-09-10 Yannick Moy <moy@adacore.com> + + * sinfo.ads: Document splitting of pre/post in N_Contract description. + +2013-09-10 Ed Schonberg <schonberg@adacore.com> + + * exp_ch4.adb (Expand_N_Op_Multiply): If the operation is of the + form X * 2 ** N and it has been marked Is_Power_Of_2_For_Shift, + add a mod operation if the result type is a binary modular type. + +2013-09-10 Hristian Kirtchev <kirtchev@adacore.com> + + * sem_prag.adb (Check_Mode_Restriction_In_Enclosing_Context): Add local + variable Context. Remove local variable Subp_Id. Start the + context traversal from the current subprogram rather than the + current scope. Update the scope traversal and error reporting. + +2013-09-10 Ed Schonberg <schonberg@adacore.com> + + * exp_ch9.adb (Expand_N_Timed_Entry_Call): New procedure + Rewrite_Triggering_Statements, to encapsulate the statements that + follow the trigger of the entry call. This procedure is needed + when the trigger is a dispatching call, because the expansion + requires several copies of those statements. The procedure is + more efficient, and preserves non-local references when the + construct is within an instance. + +2013-09-10 Ed Schonberg <schonberg@adacore.com> + + * sem_ch12.adb (Analyze_Package_Instantiation): If the + instantiation is a compilation unit, analyze aspects before + analyzing the package declaration for the instance. + * sem_ch13.adb (Analyze_Aspect_Specifications): If the + corresponding node is a package instantiation, insert generated + pragmas at the head of visible declarations. + * sem_prag.adb (Analyze_Pragma, case Preelaborate): In an instance + do not ignore the pragma if it comes from an aspect specification + in the instance, and not from the generic unit. + * sprint.adb (Sprint_Node_Actual): For a package declaration that + is an instantiation, print aspects after declaration. + +2013-09-10 Robert Dewar <dewar@adacore.com> + + * einfo.adb, sem_prag.adb, rtsfind.ads: Minor reformatting. + +2013-09-10 Hristian Kirtchev <kirtchev@adacore.com> + + * sem_prag.adb (Get_SPARK_Mode_Id): Handle the + case where the pragma may appear without an argument. + (Analyze_Global_List): Add expanded_name to the list of constructs + that denote a single item. + (Collect_Global_List): Add expanded_name to the list of constructs + that denote a single item. + +2013-09-10 Hristian Kirtchev <kirtchev@adacore.com> + + * exp_ch4.adb (Apply_Accessibility_Check): Add local constant + Pool_Id and local variables Fin_Call and Free_Stmt. Finalize + and deallocate a heap-allocated class-wide object after it + has been determined that it violates the accessibility rules. + * rtsfind.ads: Add new RTU_Id for System.Memory. Add new RE_Id + and entry in RE_Unit_Table for RE_Free. + 2013-09-01 Eric Botcazou <ebotcazou@adacore.com> Iain Sandoe <iain@codesourcery.com> @@ -297,7 +681,7 @@ node for subsequent checks, because the rewriting of the node does not take place during pre-analysis. - 2013-07-08 Robert Dewar <dewar@adacore.com> +2013-07-08 Robert Dewar <dewar@adacore.com> * sem_ch8.adb, exp_ch3.adb: Minor reformatting. diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c index c4bb7540c52..f76edb73995 100644 --- a/gcc/ada/adaint.c +++ b/gcc/ada/adaint.c @@ -2264,7 +2264,7 @@ __gnat_is_executable_file_attr (char* name, struct file_attributes* attr) #endif } - return attr->executable; + return attr->regular && attr->executable; } int @@ -3748,6 +3748,11 @@ get_gcc_version (void) #endif } +/* + * Set Close_On_Exec as indicated. + * Note: this is used for both GNAT.OS_Lib and GNAT.Sockets. + */ + int __gnat_set_close_on_exec (int fd ATTRIBUTE_UNUSED, int close_on_exec_p ATTRIBUTE_UNUSED) diff --git a/gcc/ada/aspects.adb b/gcc/ada/aspects.adb index d02edb25702..1d736467b46 100644 --- a/gcc/ada/aspects.adb +++ b/gcc/ada/aspects.adb @@ -140,6 +140,40 @@ package body Aspects is end if; end Aspect_Specifications; + ------------------------ + -- Aspects_On_Body_OK -- + ------------------------ + + function Aspects_On_Body_OK (N : Node_Id) return Boolean is + Aspect : Node_Id; + Aspects : List_Id; + + begin + -- The routine should be invoked on a body [stub] with aspects + + pragma Assert (Has_Aspects (N)); + pragma Assert (Nkind (N) in N_Body_Stub + or else Nkind_In (N, N_Package_Body, + N_Protected_Body, + N_Subprogram_Body, + N_Task_Body)); + + -- Look through all aspects and see whether they can be applied to a + -- body. + + Aspects := Aspect_Specifications (N); + Aspect := First (Aspects); + while Present (Aspect) loop + if not Aspect_On_Body_OK (Get_Aspect_Id (Aspect)) then + return False; + end if; + + Next (Aspect); + end loop; + + return True; + end Aspects_On_Body_OK; + ----------------- -- Find_Aspect -- ----------------- @@ -271,6 +305,31 @@ package body Aspects is end if; end Move_Aspects; + --------------------------- + -- Move_Or_Merge_Aspects -- + --------------------------- + + procedure Move_Or_Merge_Aspects (From : Node_Id; To : Node_Id) is + begin + if Has_Aspects (From) then + + -- Merge the aspects of From into To. Make sure that From has no + -- aspects after the merge takes place. + + if Has_Aspects (To) then + Append_List + (List => Aspect_Specifications (From), + To => Aspect_Specifications (To)); + Remove_Aspects (From); + + -- Otherwise simply move the aspects + + else + Move_Aspects (From => From, To => To); + end if; + end if; + end Move_Or_Merge_Aspects; + ----------------------------------- -- Permits_Aspect_Specifications -- ----------------------------------- @@ -294,6 +353,8 @@ package body Aspects is N_Generic_Subprogram_Declaration => True, N_Object_Declaration => True, N_Object_Renaming_Declaration => True, + N_Package_Body => True, + N_Package_Body_Stub => True, N_Package_Declaration => True, N_Package_Instantiation => True, N_Package_Specification => True, @@ -302,6 +363,7 @@ package body Aspects is N_Private_Type_Declaration => True, N_Procedure_Instantiation => True, N_Protected_Body => True, + N_Protected_Body_Stub => True, N_Protected_Type_Declaration => True, N_Single_Protected_Declaration => True, N_Single_Task_Declaration => True, @@ -311,6 +373,7 @@ package body Aspects is N_Subprogram_Body_Stub => True, N_Subtype_Declaration => True, N_Task_Body => True, + N_Task_Body_Stub => True, N_Task_Type_Declaration => True, others => False); @@ -319,6 +382,18 @@ package body Aspects is return Has_Aspect_Specifications_Flag (Nkind (N)); end Permits_Aspect_Specifications; + -------------------- + -- Remove_Aspects -- + -------------------- + + procedure Remove_Aspects (N : Node_Id) is + begin + if Has_Aspects (N) then + Aspect_Specifications_Hash_Table.Remove (N); + Set_Has_Aspects (N, False); + end if; + end Remove_Aspects; + ----------------- -- Same_Aspect -- ----------------- diff --git a/gcc/ada/aspects.ads b/gcc/ada/aspects.ads index 5a093af21cf..5e8046d1ad0 100644 --- a/gcc/ada/aspects.ads +++ b/gcc/ada/aspects.ads @@ -273,14 +273,15 @@ package Aspects is -- The following type is used for indicating allowed expression forms type Aspect_Expression is - (Optional, -- Optional boolean expression - Expression, -- Required expression - Name); -- Required name + (Expression, -- Required expression + Name, -- Required name + Optional_Expression, -- Optional boolean expression + Optional_Name); -- Optional name -- The following array indicates what argument type is required Aspect_Argument : constant array (Aspect_Id) of Aspect_Expression := - (No_Aspect => Optional, + (No_Aspect => Optional_Expression, Aspect_Abstract_State => Expression, Aspect_Address => Expression, Aspect_Alignment => Expression, @@ -323,7 +324,7 @@ package Aspects is Aspect_Simple_Storage_Pool => Name, Aspect_Size => Expression, Aspect_Small => Expression, - Aspect_SPARK_Mode => Name, + Aspect_SPARK_Mode => Optional_Name, Aspect_Static_Predicate => Expression, Aspect_Storage_Pool => Name, Aspect_Storage_Size => Expression, @@ -338,8 +339,8 @@ package Aspects is Aspect_Warnings => Name, Aspect_Write => Name, - Boolean_Aspects => Optional, - Library_Unit_Aspects => Optional); + Boolean_Aspects => Optional_Expression, + Library_Unit_Aspects => Optional_Expression); ----------------------------------------- -- Table Linking Names and Aspect_Id's -- @@ -459,6 +460,214 @@ package Aspects is -- Given an aspect specification, return the corresponding aspect_id value. -- If the name does not match any aspect, return No_Aspect. + ------------------------------------ + -- Delaying Evaluation of Aspects -- + ------------------------------------ + + -- The RM requires that all language defined aspects taking an expression + -- delay evaluation of the expression till the freeze point of the entity + -- to which the aspect applies. This allows forward references, and is of + -- use for example in connection with preconditions and postconditions + -- where the requirement of making all references in contracts to local + -- functions be backwards references would be onerous. + + -- For consistency, even attributes like Size are delayed, so we can do: + + -- type A is range 1 .. 10 + -- with Size => Not_Defined_Yet; + -- .. + -- Not_Defined_Yet : constant := 64; + + -- Resulting in A having a size of 64, which gets set when A is frozen. + -- Furthermore, we can have a situation like + + -- type A is range 1 .. 10 + -- with Size => Not_Defined_Yet; + -- .. + -- type B is new A; + -- .. + -- Not_Defined_Yet : constant := 64; + + -- where the Size of A is considered to have been previously specified at + -- the point of derivation, even though the actual value of the size is + -- not known yet, and in this example B inherits the size value of 64. + + -- Our normal implementation model (prior to Ada 2012) was simply to copy + -- inheritable attributes at the point of derivation. Then any subsequent + -- representation items apply either to the parent type, not affecting the + -- derived type, or to the derived type, not affecting the parent type. + + -- To deal with the delayed aspect case, we use two flags. The first is + -- set on the parent type if it has delayed representation aspects. This + -- flag Has_Delayed_Rep_Aspects indicates that if we derive from this type + -- we have to worry about making sure we inherit any delayed aspects. The + -- second flag is set on a derived type: May_Have_Inherited_Rep_Aspects + -- is set if the parent type has Has_Delayed_Rep_Aspects set. + + -- When we freeze a derived type, if the May_Have_Inherited_Rep_Aspects + -- flag is set, then we call Freeze.Inherit_Delayed_Rep_Aspects when + -- the derived type is frozen, which deals with the necessary copying of + -- information from the parent type, which must be frozen at that point + -- (since freezing the derived type first freezes the parent type). + + -- The following shows which aspects are delayed. There are three cases: + + type Delay_Type is + (Always_Delay, + -- This aspect is not a representation aspect that can be inherited and + -- is always delayed, as required by the language definition. + + Never_Delay, + -- There are two cases. There are language defined aspects like + -- Convention where the "expression" is simply an uninterpreted + -- identifier, and there is no issue of evaluating it and thus no + -- issue of delaying the evaluation. The second case is implementation + -- defined aspects where we have decided that we don't want to allow + -- delays (and for our own aspects we can do what we like!). + + Rep_Aspect); + -- These are the cases of representation aspects that are in general + -- delayed, and where there is a potential issue of derived types that + -- inherit delayed representation values. + + -- Note: even if this table indicates that an aspect is delayed, we never + -- delay Boolean aspects that have a missing expression (taken as True), + -- or expressions for delayed rep items that consist of an integer literal + -- (most cases of Size etc. in practice), since in these cases we know we + -- can get the value of the expression without delay. Note that we still + -- need to delay Boolean aspects that are specifically set to True: + + -- type R is array (0 .. 31) of Boolean + -- with Pack => True; + -- True : constant Boolean := False; + + -- This is nonsense, but we need to make it work and result in R not + -- being packed, and if we have something like: + + -- type R is array (0 .. 31) of Boolean + -- with Pack => True; + -- RR : R; + -- True : constant Boolean := False; + + -- This is illegal because the visibility of True changes after the freeze + -- point, which is not allowed, and we need the delay mechanism to properly + -- diagnose this error. + + Aspect_Delay : constant array (Aspect_Id) of Delay_Type := + (No_Aspect => Always_Delay, + Aspect_Address => Always_Delay, + Aspect_All_Calls_Remote => Always_Delay, + Aspect_Asynchronous => Always_Delay, + Aspect_Attach_Handler => Always_Delay, + Aspect_Compiler_Unit => Always_Delay, + Aspect_Constant_Indexing => Always_Delay, + Aspect_Contract_Cases => Always_Delay, + Aspect_CPU => Always_Delay, + Aspect_Default_Iterator => Always_Delay, + Aspect_Default_Value => Always_Delay, + Aspect_Default_Component_Value => Always_Delay, + Aspect_Depends => Always_Delay, + Aspect_Discard_Names => Always_Delay, + Aspect_Dispatching_Domain => Always_Delay, + Aspect_Dynamic_Predicate => Always_Delay, + Aspect_Elaborate_Body => Always_Delay, + Aspect_External_Name => Always_Delay, + Aspect_External_Tag => Always_Delay, + Aspect_Export => Always_Delay, + Aspect_Favor_Top_Level => Always_Delay, + Aspect_Global => Always_Delay, + Aspect_Implicit_Dereference => Always_Delay, + Aspect_Import => Always_Delay, + Aspect_Independent => Always_Delay, + Aspect_Independent_Components => Always_Delay, + Aspect_Inline => Always_Delay, + Aspect_Inline_Always => Always_Delay, + Aspect_Input => Always_Delay, + Aspect_Interrupt_Handler => Always_Delay, + Aspect_Interrupt_Priority => Always_Delay, + Aspect_Invariant => Always_Delay, + Aspect_Iterator_Element => Always_Delay, + Aspect_Link_Name => Always_Delay, + Aspect_Lock_Free => Always_Delay, + Aspect_No_Return => Always_Delay, + Aspect_Output => Always_Delay, + Aspect_Persistent_BSS => Always_Delay, + Aspect_Post => Always_Delay, + Aspect_Postcondition => Always_Delay, + Aspect_Pre => Always_Delay, + Aspect_Precondition => Always_Delay, + Aspect_Predicate => Always_Delay, + Aspect_Preelaborable_Initialization => Always_Delay, + Aspect_Preelaborate => Always_Delay, + Aspect_Preelaborate_05 => Always_Delay, + Aspect_Priority => Always_Delay, + Aspect_Pure => Always_Delay, + Aspect_Pure_05 => Always_Delay, + Aspect_Pure_12 => Always_Delay, + Aspect_Pure_Function => Always_Delay, + Aspect_Read => Always_Delay, + Aspect_Relative_Deadline => Always_Delay, + Aspect_Remote_Access_Type => Always_Delay, + Aspect_Remote_Call_Interface => Always_Delay, + Aspect_Remote_Types => Always_Delay, + Aspect_Shared => Always_Delay, + Aspect_Shared_Passive => Always_Delay, + Aspect_Simple_Storage_Pool => Always_Delay, + Aspect_Simple_Storage_Pool_Type => Always_Delay, + Aspect_Static_Predicate => Always_Delay, + Aspect_Storage_Pool => Always_Delay, + Aspect_Stream_Size => Always_Delay, + Aspect_Suppress => Always_Delay, + Aspect_Suppress_Debug_Info => Always_Delay, + Aspect_Type_Invariant => Always_Delay, + Aspect_Unchecked_Union => Always_Delay, + Aspect_Universal_Aliasing => Always_Delay, + Aspect_Universal_Data => Always_Delay, + Aspect_Unmodified => Always_Delay, + Aspect_Unreferenced => Always_Delay, + Aspect_Unreferenced_Objects => Always_Delay, + Aspect_Unsuppress => Always_Delay, + Aspect_Variable_Indexing => Always_Delay, + Aspect_Write => Always_Delay, + + Aspect_Abstract_State => Never_Delay, + Aspect_Ada_2005 => Never_Delay, + Aspect_Ada_2012 => Never_Delay, + Aspect_Convention => Never_Delay, + Aspect_Dimension => Never_Delay, + Aspect_Dimension_System => Never_Delay, + Aspect_SPARK_Mode => Never_Delay, + Aspect_Synchronization => Never_Delay, + Aspect_Test_Case => Never_Delay, + Aspect_Warnings => Never_Delay, + + Aspect_Alignment => Rep_Aspect, + Aspect_Atomic => Rep_Aspect, + Aspect_Atomic_Components => Rep_Aspect, + Aspect_Bit_Order => Rep_Aspect, + Aspect_Component_Size => Rep_Aspect, + Aspect_Machine_Radix => Rep_Aspect, + Aspect_Object_Size => Rep_Aspect, + Aspect_Pack => Rep_Aspect, + Aspect_Scalar_Storage_Order => Rep_Aspect, + Aspect_Size => Rep_Aspect, + Aspect_Small => Rep_Aspect, + Aspect_Storage_Size => Rep_Aspect, + Aspect_Value_Size => Rep_Aspect, + Aspect_Volatile => Rep_Aspect, + Aspect_Volatile_Components => Rep_Aspect); + + -- The following table indicates which aspects can apply simultaneously to + -- both subprogram/package specs and bodies. For instance, the following is + -- legal: + + -- package P with SPARK_Mode ...; + -- package body P with SPARK_Mode is ...; + + Aspect_On_Body_OK : constant array (Aspect_Id) of Boolean := + (Aspect_SPARK_Mode => True, + others => False); + --------------------------------------------------- -- Handling of Aspect Specifications in the Tree -- --------------------------------------------------- @@ -487,6 +696,10 @@ package Aspects is -- Replace calls, and this function may be used to retrieve the aspect -- specifications for the original rewritten node in such cases. + function Aspects_On_Body_OK (N : Node_Id) return Boolean; + -- N denotes a body [stub] with aspects. Determine whether all aspects of N + -- can appear simultaneously in bodies and specs. + function Find_Aspect (Id : Entity_Id; A : Aspect_Id) return Node_Id; -- Find the aspect specification of aspect A associated with entity I. -- Return Empty if Id does not have the requested aspect. @@ -501,16 +714,24 @@ package Aspects is -- Determine whether entity Id has aspect A procedure Move_Aspects (From : Node_Id; To : Node_Id); - -- Moves aspects from 'From' node to 'To' node. Has_Aspects (To) must be - -- False on entry. If Has_Aspects (From) is False, the call has no effect. - -- Otherwise the aspects are moved and on return Has_Aspects (To) is True, - -- and Has_Aspects (From) is False. + -- Relocate the aspect specifications of node From to node To. On entry it + -- is assumed that To does not have aspect specifications. If From has no + -- aspects, the routine has no effect. + + procedure Move_Or_Merge_Aspects (From : Node_Id; To : Node_Id); + -- Relocate the aspect specifications of node From to node To. If To has + -- aspects, the aspects of From are added to the aspects of To. If From has + -- no aspects, the routine has no effect. function Permits_Aspect_Specifications (N : Node_Id) return Boolean; -- Returns True if the node N is a declaration node that permits aspect -- specifications in the grammar. It is possible for other nodes to have -- aspect specifications as a result of Rewrite or Replace calls. + procedure Remove_Aspects (N : Node_Id); + -- Delete the aspect specifications associated with node N. If the node has + -- no aspects, the routine has no effect. + function Same_Aspect (A1 : Aspect_Id; A2 : Aspect_Id) return Boolean; -- Returns True if A1 and A2 are (essentially) the same aspect. This is not -- a simple equality test because e.g. Post and Postcondition are the same. diff --git a/gcc/ada/atree.ads b/gcc/ada/atree.ads index d1056b07a32..123beb3907e 100644 --- a/gcc/ada/atree.ads +++ b/gcc/ada/atree.ads @@ -939,12 +939,15 @@ package Atree is function Original_Node (Node : Node_Id) return Node_Id; pragma Inline (Original_Node); -- If Node has not been rewritten, then returns its input argument - -- unchanged, else returns the Node for the original subtree. + -- unchanged, else returns the Node for the original subtree. Note that + -- this is used extensively by ASIS on the trees constructed in ASIS mode + -- to reconstruct the original semantic tree. See section in sinfo.ads + -- for requirements on original nodes returned by this function. -- -- Note: Parents are not preserved in original tree nodes that are -- retrieved in this way (i.e. their children may have children whose - -- pointers which reference some other node). - + -- pointers which reference some other node). This needs more details??? + -- -- Note: there is no direct mechanism for deleting an original node (in -- a manner that can be reversed later). One possible approach is to use -- Rewrite to substitute a null statement for the node to be deleted. diff --git a/gcc/ada/einfo.adb b/gcc/ada/einfo.adb index 0ed05608afb..1da975d0a9e 100644 --- a/gcc/ada/einfo.adb +++ b/gcc/ada/einfo.adb @@ -548,8 +548,9 @@ package body Einfo is -- Has_Static_Predicate_Aspect Flag259 -- Has_Loop_Entry_Attributes Flag260 - -- (unused) Flag261 - -- (unused) Flag262 + -- Has_Delayed_Rep_Aspects Flag261 + -- May_Inherit_Delayed_Rep_Aspects Flag262 + -- (unused) Flag263 -- (unused) Flag264 -- (unused) Flag265 @@ -589,10 +590,6 @@ package body Einfo is -- Determine whether abstract state State has a particular property denoted -- by the name Prop_Nam. - function Rep_Clause (Id : E; Rep_Name : Name_Id) return N; - -- Returns the attribute definition clause for Id whose name is Rep_Name. - -- Returns Empty if no matching attribute definition clause found for Id. - --------------- -- Float_Rep -- --------------- @@ -638,28 +635,6 @@ package body Einfo is return False; end Has_Property; - ---------------- - -- Rep_Clause -- - ---------------- - - function Rep_Clause (Id : E; Rep_Name : Name_Id) return N is - Ritem : Node_Id; - - begin - Ritem := First_Rep_Item (Id); - while Present (Ritem) loop - if Nkind (Ritem) = N_Attribute_Definition_Clause - and then Chars (Ritem) = Rep_Name - then - return Ritem; - else - Next_Rep_Item (Ritem); - end if; - end loop; - - return Empty; - end Rep_Clause; - -------------------------------- -- Attribute Access Functions -- -------------------------------- @@ -1380,6 +1355,12 @@ package body Einfo is return Flag18 (Id); end Has_Delayed_Freeze; + function Has_Delayed_Rep_Aspects (Id : E) return B is + begin + pragma Assert (Nkind (Id) in N_Entity); + return Flag261 (Id); + end Has_Delayed_Rep_Aspects; + function Has_Discriminants (Id : E) return B is begin pragma Assert (Nkind (Id) in N_Entity); @@ -2421,6 +2402,11 @@ package body Einfo is return Flag168 (Id); end Materialize_Entity; + function May_Inherit_Delayed_Rep_Aspects (Id : E) return B is + begin + return Flag262 (Id); + end May_Inherit_Delayed_Rep_Aspects; + function Mechanism (Id : E) return M is begin pragma Assert (Ekind (Id) = E_Function or else Is_Formal (Id)); @@ -3978,6 +3964,12 @@ package body Einfo is Set_Flag18 (Id, V); end Set_Has_Delayed_Freeze; + procedure Set_Has_Delayed_Rep_Aspects (Id : E; V : B := True) is + begin + pragma Assert (Nkind (Id) in N_Entity); + Set_Flag261 (Id, V); + end Set_Has_Delayed_Rep_Aspects; + procedure Set_Has_Discriminants (Id : E; V : B := True) is begin pragma Assert (Nkind (Id) in N_Entity); @@ -5063,6 +5055,11 @@ package body Einfo is Set_Flag168 (Id, V); end Set_Materialize_Entity; + procedure Set_May_Inherit_Delayed_Rep_Aspects (Id : E; V : B := True) is + begin + Set_Flag262 (Id, V); + end Set_May_Inherit_Delayed_Rep_Aspects; + procedure Set_Mechanism (Id : E; V : M) is begin pragma Assert (Ekind (Id) = E_Function or else Is_Formal (Id)); @@ -5969,7 +5966,7 @@ package body Einfo is function Address_Clause (Id : E) return N is begin - return Rep_Clause (Id, Name_Address); + return Get_Attribute_Definition_Clause (Id, Attribute_Address); end Address_Clause; --------------- @@ -5994,7 +5991,7 @@ package body Einfo is function Alignment_Clause (Id : E) return N is begin - return Rep_Clause (Id, Name_Alignment); + return Get_Attribute_Definition_Clause (Id, Attribute_Alignment); end Alignment_Clause; ------------------- @@ -6287,7 +6284,7 @@ package body Einfo is Id = Pragma_Contract_Cases or else Id = Pragma_Test_Case; Is_PPC : constant Boolean := Id = Pragma_Precondition or else Id = Pragma_Postcondition; - Delayed : constant Boolean := Is_CDG or else Is_CTC or else Is_PPC; + Delayed : constant Boolean := Is_CDG or Is_CTC or Is_PPC; Item : Node_Id; Items : Node_Id; @@ -7627,7 +7624,7 @@ package body Einfo is function Size_Clause (Id : E) return N is begin - return Rep_Clause (Id, Name_Size); + return Get_Attribute_Definition_Clause (Id, Attribute_Size); end Size_Clause; ------------------------ @@ -7636,7 +7633,7 @@ package body Einfo is function Stream_Size_Clause (Id : E) return N is begin - return Rep_Clause (Id, Name_Stream_Size); + return Get_Attribute_Definition_Clause (Id, Attribute_Stream_Size); end Stream_Size_Clause; ------------------ @@ -7895,6 +7892,7 @@ package body Einfo is W ("Has_Default_Aspect", Flag39 (Id)); W ("Has_Delayed_Aspects", Flag200 (Id)); W ("Has_Delayed_Freeze", Flag18 (Id)); + W ("Has_Delayed_Rep_Aspects", Flag261 (Id)); W ("Has_Discriminants", Flag5 (Id)); W ("Has_Dispatch_Table", Flag220 (Id)); W ("Has_Dynamic_Predicate_Aspect", Flag258 (Id)); @@ -8070,6 +8068,7 @@ package body Einfo is W ("Low_Bound_Tested", Flag205 (Id)); W ("Machine_Radix_10", Flag84 (Id)); W ("Materialize_Entity", Flag168 (Id)); + W ("May_Inherit_Delayed_Rep_Aspects", Flag262 (Id)); W ("Must_Be_On_Byte_Boundary", Flag183 (Id)); W ("Must_Have_Preelab_Init", Flag208 (Id)); W ("Needs_Debug_Info", Flag147 (Id)); diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads index 24bb12cf797..0449674d861 100644 --- a/gcc/ada/einfo.ads +++ b/gcc/ada/einfo.ads @@ -1,6 +1,7 @@ ------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- +-- -- -- E I N F O -- -- -- -- S p e c -- @@ -1472,6 +1473,15 @@ package Einfo is -- apsect. If this flag is set, then a corresponding aspect specification -- node will be present on the rep item chain for the entity. +-- Has_Delayed_Rep_Aspects (Flag261) +-- Defined in all type and subtypes. This flag is set if there is at +-- least one aspect for a representation characteristic that has to be +-- delayed and is one of the characteristics that may be inherited by +-- types derived from this type if not overridden. If this flag is set, +-- then types derived from this type have May_Inherit_Delayed_Rep_Aspects +-- set, signalling that Freeze.Inhert_Delayed_Rep_Aspects must be called +-- at the freeze point of the derived type. + -- Has_Discriminants (Flag5) -- Defined in all types and subtypes. For types that are allowed to have -- discriminants (record types and subtypes, task types and subtypes, @@ -1795,7 +1805,7 @@ package Einfo is -- Has_Size_Clause (Flag29) -- Defined in entities for types and objects. Set if a size clause is --- Defined for the entity. Used to prevent multiple Size clauses for a +-- defined for the entity. Used to prevent multiple Size clauses for a -- given entity. Note that it is always initially cleared for a derived -- type, even though the Size for such a type is inherited from a Size -- clause given for the parent type. @@ -1879,7 +1889,7 @@ package Einfo is -- Types can have unknown discriminants either from their declaration or -- through type derivation. The use of this flag exactly meets the spec -- in RM 3.7(26). Note that all class-wide types are considered to have --- unknown discriminants. Note that both Has_Discriminants and +-- unknown discriminants. Note that both flags Has_Discriminants and -- Has_Unknown_Discriminants may be true for a type. Class-wide types and -- their subtypes have unknown discriminants and can have declared ones -- as well. Private types declared with unknown discriminants may have a @@ -3072,6 +3082,14 @@ package Einfo is -- containing the renamed address should be allocated. This is needed so -- that the debugger can find the entity. +-- May_Inherit_Delayed_Rep_Aspects (Flag262) +-- Defined in all entities for types and subtypes. Set if the type is +-- derived from a type which has delayed rep aspects (marked by the flag +-- Has_Delayed_Rep_Aspects being set). In this case, at the freeze point +-- for the derived type we know that the parent type is frozen, and if +-- a given attribute has not been set for the derived type, we copy the +-- value from the parent type. See Freeze.Inherit_Delayed_Rep_Aspects. + -- Mechanism (Uint8) (returned as Mechanism_Type) -- Defined in functions and non-generic formal parameters. Indicates -- the mechanism to be used for the function return or for the formal @@ -5008,6 +5026,7 @@ package Einfo is -- Has_Constrained_Partial_View (Flag187) -- Has_Controlled_Component (Flag43) (base type only) -- Has_Default_Aspect (Flag39) (base type only) + -- Has_Delayed_Rep_Aspects (Flag261) -- Has_Discriminants (Flag5) -- Has_Dynamic_Predicate_Aspect (Flag258) -- Has_Independent_Components (Flag34) (base type only) @@ -5047,6 +5066,7 @@ package Einfo is -- Is_Volatile (Flag16) -- Itype_Printed (Flag202) (itypes only) -- Known_To_Have_Preelab_Init (Flag207) + -- May_Inherit_Delayed_Rep_Aspects (Flag262) -- Must_Be_On_Byte_Boundary (Flag183) -- Must_Have_Preelab_Init (Flag208) -- Optimize_Alignment_Space (Flag241) @@ -6285,6 +6305,7 @@ package Einfo is function Has_Default_Aspect (Id : E) return B; function Has_Delayed_Aspects (Id : E) return B; function Has_Delayed_Freeze (Id : E) return B; + function Has_Delayed_Rep_Aspects (Id : E) return B; function Has_Discriminants (Id : E) return B; function Has_Dispatch_Table (Id : E) return B; function Has_Dynamic_Predicate_Aspect (Id : E) return B; @@ -6470,6 +6491,7 @@ package Einfo is function Machine_Radix_10 (Id : E) return B; function Master_Id (Id : E) return E; function Materialize_Entity (Id : E) return B; + function May_Inherit_Delayed_Rep_Aspects (Id : E) return B; function Mechanism (Id : E) return M; function Modulus (Id : E) return U; function Must_Be_On_Byte_Boundary (Id : E) return B; @@ -6895,6 +6917,7 @@ package Einfo is procedure Set_Has_Default_Aspect (Id : E; V : B := True); procedure Set_Has_Delayed_Aspects (Id : E; V : B := True); procedure Set_Has_Delayed_Freeze (Id : E; V : B := True); + procedure Set_Has_Delayed_Rep_Aspects (Id : E; V : B := True); procedure Set_Has_Discriminants (Id : E; V : B := True); procedure Set_Has_Dispatch_Table (Id : E; V : B := True); procedure Set_Has_Dynamic_Predicate_Aspect (Id : E; V : B := True); @@ -7085,6 +7108,7 @@ package Einfo is procedure Set_Machine_Radix_10 (Id : E; V : B := True); procedure Set_Master_Id (Id : E; V : E); procedure Set_Materialize_Entity (Id : E; V : B := True); + procedure Set_May_Inherit_Delayed_Rep_Aspects (Id : E; V : B := True); procedure Set_Mechanism (Id : E; V : M); procedure Set_Modulus (Id : E; V : U); procedure Set_Must_Be_On_Byte_Boundary (Id : E; V : B := True); @@ -7602,6 +7626,7 @@ package Einfo is pragma Inline (Has_Default_Aspect); pragma Inline (Has_Delayed_Aspects); pragma Inline (Has_Delayed_Freeze); + pragma Inline (Has_Delayed_Rep_Aspects); pragma Inline (Has_Discriminants); pragma Inline (Has_Dispatch_Table); pragma Inline (Has_Dynamic_Predicate_Aspect); @@ -7831,6 +7856,7 @@ package Einfo is pragma Inline (Machine_Radix_10); pragma Inline (Master_Id); pragma Inline (Materialize_Entity); + pragma Inline (May_Inherit_Delayed_Rep_Aspects); pragma Inline (Mechanism); pragma Inline (Modulus); pragma Inline (Must_Be_On_Byte_Boundary); @@ -8060,6 +8086,7 @@ package Einfo is pragma Inline (Set_Has_Default_Aspect); pragma Inline (Set_Has_Delayed_Aspects); pragma Inline (Set_Has_Delayed_Freeze); + pragma Inline (Set_Has_Delayed_Rep_Aspects); pragma Inline (Set_Has_Discriminants); pragma Inline (Set_Has_Dispatch_Table); pragma Inline (Set_Has_Dynamic_Predicate_Aspect); @@ -8249,6 +8276,7 @@ package Einfo is pragma Inline (Set_Machine_Radix_10); pragma Inline (Set_Master_Id); pragma Inline (Set_Materialize_Entity); + pragma Inline (Set_May_Inherit_Delayed_Rep_Aspects); pragma Inline (Set_Mechanism); pragma Inline (Set_Modulus); pragma Inline (Set_Must_Be_On_Byte_Boundary); diff --git a/gcc/ada/err_vars.ads b/gcc/ada/err_vars.ads index bc43cb15230..6009379c0a2 100644 --- a/gcc/ada/err_vars.ads +++ b/gcc/ada/err_vars.ads @@ -93,6 +93,7 @@ package Err_Vars is -- are active (see errout.ads for details). If this switch is False, then -- these sequences are ignored (i.e. simply equivalent to a single ?). The -- -gnatw.d switch sets this flag True, -gnatw.D sets this flag False. + -- Note: always ignored on VMS, where we do not provide this capability. ---------------------------------------- -- Error Message Insertion Parameters -- diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb index 5e3e72381fd..12cf828a2f2 100644 --- a/gcc/ada/errout.adb +++ b/gcc/ada/errout.adb @@ -49,6 +49,7 @@ with Sinfo; use Sinfo; with Snames; use Snames; with Stand; use Stand; with Stylesw; use Stylesw; +with Targparm; use Targparm; with Uname; use Uname; package body Errout is @@ -476,6 +477,24 @@ package body Errout is end; end Error_Msg; + -------------------------------- + -- Error_Msg_Ada_2012_Feature -- + -------------------------------- + + procedure Error_Msg_Ada_2012_Feature (Feature : String; Loc : Source_Ptr) is + begin + if Ada_Version < Ada_2012 then + Error_Msg (Feature & " is an Ada 2012 feature", Loc); + + if No (Ada_Version_Pragma) then + Error_Msg ("\unit must be compiled with -gnat2012 switch", Loc); + else + Error_Msg_Sloc := Sloc (Ada_Version_Pragma); + Error_Msg ("\incompatible with Ada version set#", Loc); + end if; + end if; + end Error_Msg_Ada_2012_Feature; + ------------------ -- Error_Msg_AP -- ------------------ @@ -1302,7 +1321,7 @@ package body Errout is CE : Error_Msg_Object renames Errors.Table (Cur); begin - if not CE.Deleted + if (CE.Warn and not CE.Deleted) and then (Warning_Specifically_Suppressed (CE.Sptr, CE.Text) or else @@ -2686,7 +2705,7 @@ package body Errout is Warning_Msg_Char := ' '; if P <= Text'Last and then Text (P) = '?' then - if Warning_Doc_Switch then + if Warning_Doc_Switch and not OpenVMS_On_Target then Warning_Msg_Char := '?'; end if; @@ -2698,7 +2717,7 @@ package body Errout is Text (P) in 'A' .. 'Z') and then Text (P + 1) = '?' then - if Warning_Doc_Switch then + if Warning_Doc_Switch and not OpenVMS_On_Target then Warning_Msg_Char := Text (P); end if; @@ -2784,7 +2803,10 @@ package body Errout is -- If tagging of messages is enabled, and this is a warning, -- then it is treated as being [enabled by default]. - if Error_Msg_Warn and Warning_Doc_Switch then + if Error_Msg_Warn + and Warning_Doc_Switch + and not OpenVMS_On_Target + then Warning_Msg_Char := '?'; end if; diff --git a/gcc/ada/errout.ads b/gcc/ada/errout.ads index 9afc4dfd34a..0c363222c37 100644 --- a/gcc/ada/errout.ads +++ b/gcc/ada/errout.ads @@ -64,6 +64,7 @@ package Errout is -- are active (see errout.ads for details). If this switch is False, then -- these sequences are ignored (i.e. simply equivalent to a single ?). The -- -gnatw.d switch sets this flag True, -gnatw.D sets this flag False. + -- Note: always ignored in VMS mode where we do not provide this feature. ----------------------------------- -- Suppression of Error Messages -- @@ -343,7 +344,8 @@ package Errout is -- generation of code in the presence of the -gnatQ switch. If the -- insertion character | appears, the message is considered to be -- non-serious, and does not cause Serious_Errors_Detected to be - -- incremented (so expansion is not prevented by such a msg). + -- incremented (so expansion is not prevented by such a msg). This + -- insertion character is ignored in continuation messages. -- Insertion character ~ (Tilde: insert string) -- Indicates that Error_Msg_String (1 .. Error_Msg_Strlen) is to be @@ -694,7 +696,9 @@ package Errout is procedure Error_Msg_F (Msg : String; N : Node_Id); -- Similar to Error_Msg_N except that the message is placed on the first - -- node of the construct N (First_Node (N)). + -- node of the construct N (First_Node (N)). Note that this procedure uses + -- Original_Node to look at the original source tree, since that's what we + -- want for placing an error message flag in the right place. procedure Error_Msg_NE (Msg : String; @@ -738,8 +742,11 @@ package Errout is -- usual manner, and need not be the same length as the original text. function First_Node (C : Node_Id) return Node_Id; - -- Given a construct C, finds the first node in the construct, i.e. the - -- one with the lowest Sloc value. This is useful in placing error msgs. + -- Given a construct C, finds the first node in the construct, i.e. the one + -- with the lowest Sloc value. This is useful in placing error msgs. Note + -- that this procedure uses Original_Node to look at the original source + -- tree, since that's what we want for placing an error message flag in + -- the right place. function First_Sloc (N : Node_Id) return Source_Ptr; -- Given the node for an expression, return a source pointer value that @@ -820,6 +827,14 @@ package Errout is -- Posts an error on the protected type declaration Typ indicating wrong -- mode of the first formal of protected type primitive Subp. + procedure Error_Msg_Ada_2012_Feature (Feature : String; Loc : Source_Ptr); + -- If not operating in Ada 2012 mode, posts errors complaining that Feature + -- is only supported in Ada 2012, with appropriate suggestions to fix this. + -- Loc is the location at which the flag is to be posted. Feature, which + -- appears at the start of the first generated message, may contain error + -- message insertion characters in the normal manner, and in particular + -- may start with | to flag a non-serious error. + procedure dmsg (Id : Error_Msg_Id) renames Erroutc.dmsg; -- Debugging routine to dump an error message diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index 6fec955113c..0802f2dfa51 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -725,20 +725,23 @@ package body Exp_Ch4 is (Ref : Node_Id; Built_In_Place : Boolean := False) is - Cond : Node_Id; - Obj_Ref : Node_Id; - Stmts : List_Id; + Pool_Id : constant Entity_Id := Associated_Storage_Pool (PtrT); + Cond : Node_Id; + Fin_Call : Node_Id; + Free_Stmt : Node_Id; + Obj_Ref : Node_Id; + Stmts : List_Id; begin if Ada_Version >= Ada_2005 and then Is_Class_Wide_Type (DesigT) + and then (Tagged_Type_Expansion or else VM_Target /= No_VM) and then not Scope_Suppress.Suppress (Accessibility_Check) and then (Type_Access_Level (Etype (Exp)) > Type_Access_Level (PtrT) or else (Is_Class_Wide_Type (Etype (Exp)) and then Scope (PtrT) /= Current_Scope)) - and then (Tagged_Type_Expansion or else VM_Target /= No_VM) then -- If the allocator was built in place, Ref is already a reference -- to the access object initialized to the result of the allocator @@ -750,7 +753,7 @@ package body Exp_Ch4 is if Built_In_Place then Remove_Side_Effects (Ref); - Obj_Ref := New_Copy (Ref); + Obj_Ref := New_Copy_Tree (Ref); else Obj_Ref := New_Reference_To (Ref, Loc); end if; @@ -759,27 +762,68 @@ package body Exp_Ch4 is Stmts := New_List; - -- Why don't we free the object ??? discussion and explanation - -- needed of why old approach did not work ??? + -- Deallocate the object if the accessibility check fails. This + -- is done only on targets or profiles that support deallocation. + + -- Free (Obj_Ref); + + if RTE_Available (RE_Free) then + Free_Stmt := Make_Free_Statement (Loc, New_Copy_Tree (Obj_Ref)); + Set_Storage_Pool (Free_Stmt, Pool_Id); + + Append_To (Stmts, Free_Stmt); + + -- The target or profile cannot deallocate objects + + else + Free_Stmt := Empty; + end if; + + -- Finalize the object if applicable. Generate: - -- Generate: -- [Deep_]Finalize (Obj_Ref.all); if Needs_Finalization (DesigT) then - Append_To (Stmts, + Fin_Call := Make_Final_Call ( Obj_Ref => Make_Explicit_Dereference (Loc, New_Copy (Obj_Ref)), - Typ => DesigT)); + Typ => DesigT); + + -- When the target or profile supports deallocation, wrap the + -- finalization call in a block to ensure proper deallocation + -- even if finalization fails. Generate: + + -- begin + -- <Fin_Call> + -- exception + -- when others => + -- <Free_Stmt> + -- raise; + -- end; + + if Present (Free_Stmt) then + Fin_Call := + Make_Block_Statement (Loc, + Handled_Statement_Sequence => + Make_Handled_Sequence_Of_Statements (Loc, + Statements => New_List (Fin_Call), + + Exception_Handlers => New_List ( + Make_Exception_Handler (Loc, + Exception_Choices => New_List ( + Make_Others_Choice (Loc)), + + Statements => New_List ( + New_Copy_Tree (Free_Stmt), + Make_Raise_Statement (Loc)))))); + end if; + + Prepend_To (Stmts, Fin_Call); end if; -- Signal the accessibility failure through a Program_Error - -- Since we may have a storage leak, I would be inclined to - -- define a new PE_ code that warns of this possibility where - -- the message would be Accessibility_Check_Failed (causing - -- storage leak) ??? - Append_To (Stmts, Make_Raise_Program_Error (Loc, Condition => New_Reference_To (Standard_True, Loc), @@ -8074,11 +8118,30 @@ package body Exp_Ch4 is return; else - Rewrite (N, - Make_Op_Shift_Left (Loc, - Left_Opnd => Lop, - Right_Opnd => - Convert_To (Standard_Natural, Right_Opnd (Rop)))); + -- If the result is modular, perform the reduction of the result + -- appropriately. + + if Is_Modular_Integer_Type (Typ) + and then not Non_Binary_Modulus (Typ) + then + Rewrite (N, + Make_Op_And (Loc, + Left_Opnd => + Make_Op_Shift_Left (Loc, + Left_Opnd => Lop, + Right_Opnd => + Convert_To (Standard_Natural, Right_Opnd (Rop))), + Right_Opnd => + Make_Integer_Literal (Loc, Modulus (Typ) - 1))); + + else + Rewrite (N, + Make_Op_Shift_Left (Loc, + Left_Opnd => Lop, + Right_Opnd => + Convert_To (Standard_Natural, Right_Opnd (Rop)))); + end if; + Analyze_And_Resolve (N, Typ); return; end if; @@ -8086,11 +8149,27 @@ package body Exp_Ch4 is -- Same processing for the operands the other way round elsif Lp2 then - Rewrite (N, - Make_Op_Shift_Left (Loc, - Left_Opnd => Rop, - Right_Opnd => - Convert_To (Standard_Natural, Right_Opnd (Lop)))); + if Is_Modular_Integer_Type (Typ) + and then not Non_Binary_Modulus (Typ) + then + Rewrite (N, + Make_Op_And (Loc, + Left_Opnd => + Make_Op_Shift_Left (Loc, + Left_Opnd => Rop, + Right_Opnd => + Convert_To (Standard_Natural, Right_Opnd (Lop))), + Right_Opnd => + Make_Integer_Literal (Loc, Modulus (Typ) - 1))); + + else + Rewrite (N, + Make_Op_Shift_Left (Loc, + Left_Opnd => Rop, + Right_Opnd => + Convert_To (Standard_Natural, Right_Opnd (Lop)))); + end if; + Analyze_And_Resolve (N, Typ); return; end if; diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb index fdafd22a6d2..16e83091529 100644 --- a/gcc/ada/exp_ch9.adb +++ b/gcc/ada/exp_ch9.adb @@ -136,6 +136,15 @@ package body Exp_Ch9 is -- build record declaration. N is the type declaration, Ctyp is the -- concurrent entity (task type or protected type). + function Build_Dispatching_Tag_Check + (K : Entity_Id; + N : Node_Id) return Node_Id; + -- Utility to create the tree to check whether the dispatching call in + -- a timed entry call, a conditional entry call, or an asynchronous + -- transfer of control is a call to a primitive of a non-synchronized type. + -- K is the temporary that holds the tagged kind of the target object, and + -- N is the enclosing construct. + function Build_Entry_Count_Expression (Concurrent_Type : Node_Id; Component_List : List_Id; @@ -1298,6 +1307,26 @@ package body Exp_Ch9 is Limited_Present => True)); end Build_Corresponding_Record; + --------------------------------- + -- Build_Dispatching_Tag_Check -- + --------------------------------- + + function Build_Dispatching_Tag_Check + (K : Entity_Id; + N : Node_Id) return Node_Id + is + Loc : constant Source_Ptr := Sloc (N); + begin + return + Make_Op_Or (Loc, + Make_Op_Eq (Loc, + Left_Opnd => New_Reference_To (K, Loc), + Right_Opnd => New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc)), + Make_Op_Eq (Loc, + Left_Opnd => New_Reference_To (K, Loc), + Right_Opnd => New_Reference_To (RTE (RE_TK_Tagged), Loc))); + end Build_Dispatching_Tag_Check; + ---------------------------------- -- Build_Entry_Count_Expression -- ---------------------------------- @@ -6607,7 +6636,9 @@ package body Exp_Ch9 is -- U : Boolean; -- begin - -- if K = Ada.Tags.TK_Limited_Tagged then + -- if K = Ada.Tags.TK_Limited_Tagged + -- or else K = Ada.Tags.TK_Tagged + -- then -- <dispatching-call>; -- <triggering-statements>; @@ -7206,7 +7237,9 @@ package body Exp_Ch9 is Prepend_To (Lim_Typ_Stmts, New_Copy_Tree (Ecall)); -- Generate: - -- if K = Ada.Tags.TK_Limited_Tagged then + -- if K = Ada.Tags.TK_Limited_Tagged + -- or else K = Ada.Tags.TK_Tagged + -- then -- Lim_Typ_Stmts -- else -- Conc_Typ_Stmts @@ -7214,18 +7247,9 @@ package body Exp_Ch9 is Append_To (Stmts, Make_Implicit_If_Statement (N, - Condition => - Make_Op_Eq (Loc, - Left_Opnd => - New_Reference_To (K, Loc), - Right_Opnd => - New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc)), - - Then_Statements => - Lim_Typ_Stmts, - - Else_Statements => - Conc_Typ_Stmts)); + Condition => Build_Dispatching_Tag_Check (K, N), + Then_Statements => Lim_Typ_Stmts, + Else_Statements => Conc_Typ_Stmts)); Rewrite (N, Make_Block_Statement (Loc, @@ -7665,7 +7689,9 @@ package body Exp_Ch9 is -- S : Integer; -- begin - -- if K = Ada.Tags.TK_Limited_Tagged then + -- if K = Ada.Tags.TK_Limited_Tagged + -- or else K = Ada.Tags.TK_Tagged + -- then -- <dispatching-call>; -- <triggering-statements> @@ -7891,7 +7917,9 @@ package body Exp_Ch9 is Prepend_To (Lim_Typ_Stmts, New_Copy_Tree (Blk)); -- Generate: - -- if K = Ada.Tags.TK_Limited_Tagged then + -- if K = Ada.Tags.TK_Limited_Tagged + -- or else K = Ada.Tags.TK_Tagged + -- then -- Lim_Typ_Stmts -- else -- Conc_Typ_Stmts @@ -7899,18 +7927,9 @@ package body Exp_Ch9 is Append_To (Stmts, Make_Implicit_If_Statement (N, - Condition => - Make_Op_Eq (Loc, - Left_Opnd => - New_Reference_To (K, Loc), - Right_Opnd => - New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc)), - - Then_Statements => - Lim_Typ_Stmts, - - Else_Statements => - Conc_Typ_Stmts)); + Condition => Build_Dispatching_Tag_Check (K, N), + Then_Statements => Lim_Typ_Stmts, + Else_Statements => Conc_Typ_Stmts)); Rewrite (N, Make_Block_Statement (Loc, @@ -11951,7 +11970,9 @@ package body Exp_Ch9 is -- S : Integer; -- begin - -- if K = Ada.Tags.TK_Limited_Tagged then + -- if K = Ada.Tags.TK_Limited_Tagged + -- or else K = Ada.Tags.TK_Tagged + -- then -- <dispatching-call>; -- <triggering-statements> @@ -11986,9 +12007,11 @@ package body Exp_Ch9 is -- end; -- The triggering statement and the sequence of timed statements have not - -- been analyzed yet (see Analyzed_Timed_Entry_Call). They may contain - -- local declarations, and therefore the copies that are made during - -- expansion must be disjoint, as for any other inlining. + -- been analyzed yet (see Analyzed_Timed_Entry_Call), but they may contain + -- global references if within an instantiation. To prevent duplication + -- between various uses of those statements, they are encapsulated into a + -- local procedure which is invoked multiple time when the trigger is a + -- dispatching call. procedure Expand_N_Timed_Entry_Call (N : Node_Id) is Loc : constant Source_Ptr := Sloc (N); @@ -12002,13 +12025,13 @@ package body Exp_Ch9 is D_Alt : constant Node_Id := Delay_Alternative (N); D_Conv : Node_Id; D_Disc : Node_Id; - D_Stat : Node_Id := Delay_Statement (D_Alt); + D_Stat : Node_Id := Delay_Statement (D_Alt); D_Stats : List_Id; D_Type : Entity_Id; Decls : List_Id; Dummy : Node_Id; E_Alt : constant Node_Id := Entry_Call_Alternative (N); - E_Call : Node_Id := Entry_Call_Statement (E_Alt); + E_Call : Node_Id := Entry_Call_Statement (E_Alt); E_Stats : List_Id; Ename : Node_Id; Formals : List_Id; @@ -12031,6 +12054,65 @@ package body Exp_Ch9 is P : Entity_Id; -- Parameter block S : Entity_Id; -- Primitive operation slot + procedure Rewrite_Triggering_Statements; + -- If the trigger is a dispatching call, the expansion inserts multiple + -- copies of the abortable part. This is both inefficient, and may lead + -- to duplicate definitions that the back-end will reject, when the + -- abortable part includes loops. This procedure rewrites the abortable + -- part into a call to a generated procedure. + + ----------------------------------- + -- Rewrite_Triggering_Statements -- + ----------------------------------- + + procedure Rewrite_Triggering_Statements is + Proc : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA); + Decl : Node_Id; + Stat : Node_Id; + + begin + Decl := + Make_Subprogram_Body (Loc, + Specification => + Make_Procedure_Specification (Loc, Defining_Unit_Name => Proc), + Declarations => New_List, + Handled_Statement_Sequence => + Make_Handled_Sequence_Of_Statements (Loc, E_Stats)); + + Append_To (Decls, Decl); + + -- Adjust the scope of blocks in the procedure. Needed because blocks + -- generate declarations that are processed before other analysis + -- takes place, and their scope is already set. The backend depends + -- on the scope chain to determine the legality of some anonymous + -- types, and thus we must indicate that the block is within the new + -- procedure. + + Stat := First (E_Stats); + while Present (Stat) loop + if Nkind (Stat) = N_Block_Statement then + Insert_Before (Stat, + Make_Implicit_Label_Declaration (Sloc (Stat), + Defining_Identifier => + Make_Defining_Identifier ( + Sloc (Stat), Chars (Identifier (Stat))))); + end if; + + Next (Stat); + end loop; + + -- Analyze (Decl); + + -- Rewrite abortable part into a call to this procedure. + + E_Stats := + New_List + (Make_Procedure_Call_Statement (Loc, + Name => New_Occurrence_Of (Proc, Loc))); + end Rewrite_Triggering_Statements; + + -- Start of processing for Expand_N_Timed_Entry_Call + begin -- Under the Ravenscar profile, timed entry calls are excluded. An error -- was already reported on spec, so do not attempt to expand the call. @@ -12070,8 +12152,9 @@ package body Exp_Ch9 is if Is_Disp_Select then Extract_Dispatching_Call (E_Call, Call_Ent, Obj, Actuals, Formals); - Decls := New_List; + Rewrite_Triggering_Statements; + Stmts := New_List; -- Generate: @@ -12280,7 +12363,11 @@ package body Exp_Ch9 is -- <timed-statements> -- end if; - N_Stats := Copy_Separate_List (E_Stats); + -- Note: we used to do Copy_Separate_List here, but this was changed + -- to New_Copy_List_Tree with no explanation or RH note??? We should + -- explain the need for the change ??? + + N_Stats := New_Copy_List_Tree (E_Stats); Prepend_To (N_Stats, Make_Implicit_If_Statement (N, @@ -12320,11 +12407,17 @@ package body Exp_Ch9 is -- <dispatching-call>; -- <triggering-statements> - Lim_Typ_Stmts := Copy_Separate_List (E_Stats); + -- Note: the following was Copy_Separate_List but it was changed to + -- New_Copy_List_Tree without comments or RH documentation ??? We + -- should explain the need for the change ??? + + Lim_Typ_Stmts := New_Copy_List_Tree (E_Stats); Prepend_To (Lim_Typ_Stmts, New_Copy_Tree (E_Call)); -- Generate: - -- if K = Ada.Tags.TK_Limited_Tagged then + -- if K = Ada.Tags.TK_Limited_Tagged + -- or else K = Ada.Tags.TK_Tagged + -- then -- Lim_Typ_Stmts -- else -- Conc_Typ_Stmts @@ -12332,11 +12425,7 @@ package body Exp_Ch9 is Append_To (Stmts, Make_Implicit_If_Statement (N, - Condition => - Make_Op_Eq (Loc, - Left_Opnd => New_Reference_To (K, Loc), - Right_Opnd => - New_Reference_To (RTE (RE_TK_Limited_Tagged), Loc)), + Condition => Build_Dispatching_Tag_Check (K, N), Then_Statements => Lim_Typ_Stmts, Else_Statements => Conc_Typ_Stmts)); diff --git a/gcc/ada/exp_prag.adb b/gcc/ada/exp_prag.adb index fba371e2b95..eeafa72d356 100644 --- a/gcc/ada/exp_prag.adb +++ b/gcc/ada/exp_prag.adb @@ -287,10 +287,13 @@ package body Exp_Prag is Msg : Node_Id; begin - -- We already know that this check is enabled, because otherwise the - -- semantic pass dealt with rewriting the assertion (see Sem_Prag) + -- Nothing to do if pragma is ignored - -- Since this check is enabled, we rewrite the pragma into a + if Is_Ignored (N) then + return; + end if; + + -- Since this check is active, we rewrite the pragma into a -- corresponding if statement, and then analyze the statement -- The normal case expansion transforms: diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb index 8a5b927c570..58098be741d 100644 --- a/gcc/ada/freeze.adb +++ b/gcc/ada/freeze.adb @@ -2463,12 +2463,14 @@ package body Freeze is or else (Chars (Comp) /= Name_uParent and then Is_Controlled (Etype (Comp))) or else (Is_Protected_Type (Etype (Comp)) - and then Present - (Corresponding_Record_Type - (Etype (Comp))) - and then Has_Controlled_Component - (Corresponding_Record_Type - (Etype (Comp))))) + and then + Present + (Corresponding_Record_Type + (Etype (Comp))) + and then + Has_Controlled_Component + (Corresponding_Record_Type + (Etype (Comp))))) then Set_Has_Controlled_Component (Rec); end if; @@ -2731,9 +2733,7 @@ package body Freeze is -- Add checks to detect proper initialization of scalars that may appear -- as subprogram parameters. - if Is_Subprogram (E) - and then Check_Validity_Of_Parameters - then + if Is_Subprogram (E) and then Check_Validity_Of_Parameters then Apply_Parameter_Validity_Checks (E); end if; @@ -3263,9 +3263,7 @@ package body Freeze is -- then the only purpose of the Import pragma is to suppress -- implicit initialization. - if Is_Imported (E) - and then No (Address_Clause (E)) - then + if Is_Imported (E) and then No (Address_Clause (E)) then Set_Is_Public (E); end if; @@ -3275,7 +3273,7 @@ package body Freeze is -- expects 8-bit sizes for these cases. if (Convention (E) = Convention_C - or else + or else Convention (E) = Convention_CPP) and then Is_Enumeration_Type (Etype (E)) and then not Is_Character_Type (Etype (E)) @@ -3349,7 +3347,7 @@ package body Freeze is -- enclosing statement sequence. if Ekind_In (E, E_Constant, E_Variable) - and then not Has_Delayed_Freeze (E) + and then not Has_Delayed_Freeze (E) then declare Init_Stmts : constant Node_Id := diff --git a/gcc/ada/g-table.adb b/gcc/ada/g-table.adb index eeaa59bb6f7..9b3692bbe06 100644 --- a/gcc/ada/g-table.adb +++ b/gcc/ada/g-table.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1998-2010, AdaCore -- +-- Copyright (C) 1998-2013, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -29,6 +29,8 @@ -- -- ------------------------------------------------------------------------------ +with GNAT.Heap_Sort_G; + with System; use System; with System.Memory; use System.Memory; @@ -114,6 +116,19 @@ package body GNAT.Table is Last_Val := Last_Val - 1; end Decrement_Last; + -------------- + -- For_Each -- + -------------- + + procedure For_Each is + Quit : Boolean := False; + begin + for Index in Table_Low_Bound .. Table_Index_Type (Last_Val) loop + Action (Index, Table (Index), Quit); + exit when Quit; + end loop; + end For_Each; + ---------- -- Free -- ---------- @@ -259,17 +274,17 @@ package body GNAT.Table is pragma Import (Ada, Allocated_Table); pragma Suppress (Range_Check, On => Allocated_Table); for Allocated_Table'Address use Allocated_Table_Address; - -- Allocated_Table represents the currently allocated array, plus - -- one element (the supplementary element is used to have a - -- convenient way of computing the address just past the end of the - -- current allocation). Range checks are suppressed because this unit - -- uses direct calls to System.Memory for allocation, and this can - -- yield misaligned storage (and we cannot rely on the bootstrap - -- compiler supporting specifically disabling alignment checks, so we - -- need to suppress all range checks). It is safe to suppress this check - -- here because we know that a (possibly misaligned) object of that type - -- does actually exist at that address. - -- ??? We should really improve the allocation circuitry here to + -- Allocated_Table represents the currently allocated array, plus one + -- element (the supplementary element is used to have a convenient + -- way of computing the address just past the end of the current + -- allocation). Range checks are suppressed because this unit uses + -- direct calls to System.Memory for allocation, and this can yield + -- misaligned storage (and we cannot rely on the bootstrap compiler + -- supporting specifically disabling alignment checks, so we need to + -- suppress all range checks). It is safe to suppress this check here + -- because we know that a (possibly misaligned) object of that type + -- does actually exist at that address. ??? We should really improve + -- the allocation circuitry here to -- guarantee proper alignment. Need_Realloc : constant Boolean := Integer (Index) > Max; @@ -324,6 +339,74 @@ package body GNAT.Table is end if; end Set_Last; + ---------------- + -- Sort_Table -- + ---------------- + + procedure Sort_Table is + + Temp : Table_Component_Type; + -- A temporary position to simulate index 0 + + -- Local subprograms + + function Index_Of (Idx : Natural) return Table_Index_Type; + -- Return index of Idx'th element of table + + function Lower_Than (Op1, Op2 : Natural) return Boolean; + -- Compare two components + + procedure Move (From : Natural; To : Natural); + -- Move one component + + package Heap_Sort is new GNAT.Heap_Sort_G (Move, Lower_Than); + + -------------- + -- Index_Of -- + -------------- + + function Index_Of (Idx : Natural) return Table_Index_Type is + J : constant Integer'Base := Table_Index_Type'Pos (First) + Idx - 1; + begin + return Table_Index_Type'Val (J); + end Index_Of; + + ---------- + -- Move -- + ---------- + + procedure Move (From : Natural; To : Natural) is + begin + if From = 0 then + Table (Index_Of (To)) := Temp; + elsif To = 0 then + Temp := Table (Index_Of (From)); + else + Table (Index_Of (To)) := Table (Index_Of (From)); + end if; + end Move; + + ---------------- + -- Lower_Than -- + ---------------- + + function Lower_Than (Op1, Op2 : Natural) return Boolean is + begin + if Op1 = 0 then + return Lt (Temp, Table (Index_Of (Op2))); + elsif Op2 = 0 then + return Lt (Table (Index_Of (Op1)), Temp); + else + return Lt (Table (Index_Of (Op1)), Table (Index_Of (Op2))); + end if; + end Lower_Than; + + -- Start of processing for Sort_Table + + begin + Heap_Sort.Sort (Natural (Last - First) + 1); + end Sort_Table; + begin Init; end GNAT.Table; diff --git a/gcc/ada/g-table.ads b/gcc/ada/g-table.ads index 5a879752e45..c9b75f61648 100644 --- a/gcc/ada/g-table.ads +++ b/gcc/ada/g-table.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1998-2010, AdaCore -- +-- Copyright (C) 1998-2013, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -201,4 +201,25 @@ package GNAT.Table is -- This means that a reference X.Table (X.Allocate) is incorrect, since -- the call to X.Allocate may modify the results of calling X.Table. + generic + with procedure Action + (Index : Table_Index_Type; + Item : Table_Component_Type; + Quit : in out Boolean) is <>; + procedure For_Each; + -- Calls procedure Action for each component of the table, or until + -- one of these calls set Quit to True. + + generic + with function Lt (Comp1, Comp2 : Table_Component_Type) return Boolean; + procedure Sort_Table; + -- This procedure sorts the components of the table into ascending + -- order making calls to Lt to do required comparisons, and using + -- assignments to move components around. The Lt function returns True + -- if Comp1 is less than Comp2 (in the sense of the desired sort), and + -- False if Comp1 is greater than Comp2. For equal objects it does not + -- matter if True or False is returned (it is slightly more efficient + -- to return False). The sort is not stable (the order of equal items + -- in the table is not preserved). + end GNAT.Table; diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in index 93250da561c..fbbb417f649 100644 --- a/gcc/ada/gcc-interface/Make-lang.in +++ b/gcc/ada/gcc-interface/Make-lang.in @@ -1280,17 +1280,17 @@ ada/checks.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \ ada/sem_warn.ads ada/set_targ.ads ada/sinfo.ads ada/sinfo.adb \ ada/sinput.ads ada/snames.ads ada/sprint.ads ada/stand.ads \ - ada/stringt.ads ada/style.ads ada/styleg.ads ada/styleg.adb \ - ada/stylesw.ads ada/system.ads ada/s-assert.ads ada/s-exctab.ads \ - ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \ - ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \ - ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ - ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \ - ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ - ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ - ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/validsw.ads \ - ada/widechar.ads + ada/stringt.ads ada/stringt.adb ada/style.ads ada/styleg.ads \ + ada/styleg.adb ada/stylesw.ads ada/system.ads ada/s-assert.ads \ + ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ + ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \ + ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ + ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ + ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ + ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ + ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ + ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \ + ada/validsw.ads ada/warnsw.ads ada/widechar.ads ada/comperr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -1471,7 +1471,7 @@ ada/exp_aggr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/validsw.ads ada/widechar.ads + ada/urealp.ads ada/validsw.ads ada/warnsw.ads ada/widechar.ads ada/exp_atag.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -1530,7 +1530,7 @@ ada/exp_attr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ ada/types.ads ada/types.adb ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \ - ada/widechar.ads + ada/warnsw.ads ada/widechar.ads ada/exp_cg.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -1575,7 +1575,7 @@ ada/exp_ch11.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ ada/tbuild.adb ada/tree_io.ads ada/types.ads ada/uintp.ads \ ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/widechar.ads + ada/urealp.ads ada/warnsw.ads ada/widechar.ads ada/exp_ch12.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -1663,7 +1663,8 @@ ada/exp_ch3.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/widechar.ads + ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/warnsw.ads \ + ada/widechar.ads ada/exp_ch4.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -1699,7 +1700,7 @@ ada/exp_ch4.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \ - ada/validsw.ads ada/widechar.ads + ada/validsw.ads ada/warnsw.ads ada/widechar.ads ada/exp_ch5.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -1731,7 +1732,7 @@ ada/exp_ch5.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ ada/types.ads ada/uintp.ads ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/validsw.ads + ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/warnsw.ads ada/exp_ch6.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -1761,17 +1762,17 @@ ada/exp_ch6.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads ada/sem_util.ads \ ada/sem_util.adb ada/sem_warn.ads ada/set_targ.ads ada/sinfo.ads \ ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/sprint.ads \ - ada/stand.ads ada/stringt.ads ada/style.ads ada/styleg.ads \ - ada/styleg.adb ada/stylesw.ads ada/system.ads ada/s-assert.ads \ - ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ - ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \ - ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ - ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ - ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ - ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ - ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ + ada/stand.ads ada/stringt.ads ada/stringt.adb ada/style.ads \ + ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \ + ada/s-assert.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \ + ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ + ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \ + ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \ + ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ + ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ + ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \ - ada/widechar.ads + ada/warnsw.ads ada/widechar.ads ada/exp_ch7.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -1805,7 +1806,8 @@ ada/exp_ch7.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/widechar.ads + ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/warnsw.ads \ + ada/widechar.ads ada/exp_ch8.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -1828,7 +1830,7 @@ ada/exp_ch8.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ ada/targparm.ads ada/tbuild.ads ada/tree_io.ads ada/ttypes.ads \ ada/types.ads ada/uintp.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/validsw.ads + ada/urealp.ads ada/validsw.ads ada/warnsw.ads ada/exp_ch9.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -1862,7 +1864,7 @@ ada/exp_ch9.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \ - ada/widechar.ads + ada/warnsw.ads ada/widechar.ads ada/exp_code.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -1942,7 +1944,7 @@ ada/exp_disp.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ ada/types.ads ada/types.adb ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \ - ada/widechar.ads + ada/warnsw.ads ada/widechar.ads ada/exp_dist.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -1967,7 +1969,7 @@ ada/exp_dist.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tbuild.ads \ ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/widechar.ads + ada/unchdeal.ads ada/urealp.ads ada/warnsw.ads ada/widechar.ads ada/exp_fixd.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -2044,7 +2046,7 @@ ada/exp_intr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/validsw.ads \ - ada/widechar.ads + ada/warnsw.ads ada/widechar.ads ada/exp_pakd.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -2071,7 +2073,7 @@ ada/exp_pakd.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ ada/uintp.adb ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \ - ada/validsw.ads + ada/validsw.ads ada/warnsw.ads ada/exp_prag.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -2131,17 +2133,16 @@ ada/exp_spark.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \ ada/exp_attr.ads ada/exp_ch4.ads ada/exp_ch6.ads ada/exp_dbug.ads \ ada/exp_spark.ads ada/exp_spark.adb ada/exp_tss.ads ada/exp_util.ads \ - ada/hostparm.ads ada/namet.ads ada/nlists.ads ada/nlists.adb \ - ada/opt.ads ada/output.ads ada/rtsfind.ads ada/sem_aux.ads \ - ada/sem_aux.adb ada/sem_res.ads ada/sem_util.ads ada/sinfo.ads \ - ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \ - ada/system.ads ada/s-assert.ads ada/s-exctab.ads ada/s-imenne.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-soflin.ads \ - ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \ - ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \ - ada/table.ads ada/table.adb ada/tbuild.ads ada/tree_io.ads \ - ada/types.ads ada/uintp.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads + ada/hostparm.ads ada/namet.ads ada/nlists.ads ada/opt.ads \ + ada/output.ads ada/rtsfind.ads ada/sem_aux.ads ada/sem_aux.adb \ + ada/sem_res.ads ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb \ + ada/sinput.ads ada/snames.ads ada/stand.ads ada/system.ads \ + ada/s-assert.ads ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads \ + ada/s-os_lib.ads ada/s-parame.ads ada/s-soflin.ads ada/s-stache.ads \ + ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ + ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \ + ada/table.adb ada/tbuild.ads ada/tree_io.ads ada/types.ads \ + ada/uintp.ads ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/exp_strm.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -2212,7 +2213,7 @@ ada/exp_util.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ ada/types.adb ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \ - ada/validsw.ads ada/widechar.ads + ada/validsw.ads ada/warnsw.ads ada/widechar.ads ada/exp_vfpt.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -2251,7 +2252,7 @@ ada/expander.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \ ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uname.ads \ - ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads + ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/warnsw.ads ada/fmap.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/debug.ads ada/fmap.ads ada/fmap.adb \ @@ -2321,7 +2322,7 @@ ada/freeze.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tree_io.ads \ ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \ - ada/widechar.ads + ada/warnsw.ads ada/widechar.ads ada/frontend.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -2349,7 +2350,8 @@ ada/frontend.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \ ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uname.ads \ - ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads + ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/warnsw.ads \ + ada/widechar.ads ada/g-byorma.o : ada/gnat.ads ada/g-byorma.ads ada/g-byorma.adb \ ada/system.ads @@ -2372,9 +2374,10 @@ ada/g-u3spch.o : ada/gnat.ads ada/g-spchge.ads ada/g-spchge.adb \ ada/get_spark_xrefs.o : ada/ada.ads ada/a-ioexce.ads ada/a-unccon.ads \ ada/get_spark_xrefs.ads ada/get_spark_xrefs.adb ada/gnat.ads \ - ada/g-table.ads ada/g-table.adb ada/spark_xrefs.ads ada/system.ads \ - ada/s-assert.ads ada/s-exctab.ads ada/s-memory.ads ada/s-stalib.ads \ - ada/s-unstyp.ads ada/types.ads ada/unchconv.ads ada/unchdeal.ads + ada/g-hesorg.ads ada/g-table.ads ada/g-table.adb ada/spark_xrefs.ads \ + ada/system.ads ada/s-assert.ads ada/s-exctab.ads ada/s-memory.ads \ + ada/s-stalib.ads ada/s-unstyp.ads ada/types.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/get_targ.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/debug.ads ada/einfo.ads \ @@ -2415,7 +2418,7 @@ ada/gnat1drv.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/tree_gen.ads ada/tree_io.ads ada/treepr.ads ada/ttypes.ads \ ada/types.ads ada/uintp.ads ada/uname.ads ada/unchconv.ads \ ada/unchdeal.ads ada/urealp.ads ada/usage.ads ada/validsw.ads \ - ada/widechar.ads + ada/warnsw.ads ada/widechar.ads ada/gnatbind.o : ada/ada.ads ada/a-comlin.ads ada/a-clrefi.ads \ ada/a-except.ads ada/a-unccon.ads ada/a-uncdea.ads ada/ali.ads \ @@ -2476,7 +2479,7 @@ ada/inline.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \ ada/table.ads ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads \ ada/uname.ads ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \ - ada/widechar.ads + ada/warnsw.ads ada/widechar.ads ada/interfac.o : ada/interfac.ads ada/system.ads @@ -2840,19 +2843,20 @@ ada/prepcomp.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/put_scos.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/debug.ads ada/gnat.ads \ - ada/g-table.ads ada/g-table.adb ada/hostparm.ads ada/namet.ads \ - ada/opt.ads ada/output.ads ada/put_scos.ads ada/put_scos.adb \ - ada/scos.ads ada/system.ads ada/s-assert.ads ada/s-exctab.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads \ - ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \ - ada/table.ads ada/table.adb ada/tree_io.ads ada/types.ads \ - ada/unchconv.ads ada/unchdeal.ads + ada/g-hesorg.ads ada/g-table.ads ada/g-table.adb ada/hostparm.ads \ + ada/namet.ads ada/opt.ads ada/output.ads ada/put_scos.ads \ + ada/put_scos.adb ada/scos.ads ada/system.ads ada/s-assert.ads \ + ada/s-exctab.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ + ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \ + ada/types.ads ada/unchconv.ads ada/unchdeal.ads ada/put_spark_xrefs.o : ada/ada.ads ada/a-unccon.ads ada/gnat.ads \ - ada/g-table.ads ada/g-table.adb ada/put_spark_xrefs.ads \ - ada/put_spark_xrefs.adb ada/spark_xrefs.ads ada/system.ads \ - ada/s-assert.ads ada/s-exctab.ads ada/s-memory.ads ada/s-stalib.ads \ - ada/s-unstyp.ads ada/types.ads ada/unchconv.ads ada/unchdeal.ads + ada/g-hesorg.ads ada/g-table.ads ada/g-table.adb \ + ada/put_spark_xrefs.ads ada/put_spark_xrefs.adb ada/spark_xrefs.ads \ + ada/system.ads ada/s-assert.ads ada/s-exctab.ads ada/s-memory.ads \ + ada/s-stalib.ads ada/s-unstyp.ads ada/types.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/repinfo.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -3128,12 +3132,13 @@ ada/scng.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/scos.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/debug.ads ada/gnat.ads \ - ada/g-table.ads ada/g-table.adb ada/hostparm.ads ada/namet.ads \ - ada/opt.ads ada/output.ads ada/scos.ads ada/scos.adb ada/system.ads \ - ada/s-assert.ads ada/s-exctab.ads ada/s-memory.ads ada/s-os_lib.ads \ - ada/s-parame.ads ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads \ - ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ - ada/tree_io.ads ada/types.ads ada/unchconv.ads ada/unchdeal.ads + ada/g-hesorg.ads ada/g-hesorg.adb ada/g-table.ads ada/g-table.adb \ + ada/hostparm.ads ada/namet.ads ada/opt.ads ada/output.ads ada/scos.ads \ + ada/scos.adb ada/system.ads ada/s-assert.ads ada/s-exctab.ads \ + ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads \ + ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \ + ada/table.ads ada/table.adb ada/tree_io.ads ada/types.ads \ + ada/unchconv.ads ada/unchdeal.ads ada/sem.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads ada/a-uncdea.ads \ ada/alloc.ads ada/aspects.ads ada/atree.ads ada/atree.adb \ @@ -3156,7 +3161,7 @@ ada/sem.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads ada/a-uncdea.ads \ ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \ ada/types.ads ada/uintp.ads ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/widechar.ads + ada/unchdeal.ads ada/urealp.ads ada/warnsw.ads ada/widechar.ads ada/sem_aggr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -3189,7 +3194,8 @@ ada/sem_aggr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/widechar.ads + ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/warnsw.ads \ + ada/widechar.ads ada/sem_attr.o : ada/ada.ads ada/a-charac.ads ada/a-chlat1.ads \ ada/a-except.ads ada/a-unccon.ads ada/a-uncdea.ads ada/alloc.ads \ @@ -3202,13 +3208,14 @@ ada/sem_attr.o : ada/ada.ads ada/a-charac.ads ada/a-chlat1.ads \ ada/exp_dist.ads ada/exp_pakd.ads ada/exp_tss.ads ada/exp_util.ads \ ada/exp_util.adb ada/expander.ads ada/fname.ads ada/fname-uf.ads \ ada/freeze.ads ada/get_targ.ads ada/gnat.ads ada/g-byorma.ads \ - ada/g-htable.ads ada/gnatvsn.ads ada/hostparm.ads ada/inline.ads \ - ada/interfac.ads ada/itypes.ads ada/lib.ads ada/lib-load.ads \ - ada/lib-util.ads ada/lib-xref.ads ada/namet.ads ada/namet.adb \ - ada/namet-sp.ads ada/nlists.ads ada/nlists.adb ada/nmake.ads \ - ada/nmake.adb ada/opt.ads ada/output.ads ada/put_spark_xrefs.ads \ - ada/restrict.ads ada/restrict.adb ada/rident.ads ada/rtsfind.ads \ - ada/scans.ads ada/sdefault.ads ada/sem.ads ada/sem.adb ada/sem_aggr.ads \ + ada/g-hesorg.ads ada/g-htable.ads ada/gnatvsn.ads ada/hostparm.ads \ + ada/inline.ads ada/interfac.ads ada/itypes.ads ada/lib.ads ada/lib.adb \ + ada/lib-list.adb ada/lib-load.ads ada/lib-sort.adb ada/lib-util.ads \ + ada/lib-xref.ads ada/namet.ads ada/namet.adb ada/namet-sp.ads \ + ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads \ + ada/output.ads ada/put_spark_xrefs.ads ada/restrict.ads \ + ada/restrict.adb ada/rident.ads ada/rtsfind.ads ada/scans.ads \ + ada/sdefault.ads ada/sem.ads ada/sem.adb ada/sem_aggr.ads \ ada/sem_attr.ads ada/sem_attr.adb ada/sem_aux.ads ada/sem_aux.adb \ ada/sem_cat.ads ada/sem_ch10.ads ada/sem_ch11.ads ada/sem_ch12.ads \ ada/sem_ch13.ads ada/sem_ch2.ads ada/sem_ch3.ads ada/sem_ch4.ads \ @@ -3230,7 +3237,7 @@ ada/sem_attr.o : ada/ada.ads ada/a-charac.ads ada/a-chlat1.ads \ ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ ada/types.ads ada/types.adb ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \ - ada/validsw.ads ada/widechar.ads + ada/validsw.ads ada/warnsw.ads ada/widechar.ads ada/sem_aux.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -3322,7 +3329,7 @@ ada/sem_ch10.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \ ada/targparm.ads ada/tbuild.ads ada/tree_io.ads ada/ttypes.ads \ ada/types.ads ada/uintp.ads ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/widechar.ads + ada/unchdeal.ads ada/urealp.ads ada/warnsw.ads ada/widechar.ads ada/sem_ch11.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -3353,12 +3360,11 @@ ada/sem_ch12.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/erroutc.ads ada/exp_ch11.ads ada/exp_ch7.ads ada/exp_disp.ads \ ada/exp_dist.ads ada/exp_tss.ads ada/exp_util.ads ada/expander.ads \ ada/fname.ads ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads \ - ada/gnat.ads ada/g-hesorg.ads ada/g-htable.ads ada/gnatvsn.ads \ - ada/hostparm.ads ada/inline.ads ada/inline.adb ada/itypes.ads \ - ada/lib.ads ada/lib.adb ada/lib-list.adb ada/lib-load.ads \ - ada/lib-sort.adb ada/lib-util.ads ada/lib-xref.ads ada/namet.ads \ - ada/namet-sp.ads ada/nlists.ads ada/nlists.adb ada/nmake.ads \ - ada/nmake.adb ada/opt.ads ada/opt.adb ada/output.ads \ + ada/gnat.ads ada/g-hesorg.ads ada/g-htable.ads ada/hostparm.ads \ + ada/inline.ads ada/inline.adb ada/itypes.ads ada/lib.ads ada/lib.adb \ + ada/lib-list.adb ada/lib-load.ads ada/lib-sort.adb ada/lib-util.ads \ + ada/lib-xref.ads ada/namet.ads ada/namet-sp.ads ada/nlists.ads \ + ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads \ ada/put_spark_xrefs.ads ada/restrict.ads ada/rident.ads ada/rtsfind.ads \ ada/rtsfind.adb ada/scans.ads ada/sem.ads ada/sem.adb ada/sem_attr.ads \ ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch10.ads ada/sem_ch11.ads \ @@ -3380,7 +3386,7 @@ ada/sem_ch12.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \ - ada/widechar.ads + ada/warnsw.ads ada/widechar.ads ada/sem_ch13.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/aspects.adb \ @@ -3469,7 +3475,7 @@ ada/sem_ch3.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \ - ada/validsw.ads ada/widechar.ads + ada/validsw.ads ada/warnsw.ads ada/widechar.ads ada/sem_ch4.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -3541,7 +3547,7 @@ ada/sem_ch5.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ ada/tbuild.ads ada/tree_io.ads ada/ttypes.ads ada/types.ads \ ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/validsw.ads + ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/warnsw.ads ada/sem_ch6.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -3579,7 +3585,7 @@ ada/sem_ch6.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \ ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \ - ada/widechar.ads + ada/warnsw.ads ada/widechar.ads ada/sem_ch7.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -3609,7 +3615,8 @@ ada/sem_ch7.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \ ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tree_io.ads \ ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \ - ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads + ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/warnsw.ads \ + ada/widechar.ads ada/sem_ch8.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -3646,7 +3653,7 @@ ada/sem_ch8.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \ - ada/urealp.ads ada/widechar.ads + ada/urealp.ads ada/warnsw.ads ada/widechar.ads ada/sem_ch9.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/aspects.adb \ @@ -3683,7 +3690,7 @@ ada/sem_ch9.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ ada/tbuild.ads ada/tree_io.ads ada/ttypes.ads ada/types.ads \ ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/validsw.ads + ada/unchdeal.ads ada/urealp.ads ada/validsw.ads ada/warnsw.ads ada/sem_dim.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -3770,28 +3777,28 @@ ada/sem_elab.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/exp_ch11.ads \ ada/exp_disp.ads ada/exp_tss.ads ada/exp_util.ads ada/expander.ads \ ada/fname.ads ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads \ - ada/gnat.ads ada/g-hesorg.ads ada/g-htable.ads ada/hostparm.ads \ - ada/interfac.ads ada/lib.ads ada/lib.adb ada/lib-list.adb \ - ada/lib-load.ads ada/lib-sort.adb ada/lib-util.ads ada/lib-xref.ads \ - ada/namet.ads ada/namet.adb ada/namet-sp.ads ada/nlists.ads \ - ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads \ - ada/put_spark_xrefs.ads ada/restrict.ads ada/restrict.adb \ - ada/rident.ads ada/rtsfind.ads ada/scans.ads ada/sem.ads \ - ada/sem_attr.ads ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch7.ads \ - ada/sem_ch8.ads ada/sem_disp.ads ada/sem_elab.ads ada/sem_elab.adb \ - ada/sem_eval.ads ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \ - ada/sem_util.adb ada/set_targ.ads ada/sinfo.ads ada/sinfo.adb \ - ada/sinput.ads ada/snames.ads ada/stand.ads ada/stringt.ads \ - ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \ - ada/system.ads ada/s-assert.ads ada/s-exctab.ads ada/s-htable.ads \ - ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ - ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \ - ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ - ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \ - ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \ - ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \ - ada/uname.ads ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \ - ada/widechar.ads + ada/gnat.ads ada/g-byorma.ads ada/g-hesorg.ads ada/g-htable.ads \ + ada/hostparm.ads ada/interfac.ads ada/lib.ads ada/lib.adb \ + ada/lib-list.adb ada/lib-load.ads ada/lib-sort.adb ada/lib-util.ads \ + ada/lib-xref.ads ada/namet.ads ada/namet.adb ada/namet-sp.ads \ + ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads \ + ada/output.ads ada/put_spark_xrefs.ads ada/restrict.ads \ + ada/restrict.adb ada/rident.ads ada/rtsfind.ads ada/scans.ads \ + ada/sem.ads ada/sem_attr.ads ada/sem_aux.ads ada/sem_cat.ads \ + ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_disp.ads ada/sem_elab.ads \ + ada/sem_elab.adb ada/sem_eval.ads ada/sem_res.ads ada/sem_type.ads \ + ada/sem_util.ads ada/sem_util.adb ada/set_targ.ads ada/sinfo.ads \ + ada/sinfo.adb ada/sinput.ads ada/sinput.adb ada/snames.ads \ + ada/stand.ads ada/stringt.ads ada/style.ads ada/styleg.ads \ + ada/styleg.adb ada/stylesw.ads ada/system.ads ada/s-assert.ads \ + ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \ + ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \ + ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ + ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ + ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ + ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \ + ada/types.ads ada/uintp.ads ada/uname.ads ada/unchconv.ads \ + ada/unchdeal.ads ada/urealp.ads ada/widechar.ads ada/sem_elim.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -3965,7 +3972,7 @@ ada/sem_res.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/types.adb \ ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/validsw.ads \ - ada/widechar.ads + ada/warnsw.ads ada/widechar.ads ada/sem_scil.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -4020,7 +4027,7 @@ ada/sem_type.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tree_io.ads \ ada/treepr.ads ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb \ ada/uname.ads ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \ - ada/widechar.ads + ada/warnsw.ads ada/widechar.ads ada/sem_util.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -4055,7 +4062,8 @@ ada/sem_util.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \ ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \ ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/widechar.ads + ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/warnsw.ads \ + ada/widechar.ads ada/sem_vfpt.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/cstand.ads \ @@ -4204,14 +4212,14 @@ ada/snames.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/unchconv.ads ada/unchdeal.ads ada/widechar.ads ada/spark_xrefs.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ - ada/a-uncdea.ads ada/gnat.ads ada/g-table.ads ada/g-table.adb \ - ada/hostparm.ads ada/output.ads ada/output.adb ada/put_spark_xrefs.ads \ - ada/put_spark_xrefs.adb ada/spark_xrefs.ads ada/spark_xrefs.adb \ - ada/system.ads ada/s-assert.ads ada/s-exctab.ads ada/s-memory.ads \ - ada/s-os_lib.ads ada/s-parame.ads ada/s-soflin.ads ada/s-stache.ads \ - ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \ - ada/s-traent.ads ada/s-unstyp.ads ada/types.ads ada/unchconv.ads \ - ada/unchdeal.ads + ada/a-uncdea.ads ada/gnat.ads ada/g-hesorg.ads ada/g-hesorg.adb \ + ada/g-table.ads ada/g-table.adb ada/hostparm.ads ada/output.ads \ + ada/output.adb ada/put_spark_xrefs.ads ada/put_spark_xrefs.adb \ + ada/spark_xrefs.ads ada/spark_xrefs.adb ada/system.ads ada/s-assert.ads \ + ada/s-exctab.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \ + ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \ + ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ + ada/types.ads ada/unchconv.ads ada/unchdeal.ads ada/sprint.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \ @@ -4490,12 +4498,11 @@ ada/validsw.o : ada/ada.ads ada/a-unccon.ads ada/a-uncdea.ads \ ada/warnsw.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/alloc.ads ada/debug.ads ada/err_vars.ads \ ada/hostparm.ads ada/namet.ads ada/opt.ads ada/output.ads \ - ada/rident.ads ada/system.ads ada/s-assert.ads ada/s-exctab.ads \ - ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \ - ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \ - ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \ - ada/tree_io.ads ada/types.ads ada/uintp.ads ada/unchconv.ads \ - ada/unchdeal.ads ada/warnsw.ads ada/warnsw.adb + ada/system.ads ada/s-assert.ads ada/s-exctab.ads ada/s-memory.ads \ + ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads ada/s-string.ads \ + ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \ + ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads \ + ada/unchconv.ads ada/unchdeal.ads ada/warnsw.ads ada/warnsw.adb ada/widechar.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \ ada/a-uncdea.ads ada/hostparm.ads ada/interfac.ads ada/opt.ads \ diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in index 0c4057c1019..4fd368283a9 100644 --- a/gcc/ada/gcc-interface/Makefile.in +++ b/gcc/ada/gcc-interface/Makefile.in @@ -153,10 +153,14 @@ objdir = . target_alias=@target_alias@ target=@target@ +target_cpu=@target_cpu@ +target_vendor=@target_vendor@ +target_os=@target_os@ +host_cpu=@host_cpu@ +host_vendor=@host_vendor@ +host_os=@host_os@ xmake_file = @xmake_file@ tmake_file = @tmake_file@ -host_canonical=@host@ -target_cpu_default=@target_cpu_default@ #version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < $(srcdir)/version.c` #mainversion=`sed -e 's/.*\"\([0-9]*\.[0-9]*\).*/\1/' < $(srcdir)/version.c` @@ -254,20 +258,6 @@ TOOLS_LIBS = ../link.o ../targext.o ../../ggc-none.o ../../libcommon-target.a \ ../../libcommon.a ../../../libcpp/libcpp.a $(LIBGNAT) $(LIBINTL) $(LIBICONV) \ ../$(LIBBACKTRACE) ../$(LIBIBERTY) $(SYSLIBS) $(TGT_LIB) -# Convert the target variable into a space separated list of architecture, -# manufacturer, and operating system and assign each of those to its own -# variable. -host:=$(subst -, ,$(host_canonical)) -targ:=$(subst -, ,$(subst -gnu, ,$(target_alias))) -arch:=$(word 1,$(targ)) -ifeq ($(words $(targ)),2) - manu:= - osys:=$(word 2,$(targ)) -else - manu:=$(word 2,$(targ)) - osys:=$(word 3,$(targ)) -endif - # Specify the directories to be searched for header files. # Both . and srcdir are used, in that order, # so that tm.h and config.h will be found in the compilation @@ -279,7 +269,7 @@ ADA_INCLUDES = -I- -I. -I$(srcdir)/ada # Likewise, but valid for subdirectories of the current dir. # FIXME: for VxWorks, we cannot add $(fsrcdir) because the regs.h file in # that directory conflicts with a system header file. -ifneq ($(findstring vxworks,$(osys)),) +ifneq ($(findstring vxworks,$(target_os)),) INCLUDES_FOR_SUBDIR = -iquote . -iquote .. -iquote ../.. \ -iquote $(fsrcdir)/ada \ -I$(fsrcdir)/../include $(GMPINC) @@ -351,12 +341,12 @@ GNATMAKE_OBJS = a-except.o ali.o ali-util.o aspects.o s-casuti.o alloc.o \ # picks up the right files. For a given target this must be coherent # with MULTILIB_DIRNAMES defined in gcc/config/target/t-*. -ifeq ($(strip $(filter-out %x86_64, $(arch))),) +ifeq ($(strip $(filter-out %x86_64, $(target_cpu))),) ifeq ($(strip $(MULTISUBDIR)),/32) - arch:=i686 + target_cpu:=i686 else ifeq ($(strip $(MULTISUBDIR)),/x32) - arch:=x32 + target_cpu:=x32 endif endif endif @@ -459,7 +449,7 @@ EXTRA_LIBGNAT_SRCS= # If what's left is null then it's a match. # m68k VxWorks -ifeq ($(strip $(filter-out m68k% wrs vx%,$(targ))),) +ifeq ($(strip $(filter-out m68k% wrs vx%,$(target_cpu) $(target_vendor) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-vxworks.ads \ a-numaux.ads<a-numaux-vxworks.ads \ @@ -502,7 +492,7 @@ ifeq ($(strip $(filter-out m68k% wrs vx%,$(targ))),) endif # PowerPC and e500v2 VxWorks -ifeq ($(strip $(filter-out e500% powerpc% wrs vxworks,$(targ))),) +ifeq ($(strip $(filter-out powerpc% wrs vxworks,$(target_cpu) $(target_vendor) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-vxworks.ads \ a-numaux.ads<a-numaux-vxworks.ads \ @@ -608,7 +598,7 @@ ifeq ($(strip $(filter-out e500% powerpc% wrs vxworks,$(targ))),) endif # PowerPC and e500v2 VxWorks 653 -ifeq ($(strip $(filter-out powerpc% e500v2 wrs vxworksae,$(targ))),) +ifeq ($(strip $(filter-out powerpc% wrs vxworksae,$(target_cpu) $(target_vendor) $(target_os))),) # target pairs for vthreads runtime LIBGNAT_TARGET_PAIRS = \ a-elchha.adb<a-elchha-vxworks-ppc-full.adb \ @@ -670,7 +660,7 @@ ifeq ($(strip $(filter-out powerpc% e500v2 wrs vxworksae,$(targ))),) endif # PowerPC and e500v2 VxWorks MILS -ifeq ($(strip $(filter-out e500% powerpc% wrs vxworksmils,$(targ))),) +ifeq ($(strip $(filter-out powerpc% wrs vxworksmils,$(target_cpu) $(target_vendor) $(target_os))),) # target pairs for vthreads runtime LIBGNAT_TARGET_PAIRS = \ a-elchha.adb<a-elchha-vx6-raven-cert.adb \ @@ -720,7 +710,7 @@ ifeq ($(strip $(filter-out e500% powerpc% wrs vxworksmils,$(targ))),) endif # VxWorksae / VxWorks 653 for x86 (vxsim) - ?? VxWorks mils not implemented -ifeq ($(strip $(filter-out %86 wrs vxworksae vxworksmils,$(targ))),) +ifeq ($(strip $(filter-out %86 wrs vxworksae vxworksmils,$(target_cpu) $(target_vendor) $(target_os))),) # target pairs for kernel + vthreads runtime LIBGNAT_TARGET_PAIRS = \ a-elchha.adb<a-elchha-vxworks-ppc-full.adb \ @@ -780,7 +770,7 @@ ifeq ($(strip $(filter-out %86 wrs vxworksae vxworksmils,$(targ))),) endif # Sparc VxWorks -ifeq ($(strip $(filter-out sparc% leon% wrs vx%,$(targ))),) +ifeq ($(strip $(filter-out sparc% wrs vx%,$(target_cpu) $(target_vendor) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-vxworks.ads \ a-numaux.ads<a-numaux-vxworks.ads \ @@ -807,16 +797,16 @@ ifeq ($(strip $(filter-out sparc% leon% wrs vx%,$(targ))),) mlib-tgt-specific.adb<mlib-tgt-specific-vxworks.adb \ indepsw.adb<indepsw-gnu.adb - ifeq ($(strip $(filter-out sparc erc32 leon leon3, $(arch))),) - # 32-bits - LIBGNAT_TARGET_PAIRS += \ - s-vxwork.ads<s-vxwork-sparc.ads \ - system.ads<system-vxworks-sparc-kernel.ads - else + ifeq ($(strip $(filter-out sparc64 sparcv9, $(target_cpu))),) # 64-bits LIBGNAT_TARGET_PAIRS += \ s-vxwork.ads<s-vxwork-sparcv9.ads \ system.ads<system-vxworks-sparcv9.ads + else + # 32-bits + LIBGNAT_TARGET_PAIRS += \ + s-vxwork.ads<s-vxwork-sparc.ads \ + system.ads<system-vxworks-sparc-kernel.ads endif ifeq ($(strip $(filter-out kernel,$(THREAD_KIND))),) @@ -832,7 +822,7 @@ ifeq ($(strip $(filter-out sparc% leon% wrs vx%,$(targ))),) endif # x86 VxWorks -ifeq ($(strip $(filter-out %86 wrs vxworks,$(targ))),) +ifeq ($(strip $(filter-out %86 wrs vxworks,$(target_cpu) $(target_vendor) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-vxworks.ads \ i-vxwork.ads<i-vxwork-x86.ads \ @@ -923,7 +913,7 @@ ifeq ($(strip $(filter-out %86 wrs vxworks,$(targ))),) endif # ARM VxWorks -ifeq ($(strip $(filter-out arm% coff wrs vx%,$(targ))),) +ifeq ($(strip $(filter-out arm% coff wrs vx%,$(target_cpu) $(target_vendor) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-vxworks.ads \ a-numaux.ads<a-numaux-vxworks.ads \ @@ -959,7 +949,7 @@ ifeq ($(strip $(filter-out arm% coff wrs vx%,$(targ))),) endif # MIPS VxWorks -ifeq ($(strip $(filter-out mips% wrs vx%,$(targ))),) +ifeq ($(strip $(filter-out mips% wrs vx%,$(target_cpu) $(target_vendor) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-vxworks.ads \ a-numaux.ads<a-numaux-vxworks.ads \ @@ -994,7 +984,8 @@ ifeq ($(strip $(filter-out mips% wrs vx%,$(targ))),) EXTRA_LIBGNAT_OBJS+=vx_stack_info.o endif -ifeq ($(strip $(filter-out arm% androideabi,$(arch) $(osys))),) +# ARM linux, Android eabi +ifeq ($(strip $(filter-out arm% linux-androideabi,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-linux.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1022,7 +1013,7 @@ ifeq ($(strip $(filter-out arm% androideabi,$(arch) $(osys))),) endif # Sparc Solaris -ifeq ($(strip $(filter-out sparc% sun solaris%,$(targ))),) +ifeq ($(strip $(filter-out sparc% sun solaris%,$(target_cpu) $(target_vendor) $(target_os))),) LIBGNAT_TARGET_PAIRS_COMMON = \ a-intnam.ads<a-intnam-solaris.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1046,7 +1037,7 @@ ifeq ($(strip $(filter-out sparc% sun solaris%,$(targ))),) $(ATOMICS_TARGET_PAIRS) \ $(ATOMICS_BUILTINS_TARGET_PAIRS) - ifeq ($(strip $(filter-out sparc sun solaris%,$(targ))),) + ifeq ($(strip $(filter-out sparc sun solaris%,$(target_cpu) $(target_vendor) $(target_os))),) ifeq ($(strip $(MULTISUBDIR)),/sparcv9) LIBGNAT_TARGET_PAIRS = \ $(LIBGNAT_TARGET_PAIRS_COMMON) $(LIBGNAT_TARGET_PAIRS_64) @@ -1097,7 +1088,7 @@ ifeq ($(strip $(filter-out sparc% sun solaris%,$(targ))),) endif # x86 and x86-64 solaris -ifeq ($(strip $(filter-out %86 %x86_64 %amd64 solaris2%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out %86 %x86_64 solaris2%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS_COMMON = \ a-intnam.ads<a-intnam-solaris.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1122,7 +1113,7 @@ ifeq ($(strip $(filter-out %86 %x86_64 %amd64 solaris2%,$(arch) $(osys))),) $(X86_64_TARGET_PAIRS) \ system.ads<system-solaris-x86_64.ads - ifeq ($(strip $(filter-out %86 solaris2%,$(arch) $(osys))),) + ifeq ($(strip $(filter-out %86 solaris2%,$(target_cpu) $(target_os))),) ifeq ($(strip $(MULTISUBDIR)),/amd64) LIBGNAT_TARGET_PAIRS = \ $(LIBGNAT_TARGET_PAIRS_COMMON) $(LIBGNAT_TARGET_PAIRS_64) @@ -1154,7 +1145,7 @@ ifeq ($(strip $(filter-out %86 %x86_64 %amd64 solaris2%,$(arch) $(osys))),) endif # x86 Linux -ifeq ($(strip $(filter-out %86 linux%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out %86 linux%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-linux.ads \ a-synbar.adb<a-synbar-posix.adb \ @@ -1215,7 +1206,7 @@ ifeq ($(strip $(filter-out %86 linux%,$(arch) $(osys))),) endif # x86 kfreebsd -ifeq ($(strip $(filter-out %86 kfreebsd%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out %86 kfreebsd%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-freebsd.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1246,7 +1237,7 @@ ifeq ($(strip $(filter-out %86 kfreebsd%,$(arch) $(osys))),) MISCLIB = -lutil endif -ifeq ($(strip $(filter-out x86_64 kfreebsd%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out x86_64 kfreebsd%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-freebsd.ads \ a-numaux.adb<a-numaux-x86.adb \ @@ -1275,7 +1266,7 @@ ifeq ($(strip $(filter-out x86_64 kfreebsd%,$(arch) $(osys))),) endif # x86 FreeBSD -ifeq ($(strip $(filter-out %86 freebsd%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out %86 freebsd%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-freebsd.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1304,7 +1295,7 @@ ifeq ($(strip $(filter-out %86 freebsd%,$(arch) $(osys))),) endif # x86-64 FreeBSD -ifeq ($(strip $(filter-out %86_64 freebsd%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out %86_64 freebsd%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-freebsd.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1333,7 +1324,7 @@ ifeq ($(strip $(filter-out %86_64 freebsd%,$(arch) $(osys))),) endif # S390 Linux -ifeq ($(strip $(filter-out s390% linux%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out s390% linux%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS_COMMON = \ a-intnam.ads<a-intnam-linux.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1354,7 +1345,7 @@ ifeq ($(strip $(filter-out s390% linux%,$(arch) $(osys))),) LIBGNAT_TARGET_PAIRS_64 = \ system.ads<system-linux-s390x.ads - ifeq ($(strip $(filter-out s390x,$(arch))),) + ifeq ($(strip $(filter-out s390x,$(target_cpu))),) ifeq ($(strip $(MULTISUBDIR)),/32) LIBGNAT_TARGET_PAIRS = \ $(LIBGNAT_TARGET_PAIRS_COMMON) $(LIBGNAT_TARGET_PAIRS_32) @@ -1379,7 +1370,7 @@ ifeq ($(strip $(filter-out s390% linux%,$(arch) $(osys))),) endif # HP/PA HP-UX 10 -ifeq ($(strip $(filter-out hppa% hp hpux10%,$(targ))),) +ifeq ($(strip $(filter-out hppa% hp hpux10%,$(target_cpu) $(target_vendor) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-excpol.adb<a-excpol-abort.adb \ a-intnam.ads<a-intnam-hpux.ads \ @@ -1399,7 +1390,7 @@ ifeq ($(strip $(filter-out hppa% hp hpux10%,$(targ))),) endif # HP/PA HP-UX 11 -ifeq ($(strip $(filter-out hppa% hp hpux11%,$(targ))),) +ifeq ($(strip $(filter-out hppa% hp hpux11%,$(target_cpu) $(target_vendor) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-hpux.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1426,7 +1417,7 @@ ifeq ($(strip $(filter-out hppa% hp hpux11%,$(targ))),) endif # IBM AIX -ifeq ($(strip $(filter-out ibm aix%,$(manu) $(osys))),) +ifeq ($(strip $(filter-out ibm aix%,$(target_vendor) $(target_os))),) LIBGNAT_TARGET_PAIRS_COMMON = \ a-intnam.ads<a-intnam-aix.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1470,7 +1461,7 @@ ifeq ($(strip $(filter-out ibm aix%,$(manu) $(osys))),) endif # RTEMS -ifeq ($(strip $(filter-out rtems%,$(osys))),) +ifeq ($(strip $(filter-out rtems%,$(target_os))),) LIBGNAT_TARGET_PAIRS = \ system.ads<system-rtems.ads \ a-intnam.ads<a-intnam-rtems.ads \ @@ -1488,7 +1479,7 @@ ifeq ($(strip $(filter-out rtems%,$(osys))),) endif # OpenVMS (host) -ifeq ($(strip $(filter-out alpha64 ia64 dec hp vms% openvms% alphavms%,$(host))),) +ifeq ($(strip $(filter-out alpha64 ia64 dec hp vms% openvms% alphavms%,$(host_cpu) $(host_vendor) $(host_os))),) soext = .exe hyphen = _ @@ -1498,7 +1489,7 @@ LN_S = cp -p endif # OpenVMS (target) -ifeq ($(strip $(filter-out alpha64 ia64 dec hp vms% openvms% alphavms%,$(targ))),) +ifeq ($(strip $(filter-out alpha64 ia64 dec hp vms% openvms% alphavms%,$(target_cpu) $(target_vendor) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-caldel.adb<a-caldel-vms.adb \ a-calend.adb<a-calend-vms.adb \ @@ -1532,7 +1523,7 @@ ifeq ($(strip $(filter-out alpha64 ia64 dec hp vms% openvms% alphavms%,$(targ))) s-tpopde.adb<s-tpopde-vms.adb \ s-tpopde.ads<s-tpopde-vms.ads - ifeq ($(strip $(filter-out ia64 hp vms% openvms%,$(targ))),) + ifeq ($(strip $(filter-out ia64 hp vms% openvms%,$(target_cpu) $(target_vendor) $(target_os))),) LIBGNAT_TARGET_PAIRS += \ g-enblsp.adb<g-enblsp-vms-ia64.adb \ g-trasym.adb<g-trasym-vms-ia64.adb \ @@ -1552,7 +1543,7 @@ ifeq ($(strip $(filter-out alpha64 ia64 dec hp vms% openvms% alphavms%,$(targ))) symbols.adb<symbols-vms.adb \ symbols-processing.adb<symbols-processing-vms-ia64.adb else - ifeq ($(strip $(filter-out alpha64 dec vms% openvms% alphavms%,$(targ))),) + ifeq ($(strip $(filter-out alpha64 dec vms% openvms% alphavms%,$(target_cpu) $(target_vendor) $(target_os))),) LIBGNAT_TARGET_PAIRS += \ g-enblsp.adb<g-enblsp-vms-alpha.adb \ g-trasym.adb<g-trasym-vms-alpha.adb \ @@ -1590,22 +1581,22 @@ ifeq ($(strip $(filter-out alpha64 ia64 dec hp vms% openvms% alphavms%,$(targ))) LIBRARY_VERSION := $(subst .,_,$(LIB_VERSION)) endif -# *-elf -ifeq ($(strip $(filter-out lmp avr none powerpc% eabispe leon% erc32% unknown elf,$(targ))),) +# *-elf, *-eabi or *-eabispe +ifeq ($(strip $(filter-out elf eabi eabispe,$(target_os))),) TOOLS_TARGET_PAIRS=\ mlib-tgt-specific.adb<mlib-tgt-specific-xi.adb \ indepsw.adb<indepsw-gnu.adb endif # Cygwin/Mingw32 -ifeq ($(strip $(filter-out cygwin% mingw32% pe,$(osys))),) +ifeq ($(strip $(filter-out cygwin% mingw32% pe,$(target_os))),) # Cygwin provides a full Posix environment, and so we use the default # versions of s-memory and g-socthi rather than the Windows-specific # MinGW versions. Ideally we would use all the default versions for # Cygwin and none of the MinGW versions, but for historical reasons # the Cygwin port has always been a CygMing frankenhybrid and it is # a long-term project to disentangle them. - ifeq ($(strip $(filter-out cygwin%,$(osys))),) + ifeq ($(strip $(filter-out cygwin%,$(target_os))),) LIBGNAT_TARGET_PAIRS = \ s-memory.adb<s-memory.adb \ g-socthi.ads<g-socthi.ads \ @@ -1663,7 +1654,7 @@ ifeq ($(strip $(filter-out cygwin% mingw32% pe,$(osys))),) s-osprim.adb<s-osprim-mingw.adb \ s-taprop.adb<s-taprop-mingw.adb - ifeq ($(strip $(filter-out x86_64%,$(arch))),) + ifeq ($(strip $(filter-out x86_64%,$(target_cpu))),) ifeq ($(strip $(MULTISUBDIR)),/32) LIBGNAT_TARGET_PAIRS += \ $(X86_TARGET_PAIRS) \ @@ -1714,7 +1705,7 @@ ifeq ($(strip $(filter-out cygwin% mingw32% pe,$(osys))),) endif # Mips Linux -ifeq ($(strip $(filter-out mips linux%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out mips linux%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-linux.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1738,7 +1729,7 @@ ifeq ($(strip $(filter-out mips linux%,$(arch) $(osys))),) endif # Mips/el Linux -ifeq ($(strip $(filter-out mipsel linux%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out mipsel linux%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS_COMMON = \ a-intnam.ads<a-intnam-linux.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1781,7 +1772,7 @@ ifeq ($(strip $(filter-out mipsel linux%,$(arch) $(osys))),) endif # Mips64/el Linux -ifeq ($(strip $(filter-out mips64el linux%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out mips64el linux%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS_COMMON = \ a-intnam.ads<a-intnam-linux.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1824,7 +1815,7 @@ ifeq ($(strip $(filter-out mips64el linux%,$(arch) $(osys))),) endif # PowerPC and e500v2 Linux -ifeq ($(strip $(filter-out powerpc% e500% linux%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out powerpc% linux%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS_COMMON = \ a-exetim.adb<a-exetim-posix.adb \ a-exetim.ads<a-exetim-default.ads \ @@ -1887,7 +1878,8 @@ ifeq ($(strip $(filter-out powerpc% e500% linux%,$(arch) $(osys))),) LIBRARY_VERSION := $(LIB_VERSION) endif -ifeq ($(strip $(filter-out arm%-linux,$(arch)-$(osys)) $(if $(findstring eabi,$(word 4,$(targ))),,$(word 4,$(targ)))),) +# ARM linux, GNU eabi +ifeq ($(strip $(filter-out arm% linux-gnueabi,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-linux.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1902,7 +1894,7 @@ ifeq ($(strip $(filter-out arm%-linux,$(arch)-$(osys)) $(if $(findstring eabi,$( s-taspri.ads<s-taspri-posix-noaltstack.ads \ s-tpopsp.adb<s-tpopsp-posix-foreign.adb - ifeq ($(strip $(filter-out arm%b,$(arch))),) + ifeq ($(strip $(filter-out arm%b,$(target_cpu))),) LIBGNAT_TARGET_PAIRS += \ system.ads<system-linux-armeb.ads else @@ -1923,7 +1915,7 @@ ifeq ($(strip $(filter-out arm%-linux,$(arch)-$(osys)) $(if $(findstring eabi,$( endif # Sparc Linux -ifeq ($(strip $(filter-out sparc% linux%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out sparc% linux%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS_COMMON = \ a-intnam.ads<a-intnam-linux.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1965,7 +1957,7 @@ ifeq ($(strip $(filter-out sparc% linux%,$(arch) $(osys))),) endif # HP/PA Linux -ifeq ($(strip $(filter-out hppa% linux%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out hppa% linux%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-linux.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -1994,7 +1986,7 @@ ifeq ($(strip $(filter-out hppa% linux%,$(arch) $(osys))),) endif # SH4 Linux -ifeq ($(strip $(filter-out sh4% linux%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out sh4% linux%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-linux.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -2024,7 +2016,7 @@ ifeq ($(strip $(filter-out sh4% linux%,$(arch) $(osys))),) endif # IA64 Linux -ifeq ($(strip $(filter-out %ia64 linux%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out %ia64 linux%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-exetim.adb<a-exetim-posix.adb \ a-exetim.ads<a-exetim-default.ads \ @@ -2063,7 +2055,7 @@ ifeq ($(strip $(filter-out %ia64 linux%,$(arch) $(osys))),) endif # IA64 HP-UX -ifeq ($(strip $(filter-out ia64% hp hpux%,$(targ))),) +ifeq ($(strip $(filter-out ia64% hp hpux%,$(target_cpu) $(target_vendor) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-hpux.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -2092,7 +2084,7 @@ ifeq ($(strip $(filter-out ia64% hp hpux%,$(targ))),) endif # Alpha Linux -ifeq ($(strip $(filter-out alpha% linux%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out alpha% linux%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-linux.ads \ s-inmaop.adb<s-inmaop-posix.adb \ @@ -2123,7 +2115,7 @@ ifeq ($(strip $(filter-out alpha% linux%,$(arch) $(osys))),) endif # x86-64 Linux -ifeq ($(strip $(filter-out %x86_64 linux%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out %x86_64 linux%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-exetim.adb<a-exetim-posix.adb \ a-exetim.ads<a-exetim-default.ads \ @@ -2160,7 +2152,7 @@ ifeq ($(strip $(filter-out %x86_64 linux%,$(arch) $(osys))),) LIBRARY_VERSION := $(LIB_VERSION) endif -ifeq ($(strip $(filter-out %x32 linux%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out %x32 linux%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-exetim.adb<a-exetim-posix.adb \ a-exetim.ads<a-exetim-default.ads \ @@ -2198,7 +2190,7 @@ ifeq ($(strip $(filter-out %x32 linux%,$(arch) $(osys))),) endif # Darwin (Mac OS X) -ifeq ($(strip $(filter-out darwin%,$(osys))),) +ifeq ($(strip $(filter-out darwin%,$(target_os))),) SO_OPTS = -shared-libgcc LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-darwin.ads \ @@ -2209,7 +2201,7 @@ ifeq ($(strip $(filter-out darwin%,$(osys))),) s-taspri.ads<s-taspri-posix.ads \ s-tpopsp.adb<s-tpopsp-posix-foreign.adb - ifeq ($(strip $(filter-out %86,$(arch))),) + ifeq ($(strip $(filter-out %86,$(target_cpu))),) LIBGNAT_TARGET_PAIRS += \ s-intman.adb<s-intman-susv3.adb \ s-osprim.adb<s-osprim-darwin.adb \ @@ -2229,7 +2221,7 @@ ifeq ($(strip $(filter-out darwin%,$(osys))),) EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o endif - ifeq ($(strip $(filter-out %x86_64,$(arch))),) + ifeq ($(strip $(filter-out %x86_64,$(target_cpu))),) LIBGNAT_TARGET_PAIRS += \ s-intman.adb<s-intman-susv3.adb \ s-osprim.adb<s-osprim-darwin.adb \ @@ -2249,7 +2241,7 @@ ifeq ($(strip $(filter-out darwin%,$(osys))),) EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o endif - ifeq ($(strip $(filter-out powerpc%,$(arch))),) + ifeq ($(strip $(filter-out powerpc%,$(target_cpu))),) LIBGNAT_TARGET_PAIRS += \ s-intman.adb<s-intman-posix.adb \ s-osprim.adb<s-osprim-posix.adb \ @@ -2279,7 +2271,7 @@ ifeq ($(strip $(filter-out darwin%,$(osys))),) endif # ARM Nucleus -ifeq ($(strip $(filter-out arm nucleus%,$(arch) $(osys))),) +ifeq ($(strip $(filter-out arm nucleus%,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ system.ads<system-nucleus-arm.ads \ a-numaux.ads<a-numaux-vxworks.ads \ @@ -2621,7 +2613,7 @@ install-gnatlib: ../stamp-gnatlib-$(RTSDIR) $(RM) ../stamp-gnatlib-$(RTSDIR) touch ../stamp-gnatlib1-$(RTSDIR) -ifeq ($(strip $(filter-out alpha64 ia64 dec hp vms% openvms% alphavms%,$(subst -, ,$(host)))),) +ifeq ($(strip $(filter-out alpha64 ia64 dec hp vms% openvms% alphavms%, $(host_cpu) $(host_os))),) OSCONS_CPP=../../$(DECC) -E /comment=as_is -DNATIVE \ -DTARGET='""$(target)""' $(fsrcpfx)ada/s-oscons-tmplt.c diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 40276a0ef42..80520a5acc8 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 91a5332de4e..197f3159f4f 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/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb index fa959df7407..b0e3087508f 100644 --- a/gcc/ada/gnat1drv.adb +++ b/gcc/ada/gnat1drv.adb @@ -242,7 +242,7 @@ procedure Gnat1drv is -- Enable assertions, since they give CodePeer valuable extra info - Assertions_Enabled := True; + Assertions_Enabled := True; -- Disable all simple value propagation. This is an optimization -- which is valuable for code optimization, and also for generation @@ -413,10 +413,10 @@ procedure Gnat1drv is -- which is more complex to formally verify than the original source. Tagged_Type_Expansion := False; - end if; - -- Set Configurable_Run_Time mode if system.ads flag set + -- Set Configurable_Run_Time mode if system.ads flag set or if the + -- special debug flag -gnatdY is set. if Targparm.Configurable_Run_Time_On_Target or Debug_Flag_YY then Configurable_Run_Time_Mode := True; @@ -571,6 +571,21 @@ procedure Gnat1drv is end if; end if; + -- Output warning if -gnateE specified and cannot be supported + + if Exception_Extra_Info + and then Restrict.No_Exception_Handlers_Set + then + Set_Standard_Error; + Write_Str + ("warning: extra exception information (-gnateE) was specified"); + Write_Eol; + Write_Str + ("warning: this capability is not available in this configuration"); + Write_Eol; + Set_Standard_Output; + end if; + -- Finally capture adjusted value of Suppress_Options as the initial -- value for Scope_Suppress, which will be modified as we move from -- scope to scope (by Suppress/Unsuppress/Overflow_Checks pragmas). diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi index 0a5f07db04a..40ffc35dacd 100644 --- a/gcc/ada/gnat_ugn.texi +++ b/gcc/ada/gnat_ugn.texi @@ -3697,7 +3697,9 @@ object file after compilation. If @command{gnatmake} is called with @option{-gnatc} as a builder switch (before @option{-cargs} or in package Builder of the project file) then @command{gnatmake} will not fail because it will not look for the object files after compilation, and it will not try -to build and link. +to build and link. This switch may not be given if a previous @code{-gnatR} +switch has been given, since @code{-gnatR} requires that the code generator +be called to complete determination of representation information. @item -gnatC @cindex @option{-gnatC} (@command{gcc}) @@ -4006,8 +4008,14 @@ Treat pragma Restrictions as Restriction_Warnings. @item ^-gnatR@r{[}0@r{/}1@r{/}2@r{/}3@r{[}s@r{]]}^/REPRESENTATION_INFO^ @cindex @option{-gnatR} (@command{gcc}) Output representation information for declared types and objects. -Note that this switch is not allowed if a previous --gnatD switch has been given, since these two switches are not compatible. +Note that this switch is not allowed if a previous @code{-gnatD} switch has +been given, since these two switches are not compatible. It is also not allowed +if a previous @code{-gnatc} switch has been given, since we must be generating +code to be able to determine representation information. + +@item ^-gnatRm[s]^/REPRESENTATION_INFO^ +Output convention and parameter passing mechanisms for all subprograms. +This form is also incompatible with the use of @code{-gnatc}. @item -gnats @cindex @option{-gnats} (@command{gcc}) @@ -7273,6 +7281,11 @@ discriminant. See source files @file{repinfo.ads/adb} in the output. If the switch is followed by an s (e.g.@: @option{-gnatR2s}), then the output is to a file with the name @file{^file.rep^file_REP^} where file is the name of the corresponding source file. + +@item -gnatRm[s] +This form of the switch controls output of subprogram conventions +and parameter passing mechanisms for all subprograms. A following +@code{s} means output to a file as described above. @end ifclear @ifset vms @item /REPRESENTATION_INFO @@ -7296,7 +7309,14 @@ If _FILE is added at the end of an option (e.g.@: @option{/REPRESENTATION_INFO=ARRAYS_FILE}), then the output is to a file with the name @file{file_REP} where file is the name of the corresponding source file. + +@item /REPRESENTATION_INFO=MECHANISMS +This qualifier form controls output of subprogram conventions +and parameter passing mechanisms for all subprograms. It is +possible to append _FILE as described above to cause information +to be written to a file. @end ifset + Note that it is possible for record components to have zero size. In this case, the component clause uses an obvious extension of permitted Ada syntax, for example @code{at 0 range 0 .. -1}. diff --git a/gcc/ada/gnatbind.adb b/gcc/ada/gnatbind.adb index 52591c46b07..14afac55386 100644 --- a/gcc/ada/gnatbind.adb +++ b/gcc/ada/gnatbind.adb @@ -572,7 +572,7 @@ begin -- First, scan to detect --version and/or --help - Check_Version_And_Help ("GNATBIND", "1995"); + Check_Version_And_Help ("GNATBIND", "1992"); -- We need to Scan_Bind_Args first, to set Verbose_Mode, so we know whether -- to Put_Bind_Args. diff --git a/gcc/ada/gnatdll.adb b/gcc/ada/gnatdll.adb index 6917e631d08..426c00f58bd 100644 --- a/gcc/ada/gnatdll.adb +++ b/gcc/ada/gnatdll.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1997-2008, Free Software Foundation, Inc. -- +-- Copyright (C) 1997-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -26,16 +26,18 @@ -- GNATDLL is a Windows specific tool for building a DLL. -- Both relocatable and non-relocatable DLL's are supported +with Gnatvsn; +with MDLL.Fil; use MDLL.Fil; +with MDLL.Utl; use MDLL.Utl; +with Switch; use Switch; + with Ada.Text_IO; use Ada.Text_IO; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Ada.Exceptions; use Ada.Exceptions; with Ada.Command_Line; use Ada.Command_Line; -with GNAT.OS_Lib; use GNAT.OS_Lib; -with GNAT.Command_Line; use GNAT.Command_Line; -with Gnatvsn; -with MDLL.Fil; use MDLL.Fil; -with MDLL.Utl; use MDLL.Utl; +with GNAT.OS_Lib; use GNAT.OS_Lib; +with GNAT.Command_Line; use GNAT.Command_Line; procedure Gnatdll is @@ -502,9 +504,13 @@ procedure Gnatdll is end loop; end Check_Context; + procedure Check_Version_And_Help is new Check_Version_And_Help_G (Syntax); + -- Start of processing for Gnatdll begin + Check_Version_And_Help ("GNATDLL", "1997"); + if Ada.Command_Line.Argument_Count = 0 then Help := True; else diff --git a/gcc/ada/gnatkr.adb b/gcc/ada/gnatkr.adb index 1df692e7b4d..908f08ef667 100644 --- a/gcc/ada/gnatkr.adb +++ b/gcc/ada/gnatkr.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2007, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -23,10 +23,13 @@ -- -- ------------------------------------------------------------------------------ -with Ada.Characters.Handling; use Ada.Characters.Handling; -with Ada.Command_Line; use Ada.Command_Line; with Gnatvsn; with Krunch; +with Switch; use Switch; + +with Ada.Characters.Handling; use Ada.Characters.Handling; +with Ada.Command_Line; use Ada.Command_Line; + with System.IO; use System.IO; procedure Gnatkr is @@ -38,13 +41,28 @@ procedure Gnatkr is function Get_Maximum_File_Name_Length return Integer; pragma Import (C, Get_Maximum_File_Name_Length, - "__gnat_get_maximum_file_name_length"); + "__gnat_get_maximum_file_name_length"); + + procedure Usage; + -- Output usage information + + ----------- + -- Usage -- + ----------- + + procedure Usage is + begin + Put_Line ("Usage: gnatkr filename[.extension] [krunch-count]"); + end Usage; + + procedure Check_Version_And_Help is new Check_Version_And_Help_G (Usage); begin + Check_Version_And_Help ("GNATKR", "1992"); Count := Argument_Count; if Count < 1 or else Count > 2 then - Put_Line ("Usage: gnatkr filename[.extension] [krunch-count]"); + Usage; raise Exit_Program; else diff --git a/gcc/ada/gnatlink.adb b/gcc/ada/gnatlink.adb index 503c2f7b152..793feb95690 100644 --- a/gcc/ada/gnatlink.adb +++ b/gcc/ada/gnatlink.adb @@ -355,7 +355,7 @@ procedure Gnatlink is begin -- First, check for --version and --help - Check_Version_And_Help ("GNATLINK", "1995"); + Check_Version_And_Help ("GNATLINK", "1996"); -- Loop through arguments of gnatlink command diff --git a/gcc/ada/gnatls.adb b/gcc/ada/gnatls.adb index ae623897d6c..4a97edde9a5 100644 --- a/gcc/ada/gnatls.adb +++ b/gcc/ada/gnatls.adb @@ -1556,7 +1556,7 @@ begin -- First check for --version or --help - Check_Version_And_Help ("GNATLS", "1997"); + Check_Version_And_Help ("GNATLS", "1992"); -- Loop to scan out arguments diff --git a/gcc/ada/inline.ads b/gcc/ada/inline.ads index f3750a83aa2..825b958f1ef 100644 --- a/gcc/ada/inline.ads +++ b/gcc/ada/inline.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2012, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -36,10 +36,11 @@ -- Frontend, and thus are not mutually recursive. with Alloc; -with Opt; use Opt; -with Sem; use Sem; +with Opt; use Opt; +with Sem; use Sem; with Table; -with Types; use Types; +with Types; use Types; +with Warnsw; use Warnsw; package Inline is @@ -89,6 +90,12 @@ package Inline is -- The body must be compiled with the same language version as the -- spec. The version may be set by a configuration pragma in a separate -- file or in the current file, and may differ from body to body. + + Version_Pragma : Node_Id; + -- This is linked with the Version value + + Warnings : Warning_Record; + -- Capture values of warning flags end record; package Pending_Instantiations is new Table.Table ( diff --git a/gcc/ada/make.adb b/gcc/ada/make.adb index d9973b52a0b..84b7a3b64e0 100644 --- a/gcc/ada/make.adb +++ b/gcc/ada/make.adb @@ -5803,7 +5803,7 @@ package body Make is if Verbose_Mode then Write_Eol; - Display_Version ("GNATMAKE", "1995"); + Display_Version ("GNATMAKE", "1992"); end if; if Osint.Number_Of_Files = 0 then diff --git a/gcc/ada/opt.adb b/gcc/ada/opt.adb index 1fc43cc203e..9f1f2d84a80 100644 --- a/gcc/ada/opt.adb +++ b/gcc/ada/opt.adb @@ -54,6 +54,7 @@ package body Opt is procedure Register_Opt_Config_Switches is begin Ada_Version_Config := Ada_Version; + Ada_Version_Pragma_Config := Ada_Version_Pragma; Ada_Version_Explicit_Config := Ada_Version_Explicit; Assertions_Enabled_Config := Assertions_Enabled; Assume_No_Invalid_Values_Config := Assume_No_Invalid_Values; @@ -87,6 +88,7 @@ package body Opt is procedure Restore_Opt_Config_Switches (Save : Config_Switches_Type) is begin Ada_Version := Save.Ada_Version; + Ada_Version_Pragma := Save.Ada_Version_Pragma; Ada_Version_Explicit := Save.Ada_Version_Explicit; Assertions_Enabled := Save.Assertions_Enabled; Assume_No_Invalid_Values := Save.Assume_No_Invalid_Values; @@ -122,6 +124,7 @@ package body Opt is procedure Save_Opt_Config_Switches (Save : out Config_Switches_Type) is begin Save.Ada_Version := Ada_Version; + Save.Ada_Version_Pragma := Ada_Version_Pragma; Save.Ada_Version_Explicit := Ada_Version_Explicit; Save.Assertions_Enabled := Assertions_Enabled; Save.Assume_No_Invalid_Values := Assume_No_Invalid_Values; @@ -161,6 +164,7 @@ package body Opt is -- the configuration setting even in a run time unit. Ada_Version := Ada_Version_Runtime; + Ada_Version_Pragma := Empty; Dynamic_Elaboration_Checks := False; Extensions_Allowed := True; External_Name_Exp_Casing := As_Is; @@ -188,6 +192,7 @@ package body Opt is else Ada_Version := Ada_Version_Config; + Ada_Version_Pragma := Ada_Version_Pragma_Config; Ada_Version_Explicit := Ada_Version_Explicit_Config; Assertions_Enabled := Assertions_Enabled_Config; Assume_No_Invalid_Values := Assume_No_Invalid_Values_Config; diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads index a4cbafd3888..605dc89e839 100644 --- a/gcc/ada/opt.ads +++ b/gcc/ada/opt.ads @@ -131,6 +131,10 @@ package Opt is -- compiler switches, or implicitly (to Ada_Version_Runtime) when a -- predefined or internal file is compiled. + Ada_Version_Pragma : Node_Id := Empty; + -- Reflects the Ada_xxx pragma that resulted in setting Ada_Version. Used + -- to specialize error messages complaining about the Ada version in use. + Ada_Version_Explicit : Ada_Version_Type := Ada_Version_Default; -- GNAT -- Like Ada_Version, but does not get set implicitly for predefined @@ -861,7 +865,7 @@ package Opt is List_Representation_Info_To_File : Boolean := False; -- GNAT - -- Set true by -gnatRs switch. Causes information from -gnatR/1/2/3 to be + -- Set true by -gnatRs switch. Causes information from -gnatR/1/2/3/m to be -- written to file.rep (where file is the name of the source file) instead -- of stdout. For example, if file x.adb is compiled using -gnatR2s then -- representation info is written to x.adb.ref. @@ -1737,6 +1741,9 @@ package Opt is -- predefined units (which are always compiled in the most up to date -- version of Ada). + Ada_Version_Pragma_Config : Node_Id; + -- This will be set non empty if it is set by a configuration pragma + Ada_Version_Explicit_Config : Ada_Version_Type; -- GNAT -- This is set in the same manner as Ada_Version_Config. The difference is @@ -2019,6 +2026,7 @@ private type Config_Switches_Type is record Ada_Version : Ada_Version_Type; Ada_Version_Explicit : Ada_Version_Type; + Ada_Version_Pragma : Node_Id; Assertions_Enabled : Boolean; Assume_No_Invalid_Values : Boolean; Check_Float_Overflow : Boolean; diff --git a/gcc/ada/par-ch11.adb b/gcc/ada/par-ch11.adb index f0537f27cd1..61df3ee2512 100644 --- a/gcc/ada/par-ch11.adb +++ b/gcc/ada/par-ch11.adb @@ -213,11 +213,7 @@ package body Ch11 is Raise_Node : Node_Id; begin - if Ada_Version < Ada_2012 then - Error_Msg_SC ("raise expression is an Ada 2012 feature"); - Error_Msg_SC ("\|unit must be compiled with -gnat2012 switch"); - end if; - + Error_Msg_Ada_2012_Feature ("raise expression", Token_Ptr); Raise_Node := New_Node (N_Raise_Expression, Token_Ptr); Scan; -- past RAISE diff --git a/gcc/ada/par-ch12.adb b/gcc/ada/par-ch12.adb index 3c192f2877b..cf75f04fa15 100644 --- a/gcc/ada/par-ch12.adb +++ b/gcc/ada/par-ch12.adb @@ -74,10 +74,13 @@ package body Ch12 is -- GENERIC_RENAMING_DECLARATION ::= -- generic package DEFINING_PROGRAM_UNIT_NAME -- renames generic_package_NAME + -- [ASPECT_SPECIFICATIONS]; -- | generic procedure DEFINING_PROGRAM_UNIT_NAME -- renames generic_procedure_NAME + -- [ASPECT_SPECIFICATIONS]; -- | generic function DEFINING_PROGRAM_UNIT_NAME -- renames generic_function_NAME + -- [ASPECT_SPECIFICATIONS]; -- GENERIC_FORMAL_PARAMETER_DECLARATION ::= -- FORMAL_OBJECT_DECLARATION @@ -140,6 +143,8 @@ package body Ch12 is Scan; -- past RENAMES Set_Defining_Unit_Name (Decl_Node, Def_Unit); Set_Name (Decl_Node, P_Name); + + P_Aspect_Specifications (Decl_Node, Semicolon => False); TF_Semicolon; return Decl_Node; end if; @@ -211,7 +216,6 @@ package body Ch12 is else Gen_Decl := New_Node (N_Generic_Subprogram_Declaration, Gen_Sloc); - Set_Specification (Gen_Decl, P_Subprogram_Specification); if Nkind (Defining_Unit_Name (Specification (Gen_Decl))) = @@ -542,12 +546,8 @@ package body Ch12 is Scan; -- past semicolon - if Ada_Version < Ada_2012 then - Error_Msg_N - ("`formal incomplete type` is an Ada 2012 feature", Decl_Node); - Error_Msg_N - ("\unit must be compiled with -gnat2012 switch", Decl_Node); - end if; + Error_Msg_Ada_2012_Feature + ("formal incomplete type", Sloc (Decl_Node)); Set_Formal_Type_Definition (Decl_Node, @@ -560,13 +560,9 @@ package body Ch12 is Def_Node := P_Formal_Type_Definition; - if Nkind (Def_Node) = N_Formal_Incomplete_Type_Definition - and then Ada_Version < Ada_2012 - then - Error_Msg_N - ("`formal incomplete type` is an Ada 2012 feature", Decl_Node); - Error_Msg_N - ("\unit must be compiled with -gnat2012 switch", Decl_Node); + if Nkind (Def_Node) = N_Formal_Incomplete_Type_Definition then + Error_Msg_Ada_2012_Feature + ("formal incomplete type", Sloc (Decl_Node)); end if; if Def_Node /= Error then diff --git a/gcc/ada/par-ch13.adb b/gcc/ada/par-ch13.adb index 4d63d0e64a4..26b8056f80f 100644 --- a/gcc/ada/par-ch13.adb +++ b/gcc/ada/par-ch13.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2012, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -128,8 +128,7 @@ package body Ch13 is if Result then Restore_Scan_State (Scan_State); - Error_Msg_SC ("|aspect specification is an Ada 2012 feature"); - Error_Msg_SC ("\|unit must be compiled with -gnat2012 switch"); + Error_Msg_Ada_2012_Feature ("|aspect specification", Token_Ptr); return True; end if; end if; @@ -266,15 +265,20 @@ package body Ch13 is if Token = Tok_Comma or else Token = Tok_Semicolon then - if Aspect_Argument (A_Id) /= Optional then + if Aspect_Argument (A_Id) /= Optional_Expression + and then + Aspect_Argument (A_Id) /= Optional_Name + then Error_Msg_Node_1 := Identifier (Aspect); Error_Msg_AP ("aspect& requires an aspect definition"); OK := False; end if; elsif not Semicolon and then Token /= Tok_Arrow then - if Aspect_Argument (A_Id) /= Optional then - + if Aspect_Argument (A_Id) /= Optional_Expression + and then + Aspect_Argument (A_Id) /= Optional_Name + then -- The name or expression may be there, but the arrow is -- missing. Skip to the end of the declaration. @@ -292,9 +296,17 @@ package body Ch13 is OK := False; end if; - if Aspect_Argument (A_Id) = Name then + if Aspect_Argument (A_Id) = Name + or else + Aspect_Argument (A_Id) = Optional_Name + then Set_Expression (Aspect, P_Name); + else + pragma Assert + (Aspect_Argument (A_Id) = Expression + or else + Aspect_Argument (A_Id) = Optional_Expression); Set_Expression (Aspect, P_Expression); end if; end if; diff --git a/gcc/ada/par-ch3.adb b/gcc/ada/par-ch3.adb index eae388ba7ae..29126152d43 100644 --- a/gcc/ada/par-ch3.adb +++ b/gcc/ada/par-ch3.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2012, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -275,13 +275,14 @@ package body Ch3 is -- PRIVATE_TYPE_DECLARATION ::= -- type DEFINING_IDENTIFIER [DISCRIMINANT_PART] - -- is [abstract] [tagged] [limited] private; + -- is [abstract] [tagged] [limited] private + -- [ASPECT_SPECIFICATIONS]; -- PRIVATE_EXTENSION_DECLARATION ::= -- type DEFINING_IDENTIFIER [DISCRIMINANT_PART] is -- [abstract] [limited | synchronized] -- new ancestor_SUBTYPE_INDICATION [and INTERFACE_LIST] - -- with private; + -- with private [ASPECT_SPECIFICATIONS]; -- TYPE_DEFINITION ::= -- ENUMERATION_TYPE_DEFINITION | INTEGER_TYPE_DEFINITION @@ -1277,12 +1278,15 @@ package body Ch3 is -- OBJECT_RENAMING_DECLARATION ::= -- DEFINING_IDENTIFIER : - -- [NULL_EXCLUSION] SUBTYPE_MARK renames object_NAME; + -- [NULL_EXCLUSION] SUBTYPE_MARK renames object_NAME + -- [ASPECT_SPECIFICATIONS]; -- | DEFINING_IDENTIFIER : - -- ACCESS_DEFINITION renames object_NAME; + -- ACCESS_DEFINITION renames object_NAME + -- [ASPECT_SPECIFICATIONS]; -- EXCEPTION_RENAMING_DECLARATION ::= - -- DEFINING_IDENTIFIER : exception renames exception_NAME; + -- DEFINING_IDENTIFIER : exception renames exception_NAME + -- [ASPECT_SPECIFICATIONS]; -- EXCEPTION_DECLARATION ::= -- DEFINING_IDENTIFIER_LIST : exception @@ -1669,15 +1673,19 @@ package body Ch3 is -- OBJECT_DECLARATION ::= -- DEFINING_IDENTIFIER_LIST : [aliased] [constant] - -- [NULL_EXCLUSION] SUBTYPE_INDICATION [:= EXPRESSION]; + -- [NULL_EXCLUSION] SUBTYPE_INDICATION [:= EXPRESSION] + -- [ASPECT_SPECIFICATIONS]; -- | DEFINING_IDENTIFIER_LIST : [aliased] [constant] - -- ACCESS_DEFINITION [:= EXPRESSION]; + -- ACCESS_DEFINITION [:= EXPRESSION] + -- [ASPECT_SPECIFICATIONS]; -- OBJECT_RENAMING_DECLARATION ::= -- DEFINING_IDENTIFIER : - -- [NULL_EXCLUSION] SUBTYPE_MARK renames object_NAME; + -- [NULL_EXCLUSION] SUBTYPE_MARK renames object_NAME + -- [ASPECT_SPECIFICATIONS]; -- | DEFINING_IDENTIFIER : - -- ACCESS_DEFINITION renames object_NAME; + -- ACCESS_DEFINITION renames object_NAME + -- [ASPECT_SPECIFICATIONS]; Not_Null_Present := P_Null_Exclusion; -- Ada 2005 (AI-231/423) @@ -1893,7 +1901,7 @@ package body Ch3 is -- type DEFINING_IDENTIFIER [DISCRIMINANT_PART] is -- [abstract] [limited | synchronized] -- new ancestor_SUBTYPE_INDICATION [and INTERFACE_LIST] - -- with private; + -- with private [ASPECT_SPECIFICATIONS]; -- RECORD_EXTENSION_PART ::= with RECORD_DEFINITION diff --git a/gcc/ada/par-ch4.adb b/gcc/ada/par-ch4.adb index 38fd00e1fbb..5766639816a 100644 --- a/gcc/ada/par-ch4.adb +++ b/gcc/ada/par-ch4.adb @@ -2672,18 +2672,12 @@ package body Ch4 is Node1 : Node_Id; begin - if Ada_Version < Ada_2012 then - Error_Msg_SC ("quantified expression is an Ada 2012 feature"); - Error_Msg_SC ("\|unit must be compiled with -gnat2012 switch"); - end if; - + Error_Msg_Ada_2012_Feature ("quantified expression", Token_Ptr); Scan; -- past FOR - Node1 := New_Node (N_Quantified_Expression, Prev_Token_Ptr); if Token = Tok_All then Set_All_Present (Node1); - elsif Token /= Tok_Some then Error_Msg_AP ("missing quantifier"); raise Error_Resync; @@ -2960,14 +2954,9 @@ package body Ch4 is Set_Subpool_Handle_Name (Alloc_Node, P_Name); T_Right_Paren; - if Ada_Version < Ada_2012 then - Error_Msg_N - ("|subpool specification is an Ada 2012 feature", - Subpool_Handle_Name (Alloc_Node)); - Error_Msg_N - ("\|unit must be compiled with -gnat2012 switch", - Subpool_Handle_Name (Alloc_Node)); - end if; + Error_Msg_Ada_2012_Feature + ("|subpool specification", + Sloc (Subpool_Handle_Name (Alloc_Node))); end if; Null_Exclusion_Present := P_Null_Exclusion; @@ -3006,11 +2995,7 @@ package body Ch4 is Save_State : Saved_Scan_State; begin - if Ada_Version < Ada_2012 then - Error_Msg_SC ("|case expression is an Ada 2012 feature"); - Error_Msg_SC ("\|unit must be compiled with -gnat2012 switch"); - end if; - + Error_Msg_Ada_2012_Feature ("|case expression", Token_Ptr); Scan; -- past CASE Case_Node := Make_Case_Expression (Loc, @@ -3096,12 +3081,7 @@ package body Ch4 is begin Inside_If_Expression := Inside_If_Expression + 1; - - if Token = Tok_If and then Ada_Version < Ada_2012 then - Error_Msg_SC ("|if expression is an Ada 2012 feature"); - Error_Msg_SC ("\|unit must be compiled with -gnat2012 switch"); - end if; - + Error_Msg_Ada_2012_Feature ("|if expression", Token_Ptr); Scan; -- past IF or ELSIF Append_To (Exprs, P_Condition); TF_Then; @@ -3182,11 +3162,7 @@ package body Ch4 is -- Set case if Token = Tok_Vertical_Bar then - if Ada_Version < Ada_2012 then - Error_Msg_SC ("set notation is an Ada 2012 feature"); - Error_Msg_SC ("\|unit must be compiled with -gnat2012 switch"); - end if; - + Error_Msg_Ada_2012_Feature ("set notation", Token_Ptr); Set_Alternatives (N, New_List (Alt)); Set_Right_Opnd (N, Empty); diff --git a/gcc/ada/par-ch5.adb b/gcc/ada/par-ch5.adb index e9b0a2c8e95..94c5bd4d073 100644 --- a/gcc/ada/par-ch5.adb +++ b/gcc/ada/par-ch5.adb @@ -1656,10 +1656,7 @@ package body Ch5 is -- during analysis of the loop parameter specification. if Token = Tok_Of or else Token = Tok_Colon then - if Ada_Version < Ada_2012 then - Error_Msg_SC ("iterator is an Ada 2012 feature"); - end if; - + Error_Msg_Ada_2012_Feature ("iterator", Token_Ptr); return P_Iterator_Specification (ID_Node); end if; diff --git a/gcc/ada/par-ch6.adb b/gcc/ada/par-ch6.adb index 7531f405fe1..f060b3f2822 100644 --- a/gcc/ada/par-ch6.adb +++ b/gcc/ada/par-ch6.adb @@ -161,13 +161,16 @@ package body Ch6 is -- [ASPECT_SPECIFICATIONS]; -- SUBPROGRAM_BODY_STUB ::= - -- SUBPROGRAM_SPECIFICATION is separate; + -- SUBPROGRAM_SPECIFICATION is separate + -- [ASPECT_SPECIFICATIONS]; -- GENERIC_INSTANTIATION ::= -- procedure DEFINING_PROGRAM_UNIT_NAME is - -- new generic_procedure_NAME [GENERIC_ACTUAL_PART]; + -- new generic_procedure_NAME [GENERIC_ACTUAL_PART] + -- [ASPECT_SPECIFICATIONS]; -- | function DEFINING_DESIGNATOR is - -- new generic_function_NAME [GENERIC_ACTUAL_PART]; + -- new generic_function_NAME [GENERIC_ACTUAL_PART] + -- [ASPECT_SPECIFICATIONS]; -- NULL_PROCEDURE_DECLARATION ::= -- SUBPROGRAM_SPECIFICATION is null; @@ -394,8 +397,8 @@ package body Ch6 is if Token = Tok_Identifier and then not Token_Is_At_Start_Of_Line then - T_Left_Paren; -- to generate message - Fpart_List := P_Formal_Part; + T_Left_Paren; -- to generate message + Fpart_List := P_Formal_Part; -- Otherwise scan out an optional formal part in the usual manner @@ -681,21 +684,21 @@ package body Ch6 is Sloc (Name_Node)); end if; + Scan; -- past SEPARATE + Stub_Node := New_Node (N_Subprogram_Body_Stub, Sloc (Specification_Node)); Set_Specification (Stub_Node, Specification_Node); - -- The specification has been parsed as part of a subprogram - -- declaration, and aspects have already been collected. - if Is_Non_Empty_List (Aspects) then - Set_Parent (Aspects, Stub_Node); - Set_Aspect_Specifications (Stub_Node, Aspects); + Error_Msg + ("aspect specifications must come after SEPARATE", + Sloc (First (Aspects))); end if; - Scan; -- past SEPARATE - Pop_Scope_Stack; + P_Aspect_Specifications (Stub_Node, Semicolon => False); TF_Semicolon; + Pop_Scope_Stack; return Stub_Node; -- Subprogram body or expression function case @@ -831,12 +834,8 @@ package body Ch6 is -- Check we are in Ada 2012 mode - if Ada_Version < Ada_2012 then - Error_Msg_SC - ("expression function is an Ada 2012 feature!"); - Error_Msg_SC - ("\unit must be compiled with -gnat2012 switch!"); - end if; + Error_Msg_Ada_2012_Feature + ("!expression function", Token_Ptr); -- Catch an illegal placement of the aspect specification -- list: @@ -1464,7 +1463,8 @@ package body Ch6 is if Token = Tok_Aliased then if Ada_Version < Ada_2012 then - Error_Msg_SC ("ALIASED parameter is an Ada 2012 feature"); + Error_Msg_Ada_2012_Feature + ("ALIASED parameter", Token_Ptr); else Set_Aliased_Present (Specification_Node); end if; diff --git a/gcc/ada/par-ch7.adb b/gcc/ada/par-ch7.adb index d52a13d6c5b..0a658c963e1 100644 --- a/gcc/ada/par-ch7.adb +++ b/gcc/ada/par-ch7.adb @@ -38,28 +38,33 @@ package body Ch7 is -- renaming declaration or generic instantiation starting with PACKAGE -- PACKAGE_DECLARATION ::= - -- PACKAGE_SPECIFICATION - -- [ASPECT_SPECIFICATIONS]; + -- PACKAGE_SPECIFICATION; -- PACKAGE_SPECIFICATION ::= - -- package DEFINING_PROGRAM_UNIT_NAME is + -- package DEFINING_PROGRAM_UNIT_NAME + -- [ASPECT_SPECIFICATIONS] + -- is -- {BASIC_DECLARATIVE_ITEM} -- [private -- {BASIC_DECLARATIVE_ITEM}] -- end [[PARENT_UNIT_NAME .] IDENTIFIER] -- PACKAGE_BODY ::= - -- package body DEFINING_PROGRAM_UNIT_NAME is + -- package body DEFINING_PROGRAM_UNIT_NAME + -- [ASPECT_SPECIFICATIONS] + -- is -- DECLARATIVE_PART -- [begin -- HANDLED_SEQUENCE_OF_STATEMENTS] -- end [[PARENT_UNIT_NAME .] IDENTIFIER] -- PACKAGE_RENAMING_DECLARATION ::= - -- package DEFINING_IDENTIFIER renames package_NAME; + -- package DEFINING_IDENTIFIER renames package_NAME + -- [ASPECT_SPECIFICATIONS]; -- PACKAGE_BODY_STUB ::= - -- package body DEFINING_IDENTIFIER is separate; + -- package body DEFINING_IDENTIFIER is separate + -- [ASPECT_SPECIFICATIONS]; -- PACKAGE_INSTANTIATION ::= -- package DEFINING_PROGRAM_UNIT_NAME is @@ -141,6 +146,12 @@ package body Ch7 is Scope.Table (Scope.Last).Sloc := Token_Ptr; Name_Node := P_Defining_Program_Unit_Name; Scope.Table (Scope.Last).Labl := Name_Node; + + if Aspect_Specifications_Present then + Aspect_Sloc := Token_Ptr; + P_Aspect_Specifications (Dummy_Node, Semicolon => False); + end if; + TF_Is; if Separate_Present then @@ -149,16 +160,30 @@ package body Ch7 is end if; Scan; -- past SEPARATE - TF_Semicolon; - Pop_Scope_Stack; Package_Node := New_Node (N_Package_Body_Stub, Package_Sloc); Set_Defining_Identifier (Package_Node, Name_Node); + if Has_Aspects (Dummy_Node) then + Error_Msg + ("aspect specifications must come after SEPARATE", + Aspect_Sloc); + end if; + + P_Aspect_Specifications (Package_Node, Semicolon => False); + TF_Semicolon; + Pop_Scope_Stack; + else Package_Node := New_Node (N_Package_Body, Package_Sloc); Set_Defining_Unit_Name (Package_Node, Name_Node); + -- Move the aspect specifications to the body node + + if Has_Aspects (Dummy_Node) then + Move_Aspects (From => Dummy_Node, To => Package_Node); + end if; + -- In SPARK, a HIDE directive can be placed at the beginning of a -- package implementation, thus hiding the package body from SPARK -- tool-set. No violation of the SPARK restriction should be @@ -204,6 +229,7 @@ package body Ch7 is Set_Name (Package_Node, P_Qualified_Simple_Name); No_Constraint; + P_Aspect_Specifications (Package_Node, Semicolon => False); TF_Semicolon; Pop_Scope_Stack; diff --git a/gcc/ada/par-ch8.adb b/gcc/ada/par-ch8.adb index fb2bf17c44d..89a2bb4a22b 100644 --- a/gcc/ada/par-ch8.adb +++ b/gcc/ada/par-ch8.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2012, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -110,14 +110,9 @@ package body Ch8 is begin if Token = Tok_All then - if Ada_Version < Ada_2012 then - Error_Msg_SC ("|`USE ALL TYPE` is an Ada 2012 feature"); - Error_Msg_SC ("\|unit must be compiled with -gnat2012 switch"); - end if; - + Error_Msg_Ada_2012_Feature ("|`USE ALL TYPE`", Token_Ptr); All_Present := True; Scan; -- past ALL - else All_Present := False; end if; diff --git a/gcc/ada/par-ch9.adb b/gcc/ada/par-ch9.adb index 2de05880b59..e1692c4a11b 100644 --- a/gcc/ada/par-ch9.adb +++ b/gcc/ada/par-ch9.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2011, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -61,14 +61,15 @@ package body Ch9 is -- [is [new INTERFACE_LIST with] TASK_DEFINITION]; -- TASK_BODY ::= - -- task body DEFINING_IDENTIFIER is + -- task body DEFINING_IDENTIFIER [ASPECT_SPECIFICATIONS] is -- DECLARATIVE_PART -- begin -- HANDLED_SEQUENCE_OF_STATEMENTS -- end [task_IDENTIFIER] -- TASK_BODY_STUB ::= - -- task body DEFINING_IDENTIFIER is separate; + -- task body DEFINING_IDENTIFIER is separate + -- [ASPECT_SPECIFICATIONS]; -- This routine scans out a task declaration, task body, or task stub @@ -78,9 +79,15 @@ package body Ch9 is -- Error recovery: cannot raise Error_Resync function P_Task return Node_Id is - Name_Node : Node_Id; - Task_Node : Node_Id; - Task_Sloc : Source_Ptr; + Aspect_Sloc : Source_Ptr; + Name_Node : Node_Id; + Task_Node : Node_Id; + Task_Sloc : Source_Ptr; + + Dummy_Node : constant Node_Id := New_Node (N_Task_Body, Token_Ptr); + -- Placeholder node used to hold legal or prematurely declared aspect + -- specifications. Depending on the context, the aspect specifications + -- may be moved to a new node. begin Push_Scope_Stack; @@ -100,6 +107,11 @@ package body Ch9 is Discard_Junk_List (P_Known_Discriminant_Part_Opt); end if; + if Aspect_Specifications_Present then + Aspect_Sloc := Token_Ptr; + P_Aspect_Specifications (Dummy_Node, Semicolon => False); + end if; + TF_Is; -- Task stub @@ -108,6 +120,14 @@ package body Ch9 is Scan; -- past SEPARATE Task_Node := New_Node (N_Task_Body_Stub, Task_Sloc); Set_Defining_Identifier (Task_Node, Name_Node); + + if Has_Aspects (Dummy_Node) then + Error_Msg + ("aspect specifications must come after SEPARATE", + Aspect_Sloc); + end if; + + P_Aspect_Specifications (Task_Node, Semicolon => False); TF_Semicolon; Pop_Scope_Stack; -- remove unused entry @@ -116,6 +136,13 @@ package body Ch9 is else Task_Node := New_Node (N_Task_Body, Task_Sloc); Set_Defining_Identifier (Task_Node, Name_Node); + + -- Move the aspect specifications to the body node + + if Has_Aspects (Dummy_Node) then + Move_Aspects (From => Dummy_Node, To => Task_Node); + end if; + Parse_Decls_Begin_End (Task_Node); end if; @@ -367,12 +394,15 @@ package body Ch9 is -- is [new INTERFACE_LIST with] PROTECTED_DEFINITION; -- PROTECTED_BODY ::= - -- protected body DEFINING_IDENTIFIER is + -- protected body DEFINING_IDENTIFIER + -- [ASPECT_SPECIFICATIONS] + -- is -- {PROTECTED_OPERATION_ITEM} -- end [protected_IDENTIFIER]; -- PROTECTED_BODY_STUB ::= - -- protected body DEFINING_IDENTIFIER is separate; + -- protected body DEFINING_IDENTIFIER is separate + -- [ASPECT_SPECIFICATIONS]; -- This routine scans out a protected declaration, protected body -- or a protected stub. @@ -383,11 +413,17 @@ package body Ch9 is -- Error recovery: cannot raise Error_Resync function P_Protected return Node_Id is + Aspect_Sloc : Source_Ptr; Name_Node : Node_Id; Protected_Node : Node_Id; Protected_Sloc : Source_Ptr; Scan_State : Saved_Scan_State; + Dummy_Node : constant Node_Id := New_Node (N_Protected_Body, Token_Ptr); + -- Placeholder node used to hold legal or prematurely declared aspect + -- specifications. Depending on the context, the aspect specifications + -- may be moved to a new node. + begin Push_Scope_Stack; Scope.Table (Scope.Last).Etyp := E_Name; @@ -405,14 +441,28 @@ package body Ch9 is Discard_Junk_List (P_Known_Discriminant_Part_Opt); end if; + if Aspect_Specifications_Present then + Aspect_Sloc := Token_Ptr; + P_Aspect_Specifications (Dummy_Node, Semicolon => False); + end if; + TF_Is; -- Protected stub if Token = Tok_Separate then Scan; -- past SEPARATE + Protected_Node := New_Node (N_Protected_Body_Stub, Protected_Sloc); Set_Defining_Identifier (Protected_Node, Name_Node); + + if Has_Aspects (Dummy_Node) then + Error_Msg + ("aspect specifications must come after SEPARATE", + Aspect_Sloc); + end if; + + P_Aspect_Specifications (Protected_Node, Semicolon => False); TF_Semicolon; Pop_Scope_Stack; -- remove unused entry @@ -421,6 +471,8 @@ package body Ch9 is else Protected_Node := New_Node (N_Protected_Body, Protected_Sloc); Set_Defining_Identifier (Protected_Node, Name_Node); + + Move_Aspects (From => Dummy_Node, To => Protected_Node); Set_Declarations (Protected_Node, P_Protected_Operation_Items); End_Statements (Protected_Node); end if; @@ -800,8 +852,8 @@ package body Ch9 is -- ENTRY_DECLARATION ::= -- [OVERRIDING_INDICATOR] - -- entry DEFINING_IDENTIFIER [(DISCRETE_SUBTYPE_DEFINITION)] - -- PARAMETER_PROFILE; + -- entry DEFINING_IDENTIFIER + -- [(DISCRETE_SUBTYPE_DEFINITION)] PARAMETER_PROFILE -- [ASPECT_SPECIFICATIONS]; -- The caller has checked that the initial token is ENTRY, NOT or diff --git a/gcc/ada/par-prag.adb b/gcc/ada/par-prag.adb index 4d01db09d12..5de6ecc0081 100644 --- a/gcc/ada/par-prag.adb +++ b/gcc/ada/par-prag.adb @@ -307,6 +307,7 @@ begin when Pragma_Ada_83 => Ada_Version := Ada_83; Ada_Version_Explicit := Ada_83; + Ada_Version_Pragma := Pragma_Node; ------------ -- Ada_95 -- @@ -319,6 +320,7 @@ begin when Pragma_Ada_95 => Ada_Version := Ada_95; Ada_Version_Explicit := Ada_95; + Ada_Version_Pragma := Pragma_Node; --------------------- -- Ada_05/Ada_2005 -- @@ -333,6 +335,7 @@ begin if Arg_Count = 0 then Ada_Version := Ada_2005; Ada_Version_Explicit := Ada_2005; + Ada_Version_Pragma := Pragma_Node; end if; --------------------- @@ -348,6 +351,7 @@ begin if Arg_Count = 0 then Ada_Version := Ada_2012; Ada_Version_Explicit := Ada_2012; + Ada_Version_Pragma := Pragma_Node; end if; ----------- diff --git a/gcc/ada/prj.adb b/gcc/ada/prj.adb index 9e0e0aa38d1..b98f711c5e7 100644 --- a/gcc/ada/prj.adb +++ b/gcc/ada/prj.adb @@ -959,6 +959,7 @@ package body Prj is -- identifiers. Opt.Ada_Version := Opt.Ada_95; + Opt.Ada_Version_Pragma := Empty; Set_Name_Table_Byte (Name_Project, Token_Type'Pos (Tok_Project)); Set_Name_Table_Byte (Name_Extends, Token_Type'Pos (Tok_Extends)); diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads index f218cdc7a2b..88cd740b00a 100644 --- a/gcc/ada/rtsfind.ads +++ b/gcc/ada/rtsfind.ads @@ -278,6 +278,7 @@ package Rtsfind is System_Machine_Code, System_Mantissa, System_Memcop, + System_Memory, System_Multiprocessors, System_Pack_03, System_Pack_05, @@ -585,8 +586,8 @@ package Rtsfind is RO_RT_Delay_Until, -- Ada.Real_Time.Delays RO_RT_To_Duration, -- Ada.Real_Time.Delays - RE_Set_Handler, -- Ada_Real_Time.Timing_Events - RE_Timing_Event, -- Ada_Real_Time.Timing_Events + RE_Set_Handler, -- Ada.Real_Time.Timing_Events + RE_Timing_Event, -- Ada.Real_Time.Timing_Events RE_Root_Stream_Type, -- Ada.Streams RE_Stream_Element, -- Ada.Streams @@ -788,13 +789,13 @@ package Rtsfind is RE_Bit_Or, -- System.Bit_Ops RE_Bit_Xor, -- System.Bit_Ops - RE_Vector_Not, -- System_Boolean_Array_Operations, - RE_Vector_And, -- System_Boolean_Array_Operations, - RE_Vector_Or, -- System_Boolean_Array_Operations, - RE_Vector_Nand, -- System_Boolean_Array_Operations, - RE_Vector_Nor, -- System_Boolean_Array_Operations, - RE_Vector_Nxor, -- System_Boolean_Array_Operations, - RE_Vector_Xor, -- System_Boolean_Array_Operations, + RE_Vector_Not, -- System.Boolean_Array_Operations, + RE_Vector_And, -- System.Boolean_Array_Operations, + RE_Vector_Or, -- System.Boolean_Array_Operations, + RE_Vector_Nand, -- System.Boolean_Array_Operations, + RE_Vector_Nor, -- System.Boolean_Array_Operations, + RE_Vector_Nxor, -- System.Boolean_Array_Operations, + RE_Vector_Xor, -- System.Boolean_Array_Operations, RE_Bswap_16, -- System.Byte_Swapping RE_Bswap_32, -- System.Byte_Swapping @@ -940,7 +941,9 @@ package Rtsfind is RE_Asm_Input_Operand, -- System.Machine_Code RE_Asm_Output_Operand, -- System.Machine_Code - RE_Mantissa_Value, -- System_Mantissa + RE_Mantissa_Value, -- System.Mantissa + + RE_Free, -- System.Memory RE_CPU_Range, -- System.Multiprocessors @@ -1224,7 +1227,7 @@ package Rtsfind is RE_Get_63, -- System.Pack_63 RE_Set_63, -- System.Pack_63 - RE_Adjust_Storage_Size, -- System_Parameters + RE_Adjust_Storage_Size, -- System.Parameters RE_Default_Stack_Size, -- System.Parameters RE_Garbage_Collected, -- System.Parameters RE_Size_Type, -- System.Parameters @@ -1689,7 +1692,7 @@ package Rtsfind is RE_Width_Wide_Character, -- System.Wid_WChar RE_Width_Wide_Wide_Character, -- System.Wid_WChar - RE_Dispatching_Domain, -- Dispatching_Domains + RE_Dispatching_Domain, -- Multiprocessors.Dispatching_Domains RE_Protected_Entry_Body_Array, -- Tasking.Protected_Objects.Entries RE_Protected_Entry_Names_Array, -- Tasking.Protected_Objects.Entries @@ -1777,7 +1780,7 @@ package Rtsfind is RE_Complete_Task, -- System.Tasking.Stages RE_Free_Task, -- System.Tasking.Stages RE_Expunge_Unactivated_Tasks, -- System.Tasking.Stages - RE_Move_Activation_Chain, -- System_Tasking_Stages + RE_Move_Activation_Chain, -- System.Tasking_Stages RE_Terminated); -- System.Tasking.Stages -- The following declarations build a table that is indexed by the RTE @@ -2197,6 +2200,8 @@ package Rtsfind is RE_Mantissa_Value => System_Mantissa, + RE_Free => System_Memory, + RE_CPU_Range => System_Multiprocessors, RE_Bits_03 => System_Pack_03, diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb index f5d12ed1c7b..ae58c9d2504 100644 --- a/gcc/ada/sem_attr.adb +++ b/gcc/ada/sem_attr.adb @@ -890,13 +890,8 @@ package body Sem_Attr is procedure Check_Ada_2012_Attribute is begin - if Ada_Version < Ada_2012 then - Error_Msg_Name_1 := Aname; - Error_Msg_N - ("attribute % is an Ada 2012 feature", N); - Error_Msg_N - ("\unit must be compiled with -gnat2012 switch", N); - end if; + Error_Msg_Name_1 := Aname; + Error_Msg_Ada_2012_Feature ("attribute %", Sloc (N)); end Check_Ada_2012_Attribute; -------------------------------- diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb index 87d2ab3c259..6c36bf2cdb7 100644 --- a/gcc/ada/sem_ch10.adb +++ b/gcc/ada/sem_ch10.adb @@ -23,6 +23,7 @@ -- -- ------------------------------------------------------------------------------ +with Aspects; use Aspects; with Atree; use Atree; with Debug; use Debug; with Einfo; use Einfo; @@ -1555,8 +1556,8 @@ package body Sem_Ch10 is ------------------------------- procedure Analyze_Package_Body_Stub (N : Node_Id) is - Id : constant Entity_Id := Defining_Identifier (N); - Nam : Entity_Id; + Id : constant Entity_Id := Defining_Identifier (N); + Nam : Entity_Id; begin -- The package declaration must be in the current declarative part @@ -1844,6 +1845,12 @@ package body Sem_Ch10 is SCO_Record (Unum); end if; + -- Propagate any aspect specifications associated with + -- with the stub to the proper body. + + Move_Or_Merge_Aspects + (From => N, To => Proper_Body (Unit (Comp_Unit))); + -- Analyze the unit if semantics active if not Fatal_Error (Unum) or else Try_Semantics then @@ -2327,8 +2334,8 @@ package body Sem_Ch10 is ---------------------------- procedure Analyze_Task_Body_Stub (N : Node_Id) is - Nam : Entity_Id := Current_Entity_In_Scope (Defining_Identifier (N)); Loc : constant Source_Ptr := Sloc (N); + Nam : Entity_Id := Current_Entity_In_Scope (Defining_Identifier (N)); begin Check_Stub_Level (N); diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb index b93d3858335..035d0b0bfda 100644 --- a/gcc/ada/sem_ch12.adb +++ b/gcc/ada/sem_ch12.adb @@ -76,6 +76,7 @@ with Table; with Tbuild; use Tbuild; with Uintp; use Uintp; with Urealp; use Urealp; +with Warnsw; use Warnsw; with GNAT.HTable; @@ -3592,8 +3593,8 @@ package body Sem_Ch12 is Append (Unit_Renaming, Renaming_List); - -- The renaming declarations are the first local declarations of - -- the new unit. + -- The renaming declarations are the first local declarations of the + -- new unit. if Is_Non_Empty_List (Visible_Declarations (Act_Spec)) then Insert_List_Before @@ -3894,7 +3895,9 @@ package body Sem_Ch12 is Current_Sem_Unit => Current_Sem_Unit, Scope_Suppress => Scope_Suppress, Local_Suppress_Stack_Top => Local_Suppress_Stack_Top, - Version => Ada_Version)); + Version => Ada_Version, + Version_Pragma => Ada_Version_Pragma, + Warnings => Save_Warnings)); end if; end if; @@ -3940,6 +3943,15 @@ package body Sem_Ch12 is Set_Unit (Parent (N), Act_Decl); Set_Parent_Spec (Act_Decl, Parent_Spec (N)); Set_Package_Instantiation (Act_Decl_Id, N); + + -- Process aspect specifications of the instance node, if any, to + -- take into account categorization pragmas before analyzing the + -- instance. + + if Has_Aspects (N) then + Analyze_Aspect_Specifications (N, Act_Decl_Id); + end if; + Analyze (Act_Decl); Set_Unit (Parent (N), N); Set_Body_Required (Parent (N), False); @@ -4043,7 +4055,7 @@ package body Sem_Ch12 is end if; <<Leave>> - if Has_Aspects (N) then + if Has_Aspects (N) and then Nkind (Parent (N)) /= N_Compilation_Unit then Analyze_Aspect_Specifications (N, Act_Decl_Id); end if; @@ -4229,7 +4241,9 @@ package body Sem_Ch12 is Current_Sem_Unit => Current_Sem_Unit, Scope_Suppress => Scope_Suppress, Local_Suppress_Stack_Top => Local_Suppress_Stack_Top, - Version => Ada_Version)), + Version => Ada_Version, + Version_Pragma => Ada_Version_Pragma, + Warnings => Save_Warnings)), Inlined_Body => True); Pop_Scope; @@ -4309,8 +4323,8 @@ package body Sem_Ch12 is end loop; end if; - -- Restore status of instances. If one of them is a body, make - -- its local entities visible again. + -- Restore status of instances. If one of them is a body, make its + -- local entities visible again. declare E : Entity_Id; @@ -4345,7 +4359,9 @@ package body Sem_Ch12 is Current_Sem_Unit => Current_Sem_Unit, Scope_Suppress => Scope_Suppress, Local_Suppress_Stack_Top => Local_Suppress_Stack_Top, - Version => Ada_Version)), + Version => Ada_Version, + Version_Pragma => Ada_Version_Pragma, + Warnings => Save_Warnings)), Inlined_Body => True); end if; end Inline_Instance_Body; @@ -4401,7 +4417,9 @@ package body Sem_Ch12 is Current_Sem_Unit => Current_Sem_Unit, Scope_Suppress => Scope_Suppress, Local_Suppress_Stack_Top => Local_Suppress_Stack_Top, - Version => Ada_Version)); + Version => Ada_Version, + Version_Pragma => Ada_Version_Pragma, + Warnings => Save_Warnings)); return True; -- Here if not inlined, or we ignore the inlining @@ -4855,7 +4873,6 @@ package body Sem_Ch12 is -- subsequent construction of the body. if Need_Subprogram_Instance_Body (N, Act_Decl_Id) then - Check_Forward_Instantiation (Gen_Decl); -- The wrapper package is always delayed, because it does not @@ -9901,6 +9918,8 @@ package body Sem_Ch12 is Local_Suppress_Stack_Top := Body_Info.Local_Suppress_Stack_Top; Scope_Suppress := Body_Info.Scope_Suppress; Opt.Ada_Version := Body_Info.Version; + Opt.Ada_Version_Pragma := Body_Info.Version_Pragma; + Restore_Warnings (Body_Info.Warnings); if No (Gen_Body_Id) then Load_Parent_Of_Generic @@ -10161,7 +10180,9 @@ package body Sem_Ch12 is Unit_Renaming : Node_Id; Parent_Installed : Boolean := False; - Save_Style_Check : constant Boolean := Style_Check; + + Saved_Style_Check : constant Boolean := Style_Check; + Saved_Warnings : constant Warning_Record := Save_Warnings; Par_Ent : Entity_Id := Empty; Par_Vis : Boolean := False; @@ -10187,6 +10208,8 @@ package body Sem_Ch12 is Local_Suppress_Stack_Top := Body_Info.Local_Suppress_Stack_Top; Scope_Suppress := Body_Info.Scope_Suppress; Opt.Ada_Version := Body_Info.Version; + Opt.Ada_Version_Pragma := Body_Info.Version_Pragma; + Restore_Warnings (Body_Info.Warnings); if No (Gen_Body_Id) then @@ -10366,7 +10389,8 @@ package body Sem_Ch12 is end if; Restore_Env; - Style_Check := Save_Style_Check; + Style_Check := Saved_Style_Check; + Restore_Warnings (Saved_Warnings); -- Body not found. Error was emitted already. If there were no previous -- errors, this may be an instance whose scope is a premature instance. @@ -10917,9 +10941,7 @@ package body Sem_Ch12 is -- Ada 2005 (AI-251) - if Ada_Version >= Ada_2005 - and then Is_Interface (Ancestor) - then + if Ada_Version >= Ada_2005 and then Is_Interface (Ancestor) then if not Interface_Present_In_Ancestor (Act_T, Ancestor) then Error_Msg_NE ("(Ada 2005) expected type implementing & in instantiation", @@ -11849,7 +11871,8 @@ package body Sem_Ch12 is Body_Optional : Boolean := False) is Comp_Unit : constant Node_Id := Cunit (Get_Source_Unit (Spec)); - Save_Style_Check : constant Boolean := Style_Check; + Saved_Style_Check : constant Boolean := Style_Check; + Saved_Warnings : constant Warning_Record := Save_Warnings; True_Parent : Node_Id; Inst_Node : Node_Id; OK : Boolean; @@ -12083,7 +12106,9 @@ package body Sem_Ch12 is Scope_Suppress => Scope_Suppress, Local_Suppress_Stack_Top => Local_Suppress_Stack_Top, - Version => Ada_Version); + Version => Ada_Version, + Version_Pragma => Ada_Version_Pragma, + Warnings => Save_Warnings); -- Package instance @@ -12119,12 +12144,13 @@ package body Sem_Ch12 is ((Inst_Node => Inst_Node, Act_Decl => True_Parent, Expander_Status => Exp_Status, - Current_Sem_Unit => - Get_Code_Unit (Sloc (Inst_Node)), + Current_Sem_Unit => Get_Code_Unit + (Sloc (Inst_Node)), Scope_Suppress => Scope_Suppress, - Local_Suppress_Stack_Top => - Local_Suppress_Stack_Top, - Version => Ada_Version)), + Local_Suppress_Stack_Top => Local_Suppress_Stack_Top, + Version => Ada_Version, + Version_Pragma => Ada_Version_Pragma, + Warnings => Save_Warnings)), Body_Optional => Body_Optional); end; end if; @@ -12135,7 +12161,8 @@ package body Sem_Ch12 is Opt.Style_Check := False; Expander_Mode_Save_And_Set (True); Load_Needed_Body (Comp_Unit, OK); - Opt.Style_Check := Save_Style_Check; + Opt.Style_Check := Saved_Style_Check; + Restore_Warnings (Saved_Warnings); Expander_Mode_Restore; if not OK diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb index 37fd72253d6..37b9e9a82b9 100644 --- a/gcc/ada/sem_ch13.adb +++ b/gcc/ada/sem_ch13.adb @@ -694,6 +694,29 @@ package body Sem_Ch13 is -- This routine analyzes an Aspect_Default_[Component_]Value denoted by -- the aspect specification node ASN. + procedure Inherit_Delayed_Rep_Aspects (ASN : Node_Id); + -- As discussed in the spec of Aspects (see Aspect_Delay declaration), + -- a derived type can inherit aspects from its parent which have been + -- specified at the time of the derivation using an aspect, as in: + -- + -- type A is range 1 .. 10 + -- with Size => Not_Defined_Yet; + -- .. + -- type B is new A; + -- .. + -- Not_Defined_Yet : constant := 64; + -- + -- In this example, the Size of A is considered to be specified prior + -- to the derivation, and thus inherited, even though the value is not + -- known at the time of derivation. To deal with this, we use two entity + -- flags. The flag Has_Derived_Rep_Aspects is set in the parent type (A + -- here), and then the flag May_Inherit_Delayed_Rep_Aspects is set in + -- the derived type (B here). If this flag is set when the derived type + -- is frozen, then this procedure is called to ensure proper inheritance + -- of all delayed aspects from the parent type. The derived type is E, + -- the argument to Analyze_Aspects_At_Freeze_Point. ASN is the first + -- aspect specification node in the Rep_Item chain for the parent type. + procedure Make_Pragma_From_Boolean_Aspect (ASN : Node_Id); -- Given an aspect specification node ASN whose expression is an -- optional Boolean, this routines creates the corresponding pragma @@ -753,6 +776,181 @@ package body Sem_Ch13 is end if; end Analyze_Aspect_Default_Value; + --------------------------------- + -- Inherit_Delayed_Rep_Aspects -- + --------------------------------- + + procedure Inherit_Delayed_Rep_Aspects (ASN : Node_Id) is + P : constant Entity_Id := Entity (ASN); + -- Entithy for parent type + + N : Node_Id; + -- Item from Rep_Item chain + + A : Aspect_Id; + + begin + -- Loop through delayed aspects for the parent type + + N := ASN; + while Present (N) loop + if Nkind (N) = N_Aspect_Specification then + exit when Entity (N) /= P; + + if Is_Delayed_Aspect (N) then + A := Get_Aspect_Id (Chars (Identifier (N))); + + -- Process delayed rep aspect. For Boolean attributes it is + -- not possible to cancel an attribute once set (the attempt + -- to use an aspect with xxx => False is an error) for a + -- derived type. So for those cases, we do not have to check + -- if a clause has been given for the derived type, since it + -- is harmless to set it again if it is already set. + + case A is + + -- Alignment + + when Aspect_Alignment => + if not Has_Alignment_Clause (E) then + Set_Alignment (E, Alignment (P)); + end if; + + -- Atomic + + when Aspect_Atomic => + if Is_Atomic (P) then + Set_Is_Atomic (E); + end if; + + -- Atomic_Components + + when Aspect_Atomic_Components => + if Has_Atomic_Components (P) then + Set_Has_Atomic_Components (Base_Type (E)); + end if; + + -- Bit_Order + + when Aspect_Bit_Order => + if Is_Record_Type (E) + and then No (Get_Attribute_Definition_Clause + (E, Attribute_Bit_Order)) + and then Reverse_Bit_Order (P) + then + Set_Reverse_Bit_Order (Base_Type (E)); + end if; + + -- Component_Size + + when Aspect_Component_Size => + if Is_Array_Type (E) + and then not Has_Component_Size_Clause (E) + then + Set_Component_Size + (Base_Type (E), Component_Size (P)); + end if; + + -- Machine_Radix + + when Aspect_Machine_Radix => + if Is_Decimal_Fixed_Point_Type (E) + and then not Has_Machine_Radix_Clause (E) + then + Set_Machine_Radix_10 (E, Machine_Radix_10 (P)); + end if; + + -- Object_Size (also Size which also sets Object_Size) + + when Aspect_Object_Size | Aspect_Size => + if not Has_Size_Clause (E) + and then + No (Get_Attribute_Definition_Clause + (E, Attribute_Object_Size)) + then + Set_Esize (E, Esize (P)); + end if; + + -- Pack + + when Aspect_Pack => + if not Is_Packed (E) then + Set_Is_Packed (Base_Type (E)); + + if Is_Bit_Packed_Array (P) then + Set_Is_Bit_Packed_Array (Base_Type (E)); + Set_Packed_Array_Type (E, Packed_Array_Type (P)); + end if; + end if; + + -- Scalar_Storage_Order + + when Aspect_Scalar_Storage_Order => + if (Is_Record_Type (E) or else Is_Array_Type (E)) + and then No (Get_Attribute_Definition_Clause + (E, Attribute_Scalar_Storage_Order)) + and then Reverse_Storage_Order (P) + then + Set_Reverse_Storage_Order (Base_Type (E)); + end if; + + -- Small + + when Aspect_Small => + if Is_Fixed_Point_Type (E) + and then not Has_Small_Clause (E) + then + Set_Small_Value (E, Small_Value (P)); + end if; + + -- Storage_Size + + when Aspect_Storage_Size => + if (Is_Access_Type (E) or else Is_Task_Type (E)) + and then not Has_Storage_Size_Clause (E) + then + Set_Storage_Size_Variable + (Base_Type (E), Storage_Size_Variable (P)); + end if; + + -- Value_Size + + when Aspect_Value_Size => + + -- Value_Size is never inherited, it is either set by + -- default, or it is explicitly set for the derived + -- type. So nothing to do here. + + null; + + -- Volatile + + when Aspect_Volatile => + if Is_Volatile (P) then + Set_Is_Volatile (E); + end if; + + -- Volatile_Components + + when Aspect_Volatile_Components => + if Has_Volatile_Components (P) then + Set_Has_Volatile_Components (Base_Type (E)); + end if; + + -- That should be all the Rep Aspects + + when others => + pragma Assert (Aspect_Delay (A_Id) /= Rep_Aspect); + null; + + end case; + end if; + end if; + + N := Next_Rep_Item (N); + end loop; + end Inherit_Delayed_Rep_Aspects; + ------------------------------------- -- Make_Pragma_From_Boolean_Aspect -- ------------------------------------- @@ -831,15 +1029,18 @@ package body Sem_Ch13 is -- Fall through means we are canceling an inherited aspect Error_Msg_Name_1 := A_Name; - Error_Msg_NE ("derived type& inherits aspect%, cannot cancel", - Expr, - E); + Error_Msg_NE + ("derived type& inherits aspect%, cannot cancel", Expr, E); end Check_False_Aspect_For_Derived_Type; -- Start of processing for Make_Pragma_From_Boolean_Aspect begin + -- Note that we know Expr is present, because for a missing Expr + -- argument, we knew it was True and did not need to delay the + -- evaluation to the freeze point. + if Is_False (Static_Boolean (Expr)) then Check_False_Aspect_For_Derived_Type; @@ -874,30 +1075,30 @@ package body Sem_Ch13 is ASN := First_Rep_Item (E); while Present (ASN) loop - if Nkind (ASN) = N_Aspect_Specification - and then Entity (ASN) = E - and then Is_Delayed_Aspect (ASN) - then - A_Id := Get_Aspect_Id (ASN); + if Nkind (ASN) = N_Aspect_Specification then + exit when Entity (ASN) /= E; - case A_Id is + if Is_Delayed_Aspect (ASN) then + A_Id := Get_Aspect_Id (ASN); - -- For aspects whose expression is an optional Boolean, make - -- the corresponding pragma at the freezing point. + case A_Id is + + -- For aspects whose expression is an optional Boolean, make + -- the corresponding pragma at the freezing point. when Boolean_Aspects | Library_Unit_Aspects => Make_Pragma_From_Boolean_Aspect (ASN); - -- Special handling for aspects that don't correspond to - -- pragmas/attributes. + -- Special handling for aspects that don't correspond to + -- pragmas/attributes. when Aspect_Default_Value | Aspect_Default_Component_Value => Analyze_Aspect_Default_Value (ASN); - -- Ditto for iterator aspects, because the corresponding - -- attributes may not have been analyzed yet. + -- Ditto for iterator aspects, because the corresponding + -- attributes may not have been analyzed yet. when Aspect_Constant_Indexing | Aspect_Variable_Indexing | @@ -907,17 +1108,27 @@ package body Sem_Ch13 is when others => null; - end case; + end case; - Ritem := Aspect_Rep_Item (ASN); + Ritem := Aspect_Rep_Item (ASN); - if Present (Ritem) then - Analyze (Ritem); + if Present (Ritem) then + Analyze (Ritem); + end if; end if; end if; Next_Rep_Item (ASN); end loop; + + -- This is where we inherit delayed rep aspects from our parent. Note + -- that if we fell out of the above loop with ASN non-empty, it means + -- we hit an aspect for an entity other than E, and it must be the + -- type from which we were derived. + + if May_Inherit_Delayed_Rep_Aspects (E) then + Inherit_Delayed_Rep_Aspects (ASN); + end if; end Analyze_Aspects_At_Freeze_Point; ----------------------------------- @@ -1046,7 +1257,7 @@ package body Sem_Ch13 is A_Id : constant Aspect_Id := Get_Aspect_Id (Nam); Anod : Node_Id; - Delay_Required : Boolean := True; + Delay_Required : Boolean; -- Set False if delay is not required Eloc : Source_Ptr := No_Location; @@ -1146,17 +1357,26 @@ package body Sem_Ch13 is (Pragma_Argument_Associations : List_Id; Pragma_Name : Name_Id) is + Args : List_Id := Pragma_Argument_Associations; + begin -- We should never get here if aspect was disabled pragma Assert (not Is_Disabled (Aspect)); + -- Certan aspects allow for an optional name or expression. Do + -- not generate a pragma with an empty argument association + -- list. + + if No (Args) or else No (Expression (First (Args))) then + Args := No_List; + end if; + -- Build the pragma Aitem := Make_Pragma (Loc, - Pragma_Argument_Associations => - Pragma_Argument_Associations, + Pragma_Argument_Associations => Args, Pragma_Identifier => Make_Identifier (Sloc (Id), Pragma_Name), Class_Present => Class_Present (Aspect), @@ -1166,6 +1386,8 @@ package body Sem_Ch13 is if Is_Ignored (Aspect) then Set_Is_Ignored (Aitem); + elsif Is_Checked (Aspect) then + Set_Is_Checked (Aitem); end if; Set_Corresponding_Aspect (Aitem, Aspect); @@ -1183,7 +1405,7 @@ package body Sem_Ch13 is -- Skip looking at aspect if it is totally disabled. Just mark -- it as such for later reference in the tree. This also sets - -- the Is_Ignored flag appropriately. + -- the Is_Ignored and Is_Checked flags appropriately. Check_Applicable_Policy (Aspect); @@ -1279,6 +1501,31 @@ package body Sem_Ch13 is Set_Entity (Id, New_Copy_Tree (Expr)); + -- Set Delay_Required as appropriate to aspect + + case Aspect_Delay (A_Id) is + when Always_Delay => + Delay_Required := True; + + when Never_Delay => + Delay_Required := False; + + when Rep_Aspect => + + -- If expression has the form of an integer literal, then + -- do not delay, since we know the value cannot change. + -- This optimization catches most rep clause cases. + + if (Present (Expr) and then Nkind (Expr) = N_Integer_Literal) + or else (A_Id in Boolean_Aspects and then No (Expr)) + then + Delay_Required := False; + else + Delay_Required := True; + Set_Has_Delayed_Rep_Aspects (E); + end if; + end case; + -- Processing based on specific aspect case A_Id is @@ -1318,7 +1565,8 @@ package body Sem_Ch13 is -- Indexing aspects apply only to tagged type if (A_Id = Aspect_Constant_Indexing - or else A_Id = Aspect_Variable_Indexing) + or else + A_Id = Aspect_Variable_Indexing) and then not (Is_Type (E) and then Is_Tagged_Type (E)) then @@ -1378,12 +1626,6 @@ package body Sem_Ch13 is Expression => Relocate_Node (Expr))), Pragma_Name => Name_Implemented); - -- No delay is required since the only values are: By_Entry - -- | By_Protected_Procedure | By_Any | Optional which don't - -- get analyzed anyway. - - Delay_Required := False; - -- Attach Handler when Aspect_Attach_Handler => @@ -1518,11 +1760,6 @@ package body Sem_Ch13 is Make_Aitem_Pragma (Pragma_Argument_Associations => Arg_List, Pragma_Name => P_Name); - - -- Convention is a static name, and must be associated - -- with the entity at once. - - Delay_Required := False; end; -- CPU, Interrupt_Priority, Priority @@ -1553,7 +1790,6 @@ package body Sem_Ch13 is -- Warnings when Aspect_Warnings => - Make_Aitem_Pragma (Pragma_Argument_Associations => New_List ( Make_Pragma_Argument_Association (Sloc (Expr), @@ -1562,11 +1798,6 @@ package body Sem_Ch13 is Expression => New_Occurrence_Of (E, Loc))), Pragma_Name => Chars (Id)); - -- We don't have to play the delay game here, since the only - -- values are ON/OFF which don't get analyzed anyway. - - Delay_Required := False; - -- Case 2c: Aspects corresponding to pragmas with three -- arguments. @@ -1620,7 +1851,6 @@ package body Sem_Ch13 is Make_Pragma_Argument_Association (Loc, Expression => Relocate_Node (Expr))), Pragma_Name => Name_Abstract_State); - Delay_Required := False; -- Depends @@ -1666,7 +1896,6 @@ package body Sem_Ch13 is Make_Pragma_Argument_Association (Loc, Expression => Relocate_Node (Expr))), Pragma_Name => Name_SPARK_Mode); - Delay_Required := False; -- Relative_Deadline @@ -1910,8 +2139,6 @@ package body Sem_Ch13 is Make_Aitem_Pragma (Pragma_Argument_Associations => Args, Pragma_Name => Nam); - - Delay_Required := False; end Test_Case; -- Contract_Cases @@ -1950,9 +2177,9 @@ package body Sem_Ch13 is else -- Set the Uses_Lock_Free flag to True if there is no - -- expression or if the expression is True. ??? The + -- expression or if the expression is True. The -- evaluation of this aspect should be delayed to the - -- freeze point. + -- freeze point (why???) if No (Expr) or else Is_True (Static_Boolean (Expr)) @@ -1984,17 +2211,17 @@ package body Sem_Ch13 is if No (A) then Error_Msg_N ("missing Convention aspect for Export/Import", - Aspect); + Aspect); end if; end; goto Continue; end if; - -- This requires special handling in the case of a package - -- declaration, the pragma needs to be inserted in the list - -- of declarations for the associated package. There is no - -- issue of visibility delay for these aspects. + -- Library unit aspects require special handling in the case + -- of a package declaration, the pragma needs to be inserted + -- in the list of declarations for the associated package. + -- There is no issue of visibility delay for these aspects. if A_Id in Library_Unit_Aspects and then @@ -2007,22 +2234,20 @@ package body Sem_Ch13 is goto Continue; end if; - -- Special handling when the aspect has no expression. In - -- this case the value is considered to be True. Thus, we - -- simply insert the pragma, no delay is required. + -- Cases where we do not delay, includes all cases where + -- the expression is missing other than the above cases. - if No (Expr) then + if not Delay_Required or else No (Expr) then Make_Aitem_Pragma (Pragma_Argument_Associations => New_List ( Make_Pragma_Argument_Association (Sloc (Ent), Expression => Ent)), Pragma_Name => Chars (Id)); - Delay_Required := False; -- In general cases, the corresponding pragma/attribute -- definition clause will be inserted later at the freezing - -- point. + -- point, and we do not need to build it now else Aitem := Empty; @@ -2112,7 +2337,8 @@ package body Sem_Ch13 is -- node (no delay is required here) except for aspects on a -- subprogram body (see below) and a generic package, for which -- we need to introduce the pragma before building the generic - -- copy (see sem_ch12). + -- copy (see sem_ch12), and for package instantiations, where + -- the library unit pragmas are better handled early. elsif Nkind (Parent (N)) = N_Compilation_Unit and then (Present (Aitem) or else Is_Boolean_Aspect (Aspect)) @@ -2161,6 +2387,18 @@ package body Sem_Ch13 is Prepend (Aitem, Visible_Declarations (Specification (N))); + elsif Nkind (N) = N_Package_Instantiation then + declare + Spec : constant Node_Id := + Specification (Instance_Spec (N)); + begin + if No (Visible_Declarations (Spec)) then + Set_Visible_Declarations (Spec, New_List); + end if; + + Prepend (Aitem, Visible_Declarations (Spec)); + end; + else if No (Pragmas_After (Aux)) then Set_Pragmas_After (Aux, New_List); @@ -2175,8 +2413,7 @@ package body Sem_Ch13 is -- The evaluation of the aspect is delayed to the freezing point. -- The pragma or attribute clause if there is one is then attached - -- to the aspect specification which is placed in the rep item - -- list. + -- to the aspect specification which is put in the rep item list. if Delay_Required then if Present (Aitem) then @@ -2205,6 +2442,18 @@ package body Sem_Ch13 is Set_Has_Delayed_Aspects (E); Record_Rep_Item (E, Aspect); + -- When delay is not required and the context is a package or a + -- subprogram body, insert the pragma in the body declarations. + + elsif Nkind_In (N, N_Package_Body, N_Subprogram_Body) then + if No (Declarations (N)) then + Set_Declarations (N, New_List); + end if; + + -- The pragma is added before source declarations + + Prepend_To (Declarations (N), Aitem); + -- When delay is not required and the context is not a compilation -- unit, we simply insert the pragma/attribute definition clause -- in sequence. @@ -7327,6 +7576,7 @@ package body Sem_Ch13 is when Boolean_Aspects | Library_Unit_Aspects => + T := Standard_Boolean; -- Aspects corresponding to attribute definition clauses @@ -8712,6 +8962,7 @@ package body Sem_Ch13 is ------------------------------------- procedure Inherit_Aspects_At_Freeze_Point (Typ : Entity_Id) is + function Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item (Rep_Item : Node_Id) return Boolean; -- This routine checks if Rep_Item is either a pragma or an aspect diff --git a/gcc/ada/sem_ch13.ads b/gcc/ada/sem_ch13.ads index 611f3f1c617..0d95174c14a 100644 --- a/gcc/ada/sem_ch13.ads +++ b/gcc/ada/sem_ch13.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2012, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -305,10 +305,12 @@ package Sem_Ch13 is -- in these two expressions are the same, by seeing if the two expressions -- are fully conformant, and if not, issue appropriate error messages. - -- Quite an awkward procedure, but this is an awkard requirement! + -- Quite an awkward approach, but this is an awkard requirement! procedure Analyze_Aspects_At_Freeze_Point (E : Entity_Id); - -- Analyze all the delayed aspects for entity E at freezing point + -- Analyze all the delayed aspects for entity E at freezing point. This + -- includes dealing with inheriting delayed aspects from the parent type + -- in the case where a derived type is frozen. procedure Check_Aspect_At_Freeze_Point (ASN : Node_Id); -- Performs the processing described above at the freeze point, ASN is the diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index f07f083463a..ea41423b46f 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -169,15 +169,15 @@ package body Sem_Ch3 is Parent_Type : Entity_Id; Derived_Type : Entity_Id; Derive_Subps : Boolean := True); - -- Subsidiary procedure for Build_Derived_Type and - -- Analyze_Private_Extension_Declaration used for tagged and untagged - -- record types. All parameters are as in Build_Derived_Type except that - -- N, in addition to being an N_Full_Type_Declaration node, can also be an + -- Subsidiary procedure used for tagged and untagged record types + -- by Build_Derived_Type and Analyze_Private_Extension_Declaration. + -- All parameters are as in Build_Derived_Type except that N, in + -- addition to being an N_Full_Type_Declaration node, can also be an -- N_Private_Extension_Declaration node. See the definition of this routine - -- for much more info. Derive_Subps indicates whether subprograms should - -- be derived from the parent type. The only case where Derive_Subps is - -- False is for an implicit derived full type for a type derived from a - -- private type (see Build_Derived_Type). + -- for much more info. Derive_Subps indicates whether subprograms should be + -- derived from the parent type. The only case where Derive_Subps is False + -- is for an implicit derived full type for a type derived from a private + -- type (see Build_Derived_Type). procedure Build_Discriminal (Discrim : Entity_Id); -- Create the discriminal corresponding to discriminant Discrim, that is @@ -1256,6 +1256,11 @@ package body Sem_Ch3 is end loop; end if; + -- Check whether an indirect call without actuals may be possible. This + -- is used when resolving calls whose result is then indexed. + + May_Need_Actuals (Desig_Type); + -- If the return type is incomplete, this is legal as long as the type -- is declared in the current scope and will be completed in it (rather -- than being part of limited view). @@ -5087,11 +5092,25 @@ package body Sem_Ch3 is Process_Formals (Parameter_Specifications (Spec), Spec); if Nkind (Spec) = N_Access_Function_Definition then - if Nkind (Result_Definition (Spec)) = N_Access_Definition then - Find_Type (Subtype_Mark (Result_Definition (Spec))); - else - Find_Type (Result_Definition (Spec)); - end if; + declare + Def : constant Node_Id := Result_Definition (Spec); + + begin + -- The result might itself be an anonymous access type, so + -- have to recurse. + + if Nkind (Def) = N_Access_Definition then + if Present (Access_To_Subprogram_Definition (Def)) then + Set_Etype (Def, + Replace_Anonymous_Access_To_Protected_Subprogram + (Spec)); + else + Find_Type (Subtype_Mark (Def)); + end if; + else + Find_Type (Def); + end if; + end; end if; End_Scope; @@ -6102,13 +6121,18 @@ package body Sem_Ch3 is -- affect anything, but it is still baffling that we cannot use the -- same mechanism for all derived numeric types. - -- There is a further complication: actually *some* representation - -- clauses can affect the implicit base type. Namely, attribute + -- There is a further complication: actually some representation + -- clauses can affect the implicit base type. For example, attribute -- definition clauses for stream-oriented attributes need to set the - -- corresponding TSS entries on the base type, and this normally cannot - -- be done after the base type is frozen, so the circuitry in - -- Sem_Ch13.New_Stream_Subprogram must account for this possibility and - -- not use Set_TSS in this case. + -- corresponding TSS entries on the base type, and this normally + -- cannot be done after the base type is frozen, so the circuitry in + -- Sem_Ch13.New_Stream_Subprogram must account for this possibility + -- and not use Set_TSS in this case. + + -- There are also consequences for the case of delayed representation + -- aspects for some cases. For example, a Size aspect is delayed and + -- should not be evaluated to the freeze point. This early freezing + -- means that the size attribute evaluation happens too early??? if Is_Fixed_Point_Type (Parent_Type) then Conditional_Delay (Implicit_Base, Parent_Type); @@ -8179,6 +8203,15 @@ package body Sem_Ch3 is Set_First_Rep_Item (Derived_Type, First_Rep_Item (Parent_Type)); end if; + -- If the parent type has delayed rep aspects, then mark the derived + -- type as possibly inheriting a delayed rep aspect. + + if Has_Delayed_Rep_Aspects (Parent_Type) then + Set_May_Inherit_Delayed_Rep_Aspects (Derived_Type); + end if; + + -- Type dependent processing + case Ekind (Parent_Type) is when Numeric_Kind => Build_Derived_Numeric_Type (N, Parent_Type, Derived_Type); @@ -8221,6 +8254,8 @@ package body Sem_Ch3 is raise Program_Error; end case; + -- Nothing more to do if some error occurred + if Etype (Derived_Type) = Any_Type then return; end if; @@ -8230,6 +8265,7 @@ package body Sem_Ch3 is -- if necessary. Set_Has_Delayed_Freeze (Derived_Type); + if Derive_Subps then Derive_Subprograms (Parent_Type, Derived_Type); end if; @@ -19021,6 +19057,27 @@ package body Sem_Ch3 is case Ekind (Base_Type (Subtype_Mark_Id)) is when Access_Kind => + + -- If this is a constraint on a class-wide type, discard it. + -- There is currently no way to express a partial discriminant + -- constraint on a type with unknown discriminants. This is + -- a pathology that the ACATS wisely decides not to test. + + if Is_Class_Wide_Type (Designated_Type (Subtype_Mark_Id)) then + if Comes_From_Source (S) then + Error_Msg_N + ("constraint on class-wide type ignored?", + Constraint (S)); + end if; + + if Nkind (P) = N_Subtype_Declaration then + Set_Subtype_Indication (P, + New_Occurrence_Of (Subtype_Mark_Id, Sloc (S))); + end if; + + return Subtype_Mark_Id; + end if; + Constrain_Access (Def_Id, S, Related_Nod); if Expander_Active diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb index a03c46552be..c4247cd403d 100644 --- a/gcc/ada/sem_ch4.adb +++ b/gcc/ada/sem_ch4.adb @@ -1037,6 +1037,9 @@ package body Sem_Ch4 is -- function that returns a pointer_to_procedure which is the entity -- being called. Finally, F (X) may be a call to a parameterless -- function that returns a pointer to a function with parameters. + -- Note that if F returns an access-to-subprogram whose designated + -- type is an array, F (X) cannot be interpreted as an indirect call + -- through the result of the call to F. elsif Is_Access_Type (Etype (Nam)) and then Ekind (Designated_Type (Etype (Nam))) = E_Subprogram_Type @@ -1047,6 +1050,8 @@ package body Sem_Ch4 is (Nkind (Parent (N)) /= N_Explicit_Dereference and then Is_Entity_Name (Nam) and then No (First_Formal (Entity (Nam))) + and then not + Is_Array_Type (Etype (Designated_Type (Etype (Nam)))) and then Present (Actuals))) then Nam_Ent := Designated_Type (Etype (Nam)); @@ -2998,7 +3003,9 @@ package body Sem_Ch4 is return; end if; - -- An indexing requires at least one actual + -- An indexing requires at least one actual. The name of the call cannot + -- be an implicit indirect call, so it cannot be a generated explicit + -- dereference. if not Is_Empty_List (Actuals) and then @@ -3007,7 +3014,11 @@ package body Sem_Ch4 is (Needs_One_Actual (Nam) and then Present (Next_Actual (First (Actuals))))) then - if Is_Array_Type (Subp_Type) then + if Is_Array_Type (Subp_Type) + and then + (Nkind (Name (N)) /= N_Explicit_Dereference + or else Comes_From_Source (Name (N))) + then Is_Indexed := Try_Indexed_Call (N, Nam, Subp_Type, Must_Skip); elsif Is_Access_Type (Subp_Type) @@ -3046,9 +3057,14 @@ package body Sem_Ch4 is if not Norm_OK then -- If an indirect call is a possible interpretation, indicate - -- success to the caller. + -- success to the caller. This may be an indexing of an explicit + -- dereference of a call that returns an access type (see above). - if Is_Indirect then + if Is_Indirect + or else (Is_Indexed + and then Nkind (Name (N)) = N_Explicit_Dereference + and then Comes_From_Source (Name (N))) + then Success := True; return; diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index 57712d83d9c..7913d362f1e 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -23,6 +23,7 @@ -- -- ------------------------------------------------------------------------------ +with Aspects; use Aspects; with Atree; use Atree; with Checks; use Checks; with Debug; use Debug; @@ -211,10 +212,6 @@ package body Sem_Ch6 is -- Create the declaration for an inequality operator that is implicitly -- created by a user-defined equality operator that yields a boolean. - procedure May_Need_Actuals (Fun : Entity_Id); - -- Flag functions that can be called without parameters, i.e. those that - -- have no parameters, or those for which defaults exist for all parameters - procedure Process_PPCs (N : Node_Id; Spec_Id : Entity_Id; @@ -2675,12 +2672,17 @@ package body Sem_Ch6 is end if; end if; - -- Ada 2012 aspects may appear in a subprogram body, but only if there - -- is no previous spec. Ditto for a subprogram stub that does not have - -- a corresponding spec, but for which there may also be a spec_id. + -- Language-defined aspects cannot appear in a subprogram body if the + -- corresponding spec already has aspects. Exception to this rule are + -- certain user-defined aspects. Aspects that apply to a body stub are + -- moved to the proper body. Do not emit an error in this case. if Has_Aspects (N) then - if Present (Spec_Id) then + if Present (Spec_Id) + and then Nkind (N) not in N_Body_Stub + and then Nkind (Parent (N)) /= N_Subunit + and then not Aspects_On_Body_OK (N) + then Error_Msg_N ("aspect specifications must appear in subprogram declaration", N); diff --git a/gcc/ada/sem_ch6.ads b/gcc/ada/sem_ch6.ads index 0799adc1849..d967c017ae0 100644 --- a/gcc/ada/sem_ch6.ads +++ b/gcc/ada/sem_ch6.ads @@ -234,6 +234,13 @@ package Sem_Ch6 is -- E is the entity for a subprogram or generic subprogram spec. This call -- lists all inherited Pre/Post aspects if List_Inherited_Pre_Post is True. + procedure May_Need_Actuals (Fun : Entity_Id); + -- Flag functions that can be called without parameters, i.e. those that + -- have no parameters, or those for which defaults exist for all parameters + -- Used for subprogram declarations and for access subprogram declarations, + -- where they apply to the anonymous designated type. On return the flag + -- Set_Needs_No_Actuals is set appropriately in Fun. + function Mode_Conformant (New_Id, Old_Id : Entity_Id) return Boolean; -- Determine whether two callable entities (subprograms, entries, -- literals) are mode conformant (RM 6.3.1(15)) diff --git a/gcc/ada/sem_ch7.adb b/gcc/ada/sem_ch7.adb index 505fe9d9916..e06b6b997cf 100644 --- a/gcc/ada/sem_ch7.adb +++ b/gcc/ada/sem_ch7.adb @@ -219,11 +219,15 @@ package body Sem_Ch7 is -- the later is never used for name resolution. In this fashion there -- is only one visible entity that denotes the package. - -- Set Body_Id. Note that this Will be reset to point to the generic + -- Set Body_Id. Note that this will be reset to point to the generic -- copy later on in the generic case. Body_Id := Defining_Entity (N); + if Has_Aspects (N) then + Analyze_Aspect_Specifications (N, Body_Id); + end if; + if Present (Corresponding_Spec (N)) then -- Body is body of package instantiation. Corresponding spec has @@ -766,7 +770,7 @@ package body Sem_Ch7 is -- True when this package declaration is not a nested declaration begin - -- Analye aspect specifications immediately, since we need to recognize + -- Analyze aspect specifications immediately, since we need to recognize -- things like Pure early enough to diagnose violations during analysis. if Has_Aspects (N) then diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb index 27ccc2d3d1e..1e6470bf223 100644 --- a/gcc/ada/sem_ch8.adb +++ b/gcc/ada/sem_ch8.adb @@ -1773,6 +1773,7 @@ package body Sem_Ch8 is Old_S : Entity_Id := Empty; Rename_Spec : Entity_Id; Save_AV : constant Ada_Version_Type := Ada_Version; + Save_AVP : constant Node_Id := Ada_Version_Pragma; Save_AV_Exp : constant Ada_Version_Type := Ada_Version_Explicit; Spec : constant Node_Id := Specification (N); @@ -2582,6 +2583,7 @@ package body Sem_Ch8 is -- ??? Ada_Version := Ada_Version_Type'Max (Ada_Version, Ada_95); + Ada_Version_Pragma := Empty; Ada_Version_Explicit := Ada_Version; if No (Old_S) then @@ -3039,6 +3041,7 @@ package body Sem_Ch8 is end if; Ada_Version := Save_AV; + Ada_Version_Pragma := Save_AVP; Ada_Version_Explicit := Save_AV_Exp; end Analyze_Subprogram_Renaming; diff --git a/gcc/ada/sem_ch9.adb b/gcc/ada/sem_ch9.adb index 41b4d9ccb2a..52dcb90d184 100644 --- a/gcc/ada/sem_ch9.adb +++ b/gcc/ada/sem_ch9.adb @@ -1734,6 +1734,22 @@ package body Sem_Ch9 is Set_Ekind (Body_Id, E_Protected_Body); Spec_Id := Find_Concurrent_Spec (Body_Id); + -- Protected bodies are currently removed by the expander. Since there + -- are no language-defined aspects that apply to a protected body, it is + -- not worth changing the whole expansion to accomodate user-defined + -- aspects. Plus we cannot possibly known the semantics of user-defined + -- aspects in order to plan ahead. + + if Has_Aspects (N) then + Error_Msg_N + ("?user-defined aspects on protected bodies are not supported", N); + + -- The aspects are removed for now to prevent cascading errors down + -- stream. + + Remove_Aspects (N); + end if; + if Present (Spec_Id) and then Ekind (Spec_Id) = E_Protected_Type then @@ -2606,6 +2622,10 @@ package body Sem_Ch9 is -- disastrous result. Analyze_Protected_Type_Declaration (N); + + if Has_Aspects (N) then + Analyze_Aspect_Specifications (N, Id); + end if; end Analyze_Single_Protected_Declaration; ------------------------------------- @@ -2703,6 +2723,22 @@ package body Sem_Ch9 is Set_Scope (Body_Id, Current_Scope); Spec_Id := Find_Concurrent_Spec (Body_Id); + -- Task bodies are transformed into a subprogram spec and body pair by + -- the expander. Since there are no language-defined aspects that apply + -- to a task body, it is not worth changing the whole expansion to + -- accomodate user-defined aspects. Plus we cannot possibly known the + -- semantics of user-defined aspects in order to plan ahead. + + if Has_Aspects (N) then + Error_Msg_N + ("?user-defined aspects on task bodies are not supported", N); + + -- The aspects are removed for now to prevent cascading errors down + -- stream. + + Remove_Aspects (N); + end if; + -- The spec is either a task type declaration, or a single task -- declaration for which we have created an anonymous type. diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb index 4fe6c57a5bd..8d716aa8454 100644 --- a/gcc/ada/sem_prag.adb +++ b/gcc/ada/sem_prag.adb @@ -186,6 +186,25 @@ package body Sem_Prag is -- whether a particular item appears in a mixed list of nodes and entities. -- It is assumed that all nodes in the list have entities. + function Check_Kind (Nam : Name_Id) return Name_Id; + -- This function is used in connection with pragmas Assert, Check, + -- and assertion aspects and pragmas, to determine if Check pragmas + -- (or corresponding assertion aspects or pragmas) are currently active + -- as determined by the presence of -gnata on the command line (which + -- sets the default), and the appearance of pragmas Check_Policy and + -- Assertion_Policy as configuration pragmas either in a configuration + -- pragma file, or at the start of the current unit, or locally given + -- Check_Policy and Assertion_Policy pragmas that are currently active. + -- + -- The value returned is one of the names Check, Ignore, Disable (On + -- returns Check, and Off returns Ignore). + -- + -- Note: for assertion kinds Pre'Class, Post'Class, Invariant'Class, + -- and Type_Invariant'Class, the name passed is Name_uPre, Name_uPost, + -- Name_uInvariant, or Name_uType_Invariant, which corresponds to _Pre, + -- _Post, _Invariant, or _Type_Invariant, which are special names used + -- in identifiers to represent these attribute references. + procedure Collect_Subprogram_Inputs_Outputs (Subp_Id : Entity_Id; Subp_Inputs : in out Elist_Id; @@ -1514,22 +1533,22 @@ package body Sem_Prag is (Item : Node_Id; Item_Id : Entity_Id) is + Context : Entity_Id; Dummy : Boolean; Inputs : Elist_Id := No_Elist; Outputs : Elist_Id := No_Elist; - Subp_Id : Entity_Id; begin -- Traverse the scope stack looking for enclosing subprograms -- subject to aspect/pragma Global. - Subp_Id := Scope (Current_Scope); - while Present (Subp_Id) and then Subp_Id /= Standard_Standard loop - if Is_Subprogram (Subp_Id) - and then Has_Aspect (Subp_Id, Aspect_Global) + Context := Scope (Subp_Id); + while Present (Context) and then Context /= Standard_Standard loop + if Is_Subprogram (Context) + and then Has_Aspect (Context, Aspect_Global) then Collect_Subprogram_Inputs_Outputs - (Subp_Id => Subp_Id, + (Subp_Id => Context, Subp_Inputs => Inputs, Subp_Outputs => Outputs, Global_Seen => Dummy); @@ -1545,11 +1564,15 @@ package body Sem_Prag is Item, Item_Id); Error_Msg_NE ("\item already appears as input of subprogram &", - Item, Subp_Id); + Item, Context); + + -- Stop the traversal once an error has been detected + + exit; end if; end if; - Subp_Id := Scope (Subp_Id); + Context := Scope (Context); end loop; end Check_Mode_Restriction_In_Enclosing_Context; @@ -1576,7 +1599,10 @@ package body Sem_Prag is begin -- Single global item declaration - if Nkind_In (List, N_Identifier, N_Selected_Component) then + if Nkind_In (List, N_Expanded_Name, + N_Identifier, + N_Selected_Component) + then Analyze_Global_Item (List, Global_Mode); -- Simple global list or moded global list declaration @@ -3495,7 +3521,7 @@ package body Sem_Prag is -- For a pragma PPC in the extended main source unit, record enabled -- status in SCO. - if not Is_Ignored (N) and then not Split_PPC (N) then + if Is_Checked (N) and then not Split_PPC (N) then Set_SCO_Pragma_Enabled (Loc); end if; @@ -3592,7 +3618,7 @@ package body Sem_Prag is -- N_Contract node. if Acts_As_Spec (PO) - and then (SPARK_Mode or else Formal_Extensions) + and then (SPARK_Mode or Formal_Extensions) then declare Prag : constant Node_Id := New_Copy_Tree (N); @@ -8164,11 +8190,27 @@ package body Sem_Prag is Prag_Id := Get_Pragma_Id (Pname); Pname := Original_Name (N); - -- Check applicable policy. We skip this for a pragma that came from - -- an aspect, since we already dealt with the Disable case, and we set - -- the Is_Ignored flag at the time the aspect was analyzed. + -- Check applicable policy. We skip this if Is_Checked or Is_Ignored + -- is already set, indicating that we have already checked the policy + -- at the right point. This happens for example in the case of a pragma + -- that is derived from an Aspect. + + if Is_Ignored (N) or else Is_Checked (N) then + null; + + -- For a pragma that is a rewriting of another pragma, copy the + -- Is_Checked/Is_Ignored status from the rewritten pragma. + + elsif Is_Rewrite_Substitution (N) + and then Nkind (Original_Node (N)) = N_Pragma + and then Original_Node (N) /= N + then + Set_Is_Ignored (N, Is_Ignored (Original_Node (N))); + Set_Is_Checked (N, Is_Checked (Original_Node (N))); + + -- Otherwise query the applicable policy at this point - if not From_Aspect_Specification (N) then + else Check_Applicable_Policy (N); -- If pragma is disabled, rewrite as NULL and skip analysis @@ -8558,8 +8600,9 @@ package body Sem_Prag is -- Now set Ada 83 mode - Ada_Version := Ada_83; - Ada_Version_Explicit := Ada_Version; + Ada_Version := Ada_83; + Ada_Version_Explicit := Ada_83; + Ada_Version_Pragma := N; ------------ -- Ada_95 -- @@ -8589,8 +8632,9 @@ package body Sem_Prag is -- Now set Ada 95 mode - Ada_Version := Ada_95; - Ada_Version_Explicit := Ada_Version; + Ada_Version := Ada_95; + Ada_Version_Explicit := Ada_95; + Ada_Version_Pragma := N; --------------------- -- Ada_05/Ada_2005 -- @@ -8637,6 +8681,7 @@ package body Sem_Prag is Ada_Version := Ada_2005; Ada_Version_Explicit := Ada_2005; + Ada_Version_Pragma := N; end if; end; @@ -8686,6 +8731,7 @@ package body Sem_Prag is Ada_Version := Ada_2012; Ada_Version_Explicit := Ada_2012; + Ada_Version_Pragma := N; end if; end; @@ -8879,6 +8925,8 @@ package body Sem_Prag is Append_To (Newa, New_Copy_Tree (Arg2)); end if; + -- Rewrite as Check pragma + Rewrite (N, Make_Pragma (Loc, Chars => Name_Check, @@ -9490,9 +9538,6 @@ package body Sem_Prag is Cname : Name_Id; Str : Node_Id; - Check_On : Boolean; - -- Set True if category of assertions referenced by Name enabled - begin GNAT_Pragma; Check_At_Least_N_Arguments (2); @@ -9526,24 +9571,33 @@ package body Sem_Prag is null; end case; - -- Set Check_On to indicate check status + -- Check applicable policy. We skip this if Checked/Ignored status + -- is already set (e.g. in the casse of a pragma from an aspect). - -- If this comes from an aspect, we have already taken care of - -- the policy active when the aspect was analyzed, and Is_Ignored - -- is set appropriately already. + if Is_Checked (N) or else Is_Ignored (N) then + null; - if From_Aspect_Specification (N) then - Check_On := not Is_Ignored (N); + -- For a non-source pragma that is a rewriting of another pragma, + -- copy the Is_Checked/Ignored status from the rewritten pragma. + + elsif Is_Rewrite_Substitution (N) + and then Nkind (Original_Node (N)) = N_Pragma + and then Original_Node (N) /= N + then + Set_Is_Ignored (N, Is_Ignored (Original_Node (N))); + Set_Is_Checked (N, Is_Checked (Original_Node (N))); - -- Otherwise check the status right now + -- Otherwise query the applicable policy at this point else case Check_Kind (Cname) is when Name_Ignore => - Check_On := False; + Set_Is_Ignored (N, True); + Set_Is_Checked (N, False); when Name_Check => - Check_On := True; + Set_Is_Ignored (N, False); + Set_Is_Checked (N, True); -- For disable, rewrite pragma as null statement and skip -- rest of the analysis of the pragma. @@ -9578,7 +9632,7 @@ package body Sem_Prag is when others => - if Check_On and then not Split_PPC (N) then + if Is_Checked (N) and then not Split_PPC (N) then -- Mark pragma/aspect SCO as enabled @@ -9595,7 +9649,7 @@ package body Sem_Prag is -- we do want to analyze (to get proper references). -- The Preanalyze_And_Resolve routine does just what we want - if not Check_On then + if Is_Ignored (N) then Preanalyze_And_Resolve (Str, Standard_String); -- Otherwise we need a proper analysis and expansion @@ -9618,11 +9672,11 @@ package body Sem_Prag is -- null; -- end if; - -- The reason we do this rewriting during semantic analysis - -- rather than as part of normal expansion is that we cannot - -- analyze and expand the code for the boolean expression - -- directly, or it may cause insertion of actions that would - -- escape the attempt to suppress the check code. + -- The reason we do this rewriting during semantic analysis rather + -- than as part of normal expansion is that we cannot analyze and + -- expand the code for the boolean expression directly, or it may + -- cause insertion of actions that would escape the attempt to + -- suppress the check code. -- Note that the Sloc for the if statement corresponds to the -- argument condition, not the pragma itself. The reason for @@ -9630,7 +9684,7 @@ package body Sem_Prag is -- False at compile time, and we do not want to delete this -- warning when we delete the if statement. - if Expander_Active and not Check_On then + if Expander_Active and Is_Ignored (N) then Eloc := Sloc (Expr); Rewrite (N, @@ -11552,6 +11606,7 @@ package body Sem_Prag is else Extensions_Allowed := False; Ada_Version := Ada_Version_Explicit; + Ada_Version_Pragma := Empty; end if; -------------- @@ -15040,11 +15095,9 @@ package body Sem_Prag is Check_Optional_Identifier (Arg1, Name_Check); Check_Precondition_Postcondition (In_Body); - -- If in spec, nothing more to do. If in body, then we convert the - -- pragma to an equivalent pragam Check. Note we do this whether - -- or not precondition checks are enabled. That works fine since - -- pragma Check will do this check, and will also analyze the - -- condition itself in the proper context. + -- If in spec, nothing more to do. If in body, then we convert + -- the pragma to an equivalent pragma Check. That works fine since + -- pragma Check will analyze the condition in the proper context. -- The form of the pragma Check is either: @@ -15057,20 +15110,25 @@ package body Sem_Prag is -- pragmas are checked. if In_Body then + + -- Rewrite as Check pragma + Rewrite (N, Make_Pragma (Loc, Chars => Name_Check, Pragma_Argument_Associations => New_List ( Make_Pragma_Argument_Association (Loc, - Expression => Make_Identifier (Loc, Pname)), + Expression => Make_Identifier (Loc, Pname)), Make_Pragma_Argument_Association (Sloc (Arg1), - Expression => Relocate_Node (Get_Pragma_Arg (Arg1)))))); + Expression => + Relocate_Node (Get_Pragma_Arg (Arg1)))))); if Arg_Count = 2 then Append_To (Pragma_Argument_Associations (N), Make_Pragma_Argument_Association (Sloc (Arg2), - Expression => Relocate_Node (Get_Pragma_Arg (Arg2)))); + Expression => + Relocate_Node (Get_Pragma_Arg (Arg2)))); end if; Analyze (N); @@ -15141,16 +15199,22 @@ package body Sem_Prag is Ent := Find_Lib_Unit_Name; Check_Duplicate_Pragma (Ent); - -- This filters out pragmas inside generic parent then - -- show up inside instantiation + -- This filters out pragmas inside generic parents that show up + -- inside instantiations. Pragmas that come from aspects in the + -- unit are not ignored. - if Present (Ent) - and then not (Pk = N_Package_Specification - and then Present (Generic_Parent (Pa))) - then - if not Debug_Flag_U then - Set_Is_Preelaborated (Ent); - Set_Suppress_Elaboration_Warnings (Ent); + if Present (Ent) then + if Pk = N_Package_Specification + and then Present (Generic_Parent (Pa)) + and then not From_Aspect_Specification (N) + then + null; + + else + if not Debug_Flag_U then + Set_Is_Preelaborated (Ent); + Set_Suppress_Elaboration_Warnings (Ent); + end if; end if; end if; end Preelaborate; @@ -16338,7 +16402,7 @@ package body Sem_Prag is -- SPARK_Mode -- ---------------- - -- pragma SPARK_Mode (On | Off | Auto); + -- pragma SPARK_Mode [(On | Off | Auto)]; when Pragma_SPARK_Mode => SPARK_Mod : declare procedure Chain_Pragma (Context : Entity_Id; Prag : Node_Id); @@ -16347,7 +16411,7 @@ package body Sem_Prag is -- the consistency between modes of visible/private declarations -- and body declarations/statements. - procedure Check_Conformance + procedure Check_Spark_Mode_Conformance (Governing_Id : Entity_Id; New_Id : Entity_Id); -- Verify the "monotonicity" of SPARK modes between two entities. @@ -16391,11 +16455,11 @@ package body Sem_Prag is end if; end Chain_Pragma; - ----------------------- - -- Check_Conformance -- - ----------------------- + ---------------------------------- + -- Check_Spark_Mode_Conformance -- + ---------------------------------- - procedure Check_Conformance + procedure Check_Spark_Mode_Conformance (Governing_Id : Entity_Id; New_Id : Entity_Id) is @@ -16427,7 +16491,7 @@ package body Sem_Prag is (Governing_Mode => Gov_Prag, New_Mode => New_Prag); end if; - end Check_Conformance; + end Check_Spark_Mode_Conformance; ------------------------------ -- Check_Pragma_Conformance -- @@ -16574,11 +16638,52 @@ package body Sem_Prag is Stmt := Prev (Stmt); end loop; - -- If we get here, then we ran out of preceding statements. The - -- pragma is immediately within a body. + -- Handle all cases where the pragma is actually an aspect and + -- applies to a library-level package spec, body or subprogram. + + -- function F ... with SPARK_Mode => ...; + -- package P with SPARK_Mode => ...; + -- package body P with SPARK_Mode => ... is - if Nkind_In (Context, N_Package_Body, - N_Subprogram_Body) + -- The following circuitry simply prepares the proper context + -- for the general pragma processing mechanism below. + + if Nkind (Context) = N_Compilation_Unit_Aux then + Context := Unit (Parent (Context)); + + if Nkind_In (Context, N_Package_Declaration, + N_Subprogram_Declaration) + then + Context := Specification (Context); + end if; + end if; + + -- The pragma is at the top level of a package spec or appears + -- as an aspect on a subprogram. + + -- function F ... with SPARK_Mode => ...; + + -- package P is + -- pragma SPARK_Mode; + + if Nkind_In (Context, N_Function_Specification, + N_Package_Specification, + N_Procedure_Specification) + then + Spec_Id := Defining_Unit_Name (Context); + Chain_Pragma (Spec_Id, N); + + -- The pragma is immediately within a package or subprogram + -- body. + + -- function F ... is + -- pragma SPARK_Mode; + + -- package body P is + -- pragma SPARK_Mode; + + elsif Nkind_In (Context, N_Package_Body, + N_Subprogram_Body) then Spec_Id := Corresponding_Spec (Context); @@ -16589,16 +16694,20 @@ package body Sem_Prag is Body_Id := Defining_Unit_Name (Context); Chain_Pragma (Body_Id, N); - Check_Conformance (Spec_Id, Body_Id); - -- The pragma is at the top level of a package spec + -- Verify that the SPARK modes are consistent between + -- body and spec, if any. - elsif Nkind (Context) = N_Package_Specification then - Spec_Id := Defining_Unit_Name (Context); - Chain_Pragma (Spec_Id, N); + if Present (Spec_Id) then + Check_Spark_Mode_Conformance (Spec_Id, Body_Id); + end if; -- The pragma applies to the statements of a package body + -- package body P is + -- begin + -- pragma SPARK_Mode; + elsif Nkind (Context) = N_Handled_Sequence_Of_Statements and then Nkind (Parent (Context)) = N_Package_Body then @@ -16607,10 +16716,9 @@ package body Sem_Prag is Body_Id := Defining_Unit_Name (Context); Chain_Pragma (Body_Id, N); - Check_Conformance (Spec_Id, Body_Id); + Check_Spark_Mode_Conformance (Spec_Id, Body_Id); - -- The pragma does not apply to a legal construct, issue an - -- error. + -- The pragma does not apply to a legal construct, issue error else Pragma_Misplaced; @@ -17855,6 +17963,10 @@ package body Sem_Prag is then Check_Arg_Is_Static_Expression (Last_Arg, Standard_String); Arg_Count := Arg_Count - 1; + + -- Not allowed in compiler units (bootstrap issues) + + Check_Compiler_Unit (N); end if; end; @@ -18286,17 +18398,33 @@ package body Sem_Prag is Pnm : constant Name_Id := Chars (Get_Pragma_Arg (First (PPA))); begin - if Ename = Pnm or else Pnm = Name_Assertion then + if Ename = Pnm + or else Pnm = Name_Assertion + or else (Pnm = Name_Statement_Assertions + and then (Ename = Name_Assert or else + Ename = Name_Assert_And_Cut or else + Ename = Name_Assume or else + Ename = Name_Loop_Invariant)) + then Policy := Chars (Get_Pragma_Arg (Last (PPA))); case Policy is when Name_Off | Name_Ignore => Set_Is_Ignored (N, True); + Set_Is_Checked (N, False); + + when Name_On | Name_Check => + Set_Is_Checked (N, True); + Set_Is_Ignored (N, False); when Name_Disable => Set_Is_Ignored (N, True); + Set_Is_Checked (N, False); Set_Is_Disabled (N, True); + -- That should be exhaustive, the null here is a defence + -- against a malformed tree from previous errors. + when others => null; end case; @@ -18313,8 +18441,12 @@ package body Sem_Prag is -- compatibility with the RM for the cases of assertion, invariant, -- precondition, predicate, and postcondition. - if not Assertions_Enabled then - Set_Is_Ignored (N); + if Assertions_Enabled then + Set_Is_Checked (N, True); + Set_Is_Ignored (N, False); + else + Set_Is_Checked (N, False); + Set_Is_Ignored (N, True); end if; end Check_Applicable_Policy; @@ -18369,7 +18501,10 @@ package body Sem_Prag is begin -- Single global item declaration - if Nkind_In (List, N_Identifier, N_Selected_Component) then + if Nkind_In (List, N_Expanded_Name, + N_Identifier, + N_Selected_Component) + then Collect_Global_Item (List, Mode); -- Simple global list or moded global list declaration @@ -18596,16 +18731,24 @@ package body Sem_Prag is ----------------------- function Get_SPARK_Mode_Id (N : Node_Id) return SPARK_Mode_Id is + Args : List_Id; Mode : Node_Id; begin - pragma Assert - (Nkind (N) = N_Pragma - and then Present (Pragma_Argument_Associations (N))); + pragma Assert (Nkind (N) = N_Pragma); + Args := Pragma_Argument_Associations (N); + + -- Extract the mode from the argument list - Mode := First (Pragma_Argument_Associations (N)); + if Present (Args) then + Mode := First (Pragma_Argument_Associations (N)); + return Get_SPARK_Mode_Id (Chars (Get_Pragma_Arg (Mode))); - return Get_SPARK_Mode_Id (Chars (Get_Pragma_Arg (Mode))); + -- When SPARK_Mode appears without an argument, the default is ON + + else + return SPARK_On; + end if; end Get_SPARK_Mode_Id; ---------------- diff --git a/gcc/ada/sem_prag.ads b/gcc/ada/sem_prag.ads index fcbe9889861..ecfb3eda75a 100644 --- a/gcc/ada/sem_prag.ads +++ b/gcc/ada/sem_prag.ads @@ -63,25 +63,6 @@ package Sem_Prag is -- expressions in the pragma as "spec expressions" (see section in Sem -- "Handling of Default and Per-Object Expressions..."). - function Check_Kind (Nam : Name_Id) return Name_Id; - -- This function is used in connection with pragmas Assert, Check, - -- and assertion aspects and pragmas, to determine if Check pragmas - -- (or corresponding assertion aspects or pragmas) are currently active - -- as determined by the presence of -gnata on the command line (which - -- sets the default), and the appearance of pragmas Check_Policy and - -- Assertion_Policy as configuration pragmas either in a configuration - -- pragma file, or at the start of the current unit, or locally given - -- Check_Policy and Assertion_Policy pragmas that are currently active. - -- - -- The value returned is one of the names Check, Ignore, Disable (On - -- returns Check, and Off returns Ignore). - -- - -- Note: for assertion kinds Pre'Class, Post'Class, Invariant'Class, - -- and Type_Invariant'Class, the name passed is Name_uPre, Name_uPost, - -- Name_uInvariant, or Name_uType_Invariant, which corresponds to _Pre, - -- _Post, _Invariant, or _Type_Invariant, which are special names used - -- in identifiers to represent these attribute references. - procedure Check_Applicable_Policy (N : Node_Id); -- N is either an N_Aspect or an N_Pragma node. There are two cases. If -- the name of the aspect or pragma is not one of those recognized as @@ -95,9 +76,10 @@ package Sem_Prag is -- If the name is a valid assertion kind name, then the Check_Policy pragma -- chain is checked for a matching entry (or for an Assertion entry which -- matches all possibilities). If a matching entry is found then the policy - -- is checked. If it is Off, Ignore, or Disable, then the Is_Ignored flag - -- is set in the aspect or pragma node. Additionally for policy Disable, - -- the Is_Disabled flag is set. + -- is checked. If it is On or Check, then the Is_Checked flag is set in + -- the aspect or pragma node. If it is Off, Ignore, or Disable, then the + -- Is_Ignored flag is set in the aspect or pragma node. Additionally for + -- policy Disable, the Is_Disabled flag is set. -- -- If no matching Check_Policy pragma is found then the effect depends on -- whether -gnata was used, if so, then the call has no effect, otherwise diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb index 61f7712a090..387e06f31db 100644 --- a/gcc/ada/sem_res.adb +++ b/gcc/ada/sem_res.adb @@ -1583,15 +1583,16 @@ package body Sem_Res is if ASIS_Mode and then Nkind (N) in N_Op then if Is_Binary then - Set_Parameter_Associations - (Original_Node (N), - New_List (New_Copy_Tree (Left_Opnd (N)), - New_Copy_Tree (Right_Opnd (N)))); + Rewrite (First (Parameter_Associations (Original_Node (N))), + New_Copy_Tree (Left_Opnd (N))); + Rewrite (Next (First (Parameter_Associations (Original_Node (N)))), + New_Copy_Tree (Right_Opnd (N))); else - Set_Parameter_Associations - (Original_Node (N), - New_List (New_Copy_Tree (Right_Opnd (N)))); + Rewrite (First (Parameter_Associations (Original_Node (N))), + New_Copy_Tree (Right_Opnd (N))); end if; + + Set_Parent (Original_Node (N), Parent (N)); end if; end Make_Call_Into_Operator; @@ -5459,7 +5460,13 @@ package body Sem_Res is ("cannot disambiguate function call and indexing", N); else New_Subp := Relocate_Node (Subp); - Set_Entity (Subp, Nam); + + -- The called entity may be an explicit dereference, in which + -- case there is no entity to set. + + if Nkind (New_Subp) /= N_Explicit_Dereference then + Set_Entity (Subp, Nam); + end if; if (Is_Array_Type (Ret_Type) and then Component_Type (Ret_Type) /= Any_Type) diff --git a/gcc/ada/sinfo.adb b/gcc/ada/sinfo.adb index c8eab8a9536..6cb18c1890c 100644 --- a/gcc/ada/sinfo.adb +++ b/gcc/ada/sinfo.adb @@ -1732,6 +1732,15 @@ package body Sinfo is return Flag16 (N); end Is_Boolean_Aspect; + function Is_Checked + (N : Node_Id) return Boolean is + begin + pragma Assert (False + or else NT (N).Nkind = N_Aspect_Specification + or else NT (N).Nkind = N_Pragma); + return Flag11 (N); + end Is_Checked; + function Is_Component_Left_Opnd (N : Node_Id) return Boolean is begin @@ -4840,6 +4849,15 @@ package body Sinfo is Set_Flag16 (N, Val); end Set_Is_Boolean_Aspect; + procedure Set_Is_Checked + (N : Node_Id; Val : Boolean := True) is + begin + pragma Assert (False + or else NT (N).Nkind = N_Aspect_Specification + or else NT (N).Nkind = N_Pragma); + Set_Flag11 (N, Val); + end Set_Is_Checked; + procedure Set_Is_Component_Left_Opnd (N : Node_Id; Val : Boolean := True) is begin diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads index e8c9805cc31..112f8fc00ab 100644 --- a/gcc/ada/sinfo.ads +++ b/gcc/ada/sinfo.ads @@ -455,6 +455,59 @@ package Sinfo is -- code is being generated, since they involved expander actions that -- destroy the tree. + --------------- + -- ASIS Mode -- + --------------- + + -- When a file is compiled in ASIS mode (-gnatct), expansion is skipped, + -- and the analysis must generate a tree in a form that meets all ASIS + -- requirements. + + -- ASIS must be able to recover the original tree that corresponds to the + -- source. It relies heavily on Original_Node for this purpose, which as + -- described in Atree, records the history when a node is rewritten. ASIS + -- uses Original_Node to recover the original node before the Rewrite. + + -- At least in ASIS mode (not really important in non-ASIS mode), when + -- N1 is rewritten as N2: + + -- The subtree rooted by the original node N1 should be fully decorated, + -- i.e. all semantic fields noted in sinfo.ads should be set properly + -- and any referenced entities should be complete (with exceptions for + -- representation information, noted below). + + -- For all the direct descendants of N1 (original node) their Parent + -- links should point not to N1, but to N2 (rewriting node). + + -- The Parent links of rewritten nodes (N1 in this example) are set in + -- some cases (to point to the rewritten parent), but in other cases + -- they are set to Empty. This needs sorting out ??? It would be much + -- cleaner if they could always be set in the original node ??? + + -- Representation Information + + -- For the purposes of the data description annex, the representation + -- information for source declared entities must be complete in the + -- ASIS tree. + + -- This requires that the front end call the back end (gigi/gcc) in + -- a special "back annotate only" mode to obtain information on layout + -- from the back end. + + -- For the purposes of this special "back annotate only" mode, the + -- requirements that would normally need to be met to generate code + -- are relaxed as follows: + + -- Anonymous types need not have full representation information (e.g. + -- sizes need not be set for types where the front end would normally + -- set the sizes), since anonymous types can be ignored in this mode. + + -- In this mode, gigi will see at least fragments of a fully annotated + -- unexpanded tree. This means that it will encounter nodes it does + -- not normally handle (such as stubs, task bodies etc). It should + -- simply ignore these nodes, since they are not relevant to the task + -- of back annotating representation information. + ------------------------ -- Common Flag Fields -- ------------------------ @@ -1269,6 +1322,15 @@ package Sinfo is -- Present in N_Aspect_Specification node. Set if the aspect is for a -- boolean aspect (i.e. Aspect_Id is in Boolean_Aspect subtype). + -- Is_Checked (Flag11-Sem) + -- Present in N_Aspect_Specification and N_Pragma nodes. Set for an + -- assertion aspect or pragma, or check pragma for an assertion, that + -- is to be checked at run time. If either Is_Checked or Is_Ignored + -- is set (they cannot both be set), then this means that the status of + -- the pragma has been checked at the appropriate point and should not + -- be further modified (in some cases these flags are copied when a + -- pragma is rewritten). + -- Is_Component_Left_Opnd (Flag13-Sem) -- Is_Component_Right_Opnd (Flag14-Sem) -- Present in concatenation nodes, to indicate that the corresponding @@ -2116,6 +2178,7 @@ package Sinfo is -- Is_Delayed_Aspect (Flag14-Sem) -- Is_Disabled (Flag15-Sem) -- Is_Ignored (Flag9-Sem) + -- Is_Checked (Flag11-Sem) -- Import_Interface_Present (Flag16-Sem) -- Split_PPC (Flag17) set if corresponding aspect had Split_PPC set @@ -4765,7 +4828,8 @@ package Sinfo is -- and put in its proper section when we know exactly where that is! -- EXPRESSION_FUNCTION ::= - -- FUNCTION SPECIFICATION IS (EXPRESSION); + -- FUNCTION SPECIFICATION IS (EXPRESSION) + -- [ASPECT_SPECIFICATIONS]; -- N_Expression_Function -- Sloc points to FUNCTION @@ -5000,7 +5064,8 @@ package Sinfo is -- PRIVATE_TYPE_DECLARATION ::= -- type DEFINING_IDENTIFIER [DISCRIMINANT_PART] - -- is [[abstract] tagged] [limited] private; + -- is [[abstract] tagged] [limited] private + -- [ASPECT_SPECIFICATIONS]; -- Note: TAGGED is not permitted in Ada 83 mode @@ -5022,7 +5087,7 @@ package Sinfo is -- type DEFINING_IDENTIFIER [DISCRIMINANT_PART] is -- [abstract] [limited | synchronized] -- new ancestor_SUBTYPE_INDICATION [and INTERFACE_LIST] - -- with private; + -- with private [ASPECT_SPECIFICATIONS]; -- Note: LIMITED, and private extension declarations are not allowed -- in Ada 83 mode. @@ -5092,9 +5157,11 @@ package Sinfo is -- OBJECT_RENAMING_DECLARATION ::= -- DEFINING_IDENTIFIER : - -- [NULL_EXCLUSION] SUBTYPE_MARK renames object_NAME; + -- [NULL_EXCLUSION] SUBTYPE_MARK renames object_NAME + -- [ASPECT_SPECIFICATIONS]; -- | DEFINING_IDENTIFIER : - -- ACCESS_DEFINITION renames object_NAME; + -- ACCESS_DEFINITION renames object_NAME + -- [ASPECT_SPECIFICATIONS]; -- Note: Access_Definition is an optional field that gives support to -- Ada 2005 (AI-230). The parser generates nodes that have either the @@ -5114,7 +5181,8 @@ package Sinfo is ----------------------------------------- -- EXCEPTION_RENAMING_DECLARATION ::= - -- DEFINING_IDENTIFIER : exception renames exception_NAME; + -- DEFINING_IDENTIFIER : exception renames exception_NAME + -- [ASPECT_SPECIFICATIONS]; -- N_Exception_Renaming_Declaration -- Sloc points to first identifier @@ -5126,7 +5194,8 @@ package Sinfo is --------------------------------------- -- PACKAGE_RENAMING_DECLARATION ::= - -- package DEFINING_PROGRAM_UNIT_NAME renames package_NAME; + -- package DEFINING_PROGRAM_UNIT_NAME renames package_NAME + -- [ASPECT_SPECIFICATIONS]; -- N_Package_Renaming_Declaration -- Sloc points to PACKAGE @@ -5139,7 +5208,8 @@ package Sinfo is ------------------------------------------ -- SUBPROGRAM_RENAMING_DECLARATION ::= - -- SUBPROGRAM_SPECIFICATION renames callable_entity_NAME; + -- SUBPROGRAM_SPECIFICATION renames callable_entity_NAME + -- [ASPECT_SPECIFICATIONS]; -- N_Subprogram_Renaming_Declaration -- Sloc points to RENAMES @@ -5157,10 +5227,13 @@ package Sinfo is -- GENERIC_RENAMING_DECLARATION ::= -- generic package DEFINING_PROGRAM_UNIT_NAME -- renames generic_package_NAME + -- [ASPECT_SPECIFICATIONS]; -- | generic procedure DEFINING_PROGRAM_UNIT_NAME -- renames generic_procedure_NAME + -- [ASPECT_SPECIFICATIONS]; -- | generic function DEFINING_PROGRAM_UNIT_NAME -- renames generic_function_NAME + -- [ASPECT_SPECIFICATIONS]; -- N_Generic_Package_Renaming_Declaration -- Sloc points to GENERIC @@ -5374,7 +5447,8 @@ package Sinfo is -- ENTRY_DECLARATION ::= -- [[not] overriding] -- entry DEFINING_IDENTIFIER - -- [(DISCRETE_SUBTYPE_DEFINITION)] PARAMETER_PROFILE; + -- [(DISCRETE_SUBTYPE_DEFINITION)] PARAMETER_PROFILE + -- [ASPECT_SPECIFICATIONS]; -- N_Entry_Declaration -- Sloc points to ENTRY @@ -5975,7 +6049,8 @@ package Sinfo is ---------------------------------- -- SUBPROGRAM_BODY_STUB ::= - -- SUBPROGRAM_SPECIFICATION is separate; + -- SUBPROGRAM_SPECIFICATION is separate + -- [ASPECT_SPECIFICATION]; -- N_Subprogram_Body_Stub -- Sloc points to FUNCTION or PROCEDURE @@ -5988,7 +6063,8 @@ package Sinfo is ------------------------------- -- PACKAGE_BODY_STUB ::= - -- package body DEFINING_IDENTIFIER is separate; + -- package body DEFINING_IDENTIFIER is separate + -- [ASPECT_SPECIFICATION]; -- N_Package_Body_Stub -- Sloc points to PACKAGE @@ -6001,7 +6077,8 @@ package Sinfo is ---------------------------- -- TASK_BODY_STUB ::= - -- task body DEFINING_IDENTIFIER is separate; + -- task body DEFINING_IDENTIFIER is separate + -- [ASPECT_SPECIFICATION]; -- N_Task_Body_Stub -- Sloc points to TASK @@ -6014,7 +6091,8 @@ package Sinfo is --------------------------------- -- PROTECTED_BODY_STUB ::= - -- protected body DEFINING_IDENTIFIER is separate; + -- protected body DEFINING_IDENTIFIER is separate + -- [ASPECT_SPECIFICATION]; -- Note: protected body stubs are not allowed in Ada 83 mode @@ -6215,7 +6293,8 @@ package Sinfo is ------------------------------------------ -- GENERIC_SUBPROGRAM_DECLARATION ::= - -- GENERIC_FORMAL_PART SUBPROGRAM_SPECIFICATION; + -- GENERIC_FORMAL_PART SUBPROGRAM_SPECIFICATION + -- [ASPECT_SPECIFICATIONS]; -- Note: Generic_Formal_Declarations can include pragmas @@ -6763,6 +6842,7 @@ package Sinfo is -- Next_Rep_Item (Node5-Sem) -- Split_PPC (Flag17) Set if split pre/post attribute -- Is_Boolean_Aspect (Flag16-Sem) + -- Is_Checked (Flag11-Sem) -- Is_Delayed_Aspect (Flag14-Sem) -- Is_Disabled (Flag15-Sem) -- Is_Ignored (Flag9-Sem) @@ -7049,16 +7129,21 @@ package Sinfo is -- Pre_Post_Conditions contains a collection of pragmas that correspond -- to pre- and postconditions associated with an entry or a subprogram. -- The pragmas can either come from source or be the byproduct of aspect - -- expansion. The ordering in the list is of LIFO fashion. + -- expansion. The ordering in the list is in LIFO fashion. + + -- Note that there might be multiple preconditions or postconditions + -- in this list, either because they come from separate pragmas in the + -- source, or because a Pre (resp. Post) aspect specification has been + -- broken into AND THEN sections. See Split_PPC for details. -- Contract_Test_Cases contains a collection of pragmas that correspond -- to aspects/pragmas Contract_Cases and Test_Case. The ordering in the - -- list is of LIFO fashion. + -- list is in LIFO fashion. -- Classifications contains pragmas that either categorize subprogram -- inputs and outputs or establish dependencies between them. Currently -- pragmas Depends and Global are stored in this list. The ordering is - -- of LIFO fashion. + -- in LIFO fashion. ------------------- -- Expanded_Name -- @@ -8720,6 +8805,9 @@ package Sinfo is function Is_Boolean_Aspect (N : Node_Id) return Boolean; -- Flag16 + function Is_Checked + (N : Node_Id) return Boolean; -- Flag11 + function Is_Component_Left_Opnd (N : Node_Id) return Boolean; -- Flag13 @@ -9710,6 +9798,9 @@ package Sinfo is procedure Set_Is_Boolean_Aspect (N : Node_Id; Val : Boolean := True); -- Flag16 + procedure Set_Is_Checked + (N : Node_Id; Val : Boolean := True); -- Flag11 + procedure Set_Is_Component_Left_Opnd (N : Node_Id; Val : Boolean := True); -- Flag13 @@ -12095,6 +12186,7 @@ package Sinfo is pragma Inline (Is_Accessibility_Actual); pragma Inline (Is_Asynchronous_Call_Block); pragma Inline (Is_Boolean_Aspect); + pragma Inline (Is_Checked); pragma Inline (Is_Component_Left_Opnd); pragma Inline (Is_Component_Right_Opnd); pragma Inline (Is_Controlling_Actual); @@ -12420,6 +12512,7 @@ package Sinfo is pragma Inline (Set_Is_Accessibility_Actual); pragma Inline (Set_Is_Asynchronous_Call_Block); pragma Inline (Set_Is_Boolean_Aspect); + pragma Inline (Set_Is_Checked); pragma Inline (Set_Is_Component_Left_Opnd); pragma Inline (Set_Is_Component_Right_Opnd); pragma Inline (Set_Is_Controlling_Actual); diff --git a/gcc/ada/sinput.adb b/gcc/ada/sinput.adb index 29be59ac688..a01c045d91f 100644 --- a/gcc/ada/sinput.adb +++ b/gcc/ada/sinput.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2012, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -258,10 +258,20 @@ package body Sinput is BOM : BOM_Kind; Len : Natural; Tst : String (1 .. 5); + C : Character; begin for J in 1 .. 5 loop - Tst (J) := Source (Scan_Ptr + Source_Ptr (J) - 1); + C := Source (Scan_Ptr + Source_Ptr (J) - 1); + + -- Definitely no BOM if EOF character marks either end of file, or + -- an illegal non-BOM character if not at the end of file. + + if C = EOF then + return; + end if; + + Tst (J) := C; end loop; Read_BOM (Tst, Len, BOM, False); diff --git a/gcc/ada/sprint.adb b/gcc/ada/sprint.adb index 8526716e08e..5259dd776ff 100644 --- a/gcc/ada/sprint.adb +++ b/gcc/ada/sprint.adb @@ -2479,6 +2479,18 @@ package body Sprint is Sprint_Node_Sloc (Specification (Node)); Write_Char (';'); + -- If this is an instantiation, get the aspects from the original + -- instantiation node. + + if Is_Generic_Instance (Defining_Entity (Node)) + and then Has_Aspects + (Package_Instantiation (Defining_Entity (Node))) + then + Sprint_Aspect_Specifications + (Package_Instantiation (Defining_Entity (Node)), + Semicolon => True); + end if; + when N_Package_Instantiation => Extra_Blank_Line; Write_Indent_Str_Sloc ("package "); @@ -2499,12 +2511,27 @@ package body Sprint is Write_Str_With_Col_Check_Sloc ("package "); Sprint_Node (Defining_Unit_Name (Node)); - if Nkind_In (Parent (Node), N_Package_Declaration, - N_Generic_Package_Declaration) + if Nkind (Parent (Node)) = N_Generic_Package_Declaration and then Has_Aspects (Parent (Node)) then Sprint_Aspect_Specifications (Parent (Node), Semicolon => False); + + -- An instantiation is rewritten as a package declaration, but + -- the aspects belong to the instantiation node. + + elsif Nkind (Parent (Node)) = N_Package_Declaration then + declare + Pack : constant Entity_Id := Defining_Entity (Node); + + begin + if not Is_Generic_Instance (Pack) then + if Has_Aspects (Parent (Node)) then + Sprint_Aspect_Specifications + (Parent (Node), Semicolon => False); + end if; + end if; + end; end if; Write_Str (" is"); diff --git a/gcc/ada/switch-c.adb b/gcc/ada/switch-c.adb index 0fc6bdb2188..197be06a19e 100644 --- a/gcc/ada/switch-c.adb +++ b/gcc/ada/switch-c.adb @@ -31,9 +31,9 @@ with Debug; use Debug; with Lib; use Lib; with Osint; use Osint; with Opt; use Opt; -with Validsw; use Validsw; with Stylesw; use Stylesw; with Ttypes; use Ttypes; +with Validsw; use Validsw; with Warnsw; use Warnsw; with Ada.Unchecked_Deallocation; @@ -310,6 +310,15 @@ package body Switch.C is ("-gnatc must be first if combined with other switches"); end if; + -- Not allowed if previous -gnatR given + + if List_Representation_Info /= 0 + or else List_Representation_Info_Mechanisms + then + Osint.Fail + ("-gnatc not allowed since -gnatR given previously"); + end if; + Ptr := Ptr + 1; Operating_Mode := Check_Semantics; @@ -772,8 +781,9 @@ package body Switch.C is -- implicit setting here, since for example, we want -- Preelaborate_05 treated as Preelaborate - Ada_Version := Ada_2012; - Ada_Version_Explicit := Ada_Version; + Ada_Version := Ada_2012; + Ada_Version_Explicit := Ada_2012; + Ada_Version_Pragma := Empty; -- Set default warnings and style checks for -gnatg @@ -1013,6 +1023,14 @@ package body Switch.C is ("-gnatR not permitted since -gnatD given previously"); end if; + -- Not allowed if previous -gnatc was given, since we must + -- call the code generator to determine rep information. + + if Operating_Mode = Check_Semantics then + Osint.Fail + ("-gnatR not permitted since -gnatc given previously"); + end if; + -- Set to annotate rep info, and set default -gnatR mode Back_Annotate_Rep_Info := True; @@ -1197,6 +1215,7 @@ package body Switch.C is Extensions_Allowed := True; Ada_Version := Ada_Version_Type'Last; Ada_Version_Explicit := Ada_Version_Type'Last; + Ada_Version_Pragma := Empty; -- -gnaty (style checks) @@ -1309,8 +1328,9 @@ package body Switch.C is Bad_Switch ("-gnat8" & Switch_Chars (Ptr .. Max)); else Ptr := Ptr + 1; - Ada_Version := Ada_83; - Ada_Version_Explicit := Ada_Version; + Ada_Version := Ada_83; + Ada_Version_Explicit := Ada_83; + Ada_Version_Pragma := Empty; end if; -- -gnat95 @@ -1326,8 +1346,9 @@ package body Switch.C is Bad_Switch ("-gnat9" & Switch_Chars (Ptr .. Max)); else Ptr := Ptr + 1; - Ada_Version := Ada_95; - Ada_Version_Explicit := Ada_Version; + Ada_Version := Ada_95; + Ada_Version_Explicit := Ada_95; + Ada_Version_Pragma := Empty; end if; -- -gnat05 @@ -1343,8 +1364,9 @@ package body Switch.C is Bad_Switch ("-gnat0" & Switch_Chars (Ptr .. Max)); else Ptr := Ptr + 1; - Ada_Version := Ada_2005; - Ada_Version_Explicit := Ada_Version; + Ada_Version := Ada_2005; + Ada_Version_Explicit := Ada_2005; + Ada_Version_Pragma := Empty; end if; -- -gnat12 @@ -1360,8 +1382,9 @@ package body Switch.C is Bad_Switch ("-gnat1" & Switch_Chars (Ptr .. Max)); else Ptr := Ptr + 1; - Ada_Version := Ada_2012; - Ada_Version_Explicit := Ada_Version; + Ada_Version := Ada_2012; + Ada_Version_Explicit := Ada_2012; + Ada_Version_Pragma := Empty; end if; -- -gnat2005 and -gnat2012 @@ -1381,6 +1404,7 @@ package body Switch.C is end if; Ada_Version_Explicit := Ada_Version; + Ada_Version_Pragma := Empty; Ptr := Ptr + 4; -- Switch cancellation, currently only -gnat-p is allowed. diff --git a/gcc/ada/tree_io.ads b/gcc/ada/tree_io.ads index 3692d1ec650..bab7f9e6a4a 100644 --- a/gcc/ada/tree_io.ads +++ b/gcc/ada/tree_io.ads @@ -47,7 +47,7 @@ package Tree_IO is Tree_Format_Error : exception; -- Raised if a format error is detected in the input file - ASIS_Version_Number : constant := 32; + ASIS_Version_Number : constant := 33; -- ASIS Version. This is used to check for consistency between the compiler -- used to generate trees and an ASIS application that is reading the -- trees. It must be incremented whenever a change is made to the tree @@ -62,6 +62,8 @@ package Tree_IO is -- 31 Remove read/write of Debug_Pragmas_Disabled/Debug_Pragmas_Enabled -- 32 Change the way entities are changed through Next_Entity field in -- the hierarchy of child units + -- 33 Add copying subtrees for rewriting infix calls of operator + -- functions for the corresponding original nodes. procedure Tree_Read_Initialize (Desc : File_Descriptor); -- Called to initialize reading of a tree file. This call must be made diff --git a/gcc/ada/usage.adb b/gcc/ada/usage.adb index dd0f2af33e4..ffcd7246905 100644 --- a/gcc/ada/usage.adb +++ b/gcc/ada/usage.adb @@ -381,7 +381,8 @@ begin -- Lines for -gnatR switch Write_Switch_Char ("R?"); - Write_Line ("List rep info (?=0/1/2/3 for none/types/all/variable)"); + Write_Line + ("List rep info (?=0/1/2/3/m for none/types/all/variable/mechanisms)"); Write_Switch_Char ("R?s"); Write_Line ("List rep info to file.rep instead of standard output"); @@ -626,8 +627,8 @@ begin Write_Line (" l check reference manual layout"); Write_Line (" Lnn check max nest level < nn "); Write_Line (" m check line length <= 79 characters"); - Write_Line (" n check casing of package Standard identifiers"); Write_Line (" Mnn check line length <= nn characters"); + Write_Line (" n check casing of package Standard identifiers"); Write_Line (" N turn off all checks"); Write_Line (" o check subprogram bodies in alphabetical order"); Write_Line (" O check overriding indicators"); diff --git a/gcc/ada/vms_data.ads b/gcc/ada/vms_data.ads index 91ee51db119..f92788af69b 100644 --- a/gcc/ada/vms_data.ads +++ b/gcc/ada/vms_data.ads @@ -2299,7 +2299,11 @@ package VMS_Data is "SYMBOLIC " & "-gnatR3 " & "SYMBOLIC_FILE " & - "-gnatR3s"; + "-gnatR3s " & + "MECHANISMS " & + "-gnatRm " & + "MECHANISMS_FILE " & + "-gnatRms"; -- /NOREPRESENTATION_INFO (D) -- /REPRESENTATION_INFO[=(keyword[,...])] -- @@ -2330,6 +2334,13 @@ package VMS_Data is -- with the name 'file_rep' where 'file' is the name -- of the corresponding source file. -- + -- MECHANISMS List convention and argument passing mechanisms + -- for all subprograms + -- + -- MECHANISMS_FILE Similar to MECHANISMS, but the output is to a file + -- with the name 'file_rep' where file is the name + -- of the corresponding source file. + -- -- DEFAULT Equivalent to ARRAYS. S_GCC_RepinfX : aliased constant S := "/NOREPRESENTATION_INFO " & @@ -2491,7 +2502,7 @@ package VMS_Data is "XTRA_PARENS " & "-gnaty-x " & "NOXTRA_PARENS " & - "-gnaty-x "; + "-gnaty-x"; -- /NOSTYLE_CHECKS (D) -- /STYLE_CHECKS[=(keyword,[...])] -- diff --git a/gcc/ada/warnsw.adb b/gcc/ada/warnsw.adb index c194b3182c1..36360f96d63 100644 --- a/gcc/ada/warnsw.adb +++ b/gcc/ada/warnsw.adb @@ -25,9 +25,197 @@ with Err_Vars; use Err_Vars; with Opt; use Opt; -with Targparm; use Targparm; + package body Warnsw is + ---------------------- + -- Restore_Warnings -- + ---------------------- + + procedure Restore_Warnings (W : Warning_Record) is + begin + Address_Clause_Overlay_Warnings := + W.Address_Clause_Overlay_Warnings; + Check_Unreferenced := + W.Check_Unreferenced; + Check_Unreferenced_Formals := + W.Check_Unreferenced_Formals; + Check_Withs := + W.Check_Withs; + Constant_Condition_Warnings := + W.Constant_Condition_Warnings; + Elab_Warnings := + W.Elab_Warnings; + Implementation_Unit_Warnings := + W.Implementation_Unit_Warnings; + Ineffective_Inline_Warnings := + W.Ineffective_Inline_Warnings; + List_Inherited_Aspects := + W.List_Inherited_Aspects; + Warning_Doc_Switch := + W.Warning_Doc_Switch; + Warn_On_Ada_2005_Compatibility := + W.Warn_On_Ada_2005_Compatibility; + Warn_On_Ada_2012_Compatibility := + W.Warn_On_Ada_2012_Compatibility; + Warn_On_All_Unread_Out_Parameters := + W.Warn_On_All_Unread_Out_Parameters; + Warn_On_Assertion_Failure := + W.Warn_On_Assertion_Failure; + Warn_On_Assumed_Low_Bound := + W.Warn_On_Assumed_Low_Bound; + Warn_On_Atomic_Synchronization := + W.Warn_On_Atomic_Synchronization; + Warn_On_Bad_Fixed_Value := + W.Warn_On_Bad_Fixed_Value; + Warn_On_Biased_Representation := + W.Warn_On_Biased_Representation; + Warn_On_Constant := + W.Warn_On_Constant; + Warn_On_Deleted_Code := + W.Warn_On_Deleted_Code; + Warn_On_Dereference := + W.Warn_On_Dereference; + Warn_On_Export_Import := + W.Warn_On_Export_Import; + Warn_On_Hiding := + W.Warn_On_Hiding; + Warn_On_Modified_Unread := + W.Warn_On_Modified_Unread; + Warn_On_No_Value_Assigned := + W.Warn_On_No_Value_Assigned; + Warn_On_Non_Local_Exception := + W.Warn_On_Non_Local_Exception; + Warn_On_Object_Renames_Function := + W.Warn_On_Object_Renames_Function; + Warn_On_Obsolescent_Feature := + W.Warn_On_Obsolescent_Feature; + Warn_On_Overlap := + W.Warn_On_Overlap; + Warn_On_Overridden_Size := + W.Warn_On_Overridden_Size; + Warn_On_Parameter_Order := + W.Warn_On_Parameter_Order; + Warn_On_Questionable_Missing_Parens := + W.Warn_On_Questionable_Missing_Parens; + Warn_On_Record_Holes := + W.Warn_On_Record_Holes; + Warn_On_Redundant_Constructs := + W.Warn_On_Redundant_Constructs; + Warn_On_Reverse_Bit_Order := + W.Warn_On_Reverse_Bit_Order; + Warn_On_Standard_Redefinition := + W.Warn_On_Standard_Redefinition; + Warn_On_Suspicious_Contract := + W.Warn_On_Suspicious_Contract; + Warn_On_Unchecked_Conversion := + W.Warn_On_Unchecked_Conversion; + Warn_On_Unordered_Enumeration_Type := + W.Warn_On_Unordered_Enumeration_Type; + Warn_On_Unrecognized_Pragma := + W.Warn_On_Unrecognized_Pragma; + Warn_On_Unrepped_Components := + W.Warn_On_Unrepped_Components; + Warn_On_Warnings_Off := + W.Warn_On_Warnings_Off; + end Restore_Warnings; + + ------------------- + -- Save_Warnings -- + ------------------- + + function Save_Warnings return Warning_Record is + W : Warning_Record; + + begin + W.Address_Clause_Overlay_Warnings := + Address_Clause_Overlay_Warnings; + W.Check_Unreferenced := + Check_Unreferenced; + W.Check_Unreferenced_Formals := + Check_Unreferenced_Formals; + W.Check_Withs := + Check_Withs; + W.Constant_Condition_Warnings := + Constant_Condition_Warnings; + W.Elab_Warnings := + Elab_Warnings; + W.Implementation_Unit_Warnings := + Implementation_Unit_Warnings; + W.Ineffective_Inline_Warnings := + Ineffective_Inline_Warnings; + W.List_Inherited_Aspects := + List_Inherited_Aspects; + W.Warning_Doc_Switch := + Warning_Doc_Switch; + W.Warn_On_Ada_2005_Compatibility := + Warn_On_Ada_2005_Compatibility; + W.Warn_On_Ada_2012_Compatibility := + Warn_On_Ada_2012_Compatibility; + W.Warn_On_All_Unread_Out_Parameters := + Warn_On_All_Unread_Out_Parameters; + W.Warn_On_Assertion_Failure := + Warn_On_Assertion_Failure; + W.Warn_On_Assumed_Low_Bound := + Warn_On_Assumed_Low_Bound; + W.Warn_On_Atomic_Synchronization := + Warn_On_Atomic_Synchronization; + W.Warn_On_Bad_Fixed_Value := + Warn_On_Bad_Fixed_Value; + W.Warn_On_Biased_Representation := + Warn_On_Biased_Representation; + W.Warn_On_Constant := + Warn_On_Constant; + W.Warn_On_Deleted_Code := + Warn_On_Deleted_Code; + W.Warn_On_Dereference := + Warn_On_Dereference; + W.Warn_On_Export_Import := + Warn_On_Export_Import; + W.Warn_On_Hiding := + Warn_On_Hiding; + W.Warn_On_Modified_Unread := + Warn_On_Modified_Unread; + W.Warn_On_No_Value_Assigned := + Warn_On_No_Value_Assigned; + W.Warn_On_Non_Local_Exception := + Warn_On_Non_Local_Exception; + W.Warn_On_Object_Renames_Function := + Warn_On_Object_Renames_Function; + W.Warn_On_Obsolescent_Feature := + Warn_On_Obsolescent_Feature; + W.Warn_On_Overlap := + Warn_On_Overlap; + W.Warn_On_Overridden_Size := + Warn_On_Overridden_Size; + W.Warn_On_Parameter_Order := + Warn_On_Parameter_Order; + W.Warn_On_Questionable_Missing_Parens := + Warn_On_Questionable_Missing_Parens; + W.Warn_On_Record_Holes := + Warn_On_Record_Holes; + W.Warn_On_Redundant_Constructs := + Warn_On_Redundant_Constructs; + W.Warn_On_Reverse_Bit_Order := + Warn_On_Reverse_Bit_Order; + W.Warn_On_Standard_Redefinition := + Warn_On_Standard_Redefinition; + W.Warn_On_Suspicious_Contract := + Warn_On_Suspicious_Contract; + W.Warn_On_Unchecked_Conversion := + Warn_On_Unchecked_Conversion; + W.Warn_On_Unordered_Enumeration_Type := + Warn_On_Unordered_Enumeration_Type; + W.Warn_On_Unrecognized_Pragma := + Warn_On_Unrecognized_Pragma; + W.Warn_On_Unrepped_Components := + Warn_On_Unrepped_Components; + W.Warn_On_Warnings_Off := + Warn_On_Warnings_Off; + + return W; + end Save_Warnings; + ---------------------------- -- Set_Dot_Warning_Switch -- ---------------------------- @@ -54,17 +242,9 @@ package body Warnsw is Warn_On_Unrepped_Components := False; when 'd' => - if OpenVMS_On_Target then - return False; - end if; - Warning_Doc_Switch := True; when 'D' => - if OpenVMS_On_Target then - return False; - end if; - Warning_Doc_Switch := False; when 'e' => @@ -77,11 +257,7 @@ package body Warnsw is Implementation_Unit_Warnings := True; Ineffective_Inline_Warnings := True; List_Inherited_Aspects := True; - - if not OpenVMS_On_Target then - Warning_Doc_Switch := True; - end if; - + Warning_Doc_Switch := True; Warn_On_Ada_2005_Compatibility := True; Warn_On_Ada_2012_Compatibility := True; Warn_On_All_Unread_Out_Parameters := True; diff --git a/gcc/ada/warnsw.ads b/gcc/ada/warnsw.ads index 45983e95114..b39f545802d 100644 --- a/gcc/ada/warnsw.ads +++ b/gcc/ada/warnsw.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1999-2012, Free Software Foundation, Inc. -- +-- Copyright (C) 1999-2013, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -35,7 +35,8 @@ package Warnsw is -- whether warnings of a given class will be generated or not. -- Note: most of these flags are still in opt, but the plan is to move them - -- here as time goes by. + -- here as time goes by. And in fact a really nice idea would be to put + -- them all in a Warn_Record so that they would be easy to save/restore. Warn_On_Record_Holes : Boolean := False; -- Warn when explicit record component clauses leave uncovered holes (gaps) @@ -52,6 +53,63 @@ package Warnsw is -- Standard. Off by default, modified by use of -gnatw.k/.K, but not -- affected by -gnatwa. + ----------------------------------- + -- Saving and Restoring Warnings -- + ----------------------------------- + + -- Type used to save and restore warnings + + type Warning_Record is record + Address_Clause_Overlay_Warnings : Boolean; + Check_Unreferenced : Boolean; + Check_Unreferenced_Formals : Boolean; + Check_Withs : Boolean; + Constant_Condition_Warnings : Boolean; + Elab_Warnings : Boolean; + Implementation_Unit_Warnings : Boolean; + Ineffective_Inline_Warnings : Boolean; + List_Inherited_Aspects : Boolean; + Warning_Doc_Switch : Boolean; + Warn_On_Ada_2005_Compatibility : Boolean; + Warn_On_Ada_2012_Compatibility : Boolean; + Warn_On_All_Unread_Out_Parameters : Boolean; + Warn_On_Assertion_Failure : Boolean; + Warn_On_Assumed_Low_Bound : Boolean; + Warn_On_Atomic_Synchronization : Boolean; + Warn_On_Bad_Fixed_Value : Boolean; + Warn_On_Biased_Representation : Boolean; + Warn_On_Constant : Boolean; + Warn_On_Deleted_Code : Boolean; + Warn_On_Dereference : Boolean; + Warn_On_Export_Import : Boolean; + Warn_On_Hiding : Boolean; + Warn_On_Modified_Unread : Boolean; + Warn_On_No_Value_Assigned : Boolean; + Warn_On_Non_Local_Exception : Boolean; + Warn_On_Object_Renames_Function : Boolean; + Warn_On_Obsolescent_Feature : Boolean; + Warn_On_Overlap : Boolean; + Warn_On_Overridden_Size : Boolean; + Warn_On_Parameter_Order : Boolean; + Warn_On_Questionable_Missing_Parens : Boolean; + Warn_On_Record_Holes : Boolean; + Warn_On_Redundant_Constructs : Boolean; + Warn_On_Reverse_Bit_Order : Boolean; + Warn_On_Standard_Redefinition : Boolean; + Warn_On_Suspicious_Contract : Boolean; + Warn_On_Unchecked_Conversion : Boolean; + Warn_On_Unordered_Enumeration_Type : Boolean; + Warn_On_Unrecognized_Pragma : Boolean; + Warn_On_Unrepped_Components : Boolean; + Warn_On_Warnings_Off : Boolean; + end record; + + function Save_Warnings return Warning_Record; + -- Returns current settingh of warnings + + procedure Restore_Warnings (W : Warning_Record); + -- Restores current settings of warning flags from W + ----------------- -- Subprograms -- ----------------- diff --git a/gcc/alias.c b/gcc/alias.c index aa79248d471..7a1774c919a 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -44,7 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "df.h" #include "tree-ssa-alias.h" #include "pointer-set.h" -#include "tree-flow.h" +#include "tree-ssa.h" /* The aliasing API provided here solves related but different problems: @@ -1894,7 +1894,7 @@ addr_side_effect_eval (rtx addr, int size, int n_refs) if (offset) addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0), - GEN_INT (offset)); + gen_int_mode (offset, GET_MODE (addr))); else addr = XEXP (addr, 0); addr = canon_rtx (addr); diff --git a/gcc/asan.c b/gcc/asan.c index d7bab697350..67b8d9c1ac4 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "gimple.h" #include "tree-iterator.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "asan.h" #include "gimple-pretty-print.h" @@ -869,7 +869,7 @@ asan_shadow_cst (unsigned char shadow_bytes[4]) for (i = 0; i < 4; i++) val |= (unsigned HOST_WIDE_INT) shadow_bytes[BYTES_BIG_ENDIAN ? 3 - i : i] << (BITS_PER_UNIT * i); - return GEN_INT (trunc_int_for_mode (val, SImode)); + return gen_int_mode (val, SImode); } /* Clear shadow memory at SHADOW_MEM, LEN bytes. Can't call a library call here @@ -901,7 +901,7 @@ asan_clear_shadow (rtx shadow_mem, HOST_WIDE_INT len) emit_label (top_label); emit_move_insn (shadow_mem, const0_rtx); - tmp = expand_simple_binop (Pmode, PLUS, addr, GEN_INT (4), addr, + tmp = expand_simple_binop (Pmode, PLUS, addr, gen_int_mode (4, Pmode), addr, true, OPTAB_LIB_WIDEN); if (tmp != addr) emit_move_insn (addr, tmp); @@ -966,17 +966,19 @@ asan_emit_stack_protection (rtx base, HOST_WIDE_INT *offsets, tree *decls, str_cst = asan_pp_string (&asan_pp); /* Emit the prologue sequence. */ - base = expand_binop (Pmode, add_optab, base, GEN_INT (base_offset), + base = expand_binop (Pmode, add_optab, base, + gen_int_mode (base_offset, Pmode), NULL_RTX, 1, OPTAB_DIRECT); mem = gen_rtx_MEM (ptr_mode, base); - emit_move_insn (mem, GEN_INT (ASAN_STACK_FRAME_MAGIC)); + emit_move_insn (mem, gen_int_mode (ASAN_STACK_FRAME_MAGIC, ptr_mode)); mem = adjust_address (mem, VOIDmode, GET_MODE_SIZE (ptr_mode)); emit_move_insn (mem, expand_normal (str_cst)); shadow_base = expand_binop (Pmode, lshr_optab, base, GEN_INT (ASAN_SHADOW_SHIFT), NULL_RTX, 1, OPTAB_DIRECT); shadow_base = expand_binop (Pmode, add_optab, shadow_base, - GEN_INT (targetm.asan_shadow_offset ()), + gen_int_mode (targetm.asan_shadow_offset (), + Pmode), NULL_RTX, 1, OPTAB_DIRECT); gcc_assert (asan_shadow_set != -1 && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4); diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 43174553133..ad04d4de83e 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -465,6 +465,23 @@ struct edge_list edge *index_to_edge; }; +/* Class to compute and manage control dependences on an edge-list. */ +class control_dependences +{ +public: + control_dependences (edge_list *); + ~control_dependences (); + bitmap get_edges_dependent_on (int); + edge get_edge (int); + +private: + void set_control_dependence_map_bit (basic_block, int); + void clear_control_dependence_bitmap (basic_block); + void find_control_dependence (int); + vec<bitmap> control_dependence_map; + edge_list *el; +}; + /* The base value for branch probability notes and edge probabilities. */ #define REG_BR_PROB_BASE 10000 diff --git a/gcc/builtins.c b/gcc/builtins.c index 718128160e9..45bf6ceaaa7 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -44,7 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "basic-block.h" #include "tree-mudflap.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "value-prof.h" #include "diagnostic-core.h" #include "builtins.h" @@ -1974,7 +1974,8 @@ expand_errno_check (tree exp, rtx target) rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno")); #endif - emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM)); + emit_move_insn (errno_rtx, + gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx))); emit_label (lab); return; } @@ -4869,8 +4870,8 @@ round_trampoline_addr (rtx tramp) /* Round address up to desired boundary. */ temp = gen_reg_rtx (Pmode); - addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1); - mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT); + addend = gen_int_mode (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1, Pmode); + mask = gen_int_mode (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT, Pmode); temp = expand_simple_binop (Pmode, PLUS, tramp, addend, temp, 0, OPTAB_LIB_WIDEN); @@ -10234,7 +10235,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 2a0c4061198..1772ba56b49 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,33 @@ +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 + * c.opt (fgnu-runtime, fnext-runtime, fobjc-abi-version, + fobjc-gc, freplace-objc-classes): Accept for LTO. + +2013-09-13 Jacek Caban <jacek@codeweavers.com> + + * c-target.def: New hook + +2013-09-09 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/43452 + * c.opt (Wdelete-incomplete): Add. + +2013-09-08 Joern Rennecke <joern.rennecke@embecosm.com> + + * c-common.c (same_scalar_type_ignoring_signedness): Delete. + (vector_types_compatible_elements_p): New function. + * c-common.h: (same_scalar_type_ignoring_signedness): Delete + declaration. + (vector_types_compatible_elements_p): Declare. + 2013-09-04 Gabriel Dos Reis <gdr@integrable-solutions.net> * c-pretty-print.h (c_pretty_printer::simple_type_specifier): Now diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 3d049ac8f52..49c191d704a 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -312,6 +312,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 *); @@ -723,6 +725,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, @@ -2200,6 +2205,14 @@ check_main_parameter_types (tree decl) "%q+D takes only zero or two arguments", decl); } +/* vector_targets_convertible_p is used for vector pointer types. The + callers perform various checks that the qualifiers are satisfactory, + while OTOH vector_targets_convertible_p ignores the number of elements + in the vectors. That's fine with vector pointers as we can consider, + say, a vector of 8 elements as two consecutive vectors of 4 elements, + and that does not require and conversion of the pointer values. + In contrast, vector_types_convertible_p and + vector_types_compatible_elements_p are used for vector value types. */ /* True if pointers to distinct types T1 and T2 can be converted to each other without an explicit cast. Only returns true for opaque vector types. */ @@ -2214,6 +2227,17 @@ vector_targets_convertible_p (const_tree t1, const_tree t2) return false; } +/* vector_types_convertible_p is used for vector value types. + It could in principle call vector_targets_convertible_p as a subroutine, + but then the check for vector type would be duplicated with its callers, + and also the purpose of vector_targets_convertible_p would become + muddled. + Where vector_types_convertible_p returns true, a conversion might still be + needed to make the types match. + In contrast, vector_targets_convertible_p is used for vector pointer + values, and vector_types_compatible_elements_p is used specifically + in the context for binary operators, as a check if use is possible without + conversion. */ /* True if vector types T1 and T2 can be converted to each other without an explicit cast. If EMIT_LAX_NOTE is true, and T1 and T2 can only be converted with -flax-vector-conversions yet that is not @@ -6549,6 +6573,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. */ @@ -10682,20 +10722,45 @@ resolve_overloaded_builtin (location_t loc, tree function, } } -/* Ignoring their sign, return true if two scalar types are the same. */ +/* vector_types_compatible_elements_p is used in type checks of vectors + values used as operands of binary operators. Where it returns true, and + the other checks of the caller succeed (being vector types in he first + place, and matching number of elements), we can just treat the types + as essentially the same. + Contrast with vector_targets_convertible_p, which is used for vector + pointer types, and vector_types_convertible_p, which will allow + language-specific matches under the control of flag_lax_vector_conversions, + and might still require a conversion. */ +/* True if vector types T1 and T2 can be inputs to the same binary + operator without conversion. + We don't check the overall vector size here because some of our callers + want to give different error messages when the vectors are compatible + except for the element count. */ + bool -same_scalar_type_ignoring_signedness (tree t1, tree t2) +vector_types_compatible_elements_p (tree t1, tree t2) { + bool opaque = TYPE_VECTOR_OPAQUE (t1) || TYPE_VECTOR_OPAQUE (t2); + t1 = TREE_TYPE (t1); + t2 = TREE_TYPE (t2); + enum tree_code c1 = TREE_CODE (t1), c2 = TREE_CODE (t2); gcc_assert ((c1 == INTEGER_TYPE || c1 == REAL_TYPE || c1 == FIXED_POINT_TYPE) && (c2 == INTEGER_TYPE || c2 == REAL_TYPE || c2 == FIXED_POINT_TYPE)); + t1 = c_common_signed_type (t1); + t2 = c_common_signed_type (t2); /* Equality works here because c_common_signed_type uses TYPE_MAIN_VARIANT. */ - return c_common_signed_type (t1) - == c_common_signed_type (t2); + if (t1 == t2) + return true; + if (opaque && c1 == c2 + && (c1 == INTEGER_TYPE || c1 == REAL_TYPE) + && TYPE_PRECISION (t1) == TYPE_PRECISION (t2)) + return true; + return false; } /* Check for missing format attributes on function pointers. LTYPE is diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index cc09dbc008f..722ba6e5c15 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -766,7 +766,7 @@ extern void warn_logical_operator (location_t, enum tree_code, tree, enum tree_code, tree, enum tree_code, tree); extern void check_main_parameter_types (tree decl); extern bool c_determine_visibility (tree); -extern bool same_scalar_type_ignoring_signedness (tree, tree); +extern bool vector_types_compatible_elements_p (tree, tree); extern void mark_valid_location_for_stdc_pragma (bool); extern bool valid_location_for_stdc_pragma_p (void); extern void set_float_const_decimal64 (void); diff --git a/gcc/c-family/c-target.def b/gcc/c-family/c-target.def index 80042df40e7..925dbd14cc4 100644 --- a/gcc/c-family/c-target.def +++ b/gcc/c-family/c-target.def @@ -102,5 +102,15 @@ DEFHOOK than just the compiler.", const char *, (void), hook_constcharptr_void_null) + +DEFHOOK +(cxx_implicit_extern_c, + "Define this hook to add target-specific C++ implicit extern C functions.\ + If this function returns true for the name of a file-scope function, that\ + function implicitly gets extern \"C\" linkage rather than whatever language\ + linkage the declaration would normally have. An example of such function\ + is WinMain on Win32 targets.", + bool, (const char*), + NULL) HOOK_VECTOR_END (C90_EMPTY_HACK) diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 9690a087fd3..24d1b87d11f 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -339,6 +339,10 @@ Wdeclaration-after-statement C ObjC Var(warn_declaration_after_statement) Warning Warn when a declaration is found after a statement +Wdelete-incomplete +C++ ObjC++ Var(warn_delete_incomplete) Init(1) Warning +Warn when deleting a pointer to incomplete type + Wdelete-non-virtual-dtor C++ ObjC++ Var(warn_delnonvdtor) Warning LangEnabledBy(C++ ObjC++,Wall) Warn about deleting polymorphic objects with non-virtual destructors @@ -941,7 +945,7 @@ C++ ObjC++ Var(flag_no_gnu_keywords, 0) Recognize GNU-defined keywords fgnu-runtime -ObjC ObjC++ Report RejectNegative Var(flag_next_runtime,0) Init(NEXT_OBJC_RUNTIME) +ObjC ObjC++ LTO Report RejectNegative Var(flag_next_runtime,0) Init(NEXT_OBJC_RUNTIME) Generate code for GNU runtime environment fgnu89-inline @@ -1015,7 +1019,7 @@ fnew-abi C++ ObjC++ Ignore Warn(switch %qs is no longer supported) fnext-runtime -ObjC ObjC++ Report RejectNegative Var(flag_next_runtime) +ObjC ObjC++ LTO Report RejectNegative Var(flag_next_runtime) Generate code for NeXT (Apple Mac OS X) runtime environment fnil-receivers @@ -1033,7 +1037,7 @@ C++ ObjC++ Optimization Var(flag_nothrow_opt) Treat a throw() exception specification as noexcept to improve code size fobjc-abi-version= -ObjC ObjC++ Joined Report RejectNegative UInteger Var(flag_objc_abi) +ObjC ObjC++ LTO Joined Report RejectNegative UInteger Var(flag_objc_abi) Specify which ABI to use for Objective-C family code and meta-data generation. ; Generate special '- .cxx_construct' and '- .cxx_destruct' methods @@ -1053,7 +1057,7 @@ ObjC ObjC++ Var(flag_objc_exceptions) Enable Objective-C exception and synchronization syntax fobjc-gc -ObjC ObjC++ Var(flag_objc_gc) +ObjC ObjC++ LTO Var(flag_objc_gc) Enable garbage collection (GC) in Objective-C/Objective-C++ programs fobjc-nilcheck @@ -1113,7 +1117,7 @@ C++ ObjC++ Var(flag_pretty_templates) Init(1) -fno-pretty-templates Do not pretty-print template specializations as the template signature followed by the arguments freplace-objc-classes -ObjC ObjC++ Var(flag_replace_objc_classes) +ObjC ObjC++ LTO Var(flag_replace_objc_classes) Used in Fix-and-Continue mode to indicate that object files may be swapped in at runtime frepo diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 3401228c039..81b2018e8c0 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,26 @@ +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 + * c-decl.c (c_builtin_function_ext_scope): Remove + wrong assumption that it is never called on prexisting + symbol. + +2013-09-08 Joern Rennecke <joern.rennecke@embecosm.com> + + * c-typeck.c (build_binary_op): Use vector_types_compatible_elements_p. + 2013-09-03 Gabriel Dos Reis <gdr@integrable-solutions.net> * c-objc-common.c (c_tree_printer): Tidy. diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 321ae0bf53c..5c90f09e85e 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -3629,9 +3629,6 @@ c_builtin_function_ext_scope (tree decl) const char *name = IDENTIFIER_POINTER (id); C_DECL_BUILTIN_PROTOTYPE (decl) = prototype_p (type); - /* Should never be called on a symbol with a preexisting meaning. */ - gcc_assert (!I_SYMBOL_BINDING (id)); - bind (id, decl, external_scope, /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION); diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index de654e6701d..14d5979624d 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -9989,7 +9989,7 @@ build_binary_op (location_t location, enum tree_code code, if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE) { tree intt; - if (TREE_TYPE (type0) != TREE_TYPE (type1)) + if (!vector_types_compatible_elements_p (type0, type1)) { error_at (location, "comparing vectors with different " "element types"); @@ -10126,7 +10126,7 @@ build_binary_op (location_t location, enum tree_code code, if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE) { tree intt; - if (TREE_TYPE (type0) != TREE_TYPE (type1)) + if (!vector_types_compatible_elements_p (type0, type1)) { error_at (location, "comparing vectors with different " "element types"); @@ -10232,8 +10232,7 @@ build_binary_op (location_t location, enum tree_code code, if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE && (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1)) - || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0), - TREE_TYPE (type1)))) + || !vector_types_compatible_elements_p (type0, type1))) { binary_op_error (location, code, type0, type1); return error_mark_node; @@ -10499,8 +10498,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. */ @@ -10508,9 +10509,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); } @@ -10538,7 +10539,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/caller-save.c b/gcc/caller-save.c index 5e65294375e..b134cde1131 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -239,7 +239,7 @@ init_caller_save (void) for (offset = 1 << (HOST_BITS_PER_INT / 2); offset; offset >>= 1) { - address = gen_rtx_PLUS (Pmode, addr_reg, GEN_INT (offset)); + address = gen_rtx_PLUS (Pmode, addr_reg, gen_int_mode (offset, Pmode)); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (regno_save_mode[i][1] != VOIDmode diff --git a/gcc/calls.c b/gcc/calls.c index 0c7f22566bc..3930d5e170a 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -40,7 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "except.h" #include "dbgcnt.h" -#include "tree-flow.h" +#include "tree-ssa.h" /* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits. */ #define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) diff --git a/gcc/cfganal.c b/gcc/cfganal.c index 63d17cede2b..c4ea7dd0a1f 100644 --- a/gcc/cfganal.c +++ b/gcc/cfganal.c @@ -340,6 +340,120 @@ verify_edge_list (FILE *f, struct edge_list *elist) } } + +/* Functions to compute control dependences. */ + +/* Indicate block BB is control dependent on an edge with index EDGE_INDEX. */ +void +control_dependences::set_control_dependence_map_bit (basic_block bb, + int edge_index) +{ + if (bb == ENTRY_BLOCK_PTR) + return; + gcc_assert (bb != EXIT_BLOCK_PTR); + bitmap_set_bit (control_dependence_map[bb->index], edge_index); +} + +/* Clear all control dependences for block BB. */ +void +control_dependences::clear_control_dependence_bitmap (basic_block bb) +{ + bitmap_clear (control_dependence_map[bb->index]); +} + +/* Find the immediate postdominator PDOM of the specified basic block BLOCK. + This function is necessary because some blocks have negative numbers. */ + +static inline basic_block +find_pdom (basic_block block) +{ + gcc_assert (block != ENTRY_BLOCK_PTR); + + if (block == EXIT_BLOCK_PTR) + return EXIT_BLOCK_PTR; + else + { + basic_block bb = get_immediate_dominator (CDI_POST_DOMINATORS, block); + if (! bb) + return EXIT_BLOCK_PTR; + return bb; + } +} + +/* Determine all blocks' control dependences on the given edge with edge_list + EL index EDGE_INDEX, ala Morgan, Section 3.6. */ + +void +control_dependences::find_control_dependence (int edge_index) +{ + basic_block current_block; + basic_block ending_block; + + gcc_assert (INDEX_EDGE_PRED_BB (el, edge_index) != EXIT_BLOCK_PTR); + + if (INDEX_EDGE_PRED_BB (el, edge_index) == ENTRY_BLOCK_PTR) + ending_block = single_succ (ENTRY_BLOCK_PTR); + else + ending_block = find_pdom (INDEX_EDGE_PRED_BB (el, edge_index)); + + for (current_block = INDEX_EDGE_SUCC_BB (el, edge_index); + current_block != ending_block && current_block != EXIT_BLOCK_PTR; + current_block = find_pdom (current_block)) + { + edge e = INDEX_EDGE (el, edge_index); + + /* For abnormal edges, we don't make current_block control + dependent because instructions that throw are always necessary + anyway. */ + if (e->flags & EDGE_ABNORMAL) + continue; + + set_control_dependence_map_bit (current_block, edge_index); + } +} + +/* Record all blocks' control dependences on all edges in the edge + list EL, ala Morgan, Section 3.6. */ + +control_dependences::control_dependences (struct edge_list *edges) + : el (edges) +{ + timevar_push (TV_CONTROL_DEPENDENCES); + control_dependence_map.create (last_basic_block); + for (int i = 0; i < last_basic_block; ++i) + control_dependence_map.quick_push (BITMAP_ALLOC (NULL)); + for (int i = 0; i < NUM_EDGES (el); ++i) + find_control_dependence (i); + timevar_pop (TV_CONTROL_DEPENDENCES); +} + +/* Free control dependences and the associated edge list. */ + +control_dependences::~control_dependences () +{ + for (unsigned i = 0; i < control_dependence_map.length (); ++i) + BITMAP_FREE (control_dependence_map[i]); + control_dependence_map.release (); + free_edge_list (el); +} + +/* Returns the bitmap of edges the basic-block I is dependent on. */ + +bitmap +control_dependences::get_edges_dependent_on (int i) +{ + return control_dependence_map[i]; +} + +/* Returns the edge with index I from the edge list. */ + +edge +control_dependences::get_edge (int i) +{ + return INDEX_EDGE (el, i); +} + + /* Given PRED and SUCC blocks, return the edge which connects the blocks. If no such edge exists, return NULL. */ diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 6836a9e6e84..e88fe2ed500 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -925,6 +925,24 @@ merge_memattrs (rtx x, rtx y) set_mem_align (y, MEM_ALIGN (x)); } } + if (code == MEM) + { + if (MEM_READONLY_P (x) != MEM_READONLY_P (y)) + { + MEM_READONLY_P (x) = 0; + MEM_READONLY_P (y) = 0; + } + if (MEM_NOTRAP_P (x) != MEM_NOTRAP_P (y)) + { + MEM_NOTRAP_P (x) = 0; + MEM_NOTRAP_P (y) = 0; + } + if (MEM_VOLATILE_P (x) != MEM_VOLATILE_P (y)) + { + MEM_VOLATILE_P (x) = 1; + MEM_VOLATILE_P (y) = 1; + } + } fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index cc21490df47..3f5391b73a5 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "expr.h" #include "langhooks.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "except.h" #include "flags.h" @@ -3154,7 +3154,12 @@ expand_debug_expr (tree exp) && GET_MODE (op0) != VOIDmode && GET_MODE (op1) != VOIDmode && GET_MODE (op0) != GET_MODE (op1)) { - if (GET_MODE_BITSIZE (GET_MODE (op0)) < GET_MODE_BITSIZE (GET_MODE (op1))) + if (GET_MODE_BITSIZE (GET_MODE (op0)) < GET_MODE_BITSIZE (GET_MODE (op1)) + /* If OP0 is a partial mode, then we must truncate, even if it has + the same bitsize as OP1 as GCC's representation of partial modes + is opaque. */ + || (GET_MODE_CLASS (GET_MODE (op0)) == MODE_PARTIAL_INT + && GET_MODE_BITSIZE (GET_MODE (op0)) == GET_MODE_BITSIZE (GET_MODE (op1)))) op1 = simplify_gen_unary (TRUNCATE, GET_MODE (op0), op1, GET_MODE (op1)); else diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index 8331fa0e956..a4248354d97 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "rtl.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "timevar.h" #include "diagnostic-core.h" #include "cfgloop.h" diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c index 11e8e36f6eb..f23eacd6454 100644 --- a/gcc/cfgloop.c +++ b/gcc/cfgloop.c @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-core.h" #include "flags.h" #include "tree.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "pointer-set.h" #include "ggc.h" #include "dumpfile.h" diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c index f35e5aedc79..ed8a2075f7a 100644 --- a/gcc/cfgloopmanip.c +++ b/gcc/cfgloopmanip.c @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "rtl.h" #include "basic-block.h" #include "cfgloop.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "dumpfile.h" static void copy_loops_to (struct loop **, int, @@ -223,15 +223,22 @@ fix_bb_placements (basic_block from, if (!fix_loop_placement (from->loop_father, irred_invalidated)) continue; target_loop = loop_outer (from->loop_father); + if (loop_closed_ssa_invalidated) + { + basic_block *bbs = get_loop_body (from->loop_father); + for (unsigned i = 0; i < from->loop_father->num_nodes; ++i) + bitmap_set_bit (loop_closed_ssa_invalidated, bbs[i]->index); + free (bbs); + } } else { /* Ordinary basic block. */ if (!fix_bb_placement (from)) continue; + target_loop = from->loop_father; if (loop_closed_ssa_invalidated) bitmap_set_bit (loop_closed_ssa_invalidated, from->index); - target_loop = from->loop_father; } FOR_EACH_EDGE (e, ei, from->succs) diff --git a/gcc/cgraph.c b/gcc/cgraph.c index c3992a6cc4c..4875223edaa 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -42,7 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple.h" #include "timevar.h" #include "dumpfile.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "value-prof.h" #include "except.h" #include "diagnostic-core.h" @@ -869,12 +869,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; } @@ -1224,13 +1224,13 @@ cgraph_resolve_speculation (struct cgraph_edge *edge, tree callee_decl) edge->frequency = CGRAPH_FREQ_MAX; edge->speculative = false; e2->speculative = false; + ipa_remove_reference (ref); if (e2->indirect_unknown_callee || e2->inline_failed) cgraph_remove_edge (e2); else cgraph_remove_node_and_inline_clones (e2->callee, NULL); if (edge->caller->call_site_hash) cgraph_update_edge_in_call_site_hash (edge); - ipa_remove_reference (ref); return edge; } @@ -2047,6 +2047,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/cgraph.h b/gcc/cgraph.h index ea8a04dbd19..50e8743bbf7 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -627,6 +627,7 @@ bool symtab_for_node_and_aliases (symtab_node, bool); symtab_node symtab_nonoverwritable_alias (symtab_node); enum availability symtab_node_availability (symtab_node); +bool symtab_semantically_equivalent_p (symtab_node, symtab_node); /* In cgraph.c */ void dump_cgraph (FILE *); @@ -700,12 +701,14 @@ void cgraph_mark_address_taken_node (struct cgraph_node *); typedef void (*cgraph_edge_hook)(struct cgraph_edge *, void *); typedef void (*cgraph_node_hook)(struct cgraph_node *, void *); +typedef void (*varpool_node_hook)(struct varpool_node *, void *); typedef void (*cgraph_2edge_hook)(struct cgraph_edge *, struct cgraph_edge *, void *); typedef void (*cgraph_2node_hook)(struct cgraph_node *, struct cgraph_node *, void *); struct cgraph_edge_hook_list; struct cgraph_node_hook_list; +struct varpool_node_hook_list; struct cgraph_2edge_hook_list; struct cgraph_2node_hook_list; struct cgraph_edge_hook_list *cgraph_add_edge_removal_hook (cgraph_edge_hook, void *); @@ -713,9 +716,15 @@ void cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *); struct cgraph_node_hook_list *cgraph_add_node_removal_hook (cgraph_node_hook, void *); void cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *); +struct varpool_node_hook_list *varpool_add_node_removal_hook (varpool_node_hook, + void *); +void varpool_remove_node_removal_hook (struct varpool_node_hook_list *); struct cgraph_node_hook_list *cgraph_add_function_insertion_hook (cgraph_node_hook, void *); void cgraph_remove_function_insertion_hook (struct cgraph_node_hook_list *); +struct varpool_node_hook_list *varpool_add_variable_insertion_hook (varpool_node_hook, + void *); +void varpool_remove_variable_insertion_hook (struct varpool_node_hook_list *); void cgraph_call_function_insertion_hooks (struct cgraph_node *node); struct cgraph_2edge_hook_list *cgraph_add_edge_duplication_hook (cgraph_2edge_hook, void *); void cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *); @@ -748,7 +757,7 @@ void fixup_same_cpp_alias_visibility (symtab_node, symtab_node target, tree); IN_SSA is true if the gimple is in SSA. */ basic_block init_lowered_empty_function (tree, bool); void cgraph_reset_node (struct cgraph_node *); -void expand_thunk (struct cgraph_node *); +bool expand_thunk (struct cgraph_node *, bool); /* In cgraphclones.c */ diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c index b9c112fef4d..98fd12cbb13 100644 --- a/gcc/cgraphbuild.c +++ b/gcc/cgraphbuild.c @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "langhooks.h" #include "pointer-set.h" #include "cgraph.h" diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index 54b97b91c78..e1aa120dce4 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -70,7 +70,7 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "tree.h" #include "rtl.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-inline.h" #include "langhooks.h" #include "pointer-set.h" diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index e3d4b60efec..0a8f9b0e834 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -164,7 +164,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "output.h" #include "rtl.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-inline.h" #include "langhooks.h" #include "pointer-set.h" @@ -592,15 +592,21 @@ analyze_function (struct cgraph_node *node) location_t saved_loc = input_location; input_location = DECL_SOURCE_LOCATION (decl); - if (node->symbol.alias) - symtab_resolve_alias - ((symtab_node) node, (symtab_node) cgraph_get_node (node->symbol.alias_target)); - else if (node->thunk.thunk_p) + if (node->thunk.thunk_p) { cgraph_create_edge (node, cgraph_get_node (node->thunk.alias), - NULL, 0, CGRAPH_FREQ_BASE); + NULL, 0, CGRAPH_FREQ_BASE); + if (!expand_thunk (node, false)) + { + node->thunk.alias = NULL; + node->symbol.analyzed = true; + return; + } node->thunk.alias = NULL; } + if (node->symbol.alias) + symtab_resolve_alias + ((symtab_node) node, (symtab_node) cgraph_get_node (node->symbol.alias_target)); else if (node->dispatcher_function) { /* Generate the dispatcher body of multi-versioned functions. */ @@ -821,6 +827,82 @@ varpool_finalize_decl (tree decl) varpool_assemble_decl (node); } +/* EDGE is an polymorphic call. Mark all possible targets as reachable + and if there is only one target, perform trivial devirtualization. + REACHABLE_CALL_TARGETS collects target lists we already walked to + avoid udplicate work. */ + +static void +walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets, + struct cgraph_edge *edge) +{ + unsigned int i; + void *cache_token; + bool final; + vec <cgraph_node *>targets + = possible_polymorphic_call_targets + (edge, &final, &cache_token); + + if (!pointer_set_insert (reachable_call_targets, + cache_token)) + { + if (cgraph_dump_file) + dump_possible_polymorphic_call_targets + (cgraph_dump_file, edge); + + for (i = 0; i < targets.length(); i++) + { + /* Do not bother to mark virtual methods in anonymous namespace; + either we will find use of virtual table defining it, or it is + unused. */ + if (targets[i]->symbol.definition + && TREE_CODE + (TREE_TYPE (targets[i]->symbol.decl)) + == METHOD_TYPE + && !type_in_anonymous_namespace_p + (method_class_type + (TREE_TYPE (targets[i]->symbol.decl)))) + enqueue_node ((symtab_node) targets[i]); + } + } + + /* Very trivial devirtualization; when the type is + final or anonymous (so we know all its derivation) + and there is only one possible virtual call target, + make the edge direct. */ + if (final) + { + if (targets.length() <= 1) + { + cgraph_node *target; + if (targets.length () == 1) + target = targets[0]; + else + target = cgraph_get_create_node + (builtin_decl_implicit (BUILT_IN_UNREACHABLE)); + + if (cgraph_dump_file) + { + fprintf (cgraph_dump_file, + "Devirtualizing call: "); + print_gimple_stmt (cgraph_dump_file, + edge->call_stmt, 0, + TDF_SLIM); + } + cgraph_make_edge_direct (edge, target); + cgraph_redirect_edge_call_stmt_to_callee (edge); + if (cgraph_dump_file) + { + fprintf (cgraph_dump_file, + "Devirtualized as: "); + print_gimple_stmt (cgraph_dump_file, + edge->call_stmt, 0, + TDF_SLIM); + } + } + } +} + /* Discover all functions and variables that are trivially needed, analyze them as well as all functions and variables referred by them */ @@ -840,9 +922,11 @@ analyze_functions (void) int i; struct ipa_ref *ref; bool changed = true; + location_t saved_loc = input_location; bitmap_obstack_initialize (NULL); cgraph_state = CGRAPH_STATE_CONSTRUCTION; + input_location = UNKNOWN_LOCATION; /* Ugly, but the fixup can not happen at a time same body alias is created; C++ FE is confused about the COMDAT groups being right. */ @@ -923,71 +1007,13 @@ analyze_functions (void) if (optimize && flag_devirtualize) { struct cgraph_edge *next; - for (edge = cnode->indirect_calls; edge; edge = next) + + for (edge = cnode->indirect_calls; edge; edge = next) { next = edge->next_callee; if (edge->indirect_info->polymorphic) - { - unsigned int i; - void *cache_token; - bool final; - vec <cgraph_node *>targets - = possible_polymorphic_call_targets - (edge, &final, &cache_token); - - if (!pointer_set_insert (reachable_call_targets, - cache_token)) - { - if (cgraph_dump_file) - dump_possible_polymorphic_call_targets - (cgraph_dump_file, edge); - - for (i = 0; i < targets.length(); i++) - { - /* Do not bother to mark virtual methods in anonymous namespace; - either we will find use of virtual table defining it, or it is - unused. */ - if (targets[i]->symbol.definition - && TREE_CODE - (TREE_TYPE (targets[i]->symbol.decl)) - == METHOD_TYPE - && !type_in_anonymous_namespace_p - (method_class_type - (TREE_TYPE (targets[i]->symbol.decl)))) - enqueue_node ((symtab_node) targets[i]); - } - } - - /* Very trivial devirtualization; when the type is - final or anonymous (so we know all its derivation) - and there is only one possible virtual call target, - make the edge direct. */ - if (final) - { - gcc_assert (targets.length()); - if (targets.length() == 1) - { - if (cgraph_dump_file) - { - fprintf (cgraph_dump_file, - "Devirtualizing call: "); - print_gimple_stmt (cgraph_dump_file, - edge->call_stmt, 0, - TDF_SLIM); - } - cgraph_make_edge_direct (edge, targets[0]); - cgraph_redirect_edge_call_stmt_to_callee (edge); - if (cgraph_dump_file) - { - fprintf (cgraph_dump_file, - "Devirtualized as: "); - print_gimple_stmt (cgraph_dump_file, - edge->call_stmt, 0, - TDF_SLIM); - } - } - } - } + walk_polymorphic_call_targets (reachable_call_targets, + edge); } } @@ -1064,6 +1090,8 @@ analyze_functions (void) } node->symbol.aux = NULL; } + for (;node; node = node->symbol.next) + node->symbol.aux = NULL; first_analyzed = cgraph_first_function (); first_analyzed_var = varpool_first_variable (); if (cgraph_dump_file) @@ -1074,6 +1102,13 @@ analyze_functions (void) bitmap_obstack_release (NULL); pointer_set_destroy (reachable_call_targets); ggc_collect (); + /* Initialize assembler name hash, in particular we want to trigger C++ + mangling and same body alias creation before we free DECL_ARGUMENTS + used by it. */ + if (!seen_error ()) + symtab_initialize_asm_name_hash (); + + input_location = saved_loc; } /* Translate the ugly representation of aliases as alias pairs into nice @@ -1403,10 +1438,12 @@ thunk_adjust (gimple_stmt_iterator * bsi, return ret; } -/* Produce assembler for thunk NODE. */ +/* Expand thunk NODE to gimple if possible. + When OUTPUT_ASM_THUNK is true, also produce assembler for + thunks that are not lowered. */ -void -expand_thunk (struct cgraph_node *node) +bool +expand_thunk (struct cgraph_node *node, bool output_asm_thunks) { bool this_adjusting = node->thunk.this_adjusting; HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset; @@ -1414,12 +1451,8 @@ expand_thunk (struct cgraph_node *node) tree virtual_offset = NULL; tree alias = node->callees->callee->symbol.decl; tree thunk_fndecl = node->symbol.decl; - tree a = DECL_ARGUMENTS (thunk_fndecl); - - current_function_decl = thunk_fndecl; + tree a; - /* Ensure thunks are emitted in their correct sections. */ - resolve_unique_section (thunk_fndecl, 0, flag_function_sections); if (this_adjusting && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset, @@ -1428,10 +1461,23 @@ expand_thunk (struct cgraph_node *node) const char *fnname; tree fn_block; tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl)); + + if (!output_asm_thunks) + return false; + + if (in_lto_p) + cgraph_get_body (node); + a = DECL_ARGUMENTS (thunk_fndecl); + current_function_decl = thunk_fndecl; + + /* Ensure thunks are emitted in their correct sections. */ + resolve_unique_section (thunk_fndecl, 0, flag_function_sections); + DECL_RESULT (thunk_fndecl) = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl), RESULT_DECL, 0, restype); + DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl; fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl)); /* The back end expects DECL_INITIAL to contain a BLOCK, so we @@ -1473,6 +1519,15 @@ expand_thunk (struct cgraph_node *node) gimple call; gimple ret; + if (in_lto_p) + cgraph_get_body (node); + a = DECL_ARGUMENTS (thunk_fndecl); + + current_function_decl = thunk_fndecl; + + /* Ensure thunks are emitted in their correct sections. */ + resolve_unique_section (thunk_fndecl, 0, flag_function_sections); + DECL_IGNORED_P (thunk_fndecl) = 1; bitmap_obstack_initialize (NULL); @@ -1487,6 +1542,7 @@ expand_thunk (struct cgraph_node *node) DECL_ARTIFICIAL (resdecl) = 1; DECL_IGNORED_P (resdecl) = 1; DECL_RESULT (thunk_fndecl) = resdecl; + DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl; } else resdecl = DECL_RESULT (thunk_fndecl); @@ -1523,6 +1579,7 @@ expand_thunk (struct cgraph_node *node) for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg)) vargs.quick_push (arg); call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs); + node->callees->call_stmt = call; vargs.release (); gimple_call_set_from_thunk (call, true); if (restmp) @@ -1591,6 +1648,9 @@ expand_thunk (struct cgraph_node *node) remove_edge (single_succ_edge (bb)); } + cfun->gimple_df->in_ssa_p = true; + /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */ + TREE_ASM_WRITTEN (thunk_fndecl) = false; delete_unreachable_blocks (); update_ssa (TODO_update_ssa); #ifdef ENABLE_CHECKING @@ -1600,12 +1660,12 @@ expand_thunk (struct cgraph_node *node) /* Since we want to emit the thunk, we explicitly mark its name as referenced. */ node->thunk.thunk_p = false; - rebuild_cgraph_edges (); - cgraph_add_new_function (thunk_fndecl, true); + node->lowered = true; bitmap_obstack_release (NULL); } current_function_decl = NULL; set_cfun (NULL); + return true; } /* Assemble thunks and aliases associated to NODE. */ @@ -1624,7 +1684,7 @@ assemble_thunks_and_aliases (struct cgraph_node *node) e = e->next_caller; assemble_thunks_and_aliases (thunk); - expand_thunk (thunk); + expand_thunk (thunk, true); } else e = e->next_caller; 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/combine.c b/gcc/combine.c index a72b927fbaa..d001a5b66fc 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -4718,13 +4718,14 @@ find_split_point (rtx *loc, rtx insn, bool set_src) if (unsignedp && len <= 8) { + unsigned HOST_WIDE_INT mask + = ((unsigned HOST_WIDE_INT) 1 << len) - 1; SUBST (SET_SRC (x), gen_rtx_AND (mode, gen_rtx_LSHIFTRT (mode, gen_lowpart (mode, inner), GEN_INT (pos)), - GEN_INT (((unsigned HOST_WIDE_INT) 1 << len) - - 1))); + gen_int_mode (mask, mode))); split = find_split_point (&SET_SRC (x), insn, true); if (split && split != &SET_SRC (x)) @@ -4807,9 +4808,11 @@ find_split_point (rtx *loc, rtx insn, bool set_src) enum machine_mode mode = GET_MODE (x); unsigned HOST_WIDE_INT this_int = INTVAL (XEXP (XEXP (x, 1), 1)); HOST_WIDE_INT other_int = trunc_int_for_mode (-this_int, mode); - SUBST (*loc, gen_rtx_PLUS (mode, gen_rtx_MULT (mode, - XEXP (XEXP (x, 1), 0), - GEN_INT (other_int)), + SUBST (*loc, gen_rtx_PLUS (mode, + gen_rtx_MULT (mode, + XEXP (XEXP (x, 1), 0), + gen_int_mode (other_int, + mode)), XEXP (x, 0))); return find_split_point (loc, insn, set_src); } @@ -6364,8 +6367,9 @@ simplify_set (rtx x) *cc_use = old_cc_use; other_changed = 0; - op0 = simplify_gen_binary (XOR, GET_MODE (op0), - op0, GEN_INT (mask)); + op0 = simplify_gen_binary (XOR, GET_MODE (op0), op0, + gen_int_mode (mask, + GET_MODE (op0))); } } } @@ -6887,11 +6891,13 @@ expand_field_assignment (const_rtx x) /* If position is ADJUST - X, new position is X. */ pos = XEXP (pos, 0); else - pos = simplify_gen_binary (MINUS, GET_MODE (pos), - GEN_INT (GET_MODE_PRECISION ( - GET_MODE (inner)) - - len), - pos); + { + HOST_WIDE_INT prec = GET_MODE_PRECISION (GET_MODE (inner)); + pos = simplify_gen_binary (MINUS, GET_MODE (pos), + gen_int_mode (prec - len, + GET_MODE (pos)), + pos); + } } } @@ -6944,7 +6950,8 @@ expand_field_assignment (const_rtx x) /* Now compute the equivalent expression. Make a copy of INNER for the SET_DEST in case it is a MEM into which we will substitute; we don't want shared RTL in that case. */ - mask = GEN_INT (((unsigned HOST_WIDE_INT) 1 << len) - 1); + mask = gen_int_mode (((unsigned HOST_WIDE_INT) 1 << len) - 1, + compute_mode); cleared = simplify_gen_binary (AND, compute_mode, simplify_gen_unary (NOT, compute_mode, simplify_gen_binary (ASHIFT, @@ -7251,7 +7258,9 @@ make_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos, pos = width - len - pos; else pos_rtx - = gen_rtx_MINUS (GET_MODE (pos_rtx), GEN_INT (width - len), pos_rtx); + = gen_rtx_MINUS (GET_MODE (pos_rtx), + gen_int_mode (width - len, GET_MODE (pos_rtx)), + pos_rtx); /* POS may be less than 0 now, but we check for that below. Note that it can only be less than 0 if !MEM_P (inner). */ } @@ -7406,9 +7415,11 @@ extract_left_shift (rtx x, int count) && (UINTVAL (XEXP (x, 1)) & ((((unsigned HOST_WIDE_INT) 1 << count)) - 1)) == 0 && (tem = extract_left_shift (XEXP (x, 0), count)) != 0) - return simplify_gen_binary (code, mode, tem, - GEN_INT (INTVAL (XEXP (x, 1)) >> count)); - + { + HOST_WIDE_INT val = INTVAL (XEXP (x, 1)) >> count; + return simplify_gen_binary (code, mode, tem, + gen_int_mode (val, mode)); + } break; default: @@ -7483,7 +7494,7 @@ make_compound_operation (rtx x, enum rtx_code in_code) multval = -multval; } multval = trunc_int_for_mode (multval, mode); - new_rtx = gen_rtx_MULT (mode, new_rtx, GEN_INT (multval)); + new_rtx = gen_rtx_MULT (mode, new_rtx, gen_int_mode (multval, mode)); } break; @@ -8116,17 +8127,10 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask, unsigned HOST_WIDE_INT cval = UINTVAL (XEXP (x, 1)) | (GET_MODE_MASK (GET_MODE (x)) & ~mask); - int width = GET_MODE_PRECISION (GET_MODE (x)); rtx y; - /* If MODE is narrower than HOST_WIDE_INT and CVAL is a negative - number, sign extend it. */ - if (width > 0 && width < HOST_BITS_PER_WIDE_INT - && (cval & (HOST_WIDE_INT_1U << (width - 1))) != 0) - cval |= HOST_WIDE_INT_M1U << width; - - y = simplify_gen_binary (AND, GET_MODE (x), - XEXP (x, 0), GEN_INT (cval)); + y = simplify_gen_binary (AND, GET_MODE (x), XEXP (x, 0), + gen_int_mode (cval, GET_MODE (x))); if (set_src_cost (y, optimize_this_for_speed_p) < set_src_cost (x, optimize_this_for_speed_p)) x = y; @@ -8216,8 +8220,9 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask, && (UINTVAL (XEXP (x, 1)) & ~nonzero_bits (XEXP (x, 0), GET_MODE (x))) == 0) { - temp = GEN_INT ((INTVAL (XEXP (x, 1)) & mask) - << INTVAL (XEXP (XEXP (x, 0), 1))); + temp = gen_int_mode ((INTVAL (XEXP (x, 1)) & mask) + << INTVAL (XEXP (XEXP (x, 0), 1)), + GET_MODE (x)); temp = simplify_gen_binary (GET_CODE (x), GET_MODE (x), XEXP (XEXP (x, 0), 0), temp); x = simplify_gen_binary (LSHIFTRT, GET_MODE (x), temp, @@ -8431,7 +8436,8 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask, && INTVAL (XEXP (x, 1)) >= 0) { temp = simplify_binary_operation (code == ROTATE ? ROTATERT : ROTATE, - GET_MODE (x), GEN_INT (mask), + GET_MODE (x), + gen_int_mode (mask, GET_MODE (x)), XEXP (x, 1)); if (temp && CONST_INT_P (temp)) SUBST (XEXP (x, 0), @@ -10080,7 +10086,8 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode, nonzero bits of the inner shift the same way the outer shift will. */ - mask_rtx = GEN_INT (nonzero_bits (varop, GET_MODE (varop))); + mask_rtx = gen_int_mode (nonzero_bits (varop, GET_MODE (varop)), + result_mode); mask_rtx = simplify_const_binary_operation (code, result_mode, mask_rtx, @@ -10181,9 +10188,10 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode, && !(code == ASHIFTRT && GET_CODE (varop) == XOR && 0 > trunc_int_for_mode (INTVAL (XEXP (varop, 1)), shift_mode)) - && (new_rtx = simplify_const_binary_operation (code, result_mode, - XEXP (varop, 1), - GEN_INT (count))) != 0 + && (new_rtx = simplify_const_binary_operation + (code, result_mode, + gen_int_mode (INTVAL (XEXP (varop, 1)), result_mode), + GEN_INT (count))) != 0 && CONST_INT_P (new_rtx) && merge_outer_ops (&outer_op, &outer_const, GET_CODE (varop), INTVAL (new_rtx), result_mode, &complement_p)) @@ -11934,11 +11942,11 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1) if (op1 == const0_rtx && (code == LT || code == GE) && HWI_COMPUTABLE_MODE_P (mode)) { + unsigned HOST_WIDE_INT sign + = (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1); op0 = simplify_gen_binary (AND, tmode, gen_lowpart (tmode, op0), - GEN_INT ((unsigned HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (mode) - - 1))); + gen_int_mode (sign, mode)); code = (code == LT) ? NE : EQ; break; } diff --git a/gcc/common.opt b/gcc/common.opt index fae976393d5..202e169d281 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2264,14 +2264,18 @@ Perform variable tracking and also tag variables that are uninitialized ftree-vectorize Common Report Var(flag_tree_vectorize) Optimization -Enable loop vectorization on trees +Enable vectorization on trees ftree-vectorizer-verbose= Common RejectNegative Joined UInteger Var(common_deferred_options) Defer -ftree-vectorizer-verbose=<number> This switch is deprecated. Use -fopt-info instead. +ftree-loop-vectorize +Common Report Var(flag_tree_loop_vectorize) Optimization +Enable loop vectorization on trees + ftree-slp-vectorize -Common Report Var(flag_tree_slp_vectorize) Init(2) Optimization +Common Report Var(flag_tree_slp_vectorize) Optimization Enable basic block vectorization (SLP) on trees fvect-cost-model 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.gcc b/gcc/config.gcc index eeab290d5be..605efc0e090 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -831,7 +831,7 @@ case ${target} in tmake_file=t-vxworks xm_defines=POSIX extra_options="${extra_options} vxworks.opt" - extra_objs=vxworks.o + extra_objs="$extra_objs vxworks.o" case ${enable_threads} in no) ;; "" | yes | vxworks) thread_file='vxworks' ;; @@ -1018,7 +1018,7 @@ bfin*-uclinux*) ;; bfin*-linux-uclibc*) tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h gnu-user.h linux.h glibc-stdint.h bfin/linux.h ./linux-sysroot-suffix.h" - tmake_file="bfin/t-bfin-linux t-slibgcc" + tmake_file="bfin/t-bfin-linux t-slibgcc t-linux-android" use_collect2=no ;; bfin*-rtems*) @@ -1053,7 +1053,7 @@ cris-*-elf | cris-*-none) crisv32-*-linux* | cris-*-linux*) tm_file="dbxelf.h elfos.h ${tm_file} gnu-user.h linux.h glibc-stdint.h cris/linux.h" # We need to avoid using t-linux, so override default tmake_file - tmake_file="cris/t-cris cris/t-linux t-slibgcc" + tmake_file="cris/t-cris cris/t-linux t-slibgcc t-linux-android" extra_options="${extra_options} cris/linux.opt" case $target in cris-*-*) @@ -1526,6 +1526,9 @@ x86_64-*-cygwin*) i[34567]86-*-mingw* | x86_64-*-mingw*) tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h" xm_file=i386/xm-mingw32.h + c_target_objs="${c_target_objs} winnt-c.o" + cxx_target_objs="${cxx_target_objs} winnt-c.o" + target_has_targetcm="yes" case ${target} in x86_64-*-* | *-w64-*) need_64bit_isa=yes @@ -1565,7 +1568,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*) ;; esac tm_file="${tm_file} i386/mingw-stdint.h" - tmake_file="${tmake_file} i386/t-cygming t-slibgcc" + tmake_file="${tmake_file} t-winnt i386/t-cygming t-slibgcc" case ${target} in x86_64-w64-*) tmake_file="${tmake_file} i386/t-mingw-w64" @@ -2030,6 +2033,13 @@ mn10300-*-*) use_collect2=no use_gcc_stdint=wrap ;; +msp430*-*-*) + tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}" + c_target_objs="msp430-c.o" + cxx_target_objs="msp430-c.o" + target_has_targetm_common=no + tmake_file="${tmake_file} msp430/t-msp430" + ;; pdp11-*-*) tm_file="${tm_file} newlib-stdint.h" use_gcc_stdint=wrap @@ -3858,7 +3868,9 @@ case ${target} in ;; i[34567]86-*-solaris2* | x86_64-*-solaris2.1[0-9]*) ;; - i[34567]86-*-cygwin* | i[34567]86-*-mingw* | x86_64-*-mingw*) + i[34567]86-*-cygwin* | x86_64-*-cygwin*) + ;; + i[34567]86-*-mingw* | x86_64-*-mingw*) ;; i[34567]86-*-freebsd* | x86_64-*-freebsd*) ;; diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c index 6816b9cfdaa..0df5b3b0d77 100644 --- a/gcc/config/aarch64/aarch64-builtins.c +++ b/gcc/config/aarch64/aarch64-builtins.c @@ -989,6 +989,8 @@ aarch64_simd_expand_args (rtx target, int icode, int have_retval, switch (thisarg) { case SIMD_ARG_COPY_TO_REG: + if (POINTER_TYPE_P (TREE_TYPE (arg[argc]))) + op[argc] = convert_memory_address (Pmode, op[argc]); /*gcc_assert (GET_MODE (op[argc]) == mode[argc]); */ if (!(*insn_data[icode].operand[argc + have_retval].predicate) (op[argc], mode[argc])) diff --git a/gcc/config/aarch64/aarch64-generic.md b/gcc/config/aarch64/aarch64-generic.md index cbb75600389..12faac84348 100644 --- a/gcc/config/aarch64/aarch64-generic.md +++ b/gcc/config/aarch64/aarch64-generic.md @@ -30,9 +30,11 @@ (const_string "no"))) (define_insn_reservation "load" 2 - (eq_attr "is_load" "yes") + (and (eq_attr "generic_sched" "yes") + (eq_attr "is_load" "yes")) "core") (define_insn_reservation "nonload" 1 - (eq_attr "is_load" "no") + (and (eq_attr "generic_sched" "yes") + (eq_attr "is_load" "no")) "core") diff --git a/gcc/config/aarch64/aarch64-option-extensions.def b/gcc/config/aarch64/aarch64-option-extensions.def index 58e815471a6..371e74c7f94 100644 --- a/gcc/config/aarch64/aarch64-option-extensions.def +++ b/gcc/config/aarch64/aarch64-option-extensions.def @@ -35,3 +35,4 @@ AARCH64_OPT_EXTENSION("fp", AARCH64_FL_FP, AARCH64_FL_FPSIMD | AARCH64_FL_CRYPTO) AARCH64_OPT_EXTENSION("simd", AARCH64_FL_FPSIMD, AARCH64_FL_SIMD | AARCH64_FL_CRYPTO) AARCH64_OPT_EXTENSION("crypto", AARCH64_FL_CRYPTO | AARCH64_FL_FPSIMD, AARCH64_FL_CRYPTO) +AARCH64_OPT_EXTENSION("crc", AARCH64_FL_CRC, AARCH64_FL_CRC) 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 f4b929edf44..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") @@ -1052,7 +1169,7 @@ fmov\\t%d0, %1 dup\\t%d0, %1" [(set_attr "v8type" "*,fmov,*") - (set_attr "type" "*,mov_reg,*") + (set_attr "type" "*,fmov,*") (set_attr "simd_type" "simd_dup,*,simd_dup") (set_attr "simd_mode" "<MODE>") (set_attr "simd" "yes,*,yes") @@ -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" @@ -2797,7 +3045,7 @@ (match_operand:VD_HSI 2 "register_operand" "w")) (sign_extend:<VWIDE> (vec_duplicate:VD_HSI - (match_operand:<VEL> 3 "register_operand" "w")))) + (match_operand:<VEL> 3 "register_operand" "<vwx>")))) (const_int 1))))] "TARGET_SIMD" "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]" @@ -2955,7 +3203,7 @@ (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" ""))) (sign_extend:<VWIDE> (vec_duplicate:<VHALF> - (match_operand:<VEL> 3 "register_operand" "w")))) + (match_operand:<VEL> 3 "register_operand" "<vwx>")))) (const_int 1))))] "TARGET_SIMD" "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]" @@ -3083,7 +3331,7 @@ (match_operand:VD_HSI 1 "register_operand" "w")) (sign_extend:<VWIDE> (vec_duplicate:VD_HSI - (match_operand:<VEL> 2 "register_operand" "w"))) + (match_operand:<VEL> 2 "register_operand" "<vwx>"))) ) (const_int 1)))] "TARGET_SIMD" @@ -3193,7 +3441,7 @@ (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" ""))) (sign_extend:<VWIDE> (vec_duplicate:<VHALF> - (match_operand:<VEL> 2 "register_operand" "w"))) + (match_operand:<VEL> 2 "register_operand" "<vwx>"))) ) (const_int 1)))] "TARGET_SIMD" @@ -4179,13 +4427,23 @@ (set_attr "simd_mode" "<MODE>")] ) +(define_insn "aarch64_frecp<FRECP:frecp_suffix><mode>" + [(set (match_operand:GPF 0 "register_operand" "=w") + (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] + FRECP))] + "TARGET_SIMD" + "frecp<FRECP:frecp_suffix>\\t%<s>0, %<s>1" + [(set_attr "simd_type" "simd_frecp<FRECP:frecp_suffix>") + (set_attr "mode" "<MODE>")] +) + (define_insn "aarch64_frecps<mode>" - [(set (match_operand:VDQF 0 "register_operand" "=w") - (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w") - (match_operand:VDQF 2 "register_operand" "w")] + [(set (match_operand:VALLF 0 "register_operand" "=w") + (unspec:VALLF [(match_operand:VALLF 1 "register_operand" "w") + (match_operand:VALLF 2 "register_operand" "w")] UNSPEC_FRECPS))] "TARGET_SIMD" - "frecps\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>" + "frecps\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>" [(set_attr "simd_type" "simd_frecps") (set_attr "simd_mode" "<MODE>")] ) diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index c1ebc909801..2df7a6426fd 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -2065,9 +2065,9 @@ aarch64_expand_prologue (void) emit_insn (gen_add2_insn (stack_pointer_rtx, op0)); aarch64_set_frame_expr (gen_rtx_SET (Pmode, stack_pointer_rtx, - gen_rtx_PLUS (Pmode, - stack_pointer_rtx, - GEN_INT (-frame_size)))); + plus_constant (Pmode, + stack_pointer_rtx, + -frame_size))); } else if (frame_size > 0) { @@ -2151,9 +2151,9 @@ aarch64_expand_prologue (void) GEN_INT (fp_offset))); aarch64_set_frame_expr (gen_rtx_SET (Pmode, hard_frame_pointer_rtx, - gen_rtx_PLUS (Pmode, - stack_pointer_rtx, - GEN_INT (fp_offset)))); + plus_constant (Pmode, + stack_pointer_rtx, + fp_offset))); RTX_FRAME_RELATED_P (insn) = 1; insn = emit_insn (gen_stack_tie (stack_pointer_rtx, hard_frame_pointer_rtx)); @@ -2349,9 +2349,9 @@ aarch64_expand_epilogue (bool for_sibcall) emit_insn (gen_add2_insn (stack_pointer_rtx, op0)); aarch64_set_frame_expr (gen_rtx_SET (Pmode, stack_pointer_rtx, - gen_rtx_PLUS (Pmode, - stack_pointer_rtx, - GEN_INT (frame_size)))); + plus_constant (Pmode, + stack_pointer_rtx, + frame_size))); } else if (frame_size > 0) { @@ -2373,10 +2373,10 @@ aarch64_expand_epilogue (bool for_sibcall) } } - aarch64_set_frame_expr (gen_rtx_SET (Pmode, stack_pointer_rtx, - gen_rtx_PLUS (Pmode, - stack_pointer_rtx, - GEN_INT (offset)))); + aarch64_set_frame_expr (gen_rtx_SET (Pmode, stack_pointer_rtx, + plus_constant (Pmode, + stack_pointer_rtx, + offset))); } emit_use (gen_rtx_REG (DImode, LR_REGNUM)); @@ -3313,14 +3313,15 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y) || GET_CODE (x) == NEG)) return CC_NZmode; - /* A compare with a shifted operand. Because of canonicalization, + /* A compare with a shifted or negated operand. Because of canonicalization, the comparison will have to be swapped when we emit the assembly code. */ if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode) && (GET_CODE (y) == REG || GET_CODE (y) == SUBREG) && (GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT || GET_CODE (x) == LSHIFTRT - || GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)) + || GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND + || GET_CODE (x) == NEG)) return CC_SWPmode; /* A compare of a mode narrower than SI mode against zero can be done @@ -4013,9 +4014,9 @@ aarch64_legitimize_reload_address (rtx *x_p, /* Reload high part into base reg, leaving the low part in the mem instruction. */ - x = gen_rtx_PLUS (xmode, - gen_rtx_PLUS (xmode, XEXP (x, 0), cst), - GEN_INT (low)); + x = plus_constant (xmode, + gen_rtx_PLUS (xmode, XEXP (x, 0), cst), + low); push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, BASE_REG_CLASS, xmode, VOIDmode, 0, 0, @@ -4236,10 +4237,18 @@ aarch64_class_max_nregs (reg_class_t regclass, enum machine_mode mode) } static reg_class_t -aarch64_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t regclass) +aarch64_preferred_reload_class (rtx x, reg_class_t regclass) { - return ((regclass == POINTER_REGS || regclass == STACK_REG) - ? GENERAL_REGS : regclass); + if (regclass == POINTER_REGS || regclass == STACK_REG) + return GENERAL_REGS; + + /* If it's an integer immediate that MOVI can't handle, then + FP_REGS is not an option, so we return NO_REGS instead. */ + if (CONST_INT_P (x) && reg_class_subset_p (regclass, FP_REGS) + && !aarch64_simd_imm_scalar_p (x, GET_MODE (x))) + return NO_REGS; + + return regclass; } void diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 092426973c6..d8012f88049 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -158,6 +158,7 @@ #define AARCH64_FL_FP (1 << 1) /* Has FP. */ #define AARCH64_FL_CRYPTO (1 << 2) /* Has crypto. */ #define AARCH64_FL_SLOWMUL (1 << 3) /* A slow multiply core. */ +#define AARCH64_FL_CRC (1 << 4) /* Has CRC. */ /* Has FP and SIMD. */ #define AARCH64_FL_FPSIMD (AARCH64_FL_FP | AARCH64_FL_SIMD) @@ -170,6 +171,7 @@ /* Macros to test ISA flags. */ extern unsigned long aarch64_isa_flags; +#define AARCH64_ISA_CRC (aarch64_isa_flags & AARCH64_FL_CRC) #define AARCH64_ISA_CRYPTO (aarch64_isa_flags & AARCH64_FL_CRYPTO) #define AARCH64_ISA_FP (aarch64_isa_flags & AARCH64_FL_FP) #define AARCH64_ISA_SIMD (aarch64_isa_flags & AARCH64_FL_SIMD) diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 47532fca2c5..797c9f422c4 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -240,9 +240,6 @@ fmovf2i,\ fmovi2f,\ fmul,\ - frecpe,\ - frecps,\ - frecpx,\ frint,\ fsqrt,\ load_acq,\ @@ -311,6 +308,14 @@ ;; Processor types. (include "aarch64-tune.md") +;; True if the generic scheduling description should be used. + +(define_attr "generic_sched" "yes,no" + (const (if_then_else + (eq_attr "tune" "large,small,cortexa53") + (const_string "no") + (const_string "yes")))) + ;; Scheduling (include "aarch64-generic.md") (include "large.md") @@ -833,8 +838,8 @@ fmov\\t%w0, %s1 fmov\\t%s0, %s1" [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov") - (set_attr "type" "mov_reg,mov_reg,mov_reg,arlo_reg,load1,load1,store1,store1,\ - mov_reg,mov_reg,mov_reg,mov_reg,mov_reg") + (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\ + adr,adr,fmov,fmov,fmov") (set_attr "mode" "SI") (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")] ) @@ -861,7 +866,7 @@ movi\\t%d0, %1" [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov,fmov") (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\ - mov_reg,mov_reg,mov_reg,mov_reg,mov_reg,mov_reg") + adr,adr,fmov,fmov,fmov,fmov") (set_attr "mode" "DI") (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*") (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")] @@ -909,7 +914,7 @@ str\\t%q1, %0" [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \ load2,store2,store2,fpsimd_load,fpsimd_store") - (set_attr "type" "mov_reg,r_2_f,f_2_r,*, \ + (set_attr "type" "multiple,f_mcr,f_mrc,*, \ load2,store2,store2,f_loadd,f_stored") (set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*") (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI") @@ -964,8 +969,8 @@ [(set_attr "v8type" "fmovi2f,fmovf2i,\ fmov,fconst,fpsimd_load,\ fpsimd_store,fpsimd_load,fpsimd_store,fmov") - (set_attr "type" "r_2_f,f_2_r,mov_reg,fconsts,\ - f_loads,f_stores,f_loads,f_stores,mov_reg") + (set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\ + f_loads,f_stores,f_loads,f_stores,fmov") (set_attr "mode" "SF")] ) @@ -987,7 +992,7 @@ [(set_attr "v8type" "fmovi2f,fmovf2i,\ fmov,fconst,fpsimd_load,\ fpsimd_store,fpsimd_load,fpsimd_store,move") - (set_attr "type" "r_2_f,f_2_r,mov_reg,fconstd,\ + (set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\ f_loadd,f_stored,f_loadd,f_stored,mov_reg") (set_attr "mode" "DF")] ) @@ -1027,8 +1032,8 @@ ldp\\t%0, %H0, %1 stp\\t%1, %H1, %0" [(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2") - (set_attr "type" "arlo_reg,mov_reg,r_2_f,f_2_r,fconstd,fconstd,\ - f_loadd,f_stored,f_loadd,f_stored") + (set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\ + f_loadd,f_stored,neon_ldm_2,neon_stm_2") (set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF") (set_attr "length" "4,8,8,8,4,4,4,4,4,4") (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*") @@ -1093,7 +1098,7 @@ GET_MODE_SIZE (<MODE>mode)))" "ldp\\t%<w>0, %<w>2, %1" [(set_attr "v8type" "fpsimd_load2") - (set_attr "type" "f_load<s>") + (set_attr "type" "neon_ldm_2") (set_attr "mode" "<MODE>")] ) @@ -1109,8 +1114,8 @@ XEXP (operands[0], 0), GET_MODE_SIZE (<MODE>mode)))" "stp\\t%<w>1, %<w>3, %0" - [(set_attr "v8type" "fpsimd_load2") - (set_attr "type" "f_load<s>") + [(set_attr "v8type" "fpsimd_store2") + (set_attr "type" "neon_stm_2") (set_attr "mode" "<MODE>")] ) @@ -1278,7 +1283,7 @@ add\\t%w0, %w1, %w2 sub\\t%w0, %w1, #%n2" [(set_attr "v8type" "alu") - (set_attr "type" "arlo_imm,arlo_reg,arlo_imm") + (set_attr "type" "alu_imm,alu_reg,alu_imm") (set_attr "mode" "SI")] ) @@ -1295,7 +1300,7 @@ add\\t%w0, %w1, %w2 sub\\t%w0, %w1, #%n2" [(set_attr "v8type" "alu") - (set_attr "type" "arlo_imm,arlo_reg,arlo_imm") + (set_attr "type" "alu_imm,alu_reg,alu_imm") (set_attr "mode" "SI")] ) @@ -1312,7 +1317,7 @@ sub\\t%x0, %x1, #%n2 add\\t%d0, %d1, %d2" [(set_attr "v8type" "alu") - (set_attr "type" "arlo_imm,arlo_reg,arlo_imm,arlo_reg") + (set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg") (set_attr "mode" "DI") (set_attr "simd" "*,*,*,yes")] ) @@ -1331,7 +1336,7 @@ adds\\t%<w>0, %<w>1, %<w>2 subs\\t%<w>0, %<w>1, #%n2" [(set_attr "v8type" "alus") - (set_attr "type" "arlo_reg,arlo_imm,arlo_imm") + (set_attr "type" "alus_reg,alus_imm,alus_imm") (set_attr "mode" "<MODE>")] ) @@ -1350,7 +1355,7 @@ adds\\t%w0, %w1, %w2 subs\\t%w0, %w1, #%n2" [(set_attr "v8type" "alus") - (set_attr "type" "arlo_reg,arlo_imm,arlo_imm") + (set_attr "type" "alus_reg,alus_imm,alus_imm") (set_attr "mode" "SI")] ) @@ -1368,7 +1373,7 @@ "" "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2" [(set_attr "v8type" "alus_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alus_shift_imm") (set_attr "mode" "<MODE>")] ) @@ -1386,7 +1391,7 @@ "" "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3" [(set_attr "v8type" "alus_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alus_shift_imm") (set_attr "mode" "<MODE>")] ) @@ -1402,7 +1407,7 @@ "" "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>" [(set_attr "v8type" "alus_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alus_ext") (set_attr "mode" "<GPI:MODE>")] ) @@ -1418,7 +1423,7 @@ "" "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>" [(set_attr "v8type" "alus_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alus_ext") (set_attr "mode" "<GPI:MODE>")] ) @@ -1440,7 +1445,7 @@ "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])" "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2" [(set_attr "v8type" "alus_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alus_ext") (set_attr "mode" "<MODE>")] ) @@ -1462,7 +1467,7 @@ "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])" "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2" [(set_attr "v8type" "alus_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alus_ext") (set_attr "mode" "<MODE>")] ) @@ -1478,19 +1483,19 @@ cmn\\t%<w>0, %<w>1 cmp\\t%<w>0, #%n1" [(set_attr "v8type" "alus") - (set_attr "type" "arlo_reg,arlo_imm,arlo_imm") + (set_attr "type" "alus_reg,alus_imm,alus_imm") (set_attr "mode" "<MODE>")] ) (define_insn "*compare_neg<mode>" - [(set (reg:CC CC_REGNUM) - (compare:CC - (match_operand:GPI 0 "register_operand" "r") - (neg:GPI (match_operand:GPI 1 "register_operand" "r"))))] + [(set (reg:CC_SWP CC_REGNUM) + (compare:CC_SWP + (neg:GPI (match_operand:GPI 0 "register_operand" "r")) + (match_operand:GPI 1 "register_operand" "r")))] "" - "cmn\\t%<w>0, %<w>1" + "cmn\\t%<w>1, %<w>0" [(set_attr "v8type" "alus") - (set_attr "type" "arlo_reg") + (set_attr "type" "alus_reg") (set_attr "mode" "<MODE>")] ) @@ -1502,7 +1507,7 @@ "" "add\\t%<w>0, %<w>3, %<w>1, <shift> %2" [(set_attr "v8type" "alu_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alu_shift_imm") (set_attr "mode" "<MODE>")] ) @@ -1516,7 +1521,7 @@ "" "add\\t%w0, %w3, %w1, <shift> %2" [(set_attr "v8type" "alu_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alu_shift_imm") (set_attr "mode" "SI")] ) @@ -1528,7 +1533,7 @@ "" "add\\t%<w>0, %<w>3, %<w>1, lsl %p2" [(set_attr "v8type" "alu_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alu_shift_imm") (set_attr "mode" "<MODE>")] ) @@ -1539,7 +1544,7 @@ "" "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "<GPI:MODE>")] ) @@ -1552,7 +1557,7 @@ "" "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "SI")] ) @@ -1565,7 +1570,7 @@ "" "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "<GPI:MODE>")] ) @@ -1580,7 +1585,7 @@ "" "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "SI")] ) @@ -1593,7 +1598,7 @@ "" "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "<GPI:MODE>")] ) @@ -1607,7 +1612,7 @@ "" "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "SI")] ) @@ -1622,7 +1627,7 @@ "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])" "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "<MODE>")] ) @@ -1639,7 +1644,7 @@ "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])" "add\\t%w0, %w4, %w1, <su>xt%e3 %p2" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "SI")] ) @@ -1653,7 +1658,7 @@ "" "adc\\t%<w>0, %<w>1, %<w>2" [(set_attr "v8type" "adc") - (set_attr "type" "arlo_reg") + (set_attr "type" "adc_reg") (set_attr "mode" "<MODE>")] ) @@ -1669,7 +1674,7 @@ "" "adc\\t%w0, %w1, %w2" [(set_attr "v8type" "adc") - (set_attr "type" "arlo_reg") + (set_attr "type" "adc_reg") (set_attr "mode" "SI")] ) @@ -1683,7 +1688,7 @@ "" "adc\\t%<w>0, %<w>1, %<w>2" [(set_attr "v8type" "adc") - (set_attr "type" "arlo_reg") + (set_attr "type" "adc_reg") (set_attr "mode" "<MODE>")] ) @@ -1699,7 +1704,7 @@ "" "adc\\t%w0, %w1, %w2" [(set_attr "v8type" "adc") - (set_attr "type" "arlo_reg") + (set_attr "type" "adc_reg") (set_attr "mode" "SI")] ) @@ -1713,7 +1718,7 @@ "" "adc\\t%<w>0, %<w>1, %<w>2" [(set_attr "v8type" "adc") - (set_attr "type" "arlo_reg") + (set_attr "type" "adc_reg") (set_attr "mode" "<MODE>")] ) @@ -1729,7 +1734,7 @@ "" "adc\\t%w0, %w1, %w2" [(set_attr "v8type" "adc") - (set_attr "type" "arlo_reg") + (set_attr "type" "adc_reg") (set_attr "mode" "SI")] ) @@ -1743,7 +1748,7 @@ "" "adc\\t%<w>0, %<w>1, %<w>2" [(set_attr "v8type" "adc") - (set_attr "type" "arlo_reg") + (set_attr "type" "adc_reg") (set_attr "mode" "<MODE>")] ) @@ -1759,7 +1764,7 @@ "" "adc\\t%w0, %w1, %w2" [(set_attr "v8type" "adc") - (set_attr "type" "arlo_reg") + (set_attr "type" "adc_reg") (set_attr "mode" "SI")] ) @@ -1776,7 +1781,7 @@ INTVAL (operands[3]))); return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "<MODE>")] ) @@ -1795,7 +1800,7 @@ INTVAL (operands[3]))); return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "SI")] ) @@ -1806,7 +1811,7 @@ "" "sub\\t%w0, %w1, %w2" [(set_attr "v8type" "alu") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_reg") (set_attr "mode" "SI")] ) @@ -1819,7 +1824,7 @@ "" "sub\\t%w0, %w1, %w2" [(set_attr "v8type" "alu") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_reg") (set_attr "mode" "SI")] ) @@ -1832,7 +1837,7 @@ sub\\t%x0, %x1, %x2 sub\\t%d0, %d1, %d2" [(set_attr "v8type" "alu") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_reg") (set_attr "mode" "DI") (set_attr "simd" "*,yes")] ) @@ -1848,7 +1853,7 @@ "" "subs\\t%<w>0, %<w>1, %<w>2" [(set_attr "v8type" "alus") - (set_attr "type" "arlo_reg") + (set_attr "type" "alus_reg") (set_attr "mode" "<MODE>")] ) @@ -1863,7 +1868,7 @@ "" "subs\\t%w0, %w1, %w2" [(set_attr "v8type" "alus") - (set_attr "type" "arlo_reg") + (set_attr "type" "alus_reg") (set_attr "mode" "SI")] ) @@ -1876,7 +1881,7 @@ "" "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2" [(set_attr "v8type" "alu_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alu_shift_imm") (set_attr "mode" "<MODE>")] ) @@ -1891,7 +1896,7 @@ "" "sub\\t%w0, %w3, %w1, <shift> %2" [(set_attr "v8type" "alu_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alu_shift_imm") (set_attr "mode" "SI")] ) @@ -1904,7 +1909,7 @@ "" "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2" [(set_attr "v8type" "alu_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alu_shift_imm") (set_attr "mode" "<MODE>")] ) @@ -1919,7 +1924,7 @@ "" "sub\\t%w0, %w3, %w1, lsl %p2" [(set_attr "v8type" "alu_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alu_shift_imm") (set_attr "mode" "SI")] ) @@ -1931,7 +1936,7 @@ "" "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "<GPI:MODE>")] ) @@ -1945,7 +1950,7 @@ "" "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "SI")] ) @@ -1958,7 +1963,7 @@ "" "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "<GPI:MODE>")] ) @@ -1973,7 +1978,7 @@ "" "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "SI")] ) @@ -1988,7 +1993,7 @@ "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])" "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "<MODE>")] ) @@ -2005,7 +2010,7 @@ "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])" "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "SI")] ) @@ -2019,7 +2024,7 @@ "" "sbc\\t%<w>0, %<w>1, %<w>2" [(set_attr "v8type" "adc") - (set_attr "type" "arlo_reg") + (set_attr "type" "adc_reg") (set_attr "mode" "<MODE>")] ) @@ -2035,7 +2040,7 @@ "" "sbc\\t%w0, %w1, %w2" [(set_attr "v8type" "adc") - (set_attr "type" "arlo_reg") + (set_attr "type" "adc_reg") (set_attr "mode" "SI")] ) @@ -2052,7 +2057,7 @@ INTVAL (operands[3]))); return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "<MODE>")] ) @@ -2071,7 +2076,7 @@ INTVAL (operands[3]))); return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";" [(set_attr "v8type" "alu_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_ext") (set_attr "mode" "SI")] ) @@ -2104,7 +2109,7 @@ DONE; } [(set_attr "v8type" "alu") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_reg") (set_attr "mode" "DI")] ) @@ -2116,7 +2121,7 @@ neg\\t%<w>0, %<w>1 neg\\t%<rtn>0<vas>, %<rtn>1<vas>" [(set_attr "v8type" "alu") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_reg") (set_attr "simd_type" "*,simd_negabs") (set_attr "simd" "*,yes") (set_attr "mode" "<MODE>") @@ -2130,7 +2135,7 @@ "" "neg\\t%w0, %w1" [(set_attr "v8type" "alu") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_reg") (set_attr "mode" "SI")] ) @@ -2141,7 +2146,7 @@ "" "ngc\\t%<w>0, %<w>1" [(set_attr "v8type" "adc") - (set_attr "type" "arlo_reg") + (set_attr "type" "adc_reg") (set_attr "mode" "<MODE>")] ) @@ -2153,7 +2158,7 @@ "" "ngc\\t%w0, %w1" [(set_attr "v8type" "adc") - (set_attr "type" "arlo_reg") + (set_attr "type" "adc_reg") (set_attr "mode" "SI")] ) @@ -2166,7 +2171,7 @@ "" "negs\\t%<w>0, %<w>1" [(set_attr "v8type" "alus") - (set_attr "type" "arlo_reg") + (set_attr "type" "alus_reg") (set_attr "mode" "<MODE>")] ) @@ -2180,7 +2185,7 @@ "" "negs\\t%w0, %w1" [(set_attr "v8type" "alus") - (set_attr "type" "arlo_reg") + (set_attr "type" "alus_reg") (set_attr "mode" "SI")] ) @@ -2196,7 +2201,7 @@ "" "negs\\t%<w>0, %<w>1, <shift> %2" [(set_attr "v8type" "alus_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alus_shift_imm") (set_attr "mode" "<MODE>")] ) @@ -2208,7 +2213,7 @@ "" "neg\\t%<w>0, %<w>1, <shift> %2" [(set_attr "v8type" "alu_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alu_shift_imm") (set_attr "mode" "<MODE>")] ) @@ -2222,7 +2227,7 @@ "" "neg\\t%w0, %w1, <shift> %2" [(set_attr "v8type" "alu_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alu_shift_imm") (set_attr "mode" "SI")] ) @@ -2234,7 +2239,7 @@ "" "neg\\t%<w>0, %<w>1, lsl %p2" [(set_attr "v8type" "alu_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alu_shift_imm") (set_attr "mode" "<MODE>")] ) @@ -2248,7 +2253,7 @@ "" "neg\\t%w0, %w1, lsl %p2" [(set_attr "v8type" "alu_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alu_shift_imm") (set_attr "mode" "SI")] ) @@ -2284,7 +2289,7 @@ "" "madd\\t%<w>0, %<w>1, %<w>2, %<w>3" [(set_attr "v8type" "madd") - (set_attr "type" "mul") + (set_attr "type" "mla") (set_attr "mode" "<MODE>")] ) @@ -2298,7 +2303,7 @@ "" "madd\\t%w0, %w1, %w2, %w3" [(set_attr "v8type" "madd") - (set_attr "type" "mul") + (set_attr "type" "mla") (set_attr "mode" "SI")] ) @@ -2311,7 +2316,7 @@ "" "msub\\t%<w>0, %<w>1, %<w>2, %<w>3" [(set_attr "v8type" "madd") - (set_attr "type" "mul") + (set_attr "type" "mla") (set_attr "mode" "<MODE>")] ) @@ -2326,7 +2331,7 @@ "" "msub\\t%w0, %w1, %w2, %w3" [(set_attr "v8type" "madd") - (set_attr "type" "mul") + (set_attr "type" "mla") (set_attr "mode" "SI")] ) @@ -2376,7 +2381,7 @@ "" "<su>maddl\\t%0, %w1, %w2, %3" [(set_attr "v8type" "maddl") - (set_attr "type" "mul") + (set_attr "type" "<su>mlal") (set_attr "mode" "DI")] ) @@ -2390,7 +2395,7 @@ "" "<su>msubl\\t%0, %w1, %w2, %3" [(set_attr "v8type" "maddl") - (set_attr "type" "mul") + (set_attr "type" "<su>mlal") (set_attr "mode" "DI")] ) @@ -2459,7 +2464,7 @@ cmp\\t%<w>0, %<w>1 cmn\\t%<w>0, #%n1" [(set_attr "v8type" "alus") - (set_attr "type" "arlo_reg,arlo_imm,arlo_imm") + (set_attr "type" "alus_reg,alus_imm,alus_imm") (set_attr "mode" "<MODE>")] ) @@ -2498,7 +2503,7 @@ "" "cmp\\t%<w>2, %<w>0, <shift> %1" [(set_attr "v8type" "alus_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "alus_shift_imm") (set_attr "mode" "<MODE>")] ) @@ -2510,7 +2515,7 @@ "" "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>" [(set_attr "v8type" "alus_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alus_ext") (set_attr "mode" "<GPI:MODE>")] ) @@ -2524,7 +2529,7 @@ "" "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1" [(set_attr "v8type" "alus_ext") - (set_attr "type" "arlo_reg") + (set_attr "type" "alus_ext") (set_attr "mode" "<GPI:MODE>")] ) @@ -2565,7 +2570,7 @@ "" "cset\\t%<w>0, %m1" [(set_attr "v8type" "csel") - (set_attr "type" "arlo_reg") + (set_attr "type" "csel") (set_attr "mode" "<MODE>")] ) @@ -2578,7 +2583,7 @@ "" "cset\\t%w0, %m1" [(set_attr "v8type" "csel") - (set_attr "type" "arlo_reg") + (set_attr "type" "csel") (set_attr "mode" "SI")] ) @@ -2589,7 +2594,7 @@ "" "csetm\\t%<w>0, %m1" [(set_attr "v8type" "csel") - (set_attr "type" "arlo_reg") + (set_attr "type" "csel") (set_attr "mode" "<MODE>")] ) @@ -2602,7 +2607,7 @@ "" "csetm\\t%w0, %m1" [(set_attr "v8type" "csel") - (set_attr "type" "arlo_reg") + (set_attr "type" "csel") (set_attr "mode" "SI")] ) @@ -2657,7 +2662,7 @@ mov\\t%<w>0, -1 mov\\t%<w>0, 1" [(set_attr "v8type" "csel") - (set_attr "type" "arlo_reg") + (set_attr "type" "csel") (set_attr "mode" "<MODE>")] ) @@ -2682,7 +2687,7 @@ mov\\t%w0, -1 mov\\t%w0, 1" [(set_attr "v8type" "csel") - (set_attr "type" "arlo_reg") + (set_attr "type" "csel") (set_attr "mode" "SI")] ) @@ -2696,7 +2701,7 @@ "TARGET_FLOAT" "fcsel\\t%<s>0, %<s>3, %<s>4, %m1" [(set_attr "v8type" "fcsel") - (set_attr "type" "arlo_reg") + (set_attr "type" "fcsel") (set_attr "mode" "<MODE>")] ) @@ -2746,7 +2751,7 @@ "" "csinc\\t%<w>0, %<w>1, %<w>1, %M2" [(set_attr "v8type" "csel") - (set_attr "type" "arlo_reg") + (set_attr "type" "csel") (set_attr "mode" "<MODE>")]) (define_insn "csinc3<mode>_insn" @@ -2760,7 +2765,7 @@ "" "csinc\\t%<w>0, %<w>4, %<w>3, %M1" [(set_attr "v8type" "csel") - (set_attr "type" "arlo_reg") + (set_attr "type" "csel") (set_attr "mode" "<MODE>")] ) @@ -2774,7 +2779,7 @@ "" "csinv\\t%<w>0, %<w>4, %<w>3, %M1" [(set_attr "v8type" "csel") - (set_attr "type" "arlo_reg") + (set_attr "type" "csel") (set_attr "mode" "<MODE>")]) (define_insn "*csneg3<mode>_insn" @@ -2787,7 +2792,7 @@ "" "csneg\\t%<w>0, %<w>4, %<w>3, %M1" [(set_attr "v8type" "csel") - (set_attr "type" "arlo_reg") + (set_attr "type" "csel") (set_attr "mode" "<MODE>")]) ;; ------------------------------------------------------------------- @@ -2801,7 +2806,7 @@ "" "<logical>\\t%<w>0, %<w>1, %<w>2" [(set_attr "v8type" "logic,logic_imm") - (set_attr "type" "arlo_reg,arlo_imm") + (set_attr "type" "logic_reg,logic_imm") (set_attr "mode" "<MODE>")]) ;; zero_extend version of above @@ -2813,7 +2818,7 @@ "" "<logical>\\t%w0, %w1, %w2" [(set_attr "v8type" "logic,logic_imm") - (set_attr "type" "arlo_reg,arlo_imm") + (set_attr "type" "logic_reg,logic_imm") (set_attr "mode" "SI")]) (define_insn "*and<mode>3_compare0" @@ -2827,7 +2832,7 @@ "" "ands\\t%<w>0, %<w>1, %<w>2" [(set_attr "v8type" "logics,logics_imm") - (set_attr "type" "arlo_reg,arlo_imm") + (set_attr "type" "logics_reg,logics_imm") (set_attr "mode" "<MODE>")] ) @@ -2843,7 +2848,7 @@ "" "ands\\t%w0, %w1, %w2" [(set_attr "v8type" "logics,logics_imm") - (set_attr "type" "arlo_reg,arlo_imm") + (set_attr "type" "logics_reg,logics_imm") (set_attr "mode" "SI")] ) @@ -2860,7 +2865,7 @@ "" "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2" [(set_attr "v8type" "logics_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "logics_shift_imm") (set_attr "mode" "<MODE>")] ) @@ -2879,7 +2884,7 @@ "" "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2" [(set_attr "v8type" "logics_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "logics_shift_imm") (set_attr "mode" "SI")] ) @@ -2892,7 +2897,7 @@ "" "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2" [(set_attr "v8type" "logic_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "logic_shift_imm") (set_attr "mode" "<MODE>")]) ;; zero_extend version of above @@ -2906,7 +2911,7 @@ "" "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2" [(set_attr "v8type" "logic_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "logic_shift_imm") (set_attr "mode" "SI")]) (define_insn "one_cmpl<mode>2" @@ -2915,7 +2920,7 @@ "" "mvn\\t%<w>0, %<w>1" [(set_attr "v8type" "logic") - (set_attr "type" "arlo_reg") + (set_attr "type" "logic_reg") (set_attr "mode" "<MODE>")]) (define_insn "*one_cmpl_<optab><mode>2" @@ -2925,7 +2930,7 @@ "" "mvn\\t%<w>0, %<w>1, <shift> %2" [(set_attr "v8type" "logic_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "logic_shift_imm") (set_attr "mode" "<MODE>")]) (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3" @@ -2936,7 +2941,7 @@ "" "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1" [(set_attr "v8type" "logic") - (set_attr "type" "arlo_reg") + (set_attr "type" "logic_reg") (set_attr "mode" "<MODE>")]) (define_insn "*and_one_cmpl<mode>3_compare0" @@ -2951,7 +2956,7 @@ "" "bics\\t%<w>0, %<w>2, %<w>1" [(set_attr "v8type" "logics") - (set_attr "type" "arlo_reg") + (set_attr "type" "logics_reg") (set_attr "mode" "<MODE>")]) ;; zero_extend version of above @@ -2967,7 +2972,7 @@ "" "bics\\t%w0, %w2, %w1" [(set_attr "v8type" "logics") - (set_attr "type" "arlo_reg") + (set_attr "type" "logics_reg") (set_attr "mode" "SI")]) (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3" @@ -2980,7 +2985,7 @@ "" "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2" [(set_attr "v8type" "logic_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "logics_shift_imm") (set_attr "mode" "<MODE>")]) (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0" @@ -2999,7 +3004,7 @@ "" "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2" [(set_attr "v8type" "logics_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "logics_shift_imm") (set_attr "mode" "<MODE>")]) ;; zero_extend version of above @@ -3019,7 +3024,7 @@ "" "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2" [(set_attr "v8type" "logics_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "logics_shift_imm") (set_attr "mode" "SI")]) (define_insn "clz<mode>2" @@ -3061,7 +3066,7 @@ "" "rbit\\t%<w>0, %<w>1" [(set_attr "v8type" "rbit") - (set_attr "type" "clz") + (set_attr "type" "rbit") (set_attr "mode" "<MODE>")]) (define_expand "ctz<mode>2" @@ -3084,7 +3089,7 @@ "" "tst\\t%<w>0, %<w>1" [(set_attr "v8type" "logics") - (set_attr "type" "arlo_reg") + (set_attr "type" "logics_reg") (set_attr "mode" "<MODE>")]) (define_insn "*and_<SHIFT:optab><mode>3nr_compare0" @@ -3098,7 +3103,7 @@ "" "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1" [(set_attr "v8type" "logics_shift") - (set_attr "type" "arlo_shift") + (set_attr "type" "logics_shift_imm") (set_attr "mode" "<MODE>")]) ;; ------------------------------------------------------------------- @@ -3203,7 +3208,7 @@ (set_attr "simd_type" "simd_shift_imm,simd_shift,*") (set_attr "simd_mode" "<MODE>,<MODE>,*") (set_attr "v8type" "*,*,shift") - (set_attr "type" "*,*,shift") + (set_attr "type" "*,*,shift_reg") (set_attr "mode" "*,*,<MODE>")] ) @@ -3222,7 +3227,7 @@ (set_attr "simd_type" "simd_shift_imm,simd_shift,*") (set_attr "simd_mode" "<MODE>,<MODE>,*") (set_attr "v8type" "*,*,shift") - (set_attr "type" "*,*,shift") + (set_attr "type" "*,*,shift_reg") (set_attr "mode" "*,*,<MODE>")] ) @@ -3267,7 +3272,7 @@ (set_attr "simd_type" "simd_shift_imm,simd_shift,*") (set_attr "simd_mode" "<MODE>,<MODE>,*") (set_attr "v8type" "*,*,shift") - (set_attr "type" "*,*,shift") + (set_attr "type" "*,*,shift_reg") (set_attr "mode" "*,*,<MODE>")] ) @@ -3365,7 +3370,7 @@ "" "ror\\t%<w>0, %<w>1, %<w>2" [(set_attr "v8type" "shift") - (set_attr "type" "shift") + (set_attr "type" "shift_reg") (set_attr "mode" "<MODE>")] ) @@ -3378,7 +3383,7 @@ "" "<shift>\\t%w0, %w1, %w2" [(set_attr "v8type" "shift") - (set_attr "type" "shift") + (set_attr "type" "shift_reg") (set_attr "mode" "SI")] ) @@ -3389,7 +3394,7 @@ "" "lsl\\t%<w>0, %<w>1, %<w>2" [(set_attr "v8type" "shift") - (set_attr "type" "shift") + (set_attr "type" "shift_reg") (set_attr "mode" "<MODE>")] ) @@ -3403,7 +3408,7 @@ return "<bfshift>\t%w0, %w1, %2, %3"; } [(set_attr "v8type" "bfm") - (set_attr "type" "arlo_reg") + (set_attr "type" "bfm") (set_attr "mode" "<MODE>")] ) @@ -3417,7 +3422,7 @@ (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))" "extr\\t%<w>0, %<w>1, %<w>2, %4" [(set_attr "v8type" "shift") - (set_attr "type" "shift") + (set_attr "type" "shift_imm") (set_attr "mode" "<MODE>")] ) @@ -3433,7 +3438,7 @@ (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)" "extr\\t%w0, %w1, %w2, %4" [(set_attr "v8type" "shift") - (set_attr "type" "shift") + (set_attr "type" "shift_imm") (set_attr "mode" "SI")] ) @@ -3447,7 +3452,7 @@ return "ror\\t%<w>0, %<w>1, %3"; } [(set_attr "v8type" "shift") - (set_attr "type" "shift") + (set_attr "type" "shift_imm") (set_attr "mode" "<MODE>")] ) @@ -3463,7 +3468,7 @@ return "ror\\t%w0, %w1, %3"; } [(set_attr "v8type" "shift") - (set_attr "type" "shift") + (set_attr "type" "shift_imm") (set_attr "mode" "SI")] ) @@ -3478,7 +3483,7 @@ return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3"; } [(set_attr "v8type" "bfm") - (set_attr "type" "arlo_reg") + (set_attr "type" "bfm") (set_attr "mode" "<GPI:MODE>")] ) @@ -3493,7 +3498,7 @@ return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3"; } [(set_attr "v8type" "bfm") - (set_attr "type" "arlo_reg") + (set_attr "type" "bfm") (set_attr "mode" "<GPI:MODE>")] ) @@ -3508,7 +3513,7 @@ return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3"; } [(set_attr "v8type" "bfm") - (set_attr "type" "arlo_reg") + (set_attr "type" "bfm") (set_attr "mode" "<GPI:MODE>")] ) @@ -3533,7 +3538,7 @@ "" "<su>bfx\\t%<w>0, %<w>1, %3, %2" [(set_attr "v8type" "bfm") - (set_attr "type" "arlo_reg") + (set_attr "type" "bfm") (set_attr "mode" "<MODE>")] ) @@ -3578,7 +3583,7 @@ > GET_MODE_BITSIZE (<MODE>mode)))" "bfi\\t%<w>0, %<w>3, %2, %1" [(set_attr "v8type" "bfm") - (set_attr "type" "arlo_reg") + (set_attr "type" "bfm") (set_attr "mode" "<MODE>")] ) @@ -3594,7 +3599,7 @@ > GET_MODE_BITSIZE (<MODE>mode)))" "bfxil\\t%<w>0, %<w>2, %3, %1" [(set_attr "v8type" "bfm") - (set_attr "type" "arlo_reg") + (set_attr "type" "bfm") (set_attr "mode" "<MODE>")] ) @@ -3611,7 +3616,7 @@ return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3"; } [(set_attr "v8type" "bfm") - (set_attr "type" "arlo_reg") + (set_attr "type" "bfm") (set_attr "mode" "<GPI:MODE>")] ) @@ -3626,7 +3631,7 @@ && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0" "ubfiz\\t%<w>0, %<w>1, %2, %P3" [(set_attr "v8type" "bfm") - (set_attr "type" "arlo_reg") + (set_attr "type" "bfm") (set_attr "mode" "<MODE>")] ) @@ -3636,7 +3641,7 @@ "" "rev\\t%<w>0, %<w>1" [(set_attr "v8type" "rev") - (set_attr "type" "arlo_reg") + (set_attr "type" "rev") (set_attr "mode" "<MODE>")] ) @@ -3646,7 +3651,7 @@ "" "rev16\\t%w0, %w1" [(set_attr "v8type" "rev") - (set_attr "type" "arlo_reg") + (set_attr "type" "rev") (set_attr "mode" "HI")] ) @@ -3657,7 +3662,7 @@ "" "rev\\t%w0, %w1" [(set_attr "v8type" "rev") - (set_attr "type" "arlo_reg") + (set_attr "type" "rev") (set_attr "mode" "SI")] ) @@ -3688,7 +3693,7 @@ "TARGET_FLOAT" "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1" [(set_attr "v8type" "fcvtf2i") - (set_attr "type" "f_cvt") + (set_attr "type" "f_cvtf2i") (set_attr "mode" "<GPF:MODE>") (set_attr "mode2" "<GPI:MODE>")] ) @@ -3788,7 +3793,7 @@ "TARGET_FLOAT" "fcvtzs\\t%<GPI:w>0, %<GPF:s>1" [(set_attr "v8type" "fcvtf2i") - (set_attr "type" "f_cvt") + (set_attr "type" "f_cvtf2i") (set_attr "mode" "<GPF:MODE>") (set_attr "mode2" "<GPI:MODE>")] ) @@ -3799,7 +3804,7 @@ "TARGET_FLOAT" "fcvtzu\\t%<GPI:w>0, %<GPF:s>1" [(set_attr "v8type" "fcvtf2i") - (set_attr "type" "f_cvt") + (set_attr "type" "f_cvtf2i") (set_attr "mode" "<GPF:MODE>") (set_attr "mode2" "<GPI:MODE>")] ) @@ -3810,7 +3815,7 @@ "TARGET_FLOAT" "scvtf\\t%<GPF:s>0, %<GPI:w>1" [(set_attr "v8type" "fcvti2f") - (set_attr "type" "f_cvt") + (set_attr "type" "f_cvti2f") (set_attr "mode" "<GPF:MODE>") (set_attr "mode2" "<GPI:MODE>")] ) @@ -3906,7 +3911,7 @@ "TARGET_FLOAT" "fsqrt\\t%<s>0, %<s>1" [(set_attr "v8type" "fsqrt") - (set_attr "type" "fdiv<s>") + (set_attr "type" "fsqrt<s>") (set_attr "mode" "<MODE>")] ) @@ -3946,29 +3951,6 @@ (set_attr "mode" "<MODE>")] ) -(define_insn "aarch64_frecp<FRECP:frecp_suffix><mode>" - [(set (match_operand:GPF 0 "register_operand" "=w") - (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")] - FRECP))] - "TARGET_FLOAT" - "frecp<FRECP:frecp_suffix>\\t%<s>0, %<s>1" - [(set_attr "v8type" "frecp<FRECP:frecp_suffix>") - (set_attr "type" "ffarith<s>") - (set_attr "mode" "<MODE>")] -) - -(define_insn "aarch64_frecps<mode>" - [(set (match_operand:GPF 0 "register_operand" "=w") - (unspec:GPF [(match_operand:GPF 1 "register_operand" "w") - (match_operand:GPF 2 "register_operand" "w")] - UNSPEC_FRECPS))] - "TARGET_FLOAT" - "frecps\\t%<s>0, %<s>1, %<s>2" - [(set_attr "v8type" "frecps") - (set_attr "type" "ffarith<s>") - (set_attr "mode" "<MODE>")] -) - ;; ------------------------------------------------------------------- ;; Reload support ;; ------------------------------------------------------------------- @@ -4031,7 +4013,7 @@ "reload_completed || reload_in_progress" "fmov\\t%x0, %d1" [(set_attr "v8type" "fmovf2i") - (set_attr "type" "f_2_r") + (set_attr "type" "f_mrc") (set_attr "mode" "DI") (set_attr "length" "4") ]) @@ -4044,7 +4026,7 @@ "reload_completed || reload_in_progress" "fmov\\t%x0, %1.d[1]" [(set_attr "v8type" "fmovf2i") - (set_attr "type" "f_2_r") + (set_attr "type" "f_mrc") (set_attr "mode" "DI") (set_attr "length" "4") ]) @@ -4056,7 +4038,7 @@ "reload_completed || reload_in_progress" "fmov\\t%0.d[1], %x1" [(set_attr "v8type" "fmovi2f") - (set_attr "type" "r_2_f") + (set_attr "type" "f_mcr") (set_attr "mode" "DI") (set_attr "length" "4") ]) @@ -4067,7 +4049,7 @@ "reload_completed || reload_in_progress" "fmov\\t%d0, %x1" [(set_attr "v8type" "fmovi2f") - (set_attr "type" "r_2_f") + (set_attr "type" "f_mcr") (set_attr "mode" "DI") (set_attr "length" "4") ]) @@ -4079,7 +4061,7 @@ "reload_completed || reload_in_progress" "fmov\\t%d0, %d1" [(set_attr "v8type" "fmovi2f") - (set_attr "type" "r_2_f") + (set_attr "type" "f_mcr") (set_attr "mode" "DI") (set_attr "length" "4") ]) @@ -4112,7 +4094,7 @@ "" "add\\t%<w>0, %<w>1, :lo12:%a2" [(set_attr "v8type" "alu") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_reg") (set_attr "mode" "<MODE>")] ) @@ -4160,7 +4142,7 @@ "" "mrs\\t%0, tpidr_el0" [(set_attr "v8type" "mrs") - (set_attr "type" "mov_reg") + (set_attr "type" "mrs") (set_attr "mode" "DI")] ) @@ -4209,7 +4191,7 @@ "" "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2" [(set_attr "v8type" "alu") - (set_attr "type" "arlo_reg") + (set_attr "type" "alu_reg") (set_attr "mode" "DI") (set_attr "length" "8")] ) diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h index 29d1378b8e6..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_), "w"(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_), "w"(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_), "w"(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_), "w"(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) { @@ -7267,7 +7046,7 @@ vmla_n_s16 (int16x4_t a, int16x4_t b, int16_t c) int16x4_t result; __asm__ ("mla %0.4h,%2.4h,%3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -7289,7 +7068,7 @@ vmla_n_u16 (uint16x4_t a, uint16x4_t b, uint16_t c) uint16x4_t result; __asm__ ("mla %0.4h,%2.4h,%3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -7380,7 +7159,7 @@ vmla_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c) int32x4_t result; \ __asm__ ("smlal2 %0.4s, %2.8h, %3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -7408,7 +7187,7 @@ vmla_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c) uint32x4_t result; \ __asm__ ("umlal2 %0.4s, %2.8h, %3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -7436,7 +7215,7 @@ vmla_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c) int32x4_t result; \ __asm__ ("smlal2 %0.4s, %2.8h, %3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -7464,7 +7243,7 @@ vmla_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c) uint32x4_t result; \ __asm__ ("umlal2 %0.4s, %2.8h, %3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -7489,7 +7268,7 @@ vmlal_high_n_s16 (int32x4_t a, int16x8_t b, int16_t c) int32x4_t result; __asm__ ("smlal2 %0.4s,%2.8h,%3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -7511,7 +7290,7 @@ vmlal_high_n_u16 (uint32x4_t a, uint16x8_t b, uint16_t c) uint32x4_t result; __asm__ ("umlal2 %0.4s,%2.8h,%3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -7602,7 +7381,7 @@ vmlal_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c) int32x4_t result; \ __asm__ ("smlal %0.4s,%2.4h,%3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -7630,7 +7409,7 @@ vmlal_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c) uint32x4_t result; \ __asm__ ("umlal %0.4s,%2.4h,%3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -7658,7 +7437,7 @@ vmlal_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c) int32x4_t result; \ __asm__ ("smlal %0.4s, %2.4h, %3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -7686,7 +7465,7 @@ vmlal_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c) uint32x4_t result; \ __asm__ ("umlal %0.4s, %2.4h, %3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -7711,7 +7490,7 @@ vmlal_n_s16 (int32x4_t a, int16x4_t b, int16_t c) int32x4_t result; __asm__ ("smlal %0.4s,%2.4h,%3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -7733,7 +7512,7 @@ vmlal_n_u16 (uint32x4_t a, uint16x4_t b, uint16_t c) uint32x4_t result; __asm__ ("umlal %0.4s,%2.4h,%3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -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_), "w"(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_), "w"(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_), "w"(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_), "w"(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) { @@ -7972,7 +7624,7 @@ vmlaq_n_s16 (int16x8_t a, int16x8_t b, int16_t c) int16x8_t result; __asm__ ("mla %0.8h,%2.8h,%3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -7994,7 +7646,7 @@ vmlaq_n_u16 (uint16x8_t a, uint16x8_t b, uint16_t c) uint16x8_t result; __asm__ ("mla %0.8h,%2.8h,%3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -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_), "w"(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_), "w"(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) { @@ -8165,7 +7746,7 @@ vmls_n_s16 (int16x4_t a, int16x4_t b, int16_t c) int16x4_t result; __asm__ ("mls %0.4h, %2.4h, %3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -8187,7 +7768,7 @@ vmls_n_u16 (uint16x4_t a, uint16x4_t b, uint16_t c) uint16x4_t result; __asm__ ("mls %0.4h, %2.4h, %3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -8278,7 +7859,7 @@ vmls_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c) int32x4_t result; \ __asm__ ("smlsl2 %0.4s, %2.8h, %3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -8306,7 +7887,7 @@ vmls_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c) uint32x4_t result; \ __asm__ ("umlsl2 %0.4s, %2.8h, %3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -8334,7 +7915,7 @@ vmls_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c) int32x4_t result; \ __asm__ ("smlsl2 %0.4s, %2.8h, %3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -8362,7 +7943,7 @@ vmls_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c) uint32x4_t result; \ __asm__ ("umlsl2 %0.4s, %2.8h, %3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -8387,7 +7968,7 @@ vmlsl_high_n_s16 (int32x4_t a, int16x8_t b, int16_t c) int32x4_t result; __asm__ ("smlsl2 %0.4s, %2.8h, %3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -8409,7 +7990,7 @@ vmlsl_high_n_u16 (uint32x4_t a, uint16x8_t b, uint16_t c) uint32x4_t result; __asm__ ("umlsl2 %0.4s, %2.8h, %3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -8500,7 +8081,7 @@ vmlsl_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c) int32x4_t result; \ __asm__ ("smlsl %0.4s, %2.4h, %3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -8528,7 +8109,7 @@ vmlsl_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c) uint32x4_t result; \ __asm__ ("umlsl %0.4s, %2.4h, %3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -8556,7 +8137,7 @@ vmlsl_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c) int32x4_t result; \ __asm__ ("smlsl %0.4s, %2.4h, %3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -8584,7 +8165,7 @@ vmlsl_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c) uint32x4_t result; \ __asm__ ("umlsl %0.4s, %2.4h, %3.h[%4]" \ : "=w"(result) \ - : "0"(a_), "w"(b_), "w"(c_), "i"(d) \ + : "0"(a_), "w"(b_), "x"(c_), "i"(d) \ : /* No clobbers */); \ result; \ }) @@ -8609,7 +8190,7 @@ vmlsl_n_s16 (int32x4_t a, int16x4_t b, int16_t c) int32x4_t result; __asm__ ("smlsl %0.4s, %2.4h, %3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -8631,7 +8212,7 @@ vmlsl_n_u16 (uint32x4_t a, uint16x4_t b, uint16_t c) uint32x4_t result; __asm__ ("umlsl %0.4s, %2.4h, %3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -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_), "w"(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_), "w"(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_), "w"(__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_), "w"(__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) { @@ -8874,7 +8313,7 @@ vmlsq_n_f64 (float64x2_t a, float64x2_t b, float64_t c) float64x2_t t1; __asm__ ("fmul %1.2d, %3.2d, %4.d[0]; fsub %0.2d, %0.2d, %1.2d" : "=w"(result), "=w"(t1) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -8885,7 +8324,7 @@ vmlsq_n_s16 (int16x8_t a, int16x8_t b, int16_t c) int16x8_t result; __asm__ ("mls %0.8h, %2.8h, %3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -8907,7 +8346,7 @@ vmlsq_n_u16 (uint16x8_t a, uint16x8_t b, uint16_t c) uint16x8_t result; __asm__ ("mls %0.8h, %2.8h, %3.h[0]" : "=w"(result) - : "0"(a), "w"(b), "w"(c) + : "0"(a), "w"(b), "x"(c) : /* No clobbers */); return result; } @@ -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) { @@ -9648,7 +8957,7 @@ vmul_n_s16 (int16x4_t a, int16_t b) int16x4_t result; __asm__ ("mul %0.4h,%1.4h,%2.h[0]" : "=w"(result) - : "w"(a), "w"(b) + : "w"(a), "x"(b) : /* No clobbers */); return result; } @@ -9670,7 +8979,7 @@ vmul_n_u16 (uint16x4_t a, uint16_t b) uint16x4_t result; __asm__ ("mul %0.4h,%1.4h,%2.h[0]" : "=w"(result) - : "w"(a), "w"(b) + : "w"(a), "x"(b) : /* No clobbers */); return result; } @@ -9707,7 +9016,7 @@ vmul_n_u32 (uint32x2_t a, uint32_t b) int32x4_t result; \ __asm__ ("smull2 %0.4s, %1.8h, %2.h[%3]" \ : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ + : "w"(a_), "x"(b_), "i"(c) \ : /* No clobbers */); \ result; \ }) @@ -9733,7 +9042,7 @@ vmul_n_u32 (uint32x2_t a, uint32_t b) uint32x4_t result; \ __asm__ ("umull2 %0.4s, %1.8h, %2.h[%3]" \ : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ + : "w"(a_), "x"(b_), "i"(c) \ : /* No clobbers */); \ result; \ }) @@ -9759,7 +9068,7 @@ vmul_n_u32 (uint32x2_t a, uint32_t b) int32x4_t result; \ __asm__ ("smull2 %0.4s, %1.8h, %2.h[%3]" \ : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ + : "w"(a_), "x"(b_), "i"(c) \ : /* No clobbers */); \ result; \ }) @@ -9785,7 +9094,7 @@ vmul_n_u32 (uint32x2_t a, uint32_t b) uint32x4_t result; \ __asm__ ("umull2 %0.4s, %1.8h, %2.h[%3]" \ : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ + : "w"(a_), "x"(b_), "i"(c) \ : /* No clobbers */); \ result; \ }) @@ -9809,7 +9118,7 @@ vmull_high_n_s16 (int16x8_t a, int16_t b) int32x4_t result; __asm__ ("smull2 %0.4s,%1.8h,%2.h[0]" : "=w"(result) - : "w"(a), "w"(b) + : "w"(a), "x"(b) : /* No clobbers */); return result; } @@ -9831,7 +9140,7 @@ vmull_high_n_u16 (uint16x8_t a, uint16_t b) uint32x4_t result; __asm__ ("umull2 %0.4s,%1.8h,%2.h[0]" : "=w"(result) - : "w"(a), "w"(b) + : "w"(a), "x"(b) : /* No clobbers */); return result; } @@ -9932,7 +9241,7 @@ vmull_high_u32 (uint32x4_t a, uint32x4_t b) int32x4_t result; \ __asm__ ("smull %0.4s,%1.4h,%2.h[%3]" \ : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ + : "w"(a_), "x"(b_), "i"(c) \ : /* No clobbers */); \ result; \ }) @@ -9958,7 +9267,7 @@ vmull_high_u32 (uint32x4_t a, uint32x4_t b) uint32x4_t result; \ __asm__ ("umull %0.4s,%1.4h,%2.h[%3]" \ : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ + : "w"(a_), "x"(b_), "i"(c) \ : /* No clobbers */); \ result; \ }) @@ -9984,7 +9293,7 @@ vmull_high_u32 (uint32x4_t a, uint32x4_t b) int32x4_t result; \ __asm__ ("smull %0.4s, %1.4h, %2.h[%3]" \ : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ + : "w"(a_), "x"(b_), "i"(c) \ : /* No clobbers */); \ result; \ }) @@ -10010,7 +9319,7 @@ vmull_high_u32 (uint32x4_t a, uint32x4_t b) uint32x4_t result; \ __asm__ ("umull %0.4s, %1.4h, %2.h[%3]" \ : "=w"(result) \ - : "w"(a_), "w"(b_), "i"(c) \ + : "w"(a_), "x"(b_), "i"(c) \ : /* No clobbers */); \ result; \ }) @@ -10034,7 +9343,7 @@ vmull_n_s16 (int16x4_t a, int16_t b) int32x4_t result; __asm__ ("smull %0.4s,%1.4h,%2.h[0]" : "=w"(result) - : "w"(a), "w"(b) + : "w"(a), "x"(b) : /* No clobbers */); return result; } @@ -10056,7 +9365,7 @@ vmull_n_u16 (uint16x4_t a, uint16_t b) uint32x4_t result; __asm__ ("umull %0.4s,%1.4h,%2.h[0]" : "=w"(result) - : "w"(a), "w"(b) + : "w"(a), "x"(b) : /* No clobbers */); return result; } @@ -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_), "w"(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_), "w"(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_), "w"(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_), "w"(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) { @@ -10333,7 +9486,7 @@ vmulq_n_s16 (int16x8_t a, int16_t b) int16x8_t result; __asm__ ("mul %0.8h,%1.8h,%2.h[0]" : "=w"(result) - : "w"(a), "w"(b) + : "w"(a), "x"(b) : /* No clobbers */); return result; } @@ -10355,7 +9508,7 @@ vmulq_n_u16 (uint16x8_t a, uint16_t b) uint16x8_t result; __asm__ ("mul %0.8h,%1.8h,%2.h[0]" : "=w"(result) - : "w"(a), "w"(b) + : "w"(a), "x"(b) : /* No clobbers */); return result; } @@ -11821,7 +10974,7 @@ vqrdmulh_n_s16 (int16x4_t a, int16_t b) int16x4_t result; __asm__ ("sqrdmulh %0.4h,%1.4h,%2.h[0]" : "=w"(result) - : "w"(a), "w"(b) + : "w"(a), "x"(b) : /* No clobbers */); return result; } @@ -11843,7 +10996,7 @@ vqrdmulhq_n_s16 (int16x8_t a, int16_t b) int16x8_t result; __asm__ ("sqrdmulh %0.8h,%1.8h,%2.h[0]" : "=w"(result) - : "w"(a), "w"(b) + : "w"(a), "x"(b) : /* No clobbers */); return result; } @@ -12764,11 +11917,11 @@ vrsqrte_f32 (float32x2_t a) return result; } -__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -vrsqrte_f64 (float64x2_t a) +__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) +vrsqrte_f64 (float64x1_t a) { - float64x2_t result; - __asm__ ("frsqrte %0.2d,%1.2d" + float64x1_t result; + __asm__ ("frsqrte %d0,%d1" : "=w"(result) : "w"(a) : /* No clobbers */); @@ -15973,7 +15126,7 @@ vqtbl1_p8 (poly8x16_t a, uint8x8_t b) } __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -vqtbl1_s8 (int8x16_t a, int8x8_t b) +vqtbl1_s8 (int8x16_t a, uint8x8_t b) { int8x8_t result; __asm__ ("tbl %0.8b, {%1.16b}, %2.8b" @@ -16006,7 +15159,7 @@ vqtbl1q_p8 (poly8x16_t a, uint8x16_t b) } __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -vqtbl1q_s8 (int8x16_t a, int8x16_t b) +vqtbl1q_s8 (int8x16_t a, uint8x16_t b) { int8x16_t result; __asm__ ("tbl %0.16b, {%1.16b}, %2.16b" @@ -16028,7 +15181,7 @@ vqtbl1q_u8 (uint8x16_t a, uint8x16_t b) } __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -vqtbl2_s8 (int8x16x2_t tab, int8x8_t idx) +vqtbl2_s8 (int8x16x2_t tab, uint8x8_t idx) { int8x8_t result; __asm__ ("ld1 {v16.16b, v17.16b}, %1\n\t" @@ -16064,7 +15217,7 @@ vqtbl2_p8 (poly8x16x2_t tab, uint8x8_t idx) } __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -vqtbl2q_s8 (int8x16x2_t tab, int8x16_t idx) +vqtbl2q_s8 (int8x16x2_t tab, uint8x16_t idx) { int8x16_t result; __asm__ ("ld1 {v16.16b, v17.16b}, %1\n\t" @@ -16100,7 +15253,7 @@ vqtbl2q_p8 (poly8x16x2_t tab, uint8x16_t idx) } __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -vqtbl3_s8 (int8x16x3_t tab, int8x8_t idx) +vqtbl3_s8 (int8x16x3_t tab, uint8x8_t idx) { int8x8_t result; __asm__ ("ld1 {v16.16b - v18.16b}, %1\n\t" @@ -16136,7 +15289,7 @@ vqtbl3_p8 (poly8x16x3_t tab, uint8x8_t idx) } __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -vqtbl3q_s8 (int8x16x3_t tab, int8x16_t idx) +vqtbl3q_s8 (int8x16x3_t tab, uint8x16_t idx) { int8x16_t result; __asm__ ("ld1 {v16.16b - v18.16b}, %1\n\t" @@ -16172,7 +15325,7 @@ vqtbl3q_p8 (poly8x16x3_t tab, uint8x16_t idx) } __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -vqtbl4_s8 (int8x16x4_t tab, int8x8_t idx) +vqtbl4_s8 (int8x16x4_t tab, uint8x8_t idx) { int8x8_t result; __asm__ ("ld1 {v16.16b - v19.16b}, %1\n\t" @@ -16209,7 +15362,7 @@ vqtbl4_p8 (poly8x16x4_t tab, uint8x8_t idx) __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -vqtbl4q_s8 (int8x16x4_t tab, int8x16_t idx) +vqtbl4q_s8 (int8x16x4_t tab, uint8x16_t idx) { int8x16_t result; __asm__ ("ld1 {v16.16b - v19.16b}, %1\n\t" @@ -16246,7 +15399,7 @@ vqtbl4q_p8 (poly8x16x4_t tab, uint8x16_t idx) __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -vqtbx1_s8 (int8x8_t r, int8x16_t tab, int8x8_t idx) +vqtbx1_s8 (int8x8_t r, int8x16_t tab, uint8x8_t idx) { int8x8_t result = r; __asm__ ("tbx %0.8b,{%1.16b},%2.8b" @@ -16279,7 +15432,7 @@ vqtbx1_p8 (poly8x8_t r, poly8x16_t tab, uint8x8_t idx) } __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -vqtbx1q_s8 (int8x16_t r, int8x16_t tab, int8x16_t idx) +vqtbx1q_s8 (int8x16_t r, int8x16_t tab, uint8x16_t idx) { int8x16_t result = r; __asm__ ("tbx %0.16b,{%1.16b},%2.16b" @@ -16312,7 +15465,7 @@ vqtbx1q_p8 (poly8x16_t r, poly8x16_t tab, uint8x16_t idx) } __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -vqtbx2_s8 (int8x8_t r, int8x16x2_t tab, int8x8_t idx) +vqtbx2_s8 (int8x8_t r, int8x16x2_t tab, uint8x8_t idx) { int8x8_t result = r; __asm__ ("ld1 {v16.16b, v17.16b}, %1\n\t" @@ -16349,7 +15502,7 @@ vqtbx2_p8 (poly8x8_t r, poly8x16x2_t tab, uint8x8_t idx) __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -vqtbx2q_s8 (int8x16_t r, int8x16x2_t tab, int8x16_t idx) +vqtbx2q_s8 (int8x16_t r, int8x16x2_t tab, uint8x16_t idx) { int8x16_t result = r; __asm__ ("ld1 {v16.16b, v17.16b}, %1\n\t" @@ -16386,7 +15539,7 @@ vqtbx2q_p8 (poly8x16_t r, poly8x16x2_t tab, uint8x16_t idx) __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -vqtbx3_s8 (int8x8_t r, int8x16x3_t tab, int8x8_t idx) +vqtbx3_s8 (int8x8_t r, int8x16x3_t tab, uint8x8_t idx) { int8x8_t result = r; __asm__ ("ld1 {v16.16b - v18.16b}, %1\n\t" @@ -16423,7 +15576,7 @@ vqtbx3_p8 (poly8x8_t r, poly8x16x3_t tab, uint8x8_t idx) __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -vqtbx3q_s8 (int8x16_t r, int8x16x3_t tab, int8x16_t idx) +vqtbx3q_s8 (int8x16_t r, int8x16x3_t tab, uint8x16_t idx) { int8x16_t result = r; __asm__ ("ld1 {v16.16b - v18.16b}, %1\n\t" @@ -16460,7 +15613,7 @@ vqtbx3q_p8 (poly8x16_t r, poly8x16x3_t tab, uint8x16_t idx) __extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -vqtbx4_s8 (int8x8_t r, int8x16x4_t tab, int8x8_t idx) +vqtbx4_s8 (int8x8_t r, int8x16x4_t tab, uint8x8_t idx) { int8x8_t result = r; __asm__ ("ld1 {v16.16b - v19.16b}, %1\n\t" @@ -16497,7 +15650,7 @@ vqtbx4_p8 (poly8x8_t r, poly8x16x4_t tab, uint8x8_t idx) __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -vqtbx4q_s8 (int8x16_t r, int8x16x4_t tab, int8x16_t idx) +vqtbx4q_s8 (int8x16_t r, int8x16x4_t tab, uint8x16_t idx) { int8x16_t result = r; __asm__ ("ld1 {v16.16b - v19.16b}, %1\n\t" @@ -19750,59 +18903,59 @@ vdupq_laneq_u64 (uint64x2_t __a, const int __b) /* vdupb_lane */ __extension__ static __inline poly8_t __attribute__ ((__always_inline__)) -vdupb_lane_p8 (poly8x8_t __a, const int __attribute__ ((unused)) __b) +vdupb_lane_p8 (poly8x8_t __a, const int __b) { - return __aarch64_vget_lane_p8 (__a, 0); + return __aarch64_vget_lane_p8 (__a, __b); } __extension__ static __inline int8_t __attribute__ ((__always_inline__)) -vdupb_lane_s8 (int8x8_t __a, const int __attribute__ ((unused)) __b) +vdupb_lane_s8 (int8x8_t __a, const int __b) { - return __aarch64_vget_lane_s8 (__a, 0); + return __aarch64_vget_lane_s8 (__a, __b); } __extension__ static __inline uint8_t __attribute__ ((__always_inline__)) -vdupb_lane_u8 (uint8x8_t __a, const int __attribute__ ((unused)) __b) +vdupb_lane_u8 (uint8x8_t __a, const int __b) { - return __aarch64_vget_lane_u8 (__a, 0); + return __aarch64_vget_lane_u8 (__a, __b); } /* vduph_lane */ __extension__ static __inline poly16_t __attribute__ ((__always_inline__)) -vduph_lane_p16 (poly16x4_t __a, const int __attribute__ ((unused)) __b) +vduph_lane_p16 (poly16x4_t __a, const int __b) { - return __aarch64_vget_lane_p16 (__a, 0); + return __aarch64_vget_lane_p16 (__a, __b); } __extension__ static __inline int16_t __attribute__ ((__always_inline__)) -vduph_lane_s16 (int16x4_t __a, const int __attribute__ ((unused)) __b) +vduph_lane_s16 (int16x4_t __a, const int __b) { - return __aarch64_vget_lane_s16 (__a, 0); + return __aarch64_vget_lane_s16 (__a, __b); } __extension__ static __inline uint16_t __attribute__ ((__always_inline__)) -vduph_lane_u16 (uint16x4_t __a, const int __attribute__ ((unused)) __b) +vduph_lane_u16 (uint16x4_t __a, const int __b) { - return __aarch64_vget_lane_u16 (__a, 0); + return __aarch64_vget_lane_u16 (__a, __b); } /* vdups_lane */ __extension__ static __inline float32_t __attribute__ ((__always_inline__)) -vdups_lane_f32 (float32x2_t __a, const int __attribute__ ((unused)) __b) +vdups_lane_f32 (float32x2_t __a, const int __b) { - return __aarch64_vget_lane_f32 (__a, 0); + return __aarch64_vget_lane_f32 (__a, __b); } __extension__ static __inline int32_t __attribute__ ((__always_inline__)) -vdups_lane_s32 (int32x2_t __a, const int __attribute__ ((unused)) __b) +vdups_lane_s32 (int32x2_t __a, const int __b) { - return __aarch64_vget_lane_s32 (__a, 0); + return __aarch64_vget_lane_s32 (__a, __b); } __extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -vdups_lane_u32 (uint32x2_t __a, const int __attribute__ ((unused)) __b) +vdups_lane_u32 (uint32x2_t __a, const int __b) { - return __aarch64_vget_lane_u32 (__a, 0); + return __aarch64_vget_lane_u32 (__a, __b); } /* vdupd_lane */ @@ -19826,78 +18979,282 @@ vdupd_lane_u64 (uint64x1_t __a, const int __attribute__ ((unused)) __b) /* vdupb_laneq */ __extension__ static __inline poly8_t __attribute__ ((__always_inline__)) -vdupb_laneq_p8 (poly8x16_t __a, const int __attribute__ ((unused)) __b) +vdupb_laneq_p8 (poly8x16_t __a, const int __b) { - return __aarch64_vgetq_lane_p8 (__a, 0); + return __aarch64_vgetq_lane_p8 (__a, __b); } __extension__ static __inline int8_t __attribute__ ((__always_inline__)) vdupb_laneq_s8 (int8x16_t __a, const int __attribute__ ((unused)) __b) { - return __aarch64_vgetq_lane_s8 (__a, 0); + return __aarch64_vgetq_lane_s8 (__a, __b); } __extension__ static __inline uint8_t __attribute__ ((__always_inline__)) -vdupb_laneq_u8 (uint8x16_t __a, const int __attribute__ ((unused)) __b) +vdupb_laneq_u8 (uint8x16_t __a, const int __b) { - return __aarch64_vgetq_lane_u8 (__a, 0); + return __aarch64_vgetq_lane_u8 (__a, __b); } /* vduph_laneq */ __extension__ static __inline poly16_t __attribute__ ((__always_inline__)) -vduph_laneq_p16 (poly16x8_t __a, const int __attribute__ ((unused)) __b) +vduph_laneq_p16 (poly16x8_t __a, const int __b) { - return __aarch64_vgetq_lane_p16 (__a, 0); + return __aarch64_vgetq_lane_p16 (__a, __b); } __extension__ static __inline int16_t __attribute__ ((__always_inline__)) -vduph_laneq_s16 (int16x8_t __a, const int __attribute__ ((unused)) __b) +vduph_laneq_s16 (int16x8_t __a, const int __b) { - return __aarch64_vgetq_lane_s16 (__a, 0); + return __aarch64_vgetq_lane_s16 (__a, __b); } __extension__ static __inline uint16_t __attribute__ ((__always_inline__)) -vduph_laneq_u16 (uint16x8_t __a, const int __attribute__ ((unused)) __b) +vduph_laneq_u16 (uint16x8_t __a, const int __b) { - return __aarch64_vgetq_lane_u16 (__a, 0); + return __aarch64_vgetq_lane_u16 (__a, __b); } /* vdups_laneq */ __extension__ static __inline float32_t __attribute__ ((__always_inline__)) -vdups_laneq_f32 (float32x4_t __a, const int __attribute__ ((unused)) __b) +vdups_laneq_f32 (float32x4_t __a, const int __b) { - return __aarch64_vgetq_lane_f32 (__a, 0); + return __aarch64_vgetq_lane_f32 (__a, __b); } __extension__ static __inline int32_t __attribute__ ((__always_inline__)) -vdups_laneq_s32 (int32x4_t __a, const int __attribute__ ((unused)) __b) +vdups_laneq_s32 (int32x4_t __a, const int __b) { - return __aarch64_vgetq_lane_s32 (__a, 0); + return __aarch64_vgetq_lane_s32 (__a, __b); } __extension__ static __inline uint32_t __attribute__ ((__always_inline__)) -vdups_laneq_u32 (uint32x4_t __a, const int __attribute__ ((unused)) __b) +vdups_laneq_u32 (uint32x4_t __a, const int __b) { - return __aarch64_vgetq_lane_u32 (__a, 0); + return __aarch64_vgetq_lane_u32 (__a, __b); } /* vdupd_laneq */ __extension__ static __inline float64_t __attribute__ ((__always_inline__)) -vdupd_laneq_f64 (float64x2_t __a, const int __attribute__ ((unused)) __b) +vdupd_laneq_f64 (float64x2_t __a, const int __b) { - return __aarch64_vgetq_lane_f64 (__a, 0); + return __aarch64_vgetq_lane_f64 (__a, __b); } __extension__ static __inline int64_t __attribute__ ((__always_inline__)) -vdupd_laneq_s64 (int64x2_t __a, const int __attribute__ ((unused)) __b) +vdupd_laneq_s64 (int64x2_t __a, const int __b) { - return __aarch64_vgetq_lane_s64 (__a, 0); + return __aarch64_vgetq_lane_s64 (__a, __b); } __extension__ static __inline uint64_t __attribute__ ((__always_inline__)) -vdupd_laneq_u64 (uint64x2_t __a, const int __attribute__ ((unused)) __b) +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 __aarch64_vgetq_lane_u64 (__a, 0); + 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 */ @@ -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 3a91d4df87c..2b14ef39033 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/alpha/linux.h b/gcc/config/alpha/linux.h index 68423c5b781..da5842fda85 100644 --- a/gcc/config/alpha/linux.h +++ b/gcc/config/alpha/linux.h @@ -59,8 +59,12 @@ along with GCC; see the file COPYING3. If not see #ifdef SINGLE_LIBC #define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC) +#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC) +#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC) #else #define OPTION_GLIBC (linux_libc == LIBC_GLIBC) +#define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC) +#define OPTION_BIONIC (linux_libc == LIBC_BIONIC) #endif /* Determine what functions are present at the runtime; diff --git a/gcc/config/arm/arm-fixed.md b/gcc/config/arm/arm-fixed.md index dc8e7ac8c14..3972a850990 100644 --- a/gcc/config/arm/arm-fixed.md +++ b/gcc/config/arm/arm-fixed.md @@ -25,7 +25,8 @@ "TARGET_32BIT" "add%?\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "yes,no")]) + (set_attr "predicable_short_it" "yes,no") + (set_attr "type" "alu_reg")]) (define_insn "add<mode>3" [(set (match_operand:ADDSUB 0 "s_register_operand" "=r") @@ -34,7 +35,8 @@ "TARGET_INT_SIMD" "sadd<qaddsub_suf>%?\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")]) + (set_attr "predicable_short_it" "no") + (set_attr "type" "alu_reg")]) (define_insn "usadd<mode>3" [(set (match_operand:UQADDSUB 0 "s_register_operand" "=r") @@ -43,7 +45,8 @@ "TARGET_INT_SIMD" "uqadd<qaddsub_suf>%?\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")]) + (set_attr "predicable_short_it" "no") + (set_attr "type" "alu_reg")]) (define_insn "ssadd<mode>3" [(set (match_operand:QADDSUB 0 "s_register_operand" "=r") @@ -52,7 +55,8 @@ "TARGET_INT_SIMD" "qadd<qaddsub_suf>%?\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")]) + (set_attr "predicable_short_it" "no") + (set_attr "type" "alu_reg")]) (define_insn "sub<mode>3" [(set (match_operand:FIXED 0 "s_register_operand" "=l,r") @@ -61,7 +65,8 @@ "TARGET_32BIT" "sub%?\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "yes,no")]) + (set_attr "predicable_short_it" "yes,no") + (set_attr "type" "alu_reg")]) (define_insn "sub<mode>3" [(set (match_operand:ADDSUB 0 "s_register_operand" "=r") @@ -70,7 +75,8 @@ "TARGET_INT_SIMD" "ssub<qaddsub_suf>%?\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")]) + (set_attr "predicable_short_it" "no") + (set_attr "type" "alu_reg")]) (define_insn "ussub<mode>3" [(set (match_operand:UQADDSUB 0 "s_register_operand" "=r") @@ -80,7 +86,8 @@ "TARGET_INT_SIMD" "uqsub<qaddsub_suf>%?\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")]) + (set_attr "predicable_short_it" "no") + (set_attr "type" "alu_reg")]) (define_insn "sssub<mode>3" [(set (match_operand:QADDSUB 0 "s_register_operand" "=r") @@ -89,7 +96,8 @@ "TARGET_INT_SIMD" "qsub<qaddsub_suf>%?\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")]) + (set_attr "predicable_short_it" "no") + (set_attr "type" "alu_reg")]) ;; Fractional multiplies. @@ -246,6 +254,7 @@ return ""; } [(set_attr "conds" "clob") + (set_attr "type" "multiple") (set (attr "length") (if_then_else (eq_attr "is_thumb" "yes") (if_then_else (match_test "arm_restrict_it") @@ -305,6 +314,7 @@ return ""; } [(set_attr "conds" "clob") + (set_attr "type" "multiple") (set (attr "length") (if_then_else (eq_attr "is_thumb" "yes") (if_then_else (match_test "arm_restrict_it") @@ -406,7 +416,7 @@ [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") (set_attr "shift" "1") - (set_attr "type" "arlo_shift")]) + (set_attr "type" "alu_shift_imm")]) (define_insn "arm_usatsihi" [(set (match_operand:HI 0 "s_register_operand" "=r") @@ -414,5 +424,6 @@ "TARGET_INT_SIMD" "usat%?\\t%0, #16, %1" [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "alu_imm")] ) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index fb66dff5916..f92a0ab661f 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -8664,8 +8664,14 @@ xscale_sched_adjust_cost (rtx insn, rtx link, rtx dep, int * cost) instruction we depend on is another ALU instruction, then we may have to account for an additional stall. */ if (shift_opnum != 0 - && (attr_type == TYPE_ARLO_SHIFT - || attr_type == TYPE_ARLO_SHIFT_REG + && (attr_type == TYPE_ALU_SHIFT_IMM + || attr_type == TYPE_ALUS_SHIFT_IMM + || attr_type == TYPE_LOGIC_SHIFT_IMM + || attr_type == TYPE_LOGICS_SHIFT_IMM + || attr_type == TYPE_ALU_SHIFT_REG + || attr_type == TYPE_ALUS_SHIFT_REG + || attr_type == TYPE_LOGIC_SHIFT_REG + || attr_type == TYPE_LOGICS_SHIFT_REG || attr_type == TYPE_MOV_SHIFT || attr_type == TYPE_MVN_SHIFT || attr_type == TYPE_MOV_SHIFT_REG @@ -8952,9 +8958,17 @@ cortexa7_older_only (rtx insn) switch (get_attr_type (insn)) { - case TYPE_ARLO_REG: + case TYPE_ALU_REG: + case TYPE_ALUS_REG: + case TYPE_LOGIC_REG: + case TYPE_LOGICS_REG: + case TYPE_ADC_REG: + case TYPE_ADCS_REG: + case TYPE_ADR: + case TYPE_BFM: + case TYPE_REV: case TYPE_MVN_REG: - case TYPE_SHIFT: + case TYPE_SHIFT_IMM: case TYPE_SHIFT_REG: case TYPE_LOAD_BYTE: case TYPE_LOAD1: @@ -8963,7 +8977,7 @@ cortexa7_older_only (rtx insn) case TYPE_FADDS: case TYPE_FFARITHD: case TYPE_FADDD: - case TYPE_FCPYS: + case TYPE_FMOV: case TYPE_F_CVT: case TYPE_FCMPS: case TYPE_FCMPD: @@ -8975,7 +8989,8 @@ cortexa7_older_only (rtx insn) case TYPE_FMACD: case TYPE_FDIVS: case TYPE_FDIVD: - case TYPE_F_2_R: + case TYPE_F_MRC: + case TYPE_F_MRRC: case TYPE_F_FLAG: case TYPE_F_LOADS: case TYPE_F_STORES: @@ -8998,7 +9013,10 @@ cortexa7_younger (FILE *file, int verbose, rtx insn) switch (get_attr_type (insn)) { - case TYPE_ARLO_IMM: + case TYPE_ALU_IMM: + case TYPE_ALUS_IMM: + case TYPE_LOGIC_IMM: + case TYPE_LOGICS_IMM: case TYPE_EXTEND: case TYPE_MVN_IMM: case TYPE_MOV_IMM: @@ -14248,9 +14266,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); @@ -14259,13 +14278,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; @@ -14275,12 +14310,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); @@ -16814,123 +16846,165 @@ arm_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED, } } -/* Generate and emit a pattern that will be recognized as STRD pattern. If even - number of registers are being pushed, multiple STRD patterns are created for - all register pairs. If odd number of registers are pushed, emit a - combination of STRDs and STR for the prologue saves. */ +/* Generate and emit a sequence of insns equivalent to PUSH, but using + STR and STRD. If an even number of registers are being pushed, one + or more STRD patterns are created for each register pair. If an + odd number of registers are pushed, emit an initial STR followed by + as many STRD instructions as are needed. This works best when the + stack is initially 64-bit aligned (the normal case), since it + ensures that each STRD is also 64-bit aligned. */ static void thumb2_emit_strd_push (unsigned long saved_regs_mask) { int num_regs = 0; - int i, j; + int i; + int regno; rtx par = NULL_RTX; - rtx insn = NULL_RTX; rtx dwarf = NULL_RTX; - rtx tmp, reg, tmp1; - - for (i = 0; i <= LAST_ARM_REGNUM; i++) - if (saved_regs_mask & (1 << i)) - num_regs++; + rtx tmp; + bool first = true; - gcc_assert (num_regs && num_regs <= 16); + num_regs = bit_count (saved_regs_mask); - /* Pre-decrement the stack pointer, based on there being num_regs 4-byte - registers to push. */ - tmp = gen_rtx_SET (VOIDmode, - stack_pointer_rtx, - plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs)); - RTX_FRAME_RELATED_P (tmp) = 1; - insn = emit_insn (tmp); + /* Must be at least one register to save, and can't save SP or PC. */ + gcc_assert (num_regs > 0 && num_regs <= 14); + gcc_assert (!(saved_regs_mask & (1 << SP_REGNUM))); + gcc_assert (!(saved_regs_mask & (1 << PC_REGNUM))); - /* Create sequence for DWARF info. */ + /* Create sequence for DWARF info. All the frame-related data for + debugging is held in this wrapper. */ dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1)); - /* RTLs cannot be shared, hence create new copy for dwarf. */ - tmp1 = gen_rtx_SET (VOIDmode, - stack_pointer_rtx, - plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs)); - RTX_FRAME_RELATED_P (tmp1) = 1; - XVECEXP (dwarf, 0, 0) = tmp1; + /* Describe the stack adjustment. */ + tmp = gen_rtx_SET (VOIDmode, + stack_pointer_rtx, + plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs)); + RTX_FRAME_RELATED_P (tmp) = 1; + XVECEXP (dwarf, 0, 0) = tmp; - gcc_assert (!(saved_regs_mask & (1 << SP_REGNUM))); - gcc_assert (!(saved_regs_mask & (1 << PC_REGNUM))); + /* Find the first register. */ + for (regno = 0; (saved_regs_mask & (1 << regno)) == 0; regno++) + ; - /* Var j iterates over all the registers to gather all the registers in - saved_regs_mask. Var i gives index of register R_j in stack frame. - A PARALLEL RTX of register-pair is created here, so that pattern for - STRD can be matched. If num_regs is odd, 1st register will be pushed - using STR and remaining registers will be pushed with STRD in pairs. - If num_regs is even, all registers are pushed with STRD in pairs. - Hence, skip first element for odd num_regs. */ - for (i = num_regs - 1, j = LAST_ARM_REGNUM; i >= (num_regs % 2); j--) - if (saved_regs_mask & (1 << j)) - { - /* Create RTX for store. New RTX is created for dwarf as - they are not sharable. */ - reg = gen_rtx_REG (SImode, j); - tmp = gen_rtx_SET (SImode, - gen_frame_mem - (SImode, - plus_constant (Pmode, stack_pointer_rtx, 4 * i)), - reg); + i = 0; - tmp1 = gen_rtx_SET (SImode, - gen_frame_mem - (SImode, - plus_constant (Pmode, stack_pointer_rtx, 4 * i)), - reg); - RTX_FRAME_RELATED_P (tmp) = 1; - RTX_FRAME_RELATED_P (tmp1) = 1; - - if (((i - (num_regs % 2)) % 2) == 1) - /* When (i - (num_regs % 2)) is odd, the RTX to be emitted is yet to - be created. Hence create it first. The STRD pattern we are - generating is : - [ (SET (MEM (PLUS (SP) (NUM))) (reg_t1)) - (SET (MEM (PLUS (SP) (NUM + 4))) (reg_t2)) ] - where the target registers need not be consecutive. */ - par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); + /* If there's an odd number of registers to push. Start off by + pushing a single register. This ensures that subsequent strd + operations are dword aligned (assuming that SP was originally + 64-bit aligned). */ + if ((num_regs & 1) != 0) + { + rtx reg, mem, insn; - /* Register R_j is added in PARALLEL RTX. If (i - (num_regs % 2)) is - even, the reg_j is added as 0th element and if it is odd, reg_i is - added as 1st element of STRD pattern shown above. */ - XVECEXP (par, 0, ((i - (num_regs % 2)) % 2)) = tmp; - XVECEXP (dwarf, 0, (i + 1)) = tmp1; + reg = gen_rtx_REG (SImode, regno); + if (num_regs == 1) + mem = gen_frame_mem (Pmode, gen_rtx_PRE_DEC (Pmode, + stack_pointer_rtx)); + else + mem = gen_frame_mem (Pmode, + gen_rtx_PRE_MODIFY + (Pmode, stack_pointer_rtx, + plus_constant (Pmode, stack_pointer_rtx, + -4 * num_regs))); - if (((i - (num_regs % 2)) % 2) == 0) - /* When (i - (num_regs % 2)) is even, RTXs for both the registers - to be loaded are generated in above given STRD pattern, and the - pattern can be emitted now. */ - emit_insn (par); + tmp = gen_rtx_SET (VOIDmode, mem, reg); + RTX_FRAME_RELATED_P (tmp) = 1; + insn = emit_insn (tmp); + RTX_FRAME_RELATED_P (insn) = 1; + add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf); + tmp = gen_rtx_SET (VOIDmode, gen_frame_mem (Pmode, stack_pointer_rtx), + reg); + RTX_FRAME_RELATED_P (tmp) = 1; + i++; + regno++; + XVECEXP (dwarf, 0, i) = tmp; + first = false; + } - i--; - } + while (i < num_regs) + if (saved_regs_mask & (1 << regno)) + { + rtx reg1, reg2, mem1, mem2; + rtx tmp0, tmp1, tmp2; + int regno2; - if ((num_regs % 2) == 1) - { - /* If odd number of registers are pushed, generate STR pattern to store - lone register. */ - for (; (saved_regs_mask & (1 << j)) == 0; j--); + /* Find the register to pair with this one. */ + for (regno2 = regno + 1; (saved_regs_mask & (1 << regno2)) == 0; + regno2++) + ; - tmp1 = gen_frame_mem (SImode, plus_constant (Pmode, - stack_pointer_rtx, 4 * i)); - reg = gen_rtx_REG (SImode, j); - tmp = gen_rtx_SET (SImode, tmp1, reg); - RTX_FRAME_RELATED_P (tmp) = 1; + reg1 = gen_rtx_REG (SImode, regno); + reg2 = gen_rtx_REG (SImode, regno2); - emit_insn (tmp); + if (first) + { + rtx insn; + + first = false; + mem1 = gen_frame_mem (Pmode, plus_constant (Pmode, + stack_pointer_rtx, + -4 * num_regs)); + mem2 = gen_frame_mem (Pmode, plus_constant (Pmode, + stack_pointer_rtx, + -4 * (num_regs - 1))); + tmp0 = gen_rtx_SET (VOIDmode, stack_pointer_rtx, + plus_constant (Pmode, stack_pointer_rtx, + -4 * (num_regs))); + tmp1 = gen_rtx_SET (VOIDmode, mem1, reg1); + tmp2 = gen_rtx_SET (VOIDmode, mem2, reg2); + RTX_FRAME_RELATED_P (tmp0) = 1; + RTX_FRAME_RELATED_P (tmp1) = 1; + RTX_FRAME_RELATED_P (tmp2) = 1; + par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (3)); + XVECEXP (par, 0, 0) = tmp0; + XVECEXP (par, 0, 1) = tmp1; + XVECEXP (par, 0, 2) = tmp2; + insn = emit_insn (par); + RTX_FRAME_RELATED_P (insn) = 1; + add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf); + } + else + { + mem1 = gen_frame_mem (Pmode, plus_constant (Pmode, + stack_pointer_rtx, + 4 * i)); + mem2 = gen_frame_mem (Pmode, plus_constant (Pmode, + stack_pointer_rtx, + 4 * (i + 1))); + tmp1 = gen_rtx_SET (VOIDmode, mem1, reg1); + tmp2 = gen_rtx_SET (VOIDmode, mem2, reg2); + RTX_FRAME_RELATED_P (tmp1) = 1; + RTX_FRAME_RELATED_P (tmp2) = 1; + par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); + XVECEXP (par, 0, 0) = tmp1; + XVECEXP (par, 0, 1) = tmp2; + emit_insn (par); + } - tmp1 = gen_rtx_SET (SImode, - gen_frame_mem - (SImode, - plus_constant (Pmode, stack_pointer_rtx, 4 * i)), - reg); - RTX_FRAME_RELATED_P (tmp1) = 1; - XVECEXP (dwarf, 0, (i + 1)) = tmp1; - } + /* Create unwind information. This is an approximation. */ + tmp1 = gen_rtx_SET (VOIDmode, + gen_frame_mem (Pmode, + plus_constant (Pmode, + stack_pointer_rtx, + 4 * i)), + reg1); + tmp2 = gen_rtx_SET (VOIDmode, + gen_frame_mem (Pmode, + plus_constant (Pmode, + stack_pointer_rtx, + 4 * (i + 1))), + reg2); + + RTX_FRAME_RELATED_P (tmp1) = 1; + RTX_FRAME_RELATED_P (tmp2) = 1; + XVECEXP (dwarf, 0, i + 1) = tmp1; + XVECEXP (dwarf, 0, i + 2) = tmp2; + i += 2; + regno = regno2 + 1; + } + else + regno++; - add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf); - RTX_FRAME_RELATED_P (insn) = 1; return; } @@ -17896,7 +17970,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; } @@ -18321,7 +18396,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) @@ -24590,7 +24666,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/arm/arm.md b/gcc/config/arm/arm.md index 45e9ada3d8e..b094cff0d7e 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -252,73 +252,6 @@ ; initialized by arm_option_override() (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched"))) -;; Classification of NEON instructions for scheduling purposes. -(define_attr "neon_type" - "neon_int_1,\ - neon_int_2,\ - neon_int_3,\ - neon_int_4,\ - neon_int_5,\ - neon_vqneg_vqabs,\ - neon_vmov,\ - neon_vaba,\ - neon_vsma,\ - neon_vaba_qqq,\ - neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\ - neon_mul_qqq_8_16_32_ddd_32,\ - neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\ - neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\ - neon_mla_qqq_8_16,\ - neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\ - neon_mla_qqq_32_qqd_32_scalar,\ - neon_mul_ddd_16_scalar_32_16_long_scalar,\ - neon_mul_qqd_32_scalar,\ - neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\ - neon_shift_1,\ - neon_shift_2,\ - neon_shift_3,\ - neon_vshl_ddd,\ - neon_vqshl_vrshl_vqrshl_qqq,\ - neon_vsra_vrsra,\ - neon_fp_vadd_ddd_vabs_dd,\ - neon_fp_vadd_qqq_vabs_qq,\ - neon_fp_vsum,\ - neon_fp_vmul_ddd,\ - neon_fp_vmul_qqd,\ - neon_fp_vmla_ddd,\ - neon_fp_vmla_qqq,\ - neon_fp_vmla_ddd_scalar,\ - neon_fp_vmla_qqq_scalar,\ - neon_fp_vrecps_vrsqrts_ddd,\ - neon_fp_vrecps_vrsqrts_qqq,\ - neon_bp_simple,\ - neon_bp_2cycle,\ - neon_bp_3cycle,\ - neon_ldr,\ - neon_str,\ - neon_vld1_1_2_regs,\ - neon_vld1_3_4_regs,\ - neon_vld2_2_regs_vld1_vld2_all_lanes,\ - neon_vld2_4_regs,\ - neon_vld3_vld4,\ - neon_vst1_1_2_regs_vst2_2_regs,\ - neon_vst1_3_4_regs,\ - neon_vst2_4_regs_vst3_vst4,\ - neon_vst3_vst4,\ - neon_vld1_vld2_lane,\ - neon_vld3_vld4_lane,\ - neon_vst1_vst2_lane,\ - neon_vst3_vst4_lane,\ - neon_vld3_vld4_all_lanes,\ - neon_mcr,\ - neon_mcr_2_mcrr,\ - neon_mrc,\ - neon_mrrc,\ - neon_ldm_2,\ - neon_stm_2,\ - none" - (const_string "none")) - ; condition codes: this one is used by final_prescan_insn to speed up ; conditionalizing instructions. It saves having to scan the rtl to see if ; it uses or alters the condition codes. @@ -344,9 +277,34 @@ (ior (eq_attr "is_thumb1" "yes") (eq_attr "type" "call")) (const_string "clob") - (if_then_else (eq_attr "neon_type" "none") - (const_string "nocond") - (const_string "unconditional")))) + (if_then_else (eq_attr "type" + "!neon_int_1, neon_int_2, neon_int_3, neon_int_4, neon_int_5,\ + neon_vqneg_vqabs, neon_vmov, neon_vaba, neon_vsma, neon_vaba_qqq,\ + neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\ + neon_mul_qqq_8_16_32_ddd_32,\ + neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\ + neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\ + neon_mla_qqq_8_16,\ + neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\ + neon_mla_qqq_32_qqd_32_scalar,\ + neon_mul_ddd_16_scalar_32_16_long_scalar, neon_mul_qqd_32_scalar,\ + neon_mla_ddd_16_scalar_qdd_32_16_long_scalar, neon_shift_1,\ + neon_shift_2, neon_shift_3, neon_vshl_ddd,\ + neon_vqshl_vrshl_vqrshl_qqq, neon_vsra_vrsra,\ + neon_fp_vadd_ddd_vabs_dd, neon_fp_vadd_qqq_vabs_qq, neon_fp_vsum,\ + neon_fp_vmul_ddd, neon_fp_vmul_qqd, neon_fp_vmla_ddd,\ + neon_fp_vmla_qqq, neon_fp_vmla_ddd_scalar, neon_fp_vmla_qqq_scalar,\ + neon_fp_vrecps_vrsqrts_ddd, neon_fp_vrecps_vrsqrts_qqq,\ + neon_bp_simple, neon_bp_2cycle, neon_bp_3cycle, neon_ldr, neon_str,\ + neon_vld1_1_2_regs, neon_vld1_3_4_regs,\ + neon_vld2_2_regs_vld1_vld2_all_lanes, neon_vld2_4_regs,\ + neon_vld3_vld4, neon_vst1_1_2_regs_vst2_2_regs, neon_vst1_3_4_regs,\ + neon_vst2_4_regs_vst3_vst4, neon_vst3_vst4, neon_vld1_vld2_lane,\ + neon_vld3_vld4_lane, neon_vst1_vst2_lane, neon_vst3_vst4_lane,\ + neon_vld3_vld4_all_lanes, neon_mcr, neon_mcr_2_mcrr, neon_mrc,\ + neon_mrrc, neon_ldm_2, neon_stm_2") + (const_string "nocond") + (const_string "unconditional")))) ; Predicable means that the insn can be conditionally executed based on ; an automatically added predicate (additional patterns are generated by @@ -372,8 +330,11 @@ ; than one on the main cpu execution unit. (define_attr "core_cycles" "single,multi" (if_then_else (eq_attr "type" - "arlo_imm, arlo_reg,\ - extend, shift, arlo_shift, float, fdivd, fdivs,\ + "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_reg,\ + alu_shift_imm, alu_shift_reg, alus_ext, alus_imm, alus_reg,\ + alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\ + logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\ + logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\ wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\ wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\ wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\ @@ -499,7 +460,8 @@ ] "TARGET_THUMB1" "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2" - [(set_attr "length" "4")] + [(set_attr "length" "4") + (set_attr "type" "multiple")] ) (define_insn_and_split "*arm_adddi3" @@ -527,7 +489,8 @@ operands[2] = gen_lowpart (SImode, operands[2]); }" [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*adddi_sesidi_di" @@ -556,7 +519,8 @@ operands[2] = gen_lowpart (SImode, operands[2]); }" [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*adddi_zesidi_di" @@ -583,7 +547,8 @@ operands[2] = gen_lowpart (SImode, operands[2]); }" [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_expand "addsi3" @@ -658,8 +623,8 @@ (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no") (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*") (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") - (const_string "arlo_imm") - (const_string "arlo_reg"))) + (const_string "alu_imm") + (const_string "alu_reg"))) ] ) @@ -709,7 +674,9 @@ operands[3] = GEN_INT (offset); operands[2] = GEN_INT (INTVAL (operands[2]) - offset); } - [(set_attr "length" "2,2,2,2,2,2,2,4,4,4")] + [(set_attr "length" "2,2,2,2,2,2,2,4,4,4") + (set_attr "type" "alus_imm,alus_imm,alus_reg,alus_reg,alus_reg, + alus_reg,alus_reg,multiple,multiple,multiple")] ) ;; Reloading and elimination of the frame pointer can @@ -740,7 +707,7 @@ sub%.\\t%0, %1, #%n2 add%.\\t%0, %1, %2" [(set_attr "conds" "set") - (set_attr "type" "arlo_imm,arlo_imm,*")] + (set_attr "type" "alus_imm,alus_imm,alus_reg")] ) (define_insn "*addsi3_compare0_scratch" @@ -756,8 +723,7 @@ cmn%?\\t%0, %1" [(set_attr "conds" "set") (set_attr "predicable" "yes") - (set_attr "type" "arlo_imm,arlo_imm,*") - ] + (set_attr "type" "alus_imm,alus_imm,alus_reg")] ) (define_insn "*compare_negsi_si" @@ -771,7 +737,8 @@ (set_attr "predicable" "yes") (set_attr "arch" "t2,*") (set_attr "length" "2,4") - (set_attr "predicable_short_it" "yes,no")] + (set_attr "predicable_short_it" "yes,no") + (set_attr "type" "alus_reg")] ) ;; This is the canonicalization of addsi3_compare0_for_combiner when the @@ -788,7 +755,8 @@ "@ add%.\\t%0, %1, %3 sub%.\\t%0, %1, #%n3" - [(set_attr "conds" "set")] + [(set_attr "conds" "set") + (set_attr "type" "alus_reg")] ) ;; Convert the sequence @@ -846,7 +814,7 @@ sub%.\\t%0, %1, #%n2 add%.\\t%0, %1, %2" [(set_attr "conds" "set") - (set_attr "type" "arlo_imm,arlo_imm,*")] + (set_attr "type" "alus_imm,alus_imm,alus_reg")] ) (define_insn "*addsi3_compare_op2" @@ -863,7 +831,7 @@ add%.\\t%0, %1, %2 sub%.\\t%0, %1, #%n2" [(set_attr "conds" "set") - (set_attr "type" "arlo_imm,arlo_imm,*")] + (set_attr "type" "alus_imm,alus_imm,alus_reg")] ) (define_insn "*compare_addsi2_op0" @@ -884,7 +852,7 @@ (set_attr "arch" "t2,t2,*,*,*") (set_attr "predicable_short_it" "yes,yes,no,no,no") (set_attr "length" "2,2,4,4,4") - (set_attr "type" "arlo_imm,*,arlo_imm,arlo_imm,*")] + (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")] ) (define_insn "*compare_addsi2_op1" @@ -905,8 +873,7 @@ (set_attr "arch" "t2,t2,*,*,*") (set_attr "predicable_short_it" "yes,yes,no,no,no") (set_attr "length" "2,2,4,4,4") - (set_attr "type" - "arlo_imm,*,arlo_imm,arlo_imm,*")] + (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")] ) (define_insn "*addsi3_carryin_<optab>" @@ -923,7 +890,8 @@ (set_attr "predicable" "yes") (set_attr "arch" "t2,*,*") (set_attr "length" "4") - (set_attr "predicable_short_it" "yes,no,no")] + (set_attr "predicable_short_it" "yes,no,no") + (set_attr "type" "adc_reg,adc_reg,adc_imm")] ) (define_insn "*addsi3_carryin_alt2_<optab>" @@ -940,7 +908,8 @@ (set_attr "predicable" "yes") (set_attr "arch" "t2,*,*") (set_attr "length" "4") - (set_attr "predicable_short_it" "yes,no,no")] + (set_attr "predicable_short_it" "yes,no,no") + (set_attr "type" "adc_reg,adc_reg,adc_imm")] ) (define_insn "*addsi3_carryin_shift_<optab>" @@ -957,8 +926,8 @@ (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") - (const_string "arlo_shift") - (const_string "arlo_shift_reg")))] + (const_string "alu_shift_imm") + (const_string "alu_shift_reg")))] ) (define_insn "*addsi3_carryin_clobercc_<optab>" @@ -969,7 +938,8 @@ (clobber (reg:CC CC_REGNUM))] "TARGET_32BIT" "adc%.\\t%0, %1, %2" - [(set_attr "conds" "set")] + [(set_attr "conds" "set") + (set_attr "type" "adcs_reg")] ) (define_insn "*subsi3_carryin" @@ -984,7 +954,8 @@ [(set_attr "conds" "use") (set_attr "arch" "*,a") (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "adc_reg,adc_imm")] ) (define_insn "*subsi3_carryin_const" @@ -994,7 +965,8 @@ (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] "TARGET_32BIT" "sbc\\t%0, %1, #%B2" - [(set_attr "conds" "use")] + [(set_attr "conds" "use") + (set_attr "type" "adc_imm")] ) (define_insn "*subsi3_carryin_compare" @@ -1007,7 +979,8 @@ (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] "TARGET_32BIT" "sbcs\\t%0, %1, %2" - [(set_attr "conds" "set")] + [(set_attr "conds" "set") + (set_attr "type" "adcs_reg")] ) (define_insn "*subsi3_carryin_compare_const" @@ -1020,7 +993,8 @@ (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] "TARGET_32BIT" "sbcs\\t%0, %1, #%B2" - [(set_attr "conds" "set")] + [(set_attr "conds" "set") + (set_attr "type" "adcs_imm")] ) (define_insn "*subsi3_carryin_shift" @@ -1036,8 +1010,8 @@ [(set_attr "conds" "use") (set_attr "predicable" "yes") (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") - (const_string "arlo_shift") - (const_string "arlo_shift_reg")))] + (const_string "alu_shift_imm") + (const_string "alu_shift_reg")))] ) (define_insn "*rsbsi3_carryin_shift" @@ -1053,8 +1027,8 @@ [(set_attr "conds" "use") (set_attr "predicable" "yes") (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") - (const_string "arlo_shift") - (const_string "arlo_shift_reg")))] + (const_string "alu_shift_imm") + (const_string "alu_shift_reg")))] ) ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant. @@ -1127,7 +1101,8 @@ operands[2] = gen_lowpart (SImode, operands[2]); } [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn "*thumb_subdi3" @@ -1137,7 +1112,8 @@ (clobber (reg:CC CC_REGNUM))] "TARGET_THUMB1" "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2" - [(set_attr "length" "4")] + [(set_attr "length" "4") + (set_attr "type" "multiple")] ) (define_insn_and_split "*subdi_di_zesidi" @@ -1162,7 +1138,8 @@ operands[5] = GEN_INT (~0); } [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*subdi_di_sesidi" @@ -1188,7 +1165,8 @@ operands[1] = gen_lowpart (SImode, operands[1]); } [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*subdi_zesidi_di" @@ -1214,7 +1192,8 @@ operands[1] = gen_lowpart (SImode, operands[1]); } [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*subdi_sesidi_di" @@ -1243,7 +1222,8 @@ operands[1] = gen_lowpart (SImode, operands[1]); } [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*subdi_zesidi_zesidi" @@ -1266,7 +1246,8 @@ operands[0] = gen_lowpart (SImode, operands[0]); } [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_expand "subsi3" @@ -1297,7 +1278,9 @@ "TARGET_THUMB1" "sub\\t%0, %1, %2" [(set_attr "length" "2") - (set_attr "conds" "set")]) + (set_attr "conds" "set") + (set_attr "type" "alus_reg")] +) ; ??? Check Thumb-2 split length (define_insn_and_split "*arm_subsi3_insn" @@ -1327,7 +1310,7 @@ (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*") (set_attr "predicable" "yes") (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no") - (set_attr "type" "*,*,*,*,arlo_imm,arlo_imm,*,*,arlo_imm")] + (set_attr "type" "alu_reg,alu_reg,alu_reg,alu_reg,alu_imm,alu_imm,alu_reg,alu_reg,multiple")] ) (define_peephole2 @@ -1357,7 +1340,7 @@ sub%.\\t%0, %1, %2 rsb%.\\t%0, %2, %1" [(set_attr "conds" "set") - (set_attr "type" "arlo_imm,*,*")] + (set_attr "type" "alus_imm,alus_reg,alus_reg")] ) (define_insn "subsi3_compare" @@ -1372,7 +1355,7 @@ sub%.\\t%0, %1, %2 rsb%.\\t%0, %2, %1" [(set_attr "conds" "set") - (set_attr "type" "arlo_imm,*,*")] + (set_attr "type" "alus_imm,alus_reg,alus_reg")] ) (define_expand "subsf3" @@ -2179,7 +2162,7 @@ gen_highpart_mode (SImode, DImode, operands[2])); }" - [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,*,*,neon_int_1,neon_int_1") + [(set_attr "type" "neon_int_1,neon_int_1,multiple,multiple,multiple,multiple,neon_int_1,neon_int_1") (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*, avoid_neon_for_64bits,avoid_neon_for_64bits") (set_attr "length" "*,*,8,8,8,8,*,*") @@ -2204,7 +2187,8 @@ operands[0] = gen_lowpart (SImode, operands[0]); operands[1] = gen_lowpart (SImode, operands[1]); }" - [(set_attr "length" "8")] + [(set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn "*anddi_sesdi_di" @@ -2214,7 +2198,8 @@ (match_operand:DI 1 "s_register_operand" "0,r")))] "TARGET_32BIT" "#" - [(set_attr "length" "8")] + [(set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_expand "andsi3" @@ -2321,8 +2306,7 @@ [(set_attr "length" "4,4,4,4,16") (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no,yes,no,no,no") - (set_attr "type" - "arlo_imm,arlo_imm,*,*,arlo_imm")] + (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")] ) (define_insn "*thumb1_andsi3_insn" @@ -2332,7 +2316,7 @@ "TARGET_THUMB1" "and\\t%0, %2" [(set_attr "length" "2") - (set_attr "type" "arlo_imm") + (set_attr "type" "logic_imm") (set_attr "conds" "set")]) (define_insn "*andsi3_compare0" @@ -2349,7 +2333,7 @@ bic%.\\t%0, %1, #%B2 and%.\\t%0, %1, %2" [(set_attr "conds" "set") - (set_attr "type" "arlo_imm,arlo_imm,*")] + (set_attr "type" "logics_imm,logics_imm,logics_reg")] ) (define_insn "*andsi3_compare0_scratch" @@ -2365,7 +2349,7 @@ bic%.\\t%2, %0, #%B1 tst%?\\t%0, %1" [(set_attr "conds" "set") - (set_attr "type" "arlo_imm,arlo_imm,*")] + (set_attr "type" "logics_imm,logics_imm,logics_reg")] ) (define_insn "*zeroextractsi_compare0_scratch" @@ -2389,7 +2373,7 @@ [(set_attr "conds" "set") (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "type" "arlo_imm")] + (set_attr "type" "logics_imm")] ) (define_insn_and_split "*ne_zeroextractsi" @@ -2426,7 +2410,8 @@ (set (attr "length") (if_then_else (eq_attr "is_thumb" "yes") (const_int 12) - (const_int 8)))] + (const_int 8))) + (set_attr "type" "multiple")] ) (define_insn_and_split "*ne_zeroextractsi_shifted" @@ -2451,7 +2436,8 @@ operands[2] = GEN_INT (32 - INTVAL (operands[2])); " [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*ite_ne_zeroextractsi" @@ -2489,7 +2475,8 @@ << INTVAL (operands[3])); " [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*ite_ne_zeroextractsi_shifted" @@ -2516,7 +2503,8 @@ operands[2] = GEN_INT (32 - INTVAL (operands[2])); " [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_split @@ -2817,7 +2805,8 @@ "bfc%?\t%0, %2, %1" [(set_attr "length" "4") (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "bfm")] ) (define_insn "insv_t2" @@ -2829,7 +2818,8 @@ "bfi%?\t%0, %3, %2, %1" [(set_attr "length" "4") (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "bfm")] ) ; constants for op 2 will never be given to these patterns. @@ -2854,7 +2844,8 @@ operands[2] = gen_lowpart (SImode, operands[2]); }" [(set_attr "length" "8") - (set_attr "predicable" "yes")] + (set_attr "predicable" "yes") + (set_attr "type" "multiple")] ) (define_insn_and_split "*anddi_notzesidi_di" @@ -2882,7 +2873,8 @@ }" [(set_attr "length" "4,8") (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "multiple")] ) (define_insn_and_split "*anddi_notsesidi_di" @@ -2906,7 +2898,8 @@ }" [(set_attr "length" "8") (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "multiple")] ) (define_insn "andsi_notsi_si" @@ -2916,7 +2909,8 @@ "TARGET_32BIT" "bic%?\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "logic_reg")] ) (define_insn "thumb1_bicsi3" @@ -2926,7 +2920,9 @@ "TARGET_THUMB1" "bic\\t%0, %1" [(set_attr "length" "2") - (set_attr "conds" "set")]) + (set_attr "conds" "set") + (set_attr "type" "logics_reg")] +) (define_insn "andsi_not_shiftsi_si" [(set (match_operand:SI 0 "s_register_operand" "=r") @@ -2939,8 +2935,8 @@ [(set_attr "predicable" "yes") (set_attr "shift" "2") (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") - (const_string "arlo_shift") - (const_string "arlo_shift_reg")))] + (const_string "logic_shift_imm") + (const_string "logic_shift_reg")))] ) (define_insn "*andsi_notsi_si_compare0" @@ -2953,7 +2949,8 @@ (and:SI (not:SI (match_dup 2)) (match_dup 1)))] "TARGET_32BIT" "bic%.\\t%0, %1, %2" - [(set_attr "conds" "set")] + [(set_attr "conds" "set") + (set_attr "type" "logics_shift_reg")] ) (define_insn "*andsi_notsi_si_compare0_scratch" @@ -2965,7 +2962,8 @@ (clobber (match_scratch:SI 0 "=r"))] "TARGET_32BIT" "bic%.\\t%0, %1, %2" - [(set_attr "conds" "set")] + [(set_attr "conds" "set") + (set_attr "type" "logics_shift_reg")] ) (define_expand "iordi3" @@ -3014,7 +3012,7 @@ gen_highpart_mode (SImode, DImode, operands[2])); }" - [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,*,*,neon_int_1,neon_int_1") + [(set_attr "type" "neon_int_1,neon_int_1,multiple,multiple,multiple,multiple,neon_int_1,neon_int_1") (set_attr "length" "*,*,8,8,8,8,*,*") (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")] ) @@ -3030,7 +3028,8 @@ #" [(set_attr "length" "4,8") (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "logic_reg,multiple")] ) (define_insn "*iordi_sesidi_di" @@ -3041,7 +3040,8 @@ "TARGET_32BIT" "#" [(set_attr "length" "8") - (set_attr "predicable" "yes")] + (set_attr "predicable" "yes") + (set_attr "type" "multiple")] ) (define_expand "iorsi3" @@ -3099,7 +3099,7 @@ (set_attr "arch" "32,t2,t2,32,32") (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no,yes,no,no,no") - (set_attr "type" "arlo_imm,*,arlo_imm,*,*")] + (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")] ) (define_insn "*thumb1_iorsi3_insn" @@ -3109,7 +3109,8 @@ "TARGET_THUMB1" "orr\\t%0, %2" [(set_attr "length" "2") - (set_attr "conds" "set")]) + (set_attr "conds" "set") + (set_attr "type" "logics_reg")]) (define_peephole2 [(match_scratch:SI 3 "r") @@ -3134,7 +3135,7 @@ "TARGET_32BIT" "orr%.\\t%0, %1, %2" [(set_attr "conds" "set") - (set_attr "type" "arlo_imm,*")] + (set_attr "type" "logics_imm,logics_reg")] ) (define_insn "*iorsi3_compare0_scratch" @@ -3146,7 +3147,7 @@ "TARGET_32BIT" "orr%.\\t%0, %1, %2" [(set_attr "conds" "set") - (set_attr "type" "arlo_imm,*")] + (set_attr "type" "logics_imm,logics_reg")] ) (define_expand "xordi3" @@ -3193,7 +3194,7 @@ }" [(set_attr "length" "*,8,8,8,8,*") - (set_attr "neon_type" "neon_int_1,*,*,*,*,neon_int_1") + (set_attr "type" "neon_int_1,multiple,multiple,multiple,multiple,neon_int_1") (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")] ) @@ -3208,7 +3209,8 @@ #" [(set_attr "length" "4,8") (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "logic_reg")] ) (define_insn "*xordi_sesidi_di" @@ -3219,7 +3221,8 @@ "TARGET_32BIT" "#" [(set_attr "length" "8") - (set_attr "predicable" "yes")] + (set_attr "predicable" "yes") + (set_attr "type" "multiple")] ) (define_expand "xorsi3" @@ -3272,7 +3275,7 @@ [(set_attr "length" "4,4,4,16") (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no,yes,no,no") - (set_attr "type" "arlo_imm,*,*,*")] + (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")] ) (define_insn "*thumb1_xorsi3_insn" @@ -3283,7 +3286,7 @@ "eor\\t%0, %2" [(set_attr "length" "2") (set_attr "conds" "set") - (set_attr "type" "arlo_imm")] + (set_attr "type" "logics_reg")] ) (define_insn "*xorsi3_compare0" @@ -3296,7 +3299,7 @@ "TARGET_32BIT" "eor%.\\t%0, %1, %2" [(set_attr "conds" "set") - (set_attr "type" "arlo_imm,*")] + (set_attr "type" "logics_imm,logics_reg")] ) (define_insn "*xorsi3_compare0_scratch" @@ -3307,7 +3310,7 @@ "TARGET_32BIT" "teq%?\\t%0, %1" [(set_attr "conds" "set") - (set_attr "type" "arlo_imm,*")] + (set_attr "type" "logics_imm,logics_reg")] ) ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), @@ -3341,7 +3344,8 @@ [(set_attr "length" "8") (set_attr "ce_count" "2") (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "multiple")] ) ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield @@ -3478,7 +3482,8 @@ "TARGET_32BIT" "bic%?\\t%0, %1, %1, asr #31" [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "logic_shift_reg")] ) (define_insn "*smax_m1" @@ -3488,7 +3493,8 @@ "TARGET_32BIT" "orr%?\\t%0, %1, %1, asr #31" [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "logic_shift_reg")] ) (define_insn_and_split "*arm_smax_insn" @@ -3509,7 +3515,8 @@ (match_dup 2)))] "" [(set_attr "conds" "clob") - (set_attr "length" "8,12")] + (set_attr "length" "8,12") + (set_attr "type" "multiple")] ) (define_expand "sminsi3" @@ -3537,7 +3544,8 @@ "TARGET_32BIT" "and%?\\t%0, %1, %1, asr #31" [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "logic_shift_reg")] ) (define_insn_and_split "*arm_smin_insn" @@ -3558,7 +3566,8 @@ (match_dup 2)))] "" [(set_attr "conds" "clob") - (set_attr "length" "8,12")] + (set_attr "length" "8,12") + (set_attr "type" "multiple,multiple")] ) (define_expand "umaxsi3" @@ -3590,7 +3599,8 @@ (match_dup 2)))] "" [(set_attr "conds" "clob") - (set_attr "length" "8,8,12")] + (set_attr "length" "8,8,12") + (set_attr "type" "store1")] ) (define_expand "uminsi3" @@ -3622,7 +3632,8 @@ (match_dup 2)))] "" [(set_attr "conds" "clob") - (set_attr "length" "8,8,12")] + (set_attr "length" "8,8,12") + (set_attr "type" "store1")] ) (define_insn "*store_minmaxsi" @@ -3691,7 +3702,8 @@ (set (attr "length") (if_then_else (eq_attr "is_thumb" "yes") (const_int 14) - (const_int 12)))] + (const_int 12))) + (set_attr "type" "multiple")] ) ; Reject the frame pointer in operand[1], since reloading this after @@ -3739,7 +3751,8 @@ (set (attr "length") (if_then_else (eq_attr "is_thumb" "yes") (const_int 14) - (const_int 12)))] + (const_int 12))) + (set_attr "type" "multiple")] ) (define_code_iterator SAT [smin smax]) @@ -3768,7 +3781,8 @@ return "usat%?\t%0, %1, %3"; } [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "alus_imm")] ) (define_insn "*satsi_<SAT:code>_shift" @@ -3796,7 +3810,7 @@ [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") (set_attr "shift" "3") - (set_attr "type" "arlo_shift")]) + (set_attr "type" "logic_shift_reg")]) ;; Shift and rotation insns @@ -3874,7 +3888,8 @@ operands[1] = gen_lowpart (SImode, operands[1]); } [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_expand "ashlsi3" @@ -3899,7 +3914,7 @@ "TARGET_THUMB1" "lsl\\t%0, %1, %2" [(set_attr "length" "2") - (set_attr "type" "shift,shift_reg") + (set_attr "type" "shift_imm,shift_reg") (set_attr "conds" "set")]) (define_expand "ashrdi3" @@ -3971,7 +3986,8 @@ operands[1] = gen_lowpart (SImode, operands[1]); } [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn "*rrx" @@ -4004,7 +4020,7 @@ "TARGET_THUMB1" "asr\\t%0, %1, %2" [(set_attr "length" "2") - (set_attr "type" "shift,shift_reg") + (set_attr "type" "shift_imm,shift_reg") (set_attr "conds" "set")]) (define_expand "lshrdi3" @@ -4076,7 +4092,8 @@ operands[1] = gen_lowpart (SImode, operands[1]); } [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_expand "lshrsi3" @@ -4101,7 +4118,7 @@ "TARGET_THUMB1" "lsr\\t%0, %1, %2" [(set_attr "length" "2") - (set_attr "type" "shift,shift_reg") + (set_attr "type" "shift_imm,shift_reg") (set_attr "conds" "set")]) (define_expand "rotlsi3" @@ -4152,18 +4169,18 @@ ) (define_insn "*arm_shiftsi3" - [(set (match_operand:SI 0 "s_register_operand" "=l,r,r") + [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r") (match_operator:SI 3 "shift_operator" - [(match_operand:SI 1 "s_register_operand" "0,r,r") - (match_operand:SI 2 "reg_or_int_operand" "l,M,r")]))] + [(match_operand:SI 1 "s_register_operand" "0,l,r,r") + (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))] "TARGET_32BIT" "* return arm_output_shift(operands, 0);" [(set_attr "predicable" "yes") - (set_attr "arch" "t2,*,*") - (set_attr "predicable_short_it" "yes,no,no") + (set_attr "arch" "t2,t2,*,*") + (set_attr "predicable_short_it" "yes,yes,no,no") (set_attr "length" "4") (set_attr "shift" "1") - (set_attr "type" "arlo_shift_reg,arlo_shift,arlo_shift_reg")] + (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")] ) (define_insn "*shiftsi3_compare" @@ -4178,7 +4195,7 @@ "* return arm_output_shift(operands, 1);" [(set_attr "conds" "set") (set_attr "shift" "1") - (set_attr "type" "arlo_shift,arlo_shift_reg")] + (set_attr "type" "alus_shift_imm,alus_shift_reg")] ) (define_insn "*shiftsi3_compare0" @@ -4193,7 +4210,7 @@ "* return arm_output_shift(operands, 1);" [(set_attr "conds" "set") (set_attr "shift" "1") - (set_attr "type" "arlo_shift,arlo_shift_reg")] + (set_attr "type" "alus_shift_imm,alus_shift_reg")] ) (define_insn "*shiftsi3_compare0_scratch" @@ -4207,7 +4224,7 @@ "* return arm_output_shift(operands, 1);" [(set_attr "conds" "set") (set_attr "shift" "1") - (set_attr "type" "shift,shift_reg")] + (set_attr "type" "shift_imm,shift_reg")] ) (define_insn "*not_shiftsi" @@ -4549,7 +4566,8 @@ "sbfx%?\t%0, %1, %3, %2" [(set_attr "length" "4") (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "bfm")] ) (define_insn "extzv_t2" @@ -4561,7 +4579,8 @@ "ubfx%?\t%0, %1, %3, %2" [(set_attr "length" "4") (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "bfm")] ) @@ -4627,7 +4646,8 @@ operands[1] = gen_lowpart (SImode, operands[1]); } [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn "*thumb1_negdi2" @@ -4636,7 +4656,8 @@ (clobber (reg:CC CC_REGNUM))] "TARGET_THUMB1" "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1" - [(set_attr "length" "6")] + [(set_attr "length" "6") + (set_attr "type" "multiple")] ) (define_expand "negsi2" @@ -4654,7 +4675,8 @@ [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "yes,no") (set_attr "arch" "t2,*") - (set_attr "length" "4")] + (set_attr "length" "4") + (set_attr "type" "alu_reg")] ) (define_insn "*thumb1_negsi2" @@ -4662,7 +4684,8 @@ (neg:SI (match_operand:SI 1 "register_operand" "l")))] "TARGET_THUMB1" "neg\\t%0, %1" - [(set_attr "length" "2")] + [(set_attr "length" "2") + (set_attr "type" "alu_imm")] ) (define_expand "negsf2" @@ -4720,7 +4743,8 @@ DONE; } [(set_attr "length" "8,8,4,4") - (set_attr "arch" "a,a,t2,t2")] + (set_attr "arch" "a,a,t2,t2") + (set_attr "type" "multiple")] ) (define_insn_and_split "*negdi_zero_extendsidi" @@ -4742,7 +4766,8 @@ operands[0] = gen_lowpart (SImode, operands[0]); } [(set_attr "conds" "clob") - (set_attr "length" "8")] ;; length in thumb is 4 + (set_attr "length" "8") + (set_attr "type" "multiple")] ;; length in thumb is 4 ) ;; abssi2 doesn't really clobber the condition codes if a different register @@ -4827,7 +4852,8 @@ [(set_attr "conds" "clob,*") (set_attr "shift" "1") (set_attr "predicable" "no, yes") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*thumb1_abssi2" @@ -4841,7 +4867,8 @@ (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))] "" - [(set_attr "length" "6")] + [(set_attr "length" "6") + (set_attr "type" "multiple")] ) (define_insn_and_split "*arm_neg_abssi2" @@ -4897,7 +4924,8 @@ [(set_attr "conds" "clob,*") (set_attr "shift" "1") (set_attr "predicable" "no, yes") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*thumb1_neg_abssi2" @@ -4911,7 +4939,8 @@ (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1))) (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))] "" - [(set_attr "length" "6")] + [(set_attr "length" "6") + (set_attr "type" "multiple")] ) (define_expand "abssf2" @@ -4960,7 +4989,7 @@ }" [(set_attr "length" "*,8,8,*") (set_attr "predicable" "no,yes,yes,no") - (set_attr "neon_type" "neon_int_1,*,*,neon_int_1") + (set_attr "type" "neon_int_1,multiple,multiple,neon_int_1") (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")] ) @@ -5147,7 +5176,8 @@ (set_attr "ce_count" "2") (set_attr "shift" "1") (set_attr "predicable" "yes") - (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")] + (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits") + (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")] ) ;; Splits for all extensions to DImode @@ -5283,7 +5313,7 @@ "@ # ldr%(h%)\\t%0, %1" - [(set_attr "type" "arlo_shift,load_byte") + [(set_attr "type" "alu_shift_reg,load_byte") (set_attr "predicable" "yes")] ) @@ -5304,7 +5334,7 @@ (match_operand:SI 2 "s_register_operand" "r")))] "TARGET_INT_SIMD" "uxtah%?\\t%0, %2, %1" - [(set_attr "type" "arlo_shift") + [(set_attr "type" "alu_shift_reg") (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no")] ) @@ -5354,7 +5384,7 @@ # ldrb\\t%0, %1" [(set_attr "length" "4,2") - (set_attr "type" "arlo_shift,load_byte") + (set_attr "type" "alu_shift_reg,load_byte") (set_attr "pool_range" "*,32")] ) @@ -5377,7 +5407,7 @@ # ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2" [(set_attr "length" "8,4") - (set_attr "type" "arlo_shift,load_byte") + (set_attr "type" "alu_shift_reg,load_byte") (set_attr "predicable" "yes")] ) @@ -5400,7 +5430,7 @@ "uxtab%?\\t%0, %2, %1" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "type" "arlo_shift")] + (set_attr "type" "alu_shift_reg")] ) (define_split @@ -5452,7 +5482,8 @@ "tst%?\\t%0, #255" [(set_attr "conds" "set") (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "logic_imm")] ) (define_expand "extendhisi2" @@ -5622,7 +5653,7 @@ # ldr%(sh%)\\t%0, %1" [(set_attr "length" "8,4") - (set_attr "type" "arlo_shift,load_byte") + (set_attr "type" "alu_shift_reg,load_byte") (set_attr "predicable" "yes") (set_attr "pool_range" "*,256") (set_attr "neg_pool_range" "*,244")] @@ -5649,6 +5680,7 @@ (match_operand:SI 2 "s_register_operand" "r")))] "TARGET_INT_SIMD" "sxtah%?\\t%0, %2, %1" + [(set_attr "type" "alu_shift_reg")] ) (define_expand "extendqihi2" @@ -5723,7 +5755,7 @@ # ldr%(sb%)\\t%0, %1" [(set_attr "length" "8,4") - (set_attr "type" "arlo_shift,load_byte") + (set_attr "type" "alu_shift_reg,load_byte") (set_attr "predicable" "yes") (set_attr "pool_range" "*,256") (set_attr "neg_pool_range" "*,244")] @@ -5749,7 +5781,7 @@ (match_operand:SI 2 "s_register_operand" "r")))] "TARGET_INT_SIMD" "sxtab%?\\t%0, %2, %1" - [(set_attr "type" "arlo_shift") + [(set_attr "type" "alu_shift_reg") (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no")] ) @@ -5969,7 +6001,7 @@ } " [(set_attr "length" "8,12,16,8,8") - (set_attr "type" "*,*,*,load2,store2") + (set_attr "type" "multiple,multiple,multiple,load2,store2") (set_attr "arm_pool_range" "*,*,*,1020,*") (set_attr "arm_neg_pool_range" "*,*,*,1004,*") (set_attr "thumb2_pool_range" "*,*,*,4094,*") @@ -6109,7 +6141,7 @@ } }" [(set_attr "length" "4,4,6,2,2,6,4,4") - (set_attr "type" "*,mov_reg,*,load2,store2,load2,store2,mov_reg") + (set_attr "type" "multiple,multiple,multiple,load2,store2,load2,store2,multiple") (set_attr "pool_range" "*,*,*,*,*,1018,*,*")] ) @@ -6207,7 +6239,8 @@ "movt%?\t%0, #:upper16:%c2" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "length" "4")] + (set_attr "length" "4") + (set_attr "type" "mov_imm")] ) (define_insn "*arm_movsi_insn" @@ -6279,7 +6312,7 @@ str\\t%1, %0 mov\\t%0, %1" [(set_attr "length" "2,2,4,4,2,2,2,2,2") - (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*") + (set_attr "type" "mov_reg,mov_imm,multiple,multiple,load1,store1,load1,store1,mov_reg") (set_attr "pool_range" "*,*,*,*,*,*,1018,*,*") (set_attr "conds" "set,clob,*,*,nocond,nocond,nocond,nocond,nocond")]) @@ -6435,7 +6468,8 @@ INTVAL (operands[2])); return \"add\\t%0, %|pc\"; " - [(set_attr "length" "2")] + [(set_attr "length" "2") + (set_attr "type" "alu_reg")] ) (define_insn "pic_add_dot_plus_eight" @@ -6450,7 +6484,8 @@ INTVAL (operands[2])); return \"add%?\\t%0, %|pc, %1\"; " - [(set_attr "predicable" "yes")] + [(set_attr "predicable" "yes") + (set_attr "type" "alu_reg")] ) (define_insn "tls_load_dot_plus_eight" @@ -6465,7 +6500,8 @@ INTVAL (operands[2])); return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\"; " - [(set_attr "predicable" "yes")] + [(set_attr "predicable" "yes") + (set_attr "type" "load1")] ) ;; PIC references to local variables can generate pic_add_dot_plus_eight @@ -6526,7 +6562,7 @@ cmp%?\\t%0, #0 sub%.\\t%0, %1, #0" [(set_attr "conds" "set") - (set_attr "type" "arlo_imm,arlo_imm")] + (set_attr "type" "alus_imm,alus_imm")] ) ;; Subroutine to store a half word from a register into memory. @@ -6872,7 +6908,7 @@ return \"ldrh %0, %1\"; }" [(set_attr "length" "2,4,2,2,2,2") - (set_attr "type" "*,load1,store1,*,*,*") + (set_attr "type" "alus_imm,load1,store1,mov_reg,mov_reg,mov_imm") (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")]) @@ -7120,7 +7156,7 @@ mov\\t%0, %1 mov\\t%0, %1" [(set_attr "length" "2") - (set_attr "type" "arlo_imm,load1,store1,mov_reg,mov_imm,mov_imm") + (set_attr "type" "alu_imm,load1,store1,mov_reg,mov_imm,mov_imm") (set_attr "pool_range" "*,32,*,*,*,*") (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")]) @@ -7185,7 +7221,7 @@ } " [(set_attr "conds" "unconditional") - (set_attr "type" "load1,store1,mov_reg,mov_reg") + (set_attr "type" "load1,store1,mov_reg,multiple") (set_attr "length" "4,4,4,8") (set_attr "predicable" "yes")] ) @@ -7298,7 +7334,7 @@ mov\\t%0, %1 mov\\t%0, %1" [(set_attr "length" "2") - (set_attr "type" "*,load1,store1,load1,store1,mov_reg,mov_reg") + (set_attr "type" "alus_imm,load1,store1,load1,store1,mov_reg,mov_reg") (set_attr "pool_range" "*,*,*,1018,*,*,*") (set_attr "conds" "clob,nocond,nocond,nocond,nocond,nocond,nocond")] ) @@ -7386,7 +7422,7 @@ } " [(set_attr "length" "8,12,16,8,8") - (set_attr "type" "*,*,*,load2,store2") + (set_attr "type" "multiple,multiple,multiple,load2,store2") (set_attr "arm_pool_range" "*,*,*,1020,*") (set_attr "thumb2_pool_range" "*,*,*,1018,*") (set_attr "arm_neg_pool_range" "*,*,*,1004,*") @@ -7430,7 +7466,7 @@ } " [(set_attr "length" "4,2,2,6,4,4") - (set_attr "type" "*,load2,store2,load2,store2,mov_reg") + (set_attr "type" "multiple,load2,store2,load2,store2,multiple") (set_attr "pool_range" "*,*,*,1018,*,*")] ) @@ -7738,7 +7774,8 @@ (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) (le (minus (match_dup 3) (pc)) (const_int 2048))) (const_int 6) - (const_int 8))))] + (const_int 8)))) + (set_attr "type" "multiple")] ) (define_insn "cbranchsi4_scratch" @@ -7774,7 +7811,8 @@ (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) (le (minus (match_dup 3) (pc)) (const_int 2048))) (const_int 6) - (const_int 8))))] + (const_int 8)))) + (set_attr "type" "multiple")] ) (define_insn "*negated_cbranchsi4" @@ -7809,7 +7847,8 @@ (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) (le (minus (match_dup 3) (pc)) (const_int 2048))) (const_int 6) - (const_int 8))))] + (const_int 8)))) + (set_attr "type" "multiple")] ) (define_insn "*tbit_cbranch" @@ -7853,7 +7892,8 @@ (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) (le (minus (match_dup 3) (pc)) (const_int 2048))) (const_int 6) - (const_int 8))))] + (const_int 8)))) + (set_attr "type" "multiple")] ) (define_insn "*tlobits_cbranch" @@ -7897,7 +7937,8 @@ (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) (le (minus (match_dup 3) (pc)) (const_int 2048))) (const_int 6) - (const_int 8))))] + (const_int 8)))) + (set_attr "type" "multiple")] ) (define_insn "*tstsi3_cbranch" @@ -7934,7 +7975,8 @@ (and (ge (minus (match_dup 2) (pc)) (const_int -2040)) (le (minus (match_dup 2) (pc)) (const_int 2048))) (const_int 6) - (const_int 8))))] + (const_int 8)))) + (set_attr "type" "multiple")] ) (define_insn "*cbranchne_decr1" @@ -8037,7 +8079,8 @@ (and (ge (minus (match_dup 4) (pc)) (const_int -2038)) (le (minus (match_dup 4) (pc)) (const_int 2048))) (const_int 8) - (const_int 10)))])] + (const_int 10)))]) + (set_attr "type" "multiple")] ) (define_insn "*addsi3_cbranch" @@ -8118,7 +8161,8 @@ (and (ge (minus (match_dup 5) (pc)) (const_int -2038)) (le (minus (match_dup 5) (pc)) (const_int 2048))) (const_int 8) - (const_int 10)))))] + (const_int 10))))) + (set_attr "type" "multiple")] ) (define_insn "*addsi3_cbranch_scratch" @@ -8186,7 +8230,8 @@ (and (ge (minus (match_dup 4) (pc)) (const_int -2040)) (le (minus (match_dup 4) (pc)) (const_int 2048))) (const_int 6) - (const_int 8))))] + (const_int 8)))) + (set_attr "type" "multiple")] ) @@ -8194,46 +8239,48 @@ (define_insn "*arm_cmpsi_insn" [(set (reg:CC CC_REGNUM) - (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r") - (match_operand:SI 1 "arm_add_operand" "Py,r,rI,L")))] + (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r") + (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))] "TARGET_32BIT" "@ cmp%?\\t%0, %1 cmp%?\\t%0, %1 cmp%?\\t%0, %1 + cmp%?\\t%0, %1 cmn%?\\t%0, #%n1" [(set_attr "conds" "set") - (set_attr "arch" "t2,t2,any,any") - (set_attr "length" "2,2,4,4") + (set_attr "arch" "t2,t2,any,any,any") + (set_attr "length" "2,2,4,4,4") (set_attr "predicable" "yes") - (set_attr "type" "*,*,*,arlo_imm")] + (set_attr "predicable_short_it" "yes,yes,yes,no,no") + (set_attr "type" "alus_imm,alus_reg,alus_reg,alus_imm,alus_imm")] ) (define_insn "*cmpsi_shiftsi" [(set (reg:CC CC_REGNUM) - (compare:CC (match_operand:SI 0 "s_register_operand" "r,r") + (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r") (match_operator:SI 3 "shift_operator" - [(match_operand:SI 1 "s_register_operand" "r,r") - (match_operand:SI 2 "shift_amount_operand" "M,rM")])))] + [(match_operand:SI 1 "s_register_operand" "r,r,r") + (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))] "TARGET_32BIT" - "cmp%?\\t%0, %1%S3" + "cmp\\t%0, %1%S3" [(set_attr "conds" "set") (set_attr "shift" "1") - (set_attr "arch" "32,a") - (set_attr "type" "arlo_shift,arlo_shift_reg")]) + (set_attr "arch" "32,a,a") + (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")]) (define_insn "*cmpsi_shiftsi_swp" [(set (reg:CC_SWP CC_REGNUM) (compare:CC_SWP (match_operator:SI 3 "shift_operator" - [(match_operand:SI 1 "s_register_operand" "r,r") - (match_operand:SI 2 "shift_amount_operand" "M,rM")]) - (match_operand:SI 0 "s_register_operand" "r,r")))] + [(match_operand:SI 1 "s_register_operand" "r,r,r") + (match_operand:SI 2 "shift_amount_operand" "M,r,M")]) + (match_operand:SI 0 "s_register_operand" "r,r,r")))] "TARGET_32BIT" "cmp%?\\t%0, %1%S3" [(set_attr "conds" "set") (set_attr "shift" "1") - (set_attr "arch" "32,a") - (set_attr "type" "arlo_shift,arlo_shift_reg")]) + (set_attr "arch" "32,a,a") + (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")]) (define_insn "*arm_cmpsi_negshiftsi_si" [(set (reg:CC_Z CC_REGNUM) @@ -8246,8 +8293,8 @@ "cmn%?\\t%0, %2%S1" [(set_attr "conds" "set") (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") - (const_string "arlo_shift") - (const_string "arlo_shift_reg"))) + (const_string "alus_shift_imm") + (const_string "alus_shift_reg"))) (set_attr "predicable" "yes")] ) @@ -8289,7 +8336,8 @@ operands[2] = gen_lowpart (SImode, operands[2]); } [(set_attr "conds" "set") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*arm_cmpdi_unsigned" @@ -8317,7 +8365,8 @@ [(set_attr "conds" "set") (set_attr "enabled_for_depr_it" "yes,yes,no") (set_attr "arch" "t2,t2,*") - (set_attr "length" "6,6,8")] + (set_attr "length" "6,6,8") + (set_attr "type" "multiple")] ) (define_insn "*arm_cmpdi_zero" @@ -8327,7 +8376,8 @@ (clobber (match_scratch:SI 1 "=r"))] "TARGET_32BIT" "orr%.\\t%1, %Q0, %R0" - [(set_attr "conds" "set")] + [(set_attr "conds" "set") + (set_attr "type" "logics_reg")] ) (define_insn "*thumb_cmpdi_zero" @@ -8338,7 +8388,8 @@ "TARGET_THUMB1" "orr\\t%1, %Q0, %R0" [(set_attr "conds" "set") - (set_attr "length" "2")] + (set_attr "length" "2") + (set_attr "type" "logics_reg")] ) ; This insn allows redundant compares to be removed by cse, nothing should @@ -8352,7 +8403,8 @@ "TARGET_32BIT" "\\t%@ deleted compare" [(set_attr "conds" "set") - (set_attr "length" "0")] + (set_attr "length" "0") + (set_attr "type" "no_insn")] ) @@ -8453,7 +8505,8 @@ (const_int 0)))] "" [(set_attr "conds" "use") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*mov_negscc" @@ -8471,7 +8524,8 @@ operands[3] = GEN_INT (~0); } [(set_attr "conds" "use") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*mov_notscc" @@ -8490,7 +8544,8 @@ operands[4] = GEN_INT (~0); } [(set_attr "conds" "use") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_expand "cstoresi4" @@ -8695,7 +8750,8 @@ "@ neg\\t%0, %1\;adc\\t%0, %0, %1 neg\\t%2, %1\;adc\\t%0, %1, %2" - [(set_attr "length" "4")] + [(set_attr "length" "4") + (set_attr "type" "multiple")] ) (define_insn "*cstoresi_ne0_thumb1_insn" @@ -8715,7 +8771,8 @@ (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r"))))] "TARGET_THUMB1" "cmp\\t%1, %2\;sbc\\t%0, %0, %0" - [(set_attr "length" "4")] + [(set_attr "length" "4") + (set_attr "type" "multiple")] ) (define_insn_and_split "cstoresi_ltu_thumb1" @@ -8729,7 +8786,8 @@ (neg:SI (ltu:SI (match_dup 1) (match_dup 2)))) (set (match_dup 0) (neg:SI (match_dup 3)))] "operands[3] = gen_reg_rtx (SImode);" - [(set_attr "length" "4")] + [(set_attr "length" "4") + (set_attr "type" "multiple")] ) ;; Used as part of the expansion of thumb les sequence. @@ -8741,7 +8799,8 @@ (match_operand:SI 4 "thumb1_cmp_operand" "lI"))))] "TARGET_THUMB1" "cmp\\t%3, %4\;adc\\t%0, %1, %2" - [(set_attr "length" "4")] + [(set_attr "length" "4") + (set_attr "type" "multiple")] ) @@ -8959,7 +9018,8 @@ (and (ge (minus (match_dup 0) (pc)) (const_int -2044)) (le (minus (match_dup 0) (pc)) (const_int 2048)))) (const_int 2) - (const_int 4)))] + (const_int 4))) + (set_attr "type" "branch")] ) (define_insn "*thumb_jump" @@ -8981,7 +9041,8 @@ (and (ge (minus (match_dup 0) (pc)) (const_int -2044)) (le (minus (match_dup 0) (pc)) (const_int 2048))) (const_int 2) - (const_int 4)))] + (const_int 4))) + (set_attr "type" "branch")] ) (define_expand "call" @@ -9465,7 +9526,8 @@ "TARGET_ARM" "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc" [(set_attr "length" "8") - (set_attr "conds" "set")] + (set_attr "conds" "set") + (set_attr "type" "multiple")] ) ;; Call subroutine returning any type. @@ -9656,7 +9718,8 @@ return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\"; " [(set_attr "conds" "clob") - (set_attr "length" "12")] + (set_attr "length" "12") + (set_attr "type" "multiple")] ) (define_expand "thumb1_casesi_internal_pic" @@ -9687,7 +9750,8 @@ (clobber (reg:SI LR_REGNUM))])] "TARGET_THUMB1" "* return thumb1_output_casesi(operands);" - [(set_attr "length" "4")] + [(set_attr "length" "4") + (set_attr "type" "multiple")] ) (define_expand "indirect_jump" @@ -9713,7 +9777,8 @@ (match_operand:SI 0 "s_register_operand" "r"))] "TARGET_ARM" "mov%?\\t%|pc, %0\\t%@ indirect register jump" - [(set_attr "predicable" "yes")] + [(set_attr "predicable" "yes") + (set_attr "type" "branch")] ) (define_insn "*load_indirect_jump" @@ -9734,7 +9799,8 @@ "TARGET_THUMB1" "mov\\tpc, %0" [(set_attr "conds" "clob") - (set_attr "length" "2")] + (set_attr "length" "2") + (set_attr "type" "branch")] ) @@ -9753,7 +9819,8 @@ [(set (attr "length") (if_then_else (eq_attr "is_thumb" "yes") (const_int 2) - (const_int 4)))] + (const_int 4))) + (set_attr "type" "mov_reg")] ) @@ -9789,7 +9856,7 @@ (if_then_else (match_operand:SI 3 "mult_operator" "") (const_string "no") (const_string "yes"))]) - (set_attr "type" "arlo_shift,arlo_shift,arlo_shift,arlo_shift_reg")]) + (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_imm,alu_shift_reg")]) (define_split [(set (match_operand:SI 0 "s_register_operand" "") @@ -9826,7 +9893,7 @@ [(set_attr "conds" "set") (set_attr "shift" "4") (set_attr "arch" "32,a") - (set_attr "type" "arlo_shift,arlo_shift_reg")]) + (set_attr "type" "alus_shift_imm,alus_shift_reg")]) (define_insn "*arith_shiftsi_compare0_scratch" [(set (reg:CC_NOOV CC_REGNUM) @@ -9843,7 +9910,7 @@ [(set_attr "conds" "set") (set_attr "shift" "4") (set_attr "arch" "32,a") - (set_attr "type" "arlo_shift,arlo_shift_reg")]) + (set_attr "type" "alus_shift_imm,alus_shift_reg")]) (define_insn "*sub_shiftsi" [(set (match_operand:SI 0 "s_register_operand" "=r,r") @@ -9856,41 +9923,41 @@ [(set_attr "predicable" "yes") (set_attr "shift" "3") (set_attr "arch" "32,a") - (set_attr "type" "arlo_shift,arlo_shift_reg")]) + (set_attr "type" "alus_shift_imm,alus_shift_reg")]) (define_insn "*sub_shiftsi_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV - (minus:SI (match_operand:SI 1 "s_register_operand" "r,r") + (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r") (match_operator:SI 2 "shift_operator" - [(match_operand:SI 3 "s_register_operand" "r,r") - (match_operand:SI 4 "shift_amount_operand" "M,rM")])) + [(match_operand:SI 3 "s_register_operand" "r,r,r") + (match_operand:SI 4 "shift_amount_operand" "M,r,M")])) (const_int 0))) - (set (match_operand:SI 0 "s_register_operand" "=r,r") + (set (match_operand:SI 0 "s_register_operand" "=r,r,r") (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) (match_dup 4)])))] "TARGET_32BIT" "sub%.\\t%0, %1, %3%S2" [(set_attr "conds" "set") (set_attr "shift" "3") - (set_attr "arch" "32,a") - (set_attr "type" "arlo_shift,arlo_shift_reg")]) + (set_attr "arch" "32,a,a") + (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")]) (define_insn "*sub_shiftsi_compare0_scratch" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV - (minus:SI (match_operand:SI 1 "s_register_operand" "r,r") + (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r") (match_operator:SI 2 "shift_operator" - [(match_operand:SI 3 "s_register_operand" "r,r") - (match_operand:SI 4 "shift_amount_operand" "M,rM")])) + [(match_operand:SI 3 "s_register_operand" "r,r,r") + (match_operand:SI 4 "shift_amount_operand" "M,r,M")])) (const_int 0))) - (clobber (match_scratch:SI 0 "=r,r"))] + (clobber (match_scratch:SI 0 "=r,r,r"))] "TARGET_32BIT" "sub%.\\t%0, %1, %3%S2" [(set_attr "conds" "set") (set_attr "shift" "3") - (set_attr "arch" "32,a") - (set_attr "type" "arlo_shift,arlo_shift_reg")]) + (set_attr "arch" "32,a,a") + (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")]) (define_insn_and_split "*and_scc" @@ -9918,7 +9985,7 @@ operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); } [(set_attr "conds" "use") - (set_attr "type" "mov_reg") + (set_attr "type" "multiple") (set_attr "length" "8")] ) @@ -9952,7 +10019,8 @@ operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); } [(set_attr "conds" "use") - (set_attr "length" "4,8")] + (set_attr "length" "4,8") + (set_attr "type" "logic_imm,multiple")] ) ; A series of splitters for the compare_scc pattern below. Note that @@ -10054,7 +10122,9 @@ else rc = reverse_condition (rc); operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx); -}) +} + [(set_attr "type" "multiple")] +) ;; Attempt to improve the sequence generated by the compare_scc splitters ;; not to use conditional execution. @@ -10171,7 +10241,7 @@ return \"\"; " [(set_attr "conds" "use") - (set_attr "type" "mov_reg") + (set_attr "type" "mov_reg,mov_reg,multiple") (set_attr "length" "4,4,8")] ) @@ -10198,7 +10268,8 @@ return \"%i5%d4\\t%0, %1, #1\"; " [(set_attr "conds" "clob") - (set_attr "length" "12")] + (set_attr "length" "12") + (set_attr "type" "multiple")] ) (define_insn "*cond_sub" @@ -10216,7 +10287,8 @@ return \"sub%d4\\t%0, %1, #1\"; " [(set_attr "conds" "clob") - (set_attr "length" "8,12")] + (set_attr "length" "8,12") + (set_attr "type" "multiple")] ) (define_insn "*cmp_ite0" @@ -10280,6 +10352,7 @@ }" [(set_attr "conds" "set") (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") + (set_attr "type" "multiple") (set_attr_alternative "length" [(const_int 6) (const_int 8) @@ -10379,7 +10452,8 @@ (const_int 10)) (if_then_else (eq_attr "is_thumb" "no") (const_int 8) - (const_int 10))])] + (const_int 10))]) + (set_attr "type" "multiple")] ) (define_insn "*cmp_and" @@ -10460,7 +10534,8 @@ (const_int 10)) (if_then_else (eq_attr "is_thumb" "no") (const_int 8) - (const_int 10))])] + (const_int 10))]) + (set_attr "type" "multiple")] ) (define_insn "*cmp_ior" @@ -10541,7 +10616,8 @@ (const_int 10)) (if_then_else (eq_attr "is_thumb" "no") (const_int 8) - (const_int 10))])] + (const_int 10))]) + (set_attr "type" "multiple")] ) (define_insn_and_split "*ior_scc_scc" @@ -10570,7 +10646,9 @@ DOM_CC_X_OR_Y), CC_REGNUM);" [(set_attr "conds" "clob") - (set_attr "length" "16")]) + (set_attr "length" "16") + (set_attr "type" "multiple")] +) ; If the above pattern is followed by a CMP insn, then the compare is ; redundant, since we can rework the conditional instruction that follows. @@ -10598,7 +10676,9 @@ (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))] "" [(set_attr "conds" "set") - (set_attr "length" "16")]) + (set_attr "length" "16") + (set_attr "type" "multiple")] +) (define_insn_and_split "*and_scc_scc" [(set (match_operand:SI 0 "s_register_operand" "=Ts") @@ -10628,7 +10708,9 @@ DOM_CC_X_AND_Y), CC_REGNUM);" [(set_attr "conds" "clob") - (set_attr "length" "16")]) + (set_attr "length" "16") + (set_attr "type" "multiple")] +) ; If the above pattern is followed by a CMP insn, then the compare is ; redundant, since we can rework the conditional instruction that follows. @@ -10656,7 +10738,9 @@ (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))] "" [(set_attr "conds" "set") - (set_attr "length" "16")]) + (set_attr "length" "16") + (set_attr "type" "multiple")] +) ;; If there is no dominance in the comparison, then we can still save an ;; instruction in the AND case, since we can know that the second compare @@ -10690,7 +10774,9 @@ operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4], operands[5]);" [(set_attr "conds" "clob") - (set_attr "length" "20")]) + (set_attr "length" "20") + (set_attr "type" "multiple")] +) (define_split [(set (reg:CC_NOOV CC_REGNUM) @@ -10801,7 +10887,8 @@ FAIL; } [(set_attr "conds" "clob") - (set_attr "length" "12")] + (set_attr "length" "12") + (set_attr "type" "multiple")] ) (define_insn_and_split "movcond_addsi" @@ -10839,7 +10926,8 @@ } " [(set_attr "conds" "clob") - (set_attr "enabled_for_depr_it" "no,yes,yes")] + (set_attr "enabled_for_depr_it" "no,yes,yes") + (set_attr "type" "multiple")] ) (define_insn "movcond" @@ -10902,7 +10990,8 @@ return \"\"; " [(set_attr "conds" "clob") - (set_attr "length" "8,8,12")] + (set_attr "length" "8,8,12") + (set_attr "type" "multiple")] ) ;; ??? The patterns below need checking for Thumb-2 usefulness. @@ -10920,7 +11009,8 @@ "TARGET_ARM" "#" [(set_attr "conds" "clob") - (set_attr "length" "8,12")] + (set_attr "length" "8,12") + (set_attr "type" "multiple")] ) (define_insn "*if_plus_move" @@ -10942,11 +11032,11 @@ (set_attr "length" "4,4,8,8") (set_attr_alternative "type" [(if_then_else (match_operand 3 "const_int_operand" "") - (const_string "arlo_imm" ) - (const_string "*")) - (const_string "arlo_imm") - (const_string "*") - (const_string "*")])] + (const_string "alu_imm" ) + (const_string "alu_reg")) + (const_string "alu_imm") + (const_string "alu_reg") + (const_string "alu_reg")])] ) (define_insn "*ifcompare_move_plus" @@ -10962,7 +11052,8 @@ "TARGET_ARM" "#" [(set_attr "conds" "clob") - (set_attr "length" "8,12")] + (set_attr "length" "8,12") + (set_attr "type" "multiple")] ) (define_insn "*if_move_plus" @@ -10982,13 +11073,7 @@ sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1" [(set_attr "conds" "use") (set_attr "length" "4,4,8,8") - (set_attr_alternative "type" - [(if_then_else (match_operand 3 "const_int_operand" "") - (const_string "arlo_imm" ) - (const_string "*")) - (const_string "arlo_imm") - (const_string "*") - (const_string "*")])] + (set_attr "type" "alu_reg,alu_imm,multiple,multiple")] ) (define_insn "*ifcompare_arith_arith" @@ -11006,7 +11091,8 @@ "TARGET_ARM" "#" [(set_attr "conds" "clob") - (set_attr "length" "12")] + (set_attr "length" "12") + (set_attr "type" "multiple")] ) (define_insn "*if_arith_arith" @@ -11022,7 +11108,8 @@ "TARGET_ARM" "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4" [(set_attr "conds" "use") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn "*ifcompare_arith_move" @@ -11063,7 +11150,8 @@ return \"\"; " [(set_attr "conds" "clob") - (set_attr "length" "8,12")] + (set_attr "length" "8,12") + (set_attr "type" "multiple")] ) (define_insn "*if_arith_move" @@ -11080,7 +11168,7 @@ %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1" [(set_attr "conds" "use") (set_attr "length" "4,8") - (set_attr "type" "*,*")] + (set_attr "type" "alu_shift_reg,multiple")] ) (define_insn "*ifcompare_move_arith" @@ -11122,7 +11210,8 @@ return \"%I7%D6\\t%0, %2, %3\"; " [(set_attr "conds" "clob") - (set_attr "length" "8,12")] + (set_attr "length" "8,12") + (set_attr "type" "multiple")] ) (define_insn "*if_move_arith" @@ -11140,7 +11229,7 @@ %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1" [(set_attr "conds" "use") (set_attr "length" "4,8") - (set_attr "type" "*,*")] + (set_attr "type" "alu_shift_reg,multiple")] ) (define_insn "*ifcompare_move_not" @@ -11156,7 +11245,8 @@ "TARGET_ARM" "#" [(set_attr "conds" "clob") - (set_attr "length" "8,12")] + (set_attr "length" "8,12") + (set_attr "type" "multiple")] ) (define_insn "*if_move_not" @@ -11173,7 +11263,8 @@ mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2" [(set_attr "conds" "use") (set_attr "type" "mvn_reg") - (set_attr "length" "4,8,8")] + (set_attr "length" "4,8,8") + (set_attr "type" "mvn_reg,multiple,multiple")] ) (define_insn "*ifcompare_not_move" @@ -11189,7 +11280,8 @@ "TARGET_ARM" "#" [(set_attr "conds" "clob") - (set_attr "length" "8,12")] + (set_attr "length" "8,12") + (set_attr "type" "multiple")] ) (define_insn "*if_not_move" @@ -11205,7 +11297,7 @@ mov%D4\\t%0, %1\;mvn%d4\\t%0, %2 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2" [(set_attr "conds" "use") - (set_attr "type" "mvn_reg") + (set_attr "type" "mvn_reg,multiple,multiple") (set_attr "length" "4,8,8")] ) @@ -11223,7 +11315,8 @@ "TARGET_ARM" "#" [(set_attr "conds" "clob") - (set_attr "length" "8,12")] + (set_attr "length" "8,12") + (set_attr "type" "multiple")] ) (define_insn "*if_shift_move" @@ -11243,9 +11336,7 @@ [(set_attr "conds" "use") (set_attr "shift" "2") (set_attr "length" "4,8,8") - (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") - (const_string "mov_shift") - (const_string "mov_shift_reg")))] + (set_attr "type" "mov_shift_reg,multiple,multiple")] ) (define_insn "*ifcompare_move_shift" @@ -11262,7 +11353,8 @@ "TARGET_ARM" "#" [(set_attr "conds" "clob") - (set_attr "length" "8,12")] + (set_attr "length" "8,12") + (set_attr "type" "multiple")] ) (define_insn "*if_move_shift" @@ -11282,9 +11374,7 @@ [(set_attr "conds" "use") (set_attr "shift" "2") (set_attr "length" "4,8,8") - (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") - (const_string "mov_shift") - (const_string "mov_shift_reg")))] + (set_attr "type" "mov_shift_reg,multiple,multiple")] ) (define_insn "*ifcompare_shift_shift" @@ -11303,7 +11393,8 @@ "TARGET_ARM" "#" [(set_attr "conds" "clob") - (set_attr "length" "12")] + (set_attr "length" "12") + (set_attr "type" "multiple")] ) (define_insn "*if_shift_shift" @@ -11343,7 +11434,8 @@ "TARGET_ARM" "#" [(set_attr "conds" "clob") - (set_attr "length" "12")] + (set_attr "length" "12") + (set_attr "type" "multiple")] ) (define_insn "*if_not_arith" @@ -11376,7 +11468,8 @@ "TARGET_ARM" "#" [(set_attr "conds" "clob") - (set_attr "length" "12")] + (set_attr "length" "12") + (set_attr "type" "multiple")] ) (define_insn "*if_arith_not" @@ -11391,7 +11484,7 @@ "TARGET_ARM" "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3" [(set_attr "conds" "use") - (set_attr "type" "mvn_reg") + (set_attr "type" "multiple") (set_attr "length" "8")] ) @@ -11407,7 +11500,8 @@ "TARGET_ARM" "#" [(set_attr "conds" "clob") - (set_attr "length" "8,12")] + (set_attr "length" "8,12") + (set_attr "type" "multiple")] ) (define_insn "*if_neg_move" @@ -11423,7 +11517,8 @@ mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0" [(set_attr "conds" "use") - (set_attr "length" "4,8,8")] + (set_attr "length" "4,8,8") + (set_attr "type" "logic_shift_imm,multiple,multiple")] ) (define_insn "*ifcompare_move_neg" @@ -11438,7 +11533,8 @@ "TARGET_ARM" "#" [(set_attr "conds" "clob") - (set_attr "length" "8,12")] + (set_attr "length" "8,12") + (set_attr "type" "multiple")] ) (define_insn "*if_move_neg" @@ -11454,7 +11550,8 @@ mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0" [(set_attr "conds" "use") - (set_attr "length" "4,8,8")] + (set_attr "length" "4,8,8") + (set_attr "type" "logic_shift_imm,multiple,multiple")] ) (define_insn "*arith_adjacentmem" @@ -11652,7 +11749,8 @@ [(unspec_volatile [(const_int 0)] VUNSPEC_THUMB1_INTERWORK)] "TARGET_THUMB1" "* return thumb1_output_interwork ();" - [(set_attr "length" "8")] + [(set_attr "length" "8") + (set_attr "type" "multiple")] ) ;; Note - although unspec_volatile's USE all hard registers, @@ -11839,7 +11937,7 @@ mvn%D4\\t%0, %2 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2" [(set_attr "conds" "use") - (set_attr "type" "mvn_reg") + (set_attr "type" "mvn_reg,multiple") (set_attr "length" "4,8")] ) @@ -11859,7 +11957,8 @@ return \"mvnne\\t%0, #0\"; " [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn "*not_signextract_onebit" @@ -11877,7 +11976,8 @@ return \"movne\\t%0, #0\"; " [(set_attr "conds" "clob") - (set_attr "length" "12")] + (set_attr "length" "12") + (set_attr "type" "multiple")] ) ;; ??? The above patterns need auditing for Thumb-2 @@ -11939,7 +12039,8 @@ UNSPEC_PRLG_STK))] "" "" - [(set_attr "length" "0")] + [(set_attr "length" "0") + (set_attr "type" "block")] ) ;; Pop (as used in epilogue RTL) @@ -12069,6 +12170,7 @@ assemble_align (32); return \"\"; " + [(set_attr "type" "no_insn")] ) (define_insn "align_8" @@ -12078,6 +12180,7 @@ assemble_align (64); return \"\"; " + [(set_attr "type" "no_insn")] ) (define_insn "consttable_end" @@ -12087,6 +12190,7 @@ making_const_table = FALSE; return \"\"; " + [(set_attr "type" "no_insn")] ) (define_insn "consttable_1" @@ -12098,7 +12202,8 @@ assemble_zeros (3); return \"\"; " - [(set_attr "length" "4")] + [(set_attr "length" "4") + (set_attr "type" "no_insn")] ) (define_insn "consttable_2" @@ -12111,7 +12216,8 @@ assemble_zeros (2); return \"\"; " - [(set_attr "length" "4")] + [(set_attr "length" "4") + (set_attr "type" "no_insn")] ) (define_insn "consttable_4" @@ -12147,7 +12253,8 @@ } return \"\"; }" - [(set_attr "length" "4")] + [(set_attr "length" "4") + (set_attr "type" "no_insn")] ) (define_insn "consttable_8" @@ -12171,7 +12278,8 @@ } return \"\"; }" - [(set_attr "length" "8")] + [(set_attr "length" "8") + (set_attr "type" "no_insn")] ) (define_insn "consttable_16" @@ -12195,7 +12303,8 @@ } return \"\"; }" - [(set_attr "length" "16")] + [(set_attr "length" "16") + (set_attr "type" "no_insn")] ) ;; Miscellaneous Thumb patterns @@ -12223,7 +12332,8 @@ (use (label_ref (match_operand 1 "" "")))] "TARGET_THUMB1" "mov\\t%|pc, %0" - [(set_attr "length" "2")] + [(set_attr "length" "2") + (set_attr "type" "no_insn")] ) ;; V5 Instructions, @@ -12265,7 +12375,9 @@ (match_operand:SI 1 "" "") (match_operand:SI 2 "" ""))] "TARGET_32BIT && arm_arch5e" - "pld\\t%a0") + "pld\\t%a0" + [(set_attr "type" "load1")] +) ;; General predication pattern @@ -12282,7 +12394,8 @@ [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)] "" "%@ %0 needed" - [(set_attr "length" "0")] + [(set_attr "length" "0") + (set_attr "type" "no_insn")] ) @@ -12330,6 +12443,7 @@ thumb_set_return_address (operands[0], operands[1]); DONE; }" + [(set_attr "type" "mov_reg")] ) @@ -12340,7 +12454,8 @@ (unspec:SI [(const_int 0)] UNSPEC_TLS))] "TARGET_HARD_TP" "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard" - [(set_attr "predicable" "yes")] + [(set_attr "predicable" "yes") + (set_attr "type" "mrs")] ) ;; Doesn't clobber R1-R3. Must use r0 for the first operand. @@ -12351,7 +12466,8 @@ (clobber (reg:CC CC_REGNUM))] "TARGET_SOFT_TP" "bl\\t__aeabi_read_tp\\t@ load_tp_soft" - [(set_attr "conds" "clob")] + [(set_attr "conds" "clob") + (set_attr "type" "branch")] ) ;; tls descriptor call @@ -12370,7 +12486,8 @@ return "bl\\t%c0(tlscall)"; } [(set_attr "conds" "clob") - (set_attr "length" "4")] + (set_attr "length" "4") + (set_attr "type" "branch")] ) ;; For thread pointer builtin @@ -12396,7 +12513,8 @@ "movt%?\t%0, %L1" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "length" "4")] + (set_attr "length" "4") + (set_attr "type" "mov_imm")] ) (define_insn "*arm_rev" @@ -12408,7 +12526,8 @@ rev%?\t%0, %1 rev%?\t%0, %1" [(set_attr "arch" "t1,t2,32") - (set_attr "length" "2,2,4")] + (set_attr "length" "2,2,4") + (set_attr "type" "rev")] ) (define_expand "arm_legacy_rev" @@ -12508,7 +12627,8 @@ revsh%?\t%0, %1 revsh%?\t%0, %1" [(set_attr "arch" "t1,t2,32") - (set_attr "length" "2,2,4")] + (set_attr "length" "2,2,4") + (set_attr "type" "rev")] ) (define_insn "*arm_rev16" @@ -12520,7 +12640,8 @@ rev16%?\t%0, %1 rev16%?\t%0, %1" [(set_attr "arch" "t1,t2,32") - (set_attr "length" "2,2,4")] + (set_attr "length" "2,2,4") + (set_attr "type" "rev")] ) (define_expand "bswaphi2" diff --git a/gcc/config/arm/arm1020e.md b/gcc/config/arm/arm1020e.md index 317e4cd4ad6..7df84d52481 100644 --- a/gcc/config/arm/arm1020e.md +++ b/gcc/config/arm/arm1020e.md @@ -66,14 +66,21 @@ ;; ALU operations with no shifted operand (define_insn_reservation "1020alu_op" 1 (and (eq_attr "tune" "arm1020e,arm1022e") - (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ - mov_imm,mov_reg,mvn_imm,mvn_reg")) + (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg,\ + mov_imm,mov_reg,mvn_imm,mvn_reg,\ + multiple,no_insn")) "1020a_e,1020a_m,1020a_w") ;; ALU operations with a shift-by-constant operand (define_insn_reservation "1020alu_shift_op" 1 (and (eq_attr "tune" "arm1020e,arm1022e") - (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift")) + (eq_attr "type" "alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + extend,mov_shift,mvn_shift")) "1020a_e,1020a_m,1020a_w") ;; ALU operations with a shift-by-register operand @@ -82,7 +89,9 @@ ;; the execute stage. (define_insn_reservation "1020alu_shift_reg_op" 2 (and (eq_attr "tune" "arm1020e,arm1022e") - (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) + (eq_attr "type" "alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg,\ + mov_shift_reg,mvn_shift_reg")) "1020a_e*2,1020a_m,1020a_w") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -270,7 +279,7 @@ ;; first execute state. We model this by using 1020a_e in the first cycle. (define_insn_reservation "v10_ffarith" 5 (and (eq_attr "vfp10" "yes") - (eq_attr "type" "fcpys,ffariths,ffarithd,fcmps,fcmpd")) + (eq_attr "type" "fmov,ffariths,ffarithd,fcmps,fcmpd")) "1020a_e+v10_fmac") (define_insn_reservation "v10_farith" 5 @@ -280,7 +289,7 @@ (define_insn_reservation "v10_cvt" 5 (and (eq_attr "vfp10" "yes") - (eq_attr "type" "f_cvt")) + (eq_attr "type" "f_cvt,f_cvti2f,f_cvtf2i")) "1020a_e+v10_fmac") (define_insn_reservation "v10_fmul" 6 @@ -290,12 +299,12 @@ (define_insn_reservation "v10_fdivs" 18 (and (eq_attr "vfp10" "yes") - (eq_attr "type" "fdivs")) + (eq_attr "type" "fdivs, fsqrts")) "1020a_e+v10_ds*14") (define_insn_reservation "v10_fdivd" 32 (and (eq_attr "vfp10" "yes") - (eq_attr "type" "fdivd")) + (eq_attr "type" "fdivd, fsqrtd")) "1020a_e+v10_fmac+v10_ds*28") (define_insn_reservation "v10_floads" 4 @@ -316,7 +325,7 @@ (define_insn_reservation "v10_c2v" 4 (and (eq_attr "vfp10" "yes") - (eq_attr "type" "r_2_f")) + (eq_attr "type" "f_mcr,f_mcrr")) "1020a_e+1020l_e+v10_ls1,v10_ls2") (define_insn_reservation "v10_fstores" 1 @@ -331,7 +340,7 @@ (define_insn_reservation "v10_v2c" 1 (and (eq_attr "vfp10" "yes") - (eq_attr "type" "f_2_r")) + (eq_attr "type" "f_mrc,f_mrrc")) "1020a_e+1020l_e,1020l_m,1020l_w") (define_insn_reservation "v10_to_cpsr" 2 diff --git a/gcc/config/arm/arm1026ejs.md b/gcc/config/arm/arm1026ejs.md index 9112122d67b..f5a0447f5da 100644 --- a/gcc/config/arm/arm1026ejs.md +++ b/gcc/config/arm/arm1026ejs.md @@ -66,14 +66,21 @@ ;; ALU operations with no shifted operand (define_insn_reservation "alu_op" 1 (and (eq_attr "tune" "arm1026ejs") - (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ - mov_imm,mov_reg,mvn_imm,mvn_reg")) + (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg,\ + mov_imm,mov_reg,mvn_imm,mvn_reg,\ + multiple,no_insn")) "a_e,a_m,a_w") ;; ALU operations with a shift-by-constant operand (define_insn_reservation "alu_shift_op" 1 (and (eq_attr "tune" "arm1026ejs") - (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift")) + (eq_attr "type" "alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + extend,mov_shift,mvn_shift")) "a_e,a_m,a_w") ;; ALU operations with a shift-by-register operand @@ -82,7 +89,9 @@ ;; the execute stage. (define_insn_reservation "alu_shift_reg_op" 2 (and (eq_attr "tune" "arm1026ejs") - (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) + (eq_attr "type" "alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg,\ + mov_shift_reg,mvn_shift_reg")) "a_e*2,a_m,a_w") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/gcc/config/arm/arm1136jfs.md b/gcc/config/arm/arm1136jfs.md index f83b9d14f2b..f6e0b8da8b6 100644 --- a/gcc/config/arm/arm1136jfs.md +++ b/gcc/config/arm/arm1136jfs.md @@ -75,14 +75,21 @@ ;; ALU operations with no shifted operand (define_insn_reservation "11_alu_op" 2 (and (eq_attr "tune" "arm1136js,arm1136jfs") - (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ - mov_imm,mov_reg,mvn_imm,mvn_reg")) + (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg,\ + mov_imm,mov_reg,mvn_imm,mvn_reg,\ + multiple,no_insn")) "e_1,e_2,e_3,e_wb") ;; ALU operations with a shift-by-constant operand (define_insn_reservation "11_alu_shift_op" 2 (and (eq_attr "tune" "arm1136js,arm1136jfs") - (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift")) + (eq_attr "type" "alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + extend,mov_shift,mvn_shift")) "e_1,e_2,e_3,e_wb") ;; ALU operations with a shift-by-register operand @@ -91,7 +98,9 @@ ;; the shift stage. (define_insn_reservation "11_alu_shift_reg_op" 3 (and (eq_attr "tune" "arm1136js,arm1136jfs") - (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) + (eq_attr "type" "alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg,\ + mov_shift_reg,mvn_shift_reg")) "e_1*2,e_2,e_3,e_wb") ;; alu_ops can start sooner, if there is no shifter dependency diff --git a/gcc/config/arm/arm926ejs.md b/gcc/config/arm/arm926ejs.md index 8c38e86ce66..d2b0e9e3cf8 100644 --- a/gcc/config/arm/arm926ejs.md +++ b/gcc/config/arm/arm926ejs.md @@ -58,9 +58,16 @@ ;; ALU operations with no shifted operand (define_insn_reservation "9_alu_op" 1 (and (eq_attr "tune" "arm926ejs") - (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,extend,arlo_shift,\ + (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + shift_imm,shift_reg,extend,\ mov_imm,mov_reg,mov_shift,\ - mvn_imm,mvn_reg,mvn_shift")) + mvn_imm,mvn_reg,mvn_shift,\ + multiple,no_insn")) "e,m,w") ;; ALU operations with a shift-by-register operand @@ -69,7 +76,9 @@ ;; the execute stage. (define_insn_reservation "9_alu_shift_reg_op" 2 (and (eq_attr "tune" "arm926ejs") - (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) + (eq_attr "type" "alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg,\ + mov_shift_reg,mvn_shift_reg")) "e*2,m,w") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/gcc/config/arm/cortex-a15-neon.md b/gcc/config/arm/cortex-a15-neon.md index bfa2f5e8818..6eb8268321a 100644 --- a/gcc/config/arm/cortex-a15-neon.md +++ b/gcc/config/arm/cortex-a15-neon.md @@ -93,389 +93,345 @@ (define_insn_reservation "cortex_a15_neon_int_1" 5 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" "neon_int_1")) + (eq_attr "type" "neon_int_1")) "ca15_issue1,ca15_cx_ialu") (define_insn_reservation "cortex_a15_neon_int_2" 5 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" "neon_int_2")) + (eq_attr "type" "neon_int_2")) "ca15_issue1,ca15_cx_ialu") (define_insn_reservation "cortex_a15_neon_int_3" 5 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" "neon_int_3")) + (eq_attr "type" "neon_int_3")) "ca15_issue1,ca15_cx_ialu") (define_insn_reservation "cortex_a15_neon_int_4" 5 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" "neon_int_4")) + (eq_attr "type" "neon_int_4")) "ca15_issue1,ca15_cx_ialu") (define_insn_reservation "cortex_a15_neon_int_5" 5 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" "neon_int_5")) + (eq_attr "type" "neon_int_5")) "ca15_issue1,ca15_cx_ialu") (define_insn_reservation "cortex_a15_neon_vqneg_vqabs" 5 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" "neon_vqneg_vqabs")) + (eq_attr "type" "neon_vqneg_vqabs")) "ca15_issue1,ca15_cx_ialu") (define_insn_reservation "cortex_a15_neon_vmov" 5 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" "neon_vmov")) + (eq_attr "type" "neon_vmov")) "ca15_issue1,ca15_cx_ialu") (define_insn_reservation "cortex_a15_neon_vaba" 7 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" "neon_vaba")) + (eq_attr "type" "neon_vaba")) "ca15_issue1,ca15_cx_ialu_with_acc") (define_insn_reservation "cortex_a15_neon_vaba_qqq" 8 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" "neon_vaba_qqq")) + (eq_attr "type" "neon_vaba_qqq")) "ca15_issue2,ca15_cx_ialu_with_acc*2") (define_insn_reservation "cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long" 6 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")) + (eq_attr "type" "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")) "ca15_issue1,ca15_cx_imac") (define_insn_reservation "cortex_a15_neon_mul_qqq_8_16_32_ddd_32" 7 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" "neon_mul_qqq_8_16_32_ddd_32")) + (eq_attr "type" "neon_mul_qqq_8_16_32_ddd_32")) "ca15_issue1,ca15_cx_imac*2") (define_insn_reservation "cortex_a15_neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar" 7 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" + (eq_attr "type" "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")) "ca15_issue1,ca15_cx_imac*2") (define_insn_reservation "cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long" 6 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" + (eq_attr "type" "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")) "ca15_issue1,ca15_cx_imac") (define_insn_reservation "cortex_a15_neon_mla_qqq_8_16" 7 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" + (eq_attr "type" "neon_mla_qqq_8_16")) "ca15_issue1,ca15_cx_imac*2") (define_insn_reservation "cortex_a15_neon_mla_ddd_32_qqd_16_ddd_32_scalar_\ - qdd_64_32_long_scalar_qdd_64_32_long" 7 + qdd_64_32_lotype_qdd_64_32_long" 7 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")) + (eq_attr "type" "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")) "ca15_issue1,ca15_cx_imac") (define_insn_reservation "cortex_a15_neon_mla_qqq_32_qqd_32_scalar" 7 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_mla_qqq_32_qqd_32_scalar")) + (eq_attr "type" "neon_mla_qqq_32_qqd_32_scalar")) "ca15_issue1,ca15_cx_imac*2") (define_insn_reservation "cortex_a15_neon_mul_ddd_16_scalar_32_16_long_scalar" 6 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_mul_ddd_16_scalar_32_16_long_scalar")) + (eq_attr "type" "neon_mul_ddd_16_scalar_32_16_long_scalar")) "ca15_issue1,ca15_cx_imac") (define_insn_reservation "cortex_a15_neon_mul_qqd_32_scalar" 7 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_mul_qqd_32_scalar")) + (eq_attr "type" "neon_mul_qqd_32_scalar")) "ca15_issue1,ca15_cx_imac*2") (define_insn_reservation "cortex_a15_neon_mla_ddd_16_scalar_qdd_32_16_long_scalar" 6 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")) + (eq_attr "type" "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")) "ca15_issue1,ca15_cx_imac") (define_insn_reservation "cortex_a15_neon_shift_1" 5 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_shift_1")) + (eq_attr "type" "neon_shift_1")) "ca15_issue1,ca15_cx_ik+ca15_cx_ishf") (define_insn_reservation "cortex_a15_neon_shift_2" 5 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_shift_2")) + (eq_attr "type" "neon_shift_2")) "ca15_issue1,ca15_cx_ik+ca15_cx_ishf") (define_insn_reservation "cortex_a15_neon_shift_3" 6 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_shift_3")) + (eq_attr "type" "neon_shift_3")) "ca15_issue2,(ca15_cx_ik+ca15_cx_ishf)*2") (define_insn_reservation "cortex_a15_neon_vshl_ddd" 5 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vshl_ddd")) + (eq_attr "type" "neon_vshl_ddd")) "ca15_issue1,ca15_cx_ik+ca15_cx_ishf") (define_insn_reservation "cortex_a15_neon_vqshl_vrshl_vqrshl_qqq" 6 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vqshl_vrshl_vqrshl_qqq")) + (eq_attr "type" "neon_vqshl_vrshl_vqrshl_qqq")) "ca15_issue2,(ca15_cx_ik+ca15_cx_ishf)*2") (define_insn_reservation "cortex_a15_neon_vsra_vrsra" 7 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vsra_vrsra")) + (eq_attr "type" "neon_vsra_vrsra")) "ca15_issue1,ca15_cx_ishf_with_acc") (define_insn_reservation "cortex_a15_neon_fp_vadd_ddd_vabs_dd" 6 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_fp_vadd_ddd_vabs_dd")) + (eq_attr "type" "neon_fp_vadd_ddd_vabs_dd")) "ca15_issue1,ca15_cx_falu") (define_insn_reservation "cortex_a15_neon_fp_vadd_qqq_vabs_qq" 7 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_fp_vadd_qqq_vabs_qq")) + (eq_attr "type" "neon_fp_vadd_qqq_vabs_qq")) "ca15_issue2,ca15_cx_falu_2") (define_insn_reservation "cortex_a15_neon_fp_vmul_ddd" 5 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_fp_vmul_ddd")) + (eq_attr "type" "neon_fp_vmul_ddd")) "ca15_issue1,ca15_cx_fmul") (define_insn_reservation "cortex_a15_neon_fp_vmul_qqd" 6 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_fp_vmul_qqd")) + (eq_attr "type" "neon_fp_vmul_qqd")) "ca15_issue2,ca15_cx_fmul_2") (define_insn_reservation "cortex_a15_neon_fp_vmla_ddd" 9 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_fp_vmla_ddd")) + (eq_attr "type" "neon_fp_vmla_ddd")) "ca15_issue1,ca15_cx_fmac") (define_insn_reservation "cortex_a15_neon_fp_vmla_qqq" 11 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_fp_vmla_qqq")) + (eq_attr "type" "neon_fp_vmla_qqq")) "ca15_issue2,ca15_cx_fmac_2") (define_insn_reservation "cortex_a15_neon_fp_vmla_ddd_scalar" 9 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_fp_vmla_ddd_scalar")) + (eq_attr "type" "neon_fp_vmla_ddd_scalar")) "ca15_issue1,ca15_cx_fmac") (define_insn_reservation "cortex_a15_neon_fp_vmla_qqq_scalar" 11 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_fp_vmla_qqq_scalar")) + (eq_attr "type" "neon_fp_vmla_qqq_scalar")) "ca15_issue2,ca15_cx_fmac_2") (define_insn_reservation "cortex_a15_neon_fp_vrecps_vrsqrts_ddd" 9 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_fp_vrecps_vrsqrts_ddd")) + (eq_attr "type" "neon_fp_vrecps_vrsqrts_ddd")) "ca15_issue1,ca15_cx_fmac") (define_insn_reservation "cortex_a15_neon_fp_vrecps_vrsqrts_qqq" 11 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_fp_vrecps_vrsqrts_qqq")) + (eq_attr "type" "neon_fp_vrecps_vrsqrts_qqq")) "ca15_issue2,ca15_cx_fmac_2") (define_insn_reservation "cortex_a15_neon_bp_simple" 4 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_bp_simple")) + (eq_attr "type" "neon_bp_simple")) "ca15_issue3,ca15_ls+ca15_cx_perm_2,ca15_cx_perm") (define_insn_reservation "cortex_a15_neon_bp_2cycle" 4 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_bp_2cycle")) + (eq_attr "type" "neon_bp_2cycle")) "ca15_issue1,ca15_cx_perm") (define_insn_reservation "cortex_a15_neon_bp_3cycle" 7 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_bp_3cycle")) + (eq_attr "type" "neon_bp_3cycle")) "ca15_issue3,ca15_cx_ialu+ca15_cx_perm_2,ca15_cx_perm") (define_insn_reservation "cortex_a15_neon_vld1_1_2_regs" 7 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vld1_1_2_regs")) + (eq_attr "type" "neon_vld1_1_2_regs")) "ca15_issue2,ca15_ls,ca15_ldr") (define_insn_reservation "cortex_a15_neon_vld1_3_4_regs" 8 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vld1_3_4_regs")) + (eq_attr "type" "neon_vld1_3_4_regs")) "ca15_issue3,ca15_ls1+ca15_ls2,ca15_ldr,ca15_ldr") (define_insn_reservation "cortex_a15_neon_vld2_2_regs_vld1_vld2_all_lanes" 9 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vld2_2_regs_vld1_vld2_all_lanes")) + (eq_attr "type" "neon_vld2_2_regs_vld1_vld2_all_lanes")) "ca15_issue3,ca15_ls,ca15_ldr") (define_insn_reservation "cortex_a15_neon_vld2_4_regs" 12 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vld2_4_regs")) + (eq_attr "type" "neon_vld2_4_regs")) "ca15_issue3,ca15_issue3+ca15_ls1+ca15_ls2,ca15_ldr*2") (define_insn_reservation "cortex_a15_neon_vld3_vld4" 12 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vld3_vld4")) + (eq_attr "type" "neon_vld3_vld4")) "ca15_issue3,ca15_issue3+ca15_ls1+ca15_ls2,ca15_ldr*2") (define_insn_reservation "cortex_a15_neon_vst1_1_2_regs_vst2_2_regs" 0 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vst1_1_2_regs_vst2_2_regs")) + (eq_attr "type" "neon_vst1_1_2_regs_vst2_2_regs")) "ca15_issue3,ca15_issue3+ca15_cx_perm+ca15_ls1+ca15_ls2,ca15_str*2") (define_insn_reservation "cortex_a15_neon_vst1_3_4_regs" 0 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vst1_3_4_regs")) + (eq_attr "type" "neon_vst1_3_4_regs")) "ca15_issue3,ca15_issue3+ca15_ls1+ca15_ls2,ca15_str*3") (define_insn_reservation "cortex_a15_neon_vst2_4_regs_vst3_vst4" 0 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vst2_4_regs_vst3_vst4")) + (eq_attr "type" "neon_vst2_4_regs_vst3_vst4")) "ca15_issue3,ca15_issue3+ca15_cx_perm_2+ca15_ls1+ca15_ls2,\ ca15_issue3+ca15_str,ca15_str*3") (define_insn_reservation "cortex_a15_neon_vst3_vst4" 0 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vst3_vst4")) + (eq_attr "type" "neon_vst3_vst4")) "ca15_issue3,ca15_issue3+ca15_cx_perm_2+ca15_ls1+ca15_ls2,ca15_str*4") (define_insn_reservation "cortex_a15_neon_vld1_vld2_lane" 9 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vld1_vld2_lane")) + (eq_attr "type" "neon_vld1_vld2_lane")) "ca15_issue3,ca15_ls,ca15_ldr") (define_insn_reservation "cortex_a15_neon_vld3_vld4_lane" 10 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vld3_vld4_lane")) + (eq_attr "type" "neon_vld3_vld4_lane")) "ca15_issue3,ca15_issue3+ca15_ls,ca15_issue3+ca15_ldr") (define_insn_reservation "cortex_a15_neon_vst1_vst2_lane" 0 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vst1_vst2_lane")) + (eq_attr "type" "neon_vst1_vst2_lane")) "ca15_issue3,ca15_cx_perm+ca15_ls,ca15_str") (define_insn_reservation "cortex_a15_neon_vst3_vst4_lane" 0 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vst3_vst4_lane")) + (eq_attr "type" "neon_vst3_vst4_lane")) "ca15_issue3,ca15_issue3+ca15_cx_perm+ca15_ls1+ca15_ls2,ca15_str*2") (define_insn_reservation "cortex_a15_neon_vld3_vld4_all_lanes" 11 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_vld3_vld4_all_lanes")) + (eq_attr "type" "neon_vld3_vld4_all_lanes")) "ca15_issue3,ca15_issue3+ca15_ls,ca15_ldr") (define_insn_reservation "cortex_a15_neon_ldm_2" 20 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_ldm_2")) + (eq_attr "type" "neon_ldm_2")) "ca15_issue3*6") (define_insn_reservation "cortex_a15_neon_stm_2" 0 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_stm_2")) + (eq_attr "type" "neon_stm_2")) "ca15_issue3*6") (define_insn_reservation "cortex_a15_neon_mcr" 6 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_mcr")) + (eq_attr "type" "neon_mcr")) "ca15_issue2,ca15_ls,ca15_cx_perm") (define_insn_reservation "cortex_a15_neon_mcr_2_mcrr" 6 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_mcr_2_mcrr")) + (eq_attr "type" "neon_mcr_2_mcrr")) "ca15_issue2,ca15_ls1+ca15_ls2") (define_insn_reservation "cortex_a15_neon_mrc" 5 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_mrc")) + (eq_attr "type" "neon_mrc")) "ca15_issue1,ca15_ls") (define_insn_reservation "cortex_a15_neon_mrrc" 6 (and (eq_attr "tune" "cortexa15") - (eq_attr "neon_type" - "neon_mrrc")) + (eq_attr "type" "neon_mrrc")) "ca15_issue2,ca15_ls1+ca15_ls2") (define_insn_reservation "cortex_a15_vfp_const" 4 @@ -515,7 +471,7 @@ (define_insn_reservation "cortex_a15_vfp_cvt" 6 (and (eq_attr "tune" "cortexa15") - (eq_attr "type" "f_cvt")) + (eq_attr "type" "f_cvt,f_cvtf2i,f_cvti2f")) "ca15_issue1,ca15_cx_vfp") (define_insn_reservation "cortex_a15_vfp_cmpd" 8 @@ -535,7 +491,7 @@ (define_insn_reservation "cortex_a15_vfp_cpys" 4 (and (eq_attr "tune" "cortexa15") - (eq_attr "type" "fcpys")) + (eq_attr "type" "fmov")) "ca15_issue1,ca15_cx_perm") (define_insn_reservation "cortex_a15_vfp_ariths" 7 @@ -545,12 +501,12 @@ (define_insn_reservation "cortex_a15_vfp_divs" 10 (and (eq_attr "tune" "cortexa15") - (eq_attr "type" "fdivs")) + (eq_attr "type" "fdivs, fsqrts")) "ca15_issue1,ca15_cx_ik") (define_insn_reservation "cortex_a15_vfp_divd" 18 (and (eq_attr "tune" "cortexa15") - (eq_attr "type" "fdivd")) + (eq_attr "type" "fdivd, fsqrtd")) "ca15_issue1,ca15_cx_ik") ;; Define bypasses. diff --git a/gcc/config/arm/cortex-a15.md b/gcc/config/arm/cortex-a15.md index 4ad87121d6d..ccad6207608 100644 --- a/gcc/config/arm/cortex-a15.md +++ b/gcc/config/arm/cortex-a15.md @@ -61,25 +61,32 @@ ;; Simple ALU without shift (define_insn_reservation "cortex_a15_alu" 2 (and (eq_attr "tune" "cortexa15") - (and (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ - mov_imm,mov_reg,\ - mvn_imm,mvn_reg") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg,\ + mov_imm,mov_reg,\ + mvn_imm,mvn_reg,\ + mrs,multiple,no_insn")) "ca15_issue1,(ca15_sx1,ca15_sx1_alu)|(ca15_sx2,ca15_sx2_alu)") ;; ALU ops with immediate shift (define_insn_reservation "cortex_a15_alu_shift" 3 (and (eq_attr "tune" "cortexa15") - (and (eq_attr "type" "extend,arlo_shift,,mov_shift,mvn_shift") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "extend,\ + alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + mov_shift,mvn_shift")) "ca15_issue1,(ca15_sx1,ca15_sx1+ca15_sx1_shf,ca15_sx1_alu)\ |(ca15_sx2,ca15_sx2+ca15_sx2_shf,ca15_sx2_alu)") ;; ALU ops with register controlled shift (define_insn_reservation "cortex_a15_alu_shift_reg" 3 (and (eq_attr "tune" "cortexa15") - (and (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg,\ + mov_shift_reg,mvn_shift_reg")) "(ca15_issue2,ca15_sx1+ca15_sx2,ca15_sx1_shf,ca15_sx2_alu)\ |(ca15_issue1,(ca15_issue1+ca15_sx2,ca15_sx1+ca15_sx2_shf)\ |(ca15_issue1+ca15_sx1,ca15_sx1+ca15_sx1_shf),ca15_sx1_alu)") @@ -89,15 +96,13 @@ ;; 32-bit multiplies (define_insn_reservation "cortex_a15_mult32" 3 (and (eq_attr "tune" "cortexa15") - (and (eq_attr "mul32" "yes") - (eq_attr "neon_type" "none"))) + (eq_attr "mul32" "yes")) "ca15_issue1,ca15_mx") ;; 64-bit multiplies (define_insn_reservation "cortex_a15_mult64" 4 (and (eq_attr "tune" "cortexa15") - (and (eq_attr "mul64" "yes") - (eq_attr "neon_type" "none"))) + (eq_attr "mul64" "yes")) "ca15_issue1,ca15_mx*2") ;; Integer divide @@ -114,8 +119,7 @@ ;; Block all issue pipes for a cycle (define_insn_reservation "cortex_a15_block" 1 (and (eq_attr "tune" "cortexa15") - (and (eq_attr "type" "block") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "block")) "ca15_issue3") ;; Branch execution Unit @@ -124,8 +128,7 @@ ;; No latency as there is no result (define_insn_reservation "cortex_a15_branch" 0 (and (eq_attr "tune" "cortexa15") - (and (eq_attr "type" "branch") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "branch")) "ca15_issue1,ca15_bx") ;; Load-store execution Unit @@ -133,29 +136,25 @@ ;; Loads of up to two words. (define_insn_reservation "cortex_a15_load1" 4 (and (eq_attr "tune" "cortexa15") - (and (eq_attr "type" "load_byte,load1,load2") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "load_byte,load1,load2")) "ca15_issue1,ca15_ls,ca15_ldr,nothing") ;; Loads of three or four words. (define_insn_reservation "cortex_a15_load3" 5 (and (eq_attr "tune" "cortexa15") - (and (eq_attr "type" "load3,load4") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "load3,load4")) "ca15_issue2,ca15_ls1+ca15_ls2,ca15_ldr,ca15_ldr,nothing") ;; Stores of up to two words. (define_insn_reservation "cortex_a15_store1" 0 (and (eq_attr "tune" "cortexa15") - (and (eq_attr "type" "store1,store2") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "store1,store2")) "ca15_issue1,ca15_ls,ca15_str") ;; Stores of three or four words. (define_insn_reservation "cortex_a15_store3" 0 (and (eq_attr "tune" "cortexa15") - (and (eq_attr "type" "store3,store4") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "store3,store4")) "ca15_issue2,ca15_ls1+ca15_ls2,ca15_str,ca15_str") ;; We include Neon.md here to ensure that the branch can block the Neon units. @@ -165,8 +164,7 @@ ;; pipeline. The result however is available the next cycle. (define_insn_reservation "cortex_a15_call" 1 (and (eq_attr "tune" "cortexa15") - (and (eq_attr "type" "call") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "call")) "ca15_issue3,\ ca15_sx1+ca15_sx2+ca15_bx+ca15_mx+ca15_cx_ij+ca15_cx_ik+ca15_ls1+ca15_ls2+\ ca15_cx_imac1+ca15_cx_ialu1+ca15_cx_ialu2+ca15_cx_ishf+\ diff --git a/gcc/config/arm/cortex-a5.md b/gcc/config/arm/cortex-a5.md index 1400c47d95a..22e0a08f38e 100644 --- a/gcc/config/arm/cortex-a5.md +++ b/gcc/config/arm/cortex-a5.md @@ -58,13 +58,22 @@ (define_insn_reservation "cortex_a5_alu" 2 (and (eq_attr "tune" "cortexa5") - (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ - mov_imm,mov_reg,mvn_imm,mvn_reg")) + (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg,\ + mov_imm,mov_reg,mvn_imm,mvn_reg,\ + mrs,multiple,no_insn")) "cortex_a5_ex1") (define_insn_reservation "cortex_a5_alu_shift" 2 (and (eq_attr "tune" "cortexa5") - (eq_attr "type" "extend,arlo_shift,arlo_shift_reg,\ + (eq_attr "type" "extend,\ + alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg,\ mov_shift,mov_shift_reg,\ mvn_shift,mvn_shift_reg")) "cortex_a5_ex1") @@ -159,7 +168,8 @@ (define_insn_reservation "cortex_a5_fpalu" 4 (and (eq_attr "tune" "cortexa5") - (eq_attr "type" "ffariths, fadds, ffarithd, faddd, fcpys, fmuls, f_cvt,\ + (eq_attr "type" "ffariths, fadds, ffarithd, faddd, fmov, fmuls,\ + f_cvt,f_cvtf2i,f_cvti2f,\ fcmps, fcmpd")) "cortex_a5_ex1+cortex_a5_fpadd_pipe") @@ -223,14 +233,14 @@ (define_insn_reservation "cortex_a5_fdivs" 14 (and (eq_attr "tune" "cortexa5") - (eq_attr "type" "fdivs")) + (eq_attr "type" "fdivs, fsqrts")) "cortex_a5_ex1, cortex_a5_fp_div_sqrt * 13") ;; ??? Similarly for fdivd. (define_insn_reservation "cortex_a5_fdivd" 29 (and (eq_attr "tune" "cortexa5") - (eq_attr "type" "fdivd")) + (eq_attr "type" "fdivd, fsqrtd")) "cortex_a5_ex1, cortex_a5_fp_div_sqrt * 28") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -243,12 +253,12 @@ (define_insn_reservation "cortex_a5_r2f" 4 (and (eq_attr "tune" "cortexa5") - (eq_attr "type" "r_2_f")) + (eq_attr "type" "f_mcr,f_mcrr")) "cortex_a5_ex1") (define_insn_reservation "cortex_a5_f2r" 2 (and (eq_attr "tune" "cortexa5") - (eq_attr "type" "f_2_r")) + (eq_attr "type" "f_mrc,f_mrrc")) "cortex_a5_ex1") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/gcc/config/arm/cortex-a53.md b/gcc/config/arm/cortex-a53.md index 39a95286e08..48d0d03853f 100644 --- a/gcc/config/arm/cortex-a53.md +++ b/gcc/config/arm/cortex-a53.md @@ -67,14 +67,22 @@ (define_insn_reservation "cortex_a53_alu" 2 (and (eq_attr "tune" "cortexa53") - (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ - mov_imm,mov_reg,mvn_imm,mvn_reg")) + (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,csel,rev,\ + shift_imm,shift_reg,\ + mov_imm,mov_reg,mvn_imm,mvn_reg,\ + mrs,multiple,no_insn")) "cortex_a53_slot_any") (define_insn_reservation "cortex_a53_alu_shift" 2 (and (eq_attr "tune" "cortexa53") - (eq_attr "type" "arlo_shift,arlo_shift_reg,\ - mov_shift,mov_shift_reg,\ + (eq_attr "type" "alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg,\ + extend,mov_shift,mov_shift_reg,\ mvn_shift,mvn_shift_reg")) "cortex_a53_slot_any") @@ -201,8 +209,9 @@ (define_insn_reservation "cortex_a53_fpalu" 4 (and (eq_attr "tune" "cortexa53") - (eq_attr "type" "ffariths, fadds, ffarithd, faddd, fcpys, fmuls, f_cvt,\ - fcmps, fcmpd")) + (eq_attr "type" "ffariths, fadds, ffarithd, faddd, fmov, fmuls,\ + f_cvt,f_cvtf2i,f_cvti2f,\ + fcmps, fcmpd, fcsel")) "cortex_a53_slot0+cortex_a53_fpadd_pipe") (define_insn_reservation "cortex_a53_fconst" 2 @@ -230,12 +239,12 @@ (define_insn_reservation "cortex_a53_fdivs" 14 (and (eq_attr "tune" "cortexa53") - (eq_attr "type" "fdivs")) + (eq_attr "type" "fdivs, fsqrts")) "cortex_a53_slot0, cortex_a53_fp_div_sqrt * 13") (define_insn_reservation "cortex_a53_fdivd" 29 (and (eq_attr "tune" "cortexa53") - (eq_attr "type" "fdivd")) + (eq_attr "type" "fdivd, fsqrtd")) "cortex_a53_slot0, cortex_a53_fp_div_sqrt * 28") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -244,12 +253,12 @@ (define_insn_reservation "cortex_a53_r2f" 4 (and (eq_attr "tune" "cortexa53") - (eq_attr "type" "r_2_f")) + (eq_attr "type" "f_mcr,f_mcrr")) "cortex_a53_slot0") (define_insn_reservation "cortex_a53_f2r" 2 (and (eq_attr "tune" "cortexa53") - (eq_attr "type" "f_2_r")) + (eq_attr "type" "f_mrc,f_mrrc")) "cortex_a53_slot0") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/gcc/config/arm/cortex-a7.md b/gcc/config/arm/cortex-a7.md index e14413d5083..a72a88d90af 100644 --- a/gcc/config/arm/cortex-a7.md +++ b/gcc/config/arm/cortex-a7.md @@ -67,8 +67,7 @@ (define_insn_reservation "cortex_a7_branch" 0 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "branch") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "branch")) "(cortex_a7_ex2|cortex_a7_ex1)+cortex_a7_branch") ;; Call cannot dual-issue as an older instruction. It can dual-issue @@ -77,8 +76,7 @@ ;; cycle. (define_insn_reservation "cortex_a7_call" 1 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "call") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "call")) "(cortex_a7_ex2|cortex_a7_both)+cortex_a7_branch") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -88,27 +86,31 @@ ;; ALU instruction with an immediate operand can dual-issue. (define_insn_reservation "cortex_a7_alu_imm" 2 (and (eq_attr "tune" "cortexa7") - (and (ior (eq_attr "type" "arlo_imm,mov_imm,mvn_imm") - (ior (eq_attr "type" "extend") - (and (eq_attr "type" "mov_reg,mov_shift,mov_shift_reg") - (not (eq_attr "length" "8"))))) - (eq_attr "neon_type" "none"))) + (ior (eq_attr "type" "adr,alu_imm,alus_imm,logic_imm,logics_imm,\ + mov_imm,mvn_imm,extend") + (and (eq_attr "type" "mov_reg,mov_shift,mov_shift_reg") + (not (eq_attr "length" "8"))))) "cortex_a7_ex2|cortex_a7_ex1") ;; ALU instruction with register operands can dual-issue ;; with a younger immediate-based instruction. (define_insn_reservation "cortex_a7_alu_reg" 2 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "arlo_reg,shift,shift_reg,mov_reg,mvn_reg") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + bfm,rev,\ + shift_imm,shift_reg,mov_reg,mvn_reg")) "cortex_a7_ex1") (define_insn_reservation "cortex_a7_alu_shift" 2 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "arlo_shift,arlo_shift_reg,\ - mov_shift,mov_shift_reg,\ - mvn_shift,mvn_shift_reg") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg,\ + mov_shift,mov_shift_reg,\ + mvn_shift,mvn_shift_reg,\ + mrs,multiple,no_insn")) "cortex_a7_ex1") ;; Forwarding path for unshifted operands. @@ -129,9 +131,8 @@ (define_insn_reservation "cortex_a7_mul" 2 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "neon_type" "none") - (ior (eq_attr "mul32" "yes") - (eq_attr "mul64" "yes")))) + (ior (eq_attr "mul32" "yes") + (eq_attr "mul64" "yes"))) "cortex_a7_both") ;; Forward the result of a multiply operation to the accumulator @@ -156,50 +157,42 @@ (define_insn_reservation "cortex_a7_load1" 2 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "load_byte,load1") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "load_byte,load1")) "cortex_a7_ex1") (define_insn_reservation "cortex_a7_store1" 0 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "store1") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "store1")) "cortex_a7_ex1") (define_insn_reservation "cortex_a7_load2" 2 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "load2") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "load2")) "cortex_a7_both") (define_insn_reservation "cortex_a7_store2" 0 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "store2") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "store2")) "cortex_a7_both") (define_insn_reservation "cortex_a7_load3" 3 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "load3") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "load3")) "cortex_a7_both, cortex_a7_ex1") (define_insn_reservation "cortex_a7_store3" 0 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "store4") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "store4")) "cortex_a7_both, cortex_a7_ex1") (define_insn_reservation "cortex_a7_load4" 3 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "load4") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "load4")) "cortex_a7_both, cortex_a7_both") (define_insn_reservation "cortex_a7_store4" 0 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "store3") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "store3")) "cortex_a7_both, cortex_a7_both") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -211,9 +204,8 @@ (define_insn_reservation "cortex_a7_fpalu" 4 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "ffariths, fadds, ffarithd, faddd, fcpys,\ - f_cvt, fcmps, fcmpd") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "ffariths, fadds, ffarithd, faddd, fmov,\ + f_cvt, f_cvtf2i, f_cvti2f, fcmps, fcmpd")) "cortex_a7_ex1+cortex_a7_fpadd_pipe") ;; For fconsts and fconstd, 8-bit immediate data is passed directly from @@ -221,8 +213,7 @@ (define_insn_reservation "cortex_a7_fconst" 3 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "fconsts,fconstd") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "fconsts,fconstd")) "cortex_a7_ex1+cortex_a7_fpadd_pipe") ;; We should try not to attempt to issue a single-precision multiplication in @@ -231,13 +222,12 @@ (define_insn_reservation "cortex_a7_fpmuls" 4 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "fmuls") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "fmuls")) "cortex_a7_ex1+cortex_a7_fpmul_pipe") (define_insn_reservation "cortex_a7_neon_mul" 4 (and (eq_attr "tune" "cortexa7") - (eq_attr "neon_type" + (eq_attr "type" "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\ neon_mul_qqq_8_16_32_ddd_32,\ neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\ @@ -249,13 +239,12 @@ (define_insn_reservation "cortex_a7_fpmacs" 8 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "fmacs,ffmas") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "fmacs,ffmas")) "cortex_a7_ex1+cortex_a7_fpmul_pipe") (define_insn_reservation "cortex_a7_neon_mla" 8 (and (eq_attr "tune" "cortexa7") - (eq_attr "neon_type" + (eq_attr "type" "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\ neon_mla_qqq_8_16,\ neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\ @@ -276,20 +265,17 @@ (define_insn_reservation "cortex_a7_fpmuld" 7 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "fmuld") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "fmuld")) "cortex_a7_ex1+cortex_a7_fpmul_pipe, cortex_a7_fpmul_pipe*3") (define_insn_reservation "cortex_a7_fpmacd" 11 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "fmacd") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "fmacd")) "cortex_a7_ex1+cortex_a7_fpmul_pipe, cortex_a7_fpmul_pipe*3") (define_insn_reservation "cortex_a7_fpfmad" 8 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "ffmad") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "ffmad")) "cortex_a7_ex1+cortex_a7_fpmul_pipe, cortex_a7_fpmul_pipe*4") (define_bypass 7 "cortex_a7_fpmacd" @@ -302,14 +288,12 @@ (define_insn_reservation "cortex_a7_fdivs" 16 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "fdivs") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "fdivs, fsqrts")) "cortex_a7_ex1+cortex_a7_fp_div_sqrt, cortex_a7_fp_div_sqrt * 13") (define_insn_reservation "cortex_a7_fdivd" 31 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "fdivd") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "fdivd, fsqrtd")) "cortex_a7_ex1+cortex_a7_fp_div_sqrt, cortex_a7_fp_div_sqrt * 28") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -320,14 +304,12 @@ (define_insn_reservation "cortex_a7_r2f" 4 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "r_2_f") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "f_mcr,f_mcrr")) "cortex_a7_both") (define_insn_reservation "cortex_a7_f2r" 2 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "f_2_r") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "f_mrc,f_mrrc")) "cortex_a7_ex1") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -339,8 +321,7 @@ (define_insn_reservation "cortex_a7_f_flags" 4 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "f_flag") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "f_flag")) "cortex_a7_ex1") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -349,26 +330,22 @@ (define_insn_reservation "cortex_a7_f_loads" 4 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "f_loads") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "f_loads")) "cortex_a7_ex1") (define_insn_reservation "cortex_a7_f_loadd" 4 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "f_loadd") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "f_loadd")) "cortex_a7_both") (define_insn_reservation "cortex_a7_f_stores" 0 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "f_stores") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "f_stores")) "cortex_a7_ex1") (define_insn_reservation "cortex_a7_f_stored" 0 (and (eq_attr "tune" "cortexa7") - (and (eq_attr "type" "f_stored") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "f_stored")) "cortex_a7_both") ;; Load-to-use for floating-point values has a penalty of one cycle, @@ -389,22 +366,21 @@ (define_insn_reservation "cortex_a7_neon" 4 (and (eq_attr "tune" "cortexa7") - (eq_attr "neon_type" - "!none,\ - neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\ - neon_mul_qqq_8_16_32_ddd_32,\ - neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\ - neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\ - neon_mla_qqq_8_16,\ - neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\ - neon_mla_qqq_32_qqd_32_scalar,\ - neon_mul_ddd_16_scalar_32_16_long_scalar,\ - neon_mul_qqd_32_scalar,\ - neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\ - neon_fp_vmul_ddd,\ - neon_fp_vmul_qqd,\ - neon_fp_vmla_ddd,\ - neon_fp_vmla_qqq,\ - neon_fp_vmla_ddd_scalar,\ - neon_fp_vmla_qqq_scalar")) + (eq_attr "type" + "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\ + neon_mul_qqq_8_16_32_ddd_32,\ + neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\ + neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\ + neon_mla_qqq_8_16,\ + neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\ + neon_mla_qqq_32_qqd_32_scalar,\ + neon_mul_ddd_16_scalar_32_16_long_scalar,\ + neon_mul_qqd_32_scalar,\ + neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\ + neon_fp_vmul_ddd,\ + neon_fp_vmul_qqd,\ + neon_fp_vmla_ddd,\ + neon_fp_vmla_qqq,\ + neon_fp_vmla_ddd_scalar,\ + neon_fp_vmla_qqq_scalar")) "cortex_a7_both*2") diff --git a/gcc/config/arm/cortex-a8-neon.md b/gcc/config/arm/cortex-a8-neon.md index 2f0cc7b3a5a..b7773891669 100644 --- a/gcc/config/arm/cortex-a8-neon.md +++ b/gcc/config/arm/cortex-a8-neon.md @@ -159,12 +159,12 @@ (define_insn_reservation "cortex_a8_vfp_divs" 37 (and (eq_attr "tune" "cortexa8") - (eq_attr "type" "fdivs")) + (eq_attr "type" "fdivs, fsqrts")) "cortex_a8_vfp,cortex_a8_vfplite*36") (define_insn_reservation "cortex_a8_vfp_divd" 65 (and (eq_attr "tune" "cortexa8") - (eq_attr "type" "fdivd")) + (eq_attr "type" "fdivd, fsqrtd")) "cortex_a8_vfp,cortex_a8_vfplite*64") ;; Comparisons can actually take 7 cycles sometimes instead of four, @@ -172,24 +172,24 @@ ;; take four cycles, we pick that latency. (define_insn_reservation "cortex_a8_vfp_farith" 4 (and (eq_attr "tune" "cortexa8") - (eq_attr "type" "fcpys,ffariths,ffarithd,fconsts,fconstd,fcmps,fcmpd")) + (eq_attr "type" "fmov,ffariths,ffarithd,fconsts,fconstd,fcmps,fcmpd")) "cortex_a8_vfp,cortex_a8_vfplite*3") (define_insn_reservation "cortex_a8_vfp_cvt" 7 (and (eq_attr "tune" "cortexa8") - (eq_attr "type" "f_cvt")) + (eq_attr "type" "f_cvt,f_cvtf2i,f_cvti2f")) "cortex_a8_vfp,cortex_a8_vfplite*6") ;; NEON -> core transfers. (define_insn_reservation "cortex_a8_neon_mrc" 20 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_mrc")) + (eq_attr "type" "neon_mrc")) "cortex_a8_neon_ls") (define_insn_reservation "cortex_a8_neon_mrrc" 21 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_mrrc")) + (eq_attr "type" "neon_mrrc")) "cortex_a8_neon_ls_2") ;; The remainder of this file is auto-generated by neon-schedgen. @@ -198,48 +198,48 @@ ;; produce a result at N3. (define_insn_reservation "cortex_a8_neon_int_1" 3 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_int_1")) + (eq_attr "type" "neon_int_1")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their (D|Q)m operands at N1, ;; their (D|Q)n operands at N2, and produce a result at N3. (define_insn_reservation "cortex_a8_neon_int_2" 3 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_int_2")) + (eq_attr "type" "neon_int_2")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N3. (define_insn_reservation "cortex_a8_neon_int_3" 3 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_int_3")) + (eq_attr "type" "neon_int_3")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their source operands at N2, and ;; produce a result at N4. (define_insn_reservation "cortex_a8_neon_int_4" 4 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_int_4")) + (eq_attr "type" "neon_int_4")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their (D|Q)m operands at N1, ;; their (D|Q)n operands at N2, and produce a result at N4. (define_insn_reservation "cortex_a8_neon_int_5" 4 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_int_5")) + (eq_attr "type" "neon_int_5")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N4. (define_insn_reservation "cortex_a8_neon_vqneg_vqabs" 4 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vqneg_vqabs")) + (eq_attr "type" "neon_vqneg_vqabs")) "cortex_a8_neon_dp") ;; Instructions using this reservation produce a result at N3. (define_insn_reservation "cortex_a8_neon_vmov" 3 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vmov")) + (eq_attr "type" "neon_vmov")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -247,7 +247,7 @@ ;; produce a result at N6. (define_insn_reservation "cortex_a8_neon_vaba" 6 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vaba")) + (eq_attr "type" "neon_vaba")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -255,35 +255,35 @@ ;; produce a result at N6 on cycle 2. (define_insn_reservation "cortex_a8_neon_vaba_qqq" 7 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vaba_qqq")) + (eq_attr "type" "neon_vaba_qqq")) "cortex_a8_neon_dp_2") ;; Instructions using this reservation read their (D|Q)m operands at N1, ;; their (D|Q)d operands at N3, and produce a result at N6. (define_insn_reservation "cortex_a8_neon_vsma" 6 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vsma")) + (eq_attr "type" "neon_vsma")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their source operands at N2, and ;; produce a result at N6. (define_insn_reservation "cortex_a8_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long" 6 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")) + (eq_attr "type" "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their source operands at N2, and ;; produce a result at N6 on cycle 2. (define_insn_reservation "cortex_a8_neon_mul_qqq_8_16_32_ddd_32" 7 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_mul_qqq_8_16_32_ddd_32")) + (eq_attr "type" "neon_mul_qqq_8_16_32_ddd_32")) "cortex_a8_neon_dp_2") ;; Instructions using this reservation read their (D|Q)n operands at N2, ;; their (D|Q)m operands at N1, and produce a result at N6 on cycle 2. (define_insn_reservation "cortex_a8_neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar" 7 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")) + (eq_attr "type" "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")) "cortex_a8_neon_dp_2") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -291,7 +291,7 @@ ;; produce a result at N6. (define_insn_reservation "cortex_a8_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long" 6 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")) + (eq_attr "type" "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -299,7 +299,7 @@ ;; produce a result at N6 on cycle 2. (define_insn_reservation "cortex_a8_neon_mla_qqq_8_16" 7 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_mla_qqq_8_16")) + (eq_attr "type" "neon_mla_qqq_8_16")) "cortex_a8_neon_dp_2") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -307,7 +307,7 @@ ;; produce a result at N6 on cycle 2. (define_insn_reservation "cortex_a8_neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long" 7 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")) + (eq_attr "type" "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")) "cortex_a8_neon_dp_2") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -315,21 +315,21 @@ ;; produce a result at N6 on cycle 4. (define_insn_reservation "cortex_a8_neon_mla_qqq_32_qqd_32_scalar" 9 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_mla_qqq_32_qqd_32_scalar")) + (eq_attr "type" "neon_mla_qqq_32_qqd_32_scalar")) "cortex_a8_neon_dp_4") ;; Instructions using this reservation read their (D|Q)n operands at N2, ;; their (D|Q)m operands at N1, and produce a result at N6. (define_insn_reservation "cortex_a8_neon_mul_ddd_16_scalar_32_16_long_scalar" 6 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_mul_ddd_16_scalar_32_16_long_scalar")) + (eq_attr "type" "neon_mul_ddd_16_scalar_32_16_long_scalar")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their (D|Q)n operands at N2, ;; their (D|Q)m operands at N1, and produce a result at N6 on cycle 4. (define_insn_reservation "cortex_a8_neon_mul_qqd_32_scalar" 9 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_mul_qqd_32_scalar")) + (eq_attr "type" "neon_mul_qqd_32_scalar")) "cortex_a8_neon_dp_4") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -337,84 +337,84 @@ ;; produce a result at N6. (define_insn_reservation "cortex_a8_neon_mla_ddd_16_scalar_qdd_32_16_long_scalar" 6 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")) + (eq_attr "type" "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N3. (define_insn_reservation "cortex_a8_neon_shift_1" 3 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_shift_1")) + (eq_attr "type" "neon_shift_1")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N4. (define_insn_reservation "cortex_a8_neon_shift_2" 4 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_shift_2")) + (eq_attr "type" "neon_shift_2")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N3 on cycle 2. (define_insn_reservation "cortex_a8_neon_shift_3" 4 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_shift_3")) + (eq_attr "type" "neon_shift_3")) "cortex_a8_neon_dp_2") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N1. (define_insn_reservation "cortex_a8_neon_vshl_ddd" 1 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vshl_ddd")) + (eq_attr "type" "neon_vshl_ddd")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N4 on cycle 2. (define_insn_reservation "cortex_a8_neon_vqshl_vrshl_vqrshl_qqq" 5 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vqshl_vrshl_vqrshl_qqq")) + (eq_attr "type" "neon_vqshl_vrshl_vqrshl_qqq")) "cortex_a8_neon_dp_2") ;; Instructions using this reservation read their (D|Q)m operands at N1, ;; their (D|Q)d operands at N3, and produce a result at N6. (define_insn_reservation "cortex_a8_neon_vsra_vrsra" 6 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vsra_vrsra")) + (eq_attr "type" "neon_vsra_vrsra")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their source operands at N2, and ;; produce a result at N5. (define_insn_reservation "cortex_a8_neon_fp_vadd_ddd_vabs_dd" 5 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd")) + (eq_attr "type" "neon_fp_vadd_ddd_vabs_dd")) "cortex_a8_neon_fadd") ;; Instructions using this reservation read their source operands at N2, and ;; produce a result at N5 on cycle 2. (define_insn_reservation "cortex_a8_neon_fp_vadd_qqq_vabs_qq" 6 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_fp_vadd_qqq_vabs_qq")) + (eq_attr "type" "neon_fp_vadd_qqq_vabs_qq")) "cortex_a8_neon_fadd_2") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N5. (define_insn_reservation "cortex_a8_neon_fp_vsum" 5 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_fp_vsum")) + (eq_attr "type" "neon_fp_vsum")) "cortex_a8_neon_fadd") ;; Instructions using this reservation read their (D|Q)n operands at N2, ;; their (D|Q)m operands at N1, and produce a result at N5. (define_insn_reservation "cortex_a8_neon_fp_vmul_ddd" 5 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_fp_vmul_ddd")) + (eq_attr "type" "neon_fp_vmul_ddd")) "cortex_a8_neon_dp") ;; Instructions using this reservation read their (D|Q)n operands at N2, ;; their (D|Q)m operands at N1, and produce a result at N5 on cycle 2. (define_insn_reservation "cortex_a8_neon_fp_vmul_qqd" 6 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_fp_vmul_qqd")) + (eq_attr "type" "neon_fp_vmul_qqd")) "cortex_a8_neon_dp_2") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -422,7 +422,7 @@ ;; produce a result at N9. (define_insn_reservation "cortex_a8_neon_fp_vmla_ddd" 9 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_fp_vmla_ddd")) + (eq_attr "type" "neon_fp_vmla_ddd")) "cortex_a8_neon_fmul_then_fadd") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -430,7 +430,7 @@ ;; produce a result at N9 on cycle 2. (define_insn_reservation "cortex_a8_neon_fp_vmla_qqq" 10 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_fp_vmla_qqq")) + (eq_attr "type" "neon_fp_vmla_qqq")) "cortex_a8_neon_fmul_then_fadd_2") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -438,7 +438,7 @@ ;; produce a result at N9. (define_insn_reservation "cortex_a8_neon_fp_vmla_ddd_scalar" 9 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_fp_vmla_ddd_scalar")) + (eq_attr "type" "neon_fp_vmla_ddd_scalar")) "cortex_a8_neon_fmul_then_fadd") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -446,152 +446,152 @@ ;; produce a result at N9 on cycle 2. (define_insn_reservation "cortex_a8_neon_fp_vmla_qqq_scalar" 10 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_fp_vmla_qqq_scalar")) + (eq_attr "type" "neon_fp_vmla_qqq_scalar")) "cortex_a8_neon_fmul_then_fadd_2") ;; Instructions using this reservation read their source operands at N2, and ;; produce a result at N9. (define_insn_reservation "cortex_a8_neon_fp_vrecps_vrsqrts_ddd" 9 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_fp_vrecps_vrsqrts_ddd")) + (eq_attr "type" "neon_fp_vrecps_vrsqrts_ddd")) "cortex_a8_neon_fmul_then_fadd") ;; Instructions using this reservation read their source operands at N2, and ;; produce a result at N9 on cycle 2. (define_insn_reservation "cortex_a8_neon_fp_vrecps_vrsqrts_qqq" 10 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_fp_vrecps_vrsqrts_qqq")) + (eq_attr "type" "neon_fp_vrecps_vrsqrts_qqq")) "cortex_a8_neon_fmul_then_fadd_2") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N2. (define_insn_reservation "cortex_a8_neon_bp_simple" 2 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_bp_simple")) + (eq_attr "type" "neon_bp_simple")) "cortex_a8_neon_perm") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N2 on cycle 2. (define_insn_reservation "cortex_a8_neon_bp_2cycle" 3 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_bp_2cycle")) + (eq_attr "type" "neon_bp_2cycle")) "cortex_a8_neon_perm_2") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N2 on cycle 3. (define_insn_reservation "cortex_a8_neon_bp_3cycle" 4 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_bp_3cycle")) + (eq_attr "type" "neon_bp_3cycle")) "cortex_a8_neon_perm_3") ;; Instructions using this reservation produce a result at N1. (define_insn_reservation "cortex_a8_neon_ldr" 1 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_ldr")) + (eq_attr "type" "neon_ldr")) "cortex_a8_neon_ls") ;; Instructions using this reservation read their source operands at N1. (define_insn_reservation "cortex_a8_neon_str" 0 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_str")) + (eq_attr "type" "neon_str")) "cortex_a8_neon_ls") ;; Instructions using this reservation produce a result at N1 on cycle 2. (define_insn_reservation "cortex_a8_neon_vld1_1_2_regs" 2 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vld1_1_2_regs")) + (eq_attr "type" "neon_vld1_1_2_regs")) "cortex_a8_neon_ls_2") ;; Instructions using this reservation produce a result at N1 on cycle 3. (define_insn_reservation "cortex_a8_neon_vld1_3_4_regs" 3 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vld1_3_4_regs")) + (eq_attr "type" "neon_vld1_3_4_regs")) "cortex_a8_neon_ls_3") ;; Instructions using this reservation produce a result at N2 on cycle 2. (define_insn_reservation "cortex_a8_neon_vld2_2_regs_vld1_vld2_all_lanes" 3 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")) + (eq_attr "type" "neon_vld2_2_regs_vld1_vld2_all_lanes")) "cortex_a8_neon_ls_2") ;; Instructions using this reservation produce a result at N2 on cycle 3. (define_insn_reservation "cortex_a8_neon_vld2_4_regs" 4 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vld2_4_regs")) + (eq_attr "type" "neon_vld2_4_regs")) "cortex_a8_neon_ls_3") ;; Instructions using this reservation produce a result at N2 on cycle 4. (define_insn_reservation "cortex_a8_neon_vld3_vld4" 5 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vld3_vld4")) + (eq_attr "type" "neon_vld3_vld4")) "cortex_a8_neon_ls_4") ;; Instructions using this reservation read their source operands at N1. (define_insn_reservation "cortex_a8_neon_vst1_1_2_regs_vst2_2_regs" 0 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")) + (eq_attr "type" "neon_vst1_1_2_regs_vst2_2_regs")) "cortex_a8_neon_ls_2") ;; Instructions using this reservation read their source operands at N1. (define_insn_reservation "cortex_a8_neon_vst1_3_4_regs" 0 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vst1_3_4_regs")) + (eq_attr "type" "neon_vst1_3_4_regs")) "cortex_a8_neon_ls_3") ;; Instructions using this reservation read their source operands at N1. (define_insn_reservation "cortex_a8_neon_vst2_4_regs_vst3_vst4" 0 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")) + (eq_attr "type" "neon_vst2_4_regs_vst3_vst4")) "cortex_a8_neon_ls_4") ;; Instructions using this reservation read their source operands at N1. (define_insn_reservation "cortex_a8_neon_vst3_vst4" 0 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vst3_vst4")) + (eq_attr "type" "neon_vst3_vst4")) "cortex_a8_neon_ls_4") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N2 on cycle 3. (define_insn_reservation "cortex_a8_neon_vld1_vld2_lane" 4 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vld1_vld2_lane")) + (eq_attr "type" "neon_vld1_vld2_lane")) "cortex_a8_neon_ls_3") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N2 on cycle 5. (define_insn_reservation "cortex_a8_neon_vld3_vld4_lane" 6 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vld3_vld4_lane")) + (eq_attr "type" "neon_vld3_vld4_lane")) "cortex_a8_neon_ls_5") ;; Instructions using this reservation read their source operands at N1. (define_insn_reservation "cortex_a8_neon_vst1_vst2_lane" 0 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vst1_vst2_lane")) + (eq_attr "type" "neon_vst1_vst2_lane")) "cortex_a8_neon_ls_2") ;; Instructions using this reservation read their source operands at N1. (define_insn_reservation "cortex_a8_neon_vst3_vst4_lane" 0 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vst3_vst4_lane")) + (eq_attr "type" "neon_vst3_vst4_lane")) "cortex_a8_neon_ls_3") ;; Instructions using this reservation produce a result at N2 on cycle 2. (define_insn_reservation "cortex_a8_neon_vld3_vld4_all_lanes" 3 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_vld3_vld4_all_lanes")) + (eq_attr "type" "neon_vld3_vld4_all_lanes")) "cortex_a8_neon_ls_3") ;; Instructions using this reservation produce a result at N2. (define_insn_reservation "cortex_a8_neon_mcr" 2 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_mcr")) + (eq_attr "type" "neon_mcr")) "cortex_a8_neon_perm") ;; Instructions using this reservation produce a result at N2. (define_insn_reservation "cortex_a8_neon_mcr_2_mcrr" 2 (and (eq_attr "tune" "cortexa8") - (eq_attr "neon_type" "neon_mcr_2_mcrr")) + (eq_attr "type" "neon_mcr_2_mcrr")) "cortex_a8_neon_perm_2") ;; Exceptions to the default latencies. diff --git a/gcc/config/arm/cortex-a8.md b/gcc/config/arm/cortex-a8.md index 1113a45ff0e..1eade5e1244 100644 --- a/gcc/config/arm/cortex-a8.md +++ b/gcc/config/arm/cortex-a8.md @@ -85,19 +85,25 @@ ;; (source read in E2 and destination available at the end of that cycle). (define_insn_reservation "cortex_a8_alu" 2 (and (eq_attr "tune" "cortexa8") - (ior (and (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg") - (eq_attr "neon_type" "none")) - (eq_attr "type" "clz"))) + (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,clz,rbit,rev,\ + shift_imm,shift_reg,\ + multiple,no_insn")) "cortex_a8_default") (define_insn_reservation "cortex_a8_alu_shift" 2 (and (eq_attr "tune" "cortexa8") - (eq_attr "type" "extend,arlo_shift")) + (eq_attr "type" "alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + extend")) "cortex_a8_default") (define_insn_reservation "cortex_a8_alu_shift_reg" 2 (and (eq_attr "tune" "cortexa8") - (eq_attr "type" "arlo_shift_reg")) + (eq_attr "type" "alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg")) "cortex_a8_default") ;; Move instructions. @@ -105,7 +111,8 @@ (define_insn_reservation "cortex_a8_mov" 1 (and (eq_attr "tune" "cortexa8") (eq_attr "type" "mov_imm,mov_reg,mov_shift,mov_shift_reg,\ - mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg")) + mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg,\ + mrs")) "cortex_a8_default") ;; Exceptions to the default latencies for data processing instructions. diff --git a/gcc/config/arm/cortex-a9-neon.md b/gcc/config/arm/cortex-a9-neon.md index 9688edc8f72..2c9d5db5bd8 100644 --- a/gcc/config/arm/cortex-a9-neon.md +++ b/gcc/config/arm/cortex-a9-neon.md @@ -109,12 +109,12 @@ ;; NEON -> core transfers. (define_insn_reservation "ca9_neon_mrc" 1 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_mrc")) + (eq_attr "type" "neon_mrc")) "ca9_issue_vfp_neon + cortex_a9_neon_mcr") (define_insn_reservation "ca9_neon_mrrc" 1 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_mrrc")) + (eq_attr "type" "neon_mrrc")) "ca9_issue_vfp_neon + cortex_a9_neon_mcr") ;; The remainder of this file is auto-generated by neon-schedgen. @@ -123,48 +123,48 @@ ;; produce a result at N3. (define_insn_reservation "cortex_a9_neon_int_1" 3 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_int_1")) + (eq_attr "type" "neon_int_1")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their (D|Q)m operands at N1, ;; their (D|Q)n operands at N2, and produce a result at N3. (define_insn_reservation "cortex_a9_neon_int_2" 3 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_int_2")) + (eq_attr "type" "neon_int_2")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N3. (define_insn_reservation "cortex_a9_neon_int_3" 3 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_int_3")) + (eq_attr "type" "neon_int_3")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their source operands at N2, and ;; produce a result at N4. (define_insn_reservation "cortex_a9_neon_int_4" 4 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_int_4")) + (eq_attr "type" "neon_int_4")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their (D|Q)m operands at N1, ;; their (D|Q)n operands at N2, and produce a result at N4. (define_insn_reservation "cortex_a9_neon_int_5" 4 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_int_5")) + (eq_attr "type" "neon_int_5")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N4. (define_insn_reservation "cortex_a9_neon_vqneg_vqabs" 4 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vqneg_vqabs")) + (eq_attr "type" "neon_vqneg_vqabs")) "cortex_a9_neon_dp") ;; Instructions using this reservation produce a result at N3. (define_insn_reservation "cortex_a9_neon_vmov" 3 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vmov")) + (eq_attr "type" "neon_vmov")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -172,7 +172,7 @@ ;; produce a result at N6. (define_insn_reservation "cortex_a9_neon_vaba" 6 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vaba")) + (eq_attr "type" "neon_vaba")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -180,35 +180,35 @@ ;; produce a result at N6 on cycle 2. (define_insn_reservation "cortex_a9_neon_vaba_qqq" 7 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vaba_qqq")) + (eq_attr "type" "neon_vaba_qqq")) "cortex_a9_neon_dp_2") ;; Instructions using this reservation read their (D|Q)m operands at N1, ;; their (D|Q)d operands at N3, and produce a result at N6. (define_insn_reservation "cortex_a9_neon_vsma" 6 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vsma")) + (eq_attr "type" "neon_vsma")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their source operands at N2, and ;; produce a result at N6. (define_insn_reservation "cortex_a9_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long" 6 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")) + (eq_attr "type" "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their source operands at N2, and ;; produce a result at N6 on cycle 2. (define_insn_reservation "cortex_a9_neon_mul_qqq_8_16_32_ddd_32" 7 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_mul_qqq_8_16_32_ddd_32")) + (eq_attr "type" "neon_mul_qqq_8_16_32_ddd_32")) "cortex_a9_neon_dp_2") ;; Instructions using this reservation read their (D|Q)n operands at N2, ;; their (D|Q)m operands at N1, and produce a result at N6 on cycle 2. (define_insn_reservation "cortex_a9_neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar" 7 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")) + (eq_attr "type" "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")) "cortex_a9_neon_dp_2") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -216,7 +216,7 @@ ;; produce a result at N6. (define_insn_reservation "cortex_a9_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long" 6 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")) + (eq_attr "type" "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -224,7 +224,7 @@ ;; produce a result at N6 on cycle 2. (define_insn_reservation "cortex_a9_neon_mla_qqq_8_16" 7 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_mla_qqq_8_16")) + (eq_attr "type" "neon_mla_qqq_8_16")) "cortex_a9_neon_dp_2") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -232,7 +232,7 @@ ;; produce a result at N6 on cycle 2. (define_insn_reservation "cortex_a9_neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long" 7 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")) + (eq_attr "type" "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")) "cortex_a9_neon_dp_2") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -240,21 +240,21 @@ ;; produce a result at N6 on cycle 4. (define_insn_reservation "cortex_a9_neon_mla_qqq_32_qqd_32_scalar" 9 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_mla_qqq_32_qqd_32_scalar")) + (eq_attr "type" "neon_mla_qqq_32_qqd_32_scalar")) "cortex_a9_neon_dp_4") ;; Instructions using this reservation read their (D|Q)n operands at N2, ;; their (D|Q)m operands at N1, and produce a result at N6. (define_insn_reservation "cortex_a9_neon_mul_ddd_16_scalar_32_16_long_scalar" 6 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_mul_ddd_16_scalar_32_16_long_scalar")) + (eq_attr "type" "neon_mul_ddd_16_scalar_32_16_long_scalar")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their (D|Q)n operands at N2, ;; their (D|Q)m operands at N1, and produce a result at N6 on cycle 4. (define_insn_reservation "cortex_a9_neon_mul_qqd_32_scalar" 9 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_mul_qqd_32_scalar")) + (eq_attr "type" "neon_mul_qqd_32_scalar")) "cortex_a9_neon_dp_4") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -262,84 +262,84 @@ ;; produce a result at N6. (define_insn_reservation "cortex_a9_neon_mla_ddd_16_scalar_qdd_32_16_long_scalar" 6 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")) + (eq_attr "type" "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N3. (define_insn_reservation "cortex_a9_neon_shift_1" 3 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_shift_1")) + (eq_attr "type" "neon_shift_1")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N4. (define_insn_reservation "cortex_a9_neon_shift_2" 4 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_shift_2")) + (eq_attr "type" "neon_shift_2")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N3 on cycle 2. (define_insn_reservation "cortex_a9_neon_shift_3" 4 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_shift_3")) + (eq_attr "type" "neon_shift_3")) "cortex_a9_neon_dp_2") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N1. (define_insn_reservation "cortex_a9_neon_vshl_ddd" 1 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vshl_ddd")) + (eq_attr "type" "neon_vshl_ddd")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N4 on cycle 2. (define_insn_reservation "cortex_a9_neon_vqshl_vrshl_vqrshl_qqq" 5 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vqshl_vrshl_vqrshl_qqq")) + (eq_attr "type" "neon_vqshl_vrshl_vqrshl_qqq")) "cortex_a9_neon_dp_2") ;; Instructions using this reservation read their (D|Q)m operands at N1, ;; their (D|Q)d operands at N3, and produce a result at N6. (define_insn_reservation "cortex_a9_neon_vsra_vrsra" 6 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vsra_vrsra")) + (eq_attr "type" "neon_vsra_vrsra")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their source operands at N2, and ;; produce a result at N5. (define_insn_reservation "cortex_a9_neon_fp_vadd_ddd_vabs_dd" 5 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd")) + (eq_attr "type" "neon_fp_vadd_ddd_vabs_dd")) "cortex_a9_neon_fadd") ;; Instructions using this reservation read their source operands at N2, and ;; produce a result at N5 on cycle 2. (define_insn_reservation "cortex_a9_neon_fp_vadd_qqq_vabs_qq" 6 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_fp_vadd_qqq_vabs_qq")) + (eq_attr "type" "neon_fp_vadd_qqq_vabs_qq")) "cortex_a9_neon_fadd_2") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N5. (define_insn_reservation "cortex_a9_neon_fp_vsum" 5 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_fp_vsum")) + (eq_attr "type" "neon_fp_vsum")) "cortex_a9_neon_fadd") ;; Instructions using this reservation read their (D|Q)n operands at N2, ;; their (D|Q)m operands at N1, and produce a result at N5. (define_insn_reservation "cortex_a9_neon_fp_vmul_ddd" 5 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_fp_vmul_ddd")) + (eq_attr "type" "neon_fp_vmul_ddd")) "cortex_a9_neon_dp") ;; Instructions using this reservation read their (D|Q)n operands at N2, ;; their (D|Q)m operands at N1, and produce a result at N5 on cycle 2. (define_insn_reservation "cortex_a9_neon_fp_vmul_qqd" 6 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_fp_vmul_qqd")) + (eq_attr "type" "neon_fp_vmul_qqd")) "cortex_a9_neon_dp_2") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -347,7 +347,7 @@ ;; produce a result at N9. (define_insn_reservation "cortex_a9_neon_fp_vmla_ddd" 9 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_fp_vmla_ddd")) + (eq_attr "type" "neon_fp_vmla_ddd")) "cortex_a9_neon_fmul_then_fadd") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -355,7 +355,7 @@ ;; produce a result at N9 on cycle 2. (define_insn_reservation "cortex_a9_neon_fp_vmla_qqq" 10 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_fp_vmla_qqq")) + (eq_attr "type" "neon_fp_vmla_qqq")) "cortex_a9_neon_fmul_then_fadd_2") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -363,7 +363,7 @@ ;; produce a result at N9. (define_insn_reservation "cortex_a9_neon_fp_vmla_ddd_scalar" 9 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_fp_vmla_ddd_scalar")) + (eq_attr "type" "neon_fp_vmla_ddd_scalar")) "cortex_a9_neon_fmul_then_fadd") ;; Instructions using this reservation read their (D|Q)n operands at N2, @@ -371,152 +371,152 @@ ;; produce a result at N9 on cycle 2. (define_insn_reservation "cortex_a9_neon_fp_vmla_qqq_scalar" 10 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_fp_vmla_qqq_scalar")) + (eq_attr "type" "neon_fp_vmla_qqq_scalar")) "cortex_a9_neon_fmul_then_fadd_2") ;; Instructions using this reservation read their source operands at N2, and ;; produce a result at N9. (define_insn_reservation "cortex_a9_neon_fp_vrecps_vrsqrts_ddd" 9 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_fp_vrecps_vrsqrts_ddd")) + (eq_attr "type" "neon_fp_vrecps_vrsqrts_ddd")) "cortex_a9_neon_fmul_then_fadd") ;; Instructions using this reservation read their source operands at N2, and ;; produce a result at N9 on cycle 2. (define_insn_reservation "cortex_a9_neon_fp_vrecps_vrsqrts_qqq" 10 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_fp_vrecps_vrsqrts_qqq")) + (eq_attr "type" "neon_fp_vrecps_vrsqrts_qqq")) "cortex_a9_neon_fmul_then_fadd_2") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N2. (define_insn_reservation "cortex_a9_neon_bp_simple" 2 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_bp_simple")) + (eq_attr "type" "neon_bp_simple")) "cortex_a9_neon_perm") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N2 on cycle 2. (define_insn_reservation "cortex_a9_neon_bp_2cycle" 3 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_bp_2cycle")) + (eq_attr "type" "neon_bp_2cycle")) "cortex_a9_neon_perm_2") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N2 on cycle 3. (define_insn_reservation "cortex_a9_neon_bp_3cycle" 4 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_bp_3cycle")) + (eq_attr "type" "neon_bp_3cycle")) "cortex_a9_neon_perm_3") ;; Instructions using this reservation produce a result at N1. (define_insn_reservation "cortex_a9_neon_ldr" 1 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_ldr")) + (eq_attr "type" "neon_ldr")) "cortex_a9_neon_ls") ;; Instructions using this reservation read their source operands at N1. (define_insn_reservation "cortex_a9_neon_str" 0 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_str")) + (eq_attr "type" "neon_str")) "cortex_a9_neon_ls") ;; Instructions using this reservation produce a result at N1 on cycle 2. (define_insn_reservation "cortex_a9_neon_vld1_1_2_regs" 2 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vld1_1_2_regs")) + (eq_attr "type" "neon_vld1_1_2_regs")) "cortex_a9_neon_ls_2") ;; Instructions using this reservation produce a result at N1 on cycle 3. (define_insn_reservation "cortex_a9_neon_vld1_3_4_regs" 3 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vld1_3_4_regs")) + (eq_attr "type" "neon_vld1_3_4_regs")) "cortex_a9_neon_ls_3") ;; Instructions using this reservation produce a result at N2 on cycle 2. (define_insn_reservation "cortex_a9_neon_vld2_2_regs_vld1_vld2_all_lanes" 3 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")) + (eq_attr "type" "neon_vld2_2_regs_vld1_vld2_all_lanes")) "cortex_a9_neon_ls_2") ;; Instructions using this reservation produce a result at N2 on cycle 3. (define_insn_reservation "cortex_a9_neon_vld2_4_regs" 4 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vld2_4_regs")) + (eq_attr "type" "neon_vld2_4_regs")) "cortex_a9_neon_ls_3") ;; Instructions using this reservation produce a result at N2 on cycle 4. (define_insn_reservation "cortex_a9_neon_vld3_vld4" 5 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vld3_vld4")) + (eq_attr "type" "neon_vld3_vld4")) "cortex_a9_neon_ls_4") ;; Instructions using this reservation read their source operands at N1. (define_insn_reservation "cortex_a9_neon_vst1_1_2_regs_vst2_2_regs" 0 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")) + (eq_attr "type" "neon_vst1_1_2_regs_vst2_2_regs")) "cortex_a9_neon_ls_2") ;; Instructions using this reservation read their source operands at N1. (define_insn_reservation "cortex_a9_neon_vst1_3_4_regs" 0 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vst1_3_4_regs")) + (eq_attr "type" "neon_vst1_3_4_regs")) "cortex_a9_neon_ls_3") ;; Instructions using this reservation read their source operands at N1. (define_insn_reservation "cortex_a9_neon_vst2_4_regs_vst3_vst4" 0 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")) + (eq_attr "type" "neon_vst2_4_regs_vst3_vst4")) "cortex_a9_neon_ls_4") ;; Instructions using this reservation read their source operands at N1. (define_insn_reservation "cortex_a9_neon_vst3_vst4" 0 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vst3_vst4")) + (eq_attr "type" "neon_vst3_vst4")) "cortex_a9_neon_ls_4") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N2 on cycle 3. (define_insn_reservation "cortex_a9_neon_vld1_vld2_lane" 4 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vld1_vld2_lane")) + (eq_attr "type" "neon_vld1_vld2_lane")) "cortex_a9_neon_ls_3") ;; Instructions using this reservation read their source operands at N1, and ;; produce a result at N2 on cycle 5. (define_insn_reservation "cortex_a9_neon_vld3_vld4_lane" 6 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vld3_vld4_lane")) + (eq_attr "type" "neon_vld3_vld4_lane")) "cortex_a9_neon_ls_5") ;; Instructions using this reservation read their source operands at N1. (define_insn_reservation "cortex_a9_neon_vst1_vst2_lane" 0 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vst1_vst2_lane")) + (eq_attr "type" "neon_vst1_vst2_lane")) "cortex_a9_neon_ls_2") ;; Instructions using this reservation read their source operands at N1. (define_insn_reservation "cortex_a9_neon_vst3_vst4_lane" 0 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vst3_vst4_lane")) + (eq_attr "type" "neon_vst3_vst4_lane")) "cortex_a9_neon_ls_3") ;; Instructions using this reservation produce a result at N2 on cycle 2. (define_insn_reservation "cortex_a9_neon_vld3_vld4_all_lanes" 3 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_vld3_vld4_all_lanes")) + (eq_attr "type" "neon_vld3_vld4_all_lanes")) "cortex_a9_neon_ls_3") ;; Instructions using this reservation produce a result at N2. (define_insn_reservation "cortex_a9_neon_mcr" 2 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_mcr")) + (eq_attr "type" "neon_mcr")) "cortex_a9_neon_perm") ;; Instructions using this reservation produce a result at N2. (define_insn_reservation "cortex_a9_neon_mcr_2_mcrr" 2 (and (eq_attr "tune" "cortexa9") - (eq_attr "neon_type" "neon_mcr_2_mcrr")) + (eq_attr "type" "neon_mcr_2_mcrr")) "cortex_a9_neon_perm_2") ;; Exceptions to the default latencies. diff --git a/gcc/config/arm/cortex-a9.md b/gcc/config/arm/cortex-a9.md index 11dc0b32c38..7c62d8489ae 100644 --- a/gcc/config/arm/cortex-a9.md +++ b/gcc/config/arm/cortex-a9.md @@ -80,17 +80,24 @@ cortex_a9_p1_e2 + cortex_a9_p0_e1 + cortex_a9_p1_e1") ;; which can go down E2 without any problem. (define_insn_reservation "cortex_a9_dp" 2 (and (eq_attr "tune" "cortexa9") - (and (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ - mov_imm,mov_reg,mvn_imm,mvn_reg,\ - mov_shift_reg,mov_shift") - (eq_attr "neon_type" "none"))) + (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg,\ + mov_imm,mov_reg,mvn_imm,mvn_reg,\ + mov_shift_reg,mov_shift,\ + mrs,multiple,no_insn")) "cortex_a9_p0_default|cortex_a9_p1_default") ;; An instruction using the shifter will go down E1. (define_insn_reservation "cortex_a9_dp_shift" 3 (and (eq_attr "tune" "cortexa9") - (eq_attr "type" "arlo_shift_reg,extend,arlo_shift,\ - mvn_shift,mvn_shift_reg")) + (eq_attr "type" "alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg,\ + extend,mvn_shift,mvn_shift_reg")) "cortex_a9_p0_shift | cortex_a9_p1_shift") ;; Loads have a latency of 4 cycles. @@ -200,7 +207,7 @@ cortex_a9_store3_4, cortex_a9_store1_2, cortex_a9_load3_4") ;; Pipelining for VFP instructions. ;; Issue happens either along load store unit or the VFP / Neon unit. ;; Pipeline Instruction Classification. -;; FPS - fcpys, ffariths, ffarithd,r_2_f,f_2_r +;; FPS - fmov, ffariths, ffarithd,f_mcr,f_mcrr,f_mrc,f_mrrc ;; FP_ADD - fadds, faddd, fcmps (1) ;; FPMUL - fmul{s,d}, fmac{s,d}, ffma{s,d} ;; FPDIV - fdiv{s,d} @@ -213,7 +220,8 @@ cortex_a9_store3_4, cortex_a9_store1_2, cortex_a9_load3_4") ;; fmrs, fmrrd, fmstat and fmrx - The data is available after 1 cycle. (define_insn_reservation "cortex_a9_fps" 2 (and (eq_attr "tune" "cortexa9") - (eq_attr "type" "fcpys, fconsts, fconstd, ffariths, ffarithd, r_2_f, f_2_r, f_flag")) + (eq_attr "type" "fmov, fconsts, fconstd, ffariths, ffarithd,\ + f_mcr, f_mcrr, f_mrc, f_mrrc, f_flag")) "ca9_issue_vfp_neon + ca9fps") (define_bypass 1 @@ -225,7 +233,7 @@ cortex_a9_store3_4, cortex_a9_store1_2, cortex_a9_load3_4") (define_insn_reservation "cortex_a9_fadd" 4 (and (eq_attr "tune" "cortexa9") - (eq_attr "type" "fadds, faddd, f_cvt")) + (eq_attr "type" "fadds, faddd, f_cvt, f_cvtf2i, f_cvti2f")) "ca9fp_add") (define_insn_reservation "cortex_a9_fcmp" 1 @@ -263,12 +271,12 @@ cortex_a9_store3_4, cortex_a9_store1_2, cortex_a9_load3_4") ;; Division pipeline description. (define_insn_reservation "cortex_a9_fdivs" 15 (and (eq_attr "tune" "cortexa9") - (eq_attr "type" "fdivs")) + (eq_attr "type" "fdivs, fsqrts")) "ca9fp_ds1 + ca9_issue_vfp_neon, nothing*14") (define_insn_reservation "cortex_a9_fdivd" 25 (and (eq_attr "tune" "cortexa9") - (eq_attr "type" "fdivd")) + (eq_attr "type" "fdivd, fsqrtd")) "ca9fp_ds1 + ca9_issue_vfp_neon, nothing*24") ;; Include Neon pipeline description diff --git a/gcc/config/arm/cortex-m4-fpu.md b/gcc/config/arm/cortex-m4-fpu.md index 4ce3f10f0de..2190938b65c 100644 --- a/gcc/config/arm/cortex-m4-fpu.md +++ b/gcc/config/arm/cortex-m4-fpu.md @@ -30,17 +30,17 @@ ;; Integer instructions following VDIV or VSQRT complete out-of-order. (define_insn_reservation "cortex_m4_fdivs" 15 (and (eq_attr "tune" "cortexm4") - (eq_attr "type" "fdivs")) + (eq_attr "type" "fdivs, fsqrts")) "cortex_m4_ex_v,cortex_m4_v*13") (define_insn_reservation "cortex_m4_vmov_1" 1 (and (eq_attr "tune" "cortexm4") - (eq_attr "type" "fcpys,fconsts")) + (eq_attr "type" "fmov,fconsts")) "cortex_m4_ex_v") (define_insn_reservation "cortex_m4_vmov_2" 2 (and (eq_attr "tune" "cortexm4") - (eq_attr "type" "f_2_r,r_2_f")) + (eq_attr "type" "f_mrc,f_mrrc,f_mcr,f_mcrr")) "cortex_m4_ex_v*2") (define_insn_reservation "cortex_m4_fmuls" 2 @@ -77,7 +77,7 @@ (define_insn_reservation "cortex_m4_f_cvt" 2 (and (eq_attr "tune" "cortexm4") - (eq_attr "type" "f_cvt")) + (eq_attr "type" "f_cvt,f_cvtf2i,f_cvti2f")) "cortex_m4_ex_v") (define_insn_reservation "cortex_m4_f_load" 2 diff --git a/gcc/config/arm/cortex-m4.md b/gcc/config/arm/cortex-m4.md index 53bd60cd98f..9ae4cc3143b 100644 --- a/gcc/config/arm/cortex-m4.md +++ b/gcc/config/arm/cortex-m4.md @@ -31,10 +31,18 @@ ;; ALU and multiply is one cycle. (define_insn_reservation "cortex_m4_alu" 1 (and (eq_attr "tune" "cortexm4") - (ior (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,extend,\ - arlo_shift,arlo_shift_reg,\ + (ior (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg,extend,\ + alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg,\ mov_imm,mov_reg,mov_shift,mov_shift_reg,\ - mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg") + mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg,\ + mrs,multiple,no_insn") (ior (eq_attr "mul32" "yes") (eq_attr "mul64" "yes")))) "cortex_m4_ex") diff --git a/gcc/config/arm/cortex-r4.md b/gcc/config/arm/cortex-r4.md index 597774dbd89..7a3ceeb15d7 100644 --- a/gcc/config/arm/cortex-r4.md +++ b/gcc/config/arm/cortex-r4.md @@ -78,7 +78,11 @@ ;; for the purposes of the dual-issue constraints above. (define_insn_reservation "cortex_r4_alu" 2 (and (eq_attr "tune_cortexr4" "yes") - (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,mvn_imm,mvn_reg")) + (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg,mvn_imm,mvn_reg")) "cortex_r4_alu") (define_insn_reservation "cortex_r4_mov" 2 @@ -88,12 +92,17 @@ (define_insn_reservation "cortex_r4_alu_shift" 2 (and (eq_attr "tune_cortexr4" "yes") - (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift")) + (eq_attr "type" "alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + extend,mov_shift,mvn_shift")) "cortex_r4_alu") (define_insn_reservation "cortex_r4_alu_shift_reg" 2 (and (eq_attr "tune_cortexr4" "yes") - (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")) + (eq_attr "type" "alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg,\ + mov_shift_reg,mvn_shift_reg,\ + mrs,multiple,no_insn")) "cortex_r4_alu_shift_reg") ;; An ALU instruction followed by an ALU instruction with no early dep. diff --git a/gcc/config/arm/cortex-r4f.md b/gcc/config/arm/cortex-r4f.md index 0c0bae0cd74..1bc4249d4d1 100644 --- a/gcc/config/arm/cortex-r4f.md +++ b/gcc/config/arm/cortex-r4f.md @@ -48,7 +48,7 @@ (define_insn_reservation "cortex_r4_fcpys" 2 (and (eq_attr "tune_cortexr4" "yes") - (eq_attr "type" "fcpys")) + (eq_attr "type" "fmov")) "cortex_r4_issue_ab") (define_insn_reservation "cortex_r4_ffariths" 2 @@ -68,7 +68,7 @@ (define_insn_reservation "cortex_r4_fdivs" 17 (and (eq_attr "tune_cortexr4" "yes") - (eq_attr "type" "fdivs")) + (eq_attr "type" "fdivs, fsqrts")) "cortex_r4_issue_ab+cortex_r4_v1,cortex_r4_issue_a+cortex_r4_v1") (define_insn_reservation "cortex_r4_floads" 2 @@ -83,12 +83,12 @@ (define_insn_reservation "cortex_r4_mcr" 2 (and (eq_attr "tune_cortexr4" "yes") - (eq_attr "type" "r_2_f")) + (eq_attr "type" "f_mcr,f_mcrr")) "cortex_r4_issue_ab") (define_insn_reservation "cortex_r4_mrc" 3 (and (eq_attr "tune_cortexr4" "yes") - (eq_attr "type" "f_2_r")) + (eq_attr "type" "f_mrc,f_mrrc")) "cortex_r4_issue_ab") ;; Bypasses for normal (not early) regs. @@ -131,7 +131,7 @@ ;; out of order. Chances are this is not a pipelined operation. (define_insn_reservation "cortex_r4_fdivd" 97 (and (eq_attr "tune_cortexr4" "yes") - (eq_attr "type" "fdivd")) + (eq_attr "type" "fdivd, fsqrtd")) "cortex_r4_single_issue*3") (define_insn_reservation "cortex_r4_ffarithd" 2 @@ -146,7 +146,7 @@ (define_insn_reservation "cortex_r4_f_cvt" 8 (and (eq_attr "tune_cortexr4" "yes") - (eq_attr "type" "f_cvt")) + (eq_attr "type" "f_cvt,f_cvtf2i,f_cvti2f")) "cortex_r4_single_issue*3") (define_insn_reservation "cortex_r4_f_memd" 8 diff --git a/gcc/config/arm/fa526.md b/gcc/config/arm/fa526.md index 9ec92d60dc5..401abd3c0a0 100644 --- a/gcc/config/arm/fa526.md +++ b/gcc/config/arm/fa526.md @@ -62,13 +62,22 @@ ;; ALU operations (define_insn_reservation "526_alu_op" 1 (and (eq_attr "tune" "fa526") - (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ - mov_imm,mov_reg,mvn_imm,mvn_reg")) + (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg,\ + mov_imm,mov_reg,mvn_imm,mvn_reg,\ + mrs,multiple,no_insn")) "fa526_core") (define_insn_reservation "526_alu_shift_op" 2 (and (eq_attr "tune" "fa526") - (eq_attr "type" "extend,arlo_shift,arlo_shift_reg,\ + (eq_attr "type" "extend,\ + alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg,\ mov_shift,mov_shift_reg,\ mvn_shift,mvn_shift_reg")) "fa526_core") diff --git a/gcc/config/arm/fa606te.md b/gcc/config/arm/fa606te.md index e61242886d7..88347bc2d96 100644 --- a/gcc/config/arm/fa606te.md +++ b/gcc/config/arm/fa606te.md @@ -62,10 +62,18 @@ ;; ALU operations (define_insn_reservation "606te_alu_op" 1 (and (eq_attr "tune" "fa606te") - (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg, - extend,arlo_shift,arlo_shift_reg,\ + (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg,extend,\ + alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg,\ mov_imm,mov_reg,mov_shift,mov_shift_reg,\ - mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg")) + mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg,\ + mrs,multiple,no_insn")) "fa606te_core") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/gcc/config/arm/fa626te.md b/gcc/config/arm/fa626te.md index 04d2a5cf33f..e6790a21215 100644 --- a/gcc/config/arm/fa626te.md +++ b/gcc/config/arm/fa626te.md @@ -68,13 +68,22 @@ ;; ALU operations (define_insn_reservation "626te_alu_op" 1 (and (eq_attr "tune" "fa626,fa626te") - (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ - mov_imm,mov_reg,mvn_imm,mvn_reg")) + (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg,\ + mov_imm,mov_reg,mvn_imm,mvn_reg,\ + mrs,multiple,no_insn")) "fa626te_core") (define_insn_reservation "626te_alu_shift_op" 2 (and (eq_attr "tune" "fa626,fa626te") - (eq_attr "type" "extend,arlo_shift,arlo_shift_reg,\ + (eq_attr "type" "extend,\ + alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm,\ + alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg,\ mov_shift,mov_shift_reg,\ mvn_shift,mvn_shift_reg")) "fa626te_core") diff --git a/gcc/config/arm/fa726te.md b/gcc/config/arm/fa726te.md index 342b9bf5d33..d0a03981eec 100644 --- a/gcc/config/arm/fa726te.md +++ b/gcc/config/arm/fa726te.md @@ -86,7 +86,12 @@ ;; Other ALU instructions 2 cycles. (define_insn_reservation "726te_alu_op" 1 (and (eq_attr "tune" "fa726te") - (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg")) + (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\ + alu_reg,alus_reg,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg,\ + mrs,multiple,no_insn")) "fa726te_issue+(fa726te_alu0_pipe|fa726te_alu1_pipe)") ;; ALU operations with a shift-by-register operand. @@ -95,12 +100,14 @@ ;; it takes 3 cycles. (define_insn_reservation "726te_alu_shift_op" 3 (and (eq_attr "tune" "fa726te") - (eq_attr "type" "extend,arlo_shift")) + (eq_attr "type" "extend,alu_shift_imm,alus_shift_imm,\ + logic_shift_imm,logics_shift_imm")) "fa726te_issue+(fa726te_alu0_pipe|fa726te_alu1_pipe)") (define_insn_reservation "726te_alu_shift_reg_op" 3 (and (eq_attr "tune" "fa726te") - (eq_attr "type" "arlo_shift_reg")) + (eq_attr "type" "alu_shift_reg,alus_shift_reg,\ + logic_shift_reg,logics_shift_reg")) "fa726te_issue+(fa726te_alu0_pipe|fa726te_alu1_pipe)") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Multiplication Instructions diff --git a/gcc/config/arm/fmp626.md b/gcc/config/arm/fmp626.md index 944645b9ead..ffb68570e37 100644 --- a/gcc/config/arm/fmp626.md +++ b/gcc/config/arm/fmp626.md @@ -63,13 +63,19 @@ ;; ALU operations (define_insn_reservation "mp626_alu_op" 1 (and (eq_attr "tune" "fmp626") - (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\ + (eq_attr "type" "alu_imm,alus_imm,alu_reg,alus_reg,\ + logic_imm,logics_imm,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg,\ mov_imm,mov_reg,mvn_imm,mvn_reg")) "fmp626_core") (define_insn_reservation "mp626_alu_shift_op" 2 (and (eq_attr "tune" "fmp626") - (eq_attr "type" "extend,arlo_shift,arlo_shift_reg,\ + (eq_attr "type" "alu_shift_imm,logic_shift_imm,alus_shift_imm,logics_shift_imm,\ + alu_shift_reg,logic_shift_reg,alus_shift_reg,logics_shift_reg,\ + extend,\ mov_shift,mov_shift_reg,\ mvn_shift,mvn_shift_reg")) "fmp626_core") diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index d84929f3d1f..c7d7079b9de 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -391,7 +391,7 @@ (define_mode_attr scalar_mul_constraint [(V4HI "x") (V2SI "t") (V2SF "t") (V8HI "x") (V4SI "t") (V4SF "t")]) -;; Predicates used for setting neon_type +;; Predicates used for setting type for neon instructions (define_mode_attr Is_float_mode [(V8QI "false") (V16QI "false") (V4HI "false") (V8HI "false") diff --git a/gcc/config/arm/iwmmxt.md b/gcc/config/arm/iwmmxt.md index f1f0a5c5150..62cdae21e3f 100644 --- a/gcc/config/arm/iwmmxt.md +++ b/gcc/config/arm/iwmmxt.md @@ -155,7 +155,8 @@ (const_int 8) (const_int 4))] (const_int 4))) - (set_attr "type" "*,*,*,load2,store2,wmmx_wmov,wmmx_tmcrr,wmmx_tmrrc,wmmx_wldr,wmmx_wstr,r_2_f,f_2_r,ffarithd,f_loadd,f_stored") + (set_attr "type" "*,*,*,load2,store2,*,*,*,*,*,f_mcrr,f_mrrc,\ + ffarithd,f_loadd,f_stored") (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,*,*,*,*,*,*,1020,*") (set_attr "arm_neg_pool_range" "*,*,*,1008,*,*,*,*,*,*,*,*,*,1008,*")] ) @@ -187,7 +188,8 @@ default: gcc_unreachable (); }" - [(set_attr "type" "*,*,*,*,load1,store1,wmmx_tmcr,wmmx_tmrc,wmmx_wldr,wmmx_wstr,r_2_f,f_2_r,fcpys,f_loads,f_stores") + [(set_attr "type" "*,*,*,*,load1,store1,*,*,*,*,f_mcr,f_mrc,\ + fmov,f_loads,f_stores") (set_attr "length" "*,*,*,*,*, *,*,*, 16, *,*,*,*,*,*") (set_attr "pool_range" "*,*,*,*,4096, *,*,*,1024, *,*,*,*,1020,*") (set_attr "neg_pool_range" "*,*,*,*,4084, *,*,*, *, 1012,*,*,*,1008,*") diff --git a/gcc/config/arm/marvell-pj4.md b/gcc/config/arm/marvell-pj4.md index 0e2c443721e..880789600e0 100644 --- a/gcc/config/arm/marvell-pj4.md +++ b/gcc/config/arm/marvell-pj4.md @@ -53,26 +53,42 @@ (define_insn_reservation "pj4_alu" 1 (and (eq_attr "tune" "marvell_pj4") - (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg") + (eq_attr "type" "alu_imm,alus_imm,alu_reg,alus_reg,\ + logic_imm,logics_imm,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg") (not (eq_attr "conds" "set"))) "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") (define_insn_reservation "pj4_alu_conds" 4 (and (eq_attr "tune" "marvell_pj4") - (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg") + (eq_attr "type" "alu_imm,alus_imm,alu_reg,alus_reg,\ + logic_imm,logics_imm,logic_reg,logics_reg,\ + adc_imm,adcs_imm,adc_reg,adcs_reg,\ + adr,bfm,rev,\ + shift_imm,shift_reg") (eq_attr "conds" "set")) "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") (define_insn_reservation "pj4_shift" 1 (and (eq_attr "tune" "marvell_pj4") - (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\ + (eq_attr "type" "alu_shift_imm,logic_shift_imm,\ + alus_shift_imm,logics_shift_imm,\ + alu_shift_reg,logic_shift_reg,\ + alus_shift_reg,logics_shift_reg,\ + extend,\ mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg") (not (eq_attr "conds" "set")) (eq_attr "shift" "1")) "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") (define_insn_reservation "pj4_shift_conds" 4 (and (eq_attr "tune" "marvell_pj4") - (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\ + (eq_attr "type" "alu_shift_imm,logic_shift_imm,\ + alus_shift_imm,logics_shift_imm,\ + alu_shift_reg,logic_shift_reg,\ + alus_shift_reg,logics_shift_reg,\ + extend,\ mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg") (eq_attr "conds" "set") (eq_attr "shift" "1")) "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)") @@ -80,14 +96,20 @@ (define_insn_reservation "pj4_alu_shift" 1 (and (eq_attr "tune" "marvell_pj4") (not (eq_attr "conds" "set")) - (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\ + (eq_attr "type" "alu_shift_imm,logic_shift_imm,\ + alus_shift_imm,logics_shift_imm,\ + alu_shift_reg,logic_shift_reg,\ + alus_shift_reg,logics_shift_reg,\ + extend,\ mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg")) "pj4_is,(pj4_alu1,nothing,pj4_w1+pj4_cp)|(pj4_alu2,nothing,pj4_w2+pj4_cp)") (define_insn_reservation "pj4_alu_shift_conds" 4 (and (eq_attr "tune" "marvell_pj4") (eq_attr "conds" "set") - (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\ + (eq_attr "type" "alu_shift_imm,logic_shift_imm,alus_shift_imm,logics_shift_imm,\ + alu_shift_reg,logic_shift_reg,alus_shift_reg,logics_shift_reg,\ + extend,\ mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg")) "pj4_is,(pj4_alu1,nothing,pj4_w1+pj4_cp)|(pj4_alu2,nothing,pj4_w2+pj4_cp)") @@ -171,11 +193,11 @@ (define_insn_reservation "pj4_vfp_divs" 20 (and (eq_attr "tune" "marvell_pj4") - (eq_attr "type" "fdivs")) "pj4_is,nothing*2,vissue,vdiv*18,nothing") + (eq_attr "type" "fdivs, fsqrts")) "pj4_is,nothing*2,vissue,vdiv*18,nothing") (define_insn_reservation "pj4_vfp_divd" 34 (and (eq_attr "tune" "marvell_pj4") - (eq_attr "type" "fdivd")) "pj4_is,nothing*2,vissue,vdiv*32,nothing") + (eq_attr "type" "fdivd, fsqrtd")) "pj4_is,nothing*2,vissue,vdiv*32,nothing") (define_insn_reservation "pj4_vfp_mac" 9 (and (eq_attr "tune" "marvell_pj4") @@ -186,8 +208,9 @@ (define_insn_reservation "pj4_vfp_cpy" 4 (and (eq_attr "tune" "marvell_pj4") - (eq_attr "type" "fcpys,ffariths,ffarithd,fconsts,fconstd,\ - fcmps,fcmpd,f_cvt")) "pj4_is,nothing*2,vissue,vfast,nothing*2") + (eq_attr "type" "fmov,ffariths,ffarithd,fconsts,fconstd,\ + fcmps,fcmpd,f_cvt,f_cvtf2i,f_cvti2f")) +"pj4_is,nothing*2,vissue,vfast,nothing*2") ;; Enlarge latency, and wish that more nondependent insns are ;; scheduled immediately after VFP load. @@ -201,9 +224,9 @@ (define_insn_reservation "pj4_vfp_to_core" 7 (and (eq_attr "tune" "marvell_pj4") - (eq_attr "type" "f_2_r,f_flag")) "pj4_isb,nothing,nothing,vissue,vfast,nothing*2") + (eq_attr "type" "f_mrc,f_mrrc,f_flag")) "pj4_isb,nothing,nothing,vissue,vfast,nothing*2") (define_insn_reservation "pj4_core_to_vfp" 2 (and (eq_attr "tune" "marvell_pj4") - (eq_attr "type" "r_2_f")) "pj4_isb,pj4_alu1,pj4_w1,vissue,pj4_cp") + (eq_attr "type" "f_mcr,f_mcrr")) "pj4_isb,pj4_alu1,pj4_w1,vissue,pj4_cp") diff --git a/gcc/config/arm/neon-schedgen.ml b/gcc/config/arm/neon-schedgen.ml index 7dacbab2625..b3699563d48 100644 --- a/gcc/config/arm/neon-schedgen.ml +++ b/gcc/config/arm/neon-schedgen.ml @@ -480,7 +480,7 @@ let emit_insn_reservations core = Printf.printf "(define_insn_reservation \"%s_%s\" %d\n" corestring producer latency; Printf.printf " (and (eq_attr \"tune\" \"%s\")\n" tunestring; - Printf.printf " (eq_attr \"neon_type\" \"%s\"))\n" producer; + Printf.printf " (eq_attr \"type\" \"%s\"))\n" producer; let str = match reservation with Mul -> "dp" | Mul_2cycle -> "dp_2" | Mul_4cycle -> "dp_4" diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index e00ca2c7bf9..ae83dba5f89 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -20,7 +20,7 @@ ;; Attribute used to permit string comparisons against <VQH_mnem> in -;; neon_type attribute definitions. +;; type attribute definitions. (define_attr "vqh_mnem" "vadd,vmin,vmax" (const_string "vadd")) (define_insn "*neon_mov<mode>" @@ -60,8 +60,8 @@ default: return output_move_double (operands, true, NULL); } } - [(set_attr "neon_type" "neon_int_1,*,neon_vmov,*,neon_mrrc,neon_mcr_2_mcrr,*,*,*") - (set_attr "type" "*,f_stored,*,f_loadd,*,*,mov_reg,load2,store2") + [(set_attr "type" "neon_int_1,f_stored,neon_vmov,f_loadd,neon_mrrc,\ + neon_mcr_2_mcrr,mov_reg,load2,store2") (set_attr "length" "4,4,4,4,4,4,8,8,8") (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,1020,*") (set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*") @@ -104,9 +104,8 @@ default: return output_move_quad (operands); } } - [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\ - neon_mrrc,neon_mcr_2_mcrr,*,*,*") - (set_attr "type" "*,*,*,*,*,*,mov_reg,load4,store4") + [(set_attr "type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\ + neon_mrrc,neon_mcr_2_mcrr,mov_reg,load4,store4") (set_attr "length" "4,8,4,8,8,8,16,8,16") (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,1020,*") (set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*") @@ -150,7 +149,7 @@ default: gcc_unreachable (); } } - [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_ldm_2") + [(set_attr "type" "neon_int_1,neon_stm_2,neon_ldm_2") (set (attr "length") (symbol_ref "arm_attr_length_move_neon (insn)"))]) (define_split @@ -258,7 +257,7 @@ UNSPEC_MISALIGNED_ACCESS))] "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access" "vst1.<V_sz_elem>\t{%P1}, %A0" - [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]) + [(set_attr "type" "neon_vst1_1_2_regs_vst2_2_regs")]) (define_insn "*movmisalign<mode>_neon_load" [(set (match_operand:VDX 0 "s_register_operand" "=w") @@ -267,7 +266,7 @@ UNSPEC_MISALIGNED_ACCESS))] "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access" "vld1.<V_sz_elem>\t{%P0}, %A1" - [(set_attr "neon_type" "neon_vld1_1_2_regs")]) + [(set_attr "type" "neon_vld1_1_2_regs")]) (define_insn "*movmisalign<mode>_neon_store" [(set (match_operand:VQX 0 "neon_permissive_struct_operand" "=Um") @@ -275,7 +274,7 @@ UNSPEC_MISALIGNED_ACCESS))] "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access" "vst1.<V_sz_elem>\t{%q1}, %A0" - [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]) + [(set_attr "type" "neon_vst1_1_2_regs_vst2_2_regs")]) (define_insn "*movmisalign<mode>_neon_load" [(set (match_operand:VQX 0 "s_register_operand" "=w") @@ -284,7 +283,7 @@ UNSPEC_MISALIGNED_ACCESS))] "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access" "vld1.<V_sz_elem>\t{%q0}, %A1" - [(set_attr "neon_type" "neon_vld1_1_2_regs")]) + [(set_attr "type" "neon_vld1_1_2_regs")]) (define_insn "vec_set<mode>_internal" [(set (match_operand:VD 0 "s_register_operand" "=w,w") @@ -305,7 +304,7 @@ else return "vmov.<V_sz_elem>\t%P0[%c2], %1"; } - [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")]) + [(set_attr "type" "neon_vld1_vld2_lane,neon_mcr")]) (define_insn "vec_set<mode>_internal" [(set (match_operand:VQ 0 "s_register_operand" "=w,w") @@ -333,7 +332,7 @@ else return "vmov.<V_sz_elem>\t%P0[%c2], %1"; } - [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")] + [(set_attr "type" "neon_vld1_vld2_lane,neon_mcr")] ) (define_insn "vec_setv2di_internal" @@ -355,7 +354,7 @@ else return "vmov\t%P0, %Q1, %R1"; } - [(set_attr "neon_type" "neon_vld1_1_2_regs,neon_mcr_2_mcrr")] + [(set_attr "type" "neon_vld1_1_2_regs,neon_mcr_2_mcrr")] ) (define_expand "vec_set<mode>" @@ -389,7 +388,7 @@ else return "vmov.<V_uf_sclr>\t%0, %P1[%c2]"; } - [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_bp_simple")] + [(set_attr "type" "neon_vst1_vst2_lane,neon_bp_simple")] ) (define_insn "vec_extract<mode>" @@ -415,7 +414,7 @@ else return "vmov.<V_uf_sclr>\t%0, %P1[%c2]"; } - [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_bp_simple")] + [(set_attr "type" "neon_vst1_vst2_lane,neon_bp_simple")] ) (define_insn "vec_extractv2di" @@ -434,7 +433,7 @@ else return "vmov\t%Q0, %R0, %P1 @ v2di"; } - [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_int_1")] + [(set_attr "type" "neon_vst1_vst2_lane,neon_int_1")] ) (define_expand "vec_init<mode>" @@ -457,7 +456,7 @@ (match_operand:VDQ 2 "s_register_operand" "w")))] "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -484,7 +483,7 @@ default: gcc_unreachable (); } } - [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1,*,*,*") + [(set_attr "type" "neon_int_1,*,*,neon_int_1,*,*,*") (set_attr "conds" "*,clob,clob,*,clob,clob,clob") (set_attr "length" "*,8,8,*,8,8,8") (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits,*,*,*")] @@ -496,7 +495,7 @@ (match_operand:VDQ 2 "s_register_operand" "w")))] "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -521,7 +520,7 @@ default: gcc_unreachable (); } } - [(set_attr "neon_type" "neon_int_2,*,*,*,neon_int_2") + [(set_attr "type" "neon_int_2,*,*,*,neon_int_2") (set_attr "conds" "*,clob,clob,clob,*") (set_attr "length" "*,8,8,8,*") (set_attr "arch" "neon_for_64bits,*,*,*,avoid_neon_for_64bits")] @@ -533,7 +532,7 @@ (match_operand:VDQ 2 "s_register_operand" "w")))] "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" "vmul.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -555,7 +554,7 @@ (match_operand:VDQ 1 "s_register_operand" "0")))] "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vmla_ddd") @@ -577,7 +576,7 @@ (match_operand:VDQ 3 "s_register_operand" "w"))))] "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vmla_ddd") @@ -604,7 +603,7 @@ (match_operand:VCVTF 3 "register_operand" "0")))] "TARGET_NEON && TARGET_FMA && flag_unsafe_math_optimizations" "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vmla_ddd") (const_string "neon_fp_vmla_qqq")))] @@ -617,7 +616,7 @@ (match_operand:VCVTF 3 "register_operand" "0")))] "TARGET_NEON && TARGET_FMA" "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vmla_ddd") (const_string "neon_fp_vmla_qqq")))] @@ -630,7 +629,7 @@ (match_operand:VCVTF 3 "register_operand" "0")))] "TARGET_NEON && TARGET_FMA && flag_unsafe_math_optimizations" "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vmla_ddd") (const_string "neon_fp_vmla_qqq")))] @@ -643,7 +642,7 @@ (match_operand:VCVTF 3 "register_operand" "0")))] "TARGET_NEON && TARGET_FMA" "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vmla_ddd") (const_string "neon_fp_vmla_qqq")))] @@ -656,7 +655,7 @@ NEON_VRINT))] "TARGET_NEON && TARGET_FPU_ARMV8" "vrint<nvrint_variant>%?.f32\\t%<V_reg>0, %<V_reg>1" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_fp_vadd_qqq_vabs_qq")))] @@ -676,7 +675,7 @@ default: gcc_unreachable (); } } - [(set_attr "neon_type" "neon_int_1")] + [(set_attr "type" "neon_int_1")] ) ;; The concrete forms of the Neon immediate-logic instructions are vbic and @@ -698,7 +697,7 @@ default: gcc_unreachable (); } } - [(set_attr "neon_type" "neon_int_1")] + [(set_attr "type" "neon_int_1")] ) (define_insn "orn<mode>3_neon" @@ -707,7 +706,7 @@ (match_operand:VDQ 1 "s_register_operand" "w")))] "TARGET_NEON" "vorn\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set_attr "neon_type" "neon_int_1")] + [(set_attr "type" "neon_int_1")] ) ;; TODO: investigate whether we should disable @@ -745,7 +744,7 @@ DONE; } }" - [(set_attr "neon_type" "neon_int_1,*,*,*") + [(set_attr "type" "neon_int_1,*,*,*") (set_attr "length" "*,16,8,8") (set_attr "arch" "any,a,t2,t2")] ) @@ -756,7 +755,7 @@ (match_operand:VDQ 1 "s_register_operand" "w")))] "TARGET_NEON" "vbic\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set_attr "neon_type" "neon_int_1")] + [(set_attr "type" "neon_int_1")] ) ;; Compare to *anddi_notdi_di. @@ -769,7 +768,7 @@ vbic\t%P0, %P1, %P2 # #" - [(set_attr "neon_type" "neon_int_1,*,*") + [(set_attr "type" "neon_int_1,*,*") (set_attr "length" "*,8,8")] ) @@ -779,7 +778,7 @@ (match_operand:VDQ 2 "s_register_operand" "w")))] "TARGET_NEON" "veor\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set_attr "neon_type" "neon_int_1")] + [(set_attr "type" "neon_int_1")] ) (define_insn "one_cmpl<mode>2" @@ -787,7 +786,7 @@ (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))] "TARGET_NEON" "vmvn\t%<V_reg>0, %<V_reg>1" - [(set_attr "neon_type" "neon_int_1")] + [(set_attr "type" "neon_int_1")] ) (define_insn "abs<mode>2" @@ -795,7 +794,7 @@ (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))] "TARGET_NEON" "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -808,7 +807,7 @@ (neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))] "TARGET_NEON" "vneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -861,7 +860,7 @@ (match_operand:VDQIW 2 "s_register_operand" "w")))] "TARGET_NEON" "vmin.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set_attr "neon_type" "neon_int_5")] + [(set_attr "type" "neon_int_5")] ) (define_insn "*umax<mode>3_neon" @@ -870,7 +869,7 @@ (match_operand:VDQIW 2 "s_register_operand" "w")))] "TARGET_NEON" "vmax.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set_attr "neon_type" "neon_int_5")] + [(set_attr "type" "neon_int_5")] ) (define_insn "*smin<mode>3_neon" @@ -879,7 +878,7 @@ (match_operand:VDQW 2 "s_register_operand" "w")))] "TARGET_NEON" "vmin.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_int_5")))] @@ -891,7 +890,7 @@ (match_operand:VDQW 2 "s_register_operand" "w")))] "TARGET_NEON" "vmax.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_int_5")))] @@ -917,7 +916,7 @@ default: gcc_unreachable (); } } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_vshl_ddd") (const_string "neon_shift_3")))] @@ -933,7 +932,7 @@ <MODE>mode, VALID_NEON_QREG_MODE (<MODE>mode), false); } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_vshl_ddd") (const_string "neon_shift_3")))] @@ -949,7 +948,7 @@ <MODE>mode, VALID_NEON_QREG_MODE (<MODE>mode), false); } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_vshl_ddd") (const_string "neon_shift_3")))] @@ -967,7 +966,7 @@ UNSPEC_ASHIFT_SIGNED))] "TARGET_NEON" "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_vshl_ddd") (const_string "neon_shift_3")))] @@ -983,7 +982,7 @@ UNSPEC_ASHIFT_UNSIGNED))] "TARGET_NEON" "vshl.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_vshl_ddd") (const_string "neon_shift_3")))] @@ -1038,7 +1037,7 @@ "@ vld1.32\t{%P0[0]}, %A1 vmov.32\t%P0[0], %1" - [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")] + [(set_attr "type" "neon_vld1_vld2_lane,neon_mcr")] ) (define_insn "ashldi3_neon_noclobber" @@ -1051,7 +1050,7 @@ "@ vshl.u64\t%P0, %P1, %2 vshl.u64\t%P0, %P1, %P2" - [(set_attr "neon_type" "neon_vshl_ddd,neon_vshl_ddd")] + [(set_attr "type" "neon_vshl_ddd,neon_vshl_ddd")] ) (define_insn_and_split "ashldi3_neon" @@ -1113,7 +1112,7 @@ UNSPEC_ASHIFT_SIGNED))] "TARGET_NEON && reload_completed" "vshl.s64\t%P0, %P1, %P2" - [(set_attr "neon_type" "neon_vshl_ddd")] + [(set_attr "type" "neon_vshl_ddd")] ) ; The shift amount needs to be negated for right-shifts @@ -1124,7 +1123,7 @@ UNSPEC_ASHIFT_UNSIGNED))] "TARGET_NEON && reload_completed" "vshl.u64\t%P0, %P1, %P2" - [(set_attr "neon_type" "neon_vshl_ddd")] + [(set_attr "type" "neon_vshl_ddd")] ) (define_insn "ashrdi3_neon_imm_noclobber" @@ -1134,7 +1133,7 @@ "TARGET_NEON && reload_completed && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 64" "vshr.s64\t%P0, %P1, %2" - [(set_attr "neon_type" "neon_vshl_ddd")] + [(set_attr "type" "neon_vshl_ddd")] ) (define_insn "lshrdi3_neon_imm_noclobber" @@ -1144,7 +1143,7 @@ "TARGET_NEON && reload_completed && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 64" "vshr.u64\t%P0, %P1, %2" - [(set_attr "neon_type" "neon_vshl_ddd")] + [(set_attr "type" "neon_vshl_ddd")] ) ;; ashrdi3_neon @@ -1215,7 +1214,7 @@ (match_operand:<V_widen> 2 "s_register_operand" "w")))] "TARGET_NEON" "vaddw.<V_s_elem>\t%q0, %q2, %P1" - [(set_attr "neon_type" "neon_int_3")] + [(set_attr "type" "neon_int_3")] ) (define_insn "widen_usum<mode>3" @@ -1225,7 +1224,7 @@ (match_operand:<V_widen> 2 "s_register_operand" "w")))] "TARGET_NEON" "vaddw.<V_u_elem>\t%q0, %q2, %P1" - [(set_attr "neon_type" "neon_int_3")] + [(set_attr "type" "neon_int_3")] ) ;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit @@ -1309,7 +1308,7 @@ "TARGET_NEON" "<VQH_mnem>.<VQH_sign>32\t%P0, %e1, %f1" [(set_attr "vqh_mnem" "<VQH_mnem>") - (set (attr "neon_type") + (set (attr "type") (if_then_else (eq_attr "vqh_mnem" "vadd") (const_string "neon_int_1") (const_string "neon_int_5")))] ) @@ -1324,7 +1323,7 @@ "TARGET_NEON && flag_unsafe_math_optimizations" "<VQH_mnem>.f32\t%P0, %e1, %f1" [(set_attr "vqh_mnem" "<VQH_mnem>") - (set (attr "neon_type") + (set (attr "type") (if_then_else (eq_attr "vqh_mnem" "vadd") (const_string "neon_int_1") (const_string "neon_int_5")))] ) @@ -1341,7 +1340,7 @@ "TARGET_NEON" "<VQH_mnem>.<VQH_sign>16\t%P0, %e1, %f1" [(set_attr "vqh_mnem" "<VQH_mnem>") - (set (attr "neon_type") + (set (attr "type") (if_then_else (eq_attr "vqh_mnem" "vadd") (const_string "neon_int_1") (const_string "neon_int_5")))] ) @@ -1362,7 +1361,7 @@ "TARGET_NEON" "<VQH_mnem>.<VQH_sign>8\t%P0, %e1, %f1" [(set_attr "vqh_mnem" "<VQH_mnem>") - (set (attr "neon_type") + (set (attr "type") (if_then_else (eq_attr "vqh_mnem" "vadd") (const_string "neon_int_1") (const_string "neon_int_5")))] ) @@ -1423,7 +1422,7 @@ UNSPEC_VPADD))] "TARGET_NEON && !BYTES_BIG_ENDIAN" "vadd.i64\t%e0, %e1, %f1" - [(set_attr "neon_type" "neon_int_1")] + [(set_attr "type" "neon_int_1")] ) ;; NEON does not distinguish between signed and unsigned addition except on @@ -1547,7 +1546,7 @@ "TARGET_NEON" "vpadd.<V_if_elem>\t%P0, %P1, %P2" ;; Assume this schedules like vadd. - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -1563,7 +1562,7 @@ "TARGET_NEON" "vpmin.<V_s_elem>\t%P0, %P1, %P2" ;; Assume this schedules like vmin. - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_int_5")))] @@ -1577,7 +1576,7 @@ "TARGET_NEON" "vpmax.<V_s_elem>\t%P0, %P1, %P2" ;; Assume this schedules like vmax. - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_int_5")))] @@ -1591,7 +1590,7 @@ "TARGET_NEON" "vpmin.<V_u_elem>\t%P0, %P1, %P2" ;; Assume this schedules like umin. - [(set_attr "neon_type" "neon_int_5")] + [(set_attr "type" "neon_int_5")] ) (define_insn "neon_vpumax<mode>" @@ -1602,7 +1601,7 @@ "TARGET_NEON" "vpmax.<V_u_elem>\t%P0, %P1, %P2" ;; Assume this schedules like umax. - [(set_attr "neon_type" "neon_int_5")] + [(set_attr "type" "neon_int_5")] ) ;; Saturating arithmetic @@ -1619,7 +1618,7 @@ (match_operand:VD 2 "s_register_operand" "w")))] "TARGET_NEON" "vqadd.<V_s_elem>\t%P0, %P1, %P2" - [(set_attr "neon_type" "neon_int_4")] + [(set_attr "type" "neon_int_4")] ) (define_insn "*us_add<mode>_neon" @@ -1628,7 +1627,7 @@ (match_operand:VD 2 "s_register_operand" "w")))] "TARGET_NEON" "vqadd.<V_u_elem>\t%P0, %P1, %P2" - [(set_attr "neon_type" "neon_int_4")] + [(set_attr "type" "neon_int_4")] ) (define_insn "*ss_sub<mode>_neon" @@ -1637,7 +1636,7 @@ (match_operand:VD 2 "s_register_operand" "w")))] "TARGET_NEON" "vqsub.<V_s_elem>\t%P0, %P1, %P2" - [(set_attr "neon_type" "neon_int_5")] + [(set_attr "type" "neon_int_5")] ) (define_insn "*us_sub<mode>_neon" @@ -1646,7 +1645,7 @@ (match_operand:VD 2 "s_register_operand" "w")))] "TARGET_NEON" "vqsub.<V_u_elem>\t%P0, %P1, %P2" - [(set_attr "neon_type" "neon_int_5")] + [(set_attr "type" "neon_int_5")] ) ;; Conditional instructions. These are comparisons with conditional moves for @@ -1938,7 +1937,7 @@ UNSPEC_VADD))] "TARGET_NEON" "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -1958,7 +1957,7 @@ UNSPEC_VADDL))] "TARGET_NEON" "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2" - [(set_attr "neon_type" "neon_int_3")] + [(set_attr "type" "neon_int_3")] ) (define_insn "neon_vaddw<mode>" @@ -1969,7 +1968,7 @@ UNSPEC_VADDW))] "TARGET_NEON" "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2" - [(set_attr "neon_type" "neon_int_2")] + [(set_attr "type" "neon_int_2")] ) ; vhadd and vrhadd. @@ -1982,7 +1981,7 @@ UNSPEC_VHADD))] "TARGET_NEON" "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set_attr "neon_type" "neon_int_4")] + [(set_attr "type" "neon_int_4")] ) (define_insn "neon_vqadd<mode>" @@ -1993,7 +1992,7 @@ UNSPEC_VQADD))] "TARGET_NEON" "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set_attr "neon_type" "neon_int_4")] + [(set_attr "type" "neon_int_4")] ) (define_insn "neon_vaddhn<mode>" @@ -2004,7 +2003,7 @@ UNSPEC_VADDHN))] "TARGET_NEON" "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2" - [(set_attr "neon_type" "neon_int_4")] + [(set_attr "type" "neon_int_4")] ) ;; We cannot replace this unspec with mul<mode>3 because of the odd @@ -2017,7 +2016,7 @@ UNSPEC_VMUL))] "TARGET_NEON" "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -2085,7 +2084,7 @@ UNSPEC_VMLA))] "TARGET_NEON" "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vmla_ddd") @@ -2109,7 +2108,7 @@ UNSPEC_VMLAL))] "TARGET_NEON" "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long") (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))] @@ -2142,7 +2141,7 @@ UNSPEC_VMLS))] "TARGET_NEON" "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vmla_ddd") @@ -2167,7 +2166,7 @@ UNSPEC_VMLSL))] "TARGET_NEON" "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long") (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))] @@ -2181,7 +2180,7 @@ UNSPEC_VQDMULH))] "TARGET_NEON" "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long") @@ -2200,7 +2199,7 @@ UNSPEC_VQDMLAL))] "TARGET_NEON" "vqdmlal.<V_s_elem>\t%q0, %P2, %P3" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long") (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))] @@ -2215,7 +2214,7 @@ UNSPEC_VQDMLSL))] "TARGET_NEON" "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long") (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))] @@ -2229,7 +2228,7 @@ UNSPEC_VMULL))] "TARGET_NEON" "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long") (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))] @@ -2243,7 +2242,7 @@ UNSPEC_VQDMULL))] "TARGET_NEON" "vqdmull.<V_s_elem>\t%q0, %P1, %P2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long") (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))] @@ -2273,7 +2272,7 @@ UNSPEC_VSUB))] "TARGET_NEON" "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -2289,7 +2288,7 @@ UNSPEC_VSUBL))] "TARGET_NEON" "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2" - [(set_attr "neon_type" "neon_int_2")] + [(set_attr "type" "neon_int_2")] ) (define_insn "neon_vsubw<mode>" @@ -2300,7 +2299,7 @@ UNSPEC_VSUBW))] "TARGET_NEON" "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2" - [(set_attr "neon_type" "neon_int_2")] + [(set_attr "type" "neon_int_2")] ) (define_insn "neon_vqsub<mode>" @@ -2311,7 +2310,7 @@ UNSPEC_VQSUB))] "TARGET_NEON" "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set_attr "neon_type" "neon_int_5")] + [(set_attr "type" "neon_int_5")] ) (define_insn "neon_vhsub<mode>" @@ -2322,7 +2321,7 @@ UNSPEC_VHSUB))] "TARGET_NEON" "vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set_attr "neon_type" "neon_int_5")] + [(set_attr "type" "neon_int_5")] ) (define_insn "neon_vsubhn<mode>" @@ -2333,7 +2332,7 @@ UNSPEC_VSUBHN))] "TARGET_NEON" "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2" - [(set_attr "neon_type" "neon_int_4")] + [(set_attr "type" "neon_int_4")] ) (define_insn "neon_vceq<mode>" @@ -2347,7 +2346,7 @@ "@ vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, #0" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -2366,7 +2365,7 @@ "@ vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -2383,7 +2382,7 @@ UNSPEC_VCGEU))] "TARGET_NEON" "vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set_attr "neon_type" "neon_int_5")] + [(set_attr "type" "neon_int_5")] ) (define_insn "neon_vcgt<mode>" @@ -2397,7 +2396,7 @@ "@ vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -2414,7 +2413,7 @@ UNSPEC_VCGTU))] "TARGET_NEON" "vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set_attr "neon_type" "neon_int_5")] + [(set_attr "type" "neon_int_5")] ) ;; VCLE and VCLT only support comparisons with immediate zero (register @@ -2429,7 +2428,7 @@ UNSPEC_VCLE))] "TARGET_NEON" "vcle.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -2446,7 +2445,7 @@ UNSPEC_VCLT))] "TARGET_NEON" "vclt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -2462,7 +2461,7 @@ UNSPEC_VCAGE))] "TARGET_NEON" "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_fp_vadd_qqq_vabs_qq")))] @@ -2476,7 +2475,7 @@ UNSPEC_VCAGT))] "TARGET_NEON" "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_fp_vadd_qqq_vabs_qq")))] @@ -2490,7 +2489,7 @@ UNSPEC_VTST))] "TARGET_NEON" "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set_attr "neon_type" "neon_int_4")] + [(set_attr "type" "neon_int_4")] ) (define_insn "neon_vabd<mode>" @@ -2501,7 +2500,7 @@ UNSPEC_VABD))] "TARGET_NEON" "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -2517,7 +2516,7 @@ UNSPEC_VABDL))] "TARGET_NEON" "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2" - [(set_attr "neon_type" "neon_int_5")] + [(set_attr "type" "neon_int_5")] ) (define_insn "neon_vaba<mode>" @@ -2529,7 +2528,7 @@ (match_operand:VDQIW 1 "s_register_operand" "0")))] "TARGET_NEON" "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_vaba") (const_string "neon_vaba_qqq")))] ) @@ -2543,7 +2542,7 @@ (match_operand:<V_widen> 1 "s_register_operand" "0")))] "TARGET_NEON" "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3" - [(set_attr "neon_type" "neon_vaba")] + [(set_attr "type" "neon_vaba")] ) (define_insn "neon_vmax<mode>" @@ -2554,7 +2553,7 @@ UNSPEC_VMAX))] "TARGET_NEON" "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -2570,7 +2569,7 @@ UNSPEC_VMIN))] "TARGET_NEON" "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -2598,7 +2597,7 @@ "TARGET_NEON" "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1" ;; Assume this schedules like vaddl. - [(set_attr "neon_type" "neon_int_3")] + [(set_attr "type" "neon_int_3")] ) (define_insn "neon_vpadal<mode>" @@ -2610,7 +2609,7 @@ "TARGET_NEON" "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2" ;; Assume this schedules like vpadd. - [(set_attr "neon_type" "neon_int_1")] + [(set_attr "type" "neon_int_1")] ) (define_insn "neon_vpmax<mode>" @@ -2622,7 +2621,7 @@ "TARGET_NEON" "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" ;; Assume this schedules like vmax. - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_int_5")))] @@ -2637,7 +2636,7 @@ "TARGET_NEON" "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" ;; Assume this schedules like vmin. - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_int_5")))] @@ -2651,7 +2650,7 @@ UNSPEC_VRECPS))] "TARGET_NEON" "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vrecps_vrsqrts_ddd") (const_string "neon_fp_vrecps_vrsqrts_qqq")))] @@ -2665,7 +2664,7 @@ UNSPEC_VRSQRTS))] "TARGET_NEON" "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vrecps_vrsqrts_ddd") (const_string "neon_fp_vrecps_vrsqrts_qqq")))] @@ -2688,7 +2687,7 @@ UNSPEC_VQABS))] "TARGET_NEON" "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1" - [(set_attr "neon_type" "neon_vqneg_vqabs")] + [(set_attr "type" "neon_vqneg_vqabs")] ) (define_expand "neon_vneg<mode>" @@ -2708,7 +2707,7 @@ UNSPEC_VQNEG))] "TARGET_NEON" "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1" - [(set_attr "neon_type" "neon_vqneg_vqabs")] + [(set_attr "type" "neon_vqneg_vqabs")] ) (define_insn "neon_vcls<mode>" @@ -2718,7 +2717,7 @@ UNSPEC_VCLS))] "TARGET_NEON" "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1" - [(set_attr "neon_type" "neon_int_1")] + [(set_attr "type" "neon_int_1")] ) (define_insn "clz<mode>2" @@ -2726,7 +2725,7 @@ (clz:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")))] "TARGET_NEON" "vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1" - [(set_attr "neon_type" "neon_int_1")] + [(set_attr "type" "neon_int_1")] ) (define_expand "neon_vclz<mode>" @@ -2744,7 +2743,7 @@ (popcount:VE (match_operand:VE 1 "s_register_operand" "w")))] "TARGET_NEON" "vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1" - [(set_attr "neon_type" "neon_int_1")] + [(set_attr "type" "neon_int_1")] ) (define_expand "neon_vcnt<mode>" @@ -2764,7 +2763,7 @@ UNSPEC_VRECPE))] "TARGET_NEON" "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_fp_vadd_qqq_vabs_qq")))] @@ -2777,7 +2776,7 @@ UNSPEC_VRSQRTE))] "TARGET_NEON" "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_fp_vadd_qqq_vabs_qq")))] @@ -2809,7 +2808,7 @@ } return "vmov.s<V_sz_elem>\t%0, %P1[%c2]"; } - [(set_attr "neon_type" "neon_bp_simple")] + [(set_attr "type" "neon_bp_simple")] ) (define_insn "neon_vget_lane<mode>_zext_internal" @@ -2828,7 +2827,7 @@ } return "vmov.u<V_sz_elem>\t%0, %P1[%c2]"; } - [(set_attr "neon_type" "neon_bp_simple")] + [(set_attr "type" "neon_bp_simple")] ) (define_insn "neon_vget_lane<mode>_sext_internal" @@ -2855,7 +2854,7 @@ return ""; } - [(set_attr "neon_type" "neon_bp_simple")] + [(set_attr "type" "neon_bp_simple")] ) (define_insn "neon_vget_lane<mode>_zext_internal" @@ -2882,7 +2881,7 @@ return ""; } - [(set_attr "neon_type" "neon_bp_simple")] + [(set_attr "type" "neon_bp_simple")] ) (define_expand "neon_vget_lane<mode>" @@ -3015,7 +3014,7 @@ "TARGET_NEON" "vdup.<V_sz_elem>\t%<V_reg>0, %1" ;; Assume this schedules like vmov. - [(set_attr "neon_type" "neon_bp_simple")] + [(set_attr "type" "neon_bp_simple")] ) (define_insn "neon_vdup_n<mode>" @@ -3026,7 +3025,7 @@ vdup.<V_sz_elem>\t%<V_reg>0, %1 vdup.<V_sz_elem>\t%<V_reg>0, %y1" ;; Assume this schedules like vmov. - [(set_attr "neon_type" "neon_bp_simple")] + [(set_attr "type" "neon_bp_simple")] ) (define_expand "neon_vdup_ndi" @@ -3047,7 +3046,7 @@ vmov\t%e0, %Q1, %R1\;vmov\t%f0, %Q1, %R1 vmov\t%e0, %P1\;vmov\t%f0, %P1" [(set_attr "length" "8") - (set_attr "neon_type" "neon_bp_simple")] + (set_attr "type" "neon_bp_simple")] ) (define_insn "neon_vdup_lane<mode>_internal" @@ -3070,7 +3069,7 @@ return "vdup.<V_sz_elem>\t%q0, %P1[%c2]"; } ;; Assume this schedules like vmov. - [(set_attr "neon_type" "neon_bp_simple")] + [(set_attr "type" "neon_bp_simple")] ) (define_expand "neon_vdup_lane<mode>" @@ -3125,7 +3124,7 @@ (set (match_dup 1) (match_dup 0))] "TARGET_NEON && reload_completed" "vswp\t%<V_reg>0, %<V_reg>1" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_bp_simple") (const_string "neon_bp_2cycle")))] @@ -3179,7 +3178,7 @@ (float:<V_CVTTO> (match_operand:VCVTI 1 "s_register_operand" "w")))] "TARGET_NEON && !flag_rounding_math" "vcvt.f32.s32\t%<V_reg>0, %<V_reg>1" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_fp_vadd_qqq_vabs_qq")))] @@ -3190,7 +3189,7 @@ (unsigned_float:<V_CVTTO> (match_operand:VCVTI 1 "s_register_operand" "w")))] "TARGET_NEON && !flag_rounding_math" "vcvt.f32.u32\t%<V_reg>0, %<V_reg>1" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_fp_vadd_qqq_vabs_qq")))] @@ -3201,7 +3200,7 @@ (fix:<V_CVTTO> (match_operand:VCVTF 1 "s_register_operand" "w")))] "TARGET_NEON" "vcvt.s32.f32\t%<V_reg>0, %<V_reg>1" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_fp_vadd_qqq_vabs_qq")))] @@ -3212,7 +3211,7 @@ (unsigned_fix:<V_CVTTO> (match_operand:VCVTF 1 "s_register_operand" "w")))] "TARGET_NEON" "vcvt.u32.f32\t%<V_reg>0, %<V_reg>1" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_fp_vadd_qqq_vabs_qq")))] @@ -3225,7 +3224,7 @@ UNSPEC_VCVT))] "TARGET_NEON" "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_fp_vadd_qqq_vabs_qq")))] @@ -3238,7 +3237,7 @@ UNSPEC_VCVT))] "TARGET_NEON" "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_fp_vadd_qqq_vabs_qq")))] @@ -3250,7 +3249,7 @@ UNSPEC_VCVT))] "TARGET_NEON && TARGET_FP16" "vcvt.f32.f16\t%q0, %P1" - [(set_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd")] + [(set_attr "type" "neon_fp_vadd_ddd_vabs_dd")] ) (define_insn "neon_vcvtv4hfv4sf" @@ -3259,7 +3258,7 @@ UNSPEC_VCVT))] "TARGET_NEON && TARGET_FP16" "vcvt.f16.f32\t%P0, %q1" - [(set_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd")] + [(set_attr "type" "neon_fp_vadd_ddd_vabs_dd")] ) (define_insn "neon_vcvt_n<mode>" @@ -3273,7 +3272,7 @@ neon_const_bounds (operands[2], 1, 33); return "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_fp_vadd_qqq_vabs_qq")))] @@ -3290,7 +3289,7 @@ neon_const_bounds (operands[2], 1, 33); return "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_fp_vadd_ddd_vabs_dd") (const_string "neon_fp_vadd_qqq_vabs_qq")))] @@ -3303,7 +3302,7 @@ UNSPEC_VMOVN))] "TARGET_NEON" "vmovn.<V_if_elem>\t%P0, %q1" - [(set_attr "neon_type" "neon_bp_simple")] + [(set_attr "type" "neon_bp_simple")] ) (define_insn "neon_vqmovn<mode>" @@ -3313,7 +3312,7 @@ UNSPEC_VQMOVN))] "TARGET_NEON" "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1" - [(set_attr "neon_type" "neon_shift_2")] + [(set_attr "type" "neon_shift_2")] ) (define_insn "neon_vqmovun<mode>" @@ -3323,7 +3322,7 @@ UNSPEC_VQMOVUN))] "TARGET_NEON" "vqmovun.<V_s_elem>\t%P0, %q1" - [(set_attr "neon_type" "neon_shift_2")] + [(set_attr "type" "neon_shift_2")] ) (define_insn "neon_vmovl<mode>" @@ -3333,7 +3332,7 @@ UNSPEC_VMOVL))] "TARGET_NEON" "vmovl.%T2%#<V_sz_elem>\t%q0, %P1" - [(set_attr "neon_type" "neon_shift_1")] + [(set_attr "type" "neon_shift_1")] ) (define_insn "neon_vmul_lane<mode>" @@ -3349,7 +3348,7 @@ neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode)); return "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_vmul_ddd") (if_then_else (match_test "<Scalar_mul_8_16>") @@ -3370,7 +3369,7 @@ neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<V_HALF>mode)); return "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_vmul_qqd") (if_then_else (match_test "<Scalar_mul_8_16>") @@ -3391,7 +3390,7 @@ neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode)); return "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar") (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))] @@ -3410,7 +3409,7 @@ neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode)); return "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar") (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))] @@ -3429,7 +3428,7 @@ neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode)); return "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar") (const_string "neon_mul_qqd_32_scalar")))] @@ -3448,7 +3447,7 @@ neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode)); return "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar") (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))] @@ -3468,7 +3467,7 @@ neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode)); return "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_vmla_ddd_scalar") (if_then_else (match_test "<Scalar_mul_8_16>") @@ -3490,7 +3489,7 @@ neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode)); return "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_vmla_qqq_scalar") (if_then_else (match_test "<Scalar_mul_8_16>") @@ -3512,7 +3511,7 @@ neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode)); return "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar") (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))] @@ -3532,7 +3531,7 @@ neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode)); return "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar") (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))] @@ -3552,7 +3551,7 @@ neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode)); return "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_vmla_ddd_scalar") (if_then_else (match_test "<Scalar_mul_8_16>") @@ -3574,7 +3573,7 @@ neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode)); return "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_float_mode>") (const_string "neon_fp_vmla_qqq_scalar") (if_then_else (match_test "<Scalar_mul_8_16>") @@ -3596,7 +3595,7 @@ neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode)); return "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar") (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))] @@ -3616,7 +3615,7 @@ neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode)); return "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Scalar_mul_8_16>") (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar") (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))] @@ -3844,7 +3843,7 @@ neon_const_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode)); return "vext.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2, %3"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_bp_simple") (const_string "neon_bp_2cycle")))] @@ -3857,7 +3856,7 @@ UNSPEC_VREV64))] "TARGET_NEON" "vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1" - [(set_attr "neon_type" "neon_bp_simple")] + [(set_attr "type" "neon_bp_simple")] ) (define_insn "neon_vrev32<mode>" @@ -3867,7 +3866,7 @@ UNSPEC_VREV32))] "TARGET_NEON" "vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1" - [(set_attr "neon_type" "neon_bp_simple")] + [(set_attr "type" "neon_bp_simple")] ) (define_insn "neon_vrev16<mode>" @@ -3877,7 +3876,7 @@ UNSPEC_VREV16))] "TARGET_NEON" "vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1" - [(set_attr "neon_type" "neon_bp_simple")] + [(set_attr "type" "neon_bp_simple")] ) ; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register @@ -3899,7 +3898,7 @@ vbsl\t%<V_reg>0, %<V_reg>2, %<V_reg>3 vbit\t%<V_reg>0, %<V_reg>2, %<V_reg>1 vbif\t%<V_reg>0, %<V_reg>3, %<V_reg>1" - [(set_attr "neon_type" "neon_int_1")] + [(set_attr "type" "neon_int_1")] ) (define_expand "neon_vbsl<mode>" @@ -3922,7 +3921,7 @@ UNSPEC_VSHL))] "TARGET_NEON" "v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_vshl_ddd") (const_string "neon_shift_3")))] @@ -3936,7 +3935,7 @@ UNSPEC_VQSHL))] "TARGET_NEON" "vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_shift_2") (const_string "neon_vqshl_vrshl_vqrshl_qqq")))] @@ -3953,7 +3952,7 @@ neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) + 1); return "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2"; } - [(set_attr "neon_type" "neon_shift_1")] + [(set_attr "type" "neon_shift_1")] ) (define_insn "neon_vshrn_n<mode>" @@ -3967,7 +3966,7 @@ neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1); return "v%O3shrn.<V_if_elem>\t%P0, %q1, %2"; } - [(set_attr "neon_type" "neon_shift_1")] + [(set_attr "type" "neon_shift_1")] ) (define_insn "neon_vqshrn_n<mode>" @@ -3981,7 +3980,7 @@ neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1); return "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2"; } - [(set_attr "neon_type" "neon_shift_2")] + [(set_attr "type" "neon_shift_2")] ) (define_insn "neon_vqshrun_n<mode>" @@ -3995,7 +3994,7 @@ neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1); return "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2"; } - [(set_attr "neon_type" "neon_shift_2")] + [(set_attr "type" "neon_shift_2")] ) (define_insn "neon_vshl_n<mode>" @@ -4009,7 +4008,7 @@ neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode)); return "vshl.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %2"; } - [(set_attr "neon_type" "neon_shift_1")] + [(set_attr "type" "neon_shift_1")] ) (define_insn "neon_vqshl_n<mode>" @@ -4023,7 +4022,7 @@ neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode)); return "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2"; } - [(set_attr "neon_type" "neon_shift_2")] + [(set_attr "type" "neon_shift_2")] ) (define_insn "neon_vqshlu_n<mode>" @@ -4037,7 +4036,7 @@ neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode)); return "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2"; } - [(set_attr "neon_type" "neon_shift_2")] + [(set_attr "type" "neon_shift_2")] ) (define_insn "neon_vshll_n<mode>" @@ -4052,7 +4051,7 @@ neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode) + 1); return "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2"; } - [(set_attr "neon_type" "neon_shift_1")] + [(set_attr "type" "neon_shift_1")] ) (define_insn "neon_vsra_n<mode>" @@ -4067,7 +4066,7 @@ neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1); return "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3"; } - [(set_attr "neon_type" "neon_vsra_vrsra")] + [(set_attr "type" "neon_vsra_vrsra")] ) (define_insn "neon_vsri_n<mode>" @@ -4081,7 +4080,7 @@ neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1); return "vsri.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_shift_1") (const_string "neon_shift_3")))] @@ -4098,7 +4097,7 @@ neon_const_bounds (operands[3], 0, neon_element_bits (<MODE>mode)); return "vsli.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_shift_1") (const_string "neon_shift_3")))] @@ -4111,7 +4110,7 @@ UNSPEC_VTBL))] "TARGET_NEON" "vtbl.8\t%P0, {%P1}, %P2" - [(set_attr "neon_type" "neon_bp_2cycle")] + [(set_attr "type" "neon_bp_2cycle")] ) (define_insn "neon_vtbl2v8qi" @@ -4132,7 +4131,7 @@ return ""; } - [(set_attr "neon_type" "neon_bp_2cycle")] + [(set_attr "type" "neon_bp_2cycle")] ) (define_insn "neon_vtbl3v8qi" @@ -4154,7 +4153,7 @@ return ""; } - [(set_attr "neon_type" "neon_bp_3cycle")] + [(set_attr "type" "neon_bp_3cycle")] ) (define_insn "neon_vtbl4v8qi" @@ -4177,7 +4176,7 @@ return ""; } - [(set_attr "neon_type" "neon_bp_3cycle")] + [(set_attr "type" "neon_bp_3cycle")] ) ;; These three are used by the vec_perm infrastructure for V16QImode. @@ -4265,7 +4264,7 @@ UNSPEC_VTBX))] "TARGET_NEON" "vtbx.8\t%P0, {%P2}, %P3" - [(set_attr "neon_type" "neon_bp_2cycle")] + [(set_attr "type" "neon_bp_2cycle")] ) (define_insn "neon_vtbx2v8qi" @@ -4287,7 +4286,7 @@ return ""; } - [(set_attr "neon_type" "neon_bp_2cycle")] + [(set_attr "type" "neon_bp_2cycle")] ) (define_insn "neon_vtbx3v8qi" @@ -4310,7 +4309,7 @@ return ""; } - [(set_attr "neon_type" "neon_bp_3cycle")] + [(set_attr "type" "neon_bp_3cycle")] ) (define_insn "neon_vtbx4v8qi" @@ -4334,7 +4333,7 @@ return ""; } - [(set_attr "neon_type" "neon_bp_3cycle")] + [(set_attr "type" "neon_bp_3cycle")] ) (define_expand "neon_vtrn<mode>_internal" @@ -4360,7 +4359,7 @@ UNSPEC_VTRN2))] "TARGET_NEON" "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_bp_simple") (const_string "neon_bp_3cycle")))] @@ -4400,7 +4399,7 @@ UNSPEC_VZIP2))] "TARGET_NEON" "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_bp_simple") (const_string "neon_bp_3cycle")))] @@ -4440,7 +4439,7 @@ UNSPEC_VUZP2))] "TARGET_NEON" "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (match_test "<Is_d_reg>") (const_string "neon_bp_simple") (const_string "neon_bp_3cycle")))] @@ -4559,7 +4558,7 @@ UNSPEC_VLD1))] "TARGET_NEON" "vld1.<V_sz_elem>\t%h0, %A1" - [(set_attr "neon_type" "neon_vld1_1_2_regs")] + [(set_attr "type" "neon_vld1_1_2_regs")] ) (define_insn "neon_vld1_lane<mode>" @@ -4579,7 +4578,7 @@ else return "vld1.<V_sz_elem>\t{%P0[%c3]}, %A1"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2)) (const_string "neon_vld1_1_2_regs") (const_string "neon_vld1_vld2_lane")))] @@ -4610,7 +4609,7 @@ else return "vld1.<V_sz_elem>\t{%P0[%c3]}, %A1"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2)) (const_string "neon_vld1_1_2_regs") (const_string "neon_vld1_vld2_lane")))] @@ -4621,7 +4620,7 @@ (vec_duplicate:VD (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))] "TARGET_NEON" "vld1.<V_sz_elem>\t{%P0[]}, %A1" - [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")] + [(set_attr "type" "neon_vld2_2_regs_vld1_vld2_all_lanes")] ) ;; Special case for DImode. Treat it exactly like a simple load. @@ -4640,7 +4639,7 @@ { return "vld1.<V_sz_elem>\t{%e0[], %f0[]}, %A1"; } - [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")] + [(set_attr "type" "neon_vld2_2_regs_vld1_vld2_all_lanes")] ) (define_insn_and_split "neon_vld1_dupv2di" @@ -4657,7 +4656,7 @@ DONE; } [(set_attr "length" "8") - (set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")] + (set_attr "type" "neon_vld2_2_regs_vld1_vld2_all_lanes")] ) (define_expand "vec_store_lanes<mode><mode>" @@ -4672,7 +4671,7 @@ UNSPEC_VST1))] "TARGET_NEON" "vst1.<V_sz_elem>\t%h1, %A0" - [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]) + [(set_attr "type" "neon_vst1_1_2_regs_vst2_2_regs")]) (define_insn "neon_vst1_lane<mode>" [(set (match_operand:<V_elem> 0 "neon_struct_operand" "=Um") @@ -4691,7 +4690,7 @@ else return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 1)) (const_string "neon_vst1_1_2_regs_vst2_2_regs") (const_string "neon_vst1_vst2_lane")))]) @@ -4721,7 +4720,7 @@ else return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0"; } - [(set_attr "neon_type" "neon_vst1_vst2_lane")] + [(set_attr "type" "neon_vst1_vst2_lane")] ) (define_expand "vec_load_lanesti<mode>" @@ -4743,7 +4742,7 @@ else return "vld2.<V_sz_elem>\t%h0, %A1"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64")) (const_string "neon_vld1_1_2_regs") (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")))] @@ -4763,7 +4762,7 @@ UNSPEC_VLD2))] "TARGET_NEON" "vld2.<V_sz_elem>\t%h0, %A1" - [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]) + [(set_attr "type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]) (define_insn "neon_vld2_lane<mode>" [(set (match_operand:TI 0 "s_register_operand" "=w") @@ -4787,7 +4786,7 @@ output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, %A2", ops); return ""; } - [(set_attr "neon_type" "neon_vld1_vld2_lane")] + [(set_attr "type" "neon_vld1_vld2_lane")] ) (define_insn "neon_vld2_lane<mode>" @@ -4817,7 +4816,7 @@ output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, %A2", ops); return ""; } - [(set_attr "neon_type" "neon_vld1_vld2_lane")] + [(set_attr "type" "neon_vld1_vld2_lane")] ) (define_insn "neon_vld2_dup<mode>" @@ -4832,7 +4831,7 @@ else return "vld1.<V_sz_elem>\t%h0, %A1"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1")) (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes") (const_string "neon_vld1_1_2_regs")))] @@ -4857,7 +4856,7 @@ else return "vst2.<V_sz_elem>\t%h1, %A0"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64")) (const_string "neon_vst1_1_2_regs_vst2_2_regs") (const_string "neon_vst1_1_2_regs_vst2_2_regs")))] @@ -4877,7 +4876,7 @@ UNSPEC_VST2))] "TARGET_NEON" "vst2.<V_sz_elem>\t%h1, %A0" - [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")] + [(set_attr "type" "neon_vst1_1_2_regs_vst2_2_regs")] ) (define_insn "neon_vst2_lane<mode>" @@ -4902,7 +4901,7 @@ output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, %A0", ops); return ""; } - [(set_attr "neon_type" "neon_vst1_vst2_lane")] + [(set_attr "type" "neon_vst1_vst2_lane")] ) (define_insn "neon_vst2_lane<mode>" @@ -4932,7 +4931,7 @@ output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, %A0", ops); return ""; } - [(set_attr "neon_type" "neon_vst1_vst2_lane")] + [(set_attr "type" "neon_vst1_vst2_lane")] ) (define_expand "vec_load_lanesei<mode>" @@ -4954,7 +4953,7 @@ else return "vld3.<V_sz_elem>\t%h0, %A1"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64")) (const_string "neon_vld1_1_2_regs") (const_string "neon_vld3_vld4")))] @@ -5001,7 +5000,7 @@ output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, %A3", ops); return ""; } - [(set_attr "neon_type" "neon_vld3_vld4")] + [(set_attr "type" "neon_vld3_vld4")] ) (define_insn "neon_vld3qb<mode>" @@ -5021,7 +5020,7 @@ output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, %A3", ops); return ""; } - [(set_attr "neon_type" "neon_vld3_vld4")] + [(set_attr "type" "neon_vld3_vld4")] ) (define_insn "neon_vld3_lane<mode>" @@ -5048,7 +5047,7 @@ ops); return ""; } - [(set_attr "neon_type" "neon_vld3_vld4_lane")] + [(set_attr "type" "neon_vld3_vld4_lane")] ) (define_insn "neon_vld3_lane<mode>" @@ -5080,7 +5079,7 @@ ops); return ""; } - [(set_attr "neon_type" "neon_vld3_vld4_lane")] + [(set_attr "type" "neon_vld3_vld4_lane")] ) (define_insn "neon_vld3_dup<mode>" @@ -5104,7 +5103,7 @@ else return "vld1.<V_sz_elem>\t%h0, %A1"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1")) (const_string "neon_vld3_vld4_all_lanes") (const_string "neon_vld1_1_2_regs")))]) @@ -5128,7 +5127,7 @@ else return "vst3.<V_sz_elem>\t%h1, %A0"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64")) (const_string "neon_vst1_1_2_regs_vst2_2_regs") (const_string "neon_vst2_4_regs_vst3_vst4")))]) @@ -5174,7 +5173,7 @@ output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, %A0", ops); return ""; } - [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")] + [(set_attr "type" "neon_vst2_4_regs_vst3_vst4")] ) (define_insn "neon_vst3qb<mode>" @@ -5193,7 +5192,7 @@ output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, %A0", ops); return ""; } - [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")] + [(set_attr "type" "neon_vst2_4_regs_vst3_vst4")] ) (define_insn "neon_vst3_lane<mode>" @@ -5220,7 +5219,7 @@ ops); return ""; } - [(set_attr "neon_type" "neon_vst3_vst4_lane")] + [(set_attr "type" "neon_vst3_vst4_lane")] ) (define_insn "neon_vst3_lane<mode>" @@ -5252,7 +5251,7 @@ ops); return ""; } -[(set_attr "neon_type" "neon_vst3_vst4_lane")]) +[(set_attr "type" "neon_vst3_vst4_lane")]) (define_expand "vec_load_lanesoi<mode>" [(set (match_operand:OI 0 "s_register_operand") @@ -5273,7 +5272,7 @@ else return "vld4.<V_sz_elem>\t%h0, %A1"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64")) (const_string "neon_vld1_1_2_regs") (const_string "neon_vld3_vld4")))] @@ -5321,7 +5320,7 @@ output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, %A4", ops); return ""; } - [(set_attr "neon_type" "neon_vld3_vld4")] + [(set_attr "type" "neon_vld3_vld4")] ) (define_insn "neon_vld4qb<mode>" @@ -5342,7 +5341,7 @@ output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, %A4", ops); return ""; } - [(set_attr "neon_type" "neon_vld3_vld4")] + [(set_attr "type" "neon_vld3_vld4")] ) (define_insn "neon_vld4_lane<mode>" @@ -5370,7 +5369,7 @@ ops); return ""; } - [(set_attr "neon_type" "neon_vld3_vld4_lane")] + [(set_attr "type" "neon_vld3_vld4_lane")] ) (define_insn "neon_vld4_lane<mode>" @@ -5403,7 +5402,7 @@ ops); return ""; } - [(set_attr "neon_type" "neon_vld3_vld4_lane")] + [(set_attr "type" "neon_vld3_vld4_lane")] ) (define_insn "neon_vld4_dup<mode>" @@ -5429,7 +5428,7 @@ else return "vld1.<V_sz_elem>\t%h0, %A1"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1")) (const_string "neon_vld3_vld4_all_lanes") (const_string "neon_vld1_1_2_regs")))] @@ -5454,7 +5453,7 @@ else return "vst4.<V_sz_elem>\t%h1, %A0"; } - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64")) (const_string "neon_vst1_1_2_regs_vst2_2_regs") (const_string "neon_vst2_4_regs_vst3_vst4")))] @@ -5502,7 +5501,7 @@ output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, %A0", ops); return ""; } - [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")] + [(set_attr "type" "neon_vst2_4_regs_vst3_vst4")] ) (define_insn "neon_vst4qb<mode>" @@ -5522,7 +5521,7 @@ output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, %A0", ops); return ""; } - [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")] + [(set_attr "type" "neon_vst2_4_regs_vst3_vst4")] ) (define_insn "neon_vst4_lane<mode>" @@ -5550,7 +5549,7 @@ ops); return ""; } - [(set_attr "neon_type" "neon_vst3_vst4_lane")] + [(set_attr "type" "neon_vst3_vst4_lane")] ) (define_insn "neon_vst4_lane<mode>" @@ -5583,7 +5582,7 @@ ops); return ""; } - [(set_attr "neon_type" "neon_vst3_vst4_lane")] + [(set_attr "type" "neon_vst3_vst4_lane")] ) (define_expand "neon_vand<mode>" @@ -5648,7 +5647,7 @@ (match_operand:VU 2 "vect_par_constant_low" ""))))] "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmovl.<US><V_sz_elem> %q0, %e1" - [(set_attr "neon_type" "neon_shift_1")] + [(set_attr "type" "neon_shift_1")] ) (define_insn "neon_vec_unpack<US>_hi_<mode>" @@ -5658,7 +5657,7 @@ (match_operand:VU 2 "vect_par_constant_high" ""))))] "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmovl.<US><V_sz_elem> %q0, %f1" - [(set_attr "neon_type" "neon_shift_1")] + [(set_attr "type" "neon_shift_1")] ) (define_expand "vec_unpack<US>_hi_<mode>" @@ -5708,7 +5707,7 @@ (match_dup 2)))))] "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmull.<US><V_sz_elem> %q0, %e1, %e3" - [(set_attr "neon_type" "neon_shift_1")] + [(set_attr "type" "neon_shift_1")] ) (define_expand "vec_widen_<US>mult_lo_<mode>" @@ -5742,7 +5741,7 @@ (match_dup 2)))))] "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmull.<US><V_sz_elem> %q0, %f1, %f3" - [(set_attr "neon_type" "neon_shift_1")] + [(set_attr "type" "neon_shift_1")] ) (define_expand "vec_widen_<US>mult_hi_<mode>" @@ -5775,7 +5774,7 @@ { return "vshll.<US><V_sz_elem> %q0, %P1, %2"; } - [(set_attr "neon_type" "neon_shift_1")] + [(set_attr "type" "neon_shift_1")] ) (define_expand "vec_widen_<US>shiftl_lo_<mode>" @@ -5811,7 +5810,7 @@ (SE:<V_widen> (match_operand:VDI 1 "register_operand" "w")))] "TARGET_NEON" "vmovl.<US><V_sz_elem> %q0, %P1" - [(set_attr "neon_type" "neon_shift_1")] + [(set_attr "type" "neon_shift_1")] ) (define_expand "vec_unpack<US>_lo_<mode>" @@ -5848,7 +5847,7 @@ (match_operand:VDI 2 "register_operand" "w"))))] "TARGET_NEON" "vmull.<US><V_sz_elem> %q0, %P1, %P2" - [(set_attr "neon_type" "neon_shift_1")] + [(set_attr "type" "neon_shift_1")] ) (define_expand "vec_widen_<US>mult_hi_<mode>" @@ -5922,7 +5921,7 @@ (match_operand:VN 2 "register_operand" "w"))))] "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmovn.i<V_sz_elem>\t%e0, %q1\;vmovn.i<V_sz_elem>\t%f0, %q2" - [(set_attr "neon_type" "neon_shift_1") + [(set_attr "type" "neon_shift_1") (set_attr "length" "8")] ) @@ -5932,7 +5931,7 @@ (truncate:<V_narrow> (match_operand:VN 1 "register_operand" "w")))] "TARGET_NEON && !BYTES_BIG_ENDIAN" "vmovn.i<V_sz_elem>\t%P0, %q1" - [(set_attr "neon_type" "neon_shift_1")] + [(set_attr "type" "neon_shift_1")] ) (define_expand "vec_pack_trunc_<mode>" @@ -5955,7 +5954,7 @@ (match_operand:VDQ 2 "s_register_operand" "w"))))] "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" "vabd.<V_s_elem> %<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0)) (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0)) (const_string "neon_fp_vadd_ddd_vabs_dd") @@ -5970,7 +5969,7 @@ UNSPEC_VSUB)))] "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)" "vabd.<V_if_elem> %<V_reg>0, %<V_reg>1, %<V_reg>2" - [(set (attr "neon_type") + [(set (attr "type") (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0)) (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0)) (const_string "neon_fp_vadd_ddd_vabs_dd") diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md index 8b184a80c2e..3b5944a014a 100644 --- a/gcc/config/arm/thumb2.md +++ b/gcc/config/arm/thumb2.md @@ -36,7 +36,7 @@ [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") (set_attr "shift" "2") - (set_attr "type" "arlo_shift")] + (set_attr "type" "alu_shift_imm")] ) ;; We use the '0' constraint for operand 1 because reload should @@ -58,7 +58,8 @@ "" [(set_attr "conds" "clob") (set_attr "enabled_for_depr_it" "yes,yes,no") - (set_attr "length" "6,6,10")] + (set_attr "length" "6,6,10") + (set_attr "type" "multiple")] ) (define_insn_and_split "*thumb2_sminsi3" @@ -78,7 +79,8 @@ "" [(set_attr "conds" "clob") (set_attr "enabled_for_depr_it" "yes,yes,no") - (set_attr "length" "6,6,10")] + (set_attr "length" "6,6,10") + (set_attr "type" "multiple")] ) (define_insn_and_split "*thumb32_umaxsi3" @@ -98,7 +100,8 @@ "" [(set_attr "conds" "clob") (set_attr "length" "6,6,10") - (set_attr "enabled_for_depr_it" "yes,yes,no")] + (set_attr "enabled_for_depr_it" "yes,yes,no") + (set_attr "type" "multiple")] ) (define_insn_and_split "*thumb2_uminsi3" @@ -118,7 +121,8 @@ "" [(set_attr "conds" "clob") (set_attr "length" "6,6,10") - (set_attr "enabled_for_depr_it" "yes,yes,no")] + (set_attr "enabled_for_depr_it" "yes,yes,no") + (set_attr "type" "multiple")] ) ;; Thumb-2 does not have rsc, so use a clever trick with shifter operands. @@ -143,7 +147,8 @@ operands[1] = gen_lowpart (SImode, operands[1]); } [(set_attr "conds" "clob") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*thumb2_abssi2" @@ -200,7 +205,8 @@ (set_attr "predicable_short_it" "no") (set_attr "enabled_for_depr_it" "yes,yes,no") (set_attr "ce_count" "2") - (set_attr "length" "8,6,10")] + (set_attr "length" "8,6,10") + (set_attr "type" "multiple")] ) (define_insn_and_split "*thumb2_neg_abssi2" @@ -257,7 +263,8 @@ (set_attr "enabled_for_depr_it" "yes,yes,no") (set_attr "predicable_short_it" "no") (set_attr "ce_count" "2") - (set_attr "length" "8,6,10")] + (set_attr "length" "8,6,10") + (set_attr "type" "multiple")] ) ;; We have two alternatives here for memory loads (and similarly for stores) @@ -282,7 +289,7 @@ ldr%?\\t%0, %1 str%?\\t%1, %0 str%?\\t%1, %0" - [(set_attr "type" "*,arlo_imm,arlo_imm,arlo_imm,*,load1,load1,store1,store1") + [(set_attr "type" "mov_reg,alu_imm,alu_imm,alu_imm,mov_imm,load1,load1,store1,store1") (set_attr "length" "2,4,2,4,4,4,4,4,4") (set_attr "predicable" "yes") (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no") @@ -303,7 +310,8 @@ INTVAL (operands[3])); return \"add\\t%2, %|pc\;ldr%?\\t%0, [%2]\"; " - [(set_attr "length" "4,4,6,6")] + [(set_attr "length" "4,4,6,6") + (set_attr "type" "multiple")] ) ;; Thumb-2 always has load/store halfword instructions, so we can avoid a lot @@ -319,12 +327,27 @@ movw%?\\t%0, %L1\\t%@ movhi str%(h%)\\t%1, %0\\t%@ movhi ldr%(h%)\\t%0, %1\\t%@ movhi" - [(set_attr "type" "*,*,store1,load1") + [(set_attr "type" "mov_imm,mov_reg,store1,load1") (set_attr "predicable" "yes") (set_attr "pool_range" "*,*,*,4094") (set_attr "neg_pool_range" "*,*,*,250")] ) +(define_insn "*thumb2_storewb_pairsi" + [(set (match_operand:SI 0 "register_operand" "=&kr") + (plus:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "const_int_operand" "n"))) + (set (mem:SI (plus:SI (match_dup 0) (match_dup 2))) + (match_operand:SI 3 "register_operand" "r")) + (set (mem:SI (plus:SI (match_dup 0) + (match_operand:SI 5 "const_int_operand" "n"))) + (match_operand:SI 4 "register_operand" "r"))] + "TARGET_THUMB2 + && INTVAL (operands[5]) == INTVAL (operands[2]) + 4" + "strd\\t%3, %4, [%0, %2]!" + [(set_attr "type" "store2")] +) + (define_insn "*thumb2_cmpsi_neg_shiftsi" [(set (reg:CC CC_REGNUM) (compare:CC (match_operand:SI 0 "s_register_operand" "r") @@ -335,7 +358,7 @@ "cmn%?\\t%0, %1%S3" [(set_attr "conds" "set") (set_attr "shift" "1") - (set_attr "type" "arlo_shift")] + (set_attr "type" "alus_shift_imm")] ) (define_insn_and_split "*thumb2_mov_scc" @@ -352,7 +375,8 @@ "" [(set_attr "conds" "use") (set_attr "enabled_for_depr_it" "yes,no") - (set_attr "length" "8,10")] + (set_attr "length" "8,10") + (set_attr "type" "multiple")] ) (define_insn_and_split "*thumb2_mov_negscc" @@ -370,7 +394,8 @@ operands[3] = GEN_INT (~0); } [(set_attr "conds" "use") - (set_attr "length" "10")] + (set_attr "length" "10") + (set_attr "type" "multiple")] ) (define_insn_and_split "*thumb2_mov_negscc_strict_it" @@ -398,7 +423,8 @@ } [(set_attr "conds" "use") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*thumb2_mov_notscc" @@ -417,7 +443,8 @@ operands[4] = GEN_INT (~0); } [(set_attr "conds" "use") - (set_attr "length" "10")] + (set_attr "length" "10") + (set_attr "type" "multiple")] ) (define_insn_and_split "*thumb2_mov_notscc_strict_it" @@ -439,7 +466,8 @@ VOIDmode, operands[2], const0_rtx); } [(set_attr "conds" "use") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn_and_split "*thumb2_movsicc_insn" @@ -499,7 +527,8 @@ } [(set_attr "length" "4,4,6,6,6,6,10,10,10,10,6") (set_attr "enabled_for_depr_it" "yes,yes,no,no,no,no,no,no,no,no,yes") - (set_attr "conds" "use")] + (set_attr "conds" "use") + (set_attr "type" "multiple")] ) (define_insn "*thumb2_movsfcc_soft_insn" @@ -513,7 +542,8 @@ it\\t%D3\;mov%D3\\t%0, %2 it\\t%d3\;mov%d3\\t%0, %1" [(set_attr "length" "6,6") - (set_attr "conds" "use")] + (set_attr "conds" "use") + (set_attr "type" "multiple")] ) (define_insn "*call_reg_thumb2" @@ -542,7 +572,8 @@ (match_operand:SI 0 "register_operand" "l*r"))] "TARGET_THUMB2" "bx\\t%0" - [(set_attr "conds" "clob")] + [(set_attr "conds" "clob") + (set_attr "type" "branch")] ) ;; Don't define thumb2_load_indirect_jump because we can't guarantee label ;; addresses will have the thumb bit set correctly. @@ -570,6 +601,7 @@ operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); } [(set_attr "conds" "use") + (set_attr "type" "multiple") (set (attr "length") (if_then_else (match_test "arm_restrict_it") (const_int 8) (const_int 10)))] @@ -602,7 +634,8 @@ operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); } [(set_attr "conds" "use") - (set_attr "length" "6,10")] + (set_attr "length" "6,10") + (set_attr "type" "multiple")] ) (define_insn "*thumb2_ior_scc_strict_it" @@ -615,7 +648,8 @@ it\\t%d2\;mov%d2\\t%0, #1\;it\\t%d2\;orr%d2\\t%0, %1 mov\\t%0, #1\;orr\\t%0, %1\;it\\t%D2\;mov%D2\\t%0, %1" [(set_attr "conds" "use") - (set_attr "length" "8")] + (set_attr "length" "8") + (set_attr "type" "multiple")] ) (define_insn "*thumb2_cond_move" @@ -664,7 +698,8 @@ return \"\"; " [(set_attr "conds" "use") - (set_attr "length" "6,6,10")] + (set_attr "length" "6,6,10") + (set_attr "type" "multiple")] ) (define_insn "*thumb2_cond_arith" @@ -701,7 +736,8 @@ return \"%i5%d4\\t%0, %1, #1\"; " [(set_attr "conds" "clob") - (set_attr "length" "14")] + (set_attr "length" "14") + (set_attr "type" "multiple")] ) (define_insn_and_split "*thumb2_cond_arith_strict_it" @@ -770,7 +806,8 @@ FAIL; } [(set_attr "conds" "clob") - (set_attr "length" "12")] + (set_attr "length" "12") + (set_attr "type" "multiple")] ) (define_insn "*thumb2_cond_sub" @@ -801,7 +838,8 @@ return \"sub%d4\\t%0, %1, #1\"; " [(set_attr "conds" "clob") - (set_attr "length" "10,14")] + (set_attr "length" "10,14") + (set_attr "type" "multiple")] ) (define_insn_and_split "*thumb2_negscc" @@ -869,7 +907,8 @@ FAIL; } [(set_attr "conds" "clob") - (set_attr "length" "14")] + (set_attr "length" "14") + (set_attr "type" "multiple")] ) (define_insn "*thumb2_movcond" @@ -952,7 +991,8 @@ return \"\"; " [(set_attr "conds" "clob") - (set_attr "length" "10,10,14")] + (set_attr "length" "10,10,14") + (set_attr "type" "multiple")] ) ;; Zero and sign extension instructions. @@ -1015,7 +1055,8 @@ "TARGET_THUMB2 && !flag_pic" "* return thumb2_output_casesi(operands);" [(set_attr "conds" "clob") - (set_attr "length" "16")] + (set_attr "length" "16") + (set_attr "type" "multiple")] ) (define_insn "thumb2_casesi_internal_pic" @@ -1033,7 +1074,8 @@ "TARGET_THUMB2 && flag_pic" "* return thumb2_output_casesi(operands);" [(set_attr "conds" "clob") - (set_attr "length" "20")] + (set_attr "length" "20") + (set_attr "type" "multiple")] ) (define_insn "*thumb2_return" @@ -1070,7 +1112,8 @@ && GET_CODE(operands[3]) != MINUS" "%I3%!\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "length" "2")] + (set_attr "length" "2") + (set_attr "type" "alu_reg")] ) (define_insn "*thumb2_shiftsi3_short" @@ -1087,8 +1130,8 @@ (set_attr "shift" "1") (set_attr "length" "2") (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") - (const_string "arlo_shift") - (const_string "arlo_shift_reg")))] + (const_string "alu_shift_imm") + (const_string "alu_shift_reg")))] ) (define_insn "*thumb2_mov<mode>_shortim" @@ -1098,7 +1141,8 @@ "TARGET_THUMB2 && reload_completed" "mov%!\t%0, %1" [(set_attr "predicable" "yes") - (set_attr "length" "2")] + (set_attr "length" "2") + (set_attr "type" "mov_imm")] ) (define_insn "*thumb2_addsi_short" @@ -1122,7 +1166,8 @@ return \"add%!\\t%0, %1, %2\"; " [(set_attr "predicable" "yes") - (set_attr "length" "2")] + (set_attr "length" "2") + (set_attr "type" "alu_reg")] ) (define_insn "*thumb2_subsi_short" @@ -1133,7 +1178,8 @@ "TARGET_THUMB2 && reload_completed" "sub%!\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "length" "2")] + (set_attr "length" "2") + (set_attr "type" "alu_reg")] ) (define_peephole2 @@ -1185,7 +1231,8 @@ return \"adds\\t%0, %1, %2\"; " [(set_attr "conds" "set") - (set_attr "length" "2,2,4")] + (set_attr "length" "2,2,4") + (set_attr "type" "alu_reg")] ) (define_insn "*thumb2_addsi3_compare0_scratch" @@ -1210,7 +1257,7 @@ " [(set_attr "conds" "set") (set_attr "length" "2,2,4,4") - (set_attr "type" "arlo_imm,*,arlo_imm,*")] + (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_reg")] ) (define_insn "*thumb2_mulsi_short" @@ -1269,7 +1316,8 @@ (le (minus (match_dup 1) (pc)) (const_int 128)) (not (match_test "which_alternative"))) (const_int 2) - (const_int 8)))] + (const_int 8))) + (set_attr "type" "branch,multiple")] ) (define_insn "*thumb2_cbnz" @@ -1292,7 +1340,8 @@ (le (minus (match_dup 1) (pc)) (const_int 128)) (not (match_test "which_alternative"))) (const_int 2) - (const_int 8)))] + (const_int 8))) + (set_attr "type" "branch,multiple")] ) (define_insn "*thumb2_one_cmplsi2_short" @@ -1302,7 +1351,8 @@ "TARGET_THUMB2 && reload_completed" "mvn%!\t%0, %1" [(set_attr "predicable" "yes") - (set_attr "length" "2")] + (set_attr "length" "2") + (set_attr "type" "mvn_reg")] ) (define_insn "*thumb2_negsi2_short" @@ -1312,7 +1362,8 @@ "TARGET_THUMB2 && reload_completed" "neg%!\t%0, %1" [(set_attr "predicable" "yes") - (set_attr "length" "2")] + (set_attr "length" "2") + (set_attr "type" "alu_reg")] ) (define_insn "*orsi_notsi_si" @@ -1322,7 +1373,8 @@ "TARGET_THUMB2" "orn%?\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no")] + (set_attr "predicable_short_it" "no") + (set_attr "type" "logic_reg")] ) (define_insn "*orsi_not_shiftsi_si" @@ -1336,7 +1388,7 @@ [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") (set_attr "shift" "2") - (set_attr "type" "arlo_shift")] + (set_attr "type" "alu_shift_imm")] ) (define_peephole2 diff --git a/gcc/config/arm/types.md b/gcc/config/arm/types.md index 51dbc7c37d7..7a96438fd48 100644 --- a/gcc/config/arm/types.md +++ b/gcc/config/arm/types.md @@ -23,46 +23,81 @@ ; ; Instruction classification: ; -; arlo_imm any arithmetic or logical instruction that doesn't have -; a shifted operand and has an immediate operand. This +; adc_imm add/subtract with carry and with an immediate operand. +; adc_reg add/subtract with carry and no immediate operand. +; adcs_imm as adc_imm, setting condition flags. +; adcs_reg as adc_reg, setting condition flags. +; adr calculate address. +; alu_ext From ARMv8-A: any arithmetic instruction that has a +; sign/zero-extended. +; AArch64 Only. +; source operand +; alu_imm any arithmetic instruction that doesn't have a shifted +; operand and has an immediate operand. This ; excludes MOV, MVN and RSB(S) immediate. -; arlo_reg any arithmetic or logical instruction that doesn't have -; a shifted or an immediate operand. This excludes +; alu_reg any arithmetic instruction that doesn't have a shifted +; or an immediate operand. This excludes ; MOV and MVN but includes MOVT. This is also the default. -; arlo_shift any arithmetic or logical instruction that has a source -; operand shifted by a constant. This excludes -; simple shifts. -; arlo_shift_reg as arlo_shift, with the shift amount specified in a +; alu_shift_imm any arithmetic instruction that has a source operand +; shifted by a constant. This excludes simple shifts. +; alu_shift_reg as alu_shift_imm, with the shift amount specified in a ; register. +; alus_ext From ARMv8-A: as alu_ext, setting condition flags. +; AArch64 Only. +; alus_imm as alu_imm, setting condition flags. +; alus_reg as alu_reg, setting condition flags. +; alus_shift_imm as alu_shift_imm, setting condition flags. +; alus_shift_reg as alu_shift_reg, setting condition flags. +; bfm bitfield move operation. ; block blockage insn, this blocks all functional units. ; branch branch. ; call subroutine call. ; clz count leading zeros (CLZ). +; csel From ARMv8-A: conditional select. ; extend extend instruction (SXTB, SXTH, UXTB, UXTH). -; f_2_r transfer from float to core (no memory needed). -; f_cvt conversion between float and integral. +; f_cvt conversion between float representations. +; f_cvtf2i conversion between float and integral types. +; f_cvti2f conversion between integral and float types. ; f_flag transfer of co-processor flags to the CPSR. ; f_load[d,s] double/single load from memory. Used for VFP unit. +; f_mcr transfer arm to vfp reg. +; f_mcrr transfer two arm regs to vfp reg. ; f_minmax[d,s] double/single floating point minimum/maximum. +; f_mrc transfer vfp to arm reg. +; f_mrrc transfer vfp to two arm regs. ; f_rint[d,s] double/single floating point rount to integral. ; f_sel[d,s] double/single floating byte select. ; f_store[d,s] double/single store to memory. Used for VFP unit. ; fadd[d,s] double/single floating-point scalar addition. ; fcmp[d,s] double/single floating-point compare. ; fconst[d,s] double/single load immediate. -; fcpys single precision floating point cpy. +; fcsel From ARMv8-A: Floating-point conditional select. ; fdiv[d,s] double/single precision floating point division. ; ffarith[d,s] double/single floating point abs/neg/cpy. ; ffma[d,s] double/single floating point fused multiply-accumulate. ; float floating point arithmetic operation. ; fmac[d,s] double/single floating point multiply-accumulate. +; fmov floating point to floating point register move. ; fmul[d,s] double/single floating point multiply. +; fsqrt[d,s] double/single precision floating point square root. ; load_acq load-acquire. ; load_byte load byte(s) from memory to arm registers. ; load1 load 1 word from memory to arm registers. ; load2 load 2 words from memory to arm registers. ; load3 load 3 words from memory to arm registers. ; load4 load 4 words from memory to arm registers. +; logic_imm any logical instruction that doesn't have a shifted +; operand and has an immediate operand. +; logic_reg any logical instruction that doesn't have a shifted +; operand or an immediate operand. +; logic_shift_imm any logical instruction that has a source operand +; shifted by a constant. This excludes simple shifts. +; logic_shift_reg as logic_shift_imm, with the shift amount specified in a +; register. +; logics_imm as logic_imm, setting condition flags. +; logics_reg as logic_reg, setting condition flags. +; logics_shift_imm as logic_shift_imm, setting condition flags. +; logics_shift_reg as logic_shift_reg, setting condition flags. ; mla integer multiply accumulate. ; mlas integer multiply accumulate, flag setting. ; mov_imm simple MOV instruction that moves an immediate to @@ -71,15 +106,21 @@ ; register. This includes MOVW, but not MOVT. ; mov_shift simple MOV instruction, shifted operand by a constant. ; mov_shift_reg simple MOV instruction, shifted operand by a register. +; mrs system/special/co-processor register move. ; mul integer multiply. ; muls integer multiply, flag setting. +; multiple more than one instruction, candidate for future +; splitting, or better modeling. ; mvn_imm inverting move instruction, immediate. ; mvn_reg inverting move instruction, register. ; mvn_shift inverting move instruction, shifted operand by a constant. ; mvn_shift_reg inverting move instruction, shifted operand by a register. -; r_2_f transfer from core to float. +; no_insn an insn which does not represent an instruction in the +; final output, thus having no impact on scheduling. +; rbit reverse bits. +; rev reverse bytes. ; sdiv signed division. -; shift simple shift operation (LSL, LSR, ASR, ROR) with an +; shift_imm simple shift operation (LSL, LSR, ASR, ROR) with an ; immediate. ; shift_reg simple shift by a register. ; smlad signed multiply accumulate dual. @@ -117,6 +158,8 @@ ; umlals unsigned multiply accumulate long, flag setting. ; umull unsigned multiply long. ; umulls unsigned multiply long, flag setting. +; untyped insn without type information - default, and error, +; case. ; ; The classification below is for instructions used by the Wireless MMX ; Technology. Each attribute value is used to classify an instruction of the @@ -181,24 +224,108 @@ ; wmmx_wunpckih ; wmmx_wunpckil ; wmmx_wxor +; +; The classification below is for NEON instructions. +; +; neon_bp_2cycle +; neon_bp_3cycle +; neon_bp_simple +; neon_fp_vadd_ddd_vabs_dd +; neon_fp_vadd_qqq_vabs_qq +; neon_fp_vmla_ddd_scalar +; neon_fp_vmla_ddd +; neon_fp_vmla_qqq_scalar +; neon_fp_vmla_qqq +; neon_fp_vmul_ddd +; neon_fp_vmul_qqd +; neon_fp_vrecps_vrsqrts_ddd +; neon_fp_vrecps_vrsqrts_qqq +; neon_fp_vsum +; neon_int_1 +; neon_int_2 +; neon_int_3 +; neon_int_4 +; neon_int_5 +; neon_ldm_2 +; neon_ldr +; neon_mcr_2_mcrr +; neon_mcr +; neon_mla_ddd_16_scalar_qdd_32_16_long_scalar +; neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long +; neon_mla_ddd_8_16_qdd_16_8_long_32_16_long +; neon_mla_qqq_32_qqd_32_scalar +; neon_mla_qqq_8_16 +; neon_mrc +; neon_mrrc +; neon_mul_ddd_16_scalar_32_16_long_scalar +; neon_mul_ddd_8_16_qdd_16_8_long_32_16_long +; neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar +; neon_mul_qqd_32_scalar +; neon_mul_qqq_8_16_32_ddd_32 +; neon_shift_1 +; neon_shift_2 +; neon_shift_3 +; neon_stm_2 +; neon_str +; neon_vaba_qqq +; neon_vaba +; neon_vld1_1_2_regs +; neon_vld1_3_4_regs +; neon_vld1_vld2_lane +; neon_vld2_2_regs_vld1_vld2_all_lanes +; neon_vld2_4_regs +; neon_vld3_vld4_all_lanes +; neon_vld3_vld4_lane +; neon_vld3_vld4 +; neon_vmov +; neon_vqneg_vqabs +; neon_vqshl_vrshl_vqrshl_qqq +; neon_vshl_ddd +; neon_vsma +; neon_vsra_vrsra +; neon_vst1_1_2_regs_vst2_2_regs +; neon_vst1_3_4_regs +; neon_vst1_vst2_lane +; neon_vst2_4_regs_vst3_vst4 +; neon_vst3_vst4_lane +; neon_vst3_vst4 (define_attr "type" - "arlo_imm,\ - arlo_reg,\ - arlo_shift,\ - arlo_shift_reg,\ + "adc_imm,\ + adc_reg,\ + adcs_imm,\ + adcs_reg,\ + adr,\ + alu_ext,\ + alu_imm,\ + alu_reg,\ + alu_shift_imm,\ + alu_shift_reg,\ + alus_ext,\ + alus_imm,\ + alus_reg,\ + alus_shift_imm,\ + alus_shift_reg,\ + bfm,\ block,\ branch,\ call,\ clz,\ + no_insn,\ + csel,\ extend,\ - f_2_r,\ f_cvt,\ + f_cvtf2i,\ + f_cvti2f,\ f_flag,\ f_loadd,\ f_loads,\ + f_mcr,\ + f_mcrr,\ f_minmaxd,\ f_minmaxs,\ + f_mrc,\ + f_mrrc,\ f_rintd,\ f_rints,\ f_seld,\ @@ -211,7 +338,7 @@ fcmps,\ fconstd,\ fconsts,\ - fcpys,\ + fcsel,\ fdivd,\ fdivs,\ ffarithd,\ @@ -221,29 +348,44 @@ float,\ fmacd,\ fmacs,\ + fmov,\ fmuld,\ fmuls,\ + fsqrts,\ + fsqrtd,\ load_acq,\ load_byte,\ load1,\ load2,\ load3,\ load4,\ + logic_imm,\ + logic_reg,\ + logic_shift_imm,\ + logic_shift_reg,\ + logics_imm,\ + logics_reg,\ + logics_shift_imm,\ + logics_shift_reg,\ mla,\ mlas,\ mov_imm,\ mov_reg,\ mov_shift,\ mov_shift_reg,\ + mrs,\ mul,\ muls,\ + multiple,\ mvn_imm,\ mvn_reg,\ mvn_shift,\ mvn_shift_reg,\ - r_2_f,\ + nop,\ + rbit,\ + rev,\ sdiv,\ - shift,\ + shift_imm,\ shift_reg,\ smlad,\ smladx,\ @@ -279,6 +421,7 @@ umlals,\ umull,\ umulls,\ + untyped,\ wmmx_tandc,\ wmmx_tbcst,\ wmmx_textrc,\ @@ -337,8 +480,70 @@ wmmx_wunpckel,\ wmmx_wunpckih,\ wmmx_wunpckil,\ - wmmx_wxor" - (const_string "arlo_reg")) + wmmx_wxor,\ + neon_bp_2cycle,\ + neon_bp_3cycle,\ + neon_bp_simple,\ + neon_fp_vadd_ddd_vabs_dd,\ + neon_fp_vadd_qqq_vabs_qq,\ + neon_fp_vmla_ddd_scalar,\ + neon_fp_vmla_ddd,\ + neon_fp_vmla_qqq_scalar,\ + neon_fp_vmla_qqq,\ + neon_fp_vmul_ddd,\ + neon_fp_vmul_qqd,\ + neon_fp_vrecps_vrsqrts_ddd,\ + neon_fp_vrecps_vrsqrts_qqq,\ + neon_fp_vsum,\ + neon_int_1,\ + neon_int_2,\ + neon_int_3,\ + neon_int_4,\ + neon_int_5,\ + neon_ldm_2,\ + neon_ldr,\ + neon_mcr_2_mcrr,\ + neon_mcr,\ + neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\ + neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\ + neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\ + neon_mla_qqq_32_qqd_32_scalar,\ + neon_mla_qqq_8_16,\ + neon_mrc,\ + neon_mrrc,\ + neon_mul_ddd_16_scalar_32_16_long_scalar,\ + neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\ + neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\ + neon_mul_qqd_32_scalar,\ + neon_mul_qqq_8_16_32_ddd_32,\ + neon_shift_1,\ + neon_shift_2,\ + neon_shift_3,\ + neon_stm_2,\ + neon_str,\ + neon_vaba_qqq,\ + neon_vaba,\ + neon_vld1_1_2_regs,\ + neon_vld1_3_4_regs,\ + neon_vld1_vld2_lane,\ + neon_vld2_2_regs_vld1_vld2_all_lanes,\ + neon_vld2_4_regs,\ + neon_vld3_vld4_all_lanes,\ + neon_vld3_vld4_lane,\ + neon_vld3_vld4,\ + neon_vmov,\ + neon_vqneg_vqabs,\ + neon_vqshl_vrshl_vqrshl_qqq,\ + neon_vshl_ddd,\ + neon_vsma,\ + neon_vsra_vrsra,\ + neon_vst1_1_2_regs_vst2_2_regs,\ + neon_vst1_3_4_regs,\ + neon_vst1_vst2_lane,\ + neon_vst2_4_regs_vst3_vst4,\ + neon_vst3_vst4_lane,\ + neon_vst3_vst4" + (const_string "untyped")) ; Is this an (integer side) multiply with a 32-bit (or smaller) result? (define_attr "mul32" "no,yes" diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md index ef8777a900b..0b10c130d70 100644 --- a/gcc/config/arm/vfp.md +++ b/gcc/config/arm/vfp.md @@ -53,8 +53,7 @@ } " [(set_attr "predicable" "yes") - (set_attr "type" "mov_reg,mov_reg,mvn_imm,mov_imm,load1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") - (set_attr "neon_type" "*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*") + (set_attr "type" "mov_reg,mov_reg,mvn_imm,mov_imm,load1,store1,f_mcr,f_mrc,fmov,f_loads,f_stores") (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*") (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")] ) @@ -101,9 +100,8 @@ " [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no,no,no,no,no,no") - (set_attr "type" "mov_reg,mov_reg,mov_reg,mvn_reg,mov_reg,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") + (set_attr "type" "mov_reg,mov_reg,mov_reg,mvn_reg,mov_reg,load1,load1,store1,store1,f_mcr,f_mrc,fmov,f_loads,f_stores") (set_attr "length" "2,4,2,4,4,4,4,4,4,4,4,4,4,4") - (set_attr "neon_type" "*,*,*,*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*") (set_attr "pool_range" "*,*,*,*,*,1018,4094,*,*,*,*,*,1018,*") (set_attr "neg_pool_range" "*,*,*,*,*, 0, 0,*,*,*,*,*,1008,*")] ) @@ -146,8 +144,7 @@ gcc_unreachable (); } " - [(set_attr "type" "*,*,*,*,load2,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored") - (set_attr "neon_type" "*,*,*,*,*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*") + [(set_attr "type" "multiple,multiple,multiple,multiple,load2,load2,store2,f_mcrr,f_mrrc,ffarithd,f_loadd,f_stored") (set (attr "length") (cond [(eq_attr "alternative" "1,4,5,6") (const_int 8) (eq_attr "alternative" "2") (const_int 12) (eq_attr "alternative" "3") (const_int 16) @@ -195,8 +192,7 @@ gcc_unreachable (); } " - [(set_attr "type" "*,*,*,*,load2,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored") - (set_attr "neon_type" "*,*,*,*,*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*") + [(set_attr "type" "multiple,multiple,multiple,multiple,load2,load2,store2,f_mcrr,f_mrrc,ffarithd,f_loadd,f_stored") (set (attr "length") (cond [(eq_attr "alternative" "1") (const_int 8) (eq_attr "alternative" "2") (const_int 12) (eq_attr "alternative" "3") (const_int 16) @@ -264,8 +260,8 @@ } " [(set_attr "conds" "unconditional") - (set_attr "type" "*,*,load1,store1,fcpys,*,r_2_f,f_2_r,*") - (set_attr "neon_type" "neon_vld1_1_2_regs,neon_vst1_1_2_regs_vst2_2_regs,*,*,*,*,*,*,*") + (set_attr "type" "neon_vld1_1_2_regs,neon_vst1_1_2_regs_vst2_2_regs,\ + load1,store1,fmov,mov_reg,f_mcr,f_mrc,multiple") (set_attr "length" "4,4,4,4,4,4,4,4,8")] ) @@ -315,7 +311,7 @@ } " [(set_attr "conds" "unconditional") - (set_attr "type" "load1,store1,fcpys,*,r_2_f,f_2_r,*") + (set_attr "type" "load1,store1,fmov,mov_reg,f_mcr,f_mrc,multiple") (set_attr "length" "4,4,4,4,4,4,8")] ) @@ -355,8 +351,7 @@ " [(set_attr "predicable" "yes") (set_attr "type" - "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,mov_reg") - (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*") + "f_mcr,f_mrc,fconsts,f_loads,f_stores,load1,store1,fmov,mov_reg") (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*") (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")] ) @@ -393,8 +388,7 @@ [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") (set_attr "type" - "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,mov_reg") - (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*") + "f_mcr,f_mrc,fconsts,f_loads,f_stores,load1,store1,fmov,mov_reg") (set_attr "pool_range" "*,*,*,1018,*,4090,*,*,*") (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")] ) @@ -434,9 +428,8 @@ } } " - [(set_attr "type" - "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*") - (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*") + [(set_attr "type" "f_mcrr,f_mrrc,fconstd,f_loadd,f_stored,\ + load2,store2,ffarithd,multiple") (set (attr "length") (cond [(eq_attr "alternative" "5,6,8") (const_int 8) (eq_attr "alternative" "7") (if_then_else @@ -480,9 +473,8 @@ } } " - [(set_attr "type" - "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*") - (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*") + [(set_attr "type" "f_mcrr,f_mrrc,fconstd,f_loadd,\ + f_stored,load2,store2,ffarithd,multiple") (set (attr "length") (cond [(eq_attr "alternative" "5,6,8") (const_int 8) (eq_attr "alternative" "7") (if_then_else @@ -517,8 +509,7 @@ fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1" [(set_attr "conds" "use") (set_attr "length" "4,4,8,4,4,8,4,4,8") - (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r") - (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr,neon_mcr,neon_mcr,neon_mrc,neon_mrc,neon_mrc")] + (set_attr "type" "fmov,fmov,fmov,f_mcr,f_mcr,f_mcr,f_mrc,f_mrc,f_mrc")] ) (define_insn "*thumb2_movsfcc_vfp" @@ -541,8 +532,7 @@ ite\\t%D3\;fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1" [(set_attr "conds" "use") (set_attr "length" "6,6,10,6,6,10,6,6,10") - (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r") - (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr,neon_mcr,neon_mcr,neon_mrc,neon_mrc,neon_mrc")] + (set_attr "type" "fmov,fmov,fmov,f_mcr,f_mcr,f_mcr,f_mrc,f_mrc,f_mrc")] ) (define_insn "*movdfcc_vfp" @@ -565,8 +555,7 @@ fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1" [(set_attr "conds" "use") (set_attr "length" "4,4,8,4,4,8,4,4,8") - (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r") - (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mrrc,neon_mrrc,neon_mrrc")] + (set_attr "type" "ffarithd,ffarithd,ffarithd,f_mcr,f_mcr,f_mcr,f_mrrc,f_mrrc,f_mrrc")] ) (define_insn "*thumb2_movdfcc_vfp" @@ -589,8 +578,7 @@ ite\\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1" [(set_attr "conds" "use") (set_attr "length" "6,6,10,6,6,10,6,6,10") - (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r") - (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mrrc,neon_mrrc,neon_mrrc")] + (set_attr "type" "ffarithd,ffarithd,ffarithd,f_mcr,f_mcr,f_mcrr,f_mrrc,f_mrrc,f_mrrc")] ) @@ -1003,7 +991,7 @@ "ftosizs%?\\t%0, %1" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] + (set_attr "type" "f_cvtf2i")] ) (define_insn "*truncsidf2_vfp" @@ -1013,7 +1001,7 @@ "ftosizd%?\\t%0, %P1" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] + (set_attr "type" "f_cvtf2i")] ) @@ -1024,7 +1012,7 @@ "ftouizs%?\\t%0, %1" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] + (set_attr "type" "f_cvtf2i")] ) (define_insn "fixuns_truncdfsi2" @@ -1034,7 +1022,7 @@ "ftouizd%?\\t%0, %P1" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] + (set_attr "type" "f_cvtf2i")] ) @@ -1045,7 +1033,7 @@ "fsitos%?\\t%0, %1" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] + (set_attr "type" "f_cvti2f")] ) (define_insn "*floatsidf2_vfp" @@ -1055,7 +1043,7 @@ "fsitod%?\\t%P0, %1" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] + (set_attr "type" "f_cvti2f")] ) @@ -1066,7 +1054,7 @@ "fuitos%?\\t%0, %1" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] + (set_attr "type" "f_cvti2f")] ) (define_insn "floatunssidf2" @@ -1076,7 +1064,7 @@ "fuitod%?\\t%P0, %1" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "type" "f_cvt")] + (set_attr "type" "f_cvti2f")] ) @@ -1089,7 +1077,7 @@ "fsqrts%?\\t%0, %1" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "type" "fdivs")] + (set_attr "type" "fsqrts")] ) (define_insn "*sqrtdf2_vfp" @@ -1099,7 +1087,7 @@ "fsqrtd%?\\t%P0, %P1" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") - (set_attr "type" "fdivd")] + (set_attr "type" "fsqrtd")] ) @@ -1229,19 +1217,20 @@ (set_attr "type" "fcmpd")] ) -;; Fixed point to floating point conversions. +;; Fixed point to floating point conversions. (define_code_iterator FCVT [unsigned_float float]) (define_code_attr FCVTI32typename [(unsigned_float "u32") (float "s32")]) (define_insn "*combine_vcvt_f32_<FCVTI32typename>" [(set (match_operand:SF 0 "s_register_operand" "=t") (mult:SF (FCVT:SF (match_operand:SI 1 "s_register_operand" "0")) - (match_operand 2 + (match_operand 2 "const_double_vcvt_power_of_two_reciprocal" "Dt")))] "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math" - "vcvt.f32.<FCVTI32typename>\\t%0, %1, %v2" - [(set_attr "predicable" "no") - (set_attr "type" "f_cvt")] + "vcvt%?.f32.<FCVTI32typename>\\t%0, %1, %v2" + [(set_attr "predicable" "yes") + (set_attr "predicable_short_it" "no") + (set_attr "type" "f_cvti2f")] ) ;; Not the ideal way of implementing this. Ideally we would be able to split @@ -1249,17 +1238,19 @@ (define_insn "*combine_vcvt_f64_<FCVTI32typename>" [(set (match_operand:DF 0 "s_register_operand" "=x,x,w") (mult:DF (FCVT:DF (match_operand:SI 1 "s_register_operand" "r,t,r")) - (match_operand 2 + (match_operand 2 "const_double_vcvt_power_of_two_reciprocal" "Dt,Dt,Dt")))] - "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math + "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math && !TARGET_VFP_SINGLE" "@ - vmov.f32\\t%0, %1\;vcvt.f64.<FCVTI32typename>\\t%P0, %P0, %v2 - vmov.f32\\t%0, %1\;vcvt.f64.<FCVTI32typename>\\t%P0, %P0, %v2 - vmov.f64\\t%P0, %1, %1\;vcvt.f64.<FCVTI32typename>\\t%P0, %P0, %v2" - [(set_attr "predicable" "no") - (set_attr "type" "f_cvt") - (set_attr "length" "8")] + vmov%?.f32\\t%0, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2 + vmov%?.f32\\t%0, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2 + vmov%?.f64\\t%P0, %1, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2" + [(set_attr "predicable" "yes") + (set_attr "ce_count" "2") + (set_attr "predicable_short_it" "no") + (set_attr "type" "f_cvti2f") + (set_attr "length" "8")] ) ;; Store multiple insn used in function prologue. diff --git a/gcc/config/arm/vfp11.md b/gcc/config/arm/vfp11.md index b027fe6c3cd..4cfa69efc24 100644 --- a/gcc/config/arm/vfp11.md +++ b/gcc/config/arm/vfp11.md @@ -51,12 +51,13 @@ (define_insn_reservation "vfp_ffarith" 4 (and (eq_attr "generic_vfp" "yes") - (eq_attr "type" "fcpys,ffariths,ffarithd,fcmps,fcmpd")) + (eq_attr "type" "fmov,ffariths,ffarithd,fcmps,fcmpd")) "fmac") (define_insn_reservation "vfp_farith" 8 (and (eq_attr "generic_vfp" "yes") - (eq_attr "type" "fadds,faddd,fconsts,fconstd,f_cvt,fmuls,fmacs,ffmas")) + (eq_attr "type" "fadds,faddd,fconsts,fconstd,f_cvt,f_cvtf2i,f_cvti2f,\ + fmuls,fmacs,ffmas")) "fmac") (define_insn_reservation "vfp_fmul" 9 @@ -66,23 +67,23 @@ (define_insn_reservation "vfp_fdivs" 19 (and (eq_attr "generic_vfp" "yes") - (eq_attr "type" "fdivs")) + (eq_attr "type" "fdivs, fsqrts")) "ds*15") (define_insn_reservation "vfp_fdivd" 33 (and (eq_attr "generic_vfp" "yes") - (eq_attr "type" "fdivd")) + (eq_attr "type" "fdivd, fsqrtd")) "fmac+ds*29") ;; Moves to/from arm regs also use the load/store pipeline. (define_insn_reservation "vfp_fload" 4 (and (eq_attr "generic_vfp" "yes") - (eq_attr "type" "f_loads,f_loadd,r_2_f")) + (eq_attr "type" "f_loads,f_loadd,f_mcr,f_mcrr")) "vfp_ls") (define_insn_reservation "vfp_fstore" 4 (and (eq_attr "generic_vfp" "yes") - (eq_attr "type" "f_stores,f_stored,f_2_r")) + (eq_attr "type" "f_stores,f_stored,f_mrc,f_mrrc")) "vfp_ls") (define_insn_reservation "vfp_to_cpsr" 4 diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 92ce3b7489b..413b79ad5e7 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -46,6 +46,7 @@ #include "cgraph.h" #include "langhooks.h" #include "bfin-protos.h" +#include "tm_p.h" #include "tm-preds.h" #include "tm-constrs.h" #include "gt-bfin.h" diff --git a/gcc/config/bfin/uclinux.h b/gcc/config/bfin/uclinux.h index ca0f4ee8a35..63cba99cec6 100644 --- a/gcc/config/bfin/uclinux.h +++ b/gcc/config/bfin/uclinux.h @@ -44,3 +44,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define TARGET_SUPPORTS_SYNC_CALLS 1 #define SUBTARGET_FDPIC_NOT_SUPPORTED + +#undef TARGET_LIBC_HAS_FUNCTION +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function diff --git a/gcc/config/c6x/uclinux-elf.h b/gcc/config/c6x/uclinux-elf.h index 5d61f4dc4ec..fa0937ed268 100644 --- a/gcc/config/c6x/uclinux-elf.h +++ b/gcc/config/c6x/uclinux-elf.h @@ -62,3 +62,5 @@ : "0" (_beg), "b" (_end), "b" (_scno)); \ } +#undef TARGET_LIBC_HAS_FUNCTION +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index 7ceb3085e2e..2a659483ce2 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -1325,6 +1325,9 @@ is_objc_metadata (tree decl) return NULL_TREE; } +static int classes_seen; +static int objc_metadata_seen; + /* Return the section required for Objective C ABI 2 metadata. */ static section * darwin_objc2_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base) @@ -1334,12 +1337,9 @@ darwin_objc2_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base) gcc_assert (TREE_CODE (ident) == IDENTIFIER_NODE); p = IDENTIFIER_POINTER (ident); - /* If we are in LTO, then we don't know the state of flag_next_runtime - or flag_objc_abi when the code was generated. We set these from the - meta-data - which is needed to deal with const string constructors. */ + gcc_checking_assert (flag_next_runtime == 1 && flag_objc_abi == 2); - flag_next_runtime = 1; - flag_objc_abi = 2; + objc_metadata_seen = 1; if (base == data_section) base = darwin_sections[objc2_metadata_section]; @@ -1362,7 +1362,10 @@ darwin_objc2_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base) else if (!strncmp (p, "V2_NLCL", 7)) return darwin_sections[objc2_nonlazy_class_section]; else if (!strncmp (p, "V2_CLAB", 7)) - return darwin_sections[objc2_classlist_section]; + { + classes_seen = 1; + return darwin_sections[objc2_classlist_section]; + } else if (!strncmp (p, "V2_SRFS", 7)) return darwin_sections[objc2_selector_refs_section]; else if (!strncmp (p, "V2_NLCA", 7)) @@ -1397,12 +1400,9 @@ darwin_objc1_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base) gcc_assert (TREE_CODE (ident) == IDENTIFIER_NODE); p = IDENTIFIER_POINTER (ident); - /* If we are in LTO, then we don't know the state of flag_next_runtime - or flag_objc_abi when the code was generated. We set these from the - meta-data - which is needed to deal with const string constructors. */ - flag_next_runtime = 1; - if (!global_options_set.x_flag_objc_abi) - flag_objc_abi = 1; + gcc_checking_assert (flag_next_runtime == 1 && flag_objc_abi < 2); + + objc_metadata_seen = 1; /* String sections first, cos there are lots of strings. */ if (!strncmp (p, "V1_STRG", 7)) @@ -1415,7 +1415,10 @@ darwin_objc1_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base) return darwin_sections[objc_meth_var_types_section]; else if (!strncmp (p, "V1_CLAS", 7)) - return darwin_sections[objc_class_section]; + { + classes_seen = 1; + return darwin_sections[objc_class_section]; + } else if (!strncmp (p, "V1_META", 7)) return darwin_sections[objc_meta_class_section]; else if (!strncmp (p, "V1_CATG", 7)) @@ -1599,8 +1602,6 @@ machopic_select_section (tree decl, if (TREE_CODE (name) == TYPE_DECL) name = DECL_NAME (name); - /* FIXME: This is unsatisfactory for LTO, since it relies on other - metadata determining the source FE. */ if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString")) { if (flag_next_runtime) @@ -2841,6 +2842,33 @@ darwin_file_end (void) finalize_ctors (); if (!vec_safe_is_empty (dtors)) finalize_dtors (); + + /* If we are expecting to output NeXT ObjC meta-data, (and we actually see + some) then we output the fix-and-continue marker (Image Info). + This applies to Objective C, Objective C++ and LTO with either language + as part of the input. */ + if (flag_next_runtime && objc_metadata_seen) + { + unsigned int flags = 0; + if (flag_objc_abi >= 2) + { + flags = 16; + output_section_asm_op + (darwin_sections[objc2_image_info_section]->unnamed.data); + } + else + output_section_asm_op + (darwin_sections[objc_image_info_section]->unnamed.data); + + ASM_OUTPUT_ALIGN (asm_out_file, 2); + fputs ("L_OBJC_ImageInfo:\n", asm_out_file); + + flags |= (flag_replace_objc_classes && classes_seen) ? 1 : 0; + flags |= flag_objc_gc ? 2 : 0; + + fprintf (asm_out_file, "\t.long\t0\n\t.long\t%u\n", flags); + } + machopic_finish (asm_out_file); if (strcmp (lang_hooks.name, "GNU C++") == 0) { 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/constraints.md b/gcc/config/i386/constraints.md index 28e626ff3be..92e0c053fac 100644 --- a/gcc/config/i386/constraints.md +++ b/gcc/config/i386/constraints.md @@ -19,7 +19,7 @@ ;;; Unused letters: ;;; B H T -;;; h jk +;;; h j ;; Integer register constraints. ;; It is not necessary to define 'r' here. @@ -78,6 +78,12 @@ "TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 ? FP_SECOND_REG : NO_REGS" "Second from top of 80387 floating-point stack (@code{%st(1)}).") +(define_register_constraint "k" "TARGET_AVX512F ? MASK_EVEX_REGS : NO_REGS" +"@internal Any mask register that can be used as predicate, i.e. k1-k7.") + +(define_register_constraint "Yk" "TARGET_AVX512F ? MASK_REGS : NO_REGS" +"@internal Any mask register.") + ;; Vector registers (also used for plain floating point nowadays). (define_register_constraint "y" "TARGET_MMX ? MMX_REGS : NO_REGS" "Any MMX register.") 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 ee97486bca8..8e6feb939a5 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1645,18 +1645,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 @@ -1714,8 +1717,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. */ @@ -1815,83 +1818,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; @@ -1930,12 +1856,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 @@ -2033,6 +1954,9 @@ enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] = EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS, + /* Mask registers. */ + MASK_REGS, MASK_EVEX_REGS, MASK_EVEX_REGS, MASK_EVEX_REGS, + MASK_EVEX_REGS, MASK_EVEX_REGS, MASK_EVEX_REGS, MASK_EVEX_REGS, }; /* The "default" register map used in 32bit mode. */ @@ -2048,6 +1972,7 @@ int const dbx_register_map[FIRST_PSEUDO_REGISTER] = -1, -1, -1, -1, -1, -1, -1, -1, /* extended SSE registers */ -1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 16-23*/ -1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 24-31*/ + 93, 94, 95, 96, 97, 98, 99, 100, /* Mask registers */ }; /* The "default" register map used in 64bit mode. */ @@ -2063,6 +1988,7 @@ int const dbx64_register_map[FIRST_PSEUDO_REGISTER] = 25, 26, 27, 28, 29, 30, 31, 32, /* extended SSE registers */ 67, 68, 69, 70, 71, 72, 73, 74, /* AVX-512 registers 16-23 */ 75, 76, 77, 78, 79, 80, 81, 82, /* AVX-512 registers 24-31 */ + 118, 119, 120, 121, 122, 123, 124, 125, /* Mask registers */ }; /* Define the register numbers to be used in Dwarf debugging information. @@ -2130,6 +2056,7 @@ int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] = -1, -1, -1, -1, -1, -1, -1, -1, /* extended SSE registers */ -1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 16-23*/ -1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 24-31*/ + 93, 94, 95, 96, 97, 98, 99, 100, /* Mask registers */ }; /* Define parameter passing and return registers. */ @@ -2379,8 +2306,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}, @@ -3177,7 +3103,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}, @@ -3188,9 +3114,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. */ }, }; @@ -3290,16 +3214,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", @@ -3325,10 +3245,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"; } } @@ -3358,6 +3275,12 @@ ix86_option_override_internal (bool main_args_p) if (!global_options_set.x_ix86_abi) ix86_abi = DEFAULT_ABI; + /* For targets using ms ABI enable ms-extensions, if not + explicit turned off. For non-ms ABI we turn off this + option. */ + if (!global_options_set.x_flag_ms_extensions) + flag_ms_extensions = (MS_ABI == DEFAULT_ABI); + if (global_options_set.x_ix86_cmodel) { switch (ix86_cmodel) @@ -3619,20 +3542,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. @@ -4219,8 +4128,13 @@ ix86_conditional_register_usage (void) /* If AVX512F is disabled, squash the registers. */ if (! TARGET_AVX512F) - for (i = FIRST_EXT_REX_SSE_REG; i < LAST_EXT_REX_SSE_REG; i++) - fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; + { + for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++) + fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; + + for (i = FIRST_MASK_REG; i <= LAST_MASK_REG; i++) + fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; + } } @@ -5707,17 +5621,9 @@ ix86_function_arg_regno_p (int regno) && (regno < FIRST_SSE_REG + SSE_REGPARM_MAX))); } - if (TARGET_MACHO) - { - if (SSE_REGNO_P (regno) && TARGET_SSE) - return true; - } - else - { - if (TARGET_SSE && SSE_REGNO_P (regno) - && (regno < FIRST_SSE_REG + SSE_REGPARM_MAX)) - return true; - } + if (TARGET_SSE && SSE_REGNO_P (regno) + && (regno < FIRST_SSE_REG + SSE_REGPARM_MAX)) + return true; /* TODO: The function should depend on current function ABI but builtins.c would need updating then. Therefore we use the @@ -17461,13 +17367,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) @@ -23330,7 +23246,7 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp, if (count_exp != const0_rtx && epilogue_size_needed > 1) expand_movmem_epilogue (dst, src, destreg, srcreg, count_exp, - size_needed); + epilogue_size_needed); if (jump_around_label) emit_label (jump_around_label); return true; @@ -24485,8 +24401,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: @@ -24750,8 +24665,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 @@ -33912,10 +33826,12 @@ ix86_preferred_reload_class (rtx x, reg_class_t regclass) return regclass; /* Force constants into memory if we are loading a (nonzero) constant into - an MMX or SSE register. This is because there are no MMX/SSE instructions - to load from a constant. */ + an MMX, SSE or MASK register. This is because there are no MMX/SSE/MASK + instructions to load from a constant. */ if (CONSTANT_P (x) - && (MAYBE_MMX_CLASS_P (regclass) || MAYBE_SSE_CLASS_P (regclass))) + && (MAYBE_MMX_CLASS_P (regclass) + || MAYBE_SSE_CLASS_P (regclass) + || MAYBE_MASK_CLASS_P (regclass))) return NO_REGS; /* Prefer SSE regs only, if we can use them for math. */ @@ -34019,10 +33935,11 @@ ix86_secondary_reload (bool in_p, rtx x, reg_class_t rclass, /* QImode spills from non-QI registers require intermediate register on 32bit targets. */ - if (!TARGET_64BIT - && !in_p && mode == QImode - && INTEGER_CLASS_P (rclass) - && MAYBE_NON_Q_CLASS_P (rclass)) + if (mode == QImode + && (MAYBE_MASK_CLASS_P (rclass) + || (!TARGET_64BIT && !in_p + && INTEGER_CLASS_P (rclass) + && MAYBE_NON_Q_CLASS_P (rclass)))) { int regno; @@ -34444,6 +34361,8 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode) return false; if (STACK_REGNO_P (regno)) return VALID_FP_MODE_P (mode); + if (MASK_REGNO_P (regno)) + return VALID_MASK_REG_MODE (mode); if (SSE_REGNO_P (regno)) { /* We implement the move patterns for all vector modes into and @@ -34466,7 +34385,7 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode) /* OImode move is available only when AVX is enabled. */ return ((TARGET_AVX && mode == OImode) - || VALID_AVX256_REG_MODE (mode) + || (TARGET_AVX && VALID_AVX256_REG_MODE (mode)) || VALID_SSE_REG_MODE (mode) || VALID_SSE2_REG_MODE (mode) || VALID_MMX_REG_MODE (mode) @@ -35253,6 +35172,10 @@ x86_order_regs_for_local_alloc (void) for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++) reg_alloc_order [pos++] = i; + /* Mask register. */ + for (i = FIRST_MASK_REG; i <= LAST_MASK_REG; i++) + reg_alloc_order [pos++] = i; + /* x87 registers. */ if (TARGET_SSE_MATH) for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++) diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index e820aa65ac5..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) @@ -893,7 +891,7 @@ enum target_cpu_default eliminated during reloading in favor of either the stack or frame pointer. */ -#define FIRST_PSEUDO_REGISTER 69 +#define FIRST_PSEUDO_REGISTER 77 /* Number of hardware registers that go into the DWARF-2 unwind info. If not defined, equals FIRST_PSEUDO_REGISTER. */ @@ -923,7 +921,9 @@ enum target_cpu_default /*xmm16,xmm17,xmm18,xmm19,xmm20,xmm21,xmm22,xmm23*/ \ 0, 0, 0, 0, 0, 0, 0, 0, \ /*xmm24,xmm25,xmm26,xmm27,xmm28,xmm29,xmm30,xmm31*/ \ - 0, 0, 0, 0, 0, 0, 0, 0 } + 0, 0, 0, 0, 0, 0, 0, 0, \ +/* k0, k1, k2, k3, k4, k5, k6, k7*/ \ + 0, 0, 0, 0, 0, 0, 0, 0 } /* 1 for registers not available across function calls. These must include the FIXED_REGISTERS and also any @@ -955,7 +955,9 @@ enum target_cpu_default /*xmm16,xmm17,xmm18,xmm19,xmm20,xmm21,xmm22,xmm23*/ \ 6, 6, 6, 6, 6, 6, 6, 6, \ /*xmm24,xmm25,xmm26,xmm27,xmm28,xmm29,xmm30,xmm31*/ \ - 6, 6, 6, 6, 6, 6, 6, 6 } + 6, 6, 6, 6, 6, 6, 6, 6, \ + /* k0, k1, k2, k3, k4, k5, k6, k7*/ \ + 1, 1, 1, 1, 1, 1, 1, 1 } /* Order in which to allocate registers. Each register must be listed once, even those in FIXED_REGISTERS. List frame pointer @@ -971,7 +973,7 @@ enum target_cpu_default 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, \ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, \ - 63, 64, 65, 66, 67, 68 } + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76 } /* ADJUST_REG_ALLOC_ORDER is a macro which permits reg_alloc_order to be rearranged based on a particular function. When using sse math, @@ -1068,6 +1070,8 @@ enum target_cpu_default || (MODE) == V16SImode || (MODE) == V32HImode || (MODE) == V8DFmode \ || (MODE) == V16SFmode) +#define VALID_MASK_REG_MODE(MODE) ((MODE) == HImode || (MODE) == QImode) + /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */ #define HARD_REGNO_MODE_OK(REGNO, MODE) \ @@ -1093,8 +1097,10 @@ enum target_cpu_default (CC_REGNO_P (REGNO) ? VOIDmode \ : (MODE) == VOIDmode && (NREGS) != 1 ? VOIDmode \ : (MODE) == VOIDmode ? choose_hard_reg_mode ((REGNO), (NREGS), false) \ - : (MODE) == HImode && !TARGET_PARTIAL_REG_STALL ? SImode \ - : (MODE) == QImode && !(TARGET_64BIT || QI_REGNO_P (REGNO)) ? SImode \ + : (MODE) == HImode && !(TARGET_PARTIAL_REG_STALL \ + || MASK_REGNO_P (REGNO)) ? SImode \ + : (MODE) == QImode && !(TARGET_64BIT || QI_REGNO_P (REGNO) \ + || MASK_REGNO_P (REGNO)) ? SImode \ : (MODE)) /* The only ABI that saves SSE registers across calls is Win64 (thus no @@ -1141,6 +1147,9 @@ enum target_cpu_default #define FIRST_EXT_REX_SSE_REG (LAST_REX_SSE_REG + 1) /*53*/ #define LAST_EXT_REX_SSE_REG (FIRST_EXT_REX_SSE_REG + 15) /*68*/ +#define FIRST_MASK_REG (LAST_EXT_REX_SSE_REG + 1) /*69*/ +#define LAST_MASK_REG (FIRST_MASK_REG + 7) /*76*/ + /* Override this in other tm.h files to cope with various OS lossage requiring a frame pointer. */ #ifndef SUBTARGET_FRAME_POINTER_REQUIRED @@ -1229,6 +1238,8 @@ enum reg_class FLOAT_INT_REGS, INT_SSE_REGS, FLOAT_INT_SSE_REGS, + MASK_EVEX_REGS, + MASK_REGS, ALL_REGS, LIM_REG_CLASSES }; @@ -1250,6 +1261,8 @@ enum reg_class reg_classes_intersect_p ((CLASS), ALL_SSE_REGS) #define MAYBE_MMX_CLASS_P(CLASS) \ reg_classes_intersect_p ((CLASS), MMX_REGS) +#define MAYBE_MASK_CLASS_P(CLASS) \ + reg_classes_intersect_p ((CLASS), MASK_REGS) #define Q_CLASS_P(CLASS) \ reg_class_subset_p ((CLASS), Q_REGS) @@ -1282,6 +1295,8 @@ enum reg_class "FLOAT_INT_REGS", \ "INT_SSE_REGS", \ "FLOAT_INT_SSE_REGS", \ + "MASK_EVEX_REGS", \ + "MASK_REGS", \ "ALL_REGS" } /* Define which registers fit in which classes. This is an initializer @@ -1319,7 +1334,9 @@ enum reg_class { 0x11ffff, 0x1fe0, 0x0 }, /* FLOAT_INT_REGS */ \ { 0x1ff100ff,0xffffffe0, 0x1f }, /* INT_SSE_REGS */ \ { 0x1ff1ffff,0xffffffe0, 0x1f }, /* FLOAT_INT_SSE_REGS */ \ -{ 0xffffffff,0xffffffff, 0x1f } \ + { 0x0, 0x0,0x1fc0 }, /* MASK_EVEX_REGS */ \ + { 0x0, 0x0,0x1fe0 }, /* MASK_REGS */ \ +{ 0xffffffff,0xffffffff,0x1fff } \ } /* The same information, inverted: @@ -1377,6 +1394,8 @@ enum reg_class : (N) <= LAST_REX_SSE_REG ? (FIRST_REX_SSE_REG + (N) - 8) \ : (FIRST_EXT_REX_SSE_REG + (N) - 16)) +#define MASK_REGNO_P(N) IN_RANGE ((N), FIRST_MASK_REG, LAST_MASK_REG) +#define ANY_MASK_REG_P(X) (REG_P (X) && MASK_REGNO_P (REGNO (X))) #define SSE_FLOAT_MODE_P(MODE) \ ((TARGET_SSE && (MODE) == SFmode) || (TARGET_SSE2 && (MODE) == DFmode)) @@ -1933,7 +1952,8 @@ do { \ "xmm16", "xmm17", "xmm18", "xmm19", \ "xmm20", "xmm21", "xmm22", "xmm23", \ "xmm24", "xmm25", "xmm26", "xmm27", \ - "xmm28", "xmm29", "xmm30", "xmm31" } + "xmm28", "xmm29", "xmm30", "xmm31", \ + "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7" } #define REGISTER_NAMES HI_REGISTER_NAMES @@ -2119,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 3307b081aaa..e009bc96fc2 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -328,6 +328,14 @@ (XMM29_REG 66) (XMM30_REG 67) (XMM31_REG 68) + (MASK0_REG 69) + (MASK1_REG 70) + (MASK2_REG 71) + (MASK3_REG 72) + (MASK4_REG 73) + (MASK5_REG 74) + (MASK6_REG 75) + (MASK7_REG 76) ]) ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls @@ -341,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 @@ -360,7 +368,7 @@ sseishft,sseishft1,ssecmp,ssecomi, ssecvt,ssecvt1,sseicvt,sseins, sseshuf,sseshuf1,ssemuladd,sse4arg, - lwp, + lwp,mskmov,msklog, mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft" (const_string "other")) @@ -379,7 +387,7 @@ ssemul,sseimul,ssediv,sselog,sselog1, sseishft,sseishft1,ssecmp,ssecomi, ssecvt,ssecvt1,sseicvt,sseins, - sseshuf,sseshuf1,ssemuladd,sse4arg") + sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov") (const_string "sse") (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft") (const_string "mmx") @@ -390,7 +398,7 @@ ;; The (bounding maximum) length of an instruction immediate. (define_attr "length_immediate" "" (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave, - bitmanip,imulx") + bitmanip,imulx,msklog,mskmov") (const_int 0) (eq_attr "unit" "i387,sse,mmx") (const_int 0) @@ -451,7 +459,7 @@ ;; Set when 0f opcode prefix is used. (define_attr "prefix_0f" "" (if_then_else - (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip") + (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov") (eq_attr "unit" "sse,mmx")) (const_int 1) (const_int 0))) @@ -651,7 +659,7 @@ fmov,fcmp,fsgn, sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt, sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1, - mmx,mmxmov,mmxcmp,mmxcvt") + mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog") (match_operand 2 "memory_operand")) (const_string "load") (and (eq_attr "type" "icmov,ssemuladd,sse4arg") @@ -695,7 +703,7 @@ ;; Used to control the "enabled" attribute on a per-instruction basis. (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64, sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx, - avx2,noavx2,bmi2,fma4,fma,avx512f,noavx512f,fma_avx512f" + avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,fma_avx512f" (const_string "base")) (define_attr "enabled" "" @@ -718,6 +726,7 @@ (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX") (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2") (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2") + (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI") (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2") (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4") (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA") @@ -2213,8 +2222,8 @@ (const_string "SI")))]) (define_insn "*movhi_internal" - [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m") - (match_operand:HI 1 "general_operand" "r ,rn,rm,rn"))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,Yk,Yk,rm") + (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,Yk,Yk"))] "!(MEM_P (operands[0]) && MEM_P (operands[1]))" { switch (get_attr_type (insn)) @@ -2223,6 +2232,16 @@ /* movzwl is faster than movw on p2 due to partial word stalls, though not as fast as an aligned movl. */ return "movz{wl|x}\t{%1, %k0|%k0, %1}"; + + case TYPE_MSKMOV: + switch (which_alternative) + { + case 4: return "kmovw\t{%k1, %0|%0, %k1}"; + case 5: return "kmovw\t{%1, %0|%0, %1}"; + case 6: return "kmovw\t{%1, %k0|%k0, %1}"; + default: gcc_unreachable (); + } + default: if (get_attr_mode (insn) == MODE_SI) return "mov{l}\t{%k1, %k0|%k0, %k1}"; @@ -2240,11 +2259,17 @@ (and (eq_attr "alternative" "1,2") (match_operand:HI 1 "aligned_operand")) (const_string "imov") + (eq_attr "alternative" "4,5,6") + (const_string "mskmov") (and (match_test "TARGET_MOVX") (eq_attr "alternative" "0,2")) (const_string "imovx") ] (const_string "imov"))) + (set (attr "prefix") + (if_then_else (eq_attr "alternative" "4,5,6") + (const_string "vex") + (const_string "orig"))) (set (attr "mode") (cond [(eq_attr "type" "imovx") (const_string "SI") @@ -2269,8 +2294,8 @@ ;; register stall machines with, where we use QImode instructions, since ;; partial register stall can be caused there. Then we use movzx. (define_insn "*movqi_internal" - [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m") - (match_operand:QI 1 "general_operand" "q ,qn,qm,q,rn,qm,qn"))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m ,Yk,Yk,r") + (match_operand:QI 1 "general_operand" "q ,qn,qm,q,rn,qm,qn,r ,Yk,Yk"))] "!(MEM_P (operands[0]) && MEM_P (operands[1]))" { switch (get_attr_type (insn)) @@ -2278,6 +2303,16 @@ case TYPE_IMOVX: gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1])); return "movz{bl|x}\t{%1, %k0|%k0, %1}"; + + case TYPE_MSKMOV: + switch (which_alternative) + { + case 7: return "kmovw\t{%k1, %0|%0, %k1}"; + case 8: return "kmovw\t{%1, %0|%0, %1}"; + case 9: return "kmovw\t{%1, %k0|%k0, %1}"; + default: gcc_unreachable (); + } + default: if (get_attr_mode (insn) == MODE_SI) return "mov{l}\t{%k1, %k0|%k0, %k1}"; @@ -2297,11 +2332,17 @@ (const_string "imov") (eq_attr "alternative" "3,5") (const_string "imovx") + (eq_attr "alternative" "7,8,9") + (const_string "mskmov") (and (match_test "TARGET_MOVX") (eq_attr "alternative" "2")) (const_string "imovx") ] (const_string "imov"))) + (set (attr "prefix") + (if_then_else (eq_attr "alternative" "7,8,9") + (const_string "vex") + (const_string "orig"))) (set (attr "mode") (cond [(eq_attr "alternative" "3,4,5") (const_string "SI") @@ -7494,6 +7535,26 @@ operands[3] = gen_lowpart (QImode, operands[3]); }) +(define_split + [(set (match_operand:SWI12 0 "mask_reg_operand") + (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand") + (match_operand:SWI12 2 "mask_reg_operand"))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_AVX512F && reload_completed" + [(set (match_dup 0) + (any_logic:SWI12 (match_dup 1) + (match_dup 2)))]) + +(define_insn "*k<logic><mode>" + [(set (match_operand:SWI12 0 "mask_reg_operand" "=Yk") + (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand" "Yk") + (match_operand:SWI12 2 "mask_reg_operand" "Yk")))] + "TARGET_AVX512F" + "k<logic>w\t{%2, %1, %0|%0, %1, %2}"; + [(set_attr "mode" "<MODE>") + (set_attr "type" "msklog") + (set_attr "prefix" "vex")]) + ;; %%% This used to optimize known byte-wide and operations to memory, ;; and sometimes to QImode registers. If this is considered useful, ;; it should be done with splitters. @@ -7617,9 +7678,9 @@ (set_attr "mode" "SI")]) (define_insn "*andhi_1" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya") - (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm") - (match_operand:HI 2 "general_operand" "rn,rm,L"))) + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!Yk") + (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,Yk") + (match_operand:HI 2 "general_operand" "rn,rm,L,Yk"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (AND, HImode, operands)" { @@ -7628,34 +7689,38 @@ case TYPE_IMOVX: return "#"; + case TYPE_MSKLOG: + return "kandw\t{%2, %1, %0|%0, %1, %2}"; + default: gcc_assert (rtx_equal_p (operands[0], operands[1])); return "and{w}\t{%2, %0|%0, %2}"; } } - [(set_attr "type" "alu,alu,imovx") - (set_attr "length_immediate" "*,*,0") + [(set_attr "type" "alu,alu,imovx,msklog") + (set_attr "length_immediate" "*,*,0,*") (set (attr "prefix_rex") (if_then_else (and (eq_attr "type" "imovx") (match_operand 1 "ext_QIreg_operand")) (const_string "1") (const_string "*"))) - (set_attr "mode" "HI,HI,SI")]) + (set_attr "mode" "HI,HI,SI,HI")]) ;; %%% Potential partial reg stall on alternative 2. What to do? (define_insn "*andqi_1" - [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") - (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!Yk") + (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk") + (match_operand:QI 2 "general_operand" "qn,qmn,rn,Yk"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (AND, QImode, operands)" "@ and{b}\t{%2, %0|%0, %2} and{b}\t{%2, %0|%0, %2} - and{l}\t{%k2, %k0|%k0, %k2}" - [(set_attr "type" "alu") - (set_attr "mode" "QI,QI,SI")]) + and{l}\t{%k2, %k0|%k0, %k2} + kandw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "alu,alu,alu,msklog") + (set_attr "mode" "QI,QI,SI,HI")]) (define_insn "*andqi_1_slp" [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) @@ -7668,6 +7733,40 @@ [(set_attr "type" "alu1") (set_attr "mode" "QI")]) +(define_insn "kandn<mode>" + [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!Yk") + (and:SWI12 + (not:SWI12 + (match_operand:SWI12 1 "register_operand" "r,0,Yk")) + (match_operand:SWI12 2 "register_operand" "r,r,Yk"))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_AVX512F" + "@ + andn\t{%k2, %k1, %k0|%k0, %k1, %k2} + # + kandnw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "bmi,*,avx512f") + (set_attr "type" "bitmanip,*,msklog") + (set_attr "prefix" "*,*,vex") + (set_attr "btver2_decode" "direct,*,*") + (set_attr "mode" "<MODE>")]) + +(define_split + [(set (match_operand:SWI12 0 "general_reg_operand") + (and:SWI12 + (not:SWI12 + (match_dup 0)) + (match_operand:SWI12 1 "general_reg_operand"))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_AVX512F && !TARGET_BMI && reload_completed" + [(set (match_dup 0) + (not:HI (match_dup 0))) + (parallel [(set (match_dup 0) + (and:HI (match_dup 0) + (match_dup 1))) + (clobber (reg:CC FLAGS_REG))])] + "") + ;; Turn *anddi_1 into *andsi_1_zext if possible. (define_split [(set (match_operand:DI 0 "register_operand") @@ -7999,29 +8098,44 @@ "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") (define_insn "*<code><mode>_1" - [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm") - (any_or:SWI248 - (match_operand:SWI248 1 "nonimmediate_operand" "%0,0") - (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>"))) + [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm") + (any_or:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "%0,0") + (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" [(set_attr "type" "alu") (set_attr "mode" "<MODE>")]) +(define_insn "*<code>hi_1" + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!Yk") + (any_or:HI + (match_operand:HI 1 "nonimmediate_operand" "%0,0,Yk") + (match_operand:HI 2 "general_operand" "<g>,r<i>,Yk"))) + (clobber (reg:CC FLAGS_REG))] + "ix86_binary_operator_ok (<CODE>, HImode, operands)" + "@ + <logic>{w}\t{%2, %0|%0, %2} + <logic>{w}\t{%2, %0|%0, %2} + k<logic>w\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "alu,alu,msklog") + (set_attr "mode" "HI")]) + ;; %%% Potential partial reg stall on alternative 2. What to do? (define_insn "*<code>qi_1" - [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") - (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:QI 2 "general_operand" "qmn,qn,rn"))) + [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!Yk") + (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk") + (match_operand:QI 2 "general_operand" "qmn,qn,rn,Yk"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (<CODE>, QImode, operands)" "@ <logic>{b}\t{%2, %0|%0, %2} <logic>{b}\t{%2, %0|%0, %2} - <logic>{l}\t{%k2, %k0|%k0, %k2}" - [(set_attr "type" "alu") - (set_attr "mode" "QI,QI,SI")]) + <logic>{l}\t{%k2, %k0|%k0, %k2} + k<logic>w\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "alu,alu,alu,msklog") + (set_attr "mode" "QI,QI,SI,HI")]) ;; See comment for addsi_1_zext why we do use nonimmediate_operand (define_insn "*<code>si_1_zext" @@ -8071,6 +8185,74 @@ [(set_attr "type" "alu") (set_attr "mode" "<MODE>")]) +(define_insn "kxnor<mode>" + [(set (match_operand:SWI12 0 "register_operand" "=r,!Yk") + (not:SWI12 + (xor:SWI12 + (match_operand:SWI12 1 "register_operand" "0,Yk") + (match_operand:SWI12 2 "register_operand" "r,Yk"))))] + "TARGET_AVX512F" + "@ + # + kxnorw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "*,msklog") + (set_attr "prefix" "*,vex") + (set_attr "mode" "<MODE>")]) + +(define_split + [(set (match_operand:SWI12 0 "general_reg_operand") + (not:SWI12 + (xor:SWI12 + (match_dup 0) + (match_operand:SWI12 1 "general_reg_operand"))))] + "TARGET_AVX512F && reload_completed" + [(parallel [(set (match_dup 0) + (xor:HI (match_dup 0) + (match_dup 1))) + (clobber (reg:CC FLAGS_REG))]) + (set (match_dup 0) + (not:HI (match_dup 0)))] + "") + +(define_insn "kortestzhi" + [(set (reg:CCZ FLAGS_REG) + (compare:CCZ + (ior:HI + (match_operand:HI 0 "register_operand" "Yk") + (match_operand:HI 1 "register_operand" "Yk")) + (const_int 0)))] + "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)" + "kortestw\t{%1, %0|%0, %1}" + [(set_attr "mode" "HI") + (set_attr "type" "msklog") + (set_attr "prefix" "vex")]) + +(define_insn "kortestchi" + [(set (reg:CCC FLAGS_REG) + (compare:CCC + (ior:HI + (match_operand:HI 0 "register_operand" "Yk") + (match_operand:HI 1 "register_operand" "Yk")) + (const_int -1)))] + "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)" + "kortestw\t{%1, %0|%0, %1}" + [(set_attr "mode" "HI") + (set_attr "type" "msklog") + (set_attr "prefix" "vex")]) + +(define_insn "kunpckhi" + [(set (match_operand:HI 0 "register_operand" "=Yk") + (ior:HI + (ashift:HI + (match_operand:HI 1 "register_operand" "Yk") + (const_int 8)) + (zero_extend:HI (match_operand:QI 2 "register_operand" "Yk"))))] + "TARGET_AVX512F" + "kunpckbw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "mode" "HI") + (set_attr "type" "msklog") + (set_attr "prefix" "vex")]) + ;; See comment for addsi_1_zext why we do use nonimmediate_operand ;; ??? Special case for immediate operand is missing - it is tricky. (define_insn "*<code>si_2_zext" @@ -8640,23 +8822,38 @@ "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;") (define_insn "*one_cmpl<mode>2_1" - [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm") - (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))] + [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") + (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0")))] "ix86_unary_operator_ok (NOT, <MODE>mode, operands)" "not{<imodesuffix>}\t%0" [(set_attr "type" "negnot") (set_attr "mode" "<MODE>")]) +(define_insn "*one_cmplhi2_1" + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!Yk") + (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,Yk")))] + "ix86_unary_operator_ok (NOT, HImode, operands)" + "@ + not{w}\t%0 + knotw\t{%1, %0|%0, %1}" + [(set_attr "isa" "*,avx512f") + (set_attr "type" "negnot,msklog") + (set_attr "prefix" "*,vex") + (set_attr "mode" "HI")]) + ;; %%% Potential partial reg stall on alternative 1. What to do? (define_insn "*one_cmplqi2_1" - [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") - (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!Yk") + (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,Yk")))] "ix86_unary_operator_ok (NOT, QImode, operands)" "@ not{b}\t%0 - not{l}\t%k0" - [(set_attr "type" "negnot") - (set_attr "mode" "QI,SI")]) + not{l}\t%k0 + knotw\t{%1, %0|%0, %1}" + [(set_attr "isa" "*,*,avx512f") + (set_attr "type" "negnot,negnot,msklog") + (set_attr "prefix" "*,*,vex") + (set_attr "mode" "QI,SI,QI")]) ;; ??? Currently never generated - xor is used instead. (define_insn "*one_cmplsi2_1_zext" @@ -16423,11 +16620,11 @@ }) ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. - +;; Do not split instructions with mask registers. (define_split - [(set (match_operand 0 "register_operand") + [(set (match_operand 0 "general_reg_operand") (match_operator 3 "promotable_binary_operator" - [(match_operand 1 "register_operand") + [(match_operand 1 "general_reg_operand") (match_operand 2 "aligned_operand")])) (clobber (reg:CC FLAGS_REG))] "! TARGET_PARTIAL_REG_STALL && reload_completed @@ -16522,9 +16719,10 @@ operands[1] = gen_lowpart (SImode, operands[1]); }) +;; Do not split instructions with mask regs. (define_split - [(set (match_operand 0 "register_operand") - (not (match_operand 1 "register_operand")))] + [(set (match_operand 0 "general_reg_operand") + (not (match_operand 1 "general_reg_operand")))] "! TARGET_PARTIAL_REG_STALL && reload_completed && (GET_MODE (operands[0]) == HImode || (GET_MODE (operands[0]) == QImode diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 3959c3892e4..18f425c4b87 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -32,6 +32,11 @@ (and (match_code "reg") (not (match_test "ANY_FP_REGNO_P (REGNO (op))")))) +;; True if the operand is a GENERAL class register. +(define_predicate "general_reg_operand" + (and (match_code "reg") + (match_test "GENERAL_REG_P (op)"))) + ;; Return true if OP is a register operand other than an i387 fp register. (define_predicate "register_and_not_fp_reg_operand" (and (match_code "reg") @@ -52,6 +57,10 @@ (and (match_code "reg") (match_test "EXT_REX_SSE_REGNO_P (REGNO (op))"))) +;; True if the operand is an AVX-512 mask register. +(define_predicate "mask_reg_operand" + (and (match_code "reg") + (match_test "MASK_REGNO_P (REGNO (op))"))) ;; True if the operand is a Q_REGS class register. (define_predicate "q_regs_operand" diff --git a/gcc/config/i386/winnt-cxx.c b/gcc/config/i386/winnt-cxx.c index 323844afe41..92de46abd59 100644 --- a/gcc/config/i386/winnt-cxx.c +++ b/gcc/config/i386/winnt-cxx.c @@ -65,6 +65,13 @@ i386_pe_type_dllexport_p (tree decl) if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE && DECL_ARTIFICIAL (decl) && !DECL_THUNK_P (decl)) return false; + if (TREE_CODE (decl) == FUNCTION_DECL + && DECL_DECLARED_INLINE_P (decl)) + { + if (DECL_REALLY_EXTERN (decl) + || !flag_keep_inline_dllexport) + return false; + } return true; } diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index c9e3aa98a37..8cf6b3c527a 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -110,6 +110,11 @@ i386_pe_determine_dllexport_p (tree decl) if (!TREE_PUBLIC (decl)) return false; + if (TREE_CODE (decl) == FUNCTION_DECL + && DECL_DECLARED_INLINE_P (decl) + && !flag_keep_inline_dllexport) + return false; + if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))) return true; diff --git a/gcc/config/i386/x86-tune.def b/gcc/config/i386/x86-tune.def index e3a34ee7b2e..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) @@ -225,7 +222,8 @@ DEF_TUNE (X86_TUNE_GENERAL_REGS_SSE_SPILL, "general_regs_sse_spill", m_CORE_ALL) /* X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE: Try to avoid memory operands for a conditional move. */ -DEF_TUNE (X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE, "avoid_mem_opnd_for_cmove", m_ATOM) +DEF_TUNE (X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE, "avoid_mem_opnd_for_cmove", + m_ATOM | m_SLM) /* X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS: Try to split memory operand for fp converts to destination register. */ DEF_TUNE (X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS, "split_mem_opnd_for_fp_converts", diff --git a/gcc/config/lm32/uclinux-elf.h b/gcc/config/lm32/uclinux-elf.h index 3a556d7258d..a5e8163cf6f 100644 --- a/gcc/config/lm32/uclinux-elf.h +++ b/gcc/config/lm32/uclinux-elf.h @@ -77,3 +77,5 @@ #undef CC1_SPEC #define CC1_SPEC "%{G*} %{!fno-PIC:-fPIC}" +#undef TARGET_LIBC_HAS_FUNCTION +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function diff --git a/gcc/config/m68k/uclinux.h b/gcc/config/m68k/uclinux.h index 8d743126547..b1af7d2c585 100644 --- a/gcc/config/m68k/uclinux.h +++ b/gcc/config/m68k/uclinux.h @@ -67,3 +67,6 @@ along with GCC; see the file COPYING3. If not see sections. */ #undef M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P #define M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 1 + +#undef TARGET_LIBC_HAS_FUNCTION +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function diff --git a/gcc/config/moxie/uclinux.h b/gcc/config/moxie/uclinux.h index 498037e8072..85c65f257ce 100644 --- a/gcc/config/moxie/uclinux.h +++ b/gcc/config/moxie/uclinux.h @@ -37,3 +37,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --wrap=mmap --wrap=munmap --wrap=alloca\ %{fmudflapth: --wrap=pthread_create\ }} %{fmudflap|fmudflapth: --wrap=main}" + +#undef TARGET_LIBC_HAS_FUNCTION +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function diff --git a/gcc/config/msp430/README.txt b/gcc/config/msp430/README.txt new file mode 100644 index 00000000000..e7343cfcaf1 --- /dev/null +++ b/gcc/config/msp430/README.txt @@ -0,0 +1,7 @@ +Random Notes +------------ + +The MSP430 port does not use leading underscores. However, the +assembler has no way of differentiating between, for example, register +R12 and symbol R12. So, if you do "int r12;" in your C program, you +may get an assembler error, and will certainly have runtime problems. diff --git a/gcc/config/msp430/constraints.md b/gcc/config/msp430/constraints.md new file mode 100644 index 00000000000..ea53481bfdb --- /dev/null +++ b/gcc/config/msp430/constraints.md @@ -0,0 +1,72 @@ +;; Machine Description for TI MSP43* processors +;; Copyright (C) 2013 Free Software Foundation, Inc. +;; Contributed by Red Hat. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; <http://www.gnu.org/licenses/>. + +(define_register_constraint "R12" "R12_REGS" + "Register R12.") + +(define_register_constraint "R13" "R13_REGS" + "Register R13.") + +(define_constraint "K" + "Integer constant 1." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, 1, 1)"))) + +(define_constraint "L" + "Integer constant -1^20..1^19." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, -1 << 20, 1 << 19)"))) + +(define_constraint "M" + "Integer constant 1-4." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, 1, 4)"))) + +;; We do not allow arbitrary constants, eg symbols or labels, +;; because their address may be above the 16-bit address limit +;; supported by the offset used in the MOVA instruction. +(define_constraint "Ya" + "Memory reference, any type, but restricted range of constants" + (and (match_code "mem") + (ior (match_code "reg" "0") + (and (match_code "plus" "0") + (match_code "reg" "00") + (match_test ("CONST_INT_P (XEXP (XEXP (op, 0), 1))"))) + (match_test "CONSTANT_P (XEXP (op, 0))") + ))) + +(define_constraint "Yl" + "Memory reference, labels only." + (and (match_code "mem") + (match_code "label_ref" "0"))) + + +;; These are memory references that are safe to use with the X suffix, +;; because we know/assume they need not index across the 64k boundary. +(define_constraint "Ys" + "Memory reference, stack only." + (and (match_code "mem") + (ior + (and (match_code "plus" "0") + (and (match_code "reg" "00") + (match_test ("CONST_INT_P (XEXP (XEXP (op, 0), 1))")) + (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-c.c b/gcc/config/msp430/msp430-c.c new file mode 100644 index 00000000000..808e02c5ffd --- /dev/null +++ b/gcc/config/msp430/msp430-c.c @@ -0,0 +1,36 @@ +/* MSP430 C-specific support + Copyright (C) 2013 Free Software Foundation, Inc. + Contributed by Red Hat, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "c-family/c-common.h" +#include "msp430-protos.h" + +/* Implements REGISTER_TARGET_PRAGMAS. */ +void +msp430_register_pragmas (void) +{ + c_register_addr_space ("__near", ADDR_SPACE_NEAR); + if (msp430x) + c_register_addr_space ("__far", ADDR_SPACE_FAR); +} diff --git a/gcc/config/msp430/msp430-modes.def b/gcc/config/msp430/msp430-modes.def new file mode 100644 index 00000000000..9e7b70127fd --- /dev/null +++ b/gcc/config/msp430/msp430-modes.def @@ -0,0 +1,3 @@ +/* 20-bit address */ +PARTIAL_INT_MODE (SI); + diff --git a/gcc/config/msp430/msp430-protos.h b/gcc/config/msp430/msp430-protos.h new file mode 100644 index 00000000000..f116855ecae --- /dev/null +++ b/gcc/config/msp430/msp430-protos.h @@ -0,0 +1,46 @@ +/* Exported function prototypes from the TI MSP430 backend. + Copyright (C) 2012-2013 Free Software Foundation, Inc. + Contributed by Red Hat. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#ifndef GCC_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); +void msp430_expand_prologue (void); +const char * msp430x_extendhisi (rtx *); +void msp430_fixup_compare_operands (enum machine_mode, rtx *); +int msp430_hard_regno_mode_ok (int, enum machine_mode); +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); +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 new file mode 100644 index 00000000000..9384d32457a --- /dev/null +++ b/gcc/config/msp430/msp430.c @@ -0,0 +1,2044 @@ +/* Subroutines used for code generation on TI MSP430 processors. + Copyright (C) 2012-2013 Free Software Foundation, Inc. + Contributed by Red Hat. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "rtl.h" +#include "regs.h" +#include "hard-reg-set.h" +#include "insn-config.h" +#include "conditions.h" +#include "output.h" +#include "insn-attr.h" +#include "flags.h" +#include "function.h" +#include "expr.h" +#include "optabs.h" +#include "libfuncs.h" +#include "recog.h" +#include "diagnostic-core.h" +#include "toplev.h" +#include "reload.h" +#include "df.h" +#include "ggc.h" +#include "tm_p.h" +#include "debug.h" +#include "target.h" +#include "target-def.h" +#include "langhooks.h" +#include "msp430-protos.h" +#include "dumpfile.h" +#include "opts.h" + + + +static void msp430_compute_frame_info (void); + + + +/* Run-time Target Specification */ + +bool msp430x = false; + +struct GTY(()) machine_function +{ + /* If set, the rest of the fields have been computed. */ + int computed; + /* Which registers need to be saved in the pro/epilogue. */ + int need_to_save [FIRST_PSEUDO_REGISTER]; + + /* These fields describe the frame layout... */ + /* arg pointer */ + /* 2/4 bytes for saved PC */ + int framesize_regs; + /* frame pointer */ + int framesize_locals; + int framesize_outgoing; + /* stack pointer */ + int framesize; + + /* How much we adjust the stack when returning from an exception + handler. */ + rtx eh_stack_adjust; +}; + +/* This is our init_machine_status, as set in + msp_option_override. */ +static struct machine_function * +msp430_init_machine_status (void) +{ + struct machine_function *m; + + m = ggc_alloc_cleared_machine_function (); + + return m; +} + +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION msp430_handle_option + +bool +msp430_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED, + location_t loc ATTRIBUTE_UNUSED) +{ + return true; +} + +#undef TARGET_OPTION_OVERRIDE +#define TARGET_OPTION_OVERRIDE msp430_option_override + +static void +msp430_option_override (void) +{ + init_machine_status = msp430_init_machine_status; + + if (target_cpu + && (strstr (target_cpu, "430x") + || strstr (target_cpu, "430X"))) + msp430x = true; + + if (TARGET_LARGE && !msp430x) + error ("-mlarge requires a 430X-compatible -mmcu="); + + if (flag_exceptions || flag_non_call_exceptions + || flag_unwind_tables || flag_asynchronous_unwind_tables) + flag_omit_frame_pointer = false; + else + flag_omit_frame_pointer = true; + + /* This is a hack to work around a problem with the newlib build + mechanism. Newlib always appends CFLAGS to the end of the GCC + command line and always sets -O2 in CFLAGS. Thus it is not + possible to build newlib with -Os enabled. Until now... */ + if (TARGET_OPT_SPACE && optimize < 3) + optimize_size = 1; +} + + + +/* Storage Layout */ + +#undef TARGET_MS_BITFIELD_LAYOUT_P +#define TARGET_MS_BITFIELD_LAYOUT_P msp430_ms_bitfield_layout_p + +bool +msp430_ms_bitfield_layout_p (const_tree record_type ATTRIBUTE_UNUSED) +{ + return false; +} + + + +/* Register Usage */ + +/* Implements HARD_REGNO_NREGS. MSP430X registers can hold a single + PSImode value, but not an SImode value. */ +int +msp430_hard_regno_nregs (int regno ATTRIBUTE_UNUSED, + enum machine_mode mode) +{ + if (mode == PSImode && msp430x) + return 1; + return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) + / UNITS_PER_WORD); +} + +/* Implements HARD_REGNO_MODE_OK. */ +int +msp430_hard_regno_mode_ok (int regno ATTRIBUTE_UNUSED, + enum machine_mode mode) +{ + return regno <= (ARG_POINTER_REGNUM - msp430_hard_regno_nregs (regno, mode)); +} + +/* Implements MODES_TIEABLE_P. */ +bool +msp430_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2) +{ + if ((mode1 == PSImode || mode2 == SImode) + || (mode1 == SImode || mode2 == PSImode)) + return false; + + return ((GET_MODE_CLASS (mode1) == MODE_FLOAT + || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT) + == (GET_MODE_CLASS (mode2) == MODE_FLOAT + || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT)); +} + +#undef TARGET_FRAME_POINTER_REQUIRED +#define TARGET_FRAME_POINTER_REQUIRED msp430_frame_pointer_required + +static bool +msp430_frame_pointer_required (void) +{ + return false; +} + +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE msp430_can_eliminate + +static bool +msp430_can_eliminate (const int from_reg ATTRIBUTE_UNUSED, + const int to_reg ATTRIBUTE_UNUSED) +{ + return true; +} + +/* Implements INITIAL_ELIMINATION_OFFSET. */ +int +msp430_initial_elimination_offset (int from, int to) +{ + int rv = 0; /* As if arg to arg. */ + + msp430_compute_frame_info (); + + switch (to) + { + case STACK_POINTER_REGNUM: + rv += cfun->machine->framesize_outgoing; + rv += cfun->machine->framesize_locals; + /* Fall through. */ + case FRAME_POINTER_REGNUM: + rv += cfun->machine->framesize_regs; + /* Allow for the saved return address. */ + rv += (TARGET_LARGE ? 4 : 2); + /* NB/ No need to allow for crtl->args.pretend_args_size. + GCC does that for us. */ + break; + default: + gcc_unreachable (); + } + + switch (from) + { + case FRAME_POINTER_REGNUM: + /* Allow for the fall through above. */ + rv -= (TARGET_LARGE ? 4 : 2); + rv -= cfun->machine->framesize_regs; + case ARG_POINTER_REGNUM: + break; + default: + gcc_unreachable (); + } + + return rv; +} + +/* Named Address Space support */ + + +/* Return the appropriate mode for a named address pointer. */ +#undef TARGET_ADDR_SPACE_POINTER_MODE +#define TARGET_ADDR_SPACE_POINTER_MODE msp430_addr_space_pointer_mode +#undef TARGET_ADDR_SPACE_ADDRESS_MODE +#define TARGET_ADDR_SPACE_ADDRESS_MODE msp430_addr_space_pointer_mode + +static enum machine_mode +msp430_addr_space_pointer_mode (addr_space_t addrspace) +{ + switch (addrspace) + { + default: + case ADDR_SPACE_GENERIC: + return Pmode; + case ADDR_SPACE_NEAR: + return HImode; + case ADDR_SPACE_FAR: + return PSImode; + } +} + +/* Function pointers are stored in unwind_word sized + variables, so make sure that unwind_word is big enough. */ +#undef TARGET_UNWIND_WORD_MODE +#define TARGET_UNWIND_WORD_MODE msp430_unwind_word_mode + +static enum machine_mode +msp430_unwind_word_mode (void) +{ + return TARGET_LARGE ? SImode : HImode; +} + +/* Determine if one named address space is a subset of another. */ +#undef TARGET_ADDR_SPACE_SUBSET_P +#define TARGET_ADDR_SPACE_SUBSET_P msp430_addr_space_subset_p +static bool +msp430_addr_space_subset_p (addr_space_t subset, addr_space_t superset) +{ + if (subset == superset) + return true; + else + return (subset != ADDR_SPACE_FAR && superset == ADDR_SPACE_FAR); +} + +#undef TARGET_ADDR_SPACE_CONVERT +#define TARGET_ADDR_SPACE_CONVERT msp430_addr_space_convert +/* Convert from one address space to another. */ +static rtx +msp430_addr_space_convert (rtx op, tree from_type, tree to_type) +{ + addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type)); + addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type)); + rtx result; + + if (to_as != ADDR_SPACE_FAR && from_as == ADDR_SPACE_FAR) + { + /* This is unpredictable, as we're truncating off usable address + bits. */ + + if (CONSTANT_P (op)) + return gen_rtx_CONST (HImode, op); + + result = gen_reg_rtx (HImode); + emit_insn (gen_truncpsihi2 (result, op)); + return result; + } + else if (to_as == ADDR_SPACE_FAR && from_as != ADDR_SPACE_FAR) + { + /* This always works. */ + + if (CONSTANT_P (op)) + return gen_rtx_CONST (PSImode, op); + + result = gen_reg_rtx (PSImode); + emit_insn (gen_zero_extendhipsi2 (result, op)); + return result; + } + else + gcc_unreachable (); +} + +/* Stack Layout and Calling Conventions. */ + +/* For each function, we list the gcc version and the TI version on + each line, where we're converting the function names. */ +static char const * const special_convention_function_names [] = +{ + "__muldi3", "__mspabi_mpyll", + "__udivdi3", "__mspabi_divull", + "__umoddi3", "__mspabi_remull", + "__divdi3", "__mspabi_divlli", + "__moddi3", "__mspabi_remlli", + "__mspabi_srall", + "__mspabi_srlll", + "__mspabi_sllll", + "__adddf3", "__mspabi_addd", + "__subdf3", "__mspabi_subd", + "__muldf3", "__mspabi_mpyd", + "__divdf3", "__mspabi_divd", + "__mspabi_cmpd", + NULL +}; + +/* TRUE if the function passed is a "speical" function. Special + functions pass two DImode parameters in registers. */ +static bool +msp430_special_register_convention_p (const char *name) +{ + int i; + + for (i = 0; special_convention_function_names [i]; i++) + if (! strcmp (name, special_convention_function_names [i])) + return true; + + return false; +} + +#undef TARGET_FUNCTION_VALUE_REGNO_P +#define TARGET_FUNCTION_VALUE_REGNO_P msp430_function_value_regno_p + +bool +msp430_function_value_regno_p (unsigned int regno) +{ + return regno == 12; +} + + +#undef TARGET_FUNCTION_VALUE +#define TARGET_FUNCTION_VALUE msp430_function_value + +rtx +msp430_function_value (const_tree ret_type, + const_tree fn_decl_or_type ATTRIBUTE_UNUSED, + bool outgoing ATTRIBUTE_UNUSED) +{ + return gen_rtx_REG (TYPE_MODE (ret_type), 12); +} + +#undef TARGET_LIBCALL_VALUE +#define TARGET_LIBCALL_VALUE msp430_libcall_value + +rtx +msp430_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED) +{ + return gen_rtx_REG (mode, 12); +} + +/* Implements INIT_CUMULATIVE_ARGS. */ +void +msp430_init_cumulative_args (CUMULATIVE_ARGS *ca, + tree fntype ATTRIBUTE_UNUSED, + rtx libname ATTRIBUTE_UNUSED, + tree fndecl ATTRIBUTE_UNUSED, + int n_named_args ATTRIBUTE_UNUSED) +{ + const char *fname; + memset (ca, 0, sizeof(*ca)); + + ca->can_split = 1; + + if (fndecl) + fname = IDENTIFIER_POINTER (DECL_NAME (fndecl)); + else if (libname) + fname = XSTR (libname, 0); + else + fname = NULL; + + if (fname && msp430_special_register_convention_p (fname)) + ca->special_p = 1; +} + +/* Helper function for argument passing; this function is the common + code that determines where an argument will be passed. */ +static void +msp430_evaluate_arg (cumulative_args_t cap, + enum machine_mode mode, + const_tree type ATTRIBUTE_UNUSED, + bool named) +{ + CUMULATIVE_ARGS *ca = get_cumulative_args (cap); + int nregs = GET_MODE_SIZE (mode); + int i; + + ca->reg_count = 0; + ca->mem_count = 0; + + if (!named) + return; + + if (mode == PSImode) + nregs = 1; + else + nregs = (nregs + 1) / 2; + + if (ca->special_p) + { + /* Function is passed two DImode operands, in R8:R11 and + R12:15. */ + ca->start_reg = 8; + ca->reg_count = 4; + return; + } + + switch (nregs) + { + case 1: + for (i = 0; i < 4; i++) + if (! ca->reg_used [i]) + { + ca->reg_count = 1; + ca->start_reg = CA_FIRST_REG + i; + return; + } + break; + case 2: + for (i = 0; i < 3; i++) + if (! ca->reg_used [i] && ! ca->reg_used [i + 1]) + { + ca->reg_count = 2; + ca->start_reg = CA_FIRST_REG + i; + return; + } + if (! ca->reg_used [3] && ca->can_split) + { + ca->reg_count = 1; + ca->mem_count = 2; + ca->start_reg = CA_FIRST_REG + 3; + return; + } + break; + case 3: + case 4: + ca->can_split = 0; + if (! ca->reg_used [0] + && ! ca->reg_used [1] + && ! ca->reg_used [2] + && ! ca->reg_used [3]) + { + ca->reg_count = 4; + ca->start_reg = CA_FIRST_REG; + return; + } + break; + } +} + +#undef TARGET_PROMOTE_PROTOTYPES +#define TARGET_PROMOTE_PROTOTYPES msp430_promote_prototypes + +bool +msp430_promote_prototypes (const_tree fntype ATTRIBUTE_UNUSED) +{ + return false; +} + +#undef TARGET_FUNCTION_ARG +#define TARGET_FUNCTION_ARG msp430_function_arg + +rtx +msp430_function_arg (cumulative_args_t cap, + enum machine_mode mode, + const_tree type, + bool named) +{ + CUMULATIVE_ARGS *ca = get_cumulative_args (cap); + + msp430_evaluate_arg (cap, mode, type, named); + + if (ca->reg_count) + return gen_rtx_REG (mode, ca->start_reg); + + return 0; +} + +#undef TARGET_ARG_PARTIAL_BYTES +#define TARGET_ARG_PARTIAL_BYTES msp430_arg_partial_bytes + +int +msp430_arg_partial_bytes (cumulative_args_t cap, + enum machine_mode mode, + tree type, + bool named) +{ + CUMULATIVE_ARGS *ca = get_cumulative_args (cap); + + msp430_evaluate_arg (cap, mode, type, named); + + if (ca->reg_count && ca->mem_count) + return ca->reg_count * UNITS_PER_WORD; + + return 0; +} + +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE msp430_pass_by_reference + +static bool +msp430_pass_by_reference (cumulative_args_t cap ATTRIBUTE_UNUSED, + enum machine_mode mode, + const_tree type, + bool named ATTRIBUTE_UNUSED) +{ + return (mode == BLKmode + || (type && TREE_CODE (type) == RECORD_TYPE) + || (type && TREE_CODE (type) == UNION_TYPE)); +} + +#undef TARGET_CALLEE_COPIES +#define TARGET_CALLEE_COPIES msp430_callee_copies + +static bool +msp430_callee_copies (cumulative_args_t cap ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + const_tree type ATTRIBUTE_UNUSED, + bool named ATTRIBUTE_UNUSED) +{ + return true; +} + +#undef TARGET_FUNCTION_ARG_ADVANCE +#define TARGET_FUNCTION_ARG_ADVANCE msp430_function_arg_advance + +void +msp430_function_arg_advance (cumulative_args_t cap, + enum machine_mode mode, + const_tree type, + bool named) +{ + CUMULATIVE_ARGS *ca = get_cumulative_args (cap); + int i; + + msp430_evaluate_arg (cap, mode, type, named); + + if (ca->start_reg >= CA_FIRST_REG) + for (i = 0; i < ca->reg_count; i ++) + ca->reg_used [i + ca->start_reg - CA_FIRST_REG] = 1; + + ca->special_p = 0; +} + +#undef TARGET_FUNCTION_ARG_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY msp430_function_arg_boundary + +static unsigned int +msp430_function_arg_boundary (enum machine_mode mode, const_tree type) +{ + if (mode == BLKmode + && int_size_in_bytes (type) > 1) + return 16; + if (GET_MODE_BITSIZE (mode) > 8) + return 16; + return 8; +} + +#undef TARGET_RETURN_IN_MEMORY +#define TARGET_RETURN_IN_MEMORY msp430_return_in_memory + +static bool +msp430_return_in_memory (const_tree ret_type, const_tree fntype ATTRIBUTE_UNUSED) +{ + enum machine_mode mode = TYPE_MODE (ret_type); + + if (mode == BLKmode + || (fntype && TREE_CODE (TREE_TYPE (fntype)) == RECORD_TYPE) + || (fntype && TREE_CODE (TREE_TYPE (fntype)) == UNION_TYPE)) + return true; + + if (GET_MODE_SIZE (mode) > 8) + return true; + + return false; +} + +#undef TARGET_GET_RAW_ARG_MODE +#define TARGET_GET_RAW_ARG_MODE msp430_get_raw_arg_mode + +static enum machine_mode +msp430_get_raw_arg_mode (int regno) +{ + return (regno == ARG_POINTER_REGNUM) ? VOIDmode : Pmode; +} + +#undef TARGET_GET_RAW_RESULT_MODE +#define TARGET_GET_RAW_RESULT_MODE msp430_get_raw_result_mode + +static enum machine_mode +msp430_get_raw_result_mode (int regno ATTRIBUTE_UNUSED) +{ + return Pmode; +} + +/* Addressing Modes */ + +#undef TARGET_LEGITIMATE_ADDRESS_P +#define TARGET_LEGITIMATE_ADDRESS_P msp430_legitimate_address_p + +static bool +reg_ok_for_addr (rtx r, bool strict) +{ + int rn = REGNO (r); + + if (strict && rn >= FIRST_PSEUDO_REGISTER) + rn = reg_renumber [rn]; + if (strict && 0 <= rn && rn < FIRST_PSEUDO_REGISTER) + return true; + if (!strict) + return true; + return false; +} + +bool +msp430_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, + rtx x ATTRIBUTE_UNUSED, + bool strict ATTRIBUTE_UNUSED) +{ + switch (GET_CODE (x)) + { + case MEM: + return false; + + case PLUS: + if (REG_P (XEXP (x, 0))) + { + if (GET_MODE (x) != GET_MODE (XEXP (x, 0))) + return false; + if (!reg_ok_for_addr (XEXP (x, 0), strict)) + return false; + switch (GET_CODE (XEXP (x, 1))) + { + case CONST: + case SYMBOL_REF: + case CONST_INT: + return true; + default: + return false; + } + } + return false; + + case REG: + if (!reg_ok_for_addr (x, strict)) + return false; + /* else... */ + case CONST: + case SYMBOL_REF: + case CONST_INT: + return true; + + default: + return false; + } +} + +#undef TARGET_LEGITIMATE_CONSTANT_P +#define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant + +static bool +msp430_legitimate_constant (enum machine_mode mode, rtx x) +{ + return ! CONST_INT_P (x) + || mode != PSImode + /* GCC does not know the width of the PSImode, so make + sure that it does not try to use a constant value that + is out of range. */ + || (INTVAL (x) < (1 << 20) && INTVAL (x) >= (-1 << 20)); +} + + +#undef TARGET_RTX_COSTS +#define TARGET_RTX_COSTS msp430_rtx_costs + +static bool msp430_rtx_costs (rtx x ATTRIBUTE_UNUSED, + int code, + int outer_code ATTRIBUTE_UNUSED, + int opno ATTRIBUTE_UNUSED, + int * total, + bool speed ATTRIBUTE_UNUSED) +{ + switch (code) + { + case SIGN_EXTEND: + if (GET_MODE (x) == SImode && outer_code == SET) + { + *total = COSTS_N_INSNS (4); + return true; + } + break; + case ASHIFT: + case ASHIFTRT: + case LSHIFTRT: + if (!msp430x) + { + *total = COSTS_N_INSNS (100); + return true; + } + break; + } + return false; +} + +/* Function Entry and Exit */ + +/* The MSP430 call frame looks like this: + + <higher addresses> + +--------------------+ + | | + | Stack Arguments | + | | + +--------------------+ <-- "arg pointer" + | | + | 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) + | | + +--------------------+ <-- "frame pointer" + | | + | Locals | + | | + +--------------------+ + | | + | Outgoing Args | + | | + +--------------------+ <-- SP during function + <lower addresses> + +*/ + +/* We use this to wrap all emitted insns in the prologue, so they get + the "frame-related" (/f) flag set. */ +static rtx +F (rtx x) +{ + RTX_FRAME_RELATED_P (x) = 1; + return x; +} + +/* This is the one spot that decides if a register is to be saved and + restored in the prologue/epilogue. */ +static bool +msp430_preserve_reg_p (int regno) +{ + /* PC, SP, SR, and the constant generator. */ + if (regno <= 3) + return false; + + /* FIXME: add interrupt, EH, etc. */ + if (crtl->calls_eh_return) + return true; + + /* Shouldn't be more than the above, but just in case... */ + 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; + + return false; +} + +/* Compute all the frame-related fields in our machine_function + structure. */ +static void +msp430_compute_frame_info (void) +{ + int i; + + cfun->machine->computed = 1; + cfun->machine->framesize_regs = 0; + cfun->machine->framesize_locals = get_frame_size (); + cfun->machine->framesize_outgoing = crtl->outgoing_args_size; + + for (i = 0; i < ARG_POINTER_REGNUM; i ++) + if (msp430_preserve_reg_p (i)) + { + cfun->machine->need_to_save [i] = 1; + cfun->machine->framesize_regs += (TARGET_LARGE ? 4 : 2); + } + else + cfun->machine->need_to_save [i] = 0; + + if ((cfun->machine->framesize_locals + cfun->machine->framesize_outgoing) & 1) + cfun->machine->framesize_locals ++; + + cfun->machine->framesize = (cfun->machine->framesize_regs + + cfun->machine->framesize_locals + + 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 + +static void +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); + fprintf (outfile, "; framesize: %d\n", cfun->machine->framesize); + fprintf (outfile, "; elim ap -> fp %d\n", msp430_initial_elimination_offset (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM)); + fprintf (outfile, "; elim fp -> sp %d\n", msp430_initial_elimination_offset (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM)); + + n = 0; + fprintf (outfile, "; saved regs:"); + for (r = 0; r < ARG_POINTER_REGNUM; r++) + if (cfun->machine->need_to_save [r]) + { + fprintf (outfile, " %s", reg_names [r]); + n = 1; + } + if (n == 0) + fprintf (outfile, "(none)"); + fprintf (outfile, "\n"); +} + +/* Common code to change the stack pointer. */ +static void +increment_stack (HOST_WIDE_INT amount) +{ + rtx inc; + rtx sp = stack_pointer_rtx; + + if (amount == 0) + return; + + if (amount < 0) + { + inc = GEN_INT (- amount); + if (TARGET_LARGE) + F (emit_insn (gen_subpsi3 (sp, sp, inc))); + else + F (emit_insn (gen_subhi3 (sp, sp, inc))); + } + else + { + inc = GEN_INT (amount); + if (TARGET_LARGE) + emit_insn (gen_addpsi3 (sp, sp, inc)); + else + emit_insn (gen_addhi3 (sp, sp, inc)); + } +} + +/* 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) +{ + int i, j; + int fs; + /* Always use stack_pointer_rtx instead of calling + rtx_gen_REG ourselves. Code elsewhere in GCC assumes + that there is a single rtx representing the stack pointer, + namely stack_pointer_rtx, and uses == to recognize it. */ + 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 (); + + if (flag_stack_usage_info) + current_function_static_stack_size = cfun->machine->framesize; + + if (crtl->args.pretend_args_size) + { + rtx note; + + gcc_assert (crtl->args.pretend_args_size == 2); + + p = emit_insn (gen_grow_and_swap ()); + + /* Document the stack decrement... */ + note = F (gen_rtx_SET (Pmode, stack_pointer_rtx, + gen_rtx_MINUS (Pmode, stack_pointer_rtx, GEN_INT (2)))); + add_reg_note (p, REG_FRAME_RELATED_EXPR, note); + + /* ...and the establishment of a new location for the return address. */ + note = F (gen_rtx_SET (Pmode, gen_rtx_MEM (Pmode, + gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (-2))), + pc_rtx)); + add_reg_note (p, REG_CFA_OFFSET, note); + F (p); + } + + for (i = 15; i >= 4; i--) + if (cfun->machine->need_to_save [i]) + { + int seq, count; + rtx note; + + for (seq = i - 1; seq >= 4 && cfun->machine->need_to_save[seq]; seq --) + ; + count = i - seq; + + if (msp430x) + { + /* Note: with TARGET_LARGE we still use PUSHM as PUSHX.A is two bytes bigger. */ + p = F (emit_insn (gen_pushm (gen_rtx_REG (Pmode, i), + GEN_INT (count)))); + + note = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1)); + + XVECEXP (note, 0, 0) + = F (gen_rtx_SET (VOIDmode, + stack_pointer_rtx, + gen_rtx_PLUS (Pmode, + stack_pointer_rtx, + GEN_INT (count * (TARGET_LARGE ? -4 : -2))))); + + /* *sp-- = R[i-j] */ + /* sp+N R10 + ... + sp R4 */ + for (j = 0; j < count; j ++) + { + rtx addr; + int ofs = (count - j - 1) * (TARGET_LARGE ? 4 : 2); + + if (ofs) + addr = gen_rtx_PLUS (Pmode, sp, GEN_INT (ofs)); + else + addr = stack_pointer_rtx; + + XVECEXP (note, 0, j + 1) = + F (gen_rtx_SET (VOIDmode, + gen_rtx_MEM (Pmode, addr), + gen_rtx_REG (Pmode, i - j)) ); + } + + add_reg_note (p, REG_FRAME_RELATED_EXPR, note); + i -= count - 1; + } + else + F (emit_insn (gen_push (gen_rtx_REG (Pmode, i)))); + } + + if (frame_pointer_needed) + F (emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM), sp)); + + fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing; + + increment_stack (- fs); + + emit_insn (gen_prologue_end_marker ()); +} + +void +msp430_expand_epilogue (int is_eh) +{ + int i; + int fs; + int helper_n = 0; + + if (is_naked_func ()) + return; + + if (cfun->machine->need_to_save [10]) + { + /* Check for a helper function. */ + helper_n = 7; /* for when the loop below never sees a match. */ + for (i = 9; i >= 4; i--) + if (!cfun->machine->need_to_save [i]) + { + helper_n = 10 - i; + for (; i >= 4; i--) + if (cfun->machine->need_to_save [i]) + { + helper_n = 0; + break; + } + break; + } + } + + emit_insn (gen_epilogue_start_marker ()); + + fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing; + + increment_stack (fs); + + if (is_eh) + { + /* We need to add the right "SP" register save just after the + regular ones, so that when we pop it off we're in the EH + return frame, not this one. This overwrites our own return + address, but we're not going to be returning anyway. */ + rtx r12 = gen_rtx_REG (Pmode, 12); + rtx (*addPmode)(rtx, rtx, rtx) = TARGET_LARGE ? gen_addpsi3 : gen_addhi3; + + /* R12 will hold the new SP. */ + i = cfun->machine->framesize_regs; + emit_move_insn (r12, stack_pointer_rtx); + emit_insn (addPmode (r12, r12, EH_RETURN_STACKADJ_RTX)); + emit_insn (addPmode (r12, r12, GEN_INT (i))); + emit_move_insn (gen_rtx_MEM (Pmode, plus_constant (Pmode, stack_pointer_rtx, i)), r12); + } + + for (i = 4; i <= 15; i++) + if (cfun->machine->need_to_save [i]) + { + int seq, count; + + for (seq = i + 1; seq <= 15 && cfun->machine->need_to_save[seq]; seq ++) + ; + count = seq - i; + + if (msp430x) + { + /* Note: With TARGET_LARGE we still use POPM as POPX.A is two + bytes bigger. + Note: See the popm pattern for the explanation of the strange + arguments. */ + emit_insn (gen_popm (stack_pointer_rtx, GEN_INT (~(seq - 1)), + GEN_INT (count))); + 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 + && !is_eh) + { + emit_insn (gen_epilogue_helper (GEN_INT (helper_n))); + return; + } + else + emit_insn (gen_pop (gen_rtx_REG (Pmode, i))); + } + + if (is_eh) + { + /* Also pop SP, which puts us into the EH return frame. Except + that you can't "pop" sp, you have to just load it off the + stack. */ + emit_move_insn (stack_pointer_rtx, gen_rtx_MEM (Pmode, stack_pointer_rtx)); + } + + 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 ()); +} + +/* Implements EH_RETURN_STACKADJ_RTX. Saved and used later in + m32c_emit_eh_epilogue. */ +rtx +msp430_eh_return_stackadj_rtx (void) +{ + if (!cfun->machine->eh_stack_adjust) + { + rtx sa; + + sa = gen_rtx_REG (Pmode, 15); + cfun->machine->eh_stack_adjust = sa; + } + return cfun->machine->eh_stack_adjust; +} + +/* This function is called before reload, to "fix" the stack in + preparation for an EH return. */ +void +msp430_expand_eh_return (rtx eh_handler) +{ + /* These are all Pmode */ + rtx ap, sa, ra, tmp; + + ap = arg_pointer_rtx; + sa = msp430_eh_return_stackadj_rtx (); + ra = eh_handler; + + tmp = ap; + tmp = gen_rtx_PLUS (Pmode, ap, sa); + tmp = plus_constant (Pmode, tmp, TARGET_LARGE ? -4 : -2); + tmp = gen_rtx_MEM (Pmode, tmp); + emit_move_insn (tmp, ra); +} + +/* This is a list of MD patterns that implement fixed-count shifts. */ +static struct +{ + const char *name; + int count; + int need_430x; + rtx (*genfunc)(rtx,rtx); +} + const_shift_helpers[] = +{ +#define CSH(N,C,X,G) { "__mspabi_"N, C, X, gen_##G } + + CSH ("slli", 1, 1, slli_1), + CSH ("slll", 1, 1, slll_1), + CSH ("slll", 2, 1, slll_2), + + CSH ("srai", 1, 0, srai_1), + CSH ("sral", 1, 0, sral_1), + CSH ("sral", 2, 0, sral_2), + + CSH ("srll", 1, 0, srll_1), + CSH ("srll", 2, 1, srll_2x), + { 0, 0, 0, 0 } +#undef CSH +}; + +/* The MSP430 ABI defines a number of helper functions that should be + used for, for example, 32-bit shifts. This function is called to + emit such a function, using the table above to optimize some + cases. */ +void +msp430_expand_helper (rtx *operands, const char *helper_name, bool const_variants) +{ + rtx c, f; + char *helper_const = NULL; + int arg2 = 13; + int arg1sz = 1; + enum machine_mode arg0mode = GET_MODE (operands[0]); + enum machine_mode arg1mode = GET_MODE (operands[1]); + enum machine_mode arg2mode = GET_MODE (operands[2]); + int have_430x = msp430x ? 1 : 0; + + if (CONST_INT_P (operands[2])) + { + int i; + + for (i=0; const_shift_helpers[i].name; i++) + { + if (const_shift_helpers[i].need_430x <= have_430x + && strcmp (helper_name, const_shift_helpers[i].name) == 0 + && INTVAL (operands[2]) == const_shift_helpers[i].count) + { + emit_insn (const_shift_helpers[i].genfunc (operands[0], operands[1])); + return; + } + } + } + + if (arg1mode == VOIDmode) + arg1mode = arg0mode; + if (arg2mode == VOIDmode) + arg2mode = arg0mode; + + if (arg1mode == SImode) + { + arg2 = 14; + arg1sz = 2; + } + + if (const_variants + && CONST_INT_P (operands[2]) + && INTVAL (operands[2]) >= 1 + && INTVAL (operands[2]) <= 15) + { + /* Note that the INTVAL is limited in value and length by the conditional above. */ + int len = strlen (helper_name) + 4; + helper_const = (char *) xmalloc (len); + snprintf (helper_const, len, "%s_%ld", helper_name, (int) INTVAL (operands[2])); + } + + emit_move_insn (gen_rtx_REG (arg1mode, 12), + operands[1]); + if (!helper_const) + emit_move_insn (gen_rtx_REG (arg2mode, arg2), + operands[2]); + + c = gen_call_value_internal (gen_rtx_REG (arg0mode, 12), + gen_rtx_SYMBOL_REF (VOIDmode, helper_const ? helper_const : helper_name), + GEN_INT (0)); + c = emit_call_insn (c); + RTL_CONST_CALL_P (c) = 1; + + f = 0; + use_regs (&f, 12, arg1sz); + if (!helper_const) + use_regs (&f, arg2, 1); + add_function_usage_to (c, f); + + emit_move_insn (operands[0], + gen_rtx_REG (arg0mode, 12)); +} + +/* Called by cbranch<mode>4 to coerce operands into usable forms. */ +void +msp430_fixup_compare_operands (enum machine_mode my_mode, rtx * operands) +{ + /* constants we're looking for, not constants which are allowed. */ + int const_op_idx = 1; + + if (msp430_reversible_cmp_operator (operands[0], VOIDmode)) + const_op_idx = 2; + + if (GET_CODE (operands[const_op_idx]) != REG + && GET_CODE (operands[const_op_idx]) != MEM) + operands[const_op_idx] = copy_to_mode_reg (my_mode, operands[const_op_idx]); +} + +/* Simplify_gen_subreg() doesn't handle memory references the way we + need it to below, so we use this function for when we must get a + valid subreg in a "natural" state. */ +rtx +msp430_subreg (enum machine_mode mode, rtx r, enum machine_mode omode, int byte) +{ + rtx rv; + + if (GET_CODE (r) == SUBREG + && SUBREG_BYTE (r) == 0) + { + rtx ireg = SUBREG_REG (r); + enum machine_mode imode = GET_MODE (ireg); + + /* special case for (HI (SI (PSI ...), 0)) */ + if (imode == PSImode + && mode == HImode + && byte == 0) + rv = gen_rtx_SUBREG (mode, ireg, byte); + else + rv = simplify_gen_subreg (mode, ireg, imode, byte); + } + else if (GET_CODE (r) == MEM) + rv = adjust_address (r, mode, byte); + else + rv = simplify_gen_subreg (mode, r, omode, byte); + + if (!rv) + gcc_unreachable (); + + return rv; +} + +/* Called by movsi_x to generate the HImode operands. */ +void +msp430_split_movsi (rtx *operands) +{ + rtx op00, op02, op10, op12; + + op00 = msp430_subreg (HImode, operands[0], SImode, 0); + op02 = msp430_subreg (HImode, operands[0], SImode, 2); + + if (GET_CODE (operands[1]) == CONST + || GET_CODE (operands[1]) == SYMBOL_REF) + { + op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (0)); + op10 = gen_rtx_CONST (HImode, op10); + op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (16)); + op12 = gen_rtx_CONST (HImode, op12); + } + else + { + op10 = msp430_subreg (HImode, operands[1], SImode, 0); + op12 = msp430_subreg (HImode, operands[1], SImode, 2); + } + + if (rtx_equal_p (operands[0], operands[1])) + { + operands[2] = op02; + operands[4] = op12; + operands[3] = op00; + operands[5] = op10; + } + else if (rtx_equal_p (op00, op12) + /* Catch the case where we are loading (rN, rN+1) from mem (rN). */ + || (REG_P (op00) && reg_mentioned_p (op00, op10)) + /* Or storing (rN) into mem (rN). */ + || (REG_P (op10) && reg_mentioned_p (op10, op00)) + ) + { + operands[2] = op02; + operands[4] = op12; + operands[3] = op00; + operands[5] = op10; + } + else + { + operands[2] = op00; + operands[4] = op10; + operands[3] = op02; + operands[5] = op12; + } +} + + +/* 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. */ +static const struct +{ + char const * const gcc_name; + char const * const ti_name; +} + helper_function_name_mappings [] = +{ + /* Floating point to/from integer conversions. */ + { "__truncdfsf2", "__mspabi_cvtdf" }, + { "__extendsfdf2", "__mspabi_cvtfd" }, + { "__fixdfhi", "__mspabi_fixdi" }, + { "__fixdfsi", "__mspabi_fixdli" }, + { "__fixdfdi", "__mspabi_fixdlli" }, + { "__fixunsdfhi", "__mspabi_fixdu" }, + { "__fixunsdfsi", "__mspabi_fixdul" }, + { "__fixunsdfdi", "__mspabi_fixdull" }, + { "__fixsfhi", "__mspabi_fixfi" }, + { "__fixsfsi", "__mspabi_fixfli" }, + { "__fixsfdi", "__mspabi_fixflli" }, + { "__fixunsfhi", "__mspabi_fixfu" }, + { "__fixunsfsi", "__mspabi_fixful" }, + { "__fixunsfdi", "__mspabi_fixfull" }, + { "__floathisf", "__mspabi_fltif" }, + { "__floatsisf", "__mspabi_fltlif" }, + { "__floatdisf", "__mspabi_fltllif" }, + { "__floathidf", "__mspabi_fltid" }, + { "__floatsidf", "__mspabi_fltlid" }, + { "__floatdidf", "__mspabi_fltllid" }, + { "__floatunhisf", "__mspabi_fltuf" }, + { "__floatunsisf", "__mspabi_fltulf" }, + { "__floatundisf", "__mspabi_fltullf" }, + { "__floatunhidf", "__mspabi_fltud" }, + { "__floatunsidf", "__mspabi_fltuld" }, + { "__floatundidf", "__mspabi_fltulld" }, + + /* Floating point comparisons. */ + /* GCC uses individual functions for each comparison, TI uses one + compare <=> function. */ + + /* Floating point arithmatic */ + { "__adddf3", "__mspabi_addd" }, + { "__addsf3", "__mspabi_addf" }, + { "__divdf3", "__mspabi_divd" }, + { "__divsf3", "__mspabi_divf" }, + { "__muldf3", "__mspabi_mpyd" }, + { "__mulsf3", "__mspabi_mpyf" }, + { "__subdf3", "__mspabi_subd" }, + { "__subsf3", "__mspabi_subf" }, + /* GCC does not use helper functions for negation */ + + /* Integer multiply, divide, remainder. */ + /* Note: gcc doesn't know about hardware multiply options (yet?) */ + { "__mulhi3", "__mspabi_mpyi" }, + { "__mulsi3", "__mspabi_mpyl" }, + { "__muldi3", "__mspabi_mpyll" }, +#if 0 + /* Clarify signed vs unsigned first. */ + { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply (yet?) */ + { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply (yet?) */ +#endif + + { "__divhi3", "__mspabi_divi" }, + { "__divsi3", "__mspabi_divli" }, + { "__divdi3", "__mspabi_divlli" }, + { "__udivhi3", "__mspabi_divu" }, + { "__udivsi3", "__mspabi_divlu" }, + { "__udivdi3", "__mspabi_divllu" }, + { "__modhi3", "__mspabi_remi" }, + { "__modsi3", "__mspabi_remli" }, + { "__moddi3", "__mspabi_remlli" }, + { "__umodhi3", "__mspabi_remu" }, + { "__umodsi3", "__mspabi_remul" }, + { "__umoddi3", "__mspabi_remull" }, + + /* Bitwise operations. */ + /* Rotation - no rotation support yet. */ + /* Logical left shift - gcc already does these itself. */ + /* Arithmetic left shift - gcc already does these itself. */ + /* Arithmetic right shift - gcc already does these itself. */ + + { NULL, NULL } +}; + +/* This function does the same as the default, but it will replace GCC + function names with the MSPABI-specified ones. */ +void +msp430_output_labelref (FILE *file, const char *name) +{ + int i; + + for (i = 0; helper_function_name_mappings [i].gcc_name; i++) + if (! strcmp (helper_function_name_mappings [i].gcc_name, name)) + { + fputs (helper_function_name_mappings [i].ti_name, file); + return; + } + + fputs (name, file); +} + +#undef TARGET_PRINT_OPERAND +#define TARGET_PRINT_OPERAND msp430_print_operand + +/* Common code for msp430_print_operand(). */ +static void +msp430_print_operand_raw (FILE * file, rtx op, int letter ATTRIBUTE_UNUSED) +{ + int i; + + switch (GET_CODE (op)) + { + case REG: + fprintf (file, "%s", reg_names [REGNO (op)]); + break; + + case CONST_INT: + i = INTVAL (op); + if (TARGET_ASM_HEX) + fprintf (file, "%#x", i); + else + fprintf (file, "%d", i); + break; + + case CONST: + case PLUS: + case MINUS: + case SYMBOL_REF: + case LABEL_REF: + output_addr_const (file, op); + break; + + default: + print_rtl (file, op); + break; + } +} + +static void +msp430_print_operand (FILE * file, rtx op, int letter) +{ + rtx addr; + + /* We can't use c, n, a, or l. */ + switch (letter) + { + case 'Z': + gcc_assert (CONST_INT_P (op)); + /* Print the constant value, less one. */ + fprintf (file, "#%ld", INTVAL (op) - 1); + return; + case 'Y': + gcc_assert (CONST_INT_P (op)); + /* Print the constant value, less four. */ + fprintf (file, "#%ld", INTVAL (op) - 4); + return; + /* case 'D': used for "decimal without '#'" */ + case 'I': + if (GET_CODE (op) == CONST_INT) + { + /* Inverse of constants */ + int i = INTVAL (op); + fprintf (file, "%d", ~i); + return; + } + op = XEXP (op, 0); + break; + case 'r': /* Conditional jump where the condition is reversed. */ + switch (GET_CODE (op)) + { + case EQ: fprintf (file, "NE"); break; + case NE: fprintf (file, "EQ"); break; + case GEU: fprintf (file, "LO"); break; + case LTU: fprintf (file, "HS"); break; + case GE: fprintf (file, "L"); break; + case LT: fprintf (file, "GE"); break; + /* Assume these have reversed operands. */ + case GTU: fprintf (file, "HS"); break; + case LEU: fprintf (file, "LO"); break; + case GT: fprintf (file, "GE"); break; + case LE: fprintf (file, "L"); break; + default: + msp430_print_operand_raw (file, op, letter); + break; + } + return; + case 'R': /* Conditional jump where the operands are reversed. */ + switch (GET_CODE (op)) + { + case GTU: fprintf (file, "LO"); break; + case LEU: fprintf (file, "HS"); break; + case GT: fprintf (file, "L"); break; + case LE: fprintf (file, "GE"); break; + default: + msp430_print_operand_raw (file, op, letter); + break; + } + return; + case 'p': /* Bit position. 0 == 0x01, 3 = 0x08 etc. */ + gcc_assert (CONST_INT_P (op)); + fprintf (file, "#%d", 1 << INTVAL (op)); + return; + case 'B': + switch (GET_MODE (op)) + { + case QImode: fprintf (file, ".B"); return; + case HImode: fprintf (file, ".W"); return; + case PSImode: fprintf (file, ".A"); return; + case SImode: fprintf (file, ".A"); return; + default: + return; + } + case 'L': /* Low half. */ + switch (GET_CODE (op)) + { + case MEM: + op = adjust_address (op, Pmode, 0); + break; + case REG: + break; + case CONST_INT: + op = GEN_INT (INTVAL (op) & 0xffff); + letter = 0; + break; + default: + /* If you get here, figure out a test case :-) */ + gcc_unreachable (); + } + break; + case 'H': /* high half */ + switch (GET_CODE (op)) + { + case MEM: + op = adjust_address (op, Pmode, 2); + break; + case REG: + op = gen_rtx_REG (Pmode, REGNO (op) + 1); + break; + case CONST_INT: + op = GEN_INT (INTVAL (op) >> 16); + letter = 0; + break; + default: + /* If you get here, figure out a test case :-) */ + gcc_unreachable (); + } + break; + + case 'X': + /* This is used to turn, for example, an ADD opcode into an ADDX + opcode when we're using 20-bit addresses. */ + if (TARGET_LARGE) + fprintf (file, "X"); + /* We don't care which operand we use, but we want 'X' in the MD + file, so we do it this way. */ + return; + + case 'x': + /* Similarly, but only for PSImodes. BIC, for example, needs this. */ + if (TARGET_LARGE && GET_MODE (op) == PSImode) + fprintf (file, "X"); + return; + + case 'A': + /* Likewise, for BR -> BRA. */ + 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)) + { + case REG: + msp430_print_operand_raw (file, op, letter); + break; + + case MEM: + addr = XEXP (op, 0); + switch (GET_CODE (addr)) + { + case REG: + fprintf (file, "@%s", reg_names [REGNO (addr)]); + break; + case PLUS: + msp430_print_operand_raw (file, XEXP (addr, 1), letter); + fprintf (file, "(%s)", reg_names [REGNO (XEXP (addr, 0))]); + break; + case CONST: + case CONST_INT: + case SYMBOL_REF: + case LABEL_REF: + fprintf (file, "&"); + msp430_print_operand_raw (file, addr, letter); + break; + + default: + print_rtl (file, addr); + break; + } + break; + + case CONST_INT: + case CONST: + case SYMBOL_REF: + case LABEL_REF: + if (letter == 0) + fprintf (file, "#"); + msp430_print_operand_raw (file, op, letter); + break; + + case EQ: fprintf (file, "EQ"); break; + case NE: fprintf (file, "NE"); break; + case GEU: fprintf (file, "HS"); break; + case LTU: fprintf (file, "LO"); break; + case GE: fprintf (file, "GE"); break; + case LT: fprintf (file, "L"); break; + + default: + print_rtl (file, op); + break; + } + +} + + +/* Frame stuff. */ + +rtx +msp430_return_addr_rtx (int count) +{ + int ra_size; + if (count) + return NULL_RTX; + + ra_size = TARGET_LARGE ? 4 : 2; + if (crtl->args.pretend_args_size) + ra_size += 2; + + return gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx, GEN_INT (- ra_size))); +} + +rtx +msp430_incoming_return_addr_rtx (void) +{ + return gen_rtx_MEM (Pmode, stack_pointer_rtx); +} + +/* Instruction generation stuff. */ + +/* Generate a sequence of instructions to sign-extend an HI + value into an SI value. Handles the tricky case where + we are overwriting the destination. */ + +const char * +msp430x_extendhisi (rtx * operands) +{ + if (REGNO (operands[0]) == REGNO (operands[1])) + /* Low word of dest == source word. */ + return "BIT.W #0x8000, %L0 { SUBC.W %H0, %H0 { INV.W %H0, %H0"; /* 8-bytes. */ + + if (! msp430x) + /* Note: This sequence is approximately the same length as invoking a helper + function to perform the sign-extension, as in: + + MOV.W %1, %L0 + MOV.W %1, r12 + CALL __mspabi_srai_15 + MOV.W r12, %H0 + + but this version does not involve any function calls or using argument + registers, so it reduces register pressure. */ + return "MOV.W %1, %L0 { BIT.W #0x8000, %L0 { SUBC.W %H0, %H0 { INV.W %H0, %H0"; /* 10-bytes. */ + + if (REGNO (operands[0]) + 1 == REGNO (operands[1])) + /* High word of dest == source word. */ + return "MOV.W %1, %L0 { RPT #15 { RRAX.W %H0"; /* 6-bytes. */ + + /* No overlap between dest and source. */ + return "MOV.W %1, %L0 { MOV.W %1, %H0 { RPT #15 { RRAX.W %H0"; /* 8-bytes. */ +} + +/* Likewise for logical right shifts. */ +const char * +msp430x_logical_shift_right (rtx amount) +{ + /* The MSP430X's logical right shift instruction - RRUM - does + not use an extension word, so we cannot encode a repeat count. + Try various alternatives to work around this. If the count + is in a register we are stuck, hence the assert. */ + gcc_assert (CONST_INT_P (amount)); + + if (INTVAL (amount) <= 0 + || INTVAL (amount) >= 16) + return "# nop logical shift."; + + if (INTVAL (amount) > 0 + && INTVAL (amount) < 5) + return "rrum.w\t%2, %0"; /* Two bytes. */ + + if (INTVAL (amount) > 4 + && INTVAL (amount) < 9) + return "rrum.w\t#4, %0 { rrum.w\t%Y2, %0 "; /* Four bytes. */ + + /* First we logically shift right by one. Now we know + that the top bit is zero and we can use the arithmetic + right shift instruction to perform the rest of the shift. */ + return "rrum.w\t#1, %0 { rpt\t%Z2 { rrax.w\t%0"; /* Six bytes. */ +} + +struct gcc_target targetm = TARGET_INITIALIZER; + +#include "gt-msp430.h" diff --git a/gcc/config/msp430/msp430.h b/gcc/config/msp430/msp430.h new file mode 100644 index 00000000000..f5289b551e3 --- /dev/null +++ b/gcc/config/msp430/msp430.h @@ -0,0 +1,406 @@ +/* GCC backend definitions for the TI MSP430 Processor + Copyright (C) 2012-2013 Free Software Foundation, Inc. + Contributed by Red Hat. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + + +/* Run-time Target Specification */ + +/* True if the MSP430x extensions are enabled. */ +#ifndef IN_LIBGCC2 +extern bool msp430x; +#endif + +#define TARGET_CPU_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("NO_TRAMPOLINES"); \ + builtin_define ("__MSP430__"); \ + if (msp430x) \ + { \ + builtin_define ("__MSP430X__"); \ + builtin_assert ("cpu=MSP430X"); \ + if (TARGET_LARGE) \ + builtin_define ("__MSP430X_LARGE__"); \ + } \ + else \ + builtin_assert ("cpu=MSP430"); \ + } \ + while (0) + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:crt0.o%s} crtbegin.o%s" + +/* -lgcc is included because crtend.o needs __mspabi_func_epilog_1. */ +#undef ENDFILE_SPEC +#define ENDFILE_SPEC "crtend.o%s crtn.o%s -lgcc" + +#define ASM_SPEC "-mP " /* Enable polymorphic instructions. */ \ + "%{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 + are creating a relocatable binary (gc does not work) or debugging + is enabled (the GDB testsuite relies upon unused entities not being deleted). */ +#define LINK_SPEC "%{mrelax:--relax} %{mlarge:%{!r:%{!g:--gc-sections}}}" + +#undef LIB_SPEC +#define LIB_SPEC " \ +--start-group \ +-lc \ +-lgcc \ +%{msim:-lsim} \ +%{!msim:-lnosys} \ +--end-group \ +%{!T*: %{msim: %{mlarge:%Tmsp430xl-sim.ld}%{!mlarge:%Tmsp430-sim.ld}}%{!msim:%Tmsp430.ld}} \ +" + + +/* Storage Layout */ + +#define BITS_BIG_ENDIAN 0 +#define BYTES_BIG_ENDIAN 0 +#define WORDS_BIG_ENDIAN 0 + + +#ifdef IN_LIBGCC2 +/* This is to get correct SI and DI modes in libgcc2.c (32 and 64 bits). */ +#define UNITS_PER_WORD 4 +/* We have a problem with libgcc2. It only defines two versions of + each function, one for "int" and one for "long long". Ie it assumes + that "sizeof (int) == sizeof (long)". For the MSP430 this is not true + and we need a third set of functions. We explicitly define + LIBGCC2_UNITS_PER_WORD here so that it is clear that we are expecting + to get the SI and DI versions from the libgcc2.c sources, and we + provide our own set of HI functions, which is why this + definition is surrounded by #ifndef..#endif. */ +#ifndef LIBGCC2_UNITS_PER_WORD +#define LIBGCC2_UNITS_PER_WORD 4 +#endif +#else +/* Actual width of a word, in units (bytes). */ +#define UNITS_PER_WORD 2 +#endif + +#define SHORT_TYPE_SIZE 16 +#define INT_TYPE_SIZE 16 +#define LONG_TYPE_SIZE 32 +#define LONG_LONG_TYPE_SIZE 64 + +#define FLOAT_TYPE_SIZE 32 +#define DOUBLE_TYPE_SIZE 64 +#define LONG_DOUBLE_TYPE_SIZE 64 /*DOUBLE_TYPE_SIZE*/ + +#define LIBGCC2_HAS_DF_MODE 1 +#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64 + +#define DEFAULT_SIGNED_CHAR 0 + +#define STRICT_ALIGNMENT 1 +#define FUNCTION_BOUNDARY 16 +#define BIGGEST_ALIGNMENT 16 +#define STACK_BOUNDARY 16 +#define PARM_BOUNDARY 8 +#define PCC_BITFIELD_TYPE_MATTERS 1 + +#define STACK_GROWS_DOWNWARD 1 +#define FRAME_GROWS_DOWNWARD 1 +#define FIRST_PARM_OFFSET(FNDECL) 0 + +#define MAX_REGS_PER_ADDRESS 1 + +#define Pmode (TARGET_LARGE ? PSImode : HImode) +/* Note: 32 is a lie. Large pointers are actually 20-bits wide. But gcc + thinks that any non-power-of-2 pointer size equates to BLKmode, which + causes all kinds of problems... */ +#define POINTER_SIZE (TARGET_LARGE ? 32 : 16) +#define POINTERS_EXTEND_UNSIGNED 1 + +#define ADDR_SPACE_NEAR 1 +#define ADDR_SPACE_FAR 2 + +#define REGISTER_TARGET_PRAGMAS() msp430_register_pragmas() + +#if 1 /* XXX */ +/* Define this macro if it is advisable to hold scalars in registers + in a wider mode than that declared by the program. In such cases, + the value is constrained to be within the bounds of the declared + type, but kept valid in the wider mode. The signedness of the + extension may differ from that of the type. */ + +#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \ + if (GET_MODE_CLASS (MODE) == MODE_INT \ + && GET_MODE_SIZE (MODE) < 2) \ + (MODE) = HImode; +#endif + +/* Layout of Source Language Data Types */ + +#undef SIZE_TYPE +#define SIZE_TYPE (TARGET_LARGE ? "long unsigned int" : "unsigned int") +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE (TARGET_LARGE ? "long int" : "int") +#undef WCHAR_TYPE +#define WCHAR_TYPE "long int" +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE BITS_PER_WORD +#define FUNCTION_MODE HImode +#define CASE_VECTOR_MODE Pmode +#define HAS_LONG_COND_BRANCH 0 +#define HAS_LONG_UNCOND_BRANCH 0 + +#define LOAD_EXTEND_OP(M) ZERO_EXTEND +/*#define WORD_REGISTER_OPERATIONS 1*/ + +#define MOVE_MAX 8 +#define STARTING_FRAME_OFFSET 0 + +#define INCOMING_RETURN_ADDR_RTX \ + msp430_incoming_return_addr_rtx () + +#define RETURN_ADDR_RTX(COUNT, FA) \ + msp430_return_addr_rtx (COUNT) + +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 + +#define SLOW_BYTE_ACCESS 0 + + +/* Register Usage */ + +/* gas doesn't recognize PC (R0), SP (R1), and SR (R2) as register + names. */ +#define REGISTER_NAMES \ +{ \ + "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", \ + "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", \ + "argptr" \ +} + +enum reg_class +{ + NO_REGS, + R12_REGS, + R13_REGS, + GEN_REGS, + ALL_REGS, + LIM_REG_CLASSES +}; + +#define REG_CLASS_NAMES \ +{ \ + "NO_REGS", \ + "R12_REGS", \ + "R13_REGS", \ + "GEN_REGS", \ + "ALL_REGS" \ +} + +#define REG_CLASS_CONTENTS \ +{ \ + 0x00000000, \ + 0x00001000, \ + 0x00002000, \ + 0x0000fff2, \ + 0x0001ffff \ +} + +#define GENERAL_REGS GEN_REGS +#define BASE_REG_CLASS GEN_REGS +#define INDEX_REG_CLASS GEN_REGS +#define N_REG_CLASSES (int) LIM_REG_CLASSES + +#define PC_REGNUM 0 +#define STACK_POINTER_REGNUM 1 +#define CC_REGNUM 2 +#define FRAME_POINTER_REGNUM 4 /* not usually used, call preserved */ +#define ARG_POINTER_REGNUM 16 +#define STATIC_CHAIN_REGNUM 5 /* FIXME */ + +#define FIRST_PSEUDO_REGISTER 17 + +#define REGNO_REG_CLASS(REGNO) ((REGNO) < 17 \ + ? GEN_REGS : NO_REGS) + +#define TRAMPOLINE_SIZE 4 /* FIXME */ +#define TRAMPOLINE_ALIGNMENT 16 /* FIXME */ + +#define ELIMINABLE_REGS \ +{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ + { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \ + { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }} + +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ + (OFFSET) = msp430_initial_elimination_offset ((FROM), (TO)) + + +#define FUNCTION_ARG_REGNO_P(N) ((N) >= 8 && (N) < ARG_POINTER_REGNUM) +#define DEFAULT_PCC_STRUCT_RETURN 0 + +/* 1 == register can't be used by gcc, in general + 0 == register can be used by gcc, in general */ +#define FIXED_REGISTERS \ +{ \ + 1,0,1,1, 0,0,0,0, \ + 0,0,0,0, 0,0,0,0, \ + 1, \ +} + +/* 1 == value changes across function calls + 0 == value is the same after a call */ +/* R4 through R10 are callee-saved */ +#define CALL_USED_REGISTERS \ +{ \ + 1,0,1,1, 0,0,0,0, \ + 0,0,0,1, 1,1,1,1, \ + 1, \ +} + +#define REG_ALLOC_ORDER \ + { 12, 13, 14, 15, 10, 9, 8, 7, 6, 5, 4, 11, 0, 1, 2, 3, 16 } +/* { 11, 15, 14, 13, 12, 10, 9, 8, 7, 6, 5, 4, 0, 1, 2, 3, 16 }*/ + +#define REGNO_OK_FOR_BASE_P(regno) 1 +#define REGNO_OK_FOR_INDEX_P(regno) 1 + + + +typedef struct +{ + /* These two are the current argument status. */ + char reg_used[4]; +#define CA_FIRST_REG 12 + char can_split; + /* These two are temporaries used internally. */ + char start_reg; + char reg_count; + char mem_count; + char special_p; +} CUMULATIVE_ARGS; + +#define INIT_CUMULATIVE_ARGS(CA, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ + msp430_init_cumulative_args (&CA, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) + + +/* FIXME */ +#define NO_PROFILE_COUNTERS 1 +#define PROFILE_BEFORE_PROLOGUE 1 + +#define FUNCTION_PROFILER(FILE, LABELNO) \ + fprintf (FILE, "\tcall\t__mcount\n"); + +#define HARD_REGNO_NREGS(REGNO, MODE) \ + msp430_hard_regno_nregs (REGNO, MODE) + +#define HARD_REGNO_MODE_OK(REGNO, MODE) \ + msp430_hard_regno_mode_ok (REGNO, MODE) + +#define MODES_TIEABLE_P(MODE1, MODE2) \ + msp430_modes_tieable_p (MODE1, MODE2) + +/* Exception Handling */ + +/* R12,R13,R14 - EH data + R15 - stack adjustment */ + +#define EH_RETURN_DATA_REGNO(N) \ + (((N) < 3) ? ((N) + 12) : INVALID_REGNUM) + +#define EH_RETURN_HANDLER_RTX \ + gen_rtx_MEM(Pmode, gen_rtx_PLUS (Pmode, gen_rtx_REG(Pmode, SP_REGNO), gen_rtx_REG (Pmode, 15))) + +#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 15) + +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) DW_EH_PE_udata4 + + +/* Stack Layout and Calling Conventions */ + + +/* Addressing Modes */ + + + +#define TEXT_SECTION_ASM_OP ".text" +#define DATA_SECTION_ASM_OP ".data" +#define BSS_SECTION_ASM_OP "\t.section .bss" + +#define ASM_COMMENT_START " ;" +#define ASM_APP_ON "" +#define ASM_APP_OFF "" +#define LOCAL_LABEL_PREFIX ".L" +#undef USER_LABEL_PREFIX +#define USER_LABEL_PREFIX "" + +#define GLOBAL_ASM_OP "\t.global\t" + +#define ASM_OUTPUT_LABELREF(FILE, SYM) msp430_output_labelref ((FILE), (SYM)) + +#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ + fprintf (FILE, "\t.long .L%d\n", VALUE) + +/* This is how to output an element of a case-vector that is relative. + Note: The local label referenced by the "3b" below is emitted by + the tablejump insn. */ + +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ + fprintf (FILE, "\t.long .L%d - 1b\n", VALUE) + + +#define ASM_OUTPUT_ALIGN(STREAM, LOG) \ + do \ + { \ + if ((LOG) == 0) \ + break; \ + fprintf (STREAM, "\t.balign %d\n", 1 << (LOG)); \ + } \ + while (0) + +#define JUMP_TABLES_IN_TEXT_SECTION 1 + +#undef DWARF2_ADDR_SIZE +#define DWARF2_ADDR_SIZE 4 + +#define INCOMING_FRAME_SP_OFFSET (POINTER_SIZE / BITS_PER_UNIT) + +#undef PREFERRED_DEBUGGING_TYPE +#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG + +#define DWARF2_ASM_LINE_DEBUG_INFO 1 + +/* Prevent reload (and others) from choosing HImode stack slots + when spilling hard registers when they may contain PSImode values. */ +#define HARD_REGNO_CALLER_SAVE_MODE(REGNO,NREGS,MODE) \ + ((TARGET_LARGE && ((NREGS) <= 2)) ? PSImode : choose_hard_reg_mode ((REGNO), (NREGS), false)) + +/* Also stop GCC from thinking that it can eliminate (SUBREG:PSI (SI)). */ +#define CANNOT_CHANGE_MODE_CLASS(FROM,TO,CLASS) \ + ( ((TO) == PSImode && (FROM) == SImode) \ + || ((TO) == SImode && (FROM) == PSImode) \ + || ((TO) == DImode && (FROM) == PSImode) \ + || ((TO) == PSImode && (FROM) == DImode) \ + ) + +#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 new file mode 100644 index 00000000000..a258867e532 --- /dev/null +++ b/gcc/config/msp430/msp430.md @@ -0,0 +1,1274 @@ +;; Machine Description for TI MSP43* processors +;; Copyright (C) 2013 Free Software Foundation, Inc. +;; Contributed by Red Hat. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; <http://www.gnu.org/licenses/>. + + +(define_constants + [ + (PC_REGNO 0) + (SP_REGNO 1) + (CARRY 2) + ]) + +(define_c_enum "unspec" + [ + UNS_PROLOGUE_START_MARKER + UNS_PROLOGUE_END_MARKER + UNS_EPILOGUE_START_MARKER + UNS_EPILOGUE_HELPER + + UNS_PUSHM + UNS_POPM + + 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") +(include "constraints.md") + +(define_mode_iterator QHI [QI HI PSI]) + +;; There are two basic "family" tests we do here: +;; +;; msp430x - true if 430X instructions are available. +;; TARGET_LARGE - true if pointers are 20-bits +;; +;; Note that there are three supported cases, since the base 430 +;; doesn't have 20-bit pointers: +;; +;; 1. MSP430 cpu, small model +;; 2. MSP430X cpu, small model. +;; 3. MSP430X cpu, large model. + +;;------------------------------------------------------------ +;; Moves + +;; Push/Pop must be before the generic move patterns + +(define_insn "push" + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNO))) + (match_operand:HI 0 "register_operand" "r"))] + "" + "PUSH\t%0" + ) + +(define_insn "pusha" + [(set (mem:PSI (pre_dec:PSI (reg:PSI SP_REGNO))) + (match_operand:PSI 0 "register_operand" "r"))] + "TARGET_LARGE" + "PUSHX.A\t%0" + ) + +(define_insn "pushm" + [(unspec_volatile [(match_operand 0 "register_operand" "r") + (match_operand 1 "immediate_operand" "n")] UNS_PUSHM)] + "" + "PUSHM%B0\t%1, %0" + ) + +(define_insn "pop" + [(set (match_operand:HI 0 "register_operand" "=r") + (mem:HI (post_inc:HI (reg:HI SP_REGNO))))] + "" + "POP\t%0" + ) + +(define_insn "popa" + [(set (match_operand:PSI 0 "register_operand" "=r") + (mem:PSI (post_inc:PSI (reg:PSI SP_REGNO))))] + "TARGET_LARGE" + "POPX.A\t%0" + ) + +;; This is nasty. Operand0 is bogus. It is only there so that we can get a +;; mode for the %B0 to work. We should use operand1 for this, but that does +;; not have a mode. +;; +;; Operand1 is actually a register, but we cannot accept (REG...) because the +;; cprop_hardreg pass can and will renumber registers even inside +;; unspec_volatiles. So we take an integer register number parameter and +;; fudge it to be a register name when we generate the assembler. We use %I +;; because that is the only operator that will omit the # prefix to an +;; integer value. Unfortunately it also inverts the integer value, so we +;; have pre-invert it when generating this insn. (We could of course add a +;; new operator, eg %D, just for this pattern...) +;; +;; The pushm pattern does not have this problem because of all of the +;; frame info cruft attached to it, so cprop_hardreg leaves it alone. +(define_insn "popm" + [(unspec_volatile [(match_operand 0 "register_operand" "r") + (match_operand 1 "immediate_operand" "i") + (match_operand 2 "immediate_operand" "i")] UNS_POPM)] + "" + "POPM%B0\t%2, r%I1" + ) + +;; The next two patterns are here to support a "feature" of how GCC implements +;; varargs. When a function uses varargs and the *second* to last named +;; argument is split between argument registers and the stack, gcc expects the +;; callee to allocate space on the stack that can contain the register-based +;; part of the argument. This space *has* to be just before the remaining +;; arguments (ie the ones that are fully on the stack). +;; +;; The problem is that the MSP430 CALL instruction pushes the return address +;; onto the stack in the exact place where the callee wants to allocate +;; this extra space. So we need a sequence of instructions that can allocate +;; the extra space and then move the return address down the stack, so that +;; the extra space is now adjacent to the remaining arguments. +;; +;; This could be constructed through regular insns, but they might be split up +;; by a misguided optimization, so an unspec volatile is used instead. + +(define_insn "grow_and_swap" + [(unspec_volatile [(const_int 0)] UNS_GROW_AND_SWAP)] + "" + { if (TARGET_LARGE) + return "SUBA\t#2, r1 \n MOVX.A\t2(r1), 0(r1)"; + return "SUB\t#2, r1 \n MOV.W\t2(r1), 0(r1)"; + } + ) + +(define_insn "swap_and_shrink" + [(unspec_volatile [(const_int 0)] UNS_SWAP_AND_SHRINK)] + "" + { return TARGET_LARGE + ? "MOVX.A\t0(r1), 2(r1) \n ADDA\t#2, SP" + : "MOV.W\t0(r1), 2(r1) \n ADD\t#2, SP"; + }) + +; I set LOAD_EXTEND_OP and WORD_REGISTER_OPERATIONS, but gcc puts in a +; zero_extend anyway. Catch it here. +(define_insn "movqihi" + [(set (match_operand:HI 0 "register_operand" "=r,r") + (zero_extend:HI (match_operand:QI 1 "memory_operand" "Ys,m")))] + "" + "@ + MOV.B\t%1, %0 + MOV%X1.B\t%1, %0" +) + +(define_insn "movqi" + [(set (match_operand:QI 0 "nonimmediate_operand" "=rYs,rm") + (match_operand:QI 1 "general_operand" "riYs,rmi"))] + "" + "@ + MOV.B\t%1, %0 + MOV%X0.B\t%1, %0" +) + +(define_insn "movhi" + [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs,rm") + (match_operand:HI 1 "general_operand" "riYs,rmi"))] + "" + "@ + MOV.W\t%1, %0 + MOV%X0.W\t%1, %0" +) + +(define_expand "movsi" + [(set (match_operand:SI 0 "nonimmediate_operand" "") + (match_operand:SI 1 "general_operand" ""))] + "" + "" + ) + +(define_insn_and_split "movsi_x" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (match_operand:SI 1 "general_operand" "rmi"))] + "" + "#" + "reload_completed" + [(set (match_operand:HI 2 "nonimmediate_operand") + (match_operand:HI 4 "general_operand")) + (set (match_operand:HI 3 "nonimmediate_operand") + (match_operand:HI 5 "general_operand"))] + "msp430_split_movsi (operands);" +) + +;; Some MOVX.A cases can be done with MOVA, this is only a few of them. +(define_insn "movpsi" + [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,Ya,rm") + (match_operand:PSI 1 "general_operand" "riYa,r,rmi"))] + "" + "@ + MOV%A0\t%1, %0 + MOV%A0\t%1, %0 + MOV%X0.%A0\t%1, %0") + +; This pattern is identical to the truncsipsi2 pattern except +; that it uses a SUBREG instead of a TRUNC. It is needed in +; order to prevent reload from converting (set:SI (SUBREG:PSI (SI))) +; into (SET:PSI (PSI)). +; +; Note: using POPM.A #1 is two bytes smaller than using POPX.A.... + +(define_insn "movsipsi2" + [(set (match_operand:PSI 0 "register_operand" "=r") + (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))] + "TARGET_LARGE" + "PUSH.W %H1 { PUSH.W %1 { POPM.A #1, %0" +) + +;;------------------------------------------------------------ +;; Math + +(define_insn "addpsi3" + [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,rm") + (plus:PSI (match_operand:PSI 1 "nonimmediate_operand" "%0,0") + (match_operand:PSI 2 "general_operand" "rLs,rmi")))] + "" + "@ + ADDA\t%2, %0 + ADDX.A\t%2, %0" +) + +(define_insn "addqi3" + [(set (match_operand:QI 0 "nonimmediate_operand" "=rYs,rm") + (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") + (match_operand:QI 2 "general_operand" "riYs,rmi")))] + "" + "@ + ADD.B\t%2, %0 + ADD%X0.B\t%2, %0" +) + +(define_insn "addhi3" + [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs,rm") + (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") + (match_operand:HI 2 "general_operand" "riYs,rmi")))] + "" + "@ + ADD.W\t%2, %0 + ADD%X0.W\t%2, %0" +) + +; This pattern is needed in order to avoid reload problems. +; It takes an SI pair of registers, adds a value to them, and +; then converts them into a single PSI register. + +(define_insn "addsipsi3" + [(set (subreg:SI (match_operand:PSI 0 "register_operand" "=&r") 0) + (plus:SI (match_operand:SI 1 "register_operand" "0") + (match_operand 2 "general_operand" "rmi")))] + "" + "ADD.W\t%L2, %L0 { ADDC.W\t%H2, %H0 { PUSH.W %H0 { PUSH.W %L0 { POPM.A #1, %0" +) + +(define_insn "addsi3" + [(set (match_operand:SI 0 "nonimmediate_operand" "=&r,rm") + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") + (match_operand:SI 2 "general_operand" "r,mi")))] + "" + "@ + ADD\t%L2, %L0 { ADDC\t%H2, %H0 + ADD%X0\t%L2, %L0 { ADDC%X0\t%H2, %H0" +) + +; Version of addhi that exposes the carry operations, for SImode adds. +; +; NOTE - we are playing a dangerous game with GCC here. We have these two +; add patterns and the splitter that follows because our tests have shown +; that this results in a significant reduction in code size - because GCC is +; able to discard any unused part of the addition. We have to annotate the +; patterns with the set and use of the carry flag because otherwise GCC will +; discard parts of the addition when they are actually needed. But we have +; not annotated all the other patterns that set the CARRY flag as doing so +; results in an overall increase in code size[1]. Instead we just *hope* +; that GCC will not move a carry-setting instruction in between the first +; and second adds. +; +; So far our experiments have shown that GCC is likely to move MOV and CMP +; instructions in between the two adds, but not other instructions. MOV is +; safe, CMP is not. So we have annotated the CMP patterns and left the +; subtract, shift and other add patterns alone. At the moment this is +; working, but with future changes to the generic parts of GCC that might +; change. +; +; [1] It is not clear exactly why the code size increases. The cause appears +; to be that reload is more prevelent to spilling a variable onto the stack +; but why it does this is unknown. Possibly the additional CLOBBERs necessary +; to correctly annotate the other patterns makes reload think that there is +; increased register pressure. Or possibly reload does not handle ADD patterns +; that are not single_set() very well. + +(define_insn "addhi3_cy" + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") + (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") + (match_operand:HI 2 "general_operand" "r,rm"))) + (set (reg:BI CARRY) + (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1)) + (zero_extend:SI (match_dup 2))) + (const_int 16)))) + ] + "" + "@ + ADD %2, %1 ; cy + ADD%X0 %2, %1 ; cy" + ) + +(define_insn "addhi3_cy_i" + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") + (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") + (match_operand:HI 2 "general_operand" "i,i"))) + (set (reg:BI CARRY) + (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1)) + (match_operand 3 "immediate_operand" "i,i")) + (const_int 16)))) + ] + "" + "@ + ADD %2, %1 ; cy + ADD%X0 %2, %1 ; cy" + ) + +; Version of addhi that adds the carry, for SImode adds. +(define_insn "addchi4_cy" + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") + (plus:HI (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") + (match_operand:HI 2 "general_operand" "ri,rmi")) + (zero_extend:HI (reg:BI CARRY)))) + ] + "" + "@ + ADDC %2, %1 + ADDC%X0 %2, %1" + ) + +; Split an SImode add into two HImode adds, keeping track of the carry +; so that gcc knows when it can and can't optimize away the two +; halves. +(define_split + [(set (match_operand:SI 0 "msp430_nonsubreg_operand" "=&rm") + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") + (match_operand:SI 2 "general_operand" "rmi"))) + ] + "" + [(parallel [(set (match_operand:HI 3 "nonimmediate_operand" "=&rm") + (plus:HI (match_dup 4) + (match_dup 5))) + (set (reg:BI CARRY) + (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 4)) + (match_dup 9)) + (const_int 16)))) + ]) + (set (match_operand:HI 6 "nonimmediate_operand" "=&rm") + (plus:HI (plus:HI (match_dup 7) + (match_dup 8)) + (zero_extend:HI (reg:BI CARRY)))) + ] + " + operands[3] = msp430_subreg (HImode, operands[0], SImode, 0); + operands[4] = msp430_subreg (HImode, operands[1], SImode, 0); + operands[5] = msp430_subreg (HImode, operands[2], SImode, 0); + operands[6] = msp430_subreg (HImode, operands[0], SImode, 2); + operands[7] = msp430_subreg (HImode, operands[1], SImode, 2); + operands[8] = msp430_subreg (HImode, operands[2], SImode, 2); + if (GET_CODE (operands[5]) == CONST_INT) + { + operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff); + } + else + { + operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]); + } + " + ) + + +;; Alternatives 2 and 3 are to handle cases generated by reload. +(define_insn "subpsi3" + [(set (match_operand:PSI 0 "nonimmediate_operand" "=r, rm, &?r, ?&r") + (minus:PSI (match_operand:PSI 1 "general_operand" "0, 0, !r, !i") + (match_operand:PSI 2 "general_operand" "rLs, rmi, rmi, r")))] + "" + "@ + SUBA\t%2, %0 + SUBX.A\t%2, %0 + MOVX.A\t%1, %0 { SUBX.A\t%2, %0 + MOVX.A\t%1, %0 { SUBA\t%2, %0" +) + +;; Alternatives 2 and 3 are to handle cases generated by reload. +(define_insn "subqi3" + [(set (match_operand:QI 0 "nonimmediate_operand" "=rYs, rm, &?r, ?&r") + (minus:QI (match_operand:QI 1 "general_operand" "0, 0, !r, !i") + (match_operand:QI 2 "general_operand" " riYs, rmi, rmi, r")))] + "" + "@ + SUB.B\t%2, %0 + SUB%X0.B\t%2, %0 + MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0 + MOV%X0.B\t%1, %0 { SUB%X0.B\t%2, %0" +) + +;; Alternatives 2 and 3 are to handle cases generated by reload. +(define_insn "subhi3" + [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs, rm, &?r, ?&r") + (minus:HI (match_operand:HI 1 "general_operand" "0, 0, !r, !i") + (match_operand:HI 2 "general_operand" " riYs, rmi, rmi, r")))] + "" + "@ + SUB.W\t%2, %0 + SUB%X0.W\t%2, %0 + MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0 + MOV%X0.W\t%1, %0 { SUB%X0.W\t%2, %0" +) + +(define_insn "subsi3" + [(set (match_operand:SI 0 "nonimmediate_operand" "=&rm") + (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0") + (match_operand:SI 2 "general_operand" "rmi")))] + "" + "SUB%X0\t%L2, %L0 { SUBC%X0\t%H2, %H0" +) + +(define_insn "*bic<mode>_cg" + [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,m") + (and:QHI (match_operand:QHI 1 "msp_general_operand" "0,0") + (match_operand 2 "msp430_inv_constgen_operator" "n,n")))] + "" + "@ + BIC%x0%B0\t#%I2, %0 + BIC%X0%B0\t#%I2, %0" +) + +(define_insn "bic<mode>3" + [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm") + (and:QHI (not:QHI (match_operand:QHI 1 "msp_general_operand" "rYs,rmn")) + (match_operand:QHI 2 "msp_nonimmediate_operand" "0,0")))] + "" + "@ + BIC%x0%B0\t%1, %0 + BIC%X0%B0\t%1, %0" +) + +(define_insn "and<mode>3" + [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm") + (and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0") + (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))] + "" + "@ + AND%x0%B0\t%2, %0 + AND%X0%B0\t%2, %0" +) + +(define_insn "ior<mode>3" + [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm") + (ior:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0") + (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))] + "" + "@ + BIS%x0%B0\t%2, %0 + BIS%X0%B0\t%2, %0" +) + +(define_insn "xor<mode>3" + [(set (match_operand:QHI 0 "nonimmediate_operand" "=rYs,rm") + (xor:QHI (match_operand:QHI 1 "nonimmediate_operand" "%0,0") + (match_operand:QHI 2 "general_operand" "riYs,rmi")))] + "" + "@ + XOR%x0%B0\t%2, %0 + XOR%X0%B0\t%2, %0" +) + +;; Macro : XOR #~0, %0 +(define_insn "one_cmpl<mode>2" + [(set (match_operand:QHI 0 "nonimmediate_operand" "=rYs,m") + (not:QHI (match_operand:QHI 1 "nonimmediate_operand" "0,0")))] + "" + "@ + INV%x0%B0\t%0 + INV%X0%B0\t%0" +) + +(define_insn "extendqihi2" + [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs,m") + (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] + "" + "@ + SXT%X0\t%0 + SXT%X0\t%0" +) + +(define_insn "zero_extendqihi2" + [(set (match_operand:HI 0 "nonimmediate_operand" "=rYs,m") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] + "" + "@ + AND\t#0xff, %0 + AND%X0\t#0xff, %0" +) + +;; Eliminate extraneous zero-extends mysteriously created by gcc. +(define_peephole2 + [(set (match_operand:HI 0 "register_operand") + (zero_extend:HI (match_operand:QI 1 "general_operand"))) + (set (match_operand:HI 2 "register_operand") + (zero_extend:HI (match_operand:QI 3 "register_operand")))] + "REGNO (operands[0]) == REGNO (operands[2]) && REGNO (operands[2]) == REGNO (operands[3])" + [(set (match_dup 0) + (zero_extend:HI (match_dup 1)))] +) + +(define_insn "zero_extendhipsi2" + [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,m") + (zero_extend:PSI (match_operand:HI 1 "nonimmediate_operand" "rm,r")))] + "" + "MOVX\t%1, %0" +) + +(define_insn "truncpsihi2" + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") + (truncate:HI (match_operand:PSI 1 "register_operand" "r")))] + "" + "MOVX\t%1, %0" +) + +(define_insn "extendhisi2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r") + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))] + "" + { return msp430x_extendhisi (operands); } +) + +(define_insn "extendhipsi2" + [(set (match_operand:PSI 0 "nonimmediate_operand" "=r") + (subreg:PSI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) 0))] + "TARGET_LARGE" + "RLAM #4, %0 { RRAM #4, %0" +) + +;; Look for cases where integer/pointer conversions are suboptimal due +;; to missing patterns, despite us not having opcodes for these +;; patterns. Doing these manually allows for alternate optimization +;; paths. +(define_insn "zero_extendhisi2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))] + "TARGET_LARGE" + "MOV.W\t#0,%H0" +) + +(define_insn "zero_extendhisipsi2" + [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r") + (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))] + "TARGET_LARGE" + "@ + AND.W\t#-1,%0 + MOV.W\t%1,%0" +) + +(define_insn "extend_and_shift1_hipsi2" + [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0) + (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) + (const_int 1)))] + "TARGET_LARGE" + "RLAM #4, %0 { RRAM #3, %0" +) + +(define_insn "extend_and_shift2_hipsi2" + [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0) + (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) + (const_int 2)))] + "TARGET_LARGE" + "RLAM #4, %0 { RRAM #2, %0" +) + +; Nasty - we are sign-extending a 20-bit PSI value in one register into +; two adjacent 16-bit registers to make an SI value. There is no MSP430X +; instruction that will do this, so we push the 20-bit value onto the stack +; and then pop it off as two 16-bit values. +; +; FIXME: The MSP430X documentation does not specify if zero-extension or +; sign-extension happens when the 20-bit value is pushed onto the stack. +; It is probably zero-extension, but if not this pattern will not work +; when the PSI value is negative.. +; +; Note: using PUSHM.A #1 is two bytes smaller than using PUSHX.A.... + +(define_insn "zero_extendpsisi2" + [(set (match_operand:SI 0 "register_operand" "=r") + (zero_extend:SI (match_operand:PSI 1 "register_operand" "r")))] + "" + "* + if (REGNO (operands[1]) == SP_REGNO) + /* If the source register is the stack pointer, the value + stored in the stack slot will be the value *after* the + stack pointer has been decremented. So allow for that + here. */ + return \"PUSHM.A #1, %1 { ADDX.W #4, @r1 { POPX.W %0 { POPX.W %H0\"; + else + return \"PUSHM.A #1, %1 { POPX.W %0 { POPX.W %H0\"; + " +) + +; See the movsipsi2 pattern above for another way that GCC performs this +; conversion. +(define_insn "truncsipsi2" + [(set (match_operand:PSI 0 "register_operand" "=r") + (truncate:PSI (match_operand:SI 1 "register_operand" "r")))] + "" + "PUSH.W %H1 { PUSH.W %1 { POPM.A #1, %0" +) + +;;------------------------------------------------------------ +;; Shift Functions + +;; Note: We do not use the RPT ... SHIFT instruction sequence +;; when the repeat count is in a register, because even though RPT +;; accepts counts in registers, it does not work if the count is +;; zero, and the actual count in the register has to be one less +;; than the required number of iterations. We could encode a +;; seqeunce like this: +;; +;; bit #0xf, Rn +;; bz 1f +;; dec Rn +;; rpt Rn +;; <shift> Rm +;; inc Rn +;; 1: +;; +;; But is longer than calling a helper function, and we are mostly +;; concerned with code size. FIXME: Maybe enable a sequence like +;; this at -O3 and above ? +;; +;; Note - we ignore shift counts of less than one or more than 15. +;; This is permitted by the ISO C99 standard as such shifts result +;; in "undefined" behaviour. [6.5.7 (3)] + +;; signed A << C + +(define_expand "ashlhi3" + [(set (match_operand:HI 0 "nonimmediate_operand") + (ashift:HI (match_operand:HI 1 "general_operand") + (match_operand:HI 2 "general_operand")))] + "" + { + if (msp430x + && REG_P (operands[0]) + && REG_P (operands[1]) + && CONST_INT_P (operands[2])) + emit_insn (gen_430x_shift_left (operands[0], operands[1], operands[2])); + else + msp430_expand_helper (operands, \"__mspabi_slli\", true); + DONE; + } +) + +(define_insn "slli_1" + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") + (ashift:HI (match_operand:HI 1 "general_operand" "0") + (const_int 1)))] + "" + "RLA.W\t%0" ;; Note - this is a macro for ADD +) + +(define_insn "430x_shift_left" + [(set (match_operand:HI 0 "register_operand" "=r") + (ashift:HI (match_operand:HI 1 "register_operand" "0") + (match_operand 2 "immediate_operand" "n")))] + "msp430x" + "* + if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16) + return \"rpt\t%2 { rlax.w\t%0\"; + return \"# nop left shift\"; + " +) + +(define_insn "slll_1" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (ashift:SI (match_operand:SI 1 "general_operand" "0") + (const_int 1)))] + "" + "RLA.W\t%L0 { RLC.W\t%H0" +) + +(define_insn "slll_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (ashift:SI (match_operand:SI 1 "general_operand" "0") + (const_int 2)))] + "" + "RLA.W\t%L0 { RLC.W\t%H0 { RLA.W\t%L0 { RLC.W\t%H0" +) + +(define_expand "ashlsi3" + [(set (match_operand:SI 0 "nonimmediate_operand") + (ashift:SI (match_operand:SI 1 "general_operand") + (match_operand:SI 2 "general_operand")))] + "" + "msp430_expand_helper (operands, \"__mspabi_slll\", true); + DONE;" +) + +;;---------- + +;; signed A >> C + +(define_expand "ashrhi3" + [(set (match_operand:HI 0 "nonimmediate_operand") + (ashiftrt:HI (match_operand:HI 1 "general_operand") + (match_operand:HI 2 "general_operand")))] + "" + { + if (msp430x + && REG_P (operands[0]) + && REG_P (operands[1]) + && CONST_INT_P (operands[2])) + emit_insn (gen_430x_arithmetic_shift_right (operands[0], operands[1], operands[2])); + else + msp430_expand_helper (operands, \"__mspabi_srai\", true); + DONE; + } +) + +(define_insn "srai_1" + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") + (ashiftrt:HI (match_operand:HI 1 "general_operand" "0") + (const_int 1)))] + "" + "RRA.W\t%0" +) + +(define_insn "430x_arithmetic_shift_right" + [(set (match_operand:HI 0 "register_operand" "=r") + (ashiftrt:HI (match_operand:HI 1 "register_operand" "0") + (match_operand 2 "immediate_operand" "n")))] + "msp430x" + "* + if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 16) + return \"rpt\t%2 { rrax.w\t%0\"; + return \"# nop arith right shift\"; + " +) + +(define_insn "srap_1" + [(set (match_operand:PSI 0 "register_operand" "=r") + (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0") + (const_int 1)))] + "msp430x" + "RRAM.A #1,%0" +) + +(define_insn "srap_2" + [(set (match_operand:PSI 0 "register_operand" "=r") + (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "0") + (const_int 2)))] + "msp430x" + "RRAM.A #2,%0" +) + +(define_insn "sral_1" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (ashiftrt:SI (match_operand:SI 1 "general_operand" "0") + (const_int 1)))] + "" + "RRA.W\t%H0 { RRC.W\t%L0" +) + +(define_insn "sral_2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (ashiftrt:SI (match_operand:SI 1 "general_operand" "0") + (const_int 2)))] + "" + "RRA.W\t%H0 { RRC.W\t%L0 { RRA.W\t%H0 { RRC.W\t%L0" +) + +(define_expand "ashrsi3" + [(set (match_operand:SI 0 "nonimmediate_operand") + (ashiftrt:SI (match_operand:SI 1 "general_operand") + (match_operand:SI 2 "general_operand")))] + "" + "msp430_expand_helper (operands, \"__mspabi_sral\", true); + DONE;" +) + +;;---------- + +;; unsigned A >> C + +(define_expand "lshrhi3" + [(set (match_operand:HI 0 "nonimmediate_operand") + (lshiftrt:HI (match_operand:HI 1 "general_operand") + (match_operand:HI 2 "general_operand")))] + "" + { + if (msp430x + && REG_P (operands[0]) + && REG_P (operands[1]) + && CONST_INT_P (operands[2])) + emit_insn (gen_430x_logical_shift_right (operands[0], operands[1], operands[2])); + else + msp430_expand_helper (operands, \"__mspabi_srli\", true); + DONE; + } +) + +(define_insn "srli_1" + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") + (lshiftrt:HI (match_operand:HI 1 "general_operand" "0") + (const_int 1)))] + "" + "CLRC { RRC.W\t%0" +) + +(define_insn "430x_logical_shift_right" + [(set (match_operand:HI 0 "register_operand" "=r") + (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") + (match_operand 2 "immediate_operand" "n")))] + "msp430x" + { + return msp430x_logical_shift_right (operands[2]); + } +) + +(define_insn "srlp_1" + [(set (match_operand:PSI 0 "register_operand" "=r") + (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "0") + (const_int 1)))] + "" + "RRUM.A #1,%0" +) + +(define_insn "srll_1" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") + (const_int 1)))] + "" + "CLRC { RRC.W\t%H0 { RRC.W\t%L0" +) + +(define_insn "srll_2x" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r") + (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") + (const_int 2)))] + "msp430x" + "RRUX.W\t%H0 { RRC.W\t%L0 { RRUX.W\t%H0 { RRC.W\t%L0" +) + +(define_expand "lshrsi3" + [(set (match_operand:SI 0 "nonimmediate_operand") + (lshiftrt:SI (match_operand:SI 1 "general_operand") + (match_operand:SI 2 "general_operand")))] + "" + "msp430_expand_helper (operands, \"__mspabi_srll\", true); + DONE;" +) + +;;------------------------------------------------------------ +;; Function Entry/Exit + +(define_expand "prologue" + [(const_int 0)] + "" + "msp430_expand_prologue (); DONE;" + ) + +(define_expand "epilogue" + [(const_int 0)] + "" + "msp430_expand_epilogue (0); DONE;" + ) + + +(define_insn "epilogue_helper" + [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] UNS_EPILOGUE_HELPER)] + "" + "BR%A0\t#__mspabi_func_epilog_%D0" + ) + + +(define_insn "prologue_start_marker" + [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_START_MARKER)] + "" + "; start of prologue" + ) + +(define_insn "prologue_end_marker" + [(unspec_volatile [(const_int 0)] UNS_PROLOGUE_END_MARKER)] + "" + "; end of prologue" + ) + +(define_insn "epilogue_start_marker" + [(unspec_volatile [(const_int 0)] UNS_EPILOGUE_START_MARKER)] + "" + "; start of epilogue" + ) + +;;------------------------------------------------------------ +;; Jumps + +(define_expand "call" + [(call:HI (match_operand 0 "") + (match_operand 1 ""))] + "" + "" +) + +(define_insn "call_internal" + [(call (mem:HI (match_operand 0 "general_operand" "rmi")) + (match_operand 1 ""))] + "" + "CALL%A0\t%0" +) + +(define_expand "call_value" + [(set (match_operand 0 "register_operand") + (call:HI (match_operand 1 "general_operand") + (match_operand 2 "")))] + "" + "" +) + +(define_insn "call_value_internal" + [(set (match_operand 0 "register_operand" "=r") + (call (mem:HI (match_operand 1 "general_operand" "rmi")) + (match_operand 2 "")))] + "" + "CALL%A0\t%1" +) + +(define_insn "msp_return" + [(return)] + "" + { return msp430_is_interrupt_func () ? "RETI" : (TARGET_LARGE ? "RETA" : "RET"); } +) + +;; This pattern is NOT, as expected, a return pattern. It's called +;; before reload and must only store its operands, and emit a +;; placeholder where the epilog needs to be. AFTER reload, the +;; placeholder should get expanded into a regular-type epilogue that +;; also does the EH return. +(define_expand "eh_return" + [(match_operand:HI 0 "" "")] + "" + "msp430_expand_eh_return (operands[0]); + emit_jump_insn (gen_msp430_eh_epilogue ()); + emit_barrier (); + DONE;" +) + +;; This is the actual EH epilogue. We emit it in the pattern above, +;; before reload, and convert it to a real epilogue after reload. +(define_insn_and_split "msp430_eh_epilogue" + [(eh_return)] + "" + "#" + "reload_completed" + [(const_int 0)] + "msp430_expand_epilogue (1); DONE;" + ) + +(define_insn "jump" + [(set (pc) + (label_ref (match_operand 0 "" "")))] + "" + "BR%A0\t#%l0" +) + +;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs +;; in indirect jumps (cf gcc.c-torture/compile/991213-3.c). +(define_insn "indirect_jump" + [(set (pc) + (match_operand 0 "nonimmediate_operand" "rYl"))] + "" + "BR%A0\t%0" +) + +;;------------------------------------------------------------ +;; Various Conditionals + +(define_expand "cbranch<mode>4" + [(parallel [(set (pc) (if_then_else + (match_operator 0 "" + [(match_operand:QHI 1 "nonimmediate_operand") + (match_operand:QHI 2 "general_operand")]) + (label_ref (match_operand 3 "" "")) + (pc))) + (clobber (reg:BI CARRY))] + )] + "" + "msp430_fixup_compare_operands (<MODE>mode, operands);" + ) + +(define_insn "cbranchpsi4_real" + [(set (pc) (if_then_else + (match_operator 0 "msp430_cmp_operator" + [(match_operand:PSI 1 "nonimmediate_operand" "r,rYs,rm") + (match_operand:PSI 2 "general_operand" "rLs,rYsi,rmi")]) + (label_ref (match_operand 3 "" "")) + (pc))) + (clobber (reg:BI CARRY)) + ] + "" + "@ + CMP%A0\t%2, %1 { J%0\t%l3 + CMPX.A\t%2, %1 { J%0\t%l3 + CMPX.A\t%2, %1 { J%0\t%l3" + ) + +(define_insn "cbranchqi4_real" + [(set (pc) (if_then_else + (match_operator 0 "msp430_cmp_operator" + [(match_operand:QI 1 "nonimmediate_operand" "rYs,rm") + (match_operand:QI 2 "general_operand" "rYsi,rmi")]) + (label_ref (match_operand 3 "" "")) + (pc))) + (clobber (reg:BI CARRY)) + ] + "" + "@ + CMP.B\t%2, %1 { J%0\t%l3 + CMP%X0.B\t%2, %1 { J%0\t%l3" + ) + +(define_insn "cbranchhi4_real" + [(set (pc) (if_then_else + (match_operator 0 "msp430_cmp_operator" + [(match_operand:HI 1 "nonimmediate_operand" "rYs,rm") + (match_operand:HI 2 "general_operand" "rYsi,rmi")]) + (label_ref (match_operand 3 "" "")) + (pc))) + (clobber (reg:BI CARRY)) + ] + "" + "@ + CMP.W\t%2, %1 { J%0\t%l3 + CMP%X0.W\t%2, %1 { J%0\t%l3" + ) + +(define_insn "cbranchpsi4_reversed" + [(set (pc) (if_then_else + (match_operator 0 "msp430_reversible_cmp_operator" + [(match_operand:PSI 1 "general_operand" "rLs,rYsi,rmi") + (match_operand:PSI 2 "general_operand" "r,rYs,rm")]) + (label_ref (match_operand 3 "" "")) + (pc))) + (clobber (reg:BI CARRY)) + ] + "" + "@ + CMP%A0\t%1, %2 { J%R0\t%l3 + CMPX.A\t%1, %2 { J%R0\t%l3 + CMPX.A\t%1, %2 { J%R0\t%l3" + ) + +(define_insn "cbranchqi4_reversed" + [(set (pc) (if_then_else + (match_operator 0 "msp430_reversible_cmp_operator" + [(match_operand:QI 1 "general_operand" "rYsi,rmi") + (match_operand:QI 2 "general_operand" "rYs,rm")]) + (label_ref (match_operand 3 "" "")) + (pc))) + (clobber (reg:BI CARRY)) + ] + "" + "@ + CMP.B\t%1, %2 { J%R0\t%l3 + CMP%X0.B\t%1, %2 { J%R0\t%l3" + ) + +(define_insn "cbranchhi4_reversed" + [(set (pc) (if_then_else + (match_operator 0 "msp430_reversible_cmp_operator" + [(match_operand:HI 1 "general_operand" "rYsi,rmi") + (match_operand:HI 2 "general_operand" "rYs,rm")]) + (label_ref (match_operand 3 "" "")) + (pc))) + (clobber (reg:BI CARRY)) + ] + "" + "@ + CMP.W\t%1, %2 { J%R0\t%l3 + 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") + (match_operand:QHI 1 "msp_general_operand" "rYsi,rmi")) + (const_int 0)) + (label_ref (match_operand 2 "" "")) + (pc))) + (clobber (reg:BI CARRY)) + ] + "" + "@ + BIT%x0%B0\t%1, %0 { JNE\t%l2 + BIT%X0%B0\t%1, %0 { JNE\t%l2" + ) + +(define_insn "*bitbranch<mode>4" + [(set (pc) (if_then_else + (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm") + (match_operand:QHI 1 "msp_general_operand" "rmi")) + (const_int 0)) + (label_ref (match_operand 2 "" "")) + (pc))) + (clobber (reg:BI CARRY)) + ] + "" + "BIT%x0%X0%B0\t%1, %0 { JEQ\t%l2" + ) + +(define_insn "*bitbranch<mode>4" + [(set (pc) (if_then_else + (eq (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm") + (match_operand:QHI 1 "msp_general_operand" "rmi")) + (const_int 0)) + (pc) + (label_ref (match_operand 2 "" "")))) + (clobber (reg:BI CARRY)) + ] + "" + "BIT%X0%B0\t%1, %0 { JNE\t%l2" + ) + +(define_insn "*bitbranch<mode>4" + [(set (pc) (if_then_else + (ne (and:QHI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm") + (match_operand:QHI 1 "msp_general_operand" "rmi")) + (const_int 0)) + (pc) + (label_ref (match_operand 2 "" "")))) + (clobber (reg:BI CARRY)) + ] + "" + "BIT%X0%B0\t%1, %0 { JEQ\t%l2" + ) + +;;------------------------------------------------------------ +;; zero-extract versions of the above + +(define_insn "*bitbranch<mode>4_z" + [(set (pc) (if_then_else + (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rYs,rm") + (const_int 1) + (match_operand 1 "msp430_bitpos" "i,i")) + (const_int 0)) + (label_ref (match_operand 2 "" "")) + (pc))) + (clobber (reg:BI CARRY)) + ] + "" + "@ + BIT%x0%B0\t%p1, %0 { JNE\t%l2 + BIT%X0%B0\t%p1, %0 { JNE\t%l2" + ) + +(define_insn "*bitbranch<mode>4_z" + [(set (pc) (if_then_else + (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm") + (const_int 1) + (match_operand 1 "msp430_bitpos" "i")) + (const_int 0)) + (label_ref (match_operand 2 "" "")) + (pc))) + (clobber (reg:BI CARRY)) + ] + "" + "BIT%x0%X0%B0\t%p1, %0 { JEQ\t%l2" + ) + +(define_insn "*bitbranch<mode>4_z" + [(set (pc) (if_then_else + (eq (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm") + (const_int 1) + (match_operand 1 "msp430_bitpos" "i")) + (const_int 0)) + (pc) + (label_ref (match_operand 2 "" "")))) + (clobber (reg:BI CARRY)) + ] + "" + "BIT%X0%B0\t%p1, %0 { JNE\t%l2" + ) + +(define_insn "*bitbranch<mode>4_z" + [(set (pc) (if_then_else + (ne (zero_extract:HI (match_operand:QHI 0 "msp_nonimmediate_operand" "rm") + (const_int 1) + (match_operand 1 "msp430_bitpos" "i")) + (const_int 0)) + (pc) + (label_ref (match_operand 2 "" "")))) + (clobber (reg:BI CARRY)) + ] + "" + "BIT%X0%B0\t%p1, %0 { JEQ\t%l2" + ) + +;;------------------------------------------------------------ +;; Misc + +(define_insn "nop" + [(const_int 0)] + "1" + "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/msp430/msp430.opt b/gcc/config/msp430/msp430.opt new file mode 100644 index 00000000000..6d4fc347e1a --- /dev/null +++ b/gcc/config/msp430/msp430.opt @@ -0,0 +1,26 @@ +msim +Target +Use simulator runtime + +masm-hex +Target Mask(ASM_HEX) +Force assembly output to always use hex constants + +mmcu= +Target Joined RejectNegative Var(target_cpu) +Specify the cpu to build for. If the name begins with 'msp430x' then the 430X instructions are enabled + +mlarge +Target Mask(LARGE) RejectNegative +Select large model - 20-bit addresses/pointers + +msmall +Target InverseMask(LARGE) RejectNegative +Select small model - 16-bit addresses/pointers (default) + +mrelax +Target Report +Optimize opcode sizes at link time + +mOs +Target Undocumented Mask(OPT_SPACE) diff --git a/gcc/config/msp430/predicates.md b/gcc/config/msp430/predicates.md new file mode 100644 index 00000000000..6f99caa94eb --- /dev/null +++ b/gcc/config/msp430/predicates.md @@ -0,0 +1,80 @@ +;; Machine Description for TI MSP43* processors +;; Copyright (C) 2013 Free Software Foundation, Inc. +;; Contributed by Red Hat. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; <http://www.gnu.org/licenses/>. + +(define_predicate "msp_volatile_memory_operand" + (and (match_code "mem") + (match_test ("memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0), MEM_ADDR_SPACE (op))"))) +) + +; TRUE for any valid general operand. We do this because +; general_operand refuses to match volatile memory refs. + +(define_predicate "msp_general_operand" + (ior (match_operand 0 "general_operand") + (match_operand 0 "msp_volatile_memory_operand")) +) + +; Likewise for nonimmediate_operand. + +(define_predicate "msp_nonimmediate_operand" + (ior (match_operand 0 "nonimmediate_operand") + (match_operand 0 "msp_volatile_memory_operand")) +) + +(define_predicate "ubyte_operand" + (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), 0, 255)"))) + +; TRUE for comparisons we support. +(define_predicate "msp430_cmp_operator" + (match_code "eq,ne,lt,ltu,ge,geu")) + +; TRUE for comparisons we need to reverse. +(define_predicate "msp430_reversible_cmp_operator" + (match_code "gt,gtu,le,leu")) + +; TRUE for constants the constant generator can produce +(define_predicate "msp430_constgen_operator" + (and (match_code "const_int") + (match_test (" INTVAL (op) == 0 + || INTVAL (op) == 1 + || INTVAL (op) == 2 + || INTVAL (op) == 4 + || INTVAL (op) == 8 + || INTVAL (op) == -1 ")))) + +; TRUE for constants the constant generator can produce +(define_predicate "msp430_inv_constgen_operator" + (and (match_code "const_int") + (match_test (" INTVAL (op) == ~0 + || INTVAL (op) == ~1 + || INTVAL (op) == ~2 + || INTVAL (op) == ~4 + || INTVAL (op) == ~8 + || INTVAL (op) == ~(-1) ")))) + +(define_predicate "msp430_nonsubreg_operand" + (match_code "reg,mem")) + +; TRUE for constants which are bit positions for zero_extract +(define_predicate "msp430_bitpos" + (and (match_code "const_int") + (match_test (" INTVAL (op) >= 0 + && INTVAL (op) <= 15 ")))) diff --git a/gcc/config/msp430/t-msp430 b/gcc/config/msp430/t-msp430 new file mode 100644 index 00000000000..c7048378da4 --- /dev/null +++ b/gcc/config/msp430/t-msp430 @@ -0,0 +1,43 @@ +# Makefile fragment for building GCC for the TI MSP430 target. +# Copyright (C) 2012-2013 Free Software Foundation, Inc. +# Contributed by Red Hat. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published +# by the Free Software Foundation; either version 3, or (at your +# option) any later version. +# +# GCC is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +# the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# Enable multilibs: + +MULTILIB_OPTIONS = mmcu=msp430x mlarge +MULTILIB_DIRNAMES = 430x large + +# Match msp430X with msp430x. +MULTILIB_MATCHES = mmcu?msp430x=mmcu?msp430X + +# each supported MCU needs a line like this: +# MULTILIB_MATCHES += mmcu?msp430x123=mmcu?msp430x + +# The only way I figured this out was to hack the script to SHOW me +# what it's doing. It's non-obvious, but it matches the directory +# structure of the multilib tree, but using the options, not the +# directory names. A shell CASE statement is generated from these, so +# the usual CASE wildcards are supported. + +MULTILIB_EXCEPTIONS = mlarge + +MULTILIB_EXTRA_OPTS = + +msp430-c.o: $(srcdir)/config/msp430/msp430-c.c $(RTL_H) $(TREE_H) $(CONFIG_H) $(TM_H) + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 74a99e36a01..b6f54108214 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -4035,7 +4035,8 @@ pa_expand_prologue (void) || (! TARGET_64BIT && df_regs_ever_live_p (i + 1))) { rtx addr, insn, reg; - addr = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (DFmode, tmpreg)); + addr = gen_rtx_MEM (DFmode, + gen_rtx_POST_INC (word_mode, tmpreg)); reg = gen_rtx_REG (DFmode, i); insn = emit_move_insn (addr, reg); if (DO_FRAME_NOTES) @@ -4328,7 +4329,8 @@ pa_expand_epilogue (void) if (df_regs_ever_live_p (i) || (! TARGET_64BIT && df_regs_ever_live_p (i + 1))) { - rtx src = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (DFmode, tmpreg)); + rtx src = gen_rtx_MEM (DFmode, + gen_rtx_POST_INC (word_mode, tmpreg)); rtx dest = gen_rtx_REG (DFmode, i); emit_move_insn (dest, src); } diff --git a/gcc/config/rl78/constraints.md b/gcc/config/rl78/constraints.md index 8b03cf32211..bb0e40c6a32 100644 --- a/gcc/config/rl78/constraints.md +++ b/gcc/config/rl78/constraints.md @@ -43,6 +43,7 @@ ; Y - any valid memory ; Wxx - various memory addressing modes ; Qxx - conditionals +; U = usual memory references mov-able to/from AX ; v = virtual registers ; Zxx = specific virtual registers @@ -56,6 +57,56 @@ (and (match_code "const_int") (match_test "IN_RANGE (ival, 1, 7)"))) +(define_constraint "Iv08" + "@internal + Integer constant equal to 8." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, 8, 8)"))) +(define_constraint "Iv16" + "@internal + Integer constant equal to 16." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, 16, 16)"))) +(define_constraint "Iv24" + "@internal + Integer constant equal to 24." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, 24, 24)"))) + +(define_constraint "Is09" + "@internal + Integer constant in the range 9 @dots{} 15 (for shifts)." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, 9, 15)"))) +(define_constraint "Is17" + "@internal + Integer constant in the range 17 @dots{} 23 (for shifts)." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, 17, 23)"))) +(define_constraint "Is25" + "@internal + Integer constant in the range 25 @dots{} 31 (for shifts)." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, 25, 31)"))) + +(define_constraint "ISsi" + "@internal + Integer constant with bit 31 set." + (and (match_code "const_int") + (match_test "(ival & 0x80000000) != 0"))) + +(define_constraint "IShi" + "@internal + Integer constant with bit 15 set." + (and (match_code "const_int") + (match_test "(ival & 0x8000) != 0"))) + +(define_constraint "ISqi" + "@internal + Integer constant with bit 7 set." + (and (match_code "const_int") + (match_test "(ival & 0x80) != 0"))) + (define_constraint "J" "Integer constant in the range -255 @dots{} 0" (and (match_code "const_int") @@ -152,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 @@ -174,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 @@ -208,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") @@ -224,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 @@ -243,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/predicates.md b/gcc/config/rl78/predicates.md index 33ce900bffa..99ee656aad5 100644 --- a/gcc/config/rl78/predicates.md +++ b/gcc/config/rl78/predicates.md @@ -46,6 +46,8 @@ (and (match_code "const_int") (match_test "IN_RANGE (INTVAL (op), 0, 65536)")))) +(define_predicate "rl78_cmp_operator_signed" + (match_code "gt,ge,lt,le")) (define_predicate "rl78_cmp_operator_real" (match_code "eq,ne,gtu,ltu,geu,leu")) (define_predicate "rl78_cmp_operator" @@ -58,3 +60,12 @@ (define_predicate "rl78_addw_operand" (and (match_code "reg") (match_test "REGNO (op) == AX_REG || REGNO (op) == SP_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER"))) + +(define_predicate "rl78_stack_based_mem" + (and (match_code "mem") + (ior (and (match_code "reg" "0") + (match_test "REGNO (XEXP (op, 0)) == SP_REG")) + (and (match_code "plus" "0") + (and (match_code "reg" "00") + (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG") + (match_code "const_int" "01")))))) diff --git a/gcc/config/rl78/rl78-expand.md b/gcc/config/rl78/rl78-expand.md index 3f24b150bab..40c416251d3 100644 --- a/gcc/config/rl78/rl78-expand.md +++ b/gcc/config/rl78/rl78-expand.md @@ -35,9 +35,24 @@ if (GET_CODE (operand1) == SUBREG && GET_CODE (XEXP (operand1, 0)) == SYMBOL_REF) FAIL; + /* Similarly for (SUBREG (CONST (PLUS (SYMBOL_REF)))). + cf. g++.dg/abi/packed.C. */ + if (GET_CODE (operand1) == SUBREG + && GET_CODE (XEXP (operand1, 0)) == CONST + && GET_CODE (XEXP (XEXP (operand1, 0), 0)) == PLUS + && GET_CODE (XEXP (XEXP (XEXP (operand1, 0), 0), 0)) == SYMBOL_REF) + FAIL; + + /* Similarly for (SUBREG (CONST (PLUS (SYMBOL_REF)))). + cf. g++.dg/abi/packed.C. */ + if (GET_CODE (operand1) == SUBREG + && GET_CODE (XEXP (operand1, 0)) == CONST + && GET_CODE (XEXP (XEXP (operand1, 0), 0)) == PLUS + && GET_CODE (XEXP (XEXP (XEXP (operand1, 0), 0), 0)) == SYMBOL_REF) + FAIL; if (CONST_INT_P (operand1) && ! IN_RANGE (INTVAL (operand1), (-1 << 8) + 1, (1 << 8) - 1)) - gcc_unreachable(); + FAIL; } ) @@ -56,17 +71,27 @@ if (GET_CODE (operand1) == SUBREG && GET_CODE (XEXP (operand1, 0)) == SYMBOL_REF) FAIL; + /* Similarly for (SUBREG (CONST (PLUS (SYMBOL_REF)))). */ + if (GET_CODE (operand1) == SUBREG + && GET_CODE (XEXP (operand1, 0)) == CONST + && GET_CODE (XEXP (XEXP (operand1, 0), 0)) == PLUS + && GET_CODE (XEXP (XEXP (XEXP (operand1, 0), 0), 0)) == SYMBOL_REF) + FAIL; } ) -(define_expand "movsi" - [(set (match_operand:SI 0 "nonimmediate_operand") - (match_operand:SI 1 "general_operand"))] +(define_insn_and_split "movsi" + [(set (match_operand:SI 0 "nonimmediate_operand" "=vYS,v,Wfr") + (match_operand:SI 1 "general_operand" "viYS,Wfr,v"))] "" - { - rl78_expand_movsi (operands); - DONE; - } + "#" + "" + [(set (match_operand:HI 2 "nonimmediate_operand") + (match_operand:HI 4 "general_operand")) + (set (match_operand:HI 3 "nonimmediate_operand") + (match_operand:HI 5 "general_operand"))] + "rl78_split_movsi (operands);" + [(set_attr "valloc" "op1")] ) ;;---------- Conversions ------------------------ @@ -200,13 +225,33 @@ ) (define_expand "ashrsi3" - [(set (match_operand:SI 0 "register_operand") - (ashiftrt:SI (match_operand:SI 1 "register_operand") - (match_operand:SI 2 "immediate_operand"))) + [(parallel [(set (match_operand:SI 0 "nonimmediate_operand") + (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand") + (match_operand:SI 2 "nonmemory_operand"))) + (clobber (reg:HI X_REG))]) ] "" - "if (GET_CODE (operands[2]) != CONST_INT) - FAIL;" + "" +) + +(define_expand "lshrsi3" + [(parallel [(set (match_operand:SI 0 "nonimmediate_operand") + (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand") + (match_operand:SI 2 "nonmemory_operand"))) + (clobber (reg:HI X_REG))]) + ] + "" + "" +) + +(define_expand "ashlsi3" + [(parallel [(set (match_operand:SI 0 "nonimmediate_operand") + (ashift:SI (match_operand:SI 1 "nonimmediate_operand") + (match_operand:SI 2 "nonmemory_operand"))) + (clobber (reg:HI X_REG))]) + ] + "" + "" ) ;;---------- Branching ------------------------ @@ -254,3 +299,16 @@ "" "rl78_expand_compare (operands);" ) + +(define_expand "cbranchsi4" + [(parallel [(set (pc) (if_then_else + (match_operator 0 "rl78_cmp_operator" + [(match_operand:SI 1 "general_operand") + (match_operand:SI 2 "nonmemory_operand")]) + (label_ref (match_operand 3 "" "")) + (pc))) + (clobber (reg:HI AX_REG)) + ])] + "1" + "rl78_expand_compare (operands);" +) diff --git a/gcc/config/rl78/rl78-protos.h b/gcc/config/rl78/rl78-protos.h index b13c65065d1..1f30e637b72 100644 --- a/gcc/config/rl78/rl78-protos.h +++ b/gcc/config/rl78/rl78-protos.h @@ -21,6 +21,7 @@ void rl78_emit_eh_epilogue (rtx); void rl78_expand_compare (rtx *); void rl78_expand_movsi (rtx *); +void rl78_split_movsi (rtx *); int rl78_force_nonfar_2 (rtx *, rtx (*gen)(rtx,rtx)); int rl78_force_nonfar_3 (rtx *, rtx (*gen)(rtx,rtx,rtx)); void rl78_expand_eh_epilogue (rtx); @@ -41,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 76daaf17e84..90b380a54e4 100644 --- a/gcc/config/rl78/rl78-real.md +++ b/gcc/config/rl78/rl78-real.md @@ -312,11 +312,26 @@ call\t%A1" ) +(define_insn "cbranchqi4_real_signed" + [(set (pc) (if_then_else + (match_operator 0 "rl78_cmp_operator_signed" + [(match_operand:QI 1 "general_operand" "A,A,A") + (match_operand:QI 2 "general_operand" "ISqi,i,v")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "rl78_real_insns_ok ()" + "@ + cmp\t%1, %2 \;xor1 CY,%1.7\;not1 CY\;sk%c0 \;br\t!!%3 + cmp\t%1, %2 \;xor1 CY,%1.7\;sk%c0 \;br\t!!%3 + cmp\t%1, %2 \;xor1 CY,%1.7\;xor1 CY,%2.7\;sk%c0 \;br\t!!%3" + ) + + (define_insn "*cbranchqi4_real" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator_real" - [(match_operand:QI 1 "general_operand" "Wabvaxbc,a, v,bcdehl") - (match_operand:QI 2 "general_operand" "M, irWhlWh1Whb,i,a")]) + [(match_operand:QI 1 "general_operand" "Wabvaxbc,a, v,bcdehl") + (match_operand:QI 2 "general_operand" "M, irvWabWhlWh1Whb,i,a")]) (label_ref (match_operand 3 "" "")) (pc)))] "rl78_real_insns_ok ()" @@ -327,13 +342,175 @@ cmp\t%1, %2 \;sk%c0 \;br\t!!%3" ) -(define_insn "*cbranchhi4_real" +(define_insn "cbranchhi4_real_signed" [(set (pc) (if_then_else - (match_operator 0 "rl78_cmp_operator_real" - [(match_operand:HI 1 "general_operand" "A") - (match_operand:HI 2 "general_operand" "iBDTWhlWh1")]) - (label_ref (match_operand 3 "" "")) + (match_operator 0 "rl78_cmp_operator_signed" + [(match_operand:HI 1 "general_operand" "A,A,A,vR") + (match_operand:HI 2 "general_operand" "IShi,i,v,1")]) + (label_ref (match_operand 3)) + (pc)))] + "rl78_real_insns_ok ()" + "@ + cmpw\t%1, %2 \;xor1 CY,%Q1.7\;not1 CY\;sk%c0 \;br\t!!%3 + cmpw\t%1, %2 \;xor1 CY,%Q1.7\;sk%c0 \;br\t!!%3 + cmpw\t%1, %2 \;xor1 CY,%Q1.7\;xor1 CY,%Q2.7\;sk%c0 \;br\t!!%3 + %z0\t!!%3" + ) + +(define_insn "cbranchhi4_real" + [(set (pc) (if_then_else + (match_operator 0 "rl78_cmp_operator_real" + [(match_operand:HI 1 "general_operand" "A,vR") + (match_operand:HI 2 "general_operand" "iBDTvWabWhlWh1,1")]) + (label_ref (match_operand 3 "" "")) (pc)))] "rl78_real_insns_ok ()" + "@ + cmpw\t%1, %2 \;sk%c0 \;br\t!!%3 + %z0\t!!%3" + ) + +(define_insn "cbranchhi4_real_inverted" + [(set (pc) (if_then_else + (match_operator 0 "rl78_cmp_operator_real" + [(match_operand:HI 1 "general_operand" "A") + (match_operand:HI 2 "general_operand" "iBDTvWabWhlWh1")]) + (pc) + (label_ref (match_operand 3 "" ""))))] + "rl78_real_insns_ok ()" "cmpw\t%1, %2 \;sk%c0 \;br\t!!%3" ) + +(define_insn "cbranchsi4_real_lt" + [(set (pc) (if_then_else + (lt (match_operand:SI 0 "general_operand" "U,vWabWhlWh1") + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc))) + (clobber (reg:HI AX_REG)) + ] + "rl78_real_insns_ok ()" + "@ + mov a, %E0 \;mov1 CY,a.7 \;sknc \;br\t!!%1 + mov1 CY,%E0.7 \;sknc \;br\t!!%1" + ) + +(define_insn "cbranchsi4_real_ge" + [(set (pc) (if_then_else + (ge (match_operand:SI 0 "general_operand" "U,vWabWhlWh1") + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc))) + (clobber (reg:HI AX_REG)) + ] + "rl78_real_insns_ok ()" + "@ + mov a, %E0 \;mov1 CY,a.7 \;skc \;br\t!!%1 + mov1 CY,%E0.7 \;skc \;br\t!!%1" + ) + +(define_insn "cbranchsi4_real_signed" + [(set (pc) (if_then_else + (match_operator 0 "rl78_cmp_operator_signed" + [(match_operand:SI 1 "nonimmediate_operand" "vU,vU,vU") + (match_operand:SI 2 "nonmemory_operand" "ISsi,i,v")]) + (label_ref (match_operand 3 "" "")) + (pc))) + (clobber (reg:HI AX_REG)) + ] + "rl78_real_insns_ok ()" + "@ + movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\;not1 CY\; movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%c0 \;br\t!!%3 + movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\; movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%c0 \;br\t!!%3 + movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\;xor1 CY,%E2.7\;movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%c0 \;br\t!!%3" + ) + +(define_insn "cbranchsi4_real" + [(set (pc) (if_then_else + (match_operator 0 "rl78_cmp_operator_real" + [(match_operand:SI 1 "general_operand" "vUi") + (match_operand:SI 2 "general_operand" "iWhlWh1v")]) + (label_ref (match_operand 3 "" "")) + (pc))) + (clobber (reg:HI AX_REG)) + ] + "rl78_real_insns_ok ()" + "movw ax,%H1 \;cmpw ax, %H2 \;movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%c0 \;br\t!!%3" + ) + +;; Peephole to match: +;; +;; (set (mem (sp)) (ax)) +;; (set (ax) (mem (sp))) +;; or: +;; (set (mem (plus (sp) (const)) (ax)) +;; (set (ax) (mem (plus (sp) (const)))) +;; +;; which can be generated as the last instruction of the conversion +;; of one virtual insn into a real insn and the first instruction of +;; the conversion of the following virtual insn. + +(define_peephole2 + [(set (match_operand:HI 0 "rl78_stack_based_mem") + (reg:HI AX_REG)) + (set (reg:HI AX_REG) + (match_dup 0))] + "" + [(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-virt.md b/gcc/config/rl78/rl78-virt.md index d73a51484ba..dc50e3b34e5 100644 --- a/gcc/config/rl78/rl78-virt.md +++ b/gcc/config/rl78/rl78-virt.md @@ -161,20 +161,130 @@ "v.shr\t%0, %1, %2" ) -;; really a macro -(define_insn "*ashrsi3_virt" - [(set (match_operand:SI 0 "register_operand" "=v,v,v") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,v,0") - (match_operand:SI 2 "immediate_operand" "M,K,i"))) +;; This is complex mostly because the RL78 has no SImode operations, +;; and very limited HImode operations, and no variable shifts. This +;; pattern is optimized for each constant shift count and operand +;; types, so as to use a hand-optimized pattern. For readability, the +;; usual \t\; syntax is not used here. Also, there's no easy way to +;; constrain to avoid partial overlaps, hence the duplication. +(define_insn "ashrsi3_virt" ;; 0 1 2-7 8 9-15 16 17-23 24 25-31 var + [(set (match_operand:SI 0 "nonimmediate_operand" "=v,vU,&vU,v, &vU, &vU, v, &vU, v, &vU, &vU, vU, v,&vU, vU, vU, vU") + (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0, 0, vU,0, vWab, U, 0, vU, 0, vWab,U, vU, 0, vU, vU, vU, 0") + (match_operand:SI 2 "nonmemory_operand" "M, K, K, Int3,Int3,Int3,Iv08,Iv08,Is09,Is09,Is09,Iv16,Is17,Is17,Iv24,Is25, iv"))) + (clobber (reg:HI X_REG)) + ] + "" + "@ + ; ashrsi %0, 0 + + movw ax,%H1 \; sarw ax,1 \; movw %H0,ax \; mov a,%Q1 \; rorc a,1 \; mov %Q0,a \; mov a,%q1 \; rorc a,1 \; mov %q0,a + movw ax,%H1 \; sarw ax,1 \; movw %H0,ax \; mov a,%Q1 \; rorc a,1 \; mov %Q0,a \; mov a,%q1 \; rorc a,1 \; mov %q0,a + + movw ax,%1 \; shlw ax,%r2 \; mov %0,a \; mov x,%Q1 \; mov a,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; sarw ax,%u2 \; movw %H0,ax + movw ax,%1 \; shlw ax,%r2 \; mov %0,a \; mov x,%Q1 \; mov a,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; sarw ax,%u2 \; movw %H0,ax + movw ax,%1 \; shlw ax,%r2 \; mov %0,a \; mov a,%Q1 \; mov x,a \; mov a,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; sarw ax,%u2 \; movw %H0,ax + + mov x,%Q1 \; mov a,%H1 \; movw %0,ax \; movw ax,%H1 \; sarw ax,8 \; movw %H0,ax + mov a,%Q1 \; mov x, a \; mov a,%H1 \; movw %0,ax \; movw ax,%H1 \; sarw ax,8 \; movw %H0,ax + + mov x,%Q1 \; mov a,%H1 \; shlw ax,%r2 \; mov %0,a \; movw ax,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; sarw ax,%u2 \; movw %H0,ax + mov x,%Q1 \; mov a,%H1 \; shlw ax,%r2 \; mov %0,a \; movw ax,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; sarw ax,%u2 \; movw %H0,ax + mov a,%Q1 \; mov x,a \; mov a,%H1 \; shlw ax,%r2 \; mov %0,a \; movw ax,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; sarw ax,%u2 \; movw %H0,ax + + movw ax,%H1 \; movw %0,ax \; sarw ax,15 \; movw %H0,ax + + movw ax,%H1 \; sarw ax,%S2 \; movw %0,ax \; sarw ax,15 \; movw %H0,ax + movw ax,%H1 \; sarw ax,%S2 \; movw %0,ax \; sarw ax,15 \; movw %H0,ax + + movw ax,%H1 \; mov %0,a \; sarw ax,15 \; movw %H0,ax \; mov %Q0,a + + movw ax,%H1 \; sar a,%s2 \; mov %0,a \; sarw ax,15 \; movw %H0,ax \; mov %Q0,a + + mov b,%2 \; cmp0 b \; bz $2f \; 1: \; movw ax,%H1 \; sarw ax,1 \; movw %H0,ax \; mov a,%Q1 \; rorc a,1 \; mov %Q0,a \; mov a,%q1 \; rorc a,1 \; mov %q0,a \; dec b \; bnz $1b \; 2:" + [(set_attr "valloc" "macax")] +) + +;; Likewise. +(define_insn "lshrsi3_virt" ;; 0 1 2-7 8 9-15 16 17-23 24 25-31 var + [(set (match_operand:SI 0 "nonimmediate_operand" "=v,vU,&vU,v, &vU, &vU, v, &vU, v, &vU, &vU, vU, v,&vU, vU, vU, vU") + (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0, 0, vU,0, vWab, U, 0, vU, 0, vWab,U, vU, 0, vU, vU, vU, 0") + (match_operand:SI 2 "nonmemory_operand" "M, K, K, Int3,Int3,Int3,Iv08,Iv08,Is09,Is09,Is09,Iv16,Is17,Is17,Iv24,Is25, iv"))) + (clobber (reg:HI X_REG)) ] "" "@ - ; ashrsi %0, 0 - movw\tax,%H1\;sarw\tax,1\;movw\t%H0,ax\;mov\ta,%Q1\;rorc\ta,1\;mov\t%Q0,a\;mov\ta,%q1\;rorc\ta,1\;mov\t%q0,a - mov\tb,%2\;1:\;movw\tax,%H1\;sarw\tax,1\;movw\t%H0,ax\;mov\ta,%Q1\;rorc\ta,1\;mov\t%Q0,a\;mov\ta,%q1\;rorc\ta,1\;mov\t%q0,a\;dec\tb\;bnz $1b" + ; lshrsi %0, 0 + + movw ax,%H1 \; shrw ax,1 \; movw %H0,ax \; mov a,%Q1 \; rorc a,1 \; mov %Q0,a \; mov a,%q1 \; rorc a,1 \; mov %q0,a + movw ax,%H1 \; shrw ax,1 \; movw %H0,ax \; mov a,%Q1 \; rorc a,1 \; mov %Q0,a \; mov a,%q1 \; rorc a,1 \; mov %q0,a + + movw ax,%1 \; shlw ax,%r2 \; mov %0,a \; mov x,%Q1 \; mov a,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; shrw ax,%u2 \; movw %H0,ax + movw ax,%1 \; shlw ax,%r2 \; mov %0,a \; mov x,%Q1 \; mov a,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; shrw ax,%u2 \; movw %H0,ax + movw ax,%1 \; shlw ax,%r2 \; mov %0,a \; mov a,%Q1 \; mov x,a \; mov a,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; shrw ax,%u2 \; movw %H0,ax + + mov x,%Q1 \; mov a,%H1 \; movw %0,ax \; movw ax,%H1 \; shrw ax,8 \; movw %H0,ax + mov a,%Q1 \; mov x, a \; mov a,%H1 \; movw %0,ax \; movw ax,%H1 \; shrw ax,8 \; movw %H0,ax + + mov x,%Q1 \; mov a,%H1 \; shlw ax,%r2 \; mov %0,a \; movw ax,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; shrw ax,%u2 \; movw %H0,ax + mov x,%Q1 \; mov a,%H1 \; shlw ax,%r2 \; mov %0,a \; movw ax,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; shrw ax,%u2 \; movw %H0,ax + mov a,%Q1 \; mov x,a \; mov a,%H1 \; shlw ax,%r2 \; mov %0,a \; movw ax,%H1 \; shlw ax,%r2 \; mov %Q0,a \; movw ax,%H1 \; shrw ax,%u2 \; movw %H0,ax + + movw ax,%H1 \; movw %0,ax \; movw ax,#0 \; movw %H0,ax + + movw ax,%H1 \; shrw ax,%S2 \; movw %0,ax \; movw ax,#0 \; movw %H0,ax + movw ax,%H1 \; shrw ax,%S2 \; movw %0,ax \; movw ax,#0 \; movw %H0,ax + + movw ax,%H1 \; mov %0,a \; movw ax,#0 \; movw %H0,ax \; mov %Q0,a + + movw ax,%H1 \; shr a,%s2 \; mov %0,a \; movw ax,#0 \; movw %H0,ax \; mov %Q0,a + + mov b,%2 \; cmp0 b \; bz $2f \; 1: \; movw ax,%H1 \; shrw ax,1 \; movw %H0,ax \; mov a,%Q1 \; rorc a,1 \; mov %Q0,a \; mov a,%q1 \; rorc a,1 \; mov %q0,a \; dec b \; bnz $1b \; 2:" [(set_attr "valloc" "macax")] ) +;; Likewise. +(define_insn "ashlsi3_virt" ;; 0 1 2-7 8 9-15 16 17-23 24 25-31 var + [(set (match_operand:SI 0 "nonimmediate_operand" "=v,vU,&vU,v, &vU, &vU, v, &vU, v, &vU, &vU, v, U, v,&vU, v, U, v, U, vWab,vU, vU") + (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0, 0, vU,0, vWab, U, 0, vU, 0, vWab,U, vU, vU, 0, vU, vU, vU, vU, vU, 0, vWab,U") + (match_operand:SI 2 "nonmemory_operand" "M, K, K, Int3,Int3,Int3,Iv08,Iv08,Is09,Is09,Is09,Iv16,Iv16,Is17,Is17,Iv24,Iv24,Is25,Is25,iv, iv, iv"))) + (clobber (reg:HI X_REG)) + ] + "" + "@ + ; lshrsi %0, 0 + + movw ax,%1 \; shlw ax,1 \; movw %0,ax \; movw ax,%H1 \; rolwc ax,1 \; movw %H0,ax + movw ax,%1 \; shlw ax,1 \; movw %0,ax \; movw ax,%H1 \; rolwc ax,1 \; movw %H0,ax + + movw ax,%H1 \; shlw ax,%u2 \; mov %E0,a \; mov x,%Q1 \; mov a, %H1 \; shlw ax,%S2 \; mov %H0,a \; movw ax,%1 \; shlw ax,%u2 \; movw %0,ax + movw ax,%H1 \; shlw ax,%u2 \; mov %E0,a \; mov x,%Q1 \; mov a, %H1 \; shlw ax,%S2 \; mov %H0,a \; movw ax,%1 \; shlw ax,%u2 \; movw %0,ax + movw ax,%H1 \; shlw ax,%u2 \; mov %E0,a \; mov a,%Q1 \; mov x,a \; mov a, %H1 \; shlw ax,%S2 \; mov %H0,a \; movw ax,%1 \; shlw ax,%u2 \; movw %0,ax + + mov x,%Q1 \; mov a,%H1 \; movw %H0,ax \; movw ax,%1 \; shlw ax,8 \; movw %0,ax + mov a,%Q1 \; mov x,a \; mov a,%H1 \; movw %H0,ax \; movw ax,%1 \; shlw ax,8 \; movw %0,ax + + mov x,%Q1 \; mov a,%H1 \; shlw ax,%s2 \; movw %H0,ax \; movw ax,%1 \; shlw ax,%s2 \; mov %H0,a \; movw ax,%1 \; shlw ax,%u2 \; movw %0,ax + mov x,%Q1 \; mov a,%H1 \; shlw ax,%s2 \; movw %H0,ax \; movw ax,%1 \; shlw ax,%s2 \; mov %H0,a \; movw ax,%1 \; shlw ax,%u2 \; movw %0,ax + mov a,%Q1 \; mov x,a \; mov a,%H1 \; shlw ax,%s2 \; movw %H0,ax \; movw ax,%1 \; shlw ax,%s2 \; mov %H0,a \; movw ax,%1 \; shlw ax,%u2 \; movw %0,ax + + movw ax,%1 \; movw %H0,ax \; movw %0,#0 + movw ax,%1 \; movw %H0,ax \; movw ax,#0 \; movw %0,ax + + movw ax,%1 \; shlw ax,%S2 \; movw %H0,ax \; movw %0,#0 + movw ax,%1 \; shlw ax,%S2 \; movw %H0,ax \; movw ax,#0 \; movw %0,ax + + mov a,%1 \; movw %H0,ax \; mov %H0,#0 \; movw %0,#0 + mov a,%1 \; movw %H0,ax \; movw ax,#0 \; mov %H0,a \; movW %0,ax + + mov a,%1 \; shl a,%s2 \; movw %H0,ax \; mov %H0,#0 \; movw %0,#0 + mov a,%1 \; shl a,%s2 \; movw %H0,ax \; movw ax,#0 \; mov %H0,a \; movW %0,ax + + mov a,%2 \; cmp0 a \; bz $2f \; mov d,a \; movw ax,%H1 \; movw bc,%1 \; 1: \; shlw bc,1 \; rolwc ax,1 \; dec d \; bnz $1b \; movw %H0,ax \; movw ax,bc \; movw %0,ax \; 2: + mov a,%2 \; mov d,a \; movw ax,%H1 \; movw bc,%1 \; cmp0 0xFFEFD \; bz $2f \; 1: \; shlw bc,1 \; rolwc ax,1 \; dec d \; bnz $1b \; 2: \; movw %H0,ax \; movw ax,bc \; movw %0,ax + mov a,%2 \; mov d,a \; movw ax,%1 \; movw bc,ax \; movw ax,%H1 \; cmp0 0xFFEFD \; bz $2f \; 1: \; shlw bc,1 \; rolwc ax,1 \; dec d \; bnz $1b \; 2: \; movw %H0,ax \; movw ax,bc \; movw %0,ax" + [(set_attr "valloc" "macax")] + ) + ;;---------- Branching ------------------------ (define_insn "*indirect_jump_virt" @@ -202,6 +312,18 @@ [(set_attr "valloc" "op1")] ) +(define_insn "cbranchqi4_virt_signed" + [(set (pc) (if_then_else + (match_operator 0 "rl78_cmp_operator_signed" + [(match_operand:QI 1 "general_operand" "vim") + (match_operand:QI 2 "nonmemory_operand" "vi")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "rl78_virt_insns_ok ()" + "v.cmp\t%1, %2\\n\tv.b%c0\t%3" + [(set_attr "valloc" "cmp")] + ) + (define_insn "*cbranchqi4_virt" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator_real" @@ -214,6 +336,18 @@ [(set_attr "valloc" "cmp")] ) +(define_insn "cbranchhi4_virt_signed" + [(set (pc) (if_then_else + (match_operator 0 "rl78_cmp_operator_signed" + [(match_operand:HI 1 "general_operand" "vim") + (match_operand:HI 2 "nonmemory_operand" "vi")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "rl78_virt_insns_ok ()" + "v.cmpw\t%1, %2\\n\tv.b%c0\t%3" + [(set_attr "valloc" "cmp")] + ) + (define_insn "*cbranchhi4_virt" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator_real" @@ -226,6 +360,20 @@ [(set_attr "valloc" "cmp")] ) +(define_insn "cbranchsi4_virt" + [(set (pc) (if_then_else + (match_operator 0 "rl78_cmp_operator" + [(match_operand:SI 1 "general_operand" "vim") + (match_operand:SI 2 "nonmemory_operand" "vi")]) + (label_ref (match_operand 3 "" "")) + (pc))) + (clobber (reg:HI AX_REG)) + ] + "rl78_virt_insns_ok ()" + "v.cmpd\t%1, %2\\n\tv.b%c0\t%3" + [(set_attr "valloc" "macax")] + ) + ;;---------- Peepholes ------------------------ (define_peephole2 diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c index d7cacc16352..5902e1ecd8f 100644 --- a/gcc/config/rl78/rl78.c +++ b/gcc/config/rl78/rl78.c @@ -50,6 +50,8 @@ #include "dumpfile.h" #include "tree-pass.h" #include "context.h" +#include "tm-constrs.h" /* for satisfies_constraint_*(). */ +#include "insn-flags.h" /* for gen_*(). */ static inline bool is_interrupt_func (const_tree decl); static inline bool is_brk_interrupt_func (const_tree decl); @@ -168,6 +170,86 @@ make_pass_rl78_devirt (gcc::context *ctxt) return new pass_rl78_devirt (ctxt); } +static unsigned int +move_elim_pass (void) +{ + rtx insn, ninsn, prev = NULL_RTX; + + for (insn = get_insns (); insn; insn = ninsn) + { + rtx set; + + ninsn = next_nonnote_nondebug_insn (insn); + + if ((set = single_set (insn)) == NULL_RTX) + { + prev = NULL_RTX; + continue; + } + + /* If we have two SET insns in a row (without anything + between them) and the source of the second one is the + destination of the first one, and vice versa, then we + can eliminate the second SET. */ + if (prev + && rtx_equal_p (SET_DEST (prev), SET_SRC (set)) + && rtx_equal_p (SET_DEST (set), SET_SRC (prev)) + ) + { + if (dump_file) + fprintf (dump_file, " Delete insn %d because it is redundant\n", + INSN_UID (insn)); + + delete_insn (insn); + prev = NULL_RTX; + } + else + prev = set; + } + + if (dump_file) + print_rtl_with_bb (dump_file, get_insns (), 0); + + return 0; +} + +namespace { + +const pass_data pass_data_rl78_move_elim = +{ + RTL_PASS, /* type */ + "move_elim", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_gate */ + true, /* has_execute */ + TV_MACH_DEP, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_rl78_move_elim : public rtl_opt_pass +{ +public: + pass_rl78_move_elim(gcc::context *ctxt) + : rtl_opt_pass(pass_data_rl78_move_elim, ctxt) + { + } + + /* opt_pass methods: */ + bool gate () { return devirt_gate (); } + unsigned int execute () { return move_elim_pass (); } +}; + +} // anon namespace + +rtl_opt_pass * +make_pass_rl78_move_elim (gcc::context *ctxt) +{ + return new pass_rl78_move_elim (ctxt); +} #undef TARGET_ASM_FILE_START #define TARGET_ASM_FILE_START rl78_asm_file_start @@ -177,22 +259,43 @@ 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); - struct register_pass_info rl78_devirt_info = + static struct register_pass_info rl78_devirt_info = { rl78_devirt_pass, - "vartrack", + "pro_and_epilogue", 1, PASS_POS_INSERT_BEFORE }; + opt_pass *rl78_move_elim_pass = make_pass_rl78_move_elim (g); + static struct register_pass_info rl78_move_elim_info = + { + rl78_move_elim_pass, + "bbro", + 1, + PASS_POS_INSERT_AFTER + }; + register_pass (& rl78_devirt_info); + register_pass (& rl78_move_elim_info); } @@ -207,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, @@ -332,6 +442,46 @@ rl78_expand_movsi (rtx *operands) } } +void +rl78_split_movsi (rtx *operands) +{ + rtx op00, op02, op10, op12; + + op00 = rl78_subreg (HImode, operands[0], SImode, 0); + op02 = rl78_subreg (HImode, operands[0], SImode, 2); + if (GET_CODE (operands[1]) == CONST + || GET_CODE (operands[1]) == SYMBOL_REF) + { + op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (0)); + op10 = gen_rtx_CONST (HImode, op10); + op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (16)); + op12 = gen_rtx_CONST (HImode, op12); + } + else + { + op10 = rl78_subreg (HImode, operands[1], SImode, 0); + op12 = rl78_subreg (HImode, operands[1], SImode, 2); + } + + if (rtx_equal_p (operands[0], operands[1])) + ; + else if (rtx_equal_p (op00, op12)) + { + operands[2] = op02; + operands[4] = op12; + operands[3] = op00; + operands[5] = op10; + } + else + { + operands[2] = op00; + operands[4] = op10; + operands[3] = op02; + operands[5] = op12; + } +} + + /* Used by various two-operand expanders which cannot accept all operands in the "far" namespace. Force some such operands into registers so that each pattern has at most one far operand. */ @@ -398,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. */ @@ -646,11 +801,11 @@ rl78_hl_b_c_addr_p (rtx op) int rl78_far_p (rtx x) { - if (GET_CODE (x) != MEM) + if (! MEM_P (x)) return 0; #if DEBUG0 - fprintf(stderr, "\033[35mrl78_far_p: "); debug_rtx(x); - fprintf(stderr, " = %d\033[0m\n", MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR); + fprintf (stderr, "\033[35mrl78_far_p: "); debug_rtx(x); + fprintf (stderr, " = %d\033[0m\n", MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR); #endif return MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR; } @@ -716,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; @@ -744,6 +903,10 @@ rl78_as_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x, if (strict && base && GET_CODE (base) == REG && REGNO (base) >= FIRST_PSEUDO_REGISTER) return false; + if (! cfun->machine->virt_insns_ok && base && GET_CODE (base) == REG + && REGNO (base) >= 8 && REGNO (base) <= 31) + return false; + return true; } @@ -789,8 +952,6 @@ rl78_addr_space_convert (rtx op, tree from_type, tree to_type) { /* This always works. */ result = gen_reg_rtx (SImode); - debug_rtx(result); - debug_rtx(op); emit_move_insn (rl78_subreg (HImode, result, SImode, 0), op); emit_move_insn (rl78_subreg (HImode, result, SImode, 2), const0_rtx); return result; @@ -878,32 +1039,49 @@ 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))); if (frame_pointer_needed) - F (emit_move_insn (gen_rtx_REG (HImode, FRAME_POINTER_REGNUM), - gen_rtx_REG (HImode, STACK_POINTER_REGNUM))); + { + F (emit_move_insn (gen_rtx_REG (HImode, AX_REG), + gen_rtx_REG (HImode, STACK_POINTER_REGNUM))); + F (emit_move_insn (gen_rtx_REG (HImode, FRAME_POINTER_REGNUM), + gen_rtx_REG (HImode, AX_REG))); + } fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing; while (fs > 0) @@ -927,8 +1105,10 @@ rl78_expand_epilogue (void) if (frame_pointer_needed) { - emit_move_insn (gen_rtx_REG (HImode, STACK_POINTER_REGNUM), + emit_move_insn (gen_rtx_REG (HImode, AX_REG), gen_rtx_REG (HImode, FRAME_POINTER_REGNUM)); + emit_move_insn (gen_rtx_REG (HImode, STACK_POINTER_REGNUM), + gen_rtx_REG (HImode, AX_REG)); } else { @@ -945,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) @@ -998,7 +1186,7 @@ rl78_start_function (FILE *file, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED) for (i = 0; i < 16; i ++) if (cfun->machine->need_to_push[i]) fprintf (file, " %s", word_regnames[i*2]); - fprintf(file, "\n"); + fprintf (file, "\n"); } if (frame_pointer_needed) @@ -1094,12 +1282,18 @@ rl78_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED, v - real register corresponding to a virtual register m - minus - negative of CONST_INT value. c - inverse of a conditional (NE vs EQ for example) + z - collapsed conditional + 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 q - bottom QI of an HI Q - top QI of an HI e - third QI of an SI (i.e. where the ES register gets values from) + E - fourth QI of an SI (i.e. MSB) */ @@ -1120,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); @@ -1146,15 +1343,20 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter) op = adjust_address (op, QImode, 2); letter = 0; } + if (letter == 'E') + { + op = adjust_address (op, QImode, 3); + letter = 0; + } if (CONSTANT_P (XEXP (op, 0))) { - fprintf(file, "!"); + fprintf (file, "!"); rl78_print_operand_1 (file, XEXP (op, 0), letter); } else if (GET_CODE (XEXP (op, 0)) == PLUS && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF) { - fprintf(file, "!"); + fprintf (file, "!"); rl78_print_operand_1 (file, XEXP (op, 0), letter); } else if (GET_CODE (XEXP (op, 0)) == PLUS @@ -1162,15 +1364,15 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter) && REGNO (XEXP (XEXP (op, 0), 0)) == 2) { rl78_print_operand_1 (file, XEXP (XEXP (op, 0), 1), 'u'); - fprintf(file, "["); + fprintf (file, "["); rl78_print_operand_1 (file, XEXP (XEXP (op, 0), 0), 0); - fprintf(file, "]"); + fprintf (file, "]"); } else { - fprintf(file, "["); + fprintf (file, "["); rl78_print_operand_1 (file, XEXP (op, 0), letter); - fprintf(file, "]"); + fprintf (file, "]"); } } break; @@ -1184,6 +1386,8 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter) fprintf (file, "%s", reg_names [REGNO (op) & ~1]); else if (letter == 'e') fprintf (file, "%s", reg_names [REGNO (op) + 2]); + else if (letter == 'E') + fprintf (file, "%s", reg_names [REGNO (op) + 3]); else if (letter == 'S') fprintf (file, "0x%x", 0xffef8 + REGNO (op)); else if (GET_MODE (op) == HImode @@ -1209,10 +1413,22 @@ 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') fprintf (file, "%ld", - INTVAL (op)); + else if (letter == 's') + fprintf (file, "%ld", INTVAL (op) % 8); + else if (letter == 'S') + fprintf (file, "%ld", INTVAL (op) % 16); + else if (letter == 'r') + fprintf (file, "%ld", 8 - (INTVAL (op) % 8)); + else if (letter == 'C') + fprintf (file, "%ld", (INTVAL (op) ^ 0x8000) & 0xffff); else - fprintf(file, "%ld", INTVAL (op)); + fprintf (file, "%ld", INTVAL (op)); break; case CONST: @@ -1316,22 +1532,68 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter) break; case LTU: - fprintf (file, letter == 'c' ? "nc" : "c"); + if (letter == 'z') + fprintf (file, "#comparison eliminated"); + else + fprintf (file, letter == 'c' ? "nc" : "c"); break; case LEU: - fprintf (file, letter == 'c' ? "h" : "nh"); + if (letter == 'z') + fprintf (file, "br"); + else + fprintf (file, letter == 'c' ? "h" : "nh"); break; case GEU: - fprintf (file, letter == 'c' ? "c" : "nc"); + if (letter == 'z') + fprintf (file, "br"); + else + fprintf (file, letter == 'c' ? "c" : "nc"); break; case GTU: - fprintf (file, letter == 'c' ? "nh" : "h"); + if (letter == 'z') + fprintf (file, "#comparison eliminated"); + else + fprintf (file, letter == 'c' ? "nh" : "h"); break; case EQ: - fprintf (file, letter == 'c' ? "nz" : "z"); + if (letter == 'z') + fprintf (file, "br"); + else + fprintf (file, letter == 'c' ? "nz" : "z"); break; case NE: - fprintf (file, letter == 'c' ? "z" : "nz"); + if (letter == 'z') + fprintf (file, "#comparison eliminated"); + else + fprintf (file, letter == 'c' ? "z" : "nz"); + break; + + /* Note: these assume appropriate adjustments were made so that + unsigned comparisons, which is all this chip has, will + work. */ + case LT: + if (letter == 'z') + fprintf (file, "#comparison eliminated"); + else + fprintf (file, letter == 'c' ? "nc" : "c"); + break; + case LE: + if (letter == 'z') + fprintf (file, "br"); + else + fprintf (file, letter == 'c' ? "h" : "nh"); + break; + case GE: + if (letter == 'z') + fprintf (file, "br"); + else + fprintf (file, letter == 'c' ? "c" : "nc"); + break; + case GT: + if (letter == 'z') + fprintf (file, "#comparison eliminated"); + else + fprintf (file, letter == 'c' ? "nh" : "h"); break; default: @@ -1346,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') + if (CONSTANT_P (op) && letter != 'u' && letter != 's' && letter != 'r' && letter != 'S' && letter != 'B') fprintf (file, "#"); rl78_print_operand_1 (file, op, letter); } @@ -1391,66 +1653,8 @@ rl78_trampoline_adjust_address (rtx m_tramp) void rl78_expand_compare (rtx *operands) { - /* RL78 does not have signed comparisons. We must modify the - operands to be in the unsigned range, and emit an unsigned - comparison. */ - - enum machine_mode mode; - rtx high_bit; - int i; - RTX_CODE new_cond; - - switch (GET_CODE (operands[0])) - { - case GE: - new_cond = GEU; - break; - case LE: - new_cond = LEU; - break; - case GT: - new_cond = GTU; - break; - case LT: - new_cond = LTU; - break; - default: - return; - } - -#if DEBUG0 - fprintf (stderr, "\033[38;5;129mrl78_expand_compare\n"); - debug_rtx (operands[0]); - fprintf (stderr, "\033[0m"); -#endif - - mode = GET_MODE (operands[1]); - if (mode == VOIDmode) - mode = GET_MODE (operands[2]); - high_bit = GEN_INT (~0 << (GET_MODE_BITSIZE (mode) - 1)); - - /* 0: conditional 1,2: operands */ - for (i = 1; i <= 2; i ++) - { - rtx r = operands[i]; - - if (GET_CODE (r) == CONST_INT) - r = GEN_INT (INTVAL (r) ^ INTVAL (high_bit)); - else - { - r = gen_rtx_PLUS (mode, operands[i], high_bit); - r = copy_to_mode_reg (mode, r); - } - operands[i] = r; - } - - operands[0] = gen_rtx_fmt_ee (new_cond, GET_MODE (operands[0]), operands[1], operands[2]); - -#if DEBUG0 - fprintf (stderr, "\033[38;5;142mrl78_expand_compare\n"); - debug_rtx (operands[0]); - fprintf (stderr, "\033[0m"); -#endif + if (GET_CODE (operands[2]) == MEM) + operands[2] = copy_to_mode_reg (GET_MODE (operands[2]), operands[2]); } @@ -1473,13 +1677,23 @@ rl78_peep_movhi_p (rtx *operands) #if DEBUG_PEEP fprintf (stderr, "\033[33m"); - debug_rtx(operands[0]); - debug_rtx(operands[1]); - debug_rtx(operands[2]); - debug_rtx(operands[3]); + debug_rtx (operands[0]); + debug_rtx (operands[1]); + debug_rtx (operands[2]); + debug_rtx (operands[3]); 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 @@ -1662,14 +1876,270 @@ 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 + avoid generating redundant move instructions. + + A value in the range 0 .. 31 indicates register A .. r31. + A value in the range 32 .. 63 indicates stack slot (value - 32). + A value of NOT_KNOWN indicates that the contents of that location + are not known. */ + +#define NUM_STACK_LOCS 32 +#define NOT_KNOWN 127 + +static unsigned char content_memory [32 + NUM_STACK_LOCS]; + +static unsigned char saved_update_index = NOT_KNOWN; +static unsigned char saved_update_value; +static enum machine_mode saved_update_mode; + + +static inline void +clear_content_memory (void) +{ + memset (content_memory, NOT_KNOWN, sizeof content_memory); + if (dump_file) + fprintf (dump_file, " clear content memory\n"); + saved_update_index = NOT_KNOWN; +} + +/* Convert LOC into an index into the content_memory array. + If LOC cannot be converted, return NOT_KNOWN. */ + +static unsigned char +get_content_index (rtx loc) +{ + enum machine_mode mode; + + if (loc == NULL_RTX) + return NOT_KNOWN; + + if (REG_P (loc)) + { + if (REGNO (loc) < 32) + return REGNO (loc); + return NOT_KNOWN; + } + + mode = GET_MODE (loc); + + if (! rl78_stack_based_mem (loc, mode)) + return NOT_KNOWN; + + loc = XEXP (loc, 0); + + if (REG_P (loc)) + /* loc = MEM (SP) */ + return 32; + + /* loc = MEM (PLUS (SP, INT)). */ + loc = XEXP (loc, 1); + + if (INTVAL (loc) < NUM_STACK_LOCS) + return 32 + INTVAL (loc); + + return NOT_KNOWN; +} + +/* Return a string describing content INDEX in mode MODE. + WARNING: Can return a pointer to a static buffer. */ + +static const char * +get_content_name (unsigned char index, enum machine_mode mode) +{ + static char buffer [128]; + + if (index == NOT_KNOWN) + return "Unknown"; + + if (index > 31) + sprintf (buffer, "stack slot %d", index - 32); + else if (mode == HImode) + sprintf (buffer, "%s%s", + reg_names [index + 1], reg_names [index]); + else + return reg_names [index]; + + return buffer; +} + +#if DEBUG_ALLOC + +static void +display_content_memory (FILE * file) +{ + unsigned int i; + + fprintf (file, " Known memory contents:\n"); + + for (i = 0; i < sizeof content_memory; i++) + if (content_memory[i] != NOT_KNOWN) + { + fprintf (file, " %s contains a copy of ", get_content_name (i, QImode)); + fprintf (file, "%s\n", get_content_name (content_memory [i], QImode)); + } +} +#endif + +static void +update_content (unsigned char index, unsigned char val, enum machine_mode mode) +{ + unsigned int i; + + gcc_assert (index < sizeof content_memory); + + content_memory [index] = val; + if (val != NOT_KNOWN) + content_memory [val] = index; + + /* Make the entry in dump_file *before* VAL is increased below. */ + if (dump_file) + { + fprintf (dump_file, " %s now contains ", get_content_name (index, mode)); + if (val == NOT_KNOWN) + fprintf (dump_file, "Unknown\n"); + else + fprintf (dump_file, "%s and vice versa\n", get_content_name (val, mode)); + } + + if (mode == HImode) + { + val = val == NOT_KNOWN ? val : val + 1; + + content_memory [index + 1] = val; + if (val != NOT_KNOWN) + { + content_memory [val] = index + 1; + -- val; + } + } + + /* Any other places that had INDEX recorded as their contents are now invalid. */ + for (i = 0; i < sizeof content_memory; i++) + { + if (i == index + || (val != NOT_KNOWN && i == val)) + { + if (mode == HImode) + ++ i; + continue; + } + + if (content_memory[i] == index + || (val != NOT_KNOWN && content_memory[i] == val)) + { + content_memory[i] = NOT_KNOWN; + + if (dump_file) + fprintf (dump_file, " %s cleared\n", get_content_name (i, mode)); + + if (mode == HImode) + content_memory[++ i] = NOT_KNOWN; + } + } +} + +/* Record that LOC contains VALUE. + For HImode locations record that LOC+1 contains VALUE+1. + If LOC is not a register or stack slot, do nothing. + If VALUE is not a register or stack slot, clear the recorded content. */ + +static void +record_content (rtx loc, rtx value) +{ + enum machine_mode mode; + unsigned char index; + unsigned char val; + + if ((index = get_content_index (loc)) == NOT_KNOWN) + return; + + val = get_content_index (value); + + mode = GET_MODE (loc); + + if (val == index) + { + if (! optimize) + return; + + /* This should not happen when optimizing. */ +#if 1 + fprintf (stderr, "ASSIGNMENT of location to itself detected! [%s]\n", + get_content_name (val, mode)); + return; +#else + gcc_unreachable (); +#endif + } + + update_content (index, val, mode); +} + +/* Returns TRUE if LOC already contains a copy of VALUE. */ + +static bool +already_contains (rtx loc, rtx value) +{ + unsigned char index; + unsigned char val; + + if ((index = get_content_index (loc)) == NOT_KNOWN) + return false; + + if ((val = get_content_index (value)) == NOT_KNOWN) + return false; + + if (content_memory [index] != val) + return false; + + if (GET_MODE (loc) == HImode) + return content_memory [index + 1] == val + 1; + + 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. */ static bool insn_ok_now (rtx insn) { + rtx pattern = PATTERN (insn); + int i; + INSN_CODE (insn) = -1; - if (recog (PATTERN (insn), insn, 0) > -1) + + if (recog (pattern, insn, 0) > -1) { extract_insn (insn); if (constrain_operands (1)) @@ -1679,15 +2149,42 @@ insn_ok_now (rtx insn) debug_rtx (insn); fprintf (stderr, "\033[0m"); #endif + 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; } } else { - fprintf (stderr, "\033[41;30m Unrecognized insn \033[0m\n"); + /* We need to re-recog the insn with virtual registers to get + the operands */ + cfun->machine->virt_insns_ok = 1; + if (recog (pattern, insn, 0) > -1) + { + extract_insn (insn); + if (constrain_operands (0)) + { + cfun->machine->virt_insns_ok = 0; + return false; + } + } + +#if DEBUG_ALLOC + fprintf (stderr, "\033[41;30m Unrecognized *virtual* insn \033[0m\n"); debug_rtx (insn); +#endif gcc_unreachable (); } + #if DEBUG_ALLOC fprintf (stderr, "\033[31m"); debug_rtx (insn); @@ -1697,15 +2194,15 @@ insn_ok_now (rtx insn) } #if DEBUG_ALLOC -#define WORKED fprintf (stderr, "\033[48;5;22m Worked at line %d \033[0m\n", __LINE__) +#define WORKED fprintf (stderr, "\033[48;5;22m Worked at line %d \033[0m\n", __LINE__) #define FAILEDSOFAR fprintf (stderr, "\033[48;5;52m FAILED at line %d \033[0m\n", __LINE__) -#define FAILED fprintf (stderr, "\033[48;5;52m FAILED at line %d \033[0m\n", __LINE__), gcc_unreachable() +#define FAILED fprintf (stderr, "\033[48;5;52m FAILED at line %d \033[0m\n", __LINE__), gcc_unreachable() #define MAYBE_OK(insn) if (insn_ok_now (insn)) { WORKED; return; } else { FAILEDSOFAR; } +#define MUST_BE_OK(insn) if (insn_ok_now (insn)) { WORKED; return; } FAILED #else -#define WORKED -#define FAILEDSOFAR #define FAILED gcc_unreachable () #define MAYBE_OK(insn) if (insn_ok_now (insn)) return; +#define MUST_BE_OK(insn) if (insn_ok_now (insn)) return; FAILED #endif /* Registers into which we move the contents of virtual registers. */ @@ -1723,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 @@ -1763,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. */ @@ -1787,16 +2288,96 @@ rl78_hi8 (rtx addr) return rl78_subreg (QImode, addr, SImode, 2); } -/* Copy any register values into real registers and return an RTX for - the same memory, now addressed by real registers. Any needed insns - are emitted before BEFORE. */ +static void +add_postponed_content_update (rtx to, rtx value) +{ + unsigned char index; + + if ((index = get_content_index (to)) == NOT_KNOWN) + return; + + gcc_assert (saved_update_index == NOT_KNOWN); + saved_update_index = index; + saved_update_value = get_content_index (value); + saved_update_mode = GET_MODE (to); +} + +static void +process_postponed_content_update (void) +{ + if (saved_update_index != NOT_KNOWN) + { + update_content (saved_update_index, saved_update_value, saved_update_mode); + saved_update_index = NOT_KNOWN; + } +} + +/* Generate and emit a move of (register) FROM into TO. if WHERE is not NULL + then if BEFORE is true then emit the insn before WHERE, otherwise emit it + after WHERE. If TO already contains FROM then do nothing. Returns TO if + BEFORE is true, FROM otherwise. */ +static rtx +gen_and_emit_move (rtx to, rtx from, rtx where, bool before) +{ + enum machine_mode mode = GET_MODE (to); + + if (optimize && before && already_contains (to, from)) + { +#if DEBUG_ALLOC + display_content_memory (stderr); +#endif + if (dump_file) + { + fprintf (dump_file, " Omit move of %s into ", + get_content_name (get_content_index (from), mode)); + fprintf (dump_file, "%s as it already contains this value\n", + get_content_name (get_content_index (to), mode)); + } + } + else + { + rtx move = mode == QImode ? gen_movqi (to, from) : gen_movhi (to, from); + + EM (move); + + if (where == NULL_RTX) + emit_insn (move); + else if (before) + emit_insn_before (move, where); + else + { + rtx note = find_reg_note (where, REG_EH_REGION, NULL_RTX); + + /* If necessary move REG_EH_REGION notes forward. + cf. compiling gcc.dg/pr44545.c. */ + if (note != NULL_RTX) + { + add_reg_note (move, REG_EH_REGION, XEXP (note, 0)); + remove_note (where, note); + } + + emit_insn_after (move, where); + } + + if (before) + record_content (to, from); + else + add_postponed_content_update (to, from); + } + return before ? to : from; +} + +/* If M is MEM(REG) or MEM(PLUS(REG,INT)) and REG is virtual then + copy it into NEWBASE and return the updated MEM. Otherwise just + return M. Any needed insns are emitted before BEFORE. */ static rtx transcode_memory_rtx (rtx m, rtx newbase, rtx before) { rtx base, index, addendr; int addend = 0; + int need_es = 0; - if (GET_CODE (m) != MEM) + if (! MEM_P (m)) return m; if (GET_MODE (XEXP (m, 0)) == SImode) @@ -1806,16 +2387,19 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) fprintf (stderr, "setting ES:\n"); debug_rtx(seg); #endif - emit_insn_before (EM(gen_movqi (A, seg)), before); - emit_insn_before (EM(gen_movqi_es (A)), before); + emit_insn_before (EM (gen_movqi (A, seg)), before); + emit_insn_before (EM (gen_movqi_es (A)), 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); + characterize_address (XEXP (m, 0), & base, & index, & addendr); gcc_assert (index == NULL_RTX); #if DEBUG_ALLOC - fprintf (stderr, "\033[33m"); debug_rtx(m); fprintf (stderr, "\033[0m"); + fprintf (stderr, "\033[33m"); debug_rtx (m); fprintf (stderr, "\033[0m"); debug_rtx (base); #endif if (base == NULL_RTX) @@ -1824,6 +2408,9 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) if (addendr && GET_CODE (addendr) == CONST_INT) addend = INTVAL (addendr); + gcc_assert (REG_P (base)); + gcc_assert (REG_P (newbase)); + if (REGNO (base) == SP_REG) { if (addend >= 0 && addend <= 255) @@ -1844,23 +2431,31 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) EM (emit_insn_before (gen_movhi (AX, base), before)); EM (emit_insn_before (gen_addhi3 (AX, AX, addendr), before)); EM (emit_insn_before (gen_movhi (newbase, AX), before)); + record_content (AX, NULL_RTX); + record_content (newbase, NULL_RTX); + base = newbase; addend = 0; } else { - EM (emit_insn_before (gen_movhi (newbase, base), before)); - base = newbase; + base = gen_and_emit_move (newbase, base, before, true); } if (addend) - base = gen_rtx_PLUS (HImode, base, GEN_INT (addend)); + { + record_content (base, NULL_RTX); + base = gen_rtx_PLUS (HImode, base, GEN_INT (addend)); + } #if DEBUG_ALLOC 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"); @@ -1874,49 +2469,48 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) static rtx move_to_acc (int opno, rtx before) { - rtx src = OP(opno); + rtx src = OP (opno); enum machine_mode mode = GET_MODE (src); - if (GET_CODE (src) == REG - && REGNO (src) < 2) + if (REG_P (src) && REGNO (src) < 2) return src; if (mode == VOIDmode) mode = recog_data.operand_mode[opno]; - if (mode == QImode) - { - EM (emit_insn_before (gen_movqi (A, src), before)); - return A; - } - else - { - EM (emit_insn_before (gen_movhi (AX, src), before)); - return AX; - } + return gen_and_emit_move (mode == QImode ? A : AX, src, before, true); +} + +static void +force_into_acc (rtx src, rtx before) +{ + enum machine_mode mode = GET_MODE (src); + rtx move; + + if (REG_P (src) && REGNO (src) < 2) + return; + + move = mode == QImode ? gen_movqi (A, src) : gen_movhi (AX, src); + + EM (move); + + emit_insn_before (move, before); + record_content (AX, NULL_RTX); } /* Copy accumulator (A or AX) to DEST, placing any generated insns after AFTER. Returns accumulator RTX. */ static rtx -move_from_acc (rtx dest, rtx after) +move_from_acc (unsigned int opno, rtx after) { + rtx dest = OP (opno); enum machine_mode mode = GET_MODE (dest); if (REG_P (dest) && REGNO (dest) < 2) return dest; - if (mode == QImode) - { - EM (emit_insn_after (gen_movqi (dest, A), after)); - return A; - } - else - { - EM (emit_insn_after (gen_movhi (dest, AX), after)); - return AX; - } + return gen_and_emit_move (dest, mode == QImode ? A : AX, after, false); } /* Copy accumulator (A or AX) to REGNO, placing any generated insns @@ -1930,16 +2524,7 @@ move_acc_to_reg (rtx acc, int regno, rtx before) reg = gen_rtx_REG (mode, regno); - if (mode == QImode) - { - EM (emit_insn_before (gen_movqi (reg, A), before)); - return reg; - } - else - { - EM (emit_insn_before (gen_movhi (reg, AX), before)); - return reg; - } + return gen_and_emit_move (reg, acc, before, true); } /* Copy SRC to X, placing any generated insns before BEFORE. @@ -1948,7 +2533,7 @@ move_acc_to_reg (rtx acc, int regno, rtx before) static rtx move_to_x (int opno, rtx before) { - rtx src = OP(opno); + rtx src = OP (opno); enum machine_mode mode = GET_MODE (src); rtx reg; @@ -1958,17 +2543,12 @@ move_to_x (int opno, rtx before) if (mode == QImode || ! is_virtual_register (OP (opno))) { - OP(opno) = move_to_acc (opno, before); - OP(opno) = move_acc_to_reg (OP(opno), X_REG, before); + OP (opno) = move_to_acc (opno, before); + OP (opno) = move_acc_to_reg (OP(opno), X_REG, before); return reg; } - if (mode == QImode) - EM (emit_insn_before (gen_movqi (reg, src), before)); - else - EM (emit_insn_before (gen_movhi (reg, src), before)); - - return reg; + return gen_and_emit_move (reg, src, before, true); } /* Copy OP(opno) to H or HL, placing any generated insns before BEFORE. @@ -1992,12 +2572,7 @@ move_to_hl (int opno, rtx before) return reg; } - if (mode == QImode) - EM (emit_insn_before (gen_movqi (reg, src), before)); - else - EM (emit_insn_before (gen_movhi (reg, src), before)); - - return reg; + return gen_and_emit_move (reg, src, before, true); } /* Copy OP(opno) to E or DE, placing any generated insns before BEFORE. @@ -2022,9 +2597,7 @@ move_to_de (int opno, rtx before) } else { - rtx move = mode == QImode ? gen_movqi (reg, src) : gen_movhi (reg, src); - - EM (emit_insn_before (move, before)); + gen_and_emit_move (reg, src, before, true); } return reg; @@ -2038,63 +2611,104 @@ rl78_alloc_physical_registers_op1 (rtx insn) /* We first try using A as the destination, then copying it back. */ - if (rtx_equal_p (OP(0), OP(1))) + if (rtx_equal_p (OP (0), OP (1))) { - OP(0) = - OP(1) = transcode_memory_rtx (OP(1), DE, insn); + OP (0) = + OP (1) = transcode_memory_rtx (OP (1), DE, insn); } else { - OP(0) = transcode_memory_rtx (OP(0), BC, insn); - OP(1) = transcode_memory_rtx (OP(1), HL, insn); + /* If necessary, load the operands into BC and HL. + Check to see if we already have OP (0) in HL + and if so, swap the order. */ + if (MEM_P (OP (0)) + && already_contains (HL, XEXP (OP (0), 0))) + { + OP (0) = transcode_memory_rtx (OP (0), HL, insn); + OP (1) = transcode_memory_rtx (OP (1), BC, insn); + } + else + { + OP (0) = transcode_memory_rtx (OP (0), BC, insn); + OP (1) = transcode_memory_rtx (OP (1), HL, insn); + } } MAYBE_OK (insn); - OP(0) = move_from_acc (OP(0), insn); + OP (0) = move_from_acc (0, insn); MAYBE_OK (insn); /* Try copying the src to acc first, then. This is for, for example, ZERO_EXTEND or NOT. */ - OP(1) = move_to_acc (1, insn); + OP (1) = move_to_acc (1, insn); - MAYBE_OK (insn); + MUST_BE_OK (insn); +} - FAILED; +/* Returns true if operand OPNUM contains a constraint of type CONSTRAINT. + Assumes that the current insn has already been recognised and hence the + constraint data has been filled in. */ +static bool +has_constraint (unsigned int opnum, enum constraint_num constraint) +{ + const char * p = recog_data.constraints[opnum]; + + /* No constraints means anything is accepted. */ + if (p == NULL || *p == 0 || *p == ',') + return true; + + do + { + char c; + unsigned int len; + + c = *p; + len = CONSTRAINT_LEN (c, p); + gcc_assert (len > 0); + + switch (c) + { + case 0: + case ',': + return false; + default: + if (lookup_constraint (p) == constraint) + return true; + } + p += len; + } + while (1); } -/* Devirtualize an insn of the form (SET (op) (unop (op) (op))). */ +/* Devirtualize an insn of the form (SET (op) (binop (op) (op))). */ static void rl78_alloc_physical_registers_op2 (rtx insn) { - /* op[0] = op[1] func op[2] */ - rtx prev = prev_nonnote_nondebug_insn (insn); + rtx prev; rtx first; bool hl_used; + int tmp_id; + rtx saved_op1; - if (rtx_equal_p (OP(0), OP(1))) + if (rtx_equal_p (OP (0), OP (1))) { - OP(0) = - OP(1) = transcode_memory_rtx (OP(1), DE, insn); - prev = next_nonnote_nondebug_insn (prev); - OP(2) = transcode_memory_rtx (OP(2), HL, insn); - prev = prev_nonnote_nondebug_insn (prev); + OP (0) = + OP (1) = transcode_memory_rtx (OP (1), DE, insn); + OP (2) = transcode_memory_rtx (OP (2), HL, insn); } - else if (rtx_equal_p (OP(0), OP(2))) + else if (rtx_equal_p (OP (0), OP (2))) { - OP(1) = transcode_memory_rtx (OP(1), DE, insn); - prev = next_nonnote_nondebug_insn (prev); - OP(0) = - OP(2) = transcode_memory_rtx (OP(2), HL, insn); - prev = prev_nonnote_nondebug_insn (prev); + OP (1) = transcode_memory_rtx (OP (1), DE, insn); + OP (0) = + OP (2) = transcode_memory_rtx (OP (2), HL, insn); } else { - OP(0) = transcode_memory_rtx (OP(0), BC, insn); - OP(1) = transcode_memory_rtx (OP(1), DE, insn); - prev = next_nonnote_nondebug_insn (prev); - OP(2) = transcode_memory_rtx (OP(2), HL, insn); + OP (0) = transcode_memory_rtx (OP (0), BC, insn); + OP (1) = transcode_memory_rtx (OP (1), DE, insn); + OP (2) = transcode_memory_rtx (OP (2), HL, insn); } MAYBE_OK (insn); @@ -2110,17 +2724,106 @@ rl78_alloc_physical_registers_op2 (rtx insn) OP (2) = tmp; } - /* Make a note of wether (H)L is being used. It matters - because if OP(2) alsoneeds reloading, then we must take + /* Make a note of whether (H)L is being used. It matters + because if OP (2) alsoneeds reloading, then we must take care not to corrupt HL. */ hl_used = reg_mentioned_p (L, OP (0)) || reg_mentioned_p (L, OP (1)); - OP(0) = move_from_acc (OP (0), insn); - OP(1) = move_to_acc (1, insn); + /* If HL is not currently being used and dest == op1 then there are + some possible optimizations available by reloading one of the + operands into HL, before trying to use the accumulator. */ + if (optimize + && ! hl_used + && rtx_equal_p (OP (0), OP (1))) + { + /* If op0 is a Ws1 type memory address then switching the base + address register to HL might allow us to perform an in-memory + operation. (eg for the INCW instruction). + + FIXME: Adding the move into HL is costly if this optimization is not + going to work, so for now, make sure that we know that the new insn will + match the requirements of the addhi3_real pattern. Really we ought to + generate a candidate sequence, test that, and then install it if the + results are good. */ + if (satisfies_constraint_Ws1 (OP (0)) + && has_constraint (0, CONSTRAINT_Wh1) + && (satisfies_constraint_K (OP (2)) || satisfies_constraint_L (OP (2)))) + { + rtx base, index, addend, newbase; + + characterize_address (XEXP (OP (0), 0), & base, & index, & addend); + gcc_assert (index == NULL_RTX); + gcc_assert (REG_P (base) && REGNO (base) == SP_REG); + + /* Ws1 addressing allows an offset of 0, Wh1 addressing requires a non-zero offset. */ + if (addend != NULL_RTX) + { + newbase = gen_and_emit_move (HL, base, insn, true); + record_content (newbase, NULL_RTX); + newbase = gen_rtx_PLUS (HImode, newbase, addend); + + OP (0) = OP (1) = change_address (OP (0), VOIDmode, newbase); + + /* We do not want to fail here as this means that + we have inserted useless insns into the stream. */ + MUST_BE_OK (insn); + } + } + else if (REG_P (OP (0)) + && satisfies_constraint_Ws1 (OP (2)) + && has_constraint (2, CONSTRAINT_Wh1)) + { + rtx base, index, addend, newbase; + + characterize_address (XEXP (OP (2), 0), & base, & index, & addend); + gcc_assert (index == NULL_RTX); + gcc_assert (REG_P (base) && REGNO (base) == SP_REG); + + /* Ws1 addressing allows an offset of 0, Wh1 addressing requires a non-zero offset. */ + if (addend != NULL_RTX) + { + gen_and_emit_move (HL, base, insn, true); + + if (REGNO (OP (0)) != X_REG) + { + OP (1) = move_to_acc (1, insn); + OP (0) = move_from_acc (0, insn); + } + + record_content (HL, NULL_RTX); + newbase = gen_rtx_PLUS (HImode, HL, addend); + + OP (2) = change_address (OP (2), VOIDmode, newbase); + + /* We do not want to fail here as this means that + we have inserted useless insns into the stream. */ + MUST_BE_OK (insn); + } + } + } + + + OP (0) = move_from_acc (0, insn); + + tmp_id = get_max_insn_count (); + saved_op1 = OP (1); + + if (rtx_equal_p (OP (1), OP (2))) + OP (2) = OP (1) = move_to_acc (1, insn); + else + OP (1) = move_to_acc (1, insn); MAYBE_OK (insn); - /* We have to copy op2 to HL, but that involves AX, which + /* If we omitted the move of OP1 into the accumulator (because + it was already there from a previous insn), then force the + generation of the move instruction now. We know that we + are about to emit a move into HL (or DE) via AX, and hence + our optimization to remove the load of OP1 is no longer valid. */ + if (tmp_id == get_max_insn_count ()) + force_into_acc (saved_op1, insn); + + /* We have to copy op2 to HL (or DE), but that involves AX, which already has a live value. Emit it before those insns. */ if (prev) @@ -2131,89 +2834,160 @@ rl78_alloc_physical_registers_op2 (rtx insn) OP (2) = hl_used ? move_to_de (2, first) : move_to_hl (2, first); - MAYBE_OK (insn); - - FAILED; + MUST_BE_OK (insn); } -/* Devirtualize an insn of the form (SET () (unop (op))). */ +/* Devirtualize an insn of the form SET (PC) (MEM/REG). */ static void rl78_alloc_physical_registers_ro1 (rtx insn) { - /* (void) op[0] */ - OP(0) = transcode_memory_rtx (OP(0), BC, insn); + OP (0) = transcode_memory_rtx (OP (0), BC, insn); MAYBE_OK (insn); - OP(0) = move_to_acc (0, insn); + OP (0) = move_to_acc (0, insn); - MAYBE_OK (insn); - - FAILED; + MUST_BE_OK (insn); } /* Devirtualize a compare insn. */ + static void rl78_alloc_physical_registers_cmp (rtx insn) { - /* op[1] cmp_op[0] op[2] */ + int tmp_id; + rtx saved_op1; rtx prev = prev_nonnote_nondebug_insn (insn); rtx first; - OP(1) = transcode_memory_rtx (OP(1), DE, insn); - OP(2) = transcode_memory_rtx (OP(2), HL, insn); + OP (1) = transcode_memory_rtx (OP (1), DE, insn); + OP (2) = transcode_memory_rtx (OP (2), HL, insn); + /* HI compares have to have OP(1) in AX, but QI + compares do not, so it is worth checking here. */ MAYBE_OK (insn); - OP(1) = move_to_acc (1, insn); + /* For an HImode compare, OP(1) must always be in AX. + But if OP(1) is a REG (and not AX), then we can avoid + a reload of OP(1) if we reload OP(2) into AX and invert + the comparison. */ + if (REG_P (OP (1)) + && REGNO (OP (1)) != AX_REG + && GET_MODE (OP (1)) == HImode + && MEM_P (OP (2))) + { + rtx cmp = XEXP (SET_SRC (PATTERN (insn)), 0); + + OP (2) = move_to_acc (2, insn); + + switch (GET_CODE (cmp)) + { + case EQ: + case NE: + break; + case LTU: cmp = gen_rtx_GTU (HImode, OP (2), OP (1)); break; + case GTU: cmp = gen_rtx_LTU (HImode, OP (2), OP (1)); break; + case LEU: cmp = gen_rtx_GEU (HImode, OP (2), OP (1)); break; + case GEU: cmp = gen_rtx_LEU (HImode, OP (2), OP (1)); break; + + case LT: + case GT: + case LE: + case GE: +#if DEBUG_ALLOC + debug_rtx (insn); +#endif + default: + gcc_unreachable (); + } + + if (GET_CODE (cmp) == EQ || GET_CODE (cmp) == NE) + PATTERN (insn) = gen_cbranchhi4_real (cmp, OP (2), OP (1), OP (3)); + else + PATTERN (insn) = gen_cbranchhi4_real_inverted (cmp, OP (2), OP (1), OP (3)); + + MUST_BE_OK (insn); + } + + /* Surprisingly, gcc can generate a comparison of a register with itself, but this + should be handled by the second alternative of the cbranchhi_real pattern. */ + if (rtx_equal_p (OP (1), OP (2))) + { + OP (1) = OP (2) = BC; + MUST_BE_OK (insn); + } + + tmp_id = get_max_insn_count (); + saved_op1 = OP (1); + + OP (1) = move_to_acc (1, insn); MAYBE_OK (insn); + /* If we omitted the move of OP1 into the accumulator (because + it was already there from a previous insn), then force the + generation of the move instruction now. We know that we + are about to emit a move into HL via AX, and hence our + optimization to remove the load of OP1 is no longer valid. */ + if (tmp_id == get_max_insn_count ()) + force_into_acc (saved_op1, insn); + /* We have to copy op2 to HL, but that involves the acc, which already has a live value. Emit it before those insns. */ - if (prev) first = next_nonnote_nondebug_insn (prev); else for (first = insn; prev_nonnote_nondebug_insn (first); first = prev_nonnote_nondebug_insn (first)) ; - OP(2) = move_to_hl (2, first); - - MAYBE_OK (insn); + OP (2) = move_to_hl (2, first); - FAILED; + MUST_BE_OK (insn); } /* Like op2, but AX = A op X. */ + static void rl78_alloc_physical_registers_umul (rtx insn) { - /* op[0] = op[1] func op[2] */ rtx prev = prev_nonnote_nondebug_insn (insn); rtx first; + int tmp_id; + rtx saved_op1; - OP(0) = transcode_memory_rtx (OP(0), BC, insn); - OP(1) = transcode_memory_rtx (OP(1), DE, insn); - OP(2) = transcode_memory_rtx (OP(2), HL, insn); + OP (0) = transcode_memory_rtx (OP (0), BC, insn); + OP (1) = transcode_memory_rtx (OP (1), DE, insn); + OP (2) = transcode_memory_rtx (OP (2), HL, insn); MAYBE_OK (insn); if (recog_data.constraints[1][0] == '%' - && is_virtual_register (OP(1)) - && !is_virtual_register (OP(2)) - && !CONSTANT_P (OP(2))) + && is_virtual_register (OP (1)) + && !is_virtual_register (OP (2)) + && !CONSTANT_P (OP (2))) { - rtx tmp = OP(1); - OP(1) = OP(2); - OP(2) = tmp; + rtx tmp = OP (1); + OP (1) = OP (2); + OP (2) = tmp; } - OP(0) = move_from_acc (OP(0), insn); - OP(1) = move_to_acc (1, insn); + OP (0) = move_from_acc (0, insn); + + tmp_id = get_max_insn_count (); + saved_op1 = OP (1); + + OP (1) = move_to_acc (1, insn); MAYBE_OK (insn); + /* If we omitted the move of OP1 into the accumulator (because + it was already there from a previous insn), then force the + generation of the move instruction now. We know that we + are about to emit a move into HL (or DE) via AX, and hence + our optimization to remove the load of OP1 is no longer valid. */ + if (tmp_id == get_max_insn_count ()) + force_into_acc (saved_op1, insn); + /* We have to copy op2 to X, but that involves the acc, which already has a live value. Emit it before those insns. */ @@ -2222,11 +2996,65 @@ rl78_alloc_physical_registers_umul (rtx insn) else for (first = insn; prev_nonnote_nondebug_insn (first); first = prev_nonnote_nondebug_insn (first)) ; - OP(2) = move_to_x (2, first); + OP (2) = move_to_x (2, first); + + MUST_BE_OK (insn); +} + +static void +rl78_alloc_address_registers_macax (rtx insn) +{ + int which, op; + bool replace_in_op0 = false; + bool replace_in_op1 = false; MAYBE_OK (insn); - FAILED; + /* Two different MEMs are not allowed. */ + which = 0; + for (op = 2; op >= 0; op --) + { + if (MEM_P (OP (op))) + { + if (op == 0 && replace_in_op0) + continue; + if (op == 1 && replace_in_op1) + continue; + + switch (which) + { + case 0: + /* If we replace a MEM, make sure that we replace it for all + occurrences of the same MEM in the insn. */ + replace_in_op0 = (op > 0 && rtx_equal_p (OP (op), OP (0))); + replace_in_op1 = (op > 1 && rtx_equal_p (OP (op), OP (1))); + + OP (op) = transcode_memory_rtx (OP (op), HL, insn); + if (op == 2 + && MEM_P (OP (op)) + && (REGNO (XEXP (OP (op), 0)) == SP_REG + || (GET_CODE (XEXP (OP (op), 0)) == PLUS + && REGNO (XEXP (XEXP (OP (op), 0), 0)) == SP_REG))) + { + emit_insn_before (gen_movhi (HL, gen_rtx_REG (HImode, SP_REG)), insn); + OP (op) = replace_rtx (OP (op), gen_rtx_REG (HImode, SP_REG), HL); + } + if (replace_in_op0) + OP (0) = OP (op); + if (replace_in_op1) + OP (1) = OP (op); + break; + case 1: + OP (op) = transcode_memory_rtx (OP (op), DE, insn); + break; + case 2: + OP (op) = transcode_memory_rtx (OP (op), BC, insn); + break; + } + which ++; + } + } + MUST_BE_OK (insn); } /* Scan all insns and devirtualize them. */ @@ -2266,23 +3094,46 @@ rl78_alloc_physical_registers (void) cfun->machine->virt_insns_ok = 0; cfun->machine->real_insns_ok = 1; + clear_content_memory (); + for (insn = get_insns (); insn; insn = curr) { + rtx pattern; + curr = insn ? next_nonnote_nondebug_insn (insn) : NULL; if (!INSN_P (insn)) - continue; - if (GET_CODE (PATTERN (insn)) != SET - && GET_CODE (PATTERN (insn)) != CALL) - continue; + { + if (LABEL_P (insn)) + clear_content_memory (); + + continue; + } - if (GET_CODE (PATTERN (insn)) == SET - && GET_CODE (SET_SRC (PATTERN (insn))) == ASM_OPERANDS) + if (dump_file) + fprintf (dump_file, "Converting insn %d\n", INSN_UID (insn)); + + pattern = PATTERN (insn); + if (GET_CODE (pattern) == PARALLEL) + pattern = XVECEXP (pattern, 0, 0); + if (JUMP_P (insn) || CALL_P (insn) || GET_CODE (pattern) == CALL) + clear_content_memory (); + if (GET_CODE (pattern) != SET + && GET_CODE (pattern) != CALL) + continue; + if (GET_CODE (SET_SRC (pattern)) == ASM_OPERANDS) continue; valloc_method = get_attr_valloc (insn); - PATTERN (insn)= copy_rtx_if_shared (PATTERN (insn)); + PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn)); + + if (valloc_method == VALLOC_MACAX) + { + record_content (AX, NULL_RTX); + record_content (BC, NULL_RTX); + record_content (DE, NULL_RTX); + } if (insn_ok_now (insn)) continue; @@ -2312,9 +3163,18 @@ rl78_alloc_physical_registers (void) rl78_alloc_physical_registers_umul (insn); break; case VALLOC_MACAX: - /* Macro that clobbers AX */ + /* Macro that clobbers AX. */ + rl78_alloc_address_registers_macax (insn); + record_content (AX, NULL_RTX); + record_content (BC, NULL_RTX); + record_content (DE, NULL_RTX); break; } + + if (JUMP_P (insn) || CALL_P (insn) || GET_CODE (pattern) == CALL) + clear_content_memory (); + else + process_postponed_content_update (); } #if DEBUG_ALLOC fprintf (stderr, "\033[0m"); @@ -2426,7 +3286,7 @@ rl78_calculate_death_notes (void) fprintf (dump_file, "\nDead:"); for (i = 0; i < FIRST_PSEUDO_REGISTER; i ++) if (dead[i]) - fprintf(dump_file, " %s", reg_names[i]); + fprintf (dump_file, " %s", reg_names[i]); fprintf (dump_file, "\n"); print_rtl_single (dump_file, insn); } @@ -2651,13 +3511,13 @@ rl78_propogate_register_origins (void) } } - /* Special case - our ADDSI3 macro uses AX */ + /* Special case - our ADDSI3 macro uses AX and sometimes BC. */ if (get_attr_valloc (insn) == VALLOC_MACAX) { if (dump_file) - fprintf (dump_file, "Resetting origin of AX for macro.\n"); + fprintf (dump_file, "Resetting origin of AX/BC for macro.\n"); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (i <= 1 || origins[i] <= 1) + if (i <= 3 || origins[i] <= 3) { origins[i] = i; age[i] = 0; @@ -2712,13 +3572,15 @@ rl78_remove_unused_sets (void) } } -#undef xTARGET_MACHINE_DEPENDENT_REORG -#define xTARGET_MACHINE_DEPENDENT_REORG rl78_reorg - /* This is the top of the devritualization pass. */ static void rl78_reorg (void) { + /* split2 only happens when optimizing, but we need all movSIs to be + split now. */ + if (optimize <= 0) + split_all_insns (); + rl78_alloc_physical_registers (); if (dump_file) @@ -2753,7 +3615,7 @@ rl78_reorg (void) df_analyze (); } -#undef TARGET_RETURN_IN_MEMORY +#undef TARGET_RETURN_IN_MEMORY #define TARGET_RETURN_IN_MEMORY rl78_return_in_memory static bool @@ -2764,6 +3626,63 @@ rl78_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) } +#undef TARGET_RTX_COSTS +#define TARGET_RTX_COSTS rl78_rtx_costs + +static bool rl78_rtx_costs (rtx x, + int code, + int outer_code ATTRIBUTE_UNUSED, + int opno ATTRIBUTE_UNUSED, + int * total, + bool speed ATTRIBUTE_UNUSED) +{ + if (code == IF_THEN_ELSE) + return COSTS_N_INSNS (10); + if (GET_MODE (x) == SImode) + { + switch (code) + { + case MULT: + if (RL78_MUL_RL78) + *total = COSTS_N_INSNS (14); + else if (RL78_MUL_G13) + *total = COSTS_N_INSNS (29); + else + *total = COSTS_N_INSNS (500); + return true; + case PLUS: + *total = COSTS_N_INSNS (8); + return true; + case ASHIFT: + case ASHIFTRT: + case LSHIFTRT: + if (GET_CODE (XEXP (x, 1)) == CONST_INT) + { + switch (INTVAL (XEXP (x, 1))) + { + case 0: *total = COSTS_N_INSNS (0); break; + case 1: *total = COSTS_N_INSNS (6); break; + case 2: case 3: case 4: case 5: case 6: case 7: + *total = COSTS_N_INSNS (10); break; + case 8: *total = COSTS_N_INSNS (6); break; + case 9: case 10: case 11: case 12: case 13: case 14: case 15: + *total = COSTS_N_INSNS (10); break; + case 16: *total = COSTS_N_INSNS (3); break; + case 17: case 18: case 19: case 20: case 21: case 22: case 23: + *total = COSTS_N_INSNS (4); break; + case 24: *total = COSTS_N_INSNS (4); break; + case 25: case 26: case 27: case 28: case 29: case 30: case 31: + *total = COSTS_N_INSNS (5); break; + } + } + else + *total = COSTS_N_INSNS (10+4*16); + return true; + } + } + return false; +} + #undef TARGET_UNWIND_WORD_MODE #define TARGET_UNWIND_WORD_MODE rl78_unwind_word_mode diff --git a/gcc/config/rl78/rl78.h b/gcc/config/rl78/rl78.h index 57c34ab763f..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) @@ -41,6 +43,17 @@ #undef ENDFILE_SPEC #define ENDFILE_SPEC "crtend.o%s crtn.o%s" +#undef ASM_SPEC +#define ASM_SPEC "\ +%{mrelax:-relax} \ +%{mg10} \ +" + +#undef LINK_SPEC +#define LINK_SPEC "\ +%{mrelax:-relax} \ +" + #undef LIB_SPEC #define LIB_SPEC " \ --start-group \ @@ -252,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. */ \ @@ -339,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 efc26210498..e1cbbb03eae 100644 --- a/gcc/config/rl78/rl78.md +++ b/gcc/config/rl78/rl78.md @@ -35,7 +35,7 @@ (FP_REG 22) (SP_REG 32) - (CC_REG 33) + (CC_REG 34) (ES_REG 35) (CS_REG 36) @@ -45,6 +45,7 @@ (UNS_RETB 3) (UNS_SET_RB 10) + (UNS_ES_ADDR 11) (UNS_TRAMPOLINE_INIT 20) (UNS_TRAMPOLINE_UNINIT 21) @@ -205,33 +206,76 @@ ;; efficient than anything else. (define_expand "addsi3" - [(set (match_operand:SI 0 "register_operand" "=&v") - (plus:SI (match_operand:SI 1 "nonmemory_operand" "vi") - (match_operand 2 "nonmemory_operand" "vi"))) + [(set (match_operand:SI 0 "nonimmediate_operand" "=&vm") + (plus:SI (match_operand:SI 1 "general_operand" "vim") + (match_operand 2 "general_operand" "vim"))) ] "" - "if (!nonmemory_operand (operands[1], SImode)) - operands[1] = force_reg (SImode, operands[1]); - if (!nonmemory_operand (operands[1], SImode)) - operands[2] = force_reg (SImode, operands[2]);" + "emit_insn (gen_addsi3_internal_virt (operands[0], operands[1], operands[2])); + DONE;" ) -(define_insn "addsi3_internal" - [(set (match_operand:SI 0 "register_operand" "=&v") - (plus:SI (match_operand:SI 1 "nonmemory_operand" "vi") - (match_operand:SI 2 "nonmemory_operand" "vi"))) +(define_insn "addsi3_internal_virt" + [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vm, vm") + (plus:SI (match_operand:SI 1 "general_operand" "0, vim, vim") + (match_operand 2 "general_operand" "vim,vim,vim"))) + (clobber (reg:HI AX_REG)) + (clobber (reg:HI BC_REG)) ] + "rl78_virt_insns_ok ()" "" - "; addSI macro %0 = %1 + %2 - movw ax, %h1 - addw ax, %h2 - movw %h0, ax - movw ax,%H1 - sknc - incw ax - addw ax,%H2 - movw %H0,ax - ; end of addSI macro" + [(set_attr "valloc" "macax")] +) + +(define_insn "addsi3_internal_real" + [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vU, vU") + (plus:SI (match_operand:SI 1 "general_operand" "+0, viU, viU") + (match_operand 2 "general_operand" "viWabWhlWh1,viWabWhlWh1,viWabWhlWh1"))) + (clobber (reg:HI AX_REG)) + (clobber (reg:HI BC_REG)) + ] + "rl78_real_insns_ok ()" + "@ + movw ax,%h1 \;addw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;incw ax \;addw ax,%H2 \;movw %H0,ax + movw ax,%h1 \;addw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;incw ax \;addw ax,%H2 \;movw %H0,ax + movw ax,%h1 \;addw ax,%h2 \;movw bc, ax \;movw ax,%H1 \;sknc \;incw ax \;addw ax,%H2 \;movw %H0,ax \;movw ax,bc \;movw %h0, ax" + [(set_attr "valloc" "macax")] +) + +(define_expand "subsi3" + [(set (match_operand:SI 0 "nonimmediate_operand" "=&vm") + (minus:SI (match_operand:SI 1 "general_operand" "vim") + (match_operand 2 "general_operand" "vim"))) + ] + "" + "emit_insn (gen_subsi3_internal_virt (operands[0], operands[1], operands[2])); + DONE;" +) + +(define_insn "subsi3_internal_virt" + [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vm, vm") + (minus:SI (match_operand:SI 1 "general_operand" "0, vim, vim") + (match_operand 2 "general_operand" "vim,vim,vim"))) + (clobber (reg:HI AX_REG)) + (clobber (reg:HI BC_REG)) + ] + "rl78_virt_insns_ok ()" + "" + [(set_attr "valloc" "macax")] +) + +(define_insn "subsi3_internal_real" + [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vU, vU") + (minus:SI (match_operand:SI 1 "general_operand" "+0, viU, viU") + (match_operand 2 "general_operand" "viWabWhlWh1,viWabWhlWh1,viWabWhlWh1"))) + (clobber (reg:HI AX_REG)) + (clobber (reg:HI BC_REG)) + ] + "rl78_real_insns_ok ()" + "@ + movw ax,%h1 \;subw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;decw ax \;subw ax,%H2 \;movw %H0,ax + movw ax,%h1 \;subw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;decw ax \;subw ax,%H2 \;movw %H0,ax + movw ax,%h1 \;subw ax,%h2 \;movw bc, ax \;movw ax,%H1 \;sknc \;decw ax \;subw ax,%H2 \;movw %H0,ax \;movw ax,bc \;movw %h0, ax" [(set_attr "valloc" "macax")] ) @@ -255,7 +299,7 @@ (define_expand "mulsi3" [(set (match_operand:SI 0 "register_operand" "=&v") - (mult:SI (match_operand:SI 1 "nonmemory_operand" "vi") + (mult:SI (match_operand:SI 1 "general_operand" "+vim") (match_operand:SI 2 "nonmemory_operand" "vi"))) ] "! RL78_MUL_NONE" @@ -319,8 +363,8 @@ ;; bits of the result). (define_insn "mulsi3_rl78" [(set (match_operand:SI 0 "register_operand" "=&v") - (mult:SI (match_operand:SI 1 "nonmemory_operand" "vi") - (match_operand:SI 2 "nonmemory_operand" "vi"))) + (mult:SI (match_operand:SI 1 "general_operand" "+viU") + (match_operand:SI 2 "general_operand" "vi"))) ] "RL78_MUL_RL78" "; mulsi macro %0 = %1 * %2 @@ -349,8 +393,8 @@ ;; Warning: this matches the silicon not the documentation. (define_insn "mulsi3_g13" [(set (match_operand:SI 0 "register_operand" "=&v") - (mult:SI (match_operand:SI 1 "nonmemory_operand" "vi") - (match_operand:SI 2 "nonmemory_operand" "vi"))) + (mult:SI (match_operand:SI 1 "general_operand" "viU") + (match_operand:SI 2 "general_operand" "viU"))) ] "RL78_MUL_G13" "; mulsi macro %0 = %1 * %2 @@ -389,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 c528ae47be6..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= @@ -41,3 +41,15 @@ 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 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/linux.h b/gcc/config/rs6000/linux.h index c9419424e15..2e5a56b3929 100644 --- a/gcc/config/rs6000/linux.h +++ b/gcc/config/rs6000/linux.h @@ -28,8 +28,12 @@ #ifdef SINGLE_LIBC #define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC) +#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC) +#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC) #else #define OPTION_GLIBC (linux_libc == LIBC_GLIBC) +#define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC) +#define OPTION_BIONIC (linux_libc == LIBC_BIONIC) #endif /* Determine what functions are present at the runtime; diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h index 63e656df150..439f53f2d23 100644 --- a/gcc/config/rs6000/linux64.h +++ b/gcc/config/rs6000/linux64.h @@ -288,8 +288,12 @@ extern int dot_symbols; #ifdef SINGLE_LIBC #define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC) +#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC) +#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC) #else #define OPTION_GLIBC (linux_libc == LIBC_GLIBC) +#define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC) +#define OPTION_BIONIC (linux_libc == LIBC_BIONIC) #endif /* Determine what functions are present at the runtime; 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/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 7338e764c5c..b5bff044779 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -376,12 +376,18 @@ (ior (match_code "const_int") (match_operand 0 "gpc_reg_operand"))) +;; Return 1 if op is a constant integer valid for addition with addis, addi. +(define_predicate "add_cint_operand" + (and (match_code "const_int") + (match_test "(unsigned HOST_WIDE_INT) + (INTVAL (op) + (mode == SImode ? 0x80000000 : 0x80008000)) + < (unsigned HOST_WIDE_INT) 0x100000000ll"))) + ;; Return 1 if op is a constant integer valid for addition ;; or non-special register. (define_predicate "reg_or_add_cint_operand" (if_then_else (match_code "const_int") - (match_test "(unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000) - < (unsigned HOST_WIDE_INT) 0x100000000ll") + (match_operand 0 "add_cint_operand") (match_operand 0 "gpc_reg_operand"))) ;; Return 1 if op is a constant integer valid for subtraction @@ -1697,7 +1703,7 @@ (define_predicate "small_toc_ref" (match_code "unspec,plus") { - if (GET_CODE (op) == PLUS && CONST_INT_P (XEXP (op, 1))) + if (GET_CODE (op) == PLUS && add_cint_operand (XEXP (op, 1), mode)) op = XEXP (op, 0); return GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_TOCREL; diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 527274acdec..e4402edc8d2 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -5926,7 +5926,7 @@ toc_relative_expr_p (const_rtx op, bool strict) tocrel_base = op; tocrel_offset = const0_rtx; - if (GET_CODE (op) == PLUS && CONST_INT_P (XEXP (op, 1))) + if (GET_CODE (op) == PLUS && add_cint_operand (XEXP (op, 1), GET_MODE (op))) { tocrel_base = XEXP (op, 0); tocrel_offset = XEXP (op, 1); diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 5acedfc86a2..a5a7a859426 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2139,12 +2139,15 @@ extern int toc_initialized; } \ else if (TARGET_XCOFF) \ { \ - fputs ("\t.lglobl\t.", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, alias); \ - putc ('\n', FILE); \ - fputs ("\t.lglobl\t", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, alias); \ - putc ('\n', FILE); \ + if (!RS6000_WEAK || !DECL_WEAK (DECL)) \ + { \ + fputs ("\t.lglobl\t.", FILE); \ + RS6000_OUTPUT_BASENAME (FILE, alias); \ + putc ('\n', FILE); \ + fputs ("\t.lglobl\t", FILE); \ + RS6000_OUTPUT_BASENAME (FILE, alias); \ + putc ('\n', FILE); \ + } \ } \ fputs ("\t.set\t.", FILE); \ RS6000_OUTPUT_BASENAME (FILE, alias); \ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 3880f9175a2..9f749f9a591 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -2376,7 +2376,9 @@ (clobber (match_scratch:DI 3 "=&r,&r,&r")) (clobber (match_scratch:DI 4 "=&r,X,&r"))] "TARGET_POWERPC64 && !TARGET_LDBRX - && (REG_P (operands[0]) || REG_P (operands[1]))" + && (REG_P (operands[0]) || REG_P (operands[1])) + && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0])) + && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))" "#" [(set_attr "length" "16,12,36")]) @@ -12207,7 +12209,7 @@ (unspec [(match_operand:DI 1 "" "") (match_operand:DI 2 "gpc_reg_operand" "b")] UNSPEC_TOCREL) - (match_operand 3 "const_int_operand" "n"))))] + (match_operand:DI 3 "add_cint_operand" "n"))))] "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%2,%1+%3@toc@ha") @@ -12218,7 +12220,7 @@ (unspec [(match_operand:P 1 "" "") (match_operand:P 2 "gpc_reg_operand" "b")] UNSPEC_TOCREL) - (match_operand 3 "const_int_operand" "n"))))] + (match_operand:P 3 "add_cint_operand" "n"))))] "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1+%3@u(%2)") diff --git a/gcc/config/s390/2827.md b/gcc/config/s390/2827.md index f21d8f8ce25..5be7cfaabfb 100644 --- a/gcc/config/s390/2827.md +++ b/gcc/config/s390/2827.md @@ -32,12 +32,12 @@ (const_int 0))) (define_attr "ooo_groupalone" "" - (cond [(eq_attr "mnemonic" "lnxbr,madb,ltxtr,clc,axtr,msebr,slbgr,xc,alcr,lpxbr,slbr,maebr,mlg,mfy,lxdtr,maeb,lxeb,nc,mxtr,sxtr,dxbr,alc,msdbr,ltxbr,lxdb,madbr,lxdbr,lxebr,mvc,m,mseb,mlr,mlgr,slb,tcxb,msdb,sqxbr,alcgr,oc,flogr,alcg,mxbr,dxtr,axbr,mr,sxbr,slbg,ml,lcxbr") (const_int 1)] + (cond [(eq_attr "mnemonic" "lnxbr,madb,ltxtr,clc,axtr,msebr,slbgr,xc,alcr,lpxbr,slbr,maebr,mlg,mfy,lxdtr,maeb,lxeb,nc,mxtr,sxtr,dxbr,alc,msdbr,ltxbr,lxdb,madbr,lxdbr,lxebr,mvc,m,mseb,mlr,mlgr,slb,tcxb,msdb,sqxbr,alcgr,oc,flogr,alcg,mxbr,dxtr,axbr,mr,sxbr,slbg,ml,lcxbr,bcr_flush") (const_int 1)] (const_int 0))) (define_insn_reservation "zEC12_simple" 1 (and (eq_attr "cpu" "zEC12") - (eq_attr "mnemonic" "ltg,ogrk,lr,lnebr,lghrl,sdbr,x,asi,lhr,sebr,madb,ar,lhrl,clfxtr,llgfr,clghrl,cgr,cli,agrk,ic,adbr,aebr,lrv,clg,cy,cghi,sy,celfbr,seb,clgfr,al,tm,lang,clfebr,lghr,cdb,lpebr,laa,ark,lh,or,icy,xi,msebr,n,llihl,afi,cs,nrk,sth,lgr,l,lcr,stey,xg,crt,slgfr,ny,ld,j,llihh,slgr,clfhsi,slg,lb,lgrl,lrl,llihf,lndbr,llcr,laxg,mvghi,rllg,sdb,xrk,laag,alhsik,algfi,algr,aly,agfi,lrvr,d,crl,llgc,tmhl,algsi,lgh,icmh,clhrl,xgrk,icm,iilf,ork,lbr,cg,ldgr,lgf,iihf,llghr,sg,clfdbr,llgtr,stam,cebr,tmhh,tceb,slgf,basr,lgbr,maebr,lgb,cgfi,aeb,ltebr,lax,clfit,lrvgr,nihl,ni,clfdtr,srdl,mdb,srk,xihf,stgrl,sthrl,algf,ltr,cdlgbr,cgit,ng,lat,llghrl,ltgr,nihh,clgfrl,srlk,maeb,agr,cxlftr,ler,bcr,stcy,cds,clfi,nihf,ly,clt,lgat,alg,lhy,lgfrl,clghsi,clrt,tmll,srlg,tcdb,ay,sty,clr,lgfi,lan,lpdbr,clgt,adb,ahik,sra,algrk,cdfbr,lcebr,clfxbr,msdbr,ceb,clgr,tmy,tmlh,alghsik,lcgr,mvi,cdbr,ltgf,xr,larl,ldr,llgcr,clgrt,clrl,cghsi,cliy,madbr,oy,ogr,llgt,meebr,slr,clgxbr,chi,s,icmy,llc,ngr,clhhsi,ltgfr,llill,lhi,o,meeb,clgdtr,sll,clgrl,clgf,ledbr,cegbr,mviy,algfr,rll,cdlftr,sldl,cdlgtr,lg,niy,st,sgr,ag,le,xgr,cr,stg,llilh,sr,lzer,cdsg,sllk,mdbr,stoc,csg,clgit,chhsi,strl,llilf,lndfr,ngrk,clgebr,clgfi,llgh,mseb,ltdbr,oill,la,llhrl,stc,lghi,oihl,xiy,sllg,llgf,cgrt,ldeb,cl,sl,cdlfbr,oi,oilh,nr,srak,oihh,ear,slgrk,og,c,slgfi,sthy,oilf,oiy,msdb,oihf,a,cfi,lzxr,lzdr,srag,cdgbr,brasl,alr,cgrl,llgfrl,cit,clgxtr,ley,exrl,lcdfr,lay,xilf,lcdbr,alsi,mvhhi,srl,chsi,lgfr,lrvg,cly,sgrk,ahi,celgbr,nill,clgdbr,jg,slrk,lxr,sar,slfi,cpsdr,lcgfr,aghik,nilh,mvhi,lpdfr,xy,alrk,lao,agsi,ldy,nilf,llhr,alfi,laog,sly,aghi,ldebr,bras,srda,cefbr,lt")) "nothing") + (eq_attr "mnemonic" "ltg,ogrk,lr,lnebr,lghrl,sdbr,x,asi,lhr,sebr,madb,ar,lhrl,clfxtr,llgfr,clghrl,cgr,cli,agrk,ic,adbr,aebr,lrv,clg,cy,cghi,sy,celfbr,seb,clgfr,al,tm,lang,clfebr,lghr,cdb,lpebr,laa,ark,lh,or,icy,xi,msebr,n,llihl,afi,cs,nrk,sth,lgr,l,lcr,stey,xg,crt,slgfr,ny,ld,j,llihh,slgr,clfhsi,slg,lb,lgrl,lrl,llihf,lndbr,llcr,laxg,mvghi,rllg,sdb,xrk,laag,alhsik,algfi,algr,aly,agfi,lrvr,d,crl,llgc,tmhl,algsi,lgh,icmh,clhrl,xgrk,icm,iilf,ork,lbr,cg,ldgr,lgf,iihf,llghr,sg,clfdbr,llgtr,stam,cebr,tmhh,tceb,slgf,basr,lgbr,maebr,lgb,cgfi,aeb,ltebr,lax,clfit,lrvgr,nihl,ni,clfdtr,srdl,mdb,srk,xihf,stgrl,sthrl,algf,ltr,cdlgbr,cgit,ng,lat,llghrl,ltgr,nihh,clgfrl,srlk,maeb,agr,cxlftr,ler,bcr_flush,stcy,cds,clfi,nihf,ly,clt,lgat,alg,lhy,lgfrl,clghsi,clrt,tmll,srlg,tcdb,ay,sty,clr,lgfi,lan,lpdbr,clgt,adb,ahik,sra,algrk,cdfbr,lcebr,clfxbr,msdbr,ceb,clgr,tmy,tmlh,alghsik,lcgr,mvi,cdbr,ltgf,xr,larl,ldr,llgcr,clgrt,clrl,cghsi,cliy,madbr,oy,ogr,llgt,meebr,slr,clgxbr,chi,s,icmy,llc,ngr,clhhsi,ltgfr,llill,lhi,o,meeb,clgdtr,sll,clgrl,clgf,ledbr,cegbr,mviy,algfr,rll,cdlftr,sldl,cdlgtr,lg,niy,st,sgr,ag,le,xgr,cr,stg,llilh,sr,lzer,cdsg,sllk,mdbr,stoc,csg,clgit,chhsi,strl,llilf,lndfr,ngrk,clgebr,clgfi,llgh,mseb,ltdbr,oill,la,llhrl,stc,lghi,oihl,xiy,sllg,llgf,cgrt,ldeb,cl,sl,cdlfbr,oi,oilh,nr,srak,oihh,ear,slgrk,og,c,slgfi,sthy,oilf,oiy,msdb,oihf,a,cfi,lzxr,lzdr,srag,cdgbr,brasl,alr,cgrl,llgfrl,cit,clgxtr,ley,exrl,lcdfr,lay,xilf,lcdbr,alsi,mvhhi,srl,chsi,lgfr,lrvg,cly,sgrk,ahi,celgbr,nill,clgdbr,jg,slrk,lxr,sar,slfi,cpsdr,lcgfr,aghik,nilh,mvhi,lpdfr,xy,alrk,lao,agsi,ldy,nilf,llhr,alfi,laog,sly,aghi,ldebr,bras,srda,cefbr,lt,fiebra,fidbra,fixbra,fidtr,fixtr")) "nothing") (define_insn_reservation "zEC12_cgdbr" 2 (and (eq_attr "cpu" "zEC12") @@ -603,3 +603,22 @@ (and (eq_attr "cpu" "zEC12") (eq_attr "mnemonic" "mh")) "nothing") +(define_insn_reservation "zEC12_fiebra" 6 + (and (eq_attr "cpu" "zEC12") + (eq_attr "mnemonic" "fiebra")) "nothing") + +(define_insn_reservation "zEC12_fidbra" 6 + (and (eq_attr "cpu" "zEC12") + (eq_attr "mnemonic" "fidbra")) "nothing") + +(define_insn_reservation "zEC12_fixbra" 10 + (and (eq_attr "cpu" "zEC12") + (eq_attr "mnemonic" "fixbra")) "nothing") + +(define_insn_reservation "zEC12_fidtr" 6 + (and (eq_attr "cpu" "zEC12") + (eq_attr "mnemonic" "fidtr")) "nothing") + +(define_insn_reservation "zEC12_fixtr" 10 + (and (eq_attr "cpu" "zEC12") + (eq_attr "mnemonic" "fixtr")) "nothing") diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index b2c5ac02308..cf9ef774675 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -117,6 +117,14 @@ ; Population Count UNSPEC_POPCNT UNSPEC_COPYSIGN + + ; Load FP Integer + UNSPEC_FPINT_FLOOR + UNSPEC_FPINT_BTRUNC + UNSPEC_FPINT_ROUND + UNSPEC_FPINT_CEIL + UNSPEC_FPINT_NEARBYINT + UNSPEC_FPINT_RINT ]) ;; @@ -291,7 +299,7 @@ z196_cracked" (const_string "none")) -(define_attr "mnemonic" "unknown" (const_string "unknown")) +(define_attr "mnemonic" "bcr_flush,unknown" (const_string "unknown")) ;; Length in bytes. @@ -429,9 +437,25 @@ ;; the same template. (define_code_iterator SHIFT [ashift lshiftrt]) -;; This iterator allow r[ox]sbg to be defined with the same template +;; This iterator allows r[ox]sbg to be defined with the same template (define_code_iterator IXOR [ior xor]) +;; This iterator is used to expand the patterns for the nearest +;; integer functions. +(define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC + UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL + UNSPEC_FPINT_NEARBYINT]) +(define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor") + (UNSPEC_FPINT_BTRUNC "btrunc") + (UNSPEC_FPINT_ROUND "round") + (UNSPEC_FPINT_CEIL "ceil") + (UNSPEC_FPINT_NEARBYINT "nearbyint")]) +(define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7") + (UNSPEC_FPINT_BTRUNC "5") + (UNSPEC_FPINT_ROUND "1") + (UNSPEC_FPINT_CEIL "6") + (UNSPEC_FPINT_NEARBYINT "0")]) + ;; This iterator and attribute allow to combine most atomic operations. (define_code_iterator ATOMIC [and ior xor plus minus mult]) (define_code_iterator ATOMIC_Z196 [and ior xor plus]) @@ -4414,6 +4438,58 @@ [(set_attr "op_type" "RRF") (set_attr "type" "fsimptf")]) +; Binary Floating Point - load fp integer + +; Expanders for: floor, btrunc, round, ceil, and nearbyint +; For all of them the inexact exceptions are suppressed. + +; fiebra, fidbra, fixbra +(define_insn "<FPINT:fpint_name><BFP:mode>2" + [(set (match_operand:BFP 0 "register_operand" "=f") + (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")] + FPINT))] + "TARGET_Z196" + "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4" + [(set_attr "op_type" "RRF") + (set_attr "type" "fsimp<BFP:mode>")]) + +; rint is supposed to raise an inexact exception so we can use the +; older instructions. + +; fiebr, fidbr, fixbr +(define_insn "rint<BFP:mode>2" + [(set (match_operand:BFP 0 "register_operand" "=f") + (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")] + UNSPEC_FPINT_RINT))] + "" + "fi<BFP:xde>br\t%0,0,%1" + [(set_attr "op_type" "RRF") + (set_attr "type" "fsimp<BFP:mode>")]) + + +; Decimal Floating Point - load fp integer + +; fidtr, fixtr +(define_insn "<FPINT:fpint_name><DFP:mode>2" + [(set (match_operand:DFP 0 "register_operand" "=f") + (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")] + FPINT))] + "TARGET_HARD_DFP" + "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4" + [(set_attr "op_type" "RRF") + (set_attr "type" "fsimp<DFP:mode>")]) + +; fidtr, fixtr +(define_insn "rint<DFP:mode>2" + [(set (match_operand:DFP 0 "register_operand" "=f") + (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")] + UNSPEC_FPINT_RINT))] + "TARGET_HARD_DFP" + "fi<DFP:xde>tr\t%0,0,%1,0" + [(set_attr "op_type" "RRF") + (set_attr "type" "fsimp<DFP:mode>")]) + +; ; Binary <-> Decimal floating point trunc patterns ; @@ -9007,12 +9083,22 @@ ; Although bcr is superscalar on Z10, this variant will never ; become part of an execution group. +; With z196 we can make use of the fast-BCR-serialization facility. +; This allows for a slightly faster sync which is sufficient for our +; purposes. (define_insn "mem_thread_fence_1" [(set (match_operand:BLK 0 "" "") (unspec:BLK [(match_dup 0)] UNSPEC_MB))] "" - "bcr\t15,0" - [(set_attr "op_type" "RR")]) +{ + if (TARGET_Z196) + return "bcr\t14,0"; + else + return "bcr\t15,0"; +} + [(set_attr "op_type" "RR") + (set_attr "mnemonic" "bcr_flush") + (set_attr "z196prop" "z196_alone")]) ; ; atomic load/store operations diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 8a140687654..2c20d3868a4 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -6878,10 +6878,11 @@ label: ;; If movqi_reg_reg is specified as an alternative of movqi, movqi will be ;; selected to copy QImode regs. If one of them happens to be allocated ;; on the stack, reload will stick to movqi insn and generate wrong -;; displacement addressing because of the generic m alternatives. -;; With the movqi_reg_reg being specified before movqi it will be initially -;; picked to load/store regs. If the regs regs are on the stack reload will -;; try other insns and not stick to movqi_reg_reg. +;; displacement addressing because of the generic m alternatives. +;; With the movqi_reg_reg being specified before movqi it will be initially +;; picked to load/store regs. If the regs regs are on the stack reload +;; try other insns and not stick to movqi_reg_reg, unless there were spilled +;; pseudos in which case 'm' constraints pertain. ;; The same applies to the movhi variants. ;; ;; Notice, that T bit is not allowed as a mov src operand here. This is to @@ -6893,11 +6894,14 @@ label: ;; reloading MAC subregs otherwise. For that probably special patterns ;; would be required. (define_insn "*mov<mode>_reg_reg" - [(set (match_operand:QIHI 0 "arith_reg_dest" "=r") - (match_operand:QIHI 1 "register_operand" "r"))] + [(set (match_operand:QIHI 0 "arith_reg_dest" "=r,m,*z") + (match_operand:QIHI 1 "register_operand" "r,*z,m"))] "TARGET_SH1 && !t_reg_operand (operands[1], VOIDmode)" - "mov %1,%0" - [(set_attr "type" "move")]) + "@ + mov %1,%0 + mov.<bw> %1,%0 + mov.<bw> %1,%0" + [(set_attr "type" "move,store,load")]) ;; FIXME: The non-SH2A and SH2A variants should be combined by adding ;; "enabled" attribute as it is done in other targets. 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/config/t-winnt b/gcc/config/t-winnt new file mode 100644 index 00000000000..1751622661b --- /dev/null +++ b/gcc/config/t-winnt @@ -0,0 +1,22 @@ +# Copyright (C) 2013 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +winnt-c.o: config/winnt-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(C_TARGET_H) $(C_TARGET_DEF_H) + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ + $< $(OUTPUT_OPTION) diff --git a/gcc/config/vax/constraints.md b/gcc/config/vax/constraints.md index a4774d4d575..66d6bf07f38 100644 --- a/gcc/config/vax/constraints.md +++ b/gcc/config/vax/constraints.md @@ -114,5 +114,6 @@ (define_constraint "T" "@internal satisfies CONSTANT_P and, if pic is enabled, is not a SYMBOL_REF, LABEL_REF, or CONST." - (ior (not (match_code "const,symbol_ref,label_ref")) - (match_test "!flag_pic"))) + (and (match_test ("CONSTANT_P (op)")) + (ior (not (match_code "symbol_ref,label_ref,const")) + (match_test "!flag_pic")))) diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index 53189a7e7d6..6b643d1af5d 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -1187,7 +1187,7 @@ vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands, { operands[1] = GEN_INT (lval); operands[2] = GEN_INT (n); - return "ashq %2,%1,%0"; + return "ashq %2,%D1,%0"; } #if HOST_BITS_PER_WIDE_INT == 32 } @@ -1199,7 +1199,7 @@ vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands, { operands[1] = GEN_INT (hval >> n); operands[2] = GEN_INT (n + 32); - return "ashq %2,%1,%0"; + return "ashq %2,%D1,%0"; #endif } } diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index eadde18ad43..2c05d007dae 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -697,14 +697,14 @@ (ashift:DI (match_operand:DI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" - "ashq %2,%1,%0") + "ashq %2,%D1,%0") (define_insn "" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (ashiftrt:DI (match_operand:DI 1 "general_operand" "g") (neg:QI (match_operand:QI 2 "general_operand" "g"))))] "" - "ashq %2,%1,%0") + "ashq %2,%D1,%0") ;; We used to have expand_shift handle logical right shifts by using extzv, ;; but this make it very difficult to do lshrdi3. Since the VAX is the diff --git a/gcc/config/winnt-c.c b/gcc/config/winnt-c.c new file mode 100644 index 00000000000..d52db62afd2 --- /dev/null +++ b/gcc/config/winnt-c.c @@ -0,0 +1,39 @@ +/* Default C-family target hooks initializer. + Copyright (C) 2013 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "c-family/c-target.h" +#include "c-family/c-target-def.h" + +static bool +winnt_implicit_extern_c (const char *ident) +{ + return !strcmp(ident, "wmain") + || !strcmp(ident, "DllMain") + || !strcmp(ident, "WinMain") + || !strcmp(ident, "wWinMain"); +} + +#undef TARGET_CXX_IMPLICIT_EXTERN_C +#define TARGET_CXX_IMPLICIT_EXTERN_C winnt_implicit_extern_c + +struct gcc_targetcm targetcm = TARGETCM_INITIALIZER; diff --git a/gcc/configure b/gcc/configure index c6bc3a69d84..f0c3c3bd2ea 100755 --- a/gcc/configure +++ b/gcc/configure @@ -13656,7 +13656,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -13681,7 +13681,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -13700,7 +13703,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -17894,7 +17900,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 17897 "configure" +#line 17903 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -18000,7 +18006,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 18003 "configure" +#line 18009 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/gcc/coverage.c b/gcc/coverage.c index 87384673a89..654dbc10ca0 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 db4cd660af3..a542ab1ffa3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,203 @@ +2013-09-20 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/58481 + * pt.c (tsubst_copy): Use current_nonlambda_class_type to + call tsubst_baselink. + +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. + (is_auto_or_concept): Declare. + * decl.c (grokdeclarator): Allow 'auto' parameters in lambdas with + -std=gnu++1y or -std=c++1y or, as a GNU extension, in plain functions. + * type-utils.h: New header defining ... + (find_type_usage): ... this new function based on pt.c (type_uses_auto) + for searching a type tree given a predicate. + * pt.c (type_uses_auto): Reimplement via type-utils.h (find_type_usage). + (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. + (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. + (cp_parser_parameter_declaration_list): Count generic + parameters and call ... + (add_implicit_template_parms): ... this new function to synthesize them + with help from type-utils.h (find_type_usage), ... + (tree_type_is_auto_or_concept): ... this new static function and ... + (make_generic_type_name): ... this new static function. + (cp_parser_direct_declarator): Account for implicit template parameters. + (cp_parser_lambda_declarator_opt): Finish fully implicit template if + necessary by calling ... + (finish_fully_implicit_template): ... this new function. + (cp_parser_init_declarator): Likewise. + (cp_parser_function_definition_after_declarator): Likewise. + (cp_parser_member_declaration): Likewise. + * Make-lang.in (cp/pt.o): Add dependency on type-utils.h. + (cp/parser.o): Likewise. + +2013-09-16 Adam Butcher <adam@jessamine.co.uk> + + * parser.c (cp_parser_lambda_declarator_opt): Accept template parameter + list with std=c++1y or std=gnu++1y. + (cp_parser_lambda_body): Don't call 'expand_or_defer_fn' for lambda call + operator template to avoid adding template result to symbol table. + * lambda.c (lambda_function): Return template result if call operator is + a template. + (maybe_add_lambda_conv_op): Move declarations to point of use. Refactor + operator call building in order to support conversion of a non-capturing + lambda template to a function pointer with help from ... + (prepare_op_call): ... this new function. + * decl2.c (check_member_template): Don't reject lambda call operator + template in local [lambda] class. + * pt.c (instantiate_class_template_1): Don't instantiate lambda call + operator template when instantiating lambda class. + +2013-09-16 Adam Butcher <adam@jessamine.co.uk> + + * pt.c (make_auto_1): Use input_location rather than BUILTINS_LOCATION. + +2013-09-15 Jason Merrill <jason@redhat.com> + + Core DR 904 + PR c++/41933 + * parser.c (cp_parser_lambda_introducer): Handle variadic capture. + * lambda.c (add_capture): Handle variadic capture. + (add_default_capture, lambda_capture_field_type): Likewise. + (build_capture_proxy, register_capture_members): Likewise. + * pt.c (register_specialization): Allow FIELD_DECL. + (retrieve_specialization): Likewise. + (find_parameter_packs_r): Handle FIELD_DECL and VAR_DECL. + (tsubst_pack_expansion): Handle FIELD_DECL packs. + (gen_elem_of_pack_expansion_instantiation): Likewise. + (instantiate_class_template_1): Likewise. + (tsubst_decl, tsubst_copy): Likewise. + (tsubst_expr) [DECL_EXPR]: Handle capture proxy packs. + (tsubst_copy_and_build) [VAR_DECL]: Likewise. + * semantics.c (finish_non_static_data_member): Don't try to represent + the type of a COMPOUND_REF of a FIELD_DECL pack. + + PR c++/41933 + * cp-tree.h (DECL_PACK_P): Replace FUNCTION_PARAMETER_PACK_P. + * cxx-pretty-print.c (direct_declarator): Adjust. + * decl2.c (cp_build_parm_decl): Adjust. + * pt.c (function_parameter_pack_p): Adjust. + (find_parameter_packs_r, push_template_decl_real): Adjust. + (tsubst_pack_expansion, tsubst_decl): Adjust. + (regenerate_decl_from_template, instantiate_decl): Adjust. + + * lambda.c (add_capture): Don't add DECL_LANG_SPECIFIC. + +2013-09-13 Jason Merrill <jason@redhat.com> + + PR c++/58273 + * pt.c (any_type_dependent_elements_p): Actually check for + type-dependence, not value-dependence. + +2013-09-13 Jacek Caban <jacek@codeweavers.com> + + * decl.c: Use new cxx_implicit_extern_c hook + +2013-09-12 Brooks Moses <bmoses@google.com> + + PR driver/42955 + * Make-lang.in: Do not install driver binaries in $(target)/bin. + +2013-09-12 Adam Butcher <adam@jessamine.co.uk> + + * pt.c (instantiate_decl): Save/restore cp_unevaluated_operand and + c_inhibit_evaluation_warnings. Reset if instantiating within a + function-local template. + +2013-09-12 Paolo Carlini <paolo.carlini@oracle.com> + + * semantics.c (finish_pseudo_destructor_expr): Add location_t + parameter. + * pt.c (unify_arg_conversion): Use EXPR_LOC_OR_HERE. + (tsubst_copy_and_build): Adjust finish_pseudo_destructor_expr + calls. + * parser.c (cp_parser_postfix_dot_deref_expression): Likewise. + (cp_parser_postfix_expression): Pass the proper location to + cp_parser_postfix_dot_deref_expression. + * cp-tree.h (finish_pseudo_destructor_expr): Update declaration. + +2013-09-10 Jan Hubicka <jh@suse.cz> + Paolo Carlini <paolo.carlini@oracle.com> + + * error.c (print_instantiation_partial_context_line): If + loc == UNKNOWN_LOCATION return immediately. + +2013-09-09 Jakub Jelinek <jakub@redhat.com> + + PR c++/58325 + * init.c (build_vec_delete): Call mark_rvalue_use on base. + +2013-09-09 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/43452 + * init.c (build_vec_delete_1): When the type is incomplete emit a + warning, enabled by default (not an error). + (build_delete): Adjust to use OPT_Wdelete_incomplete. + +2013-09-09 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/58362 + * error.c (location_of): Don't handle PARM_DECLs specially. + +2013-09-09 Paolo Carlini <paolo.carlini@oracle.com> + + * error.c (dump_expr, [PSEUDO_DTOR_EXPR]): Fix. + * cxx-pretty-print.c (cxx_pretty_printer::postfix_expression): + Tweak, TREE_OPERAND (t, 1) may be null. + +2013-09-08 Caroline Tice <cmtice@google.com> + + PR c++/58300 + * vtable-class-hierarchy.c (vtv_generate_init_routine): In + preinit case, move call to assemble_vtv_preinit_initializer to + after call to cgraph_process_new_functions. + +2013-09-08 Tom de Vries <tom@codesourcery.com> + + PR c++/58282 + * except.c (build_must_not_throw_expr): Handle + flag_exceptions. + +2013-09-08 Joern Rennecke <joern.rennecke@embecosm.com> + + * typeck.c (cp_build_binary_op): Use vector_types_compatible_elements_p. + +2013-09-04 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/24926 + * class.c (finish_struct_anon_r): New. + (finish_struct_anon): Use it. + 2013-09-04 Gabriel Dos Reis <gdr@integrable-solutions.net> * cxx-pretty-print.h (cxx_pretty_printer::simple_type_specifier): diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 65dfe081e0b..985f22b72d9 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -167,8 +167,8 @@ check_g++_parallelize = old-deja.exp dg.exp dg-torture.exp # Install hooks: # cc1plus is installed elsewhere as part of $(COMPILERS). -# Install the driver program as $(target)-g++ -# and also as either g++ (if native) or $(tooldir)/bin/g++. +# Install the driver program as $(target)-g++ and $(target)-c++, and +# also as g++ and c++ if native. c++.install-common: installdirs -rm -f $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext) -$(INSTALL_PROGRAM) xg++$(exeext) $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext) @@ -177,15 +177,7 @@ c++.install-common: installdirs -( cd $(DESTDIR)$(bindir) && \ $(LN) $(GXX_INSTALL_NAME)$(exeext) $(CXX_INSTALL_NAME)$(exeext) ) -if [ -f cc1plus$(exeext) ] ; then \ - if [ -f g++-cross$(exeext) ] ; then \ - if [ -d $(DESTDIR)$(gcc_tooldir)/bin/. ] ; then \ - rm -f $(DESTDIR)$(gcc_tooldir)/bin/g++$(exeext); \ - $(INSTALL_PROGRAM) g++-cross$(exeext) $(DESTDIR)$(gcc_tooldir)/bin/g++$(exeext); \ - rm -f $(DESTDIR)$(gcc_tooldir)/bin/c++$(exeext); \ - ( cd $(DESTDIR)$(gcc_tooldir)/bin && \ - $(LN) g++$(exeext) c++$(exeext) ); \ - else true; fi; \ - else \ + if [ ! -f g++-cross$(exeext) ] ; then \ rm -f $(DESTDIR)$(bindir)/$(GXX_TARGET_INSTALL_NAME)$(exeext); \ ( cd $(DESTDIR)$(bindir) && \ $(LN) $(GXX_INSTALL_NAME)$(exeext) $(GXX_TARGET_INSTALL_NAME)$(exeext) ); \ @@ -320,7 +312,7 @@ cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \ cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(TM_P_H) cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h cp/cp-objcp-common.h \ toplev.h $(TREE_INLINE_H) pointer-set.h gt-cp-pt.h intl.h \ - c-family/c-objc.h + c-family/c-objc.h cp/type-utils.h cp/error.o: cp/error.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_H) \ $(FLAGS_H) $(REAL_H) $(LANGHOOKS_DEF_H) $(CXX_PRETTY_PRINT_H) \ tree-diagnostic.h tree-pretty-print.h pointer-set.h c-family/c-objc.h @@ -339,7 +331,8 @@ cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) $(REAL_H) \ gt-cp-mangle.h $(TARGET_H) $(TM_P_H) $(CGRAPH_H) cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_CORE_H) \ gt-cp-parser.h $(TARGET_H) $(PLUGIN_H) intl.h cp/decl.h \ - c-family/c-objc.h tree-pretty-print.h $(CXX_PARSER_H) $(TIMEVAR_H) + c-family/c-objc.h tree-pretty-print.h $(CXX_PARSER_H) $(TIMEVAR_H) \ + cp/type-utils.h cp/cp-gimplify.o: cp/cp-gimplify.c $(CXX_TREE_H) $(C_COMMON_H) \ $(TM_H) coretypes.h pointer-set.h tree-iterator.h $(SPLAY_TREE_H) cp/vtable-class-hierarchy.o: cp/vtable-class-hierarchy.c \ diff --git a/gcc/cp/class.c b/gcc/cp/class.c index f7eff97105b..39005cbb1d9 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2774,15 +2774,93 @@ warn_hidden (tree t) } } +/* Recursive helper for finish_struct_anon. */ + +static void +finish_struct_anon_r (tree field, bool complain) +{ + bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE; + tree elt = TYPE_FIELDS (TREE_TYPE (field)); + for (; elt; elt = DECL_CHAIN (elt)) + { + /* We're generally only interested in entities the user + declared, but we also find nested classes by noticing + the TYPE_DECL that we create implicitly. You're + allowed to put one anonymous union inside another, + though, so we explicitly tolerate that. We use + TYPE_ANONYMOUS_P rather than ANON_AGGR_TYPE_P so that + we also allow unnamed types used for defining fields. */ + if (DECL_ARTIFICIAL (elt) + && (!DECL_IMPLICIT_TYPEDEF_P (elt) + || TYPE_ANONYMOUS_P (TREE_TYPE (elt)))) + continue; + + if (TREE_CODE (elt) != FIELD_DECL) + { + if (complain) + { + if (is_union) + permerror (input_location, + "%q+#D invalid; an anonymous union can " + "only have non-static data members", elt); + else + permerror (input_location, + "%q+#D invalid; an anonymous struct can " + "only have non-static data members", elt); + } + continue; + } + + if (complain) + { + if (TREE_PRIVATE (elt)) + { + if (is_union) + permerror (input_location, + "private member %q+#D in anonymous union", elt); + else + permerror (input_location, + "private member %q+#D in anonymous struct", elt); + } + else if (TREE_PROTECTED (elt)) + { + if (is_union) + permerror (input_location, + "protected member %q+#D in anonymous union", elt); + else + permerror (input_location, + "protected member %q+#D in anonymous struct", elt); + } + } + + TREE_PRIVATE (elt) = TREE_PRIVATE (field); + TREE_PROTECTED (elt) = TREE_PROTECTED (field); + + /* Recurse into the anonymous aggregates to handle correctly + access control (c++/24926): + + class A { + union { + union { + int i; + }; + }; + }; + + int j=A().i; */ + if (DECL_NAME (elt) == NULL_TREE + && ANON_AGGR_TYPE_P (TREE_TYPE (elt))) + finish_struct_anon_r (elt, /*complain=*/false); + } +} + /* Check for things that are invalid. There are probably plenty of other things we should check for also. */ static void finish_struct_anon (tree t) { - tree field; - - for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) + for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) { if (TREE_STATIC (field)) continue; @@ -2791,53 +2869,7 @@ finish_struct_anon (tree t) if (DECL_NAME (field) == NULL_TREE && ANON_AGGR_TYPE_P (TREE_TYPE (field))) - { - bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE; - tree elt = TYPE_FIELDS (TREE_TYPE (field)); - for (; elt; elt = DECL_CHAIN (elt)) - { - /* We're generally only interested in entities the user - declared, but we also find nested classes by noticing - the TYPE_DECL that we create implicitly. You're - allowed to put one anonymous union inside another, - though, so we explicitly tolerate that. We use - TYPE_ANONYMOUS_P rather than ANON_AGGR_TYPE_P so that - we also allow unnamed types used for defining fields. */ - if (DECL_ARTIFICIAL (elt) - && (!DECL_IMPLICIT_TYPEDEF_P (elt) - || TYPE_ANONYMOUS_P (TREE_TYPE (elt)))) - continue; - - if (TREE_CODE (elt) != FIELD_DECL) - { - if (is_union) - permerror (input_location, "%q+#D invalid; an anonymous union can " - "only have non-static data members", elt); - else - permerror (input_location, "%q+#D invalid; an anonymous struct can " - "only have non-static data members", elt); - continue; - } - - if (TREE_PRIVATE (elt)) - { - if (is_union) - permerror (input_location, "private member %q+#D in anonymous union", elt); - else - permerror (input_location, "private member %q+#D in anonymous struct", elt); - } - else if (TREE_PROTECTED (elt)) - { - if (is_union) - permerror (input_location, "protected member %q+#D in anonymous union", elt); - else - permerror (input_location, "protected member %q+#D in anonymous struct", elt); - } - - TREE_PRIVATE (elt) = TREE_PRIVATE (field); - TREE_PROTECTED (elt) = TREE_PROTECTED (field); - } - } + finish_struct_anon_r (field, /*complain=*/true); } } @@ -7596,7 +7628,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/cp-tree.h b/gcc/cp/cp-tree.h index e5fddc5c608..d28eb6f7eea 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -138,7 +138,6 @@ c-common.h, not after. 1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL). DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL) DECL_MEMBER_TEMPLATE_P (in TEMPLATE_DECL) - FUNCTION_PARAMETER_PACK_P (in PARM_DECL) USING_DECL_TYPENAME_P (in USING_DECL) DECL_VLA_CAPTURE_P (in FIELD_DECL) 2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL). @@ -2874,10 +2873,9 @@ extern void decl_shadowed_for_var_insert (tree, tree); the class definition is complete. */ #define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE) -/* Determine if a parameter (i.e., a PARM_DECL) is a function - parameter pack. */ -#define FUNCTION_PARAMETER_PACK_P(NODE) \ - (DECL_LANG_FLAG_1 (PARM_DECL_CHECK (NODE))) +/* Determine if a declaration (PARM_DECL or FIELD_DECL) is a pack. */ +#define DECL_PACK_P(NODE) \ + (DECL_P (NODE) && PACK_EXPANSION_P (TREE_TYPE (NODE))) /* Determines if NODE is an expansion of one or more parameter packs, e.g., a TYPE_PACK_EXPANSION or EXPR_PACK_EXPANSION. */ @@ -5455,10 +5453,12 @@ extern tree make_auto (void); extern tree make_decltype_auto (void); extern tree do_auto_deduction (tree, tree, tree); extern tree type_uses_auto (tree); +extern tree type_uses_auto_or_concept (tree); extern void append_type_to_template_for_access_check (tree, tree, tree, location_t); extern tree splice_late_return_type (tree, tree); extern bool is_auto (const_tree); +extern bool is_auto_or_concept (const_tree); extern tree process_template_parm (tree, location_t, tree, bool, bool); extern tree end_template_parm_list (tree); @@ -5734,7 +5734,7 @@ extern tree finish_call_expr (tree, vec<tree, va_gc> **, bool, bool, tsubst_flags_t); extern tree finish_increment_expr (tree, enum tree_code); extern tree finish_this_expr (void); -extern tree finish_pseudo_destructor_expr (tree, tree, tree); +extern tree finish_pseudo_destructor_expr (tree, tree, tree, location_t); extern tree finish_unary_op_expr (location_t, enum tree_code, tree, tsubst_flags_t); extern tree finish_compound_literal (tree, tree, tsubst_flags_t); diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c index 4578a5b0b05..bcef8760ad7 100644 --- a/gcc/cp/cxx-pretty-print.c +++ b/gcc/cp/cxx-pretty-print.c @@ -618,8 +618,11 @@ cxx_pretty_printer::postfix_expression (tree t) case PSEUDO_DTOR_EXPR: postfix_expression (TREE_OPERAND (t, 0)); pp_cxx_dot (this); - pp_cxx_qualified_id (this, TREE_OPERAND (t, 1)); - pp_cxx_colon_colon (this); + if (TREE_OPERAND (t, 1)) + { + pp_cxx_qualified_id (this, TREE_OPERAND (t, 1)); + pp_cxx_colon_colon (this); + } pp_complement (this); pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2)); break; @@ -1524,7 +1527,7 @@ cxx_pretty_printer::direct_declarator (tree t) { pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t)); - if ((TREE_CODE (t) == PARM_DECL && FUNCTION_PARAMETER_PACK_P (t)) + if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t)) || template_parameter_pack_p (t)) /* A function parameter pack or non-type template parameter pack. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 393c889a747..a8751ecdc33 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "c-family/c-common.h" #include "c-family/c-objc.h" #include "c-family/c-pragma.h" +#include "c-family/c-target.h" #include "diagnostic.h" #include "intl.h" #include "debug.h" @@ -7458,7 +7459,9 @@ grokfndecl (tree ctype, || (IDENTIFIER_LENGTH (declarator) > 10 && IDENTIFIER_POINTER (declarator)[0] == '_' && IDENTIFIER_POINTER (declarator)[1] == '_' - && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0)) + && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0) + || (targetcm.cxx_implicit_extern_c + && targetcm.cxx_implicit_extern_c(IDENTIFIER_POINTER (declarator)))) && current_lang_name == lang_name_cplusplus && ctype == NULL_TREE && DECL_FILE_SCOPE_P (decl)) @@ -10321,8 +10324,33 @@ grokdeclarator (const cp_declarator *declarator, if (type_uses_auto (type)) { - error ("parameter declared %<auto%>"); - type = error_mark_node; + if (template_parm_flag) + { + error ("template parameter declared %<auto%>"); + type = error_mark_node; + } + else if (decl_context == CATCHPARM) + { + error ("catch parameter declared %<auto%>"); + type = error_mark_node; + } + else if (current_class_type && LAMBDA_TYPE_P (current_class_type)) + { + if (cxx_dialect < cxx1y) + pedwarn (location_of (type), 0, + "use of %<auto%> in lambda parameter declaration " + "only available with " + "-std=c++1y or -std=gnu++1y"); + } + else if (cxx_dialect < cxx1y) + pedwarn (location_of (type), 0, + "use of %<auto%> in parameter declaration " + "only available with " + "-std=c++1y or -std=gnu++1y"); + else + pedwarn (location_of (type), OPT_Wpedantic, + "ISO C++ forbids use of %<auto%> in parameter " + "declaration"); } /* A parameter declared as an array of T is really a pointer to T. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index d5d29127cfd..4ac9445ecc9 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -188,11 +188,6 @@ cp_build_parm_decl (tree name, tree type) if (!processing_template_decl) DECL_ARG_TYPE (parm) = type_passed_as (type); - /* If the type is a pack expansion, then we have a function - parameter pack. */ - if (type && TREE_CODE (type) == TYPE_PACK_EXPANSION) - FUNCTION_PARAMETER_PACK_P (parm) = 1; - return parm; } @@ -507,8 +502,9 @@ check_member_template (tree tmpl) || (TREE_CODE (decl) == TYPE_DECL && MAYBE_CLASS_TYPE_P (TREE_TYPE (decl)))) { - /* The parser rejects template declarations in local classes. */ - gcc_assert (!current_function_decl); + /* The parser rejects template declarations in local classes + (with the exception of generic lambdas). */ + gcc_assert (!current_function_decl || LAMBDA_FUNCTION_P (decl)); /* The parser rejects any use of virtual in a function template. */ gcc_assert (!(TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl))); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 9b172594cad..4d04136e28e 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2472,12 +2472,15 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags) break; case PSEUDO_DTOR_EXPR: - dump_expr (pp, TREE_OPERAND (t, 2), flags); + dump_expr (pp, TREE_OPERAND (t, 0), flags); pp_cxx_dot (pp); - dump_type (pp, TREE_OPERAND (t, 0), flags); - pp_cxx_colon_colon (pp); + if (TREE_OPERAND (t, 1)) + { + dump_type (pp, TREE_OPERAND (t, 1), flags); + pp_cxx_colon_colon (pp); + } pp_cxx_complement (pp); - dump_type (pp, TREE_OPERAND (t, 1), flags); + dump_type (pp, TREE_OPERAND (t, 2), flags); break; case TEMPLATE_ID_EXPR: @@ -2786,9 +2789,7 @@ lang_decl_name (tree decl, int v, bool translate) location_t location_of (tree t) { - if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t)) - t = DECL_CONTEXT (t); - else if (TYPE_P (t)) + if (TYPE_P (t)) { t = TYPE_MAIN_DECL (t); if (t == NULL_TREE) @@ -3199,8 +3200,10 @@ print_instantiation_partial_context_line (diagnostic_context *context, const struct tinst_level *t, location_t loc, bool recursive_p) { - expanded_location xloc; - xloc = expand_location (loc); + if (loc == UNKNOWN_LOCATION) + return; + + expanded_location xloc = expand_location (loc); if (context->show_column) pp_verbatim (context->printer, _("%r%s:%d:%d:%R "), diff --git a/gcc/cp/except.c b/gcc/cp/except.c index fbebcbafdcb..c76d9440aa9 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -374,6 +374,9 @@ build_must_not_throw_expr (tree body, tree cond) { tree type = body ? TREE_TYPE (body) : void_type_node; + if (!flag_exceptions) + return body; + if (cond && !value_dependent_expression_p (cond)) { cond = cxx_constant_value (cond); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 5cb9acd6574..84f7ff9c20d 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3077,7 +3077,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type, { tree virtual_size; tree ptype = build_pointer_type (type = complete_type (type)); - tree size_exp = size_in_bytes (type); + tree size_exp; /* Temporary variables used by the loop. */ tree tbase, tbase_init; @@ -3105,6 +3105,23 @@ build_vec_delete_1 (tree base, tree maxindex, tree type, if (base == error_mark_node || maxindex == error_mark_node) return error_mark_node; + if (!COMPLETE_TYPE_P (type)) + { + if ((complain & tf_warning) + && warning (OPT_Wdelete_incomplete, + "possible problem detected in invocation of " + "delete [] operator:")) + { + cxx_incomplete_type_diagnostic (base, type, DK_WARNING); + inform (input_location, "neither the destructor nor the " + "class-specific operator delete [] will be called, " + "even if they are declared when the class is defined"); + } + return build_builtin_delete_call (base); + } + + size_exp = size_in_bytes (type); + if (! MAYBE_CLASS_TYPE_P (type) || TYPE_HAS_TRIVIAL_DESTRUCTOR (type)) goto no_destructor; @@ -3819,11 +3836,13 @@ build_delete (tree type, tree addr, special_function_kind auto_delete, if (!COMPLETE_TYPE_P (type)) { if ((complain & tf_warning) - && warning (0, "possible problem detected in invocation of " + && warning (OPT_Wdelete_incomplete, + "possible problem detected in invocation of " "delete operator:")) { cxx_incomplete_type_diagnostic (addr, type, DK_WARNING); - inform (input_location, "neither the destructor nor the class-specific " + inform (input_location, + "neither the destructor nor the class-specific " "operator delete will be called, even if they are " "declared when the class is defined"); } @@ -4108,6 +4127,7 @@ build_vec_delete (tree base, tree maxindex, tree cookie_addr; tree size_ptr_type = build_pointer_type (sizetype); + base = mark_rvalue_use (base); if (TREE_SIDE_EFFECTS (base)) { base_init = get_target_expr (base); diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index a53e692d48b..b04448b5487 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -196,7 +196,7 @@ lambda_function (tree lambda) /*protect=*/0, /*want_type=*/false, tf_warning_or_error); if (lambda) - lambda = BASELINK_FUNCTIONS (lambda); + lambda = STRIP_TEMPLATE (get_first_fn (lambda)); return lambda; } @@ -215,7 +215,8 @@ lambda_capture_field_type (tree expr, bool explicit_init_p) } else type = non_reference (unlowered_expr_type (expr)); - if (!type || WILDCARD_TYPE_P (type) || type_uses_auto (type)) + if (!type || WILDCARD_TYPE_P (type) || type_uses_auto (type) + || DECL_PACK_P (expr)) { type = cxx_make_type (DECLTYPE_TYPE); DECLTYPE_TYPE_EXPR (type) = expr; @@ -320,15 +321,21 @@ tree lambda_proxy_type (tree ref) { tree type; + if (ref == error_mark_node) + return error_mark_node; if (REFERENCE_REF_P (ref)) ref = TREE_OPERAND (ref, 0); + gcc_assert (TREE_CODE (ref) == COMPONENT_REF); type = TREE_TYPE (ref); - if (type && !WILDCARD_TYPE_P (non_reference (type))) - return type; - type = cxx_make_type (DECLTYPE_TYPE); - DECLTYPE_TYPE_EXPR (type) = ref; - DECLTYPE_FOR_LAMBDA_PROXY (type) = true; - SET_TYPE_STRUCTURAL_EQUALITY (type); + if (!type || WILDCARD_TYPE_P (non_reference (type))) + { + type = cxx_make_type (DECLTYPE_TYPE); + DECLTYPE_TYPE_EXPR (type) = ref; + DECLTYPE_FOR_LAMBDA_PROXY (type) = true; + SET_TYPE_STRUCTURAL_EQUALITY (type); + } + if (DECL_PACK_P (TREE_OPERAND (ref, 1))) + type = make_pack_expansion (type); return type; } @@ -341,6 +348,9 @@ build_capture_proxy (tree member) { tree var, object, fn, closure, name, lam, type; + if (PACK_EXPANSION_P (member)) + member = PACK_EXPANSION_PATTERN (member); + closure = DECL_CONTEXT (member); fn = lambda_function (closure); lam = CLASSTYPE_LAMBDA_EXPR (closure); @@ -422,12 +432,20 @@ vla_capture_type (tree array_type) and return it. */ tree -add_capture (tree lambda, tree id, tree initializer, bool by_reference_p, +add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, bool explicit_init_p) { char *buf; tree type, member, name; bool vla = false; + bool variadic = false; + tree initializer = orig_init; + + if (PACK_EXPANSION_P (initializer)) + { + initializer = PACK_EXPANSION_PATTERN (initializer); + variadic = true; + } if (TREE_CODE (initializer) == TREE_LIST) initializer = build_x_compound_expr_from_list (initializer, ELK_INIT, @@ -498,8 +516,11 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p, IDENTIFIER_MARKED (name) = true; } + if (variadic) + type = make_pack_expansion (type); + /* Make member variable. */ - member = build_lang_decl (FIELD_DECL, name, type); + member = build_decl (input_location, FIELD_DECL, name, type); DECL_VLA_CAPTURE_P (member) = vla; if (!explicit_init_p) @@ -518,8 +539,14 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p, && current_class_type == LAMBDA_EXPR_CLOSURE (lambda)) finish_member_declaration (member); + tree listmem = member; + if (variadic) + { + listmem = make_pack_expansion (member); + initializer = orig_init; + } LAMBDA_EXPR_CAPTURE_LIST (lambda) - = tree_cons (member, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda)); + = tree_cons (listmem, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda)); if (LAMBDA_EXPR_CLOSURE (lambda)) return build_capture_proxy (member); @@ -538,9 +565,14 @@ register_capture_members (tree captures) return; register_capture_members (TREE_CHAIN (captures)); + + tree field = TREE_PURPOSE (captures); + if (PACK_EXPANSION_P (field)) + field = PACK_EXPANSION_PATTERN (field); + /* We set this in add_capture to avoid duplicates. */ - IDENTIFIER_MARKED (DECL_NAME (TREE_PURPOSE (captures))) = false; - finish_member_declaration (TREE_PURPOSE (captures)); + IDENTIFIER_MARKED (DECL_NAME (field)) = false; + finish_member_declaration (field); } /* Similar to add_capture, except this works on a stack of nested lambdas. @@ -565,6 +597,8 @@ add_default_capture (tree lambda_stack, tree id, tree initializer) tree lambda = TREE_VALUE (node); current_class_type = LAMBDA_EXPR_CLOSURE (lambda); + if (DECL_PACK_P (initializer)) + initializer = make_pack_expansion (initializer); var = add_capture (lambda, id, initializer, @@ -741,6 +775,22 @@ nonlambda_method_basetype (void) return TYPE_METHOD_BASETYPE (TREE_TYPE (fn)); } +/* Helper function for maybe_add_lambda_conv_op; build a CALL_EXPR with + indicated FN and NARGS, but do not initialize the return type or any of the + argument slots. */ + +static tree +prepare_op_call (tree fn, int nargs) +{ + tree t; + + t = build_vl_exp (CALL_EXPR, nargs + 3); + CALL_EXPR_FN (t) = fn; + CALL_EXPR_STATIC_CHAIN (t) = NULL; + + return t; +} + /* If the closure TYPE has a static op(), also add a conversion to function pointer. */ @@ -749,9 +799,6 @@ maybe_add_lambda_conv_op (tree type) { bool nested = (current_function_decl != NULL_TREE); tree callop = lambda_function (type); - tree rettype, name, fntype, fn, body, compound_stmt; - tree thistype, stattype, statfn, convfn, call, arg; - vec<tree, va_gc> *argvec; if (LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (type)) != NULL_TREE) return; @@ -759,6 +806,10 @@ maybe_add_lambda_conv_op (tree type) if (processing_template_decl) return; + bool const generic_lambda_p + = (DECL_TEMPLATE_INFO (callop) + && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (callop)) == callop); + if (DECL_INITIAL (callop) == NULL_TREE) { /* If the op() wasn't instantiated due to errors, give up. */ @@ -766,16 +817,124 @@ maybe_add_lambda_conv_op (tree type) return; } - stattype = build_function_type (TREE_TYPE (TREE_TYPE (callop)), - FUNCTION_ARG_CHAIN (callop)); + /* Non-template conversion operators are defined directly with build_call_a + and using DIRECT_ARGVEC for arguments (including 'this'). Templates are + deferred and the CALL is built in-place. In the case of a deduced return + call op, the decltype expression, DECLTYPE_CALL, used as a substitute for + the return type is also built in-place. The arguments of DECLTYPE_CALL in + the return expression may differ in flags from those in the body CALL. In + particular, parameter pack expansions are marked PACK_EXPANSION_LOCAL_P in + the body CALL, but not in DECLTYPE_CALL. */ + + vec<tree, va_gc> *direct_argvec = 0; + tree decltype_call = 0, call = 0; + tree fn_result = TREE_TYPE (TREE_TYPE (callop)); + + if (generic_lambda_p) + { + /* Prepare the dependent member call for the static member function + '_FUN' and, potentially, prepare another call to be used in a decltype + return expression for a deduced return call op to allow for simple + implementation of the conversion operator. */ + + tree instance = build_nop (type, null_pointer_node); + tree objfn = build_min (COMPONENT_REF, NULL_TREE, + instance, DECL_NAME (callop), NULL_TREE); + int nargs = list_length (DECL_ARGUMENTS (callop)) - 1; + + call = prepare_op_call (objfn, nargs); + if (type_uses_auto (fn_result)) + decltype_call = prepare_op_call (objfn, nargs); + } + else + { + direct_argvec = make_tree_vector (); + direct_argvec->quick_push (build1 (NOP_EXPR, + TREE_TYPE (DECL_ARGUMENTS (callop)), + null_pointer_node)); + } + + /* Copy CALLOP's argument list (as per 'copy_list') as FN_ARGS in order to + declare the static member function "_FUN" below. For each arg append to + DIRECT_ARGVEC (for the non-template case) or populate the pre-allocated + call args (for the template case). If a parameter pack is found, expand + it, flagging it as PACK_EXPANSION_LOCAL_P for the body call. */ + + tree fn_args = NULL_TREE; + { + int ix = 0; + tree src = DECL_CHAIN (DECL_ARGUMENTS (callop)); + tree tgt; + + while (src) + { + tree new_node = copy_node (src); + + if (!fn_args) + fn_args = tgt = new_node; + else + { + TREE_CHAIN (tgt) = new_node; + tgt = new_node; + } + + mark_exp_read (tgt); + + if (generic_lambda_p) + { + if (DECL_PACK_P (tgt)) + { + tree a = make_pack_expansion (tgt); + if (decltype_call) + CALL_EXPR_ARG (decltype_call, ix) = copy_node (a); + PACK_EXPANSION_LOCAL_P (a) = true; + CALL_EXPR_ARG (call, ix) = a; + } + else + { + tree a = convert_from_reference (tgt); + CALL_EXPR_ARG (call, ix) = a; + if (decltype_call) + CALL_EXPR_ARG (decltype_call, ix) = copy_node (a); + } + ++ix; + } + else + vec_safe_push (direct_argvec, tgt); + + src = TREE_CHAIN (src); + } + } + + + if (generic_lambda_p) + { + if (decltype_call) + { + ++processing_template_decl; + fn_result = finish_decltype_type + (decltype_call, /*id_expression_or_member_access_p=*/false, + tf_warning_or_error); + --processing_template_decl; + } + } + else + call = build_call_a (callop, + direct_argvec->length (), + direct_argvec->address ()); + + CALL_FROM_THUNK_P (call) = 1; + + tree stattype = build_function_type (fn_result, FUNCTION_ARG_CHAIN (callop)); /* First build up the conversion op. */ - rettype = build_pointer_type (stattype); - name = mangle_conv_op_name_for_type (rettype); - thistype = cp_build_qualified_type (type, TYPE_QUAL_CONST); - fntype = build_method_type_directly (thistype, rettype, void_list_node); - fn = convfn = build_lang_decl (FUNCTION_DECL, name, fntype); + tree rettype = build_pointer_type (stattype); + tree name = mangle_conv_op_name_for_type (rettype); + tree thistype = cp_build_qualified_type (type, TYPE_QUAL_CONST); + tree fntype = build_method_type_directly (thistype, rettype, void_list_node); + tree convfn = build_lang_decl (FUNCTION_DECL, name, fntype); + tree fn = convfn; DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop); if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn @@ -794,6 +953,9 @@ maybe_add_lambda_conv_op (tree type) if (nested) DECL_INTERFACE_KNOWN (fn) = 1; + if (generic_lambda_p) + fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop)); + add_method (type, fn, NULL_TREE); /* Generic thunk code fails for varargs; we'll complain in mark_used if @@ -807,7 +969,8 @@ maybe_add_lambda_conv_op (tree type) /* Now build up the thunk to be returned. */ name = get_identifier ("_FUN"); - fn = statfn = build_lang_decl (FUNCTION_DECL, name, stattype); + tree statfn = build_lang_decl (FUNCTION_DECL, name, stattype); + fn = statfn; DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop); if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT) @@ -820,8 +983,8 @@ maybe_add_lambda_conv_op (tree type) DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_DECLARED_INLINE_P (fn) = 1; DECL_STATIC_FUNCTION_P (fn) = 1; - DECL_ARGUMENTS (fn) = copy_list (DECL_CHAIN (DECL_ARGUMENTS (callop))); - for (arg = DECL_ARGUMENTS (fn); arg; arg = DECL_CHAIN (arg)) + DECL_ARGUMENTS (fn) = fn_args; + for (tree arg = fn_args; arg; arg = DECL_CHAIN (arg)) { /* Avoid duplicate -Wshadow warnings. */ DECL_NAME (arg) = NULL_TREE; @@ -830,6 +993,9 @@ maybe_add_lambda_conv_op (tree type) if (nested) DECL_INTERFACE_KNOWN (fn) = 1; + if (generic_lambda_p) + fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop)); + add_method (type, fn, NULL_TREE); if (nested) @@ -850,29 +1016,23 @@ maybe_add_lambda_conv_op (tree type) ((symtab_node) cgraph_get_create_node (statfn), (symtab_node) cgraph_get_create_node (callop)); } - body = begin_function_body (); - compound_stmt = begin_compound_stmt (0); - - arg = build1 (NOP_EXPR, TREE_TYPE (DECL_ARGUMENTS (callop)), - null_pointer_node); - argvec = make_tree_vector (); - argvec->quick_push (arg); - for (arg = DECL_ARGUMENTS (statfn); arg; arg = DECL_CHAIN (arg)) + tree body = begin_function_body (); + tree compound_stmt = begin_compound_stmt (0); + if (!generic_lambda_p) { - mark_exp_read (arg); - vec_safe_push (argvec, arg); + set_flags_from_callee (call); + if (MAYBE_CLASS_TYPE_P (TREE_TYPE (call))) + call = build_cplus_new (TREE_TYPE (call), call, tf_warning_or_error); } - call = build_call_a (callop, argvec->length (), argvec->address ()); - CALL_FROM_THUNK_P (call) = 1; - if (MAYBE_CLASS_TYPE_P (TREE_TYPE (call))) - call = build_cplus_new (TREE_TYPE (call), call, tf_warning_or_error); call = convert_from_reference (call); finish_return_stmt (call); finish_compound_stmt (compound_stmt); finish_function_body (body); - expand_or_defer_fn (finish_function (2)); + fn = finish_function (/*inline*/2); + if (!generic_lambda_p) + expand_or_defer_fn (fn); /* Generate the body of the conversion op. */ @@ -888,7 +1048,9 @@ maybe_add_lambda_conv_op (tree type) finish_compound_stmt (compound_stmt); finish_function_body (body); - expand_or_defer_fn (finish_function (2)); + fn = finish_function (/*inline*/2); + if (!generic_lambda_p) + expand_or_defer_fn (fn); if (nested) pop_function_context (); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0f177ace9c9..c104f3ee413 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see #include "plugin.h" #include "tree-pretty-print.h" #include "parser.h" +#include "type-utils.h" /* The lexer. */ @@ -2063,6 +2064,11 @@ static vec<constructor_elt, va_gc> *cp_parser_initializer_list static bool cp_parser_ctor_initializer_opt_and_function_body (cp_parser *, bool); +static tree add_implicit_template_parms + (cp_parser *, size_t, tree); +static tree finish_fully_implicit_template + (cp_parser *, tree); + /* Classes [gram.class] */ static tree cp_parser_class_name @@ -3385,6 +3391,9 @@ cp_parser_new (void) /* No template parameters apply. */ parser->num_template_parameter_lists = 0; + /* Not declaring an implicit function template. */ + parser->fully_implicit_function_template_p = false; + return parser; } @@ -5533,6 +5542,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, cp_id_kind * pidk_return) { cp_token *token; + location_t loc; enum rid keyword; cp_id_kind idk = CP_ID_KIND_NONE; tree postfix_expression = NULL_TREE; @@ -5540,6 +5550,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); + loc = token->location; /* Some of the productions are determined by keywords. */ keyword = token->keyword; switch (keyword) @@ -5685,7 +5696,6 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, vec<tree, va_gc> *vec; unsigned int i; tree p; - location_t loc = token->location; cp_lexer_consume_token (parser->lexer); vec = cp_parser_parenthesized_expression_list (parser, non_attr, @@ -6018,8 +6028,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, postfix_expression = cp_parser_postfix_dot_deref_expression (parser, token->type, postfix_expression, - false, &idk, - token->location); + false, &idk, loc); is_member_access = true; break; @@ -6338,7 +6347,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, pseudo_destructor_p = true; postfix_expression = finish_pseudo_destructor_expr (postfix_expression, - s, type); + s, type, location); } } @@ -8549,10 +8558,12 @@ cp_parser_lambda_expression (cp_parser* parser) = parser->num_template_parameter_lists; unsigned char in_statement = parser->in_statement; bool in_switch_statement_p = parser->in_switch_statement_p; + bool fully_implicit_function_template_p = parser->fully_implicit_function_template_p; parser->num_template_parameter_lists = 0; parser->in_statement = 0; parser->in_switch_statement_p = false; + parser->fully_implicit_function_template_p = false; /* By virtue of defining a local class, a lambda expression has access to the private variables of enclosing classes. */ @@ -8576,6 +8587,7 @@ cp_parser_lambda_expression (cp_parser* parser) parser->num_template_parameter_lists = saved_num_template_parameter_lists; parser->in_statement = in_statement; parser->in_switch_statement_p = in_switch_statement_p; + parser->fully_implicit_function_template_p = fully_implicit_function_template_p; } pop_deferring_access_checks (); @@ -8753,6 +8765,14 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) /*template_arg_p=*/false, &error_msg, capture_token->location); + + if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) + { + cp_lexer_consume_token (parser->lexer); + capture_init_expr = make_pack_expansion (capture_init_expr); + } + else + check_for_bare_parameter_packs (capture_init_expr); } if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE @@ -8783,6 +8803,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) /* Parse the (optional) middle of a lambda expression. lambda-declarator: + < template-parameter-list [opt] > ( parameter-declaration-clause [opt] ) attribute-specifier [opt] mutable [opt] @@ -8802,9 +8823,30 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) tree param_list = void_list_node; tree attributes = NULL_TREE; tree exception_spec = NULL_TREE; + tree template_param_list = NULL_TREE; + + /* The template-parameter-list is optional, but must begin with + an opening angle if present. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) + { + if (cxx_dialect < cxx1y) + pedwarn (parser->lexer->next_token->location, 0, + "lambda templates are only available with " + "-std=c++1y or -std=gnu++1y"); + + cp_lexer_consume_token (parser->lexer); + + template_param_list = cp_parser_template_parameter_list (parser); + + cp_parser_skip_to_end_of_template_parameter_list (parser); + + /* We just processed one more parameter list. */ + ++parser->num_template_parameter_lists; + } - /* The lambda-declarator is optional, but must begin with an opening - parenthesis if present. */ + /* The parameter-declaration-clause is optional (unless + template-parameter-list was given), but must begin with an + opening parenthesis if present. */ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) { cp_lexer_consume_token (parser->lexer); @@ -8847,6 +8889,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) trailing-return-type in case of decltype. */ pop_bindings_and_leave_scope (); } + else if (template_param_list != NULL_TREE) // generate diagnostic + cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); /* Create the function call operator. @@ -8890,6 +8934,14 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) DECL_ARTIFICIAL (fco) = 1; /* Give the object parameter a different name. */ DECL_NAME (DECL_ARGUMENTS (fco)) = get_identifier ("__closure"); + if (template_param_list) + { + fco = finish_member_template_decl (fco); + finish_template_decl (template_param_list); + --parser->num_template_parameter_lists; + } + else if (parser->fully_implicit_function_template_p) + fco = finish_fully_implicit_template (parser, fco); } finish_member_declaration (fco); @@ -9012,7 +9064,11 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) finish_lambda_scope (); /* Finish the function and generate code for it if necessary. */ - expand_or_defer_fn (finish_function (/*inline*/2)); + tree fn = finish_function (/*inline*/2); + + /* Only expand if the call op is not a template. */ + if (!DECL_TEMPLATE_INFO (fco)) + expand_or_defer_fn (fn); } parser->local_variables_forbidden_p = local_variables_forbidden_p; @@ -16247,56 +16303,62 @@ cp_parser_init_declarator (cp_parser* parser, /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); - /* Check to see if the token indicates the start of a - function-definition. */ - if (function_declarator_p (declarator) - && cp_parser_token_starts_function_definition_p (token)) + + if (function_declarator_p (declarator)) { - if (!function_definition_allowed_p) + /* Check to see if the token indicates the start of a + function-definition. */ + if (cp_parser_token_starts_function_definition_p (token)) { - /* If a function-definition should not appear here, issue an - error message. */ - cp_parser_error (parser, - "a function-definition is not allowed here"); - return error_mark_node; - } - else - { - location_t func_brace_location - = cp_lexer_peek_token (parser->lexer)->location; - - /* Neither attributes nor an asm-specification are allowed - on a function-definition. */ - if (asm_specification) - error_at (asm_spec_start_token->location, - "an asm-specification is not allowed " - "on a function-definition"); - if (attributes) - error_at (attributes_start_token->location, - "attributes are not allowed on a function-definition"); - /* This is a function-definition. */ - *function_definition_p = true; - - /* Parse the function definition. */ - if (member_p) - decl = cp_parser_save_member_function_body (parser, - decl_specifiers, - declarator, - prefix_attributes); - else - decl - = (cp_parser_function_definition_from_specifiers_and_declarator - (parser, decl_specifiers, prefix_attributes, declarator)); - - if (decl != error_mark_node && DECL_STRUCT_FUNCTION (decl)) + if (!function_definition_allowed_p) { - /* This is where the prologue starts... */ - DECL_STRUCT_FUNCTION (decl)->function_start_locus - = func_brace_location; + /* If a function-definition should not appear here, issue an + error message. */ + cp_parser_error (parser, + "a function-definition is not allowed here"); + return error_mark_node; } + else + { + location_t func_brace_location + = cp_lexer_peek_token (parser->lexer)->location; + + /* Neither attributes nor an asm-specification are allowed + on a function-definition. */ + if (asm_specification) + error_at (asm_spec_start_token->location, + "an asm-specification is not allowed " + "on a function-definition"); + if (attributes) + error_at (attributes_start_token->location, + "attributes are not allowed " + "on a function-definition"); + /* This is a function-definition. */ + *function_definition_p = true; + + /* Parse the function definition. */ + if (member_p) + decl = cp_parser_save_member_function_body (parser, + decl_specifiers, + declarator, + prefix_attributes); + else + decl = + (cp_parser_function_definition_from_specifiers_and_declarator + (parser, decl_specifiers, prefix_attributes, declarator)); - return decl; + if (decl != error_mark_node && DECL_STRUCT_FUNCTION (decl)) + { + /* This is where the prologue starts... */ + DECL_STRUCT_FUNCTION (decl)->function_start_locus + = func_brace_location; + } + + return decl; + } } + else if (parser->fully_implicit_function_template_p) + decl = finish_fully_implicit_template (parser, decl); } /* [dcl.dcl] @@ -16756,8 +16818,10 @@ cp_parser_direct_declarator (cp_parser* parser, /* Parse the parameter-declaration-clause. */ params = cp_parser_parameter_declaration_clause (parser); + /* Restore saved template parameter lists accounting for implicit + template parameters. */ parser->num_template_parameter_lists - = saved_num_template_parameter_lists; + += saved_num_template_parameter_lists; /* Consume the `)'. */ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); @@ -17855,6 +17919,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) tree *tail = ¶meters; bool saved_in_unbraced_linkage_specification_p; int index = 0; + int implicit_template_parms = 0; /* Assume all will go well. */ *is_error = false; @@ -17882,11 +17947,18 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) deprecated_state = DEPRECATED_SUPPRESS; if (parameter) - decl = grokdeclarator (parameter->declarator, - ¶meter->decl_specifiers, - PARM, - parameter->default_argument != NULL_TREE, - ¶meter->decl_specifiers.attributes); + { + decl = grokdeclarator (parameter->declarator, + ¶meter->decl_specifiers, + PARM, + parameter->default_argument != NULL_TREE, + ¶meter->decl_specifiers.attributes); + + if (TREE_TYPE (decl) != error_mark_node + && parameter->decl_specifiers.type + && is_auto_or_concept (parameter->decl_specifiers.type)) + ++implicit_template_parms; + } deprecated_state = DEPRECATED_NORMAL; @@ -17974,6 +18046,11 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) parser->in_unbraced_linkage_specification_p = saved_in_unbraced_linkage_specification_p; + if (parameters != error_mark_node && implicit_template_parms) + parameters = add_implicit_template_parms (parser, + implicit_template_parms, + parameters); + return parameters; } @@ -19980,7 +20057,11 @@ cp_parser_member_declaration (cp_parser* parser) attributes); /* If the member was not a friend, declare it here. */ if (!friend_p) - finish_member_declaration (decl); + { + if (parser->fully_implicit_function_template_p) + decl = finish_fully_implicit_template (parser, decl); + finish_member_declaration (decl); + } /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); /* If the next token is a semicolon, consume it. */ @@ -19996,6 +20077,8 @@ cp_parser_member_declaration (cp_parser* parser) initializer, /*init_const_expr_p=*/true, asm_specification, attributes); + if (parser->fully_implicit_function_template_p) + decl = finish_fully_implicit_template (parser, decl); } /* Reset PREFIX_ATTRIBUTES. */ @@ -22263,6 +22346,9 @@ cp_parser_function_definition_after_declarator (cp_parser* parser, = saved_num_template_parameter_lists; parser->in_function_body = saved_in_function_body; + if (parser->fully_implicit_function_template_p) + finish_fully_implicit_template (parser, /*member_decl_opt=*/0); + return fn; } @@ -28808,4 +28894,147 @@ c_parse_file (void) the_parser = NULL; } +/* Create an identifier for a generic parameter type (a synthesized + template parameter implied by `auto' or a concept identifier). */ + +static tree +make_generic_type_name (int i) +{ + char buf[32]; + sprintf (buf, "__GenT%d", i); + return get_identifier (buf); +} + +/* Predicate that behaves as is_auto_or_concept but matches the parent + node of the generic type rather than the generic type itself. This + allows for type transformation in add_implicit_template_parms. */ + +static inline bool +tree_type_is_auto_or_concept (const_tree t) +{ + return TREE_TYPE (t) && is_auto_or_concept (TREE_TYPE (t)); +} + +/* Add COUNT implicit template parameters gleaned from the generic + type parameters in PARAMETERS to the CURRENT_TEMPLATE_PARMS + (creating a new template parameter list if necessary). Returns + PARAMETERS suitably rewritten to reference the newly created types + or ERROR_MARK_NODE on failure. */ + +tree +add_implicit_template_parms (cp_parser *parser, size_t count, tree parameters) +{ + gcc_assert (current_binding_level->kind == sk_function_parms); + + cp_binding_level *fn_parms_scope = current_binding_level; + + bool become_template = + fn_parms_scope->level_chain->kind != sk_template_parms; + + size_t synth_idx = 0; + + /* Roll back a scope level and either introduce a new template parameter list + or update an existing one. The function scope is added back after template + parameter synthesis below. */ + current_binding_level = fn_parms_scope->level_chain; + + /* TPARMS tracks the function's template parameter list. This is either a new + chain in the case of a fully implicit function template or an extension of + the function's explicitly specified template parameter list. */ + tree tparms = NULL_TREE; + + if (become_template) + { + push_deferring_access_checks (dk_deferred); + begin_template_parm_list (); + + parser->fully_implicit_function_template_p = true; + ++parser->num_template_parameter_lists; + } + else + { + /* Roll back the innermost template parameter list such that it may be + extended in the loop below as if it were being explicitly declared. */ + + gcc_assert (current_template_parms); + + /* Pop the innermost template parms into TPARMS. */ + tree inner_vec = INNERMOST_TEMPLATE_PARMS (current_template_parms); + current_template_parms = TREE_CHAIN (current_template_parms); + + size_t inner_vec_len = TREE_VEC_LENGTH (inner_vec); + if (inner_vec_len != 0) + { + tree t = tparms = TREE_VEC_ELT (inner_vec, 0); + for (size_t n = 1; n < inner_vec_len; ++n) + t = TREE_CHAIN (t) = TREE_VEC_ELT (inner_vec, n); + } + + ++processing_template_parmlist; + } + + for (tree p = parameters; p && synth_idx < count; p = TREE_CHAIN (p)) + { + tree generic_type_ptr + = find_type_usage (TREE_VALUE (p), tree_type_is_auto_or_concept); + + if (!generic_type_ptr) + continue; + + tree synth_id = make_generic_type_name (synth_idx++); + tree synth_tmpl_parm = finish_template_type_parm (class_type_node, + synth_id); + tparms = process_template_parm (tparms, DECL_SOURCE_LOCATION (TREE_VALUE + (p)), + build_tree_list (NULL_TREE, + synth_tmpl_parm), + /*non_type=*/false, + /*param_pack=*/false); + + /* Rewrite the type of P to be the template_parm added above (getdecls is + used to retrieve it since it is the most recent declaration in this + scope). Qualifiers need to be preserved also. */ + + tree& cur_type = TREE_TYPE (generic_type_ptr); + tree new_type = TREE_TYPE (getdecls ()); + + if (TYPE_QUALS (cur_type)) + cur_type = cp_build_qualified_type (new_type, TYPE_QUALS (cur_type)); + else + cur_type = new_type; + } + + gcc_assert (synth_idx == count); + + push_binding_level (fn_parms_scope); + + end_template_parm_list (tparms); + + return parameters; +} + +/* Finish the declaration of a fully implicit function template. Such a + template has no explicit template parameter list so has not been through the + normal template head and tail processing. add_implicit_template_parms tries + to do the head; this tries to do the tail. MEMBER_DECL_OPT should be + provided if the declaration is a class member such that its template + declaration can be completed. If MEMBER_DECL_OPT is provided the finished + form is returned. Otherwise NULL_TREE is returned. */ + +tree +finish_fully_implicit_template (cp_parser *parser, tree member_decl_opt) +{ + gcc_assert (parser->fully_implicit_function_template_p); + + pop_deferring_access_checks (); + if (member_decl_opt) + member_decl_opt = finish_member_template_decl (member_decl_opt); + end_template_decl (); + + parser->fully_implicit_function_template_p = false; + --parser->num_template_parameter_lists; + + return member_decl_opt; +} + #include "gt-cp-parser.h" diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h index 3d8bb742d22..ffdddaf4a08 100644 --- a/gcc/cp/parser.h +++ b/gcc/cp/parser.h @@ -341,6 +341,12 @@ typedef struct GTY(()) cp_parser { /* The number of template parameter lists that apply directly to the current declaration. */ unsigned num_template_parameter_lists; + + /* TRUE if the function being declared was made a template due to its + parameter list containing generic type specifiers (`auto' or concept + identifiers) rather than an explicit template parameter list. */ + bool fully_implicit_function_template_p; + } cp_parser; /* In parser.c */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e937318d227..b330b78cbc8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "toplev.h" #include "timevar.h" #include "tree-iterator.h" +#include "type-utils.h" /* The type of functions taking a tree, and some additional data, and returning an int. */ @@ -1004,7 +1005,10 @@ optimize_specialization_lookup_p (tree tmpl) If TMPL is a type template and CLASS_SPECIALIZATIONS_P is true, then we search for a partial specialization matching ARGS. This - parameter is ignored if TMPL is not a class template. */ + parameter is ignored if TMPL is not a class template. + + We can also look up a FIELD_DECL, if it is a lambda capture pack; the + result is a NONTYPE_ARGUMENT_PACK. */ static tree retrieve_specialization (tree tmpl, tree args, hashval_t hash) @@ -1015,12 +1019,15 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash) if (args == error_mark_node) return NULL_TREE; - gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); + gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL + || TREE_CODE (tmpl) == FIELD_DECL); /* There should be as many levels of arguments as there are levels of parameters. */ gcc_assert (TMPL_ARGS_DEPTH (args) - == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl))); + == (TREE_CODE (tmpl) == TEMPLATE_DECL + ? TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)) + : template_class_depth (DECL_CONTEXT (tmpl)))); if (optimize_specialization_lookup_p (tmpl)) { @@ -1311,7 +1318,10 @@ is_specialization_of_friend (tree decl, tree friend_decl) /* Register the specialization SPEC as a specialization of TMPL with the indicated ARGS. IS_FRIEND indicates whether the specialization is actually just a friend declaration. Returns SPEC, or an - equivalent prior declaration, if available. */ + equivalent prior declaration, if available. + + We also store instantiations of field packs in the hash table, even + though they are not themselves templates, to make lookup easier. */ static tree register_specialization (tree spec, tree tmpl, tree args, bool is_friend, @@ -1321,7 +1331,9 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend, void **slot = NULL; spec_entry elt; - gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL && DECL_P (spec)); + gcc_assert ((TREE_CODE (tmpl) == TEMPLATE_DECL && DECL_P (spec)) + || (TREE_CODE (tmpl) == FIELD_DECL + && TREE_CODE (spec) == NONTYPE_ARGUMENT_PACK)); if (TREE_CODE (spec) == FUNCTION_DECL && uses_template_parms (DECL_TI_ARGS (spec))) @@ -1443,7 +1455,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend, /* A specialization must be declared in the same namespace as the template it is specializing. */ - if (DECL_TEMPLATE_SPECIALIZATION (spec) + if (DECL_P (spec) && DECL_TEMPLATE_SPECIALIZATION (spec) && !check_specialization_namespace (tmpl)) DECL_CONTEXT (spec) = DECL_CONTEXT (tmpl); @@ -2852,7 +2864,7 @@ bool function_parameter_pack_p (const_tree t) { if (t && TREE_CODE (t) == PARM_DECL) - return FUNCTION_PARAMETER_PACK_P (t); + return DECL_PACK_P (t); return false; } @@ -3084,8 +3096,9 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) parameter_pack_p = true; break; + case FIELD_DECL: case PARM_DECL: - if (FUNCTION_PARAMETER_PACK_P (t)) + if (DECL_PACK_P (t)) { /* We don't want to walk into the type of a PARM_DECL, because we don't want to see the type parameter pack. */ @@ -3094,6 +3107,18 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) } break; + /* Look through a lambda capture proxy to the field pack. */ + case VAR_DECL: + if (DECL_HAS_VALUE_EXPR_P (t)) + { + tree v = DECL_VALUE_EXPR (t); + cp_walk_tree (&v, + &find_parameter_packs_r, + ppd, ppd->visited); + *walk_subtrees = 0; + } + break; + case BASES: parameter_pack_p = true; break; @@ -4646,7 +4671,7 @@ push_template_decl_real (tree decl, bool is_friend) while (arg && argtype) { - if (!FUNCTION_PARAMETER_PACK_P (arg) + if (!DECL_PACK_P (arg) && check_for_bare_parameter_packs (TREE_TYPE (arg))) { /* This is a PARM_DECL that contains unexpanded parameter @@ -5398,7 +5423,8 @@ unify_arg_conversion (bool explain_p, tree to_type, tree from_type, tree arg) { if (explain_p) - inform (input_location, " cannot convert %qE (type %qT) to type %qT", + inform (EXPR_LOC_OR_HERE (arg), + " cannot convert %qE (type %qT) to type %qT", arg, from_type, to_type); return 1; } @@ -8912,6 +8938,8 @@ instantiate_class_template_1 (tree type) else if (TREE_CODE (t) != CONST_DECL) { tree r; + tree vec = NULL_TREE; + int len = 1; /* The file and line for this declaration, to assist in error message reporting. Since we @@ -8924,55 +8952,68 @@ instantiate_class_template_1 (tree type) r = tsubst (t, args, tf_warning_or_error, NULL_TREE); if (TREE_CODE (t) == TEMPLATE_DECL) --processing_template_decl; - if (VAR_P (r)) + + if (TREE_CODE (r) == TREE_VEC) { - /* In [temp.inst]: - - [t]he initialization (and any associated - side-effects) of a static data member does - not occur unless the static data member is - itself used in a way that requires the - definition of the static data member to - exist. - - Therefore, we do not substitute into the - initialized for the static data member here. */ - finish_static_data_member_decl - (r, - /*init=*/NULL_TREE, - /*init_const_expr_p=*/false, - /*asmspec_tree=*/NULL_TREE, - /*flags=*/0); - /* Instantiate members marked with attribute used. */ - if (r != error_mark_node && DECL_PRESERVE_P (r)) - mark_used (r); + /* A capture pack became multiple fields. */ + vec = r; + len = TREE_VEC_LENGTH (vec); } - else if (TREE_CODE (r) == FIELD_DECL) + + for (int i = 0; i < len; ++i) { - /* Determine whether R has a valid type and can be - completed later. If R is invalid, then its type is - replaced by error_mark_node. */ - tree rtype = TREE_TYPE (r); - if (can_complete_type_without_circularity (rtype)) - complete_type (rtype); - - if (!COMPLETE_TYPE_P (rtype)) + if (vec) + r = TREE_VEC_ELT (vec, i); + if (VAR_P (r)) { - cxx_incomplete_type_error (r, rtype); - TREE_TYPE (r) = error_mark_node; + /* In [temp.inst]: + + [t]he initialization (and any associated + side-effects) of a static data member does + not occur unless the static data member is + itself used in a way that requires the + definition of the static data member to + exist. + + Therefore, we do not substitute into the + initialized for the static data member here. */ + finish_static_data_member_decl + (r, + /*init=*/NULL_TREE, + /*init_const_expr_p=*/false, + /*asmspec_tree=*/NULL_TREE, + /*flags=*/0); + /* Instantiate members marked with attribute used. */ + if (r != error_mark_node && DECL_PRESERVE_P (r)) + mark_used (r); + } + else if (TREE_CODE (r) == FIELD_DECL) + { + /* Determine whether R has a valid type and can be + completed later. If R is invalid, then its type + is replaced by error_mark_node. */ + tree rtype = TREE_TYPE (r); + if (can_complete_type_without_circularity (rtype)) + complete_type (rtype); + + if (!COMPLETE_TYPE_P (rtype)) + { + cxx_incomplete_type_error (r, rtype); + TREE_TYPE (r) = error_mark_node; + } } - } - /* If it is a TYPE_DECL for a class-scoped ENUMERAL_TYPE, - such a thing will already have been added to the field - list by tsubst_enum in finish_member_declaration in the - CLASSTYPE_NESTED_UTDS case above. */ - if (!(TREE_CODE (r) == TYPE_DECL - && TREE_CODE (TREE_TYPE (r)) == ENUMERAL_TYPE - && DECL_ARTIFICIAL (r))) - { - set_current_access_from_decl (r); - finish_member_declaration (r); + /* If it is a TYPE_DECL for a class-scoped ENUMERAL_TYPE, + such a thing will already have been added to the field + list by tsubst_enum in finish_member_declaration in the + CLASSTYPE_NESTED_UTDS case above. */ + if (!(TREE_CODE (r) == TYPE_DECL + && TREE_CODE (TREE_TYPE (r)) == ENUMERAL_TYPE + && DECL_ARTIFICIAL (r))) + { + set_current_access_from_decl (r); + finish_member_declaration (r); + } } } } @@ -9102,7 +9143,9 @@ instantiate_class_template_1 (tree type) tree decl = lambda_function (type); if (decl) { - instantiate_decl (decl, false, false); + if (!DECL_TEMPLATE_INFO (decl) + || DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl)) != decl) + instantiate_decl (decl, false, false); /* We need to instantiate the capture list from the template after we've instantiated the closure members, but before we @@ -9366,7 +9409,8 @@ gen_elem_of_pack_expansion_instantiation (tree pattern, argument_pack_element_is_expansion_p (arg_pack, index); /* Select the Ith argument from the pack. */ - if (TREE_CODE (parm) == PARM_DECL) + if (TREE_CODE (parm) == PARM_DECL + || TREE_CODE (parm) == FIELD_DECL) { if (index == 0) { @@ -9471,7 +9515,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, have the wrong value for a recursive call. Just make a dummy decl, since it's only used for its type. */ arg_pack = tsubst_decl (parm_pack, args, complain); - if (arg_pack && FUNCTION_PARAMETER_PACK_P (arg_pack)) + if (arg_pack && DECL_PACK_P (arg_pack)) /* Partial instantiation of the parm_pack, we can't build up an argument pack yet. */ arg_pack = NULL_TREE; @@ -9480,6 +9524,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, need_local_specializations = true; } } + else if (TREE_CODE (parm_pack) == FIELD_DECL) + arg_pack = tsubst_copy (parm_pack, args, complain, in_decl); else { int idx; @@ -9604,7 +9650,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, { tree parm = TREE_PURPOSE (pack); - if (TREE_CODE (parm) == PARM_DECL) + if (TREE_CODE (parm) == PARM_DECL + || TREE_CODE (parm) == FIELD_DECL) register_local_specialization (TREE_TYPE (pack), parm); else { @@ -10464,7 +10511,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) tree prev_r = NULL_TREE; tree first_r = NULL_TREE; - if (FUNCTION_PARAMETER_PACK_P (t)) + if (DECL_PACK_P (t)) { /* If there is a local specialization that isn't a parameter pack, it means that we're doing a "simple" @@ -10499,7 +10546,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) } } - /* Loop through all of the parameter's we'll build. When T is + /* Loop through all of the parameters we'll build. When T is a function parameter pack, LEN is the number of expanded types in EXPANDED_TYPES; otherwise, LEN is 1. */ r = NULL_TREE; @@ -10514,10 +10561,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) /* We're on the Ith parameter of the function parameter pack. */ { - /* An argument of a function parameter pack is not a parameter - pack. */ - FUNCTION_PARAMETER_PACK_P (r) = false; - /* Get the Ith type. */ type = TREE_VEC_ELT (expanded_types, i); @@ -10575,39 +10618,88 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) case FIELD_DECL: { - tree type; + tree type = NULL_TREE; + tree vec = NULL_TREE; + tree expanded_types = NULL_TREE; + int len = 1; - r = copy_decl (t); - type = tsubst (TREE_TYPE (t), args, complain, in_decl); - if (type == error_mark_node) - RETURN (error_mark_node); - TREE_TYPE (r) = type; - cp_apply_type_quals_to_decl (cp_type_quals (type), r); + if (PACK_EXPANSION_P (TREE_TYPE (t))) + { + /* This field is a lambda capture pack. Return a TREE_VEC of + the expanded fields to instantiate_class_template_1 and + store them in the specializations hash table as a + NONTYPE_ARGUMENT_PACK so that tsubst_copy can find them. */ + expanded_types = tsubst_pack_expansion (TREE_TYPE (t), args, + complain, in_decl); + if (TREE_CODE (expanded_types) == TREE_VEC) + { + len = TREE_VEC_LENGTH (expanded_types); + vec = make_tree_vec (len); + } + else + { + /* All we did was update the type. Make a note of that. */ + type = expanded_types; + expanded_types = NULL_TREE; + } + } - if (DECL_C_BIT_FIELD (r)) - /* For bit-fields, DECL_INITIAL gives the number of bits. For - non-bit-fields DECL_INITIAL is a non-static data member - initializer, which gets deferred instantiation. */ - DECL_INITIAL (r) - = tsubst_expr (DECL_INITIAL (t), args, - complain, in_decl, - /*integral_constant_expression_p=*/true); - else if (DECL_INITIAL (t)) + for (int i = 0; i < len; ++i) { - /* Set up DECL_TEMPLATE_INFO so that we can get at the - NSDMI in perform_member_init. Still set DECL_INITIAL - so that we know there is one. */ - DECL_INITIAL (r) = void_zero_node; - gcc_assert (DECL_LANG_SPECIFIC (r) == NULL); - retrofit_lang_decl (r); - DECL_TEMPLATE_INFO (r) = build_template_info (t, args); + r = copy_decl (t); + if (expanded_types) + { + type = TREE_VEC_ELT (expanded_types, i); + DECL_NAME (r) + = make_ith_pack_parameter_name (DECL_NAME (r), i); + } + else if (!type) + type = tsubst (TREE_TYPE (t), args, complain, in_decl); + + if (type == error_mark_node) + RETURN (error_mark_node); + TREE_TYPE (r) = type; + cp_apply_type_quals_to_decl (cp_type_quals (type), r); + + if (DECL_C_BIT_FIELD (r)) + /* For bit-fields, DECL_INITIAL gives the number of bits. For + non-bit-fields DECL_INITIAL is a non-static data member + initializer, which gets deferred instantiation. */ + DECL_INITIAL (r) + = tsubst_expr (DECL_INITIAL (t), args, + complain, in_decl, + /*integral_constant_expression_p=*/true); + else if (DECL_INITIAL (t)) + { + /* Set up DECL_TEMPLATE_INFO so that we can get at the + NSDMI in perform_member_init. Still set DECL_INITIAL + so that we know there is one. */ + DECL_INITIAL (r) = void_zero_node; + gcc_assert (DECL_LANG_SPECIFIC (r) == NULL); + retrofit_lang_decl (r); + DECL_TEMPLATE_INFO (r) = build_template_info (t, args); + } + /* We don't have to set DECL_CONTEXT here; it is set by + finish_member_declaration. */ + DECL_CHAIN (r) = NULL_TREE; + + apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0, + args, complain, in_decl); + + if (vec) + TREE_VEC_ELT (vec, i) = r; } - /* We don't have to set DECL_CONTEXT here; it is set by - finish_member_declaration. */ - DECL_CHAIN (r) = NULL_TREE; - apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0, - args, complain, in_decl); + if (vec) + { + r = vec; + tree pack = make_node (NONTYPE_ARGUMENT_PACK); + tree tpack = cxx_make_type (TYPE_ARGUMENT_PACK); + SET_ARGUMENT_PACK_ARGS (pack, vec); + SET_ARGUMENT_PACK_ARGS (tpack, expanded_types); + TREE_TYPE (pack) = tpack; + register_specialization (pack, t, args, false, 0); + } } break; @@ -10756,14 +10848,14 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) { /* It may seem that this case cannot occur, since: - typedef void f(); - void g() { f x; } + typedef void f(); + void g() { f x; } declares a function, not a variable. However: - typedef void f(); - template <typename T> void g() { T t; } - template void g<f>(); + typedef void f(); + template <typename T> void g() { T t; } + template void g<f>(); is an attempt to declare a variable with function type. */ @@ -11448,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. */ @@ -12264,6 +12356,23 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) return t; case FIELD_DECL: + if (PACK_EXPANSION_P (TREE_TYPE (t))) + { + /* Check for a local specialization set up by + tsubst_pack_expansion. */ + tree r = retrieve_local_specialization (t); + if (r) + { + if (TREE_CODE (r) == ARGUMENT_PACK_SELECT) + r = ARGUMENT_PACK_SELECT_ARG (r); + return r; + } + + /* Otherwise return the full NONTYPE_ARGUMENT_PACK that + tsubst_decl put in the hash table. */ + return retrieve_specialization (t, args, 0); + } + if (DECL_CONTEXT (t)) { tree ctx; @@ -12325,7 +12434,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) return t; case BASELINK: - return tsubst_baselink (t, current_class_type, args, complain, in_decl); + return tsubst_baselink (t, current_nonlambda_class_type (), + args, complain, in_decl); case TEMPLATE_DECL: if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)) @@ -13023,6 +13133,12 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, else do_local_using_decl (decl, scope, name); } + else if (DECL_PACK_P (decl)) + { + /* Don't build up decls for a variadic capture proxy, we'll + instantiate the elements directly as needed. */ + break; + } else { init = DECL_INITIAL (decl); @@ -14292,9 +14408,10 @@ tsubst_copy_and_build (tree t, case PSEUDO_DTOR_EXPR: RETURN (finish_pseudo_destructor_expr - (RECUR (TREE_OPERAND (t, 0)), - RECUR (TREE_OPERAND (t, 1)), - tsubst (TREE_OPERAND (t, 2), args, complain, in_decl))); + (RECUR (TREE_OPERAND (t, 0)), + RECUR (TREE_OPERAND (t, 1)), + tsubst (TREE_OPERAND (t, 2), args, complain, in_decl), + input_location)); case TREE_LIST: { @@ -14423,7 +14540,8 @@ tsubst_copy_and_build (tree t, { dtor = TREE_OPERAND (dtor, 0); if (TYPE_P (dtor)) - RETURN (finish_pseudo_destructor_expr (object, s, dtor)); + RETURN (finish_pseudo_destructor_expr + (object, s, dtor, input_location)); } } } @@ -14586,6 +14704,14 @@ tsubst_copy_and_build (tree t, case VAR_DECL: if (!args) RETURN (t); + else if (DECL_PACK_P (t)) + { + /* We don't build decls for an instantiation of a + variadic capture proxy, we instantiate the elements + when needed. */ + gcc_assert (DECL_HAS_VALUE_EXPR_P (t)); + return RECUR (DECL_VALUE_EXPR (t)); + } /* Fall through */ case PARM_DECL: @@ -18702,7 +18828,7 @@ regenerate_decl_from_template (tree decl, tree tmpl) pattern_parm = skip_artificial_parms_for (code_pattern, DECL_ARGUMENTS (code_pattern)); - while (decl_parm && !FUNCTION_PARAMETER_PACK_P (pattern_parm)) + while (decl_parm && !DECL_PACK_P (pattern_parm)) { tree parm_type; tree attributes; @@ -18725,7 +18851,7 @@ regenerate_decl_from_template (tree decl, tree tmpl) } /* Merge any parameters that match with the function parameter pack. */ - if (pattern_parm && FUNCTION_PARAMETER_PACK_P (pattern_parm)) + if (pattern_parm && DECL_PACK_P (pattern_parm)) { int i, len; tree expanded_types; @@ -18944,6 +19070,8 @@ instantiate_decl (tree d, int defer_ok, tree gen_tmpl; bool pattern_defined; location_t saved_loc = input_location; + int saved_unevaluated_operand = cp_unevaluated_operand; + int saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; bool external_p; tree fn_context; bool nested; @@ -19155,8 +19283,13 @@ instantiate_decl (tree d, int defer_ok, nested = (current_function_decl != NULL_TREE); if (!fn_context) push_to_top_level (); - else if (nested) - push_function_context (); + else + { + if (nested) + push_function_context (); + cp_unevaluated_operand = 0; + c_inhibit_evaluation_warnings = 0; + } /* Mark D as instantiated so that recursive calls to instantiate_decl do not try to instantiate it again. */ @@ -19237,7 +19370,7 @@ instantiate_decl (tree d, int defer_ok, } for (; tmpl_parm; tmpl_parm = DECL_CHAIN (tmpl_parm)) { - if (!FUNCTION_PARAMETER_PACK_P (tmpl_parm)) + if (!DECL_PACK_P (tmpl_parm)) { register_local_specialization (spec_parm, tmpl_parm); spec_parm = DECL_CHAIN (spec_parm); @@ -19280,6 +19413,8 @@ instantiate_decl (tree d, int defer_ok, out: input_location = saved_loc; + cp_unevaluated_operand = saved_unevaluated_operand; + c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings; pop_deferring_access_checks (); pop_tinst_level (); @@ -20444,7 +20579,7 @@ bool any_type_dependent_elements_p (const_tree list) { for (; list; list = TREE_CHAIN (list)) - if (value_dependent_expression_p (TREE_VALUE (list))) + if (type_dependent_expression_p (TREE_VALUE (list))) return true; return false; @@ -20910,7 +21045,7 @@ static tree make_auto_1 (tree name) { tree au = cxx_make_type (TEMPLATE_TYPE_PARM); - TYPE_NAME (au) = build_decl (BUILTINS_LOCATION, + TYPE_NAME (au) = build_decl (input_location, TYPE_DECL, name, au); TYPE_STUB_DECL (au) = TYPE_NAME (au); TEMPLATE_TYPE_PARM_INDEX (au) = build_template_parm_index @@ -21096,31 +21231,35 @@ is_auto (const_tree type) return false; } -/* Returns true iff TYPE contains a use of 'auto'. Since auto can only - appear as a type-specifier for the declaration in question, we don't - have to look through the whole type. */ +/* Returns the TEMPLATE_TYPE_PARM in TYPE representing `auto' iff TYPE contains + a use of `auto'. Returns NULL_TREE otherwise. */ tree type_uses_auto (tree type) { - enum tree_code code; - if (is_auto (type)) - return type; + return find_type_usage (type, is_auto); +} - code = TREE_CODE (type); +/* Returns true iff TYPE is a TEMPLATE_TYPE_PARM representing 'auto', + 'decltype(auto)' or a concept. */ - if (code == POINTER_TYPE || code == REFERENCE_TYPE - || code == OFFSET_TYPE || code == FUNCTION_TYPE - || code == METHOD_TYPE || code == ARRAY_TYPE) - return type_uses_auto (TREE_TYPE (type)); +bool +is_auto_or_concept (const_tree type) +{ + return is_auto (type); // or concept +} - if (TYPE_PTRMEMFUNC_P (type)) - return type_uses_auto (TREE_TYPE (TREE_TYPE - (TYPE_PTRMEMFUNC_FN_TYPE (type)))); +/* Returns the TEMPLATE_TYPE_PARM in TYPE representing a generic type (`auto' or + a concept identifier) iff TYPE contains a use of a generic type. Returns + NULL_TREE otherwise. */ - return NULL_TREE; +tree +type_uses_auto_or_concept (tree type) +{ + return find_type_usage (type, is_auto_or_concept); } + /* For a given template T, return the vector of typedefs referenced in T for which access check is needed at T instantiation time. T is either a FUNCTION_DECL or a RECORD_TYPE. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 05c4c1cd15b..6145f986877 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1604,6 +1604,9 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) if (TREE_CODE (type) == REFERENCE_TYPE) /* Quals on the object don't matter. */; + else if (PACK_EXPANSION_P (type)) + /* Don't bother trying to represent this. */ + type = NULL_TREE; else { /* Set the cv qualifiers. */ @@ -2361,7 +2364,8 @@ finish_this_expr (void) was of the form `OBJECT.SCOPE::~DESTRUCTOR'. */ tree -finish_pseudo_destructor_expr (tree object, tree scope, tree destructor) +finish_pseudo_destructor_expr (tree object, tree scope, tree destructor, + location_t loc) { if (object == error_mark_node || destructor == error_mark_node) return error_mark_node; @@ -2372,15 +2376,16 @@ finish_pseudo_destructor_expr (tree object, tree scope, tree destructor) { if (scope == error_mark_node) { - error ("invalid qualifying scope in pseudo-destructor name"); + error_at (loc, "invalid qualifying scope in pseudo-destructor name"); return error_mark_node; } if (is_auto (destructor)) destructor = TREE_TYPE (object); if (scope && TYPE_P (scope) && !check_dtor_name (scope, destructor)) { - error ("qualified type %qT does not match destructor name ~%qT", - scope, destructor); + error_at (loc, + "qualified type %qT does not match destructor name ~%qT", + scope, destructor); return error_mark_node; } @@ -2401,12 +2406,13 @@ finish_pseudo_destructor_expr (tree object, tree scope, tree destructor) if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (object), destructor)) { - error ("%qE is not of type %qT", object, destructor); + error_at (loc, "%qE is not of type %qT", object, destructor); return error_mark_node; } } - return build3 (PSEUDO_DTOR_EXPR, void_type_node, object, scope, destructor); + return build3_loc (loc, PSEUDO_DTOR_EXPR, void_type_node, object, + scope, destructor); } /* Finish an expression of the form CODE EXPR. */ diff --git a/gcc/cp/type-utils.h b/gcc/cp/type-utils.h new file mode 100644 index 00000000000..3e82ca4f957 --- /dev/null +++ b/gcc/cp/type-utils.h @@ -0,0 +1,55 @@ +/* Utilities for querying and manipulating type trees. + Copyright (C) 2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_CP_TYPE_UTILS_H +#define GCC_CP_TYPE_UTILS_H + +/* Returns the first tree within T that is directly matched by PRED. T may be a + type or PARM_DECL and is incrementally decomposed toward its type-specifier + until a match is found. NULL_TREE is returned if PRED does not match any + part of T. + + This is primarily intended for detecting whether T uses `auto' or a concept + identifier. Since either of these can only appear as a type-specifier for + the declaration in question, only top-level qualifications are traversed; + find_type_usage does not look through the whole type. */ + +inline tree +find_type_usage (tree t, bool (*pred) (const_tree)) +{ + enum tree_code code; + if (pred (t)) + return t; + + code = TREE_CODE (t); + + if (code == POINTER_TYPE || code == REFERENCE_TYPE + || code == PARM_DECL || code == OFFSET_TYPE + || code == FUNCTION_TYPE || code == METHOD_TYPE + || code == ARRAY_TYPE) + return find_type_usage (TREE_TYPE (t), pred); + + if (TYPE_PTRMEMFUNC_P (t)) + return find_type_usage + (TREE_TYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (t))), pred); + + return NULL_TREE; +} + +#endif // GCC_CP_TYPE_UTILS_H diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index b4abbc56d5e..bcb87825a1e 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4554,7 +4554,8 @@ cp_build_binary_op (location_t location, vector_compare: tree intt; if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0), - TREE_TYPE (type1))) + TREE_TYPE (type1)) + && !vector_types_compatible_elements_p (type0, type1)) { if (complain & tf_error) { @@ -4670,8 +4671,7 @@ cp_build_binary_op (location_t location, if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE) { if (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1)) - || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0), - TREE_TYPE (type1))) + || !vector_types_compatible_elements_p (type0, type1)) { if (complain & tf_error) binary_op_error (location, code, type0, type1); @@ -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/cp/vtable-class-hierarchy.c b/gcc/cp/vtable-class-hierarchy.c index 4e336d6dbb5..38ea8beeb89 100644 --- a/gcc/cp/vtable-class-hierarchy.c +++ b/gcc/cp/vtable-class-hierarchy.c @@ -1179,15 +1179,16 @@ vtv_generate_init_routine (void) TREE_USED (vtv_fndecl) = 1; DECL_PRESERVE_P (vtv_fndecl) = 1; if (flag_vtable_verify == VTV_PREINIT_PRIORITY) - { - DECL_STATIC_CONSTRUCTOR (vtv_fndecl) = 0; - assemble_vtv_preinit_initializer (vtv_fndecl); - } + DECL_STATIC_CONSTRUCTOR (vtv_fndecl) = 0; gimplify_function_tree (vtv_fndecl); cgraph_add_new_function (vtv_fndecl, false); cgraph_process_new_functions (); + + if (flag_vtable_verify == VTV_PREINIT_PRIORITY) + assemble_vtv_preinit_initializer (vtv_fndecl); + } pop_lang_context (); } diff --git a/gcc/cse.c b/gcc/cse.c index b5c98baf378..57db5dc3141 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -1354,6 +1354,11 @@ try_const_anchors (rtx src_const, enum machine_mode mode) rtx lower_exp = NULL_RTX, upper_exp = NULL_RTX; unsigned lower_old, upper_old; + /* CONST_INT is used for CC modes, but we should leave those alone. */ + if (GET_MODE_CLASS (mode) == MODE_CC) + return NULL_RTX; + + gcc_assert (SCALAR_INT_MODE_P (mode)); if (!compute_const_anchors (src_const, &lower_base, &lower_offs, &upper_base, &upper_offs)) return NULL_RTX; diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index 87c002a498a..295bbb6e045 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -245,6 +245,9 @@ diagnostic_build_prefix (diagnostic_context *context, (s.file == NULL ? build_message_string ("%s%s:%s %s%s%s", locus_cs, progname, locus_ce, text_cs, text, text_ce) + : !strcmp (s.file, N_("<built-in>")) + ? build_message_string ("%s%s:%s %s%s%s", locus_cs, s.file, locus_ce, + text_cs, text, text_ce) : context->show_column ? build_message_string ("%s%s:%d:%d:%s %s%s%s", locus_cs, s.file, s.line, s.column, locus_ce, text_cs, text, text_ce) diff --git a/gcc/doc/contrib.texi b/gcc/doc/contrib.texi index 5577c04f011..9dd2c26287c 100644 --- a/gcc/doc/contrib.texi +++ b/gcc/doc/contrib.texi @@ -176,7 +176,7 @@ The @uref{http://www.gnu.org/software/classpath/,,GNU Classpath project} for all of their merged runtime code. @item -Nick Clifton for arm, mcore, fr30, v850, m32r, rx work, +Nick Clifton for arm, mcore, fr30, v850, m32r, msp430 rx work, @option{--help}, and other random hacking. @item @@ -218,7 +218,7 @@ Mo DeJong for GCJ and libgcj bug fixes. @item DJ Delorie for the DJGPP port, build and libiberty maintenance, -various bug fixes, and the M32C, MeP, and RL78 ports. +various bug fixes, and the M32C, MeP, MSP430, and RL78 ports. @item Arnaud Desitter for helping to debug GNU Fortran. diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 151b7e9d56a..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:: @@ -10204,8 +10242,7 @@ void __builtin_ia32_mwait (unsigned int, unsigned int) @end smallexample The following built-in functions are available when @option{-mssse3} is used. -All of them generate the machine instruction that is part of the name -with MMX registers. +All of them generate the machine instruction that is part of the name. @smallexample v2si __builtin_ia32_phaddd (v2si, v2si) @@ -10227,8 +10264,7 @@ v4hi __builtin_ia32_pabsw (v4hi) @end smallexample The following built-in functions are available when @option{-mssse3} is used. -All of them generate the machine instruction that is part of the name -with SSE registers. +All of them generate the machine instruction that is part of the name. @smallexample v4si __builtin_ia32_phaddd128 (v4si, v4si) @@ -10876,42 +10912,41 @@ v8hi __builtin_ia32_vpshlw (v8hi, v8hi) @end smallexample The following built-in functions are available when @option{-mfma4} is used. -All of them generate the machine instruction that is part of the name -with MMX registers. - -@smallexample -v2df __builtin_ia32_fmaddpd (v2df, v2df, v2df) -v4sf __builtin_ia32_fmaddps (v4sf, v4sf, v4sf) -v2df __builtin_ia32_fmaddsd (v2df, v2df, v2df) -v4sf __builtin_ia32_fmaddss (v4sf, v4sf, v4sf) -v2df __builtin_ia32_fmsubpd (v2df, v2df, v2df) -v4sf __builtin_ia32_fmsubps (v4sf, v4sf, v4sf) -v2df __builtin_ia32_fmsubsd (v2df, v2df, v2df) -v4sf __builtin_ia32_fmsubss (v4sf, v4sf, v4sf) -v2df __builtin_ia32_fnmaddpd (v2df, v2df, v2df) -v4sf __builtin_ia32_fnmaddps (v4sf, v4sf, v4sf) -v2df __builtin_ia32_fnmaddsd (v2df, v2df, v2df) -v4sf __builtin_ia32_fnmaddss (v4sf, v4sf, v4sf) -v2df __builtin_ia32_fnmsubpd (v2df, v2df, v2df) -v4sf __builtin_ia32_fnmsubps (v4sf, v4sf, v4sf) -v2df __builtin_ia32_fnmsubsd (v2df, v2df, v2df) -v4sf __builtin_ia32_fnmsubss (v4sf, v4sf, v4sf) -v2df __builtin_ia32_fmaddsubpd (v2df, v2df, v2df) -v4sf __builtin_ia32_fmaddsubps (v4sf, v4sf, v4sf) -v2df __builtin_ia32_fmsubaddpd (v2df, v2df, v2df) -v4sf __builtin_ia32_fmsubaddps (v4sf, v4sf, v4sf) -v4df __builtin_ia32_fmaddpd256 (v4df, v4df, v4df) -v8sf __builtin_ia32_fmaddps256 (v8sf, v8sf, v8sf) -v4df __builtin_ia32_fmsubpd256 (v4df, v4df, v4df) -v8sf __builtin_ia32_fmsubps256 (v8sf, v8sf, v8sf) -v4df __builtin_ia32_fnmaddpd256 (v4df, v4df, v4df) -v8sf __builtin_ia32_fnmaddps256 (v8sf, v8sf, v8sf) -v4df __builtin_ia32_fnmsubpd256 (v4df, v4df, v4df) -v8sf __builtin_ia32_fnmsubps256 (v8sf, v8sf, v8sf) -v4df __builtin_ia32_fmaddsubpd256 (v4df, v4df, v4df) -v8sf __builtin_ia32_fmaddsubps256 (v8sf, v8sf, v8sf) -v4df __builtin_ia32_fmsubaddpd256 (v4df, v4df, v4df) -v8sf __builtin_ia32_fmsubaddps256 (v8sf, v8sf, v8sf) +All of them generate the machine instruction that is part of the name. + +@smallexample +v2df __builtin_ia32_vfmaddpd (v2df, v2df, v2df) +v4sf __builtin_ia32_vfmaddps (v4sf, v4sf, v4sf) +v2df __builtin_ia32_vfmaddsd (v2df, v2df, v2df) +v4sf __builtin_ia32_vfmaddss (v4sf, v4sf, v4sf) +v2df __builtin_ia32_vfmsubpd (v2df, v2df, v2df) +v4sf __builtin_ia32_vfmsubps (v4sf, v4sf, v4sf) +v2df __builtin_ia32_vfmsubsd (v2df, v2df, v2df) +v4sf __builtin_ia32_vfmsubss (v4sf, v4sf, v4sf) +v2df __builtin_ia32_vfnmaddpd (v2df, v2df, v2df) +v4sf __builtin_ia32_vfnmaddps (v4sf, v4sf, v4sf) +v2df __builtin_ia32_vfnmaddsd (v2df, v2df, v2df) +v4sf __builtin_ia32_vfnmaddss (v4sf, v4sf, v4sf) +v2df __builtin_ia32_vfnmsubpd (v2df, v2df, v2df) +v4sf __builtin_ia32_vfnmsubps (v4sf, v4sf, v4sf) +v2df __builtin_ia32_vfnmsubsd (v2df, v2df, v2df) +v4sf __builtin_ia32_vfnmsubss (v4sf, v4sf, v4sf) +v2df __builtin_ia32_vfmaddsubpd (v2df, v2df, v2df) +v4sf __builtin_ia32_vfmaddsubps (v4sf, v4sf, v4sf) +v2df __builtin_ia32_vfmsubaddpd (v2df, v2df, v2df) +v4sf __builtin_ia32_vfmsubaddps (v4sf, v4sf, v4sf) +v4df __builtin_ia32_vfmaddpd256 (v4df, v4df, v4df) +v8sf __builtin_ia32_vfmaddps256 (v8sf, v8sf, v8sf) +v4df __builtin_ia32_vfmsubpd256 (v4df, v4df, v4df) +v8sf __builtin_ia32_vfmsubps256 (v8sf, v8sf, v8sf) +v4df __builtin_ia32_vfnmaddpd256 (v4df, v4df, v4df) +v8sf __builtin_ia32_vfnmaddps256 (v8sf, v8sf, v8sf) +v4df __builtin_ia32_vfnmsubpd256 (v4df, v4df, v4df) +v8sf __builtin_ia32_vfnmsubps256 (v8sf, v8sf, v8sf) +v4df __builtin_ia32_vfmaddsubpd256 (v4df, v4df, v4df) +v8sf __builtin_ia32_vfmaddsubps256 (v8sf, v8sf, v8sf) +v4df __builtin_ia32_vfmsubaddpd256 (v4df, v4df, v4df) +v8sf __builtin_ia32_vfmsubaddps256 (v8sf, v8sf, v8sf) @end smallexample @@ -10958,6 +10993,31 @@ unsigned int __builtin_ia32_lzcnt_u32(unsigned int); unsigned long long __builtin_ia32_lzcnt_u64 (unsigned long long); @end smallexample +The following built-in functions are available when @option{-mfxsr} is used. +All of them generate the machine instruction that is part of the name. +@smallexample +void __builtin_ia32_fxsave (void *) +void __builtin_ia32_fxrstor (void *) +void __builtin_ia32_fxsave64 (void *) +void __builtin_ia32_fxrstor64 (void *) +@end smallexample + +The following built-in functions are available when @option{-mxsave} is used. +All of them generate the machine instruction that is part of the name. +@smallexample +void __builtin_ia32_xsave (void *, long long) +void __builtin_ia32_xrstor (void *, long long) +void __builtin_ia32_xsave64 (void *, long long) +void __builtin_ia32_xrstor64 (void *, long long) +@end smallexample + +The following built-in functions are available when @option{-mxsaveopt} is used. +All of them generate the machine instruction that is part of the name. +@smallexample +void __builtin_ia32_xsaveopt (void *, long long) +void __builtin_ia32_xsaveopt64 (void *, long long) +@end smallexample + The following built-in functions are available when @option{-mtbm} is used. Both of them generate the immediate form of the bextr machine instruction. @smallexample @@ -11831,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/install.texi b/gcc/doc/install.texi index 221e60e952c..0011b68065b 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -1036,6 +1036,18 @@ and for cross builds configured with @option{--with-sysroot}, and without More documentation about multiarch can be found at @uref{http://wiki.debian.org/Multiarch}. +@item --enable-vtable-verify +Specify whether to enable or disable the vtable verification feature. +Enabling this feature causes libstdc++ to be built with its virtual calls +in verifiable mode. This means that, when linked with libvtv, every +virtual call in libstdc++ will verify the vtable pointer through which the +call will be made before actually making the call. If not linked with libvtv, +the verifier will call stub functions (in libstdc++ itself) and do nothing. +If vtable verification is disabled, then libstdc++ is not built with its +virtual calls in verifiable mode at all. However the libvtv library will +still be built (see @option{--disable-libvtv} to turn off building libvtv). +@option{--disable-vtable-verify} is the default. + @item --disable-multilib Specify that multiple target libraries to support different target variants, calling @@ -1422,6 +1434,10 @@ support for @code{libquadmath} on systems supporting it. @item --disable-libgomp Specify that the run-time libraries used by GOMP should not be built. +@item --disable-libvtv +Specify that the run-time libraries used by vtable verification +should not be built. + @item --with-dwarf2 Specify that the compiler should use DWARF 2 debugging information as the default. @@ -3976,6 +3992,13 @@ The moxie processor. @html <hr /> @end html +@heading @anchor{msp430-x-elf}msp430-*-elf +TI MSP430 processor. +This configuration is intended for embedded systems. + +@html +<hr /> +@end html @heading @anchor{powerpc-x-x}powerpc-*-* You can specify a default version for the @option{-mcpu=@var{cpu_type}} diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 9dfb4d79019..aa0f4ed08b7 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -240,8 +240,8 @@ Objective-C and Objective-C++ Dialects}. -Wno-attributes -Wno-builtin-macro-redefined @gol -Wc++-compat -Wc++11-compat -Wcast-align -Wcast-qual @gol -Wchar-subscripts -Wclobbered -Wcomment -Wconditionally-supported @gol --Wconversion -Wcoverage-mismatch -Wno-cpp -Wno-deprecated @gol --Wno-deprecated-declarations -Wdisabled-optimization @gol +-Wconversion -Wcoverage-mismatch -Wdelete-incomplete -Wno-cpp @gol +-Wno-deprecated -Wno-deprecated-declarations -Wdisabled-optimization @gol -Wno-div-by-zero -Wdouble-promotion -Wempty-body -Wenum-compare @gol -Wno-endif-labels -Werror -Werror=* @gol -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol @@ -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 @@ -651,10 +652,10 @@ Objective-C and Objective-C++ Dialects}. -mavx2 -mavx512f -mavx512pf -mavx512er -mavx512cd @gol -maes -mpclmul -mfsgsbase -mrdrnd -mf16c -mfma @gol -msse4a -m3dnow -mpopcnt -mabm -mbmi -mtbm -mfma4 -mxop -mlzcnt @gol --mbmi2 -mrtm -mlwp -mthreads @gol +-mbmi2 -mfxsr -mxsave -mxsaveopt -mrtm -mlwp -mthreads @gol -mno-align-stringops -minline-all-stringops @gol -minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol --mmemcpy-strategy=@var{strategy} -mmemset-strategy=@var{strategy} +-mmemcpy-strategy=@var{strategy} -mmemset-strategy=@var{strategy} -mpush-args -maccumulate-outgoing-args -m128bit-long-double @gol -m96bit-long-double -mlong-double-64 -mlong-double-80 @gol -mregparm=@var{num} -msseregparm @gol @@ -804,6 +805,9 @@ Objective-C and Objective-C++ Dialects}. @emph{Moxie Options} @gccoptlist{-meb -mel -mno-crt0} +@emph{MSP430 Options} +@gccoptlist{-msim -masm-hex -mmcu= -mlarge -msmall -mrelax} + @emph{PDP-11 Options} @gccoptlist{-mfpu -msoft-float -mac0 -mno-ac0 -m40 -m45 -m10 @gol -mbcopy -mbcopy-builtin -mint32 -mno-int16 @gol @@ -1856,6 +1860,8 @@ Some cases of unnamed fields in structures and unions are only accepted with this option. @xref{Unnamed Fields,,Unnamed struct/union fields within structs/unions}, for details. +Note that this option is off for all targets but i?86 and x86_64 +targets using ms-abi. @item -fplan9-extensions Accept some non-standard constructs used in Plan 9 code. @@ -4490,6 +4496,12 @@ types. @option{-Wconversion-null} is enabled by default. Warn when a literal '0' is used as null pointer constant. This can be useful to facilitate the conversion to @code{nullptr} in C++11. +@item -Wdelete-incomplete @r{(C++ and Objective-C++ only)} +@opindex Wdelete-incomplete +@opindex Wno-delete-incomplete +Warn when deleting a pointer to incomplete type, which may cause +undefined behavior at runtime. This warning is enabled by default. + @item -Wuseless-cast @r{(C++ and Objective-C++ only)} @opindex Wuseless-cast @opindex Wno-useless-cast @@ -6740,8 +6752,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 @@ -8000,8 +8012,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 @@ -11028,6 +11045,7 @@ platform. * MMIX Options:: * MN10300 Options:: * Moxie Options:: +* MSP430 Options:: * PDP-11 Options:: * picoChip Options:: * PowerPC Options:: @@ -11173,6 +11191,8 @@ Feature modifiers used with @option{-march} and @option{-mcpu} can be one the following: @table @samp +@item crc +Enable CRC extension. @item crypto Enable Crypto extension. This implies Advanced SIMD is enabled. @item fp @@ -14441,6 +14461,9 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. @itemx -mno-bmi2 @itemx -mlzcnt @itemx -mno-lzcnt +@itemx -mfxsr +@itemx -mxsave +@itemx -mxsaveopt @itemx -mrtm @itemx -mtbm @itemx -mno-tbm @@ -14453,7 +14476,7 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. These switches enable or disable the use of instructions in the MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, AVX, AVX2, AVX512F, AVX512PF, AVX512ER, AVX512CD, AES, PCLMUL, FSGSBASE, RDRND, F16C, FMA, SSE4A, FMA4, XOP, LWP, ABM, BMI, BMI2, -LZCNT, RTM or 3DNow!@: +FXSR, XSAVE, XSAVEOPT, LZCNT, RTM or 3DNow!@: extended instruction sets. These extensions are also available as built-in functions: see @ref{X86 Built-in Functions}, for details of the functions enabled and @@ -16013,7 +16036,7 @@ Link the SDRAM-based runtime instead of the default ROM-based runtime. @item -msim @opindex msim -Link the simulator runtime libraries. +Link the simulator run-time libraries. @item -msimnovec @opindex msimnovec @@ -17277,6 +17300,46 @@ Do not link in the C run-time initialization object file. @end table +@node MSP430 Options +@subsection MSP430 Options +@cindex MSP430 Options + +These options are defined for the MSP430: + +@table @gcctabopt + +@item -msim +@opindex msim +Link the simulator runtime libraries. + +@item -masm-hex +@opindex masm-hex +Force assembly output to always use hex constants. Normally such +constants are signed decimals, but this option is available for +testsuite and/or aesthetic purposes. + +@item -mmcu= +@opindex mmcu= +Select the MCU to target. Note that there are two ``generic'' MCUs, +@code{msp430} and @code{msp430x}, which should be used most of the +time. This option is also passed to the assembler. + +@item -mlarge +@opindex mlarge +Use large-model addressing (20-bit pointers, 32-bit @code{size_t}). + +@item -msmall +@opindex msmall +Use small-model addressing (16-bit pointers, 16-bit @code{size_t}). + +@item -mrelax +@opindex mrelax +This option is passed to the assembler and linker, and allows the +linker to perform certain optimizations that cannot be done until +the final link. + +@end table + @node PDP-11 Options @subsection PDP-11 Options @cindex PDP-11 Options diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index c6664fa8e39..57760469d33 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -3063,6 +3063,35 @@ A constant in the range of 0 to @minus{}255. @end table +@item MSP430--@file{config/msp430/constraints.md} +@table @code + +@item R12 +Register R12. + +@item R13 +Register R13. + +@item K +Integer constant 1. + +@item L +Integer constant -1^20..1^19. + +@item M +Integer constant 1-4. + +@item Ya +Memory references which do not require an extended MOVX instruction. + +@item Yl +Memory reference, labels only. + +@item Ys +Memory reference, stack only. + +@end table + @item PDP-11---@file{config/pdp11/constraints.md} @table @code @item a @@ -9651,7 +9680,7 @@ Here's an example of int iterators in action, taken from the ARM port: QABSNEG))] "TARGET_NEON" "vq<absneg>.<V_s_elem>\t%<V_reg>0, %<V_reg>1" - [(set_attr "neon_type" "neon_vqneg_vqabs")] + [(set_attr "type" "neon_vqneg_vqabs")] ) @end smallexample @@ -9666,7 +9695,7 @@ This is equivalent to: UNSPEC_VQABS))] "TARGET_NEON" "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1" - [(set_attr "neon_type" "neon_vqneg_vqabs")] + [(set_attr "type" "neon_vqneg_vqabs")] ) (define_insn "neon_vqneg<mode>" @@ -9676,7 +9705,7 @@ This is equivalent to: UNSPEC_VQNEG))] "TARGET_NEON" "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1" - [(set_attr "neon_type" "neon_vqneg_vqabs")] + [(set_attr "type" "neon_vqneg_vqabs")] ) @end smallexample diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 54d52829b35..58187c4e532 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 @@ -10645,6 +10635,10 @@ Define this hook to return the name of a header file to be included at the start This hook can be used together with a header provided by the system C library to implement ISO C requirements for certain macros to be predefined that describe properties of the whole implementation rather than just the compiler. @end deftypefn +@deftypefn {C Target Hook} bool TARGET_CXX_IMPLICIT_EXTERN_C (const char*@var{}) +Define this hook to add target-specific C++ implicit extern C functions. If this function returns true for the name of a file-scope function, that function implicitly gets extern "C" linkage rather than whatever language linkage the declaration would normally have. An example of such function is WinMain on Win32 targets. +@end deftypefn + @defmac NO_IMPLICIT_EXTERN_C Define this macro if the system header files support C++ as well as C@. This macro inhibits the usual method of using system header files in diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 079af1dabf1..368afd6b1e7 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 @@ -7979,6 +7969,8 @@ files @code{__STDC__} will always expand to 1. @hook TARGET_C_PREINCLUDE +@hook TARGET_CXX_IMPLICIT_EXTERN_C + @defmac NO_IMPLICIT_EXTERN_C Define this macro if the system header files support C++ as well as C@. This macro inhibits the usual method of using system header files in 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/dse.c b/gcc/dse.c index 8b132eb2c91..d0e99db3dbd 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -46,7 +46,7 @@ along with GCC; see the file COPYING3. If not see #include "dbgcnt.h" #include "target.h" #include "params.h" -#include "tree-flow.h" /* for may_be_aliased */ +#include "tree-ssa.h" /* for may_be_aliased */ /* This file contains three techniques for performing Dead Store Elimination (dse). 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/dwarf2cfi.c b/gcc/dwarf2cfi.c index ee8d42c9b28..12256bcec39 100644 --- a/gcc/dwarf2cfi.c +++ b/gcc/dwarf2cfi.c @@ -246,7 +246,8 @@ init_return_column_size (enum machine_mode mode, rtx mem, unsigned int c) { HOST_WIDE_INT offset = c * GET_MODE_SIZE (mode); HOST_WIDE_INT size = GET_MODE_SIZE (Pmode); - emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size)); + emit_move_insn (adjust_address (mem, mode, offset), + gen_int_mode (size, mode)); } /* Generate code to initialize the register size table. */ diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 5c564c31b6b..619fd868c98 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -376,11 +376,15 @@ should_emit_struct_debug (tree type, enum debug_info_usage usage) type_decl = TYPE_STUB_DECL (TYPE_MAIN_VARIANT (type)); - if (criterion == DINFO_STRUCT_FILE_SYS && DECL_IN_SYSTEM_HEADER (type_decl)) - return DUMP_GSTRUCT (type, usage, criterion, generic, false, true); + if (type_decl != NULL) + { + if (criterion == DINFO_STRUCT_FILE_SYS && DECL_IN_SYSTEM_HEADER (type_decl)) + return DUMP_GSTRUCT (type, usage, criterion, generic, false, true); + + if (matches_main_base (DECL_SOURCE_FILE (type_decl))) + return DUMP_GSTRUCT (type, usage, criterion, generic, true, true); + } - if (matches_main_base (DECL_SOURCE_FILE (type_decl))) - return DUMP_GSTRUCT (type, usage, criterion, generic, true, true); return DUMP_GSTRUCT (type, usage, criterion, generic, false, false); } @@ -12517,9 +12521,10 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode, /* Turn these into a PLUS expression and fall into the PLUS code below. */ rtl = gen_rtx_PLUS (mode, XEXP (rtl, 0), - GEN_INT (GET_CODE (rtl) == PRE_INC - ? GET_MODE_UNIT_SIZE (mem_mode) - : -GET_MODE_UNIT_SIZE (mem_mode))); + gen_int_mode (GET_CODE (rtl) == PRE_INC + ? GET_MODE_UNIT_SIZE (mem_mode) + : -GET_MODE_UNIT_SIZE (mem_mode), + mode)); /* ... fall through ... */ diff --git a/gcc/except.c b/gcc/except.c index c1d33c647aa..a7be1f28029 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -139,7 +139,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic.h" #include "tree-pretty-print.h" #include "tree-pass.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" /* Provide defaults for stuff that may not be defined when using @@ -1156,7 +1156,7 @@ sjlj_mark_call_sites (void) start_sequence (); mem = adjust_address (crtl->eh.sjlj_fc, TYPE_MODE (integer_type_node), sjlj_fc_call_site_ofs); - emit_move_insn (mem, GEN_INT (this_call_site)); + emit_move_insn (mem, gen_int_mode (this_call_site, GET_MODE (mem))); p = get_insns (); end_sequence (); diff --git a/gcc/explow.c b/gcc/explow.c index a893c07ff01..360e541d973 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -157,7 +157,7 @@ plus_constant (enum machine_mode mode, rtx x, HOST_WIDE_INT c) } if (c != 0) - x = gen_rtx_PLUS (mode, x, GEN_INT (c)); + x = gen_rtx_PLUS (mode, x, gen_int_mode (c, mode)); if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF) return x; @@ -1326,7 +1326,8 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align, else { ask = expand_binop (Pmode, add_optab, size, - GEN_INT (required_align / BITS_PER_UNIT - 1), + gen_int_mode (required_align / BITS_PER_UNIT - 1, + Pmode), NULL_RTX, 1, OPTAB_LIB_WIDEN); must_align = true; } @@ -1452,13 +1453,16 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align, but we know it can't. So add ourselves and then do TRUNC_DIV_EXPR. */ target = expand_binop (Pmode, add_optab, target, - GEN_INT (required_align / BITS_PER_UNIT - 1), + gen_int_mode (required_align / BITS_PER_UNIT - 1, + Pmode), NULL_RTX, 1, OPTAB_LIB_WIDEN); target = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, target, - GEN_INT (required_align / BITS_PER_UNIT), + gen_int_mode (required_align / BITS_PER_UNIT, + Pmode), NULL_RTX, 1); target = expand_mult (Pmode, target, - GEN_INT (required_align / BITS_PER_UNIT), + gen_int_mode (required_align / BITS_PER_UNIT, + Pmode), NULL_RTX, 1); } @@ -1603,7 +1607,8 @@ probe_stack_range (HOST_WIDE_INT first, rtx size) /* ROUNDED_SIZE = SIZE & -PROBE_INTERVAL */ rounded_size - = simplify_gen_binary (AND, Pmode, size, GEN_INT (-PROBE_INTERVAL)); + = simplify_gen_binary (AND, Pmode, size, + gen_int_mode (-PROBE_INTERVAL, Pmode)); rounded_size_op = force_operand (rounded_size, NULL_RTX); @@ -1612,7 +1617,8 @@ probe_stack_range (HOST_WIDE_INT first, rtx size) /* TEST_ADDR = SP + FIRST. */ test_addr = force_operand (gen_rtx_fmt_ee (STACK_GROW_OP, Pmode, stack_pointer_rtx, - GEN_INT (first)), NULL_RTX); + gen_int_mode (first, Pmode)), + NULL_RTX); /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */ last_addr = force_operand (gen_rtx_fmt_ee (STACK_GROW_OP, Pmode, @@ -1639,7 +1645,7 @@ probe_stack_range (HOST_WIDE_INT first, rtx size) /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */ temp = expand_binop (Pmode, STACK_GROW_OPTAB, test_addr, - GEN_INT (PROBE_INTERVAL), test_addr, + gen_int_mode (PROBE_INTERVAL, Pmode), test_addr, 1, OPTAB_WIDEN); gcc_assert (temp == test_addr); @@ -1746,7 +1752,8 @@ anti_adjust_stack_and_probe (rtx size, bool adjust_back) /* ROUNDED_SIZE = SIZE & -PROBE_INTERVAL */ rounded_size - = simplify_gen_binary (AND, Pmode, size, GEN_INT (-PROBE_INTERVAL)); + = simplify_gen_binary (AND, Pmode, size, + gen_int_mode (-PROBE_INTERVAL, Pmode)); rounded_size_op = force_operand (rounded_size, NULL_RTX); diff --git a/gcc/expmed.c b/gcc/expmed.c index d42341c6536..b504a4e2f9f 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -55,7 +55,7 @@ static void store_split_bit_field (rtx, unsigned HOST_WIDE_INT, static rtx extract_fixed_bit_field (enum machine_mode, rtx, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, rtx, int, bool); -static rtx lshift_value (enum machine_mode, rtx, int, int); +static rtx lshift_value (enum machine_mode, unsigned HOST_WIDE_INT, int); static rtx extract_split_bit_field (rtx, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, int); static void do_cmp_and_jump (rtx, rtx, enum rtx_code, enum machine_mode, rtx); @@ -1003,7 +1003,7 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize, || (bitsize == HOST_BITS_PER_WIDE_INT && v == -1)) all_one = 1; - value = lshift_value (mode, value, bitnum, bitsize); + value = lshift_value (mode, v, bitnum); } else { @@ -1852,15 +1852,17 @@ extract_fixed_bit_field (enum machine_mode tmode, rtx op0, return expand_shift (RSHIFT_EXPR, mode, op0, GET_MODE_BITSIZE (mode) - bitsize, target, 0); } -/* Return a constant integer rtx with the value VALUE truncated to - BITSIZE bits and then shifted left BITPOS bits. */ + +/* Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value + VALUE << BITPOS. */ static rtx -lshift_value (enum machine_mode mode, rtx value, int bitpos, int bitsize) +lshift_value (enum machine_mode mode, unsigned HOST_WIDE_INT value, + int bitpos) { return - immed_wide_int_const (wi::lshift (wi::zext (std::make_pair (value, mode), - bitsize), bitpos), mode); + immed_wide_int_const (wi::lshift (max_wide_int (value), + bitpos), mode); } /* Extract a bit field that is split across two words @@ -2202,11 +2204,10 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted, other_amount = simplify_gen_unary (NEG, GET_MODE (op1), op1, GET_MODE (op1)); + HOST_WIDE_INT mask = GET_MODE_PRECISION (mode) - 1; other_amount - = simplify_gen_binary (AND, GET_MODE (op1), - other_amount, - GEN_INT (GET_MODE_PRECISION (mode) - - 1)); + = simplify_gen_binary (AND, GET_MODE (op1), other_amount, + gen_int_mode (mask, GET_MODE (op1))); } shifted = force_reg (mode, shifted); @@ -2994,7 +2995,8 @@ expand_mult_const (enum machine_mode mode, rtx op0, HOST_WIDE_INT val, insn = get_last_insn (); set_dst_reg_note (insn, REG_EQUAL, - gen_rtx_MULT (nmode, tem, GEN_INT (val_so_far)), + gen_rtx_MULT (nmode, tem, + gen_int_mode (val_so_far, nmode)), accum_inner); } } @@ -3649,7 +3651,8 @@ expand_smod_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d) NULL_RTX, 1, OPTAB_LIB_WIDEN); temp = expand_binop (mode, sub_optab, temp, signmask, NULL_RTX, 1, OPTAB_LIB_WIDEN); - temp = expand_binop (mode, and_optab, temp, GEN_INT (masklow), + temp = expand_binop (mode, and_optab, temp, + gen_int_mode (masklow, mode), NULL_RTX, 1, OPTAB_LIB_WIDEN); temp = expand_binop (mode, xor_optab, temp, signmask, NULL_RTX, 1, OPTAB_LIB_WIDEN); @@ -3664,7 +3667,8 @@ expand_smod_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d) temp = expand_binop (mode, add_optab, op0, signmask, NULL_RTX, 1, OPTAB_LIB_WIDEN); - temp = expand_binop (mode, and_optab, temp, GEN_INT (masklow), + temp = expand_binop (mode, and_optab, temp, + gen_int_mode (masklow, mode), NULL_RTX, 1, OPTAB_LIB_WIDEN); temp = expand_binop (mode, sub_optab, temp, signmask, NULL_RTX, 1, OPTAB_LIB_WIDEN); @@ -3739,7 +3743,7 @@ expand_sdiv_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d) start_sequence (); temp2 = copy_to_mode_reg (mode, op0); - temp = expand_binop (mode, add_optab, temp2, GEN_INT (d-1), + temp = expand_binop (mode, add_optab, temp2, gen_int_mode (d - 1, mode), NULL_RTX, 0, OPTAB_LIB_WIDEN); temp = force_reg (mode, temp); @@ -3766,7 +3770,7 @@ expand_sdiv_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d) temp = emit_store_flag (temp, LT, op0, const0_rtx, mode, 0, -1); if (shift_cost (optimize_insn_for_speed_p (), mode, ushift) > COSTS_N_INSNS (1)) - temp = expand_binop (mode, and_optab, temp, GEN_INT (d - 1), + temp = expand_binop (mode, and_optab, temp, gen_int_mode (d - 1, mode), NULL_RTX, 0, OPTAB_LIB_WIDEN); else temp = expand_shift (RSHIFT_EXPR, mode, temp, @@ -3779,7 +3783,7 @@ expand_sdiv_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d) label = gen_label_rtx (); temp = copy_to_mode_reg (mode, op0); do_cmp_and_jump (temp, const0_rtx, GE, mode, label); - expand_inc (temp, GEN_INT (d - 1)); + expand_inc (temp, gen_int_mode (d - 1, mode)); emit_label (label); return expand_shift (RSHIFT_EXPR, mode, temp, logd, NULL_RTX, 0); } @@ -4037,9 +4041,11 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, pre_shift = floor_log2 (d); if (rem_flag) { + unsigned HOST_WIDE_INT mask + = ((unsigned HOST_WIDE_INT) 1 << pre_shift) - 1; remainder = expand_binop (compute_mode, and_optab, op0, - GEN_INT (((HOST_WIDE_INT) 1 << pre_shift) - 1), + gen_int_mode (mask, compute_mode), remainder, 1, OPTAB_LIB_WIDEN); if (remainder) @@ -4090,10 +4096,10 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, = (shift_cost (speed, compute_mode, post_shift - 1) + shift_cost (speed, compute_mode, 1) + 2 * add_cost (speed, compute_mode)); - t1 = expmed_mult_highpart (compute_mode, op0, - GEN_INT (ml), - NULL_RTX, 1, - max_cost - extra_cost); + t1 = expmed_mult_highpart + (compute_mode, op0, + gen_int_mode (ml, compute_mode), + NULL_RTX, 1, max_cost - extra_cost); if (t1 == 0) goto fail1; t2 = force_operand (gen_rtx_MINUS (compute_mode, @@ -4122,10 +4128,10 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, extra_cost = (shift_cost (speed, compute_mode, pre_shift) + shift_cost (speed, compute_mode, post_shift)); - t2 = expmed_mult_highpart (compute_mode, t1, - GEN_INT (ml), - NULL_RTX, 1, - max_cost - extra_cost); + t2 = expmed_mult_highpart + (compute_mode, t1, + gen_int_mode (ml, compute_mode), + NULL_RTX, 1, max_cost - extra_cost); if (t2 == 0) goto fail1; quotient = expand_shift @@ -4249,9 +4255,9 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, extra_cost = (shift_cost (speed, compute_mode, post_shift) + shift_cost (speed, compute_mode, size - 1) + add_cost (speed, compute_mode)); - t1 = expmed_mult_highpart (compute_mode, op0, - GEN_INT (ml), NULL_RTX, 0, - max_cost - extra_cost); + t1 = expmed_mult_highpart + (compute_mode, op0, gen_int_mode (ml, compute_mode), + NULL_RTX, 0, max_cost - extra_cost); if (t1 == 0) goto fail1; t2 = expand_shift @@ -4343,9 +4349,12 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, pre_shift = floor_log2 (d); if (rem_flag) { - remainder = expand_binop (compute_mode, and_optab, op0, - GEN_INT (((HOST_WIDE_INT) 1 << pre_shift) - 1), - remainder, 0, OPTAB_LIB_WIDEN); + unsigned HOST_WIDE_INT mask + = ((unsigned HOST_WIDE_INT) 1 << pre_shift) - 1; + remainder = expand_binop + (compute_mode, and_optab, op0, + gen_int_mode (mask, compute_mode), + remainder, 0, OPTAB_LIB_WIDEN); if (remainder) return gen_lowpart (mode, remainder); } @@ -4372,9 +4381,9 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, extra_cost = (shift_cost (speed, compute_mode, post_shift) + shift_cost (speed, compute_mode, size - 1) + 2 * add_cost (speed, compute_mode)); - t3 = expmed_mult_highpart (compute_mode, t2, - GEN_INT (ml), NULL_RTX, 1, - max_cost - extra_cost); + t3 = expmed_mult_highpart + (compute_mode, t2, gen_int_mode (ml, compute_mode), + NULL_RTX, 1, max_cost - extra_cost); if (t3 != 0) { t4 = expand_shift @@ -4512,7 +4521,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0, floor_log2 (d), tquotient, 1); t2 = expand_binop (compute_mode, and_optab, op0, - GEN_INT (d - 1), + gen_int_mode (d - 1, compute_mode), NULL_RTX, 1, OPTAB_LIB_WIDEN); t3 = gen_reg_rtx (compute_mode); t3 = emit_store_flag (t3, NE, t2, const0_rtx, @@ -4609,7 +4618,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0, floor_log2 (d), tquotient, 0); t2 = expand_binop (compute_mode, and_optab, op0, - GEN_INT (d - 1), + gen_int_mode (d - 1, compute_mode), NULL_RTX, 1, OPTAB_LIB_WIDEN); t3 = gen_reg_rtx (compute_mode); t3 = emit_store_flag (t3, NE, t2, const0_rtx, @@ -5443,7 +5452,7 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1, STORE_FLAG_VALUE, target_mode); if (tem) return expand_binop (target_mode, add_optab, tem, - GEN_INT (normalizep), + gen_int_mode (normalizep, target_mode), target, 0, OPTAB_WIDEN); } else if (!want_add @@ -5547,7 +5556,8 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1, STORE_FLAG_VALUE, target_mode); if (tem != 0) tem = expand_binop (target_mode, add_optab, tem, - GEN_INT (normalizep), target, 0, OPTAB_WIDEN); + gen_int_mode (normalizep, target_mode), + target, 0, OPTAB_WIDEN); } else if (!want_add && rtx_cost (trueval, XOR, 1, diff --git a/gcc/expr.c b/gcc/expr.c index 634a166848f..a8eb57f6e9d 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -43,7 +43,7 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" #include "tm_p.h" #include "tree-iterator.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "target.h" #include "common/common-target.h" #include "timevar.h" @@ -1041,10 +1041,12 @@ move_by_pieces_1 (insn_gen_fn genfun, machine_mode mode, if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0) emit_insn (gen_add2_insn (data->to_addr, - GEN_INT (-(HOST_WIDE_INT)size))); + gen_int_mode (-(HOST_WIDE_INT) size, + GET_MODE (data->to_addr)))); if (HAVE_PRE_DECREMENT && data->explicit_inc_from < 0) emit_insn (gen_add2_insn (data->from_addr, - GEN_INT (-(HOST_WIDE_INT)size))); + gen_int_mode (-(HOST_WIDE_INT) size, + GET_MODE (data->from_addr)))); if (data->to) emit_insn ((*genfun) (to1, from1)); @@ -1058,9 +1060,13 @@ move_by_pieces_1 (insn_gen_fn genfun, machine_mode mode, } if (HAVE_POST_INCREMENT && data->explicit_inc_to > 0) - emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size))); + emit_insn (gen_add2_insn (data->to_addr, + gen_int_mode (size, + GET_MODE (data->to_addr)))); if (HAVE_POST_INCREMENT && data->explicit_inc_from > 0) - emit_insn (gen_add2_insn (data->from_addr, GEN_INT (size))); + emit_insn (gen_add2_insn (data->from_addr, + gen_int_mode (size, + GET_MODE (data->from_addr)))); if (! data->reverse) data->offset += size; @@ -2647,13 +2653,16 @@ store_by_pieces_2 (insn_gen_fn genfun, machine_mode mode, if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0) emit_insn (gen_add2_insn (data->to_addr, - GEN_INT (-(HOST_WIDE_INT) size))); + gen_int_mode (-(HOST_WIDE_INT) size, + GET_MODE (data->to_addr)))); cst = (*data->constfun) (data->constfundata, data->offset, mode); emit_insn ((*genfun) (to1, cst)); if (HAVE_POST_INCREMENT && data->explicit_inc_to > 0) - emit_insn (gen_add2_insn (data->to_addr, GEN_INT (size))); + emit_insn (gen_add2_insn (data->to_addr, + gen_int_mode (size, + GET_MODE (data->to_addr)))); if (! data->reverse) data->offset += size; @@ -3103,7 +3112,7 @@ emit_move_resolve_push (enum machine_mode mode, rtx x) /* Do not use anti_adjust_stack, since we don't want to update stack_pointer_delta. */ temp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx, - GEN_INT (adjust), stack_pointer_rtx, + gen_int_mode (adjust, Pmode), stack_pointer_rtx, 0, OPTAB_LIB_WIDEN); if (temp != stack_pointer_rtx) emit_move_insn (stack_pointer_rtx, temp); @@ -3614,7 +3623,8 @@ push_block (rtx size, int extra, int below) { temp = copy_to_mode_reg (Pmode, size); if (extra != 0) - temp = expand_binop (Pmode, add_optab, temp, GEN_INT (extra), + temp = expand_binop (Pmode, add_optab, temp, + gen_int_mode (extra, Pmode), temp, 0, OPTAB_LIB_WIDEN); anti_adjust_stack (temp); } @@ -3882,7 +3892,7 @@ emit_single_push_insn_1 (enum machine_mode mode, rtx x, tree type) add_optab, #endif stack_pointer_rtx, - GEN_INT (rounded_size), + gen_int_mode (rounded_size, Pmode), NULL_RTX, 0, OPTAB_LIB_WIDEN)); offset = (HOST_WIDE_INT) padding_size; @@ -3897,18 +3907,20 @@ emit_single_push_insn_1 (enum machine_mode mode, rtx x, tree type) previous value. */ offset -= (HOST_WIDE_INT) rounded_size; #endif - dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset)); + dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, + gen_int_mode (offset, Pmode)); } else { #ifdef STACK_GROWS_DOWNWARD /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC. */ dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, - GEN_INT (-(HOST_WIDE_INT) rounded_size)); + gen_int_mode (-(HOST_WIDE_INT) rounded_size, + Pmode)); #else /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC. */ dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, - GEN_INT (rounded_size)); + gen_int_mode (rounded_size, Pmode)); #endif dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr); } @@ -4096,8 +4108,8 @@ emit_push_insn (rtx x, enum machine_mode mode, tree type, rtx size, size = GEN_INT (INTVAL (size) - used); else size = expand_binop (GET_MODE (size), sub_optab, size, - GEN_INT (used), NULL_RTX, 0, - OPTAB_LIB_WIDEN); + gen_int_mode (used, GET_MODE (size)), + NULL_RTX, 0, OPTAB_LIB_WIDEN); } /* Get the address of the stack space. @@ -4444,7 +4456,8 @@ optimize_bitfield_assignment_op (unsigned HOST_WIDE_INT bitsize, binop = code == BIT_IOR_EXPR ? ior_optab : xor_optab; if (bitpos + bitsize != str_bitsize) { - rtx mask = GEN_INT (((unsigned HOST_WIDE_INT) 1 << bitsize) - 1); + rtx mask = gen_int_mode (((unsigned HOST_WIDE_INT) 1 << bitsize) - 1, + str_mode); value = expand_and (str_mode, value, mask, NULL_RTX); } value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1); @@ -4667,8 +4680,6 @@ expand_assignment (tree to, tree from, bool nontemporal) int unsignedp; int volatilep = 0; tree tem; - bool misalignp; - rtx mem = NULL_RTX; push_temp_slots (); tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1, @@ -4678,40 +4689,7 @@ expand_assignment (tree to, tree from, bool nontemporal) && DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1))) get_bit_range (&bitregion_start, &bitregion_end, to, &bitpos, &offset); - /* If we are going to use store_bit_field and extract_bit_field, - make sure to_rtx will be safe for multiple use. */ - mode = TYPE_MODE (TREE_TYPE (tem)); - if (TREE_CODE (tem) == MEM_REF - && mode != BLKmode - && ((align = get_object_alignment (tem)) - < GET_MODE_ALIGNMENT (mode)) - && ((icode = optab_handler (movmisalign_optab, mode)) - != CODE_FOR_nothing)) - { - struct expand_operand ops[2]; - - misalignp = true; - to_rtx = gen_reg_rtx (mode); - mem = expand_expr (tem, NULL_RTX, VOIDmode, EXPAND_WRITE); - - /* If the misaligned store doesn't overwrite all bits, perform - rmw cycle on MEM. */ - if (bitsize != GET_MODE_BITSIZE (mode)) - { - create_input_operand (&ops[0], to_rtx, mode); - create_fixed_operand (&ops[1], mem); - /* The movmisalign<mode> pattern cannot fail, else the assignment - would silently be omitted. */ - expand_insn (icode, 2, ops); - - mem = copy_rtx (mem); - } - } - else - { - misalignp = false; - to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, EXPAND_WRITE); - } + to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, EXPAND_WRITE); /* If the bitfield is volatile, we want to access it in the field's mode, not the computed mode. @@ -4856,17 +4834,6 @@ expand_assignment (tree to, tree from, bool nontemporal) get_alias_set (to), nontemporal); } - if (misalignp) - { - struct expand_operand ops[2]; - - create_fixed_operand (&ops[0], mem); - create_input_operand (&ops[1], to_rtx, mode); - /* The movmisalign<mode> pattern cannot fail, else the assignment - would silently be omitted. */ - expand_insn (icode, 2, ops); - } - if (result) preserve_temp_slots (result); pop_temp_slots (); @@ -9844,7 +9811,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, if (TYPE_UNSIGNED (TREE_TYPE (field))) { - op1 = GEN_INT (((HOST_WIDE_INT) 1 << bitsize) - 1); + op1 = gen_int_mode (((HOST_WIDE_INT) 1 << bitsize) - 1, + imode); op0 = expand_and (imode, op0, op1, target); } else @@ -11018,10 +10986,11 @@ do_tablejump (rtx index, enum machine_mode mode, rtx range, rtx table_label, GET_MODE_SIZE, because this indicates how large insns are. The other uses should all be Pmode, because they are addresses. This code could fail if addresses and insns are not the same size. */ - index = gen_rtx_PLUS (Pmode, - gen_rtx_MULT (Pmode, index, - GEN_INT (GET_MODE_SIZE (CASE_VECTOR_MODE))), - gen_rtx_LABEL_REF (Pmode, table_label)); + index = gen_rtx_PLUS + (Pmode, + gen_rtx_MULT (Pmode, index, + gen_int_mode (GET_MODE_SIZE (CASE_VECTOR_MODE), Pmode)), + gen_rtx_LABEL_REF (Pmode, table_label)); #ifdef PIC_CASE_VECTOR_ADDRESS if (flag_pic) index = PIC_CASE_VECTOR_ADDRESS (index); diff --git a/gcc/final.c b/gcc/final.c index 90fcf56a910..5c8767328b3 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -70,7 +70,7 @@ along with GCC; see the file COPYING3. If not see #include "debug.h" #include "expr.h" #include "tree-pass.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cgraph.h" #include "coverage.h" #include "df.h" diff --git a/gcc/fold-const.c b/gcc/fold-const.c index e87a31cd8ec..ab94704631e 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -58,7 +58,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "md5.h" #include "gimple.h" -#include "tree-flow.h" +#include "tree-ssa.h" /* Nonzero if we are folding constants inside an initializer; zero otherwise. */ @@ -4276,7 +4276,7 @@ build_range_check (location_t loc, tree type, tree exp, int in_p, } if (low == 0 && high == 0) - return build_int_cst (type, 1); + return omit_one_operand_loc (loc, type, build_int_cst (type, 1), exp); if (low == 0) return fold_build2_loc (loc, LE_EXPR, type, exp, @@ -9895,6 +9895,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, @@ -11217,6 +11235,7 @@ fold_binary_loc (location_t loc, { wide_int c1, c2, c3, msk; int width = TYPE_PRECISION (type), w; + bool try_simplify = true; c1 = TREE_OPERAND (arg0, 1); c2 = arg1; @@ -11248,7 +11267,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), @@ -11637,6 +11670,7 @@ fold_binary_loc (location_t loc, && TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) { +<<<<<<< .working int arg1tz = wi::ctz (TREE_OPERAND (arg0, 1)); if (arg1tz > 0) { @@ -11650,6 +11684,18 @@ fold_binary_loc (location_t loc, return fold_build2_loc (loc, code, type, op0, wide_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)); +>>>>>>> .merge-right.r202797 } /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M, diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 2b34517741d..0e4d688f975 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,49 @@ +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 + * resolve.c (generate_component_assignments): Correctly handle the + case that the LHS is not allocated. + +2013-09-15 Tobias Burnus <burnus@net-b.de> + + PR fortran/57697 + * resolve.c (generate_component_assignments): Handle unallocated + LHS with defined assignment of components. + +2013-09-12 Brooks Moses <bmoses@google.com> + + PR driver/42955 + * Make-lang.in: Do not install driver binaries in $(target)/bin. + +2013-09-09 Tobias Burnus <burnus@net-b.de> + + * invoke.texi (Error and Warning Options): Add hyphen. + 2013-09-02 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/PR56519 diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in index 12d0deee20d..ecbd2b77d0f 100644 --- a/gcc/fortran/Make-lang.in +++ b/gcc/fortran/Make-lang.in @@ -241,19 +241,14 @@ install-finclude-dir: installdirs # Install hooks: # f951 is installed elsewhere as part of $(COMPILERS). -# Install the driver program as $(target)-gfortran -# and also as either gfortran (if native) or $(tooldir)/bin/gfortran. +# Install the driver program as $(target)-gfortran, and also as gfortran +# if native. fortran.install-common: install-finclude-dir installdirs -if [ -f f951$(exeext) ] ; then \ rm -f $(DESTDIR)$(bindir)/$(GFORTRAN_INSTALL_NAME)$(exeext); \ $(INSTALL_PROGRAM) gfortran$(exeext) $(DESTDIR)$(bindir)/$(GFORTRAN_INSTALL_NAME)$(exeext); \ chmod a+x $(DESTDIR)$(bindir)/$(GFORTRAN_INSTALL_NAME)$(exeext); \ - if [ -f gfortran-cross$(exeext) ] ; then \ - if [ -d $(DESTDIR)$(gcc_tooldir)/bin/. ] ; then \ - rm -f $(DESTDIR)$(gcc_tooldir)/bin/gfortran$(exeext); \ - $(INSTALL_PROGRAM) gfortran-cross$(exeext) $(DESTDIR)$(gcc_tooldir)/bin/gfortran$(exeext); \ - else true; fi; \ - else \ + if [ ! -f gfortran-cross$(exeext) ] ; then \ rm -f $(DESTDIR)$(bindir)/$(GFORTRAN_TARGET_INSTALL_NAME)$(exeext); \ $(LN) $(DESTDIR)$(bindir)/$(GFORTRAN_INSTALL_NAME)$(exeext) $(DESTDIR)$(bindir)/$(GFORTRAN_TARGET_INSTALL_NAME)$(exeext); \ fi ; \ 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/invoke.texi b/gcc/fortran/invoke.texi index 69bec275de9..eb678d1f043 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -144,7 +144,7 @@ and warnings}. -Wconversion -Wfunction-elimination -Wimplicit-interface @gol -Wimplicit-procedure -Wintrinsic-shadow -Wintrinsics-std @gol -Wline-truncation -Wno-align-commons -Wno-tabs -Wreal-q-constant @gol --Wsurprising -Wunderflow -Wunused-parameter -Wrealloc-lhs Wrealloc-lhs-all @gol +-Wsurprising -Wunderflow -Wunused-parameter -Wrealloc-lhs -Wrealloc-lhs-all @gol -Wtarget-lifetime -fmax-errors=@var{n} -fsyntax-only -pedantic -pedantic-errors } 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 2929679aecc..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) { - gfc_error ("Variable must not be polymorphic in intrinsic assignment at " - "%L - check that there is a matching specific subroutine " - "for '=' operator", &lhs->where); + 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 ("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; } @@ -9546,6 +9568,24 @@ generate_component_assignments (gfc_code **code, gfc_namespace *ns) temp_code = build_assignment (EXEC_ASSIGN, t1, (*code)->expr1, NULL, NULL, (*code)->loc); + + /* For allocatable LHS, check whether it is allocated. Note + that allocatable components with defined assignment are + not yet support. See PR 57696. */ + if ((*code)->expr1->symtree->n.sym->attr.allocatable) + { + gfc_code *block; + gfc_expr *e = + gfc_lval_expr_from_sym ((*code)->expr1->symtree->n.sym); + block = gfc_get_code (EXEC_IF); + block->block = gfc_get_code (EXEC_IF); + block->block->expr1 + = gfc_build_intrinsic_call (ns, + GFC_ISYM_ALLOCATED, "allocated", + (*code)->loc, 1, e); + block->block->next = temp_code; + temp_code = block; + } add_code_to_chain (&temp_code, &tmp_head, &tmp_tail); } @@ -9554,6 +9594,32 @@ generate_component_assignments (gfc_code **code, gfc_namespace *ns) gfc_free_expr (this_code->ext.actual->expr); this_code->ext.actual->expr = gfc_copy_expr (t1); add_comp_ref (this_code->ext.actual->expr, comp1); + + /* If the LHS variable is allocatable and wasn't allocated and + the temporary is allocatable, pointer assign the address of + the freshly allocated LHS to the temporary. */ + if ((*code)->expr1->symtree->n.sym->attr.allocatable + && gfc_expr_attr ((*code)->expr1).allocatable) + { + gfc_code *block; + gfc_expr *cond; + cond = gfc_get_expr (); + cond->ts.type = BT_LOGICAL; + cond->ts.kind = gfc_default_logical_kind; + cond->expr_type = EXPR_OP; + cond->where = (*code)->loc; + cond->value.op.op = INTRINSIC_NOT; + cond->value.op.op1 = gfc_build_intrinsic_call (ns, + GFC_ISYM_ALLOCATED, "allocated", + (*code)->loc, 1, gfc_copy_expr (t1)); + block = gfc_get_code (EXEC_IF); + block->block = gfc_get_code (EXEC_IF); + block->block->expr1 = cond; + block->block->next = build_assignment (EXEC_POINTER_ASSIGN, + t1, (*code)->expr1, + NULL, NULL, (*code)->loc); + add_code_to_chain (&block, &head, &tail); + } } } else if (this_code->op == EXEC_ASSIGN && !this_code->next) diff --git a/gcc/function.c b/gcc/function.c index 3040a5ecb72..e0392b1e164 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -1520,7 +1520,7 @@ instantiate_virtual_regs_in_insn (rtx insn) for_each_rtx (&SET_SRC (set), instantiate_virtual_regs_in_rtx, NULL); x = simplify_gen_binary (PLUS, GET_MODE (new_rtx), SET_SRC (set), - GEN_INT (-offset)); + gen_int_mode (-offset, GET_MODE (new_rtx))); x = force_operand (x, new_rtx); if (x != new_rtx) emit_move_insn (new_rtx, x); @@ -1544,9 +1544,10 @@ instantiate_virtual_regs_in_insn (rtx insn) { start_sequence (); - x = expand_simple_binop (GET_MODE (SET_DEST (set)), PLUS, - new_rtx, GEN_INT (offset), SET_DEST (set), - 1, OPTAB_LIB_WIDEN); + x = expand_simple_binop (GET_MODE (SET_DEST (set)), PLUS, new_rtx, + gen_int_mode (offset, + GET_MODE (SET_DEST (set))), + SET_DEST (set), 1, OPTAB_LIB_WIDEN); if (x != SET_DEST (set)) emit_move_insn (SET_DEST (set), x); @@ -1666,8 +1667,8 @@ instantiate_virtual_regs_in_insn (rtx insn) to see if (plus new offset) is a valid before we put this through expand_simple_binop. */ x = expand_simple_binop (GET_MODE (x), PLUS, new_rtx, - GEN_INT (offset), NULL_RTX, - 1, OPTAB_LIB_WIDEN); + gen_int_mode (offset, GET_MODE (x)), + NULL_RTX, 1, OPTAB_LIB_WIDEN); seq = get_insns (); end_sequence (); emit_insn_before (seq, insn); @@ -1681,9 +1682,10 @@ instantiate_virtual_regs_in_insn (rtx insn) if (offset != 0) { start_sequence (); - new_rtx = expand_simple_binop (GET_MODE (new_rtx), PLUS, new_rtx, - GEN_INT (offset), NULL_RTX, - 1, OPTAB_LIB_WIDEN); + new_rtx = expand_simple_binop + (GET_MODE (new_rtx), PLUS, new_rtx, + gen_int_mode (offset, GET_MODE (new_rtx)), + NULL_RTX, 1, OPTAB_LIB_WIDEN); seq = get_insns (); end_sequence (); emit_insn_before (seq, insn); 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/gengtype.c b/gcc/gengtype.c index 1dd1c611249..ed2399145ed 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -1735,7 +1735,7 @@ open_base_files (void) "tree.h", "rtl.h", "wide-int.h", "function.h", "insn-config.h", "expr.h", "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h", "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h", - "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h", + "tree-ssa.h", "reload.h", "cpp-id-data.h", "tree-chrec.h", "except.h", "output.h", "gimple.h", "cfgloop.h", "target.h", "ipa-prop.h", "lto-streamer.h", "target-globals.h", "ipa-inline.h", "dwarf2out.h", NULL @@ -2003,14 +2003,21 @@ struct file_rule_st files_rules[] = { REG_EXTENDED, NULL_REGEX, "gt-objc-objc-map.h", "objc/objc-map.c", NULL_FRULACT }, - /* General cases. For header *.h and source *.c files, we need - * special actions to handle the language. */ + /* General cases. For header *.h and source *.c or *.cc files, we + * need special actions to handle the language. */ /* Source *.c files are using get_file_gtfilename to compute their output_name and get_file_basename to compute their for_name through the source_dot_c_frul action. */ { DIR_PREFIX_REGEX "([[:alnum:]_-]*)\\.c$", REG_EXTENDED, NULL_REGEX, "gt-$3.h", "$3.c", source_dot_c_frul}, + + /* Source *.cc files are using get_file_gtfilename to compute their + output_name and get_file_basename to compute their for_name + through the source_dot_c_frul action. */ + { DIR_PREFIX_REGEX "([[:alnum:]_-]*)\\.cc$", + REG_EXTENDED, NULL_REGEX, "gt-$3.h", "$3.cc", source_dot_c_frul}, + /* Common header files get "gtype-desc.c" as their output_name, * while language specific header files are handled specially. So * we need the header_dot_h_frul action. */ @@ -2268,9 +2275,9 @@ get_output_file_with_visibility (input_file *inpf) } if (!output_name || !for_name) { - /* This is impossible, and could only happen if the files_rules is - incomplete or buggy. */ - gcc_unreachable (); + /* This should not be possible, and could only happen if the + files_rules is incomplete or buggy. */ + fatal ("failed to compute output name for %s", inpfname); } /* Look through to see if we've ever seen this output filename diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c index eab7b676e97..487a6d45c78 100644 --- a/gcc/ggc-page.c +++ b/gcc/ggc-page.c @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "ggc-internal.h" #include "timevar.h" #include "params.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "plugin.h" diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index c125ba486e0..97e6cb13e7f 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "function.h" #include "dumpfile.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-ssa-propagate.h" #include "target.h" #include "gimple-fold.h" @@ -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. */ @@ -3136,7 +3150,7 @@ gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo) size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (v)))); offset += token * size; fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), init, - offset, size, vtable); + offset, size, v); if (!fn || integer_zerop (fn)) return NULL_TREE; gcc_assert (TREE_CODE (fn) == ADDR_EXPR diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c index 0b0151f8437..574e31f298f 100644 --- a/gcc/gimple-iterator.c +++ b/gcc/gimple-iterator.c @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "tree.h" #include "gimple.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "value-prof.h" diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index 2884b6ff6fb..a46a69f56ed 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple.h" #include "tree-iterator.h" #include "tree-inline.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "flags.h" #include "function.h" #include "diagnostic-core.h" diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 42a0e8be43c..05c0afa13e8 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic.h" #include "gimple-pretty-print.h" #include "hashtab.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "dumpfile.h" /* for dump_flags */ #include "gimple.h" #include "value-prof.h" diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c index 024dffe15eb..7a089cd0d39 100644 --- a/gcc/gimple-ssa-strength-reduction.c +++ b/gcc/gimple-ssa-strength-reduction.c @@ -42,7 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "cfgloop.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "domwalk.h" #include "pointer-set.h" #include "expmed.h" @@ -752,6 +752,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) @@ -769,7 +820,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, max_wide_int *pindex, @@ -778,7 +836,7 @@ restructure_reference (tree *pbase, tree *poffset, max_wide_int *pindex, tree base = *pbase, offset = *poffset; max_wide_int index = *pindex; tree mult_op0, t1, t2, type; - max_wide_int c1, c2, c3, c4; + max_wide_int c1, c2, c3, c4, c5; if (!base || !offset @@ -822,11 +880,12 @@ restructure_reference (tree *pbase, tree *poffset, max_wide_int *pindex, } c4 = wi::udiv_floor (index, BITS_PER_UNIT); + 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), wide_int_to_tree (sizetype, c3)); - *pindex = c1 + c2 * c3 + c4; + *pindex = c1 + c2 * c3 + c4 + c5 * c3; *ptype = type; return true; @@ -1509,11 +1568,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; @@ -3426,8 +3492,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); @@ -3447,18 +3511,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)) { @@ -3469,8 +3525,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/gimple-streamer-in.c b/gcc/gimple-streamer-in.c index 29e8bd04c83..8161a087656 100644 --- a/gcc/gimple-streamer-in.c +++ b/gcc/gimple-streamer-in.c @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "diagnostic.h" #include "tree.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "data-streamer.h" #include "tree-streamer.h" #include "gimple-streamer.h" diff --git a/gcc/gimple-streamer-out.c b/gcc/gimple-streamer-out.c index 0b8d8c1d251..33699bbbfa9 100644 --- a/gcc/gimple-streamer-out.c +++ b/gcc/gimple-streamer-out.c @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "tree.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "data-streamer.h" #include "gimple-streamer.h" #include "lto-streamer.h" diff --git a/gcc/gimple.c b/gcc/gimple.c index 9e615f19c7d..b7c8281c202 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "gimple.h" #include "diagnostic.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "value-prof.h" #include "flags.h" #include "alias.h" @@ -4324,4 +4324,260 @@ build_type_cast (tree to_type, gimple op, enum ssa_mode mode) return build_type_cast (to_type, gimple_assign_lhs (op), mode); } + +/* Return true if the conversion from INNER_TYPE to OUTER_TYPE is a + useless type conversion, otherwise return false. + + This function implicitly defines the middle-end type system. With + the notion of 'a < b' meaning that useless_type_conversion_p (a, b) + holds and 'a > b' meaning that useless_type_conversion_p (b, a) holds, + the following invariants shall be fulfilled: + + 1) useless_type_conversion_p is transitive. + If a < b and b < c then a < c. + + 2) useless_type_conversion_p is not symmetric. + From a < b does not follow a > b. + + 3) Types define the available set of operations applicable to values. + A type conversion is useless if the operations for the target type + is a subset of the operations for the source type. For example + casts to void* are useless, casts from void* are not (void* can't + be dereferenced or offsetted, but copied, hence its set of operations + is a strict subset of that of all other data pointer types). Casts + to const T* are useless (can't be written to), casts from const T* + to T* are not. */ + +bool +useless_type_conversion_p (tree outer_type, tree inner_type) +{ + /* Do the following before stripping toplevel qualifiers. */ + if (POINTER_TYPE_P (inner_type) + && POINTER_TYPE_P (outer_type)) + { + /* Do not lose casts between pointers to different address spaces. */ + if (TYPE_ADDR_SPACE (TREE_TYPE (outer_type)) + != TYPE_ADDR_SPACE (TREE_TYPE (inner_type))) + return false; + } + + /* From now on qualifiers on value types do not matter. */ + inner_type = TYPE_MAIN_VARIANT (inner_type); + outer_type = TYPE_MAIN_VARIANT (outer_type); + + if (inner_type == outer_type) + return true; + + /* If we know the canonical types, compare them. */ + if (TYPE_CANONICAL (inner_type) + && TYPE_CANONICAL (inner_type) == TYPE_CANONICAL (outer_type)) + return true; + + /* Changes in machine mode are never useless conversions unless we + deal with aggregate types in which case we defer to later checks. */ + if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type) + && !AGGREGATE_TYPE_P (inner_type)) + return false; + + /* If both the inner and outer types are integral types, then the + conversion is not necessary if they have the same mode and + signedness and precision, and both or neither are boolean. */ + if (INTEGRAL_TYPE_P (inner_type) + && INTEGRAL_TYPE_P (outer_type)) + { + /* Preserve changes in signedness or precision. */ + if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type) + || TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type)) + return false; + + /* Preserve conversions to/from BOOLEAN_TYPE if types are not + of precision one. */ + if (((TREE_CODE (inner_type) == BOOLEAN_TYPE) + != (TREE_CODE (outer_type) == BOOLEAN_TYPE)) + && TYPE_PRECISION (outer_type) != 1) + return false; + + /* We don't need to preserve changes in the types minimum or + maximum value in general as these do not generate code + unless the types precisions are different. */ + return true; + } + + /* Scalar floating point types with the same mode are compatible. */ + else if (SCALAR_FLOAT_TYPE_P (inner_type) + && SCALAR_FLOAT_TYPE_P (outer_type)) + return true; + + /* Fixed point types with the same mode are compatible. */ + else if (FIXED_POINT_TYPE_P (inner_type) + && FIXED_POINT_TYPE_P (outer_type)) + return true; + + /* We need to take special care recursing to pointed-to types. */ + else if (POINTER_TYPE_P (inner_type) + && POINTER_TYPE_P (outer_type)) + { + /* Do not lose casts to function pointer types. */ + if ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE + || TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE) + && !(TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE + || TREE_CODE (TREE_TYPE (inner_type)) == METHOD_TYPE)) + return false; + + /* We do not care for const qualification of the pointed-to types + as const qualification has no semantic value to the middle-end. */ + + /* Otherwise pointers/references are equivalent. */ + return true; + } + + /* Recurse for complex types. */ + else if (TREE_CODE (inner_type) == COMPLEX_TYPE + && TREE_CODE (outer_type) == COMPLEX_TYPE) + return useless_type_conversion_p (TREE_TYPE (outer_type), + TREE_TYPE (inner_type)); + + /* Recurse for vector types with the same number of subparts. */ + else if (TREE_CODE (inner_type) == VECTOR_TYPE + && TREE_CODE (outer_type) == VECTOR_TYPE + && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type)) + return useless_type_conversion_p (TREE_TYPE (outer_type), + TREE_TYPE (inner_type)); + + else if (TREE_CODE (inner_type) == ARRAY_TYPE + && TREE_CODE (outer_type) == ARRAY_TYPE) + { + /* Preserve string attributes. */ + if (TYPE_STRING_FLAG (inner_type) != TYPE_STRING_FLAG (outer_type)) + return false; + + /* Conversions from array types with unknown extent to + array types with known extent are not useless. */ + if (!TYPE_DOMAIN (inner_type) + && TYPE_DOMAIN (outer_type)) + return false; + + /* Nor are conversions from array types with non-constant size to + array types with constant size or to different size. */ + if (TYPE_SIZE (outer_type) + && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST + && (!TYPE_SIZE (inner_type) + || TREE_CODE (TYPE_SIZE (inner_type)) != INTEGER_CST + || !tree_int_cst_equal (TYPE_SIZE (outer_type), + TYPE_SIZE (inner_type)))) + return false; + + /* Check conversions between arrays with partially known extents. + If the array min/max values are constant they have to match. + Otherwise allow conversions to unknown and variable extents. + In particular this declares conversions that may change the + mode to BLKmode as useless. */ + if (TYPE_DOMAIN (inner_type) + && TYPE_DOMAIN (outer_type) + && TYPE_DOMAIN (inner_type) != TYPE_DOMAIN (outer_type)) + { + tree inner_min = TYPE_MIN_VALUE (TYPE_DOMAIN (inner_type)); + tree outer_min = TYPE_MIN_VALUE (TYPE_DOMAIN (outer_type)); + tree inner_max = TYPE_MAX_VALUE (TYPE_DOMAIN (inner_type)); + tree outer_max = TYPE_MAX_VALUE (TYPE_DOMAIN (outer_type)); + + /* After gimplification a variable min/max value carries no + additional information compared to a NULL value. All that + matters has been lowered to be part of the IL. */ + if (inner_min && TREE_CODE (inner_min) != INTEGER_CST) + inner_min = NULL_TREE; + if (outer_min && TREE_CODE (outer_min) != INTEGER_CST) + outer_min = NULL_TREE; + if (inner_max && TREE_CODE (inner_max) != INTEGER_CST) + inner_max = NULL_TREE; + if (outer_max && TREE_CODE (outer_max) != INTEGER_CST) + outer_max = NULL_TREE; + + /* Conversions NULL / variable <- cst are useless, but not + the other way around. */ + if (outer_min + && (!inner_min + || !tree_int_cst_equal (inner_min, outer_min))) + return false; + if (outer_max + && (!inner_max + || !tree_int_cst_equal (inner_max, outer_max))) + return false; + } + + /* Recurse on the element check. */ + return useless_type_conversion_p (TREE_TYPE (outer_type), + TREE_TYPE (inner_type)); + } + + else if ((TREE_CODE (inner_type) == FUNCTION_TYPE + || TREE_CODE (inner_type) == METHOD_TYPE) + && TREE_CODE (inner_type) == TREE_CODE (outer_type)) + { + tree outer_parm, inner_parm; + + /* If the return types are not compatible bail out. */ + if (!useless_type_conversion_p (TREE_TYPE (outer_type), + TREE_TYPE (inner_type))) + return false; + + /* Method types should belong to a compatible base class. */ + if (TREE_CODE (inner_type) == METHOD_TYPE + && !useless_type_conversion_p (TYPE_METHOD_BASETYPE (outer_type), + TYPE_METHOD_BASETYPE (inner_type))) + return false; + + /* A conversion to an unprototyped argument list is ok. */ + if (!prototype_p (outer_type)) + return true; + + /* If the unqualified argument types are compatible the conversion + is useless. */ + if (TYPE_ARG_TYPES (outer_type) == TYPE_ARG_TYPES (inner_type)) + return true; + + for (outer_parm = TYPE_ARG_TYPES (outer_type), + inner_parm = TYPE_ARG_TYPES (inner_type); + outer_parm && inner_parm; + outer_parm = TREE_CHAIN (outer_parm), + inner_parm = TREE_CHAIN (inner_parm)) + if (!useless_type_conversion_p + (TYPE_MAIN_VARIANT (TREE_VALUE (outer_parm)), + TYPE_MAIN_VARIANT (TREE_VALUE (inner_parm)))) + return false; + + /* If there is a mismatch in the number of arguments the functions + are not compatible. */ + if (outer_parm || inner_parm) + return false; + + /* Defer to the target if necessary. */ + if (TYPE_ATTRIBUTES (inner_type) || TYPE_ATTRIBUTES (outer_type)) + return comp_type_attributes (outer_type, inner_type) != 0; + + return true; + } + + /* For aggregates we rely on TYPE_CANONICAL exclusively and require + explicit conversions for types involving to be structurally + compared types. */ + else if (AGGREGATE_TYPE_P (inner_type) + && TREE_CODE (inner_type) == TREE_CODE (outer_type)) + return false; + + return false; +} + +/* Return true if a conversion from either type of TYPE1 and TYPE2 + to the other is not required. Otherwise return false. */ + +bool +types_compatible_p (tree type1, tree type2) +{ + return (type1 == type2 + || (useless_type_conversion_p (type1, type2) + && useless_type_conversion_p (type2, type1))); +} + + #include "gt-gimple.h" diff --git a/gcc/gimple.h b/gcc/gimple.h index 9f29561eb37..5f1280586d2 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -922,6 +922,8 @@ extern bool gimple_ior_addresses_taken (bitmap, gimple); extern bool gimple_call_builtin_p (gimple, enum built_in_class); extern bool gimple_call_builtin_p (gimple, enum built_in_function); extern bool gimple_asm_clobbers_memory_p (const_gimple); +extern bool useless_type_conversion_p (tree, tree); +extern bool types_compatible_p (tree, tree); /* In gimplify.c */ extern tree create_tmp_var_raw (tree, const char *); @@ -1098,12 +1100,6 @@ extern tree gimple_assign_rhs_to_tree (gimple); /* In builtins.c */ extern bool validate_gimple_arglist (const_gimple, ...); -/* In tree-ssa.c */ -extern bool tree_ssa_useless_type_conversion (tree); -extern tree tree_ssa_strip_useless_type_conversions (tree); -extern bool useless_type_conversion_p (tree, tree); -extern bool types_compatible_p (tree, tree); - /* In tree-ssa-coalesce.c */ extern bool gimple_can_coalesce_p (tree, tree); diff --git a/gcc/gimplify.c b/gcc/gimplify.c index db2c2e3bb18..10d8e52a57a 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-inline.h" #include "tree-pretty-print.h" #include "langhooks.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cgraph.h" #include "timevar.h" #include "hashtab.h" diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index bfe955ee5cb..0a91808483a 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-blocking.c b/gcc/graphite-blocking.c index ed2cf8d2e0b..9226da00eae 100644 --- a/gcc/graphite-blocking.c +++ b/gcc/graphite-blocking.c @@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "dumpfile.h" #include "cfgloop.h" #include "tree-chrec.h" diff --git a/gcc/graphite-clast-to-gimple.c b/gcc/graphite-clast-to-gimple.c index 76197040d1d..d67a748a9b3 100644 --- a/gcc/graphite-clast-to-gimple.c +++ b/gcc/graphite-clast-to-gimple.c @@ -35,7 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "diagnostic-core.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "cfgloop.h" #include "tree-chrec.h" diff --git a/gcc/graphite-dependences.c b/gcc/graphite-dependences.c index 7fd4081e926..5139e69b942 100644 --- a/gcc/graphite-dependences.c +++ b/gcc/graphite-dependences.c @@ -33,7 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "cfgloop.h" #include "tree-chrec.h" diff --git a/gcc/graphite-interchange.c b/gcc/graphite-interchange.c index 05147e18ab5..289c1d9568f 100644 --- a/gcc/graphite-interchange.c +++ b/gcc/graphite-interchange.c @@ -35,7 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "dumpfile.h" #include "cfgloop.h" #include "tree-chrec.h" diff --git a/gcc/graphite-optimize-isl.c b/gcc/graphite-optimize-isl.c index 318f80c1e0d..f47e21a5023 100644 --- a/gcc/graphite-optimize-isl.c +++ b/gcc/graphite-optimize-isl.c @@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "dumpfile.h" #include "cfgloop.h" #include "tree-chrec.h" diff --git a/gcc/graphite-poly.c b/gcc/graphite-poly.c index c44791ca592..35fe3ba2342 100644 --- a/gcc/graphite-poly.c +++ b/gcc/graphite-poly.c @@ -35,7 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "diagnostic-core.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "dumpfile.h" #include "gimple-pretty-print.h" #include "cfgloop.h" diff --git a/gcc/graphite-scop-detection.c b/gcc/graphite-scop-detection.c index 78510f3e052..120da70580c 100644 --- a/gcc/graphite-scop-detection.c +++ b/gcc/graphite-scop-detection.c @@ -31,7 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "tree-chrec.h" #include "tree-data-ref.h" diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c index ebf03ddf640..b159f236092 100644 --- a/gcc/graphite-sese-to-poly.c +++ b/gcc/graphite-sese-to-poly.c @@ -33,7 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "cfgloop.h" #include "tree-chrec.h" @@ -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/graphite.c b/gcc/graphite.c index f9536639412..2cea3894da8 100644 --- a/gcc/graphite.c +++ b/gcc/graphite.c @@ -47,7 +47,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "diagnostic-core.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-dump.h" #include "cfgloop.h" #include "tree-chrec.h" diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 5698b4f5e72..ebc4f1c3e54 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1162,8 +1162,8 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) target = expand_simple_binop (mode, (diff == STORE_FLAG_VALUE ? PLUS : MINUS), - GEN_INT (ifalse), target, if_info->x, 0, - OPTAB_WIDEN); + gen_int_mode (ifalse, mode), target, + if_info->x, 0, OPTAB_WIDEN); } /* if (test) x = 8; else x = 0; @@ -1180,8 +1180,8 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) else if (itrue == -1) { target = expand_simple_binop (mode, IOR, - target, GEN_INT (ifalse), if_info->x, 0, - OPTAB_WIDEN); + target, gen_int_mode (ifalse, mode), + if_info->x, 0, OPTAB_WIDEN); } /* if (test) x = a; else x = b; @@ -1189,11 +1189,11 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) else { target = expand_simple_binop (mode, AND, - target, GEN_INT (diff), if_info->x, 0, - OPTAB_WIDEN); + target, gen_int_mode (diff, mode), + if_info->x, 0, OPTAB_WIDEN); if (target) target = expand_simple_binop (mode, PLUS, - target, GEN_INT (ifalse), + target, gen_int_mode (ifalse, mode), if_info->x, 0, OPTAB_WIDEN); } diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 8182ebf7e10..cdf34376e00 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -108,7 +108,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple.h" #include "cgraph.h" #include "ipa-prop.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "flags.h" #include "diagnostic.h" @@ -2113,23 +2113,17 @@ propagate_constants_topo (struct topo_info *topo) for (i = topo->nnodes - 1; i >= 0; i--) { + unsigned j; struct cgraph_node *v, *node = topo->order[i]; - struct ipa_dfs_info *node_dfs_info; + vec<cgraph_node_ptr> cycle_nodes = ipa_get_nodes_in_cycle (node); - if (!cgraph_function_with_gimple_body_p (node)) - continue; - - node_dfs_info = (struct ipa_dfs_info *) node->symbol.aux; /* First, iteratively propagate within the strongly connected component until all lattices stabilize. */ - v = node_dfs_info->next_cycle; - while (v) - { + FOR_EACH_VEC_ELT (cycle_nodes, j, v) + if (cgraph_function_with_gimple_body_p (v)) push_node_to_stack (topo, v); - v = ((struct ipa_dfs_info *) v->symbol.aux)->next_cycle; - } - v = node; + v = pop_node_from_stack (topo); while (v) { struct cgraph_edge *cs; @@ -2144,19 +2138,18 @@ propagate_constants_topo (struct topo_info *topo) /* Afterwards, propagate along edges leading out of the SCC, calculates the local effects of the discovered constants and all valid values to their topological sort. */ - v = node; - while (v) - { - struct cgraph_edge *cs; - - estimate_local_effects (v); - add_all_node_vals_to_toposort (v); - for (cs = v->callees; cs; cs = cs->next_callee) - if (!edge_within_scc (cs)) - propagate_constants_accross_call (cs); + FOR_EACH_VEC_ELT (cycle_nodes, j, v) + if (cgraph_function_with_gimple_body_p (v)) + { + struct cgraph_edge *cs; - v = ((struct ipa_dfs_info *) v->symbol.aux)->next_cycle; - } + estimate_local_effects (v); + add_all_node_vals_to_toposort (v); + for (cs = v->callees; cs; cs = cs->next_callee) + if (!edge_within_scc (cs)) + propagate_constants_accross_call (cs); + } + cycle_nodes.release (); } } diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index 0358d296bcd..025602d1f5b 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -204,9 +204,6 @@ hash_type_name (tree t) } v = DECL_ASSEMBLER_NAME (v); -#ifdef ENABLE_CHECKING - gcc_assert (!strchr (IDENTIFIER_POINTER (v), '.')); -#endif hash = iterative_hash_hashval_t (hash, htab_hash_pointer (v)); return hash; } @@ -573,6 +570,8 @@ maybe_record_node (vec <cgraph_node *> &nodes, && fcode != BUILT_IN_TRAP && !pointer_set_insert (inserted, target) && (target_node = cgraph_get_node (target)) != NULL + && (TREE_PUBLIC (target) + || target_node->symbol.definition) && symtab_real_symbol_p ((symtab_node)target_node)) { pointer_set_insert (cached_polymorphic_call_targets, @@ -594,6 +593,8 @@ maybe_record_node (vec <cgraph_node *> &nodes, MATCHED_VTABLES tracks virtual tables we already did lookup for virtual function in. + + ANONYMOUS is true if BINFO is part of anonymous namespace. */ static void @@ -603,7 +604,8 @@ record_binfo (vec <cgraph_node *> &nodes, tree type_binfo, HOST_WIDE_INT otr_token, pointer_set_t *inserted, - pointer_set_t *matched_vtables) + pointer_set_t *matched_vtables, + bool anonymous) { tree type = BINFO_TYPE (binfo); int i; @@ -614,6 +616,19 @@ record_binfo (vec <cgraph_node *> &nodes, if (types_same_for_odr (type, otr_type) && !pointer_set_insert (matched_vtables, BINFO_VTABLE (type_binfo))) { + /* For types in anonymous namespace first check if the respective vtable + is alive. If not, we know the type can't be called. */ + if (!flag_ltrans && anonymous) + { + tree vtable = BINFO_VTABLE (type_binfo); + struct varpool_node *vnode; + + if (TREE_CODE (vtable) == POINTER_PLUS_EXPR) + vtable = TREE_OPERAND (TREE_OPERAND (vtable, 0), 0); + vnode = varpool_get_node (vtable); + if (!vnode || !vnode->symbol.definition) + return; + } tree target = gimple_get_virt_method_for_binfo (otr_token, type_binfo); if (target) maybe_record_node (nodes, target, inserted); @@ -629,7 +644,7 @@ record_binfo (vec <cgraph_node *> &nodes, is shared with the outer type. */ BINFO_VTABLE (base_binfo) ? base_binfo : type_binfo, otr_token, inserted, - matched_vtables); + matched_vtables, anonymous); } /* Lookup virtual methods matching OTR_TYPE (with OFFSET and OTR_TOKEN) @@ -649,7 +664,7 @@ possible_polymorphic_call_targets_1 (vec <cgraph_node *> &nodes, unsigned int i; record_binfo (nodes, binfo, otr_type, binfo, otr_token, inserted, - matched_vtables); + matched_vtables, type->anonymous_namespace); for (i = 0; i < type->derived_types.length(); i++) possible_polymorphic_call_targets_1 (nodes, inserted, matched_vtables, @@ -738,6 +753,18 @@ devirt_node_removal_hook (struct cgraph_node *n, void *d ATTRIBUTE_UNUSED) free_polymorphic_call_targets_hash (); } +/* When virtual table is removed, we may need to flush the cache. */ + +static void +devirt_variable_node_removal_hook (struct varpool_node *n, + void *d ATTRIBUTE_UNUSED) +{ + if (cached_polymorphic_call_targets + && DECL_VIRTUAL_P (n->symbol.decl) + && type_in_anonymous_namespace_p (DECL_CONTEXT (n->symbol.decl))) + free_polymorphic_call_targets_hash (); +} + /* Return vector containing possible targets of polymorphic call of type OTR_TYPE caling method OTR_TOKEN with OFFSET. If FINALp is non-NULL, store true if the list is complette. @@ -785,8 +812,12 @@ possible_polymorphic_call_targets (tree otr_type, cached_polymorphic_call_targets = pointer_set_create (); polymorphic_call_target_hash.create (23); if (!node_removal_hook_holder) - node_removal_hook_holder = - cgraph_add_node_removal_hook (&devirt_node_removal_hook, NULL); + { + node_removal_hook_holder = + cgraph_add_node_removal_hook (&devirt_node_removal_hook, NULL); + varpool_add_node_removal_hook (&devirt_variable_node_removal_hook, + NULL); + } } /* Lookup cached answer. */ @@ -931,11 +962,8 @@ likely_target_p (struct cgraph_node *n) } /* The ipa-devirt pass. - This performs very trivial devirtualization: - 1) when polymorphic call is known to have precisely one target, - turn it into direct call - 2) when polymorphic call has only one likely target in the unit, - turn it into speculative call. */ + When polymorphic call has only one likely target in the unit, + turn it into speculative call. */ static unsigned int ipa_devirt (void) @@ -968,26 +996,9 @@ ipa_devirt (void) if (dump_file) dump_possible_polymorphic_call_targets (dump_file, e); + npolymorphic++; - if (final) - { - gcc_assert (targets.length()); - if (targets.length() == 1) - { - if (dump_file) - fprintf (dump_file, - "Devirtualizing call in %s/%i to %s/%i\n", - cgraph_node_name (n), n->symbol.order, - cgraph_node_name (targets[0]), targets[0]->symbol.order); - cgraph_make_edge_direct (e, targets[0]); - ndevirtualized++; - update = true; - continue; - } - } - if (!flag_devirtualize_speculatively) - continue; if (!cgraph_maybe_hot_edge_p (e)) { if (dump_file) @@ -1087,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 @@ -1117,9 +1134,7 @@ ipa_devirt (void) static bool gate_ipa_devirt (void) { - /* FIXME: We should remove the optimize check after we ensure we never run - IPA passes when not optimizing. */ - return flag_devirtualize && !in_lto_p; + return flag_devirtualize_speculatively && optimize; } namespace { diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index fb0c8382020..ba6221e41fd 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -79,7 +79,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "coverage.h" #include "ggc.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "ipa-prop.h" #include "lto-streamer.h" #include "data-streamer.h" @@ -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))) @@ -3580,6 +3584,7 @@ estimate_size_after_inlining (struct cgraph_node *node, struct growth_data { + struct cgraph_node *node; bool self_recursive; int growth; }; @@ -3597,9 +3602,9 @@ do_estimate_growth_1 (struct cgraph_node *node, void *data) { gcc_checking_assert (e->inline_failed); - if (e->caller == node + if (e->caller == d->node || (e->caller->global.inlined_to - && e->caller->global.inlined_to == node)) + && e->caller->global.inlined_to == d->node)) d->self_recursive = true; d->growth += estimate_edge_growth (e); } @@ -3612,7 +3617,7 @@ do_estimate_growth_1 (struct cgraph_node *node, void *data) int do_estimate_growth (struct cgraph_node *node) { - struct growth_data d = { 0, false }; + struct growth_data d = { node, 0, false }; struct inline_summary *info = inline_summary (node); cgraph_for_node_and_aliases (node, do_estimate_growth_1, &d, true); @@ -3677,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-transform.c b/gcc/ipa-inline-transform.c index 2bada90bc8a..d8a637cb850 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -38,7 +38,7 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" #include "coverage.h" #include "ggc.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "ipa-prop.h" #include "ipa-inline.h" #include "tree-inline.h" diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 9a9408ee2ab..3672e57e471 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -107,7 +107,7 @@ along with GCC; see the file COPYING3. If not see #include "coverage.h" #include "ggc.h" #include "rtl.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "ipa-prop.h" #include "except.h" #include "target.h" @@ -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. */ @@ -740,16 +741,33 @@ want_inline_self_recursive_call_p (struct cgraph_edge *edge, return want_inline; } -/* Return true when NODE has caller other than EDGE. +/* Return true when NODE has uninlinable caller; + set HAS_HOT_CALL if it has hot call. Worker for cgraph_for_node_and_aliases. */ static bool -check_caller_edge (struct cgraph_node *node, void *edge) +check_callers (struct cgraph_node *node, void *has_hot_call) { - return (node->callers - && node->callers != edge); + struct cgraph_edge *e; + for (e = node->callers; e; e = e->next_caller) + { + if (!can_inline_edge_p (e, true)) + return true; + if (!has_hot_call && cgraph_maybe_hot_edge_p (e)) + *(bool *)has_hot_call = true; + } + return false; } +/* If NODE has a caller, return true. */ + +static bool +has_caller_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) +{ + if (node->callers) + return true; + return false; +} /* Decide if inlining NODE would reduce unit size by eliminating the offline copy of function. @@ -759,11 +777,10 @@ static bool want_inline_function_to_all_callers_p (struct cgraph_node *node, bool cold) { struct cgraph_node *function = cgraph_function_or_thunk_node (node, NULL); - struct cgraph_edge *e; bool has_hot_call = false; /* Does it have callers? */ - if (!node->callers) + if (!cgraph_for_node_and_aliases (node, has_caller_p, NULL, true)) return false; /* Already inlined? */ if (function->global.inlined_to) @@ -773,18 +790,9 @@ want_inline_function_to_all_callers_p (struct cgraph_node *node, bool cold) /* Inlining into all callers would increase size? */ if (estimate_growth (node) > 0) return false; - /* Maybe other aliases has more direct calls. */ - if (cgraph_for_node_and_aliases (node, check_caller_edge, node->callers, true)) - return false; /* All inlines must be possible. */ - for (e = node->callers; e; e = e->next_caller) - { - if (!can_inline_edge_p (e, true)) - return false; - if (!has_hot_call && cgraph_maybe_hot_edge_p (e)) - has_hot_call = 1; - } - + if (cgraph_for_node_and_aliases (node, check_callers, &has_hot_call, true)) + return false; if (!cold && !has_hot_call) return false; return true; @@ -1892,6 +1900,60 @@ flatten_function (struct cgraph_node *node, bool early) inline_update_overall_summary (node); } +/* Count number of callers of NODE and store it into DATA (that + points to int. Worker for cgraph_for_node_and_aliases. */ + +static bool +sum_callers (struct cgraph_node *node, void *data) +{ + struct cgraph_edge *e; + int *num_calls = (int *)data; + + for (e = node->callers; e; e = e->next_caller) + (*num_calls)++; + return false; +} + +/* Inline NODE to all callers. Worker for cgraph_for_node_and_aliases. + DATA points to number of calls originally found so we avoid infinite + recursion. */ + +static bool +inline_to_all_callers (struct cgraph_node *node, void *data) +{ + int *num_calls = (int *)data; + while (node->callers && !node->global.inlined_to) + { + struct cgraph_node *caller = node->callers->caller; + + if (dump_file) + { + fprintf (dump_file, + "\nInlining %s size %i.\n", + cgraph_node_name (node), + inline_summary (node)->size); + fprintf (dump_file, + " Called once from %s %i insns.\n", + cgraph_node_name (node->callers->caller), + inline_summary (node->callers->caller)->size); + } + + inline_call (node->callers, true, NULL, NULL, true); + if (dump_file) + fprintf (dump_file, + " Inlined into %s which now has %i size\n", + cgraph_node_name (caller), + inline_summary (caller)->size); + if (!(*num_calls)--) + { + if (dump_file) + fprintf (dump_file, "New calls found; giving up.\n"); + return true; + } + } + return false; +} + /* Decide on the inlining. We do so in the topological order to avoid expenses on updating data structures. */ @@ -2003,39 +2065,11 @@ ipa_inline (void) && want_inline_function_to_all_callers_p (node, cold)) { int num_calls = 0; - struct cgraph_edge *e; - for (e = node->callers; e; e = e->next_caller) - num_calls++; - while (node->callers && !node->global.inlined_to) - { - struct cgraph_node *caller = node->callers->caller; - - if (dump_file) - { - fprintf (dump_file, - "\nInlining %s size %i.\n", - cgraph_node_name (node), - inline_summary (node)->size); - fprintf (dump_file, - " Called once from %s %i insns.\n", - cgraph_node_name (node->callers->caller), - inline_summary (node->callers->caller)->size); - } - - inline_call (node->callers, true, NULL, NULL, true); - remove_functions = true; - if (dump_file) - fprintf (dump_file, - " Inlined into %s which now has %i size\n", - cgraph_node_name (caller), - inline_summary (caller)->size); - if (!num_calls--) - { - if (dump_file) - fprintf (dump_file, "New calls found; giving up.\n"); - break; - } - } + cgraph_for_node_and_aliases (node, sum_callers, + &num_calls, true); + cgraph_for_node_and_aliases (node, inline_to_all_callers, + &num_calls, true); + remove_functions = true; } } } diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c index cb42c8f0f45..424e4a6b6fe 100644 --- a/gcc/ipa-profile.c +++ b/gcc/ipa-profile.c @@ -17,6 +17,33 @@ 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/>. */ +/* ipa-profile pass implements the following analysis propagating profille + inter-procedurally. + + - Count histogram construction. This is a histogram analyzing how much + time is spent executing statements with a given execution count read + from profile feedback. This histogram is complette only with LTO, + otherwise it contains information only about the current unit. + + Similar histogram is also estimated by coverage runtime. This histogram + is not dependent on LTO, but it suffers from various defects; first + gcov runtime is not weighting individual basic block by estimated execution + time and second the merging of multiple runs makes assumption that the + histogram distribution did not change. Consequentely histogram constructed + here may be more precise. + + The information is used to set hot/cold thresholds. + - Next speculative indirect call resolution is performed: the local + profile pass assigns profile-id to each function and provide us with a + histogram specifying the most common target. We look up the callgraph + node corresponding to the target and produce a speculative call. + + This call may or may not survive through IPA optimization based on decision + of inliner. + - Finally we propagate the following flags: unlikely executed, executed + once, executed at startup and executed at exit. These flags are used to + control code size/performance threshold and and code placement (by producing + .text.unlikely/.text.hot/.text.startup/.text.exit subsections). */ #include "config.h" #include "system.h" #include "coretypes.h" @@ -301,6 +328,18 @@ ipa_propagate_frequency_1 (struct cgraph_node *node, void *data) d->only_called_at_startup = 0; d->only_called_at_exit &= edge->caller->only_called_at_exit; } + + /* When profile feedback is available, do not try to propagate too hard; + counts are already good guide on function frequencies and roundoff + errors can make us to push function into unlikely section even when + it is executed by the train run. Transfer the function only if all + callers are unlikely executed. */ + if (profile_info && flag_branch_probabilities + && (edge->caller->frequency != NODE_FREQUENCY_UNLIKELY_EXECUTED + || (edge->caller->global.inlined_to + && edge->caller->global.inlined_to->frequency + != NODE_FREQUENCY_UNLIKELY_EXECUTED))) + d->maybe_unlikely_executed = false; if (!edge->frequency) continue; switch (edge->caller->frequency) @@ -332,6 +371,24 @@ ipa_propagate_frequency_1 (struct cgraph_node *node, void *data) return edge != NULL; } +/* Return ture if NODE contains hot calls. */ + +bool +contains_hot_call_p (struct cgraph_node *node) +{ + struct cgraph_edge *e; + for (e = node->callees; e; e = e->next_callee) + if (cgraph_maybe_hot_edge_p (e)) + return true; + else if (!e->inline_failed + && contains_hot_call_p (e->callee)) + return true; + for (e = node->indirect_calls; e; e = e->next_callee) + if (cgraph_maybe_hot_edge_p (e)) + return true; + return false; +} + /* See if the frequency of NODE can be updated based on frequencies of its callers. */ bool @@ -343,6 +400,7 @@ ipa_propagate_frequency (struct cgraph_node *node) /* We can not propagate anything useful about externally visible functions nor about virtuals. */ if (!node->local.local + || node->symbol.alias || (flag_devirtualize && DECL_VIRTUAL_P (node->symbol.decl))) return false; gcc_assert (node->symbol.analyzed); @@ -369,6 +427,36 @@ ipa_propagate_frequency (struct cgraph_node *node) cgraph_node_name (node)); changed = true; } + + /* With profile we can decide on hot/normal based on count. */ + if (node->count) + { + bool hot = false; + if (node->count >= get_hot_bb_threshold ()) + hot = true; + if (!hot) + hot |= contains_hot_call_p (node); + if (hot) + { + if (node->frequency != NODE_FREQUENCY_HOT) + { + if (dump_file) + fprintf (dump_file, "Node %s promoted to hot.\n", + cgraph_node_name (node)); + node->frequency = NODE_FREQUENCY_HOT; + return true; + } + return false; + } + else if (node->frequency == NODE_FREQUENCY_HOT) + { + if (dump_file) + fprintf (dump_file, "Node %s reduced to normal.\n", + cgraph_node_name (node)); + node->frequency = NODE_FREQUENCY_NORMAL; + changed = true; + } + } /* These come either from profile or user hints; never update them. */ if (node->frequency == NODE_FREQUENCY_HOT || node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED) @@ -537,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-prop.c b/gcc/ipa-prop.c index 3b75b4a485e..24019655ad7 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "cgraph.h" #include "ipa-prop.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "tree-inline.h" #include "ipa-inline.h" @@ -1551,6 +1551,8 @@ ipa_compute_jump_functions_for_edge (struct param_analysis_info *parms_ainfo, return; vec_safe_grow_cleared (args->jump_functions, arg_num); + if (gimple_call_internal_p (call)) + return; if (ipa_func_spec_opts_forbid_analysis_p (cs->caller)) return; @@ -2496,23 +2498,29 @@ ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg, } /* Remove a reference to SYMBOL from the list of references of a node given by - reference description RDESC. */ + reference description RDESC. Return true if the reference has been + successfully found and removed. */ -static void +static bool remove_described_reference (symtab_node symbol, struct ipa_cst_ref_desc *rdesc) { struct ipa_ref *to_del; struct cgraph_edge *origin; origin = rdesc->cs; + if (!origin) + return false; to_del = ipa_find_reference ((symtab_node) origin->caller, symbol, origin->call_stmt, origin->lto_stmt_uid); - gcc_assert (to_del); + if (!to_del) + return false; + ipa_remove_reference (to_del); if (dump_file) fprintf (dump_file, "ipa-prop: Removed a reference from %s/%i to %s.\n", xstrdup (cgraph_node_name (origin->caller)), origin->caller->symbol.order, xstrdup (symtab_node_name (symbol))); + return true; } /* If JFUNC has a reference description with refcount different from @@ -2529,6 +2537,45 @@ jfunc_rdesc_usable (struct ipa_jump_func *jfunc) return NULL; } +/* If the value of constant jump function JFUNC is an address of a function + declaration, return the associated call graph node. Otherwise return + NULL. */ + +static cgraph_node * +cgraph_node_for_jfunc (struct ipa_jump_func *jfunc) +{ + gcc_checking_assert (jfunc->type == IPA_JF_CONST); + tree cst = ipa_get_jf_constant (jfunc); + if (TREE_CODE (cst) != ADDR_EXPR + || TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL) + return NULL; + + return cgraph_get_node (TREE_OPERAND (cst, 0)); +} + + +/* If JFUNC is a constant jump function with a usable rdesc, decrement its + refcount and if it hits zero, remove reference to SYMBOL from the caller of + the edge specified in the rdesc. Return false if either the symbol or the + reference could not be found, otherwise return true. */ + +static bool +try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc) +{ + struct ipa_cst_ref_desc *rdesc; + if (jfunc->type == IPA_JF_CONST + && (rdesc = jfunc_rdesc_usable (jfunc)) + && --rdesc->refcount == 0) + { + symtab_node symbol = (symtab_node) cgraph_node_for_jfunc (jfunc); + if (!symbol) + return false; + + return remove_described_reference (symbol, rdesc); + } + return true; +} + /* Try to find a destination for indirect edge IE that corresponds to a simple call or a call of a member function pointer and where the destination is a pointer formal parameter described by jump function JFUNC. If it can be @@ -2543,8 +2590,6 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie, struct cgraph_edge *cs; tree target; bool agg_contents = ie->indirect_info->agg_contents; - bool speculative = ie->speculative; - struct ipa_cst_ref_desc *rdesc; if (ie->indirect_info->agg_contents) target = ipa_find_agg_cst_for_param (&jfunc->agg, @@ -2556,12 +2601,17 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie, return NULL; cs = ipa_make_edge_direct_to_target (ie, target); - /* FIXME: speculative edges can be handled. */ - if (cs && !agg_contents && !speculative - && jfunc->type == IPA_JF_CONST - && (rdesc = jfunc_rdesc_usable (jfunc)) - && --rdesc->refcount == 0) - remove_described_reference ((symtab_node) cs->callee, rdesc); + if (cs && !agg_contents) + { + bool ok; + gcc_checking_assert (cs->callee + && (cs != ie + || jfunc->type != IPA_JF_CONST + || !cgraph_node_for_jfunc (jfunc) + || cs->callee == cgraph_node_for_jfunc (jfunc))); + ok = try_decrement_rdesc_refcount (jfunc); + gcc_checking_assert (ok); + } return cs; } @@ -2817,7 +2867,9 @@ propagate_controlled_uses (struct cgraph_edge *cs) if (n) { struct cgraph_node *clone; - remove_described_reference ((symtab_node) n, rdesc); + bool ok; + ok = remove_described_reference ((symtab_node) n, rdesc); + gcc_checking_assert (ok); clone = cs->caller; while (clone->global.inlined_to @@ -2960,9 +3012,28 @@ ipa_set_node_agg_value_chain (struct cgraph_node *node, static void ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED) { - /* During IPA-CP updating we can be called on not-yet analyze clones. */ + struct ipa_edge_args *args; + + /* During IPA-CP updating we can be called on not-yet analyzed clones. */ if (vec_safe_length (ipa_edge_args_vector) <= (unsigned)cs->uid) return; + + args = IPA_EDGE_REF (cs); + if (args->jump_functions) + { + struct ipa_jump_func *jf; + int i; + FOR_EACH_VEC_ELT (*args->jump_functions, i, jf) + { + struct ipa_cst_ref_desc *rdesc; + try_decrement_rdesc_refcount (jf); + if (jf->type == IPA_JF_CONST + && (rdesc = ipa_get_jf_constant_rdesc (jf)) + && rdesc->cs == cs) + rdesc->cs = NULL; + } + } + ipa_free_edge_args_substructures (IPA_EDGE_REF (cs)); } @@ -3007,6 +3078,24 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst, if (!src_rdesc) dst_jf->value.constant.rdesc = NULL; + else if (src->caller == dst->caller) + { + struct ipa_ref *ref; + symtab_node n = (symtab_node) cgraph_node_for_jfunc (src_jf); + gcc_checking_assert (n); + ref = ipa_find_reference ((symtab_node) src->caller, n, + src->call_stmt, src->lto_stmt_uid); + gcc_checking_assert (ref); + ipa_clone_ref (ref, (symtab_node) dst->caller, ref->stmt); + + gcc_checking_assert (ipa_refdesc_pool); + struct ipa_cst_ref_desc *dst_rdesc + = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool); + dst_rdesc->cs = dst; + dst_rdesc->refcount = src_rdesc->refcount; + dst_rdesc->next_duplicate = NULL; + dst_jf->value.constant.rdesc = dst_rdesc; + } else if (src_rdesc->cs == src) { struct ipa_cst_ref_desc *dst_rdesc; @@ -3447,7 +3536,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt, { tree expr, base, off; location_t loc; - unsigned int deref_align; + unsigned int deref_align = 0; bool deref_base = false; /* We create a new parameter out of the value of the old one, we can diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index 7a293657114..55b679d98a2 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -36,7 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-inline.h" #include "tree-pass.h" #include "langhooks.h" @@ -541,7 +541,8 @@ check_call (funct_state local, gimple call, bool ipa) } /* When not in IPA mode, we can still handle self recursion. */ - if (!ipa && callee_t == current_function_decl) + if (!ipa && callee_t + && recursive_call_p (current_function_decl, callee_t)) { if (dump_file) fprintf (dump_file, " Recursive call can loop.\n"); @@ -1079,8 +1080,9 @@ ignore_edge (struct cgraph_edge *e) } /* Return true if NODE is self recursive function. - ??? self recursive and indirectly recursive funcions should - be the same, so this function seems unnecessary. */ + Indirectly recursive functions appears as non-trivial strongly + connected components, so we need to care about self recursion + only. */ static bool self_recursive_p (struct cgraph_node *node) diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c index 3742474ed65..e6f19fdd1bf 100644 --- a/gcc/ipa-reference.c +++ b/gcc/ipa-reference.c @@ -41,7 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-inline.h" #include "tree-pass.h" #include "pointer-set.h" diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 5c3ee4fa2ce..322258a66f8 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -81,7 +81,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "cgraph.h" #include "ipa-prop.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "flags.h" #include "diagnostic.h" @@ -1222,6 +1222,9 @@ split_function (struct split_point *split_point) DECL_BUILT_IN_CLASS (node->symbol.decl) = NOT_BUILT_IN; DECL_FUNCTION_CODE (node->symbol.decl) = (enum built_in_function) 0; } + /* If the original function is declared inline, there is no point in issuing + a warning for the non-inlinable part. */ + DECL_NO_INLINE_WARNING_P (node->symbol.decl) = 1; cgraph_node_remove_callees (cur_node); ipa_remove_all_references (&cur_node->symbol.ref_list); if (!split_part_return_p) diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c index 0ea02eab8cc..12ce0ca0292 100644 --- a/gcc/ipa-utils.c +++ b/gcc/ipa-utils.c @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-inline.h" #include "dumpfile.h" #include "langhooks.h" @@ -791,3 +791,14 @@ ipa_merge_profiles (struct cgraph_node *dst, src->symbol.decl = oldsrcdecl; } +/* Return true if call to DEST is known to be self-recusive call withing FUNC. */ + +bool +recursive_call_p (tree func, tree dest) +{ + struct cgraph_node *dest_node = cgraph_get_create_node (dest); + struct cgraph_node *cnode = cgraph_get_create_node (func); + + return symtab_semantically_equivalent_p ((symtab_node)dest_node, + (symtab_node)cnode); +} diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h index 5619b5dcda3..d6f390daf15 100644 --- a/gcc/ipa-utils.h +++ b/gcc/ipa-utils.h @@ -46,6 +46,7 @@ int ipa_reverse_postorder (struct cgraph_node **); tree get_base_var (tree); void ipa_merge_profiles (struct cgraph_node *dst, struct cgraph_node *src); +bool recursive_call_p (tree, tree); /* In ipa-profile.c */ bool ipa_propagate_frequency (struct cgraph_node *node); diff --git a/gcc/ipa.c b/gcc/ipa.c index 37b6629b206..67b3bc0f07c 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -149,6 +149,84 @@ process_references (struct ipa_ref_list *list, } } +/* EDGE is an polymorphic call. If BEFORE_INLINING_P is set, mark + all its potential targets as reachable to permit later inlining if + devirtualization happens. After inlining still keep their declarations + around, so we can devirtualize to a direct call. + + Also try to make trivial devirutalization when no or only one target is + possible. */ + +static void +walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets, + struct cgraph_edge *edge, + symtab_node *first, + pointer_set_t *reachable, bool before_inlining_p) +{ + unsigned int i; + void *cache_token; + bool final; + vec <cgraph_node *>targets + = possible_polymorphic_call_targets + (edge, &final, &cache_token); + + if (!pointer_set_insert (reachable_call_targets, + cache_token)) + { + for (i = 0; i < targets.length(); i++) + { + struct cgraph_node *n = targets[i]; + + /* Do not bother to mark virtual methods in anonymous namespace; + either we will find use of virtual table defining it, or it is + unused. */ + if (TREE_CODE (TREE_TYPE (n->symbol.decl)) == METHOD_TYPE + && type_in_anonymous_namespace_p + (method_class_type (TREE_TYPE (n->symbol.decl)))) + continue; + + /* Prior inlining, keep alive bodies of possible targets for + devirtualization. */ + if (n->symbol.definition + && before_inlining_p) + pointer_set_insert (reachable, n); + + /* Even after inlining we want to keep the possible targets in the + boundary, so late passes can still produce direct call even if + the chance for inlining is lost. */ + enqueue_node ((symtab_node) n, first, reachable); + } + } + + /* Very trivial devirtualization; when the type is + final or anonymous (so we know all its derivation) + and there is only one possible virtual call target, + make the edge direct. */ + if (final) + { + if (targets.length() <= 1) + { + cgraph_node *target, *node = edge->caller; + if (targets.length () == 1) + target = targets[0]; + else + target = cgraph_get_create_node + (builtin_decl_implicit (BUILT_IN_UNREACHABLE)); + + if (dump_file) + fprintf (dump_file, + "Devirtualizing call in %s/%i to %s/%i\n", + cgraph_node_name (edge->caller), + edge->caller->symbol.order, + cgraph_node_name (target), target->symbol.order); + edge = cgraph_make_edge_direct (edge, target); + if (!inline_summary_vec && edge->call_stmt) + cgraph_redirect_edge_call_stmt_to_callee (edge); + else + inline_update_overall_summary (node); + } + } +} /* Perform reachability analysis and reclaim all unreachable nodes. @@ -214,7 +292,9 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) bool changed = false; struct pointer_set_t *reachable = pointer_set_create (); struct pointer_set_t *body_needed_for_clonning = pointer_set_create (); + struct pointer_set_t *reachable_call_targets = pointer_set_create (); + timevar_push (TV_IPA_UNREACHABLE); #ifdef ENABLE_CHECKING verify_symtab (); #endif @@ -238,10 +318,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) if (node->symbol.definition && !node->global.inlined_to && !node->symbol.in_other_partition - && (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node) - /* Keep around virtual functions for possible devirtualization. */ - || (before_inlining_p - && DECL_VIRTUAL_P (node->symbol.decl)))) + && !cgraph_can_remove_if_no_direct_calls_and_refs_p (node)) { gcc_assert (!node->global.inlined_to); pointer_set_insert (reachable, node); @@ -304,6 +381,19 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) if (!in_boundary_p) { struct cgraph_edge *e; + /* Keep alive possible targets for devirtualization. */ + if (optimize && flag_devirtualize) + { + struct cgraph_edge *next; + for (e = cnode->indirect_calls; e; e = next) + { + next = e->next_callee; + if (e->indirect_info->polymorphic) + walk_polymorphic_call_targets (reachable_call_targets, + e, &first, reachable, + before_inlining_p); + } + } for (e = cnode->callees; e; e = e->next_callee) { if (e->callee->symbol.definition @@ -449,6 +539,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) pointer_set_destroy (reachable); pointer_set_destroy (body_needed_for_clonning); + pointer_set_destroy (reachable_call_targets); /* Now update address_taken flags and try to promote functions to be local. */ if (file) @@ -483,6 +574,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) FOR_EACH_DEFINED_FUNCTION (node) ipa_propagate_frequency (node); + timevar_pop (TV_IPA_UNREACHABLE); return changed; } @@ -906,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/loop-init.c b/gcc/loop-init.c index 80c31ef70cd..d45f42d9153 100644 --- a/gcc/loop-init.c +++ b/gcc/loop-init.c @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "df.h" #include "ggc.h" -#include "tree-flow.h" +#include "tree-ssa.h" /* Apply FLAGS to the loop state. */ diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c index 2d8e918c43e..08a89e094fd 100644 --- a/gcc/loop-iv.c +++ b/gcc/loop-iv.c @@ -2671,11 +2671,11 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition, bound = GEN_INT (((unsigned HOST_WIDEST_INT) 1 << (size - 1 ) << 1) - 1); tmp1 = lowpart_subreg (mode, iv1.base, comp_mode); - tmp = simplify_gen_binary (UMOD, mode, tmp1, GEN_INT (d)); + tmp = simplify_gen_binary (UMOD, mode, tmp1, gen_int_mode (d, mode)); assumption = simplify_gen_relational (NE, SImode, mode, tmp, const0_rtx); desc->infinite = alloc_EXPR_LIST (0, assumption, desc->infinite); - tmp = simplify_gen_binary (UDIV, mode, tmp1, GEN_INT (d)); + tmp = simplify_gen_binary (UDIV, mode, tmp1, gen_int_mode (d, mode)); inv = inverse (s, size); tmp = simplify_gen_binary (MULT, mode, tmp, gen_int_mode (inv, mode)); desc->niter_expr = simplify_gen_binary (AND, mode, tmp, bound); diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c index 0b46f1d8399..b2587bb6aee 100644 --- a/gcc/loop-unroll.c +++ b/gcc/loop-unroll.c @@ -1160,8 +1160,7 @@ unroll_loop_runtime_iterations (struct loop *loop) the number of unrollings is a power of two, and thus this is correct even if there is overflow in the computation. */ niter = expand_simple_binop (desc->mode, AND, - niter, - GEN_INT (max_unroll), + niter, gen_int_mode (max_unroll, desc->mode), NULL_RTX, 0, OPTAB_LIB_WIDEN); init_code = get_insns (); @@ -1304,7 +1303,7 @@ unroll_loop_runtime_iterations (struct loop *loop) gcc_assert (!desc->const_iter); desc->niter_expr = simplify_gen_binary (UDIV, desc->mode, old_niter, - GEN_INT (max_unroll + 1)); + gen_int_mode (max_unroll + 1, desc->mode)); loop->nb_iterations_upper_bound = wi::udiv_trunc (loop->nb_iterations_upper_bound, max_unroll + 1); if (loop->any_estimate) diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index ee72f7f0985..f9652c773cd 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -2837,7 +2837,9 @@ emit_inc (enum reg_class new_rclass, rtx in, rtx value, int inc_amount) if (plus_p) { if (CONST_INT_P (inc)) - emit_insn (gen_add2_insn (result, GEN_INT (-INTVAL (inc)))); + emit_insn (gen_add2_insn (result, + gen_int_mode (-INTVAL (inc), + GET_MODE (result)))); else emit_insn (gen_sub2_insn (result, inc)); } @@ -3307,15 +3309,19 @@ curr_insn_transform (void) reg, we might improve the code through inheritance. If it does not get a hard register we coalesce memory/memory moves later. Ignore move insns to avoid cycling. */ - if (0 && ! lra_simple_p + if (! lra_simple_p && lra_undo_inheritance_iter < LRA_MAX_INHERITANCE_PASSES && goal_alt[i] != NO_REGS && REG_P (op) && (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER + && ! lra_former_scratch_p (regno) && reg_renumber[regno] < 0 && (curr_insn_set == NULL_RTX - || !(REG_P (SET_SRC (curr_insn_set)) - || MEM_P (SET_SRC (curr_insn_set)) - || GET_CODE (SET_SRC (curr_insn_set)) == SUBREG))) + || !((REG_P (SET_SRC (curr_insn_set)) + || MEM_P (SET_SRC (curr_insn_set)) + || GET_CODE (SET_SRC (curr_insn_set)) == SUBREG) + && (REG_P (SET_DEST (curr_insn_set)) + || MEM_P (SET_DEST (curr_insn_set)) + || GET_CODE (SET_DEST (curr_insn_set)) == SUBREG)))) optional_p = true; else continue; @@ -4329,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. */ @@ -5439,7 +5447,7 @@ remove_inheritance_pseudos (bitmap remove_pseudos) static bool undo_optional_reloads (void) { - bool change_p; + bool change_p, keep_p; unsigned int regno, uid; bitmap_iterator bi, bi2; rtx insn, set, src, dest; @@ -5448,27 +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) - EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi2) + { + 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. */ + || 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) + { + 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) { - 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 (src) == regno - && lra_reg_info[regno].restore_regno != (int) REGNO (dest)) - || (REGNO (dest) == regno - && lra_reg_info[regno].restore_regno != (int) REGNO (src))) - { - /* Optional reload was inherited. Keep it. */ - bitmap_clear_bit (&removed_optional_reload_pseudos, regno); - if (lra_dump_file != NULL) - fprintf (lra_dump_file, "Keep optional reload reg %d\n", regno); - } + 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) @@ -5550,7 +5575,11 @@ lra_undo_inheritance (void) if (lra_reg_info[regno].restore_regno >= 0) { n_all_inherit++; - if (reg_renumber[regno] < 0) + if (reg_renumber[regno] < 0 + /* If the original pseudo changed its allocation, just + removing inheritance is dangerous as for changing + allocation we used shorter live-ranges. */ + && reg_renumber[lra_reg_info[regno].restore_regno] < 0) bitmap_set_bit (&remove_pseudos, regno); else n_inherit++; diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c index a59ab6eacca..f2a57511cbd 100644 --- a/gcc/lra-eliminations.c +++ b/gcc/lra-eliminations.c @@ -745,13 +745,42 @@ mark_not_eliminable (rtx x) +#ifdef HARD_FRAME_POINTER_REGNUM + +/* Find offset equivalence note for reg WHAT in INSN and return the + found elmination offset. If the note is not found, return NULL. + Remove the found note. */ +static rtx +remove_reg_equal_offset_note (rtx insn, rtx what) +{ + rtx link, *link_loc; + + for (link_loc = ®_NOTES (insn); + (link = *link_loc) != NULL_RTX; + link_loc = &XEXP (link, 1)) + if (REG_NOTE_KIND (link) == REG_EQUAL + && GET_CODE (XEXP (link, 0)) == PLUS + && XEXP (XEXP (link, 0), 0) == what + && CONST_INT_P (XEXP (XEXP (link, 0), 1))) + { + *link_loc = XEXP (link, 1); + return XEXP (XEXP (link, 0), 1); + } + return NULL_RTX; +} + +#endif + /* Scan INSN and eliminate all eliminable hard registers in it. If REPLACE_P is true, do the replacement destructively. Also delete the insn as dead it if it is setting an eliminable register. If REPLACE_P is false, just update the offsets while keeping the - base register the same. */ + base register the same. Attach the note about used elimination for + insns setting frame pointer to update elimination easy (without + parsing already generated elimination insns to find offset + previously used) in future. */ static void eliminate_regs_in_insn (rtx insn, bool replace_p) @@ -790,59 +819,44 @@ eliminate_regs_in_insn (rtx insn, bool replace_p) if (ep->from == FRAME_POINTER_REGNUM && ep->to == HARD_FRAME_POINTER_REGNUM) { + rtx src = SET_SRC (old_set); + rtx off = remove_reg_equal_offset_note (insn, ep->to_rtx); + if (replace_p) { SET_DEST (old_set) = ep->to_rtx; lra_update_insn_recog_data (insn); return; } - else + else if (off != NULL_RTX + || src == ep->to_rtx + || (GET_CODE (src) == PLUS + && XEXP (src, 1) == ep->to_rtx + && CONST_INT_P (XEXP (src, 1)))) { - rtx base = SET_SRC (old_set); - HOST_WIDE_INT offset = 0; - rtx base_insn = insn; - - while (base != ep->to_rtx) + HOST_WIDE_INT offset = (off != NULL_RTX + ? INTVAL (off) + : src == ep->to_rtx + ? 0 : INTVAL (XEXP (src, 1))); + + offset -= (ep->offset - ep->previous_offset); + src = plus_constant (Pmode, ep->to_rtx, offset); + + /* First see if this insn remains valid when we make + the change. If not, keep the INSN_CODE the same + and let the constraint pass fit it up. */ + validate_change (insn, &SET_SRC (old_set), src, 1); + validate_change (insn, &SET_DEST (old_set), + ep->from_rtx, 1); + if (! apply_change_group ()) { - rtx prev_insn, prev_set; - - if (GET_CODE (base) == PLUS && CONST_INT_P (XEXP (base, 1))) - { - offset += INTVAL (XEXP (base, 1)); - base = XEXP (base, 0); - } - else if ((prev_insn = prev_nonnote_insn (base_insn)) != 0 - && (prev_set = single_set (prev_insn)) != 0 - && rtx_equal_p (SET_DEST (prev_set), base)) - { - base = SET_SRC (prev_set); - base_insn = prev_insn; - } - else - break; - } - - if (base == ep->to_rtx) - { - rtx src; - - offset -= (ep->offset - ep->previous_offset); - src = plus_constant (Pmode, ep->to_rtx, offset); - - /* First see if this insn remains valid when we make - the change. If not, keep the INSN_CODE the same - and let the constraint pass fit it up. */ - validate_change (insn, &SET_SRC (old_set), src, 1); - validate_change (insn, &SET_DEST (old_set), - ep->from_rtx, 1); - if (! apply_change_group ()) - { - SET_SRC (old_set) = src; - SET_DEST (old_set) = ep->from_rtx; - } - lra_update_insn_recog_data (insn); - return; + SET_SRC (old_set) = src; + SET_DEST (old_set) = ep->from_rtx; } + lra_update_insn_recog_data (insn); + /* Add offset note for future updates. */ + add_reg_note (insn, REG_EQUAL, src); + return; } 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 ef69526b0ec..f5aab173927 100644 --- a/gcc/lra.c +++ b/gcc/lra.c @@ -2365,8 +2365,10 @@ lra (FILE *f) if (! live_p) lra_clear_live_ranges (); } - bitmap_clear (&lra_optional_reload_pseudos); } + /* 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/lto-cgraph.c b/gcc/lto-cgraph.c index fcba1b92acd..952588dba2f 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "hashtab.h" #include "langhooks.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cgraph.h" #include "function.h" #include "ggc.h" @@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see #include "profile.h" #include "context.h" #include "pass_manager.h" +#include "ipa-utils.h" static void output_cgraph_opt_summary (void); static void input_cgraph_opt_summary (vec<symtab_node> nodes); @@ -766,6 +767,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder) int i; lto_symtab_encoder_t encoder; lto_symtab_encoder_iterator lsei; + struct pointer_set_t *reachable_call_targets = pointer_set_create (); encoder = lto_symtab_encoder_new (false); @@ -837,9 +839,40 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder) add_node_to (encoder, callee, false); } } + /* Add all possible targets for late devirtualization. */ + if (flag_devirtualize) + for (edge = node->indirect_calls; edge; edge = edge->next_callee) + if (edge->indirect_info->polymorphic) + { + unsigned int i; + void *cache_token; + bool final; + vec <cgraph_node *>targets + = possible_polymorphic_call_targets + (edge, &final, &cache_token); + if (!pointer_set_insert (reachable_call_targets, + cache_token)) + { + for (i = 0; i < targets.length(); i++) + { + struct cgraph_node *callee = targets[i]; + + /* Adding an external declarations into the unit serves + no purpose and just increases its boundary. */ + if (callee->symbol.definition + && !lto_symtab_encoder_in_partition_p + (encoder, (symtab_node)callee)) + { + gcc_assert (!callee->global.inlined_to); + add_node_to (encoder, callee, false); + } + } + } + } } - lto_symtab_encoder_delete (in_encoder); - return encoder; + lto_symtab_encoder_delete (in_encoder); + pointer_set_destroy (reachable_call_targets); + return encoder; } /* Output the part of the symtab in SET and VSET. */ diff --git a/gcc/lto-section-in.c b/gcc/lto-section-in.c index 5821030d4cf..d96cdb47548 100644 --- a/gcc/lto-section-in.c +++ b/gcc/lto-section-in.c @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "input.h" #include "hashtab.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cgraph.h" #include "function.h" #include "ggc.h" diff --git a/gcc/lto-section-out.c b/gcc/lto-section-out.c index 8145ec33354..59eed716630 100644 --- a/gcc/lto-section-out.c +++ b/gcc/lto-section-out.c @@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "input.h" #include "hashtab.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cgraph.h" #include "function.h" #include "ggc.h" diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 453c2445073..ae418efefdf 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "input.h" #include "hashtab.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "cgraph.h" #include "function.h" @@ -1010,6 +1010,7 @@ input_function (tree fn_decl, struct data_in *data_in, free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); free (stmts); + pop_cfun (); } @@ -1098,8 +1099,6 @@ lto_read_body (struct lto_file_decl_data *file_data, struct cgraph_node *node, /* Restore decl state */ file_data->current_decl_state = file_data->global_decl_state; - - pop_cfun (); } lto_data_in_delete (data_in); diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index 9100eb050af..3b8f077a52c 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -31,7 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "input.h" #include "hashtab.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "cgraph.h" #include "function.h" @@ -1997,8 +1997,7 @@ lto_output (void) cgraph_node *node = dyn_cast <cgraph_node> (snode); if (node && lto_symtab_encoder_encode_body_p (encoder, node) - && !node->symbol.alias - && !node->thunk.thunk_p) + && !node->symbol.alias) { #ifdef ENABLE_CHECKING gcc_assert (!bitmap_bit_p (output, DECL_UID (node->symbol.decl))); diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c index e7b66c167b5..cdc75de9bae 100644 --- a/gcc/lto-streamer.c +++ b/gcc/lto-streamer.c @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "tree.h" #include "gimple.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "diagnostic-core.h" #include "bitmap.h" #include "vec.h" diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 4a2ea0b2993..13a9593a866 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -903,7 +903,6 @@ lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder); extern void lto_symtab_merge_decls (void); extern void lto_symtab_merge_symbols (void); extern tree lto_symtab_prevailing_decl (tree decl); -extern GTY(()) vec<tree, va_gc> *lto_global_var_decls; /* In lto-opts.c. */ diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index fe8e4638a50..8ac0f8d60a4 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,13 @@ +2013-09-06 Richard Biener <rguenther@suse.de> + + * lto-symtab.c: Move from gcc/ + * lto.h: Include vec.h. + (lto_global_var_decls): Declare. + * lto.c (lto_global_var_decls): Move definition here. + * Make-lang.in (LTO_OBJS): Add lto-symtab.o. + (lto-symtab.o): Add. + * config-lang.in (gtfiles): Add lto.h. + 2013-08-31 Jan Hubicka <jh@suse.cz> * lto.c (mentions_vars_p_field_decl, lto_fixup_prevailing_decls): diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in index 1acd176dd89..c67c58e7f83 100644 --- a/gcc/lto/Make-lang.in +++ b/gcc/lto/Make-lang.in @@ -22,7 +22,7 @@ # The name of the LTO compiler. LTO_EXE = lto1$(exeext) # The LTO-specific object files inclued in $(LTO_EXE). -LTO_OBJS = lto/lto-lang.o lto/lto.o lto/lto-object.o attribs.o lto/lto-partition.o +LTO_OBJS = lto/lto-lang.o lto/lto.o lto/lto-object.o attribs.o lto/lto-partition.o lto/lto-symtab.o LTO_H = lto/lto.h $(HASHTAB_H) LINKER_PLUGIN_API_H = $(srcdir)/../include/plugin-api.h LTO_TREE_H = lto/lto-tree.h $(LINKER_PLUGIN_API_H) @@ -95,6 +95,9 @@ lto/lto-partition.o: lto/lto-partition.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ lto/lto-object.o: lto/lto-object.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(DIAGNOSTIC_CORE_H) $(LTO_H) $(TM_H) $(LTO_STREAMER_H) \ ../include/simple-object.h +lto/lto-symtab.o: lto/lto-symtab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TREE_H) $(GIMPLE_H) $(GGC_H) $(HASHTAB_H) \ + $(LTO_STREAMER_H) $(LINKER_PLUGIN_API_H) # LTO testing is done as part of C/C++/Fortran etc. testing. check-lto: diff --git a/gcc/lto/config-lang.in b/gcc/lto/config-lang.in index 266446de6d2..9217c5dfbaa 100644 --- a/gcc/lto/config-lang.in +++ b/gcc/lto/config-lang.in @@ -21,7 +21,7 @@ language="lto" compilers="lto1\$(exeext)" stagestuff="lto1\$(exeext)" -gtfiles="\$(srcdir)/lto/lto-tree.h \$(srcdir)/lto/lto-lang.c \$(srcdir)/lto/lto.c" +gtfiles="\$(srcdir)/lto/lto-tree.h \$(srcdir)/lto/lto-lang.c \$(srcdir)/lto/lto.c \$(srcdir)/lto/lto.h" # LTO is a special front end. From a user's perspective it is not # really a language, but a middle end feature. However, the GIMPLE diff --git a/gcc/lto-symtab.c b/gcc/lto/lto-symtab.c index 76e94400f6a..b1b7731c830 100644 --- a/gcc/lto-symtab.c +++ b/gcc/lto/lto-symtab.c @@ -30,9 +30,6 @@ along with GCC; see the file COPYING3. If not see #include "lto-streamer.h" #include "ipa-utils.h" -/* Vector to keep track of external variables we've seen so far. */ -vec<tree, va_gc> *lto_global_var_decls; - /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging all edges and removing the old node. */ diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 1b755acc4a2..92badd52588 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -49,6 +49,9 @@ along with GCC; see the file COPYING3. If not see #include "context.h" #include "pass_manager.h" +/* Vector to keep track of external variables we've seen so far. */ +vec<tree, va_gc> *lto_global_var_decls; + static GTY(()) tree first_personality_decl; /* Returns a hash code for P. */ diff --git a/gcc/lto/lto.h b/gcc/lto/lto.h index 2699459dc18..1734fe5def1 100644 --- a/gcc/lto/lto.h +++ b/gcc/lto/lto.h @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #define LTO_H #include "hashtab.h" +#include "vec.h" /* A file. */ typedef struct lto_file_struct @@ -40,6 +41,9 @@ extern tree lto_eh_personality (void); extern void lto_main (void); extern void lto_read_all_file_options (void); +/* In lto-symtab.c */ +extern GTY(()) vec<tree, va_gc> *lto_global_var_decls; + /* In lto-elf.c or lto-coff.c */ extern lto_file *lto_obj_file_open (const char *filename, bool writable); extern void lto_obj_file_close (lto_file *file); diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c index 0df5fb61a25..3ad2ec77f1e 100644 --- a/gcc/modulo-sched.c +++ b/gcc/modulo-sched.c @@ -1148,8 +1148,9 @@ generate_prolog_epilog (partial_schedule_ptr ps, struct loop *loop, generate_prolog_epilog function. */ rtx sub_reg = NULL_RTX; - sub_reg = expand_simple_binop (GET_MODE (count_reg), MINUS, - count_reg, GEN_INT (last_stage), + sub_reg = expand_simple_binop (GET_MODE (count_reg), MINUS, count_reg, + gen_int_mode (last_stage, + GET_MODE (count_reg)), count_reg, 1, OPTAB_DIRECT); gcc_assert (REG_P (sub_reg)); if (REGNO (sub_reg) != REGNO (count_reg)) @@ -1715,8 +1716,9 @@ sms_schedule (void) /* case the BCT count is not known , Do loop-versioning */ if (count_reg && ! count_init) { - rtx comp_rtx = gen_rtx_fmt_ee (GT, VOIDmode, count_reg, - GEN_INT(stage_count)); + rtx comp_rtx = gen_rtx_GT (VOIDmode, count_reg, + gen_int_mode (stage_count, + GET_MODE (count_reg))); unsigned prob = (PROB_SMS_ENOUGH_ITERATIONS * REG_BR_PROB_BASE) / 100; diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 30b6d17d82b..0cdd7616490 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,11 @@ +2013-09-14 Iain Sandoe <iain@codesourcery.com> + + PR target/48094 + * objc-next-runtime-abi-01.c (generate_objc_image_info): Remove. + (objc_generate_v1_next_metadata): Remove generation of ImageInfo. + * objc-next-runtime-abi-02.c (generate_v2_objc_image_info): Remove. + (objc_generate_v2_next_metadata): Remove generation of ImageInfo. + 2013-07-21 Ondřej BÃÂlka <neleai@seznam.cz> * objc-act.c: Fix typos. diff --git a/gcc/objc/objc-next-runtime-abi-01.c b/gcc/objc/objc-next-runtime-abi-01.c index 0a042ac4bf0..5e896eebc19 100644 --- a/gcc/objc/objc-next-runtime-abi-01.c +++ b/gcc/objc/objc-next-runtime-abi-01.c @@ -2332,36 +2332,6 @@ generate_classref_translation_entry (tree chain) return; } - -/* The Fix-and-Continue functionality available in Mac OS X 10.3 and - later requires that ObjC translation units participating in F&C be - specially marked. The following routine accomplishes this. */ - -/* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */ - -static void -generate_objc_image_info (void) -{ - tree decl; - int flags - = ((flag_replace_objc_classes && imp_count ? 1 : 0) - | (flag_objc_gc ? 2 : 0)); - vec<constructor_elt, va_gc> *v = NULL; - tree array_type; - - array_type = build_sized_array_type (integer_type_node, 2); - - decl = start_var_decl (array_type, "_OBJC_ImageInfo"); - - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, flags)); - /* The runtime wants this and refers to it in a manner hidden from the compiler. - So we must force the output. */ - DECL_PRESERVE_P (decl) = 1; - OBJCMETA (decl, objc_meta, meta_info); - finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v)); -} - static void objc_generate_v1_next_metadata (void) { @@ -2412,9 +2382,6 @@ objc_generate_v1_next_metadata (void) attr = build_tree_list (objc_meta, meta_modules); build_module_descriptor (vers, attr); - /* This conveys information on GC usage and zero-link. */ - generate_objc_image_info (); - /* Dump the class references. This forces the appropriate classes to be linked into the executable image, preserving unix archive semantics. */ diff --git a/gcc/objc/objc-next-runtime-abi-02.c b/gcc/objc/objc-next-runtime-abi-02.c index 0138650d7db..0f158e13f0b 100644 --- a/gcc/objc/objc-next-runtime-abi-02.c +++ b/gcc/objc/objc-next-runtime-abi-02.c @@ -3331,31 +3331,6 @@ build_v2_ivar_offset_ref_table (void) finish_var_decl (ref->decl, ref->offset); } -/* static int _OBJC_IMAGE_INFO[2] = { 0, 16 | flags }; */ - -static void -generate_v2_objc_image_info (void) -{ - tree decl, array_type; - vec<constructor_elt, va_gc> *v = NULL; - int flags = - ((flag_replace_objc_classes && imp_count ? 1 : 0) - | (flag_objc_gc ? 2 : 0)); - - flags |= 16; - - array_type = build_sized_array_type (integer_type_node, 2); - - decl = start_var_decl (array_type, "_OBJC_ImageInfo"); - - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node); - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, flags)); - /* The Runtime wants this. */ - DECL_PRESERVE_P (decl) = 1; - OBJCMETA (decl, objc_meta, meta_info); - finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v)); -} - static void objc_generate_v2_next_metadata (void) { @@ -3407,9 +3382,6 @@ objc_generate_v2_next_metadata (void) build_v2_address_table (nonlazy_category_list, "_OBJC_NonLazyCategoryList$", meta_label_nonlazy_categorylist); - /* This conveys information on GC usage and zero-link. */ - generate_v2_objc_image_info (); - /* Generate catch objects for eh, if any are needed. */ build_v2_eh_catch_objects (); diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 68cdeea9287..6d3f94dcee2 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-inline.h" #include "langhooks.h" #include "diagnostic-core.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "flags.h" #include "function.h" #include "expr.h" @@ -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; } @@ -942,7 +943,7 @@ build_outer_var_ref (tree var, omp_context *ctx) if (ctx->outer && is_taskreg_ctx (ctx)) x = lookup_decl (var, ctx->outer); else if (ctx->outer) - x = maybe_lookup_decl (var, ctx->outer); + x = maybe_lookup_decl_in_outer_ctx (var, ctx); if (x == NULL_TREE) x = var; } @@ -2303,8 +2304,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 (); @@ -2771,6 +2773,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); @@ -5681,10 +5686,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; @@ -5863,8 +5869,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/optabs.c b/gcc/optabs.c index b47692146a5..8b45195f24a 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -1566,7 +1566,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1, newop1 = negate_rtx (GET_MODE (op1), op1); else newop1 = expand_binop (GET_MODE (op1), sub_optab, - GEN_INT (bits), op1, + gen_int_mode (bits, GET_MODE (op1)), op1, NULL_RTX, unsignedp, OPTAB_DIRECT); temp = expand_binop_directly (mode, otheroptab, op0, newop1, @@ -2542,10 +2542,12 @@ widen_leading (enum machine_mode mode, rtx op0, rtx target, optab unoptab) temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX, unoptab != clrsb_optab); if (temp != 0) - temp = expand_binop (wider_mode, sub_optab, temp, - GEN_INT (GET_MODE_PRECISION (wider_mode) - - GET_MODE_PRECISION (mode)), - target, true, OPTAB_DIRECT); + temp = expand_binop + (wider_mode, sub_optab, temp, + gen_int_mode (GET_MODE_PRECISION (wider_mode) + - GET_MODE_PRECISION (mode), + wider_mode), + target, true, OPTAB_DIRECT); if (temp == 0) delete_insns_since (last); @@ -2604,7 +2606,7 @@ expand_doubleword_clz (enum machine_mode mode, rtx op0, rtx target) if (!temp) goto fail; temp = expand_binop (word_mode, add_optab, temp, - GEN_INT (GET_MODE_BITSIZE (word_mode)), + gen_int_mode (GET_MODE_BITSIZE (word_mode), word_mode), result, true, OPTAB_DIRECT); if (!temp) goto fail; @@ -2760,7 +2762,8 @@ expand_ctz (enum machine_mode mode, rtx op0, rtx target) if (temp) temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true); if (temp) - temp = expand_binop (mode, sub_optab, GEN_INT (GET_MODE_PRECISION (mode) - 1), + temp = expand_binop (mode, sub_optab, + gen_int_mode (GET_MODE_PRECISION (mode) - 1, mode), temp, target, true, OPTAB_DIRECT); if (temp == 0) @@ -2841,7 +2844,7 @@ expand_ffs (enum machine_mode mode, rtx op0, rtx target) /* temp now has a value in the range -1..bitsize-1. ffs is supposed to produce a value in the range 0..bitsize. */ - temp = expand_binop (mode, add_optab, temp, GEN_INT (1), + temp = expand_binop (mode, add_optab, temp, gen_int_mode (1, mode), target, false, OPTAB_DIRECT); if (!temp) goto fail; @@ -3311,10 +3314,12 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target, result. Similarly for clrsb. */ if ((unoptab == clz_optab || unoptab == clrsb_optab) && temp != 0) - temp = expand_binop (wider_mode, sub_optab, temp, - GEN_INT (GET_MODE_PRECISION (wider_mode) - - GET_MODE_PRECISION (mode)), - target, true, OPTAB_DIRECT); + temp = expand_binop + (wider_mode, sub_optab, temp, + gen_int_mode (GET_MODE_PRECISION (wider_mode) + - GET_MODE_PRECISION (mode), + wider_mode), + target, true, OPTAB_DIRECT); /* Likewise for bswap. */ if (unoptab == bswap_optab && temp != 0) 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/passes.c b/gcc/passes.c index 5b4975267eb..f3f85fd3b94 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -61,7 +61,7 @@ along with GCC; see the file COPYING3. If not see #include "coverage.h" #include "value-prof.h" #include "tree-inline.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "tree-dump.h" #include "df.h" diff --git a/gcc/passes.def b/gcc/passes.def index 736a28b64dc..84eb3f37e57 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -239,7 +239,13 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_vrp); NEXT_PASS (pass_cd_dce); NEXT_PASS (pass_tracer); - + NEXT_PASS (pass_dse); + NEXT_PASS (pass_forwprop); + NEXT_PASS (pass_phiopt); + NEXT_PASS (pass_fold_builtins); + NEXT_PASS (pass_optimize_widening_mul); + NEXT_PASS (pass_tail_calls); + NEXT_PASS (pass_rename_ssa_copies); /* FIXME: If DCE is not run before checking for uninitialized uses, we may get false warnings (e.g., testsuite/gcc.dg/uninit-5.c). However, this also causes us to misdiagnose cases that should be @@ -249,14 +255,10 @@ along with GCC; see the file COPYING3. If not see account for the predicates protecting the set and the use of each variable. Using a representation like Gated Single Assignment may help. */ + /* Split critical edges before late uninit warning to reduce the + number of false positives from it. */ + NEXT_PASS (pass_split_crit_edges); NEXT_PASS (pass_late_warn_uninitialized); - NEXT_PASS (pass_dse); - NEXT_PASS (pass_forwprop); - NEXT_PASS (pass_phiopt); - NEXT_PASS (pass_fold_builtins); - NEXT_PASS (pass_optimize_widening_mul); - NEXT_PASS (pass_tail_calls); - NEXT_PASS (pass_rename_ssa_copies); NEXT_PASS (pass_uncprop); NEXT_PASS (pass_local_pure_const); POP_INSERT_PASSES () @@ -282,6 +284,9 @@ along with GCC; see the file COPYING3. If not see /* ??? We do want some kind of loop invariant motion, but we possibly need to adjust LIM to be more friendly towards preserving accurate debug information here. */ + /* Split critical edges before late uninit warning to reduce the + number of false positives from it. */ + NEXT_PASS (pass_split_crit_edges); NEXT_PASS (pass_late_warn_uninitialized); NEXT_PASS (pass_uncprop); NEXT_PASS (pass_local_pure_const); diff --git a/gcc/plugin.c b/gcc/plugin.c index b269dfa3971..3b39a0b30d9 100644 --- a/gcc/plugin.c +++ b/gcc/plugin.c @@ -241,16 +241,13 @@ parse_plugin_arg_opt (const char *arg) } else if (*ptr == '=') { - if (key_parsed) - { - error ("malformed option -fplugin-arg-%s (multiple '=' signs)", - arg); - return; - } - key_len = len; - len = 0; - value_start = ptr + 1; - key_parsed = true; + if (!key_parsed) + { + key_len = len; + len = 0; + value_start = ptr + 1; + key_parsed = true; + } continue; } else diff --git a/gcc/predict.c b/gcc/predict.c index 986284744bd..18e044a04b0 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -50,7 +50,7 @@ along with GCC; see the file COPYING3. If not see #include "params.h" #include "target.h" #include "cfgloop.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "ggc.h" #include "tree-pass.h" #include "tree-scalar-evolution.h" @@ -2852,13 +2852,14 @@ compute_function_frequency (void) { basic_block bb; struct cgraph_node *node = cgraph_get_node (current_function_decl); + if (DECL_STATIC_CONSTRUCTOR (current_function_decl) || MAIN_NAME_P (DECL_NAME (current_function_decl))) node->only_called_at_startup = true; if (DECL_STATIC_DESTRUCTOR (current_function_decl)) node->only_called_at_exit = true; - if (!profile_info || !flag_branch_probabilities) + if (profile_status != PROFILE_READ) { int flags = flags_from_decl_or_type (current_function_decl); if (lookup_attribute ("cold", DECL_ATTRIBUTES (current_function_decl)) @@ -2876,7 +2877,13 @@ compute_function_frequency (void) node->frequency = NODE_FREQUENCY_EXECUTED_ONCE; return; } - node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED; + + /* Only first time try to drop function into unlikely executed. + After inlining the roundoff errors may confuse us. + Ipa-profile pass will drop functions only called from unlikely + functions to unlikely and that is most of what we care about. */ + if (!cfun->after_inlining) + node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED; FOR_EACH_BB (bb) { if (maybe_hot_bb_p (cfun, bb)) diff --git a/gcc/print-tree.c b/gcc/print-tree.c index 1413af6f95f..c3272e223c4 100644 --- a/gcc/print-tree.c +++ b/gcc/print-tree.c @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-iterator.h" #include "diagnostic.h" #include "gimple-pretty-print.h" /* FIXME */ -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-dump.h" #include "dumpfile.h" #include "wide-int-print.h" diff --git a/gcc/profile.c b/gcc/profile.c index 2abde8aec03..94a3f07c6f3 100644 --- a/gcc/profile.c +++ b/gcc/profile.c @@ -61,7 +61,7 @@ along with GCC; see the file COPYING3. If not see #include "coverage.h" #include "value-prof.h" #include "tree.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "dumpfile.h" @@ -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/ree.c b/gcc/ree.c index 4dab6e91995..541bdb5a131 100644 --- a/gcc/ree.c +++ b/gcc/ree.c @@ -298,7 +298,8 @@ combine_set_extension (ext_cand *cand, rtx curr_insn, rtx *orig_set) the source mode. */ enum machine_mode src_mode = GET_MODE (SET_DEST (*orig_set)); rtx new_const_int - = GEN_INT (INTVAL (orig_src) & GET_MODE_MASK (src_mode)); + = gen_int_mode (INTVAL (orig_src) & GET_MODE_MASK (src_mode), + GET_MODE (new_reg)); new_set = gen_rtx_SET (VOIDmode, new_reg, new_const_int); } } diff --git a/gcc/reginfo.c b/gcc/reginfo.c index 1fb6b5d226b..49a7a5864e2 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -620,40 +620,35 @@ choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED, mode = GET_MODE_WIDER_MODE (mode)) if ((unsigned) hard_regno_nregs[regno][mode] == nregs && HARD_REGNO_MODE_OK (regno, mode) - && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))) + && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)) + && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode)) found_mode = mode; - if (found_mode != VOIDmode) - return found_mode; - for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode)) if ((unsigned) hard_regno_nregs[regno][mode] == nregs && HARD_REGNO_MODE_OK (regno, mode) - && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))) + && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)) + && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode)) found_mode = mode; - if (found_mode != VOIDmode) - return found_mode; - for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT); mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode)) if ((unsigned) hard_regno_nregs[regno][mode] == nregs && HARD_REGNO_MODE_OK (regno, mode) - && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))) + && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)) + && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode)) found_mode = mode; - if (found_mode != VOIDmode) - return found_mode; - for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT); mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode)) if ((unsigned) hard_regno_nregs[regno][mode] == nregs && HARD_REGNO_MODE_OK (regno, mode) - && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))) + && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)) + && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode)) found_mode = mode; if (found_mode != VOIDmode) diff --git a/gcc/regmove.c b/gcc/regmove.c index da7fac9844e..e579a7a234d 100644 --- a/gcc/regmove.c +++ b/gcc/regmove.c @@ -786,7 +786,8 @@ fixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset) { HOST_WIDE_INT newconst = INTVAL (offset) - INTVAL (XEXP (SET_SRC (pset), 1)); - rtx add = gen_add3_insn (dst, dst, GEN_INT (newconst)); + rtx add = gen_add3_insn (dst, dst, + gen_int_mode (newconst, GET_MODE (dst))); if (add && validate_change (insn, &PATTERN (insn), add, 0)) { diff --git a/gcc/reload1.c b/gcc/reload1.c index b8c3bfabbfb..7a82c07ef21 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -435,7 +435,7 @@ init_reload (void) gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, LAST_VIRTUAL_REGISTER + 1), - GEN_INT (4))); + gen_int_mode (4, Pmode))); spill_indirect_levels = 0; while (memory_address_p (QImode, tem)) @@ -9157,7 +9157,9 @@ inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount) emit_insn (gen_add2_insn (reloadreg, inc)); emit_insn (gen_move_insn (incloc, reloadreg)); if (CONST_INT_P (inc)) - emit_insn (gen_add2_insn (reloadreg, GEN_INT (-INTVAL (inc)))); + emit_insn (gen_add2_insn (reloadreg, + gen_int_mode (-INTVAL (inc), + GET_MODE (reloadreg)))); else emit_insn (gen_sub2_insn (reloadreg, inc)); } diff --git a/gcc/resource.c b/gcc/resource.c index a0fd2ec4e69..367181289df 100644 --- a/gcc/resource.c +++ b/gcc/resource.c @@ -374,6 +374,16 @@ mark_referenced_resources (rtx x, struct resources *res, case INSN: case JUMP_INSN: + if (GET_CODE (PATTERN (x)) == COND_EXEC) + /* In addition to the usual references, also consider all outputs + as referenced, to compensate for mark_set_resources treating + them as killed. This is similar to ZERO_EXTRACT / STRICT_LOW_PART + handling, execpt that we got a partial incidence instead of a partial + width. */ + mark_set_resources (x, res, 0, + include_delayed_effects + ? MARK_SRC_DEST_CALL : MARK_SRC_DEST); + #ifdef INSN_REFERENCES_ARE_DELAYED if (! include_delayed_effects && INSN_REFERENCES_ARE_DELAYED (x)) @@ -994,11 +1004,18 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res) if (CALL_P (real_insn)) { - /* CALL clobbers all call-used regs that aren't fixed except - sp, ap, and fp. Do this before setting the result of the - call live. */ - AND_COMPL_HARD_REG_SET (current_live_regs, - regs_invalidated_by_call); + /* Values in call-clobbered registers survive a COND_EXEC CALL + if that is not executed; this matters for resoure use because + they may be used by a complementarily (or more strictly) + predicated instruction, or if the CALL is NORETURN. */ + if (GET_CODE (PATTERN (real_insn)) != COND_EXEC) + { + /* CALL clobbers all call-used regs that aren't fixed except + sp, ap, and fp. Do this before setting the result of the + call live. */ + AND_COMPL_HARD_REG_SET (current_live_regs, + regs_invalidated_by_call); + } /* A CALL_INSN sets any global register live, since it may have been modified by the call. */ diff --git a/gcc/sese.c b/gcc/sese.c index 10ccee274fb..d5ffa25bbb9 100644 --- a/gcc/sese.c +++ b/gcc/sese.c @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "hash-table.h" #include "tree-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "tree-chrec.h" #include "tree-data-ref.h" diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 3f263535cb3..eda11e6085e 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -842,7 +842,8 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op) /* Similarly, (not (neg X)) is (plus X -1). */ if (GET_CODE (op) == NEG) - return plus_constant (mode, XEXP (op, 0), -1); + return simplify_gen_binary (PLUS, mode, XEXP (op, 0), + CONSTM1_RTX (mode)); /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */ if (GET_CODE (op) == XOR @@ -949,7 +950,8 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op) /* Similarly, (neg (not X)) is (plus X 1). */ if (GET_CODE (op) == NOT) - return plus_constant (mode, XEXP (op, 0), 1); + return simplify_gen_binary (PLUS, mode, XEXP (op, 0), + CONST1_RTX (mode)); /* (neg (minus X Y)) can become (minus Y X). This transformation isn't safe for modes with signed zeros, since if X and Y are @@ -2558,12 +2560,13 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, && CONST_INT_P (XEXP (op0, 1)) && CONST_INT_P (op1) && (UINTVAL (XEXP (op0, 1)) & UINTVAL (op1)) != 0) - return simplify_gen_binary (IOR, mode, - simplify_gen_binary - (AND, mode, XEXP (op0, 0), - GEN_INT (UINTVAL (XEXP (op0, 1)) - & ~UINTVAL (op1))), - op1); + { + rtx tmp = simplify_gen_binary (AND, mode, XEXP (op0, 0), + gen_int_mode (UINTVAL (XEXP (op0, 1)) + & ~UINTVAL (op1), + mode)); + return simplify_gen_binary (IOR, mode, tmp, op1); + } /* If OP0 is (ashiftrt (plus ...) C), it might actually be a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and @@ -2693,7 +2696,7 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, /* Try to simplify ~A&C | ~B&C. */ if (na_c != NULL_RTX) return simplify_gen_binary (IOR, mode, na_c, - GEN_INT (~bval & cval)); + gen_int_mode (~bval & cval, mode)); } else { @@ -2701,9 +2704,11 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, if (na_c == const0_rtx) { rtx a_nc_b = simplify_gen_binary (AND, mode, a, - GEN_INT (~cval & bval)); + gen_int_mode (~cval & bval, + mode)); return simplify_gen_binary (IOR, mode, a_nc_b, - GEN_INT (~bval & cval)); + gen_int_mode (~bval & cval, + mode)); } } } @@ -3037,7 +3042,7 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode, if (CONST_INT_P (trueop1) && exact_log2 (UINTVAL (trueop1)) > 0) return simplify_gen_binary (AND, mode, op0, - GEN_INT (INTVAL (op1) - 1)); + gen_int_mode (INTVAL (op1) - 1, mode)); break; case MOD: diff --git a/gcc/symtab.c b/gcc/symtab.c index 253ba981844..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); @@ -1106,11 +1110,48 @@ symtab_nonoverwritable_alias (symtab_node node) { DECL_STATIC_CONSTRUCTOR (new_decl) = 0; DECL_STATIC_DESTRUCTOR (new_decl) = 0; - new_node = (symtab_node) cgraph_create_function_alias (new_decl, node->symbol.decl); + new_node = (symtab_node) cgraph_create_function_alias + (new_decl, node->symbol.decl); } else - new_node = (symtab_node) varpool_create_variable_alias (new_decl, node->symbol.decl); + new_node = (symtab_node) varpool_create_variable_alias (new_decl, + node->symbol.decl); symtab_resolve_alias (new_node, node); + gcc_assert (decl_binds_to_current_def_p (new_decl)); return new_node; } + +/* Return true if A and B represents semantically equivalent symbols. */ + +bool +symtab_semantically_equivalent_p (symtab_node a, + symtab_node b) +{ + enum availability avail; + symtab_node ba, bb; + + /* Equivalent functions are equivalent. */ + if (a->symbol.decl == b->symbol.decl) + return true; + + /* If symbol is not overwritable by different implementation, + walk to the base object it defines. */ + ba = symtab_alias_ultimate_target (a, &avail); + if (avail >= AVAIL_AVAILABLE) + { + if (ba == b) + return true; + } + else + ba = a; + bb = symtab_alias_ultimate_target (b, &avail); + if (avail >= AVAIL_AVAILABLE) + { + if (a == bb) + return true; + } + else + bb = b; + return bb == ba; +} #include "gt-symtab.h" diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 396f4518731..e0fd7d15cb3 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -68,7 +68,7 @@ along with GCC; see the file COPYING3. If not see #include "recog.h" #include "intl.h" #include "opts.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-ssa-alias.h" #include "insn-codes.h" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ffa42f090eb..2fc781a3e37 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,456 @@ +2013-09-20 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/58481 + * g++.dg/cpp0x/lambda/lambda-this17.C: New. + +2013-09-20 Jan-Benedict Glaw <jbglaw@lug-owl.de> + + PR target/56875 + * gcc.target/vax/vax.exp: New. + * gcc.target/vax/pr56875.c: Ditto. + +2013-09-20 Richard Biener <rguenther@suse.de> + + PR middle-end/58484 + * gfortran.dg/pr58484.f: New testcase. + +2013-09-20 Jeff Law <law@redhat.com> + + * gcc.dg/tree-ssa/ssa-dom-thread-3.c: Add missing dg-final clause. + +2013-09-20 Bernd Edlinger <bernd.edlinger@hotmail.de> + + PR middle-end/57748 + * gcc.dg/torture/pr57748-1.c: New test. + * gcc.dg/torture/pr57748-2.c: New test. + +2013-09-20 Marek Polacek <polacek@redhat.com> + + PR sanitizer/58413 + * c-c++-common/ubsan/shift-4.c: New test. + +2013-09-20 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58453 + * gcc.dg/tree-ssa/ldist-23.c: New testcase. + +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. + +2013-09-16 Adam Butcher <adam@jessamine.co.uk> + + * g++.dg/cpp0x/auto9.C: Downgrade two previously expected errors (now + interpreted as implicit templates) to be expected pedwarns instead. + +2013-09-16 Tobias Burnus <burnus@net-b.de> + + PR fortran/57697 + * gfortran.dg/defined_assignment_10.f90: Comment print statement. + +2013-09-15 Tobias Burnus <burnus@net-b.de> + + PR fortran/57697 + * gfortran.dg/defined_assignment_10.f90: New. + +2013-09-13 Evgeny Gavrin <e.gavrin@samsung.com> + + * gcc.dg/debug/dwarf2/omp-fesdr.c: Add test. + * g++.dg/debug/dwarf2/omp-fesdr.C: Add test. + +2013-09-13 Jacek Caban <jacek@codeweavers.com> + + * g++.dg/abi/main.C: Added implicit C linkage tests + +2013-09-13 Kai Tietz <ktietz@redhat.com> + + gcc.target/i386/pr57848.c: New file. + +2013-09-13 Christian Bruel <christian.bruel@st.com> + + PR target/58314 + * gcc.target/sh/torture/pr58314.c: New test. + +2013-09-12 Paolo Carlini <paolo.carlini@oracle.com> + + * g++.dg/torture/pr58380.C: Suppress warnings with "-w". + +2013-09-12 Martin Jambor <mjambor@suse.cz> + + PR ipa/58389 + * g++.dg/pr58389.C: New test. + +2013-09-12 Paolo Carlini <paolo.carlini@oracle.com> + + * g++.dg/template/pseudodtor2.C: Add column number to dg-error + strings. + * g++.dg/template/pseudodtor3.C: Likewise. + +2013-09-12 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58404 + * g++.dg/tree-ssa/pr58404.C: New testcase. + +2013-09-12 Martin Jambor <mjambor@suse.cz> + + PR ipa/58371 + * g++.dg/ipa/pr58371.C: New test. + +2013-09-12 Richard Biener <rguenther@suse.de> + + * gcc.dg/tree-ssa/ldist-4.c: Remove undefined behavior. Adjust + expected outcome and comment why that happens. + +2013-09-11 Richard Biener <rguenther@suse.de> + + PR middle-end/58377 + * g++.dg/uninit-pred-4.C: New testcase. + +2013-09-11 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/58385 + * gcc.c-torture/execute/pr58385.c: New test. + +2013-09-11 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * gcc.target/arm/thumb-ifcvt-2.c: New test. + +2013-09-10 Jeff Law <law@redhat.com> + + * g++.dg/torture/pr58380.C: New test. + +2013-09-10 Jan Hubicka <jh@suse.cz> + Paolo Carlini <paolo.carlini@oracle.com> + + * g++.dg/template/cond2.C: Tweak, do not expect a "required from". + +2013-09-10 Jeff Law <law@redhat.com> + + * gcc.c-torture/compile/pr58343.c: New test. + +2013-09-10 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/58365 + * gcc.c-torture/execute/pr58365.c: New test. + +2013-09-10 Michael Zolotukhin <michael.v.zolotukhin@gmail.com> + + * gcc.dg/torture/memcpy-1.c: New test. + +2013-09-10 Alan Modra <amodra@gmail.com> + + * gcc.target/powerpc/pr58330.c: New. + +2013-09-10 Alan Modra <amodra@gmail.com> + + * gcc.target/powerpc/medium_offset.c: New. + +2013-09-09 Jakub Jelinek <jakub@redhat.com> + + PR c++/58325 + * g++.dg/warn/Wunused-var-21.C: New test. + + PR tree-optimization/58364 + * gcc.c-torture/execute/pr58364.c: New test. + +2013-09-09 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/43452 + * g++.dg/warn/Wdelete-incomplete-1.C: New. + * g++.dg/warn/Wdelete-incomplete-2.C: Likewise. + * g++.dg/init/delete1.C: Adjust. + +2013-09-09 Ian Bolton <ian.bolton@arm.com> + + * gcc.target/aarch64/movdi_1.c: New test. + +2013-09-09 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/58362 + * g++.dg/warn/Wunused-parm-5.C: New. + +2013-09-09 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * gcc.target/aarch64/cmn-neg.c: New test. + +2013-09-09 Richard Biener <rguenther@suse.de> + + PR middle-end/58326 + * gcc.dg/torture/pr58326-1.c: New testcase. + * gcc.dg/torture/pr58326-2.c: Likewise. + +2013-09-09 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + PR target/57735 + * g++.dg/ext/pr57735.C: New test. + +2013-09-09 Jan Hubicka <jh@suse.cz> + + PR middle-end/58294 + * g++.dg/torture/PR58294.C: New testcase. + +2013-09-08 Jeff Law <law@redhat.com> + + * gcc.c-torture/compile/pr58340.c: New test. + +2013-09-08 Richard Sandiford <rdsandiford@googlemail.com> + + * g++.dg/debug/ra1.C: New test. + +2013-09-08 Jan Hubicka <jh@suse.cz> + + * testsuite/g++.dg/ipa/devirt-11.C: Update template. + * testsuite/g++.dg/ipa/devirt-16.C: New testcase. + * testsuite/g++.dg/ipa/devirt-17.C: New testcase. + * testsuite/g++.dg/ipa/devirt-18.C: New testcase. + +2013-09-08 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/54941 + * g++.dg/overload/new1.C: Adjust. + +2013-09-08 Joern Rennecke <joern.rennecke@embecosm.com> + + * c-c++-common/opaque-vector.c: New test. + +2013-09-08 Tom de Vries <tom@codesourcery.com> + + PR c++/58282 + * g++.dg/tm/noexcept-6.C: New test. + +2013-09-06 Joern Rennecke <joern.rennecke@embecosm.com> + + * gcc.target/arc/cond-set-use.c: New test. + +2013-09-06 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/stack_usage2.adb: New test. + +2013-09-06 James Greenhalgh <james.greenhalgh@arm.com> + + * gcc.target/aarch64/table-intrinsics.c + (qtbl_tests8_< ,2,3,4>): Fix control vector parameter type. + (qtb_tests8_< ,2,3,4>): Likewise. + (qtblq_tests8_< ,2,3,4>): Likewise. + (qtbxq_tests8_< ,2,3,4>): Likewise. + +2013-09-06 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/warn10.ad[sb]: New test. + * gnat.dg/warn10_pkg.ads: New helper. + +2013-09-06 Joern Rennecke <joern.rennecke@embecosm.com> + + * gcc.dg/ipa/ipa-pta-14.c (scan-ipa-dump) [keeps_null_pointer_checks]: + Don't expect NULL in foo.result set. + * gcc.dg/tree-ssa/pta-escape-1.c (scan-tree-dump): Don't expect NULL + in ESCAPED set. + * gcc.dg/tree-ssa/pta-escape-2.c: Likewise. + * gcc.dg/tree-ssa/pta-escape-3.c: Likewise. + +2013-09-06 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * gcc.target/s390/nearestint-1.c: New testcase. + +2013-09-06 Joern Rennecke <joern.rennecke@embecosm.com> + Vineet Gupta <Vineet.Gupta@synopsys.com> + + * gcc.c-torture/execute/20101011-1.c [__arc__] (DO_TEST): Define as 0. + * testsuite/gcc.target/arc: New directory. + * gcc.dg/torture/pr37868.c: Also skip for arc*-*-*. + * gcc.dg/stack-usage-1.c [__arc__] (SIZE): Define. + * testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c + [__arc__] (STACK_ARGUMENTS_SIZE): Set to 0. + * testsuite/gcc.dg/builtin-apply2.c + [__arc__] (STACK_ARGUMENTS_SIZE): Set to 0. + +2013-09-04 Jan Hubicka <jh@suse.cz> + + PR middle-end/58201 + * g++.dg/torture/pr58201_0.C: New testcase. + * g++.dg/torture/pr58201_1.C: New testcase. + * g++.dg/torture/pr58201.h: New testcase. + +2013-09-05 Jan Hubicka <jh@suse.cz> + + * gcc.dg/autopar/pr49960.c: Disable partial inlining + +2013-09-05 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58137 + * gcc.target/i386/pr58137.c: New testcase. + +2013-09-05 Martin Jambor <mjambor@suse.cz> + + * g++.dg/ipa/remref-1.C: New test. + * g++.dg/ipa/remref-2.C: Likewise. + +2013-09-04 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/24926 + * g++.dg/parse/access11.C: New. + +2013-09-04 David Edelsohn <dje.gcc@gmail.com> + + * g++.dg/warn/weak1.C: Skip on AIX. + +2013-09-04 Easwaran Raman <eraman@google.com> + + PR middle-end/57370 + PR tree-optimization/58011 + * gfortran.dg/reassoc_12.f90: New testcase. + * gcc.dg/tree-ssa/reassoc-31.c: New testcase. + 2013-09-04 David Edelsohn <dje.gcc@gmail.com> * gcc.dg/attr-weakref-1.c: Skip on AIX. diff --git a/gcc/testsuite/c-c++-common/opaque-vector.c b/gcc/testsuite/c-c++-common/opaque-vector.c new file mode 100644 index 00000000000..cad266e893b --- /dev/null +++ b/gcc/testsuite/c-c++-common/opaque-vector.c @@ -0,0 +1,22 @@ +#define B_TEST(TYPE) { TYPE v __attribute__((vector_size(16))); (void)((v < v) < v); } +#ifdef __cplusplus +#define T_TEST(TYPE) { TYPE s; TYPE v __attribute__((vector_size(16))); __typeof((v<v)[0]) iv __attribute__((vector_size(16))); (void)((iv ? s : s) < v); } +#else +#define T_TEST(TYPE) +#endif +#define T(TYPE) B_TEST(TYPE) T_TEST(TYPE) + +void f () +{ + T(short) + T(int) + T(long) + T(long long) + + T_TEST(float) + T_TEST(double) + /* Avoid trouble with non-power-of-two sizes. */ +#if !defined(__i386__) && !defined(__x86_64__) && !defined(__m68k__) && !defined(__ia64__) + T_TEST(long double) +#endif +} 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/c-c++-common/ubsan/shift-4.c b/gcc/testsuite/c-c++-common/ubsan/shift-4.c new file mode 100644 index 00000000000..239c0131fb9 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/shift-4.c @@ -0,0 +1,14 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=shift -w" } */ + +struct S { unsigned long long int b:40; } s; + +int +main () +{ + s.b = 2; + s.b <<= 120; + return 0; +} + +/* { dg-output "shift exponent 120 is too large\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/g++.dg/abi/main.C b/gcc/testsuite/g++.dg/abi/main.C new file mode 100644 index 00000000000..4c5f1ea213c --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/main.C @@ -0,0 +1,24 @@ +/* { dg-do compile } */ + +/* Check if entry points get implicit C linkage. If they don't, compiler will + * error on incompatible declarations */ + +int main(); +extern "C" int main(); + +#ifdef __MINGW32__ + +int wmain(); +extern "C" int wmain(); + +int DllMain(); +extern "C" int DllMain(); + +int WinMain(); +extern "C" int WinMain(); + +int wWinMain(); +extern "C" int wWinMain(); + +#endif + 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/cpp0x/auto9.C b/gcc/testsuite/g++.dg/cpp0x/auto9.C index 190bfa6e8f0..f357f2b9663 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto9.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto9.C @@ -117,8 +117,8 @@ template <auto V = 4> struct G {}; // { dg-error "auto" } template <typename T> struct H { H (); ~H (); }; H<auto> h; // { dg-error "invalid" } -void qq (auto); // { dg-error "auto" } -void qr (auto*); // { dg-error "auto" } +void qq (auto); // { dg-warning "auto" } +void qr (auto*); // { dg-warning "auto" } // PR c++/46145 typedef auto autot; // { dg-error "auto" } diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this17.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this17.C new file mode 100644 index 00000000000..2386e6b1eb8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this17.C @@ -0,0 +1,21 @@ +// PR c++/58481 +// { dg-require-effective-target c++11 } + +struct Test { + template<typename... Args> inline void triggerTest (Args&&... fargs) { } +}; + +struct TestPickled : Test { + template<typename... Args> void triggerTest (Args&&... fargs) { + [=](Args... as) { + Test::triggerTest (as...); + } (); + } +}; + +int main() +{ + TestPickled test; + test.triggerTest (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic2.C new file mode 100644 index 00000000000..fab1f6ca6ac --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic2.C @@ -0,0 +1,57 @@ +// { dg-do run { target c++11 } } + +int g() { return 0; } +template <class T, class... U> +int g(T t, U... u) +{ + return t + g(u...); +} + +template <class... T> +int f1(T... t) +{ + return [t...] { + return g(t...); + }(); +} + +template <class... T> +int f2(T... t) +{ + return [&t...] { + return g(t...); + }(); +} + +template <class... T> +int f3(T... t) +{ + return [=] { + return g(t...); + }(); +} + +template <class... T> +int f4(T... t) +{ + return [&] { + return g(t...); + }(); +} + +#define assert(E) do { if (!(E)) __builtin_abort(); } while(0) +int main() +{ + assert (f1() == 0); + assert (f2() == 0); + assert (f3() == 0); + assert (f4() == 0); + assert (f1(42) == 42); + assert (f2(42) == 42); + assert (f3(42) == 42); + assert (f4(42) == 42); + assert (f1(1,2,3) == 6); + assert (f2(1,2,3) == 6); + assert (f3(1,2,3) == 6); + assert (f4(1,2,3) == 6); +} diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/omp-fesdr.C b/gcc/testsuite/g++.dg/debug/dwarf2/omp-fesdr.C new file mode 100644 index 00000000000..b3b65e91888 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/omp-fesdr.C @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target fopenmp } */ +/* { dg-options "-g -fopenmp -gdwarf-2 -femit-struct-debug-reduced" } */ + +struct aa +{ + int a; +}; + +int +f7 (void) +{ + int v7i = 6, v7j = 7, v7k = 9, v7l = 0, v7n = 0, v7o = 1; + + #pragma omp parallel + { + #pragma omp master + v7o++; + #pragma omp for private (v7i) firstprivate (v7k) reduction (+:v7l) + for (v7n = 0; v7n < 3; v7n++) + { + int v7m = v7j + v7k; + v7i = 8; + v7l++; + } + } + + return v7i + v7j + v7k + v7l + v7n; +} + +int +main (void) +{ + f7 (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/debug/ra1.C b/gcc/testsuite/g++.dg/debug/ra1.C new file mode 100644 index 00000000000..b6f7bfc588d --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/ra1.C @@ -0,0 +1,77 @@ +/* { dg-options "-fcompare-debug" } */ + +enum signop { SIGNED, UNSIGNED }; +enum tree_code { FOO, BAR }; +enum tree_code_class { tcc_type, tcc_other }; +extern enum tree_code_class tree_code_type[]; + +struct tree_base { + enum tree_code code : 16; + unsigned unsigned_flag : 1; +}; + +struct tree_def { + tree_base base; + struct { + int precision; + } type_common; +}; + +typedef tree_def *tree; + +struct storage_ref +{ + storage_ref (const long *, unsigned int, unsigned int); + + const long *val; + unsigned int len; + unsigned int precision; +}; + +inline storage_ref::storage_ref (const long *val_in, + unsigned int len_in, + unsigned int precision_in) + : val (val_in), len (len_in), precision (precision_in) +{ +} + +struct hwi_with_prec +{ + long val; + unsigned int precision; + signop sgn; +}; + +inline storage_ref +decompose (long *scratch, unsigned int precision, + const hwi_with_prec &x) +{ + scratch[0] = x.val; + if (x.sgn == SIGNED || x.val >= 0 || precision <= sizeof (long) * 8) + return storage_ref (scratch, 1, precision); + scratch[1] = 0; + return storage_ref (scratch, 2, precision); +} + +extern void tree_class_check_failed (int) __attribute__ ((__noreturn__)); + +inline tree +tree_class_check (tree t, const enum tree_code_class cls, int x) +{ + if (tree_code_type[t->base.code] != cls) + tree_class_check_failed (x); + return t; +} + +tree wide_int_to_tree (tree, const storage_ref &); + +tree +build_int_cstu (tree type, unsigned long val) +{ + hwi_with_prec x; + x.val = val; + x.precision = tree_class_check (type, tcc_type, 1)->type_common.precision; + x.sgn = (signop) tree_class_check (type, tcc_type, 2)->base.unsigned_flag; + long scratch[2]; + return wide_int_to_tree (type, decompose (scratch, x.precision, x)); +} diff --git a/gcc/testsuite/g++.dg/ext/pr57735.C b/gcc/testsuite/g++.dg/ext/pr57735.C new file mode 100644 index 00000000000..0eb95006dda --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/pr57735.C @@ -0,0 +1,145 @@ +/* { dg-do compile { target arm*-*-* } } */ +/* { dg-options "-march=armv5te -marm -mtune=xscale -mfloat-abi=soft -O1" } */ + +typedef unsigned int size_t; +__extension__ +typedef long long int int64_t; +namespace WTF { + template<typename T> class RefPtr { + public: + inline T* operator->() const { return m_ptr; } + T* m_ptr; + }; +} +using WTF::RefPtr; +namespace JSC { + class ExecState; + class JSString; + typedef int64_t EncodedJSValue; + class JSValue { + public: + static EncodedJSValue encode(JSValue); + JSString* toString(ExecState*) const; + }; +} +typedef unsigned char LChar; + typedef short unsigned int UChar; +namespace WTF { + template<typename T, size_t inlineCapacity = 0> + class Vector { + public: + template<typename U> bool tryAppend(const U*, size_t); + }; +} +using WTF::Vector; +namespace WTF { +template<typename CharType> inline bool isASCIIDigit(CharType c) +{ +} +template<typename CharType> inline bool isASCIIHexDigit(CharType c) +{ + return isASCIIDigit(c) || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f'); +} + class StringImpl; +} +using WTF::StringImpl; +namespace WTF { +class StringImpl { +public: + unsigned length() const { return m_length; } + unsigned m_length; +}; +} +namespace JSC { + class Register { + }; +class UString { +public: + unsigned length() const + { + return m_impl->length(); + } + const LChar* characters8() const + { + } + RefPtr<StringImpl> m_impl; +}; + class ExecState : private Register { + public: + JSValue argument(size_t argument) + { + } + }; + class JSCell { + }; + class JSString : public JSCell { + public: + const UString& value(ExecState*) const; + }; +class JSStringBuilder { +public: + void append(const UChar u) + { + m_okay &= buffer16.tryAppend(&u, 1); + } + Vector<UChar, 64> buffer16; + bool m_okay; +}; +template <typename T> +class Lexer { +public: + static unsigned char convertHex(int c1, int c2); +}; +} +namespace WTF { +namespace Unicode { + int UTF8SequenceLength(char); + int decodeUTF8Sequence(const char*); +} +} +using namespace WTF; +using namespace Unicode; +namespace JSC { +template <typename CharType> +static JSValue decode(ExecState* exec, const CharType* characters, int length, const char* doNotUnescape, bool strict) +{ + JSStringBuilder builder; + int k = 0; + UChar u = 0; + while (k < length) { + const CharType* p = characters + k; + CharType c = *p; + if (c == '%') { + int charLen = 0; + if (k <= length - 3 && isASCIIHexDigit(p[1]) && isASCIIHexDigit(p[2])) { + const char b0 = Lexer<CharType>::convertHex(p[1], p[2]); + const int sequenceLen = UTF8SequenceLength(b0); + if (sequenceLen && k <= length - sequenceLen * 3) { + charLen = sequenceLen * 3; + char sequence[5]; + if (charLen != 0) { + const int character = decodeUTF8Sequence(sequence); + if (character < 0 || character >= 0x110000) + charLen = 0; + else if (character >= 0x10000) { + builder.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10))); + } else + u = static_cast<UChar>(character); + } + } + } + } + } +} +static JSValue decode(ExecState* exec, const char* doNotUnescape, bool strict) +{ + UString str = exec->argument(0).toString(exec)->value(exec); + return decode(exec, str.characters8(), str.length(), doNotUnescape, strict); +} +EncodedJSValue globalFuncDecodeURI(ExecState* exec) +{ + static const char do_not_unescape_when_decoding_URI[] = + "#$&+,/:;=?@"; + return JSValue::encode(decode(exec, do_not_unescape_when_decoding_URI, true)); +} +} diff --git a/gcc/testsuite/g++.dg/init/delete1.C b/gcc/testsuite/g++.dg/init/delete1.C index 698b127714a..304dca1caf9 100644 --- a/gcc/testsuite/g++.dg/init/delete1.C +++ b/gcc/testsuite/g++.dg/init/delete1.C @@ -1,7 +1,7 @@ // PR c++/19811 -class C; // { dg-error "forward" } +class C; // { dg-warning "forward" } void foo(void *p) { - delete [] ((C*)p) ; // { dg-error "" } + delete [] ((C*)p) ; // { dg-warning "problem|incomplete" } } diff --git a/gcc/testsuite/g++.dg/ipa/devirt-11.C b/gcc/testsuite/g++.dg/ipa/devirt-11.C index b888935ff30..d30d56cff24 100644 --- a/gcc/testsuite/g++.dg/ipa/devirt-11.C +++ b/gcc/testsuite/g++.dg/ipa/devirt-11.C @@ -46,5 +46,4 @@ bar () and two to fn3. While doing so the new symbol for fn2 needs to be introduced. */ /* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target" 3 "inline" } } */ -/* { dg-final { scan-ipa-dump-times "and turned into root of the clone tree" 1 "inline" } } */ /* { dg-final { cleanup-ipa-dump "inline" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/devirt-16.C b/gcc/testsuite/g++.dg/ipa/devirt-16.C new file mode 100644 index 00000000000..85567867ff1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-16.C @@ -0,0 +1,39 @@ +/* We shall devirtualize to unreachable. No anonymous type method should surivve + reachability. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-ipa-whole-program" } */ +namespace { +class B { +public: + virtual int foo(void) +{ + return 0; +} +}; +class A : public B { +public: + virtual int foo(void) +{ + return 1; +} +}; +} +class B *b; +main() +{ + int c; + if (c) + { + class A a; + a.foo(); + class B b; + b.foo(); + } + return b->foo(); +} + +/* { dg-final { scan-ipa-dump "Devirtualizing" "whole-program"} } */ +/* { dg-final { scan-ipa-dump "builtin_unreachable" "whole-program"} } */ +/* { dg-final { scan-ipa-dump-not "A::foo" "whole-program"} } */ +/* { dg-final { scan-ipa-dump-not "A::foo" "whole-program"} } */ +/* { dg-final { cleanup-ipa-dump "whole-program" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/devirt-17.C b/gcc/testsuite/g++.dg/ipa/devirt-17.C new file mode 100644 index 00000000000..9edfd73af56 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-17.C @@ -0,0 +1,44 @@ +/* We shall devirtualize to B::foo since it is the only live candidate of an + anonymous type. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-ipa-whole-program" } */ +namespace { +class B { +public: + virtual int foo(void) +{ + return 0; +} +}; +class A : public B { +public: + virtual int foo(void) +{ + return 1; +} +}; +} +class B *b; +void get_me_lost (void *); +main() +{ + int c; + if (c) + { + class A a; + a.foo(); + } + else + { + b = new (class B); + b->foo(); + get_me_lost ((void *)&b); + } + return b->foo(); +} + +/* { dg-final { scan-ipa-dump "Devirtualizing" "whole-program"} } */ +/* { dg-final { scan-ipa-dump-not "builtin_unreachable" "whole-program"} } */ +/* { dg-final { scan-ipa-dump "B::foo" "whole-program"} } */ +/* { dg-final { scan-ipa-dump-not "A::foo" "whole-program"} } */ +/* { dg-final { cleanup-ipa-dump "whole-program" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/devirt-18.C b/gcc/testsuite/g++.dg/ipa/devirt-18.C new file mode 100644 index 00000000000..dbbe597c92c --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-18.C @@ -0,0 +1,37 @@ +/* We shall devirtualize to unreachable. No anonymous type method should surivve + reachability. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ssa" } */ +namespace { +class B { +public: + virtual int foo(void) +{ + return 0; +} +}; +class A : public B { +public: + virtual int foo(void) +{ + return 1; +} +}; +} +class B *b; +main() +{ + if (0) + { + class A a; + a.foo(); + class B b; + b.foo(); + } + return b->foo(); +} + +/* { dg-final { scan-tree-dump-not "A::foo" "ssa"} } */ +/* { dg-final { scan-tree-dump-not "B::foo" "ssa"} } */ +/* { dg-final { scan-tree-dump "builtin_unreachable" "ssa"} } */ +/* { dg-final { cleanup-tree-dump "ssa" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/pr58371.C b/gcc/testsuite/g++.dg/ipa/pr58371.C new file mode 100644 index 00000000000..00cfbb831fc --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr58371.C @@ -0,0 +1,204 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + + +typedef int size_t; +namespace { +template < typename > struct char_traits; +} +namespace __gnu_cxx { +template < typename > class new_allocator { +}; +} +namespace std { +template < typename _Tp > class allocator:__gnu_cxx::new_allocator < _Tp > { +public: + size_t size_type; + typedef _Tp & const_reference; + template < typename > struct rebind { + typedef allocator other; + }; +}; +} +namespace __gnu_cxx { +template < typename _Alloc > struct __alloc_traits { + typedef typename _Alloc::const_reference const_reference; + template < typename _Tp > struct rebind { + typedef typename _Alloc::template rebind < _Tp >::other other; + }; +}; +} +namespace std { +struct __numeric_limits_base { +}; +template < typename _Tp > struct numeric_limits:__numeric_limits_base { + static _Tp max () { + } +}; +template < typename _Tp, typename _Alloc > struct _Vector_base { + typedef typename __gnu_cxx::__alloc_traits < _Alloc >::template rebind < + _Tp >::other _Tp_alloc_type; +}; +template < typename _Tp, typename _Alloc = std::allocator < _Tp > >class vector:_Vector_base < _Tp, + _Alloc + > { + typedef _Vector_base < _Tp, _Alloc > _Base; + typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; + typedef __gnu_cxx::__alloc_traits < _Tp_alloc_type > _Alloc_traits; +public: + _Tp value_type; + typedef typename _Alloc_traits::const_reference const_reference; + typedef size_t size_type; + size_type size () { + } const_reference operator[] (size_type) { + } +}; +template < typename _CharT, typename = +char_traits < _CharT > >class basic_ostream; +typedef basic_ostream < int >ostream; +class ios_base { +}; +template < typename, typename > class basic_ios:ios_base { +}; +template < typename _CharT, typename _Traits > class basic_ostream:basic_ios < _CharT, + _Traits + > { +public: + _CharT char_type; + typedef basic_ostream __ostream_type; + __ostream_type & operator<< (const void *) { + } +}; +} +namespace logging { +int GetMinLogLevel (); +typedef int LogSeverity; +LogSeverity LOG_ERROR_REPORT; +LogSeverity LOG_DCHECK; +class LogMessage { +public: + LogMessage (const char *, int, LogSeverity); + std::ostream & stream () { + } +}; +class LogMessageVoidify { +public: + LogMessageVoidify () { + } void operator& (std::ostream &) { + } +}; +} +namespace base { +namespace internal { +class WeakPtrBase { +}; +class SupportsWeakPtrBase { +}; +} template < typename T > class WeakPtr:internal::WeakPtrBase { +public: + WeakPtr () :ptr_ () { + } T *operator-> () { + logging:0 && + logging::LOG_DCHECK >= + logging::GetMinLogLevel () ? (void) 0 : logging:: + LogMessageVoidify () & logging:: + LogMessage ("../../base/memory/weak_ptr.h", 0, + logging::LOG_ERROR_REPORT).stream () << ". "; + } T *ptr_; +}; +template < class > class SupportsWeakPtr:internal::SupportsWeakPtrBase { +}; +} +template < class ObserverType > class ObserverListBase:base::SupportsWeakPtr < ObserverListBase < ObserverType > + > { +public: + class Iterator { + public: + Iterator (ObserverListBase & list) :max_index_ (0 ? std::numeric_limits < + size_t >::max () : list.observers_. + size () ) { + } ObserverType * + GetNext () { + ListType & observers = list_->observers_; + if (observers[0]) + ++index_; + } + base::WeakPtr < ObserverListBase > list_; + size_t + index_; + size_t + max_index_; + }; + typedef + std::vector < + ObserverType * > + ListType; + ListType + observers_; +}; +template < class ObserverType, bool > class ObserverList:public ObserverListBase < + ObserverType > { +}; +namespace + ProxyPrefs { +enum ConfigState +{ }; +} +namespace + net { +class + ProxyConfig { +}; +class + ProxyConfigService { +public: + enum ConfigAvailability + { }; + class + Observer { + public: + Observer () { + } virtual void + OnProxyConfigChanged (const ProxyConfig &, ConfigAvailability) = 0; + }; + virtual void + OnLazyPoll () { + } +}; +} +class + ChromeProxyConfigService: + net::ProxyConfigService, + net::ProxyConfigService::Observer { + ConfigAvailability + GetLatestProxyConfig (net::ProxyConfig *); + void + UpdateProxyConfig (ProxyPrefs::ConfigState, const net::ProxyConfig &); + void + OnProxyConfigChanged (const net::ProxyConfig &, ConfigAvailability); + ObserverList < + net::ProxyConfigService::Observer, + 0 > + observers_; +}; +void +ChromeProxyConfigService::UpdateProxyConfig (ProxyPrefs::ConfigState, + const net::ProxyConfig &) { + net::ProxyConfig new_config; + ConfigAvailability availability = GetLatestProxyConfig (0); +net: + ProxyConfigService::Observer * obs; + obs->OnProxyConfigChanged (new_config, availability); +} +void +ChromeProxyConfigService::OnProxyConfigChanged (const net::ProxyConfig &, + ConfigAvailability + availability) { + net::ProxyConfig actual_config; + ObserverListBase < + net::ProxyConfigService::Observer >::Iterator it (observers_); +net: + ProxyConfigService::Observer * obs; + if (it.GetNext () ) + obs->OnProxyConfigChanged (actual_config, availability); +} diff --git a/gcc/testsuite/g++.dg/ipa/remref-1.C b/gcc/testsuite/g++.dg/ipa/remref-1.C new file mode 100644 index 00000000000..c25c425e9b7 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/remref-1.C @@ -0,0 +1,36 @@ +/* Verify that indirect-inlining induced removal of referenes will not remove + too many references in presence of speculative devirtualization. */ +/* { dg-do link } */ +/* { dg-options "-O3 -fno-early-inlining" } */ + +class A +{ + public: + virtual void foo(void (*)(void)); +}; + +static +void b(void) +{ +} + +void +A::foo(void (*back)(void)) +{ + back(); +} + +class A *a; + +void __attribute__ ((noinline, noclone)) +allocate_a () +{ + a = new A(); +} + +main() +{ + allocate_a(); + for (int i=0; i<10000;i++) + a->foo(b); +} diff --git a/gcc/testsuite/g++.dg/ipa/remref-2.C b/gcc/testsuite/g++.dg/ipa/remref-2.C new file mode 100644 index 00000000000..06bc71a5b00 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/remref-2.C @@ -0,0 +1,37 @@ +/* Verify that we survive creation and deletion of references to facilitate + reference removal while also doing (unsuccessful) speculative + devirtualization. */ +/* { dg-do link } */ +/* { dg-options "-O3 -fno-early-inlining" } */ + +class A +{ + public: + virtual void __attribute__ ((noinline)) foo(void (*)(void)); +}; + +static +void b(void) +{ +} + +void __attribute__ ((noinline)) +A::foo(void (*back)(void)) +{ + back(); +} + +class A *a; + +void __attribute__ ((noinline, noclone)) +allocate_a () +{ + a = new A(); +} + +main() +{ + allocate_a(); + for (int i=0; i<10000;i++) + a->foo(b); +} diff --git a/gcc/testsuite/g++.dg/overload/new1.C b/gcc/testsuite/g++.dg/overload/new1.C index 9adb4c07245..f1b7328366f 100644 --- a/gcc/testsuite/g++.dg/overload/new1.C +++ b/gcc/testsuite/g++.dg/overload/new1.C @@ -17,6 +17,5 @@ void f(X *x = new (3) X(6)); // { dg-error "" } void f(X *x = new (2) X[10]); // { dg-error "" } // { dg-message "candidate" "candidate note" { target *-*-* } 18 } -// { dg-message "operator new|candidate expects" "match candidate text" { target *-*-* } 00 } void f(X *x = new X[10][5]); // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/parse/access11.C b/gcc/testsuite/g++.dg/parse/access11.C new file mode 100644 index 00000000000..7004fa76401 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/access11.C @@ -0,0 +1,35 @@ +// PR c++/24926 + +class A { + union { + int i; // { dg-error "private" } + }; + union { + int j; // { dg-error "private" } + }; + union { + union { + int k; // { dg-error "private" } + }; + union { + union { + int l; // { dg-error "private" } + }; + union { + int m; // { dg-error "private" } + union { + int n; // { dg-error "private" } + int o; // { dg-error "private" } + }; + }; + }; + }; +}; + +int a1 = A().i; // { dg-error "context" } +int a2 = A().j; // { dg-error "context" } +int a3 = A().k; // { dg-error "context" } +int a4 = A().l; // { dg-error "context" } +int a5 = A().m; // { dg-error "context" } +int a6 = A().n; // { dg-error "context" } +int a7 = A().o; // { dg-error "context" } 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/pr58389.C b/gcc/testsuite/g++.dg/pr58389.C new file mode 100644 index 00000000000..648c145459b --- /dev/null +++ b/gcc/testsuite/g++.dg/pr58389.C @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +template <typename _RandomAccessIterator, typename _Compare> +void __insertion_sort(_RandomAccessIterator, _Compare); +template <typename _RandomAccessIterator, typename _Compare> +void __final_insertion_sort(_RandomAccessIterator p1, _Compare p2) { + _RandomAccessIterator a; + if (p1 - a) + ; + else + std: + __insertion_sort(0, p2); +} +template <typename _RandomAccessIterator, typename _Size, typename _Compare> +void __introsort_loop(_RandomAccessIterator, _Size, _Compare); +template <typename _RandomAccessIterator, typename _Compare> +void sort(_RandomAccessIterator, _RandomAccessIterator p2, _Compare p3) { +std: + __introsort_loop(0, 0, p3); + __final_insertion_sort(p2, p3); +} +class A { +public: + int m_fn1(); + void __lg(); + class B { + public: + int i; + int operator-(B); + }; +}; +class C; +class D { +public: + C *operator->(); +}; +class F { + A m_fn1() const; + D d_ptr; +}; +class C { + friend F; + void m_fn1(); + A children; +}; +void qt_notclosestLeaf(); +inline void C::m_fn1() { + A::B b, c; + if (children.m_fn1()) { + sort(c, b, qt_notclosestLeaf); + } +} +A F::m_fn1() const { const_cast<F *>(this)->d_ptr->m_fn1(); } 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/template/cond2.C b/gcc/testsuite/g++.dg/template/cond2.C index fad86bebe51..e6bd19d40fa 100644 --- a/gcc/testsuite/g++.dg/template/cond2.C +++ b/gcc/testsuite/g++.dg/template/cond2.C @@ -6,5 +6,5 @@ template<int X> class c; template<int X, int Y> int test(c<X ? : Y>&); // { dg-error "omitted" } void test(c<2>*c2) { - test<0, 2>(*c2); // { dg-message "required" } + test<0, 2>(*c2); } diff --git a/gcc/testsuite/g++.dg/template/inherit9.C b/gcc/testsuite/g++.dg/template/inherit9.C new file mode 100644 index 00000000000..926343b4e23 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/inherit9.C @@ -0,0 +1,15 @@ +// PR c++/58273 + +class A {}; +class B +{ + int goo(A); +}; +template<typename E> +class D : public B +{ + void foo(A t) + { + int const i(B::goo(t)); + } +}; diff --git a/gcc/testsuite/g++.dg/template/pseudodtor2.C b/gcc/testsuite/g++.dg/template/pseudodtor2.C index 796aff0785b..d4a9ac1cbc8 100644 --- a/gcc/testsuite/g++.dg/template/pseudodtor2.C +++ b/gcc/testsuite/g++.dg/template/pseudodtor2.C @@ -6,7 +6,7 @@ template<typename S> struct D typedef int T; S foo (); - D () { foo ().~T(); } // { dg-error "is not of type" } + D () { foo ().~T(); } // { dg-error "10:is not of type" } }; struct Z diff --git a/gcc/testsuite/g++.dg/template/pseudodtor3.C b/gcc/testsuite/g++.dg/template/pseudodtor3.C index 5f392f4e492..202182f5337 100644 --- a/gcc/testsuite/g++.dg/template/pseudodtor3.C +++ b/gcc/testsuite/g++.dg/template/pseudodtor3.C @@ -5,13 +5,13 @@ struct A { typedef int T; T &foo (); - A () { foo.~T (); } // { dg-error "does not have class type|expected" } + A () { foo.~T (); } // { dg-error "10:does not have class type|expected" } }; template <typename T> struct B { T &foo (); - B () { foo.~T (); } // { dg-error "invalid use of member" } + B () { foo.~T (); } // { dg-error "10:invalid use of member" } }; B<int> b; @@ -19,7 +19,7 @@ B<int> b; template <typename T, typename S> struct C { T t; - C () { t.~S (); } // { dg-error "is not of type" } + C () { t.~S (); } // { dg-error "10:is not of type" } }; C<int, long int> c; @@ -28,7 +28,7 @@ template <typename T> struct D { T t; typedef long int U; - D () { t.~U (); } // { dg-error "is not of type" } + D () { t.~U (); } // { dg-error "10:is not of type" } }; D<int> d; @@ -37,7 +37,7 @@ template <typename T> struct E { T &foo (); typedef long int U; - E () { foo.~U (); } // { dg-error "is not of type" } + E () { foo.~U (); } // { dg-error "10:is not of type" } }; E<int> e; diff --git a/gcc/testsuite/g++.dg/tm/noexcept-6.C b/gcc/testsuite/g++.dg/tm/noexcept-6.C new file mode 100644 index 00000000000..4391159e235 --- /dev/null +++ b/gcc/testsuite/g++.dg/tm/noexcept-6.C @@ -0,0 +1,23 @@ +// { dg-do compile } +// { dg-options "-fno-exceptions -fgnu-tm -O -std=c++0x -fdump-tree-tmlower" } + +struct TrueFalse +{ + static constexpr bool v() { return true; } +}; + +int global; + +template<typename T> int foo() +{ + return __transaction_atomic noexcept(T::v()) (global + 1); +} + +int f1() +{ + return foo<TrueFalse>(); +} + +/* { dg-final { scan-tree-dump-times "eh_must_not_throw" 0 "tmlower" } } */ +/* { dg-final { scan-tree-dump-times "__transaction_atomic" 1 "tmlower" } } */ +/* { dg-final { cleanup-tree-dump "tmlower" } } */ diff --git a/gcc/testsuite/g++.dg/torture/PR58294.C b/gcc/testsuite/g++.dg/torture/PR58294.C new file mode 100644 index 00000000000..e1fb95ae23d --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/PR58294.C @@ -0,0 +1,20 @@ +// { dg-do compile } +struct A { + virtual ~A(); + virtual void m_fn1() { delete this; } + void m_fn2() { m_fn1(); } +}; + +struct B { + A *pi_; + B() { pi_->m_fn2(); } +}; +struct C { + B pn; +}; +void _setjmp(); +int png_decode() { + _setjmp(); + C a; + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/pr58201.h b/gcc/testsuite/g++.dg/torture/pr58201.h new file mode 100644 index 00000000000..6071ccdf877 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr58201.h @@ -0,0 +1,24 @@ +class A +{ + protected: + A(); + virtual ~A(); +}; + +class B : virtual public A +{ + public: + B(); + virtual ~B(); +}; + +class C +{ + private: + class C2 : public B + { + public: + C2(); + virtual ~C2(); + }; +}; diff --git a/gcc/testsuite/g++.dg/torture/pr58201_0.C b/gcc/testsuite/g++.dg/torture/pr58201_0.C new file mode 100644 index 00000000000..f8fa7173c11 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr58201_0.C @@ -0,0 +1,9 @@ +#include "pr58201.h" + +C::C2::C2(){ } +C::C2::~C2() { } + +int main () +{ + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/pr58201_1.C b/gcc/testsuite/g++.dg/torture/pr58201_1.C new file mode 100644 index 00000000000..132cd5a43b8 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr58201_1.C @@ -0,0 +1,10 @@ +/* { dg-do link } */ +/* { dg-options "-O2" } */ +/* { dg-additional-sources "pr58201_0.C" } */ +#include "pr58201.h" + +A::A() { } +A::~A() { } +B::B() { } +B::~B() { } + diff --git a/gcc/testsuite/g++.dg/torture/pr58380.C b/gcc/testsuite/g++.dg/torture/pr58380.C new file mode 100644 index 00000000000..3a6ca942067 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr58380.C @@ -0,0 +1,173 @@ +// { dg-do compile } +// { dg-options "-w" } + +class iplugin_factory; +class idocument_plugin_factory { + virtual idocument_plugin_factory *create_plugin(iplugin_factory &, int &); +}; +template <typename _Iterator, typename> class __normal_iterator { + _Iterator _M_current; + +public: + _Iterator iterator_type; + __normal_iterator(const _Iterator &p1) : _M_current(p1) {} + void operator++(); + _Iterator &base() { return _M_current; } +}; + +template <typename _IteratorL, typename _IteratorR, typename _Container> +int operator!=(__normal_iterator<_IteratorL, _Container> &p1, + __normal_iterator<_IteratorR, _Container> &p2) { + return p1.base() != p2.base(); +} + +class new_allocator { +public: + typedef int *const_pointer; + int *allocate(); +}; +template <typename> class allocator : public new_allocator {}; + +class basic_string { +public: + basic_string(char *); +}; +struct __uninitialized_copy { + template <typename _InputIterator, typename _ForwardIterator> + static _ForwardIterator __uninit_copy(_InputIterator p1, _InputIterator p2, + _ForwardIterator p3) try { + for (; p1 != p2; ++p1, ++p3) + ; + return p3; + } + catch (...) { + } +}; + +template <typename _InputIterator, typename _ForwardIterator> +_ForwardIterator uninitialized_copy(_InputIterator p1, _InputIterator p2, + _ForwardIterator p3) { + return __uninitialized_copy::__uninit_copy(p1, p2, p3); +} + +template <typename _InputIterator, typename _ForwardIterator, typename _Tp> +_ForwardIterator __uninitialized_copy_a(_InputIterator p1, _InputIterator p2, + _ForwardIterator p3, allocator<_Tp> &) { + return uninitialized_copy(p1, p2, p3); +} + +struct _Vector_base { + struct _Vector_impl : allocator<int> { + int *_M_start; + int *_M_finish; + }; + allocator<int> &_M_get_Tp_allocator() {} + _Vector_base() {} + _Vector_base(int p1) { _M_create_storage(p1); } + _Vector_impl _M_impl; + int *_M_allocate(int p1) { p1 ? _M_impl.allocate() : 0; } + void _M_create_storage(int p1) { + this->_M_impl._M_start = this->_M_allocate(p1); + } +}; + +class vector : _Vector_base { + _Vector_base _Base; + +public: + vector() {} + vector(const vector &p1) : _Base(p1.size()) { + this->_M_impl._M_finish = __uninitialized_copy_a( + p1.begin(), p1.end(), this->_M_impl._M_start, _M_get_Tp_allocator()); + } + ~vector(); + __normal_iterator<typename allocator<int>::const_pointer, int> begin() const { + return this->_M_impl._M_start; + } + __normal_iterator<typename allocator<int>::const_pointer, int> end() const { + return this->_M_impl._M_finish; + } + int size() const { return this->_M_impl._M_finish - this->_M_impl._M_start; } +}; +class iplugin_factory { +public: + typedef enum { + STABLE, + EXPERIMENTAL + } quality_t; +}; +class plugin_factory : public iplugin_factory { +public: + plugin_factory(const int &, const basic_string &, const basic_string &, + const basic_string &, quality_t); +}; +template <typename plugin_t> +class document_plugin_factory : plugin_factory, idocument_plugin_factory { +public: + document_plugin_factory(const int &p1, const basic_string &, + const basic_string &, const basic_string &, quality_t) + : plugin_factory(0, 0, 0, 0, STABLE) {} + idocument_plugin_factory *create_plugin(iplugin_factory &p1, int &p2) { + plugin_t(p1, p2); + } +}; + +class container { +public: + template <typename init_t> container(init_t &); +}; +template <class init_t> class initializer_t : init_t { +public: + initializer_t(const init_t &p1) : init_t(p1) {} +}; + +class composition_t {}; +template <typename lhs_t, typename rhs_t> +const initializer_t<composition_t> operator+(const initializer_t<lhs_t> &, + const initializer_t<rhs_t> &); +template <typename value_t> class value_initializer_t { +public: + value_initializer_t(const value_t &p1) : m_value(p1) {} + value_t m_value; +}; + +template <typename value_t> +initializer_t<value_initializer_t<value_t> > init_value(const value_t &p1) { + initializer_t<value_initializer_t<value_t> >( + value_initializer_t<value_t>(p1)); +} + +class name_t {}; +class label_t {}; +class description_t {}; +class owner_initializer_t {}; +template <typename owner_t> +initializer_t<owner_initializer_t> init_owner(owner_t &); +class set : vector {}; +class node { +public: + node(iplugin_factory &, int &); +}; +initializer_t<name_t> init_name(); +initializer_t<label_t> init_label(); +initializer_t<description_t> init_description(); +template <typename base_t> class mesh_selection_sink : base_t { +public: + mesh_selection_sink(iplugin_factory &p1, int &p2) + : base_t(p1, p2), + m_mesh_selection(init_owner(*this) + init_name() + init_label() + + init_description() + init_value(set())) {} + container m_mesh_selection; +}; + +class selection_to_stdout : mesh_selection_sink<node> { +public: + selection_to_stdout(iplugin_factory &p1, int &p2) + : mesh_selection_sink(p1, p2) {} + static iplugin_factory &get_factory() { + document_plugin_factory<selection_to_stdout>(0, "", 0, "", + iplugin_factory::EXPERIMENTAL); + } +}; + +void selection_to_stdout_factory() { selection_to_stdout::get_factory(); } diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr58404.C b/gcc/testsuite/g++.dg/tree-ssa/pr58404.C new file mode 100644 index 00000000000..aa8fb796c6f --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr58404.C @@ -0,0 +1,20 @@ +// { dg-do compile } +// { dg-options "-O -fdump-tree-cddce1" } + +struct S { int s; }; +S a[1024]; + +void +foo () +{ + for (int i = 0; i < 1024; i++) + { + S &r = a[i]; + r.s++; + } +} + +// We should propagate the reference into both memory accesses +// during the first forwprop pass +// { dg-final { scan-tree-dump-times "= &a" 0 "cddce1" } } +// { dg-final { cleanup-tree-dump "cddce1" } } 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/g++.dg/uninit-pred-4.C b/gcc/testsuite/g++.dg/uninit-pred-4.C new file mode 100644 index 00000000000..94ab13c50d6 --- /dev/null +++ b/gcc/testsuite/g++.dg/uninit-pred-4.C @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -Og" } */ + +int pop (); +int pop_first_bucket; + +int my_pop () +{ + int out; // { dg-bogus "uninitialized" "uninitialized variable warning" } + + while (pop_first_bucket) + if (pop_first_bucket && (out = pop())) + return out; + + return 0; +} diff --git a/gcc/testsuite/g++.dg/warn/Wdelete-incomplete-1.C b/gcc/testsuite/g++.dg/warn/Wdelete-incomplete-1.C new file mode 100644 index 00000000000..69689ba3488 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wdelete-incomplete-1.C @@ -0,0 +1,7 @@ +// PR c++/43452 + +class Foo; // { dg-warning "forward" } +int main() { + Foo* p; // { dg-warning "incomplete" } + delete [] p; // { dg-warning "problem" } +} diff --git a/gcc/testsuite/g++.dg/warn/Wdelete-incomplete-2.C b/gcc/testsuite/g++.dg/warn/Wdelete-incomplete-2.C new file mode 100644 index 00000000000..6c3aaa74f1a --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wdelete-incomplete-2.C @@ -0,0 +1,8 @@ +// PR c++/43452 +// { dg-options -Wno-delete-incomplete } + +class Foo; +int main() { + Foo* p; + delete [] p; +} diff --git a/gcc/testsuite/g++.dg/warn/Wunused-parm-5.C b/gcc/testsuite/g++.dg/warn/Wunused-parm-5.C new file mode 100644 index 00000000000..e952d0221bd --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wunused-parm-5.C @@ -0,0 +1,14 @@ +// PR c++/58362 +// { dg-options "-Wunused-parameter" } + +void f1 (long s) { } // { dg-warning "15:unused parameter 's'" } + +void f2 (long s, int u) { } // { dg-warning "15:unused parameter 's'" } +// { dg-warning "22:unused parameter 'u'" "" { target *-*-* } 6 } + +void f3 (long s); +void f3 (long s) { } // { dg-warning "15:unused parameter 's'" } + +void f4 (long s, int u); +void f4 (long s, int u) { } // { dg-warning "15:unused parameter 's'" } +// { dg-warning "22:unused parameter 'u'" "" { target *-*-* } 13 } diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-21.C b/gcc/testsuite/g++.dg/warn/Wunused-var-21.C new file mode 100644 index 00000000000..d279e598033 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wunused-var-21.C @@ -0,0 +1,31 @@ +// PR c++/58325 +// { dg-do compile } +// { dg-options "-Wunused" } + +void +f1 () +{ + int *volatile a = new int[1]; + delete[] a; +} + +void +f2 () +{ + int *b = new int[1]; + delete[] b; +} + +void +f3 () +{ + int *volatile c = new int; + delete c; +} + +void +f4 () +{ + int *d = new int; + delete d; +} diff --git a/gcc/testsuite/g++.dg/warn/weak1.C b/gcc/testsuite/g++.dg/warn/weak1.C index efce90a2bcf..456e6f34c53 100644 --- a/gcc/testsuite/g++.dg/warn/weak1.C +++ b/gcc/testsuite/g++.dg/warn/weak1.C @@ -2,6 +2,7 @@ // { dg-require-weak "" } // The PA HP-UX dynamic loader doesn't support unsatisfied weak symbols. // { dg-skip-if "No unsat" { hppa*-*-hpux* } { "*" } { "" } } +// { dg-skip-if "No weak unsat" { *-*-aix* } { "*" } { "" } } // The darwin loader does, but they do need to exist at link time. // { dg-skip-if "No link unsat" { *-*-darwin* } { "*" } { "" } } // For kernel modules and static RTPs, the loader treats undefined weak 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/compile/pr58340.c b/gcc/testsuite/gcc.c-torture/compile/pr58340.c new file mode 100644 index 00000000000..ca3ccda0a47 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr58340.c @@ -0,0 +1,16 @@ +int a, b, c, d; + +int foo (int x, int y) +{ + return y == 0 ? x : 1 % y; +} + +int main () +{ + c = 0 || a; + + for (;;) + b = foo (d, c) && 1; + + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr58343.c b/gcc/testsuite/gcc.c-torture/compile/pr58343.c new file mode 100644 index 00000000000..cdd2ce9f4a6 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr58343.c @@ -0,0 +1,15 @@ +int a; + +int main () +{ + int b = a; + + for (a = 1; a > 0; a--) + ; + + lbl: + if (b && a) + goto lbl; + + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c index 8d821839b1a..bd54318a263 100644 --- a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c +++ b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c @@ -43,6 +43,9 @@ #elif defined (__CRIS__) /* No SIGFPE for CRIS integer division. */ # define DO_TEST 0 +#elif defined (__arc__) + /* No SIGFPE for ARC integer division. */ +# define DO_TEST 0 #elif defined (__arm__) && defined (__ARM_EABI__) # ifdef __ARM_ARCH_EXT_IDIV__ /* Hardware division instructions may not trap, and handle trapping diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58364.c b/gcc/testsuite/gcc.c-torture/execute/pr58364.c new file mode 100644 index 00000000000..59ad7b47a16 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr58364.c @@ -0,0 +1,17 @@ +/* PR tree-optimization/58364 */ + +int a = 1, b, c; + +int +foo (int x) +{ + return x < 0 ? 1 : x; +} + +int +main () +{ + if (foo (a > c == (b = 0))) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58365.c b/gcc/testsuite/gcc.c-torture/execute/pr58365.c new file mode 100644 index 00000000000..1e6079d8429 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr58365.c @@ -0,0 +1,35 @@ +/* PR rtl-optimization/58365 */ + +extern void abort (void); + +struct S +{ + volatile int a; + int b, c, d, e; +} f; +static struct S g, h; +int i = 1; + +char +foo (void) +{ + return i; +} + +static struct S +bar (void) +{ + if (foo ()) + return f; + return g; +} + +int +main () +{ + h = bar (); + f.b = 1; + if (h.b != 0) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58385.c b/gcc/testsuite/gcc.c-torture/execute/pr58385.c new file mode 100644 index 00000000000..8d7da6fc972 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr58385.c @@ -0,0 +1,21 @@ +/* PR tree-optimization/58385 */ + +extern void abort (void); + +int a, b = 1; + +int +foo () +{ + b = 0; + return 0; +} + +int +main () +{ + ((0 || a) & foo () >= 0) <= 1 && 1; + if (b) + abort (); + return 0; +} 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/autopar/pr49960.c b/gcc/testsuite/gcc.dg/autopar/pr49960.c index b34a5207755..5dacb8de84a 100644 --- a/gcc/testsuite/gcc.dg/autopar/pr49960.c +++ b/gcc/testsuite/gcc.dg/autopar/pr49960.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */ +/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized -fno-partial-inlining" } */ #include <stdio.h> #define MB 100 @@ -12,7 +12,9 @@ void MRTRBR(int MA_1, int NA_1, int MB_1) int i,j, t,k; /* At the moment we are not able to hoist the loop headers out of the loop - nest. */ + nest. + Partial inlining needs to be disabled so we do not optimize this out + of the function body. */ if (MA_1 < 4 || NA_1 < 4 || MB_1 < 4) return; diff --git a/gcc/testsuite/gcc.dg/builtin-apply2.c b/gcc/testsuite/gcc.dg/builtin-apply2.c index 9b731470e6c..daaef477894 100644 --- a/gcc/testsuite/gcc.dg/builtin-apply2.c +++ b/gcc/testsuite/gcc.dg/builtin-apply2.c @@ -17,7 +17,7 @@ E, F and G are passed on stack. So the size of the stack argument data is 20. */ #define STACK_ARGUMENTS_SIZE 20 -#elif defined __MMIX__ +#elif defined __MMIX__ || defined __arc__ /* No parameters on stack for bar. */ #define STACK_ARGUMENTS_SIZE 0 #else diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/omp-fesdr.c b/gcc/testsuite/gcc.dg/debug/dwarf2/omp-fesdr.c new file mode 100644 index 00000000000..d7b03192be2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/omp-fesdr.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target fopenmp } */ +/* { dg-options "-g -fopenmp -gdwarf-2 -femit-struct-debug-reduced" } */ + +struct aa +{ + int a; +}; + +int +f7 (void) +{ + int v7i = 6, v7j = 7, v7k = 9, v7l = 0, v7n = 0, v7o = 1; + + #pragma omp parallel + { + #pragma omp master + v7o++; + #pragma omp for private (v7i) firstprivate (v7k) reduction (+:v7l) + for (v7n = 0; v7n < 3; v7n++) + { + int v7m = v7j + v7k; + v7i = 8; + v7l++; + } + } + + return v7i + v7j + v7k + v7l + v7n; +} + +int +main (void) +{ + f7 (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c index e8abc3244a0..ed59cbfda00 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c @@ -22,7 +22,8 @@ int main() a.p = (void *)&c; p = foo(&a, &a); /* { dg-final { scan-ipa-dump "foo.result = { NULL a\[^ \]* c\[^ \]* }" "pta" { xfail *-*-* } } } */ - /* { dg-final { scan-ipa-dump "foo.result = { NULL a\[^ \]* a\[^ \]* c\[^ \]* }" "pta" } } */ + /* { dg-final { scan-ipa-dump "foo.result = { NULL a\[^ \]* a\[^ \]* c\[^ \]* }" "pta" { target { ! keeps_null_pointer_checks } } } } */ + /* { dg-final { scan-ipa-dump "foo.result = { NONLOCAL a\[^ \]* a\[^ \]* c\[^ \]* }" "pta" { target { keeps_null_pointer_checks } } } } */ ((struct X *)p)->p = (void *)0; if (a.p != (void *)0) abort (); 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/stack-usage-1.c b/gcc/testsuite/gcc.dg/stack-usage-1.c index fa299c4385a..ff9709ad4a2 100644 --- a/gcc/testsuite/gcc.dg/stack-usage-1.c +++ b/gcc/testsuite/gcc.dg/stack-usage-1.c @@ -9,6 +9,8 @@ #if defined(__aarch64__) # define SIZE 256 /* No frame pointer for leaf functions (default) */ +#elif defined(__arc__) +# define SIZE (256-4) #elif defined(__i386__) # define SIZE 248 #elif defined(__x86_64__) diff --git a/gcc/testsuite/gcc.dg/torture/memcpy-1.c b/gcc/testsuite/gcc.dg/torture/memcpy-1.c new file mode 100644 index 00000000000..290c78923e4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/memcpy-1.c @@ -0,0 +1,22 @@ +/* { dg-do run } */ +/* { dg-additional-options "-mtune=pentiumpro" { target ia32 } } */ +/* { dg-additional-options "-minline-all-stringops" { target { i?86-*-* x86_64-*-* } } } */ + +static void __attribute__((noinline, noclone)) +my_memcpy (char *dest, const char *src, int n) +{ + __builtin_memcpy (dest, src, n); +} + +int +main (void) +{ + char a1[4], a2[4]; + __builtin_memset (a1, 'a', 4); + __builtin_memset (a2, 'b', 4); + my_memcpy (a2, a1, 4); + if (a2[0] != 'a') + __builtin_abort (); + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/torture/pr37868.c b/gcc/testsuite/gcc.dg/torture/pr37868.c index 2b245ebf49b..cc9c24f49bb 100644 --- a/gcc/testsuite/gcc.dg/torture/pr37868.c +++ b/gcc/testsuite/gcc.dg/torture/pr37868.c @@ -1,6 +1,6 @@ /* { dg-do run } */ /* { dg-options "-fno-strict-aliasing" } */ -/* { dg-skip-if "unaligned access" { epiphany-*-* sparc*-*-* sh*-*-* tic6x-*-* } "*" "" } */ +/* { dg-skip-if "unaligned access" { arc*-*-* epiphany-*-* sparc*-*-* sh*-*-* tic6x-*-* } "*" "" } */ extern void abort (void); #if (__SIZEOF_INT__ <= 2) diff --git a/gcc/testsuite/gcc.dg/torture/pr57748-1.c b/gcc/testsuite/gcc.dg/torture/pr57748-1.c new file mode 100644 index 00000000000..dc0fcdc3b85 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr57748-1.c @@ -0,0 +1,49 @@ +/* PR middle-end/57748 */ +/* { dg-do run } */ +/* ICE in expand_assignment: + misalignp == true, !MEM_P (to_rtx), offset != 0, + => gcc_assert (TREE_CODE (offset) == INTEGER_CST) */ + +#include <stdlib.h> + +extern void abort (void); + +typedef long long V + __attribute__ ((vector_size (2 * sizeof (long long)), may_alias)); + +typedef struct S { V a; V b[0]; } P __attribute__((aligned (1))); + +struct __attribute__((packed)) T { char c; P s; }; + +void __attribute__((noinline, noclone)) +check (struct T *t) +{ + if (t->s.b[0][0] != 3 || t->s.b[0][1] != 4) + abort (); +} + +int __attribute__((noinline, noclone)) +get_i (void) +{ + return 0; +} + +void __attribute__((noinline, noclone)) +foo (P *p) +{ + V a = { 3, 4 }; + int i = get_i (); + p->b[i] = a; +} + +int +main () +{ + struct T *t = (struct T *) calloc (128, 1); + + foo (&t->s); + check (t); + + free (t); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr57748-2.c b/gcc/testsuite/gcc.dg/torture/pr57748-2.c new file mode 100644 index 00000000000..4e3b4b88468 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr57748-2.c @@ -0,0 +1,43 @@ +/* PR middle-end/57748 */ +/* { dg-do run } */ +/* wrong code in expand_assignment: + misalignp == true, !MEM_P (to_rtx), + offset == 0, bitpos >= GET_MODE_PRECISION, + => result = NULL. */ + +#include <stdlib.h> + +extern void abort (void); + +typedef long long V + __attribute__ ((vector_size (2 * sizeof (long long)), may_alias)); + +typedef struct S { V a; V b[0]; } P __attribute__((aligned (1))); + +struct __attribute__((packed)) T { char c; P s; }; + +void __attribute__((noinline, noclone)) +check (struct T *t) +{ + if (t->s.b[0][0] != 3 || t->s.b[0][1] != 4) + abort (); +} + +void __attribute__((noinline, noclone)) +foo (P *p) +{ + V a = { 3, 4 }; + p->b[0] = a; +} + +int +main () +{ + struct T *t = (struct T *) calloc (128, 1); + + foo (&t->s); + check (t); + + free (t); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr58326-1.c b/gcc/testsuite/gcc.dg/torture/pr58326-1.c new file mode 100644 index 00000000000..3b46eed9cac --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr58326-1.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ + +int a, *d; +long b; +short c; + +void foo () +{ + int e; +lbl: + for (c = 0; c < 2; c++) + { + if (1 >> b) + break; + e = *d; + for (; a; a++) + { + *d = e; + if (b) + goto lbl; + } + } +} diff --git a/gcc/testsuite/gcc.dg/torture/pr58326-2.c b/gcc/testsuite/gcc.dg/torture/pr58326-2.c new file mode 100644 index 00000000000..ddddbbe5785 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr58326-2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ + +int a, b, c, d; + +void foo () +{ + int e; + +lbl: + for (c = 0; c < 2; c++) + { + e = d; + for (; a; a++) + { + d = e; + if (b) + goto lbl; + } + } +} 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/torture/stackalign/builtin-apply-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c index f683a2a042d..ed81e808309 100644 --- a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c +++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c @@ -19,7 +19,7 @@ E, F and G are passed on stack. So the size of the stack argument data is 20. */ #define STACK_ARGUMENTS_SIZE 20 -#elif defined __aarch64__ || defined __MMIX__ +#elif defined __aarch64__ || defined __arc__ || defined __MMIX__ /* No parameters on stack for bar. */ #define STACK_ARGUMENTS_SIZE 0 #else diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-22.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-22.c new file mode 100644 index 00000000000..afc792f6503 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-22.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fdump-tree-ldist-details" } */ + +extern void abort (void); + +int a[1024], b[1024]; + +void __attribute__((noinline,noclone)) +foo (void) +{ + int i; + for (i = 0; i < 1024; ++i) + { + a[i] = 0; + if (i > 100) + b[i] = i; + } +} + +int main() +{ + b[100] = 1; + foo (); + if (b[100] != 1 || b[101] != 101) + abort (); + if (a[0] != 0 || a[101] != 0) + abort (); + return 0; +} + +/* { dg-final { scan-tree-dump "generated memset zero" "ldist" } } */ +/* { dg-final { cleanup-tree-dump "ldist" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-23.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-23.c new file mode 100644 index 00000000000..22b82d9920d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-23.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fdump-tree-ldist-details" } */ + +extern void abort (void); + +int a[128], b[128], c[128], d[128]; + +void __attribute__((noinline,noclone)) +foo (void) +{ + int i; + for (i = 0; i < 128; ++i) + { + a[i] = a[i] + 1; + b[i] = d[i]; + c[i] = a[i] / d[i]; + } +} +int main() +{ + int i; + for (i = 0; i < 128; ++i) + a[i] = i; + for (i = 0; i < 128; ++i) + d[i] = 1; + foo (); + if (c[0] != 1) + abort (); + return 0; +} + +/* { dg-final { scan-tree-dump "split to 2 loops" "ldist" } } */ +/* { dg-final { scan-tree-dump "generated memcpy" "ldist" } } */ +/* { dg-final { cleanup-tree-dump "ldist" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-4.c index a744fea020a..80626bdacac 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ldist-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-4.c @@ -10,20 +10,18 @@ int loop1 (int k) a[0] = k; for (i = 1; i < 100; i ++) { - for (j = 0; j < 100; j++) + for (j = 1; j < 100; j++) { a[j] = k * i; b[i][j] = a[j-1] + k; } } - return b[100-1][0]; + return b[100-1][1]; } -/* We used to distribute also innermost loops, but these could produce - too much code in the outer loop, degrading performance of scalar - code. So this test was XFAILed because the cost model of the stand - alone distribution pass has evolved. Now it passes. */ -/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 0 "ldist" { target ilp32 } } } */ -/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 1 "ldist" { target lp64 } } } */ +/* The current cost model fuses the two partitions because they have + similar memory accesses. */ +/* { dg-final { scan-tree-dump "similar memory accesses" "ldist" } } */ +/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 0 "ldist" } } */ /* { dg-final { cleanup-tree-dump "ldist" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c index a4244171305..dcfae5dd957 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c @@ -33,5 +33,6 @@ int main() return 0; } -/* { dg-final { scan-tree-dump "ESCAPED = { NULL ESCAPED NONLOCAL x }" "alias" } } */ +/* { dg-final { scan-tree-dump "ESCAPED = { NULL ESCAPED NONLOCAL x }" "alias" { target { ! keeps_null_pointer_checks } } } } */ +/* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL x }" "alias" { target { keeps_null_pointer_checks } } } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c index 8580382fca6..e6139591ec8 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c @@ -34,5 +34,6 @@ int main() return 0; } -/* { dg-final { scan-tree-dump "ESCAPED = { NULL ESCAPED NONLOCAL x }" "alias" } } */ +/* { dg-final { scan-tree-dump "ESCAPED = { NULL ESCAPED NONLOCAL x }" "alias" { target { ! keeps_null_pointer_checks } } } } */ +/* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL x }" "alias" { target { keeps_null_pointer_checks } } } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c index 5a121a0d9a7..870dcf6b19a 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c @@ -38,5 +38,6 @@ int main() return 0; } -/* { dg-final { scan-tree-dump "ESCAPED = { NULL ESCAPED NONLOCAL x }" "alias" } } */ +/* { dg-final { scan-tree-dump "ESCAPED = { NULL ESCAPED NONLOCAL x }" "alias" { target { ! keeps_null_pointer_checks } } } } */ +/* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL x }" "alias" { target { keeps_null_pointer_checks } } } } */ /* { dg-final { cleanup-tree-dump "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-31.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-31.c new file mode 100644 index 00000000000..1c1527f1350 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-31.c @@ -0,0 +1,17 @@ +/* PR tree-optimization/58011 */ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ +int a, b; + +void f(unsigned p) +{ + unsigned *pp = &p; + + if(!a) + p = 0; + + for(b = 0; b < 1; b++) + if(3 * p + 5 * *pp) + a = 0; +} + 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/tree-ssa/ssa-dom-thread-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c index c2efd15eb33..d2a1fbb436a 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c @@ -45,3 +45,5 @@ expand_one_var (tree var, unsigned char toplevel, unsigned char really_expand) /* { dg-final { scan-tree-dump-times "Threaded" 1 "dom1"} } */ /* { dg-final { scan-tree-dump-times "Registering jump thread .through joiner block.: \\(.*\\); \\(.*\\); \\(.*\\);" 1 "dom1"} } */ +/* { dg-final { cleanup-tree-dump "dom1" } } */ + 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/cmn-neg.c b/gcc/testsuite/gcc.target/aarch64/cmn-neg.c new file mode 100644 index 00000000000..05c8bbff5be --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/cmn-neg.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ + +extern void abort (void); + +void __attribute__ ((noinline)) +foo_s32 (int a, int b) +{ + if (a < -b) + abort (); +} +/* { dg-final { scan-assembler "cmn\tw\[0-9\]" } } */ + +void __attribute__ ((noinline)) +foo_s64 (long long a, long long b) +{ + if (a < -b) + abort (); +} +/* { dg-final { scan-assembler "cmn\tx\[0-9\]" } } */ + + +int +main (void) +{ + int a = 30; + int b = 42; + foo_s32 (a, b); + foo_s64 (a, b); + return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ 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/movdi_1.c b/gcc/testsuite/gcc.target/aarch64/movdi_1.c new file mode 100644 index 00000000000..a22378db00f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/movdi_1.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-inline" } */ + +#include <arm_neon.h> + +void +foo1 (uint64_t *a) +{ + uint64x1_t val18; + uint32x2_t val19; + uint64x1_t val20; + val19 = vcreate_u32 (0x800000004cf3dffbUL); + val20 = vrsra_n_u64 (val18, vreinterpret_u64_u32 (val19), 34); + vst1_u64 (a, val20); +} + +void +foo2 (uint64_t *a) +{ + uint64x1_t val18; + uint32x2_t val19; + uint64x1_t val20; + val19 = vcreate_u32 (0xdffbUL); + val20 = vrsra_n_u64 (val18, vreinterpret_u64_u32 (val19), 34); + vst1_u64 (a, val20); +} 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/aarch64/table-intrinsics.c b/gcc/testsuite/gcc.target/aarch64/table-intrinsics.c index 5d53abe8d10..6281cdae74e 100644 --- a/gcc/testsuite/gcc.target/aarch64/table-intrinsics.c +++ b/gcc/testsuite/gcc.target/aarch64/table-intrinsics.c @@ -148,7 +148,7 @@ tb_testp8_4 (poly8x8_t r, poly8x8x4_t tab, uint8x8_t idx) } int8x8_t -qtbl_tests8_ (int8x16_t tab, int8x8_t idx) +qtbl_tests8_ (int8x16_t tab, uint8x8_t idx) { return vqtbl1_s8 (tab, idx); } @@ -166,7 +166,7 @@ qtbl_testp8_ (poly8x16_t tab, uint8x8_t idx) } int8x8_t -qtbl_tests8_2 (int8x16x2_t tab, int8x8_t idx) +qtbl_tests8_2 (int8x16x2_t tab, uint8x8_t idx) { return vqtbl2_s8 (tab, idx); } @@ -184,7 +184,7 @@ qtbl_testp8_2 (poly8x16x2_t tab, uint8x8_t idx) } int8x8_t -qtbl_tests8_3 (int8x16x3_t tab, int8x8_t idx) +qtbl_tests8_3 (int8x16x3_t tab, uint8x8_t idx) { return vqtbl3_s8 (tab, idx); } @@ -202,7 +202,7 @@ qtbl_testp8_3 (poly8x16x3_t tab, uint8x8_t idx) } int8x8_t -qtbl_tests8_4 (int8x16x4_t tab, int8x8_t idx) +qtbl_tests8_4 (int8x16x4_t tab, uint8x8_t idx) { return vqtbl4_s8 (tab, idx); } @@ -220,7 +220,7 @@ qtbl_testp8_4 (poly8x16x4_t tab, uint8x8_t idx) } int8x8_t -qtb_tests8_ (int8x8_t r, int8x16_t tab, int8x8_t idx) +qtb_tests8_ (int8x8_t r, int8x16_t tab, uint8x8_t idx) { return vqtbx1_s8 (r, tab, idx); } @@ -238,7 +238,7 @@ qtb_testp8_ (poly8x8_t r, poly8x16_t tab, uint8x8_t idx) } int8x8_t -qtb_tests8_2 (int8x8_t r, int8x16x2_t tab, int8x8_t idx) +qtb_tests8_2 (int8x8_t r, int8x16x2_t tab, uint8x8_t idx) { return vqtbx2_s8 (r, tab, idx); } @@ -256,7 +256,7 @@ qtb_testp8_2 (poly8x8_t r, poly8x16x2_t tab, uint8x8_t idx) } int8x8_t -qtb_tests8_3 (int8x8_t r, int8x16x3_t tab, int8x8_t idx) +qtb_tests8_3 (int8x8_t r, int8x16x3_t tab, uint8x8_t idx) { return vqtbx3_s8 (r, tab, idx); } @@ -274,7 +274,7 @@ qtb_testp8_3 (poly8x8_t r, poly8x16x3_t tab, uint8x8_t idx) } int8x8_t -qtb_tests8_4 (int8x8_t r, int8x16x4_t tab, int8x8_t idx) +qtb_tests8_4 (int8x8_t r, int8x16x4_t tab, uint8x8_t idx) { return vqtbx4_s8 (r, tab, idx); } @@ -292,7 +292,7 @@ qtb_testp8_4 (poly8x8_t r, poly8x16x4_t tab, uint8x8_t idx) } int8x16_t -qtblq_tests8_ (int8x16_t tab, int8x16_t idx) +qtblq_tests8_ (int8x16_t tab, uint8x16_t idx) { return vqtbl1q_s8 (tab, idx); } @@ -310,7 +310,7 @@ qtblq_testp8_ (poly8x16_t tab, uint8x16_t idx) } int8x16_t -qtblq_tests8_2 (int8x16x2_t tab, int8x16_t idx) +qtblq_tests8_2 (int8x16x2_t tab, uint8x16_t idx) { return vqtbl2q_s8 (tab, idx); } @@ -328,7 +328,7 @@ qtblq_testp8_2 (poly8x16x2_t tab, uint8x16_t idx) } int8x16_t -qtblq_tests8_3 (int8x16x3_t tab, int8x16_t idx) +qtblq_tests8_3 (int8x16x3_t tab, uint8x16_t idx) { return vqtbl3q_s8 (tab, idx); } @@ -346,7 +346,7 @@ qtblq_testp8_3 (poly8x16x3_t tab, uint8x16_t idx) } int8x16_t -qtblq_tests8_4 (int8x16x4_t tab, int8x16_t idx) +qtblq_tests8_4 (int8x16x4_t tab, uint8x16_t idx) { return vqtbl4q_s8 (tab, idx); } @@ -364,7 +364,7 @@ qtblq_testp8_4 (poly8x16x4_t tab, uint8x16_t idx) } int8x16_t -qtbxq_tests8_ (int8x16_t r, int8x16_t tab, int8x16_t idx) +qtbxq_tests8_ (int8x16_t r, int8x16_t tab, uint8x16_t idx) { return vqtbx1q_s8 (r, tab, idx); } @@ -382,7 +382,7 @@ qtbxq_testp8_ (poly8x16_t r, poly8x16_t tab, uint8x16_t idx) } int8x16_t -qtbxq_tests8_2 (int8x16_t r, int8x16x2_t tab, int8x16_t idx) +qtbxq_tests8_2 (int8x16_t r, int8x16x2_t tab, uint8x16_t idx) { return vqtbx2q_s8 (r, tab, idx); } @@ -400,7 +400,7 @@ qtbxq_testp8_2 (poly8x16_t r, poly8x16x2_t tab, uint8x16_t idx) } int8x16_t -qtbxq_tests8_3 (int8x16_t r, int8x16x3_t tab, int8x16_t idx) +qtbxq_tests8_3 (int8x16_t r, int8x16x3_t tab, uint8x16_t idx) { return vqtbx3q_s8 (r, tab, idx); } @@ -418,7 +418,7 @@ qtbxq_testp8_3 (poly8x16_t r, poly8x16x3_t tab, uint8x16_t idx) } int8x16_t -qtbxq_tests8_4 (int8x16_t r, int8x16x4_t tab, int8x16_t idx) +qtbxq_tests8_4 (int8x16_t r, int8x16x4_t tab, uint8x16_t idx) { return vqtbx4q_s8 (r, tab, idx); } diff --git a/gcc/testsuite/gcc.target/arc/arc.exp b/gcc/testsuite/gcc.target/arc/arc.exp new file mode 100644 index 00000000000..83e2762e64a --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/arc.exp @@ -0,0 +1,41 @@ +# Copyright (C) 2007, 2011, 2012 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't an arc target. +if ![istarget arc*-*-*] then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-1.c b/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-1.c new file mode 100644 index 00000000000..b1990c628e9 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-1.c @@ -0,0 +1,16 @@ +/* { dg-do run } */ +/* { dg-options "-O" } */ + +extern void abort (void); + +/* In macros like optimized memset, we want to be able to decide what + alignment a passed pointer has. */ +#define f(p) __builtin_arc_aligned (p, 4) + +int main (void) +{ + int i; + if (f (&i) == 0) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-2.c b/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-2.c new file mode 100644 index 00000000000..d48a915b8bd --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-2.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ +/* { dg-options "-O" } */ + +extern void abort (void); + +typedef struct { + short x; +} mytype_t; + +mytype_t *__attribute__ ((noinline,weak)) +some_func (void) +{ + static mytype_t s; + return &s; +}; + +int main (void) +{ + int y, y2; + mytype_t *shorter = some_func(); + y = __builtin_arc_aligned (shorter, 2); + if (!y) + abort (); + y2 = __builtin_arc_aligned (shorter, 4); + if (y2) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-3.c b/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-3.c new file mode 100644 index 00000000000..23d80edd478 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-3.c @@ -0,0 +1,67 @@ +/* { dg-do run } */ +/* { dg-options "-O" } */ + +extern void abort (void); + +typedef struct { + int b, c; +} +__attribute__((aligned(32))) inner_t; // data type is 32 byte aligned + +typedef struct { + inner_t *inner; + int a; +} outer_t; + +void __attribute__ ((noinline,weak)) +somefunc (int a, int b, int c) +{ + if (!a || !b || c) + abort (); +}; + +__attribute__ ((noinline,weak)) +outer_t * +some_alloc_1 () +{ + static outer_t x; + return &x; +} + +__attribute__ ((noinline,weak)) +inner_t * +some_alloc_2 () +{ + static inner_t x; + return &x; +} + +int main (void) +{ + int y, y2, y3; + // @p_out is pointing to instance of outer_t, naturally aligned to 4+4 = 8 + // and not gauranteed be 32 byte aligned. + outer_t *p_out = some_alloc_1( ); // returns 8 byte aligned ptr + + // @ptr is pointing to instance of inner_t which is naturally aligned to 32. + // It is assigned to p_out->inner which is of type inner_t thus 32 byte + // aligned as well + // Note that gcc can deduce p_out->inner is 32b aligned, not at runtime, + // because it was assigned @ptr, but even at compile time, because it's data + // type is naturally 32 byte aligned. + inner_t *ptr = some_alloc_2(); // returns 32 byte aligned ptr + p_out->inner = ptr; // this ptr will also be 32 byte aligned + + y = __builtin_arc_aligned(ptr, 32); // this shd return 1 + y2 = __builtin_arc_aligned(p_out->inner, 32); // this also shd return 1 + // Although p_out->inner ptr is 32 byte aligned, + // it's container &(p_out->inner) need not be. + // That is because the hoister has no relation to contents. + // p_out is not gauranteed to be 32 byte + // aligned, so it's member @inner in p_out need not be. + y3 = __builtin_arc_aligned(&(p_out->inner), 32); + // compiler not sure, so must return 0 + + somefunc(y, y2, y3); + return 0; +} diff --git a/gcc/testsuite/gcc.target/arc/cond-set-use.c b/gcc/testsuite/gcc.target/arc/cond-set-use.c new file mode 100644 index 00000000000..aee27251a5c --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/cond-set-use.c @@ -0,0 +1,128 @@ +/* { dg-do run } */ +/* { dg-options "-Os" } */ + +/* Based on gethostbyname_r, + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB + * + * Extraction / wrapping as test by + * Joern Rennecke <joern.rennecke@embecosm.com> + * Copyright (C) 2013 Free Software Foundation, Inc. + */ + +typedef unsigned size_t; +typedef int ssize_t; +typedef unsigned uint32_t; +struct resolv_answer { + char *dotted; + int atype; + int aclass; + int ttl; + int rdlength; + const unsigned char *rdata; + int rdoffset; + char* buf; + size_t buflen; + size_t add_count; +}; +struct hostent +{ + char *h_name; + char **h_aliases; + int h_addrtype; + int h_length; + char **h_addr_list; +}; + +int *__attribute__ ((noinline,weak)) nop (void * p) { return p; }; +void __attribute__ ((noinline,weak)) seta (struct resolv_answer * p) +{ p->atype = 1;} + +int ghostbyname_r( + struct hostent *result_buf, + char *buf, + size_t buflen, + struct hostent **result, + int *h_errnop) +{ + char **addr_list; + char **alias; + char *alias0; + int i0; + struct resolv_answer a; + int i; + + *result = ((void *)0); + + *h_errnop = -1; + + if ((ssize_t)buflen <= 5) + return 34; + + alias = (char **)buf; + addr_list = (char **)buf; + + /* This got turned into branch with conditional move in delay slot. */ + if ((ssize_t)buflen < 256) + return 34; + + + { + if (!nop(&i0)) { + result_buf->h_aliases = alias; + result_buf->h_addrtype = 2; + result_buf->h_length = 4; + result_buf->h_addr_list = addr_list; + *result = result_buf; + *h_errnop = 0; + return 0; + } + } + + + seta (&a); + + if (a.atype == 1) { + + int need_bytes = sizeof(addr_list[0]) * (a.add_count + 1 + 1); + + int ips_len = a.add_count * a.rdlength; + + buflen -= (need_bytes + ips_len); + if ((ssize_t)buflen < 0) { + i = 34; + goto free_and_ret; + } + + result_buf->h_addrtype = 2; + *result = result_buf; + *h_errnop = 0; + i = 0; + goto free_and_ret; + } + + /* For cse, the 1 was is loaded into a call-saved register; + the load was hoisted into a delay slot before the conditional load, + clobbering result_buf, which (conditionally) lived in the same + call-saved register, because mark_referenced_resources considered the + destination of the COND_EXEC only clobbered, but not used. */ + *h_errnop = 1; + *nop(&i0) = 1; + i = 2; + + free_and_ret: + nop (&i0); + return i; +} + +int +main () +{ + struct hostent buf, *res; + int i; + char c; + ghostbyname_r (&buf, &c, 1024, &res, &i); + ghostbyname_r (&buf, 0, 1024, &res, &i); + return 0; +} diff --git a/gcc/testsuite/gcc.target/arc/interrupt-1.c b/gcc/testsuite/gcc.target/arc/interrupt-1.c new file mode 100644 index 00000000000..70514572ea5 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/interrupt-1.c @@ -0,0 +1,5 @@ +void __attribute__ ((interrupt("ilink1"))) +handler1 (void) +{ +} +/* { dg-final { scan-assembler-times "j.*\[ilink1\]" 1 } } */ diff --git a/gcc/testsuite/gcc.target/arc/interrupt-2.c b/gcc/testsuite/gcc.target/arc/interrupt-2.c new file mode 100644 index 00000000000..ee8593b3039 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/interrupt-2.c @@ -0,0 +1,5 @@ +void __attribute__ ((interrupt("ilink2"))) +handler1 (void) +{ +} +/* { dg-final { scan-assembler-times "j.*\[ilink2\]" 1 } } */ diff --git a/gcc/testsuite/gcc.target/arc/interrupt-3.c b/gcc/testsuite/gcc.target/arc/interrupt-3.c new file mode 100644 index 00000000000..fa598d67e6b --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/interrupt-3.c @@ -0,0 +1,14 @@ +void __attribute__ ((interrupt)) +handler0 (void) +{ /* { dg-error "wrong number of arguments specified" } */ +} + +void __attribute__ ((interrupt("you load too"))) +handler1 (void) +{ /* { dg-warning "is not \"ilink1\" or \"ilink2\"" } */ +} + +void __attribute__ ((interrupt(42))) +hander2 (void) +{ /* { dg-warning "is not a string constant" } */ +} diff --git a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c new file mode 100644 index 00000000000..398ecfe948e --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mARC700 --save-temps" } */ + +#include <stdlib.h> + +/* Hide value propagation from the optimizers. */ +static int +id (int i) +{ + asm ("": "+Xr" (i)); + return i; +} + +static int +mulhigh (unsigned a, unsigned b) +{ + return (unsigned long long) a * b >> 32; +} + +int +main (void) +{ + if (mulhigh (id (0x12345678), id (0x90abcdef)) != 0xa49a83e) + abort (); + return 0; +} + +/* { dg-final { scan-assembler "mpyhu\[ \t\]" } } */ diff --git a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c new file mode 100644 index 00000000000..ccc74e7b1ad --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mARC700 --save-temps -mno-mpy" } */ + +#include <stdlib.h> + +/* Hide value propagation from the optimizers. */ +static int +id (int i) +{ + asm ("": "+Xr" (i)); + return i; +} + +static int +mulhigh (unsigned a, unsigned b) +{ + return (unsigned long long) a * b >> 32; +} + +int +main (void) +{ + if (mulhigh (id (0x12345678), id (0x90abcdef)) != 0xa49a83e) + abort (); + return 0; +} + +/* { dg-final { scan-assembler-not "mpyhu\[ \t\]" } } */ +/* { dg-final { scan-assembler-not "@__muldi3" } } */ +/* { dg-final { scan-assembler "@__umulsi3_highpart" } } */ diff --git a/gcc/testsuite/gcc.target/arc/nv-cache.c b/gcc/testsuite/gcc.target/arc/nv-cache.c new file mode 100644 index 00000000000..9687195981c --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/nv-cache.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-volatile-cache" } */ + +volatile int i; +void f (void) +{ + i = 0; +} +/* { dg-final { scan-assembler "st\.di" } } */ diff --git a/gcc/testsuite/gcc.target/arc/sdata-1.c b/gcc/testsuite/gcc.target/arc/sdata-1.c new file mode 100644 index 00000000000..3d8366c1564 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/sdata-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msdata" } */ + +int i; + +int f (void) +{ + return i; +} +/* { dg-final { scan-assembler "@sda" } } */ diff --git a/gcc/testsuite/gcc.target/arc/sdata-2.c b/gcc/testsuite/gcc.target/arc/sdata-2.c new file mode 100644 index 00000000000..ebaa25e7267 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/sdata-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-sdata" } */ + +int i; + +int f (void) +{ + return i; +} +/* { dg-final { scan-assembler-not "@sda" } } */ diff --git a/gcc/testsuite/gcc.target/arc/v-cache.c b/gcc/testsuite/gcc.target/arc/v-cache.c new file mode 100644 index 00000000000..7722c433581 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/v-cache.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mvolatile-cache" } */ + +volatile int i; +void f (void) +{ + i = 0; +} +/* { dg-final { scan-assembler-not "st\.di" } } */ diff --git a/gcc/testsuite/gcc.target/arm/thumb-ifcvt-2.c b/gcc/testsuite/gcc.target/arm/thumb-ifcvt-2.c new file mode 100644 index 00000000000..3da9ef080f4 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/thumb-ifcvt-2.c @@ -0,0 +1,18 @@ +/* Check that Thumb 16-bit shifts by immediate can be if-converted. */ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_thumb2_ok } */ +/* { dg-options "-O2 -mthumb" } */ + +int +foo (int a, int b) +{ + if (a != b) + a = a << 1; + else + a = a >> 1; + + return a + b; +} + +/* { dg-final { scan-assembler "lslne" } } */ +/* { dg-final { scan-assembler "asreq" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr57848.c b/gcc/testsuite/gcc.target/i386/pr57848.c new file mode 100644 index 00000000000..d26b84c1b48 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr57848.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -m32" } */ + +extern unsigned int __builtin_ia32_crc32si (unsigned int, unsigned int); +#pragma GCC target("sse4.2") + diff --git a/gcc/testsuite/gcc.target/i386/pr58137.c b/gcc/testsuite/gcc.target/i386/pr58137.c new file mode 100644 index 00000000000..0a7daf83cd5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr58137.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mavx2" } */ + +typedef unsigned int U32; + +struct sv { + void* sv_any; + U32 sv_refcnt; + U32 sv_flags; +}; +typedef struct sv SV; + +struct xrv { + SV * xrv_rv; +}; +typedef struct xrv XRV; + +extern XRV * PL_xrv_root; + +void +more_xrv (void) +{ + register XRV* xrv; + register XRV* xrvend; + xrv = PL_xrv_root; + xrvend = &xrv[200 / sizeof (XRV) - 1]; + while (xrv < xrvend) + { + xrv->xrv_rv = (SV*)(xrv + 1); + xrv++; + } + xrv->xrv_rv = 0; +} 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/gcc.target/powerpc/medium_offset.c b/gcc/testsuite/gcc.target/powerpc/medium_offset.c new file mode 100644 index 00000000000..f29eba08c38 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/medium_offset.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O" } */ +/* { dg-final { scan-assembler-not "\\+4611686018427387904" } } */ + +static int x; + +unsigned long +foo (void) +{ + return ((unsigned long) &x) - 0xc000000000000000; +} diff --git a/gcc/testsuite/gcc.target/powerpc/pr58330.c b/gcc/testsuite/gcc.target/powerpc/pr58330.c new file mode 100644 index 00000000000..76983dd55ab --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr58330.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O -mno-popcntb" } */ +/* { dg-final { scan-assembler-not "stwbrx" } } */ + +void +write_reverse (unsigned long *addr, unsigned long val) +{ + unsigned long reverse = __builtin_bswap64 (val); + __atomic_store_n (addr, reverse, __ATOMIC_RELAXED); +} diff --git a/gcc/testsuite/gcc.target/s390/nearestint-1.c b/gcc/testsuite/gcc.target/s390/nearestint-1.c new file mode 100644 index 00000000000..1d9a753b3e4 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/nearestint-1.c @@ -0,0 +1,48 @@ +/* Since z196 the nearest integer functions can be expanded to single + instructions. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -march=z196 -mzarch" } */ + +extern float ceilf (float x); +extern double ceil (double x); +extern long double ceill (long double x); +extern float floorf (float x); +extern double floor (double x); +extern long double floorl (long double x); +extern float truncf (float x); +extern double trunc (double x); +extern long double truncl (long double x); +extern float nearbyintf (float x); +extern double nearbyint (double x); +extern long double nearbyintl (long double x); +extern float rintf (float x); +extern double rint (double x); +extern long double rintl (long double x); + +float my_ceilf (float x) { return ceilf (x); } +double my_ceil (double x) { return ceil (x); } +long double my_ceill (long double x) { return ceill (x); } + +float my_floorf (float x) { return floorf (x); } +double my_floor (double x) { return floor (x); } +long double my_floorl (long double x) { return floorl (x); } + +float my_truncf (float x) { return truncf (x); } +double my_trunc (double x) { return trunc (x); } +long double my_truncl (long double x) { return truncl (x); } + +float my_nearbyintf (float x) { return nearbyintf (x); } +double my_nearbyint (double x) { return nearbyint (x); } +long double my_nearbyintl (long double x) { return nearbyintl (x); } + +float my_rintf (float x) { return rintf (x); } +double my_rint (double x) { return rint (x); } +long double my_rintl (long double x) { return rintl (x); } + +/* { dg-final { scan-assembler-times "fiebr\t" 1 } } */ +/* { dg-final { scan-assembler-times "fidbr\t" 1 } } */ +/* { dg-final { scan-assembler-times "fixbr\t" 1 } } */ +/* { dg-final { scan-assembler-times "fiebra\t" 4 } } */ +/* { dg-final { scan-assembler-times "fidbra\t" 4 } } */ +/* { dg-final { scan-assembler-times "fixbra\t" 4 } } */ diff --git a/gcc/testsuite/gcc.target/sh/torture/pr58314.c b/gcc/testsuite/gcc.target/sh/torture/pr58314.c new file mode 100644 index 00000000000..61447d84ff9 --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/torture/pr58314.c @@ -0,0 +1,102 @@ +/* { dg-do compile { target "sh*-*-*" } } */ +/* { dg-options "-Os" } */ + +typedef unsigned short __u16; +typedef unsigned int __u32; + +typedef signed short s16; + + +static inline __attribute__((always_inline)) __attribute__((__const__)) __u16 __arch_swab16(__u16 x) +{ + __asm__( + "swap.b %1, %0" + : "=r" (x) + : "r" (x)); + return x; +} + +void u16_add_cpu(__u16 *var) +{ + *var = __arch_swab16(*var); +} + +typedef struct xfs_mount { + int m_attr_magicpct; +} xfs_mount_t; + +typedef struct xfs_da_args { + struct xfs_mount *t_mountp; + int index; +} xfs_da_args_t; + +typedef struct xfs_dabuf { + void *data; +} xfs_dabuf_t; + +typedef struct xfs_attr_leaf_map { + __u16 base; + __u16 size; +} xfs_attr_leaf_map_t; +typedef struct xfs_attr_leaf_hdr { + __u16 count; + xfs_attr_leaf_map_t freemap[3]; +} xfs_attr_leaf_hdr_t; + +typedef struct xfs_attr_leaf_entry { + __u16 nameidx; +} xfs_attr_leaf_entry_t; + +typedef struct xfs_attr_leafblock { + xfs_attr_leaf_hdr_t hdr; + xfs_attr_leaf_entry_t entries[1]; +} xfs_attr_leafblock_t; + +int +xfs_attr_leaf_remove(xfs_attr_leafblock_t *leaf, xfs_da_args_t *args) +{ + xfs_attr_leaf_hdr_t *hdr; + xfs_attr_leaf_map_t *map; + xfs_attr_leaf_entry_t *entry; + int before, after, smallest, entsize; + int tablesize, tmp, i; + xfs_mount_t *mp; + hdr = &leaf->hdr; + mp = args->t_mountp; + + entry = &leaf->entries[args->index]; + + tablesize = __arch_swab16(hdr->count); + + map = &hdr->freemap[0]; + tmp = map->size; + before = after = -1; + smallest = 3 - 1; + entsize = xfs_attr_leaf_entsize(leaf, args->index); + + for (i = 0; i < 2; map++, i++) { + + if (map->base == tablesize) + u16_add_cpu(&map->base); + + if (__arch_swab16(map->base) + __arch_swab16(map->size) == __arch_swab16(entry->nameidx)) + before = i; + else if (map->base == entsize) + after = i; + else if (__arch_swab16(map->size) < tmp) + smallest = i; + } + + if (before >= 0) + { + map = &hdr->freemap[after]; + map->base = entry->nameidx; + + } + + map = &hdr->freemap[smallest]; + + map->base = __arch_swab16(entry->nameidx); + + return(tmp < mp->m_attr_magicpct); +} diff --git a/gcc/testsuite/gcc.target/vax/pr56875.c b/gcc/testsuite/gcc.target/vax/pr56875.c new file mode 100644 index 00000000000..f409afe88e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/pr56875.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ +/* { dg-final { scan-assembler "ashq .*,\\\$0xffffffffffffffff," } } */ +/* { dg-final { scan-assembler-not "ashq .*,\\\$-1," } } */ + +void +a (void) +{ + unsigned long i = 1; + unsigned long long v; + + v = ~ (unsigned long long) 0 << i; +} diff --git a/gcc/testsuite/gcc.target/vax/vax.exp b/gcc/testsuite/gcc.target/vax/vax.exp new file mode 100644 index 00000000000..2aec4eec192 --- /dev/null +++ b/gcc/testsuite/gcc.target/vax/vax.exp @@ -0,0 +1,41 @@ +# Copyright (C) 2013 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't a VAX target. +if ![istarget vax-*-*] then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish 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_10.f90 b/gcc/testsuite/gfortran.dg/defined_assignment_10.f90 new file mode 100644 index 00000000000..4385925dcd1 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/defined_assignment_10.f90 @@ -0,0 +1,35 @@ +! { dg-do run } +! +! PR fortran/57697 +! +! Further test of typebound defined assignment +! +module m0 + implicit none + type component + integer :: i = 42 + contains + procedure :: assign0 + generic :: assignment(=) => assign0 + end type + type parent + type(component) :: foo + end type +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(parent), allocatable :: left + type(parent) :: right +! print *, right%foo + left = right +! print *, left%foo + if (left%foo%i /= 20) call abort() +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/pr58484.f b/gcc/testsuite/gfortran.dg/pr58484.f new file mode 100644 index 00000000000..2fd791347e9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr58484.f @@ -0,0 +1,15 @@ +! { dg-do compile } +! { dg-options "-O2" } + SUBROUTINE UMPSE(AIBJ,NOC,NDIM,NOCA,NVIRA,NOCCA,E2) + DIMENSION AIBJ(NOC,NDIM,*) + DO 20 MA=1,NVIRA + DO 20 MI=1,NOCA + DO 10 MB=1,MA + MBI = MI+NOCA*(MB-1) + DO 10 MJ=1,NOCCA + DUM = AIBJ(MJ,MAI,MB)-AIBJ(MJ,MBI,MA) + E2A = E2A-DUM + 10 CONTINUE + 20 CONTINUE + E2 = E2+E2A + END 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/gfortran.dg/reassoc_12.f90 b/gcc/testsuite/gfortran.dg/reassoc_12.f90 new file mode 100644 index 00000000000..7f4d70e31ca --- /dev/null +++ b/gcc/testsuite/gfortran.dg/reassoc_12.f90 @@ -0,0 +1,74 @@ +! { dg-do compile } +! { dg-options "-O2 -ffast-math" } +! PR middle-end/57370 + + SUBROUTINE xb88_lr_adiabatic_lda_calc(e_ndrho_ndrho_ndrho, & + grad_deriv,npoints, sx) + IMPLICIT REAL*8 (t) + INTEGER, PARAMETER :: dp=8 + REAL(kind=dp), DIMENSION(1:npoints) :: e_ndrho_ndrho_ndrho, & + e_ndrho_ndrho_rho + DO ii=1,npoints + IF( grad_deriv >= 2 .OR. grad_deriv == -2 ) THEN + t1425 = t233 * t557 + t1429 = beta * t225 + t1622 = t327 * t1621 + t1626 = t327 * t1625 + t1632 = t327 * t1631 + t1685 = t105 * t1684 + t2057 = t1636 + t8 * (t2635 + t3288) + END IF + IF( grad_deriv >= 3 .OR. grad_deriv == -3 ) THEN + t5469 = t5440 - t5443 - t5446 - t5449 - & + t5451 - t5454 - t5456 + t5459 - & + t5462 + t5466 - t5468 + t5478 = 0.240e2_dp * t1616 * t973 * t645 * t1425 + t5489 = 0.1600000000e2_dp * t1429 * t1658 + t5531 = 0.160e2_dp * t112 * t1626 + t5533 = 0.160e2_dp * t112 * t1632 + t5537 = 0.160e2_dp * t112 * t1622 + t5541 = t5472 - t5478 - t5523 + t5525 + & + t5531 + t5533 + t5535 + t5537 + & + t5540 + t5565 = t112 * t1685 + t5575 = t5545 - t5548 + t5551 + t5553 - & + t5558 + t5560 - t5562 + t5564 - & + 0.80e1_dp * t5565 + t5568 + t5572 + & + t5574 + t5611 = t5579 - t5585 + t5590 - t5595 + & + t5597 - t5602 + t5604 + t5607 + & + t5610 + t5613 = t5469 + t5541 + t5575 + t5611 + t6223 = t6189 - & + 0.3333333336e0_dp * t83 * t84 * t5613 + & + t6222 + t6227 = - t8 * (t5305 + t6223) + e_ndrho_ndrho_rho(ii) = e_ndrho_ndrho_rho(ii) + & + t6227 * sx + t6352 = t5440 - t5443 - t5446 - t5449 - & + t5451 - t5454 + & + 0.40e1_dp * t102 * t327 * t2057 * t557 - & + t5456 + t5459 - t5462 + t5466 - & + t5468 + t6363 = t5480 - t5489 + & + 0.9600000000e2_dp * t1054 * t640 * t3679 + t6367 = t5472 - t5474 - t5478 - t5523 + & + t5525 + t5531 + t5533 + t5535 + & + t5537 - 0.20e1_dp * t102 * t105 * t6363 + & + t5540 + t6370 = t5545 - t5548 + t5551 + t5553 - & + t5558 + t5560 - t5562 + t5564 - & + 0.40e1_dp * t5565 + & + t5568 + t5572 + t5574 + t6373 = t5579 - t5585 + t5590 - t5595 + & + t5597 - t5602 + t5604 + t5607 + & + t5610 + t6375 = t6352 + t6367 + t6370 + t6373 + t6380 = - 0.3333333336e0_dp * t83 * t84 * t6375 + t5701 + t6669 = -t4704 - t8 * (t6344 + t6380 + t6665) + e_ndrho_ndrho_ndrho(ii) = e_ndrho_ndrho_ndrho(ii) + & + t6669 * sx + END IF + END DO + END SUBROUTINE xb88_lr_adiabatic_lda_calc + 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/gnat.dg/stack_usage2.adb b/gcc/testsuite/gnat.dg/stack_usage2.adb new file mode 100644 index 00000000000..d458a929037 --- /dev/null +++ b/gcc/testsuite/gnat.dg/stack_usage2.adb @@ -0,0 +1,26 @@ +-- { dg-do compile } +-- { dg-options "-O2 -fstack-usage" } + +with System; + +procedure Stack_Usage2 is + + Sink : System.Address; + pragma Import (Ada, Sink); + + procedure Transmit_Data (Branch : Integer) is + pragma No_Inline (Transmit_Data); + X : Integer; + begin + case Branch is + when 1 => Sink := X'Address; + when others => null; + end case; + end; + +begin + Transmit_Data (Branch => 1); +end; + +-- { dg-final { scan-stack-usage-not ":Constprop" } } +-- { dg-final { cleanup-stack-usage } } diff --git a/gcc/testsuite/gnat.dg/warn10.adb b/gcc/testsuite/gnat.dg/warn10.adb new file mode 100644 index 00000000000..29b140d7598 --- /dev/null +++ b/gcc/testsuite/gnat.dg/warn10.adb @@ -0,0 +1,12 @@ +-- { dg-do compile } +-- { dg-options "-O3 -gnatn -Winline" } + +package body Warn10 is + + procedure Do_Something(Driver : My_Driver) is + X : Float; + begin + X := Get_Input_Value( Driver, 1, 1); + end; + +end Warn10; diff --git a/gcc/testsuite/gnat.dg/warn10.ads b/gcc/testsuite/gnat.dg/warn10.ads new file mode 100644 index 00000000000..01aa1e4b58a --- /dev/null +++ b/gcc/testsuite/gnat.dg/warn10.ads @@ -0,0 +1,11 @@ +with Warn10_Pkg; use Warn10_Pkg; + +package Warn10 is + + type My_Driver is new Root with record + Extra : Natural; + end record; + + procedure Do_Something(Driver : My_Driver); + +end Warn10; diff --git a/gcc/testsuite/gnat.dg/warn10_pkg.ads b/gcc/testsuite/gnat.dg/warn10_pkg.ads new file mode 100644 index 00000000000..ac5b676777d --- /dev/null +++ b/gcc/testsuite/gnat.dg/warn10_pkg.ads @@ -0,0 +1,12 @@ +package Warn10_Pkg is + + Size : constant Natural := 100; + type My_Array is array(1..Size, 1..Size) of Float; + + type Root is tagged record + Input_Values : My_Array; + end record; + + function Get_Input_Value( Driver : Root; I, J : Natural) return Float; + +end Warn10_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/timevar.def b/gcc/timevar.def index 5fe90953235..5a880a8a364 100644 --- a/gcc/timevar.def +++ b/gcc/timevar.def @@ -64,6 +64,7 @@ DEFTIMEVAR (TV_PCH_CPP_RESTORE , "PCH preprocessor state restore") DEFTIMEVAR (TV_CGRAPH , "callgraph construction") DEFTIMEVAR (TV_CGRAPHOPT , "callgraph optimization") +DEFTIMEVAR (TV_IPA_UNREACHABLE , "ipa dead code removal") DEFTIMEVAR (TV_IPA_INHERITANCE , "ipa inheritance graph") DEFTIMEVAR (TV_IPA_VIRTUAL_CALL , "ipa virtual call target") DEFTIMEVAR (TV_IPA_DEVIRT , "ipa devirtualization") diff --git a/gcc/toplev.c b/gcc/toplev.c index 4d12bc9246f..3473211efb1 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1017,22 +1017,35 @@ output_stack_usage (void) { expanded_location loc = expand_location (DECL_SOURCE_LOCATION (current_function_decl)); - const char *raw_id, *id; - - /* Strip the scope prefix if any. */ - raw_id = lang_hooks.decl_printable_name (current_function_decl, 2); - id = strrchr (raw_id, '.'); - if (id) - id++; + /* We don't want to print the full qualified name because it can be long, + so we strip the scope prefix, but we may need to deal with the suffix + created by the compiler. */ + const char *suffix + = strchr (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)), '.'); + const char *name + = lang_hooks.decl_printable_name (current_function_decl, 2); + if (suffix) + { + const char *dot = strchr (name, '.'); + while (dot && strcasecmp (dot, suffix) != 0) + { + name = dot + 1; + dot = strchr (name, '.'); + } + } else - id = raw_id; + { + const char *dot = strrchr (name, '.'); + if (dot) + name = dot + 1; + } fprintf (stack_usage_file, "%s:%d:%d:%s\t"HOST_WIDE_INT_PRINT_DEC"\t%s\n", lbasename (loc.file), loc.line, loc.column, - id, + name, stack_usage, stack_usage_kind_str[stack_usage_kind]); } diff --git a/gcc/tracer.c b/gcc/tracer.c index 0139669aa16..aa1736c685e 100644 --- a/gcc/tracer.c +++ b/gcc/tracer.c @@ -46,7 +46,7 @@ #include "params.h" #include "coverage.h" #include "tree-pass.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-inline.h" #include "cfgloop.h" diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index 9d5155d6c7c..c1b917f2f88 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -23,7 +23,7 @@ #include "hash-table.h" #include "tree.h" #include "gimple.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "tree-inline.h" #include "diagnostic-core.h" diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c index 9026babe631..fe19182a509 100644 --- a/gcc/tree-call-cdce.c +++ b/gcc/tree-call-cdce.c @@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "tree.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "gimple.h" #include "tree-pass.h" #include "flags.h" diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 6f6036954ba..22f91c0a613 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "ggc.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-dump.h" #include "tree-pass.h" #include "diagnostic-core.h" @@ -3574,11 +3574,10 @@ verify_gimple_assign_binary (gimple stmt) case PLUS_EXPR: case MINUS_EXPR: { - /* We use regular PLUS_EXPR and MINUS_EXPR for vectors. - ??? This just makes the checker happy and may not be what is - intended. */ - if (TREE_CODE (lhs_type) == VECTOR_TYPE - && POINTER_TYPE_P (TREE_TYPE (lhs_type))) + tree lhs_etype = lhs_type; + tree rhs1_etype = rhs1_type; + tree rhs2_etype = rhs2_type; + if (TREE_CODE (lhs_type) == VECTOR_TYPE) { if (TREE_CODE (rhs1_type) != VECTOR_TYPE || TREE_CODE (rhs2_type) != VECTOR_TYPE) @@ -3586,22 +3585,13 @@ verify_gimple_assign_binary (gimple stmt) error ("invalid non-vector operands to vector valued plus"); return true; } - lhs_type = TREE_TYPE (lhs_type); - rhs1_type = TREE_TYPE (rhs1_type); - rhs2_type = TREE_TYPE (rhs2_type); - /* PLUS_EXPR is commutative, so we might end up canonicalizing - the pointer to 2nd place. */ - if (POINTER_TYPE_P (rhs2_type)) - { - tree tem = rhs1_type; - rhs1_type = rhs2_type; - rhs2_type = tem; - } - goto do_pointer_plus_expr_check; + lhs_etype = TREE_TYPE (lhs_type); + rhs1_etype = TREE_TYPE (rhs1_type); + rhs2_etype = TREE_TYPE (rhs2_type); } - if (POINTER_TYPE_P (lhs_type) - || POINTER_TYPE_P (rhs1_type) - || POINTER_TYPE_P (rhs2_type)) + if (POINTER_TYPE_P (lhs_etype) + || POINTER_TYPE_P (rhs1_etype) + || POINTER_TYPE_P (rhs2_etype)) { error ("invalid (pointer) operands to plus/minus"); return true; @@ -3613,7 +3603,6 @@ verify_gimple_assign_binary (gimple stmt) case POINTER_PLUS_EXPR: { -do_pointer_plus_expr_check: if (!POINTER_TYPE_P (rhs1_type) || !useless_type_conversion_p (lhs_type, rhs1_type) || !ptrofftype_p (rhs2_type)) @@ -5577,6 +5566,7 @@ gimple_duplicate_bb (basic_block bb) copy = create_phi_node (NULL_TREE, new_bb); create_new_def_for (gimple_phi_result (phi), copy, gimple_phi_result_ptr (copy)); + gimple_set_uid (copy, gimple_uid (phi)); } gsi_tgt = gsi_start_bb (new_bb); @@ -6778,10 +6768,10 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, if (bb->loop_father->header == bb && loop_outer (bb->loop_father) == loop) { - struct loop *loop = bb->loop_father; + struct loop *this_loop = bb->loop_father; flow_loop_tree_node_remove (bb->loop_father); - flow_loop_tree_node_add (get_loop (dest_cfun, 0), loop); - fixup_loop_arrays_after_move (saved_cfun, cfun, loop); + flow_loop_tree_node_add (get_loop (dest_cfun, 0), this_loop); + fixup_loop_arrays_after_move (saved_cfun, cfun, this_loop); } /* Remove loop exits from the outlined region. */ @@ -6836,6 +6826,23 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, outer; outer = loop_outer (outer)) outer->num_nodes -= bbs.length (); + if (saved_cfun->has_simduid_loops || saved_cfun->has_force_vect_loops) + { + struct loop *aloop; + for (i = 0; vec_safe_iterate (loops->larray, i, &aloop); i++) + if (aloop != NULL) + { + if (aloop->simduid) + { + replace_by_duplicate_decl (&aloop->simduid, d.vars_map, + d.to_context); + dest_cfun->has_simduid_loops = true; + } + if (aloop->force_vect) + dest_cfun->has_force_vect_loops = true; + } + } + /* Rewire BLOCK_SUBBLOCKS of orig_block. */ if (orig_block) { @@ -7943,6 +7950,7 @@ public: /* opt_pass methods: */ unsigned int execute () { return split_critical_edges (); } + opt_pass * clone () { return new pass_split_crit_edges (ctxt_); } }; // class pass_split_crit_edges } // anon namespace diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 8917f855705..e0acbed8ef2 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "ggc.h" #include "langhooks.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "except.h" #include "cfgloop.h" diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c index 7c3960ecbbe..8ede0c67df9 100644 --- a/gcc/tree-chrec.c +++ b/gcc/tree-chrec.c @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tree-pretty-print.h" #include "cfgloop.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-chrec.h" #include "dumpfile.h" #include "params.h" @@ -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-chrec.h b/gcc/tree-chrec.h index ad39a6b22d3..c69183b966e 100644 --- a/gcc/tree-chrec.h +++ b/gcc/tree-chrec.h @@ -137,15 +137,18 @@ build_polynomial_chrec (unsigned loop_num, || !val) return chrec_dont_know; - /* Pointer types should occur only on the left hand side, i.e. in - the base of the chrec, and not in the step. */ - gcc_assert (!POINTER_TYPE_P (TREE_TYPE (right))); - - /* Types of left and right sides of a chrec should be compatible. */ + /* Types of left and right sides of a chrec should be compatible, but + pointer CHRECs are special in that the evolution is of ptroff type. */ if (POINTER_TYPE_P (TREE_TYPE (left))) - gcc_assert (ptrofftype_p (TREE_TYPE (right))); + gcc_checking_assert (ptrofftype_p (TREE_TYPE (right))); else - gcc_assert (TREE_TYPE (left) == TREE_TYPE (right)); + { + /* Pointer types should occur only on the left hand side, i.e. in + the base of the chrec, and not in the step. */ + gcc_checking_assert (!POINTER_TYPE_P (TREE_TYPE (right)) + && types_compatible_p (TREE_TYPE (left), + TREE_TYPE (right))); + } if (chrec_zerop (right)) return left; diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c index 225728fdaeb..91798ecdee6 100644 --- a/gcc/tree-complex.c +++ b/gcc/tree-complex.c @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "tree.h" #include "flags.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "gimple.h" #include "tree-iterator.h" #include "tree-pass.h" diff --git a/gcc/tree-core.h b/gcc/tree-core.h index f825b0062be..89b7e18b787 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -781,6 +781,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 @@ -801,6 +804,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 @@ -936,6 +942,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 { @@ -1198,8 +1207,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. @@ -1329,6 +1337,11 @@ struct GTY(()) tree_decl_non_common { tree vindex; }; +/* FUNCTION_DECL inherits from DECL_NON_COMMON because of the use of the + arguments/result/saved_tree fields by front ends. It was either inherit + FUNCTION_DECL from non_common, or inherit non_common from FUNCTION_DECL, + which seemed a bit strange. */ + struct GTY(()) tree_function_decl { struct tree_decl_non_common common; @@ -1399,6 +1412,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; @@ -1414,6 +1430,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; @@ -1559,6 +1577,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-data-ref.c b/gcc/tree-data-ref.c index dad8cbeea60..0e608f5786f 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -77,7 +77,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "tree-data-ref.h" #include "tree-scalar-evolution.h" @@ -4798,446 +4798,3 @@ free_data_refs (vec<data_reference_p> datarefs) free_data_ref (dr); datarefs.release (); } - - - -/* Dump vertex I in RDG to FILE. */ - -static void -dump_rdg_vertex (FILE *file, struct graph *rdg, int i) -{ - struct vertex *v = &(rdg->vertices[i]); - struct graph_edge *e; - - fprintf (file, "(vertex %d: (%s%s) (in:", i, - RDG_MEM_WRITE_STMT (rdg, i) ? "w" : "", - RDG_MEM_READS_STMT (rdg, i) ? "r" : ""); - - if (v->pred) - for (e = v->pred; e; e = e->pred_next) - fprintf (file, " %d", e->src); - - fprintf (file, ") (out:"); - - if (v->succ) - for (e = v->succ; e; e = e->succ_next) - fprintf (file, " %d", e->dest); - - fprintf (file, ")\n"); - print_gimple_stmt (file, RDGV_STMT (v), 0, TDF_VOPS|TDF_MEMSYMS); - fprintf (file, ")\n"); -} - -/* Call dump_rdg_vertex on stderr. */ - -DEBUG_FUNCTION void -debug_rdg_vertex (struct graph *rdg, int i) -{ - dump_rdg_vertex (stderr, rdg, i); -} - -/* Dump component C of RDG to FILE. If DUMPED is non-null, set the - dumped vertices to that bitmap. */ - -static void -dump_rdg_component (FILE *file, struct graph *rdg, int c, bitmap dumped) -{ - int i; - - fprintf (file, "(%d\n", c); - - for (i = 0; i < rdg->n_vertices; i++) - if (rdg->vertices[i].component == c) - { - if (dumped) - bitmap_set_bit (dumped, i); - - dump_rdg_vertex (file, rdg, i); - } - - fprintf (file, ")\n"); -} - -/* Call dump_rdg_vertex on stderr. */ - -DEBUG_FUNCTION void -debug_rdg_component (struct graph *rdg, int c) -{ - dump_rdg_component (stderr, rdg, c, NULL); -} - -/* Dump the reduced dependence graph RDG to FILE. */ - -void -dump_rdg (FILE *file, struct graph *rdg) -{ - int i; - bitmap dumped = BITMAP_ALLOC (NULL); - - fprintf (file, "(rdg\n"); - - for (i = 0; i < rdg->n_vertices; i++) - if (!bitmap_bit_p (dumped, i)) - dump_rdg_component (file, rdg, rdg->vertices[i].component, dumped); - - fprintf (file, ")\n"); - BITMAP_FREE (dumped); -} - -/* Call dump_rdg on stderr. */ - -DEBUG_FUNCTION void -debug_rdg (struct graph *rdg) -{ - dump_rdg (stderr, rdg); -} - -static void -dot_rdg_1 (FILE *file, struct graph *rdg) -{ - int i; - - fprintf (file, "digraph RDG {\n"); - - for (i = 0; i < rdg->n_vertices; i++) - { - struct vertex *v = &(rdg->vertices[i]); - struct graph_edge *e; - - /* Highlight reads from memory. */ - if (RDG_MEM_READS_STMT (rdg, i)) - fprintf (file, "%d [style=filled, fillcolor=green]\n", i); - - /* Highlight stores to memory. */ - if (RDG_MEM_WRITE_STMT (rdg, i)) - fprintf (file, "%d [style=filled, fillcolor=red]\n", i); - - if (v->succ) - for (e = v->succ; e; e = e->succ_next) - switch (RDGE_TYPE (e)) - { - case input_dd: - fprintf (file, "%d -> %d [label=input] \n", i, e->dest); - break; - - case output_dd: - fprintf (file, "%d -> %d [label=output] \n", i, e->dest); - break; - - case flow_dd: - /* These are the most common dependences: don't print these. */ - fprintf (file, "%d -> %d \n", i, e->dest); - break; - - case anti_dd: - fprintf (file, "%d -> %d [label=anti] \n", i, e->dest); - break; - - default: - gcc_unreachable (); - } - } - - fprintf (file, "}\n\n"); -} - -/* Display the Reduced Dependence Graph using dotty. */ -extern void dot_rdg (struct graph *); - -DEBUG_FUNCTION void -dot_rdg (struct graph *rdg) -{ - /* When debugging, enable the following code. This cannot be used - in production compilers because it calls "system". */ -#if 0 - FILE *file = fopen ("/tmp/rdg.dot", "w"); - gcc_assert (file != NULL); - - dot_rdg_1 (file, rdg); - fclose (file); - - system ("dotty /tmp/rdg.dot &"); -#else - dot_rdg_1 (stderr, rdg); -#endif -} - -/* Returns the index of STMT in RDG. */ - -int -rdg_vertex_for_stmt (struct graph *rdg ATTRIBUTE_UNUSED, gimple stmt) -{ - int index = gimple_uid (stmt); - gcc_checking_assert (index == -1 || RDG_STMT (rdg, index) == stmt); - return index; -} - -/* Creates an edge in RDG for each distance vector from DDR. The - order that we keep track of in the RDG is the order in which - statements have to be executed. */ - -static void -create_rdg_edge_for_ddr (struct graph *rdg, ddr_p ddr) -{ - struct graph_edge *e; - int va, vb; - data_reference_p dra = DDR_A (ddr); - data_reference_p drb = DDR_B (ddr); - unsigned level = ddr_dependence_level (ddr); - - /* For non scalar dependences, when the dependence is REVERSED, - statement B has to be executed before statement A. */ - if (level > 0 - && !DDR_REVERSED_P (ddr)) - { - data_reference_p tmp = dra; - dra = drb; - drb = tmp; - } - - va = rdg_vertex_for_stmt (rdg, DR_STMT (dra)); - vb = rdg_vertex_for_stmt (rdg, DR_STMT (drb)); - - if (va < 0 || vb < 0) - return; - - e = add_edge (rdg, va, vb); - e->data = XNEW (struct rdg_edge); - - RDGE_LEVEL (e) = level; - RDGE_RELATION (e) = ddr; - - /* Determines the type of the data dependence. */ - if (DR_IS_READ (dra) && DR_IS_READ (drb)) - RDGE_TYPE (e) = input_dd; - else if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb)) - RDGE_TYPE (e) = output_dd; - else if (DR_IS_WRITE (dra) && DR_IS_READ (drb)) - RDGE_TYPE (e) = flow_dd; - else if (DR_IS_READ (dra) && DR_IS_WRITE (drb)) - RDGE_TYPE (e) = anti_dd; -} - -/* Creates dependence edges in RDG for all the uses of DEF. IDEF is - the index of DEF in RDG. */ - -static void -create_rdg_edges_for_scalar (struct graph *rdg, tree def, int idef) -{ - use_operand_p imm_use_p; - imm_use_iterator iterator; - - FOR_EACH_IMM_USE_FAST (imm_use_p, iterator, def) - { - struct graph_edge *e; - int use = rdg_vertex_for_stmt (rdg, USE_STMT (imm_use_p)); - - if (use < 0) - continue; - - e = add_edge (rdg, idef, use); - e->data = XNEW (struct rdg_edge); - RDGE_TYPE (e) = flow_dd; - RDGE_RELATION (e) = NULL; - } -} - -/* Creates the edges of the reduced dependence graph RDG. */ - -static void -create_rdg_edges (struct graph *rdg, vec<ddr_p> ddrs) -{ - int i; - struct data_dependence_relation *ddr; - def_operand_p def_p; - ssa_op_iter iter; - - FOR_EACH_VEC_ELT (ddrs, i, ddr) - if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE) - create_rdg_edge_for_ddr (rdg, ddr); - - for (i = 0; i < rdg->n_vertices; i++) - FOR_EACH_PHI_OR_STMT_DEF (def_p, RDG_STMT (rdg, i), - iter, SSA_OP_DEF) - create_rdg_edges_for_scalar (rdg, DEF_FROM_PTR (def_p), i); -} - -/* Build the vertices of the reduced dependence graph RDG. */ - -static void -create_rdg_vertices (struct graph *rdg, vec<gimple> stmts, loop_p loop) -{ - int i, j; - gimple stmt; - - FOR_EACH_VEC_ELT (stmts, i, stmt) - { - vec<data_ref_loc, va_stack> references; - data_ref_loc *ref; - struct vertex *v = &(rdg->vertices[i]); - - /* Record statement to vertex mapping. */ - gimple_set_uid (stmt, i); - - v->data = XNEW (struct rdg_vertex); - RDGV_STMT (v) = stmt; - RDGV_DATAREFS (v).create (0); - RDGV_HAS_MEM_WRITE (v) = false; - RDGV_HAS_MEM_READS (v) = false; - if (gimple_code (stmt) == GIMPLE_PHI) - continue; - - vec_stack_alloc (data_ref_loc, references, 2); - get_references_in_stmt (stmt, &references); - FOR_EACH_VEC_ELT (references, j, ref) - { - data_reference_p dr; - if (!ref->is_read) - RDGV_HAS_MEM_WRITE (v) = true; - else - RDGV_HAS_MEM_READS (v) = true; - dr = create_data_ref (loop, loop_containing_stmt (stmt), - *ref->pos, stmt, ref->is_read); - if (dr) - RDGV_DATAREFS (v).safe_push (dr); - } - references.release (); - } -} - -/* Initialize STMTS with all the statements of LOOP. When - INCLUDE_PHIS is true, include also the PHI nodes. The order in - which we discover statements is important as - generate_loops_for_partition is using the same traversal for - identifying statements. */ - -static void -stmts_from_loop (struct loop *loop, vec<gimple> *stmts) -{ - unsigned int i; - basic_block *bbs = get_loop_body_in_dom_order (loop); - - for (i = 0; i < loop->num_nodes; i++) - { - basic_block bb = bbs[i]; - gimple_stmt_iterator bsi; - gimple stmt; - - for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi)) - stmts->safe_push (gsi_stmt (bsi)); - - for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) - { - stmt = gsi_stmt (bsi); - if (gimple_code (stmt) != GIMPLE_LABEL && !is_gimple_debug (stmt)) - stmts->safe_push (stmt); - } - } - - free (bbs); -} - -/* Returns true when all the dependences are computable. */ - -static bool -known_dependences_p (vec<ddr_p> dependence_relations) -{ - ddr_p ddr; - unsigned int i; - - FOR_EACH_VEC_ELT (dependence_relations, i, ddr) - if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know) - return false; - - return true; -} - -/* Build the Reduced Dependence Graph (RDG) with one vertex per - statement of the loop nest, and one edge per data dependence or - scalar dependence. */ - -struct graph * -build_empty_rdg (int n_stmts) -{ - struct graph *rdg = new_graph (n_stmts); - return rdg; -} - -/* Build the Reduced Dependence Graph (RDG) with one vertex per - statement of the loop nest, and one edge per data dependence or - scalar dependence. */ - -struct graph * -build_rdg (struct loop *loop, - vec<loop_p> *loop_nest, - vec<ddr_p> *dependence_relations, - vec<data_reference_p> *datarefs) -{ - struct graph *rdg = NULL; - - if (compute_data_dependences_for_loop (loop, false, loop_nest, datarefs, - dependence_relations) - && known_dependences_p (*dependence_relations)) - { - vec<gimple> stmts; - stmts.create (10); - stmts_from_loop (loop, &stmts); - rdg = build_empty_rdg (stmts.length ()); - create_rdg_vertices (rdg, stmts, loop); - create_rdg_edges (rdg, *dependence_relations); - stmts.release (); - } - - return rdg; -} - -/* Free the reduced dependence graph RDG. */ - -void -free_rdg (struct graph *rdg) -{ - int i; - - for (i = 0; i < rdg->n_vertices; i++) - { - struct vertex *v = &(rdg->vertices[i]); - struct graph_edge *e; - - for (e = v->succ; e; e = e->succ_next) - free (e->data); - - gimple_set_uid (RDGV_STMT (v), -1); - free_data_refs (RDGV_DATAREFS (v)); - free (v->data); - } - - free_graph (rdg); -} - -/* Determines whether the statement from vertex V of the RDG has a - definition used outside the loop that contains this statement. */ - -bool -rdg_defs_used_in_other_loops_p (struct graph *rdg, int v) -{ - gimple stmt = RDG_STMT (rdg, v); - struct loop *loop = loop_containing_stmt (stmt); - use_operand_p imm_use_p; - imm_use_iterator iterator; - ssa_op_iter it; - def_operand_p def_p; - - if (!loop) - return true; - - FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, it, SSA_OP_DEF) - { - FOR_EACH_IMM_USE_FAST (imm_use_p, iterator, DEF_FROM_PTR (def_p)) - { - if (loop_containing_stmt (USE_STMT (imm_use_p)) != loop) - return true; - } - } - - return false; -} diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h index 27737262b1f..0763382bf8c 100644 --- a/gcc/tree-data-ref.h +++ b/gcc/tree-data-ref.h @@ -482,6 +482,21 @@ ddrs_have_anti_deps (vec<ddr_p> dependence_relations) return false; } +/* Returns true when all the dependences are computable. */ + +inline bool +known_dependences_p (vec<ddr_p> dependence_relations) +{ + ddr_p ddr; + unsigned int i; + + FOR_EACH_VEC_ELT (dependence_relations, i, ddr) + if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know) + return false; + + return true; +} + /* Returns the dependence level for a vector DIST of size LENGTH. LEVEL = 0 means a lexicographic dependence, i.e. a dependence due to the sequence of statements, not carried by any loop. */ @@ -515,83 +530,6 @@ ddr_dependence_level (ddr_p ddr) return level; } - - -/* A Reduced Dependence Graph (RDG) vertex representing a statement. */ -typedef struct rdg_vertex -{ - /* The statement represented by this vertex. */ - gimple stmt; - - /* Vector of data-references in this statement. */ - vec<data_reference_p> datarefs; - - /* True when the statement contains a write to memory. */ - bool has_mem_write; - - /* True when the statement contains a read from memory. */ - bool has_mem_reads; -} *rdg_vertex_p; - -#define RDGV_STMT(V) ((struct rdg_vertex *) ((V)->data))->stmt -#define RDGV_DATAREFS(V) ((struct rdg_vertex *) ((V)->data))->datarefs -#define RDGV_HAS_MEM_WRITE(V) ((struct rdg_vertex *) ((V)->data))->has_mem_write -#define RDGV_HAS_MEM_READS(V) ((struct rdg_vertex *) ((V)->data))->has_mem_reads -#define RDG_STMT(RDG, I) RDGV_STMT (&(RDG->vertices[I])) -#define RDG_DATAREFS(RDG, I) RDGV_DATAREFS (&(RDG->vertices[I])) -#define RDG_MEM_WRITE_STMT(RDG, I) RDGV_HAS_MEM_WRITE (&(RDG->vertices[I])) -#define RDG_MEM_READS_STMT(RDG, I) RDGV_HAS_MEM_READS (&(RDG->vertices[I])) - -void debug_rdg_vertex (struct graph *, int); -void debug_rdg_component (struct graph *, int); -void dump_rdg (FILE *, struct graph *); -void debug_rdg (struct graph *); -int rdg_vertex_for_stmt (struct graph *, gimple); - -/* Data dependence type. */ - -enum rdg_dep_type -{ - /* Read After Write (RAW). */ - flow_dd = 'f', - - /* Write After Read (WAR). */ - anti_dd = 'a', - - /* Write After Write (WAW). */ - output_dd = 'o', - - /* Read After Read (RAR). */ - input_dd = 'i' -}; - -/* Dependence information attached to an edge of the RDG. */ - -typedef struct rdg_edge -{ - /* Type of the dependence. */ - enum rdg_dep_type type; - - /* Levels of the dependence: the depth of the loops that carry the - dependence. */ - unsigned level; - - /* Dependence relation between data dependences, NULL when one of - the vertices is a scalar. */ - ddr_p relation; -} *rdg_edge_p; - -#define RDGE_TYPE(E) ((struct rdg_edge *) ((E)->data))->type -#define RDGE_LEVEL(E) ((struct rdg_edge *) ((E)->data))->level -#define RDGE_RELATION(E) ((struct rdg_edge *) ((E)->data))->relation - -struct graph *build_rdg (struct loop *, - vec<loop_p> *, - vec<ddr_p> *, - vec<data_reference_p> *); -struct graph *build_empty_rdg (int); -void free_rdg (struct graph *); - /* Return the index of the variable VAR in the LOOP_NEST array. */ static inline int @@ -608,8 +546,6 @@ index_in_loop_nest (int var, vec<loop_p> loop_nest) return var_index; } -bool rdg_defs_used_in_other_loops_p (struct graph *, int); - /* Returns true when the data reference DR the form "A[i] = ..." with a stride equal to its unit type size. */ @@ -630,19 +566,8 @@ adjacent_dr_p (struct data_reference *dr) TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr)))); } -/* In tree-data-ref.c */ void split_constant_offset (tree , tree *, tree *); -/* Strongly connected components of the reduced data dependence graph. */ - -typedef struct rdg_component -{ - int num; - vec<int> vertices; -} *rdgc; - - - /* Compute the greatest common divisor of a VECTOR of SIZE numbers. */ static inline int diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index ec77264950a..9df1958d8a9 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -33,7 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "tree-pretty-print.h" #include "gimple.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-inline.h" #include "tree-pass.h" #include "convert.h" diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 6ffbd266711..51eab57c716 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "except.h" #include "pointer-set.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-inline.h" #include "tree-pass.h" #include "langhooks.h" diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c index ed8edc3569c..23d50389b98 100644 --- a/gcc/tree-emutls.c +++ b/gcc/tree-emutls.c @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "gimple.h" #include "tree-pass.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cgraph.h" #include "langhooks.h" #include "target.h" diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index 59505d05c50..85f4bc9910e 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -1158,70 +1158,6 @@ gimple_ssa_operands (const struct function *fun) return &fun->gimple_df->ssa_operands; } -/* Given an edge_var_map V, return the PHI arg definition. */ - -static inline tree -redirect_edge_var_map_def (edge_var_map *v) -{ - return v->def; -} - -/* Given an edge_var_map V, return the PHI result. */ - -static inline tree -redirect_edge_var_map_result (edge_var_map *v) -{ - return v->result; -} - -/* Given an edge_var_map V, return the PHI arg location. */ - -static inline source_location -redirect_edge_var_map_location (edge_var_map *v) -{ - return v->locus; -} - - -/* Return an SSA_NAME node for variable VAR defined in statement STMT - in function cfun. */ - -static inline tree -make_ssa_name (tree var, gimple stmt) -{ - return make_ssa_name_fn (cfun, var, stmt); -} - -/* Return an SSA_NAME node using the template SSA name NAME defined in - statement STMT in function cfun. */ - -static inline tree -copy_ssa_name (tree var, gimple stmt) -{ - return copy_ssa_name_fn (cfun, var, stmt); -} - -/* Creates a duplicate of a SSA name NAME tobe defined by statement STMT - in function cfun. */ - -static inline tree -duplicate_ssa_name (tree var, gimple stmt) -{ - return duplicate_ssa_name_fn (cfun, var, stmt); -} - -/* Return an anonymous SSA_NAME node for type TYPE defined in statement STMT - in function cfun. Arrange so that it uses NAME in dumps. */ - -static inline tree -make_temp_ssa_name (tree type, gimple stmt, const char *name) -{ - tree ssa_name; - gcc_checking_assert (TYPE_P (type)); - ssa_name = make_ssa_name_fn (cfun, type, stmt); - SET_SSA_NAME_VAR_OR_IDENTIFIER (ssa_name, get_identifier (name)); - return ssa_name; -} /* Returns the base object and a constant BITS_PER_UNIT offset in *POFFSET that denotes the starting address of the memory access EXP. diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 023654a772c..9d6ecb47d7e 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -93,12 +93,6 @@ struct GTY(()) gimple_df { htab_t GTY ((param_is (struct tm_restart_node))) tm_restart; }; -/* Accessors for internal use only. Generic code should use abstraction - provided by tree-flow-inline.h or specific modules. */ -#define FREE_SSANAMES(fun) (fun)->gimple_df->free_ssanames -#define SSANAMES(fun) (fun)->gimple_df->ssa_names -#define MODIFIED_NORETURN_CALLS(fun) (fun)->gimple_df->modified_noreturn_calls -#define DEFAULT_DEFS(fun) (fun)->gimple_df->default_defs typedef struct { @@ -114,41 +108,6 @@ typedef struct !end_htab_p (&(ITER)); \ RESULT = (TYPE) next_htab_element (&(ITER))) -/*--------------------------------------------------------------------------- - Attributes for SSA_NAMEs. - - NOTE: These structures are stored in struct tree_ssa_name - but are only used by the tree optimizers, so it makes better sense - to declare them here to avoid recompiling unrelated files when - making changes. ----------------------------------------------------------------------------*/ - -/* Aliasing information for SSA_NAMEs representing pointer variables. */ - -struct GTY(()) ptr_info_def -{ - /* The points-to solution. */ - struct pt_solution pt; - - /* Alignment and misalignment of the pointer in bytes. Together - align and misalign specify low known bits of the pointer. - ptr & (align - 1) == misalign. */ - - /* When known, this is the power-of-two byte alignment of the object this - pointer points into. This is usually DECL_ALIGN_UNIT for decls and - MALLOC_ABI_ALIGNMENT for allocated storage. When the alignment is not - known, it is zero. Do not access directly but use functions - get_ptr_info_alignment, set_ptr_info_alignment, - mark_ptr_info_alignment_unknown and similar. */ - unsigned int align; - - /* When alignment is known, the byte offset this pointer differs from the - above alignment. Access only through the same helper functions as align - above. */ - unsigned int misalign; -}; - - /* It is advantageous to avoid things like life analysis for variables which do not need PHI nodes. This enum describes whether or not a particular variable may need a PHI node. */ @@ -283,9 +242,6 @@ struct int_tree_map { tree to; }; -#define num_ssa_names (vec_safe_length (cfun->gimple_df->ssa_names)) -#define ssa_name(i) ((*cfun->gimple_df->ssa_names)[(i)]) - /* Macros for showing usage statistics. */ #define SCALE(x) ((unsigned long) ((x) < 1024*10 \ ? (x) \ @@ -466,48 +422,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.c */ - -/* Mapping for redirected edges. */ -struct _edge_var_map { - tree result; /* PHI result. */ - tree def; /* PHI arg definition. */ - source_location locus; /* PHI arg location. */ -}; -typedef struct _edge_var_map edge_var_map; - - -/* A vector of var maps. */ -typedef vec<edge_var_map, va_heap, vl_embed> edge_var_map_vector; - -extern void init_tree_ssa (struct function *); -extern void redirect_edge_var_map_add (edge, tree, tree, source_location); -extern void redirect_edge_var_map_clear (edge); -extern void redirect_edge_var_map_dup (edge, edge); -extern edge_var_map_vector *redirect_edge_var_map_vector (edge); -extern void redirect_edge_var_map_destroy (void); - -extern edge ssa_redirect_edge (edge, basic_block); -extern void flush_pending_stmts (edge); -extern void verify_ssa (bool); -extern void delete_tree_ssa (void); -extern bool ssa_undefined_value_p (tree); -extern void warn_uninit (enum opt_code, tree, tree, tree, const char *, void *); -extern unsigned int warn_uninitialized_vars (bool); -extern void execute_update_addresses_taken (void); - -/* Call-back function for walk_use_def_chains(). At each reaching - definition, a function with this prototype is called. */ -typedef bool (*walk_use_def_chains_fn) (tree, gimple, void *); - -extern void walk_use_def_chains (tree, walk_use_def_chains_fn, void *, bool); - -void insert_debug_temps_for_defs (gimple_stmt_iterator *); -void insert_debug_temp_for_var_def (gimple_stmt_iterator *, tree); -void reset_debug_uses (gimple); -void release_defs_bitset (bitmap toremove); - /* In tree-into-ssa.c */ void update_ssa (unsigned); void delete_update_ssa (void); @@ -519,26 +433,6 @@ void mark_virtual_operands_for_renaming (struct function *); tree get_current_def (tree); void set_current_def (tree, tree); -/* In tree-ssanames.c */ -extern void init_ssanames (struct function *, int); -extern void fini_ssanames (void); -extern tree make_ssa_name_fn (struct function *, tree, gimple); -extern tree copy_ssa_name_fn (struct function *, tree, gimple); -extern tree duplicate_ssa_name_fn (struct function *, tree, gimple); -extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *); -extern void release_ssa_name (tree); -extern void release_defs (gimple); -extern void replace_ssa_name_symbol (tree, tree); -extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *, - unsigned int *); -extern void mark_ptr_info_alignment_unknown (struct ptr_info_def *); -extern void set_ptr_info_alignment (struct ptr_info_def *, unsigned int, - unsigned int); -extern void adjust_ptr_info_misalignment (struct ptr_info_def *, - unsigned int); - -extern void ssanames_print_statistics (void); - /* In tree-ssa-ccp.c */ tree fold_const_aggregate_ref (tree); tree gimple_fold_stmt_to_constant (gimple, tree (*)(tree)); diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 3ef356a0ac7..4851023d27f 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -88,7 +88,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "basic-block.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "tree-chrec.h" #include "tree-data-ref.h" @@ -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 ee9c895e778..39225ca6ed5 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -36,9 +36,9 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "intl.h" #include "tree-mudflap.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "function.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pretty-print.h" #include "except.h" #include "debug.h" @@ -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 *'. @@ -839,20 +853,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; } @@ -1041,45 +1059,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; @@ -1088,20 +1105,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; } @@ -2239,14 +2260,14 @@ maybe_move_debug_stmts_to_successors (copy_body_data *id, basic_block new_bb) as siblings of DEST_PARENT. */ static void -copy_loops (bitmap blocks_to_copy, +copy_loops (copy_body_data *id, struct loop *dest_parent, struct loop *src_parent) { struct loop *src_loop = src_parent->inner; while (src_loop) { - if (!blocks_to_copy - || bitmap_bit_p (blocks_to_copy, src_loop->header->index)) + if (!id->blocks_to_copy + || bitmap_bit_p (id->blocks_to_copy, src_loop->header->index)) { struct loop *dest_loop = alloc_loop (); @@ -2270,8 +2291,19 @@ copy_loops (bitmap blocks_to_copy, place_new_loop (cfun, dest_loop); flow_loop_tree_node_add (dest_parent, dest_loop); + if (src_loop->simduid) + { + dest_loop->simduid = remap_decl (src_loop->simduid, id); + cfun->has_simduid_loops = true; + } + if (src_loop->force_vect) + { + dest_loop->force_vect = true; + cfun->has_force_vect_loops = true; + } + /* Recurse. */ - copy_loops (blocks_to_copy, dest_loop, src_loop); + copy_loops (id, dest_loop, src_loop); } src_loop = src_loop->next; } @@ -2300,7 +2332,7 @@ redirect_all_calls (copy_body_data * id, basic_block bb) static tree copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, basic_block entry_block_map, basic_block exit_block_map, - bitmap blocks_to_copy, basic_block new_entry) + basic_block new_entry) { tree callee_fndecl = id->src_fn; /* Original cfun for the callee, doesn't change. */ @@ -2364,7 +2396,7 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, /* Use aux pointers to map the original blocks to copy. */ FOR_EACH_BB_FN (bb, cfun_to_copy) - if (!blocks_to_copy || bitmap_bit_p (blocks_to_copy, bb->index)) + if (!id->blocks_to_copy || bitmap_bit_p (id->blocks_to_copy, bb->index)) { basic_block new_bb = copy_bb (id, bb, frequency_scale, count_scale); bb->aux = new_bb; @@ -2378,8 +2410,8 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, bool can_make_abormal_goto = id->gimple_call && stmt_can_make_abnormal_goto (id->gimple_call); FOR_ALL_BB_FN (bb, cfun_to_copy) - if (!blocks_to_copy - || (bb->index > 0 && bitmap_bit_p (blocks_to_copy, bb->index))) + if (!id->blocks_to_copy + || (bb->index > 0 && bitmap_bit_p (id->blocks_to_copy, bb->index))) need_debug_cleanup |= copy_edges_for_bb (bb, count_scale, exit_block_map, can_make_abormal_goto); @@ -2394,12 +2426,10 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, if (loops_for_fn (src_cfun) != NULL && current_loops != NULL) { - copy_loops (blocks_to_copy, entry_block_map->loop_father, + copy_loops (id, entry_block_map->loop_father, get_loop (src_cfun, 0)); /* Defer to cfgcleanup to update loop-father fields of basic-blocks. */ loops_state_set (LOOPS_NEED_FIXUP); - cfun->has_force_vect_loops |= src_cfun->has_force_vect_loops; - cfun->has_simduid_loops |= src_cfun->has_simduid_loops; } /* If the loop tree in the source function needed fixup, mark the @@ -2409,8 +2439,8 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, if (gimple_in_ssa_p (cfun)) FOR_ALL_BB_FN (bb, cfun_to_copy) - if (!blocks_to_copy - || (bb->index > 0 && bitmap_bit_p (blocks_to_copy, bb->index))) + if (!id->blocks_to_copy + || (bb->index > 0 && bitmap_bit_p (id->blocks_to_copy, bb->index))) copy_phis_for_bb (bb, id); FOR_ALL_BB_FN (bb, cfun_to_copy) @@ -2582,7 +2612,7 @@ copy_tree_body (copy_body_data *id) static tree copy_body (copy_body_data *id, gcov_type count, int frequency_scale, basic_block entry_block_map, basic_block exit_block_map, - bitmap blocks_to_copy, basic_block new_entry) + basic_block new_entry) { tree fndecl = id->src_fn; tree body; @@ -2590,7 +2620,7 @@ copy_body (copy_body_data *id, gcov_type count, int frequency_scale, /* If this body has a CFG, walk CFG and copy. */ gcc_assert (ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (fndecl))); body = copy_cfg_body (id, count, frequency_scale, entry_block_map, exit_block_map, - blocks_to_copy, new_entry); + new_entry); copy_debug_stmts (id); return body; @@ -3742,7 +3772,14 @@ estimate_num_insns (gimple stmt, eni_weights *weights) return 0; case GIMPLE_ASM: - return asm_str_count (gimple_asm_string (stmt)); + { + int count = asm_str_count (gimple_asm_string (stmt)); + /* 1000 means infinity. This avoids overflows later + with very long asm statements. */ + if (count > 1000) + count = 1000; + return count; + } case GIMPLE_RESX: /* This is either going to be an external function call with one @@ -4192,7 +4229,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) duplicate our body before altering anything. */ copy_body (id, bb->count, GCOV_COMPUTE_SCALE (cg_edge->frequency, CGRAPH_FREQ_BASE), - bb, return_block, NULL, NULL); + bb, return_block, NULL); /* Reset the escaped solution. */ if (cfun->gimple_df) @@ -4434,6 +4471,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 (); @@ -4739,6 +4777,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. */ @@ -5198,6 +5237,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 @@ -5319,7 +5359,7 @@ tree_function_versioning (tree old_decl, tree new_decl, /* Copy the Function's body. */ copy_body (&id, old_entry_block->count, REG_BR_PROB_BASE, - ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, blocks_to_copy, new_entry); + ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, new_entry); /* Renumber the lexical scoping (non-code) blocks consecutively. */ number_blocks (new_decl); @@ -5422,6 +5462,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 33d4ba8c623..384d3b33cff 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "gimple-pretty-print.h" #include "bitmap.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "gimple.h" #include "tree-inline.h" #include "hash-table.h" @@ -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); @@ -2409,6 +2375,14 @@ rewrite_into_ssa (void) return 0; } +/* Gate for IPCP optimization. */ + +static bool +gate_into_ssa (void) +{ + /* Do nothing for funcions that was produced already in SSA form. */ + return !(cfun->curr_properties & PROP_ssa); +} namespace { @@ -2417,7 +2391,7 @@ const pass_data pass_data_build_ssa = GIMPLE_PASS, /* type */ "ssa", /* name */ OPTGROUP_NONE, /* optinfo_flags */ - false, /* has_gate */ + true, /* has_gate */ true, /* has_execute */ TV_TREE_SSA_OTHER, /* tv_id */ PROP_cfg, /* properties_required */ @@ -2435,6 +2409,7 @@ public: {} /* opt_pass methods: */ + bool gate () { return gate_into_ssa (); } unsigned int execute () { return rewrite_into_ssa (); } }; // class pass_build_ssa diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 95c4d5f753a..51b6ef03b4e 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -44,12 +44,517 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "tree-chrec.h" #include "tree-data-ref.h" #include "tree-scalar-evolution.h" #include "tree-pass.h" +#include "gimple-pretty-print.h" + + +/* A Reduced Dependence Graph (RDG) vertex representing a statement. */ +typedef struct rdg_vertex +{ + /* The statement represented by this vertex. */ + gimple stmt; + + /* Vector of data-references in this statement. */ + vec<data_reference_p> datarefs; + + /* True when the statement contains a write to memory. */ + bool has_mem_write; + + /* True when the statement contains a read from memory. */ + bool has_mem_reads; +} *rdg_vertex_p; + +#define RDGV_STMT(V) ((struct rdg_vertex *) ((V)->data))->stmt +#define RDGV_DATAREFS(V) ((struct rdg_vertex *) ((V)->data))->datarefs +#define RDGV_HAS_MEM_WRITE(V) ((struct rdg_vertex *) ((V)->data))->has_mem_write +#define RDGV_HAS_MEM_READS(V) ((struct rdg_vertex *) ((V)->data))->has_mem_reads +#define RDG_STMT(RDG, I) RDGV_STMT (&(RDG->vertices[I])) +#define RDG_DATAREFS(RDG, I) RDGV_DATAREFS (&(RDG->vertices[I])) +#define RDG_MEM_WRITE_STMT(RDG, I) RDGV_HAS_MEM_WRITE (&(RDG->vertices[I])) +#define RDG_MEM_READS_STMT(RDG, I) RDGV_HAS_MEM_READS (&(RDG->vertices[I])) + +/* Data dependence type. */ + +enum rdg_dep_type +{ + /* Read After Write (RAW). */ + flow_dd = 'f', + + /* Write After Read (WAR). */ + anti_dd = 'a', + + /* Write After Write (WAW). */ + output_dd = 'o', + + /* Read After Read (RAR). */ + input_dd = 'i', + + /* Control dependence (execute conditional on). */ + control_dd = 'c' +}; + +/* Dependence information attached to an edge of the RDG. */ + +typedef struct rdg_edge +{ + /* Type of the dependence. */ + enum rdg_dep_type type; + + /* Levels of the dependence: the depth of the loops that carry the + dependence. */ + unsigned level; + + /* Dependence relation between data dependences, NULL when one of + the vertices is a scalar. */ + ddr_p relation; +} *rdg_edge_p; + +#define RDGE_TYPE(E) ((struct rdg_edge *) ((E)->data))->type +#define RDGE_LEVEL(E) ((struct rdg_edge *) ((E)->data))->level +#define RDGE_RELATION(E) ((struct rdg_edge *) ((E)->data))->relation + +/* Dump vertex I in RDG to FILE. */ + +static void +dump_rdg_vertex (FILE *file, struct graph *rdg, int i) +{ + struct vertex *v = &(rdg->vertices[i]); + struct graph_edge *e; + + fprintf (file, "(vertex %d: (%s%s) (in:", i, + RDG_MEM_WRITE_STMT (rdg, i) ? "w" : "", + RDG_MEM_READS_STMT (rdg, i) ? "r" : ""); + + if (v->pred) + for (e = v->pred; e; e = e->pred_next) + fprintf (file, " %d", e->src); + + fprintf (file, ") (out:"); + + if (v->succ) + for (e = v->succ; e; e = e->succ_next) + fprintf (file, " %d", e->dest); + + fprintf (file, ")\n"); + print_gimple_stmt (file, RDGV_STMT (v), 0, TDF_VOPS|TDF_MEMSYMS); + fprintf (file, ")\n"); +} + +/* Call dump_rdg_vertex on stderr. */ + +DEBUG_FUNCTION void +debug_rdg_vertex (struct graph *rdg, int i) +{ + dump_rdg_vertex (stderr, rdg, i); +} + +/* Dump the reduced dependence graph RDG to FILE. */ + +static void +dump_rdg (FILE *file, struct graph *rdg) +{ + fprintf (file, "(rdg\n"); + for (int i = 0; i < rdg->n_vertices; i++) + dump_rdg_vertex (file, rdg, i); + fprintf (file, ")\n"); +} + +/* Call dump_rdg on stderr. */ + +DEBUG_FUNCTION void +debug_rdg (struct graph *rdg) +{ + dump_rdg (stderr, rdg); +} + +static void +dot_rdg_1 (FILE *file, struct graph *rdg) +{ + int i; + pretty_printer buffer; + pp_needs_newline (&buffer) = false; + buffer.buffer->stream = file; + + fprintf (file, "digraph RDG {\n"); + + for (i = 0; i < rdg->n_vertices; i++) + { + struct vertex *v = &(rdg->vertices[i]); + struct graph_edge *e; + + fprintf (file, "%d [label=\"[%d] ", i, i); + pp_gimple_stmt_1 (&buffer, RDGV_STMT (v), 0, TDF_SLIM); + pp_flush (&buffer); + fprintf (file, "\"]\n"); + + /* Highlight reads from memory. */ + if (RDG_MEM_READS_STMT (rdg, i)) + fprintf (file, "%d [style=filled, fillcolor=green]\n", i); + + /* Highlight stores to memory. */ + if (RDG_MEM_WRITE_STMT (rdg, i)) + fprintf (file, "%d [style=filled, fillcolor=red]\n", i); + + if (v->succ) + for (e = v->succ; e; e = e->succ_next) + switch (RDGE_TYPE (e)) + { + case input_dd: + fprintf (file, "%d -> %d [label=input] \n", i, e->dest); + break; + + case output_dd: + fprintf (file, "%d -> %d [label=output] \n", i, e->dest); + break; + + case flow_dd: + /* These are the most common dependences: don't print these. */ + fprintf (file, "%d -> %d \n", i, e->dest); + break; + + case anti_dd: + fprintf (file, "%d -> %d [label=anti] \n", i, e->dest); + break; + + case control_dd: + fprintf (file, "%d -> %d [label=control] \n", i, e->dest); + break; + + default: + gcc_unreachable (); + } + } + + fprintf (file, "}\n\n"); +} + +/* Display the Reduced Dependence Graph using dotty. */ + +DEBUG_FUNCTION void +dot_rdg (struct graph *rdg) +{ + /* When debugging, you may want to enable the following code. */ +#if 1 + FILE *file = popen("dot -Tx11", "w"); + if (!file) + return; + dot_rdg_1 (file, rdg); + fflush (file); + close (fileno (file)); + pclose (file); +#else + dot_rdg_1 (stderr, rdg); +#endif +} + +/* Returns the index of STMT in RDG. */ + +static int +rdg_vertex_for_stmt (struct graph *rdg ATTRIBUTE_UNUSED, gimple stmt) +{ + int index = gimple_uid (stmt); + gcc_checking_assert (index == -1 || RDG_STMT (rdg, index) == stmt); + return index; +} + +/* Creates an edge in RDG for each distance vector from DDR. The + order that we keep track of in the RDG is the order in which + statements have to be executed. */ + +static void +create_rdg_edge_for_ddr (struct graph *rdg, ddr_p ddr) +{ + struct graph_edge *e; + int va, vb; + data_reference_p dra = DDR_A (ddr); + data_reference_p drb = DDR_B (ddr); + unsigned level = ddr_dependence_level (ddr); + + /* For non scalar dependences, when the dependence is REVERSED, + statement B has to be executed before statement A. */ + if (level > 0 + && !DDR_REVERSED_P (ddr)) + { + data_reference_p tmp = dra; + dra = drb; + drb = tmp; + } + + va = rdg_vertex_for_stmt (rdg, DR_STMT (dra)); + vb = rdg_vertex_for_stmt (rdg, DR_STMT (drb)); + + if (va < 0 || vb < 0) + return; + + e = add_edge (rdg, va, vb); + e->data = XNEW (struct rdg_edge); + + RDGE_LEVEL (e) = level; + RDGE_RELATION (e) = ddr; + + /* Determines the type of the data dependence. */ + if (DR_IS_READ (dra) && DR_IS_READ (drb)) + RDGE_TYPE (e) = input_dd; + else if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb)) + RDGE_TYPE (e) = output_dd; + else if (DR_IS_WRITE (dra) && DR_IS_READ (drb)) + RDGE_TYPE (e) = flow_dd; + else if (DR_IS_READ (dra) && DR_IS_WRITE (drb)) + RDGE_TYPE (e) = anti_dd; +} + +/* Creates dependence edges in RDG for all the uses of DEF. IDEF is + the index of DEF in RDG. */ + +static void +create_rdg_edges_for_scalar (struct graph *rdg, tree def, int idef) +{ + use_operand_p imm_use_p; + imm_use_iterator iterator; + + FOR_EACH_IMM_USE_FAST (imm_use_p, iterator, def) + { + struct graph_edge *e; + int use = rdg_vertex_for_stmt (rdg, USE_STMT (imm_use_p)); + + if (use < 0) + continue; + + e = add_edge (rdg, idef, use); + e->data = XNEW (struct rdg_edge); + RDGE_TYPE (e) = flow_dd; + RDGE_RELATION (e) = NULL; + } +} + +/* Creates an edge for the control dependences of BB to the vertex V. */ + +static void +create_edge_for_control_dependence (struct graph *rdg, basic_block bb, + int v, control_dependences *cd) +{ + bitmap_iterator bi; + unsigned edge_n; + EXECUTE_IF_SET_IN_BITMAP (cd->get_edges_dependent_on (bb->index), + 0, edge_n, bi) + { + basic_block cond_bb = cd->get_edge (edge_n)->src; + gimple stmt = last_stmt (cond_bb); + if (stmt && is_ctrl_stmt (stmt)) + { + struct graph_edge *e; + int c = rdg_vertex_for_stmt (rdg, stmt); + if (c < 0) + continue; + + e = add_edge (rdg, c, v); + e->data = XNEW (struct rdg_edge); + RDGE_TYPE (e) = control_dd; + RDGE_RELATION (e) = NULL; + } + } +} + +/* Creates the edges of the reduced dependence graph RDG. */ + +static void +create_rdg_edges (struct graph *rdg, vec<ddr_p> ddrs, control_dependences *cd) +{ + int i; + struct data_dependence_relation *ddr; + def_operand_p def_p; + ssa_op_iter iter; + + FOR_EACH_VEC_ELT (ddrs, i, ddr) + if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE) + create_rdg_edge_for_ddr (rdg, ddr); + else + free_dependence_relation (ddr); + + for (i = 0; i < rdg->n_vertices; i++) + FOR_EACH_PHI_OR_STMT_DEF (def_p, RDG_STMT (rdg, i), + iter, SSA_OP_DEF) + create_rdg_edges_for_scalar (rdg, DEF_FROM_PTR (def_p), i); + + if (cd) + for (i = 0; i < rdg->n_vertices; i++) + { + gimple stmt = RDG_STMT (rdg, i); + if (gimple_code (stmt) == GIMPLE_PHI) + { + edge_iterator ei; + edge e; + FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->preds) + create_edge_for_control_dependence (rdg, e->src, i, cd); + } + else + create_edge_for_control_dependence (rdg, gimple_bb (stmt), i, cd); + } +} + +/* Build the vertices of the reduced dependence graph RDG. Return false + if that failed. */ + +static bool +create_rdg_vertices (struct graph *rdg, vec<gimple> stmts, loop_p loop, + vec<data_reference_p> *datarefs) +{ + int i; + gimple stmt; + + FOR_EACH_VEC_ELT (stmts, i, stmt) + { + struct vertex *v = &(rdg->vertices[i]); + + /* Record statement to vertex mapping. */ + gimple_set_uid (stmt, i); + + v->data = XNEW (struct rdg_vertex); + RDGV_STMT (v) = stmt; + RDGV_DATAREFS (v).create (0); + RDGV_HAS_MEM_WRITE (v) = false; + RDGV_HAS_MEM_READS (v) = false; + if (gimple_code (stmt) == GIMPLE_PHI) + continue; + + unsigned drp = datarefs->length (); + if (!find_data_references_in_stmt (loop, stmt, datarefs)) + return false; + for (unsigned j = drp; j < datarefs->length (); ++j) + { + data_reference_p dr = (*datarefs)[j]; + if (DR_IS_READ (dr)) + RDGV_HAS_MEM_READS (v) = true; + else + RDGV_HAS_MEM_WRITE (v) = true; + RDGV_DATAREFS (v).safe_push (dr); + } + } + return true; +} + +/* Initialize STMTS with all the statements of LOOP. The order in + which we discover statements is important as + generate_loops_for_partition is using the same traversal for + identifying statements in loop copies. */ + +static void +stmts_from_loop (struct loop *loop, vec<gimple> *stmts) +{ + unsigned int i; + basic_block *bbs = get_loop_body_in_dom_order (loop); + + for (i = 0; i < loop->num_nodes; i++) + { + basic_block bb = bbs[i]; + gimple_stmt_iterator bsi; + gimple stmt; + + for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi)) + if (!virtual_operand_p (gimple_phi_result (gsi_stmt (bsi)))) + stmts->safe_push (gsi_stmt (bsi)); + + for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) + { + stmt = gsi_stmt (bsi); + if (gimple_code (stmt) != GIMPLE_LABEL && !is_gimple_debug (stmt)) + stmts->safe_push (stmt); + } + } + + free (bbs); +} + +/* Build the Reduced Dependence Graph (RDG) with one vertex per + statement of the loop nest, and one edge per data dependence or + scalar dependence. */ + +struct graph * +build_empty_rdg (int n_stmts) +{ + struct graph *rdg = new_graph (n_stmts); + return rdg; +} + +/* Free the reduced dependence graph RDG. */ + +static void +free_rdg (struct graph *rdg) +{ + int i; + + for (i = 0; i < rdg->n_vertices; i++) + { + struct vertex *v = &(rdg->vertices[i]); + struct graph_edge *e; + + for (e = v->succ; e; e = e->succ_next) + { + free_dependence_relation (RDGE_RELATION (e)); + free (e->data); + } + + if (v->data) + { + gimple_set_uid (RDGV_STMT (v), -1); + free_data_refs (RDGV_DATAREFS (v)); + free (v->data); + } + } + + free_graph (rdg); +} + +/* Build the Reduced Dependence Graph (RDG) with one vertex per + statement of the loop nest LOOP_NEST, and one edge per data dependence or + scalar dependence. */ + +static struct graph * +build_rdg (vec<loop_p> loop_nest, control_dependences *cd) +{ + struct graph *rdg; + vec<gimple> stmts; + vec<data_reference_p> datarefs; + vec<ddr_p> dependence_relations; + + /* Create the RDG vertices from the stmts of the loop nest. */ + stmts.create (10); + stmts_from_loop (loop_nest[0], &stmts); + rdg = build_empty_rdg (stmts.length ()); + datarefs.create (10); + if (!create_rdg_vertices (rdg, stmts, loop_nest[0], &datarefs)) + { + stmts.release (); + datarefs.release (); + free_rdg (rdg); + return NULL; + } + stmts.release (); + + /* Create the RDG edges from the data dependences in the loop nest. */ + dependence_relations.create (100); + if (!compute_all_dependences (datarefs, &dependence_relations, loop_nest, + false) + || !known_dependences_p (dependence_relations)) + { + free_dependence_relations (dependence_relations); + datarefs.release (); + free_rdg (rdg); + return NULL; + } + create_rdg_edges (rdg, dependence_relations, cd); + dependence_relations.release (); + datarefs.release (); + + return rdg; +} + + enum partition_kind { PKIND_NORMAL, PKIND_REDUCTION, PKIND_MEMSET, PKIND_MEMCPY @@ -58,6 +563,7 @@ enum partition_kind { typedef struct partition_s { bitmap stmts; + bitmap loops; bool has_writes; enum partition_kind kind; /* data-references a kind != PKIND_NORMAL partition is about. */ @@ -69,10 +575,11 @@ typedef struct partition_s /* Allocate and initialize a partition from BITMAP. */ static partition_t -partition_alloc (bitmap stmts) +partition_alloc (bitmap stmts, bitmap loops) { partition_t partition = XCNEW (struct partition_s); partition->stmts = stmts ? stmts : BITMAP_ALLOC (NULL); + partition->loops = loops ? loops : BITMAP_ALLOC (NULL); partition->has_writes = false; partition->kind = PKIND_NORMAL; return partition; @@ -84,6 +591,7 @@ static void partition_free (partition_t partition) { BITMAP_FREE (partition->stmts); + BITMAP_FREE (partition->loops); free (partition); } @@ -103,17 +611,6 @@ partition_has_writes (partition_t partition) return partition->has_writes; } -/* If bit I is not set, it means that this node represents an - operation that has already been performed, and that should not be - performed again. This is the subgraph of remaining important - computations that is passed to the DFS algorithm for avoiding to - include several times the same stores in different loops. */ -static bitmap remaining_stmts; - -/* A node of the RDG is marked in this bitmap when it has as a - predecessor a node that writes to memory. */ -static bitmap upstream_mem_writes; - /* Returns true when DEF is an SSA_NAME defined in LOOP and used after the LOOP. */ @@ -193,7 +690,7 @@ static void generate_loops_for_partition (struct loop *loop, partition_t partition, bool copy_p) { - unsigned i, x; + unsigned i; gimple_stmt_iterator bsi; basic_block *bbs; @@ -205,58 +702,75 @@ generate_loops_for_partition (struct loop *loop, partition_t partition, create_bb_after_loop (loop); } - /* Remove stmts not in the PARTITION bitmap. The order in which we - visit the phi nodes and the statements is exactly as in - stmts_from_loop. */ + /* Remove stmts not in the PARTITION bitmap. */ bbs = get_loop_body_in_dom_order (loop); if (MAY_HAVE_DEBUG_STMTS) - for (x = 0, i = 0; i < loop->num_nodes; i++) + for (i = 0; i < loop->num_nodes; i++) { basic_block bb = bbs[i]; for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi)) - if (!bitmap_bit_p (partition->stmts, x++)) - reset_debug_uses (gsi_stmt (bsi)); + { + gimple phi = gsi_stmt (bsi); + if (!virtual_operand_p (gimple_phi_result (phi)) + && !bitmap_bit_p (partition->stmts, gimple_uid (phi))) + reset_debug_uses (phi); + } for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) { gimple stmt = gsi_stmt (bsi); if (gimple_code (stmt) != GIMPLE_LABEL && !is_gimple_debug (stmt) - && !bitmap_bit_p (partition->stmts, x++)) + && !bitmap_bit_p (partition->stmts, gimple_uid (stmt))) reset_debug_uses (stmt); } } - for (x = 0, i = 0; i < loop->num_nodes; i++) + for (i = 0; i < loop->num_nodes; i++) { basic_block bb = bbs[i]; for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi);) - if (!bitmap_bit_p (partition->stmts, x++)) - { - gimple phi = gsi_stmt (bsi); - if (virtual_operand_p (gimple_phi_result (phi))) - mark_virtual_phi_result_for_renaming (phi); + { + gimple phi = gsi_stmt (bsi); + if (!virtual_operand_p (gimple_phi_result (phi)) + && !bitmap_bit_p (partition->stmts, gimple_uid (phi))) remove_phi_node (&bsi, true); - } - else - gsi_next (&bsi); + else + gsi_next (&bsi); + } for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi);) { gimple stmt = gsi_stmt (bsi); if (gimple_code (stmt) != GIMPLE_LABEL && !is_gimple_debug (stmt) - && !bitmap_bit_p (partition->stmts, x++)) + && !bitmap_bit_p (partition->stmts, gimple_uid (stmt))) { - unlink_stmt_vdef (stmt); - gsi_remove (&bsi, true); - release_defs (stmt); + /* Choose an arbitrary path through the empty CFG part + that this unnecessary control stmt controls. */ + if (gimple_code (stmt) == GIMPLE_COND) + { + gimple_cond_make_false (stmt); + update_stmt (stmt); + } + else if (gimple_code (stmt) == GIMPLE_SWITCH) + { + gimple_switch_set_index + (stmt, CASE_LOW (gimple_switch_label (stmt, 1))); + update_stmt (stmt); + } + else + { + unlink_stmt_vdef (stmt); + gsi_remove (&bsi, true); + release_defs (stmt); + continue; + } } - else - gsi_next (&bsi); + gsi_next (&bsi); } } @@ -538,168 +1052,17 @@ rdg_cannot_recompute_vertex_p (struct graph *rdg, int v) static inline bool already_processed_vertex_p (bitmap processed, int v) { - return (bitmap_bit_p (processed, v) - || !bitmap_bit_p (remaining_stmts, v)); -} - -/* Returns NULL when there is no anti-dependence or output-dependence - among the successors of vertex V, otherwise returns the edge with the - dependency. */ - -static struct graph_edge * -has_anti_or_output_dependence (struct vertex *v) -{ - struct graph_edge *e; - - if (v->succ) - for (e = v->succ; e; e = e->succ_next) - if (RDGE_TYPE (e) == anti_dd - || RDGE_TYPE (e) == output_dd) - return e; - - return NULL; -} - -/* Returns true when V has an anti-dependence edge among its successors. */ - -static bool -predecessor_has_mem_write (struct graph *rdg, struct vertex *v) -{ - struct graph_edge *e; - - if (v->pred) - for (e = v->pred; e; e = e->pred_next) - if (bitmap_bit_p (upstream_mem_writes, e->src) - /* Don't consider flow channels: a write to memory followed - by a read from memory. These channels allow the split of - the RDG in different partitions. */ - && !RDG_MEM_WRITE_STMT (rdg, e->src)) - return true; - - return false; -} - -/* Initializes the upstream_mem_writes bitmap following the - information from RDG. */ - -static void -mark_nodes_having_upstream_mem_writes (struct graph *rdg) -{ - int v, x; - bitmap seen = BITMAP_ALLOC (NULL); - - for (v = rdg->n_vertices - 1; v >= 0; v--) - if (!bitmap_bit_p (seen, v)) - { - unsigned i; - vec<int> nodes; - nodes.create (3); - - graphds_dfs (rdg, &v, 1, &nodes, false, NULL); - - FOR_EACH_VEC_ELT (nodes, i, x) - { - if (!bitmap_set_bit (seen, x)) - continue; - - if (RDG_MEM_WRITE_STMT (rdg, x) - || predecessor_has_mem_write (rdg, &(rdg->vertices[x])) - /* In anti dependences the read should occur before - the write, this is why both the read and the write - should be placed in the same partition. In output - dependences the writes order need to be preserved. */ - || has_anti_or_output_dependence (&(rdg->vertices[x]))) - bitmap_set_bit (upstream_mem_writes, x); - } - - nodes.release (); - } -} - -/* Returns true when vertex u has a memory write node as a predecessor - in RDG. */ - -static bool -has_upstream_mem_writes (int u) -{ - return bitmap_bit_p (upstream_mem_writes, u); + return bitmap_bit_p (processed, v); } static void rdg_flag_vertex_and_dependent (struct graph *, int, partition_t, - bitmap, bitmap); - -/* Flag the uses of U stopping following the information from - upstream_mem_writes. */ - -static void -rdg_flag_uses (struct graph *rdg, int u, partition_t partition, bitmap loops, - bitmap processed) -{ - use_operand_p use_p; - struct vertex *x = &(rdg->vertices[u]); - gimple stmt = RDGV_STMT (x); - struct graph_edge *anti_dep = has_anti_or_output_dependence (x); - - /* Keep in the same partition the destination of an antidependence, - because this is a store to the exact same location. Putting this - in another partition is bad for cache locality. */ - if (anti_dep) - { - int v = anti_dep->dest; - - if (!already_processed_vertex_p (processed, v)) - rdg_flag_vertex_and_dependent (rdg, v, partition, loops, - processed); - } - - if (gimple_code (stmt) != GIMPLE_PHI) - { - if ((use_p = gimple_vuse_op (stmt)) != NULL_USE_OPERAND_P) - { - tree use = USE_FROM_PTR (use_p); - - if (TREE_CODE (use) == SSA_NAME - && !SSA_NAME_IS_DEFAULT_DEF (use)) - { - gimple def_stmt = SSA_NAME_DEF_STMT (use); - int v = rdg_vertex_for_stmt (rdg, def_stmt); - - if (v >= 0 - && !already_processed_vertex_p (processed, v)) - rdg_flag_vertex_and_dependent (rdg, v, partition, loops, - processed); - } - } - } - - if (is_gimple_assign (stmt) && has_upstream_mem_writes (u)) - { - tree op0 = gimple_assign_lhs (stmt); - - /* Scalar channels don't have enough space for transmitting data - between tasks, unless we add more storage by privatizing. */ - if (is_gimple_reg (op0)) - { - use_operand_p use_p; - imm_use_iterator iter; - - FOR_EACH_IMM_USE_FAST (use_p, iter, op0) - { - int v = rdg_vertex_for_stmt (rdg, USE_STMT (use_p)); - - if (!already_processed_vertex_p (processed, v)) - rdg_flag_vertex_and_dependent (rdg, v, partition, loops, - processed); - } - } - } -} + bitmap); /* Flag V from RDG as part of PARTITION, and also flag its loop number in LOOPS. */ static void -rdg_flag_vertex (struct graph *rdg, int v, partition_t partition, bitmap loops) +rdg_flag_vertex (struct graph *rdg, int v, partition_t partition) { struct loop *loop; @@ -707,13 +1070,10 @@ rdg_flag_vertex (struct graph *rdg, int v, partition_t partition, bitmap loops) return; loop = loop_containing_stmt (RDG_STMT (rdg, v)); - bitmap_set_bit (loops, loop->num); + bitmap_set_bit (partition->loops, loop->num); if (rdg_cannot_recompute_vertex_p (rdg, v)) - { - partition->has_writes = true; - bitmap_clear_bit (remaining_stmts, v); - } + partition->has_writes = true; } /* Flag in the bitmap PARTITION the vertex V and all its predecessors. @@ -721,164 +1081,35 @@ rdg_flag_vertex (struct graph *rdg, int v, partition_t partition, bitmap loops) static void rdg_flag_vertex_and_dependent (struct graph *rdg, int v, partition_t partition, - bitmap loops, bitmap processed) + bitmap processed) { unsigned i; vec<int> nodes; nodes.create (3); int x; - bitmap_set_bit (processed, v); - rdg_flag_uses (rdg, v, partition, loops, processed); - graphds_dfs (rdg, &v, 1, &nodes, false, remaining_stmts); - rdg_flag_vertex (rdg, v, partition, loops); + graphds_dfs (rdg, &v, 1, &nodes, false, NULL); FOR_EACH_VEC_ELT (nodes, i, x) - if (!already_processed_vertex_p (processed, x)) - rdg_flag_vertex_and_dependent (rdg, x, partition, loops, processed); + if (bitmap_set_bit (processed, x)) + rdg_flag_vertex (rdg, x, partition); nodes.release (); } -/* Initialize CONDS with all the condition statements from the basic - blocks of LOOP. */ - -static void -collect_condition_stmts (struct loop *loop, vec<gimple> *conds) -{ - unsigned i; - edge e; - vec<edge> exits = get_loop_exit_edges (loop); - - FOR_EACH_VEC_ELT (exits, i, e) - { - gimple cond = last_stmt (e->src); - - if (cond) - conds->safe_push (cond); - } - - exits.release (); -} - -/* Add to PARTITION all the exit condition statements for LOOPS - together with all their dependent statements determined from - RDG. */ - -static void -rdg_flag_loop_exits (struct graph *rdg, bitmap loops, partition_t partition, - bitmap processed) -{ - unsigned i; - bitmap_iterator bi; - vec<gimple> conds; - conds.create (3); - - EXECUTE_IF_SET_IN_BITMAP (loops, 0, i, bi) - collect_condition_stmts (get_loop (cfun, i), &conds); - - while (!conds.is_empty ()) - { - gimple cond = conds.pop (); - int v = rdg_vertex_for_stmt (rdg, cond); - bitmap new_loops = BITMAP_ALLOC (NULL); - - if (!already_processed_vertex_p (processed, v)) - rdg_flag_vertex_and_dependent (rdg, v, partition, new_loops, processed); - - EXECUTE_IF_SET_IN_BITMAP (new_loops, 0, i, bi) - if (bitmap_set_bit (loops, i)) - collect_condition_stmts (get_loop (cfun, i), &conds); - - BITMAP_FREE (new_loops); - } - - conds.release (); -} - -/* Returns a bitmap in which all the statements needed for computing - the strongly connected component C of the RDG are flagged, also - including the loop exit conditions. */ +/* Returns a partition with all the statements needed for computing + the vertex V of the RDG, also including the loop exit conditions. */ static partition_t -build_rdg_partition_for_component (struct graph *rdg, rdgc c) +build_rdg_partition_for_vertex (struct graph *rdg, int v) { - int i, v; - partition_t partition = partition_alloc (NULL); - bitmap loops = BITMAP_ALLOC (NULL); + partition_t partition = partition_alloc (NULL, NULL); bitmap processed = BITMAP_ALLOC (NULL); - - FOR_EACH_VEC_ELT (c->vertices, i, v) - if (!already_processed_vertex_p (processed, v)) - rdg_flag_vertex_and_dependent (rdg, v, partition, loops, processed); - - rdg_flag_loop_exits (rdg, loops, partition, processed); - + rdg_flag_vertex_and_dependent (rdg, v, partition, processed); BITMAP_FREE (processed); - BITMAP_FREE (loops); return partition; } -/* Free memory for COMPONENTS. */ - -static void -free_rdg_components (vec<rdgc> components) -{ - int i; - rdgc x; - - FOR_EACH_VEC_ELT (components, i, x) - { - x->vertices.release (); - free (x); - } - - components.release (); -} - -/* Build the COMPONENTS vector with the strongly connected components - of RDG in which the STARTING_VERTICES occur. */ - -static void -rdg_build_components (struct graph *rdg, vec<int> starting_vertices, - vec<rdgc> *components) -{ - int i, v; - bitmap saved_components = BITMAP_ALLOC (NULL); - int n_components = graphds_scc (rdg, NULL); - /* ??? Macros cannot process template types with more than one - argument, so we need this typedef. */ - typedef vec<int> vec_int_heap; - vec<int> *all_components = XNEWVEC (vec_int_heap, n_components); - - for (i = 0; i < n_components; i++) - all_components[i].create (3); - - for (i = 0; i < rdg->n_vertices; i++) - all_components[rdg->vertices[i].component].safe_push (i); - - FOR_EACH_VEC_ELT (starting_vertices, i, v) - { - int c = rdg->vertices[v].component; - - if (bitmap_set_bit (saved_components, c)) - { - rdgc x = XCNEW (struct rdg_component); - x->num = c; - x->vertices = all_components[c]; - - components->safe_push (x); - } - } - - for (i = 0; i < n_components; i++) - if (!bitmap_bit_p (saved_components, i)) - all_components[i].release (); - - free (all_components); - BITMAP_FREE (saved_components); -} - /* Classifies the builtin kind we can generate for PARTITION of RDG and LOOP. For the moment we detect only the memset zero pattern. */ @@ -1095,23 +1326,28 @@ similar_memory_accesses (struct graph *rdg, partition_t partition1, distributed in different loops. */ static void -rdg_build_partitions (struct graph *rdg, vec<rdgc> components, - vec<int> *other_stores, - vec<partition_t> *partitions, bitmap processed) +rdg_build_partitions (struct graph *rdg, + vec<gimple> starting_stmts, + vec<partition_t> *partitions) { + bitmap processed = BITMAP_ALLOC (NULL); int i; - rdgc x; - partition_t partition = partition_alloc (NULL); + gimple stmt; + partition_t partition = partition_alloc (NULL, NULL); - FOR_EACH_VEC_ELT (components, i, x) + FOR_EACH_VEC_ELT (starting_stmts, i, stmt) { partition_t np; - int v = x->vertices[0]; + int v = rdg_vertex_for_stmt (rdg, stmt); + + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + "ldist asked to generate code for vertex %d\n", v); if (bitmap_bit_p (processed, v)) continue; - np = build_rdg_partition_for_component (rdg, x); + np = build_rdg_partition_for_vertex (rdg, v); bitmap_ior_into (partition->stmts, np->stmts); partition->has_writes = partition_has_writes (np); bitmap_ior_into (processed, np->stmts); @@ -1126,40 +1362,27 @@ rdg_build_partitions (struct graph *rdg, vec<rdgc> components, } partitions->safe_push (partition); - partition = partition_alloc (NULL); + partition = partition_alloc (NULL, NULL); } } - /* Add the nodes from the RDG that were not marked as processed, and - that are used outside the current loop. These are scalar - computations that are not yet part of previous partitions. */ - for (i = 0; i < rdg->n_vertices; i++) - if (!bitmap_bit_p (processed, i) - && rdg_defs_used_in_other_loops_p (rdg, i)) - other_stores->safe_push (i); - - /* If there are still statements left in the OTHER_STORES array, - create other components and partitions with these stores and - their dependences. */ - if (other_stores->length () > 0) - { - vec<rdgc> comps; - comps.create (3); - vec<int> foo; - foo.create (3); + /* All vertices should have been assigned to at least one partition now, + other than vertices belonging to dead code. */ - rdg_build_components (rdg, *other_stores, &comps); - rdg_build_partitions (rdg, comps, &foo, partitions, processed); + if (!bitmap_empty_p (partition->stmts)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "remaining partition:\n"); + dump_bitmap (dump_file, partition->stmts); + } - foo.release (); - free_rdg_components (comps); + partitions->safe_push (partition); } - - /* If there is something left in the last partition, save it. */ - if (bitmap_count_bits (partition->stmts) > 0) - partitions->safe_push (partition); else partition_free (partition); + + BITMAP_FREE (processed); } /* Dump to FILE the PARTITIONS. */ @@ -1242,56 +1465,47 @@ partition_contains_all_rw (struct graph *rdg, return false; } -/* Generate code from STARTING_VERTICES in RDG. Returns the number of - distributed loops. */ + +/* Distributes the code from LOOP in such a way that producer + statements are placed before consumer statements. Tries to separate + only the statements from STMTS into separate loops. + Returns the number of distributed loops. */ static int -ldist_gen (struct loop *loop, struct graph *rdg, - vec<int> starting_vertices) +distribute_loop (struct loop *loop, vec<gimple> stmts, + control_dependences *cd) { - int i, nbp; - vec<rdgc> components; - components.create (3); + struct graph *rdg; + vec<loop_p> loop_nest; vec<partition_t> partitions; - partitions.create (3); - vec<int> other_stores; - other_stores.create (3); partition_t partition; - bitmap processed = BITMAP_ALLOC (NULL); bool any_builtin; + int i, nbp; - remaining_stmts = BITMAP_ALLOC (NULL); - upstream_mem_writes = BITMAP_ALLOC (NULL); - - for (i = 0; i < rdg->n_vertices; i++) + loop_nest.create (3); + if (!find_loop_nest (loop, &loop_nest)) { - bitmap_set_bit (remaining_stmts, i); - - /* Save in OTHER_STORES all the memory writes that are not in - STARTING_VERTICES. */ - if (RDG_MEM_WRITE_STMT (rdg, i)) - { - int v; - unsigned j; - bool found = false; + loop_nest.release (); + return 0; + } - FOR_EACH_VEC_ELT (starting_vertices, j, v) - if (i == v) - { - found = true; - break; - } + rdg = build_rdg (loop_nest, cd); + if (!rdg) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + "Loop %d not distributed: failed to build the RDG.\n", + loop->num); - if (!found) - other_stores.safe_push (i); - } + loop_nest.release (); + return 0; } - mark_nodes_having_upstream_mem_writes (rdg); - rdg_build_components (rdg, starting_vertices, &components); - rdg_build_partitions (rdg, components, &other_stores, &partitions, - processed); - BITMAP_FREE (processed); + if (dump_file && (dump_flags & TDF_DETAILS)) + dump_rdg (dump_file, rdg); + + partitions.create (3); + rdg_build_partitions (rdg, stmts, &partitions); any_builtin = false; FOR_EACH_VEC_ELT (partitions, i, partition) @@ -1300,18 +1514,51 @@ ldist_gen (struct loop *loop, struct graph *rdg, any_builtin |= partition_builtin_p (partition); } + /* If we did not detect any builtin but are not asked to apply + regular loop distribution simply bail out. */ + if (!flag_tree_loop_distribution + && !any_builtin) + { + nbp = 0; + goto ldist_done; + } + + /* Apply our simple cost model - fuse partitions with similar + memory accesses. */ + partition_t into; + for (i = 0; partitions.iterate (i, &into); ++i) + { + if (partition_builtin_p (into)) + continue; + for (int j = i + 1; + partitions.iterate (j, &partition); ++j) + { + if (!partition_builtin_p (partition) + && similar_memory_accesses (rdg, into, partition)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "fusing partitions\n"); + dump_bitmap (dump_file, into->stmts); + dump_bitmap (dump_file, partition->stmts); + fprintf (dump_file, "because they have similar " + "memory accesses\n"); + } + bitmap_ior_into (into->stmts, partition->stmts); + if (partition->kind == PKIND_REDUCTION) + into->kind = PKIND_REDUCTION; + partitions.ordered_remove (j); + partition_free (partition); + j--; + } + } + } + /* If we are only distributing patterns fuse all partitions that - were not properly classified as builtins. Else fuse partitions - with similar memory accesses. */ + were not properly classified as builtins. */ if (!flag_tree_loop_distribution) { partition_t into; - /* If we did not detect any builtin simply bail out. */ - if (!any_builtin) - { - nbp = 0; - goto ldist_done; - } /* Only fuse adjacent non-builtin partitions, see PR53616. ??? Use dependence information to improve partition ordering. */ i = 0; @@ -1335,41 +1582,6 @@ ldist_gen (struct loop *loop, struct graph *rdg, } while ((unsigned) i < partitions.length ()); } - else - { - partition_t into; - int j; - for (i = 0; partitions.iterate (i, &into); ++i) - { - if (partition_builtin_p (into)) - continue; - for (j = i + 1; - partitions.iterate (j, &partition); ++j) - { - if (!partition_builtin_p (partition) - /* ??? The following is horribly inefficient, - we are re-computing and analyzing data-references - of the stmts in the partitions all the time. */ - && similar_memory_accesses (rdg, into, partition)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "fusing partitions\n"); - dump_bitmap (dump_file, into->stmts); - dump_bitmap (dump_file, partition->stmts); - fprintf (dump_file, "because they have similar " - "memory accesses\n"); - } - bitmap_ior_into (into->stmts, partition->stmts); - if (partition->kind == PKIND_REDUCTION) - into->kind = PKIND_REDUCTION; - partitions.ordered_remove (j); - partition_free (partition); - j--; - } - } - } - } /* Fuse all reduction partitions into the last. */ if (partitions.length () > 1) @@ -1412,80 +1624,13 @@ ldist_gen (struct loop *loop, struct graph *rdg, ldist_done: - BITMAP_FREE (remaining_stmts); - BITMAP_FREE (upstream_mem_writes); - FOR_EACH_VEC_ELT (partitions, i, partition) partition_free (partition); - - other_stores.release (); partitions.release (); - free_rdg_components (components); - return nbp; -} - -/* Distributes the code from LOOP in such a way that producer - statements are placed before consumer statements. When STMTS is - NULL, performs the maximal distribution, if STMTS is not NULL, - tries to separate only these statements from the LOOP's body. - Returns the number of distributed loops. */ - -static int -distribute_loop (struct loop *loop, vec<gimple> stmts) -{ - int res = 0; - struct graph *rdg; - gimple s; - unsigned i; - vec<int> vertices; - vec<ddr_p> dependence_relations; - vec<data_reference_p> datarefs; - vec<loop_p> loop_nest; - - datarefs.create (10); - dependence_relations.create (100); - loop_nest.create (3); - rdg = build_rdg (loop, &loop_nest, &dependence_relations, &datarefs); - - if (!rdg) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - "FIXME: Loop %d not distributed: failed to build the RDG.\n", - loop->num); - - free_dependence_relations (dependence_relations); - free_data_refs (datarefs); - loop_nest.release (); - return res; - } - - vertices.create (3); - if (dump_file && (dump_flags & TDF_DETAILS)) - dump_rdg (dump_file, rdg); - - FOR_EACH_VEC_ELT (stmts, i, s) - { - int v = rdg_vertex_for_stmt (rdg, s); - - if (v >= 0) - { - vertices.safe_push (v); - - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - "ldist asked to generate code for vertex %d\n", v); - } - } - - res = ldist_gen (loop, rdg, vertices); - vertices.release (); free_rdg (rdg); - free_dependence_relations (dependence_relations); - free_data_refs (datarefs); loop_nest.release (); - return res; + return nbp; } /* Distribute all loops in the current function. */ @@ -1497,6 +1642,7 @@ tree_loop_distribution (void) loop_iterator li; bool changed = false; basic_block bb; + control_dependences *cd = NULL; FOR_ALL_BB (bb) { @@ -1526,18 +1672,34 @@ tree_loop_distribution (void) if (!optimize_loop_for_speed_p (loop)) continue; - /* Only distribute loops with a header and latch for now. */ - if (loop->num_nodes > 2) - continue; - /* Initialize the worklist with stmts we seed the partitions with. */ bbs = get_loop_body_in_dom_order (loop); 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); + + /* If there is a stmt with side-effects bail out - we + cannot and should not distribute this loop. */ + if (gimple_has_side_effects (stmt)) + { + work_list.truncate (0); + goto out; + } + /* Distribute stmts which have defs that are used outside of the loop. */ if (stmt_has_scalar_dependences_outside_loop (loop, stmt)) @@ -1550,10 +1712,19 @@ tree_loop_distribution (void) work_list.safe_push (stmt); } } +out: free (bbs); if (work_list.length () > 0) - nb_generated_loops = distribute_loop (loop, work_list); + { + if (!cd) + { + calculate_dominance_info (CDI_POST_DOMINATORS); + cd = new control_dependences (create_edge_list ()); + free_dominance_info (CDI_POST_DOMINATORS); + } + nb_generated_loops = distribute_loop (loop, work_list, cd); + } if (nb_generated_loops > 0) changed = true; @@ -1570,6 +1741,9 @@ tree_loop_distribution (void) work_list.release (); } + if (cd) + delete cd; + if (changed) { mark_virtual_operands_for_renaming (cfun); diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c index 4a1cf47cf9c..620a919f597 100644 --- a/gcc/tree-mudflap.c +++ b/gcc/tree-mudflap.c @@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-inline.h" #include "gimple.h" #include "tree-iterator.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-mudflap.h" #include "tree-pass.h" #include "hashtab.h" diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index fe44679a013..c4f9b808af5 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -28,7 +28,7 @@ #include "tree-inline.h" #include "gimple.h" #include "tree-iterator.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cgraph.h" #include "expr.h" /* FIXME: For STACK_SAVEAREA_MODE and SAVE_NONLOCAL. */ #include "langhooks.h" diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c index 2acb2ebaa34..1961a297429 100644 --- a/gcc/tree-nrv.c +++ b/gcc/tree-nrv.c @@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "basic-block.h" #include "tree-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "langhooks.h" #include "flags.h" /* For "optimize" in gate_pass_return_slot. diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index a0cdf829745..924c4776411 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "diagnostic-core.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "tree-ssa-propagate.h" diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index 9c99ec23a2e..0c278d0292c 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "basic-block.h" #include "flags.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "function.h" #include "langhooks.h" #include "diagnostic-core.h" diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index ff3e058a978..5ed145db024 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "gimple-pretty-print.h" #include "bitmap.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "dumpfile.h" #include "diagnostic-core.h" #include "ssaexpand.h" diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index 9d413c7fb42..94843cae52b 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -22,7 +22,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "tree-data-ref.h" #include "tree-scalar-evolution.h" diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c index 44997537ccb..0bd5085ba99 100644 --- a/gcc/tree-phinodes.c +++ b/gcc/tree-phinodes.c @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "ggc.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "diagnostic-core.h" #include "gimple.h" diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index 11c66235eff..e078ce74f90 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -191,7 +191,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "tm_p.h" #include "cfgloop.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "ggc.h" #include "tree-data-ref.h" #include "tree-scalar-evolution.h" diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index dae0b9c6fd2..ad4845c0c27 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "tree-pretty-print.h" #include "hashtab.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "langhooks.h" #include "tree-iterator.h" #include "tree-chrec.h" diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index dd164b53a74..a2c4209646f 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.c @@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-core.h" #include "coverage.h" #include "tree.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "value-prof.h" #include "cgraph.h" diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index bed621fe052..bda45a6f63b 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -258,7 +258,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "hash-table.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "tree-chrec.h" #include "tree-scalar-evolution.h" @@ -269,13 +269,13 @@ static tree analyze_scalar_evolution_1 (struct loop *, tree, tree); static tree analyze_scalar_evolution_for_address_of (struct loop *loop, tree var); -/* The cached information about an SSA name VAR, claiming that below - basic block INSTANTIATED_BELOW, the value of VAR can be expressed - as CHREC. */ +/* The cached information about an SSA name with version NAME_VERSION, + claiming that below basic block with index INSTANTIATED_BELOW, the + value of the SSA name can be expressed as CHREC. */ struct GTY(()) scev_info_str { - basic_block instantiated_below; - tree var; + unsigned int name_version; + int instantiated_below; tree chrec; }; @@ -309,9 +309,9 @@ new_scev_info_str (basic_block instantiated_below, tree var) struct scev_info_str *res; res = ggc_alloc_scev_info_str (); - res->var = var; + res->name_version = SSA_NAME_VERSION (var); res->chrec = chrec_not_analyzed_yet; - res->instantiated_below = instantiated_below; + res->instantiated_below = instantiated_below->index; return res; } @@ -319,9 +319,10 @@ new_scev_info_str (basic_block instantiated_below, tree var) /* Computes a hash function for database element ELT. */ static inline hashval_t -hash_scev_info (const void *elt) +hash_scev_info (const void *elt_) { - return SSA_NAME_VERSION (((const struct scev_info_str *) elt)->var); + const struct scev_info_str *elt = (const struct scev_info_str *) elt_; + return elt->name_version ^ elt->instantiated_below; } /* Compares database elements E1 and E2. */ @@ -332,7 +333,7 @@ eq_scev_info (const void *e1, const void *e2) const struct scev_info_str *elt1 = (const struct scev_info_str *) e1; const struct scev_info_str *elt2 = (const struct scev_info_str *) e2; - return (elt1->var == elt2->var + return (elt1->name_version == elt2->name_version && elt1->instantiated_below == elt2->instantiated_below); } @@ -355,8 +356,8 @@ find_var_scev_info (basic_block instantiated_below, tree var) struct scev_info_str tmp; PTR *slot; - tmp.var = var; - tmp.instantiated_below = instantiated_below; + tmp.name_version = SSA_NAME_VERSION (var); + tmp.instantiated_below = instantiated_below->index; slot = htab_find_slot (scalar_evolution_info, &tmp, INSERT); if (!*slot) @@ -1648,6 +1649,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 +1664,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 +1675,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 +1688,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 +1698,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 +1708,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 +1717,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 +1726,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 +1737,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; @@ -2051,84 +2066,76 @@ analyze_scalar_evolution_in_loop (struct loop *wrto_loop, struct loop *use_loop, instantiating a CHREC or resolving mixers. For this use instantiated_below is always the same. */ -struct instantiate_cache_entry -{ - tree name; - 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; - vec<instantiate_cache_entry> entries; + htab_t map; + vec<scev_info_str> 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 (); + htab_delete (map); entries.release (); } } -static instantiate_cache_type *ctbl; +/* 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; + +/* Computes a hash function for database element ELT. */ -inline hashval_t -instantiate_cache_entry_hasher::hash (const value_type *idx) +static inline hashval_t +hash_idx_scev_info (const void *elt_) { - instantiate_cache_entry *elt - = &ctbl->entries[reinterpret_cast <uintptr_t> (idx) - 2]; - return SSA_NAME_VERSION (elt->name); + unsigned idx = ((size_t) elt_) - 2; + return hash_scev_info (&global_cache->entries[idx]); } -inline bool -instantiate_cache_entry_hasher::equal (const value_type *idx1, - const compare_type *elt2) +/* Compares database elements E1 and E2. */ + +static inline int +eq_idx_scev_info (const void *e1, const void *e2) { - compare_type *elt1 = &ctbl->entries[reinterpret_cast <uintptr_t> (idx1) - 2]; - return elt1->name == elt2->name; + unsigned idx1 = ((size_t) e1) - 2; + return eq_scev_info (&global_cache->entries[idx1], e2); } -/* 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 * -get_instantiated_value_entry (instantiate_cache_type &cache, tree name) +static unsigned +get_instantiated_value_entry (instantiate_cache_type &cache, + tree name, basic_block instantiate_below) { - struct instantiate_cache_entry e; - uintptr_t **slot; - - if (!cache.htab.is_created ()) + if (!cache.map) { - cache.htab.create (10); + cache.map = htab_create (10, hash_idx_scev_info, eq_idx_scev_info, NULL); cache.entries.create (10); } - ctbl = &cache; - - e.name = name; - slot = cache.htab.find_slot_with_hash (&e, SSA_NAME_VERSION (name), INSERT); + scev_info_str e; + e.name_version = SSA_NAME_VERSION (name); + e.instantiated_below = instantiate_below->index; + void **slot = htab_find_slot_with_hash (cache.map, &e, + hash_scev_info (&e), INSERT); if (!*slot) { e.chrec = chrec_not_analyzed_yet; + *slot = (void *)(size_t)(cache.entries.length () + 2); 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 ((size_t)*slot) - 2; } + /* Return the closed_loop_phi node for VAR. If there is none, return NULL_TREE. */ @@ -2160,7 +2167,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 +2187,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 +2210,13 @@ 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, instantiate_below); + 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 +2249,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 +2266,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 +2291,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 +2337,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 +2393,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 +2430,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 +2480,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 +2529,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 +2577,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 +2617,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 +2650,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 +2666,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 +2682,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 +2696,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 +2708,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 +2722,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 +2756,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 +2767,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 +2801,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-sra.c b/gcc/tree-sra.c index 18b82fb522f..85f9ea81dc3 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -80,7 +80,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "gimple.h" #include "cgraph.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "ipa-prop.h" #include "statistics.h" @@ -91,6 +91,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-inline.h" #include "gimple-pretty-print.h" #include "ipa-inline.h" +#include "ipa-utils.h" /* Enumeration of all aggregate reductions we can do. */ enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */ @@ -1256,8 +1257,7 @@ scan_function (void) if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS) encountered_apply_args = true; - if (cgraph_get_node (dest) - == cgraph_get_node (current_function_decl)) + if (recursive_call_p (current_function_decl, dest)) { encountered_recursive_call = true; if (!callsite_has_enough_arguments_p (stmt)) @@ -4906,6 +4906,16 @@ modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments) return cfg_changed; } +/* If NODE has a caller, return true. */ + +static bool +has_caller_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) +{ + if (node->callers) + return true; + return false; +} + /* Return false the function is apparently unsuitable for IPA-SRA based on it's attributes, return true otherwise. NODE is the cgraph node of the current function. */ @@ -4949,7 +4959,7 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node) return false; } - if (!node->callers) + if (!cgraph_for_node_and_aliases (node, has_caller_p, NULL, true)) { if (dump_file) fprintf (dump_file, diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c index d2a17e825df..b282cdd4af9 100644 --- a/gcc/tree-ssa-address.c +++ b/gcc/tree-ssa-address.c @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "basic-block.h" #include "tree-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "dumpfile.h" #include "flags.h" #include "tree-inline.h" diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 8ed18e2e604..fe7b6b0e4a5 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pretty-print.h" #include "dumpfile.h" #include "gimple.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-inline.h" #include "params.h" #include "vec.h" diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h index 96d01928e9d..e560685028b 100644 --- a/gcc/tree-ssa-alias.h +++ b/gcc/tree-ssa-alias.h @@ -116,7 +116,6 @@ extern void *walk_non_aliased_vuses (ao_ref *, tree, extern unsigned int walk_aliased_vdefs (ao_ref *, tree, bool (*)(ao_ref *, tree, void *), void *, bitmap *); -extern struct ptr_info_def *get_ptr_info (tree); extern void dump_alias_info (FILE *); extern void debug_alias_info (void); extern void dump_points_to_solution (FILE *, struct pt_solution *); diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 556021b92d3..bec3cfe2097 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -128,7 +128,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "function.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "tree-ssa-propagate.h" #include "value-prof.h" diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c index d6471918d51..d86e0b86560 100644 --- a/gcc/tree-ssa-coalesce.c +++ b/gcc/tree-ssa-coalesce.c @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pretty-print.h" #include "bitmap.h" #include "dumpfile.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "hash-table.h" #include "tree-ssa-live.h" #include "diagnostic-core.h" diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c index 9bc455c61a7..31979177444 100644 --- a/gcc/tree-ssa-copy.c +++ b/gcc/tree-ssa-copy.c @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "function.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "tree-ssa-propagate.h" #include "langhooks.h" diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c index 990598ef29b..f6e4b451541 100644 --- a/gcc/tree-ssa-copyrename.c +++ b/gcc/tree-ssa-copyrename.c @@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "tree-pretty-print.h" #include "bitmap.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "gimple.h" #include "tree-inline.h" #include "hashtab.h" diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index 22ae50b791c..8e8f37ce8c8 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -50,7 +50,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "gimple-pretty-print.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "gimple.h" #include "tree-pass.h" #include "flags.h" @@ -87,7 +87,7 @@ static sbitmap bb_contains_live_stmts; use a bitmap for each block recording its edges. An array holds the bitmap. The Ith bit in the bitmap is set if that block is dependent on the Ith edge. */ -static bitmap *control_dependence_map; +static control_dependences *cd; /* Vector indicating that a basic block has already had all the edges processed that it is control dependent on. */ @@ -100,96 +100,6 @@ static sbitmap visited_control_parents; to be recomputed. */ static bool cfg_altered; -/* Execute code that follows the macro for each edge (given number - EDGE_NUMBER within the CODE) for which the block with index N is - control dependent. */ -#define EXECUTE_IF_CONTROL_DEPENDENT(BI, N, EDGE_NUMBER) \ - EXECUTE_IF_SET_IN_BITMAP (control_dependence_map[(N)], 0, \ - (EDGE_NUMBER), (BI)) - - -/* Indicate block BB is control dependent on an edge with index EDGE_INDEX. */ -static inline void -set_control_dependence_map_bit (basic_block bb, int edge_index) -{ - if (bb == ENTRY_BLOCK_PTR) - return; - gcc_assert (bb != EXIT_BLOCK_PTR); - bitmap_set_bit (control_dependence_map[bb->index], edge_index); -} - -/* Clear all control dependences for block BB. */ -static inline void -clear_control_dependence_bitmap (basic_block bb) -{ - bitmap_clear (control_dependence_map[bb->index]); -} - - -/* Find the immediate postdominator PDOM of the specified basic block BLOCK. - This function is necessary because some blocks have negative numbers. */ - -static inline basic_block -find_pdom (basic_block block) -{ - gcc_assert (block != ENTRY_BLOCK_PTR); - - if (block == EXIT_BLOCK_PTR) - return EXIT_BLOCK_PTR; - else - { - basic_block bb = get_immediate_dominator (CDI_POST_DOMINATORS, block); - if (! bb) - return EXIT_BLOCK_PTR; - return bb; - } -} - - -/* Determine all blocks' control dependences on the given edge with edge_list - EL index EDGE_INDEX, ala Morgan, Section 3.6. */ - -static void -find_control_dependence (struct edge_list *el, int edge_index) -{ - basic_block current_block; - basic_block ending_block; - - gcc_assert (INDEX_EDGE_PRED_BB (el, edge_index) != EXIT_BLOCK_PTR); - - if (INDEX_EDGE_PRED_BB (el, edge_index) == ENTRY_BLOCK_PTR) - ending_block = single_succ (ENTRY_BLOCK_PTR); - else - ending_block = find_pdom (INDEX_EDGE_PRED_BB (el, edge_index)); - - for (current_block = INDEX_EDGE_SUCC_BB (el, edge_index); - current_block != ending_block && current_block != EXIT_BLOCK_PTR; - current_block = find_pdom (current_block)) - { - edge e = INDEX_EDGE (el, edge_index); - - /* For abnormal edges, we don't make current_block control - dependent because instructions that throw are always necessary - anyway. */ - if (e->flags & EDGE_ABNORMAL) - continue; - - set_control_dependence_map_bit (current_block, edge_index); - } -} - - -/* Record all blocks' control dependences on all edges in the edge - list EL, ala Morgan, Section 3.6. */ - -static void -find_all_control_dependences (struct edge_list *el) -{ - int i; - - for (i = 0; i < NUM_EDGES (el); ++i) - find_control_dependence (el, i); -} /* If STMT is not already marked necessary, mark it, and add it to the worklist if ADD_TO_WORKLIST is true. */ @@ -400,8 +310,7 @@ mark_last_stmt_necessary (basic_block bb) When IGNORE_SELF is true, ignore BB in the list of control dependences. */ static void -mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el, - bool ignore_self) +mark_control_dependent_edges_necessary (basic_block bb, bool ignore_self) { bitmap_iterator bi; unsigned edge_number; @@ -412,9 +321,10 @@ mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el, if (bb == ENTRY_BLOCK_PTR) return; - EXECUTE_IF_CONTROL_DEPENDENT (bi, bb->index, edge_number) + EXECUTE_IF_SET_IN_BITMAP (cd->get_edges_dependent_on (bb->index), + 0, edge_number, bi) { - basic_block cd_bb = INDEX_EDGE_PRED_BB (el, edge_number); + basic_block cd_bb = cd->get_edge (edge_number)->src; if (ignore_self && cd_bb == bb) { @@ -439,7 +349,7 @@ mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el, dependence analysis. */ static void -find_obviously_necessary_stmts (struct edge_list *el) +find_obviously_necessary_stmts (bool aggressive) { basic_block bb; gimple_stmt_iterator gsi; @@ -461,7 +371,7 @@ find_obviously_necessary_stmts (struct edge_list *el) { stmt = gsi_stmt (gsi); gimple_set_plf (stmt, STMT_NECESSARY, false); - mark_stmt_if_obviously_necessary (stmt, el != NULL); + mark_stmt_if_obviously_necessary (stmt, aggressive); } } @@ -472,7 +382,7 @@ find_obviously_necessary_stmts (struct edge_list *el) return; /* Prevent the empty possibly infinite loops from being removed. */ - if (el) + if (aggressive) { loop_iterator li; struct loop *loop; @@ -488,7 +398,7 @@ find_obviously_necessary_stmts (struct edge_list *el) if (dump_file) fprintf (dump_file, "Marking back edge of irreducible loop %i->%i\n", e->src->index, e->dest->index); - mark_control_dependent_edges_necessary (e->dest, el, false); + mark_control_dependent_edges_necessary (e->dest, false); } } @@ -497,7 +407,7 @@ find_obviously_necessary_stmts (struct edge_list *el) { if (dump_file) fprintf (dump_file, "can not prove finiteness of loop %i\n", loop->num); - mark_control_dependent_edges_necessary (loop->latch, el, false); + mark_control_dependent_edges_necessary (loop->latch, false); } scev_finalize (); } @@ -690,10 +600,9 @@ degenerate_phi_p (gimple phi) In conservative mode, EL is NULL. */ static void -propagate_necessity (struct edge_list *el) +propagate_necessity (bool aggressive) { gimple stmt; - bool aggressive = (el ? true : false); if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "\nProcessing worklist:\n"); @@ -718,7 +627,7 @@ propagate_necessity (struct edge_list *el) basic_block bb = gimple_bb (stmt); if (bb != ENTRY_BLOCK_PTR && !bitmap_bit_p (visited_control_parents, bb->index)) - mark_control_dependent_edges_necessary (bb, el, false); + mark_control_dependent_edges_necessary (bb, false); } if (gimple_code (stmt) == GIMPLE_PHI @@ -825,7 +734,7 @@ propagate_necessity (struct edge_list *el) else if (arg_bb != ENTRY_BLOCK_PTR && !bitmap_bit_p (visited_control_parents, arg_bb->index)) - mark_control_dependent_edges_necessary (arg_bb, el, true); + mark_control_dependent_edges_necessary (arg_bb, true); } } } @@ -1486,12 +1395,6 @@ tree_dce_init (bool aggressive) if (aggressive) { - int i; - - control_dependence_map = XNEWVEC (bitmap, last_basic_block); - for (i = 0; i < last_basic_block; ++i) - control_dependence_map[i] = BITMAP_ALLOC (NULL); - last_stmt_necessary = sbitmap_alloc (last_basic_block); bitmap_clear (last_stmt_necessary); bb_contains_live_stmts = sbitmap_alloc (last_basic_block); @@ -1512,12 +1415,7 @@ tree_dce_done (bool aggressive) { if (aggressive) { - int i; - - for (i = 0; i < last_basic_block; ++i) - BITMAP_FREE (control_dependence_map[i]); - free (control_dependence_map); - + delete cd; sbitmap_free (visited_control_parents); sbitmap_free (last_stmt_necessary); sbitmap_free (bb_contains_live_stmts); @@ -1546,7 +1444,6 @@ tree_dce_done (bool aggressive) static unsigned int perform_tree_ssa_dce (bool aggressive) { - struct edge_list *el = NULL; bool something_changed = 0; calculate_dominance_info (CDI_DOMINATORS); @@ -1563,11 +1460,8 @@ perform_tree_ssa_dce (bool aggressive) if (aggressive) { /* Compute control dependence. */ - timevar_push (TV_CONTROL_DEPENDENCES); calculate_dominance_info (CDI_POST_DOMINATORS); - el = create_edge_list (); - find_all_control_dependences (el); - timevar_pop (TV_CONTROL_DEPENDENCES); + cd = new control_dependences (create_edge_list ()); visited_control_parents = sbitmap_alloc (last_basic_block); bitmap_clear (visited_control_parents); @@ -1575,7 +1469,7 @@ perform_tree_ssa_dce (bool aggressive) mark_dfs_back_edges (); } - find_obviously_necessary_stmts (el); + find_obviously_necessary_stmts (aggressive); if (aggressive) loop_optimizer_finalize (); @@ -1585,7 +1479,7 @@ perform_tree_ssa_dce (bool aggressive) nr_walks = 0; chain_ovfl = false; visited = BITMAP_ALLOC (NULL); - propagate_necessity (el); + propagate_necessity (aggressive); BITMAP_FREE (visited); something_changed |= eliminate_unnecessary_stmts (); @@ -1609,8 +1503,6 @@ perform_tree_ssa_dce (bool aggressive) tree_dce_done (aggressive); - free_edge_list (el); - if (something_changed) return TODO_update_ssa | TODO_cleanup_cfg; return 0; diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 691e6f905a2..f0cc0ee728b 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "function.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "domwalk.h" #include "tree-pass.h" #include "tree-ssa-propagate.h" @@ -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,69 @@ simplify_stmt_for_jump_threading (gimple stmt, return lookup_avail_expr (stmt, false); } +/* Record into the equivalence tables any equivalences implied by + traversing edge E (which are cached in E->aux). + + Callers are responsible for managing the unwinding markers. */ +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 +1272,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 +1679,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 +1726,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 +1901,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 +1939,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 +1952,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 +1967,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 65787582a28..d0669504325 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "basic-block.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "domwalk.h" #include "flags.h" @@ -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-forwprop.c b/gcc/tree-ssa-forwprop.c index d6623f2e237..3d10c95d7ef 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "basic-block.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "langhooks.h" #include "flags.h" @@ -786,9 +786,10 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, /* Now strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS. ADDR_EXPR will not appear on the LHS. */ - lhs = gimple_assign_lhs (use_stmt); - while (handled_component_p (lhs)) - lhs = TREE_OPERAND (lhs, 0); + tree *lhsp = gimple_assign_lhs_ptr (use_stmt); + while (handled_component_p (*lhsp)) + lhsp = &TREE_OPERAND (*lhsp, 0); + lhs = *lhsp; /* Now see if the LHS node is a MEM_REF using NAME. If so, propagate the ADDR_EXPR into the use of NAME and fold the result. */ @@ -822,11 +823,13 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, /* If the LHS is a plain dereference and the value type is the same as that of the pointed-to type of the address we can put the dereferenced address on the LHS preserving the original alias-type. */ - else if (gimple_assign_lhs (use_stmt) == lhs - && integer_zerop (TREE_OPERAND (lhs, 1)) - && useless_type_conversion_p - (TREE_TYPE (TREE_OPERAND (def_rhs, 0)), - TREE_TYPE (gimple_assign_rhs1 (use_stmt))) + else if (integer_zerop (TREE_OPERAND (lhs, 1)) + && ((gimple_assign_lhs (use_stmt) == lhs + && useless_type_conversion_p + (TREE_TYPE (TREE_OPERAND (def_rhs, 0)), + TREE_TYPE (gimple_assign_rhs1 (use_stmt)))) + || types_compatible_p (TREE_TYPE (lhs), + TREE_TYPE (TREE_OPERAND (def_rhs, 0)))) /* Don't forward anything into clobber stmts if it would result in the lhs no longer being a MEM_REF. */ && (!gimple_clobber_p (use_stmt) @@ -854,7 +857,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (lhs); TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (lhs); new_lhs = unshare_expr (TREE_OPERAND (def_rhs, 0)); - gimple_assign_set_lhs (use_stmt, new_lhs); + *lhsp = new_lhs; TREE_THIS_VOLATILE (new_lhs) = TREE_THIS_VOLATILE (lhs); TREE_SIDE_EFFECTS (new_lhs) = TREE_SIDE_EFFECTS (lhs); *def_rhs_basep = saved; @@ -873,11 +876,12 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, /* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR nodes from the RHS. */ - rhs = gimple_assign_rhs1 (use_stmt); - if (TREE_CODE (rhs) == ADDR_EXPR) - rhs = TREE_OPERAND (rhs, 0); - while (handled_component_p (rhs)) - rhs = TREE_OPERAND (rhs, 0); + tree *rhsp = gimple_assign_rhs1_ptr (use_stmt); + if (TREE_CODE (*rhsp) == ADDR_EXPR) + rhsp = &TREE_OPERAND (*rhsp, 0); + while (handled_component_p (*rhsp)) + rhsp = &TREE_OPERAND (*rhsp, 0); + rhs = *rhsp; /* Now see if the RHS node is a MEM_REF using NAME. If so, propagate the ADDR_EXPR into the use of NAME and fold the result. */ @@ -909,11 +913,13 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, /* If the RHS is a plain dereference and the value type is the same as that of the pointed-to type of the address we can put the dereferenced address on the RHS preserving the original alias-type. */ - else if (gimple_assign_rhs1 (use_stmt) == rhs - && integer_zerop (TREE_OPERAND (rhs, 1)) - && useless_type_conversion_p - (TREE_TYPE (gimple_assign_lhs (use_stmt)), - TREE_TYPE (TREE_OPERAND (def_rhs, 0)))) + else if (integer_zerop (TREE_OPERAND (rhs, 1)) + && ((gimple_assign_rhs1 (use_stmt) == rhs + && useless_type_conversion_p + (TREE_TYPE (gimple_assign_lhs (use_stmt)), + TREE_TYPE (TREE_OPERAND (def_rhs, 0)))) + || types_compatible_p (TREE_TYPE (rhs), + TREE_TYPE (TREE_OPERAND (def_rhs, 0))))) { tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0); tree new_offset, new_base, saved, new_rhs; @@ -937,7 +943,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (rhs); TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (rhs); new_rhs = unshare_expr (TREE_OPERAND (def_rhs, 0)); - gimple_assign_set_rhs1 (use_stmt, new_rhs); + *rhsp = new_rhs; TREE_THIS_VOLATILE (new_rhs) = TREE_THIS_VOLATILE (rhs); TREE_SIDE_EFFECTS (new_rhs) = TREE_SIDE_EFFECTS (rhs); *def_rhs_basep = saved; diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c index 984a7634ef6..c45d42a891d 100644 --- a/gcc/tree-ssa-ifcombine.c +++ b/gcc/tree-ssa-ifcombine.c @@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "basic-block.h" #include "tree-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" /* This pass combines COND_EXPRs to simplify control flow. It diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c index a624d0055c2..c21b2e87441 100644 --- a/gcc/tree-ssa-live.c +++ b/gcc/tree-ssa-live.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "gimple-pretty-print.h" #include "bitmap.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "timevar.h" #include "dumpfile.h" #include "tree-ssa-live.h" diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c index f500761c9c2..0e87770b5b6 100644 --- a/gcc/tree-ssa-loop-ch.c +++ b/gcc/tree-ssa-loop-ch.c @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "tm_p.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "cfgloop.h" #include "tree-inline.h" diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index e467afd1ec6..f0b4a4e6767 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "basic-block.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "domwalk.h" #include "params.h" @@ -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-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c index 101130188d6..d9de8d37dd1 100644 --- a/gcc/tree-ssa-loop-ivcanon.c +++ b/gcc/tree-ssa-loop-ivcanon.c @@ -40,7 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "basic-block.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "tree-pass.h" #include "tree-chrec.h" diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 5fa1804f52c..4915877c188 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -69,7 +69,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "basic-block.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "tree-pass.h" #include "ggc.h" diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c index edc5b7b5fdd..e44458e4a0f 100644 --- a/gcc/tree-ssa-loop-manip.c +++ b/gcc/tree-ssa-loop-manip.c @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "tm_p.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "dumpfile.h" #include "gimple-pretty-print.h" #include "cfgloop.h" diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 49d2e3d0eff..5fbe88deaa9 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "gimple-pretty-print.h" #include "intl.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "dumpfile.h" #include "cfgloop.h" #include "ggc.h" diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c index a3ff32a2155..ca8752eba73 100644 --- a/gcc/tree-ssa-loop-prefetch.c +++ b/gcc/tree-ssa-loop-prefetch.c @@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "basic-block.h" #include "tree-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "tree-pass.h" #include "insn-config.h" diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c index 5c32b564d4d..6ce06c1326c 100644 --- a/gcc/tree-ssa-loop-unswitch.c +++ b/gcc/tree-ssa-loop-unswitch.c @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "tm_p.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "params.h" #include "tree-pass.h" diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c index 8bcfd060e60..cb3eec8dd38 100644 --- a/gcc/tree-ssa-loop.c +++ b/gcc/tree-ssa-loop.c @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "tm_p.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "cfgloop.h" #include "flags.h" @@ -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-math-opts.c b/gcc/tree-ssa-math-opts.c index 9cda5ac331a..ee6aa1d7a0e 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -90,7 +90,7 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "flags.h" #include "tree.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "alloc-pool.h" #include "basic-block.h" diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index 0915080c71c..7e02bd8bfb5 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "function.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-inline.h" #include "timevar.h" #include "dumpfile.h" diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 6b7dd3399d2..c9692c3d53f 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "tm_p.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "langhooks.h" #include "pointer-set.h" @@ -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-phiprop.c b/gcc/tree-ssa-phiprop.c index 1257334f51b..66b220fadd1 100644 --- a/gcc/tree-ssa-phiprop.c +++ b/gcc/tree-ssa-phiprop.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "basic-block.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "langhooks.h" #include "flags.h" diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 24eda8a4844..4a9837cc872 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "gimple-pretty-print.h" #include "tree-inline.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "gimple.h" #include "hash-table.h" #include "tree-iterator.h" @@ -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-propagate.c b/gcc/tree-ssa-propagate.c index afd7233c213..e5dfabcb41c 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -29,7 +29,7 @@ #include "function.h" #include "gimple-pretty-print.h" #include "dumpfile.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-ssa-propagate.h" #include "langhooks.h" #include "vec.h" diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 35b5b153953..6a5b11eca64 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "gimple-pretty-print.h" #include "tree-inline.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "gimple.h" #include "tree-iterator.h" #include "tree-pass.h" @@ -1141,6 +1141,14 @@ zero_one_operation (tree *def, enum tree_code opcode, tree op) while (1); } +/* Returns the UID of STMT if it is non-NULL. Otherwise return 1. */ + +static inline unsigned +get_stmt_uid_with_default (gimple stmt) +{ + return stmt ? gimple_uid (stmt) : 1; +} + /* Builds one statement performing OP1 OPCODE OP2 using TMPVAR for the result. Places the statement after the definition of either OP1 or OP2. Returns the new statement. */ @@ -1165,12 +1173,8 @@ build_and_add_sum (tree type, tree op1, tree op2, enum tree_code opcode) if ((!op1def || gimple_nop_p (op1def)) && (!op2def || gimple_nop_p (op2def))) { - gimple first_stmt; - unsigned uid; gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR)); - first_stmt = gsi_stmt (gsi); - uid = first_stmt ? gimple_uid (first_stmt) : 1; - gimple_set_uid (sum, uid); + gimple_set_uid (sum, get_stmt_uid_with_default (gsi_stmt (gsi))); gsi_insert_before (&gsi, sum, GSI_NEW_STMT); } else if ((!op1def || gimple_nop_p (op1def)) @@ -1180,7 +1184,7 @@ build_and_add_sum (tree type, tree op1, tree op2, enum tree_code opcode) if (gimple_code (op2def) == GIMPLE_PHI) { gsi = gsi_after_labels (gimple_bb (op2def)); - gimple_set_uid (sum, gimple_uid (gsi_stmt (gsi))); + gimple_set_uid (sum, get_stmt_uid_with_default (gsi_stmt (gsi))); gsi_insert_before (&gsi, sum, GSI_NEW_STMT); } else @@ -1207,7 +1211,7 @@ build_and_add_sum (tree type, tree op1, tree op2, enum tree_code opcode) if (gimple_code (op1def) == GIMPLE_PHI) { gsi = gsi_after_labels (gimple_bb (op1def)); - gimple_set_uid (sum, gimple_uid (op1def)); + gimple_set_uid (sum, get_stmt_uid_with_default (gsi_stmt (gsi))); gsi_insert_before (&gsi, sum, GSI_NEW_STMT); } else @@ -1797,7 +1801,14 @@ init_range_entry (struct range_entry *r, tree exp, gimple stmt) switch (code) { case BIT_NOT_EXPR: - if (TREE_CODE (TREE_TYPE (exp)) == BOOLEAN_TYPE) + if (TREE_CODE (TREE_TYPE (exp)) == BOOLEAN_TYPE + /* Ensure the range is either +[-,0], +[0,0], + -[-,0], -[0,0] or +[1,-], +[1,1], -[1,-] or + -[1,1]. If it is e.g. +[-,-] or -[-,-] + or similar expression of unconditional true or + false, it should not be negated. */ + && ((high && integer_zerop (high)) + || (low && integer_onep (low)))) { in_p = !in_p; exp = arg0; @@ -2860,7 +2871,7 @@ not_dominated_by (gimple a, gimple b) basic_block bb_a, bb_b; bb_a = gimple_bb (a); bb_b = gimple_bb (b); - return ((bb_a == bb_b && gimple_uid (a) < gimple_uid (b)) + return ((bb_a == bb_b && gimple_uid (a) < gimple_uid (b)) || (bb_a != bb_b && !dominated_by_p (CDI_DOMINATORS, bb_a, bb_b))); @@ -2874,10 +2885,7 @@ appears_later_in_bb (gimple stmt1, gimple stmt2) { unsigned uid = gimple_uid (stmt1); gimple_stmt_iterator gsi = gsi_for_stmt (stmt1); - gsi_next (&gsi); - if (gsi_end_p (gsi)) - return stmt1; - for (; !gsi_end_p (gsi); gsi_next (&gsi)) + for (gsi_next (&gsi); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple stmt = gsi_stmt (gsi); diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index ef21995e9a5..302207a4796 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "gimple-pretty-print.h" #include "tree-inline.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "gimple.h" #include "dumpfile.h" #include "hash-table.h" diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c index e8540e80534..cc9cff886f7 100644 --- a/gcc/tree-ssa-sink.c +++ b/gcc/tree-ssa-sink.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "gimple-pretty-print.h" #include "tree-inline.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "gimple.h" #include "hashtab.h" #include "tree-iterator.h" diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 7e8a772dd62..21f4f74385a 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -22,7 +22,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "hash-table.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "domwalk.h" #include "alloc-pool.h" @@ -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-structalias.c b/gcc/tree-ssa-structalias.c index c65b5251e00..596872def50 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -28,7 +28,7 @@ #include "flags.h" #include "basic-block.h" #include "tree.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-inline.h" #include "diagnostic-core.h" #include "gimple.h" diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c index fa6de9c3531..4998b7e616c 100644 --- a/gcc/tree-ssa-tail-merge.c +++ b/gcc/tree-ssa-tail-merge.c @@ -194,7 +194,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "flags.h" #include "function.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "bitmap.h" #include "tree-ssa-alias.h" #include "params.h" diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c index 2a2e143de38..ee18cd8f164 100644 --- a/gcc/tree-ssa-ter.c +++ b/gcc/tree-ssa-ter.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "gimple-pretty-print.h" #include "bitmap.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "dumpfile.h" #include "tree-ssa-live.h" #include "flags.h" diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index dddcfce5a3b..47db2804117 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "timevar.h" #include "dumpfile.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-ssa-propagate.h" #include "langhooks.h" #include "params.h" @@ -738,46 +738,81 @@ propagate_threaded_block_debug_into (basic_block dest, basic_block src) fewvars.release (); } -/* TAKEN_EDGE represents the an edge taken as a result of jump threading. - See if we can thread around TAKEN_EDGE->dest as well. If so, return - the edge out of TAKEN_EDGE->dest that we can statically compute will be - traversed. - - We are much more restrictive as to the contents of TAKEN_EDGE->dest - as the path isolation code in tree-ssa-threadupdate.c isn't prepared - to handle copying intermediate blocks on a threaded path. - - Long term a more consistent and structured approach to path isolation - would be a huge help. */ -static edge -thread_around_empty_block (edge taken_edge, - gimple dummy_cond, - bool handle_dominating_asserts, - tree (*simplify) (gimple, gimple), - bitmap visited) +/* See if TAKEN_EDGE->dest is a threadable block with no side effecs (ie, it + need not be duplicated as part of the CFG/SSA updating process). + + If it is threadable, add it to PATH and VISITED and recurse, ultimately + returning TRUE from the toplevel call. Otherwise do nothing and + return false. + + DUMMY_COND, HANDLE_DOMINATING_ASSERTS and SIMPLIFY are used to + try and simplify the condition at the end of TAKEN_EDGE->dest. */ +static bool +thread_around_empty_blocks (edge taken_edge, + gimple dummy_cond, + bool handle_dominating_asserts, + tree (*simplify) (gimple, gimple), + bitmap visited, + vec<edge> *path) { basic_block bb = taken_edge->dest; gimple_stmt_iterator gsi; gimple stmt; tree cond; - /* This block can have no PHI nodes. This is overly conservative. */ + /* The key property of these blocks is that they need not be duplicated + when threading. Thus they can not have visible side effects such + as PHI nodes. */ if (!gsi_end_p (gsi_start_phis (bb))) - return NULL; + return false; /* Skip over DEBUG statements at the start of the block. */ gsi = gsi_start_nondebug_bb (bb); + /* If the block has no statements, but does have a single successor, then + it's just a forwarding block and we can thread through it trivially. + + However, note that just threading through empty blocks with single + successors is not inherently profitable. For the jump thread to + be profitable, we must avoid a runtime conditional. + + By taking the return value from the recursive call, we get the + desired effect of returning TRUE when we found a profitable jump + threading opportunity and FALSE otherwise. + + This is particularly important when this routine is called after + processing a joiner block. Returning TRUE too aggressively in + that case results in pointless duplication of the joiner block. */ if (gsi_end_p (gsi)) - return NULL; + { + if (single_succ_p (bb)) + { + taken_edge = single_succ_edge (bb); + if ((taken_edge->flags & EDGE_DFS_BACK) == 0 + && !bitmap_bit_p (visited, taken_edge->dest->index)) + { + bitmap_set_bit (visited, taken_edge->dest->index); + path->safe_push (taken_edge); + return thread_around_empty_blocks (taken_edge, + dummy_cond, + handle_dominating_asserts, + simplify, + visited, + path); + } + } - /* This block can have no statements other than its control altering - statement. This is overly conservative. */ + /* We have a block with no statements, but multiple successors? */ + return false; + } + + /* The only real statements this block can have are a control + flow altering statement. Anything else stops the thread. */ stmt = gsi_stmt (gsi); if (gimple_code (stmt) != GIMPLE_COND && gimple_code (stmt) != GIMPLE_GOTO && gimple_code (stmt) != GIMPLE_SWITCH) - return NULL; + return false; /* Extract and simplify the condition. */ cond = simplify_control_stmt_condition (taken_edge, stmt, dummy_cond, @@ -788,39 +823,24 @@ thread_around_empty_block (edge taken_edge, path. */ if (cond && is_gimple_min_invariant (cond)) { - edge taken_edge = find_taken_edge (bb, cond); + taken_edge = find_taken_edge (bb, cond); if (bitmap_bit_p (visited, taken_edge->dest->index)) - return NULL; + return false; bitmap_set_bit (visited, taken_edge->dest->index); - return taken_edge; + path->safe_push (taken_edge); + thread_around_empty_blocks (taken_edge, + dummy_cond, + handle_dominating_asserts, + simplify, + visited, + path); + return true; } - return NULL; + 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. @@ -896,51 +916,40 @@ thread_across_edge (gimple dummy_cond, edge taken_edge = find_taken_edge (e->dest, cond); basic_block dest = (taken_edge ? taken_edge->dest : NULL); bitmap visited; - edge e2; - if (dest == e->dest) + /* DEST could be NULL for a computed jump to an absolute + address. */ + if (dest == NULL || dest == e->dest) goto fail; vec<edge> path = vNULL; path.safe_push (e); path.safe_push (taken_edge); - /* DEST could be null for a computed jump to an absolute - address. If DEST is not null, then see if we can thread - through it as well, this helps capture secondary effects - of threading without having to re-run DOM or VRP. */ - if (dest - && ((e->flags & EDGE_DFS_BACK) == 0 - || ! cond_arg_set_in_bb (taken_edge, e->dest))) + /* See if we can thread through DEST as well, this helps capture + secondary effects of threading without having to re-run DOM or + VRP. */ + if ((e->flags & EDGE_DFS_BACK) == 0 + || ! cond_arg_set_in_bb (taken_edge, e->dest)) { /* We don't want to thread back to a block we have already visited. This may be overly conservative. */ visited = BITMAP_ALLOC (NULL); bitmap_set_bit (visited, dest->index); bitmap_set_bit (visited, e->dest->index); - do - { - e2 = thread_around_empty_block (taken_edge, - dummy_cond, - handle_dominating_asserts, - simplify, - visited); - if (e2) - { - taken_edge = e2; - path.safe_push (e2); - } - } - while (e2); + thread_around_empty_blocks (taken_edge, + dummy_cond, + handle_dominating_asserts, + simplify, + visited, + &path); BITMAP_FREE (visited); } remove_temporary_equivalences (stack); - if (taken_edge) - { - propagate_threaded_block_debug_into (taken_edge->dest, e->dest); - register_jump_thread (path, false); - } + propagate_threaded_block_debug_into (path[path.length () - 1]->dest, + e->dest); + register_jump_thread (path, false); path.release (); return; } @@ -958,9 +967,9 @@ thread_across_edge (gimple dummy_cond, This is a stopgap until we have a more structured approach to path isolation. */ { - edge e2, e3, taken_edge; + edge taken_edge; edge_iterator ei; - bool found = false; + bool found; bitmap visited = BITMAP_ALLOC (NULL); /* Look at each successor of E->dest to see if we can thread through it. */ @@ -977,44 +986,22 @@ thread_across_edge (gimple dummy_cond, path.safe_push (e); path.safe_push (taken_edge); found = false; - e3 = taken_edge; - do - { - if ((e->flags & EDGE_DFS_BACK) == 0 - || ! cond_arg_set_in_bb (e3, e->dest)) - e2 = thread_around_empty_block (e3, + if ((e->flags & EDGE_DFS_BACK) == 0 + || ! cond_arg_set_in_bb (path[path.length () - 1], e->dest)) + found = thread_around_empty_blocks (taken_edge, dummy_cond, handle_dominating_asserts, simplify, - visited); - else - e2 = NULL; - - if (e2) - { - path.safe_push (e2); - e3 = e2; - found = true; - } - } - while (e2); + visited, + &path); /* If we were able to thread through a successor of E->dest, then record the jump threading opportunity. */ if (found) { - edge tmp; - /* If there is already an edge from the block to be duplicated - (E2->src) to the final target (E3->dest), then make sure that - the PHI args associated with the edges E2 and E3 are the - same. */ - tmp = find_edge (taken_edge->src, e3->dest); - if (!tmp || phi_args_equal_on_edges (tmp, e3)) - { - propagate_threaded_block_debug_into (e3->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 8e40f6668cf..413112814d6 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "basic-block.h" #include "function.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "dumpfile.h" #include "cfgloop.h" #include "hash-table.h" @@ -640,14 +640,38 @@ thread_block (basic_block bb, bool noloop_only) else e2 = THREAD_TARGET (e); - if (!e2 + if (!e2 || noloop_only) + { /* If NOLOOP_ONLY is true, we only allow threading through the - header of a loop to exit edges. */ - || (noloop_only - && bb == bb->loop_father->header + header of a loop to exit edges. + + There are two cases to consider. The first when BB is the + loop header. We will attempt to thread this elsewhere, so + we can just continue here. */ + + if (bb == bb->loop_father->header && (!loop_exit_edge_p (bb->loop_father, e2) - || THREAD_TARGET2 (e)))) - continue; + || THREAD_TARGET2 (e))) + continue; + + + /* The second occurs when there was loop header buried in a jump + threading path. We do not try and thread this elsewhere, so + just cancel the jump threading request by clearing the AUX + field now. */ + if ((bb->loop_father != e2->src->loop_father + && !loop_exit_edge_p (e2->src->loop_father, e2)) + || (e2->src->loop_father != e2->dest->loop_father + && !loop_exit_edge_p (e2->src->loop_father, e2))) + { + /* Since this case is not handled by our special code + to thread through a loop header, we must explicitly + cancel the threading request here. */ + free (e->aux); + e->aux = NULL; + continue; + } + } if (e->dest == e2->src) update_bb_profile_for_threading (e->dest, EDGE_FREQUENCY (e), @@ -1123,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. @@ -1195,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 837c4eaf066..a13ccf01135 100644 --- a/gcc/tree-ssa-uncprop.c +++ b/gcc/tree-ssa-uncprop.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "basic-block.h" #include "function.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "domwalk.h" #include "tree-pass.h" #include "tree-ssa-propagate.h" @@ -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 6d2d768a243..bd46ddfb18e 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-pretty-print.h" #include "bitmap.h" #include "pointer-set.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "gimple.h" #include "tree-inline.h" #include "hashtab.h" @@ -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 b2e5cf34671..f189d69800a 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-pretty-print.h" #include "bitmap.h" #include "pointer-set.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "gimple.h" #include "tree-inline.h" #include "hashtab.h" @@ -1084,10 +1084,20 @@ static unsigned int execute_init_datastructures (void) { /* Allocate hash tables, arrays and other structures. */ + gcc_assert (!cfun->gimple_df); init_tree_ssa (cfun); return 0; } +/* Gate for IPCP optimization. */ + +static bool +gate_init_datastructures (void) +{ + /* Do nothing for funcions that was produced already in SSA form. */ + return !(cfun->curr_properties & PROP_ssa); +} + namespace { const pass_data pass_data_init_datastructures = @@ -1095,7 +1105,7 @@ const pass_data pass_data_init_datastructures = GIMPLE_PASS, /* type */ "*init_datastructures", /* name */ OPTGROUP_NONE, /* optinfo_flags */ - false, /* has_gate */ + true, /* has_gate */ true, /* has_execute */ TV_NONE, /* tv_id */ PROP_cfg, /* properties_required */ @@ -1113,6 +1123,7 @@ public: {} /* opt_pass methods: */ + bool gate () { return gate_init_datastructures (); } unsigned int execute () { return execute_init_datastructures (); } }; // class pass_init_datastructures @@ -1149,260 +1160,6 @@ delete_tree_ssa (void) redirect_edge_var_map_destroy (); } -/* Return true if the conversion from INNER_TYPE to OUTER_TYPE is a - useless type conversion, otherwise return false. - - This function implicitly defines the middle-end type system. With - the notion of 'a < b' meaning that useless_type_conversion_p (a, b) - holds and 'a > b' meaning that useless_type_conversion_p (b, a) holds, - the following invariants shall be fulfilled: - - 1) useless_type_conversion_p is transitive. - If a < b and b < c then a < c. - - 2) useless_type_conversion_p is not symmetric. - From a < b does not follow a > b. - - 3) Types define the available set of operations applicable to values. - A type conversion is useless if the operations for the target type - is a subset of the operations for the source type. For example - casts to void* are useless, casts from void* are not (void* can't - be dereferenced or offsetted, but copied, hence its set of operations - is a strict subset of that of all other data pointer types). Casts - to const T* are useless (can't be written to), casts from const T* - to T* are not. */ - -bool -useless_type_conversion_p (tree outer_type, tree inner_type) -{ - /* Do the following before stripping toplevel qualifiers. */ - if (POINTER_TYPE_P (inner_type) - && POINTER_TYPE_P (outer_type)) - { - /* Do not lose casts between pointers to different address spaces. */ - if (TYPE_ADDR_SPACE (TREE_TYPE (outer_type)) - != TYPE_ADDR_SPACE (TREE_TYPE (inner_type))) - return false; - } - - /* From now on qualifiers on value types do not matter. */ - inner_type = TYPE_MAIN_VARIANT (inner_type); - outer_type = TYPE_MAIN_VARIANT (outer_type); - - if (inner_type == outer_type) - return true; - - /* If we know the canonical types, compare them. */ - if (TYPE_CANONICAL (inner_type) - && TYPE_CANONICAL (inner_type) == TYPE_CANONICAL (outer_type)) - return true; - - /* Changes in machine mode are never useless conversions unless we - deal with aggregate types in which case we defer to later checks. */ - if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type) - && !AGGREGATE_TYPE_P (inner_type)) - return false; - - /* If both the inner and outer types are integral types, then the - conversion is not necessary if they have the same mode and - signedness and precision, and both or neither are boolean. */ - if (INTEGRAL_TYPE_P (inner_type) - && INTEGRAL_TYPE_P (outer_type)) - { - /* Preserve changes in signedness or precision. */ - if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type) - || TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type)) - return false; - - /* Preserve conversions to/from BOOLEAN_TYPE if types are not - of precision one. */ - if (((TREE_CODE (inner_type) == BOOLEAN_TYPE) - != (TREE_CODE (outer_type) == BOOLEAN_TYPE)) - && TYPE_PRECISION (outer_type) != 1) - return false; - - /* We don't need to preserve changes in the types minimum or - maximum value in general as these do not generate code - unless the types precisions are different. */ - return true; - } - - /* Scalar floating point types with the same mode are compatible. */ - else if (SCALAR_FLOAT_TYPE_P (inner_type) - && SCALAR_FLOAT_TYPE_P (outer_type)) - return true; - - /* Fixed point types with the same mode are compatible. */ - else if (FIXED_POINT_TYPE_P (inner_type) - && FIXED_POINT_TYPE_P (outer_type)) - return true; - - /* We need to take special care recursing to pointed-to types. */ - else if (POINTER_TYPE_P (inner_type) - && POINTER_TYPE_P (outer_type)) - { - /* Do not lose casts to function pointer types. */ - if ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE) - && !(TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (inner_type)) == METHOD_TYPE)) - return false; - - /* We do not care for const qualification of the pointed-to types - as const qualification has no semantic value to the middle-end. */ - - /* Otherwise pointers/references are equivalent. */ - return true; - } - - /* Recurse for complex types. */ - else if (TREE_CODE (inner_type) == COMPLEX_TYPE - && TREE_CODE (outer_type) == COMPLEX_TYPE) - return useless_type_conversion_p (TREE_TYPE (outer_type), - TREE_TYPE (inner_type)); - - /* Recurse for vector types with the same number of subparts. */ - else if (TREE_CODE (inner_type) == VECTOR_TYPE - && TREE_CODE (outer_type) == VECTOR_TYPE - && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type)) - return useless_type_conversion_p (TREE_TYPE (outer_type), - TREE_TYPE (inner_type)); - - else if (TREE_CODE (inner_type) == ARRAY_TYPE - && TREE_CODE (outer_type) == ARRAY_TYPE) - { - /* Preserve string attributes. */ - if (TYPE_STRING_FLAG (inner_type) != TYPE_STRING_FLAG (outer_type)) - return false; - - /* Conversions from array types with unknown extent to - array types with known extent are not useless. */ - if (!TYPE_DOMAIN (inner_type) - && TYPE_DOMAIN (outer_type)) - return false; - - /* Nor are conversions from array types with non-constant size to - array types with constant size or to different size. */ - if (TYPE_SIZE (outer_type) - && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST - && (!TYPE_SIZE (inner_type) - || TREE_CODE (TYPE_SIZE (inner_type)) != INTEGER_CST - || !tree_int_cst_equal (TYPE_SIZE (outer_type), - TYPE_SIZE (inner_type)))) - return false; - - /* Check conversions between arrays with partially known extents. - If the array min/max values are constant they have to match. - Otherwise allow conversions to unknown and variable extents. - In particular this declares conversions that may change the - mode to BLKmode as useless. */ - if (TYPE_DOMAIN (inner_type) - && TYPE_DOMAIN (outer_type) - && TYPE_DOMAIN (inner_type) != TYPE_DOMAIN (outer_type)) - { - tree inner_min = TYPE_MIN_VALUE (TYPE_DOMAIN (inner_type)); - tree outer_min = TYPE_MIN_VALUE (TYPE_DOMAIN (outer_type)); - tree inner_max = TYPE_MAX_VALUE (TYPE_DOMAIN (inner_type)); - tree outer_max = TYPE_MAX_VALUE (TYPE_DOMAIN (outer_type)); - - /* After gimplification a variable min/max value carries no - additional information compared to a NULL value. All that - matters has been lowered to be part of the IL. */ - if (inner_min && TREE_CODE (inner_min) != INTEGER_CST) - inner_min = NULL_TREE; - if (outer_min && TREE_CODE (outer_min) != INTEGER_CST) - outer_min = NULL_TREE; - if (inner_max && TREE_CODE (inner_max) != INTEGER_CST) - inner_max = NULL_TREE; - if (outer_max && TREE_CODE (outer_max) != INTEGER_CST) - outer_max = NULL_TREE; - - /* Conversions NULL / variable <- cst are useless, but not - the other way around. */ - if (outer_min - && (!inner_min - || !tree_int_cst_equal (inner_min, outer_min))) - return false; - if (outer_max - && (!inner_max - || !tree_int_cst_equal (inner_max, outer_max))) - return false; - } - - /* Recurse on the element check. */ - return useless_type_conversion_p (TREE_TYPE (outer_type), - TREE_TYPE (inner_type)); - } - - else if ((TREE_CODE (inner_type) == FUNCTION_TYPE - || TREE_CODE (inner_type) == METHOD_TYPE) - && TREE_CODE (inner_type) == TREE_CODE (outer_type)) - { - tree outer_parm, inner_parm; - - /* If the return types are not compatible bail out. */ - if (!useless_type_conversion_p (TREE_TYPE (outer_type), - TREE_TYPE (inner_type))) - return false; - - /* Method types should belong to a compatible base class. */ - if (TREE_CODE (inner_type) == METHOD_TYPE - && !useless_type_conversion_p (TYPE_METHOD_BASETYPE (outer_type), - TYPE_METHOD_BASETYPE (inner_type))) - return false; - - /* A conversion to an unprototyped argument list is ok. */ - if (!prototype_p (outer_type)) - return true; - - /* If the unqualified argument types are compatible the conversion - is useless. */ - if (TYPE_ARG_TYPES (outer_type) == TYPE_ARG_TYPES (inner_type)) - return true; - - for (outer_parm = TYPE_ARG_TYPES (outer_type), - inner_parm = TYPE_ARG_TYPES (inner_type); - outer_parm && inner_parm; - outer_parm = TREE_CHAIN (outer_parm), - inner_parm = TREE_CHAIN (inner_parm)) - if (!useless_type_conversion_p - (TYPE_MAIN_VARIANT (TREE_VALUE (outer_parm)), - TYPE_MAIN_VARIANT (TREE_VALUE (inner_parm)))) - return false; - - /* If there is a mismatch in the number of arguments the functions - are not compatible. */ - if (outer_parm || inner_parm) - return false; - - /* Defer to the target if necessary. */ - if (TYPE_ATTRIBUTES (inner_type) || TYPE_ATTRIBUTES (outer_type)) - return comp_type_attributes (outer_type, inner_type) != 0; - - return true; - } - - /* For aggregates we rely on TYPE_CANONICAL exclusively and require - explicit conversions for types involving to be structurally - compared types. */ - else if (AGGREGATE_TYPE_P (inner_type) - && TREE_CODE (inner_type) == TREE_CODE (outer_type)) - return false; - - return false; -} - -/* Return true if a conversion from either type of TYPE1 and TYPE2 - to the other is not required. Otherwise return false. */ - -bool -types_compatible_p (tree type1, tree type2) -{ - return (type1 == type2 - || (useless_type_conversion_p (type1, type2) - && useless_type_conversion_p (type2, type1))); -} - /* Return true if EXPR is a useless type conversion, otherwise return false. */ @@ -1436,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. @@ -1544,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 new file mode 100644 index 00000000000..1808b1c447a --- /dev/null +++ b/gcc/tree-ssa.h @@ -0,0 +1,89 @@ +/* Header file for any pass which requires SSA routines. + Copyright (C) 2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_TREE_SSA_H +#define GCC_TREE_SSA_H + +#include "tree-flow.h" +#include "tree-ssanames.h" + +/* Mapping for redirected edges. */ +struct _edge_var_map { + tree result; /* PHI result. */ + tree def; /* PHI arg definition. */ + source_location locus; /* PHI arg location. */ +}; +typedef struct _edge_var_map edge_var_map; + +/* A vector of var maps. */ +typedef vec<edge_var_map, va_heap, vl_embed> edge_var_map_vector; + + +extern void redirect_edge_var_map_add (edge, tree, tree, source_location); +extern void redirect_edge_var_map_clear (edge); +extern void redirect_edge_var_map_dup (edge, edge); +extern edge_var_map_vector *redirect_edge_var_map_vector (edge); +extern void redirect_edge_var_map_destroy (void); +extern edge ssa_redirect_edge (edge, basic_block); +extern void flush_pending_stmts (edge); +extern tree target_for_debug_bind (tree); +extern void insert_debug_temp_for_var_def (gimple_stmt_iterator *, tree); +extern void insert_debug_temps_for_defs (gimple_stmt_iterator *); +extern void reset_debug_uses (gimple); +extern void release_defs_bitset (bitmap toremove); +extern void verify_ssa (bool); +extern void init_tree_ssa (struct function *); +extern void delete_tree_ssa (void); +extern bool tree_ssa_useless_type_conversion (tree); +extern tree tree_ssa_strip_useless_type_conversions (tree); + +/* Call-back function for walk_use_def_chains(). At each reaching + definition, a function with this prototype is called. */ +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 bool ssa_undefined_value_p (tree); +extern void execute_update_addresses_taken (void); + +/* Given an edge_var_map V, return the PHI arg definition. */ + +static inline tree +redirect_edge_var_map_def (edge_var_map *v) +{ + return v->def; +} + +/* Given an edge_var_map V, return the PHI result. */ + +static inline tree +redirect_edge_var_map_result (edge_var_map *v) +{ + return v->result; +} + +/* Given an edge_var_map V, return the PHI arg location. */ + +static inline source_location +redirect_edge_var_map_location (edge_var_map *v) +{ + return v->locus; +} + + +#endif /* GCC_TREE_SSA_H */ diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index a6af3da192c..e64bd656dff 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -22,7 +22,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" /* Rewriting a function into SSA form can create a huge number of SSA_NAMEs, @@ -60,6 +60,9 @@ along with GCC; see the file COPYING3. If not see unsigned int ssa_name_nodes_reused; unsigned int ssa_name_nodes_created; +#define FREE_SSANAMES(fun) (fun)->gimple_df->free_ssanames + + /* Initialize management of SSA_NAMEs to default SIZE. If SIZE is zero use default. */ diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h new file mode 100644 index 00000000000..8cc3efd02b1 --- /dev/null +++ b/gcc/tree-ssanames.h @@ -0,0 +1,119 @@ +/* SSA name expresssons routines + Copyright (C) 2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_TREE_SSANAMES_H +#define GCC_TREE_SSANAMES_H + +/* Aliasing information for SSA_NAMEs representing pointer variables. */ + +struct GTY(()) ptr_info_def +{ + /* The points-to solution. */ + struct pt_solution pt; + + /* Alignment and misalignment of the pointer in bytes. Together + align and misalign specify low known bits of the pointer. + ptr & (align - 1) == misalign. */ + + /* When known, this is the power-of-two byte alignment of the object this + pointer points into. This is usually DECL_ALIGN_UNIT for decls and + MALLOC_ABI_ALIGNMENT for allocated storage. When the alignment is not + known, it is zero. Do not access directly but use functions + get_ptr_info_alignment, set_ptr_info_alignment, + mark_ptr_info_alignment_unknown and similar. */ + unsigned int align; + + /* When alignment is known, the byte offset this pointer differs from the + above alignment. Access only through the same helper functions as align + above. */ + unsigned int misalign; +}; + + +#define SSANAMES(fun) (fun)->gimple_df->ssa_names +#define MODIFIED_NORETURN_CALLS(fun) (fun)->gimple_df->modified_noreturn_calls +#define DEFAULT_DEFS(fun) (fun)->gimple_df->default_defs + +#define num_ssa_names (vec_safe_length (cfun->gimple_df->ssa_names)) +#define ssa_name(i) ((*cfun->gimple_df->ssa_names)[(i)]) + + +extern void init_ssanames (struct function *, int); +extern void fini_ssanames (void); +extern void ssanames_print_statistics (void); +extern tree make_ssa_name_fn (struct function *, tree, gimple); +extern void release_ssa_name (tree); +extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *, + unsigned int *); +extern void mark_ptr_info_alignment_unknown (struct ptr_info_def *); +extern void set_ptr_info_alignment (struct ptr_info_def *, unsigned int, + unsigned int); +extern void adjust_ptr_info_misalignment (struct ptr_info_def *, + unsigned int); +extern struct ptr_info_def *get_ptr_info (tree); + +extern tree copy_ssa_name_fn (struct function *, tree, gimple); +extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *); +extern tree duplicate_ssa_name_fn (struct function *, tree, gimple); +extern void release_defs (gimple); +extern void replace_ssa_name_symbol (tree, tree); + + +/* Return an SSA_NAME node for variable VAR defined in statement STMT + in function cfun. */ + +static inline tree +make_ssa_name (tree var, gimple stmt) +{ + return make_ssa_name_fn (cfun, var, stmt); +} + +/* Return an SSA_NAME node using the template SSA name NAME defined in + statement STMT in function cfun. */ + +static inline tree +copy_ssa_name (tree var, gimple stmt) +{ + return copy_ssa_name_fn (cfun, var, stmt); +} + +/* Creates a duplicate of a SSA name NAME tobe defined by statement STMT + in function cfun. */ + +static inline tree +duplicate_ssa_name (tree var, gimple stmt) +{ + return duplicate_ssa_name_fn (cfun, var, stmt); +} + +/* Return an anonymous SSA_NAME node for type TYPE defined in statement STMT + in function cfun. Arrange so that it uses NAME in dumps. */ + +static inline tree +make_temp_ssa_name (tree type, gimple stmt, const char *name) +{ + tree ssa_name; + gcc_checking_assert (TYPE_P (type)); + ssa_name = make_ssa_name_fn (cfun, type, stmt); + SET_SSA_NAME_VAR_OR_IDENTIFIER (ssa_name, get_identifier (name)); + return ssa_name; +} + + +#endif /* GCC_TREE_SSANAMES_H */ diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c index 2c3519bdc86..8cc0d7ee025 100644 --- a/gcc/tree-stdarg.c +++ b/gcc/tree-stdarg.c @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "gimple-pretty-print.h" #include "target.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "tree-stdarg.h" diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c index 3e62f903001..35f3abd51e7 100644 --- a/gcc/tree-streamer-in.c +++ b/gcc/tree-streamer-in.c @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "diagnostic.h" #include "tree.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-streamer.h" #include "data-streamer.h" #include "streamer-hooks.h" diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index a3a9ab0aded..fa845819f9b 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -31,7 +31,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "flags.h" #include "tree.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-flow-inline.h" #include "tree-ssa-operands.h" #include "tree-pass.h" diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index 96940467181..c91c9da0222 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "basic-block.h" #include "function.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "gimple-pretty-print.h" #include "except.h" #include "tree-pass.h" @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "cfgloop.h" #include "common/common-target.h" +#include "ipa-utils.h" /* The file implements the tail recursion elimination. It is also used to analyze the tail calls in general, passing the results to the rtl level @@ -445,7 +446,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret) /* We found the call, check whether it is suitable. */ tail_recursion = false; func = gimple_call_fndecl (call); - if (func == current_function_decl) + if (func && recursive_call_p (current_function_decl, func)) { tree arg; diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 5ee2815169a..13262194186 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "basic-block.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "dumpfile.h" #include "cfgloop.h" #include "tree-chrec.h" @@ -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-generic.c b/gcc/tree-vect-generic.c index a23ea430d36..00489dbbe22 100644 --- a/gcc/tree-vect-generic.c +++ b/gcc/tree-vect-generic.c @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "tm.h" #include "langhooks.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "gimple.h" #include "tree-iterator.h" #include "tree-pass.h" diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index 5e53a0aab3a..1cd2244d98d 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "basic-block.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "cfgloop.h" #include "diagnostic-core.h" @@ -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 c51b3e2c316..76b64dd4102 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "basic-block.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "cfgloop.h" #include "expr.h" @@ -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_to_hwi (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; } @@ -1384,7 +1409,7 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) return false; op_def_stmt = SSA_NAME_DEF_STMT (phi_op); - if (!op_def_stmt + if (gimple_nop_p (op_def_stmt) || !flow_bb_inside_loop_p (loop, gimple_bb (op_def_stmt)) || !vinfo_for_stmt (op_def_stmt)) 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); } @@ -3133,7 +3170,6 @@ get_initial_def_for_induction (gimple iv_phi) stmt_vec_info stmt_vinfo = vinfo_for_stmt (iv_phi); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo); struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); - tree scalar_type; tree vectype; int nunits; edge pe = loop_preheader_edge (loop); @@ -3185,8 +3221,7 @@ get_initial_def_for_induction (gimple iv_phi) gcc_assert (ok); pe = loop_preheader_edge (iv_loop); - scalar_type = TREE_TYPE (init_expr); - vectype = get_vectype_for_scalar_type (scalar_type); + vectype = get_vectype_for_scalar_type (TREE_TYPE (init_expr)); resvectype = get_vectype_for_scalar_type (TREE_TYPE (PHI_RESULT (iv_phi))); gcc_assert (vectype); nunits = TYPE_VECTOR_SUBPARTS (vectype); @@ -3229,8 +3264,11 @@ get_initial_def_for_induction (gimple iv_phi) /* iv_loop is the loop to be vectorized. Create: vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr) */ - new_var = vect_get_new_vect_var (scalar_type, vect_scalar_var, "var_"); - new_name = force_gimple_operand (init_expr, &stmts, false, new_var); + new_var = vect_get_new_vect_var (TREE_TYPE (vectype), + vect_scalar_var, "var_"); + new_name = force_gimple_operand (fold_convert (TREE_TYPE (vectype), + init_expr), + &stmts, false, new_var); if (stmts) { new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts); @@ -3243,9 +3281,8 @@ get_initial_def_for_induction (gimple iv_phi) for (i = 1; i < nunits; i++) { /* Create: new_name_i = new_name + step_expr */ - enum tree_code code = POINTER_TYPE_P (scalar_type) - ? POINTER_PLUS_EXPR : PLUS_EXPR; - new_name = fold_build2 (code, scalar_type, new_name, step_expr); + new_name = fold_build2 (PLUS_EXPR, TREE_TYPE (new_name), + new_name, step_expr); if (!is_gimple_min_invariant (new_name)) { init_stmt = gimple_build_assign (new_var, new_name); @@ -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_to_uhwi (TYPE_SIZE (vectype)); 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); @@ -5868,5 +5914,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 37cf077e626..e9222232479 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "basic-block.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "expr.h" #include "optabs.h" @@ -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 4217f2be54c..8ed0fc58c59 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "basic-block.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "cfgloop.h" #include "expr.h" @@ -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 9034dd32432..c5dcebdd9ba 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "basic-block.h" #include "gimple-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "expr.h" #include "recog.h" /* FIXME: for insn_data */ @@ -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 @@ -6203,8 +6233,7 @@ get_vectype_for_scalar_type_and_size (tree scalar_type, unsigned size) corresponding to that mode. The theory is that any use that would cause problems with this will disable vectorization anyway. */ else if (!SCALAR_FLOAT_TYPE_P (scalar_type) - && !INTEGRAL_TYPE_P (scalar_type) - && !POINTER_TYPE_P (scalar_type)) + && !INTEGRAL_TYPE_P (scalar_type)) scalar_type = lang_hooks.types.type_for_mode (inner_mode, 1); /* We can't build a vector type of elements with alignment bigger than @@ -6304,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)) @@ -6322,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); } @@ -6330,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; } @@ -6339,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; } @@ -6347,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. @@ -6377,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)) { @@ -6402,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 575cb756245..638c19b72ee 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -62,7 +62,7 @@ along with GCC; see the file COPYING3. If not see #include "ggc.h" #include "tree.h" #include "tree-pretty-print.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cfgloop.h" #include "tree-vectorizer.h" #include "tree-pass.h" @@ -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/tree-vrp.c b/gcc/tree-vrp.c index dfe423228ad..db4d3f8e101 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "tree.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "tree-dump.h" #include "gimple-pretty-print.h" diff --git a/gcc/tree.c b/gcc/tree.c index 856bb6d902a..895c58607b7 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -47,7 +47,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-inline.h" #include "tree-iterator.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "params.h" #include "pointer-set.h" #include "tree-pass.h" @@ -11782,13 +11782,6 @@ types_same_for_odr (tree type1, tree type2) } v1 = DECL_ASSEMBLER_NAME (v1); v2 = DECL_ASSEMBLER_NAME (v2); - /* If we ever start adding random .blah suffixes after - assembler names, we need to compare for match ignoring - these (and update odr_type_hash, too). */ -#ifdef ENABLE_CHECKING - gcc_assert (!strchr (IDENTIFIER_POINTER (v1), '.') - && !strchr (IDENTIFIER_POINTER (v2), '.')); -#endif return (v1 == v2); } diff --git a/gcc/tree.h b/gcc/tree.h index 4b23543a998..8b0b8d36a96 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2496,7 +2496,7 @@ extern vec<tree, va_gc> **decl_debug_args_insert (tree); recognized by optimizers and expanders. Note that it is different from the DECL_IS_BUILTIN accessor. For - instance, user declarated prototypes of C library functions are not + instance, user declared prototypes of C library functions are not DECL_IS_BUILTIN but may be DECL_BUILT_IN. */ #define DECL_BUILT_IN(NODE) (DECL_BUILT_IN_CLASS (NODE) != NOT_BUILT_IN) @@ -2545,11 +2545,6 @@ extern vec<tree, va_gc> **decl_debug_args_insert (tree); #define DECL_FINAL_P(NODE)\ (FUNCTION_DECL_CHECK (NODE)->decl_with_vis.final) -/* FUNCTION_DECL inherits from DECL_NON_COMMON because of the use of the - arguments/result/saved_tree fields by front ends. It was either inherit - FUNCTION_DECL from non_common, or inherit non_common from FUNCTION_DECL, - which seemed a bit strange. */ - /* The source language of the translation-unit. */ #define TRANSLATION_UNIT_LANGUAGE(NODE) \ (TRANSLATION_UNIT_DECL_CHECK (NODE)->translation_unit_decl.language) @@ -4916,10 +4911,6 @@ extern unsigned int tree_decl_map_hash (const void *); #define tree_vec_map_hash tree_decl_map_hash #define tree_vec_map_marked_p tree_map_base_marked_p -/* In tree-ssa.c */ - -tree target_for_debug_bind (tree); - /* In tree-ssa-address.c. */ extern tree tree_mem_ref_addr (tree, tree); extern void copy_ref_info (tree, tree); diff --git a/gcc/tsan.c b/gcc/tsan.c index 943e73037d1..e6180336261 100644 --- a/gcc/tsan.c +++ b/gcc/tsan.c @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "gimple.h" #include "function.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "tree-iterator.h" #include "langhooks.h" diff --git a/gcc/ubsan.c b/gcc/ubsan.c index b8d40d52128..6c6fea80afd 100644 --- a/gcc/ubsan.c +++ b/gcc/ubsan.c @@ -233,10 +233,9 @@ ubsan_source_location (location_t loc) static unsigned short get_ubsan_type_info_for_type (tree type) { - int prec = exact_log2 (TYPE_PRECISION (type)); - if (prec == -1) - error ("unexpected size of type %qT", type); - + gcc_assert (TYPE_SIZE (type) && host_integerp (TYPE_SIZE (type), 1)); + int prec = exact_log2 (tree_low_cst (TYPE_SIZE (type), 1)); + gcc_assert (prec != -1); return (prec << 1) | !TYPE_UNSIGNED (type); } diff --git a/gcc/valtrack.c b/gcc/valtrack.c index 997f68b5089..c61c11704e4 100644 --- a/gcc/valtrack.c +++ b/gcc/valtrack.c @@ -93,9 +93,10 @@ cleanup_auto_inc_dec (rtx src, enum machine_mode mem_mode ATTRIBUTE_UNUSED) gcc_assert (mem_mode != VOIDmode && mem_mode != BLKmode); return gen_rtx_PLUS (GET_MODE (x), cleanup_auto_inc_dec (XEXP (x, 0), mem_mode), - GEN_INT (code == PRE_INC - ? GET_MODE_SIZE (mem_mode) - : -GET_MODE_SIZE (mem_mode))); + gen_int_mode (code == PRE_INC + ? GET_MODE_SIZE (mem_mode) + : -GET_MODE_SIZE (mem_mode), + GET_MODE (x))); case POST_INC: case POST_DEC: diff --git a/gcc/value-prof.c b/gcc/value-prof.c index bda3030e46a..cb6a699131d 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "optabs.h" #include "regs.h" #include "ggc.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-flow-inline.h" #include "diagnostic.h" #include "gimple-pretty-print.h" @@ -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; @@ -1283,7 +1283,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; } @@ -1307,6 +1307,9 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, edge e_cd, e_ci, e_di, e_dj = NULL, e_ij; gimple_stmt_iterator gsi; int lp_nr, dflags; + edge e_eh, e; + edge_iterator ei; + gimple_stmt_iterator psi; cond_bb = gimple_bb (icall_stmt); gsi = gsi_for_stmt (icall_stmt); @@ -1409,24 +1412,21 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, lp_nr = lookup_stmt_eh_lp (icall_stmt); if (lp_nr > 0 && stmt_could_throw_p (dcall_stmt)) { - edge e_eh, e; - edge_iterator ei; - gimple_stmt_iterator psi; - add_stmt_to_eh_lp (dcall_stmt, lp_nr); - FOR_EACH_EDGE (e_eh, ei, icall_bb->succs) - if (e_eh->flags & EDGE_EH) - break; - e = make_edge (dcall_bb, e_eh->dest, EDGE_EH); - for (psi = gsi_start_phis (e_eh->dest); - !gsi_end_p (psi); gsi_next (&psi)) - { - gimple phi = gsi_stmt (psi); - SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), - PHI_ARG_DEF_FROM_EDGE (phi, e_eh)); - } } + FOR_EACH_EDGE (e_eh, ei, icall_bb->succs) + if (e_eh->flags & (EDGE_EH | EDGE_ABNORMAL)) + { + e = make_edge (dcall_bb, e_eh->dest, e_eh->flags); + for (psi = gsi_start_phis (e_eh->dest); + !gsi_end_p (psi); gsi_next (&psi)) + { + gimple phi = gsi_stmt (psi); + SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), + PHI_ARG_DEF_FROM_EDGE (phi, e_eh)); + } + } return dcall_stmt; } diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 086c42d4bb5..2c1aa1a916e 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -104,7 +104,7 @@ #include "regs.h" #include "expr.h" #include "tree-pass.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "cselib.h" #include "target.h" #include "params.h" @@ -1045,9 +1045,10 @@ adjust_mems (rtx loc, const_rtx old_rtx, void *data) case PRE_INC: case PRE_DEC: addr = gen_rtx_PLUS (GET_MODE (loc), XEXP (loc, 0), - GEN_INT (GET_CODE (loc) == PRE_INC - ? GET_MODE_SIZE (amd->mem_mode) - : -GET_MODE_SIZE (amd->mem_mode))); + gen_int_mode (GET_CODE (loc) == PRE_INC + ? GET_MODE_SIZE (amd->mem_mode) + : -GET_MODE_SIZE (amd->mem_mode), + GET_MODE (loc))); case POST_INC: case POST_DEC: if (addr == loc) @@ -1055,10 +1056,11 @@ adjust_mems (rtx loc, const_rtx old_rtx, void *data) gcc_assert (amd->mem_mode != VOIDmode && amd->mem_mode != BLKmode); addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data); tem = gen_rtx_PLUS (GET_MODE (loc), XEXP (loc, 0), - GEN_INT ((GET_CODE (loc) == PRE_INC - || GET_CODE (loc) == POST_INC) - ? GET_MODE_SIZE (amd->mem_mode) - : -GET_MODE_SIZE (amd->mem_mode))); + gen_int_mode ((GET_CODE (loc) == PRE_INC + || GET_CODE (loc) == POST_INC) + ? GET_MODE_SIZE (amd->mem_mode) + : -GET_MODE_SIZE (amd->mem_mode), + GET_MODE (loc))); amd->side_effects = alloc_EXPR_LIST (0, gen_rtx_SET (VOIDmode, XEXP (loc, 0), diff --git a/gcc/varpool.c b/gcc/varpool.c index f558aae0bd1..d5324adb52b 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -33,9 +33,103 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "output.h" #include "gimple.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "flags.h" +/* List of hooks triggered on varpool_node events. */ +struct varpool_node_hook_list { + varpool_node_hook hook; + void *data; + struct varpool_node_hook_list *next; +}; + +/* List of hooks triggered when a node is removed. */ +struct varpool_node_hook_list *first_varpool_node_removal_hook; +/* List of hooks triggered when an variable is inserted. */ +struct varpool_node_hook_list *first_varpool_variable_insertion_hook; + +/* Register HOOK to be called with DATA on each removed node. */ +struct varpool_node_hook_list * +varpool_add_node_removal_hook (varpool_node_hook hook, void *data) +{ + struct varpool_node_hook_list *entry; + struct varpool_node_hook_list **ptr = &first_varpool_node_removal_hook; + + entry = (struct varpool_node_hook_list *) xmalloc (sizeof (*entry)); + entry->hook = hook; + entry->data = data; + entry->next = NULL; + while (*ptr) + ptr = &(*ptr)->next; + *ptr = entry; + return entry; +} + +/* Remove ENTRY from the list of hooks called on removing nodes. */ +void +varpool_remove_node_removal_hook (struct varpool_node_hook_list *entry) +{ + struct varpool_node_hook_list **ptr = &first_varpool_node_removal_hook; + + while (*ptr != entry) + ptr = &(*ptr)->next; + *ptr = entry->next; + free (entry); +} + +/* Call all node removal hooks. */ +static void +varpool_call_node_removal_hooks (struct varpool_node *node) +{ + struct varpool_node_hook_list *entry = first_varpool_node_removal_hook; + while (entry) + { + entry->hook (node, entry->data); + entry = entry->next; + } +} + +/* Register HOOK to be called with DATA on each inserted node. */ +struct varpool_node_hook_list * +varpool_add_variable_insertion_hook (varpool_node_hook hook, void *data) +{ + struct varpool_node_hook_list *entry; + struct varpool_node_hook_list **ptr = &first_varpool_variable_insertion_hook; + + entry = (struct varpool_node_hook_list *) xmalloc (sizeof (*entry)); + entry->hook = hook; + entry->data = data; + entry->next = NULL; + while (*ptr) + ptr = &(*ptr)->next; + *ptr = entry; + return entry; +} + +/* Remove ENTRY from the list of hooks called on inserted nodes. */ +void +varpool_remove_variable_insertion_hook (struct varpool_node_hook_list *entry) +{ + struct varpool_node_hook_list **ptr = &first_varpool_variable_insertion_hook; + + while (*ptr != entry) + ptr = &(*ptr)->next; + *ptr = entry->next; + free (entry); +} + +/* Call all node insertion hooks. */ +void +varpool_call_variable_insertion_hooks (struct varpool_node *node) +{ + struct varpool_node_hook_list *entry = first_varpool_variable_insertion_hook; + while (entry) + { + entry->hook (node, entry->data); + entry = entry->next; + } +} + /* Allocate new callgraph node and insert it into basic data structures. */ struct varpool_node * @@ -65,8 +159,9 @@ varpool_node_for_decl (tree decl) void varpool_remove_node (struct varpool_node *node) { - symtab_unregister_node ((symtab_node)node); tree init; + varpool_call_node_removal_hooks (node); + symtab_unregister_node ((symtab_node)node); /* Because we remove references from external functions before final compilation, we may end up removing useful constructors. @@ -246,6 +341,7 @@ varpool_add_new_variable (tree decl) struct varpool_node *node; varpool_finalize_decl (decl); node = varpool_node_for_decl (decl); + varpool_call_variable_insertion_hooks (node); if (varpool_externally_visible_p (node)) node->symbol.externally_visible = true; } diff --git a/gcc/vtable-verify.c b/gcc/vtable-verify.c index b6c5bc3bce4..1b5cc0c6e98 100644 --- a/gcc/vtable-verify.c +++ b/gcc/vtable-verify.c @@ -138,7 +138,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tree.h" #include "basic-block.h" -#include "tree-flow.h" +#include "tree-ssa.h" #include "tree-pass.h" #include "cfgloop.h" diff --git a/libatomic/ChangeLog b/libatomic/ChangeLog index 794aa7262a3..7a94b7759f5 100644 --- a/libatomic/ChangeLog +++ b/libatomic/ChangeLog @@ -1,3 +1,7 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2013-01-14 Richard Sandiford <rdsandiford@googlemail.com> Update copyright years. diff --git a/libatomic/configure b/libatomic/configure index a9dfa03bb34..6a27ebdad9f 100755 --- a/libatomic/configure +++ b/libatomic/configure @@ -6505,7 +6505,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -6530,7 +6530,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -6549,7 +6552,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -11013,7 +11019,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11016 "configure" +#line 11022 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11119,7 +11125,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11122 "configure" +#line 11128 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog index d6f7205f1d1..39e4086b59e 100644 --- a/libbacktrace/ChangeLog +++ b/libbacktrace/ChangeLog @@ -1,3 +1,7 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2013-07-23 Alexander Monakov <amonakov@ispras.ru> * elf.c (elf_syminfo): Loop over the elf_syminfo_data chain. diff --git a/libbacktrace/configure b/libbacktrace/configure index 46ad9eec9a6..e8ef1ff7c82 100755 --- a/libbacktrace/configure +++ b/libbacktrace/configure @@ -6842,7 +6842,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -6867,7 +6867,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -6886,7 +6889,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -11081,7 +11087,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11084 "configure" +#line 11090 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11187,7 +11193,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11190 "configure" +#line 11196 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 77a949d13e5..6846f51cd03 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,7 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2013-06-25 Alan Modra <amodra@gmail.com> * src/powerpc/ffi.c (ffi_prep_args_SYSV): Move var declaration diff --git a/libffi/configure b/libffi/configure index ce6c8adced7..cb959174d00 100755 --- a/libffi/configure +++ b/libffi/configure @@ -6392,7 +6392,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -6417,7 +6417,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -6436,7 +6439,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -10900,7 +10906,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10903 "configure" +#line 10909 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11006,7 +11012,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11009 "configure" +#line 11015 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 2f415bfc80a..5f503617658 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,36 @@ +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> + + * config/rl78/mulsi3.S: Remove a few unneeded moves and branches. + * config/rl78/vregs.h: New. + * config/rl78/signbit.S: New file. Implements signbit function. + * config/rl78/divmodsi.S: New. + * config/rl78/divmodhi.S: New. + * config/rl78/divmodqi.S: New. + * config/rl78/t-rl78: Build them here... + * config/rl78/lib2div.c: ...but not here. + +2013-09-12 DJ Delorie <dj@redhat.com> + + * config.host (msp*-*-elf): New. + * config/msp430/: New port. + 2013-08-18 Iain Sandoe <iain@codesourcery.com> PR gcov-profile/58127 diff --git a/libgcc/config.host b/libgcc/config.host index 187391e9a2e..1fa3a654131 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -831,6 +831,9 @@ moxie-*-rtems*) # Don't use default. extra_parts= ;; +msp430*-*-elf) + tmake_file="$tm_file t-crtstuff t-fdpbit msp430/t-msp430" + ;; pdp11-*-*) tmake_file="pdp11/t-pdp11 t-fdpbit" ;; 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/msp430/cmpd.c b/libgcc/config/msp430/cmpd.c new file mode 100644 index 00000000000..03e690dff53 --- /dev/null +++ b/libgcc/config/msp430/cmpd.c @@ -0,0 +1,19 @@ +/* Public domain. */ +int +__mspabi_cmpf (float x, float y) +{ + if (x < y) + return -1; + if (x > y) + return 1; + return 0; +} +int +__mspabi_cmpd (double x, double y) +{ + if (x < y) + return -1; + if (x > y) + return 1; + return 0; +} diff --git a/libgcc/config/msp430/cmpsi2.S b/libgcc/config/msp430/cmpsi2.S new file mode 100644 index 00000000000..e8e5b3935a4 --- /dev/null +++ b/libgcc/config/msp430/cmpsi2.S @@ -0,0 +1,98 @@ +; Copyright (C) 2012, 2013 Free Software Foundation, Inc. +; Contributed by Red Hat. +; +; This file is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by the +; Free Software Foundation; either version 3, or (at your option) any +; later version. +; +; This file is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; Under Section 7 of GPL version 3, you are granted additional +; permissions described in the GCC Runtime Library Exception, version +; 3.1, as published by the Free Software Foundation. +; +; You should have received a copy of the GNU General Public License and +; a copy of the GCC Runtime Library Exception along with this program; +; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +; <http://www.gnu.org/licenses/>. + +#ifdef __MSP430X_LARGE__ +#define ret_ RETA +#else +#define ret_ RET +#endif + + .text + + ;; int __cmpsi2 (signed long A, signed long B) + ;; + ;; Performs a signed comparison of A and B. + ;; If A is less than B it returns 0. If A is greater + ;; than B it returns 2. If they are equal it returns 1. + + ;; Note - this code is also used by the __ucmpsi2 routine below. + + .global __cmpsi2 + .type __cmpsi2, @function +__cmpsi2: + ;; A is in r12 (low), r13 (high) + ;; B is in r14 (low), r15 (high) + ;; Result put in r12 + + cmp.w r13, r15 + jeq .L_compare_low + jge .L_less_than +.L_greater_than: + mov.w #2, r12 + ret_ +.L_less_than: + mov.w #0, r12 + ret_ + +.L_compare_low: + cmp.w r12, r14 + jl .L_greater_than + jne .L_less_than + mov.w #1, r12 + ret_ + + .size __cmpsi2, . - __cmpsi2 + + + ;; int __ucmpsi2 (unsigned long A, unsigned long B) + ;; + ;; Performs an unsigned comparison of A and B. + ;; If A is less than B it returns 0. If A is greater + ;; than B it returns 2. If they are equal it returns 1. + +;;; Note - this function branches into the __cmpsi2 code above. + + .global __ucmpsi2 + .type __ucmpsi2, @function +__ucmpsi2: + ;; A is in r12 (low), r13 (high) + ;; B is in r14 (low), r15 (high) + ;; Result put in r12 + + tst r13 + jn .L_top_bit_set_in_A + tst r15 +;;; If the top bit of B is set, but A's is clear we know that A < B. + jn .L_less_than +;;; Neither A nor B has their top bit set so we can use the __cmpsi2 routine. +;;; Note we use Jc rather than BR as that saves two bytes. The TST insn always +;;; sets the C bit. + jc __cmpsi2 + +.L_top_bit_set_in_A: + tst r15 +;;; If both A and B have their top bit set we can use the __cmpsi2 routine. + jn __cmpsi2 +;;; Otherwise A has its top bit set and B does not so A > B. + jc .L_greater_than + + .size __ucmpsi2, . - __ucmpsi2 diff --git a/libgcc/config/msp430/epilogue.S b/libgcc/config/msp430/epilogue.S new file mode 100644 index 00000000000..2e86decafc1 --- /dev/null +++ b/libgcc/config/msp430/epilogue.S @@ -0,0 +1,51 @@ +; Copyright (C) 2012, 2013 Free Software Foundation, Inc. +; Contributed by Red Hat. +; +; This file is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by the +; Free Software Foundation; either version 3, or (at your option) any +; later version. +; +; This file is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; Under Section 7 of GPL version 3, you are granted additional +; permissions described in the GCC Runtime Library Exception, version +; 3.1, as published by the Free Software Foundation. +; +; You should have received a copy of the GNU General Public License and +; a copy of the GCC Runtime Library Exception along with this program; +; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +; <http://www.gnu.org/licenses/>. + + .text + + .global __mspabi_func_epilog_7 + .global __mspabi_func_epilog_6 + .global __mspabi_func_epilog_5 + .global __mspabi_func_epilog_4 + .global __mspabi_func_epilog_3 + .global __mspabi_func_epilog_2 + .global __mspabi_func_epilog_1 + +__mspabi_func_epilog_7: + POP R4 +__mspabi_func_epilog_6: + POP R5 +__mspabi_func_epilog_5: + POP R6 +__mspabi_func_epilog_4: + POP R7 +__mspabi_func_epilog_3: + POP R8 +__mspabi_func_epilog_2: + POP R9 +__mspabi_func_epilog_1: + POP R10 +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif diff --git a/libgcc/config/msp430/floathidf.c b/libgcc/config/msp430/floathidf.c new file mode 100644 index 00000000000..304731d518b --- /dev/null +++ b/libgcc/config/msp430/floathidf.c @@ -0,0 +1,8 @@ +/* Public domain. */ +extern double __floatsidf (long); + +double +__floathidf (int u) +{ + return __floatsidf ((long)u); +} diff --git a/libgcc/config/msp430/floathisf.c b/libgcc/config/msp430/floathisf.c new file mode 100644 index 00000000000..64e5d805d21 --- /dev/null +++ b/libgcc/config/msp430/floathisf.c @@ -0,0 +1,11 @@ +/* Public domain. */ +typedef int HItype __attribute__ ((mode (HI))); +typedef float SFtype __attribute__ ((mode (SF))); + +extern SFtype __floatsisf (unsigned long); + +SFtype +__floathisf (HItype u) +{ + return __floatsisf ((unsigned long)u); +} diff --git a/libgcc/config/msp430/floatunhidf.c b/libgcc/config/msp430/floatunhidf.c new file mode 100644 index 00000000000..f13b5507692 --- /dev/null +++ b/libgcc/config/msp430/floatunhidf.c @@ -0,0 +1,12 @@ +/* Public domain. */ +typedef int HItype __attribute__ ((mode (HI))); +typedef unsigned int UHItype __attribute__ ((mode (HI))); +typedef float DFtype __attribute__ ((mode (DF))); + +extern DFtype __floatunsidf (unsigned long); + +DFtype +__floatunhidf (UHItype u) +{ + return __floatunsidf ((unsigned long)u); +} diff --git a/libgcc/config/msp430/floatunhisf.c b/libgcc/config/msp430/floatunhisf.c new file mode 100644 index 00000000000..ea920bd853a --- /dev/null +++ b/libgcc/config/msp430/floatunhisf.c @@ -0,0 +1,12 @@ +/* Public domain. */ +typedef int HItype __attribute__ ((mode (HI))); +typedef unsigned int UHItype __attribute__ ((mode (HI))); +typedef float SFtype __attribute__ ((mode (SF))); + +extern SFtype __floatunsisf (unsigned long); + +SFtype +__floatunhisf (UHItype u) +{ + return __floatunsisf ((unsigned long)u); +} diff --git a/libgcc/config/msp430/lib2bitcountHI.c b/libgcc/config/msp430/lib2bitcountHI.c new file mode 100644 index 00000000000..f0291ad60b0 --- /dev/null +++ b/libgcc/config/msp430/lib2bitcountHI.c @@ -0,0 +1,50 @@ +/* libgcc routines for MSP430 + Copyright (C) 2012 + Free Software Foundation, Inc. + Contributed by Red Hat. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +typedef int sint32_type __attribute__ ((mode (SI))); +typedef unsigned int uint32_type __attribute__ ((mode (SI))); +typedef int sint16_type __attribute__ ((mode (HI))); +typedef unsigned int uint16_type __attribute__ ((mode (HI))); +typedef int sint08_type __attribute__ ((mode (QI))); +typedef unsigned int uint08_type __attribute__ ((mode (QI))); +typedef int word_type __attribute__ ((mode (__word__))); + +#define C3B(a,b,c) a##b##c +#define C3(a,b,c) C3B(a,b,c) + +/* See the comment by the definition of LIBGCC2_UNITS_PER_WORD in + msp430.h for why we are creating extra versions of some of the + functions defined in libgcc2.c. */ + +#define LIBGCC2_UNITS_PER_WORD 2 + +#define L_clzsi2 +#define L_ctzsi2 +#define L_ffssi2 +#define L_paritysi2 +#define L_popcountsi2 + +#include "libgcc2.c" diff --git a/libgcc/config/msp430/lib2divHI.c b/libgcc/config/msp430/lib2divHI.c new file mode 100644 index 00000000000..e70ed400513 --- /dev/null +++ b/libgcc/config/msp430/lib2divHI.c @@ -0,0 +1,43 @@ +/* HI mode divide routines for libgcc for MSP430 + Copyright (C) 2012 + Free Software Foundation, Inc. + Contributed by Red Hat. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +typedef int sint32_type __attribute__ ((mode (SI))); +typedef unsigned int uint32_type __attribute__ ((mode (SI))); +typedef int sint16_type __attribute__ ((mode (HI))); +typedef unsigned int uint16_type __attribute__ ((mode (HI))); +typedef int sint08_type __attribute__ ((mode (QI))); +typedef unsigned int uint08_type __attribute__ ((mode (QI))); +typedef int word_type __attribute__ ((mode (__word__))); + +#define C3B(a,b,c) a##b##c +#define C3(a,b,c) C3B(a,b,c) + +#define UINT_TYPE uint16_type +#define SINT_TYPE sint16_type +#define BITS_MINUS_1 15 +#define NAME_MODE hi + +#include "msp430-divmod.h" diff --git a/libgcc/config/msp430/lib2divQI.c b/libgcc/config/msp430/lib2divQI.c new file mode 100644 index 00000000000..fe341fc2fdc --- /dev/null +++ b/libgcc/config/msp430/lib2divQI.c @@ -0,0 +1,44 @@ +/* QI mode divide routines for libgcc for MSP430 + Copyright (C) 2012 + Free Software Foundation, Inc. + Contributed by Red Hat. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +typedef int sint32_type __attribute__ ((mode (SI))); +typedef unsigned int uint32_type __attribute__ ((mode (SI))); +typedef int sint16_type __attribute__ ((mode (HI))); +typedef unsigned int uint16_type __attribute__ ((mode (HI))); +typedef int sint08_type __attribute__ ((mode (QI))); +typedef unsigned int uint08_type __attribute__ ((mode (QI))); +typedef int word_type __attribute__ ((mode (__word__))); + +#define C3B(a,b,c) a##b##c +#define C3(a,b,c) C3B(a,b,c) + +#define UINT_TYPE uint08_type +#define SINT_TYPE sint08_type +#define BITS_MINUS_1 7 +#define NAME_MODE qi + +#include "msp430-divmod.h" + diff --git a/libgcc/config/msp430/lib2divSI.c b/libgcc/config/msp430/lib2divSI.c new file mode 100644 index 00000000000..bc1dacaf51f --- /dev/null +++ b/libgcc/config/msp430/lib2divSI.c @@ -0,0 +1,43 @@ +/* SI mode divide routines for libgcc for MSP430 + Copyright (C) 2012 + Free Software Foundation, Inc. + Contributed by Red Hat. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +typedef int sint32_type __attribute__ ((mode (SI))); +typedef unsigned int uint32_type __attribute__ ((mode (SI))); +typedef int sint16_type __attribute__ ((mode (HI))); +typedef unsigned int uint16_type __attribute__ ((mode (HI))); +typedef int sint08_type __attribute__ ((mode (QI))); +typedef unsigned int uint08_type __attribute__ ((mode (QI))); +typedef int word_type __attribute__ ((mode (__word__))); + +#define C3B(a,b,c) a##b##c +#define C3(a,b,c) C3B(a,b,c) + +#define UINT_TYPE uint32_type +#define SINT_TYPE sint32_type +#define BITS_MINUS_1 31 +#define NAME_MODE si + +#include "msp430-divmod.h" diff --git a/libgcc/config/msp430/lib2mul.c b/libgcc/config/msp430/lib2mul.c new file mode 100644 index 00000000000..9f68f4c5e67 --- /dev/null +++ b/libgcc/config/msp430/lib2mul.c @@ -0,0 +1,59 @@ +/* libgcc routines for MSP430 + Copyright (C) 2005, 2009, 2011 + Free Software Foundation, Inc. + Contributed by Red Hat. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +typedef unsigned int uint32_type __attribute__ ((mode (SI))); +typedef unsigned int uint16_type __attribute__ ((mode (HI))); +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) + + +#define UINT_TYPE uint16_type +#define BITS_MINUS_1 15 +#define NAME_MODE hi + +#include "msp430-mul.h" + +#undef UINT_TYPE +#undef BITS_MINUS_1 +#undef NAME_MODE + +#define UINT_TYPE uint08_type +#define BITS_MINUS_1 7 +#define NAME_MODE qi + +#include "msp430-mul.h" + +#undef UINT_TYPE +#undef BITS_MINUS_1 +#undef NAME_MODE + +#define UINT_TYPE uint32_type +#define BITS_MINUS_1 31 +#define NAME_MODE si + +#include "msp430-mul.h" diff --git a/libgcc/config/msp430/lib2shift.c b/libgcc/config/msp430/lib2shift.c new file mode 100644 index 00000000000..53d7eaec682 --- /dev/null +++ b/libgcc/config/msp430/lib2shift.c @@ -0,0 +1,113 @@ +/* Shift functions for the GCC support library for the MSP430 + Copyright (C) 2011 Free Software Foundation, Inc. + Contributed by Red Hat. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +typedef int sint32_type __attribute__ ((mode (SI))); +typedef unsigned int uint32_type __attribute__ ((mode (SI))); +typedef int sint16_type __attribute__ ((mode (HI))); +typedef unsigned int uint16_type __attribute__ ((mode (HI))); + +uint32_type __ashlsi3 (uint32_type in, char bit); +sint32_type __ashrsi3 (sint32_type in, char bit); +int __clrsbhi2 (sint16_type x); +extern int __clrsbsi2 (sint32_type x); + +typedef struct +{ + union + { + uint32_type u; + uint16_type h[2]; + } u; +} dd; + +uint32_type +__ashlsi3 (uint32_type in, char bit) +{ + uint16_type h, l; + dd d; + + if (bit > 32) + return 0; + if (bit < 0) + return in; + + d.u.u = in; + h = d.u.h[1]; + l = d.u.h[0]; + + if (bit > 15) + { + h = l; + l = 0; + bit -= 16; + } + + while (bit) + { + h = (h << 1) | (l >> 15); + l <<= 1; + bit --; + } + + d.u.h[1] = h; + d.u.h[0] = l; + return d.u.u; +} + +sint32_type +__ashrsi3 (sint32_type in, char bit) +{ + sint16_type h; + uint16_type l; + dd d; + + if (bit > 32) + return 0; + if (bit < 0) + return in; + + d.u.u = in; + h = d.u.h[1]; + l = d.u.h[0]; + + while (bit) + { + l = (h << 15) | (l >> 1); + h >>= 1; + bit --; + } + + d.u.h[1] = h; + d.u.h[0] = l; + return d.u.u; +} + +int +__clrsbhi2 (sint16_type x) +{ + if (x == 0) + return 15; + return __clrsbsi2 ((sint32_type) x) - 16; +} diff --git a/libgcc/config/msp430/mpy.c b/libgcc/config/msp430/mpy.c new file mode 100644 index 00000000000..57cffd0ba2a --- /dev/null +++ b/libgcc/config/msp430/mpy.c @@ -0,0 +1,15 @@ +/* Public domain. */ +extern int __mulhi3 (int, int); + +int +__mulhi3 (int x, int y) +{ + volatile int rv = 0; + + while (y > 0) + { + rv += x; + y --; + } + return rv; +} diff --git a/libgcc/config/msp430/msp430-divmod.h b/libgcc/config/msp430/msp430-divmod.h new file mode 100644 index 00000000000..206c7516c3e --- /dev/null +++ b/libgcc/config/msp430/msp430-divmod.h @@ -0,0 +1,118 @@ +/* libgcc routines for MSP430 + Copyright (C) 2005, 2009, 2011 + Free Software Foundation, Inc. + Contributed by Red Hat. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +UINT_TYPE C3(udivmod,NAME_MODE,4) (UINT_TYPE, UINT_TYPE, word_type); +SINT_TYPE C3(__div,NAME_MODE,3) (SINT_TYPE, SINT_TYPE); +SINT_TYPE C3(__mod,NAME_MODE,3) (SINT_TYPE, SINT_TYPE); +UINT_TYPE C3(__udiv,NAME_MODE,3) (UINT_TYPE, UINT_TYPE); +UINT_TYPE C3(__umod,NAME_MODE,3) (UINT_TYPE, UINT_TYPE); + +UINT_TYPE +C3(udivmod,NAME_MODE,4) (UINT_TYPE num, UINT_TYPE den, word_type modwanted) +{ + UINT_TYPE bit = 1; + UINT_TYPE res = 0; + + while (den < num && bit && !(den & (1L << BITS_MINUS_1))) + { + den <<= 1; + bit <<= 1; + } + while (bit) + { + if (num >= den) + { + num -= den; + res |= bit; + } + bit >>= 1; + den >>= 1; + } + if (modwanted) + return num; + return res; +} + +SINT_TYPE +C3(__div,NAME_MODE,3) (SINT_TYPE a, SINT_TYPE b) +{ + word_type neg = 0; + SINT_TYPE res; + + if (a < 0) + { + a = -a; + neg = !neg; + } + + if (b < 0) + { + b = -b; + neg = !neg; + } + + res = C3(udivmod,NAME_MODE,4) (a, b, 0); + + if (neg) + res = -res; + + return res; +} + +SINT_TYPE +C3(__mod,NAME_MODE,3) (SINT_TYPE a, SINT_TYPE b) +{ + word_type neg = 0; + SINT_TYPE res; + + if (a < 0) + { + a = -a; + neg = 1; + } + + if (b < 0) + b = -b; + + res = C3(udivmod,NAME_MODE,4) (a, b, 1); + + if (neg) + res = -res; + + return res; +} + +UINT_TYPE +C3(__udiv,NAME_MODE,3) (UINT_TYPE a, UINT_TYPE b) +{ + return C3(udivmod,NAME_MODE,4) (a, b, 0); +} + +UINT_TYPE +C3(__umod,NAME_MODE,3) (UINT_TYPE a, UINT_TYPE b) +{ + return C3(udivmod,NAME_MODE,4) (a, b, 1); +} diff --git a/libgcc/config/msp430/msp430-mul.h b/libgcc/config/msp430/msp430-mul.h new file mode 100644 index 00000000000..fc2cd6c6ebb --- /dev/null +++ b/libgcc/config/msp430/msp430-mul.h @@ -0,0 +1,43 @@ +/* libgcc routines for RL78 + Copyright (C) 2005, 2009, 2011 + Free Software Foundation, Inc. + Contributed by Red Hat. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +UINT_TYPE C3(__mul,NAME_MODE,3) (UINT_TYPE, UINT_TYPE); +UINT_TYPE +C3(__mul,NAME_MODE,3) (UINT_TYPE a, UINT_TYPE b) +{ + UINT_TYPE rv = 0; + + char bit; + + for (bit=0; b && bit<sizeof(UINT_TYPE)*8; bit++) + { + if (b & 1) + rv += a; + a <<= 1; + b >>= 1; + } + return rv; +} diff --git a/libgcc/config/msp430/slli.S b/libgcc/config/msp430/slli.S new file mode 100644 index 00000000000..48ed15d3ec3 --- /dev/null +++ b/libgcc/config/msp430/slli.S @@ -0,0 +1,108 @@ +; Copyright (C) 2012, 2013 Free Software Foundation, Inc. +; Contributed by Red Hat. +; +; This file is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by the +; Free Software Foundation; either version 3, or (at your option) any +; later version. +; +; This file is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; Under Section 7 of GPL version 3, you are granted additional +; permissions described in the GCC Runtime Library Exception, version +; 3.1, as published by the Free Software Foundation. +; +; You should have received a copy of the GNU General Public License and +; a copy of the GCC Runtime Library Exception along with this program; +; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +; <http://www.gnu.org/licenses/>. + + .text + +/* Logical Left Shift - R12 -> R12 */ + + .macro _slli n + .global __mspabi_slli_\n +__mspabi_slli_\n: + ADD.W R12,R12 + .endm + + _slli 15 + _slli 14 + _slli 13 + _slli 12 + _slli 11 + _slli 10 + _slli 9 + _slli 8 + _slli 7 + _slli 6 + _slli 5 + _slli 4 + _slli 3 + _slli 2 + _slli 1 +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +1: ADD.W #-1,R13 + ADD.W R12,R12 + .global __mspabi_slli +__mspabi_slli: + CMP #0,R13 + JNZ 1b +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +/* Logical Left Shift - R12:R13 -> R12:R13 */ + + .macro _slll n + .global __mspabi_slll_\n +__mspabi_slll_\n: + ADD.W R12,R12 + ADDC.W R13,R13 + .endm + + _slll 15 + _slll 14 + _slll 13 + _slll 12 + _slll 11 + _slll 10 + _slll 9 + _slll 8 + _slll 7 + _slll 6 + _slll 5 + _slll 4 + _slll 3 + _slll 2 + _slll 1 +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +1: ADD.W #-1,R14 + ADD.W R12,R12 + ADDC.W R13,R13 + .global __mspabi_slll +__mspabi_slll: + CMP #0,R14 + JNZ 1b +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + diff --git a/libgcc/config/msp430/srai.S b/libgcc/config/msp430/srai.S new file mode 100644 index 00000000000..8f841229fde --- /dev/null +++ b/libgcc/config/msp430/srai.S @@ -0,0 +1,106 @@ +; Copyright (C) 2012, 2013 Free Software Foundation, Inc. +; Contributed by Red Hat. +; +; This file is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by the +; Free Software Foundation; either version 3, or (at your option) any +; later version. +; +; This file is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; Under Section 7 of GPL version 3, you are granted additional +; permissions described in the GCC Runtime Library Exception, version +; 3.1, as published by the Free Software Foundation. +; +; You should have received a copy of the GNU General Public License and +; a copy of the GCC Runtime Library Exception along with this program; +; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +; <http://www.gnu.org/licenses/>. + + .text + + .macro _srai n + .global __mspabi_srai_\n +__mspabi_srai_\n: + RRA.W R12 + .endm + +/* Logical Right Shift - R12 -> R12 */ + _srai 15 + _srai 14 + _srai 13 + _srai 12 + _srai 11 + _srai 10 + _srai 9 + _srai 8 + _srai 7 + _srai 6 + _srai 5 + _srai 4 + _srai 3 + _srai 2 + _srai 1 +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +1: ADD.W #-1,R13 + RRA.W R12,R12 + .global __mspabi_srai +__mspabi_srai: + CMP #0,R13 + JNZ 1b +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +/* Logical Right Shift - R12:R13 -> R12:R13 */ + + .macro _sral n + .global __mspabi_sral_\n +__mspabi_sral_\n: + RRA.W R13 + RRC.W R12 + .endm + + _sral 15 + _sral 14 + _sral 13 + _sral 12 + _sral 11 + _sral 10 + _sral 9 + _sral 8 + _sral 7 + _sral 6 + _sral 5 + _sral 4 + _sral 3 + _sral 2 + _sral 1 +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +1: ADD.W #-1,R14 + RRA.W R13 + RRC.W R12 + .global __mspabi_sral +__mspabi_sral: + CMP #0,R14 + JNZ 1b +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif diff --git a/libgcc/config/msp430/srli.S b/libgcc/config/msp430/srli.S new file mode 100644 index 00000000000..3ec33df343f --- /dev/null +++ b/libgcc/config/msp430/srli.S @@ -0,0 +1,110 @@ +; Copyright (C) 2012, 2013 Free Software Foundation, Inc. +; Contributed by Red Hat. +; +; This file is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by the +; Free Software Foundation; either version 3, or (at your option) any +; later version. +; +; This file is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; Under Section 7 of GPL version 3, you are granted additional +; permissions described in the GCC Runtime Library Exception, version +; 3.1, as published by the Free Software Foundation. +; +; You should have received a copy of the GNU General Public License and +; a copy of the GCC Runtime Library Exception along with this program; +; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +; <http://www.gnu.org/licenses/>. + + .text + + .macro _srli n + .global __mspabi_srli_\n +__mspabi_srli_\n: + CLRC + RRC.W R12 + .endm + +/* Logical Right Shift - R12 -> R12 */ + _srli 15 + _srli 14 + _srli 13 + _srli 12 + _srli 11 + _srli 10 + _srli 9 + _srli 8 + _srli 7 + _srli 6 + _srli 5 + _srli 4 + _srli 3 + _srli 2 + _srli 1 +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +1: ADD.W #-1,R13 + CLRC + RRC.W R12,R12 + .global __mspabi_srli +__mspabi_srli: + CMP #0,R13 + JNZ 1b +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +/* Logical Right Shift - R12:R13 -> R12:R13 */ + + .macro _srll n + .global __mspabi_srll_\n +__mspabi_srll_\n: + CLRC + RRC.W R13 + RRC.W R12 + .endm + + _srll 15 + _srll 14 + _srll 13 + _srll 12 + _srll 11 + _srll 10 + _srll 9 + _srll 8 + _srll 7 + _srll 6 + _srll 5 + _srll 4 + _srll 3 + _srll 2 + _srll 1 +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif + +1: ADD.W #-1,R14 + CLRC + RRC.W R13 + RRC.W R12 + .global __mspabi_srll +__mspabi_srll: + CMP #0,R14 + JNZ 1b +#ifdef __MSP430X_LARGE__ + RETA +#else + RET +#endif diff --git a/libgcc/config/msp430/t-msp430 b/libgcc/config/msp430/t-msp430 new file mode 100644 index 00000000000..a4d4158e199 --- /dev/null +++ b/libgcc/config/msp430/t-msp430 @@ -0,0 +1,48 @@ +# Makefile fragment for building LIBGCC for the TI MSP430 processor. +# Copyright (C) 2011 Free Software Foundation, Inc. +# Contributed by Red Hat. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published +# by the Free Software Foundation; either version 3, or (at your +# option) any later version. +# +# GCC is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +# the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# Note - we have separate versions of the lib2div<mode> files +# as the functions are quite large and we do not want to pull +# in unneeded division routines. + +LIB2ADD = \ + $(srcdir)/config/msp430/lib2divQI.c \ + $(srcdir)/config/msp430/lib2divHI.c \ + $(srcdir)/config/msp430/lib2divSI.c \ + $(srcdir)/config/msp430/lib2bitcountHI.c \ + $(srcdir)/config/msp430/lib2mul.c \ + $(srcdir)/config/msp430/lib2shift.c \ + $(srcdir)/config/msp430/epilogue.S \ + $(srcdir)/config/msp430/mpy.c \ + $(srcdir)/config/msp430/slli.S \ + $(srcdir)/config/msp430/srai.S \ + $(srcdir)/config/msp430/srli.S \ + $(srcdir)/config/msp430/cmpsi2.S \ + $(srcdir)/config/msp430/floatunhisf.c \ + $(srcdir)/config/msp430/floatunhidf.c \ + $(srcdir)/config/msp430/floathidf.c \ + $(srcdir)/config/msp430/floathisf.c \ + $(srcdir)/config/msp430/cmpd.c + +HOST_LIBGCC2_CFLAGS += -Os -ffunction-sections -fdata-sections + +# Local Variables: +# mode: Makefile +# End: 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/divmodhi.S b/libgcc/config/rl78/divmodhi.S new file mode 100644 index 00000000000..4e0a1237b28 --- /dev/null +++ b/libgcc/config/rl78/divmodhi.S @@ -0,0 +1,337 @@ +/* HImode div/mod functions for the GCC support library for the Renesas RL78 processors. + Copyright (C) 2012,2013 Free Software Foundation, Inc. + Contributed by Red Hat. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef __RL78_G10__ + +#include "vregs.h" + + .macro make_generic which,need_result + + .if \need_result + quot = r8 + num = r10 + den = r12 + bit = r14 + .else + num = r8 + quot = r10 + den = r12 + bit = r14 + .endif + + quotB0 = quot + quotB1 = quot+1 + + numB0 = num + numB1 = num+1 + + denB0 = den + denB1 = den+1 + + bitB0 = bit + bitB1 = bit+1 + +#if 1 +#define bit bc +#define bitB0 c +#define bitB1 b +#endif + +num_lt_den\which: + .if \need_result + movw r8, #0 + .else + movw ax, [sp+8] + movw r8, ax + .endif + ret + + ;; These routines leave DE alone - the signed functions use DE + ;; to store sign information that must remain intact + + .if \need_result + +generic_div: + + .else + +generic_mod: + + .endif + + ;; (quot,rem) = 8[sp] /% 10[sp] + + movw hl, sp + movw ax, [hl+10] ; denH + cmpw ax, [hl+8] ; numH + bh $num_lt_den\which + + ;; (quot,rem) = 16[sp] /% 20[sp] + + ;; copy numerator + movw ax, [hl+8] + movw num, ax + + ;; copy denomonator + movw ax, [hl+10] + movw den, ax + + movw ax, den + cmpw ax, #0 + bnz $den_not_zero\which + movw num, #0 + ret + +den_not_zero\which: + .if \need_result + ;; zero out quot + movw quot, #0 + .endif + + ;; initialize bit to 1 + movw bit, #1 + +; while (den < num && !(den & (1L << BITS_MINUS_1))) + +shift_den_bit\which: + movw ax, den + mov1 cy,a.7 + bc $enter_main_loop\which + cmpw ax, num + bh $enter_main_loop\which + + ;; den <<= 1 +; movw ax, den ; already has it from the cmpw above + shlw ax, 1 + movw den, ax + + ;; bit <<= 1 + .if \need_result +#ifdef bit + shlw bit, 1 +#else + movw ax, bit + shlw ax, 1 + movw bit, ax +#endif + .else + ;; if we don't need to compute the quotent, we don't need an + ;; actual bit *mask*, we just need to keep track of which bit + inc bitB0 + .endif + + br $shift_den_bit\which + +main_loop\which: + + ;; if (num >= den) (cmp den > num) + movw ax, den + cmpw ax, num + bh $next_loop\which + + ;; num -= den + movw ax, num + subw ax, den + movw num, ax + + .if \need_result + ;; res |= bit + mov a, quotB0 + or a, bitB0 + mov quotB0, a + mov a, quotB1 + or a, bitB1 + mov quotB1, a + .endif + +next_loop\which: + + ;; den >>= 1 + movw ax, den + shrw ax, 1 + movw den, ax + + .if \need_result + ;; bit >>= 1 + movw ax, bit + shrw ax, 1 + movw bit, ax + .else + dec bitB0 + .endif + +enter_main_loop\which: + .if \need_result + movw ax, bit + cmpw ax, #0 + .else + cmp0 bitB0 + .endif + bnz $main_loop\which + +main_loop_done\which: + ret + .endm + + make_generic _d 1 + make_generic _m 0 + +;---------------------------------------------------------------------- + + .global ___udivhi3 + .type ___udivhi3,@function +___udivhi3: + ;; r8 = 4[sp] / 6[sp] + call $!generic_div + ret + .size ___udivhi3, . - ___udivhi3 + + + .global ___umodhi3 + .type ___umodhi3,@function +___umodhi3: + ;; r8 = 4[sp] % 6[sp] + call $!generic_mod + ret + .size ___umodhi3, . - ___umodhi3 + +;---------------------------------------------------------------------- + + .macro neg_ax + movw hl, ax + movw ax, #0 + subw ax, [hl] + movw [hl], ax + .endm + + .global ___divhi3 + .type ___divhi3,@function +___divhi3: + ;; r8 = 4[sp] / 6[sp] + movw de, #0 + mov a, [sp+5] + mov1 cy, a.7 + bc $div_signed_num + mov a, [sp+7] + mov1 cy, a.7 + bc $div_signed_den + call $!generic_div + ret + +div_signed_num: + ;; neg [sp+4] + movw ax, sp + addw ax, #4 + neg_ax + mov d, #1 + mov a, [sp+7] + mov1 cy, a.7 + bnc $div_unsigned_den +div_signed_den: + ;; neg [sp+6] + movw ax, sp + addw ax, #6 + neg_ax + mov e, #1 +div_unsigned_den: + call $!generic_div + + mov a, d + cmp0 a + bz $div_skip_restore_num + ;; We have to restore the numerator [sp+4] + movw ax, sp + addw ax, #4 + neg_ax + mov a, d +div_skip_restore_num: + xor a, e + bz $div_no_neg + movw ax, #r8 + neg_ax +div_no_neg: + mov a, e + cmp0 a + bz $div_skip_restore_den + movw ax, sp + addw ax, #6 + neg_ax +div_skip_restore_den: + ret + .size ___divhi3, . - ___divhi3 + + + .global ___modhi3 + .type ___modhi3,@function +___modhi3: + ;; r8 = 4[sp] % 6[sp] + movw de, #0 + mov a, [sp+5] + mov1 cy, a.7 + bc $mod_signed_num + mov a, [sp+7] + mov1 cy, a.7 + bc $mod_signed_den + call $!generic_mod + ret + +mod_signed_num: + ;; neg [sp+4] + movw ax, sp + addw ax, #4 + neg_ax + mov d, #1 + mov a, [sp+7] + mov1 cy, a.7 + bnc $mod_unsigned_den +mod_signed_den: + ;; neg [sp+6] + movw ax, sp + addw ax, #6 + neg_ax +mod_unsigned_den: + call $!generic_mod + + mov a, d + cmp0 a + bz $mod_no_neg + movw ax, #r8 + neg_ax + ;; Also restore numerator + movw ax, sp + addw ax, #4 + neg_ax +mod_no_neg: + mov a, e + cmp0 a + bz $mod_skip_restore_den + movw ax, sp + addw ax, #6 + neg_ax +mod_skip_restore_den: + ret + .size ___modhi3, . - ___modhi3 + +#endif diff --git a/libgcc/config/rl78/divmodqi.S b/libgcc/config/rl78/divmodqi.S new file mode 100644 index 00000000000..62d6f776143 --- /dev/null +++ b/libgcc/config/rl78/divmodqi.S @@ -0,0 +1,310 @@ +/* QImode div/mod functions for the GCC support library for the Renesas RL78 processors. + Copyright (C) 2012,2013 Free Software Foundation, Inc. + Contributed by Red Hat. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef __RL78_G10__ + +#include "vregs.h" + + .macro make_generic which,need_result + + .if \need_result + quot = r8 + num = r10 + den = r12 + bit = r14 + .else + num = r8 + quot = r10 + den = r12 + bit = r14 + .endif + +#if 1 +#define bit b +#define den c +#define bitden bc +#endif + +num_lt_den\which: + .if \need_result + mov r8, #0 + .else + mov a, [hl+4] + mov r8, a + .endif + ret + +num_eq_den\which: + .if \need_result + mov r8, #1 + .else + mov r8, #0 + .endif + ret + +den_is_zero\which: + mov r8, #0xff + ret + + ;; These routines leave DE alone - the signed functions use DE + ;; to store sign information that must remain intact + + .if \need_result + +generic_div: + + .else + +generic_mod: + + .endif + + ;; (quot,rem) = 4[hl] /% 6[hl] + + mov a, [hl+4] ; num + cmp a, [hl+6] ; den + bz $num_eq_den\which + bnh $num_lt_den\which + + ;; copy numerator +; mov a, [hl+4] ; already there from above + mov num, a + + ;; copy denomonator + mov a, [hl+6] + mov den, a + + cmp0 den + bz $den_is_zero\which + +den_not_zero\which: + .if \need_result + ;; zero out quot + mov quot, #0 + .endif + + ;; initialize bit to 1 + mov bit, #1 + +; while (den < num && !(den & (1L << BITS_MINUS_1))) + +shift_den_bit\which: + .macro sdb_one\which + mov a, den + mov1 cy,a.7 + bc $enter_main_loop\which + cmp a, num + bh $enter_main_loop\which + + ;; den <<= 1 +; mov a, den ; already has it from the cmpw above + shl a, 1 + mov den, a + + ;; bit <<= 1 + shl bit, 1 + .endm + + sdb_one\which + sdb_one\which + + br $shift_den_bit\which + +main_loop\which: + + ;; if (num >= den) (cmp den > num) + mov a, den + cmp a, num + bh $next_loop\which + + ;; num -= den + mov a, num + sub a, den + mov num, a + + .if \need_result + ;; res |= bit + mov a, quot + or a, bit + mov quot, a + .endif + +next_loop\which: + + ;; den, bit >>= 1 + movw ax, bitden + shrw ax, 1 + movw bitden, ax + +enter_main_loop\which: + cmp0 bit + bnz $main_loop\which + +main_loop_done\which: + ret + .endm + + make_generic _d 1 + make_generic _m 0 + +;---------------------------------------------------------------------- + + .global ___udivqi3 + .type ___udivqi3,@function +___udivqi3: + ;; r8 = 4[sp] / 6[sp] + movw hl, sp + br $!generic_div + .size ___udivqi3, . - ___udivqi3 + + + .global ___umodqi3 + .type ___umodqi3,@function +___umodqi3: + ;; r8 = 4[sp] % 6[sp] + movw hl, sp + br $!generic_mod + .size ___umodqi3, . - ___umodqi3 + +;---------------------------------------------------------------------- + + .macro neg_ax + movw hl, ax + mov a, #0 + sub a, [hl] + mov [hl], a + .endm + + .global ___divqi3 + .type ___divqi3,@function +___divqi3: + ;; r8 = 4[sp] / 6[sp] + movw hl, sp + movw de, #0 + mov a, [sp+4] + mov1 cy, a.7 + bc $div_signed_num + mov a, [sp+6] + mov1 cy, a.7 + bc $div_signed_den + br $!generic_div + +div_signed_num: + ;; neg [sp+4] + mov a, #0 + sub a, [hl+4] + mov [hl+4], a + mov d, #1 + mov a, [sp+6] + mov1 cy, a.6 + bnc $div_unsigned_den +div_signed_den: + ;; neg [sp+6] + mov a, #0 + sub a, [hl+6] + mov [hl+6], a + mov e, #1 +div_unsigned_den: + call $!generic_div + + mov a, d + cmp0 a + bz $div_skip_restore_num + ;; We have to restore the numerator [sp+4] + movw ax, sp + addw ax, #4 + neg_ax + mov a, d +div_skip_restore_num: + xor a, e + bz $div_no_neg + movw ax, #r8 + neg_ax +div_no_neg: + mov a, e + cmp0 a + bz $div_skip_restore_den + movw ax, sp + addw ax, #6 + neg_ax +div_skip_restore_den: + ret + .size ___divqi3, . - ___divqi3 + + + .global ___modqi3 + .type ___modqi3,@function +___modqi3: + ;; r8 = 4[sp] % 6[sp] + movw hl, sp + movw de, #0 + mov a, [hl+4] + mov1 cy, a.7 + bc $mod_signed_num + mov a, [hl+6] + mov1 cy, a.7 + bc $mod_signed_den + br $!generic_mod + +mod_signed_num: + ;; neg [sp+4] + mov a, #0 + sub a, [hl+4] + mov [hl+4], a + mov d, #1 + mov a, [hl+6] + mov1 cy, a.7 + bnc $mod_unsigned_den +mod_signed_den: + ;; neg [sp+6] + mov a, #0 + sub a, [hl+6] + mov [hl+6], a + mov e, #1 +mod_unsigned_den: + call $!generic_mod + + mov a, d + cmp0 a + bz $mod_no_neg + mov a, #0 + sub a, r8 + mov r8, a + ;; Also restore numerator + movw ax, sp + addw ax, #4 + neg_ax +mod_no_neg: + mov a, e + cmp0 a + bz $mod_skip_restore_den + movw ax, sp + addw ax, #6 + neg_ax +mod_skip_restore_den: + ret + .size ___modqi3, . - ___modqi3 + +#endif diff --git a/libgcc/config/rl78/divmodsi.S b/libgcc/config/rl78/divmodsi.S new file mode 100644 index 00000000000..e22b5ba56e8 --- /dev/null +++ b/libgcc/config/rl78/divmodsi.S @@ -0,0 +1,521 @@ +/* SImode div/mod functions for the GCC support library for the Renesas RL78 processors. + Copyright (C) 2012,2013 Free Software Foundation, Inc. + Contributed by Red Hat. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef __RL78_G10__ + +#include "vregs.h" + + .macro make_generic which,need_result + + .if \need_result + quot = r8 + num = r12 + den = r16 + bit = r20 + .else + num = r8 + quot = r12 + den = r16 + bit = r20 + .endif + + quotH = quot+2 + quotL = quot + quotB0 = quot + quotB1 = quot+1 + quotB2 = quot+2 + quotB3 = quot+3 + + numH = num+2 + numL = num + numB0 = num + numB1 = num+1 + numB2 = num+2 + numB3 = num+3 + +#define denH bc + denL = den + denB0 = den + denB1 = den+1 +#define denB2 c +#define denB3 b + + bitH = bit+2 + bitL = bit + bitB0 = bit + bitB1 = bit+1 + bitB2 = bit+2 + bitB3 = bit+3 + +num_lt_den\which: + .if \need_result + movw r8, #0 + movw r10, #0 + .else + movw ax, [sp+8] + movw r8, ax + movw ax, [sp+10] + movw r10, ax + .endif + ret + +shift_den_bit16\which: + movw ax, denL + movw denH, ax + movw denL, #0 + .if \need_result + movw ax, bitL + movw bitH, ax + movw bitL, #0 + .else + mov a, bit + add a, #16 + mov bit, a + .endif + br $shift_den_bit\which + + ;; These routines leave DE alone - the signed functions use DE + ;; to store sign information that must remain intact + + .if \need_result + +generic_div: + + .else + +generic_mod: + + .endif + + ;; (quot,rem) = 8[sp] /% 12[sp] + + movw hl, sp + movw ax, [hl+14] ; denH + cmpw ax, [hl+10] ; numH + movw ax, [hl+12] ; denL + sknz + cmpw ax, [hl+8] ; numL + bh $num_lt_den\which + + sel rb2 + push ax ; denL +; push bc ; denH + push de ; bitL + push hl ; bitH - stored in BC + sel rb0 + + ;; (quot,rem) = 16[sp] /% 20[sp] + + ;; copy numerator + movw ax, [hl+8] + movw numL, ax + movw ax, [hl+10] + movw numH, ax + + ;; copy denomonator + movw ax, [hl+12] + movw denL, ax + movw ax, [hl+14] + movw denH, ax + + movw ax, denL + or a, denB2 + or a, denB3 ; not x + cmpw ax, #0 + bnz $den_not_zero\which + movw numL, #0 + movw numH, #0 + ret + +den_not_zero\which: + .if \need_result + ;; zero out quot + movw quotL, #0 + movw quotH, #0 + .endif + + ;; initialize bit to 1 + movw bitL, #1 + movw bitH, #0 + +; while (den < num && !(den & (1L << BITS_MINUS_1))) + + .if 1 + ;; see if we can short-circuit a bunch of shifts + movw ax, denH + cmpw ax, #0 + bnz $shift_den_bit\which + movw ax, denL + cmpw ax, numH + bnh $shift_den_bit16\which + .endif + +shift_den_bit\which: + movw ax, denH + mov1 cy,a.7 + bc $enter_main_loop\which + cmpw ax, numH + movw ax, denL ; we re-use this below + sknz + cmpw ax, numL + bh $enter_main_loop\which + + ;; den <<= 1 +; movw ax, denL ; already has it from the cmpw above + shlw ax, 1 + movw denL, ax +; movw ax, denH + rolwc denH, 1 +; movw denH, ax + + ;; bit <<= 1 + .if \need_result + movw ax, bitL + shlw ax, 1 + movw bitL, ax + movw ax, bitH + rolwc ax, 1 + movw bitH, ax + .else + ;; if we don't need to compute the quotent, we don't need an + ;; actual bit *mask*, we just need to keep track of which bit + inc bitB0 + .endif + + br $shift_den_bit\which + + ;; while (bit) +main_loop\which: + + ;; if (num >= den) (cmp den > num) + movw ax, numH + cmpw ax, denH + movw ax, numL + sknz + cmpw ax, denL + skz + bnh $next_loop\which + + ;; num -= den +; movw ax, numL ; already has it from the cmpw above + subw ax, denL + movw numL, ax + movw ax, numH + sknc + decw ax + subw ax, denH + movw numH, ax + + .if \need_result + ;; res |= bit + mov a, quotB0 + or a, bitB0 + mov quotB0, a + mov a, quotB1 + or a, bitB1 + mov quotB1, a + mov a, quotB2 + or a, bitB2 + mov quotB2, a + mov a, quotB3 + or a, bitB3 + mov quotB3, a + .endif + +next_loop\which: + + ;; den >>= 1 + movw ax, denH + shrw ax, 1 + movw denH, ax + mov a, denB1 + rorc a, 1 + mov denB1, a + mov a, denB0 + rorc a, 1 + mov denB0, a + + ;; bit >>= 1 + .if \need_result + movw ax, bitH + shrw ax, 1 + movw bitH, ax + mov a, bitB1 + rorc a, 1 + mov bitB1, a + mov a, bitB0 + rorc a, 1 + mov bitB0, a + .else + dec bitB0 + .endif + +enter_main_loop\which: + .if \need_result + movw ax, bitH + cmpw ax, #0 + bnz $main_loop\which + .else + cmp bitB0, #15 + bh $main_loop\which + .endif + ;; bit is HImode now; check others + movw ax, numH ; numerator + cmpw ax, #0 + bnz $bit_high_set\which + movw ax, denH ; denominator + cmpw ax, #0 + bz $switch_to_himode\which +bit_high_set\which: + .if \need_result + movw ax, bitL + cmpw ax, #0 + .else + cmp0 bitB0 + .endif + bnz $main_loop\which + +switch_to_himode\which: + .if \need_result + movw ax, bitL + cmpw ax, #0 + .else + cmp0 bitB0 + .endif + bz $main_loop_done_himode\which + + ;; From here on in, r22, r14, and r18 are all zero + ;; while (bit) +main_loop_himode\which: + + ;; if (num >= den) (cmp den > num) + movw ax, denL + cmpw ax, numL + bh $next_loop_himode\which + + ;; num -= den + movw ax, numL + subw ax, denL + movw numL, ax + movw ax, numH + sknc + decw ax + subw ax, denH + movw numH, ax + + .if \need_result + ;; res |= bit + mov a, quotB0 + or a, bitB0 + mov quotB0, a + mov a, quotB1 + or a, bitB1 + mov quotB1, a + .endif + +next_loop_himode\which: + + ;; den >>= 1 + movw ax, denL + shrw ax, 1 + movw denL, ax + + .if \need_result + ;; bit >>= 1 + movw ax, bitL + shrw ax, 1 + movw bitL, ax + .else + dec bitB0 + .endif + + .if \need_result + movw ax, bitL + cmpw ax, #0 + .else + cmp0 bitB0 + .endif + bnz $main_loop_himode\which + +main_loop_done_himode\which: + sel rb2 + pop hl ; bitH - stored in BC + pop de ; bitL +; pop bc ; denH + pop ax ; denL + sel rb0 + + ret + .endm + + make_generic _d 1 + make_generic _m 0 + +;---------------------------------------------------------------------- + + .global ___udivsi3 + .type ___udivsi3,@function +___udivsi3: + ;; r8 = 4[sp] / 8[sp] + call $!generic_div + ret + .size ___udivsi3, . - ___udivsi3 + + + .global ___umodsi3 + .type ___umodsi3,@function +___umodsi3: + ;; r8 = 4[sp] % 8[sp] + call $!generic_mod + ret + .size ___umodsi3, . - ___umodsi3 + +;---------------------------------------------------------------------- + + .macro neg_ax + movw hl, ax + movw ax, #0 + subw ax, [hl] + movw [hl], ax + movw ax, #0 + sknc + decw ax + subw ax, [hl+2] + movw [hl+2], ax + .endm + + .global ___divsi3 + .type ___divsi3,@function +___divsi3: + ;; r8 = 4[sp] / 8[sp] + movw de, #0 + mov a, [sp+7] + mov1 cy, a.7 + bc $div_signed_num + mov a, [sp+11] + mov1 cy, a.7 + bc $div_signed_den + call $!generic_div + ret + +div_signed_num: + ;; neg [sp+4] + movw ax, sp + addw ax, #4 + neg_ax + mov d, #1 + mov a, [sp+11] + mov1 cy, a.7 + bnc $div_unsigned_den +div_signed_den: + ;; neg [sp+8] + movw ax, sp + addw ax, #8 + neg_ax + mov e, #1 +div_unsigned_den: + call $!generic_div + + mov a, d + cmp0 a + bz $div_skip_restore_num + ;; We have to restore the numerator [sp+4] + movw ax, sp + addw ax, #4 + neg_ax + mov a, d +div_skip_restore_num: + xor a, e + bz $div_no_neg + movw ax, #r8 + neg_ax +div_no_neg: + mov a, e + cmp0 a + bz $div_skip_restore_den + ;; We have to restore the denominator [sp+8] + movw ax, sp + addw ax, #8 + neg_ax +div_skip_restore_den: + ret + .size ___divsi3, . - ___divsi3 + + + .global ___modsi3 + .type ___modsi3,@function +___modsi3: + ;; r8 = 4[sp] % 8[sp] + movw de, #0 + mov a, [sp+7] + mov1 cy, a.7 + bc $mod_signed_num + mov a, [sp+11] + mov1 cy, a.7 + bc $mod_signed_den + call $!generic_mod + ret + +mod_signed_num: + ;; neg [sp+4] + movw ax, sp + addw ax, #4 + neg_ax + mov d, #1 + mov a, [sp+11] + mov1 cy, a.7 + bnc $mod_unsigned_den +mod_signed_den: + ;; neg [sp+8] + movw ax, sp + addw ax, #8 + neg_ax + mov e, #1 +mod_unsigned_den: + call $!generic_mod + + mov a, d + cmp0 a + bz $mod_no_neg + movw ax, #r8 + neg_ax + ;; We have to restore [sp+4] as well. + movw ax, sp + addw ax, #4 + neg_ax +mod_no_neg: + .if 1 + mov a, e + cmp0 a + bz $mod_skip_restore_den + movw ax, sp + addw ax, #8 + neg_ax +mod_skip_restore_den: + .endif + ret + .size ___modsi3, . - ___modsi3 + +#endif diff --git a/libgcc/config/rl78/lib2div.c b/libgcc/config/rl78/lib2div.c index d9dcf4c2745..b37f55a94ac 100644 --- a/libgcc/config/rl78/lib2div.c +++ b/libgcc/config/rl78/lib2div.c @@ -34,6 +34,8 @@ typedef int word_type __attribute__ ((mode (__word__))); #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 SINT_TYPE sint32_type #define BITS_MINUS_1 31 @@ -65,6 +67,8 @@ typedef int word_type __attribute__ ((mode (__word__))); #include "rl78-divmod.h" +#endif + /* See the comment by the definition of LIBGCC2_UNITS_PER_WORD in m32c.h for why we are creating extra versions of some of the functions defined in libgcc2.c. */ 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 4ce343c1420..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__ ;---------------------------------------------------------------------- @@ -70,10 +47,6 @@ ___mulsi3: ;; B is at [sp+8] ;; result is in R8..R11 - movw ax, sp - addw ax, #4 - movw hl, ax - sel rb2 push ax push bc @@ -83,37 +56,37 @@ ___mulsi3: movw r8, ax movw r16, ax - movw ax, [hl+6] + movw ax, [sp+14] cmpw ax, #0 bz $1f cmpw ax, #0xffff bnz $2f - movw ax, [hl] + movw ax, [sp+8] sel rb1 subw ax, r_0 sel rb0 br $1f 2: movw bc, ax - movw ax, [hl] + movw ax, [sp+8] cmpw ax, #0 skz call !.Lmul_hi 1: - movw ax, [hl+2] + movw ax, [sp+10] cmpw ax, #0 bz $1f cmpw ax, #0xffff bnz $2f - movw ax, [hl+4] + movw ax, [sp+12] sel rb1 subw ax, r_0 sel rb0 br $1f 2: movw bc, ax - movw ax, [hl+4] + movw ax, [sp+12] cmpw ax, #0 skz call !.Lmul_hi @@ -130,9 +103,9 @@ ___mulsi3: ;; op2 is in BC.2 and BC.1 (bc can shlw/rolcw) ;; res is in AX.2 and AX.1 (needs to addw) - movw ax, [hl] + movw ax, [sp+8] movw r10, ax ; BC.1 - movw ax, [hl+4] + movw ax, [sp+12] cmpw ax, r10 bc $.Lmul_hisi_top @@ -191,6 +164,13 @@ ___mulsi3: ;---------------------------------------------------------------------- + .global ___mulhi3 +___mulhi3: + movw r8, #0 + movw ax, [sp+6] + movw bc, ax + movw ax, [sp+4] + ;; R8 += AX * BC .Lmul_hi: cmpw ax, bc @@ -219,17 +199,4 @@ ___mulsi3: .Lmul_hi_done: ret -;---------------------------------------------------------------------- - - .global ___mulhi3 -___mulhi3: - sel rb1 - clrw ax - sel rb0 - movw ax, sp - addw ax, #4 - movw hl, ax - movw ax, [hl+2] - movw bc, ax - movw ax, [hl] - br $.Lmul_hi +#endif diff --git a/libgcc/config/rl78/signbit.S b/libgcc/config/rl78/signbit.S new file mode 100644 index 00000000000..afd0f07eb47 --- /dev/null +++ b/libgcc/config/rl78/signbit.S @@ -0,0 +1,67 @@ +; Copyright (C) 2012,2013 Free Software Foundation, Inc. +; Contributed by Red Hat. +; +; This file is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License as published by the +; Free Software Foundation; either version 3, or (at your option) any +; later version. +; +; This file is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; Under Section 7 of GPL version 3, you are granted additional +; permissions described in the GCC Runtime Library Exception, version +; 3.1, as published by the Free Software Foundation. +; +; You should have received a copy of the GNU General Public License and +; a copy of the GCC Runtime Library Exception along with this program; +; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +; <http://www.gnu.org/licenses/>. + +#include "vregs.h" + +;; int signbitf (float X) +;; int signbit (double X) +;; int signbitl (long double X) +;; +;; `signbit' returns a nonzero value if the value of X has its sign +;; bit set. +;; +;; This is not the same as `x < 0.0', because IEEE 754 floating point +;; allows zero to be signed. The comparison `-0.0 < 0.0' is false, +;; but `signbit (-0.0)' will return a nonzero value. + +;---------------------------------------------------------------------- + + .text + + .global _signbit +_signbit: + .global _signbitf +_signbitf: + ;; X is at [sp+4] + ;; result is in R8..R9 + + movw r8, #0 + mov a, [sp+7] + mov1 cy, a.7 + sknc + movw r8, #1 + ret + .size _signbit, . - _signbit + .size _signbitf, . - _signbitf + + .global _signbitl +_signbitl: + ;; X is at [sp+4] + ;; result is in R8..R9 + + movw r8, #0 + mov a, [sp+11] + mov1 cy, a.7 + sknc + movw r8, #1 + ret + .size _signbitl, . - _signbitl diff --git a/libgcc/config/rl78/t-rl78 b/libgcc/config/rl78/t-rl78 index da7f7bb9bf7..d3260aa23d2 100644 --- a/libgcc/config/rl78/t-rl78 +++ b/libgcc/config/rl78/t-rl78 @@ -25,4 +25,8 @@ LIB2ADD = \ $(srcdir)/config/rl78/lib2shift.c \ $(srcdir)/config/rl78/lshrsi3.S \ $(srcdir)/config/rl78/mulsi3.S \ + $(srcdir)/config/rl78/divmodsi.S \ + $(srcdir)/config/rl78/divmodhi.S \ + $(srcdir)/config/rl78/divmodqi.S \ + $(srcdir)/config/rl78/signbit.S \ $(srcdir)/config/rl78/cmpsi2.S 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 new file mode 100644 index 00000000000..fa488fabcb1 --- /dev/null +++ b/libgcc/config/rl78/vregs.h @@ -0,0 +1,56 @@ + +; 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 + +#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 +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 + +#endif diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 940d41444a5..3a24b14d637 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,7 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2013-07-23 Uros Bizjak <ubizjak@gmail.com> * config/fpu-387.h (get_fpu_rounding_mode): Read rounding mode diff --git a/libgfortran/configure b/libgfortran/configure index 21c23107394..a54d6ac8d24 100755 --- a/libgfortran/configure +++ b/libgfortran/configure @@ -8060,7 +8060,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -8085,7 +8085,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -8104,7 +8107,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -12331,7 +12337,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12334 "configure" +#line 12340 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12437,7 +12443,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12440 "configure" +#line 12446 "configure" #include "confdefs.h" #if HAVE_DLFCN_H 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..7646e5c05e2 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,17 @@ +2013-09-20 Jakub Jelinek <jakub@redhat.com> + + PR testsuite/57605 + * testsuite/lib/libgomp.exp: Add -fdiagnostics-color=never to + ALWAYS_CFLAGS. + +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + +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/configure b/libgomp/configure index 238b1af76c4..983c63df712 100755 --- a/libgomp/configure +++ b/libgomp/configure @@ -6580,7 +6580,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -6605,7 +6605,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -6624,7 +6627,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -11088,7 +11094,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11091 "configure" +#line 11097 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11194,7 +11200,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11197 "configure" +#line 11203 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/libgomp/testsuite/lib/libgomp.exp b/libgomp/testsuite/lib/libgomp.exp index 72daa7e3a3e..d1d8bc8627b 100644 --- a/libgomp/testsuite/lib/libgomp.exp +++ b/libgomp/testsuite/lib/libgomp.exp @@ -167,6 +167,9 @@ proc libgomp_init { args } { # Disable caret lappend ALWAYS_CFLAGS "additional_flags=-fno-diagnostics-show-caret" + # Disable color diagnostics + lappend ALWAYS_CFLAGS "additional_flags=-fdiagnostics-color=never" + # And, gee, turn on OpenMP. lappend ALWAYS_CFLAGS "additional_flags=-fopenmp" } 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/libiberty/ChangeLog b/libiberty/ChangeLog index e4ce0b9a637..89e108a8da6 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,48 @@ +2013-09-10 Paolo Carlini <paolo.carlini@oracle.com> + + PR bootstrap/58386 + Revert: + + 2013-09-10 Gary Benson <gbenson@redhat.com> + + * cp-demangle.c: Include hashtab.h. + (struct d_print_info): New field saved_scopes. + (d_print_init): Initialize the above. + (d_print_free): New function. + (cplus_demangle_print_callback): Call the above. + (struct d_saved_scope): New structure. + (d_store_scope): New function. + (d_free_scope) Likewise. + (d_restore_scope) Likewise. + (d_hash_saved_scope) Likewise. + (d_equal_saved_scope) Likewise. + (d_print_comp): New variable saved_scope. + [DEMANGLE_COMPONENT_REFERENCE, + DEMANGLE_COMPONENT_RVALUE_REFERENCE]: Capture scope the first + time the component is traversed, and use the captured scope for + subsequent traversals. + * testsuite/demangle-expected: Add regression test. + +2013-09-10 Gary Benson <gbenson@redhat.com> + + * cp-demangle.c: Include hashtab.h. + (struct d_print_info): New field saved_scopes. + (d_print_init): Initialize the above. + (d_print_free): New function. + (cplus_demangle_print_callback): Call the above. + (struct d_saved_scope): New structure. + (d_store_scope): New function. + (d_free_scope) Likewise. + (d_restore_scope) Likewise. + (d_hash_saved_scope) Likewise. + (d_equal_saved_scope) Likewise. + (d_print_comp): New variable saved_scope. + [DEMANGLE_COMPONENT_REFERENCE, + DEMANGLE_COMPONENT_RVALUE_REFERENCE]: Capture scope the first + time the component is traversed, and use the captured scope for + subsequent traversals. + * testsuite/demangle-expected: Add regression test. + 2013-08-20 Alan Modra <amodra@gmail.com> * floatformat.c (floatformat_ibm_long_double): Rename to.. diff --git a/libitm/ChangeLog b/libitm/ChangeLog index adf42308ef3..28f8a227f20 100644 --- a/libitm/ChangeLog +++ b/libitm/ChangeLog @@ -1,3 +1,7 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2013-08-30 Torvald Riegel <triegel@redhat.com> * config/posix/rwlock.cc: Fix initialization order. diff --git a/libitm/configure b/libitm/configure index 21361b031ad..031c19ce337 100644 --- a/libitm/configure +++ b/libitm/configure @@ -7270,7 +7270,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -7295,7 +7295,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -7314,7 +7317,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -11779,7 +11785,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11782 "configure" +#line 11788 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11885,7 +11891,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11888 "configure" +#line 11894 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 23a6accf5df..cda2ed09fd9 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,7 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2013-06-20 Roland Lutz <rlutz@hedmen.org> * contrib/aot-compile.in: Fix typo in option list. diff --git a/libjava/classpath/ChangeLog b/libjava/classpath/ChangeLog index 49815367045..4d9f1a6e49c 100644 --- a/libjava/classpath/ChangeLog +++ b/libjava/classpath/ChangeLog @@ -1,3 +1,7 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2013-05-22 Mark Mitchell <mark@codesourcery.com> Sandra Loosemore <sandra@codesourcery.com> diff --git a/libjava/classpath/configure b/libjava/classpath/configure index 6def45cf7e8..bcb5bff1c18 100755 --- a/libjava/classpath/configure +++ b/libjava/classpath/configure @@ -7630,7 +7630,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -7655,7 +7655,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -7674,7 +7677,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -11873,7 +11879,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11876 "configure" +#line 11882 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11979,7 +11985,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11982 "configure" +#line 11988 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -25353,7 +25359,7 @@ else JAVA_TEST=Object.java CLASS_TEST=Object.class cat << \EOF > $JAVA_TEST -/* #line 25356 "configure" */ +/* #line 25362 "configure" */ package java.lang; public class Object @@ -25446,7 +25452,7 @@ EOF if uudecode$EXEEXT Test.uue; then ac_cv_prog_uudecode_base64=yes else - echo "configure: 25449: uudecode had trouble decoding base 64 file 'Test.uue'" >&5 + echo "configure: 25455: uudecode had trouble decoding base 64 file 'Test.uue'" >&5 echo "configure: failed file was:" >&5 cat Test.uue >&5 ac_cv_prog_uudecode_base64=no @@ -25474,7 +25480,7 @@ JAVA_TEST=Test.java CLASS_TEST=Test.class TEST=Test cat << \EOF > $JAVA_TEST -/* [#]line 25477 "configure" */ +/* [#]line 25483 "configure" */ public class Test { public static void main (String args[]) { System.exit (0); @@ -25682,7 +25688,7 @@ if test "x${use_glibj_zip}" = xfalse || \ JAVA_TEST=Test.java CLASS_TEST=Test.class cat << \EOF > $JAVA_TEST - /* #line 25685 "configure" */ + /* #line 25691 "configure" */ public class Test { public static void main(String args) diff --git a/libjava/configure b/libjava/configure index 6eb11bd2b96..55443608c0c 100755 --- a/libjava/configure +++ b/libjava/configure @@ -8842,7 +8842,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -8867,7 +8867,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -8886,7 +8889,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -13382,7 +13388,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 13385 "configure" +#line 13391 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -13488,7 +13494,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 13491 "configure" +#line 13497 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -19483,7 +19489,7 @@ if test "${enable_sjlj_exceptions+set}" = set; then : enableval=$enable_sjlj_exceptions; : else cat > conftest.$ac_ext << EOF -#line 19486 "configure" +#line 19492 "configure" struct S { ~S(); }; void bar(); void foo() diff --git a/libjava/libltdl/ChangeLog b/libjava/libltdl/ChangeLog index df5ce43462d..c00e5192e3e 100644 --- a/libjava/libltdl/ChangeLog +++ b/libjava/libltdl/ChangeLog @@ -1,3 +1,9 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * acinclude.m4 (_LT_ENABLE_LOCK <ld -m flags>): Remove non-canonical + ppc host match. Support little-endian powerpc linux hosts. + * configure: Regenerate. + 2011-11-21 Andreas Tobler <andreast@fgznet.ch> * acinclude.m4: Additional FreeBSD 10 fixes. diff --git a/libjava/libltdl/acinclude.m4 b/libjava/libltdl/acinclude.m4 index d77a1a3990d..f08911950fd 100644 --- a/libjava/libltdl/acinclude.m4 +++ b/libjava/libltdl/acinclude.m4 @@ -519,7 +519,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) +x86_64-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then @@ -529,7 +529,10 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -545,7 +548,10 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*) diff --git a/libjava/libltdl/configure b/libjava/libltdl/configure index 35b89dc5551..146ca43299e 100755 --- a/libjava/libltdl/configure +++ b/libjava/libltdl/configure @@ -4806,7 +4806,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) +x86_64-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 @@ -4820,7 +4820,10 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -4836,7 +4839,10 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*) @@ -6456,11 +6462,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6459: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6465: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6463: \$? = $ac_status" >&5 + echo "$as_me:6469: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -6718,11 +6724,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6721: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6727: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6725: \$? = $ac_status" >&5 + echo "$as_me:6731: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -6780,11 +6786,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6783: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6789: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:6787: \$? = $ac_status" >&5 + echo "$as_me:6793: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -8099,7 +8105,7 @@ linux*) libsuff= case "$host_cpu" in x86_64*|s390x*|powerpc64*) - echo '#line 8102 "configure"' > conftest.$ac_ext + echo '#line 8108 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -8652,7 +8658,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<EOF -#line 8655 "configure" +#line 8661 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -8750,7 +8756,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<EOF -#line 8753 "configure" +#line 8759 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10591,7 +10597,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<EOF -#line 10594 "configure" +#line 10600 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/libmudflap/ChangeLog b/libmudflap/ChangeLog index 6e0d65c2fb7..333029fc9df 100644 --- a/libmudflap/ChangeLog +++ b/libmudflap/ChangeLog @@ -1,3 +1,13 @@ +2013-09-20 Jakub Jelinek <jakub@redhat.com> + + PR testsuite/57605 + * testsuite/lib/libmudflap.exp (libmudflap-init): Append + -fdiagnostics-color=never to cxxflags. + +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2013-03-14 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/53265 diff --git a/libmudflap/configure b/libmudflap/configure index b3a0178a514..1e91dbb3a6a 100755 --- a/libmudflap/configure +++ b/libmudflap/configure @@ -6377,7 +6377,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -6402,7 +6402,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -6421,7 +6424,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -10615,7 +10621,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10618 "configure" +#line 10624 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10721,7 +10727,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10724 "configure" +#line 10730 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/libmudflap/testsuite/lib/libmudflap.exp b/libmudflap/testsuite/lib/libmudflap.exp index 48166e1d0f3..9927ba1745a 100644 --- a/libmudflap/testsuite/lib/libmudflap.exp +++ b/libmudflap/testsuite/lib/libmudflap.exp @@ -85,7 +85,7 @@ proc libmudflap-init { language } { append ld_library_path ":${blddir}/.libs" set libs "-L${blddir}/.libs" - set cxxflags "-ggdb3 -DDEBUG_ASSERT" + set cxxflags "-ggdb3 -DDEBUG_ASSERT -fdiagnostics-color=never" set includes "-I${srcdir} -I${srcdir}/.. -I.." if {$language == "c++"} { diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog index c2e1a2887b5..85b864abe01 100644 --- a/libobjc/ChangeLog +++ b/libobjc/ChangeLog @@ -1,3 +1,7 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2013-07-21 Ondřej BÃÂlka <neleai@seznam.cz> * class.c: Fix typos. diff --git a/libobjc/configure b/libobjc/configure index a220b155893..dd39d7ec8b4 100755 --- a/libobjc/configure +++ b/libobjc/configure @@ -6056,7 +6056,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -6081,7 +6081,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -6100,7 +6103,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -10595,7 +10601,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10598 "configure" +#line 10604 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10701,7 +10707,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10704 "configure" +#line 10710 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11472,7 +11478,7 @@ if test "${enable_sjlj_exceptions+set}" = set; then : enableval=$enable_sjlj_exceptions; : else cat > conftest.$ac_ext << EOF -#line 11475 "configure" +#line 11481 "configure" @interface Frob @end @implementation Frob diff --git a/libquadmath/ChangeLog b/libquadmath/ChangeLog index f04c70180b5..d3c17f67d5d 100644 --- a/libquadmath/ChangeLog +++ b/libquadmath/ChangeLog @@ -1,3 +1,7 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2013-03-06 Shakthi Kannan <shakthimaan@gmail.com> PR libquadmath/55473 diff --git a/libquadmath/configure b/libquadmath/configure index 0ea6e07455d..907e0cf05cd 100755 --- a/libquadmath/configure +++ b/libquadmath/configure @@ -6248,7 +6248,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -6273,7 +6273,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -6292,7 +6295,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -10521,7 +10527,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10524 "configure" +#line 10530 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10627,7 +10633,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10630 "configure" +#line 10636 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog index f5162c90250..e8e57f94be3 100644 --- a/libsanitizer/ChangeLog +++ b/libsanitizer/ChangeLog @@ -1,3 +1,7 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2013-09-01 Iain Sandoe <iain@codesourcery.com> * ubsan/Makefile.am (libubsan_la_LIBADD): Revise to omit diff --git a/libsanitizer/configure b/libsanitizer/configure index 2cad869f458..5d393ca42f3 100755 --- a/libsanitizer/configure +++ b/libsanitizer/configure @@ -6604,7 +6604,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -6629,7 +6629,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -6648,7 +6651,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -11111,7 +11117,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11114 "configure" +#line 11120 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11217,7 +11223,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11220 "configure" +#line 11226 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/libssp/ChangeLog b/libssp/ChangeLog index eb020d9dcf8..c127fce7f3f 100644 --- a/libssp/ChangeLog +++ b/libssp/ChangeLog @@ -1,3 +1,7 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2013-02-06 Richard Sandiford <rdsandiford@googlemail.com> Revert previous patch. diff --git a/libssp/configure b/libssp/configure index 5e162088767..b26c0b33524 100755 --- a/libssp/configure +++ b/libssp/configure @@ -6385,7 +6385,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -6410,7 +6410,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -6429,7 +6432,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -10658,7 +10664,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10661 "configure" +#line 10667 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10764,7 +10770,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10767 "configure" +#line 10773 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 50d65dd3843..7f8cae5fb99 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,8 +1,311 @@ +2013-09-20 Jakub Jelinek <jakub@redhat.com> + + PR testsuite/57605 + * testsuite/lib/libstdc++.exp (libstdc++_init): Prepend + -fdiagnostics-color=never to cxxflags. + +2013-09-20 Marc Glisse <marc.glisse@inria.fr> + + PR libstdc++/58338 + * include/bits/allocator.h (__alloc_swap::_S_do_it, + __shrink_to_fit_aux::_S_do_it): Mark as noexcept. + * include/bits/basic_string.h (basic_string::_Rep) [_S_empty_rep, + _M_is_leaked, _M_is_shared, _M_set_leaked, _M_set_sharable, + _M_set_length_and_sharable, _M_dispose]: Likewise. + (basic_string::_Alloc_hider::_Alloc_hider): Likewise. + (basic_string) [_M_data, _M_rep, _M_ibegin, _M_iend, _M_limit, + _M_disjunct, _M_copy, _M_move, _M_assign, _S_copy_chars, _S_compare, + _S_empty_rep, shrink_to_fit, operator[] const, front const, back const]: + Likewise. + [clear]: Link to PR 56166. + [swap]: Link to PR 58265. + * include/bits/stl_deque.h (_Deque_iterator) [_S_buffer_size, + _Deque_iterator, _M_const_cast, operator*, operator->, operator++, + operator--, operator+=, operator+, operator-=, operator-, operator[], + _M_set_node]: Mark as noexcept. + (operator==(const _Deque_iterator&, const _Deque_iterator&), + operator!=(const _Deque_iterator&, const _Deque_iterator&), + operator<(const _Deque_iterator&, const _Deque_iterator&), + operator>(const _Deque_iterator&, const _Deque_iterator&), + operator<=(const _Deque_iterator&, const _Deque_iterator&), + operator>=(const _Deque_iterator&, const _Deque_iterator&), + operator-(const _Deque_iterator&, const _Deque_iterator&), + operator+(ptrdiff_t, const _Deque_iterator&)): Likewise. + (_Deque_base) [_Deque_base(const allocator_type&)]: Add missing call to + _M_initialize_map. + [~_Deque_base, _M_deallocate_node, _M_deallocate_map, _M_destroy_nodes]: + Mark as noexcept. + (_Deque_base::_Deque_impl) [_Deque_impl(const _Tp_alloc_type&), + _Deque_impl(_Tp_alloc_type&&)]: Likewise. + (deque) [_S_buffer_size, operator=(deque&&), shrink_to_fit, operator[], + front, back, pop_front, pop_back, swap]: Likewise. + [deque(), deque(const allocator_type&)]: Merge. + * include/debug/deque (deque) [operator=(deque&&), shrink_to_fit, + operator[], front, back, pop_front, pop_back, swap]: Mark as noexcept. + * include/profile/deque (deque) [operator=(deque&&), operator[], front, + back, pop_front, pop_back, swap]: Likewise. + * testsuite/23_containers/deque/requirements/dr438/assign_neg.cc: + Adjust line number. + * testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc: + Likewise. + * testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc: + Likewise. + * testsuite/23_containers/deque/requirements/dr438/insert_neg.cc: + Likewise. + +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + +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<>): + Change regex_executor caller. Now use their return value instead + of checking __m[0].matched to find out if it's successful. + (regex_search<>): Move the search logic to regex_executor. + * include/bits/regex_automaton.h: Add some new _Opcode. Refactor + _NFA::_M_insert_*. + * include/bits/regex_automaton.tcc: Add DEBUG dump for new + _Opcode. Refactor _NFA::_M_insert_*. + * include/bits/regex_compiler.h (_Compiler<>::_M_get_nfa): + Use make_shared instead of construct by hand. + * include/bits/regex_compiler.tcc: Implement _Compiler<>::_M_assertion. + * include/bits/regex_constants.h: Fix indentation and line breaking. + * include/bits/regex_executor.h: Add _ResultsEntry to support + greedy/ungreedy mode. Move regex_search logic here. + * include/bits/regex_executor.tcc: Implement assertions and + greedy/ungreedy matching. + * include/bits/regex_scanner.h: Add a new token _S_token_ungreedy. + * include/bits/regex_scanner.tcc: Parse a new token _S_token_ungreedy. + * testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc: New. + * testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc: New. + * testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc: + Fix comment. + +2013-09-13 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/58415 + * include/ext/sso_string_base.h (__sso_string_base<>:: + __sso_string_base(__sso_string_base&&)): Fix thinkos about + _M_length vs _M_set_length. + * testsuite/ext/vstring/cons/58415-1.cc: New. + * testsuite/ext/vstring/cons/58415-2.cc: Likewise. + +2013-09-12 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/58403 + * include/bits/stl_iterator.h (__normal_iterator<>::operator[], + operator+=, operator+, operator-=, operator-): Take the argument + by value. + * testsuite/24_iterators/normal_iterator/58403.cc: New. + +2013-09-11 Mitsuru Kariya <kariya_mitsuru@hotmail.com> + Chris Jefferson <chris@bubblescope.net> + + PR libstdc++/58358 + * include/bits/stl_algo.h (search_n): Fix to guarantee a number + of comparisons <= number of elements in the range. + * testsuite/25_algorithms/search_n/58358.cc: New. + * testsuite/25_algorithms/search_n/iterator.cc: Extend. + +2013-09-10 Ed Smith-Rowland <3dw4rd@verizon.net> + + * testsuite/28_regex/traits/wchar_t/value.cc: Change template args + from char to wchar_t, literals from 'x' to L'x'. + +2013-09-10 Kai Tietz <ktietz@redhat.com> + + PR libstdc++/54314 + * config/abi/pre/gnu-versioned-namespace.ver: Add thunk _ZTv0_n12_NS* + like in gnu.ver. + +2013-09-07 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/58341 + * include/bits/stl_algobase.h (copy_backward): Fix documentation + per DR 1206. + +2013-09-05 Tim Shen <timshen91@gmail.com> + + * include/bits/regex_automaton.h: Add dummy node type. Rewrite + _StateSeq. + * include/bits/regex_automaton.tcc: Implement them. + * include/bits/regex_compiler.h: Rewrite _Compiler to use new + _StateSeq interfaces. + * include/bits/regex_compiler.tcc: Implement them. + * include/bits/regex_scanner.h: Add word boundry assertion token. + * include/bits/regex_scanner.tcc (_Scanner<>::_M_eat_escape_ecma): + Support word boundry. + * testsuite/28_regex/algorithms/regex_match/basic/ + string_range_02_03.cc: Remove "xfail". + * testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc: + Likewise. + * testsuite/28_regex/algorithms/regex_match/extended/ + string_range_02_03.cc: Likewise. + * testsuite/28_regex/algorithms/regex_match/extended/ + cstring_questionmark.cc: Remove xfail and get correct length of + c-string. + * testsuite/28_regex/algorithms/regex_match/extended/ + string_range_00_03.cc: Likewise. + * testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc: + New. + * testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc: + New. + * testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc: New. + 2013-09-03 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/58302 * include/bits/random.tcc (negative_binomial_distribution<>:: - operator()(_UniformRandomNumberGenerator&, const param_type&): + operator()(_UniformRandomNumberGenerator&, const param_type&)): Fix typo in template argument. * testsuite/26_numerics/random/negative_binomial_distribution/ operators/58302.cc: New. diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver index 33a0068e2d7..b795a482557 100644 --- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver +++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver @@ -63,6 +63,7 @@ GLIBCXX_7.0 { _ZTVN9__gnu_cxx3__718stdio_sync_filebufI[cw]NSt3__711char_traitsI[cw]EEEE; # thunk + _ZTv0_n12_NS*; _ZTv0_n24_NS*; # typeinfo structure diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index f3b4b13ecd7..e1672e068fd 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -7118,7 +7118,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -7143,7 +7143,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -7162,7 +7165,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -11520,7 +11526,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11523 "configure" +#line 11529 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11626,7 +11632,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11629 "configure" +#line 11635 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -15046,7 +15052,7 @@ fi # # Fake what AC_TRY_COMPILE does. XXX Look at redoing this new-style. cat > conftest.$ac_ext << EOF -#line 15049 "configure" +#line 15055 "configure" struct S { ~S(); }; void bar(); void foo() @@ -15396,7 +15402,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; } # Fake what AC_TRY_COMPILE does. cat > conftest.$ac_ext << EOF -#line 15399 "configure" +#line 15405 "configure" int main() { typedef bool atomic_type; @@ -15431,7 +15437,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15434 "configure" +#line 15440 "configure" int main() { typedef short atomic_type; @@ -15466,7 +15472,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15469 "configure" +#line 15475 "configure" int main() { // NB: _Atomic_word not necessarily int. @@ -15502,7 +15508,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15505 "configure" +#line 15511 "configure" int main() { typedef long long atomic_type; @@ -15581,7 +15587,7 @@ $as_echo "$as_me: WARNING: Performance of certain classes will degrade as a resu # unnecessary for this test. cat > conftest.$ac_ext << EOF -#line 15584 "configure" +#line 15590 "configure" int main() { _Decimal32 d1; @@ -15623,7 +15629,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # unnecessary for this test. cat > conftest.$ac_ext << EOF -#line 15626 "configure" +#line 15632 "configure" template<typename T1, typename T2> struct same { typedef T2 type; }; @@ -15657,7 +15663,7 @@ $as_echo "$enable_int128" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15660 "configure" +#line 15666 "configure" template<typename T1, typename T2> struct same { typedef T2 type; }; diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h index 28df242b1bc..c72859b6ed3 100644 --- a/libstdc++-v3/include/bits/allocator.h +++ b/libstdc++-v3/include/bits/allocator.h @@ -158,13 +158,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // To implement Option 3 of DR 431. template<typename _Alloc, bool = __is_empty(_Alloc)> struct __alloc_swap - { static void _S_do_it(_Alloc&, _Alloc&) { } }; + { static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } }; template<typename _Alloc> struct __alloc_swap<_Alloc, false> { static void - _S_do_it(_Alloc& __one, _Alloc& __two) + _S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT { // Precondition: swappable allocators. if (__one != __two) @@ -194,13 +194,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION = __or_<is_copy_constructible<typename _Tp::value_type>, is_nothrow_move_constructible<typename _Tp::value_type>>::value> struct __shrink_to_fit_aux - { static bool _S_do_it(_Tp&) { return false; } }; + { static bool _S_do_it(_Tp&) noexcept { return false; } }; template<typename _Tp> struct __shrink_to_fit_aux<_Tp, true> { static bool - _S_do_it(_Tp& __c) + _S_do_it(_Tp& __c) noexcept { __try { diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index c8723ededd9..48904288867 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -178,7 +178,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static size_type _S_empty_rep_storage[]; static _Rep& - _S_empty_rep() + _S_empty_rep() _GLIBCXX_NOEXCEPT { // NB: Mild hack to avoid strict-aliasing warnings. Note that // _S_empty_rep_storage is never modified and the punning should @@ -188,23 +188,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } bool - _M_is_leaked() const + _M_is_leaked() const _GLIBCXX_NOEXCEPT { return this->_M_refcount < 0; } bool - _M_is_shared() const + _M_is_shared() const _GLIBCXX_NOEXCEPT { return this->_M_refcount > 0; } void - _M_set_leaked() + _M_set_leaked() _GLIBCXX_NOEXCEPT { this->_M_refcount = -1; } void - _M_set_sharable() + _M_set_sharable() _GLIBCXX_NOEXCEPT { this->_M_refcount = 0; } void - _M_set_length_and_sharable(size_type __n) + _M_set_length_and_sharable(size_type __n) _GLIBCXX_NOEXCEPT { #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 if (__builtin_expect(this != &_S_empty_rep(), false)) @@ -234,7 +234,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_create(size_type, size_type, const _Alloc&); void - _M_dispose(const _Alloc& __a) + _M_dispose(const _Alloc& __a) _GLIBCXX_NOEXCEPT { #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 if (__builtin_expect(this != &_S_empty_rep(), false)) @@ -271,7 +271,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Use empty-base optimization: http://www.cantrip.org/emptyopt.html struct _Alloc_hider : _Alloc { - _Alloc_hider(_CharT* __dat, const _Alloc& __a) + _Alloc_hider(_CharT* __dat, const _Alloc& __a) _GLIBCXX_NOEXCEPT : _Alloc(__a), _M_p(__dat) { } _CharT* _M_p; // The actual data. @@ -289,25 +289,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION mutable _Alloc_hider _M_dataplus; _CharT* - _M_data() const + _M_data() const _GLIBCXX_NOEXCEPT { return _M_dataplus._M_p; } _CharT* - _M_data(_CharT* __p) + _M_data(_CharT* __p) _GLIBCXX_NOEXCEPT { return (_M_dataplus._M_p = __p); } _Rep* - _M_rep() const + _M_rep() const _GLIBCXX_NOEXCEPT { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); } // 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(_M_data()); } iterator - _M_iend() const + _M_iend() const _GLIBCXX_NOEXCEPT { return iterator(_M_data() + this->size()); } void @@ -334,7 +334,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; @@ -342,7 +342,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 (less<const _CharT*>()(__s, _M_data()) || less<const _CharT*>()(_M_data() + this->size(), __s)); @@ -351,7 +351,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // When __n = 1 way faster than the general multichar // traits_type::copy/move/assign. static void - _M_copy(_CharT* __d, const _CharT* __s, size_type __n) + _M_copy(_CharT* __d, const _CharT* __s, size_type __n) _GLIBCXX_NOEXCEPT { if (__n == 1) traits_type::assign(*__d, *__s); @@ -360,7 +360,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } static void - _M_move(_CharT* __d, const _CharT* __s, size_type __n) + _M_move(_CharT* __d, const _CharT* __s, size_type __n) _GLIBCXX_NOEXCEPT { if (__n == 1) traits_type::assign(*__d, *__s); @@ -369,7 +369,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } static void - _M_assign(_CharT* __d, size_type __n, _CharT __c) + _M_assign(_CharT* __d, size_type __n, _CharT __c) _GLIBCXX_NOEXCEPT { if (__n == 1) traits_type::assign(*__d, __c); @@ -382,29 +382,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<class _Iterator> static void _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) + _GLIBCXX_NOEXCEPT { for (; __k1 != __k2; ++__k1, ++__p) traits_type::assign(*__p, *__k1); // These types are off. } static void - _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) + _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPT { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2) + _GLIBCXX_NOEXCEPT { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void - _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) + _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPT { _M_copy(__p, __k1, __k2 - __k1); } static void _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) + _GLIBCXX_NOEXCEPT { _M_copy(__p, __k1, __k2 - __k1); } static int - _S_compare(size_type __n1, size_type __n2) + _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPT { const difference_type __d = difference_type(__n1 - __n2); @@ -423,7 +426,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_leak_hard(); static _Rep& - _S_empty_rep() + _S_empty_rep() _GLIBCXX_NOEXCEPT { return _Rep::_S_empty_rep(); } public: @@ -756,7 +759,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L /// A non-binding request to reduce capacity() to size(). void - shrink_to_fit() + shrink_to_fit() _GLIBCXX_NOEXCEPT { if (capacity() > size()) { @@ -799,6 +802,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * Erases the string, making it empty. */ + // PR 56166: this should not throw. void clear() _GLIBCXX_NOEXCEPT { _M_mutate(0, this->size(), 0); } @@ -823,7 +827,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 <= size()); return _M_data()[__pos]; @@ -903,7 +907,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * element of the %string. */ const_reference - front() const + front() const _GLIBCXX_NOEXCEPT { return operator[](0); } /** @@ -919,7 +923,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * last element of the %string. */ const_reference - back() const + back() const _GLIBCXX_NOEXCEPT { return operator[](this->size() - 1); } #endif @@ -1787,6 +1791,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * Exchanges the contents of this string with that of @a __s in constant * time. */ + // PR 58265, this should be noexcept. void swap(basic_string& __s); 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 412465adfa2..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,19 +2120,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename, typename, typename, typename> friend class __detail::_BFSExecutor; - template<typename _Bp, typename _Ap, typename _Ch_type, typename _Rx_traits> + template<typename, typename, typename> + friend class regex_iterator; + + template<typename _Bp, typename _Ap, + typename _Ch_type, typename _Rx_traits> friend bool regex_match(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Ch_type, _Rx_traits>&, regex_constants::match_flag_type); - template<typename _Bp, typename _Ap, typename _Ch_type, typename _Rx_traits> + template<typename _Bp, typename _Ap, + typename _Ch_type, typename _Rx_traits> friend bool regex_search(_Bp, _Bp, match_results<_Bp, _Ap>&, 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; @@ -2198,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> @@ -2213,8 +2233,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__re._M_automaton == nullptr) return false; - __detail::__get_executor(__s, __e, __m, __re, __flags)->_M_match(); - if (__m.size() > 0 && __m[0].matched) + + 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) if (!__it.matched) @@ -2359,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> @@ -2373,29 +2397,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__re._M_automaton == nullptr) return false; - auto __cur = __first; - // Continue when __cur == __last - do + + 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()) { - __detail::__get_executor(__cur, __last, __m, __re, __flags) - ->_M_search_from_first(); - if (__m.size() > 0 && __m[0].matched) - { - for (auto __it : __m) - if (!__it.matched) - __it.first = __it.second = __last; - __m.at(__m.size()).first = __first; - __m.at(__m.size()).second = __m[0].first; - __m.at(__m.size()+1).first = __m[0].second; - __m.at(__m.size()+1).second = __last; - __m.at(__m.size()).matched = - (__m.prefix().first != __m.prefix().second); - __m.at(__m.size()+1).matched = - (__m.suffix().first != __m.suffix().second); - return true; - } + for (auto __it : __m) + if (!__it.matched) + __it.first = __it.second = __last; + __m.at(__m.size()).first = __first; + __m.at(__m.size()).second = __m[0].first; + __m.at(__m.size()+1).first = __m[0].second; + __m.at(__m.size()+1).second = __last; + __m.at(__m.size()).matched = + (__m.prefix().first != __m.prefix().second); + __m.at(__m.size()+1).matched = + (__m.suffix().first != __m.suffix().second); + return true; } - while (__cur++ != __last); return false; } @@ -2683,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, @@ -2703,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_automaton.h b/libstdc++-v3/include/bits/regex_automaton.h index 2c872aa9482..94a14ce96aa 100644 --- a/libstdc++-v3/include/bits/regex_automaton.h +++ b/libstdc++-v3/include/bits/regex_automaton.h @@ -51,13 +51,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// that represents the regular expression. enum _Opcode { - _S_opcode_unknown = 0, - _S_opcode_alternative = 1, - _S_opcode_backref = 2, - _S_opcode_subexpr_begin = 4, - _S_opcode_subexpr_end = 5, - _S_opcode_match = 100, - _S_opcode_accept = 255 + _S_opcode_unknown, + _S_opcode_alternative, + _S_opcode_backref, + _S_opcode_line_begin_assertion, + _S_opcode_line_end_assertion, + _S_opcode_word_boundry, + _S_opcode_subexpr_lookahead, + _S_opcode_subexpr_begin, + _S_opcode_subexpr_end, + _S_opcode_dummy, + _S_opcode_match, + _S_opcode_accept, }; template<typename _CharT, typename _TraitsT> @@ -69,37 +74,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _OpcodeT _M_opcode; // type of outgoing transition _StateIdT _M_next; // outgoing transition - union // Since they are mutual exclusive. + union // Since they are mutually exclusive. { - _StateIdT _M_alt; // for _S_opcode_alternative unsigned int _M_subexpr; // for _S_opcode_subexpr_* unsigned int _M_backref_index; // for _S_opcode_backref + struct + { + // for _S_opcode_alternative. + _StateIdT _M_quant_index; + // for _S_opcode_alternative or _S_opcode_subexpr_lookahead + _StateIdT _M_alt; + // for _S_opcode_word_boundry or _S_opcode_subexpr_lookahead or + // quantifiers(ungreedy if set true) + bool _M_neg; + }; }; - _MatcherT _M_matches; // for _S_opcode_match + _MatcherT _M_matches; // for _S_opcode_match explicit _State(_OpcodeT __opcode) : _M_opcode(__opcode), _M_next(_S_invalid_state_id) { } - _State(const _MatcherT& __m) - : _M_opcode(_S_opcode_match), _M_next(_S_invalid_state_id), - _M_matches(__m) - { } - - _State(_OpcodeT __opcode, unsigned __index) - : _M_opcode(__opcode), _M_next(_S_invalid_state_id) - { - if (__opcode == _S_opcode_subexpr_begin - || __opcode == _S_opcode_subexpr_end) - _M_subexpr = __index; - else if (__opcode == _S_opcode_backref) - _M_backref_index = __index; - } - - _State(_StateIdT __next, _StateIdT __alt) - : _M_opcode(_S_opcode_alternative), _M_next(__next), _M_alt(__alt) - { } - #ifdef _GLIBCXX_DEBUG std::ostream& _M_print(std::ostream& ostr) const; @@ -140,7 +135,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _NFA(_FlagT __f) : _M_flags(__f), _M_start_state(0), _M_subexpr_count(0), - _M_has_backref(false) + _M_has_backref(false), _M_quant_count(0) { } _FlagT @@ -162,23 +157,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _StateIdT _M_insert_accept() { - this->push_back(_StateT(_S_opcode_accept)); - _M_accepting_states.insert(this->size()-1); - return this->size()-1; + auto __ret = _M_insert_state(_StateT(_S_opcode_accept)); + _M_accepting_states.insert(__ret); + return __ret; } _StateIdT - _M_insert_alt(_StateIdT __next, _StateIdT __alt) + _M_insert_alt(_StateIdT __next, _StateIdT __alt, bool __neg) { - this->push_back(_StateT(__next, __alt)); - return this->size()-1; + _StateT __tmp(_S_opcode_alternative); + // It labels every quantifier to make greedy comparison easier in BFS + // approach. + __tmp._M_quant_index = _M_quant_count++; + __tmp._M_next = __next; + __tmp._M_alt = __alt; + __tmp._M_neg = __neg; + return _M_insert_state(__tmp); } _StateIdT _M_insert_matcher(_MatcherT __m) { - this->push_back(_StateT(__m)); - return this->size()-1; + _StateT __tmp(_S_opcode_match); + __tmp._M_matches = __m; + return _M_insert_state(__tmp); } _StateIdT @@ -186,21 +188,63 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { auto __id = _M_subexpr_count++; _M_paren_stack.push_back(__id); - this->push_back(_StateT(_S_opcode_subexpr_begin, __id)); - return this->size()-1; + _StateT __tmp(_S_opcode_subexpr_begin); + __tmp._M_subexpr = __id; + return _M_insert_state(__tmp); } _StateIdT _M_insert_subexpr_end() { - this->push_back(_StateT(_S_opcode_subexpr_end, _M_paren_stack.back())); + _StateT __tmp(_S_opcode_subexpr_end); + __tmp._M_subexpr = _M_paren_stack.back(); _M_paren_stack.pop_back(); - return this->size()-1; + return _M_insert_state(__tmp); } _StateIdT _M_insert_backref(unsigned int __index); + _StateIdT + _M_insert_line_begin() + { return _M_insert_state(_StateT(_S_opcode_line_begin_assertion)); } + + _StateIdT + _M_insert_line_end() + { return _M_insert_state(_StateT(_S_opcode_line_end_assertion)); } + + _StateIdT + _M_insert_word_bound(bool __neg) + { + _StateT __tmp(_S_opcode_word_boundry); + __tmp._M_neg = __neg; + return _M_insert_state(__tmp); + } + + _StateIdT + _M_insert_lookahead(_StateIdT __alt, bool __neg) + { + _StateT __tmp(_S_opcode_subexpr_lookahead); + __tmp._M_alt = __alt; + __tmp._M_neg = __neg; + return _M_insert_state(__tmp); + } + + _StateIdT + _M_insert_dummy() + { return _M_insert_state(_StateT(_S_opcode_dummy)); } + + _StateIdT + _M_insert_state(_StateT __s) + { + this->push_back(__s); + return this->size()-1; + } + + // Eliminate dummy node in this NFA to make it compact. + void + _M_eliminate_dummy(); + #ifdef _GLIBCXX_DEBUG std::ostream& _M_dot(std::ostream& __ostr) const; @@ -211,6 +255,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _FlagT _M_flags; _StateIdT _M_start_state; _SizeT _M_subexpr_count; + _SizeT _M_quant_count; bool _M_has_backref; }; @@ -222,58 +267,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: typedef _NFA<_CharT, _TraitsT> _RegexT; - public: - // Constructs a single-node sequence - _StateSeq(_RegexT& __ss, _StateIdT __s, - _StateIdT __e = _S_invalid_state_id) - : _M_nfa(__ss), _M_start(__s), _M_end1(__s), _M_end2(__e) - { } - // Constructs a split sequence from two other sequencces - _StateSeq(const _StateSeq& __e1, const _StateSeq& __e2) - : _M_nfa(__e1._M_nfa), - _M_start(_M_nfa._M_insert_alt(__e1._M_start, __e2._M_start)), - _M_end1(__e1._M_end1), _M_end2(__e2._M_end1) - { } - // Constructs a split sequence from a single sequence - _StateSeq(const _StateSeq& __e, _StateIdT __id) - : _M_nfa(__e._M_nfa), - _M_start(_M_nfa._M_insert_alt(__id, __e._M_start)), - _M_end1(__id), _M_end2(__e._M_end1) + public: + _StateSeq(_RegexT& __nfa, _StateIdT __s) + : _StateSeq(__nfa, __s, __s) { } - // Constructs a copy of a %_StateSeq - _StateSeq(const _StateSeq& __rhs) - : _M_nfa(__rhs._M_nfa), _M_start(__rhs._M_start), - _M_end1(__rhs._M_end1), _M_end2(__rhs._M_end2) + _StateSeq(_RegexT& __nfa, _StateIdT __s, _StateIdT __end) + : _M_nfa(__nfa), _M_start(__s), _M_end(__end) { } - _StateSeq& operator=(const _StateSeq& __rhs); - - _StateIdT - _M_front() const - { return _M_start; } - - // Extends a sequence by one. - void - _M_push_back(_StateIdT __id); - - // Extends and maybe joins a sequence. + // Append a state on *this and change *this to the new sequence. void - _M_append(_StateIdT __id); + _M_append(_StateIdT __id) + { + _M_nfa[_M_end]._M_next = __id; + _M_end = __id; + } + // Append a sequence on *this and change *this to the new sequence. void - _M_append(_StateSeq& __rhs); + _M_append(const _StateSeq& __s) + { + _M_nfa[_M_end]._M_next = __s._M_start; + _M_end = __s._M_end; + } // Clones an entire sequence. - _StateIdT + _StateSeq _M_clone(); - private: + public: _RegexT& _M_nfa; _StateIdT _M_start; - _StateIdT _M_end1; - _StateIdT _M_end2; + _StateIdT _M_end; }; //@} regex-detail diff --git a/libstdc++-v3/include/bits/regex_automaton.tcc b/libstdc++-v3/include/bits/regex_automaton.tcc index 2c25d97549c..13af984c273 100644 --- a/libstdc++-v3/include/bits/regex_automaton.tcc +++ b/libstdc++-v3/include/bits/regex_automaton.tcc @@ -80,6 +80,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION << __id << " -> " << _M_alt << " [label=\"epsilon\", tailport=\"n\"];\n"; break; + case _S_opcode_backref: + __ostr << __id << " [label=\"" << __id << "\\nBACKREF " + << _M_subexpr << "\"];\n" + << __id << " -> " << _M_next << " [label=\"<match>\"];\n"; + break; + case _S_opcode_line_begin_assertion: + __ostr << __id << " [label=\"" << __id << "\\nLINE_BEGIN \"];\n" + << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; + break; + case _S_opcode_line_end_assertion: + __ostr << __id << " [label=\"" << __id << "\\nLINE_END \"];\n" + << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; + break; + case _S_opcode_word_boundry: + __ostr << __id << " [label=\"" << __id << "\\nWORD_BOUNDRY " + << _M_neg << "\"];\n" + << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; + break; + case _S_opcode_subexpr_lookahead: + __ostr << __id << " [label=\"" << __id << "\\nLOOK_AHEAD\"];\n" + << __id << " -> " << _M_next + << " [label=\"epsilon\", tailport=\"s\"];\n" + << __id << " -> " << _M_alt + << " [label=\"<assert>\", tailport=\"n\"];\n"; + break; case _S_opcode_subexpr_begin: __ostr << __id << " [label=\"" << __id << "\\nSBEGIN " << _M_subexpr << "\"];\n" @@ -90,10 +115,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION << _M_subexpr << "\"];\n" << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; break; - case _S_opcode_backref: - __ostr << __id << " [label=\"" << __id << "\\nBACKREF " - << _M_subexpr << "\"];\n" - << __id << " -> " << _M_next << " [label=\"<match>\"];\n"; + case _S_opcode_dummy: break; case _S_opcode_match: __ostr << __id << " [label=\"" << __id << "\\nMATCH\"];\n" @@ -103,8 +125,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ; break; default: - __ostr << __id << " [label=\"" << __id << "\\nUNK\"];\n" - << __id << " -> " << _M_next << " [label=\"?\"];\n"; + _GLIBCXX_DEBUG_ASSERT(false); break; } return __ostr; @@ -140,71 +161,68 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__index == __it) __throw_regex_error(regex_constants::error_backref); _M_has_backref = true; - this->push_back(_StateT(_S_opcode_backref, __index)); - return this->size()-1; - } - - template<typename _CharT, typename _TraitsT> - _StateSeq<_CharT, _TraitsT>& _StateSeq<_CharT, _TraitsT>:: - operator=(const _StateSeq& __rhs) - { - _M_start = __rhs._M_start; - _M_end1 = __rhs._M_end1; - _M_end2 = __rhs._M_end2; - return *this; + _StateT __tmp(_S_opcode_backref); + __tmp._M_backref_index = __index; + return _M_insert_state(__tmp); } template<typename _CharT, typename _TraitsT> - void _StateSeq<_CharT, _TraitsT>:: - _M_push_back(_StateIdT __id) + void _NFA<_CharT, _TraitsT>:: + _M_eliminate_dummy() { - if (_M_end1 != _S_invalid_state_id) - _M_nfa[_M_end1]._M_next = __id; - _M_end1 = __id; + for (auto& __it : *this) + { + while (__it._M_next >= 0 && (*this)[__it._M_next]._M_opcode + == _S_opcode_dummy) + __it._M_next = (*this)[__it._M_next]._M_next; + if (__it._M_opcode == _S_opcode_alternative) + while (__it._M_alt >= 0 && (*this)[__it._M_alt]._M_opcode + == _S_opcode_dummy) + __it._M_alt = (*this)[__it._M_alt]._M_next; + } } + // Just apply DFS on the sequence and re-link their links. template<typename _CharT, typename _TraitsT> - void _StateSeq<_CharT, _TraitsT>:: - _M_append(_StateIdT __id) - { - if (_M_end2 != _S_invalid_state_id) - { - if (_M_end2 == _M_end1) - _M_nfa[_M_end2]._M_alt = __id; - else - _M_nfa[_M_end2]._M_next = __id; - _M_end2 = _S_invalid_state_id; - } - if (_M_end1 != _S_invalid_state_id) - _M_nfa[_M_end1]._M_next = __id; - _M_end1 = __id; - } - - template<typename _CharT, typename _TraitsT> - void _StateSeq<_CharT, _TraitsT>:: - _M_append(_StateSeq& __rhs) + _StateSeq<_CharT, _TraitsT> _StateSeq<_CharT, _TraitsT>:: + _M_clone() { - if (_M_end2 != _S_invalid_state_id) - { - if (_M_end2 == _M_end1) - _M_nfa[_M_end2]._M_alt = __rhs._M_start; - else - _M_nfa[_M_end2]._M_next = __rhs._M_start; - _M_end2 = _S_invalid_state_id; - } - if (__rhs._M_end2 != _S_invalid_state_id) - _M_end2 = __rhs._M_end2; - if (_M_end1 != _S_invalid_state_id) - _M_nfa[_M_end1]._M_next = __rhs._M_start; - _M_end1 = __rhs._M_end1; + std::map<_StateIdT, _StateIdT> __m; + std::stack<_StateIdT> __stack; + __stack.push(_M_start); + while (!__stack.empty()) + { + auto __u = __stack.top(); + __stack.pop(); + auto __dup = _M_nfa[__u]; + auto __id = _M_nfa._M_insert_state(__dup); + __m[__u] = __id; + if (__u == _M_end) + continue; + if (__m.count(__dup._M_next) == 0) + __stack.push(__dup._M_next); + if (__dup._M_opcode == _S_opcode_alternative) + if (__m.count(__dup._M_alt) == 0) + __stack.push(__dup._M_alt); + } + for (auto __it : __m) + { + auto& __ref = _M_nfa[__it.second]; + if (__ref._M_next != -1) + { + _GLIBCXX_DEBUG_ASSERT(__m.count(__ref._M_next)); + __ref._M_next = __m[__ref._M_next]; + } + if (__ref._M_opcode == _S_opcode_alternative) + if (__ref._M_alt != -1) + { + _GLIBCXX_DEBUG_ASSERT(__m.count(__ref._M_alt)); + __ref._M_alt = __m[__ref._M_alt]; + } + } + return _StateSeq(_M_nfa, __m[_M_start], __m[_M_end]); } - // @todo implement this function. - template<typename _CharT, typename _TraitsT> - _StateIdT _StateSeq<_CharT, _TraitsT>:: - _M_clone() - { return 0; } - _GLIBCXX_END_NAMESPACE_VERSION } // namespace __detail } // namespace diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h index 55ecdb92d41..3b85d3a46c3 100644 --- a/libstdc++-v3/include/bits/regex_compiler.h +++ b/libstdc++-v3/include/bits/regex_compiler.h @@ -56,7 +56,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::shared_ptr<_RegexT> _M_get_nfa() const - { return std::shared_ptr<_RegexT>(new _RegexT(_M_state_store)); } + { return make_shared<_RegexT>(_M_nfa); } private: typedef _Scanner<_FwdIter> _ScannerT; @@ -64,6 +64,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _StateSeq<_CharT, _TraitsT> _StateSeqT; typedef std::stack<_StateSeqT, std::vector<_StateSeqT>> _StackT; typedef _BracketMatcher<_CharT, _TraitsT> _BMatcherT; + typedef std::ctype<_CharT> _CtypeT; // accepts a specific token or returns false. bool @@ -91,21 +92,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_bracket_expression(); void - _M_bracket_list(_BMatcherT& __matcher); - - bool - _M_follow_list(_BMatcherT& __matcher); - - void _M_expression_term(_BMatcherT& __matcher); bool _M_range_expression(_BMatcherT& __matcher); bool - _M_start_range(_BMatcherT& __matcher); - - bool _M_collating_symbol(_BMatcherT& __matcher); bool @@ -120,12 +112,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _M_try_char(); - _CharT - _M_get_char(); + _StateSeqT + _M_pop() + { + auto ret = _M_stack.top(); + _M_stack.pop(); + return ret; + } const _TraitsT& _M_traits; + const _CtypeT& _M_ctype; _ScannerT _M_scanner; - _RegexT _M_state_store; + _RegexT _M_nfa; _StringT _M_value; _StackT _M_stack; _FlagT _M_flags; diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc index e41b251c257..7f9a19af2d9 100644 --- a/libstdc++-v3/include/bits/regex_compiler.tcc +++ b/libstdc++-v3/include/bits/regex_compiler.tcc @@ -28,6 +28,31 @@ * Do not attempt to use it directly. @headername{regex} */ +// FIXME make comments doxygen format. + +// This compiler refers to "Regular Expression Matching Can Be Simple And Fast" +// (http://swtch.com/~rsc/regexp/regexp1.html"), +// but doesn't strictly follow it. +// +// When compiling, states are *chained* instead of tree- or graph-constructed. +// It's more like structured programs: there's if statement and loop statement. +// +// For alternative structure(say "a|b"), aka "if statement", two branchs should +// be constructed. However, these two shall merge to an "end_tag" at the end of +// this operator: +// +// branch1 +// / \ +// => begin_tag end_tag => +// \ / +// branch2 +// +// This is the difference between this implementation and that in Russ's +// article. +// +// That's why we introduced dummy node here ------ "end_tag" is a dummy node. +// All dummy node will be eliminated at the end of compiling process. + namespace std _GLIBCXX_VISIBILITY(default) { namespace __detail @@ -39,32 +64,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Compiler(_FwdIter __b, _FwdIter __e, const _TraitsT& __traits, _FlagT __flags) : _M_traits(__traits), _M_scanner(__b, __e, __flags, _M_traits.getloc()), - _M_state_store(__flags), _M_flags(__flags) + _M_ctype(std::use_facet<std::ctype<_CharT>>(_M_traits.getloc())), + _M_nfa(__flags), _M_flags(__flags) { - _StateSeqT __r(_M_state_store, - _M_state_store._M_insert_subexpr_begin()); - _M_disjunction(); - if (!_M_stack.empty()) - { - __r._M_append(_M_stack.top()); - _M_stack.pop(); - } - __r._M_append(_M_state_store._M_insert_subexpr_end()); - __r._M_append(_M_state_store._M_insert_accept()); - } - - template<typename _FwdIter, typename _CharT, typename _TraitsT> - bool - _Compiler<_FwdIter, _CharT, _TraitsT>:: - _M_match_token(_TokenT token) - { - if (token == _M_scanner._M_get_token()) - { - _M_value = _M_scanner._M_get_value(); - _M_scanner._M_advance(); - return true; - } - return false; + _StateSeqT __r(_M_nfa, _M_nfa._M_start()); + __r._M_append(_M_nfa._M_insert_subexpr_begin()); + this->_M_disjunction(); + if (!_M_match_token(_ScannerT::_S_token_eof)) + __throw_regex_error(regex_constants::error_paren); + __r._M_append(_M_pop()); + _GLIBCXX_DEBUG_ASSERT(_M_stack.empty()); + __r._M_append(_M_nfa._M_insert_subexpr_end()); + __r._M_append(_M_nfa._M_insert_accept()); + _M_nfa._M_eliminate_dummy(); } template<typename _FwdIter, typename _CharT, typename _TraitsT> @@ -73,12 +85,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_disjunction() { this->_M_alternative(); - if (_M_match_token(_ScannerT::_S_token_or)) + // TODO empty alternative like, um, "(|asdf)" + while (_M_match_token(_ScannerT::_S_token_or)) { - _StateSeqT __alt1 = _M_stack.top(); _M_stack.pop(); - this->_M_disjunction(); - _StateSeqT __alt2 = _M_stack.top(); _M_stack.pop(); - _M_stack.push(_StateSeqT(__alt1, __alt2)); + _StateSeqT __alt1 = _M_pop(); + this->_M_alternative(); + _StateSeqT __alt2 = _M_pop(); + auto __end = _M_nfa._M_insert_dummy(); + __alt1._M_append(__end); + __alt2._M_append(__end); + _M_stack.push(_StateSeqT(_M_nfa, + _M_nfa._M_insert_alt(__alt1._M_start, + __alt2._M_start, false), + __end)); } } @@ -89,15 +108,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (this->_M_term()) { - _StateSeqT __re = _M_stack.top(); _M_stack.pop(); + _StateSeqT __re = _M_pop(); this->_M_alternative(); - if (!_M_stack.empty()) - { - __re._M_append(_M_stack.top()); - _M_stack.pop(); - } + __re._M_append(_M_pop()); _M_stack.push(__re); } + else + _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_dummy())); } template<typename _FwdIter, typename _CharT, typename _TraitsT> @@ -115,13 +132,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return false; } - // TODO Implement it. template<typename _FwdIter, typename _CharT, typename _TraitsT> bool _Compiler<_FwdIter, _CharT, _TraitsT>:: _M_assertion() { - return false; + if (_M_match_token(_ScannerT::_S_token_line_begin)) + _M_stack.push(_StateSeqT(_M_nfa, _M_nfa. + _M_insert_line_begin())); + else if (_M_match_token(_ScannerT::_S_token_line_end)) + _M_stack.push(_StateSeqT(_M_nfa, _M_nfa. + _M_insert_line_end())); + else if (_M_match_token(_ScannerT::_S_token_word_bound)) + // _M_value[0] == 'n' means it's negtive, say "not word boundary". + _M_stack.push(_StateSeqT(_M_nfa, _M_nfa. + _M_insert_word_bound(_M_value[0] == 'n'))); + else if (_M_match_token(_ScannerT::_S_token_subexpr_lookahead_begin)) + { + auto __neg = _M_value[0] == 'n'; + this->_M_disjunction(); + if (!_M_match_token(_ScannerT::_S_token_subexpr_end)) + __throw_regex_error(regex_constants::error_paren); + auto __tmp = _M_pop(); + __tmp._M_append(_M_nfa._M_insert_accept()); + _M_stack.push( + _StateSeqT( + _M_nfa, + _M_nfa._M_insert_lookahead(__tmp._M_start, __neg))); + } + else + return false; + return true; } template<typename _FwdIter, typename _CharT, typename _TraitsT> @@ -129,71 +170,91 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Compiler<_FwdIter, _CharT, _TraitsT>:: _M_quantifier() { - if (_M_match_token(_ScannerT::_S_token_closure0)) + bool __neg = regex_constants::ECMAScript; + auto __init = [this, &__neg]() { if (_M_stack.empty()) __throw_regex_error(regex_constants::error_badrepeat); - _StateSeqT __r(_M_stack.top(), -1); - __r._M_append(__r._M_front()); - _M_stack.pop(); + __neg = __neg && _M_match_token(_ScannerT::_S_token_opt); + }; + if (_M_match_token(_ScannerT::_S_token_closure0)) + { + __init(); + auto __e = _M_pop(); + _StateSeqT __r(_M_nfa, _M_nfa._M_insert_alt(_S_invalid_state_id, + __e._M_start, __neg)); + __e._M_append(__r); _M_stack.push(__r); - return; } - if (_M_match_token(_ScannerT::_S_token_closure1)) + else if (_M_match_token(_ScannerT::_S_token_closure1)) { - if (_M_stack.empty()) - __throw_regex_error(regex_constants::error_badrepeat); - _StateSeqT __r(_M_state_store, - _M_state_store. - _M_insert_alt(_S_invalid_state_id, - _M_stack.top()._M_front())); - _M_stack.top()._M_append(__r); - return; + __init(); + auto __e = _M_pop(); + __e._M_append(_M_nfa._M_insert_alt(_S_invalid_state_id, __e._M_start, + __neg)); + _M_stack.push(__e); } - if (_M_match_token(_ScannerT::_S_token_opt)) + else if (_M_match_token(_ScannerT::_S_token_opt)) { - if (_M_stack.empty()) - __throw_regex_error(regex_constants::error_badrepeat); - _StateSeqT __r(_M_stack.top(), -1); - _M_stack.pop(); + __init(); + auto __e = _M_pop(); + auto __end = _M_nfa._M_insert_dummy(); + _StateSeqT __r(_M_nfa, _M_nfa._M_insert_alt(_S_invalid_state_id, + __e._M_start, __neg)); + __e._M_append(__end); + __r._M_append(__end); _M_stack.push(__r); - return; } - if (_M_match_token(_ScannerT::_S_token_interval_begin)) + else if (_M_match_token(_ScannerT::_S_token_interval_begin)) { - if (_M_stack.empty()) - __throw_regex_error(regex_constants::error_badrepeat); + __init(); if (!_M_match_token(_ScannerT::_S_token_dup_count)) __throw_regex_error(regex_constants::error_badbrace); - _StateSeqT __r(_M_stack.top()); + _StateSeqT __r(_M_pop()); + _StateSeqT __e(_M_nfa, _M_nfa._M_insert_dummy()); int __min_rep = _M_cur_int_value(10); - for (int __i = 1; __i < __min_rep; ++__i) - _M_stack.top()._M_append(__r._M_clone()); + // {3 + for (int __i = 0; __i < __min_rep; ++__i) + __e._M_append(__r._M_clone()); if (_M_match_token(_ScannerT::_S_token_comma)) - if (_M_match_token(_ScannerT::_S_token_dup_count)) + if (_M_match_token(_ScannerT::_S_token_dup_count)) // {3,7} { int __n = _M_cur_int_value(10) - __min_rep; 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) { - _StateSeqT __r(_M_state_store, - _M_state_store. - _M_insert_alt(_S_invalid_state_id, - _M_stack.top()._M_front())); - _M_stack.top()._M_append(__r); + auto __tmp = __r._M_clone(); + 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 + else // {3,} { - _StateSeqT __r(_M_stack.top(), -1); - __r._M_push_back(__r._M_front()); - _M_stack.pop(); - _M_stack.push(__r); + auto __tmp = __r._M_clone(); + _StateSeqT __s(_M_nfa, + _M_nfa._M_insert_alt(_S_invalid_state_id, + __tmp._M_start, __neg)); + __tmp._M_append(__s); + __e._M_append(__s); } if (!_M_match_token(_ScannerT::_S_token_interval_end)) __throw_regex_error(regex_constants::error_brace); - return; + _M_stack.push(__e); } } @@ -203,46 +264,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_atom() { if (_M_match_token(_ScannerT::_S_token_anychar)) + _M_stack.push(_StateSeqT(_M_nfa, + _M_nfa._M_insert_matcher + (_AnyMatcher<_CharT, _TraitsT>(_M_traits)))); + else if (_M_try_char()) + _M_stack.push(_StateSeqT(_M_nfa, + _M_nfa._M_insert_matcher + (_CharMatcher<_CharT, _TraitsT>(_M_value[0], + _M_traits, + _M_flags)))); + else if (_M_match_token(_ScannerT::_S_token_backref)) + _M_stack.push(_StateSeqT(_M_nfa, _M_nfa. + _M_insert_backref(_M_cur_int_value(10)))); + else if (_M_match_token(_ScannerT::_S_token_quoted_class)) { - _M_stack.push(_StateSeqT(_M_state_store, - _M_state_store._M_insert_matcher - (_AnyMatcher<_CharT, _TraitsT>(_M_traits)))); - return true; - } - if (_M_try_char()) - { - _M_stack.push(_StateSeqT(_M_state_store, - _M_state_store._M_insert_matcher - (_CharMatcher<_CharT, _TraitsT>(_M_value[0], - _M_traits, - _M_flags)))); - return true; + _GLIBCXX_DEBUG_ASSERT(_M_value.size() == 1); + _BMatcherT __matcher(_M_ctype.is(_CtypeT::upper, _M_value[0]), + _M_traits, _M_flags); + __matcher._M_add_character_class(_M_value); + _M_stack.push(_StateSeqT(_M_nfa, + _M_nfa._M_insert_matcher(__matcher))); } - if (_M_match_token(_ScannerT::_S_token_backref)) + else if (_M_match_token(_ScannerT::_S_token_subexpr_no_group_begin)) { - _M_stack.push(_StateSeqT(_M_state_store, _M_state_store. - _M_insert_backref(_M_cur_int_value(10)))); - return true; + _StateSeqT __r(_M_nfa, _M_nfa._M_insert_dummy()); + this->_M_disjunction(); + if (!_M_match_token(_ScannerT::_S_token_subexpr_end)) + __throw_regex_error(regex_constants::error_paren); + __r._M_append(_M_pop()); + _M_stack.push(__r); } - if (_M_match_token(_ScannerT::_S_token_subexpr_begin)) + else if (_M_match_token(_ScannerT::_S_token_subexpr_begin)) { - int __mark = _M_state_store._M_sub_count(); - _StateSeqT __r(_M_state_store, - _M_state_store. - _M_insert_subexpr_begin()); + int __mark = _M_nfa._M_sub_count(); + _StateSeqT __r(_M_nfa, _M_nfa._M_insert_subexpr_begin()); this->_M_disjunction(); if (!_M_match_token(_ScannerT::_S_token_subexpr_end)) __throw_regex_error(regex_constants::error_paren); - if (!_M_stack.empty()) - { - __r._M_append(_M_stack.top()); - _M_stack.pop(); - } - __r._M_append(_M_state_store._M_insert_subexpr_end()); + __r._M_append(_M_pop()); + __r._M_append(_M_nfa._M_insert_subexpr_end()); _M_stack.push(__r); - return true; } - return _M_bracket_expression(); + else if (!_M_bracket_expression()) + return false; + return true; } template<typename _FwdIter, typename _CharT, typename _TraitsT> @@ -255,51 +320,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (!(__neg || _M_match_token(_ScannerT::_S_token_bracket_begin))) return false; _BMatcherT __matcher(__neg, _M_traits, _M_flags); - _M_bracket_list(__matcher); - _M_stack.push(_StateSeqT(_M_state_store, - _M_state_store._M_insert_matcher(__matcher))); + while (!_M_match_token(_ScannerT::_S_token_bracket_end)) + _M_expression_term(__matcher); + _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_matcher(__matcher))); return true; } template<typename _FwdIter, typename _CharT, typename _TraitsT> void _Compiler<_FwdIter, _CharT, _TraitsT>:: - _M_bracket_list(_BMatcherT& __matcher) - { - if (_M_match_token(_ScannerT::_S_token_bracket_end)) - return; - _M_expression_term(__matcher); - _M_bracket_list(__matcher); - return; - } - - template<typename _FwdIter, typename _CharT, typename _TraitsT> - void - _Compiler<_FwdIter, _CharT, _TraitsT>:: _M_expression_term(_BMatcherT& __matcher) { if (_M_match_token(_ScannerT::_S_token_collsymbol)) - { - __matcher._M_add_collating_element(_M_value); - return; - } - if (_M_match_token(_ScannerT::_S_token_equiv_class_name)) - { - __matcher._M_add_equivalence_class(_M_value); - return; - } - if (_M_match_token(_ScannerT::_S_token_char_class_name)) - { - __matcher._M_add_character_class(_M_value); - return; - } - if (_M_try_char()) // [a + __matcher._M_add_collating_element(_M_value); + else if (_M_match_token(_ScannerT::_S_token_equiv_class_name)) + __matcher._M_add_equivalence_class(_M_value); + else if (_M_match_token(_ScannerT::_S_token_char_class_name)) + __matcher._M_add_character_class(_M_value); + else if (_M_try_char()) // [a { auto __ch = _M_value[0]; if (_M_try_char()) { - if (_M_value[0] == std::use_facet<std::ctype<_CharT>> - (_M_traits.getloc()).widen('-')) // [a- + if (_M_value[0] == '-') // [a- { if (_M_try_char()) // [a-z] { @@ -315,9 +358,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __matcher._M_add_char(_M_value[0]); } __matcher._M_add_char(__ch); - return; } - __throw_regex_error(regex_constants::error_brack); + else + __throw_regex_error(regex_constants::error_brack); } template<typename _FwdIter, typename _CharT, typename _TraitsT> @@ -342,6 +385,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template<typename _FwdIter, typename _CharT, typename _TraitsT> + bool + _Compiler<_FwdIter, _CharT, _TraitsT>:: + _M_match_token(_TokenT token) + { + if (token == _M_scanner._M_get_token()) + { + _M_value = _M_scanner._M_get_value(); + _M_scanner._M_advance(); + return true; + } + return false; + } + + template<typename _FwdIter, typename _CharT, typename _TraitsT> int _Compiler<_FwdIter, _CharT, _TraitsT>:: _M_cur_int_value(int __radix) diff --git a/libstdc++-v3/include/bits/regex_constants.h b/libstdc++-v3/include/bits/regex_constants.h index 23174becdf9..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. @@ -78,87 +78,87 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * %set. */ enum syntax_option_type : unsigned int - { - /** - * Specifies that the matching of regular expressions against a character - * sequence shall be performed without regard to case. - */ - icase = 1 << _S_icase, - - /** - * Specifies that when a regular expression is matched against a character - * container sequence, no sub-expression matches are to be stored in the - * supplied match_results structure. - */ - nosubs = 1 << _S_nosubs, - - /** - * Specifies that the regular expression engine should pay more attention to - * the speed with which regular expressions are matched, and less to the - * speed with which regular expression objects are constructed. Otherwise - * it has no detectable effect on the program output. - */ - optimize = 1 << _S_optimize, - - /** - * Specifies that character ranges of the form [a-b] should be locale - * sensitive. - */ - collate = 1 << _S_collate, - - /** - * Specifies that the grammar recognized by the regular expression engine is - * that used by ECMAScript in ECMA-262 [Ecma International, ECMAScript - * Language Specification, Standard Ecma-262, third edition, 1999], as - * modified in section [28.13]. This grammar is similar to that defined - * in the PERL scripting language but extended with elements found in the - * POSIX regular expression grammar. - */ - ECMAScript = 1 << _S_ECMAScript, - - /** - * Specifies that the grammar recognized by the regular expression engine is - * that used by POSIX basic regular expressions in IEEE Std 1003.1-2001, - * Portable Operating System Interface (POSIX), Base Definitions and - * Headers, Section 9, Regular Expressions [IEEE, Information Technology -- - * Portable Operating System Interface (POSIX), IEEE Standard 1003.1-2001]. - */ - basic = 1 << _S_basic, - - /** - * Specifies that the grammar recognized by the regular expression engine is - * that used by POSIX extended regular expressions in IEEE Std 1003.1-2001, - * Portable Operating System Interface (POSIX), Base Definitions and Headers, - * Section 9, Regular Expressions. - */ - extended = 1 << _S_extended, - - /** - * Specifies that the grammar recognized by the regular expression engine is - * that used by POSIX utility awk in IEEE Std 1003.1-2001. This option is - * identical to syntax_option_type extended, except that C-style escape - * sequences are supported. These sequences are: - * \\\\, \\a, \\b, \\f, \\n, \\r, \\t , \\v, \\&apos,, &apos,, - * and \\ddd (where ddd is one, two, or three octal digits). - */ - awk = 1 << _S_awk, - - /** - * Specifies that the grammar recognized by the regular expression engine is - * that used by POSIX utility grep in IEEE Std 1003.1-2001. This option is - * identical to syntax_option_type basic, except that newlines are treated - * as whitespace. - */ - grep = 1 << _S_grep, - - /** - * Specifies that the grammar recognized by the regular expression engine is - * that used by POSIX utility grep when given the -E option in - * IEEE Std 1003.1-2001. This option is identical to syntax_option_type - * extended, except that newlines are treated as whitespace. - */ - egrep = 1 << _S_egrep, - }; + { + /** + * Specifies that the matching of regular expressions against a character + * sequence shall be performed without regard to case. + */ + icase = 1 << _S_icase, + + /** + * Specifies that when a regular expression is matched against a character + * container sequence, no sub-expression matches are to be stored in the + * supplied match_results structure. + */ + nosubs = 1 << _S_nosubs, + + /** + * Specifies that the regular expression engine should pay more attention to + * the speed with which regular expressions are matched, and less to the + * speed with which regular expression objects are constructed. Otherwise + * it has no detectable effect on the program output. + */ + optimize = 1 << _S_optimize, + + /** + * Specifies that character ranges of the form [a-b] should be locale + * sensitive. + */ + collate = 1 << _S_collate, + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by ECMAScript in ECMA-262 [Ecma International, ECMAScript + * Language Specification, Standard Ecma-262, third edition, 1999], as + * modified in section [28.13]. This grammar is similar to that defined + * in the PERL scripting language but extended with elements found in the + * POSIX regular expression grammar. + */ + ECMAScript = 1 << _S_ECMAScript, + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX basic regular expressions in IEEE Std 1003.1-2001, + * Portable Operating System Interface (POSIX), Base Definitions and + * Headers, Section 9, Regular Expressions [IEEE, Information Technology -- + * Portable Operating System Interface (POSIX), IEEE Standard 1003.1-2001]. + */ + basic = 1 << _S_basic, + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX extended regular expressions in IEEE Std 1003.1-2001, + * Portable Operating System Interface (POSIX), Base Definitions and + * Headers, Section 9, Regular Expressions. + */ + extended = 1 << _S_extended, + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX utility awk in IEEE Std 1003.1-2001. This option is + * identical to syntax_option_type extended, except that C-style escape + * sequences are supported. These sequences are: + * \\\\, \\a, \\b, \\f, \\n, \\r, \\t , \\v, \\&apos,, &apos,, + * and \\ddd (where ddd is one, two, or three octal digits). + */ + awk = 1 << _S_awk, + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX utility grep in IEEE Std 1003.1-2001. This option is + * identical to syntax_option_type basic, except that newlines are treated + * as whitespace. + */ + grep = 1 << _S_grep, + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX utility grep when given the -E option in + * IEEE Std 1003.1-2001. This option is identical to syntax_option_type + * extended, except that newlines are treated as whitespace. + */ + egrep = 1 << _S_egrep, + }; constexpr inline syntax_option_type operator&(syntax_option_type __a, syntax_option_type __b) @@ -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; - - /** - * 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). - */ - 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). - */ - constexpr match_flag_type match_not_eol = 1 << _S_not_eol; - - /** - * 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). - */ - 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. - */ - constexpr match_flag_type match_any = 1 << _S_any; - - /** - * The expression does not match an empty sequence. - */ - constexpr match_flag_type match_not_null = 1 << _S_not_null; + enum match_flag_type : unsigned int + { + /** + * The default matching rules. + */ + 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 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 expression \\b is not matched against the sub-sequence + * [first,first). + */ + 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, + + /** + * If more than one match is possible then any match is an acceptable + * result. + */ + match_any = 1 << _S_any, + + /** + * The expression does not match an empty sequence. + */ + match_not_null = 1 << _S_not_null, + + /** + * The expression only matches a sub-sequence that begins at first . + */ + 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, + + /** + * 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 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, + + /** + * 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, + + /** + * 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, + }; + + 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)); + } - /** - * The expression only matches a sub-sequence that begins at first . - */ - constexpr match_flag_type match_continuous = 1 << _S_continuous; + 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)); + } - /** - * --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; + 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)); + } - /** - * 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; + constexpr inline match_flag_type + operator~(match_flag_type __a) + { return (match_flag_type)(~static_cast<unsigned int>(__a)); } - /** - * 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; + inline match_flag_type& + operator&=(match_flag_type& __a, match_flag_type __b) + { return __a = __a & __b; } - /** - * 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; + inline match_flag_type& + operator|=(match_flag_type& __a, match_flag_type __b) + { return __a = __a | __b; } - /** - * 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; + 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 6d66d881584..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,42 +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 void - _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 void - _M_search_from_first() = 0; - - protected: - typedef typename _NFA<_CharT, _TraitsT>::_SizeT _SizeT; - _Executor(_BiIter __begin, - _BiIter __end, - _ResultsT& __results, - _FlagT __flags, - _SizeT __size) - : _M_current(__begin), _M_end(__end), _M_results(__results), - _M_flags(__flags) + bool + _M_search_from_first() { - __size += 2; - _M_results.resize(__size); - for (auto __i = 0; __i < __size; __i++) - _M_results[__i].matched = false; + _M_match_mode = false; + _M_init(_M_begin); + return _M_main(); } - _BiIter _M_current; - _BiIter _M_end; - _ResultsVec& _M_results; - _FlagT _M_flags; + bool + _M_search() + { + 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) const + { + static const _CharT __s = 'w'; + 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; + 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 @@ -115,37 +184,47 @@ _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()), - _M_traits(__traits), _M_nfa(__nfa), _M_results_ret(this->_M_results) + : _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()) { } + private: void - _M_match() - { _M_dfs<true>(_M_nfa._M_start()); } + _M_init(_BiIter __cur) + { + _M_cur_results.resize(_M_nfa._M_sub_count() + 2); + this->_M_current = __cur; + } void - _M_search_from_first() - { _M_dfs<false>(_M_nfa._M_start()); } + _M_set_start(_StateIdT __start) + { _M_start_state = __start; } - private: - template<bool __match_mode> - bool - _M_dfs(_StateIdT __i); + bool + _M_main() + { return _M_dfs(this->_M_start_state); } + + bool + _M_dfs(_StateIdT __start); - _ResultsVec _M_results_ret; - const _TraitsT& _M_traits; - const _RegexT& _M_nfa; + // To record current solution. + _ResultsVec _M_cur_results; + const _NFAT& _M_nfa; + _StateIdT _M_start_state; }; // Like the DFS approach, it try every possible state transition; Unlike DFS, @@ -168,38 +247,114 @@ _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 std::unique_ptr<_ResultsVec> _ResultsPtr; - typedef regex_constants::match_flag_type _FlagT; - - _BFSExecutor(_BiIter __begin, - _BiIter __end, - _ResultsT& __results, - const _RegexT& __nfa, - _FlagT __flags) - : _BaseT(__begin, __end, __results, __flags, __nfa._M_sub_count()), - _M_nfa(__nfa) + 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 matched. Two + // matching states conflict if they have equivalent `where` and `when`. + // + // 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 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 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, and indicates the same solution; so just return + // false. + struct _ResultsEntry + : private _ResultsVec { - if (_M_nfa._M_start() != _S_invalid_state_id) - _M_covered[_M_nfa._M_start()] = - _ResultsPtr(new _ResultsVec(this->_M_results)); - _M_e_closure(); - } + public: + _ResultsEntry(unsigned int __res_sz, unsigned int __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 _ResultsVec::operator[](__idx); } + + bool + operator<(const _ResultsEntry& __rhs) const + { + _GLIBCXX_DEBUG_ASSERT(_M_quant_keys.size() + == __rhs._M_quant_keys.size()); + return lexicographical_compare(_M_quant_keys.begin(), + _M_quant_keys.end(), + __rhs._M_quant_keys.begin(), + __rhs._M_quant_keys.end()); + } + + void + _M_inc(unsigned int __idx, bool __neg) + { _M_quant_keys[__idx] += __neg ? 1 : -1; } + + _ResultsVec + _M_get() + { return *this; } + + public: + std::vector<int> _M_quant_keys; + }; + typedef std::unique_ptr<_ResultsEntry> _ResultsPtr; + + public: + _BFSExecutor(_BiIter __begin, + _BiIter __end, + _ResultsT& __results, + const _RegexT& __re, + _FlagT __flags) + : _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()) + { } + private: void - _M_match() - { _M_main_loop<true>(); } + _M_init(_BiIter __cur) + { + _GLIBCXX_DEBUG_ASSERT(this->_M_start_state != _S_invalid_state_id); + this->_M_current = __cur; + _M_covered.clear(); + _ResultsVec& __res(this->_M_results); + _M_covered[this->_M_start_state] = + _ResultsPtr(new _ResultsEntry(__res.size(), + _M_nfa._M_quant_count)); + _M_e_closure(); + } void - _M_search_from_first() - { _M_main_loop<false>(); } + _M_set_start(_StateIdT __start) + { _M_start_state = __start; } - private: - template<bool __match_mode> - void - _M_main_loop(); + bool + _M_main(); void _M_e_closure(); @@ -208,15 +363,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_move(); bool - _M_match_less_than(const _ResultsVec& __u, const _ResultsVec& __v) const; + _M_includes_some(); - bool - _M_includes_some() const; - - std::map<_StateIdT, _ResultsPtr> _M_covered; - const _RegexT& _M_nfa; + std::map<_StateIdT, _ResultsPtr> _M_covered; + // To record global optimal solution. + _ResultsPtr _M_cur_results; + 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 788d65e54de..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,90 +43,122 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // This is not that certain. Need deeper investigate. return false; auto& __current = this->_M_current; - auto& __end = this->_M_end; - auto& __results = _M_results_ret; const auto& __state = _M_nfa[__i]; bool __ret = false; switch (__state._M_opcode) { case _S_opcode_alternative: - // Greedy mode by default. For non-greedy mode, - // swap _M_alt and _M_next. - // TODO: Add greedy mode option. - __ret = _M_dfs<__match_mode>(__state._M_alt) - || _M_dfs<__match_mode>(__state._M_next); + // Greedy or not, this is a question ;) + if (!__state._M_neg) + __ret = _M_dfs(__state._M_alt) + || _M_dfs(__state._M_next); + else + __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 (this->_M_at_begin()) + __ret = _M_dfs(__state._M_next); + break; + case _S_opcode_line_end_assertion: + if (this->_M_at_end()) + __ret = _M_dfs(__state._M_next); + break; + case _S_opcode_word_boundry: + 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: + 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); @@ -137,20 +168,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _BiIter, typename _Alloc, typename _CharT, typename _TraitsT> - template<bool __match_mode> - void _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>:: - _M_main_loop() + bool _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>:: + _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) - if (_M_includes_some()) - return; _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; } - _M_includes_some(); + if (this->_M_match_mode) + __ret = _M_includes_some(); + if (__ret) + { + _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; } template<typename _BiIter, typename _Alloc, @@ -158,9 +207,10 @@ _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& __current = this->_M_current; + for (auto& __it : _M_covered) { __in_q[__it.first] = true; @@ -173,18 +223,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __in_q[__u] = false; const auto& __state = _M_nfa[__u]; - // Can be implemented using method, but there're too much arguments. - // I would use macro function before C++11, but lambda is a better - // choice, since hopefully compiler can inline it. + // Can be implemented using method, but there will be too many + // arguments. I would use macro function before C++11, but lambda is + // a better choice, since hopefully compiler can inline it. auto __add_visited_state = [&](_StateIdT __v) { if (__v == _S_invalid_state_id) return; if (_M_covered.count(__u) != 0 && (_M_covered.count(__v) == 0 - || _M_match_less_than(*_M_covered[__u], *_M_covered[__v]))) + || *_M_covered[__u] < *_M_covered[__v])) { - _M_covered[__v] = _ResultsPtr(new _ResultsVec(*_M_covered[__u])); + _M_covered[__v] = + _ResultsPtr(new _ResultsEntry(*_M_covered[__u])); // if a state is updated, it's outgoing neighbors should be // reconsidered too. Push them to the queue. if (!__in_q[__v]) @@ -195,19 +246,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } }; + // Identical to DFS's switch part. switch (__state._M_opcode) { + // Needs to maintain quantifier count vector here. A quantifier + // must be concerned with a alt node. case _S_opcode_alternative: - __add_visited_state(__state._M_next); - __add_visited_state(__state._M_alt); + { + __add_visited_state(__state._M_next); + auto __back = + _M_covered[__u]->_M_quant_keys[__state._M_quant_index]; + _M_covered[__u]->_M_inc(__state._M_quant_index, + __state._M_neg); + __add_visited_state(__state._M_alt); + _M_covered[__u]->_M_quant_keys[__state._M_quant_index] + = __back; + } break; case _S_opcode_subexpr_begin: { - auto& __cu = *_M_covered[__u]; - auto __back = __cu[__state._M_subexpr].first; - __cu[__state._M_subexpr].first = __current; - __add_visited_state(__state._M_next); - __cu[__state._M_subexpr].first = __back; + auto& __sub = (*_M_covered[__u])[__state._M_subexpr]; + if (!__sub.matched || __sub.first != __current) + { + auto __back = __sub.first; + __sub.first = __current; + __add_visited_state(__state._M_next); + __sub.first = __back; + } } break; case _S_opcode_subexpr_end: @@ -220,10 +285,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __cu[__state._M_subexpr] = __back; } break; + case _S_opcode_line_begin_assertion: + if (this->_M_at_begin()) + __add_visited_state(__state._M_next); + break; + case _S_opcode_line_end_assertion: + if (this->_M_at_end()) + __add_visited_state(__state._M_next); + break; + case _S_opcode_word_boundry: + if (this->_M_word_boundry(__state) == !__state._M_neg) + __add_visited_state(__state._M_next); + break; + case _S_opcode_subexpr_lookahead: + if (this->_M_lookahead(__state) == !__state._M_neg) + __add_visited_state(__state._M_next); + break; case _S_opcode_match: break; case _S_opcode_accept: - __add_visited_state(__state._M_next); break; default: _GLIBCXX_DEBUG_ASSERT(false); @@ -244,7 +324,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && __state._M_matches(*this->_M_current)) if (__state._M_next != _S_invalid_state_id) if (__next.count(__state._M_next) == 0 - || _M_match_less_than(*__it.second, *__next[__state._M_next])) + || *__it.second < *__next[__state._M_next]) __next[__state._M_next] = move(__it.second); } _M_covered = move(__next); @@ -253,37 +333,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _BiIter, typename _Alloc, typename _CharT, typename _TraitsT> bool _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>:: - _M_match_less_than(const _ResultsVec& __u, const _ResultsVec& __v) const - { - // TODO: Greedy and Non-greedy support - _GLIBCXX_DEBUG_ASSERT(__u.size() == __v.size()); - auto __size = __u.size(); - for (auto __i = 0; __i < __size; __i++) - { - auto __uit = __u[__i], __vit = __v[__i]; - if (__uit.matched && !__vit.matched) - return true; - if (!__uit.matched && __vit.matched) - return false; - if (__uit.matched && __vit.matched) - { - // GREEDY - if (__uit.first != __vit.first) - return __uit.first < __vit.first; - if (__uit.second != __vit.second) - return __uit.second > __vit.second; - } - } - return false; - } - - template<typename _BiIter, typename _Alloc, - typename _CharT, typename _TraitsT> - bool _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>:: - _M_includes_some() const + _M_includes_some() { auto& __s = _M_nfa._M_final_states(); auto& __t = _M_covered; + bool __succ = false; if (__s.size() > 0 && __t.size() > 0) { auto __first = __s.begin(); @@ -292,16 +346,59 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (*__first < __second->first) ++__first; - else if (__second->first < *__first) + else if (*__first > __second->first) ++__second; else { - this->_M_results = *__second->second; - return true; + if (_M_cur_results == nullptr + || *__second->second < *_M_cur_results) + _M_cur_results = + _ResultsPtr(new _ResultsEntry(*__second->second)); + __succ = true; + ++__first; + ++__second; } } } - return false; + 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, @@ -320,9 +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, __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 080ef635b0c..09a18f634a0 100644 --- a/libstdc++-v3/include/bits/regex_scanner.h +++ b/libstdc++-v3/include/bits/regex_scanner.h @@ -68,8 +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_neg_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, @@ -84,8 +83,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_token_or, _S_token_closure0, _S_token_closure1, + _S_token_ungreedy, _S_token_line_begin, _S_token_line_end, + _S_token_word_bound, // neg if _M_value[0] == 'n' _S_token_comma, _S_token_dup_count, _S_token_eof, @@ -173,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 0d1d2cd9778..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 @@ -210,11 +210,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { ++_M_current; _M_token = _S_token_subexpr_lookahead_begin; + _M_value.assign(1, 'p'); } else if (*_M_current == '!') { ++_M_current; - _M_token = _S_token_subexpr_neg_lookahead_begin; + _M_token = _S_token_subexpr_lookahead_begin; + _M_value.assign(1, 'n'); } else __throw_regex_error(regex_constants::error_paren); @@ -370,10 +372,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_token = _S_token_ord_char; _M_value.assign(1, _M_escape_map.at(__c)); } + else if (__c == 'b') + { + _M_token = _S_token_word_bound; + _M_value.assign(1, 'p'); + } + else if (__c == 'B') + { + _M_token = _S_token_word_bound; + _M_value.assign(1, 'n'); + } // N3376 28.13 - else if (__c == 'b' - || __c == 'B' - || __c == 'd' + else if (__c == 'd' || __c == 'D' || __c == 's' || __c == 'S' @@ -579,9 +589,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION case _S_token_subexpr_lookahead_begin: ostr << "lookahead subexpr begin\n"; break; - case _S_token_subexpr_neg_lookahead_begin: - ostr << "neg lookahead subexpr begin\n"; - break; case _S_token_subexpr_end: ostr << "subexpr end\n"; break; diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index 9d6b466cf2e..b06211e0100 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -385,38 +385,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _DistanceType; _DistanceType __tailSize = __last - __first; - const _DistanceType __pattSize = __count; + _DistanceType __remainder = __count; - if (__tailSize < __pattSize) - return __last; - - const _DistanceType __skipOffset = __pattSize - 1; - _RandomAccessIter __lookAhead = __first + __skipOffset; - __tailSize -= __pattSize; - - while (1) // the main loop... + while (__remainder <= __tailSize) // the main loop... { - // __lookAhead here is always pointing to the last element of next - // possible match. - while (!(*__lookAhead == __val)) // the skip loop... - { - if (__tailSize < __pattSize) - return __last; // Failure - __lookAhead += __pattSize; - __tailSize -= __pattSize; - } - _DistanceType __remainder = __skipOffset; - for (_RandomAccessIter __backTrack = __lookAhead - 1; - *__backTrack == __val; --__backTrack) + __first += __remainder; + __tailSize -= __remainder; + // __first here is always pointing to one past the last element of + // next possible match. + _RandomAccessIter __backTrack = __first; + while (*--__backTrack == __val) { if (--__remainder == 0) - return (__lookAhead - __skipOffset); // Success + return (__first - __count); // Success } - if (__remainder > __tailSize) - return __last; // Failure - __lookAhead += __remainder; - __tailSize -= __remainder; + __remainder = __count + 1 - (__first - __backTrack); } + return __last; // Failure } // search_n @@ -478,38 +463,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _DistanceType; _DistanceType __tailSize = __last - __first; - const _DistanceType __pattSize = __count; + _DistanceType __remainder = __count; - if (__tailSize < __pattSize) - return __last; - - const _DistanceType __skipOffset = __pattSize - 1; - _RandomAccessIter __lookAhead = __first + __skipOffset; - __tailSize -= __pattSize; - - while (1) // the main loop... + while (__remainder <= __tailSize) // the main loop... { - // __lookAhead here is always pointing to the last element of next - // possible match. - while (!bool(__binary_pred(*__lookAhead, __val))) // the skip loop... - { - if (__tailSize < __pattSize) - return __last; // Failure - __lookAhead += __pattSize; - __tailSize -= __pattSize; - } - _DistanceType __remainder = __skipOffset; - for (_RandomAccessIter __backTrack = __lookAhead - 1; - __binary_pred(*__backTrack, __val); --__backTrack) + __first += __remainder; + __tailSize -= __remainder; + // __first here is always pointing to one past the last element of + // next possible match. + _RandomAccessIter __backTrack = __first; + while (__binary_pred(*--__backTrack, __val)) { if (--__remainder == 0) - return (__lookAhead - __skipOffset); // Success + return (__first - __count); // Success } - if (__remainder > __tailSize) - return __last; // Failure - __lookAhead += __remainder; - __tailSize -= __remainder; + __remainder = __count + 1 - (__first - __backTrack); } + return __last; // Failure } // find_end for forward iterators. diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index e1daac2ddda..1c889356460 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -611,7 +611,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * loop count will be known (and therefore a candidate for compiler * optimizations such as unrolling). * - * Result may not be in the range [first,last). Use copy instead. Note + * Result may not be in the range (first,last]. Use copy instead. Note * that the start of the output range may overlap [first,last). */ template<typename _BI1, typename _BI2> diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index a4656734469..98556f59848 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -108,7 +108,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; - static size_t _S_buffer_size() + static size_t _S_buffer_size() _GLIBCXX_NOEXCEPT { return __deque_buf_size(sizeof(_Tp)); } typedef std::random_access_iterator_tag iterator_category; @@ -125,31 +125,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Tp* _M_last; _Map_pointer _M_node; - _Deque_iterator(_Tp* __x, _Map_pointer __y) + _Deque_iterator(_Tp* __x, _Map_pointer __y) _GLIBCXX_NOEXCEPT : _M_cur(__x), _M_first(*__y), _M_last(*__y + _S_buffer_size()), _M_node(__y) { } - _Deque_iterator() + _Deque_iterator() _GLIBCXX_NOEXCEPT : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) { } - _Deque_iterator(const iterator& __x) + _Deque_iterator(const iterator& __x) _GLIBCXX_NOEXCEPT : _M_cur(__x._M_cur), _M_first(__x._M_first), _M_last(__x._M_last), _M_node(__x._M_node) { } iterator - _M_const_cast() const + _M_const_cast() const _GLIBCXX_NOEXCEPT { return iterator(_M_cur, _M_node); } reference - operator*() const + operator*() const _GLIBCXX_NOEXCEPT { return *_M_cur; } pointer - operator->() const + operator->() const _GLIBCXX_NOEXCEPT { return _M_cur; } _Self& - operator++() + operator++() _GLIBCXX_NOEXCEPT { ++_M_cur; if (_M_cur == _M_last) @@ -161,7 +161,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } _Self - operator++(int) + operator++(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; ++*this; @@ -169,7 +169,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } _Self& - operator--() + operator--() _GLIBCXX_NOEXCEPT { if (_M_cur == _M_first) { @@ -181,7 +181,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } _Self - operator--(int) + operator--(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; --*this; @@ -189,7 +189,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } _Self& - operator+=(difference_type __n) + operator+=(difference_type __n) _GLIBCXX_NOEXCEPT { const difference_type __offset = __n + (_M_cur - _M_first); if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) @@ -208,25 +208,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } _Self - operator+(difference_type __n) const + operator+(difference_type __n) const _GLIBCXX_NOEXCEPT { _Self __tmp = *this; return __tmp += __n; } _Self& - operator-=(difference_type __n) + operator-=(difference_type __n) _GLIBCXX_NOEXCEPT { return *this += -__n; } _Self - operator-(difference_type __n) const + operator-(difference_type __n) const _GLIBCXX_NOEXCEPT { _Self __tmp = *this; return __tmp -= __n; } reference - operator[](difference_type __n) const + operator[](difference_type __n) const _GLIBCXX_NOEXCEPT { return *(*this + __n); } /** @@ -235,7 +235,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * immediately afterwards, based on _M_first and _M_last. */ void - _M_set_node(_Map_pointer __new_node) + _M_set_node(_Map_pointer __new_node) _GLIBCXX_NOEXCEPT { _M_node = __new_node; _M_first = *__new_node; @@ -249,33 +249,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT { return __x._M_cur == __y._M_cur; } template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT { return __x._M_cur == __y._M_cur; } template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT { return !(__x == __y); } template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT { return !(__x == __y); } template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node); } @@ -283,47 +283,47 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typename _RefR, typename _PtrR> inline bool operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node); } template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT { return __y < __x; } template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT { return __y < __x; } template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT { return !(__y < __x); } template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT { return !(__y < __x); } template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT { return !(__x < __y); } template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT { return !(__x < __y); } // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -333,7 +333,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp, typename _Ref, typename _Ptr> inline typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type operator-(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT { return typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type (_Deque_iterator<_Tp, _Ref, _Ptr>::_S_buffer_size()) @@ -345,7 +345,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typename _RefR, typename _PtrR> inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT { return typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) @@ -356,6 +356,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp, typename _Ref, typename _Ptr> inline _Deque_iterator<_Tp, _Ref, _Ptr> operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) + _GLIBCXX_NOEXCEPT { return __x + __n; } template<typename _Tp> @@ -466,7 +467,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Deque_base(const allocator_type& __a) : _M_impl(__a) - { } + { _M_initialize_map(0); } #if __cplusplus >= 201103L _Deque_base(_Deque_base&& __x) @@ -483,7 +484,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } #endif - ~_Deque_base(); + ~_Deque_base() _GLIBCXX_NOEXCEPT; protected: //This struct encapsulates the implementation of the std::deque @@ -506,13 +507,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_start(), _M_finish() { } - _Deque_impl(const _Tp_alloc_type& __a) + _Deque_impl(const _Tp_alloc_type& __a) _GLIBCXX_NOEXCEPT : _Tp_alloc_type(__a), _M_map(0), _M_map_size(0), _M_start(), _M_finish() { } #if __cplusplus >= 201103L - _Deque_impl(_Tp_alloc_type&& __a) + _Deque_impl(_Tp_alloc_type&& __a) _GLIBCXX_NOEXCEPT : _Tp_alloc_type(std::move(__a)), _M_map(0), _M_map_size(0), _M_start(), _M_finish() { } @@ -538,7 +539,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } void - _M_deallocate_node(_Tp* __p) + _M_deallocate_node(_Tp* __p) _GLIBCXX_NOEXCEPT { _M_impl._Tp_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp))); } @@ -548,13 +549,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { return _M_get_map_allocator().allocate(__n); } void - _M_deallocate_map(_Tp** __p, size_t __n) + _M_deallocate_map(_Tp** __p, size_t __n) _GLIBCXX_NOEXCEPT { _M_get_map_allocator().deallocate(__p, __n); } protected: void _M_initialize_map(size_t); void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); - void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); + void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) _GLIBCXX_NOEXCEPT; enum { _S_initial_map_size = 8 }; _Deque_impl _M_impl; @@ -562,7 +563,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp, typename _Alloc> _Deque_base<_Tp, _Alloc>:: - ~_Deque_base() + ~_Deque_base() _GLIBCXX_NOEXCEPT { if (this->_M_impl._M_map) { @@ -640,7 +641,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp, typename _Alloc> void _Deque_base<_Tp, _Alloc>:: - _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) + _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) _GLIBCXX_NOEXCEPT { for (_Tp** __n = __nstart; __n < __nfinish; ++__n) _M_deallocate_node(*__n); @@ -758,7 +759,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER protected: typedef pointer* _Map_pointer; - static size_t _S_buffer_size() + static size_t _S_buffer_size() _GLIBCXX_NOEXCEPT { return __deque_buf_size(sizeof(_Tp)); } // Functions controlling memory layout, and nothing else. @@ -781,18 +782,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // [23.2.1.1] construct/copy/destroy // (assign() and get_allocator() are also listed in this section) /** - * @brief Default constructor creates no elements. - */ - deque() - : _Base() { } - - /** * @brief Creates a %deque with no elements. * @param __a An allocator object. */ explicit - deque(const allocator_type& __a) - : _Base(__a, 0) { } + deque(const allocator_type& __a = allocator_type()) + : _Base(__a) { } #if __cplusplus >= 201103L /** @@ -940,7 +935,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * @a __x is a valid, but unspecified %deque. */ deque& - operator=(deque&& __x) + operator=(deque&& __x) noexcept { // NB: DR 1204. // NB: DR 675. @@ -1220,7 +1215,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER #if __cplusplus >= 201103L /** A non-binding request to reduce memory use. */ void - shrink_to_fit() + shrink_to_fit() noexcept { _M_shrink_to_fit(); } #endif @@ -1245,7 +1240,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * see at().) */ reference - operator[](size_type __n) + operator[](size_type __n) _GLIBCXX_NOEXCEPT { return this->_M_impl._M_start[difference_type(__n)]; } /** @@ -1260,7 +1255,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[difference_type(__n)]; } protected: @@ -1314,7 +1309,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * element of the %deque. */ reference - front() + front() _GLIBCXX_NOEXCEPT { return *begin(); } /** @@ -1322,7 +1317,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * element of the %deque. */ const_reference - front() const + front() const _GLIBCXX_NOEXCEPT { return *begin(); } /** @@ -1330,7 +1325,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * %deque. */ reference - back() + back() _GLIBCXX_NOEXCEPT { iterator __tmp = end(); --__tmp; @@ -1342,7 +1337,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * element of the %deque. */ const_reference - back() const + back() const _GLIBCXX_NOEXCEPT { const_iterator __tmp = end(); --__tmp; @@ -1422,7 +1417,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * needed, it should be retrieved before pop_front() is called. */ void - pop_front() + pop_front() _GLIBCXX_NOEXCEPT { if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_last - 1) @@ -1443,7 +1438,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * needed, it should be retrieved before pop_back() is called. */ void - pop_back() + pop_back() _GLIBCXX_NOEXCEPT { if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_first) @@ -1655,7 +1650,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * std::swap(d1,d2) will feed to this function. */ void - swap(deque& __x) + swap(deque& __x) _GLIBCXX_NOEXCEPT { std::swap(this->_M_impl._M_start, __x._M_impl._M_start); std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 9952c2c92d6..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[](const difference_type& __n) const + operator[](difference_type __n) const _GLIBCXX_NOEXCEPT { return _M_current[__n]; } __normal_iterator& - operator+=(const difference_type& __n) + operator+=(difference_type __n) _GLIBCXX_NOEXCEPT { _M_current += __n; return *this; } __normal_iterator - operator+(const difference_type& __n) const + operator+(difference_type __n) const _GLIBCXX_NOEXCEPT { return __normal_iterator(_M_current + __n); } __normal_iterator& - operator-=(const difference_type& __n) + operator-=(difference_type __n) _GLIBCXX_NOEXCEPT { _M_current -= __n; return *this; } __normal_iterator - operator-(const 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/deque b/libstdc++-v3/include/debug/deque index e5e902dfc7b..3984f11ac6b 100644 --- a/libstdc++-v3/include/debug/deque +++ b/libstdc++-v3/include/debug/deque @@ -128,7 +128,7 @@ namespace __debug #if __cplusplus >= 201103L deque& - operator=(deque&& __x) + operator=(deque&& __x) noexcept { // NB: DR 1204. // NB: DR 675. @@ -287,7 +287,7 @@ namespace __debug #if __cplusplus >= 201103L void - shrink_to_fit() + shrink_to_fit() noexcept { if (_Base::_M_shrink_to_fit()) this->_M_invalidate_all(); @@ -298,14 +298,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]; @@ -314,28 +314,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(); @@ -468,7 +468,7 @@ namespace __debug #endif void - pop_front() + pop_front() _GLIBCXX_NOEXCEPT { __glibcxx_check_nonempty(); this->_M_invalidate_if(_Equal(_Base::begin())); @@ -476,7 +476,7 @@ namespace __debug } void - pop_back() + pop_back() _GLIBCXX_NOEXCEPT { __glibcxx_check_nonempty(); this->_M_invalidate_if(_Equal(--_Base::end())); @@ -556,7 +556,7 @@ namespace __debug } void - swap(deque& __x) + swap(deque& __x) _GLIBCXX_NOEXCEPT { _Base::swap(__x); this->_M_swap(__x); 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/sso_string_base.h b/libstdc++-v3/include/ext/sso_string_base.h index 9e5b50e6e24..6cb4302b688 100644 --- a/libstdc++-v3/include/ext/sso_string_base.h +++ b/libstdc++-v3/include/ext/sso_string_base.h @@ -361,9 +361,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_capacity(__rcs._M_allocated_capacity); } - _M_length(__rcs._M_length()); - __rcs._M_length(0); + _M_set_length(__rcs._M_length()); __rcs._M_data(__rcs._M_local_data); + __rcs._M_set_length(0); } #endif 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/deque b/libstdc++-v3/include/profile/deque index c46618e27e4..52d474d4c11 100644 --- a/libstdc++-v3/include/profile/deque +++ b/libstdc++-v3/include/profile/deque @@ -117,7 +117,7 @@ namespace __profile #if __cplusplus >= 201103L deque& - operator=(deque&& __x) + operator=(deque&& __x) noexcept { // NB: DR 1204. // NB: DR 675. @@ -245,13 +245,13 @@ namespace __profile // element access: reference - operator[](size_type __n) + operator[](size_type __n) _GLIBCXX_NOEXCEPT { return _M_base()[__n]; } const_reference - operator[](size_type __n) const + operator[](size_type __n) const _GLIBCXX_NOEXCEPT { return _M_base()[__n]; } @@ -259,25 +259,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(); } @@ -375,13 +375,13 @@ namespace __profile #endif void - pop_front() + pop_front() _GLIBCXX_NOEXCEPT { _Base::pop_front(); } void - pop_back() + pop_back() _GLIBCXX_NOEXCEPT { _Base::pop_back(); } @@ -409,7 +409,7 @@ namespace __profile } void - swap(deque& __x) + swap(deque& __x) _GLIBCXX_NOEXCEPT { _Base::swap(__x); } 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/deque/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc index 7558ac7d855..a0bdcdb53f8 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1760 } +// { dg-error "no matching" "" { target *-*-* } 1755 } #include <deque> diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc index ee6b721d9d3..86d7016e616 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1693 } +// { dg-error "no matching" "" { target *-*-* } 1688 } #include <deque> diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc index d36964efa4e..84be8ebda5e 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1693 } +// { dg-error "no matching" "" { target *-*-* } 1688 } #include <deque> #include <utility> diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc index cda684d29f5..26e5c290013 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1844 } +// { dg-error "no matching" "" { target *-*-* } 1839 } #include <deque> 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/23_containers/list/operations/5.cc b/libstdc++-v3/testsuite/24_iterators/normal_iterator/58403.cc index fbb55b3ea3c..0c7e281af16 100644 --- a/libstdc++-v3/testsuite/23_containers/list/operations/5.cc +++ b/libstdc++-v3/testsuite/24_iterators/normal_iterator/58403.cc @@ -1,6 +1,7 @@ -// 2006-01-19 Paolo Carlini <pcarlini@suse.de> +// { dg-options "-std=gnu++11" } +// { dg-do link } -// Copyright (C) 2006-2013 Free Software Foundation, Inc. +// 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 @@ -17,15 +18,17 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. -#include "5.h" -#include <list> +#include <string> +#include <iterator> + +struct A { + static constexpr std::iterator_traits< + std::string::iterator>::difference_type a = 1; +}; 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; + std::string s = "foo"; + auto it = s.begin(); + it += A::a; } diff --git a/libstdc++-v3/testsuite/25_algorithms/search_n/58358.cc b/libstdc++-v3/testsuite/25_algorithms/search_n/58358.cc new file mode 100644 index 00000000000..b5ae34617f9 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/search_n/58358.cc @@ -0,0 +1,41 @@ +// 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/>. + +// { dg-options "-std=gnu++11" } + +// 25.1.9 [lib.alg.search] + +#include <algorithm> +#include <vector> +#include <testsuite_hooks.h> + +void test01() +{ + bool test __attribute__((unused)) = true; + + std::vector<int> a{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + int count = 0; + std::search_n(a.begin(), a.end(), 10, 1, + [&count](int t, int u) { ++count; return t == u; }); + VERIFY( count <= 11 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/search_n/iterator.cc b/libstdc++-v3/testsuite/25_algorithms/search_n/iterator.cc index 27cffe74116..10616960dc2 100644 --- a/libstdc++-v3/testsuite/25_algorithms/search_n/iterator.cc +++ b/libstdc++-v3/testsuite/25_algorithms/search_n/iterator.cc @@ -31,9 +31,11 @@ int array1[11] = {0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0}; int array2[TEST_DEPTH]; +int pred_count; bool pred(int i, int j) { + ++pred_count; return i == j; } @@ -90,16 +92,22 @@ int main() int* t1 = search_n(forwardcon.begin(), forwardcon.end(), j, 1).ptr; + pred_count = 0; int* t2 = search_n(forwardcon.begin(), forwardcon.end(), j, 1, pred).ptr; + VERIFY(pred_count <= i); int* t3 = search_n(bidircon.begin(), bidircon.end(), j, 1).ptr; + pred_count = 0; int* t4 = search_n(bidircon.begin(), bidircon.end(), j, 1, pred).ptr; + VERIFY(pred_count <= i); int* t5 = search_n(randomcon.begin(), randomcon.end(), j, 1).ptr; + pred_count = 0; int* t6 = search_n(randomcon.begin(), randomcon.end(), j, 1, pred).ptr; + VERIFY(pred_count <= i); VERIFY((t1 == t2) && (t2 == t3) && (t3 == t4) && (t4 == t5) && (t5 == t6)); } diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc index 5d43d7c4354..91bc101392b 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc @@ -1,5 +1,4 @@ // { dg-options "-std=c++0x" } -// { dg-do run { xfail *-*-* } } // // 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca> diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc new file mode 100644 index 00000000000..b54f5619a24 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc @@ -0,0 +1,52 @@ +// { dg-options "-std=gnu++11" } + +// +// 2013-09-05 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.2 regex_match +// Tests ECMAScript \d \D \s \S \w \W + +#include <regex> +#include <testsuite_hooks.h> + +using namespace std; + +void +test01() +{ + bool test __attribute__((unused)) = true; + + VERIFY(regex_match("01", regex("\\d*"))); + VERIFY(regex_match("asdfjkl", regex("\\D*"))); + VERIFY(!regex_match("asdfjkl0", regex("\\D*"))); + VERIFY(regex_match("\r\t\v\f ", regex("\\s*"))); + VERIFY(regex_match("asdfjkl", regex("\\S*"))); + VERIFY(!regex_match("asdfjkl\r", regex("\\S*"))); + VERIFY(regex_match("_az", regex("\\w*"))); + VERIFY(regex_match("!@#$%", regex("\\W*"))); + VERIFY(!regex_match("_01234", regex("\\W*"))); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc index 67bc1d8a5c2..375f34b8064 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc @@ -1,5 +1,4 @@ // { dg-options "-std=c++0x" } -// { dg-do run { xfail *-*-* } } // // 2010-06-21 Stephen M. Webb <stephen.webb@bregmasoft.ca> @@ -32,27 +31,31 @@ test01() { bool test __attribute__((unused)) = true; - std::regex re("(a+)", std::regex::extended); - const char target[] = "aa"; - std::cmatch m; + std::regex re("(a+)", std::regex::extended); + const char target[] = "aa"; + std::cmatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( std::regex_match(target, m, re) ); - VERIFY( re.mark_count() == 1 ); - VERIFY( m.size() == re.mark_count()+1 ); - VERIFY( m.empty() == false ); - VERIFY( m.prefix().first == target ); - VERIFY( m.prefix().second == target ); - VERIFY( m.prefix().matched == false ); - VERIFY( m.suffix().first == target+sizeof(target) ); - VERIFY( m.suffix().second == target+sizeof(target) ); - VERIFY( m.suffix().matched == false ); - VERIFY( m[0].first == target ); - VERIFY( m[0].second == target+sizeof(target) ); - VERIFY( m[0].matched == true ); - VERIFY( m[1].first == target ); - VERIFY( m[1].second == target+sizeof(target) ); - VERIFY( m[1].matched == true ); + VERIFY( re.mark_count() == 1 ); + VERIFY( m.size() == re.mark_count()+1 ); + VERIFY( m.empty() == false ); + VERIFY( m.prefix().first == target ); + VERIFY( m.prefix().second == target ); + VERIFY( m.prefix().matched == false ); + VERIFY( m.suffix().first == target+sizeof(target)-1 ); + VERIFY( m.suffix().second == target+sizeof(target)-1 ); + VERIFY( m.suffix().matched == false ); + VERIFY( m[0].first == target ); + VERIFY( m[0].second == target+sizeof(target)-1 ); + VERIFY( m[0].matched == true ); + VERIFY( m[1].first == target ); + VERIFY( m[1].second == target+sizeof(target)-1 ); + VERIFY( m[1].matched == true ); + + VERIFY(!std::regex_match("", std::regex("a+", std::regex::extended))); + VERIFY(std::regex_match("a", std::regex("a+", std::regex::extended))); + VERIFY(std::regex_match("aa", std::regex("a+", std::regex::extended))); } diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc index c0c8b92965b..79b52a88c4f 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc @@ -1,5 +1,4 @@ // { dg-options "-std=c++0x" } -// { dg-do run { xfail *-*-* } } // // 2010-06-21 Stephen M. Webb <stephen.webb@bregmasoft.ca> @@ -32,27 +31,31 @@ test01() { bool test __attribute__((unused)) = true; - std::regex re("(aa?)", std::regex::extended); - char target[] = "a"; - std::cmatch m; + std::regex re("(aa?)", std::regex::extended); + char target[] = "a"; + std::cmatch m; - VERIFY( std::regex_match(target, m, re) ); + VERIFY( std::regex_match(target, m, re) ); - VERIFY( re.mark_count() == 1 ); - VERIFY( m.size() == re.mark_count()+1 ); - VERIFY( m.empty() == false ); - VERIFY( m.prefix().first == target ); - VERIFY( m.prefix().second == target ); - VERIFY( m.prefix().matched == false ); - VERIFY( m.suffix().first == target+sizeof(target) ); - VERIFY( m.suffix().second == target+sizeof(target) ); - VERIFY( m.suffix().matched == false ); - VERIFY( m[0].first == target ); - VERIFY( m[0].second == target+sizeof(target) ); - VERIFY( m[0].matched == true ); - VERIFY( m[1].first == target ); - VERIFY( m[1].second == target+sizeof(target) ); - VERIFY( m[1].matched == true ); + VERIFY( re.mark_count() == 1 ); + VERIFY( m.size() == re.mark_count()+1 ); + VERIFY( m.empty() == false ); + VERIFY( m.prefix().first == target ); + VERIFY( m.prefix().second == target ); + VERIFY( m.prefix().matched == false ); + VERIFY( m.suffix().first == target+sizeof(target)-1 ); + VERIFY( m.suffix().second == target+sizeof(target)-1 ); + VERIFY( m.suffix().matched == false ); + VERIFY( m[0].first == target ); + VERIFY( m[0].second == target+sizeof(target)-1 ); + VERIFY( m[0].matched == true ); + VERIFY( m[1].first == target ); + VERIFY( m[1].second == target+sizeof(target)-1 ); + VERIFY( m[1].matched == true ); + + VERIFY(std::regex_match("", std::regex("a?", std::regex::extended))); + VERIFY(std::regex_match("a", std::regex("a?", std::regex::extended))); + VERIFY(!std::regex_match("aa", std::regex("a?", std::regex::extended))); } diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc new file mode 100644 index 00000000000..62f825a0fb9 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc @@ -0,0 +1,68 @@ +// { dg-options "-std=gnu++11" } + +// +// 2013-09-05 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.2 regex_match +// Tests Extended interval range. + +#include <regex> +#include <testsuite_hooks.h> + +using namespace std; + +void +test01() +{ + bool test __attribute__((unused)) = true; + + regex re; + re.assign("(ab){3}", std::regex::extended); + VERIFY(!regex_match("abab", re)); + VERIFY(regex_match("ababab", re)); + VERIFY(!regex_match("abababab", re)); + re.assign("(ab){3,}", std::regex::extended); + VERIFY(!regex_match("abab", re)); + VERIFY(regex_match("ababab", re)); + VERIFY(regex_match("abababab", re)); + VERIFY(regex_match("ababababab", re)); + re.assign("(ab){0,3}", std::regex::extended); + VERIFY(regex_match("", re)); + VERIFY(regex_match("ab", re)); + VERIFY(regex_match("abab", re)); + VERIFY(regex_match("ababab", re)); + VERIFY(!regex_match("abababab", re)); + re.assign("(a|b){0,2}", std::regex::extended); + VERIFY(regex_match("", re)); + VERIFY(regex_match("a", re)); + VERIFY(regex_match("b", re)); + VERIFY(regex_match("aa", re)); + VERIFY(regex_match("ab", re)); + VERIFY(regex_match("ba", re)); + VERIFY(regex_match("bb", re)); + VERIFY(!regex_match("aaa", re)); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc index 180c35962e1..e10dba81ffa 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc @@ -31,23 +31,23 @@ test01() { bool test __attribute__((unused)) = true; - std::regex re("a{0,3}", std::regex::extended); - std::string target("aa"); - std::smatch m; - - VERIFY( std::regex_match(target, m, re) ); - - VERIFY( m.size() == re.mark_count()+1 ); - VERIFY( m.empty() == false ); - VERIFY( m.prefix().first == target.begin() ); - VERIFY( m.prefix().second == target.begin() ); - VERIFY( m.prefix().matched == false ); - VERIFY( m.suffix().first == target.end() ); - VERIFY( m.suffix().second == target.end() ); - VERIFY( m.suffix().matched == false ); - VERIFY( m[0].first == target.begin() ); - VERIFY( m[0].second == target.end() ); - VERIFY( m[0].matched == true ); + std::regex re("a{0,3}", std::regex::extended); + std::string target("aa"); + std::smatch m; + + VERIFY( std::regex_match(target, m, re) ); + + VERIFY( m.size() == re.mark_count()+1 ); + VERIFY( m.empty() == false ); + VERIFY( m.prefix().first == target.begin() ); + VERIFY( m.prefix().second == target.begin() ); + VERIFY( m.prefix().matched == false ); + VERIFY( m.suffix().first == target.end() ); + VERIFY( m.suffix().second == target.end() ); + VERIFY( m.suffix().matched == false ); + VERIFY( m[0].first == target.begin() ); + VERIFY( m[0].second == target.end() ); + VERIFY( m[0].matched == true ); } diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc index 532869d1341..62793b4a199 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc @@ -1,5 +1,4 @@ // { dg-options "-std=c++0x" } -// { dg-do run { xfail *-*-* } } // // 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca> 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 new file mode 100644 index 00000000000..3064b3b26e4 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc @@ -0,0 +1,94 @@ +// { dg-options "-std=gnu++11" } + +// +// 2013-09-14 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 assertion. + +#include <regex> +#include <testsuite_hooks.h> + +using namespace std; + +void +test01() +{ + bool test __attribute__((unused)) = true; + + VERIFY(!regex_search("2123456", regex("^1234"))); + VERIFY(regex_search("123456", regex("^1234"))); + VERIFY(regex_search("123456", regex("(5|^)1234"))); + VERIFY(regex_search("5123456", regex("(5|^)1234"))); + VERIFY(!regex_search("1234562", regex("3456$"))); + VERIFY(regex_search("123456", regex("3456$"))); + VERIFY(!regex_search("123456", regex("(?=1234)56"))); + VERIFY(regex_search("123456", regex("(?=1234)123456"))); + VERIFY(regex_search("123456", regex("(?!1234)56"))); + VERIFY(!regex_search("123456", regex("(?!1234)123456"))); + + VERIFY(regex_search("a-", regex("a\\b-"))); + VERIFY(!regex_search("ab", regex("a\\bb"))); + VERIFY(!regex_search("a-", regex("a\\B-"))); + VERIFY(regex_search("ab", regex("a\\Bb"))); + + string s("This is a regular expression"); + 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(); + ++it) + { + string s((*it)[0].first, (*it)[0].second); + VERIFY(s == sol[i++]); + } + 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 +main() +{ + test01(); + return 0; +} 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/algorithms/regex_search/ecma/greedy.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc new file mode 100644 index 00000000000..ad37ec8649a --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc @@ -0,0 +1,71 @@ +// { dg-options "-std=gnu++11" } + +// +// 2013-09-14 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 greedy and ungreedy quantifiers. + +#include <regex> +#include <testsuite_hooks.h> + +using namespace std; + +void +test01() +{ + bool test __attribute__((unused)) = true; + + cmatch m; +#define TEST(i, s) VERIFY(m[i].matched && string(m[i].first, m[i].second) == s) + VERIFY(regex_search("aaaa", m, regex("a*"))); + TEST(0, "aaaa"); + VERIFY(regex_search("aaaa", m, regex("a*?"))); + TEST(0, ""); + VERIFY(regex_search("aaaa", m, regex("a+"))); + TEST(0, "aaaa"); + VERIFY(regex_search("aaaa", m, regex("a+?"))); + TEST(0, "a"); + VERIFY(regex_search("a", m, regex("a?"))); + TEST(0, "a"); + VERIFY(regex_search("a", m, regex("a??"))); + TEST(0, ""); + VERIFY(regex_search("", m, regex("a??"))); + TEST(0, ""); + VERIFY(regex_search("aaaa", m, regex("(a+)(a+)"))); + TEST(1, "aaa"); + TEST(2, "a"); + VERIFY(regex_search("aaaa", m, regex("(a+?)(a+)"))); + TEST(1, "a"); + TEST(2, "aaa"); + VERIFY(regex_search("aaaa", m, regex("(a+?)(a+)"))); + TEST(1, "a"); + TEST(2, "aaa"); + VERIFY(regex_search("aaaa", m, regex("(a+?)(a+?)"))); + TEST(1, "a"); + TEST(2, "a"); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc index a2d290db283..ec25875fdee 100644 --- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc +++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc @@ -21,7 +21,7 @@ // <http://www.gnu.org/licenses/>. // 28.11.3 regex_search -// Tests BRE against a std::string target. +// Tests ECMAScript against a std::string target. #include <regex> #include <testsuite_hooks.h> 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 new file mode 100644 index 00000000000..9cb96f7a162 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc @@ -0,0 +1,64 @@ +// { dg-options "-std=gnu++11" } +// { dg-require-namedlocale "en_US.UTF-8" } + +// +// 2013-09-05 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.12.1 regex_iterator +// Tests regex_iterator class + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::setlocale(LC_ALL, "en_US.UTF-8"); + + std::wstring str2 = L"ä\u2009Ä\u2009ö\u2009Ö\u2009ü\u2009Ãœ"; + + std::wregex re2; + re2.imbue(std::locale("en_US.UTF-8")); + + re2.assign(L"([[:lower:]]{0,1}[[:space:]]{0,1}[[:upper:]]{0,1})"); + + 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 +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/value.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/value.cc index e68dac64e03..6d5885cc627 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/value.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/value.cc @@ -25,20 +25,20 @@ #include <regex> #include <testsuite_hooks.h> -// Tests the value() function of the regex_traits<char> class. +// Tests the value() function of the regex_traits<wchar_t> class. void test01() { bool test __attribute__((unused)) = true; - std::regex_traits<char> t; - VERIFY( t.value('7', 8) == 7 ); - VERIFY( t.value('7', 10) == 7 ); - VERIFY( t.value('7', 16) == 7 ); - VERIFY( t.value('9', 8) == -1 ); - VERIFY( t.value('9', 10) == 9 ); - VERIFY( t.value('9', 16) == 9 ); - VERIFY( t.value('d', 8) == -1 ); - VERIFY( t.value('d', 10) == -1 ); - VERIFY( t.value('d', 16) == 13 ); + std::regex_traits<wchar_t> t; + VERIFY( t.value(L'7', 8) == 7 ); + VERIFY( t.value(L'7', 10) == 7 ); + VERIFY( t.value(L'7', 16) == 7 ); + VERIFY( t.value(L'9', 8) == -1 ); + VERIFY( t.value(L'9', 10) == 9 ); + VERIFY( t.value(L'9', 16) == 9 ); + VERIFY( t.value(L'd', 8) == -1 ); + VERIFY( t.value(L'd', 10) == -1 ); + VERIFY( t.value(L'd', 16) == 13 ); } int diff --git a/libstdc++-v3/testsuite/ext/vstring/cons/58415-1.cc b/libstdc++-v3/testsuite/ext/vstring/cons/58415-1.cc new file mode 100644 index 00000000000..cfcb8938e26 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/vstring/cons/58415-1.cc @@ -0,0 +1,41 @@ +// { dg-options "-std=gnu++11" } +// { dg-require-string-conversions "" } + +// 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/>. + +#include <ext/vstring.h> +#include <testsuite_hooks.h> + +typedef __gnu_cxx::__versa_string<char> string; + +void test01() +{ + bool test __attribute__((unused)) = true; + + string s1("string"); + string s2(""); + std::swap(s1, s2); + + VERIFY( s1.c_str()[0] == '\0' ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/ext/vstring/cons/58415-2.cc b/libstdc++-v3/testsuite/ext/vstring/cons/58415-2.cc new file mode 100644 index 00000000000..9ba192ab228 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/vstring/cons/58415-2.cc @@ -0,0 +1,38 @@ +// { dg-options "-std=gnu++11" } +// { dg-require-string-conversions "" } + +// 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/>. + +#include <ext/vstring.h> +#include <testsuite_hooks.h> + +typedef __gnu_cxx::__versa_string<char> string; + +void test01() +{ + string s1; + string s2 = std::move(s1); + + VERIFY( s2.c_str()[0] == '\0' ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp index 83a3862fbd0..0dff98caa66 100644 --- a/libstdc++-v3/testsuite/lib/libstdc++.exp +++ b/libstdc++-v3/testsuite/lib/libstdc++.exp @@ -283,7 +283,7 @@ proc libstdc++_init { testfile } { v3track cxxflags 2 # Always use MO files built by this test harness. - set cxxflags "$cxxflags -DLOCALEDIR=\".\"" + set cxxflags "-fdiagnostics-color=never $cxxflags -DLOCALEDIR=\".\"" set ccflags "$cxxflags -DLOCALEDIR=\".\"" # If a PCH file is available, use it. We must delay performing 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); } diff --git a/libtool.m4 b/libtool.m4 index 8a14e2b22f9..797468f02a5 100644 --- a/libtool.m4 +++ b/libtool.m4 @@ -1220,7 +1220,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -1241,7 +1241,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -1260,7 +1263,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) diff --git a/libvtv/ChangeLog b/libvtv/ChangeLog index c9a1cc3590e..9125287d898 100644 --- a/libvtv/ChangeLog +++ b/libvtv/ChangeLog @@ -1,3 +1,112 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + +2013-09-12 Alexander Ivchenko <alexander.ivchenko@intel.com> + + * configure.tgt: Remove *-*-*android* from supported targets. + +2013-09-09 H.J. Lu <hongjiu.lu@intel.com> + + PR other/58374 + * configure.ac: Move VTV_SUPPORTED check after AC_CANONICAL_SYSTEM. + * configure: Regenerated. + +2013-09-08 Caroline Tice <cmtice@google.com> + + * testsuite/event-main.cc: Move to libvtv.cc subdirectory. + * testsuite/environment.cc: Ditto. + * testsuite/template-list2.cc: Ditto. + * testsuite/event.h: Ditto. + * testsuite/dataentry.cc: Ditto. + * testsuite/event-private.h: Ditto. + * testsuite/virtual_inheritance.cc: Ditto. + * testsuite/povray-derived.cc: Ditto. + * testsuite/nested_vcall_test.cc: Ditto. + * testsuite/template-list-iostream.cc: Ditto. + * testsuite/parts-test-extra-parts-views.h: Ditto. + * testsuite/virtfunc-test.cc: Ditto. + * testsuite/parts-test-extra-parts.h: Ditto. + * testsuite/const_vtable.cc: Ditto. + * testsuite/template-list.cc: Ditto. + * testsuite/dup_name.cc: Ditto. + * testsuite/thunk.cc: Ditto. + * testsuite/parts-test-main.h: Ditto. + * testsuite/mul_inh.cc: Ditto. + * testsuite/test1.cc: Ditto. + * testsuite/bb_tests.cc: Ditto. + * testsuite/v8-test-2.cc: Ditto. + * testsuite/thunk_vtable_map_attack.cc: Ditto. + * testsuite/xlan-test.cc: Ditto. + * testsuite/parts-test-main.cpp: Move to libvtv.cc subdirectory and + change file extension from .cc to .cpp. + * testsuite/event-definitions.cpp: Ditto. + * testsuite/event-main.cpp: Ditto. + * testsuite/derived-main.cpp: Ditto. + * testsuite/derived-lib.cpp: Ditto. + * testsuite/event-private.cpp: Ditto. + * testsuite/parts-test-extra-parts-views.cpp: Ditto. + * testsuite/parts-test-extra-parts.cpp: Ditto. + * testsuite/parts-test.list: Move to libvtv.cc subdirectory. Change + file extensions inside file from .cc to .cpp. + * testsuite/event.list: Ditto. + * testsuite/derived.list: Ditto. + * testsuite/register_pair.cc: Move to libvtv.cc; rename file to + register_set_pair.cc; include stdlib.h, stdio.h stdint.h string.h + (KEY_TYPE_FIXED_SIZE): New define. + (key_buffer, name_string, fake_names): New global variables. + (generate_names): New function. + (vtv_string_hans): New function. + (main): Add call to generate_names. Update middle for-loop to + initialize new parameters for __VLTRegisterPair... calls; move calls + to __VLTRegisterPair... to middle for-loop. Add calls to + __VLTRegisterSet... + * testsuite/register_pair_mt.cc: Ditto; renamed to + register_set_pair_mt.cc + * testsuite/libvtv.cc/vtv.exp: New file. + * testsuite/libvtv.mempool.cc/mempool.exp: New file. + * testsuite/libvtv.mt.cc/mt.exp: New file. + * testsuite/lib/libvtv.exp: New file. + * testsuite/lib/libvtv-dg.exp: New file. + * testsuite/config/default.exp: New file. + * testsuite/Makefile.am: New file. (Old file was moved to other-tests + subdirectory.) + * testsuite/Makefile.in: New file (generated). + * testsuite/mempool_negative.c: Change to C++ file; move to + libvtv.mempool.cc; include vtv-change-permission.h. + (main): Add call to __VLTChangePermission. + * testsuite/mempool_positive.c: Change to C++ file; move to + libvtv.mempool.cc; include vtv-change-permission.h. + (main): Add call to __VLTChangePermission. + * testsuite/temp_deriv3.cc: Move to other-tests subdirectory. + * testsuite/environment-fail-64.s: Ditto. + * testsutite/dlopen.cc: Ditto. + * testsuite/so.cc: Ditto. + * testsuite/temp_deriv2.cc: Ditto. + * testsuite/field-test.cc: Ditto. + * testsuite/dlopen_mt.cc: Ditto. + * testsuite/environment-fail-32.s: Ditto. + * testsuite/temp_deriv.cc: Ditto. + * testsuite/replace-fail.cc: Ditto. + * testsuite/other-tests/Makefile.am: New file. Copied from the + Makefile.am that used to be in testsuite directory. + * testsuite/other-tests/Makefile.in: Generated. (New file). + * testsuite/other-tests/README: New file. + +2013-09-07 Paolo Carlini <paolo.carlini@oracle.com> + + * testsuite/Makefile.am: Remove #if ENABLE_VTABLE_VERIFY check around + definition of check-am:. + * testsuite/Makefile.in: Regenerate. + +2013-09-06 Caroline Tice <cmtice@google.com> + + * Makefile.am: Remove #if ENABLE_VTABLE_VERIFY checks around + definitions of SUBDIRS, libvtv_la_SOURCES and libvtv_include_HEADERS. + * Makefile.in: Regenerate. + * configure.ac: Remove checks and tests for --enable-vtable-verify. + * configure: Regenerate. + 2013-08-20 Caroline Tice <cmtice@google.com> * Makefile.am (DEFS): Add "@DEFS@", to inherit defintions. diff --git a/libvtv/Makefile.am b/libvtv/Makefile.am index 567bd81e5b6..c3983effb7d 100644 --- a/libvtv/Makefile.am +++ b/libvtv/Makefile.am @@ -19,11 +19,7 @@ ## along with this library; see the file COPYING3. If not see ## <http://www.gnu.org/licenses/>. -if ENABLE_VTABLE_VERIFY SUBDIRS = testsuite -else -SUBDIRS = -endif ACLOCAL_AMFLAGS = -I .. -I ../config @@ -67,13 +63,8 @@ vtv_end.c: rm -f $@ $(LN_S) $(toplevel_srcdir)/libgcc/vtv_end.c $@ -if ENABLE_VTABLE_VERIFY libvtv_la_SOURCES = $(vtv_sources) libvtv_include_HEADERS = $(vtv_headers) -else -libvtv_la_SOURCES = -libvtv_include_HEADERS = -endif # Least ordering for dependencies mean linking w/o libstdc++ for as # long as the development of libvtv does not absolutely require it. diff --git a/libvtv/Makefile.in b/libvtv/Makefile.in index a1b71bfabcd..e021d42fd14 100644 --- a/libvtv/Makefile.in +++ b/libvtv/Makefile.in @@ -40,7 +40,7 @@ subdir = . DIST_COMMON = ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/configure $(am__configure_deps) \ $(srcdir)/../mkinstalldirs $(srcdir)/../depcomp \ - $(am__libvtv_include_HEADERS_DIST) + $(libvtv_include_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ $(top_srcdir)/../config/depstand.m4 \ @@ -86,7 +86,7 @@ LTLIBRARIES = $(toolexeclib_LTLIBRARIES) libvtv_la_LIBADD = am__objects_1 = vtv_start.lo vtv_malloc.lo vtv_rts.lo vtv_utils.lo \ vtv_end.lo -@ENABLE_VTABLE_VERIFY_TRUE@am_libvtv_la_OBJECTS = $(am__objects_1) +am_libvtv_la_OBJECTS = $(am__objects_1) libvtv_la_OBJECTS = $(am_libvtv_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/../depcomp @@ -118,8 +118,6 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive -am__libvtv_include_HEADERS_DIST = vtv_map.h vtv_malloc.h vtv_fail.h \ - vtv_set.h vtv_utils.h vtv_rts.h HEADERS = $(libvtv_include_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive @@ -127,7 +125,7 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS ETAGS = etags CTAGS = ctags -DIST_SUBDIRS = testsuite +DIST_SUBDIRS = $(SUBDIRS) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ @@ -265,8 +263,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ toplevel_builddir = @toplevel_builddir@ toplevel_srcdir = @toplevel_srcdir@ -@ENABLE_VTABLE_VERIFY_FALSE@SUBDIRS = -@ENABLE_VTABLE_VERIFY_TRUE@SUBDIRS = testsuite +SUBDIRS = testsuite ACLOCAL_AMFLAGS = -I .. -I ../config # May be used by toolexeclibdir. @@ -296,10 +293,8 @@ libvtv_includedir = $(includedir) # Link in vtv_start and vtv_end. BUILT_SOURCES = vtv_start.c vtv_end.c -@ENABLE_VTABLE_VERIFY_FALSE@libvtv_la_SOURCES = -@ENABLE_VTABLE_VERIFY_TRUE@libvtv_la_SOURCES = $(vtv_sources) -@ENABLE_VTABLE_VERIFY_FALSE@libvtv_include_HEADERS = -@ENABLE_VTABLE_VERIFY_TRUE@libvtv_include_HEADERS = $(vtv_headers) +libvtv_la_SOURCES = $(vtv_sources) +libvtv_include_HEADERS = $(vtv_headers) # Least ordering for dependencies mean linking w/o libstdc++ for as # long as the development of libvtv does not absolutely require it. diff --git a/libvtv/configure b/libvtv/configure index 6c50457fd22..37f2380705a 100755 --- a/libvtv/configure +++ b/libvtv/configure @@ -699,8 +699,6 @@ build_os build_vendor build_cpu build -ENABLE_VTABLE_VERIFY_FALSE -ENABLE_VTABLE_VERIFY_TRUE target_alias host_alias build_alias @@ -743,7 +741,6 @@ ac_subst_files='' ac_user_opts=' enable_option_checking enable_version_specific_runtime_libs -enable_vtable_verify enable_multilib enable_maintainer_mode enable_dependency_tracking @@ -1385,7 +1382,6 @@ Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory - --enable-vtable-verify Enable vtable verification feature --enable-multilib build many library versions (default) --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer @@ -2343,49 +2339,6 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $version_specific_libs" >&5 $as_echo "$version_specific_libs" >&6; } -# Use same top-level configure hooks in libgcc/libstdc++/libvtv. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-vtable-verify" >&5 -$as_echo_n "checking for --enable-vtable-verify... " >&6; } -# Check whether --enable-vtable-verify was given. -if test "${enable_vtable_verify+set}" = set; then : - enableval=$enable_vtable_verify; case "$enableval" in - yes) enable_vtable_verify=yes ;; - no) enable_vtable_verify=no ;; - *) enable_vtable_verify=no;; - esac -else - enable_vtable_verify=no -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_vtable_verify" >&5 -$as_echo "$enable_vtable_verify" >&6; } - -# See if supported. -unset VTV_SUPPORTED -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for host support for vtable verification" >&5 -$as_echo_n "checking for host support for vtable verification... " >&6; } -. ${srcdir}/configure.tgt -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $VTV_SUPPORTED" >&5 -$as_echo "$VTV_SUPPORTED" >&6; } - -# Decide if it's usable. -use_vtable_verify=no -if test "x$VTV_SUPPORTED" = "xyes"; then - if test "x$enable_vtable_verify" = "xyes"; then - use_vtable_verify=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: using vtable verification" >&5 -$as_echo "$as_me: using vtable verification" >&6;} - fi -fi - if test $use_vtable_verify = yes; then - ENABLE_VTABLE_VERIFY_TRUE= - ENABLE_VTABLE_VERIFY_FALSE='#' -else - ENABLE_VTABLE_VERIFY_TRUE='#' - ENABLE_VTABLE_VERIFY_FALSE= -fi - - # Do not delete or change the following two lines. For why, see # http://gcc.gnu.org/ml/libstdc++/2003-07/msg00451.html ac_aux_dir= @@ -2553,6 +2506,22 @@ esac +# See if supported. +unset VTV_SUPPORTED +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for host support for vtable verification" >&5 +$as_echo_n "checking for host support for vtable verification... " >&6; } +. ${srcdir}/configure.tgt +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $VTV_SUPPORTED" >&5 +$as_echo "$VTV_SUPPORTED" >&6; } + +# Decide if it's usable. +use_vtable_verify=no +if test "x$VTV_SUPPORTED" = "xyes"; then + use_vtable_verify=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: using vtable verification" >&5 +$as_echo "$as_me: using vtable verification" >&6;} +fi + am__api_version='1.11' # Find a good install program. We prefer a C program (faster), @@ -7882,7 +7851,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -7907,7 +7876,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -7926,7 +7898,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -12121,7 +12096,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12124 "configure" +#line 12099 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12227,7 +12202,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12230 "configure" +#line 12205 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -15637,10 +15612,6 @@ LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs -if test -z "${ENABLE_VTABLE_VERIFY_TRUE}" && test -z "${ENABLE_VTABLE_VERIFY_FALSE}"; then - as_fn_error "conditional \"ENABLE_VTABLE_VERIFY\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' diff --git a/libvtv/configure.ac b/libvtv/configure.ac index 60350dfccc3..e3fb92fc29e 100644 --- a/libvtv/configure.ac +++ b/libvtv/configure.ac @@ -20,17 +20,12 @@ AC_ARG_ENABLE(version-specific-runtime-libs, [version_specific_libs=no]) AC_MSG_RESULT($version_specific_libs) -# Use same top-level configure hooks in libgcc/libstdc++/libvtv. -AC_MSG_CHECKING([for --enable-vtable-verify]) -AC_ARG_ENABLE(vtable-verify, -[ --enable-vtable-verify Enable vtable verification feature ], -[case "$enableval" in - yes) enable_vtable_verify=yes ;; - no) enable_vtable_verify=no ;; - *) enable_vtable_verify=no;; - esac], -[enable_vtable_verify=no]) -AC_MSG_RESULT($enable_vtable_verify) +# Do not delete or change the following two lines. For why, see +# http://gcc.gnu.org/ml/libstdc++/2003-07/msg00451.html +AC_CANONICAL_SYSTEM +target_alias=${target_alias-$host_alias} +AC_SUBST(target_alias) +GCC_LIBSTDCXX_RAW_CXX_FLAGS # See if supported. unset VTV_SUPPORTED @@ -41,19 +36,9 @@ AC_MSG_RESULT($VTV_SUPPORTED) # Decide if it's usable. use_vtable_verify=no if test "x$VTV_SUPPORTED" = "xyes"; then - if test "x$enable_vtable_verify" = "xyes"; then - use_vtable_verify=yes - AC_MSG_NOTICE(using vtable verification) - fi + use_vtable_verify=yes + AC_MSG_NOTICE(using vtable verification) fi -AM_CONDITIONAL(ENABLE_VTABLE_VERIFY, test $use_vtable_verify = yes) - -# Do not delete or change the following two lines. For why, see -# http://gcc.gnu.org/ml/libstdc++/2003-07/msg00451.html -AC_CANONICAL_SYSTEM -target_alias=${target_alias-$host_alias} -AC_SUBST(target_alias) -GCC_LIBSTDCXX_RAW_CXX_FLAGS AM_INIT_AUTOMAKE(foreign no-dist) AM_ENABLE_MULTILIB(, ..) diff --git a/libvtv/configure.tgt b/libvtv/configure.tgt index 801d2f09564..046b4152429 100644 --- a/libvtv/configure.tgt +++ b/libvtv/configure.tgt @@ -21,6 +21,8 @@ # Filter out unsupported systems. VTV_SUPPORTED=no case "${target}" in + *-*-*android*) + ;; x86_64-*-linux* | i?86-*-linux*) VTV_SUPPORTED=yes ;; diff --git a/libvtv/testsuite/Makefile.am b/libvtv/testsuite/Makefile.am index 5f6ab0a037f..a2c1e9f4ea3 100644 --- a/libvtv/testsuite/Makefile.am +++ b/libvtv/testsuite/Makefile.am @@ -1,56 +1,11 @@ -## Makefile for the testsuite subdirectory of the VTV library. -## -## Copyright (C) 2013 Free Software Foundation, Inc. -## -## Process this file with automake to produce Makefile.in. -## -## This file is part of the Vtable Verification (VTV) 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. +## Process this with automake to create Makefile.in -## 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. +AUTOMAKE_OPTIONS = foreign dejagnu -## 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/>. +EXPECT = `if [ -f ../../expect/expect ] ; then \ + echo ../../expect/expect ; \ + else echo expect ; fi` -AUTOMAKE_OPTIONS = nostdinc - -# Runs the testsuite via a script. - -# Create subdirectories. -stamp-subdir: - if test ! -d lib64; then \ - mkdir -p lib64; \ - fi; \ - if test ! -d lib32; then \ - mkdir -p lib32; \ - fi; \ - echo `date` > stamp-subdir; - - -testing_script=${libvtv_srcdir}/scripts/run-testsuite.sh -check-script: ${testing_script} stamp-subdir - -@(chmod +x ${testing_script}; \ - ${testing_script} ${libvtv_srcdir} ${libvtv_builddir}) - -if ENABLE_VTABLE_VERIFY -check-am: - $(MAKE) $(AM_MAKEFLAGS) check-script -else -check-am: -endif - -.PHONY: check-script - -# By adding these files here, automake will remove them for 'make clean' -CLEANFILES = *.out environment-fail-* stamp-* replace-fail-* - -# To remove directories. -clean-local: - rm -rf lib* +RUNTEST = `if [ -f ${srcdir}/../../dejagnu/runtest ] ; then \ + echo ${srcdir}/../../dejagnu/runtest ; \ + else echo runtest ; fi` diff --git a/libvtv/testsuite/Makefile.in b/libvtv/testsuite/Makefile.in index 2992a905142..ba28e744f95 100644 --- a/libvtv/testsuite/Makefile.in +++ b/libvtv/testsuite/Makefile.in @@ -53,6 +53,8 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = +DEJATOOL = $(PACKAGE) +RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ @@ -190,11 +192,15 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ toplevel_builddir = @toplevel_builddir@ toplevel_srcdir = @toplevel_srcdir@ -AUTOMAKE_OPTIONS = nostdinc -testing_script = ${libvtv_srcdir}/scripts/run-testsuite.sh +AUTOMAKE_OPTIONS = foreign dejagnu +EXPECT = `if [ -f ../../expect/expect ] ; then \ + echo ../../expect/expect ; \ + else echo expect ; fi` + +RUNTEST = `if [ -f ${srcdir}/../../dejagnu/runtest ] ; then \ + echo ${srcdir}/../../dejagnu/runtest ; \ + else echo runtest ; fi` -# By adding these files here, automake will remove them for 'make clean' -CLEANFILES = *.out environment-fail-* stamp-* replace-fail-* all: all-am .SUFFIXES: @@ -240,7 +246,46 @@ TAGS: ctags: CTAGS CTAGS: + +check-DEJAGNU: site.exp + srcdir=`$(am__cd) $(srcdir) && pwd`; export srcdir; \ + EXPECT=$(EXPECT); export EXPECT; \ + runtest=$(RUNTEST); \ + if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \ + exit_status=0; l='$(DEJATOOL)'; for tool in $$l; do \ + if $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \ + then :; else exit_status=1; fi; \ + done; \ + else echo "WARNING: could not find \`runtest'" 1>&2; :;\ + fi; \ + exit $$exit_status +site.exp: Makefile + @echo 'Making a new site.exp file...' + @echo '## these variables are automatically generated by make ##' >site.tmp + @echo '# Do not edit here. If you wish to override these values' >>site.tmp + @echo '# edit the last section' >>site.tmp + @echo 'set srcdir $(srcdir)' >>site.tmp + @echo "set objdir `pwd`" >>site.tmp + @echo 'set build_alias "$(build_alias)"' >>site.tmp + @echo 'set build_triplet $(build_triplet)' >>site.tmp + @echo 'set host_alias "$(host_alias)"' >>site.tmp + @echo 'set host_triplet $(host_triplet)' >>site.tmp + @echo 'set target_alias "$(target_alias)"' >>site.tmp + @echo 'set target_triplet $(target_triplet)' >>site.tmp + @echo '## All variables above are generated by configure. Do Not Edit ##' >>site.tmp + @test ! -f site.exp || \ + sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp + @-rm -f site.bak + @test ! -f site.exp || mv site.exp site.bak + @mv site.tmp site.exp + +distclean-DEJAGNU: + -rm -f site.exp site.bak + -l='$(DEJATOOL)'; for tool in $$l; do \ + rm -f $$tool.sum $$tool.log; \ + done check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU check: check-am all-am: Makefile installdirs: @@ -261,7 +306,6 @@ install-strip: mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) @@ -272,11 +316,11 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libtool clean-local mostlyclean-am +clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile -distclean-am: clean-am distclean-generic +distclean-am: clean-am distclean-DEJAGNU distclean-generic dvi: dvi-am @@ -336,44 +380,20 @@ ps-am: uninstall-am: -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - clean-local distclean distclean-generic distclean-libtool dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am - - -# Runs the testsuite via a script. - -# Create subdirectories. -stamp-subdir: - if test ! -d lib64; then \ - mkdir -p lib64; \ - fi; \ - if test ! -d lib32; then \ - mkdir -p lib32; \ - fi; \ - echo `date` > stamp-subdir; -check-script: ${testing_script} stamp-subdir - -@(chmod +x ${testing_script}; \ - ${testing_script} ${libvtv_srcdir} ${libvtv_builddir}) - -@ENABLE_VTABLE_VERIFY_TRUE@check-am: -@ENABLE_VTABLE_VERIFY_TRUE@ $(MAKE) $(AM_MAKEFLAGS) check-script -@ENABLE_VTABLE_VERIFY_FALSE@check-am: +.MAKE: check-am install-am install-strip -.PHONY: check-script +.PHONY: all all-am check check-DEJAGNU check-am clean clean-generic \ + clean-libtool distclean distclean-DEJAGNU distclean-generic \ + distclean-libtool dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + uninstall uninstall-am -# To remove directories. -clean-local: - rm -rf lib* # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/libvtv/testsuite/config/default.exp b/libvtv/testsuite/config/default.exp new file mode 100644 index 00000000000..6d5eba84f10 --- /dev/null +++ b/libvtv/testsuite/config/default.exp @@ -0,0 +1,17 @@ +# Copyright (C) 2013 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +load_lib "standard.exp" diff --git a/libvtv/testsuite/event.list b/libvtv/testsuite/event.list deleted file mode 100644 index 83226fdd03f..00000000000 --- a/libvtv/testsuite/event.list +++ /dev/null @@ -1 +0,0 @@ -event-main.cc event-definitions.cc event-private.cc
\ No newline at end of file diff --git a/libvtv/testsuite/lib/libvtv-dg.exp b/libvtv/testsuite/lib/libvtv-dg.exp new file mode 100644 index 00000000000..b140c194cdc --- /dev/null +++ b/libvtv/testsuite/lib/libvtv-dg.exp @@ -0,0 +1,21 @@ +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +proc libvtv-dg-test { prog do_what extra_tool_flags } { + return [gcc-dg-test-1 libvtv_target_compile $prog $do_what $extra_tool_flags] +} + +proc libvtv-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} diff --git a/libvtv/testsuite/lib/libvtv.exp b/libvtv/testsuite/lib/libvtv.exp new file mode 100644 index 00000000000..83674be29a2 --- /dev/null +++ b/libvtv/testsuite/lib/libvtv.exp @@ -0,0 +1,220 @@ +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Damn dejagnu for not having proper library search paths for load_lib. +# We have to explicitly load everything that gcc-dg.exp wants to load. + +proc load_gcc_lib { filename } { + global srcdir loaded_libs + + load_file $srcdir/../../gcc/testsuite/lib/$filename + set loaded_libs($filename) "" +} + +load_lib dg.exp +load_gcc_lib file-format.exp +load_gcc_lib target-supports.exp +load_gcc_lib target-supports-dg.exp +load_gcc_lib scanasm.exp +load_gcc_lib scandump.exp +load_gcc_lib scanrtl.exp +load_gcc_lib scantree.exp +load_gcc_lib scanipa.exp +load_gcc_lib prune.exp +load_gcc_lib target-libpath.exp +load_gcc_lib wrapper.exp +load_gcc_lib gcc-defs.exp +load_gcc_lib torture-options.exp +load_gcc_lib timeout.exp +load_gcc_lib timeout-dg.exp +load_gcc_lib fortran-modules.exp +load_gcc_lib gcc-dg.exp + +set dg-do-what-default run + +# +# GCC_UNDER_TEST is the compiler under test. +# + +set libvtv_compile_options "" + +# +# libvtv_init +# + +if [info exists TOOL_OPTIONS] { + set multilibs [get_multilibs $TOOL_OPTIONS] +} else { + set multilibs [get_multilibs] +} + +proc libvtv_init { args } { + global srcdir blddir objdir tool_root_dir + global libvtv_initialized + global tmpdir + global blddir + global gluefile wrap_flags + global ALWAYS_CFLAGS + global CFLAGS + global TOOL_EXECUTABLE TOOL_OPTIONS + global GCC_UNDER_TEST + global TESTING_IN_BUILD_TREE + global target_triplet + global always_ld_library_path + + set blddir [lookfor_file [get_multilibs] libvtv] + + # We set LC_ALL and LANG to C so that we get the same error + # messages as expected. + setenv LC_ALL C + setenv LANG C + + if ![info exists GCC_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set GCC_UNDER_TEST $TOOL_EXECUTABLE + } else { + set GCC_UNDER_TEST "[find_gcc]" + } + } + + if ![info exists tmpdir] { + set tmpdir "/tmp" + } + + if [info exists gluefile] { + unset gluefile + } + + if {![info exists CFLAGS]} { + set CFLAGS "" + } + + # Locate libgcc.a so we don't need to account for different values of + # SHLIB_EXT on different platforms + set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a] + if {$gccdir != ""} { + set gccdir [file dirname $gccdir] + } + + # Compute what needs to be put into LD_LIBRARY_PATH + set always_ld_library_path ".:${blddir}/.libs" + + # Compute what needs to be added to the existing LD_LIBRARY_PATH. + if {$gccdir != ""} { + # Add AIX pthread directory first. + if { [llength [glob -nocomplain ${gccdir}/pthread/libgcc_s*.a]] >= 1 } { + append always_ld_library_path ":${gccdir}/pthread" + } + append always_ld_library_path ":${gccdir}" + set compiler [lindex $GCC_UNDER_TEST 0] + + if { [is_remote host] == 0 && [which $compiler] != 0 } { + foreach i "[exec $compiler --print-multi-lib]" { + set mldir "" + regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir + set mldir [string trimright $mldir "\;@"] + if { "$mldir" == "." } { + continue + } + if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } { + append always_ld_library_path ":${gccdir}/${mldir}" + } + } + } + } + + set ALWAYS_CFLAGS "" + if { $blddir != "" } { + lappend ALWAYS_CFLAGS "additional_flags=-B${blddir}/" + lappend ALWAYS_CFLAGS "additional_flags=-I${blddir}" + lappend ALWAYS_CFLAGS "ldflags=-L${blddir}/.libs" + } + lappend ALWAYS_CFLAGS "additional_flags=-I${srcdir}/.." + + if [istarget *-*-darwin*] { + lappend ALWAYS_CFLAGS "additional_flags=-shared-libgcc" + } + + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_CFLAGS "additional_flags=$TOOL_OPTIONS" + } + + # Make sure that lines are not wrapped. That can confuse the + # error-message parsing machinery. + lappend ALWAYS_CFLAGS "additional_flags=-fmessage-length=0" + + # Turn on vtable verification + lappend ALWAYS_CFLAGS "-fvtable-verify=std" + # lappend ALWAYS_CFLAGS "ldflags=-lvtv" +} + +# +# libvtv_target_compile -- compile a source file +# + +proc libvtv_target_compile { source dest type options } { + global blddir + global libvtv_compile_options + global gluefile wrap_flags + global ALWAYS_CFLAGS + global GCC_UNDER_TEST + global lang_test_file + global lang_library_path + global lang_link_flags + + if { [info exists lang_test_file] } { + if { $blddir != "" } { + lappend options "ldflags=-L${blddir}/${lang_library_path}" + } + lappend options "ldflags=${lang_link_flags}" + } + + if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=${wrap_flags}" + } + + lappend options "additional_flags=[libio_include_flags]" + lappend options "timeout=[timeout_value]" + lappend options "compiler=$GCC_UNDER_TEST" + + set options [concat $libvtv_compile_options $options] + + if [info exists ALWAYS_CFLAGS] { + set options [concat "$ALWAYS_CFLAGS" $options] + } + + set options [dg-additional-files-options $options $source] + + set result [target_compile $source $dest $type $options] + + return $result +} + +proc libvtv_option_help { } { + send_user " --additional_options,OPTIONS\t\tUse OPTIONS to compile the testcase files. OPTIONS should be comma-separated.\n" +} + +proc libvtv_option_proc { option } { + if [regexp "^--additional_options," $option] { + global libvtv_compile_options + regsub "--additional_options," $option "" option + foreach x [split $option ","] { + lappend libvtv_compile_options "additional_flags=$x" + } + return 1 + } else { + return 0 + } +} diff --git a/libvtv/testsuite/libvtv.cc/bb_tests.cc b/libvtv/testsuite/libvtv.cc/bb_tests.cc new file mode 100644 index 00000000000..2a2447d02c8 --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/bb_tests.cc @@ -0,0 +1,53 @@ +// { dg-do run } +struct base +{ + int total; + virtual void add (int i) { total += i; } + virtual void sub (int i) { total -= i; } + virtual void init (void) { total = 73; } +}; + +struct derived : public base +{ + int total; + virtual void add (int i) { total += 10 * i; } + virtual void sub (int i) { total -= 2 * i; } + virtual void init (void) { total = 0; } +}; + +bool +get_cond_value (int x) +{ + if ((x % 3) > 0) + return true; + else + return false; + + return false; +} + +int +main (int argc, char **argv) +{ + base *a; + bool cond_value = get_cond_value (10); + int x; + + if (cond_value) + a = new base (); + else + a = new derived (); + + cond_value = get_cond_value (47); + x = 0; + if (!cond_value) + x = 17; + + a->init (); + + for ( ; x < 10; ++x) + { + a->add(50); + a->sub(25); + } +} diff --git a/libvtv/testsuite/const_vtable.cc b/libvtv/testsuite/libvtv.cc/const_vtable.cc index a0946abf4fe..3229f008308 100644 --- a/libvtv/testsuite/const_vtable.cc +++ b/libvtv/testsuite/libvtv.cc/const_vtable.cc @@ -1,3 +1,4 @@ +// { dg-do run } extern "C" int printf(const char *,...); struct V1 { int v; diff --git a/libvtv/testsuite/dataentry.cc b/libvtv/testsuite/libvtv.cc/dataentry.cc index fa027d5bc71..6246136e521 100644 --- a/libvtv/testsuite/dataentry.cc +++ b/libvtv/testsuite/libvtv.cc/dataentry.cc @@ -1,3 +1,5 @@ +// { dg-do run } + template<int patch_dim, int patch_space_dim> class DataOutInterface { diff --git a/libvtv/testsuite/libvtv.cc/derived-lib.cpp b/libvtv/testsuite/libvtv.cc/derived-lib.cpp new file mode 100644 index 00000000000..375dbe41bde --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/derived-lib.cpp @@ -0,0 +1,18 @@ +#include "lib.h" + +struct Derived_Private : public Base +{ + virtual ~Derived_Private() + { printf("in Derived_Private destructor\n"); } +}; + +Base * GetPrivate() +{ + return new Derived_Private(); +} + +void Destroy(Base * pb) +{ + delete pb; // Virtual call #1 +} + diff --git a/libvtv/testsuite/libvtv.cc/derived-main.cpp b/libvtv/testsuite/libvtv.cc/derived-main.cpp new file mode 100644 index 00000000000..0933ff69621 --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/derived-main.cpp @@ -0,0 +1,18 @@ +// { dg-do run } + +#include "lib.h" + +struct Derived: public Base +{ + virtual ~Derived() + { printf("In Derived destructor\n"); } +}; + +int main() +{ + Derived * d = new Derived; + Destroy(d); + Base * pp = GetPrivate(); + delete pp; // Virtual call #2 +} + diff --git a/libvtv/testsuite/libvtv.cc/derived.list b/libvtv/testsuite/libvtv.cc/derived.list new file mode 100644 index 00000000000..6ea3b9cf603 --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/derived.list @@ -0,0 +1 @@ +derived-main.cpp derived-lib.cpp diff --git a/libvtv/testsuite/dup_name.cc b/libvtv/testsuite/libvtv.cc/dup_name.cc index f0f1c2a8136..d9d02512630 100644 --- a/libvtv/testsuite/dup_name.cc +++ b/libvtv/testsuite/libvtv.cc/dup_name.cc @@ -1,3 +1,5 @@ +// { dg-do run } + #include <assert.h> extern "C" int printf(const char *, ...); diff --git a/libvtv/testsuite/environment.cc b/libvtv/testsuite/libvtv.cc/environment.cc index 83adf53b601..af1a8775298 100644 --- a/libvtv/testsuite/environment.cc +++ b/libvtv/testsuite/libvtv.cc/environment.cc @@ -1,3 +1,4 @@ +// { dg-do run } extern "C" int printf(const char *, ...); diff --git a/libvtv/testsuite/event-definitions.cc b/libvtv/testsuite/libvtv.cc/event-defintions.cpp index ba9efe11a4d..ba9efe11a4d 100644 --- a/libvtv/testsuite/event-definitions.cc +++ b/libvtv/testsuite/libvtv.cc/event-defintions.cpp diff --git a/libvtv/testsuite/event-main.cc b/libvtv/testsuite/libvtv.cc/event-main.cpp index b0312848934..95c4640313a 100644 --- a/libvtv/testsuite/event-main.cc +++ b/libvtv/testsuite/libvtv.cc/event-main.cpp @@ -1,3 +1,5 @@ +// { dg-do run } + #include "event-private.h" template<typename T> void derefIfNotNull(T* ptr) diff --git a/libvtv/testsuite/event-private.cc b/libvtv/testsuite/libvtv.cc/event-private.cpp index a27f4697a25..a27f4697a25 100644 --- a/libvtv/testsuite/event-private.cc +++ b/libvtv/testsuite/libvtv.cc/event-private.cpp diff --git a/libvtv/testsuite/event-private.h b/libvtv/testsuite/libvtv.cc/event-private.h index 678ab5f68af..678ab5f68af 100644 --- a/libvtv/testsuite/event-private.h +++ b/libvtv/testsuite/libvtv.cc/event-private.h diff --git a/libvtv/testsuite/event.h b/libvtv/testsuite/libvtv.cc/event.h index 61e1d7c9172..61e1d7c9172 100644 --- a/libvtv/testsuite/event.h +++ b/libvtv/testsuite/libvtv.cc/event.h diff --git a/libvtv/testsuite/libvtv.cc/event.list b/libvtv/testsuite/libvtv.cc/event.list new file mode 100644 index 00000000000..77606f8c122 --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/event.list @@ -0,0 +1 @@ +event-main.cpp event-definitions.cpp event-private.cpp
\ No newline at end of file diff --git a/libvtv/testsuite/libvtv.cc/mul_inh.cc b/libvtv/testsuite/libvtv.cc/mul_inh.cc new file mode 100644 index 00000000000..b32b710c835 --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/mul_inh.cc @@ -0,0 +1,27 @@ +// { dg-do run } + +extern "C" int printf(const char *, ...); + +struct A { + virtual ~A() {} +}; + +struct B { + virtual ~B() {} +}; + +struct C: public A { + virtual ~C() {} +}; + +struct D: public C, B { + virtual ~D() {} +}; + +D d; + +int main() +{ + printf ("%p\n", &d); + return 0; +} diff --git a/libvtv/testsuite/nested_vcall_test.cc b/libvtv/testsuite/libvtv.cc/nested_vcall_test.cc index 13d7143edf8..9d1a9c692da 100644 --- a/libvtv/testsuite/nested_vcall_test.cc +++ b/libvtv/testsuite/libvtv.cc/nested_vcall_test.cc @@ -1,3 +1,4 @@ +// { dg-do run } class EtherCtrl { protected: diff --git a/libvtv/testsuite/parts-test-extra-parts-views.cc b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts-views.cpp index 13d7fdc6e4f..13d7fdc6e4f 100644 --- a/libvtv/testsuite/parts-test-extra-parts-views.cc +++ b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts-views.cpp diff --git a/libvtv/testsuite/parts-test-extra-parts-views.h b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts-views.h index 0784c0ecdaa..0784c0ecdaa 100644 --- a/libvtv/testsuite/parts-test-extra-parts-views.h +++ b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts-views.h diff --git a/libvtv/testsuite/parts-test-extra-parts.cc b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts.cpp index dbd3dbfd8f5..dbd3dbfd8f5 100644 --- a/libvtv/testsuite/parts-test-extra-parts.cc +++ b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts.cpp diff --git a/libvtv/testsuite/parts-test-extra-parts.h b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts.h index 4ed2a4ce1a0..4ed2a4ce1a0 100644 --- a/libvtv/testsuite/parts-test-extra-parts.h +++ b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts.h diff --git a/libvtv/testsuite/parts-test-main.cc b/libvtv/testsuite/libvtv.cc/parts-test-main.cpp index c90901e7919..a0cc721abf5 100644 --- a/libvtv/testsuite/parts-test-main.cc +++ b/libvtv/testsuite/libvtv.cc/parts-test-main.cpp @@ -1,3 +1,5 @@ +// { dg-do run } + #include "parts-test-main.h" #include "parts-test-extra-parts-views.h" diff --git a/libvtv/testsuite/parts-test-main.h b/libvtv/testsuite/libvtv.cc/parts-test-main.h index fb631dec340..fb631dec340 100644 --- a/libvtv/testsuite/parts-test-main.h +++ b/libvtv/testsuite/libvtv.cc/parts-test-main.h diff --git a/libvtv/testsuite/libvtv.cc/parts-test.list b/libvtv/testsuite/libvtv.cc/parts-test.list new file mode 100644 index 00000000000..11a959a62d1 --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/parts-test.list @@ -0,0 +1 @@ +parts-test-main.cpp parts-test-extra-parts.cpp parts-test-extra-parts-views.cpp diff --git a/libvtv/testsuite/povray-derived.cc b/libvtv/testsuite/libvtv.cc/povray-derived.cc index 4f56a3d730f..9005826dff4 100644 --- a/libvtv/testsuite/povray-derived.cc +++ b/libvtv/testsuite/libvtv.cc/povray-derived.cc @@ -1,3 +1,5 @@ +// { dg-do run } + // Small test case from povray, see if it reproduces. #include <stdio.h> diff --git a/libvtv/testsuite/libvtv.cc/register_set_pair.cc b/libvtv/testsuite/libvtv.cc/register_set_pair.cc new file mode 100644 index 00000000000..b7f08331d68 --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/register_set_pair.cc @@ -0,0 +1,101 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> + +#include "vtv_utils.h" +#include "vtv_rts.h" + +/* This configuration will test mostly inserting of elements that are already inserted since + the number of repeats is 200 */ + +#define NUM_MAPS 4000 +#define ELEMENTS_PER_MAP 100 +#define NUM_REPEATS 200 + +#define KEY_TYPE_FIXED_SIZE 8 +void *key_buffer = malloc (17); +typedef char * name_string; +name_string fake_names[NUM_MAPS]; + +/* This variable has to be put in rel.ro */ +void * maps[NUM_MAPS] VTV_PROTECTED_VAR; + +struct fake_vt { + void * fake_vfp [4]; +}; +void * fake_vts [NUM_MAPS * ELEMENTS_PER_MAP]; + +void +generate_names (void) +{ + int i; + + for (i = 0; i < NUM_MAPS; ++i) + { + fake_names[i] = (char *) malloc (9 * sizeof (char)); + snprintf (fake_names[i], 9, "name%d", i); + } +} + +static uint32_t +vtv_string_hash(const char *in) +{ + const char *s = in; + uint32_t h = 0; + + for ( ; *s; ++s) + h = 5 * h + *s; + return h; +} + +int main() +{ + __VLTChangePermission(__VLTP_READ_WRITE); + + generate_names (); + + for (int k = 0; k < NUM_REPEATS; k++) + { + int curr_fake_vt = 0; + for (int i = 0; i < NUM_MAPS; i++) + { + uint32_t *value_ptr = (uint32_t *) key_buffer; + uint32_t len1 = strlen (fake_names[i]); + uint32_t hash_value = vtv_string_hash (fake_names[i]); + void *temp_array[ELEMENTS_PER_MAP]; + + *value_ptr = len1; + value_ptr++; + *value_ptr = hash_value; + + memcpy ((char *) key_buffer + KEY_TYPE_FIXED_SIZE, fake_names[i], + len1); + + +#ifdef VTV_DEBUG + __VLTRegisterPairDebug (&maps[i], (char *) key_buffer, 128, + &fake_vts[curr_fake_vt], "", ""); +#else + __VLTRegisterPair (&maps[i], (char *) key_buffer, 128, + &fake_vts[curr_fake_vt]); +#endif + for (int j = 0; j < ELEMENTS_PER_MAP; j++) + { + temp_array[j] = &fake_vts[curr_fake_vt]; + curr_fake_vt++; + } +#ifdef VTV_DEBUG + __VLTRegisterSetDebug (&maps[i], (char *) key_buffer, 128, 100, + (void **) &temp_array); +#else + __VLTRegisterSet (&maps[i], (char *) key_buffer, 128, 100, + (void **) &temp_array); +#endif + } + } + + __VLTChangePermission(__VLTP_READ_ONLY); + + return 0; +} diff --git a/libvtv/testsuite/libvtv.cc/register_set_pair_inserts.cc b/libvtv/testsuite/libvtv.cc/register_set_pair_inserts.cc new file mode 100644 index 00000000000..297e8756797 --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/register_set_pair_inserts.cc @@ -0,0 +1,106 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> + +#include "vtv_utils.h" +#include "vtv_rts.h" + +/* This configuration will test mostly inserting of new elements since + the number of repeats is 1. It should also do a lot of rehashing */ + +/* This test case may fail depending on the system configuration. + Check the value of /proc/sys/vm/max_map_count and fix by doing + Ex: sudo sh -c "echo 131060 > /proc/sys/vm/max_map_count" */ + +#define NUM_MAPS 40000 +#define ELEMENTS_PER_MAP 100 +#define NUM_REPEATS 1 + +#define KEY_TYPE_FIXED_SIZE 8 +void *key_buffer = malloc (17); +typedef char * name_string; +name_string fake_names[NUM_MAPS]; + +/* This variable has to be put in rel.ro */ +void * maps[NUM_MAPS] VTV_PROTECTED_VAR; + +struct fake_vt { + void * fake_vfp [4]; +}; +void * fake_vts [NUM_MAPS * ELEMENTS_PER_MAP]; + + +void +generate_names (void) +{ + int i; + + for (i = 0; i < NUM_MAPS; ++i) + { + fake_names[i] = (char *) malloc (9 * sizeof (char)); + snprintf (fake_names[i], 9, "name%d", i); + } +} + +static uint32_t +vtv_string_hash(const char *in) +{ + const char *s = in; + uint32_t h = 0; + + for ( ; *s; ++s) + h = 5 * h + *s; + return h; +} + +int main() +{ + __VLTChangePermission(__VLTP_READ_WRITE); + + generate_names(); + + for (int k = 0; k < NUM_REPEATS; k++) + { + int curr_fake_vt = 0; + for (int i = 0; i < NUM_MAPS; i++) + { + uint32_t *value_ptr = (uint32_t *) key_buffer; + uint32_t len1 = strlen (fake_names[i]); + uint32_t hash_value = vtv_string_hash (fake_names[i]); + void *temp_array[ELEMENTS_PER_MAP]; + + *value_ptr = len1; + value_ptr++; + *value_ptr = hash_value; + + memcpy ((char *) key_buffer + KEY_TYPE_FIXED_SIZE, fake_names[i], + len1); + + +#ifdef VTV_DEBUG + __VLTRegisterPairDebug (&maps[i], (char *) key_buffer, 128, + &fake_vts[curr_fake_vt], "", ""); +#else + __VLTRegisterPair (&maps[i], (char *) key_buffer, 128, + &fake_vts[curr_fake_vt]); +#endif + for (int j = 0; j < ELEMENTS_PER_MAP; j++) + { + temp_array[j] = &fake_vts[curr_fake_vt]; + curr_fake_vt++; + } +#ifdef VTV_DEBUG + __VLTRegisterSetDebug (&maps[i], (char *) key_buffer, 128, 100, + (void **) &temp_array); +#else + __VLTRegisterSet (&maps[i], (char *) key_buffer, 128, 100, + (void **) &temp_array); +#endif + } + } + + __VLTChangePermission(__VLTP_READ_ONLY); + + return 0; +} diff --git a/libvtv/testsuite/template-list-iostream.cc b/libvtv/testsuite/libvtv.cc/template-list-iostream.cc index a35fd308382..06ec3b01e10 100644 --- a/libvtv/testsuite/template-list-iostream.cc +++ b/libvtv/testsuite/libvtv.cc/template-list-iostream.cc @@ -1,3 +1,5 @@ +// { dg-do run } + #include <assert.h> #include <iostream> #include <fstream> diff --git a/libvtv/testsuite/template-list.cc b/libvtv/testsuite/libvtv.cc/template-list.cc index 95233f87765..aeb2db9e526 100644 --- a/libvtv/testsuite/template-list.cc +++ b/libvtv/testsuite/libvtv.cc/template-list.cc @@ -1,3 +1,5 @@ +// { dg-do run } + #include <assert.h> extern "C" int printf(const char *, ...); diff --git a/libvtv/testsuite/template-list2.cc b/libvtv/testsuite/libvtv.cc/template-list2.cc index f8ec739b6d5..3df8d372418 100644 --- a/libvtv/testsuite/template-list2.cc +++ b/libvtv/testsuite/libvtv.cc/template-list2.cc @@ -1,3 +1,5 @@ +// { dg-do run } + #include <assert.h> extern "C" int printf(const char *, ...); diff --git a/libvtv/testsuite/libvtv.cc/test1.cc b/libvtv/testsuite/libvtv.cc/test1.cc new file mode 100644 index 00000000000..9005826dff4 --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/test1.cc @@ -0,0 +1,74 @@ +// { dg-do run } + +// Small test case from povray, see if it reproduces. + +#include <stdio.h> + +class POVMS_MessageReceiver +{ + +private: + int x; + class Handler + { + public: + virtual void print() = 0; + }; +protected: + template<class T> class MemberHandler : public Handler + { + public: + MemberHandler(T *xx) + { + x = xx; + } + + ~MemberHandler() {} + + void print() + { + printf("In print\n"); + } + private: + T *x; + }; + +private: + struct HandlerNode + { + Handler *handler; + }; + + HandlerNode *receiver; +public: + POVMS_MessageReceiver(int xx) : x(xx) {} + ~POVMS_MessageReceiver() {} + + void foo(int *xx); + void try_call(); +}; + +void POVMS_MessageReceiver::foo(int *xx) +{ + receiver = new HandlerNode; + + receiver->handler = new MemberHandler<int>(xx); +} + +void POVMS_MessageReceiver::try_call() +{ + receiver->handler->print(); +} + + +int main() +{ + int loc = 34; + POVMS_MessageReceiver a_test(100); + + a_test.foo(&loc); + a_test.try_call(); +} + + + diff --git a/libvtv/testsuite/thunk.cc b/libvtv/testsuite/libvtv.cc/thunk.cc index 6ab81a0dfd4..bec1057f564 100644 --- a/libvtv/testsuite/thunk.cc +++ b/libvtv/testsuite/libvtv.cc/thunk.cc @@ -1,3 +1,5 @@ +// { dg-do run } + #include <assert.h> struct A { A():value(123) {} diff --git a/libvtv/testsuite/thunk_vtable_map_attack.cc b/libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc index 84d4bbf3257..51f974ee4e7 100644 --- a/libvtv/testsuite/thunk_vtable_map_attack.cc +++ b/libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc @@ -1,3 +1,5 @@ +// { dg-do run } + #include <assert.h> #include <signal.h> #include <setjmp.h> diff --git a/libvtv/testsuite/libvtv.cc/v8-test-2.cc b/libvtv/testsuite/libvtv.cc/v8-test-2.cc new file mode 100644 index 00000000000..6bfda56e8c6 --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/v8-test-2.cc @@ -0,0 +1,97 @@ +// { dg-do run } + +#include <stdlib.h> +#include <string> + +class Literal; +class CallRuntime; + +class AstNode { +public: + + enum Type { + kLiteral, kCallRuntime, + kInvalid = -1 + }; + + AstNode() { } + + virtual ~AstNode() { } + + virtual Type node_type() const = 0; + + bool + IsLiteral() { return node_type() == AstNode::kLiteral; } + + Literal * + AsLiteral() { return IsLiteral() ? reinterpret_cast<Literal*>(this) + : NULL; } + + bool + IsCallRuntime() { return node_type() == AstNode::kCallRuntime; } + + CallRuntime * + AsCallRuntime() { return IsCallRuntime() ? reinterpret_cast<CallRuntime*>(this) + : NULL; } + +}; + +class Expression: public AstNode { +public: +private: + int id_; +}; + +class Literal: public Expression { +public: + + virtual AstNode::Type node_type() const { return AstNode::kLiteral; } + + private: + std::string ToString(); + +}; + +class CallRuntime: public Expression { +public: + + virtual AstNode::Type node_type() const { return AstNode::kCallRuntime; } + + private: + std::string name_; +}; + +Expression * +ExpressionCheck (bool *ok) +{ + if (*ok == true) + return new CallRuntime(); + else + return new Literal (); + + return NULL; +} + +Expression * +GetExpression (bool *ok) +{ + Expression *expression = ExpressionCheck (ok); + Expression *return_expr = NULL; + + if (expression != NULL && expression->AsLiteral() != NULL) + return_expr = new Literal(); + else if (expression != NULL && expression->AsCallRuntime() != NULL) + return_expr = expression; + + return return_expr; +} + +int +main (int argc, char **argv) +{ + bool a_bool = true; + + AstNode *node = GetExpression (&a_bool); + + return 0; +} diff --git a/libvtv/testsuite/libvtv.cc/virtfunc-test.cc b/libvtv/testsuite/libvtv.cc/virtfunc-test.cc new file mode 100644 index 00000000000..3ad12b896c1 --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/virtfunc-test.cc @@ -0,0 +1,222 @@ +// { dg-do run } + +/* This test script is part of GDB, the GNU debugger. + + Copyright 1993, 1994, 1997, 1998, 1999, 2003, 2004, + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +// Pls try the following program on virtual functions and try to do print on +// most of the code in main(). Almost none of them works ! + +// +// The inheritance structure is: +// +// V : VA VB +// A : (V) +// B : A +// D : AD (V) +// C : (V) +// E : B (V) D C +// + +class VA +{ +public: + int va; +}; + +class VB +{ +public: + int vb; + int fvb(); + virtual int vvb(); +}; + +class V : public VA, public VB +{ +public: + int f(); + virtual int vv(); + int w; +}; + +class A : virtual public V +{ +public: + virtual int f(); +private: + int a; +}; + +class B : public A +{ +public: + int f(); +private: + int b; +}; + +class C : public virtual V +{ +public: + int c; +}; + +class AD +{ +public: + virtual int vg() = 0; +}; + +class D : public AD, virtual public V +{ +public: + static void s(); + virtual int vg(); + virtual int vd(); + int fd(); + int d; +}; + +class E : public B, virtual public V, public D, public C +{ +public: + int f(); + int vg(); + int vv(); + int e; +}; + +D dd; +D* ppd = ⅆ +AD* pAd = ⅆ + +A a; +B b; +C c; +D d; +E e; +V v; +VB vb; + + +A* pAa = &a; +A* pAe = &e; + +B* pBe = &e; + +D* pDd = &d; +D* pDe = &e; + +V* pVa = &a; +V* pVv = &v; +V* pVe = &e; +V* pVd = &d; + +AD* pADe = &e; + +E* pEe = &e; + +VB* pVB = &vb; + +void init() +{ + a.vb = 1; + b.vb = 2; + c.vb = 3; + d.vb = 4; + e.vb = 5; + v.vb = 6; + vb.vb = 7; + + d.d = 1; + e.d = 2; +} + +extern "C" int printf(const char *, ...); + +int all_count = 0; +int failed_count = 0; + +#define TEST(EXPR, EXPECTED) \ + ret = EXPR; \ + if (ret != EXPECTED) {\ + printf("Failed %s is %d, should be %d!\n", #EXPR, ret, EXPECTED); \ + failed_count++; } \ + all_count++; + +int ret; + +void test_calls() +{ + TEST(pAe->f(), 20); + TEST(pAa->f(), 1); + + TEST(pDe->vg(), 202); + TEST(pADe->vg(), 202); + TEST(pDd->vg(), 101); + + TEST(pEe->vvb(), 411); + + TEST(pVB->vvb(), 407); + + TEST(pBe->vvb(), 411); + TEST(pDe->vvb(), 411); + + TEST(pEe->vd(), 282); + TEST(pEe->fvb(), 311); + + TEST(pEe->D::vg(), 102); + printf("Did %d tests, of which %d failed.\n", all_count, failed_count); +} +#ifdef usestubs +extern "C" { + void set_debug_traps(); + void breakpoint(); +}; +#endif + +int main() +{ +#ifdef usestubs + set_debug_traps(); + breakpoint(); +#endif + init(); + + e.w = 7; + e.vb = 11; + + test_calls(); + return 0; + +} + +int A::f() {return 1;} +int B::f() {return 2;} +void D::s() {} +int E::f() {return 20;} +int D::vg() {return 100+d;} +int E::vg() {return 200+d;} +int V::f() {return 600+w;} +int V::vv() {return 400+w;} +int E::vv() {return 450+w;} +int D::fd() {return 250+d;} +int D::vd() {return 280+d;} +int VB::fvb() {return 300+vb;} +int VB::vvb() {return 400+vb;} diff --git a/libvtv/testsuite/virtual_inheritance.cc b/libvtv/testsuite/libvtv.cc/virtual_inheritance.cc index 89fe388a856..1c49c966453 100644 --- a/libvtv/testsuite/virtual_inheritance.cc +++ b/libvtv/testsuite/libvtv.cc/virtual_inheritance.cc @@ -1,3 +1,5 @@ +// { dg-do run } + #include <assert.h> struct V { V(): virtual_value(-123) {} diff --git a/libvtv/testsuite/libvtv.cc/vtv.exp b/libvtv/testsuite/libvtv.cc/vtv.exp new file mode 100644 index 00000000000..12ed77431a8 --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/vtv.exp @@ -0,0 +1,83 @@ +load_lib libvtv-dg.exp +load_gcc_lib gcc-dg.exp + +global VTV_FLAGS +set VTV_FLAGS [list {-O0} {-O2}] + +libvtv_init c++ + +set shlib_ext [get_shlib_extension] +set lang_link_flags "-shared-libgcc -lstdc++" +set lang_test_file_found 0 +set lang_library_path "../libstdc++-v3/src/.libs" + +dg-init + +set blddir [lookfor_file [get_multilibs] libvtv] + +# Find the correct libstdc++ library to use. + +if { $blddir != "" } { + # Look for a static libstdc++ first. + if [file exists "${blddir}/${lang_library_path}/libstdc++.a"] { + set lang_test_file "${lang_library_path}/libstdc++.a" + set lang_test_file_found 1 + # We may have a shared only build, so look for a shared libstdc++. + } elseif [file exists "${blddir}/${lang_library_path}/libstdc++.${shlib_ext}"] { + set lang_test_file "${lang_library_path}/libstdc++.${shlib_ext}" + set lang_test_file_found 1 + } else { + puts "looking for ${blddir}/${lang_library_path}/libstdc++.${shlib_ext}" + puts "No libstdc++ library found, will not execute c++ tests" + } +} elseif { [info exists GXX_UNDER_TEST] } { + set lang_test_file_found 1 + # Needs to exist for libvtv.exp. + set lang_test_file "" +} else { + puts "GXX_UNDER_TEST not defined, will not execute c++ tests" +} + + +global srcdir + +if { $lang_test_file_found } { + # Set the path for finding libstdc++. + if { $blddir != "" } { + set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}" + } else { + set ld_library_path "$always_ld_library_path" + } + append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST] + set_ld_library_path_env_vars + + # Make sure we can find the libstdc++ header files. + set flags_file "${blddir}/../libstdc++-v3/scripts/testsuite_flags" + if { [file exists $flags_file] } { + set libstdcxx_includes [exec sh $flags_file --build-includes] + } else { + set libstdcxx_includes "" + } + + # Run the tests with -fvtable-verify=std + foreach flags $VTV_FLAGS { + foreach srcfile [lsort [glob -nocomplain ${srcdir}/libvtv.cc/*.cc]] { + dg-runtest $srcfile "$flags -fvtable-verify=std" $libstdcxx_includes + } + + foreach srcfile [lsort [glob -nocomplain ${srcdir}/libvtv.cc/@*.list]] { + dg-runtest $srcfile "$flags -fvtable-verify=std" $libstdcxx_includes + } + } + + # Run the tests with -fvtable-verify=preinit + foreach flags $VTV_FLAGS { + foreach srcfile [lsort [glob -nocomplain ${srcdir}/libvtv.cc/*.cc]] { + dg-runtest $srcfile "$flags -fvtable-verify=preinit" $libstdcxx_includes + } + + foreach srcfile [lsort [glob -nocomplain ${srcdir}/libvtv.cc/@*.list]] { + dg-runtest $srcfile "$flags -fvtable-verify=preinit" $libstdcxx_includes + } + } +} diff --git a/libvtv/testsuite/libvtv.cc/xlan-test.cc b/libvtv/testsuite/libvtv.cc/xlan-test.cc new file mode 100644 index 00000000000..213ed613fbb --- /dev/null +++ b/libvtv/testsuite/libvtv.cc/xlan-test.cc @@ -0,0 +1,185 @@ +// { dg-do run } + +#include <stdio.h> +#include <stdlib.h> + +class XMemory +{ +public: + void * operator new (size_t size); + void operator delete (void *p); + +protected: + XMemory () {} + + virtual ~XMemory() {} +}; + +class XSerializable +{ +public: + virtual ~XSerializable () {}; + + virtual bool isSerializable() const = 0; + virtual void serialize () = 0; + +protected: + XSerializable() {}; + +}; + +class Grammar: public XSerializable, public XMemory +{ +public: + enum GrammarType { + DTDGrammarType, + SchemaGrammarType, + OtherGrammarType, + Unknown + }; + + virtual ~Grammar() {} + + virtual GrammarType getGrammarType() const = 0; + virtual bool getValidated() const = 0; + + virtual bool isSerializable() const; + virtual void serialize (); + +protected: + Grammar() {}; + +}; + +class SchemaGrammar : public Grammar +{ +public: + + SchemaGrammar () : Grammar(), elemID(10) { fValidated = true; } + + virtual ~SchemaGrammar() {} + + virtual Grammar::GrammarType getGrammarType() const; + virtual bool getValidated() const; + + virtual bool isSerializable () const; + virtual void serialize (); + +private: + const unsigned int elemID; + bool fValidated; + +}; + +class OtherGrammar : public Grammar +{ +public: + + OtherGrammar () : Grammar(), elemID(10) { fValidated = true; } + + virtual ~OtherGrammar() {} + + virtual Grammar::GrammarType getGrammarType() const; + virtual bool getValidated() const; + + virtual bool isSerializable () const; + virtual void serialize (); + +private: + const unsigned int elemID; + bool fValidated; + +}; + +void +Grammar::serialize () +{ + printf ("in Grammar::serialize\n"); +} + +bool +Grammar::isSerializable () const +{ + return true; +} + +bool +SchemaGrammar::isSerializable () const +{ + return true; +} + +void +SchemaGrammar::serialize () +{ + printf ("in SchemaGrammar::serialize\n"); +} + +Grammar::GrammarType +SchemaGrammar::getGrammarType() const { + return Grammar::SchemaGrammarType; +} + +bool +SchemaGrammar::getValidated () const +{ + return fValidated; +} + +void * +XMemory::operator new (size_t size) +{ + return malloc (size); +} + +void +XMemory::operator delete (void *p) +{ +} + +bool +OtherGrammar::isSerializable () const +{ + return false; +} + +void +OtherGrammar::serialize () +{ + printf ("in OtherGrammar::serialize\n"); +} + +Grammar::GrammarType +OtherGrammar::getGrammarType() const { + return Grammar::OtherGrammarType; +} + +bool +OtherGrammar::getValidated () const +{ + return fValidated; +} + +int +main (int argc, char **argv) +{ + SchemaGrammar sPtr; + OtherGrammar oPtr; + Grammar &sGrammar = sPtr; + + for (int i = 0; i < 2; ++i) + { + if (i == 0) + sGrammar = oPtr; + else + sGrammar = sPtr; + + if (sGrammar.getGrammarType() != Grammar::SchemaGrammarType || + sGrammar.getValidated ()) + printf ("if condition was true.\n"); + else + printf ("if condition was false.\n"); + } + + return 0; +} diff --git a/libvtv/testsuite/libvtv.mempool.cc/mempool.exp b/libvtv/testsuite/libvtv.mempool.cc/mempool.exp new file mode 100644 index 00000000000..9565eae711a --- /dev/null +++ b/libvtv/testsuite/libvtv.mempool.cc/mempool.exp @@ -0,0 +1,68 @@ +load_lib libvtv-dg.exp +load_gcc_lib gcc-dg.exp + +global VTV_FLAGS +set VTV_FLAGS [list {-O0} {-O2}] + +libvtv_init c++ + +set shlib_ext [get_shlib_extension] +set lang_link_flags "-shared-libgcc -lstdc++" +set lang_test_file_found 0 +set lang_library_path "../libstdc++-v3/src/.libs" + +dg-init + +set blddir [lookfor_file [get_multilibs] libvtv] + +# Find the correct libstdc++ library to use. + +if { $blddir != "" } { + # Look for a static libstdc++ first. + if [file exists "${blddir}/${lang_library_path}/libstdc++.a"] { + set lang_test_file "${lang_library_path}/libstdc++.a" + set lang_test_file_found 1 + # We may have a shared only build, so look for a shared libstdc++. + } elseif [file exists "${blddir}/${lang_library_path}/libstdc++.${shlib_ext}"] { + set lang_test_file "${lang_library_path}/libstdc++.${shlib_ext}" + set lang_test_file_found 1 + } else { + puts "looking for ${blddir}/${lang_library_path}/libstdc++.${shlib_ext}" + puts "No libstdc++ library found, will not execute c++ tests" + } +} elseif { [info exists GXX_UNDER_TEST] } { + set lang_test_file_found 1 + # Needs to exist for libvtv.exp. + set lang_test_file "" +} else { + puts "GXX_UNDER_TEST not defined, will not execute c++ tests" +} + + +global srcdir + +if { $lang_test_file_found } { + # Set the path for finding libstdc++. + if { $blddir != "" } { + set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}" + } else { + set ld_library_path "$always_ld_library_path" + } + append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST] + set_ld_library_path_env_vars + + # Make sure we can find the libstdc++ header files. + set flags_file "${blddir}/../libstdc++-v3/scripts/testsuite_flags" + if { [file exists $flags_file] } { + set libstdcxx_includes [exec sh $flags_file --build-includes] + } else { + set libstdcxx_includes "" + } + + # Run the tests with -fvtable-verify=std + foreach flags $VTV_FLAGS { + foreach srcfile [lsort [glob -nocomplain ${srcdir}/libvtv.mempool.cc/*.cc]] { + dg-runtest $srcfile "$flags -fvtable-verify=std" $libstdcxx_includes + } + } +} diff --git a/libvtv/testsuite/mempool_negative.c b/libvtv/testsuite/libvtv.mempool.cc/mempool_negative.cc index 50ed53109bd..2d5e1d0b531 100644 --- a/libvtv/testsuite/mempool_negative.c +++ b/libvtv/testsuite/libvtv.mempool.cc/mempool_negative.cc @@ -5,26 +5,21 @@ #include <setjmp.h> #include "vtv_malloc.h" +#include "../../../include/vtv-change-permission.h" volatile static int signal_count = 0; sigjmp_buf before_segv; -bool vtv_debug = false; +unsigned int vtv_debug = 0; static void handler(int sig, siginfo_t *si, void *unused) { - /* - printf("Got SIGSEGV at address: 0x%lx\n", - (long) si->si_addr); - */ - signal_count++; /* You are not supposed to longjmp out of a signal handler but it seems to work for this test case and it simplifies it */ siglongjmp(before_segv, 1); - /* exit(1); */ } /* Try to modify the memory pointed by "s" but dont actually change the values. @@ -38,13 +33,13 @@ void mempoke(void * s, size_t n) ret = sigsetjmp(before_segv, 1); if (ret == 0) p[0] = p[0]; - /* printf("after first setjmp ret=%d\n", ret); */ + assert(ret == 1 && signal_count == 1); ret = sigsetjmp(before_segv, 1); if (ret == 0) p[n - 1] = p[n - 1]; - /* printf("after second setjmp ret=%d\n", ret); */ + assert(ret == 1 && signal_count == 2); } @@ -61,6 +56,8 @@ int main() if (sigaction(SIGSEGV, &sa, NULL) == -1) assert(0); + /* Make the 'bookkeeping' vars read-write. */ + __VLTChangePermission (__VLTP_READ_WRITE); __vtv_malloc_init(); size = 10; diff --git a/libvtv/testsuite/mempool_positive.c b/libvtv/testsuite/libvtv.mempool.cc/mempool_positive.cc index 511f50a1040..5e60df9b686 100644 --- a/libvtv/testsuite/mempool_positive.c +++ b/libvtv/testsuite/libvtv.mempool.cc/mempool_positive.cc @@ -4,8 +4,9 @@ #include <stdio.h> #include "vtv_malloc.h" +#include "../../../include/vtv-change-permission.h" -bool vtv_debug = false; +unsigned int vtv_debug = 0; static void handler(int sig, siginfo_t *si, void *unused) @@ -37,6 +38,8 @@ int main() if (sigaction(SIGSEGV, &sa, NULL) == -1) assert(0); + /* Make the 'bookkeeping' vars read-write. */ + __VLTChangePermission (__VLTP_READ_WRITE); __vtv_malloc_init(); size = 10; diff --git a/libvtv/testsuite/libvtv.mt.cc/mt.exp b/libvtv/testsuite/libvtv.mt.cc/mt.exp new file mode 100644 index 00000000000..e2ee43577a3 --- /dev/null +++ b/libvtv/testsuite/libvtv.mt.cc/mt.exp @@ -0,0 +1,68 @@ +load_lib libvtv-dg.exp +load_gcc_lib gcc-dg.exp + +global VTV_FLAGS +set VTV_FLAGS [list {-O0} {-O2}] + +libvtv_init c++ + +set shlib_ext [get_shlib_extension] +set lang_link_flags "-shared-libgcc -lstdc++" +set lang_test_file_found 0 +set lang_library_path "../libstdc++-v3/src/.libs" + +dg-init + +set blddir [lookfor_file [get_multilibs] libvtv] + +# Find the correct libstdc++ library to use. + +if { $blddir != "" } { + # Look for a static libstdc++ first. + if [file exists "${blddir}/${lang_library_path}/libstdc++.a"] { + set lang_test_file "${lang_library_path}/libstdc++.a" + set lang_test_file_found 1 + # We may have a shared only build, so look for a shared libstdc++. + } elseif [file exists "${blddir}/${lang_library_path}/libstdc++.${shlib_ext}"] { + set lang_test_file "${lang_library_path}/libstdc++.${shlib_ext}" + set lang_test_file_found 1 + } else { + puts "looking for ${blddir}/${lang_library_path}/libstdc++.${shlib_ext}" + puts "No libstdc++ library found, will not execute c++ tests" + } +} elseif { [info exists GXX_UNDER_TEST] } { + set lang_test_file_found 1 + # Needs to exist for libvtv.exp. + set lang_test_file "" +} else { + puts "GXX_UNDER_TEST not defined, will not execute c++ tests" +} + + +global srcdir + +if { $lang_test_file_found } { + # Set the path for finding libstdc++. + if { $blddir != "" } { + set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}" + } else { + set ld_library_path "$always_ld_library_path" + } + append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST] + set_ld_library_path_env_vars + + # Make sure we can find the libstdc++ header files. + set flags_file "${blddir}/../libstdc++-v3/scripts/testsuite_flags" + if { [file exists $flags_file] } { + set libstdcxx_includes [exec sh $flags_file --build-includes] + } else { + set libstdcxx_includes "" + } + + # Run the tests with -fvtable-verify=std + foreach flags $VTV_FLAGS { + foreach srcfile [lsort [glob -nocomplain ${srcdir}/libvtv.mt.cc/*.cc]] { + dg-runtest $srcfile "$flags -fvtable-verify=std -lpthread" $libstdcxx_includes + } + } +} diff --git a/libvtv/testsuite/register_pair_inserts_mt.cc b/libvtv/testsuite/libvtv.mt.cc/register_set_pair_inserts_mt.cc index a79dc1f9196..6df197343f7 100644 --- a/libvtv/testsuite/register_pair_inserts_mt.cc +++ b/libvtv/testsuite/libvtv.mt.cc/register_set_pair_inserts_mt.cc @@ -1,7 +1,11 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> + #include "vtv_utils.h" #include "vtv_rts.h" #include "pthread.h" -#include <stdio.h> /* Multi-threaded test for calls to RegisterPair */ @@ -19,6 +23,11 @@ #define NUM_THREADS 9 +#define KEY_TYPE_FIXED_SIZE 8 +void *key_buffer = malloc (17); +typedef char * name_string; +name_string fake_names[NUM_MAPS]; + /* This variable has to be put in rel.ro */ void * volatile maps[NUM_MAPS] VTV_PROTECTED_VAR; @@ -30,6 +39,29 @@ void * fake_vts [NUM_MAPS * ELEMENTS_PER_MAP]; volatile int current_map = -1; volatile int threads_completed_it = 0; +void +generate_names (void) +{ + int i; + + for (i = 0; i < NUM_MAPS; ++i) + { + fake_names[i] = (char *) malloc (9 * sizeof (char)); + snprintf (fake_names[i], 9, "name%d", i); + } +} + +static uint32_t +vtv_string_hash(const char *in) +{ + const char *s = in; + uint32_t h = 0; + + for ( ; *s; ++s) + h = 5 * h + *s; + return h; +} + void * do_register_pairs(void *) { for (int k = 0; k < NUM_REPEATS; k++) @@ -37,22 +69,44 @@ void * do_register_pairs(void *) int curr_fake_vt = 0; for (int i = 0; i < NUM_MAPS; i++) { + uint32_t *value_ptr = (uint32_t *) key_buffer; + uint32_t len1 = strlen (fake_names[i]); + uint32_t hash_value = vtv_string_hash (fake_names[i]); + void *temp_array[ELEMENTS_PER_MAP]; + while (current_map < (k*NUM_MAPS + i)) ; __VLTChangePermission(__VLTP_READ_WRITE); - for (int j = 0; j < ELEMENTS_PER_MAP; j++) - { + *value_ptr = len1; + value_ptr++; + *value_ptr = hash_value; + + memcpy ((char *) key_buffer + KEY_TYPE_FIXED_SIZE, fake_names[i], + len1); + + #ifdef VTV_DEBUG - __VLTRegisterPairDebug((void **) &maps[i], &fake_vts[curr_fake_vt], 0, 0, 0, 0); + __VLTRegisterPairDebug ((void **) &maps[i], (char *) key_buffer, 128, + &fake_vts[curr_fake_vt], "", ""); #else - __VLTRegisterPair((void **) &maps[i], &fake_vts[curr_fake_vt]); + __VLTRegisterPair ((void **) &maps[i], (char *) key_buffer, 128, + &fake_vts[curr_fake_vt]); #endif - __VLTVerifyVtablePointer((void **) &maps[i], &fake_vts[curr_fake_vt]); + for (int j = 0; j < ELEMENTS_PER_MAP; j++) + { + temp_array[j] = &fake_vts[curr_fake_vt]; curr_fake_vt++; } +#ifdef VTV_DEBUG + __VLTRegisterSetDebug ((void **) &maps[i], (char *) key_buffer, 128, 100, + (void **) &temp_array); +#else + __VLTRegisterSet ((void **) &maps[i], (char *) key_buffer, 128, 100, + (void **) &temp_array); +#endif __VLTChangePermission(__VLTP_READ_ONLY); int old_value; @@ -78,6 +132,8 @@ int main() { pthread_t thread_ids[NUM_THREADS]; + generate_names(); + for (int t = 0; t < NUM_THREADS; t++ ) if (pthread_create(&thread_ids[t], NULL, do_register_pairs, NULL) != 0) { diff --git a/libvtv/testsuite/register_pair_mt.cc b/libvtv/testsuite/libvtv.mt.cc/register_set_pair_mt.cc index e421c4f0d2b..1d480a1e3b8 100644 --- a/libvtv/testsuite/register_pair_mt.cc +++ b/libvtv/testsuite/libvtv.mt.cc/register_set_pair_mt.cc @@ -1,7 +1,11 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> + #include "vtv_utils.h" #include "vtv_rts.h" #include "pthread.h" -#include <stdio.h> /* Multi-threaded test for calls to RegisterPair */ @@ -19,6 +23,11 @@ #define NUM_THREADS 9 +#define KEY_TYPE_FIXED_SIZE 8 +void *key_buffer = malloc (17); +typedef char * name_string; +name_string fake_names[NUM_MAPS]; + /* This variable has to be put in rel.ro */ void * volatile maps[NUM_MAPS] VTV_PROTECTED_VAR; @@ -30,6 +39,29 @@ void * fake_vts [NUM_MAPS * ELEMENTS_PER_MAP]; volatile int current_map = -1; volatile int threads_completed_it = 0; +void +generate_names (void) +{ + int i; + + for (i = 0; i < NUM_MAPS; ++i) + { + fake_names[i] = (char *) malloc (9 * sizeof (char)); + snprintf (fake_names[i], 9, "name%d", i); + } +} + +static uint32_t +vtv_string_hash(const char *in) +{ + const char *s = in; + uint32_t h = 0; + + for ( ; *s; ++s) + h = 5 * h + *s; + return h; +} + void * do_register_pairs(void *) { for (int k = 0; k < NUM_REPEATS; k++) @@ -37,22 +69,44 @@ void * do_register_pairs(void *) int curr_fake_vt = 0; for (int i = 0; i < NUM_MAPS; i++) { + uint32_t *value_ptr = (uint32_t *) key_buffer; + uint32_t len1 = strlen (fake_names[i]); + uint32_t hash_value = vtv_string_hash (fake_names[i]); + void *temp_array[ELEMENTS_PER_MAP]; + while (current_map < (k*NUM_MAPS + i)) ; - + __VLTChangePermission(__VLTP_READ_WRITE); + + *value_ptr = len1; + value_ptr++; + *value_ptr = hash_value; + + memcpy ((char *) key_buffer + KEY_TYPE_FIXED_SIZE, fake_names[i], + len1); + - for (int j = 0; j < ELEMENTS_PER_MAP; j++) - { #ifdef VTV_DEBUG - __VLTRegisterPair((void **) &maps[i], &fake_vts[curr_fake_vt], 0, 0, 0, 0); + __VLTRegisterPairDebug ((void **) &maps[i], (char *) key_buffer, 128, + &fake_vts[curr_fake_vt], "", ""); #else - __VLTRegisterPair((void **) &maps[i], &fake_vts[curr_fake_vt]); + __VLTRegisterPair ((void **) &maps[i], (char *) key_buffer, 128, + &fake_vts[curr_fake_vt]); #endif - __VLTVerifyVtablePointer((void **) &maps[i], &fake_vts[curr_fake_vt]); + for (int j = 0; j < ELEMENTS_PER_MAP; j++) + { + temp_array[j] = &fake_vts[curr_fake_vt]; curr_fake_vt++; } +#ifdef VTV_DEBUG + __VLTRegisterSetDebug ((void **) &maps[i], (char *) key_buffer, 128, 100, + (void **) &temp_array); +#else + __VLTRegisterSet ((void **) &maps[i], (char *) key_buffer, 128, 100, + (void **) &temp_array); +#endif __VLTChangePermission(__VLTP_READ_ONLY); int old_value; @@ -77,6 +131,8 @@ void * do_register_pairs(void *) int main() { pthread_t thread_ids[NUM_THREADS]; + + generate_names (); for (int t = 0; t < NUM_THREADS; t++ ) if (pthread_create(&thread_ids[t], NULL, do_register_pairs, NULL) != 0) diff --git a/libvtv/testsuite/other-tests/Makefile.am b/libvtv/testsuite/other-tests/Makefile.am new file mode 100644 index 00000000000..56f76a79f5b --- /dev/null +++ b/libvtv/testsuite/other-tests/Makefile.am @@ -0,0 +1,52 @@ +## Makefile for the testsuite subdirectory of the VTV library. +## +## Copyright (C) 2013 Free Software Foundation, Inc. +## +## Process this file with automake to produce Makefile.in. +## +## This file is part of the Vtable Verification (VTV) 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/>. + +AUTOMAKE_OPTIONS = nostdinc + +# Runs the testsuite via a script. + +# Create subdirectories. +stamp-subdir: + if test ! -d lib64; then \ + mkdir -p lib64; \ + fi; \ + if test ! -d lib32; then \ + mkdir -p lib32; \ + fi; \ + echo `date` > stamp-subdir; + + +testing_script=${libvtv_srcdir}/scripts/run-testsuite.sh +check-script: ${testing_script} stamp-subdir + -@(chmod +x ${testing_script}; \ + ${testing_script} ${libvtv_srcdir} ${libvtv_builddir}) + +check-am: + $(MAKE) $(AM_MAKEFLAGS) check-script + +.PHONY: check-script + +# By adding these files here, automake will remove them for 'make clean' +CLEANFILES = *.out environment-fail-* stamp-* replace-fail-* + +# To remove directories. +clean-local: + rm -rf lib* diff --git a/libvtv/testsuite/other-tests/Makefile.in b/libvtv/testsuite/other-tests/Makefile.in new file mode 100644 index 00000000000..66a75e16ea6 --- /dev/null +++ b/libvtv/testsuite/other-tests/Makefile.in @@ -0,0 +1,379 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = testsuite +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ + $(top_srcdir)/../config/depstand.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ + $(top_srcdir)/../config/libstdc++-raw-cxx.m4 \ + $(top_srcdir)/../config/multi.m4 \ + $(top_srcdir)/../config/override.m4 \ + $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ + $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/../libtool.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX_RAW_CXX_CXXFLAGS = @LIBSTDCXX_RAW_CXX_CXXFLAGS@ +LIBSTDCXX_RAW_CXX_LDFLAGS = @LIBSTDCXX_RAW_CXX_LDFLAGS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XCFLAGS = @XCFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_shared = @enable_shared@ +enable_static = @enable_static@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libtool_VERSION = @libtool_VERSION@ +libvtv_builddir = @libvtv_builddir@ +libvtv_srcdir = @libvtv_srcdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +multi_basedir = @multi_basedir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_noncanonical = @target_noncanonical@ +target_os = @target_os@ +target_vendor = @target_vendor@ +toolexecdir = @toolexecdir@ +toolexeclibdir = @toolexeclibdir@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +toplevel_builddir = @toplevel_builddir@ +toplevel_srcdir = @toplevel_srcdir@ +AUTOMAKE_OPTIONS = nostdinc +testing_script = ${libvtv_srcdir}/scripts/run-testsuite.sh + +# By adding these files here, automake will remove them for 'make clean' +CLEANFILES = *.out environment-fail-* stamp-* replace-fail-* +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign testsuite/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-local mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + clean-local distclean distclean-generic distclean-libtool dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + + +# Runs the testsuite via a script. + +# Create subdirectories. +stamp-subdir: + if test ! -d lib64; then \ + mkdir -p lib64; \ + fi; \ + if test ! -d lib32; then \ + mkdir -p lib32; \ + fi; \ + echo `date` > stamp-subdir; +check-script: ${testing_script} stamp-subdir + -@(chmod +x ${testing_script}; \ + ${testing_script} ${libvtv_srcdir} ${libvtv_builddir}) + +check-am: + $(MAKE) $(AM_MAKEFLAGS) check-script + +.PHONY: check-script + +# To remove directories. +clean-local: + rm -rf lib* + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libvtv/testsuite/other-tests/README b/libvtv/testsuite/other-tests/README new file mode 100644 index 00000000000..a64047460a6 --- /dev/null +++ b/libvtv/testsuite/other-tests/README @@ -0,0 +1,8 @@ +This directory contains tests that have not yet been converted to +proper dejagnu tests. If you look at the run_testsuite script in +libvtv/scripts, you should get a fair idea as to how to run these +tests. The plan is to convert these tests into proper dejangnu tests +sometime in the near future. + + +Aug. 30, 2013
\ No newline at end of file diff --git a/libvtv/testsuite/dlopen.cc b/libvtv/testsuite/other-tests/dlopen.cc index 4ffbe83acf7..4ffbe83acf7 100644 --- a/libvtv/testsuite/dlopen.cc +++ b/libvtv/testsuite/other-tests/dlopen.cc diff --git a/libvtv/testsuite/dlopen_mt.cc b/libvtv/testsuite/other-tests/dlopen_mt.cc index 772e8a733ed..772e8a733ed 100644 --- a/libvtv/testsuite/dlopen_mt.cc +++ b/libvtv/testsuite/other-tests/dlopen_mt.cc diff --git a/libvtv/testsuite/environment-fail-32.s b/libvtv/testsuite/other-tests/environment-fail-32.s index cac501652a7..cac501652a7 100644 --- a/libvtv/testsuite/environment-fail-32.s +++ b/libvtv/testsuite/other-tests/environment-fail-32.s diff --git a/libvtv/testsuite/environment-fail-64.s b/libvtv/testsuite/other-tests/environment-fail-64.s index d75db248b07..d75db248b07 100644 --- a/libvtv/testsuite/environment-fail-64.s +++ b/libvtv/testsuite/other-tests/environment-fail-64.s diff --git a/libvtv/testsuite/field-test.cc b/libvtv/testsuite/other-tests/field-test.cc index b6f34bca02c..b6f34bca02c 100644 --- a/libvtv/testsuite/field-test.cc +++ b/libvtv/testsuite/other-tests/field-test.cc diff --git a/libvtv/testsuite/replace-fail.cc b/libvtv/testsuite/other-tests/replace-fail.cc index 2b4070eec77..2b4070eec77 100644 --- a/libvtv/testsuite/replace-fail.cc +++ b/libvtv/testsuite/other-tests/replace-fail.cc diff --git a/libvtv/testsuite/so.cc b/libvtv/testsuite/other-tests/so.cc index 3f0a346f1e8..3f0a346f1e8 100644 --- a/libvtv/testsuite/so.cc +++ b/libvtv/testsuite/other-tests/so.cc diff --git a/libvtv/testsuite/temp_deriv.cc b/libvtv/testsuite/other-tests/temp_deriv.cc index ca360c0bc91..ca360c0bc91 100644 --- a/libvtv/testsuite/temp_deriv.cc +++ b/libvtv/testsuite/other-tests/temp_deriv.cc diff --git a/libvtv/testsuite/temp_deriv2.cc b/libvtv/testsuite/other-tests/temp_deriv2.cc index 78b43f8b08b..78b43f8b08b 100644 --- a/libvtv/testsuite/temp_deriv2.cc +++ b/libvtv/testsuite/other-tests/temp_deriv2.cc diff --git a/libvtv/testsuite/temp_deriv3.cc b/libvtv/testsuite/other-tests/temp_deriv3.cc index 924c47e9628..924c47e9628 100644 --- a/libvtv/testsuite/temp_deriv3.cc +++ b/libvtv/testsuite/other-tests/temp_deriv3.cc diff --git a/libvtv/testsuite/parts-test.list b/libvtv/testsuite/parts-test.list deleted file mode 100644 index fdf95a8876c..00000000000 --- a/libvtv/testsuite/parts-test.list +++ /dev/null @@ -1 +0,0 @@ -parts-test-main.cc parts-test-extra-parts.cc parts-test-extra-parts-views.cc diff --git a/libvtv/testsuite/register_pair.cc b/libvtv/testsuite/register_pair.cc deleted file mode 100644 index 0759c472df1..00000000000 --- a/libvtv/testsuite/register_pair.cc +++ /dev/null @@ -1,39 +0,0 @@ -#include "vtv_utils.h" -#include "vtv_rts.h" - -/* This configuration will test mostly inserting of elements that are already inserted since - the number of repeats is 200 */ - -#define NUM_MAPS 4000 -#define ELEMENTS_PER_MAP 100 -#define NUM_REPEATS 200 - -/* This variable has to be put in rel.ro */ -void * maps[NUM_MAPS] VTV_PROTECTED_VAR; - -struct fake_vt { - void * fake_vfp [4]; -}; -void * fake_vts [NUM_MAPS * ELEMENTS_PER_MAP]; - -int main() -{ - __VLTChangePermission(__VLTP_READ_WRITE); - - for (int k = 0; k < NUM_REPEATS; k++) - { - int curr_fake_vt = 0; - for (int i = 0; i < NUM_MAPS; i++) - for (int j = 0; j < ELEMENTS_PER_MAP; j++) - { -#ifdef VTV_DEBUG - __VLTRegisterPairDebug(&maps[i], &fake_vts[curr_fake_vt]); -#endif - curr_fake_vt++; - } - } - - __VLTChangePermission(__VLTP_READ_ONLY); - - return 0; -} diff --git a/libvtv/testsuite/register_pair_inserts.cc b/libvtv/testsuite/register_pair_inserts.cc deleted file mode 100644 index 72d6d968465..00000000000 --- a/libvtv/testsuite/register_pair_inserts.cc +++ /dev/null @@ -1,46 +0,0 @@ -#include "vtv_utils.h" -#include "vtv_rts.h" - -/* This configuration will test mostly inserting of new elements since - the number of repeats is 1. It should also do a lot of rehashing */ - -/* This test case may fail depending on the system configuration. - Check the value of /proc/sys/vm/max_map_count and fix by doing - Ex: sudo sh -c "echo 131060 > /proc/sys/vm/max_map_count" */ - -#define NUM_MAPS 40000 -#define ELEMENTS_PER_MAP 100 -#define NUM_REPEATS 1 - -/* This variable has to be put in rel.ro */ -void * maps[NUM_MAPS] VTV_PROTECTED_VAR; - -struct fake_vt { - void * fake_vfp [4]; -}; -void * fake_vts [NUM_MAPS * ELEMENTS_PER_MAP]; - - -int main() -{ - __VLTChangePermission(__VLTP_READ_WRITE); - - for (int k = 0; k < NUM_REPEATS; k++) - { - int curr_fake_vt = 0; - for (int i = 0; i < NUM_MAPS; i++) - for (int j = 0; j < ELEMENTS_PER_MAP; j++) - { -#ifdef VTV_DEBUG - __VLTRegisterPairDebug(&maps[i], &fake_vts[curr_fake_vt], 0, 0, 0, 0); -#else - __VLTRegisterPair(&maps[i], &fake_vts[curr_fake_vt]); -#endif - curr_fake_vt++; - } - } - - __VLTChangePermission(__VLTP_READ_ONLY); - - return 0; -} diff --git a/lto-plugin/ChangeLog b/lto-plugin/ChangeLog index c8ed0f3f6e7..070cf380817 100644 --- a/lto-plugin/ChangeLog +++ b/lto-plugin/ChangeLog @@ -1,3 +1,7 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2012-09-14 David Edelsohn <dje.gcc@gmail.com> * configure: Regenerated. diff --git a/lto-plugin/configure b/lto-plugin/configure index 4900d8079bf..7a0d953e90b 100755 --- a/lto-plugin/configure +++ b/lto-plugin/configure @@ -6044,7 +6044,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -6069,7 +6069,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -6088,7 +6091,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -10552,7 +10558,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10555 "configure" +#line 10561 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10658,7 +10664,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10661 "configure" +#line 10667 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/zlib/ChangeLog.gcj b/zlib/ChangeLog.gcj index 13b62a4a129..6025369262a 100644 --- a/zlib/ChangeLog.gcj +++ b/zlib/ChangeLog.gcj @@ -1,3 +1,7 @@ +2013-09-20 Alan Modra <amodra@gmail.com> + + * configure: Regenerate. + 2012-11-16 Matthias Klose <doko@ubuntu.com> * Imported zlib 1.2.7; merged local changes. diff --git a/zlib/configure b/zlib/configure index 8e4a93f2abe..c71984f4c67 100755 --- a/zlib/configure +++ b/zlib/configure @@ -5853,7 +5853,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -5878,7 +5878,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -5897,7 +5900,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -10394,7 +10400,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10397 "configure" +#line 10403 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10500,7 +10506,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10503 "configure" +#line 10509 "configure" #include "confdefs.h" #if HAVE_DLFCN_H |