diff options
author | burnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-06-17 19:31:06 +0000 |
---|---|---|
committer | burnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-06-17 19:31:06 +0000 |
commit | 8e882a1674e70cdea3bf8630a7613fe2bf12e52d (patch) | |
tree | 3580b7403687d7d146efbcceecee9d57deff3d8f /gcc | |
parent | fade5ce98b583fa416ba84b4cc3cad12af227f57 (diff) | |
parent | 634a5ad7fc8a4498978609c4e523b29658affa22 (diff) | |
download | gcc-8e882a1674e70cdea3bf8630a7613fe2bf12e52d.tar.gz |
2014-06-17 Tobias Burnus <burnus@net-b.de>
* Merge from the trunk to r211744.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/fortran-dev@211745 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
420 files changed, 13760 insertions, 10135 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 839cb0d6ab1..2820759a280 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,903 @@ +2014-06-17 Richard Biener <rguenther@suse.de> + + * genopinit.c (main): Use vec<>::qsort method. + * tree-ssa-loop-niter.c (discover_iteration_bound_by_body_walk): + Likewise. + * tree-vect-data-refs.c (vect_analyze_data_ref_accesses): Likewise. + +2014-06-17 Matthew Fortune <matthew.fortune@imgtec.com> + + * config/mips/mips-protos.h (mips_expand_fcc_reload): Remove. + * config/mips/mips.c (mips_expand_fcc_reload): Remove. + (mips_move_to_gpr_cost): Remove ST_REGS case. + (mips_move_from_gpr_cost): Likewise. + (mips_register_move_cost): Likewise. + (mips_secondary_reload_class): Likewise. + +2014-06-17 Richard Biener <rguenther@suse.de> + + * passes.def (pass_all_early_optimizations): Remove copy-prop pass. + (pass_all_optimizations): Move 3rd copy-prop pass from after + fre to before ifcombine/phiopt. + +2014-06-17 Richard Biener <rguenther@suse.de> + + * tree-switch-conversion.c (collect_switch_conv_info): Simplify + and allow all blocks to be forwarders. + +2014-06-17 Yufeng Zhang <yufeng.zhang@arm.com> + + PR target/61483 + * config/aarch64/aarch64.c (aarch64_layout_arg): Add new local + variable 'size'; calculate 'size' right in the front; use + 'size' to compute 'nregs' (when 'allocate_ncrn != 0') and + pcum->aapcs_stack_words. + +2014-06-17 Nick Clifton <nickc@redhat.com> + + * config/msp430/msp430.md (mulhisi3): Add a NOP after the DINT. + (umulhi3, mulsidi3, umulsidi3): Likewise. + +2014-06-17 Thomas Schwinge <thomas@codesourcery.com> + + PR middle-end/61508 + * fold-const.c (fold_checksum_tree) <TS_DECL_WITH_VIS>: Remove + check for section name. + +2014-06-17 Richard Biener <rguenther@suse.de> + + * tree-ssa-propagate.c: Include domwalk.h. + (substitute_and_fold): Outline main worker into a domwalker ... + (substitute_and_fold_dom_walker::before_dom_children): ... here. + Schedule stmts we can fully propagate for removal. Remove + poor-mans DCE. + (substitute_and_fold): Apply a dominator walk to perform + substitution. Process stmts scheduled for removal here. + +2014-06-17 Richard Biener <rguenther@suse.de> + + * tree-ssa-loop-im.c (determine_max_movement): Adjust cost + of PHI node moving. + +2014-06-17 Kugan Vivekanandarajah <kuganv@linaro.org> + + * config/arm/arm.c (arm_atomic_assign_expand_fenv): call + default_atomic_assign_expand_fenv for !TARGET_HARD_FLOAT. + (arm_init_builtins) : Initialize builtins __builtins_arm_set_fpscr and + __builtins_arm_get_fpscr only when TARGET_HARD_FLOAT. + * config/arm/vfp.md (set_fpscr): Make pattern conditional on + TARGET_HARD_FLOAT. + (get_fpscr) : Likewise. + +2014-06-16 Vladimir Makarov <vmakarov@redhat.com> + + PR rtl-optimization/61325 + * lra-constraints.c (valid_address_p): Add forward declaration. + (simplify_operand_subreg): Check address validity before and after + alter_reg of memory subreg. + +2014-06-16 Uros Bizjak <ubizjak@gmail.com> + + * config/i386/i386.c (decide_alg): Correctly handle + maximum size of stringop algorithm. + +2014-06-16 Yury Gribov <y.gribov@samsung.com> + + * asan.c (build_check_stmt): Fix maybe-uninitialized warning. + +2014-06-16 Vladimir Makarov <vmakarov@redhat.com> + + PR rtl-optimization/61522 + * lra-assigns.c (assign_by_spills): Check null targetm.spill_class. + +2014-06-16 Jan Hubicka <hubicka@ucw.cz> + + Revert: + * symtab.c (symtab_node::reset_section): New method. + * cgraph.c (cgraph_node_cannot_be_local_p_1): Accept non-local + for localization. + * cgraph.h (reset_section): Declare. + * ipa-inline-analysis.c (do_estimate_growth): Check for comdat groups; + do not consider comdat locals. + * cgraphclones.c (set_new_clone_decl_and_node_flags): Get section + for new symbol. + * ipa-visiblity.c (cgraph_externally_visible_p): Cleanup. + (update_visibility_by_resolution_info): Consider UNDEF; fix checking; + reset sections of symbols dragged out of the comdats. + (function_and_variable_visibility): Reset sections of localized symbols. + +2014-06-16 Richard Biener <rguenther@suse.de> + + PR tree-optimization/61482 + * tree-vrp.c (adjust_range_with_scev): Avoid setting of + [-INF(OVF), +INF(OVF)] range. + +2014-06-16 Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com> + + * config/i386/i386.c (ix86_expand_sse2_mulvxdi3): Issue + instructions "vpmuludq" and "vpaddq" instead of "vpmacsdql" for + handling 32-bit multiplication. + +2014-06-16 Chung-Lin Tang <cltang@codesourcery.com> + + PR middle-end/61430 + * lra-lives.c (process_bb_lives): Skip creating copy during + insn scan when src/dest has constrained to same regno. + +2014-06-15 Jan Hubicka <hubicka@ucw.cz> + + * tree-vect-data-refs.c (vect_can_force_dr_alignment_p): Check again + DECL_IN_CONSTANT_POOL and TREE_ASM_WRITTEN. + +2014-06-16 Yury Gribov <y.gribov@samsung.com> + + * asan.c (check_func): New function. + (maybe_create_ssa_name): Likewise. + (build_check_stmt_with_calls): Likewise. + (use_calls_p): Likewise. + (report_error_func): Change interface. + (build_check_stmt): Allow non-integer lengths; add support + for new parameter. + (asan_instrument): Likewise. + (instrument_mem_region_access): Moved code to build_check_stmt. + (instrument_derefs): Likewise. + (instrument_strlen_call): Likewise. + * cfgcleanup.c (old_insns_match_p): Add support for new functions. + * doc/invoke.texi: Describe new parameter. + * params.def: Define new parameter. + * params.h: Likewise. + * sanitizer.def: Describe new builtins. + +2014-06-16 Richard Biener <rguenther@suse.de> + + * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): + Make all defs available at the end. + (eliminate): If we remove a PHI node schedule cfg-cleanup. + +2014-06-18 Jakub Jelinek <jakub@redhat.com> + + PR plugins/45078 + * config.gcc (arm*-*-linux-*): Include vxworks-dummy.h in tm_file. + +2014-06-16 Richard Sandiford <rdsandiford@googlemail.com> + + PR bootstrap/61516 + * auto-inc-dec.c (merge_in_block): Fix location of insn_info + initialization. Replace remaining use of uid. + +2014-06-15 Jan Hubicka <hubicka@ucw.cz> + + * c-family/c-common.c (handle_tls_model_attribute): Use + set_decl_tls_model. + * c-family/c-common.c (handle_tls_model_attribute): Use + set_decl_tls_model. + * cgraph.h (struct varpool_node): Add tls_model. + * tree.c (decl_tls_model, set_decl_tls_model): New functions. + * tree.h (DECL_TLS_MODEL): Update. + (DECL_THREAD_LOCAL_P): Check that variable is static. + (decl_tls_model): Declare. + (set_decl_tls_model): Declare. + * tree-emutls.c (get_emutls_init_templ_addr): First build decl and then + set symbol prorperties. + (get_emutls_init_templ_addr): Cleanup. + (new_emutls_decl): Update. + * lto-cgraph.c (lto_output_varpool_node): Stream TLS model + (lto_input_varpool_node): Likewise. + * lto-streamer-out.c (hash_tree): Likewise. + * tree-streamer-in.c (unpack_ts_decl_with_vis_value_fields): Do + not stream DECL_TLS_MODEL. + * tree-profile.c (init_ic_make_global_vars): Use + set_decl_tls_model. + * tree-core.h (tree_decl_with_vis): Remove tls_model; + update comments. + +2014-06-15 Richard Sandiford <rdsandiford@googlemail.com> + + * df.h (DF_REF_REG_USE_P, DF_MWS_REG_USE_P): Remove null checks. + +2014-06-15 Richard Sandiford <rdsandiford@googlemail.com> + + * df.h (df_mw_hardreg, df_base_ref): Add a link pointer. + (df_insn_info): Turn defs, uses, eq_uses and mw_hardregs into linked + lists. + (df_scan_bb_info): Likewise artificial_defs and artificial_uses. + (DF_REF_NEXT_LOC, DF_MWS_NEXT): New macros. + (FOR_EACH_INSN_INFO_DEF, FOR_EACH_INSN_INFO_USE) + (FOR_EACH_INSN_INFO_EQ_USE, FOR_EACH_INSN_INFO_MW) + (FOR_EACH_ARTIFICIAL_USE, FOR_EACH_ARTIFICIAL_DEF) + (df_get_artificial_defs, df_get_artificial_uses) + (df_single_def, df_single_use): Update accordingly. + (df_refs_chain_dump): Take the first element in a linked list as + parameter, rather than a pointer to an array of pointers. + * df-core.c (df_refs_chain_dump, df_mws_dump): Likewise. + * df-problems.c (df_rd_bb_local_compute_process_def): Likewise. + (df_chain_create_bb_process_use): Likewise. + (df_md_bb_local_compute_process_def): Likewise. + * fwprop.c (process_defs, process_uses): Likewise. + (register_active_defs, update_uses): Likewise. + (forward_propagate_asm): Update for new df_ref linking. + * df-scan.c (df_scan_free_ref_vec, df_scan_free_mws_vec): Delete. + (df_null_ref_rec, df_null_mw_rec): Likewise. + (df_scan_free_internal): Don't free df_ref and df_mw_hardreg lists + explicitly. + (df_scan_free_bb_info): Remove check for null artificial_defs. + (df_install_ref_incremental): Adjust for new df_ref linking. + Use a single-element insertion rather than a full sort. + (df_ref_chain_delete_du_chain): Take the first element + in a linked list as parameter, rather than a pointer to an array of + pointers. + (df_ref_chain_delete, df_mw_hardreg_chain_delete): Likewise. + (df_add_refs_to_table, df_refs_verify, df_mws_verify): Likewise. + (df_insn_info_delete): Remove check for null defs and call to + df_scan_free_mws_vec. + (df_insn_rescan): Initialize df_ref and df_mw_hardreg lists to + null rather than df_null_*_rec. + (df_insn_rescan_debug_internal): Likewise, and update null + checks in the same way. Remove check for null defs. + (df_ref_change_reg_with_loc_1): Fix choice of list for defs. + Move a single element rather doing a full sort. + (df_mw_hardreg_chain_delete_eq_uses): Adjust for new df_mw_hardreg + linking. + (df_notes_rescan): Likewise. Use a merge rather than a full sort. + Initialize df_ref and df_mw_hardreg lists to null rather than + df_null_*_rec. + (df_ref_compare): Take df_refs as parameter, transferring the + old interface to... + (df_ref_ptr_compare): ...this new function. + (df_sort_and_compress_refs): Update accordingly. + (df_mw_compare): Take df_mw_hardregs as parameter, transferring the + old interface to... + (df_mw_ptr_compare): ...this new function. + (df_sort_and_compress_mws): Update accordingly. + (df_install_refs, df_install_mws): Return a linked list rather than + an array of pointers. + (df_refs_add_to_chains): Assert that old lists are empty rather + than freeing them. + (df_insn_refs_verify): Don't handle null defs speciailly. + * web.c (union_match_dups): Update for new df_ref linking. + +2014-06-15 Richard Sandiford <rdsandiford@googlemail.com> + + * df.h (df_ref_create, df_ref_remove): Delete. + * df-scan.c (df_ref_create, df_ref_compress_rec): Likewise. + (df_ref_remove): Likewise. + +2014-06-15 Richard Sandiford <rdsandiford@googlemail.com> + + * df.h (df_single_def, df_single_use): New functions. + * ira.c (find_moveable_pseudos): Use them. + +2014-06-15 Richard Sandiford <rdsandiford@googlemail.com> + + * df.h (FOR_EACH_INSN_INFO_MW): New macro. + * df-problems.c (df_note_bb_compute): Use it. + * regstat.c (regstat_bb_compute_ri): Likewise. + +2014-06-15 Richard Sandiford <rdsandiford@googlemail.com> + + * df.h (FOR_EACH_ARTIFICIAL_USE, FOR_EACH_ARTIFICIAL_DEF): New macros. + * cse.c (cse_extended_basic_block): Use them. + * dce.c (mark_artificial_use): Likewise. + * df-problems.c (df_rd_simulate_artificial_defs_at_top): Likewise. + (df_lr_bb_local_compute, df_live_bb_local_compute): Likewise. + (df_chain_remove_problem, df_chain_bb_dump): Likewise. + (df_word_lr_bb_local_compute, df_note_bb_compute): Likewise. + (df_simulate_initialize_backwards): Likewise. + (df_simulate_finalize_backwards): Likewise. + (df_simulate_initialize_forwards): Likewise. + (df_md_simulate_artificial_defs_at_top): Likewise. + * df-scan.c (df_reorganize_refs_by_reg_by_insn): Likewise. + * regrename.c (init_rename_info): Likewise. + * regstat.c (regstat_bb_compute_ri): Likewise. + (regstat_bb_compute_calls_crossed): Likewise. + +2014-06-15 Richard Sandiford <rdsandiford@googlemail.com> + + * df.h (DF_INSN_INFO_MWS, FOR_EACH_INSN_INFO_DEF): New macros. + (FOR_EACH_INSN_INFO_USE, FOR_EACH_INSN_INFO_EQ_USE): Likewise. + (FOR_EACH_INSN_DEF, FOR_EACH_INSN_USE, FOR_EACH_INSN_EQ_USE): Likewise. + * auto-inc-dec.c (find_inc, merge_in_block): Use them. + * combine.c (create_log_links): Likewise. + * compare-elim.c (find_flags_uses_in_insn): Likewise. + (try_eliminate_compare): Likewise. + * cprop.c (make_set_regs_unavailable, mark_oprs_set): Likewise. + * dce.c (deletable_insn_p, find_call_stack_args): Likewise. + (remove_reg_equal_equiv_notes_for_defs): Likewise. + (reset_unmarked_insns_debug_uses, mark_reg_dependencies): Likewise. + (word_dce_process_block, dce_process_block): Likewise. + * ddg.c (def_has_ccmode_p): Likewise. + * df-core.c (df_bb_regno_first_def_find): Likewise. + (df_bb_regno_last_def_find, df_find_def, df_find_use): Likewise. + * df-problems.c (df_rd_simulate_one_insn): Likewise. + (df_lr_bb_local_compute, df_live_bb_local_compute): Likewise. + (df_chain_remove_problem, df_chain_insn_top_dump): Likewise. + (df_chain_insn_bottom_dump, df_word_lr_bb_local_compute): Likewise. + (df_word_lr_simulate_defs, df_word_lr_simulate_uses): Likewise. + (df_remove_dead_eq_notes, df_note_bb_compute): Likewise. + (df_simulate_find_defs, df_simulate_find_uses): Likewise. + (df_simulate_find_noclobber_defs, df_simulate_defs): Likewise. + (df_simulate_uses, df_md_simulate_one_insn): Likewise. + * df-scan.c (df_reorganize_refs_by_reg_by_insn): Likewise. + * fwprop.c (local_ref_killed_between_p): Likewise. + (all_uses_available_at, free_load_extend): Likewise. + * gcse.c (update_bb_reg_pressure, calculate_bb_reg_pressure): Likewise. + * hw-doloop.c (scan_loop): Likewise. + * ifcvt.c (dead_or_predicable): Likewise. + * init-regs.c (initialize_uninitialized_regs): Likewise. + * ira-lives.c (mark_hard_reg_early_clobbers): Likewise. + (process_bb_node_lives): Likewise. + * ira.c (compute_regs_asm_clobbered, build_insn_chain): Likewise. + (find_moveable_pseudos): Likewise. + * loop-invariant.c (check_dependencies, record_uses): Likewise. + * recog.c (peep2_find_free_register): Likewise. + * ree.c (get_defs): Likewise. + * regstat.c (regstat_bb_compute_ri): Likewise. + (regstat_bb_compute_calls_crossed): Likewise. + * sched-deps.c (find_inc, find_mem): Likewise. + * sel-sched-ir.c (maybe_downgrade_id_to_use): Likewise. + (maybe_downgrade_id_to_use, setup_id_reg_sets): Likewise. + * shrink-wrap.c (requires_stack_frame_p): Likewise. + (prepare_shrink_wrap): Likewise. + * store-motion.c (compute_store_table, build_store_vectors): Likewise. + * web.c (union_defs, pass_web::execute): Likewise. + * config/i386/i386.c (increase_distance, insn_defines_reg): Likewise. + (insn_uses_reg_mem, ix86_ok_to_clobber_flags): Likewise. + +2014-06-13 Vladimir Makarov <vmakarov@redhat.com> + + * lra-assign.c (assign_by_spills): Add code to assign vector regs + to inheritance pseudos. + * config/i386/i386.c (ix86_spill_class): Add check on NO_REGS. + +2014-06-13 Peter Bergner <bergner@vnet.ibm.com> + + PR target/61415 + * config/rs6000/rs6000-builtin.def (BU_MISC_1): Delete. + (BU_MISC_2): Rename to ... + (BU_LDBL128_2): ... this. + * config/rs6000/rs6000.h (RS6000_BTM_LDBL128): New define. + (RS6000_BTM_COMMON): Add RS6000_BTM_LDBL128. + * config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Handle + RS6000_BTM_LDBL128. + (rs6000_invalid_builtin): Add long double 128-bit builtin support. + (rs6000_builtin_mask_names): Add RS6000_BTM_LDBL128. + * config/rs6000/rs6000.md (unpacktf_0): Remove define)expand. + (unpacktf_1): Likewise. + * doc/extend.texi (__builtin_longdouble_dw0): Remove documentation. + (__builtin_longdouble_dw1): Likewise. + * doc/sourcebuild.texi (longdouble128): Document. + +2014-06-13 Jeff Law <law@redhat.com> + + PR rtl-optimization/61094 + PR rtl-optimization/61446 + * ree.c (combine_reaching_defs): Get the mode for the copy from + the extension insn rather than the defining insn. + +2014-06-13 Dehao Chen <dehao@google.com> + + * dwarf2out.c (add_linkage_name): Emit more linkage name. + +2014-06-13 Thomas Schwinge <thomas@codesourcery.com> + + * doc/install.texi (--enable-linker-plugin-configure-flags) + (--enable-linker-plugin-flags): Document new flags. + +2014-06-13 Martin Jambor <mjambor@suse.cz> + + PR ipa/61186 + * ipa-devirt.c (possible_polymorphic_call_targets): Store NULL to + cache_token if returning early. + +2014-06-13 Nick Clifton <nickc@redhat.com> + + * config/rx/rx.h (JUMP_ALIGN): Return the log value if user + requested alignment is active. + (LABEL_ALIGN): Likewise. + (LOOP_ALIGN): Likewise. + +2014-06-13 Richard Biener <rguenther@suse.de> + + * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): + Rewrite to propagate the VN result into all uses where + possible and to remove stmts becoming dead because of that. + (eliminate): Generalize stmt removal handling, remove in + reverse dominator order to support proper debug stmt + generation. Update stmts before removing stmts. + * tree-ssa-propagate.c (propagate_tree_value): Remove bogus assert. + +2014-06-13 Thomas Preud'homme <thomas.preudhomme@arm.com> + + PR tree-optimization/61375 + * tree-ssa-math-opts.c (init_symbolic_number): Cancel optimization if + symbolic number cannot be represented in an uint64_t. + (find_bswap_or_nop_1): Likewise. + +2014-06-12 Jan Hubicka <hubicka@ucw.cz> + + * symtab.c (symtab_node::reset_section): New method. + * cgraph.c (cgraph_node_cannot_be_local_p_1): Accept non-local + for localization. + * cgraph.h (reset_section): Declare. + * ipa-inline-analysis.c (do_estimate_growth): Check for comdat groups; + do not consider comdat locals. + * cgraphclones.c (set_new_clone_decl_and_node_flags): Get section + for new symbol. + * ipa-visiblity.c (cgraph_externally_visible_p): Cleanup. + (update_visibility_by_resolution_info): Consider UNDEF; fix checking; + reset sections of symbols dragged out of the comdats. + (function_and_variable_visibility): Reset sections of + localized symbols. + +2014-06-12 Jan Hubicka <hubicka@ucw.cz> + + * tree-vect-data-refs.c (vect_can_force_dr_alignment_p): Reorg + to use symtab and decl_binds_to_current_def_p + * tree-vectorizer.c (increase_alignment): Increase alignment + of alias target, too. + +2014-06-12 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/61486 + * gimplify.c (struct gimplify_omp_ctx): Add distribute field. + (gimplify_adjust_omp_clauses): Don't or in GOVD_LASTPRIVATE + if outer combined construct is distribute. + (gimplify_omp_for): For OMP_DISTRIBUTE set + gimplify_omp_ctxp->distribute. + * omp-low.c (scan_sharing_clauses) <case OMP_CLAUSE_SHARED>: For + GIMPLE_OMP_TEAMS, if decl isn't global in outer context, record + mapping into decl map. + +2014-06-12 Jason Merrill <jason@redhat.com> + + * common.opt (fabi-version): Change default to 0. + +2014-06-12 Jason Merrill <jason@redhat.com> + + * toplev.c (process_options): Reject -fabi-version=1. + +2014-06-12 Jeff Law <law@redhat.com> + + PR tree-optimization/61009 + * tree-ssa-threadedge.c (thread_through_normal_block): Correct return + value when we stop processing a block due to problematic PHIs. + +2014-06-12 Alan Lawrence <alan.lawrence@arm.com> + + * config/aarch64/arm_neon.h (vmlaq_n_f64, vmlsq_n_f64, vrsrtsq_f64, + vcge_p8, vcgeq_p8, vcgez_p8, vcgez_u8, vcgez_u16, vcgez_u32, vcgez_u64, + vcgezq_p8, vcgezq_u8, vcgezq_u16, vcgezq_u32, vcgezq_u64, vcgezd_u64, + vcgt_p8, vcgtq_p8, vcgtz_p8, vcgtz_u8, vcgtz_u16, vcgtz_u32, vcgtz_u64, + vcgtzq_p8, vcgtzq_u8, vcgtzq_u16, vcgtzq_u32, vcgtzq_u64, vcgtzd_u64, + vcle_p8, vcleq_p8, vclez_p8, vclez_u64, vclezq_p8, vclezd_u64, vclt_p8, + vcltq_p8, vcltz_p8, vcltzq_p8, vcltzd_u64): Remove functions as they + are not in the spec. + +2014-06-10 Alan Lawrence <alan.lawrence@arm.com> + + PR target/59843 + * config/aarch64/aarch64-modes.def: Add V1DFmode. + * config/aarch64/aarch64.c (aarch64_vector_mode_supported_p): + Support V1DFmode. + +2014-06-12 Eric Botcazou <ebotcazou@adacore.com> + + * tree-core.h (DECL_NONALIASED): Use proper spelling in comment. + +2014-06-12 Georg-Johann Lay <avr@gjlay.de> + + PR target/61443 + * config/avr/avr.md (push<mode>1): Avoid (subreg(mem)) when + loading from address spaces. + +2014-06-12 Martin Liska <mliska@suse.cz> + + PR ipa/61462 + * ipa-prop.c (ipa_make_edge_direct_to_target): Check that gimple call + statement is reachable. + +2014-06-11 Jan Hubicka <hubicka@ucw.cz> + + * symtab.c (section_hash): New hash. + (symtab_unregister_node): Clear section before freeing. + (hash_section_hash_entry): New haser. + (eq_sections): New function. + (symtab_node::set_section_for_node): New method. + (set_section_1): Update. + (symtab_node::set_section): Take string instead of tree as parameter. + (symtab_resolve_alias): Update. + * cgraph.h (section_hash_entry_d): New structure. + (section_hash_entry): New typedef. + (cgraph_node): Change comdat_group_ to x_comdat_group, + change section_ to x_section and turn into section_hash_entry; + update accestors; put set_section_for_node offline. + * tree.c (decl_section_name): Turn into string. + (set_decl_section_name): Change parameter to be string. + * tree.h (decl_section_name, set_decl_section_name): Update prototypes. + * sdbout.c (sdbout_one_type): Update. + * tree-vect-data-refs.c (vect_can_force_dr_alignment_p): Update. + * varasm.c (IN_NAMED_SECTION, get_named_section, resolve_unique_section, + hot_function_section, get_named_text_section, + USE_SELECT_SECTION_FOR_FUNCTIONS, default_function_rodata_section, + make_decl_rtl, default_unique_section): Update. + * config/c6x/c6x.c (c6x_in_small_data_p): Update. + (c6x_elf_unique_section): Update. + * config/nios2/nios2.c (nios2_in_small_data_p): Update. + * config/pa/pa.c (pa_function_section): Update. + * config/pa/pa.h (IN_NAMED_SECTION_P): Update. + * config/ia64/ia64.c (ia64_in_small_data_p): Update. + * config/arc/arc.c (arc_in_small_data_p): Update. + * config/arm/unknown-elf.h (IN_NAMED_SECTION_P): Update. + * config/mcore/mcore.c (mcore_unique_section): Update. + * config/mips/mips.c (mips16_build_function_stub): Update. + (mips16_build_call_stub): Update. + (mips_function_rodata_section): Update. + (mips_in_small_data_p): Update. + * config/score/score.c (score_in_small_data_p): Update. + * config/rx/rx.c (rx_in_small_data): Update. + * config/rs6000/rs6000.c (rs6000_elf_in_small_data_p): Update. + (rs6000_xcoff_asm_named_section): Update. + (rs6000_xcoff_unique_section): Update. + * config/frv/frv.c (frv_string_begins_with): Update. + (frv_in_small_data_p): Update. + * config/v850/v850.c (v850_encode_data_area): Update. + * config/bfin/bfin.c (DECL_SECTION_NAME): Update. + (bfin_handle_l1_data_attribute): Update. + (bfin_handle_l2_attribute): Update. + * config/mep/mep.c (mep_unique_section): Update. + * config/microblaze/microblaze.c (microblaze_elf_in_small_data_p): + Update. + * config/h8300/h8300.c (h8300_handle_eightbit_data_attribute): Update. + (h8300_handle_tiny_data_attribute): Update. + * config/m32r/m32r.c (m32r_in_small_data_p): Update. + (m32r_in_small_data_p): Update. + * config/alpha/alpha.c (alpha_in_small_data_p): Update. + * config/i386/i386.c (ix86_in_large_data_p): Update. + * config/i386/winnt.c (i386_pe_unique_section): Update. + * config/darwin.c (darwin_function_section): Update. + * config/lm32/lm32.c (lm32_in_small_data_p): Update. + * tree-emutls.c (get_emutls_init_templ_addr): Update. + (new_emutls_decl): Update. + * lto-cgraph.c (lto_output_node, input_node, input_varpool_node, + input_varpool_node): Update. + (ead_string_cst): Turn to ... + (read_string): ... this one. + * dwarf2out.c (secname_for_decl): Update. + * asan.c (asan_protect_global): Update. + +2014-06-11 DJ Delorie <dj@redhat.com> + + * config/rx/rx.h (FUNCTION_BOUNDARY): Adjust for RX100/200 4-byte + cache lines. + * config/rx/rx.c (rx_option_override): Likewise. + (rx_align_for_label): Likewise. + + * config/rx/rx.c (rx_max_skip_for_label): Don't skip anything if -Os. + +2014-06-11 Maciej W. Rozycki <macro@codesourcery.com> + + * config/mmix/mmix-protos.h (mmix_asm_output_source_line): Remove + prototype. + +2014-06-11 Richard Sandiford <rdsandiford@googlemail.com> + + * common.md: New file. + * doc/md.texi: Update description of generic, machine-independent + constraints. + * config/s390/constraints.md (e): Delete. + * Makefile.in (md_file): Include common.md. + * config/m32c/t-m32c (md_file): Likewise. + * genpreds.c (general_mem): New array. + (generic_constraint_letters): Remove constraints now defined by + common.md. + (add_constraint): Map TARGET_MEM_CONSTRAINT to general_mem. + Allow the first character to be '<' or '>' as well. + * genoutput.c (general_mem): New array. + (indep_constraints): Remove constraints now defined by common.md. + (note_constraint): Map TARGET_MEM_CONSTRAINT to general_mem. + Remove special handling of 'm'. + * ira-costs.c (record_reg_classes): Remove special handling of + constraints now defined by common.md. + * ira.c (ira_setup_alts, ira_get_dup_out_num): Likewise. + * ira-lives.c (single_reg_class): Likewise. + (ira_implicitly_set_insn_hard_regs): Likewise. + * lra-constraints.c (reg_class_from_constraints): Likewise. + (process_alt_operands, process_address, curr_insn_transform): Likewise. + * postreload.c (reload_cse_simplify_operands): Likewise. + * reload.c (push_secondary_reload, scratch_reload_class) + (find_reloads, alternative_allows_const_pool_ref): Likewise. + * reload1.c (maybe_fix_stack_asms): Likewise. + * targhooks.c (default_secondary_reload): Likewise. + * stmt.c (parse_output_constraint): Likewise. + * recog.c (preprocess_constraints): Likewise. + (constrain_operands, peep2_find_free_register): Likewise. + (asm_operand_ok): Likewise, but add a comment saying why 'o' + must be handled specially. + +2014-06-11 Richard Sandiford <rdsandiford@googlemail.com> + + * system.h (CONST_DOUBLE_OK_FOR_CONSTRAINT_P): Poison. + * genpreds.c (have_const_dbl_constraints): Delete. + (add_constraint): Don't set it. + (write_tm_preds_h): Don't call CONST_DOUBLE_OK_FOR_CONSTRAINT_P. + * ira-costs.c (record_reg_classes): Handle CONST_INT and CONST_DOUBLE + constraints using the lookup_constraint logic. + * ira-lives.c (single_reg_class): Likewise. + * ira.c (ira_setup_alts): Likewise. + * lra-constraints.c (process_alt_operands): Likewise. + * recog.c (asm_operand_ok, constrain_operands): Likewise. + * reload.c (find_reloads): Likewise. + +2014-06-11 Richard Sandiford <rdsandiford@googlemail.com> + + * genpreds.c (const_int_start, const_int_end): New variables. + (choose_enum_order): Output CONST_INT constraints before memory + constraints. + (write_tm_preds_h): Always define insn_const_int_ok_for_constraint. + Add CT_CONST_INT. + * ira-costs.c (record_reg_classes): Handle CT_CONST_INT. + * ira.c (ira_setup_alts): Likewise. + * lra-constraints.c (process_alt_operands): Likewise. + * recog.c (asm_operand_ok, preprocess_constraints): Likewise. + * reload.c (find_reloads): Likewise. + +2014-06-11 Richard Sandiford <rdsandiford@googlemail.com> + + * recog.h (operand_alternative): Remove offmem_ok, nonffmem_ok, + decmem_ok and incmem_ok. Reformat other bitfields for consistency. + * recog.c (preprocess_constraints): Update accordingly. + +2014-06-11 Richard Sandiford <rdsandiford@googlemail.com> + + * system.h (REG_CLASS_FROM_CONSTRAINT): Poison. + (REG_CLASS_FOR_CONSTRAINT, EXTRA_CONSTRAINT_STR): Likewise. + (EXTRA_MEMORY_CONSTRAINT, EXTRA_ADDRESS_CONSTRAINT): Likewise. + * genpreds.c (print_type_tree): New function. + (write_tm_preds_h): Remove REG_CLASS_FROM_CONSTRAINT, + REG_CLASS_FOR_CONSTRAINT, EXTRA_MEMORY_CONSTRAINT, + EXTRA_ADDRESS_CONSTRAINT and EXTRA_CONSTRAINT_STR. + Write out enum constraint_type and get_constraint_type. + * lra-constraints.c (satisfies_memory_constraint_p): Take a + constraint_num rather than a constraint string. + (satisfies_address_constraint_p): Likewise. + (reg_class_from_constraints): Avoid old constraint macros. + (process_alt_operands, process_address_1): Likewise. + (curr_insn_transform): Likewise. + * ira-costs.c (record_reg_classes): Likewise. + (record_operand_costs): Likewise. + * ira-lives.c (single_reg_class): Likewise. + (ira_implicitly_set_insn_hard_regs): Likewise. + * ira.c (ira_setup_alts, ira_get_dup_out_num): Likewise. + * postreload.c (reload_cse_simplify_operands): Likewise. + * recog.c (asm_operand_ok, preprocess_constraints): Likewise. + (constrain_operands, peep2_find_free_register): Likewise. + * reload.c (push_secondary_reload, scratch_reload_class): Likewise. + (find_reloads, alternative_allows_const_pool_ref): Likewise. + * reload1.c (maybe_fix_stack_asms): Likewise. + * stmt.c (parse_output_constraint, parse_input_constraint): Likewise. + * targhooks.c (default_secondary_reload): Likewise. + * config/m32c/m32c.c (m32c_matches_constraint_p): Avoid reference + to EXTRA_CONSTRAINT_STR. + * config/sparc/constraints.md (U): Likewise REG_CLASS_FROM_CONSTRAINT. + +2014-06-11 Richard Sandiford <rdsandiford@googlemail.com> + + * genpreds.c (write_constraint_satisfied_p_1): Replace with... + (write_constraint_satisfied_p_array): ...this new function. + (write_tm_preds_h): Replace write_constraint_satisfied_p_1 with + an array. + (write_insn_preds_c): Update accordingly. + +2014-06-11 Richard Sandiford <rdsandiford@googlemail.com> + + * genpreds.c (write_lookup_constraint): Rename to... + (write_lookup_constraint_1): ...this. + (write_lookup_constraint_array): New function. + (write_tm_preds_h): Define lookup_constraint as an inline function + that uses write_lookup_constraint_array where possible. + (write_insn_preds_c): Update for the changes above. + +2014-06-11 Richard Sandiford <rdsandiford@googlemail.com> + + * doc/md.texi (regclass_for_constraint): Rename to... + (reg_class_for_constraint): ...this. + * genpreds.c (num_constraints, enum_order, register_start) + (register_end, satisfied_start, memory_start, memory_end) + (address_start, address_end): New variables. + (add_constraint): Count the number of constraints. + (choose_enum_order): New function. + (write_enum_constraint_num): Iterate over enum_order. + (write_regclass_for_constraint): Rename to... + (write_reg_class_for_constraint_1): ...this and update output + accordingly. + (write_constraint_satisfied_p): Rename to... + (write_constraint_satisfied_p_1): ...this and update output + accordingly. Do nothing if all extra constraints are register + constraints. + (write_insn_extra_memory_constraint): Delete. + (write_insn_extra_address_constraint): Delete. + (write_range_function): New function. + (write_tm_preds_h): Define constraint_satisfied_p and + reg_class_for_constraint as inline functions that do a range check + before calling the out-of-line function. Use write_range_function + to implement insn_extra_{register,memory,address}_constraint, + the first of which is new. + (write_insn_preds_c): Update after above changes to write_* functions. + (main): Call choose_enum_order. + +2014-06-11 Thomas Preud'homme <thomas.preudhomme@arm.com> + + PR tree-optimization/61306 + * tree-ssa-math-opts.c (struct symbolic_number): Store type of + expression instead of its size. + (do_shift_rotate): Adapt to change in struct symbolic_number. Return + false to prevent optimization when the result is unpredictable due to + arithmetic right shift of signed type with highest byte is set. + (verify_symbolic_number_p): Adapt to change in struct symbolic_number. + (init_symbolic_number): Likewise. + (find_bswap_or_nop_1): Likewise. Return NULL to prevent optimization + when the result is unpredictable due to sign extension. + +2014-06-11 Terry Guo <terry.guo@arm.com> + + * config/arm/arm.md (*thumb1_adddi3): Move into new file thumb1.md. + (*thumb1_addsi3): Ditto. + (*thumb_subdi3): Ditto. + (thumb1_subsi3_insn): Ditto. + (*thumb_mulsi3): Ditto. + (*thumb_mulsi3_v6): Ditto. + (*thumb1_andsi3_insn): Ditto. + (thumb1_bicsi3): Ditto. + (*thumb1_iorsi3_insn): Ditto. + (*thumb1_xorsi3_insn): Ditto. + (*thumb1_ashlsi3): Ditto. + (*thumb1_ashrsi3): Ditto. + (*thumb1_lshrsi3): Ditto. + (*thumb1_rotrsi3): Ditto. + (*thumb1_negdi2): Ditto. + (*thumb1_negsi2): Ditto. + (*thumb1_abssi2): Ditto. + (*thumb1_neg_abssi2): Ditto. + (*thumb1_one_cmplsi2): Ditto. + (*thumb1_zero_extendhisi2): Ditto. + (*thumb1_zero_extendqisi2): Ditto. + (*thumb1_zero_extendqisi2_v6): Ditto. + (thumb1_extendhisi2): Ditto. + (thumb1_extendqisi2): Ditto. + (*thumb1_movdi_insn): Ditto. + (*thumb1_movsi_insn): Ditto. + (*thumb1_movhi_insn): Ditto. + (thumb_movhi_clobber): Ditto. + (*thumb1_movqi_insn): Ditto. + (*thumb1_movhf): Ditto. + (*thumb1_movsf_insn): Ditto. + (*thumb_movdf_insn): Ditto. + (movmem12b): Ditto. + (movmem8b): Ditto. + (cbranchqi4): Ditto. + (cbranchsi4_insn): Ditto. + (cbranchsi4_scratch): Ditto. + (*negated_cbranchsi4): Ditto. + (*tbit_cbranch): Ditto. + (*tlobits_cbranch): Ditto. + (*tstsi3_cbranch): Ditto. + (*cbranchne_decr1): Ditto. + (*addsi3_cbranch): Ditto. + (*addsi3_cbranch_scratch): Ditto. + (*thumb_cmpdi_zero): Ditto. + (cstoresi_eq0_thumb1): Ditto. + (cstoresi_ne0_thumb1): Ditto. + (*cstoresi_eq0_thumb1_insn): Ditto. + (*cstoresi_ne0_thumb1_insn): Ditto. + (cstoresi_nltu_thumb1): Ditto. + (cstoresi_ltu_thumb1): Ditto. + (thumb1_addsi3_addgeu): Ditto. + (*thumb_jump): Ditto. + (*call_reg_thumb1_v5): Ditto. + (*call_reg_thumb1): Ditto. + (*call_value_reg_thumb1_v5): Ditto. + (*call_value_reg_thumb1): Ditto. + (*call_insn): Ditto. + (*call_value_insn): Ditto. + (thumb1_casesi_internal_pic): Ditto. + (thumb1_casesi_dispatch): Ditto. + (*thumb1_indirect_jump): Ditto. + (prologue_thumb1_interwork): Ditto. + (*epilogue_insns): Ditto. + (consttable_1): Ditto. + (consttable_2): Ditto. + (tablejump): Ditto. + (*thumb1_tablejump): Ditto. + (thumb_eh_return): Ditto. + (define_peephole2): Two of them are thumb1 only and got moved into + new file thumb1.md. + (define_split): Six of them are thumb1 only and got moved into new + file thumb1.md. + * config/arm/thumb1.md: New file comprised of above thumb1 only + patterns. + +2014-06-11 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * config.gcc (aarch64*-*-*): Add arm_acle.h to extra headers. + * Makefile.in (TEXI_GCC_FILES): Add aarch64-acle-intrinsics.texi to + dependencies. + * config/aarch64/aarch64-builtins.c (AARCH64_CRC32_BUILTINS): Define. + (aarch64_crc_builtin_datum): New struct. + (aarch64_crc_builtin_data): New. + (aarch64_init_crc32_builtins): New function. + (aarch64_init_builtins): Initialise CRC32 builtins when appropriate. + (aarch64_crc32_expand_builtin): New. + (aarch64_expand_builtin): Add CRC32 builtin expansion case. + * config/aarch64/aarch64.h (TARGET_CPU_CPP_BUILTINS): Define + __ARM_FEATURE_CRC32 when appropriate. + (TARGET_CRC32): Define. + * config/aarch64/aarch64.md (UNSPEC_CRC32B, UNSPEC_CRC32H, + UNSPEC_CRC32W, UNSPEC_CRC32X, UNSPEC_CRC32CB, UNSPEC_CRC32CH, + UNSPEC_CRC32CW, UNSPEC_CRC32CX): New unspec values. + (aarch64_<crc_variant>): New pattern. + * config/aarch64/arm_acle.h: New file. + * config/aarch64/iterators.md (CRC): New int iterator. + (crc_variant, crc_mode): New int attributes. + * doc/aarch64-acle-intrinsics.texi: New file. + * doc/extend.texi (aarch64): Document aarch64 ACLE intrinsics. + Include aarch64-acle-intrinsics.texi. + +2014-06-11 Evgeny Stupachenko <evstupac@gmail.com> + + * tree-vect-data-refs.c (vect_grouped_store_supported): New + check for stores group of length 3. + (vect_permute_store_chain): New permutations for stores group of + length 3. + * tree-vect-stmts.c (vect_model_store_cost): Change cost + of vec_perm_shuffle for the new permutations. + +2014-06-11 Jan Hubicka <hubicka@ucw.cz> + + * ipa-visibility.c (function_and_variable_visibility): Disable virtual + table rewriting temporarily on targets not supporting ONE_ONLY. + +2014-06-11 Richard Biener <rguenther@suse.de> + + PR middle-end/61437 + Revert + 2014-06-04 Richard Biener <rguenther@suse.de> + + * tree.h (may_be_aliased): Trust TREE_ADDRESSABLE from + TREE_PUBLIC and DECL_EXTERNAL decls. + +2014-06-10 Jan Hubicka <hubicka@ucw.cz> + + * varasm.c (set_implicit_section): New function. + (resolve_unique_section): Use it to set implicit section + for aliases, too. + (get_named_text_section): Use symtab_get_node (decl)->implicit_section + (default_function_section): Likewise. + (decl_binds_to_current_def_p): Constify argument. + * varasm.h (decl_binds_to_current_def_p): Update prototype. + * asan.c (asan_protect_global): Use + symtab_get_node (decl)->implicit_section. + * symtab.c (dump_symtab_base): Dump implicit sections. + (verify_symtab_base): Verify sanity of sectoins and comdats. + (symtab_resolve_alias): Alias share the section of its target. + (set_section_1): New function. + (symtab_node::set_section): Move here, recurse to aliases. + (verify_symtab): Check for duplicated symtab lists. + * tree-core.h (implicit_section_name_p): Remove. + * tree-vect-data-refs.c: Include varasm.h. + (vect_can_force_dr_alignment_p): Fix conditional on when + decl bints to current definition; use + symtab_get_node (decl)->implicit_section. + * cgraph.c (cgraph_make_node_local_1): Fix section set. + * cgraph.h (struct symtab_node): Add implicit_section. + (set_section): Rename to ... + (set_section_for_node): ... this one. + (set_section): Declare. + * tree.h (DECL_HAS_IMPLICIT_SECTION_NAME_P): Remove. + * lto-cgraph.c (lto_output_node, lto_output_varpool_node, + input_overwrite_node, input_varpool_node): Stream implicit_section. + * ipa.c (symtab_remove_unreachable_nodes): Do not check symtab before + removal; it will fail in LTO. + 2014-06-10 Kyrylo Tkachov <kyrylo.tkachov@arm.com> * config/aarch64/aarch64-simd.md (move_lo_quad_<mode>): @@ -88,8 +988,8 @@ 2014-06-10 Jan Hubicka <hubicka@ucw.cz> - * ipa-reference.c (is_proper_for_analysis): Exclude addressable and public - vars. + * ipa-reference.c (is_proper_for_analysis): Exclude addressable + and public vars. (intersect_static_var_sets): Remove. (propagate): Do not prune local statics. @@ -118,7 +1018,7 @@ PR middle-end/61141 * emit-rtl.c (reset_all_used_flags): In a sequence, check that XVECEXP (pat, 0, i) is an INSN before calling reset_insn_used_flags. - (verify_rtl_sharing): Likewise. + (verify_rtl_sharing): Likewise. 2014-06-09 Marc Glisse <marc.glisse@inria.fr> @@ -135,13 +1035,13 @@ PR target/61062 * config/arm/arm_neon.h (vtrn_s8, vtrn_s16, vtrn_u8, vtrn_u16, vtrn_p8, vtrn_p16, vtrn_s32, vtrn_f32, vtrn_u32, vtrnq_s8, vtrnq_s16, vtrnq_s32, - vtrnq_f32, vtrnq_u8, vtrnq_u16, vtrnq_u32, vtrnq_p8, vtrnq_p16, vzip_s8, - vzip_s16, vzip_u8, vzip_u16, vzip_p8, vzip_p16, vzip_s32, vzip_f32, - vzip_u32, vzipq_s8, vzipq_s16, vzipq_s32, vzipq_f32, vzipq_u8, - vzipq_u16, vzipq_u32, vzipq_p8, vzipq_p16, vuzp_s8, vuzp_s16, vuzp_s32, - vuzp_f32, vuzp_u8, vuzp_u16, vuzp_u32, vuzp_p8, vuzp_p16, vuzpq_s8, - vuzpq_s16, vuzpq_s32, vuzpq_f32, vuzpq_u8, vuzpq_u16, vuzpq_u32, - vuzpq_p8, vuzpq_p16): Correct mask for bigendian. + vtrnq_f32, vtrnq_u8, vtrnq_u16, vtrnq_u32, vtrnq_p8, vtrnq_p16, + vzip_s8, vzip_s16, vzip_u8, vzip_u16, vzip_p8, vzip_p16, vzip_s32, + vzip_f32, vzip_u32, vzipq_s8, vzipq_s16, vzipq_s32, vzipq_f32, + vzipq_u8, vzipq_u16, vzipq_u32, vzipq_p8, vzipq_p16, vuzp_s8, vuzp_s16, + vuzp_s32, vuzp_f32, vuzp_u8, vuzp_u16, vuzp_u32, vuzp_p8, vuzp_p16, + vuzpq_s8, vuzpq_s16, vuzpq_s32, vuzpq_f32, vuzpq_u8, vuzpq_u16, + vuzpq_u32, vuzpq_p8, vuzpq_p16): Correct mask for bigendian. 2014-06-09 Jan Hubicka <hubicka@ucw.cz> @@ -163,12 +1063,10 @@ * tree.c (decl_comdat_group, decl_comdat_group_id): Constify argument. (decl_section_name, set_decl_section_name): New accessors. (find_decls_types_r): Do not walk section name - * tree.h (DECL_SECTION_NAME): Implement using - decl_section_name. + * tree.h (DECL_SECTION_NAME): Implement using decl_section_name. (decl_comdat_group, decl_comdat_group_id): Constify. (decl_section_name, set_decl_section_name): Update. - * varpool.c (varpool_finalize_named_section_flags): Use - get_section. + * varpool.c (varpool_finalize_named_section_flags): Use get_section. * cgraph.c (cgraph_add_thunk): Reset node instead of rebuilding. (cgraph_make_node_local_1): Clear section and comdat group. * cgraph.h (set_comdat_group): Sanity check. @@ -176,8 +1074,7 @@ * ipa-comdats.c (ipa_comdats): Use get_section. * ipa.c (ipa_discover_readonly_nonaddressable_var): Likewise. * lto-streamer-out.c: Do not follow section names. - * c-family/c-common.c (handle_section_attribute): - Update. + * c-family/c-common.c (handle_section_attribute): Update. * lto-cgraph.c (lto_output_node): Output section. (lto_output_varpool_node): Likewise. (read_comdat_group): Rename to ... @@ -186,8 +1083,7 @@ (input_node, input_varpool_node): Input section names. * tree-emutls.c (get_emutls_init_templ_addr): Update. (new_emutls_decl): Update. - (secname_for_decl): Check section names only of static - vars. + (secname_for_decl): Check section names only of static vars. * config/mep/mep.c (mep_unique_section): Use set_decl_section_name. * config/i386/winnt.c (i386_pe_unique_section): Likewise. * config/i386/i386.c (x86_64_elf_unique_section): Likewise. @@ -196,7 +1092,7 @@ * config/mcore/mcore.c (mcore_unique_section): Likewise. * config/mips/mips.c (mips16_build_function_stub): Likewise. * config/v850/v850.c (v850_insert_attributes): Likewise. - * config/h8300/h8300.c: (h8300_handle_eightbit_data_attribute): + * config/h8300/h8300.c (h8300_handle_eightbit_data_attribute): Likewise. (h8300_handle_tiny_data_attribute): Likewise. * config/bfin/bfin.c (bfin_handle_l1_text_attribute): Likewise. @@ -209,8 +1105,8 @@ 2014-06-07 Jan Hubicka <hubicka@ucw.cz> - * varasm.c (use_blocks_for_decl_p): Check symbol table instead of alias - attribute. + * varasm.c (use_blocks_for_decl_p): Check symbol table + instead of alias attribute. (place_block_symbol): Recurse on aliases. 2014-06-07 Jan Hubicka <hubicka@ucw.cz> @@ -225,7 +1121,7 @@ 2014-06-07 Steven Bosscher <steven@gcc.gnu.org> - * gcse.c (can_assign_to_reg_without_clobbers_p): Do not let pointers + * gcse.c (can_assign_to_reg_without_clobbers_p): Do not let pointers from test_insn into GGC space escape via SET_SRC. 2014-06-07 Eric Botcazou <ebotcazou@adacore.com> @@ -661,7 +1557,7 @@ 2014-06-04 Matthew Fortune <matthew.fortune@imgtec.com> - * regcprop.c (copyprop_hardreg_forward_1): Account for + * regcprop.c (copyprop_hardreg_forward_1): Account for HARD_REGNO_CALL_PART_CLOBBERED. 2014-06-04 Richard Biener <rguenther@suse.de> @@ -8987,10 +9883,10 @@ PR tree-optimization/60577 * tree-core.h (struct tree_base): Document nothrow_flag use - in VAR_DECL_NONALIASED. - * tree.h (VAR_DECL_NONALIASED): New. + in DECL_NONALIASED. + * tree.h (DECL_NONALIASED): New. (may_be_aliased): Adjust. - * coverage.c (build_var): Set VAR_DECL_NONALIASED. + * coverage.c (build_var): Set DECL_NONALIASED. 2014-03-20 Eric Botcazou <ebotcazou@adacore.com> diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 05a7007ea83..7a41a512c65 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20140610 +20140617 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 335018606e5..5587b75d62a 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -491,7 +491,7 @@ out_file=$(srcdir)/config/@out_file@ out_object_file=@out_object_file@ common_out_file=$(srcdir)/common/config/@common_out_file@ common_out_object_file=@common_out_object_file@ -md_file=$(srcdir)/config/@md_file@ +md_file=$(srcdir)/common.md $(srcdir)/config/@md_file@ tm_file_list=@tm_file_list@ tm_include_list=@tm_include_list@ tm_defines=@tm_defines@ @@ -2801,7 +2801,7 @@ TEXI_GCC_FILES = gcc.texi gcc-common.texi gcc-vers.texi frontends.texi \ contribute.texi compat.texi funding.texi gnu.texi gpl_v3.texi \ fdl.texi contrib.texi cppenv.texi cppopts.texi avr-mmcu.texi \ implement-c.texi implement-cxx.texi arm-neon-intrinsics.texi \ - arm-acle-intrinsics.texi + arm-acle-intrinsics.texi aarch64-acle-intrinsics.texi # we explicitly use $(srcdir)/doc/tm.texi here to avoid confusion with # the generated tm.texi; the latter might have a more recent timestamp, diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 7cbfba0a915..ce762077091 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,724 @@ +2014-06-15 Jan Hubicka <hubicka@ucw.cz> + + * gcc-interface/utils.c (process_attributes): Use set_decl_tls_model. + +2014-06-14 Bernd Edlinger <bernd.edlinger@hotmail.de> + + PR ada/61505 + * gnat_rm.texi: Fix errors with makeinfo 5.1. + +2014-06-14 Arnaud Charlet <charlet@adacore.com> + + PR ada/61505 + * gnat_rm.texi: Attempt to fix error with makeinfo 5.1. + +2014-06-13 Yannick Moy <moy@adacore.com> + + * exp_attr.adb: Fix typo in comment. + * gnat1drv.adb (Adjust_Global_Switches): Force float overflow + checking in GNATprove_Mode. + +2014-06-13 Ed Schonberg <schonberg@adacore.com> + + * a-coinho-shared.adb, a-coinho-shared.ads: Update shared version. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * sem_ch3.adb, sem_ch9.adb, a-coinho.adb, a-coinho.ads: Minor + reformatting. + +2014-06-13 Hristian Kirtchev <kirtchev@adacore.com> + + * sem_prag.adb (Analyze_Pragma): Add local + variable Missing_Parentheses. Emit an error when a state + declaration with options appears without parentheses. Add a + guard to prevent a bogus error when a state declaration may be + interpreted as an option if a previous declaration with options + was not parenthesized. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * checks.adb: Validate_Alignment_Check_Warnings: New procedure + (Apply_Address_Clause_Check): Make Aligment_Warnings table entry. + * checks.ads (Alignment_Warnings_Record): New type. + (Alignment_Warnings): New table + (Validate_Alignment_Check_Warnings): New procedure. + * errout.adb (Delete_Warning_And_Continuations): New procedure + (Error_Msg_Internal): Set Warning_Msg (Delete_Warning): Handle + Warnings_Treated_As_Errors (Finalize): Minor reformatting + * errout.ads (Warning_Msg): New variable + (Delete_Warning_And_Continuations): New procedure + * erroutc.adb (Delete_Msg): Handle Warnings_Treated_As_Errors count. + * gnat1drv.adb (Post_Compilation_Validation_Checks): New procedure. + +2014-06-13 Ed Schonberg <schonberg@adacore.com> + + * a-coinho.adb, a-coinho.ads: Add Reference machinery. + +2014-06-13 Hristian Kirtchev <kirtchev@adacore.com> + + * errout.adb (SPARK_Msg_N): New routine. + (SPARK_Msg_NE): New routine. + * errout.ads Add a section on SPARK-related error routines. + (SPARK_Msg_N): New routine. + (SPARK_Msg_NE): New routine. + * sem_ch13.adb (Analyze_Aspect_Specifications): Ensure that + pragma Abstract_State is always inserted after SPARK_Mode. + (Insert_After_SPARK_Mode): New routine. + * sem_prag.adb (Analyze_Abstract_State, + Analyze_Constituent, Analyze_External_Property, + Analyze_External_Property_In_Decl_Part, Analyze_Global_Item, + Analyze_Global_List, Analyze_Initialization_Item, + Analyze_Initialization_Item_With_Inputs, Analyze_Input_Item, + Analyze_Input_List, Analyze_Input_Output, Analyze_Part_Of, + Analyze_Pragma, Analyze_Refined_Depends_In_Decl_Part, + Analyze_Refined_Global_In_Decl_Part, + Analyze_Refined_State_In_Decl_Part, Analyze_Refinement_Clause, + Check_Aspect_Specification_Order, Check_Constituent_Usage, + Check_Declaration_Order, Check_Dependency_Clause, + Check_Duplicate_Mode, Check_Duplicate_Option, + Check_Duplicate_Property, Check_External_Properties, + Check_External_Property, Check_Function_Return, + Check_Matching_Constituent, Check_Matching_State, + Check_Mode_Restriction_In_Enclosing_Context, + Check_Mode_Restriction_In_Function, Check_Refined_Global_Item, + Check_State_And_Constituent_Use, Create_Or_Modify_Clause, + Has_Extra_Parentheses, Inconsistent_Mode_Error, + Match_Error, Propagate_Part_Of, Report_Extra_Clauses, + Report_Extra_Constituents_In_List, Report_Extra_Inputs, + Report_Unrefined_States, Report_Unused_Constituents, + Report_Unused_States, Role_Error, Usage_Error): + Convert Error_Msg_XXX calls to SPARK_Msg_XXX calls + to report semantic errors only when SPARK_Mode is on. + (Analyze_Depends_In_Decl_Part): Do not check the syntax of + pragma Depends explicitly, this is now done by the analysis. + (Analyze_Global_In_Decl_List): Do not check the syntax of + pragma Global explicitly, this is now done by the analysis. + (Analyze_Initializes_In_Decl_Part): Do not check the syntax of + pragma Initializes explicitly, this is now done by the analysis. + (Analyze_Part_Of): Do not check the syntax of the encapsulating + state, this is now done by the analysis. + (Analyze_Pragma): Do + not check the syntax of a state declaration, this is now done + by the analysis. + (Analyze_Refined_Depends_In_Decl_Part): Do not + check the syntax of pragma Refined_Depends explicitly, this is now + done by the analysis. + (Analyze_Refined_Global_In_Decl_Part): Do + not check the syntax of pragma Refined_Global explicitly, this is + now done by the analysis. + (Analyze_Refined_State_In_Decl_Part): + Do not check the syntax of pragma Refined_State explicitly, this + is now done by the analysis. + (Check_Dependence_List_Syntax): Removed. + (Check_Global_List_Syntax): Removed. + (Check_Initialization_List_Syntax): Removed. + (Check_Item_Syntax): Removed. + (Check_Missing_Part_Of): Do not consider items from an instance. + (Check_Refinement_List_Syntax): Removed. + (Check_State_Declaration_Syntax): Removed. + (Collect_Global_List): Do not raise Program_Error when the input is + malformed. + (Process_Global_List): Do not raise Program_Error when the input + is malformed. + * sem_ch13.adb: Minor reformatting. + +2014-06-13 Ed Schonberg <schonberg@adacore.com> + + * sem_ch3.adb (Find_Type_Name): Diagnose a private type completion + that is an interface definition with an interface list. + (Process_Full_View): Move error message on missmatched interfaces + between views to the declaration of full view, for clarity. + * sem_ch9.adb (Check_Interfaces): Move error message to full view, + for clarity. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * exp_attr.adb (Expand_N_Attribute_Reference, case Pred/Succ): Change + reason to Overflow. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * makeutl.adb: Minor reformatting. + +2014-06-13 Gail Schenker <schenker@adacore.com> + + * debug.adb, sem_eval.adb (Why_Not_Static): Remove temporary code and + associated flag (d.z), no longer needed. + +2014-06-13 Ed Schonberg <schonberg@adacore.com> + + * sem_ch13.adb (Analyze_Aspect_Specifications): For Import and + Export aspects, do not check whether a corresponding Convention + aspect has been specified. Convention is optional in Ada2012, + and defaults to Convention_Ada. + +2014-06-13 Eric Botcazou <ebotcazou@adacore.com> + + * checks.adb (Apply_Address_Clause_Check): Only issue the new + warning if the propagation warning is issued. + +2014-06-13 Thomas Quinot <quinot@adacore.com> + + * exp_ch4.adb: Minor reformatting. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * exp_attr.adb (Expand_N_Attribute_Reference, case Pred): + Handle float range check case (Expand_N_Attribute_Reference, + case Succ): Handle float range check case. + * sem_attr.adb (Analyze_Attribute, case Pred/Succ): Handle float + range check case. + +2014-06-13 Vincent Celier <celier@adacore.com> + + * makeutl.ads (Compute_Builder_Switches): Change name of + parameter Root_Environment to Env. + * prj-conf.adb (Check_Switches): Call Locate_Runtime with the + Env parameter of procedure Get_Or_Create_Configuration_File. + (Locate_Runtime): Call Find_Rts_In_Path with the Project_Path + of new parameter Env. + * prj-conf.ads (Locate_Runtime): New parameter Env of type + Prj.Tree.Environment. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * gnat_rm.texi: Minor comment clarification for Check_Float_Overflow. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * exp_attr.adb, exp_ch9.adb, lib-writ.adb, g-comlin.adb: Minor + reformatting. + * sem_attr.adb: Minor code reformatting and simplification. + * checks.adb: Fix minor typo. + +2014-06-13 Emmanuel Briot <briot@adacore.com> + + * g-comlin.adb (Get_Argument): fix expansion + of command line arguments (e.g. "*.adb") when using a custom + parser. The parser was not passed to the recursive call, and + thus we were trying to do the expansion on the default command + line parser. + +2014-06-13 Thomas Quinot <quinot@adacore.com> + + * exp_ch9.adb: Minor reformatting. + +2014-06-13 Ed Schonberg <schonberg@adacore.com> + + * exp_attr.adb (Expand_N_Attribute_Reference, case 'Old): + To determine whether the attribute should be expanded, examine + whether the enclosing postcondition pragma is to be checked, + rather than using the internal flag Assertions_Enabled. + +2014-06-13 Ben Brosgol <brosgol@adacore.com> + + * gnat_rm.texi: Minor fixes. + * gnat_ugn.texi: Added a missing "@itemize". + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * debug.adb: Remove -gnatd.1 flag documentation. + * layout.adb (Layout_Type): Remove special handling of size + for anonymous access type. + * sem_ch3.adb (Replace_Type): Remove special handling of size + for anonymous access type. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * debug.adb: Document debug flag -gnatd.1. + * layout.adb (Layout_Type): Size change for anonymous access + types under -gnatd.1. + * sem_ch3.adb (Replace_Type): Size change for anonymous access + types under -gnatd.1. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * layout.adb (Layout_Type): Anonymous access types designating + unconstrained arrays are always thin pointers. + * sem_ch3.adb (Replace_Type): Anonymous access types designating + unconstrained arrays are always thin pointers. + +2014-06-13 Ed Schonberg <schonberg@adacore.com> + + * sem_attr.adb (Analyze_Attribute): Use Check_Parameterless_Call + to resolve the prefix of an attribute that is an entity name + and may be a parameterless call. Minor code reorganization. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * lib.ads, lib.adb, lib-writ.adb, lib-load.adb (Is_Compiler_Unit): + Removed. + * opt.ads (Compiler_Unit): New flag. + * par-ch5.adb (Test_Statement_Required): Call Check_Compiler_Unit + for null statement sequence (not allowed in compiler unit). + * par-prag.adb (Prag): Handle Compiler_Unit[_Warning] during + parsing. + * restrict.ads, restrict.adb (Check_Compiler_Unit): New version and new + calling sequence. + * sem_ch11.adb, sem_ch3.adb, sem_ch4.adb: New calling sequence for + Check_Compiler_Unit. + * sem_ch6.adb (Analyze_Extended_Return_Statement): Call + Check_Compiler_Unit (this construct is not allowed in compiler + units). + * sem_prag.adb (Analyze_Pragma, case Compiler_Unit[_Warning]): + Set Opt.Compiler_Unit. + +2014-06-13 Geert Bosch <bosch@adacore.com> + + * gnat_rm.texi, s-tasinf-solaris.ads, sem_prag.adb, gnat_ugn.texi, + s-tasinf-mingw.ads, s-tasinf.ads, s-tasinf-linux.ads, + s-tasinf-vxworks.ads: Make Task_Info pragma and package obsolescent. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * s-tasini.adb, s-tarest.adb, s-taprob.adb: Minor reformatting. + +2014-06-13 Hristian Kirtchev <kirtchev@adacore.com> + + * freeze.adb (Freeze_Entity): Remove the check concerning volatile + types in SPARK as it is poorly placed and poorly formulated. The + check was flagging ALL volatile entities as illegal in SPARK. + * sem_prag.adb (Process_Atomic_Shared_Volatile): Flag volatile + types as illegal in SPARK. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * sem_cat.adb: Minor reformatting. + +2014-06-13 Yannick Moy <moy@adacore.com> + + * sem_prag.adb (Analyze_Pragma/Post_Class): Fix typo. + +2014-06-13 Arnaud Charlet <charlet@adacore.com> + + * gnat_rm.texi: Add detail on SPARK_05 restriction. + +2014-06-13 Bob Duff <duff@adacore.com> + + * s-solita.adb (Get_Sec_Stack_Addr, Init_Tasking_Soft_Links): + Add assertions requiring the secondary stack to be initialized. + * s-solita.ads (Init_Tasking_Soft_Links): Comment. + * s-taprob.adb, s-tarest.adb, s-tasini.adb (elab code): Make sure the + secondary stack is initialized before calling Init_Tasking_Soft_Links, + by adding pragmas Elaborate_Body. + +2014-06-13 Thomas Quinot <quinot@adacore.com> + + * sem_ch13.adb (Analyze_Stream_TSS_Definition): Remove temporary + kludge disabling new legality check. + +2014-06-13 Hristian Kirtchev <kirtchev@adacore.com> + + * freeze.adb (Freeze_Record_Type): Remove checks related to SPARK + volatile types. + (Freeze_Type): Volatile types are now illegal in SPARK. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * aspects.ads, aspects.adb: Add aspect Thread_Local_Storage. + * gnat_rm.texi: Document aspect Thread_Local_Storage. + +2014-06-13 Ed Schonberg <schonberg@adacore.com> + + * sem_cat.adb (Validate_Static_Object_Name): A constant whose + value is a temporary that renames an aggregate is legal in a + preelaborated unit. Illegalities, if any will be detected in + the aggregate components. + +2014-06-13 Ed Schonberg <schonberg@adacore.com> + + * einfo.ads: Minor reformatting an comment expansion. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * back_end.ads, back_end.adb: Make_Id, Make_SC, Set_RND are moved to + Tbuild. + * tbuild.ads, tbuild.adb: Make_Id, Make_SC, Set_RND are moved here from + Back_End. + * gnat1drv.adb: Make_Id, Make_SC, Set_RND are moved to Tbuild + * sem_warn.adb: Minor reformatting. + +2014-06-13 Doug Rupp <rupp@adacore.com> + + * adaint.c (__gnat_open_new_temp) [VMS]: Open binary + files with rfm=udf. + +2014-06-13 Yannick Moy <moy@adacore.com> + + * sem_warn.adb (Check_Unset_References): Take + case of Refined_Post into account in Within_Postcondition check. + +2014-06-13 Hristian Kirtchev <kirtchev@adacore.com> + + * freeze.adb (Freeze_Record_Type): Volatile types are not allowed in + SPARK. + +2014-06-13 Yannick Moy <moy@adacore.com> + + * sem_ch13.adb (Analyze_Aspect_Specifications/Aspect_Import, + Aspect_Export): Consider that variables may be set outside the program. + +2014-06-13 Robert Dewar <dewar@adacore.com> + + * back_end.adb (Make_Id): New function. + (Make_SC): New function. + (Set_RND): New procedure. + * back_end.ads (Make_Id): New function. + (Make_SC): New function. + (Set_RND): New procedure. + * einfo.ads: Minor comment updates. + * frontend.adb: Move Atree.Initialize call to Gnat1drv. + * gnat1drv.adb (Gnat1drv): New calling sequence for + Get_Target_Parameters. + (Gnat1drv): Move Atree.Initialize here from Frontend. + * targparm.adb (Get_Target_Parameters): New calling + sequence (Get_Target_Parameters): Handle pragma Restriction + (No_Dependence,..) + * targparm.ads (Get_Target_Parameters): New calling sequence. + +2014-06-13 Gary Dismukes <dismukes@adacore.com> + + * sem_prag.adb (Process_Import_Or_Interface): Exit the homonym + loop if the pragma does not come from source, so that an implicit + pragma Import only applies to the first declaration, avoiding + possible conflicts with earlier explicit and implicit declarations + due to multiple Provide_Shift_Operators pragmas. + (Set_Imported): Remove previous fix that bypassed pragma duplication + error. + * gnat_rm.texi: Change 'equivalent' to 'similar' in description + of Provide_Shift_Operators. + +2014-06-12 Jan Hubicka <hubicka@ucw.cz> + + * gcc-interface/utils.c (process_attributes) <ATTR_LINK_SECTION>: Pass + string pointer directly to set_decl_section_name. + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * sem_ch13.adb: Minor reformatting. + +2014-06-11 Hristian Kirtchev <kirtchev@adacore.com> + + * sem_prag.adb (Check_Clause_Syntax): Add new + local variable Outputs. Account for the case where multiple + output items appear as an aggregate. + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * sem_warn.adb (Output_Obsolescent_Entity_Warnings): Tag warning + with ?j? not ??. + +2014-06-11 Ed Schonberg <schonberg@adacore.com> + + * einfo.ads: Minor reformatting. + +2014-06-11 Hristian Kirtchev <kirtchev@adacore.com> + + * a-cbdlli.adb, a-cdlili.adb, a-cidlli.adb, a-crdlli.adb (Insert): Add + new variable First_Node. Update the position after all insertions have + taken place to First_Node. + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * debug.adb: Remove debug flag -gnatd.1, no longer needed. + * layout.adb (Layout_Type): Remove test of -gnatd.1. + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * sem_ch13.adb: Minor reformatting. + +2014-06-11 Hristian Kirtchev <kirtchev@adacore.com> + + * sem_prag.adb (Check_Clause_Syntax): Add new + local variable Outputs. Account for the case where multiple + output items appear as an aggregate. + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * sem_warn.adb (Output_Obsolescent_Entity_Warnings): Tag warning + with ?j? not ??. + +2014-06-11 Ed Schonberg <schonberg@adacore.com> + + * einfo.ads: Minor reformatting. + +2014-06-11 Hristian Kirtchev <kirtchev@adacore.com> + + * a-cbdlli.adb, a-cdlili.adb, a-cidlli.adb, a-crdlli.adb (Insert): Add + new variable First_Node. Update the position after all insertions have + taken place to First_Node. + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * debug.adb: Remove debug flag -gnatd.1, no longer needed. + * layout.adb (Layout_Type): Remove test of -gnatd.1. + +2014-06-11 Thomas Quinot <quinot@adacore.com> + + * freeze.ads: Minor reformatting. + * checks.adb (Determine_Range): Do not attempt to determine + the range of a deferred constant whose full view has not been + seen yet. + * sem_res.adb (Resolve): Remove undesirable guard against + resolving expressions from expression functions. + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * debug.adb (Debug_Flag_Dot_1): Set to enable fix for anonymous + access types. + * layout.adb (Layout_Type): Make anonymous access types for + subprogram formal types and return types always thin. For now + only enabled if -gnatd.1 set. + +2014-06-11 Ed Schonberg <schonberg@adacore.com> + + * sem_ch13.adb (Analyze_Stream_TSS_Definition): Apply legality + rule for stream attributes of interface types (RM 13.13.2 (38/3)): + subprogram must be a null procedure. + +2014-06-11 Hristian Kirtchev <kirtchev@adacore.com> + + * sem_prag.adb (Analyze_Input_Item): Allow formal + parameters to appear as input_items in an initialization_list + of pragma Initializes. Encapsulation now applies to states and + variables only (as it should). Add RM references to key errors. + * sem_prag.adb (Set_Imported): Suppress errors + about preceding Imports when the pragma does not come from source, + which can happen through use of pragma Provide_Shift_Operators. + +2014-06-11 Thomas Quinot <quinot@adacore.com> + + * sem_ch3.adb: Minor reformatting. + * einfo.ads (Full_View): Minor comment update. + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * einfo.adb (Is_Independent): New flag. + * einfo.ads (Is_Independent): New flag. + (Has_Independent_Components): Clean up and fix comments. + * sem_prag.adb (Fix_Error): Deal with changing argument + [of] to entity [for]. + (Analyze_Pragma, case Independent): Set Is_Independent flag + (Analyze_Pragma, case Independent_Components): Set Is_Independent flag + in all components of specified record. + +2014-06-11 Thomas Quinot <quinot@adacore.com> + + * sem_ch12.adb (Analyze_Formal_Decimal_Fixed_Point_Type): + Set proper Etype on bounds of dummy type created for analysis + of the generic. + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * debug.adb: Minor comment fix (add missing section of dot + numeric flags). + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * gnat_rm.texi, switch-c.adb, sem_prag.adb, a-tgdico.ads, par-prag.adb, + opt.ads, a-finali.ads, snames.ads-tmpl: Remove all traces of + pragma/aspects Pure_05 Pure_12 Preelaborate_05. + * errout.adb (Output_Messages): Avoid duplicate output for + library level instance. + * sem_elab.adb (Is_Call_Of_Generic_Formal): Moved to outer level + (Check_Elab_Call): Add call to Is_Call_Of_Generic_Formal + * exp_ch4.adb (Expand_N_Op_Expon): New interface for Exp_Modular. + * s-expmod.ads, s-expmod.adb (Exp_Modular): Change interface to + accomodate largest modulus value. + * gnat_ugn.texi: Minor updates. + +2014-06-11 Ed Schonberg <schonberg@adacore.com> + + * sem_ch12.adb (Instantiate_Package_Body): Do not attempt to + load body of generic package or its parent, if body is optional + and the unit does not require a body. + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * gnat_rm.texi: Document System.Unsigned_Types. + * impunit.adb: System.Unsigned_Types (s-unstyp.ads) is user accessible. + * s-unstyp.ads: Update comments (this is now user available unit). + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * make.adb, sem_res.adb: Minor reformatting. + +2014-06-11 Thomas Quinot <quinot@adacore.com> + + * a-astaco.ads, a-tags.ads, s-excdeb.ads, a-tgdico.ads, a-stmaco.ads, + a-except-2005.ads, s-except.ads, a-taside.ads, a-dynpri.ads, + a-chahan.ads, a-sytaco.ads, s-stalib.ads, a-strmap.ads: Change pragmas + Preelaborate_05 to just Preelaborate in runtime units, and similarly + change Pure_05 to just Pure. + +2014-06-11 Ed Schonberg <schonberg@adacore.com> + + * sem_ch6.adb (Analyze_Subprogram_Body_Contract): Do not attempt + analysis if error has been posted on subprogram body. + +2014-06-11 Ed Schonberg <schonberg@adacore.com> + + * sem_ch13.adb (Analyze_Stream_TSS_Definition): Apply legality + rule given in RM 13.1 (8/1) for operational attributes to stream + attributes: the attribute must apply to a first subtype. Fixes + missing errors in ACATS test bdd2004. + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * exp_ch3.adb (Build_Record_Init_Proc): Don't build for variant + record type if restriction No_Implicit_Conditionals is active. + (Expand_N_Object_Declaration): Don't allow default initialization + for variant record type if restriction No_Implicit_Condition is active. + (Build_Variant_Record_Equality): Don't build for variant + record type if restriction No_Implicit_Conditionals is active. + * exp_ch4.adb (Expand_N_Op_Eq): Error if variant records with + No_Implicit_Conditionals. + * sem_aux.ads, sem_aux.adb (Has_Variant_Part): New function. + +2014-06-11 Ramon Fernandez <fernandez@adacore.com> + + * i-cstrin.ads: Update comments. + +2014-06-11 Ed Schonberg <schonberg@adacore.com> + + * sem_res.adb (Resolve_Selected_Component): Handle properly a + selected component whose prefix is overloaded, when none of the + interpretations matches the expected type. + +2014-06-11 Bob Duff <duff@adacore.com> + + * make.adb (Wait_For_Available_Slot): Give a more + informative error message; if the ALI file is not found, print + the full path of what it's looking for. + +2014-06-11 Sergey Rybin <rybin@adacore.com frybin> + + * gnat_ugn.texi, vms_data.ads: add description of gnatstub -W<par> + option to specify the result file encoding. + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * errout.ads, sem_ch12.adb: Minor reformatting. + * debug.adb, erroutc.adb: Remove -gnatd.q debug switch. + * lib-xref.adb: Minor reformatting. + * restrict.adb: Minor code reorganization (put routines in + alpha order). + +2014-06-11 Yannick Moy <moy@adacore.com> + + * einfo.ads: Minor typo in comment + +2014-06-11 Ed Schonberg <schonberg@adacore.com> + + * sinfo.ads, sinfo.adb: New attribute Uninitialized_Variable, for + formal private types and private type extensions, to indicate + variable in a generic unit whose uninitialized use suggest that + actual type should be fully initialized. + Needs_Initialized_Actual: removed, functionaity replaced by + the above. + * lib-xref.adb (Generate_Reference): Generate a reference for + variables of a formal type when the unit is not the main unit, + to enable appropriate warnings in an instance. + * sem_ch12.adb (Check_Ininialized_Type): Improve warning on use + of variable in a generic unit that suggests that actual type + should be full initialized. + * sem_warn.adb; (May_Need_Initialized_Actual): Make into procedure + and do not emot warning, which now only appears in an instance. + +2014-06-11 Eric Botcazou <ebotcazou@adacore.com> + + * gnat_ugn.texi: Fix minor typo. + +2014-06-11 Hristian Kirtchev <kirtchev@adacore.com> + + * sem_ch3.adb Add with and use clause for Sem_Ch10. + (Analyze_Declarations): Code reformatting. Analyze the contract + of a subprogram body stub at the end of the declarative region. + * sem_ch6.adb (Analyze_Subprogram_Body_Contract): Spec_Id is + now a variable. Do not process the body if its contract is not + available. Account for subprogram body stubs when extracting + the corresponding spec. + * sem_ch6.ads (Analyze_Subprogram_Contract): Update the comment + on usage. + * sem_ch10.ads, sem_ch10.adb (Analyze_Subprogram_Body_Stub_Contract): + New routine. + * sem_prag.adb (Analyze_Depends_In_Decl_Part): + Account for subprogram body stubs when extracting the + corresponding spec. + (Analyze_Global_In_Decl_List): + Account for subprogram body stubs when extracting the + corresponding spec. + (Analyze_Refined_Depends_In_Decl_Part): + Use Find_Related_Subprogram_Or_Body to retrieve the declaration + of the related body. Spec_Is now a variable. Account for + subprogram body stubs when extracting the corresponding spec. + (Analyze_Refined_Global_In_Decl_Part): Use + Find_Related_Subprogram_Or_Body to retrieve the declaration + of the related body. Spec_Is now a variable. Account for + subprogram body stubs when extracting the corresponding spec. + (Collect_Subprogram_Inputs_Output): Account for subprogram body + stubs when extracting the corresponding spec. + +2014-06-11 Vincent Celier <celier@adacore.com> + + * gnatcmd.adb (Process_Link): Do not invoke gnatlink with + -lgnarl or -lgnat. + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * debug.adb: Add debug flag -gnatd.q. + * erroutc.adb (Prescan_Message): Bomb if untagged warning with + -gnatd.q set. + * styleg.adb (Check_Xtra_Parens): Message should be a style + message. + * sem_aggr.adb, sem_ch3.adb, exp_ch9.adb, checks.adb, sem_prag.adb, + par-endh.adb, eval_fat.adb, freeze.adb, sem_util.adb, sem_attr.adb, + sem_elab.adb, sem_ch6.adb, sem_warn.adb, sem_cat.adb, + sem_ch13.adb, lib-xref.adb: Add remaining warning tags. + +2014-06-11 Ben Brosgol <brosgol@adacore.com> + + * gnat_rm.texi: Revised chapter on Implementation Defined + Characteristics. + +2014-06-11 Geert Bosch <bosch@adacore.com> + + * s-exctab.adb: avoid race conditions in exception registration. + +2014-06-11 Robert Dewar <dewar@adacore.com> + + * errout.adb (Warn_Insertion): New function. + (Error_Msg): Use Warn_Insertion and Prescan_Message. + (Error_Msg_Internal): Set Info field of error object. + (Error_Msg_NEL): Use Prescan_Message. + (Set_Msg_Text): Don't store info: at start of message. + (Skip_Msg_Insertion_Warning): New name for Set_Msg_Insertion_Warning. + (Skip_Msg_Insertion_Warning): Now just skips warning insertion. + * errout.ads: Document new ?$? and >$> insertion sequences + Document use of "(style)" and "info: " + * erroutc.adb (dmsg): Print several missing fields + (Get_Warning_Tag): Handle -gnatel case (?$?) (Output_Msg_Text): + Deal with new tagging of info messages + * erroutc.ads: Is_Info_Msg: New global (Error_Msg_Object): + Add field Info (Prescan_Message): New procedure, this procedure + replaces the old Test_Style_Warning_Serious_Unconditional_Msg + * errutil.adb, exp_util.adb, par-ch7.adb, sem_ch13.adb, sem_ch7.adb, + sem_elab.adb: Follow new rules for info message (info belongs + only at the start of a message, and only in the first message, + not in any of the continuations). + * gnat_ugn.texi: Document full set of warning tags. + +2014-06-11 Gary Dismukes <dismukes@adacore.com> + + * sem_util.adb: Minor typo fix. + +2014-06-11 Ed Schonberg <schonberg@adacore.com> + + * sem_warn.adb (Check_References): Do not emit spurious warnings + on uninitialzed variable of a formal private type if variable + is not read. + 2014-06-09 Jan Hubicka <hubicka@ucw.cz> * gcc-interface/utils.c (process_attributes) <ATTR_LINK_SECTION>: Use diff --git a/gcc/ada/a-astaco.ads b/gcc/ada/a-astaco.ads index 3200c7ecdaf..1fa7c25697d 100644 --- a/gcc/ada/a-astaco.ads +++ b/gcc/ada/a-astaco.ads @@ -27,7 +27,7 @@ with Ada.Task_Identification; package Ada.Asynchronous_Task_Control is - pragma Preelaborate_05; + pragma Preelaborate; -- In accordance with Ada 2005 AI-362 pragma Unimplemented_Unit; diff --git a/gcc/ada/a-cbdlli.adb b/gcc/ada/a-cbdlli.adb index d36239abc9c..d0b6c12d578 100644 --- a/gcc/ada/a-cbdlli.adb +++ b/gcc/ada/a-cbdlli.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2004-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2004-2014, 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- -- @@ -1067,7 +1067,8 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is Position : out Cursor; Count : Count_Type := 1) is - New_Node : Count_Type; + First_Node : Count_Type; + New_Node : Count_Type; begin if Before.Container /= null then @@ -1094,13 +1095,15 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is end if; Allocate (Container, New_Item, New_Node); - Insert_Internal (Container, Before.Node, New_Node => New_Node); - Position := Cursor'(Container'Unchecked_Access, Node => New_Node); + First_Node := New_Node; + Insert_Internal (Container, Before.Node, New_Node); for Index in Count_Type'(2) .. Count loop - Allocate (Container, New_Item, New_Node => New_Node); - Insert_Internal (Container, Before.Node, New_Node => New_Node); + Allocate (Container, New_Item, New_Node); + Insert_Internal (Container, Before.Node, New_Node); end loop; + + Position := Cursor'(Container'Unchecked_Access, First_Node); end Insert; procedure Insert diff --git a/gcc/ada/a-cdlili.adb b/gcc/ada/a-cdlili.adb index 9bd8899e2dd..eae608c05b2 100644 --- a/gcc/ada/a-cdlili.adb +++ b/gcc/ada/a-cdlili.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2004-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2004-2014, 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- -- @@ -942,7 +942,8 @@ package body Ada.Containers.Doubly_Linked_Lists is Position : out Cursor; Count : Count_Type := 1) is - New_Node : Node_Access; + First_Node : Node_Access; + New_Node : Node_Access; begin if Before.Container /= null then @@ -966,15 +967,16 @@ package body Ada.Containers.Doubly_Linked_Lists is "attempt to tamper with cursors (list is busy)"; else - New_Node := new Node_Type'(New_Item, null, null); + New_Node := new Node_Type'(New_Item, null, null); + First_Node := New_Node; Insert_Internal (Container, Before.Node, New_Node); - Position := Cursor'(Container'Unchecked_Access, New_Node); - for J in 2 .. Count loop New_Node := new Node_Type'(New_Item, null, null); Insert_Internal (Container, Before.Node, New_Node); end loop; + + Position := Cursor'(Container'Unchecked_Access, First_Node); end if; end Insert; @@ -996,7 +998,8 @@ package body Ada.Containers.Doubly_Linked_Lists is Position : out Cursor; Count : Count_Type := 1) is - New_Node : Node_Access; + First_Node : Node_Access; + New_Node : Node_Access; begin if Before.Container /= null then @@ -1021,15 +1024,16 @@ package body Ada.Containers.Doubly_Linked_Lists is "attempt to tamper with cursors (list is busy)"; else - New_Node := new Node_Type; + New_Node := new Node_Type; + First_Node := New_Node; Insert_Internal (Container, Before.Node, New_Node); - Position := Cursor'(Container'Unchecked_Access, New_Node); - for J in 2 .. Count loop New_Node := new Node_Type; Insert_Internal (Container, Before.Node, New_Node); end loop; + + Position := Cursor'(Container'Unchecked_Access, First_Node); end if; end Insert; diff --git a/gcc/ada/a-chahan.ads b/gcc/ada/a-chahan.ads index ca52f94730c..c34e5e2e450 100644 --- a/gcc/ada/a-chahan.ads +++ b/gcc/ada/a-chahan.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- This specification is derived from the Ada Reference Manual for use with -- -- GNAT. The copyright notice above, and the license provisions that follow -- @@ -34,8 +34,7 @@ ------------------------------------------------------------------------------ package Ada.Characters.Handling is - pragma Preelaborate; - pragma Pure_05; + pragma Pure; -- In accordance with Ada 2005 AI-362 ---------------------------------------- diff --git a/gcc/ada/a-cidlli.adb b/gcc/ada/a-cidlli.adb index f1fc3d3beb2..c41be78fcf3 100644 --- a/gcc/ada/a-cidlli.adb +++ b/gcc/ada/a-cidlli.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2004-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2004-2014, 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- -- @@ -983,7 +983,8 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is Position : out Cursor; Count : Count_Type := 1) is - New_Node : Node_Access; + First_Node : Node_Access; + New_Node : Node_Access; begin if Before.Container /= null then @@ -1026,7 +1027,8 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is Element : Element_Access := new Element_Type'(New_Item); begin - New_Node := new Node_Type'(Element, null, null); + New_Node := new Node_Type'(Element, null, null); + First_Node := New_Node; exception when others => @@ -1035,7 +1037,6 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is end; Insert_Internal (Container, Before.Node, New_Node); - Position := Cursor'(Container'Unchecked_Access, New_Node); for J in 2 .. Count loop declare @@ -1050,6 +1051,8 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is Insert_Internal (Container, Before.Node, New_Node); end loop; + + Position := Cursor'(Container'Unchecked_Access, First_Node); end Insert; procedure Insert diff --git a/gcc/ada/a-coinho-shared.adb b/gcc/ada/a-coinho-shared.adb index 9300c0b1dc6..222c2f14205 100644 --- a/gcc/ada/a-coinho-shared.adb +++ b/gcc/ada/a-coinho-shared.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2013-2014, 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- -- @@ -62,6 +62,13 @@ package body Ada.Containers.Indefinite_Holders is Container.Busy := 0; end Adjust; + overriding procedure Adjust (Control : in out Reference_Control_Type) is + begin + if Control.Container /= null then + Reference (Control.Container); + end if; + end Adjust; + ------------ -- Assign -- ------------ @@ -99,6 +106,21 @@ package body Ada.Containers.Indefinite_Holders is Container.Reference := null; end Clear; + ------------------------ + -- Constant_Reference -- + ------------------------ + + function Constant_Reference + (Container : aliased Holder) return Constant_Reference_Type + is + Ref : constant Constant_Reference_Type := + (Element => Container.Reference.Element, + Control => (Controlled with Container.Reference)); + begin + Reference (Ref.Control.Container); + return Ref; + end Constant_Reference; + ---------- -- Copy -- ---------- @@ -106,11 +128,11 @@ package body Ada.Containers.Indefinite_Holders is function Copy (Source : Holder) return Holder is begin if Source.Reference = null then - return (AF.Controlled with null, 0); + return (Controlled with null, 0); else Reference (Source.Reference); - return (AF.Controlled with Source.Reference, 0); + return (Controlled with Source.Reference, 0); end if; end Copy; @@ -143,6 +165,15 @@ package body Ada.Containers.Indefinite_Holders is end if; end Finalize; + overriding procedure Finalize (Control : in out Reference_Control_Type) is + begin + if Control.Container /= null then + Unreference (Control.Container); + end if; + + Control.Container := null; + end Finalize; + -------------- -- Is_Empty -- -------------- @@ -223,6 +254,22 @@ package body Ada.Containers.Indefinite_Holders is end if; end Read; + procedure Read + (Stream : not null access Root_Stream_Type'Class; + Item : out Constant_Reference_Type) + is + begin + raise Program_Error with "attempt to stream reference"; + end Read; + + procedure Read + (Stream : not null access Root_Stream_Type'Class; + Item : out Reference_Type) + is + begin + raise Program_Error with "attempt to stream reference"; + end Read; + --------------- -- Reference -- --------------- @@ -232,6 +279,17 @@ package body Ada.Containers.Indefinite_Holders is System.Atomic_Counters.Increment (Item.Counter); end Reference; + function Reference + (Container : aliased in out Holder) return Reference_Type + is + Ref : constant Reference_Type := + (Element => Container.Reference.Element, + Control => (Controlled with Container.Reference)); + begin + Reference (Ref.Control.Container); + return Ref; + end Reference; + --------------------- -- Replace_Element -- --------------------- @@ -287,7 +345,7 @@ package body Ada.Containers.Indefinite_Holders is begin return - (AF.Controlled with + (Controlled with new Shared_Holder' (Counter => <>, Element => new Element_Type'(New_Item)), 0); @@ -355,4 +413,20 @@ package body Ada.Containers.Indefinite_Holders is end if; end Write; + procedure Write + (Stream : not null access Root_Stream_Type'Class; + Item : Reference_Type) + is + begin + raise Program_Error with "attempt to stream reference"; + end Write; + + procedure Write + (Stream : not null access Root_Stream_Type'Class; + Item : Constant_Reference_Type) + is + begin + raise Program_Error with "attempt to stream reference"; + end Write; + end Ada.Containers.Indefinite_Holders; diff --git a/gcc/ada/a-coinho-shared.ads b/gcc/ada/a-coinho-shared.ads index 9abeda33a8f..e97a64af655 100644 --- a/gcc/ada/a-coinho-shared.ads +++ b/gcc/ada/a-coinho-shared.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2013-2014, Free Software Foundation, Inc. -- -- -- -- This specification is derived from the Ada Reference Manual for use with -- -- GNAT. The copyright notice above, and the license provisions that follow -- @@ -67,6 +67,24 @@ package Ada.Containers.Indefinite_Holders is (Container : Holder; Process : not null access procedure (Element : in out Element_Type)); + type Constant_Reference_Type + (Element : not null access constant Element_Type) is private + with + Implicit_Dereference => Element; + + type Reference_Type + (Element : not null access Element_Type) is private + with + Implicit_Dereference => Element; + + function Constant_Reference + (Container : aliased Holder) return Constant_Reference_Type; + pragma Inline (Constant_Reference); + + function Reference + (Container : aliased in out Holder) return Reference_Type; + pragma Inline (Reference); + procedure Assign (Target : in out Holder; Source : Holder); function Copy (Source : Holder) return Holder; @@ -75,7 +93,8 @@ package Ada.Containers.Indefinite_Holders is private - package AF renames Ada.Finalization; + use Ada.Finalization; + use Ada.Streams; type Element_Access is access all Element_Type; @@ -110,6 +129,51 @@ private overriding procedure Adjust (Container : in out Holder); overriding procedure Finalize (Container : in out Holder); - Empty_Holder : constant Holder := (AF.Controlled with null, 0); + type Reference_Control_Type is new Controlled with + record + Container : Shared_Holder_Access; + end record; + + overriding procedure Adjust (Control : in out Reference_Control_Type); + pragma Inline (Adjust); + + overriding procedure Finalize (Control : in out Reference_Control_Type); + pragma Inline (Finalize); + + type Constant_Reference_Type + (Element : not null access constant Element_Type) is + record + Control : Reference_Control_Type; + end record; + + procedure Write + (Stream : not null access Root_Stream_Type'Class; + Item : Constant_Reference_Type); + + for Constant_Reference_Type'Write use Write; + + procedure Read + (Stream : not null access Root_Stream_Type'Class; + Item : out Constant_Reference_Type); + + for Constant_Reference_Type'Read use Read; + + type Reference_Type (Element : not null access Element_Type) is record + Control : Reference_Control_Type; + end record; + + procedure Write + (Stream : not null access Root_Stream_Type'Class; + Item : Reference_Type); + + for Reference_Type'Write use Write; + + procedure Read + (Stream : not null access Root_Stream_Type'Class; + Item : out Reference_Type); + + for Reference_Type'Read use Read; + + Empty_Holder : constant Holder := (Controlled with null, 0); end Ada.Containers.Indefinite_Holders; diff --git a/gcc/ada/a-coinho.adb b/gcc/ada/a-coinho.adb index 0d0d40064e9..4cb717936d6 100644 --- a/gcc/ada/a-coinho.adb +++ b/gcc/ada/a-coinho.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2012, Free Software Foundation, Inc. -- +-- Copyright (C) 2012-2014, 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- -- @@ -62,6 +62,17 @@ package body Ada.Containers.Indefinite_Holders is Container.Busy := 0; end Adjust; + overriding procedure Adjust (Control : in out Reference_Control_Type) is + begin + if Control.Container /= null then + declare + B : Natural renames Control.Container.Busy; + begin + B := B + 1; + end; + end if; + end Adjust; + ------------ -- Assign -- ------------ @@ -94,6 +105,22 @@ package body Ada.Containers.Indefinite_Holders is Free (Container.Element); end Clear; + ------------------------ + -- Constant_Reference -- + ------------------------ + + function Constant_Reference + (Container : aliased Holder) return Constant_Reference_Type + is + Ref : constant Constant_Reference_Type := + (Element => Container.Element.all'Access, + Control => (Controlled with Container'Unrestricted_Access)); + B : Natural renames Ref.Control.Container.Busy; + begin + B := B + 1; + return Ref; + end Constant_Reference; + ---------- -- Copy -- ---------- @@ -101,9 +128,9 @@ package body Ada.Containers.Indefinite_Holders is function Copy (Source : Holder) return Holder is begin if Source.Element = null then - return (AF.Controlled with null, 0); + return (Controlled with null, 0); else - return (AF.Controlled with new Element_Type'(Source.Element.all), 0); + return (Controlled with new Element_Type'(Source.Element.all), 0); end if; end Copy; @@ -133,6 +160,19 @@ package body Ada.Containers.Indefinite_Holders is Free (Container.Element); end Finalize; + overriding procedure Finalize (Control : in out Reference_Control_Type) is + begin + if Control.Container /= null then + declare + B : Natural renames Control.Container.Busy; + begin + B := B - 1; + end; + end if; + + Control.Container := null; + end Finalize; + -------------- -- Is_Empty -- -------------- @@ -207,6 +247,37 @@ package body Ada.Containers.Indefinite_Holders is end if; end Read; + procedure Read + (Stream : not null access Root_Stream_Type'Class; + Item : out Constant_Reference_Type) + is + begin + raise Program_Error with "attempt to stream reference"; + end Read; + + procedure Read + (Stream : not null access Root_Stream_Type'Class; + Item : out Reference_Type) + is + begin + raise Program_Error with "attempt to stream reference"; + end Read; + + --------------- + -- Reference -- + --------------- + + function Reference + (Container : aliased in out Holder) return Reference_Type + is + Ref : constant Reference_Type := + (Element => Container.Element.all'Access, + Control => (Controlled with Container'Unrestricted_Access)); + begin + Container.Busy := Container.Busy + 1; + return Ref; + end Reference; + --------------------- -- Replace_Element -- --------------------- @@ -240,6 +311,7 @@ package body Ada.Containers.Indefinite_Holders is --------------- function To_Holder (New_Item : Element_Type) return Holder is + -- The element allocator may need an accessibility check in the case the -- actual type is class-wide or has access discriminants (RM 4.8(10.1) -- and AI12-0035). @@ -247,7 +319,7 @@ package body Ada.Containers.Indefinite_Holders is pragma Unsuppress (Accessibility_Check); begin - return (AF.Controlled with new Element_Type'(New_Item), 0); + return (Controlled with new Element_Type'(New_Item), 0); end To_Holder; -------------------- @@ -294,4 +366,20 @@ package body Ada.Containers.Indefinite_Holders is end if; end Write; + procedure Write + (Stream : not null access Root_Stream_Type'Class; + Item : Reference_Type) + is + begin + raise Program_Error with "attempt to stream reference"; + end Write; + + procedure Write + (Stream : not null access Root_Stream_Type'Class; + Item : Constant_Reference_Type) + is + begin + raise Program_Error with "attempt to stream reference"; + end Write; + end Ada.Containers.Indefinite_Holders; diff --git a/gcc/ada/a-coinho.ads b/gcc/ada/a-coinho.ads index 4646b6722b8..c5f45f54636 100644 --- a/gcc/ada/a-coinho.ads +++ b/gcc/ada/a-coinho.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2011, Free Software Foundation, Inc. -- +-- Copyright (C) 2011-2014, Free Software Foundation, Inc. -- -- -- -- This specification is derived from the Ada Reference Manual for use with -- -- GNAT. The copyright notice above, and the license provisions that follow -- @@ -62,10 +62,29 @@ package Ada.Containers.Indefinite_Holders is procedure Query_Element (Container : Holder; Process : not null access procedure (Element : Element_Type)); + procedure Update_Element (Container : Holder; Process : not null access procedure (Element : in out Element_Type)); + type Constant_Reference_Type + (Element : not null access constant Element_Type) is private + with + Implicit_Dereference => Element; + + type Reference_Type + (Element : not null access Element_Type) is private + with + Implicit_Dereference => Element; + + function Constant_Reference + (Container : aliased Holder) return Constant_Reference_Type; + pragma Inline (Constant_Reference); + + function Reference + (Container : aliased in out Holder) return Reference_Type; + pragma Inline (Reference); + procedure Assign (Target : in out Holder; Source : Holder); function Copy (Source : Holder) return Holder; @@ -74,10 +93,14 @@ package Ada.Containers.Indefinite_Holders is private - package AF renames Ada.Finalization; + use Ada.Finalization; + use Ada.Streams; type Element_Access is access all Element_Type; + type Holder_Access is access all Holder; + for Holder_Access'Storage_Size use 0; + procedure Read (Stream : not null access Ada.Streams.Root_Stream_Type'Class; Container : out Holder); @@ -96,6 +119,51 @@ private overriding procedure Adjust (Container : in out Holder); overriding procedure Finalize (Container : in out Holder); - Empty_Holder : constant Holder := (AF.Controlled with null, 0); + type Reference_Control_Type is new Controlled with + record + Container : Holder_Access; + end record; + + overriding procedure Adjust (Control : in out Reference_Control_Type); + pragma Inline (Adjust); + + overriding procedure Finalize (Control : in out Reference_Control_Type); + pragma Inline (Finalize); + + type Constant_Reference_Type + (Element : not null access constant Element_Type) is + record + Control : Reference_Control_Type; + end record; + + procedure Write + (Stream : not null access Root_Stream_Type'Class; + Item : Constant_Reference_Type); + + for Constant_Reference_Type'Write use Write; + + procedure Read + (Stream : not null access Root_Stream_Type'Class; + Item : out Constant_Reference_Type); + + for Constant_Reference_Type'Read use Read; + + type Reference_Type (Element : not null access Element_Type) is record + Control : Reference_Control_Type; + end record; + + procedure Write + (Stream : not null access Root_Stream_Type'Class; + Item : Reference_Type); + + for Reference_Type'Write use Write; + + procedure Read + (Stream : not null access Root_Stream_Type'Class; + Item : out Reference_Type); + + for Reference_Type'Read use Read; + + Empty_Holder : constant Holder := (Controlled with null, 0); end Ada.Containers.Indefinite_Holders; diff --git a/gcc/ada/a-crdlli.adb b/gcc/ada/a-crdlli.adb index 8d5fe9f5c56..0c6f5dccbb7 100644 --- a/gcc/ada/a-crdlli.adb +++ b/gcc/ada/a-crdlli.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2004-2012, Free Software Foundation, Inc. -- +-- Copyright (C) 2004-2014, 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- -- @@ -614,7 +614,8 @@ package body Ada.Containers.Restricted_Doubly_Linked_Lists is Position : out Cursor; Count : Count_Type := 1) is - J : Count_Type; + First_Node : Count_Type; + New_Node : Count_Type; begin if Before.Container /= null then @@ -638,14 +639,16 @@ package body Ada.Containers.Restricted_Doubly_Linked_Lists is -- raise Program_Error; -- end if; - Allocate (Container, New_Item, New_Node => J); - Insert_Internal (Container, Before.Node, New_Node => J); - Position := Cursor'(Container'Unrestricted_Access, Node => J); + Allocate (Container, New_Item, New_Node); + First_Node := New_Node; + Insert_Internal (Container, Before.Node, New_Node); for Index in 2 .. Count loop - Allocate (Container, New_Item, New_Node => J); - Insert_Internal (Container, Before.Node, New_Node => J); + Allocate (Container, New_Item, New_Node); + Insert_Internal (Container, Before.Node, New_Node); end loop; + + Position := Cursor'(Container'Unrestricted_Access, First_Node); end Insert; procedure Insert diff --git a/gcc/ada/a-dynpri.ads b/gcc/ada/a-dynpri.ads index 03e02d63547..24fbbe48d8d 100644 --- a/gcc/ada/a-dynpri.ads +++ b/gcc/ada/a-dynpri.ads @@ -17,7 +17,7 @@ with System; with Ada.Task_Identification; package Ada.Dynamic_Priorities is - pragma Preelaborate_05; + pragma Preelaborate; -- In accordance with Ada 2005 AI-362 procedure Set_Priority diff --git a/gcc/ada/a-except-2005.ads b/gcc/ada/a-except-2005.ads index 71a3f198c14..90c952c3086 100644 --- a/gcc/ada/a-except-2005.ads +++ b/gcc/ada/a-except-2005.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- This specification is derived from the Ada Reference Manual for use with -- -- GNAT. The copyright notice above, and the license provisions that follow -- @@ -51,7 +51,7 @@ with System.Standard_Library; with System.Traceback_Entries; package Ada.Exceptions is - pragma Preelaborate_05; + pragma Preelaborate; -- In accordance with Ada 2005 AI-362. type Exception_Id is private; diff --git a/gcc/ada/a-finali.ads b/gcc/ada/a-finali.ads index b53fd2a8784..b65f6eabac7 100644 --- a/gcc/ada/a-finali.ads +++ b/gcc/ada/a-finali.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2011, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- This specification is derived from the Ada Reference Manual for use with -- -- GNAT. The copyright notice above, and the license provisions that follow -- @@ -38,12 +38,7 @@ with System.Finalization_Root; pragma Warnings (On); package Ada.Finalization is - pragma Pure_12; - -- Ada.Finalization is declared pure in Ada 2012 (AI05-0212) - - pragma Preelaborate; - pragma Remote_Types; - -- The above apply in versions of Ada before Ada 2012 + pragma Pure; type Controlled is abstract tagged private; pragma Preelaborable_Initialization (Controlled); diff --git a/gcc/ada/a-stmaco.ads b/gcc/ada/a-stmaco.ads index 733dfc66d70..92d70219602 100644 --- a/gcc/ada/a-stmaco.ads +++ b/gcc/ada/a-stmaco.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- This specification is derived from the Ada Reference Manual for use with -- -- GNAT. The copyright notice above, and the license provisions that follow -- @@ -36,8 +36,7 @@ with Ada.Characters.Latin_1; package Ada.Strings.Maps.Constants is - pragma Preelaborate; - pragma Pure_05; + pragma Pure; -- In accordance with Ada 2005 AI-362 Control_Set : constant Character_Set; diff --git a/gcc/ada/a-strmap.ads b/gcc/ada/a-strmap.ads index 2a6908ff3ae..a882e9c4ed5 100644 --- a/gcc/ada/a-strmap.ads +++ b/gcc/ada/a-strmap.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- This specification is derived from the Ada Reference Manual for use with -- -- GNAT. The copyright notice above, and the license provisions that follow -- @@ -36,8 +36,7 @@ with Ada.Characters.Latin_1; package Ada.Strings.Maps is - pragma Preelaborate; - pragma Pure_05; + pragma Pure; -- In accordance with Ada 2005 AI-362 -------------------------------- diff --git a/gcc/ada/a-sytaco.ads b/gcc/ada/a-sytaco.ads index 02ba6ae1a9f..a6bd84e1a2b 100644 --- a/gcc/ada/a-sytaco.ads +++ b/gcc/ada/a-sytaco.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- This specification is derived from the Ada Reference Manual for use with -- -- GNAT. The copyright notice above, and the license provisions that follow -- @@ -38,7 +38,7 @@ with System.Task_Primitives; with Ada.Finalization; package Ada.Synchronous_Task_Control is - pragma Preelaborate_05; + pragma Preelaborate; -- In accordance with Ada 2005 AI-362 type Suspension_Object is limited private; diff --git a/gcc/ada/a-tags.ads b/gcc/ada/a-tags.ads index 6d94c3fa4d9..0a0a375c061 100644 --- a/gcc/ada/a-tags.ads +++ b/gcc/ada/a-tags.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2011, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- This specification is derived from the Ada Reference Manual for use with -- -- GNAT. The copyright notice above, and the license provisions that follow -- @@ -37,7 +37,7 @@ with System; with System.Storage_Elements; package Ada.Tags is - pragma Preelaborate_05; + pragma Preelaborate; -- In accordance with Ada 2005 AI-362 type Tag is private; diff --git a/gcc/ada/a-taside.ads b/gcc/ada/a-taside.ads index e53ff04ac28..d736b0317d0 100644 --- a/gcc/ada/a-taside.ads +++ b/gcc/ada/a-taside.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- This specification is derived from the Ada Reference Manual for use with -- -- GNAT. The copyright notice above, and the license provisions that follow -- @@ -37,7 +37,7 @@ with System; with System.Tasking; package Ada.Task_Identification is - pragma Preelaborate_05; + pragma Preelaborate; -- In accordance with Ada 2005 AI-362 type Task_Id is private; diff --git a/gcc/ada/a-tgdico.ads b/gcc/ada/a-tgdico.ads index d1150fd5991..6da900183dc 100644 --- a/gcc/ada/a-tgdico.ads +++ b/gcc/ada/a-tgdico.ads @@ -25,9 +25,5 @@ generic function Ada.Tags.Generic_Dispatching_Constructor (The_Tag : Tag; Params : not null access Parameters) return T'Class; -pragma Preelaborate_05 (Generic_Dispatching_Constructor); +pragma Preelaborate (Generic_Dispatching_Constructor); pragma Import (Intrinsic, Generic_Dispatching_Constructor); --- Note: the reason that we use Preelaborate_05 here is so that this will --- compile fine during the normal build procedures. In Ada 2005 mode (which --- is required for this package anyway), this will be treated as Preelaborate --- so everything will be fine. diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c index 8d574da2cc8..b1d31b79a96 100644 --- a/gcc/ada/adaint.c +++ b/gcc/ada/adaint.c @@ -6,7 +6,7 @@ * * * C Implementation File * * * - * Copyright (C) 1992-2013, Free Software Foundation, Inc. * + * Copyright (C) 1992-2014, 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- * @@ -1159,9 +1159,12 @@ __gnat_open_new_temp (char *path, int fmode) o_fmode = O_TEXT; #if defined (VMS) + /* Passing rfm=stmlf for binary files seems questionable since it results + in having an extraneous line feed added after every call to CRTL write, + so pass rfm=udf (aka undefined) instead. */ fd = open (path, O_WRONLY | O_CREAT | O_EXCL | o_fmode, PERM, - "rfm=stmlf", "ctx=rec", "rat=none", "shr=del,get,put,upd", - "mbc=16", "deq=64", "fop=tef"); + fmode ? "rfm=stmlf" : "rfm=udf", "ctx=rec", "rat=none", + "shr=del,get,put,upd", "mbc=16", "deq=64", "fop=tef"); #else fd = open (path, O_WRONLY | O_CREAT | O_EXCL | o_fmode, PERM); #endif diff --git a/gcc/ada/aspects.adb b/gcc/ada/aspects.adb index cc8d2f93d82..d79566d1396 100644 --- a/gcc/ada/aspects.adb +++ b/gcc/ada/aspects.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2010-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2010-2014, 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- -- @@ -583,6 +583,7 @@ package body Aspects is Aspect_Suppress_Debug_Info => Aspect_Suppress_Debug_Info, Aspect_Synchronization => Aspect_Synchronization, Aspect_Test_Case => Aspect_Test_Case, + Aspect_Thread_Local_Storage => Aspect_Thread_Local_Storage, Aspect_Type_Invariant => Aspect_Invariant, Aspect_Unchecked_Union => Aspect_Unchecked_Union, Aspect_Universal_Aliasing => Aspect_Universal_Aliasing, diff --git a/gcc/ada/aspects.ads b/gcc/ada/aspects.ads index ad79cbdbbd7..8199df9f39a 100644 --- a/gcc/ada/aspects.ads +++ b/gcc/ada/aspects.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2010-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2010-2014, 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- -- @@ -183,6 +183,7 @@ package Aspects is Aspect_Shared, -- GNAT (equivalent to Atomic) Aspect_Simple_Storage_Pool_Type, -- GNAT Aspect_Suppress_Debug_Info, -- GNAT + Aspect_Thread_Local_Storage, -- GNAT Aspect_Unchecked_Union, Aspect_Universal_Aliasing, -- GNAT Aspect_Unmodified, -- GNAT @@ -237,6 +238,7 @@ package Aspects is Aspect_Simple_Storage_Pool => True, Aspect_Simple_Storage_Pool_Type => True, Aspect_Suppress_Debug_Info => True, + Aspect_Thread_Local_Storage => True, Aspect_Test_Case => True, Aspect_Universal_Aliasing => True, Aspect_Universal_Data => True, @@ -454,6 +456,7 @@ package Aspects is Aspect_Stream_Size => Name_Stream_Size, Aspect_Suppress => Name_Suppress, Aspect_Suppress_Debug_Info => Name_Suppress_Debug_Info, + Aspect_Thread_Local_Storage => Name_Thread_Local_Storage, Aspect_Synchronization => Name_Synchronization, Aspect_Test_Case => Name_Test_Case, Aspect_Type_Invariant => Name_Type_Invariant, @@ -647,6 +650,7 @@ package Aspects is Aspect_Stream_Size => Always_Delay, Aspect_Suppress => Always_Delay, Aspect_Suppress_Debug_Info => Always_Delay, + Aspect_Thread_Local_Storage => Always_Delay, Aspect_Type_Invariant => Always_Delay, Aspect_Unchecked_Union => Always_Delay, Aspect_Universal_Aliasing => Always_Delay, diff --git a/gcc/ada/back_end.adb b/gcc/ada/back_end.adb index bb442ad5e53..b79f1f9072a 100644 --- a/gcc/ada/back_end.adb +++ b/gcc/ada/back_end.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -163,6 +163,15 @@ package body Back_End is gigi_operating_mode => Mode); end Call_Back_End; + ------------------------------- + -- Gen_Or_Update_Object_File -- + ------------------------------- + + procedure Gen_Or_Update_Object_File is + begin + null; + end Gen_Or_Update_Object_File; + ------------- -- Len_Arg -- ------------- @@ -342,13 +351,4 @@ package body Back_End is end loop; end Scan_Compiler_Arguments; - ------------------------------- - -- Gen_Or_Update_Object_File -- - ------------------------------- - - procedure Gen_Or_Update_Object_File is - begin - null; - end Gen_Or_Update_Object_File; - end Back_End; diff --git a/gcc/ada/back_end.ads b/gcc/ada/back_end.ads index 9e28a6ed6f3..0d45a9ba7e6 100644 --- a/gcc/ada/back_end.ads +++ b/gcc/ada/back_end.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -24,6 +24,8 @@ ------------------------------------------------------------------------------ -- Call the back end with all the information needed +-- Note: there are multiple bodies/variants of this package, so do not +-- modify this spec without coordination. package Back_End is diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb index 7d3979dcbb2..61d0324cc7d 100644 --- a/gcc/ada/checks.adb +++ b/gcc/ada/checks.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -27,15 +27,14 @@ with Atree; use Atree; with Casing; use Casing; with Debug; use Debug; with Einfo; use Einfo; -with Errout; use Errout; +with Elists; use Elists; +with Eval_Fat; use Eval_Fat; +with Exp_Ch11; use Exp_Ch11; with Exp_Ch2; use Exp_Ch2; with Exp_Ch4; use Exp_Ch4; -with Exp_Ch11; use Exp_Ch11; with Exp_Pakd; use Exp_Pakd; with Exp_Util; use Exp_Util; -with Elists; use Elists; with Expander; use Expander; -with Eval_Fat; use Eval_Fat; with Freeze; use Freeze; with Lib; use Lib; with Nlists; use Nlists; @@ -47,9 +46,9 @@ with Rident; use Rident; with Rtsfind; use Rtsfind; with Sem; use Sem; with Sem_Aux; use Sem_Aux; -with Sem_Eval; use Sem_Eval; with Sem_Ch3; use Sem_Ch3; with Sem_Ch8; use Sem_Ch8; +with Sem_Eval; use Sem_Eval; with Sem_Res; use Sem_Res; with Sem_Util; use Sem_Util; with Sem_Warn; use Sem_Warn; @@ -589,7 +588,7 @@ package body Checks is Expr : Node_Id; -- Address expression (not necessarily the same as Aexp, for example -- when Aexp is a reference to a constant, in which case Expr gets - -- reset to reference the value expression of the constant. + -- reset to reference the value expression of the constant). procedure Compile_Time_Bad_Alignment; -- Post error warnings when alignment is known to be incompatible. Note @@ -758,20 +757,32 @@ package body Checks is Prefix => New_Occurrence_Of (E, Loc), Attribute_Name => Name_Alignment)), Right_Opnd => Make_Integer_Literal (Loc, Uint_0)), - Reason => PE_Misaligned_Address_Value)); + Reason => PE_Misaligned_Address_Value)); + + Warning_Msg := No_Error_Msg; Analyze (First (Actions (N)), Suppress => All_Checks); - -- If the address clause generates an alignment check and we are - -- in ZPF or some restricted run-time, add a warning to explain - -- the propagation warning that is generated by the check. + -- If the address clause generated a warning message (for example, + -- from Warn_On_Non_Local_Exception mode with the active restriction + -- No_Exception_Propagation). + + if Warning_Msg /= No_Error_Msg then + + -- If the expression has a known at compile time value, then + -- once we know the alignment of the type, we can check if the + -- exception will be raised or not, and if not, we don't need + -- the warning so we will kill the warning later on. + + if Compile_Time_Known_Value (Expr) then + Alignment_Warnings.Append + ((E => E, A => Expr_Value (Expr), W => Warning_Msg)); + end if; + + -- Add explanation of the warning that is generated by the check - if Nkind (First (Actions (N))) = N_Raise_Program_Error - and then not Warnings_Off (E) - and then Restriction_Active (No_Exception_Propagation) - then Error_Msg_N - ("address value may be incompatible with alignment of object?", - N); + ("\address value may be incompatible with alignment " + & "of object?X?", AC); end if; return; @@ -3128,7 +3139,7 @@ package body Checks is else Apply_Compile_Time_Constraint_Error (Ck_Node, - "static value out of range of}?", + "static value out of range of}??", CE_Range_Check_Failed, Ent => Target_Typ, Typ => Target_Typ); @@ -3913,7 +3924,7 @@ package body Checks is Apply_Compile_Time_Constraint_Error (N => Expr, Msg => "(Ada 2005) null not allowed " - & "in null-excluding objects?", + & "in null-excluding objects??", Reason => CE_Null_Not_Allowed); when N_Parameter_Specification => @@ -4118,26 +4129,37 @@ package body Checks is -- Start of processing for Determine_Range begin + -- Prevent junk warnings by initializing range variables + + Lo := No_Uint; + Hi := No_Uint; + Lor := No_Uint; + Hir := No_Uint; + -- For temporary constants internally generated to remove side effects -- we must use the corresponding expression to determine the range of - -- the expression. + -- the expression. But note that the expander can also generate + -- constants in other cases, including deferred constants. if Is_Entity_Name (N) and then Nkind (Parent (Entity (N))) = N_Object_Declaration and then Ekind (Entity (N)) = E_Constant and then Is_Internal_Name (Chars (Entity (N))) then - Determine_Range - (Expression (Parent (Entity (N))), OK, Lo, Hi, Assume_Valid); - return; - end if; + if Present (Expression (Parent (Entity (N)))) then + Determine_Range + (Expression (Parent (Entity (N))), OK, Lo, Hi, Assume_Valid); - -- Prevent junk warnings by initializing range variables + elsif Present (Full_View (Entity (N))) then + Determine_Range + (Expression (Parent (Full_View (Entity (N)))), + OK, Lo, Hi, Assume_Valid); - Lo := No_Uint; - Hi := No_Uint; - Lor := No_Uint; - Hir := No_Uint; + else + OK := False; + end if; + return; + end if; -- If type is not defined, we can't determine its range @@ -9471,6 +9493,26 @@ package body Checks is end if; end Tag_Checks_Suppressed; + --------------------------------------- + -- Validate_Alignment_Check_Warnings -- + --------------------------------------- + + procedure Validate_Alignment_Check_Warnings is + begin + for J in Alignment_Warnings.First .. Alignment_Warnings.Last loop + declare + AWR : Alignment_Warnings_Record + renames Alignment_Warnings.Table (J); + begin + if Known_Alignment (AWR.E) + and then AWR.A mod Alignment (AWR.E) = 0 + then + Delete_Warning_And_Continuations (AWR.W); + end if; + end; + end loop; + end Validate_Alignment_Check_Warnings; + -------------------------- -- Validity_Check_Range -- -------------------------- diff --git a/gcc/ada/checks.ads b/gcc/ada/checks.ads index 2d9c25e31ae..1c6b810848d 100644 --- a/gcc/ada/checks.ads +++ b/gcc/ada/checks.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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,6 +35,7 @@ -- This always occurs whether checks are suppressed or not. Dynamic range -- checks are, of course, not inserted if checks are suppressed. +with Errout; use Errout; with Namet; use Namet; with Table; with Types; use Types; @@ -79,6 +80,53 @@ package Checks is -- Returns current overflow checking mode, taking into account whether -- we are inside an assertion expression. + ------------------------------------------ + -- Control of Alignment Check Warnings -- + ------------------------------------------ + + -- When we have address clauses, there is an issue of whether the address + -- specified is appropriate to the alignment. In the general case where the + -- address is dynamic, we generate a check and a possible warning (this + -- warning occurs for example if we have a restricted run time with the + -- restriction No_Exception_Propagation). We also issue this warning in + -- the case where the address is static, but we don't know the alignment + -- at the time we process the address clause. In such a case, we issue the + -- warning, but we may be able to find out later (after the back end has + -- annotated the actual alignment chosen) that the warning was not needed. + + -- To deal with deleting these potentially annoying warnings, we save the + -- warning information in a table, and then delete the waranings in the + -- post compilation validation stage if we can tell that the check would + -- never fail (in general the back end will also optimize away the check + -- in such cases). + + -- Table used to record information + + type Alignment_Warnings_Record is record + E : Entity_Id; + -- Entity whose alignment possibly warrants a warning + + A : Uint; + -- Compile time known value of address clause for which the alignment + -- is to be checked once we know the alignment. + + W : Error_Msg_Id; + -- Id of warning message we might delete + end record; + + package Alignment_Warnings is new Table.Table ( + Table_Component_Type => Alignment_Warnings_Record, + Table_Index_Type => Int, + Table_Low_Bound => 0, + Table_Initial => 10, + Table_Increment => 200, + Table_Name => "Alignment_Warnings"); + + procedure Validate_Alignment_Check_Warnings; + -- This routine is called after back annotation of type data to delete any + -- alignment warnings that turn out to be false alarms, based on knowing + -- the actual alignment, and a compile-time known alignment value. + ------------------------------------------- -- Procedures to Activate Checking Flags -- ------------------------------------------- diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb index 8399a2c9900..e54b631d241 100644 --- a/gcc/ada/debug.adb +++ b/gcc/ada/debug.adb @@ -116,7 +116,7 @@ package body Debug is -- d.w Do not check for infinite loops -- d.x No exception handlers -- d.y - -- d.z Temporary ASIS kludge for why non-static messages + -- d.z -- d.A Read/write Aspect_Specifications hash table to tree -- d.B @@ -155,6 +155,16 @@ package body Debug is -- d8 Force opposite endianness in packed stuff -- d9 Allow lock free implementation + -- d.1 + -- d.2 + -- d.3 + -- d.4 + -- d.5 + -- d.6 + -- d.7 + -- d.8 + -- d.9 + -- Debug flags for binder (GNATBIND) -- da All links (including internal units) listed if there is a cycle @@ -589,11 +599,6 @@ package body Debug is -- fully compiled and analyzed, they just get eliminated from the -- code generation step. - -- d.z Temporary debug switch for control of the why non-static messages - -- generated by Why_Non_Static. Normally these messages are suppressed - -- in ASIS mode (d2), but if d.z is set they are not suppressed. This - -- is a temporary switch to aid in updating ASIS base lines. - -- d.A There seems to be a problem with ASIS if we activate the circuit -- for reading and writing the aspect specification hash table, so -- for now, this is controlled by the debug flag d.A. The hash table diff --git a/gcc/ada/einfo.adb b/gcc/ada/einfo.adb index 076cf7bf057..22bd41fdc05 100644 --- a/gcc/ada/einfo.adb +++ b/gcc/ada/einfo.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -558,12 +558,12 @@ package body Einfo is -- SPARK_Pragma_Inherited Flag265 -- SPARK_Aux_Pragma_Inherited Flag266 -- Has_Shift_Operator Flag267 + -- Is_Independent Flag268 -- (unused) Flag1 -- (unused) Flag2 -- (unused) Flag3 - -- (unused) Flag268 -- (unused) Flag269 -- (unused) Flag270 @@ -1476,8 +1476,8 @@ package body Einfo is function Has_Independent_Components (Id : E) return B is begin - pragma Assert (Is_Object (Id) or else Is_Type (Id)); - return Flag34 (Id); + pragma Assert (Is_Array_Type (Id) or else Is_Record_Type (Id)); + return Flag34 (Base_Type (Id)); end Has_Independent_Components; function Has_Inheritable_Invariants (Id : E) return B is @@ -2077,6 +2077,12 @@ package body Einfo is return Flag24 (Id); end Is_Imported; + function Is_Independent (Id : E) return B is + begin + pragma Assert (Ekind (Id) = E_Component); + return Flag268 (Id); + end Is_Independent; + function Is_Inlined (Id : E) return B is begin return Flag11 (Id); @@ -4177,7 +4183,8 @@ package body Einfo is procedure Set_Has_Independent_Components (Id : E; V : B := True) is begin - pragma Assert (Is_Object (Id) or else Is_Type (Id)); + pragma Assert ((Is_Array_Type (Id) or else Is_Record_Type (Id)) + and then Is_Base_Type (Id)); Set_Flag34 (Id, V); end Set_Has_Independent_Components; @@ -4811,6 +4818,12 @@ package body Einfo is Set_Flag24 (Id, V); end Set_Is_Imported; + procedure Set_Is_Independent (Id : E; V : B := True) is + begin + pragma Assert (Ekind_In (Id, E_Component, E_Void)); + Set_Flag268 (Id, V); + end Set_Is_Independent; + procedure Set_Is_Inlined (Id : E; V : B := True) is begin Set_Flag11 (Id, V); @@ -8181,6 +8194,7 @@ package body Einfo is W ("Has_Gigi_Rep_Item", Flag82 (Id)); W ("Has_Homonym", Flag56 (Id)); W ("Has_Implicit_Dereference", Flag251 (Id)); + W ("Has_Independent_Components", Flag34 (Id)); W ("Has_Inheritable_Invariants", Flag248 (Id)); W ("Has_Initial_Value", Flag219 (Id)); W ("Has_Invariants", Flag232 (Id)); @@ -8283,6 +8297,7 @@ package body Einfo is W ("Is_Immediately_Visible", Flag7 (Id)); W ("Is_Implementation_Defined", Flag254 (Id)); W ("Is_Imported", Flag24 (Id)); + W ("Is_Independent", Flag268 (Id)); W ("Is_Inlined", Flag11 (Id)); W ("Is_Instantiated", Flag126 (Id)); W ("Is_Interface", Flag186 (Id)); diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads index 998be8b7842..51b537bb93c 100644 --- a/gcc/ada/einfo.ads +++ b/gcc/ada/einfo.ads @@ -101,9 +101,9 @@ package Einfo is -- pragma Inline declarations -- This order must be observed. There are no restrictions on the procedures, --- since the C header file only includes functions (Gigi is not allowed to --- modify the generated tree). However, functions are required to have headers --- that fit on a single line. +-- since the C header file only includes functions (The back end is not +-- allowed to modify the generated tree). However, functions are required to +-- have headers that fit on a single line. -- XEINFO reads and processes the function specs and the pragma Inlines. For -- functions that are declared as inlined, XEINFO reads the corresponding body @@ -121,7 +121,7 @@ package Einfo is -- For functions that are not inlined, there is no restriction on the body, -- and XEINFO generates a direct reference in the C header file which allows --- the C code in Gigi to directly call the corresponding Ada body. +-- the C code in the backend to directly call the corresponding Ada body. ---------------------------------- -- Handling of Type'Size Values -- @@ -378,16 +378,16 @@ package Einfo is -- the N_Attribute_Definition_Clause node. Empty if no Address clause. -- The expression in the address clause is always a constant that is -- defined before the entity to which the address clause applies. --- Note: Gigi references this field in E_Task_Type entities??? +-- Note: The backend references this field in E_Task_Type entities??? -- Address_Taken (Flag104) -- Defined in all entities. Set if the Address or Unrestricted_Access -- attribute is applied directly to the entity, i.e. the entity is the -- entity of the prefix of the attribute reference. Also set if the -- entity is the second argument of an Asm_Input or Asm_Output attribute, --- as the construct may entail taking its address. Used by Gigi to make --- sure that the address can be meaningfully taken, and also in the case --- of subprograms to control output of certain warnings. +-- as the construct may entail taking its address. Used by the backend to +-- make sure that the address can be meaningfully taken, and also in the +-- case of subprograms to control output of certain warnings. -- Aft_Value (synthesized) -- Applies to fixed and decimal types. Computes a universal integer @@ -415,7 +415,7 @@ package Einfo is -- object. A value of zero (Uint_0) indicates that the alignment has not -- been set yet. The alignment can be set by an explicit alignment -- clause, or set by the front-end in package Layout, or set by the --- back-end as part of the back end back-annotation process. The +-- back-end as part of the back-end back-annotation process. The -- alignment field is also defined in E_Exception entities, but there it -- is used only by the back-end for back annotation. @@ -534,13 +534,13 @@ package Einfo is -- Can_Use_Internal_Rep (Flag229) [base type only] -- Defined in Access_Subprogram_Kind nodes. This flag is set by the --- front end and used by the back end. False means that the back end +-- front end and used by the backend. False means that the backend -- must represent the type in the same way as Convention-C types (and -- other foreign-convention types). On many targets, this means that --- the back end will use dynamically generated trampolines for nested --- subprograms. True means that the back end can represent the type in +-- the backend will use dynamically generated trampolines for nested +-- subprograms. True means that the backend can represent the type in -- some internal way. On the aforementioned targets, this means that the --- back end will not use dynamically generated trampolines. This flag +-- backend will not use dynamically generated trampolines. This flag -- must be False if Has_Foreign_Convention is True; otherwise, the front -- end is free to set the policy. -- @@ -568,11 +568,11 @@ package Einfo is -- table that has the character string of the identifier, character -- literal or operator symbol. See Namet for further details. Note that -- throughout the processing of the front end, this name is the simple --- unqualified name. However, just before gigi is called, a call is made --- to Qualify_All_Entity_Names. This causes entity names to be qualified --- using the encoding described in exp_dbug.ads, and from that point on --- (including post gigi steps such as cross-reference generation), the --- entities will contain the encoded qualified names. +-- unqualified name. However, just before the backend is called, a call +-- is made to Qualify_All_Entity_Names. This causes entity names to be +-- qualified using the encoding described in exp_dbug.ads, and from that +-- point (including post backend steps, e.g. cross-reference generation), +-- the entities will contain the encoded qualified names. -- Checks_May_Be_Suppressed (Flag31) -- Defined in all entities. Set if a pragma Suppress or Unsuppress @@ -639,7 +639,7 @@ package Einfo is -- Note: Component_Bit_Offset is redundant with respect to the fields -- Normalized_First_Bit and Normalized_Position, and could in principle -- be eliminated, but it is convenient in several situations, including --- use in Gigi, to have this redundant field. +-- use in the backend, to have this redundant field. -- Component_Clause (Node13) -- Defined in record components and discriminants. If a record @@ -733,7 +733,7 @@ package Einfo is -- to the entity, or if internal processing in the compiler determines -- that suppression of debug information is desirable. Note that this -- flag is only for use by the front end as part of the processing for --- determining if Needs_Debug_Info should be set. The back end should +-- determining if Needs_Debug_Info should be set. The backend should -- always test Needs_Debug_Info, it should never test Debug_Info_Off. -- Debug_Renaming_Link (Node25) @@ -1088,7 +1088,7 @@ package Einfo is -- Defined in class wide types and subtypes, access to protected -- subprogram types, and in exception types. For a classwide type, it -- is always Empty. For a class wide subtype, it points to an entity --- created by the expander which gives Gigi an easily understandable +-- created by the expander which gives the backend an understandable -- equivalent of the class subtype with a known size (given by an -- initial value). See Exp_Util.Expand_Class_Wide_Subtype for further -- details. For E_Exception_Type, this points to the record containing @@ -1111,8 +1111,8 @@ package Einfo is -- of a component to be set without a component clause defined, which -- means that the component size is specified, but not the position. -- See also RM_Size and the section on "Handling of Type'Size Values". --- During gigi processing, the value is back annotated for all zero --- values, so that after the call to gigi, the value is properly set. +-- During backend processing, the value is back annotated for all zero +-- values, so that after the call to the backend, the value is set. -- Etype (Node5) -- Defined in all entities. Represents the type of the entity, which @@ -1309,7 +1309,7 @@ package Einfo is -- Thread_Local_Storage pragma -- -- If any of these items are present, then the flag Has_Gigi_Rep_Item is --- set, indicating that Gigi should search the chain. +-- set, indicating that the backend should search the chain. -- -- Other representation items are included in the chain so that error -- messages can easily locate the relevant nodes for posting errors. @@ -1336,12 +1336,12 @@ package Einfo is -- Full_View (Node11) -- Defined in all type and subtype entities and in deferred constants. --- References the entity for the corresponding full type declaration. --- For all types other than private and incomplete types, this field --- always contains Empty. If an incomplete type E1 is completed by a --- private type E2 whose full type declaration entity is E3 then the --- full view of E1 is E2, and the full view of E2 is E3. See also --- Underlying_Type. +-- References the entity for the corresponding full type or constant +-- declaration. For all types other than private and incomplete types, +-- this field always contains Empty. If an incomplete type E1 is +-- completed by a private type E2 whose full type declaration entity is +-- E3 then the full view of E1 is E2, and the full view of E2 is E3. See +-- also Underlying_Type. -- Generic_Homonym (Node11) -- Defined in generic packages. The generic homonym is the entity of @@ -1558,8 +1558,8 @@ package Einfo is -- Has_Gigi_Rep_Item (Flag82) -- Defined in all entities. Set if the rep item chain (referenced by -- First_Rep_Item and linked through the Next_Rep_Item chain) contains a --- representation item that needs to be specially processed by Gigi, i.e. --- one of the following items: +-- representation item that needs to be specially processed by the back +-- end, i.e. one of the following items: -- -- Machine_Attribute pragma -- Linker_Alias pragma @@ -1568,22 +1568,24 @@ package Einfo is -- Weak_External pragma -- Thread_Local_Storage pragma -- --- If this flag is set, then Gigi should scan the rep item chain to --- process any of these items that appear. At least one such item will +-- If this flag is set, then the backend should scan the rep item chain +-- to process any of these items that appear. At least one such item will -- be present. -- -- Has_Homonym (Flag56) -- Defined in all entities. Set if an entity has a homonym in the same --- scope. Used by Gigi to generate unique names for such entities. +-- scope. Used by the backend to generate unique names for all entities. -- Has_Implicit_Dereference (Flag251) -- Defined in types and discriminants. Set if the type has an aspect -- Implicit_Dereference. Set also on the discriminant named in the aspect -- clause, to simplify type resolution. --- Has_Independent_Components (Flag34) --- Defined in objects and types. Set if the aspect Independent_Components --- applies (as set by coresponding pragma or aspect specification). +-- Has_Independent_Components (Flag34) [base type only] +-- Defined in types. Set if the aspect Independent_Components applies +-- (in the base type only), if corresponding pragma or aspect applies. +-- In the case of an object of anonymous array type, the flag is set on +-- the created array type. -- Has_Inheritable_Invariants (Flag248) -- Defined in all type entities. Set in private types from which one @@ -1644,7 +1646,7 @@ package Einfo is -- scope that has an exception handler and the two scopes are in the -- same procedure. This is used by the backend for controlling certain -- optimizations to ensure that they are consistent with exceptions. --- See documentation in Gigi for further details. +-- See documentation in backend for further details. -- Has_Non_Null_Refinement (synth) -- Defined in E_Abstract_State entities. True if the state has at least @@ -1870,7 +1872,7 @@ package Einfo is -- include only the components corresponding to these discriminants. -- Has_Static_Predicate_Aspect (Flag259) --- Defined in all types and subtypes. Set if a Dynamic_Predicate aspect +-- Defined in all types and subtypes. Set if a Static_Predicate aspect -- applies to the type. Note that we can tell if a static predicate is -- present by looking at Has_Predicates and Static_Predicate, but that -- could have come from a Predicate aspect or pragma, and we need to @@ -2183,9 +2185,9 @@ package Einfo is -- by the expander to represent a task or protected type. For every -- concurrent type, such as record type is constructed, and task and -- protected objects are instances of this record type at runtime --- (Gigi will replace declarations of the concurrent type using the --- declarations of the corresponding record type). See package Exp_Ch9 --- for further details. +-- (The backend will replace declarations of the concurrent type using +-- the declarations of the corresponding record type). See Exp_Ch9 for +-- further details. -- Is_Concurrent_Type (synthesized) -- Applies to all entities, true for task types and subtypes and for @@ -2210,7 +2212,7 @@ package Einfo is -- Defined in all types and subtypes. This flag can be set only if -- Is_Constr_Subt_For_U_Nominal is also set. It indicates that in -- addition the object concerned is aliased. This flag is used by --- Gigi to determine whether a template must be constructed. +-- the backend to determine whether a template must be constructed. -- Is_Constructor (Flag76) -- Defined in function and procedure entities. Set if a pragma @@ -2415,6 +2417,11 @@ package Einfo is -- Is_Incomplete_Type (synthesized) -- Applies to all entities, true for incomplete types and subtypes +-- Is_Independent (Flag268) +-- Defined in record components. Set if a valid pragma or aspect +-- Independent applies to the component, or if a valid pragma or aspect +-- Independent_Components applies to the enclosing record type. + -- Is_Inlined (Flag11) -- Defined in all entities. Set for functions and procedures which are -- to be inlined. For subprograms created during expansion, this flag @@ -2490,9 +2497,9 @@ package Einfo is -- Is_Itype (Flag91) -- Defined in all entities. Set to indicate that a type is an Itype, -- which means that the declaration for the type does not appear --- explicitly in the tree. Instead gigi will elaborate the type when it --- is first used. Has_Delayed_Freeze can be set for Itypes, and the --- meaning is that the first use (the one which causes the type to be +-- explicitly in the tree. Instead the backend will elaborate the type +-- when it is first used. Has_Delayed_Freeze can be set for Itypes, and +-- the meaning is that the first use (the one which causes the type to be -- defined) will be the freeze node. Note that an important restriction -- on Itypes is that the first use of such a type (the one that causes it -- to be defined) must be in the same scope as the type. @@ -2516,7 +2523,7 @@ package Einfo is -- The flag is dynamically set and reset as semantic analysis and -- expansion proceeds. Its value is meaningless once the tree is -- fully constructed, since it simply indicates the last state. --- Thus this flag has no meaning to the back end. +-- Thus this flag has no meaning to the backend. -- Is_Known_Null (Flag204) -- Defined in all entities. Relevant (and can be set ) only for @@ -2545,7 +2552,7 @@ package Einfo is -- -- For objects, the flag indicates the state of knowledge about the -- current value of the object. This may be modified during expansion, --- and thus the final value is not relevant to gigi. +-- and thus the final value is not relevant to the backend. -- -- For types and subtypes, the flag is set if all possible bit patterns -- of length Object_Size (i.e. Esize of the type) represent valid values @@ -2560,7 +2567,7 @@ package Einfo is -- The flag is dynamically set and reset as semantic analysis and -- expansion proceeds. Its value is meaningless once the tree is -- fully constructed, since it simply indicates the last state. --- Thus this flag has no meaning to the back end. +-- Thus this flag has no meaning to the backend. -- Is_Limited_Composite (Flag106) -- Defined in all entities. Set for composite types that have a limited @@ -2702,11 +2709,11 @@ package Einfo is -- used to implement a packed array (either a modular type, or a subtype -- of Packed_Bytes{1,2,4} as appropriate). The flag is set if and only -- if the type appears in the Packed_Array_Type field of some other type --- entity. It is used by Gigi to activate the special processing for such --- types (unchecked conversions that would not otherwise be allowed are --- allowed for such types). If the Is_Packed_Array_Type flag is set in --- an entity, then the Original_Array_Type field of this entity points --- to the original array type for which this is the packed array type. +-- entity. It is used by the backend to activate the special processing +-- for such types (unchecked conversions that would not otherwise be +-- allowed are allowed for such types). If the Is_Packed_Array_Type flag +-- is set in an entity, then the Original_Array_Type field of this entity +-- points to the array type for which this is the packed array type. -- Is_Potentially_Use_Visible (Flag9) -- Defined in all entities. Set if entity is potentially use visible, @@ -2790,8 +2797,8 @@ package Einfo is -- Defined in all entities. Set to indicate that an entity defined in -- one compilation unit can be referenced from other compilation units. -- If this reference causes a reference in the generated variable, for --- example in the case of a variable name, then Gigi will generate an --- appropriate external name for use by the linker. +-- example in the case of a variable name, then the backend will generate +-- an appropriate external name for use by the linker. -- Is_Protected_Record_Type (synthesized) -- Applies to all entities, true if Is_Concurrent_Record_Type is true and @@ -3004,7 +3011,7 @@ package Einfo is -- and full view. The flag is not set reliably on private subtypes, -- and is always retrieved from the base type (but this is not a base- -- type-only attribute because it applies to other entities). Note that --- the back end should use Treat_As_Volatile, rather than Is_Volatile +-- the backend should use Treat_As_Volatile, rather than Is_Volatile -- to indicate code generation requirements for volatile variables. -- Similarly, any front end test which is concerned with suppressing -- optimizations on volatile objects should test Treat_As_Volatile @@ -3151,7 +3158,7 @@ package Einfo is -- Defined in entities for types and subtypes. Set if objects of the type -- must always be allocated on a byte boundary (more accurately a storage -- unit boundary). The front end checks that component clauses respect --- this rule, and the back end ensures that record packing does not +-- this rule, and the backend ensures that record packing does not -- violate this rule. Currently the flag is set only for packed arrays -- longer than 64 bits where the component size is not a power of 2. @@ -3168,7 +3175,7 @@ package Einfo is -- Comes_From_Source set, and also transitively for entities associated -- with such components (e.g. their types). It is true for all entities -- in Debug_Generated_Code mode (-gnatD switch). This is the flag that --- the back end should check to determine whether or not to generate +-- the backend should check to determine whether or not to generate -- debugging information for an entity. Note that callers should always -- use Sem_Util.Set_Debug_Info_Needed, rather than Set_Needs_Debug_Info, -- so that the flag is set properly on subsidiary entities. @@ -3276,7 +3283,7 @@ package Einfo is -- Next_Inlined_Subprogram (Node12) -- Defined in subprograms. Used to chain inlined subprograms used in -- the current compilation, in the order in which they must be compiled --- by Gigi to insure that all inlinings are performed. +-- by the backend to insure that all inlinings are performed. -- Next_Literal (synthesized) -- Applies to enumeration literals, returns the next literal, or @@ -3332,10 +3339,10 @@ package Einfo is -- there are default discriminants, and also for the 'Size value). -- No_Strict_Aliasing (Flag136) [base type only] --- Defined in access types. Set to direct the back end to avoid any +-- Defined in access types. Set to direct the backend to avoid any -- optimizations based on an assumption about the aliasing status of -- objects designated by the access type. For the case of the gcc --- back end, the effect is as though all references to objects of +-- backend, the effect is as though all references to objects of -- the type were compiled with -fno-strict-aliasing. This flag is -- set if an unchecked conversion with the access type as a target -- type occurs in the same source unit as the declaration of the @@ -3365,7 +3372,7 @@ package Einfo is -- types, it is cheaper to do the copy. -- OK_To_Reorder_Components (Flag239) [base type only] --- Defined in record types. Set if the back end is permitted to reorder +-- Defined in record types. Set if the backend is permitted to reorder -- the components. If not set, the record must be layed out in the order -- in which the components are declared textually. Currently this flag -- can only be set by debug switches. @@ -3406,9 +3413,9 @@ package Einfo is -- In base tagged types: -- When the component is inherited in a record extension, it points -- to the original component (the entity of the ancestor component --- which is not itself inherited) otherwise it points to itself. --- Gigi uses this attribute to implement the automatic dereference in --- the extension and to apply the transformation: +-- which is not itself inherited) otherwise it points to itself. The +-- backend uses this attribute to implement the automatic dereference +-- in the extension and to apply the transformation: -- -- Rec_Ext.Comp -> Rec_Ext.Parent. ... .Parent.Comp -- @@ -3992,7 +3999,7 @@ package Einfo is -- be set as a result of situations (such as address overlays) where -- the front end wishes to force volatile handling to inhibit aliasing -- optimization which might be legally ok, but is undesirable. Note --- that the back end always tests this flag rather than Is_Volatile. +-- that the backend always tests this flag rather than Is_Volatile. -- The front end tests Is_Volatile if it is concerned with legality -- checks associated with declared volatile variables, but if the test -- is for the purposes of suppressing optimizations, then the front @@ -4022,7 +4029,7 @@ package Einfo is -- the full view of a private type T is derived from another private type -- with discriminants Td, the full view of T is also private, and there -- is no way to attach to it a further full view that would convey the --- structure of T to the back end. The Underlying_Full_ View is an +-- structure of T to the backend. The Underlying_Full_ View is an -- attribute of the full view that is a subtype of Td with the same -- constraint as the declaration for T. The declaration for this subtype -- is built at the point of the declaration of T, either as completion, @@ -4050,6 +4057,11 @@ package Einfo is -- types, is to legitimize code where Underlying_Type is applied to an -- entity which may or may not be a type, with the intent that if it is a -- type, its underlying type is taken. +-- +-- Note also that the value of this attribute is interesting only after +-- the full view of the parent type has been processed. If the parent +-- type is declared in an enclosing package, the attribute will be non- +-- trivial only after the full view of the type has been analyzed. -- Universal_Aliasing (Flag216) [implementation base type only] -- Defined in all type entities. Set to direct the back-end to avoid @@ -4215,7 +4227,7 @@ package Einfo is -- In addition, we define the kind E_Allocator_Type to label allocators. -- This is because special resolution rules apply to this construct. -- Eventually the constructs are labeled with the access type imposed by --- the context. Gigi should never see the type E_Allocator. +-- the context. The backend should never see types with this Ekind. -- Similarly, the type E_Access_Attribute_Type is used as the initial kind -- associated with an access attribute. After resolution a specific access @@ -4398,11 +4410,12 @@ package Einfo is -- 'Unrestricted_Access and Unchecked_Access) E_Allocator_Type, - -- A special internal type used to label allocators and attribute - -- references using 'Access. This is needed because special resolution + -- A special internal type used to label allocators and references to + -- objects using 'Reference. This is needed because special resolution -- rules apply to these constructs. On the resolution pass, this type - -- is always replaced by the actual access type, so Gigi should never - -- see types with this Ekind. + -- is almost always replaced by the actual access type, but if the + -- context does not provide one, the backend will see Allocator_Type + -- itself (which will already have been frozen). E_General_Access_Type, -- An access type created by an access type declaration with the all @@ -5350,6 +5363,7 @@ package Einfo is -- Has_Biased_Representation (Flag139) -- Has_Per_Object_Constraint (Flag154) -- Is_Atomic (Flag85) + -- Is_Independent (Flag268) -- Is_Tag (Flag78) -- Is_Volatile (Flag16) -- Treat_As_Volatile (Flag41) @@ -5379,7 +5393,6 @@ package Einfo is -- Has_Atomic_Components (Flag86) -- Has_Biased_Representation (Flag139) -- Has_Completion (Flag26) (constants only) - -- Has_Independent_Components (Flag34) (base type only) -- Has_Thunks (Flag228) (constants only) -- Has_Size_Clause (Flag29) -- Has_Up_Level_Access (Flag215) @@ -6089,7 +6102,6 @@ package Einfo is -- Has_Alignment_Clause (Flag46) -- Has_Atomic_Components (Flag86) -- Has_Biased_Representation (Flag139) - -- Has_Independent_Components (Flag34) (base type only) -- Has_Initial_Value (Flag219) -- Has_Size_Clause (Flag29) -- Has_Up_Level_Access (Flag215) @@ -6589,6 +6601,7 @@ package Einfo is function Is_Immediately_Visible (Id : E) return B; function Is_Implementation_Defined (Id : E) return B; function Is_Imported (Id : E) return B; + function Is_Independent (Id : E) return B; function Is_Inlined (Id : E) return B; function Is_Instantiated (Id : E) return B; function Is_Interface (Id : E) return B; @@ -7217,6 +7230,7 @@ package Einfo is procedure Set_Is_Immediately_Visible (Id : E; V : B := True); procedure Set_Is_Implementation_Defined (Id : E; V : B := True); procedure Set_Is_Imported (Id : E; V : B := True); + procedure Set_Is_Independent (Id : E; V : B := True); procedure Set_Is_Inlined (Id : E; V : B := True); procedure Set_Is_Instantiated (Id : E; V : B := True); procedure Set_Is_Interface (Id : E; V : B := True); @@ -7979,6 +7993,7 @@ package Einfo is pragma Inline (Is_Imported); pragma Inline (Is_Incomplete_Or_Private_Type); pragma Inline (Is_Incomplete_Type); + pragma Inline (Is_Independent); pragma Inline (Is_Inlined); pragma Inline (Is_Instantiated); pragma Inline (Is_Integer_Type); @@ -8426,6 +8441,7 @@ package Einfo is pragma Inline (Set_Is_Immediately_Visible); pragma Inline (Set_Is_Implementation_Defined); pragma Inline (Set_Is_Imported); + pragma Inline (Set_Is_Independent); pragma Inline (Set_Is_Inlined); pragma Inline (Set_Is_Instantiated); pragma Inline (Set_Is_Interface); diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb index 37a1b64d686..a2e9b45f1f3 100644 --- a/gcc/ada/errout.adb +++ b/gcc/ada/errout.adb @@ -197,6 +197,17 @@ package body Errout is -- spec for precise definition of the conversion that is performed by this -- routine in OpenVMS mode. + function Warn_Insertion return String; + -- This is called for warning messages only (so Warning_Msg_Char is set) + -- and returns a corresponding string to use at the beginning of generated + -- auxiliary messages, such as "in instantiation at ...". + -- 'a' .. 'z' returns "?x?" + -- 'A' .. 'Z' returns "?X?" + -- '*' returns "?*?" + -- '$' returns "?$?info: " + -- ' ' returns " " + -- No other settings are valid + ----------------------- -- Change_Error_Text -- ----------------------- @@ -238,6 +249,38 @@ package body Errout is end if; end Compilation_Errors; + -------------------------------------- + -- Delete_Warning_And_Continuations -- + -------------------------------------- + + procedure Delete_Warning_And_Continuations (Msg : Error_Msg_Id) is + Id : Error_Msg_Id; + + begin + pragma Assert (not Errors.Table (Msg).Msg_Cont); + + Id := Msg; + loop + declare + M : Error_Msg_Object renames Errors.Table (Id); + + begin + if not M.Deleted then + M.Deleted := True; + Warnings_Detected := Warnings_Detected - 1; + + if M.Warn_Err then + Warnings_Treated_As_Errors := Warnings_Treated_As_Errors + 1; + end if; + end if; + + Id := M.Next; + exit when Id = No_Error_Msg; + exit when not Errors.Table (Id).Msg_Cont; + end; + end loop; + end Delete_Warning_And_Continuations; + --------------- -- Error_Msg -- --------------- @@ -282,7 +325,7 @@ package body Errout is -- Start of processing for new message Sindex := Get_Source_File_Index (Flag_Location); - Test_Style_Warning_Serious_Unconditional_Msg (Msg); + Prescan_Message (Msg); Orig_Loc := Original_Location (Flag_Location); -- If the current location is in an instantiation, the issue arises of @@ -332,8 +375,7 @@ package body Errout is -- that style checks are not considered warning messages for this -- purpose. - if Is_Warning_Msg - and then Warnings_Suppressed (Orig_Loc) /= No_String + if Is_Warning_Msg and then Warnings_Suppressed (Orig_Loc) /= No_String then return; @@ -438,9 +480,9 @@ package body Errout is -- Case of inlined body if Inlined_Body (X) then - if Is_Warning_Msg or else Is_Style_Msg then + if Is_Warning_Msg or Is_Style_Msg then Error_Msg_Internal - ("?in inlined body #", + (Warn_Insertion & "in inlined body #", Actual_Error_Loc, Flag_Location, Msg_Cont_Status); else Error_Msg_Internal @@ -453,7 +495,7 @@ package body Errout is else if Is_Warning_Msg or else Is_Style_Msg then Error_Msg_Internal - ("?in instantiation #", + (Warn_Insertion & "in instantiation #", Actual_Error_Loc, Flag_Location, Msg_Cont_Status); else Error_Msg_Internal @@ -732,7 +774,6 @@ package body Errout is Continuation_New_Line := False; Suppress_Message := False; Kill_Message := False; - Warning_Msg_Char := ' '; Set_Msg_Text (Msg, Sptr); -- Kill continuation if parent message killed @@ -944,6 +985,7 @@ package body Errout is Line => Get_Physical_Line_Number (Sptr), Col => Get_Column_Number (Sptr), Warn => Is_Warning_Msg, + Info => Is_Info_Msg, Warn_Err => False, -- reset below Warn_Chr => Warning_Msg_Char, Style => Is_Style_Msg, @@ -1107,6 +1149,14 @@ package body Errout is end if; end if; + -- Record warning message issued + + if Errors.Table (Cur_Msg).Warn + and then not Errors.Table (Cur_Msg).Msg_Cont + then + Warning_Msg := Cur_Msg; + end if; + -- If too many warnings turn off warnings if Maximum_Messages /= 0 then @@ -1159,7 +1209,7 @@ package body Errout is return; end if; - Test_Style_Warning_Serious_Unconditional_Msg (Msg); + Prescan_Message (Msg); -- Special handling for warning messages @@ -1286,7 +1336,7 @@ package body Errout is F : Error_Msg_Id; procedure Delete_Warning (E : Error_Msg_Id); - -- Delete a message if not already deleted and adjust warning count + -- Delete a warning msg if not already deleted and adjust warning count -------------------- -- Delete_Warning -- @@ -1297,10 +1347,14 @@ package body Errout is if not Errors.Table (E).Deleted then Errors.Table (E).Deleted := True; Warnings_Detected := Warnings_Detected - 1; + + if Errors.Table (E).Warn_Err then + Warnings_Treated_As_Errors := Warnings_Treated_As_Errors + 1; + end if; end if; end Delete_Warning; - -- Start of message for Finalize + -- Start of processing for Finalize begin -- Set Prev pointers @@ -1350,11 +1404,12 @@ package body Errout is then Delete_Warning (Cur); - -- If this is a continuation, delete previous messages + -- If this is a continuation, delete previous parts of message F := Cur; while Errors.Table (F).Msg_Cont loop F := Errors.Table (F).Prev; + exit when F = No_Error_Msg; Delete_Warning (F); end loop; @@ -1841,8 +1896,14 @@ package body Errout is and then (No (Cunit_Entity (U)) - or else Comes_From_Source (Cunit_Entity (U)) - or else not Is_Subprogram (Cunit_Entity (U))) + or else Comes_From_Source (Cunit_Entity (U)) + or else not Is_Subprogram (Cunit_Entity (U))) + + -- If the compilation unit associated with this unit does not + -- come from source, it means it is an instantiation that should + -- not be included in the source listing. + + and then Comes_From_Source (Cunit (U)) then declare Sfile : constant Source_File_Index := Source_Index (U); @@ -2745,19 +2806,21 @@ package body Errout is C : Character; -- Current character P : Natural; -- Current index; - procedure Set_Msg_Insertion_Warning (C : Character); - -- Deal with ? ?? ?x? ?X? insertion sequences (also < << <x< <X<). The - -- caller has already bumped the pointer past the initial ? or < and C - -- is set to this initial character (? or <). + procedure Skip_Msg_Insertion_Warning (C : Character); + -- Deal with ? ?? ?x? ?X? ?*? ?$? insertion sequences (and the same + -- sequences using < instead of ?). The caller has already bumped + -- the pointer past the initial ? or < and C is set to this initial + -- character (? or <). This procedure skips past the rest of the + -- sequence. We do not need to set Msg_Insertion_Char, since this + -- was already done during the message prescan. - ------------------------------- - -- Set_Msg_Insertion_Warning -- - ------------------------------- + -------------------------------- + -- Skip_Msg_Insertion_Warning -- + -------------------------------- - procedure Set_Msg_Insertion_Warning (C : Character) is + procedure Skip_Msg_Insertion_Warning (C : Character) is begin if P <= Text'Last and then Text (P) = C then - Warning_Msg_Char := '?'; P := P + 1; elsif P + 1 <= Text'Last @@ -2765,15 +2828,14 @@ package body Errout is or else Text (P) in 'A' .. 'Z' or else - Text (P) = '*') + Text (P) = '*' + or else + Text (P) = '$') and then Text (P + 1) = C then - Warning_Msg_Char := Text (P); P := P + 2; - else - Warning_Msg_Char := ' '; end if; - end Set_Msg_Insertion_Warning; + end Skip_Msg_Insertion_Warning; -- Start of processing for Set_Msg_Text @@ -2782,7 +2844,21 @@ package body Errout is Msglen := 0; Flag_Source := Get_Source_File_Index (Flag); - P := Text'First; + -- Skip info: at start, we have recorded this in Is_Info_Msg, and this + -- will be used (Info field in error message object) to put back the + -- string when it is printed. We need to do this, or we get confused + -- with instantiation continuations. + + if Text'Length > 6 + and then Text (Text'First .. Text'First + 5) = "info: " + then + P := Text'First + 6; + else + P := Text'First; + end if; + + -- Loop through characters of message + while P <= Text'Last loop C := Text (P); P := P + 1; @@ -2846,16 +2922,10 @@ package body Errout is null; -- already dealt with when '?' => - Set_Msg_Insertion_Warning ('?'); + Skip_Msg_Insertion_Warning ('?'); when '<' => - - -- Note: the prescan already set Is_Warning_Msg True if and - -- only if Error_Msg_Warn is set to True. If Error_Msg_Warn - -- is False, the call to Set_Msg_Insertion_Warning here does - -- no harm, since Warning_Msg_Char is ignored in that case. - - Set_Msg_Insertion_Warning ('<'); + Skip_Msg_Insertion_Warning ('<'); when '|' => null; -- already dealt with @@ -3040,6 +3110,32 @@ package body Errout is return False; end Special_Msg_Delete; + ----------------- + -- SPARK_Msg_N -- + ----------------- + + procedure SPARK_Msg_N (Msg : String; N : Node_Or_Entity_Id) is + begin + if SPARK_Mode = On then + Error_Msg_N (Msg, N); + end if; + end SPARK_Msg_N; + + ------------------ + -- SPARK_Msg_NE -- + ------------------ + + procedure SPARK_Msg_NE + (Msg : String; + N : Node_Or_Entity_Id; + E : Node_Or_Entity_Id) + is + begin + if SPARK_Mode = On then + Error_Msg_NE (Msg, N, E); + end if; + end SPARK_Msg_NE; + -------------------------- -- Unwind_Internal_Type -- -------------------------- @@ -3233,4 +3329,22 @@ package body Errout is end loop; end VMS_Convert; + -------------------- + -- Warn_Insertion -- + -------------------- + + function Warn_Insertion return String is + begin + case Warning_Msg_Char is + when '?' => + return "??"; + when 'a' .. 'z' | 'A' .. 'Z' | '*' | '$' => + return '?' & Warning_Msg_Char & '?'; + when ' ' => + return "?"; + when others => + raise Program_Error; + end case; + end Warn_Insertion; + end Errout; diff --git a/gcc/ada/errout.ads b/gcc/ada/errout.ads index a42d3dba75c..303c21494eb 100644 --- a/gcc/ada/errout.ads +++ b/gcc/ada/errout.ads @@ -60,12 +60,13 @@ package Errout is -- Exception raised if Raise_Exception_On_Error is true Warning_Doc_Switch : Boolean renames Err_Vars.Warning_Doc_Switch; - -- If this is set True, then the ??/?*?/?x?/?X? sequences in error messages - -- generate appropriate tags for the output error messages. If this switch - -- is False, then these sequences are still recognized (for the purposes - -- of implementing pragmas Warnings (Off,..) and Warning_As_Pragma(...) but - -- do not result in adding the error message tag. The -gnatw.d switch sets - -- this flag True, -gnatw.D sets this flag False. + -- If this is set True, then the ??/?*?/?$?/?x?/?X? insertion sequences in + -- error messages generate appropriate tags for the output error messages. + -- If this switch is False, then these sequences are still recognized (for + -- the purposes of implementing the pattern matching in pragmas Warnings + -- (Off,..) and Warning_As_Pragma(...) but do not result in adding the + -- error message tag. The -gnatw.d switch sets this flag True, -gnatw.D + -- sets this flag False. ----------------------------------- -- Suppression of Error Messages -- @@ -281,9 +282,10 @@ package Errout is -- status of continuations is determined only by the parent message -- which is being continued. It is allowable to put ? in continuation -- messages, and the usual style is to include it, since it makes it - -- clear that the continuation is part of a warning message. + -- clear that the continuation is part of a warning message, but it is + -- not necessary to go through any computational effort to include it. -- - -- Note: this usage is obsolete, use ?? ?*? ?x? ?X? instead to specify + -- Note: this usage is obsolete, use ?? ?*? ?$? ?x? ?X? to specify -- the string to be added when Warn_Doc_Switch is set to True. If this -- switch is True, then for simple ? messages it has no effect. This -- simple form is to ease transition and will be removed later. @@ -309,11 +311,17 @@ package Errout is -- "[restriction warning]" at the end of the warning message. For -- continuations, use this on each continuation message. + -- Insertion character ?$? (elaboration information messages) + -- Like ?, but if the flag Warn_Doc_Switch is True, adds the string + -- "[-gnatel]" at the end of the info message. This is used for the + -- messages generated by the switch -gnatel. For continuations, use + -- this on each continuation message. + -- Insertion character < (Less Than: conditional warning message) -- The character < appearing anywhere in a message is used for a -- conditional error message. If Error_Msg_Warn is True, then the - -- effect is the same as ? described above, and in particular << - -- <X< and <*< have the effect of ?? ?X? and ?*? respectively. If + -- effect is the same as ? described above, and in particular << <X< + -- <x< <$< <*< have the effect of ?? ?X? ?x? ?$? ?*? respectively. If -- Error_Msg_Warn is False, then the < << or <X< sequence is ignored -- and the message is treated as a error rather than a warning. @@ -392,6 +400,19 @@ package Errout is -- This is like [ except that the insertion messages say may/might, -- instead of will/would. + -- Insertion sequence "(style)" (style message) + -- This appears only at the start of the message (and not any of its + -- continuations, if any), and indicates that the message is a style + -- message. Style messages are also considered to be warnings, but + -- they do not get a tag. + + -- Insertion sequence "info: " (information message) + -- This appears only at the start of the message (and not any of its + -- continuations, if any), and indicates that the message is an info + -- message. The message will be output with this prefix, and if there + -- are continuations that are not printed using the -gnatj switch they + -- will also have this prefix. + ---------------------------------------- -- Specialization of Messages for VMS -- ---------------------------------------- @@ -594,6 +615,16 @@ package Errout is -- A constant which is different from any value returned by Get_Error_Id. -- Typically used by a client to indicate absense of a saved Id value. + Warning_Msg : Error_Msg_Id := No_Error_Msg; + -- This is set if a warning message is generated to the ID of the resulting + -- message. Continuation messages have no effect. It is legitimate for the + -- client to set this to No_Error_Msg and then test it to see if a warning + -- message has been issued. + + procedure Delete_Warning_And_Continuations (Msg : Error_Msg_Id); + -- Deletes the given warning message and all its continuations. This is + -- typically used in conjunction with reading the value of Warning_Msg. + function Get_Msg_Id return Error_Msg_Id renames Erroutc.Get_Msg_Id; -- Returns the Id of the message most recently posted using one of the -- Error_Msg routines. @@ -888,6 +919,29 @@ package Errout is -- Debugging routine to dump an error message ------------------------------------ + -- SPARK Error Output Subprograms -- + ------------------------------------ + + -- The following routines are intended to report semantic errors in SPARK + -- constructs subject to aspect/pragma SPARK_Mode. Note that syntax errors + -- must be reported using the Error_Msg_XXX routines. This allows for the + -- partial analysis of SPARK features when they are disabled via SPARK_Mode + -- set to "off". + + procedure SPARK_Msg_N (Msg : String; N : Node_Or_Entity_Id); + pragma Inline (SPARK_Msg_N); + -- Same as Error_Msg_N, but the error is reported only when SPARK_Mode is + -- "on". The routine is inlined because it acts as a simple wrapper. + + procedure SPARK_Msg_NE + (Msg : String; + N : Node_Or_Entity_Id; + E : Node_Or_Entity_Id); + pragma Inline (SPARK_Msg_NE); + -- Same as Error_Msg_NE, but the error is reported only when SPARK_Mode is + -- "on". The routine is inlined because it acts as a simple wrapper. + + ------------------------------------ -- Utility Interface for Back End -- ------------------------------------ diff --git a/gcc/ada/erroutc.adb b/gcc/ada/erroutc.adb index 4a107d1df10..66ab8f18452 100644 --- a/gcc/ada/erroutc.adb +++ b/gcc/ada/erroutc.adb @@ -140,6 +140,11 @@ package body Erroutc is if Errors.Table (D).Warn or else Errors.Table (D).Style then Warnings_Detected := Warnings_Detected - 1; + if Errors.Table (D).Warn_Err then + Warnings_Treated_As_Errors := + Warnings_Treated_As_Errors + 1; + end if; + else Total_Errors_Detected := Total_Errors_Detected - 1; @@ -257,6 +262,7 @@ package body Erroutc is w ("Dumping error message, Id = ", Int (Id)); w (" Text = ", E.Text.all); w (" Next = ", Int (E.Next)); + w (" Prev = ", Int (E.Prev)); w (" Sfile = ", Int (E.Sfile)); Write_Str @@ -272,6 +278,8 @@ package body Erroutc is w (" Line = ", Int (E.Line)); w (" Col = ", Int (E.Col)); w (" Warn = ", E.Warn); + w (" Warn_Err = ", E.Warn_Err); + w (" Warn_Chr = '" & E.Warn_Chr & '''); w (" Style = ", E.Style); w (" Serious = ", E.Serious); w (" Uncond = ", E.Uncond); @@ -312,6 +320,8 @@ package body Erroutc is return "[enabled by default]"; elsif Warn_Chr = '*' then return "[restriction warning]"; + elsif Warn_Chr = '$' then + return "[-gnatel]"; elsif Warn_Chr in 'a' .. 'z' then return "[-gnatw" & Warn_Chr & ']'; else pragma Assert (Warn_Chr in 'A' .. 'Z'); @@ -574,24 +584,22 @@ package body Erroutc is if Errors.Table (E).Warn then - -- Nothing to do with info messages, "info " already set + -- For info messages, prefix message with "info: " - if Txt'Length >= 6 - and then Txt (Txt'First .. Txt'First + 5) = "info: " - then - null; + if Errors.Table (E).Info then + Txt := new String'("info: " & Txt.all); -- Warning treated as error elsif Errors.Table (E).Warn_Err then - -- We prefix the tag error: rather than warning: and postfix + -- We prefix with "error:" rather than warning: and postfix -- [warning-as-error] at the end. Warnings_Treated_As_Errors := Warnings_Treated_As_Errors + 1; Txt := new String'("error: " & Txt.all & " [warning-as-error]"); - -- Normal case, prefix + -- Normal case, prefix with "warning: " else Txt := new String'("warning: " & Txt.all); @@ -683,6 +691,110 @@ package body Erroutc is end; end Output_Msg_Text; + --------------------- + -- Prescan_Message -- + --------------------- + + procedure Prescan_Message (Msg : String) is + J : Natural; + + begin + -- Nothing to do for continuation line + + if Msg (Msg'First) = '\' then + return; + end if; + + -- Set initial values of globals (may be changed during scan) + + Is_Serious_Error := True; + Is_Unconditional_Msg := False; + Is_Warning_Msg := False; + Has_Double_Exclam := False; + + -- Check style message + + Is_Style_Msg := + Msg'Length > 7 and then Msg (Msg'First .. Msg'First + 6) = "(style)"; + + -- Check info message + + Is_Info_Msg := + Msg'Length > 6 and then Msg (Msg'First .. Msg'First + 5) = "info: "; + + -- Loop through message looking for relevant insertion sequences + + J := Msg'First; + while J <= Msg'Last loop + + -- If we have a quote, don't look at following character + + if Msg (J) = ''' then + J := J + 2; + + -- Warning message (? or < insertion sequence) + + elsif Msg (J) = '?' or else Msg (J) = '<' then + Is_Warning_Msg := Msg (J) = '?' or else Error_Msg_Warn; + Warning_Msg_Char := ' '; + J := J + 1; + + if Is_Warning_Msg then + declare + C : constant Character := Msg (J - 1); + begin + if J <= Msg'Last then + if Msg (J) = C then + Warning_Msg_Char := '?'; + J := J + 1; + + elsif J < Msg'Last and then Msg (J + 1) = C + and then (Msg (J) in 'a' .. 'z' or else + Msg (J) in 'A' .. 'Z' or else + Msg (J) = '*' or else + Msg (J) = '$') + then + Warning_Msg_Char := Msg (J); + J := J + 2; + end if; + end if; + end; + end if; + + -- Bomb if untagged warning message. This code can be uncommented + -- for debugging when looking for untagged warning messages. + + -- if Is_Warning_Msg and then Warning_Msg_Char = ' ' then + -- raise Program_Error; + -- end if; + + -- Unconditional message (! insertion) + + elsif Msg (J) = '!' then + Is_Unconditional_Msg := True; + J := J + 1; + + if J <= Msg'Last and then Msg (J) = '!' then + Has_Double_Exclam := True; + J := J + 1; + end if; + + -- Non-serious error (| insertion) + + elsif Msg (J) = '|' then + Is_Serious_Error := False; + J := J + 1; + + else + J := J + 1; + end if; + end loop; + + if Is_Warning_Msg or Is_Style_Msg then + Is_Serious_Error := False; + end if; + end Prescan_Message; + -------------------- -- Purge_Messages -- -------------------- @@ -1251,6 +1363,7 @@ package body Erroutc is for J in 1 .. Specific_Warnings.Last loop declare SWE : Specific_Warning_Entry renames Specific_Warnings.Table (J); + begin if Msg = SWE.Msg.all and then Loc > SWE.Start @@ -1352,63 +1465,6 @@ package body Erroutc is end if; end Set_Warnings_Mode_On; - ------------------------------------ - -- Test_Style_Warning_Serious_Msg -- - ------------------------------------ - - procedure Test_Style_Warning_Serious_Unconditional_Msg (Msg : String) is - begin - -- Nothing to do for continuation line - - if Msg (Msg'First) = '\' then - return; - end if; - - -- Set initial values of globals (may be changed during scan) - - Is_Serious_Error := True; - Is_Unconditional_Msg := False; - Is_Warning_Msg := False; - Has_Double_Exclam := False; - - Is_Style_Msg := - (Msg'Length > 7 and then Msg (Msg'First .. Msg'First + 6) = "(style)"); - - for J in Msg'Range loop - if Msg (J) = '?' - and then (J = Msg'First or else Msg (J - 1) /= ''') - then - Is_Warning_Msg := True; - Warning_Msg_Char := ' '; - - elsif Msg (J) = '!' - and then (J = Msg'First or else Msg (J - 1) /= ''') - then - Is_Unconditional_Msg := True; - Warning_Msg_Char := ' '; - - if J < Msg'Last and then Msg (J + 1) = '!' then - Has_Double_Exclam := True; - end if; - - elsif Msg (J) = '<' - and then (J = Msg'First or else Msg (J - 1) /= ''') - then - Is_Warning_Msg := Error_Msg_Warn; - Warning_Msg_Char := ' '; - - elsif Msg (J) = '|' - and then (J = Msg'First or else Msg (J - 1) /= ''') - then - Is_Serious_Error := False; - end if; - end loop; - - if Is_Warning_Msg or Is_Style_Msg then - Is_Serious_Error := False; - end if; - end Test_Style_Warning_Serious_Unconditional_Msg; - -------------------------------- -- Validate_Specific_Warnings -- -------------------------------- diff --git a/gcc/ada/erroutc.ads b/gcc/ada/erroutc.ads index c638aac1b1e..f23f4df588f 100644 --- a/gcc/ada/erroutc.ads +++ b/gcc/ada/erroutc.ads @@ -60,15 +60,24 @@ package Erroutc is -- character ! and is thus to be treated as an unconditional message. Is_Warning_Msg : Boolean := False; - -- Set True to indicate if current message is warning message (contains ?) + -- Set True to indicate if current message is warning message (contains ? + -- or contains < and Error_Msg_Warn is True. + + Is_Info_Msg : Boolean := False; + -- Set True to indicate that the current message starts with the characters + -- "info: " and is to be treated as an information message. This string + -- will be prepended to the message and all its continuations. Warning_Msg_Char : Character; -- Warning character, valid only if Is_Warning_Msg is True - -- ' ' -- ? appeared on its own in message - -- '?' -- ?? appeared in message - -- 'x' -- ?x? appeared in message (x = a .. z) - -- 'X' -- ?X? appeared in message (X = A .. Z) - -- '*' -- ?*? appeared in message + -- ' ' -- ? or < appeared on its own in message + -- '?' -- ?? or << appeared in message + -- 'x' -- ?x? or <x< appeared in message (x = a .. z) + -- 'X' -- ?X? or <X< appeared in message (X = A .. Z) + -- '*' -- ?*? or <*< appeared in message + -- '$' -- ?$? or <$< appeared in message + -- In the case of the < sequences, this is set only if the message is + -- actually a warning, i.e. if Error_Msg_Warn is True Is_Style_Msg : Boolean := False; -- Set True to indicate if the current message is a style message @@ -194,7 +203,10 @@ package Erroutc is -- Column number for error message Warn : Boolean; - -- True if warning message (i.e. insertion character ? appeared) + -- True if warning message + + Info : Boolean; + -- True if info message Warn_Err : Boolean; -- True if this is a warning message which is to be treated as an error @@ -202,11 +214,14 @@ package Erroutc is Warn_Chr : Character; -- Warning character (note: set even if Warning_Doc_Switch is False) - -- ' ' -- ? appeared on its own in message - -- '?' -- ?? appeared in message - -- 'x' -- ?x? appeared in message (x = a .. z) - -- 'X' -- ?X? appeared in message (X = A .. Z) - -- '*' -- ?*? appeared in message + -- ' ' -- ? or < appeared on its own in message + -- '?' -- ?? or << appeared in message + -- 'x' -- ?x? or <x< appeared in message (x = a .. z) + -- 'X' -- ?X? or <X< appeared in message (X = A .. Z) + -- '*' -- ?*? or <*< appeared in message + -- '$' -- ?$? or <$< appeared in message + -- In the case of the < sequences, this is set only if the message is + -- actually a warning, i.e. if Error_Msg_Warn is True Style : Boolean; -- True if style message (starts with "(style)") @@ -404,6 +419,34 @@ package Erroutc is -- splits the line generating multiple lines of output, and in this case -- the last line has no terminating end of line character. + procedure Prescan_Message (Msg : String); + -- Scans message text and sets the following variables: + -- + -- Is_Warning_Msg is set True if Msg is a warning message (contains a + -- question mark character), and False otherwise. + -- + -- Is_Style_Msg is set True if Msg is a style message (starts with + -- "(style)") and False otherwise. + -- + -- Is_Info_Msg is set True if Msg is an information message (starts + -- with "info: ". Such messages must contain a ? sequence since they + -- are also considered to be warning messages, and get a tag. + -- + -- Is_Serious_Error is set to True unless the message is a warning or + -- style message or contains the character | (non-serious error). + -- + -- Is_Unconditional_Msg is set True if the message contains the character + -- ! and is otherwise set False. + -- + -- Has_Double_Exclam is set True if the message contains the sequence !! + -- and is otherwise set False. + -- + -- We need to know right away these aspects of a message, since we will + -- test these values before doing the full error scan. + -- + -- Note that the call has no effect for continuation messages (those whose + -- first character is '\'), and all variables are left unchanged. + procedure Purge_Messages (From : Source_Ptr; To : Source_Ptr); -- All error messages whose location is in the range From .. To (not -- including the end points) will be deleted from the error listing. @@ -523,27 +566,6 @@ package Erroutc is -- Called in response to a pragma Warnings (On) to record the source -- location from which warnings are to be turned back on. - procedure Test_Style_Warning_Serious_Unconditional_Msg (Msg : String); - -- Scans message text and sets the following variables: - -- - -- Is_Warning_Msg is set True if Msg is a warning message (contains a - -- question mark character), and False otherwise. - -- - -- Is_Style_Msg is set True if Msg is a style message (starts with - -- "(style)") and False otherwise. - -- - -- Is_Serious_Error is set to True unless the message is a warning or - -- style message or contains the character | (non-serious error). - -- - -- Is_Unconditional_Msg is set True if the message contains the character - -- ! and is otherwise set False. - -- - -- Has_Double_Exclam is set True if the message contains the sequence !! - -- and is otherwise set False. - -- - -- Note that the call has no effect for continuation messages (those whose - -- first character is '\'), and all variables are left unchanged. - function Warnings_Suppressed (Loc : Source_Ptr) return String_Id; -- Determines if given location is covered by a warnings off suppression -- range in the warnings table (or is suppressed by compilation option, diff --git a/gcc/ada/errutil.adb b/gcc/ada/errutil.adb index 0d4af6c49c8..f15eec9a7b1 100644 --- a/gcc/ada/errutil.adb +++ b/gcc/ada/errutil.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1991-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1991-2014, 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- -- @@ -177,7 +177,7 @@ package body Errutil is raise Error_Msg_Exception; end if; - Test_Style_Warning_Serious_Unconditional_Msg (Msg); + Prescan_Message (Msg); Set_Msg_Text (Msg, Sptr); -- Kill continuation if parent message killed @@ -212,6 +212,7 @@ package body Errutil is Errors.Table (Cur_Msg).Col := Get_Column_Number (Sptr); Errors.Table (Cur_Msg).Style := Is_Style_Msg; Errors.Table (Cur_Msg).Warn := Is_Warning_Msg; + Errors.Table (Cur_Msg).Info := Is_Info_Msg; Errors.Table (Cur_Msg).Warn_Chr := Warning_Msg_Char; Errors.Table (Cur_Msg).Serious := Is_Serious_Error; Errors.Table (Cur_Msg).Uncond := Is_Unconditional_Msg; diff --git a/gcc/ada/eval_fat.adb b/gcc/ada/eval_fat.adb index bb729f9e0b9..7217048c54e 100644 --- a/gcc/ada/eval_fat.adb +++ b/gcc/ada/eval_fat.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -508,12 +508,12 @@ package body Eval_Fat is if X_Exp < Emin_Den or not Has_Denormals (RT) then if Has_Signed_Zeros (RT) and then UR_Is_Negative (X) then Error_Msg_N - ("floating-point value underflows to -0.0?", Enode); + ("floating-point value underflows to -0.0??", Enode); return Ureal_M_0; else Error_Msg_N - ("floating-point value underflows to 0.0?", Enode); + ("floating-point value underflows to 0.0??", Enode); return Ureal_0; end if; @@ -545,7 +545,7 @@ package body Eval_Fat is begin if X_Frac_Denorm /= X_Frac then Error_Msg_N - ("gradual underflow causes loss of precision?", + ("gradual underflow causes loss of precision??", Enode); X_Frac := X_Frac_Denorm; end if; diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb index 4b4ede7b820..80e2bf44708 100644 --- a/gcc/ada/exp_attr.adb +++ b/gcc/ada/exp_attr.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -3962,13 +3962,6 @@ package body Exp_Attr is Temp : Entity_Id; begin - -- If assertions are disabled, no need to create the declaration - -- that preserves the value. - - if not Assertions_Enabled then - return; - end if; - Temp := Make_Temporary (Loc, 'T', Pref); -- Climb the parent chain looking for subprogram _Postconditions @@ -3978,6 +3971,15 @@ package body Exp_Attr is exit when Nkind (Subp) = N_Subprogram_Body and then Chars (Defining_Entity (Subp)) = Name_uPostconditions; + -- If assertions are disabled, no need to create the declaration + -- that preserves the value. The postcondition pragma in which + -- 'Old appears will be checked or disabled according to the + -- current policy in effect. + + if Nkind (Subp) = N_Pragma and then not Is_Checked (Subp) then + return; + end if; + Subp := Parent (Subp); end loop; @@ -4179,10 +4181,9 @@ package body Exp_Attr is Analyze (N); return; - -- For elementary types, we call the W_xxx routine directly. - -- Note that the effect of Write and Output is identical for - -- the case of an elementary type, since there are no - -- discriminants or bounds. + -- For elementary types, we call the W_xxx routine directly. Note + -- that the effect of Write and Output is identical for the case + -- of an elementary type (there are no discriminants or bounds). elsif Is_Elementary_Type (U_Type) then @@ -4439,7 +4440,8 @@ package body Exp_Attr is ---------- -- 1. Deal with enumeration types with holes - -- 2. For floating-point, generate call to attribute function + -- 2. For floating-point, generate call to attribute function and deal + -- with range checking if Check_Float_Overflow mode is set. -- 3. For other cases, deal with constraint checking when Attribute_Pred => Pred : @@ -4511,9 +4513,36 @@ package body Exp_Attr is Analyze_And_Resolve (N, Typ); -- For floating-point, we transform 'Pred into a call to the Pred - -- floating-point attribute function in Fat_xxx (xxx is root type) + -- floating-point attribute function in Fat_xxx (xxx is root type). elsif Is_Floating_Point_Type (Ptyp) then + + -- Handle case of range check. The Do_Range_Check flag is set only + -- in Check_Float_Overflow mode, and what we need is a specific + -- check against typ'First, since that is the only overflow case. + + declare + Expr : constant Node_Id := First (Exprs); + begin + if Do_Range_Check (Expr) then + Set_Do_Range_Check (Expr, False); + Insert_Action (N, + Make_Raise_Constraint_Error (Loc, + Condition => + Make_Op_Eq (Loc, + Left_Opnd => Duplicate_Subexpr (Expr), + Right_Opnd => + Make_Attribute_Reference (Loc, + Attribute_Name => Name_First, + Prefix => + New_Occurrence_Of (Base_Type (Ptyp), Loc))), + Reason => CE_Overflow_Check_Failed), + Suppress => All_Checks); + end if; + end; + + -- Transform into call to attribute function + Expand_Fpt_Attribute_R (N); Analyze_And_Resolve (N, Typ); @@ -5562,6 +5591,33 @@ package body Exp_Attr is -- floating-point attribute function in Fat_xxx (xxx is root type) elsif Is_Floating_Point_Type (Ptyp) then + + -- Handle case of range check. The Do_Range_Check flag is set only + -- in Check_Float_Overflow mode, and what we need is a specific + -- check against typ'Last, since that is the only overflow case. + + declare + Expr : constant Node_Id := First (Exprs); + begin + if Do_Range_Check (Expr) then + Set_Do_Range_Check (Expr, False); + Insert_Action (N, + Make_Raise_Constraint_Error (Loc, + Condition => + Make_Op_Eq (Loc, + Left_Opnd => Duplicate_Subexpr (Expr), + Right_Opnd => + Make_Attribute_Reference (Loc, + Attribute_Name => Name_Last, + Prefix => + New_Occurrence_Of (Base_Type (Ptyp), Loc))), + Reason => CE_Overflow_Check_Failed), + Suppress => All_Checks); + end if; + end; + + -- Transform into call to attribute function + Expand_Fpt_Attribute_R (N); Analyze_And_Resolve (N, Typ); diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb index 6934363a565..a96f7f4534b 100644 --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -3484,6 +3484,18 @@ package body Exp_Ch3 is Rec_Type := Underlying_Type (Rec_Type); end if; + -- If we have a variant record with restriction No_Implicit_Conditionals + -- in effect, then we skip building the procedure. This is safe because + -- if we can see the restriction, so can any caller, calls to initialize + -- such records are not allowed for variant records if this restriction + -- is active. + + if Has_Variant_Part (Rec_Type) + and then Restriction_Active (No_Implicit_Conditionals) + then + return; + end if; + -- If there are discriminants, build the discriminant map to replace -- discriminants by their discriminals in complex bound expressions. -- These only arise for the corresponding records of synchronized types. @@ -4316,6 +4328,16 @@ package body Exp_Ch3 is Pspecs : constant List_Id := New_List; begin + -- If we have a variant record with restriction No_Implicit_Conditionals + -- in effect, then we skip building the procedure. This is safe because + -- if we can see the restriction, so can any caller, calls to equality + -- test routines are not allowed for variant records if this restriction + -- is active. + + if Restriction_Active (No_Implicit_Conditionals) then + return; + end if; + -- Derived Unchecked_Union types no longer inherit the equality function -- of their parent. @@ -4431,11 +4453,8 @@ package body Exp_Ch3 is else Append_To (Stmts, - Make_Eq_If (Typ, - Discriminant_Specifications (Def))); - - Append_List_To (Stmts, - Make_Eq_Case (Typ, Comps)); + Make_Eq_If (Typ, Discriminant_Specifications (Def))); + Append_List_To (Stmts, Make_Eq_Case (Typ, Comps)); end if; Append_To (Stmts, @@ -4838,6 +4857,7 @@ package body Exp_Ch3 is Def_Id : constant Entity_Id := Defining_Identifier (N); Expr : constant Node_Id := Expression (N); Loc : constant Source_Ptr := Sloc (N); + Obj_Def : constant Node_Id := Object_Definition (N); Typ : constant Entity_Id := Etype (Def_Id); Base_Typ : constant Entity_Id := Base_Type (Typ); Expr_Q : Node_Id; @@ -4999,7 +5019,7 @@ package body Exp_Ch3 is and then Is_Entity_Name (Expr_Q) and then Ekind (Entity (Expr_Q)) = E_Variable and then OK_To_Rename (Entity (Expr_Q)) - and then Is_Entity_Name (Object_Definition (N)); + and then Is_Entity_Name (Obj_Def); end Rewrite_As_Renaming; -- Start of processing for Expand_N_Object_Declaration @@ -5065,6 +5085,26 @@ package body Exp_Ch3 is if No (Expr) then + -- If we have a type with a variant part, the initialization proc + -- will contain implicit tests of the discriminant values, which + -- counts as a violation of the restriction No_Implicit_Conditionals. + + if Has_Variant_Part (Typ) then + declare + Msg : Boolean; + + begin + Check_Restriction (Msg, No_Implicit_Conditionals, Obj_Def); + + if Msg then + Error_Msg_N + ("\initialization of variant record tests discriminants", + Obj_Def); + return; + end if; + end; + end if; + -- For the default initialization case, if we have a private type -- with invariants, and invariant checks are enabled, then insert an -- invariant check after the object declaration. Note that it is OK @@ -5305,9 +5345,9 @@ package body Exp_Ch3 is -- then we've done it already and must not do it again. and then not - (Nkind (Object_Definition (N)) = N_Identifier + (Nkind (Obj_Def) = N_Identifier and then - Present (Equivalent_Type (Entity (Object_Definition (N))))) + Present (Equivalent_Type (Entity (Obj_Def)))) then pragma Assert (Is_Class_Wide_Type (Typ)); @@ -5416,7 +5456,7 @@ package body Exp_Ch3 is Expand_Subtype_From_Expr (N => N, Unc_Type => Typ, - Subtype_Indic => Object_Definition (N), + Subtype_Indic => Obj_Def, Exp => Expr_N); if not Is_Interface (Etype (Expr_N)) then @@ -5427,7 +5467,7 @@ package body Exp_Ch3 is else New_Expr := - Unchecked_Convert_To (Etype (Object_Definition (N)), + Unchecked_Convert_To (Etype (Obj_Def), Make_Explicit_Dereference (Loc, Unchecked_Convert_To (RTE (RE_Tag_Ptr), Make_Attribute_Reference (Loc, @@ -5442,8 +5482,7 @@ package body Exp_Ch3 is Make_Object_Declaration (Loc, Defining_Identifier => Obj_Id, Object_Definition => - New_Occurrence_Of - (Etype (Object_Definition (N)), Loc), + New_Occurrence_Of (Etype (Obj_Def), Loc), Expression => New_Expr)); -- Rename limited type object since they cannot be copied @@ -5455,11 +5494,10 @@ package body Exp_Ch3 is Make_Object_Renaming_Declaration (Loc, Defining_Identifier => Obj_Id, Subtype_Mark => - New_Occurrence_Of - (Etype (Object_Definition (N)), Loc), + New_Occurrence_Of (Etype (Obj_Def), Loc), Name => Unchecked_Convert_To - (Etype (Object_Definition (N)), New_Expr))); + (Etype (Obj_Def), New_Expr))); end if; -- Dynamically reference the tag associated with the @@ -5744,7 +5782,7 @@ package body Exp_Ch3 is Rewrite (N, Make_Object_Renaming_Declaration (Loc, Defining_Identifier => Defining_Identifier (N), - Subtype_Mark => Object_Definition (N), + Subtype_Mark => Obj_Def, Name => Expr_Q)); -- We do not analyze this renaming declaration, because all its @@ -5778,7 +5816,7 @@ package body Exp_Ch3 is end if; if Nkind (N) = N_Object_Declaration - and then Nkind (Object_Definition (N)) = N_Access_Definition + and then Nkind (Obj_Def) = N_Access_Definition and then not Is_Local_Anonymous_Access (Etype (Def_Id)) then -- An Ada 2012 stand-alone object of an anonymous access type @@ -5810,12 +5848,14 @@ package body Exp_Ch3 is Level_Expr := Dynamic_Accessibility_Level (Expr); end if; - Level_Decl := Make_Object_Declaration (Loc, - Defining_Identifier => Level, - Object_Definition => New_Occurrence_Of (Standard_Natural, Loc), - Expression => Level_Expr, - Constant_Present => Constant_Present (N), - Has_Init_Expression => True); + Level_Decl := + Make_Object_Declaration (Loc, + Defining_Identifier => Level, + Object_Definition => + New_Occurrence_Of (Standard_Natural, Loc), + Expression => Level_Expr, + Constant_Present => Constant_Present (N), + Has_Init_Expression => True); Insert_Action_After (Init_After, Level_Decl); @@ -8641,6 +8681,7 @@ package body Exp_Ch3 is if Chars (Discr) = External_Name (Node (Elm)) then return Node (Elm); end if; + Next_Elmt (Elm); end loop; @@ -8676,14 +8717,12 @@ package body Exp_Ch3 is end if; Alt_List := New_List; - while Present (Variant) loop Append_To (Alt_List, Make_Case_Statement_Alternative (Loc, Discrete_Choices => New_Copy_List (Discrete_Choices (Variant)), Statements => Make_Eq_Case (E, Component_List (Variant), Discrs))); - Next_Non_Pragma (Variant); end loop; @@ -8785,7 +8824,7 @@ package body Exp_Ch3 is else return Make_Implicit_If_Statement (E, - Condition => Cond, + Condition => Cond, Then_Statements => New_List ( Make_Simple_Return_Statement (Loc, Expression => New_Occurrence_Of (Standard_False, Loc)))); @@ -8793,9 +8832,9 @@ package body Exp_Ch3 is end if; end Make_Eq_If; - -------------------- - -- Make_Neq_Body -- - -------------------- + ------------------- + -- Make_Neq_Body -- + ------------------- function Make_Neq_Body (Tag_Typ : Entity_Id) return Node_Id is diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index a3213aaeae5..5b9eb86c2cb 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -6674,6 +6674,8 @@ package body Exp_Ch4 is R_Exp : Node_Id := Relocate_Node (Rhs); begin + -- Adjust operands if necessary to comparison type + if Base_Type (Op_Type) /= Base_Type (A_Typ) and then not Is_Class_Wide_Type (A_Typ) then @@ -6771,8 +6773,7 @@ package body Exp_Ch4 is -- formal is that of the discriminant, with added suffix, -- see Exp_Ch3.Build_Record_Equality for details. - if Is_Unchecked_Union - (Scope (Entity (Selector_Name (Lhs)))) + if Is_Unchecked_Union (Scope (Entity (Selector_Name (Lhs)))) then Discr := First_Discriminant @@ -7074,6 +7075,25 @@ package body Exp_Ch4 is Typl := Base_Type (Typl); + -- Equality between variant records results in a call to a routine + -- that has conditional tests of the discriminant value(s), and hence + -- violates the No_Implicit_Conditionals restriction. + + if Has_Variant_Part (Typl) then + declare + Msg : Boolean; + + begin + Check_Restriction (Msg, No_Implicit_Conditionals, N); + + if Msg then + Error_Msg_N + ("\comparison of variant records tests discriminants", N); + return; + end if; + end; + end if; + -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that -- means we no longer have a comparison operation, we are all done. @@ -7573,7 +7593,7 @@ package body Exp_Ch4 is Make_Function_Call (Loc, Name => New_Occurrence_Of (RTE (RE_Exp_Modular), Loc), Parameter_Associations => New_List ( - Convert_To (Standard_Integer, Base), + Convert_To (RTE (RE_Unsigned), Base), Make_Integer_Literal (Loc, Modulus (Rtyp)), Exp)))); @@ -12539,7 +12559,7 @@ package body Exp_Ch4 is -- hook pointer is null. procedure Find_Enclosing_Contexts (N : Node_Id); - -- Find the logical context where N appears, and initializae + -- Find the logical context where N appears, and initialize -- Hook_Context and Finalization_Context accordingly. Also -- sets Finalize_Always. diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb index 0103cfac95b..e1a4d0f49a5 100644 --- a/gcc/ada/exp_ch9.adb +++ b/gcc/ada/exp_ch9.adb @@ -291,10 +291,10 @@ package body Exp_Ch9 is (N : Node_Id; Pid : Node_Id) return Node_Id; -- This routine constructs the unprotected version of a protected - -- subprogram body, which is contains all of the code in the - -- original, unexpanded body. This is the version of the protected - -- subprogram that is called from all protected operations on the same - -- object, including the protected version of the same subprogram. + -- subprogram body, which is contains all of the code in the original, + -- unexpanded body. This is the version of the protected subprogram that is + -- called from all protected operations on the same object, including the + -- protected version of the same subprogram. procedure Build_Wrapper_Bodies (Loc : Source_Ptr; @@ -532,7 +532,7 @@ package body Exp_Ch9 is else B := Make_Selected_Component (Sloc, - Prefix => New_Copy_Tree (Tsk), + Prefix => New_Copy_Tree (Tsk), Selector_Name => New_Occurrence_Of (Entity (Bound), Sloc)); Analyze_And_Resolve (B, Typ); @@ -541,8 +541,8 @@ package body Exp_Ch9 is return Make_Attribute_Reference (Sloc, Attribute_Name => Name_Pos, - Prefix => New_Occurrence_Of (Etype (Bound), Sloc), - Expressions => New_List (B)); + Prefix => New_Occurrence_Of (Etype (Bound), Sloc), + Expressions => New_List (B)); end Actual_Discriminant_Ref; -- Start of processing for Actual_Family_Offset @@ -592,7 +592,6 @@ package body Exp_Ch9 is -- Now add lengths of preceding entries and entry families Prev := First_Entity (Ttyp); - while Chars (Prev) /= Chars (Ent) or else (Ekind (Prev) /= Ekind (Ent)) or else not Sem_Ch6.Type_Conformant (Ent, Prev) @@ -659,7 +658,7 @@ package body Exp_Ch9 is Left_Opnd => Expr, Right_Opnd => Make_Op_Add (Sloc, - Left_Opnd => + Left_Opnd => Actual_Family_Offset (Hi, Lo), Right_Opnd => Make_Integer_Literal (Sloc, 1))); @@ -769,11 +768,9 @@ package body Exp_Ch9 is Decl := Make_Object_Declaration (Loc, - Defining_Identifier => - Make_Defining_Identifier (Loc, Name_uObject), - Object_Definition => - New_Occurrence_Of (Obj_Ptr, Loc), - Expression => + Defining_Identifier => Make_Defining_Identifier (Loc, Name_uObject), + Object_Definition => New_Occurrence_Of (Obj_Ptr, Loc), + Expression => Unchecked_Convert_To (Obj_Ptr, Make_Identifier (Loc, Name_uO))); Set_Debug_Info_Needed (Defining_Identifier (Decl)); Prepend_To (Decls, Decl); @@ -863,19 +860,20 @@ package body Exp_Ch9 is Statements => New_List ( Make_Procedure_Call_Statement (Sloc (Stats), - Name => New_Occurrence_Of ( + Name => New_Occurrence_Of ( RTE (RE_Exceptional_Complete_Rendezvous), Sloc (Stats)), Parameter_Associations => New_List ( Make_Function_Call (Sloc (Stats), - Name => New_Occurrence_Of ( - RTE (RE_Get_GNAT_Exception), Sloc (Stats))))))))); + Name => + New_Occurrence_Of + (RTE (RE_Get_GNAT_Exception), Sloc (Stats))))))))); Set_Parent (New_S, Astat); -- temp parent for Analyze call Analyze_Exception_Handlers (Exception_Handlers (New_S)); Expand_Exception_Handlers (New_S); - -- Exceptional_Complete_Rendezvous must be called with abort - -- still deferred, which is the case for a "when all others" handler. + -- Exceptional_Complete_Rendezvous must be called with abort still + -- deferred, which is the case for a "when all others" handler. return New_S; end Build_Accept_Body; @@ -886,8 +884,7 @@ package body Exp_Ch9 is procedure Build_Activation_Chain_Entity (N : Node_Id) is function Has_Activation_Chain (Stmt : Node_Id) return Boolean; - -- Determine whether an extended return statement has an activation - -- chain. + -- Determine whether an extended return statement has activation chain -------------------------- -- Has_Activation_Chain -- @@ -1068,22 +1065,21 @@ package body Exp_Ch9 is Set_Debug_Info_Needed (Def_Id); return Make_Function_Specification (Loc, - Defining_Unit_Name => Def_Id, + Defining_Unit_Name => Def_Id, Parameter_Specifications => New_List ( Make_Parameter_Specification (Loc, Defining_Identifier => Make_Defining_Identifier (Loc, Name_uO), - Parameter_Type => + Parameter_Type => New_Occurrence_Of (RTE (RE_Address), Loc)), Make_Parameter_Specification (Loc, Defining_Identifier => Make_Defining_Identifier (Loc, Name_uE), - Parameter_Type => + Parameter_Type => New_Occurrence_Of (RTE (RE_Protected_Entry_Index), Loc))), - Result_Definition => - New_Occurrence_Of (Standard_Boolean, Loc)); + Result_Definition => New_Occurrence_Of (Standard_Boolean, Loc)); end Build_Barrier_Function_Specification; -------------------------- @@ -1098,7 +1094,7 @@ package body Exp_Ch9 is begin return Make_Function_Call (Loc, - Name => New_Occurrence_Of (E, Loc), + Name => New_Occurrence_Of (E, Loc), Parameter_Associations => New_List (Concurrent_Ref (N))); end Build_Call_With_Task; @@ -1121,7 +1117,7 @@ package body Exp_Ch9 is return; end if; - -- Find the declaration that created the access type. It is either a + -- Find the declaration that created the access type, which is either a -- type declaration, or an object declaration with an access definition, -- in which case the type is anonymous. @@ -1206,11 +1202,10 @@ package body Exp_Ch9 is end if; Master_Id := - Make_Defining_Identifier (Loc, - New_External_Name (Chars (Typ), 'M')); + Make_Defining_Identifier (Loc, New_External_Name (Chars (Typ), 'M')); -- Generate: - -- Mnn renames _master; + -- typeMnn renames _master; Ren_Decl := Make_Object_Renaming_Declaration (Loc, @@ -6233,8 +6228,8 @@ package body Exp_Ch9 is null; else - Error_Msg_N ("potentially unsynchronized barrier?", N); - Error_Msg_N ("\& should be private component of type?", N); + Error_Msg_N ("potentially unsynchronized barrier??", N); + Error_Msg_N ("\& should be private component of type??", N); end if; end if; end if; @@ -13786,7 +13781,8 @@ package body Exp_Ch9 is Append_To (L, Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (Called_Subp), Loc), + Name => + New_Occurrence_Of (RTE (Called_Subp), Loc), Parameter_Associations => Args)); end; end if; @@ -13847,10 +13843,13 @@ package body Exp_Ch9 is Unchecked_Convert_To (RTE (RE_System_Interrupt_Id), Expr), Make_Attribute_Reference (Loc, - Prefix => Make_Selected_Component (Loc, - Make_Identifier (Loc, Name_uInit), - Duplicate_Subexpr_No_Checks - (Expression (Handler))), + Prefix => + Make_Selected_Component (Loc, + Prefix => + Make_Identifier (Loc, Name_uInit), + Selector_Name => + Duplicate_Subexpr_No_Checks + (Expression (Handler))), Attribute_Name => Name_Access)))); end; end if; @@ -13874,16 +13873,17 @@ package body Exp_Ch9 is Make_Procedure_Call_Statement (Loc, Name => New_Occurrence_Of - (RTE (RE_Install_Restricted_Handlers), Loc), + (RTE (RE_Install_Restricted_Handlers), Loc), Parameter_Associations => Args)); else if not Uses_Lock_Free (Defining_Identifier (Pdec)) then + -- First, prepends the _object argument Prepend_To (Args, Make_Attribute_Reference (Loc, - Prefix => + Prefix => Make_Selected_Component (Loc, Prefix => Make_Identifier (Loc, Name_uInit), Selector_Name => @@ -13895,7 +13895,8 @@ package body Exp_Ch9 is Append_To (L, Make_Procedure_Call_Statement (Loc, - Name => New_Occurrence_Of (RTE (RE_Install_Handlers), Loc), + Name => + New_Occurrence_Of (RTE (RE_Install_Handlers), Loc), Parameter_Associations => Args)); end if; end; @@ -14049,8 +14050,7 @@ package body Exp_Ch9 is then Append_To (Args, Make_Selected_Component (Loc, - Prefix => - Make_Identifier (Loc, Name_uInit), + Prefix => Make_Identifier (Loc, Name_uInit), Selector_Name => Make_Identifier (Loc, Name_uRelative_Deadline))); @@ -14151,8 +14151,7 @@ package body Exp_Ch9 is Subtype_Mark => New_Occurrence_Of (Subp_Ptr_Typ, Loc), Expression => Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Body_Proc, Loc), + Prefix => New_Occurrence_Of (Body_Proc, Loc), Attribute_Name => Name_Unrestricted_Access)))); -- For the .NET/JVM cases revert to the original code below ??? @@ -14161,8 +14160,7 @@ package body Exp_Ch9 is Append_To (Args, Unchecked_Convert_To (RTE (RE_Task_Procedure_Access), Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (Body_Proc, Loc), + Prefix => New_Occurrence_Of (Body_Proc, Loc), Attribute_Name => Name_Address))); end if; end; @@ -14236,7 +14234,7 @@ package body Exp_Ch9 is return Make_Procedure_Call_Statement (Loc, - Name => Name, + Name => Name, Parameter_Associations => Args); end Make_Task_Create_Call; @@ -14307,7 +14305,6 @@ package body Exp_Ch9 is Actual := First (Actuals); Formal := Defining_Identifier (First (Formals)); Params := New_List; - while Present (Actual) loop if Is_By_Copy_Type (Etype (Actual)) then -- Generate: @@ -14317,11 +14314,9 @@ package body Exp_Ch9 is Append_To (Decls, Make_Object_Declaration (Loc, - Aliased_Present => - True, - Defining_Identifier => - Temp_Nam, - Object_Definition => + Aliased_Present => True, + Defining_Identifier => Temp_Nam, + Object_Definition => New_Occurrence_Of (Etype (Formal), Loc))); if Ekind (Formal) /= E_Out_Parameter then @@ -14336,10 +14331,8 @@ package body Exp_Ch9 is Append_To (Stmts, Make_Assignment_Statement (Loc, - Name => - Temp_Asn, - Expression => - New_Copy_Tree (Actual))); + Name => Temp_Asn, + Expression => New_Copy_Tree (Actual))); end if; -- Generate: @@ -14347,10 +14340,8 @@ package body Exp_Ch9 is Append_To (Params, Make_Attribute_Reference (Loc, - Attribute_Name => - Name_Unchecked_Access, - Prefix => - New_Occurrence_Of (Temp_Nam, Loc))); + Attribute_Name => Name_Unchecked_Access, + Prefix => New_Occurrence_Of (Temp_Nam, Loc))); Has_Param := True; @@ -14383,12 +14374,9 @@ package body Exp_Ch9 is Append_To (Decls, Make_Object_Declaration (Loc, - Defining_Identifier => - P, - Object_Definition => - New_Occurrence_Of (Blk_Typ, Loc), - Expression => - Expr)); + Defining_Identifier => P, + Object_Definition => New_Occurrence_Of (Blk_Typ, Loc), + Expression => Expr)); return P; end Parameter_Block_Pack; @@ -14421,7 +14409,7 @@ package body Exp_Ch9 is Asnmt := Make_Assignment_Statement (Loc, - Name => + Name => New_Copy (Actual), Expression => Make_Explicit_Dereference (Loc, diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb index f409cb07ae5..3e72bac9063 100644 --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -228,10 +228,10 @@ package body Exp_Util is if Present (Msg_Node) then Error_Msg_N - ("?N?info: atomic synchronization set for &", Msg_Node); + ("info: atomic synchronization set for &?N?", Msg_Node); else Error_Msg_N - ("?N?info: atomic synchronization set", N); + ("info: atomic synchronization set?N?", N); end if; end if; end Activate_Atomic_Synchronization; diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb index e091cea3076..ec944a102be 100644 --- a/gcc/ada/freeze.adb +++ b/gcc/ada/freeze.adb @@ -3355,45 +3355,6 @@ package body Freeze is end if; end if; - -- The following checks are only relevant when SPARK_Mode is on as - -- they are not standard Ada legality rules. - - if SPARK_Mode = On then - if Is_SPARK_Volatile (Rec) then - - -- A discriminated type cannot be volatile (SPARK RM C.6(4)) - - if Has_Discriminants (Rec) then - Error_Msg_N ("discriminated type & cannot be volatile", Rec); - - -- A tagged type cannot be volatile (SPARK RM C.6(5)) - - elsif Is_Tagged_Type (Rec) then - Error_Msg_N ("tagged type & cannot be volatile", Rec); - end if; - - -- A non-volatile record type cannot contain volatile components - -- (SPARK RM C.6(2)). The check is performed at freeze point - -- because the volatility status of the record type and its - -- components is clearly known. - - else - Comp := First_Component (Rec); - while Present (Comp) loop - if Comes_From_Source (Comp) - and then Is_SPARK_Volatile (Comp) - then - Error_Msg_Name_1 := Chars (Rec); - Error_Msg_N - ("component & of non-volatile record type % cannot be " - & "volatile", Comp); - end if; - - Next_Component (Comp); - end loop; - end if; - end if; - -- All done if not a full record definition if Ekind (Rec) /= E_Record_Type then @@ -4301,7 +4262,7 @@ package body Freeze is Error_Msg_N ("??convention C enumeration object has size less than ^", E); - Error_Msg_N ("\?use explicit size clause to set size", E); + Error_Msg_N ("\??use explicit size clause to set size", E); end if; end if; diff --git a/gcc/ada/freeze.ads b/gcc/ada/freeze.ads index 5f08f590364..188ea5dc1d8 100644 --- a/gcc/ada/freeze.ads +++ b/gcc/ada/freeze.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2011, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -195,7 +195,7 @@ package Freeze is -- Returns No_List if no freeze nodes needed. procedure Freeze_All (From : Entity_Id; After : in out Node_Id); - -- Before a non-instance body, or at the end of a declarative part + -- Before a non-instance body, or at the end of a declarative part, -- freeze all entities therein that are not yet frozen. Calls itself -- recursively to catch types in inner packages that were not frozen -- at the inner level because they were not yet completely defined. diff --git a/gcc/ada/frontend.adb b/gcc/ada/frontend.adb index 2ead14c09da..24b33cfe209 100644 --- a/gcc/ada/frontend.adb +++ b/gcc/ada/frontend.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -80,7 +80,6 @@ begin -- since it uses names table entries. Rtsfind.Initialize; - Atree.Initialize; Nlists.Initialize; Elists.Initialize; Lib.Load.Initialize; diff --git a/gcc/ada/g-comlin.adb b/gcc/ada/g-comlin.adb index 0f74bbfdc60..43592949a83 100644 --- a/gcc/ada/g-comlin.adb +++ b/gcc/ada/g-comlin.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1999-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1999-2014, 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- -- @@ -449,21 +449,16 @@ package body GNAT.Command_Line is declare Arg : constant String := Argument (Parser, Parser.Current_Argument - 1); - Index : Positive; - begin - Index := Arg'First; - while Index <= Arg'Last loop + for Index in Arg'Range loop if Arg (Index) = '*' or else Arg (Index) = '?' or else Arg (Index) = '[' then Parser.In_Expansion := True; Start_Expansion (Parser.Expansion_It, Arg); - return Get_Argument (Do_Expansion); + return Get_Argument (Do_Expansion, Parser); end if; - - Index := Index + 1; end loop; end; end if; diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 5b32f208e72..4d4623b3419 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -2476,9 +2476,7 @@ process_attributes (tree *node, struct attrib **attr_list, bool in_place, case ATTR_LINK_SECTION: if (targetm_common.have_named_sections) { - tree name = build_string (IDENTIFIER_LENGTH (attr->name), - IDENTIFIER_POINTER (attr->name)); - set_decl_section_name (*node, name); + set_decl_section_name (*node, IDENTIFIER_POINTER (attr->name)); DECL_COMMON (*node) = 0; } else @@ -2497,7 +2495,7 @@ process_attributes (tree *node, struct attrib **attr_list, bool in_place, break; case ATTR_THREAD_LOCAL_STORAGE: - DECL_TLS_MODEL (*node) = decl_default_tls_model (*node); + set_decl_tls_model (*node, decl_default_tls_model (*node)); DECL_COMMON (*node) = 0; break; } diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb index 87dcaca6afe..756961e3d2d 100644 --- a/gcc/ada/gnat1drv.adb +++ b/gcc/ada/gnat1drv.adb @@ -25,6 +25,7 @@ with Atree; use Atree; with Back_End; use Back_End; +with Checks; with Comperr; with Csets; use Csets; with Debug; use Debug; @@ -69,6 +70,7 @@ with Sprint; use Sprint; with Stringt; with Stylesw; use Stylesw; with Targparm; use Targparm; +with Tbuild; with Tree_Gen; with Treepr; use Treepr; with Ttypes; @@ -81,6 +83,10 @@ with Validsw; use Validsw; with System.Assertions; +-------------- +-- Gnat1drv -- +-------------- + procedure Gnat1drv is Main_Unit_Node : Node_Id; -- Compilation unit node for main unit @@ -105,6 +111,13 @@ procedure Gnat1drv is -- Called when we are not generating code, to check if -gnatR was requested -- and if so, explain that we will not be honoring the request. + procedure Post_Compilation_Validation_Checks; + -- This procedure performs various validation checks that have to be left + -- to the end of the compilation process, after generating code but before + -- issuing error messages. In particular, these checks generally require + -- the information provided by the back end in back annotation of declared + -- entities (e.g. actual size and alignment values chosen by the back end). + ---------------------------- -- Adjust_Global_Switches -- ---------------------------- @@ -351,6 +364,12 @@ procedure Gnat1drv is Dynamic_Elaboration_Checks := False; + -- Detect overflow on unconstrained floating-point types, such as + -- the predefined types Float, Long_Float and Long_Long_Float from + -- package Standard. + + Check_Float_Overflow := True; + -- Set STRICT mode for overflow checks if not set explicitly. This -- prevents suppressing of overflow checks by default, in code down -- below. @@ -741,6 +760,35 @@ procedure Gnat1drv is end if; end Check_Rep_Info; + ---------------------------------------- + -- Post_Compilation_Validation_Checks -- + ---------------------------------------- + + procedure Post_Compilation_Validation_Checks is + begin + -- Validate alignment check warnings. In some cases we generate warnings + -- about possible alignment errors because we don't know the alignment + -- that will be chosen by the back end. This routine is in charge of + -- getting rid of those warnings if we can tell they are not needed. + + Checks.Validate_Alignment_Check_Warnings; + + -- Validate unchecked conversions (using the values for size and + -- alignment annotated by the backend where possible). + + Sem_Ch13.Validate_Unchecked_Conversions; + + -- Validate address clauses (again using alignment values annotated + -- by the backend where possible). + + Sem_Ch13.Validate_Address_Clauses; + + -- Validate independence pragmas (again using values annotated by + -- the back end for component layout etc.) + + Sem_Ch13.Validate_Independence; + end Post_Compilation_Validation_Checks; + -- Start of processing for Gnat1drv begin @@ -763,6 +811,7 @@ begin Scan_Compiler_Arguments; Osint.Add_Default_Search_Dirs; + Atree.Initialize; Nlists.Initialize; Sinput.Initialize; Sem.Initialize; @@ -785,7 +834,7 @@ begin -- Acquire target parameters from system.ads (source of package System) - declare + Targparm_Acquire : declare use Sinput; S : Source_File_Index; @@ -812,12 +861,17 @@ begin Targparm.Get_Target_Parameters (System_Text => Source_Text (S), Source_First => Source_First (S), - Source_Last => Source_Last (S)); + Source_Last => Source_Last (S), + Make_Id => Tbuild.Make_Id'Access, + Make_SC => Tbuild.Make_SC'Access, + Set_RND => Tbuild.Set_RND'Access); -- Acquire configuration pragma information from Targparm Restrict.Restrictions := Targparm.Restrictions_On_Target; - end; + end Targparm_Acquire; + + -- Perform various adjustments and settings of global switches Adjust_Global_Switches; @@ -886,9 +940,7 @@ begin if Compilation_Errors then Treepr.Tree_Dump; - Sem_Ch13.Validate_Unchecked_Conversions; - Sem_Ch13.Validate_Address_Clauses; - Sem_Ch13.Validate_Independence; + Post_Compilation_Validation_Checks; Errout.Output_Messages; Namet.Finalize; @@ -1084,9 +1136,7 @@ begin Set_Standard_Output; - Sem_Ch13.Validate_Unchecked_Conversions; - Sem_Ch13.Validate_Address_Clauses; - Sem_Ch13.Validate_Independence; + Post_Compilation_Validation_Checks; Errout.Finalize (Last_Call => True); Errout.Output_Messages; Treepr.Tree_Dump; @@ -1126,9 +1176,7 @@ begin or else Targparm.Frontend_Layout_On_Target or else Targparm.VM_Target /= No_VM) then - Sem_Ch13.Validate_Unchecked_Conversions; - Sem_Ch13.Validate_Address_Clauses; - Sem_Ch13.Validate_Independence; + Post_Compilation_Validation_Checks; Errout.Finalize (Last_Call => True); Errout.Output_Messages; Write_ALI (Object => False); @@ -1178,20 +1226,9 @@ begin Exp_CG.Generate_CG_Output; - -- Validate unchecked conversions (using the values for size and - -- alignment annotated by the backend where possible). - - Sem_Ch13.Validate_Unchecked_Conversions; - - -- Validate address clauses (again using alignment values annotated - -- by the backend where possible). - - Sem_Ch13.Validate_Address_Clauses; + -- Perform post compilation validation checks - -- Validate independence pragmas (again using values annotated by - -- the back end for component layout etc.) - - Sem_Ch13.Validate_Independence; + Post_Compilation_Validation_Checks; -- Now we complete output of errors, rep info and the tree info. These -- are delayed till now, since it is perfectly possible for gigi to diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index 79e43ab90b0..bbe5676ca21 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -218,7 +218,6 @@ Implementation Defined Pragmas * Pragma Precondition:: * Pragma Predicate:: * Pragma Preelaborable_Initialization:: -* Pragma Preelaborate_05:: * Pragma Pre_Class:: * Pragma Priority_Specific_Dispatching:: * Pragma Profile:: @@ -226,8 +225,6 @@ Implementation Defined Pragmas * Pragma Propagate_Exceptions:: * Pragma Provide_Shift_Operators:: * Pragma Psect_Object:: -* Pragma Pure_05:: -* Pragma Pure_12:: * Pragma Pure_Function:: * Pragma Ravenscar:: * Pragma Refined_State:: @@ -254,7 +251,6 @@ Implementation Defined Pragmas * Pragma Suppress_Debug_Info:: * Pragma Suppress_Exception_Locations:: * Pragma Suppress_Initialization:: -* Pragma Task_Info:: * Pragma Task_Name:: * Pragma Task_Storage:: * Pragma Test_Case:: @@ -297,9 +293,6 @@ Implementation Defined Aspects * Aspect Object_Size:: * Aspect Persistent_BSS:: * Aspect Predicate:: -* Aspect Preelaborate_05:: -* Aspect Pure_05:: -* Aspect Pure_12:: * Aspect Pure_Function:: * Aspect Refined_State:: * Aspect Remote_Access_Type:: @@ -310,6 +303,7 @@ Implementation Defined Aspects * Aspect SPARK_Mode:: * Aspect Suppress_Debug_Info:: * Aspect Test_Case:: +* Aspect Thread_Local_Storage:: * Aspect Universal_Aliasing:: * Aspect Universal_Data:: * Aspect Unmodified:: @@ -635,7 +629,7 @@ The GNAT Library * System.Restrictions (s-restri.ads):: * System.Rident (s-rident.ads):: * System.Strings.Stream_Ops (s-ststop.ads):: -* System.Task_Info (s-tasinf.ads):: +* System.Unsigned_Types (s-unstyp.ads):: * System.Wch_Cnv (s-wchcnv.ads):: * System.Wch_Con (s-wchcon.ads):: @@ -1053,7 +1047,6 @@ consideration, the use of these pragmas should be minimized. * Pragma Precondition:: * Pragma Predicate:: * Pragma Preelaborable_Initialization:: -* Pragma Preelaborate_05:: * Pragma Pre_Class:: * Pragma Priority_Specific_Dispatching:: * Pragma Profile:: @@ -1061,8 +1054,6 @@ consideration, the use of these pragmas should be minimized. * Pragma Propagate_Exceptions:: * Pragma Provide_Shift_Operators:: * Pragma Psect_Object:: -* Pragma Pure_05:: -* Pragma Pure_12:: * Pragma Pure_Function:: * Pragma Ravenscar:: * Pragma Refined_State:: @@ -1089,7 +1080,6 @@ consideration, the use of these pragmas should be minimized. * Pragma Suppress_Debug_Info:: * Pragma Suppress_Exception_Locations:: * Pragma Suppress_Initialization:: -* Pragma Task_Info:: * Pragma Task_Name:: * Pragma Task_Storage:: * Pragma Test_Case:: @@ -1789,7 +1779,8 @@ as overflow checking could be guaranteed. The @code{Check_Float_Overflow} configuration pragma achieves this effect. If a unit is compiled subject to this configuration pragma, then all operations -on predefined floating-point types will be treated as +on predefined floating-point types including operations on +base types of these floating-point types will be treated as though those types were constrained, and overflow checks will be generated. The @code{Constraint_Error} exception is raised if the result is out of range. @@ -4113,8 +4104,6 @@ Normally a unit with no @code{License} pragma is considered to have an unknown license, and no checking is done. However, standard GNAT headers are recognized, and license information is derived from them as follows. -@itemize @bullet - A GNAT license header starts with a line containing 78 hyphens. The following comment text is searched for the appearance of any of the following strings. @@ -4126,7 +4115,6 @@ If one of the strings ``This specification is adapted from the Ada Semantic Interface'' or ``This specification is derived from the Ada Reference Manual'' is found then the unit is assumed to be unrestricted. -@end itemize @noindent These default actions means that a program with a restricted license pragma @@ -5597,24 +5585,6 @@ This pragma is standard in Ada 2005, but is available in all earlier versions of Ada as an implementation-defined pragma. See Ada 2012 Reference Manual for details. -@node Pragma Preelaborate_05 -@unnumberedsec Pragma Preelaborate_05 -@findex Preelaborate_05 -@noindent -Syntax: - -@smallexample @c ada -pragma Preelaborate_05 [(library_unit_NAME)]; -@end smallexample - -@noindent -This pragma is only available in GNAT mode (@option{-gnatg} switch set) -and is intended for use in the standard run-time library only. It has -no effect in Ada 83 or Ada 95 mode, but is -equivalent to @code{pragma Prelaborate} when operating in later -Ada versions. This is used to handle some cases where packages -not previously preelaborable became so in Ada 2005. - @node Pragma Pre_Class @unnumberedsec Pragma Pre_Class @cindex Pre_Class @@ -5878,7 +5848,7 @@ pragma Provide_Shift_Operators (integer_first_subtype_LOCAL_NAME); This pragma can be applied to a first subtype local name that specifies either an unsigned or signed type. It has the effect of providing the five shift operators (Shift_Left, Shift_Right, Shift_Right_Arithmetic, -Rotate_Left and Rotate_Right) for the given type. It is equivalent to +Rotate_Left and Rotate_Right) for the given type. It is similar to including the function declarations for these five operators, together with the pragma Import (Intrinsic, ...) statements. @@ -5902,42 +5872,6 @@ EXTERNAL_SYMBOL ::= @noindent This pragma is identical in effect to pragma @code{Common_Object}. -@node Pragma Pure_05 -@unnumberedsec Pragma Pure_05 -@findex Pure_05 -@noindent -Syntax: - -@smallexample @c ada -pragma Pure_05 [(library_unit_NAME)]; -@end smallexample - -@noindent -This pragma is only available in GNAT mode (@option{-gnatg} switch set) -and is intended for use in the standard run-time library only. It has -no effect in Ada 83 or Ada 95 mode, but is -equivalent to @code{pragma Pure} when operating in later -Ada versions. This is used to handle some cases where packages -not previously pure became so in Ada 2005. - -@node Pragma Pure_12 -@unnumberedsec Pragma Pure_12 -@findex Pure_12 -@noindent -Syntax: - -@smallexample @c ada -pragma Pure_12 [(library_unit_NAME)]; -@end smallexample - -@noindent -This pragma is only available in GNAT mode (@option{-gnatg} switch set) -and is intended for use in the standard run-time library only. It has -no effect in Ada 83, Ada 95, or Ada 2005 modes, but is -equivalent to @code{pragma Pure} when operating in later -Ada versions. This is used to handle some cases where packages -not previously pure became so in Ada 2012. - @node Pragma Pure_Function @unnumberedsec Pragma Pure_Function @findex Pure_Function @@ -6931,27 +6865,6 @@ to apply to the base type and all its subtypes. If the pragma is given for other than a first subtype, then it applies only to the given subtype. The pragma may not be given after the type is frozen. -@node Pragma Task_Info -@unnumberedsec Pragma Task_Info -@findex Task_Info -@noindent -Syntax - -@smallexample @c ada -pragma Task_Info (EXPRESSION); -@end smallexample - -@noindent -This pragma appears within a task definition (like pragma -@code{Priority}) and applies to the task in which it appears. The -argument must be of type @code{System.Task_Info.Task_Info_Type}. -The @code{Task_Info} pragma provides system dependent control over -aspects of tasking implementation, for example, the ability to map -tasks to specific processors. For details on the facilities available -for the version of GNAT that you are using, see the documentation -in the spec of package System.Task_Info in the runtime -library. - @node Pragma Task_Name @unnumberedsec Pragma Task_Name @findex Task_Name @@ -7919,9 +7832,6 @@ clause. * Aspect Object_Size:: * Aspect Persistent_BSS:: * Aspect Predicate:: -* Aspect Preelaborate_05:: -* Aspect Pure_05:: -* Aspect Pure_12:: * Aspect Pure_Function:: * Aspect Refined_State:: * Aspect Remote_Access_Type:: @@ -7932,6 +7842,7 @@ clause. * Aspect SPARK_Mode:: * Aspect Suppress_Debug_Info:: * Aspect Test_Case:: +* Aspect Thread_Local_Storage:: * Aspect Universal_Aliasing:: * Aspect Universal_Data:: * Aspect Unmodified:: @@ -8125,24 +8036,6 @@ predicate is static or dynamic is controlled by the form of the expression. It is also separately controllable using pragma @code{Assertion_Policy}. -@node Aspect Preelaborate_05 -@unnumberedsec Aspect Preelaborate_05 -@findex Preelaborate_05 -@noindent -This aspect is equivalent to pragma @code{Preelaborate_05}. - -@node Aspect Pure_05 -@unnumberedsec Aspect Pure_05 -@findex Pure_05 -@noindent -This aspect is equivalent to pragma @code{Pure_05}. - -@node Aspect Pure_12 -@unnumberedsec Aspect Pure_12 -@findex Pure_12 -@noindent -This aspect is equivalent to pragma @code{Pure_12}. - @node Aspect Pure_Function @unnumberedsec Aspect Pure_Function @findex Pure_Function @@ -8208,6 +8101,12 @@ This aspect is equivalent to pragma @code{Suppress_Debug_Info}. @noindent This aspect is equivalent to pragma @code{Test_Case}. +@node Aspect Thread_Local_Storage +@unnumberedsec Aspect Thread_Local_Storage +@findex Thread_Local_Storage +@noindent +This aspect is equivalent to pragma @code{Thread_Local_Storage}. + @node Aspect Universal_Aliasing @unnumberedsec Aspect Universal_Aliasing @findex Universal_Aliasing @@ -10538,8 +10437,8 @@ violation of restriction "SPARK" at <file> @end smallexample This is not a replacement for the semantic checks performed by the -SPARK Examiner tool, as the compiler only deals currently with code, -not at all with SPARK 2005 annotations and does not guarantee catching all +SPARK Examiner tool, as the compiler currently only deals with code, +not SPARK 2005 annotations, and does not guarantee catching all cases of constructs forbidden by SPARK 2005. Thus it may well be the case that code which passes the compiler with @@ -10551,7 +10450,123 @@ This restriction can be useful in providing an initial filter for code developed using SPARK 2005, or in examining legacy code to see how far it is from meeting SPARK restrictions. -Note that if a unit is compiled in Ada 95 mode with SPARK restriction, +The list below summarises the checks that are performed when this +restriction is in force: +@itemize @bullet +@item No block statements +@item No case statements with only an others clause +@item Exit statements in loops must respect the SPARK 2005 language restrictions +@item No goto statements +@item Return can only appear as last statement in function +@item Function must have return statement +@item Loop parameter specification must include subtype mark +@item Prefix of expanded name cannot be a loop statement +@item Abstract subprogram not allowed +@item User-defined operators not allowed +@item Access type parameters not allowed +@item Default expressions for parameters not allowed +@item Default expressions for record fields not allowed +@item No tasking constructs allowed +@item Label needed at end of subprograms and packages +@item No mixing of positional and named parameter association +@item No access types as result type +@item No unconstrained arrays as result types +@item No null procedures +@item Initial and later declarations must be in correct order (declaration can't come after body) +@item No attributes on private types if full declaration not visible +@item No package declaration within package specification +@item No controlled types +@item No discriminant types +@item No overloading +@item Selector name cannot be operator symbol (i.e. operator symbol cannot be prefixed) +@item Access attribute not allowed +@item Allocator not allowed +@item Result of catenation must be String +@item Operands of catenation must be string literal, static char or another catenation +@item No conditional expressions +@item No explicit dereference +@item Quantified expression not allowed +@item Slicing not allowed +@item No exception renaming +@item No generic renaming +@item No object renaming +@item No use clause +@item Aggregates must be qualified +@item Non-static choice in array aggregates not allowed +@item The only view conversions which are allowed as in-out parameters are conversions of a tagged type to an ancestor type +@item No mixing of positional and named association in aggregate, no multi choice +@item AND, OR and XOR for arrays only allowed when operands have same static bounds +@item Fixed point operands to * or / must be qualified or converted +@item Comparison operators not allowed for Booleans or arrays (except strings) +@item Equality not allowed for arrays with non-matching static bounds (except strings) +@item Conversion / qualification not allowed for arrays with non-matching static bounds +@item Subprogram declaration only allowed in package spec (unless followed by import) +@item Access types not allowed +@item Incomplete type declaration not allowed +@item Object and subtype declarations must respect SPARK restrictions +@item Digits or delta constraint not allowed +@item Decimal fixed point type not allowed +@item Aliasing of objects not allowed +@item Modular type modulus must be power of 2 +@item Base not allowed on subtype mark +@item Unary operators not allowed on modular types (except not) +@item Non-tagged record cannot be null +@item No class-wide operations +@item Initialization expressions must respect SPARK restrictions +@item Non-static ranges not allowed except in iteration schemes +@item String subtypes must have lower bound of 1 +@item Subtype of Boolean cannot have constraint +@item At most one tagged type or extension per package +@item Interface is not allowed +@item Character literal cannot be prefixed (selector name cannot be character literal) +@item Record aggregate cannot contain 'others' +@item Component association in record aggregate must contain a single choice +@item Ancestor part cannot be a type mark +@item Attributes 'Image, 'Width and 'Value not allowed +@item Functions may not update globals +@item Subprograms may not contain direct calls to themselves (prevents recursion within unit) +@item Call to subprogram not allowed in same unit before body has been seen (prevents recursion within unit) +@end itemize + +The following restrictions are enforced, but note that they are actually more +strict that the latest SPARK 2005 language definition: + +@itemize @bullet +@item No derived types other than tagged type extensions +@item Subtype of unconstrained array must have constraint +@end itemize + +This list summarises the main SPARK 2005 language rules that are not +currently checked by the SPARK_05 restriction: + +@itemize @bullet +@item SPARK annotations are treated as comments so are not checked at all +@item Based real literals not allowed +@item Objects cannot be initialized at declaration by calls to user-defined functions +@item Objects cannot be initialized at declaration by assignments from variables +@item Objects cannot be initialized at declaration by assignments from indexed/selected components +@item Ranges shall not be null +@item A fixed point delta expression must be a simple expression +@item Restrictions on where renaming declarations may be placed +@item Externals of mode 'out' cannot be referenced +@item Externals of mode 'in' cannot be updated +@item Loop with no iteration scheme or exits only allowed as last statement in main program or task +@item Subprogram cannot have parent unit name +@item SPARK 2005 inherited subprogram must be prefixed with overriding +@item External variables (or functions that reference them) may not be passed as actual parameters +@item Globals must be explicitly mentioned in contract +@item Deferred constants cannot be completed by pragma Import +@item Package initialization cannot read/write variables from other packages +@item Prefix not allowed for entities that are directly visible +@item Identifier declaration can't override inherited package name +@item Cannot use Standard or other predefined packages as identifiers +@item After renaming, cannot use the original name +@item Subprograms can only be renamed to remove package prefix +@item Pragma import must be immediately after entity it names +@item No mutual recursion between multiple units (this can be checked with gnatcheck) +@end itemize + +Note that if a unit is compiled in Ada 95 mode with the SPARK restriction, violations will be reported for constructs forbidden in SPARK 95, instead of SPARK 2005. @@ -12021,82 +12036,96 @@ Manual, and are summarized in Annex M@. A requirement for conforming Ada compilers is that they provide documentation describing how the implementation deals with each of these -issues. In this chapter, you will find each point in Annex M listed -followed by a description in italic font of how GNAT +issues. In this chapter you will find each point in Annex M listed, +followed by a description of how GNAT handles the implementation dependence. You can use this chapter as a guide to minimizing implementation dependent features in your programs if portability to other compilers and other operating systems is an important consideration. The numbers -in each section below correspond to the paragraph number in the Ada +in each entry below correspond to the paragraph numbers in the Ada Reference Manual. + +@itemize @bullet @sp 1 +@item @cartouche @noindent -@strong{2}. Whether or not each recommendation given in Implementation +Whether or not each recommendation given in Implementation Advice is followed. See 1.1.2(37). @end cartouche @noindent @xref{Implementation Advice}. + @sp 1 +@item @cartouche @noindent -@strong{3}. Capacity limitations of the implementation. See 1.1.3(3). +Capacity limitations of the implementation. See 1.1.3(3). @end cartouche @noindent The complexity of programs that can be processed is limited only by the total amount of available virtual memory, and disk space for the generated object files. + @sp 1 +@item @cartouche @noindent -@strong{4}. Variations from the standard that are impractical to avoid +Variations from the standard that are impractical to avoid given the implementation's execution environment. See 1.1.3(6). @end cartouche @noindent There are no variations from the standard. + @sp 1 +@item @cartouche @noindent -@strong{5}. Which @code{code_statement}s cause external +Which @code{code_statement}s cause external interactions. See 1.1.3(10). @end cartouche @noindent Any @code{code_statement} can potentially cause external interactions. @sp 1 +@item @cartouche @noindent -@strong{6}. The coded representation for the text of an Ada +The coded representation for the text of an Ada program. See 2.1(4). @end cartouche @noindent See separate section on source representation. + @sp 1 +@item @cartouche @noindent -@strong{7}. The control functions allowed in comments. See 2.1(14). +The control functions allowed in comments. See 2.1(14). @end cartouche @noindent See separate section on source representation. @sp 1 +@item @cartouche @noindent -@strong{8}. The representation for an end of line. See 2.2(2). +The representation for an end of line. See 2.2(2). @end cartouche @noindent See separate section on source representation. @sp 1 +@item @cartouche @noindent -@strong{9}. Maximum supported line length and lexical element +Maximum supported line length and lexical element length. See 2.2(15). @end cartouche @noindent @@ -12108,18 +12137,20 @@ line length to be specified to be any value up to 32767. The maximum length of a lexical element is the same as the maximum line length. @sp 1 +@item @cartouche @noindent -@strong{10}. Implementation defined pragmas. See 2.8(14). +Implementation defined pragmas. See 2.8(14). @end cartouche @noindent @xref{Implementation Defined Pragmas}. @sp 1 +@item @cartouche @noindent -@strong{11}. Effect of pragma @code{Optimize}. See 2.8(27). +Effect of pragma @code{Optimize}. See 2.8(27). @end cartouche @noindent Pragma @code{Optimize}, if given with a @code{Time} or @code{Space} @@ -12127,9 +12158,10 @@ parameter, checks that the optimization flag is set, and aborts if it is not. @sp 1 +@item @cartouche @noindent -@strong{12}. The sequence of characters of the value returned by +The sequence of characters of the value returned by @code{@var{S}'Image} when some of the graphic characters of @code{@var{S}'Wide_Image} are not defined in @code{Character}. See 3.5(37). @@ -12140,9 +12172,10 @@ method used for the source. See section on source representation for further details. @sp 1 +@item @cartouche @noindent -@strong{13}. The predefined integer types declared in +The predefined integer types declared in @code{Standard}. See 3.5.4(25). @end cartouche @noindent @@ -12161,36 +12194,40 @@ further details. @end table @sp 1 +@item @cartouche @noindent -@strong{14}. Any nonstandard integer types and the operators defined +Any nonstandard integer types and the operators defined for them. See 3.5.4(26). @end cartouche @noindent There are no nonstandard integer types. @sp 1 +@item @cartouche @noindent -@strong{15}. Any nonstandard real types and the operators defined for +Any nonstandard real types and the operators defined for them. See 3.5.6(8). @end cartouche @noindent There are no nonstandard real types. @sp 1 +@item @cartouche @noindent -@strong{16}. What combinations of requested decimal precision and range +What combinations of requested decimal precision and range are supported for floating point types. See 3.5.7(7). @end cartouche @noindent The precision and range is as defined by the IEEE standard. @sp 1 +@item @cartouche @noindent -@strong{17}. The predefined floating point types declared in +The predefined floating point types declared in @code{Standard}. See 3.5.7(16). @end cartouche @noindent @@ -12206,17 +12243,19 @@ The precision and range is as defined by the IEEE standard. @end table @sp 1 +@item @cartouche @noindent -@strong{18}. The small of an ordinary fixed point type. See 3.5.9(8). +The small of an ordinary fixed point type. See 3.5.9(8). @end cartouche @noindent @code{Fine_Delta} is 2**(@minus{}63) @sp 1 +@item @cartouche @noindent -@strong{19}. What combinations of small, range, and digits are +What combinations of small, range, and digits are supported for fixed point types. See 3.5.9(10). @end cartouche @noindent @@ -12228,9 +12267,10 @@ Text_IO is accurate to only 53 bits, rather than the full mantissa. This is because floating-point conversions are used to convert fixed point. @sp 1 +@item @cartouche @noindent -@strong{20}. The result of @code{Tags.Expanded_Name} for types declared +The result of @code{Tags.Expanded_Name} for types declared within an unnamed @code{block_statement}. See 3.9(10). @end cartouche @noindent @@ -12238,34 +12278,38 @@ Block numbers of the form @code{B@var{nnn}}, where @var{nnn} is a decimal integer are allocated. @sp 1 +@item @cartouche @noindent -@strong{21}. Implementation-defined attributes. See 4.1.4(12). +Implementation-defined attributes. See 4.1.4(12). @end cartouche @noindent @xref{Implementation Defined Attributes}. @sp 1 +@item @cartouche @noindent -@strong{22}. Any implementation-defined time types. See 9.6(6). +Any implementation-defined time types. See 9.6(6). @end cartouche @noindent There are no implementation-defined time types. @sp 1 +@item @cartouche @noindent -@strong{23}. The time base associated with relative delays. +The time base associated with relative delays. @end cartouche @noindent See 9.6(20). The time base used is that provided by the C library function @code{gettimeofday}. @sp 1 +@item @cartouche @noindent -@strong{24}. The time base of the type @code{Calendar.Time}. See +The time base of the type @code{Calendar.Time}. See 9.6(23). @end cartouche @noindent @@ -12273,9 +12317,10 @@ The time base used is that provided by the C library function @code{gettimeofday}. @sp 1 +@item @cartouche @noindent -@strong{25}. The time zone used for package @code{Calendar} +The time zone used for package @code{Calendar} operations. See 9.6(24). @end cartouche @noindent @@ -12284,18 +12329,20 @@ setting for local time, as accessed by the C library function @code{localtime}. @sp 1 +@item @cartouche @noindent -@strong{26}. Any limit on @code{delay_until_statements} of +Any limit on @code{delay_until_statements} of @code{select_statements}. See 9.6(29). @end cartouche @noindent There are no such limits. @sp 1 +@item @cartouche @noindent -@strong{27}. Whether or not two non-overlapping parts of a composite +Whether or not two non-overlapping parts of a composite object are independently addressable, in the case where packing, record layout, or @code{Component_Size} is specified for the object. See 9.10(1). @@ -12305,18 +12352,20 @@ Separate components are independently addressable if they do not share overlapping storage units. @sp 1 +@item @cartouche @noindent -@strong{28}. The representation for a compilation. See 10.1(2). +The representation for a compilation. See 10.1(2). @end cartouche @noindent A compilation is represented by a sequence of files presented to the compiler in a single invocation of the @command{gcc} command. @sp 1 +@item @cartouche @noindent -@strong{29}. Any restrictions on compilations that contain multiple +Any restrictions on compilations that contain multiple compilation_units. See 10.1(4). @end cartouche @noindent @@ -12325,18 +12374,20 @@ sequence of files can be presented to the compiler as a single compilation. @sp 1 +@item @cartouche @noindent -@strong{30}. The mechanisms for creating an environment and for adding +The mechanisms for creating an environment and for adding and replacing compilation units. See 10.1.4(3). @end cartouche @noindent See separate section on compilation model. @sp 1 +@item @cartouche @noindent -@strong{31}. The manner of explicitly assigning library units to a +The manner of explicitly assigning library units to a partition. See 10.2(2). @end cartouche @noindent @@ -12360,9 +12411,10 @@ options, refer to @ref{The GNAT Make Program gnatmake,,, gnat_ugn, @value{EDITION} User's Guide}. @sp 1 +@item @cartouche @noindent -@strong{32}. The implementation-defined means, if any, of specifying +The implementation-defined means, if any, of specifying which compilation units are needed by a given compilation unit. See 10.2(2). @end cartouche @@ -12373,9 +12425,10 @@ implementation-defined pragmas or other implementation-defined means for specifying needed units. @sp 1 +@item @cartouche @noindent -@strong{33}. The manner of designating the main subprogram of a +The manner of designating the main subprogram of a partition. See 10.2(7). @end cartouche @noindent @@ -12383,9 +12436,10 @@ The main program is designated by providing the name of the corresponding @file{ALI} file as the input parameter to the binder. @sp 1 +@item @cartouche @noindent -@strong{34}. The order of elaboration of @code{library_items}. See +The order of elaboration of @code{library_items}. See 10.2(18). @end cartouche @noindent @@ -12399,9 +12453,10 @@ third by elaborating in alphabetical order of unit names where a choice still remains. @sp 1 +@item @cartouche @noindent -@strong{35}. Parameter passing and function return for the main +Parameter passing and function return for the main subprogram. See 10.2(21). @end cartouche @noindent @@ -12411,9 +12466,10 @@ value is the return code of the program (overriding any value that may have been set by a call to @code{Ada.Command_Line.Set_Exit_Status}). @sp 1 +@item @cartouche @noindent -@strong{36}. The mechanisms for building and running partitions. See +The mechanisms for building and running partitions. See 10.2(24). @end cartouche @noindent @@ -12424,18 +12480,20 @@ programs consisting of multiple partitions. See the separate GLADE manual for details. @sp 1 +@item @cartouche @noindent -@strong{37}. The details of program execution, including program +The details of program execution, including program termination. See 10.2(25). @end cartouche @noindent See separate section on compilation model. @sp 1 +@item @cartouche @noindent -@strong{38}. The semantics of any non-active partitions supported by the +The semantics of any non-active partitions supported by the implementation. See 10.2(28). @end cartouche @noindent @@ -12444,9 +12502,10 @@ provided by the operating system. See the GLADE reference manual for further details. @sp 1 +@item @cartouche @noindent -@strong{39}. The information returned by @code{Exception_Message}. See +The information returned by @code{Exception_Message}. See 11.4.1(10). @end cartouche @noindent @@ -12454,9 +12513,10 @@ Exception message returns the null string unless a specific message has been passed by the program. @sp 1 +@item @cartouche @noindent -@strong{40}. The result of @code{Exceptions.Exception_Name} for types +The result of @code{Exceptions.Exception_Name} for types declared within an unnamed @code{block_statement}. See 11.4.1(12). @end cartouche @noindent @@ -12464,9 +12524,10 @@ Blocks have implementation defined names of the form @code{B@var{nnn}} where @var{nnn} is an integer. @sp 1 +@item @cartouche @noindent -@strong{41}. The information returned by +The information returned by @code{Exception_Information}. See 11.4.1(13). @end cartouche @noindent @@ -12511,9 +12572,10 @@ The line terminator sequence at the end of each line, including the last line is a single @code{LF} character (@code{16#0A#}). @sp 1 +@item @cartouche @noindent -@strong{42}. Implementation-defined check names. See 11.5(27). +Implementation-defined check names. See 11.5(27). @end cartouche @noindent The implementation defined check name Alignment_Check controls checking of @@ -12530,27 +12592,30 @@ In addition, a user program can add implementation-defined check names by means of the pragma Check_Name. @sp 1 +@item @cartouche @noindent -@strong{43}. The interpretation of each aspect of representation. See +The interpretation of each aspect of representation. See 13.1(20). @end cartouche @noindent See separate section on data representations. @sp 1 +@item @cartouche @noindent -@strong{44}. Any restrictions placed upon representation items. See +Any restrictions placed upon representation items. See 13.1(20). @end cartouche @noindent See separate section on data representations. @sp 1 +@item @cartouche @noindent -@strong{45}. The meaning of @code{Size} for indefinite subtypes. See +The meaning of @code{Size} for indefinite subtypes. See 13.3(48). @end cartouche @noindent @@ -12559,9 +12624,10 @@ for the case of a subprogram parameter, the size of the parameter object is the actual size. @sp 1 +@item @cartouche @noindent -@strong{46}. The default external representation for a type tag. See +The default external representation for a type tag. See 13.3(75). @end cartouche @noindent @@ -12569,9 +12635,10 @@ The default external representation for a type tag is the fully expanded name of the type in upper case letters. @sp 1 +@item @cartouche @noindent -@strong{47}. What determines whether a compilation unit is the same in +What determines whether a compilation unit is the same in two different partitions. See 13.3(76). @end cartouche @noindent @@ -12579,18 +12646,20 @@ A compilation unit is the same in two different partitions if and only if it derives from the same source file. @sp 1 +@item @cartouche @noindent -@strong{48}. Implementation-defined components. See 13.5.1(15). +Implementation-defined components. See 13.5.1(15). @end cartouche @noindent The only implementation defined component is the tag for a tagged type, which contains a pointer to the dispatching table. @sp 1 +@item @cartouche @noindent -@strong{49}. If @code{Word_Size} = @code{Storage_Unit}, the default bit +If @code{Word_Size} = @code{Storage_Unit}, the default bit ordering. See 13.5.3(5). @end cartouche @noindent @@ -12599,9 +12668,10 @@ implementation, so no non-default bit ordering is supported. The default bit ordering corresponds to the natural endianness of the target architecture. @sp 1 +@item @cartouche @noindent -@strong{50}. The contents of the visible part of package @code{System} +The contents of the visible part of package @code{System} and its language-defined children. See 13.7(2). @end cartouche @noindent @@ -12609,9 +12679,10 @@ See the definition of these packages in files @file{system.ads} and @file{s-stoele.ads}. @sp 1 +@item @cartouche @noindent -@strong{51}. The contents of the visible part of package +The contents of the visible part of package @code{System.Machine_Code}, and the meaning of @code{code_statements}. See 13.8(7). @end cartouche @@ -12619,9 +12690,10 @@ See the definition of these packages in files @file{system.ads} and See the definition and documentation in file @file{s-maccod.ads}. @sp 1 +@item @cartouche @noindent -@strong{52}. The effect of unchecked conversion. See 13.9(11). +The effect of unchecked conversion. See 13.9(11). @end cartouche @noindent Unchecked conversion between types of the same size @@ -12639,9 +12711,10 @@ greater than the source alignment, then a copy of the result is made with appropriate alignment @sp 1 +@item @cartouche @noindent -@strong{53}. The semantics of operations on invalid representations. +The semantics of operations on invalid representations. See 13.9.2(10-11). @end cartouche @noindent @@ -12668,9 +12741,10 @@ As indicated, an exception is raised on the array assignment, but not on the simple assignment of the invalid negative value from Y to Z. @sp 1 +@item @cartouche @noindent -@strong{53}. The manner of choosing a storage pool for an access type +The manner of choosing a storage pool for an access type when @code{Storage_Pool} is not specified for the type. See 13.11(17). @end cartouche @noindent @@ -12684,21 +12758,23 @@ library units @code{System.Pool_Global}, @code{System.Pool_Size} and default pools used. @sp 1 +@item @cartouche @noindent -@strong{54}. Whether or not the implementation provides user-accessible +Whether or not the implementation provides user-accessible names for the standard pool type(s). See 13.11(17). @end cartouche @noindent -See documentation in the sources of the run time mentioned in paragraph -@strong{53} . All these pools are accessible by means of @code{with}'ing +See documentation in the sources of the run time mentioned in the previous +paragraph. All these pools are accessible by means of @code{with}'ing these units. @sp 1 +@item @cartouche @noindent -@strong{55}. The meaning of @code{Storage_Size}. See 13.11(18). +The meaning of @code{Storage_Size}. See 13.11(18). @end cartouche @noindent @code{Storage_Size} is measured in storage units, and refers to the @@ -12706,28 +12782,32 @@ total space available for an access type collection, or to the primary stack space for a task. @sp 1 +@item @cartouche @noindent -@strong{56}. Implementation-defined aspects of storage pools. See +Implementation-defined aspects of storage pools. See 13.11(22). @end cartouche @noindent -See documentation in the sources of the run time mentioned in paragraph -@strong{53} for details on GNAT-defined aspects of storage pools. +See documentation in the sources of the run time mentioned in the +paragraph about standard storage pools above +for details on GNAT-defined aspects of storage pools. @sp 1 +@item @cartouche @noindent -@strong{57}. The set of restrictions allowed in a pragma +The set of restrictions allowed in a pragma @code{Restrictions}. See 13.12(7). @end cartouche @noindent @xref{Standard and Implementation Defined Restrictions}. @sp 1 +@item @cartouche @noindent -@strong{58}. The consequences of violating limitations on +The consequences of violating limitations on @code{Restrictions} pragmas. See 13.12(9). @end cartouche @noindent @@ -12736,9 +12816,10 @@ if violated. Currently there are no other consequences of violating restrictions. @sp 1 +@item @cartouche @noindent -@strong{59}. The representation used by the @code{Read} and +The representation used by the @code{Read} and @code{Write} attributes of elementary types in terms of stream elements. See 13.13.2(9). @end cartouche @@ -12748,18 +12829,20 @@ the type, using the number of bits corresponding to the @code{@var{type}'Size} value, and the natural ordering of the machine. @sp 1 +@item @cartouche @noindent -@strong{60}. The names and characteristics of the numeric subtypes +The names and characteristics of the numeric subtypes declared in the visible part of package @code{Standard}. See A.1(3). @end cartouche @noindent See items describing the integer and floating-point types supported. @sp 1 +@item @cartouche @noindent -@strong{61}. The string returned by @code{Character_Set_Version}. +The string returned by @code{Character_Set_Version}. See A.3.5(3). @end cartouche @noindent @@ -12768,9 +12851,10 @@ the string "Unicode 4.0", referring to version 4.0 of the Unicode specification. @sp 1 +@item @cartouche @noindent -@strong{62}. The accuracy actually achieved by the elementary +The accuracy actually achieved by the elementary functions. See A.5.1(1). @end cartouche @noindent @@ -12778,9 +12862,10 @@ The elementary functions correspond to the functions available in the C library. Only fast math mode is implemented. @sp 1 +@item @cartouche @noindent -@strong{63}. The sign of a zero result from some of the operators or +The sign of a zero result from some of the operators or functions in @code{Numerics.Generic_Elementary_Functions}, when @code{Float_Type'Signed_Zeros} is @code{True}. See A.5.1(46). @end cartouche @@ -12789,27 +12874,30 @@ The sign of zeroes follows the requirements of the IEEE 754 standard on floating-point. @sp 1 +@item @cartouche @noindent -@strong{64}. The value of +The value of @code{Numerics.Float_Random.Max_Image_Width}. See A.5.2(27). @end cartouche @noindent Maximum image width is 6864, see library file @file{s-rannum.ads}. @sp 1 +@item @cartouche @noindent -@strong{65}. The value of +The value of @code{Numerics.Discrete_Random.Max_Image_Width}. See A.5.2(27). @end cartouche @noindent Maximum image width is 6864, see library file @file{s-rannum.ads}. @sp 1 +@item @cartouche @noindent -@strong{66}. The algorithms for random number generation. See +The algorithms for random number generation. See A.5.2(32). @end cartouche @noindent @@ -12818,9 +12906,10 @@ The algorithm is the Mersenne Twister, as documented in the source file 2**19937-1. @sp 1 +@item @cartouche @noindent -@strong{67}. The string representation of a random number generator's +The string representation of a random number generator's state. See A.5.2(38). @end cartouche @noindent @@ -12829,9 +12918,10 @@ the fixed-width decimal representations of the 624 32-bit integers of the state vector. @sp 1 +@item @cartouche @noindent -@strong{68}. The minimum time interval between calls to the +The minimum time interval between calls to the time-dependent Reset procedure that are guaranteed to initiate different random number sequences. See A.5.2(45). @end cartouche @@ -12840,9 +12930,10 @@ The minimum period between reset calls to guarantee distinct series of random numbers is one microsecond. @sp 1 +@item @cartouche @noindent -@strong{69}. The values of the @code{Model_Mantissa}, +The values of the @code{Model_Mantissa}, @code{Model_Emin}, @code{Model_Epsilon}, @code{Model}, @code{Safe_First}, and @code{Safe_Last} attributes, if the Numerics Annex is not supported. See A.5.3(72). @@ -12852,9 +12943,10 @@ Run the compiler with @option{-gnatS} to produce a listing of package @code{Standard}, has the values of all numeric attributes. @sp 1 +@item @cartouche @noindent -@strong{70}. Any implementation-defined characteristics of the +Any implementation-defined characteristics of the input-output packages. See A.7(14). @end cartouche @noindent @@ -12862,9 +12954,10 @@ There are no special implementation defined characteristics for these packages. @sp 1 +@item @cartouche @noindent -@strong{71}. The value of @code{Buffer_Size} in @code{Storage_IO}. See +The value of @code{Buffer_Size} in @code{Storage_IO}. See A.9(10). @end cartouche @noindent @@ -12873,9 +12966,10 @@ the value of @code{@var{type}'Size} rounded up to the next storage unit boundary. @sp 1 +@item @cartouche @noindent -@strong{72}. External files for standard input, standard output, and +External files for standard input, standard output, and standard error See A.10(5). @end cartouche @noindent @@ -12883,9 +12977,10 @@ These files are mapped onto the files provided by the C streams libraries. See source file @file{i-cstrea.ads} for further details. @sp 1 +@item @cartouche @noindent -@strong{73}. The accuracy of the value produced by @code{Put}. See +The accuracy of the value produced by @code{Put}. See A.10.9(36). @end cartouche @noindent @@ -12894,9 +12989,10 @@ precision of the value, zeroes are output in the corresponding least significant digit positions. @sp 1 +@item @cartouche @noindent -@strong{74}. The meaning of @code{Argument_Count}, @code{Argument}, and +The meaning of @code{Argument_Count}, @code{Argument}, and @code{Command_Name}. See A.15(1). @end cartouche @noindent @@ -12904,27 +13000,30 @@ These are mapped onto the @code{argv} and @code{argc} parameters of the main program in the natural manner. @sp 1 +@item @cartouche @noindent -@strong{75}. The interpretation of the @code{Form} parameter in procedure +The interpretation of the @code{Form} parameter in procedure @code{Create_Directory}. See A.16(56). @end cartouche @noindent The @code{Form} parameter is not used. @sp 1 +@item @cartouche @noindent -@strong{76}. The interpretation of the @code{Form} parameter in procedure +The interpretation of the @code{Form} parameter in procedure @code{Create_Path}. See A.16(60). @end cartouche @noindent The @code{Form} parameter is not used. @sp 1 +@item @cartouche @noindent -@strong{77}. The interpretation of the @code{Form} parameter in procedure +The interpretation of the @code{Form} parameter in procedure @code{Copy_File}. See A.16(68). @end cartouche @noindent @@ -13001,9 +13100,24 @@ Form => "mode=internal, preserve=timestamps" @end smallexample @sp 1 +@item +@cartouche +@noindent +The interpretation of the @code{Pattern} parameter, when not the null string, +in the @code{Start_Search} and @code{Search} procedures. +See A.16(104) and A.16(112). +@end cartouche +@noindent +When the @code{Pattern} parameter is not the null string, it is interpreted +according to the syntax of regular expressions as defined in the +@code{GNAT.Regexp} package. +@xref{GNAT.Regexp (g-regexp.ads)}. + +@sp 1 +@item @cartouche @noindent -@strong{78}. Implementation-defined convention names. See B.1(11). +Implementation-defined convention names. See B.1(11). @end cartouche @noindent The following convention names are supported @@ -13068,17 +13182,19 @@ except for VMS, use of such other names results in a warning. In VMS implementations, these names are accepted silently. @sp 1 +@item @cartouche @noindent -@strong{79}. The meaning of link names. See B.1(36). +The meaning of link names. See B.1(36). @end cartouche @noindent Link names are the actual names used by the linker. @sp 1 +@item @cartouche @noindent -@strong{80}. The manner of choosing link names when neither the link +The manner of choosing link names when neither the link name nor the address of an imported or exported entity is specified. See B.1(36). @end cartouche @@ -13088,9 +13204,10 @@ external language, interpreting the Ada name as being in all lower case letters. @sp 1 +@item @cartouche @noindent -@strong{81}. The effect of pragma @code{Linker_Options}. See B.1(37). +The effect of pragma @code{Linker_Options}. See B.1(37). @end cartouche @noindent The string passed to @code{Linker_Options} is presented uninterpreted as @@ -13109,18 +13226,20 @@ order. For example, linker options for a body always appear before the options from the corresponding package spec. @sp 1 +@item @cartouche @noindent -@strong{82}. The contents of the visible part of package +The contents of the visible part of package @code{Interfaces} and its language-defined descendants. See B.2(1). @end cartouche @noindent See files with prefix @file{i-} in the distributed library. @sp 1 +@item @cartouche @noindent -@strong{83}. Implementation-defined children of package +Implementation-defined children of package @code{Interfaces}. The contents of the visible part of package @code{Interfaces}. See B.2(11). @end cartouche @@ -13128,9 +13247,10 @@ See files with prefix @file{i-} in the distributed library. See files with prefix @file{i-} in the distributed library. @sp 1 +@item @cartouche @noindent -@strong{84}. The types @code{Floating}, @code{Long_Floating}, +The types @code{Floating}, @code{Long_Floating}, @code{Binary}, @code{Long_Binary}, @code{Decimal_ Element}, and @code{COBOL_Character}; and the initialization of the variables @code{Ada_To_COBOL} and @code{COBOL_To_Ada}, in @@ -13156,26 +13276,29 @@ Character For initialization, see the file @file{i-cobol.ads} in the distributed library. @sp 1 +@item @cartouche @noindent -@strong{85}. Support for access to machine instructions. See C.1(1). +Support for access to machine instructions. See C.1(1). @end cartouche @noindent See documentation in file @file{s-maccod.ads} in the distributed library. @sp 1 +@item @cartouche @noindent -@strong{86}. Implementation-defined aspects of access to machine +Implementation-defined aspects of access to machine operations. See C.1(9). @end cartouche @noindent See documentation in file @file{s-maccod.ads} in the distributed library. @sp 1 +@item @cartouche @noindent -@strong{87}. Implementation-defined aspects of interrupts. See C.3(2). +Implementation-defined aspects of interrupts. See C.3(2). @end cartouche @noindent Interrupts are mapped to signals or conditions as appropriate. See @@ -13184,9 +13307,10 @@ definition of unit on the interrupts supported on a particular target. @sp 1 +@item @cartouche @noindent -@strong{88}. Implementation-defined aspects of pre-elaboration. See +Implementation-defined aspects of pre-elaboration. See C.4(13). @end cartouche @noindent @@ -13194,9 +13318,10 @@ GNAT does not permit a partition to be restarted without reloading, except under control of the debugger. @sp 1 +@item @cartouche @noindent -@strong{89}. The semantics of pragma @code{Discard_Names}. See C.5(7). +The semantics of pragma @code{Discard_Names}. See C.5(7). @end cartouche @noindent Pragma @code{Discard_Names} causes names of enumeration literals to @@ -13205,9 +13330,10 @@ provides the image of the Pos of the literal, and Value accepts Pos values. @sp 1 +@item @cartouche @noindent -@strong{90}. The result of the @code{Task_Identification.Image} +The result of the @code{Task_Identification.Image} attribute. See C.7.1(7). @end cartouche @noindent @@ -13235,9 +13361,10 @@ No_Implicit_Heap_Allocation is in effect, the image reduces to the numeric suffix, that is to say the hexadecimal representation of the virtual address of the control block of the task. @sp 1 +@item @cartouche @noindent -@strong{91}. The value of @code{Current_Task} when in a protected entry +The value of @code{Current_Task} when in a protected entry or interrupt handler. See C.7.1(17). @end cartouche @noindent @@ -13245,9 +13372,10 @@ Protected entries or interrupt handlers can be executed by any convenient thread, so the value of @code{Current_Task} is undefined. @sp 1 +@item @cartouche @noindent -@strong{92}. The effect of calling @code{Current_Task} from an entry +The effect of calling @code{Current_Task} from an entry body or interrupt handler. See C.7.1(19). @end cartouche @noindent @@ -13256,18 +13384,20 @@ interrupt handler is to return the identification of the task currently executing the code. @sp 1 +@item @cartouche @noindent -@strong{93}. Implementation-defined aspects of +Implementation-defined aspects of @code{Task_Attributes}. See C.7.2(19). @end cartouche @noindent There are no implementation-defined aspects of @code{Task_Attributes}. @sp 1 +@item @cartouche @noindent -@strong{94}. Values of all @code{Metrics}. See D(2). +Values of all @code{Metrics}. See D(2). @end cartouche @noindent The metrics information for GNAT depends on the performance of the @@ -13280,26 +13410,29 @@ on the exact target in use, this information can be used to determine the required metrics. @sp 1 +@item @cartouche @noindent -@strong{95}. The declarations of @code{Any_Priority} and +The declarations of @code{Any_Priority} and @code{Priority}. See D.1(11). @end cartouche @noindent See declarations in file @file{system.ads}. @sp 1 +@item @cartouche @noindent -@strong{96}. Implementation-defined execution resources. See D.1(15). +Implementation-defined execution resources. See D.1(15). @end cartouche @noindent There are no implementation-defined execution resources. @sp 1 +@item @cartouche @noindent -@strong{97}. Whether, on a multiprocessor, a task that is waiting for +Whether, on a multiprocessor, a task that is waiting for access to a protected object keeps its processor busy. See D.2.1(3). @end cartouche @noindent @@ -13307,9 +13440,10 @@ On a multi-processor, a task that is waiting for access to a protected object does not keep its processor busy. @sp 1 +@item @cartouche @noindent -@strong{98}. The affect of implementation defined execution resources +The affect of implementation defined execution resources on task dispatching. See D.2.1(9). @end cartouche @noindent @@ -13318,9 +13452,10 @@ and appropriate, these threads correspond to native threads of the underlying operating system. @sp 1 +@item @cartouche @noindent -@strong{99}. Implementation-defined @code{policy_identifiers} allowed +Implementation-defined @code{policy_identifiers} allowed in a pragma @code{Task_Dispatching_Policy}. See D.2.2(3). @end cartouche @noindent @@ -13328,9 +13463,10 @@ There are no implementation-defined policy-identifiers allowed in this pragma. @sp 1 +@item @cartouche @noindent -@strong{100}. Implementation-defined aspects of priority inversion. See +Implementation-defined aspects of priority inversion. See D.2.2(16). @end cartouche @noindent @@ -13338,17 +13474,19 @@ Execution of a task cannot be preempted by the implementation processing of delay expirations for lower priority tasks. @sp 1 +@item @cartouche @noindent -@strong{101}. Implementation-defined task dispatching. See D.2.2(18). +Implementation-defined task dispatching. See D.2.2(18). @end cartouche @noindent The policy is the same as that of the underlying threads implementation. @sp 1 +@item @cartouche @noindent -@strong{102}. Implementation-defined @code{policy_identifiers} allowed +Implementation-defined @code{policy_identifiers} allowed in a pragma @code{Locking_Policy}. See D.3(4). @end cartouche @noindent @@ -13363,9 +13501,10 @@ read/write lock allowing multiple propected object functions to enter concurrently. @sp 1 +@item @cartouche @noindent -@strong{103}. Default ceiling priorities. See D.3(10). +Default ceiling priorities. See D.3(10). @end cartouche @noindent The ceiling priority of protected objects of the type @@ -13373,9 +13512,10 @@ The ceiling priority of protected objects of the type Reference Manual D.3(10), @sp 1 +@item @cartouche @noindent -@strong{104}. The ceiling of any protected object used internally by +The ceiling of any protected object used internally by the implementation. See D.3(16). @end cartouche @noindent @@ -13383,17 +13523,19 @@ The ceiling priority of internal protected objects is @code{System.Priority'Last}. @sp 1 +@item @cartouche @noindent -@strong{105}. Implementation-defined queuing policies. See D.4(1). +Implementation-defined queuing policies. See D.4(1). @end cartouche @noindent There are no implementation-defined queuing policies. @sp 1 +@item @cartouche @noindent -@strong{106}. On a multiprocessor, any conditions that cause the +On a multiprocessor, any conditions that cause the completion of an aborted construct to be delayed later than what is specified for a single processor. See D.6(3). @end cartouche @@ -13402,9 +13544,10 @@ The semantics for abort on a multi-processor is the same as on a single processor, there are no further delays. @sp 1 +@item @cartouche @noindent -@strong{107}. Any operations that implicitly require heap storage +Any operations that implicitly require heap storage allocation. See D.7(8). @end cartouche @noindent @@ -13412,27 +13555,30 @@ The only operation that implicitly requires heap storage allocation is task creation. @sp 1 +@item @cartouche @noindent -@strong{108}. Implementation-defined aspects of pragma +Implementation-defined aspects of pragma @code{Restrictions}. See D.7(20). @end cartouche @noindent There are no such implementation-defined aspects. @sp 1 +@item @cartouche @noindent -@strong{109}. Implementation-defined aspects of package +Implementation-defined aspects of package @code{Real_Time}. See D.8(17). @end cartouche @noindent There are no implementation defined aspects of package @code{Real_Time}. @sp 1 +@item @cartouche @noindent -@strong{110}. Implementation-defined aspects of +Implementation-defined aspects of @code{delay_statements}. See D.9(8). @end cartouche @noindent @@ -13440,9 +13586,10 @@ Any difference greater than one microsecond will cause the task to be delayed (see D.9(7)). @sp 1 +@item @cartouche @noindent -@strong{111}. The upper bound on the duration of interrupt blocking +The upper bound on the duration of interrupt blocking caused by the implementation. See D.12(5). @end cartouche @noindent @@ -13450,9 +13597,10 @@ The upper bound is determined by the underlying operating system. In no cases is it more than 10 milliseconds. @sp 1 +@item @cartouche @noindent -@strong{112}. The means for creating and executing distributed +The means for creating and executing distributed programs. See E(5). @end cartouche @noindent @@ -13460,18 +13608,20 @@ The GLADE package provides a utility GNATDIST for creating and executing distributed programs. See the GLADE reference manual for further details. @sp 1 +@item @cartouche @noindent -@strong{113}. Any events that can result in a partition becoming +Any events that can result in a partition becoming inaccessible. See E.1(7). @end cartouche @noindent See the GLADE reference manual for full details on such events. @sp 1 +@item @cartouche @noindent -@strong{114}. The scheduling policies, treatment of priorities, and +The scheduling policies, treatment of priorities, and management of shared resources between partitions in certain cases. See E.1(11). @end cartouche @@ -13480,9 +13630,10 @@ See the GLADE reference manual for full details on these aspects of multi-partition execution. @sp 1 +@item @cartouche @noindent -@strong{115}. Events that cause the version of a compilation unit to +Events that cause the version of a compilation unit to change. See E.3(5). @end cartouche @noindent @@ -13493,9 +13644,10 @@ are significant except those which affect only layout, capitalization or comments. @sp 1 +@item @cartouche @noindent -@strong{116}. Whether the execution of the remote subprogram is +Whether the execution of the remote subprogram is immediately aborted as a result of cancellation. See E.4(13). @end cartouche @noindent @@ -13503,18 +13655,20 @@ See the GLADE reference manual for details on the effect of abort in a distributed application. @sp 1 +@item @cartouche @noindent -@strong{117}. Implementation-defined aspects of the PCS@. See E.5(25). +Implementation-defined aspects of the PCS@. See E.5(25). @end cartouche @noindent See the GLADE reference manual for a full description of all implementation defined aspects of the PCS@. @sp 1 +@item @cartouche @noindent -@strong{118}. Implementation-defined interfaces in the PCS@. See +Implementation-defined interfaces in the PCS@. See E.5(26). @end cartouche @noindent @@ -13522,9 +13676,10 @@ See the GLADE reference manual for a full description of all implementation defined interfaces. @sp 1 +@item @cartouche @noindent -@strong{119}. The values of named numbers in the package +The values of named numbers in the package @code{Decimal}. See F.2(7). @end cartouche @noindent @@ -13542,27 +13697,30 @@ implementation defined interfaces. @end table @sp 1 +@item @cartouche @noindent -@strong{120}. The value of @code{Max_Picture_Length} in the package +The value of @code{Max_Picture_Length} in the package @code{Text_IO.Editing}. See F.3.3(16). @end cartouche @noindent 64 @sp 1 +@item @cartouche @noindent -@strong{121}. The value of @code{Max_Picture_Length} in the package +The value of @code{Max_Picture_Length} in the package @code{Wide_Text_IO.Editing}. See F.3.4(5). @end cartouche @noindent 64 @sp 1 +@item @cartouche @noindent -@strong{122}. The accuracy actually achieved by the complex elementary +The accuracy actually achieved by the complex elementary functions and by other complex arithmetic operations. See G.1(1). @end cartouche @noindent @@ -13570,9 +13728,10 @@ Standard library functions are used for the complex arithmetic operations. Only fast math mode is currently supported. @sp 1 +@item @cartouche @noindent -@strong{123}. The sign of a zero result (or a component thereof) from +The sign of a zero result (or a component thereof) from any operator or function in @code{Numerics.Generic_Complex_Types}, when @code{Real'Signed_Zeros} is True. See G.1.1(53). @end cartouche @@ -13581,9 +13740,10 @@ The signs of zero values are as recommended by the relevant implementation advice. @sp 1 +@item @cartouche @noindent -@strong{124}. The sign of a zero result (or a component thereof) from +The sign of a zero result (or a component thereof) from any operator or function in @code{Numerics.Generic_Complex_Elementary_Functions}, when @code{Real'Signed_Zeros} is @code{True}. See G.1.2(45). @@ -13593,9 +13753,10 @@ The signs of zero values are as recommended by the relevant implementation advice. @sp 1 +@item @cartouche @noindent -@strong{125}. Whether the strict mode or the relaxed mode is the +Whether the strict mode or the relaxed mode is the default. See G.2(2). @end cartouche @noindent @@ -13603,9 +13764,10 @@ The strict mode is the default. There is no separate relaxed mode. GNAT provides a highly efficient implementation of strict mode. @sp 1 +@item @cartouche @noindent -@strong{126}. The result interval in certain cases of fixed-to-float +The result interval in certain cases of fixed-to-float conversion. See G.2.1(10). @end cartouche @noindent @@ -13614,9 +13776,10 @@ accuracy is that provided by performing all operations in 64-bit IEEE floating-point format. @sp 1 +@item @cartouche @noindent -@strong{127}. The result of a floating point arithmetic operation in +The result of a floating point arithmetic operation in overflow situations, when the @code{Machine_Overflows} attribute of the result type is @code{False}. See G.2.1(13). @end cartouche @@ -13631,9 +13794,10 @@ of a significant performance penalty), so infinite and NaN values are properly generated. @sp 1 +@item @cartouche @noindent -@strong{128}. The result interval for division (or exponentiation by a +The result interval for division (or exponentiation by a negative exponent), when the floating point hardware implements division as multiplication by a reciprocal. See G.2.1(16). @end cartouche @@ -13641,9 +13805,10 @@ as multiplication by a reciprocal. See G.2.1(16). Not relevant, division is IEEE exact. @sp 1 +@item @cartouche @noindent -@strong{129}. The definition of close result set, which determines the +The definition of close result set, which determines the accuracy of certain fixed point multiplications and divisions. See G.2.3(5). @end cartouche @@ -13654,9 +13819,10 @@ floating-point, the operation is done in floating-point, and the result is converted to the target type. @sp 1 +@item @cartouche @noindent -@strong{130}. Conditions on a @code{universal_real} operand of a fixed +Conditions on a @code{universal_real} operand of a fixed point multiplication or division for which the result shall be in the perfect result set. See G.2.3(22). @end cartouche @@ -13666,9 +13832,10 @@ can be computed by a single scaling operation involving a scale factor representable in 64-bits. @sp 1 +@item @cartouche @noindent -@strong{131}. The result of a fixed point arithmetic operation in +The result of a fixed point arithmetic operation in overflow situations, when the @code{Machine_Overflows} attribute of the result type is @code{False}. See G.2.3(27). @end cartouche @@ -13677,9 +13844,10 @@ Not relevant, @code{Machine_Overflows} is @code{True} for fixed-point types. @sp 1 +@item @cartouche @noindent -@strong{132}. The result of an elementary function reference in +The result of an elementary function reference in overflow situations, when the @code{Machine_Overflows} attribute of the result type is @code{False}. See G.2.4(4). @end cartouche @@ -13687,9 +13855,10 @@ result type is @code{False}. See G.2.4(4). IEEE infinite and Nan values are produced as appropriate. @sp 1 +@item @cartouche @noindent -@strong{133}. The value of the angle threshold, within which certain +The value of the angle threshold, within which certain elementary functions, complex arithmetic operations, and complex elementary functions yield results conforming to a maximum relative error bound. See G.2.4(10). @@ -13698,18 +13867,20 @@ error bound. See G.2.4(10). Information on this subject is not yet available. @sp 1 +@item @cartouche @noindent -@strong{134}. The accuracy of certain elementary functions for +The accuracy of certain elementary functions for parameters beyond the angle threshold. See G.2.4(10). @end cartouche @noindent Information on this subject is not yet available. @sp 1 +@item @cartouche @noindent -@strong{135}. The result of a complex arithmetic operation or complex +The result of a complex arithmetic operation or complex elementary function reference in overflow situations, when the @code{Machine_Overflows} attribute of the corresponding real type is @code{False}. See G.2.6(5). @@ -13718,9 +13889,10 @@ elementary function reference in overflow situations, when the IEEE infinite and Nan values are produced as appropriate. @sp 1 +@item @cartouche @noindent -@strong{136}. The accuracy of certain complex arithmetic operations and +The accuracy of certain complex arithmetic operations and certain complex elementary functions for parameters (or components thereof) beyond the angle threshold. See G.2.6(8). @end cartouche @@ -13728,18 +13900,20 @@ thereof) beyond the angle threshold. See G.2.6(8). Information on those subjects is not yet available. @sp 1 +@item @cartouche @noindent -@strong{137}. Information regarding bounded errors and erroneous +Information regarding bounded errors and erroneous execution. See H.2(1). @end cartouche @noindent Information on this subject is not yet available. @sp 1 +@item @cartouche @noindent -@strong{138}. Implementation-defined aspects of pragma +Implementation-defined aspects of pragma @code{Inspection_Point}. See H.3.2(8). @end cartouche @noindent @@ -13747,9 +13921,10 @@ Pragma @code{Inspection_Point} ensures that the variable is live and can be examined by the debugger at the inspection point. @sp 1 +@item @cartouche @noindent -@strong{139}. Implementation-defined aspects of pragma +Implementation-defined aspects of pragma @code{Restrictions}. See H.4(25). @end cartouche @noindent @@ -13758,14 +13933,19 @@ use of pragma @code{Restrictions [No_Exceptions]} has no effect on the generated code. Checks must suppressed by use of pragma @code{Suppress}. @sp 1 +@item @cartouche @noindent -@strong{140}. Any restrictions on pragma @code{Restrictions}. See +Any restrictions on pragma @code{Restrictions}. See H.4(27). @end cartouche @noindent There are no restrictions on pragma @code{Restrictions}. +@end itemize + + +@c ======================= @node Intrinsic Subprograms @chapter Intrinsic Subprograms @cindex Intrinsic Subprograms @@ -18091,7 +18271,7 @@ of GNAT, and will generate a warning message. * System.Restrictions (s-restri.ads):: * System.Rident (s-rident.ads):: * System.Strings.Stream_Ops (s-ststop.ads):: -* System.Task_Info (s-tasinf.ads):: +* System.Unsigned_Types (s-unstyp.ads):: * System.Wch_Cnv (s-wchcnv.ads):: * System.Wch_Con (s-wchcon.ads):: @end menu @@ -19114,7 +19294,7 @@ standard Ada library and are more convenient to use. @noindent A simple implementation of regular expressions, using a subset of regular expression syntax copied from familiar Unix style utilities. This is the -simples of the three pattern matching packages provided, and is particularly +simplest of the three pattern matching packages provided, and is particularly suitable for ``file globbing'' applications. @node GNAT.Registry (g-regist.ads) @@ -19671,14 +19851,16 @@ It is intended primarily to support implicit use of such subprograms when stream attributes are applied to string types, but the subprograms in this package can be used directly by application programs. -@node System.Task_Info (s-tasinf.ads) -@section @code{System.Task_Info} (@file{s-tasinf.ads}) -@cindex @code{System.Task_Info} (@file{s-tasinf.ads}) -@cindex Task_Info pragma +@node System.Unsigned_Types (s-unstyp.ads) +@section @code{System.Unsigned_Types} (@file{s-unstyp.ads}) +@cindex @code{System.Unsigned_Types} (@file{s-unstyp.ads}) @noindent -This package provides target dependent functionality that is used -to support the @code{Task_Info} pragma +This package contains definitions of standard unsigned types that +correspond in size to the standard signed types declared in Standard, +and (unlike the types in Interfaces) have corresponding names. It +also contains some related definitions for other specialized types +used by the compiler in connection with packed array types. @node System.Wch_Cnv (s-wchcnv.ads) @section @code{System.Wch_Cnv} (@file{s-wchcnv.ads}) @@ -20743,6 +20925,7 @@ A complete description of the AIs may be found in @item @code{Suppress} @tab @item @code{Suppress_Debug_Info} @tab -- GNAT @item @code{Test_Case} @tab -- GNAT +@item @code{Thread_Local_Storage} @tab -- GNAT @item @code{Type_Invariant} @tab @item @code{Unchecked_Union} @tab @item @code{Universal_Aliasing} @tab -- GNAT @@ -22218,6 +22401,8 @@ compatibility purposes. * pragma No_Run_Time:: * pragma Ravenscar:: * pragma Restricted_Run_Time:: +* pragma Task_Info:: +* System.Task_Info (s-tasinf.ads):: @end menu @node pragma No_Run_Time @@ -22246,6 +22431,41 @@ pragma @code{Profile (Restricted)}. The latter usage is preferred since the Ada 2005 pragma @code{Profile} is intended for this kind of implementation dependent addition. +@node pragma Task_Info +@section pragma Task_Info + +The functionality provided by pragma @code{Task_Info} is now part of the +Ada language. The @code{CPU} aspect and the package +@code{System.Multiprocessors} offer a less system-dependent way to specify +task affinity or to query the number of processsors. + +@noindent +Syntax + +@smallexample @c ada +pragma Task_Info (EXPRESSION); +@end smallexample + +@noindent +This pragma appears within a task definition (like pragma +@code{Priority}) and applies to the task in which it appears. The +argument must be of type @code{System.Task_Info.Task_Info_Type}. +The @code{Task_Info} pragma provides system dependent control over +aspects of tasking implementation, for example, the ability to map +tasks to specific processors. For details on the facilities available +for the version of GNAT that you are using, see the documentation +in the spec of package System.Task_Info in the runtime +library. + +@node System.Task_Info (s-tasinf.ads) +@section package System.Task_Info (@file{s-tasinf.ads}) + +@noindent +This package provides target dependent functionality that is used +to support the @code{Task_Info} pragma. The predefined Ada package + @code{System.Multiprocessors} and the @code{CPU} aspect now provide a +standard replacement for GNAT's @code{Task_Info} functionality. + @include fdl.texi @c GNU Free Documentation License diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi index 9a347525e91..dde83b45c17 100644 --- a/gcc/ada/gnat_ugn.texi +++ b/gcc/ada/gnat_ugn.texi @@ -5096,19 +5096,46 @@ This switch suppresses warnings for implicit dereferences in indexed components, slices, and selected components. @item -gnatw.d -@emph{Activate tagging of warning messages.} +@emph{Activate tagging of warning and info messages.} @cindex @option{-gnatw.d} (@command{gcc}) -If this switch is set, then warning messages are tagged, either with -the string ``@option{-gnatw?}'' showing which switch controls the warning, -or with ``[enabled by default]'' if the warning is not under control of a -specific @option{-gnatw?} switch. This mode is off by default, and is not -affected by the use of @code{-gnatwa}. +If this switch is set, then warning messages are tagged, with one of the +following strings: + +@table @option + +@item [-gnatw?] +Used to tag warnings controlled by the switch @option{-gnatwx} where x +is a letter a-z. + +@item [-gnatw.?] +Used to tag warnings controlled by the switch @option{-gnatw.x} where x +is a letter a-z. + +@item [-gnatel] +Used to tag elaboration information (info) messages generated when the +static model of elaboration is used and the @option{-gnatel} switch is set. + +@item [restriction warning] +Used to tag warning messages for restriction violations, activated by use +of the pragma @option{Restriction_Warnings}. + +@item [warning-as-error] +Used to tag warning messages that have been converted to error messages by +use of the pragma Warning_As_Error. Note that such warnings are prefixed by +the string "error: " rather than "warning: ". + +@item [enabled by default] +Used to tag all other warnings that are always given by default, unless +warnings are completely suppressed using pragma @option{Warnings(Off)} or +the switch @option{-gnatws}. + +@end table @item -gnatw.D -@emph{Deactivate tagging of warning messages.} +@emph{Deactivate tagging of warning and info messages messages.} @cindex @option{-gnatw.d} (@command{gcc}) If this switch is set, then warning messages return to the default -mode in which warnings are not tagged as described above for +mode in which warnings and info messages are not tagged as described above for @code{-gnatw.d}. @item -gnatwe @@ -11586,9 +11613,9 @@ the @option{-Wl,--gc-sections} option to gcc command or in the @option{-largs} section of @command{gnatmake}. This will perform a garbage collection of code and data never referenced. -If the linker performs a partial link (@option{-r} ld linker option), then you -will need to provide one or several entry point using the -@option{-e} / @option{--entry} ld option. +If the linker performs a partial link (@option{-r} linker option), then you +will need to provide the entry point using the @option{-e} / @option{--entry} +linker option. Note that objects compiled without the @option{-ffunction-sections} and @option{-fdata-sections} options can still be linked with the executable. @@ -14512,7 +14539,7 @@ is made; this is the default. @cindex @option{^--par_threshold^/MAX_PAR^} (@command{gnatpp}) If the number of parameter specifications is greater than @var{nnn} (or equal to @var{nnn} in case of a function), start each specification from -a new line. The default for @var{nnn} is 3. +a new line. This feature is disabled by default. @end table @node Setting the Source Search Path @@ -15071,7 +15098,7 @@ Ada source code into XML. @menu * Switches for gnat2xml:: -* Driving gnat2xml with gnatmake or gprbuild:: +* Driving gnat2xml with gnatmake:: * Other Programs:: * Structure of the XML:: @end menu @@ -15130,8 +15157,6 @@ Options: -v -- verbose (print out the command line options, and the names of output files as they are generated). --t -- do not delete tree files when done (they are deleted by default). - -cargs ... -- options to pass to gcc @end smallexample @@ -15140,21 +15165,9 @@ If a project file is specified and no argument source is explicitly specified, and no @option{-U} is specified, then the set of processed sources is all the immediate units of the argument project. - -You can generate the ``tree files'' ahead of time using the -gnatct switch: - -@smallexample -gnatmake -gnat2012 -gnatct *.ad[sb] -@end smallexample - -@noindent -If tree files do not exist, @command{gnat2xml} will create them by running gcc. -See the ASIS documentation for more information on tree files. - Example: @smallexample -mkdir xml-files gnat2xml -v -mxml-files *.ad[sb] -cargs -gnat2012 @end smallexample @@ -15165,34 +15178,31 @@ body source code lives in mumble-dumble.ads and mumble-dumble.adb, the above will produce xml-files/mumble-dumble.ads.xml and xml-files/mumble-dumble.adb.xml. -@node Driving gnat2xml with gnatmake or gprbuild -@section Driving @command{gnat2xml} with @command{gnatmake} or @command{gprbuild} +@node Driving gnat2xml with gnatmake +@section Driving @command{gnat2xml} with @command{gnatmake} @noindent -You can use gnatmake or gprbuild to drive @command{gnat2xml} to get -incremental updates of the XML files on a per-source-file basis. For -example, if you already have a bunch of XML files, and then you change -one source file, it will regenerate XML files only for that source -file, and other source files that depend on it. Gnatmake and gprbuild -take care of tracking inter-file dependencies. For example, if -this.adb says @code{with That;}, then this.adb depends on that.ads. +You can use gnatmake to drive @command{gnat2xml} to get incremental +updates of the XML files on a per-source-file basis. For example, if +you already have a bunch of XML files, and then you change one source +file, it will regenerate XML files only for that source file, and +other related source files. Gnatmake takes care of tracking inter-file +dependencies. -To do this, you tell gnatmake/gprbuild to pretend that -@command{gnat2xml} is the Ada compiler (instead of using gcc as the -Ada compiler, as is normal). +To do this, you tell gnatmake to pretend that @command{gnat2xml} is +the Ada compiler (instead of using gcc as the Ada compiler, as is +normal). To tell gnatmake to use @command{gnat2xml} instead of gcc as the ``compiler'', for example: @smallexample -gnatmake -gnatc *.adb --GCC="gnat2xml -t -mxml" +gnatmake -gnatc main.adb --GCC="gnat2xml -mxml" @end smallexample @noindent The @option{--GCC=} switch tells gnatmake that the ``compiler'' to run -is @command{gnat2xml -t -mxml}. The @option{-t} switch means to keep the tree -files, so they can be reused on the next run. (@command{gnat2xml} -deletes them by default.) As usual, @option{-mxml} means to put the +is @command{gnat2xml -mxml}. As usual, @option{-mxml} means to put the XML files in the @file{xml} subdirectory. You must give the @option{-gnatc} switch to gnatmake, which means @@ -15200,40 +15210,6 @@ You must give the @option{-gnatc} switch to gnatmake, which means complain about missing object (*.o) files; @command{gnat2xml} of course does not generate *.o files. -Using gprbuild is similar: you tell it to use @command{gnat2xml} -instead of gcc. First write a project file, such as my_project.gpr: - -@smallexample @c projectfile -project My_Project is - - package Compiler is - for Driver ("ada") use "gnat2xml"; - -- Use gnat2xml instead of the usual gcc. - - for Default_Switches ("ada") use ("-t", "-mxml"); - -- Same switches as in the gnatmake case. - end Compiler; - -end My_Project; -@end smallexample - -@noindent -Then: - -@smallexample @c projectfile -gprbuild --no-object-check -P my_project.gpr -@end smallexample - -@noindent -The @option{--no-object-check} switch serves the same purpose as -@option{-gnatc} in the gnatmake case --- it tells gprbuild not to -expect that the ``compiler'' (really @command{gnat2xml}) will produce -*.o files. - -See the gprbuild documentation for information on many other things -you can put in the project file, such as telling it where to find -the source files. - @node Other Programs @section Other Programs @@ -19493,6 +19469,32 @@ conventions. If this switch is omitted the default name for the body will be obtained from the argument file name according to the GNAT file naming conventions. +@item ^-W^/RESULT_ENCODING=^@var{e} +@cindex @option{^-W^/RESULT_ENCODING=^} (@command{gnatstub}) +Specify the wide character encoding method for the output body file. +@var{e} is one of the following: + +@itemize @bullet + +@item ^h^HEX^ +Hex encoding + +@item ^u^UPPER^ +Upper half encoding + +@item ^s^SHIFT_JIS^ +Shift/JIS encoding + +@item ^e^EUC^ +EUC encoding + +@item ^8^UTF8^ +UTF-8 encoding + +@item ^b^BRACKETS^ +Brackets encoding (default value) +@end itemize + @item ^-q^/QUIET^ @cindex @option{^-q^/QUIET^} (@command{gnatstub}) Quiet mode: do not generate a confirmation when a body is @@ -22871,21 +22873,16 @@ stack overflow.) On OpenVMS Alpha systems, if the pragma area is created. In the absence of a pragma @code{TASK_STORAGE}, a default guard area is created. -GNAT supplies the following task-related pragmas: - -@itemize @bullet -@item @code{TASK_INFO} - -This pragma appears within a task definition and -applies to the task in which it appears. The argument -must be of type @code{SYSTEM.TASK_INFO.TASK_INFO_TYPE}. +GNAT supplies the following task-related pragma: +@itemize @item @code{TASK_STORAGE} GNAT implements pragma @code{TASK_STORAGE} in the same way as HP Ada. Both HP Ada and GNAT supply the pragmas @code{PASSIVE}, @code{SUPPRESS}, and @code{VOLATILE}. @end itemize + @node Scheduling and Task Priority @subsection Scheduling and Task Priority @@ -23073,8 +23070,6 @@ following: @item @code{SOURCE_REFERENCE} -@item @code{TASK_INFO} - @item @code{UNCHECKED_UNION} @item @code{UNIMPLEMENTED_UNIT} diff --git a/gcc/ada/gnatcmd.adb b/gcc/ada/gnatcmd.adb index 50bc3ad3568..7eb39cefdd4 100644 --- a/gcc/ada/gnatcmd.adb +++ b/gcc/ada/gnatcmd.adb @@ -1075,17 +1075,7 @@ procedure GNATCmd is if Libraries_Present then - -- Add -L<lib_dir> -lgnarl -lgnat -Wl,-rpath,<lib_dir> - - Last_Switches.Increment_Last; - Last_Switches.Table (Last_Switches.Last) := - new String'("-L" & MLib.Utl.Lib_Directory); - Last_Switches.Increment_Last; - Last_Switches.Table (Last_Switches.Last) := - new String'("-lgnarl"); - Last_Switches.Increment_Last; - Last_Switches.Table (Last_Switches.Last) := - new String'("-lgnat"); + -- Add -Wl,-rpath,<lib_dir> -- If Path_Option is not null, create the switch ("-Wl,-rpath," or -- equivalent) with all the library dirs plus the standard GNAT diff --git a/gcc/ada/i-cstrin.ads b/gcc/ada/i-cstrin.ads index bebf6c02d26..833a69ac6f7 100644 --- a/gcc/ada/i-cstrin.ads +++ b/gcc/ada/i-cstrin.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1993-2011, Free Software Foundation, Inc. -- +-- Copyright (C) 1993-2014, Free Software Foundation, Inc. -- -- -- -- This specification is derived from the Ada Reference Manual for use with -- -- GNAT. The copyright notice above, and the license provisions that follow -- @@ -60,6 +60,8 @@ package Interfaces.C.Strings is function New_String (Str : String) return chars_ptr; procedure Free (Item : in out chars_ptr); + -- When deallocation is prohibited (eg: cert runtimes) this routine + -- will raise Program_Error Dereference_Error : exception; diff --git a/gcc/ada/impunit.adb b/gcc/ada/impunit.adb index 6b6b45febaa..de0cb0b2d15 100644 --- a/gcc/ada/impunit.adb +++ b/gcc/ada/impunit.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2000-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2000-2014, 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- -- @@ -380,6 +380,7 @@ package body Impunit is ("s-rident", F), -- System.Rident ("s-ststop", F), -- System.Strings.Stream_Ops ("s-tasinf", F), -- System.Task_Info + ("s-unstyp", F), -- System.Unsigned_Types ("s-wchcnv", F), -- System.Wch_Cnv ("s-wchcon", F), -- System.Wch_Con diff --git a/gcc/ada/layout.adb b/gcc/ada/layout.adb index 466d1ca2929..52c981e36c8 100644 --- a/gcc/ada/layout.adb +++ b/gcc/ada/layout.adb @@ -1200,8 +1200,7 @@ package body Layout is Len := Convert_To (Standard_Unsigned, Len); - -- If range definitely flat or superflat, - -- result size is zero + -- If range definitely flat or superflat, result size is 0 if OK and then LHi <= 0 then Set_Esize (E, Uint_0); @@ -2432,7 +2431,6 @@ package body Layout is -- represents them the same way. if Is_Access_Type (E) then - Desig_Type := Underlying_Type (Designated_Type (E)); -- If we only have a limited view of the type, see whether the @@ -2469,10 +2467,13 @@ package body Layout is -- address size to accommodate a fat pointer. elsif Present (Desig_Type) - and then Is_Array_Type (Desig_Type) - and then not Is_Constrained (Desig_Type) - and then not Has_Completion_In_Body (Desig_Type) - and then not Debug_Flag_6 + and then Is_Array_Type (Desig_Type) + and then not Is_Constrained (Desig_Type) + and then not Has_Completion_In_Body (Desig_Type) + + -- Debug Flag -gnatd6 says make all pointers to unconstrained thin + + and then not Debug_Flag_6 then Init_Size (E, 2 * System_Address_Size); @@ -2493,12 +2494,11 @@ package body Layout is -- fat pointer. elsif Present (Desig_Type) - and then Present (Parent (Desig_Type)) - and then Nkind (Parent (Desig_Type)) = N_Full_Type_Declaration - and then - Nkind (Type_Definition (Parent (Desig_Type))) - = N_Unconstrained_Array_Definition - and then not Debug_Flag_6 + and then Present (Parent (Desig_Type)) + and then Nkind (Parent (Desig_Type)) = N_Full_Type_Declaration + and then Nkind (Type_Definition (Parent (Desig_Type))) = + N_Unconstrained_Array_Definition + and then not Debug_Flag_6 then Init_Size (E, 2 * System_Address_Size); @@ -2519,6 +2519,9 @@ package body Layout is or else Present (Enclosing_Subprogram (E))))) then Init_Size (E, 2 * System_Address_Size); + + -- Normal case of thin pointer + else Init_Size (E, System_Address_Size); end if; diff --git a/gcc/ada/lib-load.adb b/gcc/ada/lib-load.adb index 540bd63043c..eecf2a72498 100644 --- a/gcc/ada/lib-load.adb +++ b/gcc/ada/lib-load.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -216,7 +216,7 @@ package body Lib.Load is Generate_Code => False, Has_Allocator => False, Has_RACW => False, - Is_Compiler_Unit => False, + Filler => False, Ident_String => Empty, Loading => False, Main_Priority => Default_Main_Priority, @@ -323,7 +323,7 @@ package body Lib.Load is Generate_Code => False, Has_Allocator => False, Has_RACW => False, - Is_Compiler_Unit => False, + Filler => False, Ident_String => Empty, Loading => True, Main_Priority => Default_Main_Priority, @@ -687,7 +687,7 @@ package body Lib.Load is Generate_Code => False, Has_Allocator => False, Has_RACW => False, - Is_Compiler_Unit => False, + Filler => False, Ident_String => Empty, Loading => True, Main_Priority => Default_Main_Priority, diff --git a/gcc/ada/lib-writ.adb b/gcc/ada/lib-writ.adb index 48adf70c97a..cdddcf33c90 100644 --- a/gcc/ada/lib-writ.adb +++ b/gcc/ada/lib-writ.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -84,7 +84,7 @@ package body Lib.Writ is Generate_Code => False, Has_Allocator => False, Has_RACW => False, - Is_Compiler_Unit => False, + Filler => False, Ident_String => Empty, Loading => False, Main_Priority => -1, @@ -142,7 +142,7 @@ package body Lib.Writ is Generate_Code => False, Has_Allocator => False, Has_RACW => False, - Is_Compiler_Unit => False, + Filler => False, Ident_String => Empty, Loading => False, Main_Priority => -1, @@ -1445,7 +1445,7 @@ package body Lib.Writ is Write_Info_Str (Name_Buffer (1 .. Name_Len - 2)); end if; - -- If Source_Reference pragma used output information + -- If Source_Reference pragma used, output information if Num_SRef_Pragmas (Sind) > 0 then Write_Info_Char (' '); diff --git a/gcc/ada/lib-xref.adb b/gcc/ada/lib-xref.adb index ed1138927cf..283c0294a84 100644 --- a/gcc/ada/lib-xref.adb +++ b/gcc/ada/lib-xref.adb @@ -640,6 +640,11 @@ package body Lib.Xref is -- For the same reason we accept an implicit reference generated for -- a default in an instance. + -- We also set the referenced flag in a generic package that is not in + -- then main source unit, when the variable is of a formal private type, + -- to warn in the instance if the corresponding type is not a fully + -- initialized type. + if not In_Extended_Main_Source_Unit (N) then if Typ = 'e' or else Typ = 'I' @@ -657,6 +662,20 @@ package body Lib.Xref is and then (Typ = 'm' or else Typ = 'r' or else Typ = 's')) then null; + + elsif In_Instance_Body + and then In_Extended_Main_Code_Unit (N) + and then Is_Generic_Type (Etype (E)) + then + Set_Referenced (E); + return; + + elsif Inside_A_Generic + and then Is_Generic_Type (Etype (E)) + then + Set_Referenced (E); + return; + else return; end if; @@ -868,7 +887,7 @@ package body Lib.Xref is else Error_Msg_NE -- CODEFIX - ("?pragma Unreferenced given for&!", N, E); + ("??pragma Unreferenced given for&!", N, E); end if; end if; diff --git a/gcc/ada/lib.adb b/gcc/ada/lib.adb index 9ea496f3d26..826fcc99683 100644 --- a/gcc/ada/lib.adb +++ b/gcc/ada/lib.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -126,11 +126,6 @@ package body Lib is return Units.Table (U).Has_RACW; end Has_RACW; - function Is_Compiler_Unit (U : Unit_Number_Type) return Boolean is - begin - return Units.Table (U).Is_Compiler_Unit; - end Is_Compiler_Unit; - function Ident_String (U : Unit_Number_Type) return Node_Id is begin return Units.Table (U).Ident_String; @@ -221,14 +216,6 @@ package body Lib is Units.Table (U).Has_RACW := B; end Set_Has_RACW; - procedure Set_Is_Compiler_Unit - (U : Unit_Number_Type; - B : Boolean := True) - is - begin - Units.Table (U).Is_Compiler_Unit := B; - end Set_Is_Compiler_Unit; - procedure Set_Ident_String (U : Unit_Number_Type; N : Node_Id) is begin Units.Table (U).Ident_String := N; diff --git a/gcc/ada/lib.ads b/gcc/ada/lib.ads index 1b6898db60e..b5499df96f3 100644 --- a/gcc/ada/lib.ads +++ b/gcc/ada/lib.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -326,10 +326,6 @@ package Lib is -- (RACW) object. This is used for controlling generation of the RA -- attribute in the ali file. - -- Is_Compiler_Unit - -- A Boolean flag, initially set False by default, set to True if a - -- pragma Compiler_Unit_Warning appears in the unit. - -- Ident_String -- N_String_Literal node from a valid pragma Ident that applies to -- this unit. If no Ident pragma applies to the unit, then Empty. @@ -415,7 +411,6 @@ package Lib is function Ident_String (U : Unit_Number_Type) return Node_Id; function Has_Allocator (U : Unit_Number_Type) return Boolean; function Has_RACW (U : Unit_Number_Type) return Boolean; - function Is_Compiler_Unit (U : Unit_Number_Type) return Boolean; function Loading (U : Unit_Number_Type) return Boolean; function Main_CPU (U : Unit_Number_Type) return Int; function Main_Priority (U : Unit_Number_Type) return Int; @@ -434,7 +429,6 @@ package Lib is procedure Set_Generate_Code (U : Unit_Number_Type; B : Boolean := True); procedure Set_Has_RACW (U : Unit_Number_Type; B : Boolean := True); procedure Set_Has_Allocator (U : Unit_Number_Type; B : Boolean := True); - procedure Set_Is_Compiler_Unit (U : Unit_Number_Type; B : Boolean := True); procedure Set_Ident_String (U : Unit_Number_Type; N : Node_Id); procedure Set_Loading (U : Unit_Number_Type; B : Boolean := True); procedure Set_Main_CPU (U : Unit_Number_Type; P : Int); @@ -734,7 +728,6 @@ private pragma Inline (Generate_Code); pragma Inline (Has_Allocator); pragma Inline (Has_RACW); - pragma Inline (Is_Compiler_Unit); pragma Inline (Increment_Serial_Number); pragma Inline (Loading); pragma Inline (Main_CPU); @@ -774,8 +767,8 @@ private Fatal_Error : Boolean; Generate_Code : Boolean; Has_RACW : Boolean; - Is_Compiler_Unit : Boolean; Dynamic_Elab : Boolean; + Filler : Boolean; Loading : Boolean; Has_Allocator : Boolean; OA_Setting : Character; @@ -805,7 +798,7 @@ private Generate_Code at 57 range 0 .. 7; Has_RACW at 58 range 0 .. 7; Dynamic_Elab at 59 range 0 .. 7; - Is_Compiler_Unit at 60 range 0 .. 7; + Filler at 60 range 0 .. 7; OA_Setting at 61 range 0 .. 7; Loading at 62 range 0 .. 7; Has_Allocator at 63 range 0 .. 7; diff --git a/gcc/ada/make.adb b/gcc/ada/make.adb index e8acb4e604a..74be6988cfa 100644 --- a/gcc/ada/make.adb +++ b/gcc/ada/make.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -3728,6 +3728,13 @@ package body Make is Inform (Data.Lib_File, "WARNING: ALI or object file not found after compile"); + + if not Is_Regular_File + (Get_Name_String (Name_Id (Data.Full_Lib_File))) + then + Inform (Data.Full_Lib_File, "not found"); + end if; + Record_Failure (Data.Full_Source_File, Data.Source_Unit); end if; end if; @@ -5320,7 +5327,7 @@ package body Make is if Compute_Builder then Do_Compute_Builder_Switches (Project_Tree => Project_Tree, - Root_Environment => Root_Environment, + Env => Root_Environment, Main_Project => Main_Project, Only_For_Lang => Name_Ada); diff --git a/gcc/ada/makeutl.adb b/gcc/ada/makeutl.adb index d9772510cac..45189597806 100644 --- a/gcc/ada/makeutl.adb +++ b/gcc/ada/makeutl.adb @@ -309,10 +309,10 @@ package body Makeutl is if Replacement /= No_File then if Verbose_Mode then Write_Line - ("source file" & - Get_Name_String (SD.Sfile) & - " has been replaced by " & - Get_Name_String (Replacement)); + ("source file" + & Get_Name_String (SD.Sfile) + & " has been replaced by " + & Get_Name_String (Replacement)); end if; return No_Name; @@ -648,10 +648,10 @@ package body Makeutl is if Sw (J) = Directory_Separator then Switch := new String' - (Sw (1 .. Start - 1) & - Parent & - Directory_Separator & - Sw (Start .. Sw'Last)); + (Sw (1 .. Start - 1) + & Parent + & Directory_Separator + & Sw (Start .. Sw'Last)); return; end if; end loop; @@ -659,10 +659,10 @@ package body Makeutl is else Switch := new String' - (Sw (1 .. Start - 1) & - Parent & - Directory_Separator & - Sw (Start .. Sw'Last)); + (Sw (1 .. Start - 1) + & Parent + & Directory_Separator + & Sw (Start .. Sw'Last)); end if; end if; @@ -1999,8 +1999,8 @@ package body Makeutl is if Project.Library then Fail_Program (Tree, - "cannot specify a main program " & - "for a library project file"); + "cannot specify a main program " + & "for a library project file"); end if; Add_Main (Name => Get_Name_String (Element.Value), @@ -2118,8 +2118,8 @@ package body Makeutl is if Names.Last = 0 then Fail_Program (Project_Tree, - "cannot specify a multi-unit index but no main " & - "on the command line"); + "cannot specify a multi-unit index but no main " + & "on the command line"); elsif Names.Last > 1 then Fail_Program @@ -3153,10 +3153,10 @@ package body Makeutl is if Current_Verbosity = High then Debug_Output ("compilation phases: " & " compile=" & Data.Need_Compilation'Img - & " bind=" & Data.Need_Binding'Img - & " link=" & Data.Need_Linking'Img + & " bind=" & Data.Need_Binding'Img + & " link=" & Data.Need_Linking'Img & " closure=" & Data.Closure_Needed'Img - & " mains=" & Data.Number_Of_Mains'Img, + & " mains=" & Data.Number_Of_Mains'Img, Project.Name); end if; end Do_Compute; @@ -3173,7 +3173,7 @@ package body Makeutl is procedure Compute_Builder_Switches (Project_Tree : Project_Tree_Ref; - Root_Environment : in out Prj.Tree.Environment; + Env : in out Prj.Tree.Environment; Main_Project : Project_Id; Only_For_Lang : Name_Id := No_Name) is @@ -3312,14 +3312,13 @@ package body Makeutl is and then Default_Switches_Array /= No_Array then Prj.Err.Error_Msg - (Root_Environment.Flags, - "Default_Switches forbidden in presence of " & - "Global_Compilation_Switches. Use Switches instead.", + (Env.Flags, + "Default_Switches forbidden in presence of " + & "Global_Compilation_Switches. Use Switches instead.", Project_Tree.Shared.Arrays.Table (Default_Switches_Array).Location); Fail_Program - (Project_Tree, - "*** illegal combination of Builder attributes"); + (Project_Tree, "*** illegal combination of Builder attributes"); end if; if Lang /= No_Name then @@ -3432,15 +3431,15 @@ package body Makeutl is Name_Len := Name_Len + Name_Len; Prj.Err.Error_Msg - (Root_Environment.Flags, - '"' & Name_Buffer (1 .. Name_Len) & - """ is not a builder switch. Consider moving " & - "it to Global_Compilation_Switches.", + (Env.Flags, + '"' & Name_Buffer (1 .. Name_Len) + & """ is not a builder switch. Consider moving " + & "it to Global_Compilation_Switches.", Element.Location); Fail_Program (Project_Tree, - "*** illegal switch """ & - Get_Name_String (Element.Value) & '"'); + "*** illegal switch """ + & Get_Name_String (Element.Value) & '"'); end if; end if; diff --git a/gcc/ada/makeutl.ads b/gcc/ada/makeutl.ads index 88c9c988cbe..370f32ae14e 100644 --- a/gcc/ada/makeutl.ads +++ b/gcc/ada/makeutl.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2004-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2004-2014, 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- -- @@ -323,7 +323,7 @@ package Makeutl is procedure Compute_Builder_Switches (Project_Tree : Project_Tree_Ref; - Root_Environment : in out Prj.Tree.Environment; + Env : in out Prj.Tree.Environment; Main_Project : Project_Id; Only_For_Lang : Name_Id := No_Name); -- Compute the builder switches and global compilation switches. Every time diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads index ecefdadc6df..cbd1045d822 100644 --- a/gcc/ada/opt.ads +++ b/gcc/ada/opt.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -137,12 +137,11 @@ package Opt is Ada_Version_Explicit : Ada_Version_Type := Ada_Version_Default; -- GNAT - -- Like Ada_Version, but does not get set implicitly for predefined - -- or internal units, so it reflects the Ada version explicitly set - -- using configuration pragmas or compiler switches (or if neither - -- appears, it remains set to Ada_Version_Default). This is used in - -- the rare cases (notably for pragmas Preelaborate_05 and Pure_05/12) - -- where in the run-time we want the explicit version set. + -- Like Ada_Version, but does not get set implicitly for predefined or + -- internal units, so it reflects the Ada version explicitly set using + -- configuration pragmas or compiler switches (or if neither appears, it + -- remains set to Ada_Version_Default). This is used in the rare cases + -- (notably pragma Obsolescent) where we want the explicit version set. Ada_Version_Runtime : Ada_Version_Type := Ada_2012; -- GNAT @@ -376,6 +375,15 @@ package Opt is -- set to True to delete only the files produced by the compiler but not -- the library files or the executable files. + Compiler_Unit : Boolean := False; + -- GNAT1 + -- Set True by an occurrence of pragma Compiler_Unit_Warning (or of the + -- obsolete pragma Compiler_Unit) in the main unit. Once set True, stays + -- True, since any units that are with'ed directly or indirectly by + -- a Compiler_Unit_Warning main unit are subject to the same restrictions. + -- Such units really should have their own pragmas, but we do not bother to + -- check for that, so this transitivity provides extra checking. + Config_File : Boolean := True; -- GNAT -- Set to False to inhibit reading and processing of gnat.adc file diff --git a/gcc/ada/par-ch5.adb b/gcc/ada/par-ch5.adb index 517e58a3d4e..1d5504df922 100644 --- a/gcc/ada/par-ch5.adb +++ b/gcc/ada/par-ch5.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -240,6 +240,10 @@ package body Ch5 is and then Statement_Seen) or else All_Pragmas) then + -- This Ada 2012 construct not allowed in a compiler unit + + Check_Compiler_Unit ("null statement list", Token_Ptr); + declare Null_Stm : constant Node_Id := Make_Null_Statement (Token_Ptr); diff --git a/gcc/ada/par-ch7.adb b/gcc/ada/par-ch7.adb index 0a658c963e1..dd4bdb4b329 100644 --- a/gcc/ada/par-ch7.adb +++ b/gcc/ada/par-ch7.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -270,7 +270,7 @@ package body Ch7 is if Aspect_Sloc /= No_Location and then not Aspect_Specifications_Present then - Error_Msg_SC ("\info: aspect specifications belong here"); + Error_Msg_SC ("info: aspect specifications belong here??"); Move_Aspects (From => Dummy_Node, To => Package_Node); end if; diff --git a/gcc/ada/par-endh.adb b/gcc/ada/par-endh.adb index d22cce2a534..3c065ec9fb9 100644 --- a/gcc/ada/par-endh.adb +++ b/gcc/ada/par-endh.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -412,7 +412,7 @@ package body Endh is Error_Msg_SC ("misplaced aspects for package declaration"); Error_Msg - ("info: aspect specifications belong here", Is_Loc); + ("info: aspect specifications belong here??", Is_Loc); P_Aspect_Specifications (Empty); -- Other cases where aspect specifications are not allowed diff --git a/gcc/ada/par-prag.adb b/gcc/ada/par-prag.adb index 32b8fb7817a..61ba85903e8 100644 --- a/gcc/ada/par-prag.adb +++ b/gcc/ada/par-prag.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -354,6 +354,22 @@ begin Ada_Version_Pragma := Pragma_Node; end if; + --------------------------- + -- Compiler_Unit_Warning -- + --------------------------- + + -- This pragma must be processed at parse time, since the resulting + -- status may be tested during the parsing of the program. + + when Pragma_Compiler_Unit | Pragma_Compiler_Unit_Warning => + Check_Arg_Count (0); + + -- Only recognized in main unit + + if Current_Source_Unit = Main_Unit then + Compiler_Unit := True; + end if; + ----------- -- Debug -- ----------- @@ -1153,8 +1169,6 @@ begin Pragma_CIL_Constructor | Pragma_Compile_Time_Error | Pragma_Compile_Time_Warning | - Pragma_Compiler_Unit | - Pragma_Compiler_Unit_Warning | Pragma_Contract_Cases | Pragma_Convention_Identifier | Pragma_CPP_Class | @@ -1271,7 +1285,6 @@ begin Pragma_Precondition | Pragma_Predicate | Pragma_Preelaborate | - Pragma_Preelaborate_05 | Pragma_Pre_Class | Pragma_Priority | Pragma_Priority_Specific_Dispatching | @@ -1281,8 +1294,6 @@ begin Pragma_Provide_Shift_Operators | Pragma_Psect_Object | Pragma_Pure | - Pragma_Pure_05 | - Pragma_Pure_12 | Pragma_Pure_Function | Pragma_Queuing_Policy | Pragma_Refined_Depends | diff --git a/gcc/ada/prj-conf.adb b/gcc/ada/prj-conf.adb index b0dfceb6b62..1becd7028c3 100644 --- a/gcc/ada/prj-conf.adb +++ b/gcc/ada/prj-conf.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2006-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2006-2014, 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- -- @@ -721,7 +721,7 @@ package body Prj.Conf is Set_Runtime_For (Name_Ada, Name_Buffer (7 .. Name_Len)); - Locate_Runtime (Name_Ada, Project_Tree); + Locate_Runtime (Name_Ada, Project_Tree, Env); end if; elsif Name_Len > 7 @@ -748,7 +748,7 @@ package body Prj.Conf is if not Runtime_Name_Set_For (Lang) then Set_Runtime_For (Lang, RTS); - Locate_Runtime (Lang, Project_Tree); + Locate_Runtime (Lang, Project_Tree, Env); end if; end; end if; @@ -1518,7 +1518,8 @@ package body Prj.Conf is procedure Locate_Runtime (Language : Name_Id; - Project_Tree : Prj.Project_Tree_Ref) + Project_Tree : Prj.Project_Tree_Ref; + Env : Prj.Tree.Environment) is function Is_Base_Name (Path : String) return Boolean; -- Returns True if Path has no directory separator @@ -1551,7 +1552,7 @@ package body Prj.Conf is begin if not Is_Base_Name (RTS_Name) then Full_Path := - Find_Rts_In_Path (Root_Environment.Project_Path, RTS_Name); + Find_Rts_In_Path (Env.Project_Path, RTS_Name); if Full_Path = null then Fail_Program (Project_Tree, "cannot find RTS " & RTS_Name); diff --git a/gcc/ada/prj-conf.ads b/gcc/ada/prj-conf.ads index 70382c3da83..df830ad93b6 100644 --- a/gcc/ada/prj-conf.ads +++ b/gcc/ada/prj-conf.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2006-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2006-2014, 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- -- @@ -218,7 +218,8 @@ package Prj.Conf is procedure Locate_Runtime (Language : Name_Id; - Project_Tree : Prj.Project_Tree_Ref); + Project_Tree : Prj.Project_Tree_Ref; + Env : Prj.Tree.Environment); -- If RTS_Name is a base name (a name without path separator), then -- do nothing. Otherwise, convert it to an absolute path (possibly by -- searching it in the project path) and call Set_Runtime_For with the diff --git a/gcc/ada/restrict.adb b/gcc/ada/restrict.adb index 78591c1efcd..8983f78ee1c 100644 --- a/gcc/ada/restrict.adb +++ b/gcc/ada/restrict.adb @@ -168,10 +168,17 @@ package body Restrict is -- Check_Compiler_Unit -- ------------------------- - procedure Check_Compiler_Unit (N : Node_Id) is + procedure Check_Compiler_Unit (Feature : String; N : Node_Id) is begin - if Is_Compiler_Unit (Get_Source_Unit (N)) then - Error_Msg_N ("use of construct not allowed in compiler!!??", N); + if Compiler_Unit then + Error_Msg_N (Feature & " not allowed in compiler unit!!??", N); + end if; + end Check_Compiler_Unit; + + procedure Check_Compiler_Unit (Feature : String; Loc : Source_Ptr) is + begin + if Compiler_Unit then + Error_Msg (Feature & " not allowed in compiler unit!!??", Loc); end if; end Check_Compiler_Unit; @@ -274,72 +281,6 @@ package body Restrict is Check_Restriction (No_Implicit_Heap_Allocations, N); end Check_No_Implicit_Heap_Alloc; - ------------------------------------------- - -- Check_Restriction_No_Use_Of_Attribute -- - -------------------------------------------- - - procedure Check_Restriction_No_Use_Of_Attribute (N : Node_Id) is - Id : constant Name_Id := Chars (N); - A_Id : constant Attribute_Id := Get_Attribute_Id (Id); - - begin - -- Ignore call if node N is not in the main source unit, since we only - -- give messages for the main unit. This avoids giving messages for - -- aspects that are specified in withed units. - - if not In_Extended_Main_Source_Unit (N) then - return; - end if; - - -- If nothing set, nothing to check - - if not No_Use_Of_Attribute_Set then - return; - end if; - - Error_Msg_Sloc := No_Use_Of_Attribute (A_Id); - - if Error_Msg_Sloc /= No_Location then - Error_Msg_Node_1 := N; - Error_Msg_Warn := No_Use_Of_Attribute_Warning (A_Id); - Error_Msg_N - ("<*<violation of restriction `No_Use_Of_Attribute '='> &`#", N); - end if; - end Check_Restriction_No_Use_Of_Attribute; - - ---------------------------------------- - -- Check_Restriction_No_Use_Of_Pragma -- - ---------------------------------------- - - procedure Check_Restriction_No_Use_Of_Pragma (N : Node_Id) is - Id : constant Node_Id := Pragma_Identifier (N); - P_Id : constant Pragma_Id := Get_Pragma_Id (Chars (Id)); - - begin - -- Ignore call if node N is not in the main source unit, since we only - -- give messages for the main unit. This avoids giving messages for - -- aspects that are specified in withed units. - - if not In_Extended_Main_Source_Unit (N) then - return; - end if; - - -- If nothing set, nothing to check - - if not No_Use_Of_Pragma_Set then - return; - end if; - - Error_Msg_Sloc := No_Use_Of_Pragma (P_Id); - - if Error_Msg_Sloc /= No_Location then - Error_Msg_Node_1 := Id; - Error_Msg_Warn := No_Use_Of_Pragma_Warning (P_Id); - Error_Msg_N - ("<*<violation of restriction `No_Use_Of_Pragma '='> &`#", Id); - end if; - end Check_Restriction_No_Use_Of_Pragma; - ----------------------------------- -- Check_Obsolescent_2005_Entity -- ----------------------------------- @@ -696,6 +637,72 @@ package body Restrict is end if; end Check_Restriction_No_Specification_Of_Aspect; + ------------------------------------------- + -- Check_Restriction_No_Use_Of_Attribute -- + -------------------------------------------- + + procedure Check_Restriction_No_Use_Of_Attribute (N : Node_Id) is + Id : constant Name_Id := Chars (N); + A_Id : constant Attribute_Id := Get_Attribute_Id (Id); + + begin + -- Ignore call if node N is not in the main source unit, since we only + -- give messages for the main unit. This avoids giving messages for + -- aspects that are specified in withed units. + + if not In_Extended_Main_Source_Unit (N) then + return; + end if; + + -- If nothing set, nothing to check + + if not No_Use_Of_Attribute_Set then + return; + end if; + + Error_Msg_Sloc := No_Use_Of_Attribute (A_Id); + + if Error_Msg_Sloc /= No_Location then + Error_Msg_Node_1 := N; + Error_Msg_Warn := No_Use_Of_Attribute_Warning (A_Id); + Error_Msg_N + ("<*<violation of restriction `No_Use_Of_Attribute '='> &`#", N); + end if; + end Check_Restriction_No_Use_Of_Attribute; + + ---------------------------------------- + -- Check_Restriction_No_Use_Of_Pragma -- + ---------------------------------------- + + procedure Check_Restriction_No_Use_Of_Pragma (N : Node_Id) is + Id : constant Node_Id := Pragma_Identifier (N); + P_Id : constant Pragma_Id := Get_Pragma_Id (Chars (Id)); + + begin + -- Ignore call if node N is not in the main source unit, since we only + -- give messages for the main unit. This avoids giving messages for + -- aspects that are specified in withed units. + + if not In_Extended_Main_Source_Unit (N) then + return; + end if; + + -- If nothing set, nothing to check + + if not No_Use_Of_Pragma_Set then + return; + end if; + + Error_Msg_Sloc := No_Use_Of_Pragma (P_Id); + + if Error_Msg_Sloc /= No_Location then + Error_Msg_Node_1 := Id; + Error_Msg_Warn := No_Use_Of_Pragma_Warning (P_Id); + Error_Msg_N + ("<*<violation of restriction `No_Use_Of_Pragma '='> &`#", Id); + end if; + end Check_Restriction_No_Use_Of_Pragma; + -------------------------------------- -- Check_Wide_Character_Restriction -- -------------------------------------- diff --git a/gcc/ada/restrict.ads b/gcc/ada/restrict.ads index 882cb84b44e..b6c93f8a7d7 100644 --- a/gcc/ada/restrict.ads +++ b/gcc/ada/restrict.ads @@ -192,10 +192,15 @@ package Restrict is -- For abort to be allowed, either No_Abort_Statements must be False, -- or Max_Asynchronous_Select_Nesting must be non-zero. - procedure Check_Compiler_Unit (N : Node_Id); - -- If unit N is in a unit that has a pragma Compiler_Unit, then a message - -- is posted on node N noting use of a construct that is not permitted in - -- the compiler. + procedure Check_Compiler_Unit (Feature : String; N : Node_Id); + -- If unit N is in a unit that has a pragma Compiler_Unit_Warning, then + -- a message is posted on node N noting use of the given feature is not + -- permitted in the compiler (bootstrap considerations). + + procedure Check_Compiler_Unit (Feature : String; Loc : Source_Ptr); + -- If unit N is in a unit that has a pragma Compiler_Unit_Warning, then a + -- message is posted at location Loc noting use of the given feature is not + -- permitted in the compiler (bootstrap considerations). procedure Check_Restricted_Unit (U : Unit_Name_Type; N : Node_Id); -- Checks if loading of unit U is prohibited by the setting of some diff --git a/gcc/ada/s-excdeb.ads b/gcc/ada/s-excdeb.ads index 4dd94c20583..9984d7b37a9 100644 --- a/gcc/ada/s-excdeb.ads +++ b/gcc/ada/s-excdeb.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2006-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2006-2014, 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- -- @@ -39,7 +39,7 @@ with System.Standard_Library; package System.Exceptions_Debug is - pragma Preelaborate_05; + pragma Preelaborate; -- To let Ada.Exceptions "with" us and let us "with" Standard_Library package SSL renames System.Standard_Library; diff --git a/gcc/ada/s-except.ads b/gcc/ada/s-except.ads index 8bf0284ab19..e88a1572b2d 100644 --- a/gcc/ada/s-except.ads +++ b/gcc/ada/s-except.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2006-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2006-2014, 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- -- @@ -33,7 +33,7 @@ pragma Compiler_Unit_Warning; package System.Exceptions is - pragma Preelaborate_05; + pragma Preelaborate; -- To let Ada.Exceptions "with" us and let us "with" Standard_Library ZCX_By_Default : constant Boolean; diff --git a/gcc/ada/s-exctab.adb b/gcc/ada/s-exctab.adb index a94d99a4eba..23a48158092 100644 --- a/gcc/ada/s-exctab.adb +++ b/gcc/ada/s-exctab.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1996-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1996-2014, 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- -- @@ -31,71 +31,167 @@ pragma Compiler_Unit_Warning; -with System.HTable; -with System.Soft_Links; use System.Soft_Links; +with System.Soft_Links; use System.Soft_Links; package body System.Exception_Table is use System.Standard_Library; - type HTable_Headers is range 1 .. 37; - - procedure Set_HT_Link (T : Exception_Data_Ptr; Next : Exception_Data_Ptr); - function Get_HT_Link (T : Exception_Data_Ptr) return Exception_Data_Ptr; - - function Hash (F : System.Address) return HTable_Headers; - function Equal (A, B : System.Address) return Boolean; - function Get_Key (T : Exception_Data_Ptr) return System.Address; - - package Exception_HTable is new System.HTable.Static_HTable ( - Header_Num => HTable_Headers, - Element => Exception_Data, - Elmt_Ptr => Exception_Data_Ptr, - Null_Ptr => null, - Set_Next => Set_HT_Link, - Next => Get_HT_Link, - Key => System.Address, - Get_Key => Get_Key, - Hash => Hash, - Equal => Equal); - - ----------- - -- Equal -- - ----------- - - function Equal (A, B : System.Address) return Boolean is - S1 : constant Big_String_Ptr := To_Ptr (A); - S2 : constant Big_String_Ptr := To_Ptr (B); - J : Integer := 1; + type Hash_Val is mod 2 ** 8; + subtype Hash_Idx is Hash_Val range 1 .. 37; + + HTable : array (Hash_Idx) of aliased Exception_Data_Ptr; + -- Actual hash table containing all registered exceptions + -- + -- The table is very small and the hash function weak, as looking up + -- registered exceptions is rare and minimizing space and time overhead + -- of registration is more important. In addition, it is expected that the + -- exceptions that need to be looked up are registered dynamically, and + -- therefore will be at the begin of the hash chains. + -- + -- The table differs from System.HTable.Static_HTable in that the final + -- element of each chain is not marked by null, but by a pointer to self. + -- This way it is possible to defend against the same entry being inserted + -- twice, without having to do a lookup which is relatively expensive for + -- programs with large number + -- + -- All non-local subprograms use the global Task_Lock to protect against + -- concurrent use of the exception table. This is needed as local + -- exceptions may be declared concurrently with those declared at the + -- library level. + + -- Local Subprograms + + generic + with procedure Process (T : Exception_Data_Ptr; More : out Boolean); + procedure Iterate; + -- Iterate over all + + function Lookup (Name : String) return Exception_Data_Ptr; + -- Find and return the Exception_Data of the exception with the given Name + -- (which must be in all uppercase), or null if none was registered. + + procedure Register (Item : Exception_Data_Ptr); + -- Register an exception with the given Exception_Data in the table. + + function Has_Name (Item : Exception_Data_Ptr; Name : String) return Boolean; + -- Return True iff Item.Full_Name and Name are equal. Both names are + -- assumed to be in all uppercase and end with ASCII.NUL. + + function Hash (S : String) return Hash_Idx; + -- Return the index in the hash table for S, which is assumed to be all + -- uppercase and end with ASCII.NUL. + + -------------- + -- Has_Name -- + -------------- + + function Has_Name (Item : Exception_Data_Ptr; Name : String) return Boolean + is + S : constant Big_String_Ptr := To_Ptr (Item.Full_Name); + J : Integer := S'First; + begin - loop - if S1 (J) /= S2 (J) then + for K in Name'Range loop + + -- Note that as both items are terminated with ASCII.NUL, the + -- comparison below must fail for strings of different lengths. + + if S (J) /= Name (K) then return False; - elsif S1 (J) = ASCII.NUL then - return True; - else - J := J + 1; end if; + + J := J + 1; end loop; - end Equal; - ----------------- - -- Get_HT_Link -- - ----------------- + return True; + end Has_Name; + + ------------ + -- Lookup -- + ------------ + + function Lookup (Name : String) return Exception_Data_Ptr is + Prev : Exception_Data_Ptr; + Curr : Exception_Data_Ptr; + + begin + Curr := HTable (Hash (Name)); + Prev := null; + while Curr /= Prev loop + if Has_Name (Curr, Name) then + return Curr; + end if; + + Prev := Curr; + Curr := Curr.HTable_Ptr; + end loop; + + return null; + end Lookup; + + ---------- + -- Hash -- + ---------- + + function Hash (S : String) return Hash_Idx is + Hash : Hash_Val := 0; - function Get_HT_Link (T : Exception_Data_Ptr) return Exception_Data_Ptr is begin - return T.HTable_Ptr; - end Get_HT_Link; + for J in S'Range loop + exit when S (J) = ASCII.NUL; + Hash := Hash xor Character'Pos (S (J)); + end loop; + + return Hash_Idx'First + Hash mod (Hash_Idx'Last - Hash_Idx'First + 1); + end Hash; ------------- - -- Get_Key -- + -- Iterate -- ------------- - function Get_Key (T : Exception_Data_Ptr) return System.Address is + procedure Iterate is + More : Boolean; + Prev, Curr : Exception_Data_Ptr; + begin - return T.Full_Name; - end Get_Key; + Outer : for Idx in HTable'Range loop + Prev := null; + Curr := HTable (Idx); + + while Curr /= Prev loop + Process (Curr, More); + + exit Outer when not More; + + Prev := Curr; + Curr := Curr.HTable_Ptr; + end loop; + end loop Outer; + end Iterate; + + -------------- + -- Register -- + -------------- + + procedure Register (Item : Exception_Data_Ptr) is + begin + if Item.HTable_Ptr = null then + Prepend_To_Chain : declare + Chain : Exception_Data_Ptr + renames HTable (Hash (To_Ptr (Item.Full_Name).all)); + + begin + if Chain = null then + Item.HTable_Ptr := Item; + else + Item.HTable_Ptr := Chain; + end if; + + Chain := Item; + end Prepend_To_Chain; + end if; + end Register; ------------------------------- -- Get_Registered_Exceptions -- @@ -105,44 +201,40 @@ package body System.Exception_Table is (List : out Exception_Data_Array; Last : out Integer) is - Data : Exception_Data_Ptr := Exception_HTable.Get_First; + procedure Get_One (Item : Exception_Data_Ptr; More : out Boolean); + -- Add Item to List (List'First .. Last) by first incrementing Last + -- and storing Item in List (Last). Last should be in List'First - 1 + -- and List'Last. - begin - Lock_Task.all; - Last := List'First - 1; + procedure Get_All is new Iterate (Get_One); + -- Store all registered exceptions in List, updating Last - while Last < List'Last and then Data /= null loop - Last := Last + 1; - List (Last) := Data; - Data := Exception_HTable.Get_Next; - end loop; + ------------- + -- Get_One -- + ------------- - Unlock_Task.all; - end Get_Registered_Exceptions; + procedure Get_One (Item : Exception_Data_Ptr; More : out Boolean) is + begin + if Last < List'Last then + Last := Last + 1; + List (Last) := Item; + More := True; - ---------- - -- Hash -- - ---------- + else + More := False; + end if; + end Get_One; - function Hash (F : System.Address) return HTable_Headers is - type S is mod 2**8; + begin + -- In this routine the invariant is that List (List'First .. Last) + -- contains the registered exceptions retrieved so far. - Str : constant Big_String_Ptr := To_Ptr (F); - Size : constant S := S (HTable_Headers'Last - HTable_Headers'First + 1); - Tmp : S := 0; - J : Positive; + Last := List'First - 1; - begin - J := 1; - loop - if Str (J) = ASCII.NUL then - return HTable_Headers'First + HTable_Headers'Base (Tmp mod Size); - else - Tmp := Tmp xor S (Character'Pos (Str (J))); - end if; - J := J + 1; - end loop; - end Hash; + Lock_Task.all; + Get_All; + Unlock_Task.all; + end Get_Registered_Exceptions; ------------------------ -- Internal_Exception -- @@ -152,25 +244,30 @@ package body System.Exception_Table is (X : String; Create_If_Not_Exist : Boolean := True) return Exception_Data_Ptr is + -- If X was not yet registered and Create_if_Not_Exist is True, + -- dynamically allocate and register a new exception. + type String_Ptr is access all String; - Copy : aliased String (X'First .. X'Last + 1); - Res : Exception_Data_Ptr; Dyn_Copy : String_Ptr; + Copy : aliased String (X'First .. X'Last + 1); + Result : Exception_Data_Ptr; begin + Lock_Task.all; + Copy (X'Range) := X; Copy (Copy'Last) := ASCII.NUL; - Res := Exception_HTable.Get (Copy'Address); + Result := Lookup (Copy); -- If unknown exception, create it on the heap. This is a legitimate - -- situation in the distributed case when an exception is defined only - -- in a partition + -- situation in the distributed case when an exception is defined + -- only in a partition - if Res = null and then Create_If_Not_Exist then + if Result = null and then Create_If_Not_Exist then Dyn_Copy := new String'(Copy); - Res := + Result := new Exception_Data' (Not_Handled_By_Others => False, Lang => 'A', @@ -180,10 +277,12 @@ package body System.Exception_Table is Foreign_Data => Null_Address, Raise_Hook => null); - Register_Exception (Res); + Register (Result); end if; - return Res; + Unlock_Task.all; + + return Result; end Internal_Exception; ------------------------ @@ -192,7 +291,9 @@ package body System.Exception_Table is procedure Register_Exception (X : Exception_Data_Ptr) is begin - Exception_HTable.Set (X); + Lock_Task.all; + Register (X); + Unlock_Task.all; end Register_Exception; --------------------------------- @@ -201,43 +302,38 @@ package body System.Exception_Table is function Registered_Exceptions_Count return Natural is Count : Natural := 0; - Data : Exception_Data_Ptr := Exception_HTable.Get_First; - begin - -- We need to lock the runtime in the meantime, to avoid concurrent - -- access since we have only one iterator. - - Lock_Task.all; + procedure Count_Item (Item : Exception_Data_Ptr; More : out Boolean); + -- Update Count for given Item - while Data /= null loop + procedure Count_Item (Item : Exception_Data_Ptr; More : out Boolean) is + pragma Unreferenced (Item); + begin Count := Count + 1; - Data := Exception_HTable.Get_Next; - end loop; + More := Count < Natural'Last; + end Count_Item; - Unlock_Task.all; - return Count; - end Registered_Exceptions_Count; - - ----------------- - -- Set_HT_Link -- - ----------------- + procedure Count_All is new Iterate (Count_Item); - procedure Set_HT_Link - (T : Exception_Data_Ptr; - Next : Exception_Data_Ptr) - is begin - T.HTable_Ptr := Next; - end Set_HT_Link; + Lock_Task.all; + Count_All; + Unlock_Task.all; --- Register the standard exceptions at elaboration time + return Count; + end Registered_Exceptions_Count; begin - Register_Exception (Abort_Signal_Def'Access); - Register_Exception (Tasking_Error_Def'Access); - Register_Exception (Storage_Error_Def'Access); - Register_Exception (Program_Error_Def'Access); - Register_Exception (Numeric_Error_Def'Access); - Register_Exception (Constraint_Error_Def'Access); - + -- Register the standard exceptions at elaboration time + + -- We don't need to use the locking version here as the elaboration + -- will not be concurrent and no tasks can call any subprograms of this + -- unit before it has been elaborated. + + Register (Abort_Signal_Def'Access); + Register (Tasking_Error_Def'Access); + Register (Storage_Error_Def'Access); + Register (Program_Error_Def'Access); + Register (Numeric_Error_Def'Access); + Register (Constraint_Error_Def'Access); end System.Exception_Table; diff --git a/gcc/ada/s-expmod.adb b/gcc/ada/s-expmod.adb index ecd736f2072..aa1aa11c62f 100644 --- a/gcc/ada/s-expmod.adb +++ b/gcc/ada/s-expmod.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2009 Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -30,35 +30,27 @@ ------------------------------------------------------------------------------ package body System.Exp_Mod is + use System.Unsigned_Types; ----------------- -- Exp_Modular -- ----------------- function Exp_Modular - (Left : Integer; - Modulus : Integer; - Right : Natural) - return Integer + (Left : Unsigned; + Modulus : Unsigned; + Right : Natural) return Unsigned is - Result : Integer := 1; - Factor : Integer := Left; + Result : Unsigned := 1; + Factor : Unsigned := Left; Exp : Natural := Right; - function Mult (X, Y : Integer) return Integer; - pragma Inline (Mult); + function Mult (X, Y : Unsigned) return Unsigned is + (Unsigned (Long_Long_Unsigned (X) * Long_Long_Unsigned (Y) + mod Long_Long_Unsigned (Modulus))); -- Modular multiplication. Note that we can't take advantage of the -- compiler's circuit, because the modulus is not known statically. - function Mult (X, Y : Integer) return Integer is - begin - return Integer - (Long_Long_Integer (X) * Long_Long_Integer (Y) - mod Long_Long_Integer (Modulus)); - end Mult; - - -- Start of processing for Exp_Modular - begin -- We use the standard logarithmic approach, Exp gets shifted right -- testing successive low order bits and Factor is the value of the diff --git a/gcc/ada/s-expmod.ads b/gcc/ada/s-expmod.ads index 73d845c8ee3..3dd118d5e9f 100644 --- a/gcc/ada/s-expmod.ads +++ b/gcc/ada/s-expmod.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -33,13 +33,14 @@ -- modulus values. Arithmetic is done in Long_Long_Unsigned, with explicit -- accounting for the modulus value which is passed as the second argument. +with System.Unsigned_Types; + package System.Exp_Mod is pragma Pure; function Exp_Modular - (Left : Integer; - Modulus : Integer; - Right : Natural) - return Integer; + (Left : System.Unsigned_Types.Unsigned; + Modulus : System.Unsigned_Types.Unsigned; + Right : Natural) return System.Unsigned_Types.Unsigned; end System.Exp_Mod; diff --git a/gcc/ada/s-solita.adb b/gcc/ada/s-solita.adb index 19a422a81df..a8f101d0fd8 100644 --- a/gcc/ada/s-solita.adb +++ b/gcc/ada/s-solita.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2004-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2004-2014, 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- -- @@ -95,7 +95,11 @@ package body System.Soft_Links.Tasking is function Get_Sec_Stack_Addr return Address is begin - return STPO.Self.Common.Compiler_Data.Sec_Stack_Addr; + return Result : constant Address := + STPO.Self.Common.Compiler_Data.Sec_Stack_Addr + do + pragma Assert (Result /= Null_Address); + end return; end Get_Sec_Stack_Addr; function Get_Stack_Info return Stack_Checking.Stack_Access is @@ -222,6 +226,8 @@ package body System.Soft_Links.Tasking is SSL.Set_Sec_Stack_Addr (SSL.Get_Sec_Stack_Addr_NT); SSL.Set_Jmpbuf_Address (SSL.Get_Jmpbuf_Address_NT); end if; + + pragma Assert (Get_Sec_Stack_Addr /= Null_Address); end Init_Tasking_Soft_Links; end System.Soft_Links.Tasking; diff --git a/gcc/ada/s-solita.ads b/gcc/ada/s-solita.ads index d91568149a9..0e987ea0bab 100644 --- a/gcc/ada/s-solita.ads +++ b/gcc/ada/s-solita.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2009, Free Software Foundation, Inc. -- +-- Copyright (C) 2009-2014, 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- -- @@ -38,6 +38,7 @@ package System.Soft_Links.Tasking is procedure Init_Tasking_Soft_Links; -- Set the tasking soft links that are common to the full and the - -- restricted run times. + -- restricted run times. Clients need to make sure the body of + -- System.Secondary_Stack is elaborated before calling this. end System.Soft_Links.Tasking; diff --git a/gcc/ada/s-stalib.ads b/gcc/ada/s-stalib.ads index e38f36e5567..520fb3c92d1 100644 --- a/gcc/ada/s-stalib.ads +++ b/gcc/ada/s-stalib.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -54,7 +54,7 @@ with Ada.Unchecked_Conversion; package System.Standard_Library is pragma Warnings (Off); - pragma Preelaborate_05; + pragma Preelaborate; pragma Warnings (On); subtype Big_String is String (1 .. Positive'Last); diff --git a/gcc/ada/s-taprob.adb b/gcc/ada/s-taprob.adb index ab0557d86dd..755b772260a 100644 --- a/gcc/ada/s-taprob.adb +++ b/gcc/ada/s-taprob.adb @@ -7,7 +7,7 @@ -- B o d y -- -- -- -- Copyright (C) 1991-1994, Florida State University -- --- Copyright (C) 1995-2011, AdaCore -- +-- Copyright (C) 1995-2014, 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- -- @@ -31,14 +31,20 @@ ------------------------------------------------------------------------------ pragma Polling (Off); --- Turn off polling, we do not want ATC polling to take place during --- tasking operations. It causes infinite loops and other problems. +-- Turn off polling, we do not want ATC polling to take place during tasking +-- operations. It causes infinite loops and other problems. with System.Task_Primitives.Operations; with System.Parameters; with System.Traces; with System.Soft_Links.Tasking; +with System.Secondary_Stack; +pragma Elaborate_All (System.Secondary_Stack); +pragma Unreferenced (System.Secondary_Stack); +-- Make sure the body of Secondary_Stack is elaborated before calling +-- Init_Tasking_Soft_Links. See comments for this routine for explanation. + package body System.Tasking.Protected_Objects is use System.Task_Primitives.Operations; diff --git a/gcc/ada/s-taprop-linux.adb b/gcc/ada/s-taprop-linux.adb index 5aa384ba126..4a81c0880fa 100644 --- a/gcc/ada/s-taprop-linux.adb +++ b/gcc/ada/s-taprop-linux.adb @@ -1076,9 +1076,11 @@ package body System.Task_Primitives.Operations is procedure Abort_Task (T : Task_Id) is Result : Interfaces.C.int; - ESRCH : constant := 3; -- No such process + + ESRCH : constant := 3; -- No such process -- It can happen that T has already vanished, in which case pthread_kill -- returns ESRCH, so we don't consider that to be an error. + begin if Abort_Handler_Installed then Result := diff --git a/gcc/ada/s-tarest.adb b/gcc/ada/s-tarest.adb index 71b116cd06a..1436f2a01aa 100644 --- a/gcc/ada/s-tarest.adb +++ b/gcc/ada/s-tarest.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1999-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1999-2014, Free Software Foundation, Inc. -- -- -- -- GNARL 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- -- @@ -47,9 +47,13 @@ with Ada.Exceptions; with System.Task_Primitives.Operations; with System.Soft_Links.Tasking; -with System.Secondary_Stack; with System.Storage_Elements; +with System.Secondary_Stack; +pragma Elaborate_All (System.Secondary_Stack); +-- Make sure the body of Secondary_Stack is elaborated before calling +-- Init_Tasking_Soft_Links. See comments for this routine for explanation. + with System.Soft_Links; -- Used for the non-tasking routines (*_NT) that refer to global data. They -- are needed here before the tasking run time has been elaborated. used for diff --git a/gcc/ada/s-tasinf-linux.ads b/gcc/ada/s-tasinf-linux.ads index 740c6bb3646..94bcac1a638 100644 --- a/gcc/ada/s-tasinf-linux.ads +++ b/gcc/ada/s-tasinf-linux.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2007-2012, Free Software Foundation, Inc. -- +-- Copyright (C) 2007-2014, 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,14 +36,15 @@ -- Note: the compiler generates direct calls to this interface, via Rtsfind. -- Any changes to this interface may require corresponding compiler changes. --- This unit may be used directly from an application program by providing --- an appropriate WITH, and the interface can be expected to remain stable. +-- The functionality in this unit is now provided by the predefined package +-- System.Multiprocessors and the CPU aspect. This package is obsolescent. -- This is the GNU/Linux version of this module with System.OS_Interface; package System.Task_Info is + pragma Obsolescent (Task_Info, "use System.Multiprocessors and CPU aspect"); pragma Preelaborate; pragma Elaborate_Body; -- To ensure that a body is allowed diff --git a/gcc/ada/s-tasinf-mingw.ads b/gcc/ada/s-tasinf-mingw.ads index fb70109ac21..f4892d76a26 100644 --- a/gcc/ada/s-tasinf-mingw.ads +++ b/gcc/ada/s-tasinf-mingw.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2007-2009, Free Software Foundation, Inc. -- +-- Copyright (C) 2007-2014, 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,14 +36,15 @@ -- Note: the compiler generates direct calls to this interface, via Rtsfind. -- Any changes to this interface may require corresponding compiler changes. --- This unit may be used directly from an application program by providing --- an appropriate WITH, and the interface can be expected to remain stable. +-- The functionality in this unit is now provided by the predefined package +-- System.Multiprocessors and the CPU aspect. This package is obsolescent. -- This is the Windows (native) version of this module with System.Win32; package System.Task_Info is + pragma Obsolescent (Task_Info, "use System.Multiprocessors and CPU aspect"); pragma Preelaborate; pragma Elaborate_Body; -- To ensure that a body is allowed diff --git a/gcc/ada/s-tasinf-solaris.ads b/gcc/ada/s-tasinf-solaris.ads index a7fc7ac1976..2b457bc68ec 100644 --- a/gcc/ada/s-tasinf-solaris.ads +++ b/gcc/ada/s-tasinf-solaris.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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,14 +36,15 @@ -- Note: the compiler generates direct calls to this interface, via Rtsfind. -- Any changes to this interface may require corresponding compiler changes. --- This unit may be used directly from an application program by providing --- an appropriate WITH, and the interface can be expected to remain stable. +-- The functionality in this unit is now provided by the predefined package +-- System.Multiprocessors and the CPU aspect. This package is obsolescent. -- This is the Solaris (native) version of this module with System.OS_Interface; package System.Task_Info is + pragma Obsolescent (Task_Info, "use System.Multiprocessors and CPU aspect"); pragma Preelaborate; pragma Elaborate_Body; -- To ensure that a body is allowed diff --git a/gcc/ada/s-tasinf-vxworks.ads b/gcc/ada/s-tasinf-vxworks.ads index db6bc56af60..2c57c2b22e7 100644 --- a/gcc/ada/s-tasinf-vxworks.ads +++ b/gcc/ada/s-tasinf-vxworks.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2011, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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,14 +36,15 @@ -- Note: the compiler generates direct calls to this interface, via Rtsfind. -- Any changes to this interface may require corresponding compiler changes. --- This unit may be used directly from an application program by providing --- an appropriate WITH, and the interface can be expected to remain stable. +-- The functionality in this unit is now provided by the predefined package +-- System.Multiprocessors and the CPU aspect. This package is obsolescent. -- This is the VxWorks version of this package with Interfaces.C; package System.Task_Info is + pragma Obsolescent (Task_Info, "use System.Multiprocessors and CPU aspect"); pragma Preelaborate; pragma Elaborate_Body; -- To ensure that a body is allowed diff --git a/gcc/ada/s-tasinf.ads b/gcc/ada/s-tasinf.ads index 55f949ab181..adad387f2da 100644 --- a/gcc/ada/s-tasinf.ads +++ b/gcc/ada/s-tasinf.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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 @@ -- Note: the compiler generates direct calls to this interface, via Rtsfind. -- Any changes to this interface may require corresponding compiler changes. --- This unit may be used directly from an application program by providing --- an appropriate WITH, and the interface can be expected to remain stable. +-- The functionality in this unit is now provided by the predefined package +-- System.Multiprocessors and the CPU aspect. This package is obsolescent. package System.Task_Info is + pragma Obsolescent (Task_Info, "use System.Multiprocessors and CPU aspect"); pragma Preelaborate; pragma Elaborate_Body; -- To ensure that a body is allowed diff --git a/gcc/ada/s-tasini.adb b/gcc/ada/s-tasini.adb index 27bf9398151..45c99cdadce 100644 --- a/gcc/ada/s-tasini.adb +++ b/gcc/ada/s-tasini.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNARL 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- -- @@ -47,6 +47,12 @@ with System.Soft_Links.Tasking; with System.Tasking.Debug; with System.Parameters; +with System.Secondary_Stack; +pragma Elaborate_All (System.Secondary_Stack); +pragma Unreferenced (System.Secondary_Stack); +-- Make sure the body of Secondary_Stack is elaborated before calling +-- Init_Tasking_Soft_Links. See comments for this routine for explanation. + package body System.Tasking.Initialization is package STPO renames System.Task_Primitives.Operations; diff --git a/gcc/ada/s-tassta.adb b/gcc/ada/s-tassta.adb index 4eff8eeaa76..decfcab0f83 100644 --- a/gcc/ada/s-tassta.adb +++ b/gcc/ada/s-tassta.adb @@ -870,15 +870,14 @@ package body System.Tasking.Stages is Write_Lock (Self_ID); -- If the Abort_Task signal is set to system, it means that we may - -- not have been able to abort all independent tasks (in particular + -- not have been able to abort all independent tasks (in particular, -- Server_Task may be blocked, waiting for a signal), in which case, do -- not wait for Independent_Task_Count to go down to 0. We arbitrarily -- limit the number of loop iterations; if an independent task does not -- terminate, we do not want to hang here. In that case, the thread will -- be terminated when the process exits. - if State (System.Interrupt_Management.Abort_Task_Interrupt) /= - Default + if State (System.Interrupt_Management.Abort_Task_Interrupt) /= Default then for J in 1 .. 10 loop exit when Utilities.Independent_Task_Count = 0; diff --git a/gcc/ada/s-unstyp.ads b/gcc/ada/s-unstyp.ads index ee77af897ac..3b97599be87 100644 --- a/gcc/ada/s-unstyp.ads +++ b/gcc/ada/s-unstyp.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -200,7 +200,7 @@ package System.Unsigned_Types is -- previous version of the compiler and runtime, but are not needed -- by the current version. We retain them to help with bootstrap path -- problems. Also they seem harmless, and if any user programs have - -- been (rather improperly) using these types, why discombobulate them? + -- been using these types, why discombobulate them? subtype Packed_Bytes is Packed_Bytes4; subtype Packed_Bytes_Unaligned is Packed_Bytes1; diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb index bb1794444cd..df24ba272e3 100644 --- a/gcc/ada/sem_aggr.adb +++ b/gcc/ada/sem_aggr.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -4749,7 +4749,7 @@ package body Sem_Aggr is Error_Msg_N ("(Ada 2005) null not allowed in null-excluding component??", Expr); Error_Msg_N - ("\Constraint_Error will be raised at run time?", Expr); + ("\Constraint_Error will be raised at run time??", Expr); Rewrite (Expr, Make_Raise_Constraint_Error diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb index 968ba008ec3..bda9f357cc1 100644 --- a/gcc/ada/sem_attr.adb +++ b/gcc/ada/sem_attr.adb @@ -2409,69 +2409,70 @@ package body Sem_Attr is end if; end if; - -- Ada 2005 (AI-345): Ensure that the compiler gives exactly the current - -- output compiling in Ada 95 mode for the case of ambiguous prefixes. + -- Cases where prefix must be resolvable by itself - if Ada_Version < Ada_2005 - and then Is_Overloaded (P) + if Is_Overloaded (P) and then Aname /= Name_Access and then Aname /= Name_Address and then Aname /= Name_Code_Address - and then Aname /= Name_Count and then Aname /= Name_Result and then Aname /= Name_Unchecked_Access then - Error_Attr ("ambiguous prefix for % attribute", P); + -- The prefix must be resolvable by itself, without reference to the + -- attribute. One case that requires special handling is a prefix + -- that is a function name, where one interpretation may be a + -- parameterless call. Entry attributes are handled specially below. - elsif Ada_Version >= Ada_2005 - and then Is_Overloaded (P) - and then Aname /= Name_Access - and then Aname /= Name_Address - and then Aname /= Name_Code_Address - and then Aname /= Name_Result - and then Aname /= Name_Unchecked_Access - then - -- Ada 2005 (AI-345): Since protected and task types have primitive - -- entry wrappers, the attributes Count, Caller and AST_Entry require - -- a context check - - if Ada_Version >= Ada_2005 - and then Nam_In (Aname, Name_Count, Name_Caller, Name_AST_Entry) + if Is_Entity_Name (P) + and then not Nam_In (Aname, Name_Count, Name_Caller, Name_AST_Entry) then - declare - Count : Natural := 0; - I : Interp_Index; - It : Interp; + Check_Parameterless_Call (P); + end if; - begin - Get_First_Interp (P, I, It); - while Present (It.Nam) loop - if Comes_From_Source (It.Nam) then - Count := Count + 1; - else - Remove_Interp (I); - end if; + if Is_Overloaded (P) then - Get_Next_Interp (I, It); - end loop; + -- Ada 2005 (AI-345): Since protected and task types have + -- primitive entry wrappers, the attributes Count, Caller and + -- AST_Entry require a context check - if Count > 1 then - Error_Attr ("ambiguous prefix for % attribute", P); - else - Set_Is_Overloaded (P, False); - end if; - end; + if Nam_In (Aname, Name_Count, Name_Caller, Name_AST_Entry) then + declare + Count : Natural := 0; + I : Interp_Index; + It : Interp; - else - Error_Attr ("ambiguous prefix for % attribute", P); + begin + Get_First_Interp (P, I, It); + while Present (It.Nam) loop + if Comes_From_Source (It.Nam) then + Count := Count + 1; + else + Remove_Interp (I); + end if; + + Get_Next_Interp (I, It); + end loop; + + if Count > 1 then + Error_Attr ("ambiguous prefix for % attribute", P); + else + Set_Is_Overloaded (P, False); + end if; + end; + + else + Error_Attr ("ambiguous prefix for % attribute", P); + end if; end if; end if; -- In SPARK, attributes of private types are only allowed if the full -- type declaration is visible. - if Is_Entity_Name (P) - and then Present (Entity (P)) -- needed in some cases + -- Note: the check for Present (Entity (P)) defends against some error + -- conditions where the Entity field is not set. + + if Is_Entity_Name (P) and then Present (Entity (P)) and then Is_Type (Entity (P)) and then Is_Private_Type (P_Type) and then not In_Open_Scopes (Scope (P_Type)) @@ -4492,7 +4493,7 @@ package body Sem_Attr is if Is_Potentially_Unevaluated (P) then Error_Msg_Name_1 := Aname; Error_Msg_N - ("?prefix of attribute % is always evaluated when " + ("??prefix of attribute % is always evaluated when " & "related consequence is selected", P); end if; @@ -4836,17 +4837,20 @@ package body Sem_Attr is if Is_Real_Type (P_Type) or else Is_Boolean_Type (P_Type) then Error_Msg_Name_1 := Aname; Error_Msg_Name_2 := Chars (P_Type); - Check_SPARK_Restriction - ("attribute% is not allowed for type%", P); + Check_SPARK_Restriction ("attribute% is not allowed for type%", P); end if; Resolve (E1, P_Base_Type); Set_Etype (N, P_Base_Type); - -- Nothing to do for real type case + -- For real types, enable range check in Check_Overflow_Mode only if Is_Real_Type (P_Type) then - null; + if Check_Float_Overflow + and then not Range_Checks_Suppressed (P_Base_Type) + then + Enable_Range_Check (E1); + end if; -- If not modular type, test for overflow check required @@ -5740,17 +5744,20 @@ package body Sem_Attr is if Is_Real_Type (P_Type) or else Is_Boolean_Type (P_Type) then Error_Msg_Name_1 := Aname; Error_Msg_Name_2 := Chars (P_Type); - Check_SPARK_Restriction - ("attribute% is not allowed for type%", P); + Check_SPARK_Restriction ("attribute% is not allowed for type%", P); end if; Resolve (E1, P_Base_Type); Set_Etype (N, P_Base_Type); - -- Nothing to do for real type case + -- For real types, enable range check in Check_Overflow_Mode only if Is_Real_Type (P_Type) then - null; + if Check_Float_Overflow + and then not Range_Checks_Suppressed (P_Base_Type) + then + Enable_Range_Check (E1); + end if; -- If not modular type, test for overflow check required diff --git a/gcc/ada/sem_aux.adb b/gcc/ada/sem_aux.adb index 897d99b4d22..f36c500bd08 100644 --- a/gcc/ada/sem_aux.adb +++ b/gcc/ada/sem_aux.adb @@ -666,6 +666,51 @@ package body Sem_Aux is end if; end Has_Unconstrained_Elements; + ---------------------- + -- Has_Variant_Part -- + ---------------------- + + function Has_Variant_Part (Typ : Entity_Id) return Boolean is + FSTyp : Entity_Id; + Decl : Node_Id; + TDef : Node_Id; + CList : Node_Id; + + begin + if not Is_Type (Typ) then + return False; + end if; + + FSTyp := First_Subtype (Typ); + + if not Has_Discriminants (FSTyp) then + return False; + end if; + + -- Proceed with cautious checks here, return False if tree is not + -- as expected (may be caused by prior errors). + + Decl := Declaration_Node (FSTyp); + + if Nkind (Decl) /= N_Full_Type_Declaration then + return False; + end if; + + TDef := Type_Definition (Decl); + + if Nkind (TDef) /= N_Record_Definition then + return False; + end if; + + CList := Component_List (TDef); + + if Nkind (CList) /= N_Component_List then + return False; + else + return Present (Variant_Part (CList)); + end if; + end Has_Variant_Part; + --------------------- -- In_Generic_Body -- --------------------- diff --git a/gcc/ada/sem_aux.ads b/gcc/ada/sem_aux.ads index 6a3ebeb7840..d394d0975c0 100644 --- a/gcc/ada/sem_aux.ads +++ b/gcc/ada/sem_aux.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -255,6 +255,10 @@ package Sem_Aux is -- True if T has discriminants and is unconstrained, or is an array type -- whose element type Has_Unconstrained_Elements. + function Has_Variant_Part (Typ : Entity_Id) return Boolean; + -- Return True if the first subtype of Typ is a discriminated record type + -- which has a variant part. False otherwise. + function In_Generic_Body (Id : Entity_Id) return Boolean; -- Determine whether entity Id appears inside a generic body diff --git a/gcc/ada/sem_cat.adb b/gcc/ada/sem_cat.adb index 47736565dd5..b9800c40a9b 100644 --- a/gcc/ada/sem_cat.adb +++ b/gcc/ada/sem_cat.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -277,7 +277,7 @@ package body Sem_Cat is and then Is_Preelaborated (Depended_Entity) then Error_Msg_NE - ("<must use private with clause for preelaborated unit& ", + ("<<must use private with clause for preelaborated unit& ", N, Depended_Entity); -- Subunit case @@ -291,7 +291,7 @@ package body Sem_Cat is else Error_Msg_NE - ("<cannot depend on& " & + ("<<cannot depend on& " & "(wrong categorization)", N, Depended_Entity); end if; @@ -299,7 +299,7 @@ package body Sem_Cat is if Unit_Category = Pure then Error_Msg_NE - ("\<pure unit cannot depend on non-pure unit", + ("\<<pure unit cannot depend on non-pure unit", N, Depended_Entity); elsif Is_Preelaborated (Unit_Entity) @@ -307,7 +307,7 @@ package body Sem_Cat is and then not Is_Pure (Depended_Entity) then Error_Msg_NE - ("\<preelaborated unit cannot depend on " + ("\<<preelaborated unit cannot depend on " & "non-preelaborated unit", N, Depended_Entity); end if; @@ -1102,7 +1102,7 @@ package body Sem_Cat is Error_Msg_Warn := GNAT_Mode; Error_Msg_N - ("<statements not allowed in preelaborated unit", Item); + ("<<statements not allowed in preelaborated unit", Item); exit; end if; @@ -2048,7 +2048,8 @@ package body Sem_Cat is --------------------------------- procedure Validate_Static_Object_Name (N : Node_Id) is - E : Entity_Id; + E : Entity_Id; + Val : Node_Id; function Is_Primary (N : Node_Id) return Boolean; -- Determine whether node is syntactically a primary in an expression @@ -2151,7 +2152,8 @@ package body Sem_Cat is elsif Ekind (Entity (N)) = E_Constant and then not Is_Static_Expression (N) then - E := Entity (N); + E := Entity (N); + Val := Constant_Value (E); if Is_Internal_File_Name (Unit_File_Name (Get_Source_Unit (N))) and then @@ -2162,10 +2164,25 @@ package body Sem_Cat is and then Is_Entity_Name (Renamed_Object (E)) and then (Is_Preelaborated - (Scope (Renamed_Object (E))) - or else - Is_Pure (Scope - (Renamed_Object (E)))))) + (Scope (Renamed_Object (E))) + or else + Is_Pure + (Scope (Renamed_Object (E)))))) + then + null; + + -- If the value of the constant is a local variable that renames + -- an aggregate, this is in itself legal. The aggregate may be + -- expanded into a loop, but this does not affect preelaborability + -- in itself. If some aggregate components are non-static, that is + -- to say if they involve non static primaries, they will be + -- flagged when analyzed. + + elsif Present (Val) + and then Is_Entity_Name (Val) + and then Is_Array_Type (Etype (Val)) + and then not Comes_From_Source (Val) + and then Nkind (Original_Node (Val)) = N_Aggregate then null; diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb index 49f7df1023b..538746e7363 100644 --- a/gcc/ada/sem_ch10.adb +++ b/gcc/ada/sem_ch10.adb @@ -1879,6 +1879,39 @@ package body Sem_Ch10 is end if; end Analyze_Protected_Body_Stub; + ------------------------------------------- + -- Analyze_Subprogram_Body_Stub_Contract -- + ------------------------------------------- + + procedure Analyze_Subprogram_Body_Stub_Contract (Stub_Id : Entity_Id) is + Stub_Decl : constant Node_Id := Parent (Parent (Stub_Id)); + Spec_Id : constant Entity_Id := Corresponding_Spec_Of_Stub (Stub_Decl); + + begin + -- A subprogram body stub may act as its own spec or as the completion + -- of a previous declaration. Depending on the context, the contract of + -- the stub may contain two sets of pragmas. + + -- The stub is a completion, the applicable pragmas are: + -- Contract_Cases + -- Depends + -- Global + -- Postcondition + -- Precondition + -- Test_Case + + if Present (Spec_Id) then + Analyze_Subprogram_Body_Contract (Stub_Id); + + -- The stub acts as its own spec, the applicable pragmas are: + -- Refined_Depends + -- Refined_Global + + else + Analyze_Subprogram_Contract (Stub_Id); + end if; + end Analyze_Subprogram_Body_Stub_Contract; + ---------------------------------- -- Analyze_Subprogram_Body_Stub -- ---------------------------------- diff --git a/gcc/ada/sem_ch10.ads b/gcc/ada/sem_ch10.ads index 6eb7fab5cd3..c003526ecbe 100644 --- a/gcc/ada/sem_ch10.ads +++ b/gcc/ada/sem_ch10.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2010, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -33,6 +33,19 @@ package Sem_Ch10 is procedure Analyze_Protected_Body_Stub (N : Node_Id); procedure Analyze_Subunit (N : Node_Id); + procedure Analyze_Subprogram_Body_Stub_Contract (Stub_Id : Entity_Id); + -- Analyze all delayed aspects chained on the contract of a subprogram body + -- stub Stub_Id as if they appeared at the end of a declarative region. The + -- aspects in question are: + -- Contract_Cases + -- Depends + -- Global + -- Postcondition + -- Precondition + -- Refined_Depends + -- Refined_Global + -- Test_Case + procedure Install_Context (N : Node_Id); -- Installs the entities from the context clause of the given compilation -- unit into the visibility chains. This is done before analyzing a unit. diff --git a/gcc/ada/sem_ch11.adb b/gcc/ada/sem_ch11.adb index a712fedd83f..c4a148f0cd5 100644 --- a/gcc/ada/sem_ch11.adb +++ b/gcc/ada/sem_ch11.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -436,7 +436,7 @@ package body Sem_Ch11 is begin if Comes_From_Source (N) then - Check_Compiler_Unit (N); + Check_Compiler_Unit ("raise expression", N); end if; Check_SPARK_Restriction ("raise expression is not allowed", N); diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb index 2d7487667bc..65ce631456e 100644 --- a/gcc/ada/sem_ch12.adb +++ b/gcc/ada/sem_ch12.adb @@ -1776,6 +1776,22 @@ package body Sem_Ch12 is Delta_Val : constant Ureal := Ureal_1; Digs_Val : constant Uint := Uint_6; + function Make_Dummy_Bound return Node_Id; + -- Return a properly typed universal real literal to use as a bound + + ---------------------- + -- Make_Dummy_Bound -- + ---------------------- + + function Make_Dummy_Bound return Node_Id is + Bound : constant Node_Id := Make_Real_Literal (Loc, Ureal_1); + begin + Set_Etype (Bound, Universal_Real); + return Bound; + end Make_Dummy_Bound; + + -- Start of processing for Analyze_Formal_Decimal_Fixed_Point_Type + begin Enter_Name (T); @@ -1788,8 +1804,8 @@ package body Sem_Ch12 is Set_Small_Value (Base, Delta_Val); Set_Scalar_Range (Base, Make_Range (Loc, - Low_Bound => Make_Real_Literal (Loc, Ureal_1), - High_Bound => Make_Real_Literal (Loc, Ureal_1))); + Low_Bound => Make_Dummy_Bound, + High_Bound => Make_Dummy_Bound)); Set_Is_Generic_Type (Base); Set_Parent (Base, Parent (Def)); @@ -9951,27 +9967,36 @@ package body Sem_Ch12 is ----------------------------- procedure Check_Initialized_Types is - Decl : Node_Id; - Formal : Entity_Id; - Actual : Entity_Id; + Decl : Node_Id; + Formal : Entity_Id; + Actual : Entity_Id; + Uninit_Var : Entity_Id; begin Decl := First (Generic_Formal_Declarations (Gen_Decl)); while Present (Decl) loop - if (Nkind (Decl) = N_Private_Extension_Declaration - and then Needs_Initialized_Actual (Decl)) - - or else (Nkind (Decl) = N_Formal_Type_Declaration - and then Nkind (Formal_Type_Definition (Decl)) = - N_Formal_Private_Type_Definition - and then Needs_Initialized_Actual - (Formal_Type_Definition (Decl))) + Uninit_Var := Empty; + + if Nkind (Decl) = N_Private_Extension_Declaration then + Uninit_Var := Uninitialized_Variable (Decl); + + elsif Nkind (Decl) = N_Formal_Type_Declaration + and then Nkind (Formal_Type_Definition (Decl)) = + N_Formal_Private_Type_Definition then + Uninit_Var := + Uninitialized_Variable (Formal_Type_Definition (Decl)); + end if; + + if Present (Uninit_Var) then Formal := Defining_Identifier (Decl); Actual := First_Entity (Act_Decl_Id); -- For each formal there is a subtype declaration that renames - -- the actual and has the same name as the formal. + -- the actual and has the same name as the formal. Locate the + -- formal for warning message about uninitialized variables + -- in the generic, for which the actual type should be a fully + -- initialized type. while Present (Actual) loop exit when Ekind (Actual) = E_Package @@ -9982,9 +10007,13 @@ package body Sem_Ch12 is and then not Is_Fully_Initialized_Type (Actual) and then Warn_On_No_Value_Assigned then + Error_Msg_Node_2 := Formal; + Error_Msg_NE + ("generic unit has uninitialized variable& of " + & "formal private type &?v?", Actual, Uninit_Var); Error_Msg_NE - ("from its use in generic unit, actual for& should " - & "be fully initialized type??", Actual, Formal); + ("actual type for& should be fully initialized type?v?", + Actual, Formal); exit; end if; @@ -10024,9 +10053,21 @@ package body Sem_Ch12 is Opt.SPARK_Mode_Pragma := Body_Info.SPARK_Mode_Pragma; if No (Gen_Body_Id) then - Load_Parent_Of_Generic - (Inst_Node, Specification (Gen_Decl), Body_Optional); - Gen_Body_Id := Corresponding_Body (Gen_Decl); + + -- Do not look for parent of generic body if none is required. + -- This may happen when the routine is called as part of the + -- Pending_Instantiations processing, when nested instances + -- may precede the one generated from the main unit. + + if not Unit_Requires_Body (Defining_Entity (Gen_Decl)) + and then Body_Optional + then + return; + else + Load_Parent_Of_Generic + (Inst_Node, Specification (Gen_Decl), Body_Optional); + Gen_Body_Id := Corresponding_Body (Gen_Decl); + end if; end if; -- Establish global variable for sloc adjustment and for error recovery diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb index bf42b0eebc4..149826f2519 100644 --- a/gcc/ada/sem_ch13.adb +++ b/gcc/ada/sem_ch13.adb @@ -661,12 +661,12 @@ package body Sem_Ch13 is if Bytes_Big_Endian then Error_Msg_NE - ("\info: big-endian range for " + ("\big-endian range for " & "component & is ^ .. ^?V?", First_Bit (CC), Comp); else Error_Msg_NE - ("\info: little-endian range " + ("\little-endian range " & "for component & is ^ .. ^?V?", First_Bit (CC), Comp); end if; @@ -1603,7 +1603,7 @@ package body Sem_Ch13 is goto Continue; end if; - -- For case of address aspect, we don't consider that we + -- For the case of aspect Address, we don't consider that we -- know the entity is never set in the source, since it is -- is likely aliasing is occurring. @@ -2007,10 +2007,51 @@ package body Sem_Ch13 is -- immediately. when Aspect_Abstract_State => Abstract_State : declare + procedure Insert_After_SPARK_Mode + (Ins_Nod : Node_Id; + Decls : List_Id); + -- Insert Aitem before node Ins_Nod. If Ins_Nod denotes + -- pragma SPARK_Mode, then SPARK_Mode is skipped. Decls is + -- the associated declarative list where Aitem is to reside. + + ----------------------------- + -- Insert_After_SPARK_Mode -- + ----------------------------- + + procedure Insert_After_SPARK_Mode + (Ins_Nod : Node_Id; + Decls : List_Id) + is + Decl : Node_Id := Ins_Nod; + + begin + -- Skip SPARK_Mode + + if Present (Decl) + and then Nkind (Decl) = N_Pragma + and then Pragma_Name (Decl) = Name_SPARK_Mode + then + Decl := Next (Decl); + end if; + + if Present (Decl) then + Insert_Before (Decl, Aitem); + + -- Aitem acts as the last declaration + + else + Append_To (Decls, Aitem); + end if; + end Insert_After_SPARK_Mode; + + -- Local variables + Context : Node_Id := N; Decl : Node_Id; Decls : List_Id; + -- Start of processing for Abstract_State + begin -- When aspect Abstract_State appears on a generic package, -- it is propageted to the package instance. The context in @@ -2061,17 +2102,20 @@ package body Sem_Ch13 is Decl := Next (Decl); end loop; - if Present (Decl) then - Insert_Before (Decl, Aitem); - else - Append_To (Decls, Aitem); - end if; + -- Pragma Abstract_State must be inserted after + -- pragma SPARK_Mode in the tree. This ensures that + -- any error messages dependent on SPARK_Mode will + -- be properly enabled/suppressed. + + Insert_After_SPARK_Mode (Decl, Decls); -- The related package is not a generic instance, the - -- corresponding pragma must be the first declaration. + -- corresponding pragma must be the first declaration + -- except when SPARK_Mode is already in the list. In + -- that case pragma Abstract_State is placed second. else - Prepend_To (Decls, Aitem); + Insert_After_SPARK_Mode (First (Decls), Decls); end if; -- Otherwise the pragma forms a new declarative list @@ -2691,50 +2735,25 @@ package body Sem_Ch13 is elsif A_Id = Aspect_Import or else A_Id = Aspect_Export then - -- Verify that there is an aspect Convention that will - -- incorporate the Import/Export aspect, and eventual - -- Link/External names. + -- For the case of aspects Import and Export, we don't + -- consider that we know the entity is never set in the + -- source, since it is is likely modified outside the + -- program. - declare - A : Node_Id; - - begin - A := First (L); - while Present (A) loop - exit when Chars (Identifier (A)) = Name_Convention; - Next (A); - end loop; - - -- It is legal to specify Import for a variable, in - -- order to suppress initialization for it, without - -- specifying explicitly its convention. However this - -- is only legal if the convention of the object type - -- is Ada or similar. + -- Note: one might think that the analysis of the + -- resulting pragma would take care of that, but + -- that's not the case since it won't be from source. - if No (A) then - if Ekind (E) = E_Variable - and then A_Id = Aspect_Import - then - declare - C : constant Convention_Id := - Convention (Etype (E)); - begin - if C = Convention_Ada or else - C = Convention_Ada_Pass_By_Copy or else - C = Convention_Ada_Pass_By_Reference - then - goto Continue; - end if; - end; - end if; - - -- Otherwise, Convention must be specified + if Ekind (E) = E_Variable then + Set_Never_Set_In_Source (E, False); + end if; - Error_Msg_N - ("missing Convention aspect for Export/Import", - Aspect); - end if; - end; + -- In older versions of Ada the corresponding pragmas + -- specified a Convention. In Ada 2012 the convention + -- is specified as a separate aspect, and it is optional, + -- given that it defaults to Convention_Ada. The code + -- that verifed that there was a matching convention + -- is now obsolete. goto Continue; end if; @@ -3132,8 +3151,23 @@ package body Sem_Ch13 is Typ := Etype (Subp); end if; - return Base_Type (Typ) = Base_Type (Ent) - and then No (Next_Formal (F)); + -- Verify that the prefix of the attribute and the local name + -- for the type of the formal match. + + if Base_Type (Typ) /= Base_Type (Ent) + or else Present ((Next_Formal (F))) + then + return False; + + elsif not Is_Scalar_Type (Typ) + and then not Is_First_Subtype (Typ) + and then not Is_Class_Wide_Type (Typ) + then + return False; + + else + return True; + end if; end Has_Good_Profile; -- Start of processing for Analyze_Stream_TSS_Definition @@ -3144,6 +3178,10 @@ package body Sem_Ch13 is if not Is_Type (U_Ent) then Error_Msg_N ("local name must be a subtype", Nam); return; + + elsif not Is_First_Subtype (U_Ent) then + Error_Msg_N ("local name must be a first subtype", Nam); + return; end if; Pnam := TSS (Base_Type (U_Ent), TSS_Nam); @@ -3194,6 +3232,20 @@ package body Sem_Ch13 is if Is_Abstract_Subprogram (Subp) then Error_Msg_N ("stream subprogram must not be abstract", Expr); return; + + -- Test for stream subprogram for interface type being non-null + + elsif Is_Interface (U_Ent) + and then not Inside_A_Generic + and then Ekind (Subp) = E_Procedure + and then + not Null_Present + (Specification + (Unit_Declaration_Node (Ultimate_Alias (Subp)))) + then + Error_Msg_N + ("stream subprogram for interface type " + & "must be null procedure", Expr); end if; Set_Entity (Expr, Subp); @@ -6324,7 +6376,7 @@ package body Sem_Ch13 is if Inherit and Opt.List_Inherited_Aspects then Error_Msg_Sloc := Sloc (Ritem); Error_Msg_N - ("?L?info: & inherits `Invariant''Class` aspect from #", + ("info: & inherits `Invariant''Class` aspect from #?L?", Typ); end if; end if; @@ -11285,7 +11337,7 @@ package body Sem_Ch13 is and then X_Size > Y_Size then Error_Msg_NE - ("?& overlays smaller object", ACCR.N, ACCR.X); + ("??& overlays smaller object", ACCR.N, ACCR.X); Error_Msg_N ("\??program execution may be erroneous", ACCR.N); Error_Msg_Uint_1 := X_Size; @@ -11926,7 +11978,7 @@ package body Sem_Ch13 is elsif Is_Unsigned_Type (Source) then Error_Msg ("\?z?source will be extended with ^ high order " - & "zero bits?!", Eloc); + & "zero bits!", Eloc); else Error_Msg diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index 293a3f695cd..9dc8d1281d7 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -57,6 +57,7 @@ with Sem_Cat; use Sem_Cat; with Sem_Ch6; use Sem_Ch6; with Sem_Ch7; use Sem_Ch7; with Sem_Ch8; use Sem_Ch8; +with Sem_Ch10; use Sem_Ch10; with Sem_Ch13; use Sem_Ch13; with Sem_Dim; use Sem_Dim; with Sem_Disp; use Sem_Disp; @@ -835,7 +836,7 @@ package body Sem_Ch3 is -- the runtime library but must also be compilable in Ada 95 mode -- (when bootstrapping the compiler). - Check_Compiler_Unit (N); + Check_Compiler_Unit ("anonymous access to subprogram", N); Access_Subprogram_Declaration (T_Name => Anon_Type, @@ -2371,13 +2372,16 @@ package body Sem_Ch3 is if Nkind (Decl) = N_Object_Declaration then Analyze_Object_Contract (Defining_Entity (Decl)); + elsif Nkind_In (Decl, N_Abstract_Subprogram_Declaration, + N_Subprogram_Declaration) + then + Analyze_Subprogram_Contract (Defining_Entity (Decl)); + elsif Nkind (Decl) = N_Subprogram_Body then Analyze_Subprogram_Body_Contract (Defining_Entity (Decl)); - elsif Nkind_In (Decl, N_Subprogram_Declaration, - N_Abstract_Subprogram_Declaration) - then - Analyze_Subprogram_Contract (Defining_Entity (Decl)); + elsif Nkind (Decl) = N_Subprogram_Body_Stub then + Analyze_Subprogram_Body_Stub_Contract (Defining_Entity (Decl)); end if; Next (Decl); @@ -10227,7 +10231,7 @@ package body Sem_Ch3 is if GNAT_Mode then Error_Msg_N - ("?cannot initialize entities of limited type!", Exp); + ("??cannot initialize entities of limited type!", Exp); elsif Ada_Version < Ada_2005 then @@ -13558,22 +13562,29 @@ package body Sem_Ch3 is -- interface primitives. or else (Is_Interface (Desig_Typ) - and then not Is_Class_Wide_Type (Desig_Typ)) + and then not Is_Class_Wide_Type (Desig_Typ)) then Acc_Type := New_Copy (Etype (Id)); Set_Etype (Acc_Type, Acc_Type); Set_Scope (Acc_Type, New_Subp); - -- Compute size of anonymous access type + -- Set size of anonymous access type. If we have an access + -- to an unconstrained array, this is a fat pointer, so it + -- is sizes at twice addtress size. if Is_Array_Type (Desig_Typ) and then not Is_Constrained (Desig_Typ) then Init_Size (Acc_Type, 2 * System_Address_Size); + + -- Other cases use a thin pointer + else Init_Size (Acc_Type, System_Address_Size); end if; + -- Set remaining characterstics of anonymous access type + Init_Alignment (Acc_Type); Set_Directly_Designated_Type (Acc_Type, Derived_Type); @@ -13581,6 +13592,7 @@ package body Sem_Ch3 is Set_Scope (New_Id, New_Subp); -- Create a reference to it + Build_Itype_Reference (Acc_Type, Parent (Derived_Type)); else @@ -15504,7 +15516,6 @@ package body Sem_Ch3 is or else No (Full_View (Prev)) or else not Is_Private_Type (Full_View (Prev))) then - -- Indicate that the incomplete declaration has a matching full -- declaration. The defining occurrence of the incomplete -- declaration remains the visible one, and the procedure @@ -15587,8 +15598,9 @@ package body Sem_Ch3 is end if; elsif Nkind (N) = N_Full_Type_Declaration - and then - Nkind (Type_Definition (N)) = N_Record_Definition + and then Nkind_In + (Type_Definition (N), N_Record_Definition, + N_Derived_Type_Definition) and then Interface_Present (Type_Definition (N)) then Error_Msg_N @@ -18296,16 +18308,16 @@ package body Sem_Ch3 is if Present (Iface) then Error_Msg_NE - ("interface & not implemented by full type " & - "(RM-2005 7.3 (7.3/2))", Priv_T, Iface); + ("interface in partial view& not implemented by full type " + & "(RM-2005 7.3 (7.3/2))", Full_T, Iface); end if; Iface := Find_Hidden_Interface (Full_T_Ifaces, Priv_T_Ifaces); if Present (Iface) then Error_Msg_NE - ("interface & not implemented by partial view " & - "(RM-2005 7.3 (7.3/2))", Full_T, Iface); + ("interface & not implemented by partial view " + & "(RM-2005 7.3 (7.3/2))", Full_T, Iface); end if; end; end if; @@ -18336,7 +18348,7 @@ package body Sem_Ch3 is if Priv_Parent = Any_Type or else Full_Parent = Any_Type then return; - -- Ada 2005 (AI-251): Interfaces in the full-typ can be given in + -- Ada 2005 (AI-251): Interfaces in the full type can be given in -- any order. Therefore we don't have to check that its parent must -- be a descendant of the parent of the private type declaration. @@ -19458,7 +19470,7 @@ package body Sem_Ch3 is 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 on class-wide type ignored??", Constraint (S)); end if; diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb index b3da4adf9da..52ff590c521 100644 --- a/gcc/ada/sem_ch4.adb +++ b/gcc/ada/sem_ch4.adb @@ -1392,7 +1392,7 @@ package body Sem_Ch4 is begin if Comes_From_Source (N) then - Check_Compiler_Unit (N); + Check_Compiler_Unit ("case expression", N); end if; Analyze_And_Resolve (Expr, Any_Discrete); @@ -2077,7 +2077,7 @@ package body Sem_Ch4 is Else_Expr := Next (Then_Expr); if Comes_From_Source (N) then - Check_Compiler_Unit (N); + Check_Compiler_Unit ("if expression", N); end if; Analyze_Expression (Condition); @@ -2669,7 +2669,7 @@ package body Sem_Ch4 is begin if Comes_From_Source (N) then - Check_Compiler_Unit (N); + Check_Compiler_Unit ("set membership", N); end if; Analyze (L); @@ -7038,7 +7038,7 @@ package body Sem_Ch4 is -- a dereference operation. if Comes_From_Source (N) then - Check_Compiler_Unit (N); + Check_Compiler_Unit ("generalized indexing", N); end if; declare diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index 01187831fe1..207f70e3107 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -525,6 +525,7 @@ package body Sem_Ch6 is procedure Analyze_Extended_Return_Statement (N : Node_Id) is begin + Check_Compiler_Unit ("extended return statement", N); Analyze_Return_Statement (N); end Analyze_Extended_Return_Statement; @@ -933,8 +934,8 @@ package body Sem_Ch6 is -- Can it really happen (extended return???) Error_Msg_N - ("aliased only allowed for limited" - & " return objects in Ada 2012?", N); + ("aliased only allowed for limited return objects " + & "in Ada 2012??", N); elsif not Is_Limited_View (R_Type) then Error_Msg_N ("aliased only allowed for limited" @@ -2031,21 +2032,27 @@ package body Sem_Ch6 is -------------------------------------- procedure Analyze_Subprogram_Body_Contract (Body_Id : Entity_Id) is - Body_Decl : constant Node_Id := Parent (Parent (Body_Id)); - Spec_Id : constant Entity_Id := Corresponding_Spec (Body_Decl); + Body_Decl : constant Node_Id := Parent (Parent (Body_Id)); Prag : Node_Id; Ref_Depends : Node_Id := Empty; Ref_Global : Node_Id := Empty; + Spec_Id : Entity_Id; begin -- When a subprogram body declaration is illegal, its defining entity is -- left unanalyzed. There is nothing left to do in this case because the - -- body lacks a contract. + -- body lacks a contract, or even a proper Ekind. - if not Analyzed (Body_Id) then + if Ekind (Body_Id) = E_Void then return; end if; + if Nkind (Body_Decl) = N_Subprogram_Body_Stub then + Spec_Id := Corresponding_Spec_Of_Stub (Body_Decl); + else + Spec_Id := Corresponding_Spec (Body_Decl); + end if; + -- Locate and store pragmas Refined_Depends and Refined_Global since -- their order of analysis matters. @@ -2817,7 +2824,7 @@ package body Sem_Ch6 is elsif Ekind (Scope (Spec_Id)) = E_Protected_Type then Error_Msg_Warn := Error_To_Warning; Error_Msg_N - ("<overriding indicator not allowed for protected " + ("<<overriding indicator not allowed for protected " & "subprogram body", Body_Spec); end if; @@ -2842,7 +2849,7 @@ package body Sem_Ch6 is Error_Msg_Warn := Error_To_Warning; Error_Msg_N - ("<overriding indicator not allowed " & + ("<<overriding indicator not allowed " & "for protected subprogram body", Body_Spec); @@ -11609,7 +11616,7 @@ package body Sem_Ch6 is if Convention (Formal_Type) = Convention_Ada_Pass_By_Copy then Error_Msg_N - ("cannot pass aliased parameter & by copy?", Formal); + ("cannot pass aliased parameter & by copy??", Formal); end if; -- Force mechanism if type has Convention Ada_Pass_By_Ref/Copy diff --git a/gcc/ada/sem_ch6.ads b/gcc/ada/sem_ch6.ads index e03341c199b..67bb65268a4 100644 --- a/gcc/ada/sem_ch6.ads +++ b/gcc/ada/sem_ch6.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -57,6 +57,8 @@ package Sem_Ch6 is -- as if they appeared at the end of a declarative region. The aspects in -- question are: -- Contract_Cases + -- Depends + -- Global -- Postcondition -- Precondition -- Test_Case diff --git a/gcc/ada/sem_ch7.adb b/gcc/ada/sem_ch7.adb index 7afe23676c5..d9a9dab88ec 100644 --- a/gcc/ada/sem_ch7.adb +++ b/gcc/ada/sem_ch7.adb @@ -2885,13 +2885,12 @@ package body Sem_Ch7 is -- Body required if library package with pragma Elaborate_Body elsif Has_Pragma_Elaborate_Body (P) then - Error_Msg_N - ("?Y?info: & requires body (Elaborate_Body)", P); + Error_Msg_N ("info: & requires body (Elaborate_Body)?Y?", P); -- Body required if subprogram elsif Is_Subprogram (P) or else Is_Generic_Subprogram (P) then - Error_Msg_N ("?Y?info: & requires body (subprogram case)", P); + Error_Msg_N ("info: & requires body (subprogram case)?Y?", P); -- Body required if generic parent has Elaborate_Body @@ -2904,7 +2903,7 @@ package body Sem_Ch7 is begin if Has_Pragma_Elaborate_Body (G_P) then Error_Msg_N - ("?Y?info: & requires body (generic parent Elaborate_Body)", + ("info: & requires body (generic parent Elaborate_Body)?Y?", P); end if; end; @@ -2922,7 +2921,7 @@ package body Sem_Ch7 is not Is_Null_State (Node (First_Elmt (Abstract_States (P)))) then Error_Msg_N - ("?Y?info: & requires body (non-null abstract state aspect)", P); + ("info: & requires body (non-null abstract state aspect)?Y?", P); end if; -- Otherwise search entity chain for entity requiring completion @@ -2985,7 +2984,7 @@ package body Sem_Ch7 is then Error_Msg_Node_2 := E; Error_Msg_NE - ("?Y?info: & requires body (& requires completion)", + ("info: & requires body (& requires completion)?Y?", E, P); -- Entity that does not require completion diff --git a/gcc/ada/sem_ch9.adb b/gcc/ada/sem_ch9.adb index 4894a646cff..9dcd7de94aa 100644 --- a/gcc/ada/sem_ch9.adb +++ b/gcc/ada/sem_ch9.adb @@ -3327,8 +3327,8 @@ package body Sem_Ch9 is if Present (Iface) then Error_Msg_NE - ("interface & not implemented by full type " & - "(RM-2005 7.3 (7.3/2))", Priv_T, Iface); + ("interface in partial view& not implemented by full " + & "type (RM-2005 7.3 (7.3/2))", T, Iface); end if; Iface := Find_Hidden_Interface (Full_T_Ifaces, Priv_T_Ifaces); diff --git a/gcc/ada/sem_elab.adb b/gcc/ada/sem_elab.adb index 7f494d85183..e8f68e5ab30 100644 --- a/gcc/ada/sem_elab.adb +++ b/gcc/ada/sem_elab.adb @@ -257,6 +257,9 @@ package body Sem_Elab is -- or instantiation node for which the check code is required. C is the -- test whose failure triggers the raise. + function Is_Call_Of_Generic_Formal (N : Node_Id) return Boolean; + -- Returns True if node N is a call to a generic formal subprogram + function Is_Finalization_Procedure (Id : Entity_Id) return Boolean; -- Determine whether entity Id denotes a [Deep_]Finalize procedure @@ -312,9 +315,9 @@ package body Sem_Elab is procedure Supply_Bodies (N : Node_Id); -- Given a node, N, that is either a subprogram declaration or a package -- declaration, this procedure supplies dummy bodies for the subprogram - -- or for all subprograms in the package. If the given node is not one - -- of these two possibilities, then Supply_Bodies does nothing. The - -- dummy body contains a single Raise statement. + -- or for all subprograms in the package. If the given node is not one of + -- these two possibilities, then Supply_Bodies does nothing. The dummy body + -- contains a single Raise statement. procedure Supply_Bodies (L : List_Id); -- Calls Supply_Bodies for all elements of the given list L @@ -541,31 +544,6 @@ package body Sem_Elab is -- warnings on the scope are also suppressed. For the internal case, -- we ignore this flag. - function Is_Call_Of_Generic_Formal return Boolean; - -- Returns True if node N is a call to a generic formal subprogram - - ------------------------------- - -- Is_Call_Of_Generic_Formal -- - ------------------------------- - - function Is_Call_Of_Generic_Formal return Boolean is - begin - return Nkind_In (N, N_Function_Call, N_Procedure_Call_Statement) - - -- Always return False if debug flag -gnatd.G is set - - and then not Debug_Flag_Dot_GG - - -- For now, we detect this by looking for the strange identifier - -- node, whose Chars reflect the name of the generic formal, but - -- the Chars of the Entity references the generic actual. - - and then Nkind (Name (N)) = N_Identifier - and then Chars (Name (N)) /= Chars (Entity (Name (N))); - end Is_Call_Of_Generic_Formal; - - -- Start of processing for Check_A_Call - begin -- If the call is known to be within a local Suppress Elaboration -- pragma, nothing to check. This can happen in task bodies. But @@ -573,7 +551,7 @@ package body Sem_Elab is if Nkind (N) in N_Subprogram_Call and then No_Elaboration_Check (N) - and then not Is_Call_Of_Generic_Formal + and then not Is_Call_Of_Generic_Formal (N) then return; end if; @@ -801,7 +779,7 @@ package body Sem_Elab is if Unit_Caller /= No_Unit and then Unit_Callee /= Unit_Caller and then not Dynamic_Elaboration_Checks - and then not Is_Call_Of_Generic_Formal + and then not Is_Call_Of_Generic_Formal (N) then E_Scope := Spec_Entity (Cunit_Entity (Unit_Caller)); @@ -942,7 +920,7 @@ package body Sem_Elab is if Inst_Case then Elab_Warning ("instantiation of& may raise Program_Error?l?", - "info: instantiation of& during elaboration?", Ent); + "info: instantiation of& during elaboration?$?", Ent); -- Indirect call case, info message only in static elaboration -- case, because the attribute reference itself cannot raise @@ -950,7 +928,7 @@ package body Sem_Elab is elsif Access_Case then Elab_Warning - ("", "info: access to& during elaboration?", Ent); + ("", "info: access to& during elaboration?$?", Ent); -- Subprogram call case @@ -961,13 +939,13 @@ package body Sem_Elab is then Elab_Warning ("implicit call to & may raise Program_Error?l?", - "info: implicit call to & during elaboration?", + "info: implicit call to & during elaboration?$?", Ent); else Elab_Warning ("call to & may raise Program_Error?l?", - "info: call to & during elaboration?", + "info: call to & during elaboration?$?", Ent); end if; end if; @@ -977,13 +955,13 @@ package body Sem_Elab is if Nkind (N) in N_Subprogram_Instantiation then Elab_Warning ("\missing pragma Elaborate for&?l?", - "\info: implicit pragma Elaborate for& generated?", + "\implicit pragma Elaborate for& generated?$?", W_Scope); else Elab_Warning ("\missing pragma Elaborate_All for&?l?", - "\info: implicit pragma Elaborate_All for & generated?", + "\implicit pragma Elaborate_All for & generated?$?", W_Scope); end if; end Generate_Elab_Warnings; @@ -1063,7 +1041,7 @@ package body Sem_Elab is Error_Msg_Node_2 := W_Scope; Error_Msg_NE ("info: call to& in elaboration code " & - "requires pragma Elaborate_All on&?", N, E); + "requires pragma Elaborate_All on&?$?", N, E); end if; -- Set indication for binder to generate Elaborate_All @@ -1302,6 +1280,7 @@ package body Sem_Elab is -- First case, we are in elaboration code From_Elab_Code := not In_Subprogram_Or_Concurrent_Unit; + if From_Elab_Code then -- Complain if call that comes from source in preelaborated unit @@ -1317,7 +1296,7 @@ package body Sem_Elab is Error_Msg_Warn := GNAT_Mode; Error_Msg_N - ("<non-static call not allowed in preelaborated unit", N); + ("<<non-static call not allowed in preelaborated unit", N); return; end if; @@ -1482,7 +1461,15 @@ package body Sem_Elab is Inter_Unit_Only => False, In_Init_Proc => In_Init_Proc); - elsif Elaboration_Checks_Suppressed (Current_Scope) then + -- Nothing to do if elaboration checks suppressed for this scope. + -- However, an interesting exception, the fact that elaboration checks + -- are suppressed within an instance (because we can trace the body when + -- we process the template) does not extend to calls to generic formal + -- subprograms. + + elsif Elaboration_Checks_Suppressed (Current_Scope) + and then not Is_Call_Of_Generic_Formal (N) + then null; elsif From_Elab_Code then @@ -2320,15 +2307,14 @@ package body Sem_Elab is if Inst_Case then Error_Msg_NE - ("instantiation of& may occur before body is seen<<", + ("instantiation of& may occur before body is seen<l<", N, Orig_Ent); else Error_Msg_NE - ("call to& may occur before body is seen<<", N, Orig_Ent); + ("call to& may occur before body is seen<l<", N, Orig_Ent); end if; - Error_Msg_N - ("\Program_Error ]<<", N); + Error_Msg_N ("\Program_Error ]<l<", N); Output_Calls (N); end if; @@ -2570,7 +2556,7 @@ package body Sem_Elab is Error_Msg_Node_2 := Task_Scope; Error_Msg_NE ("info: activation of an instance of task type&" & - " requires pragma Elaborate_All on &?", N, Ent); + " requires pragma Elaborate_All on &?$?", N, Ent); end if; Activate_Elaborate_All_Desirable (N, Task_Scope); @@ -2595,6 +2581,26 @@ package body Sem_Elab is In_Task_Activation := False; end Check_Task_Activation; + ------------------------------- + -- Is_Call_Of_Generic_Formal -- + ------------------------------- + + function Is_Call_Of_Generic_Formal (N : Node_Id) return Boolean is + begin + return Nkind_In (N, N_Function_Call, N_Procedure_Call_Statement) + + -- Always return False if debug flag -gnatd.G is set + + and then not Debug_Flag_Dot_GG + + -- For now, we detect this by looking for the strange identifier + -- node, whose Chars reflect the name of the generic formal, but + -- the Chars of the Entity references the generic actual. + + and then Nkind (Name (N)) = N_Identifier + and then Chars (Name (N)) /= Chars (Entity (Name (N))); + end Is_Call_Of_Generic_Formal; + -------------------------------- -- Set_Elaboration_Constraint -- -------------------------------- @@ -3056,6 +3062,10 @@ package body Sem_Elab is -- by the error message circuits (i.e. it has a single upper -- case letter at the end). + ----------------------------- + -- Is_Printable_Error_Name -- + ----------------------------- + function Is_Printable_Error_Name (Nm : Name_Id) return Boolean is begin if not Is_Internal_Name (Nm) then @@ -3078,17 +3088,31 @@ package body Sem_Elab is Ent := Elab_Call.Table (J).Ent; - if Is_Generic_Unit (Ent) then - Error_Msg_NE ("\??& instantiated #", N, Ent); + -- Dynamic elaboration model, warnings controlled by -gnatwl - elsif Is_Init_Proc (Ent) then - Error_Msg_N ("\??initialization procedure called #", N); + if Dynamic_Elaboration_Checks then + if Is_Generic_Unit (Ent) then + Error_Msg_NE ("\\?l?& instantiated #", N, Ent); + elsif Is_Init_Proc (Ent) then + Error_Msg_N ("\\?l?initialization procedure called #", N); + elsif Is_Printable_Error_Name (Chars (Ent)) then + Error_Msg_NE ("\\?l?& called #", N, Ent); + else + Error_Msg_N ("\\?l?called #", N); + end if; - elsif Is_Printable_Error_Name (Chars (Ent)) then - Error_Msg_NE ("\??& called #", N, Ent); + -- Static elaboration model, info messages controlled by -gnatel else - Error_Msg_N ("\?? called #", N); + if Is_Generic_Unit (Ent) then + Error_Msg_NE ("\\?$?& instantiated #", N, Ent); + elsif Is_Init_Proc (Ent) then + Error_Msg_N ("\\?$?initialization procedure called #", N); + elsif Is_Printable_Error_Name (Chars (Ent)) then + Error_Msg_NE ("\\?$?& called #", N, Ent); + else + Error_Msg_N ("\\?$?called #", N); + end if; end if; end loop; end Output_Calls; diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb index 3c06188b97e..27eab6e2d19 100644 --- a/gcc/ada/sem_eval.adb +++ b/gcc/ada/sem_eval.adb @@ -102,7 +102,7 @@ package body Sem_Eval is type Bits is array (Nat range <>) of Boolean; -- Used to convert unsigned (modular) values for folding logical ops - -- The following definitions are used to maintain a cache of nodes that + -- The following declarations are used to maintain a cache of nodes that -- have compile time known values. The cache is maintained only for -- discrete types (the most common case), and is populated by calls to -- Compile_Time_Known_Value and Expr_Value, but only used by Expr_Value @@ -138,43 +138,43 @@ package body Sem_Eval is ----------------------- function From_Bits (B : Bits; T : Entity_Id) return Uint; - -- Converts a bit string of length B'Length to a Uint value to be used - -- for a target of type T, which is a modular type. This procedure - -- includes the necessary reduction by the modulus in the case of a - -- non-binary modulus (for a binary modulus, the bit string is the - -- right length any way so all is well). + -- Converts a bit string of length B'Length to a Uint value to be used for + -- a target of type T, which is a modular type. This procedure includes the + -- necessary reduction by the modulus in the case of a non-binary modulus + -- (for a binary modulus, the bit string is the right length any way so all + -- is well). function Get_String_Val (N : Node_Id) return Node_Id; - -- Given a tree node for a folded string or character value, returns - -- the corresponding string literal or character literal (one of the - -- two must be available, or the operand would not have been marked - -- as foldable in the earlier analysis of the operation). + -- Given a tree node for a folded string or character value, returns the + -- corresponding string literal or character literal (one of the two must + -- be available, or the operand would not have been marked as foldable in + -- the earlier analysis of the operation). function OK_Bits (N : Node_Id; Bits : Uint) return Boolean; -- Bits represents the number of bits in an integer value to be computed -- (but the value has not been computed yet). If this value in Bits is - -- reasonable, a result of True is returned, with the implication that - -- the caller should go ahead and complete the calculation. If the value - -- in Bits is unreasonably large, then an error is posted on node N, and + -- reasonable, a result of True is returned, with the implication that the + -- caller should go ahead and complete the calculation. If the value in + -- Bits is unreasonably large, then an error is posted on node N, and -- False is returned (and the caller skips the proposed calculation). procedure Out_Of_Range (N : Node_Id); - -- This procedure is called if it is determined that node N, which - -- appears in a non-static context, is a compile time known value - -- which is outside its range, i.e. the range of Etype. This is used - -- in contexts where this is an illegality if N is static, and should - -- generate a warning otherwise. + -- This procedure is called if it is determined that node N, which appears + -- in a non-static context, is a compile time known value which is outside + -- its range, i.e. the range of Etype. This is used in contexts where + -- this is an illegality if N is static, and should generate a warning + -- otherwise. procedure Rewrite_In_Raise_CE (N : Node_Id; Exp : Node_Id); - -- N and Exp are nodes representing an expression, Exp is known - -- to raise CE. N is rewritten in term of Exp in the optimal way. + -- N and Exp are nodes representing an expression, Exp is known to raise + -- CE. N is rewritten in term of Exp in the optimal way. function String_Type_Len (Stype : Entity_Id) return Uint; - -- Given a string type, determines the length of the index type, or, - -- if this index type is non-static, the length of the base type of - -- this index type. Note that if the string type is itself static, - -- then the index type is static, so the second case applies only - -- if the string type passed is non-static. + -- Given a string type, determines the length of the index type, or, if + -- this index type is non-static, the length of the base type of this index + -- type. Note that if the string type is itself static, then the index type + -- is static, so the second case applies only if the string type passed is + -- non-static. function Test (Cond : Boolean) return Uint; pragma Inline (Test); @@ -184,13 +184,12 @@ package body Sem_Eval is -- logical operators function Find_Universal_Operator_Type (N : Node_Id) return Entity_Id; - -- Check whether an arithmetic operation with universal operands which - -- is a rewritten function call with an explicit scope indication is - -- ambiguous: P."+" (1, 2) will be ambiguous if there is more than one - -- visible numeric type declared in P and the context does not impose a - -- type on the result (e.g. in the expression of a type conversion). - -- If ambiguous, emit an error and return Empty, else return the result - -- type of the operator. + -- Check whether an arithmetic operation with universal operands which is a + -- rewritten function call with an explicit scope indication is ambiguous: + -- P."+" (1, 2) will be ambiguous if there is more than one visible numeric + -- type declared in P and the context does not impose a type on the result + -- (e.g. in the expression of a type conversion). If ambiguous, emit an + -- error and return Empty, else return the result type of the operator. procedure Test_Expression_Is_Foldable (N : Node_Id; @@ -199,29 +198,29 @@ package body Sem_Eval is Fold : out Boolean); -- Tests to see if expression N whose single operand is Op1 is foldable, -- i.e. the operand value is known at compile time. If the operation is - -- foldable, then Fold is True on return, and Stat indicates whether - -- the result is static (i.e. the operand was static). Note that it - -- is quite possible for Fold to be True, and Stat to be False, since - -- there are cases in which we know the value of an operand even though - -- it is not technically static (e.g. the static lower bound of a range - -- whose upper bound is non-static). + -- foldable, then Fold is True on return, and Stat indicates whether the + -- result is static (i.e. the operand was static). Note that it is quite + -- possible for Fold to be True, and Stat to be False, since there are + -- cases in which we know the value of an operand even though it is not + -- technically static (e.g. the static lower bound of a range whose upper + -- bound is non-static). -- - -- If Stat is set False on return, then Test_Expression_Is_Foldable makes a - -- call to Check_Non_Static_Context on the operand. If Fold is False on - -- return, then all processing is complete, and the caller should - -- return, since there is nothing else to do. + -- If Stat is set False on return, then Test_Expression_Is_Foldable makes + -- a call to Check_Non_Static_Context on the operand. If Fold is False on + -- return, then all processing is complete, and the caller should return, + -- since there is nothing else to do. -- -- If Stat is set True on return, then Is_Static_Expression is also set -- true in node N. There are some cases where this is over-enthusiastic, - -- e.g. in the two operand case below, for string comparison, the result - -- is not static even though the two operands are static. In such cases, - -- the caller must reset the Is_Static_Expression flag in N. + -- e.g. in the two operand case below, for string comparison, the result is + -- not static even though the two operands are static. In such cases, the + -- caller must reset the Is_Static_Expression flag in N. -- -- If Fold and Stat are both set to False then this routine performs also -- the following extra actions: -- - -- If either operand is Any_Type then propagate it to result to - -- prevent cascaded errors. + -- If either operand is Any_Type then propagate it to result to prevent + -- cascaded errors. -- -- If some operand raises constraint error, then replace the node N -- with the raise constraint error node. This replacement inherits the @@ -278,8 +277,8 @@ package body Sem_Eval is end if; -- At this stage we have a scalar type. If we have an expression that - -- raises CE, then we already issued a warning or error msg so there - -- is nothing more to be done in this routine. + -- raises CE, then we already issued a warning or error msg so there is + -- nothing more to be done in this routine. if Raises_Constraint_Error (N) then return; @@ -370,7 +369,7 @@ package body Sem_Eval is and then Nkind (Parent (N)) in N_Subexpr and then (Intval (N) < Expr_Value (Type_Low_Bound (Universal_Integer)) - or else + or else Intval (N) > Expr_Value (Type_High_Bound (Universal_Integer))) then Apply_Compile_Time_Constraint_Error @@ -387,9 +386,7 @@ package body Sem_Eval is -- appears in a range that could be null (warnings are handled elsewhere -- for this case). - elsif T /= Base_Type (T) - and then Nkind (Parent (N)) /= N_Range - then + elsif T /= Base_Type (T) and then Nkind (Parent (N)) /= N_Range then if Is_In_Range (N, T, Assume_Valid => True) then null; @@ -413,8 +410,7 @@ package body Sem_Eval is procedure Check_String_Literal_Length (N : Node_Id; Ttype : Entity_Id) is begin if not Raises_Constraint_Error (N) and then Is_Constrained (Ttype) then - if - UI_From_Int (String_Length (Strval (N))) /= String_Type_Len (Ttype) + if UI_From_Int (String_Length (Strval (N))) /= String_Type_Len (Ttype) then Apply_Compile_Time_Constraint_Error (N, "string length wrong for}??", @@ -550,9 +546,9 @@ package body Sem_Eval is Xtyp := Designated_Type (Xtyp); end if; - -- If we don't have an array type at this stage, something - -- is peculiar, e.g. another error, and we abandon the attempt - -- at a fixup. + -- If we don't have an array type at this stage, something is + -- peculiar, e.g. another error, and we abandon the attempt at + -- a fixup. if not Is_Array_Type (Xtyp) then return N; @@ -567,11 +563,11 @@ package body Sem_Eval is if Ekind (Xtyp) = E_String_Literal_Subtype then if Attribute_Name (N) = Name_First then return String_Literal_Low_Bound (Xtyp); - else - return Make_Integer_Literal (Sloc (N), - Intval => Intval (String_Literal_Low_Bound (Xtyp)) - + String_Literal_Length (Xtyp)); + return + Make_Integer_Literal (Sloc (N), + Intval => Intval (String_Literal_Low_Bound (Xtyp)) + + String_Literal_Length (Xtyp)); end if; end if; @@ -611,7 +607,7 @@ package body Sem_Eval is or else Ekind (Entity (Opnd)) = E_In_Parameter or else (Ekind (Entity (Opnd)) in Object_Kind - and then Present (Current_Value (Entity (Opnd)))))) + and then Present (Current_Value (Entity (Opnd)))))) or else Is_OK_Static_Expression (Opnd); end Is_Known_Valid_Operand; @@ -814,7 +810,8 @@ package body Sem_Eval is -- Case where comparison involves two compile time known values elsif Compile_Time_Known_Value (L) - and then Compile_Time_Known_Value (R) + and then + Compile_Time_Known_Value (R) then -- For the floating-point case, we have to be a little careful, since -- at compile time we are dealing with universal exact values, but at @@ -828,7 +825,6 @@ package body Sem_Eval is declare Lo : constant Ureal := Expr_Value_R (L); Hi : constant Ureal := Expr_Value_R (R); - begin if Lo < Hi then return LE; @@ -880,15 +876,12 @@ package body Sem_Eval is declare Lo : constant Uint := Expr_Value (L); Hi : constant Uint := Expr_Value (R); - begin if Lo < Hi then Diff.all := Hi - Lo; return LT; - elsif Lo = Hi then return EQ; - else Diff.all := Lo - Hi; return GT; @@ -902,7 +895,8 @@ package body Sem_Eval is -- Remaining checks apply only for discrete types if not Is_Discrete_Type (Ltyp) - or else not Is_Discrete_Type (Rtyp) + or else + not Is_Discrete_Type (Rtyp) then return Unknown; end if; @@ -933,9 +927,9 @@ package body Sem_Eval is return Unknown; end if; - -- Replace types by base types for the case of entities which are - -- not known to have valid representations. This takes care of - -- properly dealing with invalid representations. + -- Replace types by base types for the case of entities which are not + -- known to have valid representations. This takes care of properly + -- dealing with invalid representations. if not Assume_Valid and then not Assume_No_Invalid_Values then if Is_Entity_Name (L) and then not Is_Known_Valid (Entity (L)) then @@ -977,11 +971,9 @@ package body Sem_Eval is if Is_Same_Value (Lnode, Rnode) then if Loffs = Roffs then return EQ; - elsif Loffs < Roffs then Diff.all := Roffs - Loffs; return LT; - else Diff.all := Loffs - Roffs; return GT; @@ -1072,9 +1064,9 @@ package body Sem_Eval is if not Rec then - -- See if we can get a decisive check against one operand and - -- a bound of the other operand (four possible tests here). - -- Note that we avoid testing junk bounds of a generic type. + -- See if we can get a decisive check against one operand and a + -- bound of the other operand (four possible tests here). Note + -- that we avoid testing junk bounds of a generic type. if not Is_Generic_Type (Rtyp) then case Compile_Time_Compare (L, Type_Low_Bound (Rtyp), @@ -1351,13 +1343,10 @@ package body Sem_Eval is -- Other literals and NULL are known at compile time elsif - K = N_Character_Literal - or else - K = N_Real_Literal - or else - K = N_String_Literal - or else - K = N_Null + Nkind_In (K, N_Character_Literal, + N_Real_Literal, + N_String_Literal, + N_Null) then return True; @@ -1422,15 +1411,14 @@ package body Sem_Eval is if Present (Expressions (Op)) then declare Expr : Node_Id; - begin Expr := First (Expressions (Op)); while Present (Expr) loop if not Compile_Time_Known_Value_Or_Aggr (Expr) then return False; + else + Next (Expr); end if; - - Next (Expr); end loop; end; end if; @@ -1502,7 +1490,6 @@ package body Sem_Eval is procedure Eval_Allocator (N : Node_Id) is Expr : constant Node_Id := Expression (N); - begin if Nkind (Expr) = N_Qualified_Expression then Check_Non_Static_Context (Expression (Expr)); @@ -1553,7 +1540,6 @@ package body Sem_Eval is begin case Nkind (N) is - when N_Op_Add => Result := Left_Int + Right_Int; @@ -1577,8 +1563,7 @@ package body Sem_Eval is if Right_Int = 0 then Apply_Compile_Time_Constraint_Error - (N, "division by zero", - CE_Divide_By_Zero, + (N, "division by zero", CE_Divide_By_Zero, Warn => not Stat); return; @@ -1593,8 +1578,7 @@ package body Sem_Eval is if Right_Int = 0 then Apply_Compile_Time_Constraint_Error - (N, "mod with zero divisor", - CE_Divide_By_Zero, + (N, "mod with zero divisor", CE_Divide_By_Zero, Warn => not Stat); return; else @@ -1608,8 +1592,7 @@ package body Sem_Eval is if Right_Int = 0 then Apply_Compile_Time_Constraint_Error - (N, "rem with zero divisor", - CE_Divide_By_Zero, + (N, "rem with zero divisor", CE_Divide_By_Zero, Warn => not Stat); return; @@ -1776,7 +1759,6 @@ package body Sem_Eval is if Is_Static_Expression (Expression (N)) then Val := Expr_Value (Expression (N)); - else Check_Non_Static_Context (Expression (N)); Is_Static := False; @@ -2246,11 +2228,11 @@ package body Sem_Eval is -- but those have bounds smaller that those of any integer base type, -- so we can safely ignore these cases. - return K = N_Number_Declaration - or else K = N_Attribute_Reference - or else K = N_Attribute_Definition_Clause - or else K = N_Modular_Type_Definition - or else K = N_Signed_Integer_Type_Definition; + return Nkind_In (K, N_Number_Declaration, + N_Attribute_Reference, + N_Attribute_Definition_Clause, + N_Modular_Type_Definition, + N_Signed_Integer_Type_Definition); end In_Any_Integer_Context; -- Start of processing for Eval_Integer_Literal @@ -2422,7 +2404,6 @@ package body Sem_Eval is if not Is_String_Type (Def_Id) then Lo := Type_Low_Bound (Def_Id); Hi := Type_High_Bound (Def_Id); - else Lo := Empty; Hi := Empty; @@ -2480,7 +2461,6 @@ package body Sem_Eval is elsif Is_Real_Type (Etype (Right)) then declare Leftval : constant Ureal := Expr_Value_R (Left); - begin Result := Expr_Value_R (Lo) <= Leftval and then Leftval <= Expr_Value_R (Hi); @@ -2489,7 +2469,6 @@ package body Sem_Eval is else declare Leftval : constant Uint := Expr_Value (Left); - begin Result := Expr_Value (Lo) <= Leftval and then Leftval <= Expr_Value (Hi); @@ -2573,8 +2552,7 @@ package body Sem_Eval is if Right_Int < 0 then Apply_Compile_Time_Constraint_Error - (N, "integer exponent negative", - CE_Range_Check_Failed, + (N, "integer exponent negative", CE_Range_Check_Failed, Warn => not Stat); return; @@ -2606,8 +2584,7 @@ package body Sem_Eval is if Right_Int < 0 then Apply_Compile_Time_Constraint_Error - (N, "zero ** negative integer", - CE_Range_Check_Failed, + (N, "zero ** negative integer", CE_Range_Check_Failed, Warn => not Stat); return; else @@ -2657,9 +2634,7 @@ package body Sem_Eval is if Is_Modular_Integer_Type (Typ) then Fold_Uint (N, Modulus (Typ) - 1 - Rint, Stat); - - else - pragma Assert (Is_Boolean_Type (Typ)); + else pragma Assert (Is_Boolean_Type (Typ)); Fold_Uint (N, Test (not Is_True (Rint)), Stat); end if; @@ -2812,7 +2787,8 @@ package body Sem_Eval is and then (Nkind (N) = N_Op_Eq or else Nkind (N) = N_Op_Ne) then if Raises_Constraint_Error (Left) - or else Raises_Constraint_Error (Right) + or else + Raises_Constraint_Error (Right) then return; end if; @@ -2854,10 +2830,8 @@ package body Sem_Eval is -- The simple case, both bounds are known at compile time if Is_Discrete_Type (T) - and then - Compile_Time_Known_Value (Type_Low_Bound (T)) - and then - Compile_Time_Known_Value (Type_High_Bound (T)) + and then Compile_Time_Known_Value (Type_Low_Bound (T)) + and then Compile_Time_Known_Value (Type_High_Bound (T)) then Len := UI_Max (Uint_0, Expr_Value (Type_High_Bound (T)) - @@ -2879,11 +2853,11 @@ package body Sem_Eval is Ent : out Entity_Id; Kind : out Character; Cons : out Uint); - -- Given an expression, see if is of the form above, - -- X [+/- K]. If so Ent is set to the entity in X, - -- Kind is 'F','L','E' for 'First/'Last/simple entity, - -- and Cons is the value of K. If the expression is - -- not of the required form, Ent is set to Empty. + -- Given an expression see if it is of the form given above, + -- X [+/- K]. If so Ent is set to the entity in X, Kind is + -- 'F','L','E' for 'First/'Last/simple entity, and Cons is + -- the value of K. If the expression is not of the required + -- form, Ent is set to Empty. -------------------- -- Decompose_Expr -- @@ -2940,10 +2914,8 @@ package body Sem_Eval is if Nkind (Exp) = N_Attribute_Reference then if Attribute_Name (Exp) = Name_First then Kind := 'F'; - elsif Attribute_Name (Exp) = Name_Last then Kind := 'L'; - else Ent := Empty; return; @@ -2955,8 +2927,7 @@ package body Sem_Eval is Kind := 'E'; end if; - if Is_Entity_Name (Exp) - and then Present (Entity (Exp)) + if Is_Entity_Name (Exp) and then Present (Entity (Exp)) then Ent := Entity (Exp); else @@ -3013,7 +2984,8 @@ package body Sem_Eval is declare Is_Static_Expression : Boolean; - Is_Foldable : Boolean; + + Is_Foldable : Boolean; pragma Unreferenced (Is_Foldable); begin @@ -3287,6 +3259,7 @@ package body Sem_Eval is procedure Eval_Slice (N : Node_Id) is Drange : constant Node_Id := Discrete_Range (N); + begin if Nkind (Drange) = N_Range then Check_Non_Static_Context (Low_Bound (Drange)); @@ -3301,6 +3274,7 @@ package body Sem_Eval is declare E : constant Entity_Id := Entity (Prefix (N)); T : constant Entity_Id := Etype (E); + begin if Ekind (E) = E_Constant and then Is_Array_Type (T) @@ -3345,10 +3319,11 @@ package body Sem_Eval is -- membership test can be evaluated statically. The caller transforms -- a result of False into a static contraint error. - Test := Make_In (Loc, - Left_Opnd => New_Copy_Tree (N), - Right_Opnd => Empty, - Alternatives => Pred); + Test := + Make_In (Loc, + Left_Opnd => New_Copy_Tree (N), + Right_Opnd => Empty, + Alternatives => Pred); Analyze_And_Resolve (Test, Standard_Boolean); return Nkind (Test) = N_Identifier @@ -3389,7 +3364,7 @@ package body Sem_Eval is -- but may be possible in future). elsif not Is_OK_Static_Expression - (Type_Low_Bound (Etype (First_Index (Typ)))) + (Type_Low_Bound (Etype (First_Index (Typ)))) then Set_Is_Static_Expression (N, False); return; @@ -3534,7 +3509,6 @@ package body Sem_Eval is if not Is_Static_Subtype (Target_Type) then Check_Non_Static_Context (Operand); return; - elsif Error_Posted (N) then return; end if; @@ -3561,7 +3535,6 @@ package body Sem_Eval is if Is_String_Type (Target_Type) then Fold_Str (N, Strval (Get_String_Val (Operand)), Static => False); - return; -- Fold conversion, case of integer target type @@ -3698,10 +3671,8 @@ package body Sem_Eval is begin if Nkind (N) = N_Op_Plus then Result := Rreal; - elsif Nkind (N) = N_Op_Minus then Result := UR_Negate (Rreal); - else pragma Assert (Nkind (N) = N_Op_Abs); Result := abs Rreal; @@ -3848,7 +3819,6 @@ package body Sem_Eval is -- obtain the desired value from Corresponding_Integer_Value. elsif Kind = N_Real_Literal then - pragma Assert (Is_Fixed_Point_Type (Underlying_Type (Etype (N)))); Val := Corresponding_Integer_Value (N); @@ -3891,7 +3861,6 @@ package body Sem_Eval is function Expr_Value_E (N : Node_Id) return Entity_Id is Ent : constant Entity_Id := Entity (N); - begin if Ekind (Ent) = E_Enumeration_Literal then return Ent; @@ -4046,10 +4015,9 @@ package body Sem_Eval is and then Nkind (Parent (E)) /= N_Subtype_Declaration and then Comes_From_Source (E) and then Is_Integer_Type (E) = Is_Int - and then - (Nkind (N) in N_Unary_Op - or else Is_Relational - or else Is_Fixed_Point_Type (E) = Is_Fix) + and then (Nkind (N) in N_Unary_Op + or else Is_Relational + or else Is_Fixed_Point_Type (E) = Is_Fix) then if No (Typ1) then Typ1 := E; @@ -4141,9 +4109,7 @@ package body Sem_Eval is -- If we are folding a named number, retain the entity in the literal, -- for ASIS use. - if Is_Entity_Name (N) - and then Ekind (Entity (N)) = E_Named_Integer - then + if Is_Entity_Name (N) and then Ekind (Entity (N)) = E_Named_Integer then Ent := Entity (N); else Ent := Empty; @@ -4160,7 +4126,6 @@ package body Sem_Eval is if Is_Integer_Type (Typ) then Rewrite (N, Make_Integer_Literal (Loc, Val)); - Set_Original_Entity (N, Ent); -- Otherwise we have an enumeration type, and we substitute either @@ -4201,9 +4166,7 @@ package body Sem_Eval is -- If we are folding a named number, retain the entity in the literal, -- for ASIS use. - if Is_Entity_Name (N) - and then Ekind (Entity (N)) = E_Named_Real - then + if Is_Entity_Name (N) and then Ekind (Entity (N)) = E_Named_Real then Ent := Entity (N); else Ent := Empty; @@ -4258,12 +4221,8 @@ package body Sem_Eval is function Get_String_Val (N : Node_Id) return Node_Id is begin - if Nkind (N) = N_String_Literal then - return N; - - elsif Nkind (N) = N_Character_Literal then + if Nkind_In (N, N_String_Literal, N_Character_Literal) then return N; - else pragma Assert (Is_Entity_Name (N)); return Get_String_Val (Constant_Value (Entity (N))); @@ -4402,8 +4361,8 @@ package body Sem_Eval is Int_Real : Boolean := False) return Boolean is begin - return Test_In_Range (N, Typ, Assume_Valid, Fixed_Int, Int_Real) - = In_Range; + return + Test_In_Range (N, Typ, Assume_Valid, Fixed_Int, Int_Real) = In_Range; end Is_In_Range; ------------------- @@ -4422,9 +4381,7 @@ package body Sem_Eval is if Is_Discrete_Type (Typ) then return Expr_Value (Lo) > Expr_Value (Hi); - - else - pragma Assert (Is_Real_Type (Typ)); + else pragma Assert (Is_Real_Type (Typ)); return Expr_Value_R (Lo) > Expr_Value_R (Hi); end if; end Is_Null_Range; @@ -4435,8 +4392,7 @@ package body Sem_Eval is function Is_OK_Static_Expression (N : Node_Id) return Boolean is begin - return Is_Static_Expression (N) - and then not Raises_Constraint_Error (N); + return Is_Static_Expression (N) and then not Raises_Constraint_Error (N); end Is_OK_Static_Expression; ------------------------ @@ -4528,8 +4484,8 @@ package body Sem_Eval is Int_Real : Boolean := False) return Boolean is begin - return Test_In_Range (N, Typ, Assume_Valid, Fixed_Int, Int_Real) - = Out_Of_Range; + return Test_In_Range (N, Typ, Assume_Valid, Fixed_Int, Int_Real) = + Out_Of_Range; end Is_Out_Of_Range; --------------------- @@ -4544,7 +4500,8 @@ package body Sem_Eval is function Is_Static_Range (N : Node_Id) return Boolean is begin return Is_Static_Expression (Low_Bound (N)) - and then Is_Static_Expression (High_Bound (N)); + and then + Is_Static_Expression (High_Bound (N)); end Is_Static_Range; ----------------------- @@ -4620,10 +4577,7 @@ package body Sem_Eval is if Is_Discrete_Type (Typ) then return Expr_Value (Lo) <= Expr_Value (Hi); - - else - pragma Assert (Is_Real_Type (Typ)); - + else pragma Assert (Is_Real_Type (Typ)); return Expr_Value_R (Lo) <= Expr_Value_R (Hi); end if; end Not_Null_Range; @@ -4639,6 +4593,8 @@ package body Sem_Eval is if Bits < 500_000 then return True; + -- Error if this maximum is exceeded + else Error_Msg_N ("static value too large, capacity exceeded", N); return False; @@ -5104,8 +5060,7 @@ package body Sem_Eval is -- checking on an inherited operation may compare the actual with the -- subtype that renames it in the instance. - elsif - Has_Unknown_Discriminants (T1) /= Has_Unknown_Discriminants (T2) + elsif Has_Unknown_Discriminants (T1) /= Has_Unknown_Discriminants (T2) then return Is_Generic_Actual_Type (T1) or else Is_Generic_Actual_Type (T2); @@ -5257,7 +5212,8 @@ package body Sem_Eval is CRT_Safe : Boolean := False) is Rstat : constant Boolean := Is_Static_Expression (Op1) - and then Is_Static_Expression (Op2); + and then + Is_Static_Expression (Op2); begin Stat := False; @@ -5435,9 +5391,7 @@ package body Sem_Eval is Val := Expr_Value (N); if LB_Known and HB_Known then - if Val >= Expr_Value (Lo) - and then - Val <= Expr_Value (Hi) + if Val >= Expr_Value (Lo) and then Val <= Expr_Value (Hi) then return In_Range; else @@ -5501,15 +5455,6 @@ package body Sem_Eval is -- Start of processing for Why_Not_Static begin - -- If in ACATS mode (debug flag 2), then suppress all these messages, - -- this avoids massive updates to the ACATS base line. But if the flag - -- d.z is set, then don't suppress the messages. This is a temporary - -- kludge to aid in doing the necessary updates to the ACATS base line. - - if Debug_Flag_2 and then not Debug_Flag_Dot_Z then - return; - end if; - -- Ignore call on error or empty node if No (Expr) or else Nkind (Expr) = N_Error then @@ -5530,8 +5475,8 @@ package body Sem_Eval is if Raises_Constraint_Error (Expr) then Error_Msg_N - ("!expression raises exception, cannot be static " & - "(RM 4.9(34))", N); + ("!expression raises exception, cannot be static (RM 4.9(34))", + N); return; end if; @@ -5592,6 +5537,7 @@ package body Sem_Eval is if Nkind (Original_Node (N)) = N_Aggregate then Error_Msg_Sloc := Sloc (Original_Node (N)); return True; + elsif Is_Entity_Name (N) and then Ekind (Entity (N)) = E_Constant and then @@ -5601,6 +5547,7 @@ package body Sem_Eval is Error_Msg_Sloc := Sloc (Original_Node (Constant_Value (Entity (N)))); return True; + else return False; end if; @@ -5635,7 +5582,6 @@ package body Sem_Eval is if Nkind (N) in N_Op_Shift then Error_Msg_N ("!shift functions are never static (RM 4.9(6,18))", N); - else Why_Not_Static (Left_Opnd (N)); Why_Not_Static (Right_Opnd (N)); @@ -5667,11 +5613,9 @@ package body Sem_Eval is -- Flag array cases elsif Is_Array_Type (E) then - if Attribute_Name (N) /= Name_First - and then - Attribute_Name (N) /= Name_Last - and then - Attribute_Name (N) /= Name_Length + if not Nam_In (Attribute_Name (N), Name_First, + Name_Last, + Name_Length) then Error_Msg_N ("!static array attribute must be Length, First, or Last " @@ -5690,10 +5634,7 @@ package body Sem_Eval is -- Special case generic types, since again this is a common source -- of confusion. - elsif Is_Generic_Actual_Type (E) - or else - Is_Generic_Type (E) - then + elsif Is_Generic_Actual_Type (E) or else Is_Generic_Type (E) then Error_Msg_N ("!attribute of generic type is never static " & "(RM 4.9(7,8))", N); diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb index 30607203141..f95fb3b12c9 100644 --- a/gcc/ada/sem_prag.adb +++ b/gcc/ada/sem_prag.adb @@ -184,19 +184,6 @@ 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. - procedure Check_Dependence_List_Syntax (List : Node_Id); - -- Subsidiary to the analysis of pragmas Depends and Refined_Depends. - -- Verify the syntax of dependence relation List. - - procedure Check_Global_List_Syntax (List : Node_Id); - -- Subsidiary to the analysis of pragmas Global and Refined_Global. Verify - -- the syntax of global list List. - - procedure Check_Item_Syntax (Item : Node_Id); - -- Subsidiary to the analysis of pragmas Depends, Global, Initializes, - -- Part_Of, Refined_Depends, Refined_Depends and Refined_State. Verify the - -- syntax of a SPARK annotation item. - 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 @@ -674,7 +661,7 @@ package body Sem_Prag is if Nkind (Inputs) = N_Aggregate then if Present (Component_Associations (Inputs)) then - Error_Msg_N + SPARK_Msg_N ("nested dependency relations not allowed", Inputs); elsif Present (Expressions (Inputs)) then @@ -692,6 +679,8 @@ package body Sem_Prag is Next (Input); end loop; + -- Syntax error, always report + else Error_Msg_N ("malformed input dependency list", Inputs); end if; @@ -714,7 +703,7 @@ package body Sem_Prag is -- (null =>[+] null) if Null_Output_Seen and then Null_Input_Seen then - Error_Msg_N + SPARK_Msg_N ("null dependency clause cannot have a null input list", Inputs); end if; @@ -742,10 +731,10 @@ package body Sem_Prag is if Nkind (Item) = N_Aggregate then if not Top_Level then - Error_Msg_N ("nested grouping of items not allowed", Item); + SPARK_Msg_N ("nested grouping of items not allowed", Item); elsif Present (Component_Associations (Item)) then - Error_Msg_N + SPARK_Msg_N ("nested dependency relations not allowed", Item); -- Recursively analyze the grouped items @@ -765,6 +754,8 @@ package body Sem_Prag is Next (Grouped); end loop; + -- Syntax error, always report + else Error_Msg_N ("malformed dependency list", Item); end if; @@ -787,7 +778,7 @@ package body Sem_Prag is or else Entity (Prefix (Item)) /= Spec_Id then Error_Msg_Name_1 := Name_Result; - Error_Msg_N + SPARK_Msg_N ("prefix of attribute % must denote the enclosing " & "function", Item); @@ -795,10 +786,10 @@ package body Sem_Prag is -- dependency clause (SPARK RM 6.1.5(6)). elsif Is_Input then - Error_Msg_N ("function result cannot act as input", Item); + SPARK_Msg_N ("function result cannot act as input", Item); elsif Null_Seen then - Error_Msg_N + SPARK_Msg_N ("cannot mix null and non-null dependency items", Item); else @@ -811,11 +802,11 @@ package body Sem_Prag is elsif Nkind (Item) = N_Null then if Null_Seen then - Error_Msg_N + SPARK_Msg_N ("multiple null dependency relations not allowed", Item); elsif Non_Null_Seen then - Error_Msg_N + SPARK_Msg_N ("cannot mix null and non-null dependency items", Item); else @@ -823,7 +814,7 @@ package body Sem_Prag is if Is_Output then if not Is_Last then - Error_Msg_N + SPARK_Msg_N ("null output list must be the last clause in a " & "dependency relation", Item); @@ -831,7 +822,7 @@ package body Sem_Prag is -- null =>+ ... elsif Self_Ref then - Error_Msg_N + SPARK_Msg_N ("useless dependence, null depends on itself", Item); end if; end if; @@ -843,7 +834,7 @@ package body Sem_Prag is Non_Null_Seen := True; if Null_Seen then - Error_Msg_N ("cannot mix null and non-null items", Item); + SPARK_Msg_N ("cannot mix null and non-null items", Item); end if; Analyze (Item); @@ -873,7 +864,7 @@ package body Sem_Prag is -- item to the list of processed relations. if Contains (Seen, Item_Id) then - Error_Msg_NE + SPARK_Msg_NE ("duplicate use of item &", Item, Item_Id); else Add_Item (Item_Id, Seen); @@ -887,7 +878,7 @@ package body Sem_Prag is and then Null_Output_Seen and then Contains (All_Inputs_Seen, Item_Id) then - Error_Msg_N + SPARK_Msg_N ("input of a null output list cannot appear in " & "multiple input lists", Item); end if; @@ -903,10 +894,10 @@ package body Sem_Prag is if Ekind (Item_Id) = E_Abstract_State then if Has_Visible_Refinement (Item_Id) then - Error_Msg_NE + SPARK_Msg_NE ("cannot mention state & in global refinement", Item, Item_Id); - Error_Msg_N + SPARK_Msg_N ("\use its constituents instead", Item); return; @@ -948,18 +939,17 @@ package body Sem_Prag is -- (SPARK RM 6.1.5(1)). else - Error_Msg_N + SPARK_Msg_N ("item must denote parameter, variable, or state", Item); end if; -- All other input/output items are illegal - -- (SPARK RM 6.1.5(1)) + -- (SPARK RM 6.1.5(1)). This is a syntax error, always report. else Error_Msg_N - ("item must denote parameter, variable, or state", - Item); + ("item must denote parameter, variable, or state", Item); end if; end if; end Analyze_Input_Output; @@ -1015,7 +1005,7 @@ package body Sem_Prag is procedure Check_Function_Return is begin if Ekind (Spec_Id) = E_Function and then not Result_Seen then - Error_Msg_NE + SPARK_Msg_NE ("result of & must appear in exactly one output list", N, Spec_Id); end if; @@ -1164,10 +1154,10 @@ package body Sem_Prag is (" & cannot appear in dependence relation"); Error_Msg := Name_Find; - Error_Msg_NE (Get_Name_String (Error_Msg), Item, Item_Id); + SPARK_Msg_NE (Get_Name_String (Error_Msg), Item, Item_Id); Error_Msg_Name_1 := Chars (Subp_Id); - Error_Msg_NE + SPARK_Msg_NE ("\& is not part of the input or output set of subprogram %", Item, Item_Id); @@ -1194,7 +1184,7 @@ package body Sem_Prag is Add_Str_To_Name_Buffer (" in dependence relation"); Error_Msg := Name_Find; - Error_Msg_NE (Get_Name_String (Error_Msg), Item, Item_Id); + SPARK_Msg_NE (Get_Name_String (Error_Msg), Item, Item_Id); end if; end Role_Error; @@ -1266,7 +1256,7 @@ package body Sem_Prag is (" & must appear in at least one input dependence list"); Error_Msg := Name_Find; - Error_Msg_NE (Get_Name_String (Error_Msg), Item, Item_Id); + SPARK_Msg_NE (Get_Name_String (Error_Msg), Item, Item_Id); end if; -- Output case (SPARK RM 6.1.5(10)) @@ -1279,7 +1269,7 @@ package body Sem_Prag is (" & must appear in exactly one output dependence list"); Error_Msg := Name_Find; - Error_Msg_NE (Get_Name_String (Error_Msg), Item, Item_Id); + SPARK_Msg_NE (Get_Name_String (Error_Msg), Item, Item_Id); end if; end Usage_Error; @@ -1486,7 +1476,7 @@ package body Sem_Prag is -- appear in the input list of a relation (SPARK RM 6.1.5(10)). elsif Is_Attribute_Result (Output) then - Error_Msg_N ("function result cannot depend on itself", Output); + SPARK_Msg_N ("function result cannot depend on itself", Output); return; end if; @@ -1683,14 +1673,6 @@ package body Sem_Prag is begin Set_Analyzed (N); - -- Verify the syntax of pragma Depends when SPARK checks are suppressed. - -- Semantic analysis and normalization are disabled in this mode. - - if SPARK_Mode = Off then - Check_Dependence_List_Syntax (Deps); - return; - end if; - Subp_Decl := Find_Related_Subprogram_Or_Body (N); Subp_Id := Defining_Entity (Subp_Decl); @@ -1700,11 +1682,13 @@ package body Sem_Prag is -- Refined_Depends. if Nkind (Subp_Decl) = N_Subprogram_Body - and then not Acts_As_Spec (Subp_Decl) + and then Present (Corresponding_Spec (Subp_Decl)) then Spec_Id := Corresponding_Spec (Subp_Decl); - elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub then + elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub + and then Present (Corresponding_Spec_Of_Stub (Subp_Decl)) + then Spec_Id := Corresponding_Spec_Of_Stub (Subp_Decl); else @@ -1807,14 +1791,16 @@ package body Sem_Prag is Check_Usage (Subp_Outputs, All_Outputs_Seen, False); Check_Function_Return; - -- The dependency list is malformed + -- The dependency list is malformed. This is a syntax error, always + -- report. else Error_Msg_N ("malformed dependency relation", Deps); return; end if; - -- The top level dependency relation is malformed + -- The top level dependency relation is malformed. This is a syntax + -- error, always report. else Error_Msg_N ("malformed dependency relation", Deps); @@ -1853,10 +1839,10 @@ package body Sem_Prag is and then Present (Entity (Obj)) and then Is_Formal (Entity (Obj)) then - Error_Msg_N ("external property % cannot apply to parameter", N); + SPARK_Msg_N ("external property % cannot apply to parameter", N); end if; else - Error_Msg_N + SPARK_Msg_N ("external property % must apply to a volatile object", N); end if; @@ -1872,7 +1858,7 @@ package body Sem_Prag is Expr_Val := Is_True (Expr_Value (Expr)); else Error_Msg_Name_1 := Pragma_Name (N); - Error_Msg_N ("expression of % must be static", Expr); + SPARK_Msg_N ("expression of % must be static", Expr); end if; end if; end Analyze_External_Property_In_Decl_Part; @@ -1967,7 +1953,7 @@ package body Sem_Prag is -- with Global => (Name, null) if Nkind (Item) = N_Null then - Error_Msg_N ("cannot mix null and non-null global items", Item); + SPARK_Msg_N ("cannot mix null and non-null global items", Item); return; end if; @@ -1988,7 +1974,7 @@ package body Sem_Prag is if Is_Formal (Item_Id) then if Scope (Item_Id) = Spec_Id then - Error_Msg_NE + SPARK_Msg_NE ("global item cannot reference parameter of subprogram", Item, Spec_Id); return; @@ -1998,13 +1984,13 @@ package body Sem_Prag is -- Do this check first to provide a better error diagnostic. elsif Ekind (Item_Id) = E_Constant then - Error_Msg_N ("global item cannot denote a constant", Item); + SPARK_Msg_N ("global item cannot denote a constant", Item); -- The only legal references are those to abstract states and -- variables (SPARK RM 6.1.4(4)). elsif not Ekind_In (Item_Id, E_Abstract_State, E_Variable) then - Error_Msg_N + SPARK_Msg_N ("global item must denote variable or state", Item); return; end if; @@ -2018,10 +2004,10 @@ package body Sem_Prag is -- some of its constituents (SPARK RM 6.1.4(8)). if Has_Visible_Refinement (Item_Id) then - Error_Msg_NE + SPARK_Msg_NE ("cannot mention state & in global refinement", Item, Item_Id); - Error_Msg_N ("\use its constituents instead", Item); + SPARK_Msg_N ("\use its constituents instead", Item); return; -- If the reference to the abstract state appears in an @@ -2091,7 +2077,7 @@ package body Sem_Prag is -- (SPARK RM 6.1.4(11)). if Contains (Seen, Item_Id) then - Error_Msg_N ("duplicate global item", Item); + SPARK_Msg_N ("duplicate global item", Item); -- Add the entity of the current item to the list of processed -- items. @@ -2121,7 +2107,7 @@ package body Sem_Prag is is begin if Status then - Error_Msg_N ("duplicate global mode", Mode); + SPARK_Msg_N ("duplicate global mode", Mode); end if; Status := True; @@ -2164,10 +2150,10 @@ package body Sem_Prag is if Appears_In (Inputs, Item_Id) and then not Appears_In (Outputs, Item_Id) then - Error_Msg_NE + SPARK_Msg_NE ("global item & cannot have mode In_Out or Output", Item, Item_Id); - Error_Msg_NE + SPARK_Msg_NE ("\item already appears as input of subprogram &", Item, Context); @@ -2188,7 +2174,7 @@ package body Sem_Prag is procedure Check_Mode_Restriction_In_Function (Mode : Node_Id) is begin if Ekind (Spec_Id) = E_Function then - Error_Msg_N + SPARK_Msg_N ("global mode & is not applicable to functions", Mode); end if; end Check_Mode_Restriction_In_Function; @@ -2223,7 +2209,7 @@ package body Sem_Prag is if Present (Expressions (List)) then if Present (Component_Associations (List)) then - Error_Msg_N + SPARK_Msg_N ("cannot mix moded and non-moded global lists", List); end if; @@ -2240,7 +2226,7 @@ package body Sem_Prag is elsif Present (Component_Associations (List)) then if Present (Expressions (List)) then - Error_Msg_N + SPARK_Msg_N ("cannot mix moded and non-moded global lists", List); end if; @@ -2264,11 +2250,11 @@ package body Sem_Prag is Check_Duplicate_Mode (Mode, Proof_Seen); else - Error_Msg_N ("invalid mode selector", Mode); + SPARK_Msg_N ("invalid mode selector", Mode); end if; else - Error_Msg_N ("invalid mode selector", Mode); + SPARK_Msg_N ("invalid mode selector", Mode); end if; -- Items in a moded list appear as a collection of @@ -2288,7 +2274,8 @@ package body Sem_Prag is raise Program_Error; end if; - -- Any other attempt to declare a global item is illegal + -- Any other attempt to declare a global item is illegal. This is a + -- syntax error, always report. else Error_Msg_N ("malformed global list", List); @@ -2310,14 +2297,6 @@ package body Sem_Prag is Set_Analyzed (N); Check_SPARK_Aspect_For_ASIS (N); - -- Verify the syntax of pragma Global when SPARK checks are suppressed. - -- Semantic analysis is disabled in this mode. - - if SPARK_Mode = Off then - Check_Global_List_Syntax (Items); - return; - end if; - Subp_Decl := Find_Related_Subprogram_Or_Body (N); Subp_Id := Defining_Entity (Subp_Decl); @@ -2327,11 +2306,13 @@ package body Sem_Prag is -- Refined_Global. if Nkind (Subp_Decl) = N_Subprogram_Body - and then not Acts_As_Spec (Subp_Decl) + and then Present (Corresponding_Spec (Subp_Decl)) then Spec_Id := Corresponding_Spec (Subp_Decl); - elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub then + elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub + and then Present (Corresponding_Spec_Of_Stub (Subp_Decl)) + then Spec_Id := Corresponding_Spec_Of_Stub (Subp_Decl); else @@ -2430,9 +2411,6 @@ package body Sem_Prag is -- Verify the legality of a single initialization item followed by a -- list of input items. - procedure Check_Initialization_List_Syntax (List : Node_Id); - -- Verify the syntax of initialization list List - procedure Collect_States_And_Variables; -- Inspect the visible declarations of the related package and gather -- the entities of all abstract states and variables in States_And_Vars. @@ -2449,10 +2427,10 @@ package body Sem_Prag is if Nkind (Item) = N_Null then if Null_Seen then - Error_Msg_N ("multiple null initializations not allowed", Item); + SPARK_Msg_N ("multiple null initializations not allowed", Item); elsif Non_Null_Seen then - Error_Msg_N + SPARK_Msg_N ("cannot mix null and non-null initialization items", Item); else Null_Seen := True; @@ -2464,7 +2442,7 @@ package body Sem_Prag is Non_Null_Seen := True; if Null_Seen then - Error_Msg_N + SPARK_Msg_N ("cannot mix null and non-null initialization items", Item); end if; @@ -2481,7 +2459,7 @@ package body Sem_Prag is if not Contains (States_And_Vars, Item_Id) then Error_Msg_Name_1 := Chars (Pack_Id); - Error_Msg_NE + SPARK_Msg_NE ("initialization item & must appear in the visible " & "declarations of package %", Item, Item_Id); @@ -2489,7 +2467,7 @@ package body Sem_Prag is -- (SPARK RM 7.1.5(5)). elsif Contains (Items_Seen, Item_Id) then - Error_Msg_N ("duplicate initialization item", Item); + SPARK_Msg_N ("duplicate initialization item", Item); -- The item is legal, add it to the list of processed states -- and variables. @@ -2510,13 +2488,13 @@ package body Sem_Prag is -- variable (SPARK RM 7.1.5(3)). else - Error_Msg_N + SPARK_Msg_N ("initialization item must denote variable or state", Item); end if; -- Some form of illegal construct masquerading as a name - -- (SPARK RM 7.1.5(3)). + -- (SPARK RM 7.1.5(3)). This is a syntax error, always report. else Error_Msg_N @@ -2553,11 +2531,11 @@ package body Sem_Prag is if Nkind (Input) = N_Null then if Null_Seen then - Error_Msg_N + SPARK_Msg_N ("multiple null initializations not allowed", Item); elsif Non_Null_Seen then - Error_Msg_N + SPARK_Msg_N ("cannot mix null and non-null initialization item", Item); else Null_Seen := True; @@ -2569,7 +2547,7 @@ package body Sem_Prag is Non_Null_Seen := True; if Null_Seen then - Error_Msg_N + SPARK_Msg_N ("cannot mix null and non-null initialization item", Item); end if; @@ -2579,14 +2557,18 @@ package body Sem_Prag is if Is_Entity_Name (Input) then Input_Id := Entity_Of (Input); - if Ekind_In (Input_Id, E_Abstract_State, E_Variable) then - + if Ekind_In (Input_Id, E_Abstract_State, + E_In_Parameter, + E_In_Out_Parameter, + E_Out_Parameter, + E_Variable) + then -- The input cannot denote states or variables declared -- within the related package. if Within_Scope (Input_Id, Current_Scope) then Error_Msg_Name_1 := Chars (Pack_Id); - Error_Msg_NE + SPARK_Msg_NE ("input item & cannot denote a visible variable or " & "state of package % (SPARK RM 7.1.5(4))", Input, Input_Id); @@ -2595,7 +2577,7 @@ package body Sem_Prag is -- (SPARK RM 7.1.5(5)). elsif Contains (Inputs_Seen, Input_Id) then - Error_Msg_N ("duplicate input item", Input); + SPARK_Msg_N ("duplicate input item", Input); -- Input is legal, add it to the list of processed inputs @@ -2606,23 +2588,26 @@ package body Sem_Prag is Add_Item (Input_Id, States_Seen); end if; - if Present (Encapsulating_State (Input_Id)) then + if Ekind_In (Input_Id, E_Abstract_State, E_Variable) + and then Present (Encapsulating_State (Input_Id)) + then Add_Item (Input_Id, Constits_Seen); end if; end if; -- The input references something that is not a state or a - -- variable. + -- variable (SPARK RM 7.1.5(3)). else - Error_Msg_N + SPARK_Msg_N ("input item must denote variable or state", Input); end if; -- Some form of illegal construct masquerading as a name + -- (SPARK RM 7.1.5(3)). else - Error_Msg_N + SPARK_Msg_N ("input item must denote variable or state", Input); end if; end if; @@ -2645,7 +2630,7 @@ package body Sem_Prag is Elmt := First (Choices (Item)); while Present (Elmt) loop if Name_Seen then - Error_Msg_N ("only one item allowed in initialization", Elmt); + SPARK_Msg_N ("only one item allowed in initialization", Elmt); else Name_Seen := True; Analyze_Initialization_Item (Elmt); @@ -2666,7 +2651,7 @@ package body Sem_Prag is end if; if Present (Component_Associations (Inputs)) then - Error_Msg_N + SPARK_Msg_N ("inputs must appear in named association form", Inputs); end if; @@ -2677,61 +2662,6 @@ package body Sem_Prag is end if; end Analyze_Initialization_Item_With_Inputs; - -------------------------------------- - -- Check_Initialization_List_Syntax -- - -------------------------------------- - - procedure Check_Initialization_List_Syntax (List : Node_Id) is - Init : Node_Id; - Input : Node_Id; - - begin - -- Null initialization list - - if Nkind (List) = N_Null then - null; - - elsif Nkind (List) = N_Aggregate then - - -- Simple initialization items - - if Present (Expressions (List)) then - Init := First (Expressions (List)); - while Present (Init) loop - Check_Item_Syntax (Init); - Next (Init); - end loop; - end if; - - -- Initialization items with a input lists - - if Present (Component_Associations (List)) then - Init := First (Component_Associations (List)); - while Present (Init) loop - Check_Item_Syntax (First (Choices (Init))); - - if Nkind (Expression (Init)) = N_Aggregate - and then Present (Expressions (Expression (Init))) - then - Input := First (Expressions (Expression (Init))); - while Present (Input) loop - Check_Item_Syntax (Input); - Next (Input); - end loop; - - else - Error_Msg_N ("malformed initialization item", Init); - end if; - - Next (Init); - end loop; - end if; - - else - Error_Msg_N ("malformed initialization list", List); - end if; - end Check_Initialization_List_Syntax; - ---------------------------------- -- Collect_States_And_Variables -- ---------------------------------- @@ -2781,13 +2711,6 @@ package body Sem_Prag is if Nkind (Inits) = N_Null then return; - - -- Verify the syntax of pragma Initializes when SPARK checks are - -- suppressed. Semantic analysis is disabled in this mode. - - elsif SPARK_Mode = Off then - Check_Initialization_List_Syntax (Inits); - return; end if; -- Single and multiple initialization clauses appear as an aggregate. If @@ -2829,10 +2752,6 @@ package body Sem_Prag is -- Analyze_Pragma -- -------------------- - -------------------- - -- Analyze_Pragma -- - -------------------- - procedure Analyze_Pragma (N : Node_Id) is Loc : constant Source_Ptr := Sloc (N); Prag_Id : Pragma_Id; @@ -3215,14 +3134,27 @@ package body Sem_Prag is -- procedure identified by Name, returns it if it exists, otherwise -- errors out and uses Arg as the pragma argument for the message. - procedure Fix_Error (Msg : in out String); - -- This is called prior to issuing an error message. Msg is a string - -- that typically contains the substring "pragma". If the pragma comes - -- from an aspect, each such "pragma" substring is replaced with the - -- characters "aspect", and Error_Msg_Name_1 is set to the name of the - -- aspect (which may be different from the pragma name). If the current - -- pragma results from rewriting another pragma, then Error_Msg_Name_1 - -- is set to the original pragma name. + function Fix_Error (Msg : String) return String; + -- This is called prior to issuing an error message. Msg is the normal + -- error message issued in the pragma case. This routine checks for the + -- case of a pragma coming from an aspect in the source, and returns a + -- message suitable for the aspect case as follows: + -- + -- Each substring "pragma" is replaced by "aspect" + -- + -- If "argument of" is at the start of the error message text, it is + -- replaced by "entity for". + -- + -- If "argument" is at the start of the error message text, it is + -- replaced by "entity". + -- + -- So for example, "argument of pragma X must be discrete type" + -- returns "entity for aspect X must be a discrete type". + + -- Finally Error_Msg_Name_1 is set to the name of the aspect (which may + -- be different from the pragma name). If the current pragma results + -- from rewriting another pragma, then Error_Msg_Name_1 is set to the + -- original pragma name. procedure Gather_Associations (Names : Name_List; @@ -3454,21 +3386,25 @@ package body Sem_Prag is Legal := False; - -- Verify the syntax of the encapsulating state when SPARK check are - -- suppressed. Semantic analysis is disabled in this mode. + if Nkind_In (State, N_Expanded_Name, + N_Identifier, + N_Selected_Component) + then + Analyze (State); + Resolve_State (State); - if SPARK_Mode = Off then - Check_Item_Syntax (State); - return; - end if; + if Is_Entity_Name (State) + and then Ekind (Entity (State)) = E_Abstract_State + then + State_Id := Entity (State); - Analyze (State); - Resolve_State (State); + else + SPARK_Msg_N + ("indicator Part_Of must denote an abstract state", State); + return; + end if; - if Is_Entity_Name (State) - and then Ekind (Entity (State)) = E_Abstract_State - then - State_Id := Entity (State); + -- This is a syntax error, always report else Error_Msg_N @@ -3492,11 +3428,11 @@ package body Sem_Prag is -- visible. if Placement = Not_In_Package then - Error_Msg_N + SPARK_Msg_N ("indicator Part_Of cannot appear in this context " & "(SPARK RM 7.2.6(5))", Indic); Error_Msg_Name_1 := Chars (Scope (State_Id)); - Error_Msg_NE + SPARK_Msg_NE ("\& is not part of the hidden state of package %", Indic, Item_Id); @@ -3530,7 +3466,7 @@ package body Sem_Prag is Parent_Unit := Scope (Parent_Unit); if not Is_Child_Or_Sibling (Pack_Id, Scope (State_Id)) then - Error_Msg_NE + SPARK_Msg_NE ("indicator Part_Of must denote an abstract state of& " & "or public descendant (SPARK RM 7.2.6(3))", Indic, Parent_Unit); @@ -3543,7 +3479,7 @@ package body Sem_Prag is null; else - Error_Msg_NE + SPARK_Msg_NE ("indicator Part_Of must denote an abstract state of& " & "or public descendant (SPARK RM 7.2.6(3))", Indic, Parent_Unit); @@ -3553,11 +3489,11 @@ package body Sem_Prag is -- a private child unit or a public descendant thereof. else - Error_Msg_N - ("indicator Part_Of cannot appear in this context (SPARK " - & "RM 7.2.6(5))", Indic); + SPARK_Msg_N + ("indicator Part_Of cannot appear in this context " + & "(SPARK RM 7.2.6(5))", Indic); Error_Msg_Name_1 := Chars (Pack_Id); - Error_Msg_NE + SPARK_Msg_NE ("\& is declared in the visible part of package %", Indic, Item_Id); end if; @@ -3567,11 +3503,11 @@ package body Sem_Prag is elsif Placement = Private_State_Space then if Scope (State_Id) /= Pack_Id then - Error_Msg_NE + SPARK_Msg_NE ("indicator Part_Of must designate an abstract state of " & "package & (SPARK RM 7.2.6(2))", Indic, Pack_Id); Error_Msg_Name_1 := Chars (Pack_Id); - Error_Msg_NE + SPARK_Msg_NE ("\& is declared in the private part of package %", Indic, Item_Id); end if; @@ -3580,13 +3516,13 @@ package body Sem_Prag is -- Part_Of indicators as the refinement has already been seen. else - Error_Msg_N + SPARK_Msg_N ("indicator Part_Of cannot appear in this context " & "(SPARK RM 7.2.6(5))", Indic); if Scope (State_Id) = Pack_Id then Error_Msg_Name_1 := Chars (Pack_Id); - Error_Msg_NE + SPARK_Msg_NE ("\& is declared in the body of package %", Indic, Item_Id); end if; end if; @@ -3742,12 +3678,11 @@ package body Sem_Prag is Error_Msg_Name_1 := Pname; declare - Msg : String := + Msg : constant String := "argument for pragma% must be a identifier or " & "static string expression!"; begin - Fix_Error (Msg); - Flag_Non_Static_Expr (Msg, Argx); + Flag_Non_Static_Expr (Fix_Error (Msg), Argx); raise Pragma_Exit; end; end if; @@ -4204,7 +4139,7 @@ package body Sem_Prag is -- If we get here, then the aspects are out of order - Error_Msg_N ("aspect % cannot come after aspect %", First); + SPARK_Msg_N ("aspect % cannot come after aspect %", First); end Check_Aspect_Specification_Order; -- Local variables @@ -4239,7 +4174,7 @@ package body Sem_Prag is else if From_Aspect_Specification (Second) then - Error_Msg_N ("pragma % cannot come after aspect %", First); + SPARK_Msg_N ("pragma % cannot come after aspect %", First); -- Both pragmas are source constructs. Try to reach First from -- Second by traversing the declarations backwards. @@ -4259,7 +4194,7 @@ package body Sem_Prag is -- If we get here, then the pragmas are out of order - Error_Msg_N ("pragma % cannot come after pragma %", First); + SPARK_Msg_N ("pragma % cannot come after pragma %", First); end if; end if; end Check_Declaration_Order; @@ -4415,15 +4350,9 @@ package body Sem_Prag is else Error_Msg_Name_1 := Pname; - - declare - Msg : String := - "argument for pragma% must be a static expression!"; - begin - Fix_Error (Msg); - Flag_Non_Static_Expr (Msg, Expr); - end; - + Flag_Non_Static_Expr + (Fix_Error ("argument for pragma% must be a static expression!"), + Expr); raise Pragma_Exit; end if; end Check_Expr_Is_Static_Expression; @@ -5818,11 +5747,9 @@ package body Sem_Prag is ------------------ procedure Error_Pragma (Msg : String) is - MsgF : String := Msg; begin Error_Msg_Name_1 := Pname; - Fix_Error (MsgF); - Error_Msg_N (MsgF, N); + Error_Msg_N (Fix_Error (Msg), N); raise Pragma_Exit; end Error_Pragma; @@ -5831,20 +5758,16 @@ package body Sem_Prag is ---------------------- procedure Error_Pragma_Arg (Msg : String; Arg : Node_Id) is - MsgF : String := Msg; begin Error_Msg_Name_1 := Pname; - Fix_Error (MsgF); - Error_Msg_N (MsgF, Get_Pragma_Arg (Arg)); + Error_Msg_N (Fix_Error (Msg), Get_Pragma_Arg (Arg)); raise Pragma_Exit; end Error_Pragma_Arg; procedure Error_Pragma_Arg (Msg1, Msg2 : String; Arg : Node_Id) is - MsgF : String := Msg1; begin Error_Msg_Name_1 := Pname; - Fix_Error (MsgF); - Error_Msg_N (MsgF, Get_Pragma_Arg (Arg)); + Error_Msg_N (Fix_Error (Msg1), Get_Pragma_Arg (Arg)); Error_Pragma_Arg (Msg2, Arg); end Error_Pragma_Arg; @@ -5853,11 +5776,9 @@ package body Sem_Prag is ---------------------------- procedure Error_Pragma_Arg_Ident (Msg : String; Arg : Node_Id) is - MsgF : String := Msg; begin Error_Msg_Name_1 := Pname; - Fix_Error (MsgF); - Error_Msg_N (MsgF, Arg); + Error_Msg_N (Fix_Error (Msg), Arg); raise Pragma_Exit; end Error_Pragma_Arg_Ident; @@ -5866,12 +5787,10 @@ package body Sem_Prag is ---------------------- procedure Error_Pragma_Ref (Msg : String; Ref : Entity_Id) is - MsgF : String := Msg; begin Error_Msg_Name_1 := Pname; - Fix_Error (MsgF); - Error_Msg_Sloc := Sloc (Ref); - Error_Msg_NE (MsgF, N, Ref); + Error_Msg_Sloc := Sloc (Ref); + Error_Msg_NE (Fix_Error (Msg), N, Ref); raise Pragma_Exit; end Error_Pragma_Ref; @@ -6002,7 +5921,11 @@ package body Sem_Prag is -- Fix_Error -- --------------- - procedure Fix_Error (Msg : in out String) is + function Fix_Error (Msg : String) return String is + Res : String (Msg'Range) := Msg; + Res_Last : Natural := Msg'Last; + J : Natural; + begin -- If we have a rewriting of another pragma, go to that pragma @@ -6018,16 +5941,47 @@ package body Sem_Prag is -- Change appearence of "pragma" in message to "aspect" - for J in Msg'First .. Msg'Last - 5 loop - if Msg (J .. J + 5) = "pragma" then - Msg (J .. J + 5) := "aspect"; + J := Res'First; + while J <= Res_Last - 5 loop + if Res (J .. J + 5) = "pragma" then + Res (J .. J + 5) := "aspect"; + J := J + 6; + + else + J := J + 1; end if; end loop; + -- Change "argument of" at start of message to "entity for" + + if Res'Length > 11 + and then Res (Res'First .. Res'First + 10) = "argument of" + then + Res (Res'First .. Res'First + 9) := "entity for"; + Res (Res'First + 10 .. Res_Last - 1) := + Res (Res'First + 11 .. Res_Last); + Res_Last := Res_Last - 1; + end if; + + -- Change "argument" at start of message to "entity" + + if Res'Length > 8 + and then Res (Res'First .. Res'First + 7) = "argument" + then + Res (Res'First .. Res'First + 5) := "entity"; + Res (Res'First + 6 .. Res_Last - 2) := + Res (Res'First + 8 .. Res_Last); + Res_Last := Res_Last - 2; + end if; + -- Get name from corresponding aspect Error_Msg_Name_1 := Original_Aspect_Name (N); end if; + + -- Return possibly modified message + + return Res (Res'First .. Res_Last); end Fix_Error; ------------------------- @@ -6328,6 +6282,14 @@ package body Sem_Prag is Set_Treat_As_Volatile (E); Set_Treat_As_Volatile (Underlying_Type (E)); + -- The following check is only relevant when SPARK_Mode is on as + -- this is not a standard Ada legality rule. Volatile types are + -- not allowed (SPARK RM C.6(1)). + + if SPARK_Mode = On and then Prag_Id = Pragma_Volatile then + Error_Msg_N ("volatile type not allowed", E); + end if; + elsif K = N_Object_Declaration or else (K = N_Component_Declaration and then Original_Record_Component (E) = E) @@ -6482,10 +6444,10 @@ package body Sem_Prag is if Force then if Cont = False then - Error_Msg_N ("<~!!", Arg1); + Error_Msg_N ("<<~!!", Arg1); Cont := True; else - Error_Msg_N ("\<~!!", Arg1); + Error_Msg_N ("\<<~!!", Arg1); end if; -- Error, rather than warning, or in a body, so we do not @@ -6496,10 +6458,10 @@ package body Sem_Prag is else if Cont = False then - Error_Msg_N ("<~", Arg1); + Error_Msg_N ("<<~", Arg1); Cont := True; else - Error_Msg_N ("\<~", Arg1); + Error_Msg_N ("\<<~", Arg1); end if; end if; @@ -8024,7 +7986,8 @@ package body Sem_Prag is then -- If the name is overloaded, pragma applies to all of the denoted -- entities in the same declarative part, unless the pragma comes - -- from an aspect specification. + -- from an aspect specification or was generated by the compiler + -- (such as for pragma Provide_Shift_Operators). Hom_Id := Def_Id; while Present (Hom_Id) loop @@ -8136,6 +8099,19 @@ package body Sem_Prag is elsif From_Aspect_Specification (N) then exit; + -- If the pragma was created by the compiler, then we don't + -- want it to apply to other homonyms. This kind of case can + -- occur when using pragma Provide_Shift_Operators, which + -- generates implicit shift and rotate operators with Import + -- pragmas that might apply to earlier explicit or implicit + -- declarations marked with Import (for example, coming from + -- an earlier pragma Provide_Shift_Operators for another type), + -- and we don't generally want other homonyms being treated + -- as imported or the pragma flagged as an illegal duplicate. + + elsif not Comes_From_Source (N) then + exit; + else Hom_Id := Homonym (Hom_Id); end if; @@ -9068,7 +9044,7 @@ package body Sem_Prag is if Nkind (Expr) /= N_Identifier or else not Is_Attribute_Name (Chars (Expr)) then - Error_Msg_N ("unknown attribute name?", Expr); + Error_Msg_N ("unknown attribute name??", Expr); else Set_Restriction_No_Use_Of_Attribute (Expr, Warn); @@ -9078,7 +9054,7 @@ package body Sem_Prag is if Nkind (Expr) /= N_Identifier or else not Is_Pragma_Name (Chars (Expr)) then - Error_Msg_N ("unknown pragma name?", Expr); + Error_Msg_N ("unknown pragma name??", Expr); else Set_Restriction_No_Use_Of_Pragma (Expr, Warn); @@ -10157,6 +10133,9 @@ package body Sem_Prag is -- ABSTRACT_STATE ::= name when Pragma_Abstract_State => Abstract_State : declare + Missing_Parentheses : Boolean := False; + -- Flag set when a state declaration with options is not properly + -- parenthesized. -- Flags used to verify the consistency of states @@ -10171,9 +10150,6 @@ package body Sem_Prag is -- decorate a state abstraction entity and introduce it into the -- visibility chain. - procedure Check_State_Declaration_Syntax (State : Node_Id); - -- Verify the syntex of state declaration State - ---------------------------- -- Analyze_Abstract_State -- ---------------------------- @@ -10328,7 +10304,7 @@ package body Sem_Prag is if Nkind (Prop) = N_Others_Choice then if Others_Seen then - Error_Msg_N + SPARK_Msg_N ("only one others choice allowed in option External", Prop); else @@ -10336,7 +10312,7 @@ package body Sem_Prag is end if; elsif Others_Seen then - Error_Msg_N + SPARK_Msg_N ("others must be the last property in option External", Prop); @@ -10354,7 +10330,7 @@ package body Sem_Prag is -- Otherwise the construct is not a valid property else - Error_Msg_N ("invalid external state property", Prop); + SPARK_Msg_N ("invalid external state property", Prop); return; end if; @@ -10367,7 +10343,7 @@ package body Sem_Prag is if Is_Static_Expression (Expr) then Expr_Val := Is_True (Expr_Value (Expr)); else - Error_Msg_N + SPARK_Msg_N ("expression of external state property must be " & "static", Expr); end if; @@ -10461,7 +10437,7 @@ package body Sem_Prag is is begin if Status then - Error_Msg_N ("duplicate state option", Opt); + SPARK_Msg_N ("duplicate state option", Opt); end if; Status := True; @@ -10477,7 +10453,7 @@ package body Sem_Prag is is begin if Status then - Error_Msg_N ("duplicate external property", Prop); + SPARK_Msg_N ("duplicate external property", Prop); end if; Status := True; @@ -10541,7 +10517,7 @@ package body Sem_Prag is -- declare additional states. if Null_Seen then - Error_Msg_NE + SPARK_Msg_NE ("package & has null abstract state", State, Pack_Id); -- Null states appear as internally generated entities @@ -10558,7 +10534,7 @@ package body Sem_Prag is -- non-null states. if Non_Null_Seen then - Error_Msg_NE + SPARK_Msg_NE ("package & has non-null abstract state", State, Pack_Id); end if; @@ -10585,7 +10561,7 @@ package body Sem_Prag is Is_Null => False); Non_Null_Seen := True; else - Error_Msg_N + SPARK_Msg_N ("state name must be an identifier", Ancestor_Part (State)); end if; @@ -10596,25 +10572,63 @@ package body Sem_Prag is Opt := First (Expressions (State)); while Present (Opt) loop - if Nkind (Opt) = N_Identifier - and then Chars (Opt) = Name_External - then - Analyze_External_Option (Opt); + if Nkind (Opt) = N_Identifier then + if Chars (Opt) = Name_External then + Analyze_External_Option (Opt); - -- When an illegal option Part_Of is without a parent - -- state, it appears in the list of expression of the - -- aggregate rather than the component associations - -- (SPARK RM 7.1.4(9)). + -- Option Part_Of without an encapsulating state is + -- illegal. (SPARK RM 7.1.4(9)). + + elsif Chars (Opt) = Name_Part_Of then + SPARK_Msg_N + ("indicator Part_Of must denote an abstract " + & "state", Opt); + + -- Do not emit an error message when a previous state + -- declaration with options was not parenthesized as + -- the option is actually another state declaration. + -- + -- with Abstract_State + -- (State_1 with ..., -- missing parentheses + -- (State_2 with ...), + -- State_3) -- ok state declaration + + elsif Missing_Parentheses then + null; + + -- Otherwise the option is not allowed. Note that it + -- is not possible to distinguish between an option + -- and a state declaration when a previous state with + -- options not properly parentheses. + -- + -- with Abstract_State + -- (State_1 with ..., -- missing parentheses + -- State_2); -- could be an option - elsif Chars (Opt) = Name_Part_Of then - Error_Msg_N - ("indicator Part_Of must denote an abstract state", - Opt); + else + SPARK_Msg_N + ("simple option not allowed in state declaration", + Opt); + end if; + + -- Catch a case where missing parentheses around a state + -- declaration with options cause a subsequent state + -- declaration with options to be treated as an option. + -- + -- with Abstract_State + -- (State_1 with ..., -- missing parentheses + -- (State_2 with ...)) + + elsif Nkind (Opt) = N_Extension_Aggregate then + Missing_Parentheses := True; + SPARK_Msg_N + ("state declaration must be parenthesized", + Ancestor_Part (State)); + + -- Otherwise the option is malformed else - Error_Msg_N - ("simple option not allowed in state declaration", - Opt); + SPARK_Msg_N ("malformed option", Opt); end if; Next (Opt); @@ -10635,19 +10649,21 @@ package body Sem_Prag is Analyze_Part_Of_Option (Opt); else - Error_Msg_N ("invalid state option", Opt); + SPARK_Msg_N ("invalid state option", Opt); end if; else - Error_Msg_N ("invalid state option", Opt); + SPARK_Msg_N ("invalid state option", Opt); end if; Next (Opt); end loop; - -- Any other attempt to declare a state is illegal + -- Any other attempt to declare a state is illegal. This is a + -- syntax error, always report. else Error_Msg_N ("malformed abstract state declaration", State); + return; end if; -- Guard against a junk state. In such cases no entity is @@ -10679,49 +10695,6 @@ package body Sem_Prag is end if; end Analyze_Abstract_State; - ------------------------------------ - -- Check_State_Declaration_Syntax -- - ------------------------------------ - - procedure Check_State_Declaration_Syntax (State : Node_Id) is - Decl : Node_Id; - - begin - -- Null abstract state - - if Nkind (State) = N_Null then - null; - - -- Single state - - elsif Nkind (State) = N_Identifier then - null; - - -- State with various options - - elsif Nkind (State) = N_Extension_Aggregate then - if Nkind (Ancestor_Part (State)) /= N_Identifier then - Error_Msg_N - ("state name must be an identifier", - Ancestor_Part (State)); - end if; - - -- Multiple states - - elsif Nkind (State) = N_Aggregate - and then Present (Expressions (State)) - then - Decl := First (Expressions (State)); - while Present (Decl) loop - Check_State_Declaration_Syntax (Decl); - Next (Decl); - end loop; - - else - Error_Msg_N ("malformed abstract state", State); - end if; - end Check_State_Declaration_Syntax; - -- Local variables Context : constant Node_Id := Parent (Parent (N)); @@ -10744,16 +10717,7 @@ package body Sem_Prag is return; end if; - State := Expression (Arg1); - - -- Verify the syntax of pragma Abstract_State when SPARK checks - -- are suppressed. Semantic analysis is disabled in this mode. - - if SPARK_Mode = Off then - Check_State_Declaration_Syntax (State); - return; - end if; - + State := Expression (Arg1); Pack_Id := Defining_Entity (Context); -- Multiple non-null abstract states appear as an aggregate @@ -12345,7 +12309,12 @@ package body Sem_Prag is when Pragma_Compiler_Unit | Pragma_Compiler_Unit_Warning => GNAT_Pragma; Check_Arg_Count (0); - Set_Is_Compiler_Unit (Get_Source_Unit (N)); + + -- Only recognized in main unit + + if Current_Sem_Unit = Main_Unit then + Compiler_Unit := True; + end if; ----------------------------- -- Complete_Representation -- @@ -14970,13 +14939,11 @@ package body Sem_Prag is -- Independent -- ----------------- - -- pragma Independent (LOCAL_NAME); + -- pragma Independent (record_component_LOCAL_NAME); when Pragma_Independent => Independent : declare E_Id : Node_Id; E : Entity_Id; - D : Node_Id; - K : Node_Kind; begin Check_Ada_83_Warning; @@ -14991,38 +14958,32 @@ package body Sem_Prag is end if; E := Entity (E_Id); - D := Declaration_Node (E); - K := Nkind (D); + + -- Check we have a record component. We have not yet setup + -- components fully, so identify by syntactic structure. + + if Nkind (Declaration_Node (E)) /= N_Component_Declaration then + Error_Pragma_Arg + ("argument for pragma% must be record component", Arg1); + end if; -- Check duplicate before we chain ourselves Check_Duplicate_Pragma (E); - -- Check appropriate entity - - if Is_Type (E) then - if Rep_Item_Too_Early (E, N) - or else - Rep_Item_Too_Late (E, N) - then - return; - else - Check_First_Subtype (Arg1); - end if; + -- Chain pragma - elsif K = N_Object_Declaration - or else (K = N_Component_Declaration - and then Original_Record_Component (E) = E) + if Rep_Item_Too_Early (E, N) + or else + Rep_Item_Too_Late (E, N) then - if Rep_Item_Too_Late (E, N) then - return; - end if; - - else - Error_Pragma_Arg - ("inappropriate entity for pragma%", Arg1); + return; end if; + -- Set flag in component + + Set_Is_Independent (E); + Independence_Checks.Append ((N, E)); end Independent; @@ -15039,6 +15000,7 @@ package body Sem_Prag is E : Entity_Id; D : Node_Id; K : Node_Kind; + C : Node_Id; begin Check_Ada_83_Warning; @@ -15073,16 +15035,26 @@ package body Sem_Prag is if K = N_Full_Type_Declaration and then (Is_Array_Type (E) or else Is_Record_Type (E)) then - Independence_Checks.Append ((N, E)); + Independence_Checks.Append ((N, Base_Type (E))); Set_Has_Independent_Components (Base_Type (E)); + -- For record type, set all components independent + + if Is_Record_Type (E) then + C := First_Component (E); + while Present (C) loop + Set_Is_Independent (C); + Next_Component (C); + end loop; + end if; + elsif (Ekind (E) = E_Constant or else Ekind (E) = E_Variable) and then Nkind (D) = N_Object_Declaration and then Nkind (Object_Definition (D)) = N_Constrained_Array_Definition then - Independence_Checks.Append ((N, E)); - Set_Has_Independent_Components (E); + Independence_Checks.Append ((N, Base_Type (Etype (E)))); + Set_Has_Independent_Components (Base_Type (Etype (E))); else Error_Pragma_Arg ("inappropriate entity for pragma%", Arg1); @@ -17422,8 +17394,15 @@ package body Sem_Prag is Check_No_Identifiers; Check_Arg_Count (1); Check_Arg_Is_Local_Name (Arg1); - Type_Id := Get_Pragma_Arg (Assoc); + + if not Is_Entity_Name (Type_Id) + or else not Is_Type (Entity (Type_Id)) + then + Error_Pragma_Arg + ("argument for pragma% must be type or subtype", Arg1); + end if; + Find_Type (Type_Id); Typ := Entity (Type_Id); @@ -17620,7 +17599,7 @@ package body Sem_Prag is -- indicator, but has no visible state. if not Has_Item then - Error_Msg_NE + SPARK_Msg_NE ("package instantiation & has Part_Of indicator but " & "lacks visible state", Instance, Pack_Id); end if; @@ -17686,7 +17665,7 @@ package body Sem_Prag is if Nkind (Stmt) = N_Object_Declaration and then Ekind (Defining_Entity (Stmt)) /= E_Variable then - Error_Msg_N ("indicator Part_Of must apply to a variable", N); + SPARK_Msg_N ("indicator Part_Of must apply to a variable", N); return; end if; @@ -17966,10 +17945,10 @@ package body Sem_Prag is Check_No_Identifiers; Check_Pre_Post; - -- Rewrite Post[_Class] pragma as Precondition pragma setting the + -- Rewrite Post[_Class] pragma as Postcondition pragma setting the -- flag Class_Present to True for the Post_Class case. - Set_Class_Present (N, Prag_Id = Pragma_Pre_Class); + Set_Class_Present (N, Prag_Id = Pragma_Post_Class); PC_Pragma := New_Copy (N); Set_Pragma_Identifier (PC_Pragma, Make_Identifier (Loc, Name_Postcondition)); @@ -18181,44 +18160,6 @@ package body Sem_Prag is end if; end Preelaborate; - --------------------- - -- Preelaborate_05 -- - --------------------- - - -- pragma Preelaborate_05 [(library_unit_NAME)]; - - -- This pragma is useable only in GNAT_Mode, where it is used like - -- pragma Preelaborate but it is only effective in Ada 2005 mode - -- (otherwise it is ignored). This is used to implement AI-362 which - -- recategorizes some run-time packages in Ada 2005 mode. - - when Pragma_Preelaborate_05 => Preelaborate_05 : declare - Ent : Entity_Id; - - begin - GNAT_Pragma; - Check_Valid_Library_Unit_Pragma; - - if not GNAT_Mode then - Error_Pragma ("pragma% only available in GNAT mode"); - end if; - - if Nkind (N) = N_Null_Statement then - return; - end if; - - -- This is one of the few cases where we need to test the value of - -- Ada_Version_Explicit rather than Ada_Version (which is always - -- set to Ada_2012 in a predefined unit), we need to know the - -- explicit version set to know if this pragma is active. - - if Ada_Version_Explicit >= Ada_2005 then - Ent := Find_Lib_Unit_Name; - Set_Is_Preelaborated (Ent); - Set_Suppress_Elaboration_Warnings (Ent); - end if; - end Preelaborate_05; - -------------- -- Priority -- -------------- @@ -18830,88 +18771,6 @@ package body Sem_Prag is Set_Suppress_Elaboration_Warnings (Ent); end Pure; - ------------- - -- Pure_05 -- - ------------- - - -- pragma Pure_05 [(library_unit_NAME)]; - - -- This pragma is useable only in GNAT_Mode, where it is used like - -- pragma Pure but it is only effective in Ada 2005 mode (otherwise - -- it is ignored). It may be used after a pragma Preelaborate, in - -- which case it overrides the effect of the pragma Preelaborate. - -- This is used to implement AI-362 which recategorizes some run-time - -- packages in Ada 2005 mode. - - when Pragma_Pure_05 => Pure_05 : declare - Ent : Entity_Id; - - begin - GNAT_Pragma; - Check_Valid_Library_Unit_Pragma; - - if not GNAT_Mode then - Error_Pragma ("pragma% only available in GNAT mode"); - end if; - - if Nkind (N) = N_Null_Statement then - return; - end if; - - -- This is one of the few cases where we need to test the value of - -- Ada_Version_Explicit rather than Ada_Version (which is always - -- set to Ada_2012 in a predefined unit), we need to know the - -- explicit version set to know if this pragma is active. - - if Ada_Version_Explicit >= Ada_2005 then - Ent := Find_Lib_Unit_Name; - Set_Is_Preelaborated (Ent, False); - Set_Is_Pure (Ent); - Set_Suppress_Elaboration_Warnings (Ent); - end if; - end Pure_05; - - ------------- - -- Pure_12 -- - ------------- - - -- pragma Pure_12 [(library_unit_NAME)]; - - -- This pragma is useable only in GNAT_Mode, where it is used like - -- pragma Pure but it is only effective in Ada 2012 mode (otherwise - -- it is ignored). It may be used after a pragma Preelaborate, in - -- which case it overrides the effect of the pragma Preelaborate. - -- This is used to implement AI05-0212 which recategorizes some - -- run-time packages in Ada 2012 mode. - - when Pragma_Pure_12 => Pure_12 : declare - Ent : Entity_Id; - - begin - GNAT_Pragma; - Check_Valid_Library_Unit_Pragma; - - if not GNAT_Mode then - Error_Pragma ("pragma% only available in GNAT mode"); - end if; - - if Nkind (N) = N_Null_Statement then - return; - end if; - - -- This is one of the few cases where we need to test the value of - -- Ada_Version_Explicit rather than Ada_Version (which is always - -- set to Ada_2012 in a predefined unit), we need to know the - -- explicit version set to know if this pragma is active. - - if Ada_Version_Explicit >= Ada_2012 then - Ent := Find_Lib_Unit_Name; - Set_Is_Preelaborated (Ent, False); - Set_Is_Pure (Ent); - Set_Suppress_Elaboration_Warnings (Ent); - end if; - end Pure_12; - ------------------- -- Pure_Function -- ------------------- @@ -19766,13 +19625,12 @@ package body Sem_Prag is -------------------------------- procedure Check_Library_Level_Entity (E : Entity_Id) is - MsgF : String := "incorrect placement of pragma%"; + MsgF : constant String := "incorrect placement of pragma%"; begin if not Is_Library_Level_Entity (E) then Error_Msg_Name_1 := Pname; - Fix_Error (MsgF); - Error_Msg_N (MsgF, N); + Error_Msg_N (Fix_Error (MsgF), N); if Ekind_In (E, E_Generic_Package, E_Package, @@ -20566,6 +20424,12 @@ package body Sem_Prag is begin GNAT_Pragma; + if Warn_On_Obsolescent_Feature then + Error_Msg_N + ("'G'N'A'T pragma Task_Info is now obsolete, use 'C'P'U " + & "instead?j?", N); + end if; + if Nkind (P) /= N_Task_Definition then Error_Pragma ("pragma% must appear in task definition"); end if; @@ -21387,7 +21251,7 @@ package body Sem_Prag is -- Not allowed in compiler units (bootstrap issues) - Check_Compiler_Unit (N); + Check_Compiler_Unit ("Reason for pragma Warnings", N); -- No REASON string, set null string as reason @@ -22171,12 +22035,12 @@ package body Sem_Prag is -- a matching clause, emit an error. else - Error_Msg_NE + SPARK_Msg_NE ("dependence clause of subprogram & has no matching refinement " & "in body", Ref_Clause, Spec_Id); if Has_Refined_State then - Error_Msg_N + SPARK_Msg_N ("\check the use of constituents in dependence refinement", Ref_Clause); end if; @@ -22202,7 +22066,7 @@ package body Sem_Prag is procedure Match_Error (Msg : String; N : Node_Id) is begin if Post_Errors then - Error_Msg_N (Msg, N); + SPARK_Msg_N (Msg, N); end if; end Match_Error; @@ -22436,7 +22300,7 @@ package body Sem_Prag is if Present (Ref_Inputs) and then Post_Errors then Input := First (Ref_Inputs); while Present (Input) loop - Error_Msg_N + SPARK_Msg_N ("unmatched or extra input in refinement clause", Input); Next (Input); @@ -22611,7 +22475,7 @@ package body Sem_Prag is if Nkind (Clause) /= N_Component_Association or else Nkind (Expression (Clause)) /= N_Null then - Error_Msg_N + SPARK_Msg_N ("unmatched or extra clause in dependence refinement", Clause); end if; @@ -22623,7 +22487,7 @@ package body Sem_Prag is -- Local variables - Body_Decl : constant Node_Id := Parent (N); + Body_Decl : constant Node_Id := Find_Related_Subprogram_Or_Body (N); Errors : constant Nat := Serious_Errors_Detected; Refs : constant Node_Id := Get_Pragma_Arg (First (Pragma_Argument_Associations (N))); @@ -22633,22 +22497,19 @@ package body Sem_Prag is -- Start of processing for Analyze_Refined_Depends_In_Decl_Part begin - -- Verify the syntax of pragma Refined_Depends when SPARK checks are - -- suppressed. Semantic analysis is disabled in this mode. - - if SPARK_Mode = Off then - Check_Dependence_List_Syntax (Refs); - return; + if Nkind (Body_Decl) = N_Subprogram_Body_Stub then + Spec_Id := Corresponding_Spec_Of_Stub (Body_Decl); + else + Spec_Id := Corresponding_Spec (Body_Decl); end if; - Spec_Id := Corresponding_Spec (Body_Decl); Depends := Get_Pragma (Spec_Id, Pragma_Depends); -- Subprogram declarations lacks pragma Depends. Refined_Depends is -- rendered useless as there is nothing to refine (SPARK RM 7.2.5(2)). if No (Depends) then - Error_Msg_NE + SPARK_Msg_NE ("useless refinement, declaration of subprogram & lacks aspect or " & "pragma Depends", N, Spec_Id); return; @@ -22662,7 +22523,7 @@ package body Sem_Prag is -- (SPARK RM 7.2.5(2)). if Nkind (Deps) = N_Null then - Error_Msg_NE + SPARK_Msg_NE ("useless refinement, subprogram & does not depend on abstract " & "state with visible refinement", N, Spec_Id); @@ -22852,7 +22713,7 @@ package body Sem_Prag is elsif Present_Then_Remove (Proof_In_Constits, Constit_Id) then Error_Msg_Name_1 := Chars (State_Id); - Error_Msg_NE + SPARK_Msg_NE ("constituent & of state % must have mode Input, In_Out " & "or Output in global refinement", N, Constit_Id); @@ -22882,7 +22743,7 @@ package body Sem_Prag is null; else - Error_Msg_NE + SPARK_Msg_NE ("global refinement of state & redefines the mode of its " & "constituents", N, State_Id); end if; @@ -22955,7 +22816,7 @@ package body Sem_Prag is or else Present_Then_Remove (Proof_In_Constits, Constit_Id) then Error_Msg_Name_1 := Chars (State_Id); - Error_Msg_NE + SPARK_Msg_NE ("constituent & of state % must have mode Input in global " & "refinement", N, Constit_Id); end if; @@ -22966,7 +22827,7 @@ package body Sem_Prag is -- Not one of the constituents appeared as Input if not In_Seen then - Error_Msg_NE + SPARK_Msg_NE ("global refinement of state & must include at least one " & "constituent of mode Input", N, State_Id); end if; @@ -23037,7 +22898,7 @@ package body Sem_Prag is or else Present_Then_Remove (Proof_In_Constits, Constit_Id) then Error_Msg_Name_1 := Chars (State_Id); - Error_Msg_NE + SPARK_Msg_NE ("constituent & of state % must have mode Output in " & "global refinement", N, Constit_Id); @@ -23046,12 +22907,12 @@ package body Sem_Prag is else if not Posted then Posted := True; - Error_Msg_NE + SPARK_Msg_NE ("output state & must be replaced by all its " & "constituents in global refinement", N, State_Id); end if; - Error_Msg_NE + SPARK_Msg_NE ("\constituent & is missing in output list", N, Constit_Id); end if; @@ -23127,7 +22988,7 @@ package body Sem_Prag is or else Present_Then_Remove (Out_Constits, Constit_Id) then Error_Msg_Name_1 := Chars (State_Id); - Error_Msg_NE + SPARK_Msg_NE ("constituent & of state % must have mode Proof_In in " & "global refinement", N, Constit_Id); end if; @@ -23138,7 +22999,7 @@ package body Sem_Prag is -- Not one of the constituents appeared as Proof_In if not Proof_In_Seen then - Error_Msg_NE + SPARK_Msg_NE ("global refinement of state & must include at least one " & "constituent of mode Proof_In", N, State_Id); end if; @@ -23208,12 +23069,12 @@ package body Sem_Prag is procedure Inconsistent_Mode_Error (Expect : Name_Id) is begin - Error_Msg_NE + SPARK_Msg_NE ("global item & has inconsistent modes", Item, Item_Id); Error_Msg_Name_1 := Global_Mode; Error_Msg_Name_2 := Expect; - Error_Msg_N ("\expected mode %, found mode %", Item); + SPARK_Msg_N ("\expected mode %, found mode %", Item); end Inconsistent_Mode_Error; -- Start of processing for Check_Refined_Global_Item @@ -23264,7 +23125,7 @@ package body Sem_Prag is -- it must be an extra (SPARK RM 7.2.4(3)). else - Error_Msg_NE ("extra global item &", Item, Item_Id); + SPARK_Msg_NE ("extra global item &", Item, Item_Id); end if; end Check_Refined_Global_Item; @@ -23373,7 +23234,7 @@ package body Sem_Prag is if Present (List) then Constit_Elmt := First_Elmt (List); while Present (Constit_Elmt) loop - Error_Msg_NE ("extra constituent &", N, Node (Constit_Elmt)); + SPARK_Msg_NE ("extra constituent &", N, Node (Constit_Elmt)); Next_Elmt (Constit_Elmt); end loop; end if; @@ -23390,21 +23251,19 @@ package body Sem_Prag is -- Local variables - Body_Decl : constant Node_Id := Parent (N); + Body_Decl : constant Node_Id := Find_Related_Subprogram_Or_Body (N); Errors : constant Nat := Serious_Errors_Detected; Items : constant Node_Id := Get_Pragma_Arg (First (Pragma_Argument_Associations (N))); - Spec_Id : constant Entity_Id := Corresponding_Spec (Body_Decl); + Spec_Id : Entity_Id; -- Start of processing for Analyze_Refined_Global_In_Decl_Part begin - -- Verify the syntax of pragma Refined_Global when SPARK checks are - -- suppressed. Semantic analysis is disabled in this mode. - - if SPARK_Mode = Off then - Check_Global_List_Syntax (Items); - return; + if Nkind (Body_Decl) = N_Subprogram_Body_Stub then + Spec_Id := Corresponding_Spec_Of_Stub (Body_Decl); + else + Spec_Id := Corresponding_Spec (Body_Decl); end if; Global := Get_Pragma (Spec_Id, Pragma_Global); @@ -23413,7 +23272,7 @@ package body Sem_Prag is -- Refined_Global useless as there is nothing to refine. if No (Global) then - Error_Msg_NE + SPARK_Msg_NE ("useless refinement, declaration of subprogram & lacks aspect or " & "pragma Global", N, Spec_Id); return; @@ -23443,7 +23302,7 @@ package body Sem_Prag is and then not Has_Proof_In_State and then not Has_Null_State then - Error_Msg_NE + SPARK_Msg_NE ("useless refinement, subprogram & does not depend on abstract " & "state with visible refinement", N, Spec_Id); return; @@ -23461,7 +23320,7 @@ package body Sem_Prag is or else Present (Proof_In_Items)) and then not Has_Null_State then - Error_Msg_NE + SPARK_Msg_NE ("refinement cannot be null, subprogram & has global items", N, Spec_Id); return; @@ -23547,9 +23406,6 @@ package body Sem_Prag is procedure Analyze_Refinement_Clause (Clause : Node_Id); -- Perform full analysis of a single refinement clause - procedure Check_Refinement_List_Syntax (List : Node_Id); - -- Verify the syntax of refinement clause list List - function Collect_Body_States (Pack_Id : Entity_Id) return Elist_Id; -- Gather the entities of all abstract states and variables declared in -- the body state space of package Pack_Id. @@ -23689,7 +23545,7 @@ package body Sem_Prag is -- Detect a duplicate use of a constituent if Contains (Constituents_Seen, Constit_Id) then - Error_Msg_NE + SPARK_Msg_NE ("duplicate use of constituent &", Constit, Constit_Id); return; end if; @@ -23706,10 +23562,10 @@ package body Sem_Prag is else Error_Msg_Name_1 := Chars (State_Id); - Error_Msg_NE + SPARK_Msg_NE ("& cannot act as constituent of state %", Constit, Constit_Id); - Error_Msg_NE + SPARK_Msg_NE ("\Part_Of indicator specifies & as encapsulating " & "state", Constit, Encapsulating_State (Constit_Id)); end if; @@ -23740,7 +23596,7 @@ package body Sem_Prag is -- refinement (SPARK RM 7.2.2(9)). Error_Msg_Name_1 := Chars (Spec_Id); - Error_Msg_NE + SPARK_Msg_NE ("cannot use & in refinement, constituent is not a hidden " & "state of package %", Constit, Constit_Id); end if; @@ -23758,11 +23614,11 @@ package body Sem_Prag is if Nkind (Constit) = N_Null then if Null_Seen then - Error_Msg_N + SPARK_Msg_N ("multiple null constituents not allowed", Constit); elsif Non_Null_Seen then - Error_Msg_N + SPARK_Msg_N ("cannot mix null and non-null constituents", Constit); else @@ -23785,7 +23641,7 @@ package body Sem_Prag is Non_Null_Seen := True; if Null_Seen then - Error_Msg_N + SPARK_Msg_N ("cannot mix null and non-null constituents", Constit); end if; @@ -23802,7 +23658,7 @@ package body Sem_Prag is Check_Matching_Constituent (Constit_Id); else - Error_Msg_NE + SPARK_Msg_NE ("constituent & must denote a variable or state (SPARK " & "RM 7.2.2(5))", Constit, Constit_Id); end if; @@ -23810,7 +23666,7 @@ package body Sem_Prag is -- The constituent is illegal else - Error_Msg_N ("malformed constituent", Constit); + SPARK_Msg_N ("malformed constituent", Constit); end if; end if; end Analyze_Constituent; @@ -23832,7 +23688,7 @@ package body Sem_Prag is if Enabled then if No (Constit) then - Error_Msg_NE + SPARK_Msg_NE ("external state & requires at least one constituent with " & "property %", State, State_Id); end if; @@ -23843,7 +23699,7 @@ package body Sem_Prag is elsif Present (Constit) then Error_Msg_Name_2 := Chars (Constit); - Error_Msg_NE + SPARK_Msg_NE ("external state & lacks property % set by constituent %", State, State_Id); end if; @@ -23860,7 +23716,7 @@ package body Sem_Prag is -- Detect a duplicate refinement of a state (SPARK RM 7.2.2(8)) if Contains (Refined_States_Seen, State_Id) then - Error_Msg_NE + SPARK_Msg_NE ("duplicate refinement of state &", State, State_Id); return; end if; @@ -23890,7 +23746,7 @@ package body Sem_Prag is -- the package declaration. Error_Msg_Name_1 := Chars (Spec_Id); - Error_Msg_NE + SPARK_Msg_NE ("cannot refine state, & is not defined in package %", State, State_Id); end Check_Matching_State; @@ -23918,7 +23774,7 @@ package body Sem_Prag is if not Posted then Posted := True; - Error_Msg_NE + SPARK_Msg_NE ("state & has unused Part_Of constituents", State, State_Id); end if; @@ -23926,10 +23782,10 @@ package body Sem_Prag is Error_Msg_Sloc := Sloc (Constit_Id); if Ekind (Constit_Id) = E_Abstract_State then - Error_Msg_NE + SPARK_Msg_NE ("\abstract state & defined #", State, Constit_Id); else - Error_Msg_NE + SPARK_Msg_NE ("\variable & defined #", State, Constit_Id); end if; @@ -23950,6 +23806,7 @@ package body Sem_Prag is begin -- A refinement clause appears as a component association where the -- sole choice is the state and the expressions are the constituents. + -- This is a syntax error, always report. if Nkind (Clause) /= N_Component_Association then Error_Msg_N ("malformed state refinement clause", Clause); @@ -23975,7 +23832,7 @@ package body Sem_Prag is if Ekind (State_Id) = E_Abstract_State then Check_Matching_State; else - Error_Msg_NE + SPARK_Msg_NE ("& must denote an abstract state", State, State_Id); return; end if; @@ -23992,15 +23849,15 @@ package body Sem_Prag is while Present (Body_Ref_Elmt) loop Body_Ref := Node (Body_Ref_Elmt); - Error_Msg_N ("reference to & not allowed", Body_Ref); + SPARK_Msg_N ("reference to & not allowed", Body_Ref); Error_Msg_Sloc := Sloc (State); - Error_Msg_N ("\refinement of & is visible#", Body_Ref); + SPARK_Msg_N ("\refinement of & is visible#", Body_Ref); Next_Elmt (Body_Ref_Elmt); end loop; end if; - -- The state name is illegal + -- The state name is illegal. This is a syntax error, always report. else Error_Msg_N ("malformed state name in refinement clause", State); @@ -24012,7 +23869,7 @@ package body Sem_Prag is Extra_State := Next (State); if Present (Extra_State) then - Error_Msg_N + SPARK_Msg_N ("refinement clause cannot cover multiple states", Extra_State); end if; @@ -24028,7 +23885,7 @@ package body Sem_Prag is if Nkind (Constit) = N_Aggregate then if Present (Component_Associations (Constit)) then - Error_Msg_N + SPARK_Msg_N ("constituents of refinement clause must appear in " & "positional form", Constit); @@ -24087,7 +23944,7 @@ package body Sem_Prag is -- external (SPARK RM 7.2.8(2)). else - Error_Msg_NE + SPARK_Msg_NE ("external state & requires at least one external " & "constituent or null refinement", State, State_Id); end if; @@ -24096,7 +23953,7 @@ package body Sem_Prag is -- constituents (SPARK RM 7.2.8(1)). elsif External_Constit_Seen then - Error_Msg_NE + SPARK_Msg_NE ("non-external state & cannot contain external constituents in " & "refinement", State, State_Id); end if; @@ -24107,70 +23964,6 @@ package body Sem_Prag is Report_Unused_Constituents (Part_Of_Constits); end Analyze_Refinement_Clause; - ---------------------------------- - -- Check_Refinement_List_Syntax -- - ---------------------------------- - - procedure Check_Refinement_List_Syntax (List : Node_Id) is - procedure Check_Clause_Syntax (Clause : Node_Id); - -- Verify the syntax of state refinement clause Clause - - ------------------------- - -- Check_Clause_Syntax -- - ------------------------- - - procedure Check_Clause_Syntax (Clause : Node_Id) is - Constits : constant Node_Id := Expression (Clause); - Constit : Node_Id; - - begin - -- State to be refined - - Check_Item_Syntax (First (Choices (Clause))); - - -- Multiple constituents - - if Nkind (Constits) = N_Aggregate - and then Present (Expressions (Constits)) - then - Constit := First (Expressions (Constits)); - while Present (Constit) loop - Check_Item_Syntax (Constit); - Next (Constit); - end loop; - - -- Single constituent - - else - Check_Item_Syntax (Constits); - end if; - end Check_Clause_Syntax; - - -- Local variables - - Clause : Node_Id; - - -- Start of processing for Check_Refinement_List_Syntax - - begin - -- Multiple state refinement clauses - - if Nkind (List) = N_Aggregate - and then Present (Component_Associations (List)) - then - Clause := First (Component_Associations (List)); - while Present (Clause) loop - Check_Clause_Syntax (Clause); - Next (Clause); - end loop; - - -- Single state refinement clause - - else - Check_Clause_Syntax (List); - end if; - end Check_Refinement_List_Syntax; - ------------------------- -- Collect_Body_States -- ------------------------- @@ -24271,7 +24064,7 @@ package body Sem_Prag is if Present (States) then State_Elmt := First_Elmt (States); while Present (State_Elmt) loop - Error_Msg_N + SPARK_Msg_N ("abstract state & must be refined", Node (State_Elmt)); Next_Elmt (State_Elmt); @@ -24302,17 +24095,17 @@ package body Sem_Prag is if not Posted then Posted := True; - Error_Msg_N + SPARK_Msg_N ("body of package & has unused hidden states", Body_Id); end if; Error_Msg_Sloc := Sloc (State_Id); if Ekind (State_Id) = E_Abstract_State then - Error_Msg_NE + SPARK_Msg_NE ("\abstract state & defined #", Body_Id, State_Id); else - Error_Msg_NE + SPARK_Msg_NE ("\variable & defined #", Body_Id, State_Id); end if; @@ -24333,14 +24126,6 @@ package body Sem_Prag is begin Set_Analyzed (N); - -- Verify the syntax of pragma Refined_State when SPARK checks are - -- suppressed. Semantic analysis is disabled in this mode. - - if SPARK_Mode = Off then - Check_Refinement_List_Syntax (Clauses); - return; - end if; - Body_Id := Defining_Entity (Body_Decl); Spec_Id := Corresponding_Spec (Body_Decl); @@ -24359,7 +24144,7 @@ package body Sem_Prag is if Nkind (Clauses) = N_Aggregate then if Present (Expressions (Clauses)) then - Error_Msg_N + SPARK_Msg_N ("state refinements must appear as component associations", Clauses); @@ -24525,94 +24310,6 @@ package body Sem_Prag is end if; end Check_Applicable_Policy; - ---------------------------------- - -- Check_Dependence_List_Syntax -- - ---------------------------------- - - procedure Check_Dependence_List_Syntax (List : Node_Id) is - procedure Check_Clause_Syntax (Clause : Node_Id); - -- Verify the syntax of a dependency clause Clause - - ------------------------- - -- Check_Clause_Syntax -- - ------------------------- - - procedure Check_Clause_Syntax (Clause : Node_Id) is - Input : Node_Id; - Inputs : Node_Id; - Output : Node_Id; - - begin - -- Output items - - Output := First (Choices (Clause)); - while Present (Output) loop - Check_Item_Syntax (Output); - Next (Output); - end loop; - - Inputs := Expression (Clause); - - -- A self-dependency appears as operator "+" - - if Nkind (Inputs) = N_Op_Plus then - Inputs := Right_Opnd (Inputs); - end if; - - -- Input items - - if Nkind (Inputs) = N_Aggregate then - if Present (Expressions (Inputs)) then - Input := First (Expressions (Inputs)); - while Present (Input) loop - Check_Item_Syntax (Input); - Next (Input); - end loop; - - else - Error_Msg_N ("malformed input dependency list", Inputs); - end if; - - -- Single input item - - else - Check_Item_Syntax (Inputs); - end if; - end Check_Clause_Syntax; - - -- Local variables - - Clause : Node_Id; - - -- Start of processing for Check_Dependence_List_Syntax - - begin - -- Null dependency relation - - if Nkind (List) = N_Null then - null; - - -- Verify the syntax of a single or multiple dependency clauses - - elsif Nkind (List) = N_Aggregate - and then Present (Component_Associations (List)) - then - Clause := First (Component_Associations (List)); - while Present (Clause) loop - if Has_Extra_Parentheses (Clause) then - null; - else - Check_Clause_Syntax (Clause); - end if; - - Next (Clause); - end loop; - - else - Error_Msg_N ("malformed dependency relation", List); - end if; - end Check_Dependence_List_Syntax; - ------------------------------- -- Check_External_Properties -- ------------------------------- @@ -24658,97 +24355,12 @@ package body Sem_Prag is null; else - Error_Msg_N + SPARK_Msg_N ("illegal combination of external properties (SPARK RM 7.1.2(6))", Item); end if; end Check_External_Properties; - ------------------------------ - -- Check_Global_List_Syntax -- - ------------------------------ - - procedure Check_Global_List_Syntax (List : Node_Id) is - Assoc : Node_Id; - Item : Node_Id; - - begin - -- Null global list - - if Nkind (List) = N_Null then - null; - - -- Single global item - - elsif Nkind_In (List, N_Expanded_Name, - N_Identifier, - N_Selected_Component) - then - null; - - elsif Nkind (List) = N_Aggregate then - - -- Items in a simple global list - - if Present (Expressions (List)) then - Item := First (Expressions (List)); - while Present (Item) loop - Check_Item_Syntax (Item); - Next (Item); - end loop; - - -- Items in a moded global list - - elsif Present (Component_Associations (List)) then - Assoc := First (Component_Associations (List)); - while Present (Assoc) loop - Check_Item_Syntax (First (Choices (Assoc))); - Check_Global_List_Syntax (Expression (Assoc)); - - Next (Assoc); - end loop; - end if; - - -- Anything else is an error - - else - Error_Msg_N ("malformed global list", List); - end if; - end Check_Global_List_Syntax; - - ----------------------- - -- Check_Item_Syntax -- - ----------------------- - - procedure Check_Item_Syntax (Item : Node_Id) is - begin - -- Null can appear in various annotation lists to denote a missing or - -- optional relation. - - if Nkind (Item) = N_Null then - null; - - -- Formal parameter, state or variable nodes - - elsif Nkind_In (Item, N_Expanded_Name, - N_Identifier, - N_Selected_Component) - then - null; - - -- Attribute 'Result can appear in annotations to denote the outcome of - -- a function call. - - elsif Is_Attribute_Result (Item) then - null; - - -- Any other node cannot possibly denote a legal SPARK item - - else - Error_Msg_N ("malformed item", Item); - end if; - end Check_Item_Syntax; - ---------------- -- Check_Kind -- ---------------- @@ -24862,10 +24474,17 @@ package body Sem_Prag is -- Start of processing for Check_Missing_Part_Of begin + -- Do not consider abstract states, variables or package instantiations + -- coming from an instance as those always inherit the Part_Of indicator + -- of the instance itself. + + if In_Instance then + return; + -- Do not consider internally generated entities as these can never -- have a Part_Of indicator. - if not Comes_From_Source (Item_Id) then + elsif not Comes_From_Source (Item_Id) then return; -- Perform these checks only when SPARK_Mode is enabled as they will @@ -25068,7 +24687,7 @@ package body Sem_Prag is if Present (State_Id) then Error_Msg_Name_1 := Chars (Constit_Id); - Error_Msg_NE + SPARK_Msg_NE ("cannot mention state & and its constituent % in the same " & "context", Context, State_Id); exit; @@ -25208,10 +24827,12 @@ package body Sem_Prag is raise Program_Error; end if; - -- Invalid list + -- To accomodate partial decoration of disabled SPARK features, this + -- routine may be called with illegal input. If this is the case, do + -- not raise Program_Error. else - raise Program_Error; + null; end if; end Process_Global_List; @@ -25314,19 +24935,22 @@ package body Sem_Prag is end loop; end if; - -- Invalid list + -- To accomodate partial decoration of disabled SPARK features, this + -- routine may be called with illegal input. If this is the case, do + -- not raise Program_Error. else - raise Program_Error; + null; end if; end Collect_Global_List; -- Local variables - Formal : Entity_Id; - Global : Node_Id; - List : Node_Id; - Spec_Id : Entity_Id; + Subp_Decl : constant Node_Id := Parent (Parent (Subp_Id)); + Formal : Entity_Id; + Global : Node_Id; + List : Node_Id; + Spec_Id : Entity_Id; -- Start of processing for Collect_Subprogram_Inputs_Outputs @@ -25335,8 +24959,16 @@ package body Sem_Prag is -- Find the entity of the corresponding spec when processing a body - if Ekind (Subp_Id) = E_Subprogram_Body then - Spec_Id := Corresponding_Spec (Parent (Parent (Subp_Id))); + if Nkind (Subp_Decl) = N_Subprogram_Body + and then Present (Corresponding_Spec (Subp_Decl)) + then + Spec_Id := Corresponding_Spec (Subp_Decl); + + elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub + and then Present (Corresponding_Spec_Of_Stub (Subp_Decl)) + then + Spec_Id := Corresponding_Spec_Of_Stub (Subp_Decl); + else Spec_Id := Subp_Id; end if; @@ -25616,13 +25248,13 @@ package body Sem_Prag is if Nkind (Expr) = N_Aggregate and then Present (Component_Associations (Expr)) then - Error_Msg_N + SPARK_Msg_N ("dependency clause contains extra parentheses", Expr); -- Otherwise the expression is a malformed construct else - Error_Msg_N ("malformed dependency clause", Expr); + SPARK_Msg_N ("malformed dependency clause", Expr); end if; Next (Expr); @@ -25893,7 +25525,6 @@ package body Sem_Prag is Pragma_Predicate => -1, Pragma_Preelaborable_Initialization => -1, Pragma_Preelaborate => -1, - Pragma_Preelaborate_05 => -1, Pragma_Pre_Class => -1, Pragma_Priority => -1, Pragma_Priority_Specific_Dispatching => -1, @@ -25903,8 +25534,6 @@ package body Sem_Prag is Pragma_Provide_Shift_Operators => -1, Pragma_Psect_Object => -1, Pragma_Pure => -1, - Pragma_Pure_05 => -1, - Pragma_Pure_12 => -1, Pragma_Pure_Function => -1, Pragma_Queuing_Policy => -1, Pragma_Rational => -1, diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb index c1f9f8c4deb..90a362c7799 100644 --- a/gcc/ada/sem_res.adb +++ b/gcc/ada/sem_res.adb @@ -1790,10 +1790,6 @@ package body Sem_Res is -- Try and fix up a literal so that it matches its expected type. New -- literals are manufactured if necessary to avoid cascaded errors. - function Proper_Current_Scope return Entity_Id; - -- Return the current scope. Skip loop scopes created for the purpose of - -- quantified expression analysis since those do not appear in the tree. - procedure Report_Ambiguous_Argument; -- Additional diagnostics when an ambiguous call has an ambiguous -- argument (typically a controlling actual). @@ -1856,30 +1852,6 @@ package body Sem_Res is end if; end Patch_Up_Value; - -------------------------- - -- Proper_Current_Scope -- - -------------------------- - - function Proper_Current_Scope return Entity_Id is - S : Entity_Id := Current_Scope; - - begin - while Present (S) loop - - -- Skip a loop scope created for quantified expression analysis - - if Ekind (S) = E_Loop - and then Nkind (Parent (S)) = N_Quantified_Expression - then - S := Scope (S); - else - exit; - end if; - end loop; - - return S; - end Proper_Current_Scope; - ------------------------------- -- Report_Ambiguous_Argument -- ------------------------------- @@ -2933,15 +2905,12 @@ package body Sem_Res is -- default expression mode (the Freeze_Expression routine tests this -- flag and only freezes static types if it is set). - -- Ada 2012 (AI05-177): Expression functions do not freeze. Only - -- their use (in an expanded call) freezes. + -- Ada 2012 (AI05-177): The declaration of an expression function + -- does not cause freezing, but we never reach here in that case. + -- Here we are resolving the corresponding expanded body, so we do + -- need to perform normal freezing. - if Ekind (Proper_Current_Scope) /= E_Function - or else Nkind (Original_Node (Unit_Declaration_Node - (Proper_Current_Scope))) /= N_Expression_Function - then - Freeze_Expression (N); - end if; + Freeze_Expression (N); -- Now we can do the expansion @@ -9159,7 +9128,7 @@ package body Sem_Res is Comp := First_Entity (T); while Present (Comp) loop if Chars (Comp) = Chars (S) - and then Covers (Etype (Comp), Typ) + and then Covers (Typ, Etype (Comp)) then if not Found then Found := True; @@ -9213,6 +9182,9 @@ package body Sem_Res is Get_Next_Interp (I, It); end loop Search; + -- There must be a legal interpretation at this point + + pragma Assert (Found); Resolve (P, It1.Typ); Set_Etype (N, Typ); Set_Entity_With_Checks (S, Comp1); diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index afb62c13cce..624687e39b7 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -638,7 +638,7 @@ package body Sem_Util is is begin Error_Msg_Warn := Warn; - Error_Msg_N ("unrecognized attribute&<", N); + Error_Msg_N ("unrecognized attribute&<<", N); -- Check for possible misspelling @@ -646,7 +646,7 @@ package body Sem_Util is while Error_Msg_Name_1 <= Last_Attribute_Name loop if Is_Bad_Spelling_Of (Nam, Error_Msg_Name_1) then Error_Msg_N -- CODEFIX - ("\possible misspelling of %<", N); + ("\possible misspelling of %<<", N); exit; end if; @@ -687,9 +687,9 @@ package body Sem_Util is end if; end Bad_Predicated_Subtype_Use; - ---------------------------------------- + ----------------------------------------- -- Bad_Unordered_Enumeration_Reference -- - ---------------------------------------- + ----------------------------------------- function Bad_Unordered_Enumeration_Reference (N : Node_Id; @@ -1555,7 +1555,7 @@ package body Sem_Util is else Error_Msg_NE - ("?static expression fails static predicate check on &", + ("??static expression fails static predicate check on &", Expr, Typ); end if; end if; @@ -2087,7 +2087,7 @@ package body Sem_Util is Error_Msg_N ("writable function parameter may affect " & "value in other component because order " - & "of evaluation is unspecified?", + & "of evaluation is unspecified??", Node (First_Elmt (Writable_Actuals_List))); end if; end if; @@ -15908,7 +15908,7 @@ package body Sem_Util is -- Remaining checks are only done on source nodes. Note that we test -- for violation of No_Fixed_IO even on non-source nodes, because the -- cases for checking violations of this restriction are instantiations - -- where the refernece in the instance has Comes_From_Source False. + -- where the reference in the instance has Comes_From_Source False. if not Comes_From_Source (N) then return; diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb index 6571a9ea7c2..d54937b8d4a 100644 --- a/gcc/ada/sem_warn.adb +++ b/gcc/ada/sem_warn.adb @@ -327,9 +327,7 @@ package body Sem_Warn is begin -- One argument, so check the argument - if Present (PA) - and then List_Length (PA) = 1 - then + if Present (PA) and then List_Length (PA) = 1 then if Nkind (First (PA)) = N_Parameter_Association then Find_Var (Explicit_Actual_Parameter (First (PA))); else @@ -415,9 +413,7 @@ package body Sem_Warn is begin for J in 1 .. Name_Len - (Len - 1) loop if Name_Buffer (J .. J + (Len - 1)) = S - and then - (J = 1 - or else Name_Buffer (J - 1) not in 'a' .. 'z') + and then (J = 1 or else Name_Buffer (J - 1) not in 'a' .. 'z') and then (J + Len > Name_Len or else Name_Buffer (J + Len) not in 'a' .. 'z') @@ -766,13 +762,14 @@ package body Sem_Warn is -- For an entry formal entity from an entry declaration, find the -- corresponding body formal from the given accept statement. - function May_Need_Initialized_Actual (Ent : Entity_Id) return Boolean; + procedure May_Need_Initialized_Actual (Ent : Entity_Id); -- If an entity of a generic type has default initialization, then the -- corresponding actual type should be fully initialized, or else there -- will be uninitialized components in the instantiation, that might go - -- unreported. This predicate allows the compiler to emit an appropriate - -- warning in the generic itself. In a sense, the use of a type that - -- requires full initialization is a weak part of the generic contract. + -- unreported. This routine marks the type of the uninitialized variable + -- appropriately to allow the compiler to emit an appropriate warning + -- in the instance. In a sense, the use of a type that requires full + -- initialization is a weak part of the generic contract. function Missing_Subunits return Boolean; -- We suppress warnings when there are missing subunits, because this @@ -827,38 +824,30 @@ package body Sem_Warn is -- May_Need_Initialized_Actual -- ----------------------------------- - function May_Need_Initialized_Actual (Ent : Entity_Id) return Boolean is + procedure May_Need_Initialized_Actual (Ent : Entity_Id) is T : constant Entity_Id := Etype (Ent); Par : constant Node_Id := Parent (T); - Res : Boolean; begin if not Is_Generic_Type (T) then - Res := False; + null; elsif (Nkind (Par)) = N_Private_Extension_Declaration then - Set_Needs_Initialized_Actual (Par); - Res := True; - elsif (Nkind (Par)) = N_Formal_Type_Declaration - and then Nkind (Formal_Type_Definition (Par)) - = N_Formal_Private_Type_Definition - then - Set_Needs_Initialized_Actual (Formal_Type_Definition (Par)); - Res := True; + -- We only indicate the first such variable in the generic. - else - Res := False; - end if; + if No (Uninitialized_Variable (Par)) then + Set_Uninitialized_Variable (Par, Ent); + end if; - if Res then - Error_Msg_N ("??!variable& of a generic type is potentially " - & "uninitialized", Ent); - Error_Msg_NE ("\??instantiations must provide fully initialized " - & "type for&", Ent, T); + elsif (Nkind (Par)) = N_Formal_Type_Declaration + and then Nkind (Formal_Type_Definition (Par)) = + N_Formal_Private_Type_Definition + then + if No (Uninitialized_Variable (Formal_Type_Definition (Par))) then + Set_Uninitialized_Variable (Formal_Type_Definition (Par), Ent); + end if; end if; - - return Res; end May_Need_Initialized_Actual; ---------------------- @@ -984,8 +973,8 @@ package body Sem_Warn is when N_Generic_Package_Declaration => return not Is_List_Member (Prev) - or else List_Containing (Prev) - /= Generic_Formal_Declarations (P); + or else List_Containing (Prev) /= + Generic_Formal_Declarations (P); -- Similarly, the generic formals of a generic subprogram are -- not accessible. @@ -1051,9 +1040,7 @@ package body Sem_Warn is -- real errors so far (this last check avoids junk messages resulting -- from errors, e.g. a subunit that is not loaded). - if Warning_Mode = Suppress - or else Serious_Errors_Detected /= 0 - then + if Warning_Mode = Suppress or else Serious_Errors_Detected /= 0 then return; end if; @@ -1101,9 +1088,8 @@ package body Sem_Warn is -- Special processing for access types - if Present (UR) - and then Is_Access_Type (E1T) - then + if Present (UR) and then Is_Access_Type (E1T) then + -- For access types, the only time we made a UR entry was -- for a dereference, and so we post the appropriate warning -- here (note that the dereference may not be explicit in @@ -1125,7 +1111,7 @@ package body Sem_Warn is elsif Warn_On_Constant and then (Ekind (E1) = E_Variable - and then Has_Initial_Value (E1)) + and then Has_Initial_Value (E1)) and then Never_Set_In_Source_Check_Spec (E1) and then not Address_Taken (E1) and then not Generic_Package_Spec_Entity (E1) @@ -1173,35 +1159,35 @@ package body Sem_Warn is elsif Never_Set_In_Source_Check_Spec (E1) - -- No warning if warning for this case turned off + -- No warning if warning for this case turned off - and then Warn_On_No_Value_Assigned + and then Warn_On_No_Value_Assigned - -- No warning if address taken somewhere + -- No warning if address taken somewhere - and then not Address_Taken (E1) + and then not Address_Taken (E1) - -- No warning if explicit initial value + -- No warning if explicit initial value - and then not Has_Initial_Value (E1) + and then not Has_Initial_Value (E1) - -- No warning for generic package spec entities, since we - -- might set them in a child unit or something like that + -- No warning for generic package spec entities, since we + -- might set them in a child unit or something like that - and then not Generic_Package_Spec_Entity (E1) + and then not Generic_Package_Spec_Entity (E1) - -- No warning if fully initialized type, except that for - -- this purpose we do not consider access types to qualify - -- as fully initialized types (relying on an access type - -- variable being null when it is never set is a bit odd). + -- No warning if fully initialized type, except that for + -- this purpose we do not consider access types to qualify + -- as fully initialized types (relying on an access type + -- variable being null when it is never set is a bit odd). - -- Also we generate warning for an out parameter that is - -- never referenced, since again it seems odd to rely on - -- default initialization to set an out parameter value. + -- Also we generate warning for an out parameter that is + -- never referenced, since again it seems odd to rely on + -- default initialization to set an out parameter value. - and then (Is_Access_Type (E1T) - or else Ekind (E1) = E_Out_Parameter - or else not Is_Fully_Initialized_Type (E1T)) + and then (Is_Access_Type (E1T) + or else Ekind (E1) = E_Out_Parameter + or else not Is_Fully_Initialized_Type (E1T)) then -- Do not output complaint about never being assigned a -- value if a pragma Unmodified applies to the variable @@ -1312,16 +1298,15 @@ package body Sem_Warn is if not Has_Unmodified (E1) and then not Warnings_Off_E1 and then not Is_Junk_Name (Chars (E1)) - and then not May_Need_Initialized_Actual (E1) then Output_Reference_Error ("?v?variable& is read but never assigned!"); + May_Need_Initialized_Actual (E1); end if; elsif not Has_Unreferenced (E1) and then not Warnings_Off_E1 and then not Is_Junk_Name (Chars (E1)) - and then not May_Need_Initialized_Actual (E1) then Output_Reference_Error -- CODEFIX ("?v?variable& is never read and never assigned!"); @@ -1433,20 +1418,20 @@ package body Sem_Warn is if not Is_Trivial_Subprogram (Scope (E1)) then if not Warnings_Off_E1 then if Is_Access_Type (Etype (Parent (UR))) then - Error_Msg_N ("?`&.&` may be null!", UR); + Error_Msg_N ("??`&.&` may be null!", UR); else Error_Msg_N - ("?`&.&` may be referenced before " + ("??`&.&` may be referenced before " & "it has a value!", UR); end if; end if; end if; - -- All other cases of unset reference active + + -- All other cases of unset reference active elsif not Warnings_Off_E1 then Error_Msg_N - ("?& may be referenced before it has a value!", - UR); + ("??& may be referenced before it has a value!", UR); end if; end if; @@ -1460,134 +1445,125 @@ package body Sem_Warn is if not Referenced_Check_Spec (E1) - -- If Referenced_As_LHS is set, then that's still interesting - -- (potential "assigned but never read" case), but not if we - -- have pragma Unreferenced, which cancels this warning. + -- If Referenced_As_LHS is set, then that's still interesting + -- (potential "assigned but never read" case), but not if we + -- have pragma Unreferenced, which cancels this warning. and then (not Referenced_As_LHS_Check_Spec (E1) - or else not Has_Unreferenced (E1)) + or else not Has_Unreferenced (E1)) - -- Check that warnings on unreferenced entities are enabled + -- Check that warnings on unreferenced entities are enabled and then ((Check_Unreferenced and then not Is_Formal (E1)) - -- Case of warning on unreferenced formal - - or else - (Check_Unreferenced_Formals and then Is_Formal (E1)) - - -- Case of warning on unread variables modified by an - -- assignment, or an OUT parameter if it is the only one. - - or else - (Warn_On_Modified_Unread - and then Referenced_As_LHS_Check_Spec (E1)) - - -- Case of warning on any unread OUT parameter (note - -- such indications are only set if the appropriate - -- warning options were set, so no need to recheck here.) - - or else - Referenced_As_Out_Parameter_Check_Spec (E1)) - - -- All other entities, including local packages that cannot be - -- referenced from elsewhere, including those declared within a - -- package body. - - and then (Is_Object (E1) - or else - Is_Type (E1) - or else - Ekind (E1) = E_Label - or else - Ekind (E1) = E_Exception - or else - Ekind (E1) = E_Named_Integer - or else - Ekind (E1) = E_Named_Real - or else - Is_Overloadable (E1) - - -- Package case, if the main unit is a package spec - -- or generic package spec, then there may be a - -- corresponding body that references this package - -- in some other file. Otherwise we can be sure - -- that there is no other reference. - - or else - (Ekind (E1) = E_Package - and then - not Is_Package_Or_Generic_Package - (Cunit_Entity (Current_Sem_Unit)))) + -- Case of warning on unreferenced formal - -- Exclude instantiations, since there is no reason why every - -- entity in an instantiation should be referenced. + or else (Check_Unreferenced_Formals and then Is_Formal (E1)) - and then Instantiation_Location (Sloc (E1)) = No_Location + -- Case of warning on unread variables modified by an + -- assignment, or an OUT parameter if it is the only one. - -- Exclude formal parameters from bodies if the corresponding - -- spec entity has been referenced in the case where there is - -- a separate spec. + or else (Warn_On_Modified_Unread + and then Referenced_As_LHS_Check_Spec (E1)) - and then not (Is_Formal (E1) - and then Ekind (Scope (E1)) = E_Subprogram_Body - and then Present (Spec_Entity (E1)) - and then Referenced (Spec_Entity (E1))) + -- Case of warning on any unread OUT parameter (note such + -- indications are only set if the appropriate warning + -- options were set, so no need to recheck here.) - -- Consider private type referenced if full view is referenced. - -- If there is not full view, this is a generic type on which - -- warnings are also useful. + or else Referenced_As_Out_Parameter_Check_Spec (E1)) - and then - not (Is_Private_Type (E1) - and then Present (Full_View (E1)) - and then Referenced (Full_View (E1))) + -- All other entities, including local packages that cannot be + -- referenced from elsewhere, including those declared within a + -- package body. - -- Don't worry about full view, only about private type + and then (Is_Object (E1) + or else Is_Type (E1) + or else Ekind (E1) = E_Label + or else Ekind_In (E1, E_Exception, + E_Named_Integer, + E_Named_Real) + or else Is_Overloadable (E1) - and then not Has_Private_Declaration (E1) + -- Package case, if the main unit is a package spec + -- or generic package spec, then there may be a + -- corresponding body that references this package + -- in some other file. Otherwise we can be sure + -- that there is no other reference. - -- Eliminate dispatching operations from consideration, we - -- cannot tell if these are referenced or not in any easy - -- manner (note this also catches Adjust/Finalize/Initialize). + or else + (Ekind (E1) = E_Package + and then + not Is_Package_Or_Generic_Package + (Cunit_Entity (Current_Sem_Unit)))) - and then not Is_Dispatching_Operation (E1) + -- Exclude instantiations, since there is no reason why every + -- entity in an instantiation should be referenced. - -- Check entity that can be publicly referenced (we do not give - -- messages for such entities, since there could be other - -- units, not involved in this compilation, that contain - -- relevant references. + and then Instantiation_Location (Sloc (E1)) = No_Location - and then not Publicly_Referenceable (E1) + -- Exclude formal parameters from bodies if the corresponding + -- spec entity has been referenced in the case where there is + -- a separate spec. - -- Class wide types are marked as source entities, but they are - -- not really source entities, and are always created, so we do - -- not care if they are not referenced. + and then not (Is_Formal (E1) + and then Ekind (Scope (E1)) = E_Subprogram_Body + and then Present (Spec_Entity (E1)) + and then Referenced (Spec_Entity (E1))) - and then Ekind (E1) /= E_Class_Wide_Type + -- Consider private type referenced if full view is referenced. + -- If there is not full view, this is a generic type on which + -- warnings are also useful. + + and then + not (Is_Private_Type (E1) + and then Present (Full_View (E1)) + and then Referenced (Full_View (E1))) - -- Objects other than parameters of task types are allowed to - -- be non-referenced, since they start up tasks. + -- Don't worry about full view, only about private type - and then ((Ekind (E1) /= E_Variable - and then Ekind (E1) /= E_Constant - and then Ekind (E1) /= E_Component) - or else not Is_Task_Type (E1T)) + and then not Has_Private_Declaration (E1) - -- For subunits, only place warnings on the main unit itself, - -- since parent units are not completely compiled. + -- Eliminate dispatching operations from consideration, we + -- cannot tell if these are referenced or not in any easy + -- manner (note this also catches Adjust/Finalize/Initialize). - and then (Nkind (Unit (Cunit (Main_Unit))) /= N_Subunit - or else Get_Source_Unit (E1) = Main_Unit) + and then not Is_Dispatching_Operation (E1) - -- No warning on a return object, because these are often - -- created with a single expression and an implicit return. - -- If the object is a variable there will be a warning - -- indicating that it could be declared constant. + -- Check entity that can be publicly referenced (we do not give + -- messages for such entities, since there could be other + -- units, not involved in this compilation, that contain + -- relevant references. - and then not - (Ekind (E1) = E_Constant and then Is_Return_Object (E1)) + and then not Publicly_Referenceable (E1) + + -- Class wide types are marked as source entities, but they are + -- not really source entities, and are always created, so we do + -- not care if they are not referenced. + + and then Ekind (E1) /= E_Class_Wide_Type + + -- Objects other than parameters of task types are allowed to + -- be non-referenced, since they start up tasks. + + and then ((Ekind (E1) /= E_Variable + and then Ekind (E1) /= E_Constant + and then Ekind (E1) /= E_Component) + or else not Is_Task_Type (E1T)) + + -- For subunits, only place warnings on the main unit itself, + -- since parent units are not completely compiled. + + and then (Nkind (Unit (Cunit (Main_Unit))) /= N_Subunit + or else Get_Source_Unit (E1) = Main_Unit) + + -- No warning on a return object, because these are often + -- created with a single expression and an implicit return. + -- If the object is a variable there will be a warning + -- indicating that it could be declared constant. + + and then not + (Ekind (E1) = E_Constant and then Is_Return_Object (E1)) then -- Suppress warnings in internal units if not in -gnatg mode -- (these would be junk warnings for an applications program, @@ -1648,10 +1624,10 @@ package body Sem_Warn is <<Continue>> if (Is_Package_Or_Generic_Package (E1) - and then Nkind (Parent (E1)) = N_Package_Specification - and then - Nkind (Original_Node (Unit_Declaration_Node (E1))) - /= N_Formal_Package_Declaration) + and then Nkind (Parent (E1)) = N_Package_Specification + and then + Nkind (Original_Node (Unit_Declaration_Node (E1))) /= + N_Formal_Package_Declaration) or else Ekind (E1) = E_Block then @@ -1770,9 +1746,7 @@ package body Sem_Warn is E : constant Entity_Id := Entity (N); begin - if (Ekind (E) = E_Variable - or else - Ekind (E) = E_Out_Parameter) + if Ekind_In (E, E_Variable, E_Out_Parameter) and then Never_Set_In_Source_Check_Spec (E) and then not Has_Initial_Value (E) and then (No (Unset_Reference (E)) @@ -1836,8 +1810,9 @@ package body Sem_Warn is SE : constant Entity_Id := Scope (E); function Within_Postcondition return Boolean; - -- Returns True iff N is within a Postcondition, an - -- Ensures component in a Test_Case, or a Contract_Cases. + -- Returns True if N is within a Postcondition, a + -- Refined_Post, an Ensures component in a Test_Case, + -- or a Contract_Cases. -------------------------- -- Within_Postcondition -- @@ -1852,6 +1827,7 @@ package body Sem_Warn is if Nkind (Nod) = N_Pragma and then Nam_In (Pragma_Name (Nod), Name_Postcondition, + Name_Refined_Post, Name_Contract_Cases) then return True; @@ -1860,10 +1836,8 @@ package body Sem_Warn is P := Parent (Nod); if Nkind (P) = N_Pragma - and then - Pragma_Name (P) = Name_Test_Case - and then - Nod = Get_Ensures_From_CTC_Pragma (P) + and then Pragma_Name (P) = Name_Test_Case + and then Nod = Get_Ensures_From_CTC_Pragma (P) then return True; end if; @@ -1977,10 +1951,8 @@ package body Sem_Warn is P := Parent (P); exit when No (P); - if (Nkind (P) = N_If_Statement - or else - Nkind (P) = N_Elsif_Part) - and then Ref_In (Condition (P)) + if Nkind_In (P, N_If_Statement, N_Elsif_Part) + and then Ref_In (Condition (P)) then return; @@ -2272,9 +2244,7 @@ package body Sem_Warn is E1 := First_Entity (P); while Present (E1) loop - if Ekind (E1) = E_Package - and then Renamed_Object (E1) = L - then + if Ekind (E1) = E_Package and then Renamed_Object (E1) = L then Is_Visible_Renaming := not Is_Hidden (E1); return E1; @@ -2321,12 +2291,8 @@ package body Sem_Warn is E := First_Entity (P); end if; - while Present (E) - and then E /= First_Private_Entity (P) - loop - if Comes_From_Source (E) - or else Present (Limited_View (P)) - then + while Present (E) and then E /= First_Private_Entity (P) loop + if Comes_From_Source (E) or else Present (Limited_View (P)) then return True; end if; @@ -2364,16 +2330,15 @@ package body Sem_Warn is Item := First (Context_Items (Cnode)); while Present (Item) loop if Nkind (Item) = N_With_Clause - and then not Implicit_With (Item) - and then In_Extended_Main_Source_Unit (Item) + and then not Implicit_With (Item) + and then In_Extended_Main_Source_Unit (Item) then Lunit := Entity (Name (Item)); -- Check if this unit is referenced (skip the check if this -- is explicitly marked by a pragma Unreferenced). - if not Referenced (Lunit) - and then not Has_Unreferenced (Lunit) + if not Referenced (Lunit) and then not Has_Unreferenced (Lunit) then -- Suppress warnings in internal units if not in -gnatg mode -- (these would be junk warnings for an application program, @@ -2688,9 +2653,7 @@ package body Sem_Warn is function Goto_Spec_Entity (E : Entity_Id) return Entity_Id is begin - if Is_Formal (E) - and then Present (Spec_Entity (E)) - then + if Is_Formal (E) and then Present (Spec_Entity (E)) then return Spec_Entity (E); else return E; @@ -2963,10 +2926,10 @@ package body Sem_Warn is if Nkind (P) = N_With_Clause then if Ekind (E) = E_Package then Error_Msg_NE - ("??with of obsolescent package& declared#", N, E); + ("?j?with of obsolescent package& declared#", N, E); elsif Ekind (E) = E_Procedure then Error_Msg_NE - ("??with of obsolescent procedure& declared#", N, E); + ("?j?with of obsolescent procedure& declared#", N, E); else Error_Msg_NE ("??with of obsolescent function& declared#", N, E); @@ -3217,9 +3180,7 @@ package body Sem_Warn is Track (Left_Opnd (Nod), Loc); Track (Right_Opnd (Nod), Loc); - elsif Is_Entity_Name (Nod) - and then Is_Object (Entity (Nod)) - then + elsif Is_Entity_Name (Nod) and then Is_Object (Entity (Nod)) then declare CV : constant Node_Id := Current_Value (Entity (Nod)); @@ -3228,15 +3189,15 @@ package body Sem_Warn is Error_Msg_Sloc := Sloc (CV); if Nkind (CV) not in N_Subexpr then - Error_Msg_N ("\\?(see test #)", Loc); + Error_Msg_N ("\\??(see test #)", Loc); elsif Nkind (Parent (CV)) = N_Case_Statement_Alternative then - Error_Msg_N ("\\?(see case alternative #)", Loc); + Error_Msg_N ("\\??(see case alternative #)", Loc); else - Error_Msg_N ("\\?(see assignment #)", Loc); + Error_Msg_N ("\\??(see assignment #)", Loc); end if; end if; end; @@ -3343,8 +3304,7 @@ package body Sem_Warn is Cond : Node_Id := C; begin - if Present (Parent (C)) - and then Nkind (Parent (C)) = N_Op_Not + if Present (Parent (C)) and then Nkind (Parent (C)) = N_Op_Not then True_Branch := not True_Branch; Cond := Parent (C); @@ -3479,9 +3439,9 @@ package body Sem_Warn is Present (Underlying_Type (Etype (Form1))) and then (Is_By_Reference_Type (Underlying_Type (Etype (Form1))) - or else - Convention (Underlying_Type (Etype (Form1))) = - Convention_Ada_Pass_By_Reference) + or else + Convention (Underlying_Type (Etype (Form1))) = + Convention_Ada_Pass_By_Reference) then null; @@ -3555,7 +3515,7 @@ package body Sem_Warn is then if Act1 = First_Actual (N) then Error_Msg_FE - ("<`IN OUT` prefix overlaps with " + ("<<`IN OUT` prefix overlaps with " & "actual for&", Act1, Form); else @@ -3563,7 +3523,7 @@ package body Sem_Warn is Error_Msg_Node_2 := Form; Error_Msg_FE - ("<writable actual for & overlaps with " + ("<<writable actual for & overlaps with " & "actual for&", Act1, Form); end if; @@ -3575,7 +3535,7 @@ package body Sem_Warn is -- This is one of the messages Error_Msg_FE - ("<writable actual for & overlaps with " + ("<<writable actual for & overlaps with " & "actual for&", Act1, Form1); end if; end; @@ -3673,9 +3633,9 @@ package body Sem_Warn is begin return Nkind (R) = N_Attribute_Reference - and then Attribute_Name (R) = Name_Length - and then Is_Entity_Name (Prefix (R)) - and then Entity (Prefix (R)) = Ent; + and then Attribute_Name (R) = Name_Length + and then Is_Entity_Name (Prefix (R)) + and then Entity (Prefix (R)) = Ent; end Length_Reference; ----------- @@ -3777,7 +3737,7 @@ package body Sem_Warn is exit when Pctr = 0 and then (Tref (Sref .. Sref + 1) = ".." - or else + or else Tref (Sref .. Sref + 2) = " .."); -- Quit if we have hit EOF character, something wrong @@ -4132,9 +4092,7 @@ package body Sem_Warn is -- is not quite right, but it really does not matter that we fail -- to output the warning in some obscure cases of name clashes. - if Nkind (N) = N_Identifier - and then Chars (N) = Chars (Ent) - then + if Nkind (N) = N_Identifier and then Chars (N) = Chars (Ent) then return Abandon; else return OK; diff --git a/gcc/ada/sinfo.adb b/gcc/ada/sinfo.adb index c1eaae55793..0c1a7776502 100644 --- a/gcc/ada/sinfo.adb +++ b/gcc/ada/sinfo.adb @@ -2224,15 +2224,6 @@ package body Sinfo is return List2 (N); end Names; - function Needs_Initialized_Actual - (N : Node_Id) return Boolean is - begin - pragma Assert (False - or else NT (N).Nkind = N_Formal_Private_Type_Definition - or else NT (N).Nkind = N_Private_Extension_Declaration); - return Flag18 (N); - end Needs_Initialized_Actual; - function Next_Entity (N : Node_Id) return Node_Id is begin @@ -3184,6 +3175,15 @@ package body Sinfo is return List2 (N); end Visible_Declarations; + function Uninitialized_Variable + (N : Node_Id) return Node_Id is + begin + pragma Assert (False + or else NT (N).Nkind = N_Formal_Private_Type_Definition + or else NT (N).Nkind = N_Private_Extension_Declaration); + return Node3 (N); + end Uninitialized_Variable; + function Used_Operations (N : Node_Id) return Elist_Id is begin @@ -5373,15 +5373,6 @@ package body Sinfo is Set_List2_With_Parent (N, Val); end Set_Names; - procedure Set_Needs_Initialized_Actual - (N : Node_Id; Val : Boolean := True) is - begin - pragma Assert (False - or else NT (N).Nkind = N_Formal_Private_Type_Definition - or else NT (N).Nkind = N_Private_Extension_Declaration); - Set_Flag18 (N, Val); - end Set_Needs_Initialized_Actual; - procedure Set_Next_Entity (N : Node_Id; Val : Node_Id) is begin @@ -6333,6 +6324,15 @@ package body Sinfo is Set_List2_With_Parent (N, Val); end Set_Visible_Declarations; + procedure Set_Uninitialized_Variable + (N : Node_Id; Val : Node_Id) is + begin + pragma Assert (False + or else NT (N).Nkind = N_Formal_Private_Type_Definition + or else NT (N).Nkind = N_Private_Extension_Declaration); + Set_Node3 (N, Val); + end Set_Uninitialized_Variable; + procedure Set_Used_Operations (N : Node_Id; Val : Elist_Id) is begin diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads index 9a0afe7f5a7..73dea2a6601 100644 --- a/gcc/ada/sinfo.ads +++ b/gcc/ada/sinfo.ads @@ -1701,12 +1701,6 @@ package Sinfo is -- present in an N_Subtype_Indication node, since we also use these in -- calls to Freeze_Expression. - -- Needs_Initialized_Actual (Flag18-Sem) - -- Present in formal_private_type_definitions and on private extension - -- declarations. Set when the use of a formal type in a generic suggests - -- that the actual should be a fully initialized type, to avoid potential - -- use of uninitialized values. - -- Next_Entity (Node2-Sem) -- Present in defining identifiers, defining character literals and -- defining operator symbols (i.e. in all entities). The entities of a @@ -2050,6 +2044,13 @@ package Sinfo is -- the body, so this flag is used to generate the proper message (see -- Sem_Util.Check_Unused_Withs for details) + -- Uninitialized_Variable (Node3-Sem) + -- Present in N_Formal_Private_Type_Definition and in N_Private_ + -- Extension_Declarations. Indicates that a variable in a generic unit + -- whose type is a formal private or derived type is read without being + -- initialized. Used to warn if the corresponding actual type is not + -- a fully initialized type. + -- Used_Operations (Elist5-Sem) -- Present in N_Use_Type_Clause nodes. Holds the list of operations that -- are made potentially use-visible by the clause. Simplifies processing @@ -5278,6 +5279,7 @@ package Sinfo is -- N_Private_Extension_Declaration -- Sloc points to TYPE -- Defining_Identifier (Node1) + -- Uninitialized_Variable (Node3-Sem) -- Discriminant_Specifications (List4) (set to No_List if no -- discriminant part) -- Unknown_Discriminants_Present (Flag13) set if (<>) discriminant @@ -5286,7 +5288,6 @@ package Sinfo is -- Synchronized_Present (Flag7) -- Subtype_Indication (Node5) -- Interface_List (List2) (set to No_List if none) - -- Needs_Initialized_Actual (Flag18-Sem) --------------------- -- 8.4 Use Clause -- @@ -6709,10 +6710,10 @@ package Sinfo is -- N_Formal_Private_Type_Definition -- Sloc points to PRIVATE + -- Uninitialized_Variable (Node3-Sem) -- Abstract_Present (Flag4) -- Tagged_Present (Flag15) -- Limited_Present (Flag17) - -- Needs_Initialized_Actual (Flag18-Sem) -------------------------------------------- -- 12.5.1 Formal Derived Type Definition -- @@ -9202,9 +9203,6 @@ package Sinfo is function Names (N : Node_Id) return List_Id; -- List2 - function Needs_Initialized_Actual - (N : Node_Id) return Boolean; -- Flag18 - function Next_Entity (N : Node_Id) return Node_Id; -- Node2 @@ -9502,6 +9500,9 @@ package Sinfo is function Visible_Declarations (N : Node_Id) return List_Id; -- List2 + function Uninitialized_Variable + (N : Node_Id) return Node_Id; -- Node3 + function Used_Operations (N : Node_Id) return Elist_Id; -- Elist5 @@ -10204,9 +10205,6 @@ package Sinfo is procedure Set_Names (N : Node_Id; Val : List_Id); -- List2 - procedure Set_Needs_Initialized_Actual - (N : Node_Id; Val : Boolean := True); -- Flag18 - procedure Set_Next_Entity (N : Node_Id; Val : Node_Id); -- Node2 @@ -10504,6 +10502,9 @@ package Sinfo is procedure Set_Visible_Declarations (N : Node_Id; Val : List_Id); -- List2 + procedure Set_Uninitialized_Variable + (N : Node_Id; Val : Node_Id); -- Node3 + procedure Set_Used_Operations (N : Node_Id; Val : Elist_Id); -- Elist5 @@ -12496,7 +12497,6 @@ package Sinfo is pragma Inline (Must_Override); pragma Inline (Name); pragma Inline (Names); - pragma Inline (Needs_Initialized_Actual); pragma Inline (Next_Entity); pragma Inline (Next_Exit_Statement); pragma Inline (Next_Implicit_With); @@ -12591,6 +12591,7 @@ package Sinfo is pragma Inline (TSS_Elist); pragma Inline (Type_Definition); pragma Inline (Unit); + pragma Inline (Uninitialized_Variable); pragma Inline (Unknown_Discriminants_Present); pragma Inline (Unreferenced_In_Spec); pragma Inline (Variant_Part); @@ -12826,7 +12827,6 @@ package Sinfo is pragma Inline (Set_Must_Override); pragma Inline (Set_Name); pragma Inline (Set_Names); - pragma Inline (Set_Needs_Initialized_Actual); pragma Inline (Set_Next_Entity); pragma Inline (Set_Next_Exit_Statement); pragma Inline (Set_Next_Implicit_With); @@ -12919,6 +12919,7 @@ package Sinfo is pragma Inline (Set_Triggering_Statement); pragma Inline (Set_Type_Definition); pragma Inline (Set_Unit); + pragma Inline (Set_Uninitialized_Variable); pragma Inline (Set_Unknown_Discriminants_Present); pragma Inline (Set_Unreferenced_In_Spec); pragma Inline (Set_Used_Operations); diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl index b4fcb54ccb2..40202f2a3a0 100644 --- a/gcc/ada/snames.ads-tmpl +++ b/gcc/ada/snames.ads-tmpl @@ -578,7 +578,6 @@ package Snames is Name_Predicate : constant Name_Id := N + $; -- GNAT Name_Preelaborable_Initialization : constant Name_Id := N + $; -- Ada 05 Name_Preelaborate : constant Name_Id := N + $; - Name_Preelaborate_05 : constant Name_Id := N + $; -- GNAT Name_Pre_Class : constant Name_Id := N + $; -- GNAT -- Note: Priority is not in this list because its name matches the name of @@ -590,8 +589,6 @@ package Snames is Name_Provide_Shift_Operators : constant Name_Id := N + $; -- GNAT Name_Psect_Object : constant Name_Id := N + $; -- VMS Name_Pure : constant Name_Id := N + $; - Name_Pure_05 : constant Name_Id := N + $; -- GNAT - Name_Pure_12 : constant Name_Id := N + $; -- GNAT Name_Pure_Function : constant Name_Id := N + $; -- GNAT Name_Refined_Depends : constant Name_Id := N + $; -- GNAT Name_Refined_Global : constant Name_Id := N + $; -- GNAT @@ -1893,13 +1890,10 @@ package Snames is Pragma_Predicate, Pragma_Preelaborable_Initialization, Pragma_Preelaborate, - Pragma_Preelaborate_05, Pragma_Pre_Class, Pragma_Provide_Shift_Operators, Pragma_Psect_Object, Pragma_Pure, - Pragma_Pure_05, - Pragma_Pure_12, Pragma_Pure_Function, Pragma_Refined_Depends, Pragma_Refined_Global, diff --git a/gcc/ada/styleg.adb b/gcc/ada/styleg.adb index 0a1880f419e..c94759c7da0 100644 --- a/gcc/ada/styleg.adb +++ b/gcc/ada/styleg.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -1003,9 +1003,9 @@ package body Styleg is -- Check_Then -- ---------------- - -- In check if then layout mode (-gnatyi), we expect a THEN keyword - -- to appear either on the same line as the IF, or on a separate line - -- if the IF statement extends for more than one line. + -- In check if then layout mode (-gnatyi), we expect a THEN keyword to + -- appear either on the same line as the IF, or on a separate line if + -- the IF statement extends for more than one line. procedure Check_Then (If_Loc : Source_Ptr) is begin @@ -1061,7 +1061,7 @@ package body Styleg is begin if Style_Check_Xtra_Parens then Error_Msg -- CODEFIX - ("redundant parentheses?", Loc); + ("(style) redundant parentheses", Loc); end if; end Check_Xtra_Parens; diff --git a/gcc/ada/switch-c.adb b/gcc/ada/switch-c.adb index e7e32eb2653..e2f7c2ec494 100644 --- a/gcc/ada/switch-c.adb +++ b/gcc/ada/switch-c.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2001-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2001-2014, 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- -- @@ -815,11 +815,6 @@ package body Switch.C is System_Extend_Unit := Empty; Warning_Mode := Treat_As_Error; Style_Check_Main := True; - - -- Set Ada 2012 mode explicitly. We don't want to rely on the - -- implicit setting here, since for example, we want - -- Preelaborate_05 treated as Preelaborate - Ada_Version := Ada_2012; Ada_Version_Explicit := Ada_2012; Ada_Version_Pragma := Empty; diff --git a/gcc/ada/targparm.adb b/gcc/ada/targparm.adb index 3357c5dfe0e..0f93344ef37 100644 --- a/gcc/ada/targparm.adb +++ b/gcc/ada/targparm.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1999-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1999-2014, 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- -- @@ -160,7 +160,11 @@ package body Targparm is -- Version which reads in system.ads - procedure Get_Target_Parameters is + procedure Get_Target_Parameters + (Make_Id : Make_Id_Type := null; + Make_SC : Make_SC_Type := null; + Set_RND : Set_RND_Type := null) + is Text : Source_Buffer_Ptr; Hi : Source_Ptr; @@ -183,7 +187,10 @@ package body Targparm is Get_Target_Parameters (System_Text => Text, Source_First => 0, - Source_Last => Hi); + Source_Last => Hi, + Make_Id => Make_Id, + Make_SC => Make_SC, + Set_RND => Set_RND); end Get_Target_Parameters; -- Version where caller supplies system.ads text @@ -191,7 +198,10 @@ package body Targparm is procedure Get_Target_Parameters (System_Text : Source_Buffer_Ptr; Source_First : Source_Ptr; - Source_Last : Source_Ptr) + Source_Last : Source_Ptr; + Make_Id : Make_Id_Type := null; + Make_SC : Make_SC_Type := null; + Set_RND : Set_RND_Type := null) is P : Source_Ptr; -- Scans source buffer containing source of system.ads @@ -341,6 +351,61 @@ package body Targparm is null; end loop Ploop; + -- No_Dependence case + + if System_Text (P .. P + 16) = "No_Dependence => " then + P := P + 17; + + -- Skip this processing (and simply ignore No_Dependence lines) + -- if caller did not supply the three subprograms we need to + -- process these lines. + + if Make_Id = null then + goto Line_Loop_Continue; + end if; + + -- We have scanned out "pragma Restrictions (No_Dependence =>" + + declare + Unit : Node_Id; + Id : Node_Id; + Start : Source_Ptr; + + begin + Unit := Empty; + + -- Loop through components of name, building up Unit + + loop + Start := P; + while System_Text (P) /= '.' + and then + System_Text (P) /= ')' + loop + P := P + 1; + end loop; + + Id := Make_Id (System_Text (Start .. P - 1)); + + -- If first name, just capture the identifier + + if Unit = Empty then + Unit := Id; + else + Unit := Make_SC (Unit, Id); + end if; + + exit when System_Text (P) = ')'; + P := P + 1; + end loop; + + Set_RND (Unit); + goto Line_Loop_Continue; + end; + end if; + + -- Here if unrecognizable restrictions pragma form + Set_Standard_Error; Write_Line ("fatal error: system.ads is incorrectly formatted"); diff --git a/gcc/ada/targparm.ads b/gcc/ada/targparm.ads index 11c7a7edfb3..21f2d6db416 100644 --- a/gcc/ada/targparm.ads +++ b/gcc/ada/targparm.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1999-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1999-2014, 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- -- @@ -612,17 +612,42 @@ package Targparm is -- These subprograms are used to initialize the target parameter values -- from the system.ads file. Note that this is only done once, so if more -- than one call is made to either routine, the second and subsequent - -- calls are ignored. + -- calls are ignored. It also reads restriction pragmas from system.ads + -- and records them, though as further detailed below, the caller has some + -- control over the handling of No_Dependence restrictions. + + type Make_Id_Type is access function (Str : Text_Buffer) return Node_Id; + -- Parameter type for Get_Target_Parameters for function that creates an + -- identifier node with Sloc value System_Location and given string as the + -- Chars value. + + type Make_SC_Type is access function (Pre, Sel : Node_Id) return Node_Id; + -- Parameter type for Get_Target_Parameters for function that creates a + -- selected component with Sloc value System_Location and given Prefix + -- (Pre) and Selector (Sel) values. + + type Set_RND_Type is access procedure (Unit : Node_Id); + -- Parameter type for Get_Target_Parameters that records a Restriction + -- No_Dependence for the given unit (identifier or selected component). procedure Get_Target_Parameters (System_Text : Source_Buffer_Ptr; Source_First : Source_Ptr; - Source_Last : Source_Ptr); + Source_Last : Source_Ptr; + Make_Id : Make_Id_Type := null; + Make_SC : Make_SC_Type := null; + Set_RND : Set_RND_Type := null); -- Called at the start of execution to obtain target parameters from -- the source of package System. The parameters provide the source -- text to be scanned (in System_Text (Source_First .. Source_Last)). + -- if the three subprograms are left at their default value of null, + -- Get_Target_Parameters will ignore pragma Restrictions No_Dependence + -- lines, otherwise it will use these three subprograms to record them. - procedure Get_Target_Parameters; + procedure Get_Target_Parameters + (Make_Id : Make_Id_Type := null; + Make_SC : Make_SC_Type := null; + Set_RND : Set_RND_Type := null); -- This version reads in system.ads using Osint. The idea is that the -- caller uses the first version if they have to read system.ads anyway -- (e.g. the compiler) and uses this simpler interface if system.ads is diff --git a/gcc/ada/tbuild.adb b/gcc/ada/tbuild.adb index 524c14f7100..17ca12eac8c 100644 --- a/gcc/ada/tbuild.adb +++ b/gcc/ada/tbuild.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, 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- -- @@ -24,6 +24,7 @@ ------------------------------------------------------------------------------ with Atree; use Atree; +with Csets; use Csets; with Einfo; use Einfo; with Elists; use Elists; with Lib; use Lib; @@ -240,6 +241,24 @@ package body Tbuild is end if; end Make_Float_Literal; + ------------- + -- Make_Id -- + ------------- + + function Make_Id (Str : Text_Buffer) return Node_Id is + begin + Name_Len := 0; + + for J in Str'Range loop + Name_Len := Name_Len + 1; + Name_Buffer (Name_Len) := Fold_Lower (Str (J)); + end loop; + + return + Make_Identifier (System_Location, + Chars => Name_Find); + end Make_Id; + ------------------------------------- -- Make_Implicit_Exception_Handler -- ------------------------------------- @@ -459,6 +478,18 @@ package body Tbuild is UI_From_Int (RT_Exception_Code'Pos (Reason))); end Make_Raise_Storage_Error; + ------------- + -- Make_SC -- + ------------- + + function Make_SC (Pre, Sel : Node_Id) return Node_Id is + begin + return + Make_Selected_Component (System_Location, + Prefix => Pre, + Selector_Name => Sel); + end Make_SC; + ------------------------- -- Make_String_Literal -- ------------------------- @@ -749,6 +780,15 @@ package body Tbuild is return Result; end OK_Convert_To; + ------------- + -- Set_RND -- + ------------- + + procedure Set_RND (Unit : Node_Id) is + begin + Set_Restriction_No_Dependence (Unit, Warn => False); + end Set_RND; + -------------------------- -- Unchecked_Convert_To -- -------------------------- diff --git a/gcc/ada/tbuild.ads b/gcc/ada/tbuild.ads index 507dca41bf1..67a59d923c3 100644 --- a/gcc/ada/tbuild.ads +++ b/gcc/ada/tbuild.ads @@ -321,4 +321,16 @@ package Tbuild is -- Like Convert_To, but if a conversion is actually needed, constructs an -- N_Unchecked_Type_Conversion node to do the required conversion. + ------------------------------------- + -- Subprograms for Use by Gnat1drv -- + ------------------------------------- + + function Make_Id (Str : Text_Buffer) return Node_Id; + function Make_SC (Pre, Sel : Node_Id) return Node_Id; + procedure Set_RND (Unit : Node_Id); + -- Subprograms for call to Get_Target_Parameters in Gnat1drv, see spec + -- of package Targparm for full description of these three subprograms. + -- These have to be declared at the top level of a package (accessibility + -- issues), and Gnat1drv is a procedure, so they can't go there. + end Tbuild; diff --git a/gcc/ada/vms_data.ads b/gcc/ada/vms_data.ads index f28b9bf0732..ac07c620b88 100644 --- a/gcc/ada/vms_data.ads +++ b/gcc/ada/vms_data.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1996-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1996-2014, 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- -- @@ -7155,6 +7155,40 @@ package VMS_Data is -- -- Look for source, library or object files in the default directory. + S_Stub_Encoding : aliased constant S := "/RESULT_ENCODING=" & + "BRACKETS " & + "-Wb " & + "HEX " & + "-Wh " & + "UPPER " & + "-Wu " & + "SHIFT_JIS " & + "-Ws " & + "EUC " & + "-We " & + "UTF8 " & + "-W8"; + -- /RESULT_ENCODING[=encoding-type] + -- + -- Specify the wide character encoding method used when writing the + -- generated body in the result file. 'encoding-type' is one of the + -- following: + -- + -- BRACKETS (D) Brackets encoding. + -- + -- HEX Hex ESC encoding. + -- + -- UPPER Upper half encoding. + -- + -- SHIFT_JIS Shift-JIS encoding. + -- + -- EUC EUC Encoding. + -- + -- UTF8 UTF-8 encoding. + -- + -- See 'HELP GNAT COMPILE /WIDE_CHARACTER_ENCODING' for an explanation + -- about the different character encoding methods. + S_Stub_Ext : aliased constant S := "/EXTERNAL_REFERENCE=" & '"' & "-X" & '"'; -- /EXTERNAL_REFERENCE="name=val" @@ -7349,6 +7383,7 @@ package VMS_Data is (S_Stub_Add 'Access, S_Stub_Config 'Access, S_Stub_Current 'Access, + S_Stub_Encoding 'Access, S_Stub_Ext 'Access, S_Stub_Follow 'Access, S_Stub_Full 'Access, diff --git a/gcc/asan.c b/gcc/asan.c index 5021338b855..281a7956bbe 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -243,6 +243,19 @@ static GTY(()) tree shadow_ptr_types[2]; /* Decl for __asan_option_detect_stack_use_after_return. */ static GTY(()) tree asan_detect_stack_use_after_return; +/* Number of instrumentations in current function so far. */ + +static int asan_num_accesses; + +/* Check whether we should replace inline instrumentation with calls. */ + +static inline bool +use_calls_p () +{ + return ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX + && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD; +} + /* Hashtable support for memory references used by gimple statements. */ @@ -1288,8 +1301,8 @@ asan_protect_global (tree decl) into user section from multiple TUs are then assumed to be an array of such vars, putting padding in there breaks this assumption. */ - || (DECL_SECTION_NAME (decl) != NULL_TREE - && !DECL_HAS_IMPLICIT_SECTION_NAME_P (decl)) + || (DECL_SECTION_NAME (decl) != NULL + && !symtab_get_node (decl)->implicit_section) || DECL_SIZE (decl) == 0 || ASAN_RED_ZONE_SIZE * BITS_PER_UNIT > MAX_OFILE_ALIGNMENT || !valid_constant_size_p (DECL_SIZE_UNIT (decl)) @@ -1320,7 +1333,7 @@ asan_protect_global (tree decl) IS_STORE is either 1 (for a store) or 0 (for a load). */ static tree -report_error_func (bool is_store, HOST_WIDE_INT size_in_bytes, bool slow_p) +report_error_func (bool is_store, HOST_WIDE_INT size_in_bytes, int *nargs) { static enum built_in_function report[2][6] = { { BUILT_IN_ASAN_REPORT_LOAD1, BUILT_IN_ASAN_REPORT_LOAD2, @@ -1329,13 +1342,37 @@ report_error_func (bool is_store, HOST_WIDE_INT size_in_bytes, bool slow_p) { BUILT_IN_ASAN_REPORT_STORE1, BUILT_IN_ASAN_REPORT_STORE2, BUILT_IN_ASAN_REPORT_STORE4, BUILT_IN_ASAN_REPORT_STORE8, BUILT_IN_ASAN_REPORT_STORE16, BUILT_IN_ASAN_REPORT_STORE_N } }; - if ((size_in_bytes & (size_in_bytes - 1)) != 0 - || size_in_bytes > 16 - || slow_p) - return builtin_decl_implicit (report[is_store][5]); + if (size_in_bytes == -1) + { + *nargs = 2; + return builtin_decl_implicit (report[is_store][5]); + } + *nargs = 1; return builtin_decl_implicit (report[is_store][exact_log2 (size_in_bytes)]); } +/* Construct a function tree for __asan_{load,store}{1,2,4,8,16,_n}. + IS_STORE is either 1 (for a store) or 0 (for a load). */ + +static tree +check_func (bool is_store, int size_in_bytes, int *nargs) +{ + static enum built_in_function check[2][6] + = { { BUILT_IN_ASAN_LOAD1, BUILT_IN_ASAN_LOAD2, + BUILT_IN_ASAN_LOAD4, BUILT_IN_ASAN_LOAD8, + BUILT_IN_ASAN_LOAD16, BUILT_IN_ASAN_LOADN }, + { BUILT_IN_ASAN_STORE1, BUILT_IN_ASAN_STORE2, + BUILT_IN_ASAN_STORE4, BUILT_IN_ASAN_STORE8, + BUILT_IN_ASAN_STORE16, BUILT_IN_ASAN_STOREN } }; + if (size_in_bytes == -1) + { + *nargs = 2; + return builtin_decl_implicit (check[is_store][5]); + } + *nargs = 1; + return builtin_decl_implicit (check[is_store][exact_log2 (size_in_bytes)]); +} + /* Split the current basic block and create a condition statement insertion point right before or after the statement pointed to by ITER. Return an iterator to the point at which the caller might @@ -1495,6 +1532,76 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location, return gimple_assign_lhs (g); } +/* BASE can already be an SSA_NAME; in that case, do not create a + new SSA_NAME for it. */ + +static tree +maybe_create_ssa_name (location_t loc, tree base, gimple_stmt_iterator *iter, + bool before_p) +{ + if (TREE_CODE (base) == SSA_NAME) + return base; + gimple g + = gimple_build_assign_with_ops (TREE_CODE (base), + make_ssa_name (TREE_TYPE (base), NULL), + base, NULL_TREE); + gimple_set_location (g, loc); + if (before_p) + gsi_insert_before (iter, g, GSI_SAME_STMT); + else + gsi_insert_after (iter, g, GSI_NEW_STMT); + return gimple_assign_lhs (g); +} + +/* Instrument the memory access instruction using callbacks. + Parameters are similar to BUILD_CHECK_STMT. */ + +static void +build_check_stmt_with_calls (location_t loc, tree base, tree len, + HOST_WIDE_INT size_in_bytes, gimple_stmt_iterator *iter, + bool before_p, bool is_store, bool is_scalar_access) +{ + gimple_stmt_iterator gsi = *iter; + tree base_ssa = maybe_create_ssa_name (loc, base, &gsi, before_p); + + gimple g + = gimple_build_assign_with_ops (NOP_EXPR, + make_ssa_name (pointer_sized_int_node, NULL), + base_ssa, NULL_TREE); + gimple_set_location (g, loc); + if (before_p) + gsi_insert_before (&gsi, g, GSI_NEW_STMT); + else + gsi_insert_after (&gsi, g, GSI_NEW_STMT); + tree base_addr = gimple_assign_lhs (g); + + int nargs; + tree fun + = check_func (is_store, is_scalar_access ? size_in_bytes : -1, &nargs); + if (nargs == 1) + g = gimple_build_call (fun, 1, base_addr); + else + { + gcc_assert (nargs == 2); + g = gimple_build_assign_with_ops (NOP_EXPR, + make_ssa_name (pointer_sized_int_node, + NULL), + len, NULL_TREE); + gimple_set_location (g, loc); + gsi_insert_after (&gsi, g, GSI_NEW_STMT); + tree sz_arg = gimple_assign_lhs (g); + g = gimple_build_call (fun, nargs, base_addr, sz_arg); + } + gimple_set_location (g, loc); + gsi_insert_after (&gsi, g, GSI_NEW_STMT); + + if (!before_p) + { + gsi_next (&gsi); + *iter = gsi; + } +} + /* Instrument the memory access instruction BASE. Insert new statements before or after ITER. @@ -1502,111 +1609,199 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location, SSA_NAME, or a non-SSA expression. LOCATION is the source code location. IS_STORE is TRUE for a store, FALSE for a load. BEFORE_P is TRUE for inserting the instrumentation code before - ITER, FALSE for inserting it after ITER. + ITER, FALSE for inserting it after ITER. IS_SCALAR_ACCESS is TRUE + for a scalar memory access and FALSE for memory region access. + NON_ZERO_P is TRUE if memory region is guaranteed to have non-zero + length. ALIGN tells alignment of accessed memory object. + + START_INSTRUMENTED and END_INSTRUMENTED are TRUE if start/end of + memory region have already been instrumented. If BEFORE_P is TRUE, *ITER is arranged to still point to the statement it was pointing to prior to calling this function, otherwise, it points to the statement logically following it. */ static void -build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter, - bool before_p, bool is_store, HOST_WIDE_INT size_in_bytes, - bool slow_p = false) +build_check_stmt (location_t location, tree base, tree len, + HOST_WIDE_INT size_in_bytes, gimple_stmt_iterator *iter, + bool non_zero_len_p, bool before_p, bool is_store, + bool is_scalar_access, unsigned int align = 0, + bool start_instrumented = false, + bool end_instrumented = false) { - gimple_stmt_iterator gsi; - basic_block then_bb, else_bb; - tree t, base_addr, shadow; + gimple_stmt_iterator gsi = *iter; gimple g; - tree shadow_ptr_type = shadow_ptr_types[size_in_bytes == 16 ? 1 : 0]; - tree shadow_type = TREE_TYPE (shadow_ptr_type); tree uintptr_type = build_nonstandard_integer_type (TYPE_PRECISION (TREE_TYPE (base)), 1); - tree base_ssa = base; - HOST_WIDE_INT real_size_in_bytes = size_in_bytes; - tree sz_arg = NULL_TREE; - - if (size_in_bytes == 1) - slow_p = false; - else if ((size_in_bytes & (size_in_bytes - 1)) != 0 - || size_in_bytes > 16 - || slow_p) + + gcc_assert (!(size_in_bytes > 0 && !non_zero_len_p)); + + if (start_instrumented && end_instrumented) { - real_size_in_bytes = 1; - slow_p = true; + if (!before_p) + gsi_next (iter); + return; + } + + if (len) + len = unshare_expr (len); + else + { + gcc_assert (size_in_bytes != -1); + len = build_int_cst (pointer_sized_int_node, size_in_bytes); + } + + if (size_in_bytes > 1) + { + if ((size_in_bytes & (size_in_bytes - 1)) != 0 + || size_in_bytes > 16) + size_in_bytes = -1; + else if (align && align < size_in_bytes * BITS_PER_UNIT) + { + /* On non-strict alignment targets, if + 16-byte access is just 8-byte aligned, + this will result in misaligned shadow + memory 2 byte load, but otherwise can + be handled using one read. */ + if (size_in_bytes != 16 + || STRICT_ALIGNMENT + || align < 8 * BITS_PER_UNIT) + size_in_bytes = -1; + } + } + + HOST_WIDE_INT real_size_in_bytes = size_in_bytes == -1 ? 1 : size_in_bytes; + + tree shadow_ptr_type = shadow_ptr_types[real_size_in_bytes == 16 ? 1 : 0]; + tree shadow_type = TREE_TYPE (shadow_ptr_type); + + base = unshare_expr (base); + + if (use_calls_p ()) + { + gsi = *iter; + build_check_stmt_with_calls (location, base, len, size_in_bytes, iter, + before_p, is_store, is_scalar_access); + return; + } + + ++asan_num_accesses; + + if (!non_zero_len_p) + { + gcc_assert (before_p); + + /* So, the length of the memory area to asan-protect is + non-constant. Let's guard the generated instrumentation code + like: + + if (len != 0) + { + //asan instrumentation code goes here. + } + // falltrough instructions, starting with *ITER. */ + + g = gimple_build_cond (NE_EXPR, + len, + build_int_cst (TREE_TYPE (len), 0), + NULL_TREE, NULL_TREE); + gimple_set_location (g, location); + + basic_block then_bb, fallthrough_bb; + insert_if_then_before_iter (g, iter, /*then_more_likely_p=*/true, + &then_bb, &fallthrough_bb); + /* Note that fallthrough_bb starts with the statement that was + pointed to by ITER. */ + + /* The 'then block' of the 'if (len != 0) condition is where + we'll generate the asan instrumentation code now. */ + gsi = gsi_last_bb (then_bb); + build_check_stmt (location, base, len, size_in_bytes, &gsi, + /*non_zero_len_p*/true, /*before_p*/true, is_store, + is_scalar_access, align, + start_instrumented, end_instrumented); + return; } /* Get an iterator on the point where we can add the condition statement for the instrumentation. */ - gsi = create_cond_insert_point (iter, before_p, + basic_block then_bb, else_bb; + gsi = create_cond_insert_point (&gsi, before_p, /*then_more_likely_p=*/false, /*create_then_fallthru_edge=*/false, &then_bb, &else_bb); - base = unshare_expr (base); - - /* BASE can already be an SSA_NAME; in that case, do not create a - new SSA_NAME for it. */ - if (TREE_CODE (base) != SSA_NAME) - { - g = gimple_build_assign_with_ops (TREE_CODE (base), - make_ssa_name (TREE_TYPE (base), NULL), - base, NULL_TREE); - gimple_set_location (g, location); - gsi_insert_after (&gsi, g, GSI_NEW_STMT); - base_ssa = gimple_assign_lhs (g); - } + tree base_ssa = maybe_create_ssa_name (location, base, &gsi, + /*before_p*/false); g = gimple_build_assign_with_ops (NOP_EXPR, make_ssa_name (uintptr_type, NULL), base_ssa, NULL_TREE); gimple_set_location (g, location); gsi_insert_after (&gsi, g, GSI_NEW_STMT); - base_addr = gimple_assign_lhs (g); - - /* Build - (base_addr >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset (). */ - shadow = build_shadow_mem_access (&gsi, location, base_addr, - shadow_ptr_type); + tree base_addr = gimple_assign_lhs (g); - if (real_size_in_bytes < 8) + tree t = NULL_TREE; + if (real_size_in_bytes >= 8) + { + tree shadow = build_shadow_mem_access (&gsi, location, base_addr, + shadow_ptr_type); + t = shadow; + } + else { - /* Slow path for 1, 2 and 4 byte accesses. - Test (shadow != 0) - & ((base_addr & 7) + (real_size_in_bytes - 1)) >= shadow). */ - gimple_seq seq = NULL; - gimple shadow_test = build_assign (NE_EXPR, shadow, 0); - gimple_seq_add_stmt (&seq, shadow_test); - gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, base_addr, 7)); - gimple_seq_add_stmt (&seq, build_type_cast (shadow_type, - gimple_seq_last (seq))); - if (real_size_in_bytes > 1) - gimple_seq_add_stmt (&seq, - build_assign (PLUS_EXPR, gimple_seq_last (seq), - real_size_in_bytes - 1)); - gimple_seq_add_stmt (&seq, build_assign (GE_EXPR, gimple_seq_last (seq), - shadow)); - gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test, - gimple_seq_last (seq))); - t = gimple_assign_lhs (gimple_seq_last (seq)); - gimple_seq_set_location (seq, location); - gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING); - /* For weird access sizes or misaligned, check first and last byte. */ - if (slow_p) + /* Slow path for 1, 2 and 4 byte accesses. */ + + if (!start_instrumented) + { + /* Test (shadow != 0) + & ((base_addr & 7) + (real_size_in_bytes - 1)) >= shadow). */ + tree shadow = build_shadow_mem_access (&gsi, location, base_addr, + shadow_ptr_type); + gimple shadow_test = build_assign (NE_EXPR, shadow, 0); + gimple_seq seq = NULL; + gimple_seq_add_stmt (&seq, shadow_test); + gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, base_addr, 7)); + gimple_seq_add_stmt (&seq, build_type_cast (shadow_type, + gimple_seq_last (seq))); + if (real_size_in_bytes > 1) + gimple_seq_add_stmt (&seq, + build_assign (PLUS_EXPR, gimple_seq_last (seq), + real_size_in_bytes - 1)); + gimple_seq_add_stmt (&seq, build_assign (GE_EXPR, + gimple_seq_last (seq), + shadow)); + gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test, + gimple_seq_last (seq))); + t = gimple_assign_lhs (gimple_seq_last (seq)); + gimple_seq_set_location (seq, location); + gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING); + } + + /* For non-constant, misaligned or otherwise weird access sizes, + check first and last byte. */ + if (size_in_bytes == -1 && !end_instrumented) { + g = gimple_build_assign_with_ops (MINUS_EXPR, + make_ssa_name (uintptr_type, NULL), + len, + build_int_cst (uintptr_type, 1)); + gimple_set_location (g, location); + gsi_insert_after (&gsi, g, GSI_NEW_STMT); + tree last = gimple_assign_lhs (g); g = gimple_build_assign_with_ops (PLUS_EXPR, make_ssa_name (uintptr_type, NULL), base_addr, - build_int_cst (uintptr_type, - size_in_bytes - 1)); + last); gimple_set_location (g, location); gsi_insert_after (&gsi, g, GSI_NEW_STMT); tree base_end_addr = gimple_assign_lhs (g); - shadow = build_shadow_mem_access (&gsi, location, base_end_addr, - shadow_ptr_type); - seq = NULL; - shadow_test = build_assign (NE_EXPR, shadow, 0); + tree shadow = build_shadow_mem_access (&gsi, location, base_end_addr, + shadow_ptr_type); + gimple shadow_test = build_assign (NE_EXPR, shadow, 0); + gimple_seq seq = NULL; gimple_seq_add_stmt (&seq, shadow_test); gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, base_end_addr, 7)); @@ -1617,16 +1812,14 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter, shadow)); gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test, gimple_seq_last (seq))); - gimple_seq_add_stmt (&seq, build_assign (BIT_IOR_EXPR, t, - gimple_seq_last (seq))); + if (!start_instrumented) + gimple_seq_add_stmt (&seq, build_assign (BIT_IOR_EXPR, t, + gimple_seq_last (seq))); t = gimple_assign_lhs (gimple_seq_last (seq)); gimple_seq_set_location (seq, location); gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING); - sz_arg = build_int_cst (pointer_sized_int_node, size_in_bytes); } } - else - t = shadow; g = gimple_build_cond (NE_EXPR, t, build_int_cst (TREE_TYPE (t), 0), NULL_TREE, NULL_TREE); @@ -1635,8 +1828,23 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter, /* Generate call to the run-time library (e.g. __asan_report_load8). */ gsi = gsi_start_bb (then_bb); - g = gimple_build_call (report_error_func (is_store, size_in_bytes, slow_p), - sz_arg ? 2 : 1, base_addr, sz_arg); + int nargs; + tree fun = report_error_func (is_store, is_scalar_access ? size_in_bytes : -1, + &nargs); + if (nargs == 1) + g = gimple_build_call (fun, 1, base_addr); + else + { + gcc_assert (nargs == 2); + g = gimple_build_assign_with_ops (NOP_EXPR, + make_ssa_name (pointer_sized_int_node, + NULL), + len, NULL_TREE); + gimple_set_location (g, location); + gsi_insert_after (&gsi, g, GSI_NEW_STMT); + tree sz_arg = gimple_assign_lhs (g); + g = gimple_build_call (fun, nargs, base_addr, sz_arg); + } gimple_set_location (g, location); gsi_insert_after (&gsi, g, GSI_NEW_STMT); @@ -1731,31 +1939,10 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t, base = build_fold_addr_expr (t); if (!has_mem_ref_been_instrumented (base, size_in_bytes)) { - bool slow_p = false; - if (size_in_bytes > 1) - { - if ((size_in_bytes & (size_in_bytes - 1)) != 0 - || size_in_bytes > 16) - slow_p = true; - else - { - unsigned int align = get_object_alignment (t); - if (align < size_in_bytes * BITS_PER_UNIT) - { - /* On non-strict alignment targets, if - 16-byte access is just 8-byte aligned, - this will result in misaligned shadow - memory 2 byte load, but otherwise can - be handled using one read. */ - if (size_in_bytes != 16 - || STRICT_ALIGNMENT - || align < 8 * BITS_PER_UNIT) - slow_p = true; - } - } - } - build_check_stmt (location, base, iter, /*before_p=*/true, - is_store, size_in_bytes, slow_p); + unsigned int align = get_object_alignment (t); + build_check_stmt (location, base, NULL_TREE, size_in_bytes, iter, + /*non_zero_len_p*/size_in_bytes > 0, /*before_p=*/true, + is_store, /*is_scalar_access*/true, align); update_mem_ref_hash_table (base, size_in_bytes); update_mem_ref_hash_table (t, size_in_bytes); } @@ -1780,142 +1967,24 @@ instrument_mem_region_access (tree base, tree len, || integer_zerop (len)) return; - gimple_stmt_iterator gsi = *iter; - - basic_block fallthrough_bb = NULL, then_bb = NULL; - /* If the beginning of the memory region has already been instrumented, do not instrument it. */ bool start_instrumented = has_mem_ref_been_instrumented (base, 1); /* If the end of the memory region has already been instrumented, do - not instrument it. */ + not instrument it. */ tree end = asan_mem_ref_get_end (base, len); bool end_instrumented = has_mem_ref_been_instrumented (end, 1); - if (start_instrumented && end_instrumented) - return; + HOST_WIDE_INT size_in_bytes = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1; - if (!is_gimple_constant (len)) - { - /* So, the length of the memory area to asan-protect is - non-constant. Let's guard the generated instrumentation code - like: + build_check_stmt (location, base, len, size_in_bytes, iter, + /*non_zero_len_p*/size_in_bytes > 0, /*before_p*/true, + is_store, /*is_scalar_access*/false, /*align*/0, + start_instrumented, end_instrumented); - if (len != 0) - { - //asan instrumentation code goes here. - } - // falltrough instructions, starting with *ITER. */ - - gimple g = gimple_build_cond (NE_EXPR, - len, - build_int_cst (TREE_TYPE (len), 0), - NULL_TREE, NULL_TREE); - gimple_set_location (g, location); - insert_if_then_before_iter (g, iter, /*then_more_likely_p=*/true, - &then_bb, &fallthrough_bb); - /* Note that fallthrough_bb starts with the statement that was - pointed to by ITER. */ - - /* The 'then block' of the 'if (len != 0) condition is where - we'll generate the asan instrumentation code now. */ - gsi = gsi_last_bb (then_bb); - } - - if (!start_instrumented) - { - /* Instrument the beginning of the memory region to be accessed, - and arrange for the rest of the intrumentation code to be - inserted in the then block *after* the current gsi. */ - build_check_stmt (location, base, &gsi, /*before_p=*/true, is_store, 1); - - if (then_bb) - /* We are in the case where the length of the region is not - constant; so instrumentation code is being generated in the - 'then block' of the 'if (len != 0) condition. Let's arrange - for the subsequent instrumentation statements to go in the - 'then block'. */ - gsi = gsi_last_bb (then_bb); - else - { - *iter = gsi; - /* Don't remember this access as instrumented, if length - is unknown. It might be zero and not being actually - instrumented, so we can't rely on it being instrumented. */ - update_mem_ref_hash_table (base, 1); - } - } - - if (end_instrumented) - return; - - /* We want to instrument the access at the end of the memory region, - which is at (base + len - 1). */ - - /* offset = len - 1; */ - len = unshare_expr (len); - tree offset; - gimple_seq seq = NULL; - if (TREE_CODE (len) == INTEGER_CST) - offset = fold_build2 (MINUS_EXPR, size_type_node, - fold_convert (size_type_node, len), - build_int_cst (size_type_node, 1)); - else - { - gimple g; - tree t; - - if (TREE_CODE (len) != SSA_NAME) - { - t = make_ssa_name (TREE_TYPE (len), NULL); - g = gimple_build_assign_with_ops (TREE_CODE (len), t, len, NULL); - gimple_set_location (g, location); - gimple_seq_add_stmt_without_update (&seq, g); - len = t; - } - if (!useless_type_conversion_p (size_type_node, TREE_TYPE (len))) - { - t = make_ssa_name (size_type_node, NULL); - g = gimple_build_assign_with_ops (NOP_EXPR, t, len, NULL); - gimple_set_location (g, location); - gimple_seq_add_stmt_without_update (&seq, g); - len = t; - } - - t = make_ssa_name (size_type_node, NULL); - g = gimple_build_assign_with_ops (MINUS_EXPR, t, len, - build_int_cst (size_type_node, 1)); - gimple_set_location (g, location); - gimple_seq_add_stmt_without_update (&seq, g); - offset = gimple_assign_lhs (g); - } - - /* _1 = base; */ - base = unshare_expr (base); - gimple region_end = - gimple_build_assign_with_ops (TREE_CODE (base), - make_ssa_name (TREE_TYPE (base), NULL), - base, NULL); - gimple_set_location (region_end, location); - gimple_seq_add_stmt_without_update (&seq, region_end); - - /* _2 = _1 + offset; */ - region_end = - gimple_build_assign_with_ops (POINTER_PLUS_EXPR, - make_ssa_name (TREE_TYPE (base), NULL), - gimple_assign_lhs (region_end), - offset); - gimple_set_location (region_end, location); - gimple_seq_add_stmt_without_update (&seq, region_end); - gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); - - /* instrument access at _2; */ - gsi = gsi_for_stmt (region_end); - build_check_stmt (location, gimple_assign_lhs (region_end), - &gsi, /*before_p=*/false, is_store, 1); - - if (then_bb == NULL) + update_mem_ref_hash_table (base, 1); + if (size_in_bytes != -1) update_mem_ref_hash_table (end, 1); *iter = gsi_for_stmt (gsi_stmt (*iter)); @@ -1957,47 +2026,30 @@ instrument_strlen_call (gimple_stmt_iterator *iter) location_t loc = gimple_location (call); tree str_arg = gimple_call_arg (call, 0); - /* Instrument the access to the first byte of str_arg. i.e: - - _1 = str_arg; instrument (_1); */ tree cptr_type = build_pointer_type (char_type_node); gimple str_arg_ssa = gimple_build_assign_with_ops (NOP_EXPR, make_ssa_name (cptr_type, NULL), str_arg, NULL); gimple_set_location (str_arg_ssa, loc); - gimple_stmt_iterator gsi = *iter; - gsi_insert_before (&gsi, str_arg_ssa, GSI_NEW_STMT); - build_check_stmt (loc, gimple_assign_lhs (str_arg_ssa), &gsi, - /*before_p=*/false, /*is_store=*/false, 1); + gsi_insert_before (iter, str_arg_ssa, GSI_SAME_STMT); - /* If we initially had an instruction like: + build_check_stmt (loc, gimple_assign_lhs (str_arg_ssa), NULL_TREE, 1, iter, + /*non_zero_len_p*/true, /*before_p=*/true, + /*is_store=*/false, /*is_scalar_access*/false, /*align*/0); - int n = strlen (str) - - we now want to instrument the access to str[n], after the - instruction above.*/ - - /* So let's build the access to str[n] that is, access through the - pointer_plus expr: (_1 + len). */ gimple stmt = - gimple_build_assign_with_ops (POINTER_PLUS_EXPR, - make_ssa_name (cptr_type, NULL), - gimple_assign_lhs (str_arg_ssa), - len); + gimple_build_assign_with_ops (PLUS_EXPR, + make_ssa_name (TREE_TYPE (len), NULL), + len, + build_int_cst (TREE_TYPE (len), 1)); gimple_set_location (stmt, loc); - gsi_insert_after (&gsi, stmt, GSI_NEW_STMT); - - build_check_stmt (loc, gimple_assign_lhs (stmt), &gsi, - /*before_p=*/false, /*is_store=*/false, 1); - - /* Ensure that iter points to the statement logically following the - one it was initially pointing to. */ - *iter = gsi; - /* As *ITER has been advanced to point to the next statement, let's - return true to inform transform_statements that it shouldn't - advance *ITER anymore; otherwises it will skip that next - statement, which wouldn't be instrumented. */ + gsi_insert_after (iter, stmt, GSI_NEW_STMT); + + build_check_stmt (loc, gimple_assign_lhs (stmt), len, 1, iter, + /*non_zero_len_p*/true, /*before_p=*/false, + /*is_store=*/false, /*is_scalar_access*/false, /*align*/0); + return true; } @@ -2569,6 +2621,7 @@ asan_instrument (void) { if (shadow_ptr_types[0] == NULL_TREE) asan_init_shadow_ptr_types (); + asan_num_accesses = 0; transform_statements (); return 0; } diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c index 0314d183a83..1007d724e4f 100644 --- a/gcc/auto-inc-dec.c +++ b/gcc/auto-inc-dec.c @@ -969,7 +969,7 @@ find_inc (bool first_try) rtx insn; basic_block bb = BLOCK_FOR_INSN (mem_insn.insn); rtx other_insn; - df_ref *def_rec; + df_ref def; /* Make sure this reg appears only once in this insn. */ if (count_occurrences (PATTERN (mem_insn.insn), mem_insn.reg0, 1) != 1) @@ -1013,9 +1013,8 @@ find_inc (bool first_try) /* Need to assure that none of the operands of the inc instruction are assigned to by the mem insn. */ - for (def_rec = DF_INSN_DEFS (mem_insn.insn); *def_rec; def_rec++) + FOR_EACH_INSN_DEF (def, mem_insn.insn) { - df_ref def = *def_rec; unsigned int regno = DF_REF_REGNO (def); if ((regno == REGNO (inc_insn.reg0)) || (regno == REGNO (inc_insn.reg_res))) @@ -1342,7 +1341,6 @@ merge_in_block (int max_reg, basic_block bb) FOR_BB_INSNS_REVERSE_SAFE (bb, insn, curr) { - unsigned int uid = INSN_UID (insn); bool insn_is_add_or_inc = true; if (!NONDEBUG_INSN_P (insn)) @@ -1418,22 +1416,20 @@ merge_in_block (int max_reg, basic_block bb) /* If the inc insn was merged with a mem, the inc insn is gone and there is noting to update. */ - if (DF_INSN_UID_GET (uid)) + if (df_insn_info *insn_info = DF_INSN_INFO_GET (insn)) { - df_ref *def_rec; - df_ref *use_rec; + df_ref def, use; + /* Need to update next use. */ - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + FOR_EACH_INSN_INFO_DEF (def, insn_info) { - df_ref def = *def_rec; reg_next_use[DF_REF_REGNO (def)] = NULL; reg_next_inc_use[DF_REF_REGNO (def)] = NULL; reg_next_def[DF_REF_REGNO (def)] = insn; } - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) + FOR_EACH_INSN_INFO_USE (use, insn_info) { - df_ref use = *use_rec; reg_next_use[DF_REF_REGNO (use)] = insn; if (insn_is_add_or_inc) reg_next_inc_use[DF_REF_REGNO (use)] = insn; @@ -1442,7 +1438,8 @@ merge_in_block (int max_reg, basic_block bb) } } else if (dump_file) - fprintf (dump_file, "skipping update of deleted insn %d\n", uid); + fprintf (dump_file, "skipping update of deleted insn %d\n", + INSN_UID (insn)); } /* If we were successful, try again. There may have been several diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index b976f21988d..ffa94ebacf6 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,28 @@ +2014-06-16 Marek Polacek <polacek@redhat.com> + + PR c/60439 + * c.opt (Wswitch-bool): Add Var. + +2014-06-12 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/61486 + * c-omp.c (c_omp_split_clauses): Don't crash on firstprivate in + #pragma omp target teams or + #pragma omp {,target }teams distribute simd. + +2014-06-12 Jason Merrill <jason@redhat.com> + + * c.opt (Wabi=, fabi-compat-version): New. + * c-opts.c (c_common_handle_option): Handle -Wabi=. + (c_common_post_options): Handle flag_abi_compat_version default. + Disallow -fabi-compat-version=1. + * c-common.h (abi_version_crosses): New. + +2014-06-11 Jan Hubicka <hubicka@ucw.cz> + + * c-family/c-common.c (handle_section_attribute): Update handling for + section names that are no longer trees. + 2014-06-10 Jakub Jelinek <jakub@redhat.com> PR fortran/60928 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 4f480b04ade..077263e1de5 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -7426,8 +7426,8 @@ handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args, /* The decl may have already been given a section attribute from a previous declaration. Ensure they match. */ - else if (DECL_SECTION_NAME (decl) != NULL_TREE - && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)), + else if (DECL_SECTION_NAME (decl) != NULL + && strcmp (DECL_SECTION_NAME (decl), TREE_STRING_POINTER (TREE_VALUE (args))) != 0) { error ("section of %q+D conflicts with previous declaration", @@ -7442,7 +7442,8 @@ handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args, *no_add_attrs = true; } else - set_decl_section_name (decl, TREE_VALUE (args)); + set_decl_section_name (decl, + TREE_STRING_POINTER (TREE_VALUE (args))); } else { @@ -8035,7 +8036,7 @@ handle_tls_model_attribute (tree *node, tree name, tree args, else error ("tls_model argument must be one of \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\""); - DECL_TLS_MODEL (decl) = kind; + set_decl_tls_model (decl, kind); return NULL_TREE; } diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 83d5dee30e0..6bf4051622d 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -619,6 +619,13 @@ extern const char *constant_string_class_name; /* C++ language option variables. */ +/* Return TRUE if one of {flag_abi_version,flag_abi_compat_version} is + less than N and the other is at least N, for use by -Wabi. */ +#define abi_version_crosses(N) \ + (abi_version_at_least(N) \ + != (flag_abi_compat_version == 0 \ + || flag_abi_compat_version >= (N))) + /* Nonzero means generate separate instantiation control files and juggle them at link time. */ diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c index dd0a45d968a..6a0e41988a7 100644 --- a/gcc/c-family/c-omp.c +++ b/gcc/c-family/c-omp.c @@ -789,8 +789,13 @@ c_omp_split_clauses (location_t loc, enum tree_code code, else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) != 0) { - /* This must be #pragma omp {,target }teams distribute. */ - gcc_assert (code == OMP_DISTRIBUTE); + /* This must be one of + #pragma omp {,target }teams distribute + #pragma omp target teams + #pragma omp {,target }teams distribute simd. */ + gcc_assert (code == OMP_DISTRIBUTE + || code == OMP_TEAMS + || code == OMP_SIMD); s = C_OMP_CLAUSE_SPLIT_TEAMS; } else if ((mask & (OMP_CLAUSE_MASK_1 diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index 29e9a355bee..fbbc80ee94a 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -456,6 +456,16 @@ c_common_handle_option (size_t scode, const char *arg, int value, handle_OPT_d (arg); break; + case OPT_Wabi_: + warn_abi = true; + if (value == 1) + { + warning (0, "%<-Wabi=1%> is not supported, using =2"); + value = 2; + } + flag_abi_compat_version = value; + break; + case OPT_fcanonical_system_headers: cpp_opts->canonical_system_headers = value; break; @@ -910,6 +920,22 @@ c_common_post_options (const char **pfilename) if (flag_declone_ctor_dtor == -1) flag_declone_ctor_dtor = optimize_size; + if (flag_abi_compat_version == 1) + { + warning (0, "%<-fabi-compat-version=1%> is not supported, using =2"); + flag_abi_compat_version = 2; + } + else if (flag_abi_compat_version == -1) + { + /* Generate compatibility aliases for ABI v2 (3.4-4.9) by default. */ + flag_abi_compat_version = (flag_abi_version == 0 ? 2 : 0); + + /* But don't warn about backward compatibility unless explicitly + requested with -Wabi=n. */ + if (flag_abi_version == 0) + warn_abi = false; + } + if (cxx_dialect >= cxx11) { /* If we're allowing C++0x constructs, don't warn about C++98 diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 76e67d78ac7..91f8275ef14 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -256,6 +256,10 @@ Wabi C ObjC C++ ObjC++ LTO Var(warn_abi) Warning Warn about things that will change when compiling with an ABI-compliant compiler +Wabi= +C ObjC C++ ObjC++ LTO Joined RejectNegative UInteger Warning +Warn about things that change between the current -fabi-version and the specified version + Wabi-tag C++ ObjC++ Var(warn_abi_tag) Warning Warn if a subobject has an abi_tag attribute that the complete object type does not have @@ -539,7 +543,7 @@ C ObjC C++ ObjC++ Var(warn_switch_enum) Warning Warn about all enumerated switches missing a specific case Wswitch-bool -C ObjC C++ ObjC++ Warning Init(1) +C ObjC C++ ObjC++ Var(warn_switch_bool) Warning Init(1) Warn about switches with boolean controlling expression Wmissing-format-attribute @@ -845,6 +849,10 @@ d C ObjC C++ ObjC++ Joined ; Documented in common.opt. FIXME - what about -dI, -dD, -dN and -dD? +fabi-compat-version= +C++ ObjC++ Joined RejectNegative UInteger Var(flag_abi_compat_version) Init(-1) +The version of the C++ ABI used for -Wabi warnings and link compatibility aliases + faccess-control C++ ObjC++ Var(flag_access_control) Init(1) Enforce class member access control semantics diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 86372fa3035..cc3e5feda8a 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2014-06-15 Jan Hubicka <hubicka@ucw.cz> + + * c-parser.c (c_parser_omp_threadprivate): Likewise. + * c-decl.c (merge_decls): Likewise. + 2014-06-09 Marek Polacek <polacek@redhat.com> PR c/36446 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 524b0647432..34560308b83 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -2294,7 +2294,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) /* Merge the threadprivate attribute. */ if (TREE_CODE (olddecl) == VAR_DECL && C_DECL_THREADPRIVATE_P (olddecl)) { - DECL_TLS_MODEL (newdecl) = DECL_TLS_MODEL (olddecl); + set_decl_tls_model (newdecl, DECL_TLS_MODEL (olddecl)); C_DECL_THREADPRIVATE_P (newdecl) = 1; } @@ -2305,7 +2305,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) must be done later in decl_attributes since we are called before attributes are assigned. */ if ((DECL_EXTERNAL (olddecl) || TREE_PUBLIC (olddecl) || TREE_STATIC (olddecl)) - && DECL_SECTION_NAME (newdecl) == NULL_TREE + && DECL_SECTION_NAME (newdecl) == NULL && DECL_SECTION_NAME (olddecl)) set_decl_section_name (newdecl, DECL_SECTION_NAME (olddecl)); @@ -6345,7 +6345,7 @@ grokdeclarator (const struct c_declarator *declarator, } if (threadp) - DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); + set_decl_tls_model (decl, decl_default_tls_model (decl)); } if ((storage_class == csc_extern diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index abd636c5436..5fecb488b6a 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -13557,7 +13557,7 @@ c_parser_omp_threadprivate (c_parser *parser) { if (! DECL_THREAD_LOCAL_P (v)) { - DECL_TLS_MODEL (v) = decl_default_tls_model (v); + set_decl_tls_model (v, decl_default_tls_model (v)); /* If rtl has been already set for this var, call make_decl_rtl once again, so that encode_section_info has a chance to look at the new decl flags. */ diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 26dfbe62ddc..10688bcca5c 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -1174,7 +1174,7 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2) && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol)) >= BUILT_IN_ASAN_REPORT_LOAD1 && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol)) - <= BUILT_IN_ASAN_REPORT_STORE16) + <= BUILT_IN_ASAN_STOREN) return dir_none; } } diff --git a/gcc/cgraph.c b/gcc/cgraph.c index c3a3eefe4ec..610bf6717c1 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -2264,7 +2264,7 @@ cgraph_make_node_local_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) node->externally_visible = false; node->forced_by_abi = false; node->local.local = true; - node->set_comdat_group (NULL); + node->set_section (NULL); node->unique_name = (node->resolution == LDPR_PREVAILING_DEF_IRONLY || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP); node->resolution = LDPR_PREVAILING_DEF_IRONLY; diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 882f1e81410..0490e243119 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -37,6 +37,19 @@ enum symtab_type SYMTAB_VARIABLE }; +/* Section names are stored as reference counted strings in GGC safe hashtable + (to make them survive through PCH). */ + +struct GTY(()) section_hash_entry_d +{ + int ref_count; + char *name; /* As long as this datastructure stays in GGC, we can not put + string at the tail of structure of GGC dies in horrible + way */ +}; + +typedef struct section_hash_entry_d section_hash_entry; + /* Base of all entries in the symbol table. The symtab_node is inherited by cgraph and varpol nodes. */ class GTY((desc ("%h.type"), tag ("SYMTAB_SYMBOL"), @@ -93,6 +106,9 @@ public: unsigned forced_by_abi : 1; /* True when the name is known to be unique and thus it does not need mangling. */ unsigned unique_name : 1; + /* Specify whether the section was set by user or by + compiler via -ffunction-sections. */ + unsigned implicit_section : 1; /* True when body and other characteristics have been removed by symtab_remove_unreachable_nodes. */ unsigned body_removed : 1; @@ -144,14 +160,14 @@ public: /* Return comdat group. */ tree get_comdat_group () { - return comdat_group_; + return x_comdat_group; } tree get_comdat_group_id () { - if (comdat_group_ && TREE_CODE (comdat_group_) != IDENTIFIER_NODE) - comdat_group_ = DECL_ASSEMBLER_NAME (comdat_group_); - return comdat_group_; + if (x_comdat_group && TREE_CODE (x_comdat_group) != IDENTIFIER_NODE) + x_comdat_group = DECL_ASSEMBLER_NAME (x_comdat_group); + return x_comdat_group; } /* Set comdat group. */ @@ -159,20 +175,15 @@ public: { gcc_checking_assert (!group || TREE_CODE (group) == IDENTIFIER_NODE || DECL_P (group)); - comdat_group_ = group; + x_comdat_group = group; } - /* Return section. */ - tree get_section () + /* Return section as string. */ + const char * get_section () { - return section_; - } - - /* Set section. */ - void set_section (tree section) - { - gcc_checking_assert (!section || TREE_CODE (section) == STRING_CST); - section_ = section; + if (!x_section) + return NULL; + return x_section->name; } /* Vectors of referring and referenced entities. */ @@ -189,10 +200,14 @@ public: PTR GTY ((skip)) aux; /* Comdat group the symbol is in. Can be private if GGC allowed that. */ - tree comdat_group_; + tree x_comdat_group; /* Section name. Again can be private, if allowed. */ - tree section_; + section_hash_entry *x_section; + + /* Set section for symbol and its aliases. */ + void set_section (const char *section); + void set_section_for_node (const char *section); }; enum availability @@ -692,6 +707,8 @@ public: /* Set if the variable is dynamically initialized, except for function local statics. */ unsigned dynamically_initialized : 1; + + ENUM_BITFIELD(tls_model) tls_model : 3; }; /* Every top level asm statement is put into a asm_node. */ diff --git a/gcc/combine.c b/gcc/combine.c index 72bde7a2694..4e7ef55126e 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -985,7 +985,7 @@ create_log_links (void) { basic_block bb; rtx *next_use, insn; - df_ref *def_vec, *use_vec; + df_ref def, use; next_use = XCNEWVEC (rtx, max_reg_num ()); @@ -1008,9 +1008,8 @@ create_log_links (void) /* Log links are created only once. */ gcc_assert (!LOG_LINKS (insn)); - for (def_vec = DF_INSN_DEFS (insn); *def_vec; def_vec++) + FOR_EACH_INSN_DEF (def, insn) { - df_ref def = *def_vec; int regno = DF_REF_REGNO (def); rtx use_insn; @@ -1061,9 +1060,8 @@ create_log_links (void) next_use[regno] = NULL_RTX; } - for (use_vec = DF_INSN_USES (insn); *use_vec; use_vec++) + FOR_EACH_INSN_USE (use, insn) { - df_ref use = *use_vec; int regno = DF_REF_REGNO (use); /* Do not consider the usage of the stack pointer diff --git a/gcc/common.md b/gcc/common.md new file mode 100644 index 00000000000..23abea154cb --- /dev/null +++ b/gcc/common.md @@ -0,0 +1,95 @@ +;; Common GCC machine description file, shared by all targets. +;; Copyright (C) 2014 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/>. */ + +(define_register_constraint "r" "GENERAL_REGS" + "Matches any general register.") + +(define_memory_constraint "TARGET_MEM_CONSTRAINT" + "Matches any valid memory." + (and (match_code "mem") + (match_test "memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0), + MEM_ADDR_SPACE (op))"))) + +(define_memory_constraint "o" + "Matches an offsettable memory reference." + (and (match_code "mem") + (match_test "offsettable_nonstrict_memref_p (op)"))) + +;; "V" matches TARGET_MEM_CONSTRAINTs that are rejected by "o". +;; This means that it is not a memory constraint in the usual sense, +;; since reloading the address into a base register would make the +;; address offsettable. +(define_constraint "V" + "Matches a non-offsettable memory reference." + (and (match_code "mem") + (match_test "memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0), + MEM_ADDR_SPACE (op))") + (not (match_test "offsettable_nonstrict_memref_p (op)")))) + +;; Like "V", this is not a memory constraint, since reloading the address +;; into a base register would cause it not to match. +(define_constraint "<" + "Matches a pre-dec or post-dec operand." + (and (match_code "mem") + (ior (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC") + (match_test "GET_CODE (XEXP (op, 0)) == POST_DEC")))) + +;; See the comment for "<". +(define_constraint ">" + "Matches a pre-inc or post-inc operand." + (and (match_code "mem") + (ior (match_test "GET_CODE (XEXP (op, 0)) == PRE_INC") + (match_test "GET_CODE (XEXP (op, 0)) == POST_INC")))) + +(define_address_constraint "p" + "Matches a general address." + (match_test "address_operand (op, VOIDmode)")) + +(define_constraint "i" + "Matches a general integer constant." + (and (match_test "CONSTANT_P (op)") + (match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)"))) + +(define_constraint "s" + "Matches a symbolic integer constant." + (and (match_test "CONSTANT_P (op)") + (match_test "!CONST_SCALAR_INT_P (op)") + (match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)"))) + +(define_constraint "n" + "Matches a non-symbolic integer constant." + (and (match_test "CONST_SCALAR_INT_P (op)") + (match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)"))) + +(define_constraint "E" + "Matches a floating-point constant." + (ior (match_test "CONST_DOUBLE_AS_FLOAT_P (op)") + (match_test "GET_CODE (op) == CONST_VECTOR + && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT"))) + +;; There is no longer a distinction between "E" and "F". +(define_constraint "F" + "Matches a floating-point constant." + (ior (match_test "CONST_DOUBLE_AS_FLOAT_P (op)") + (match_test "GET_CODE (op) == CONST_VECTOR + && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT"))) + +(define_constraint "X" + "Matches anything." + (match_test "true")) diff --git a/gcc/common.opt b/gcc/common.opt index 5c3f83404ba..7f0509229d0 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -776,7 +776,7 @@ Driver Undocumented ; Therefore, 0 will not necessarily indicate the same ABI in different ; versions of G++. ; -; 1: The version of the ABI first used in G++ 3.2. +; 1: The version of the ABI first used in G++ 3.2. No longer selectable. ; ; 2: The version of the ABI first used in G++ 3.4 (and current default). ; @@ -808,7 +808,8 @@ Driver Undocumented ; Additional positive integers will be assigned as new versions of ; the ABI become the default version of the ABI. fabi-version= -Common Joined RejectNegative UInteger Var(flag_abi_version) Init(2) +Common Joined RejectNegative UInteger Var(flag_abi_version) Init(0) +The version of the C++ ABI in use faggressive-loop-optimizations Common Report Var(flag_aggressive_loop_optimizations) Optimization Init(1) diff --git a/gcc/compare-elim.c b/gcc/compare-elim.c index a3737990aec..2fbb75bd07f 100644 --- a/gcc/compare-elim.c +++ b/gcc/compare-elim.c @@ -193,14 +193,14 @@ arithmetic_flags_clobber_p (rtx insn) static void find_flags_uses_in_insn (struct comparison *cmp, rtx insn) { - df_ref *use_rec, use; + df_ref use; /* If we've already lost track of uses, don't bother collecting more. */ if (cmp->missing_uses) return; /* Find a USE of the flags register. */ - for (use_rec = DF_INSN_USES (insn); (use = *use_rec) != NULL; use_rec++) + FOR_EACH_INSN_USE (use, insn) if (DF_REF_REGNO (use) == targetm.flags_regnum) { rtx x, *loc; @@ -522,7 +522,7 @@ try_eliminate_compare (struct comparison *cmp) | DF_REF_MUST_CLOBBER | DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT | DF_REF_STRICT_LOW_PART | DF_REF_PRE_POST_MODIFY); - df_ref *def_rec, def; + df_ref def; /* Note that the BB_HEAD is always either a note or a label, but in any case it means that IN_A is defined outside the block. */ @@ -532,7 +532,7 @@ try_eliminate_compare (struct comparison *cmp) continue; /* Find a possible def of IN_A in INSN. */ - for (def_rec = DF_INSN_DEFS (insn); (def = *def_rec) != NULL; def_rec++) + FOR_EACH_INSN_DEF (def, insn) if (DF_REF_REGNO (def) == REGNO (in_a)) break; diff --git a/gcc/config.gcc b/gcc/config.gcc index c3f3ea6646c..93961be7d7a 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -302,7 +302,7 @@ m32c*-*-*) ;; aarch64*-*-*) cpu_type=aarch64 - extra_headers="arm_neon.h" + extra_headers="arm_neon.h arm_acle.h" extra_objs="aarch64-builtins.o aarch-common.o" target_has_targetm_common=yes ;; @@ -1012,7 +1012,7 @@ arm*-*-linux-*) # ARM GNU/Linux with ELF ;; esac tmake_file="${tmake_file} arm/t-arm arm/t-arm-elf arm/t-bpabi arm/t-linux-eabi" - tm_file="$tm_file arm/bpabi.h arm/linux-eabi.h arm/aout.h arm/arm.h" + tm_file="$tm_file arm/bpabi.h arm/linux-eabi.h arm/aout.h vxworks-dummy.h arm/arm.h" # Define multilib configuration for arm-linux-androideabi. case ${target} in *-androideabi) diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c index fe4d39283b0..a94ef52f71a 100644 --- a/gcc/config/aarch64/aarch64-builtins.c +++ b/gcc/config/aarch64/aarch64-builtins.c @@ -411,6 +411,28 @@ static aarch64_simd_builtin_datum aarch64_simd_builtin_data[] = { #include "aarch64-simd-builtins.def" }; +/* There's only 8 CRC32 builtins. Probably not worth their own .def file. */ +#define AARCH64_CRC32_BUILTINS \ + CRC32_BUILTIN (crc32b, QI) \ + CRC32_BUILTIN (crc32h, HI) \ + CRC32_BUILTIN (crc32w, SI) \ + CRC32_BUILTIN (crc32x, DI) \ + CRC32_BUILTIN (crc32cb, QI) \ + CRC32_BUILTIN (crc32ch, HI) \ + CRC32_BUILTIN (crc32cw, SI) \ + CRC32_BUILTIN (crc32cx, DI) + +typedef struct +{ + const char *name; + enum machine_mode mode; + const enum insn_code icode; + unsigned int fcode; +} aarch64_crc_builtin_datum; + +#define CRC32_BUILTIN(N, M) \ + AARCH64_BUILTIN_##N, + #undef VAR1 #define VAR1(T, N, MAP, A) \ AARCH64_SIMD_BUILTIN_##T##_##N##A, @@ -428,9 +450,22 @@ enum aarch64_builtins #include "aarch64-simd-builtins.def" AARCH64_SIMD_BUILTIN_MAX = AARCH64_SIMD_BUILTIN_BASE + ARRAY_SIZE (aarch64_simd_builtin_data), + AARCH64_CRC32_BUILTIN_BASE, + AARCH64_CRC32_BUILTINS + AARCH64_CRC32_BUILTIN_MAX, AARCH64_BUILTIN_MAX }; +#undef CRC32_BUILTIN +#define CRC32_BUILTIN(N, M) \ + {"__builtin_aarch64_"#N, M##mode, CODE_FOR_aarch64_##N, AARCH64_BUILTIN_##N}, + +static aarch64_crc_builtin_datum aarch64_crc_builtin_data[] = { + AARCH64_CRC32_BUILTINS +}; + +#undef CRC32_BUILTIN + static GTY(()) tree aarch64_builtin_decls[AARCH64_BUILTIN_MAX]; #define NUM_DREG_TYPES 6 @@ -802,6 +837,24 @@ aarch64_init_simd_builtins (void) } } +static void +aarch64_init_crc32_builtins () +{ + tree usi_type = aarch64_build_unsigned_type (SImode); + unsigned int i = 0; + + for (i = 0; i < ARRAY_SIZE (aarch64_crc_builtin_data); ++i) + { + aarch64_crc_builtin_datum* d = &aarch64_crc_builtin_data[i]; + tree argtype = aarch64_build_unsigned_type (d->mode); + tree ftype = build_function_type_list (usi_type, usi_type, argtype, NULL_TREE); + tree fndecl = add_builtin_function (d->name, ftype, d->fcode, + BUILT_IN_MD, NULL, NULL_TREE); + + aarch64_builtin_decls[d->fcode] = fndecl; + } +} + void aarch64_init_builtins (void) { @@ -825,6 +878,8 @@ aarch64_init_builtins (void) if (TARGET_SIMD) aarch64_init_simd_builtins (); + if (TARGET_CRC32) + aarch64_init_crc32_builtins (); } tree @@ -1024,6 +1079,41 @@ aarch64_simd_expand_builtin (int fcode, tree exp, rtx target) SIMD_ARG_STOP); } +rtx +aarch64_crc32_expand_builtin (int fcode, tree exp, rtx target) +{ + rtx pat; + aarch64_crc_builtin_datum *d + = &aarch64_crc_builtin_data[fcode - (AARCH64_CRC32_BUILTIN_BASE + 1)]; + enum insn_code icode = d->icode; + tree arg0 = CALL_EXPR_ARG (exp, 0); + tree arg1 = CALL_EXPR_ARG (exp, 1); + rtx op0 = expand_normal (arg0); + rtx op1 = expand_normal (arg1); + enum machine_mode tmode = insn_data[icode].operand[0].mode; + enum machine_mode mode0 = insn_data[icode].operand[1].mode; + enum machine_mode mode1 = insn_data[icode].operand[2].mode; + + if (! target + || GET_MODE (target) != tmode + || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) + target = gen_reg_rtx (tmode); + + gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode) + && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode)); + + if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) + op0 = copy_to_mode_reg (mode0, op0); + if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) + op1 = copy_to_mode_reg (mode1, op1); + + pat = GEN_FCN (icode) (target, op0, op1); + if (! pat) + return 0; + emit_insn (pat); + return target; +} + /* Expand an expression EXP that calls a built-in function, with result going to TARGET if that's convenient. */ rtx @@ -1066,8 +1156,10 @@ aarch64_expand_builtin (tree exp, return target; } - if (fcode >= AARCH64_SIMD_BUILTIN_BASE) + if (fcode >= AARCH64_SIMD_BUILTIN_BASE && fcode <= AARCH64_SIMD_BUILTIN_MAX) return aarch64_simd_expand_builtin (fcode, exp, target); + else if (fcode >= AARCH64_CRC32_BUILTIN_BASE && fcode <= AARCH64_CRC32_BUILTIN_MAX) + return aarch64_crc32_expand_builtin (fcode, exp, target); return NULL_RTX; } diff --git a/gcc/config/aarch64/aarch64-modes.def b/gcc/config/aarch64/aarch64-modes.def index 1d2cc767946..f9c436948a6 100644 --- a/gcc/config/aarch64/aarch64-modes.def +++ b/gcc/config/aarch64/aarch64-modes.def @@ -31,6 +31,7 @@ VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI. */ VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI. */ VECTOR_MODES (FLOAT, 8); /* V2SF. */ VECTOR_MODES (FLOAT, 16); /* V4SF V2DF. */ +VECTOR_MODE (FLOAT, DF, 1); /* V1DF. */ /* Oct Int: 256-bit integer mode needed for 32-byte vector arguments. */ INT_MODE (OI, 32); diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index f2968fff30b..e0c25e7afef 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -1504,6 +1504,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, enum machine_mode mode, CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v); int ncrn, nvrn, nregs; bool allocate_ncrn, allocate_nvrn; + HOST_WIDE_INT size; /* We need to do this once per argument. */ if (pcum->aapcs_arg_processed) @@ -1511,6 +1512,11 @@ aarch64_layout_arg (cumulative_args_t pcum_v, enum machine_mode mode, pcum->aapcs_arg_processed = true; + /* Size in bytes, rounded to the nearest multiple of 8 bytes. */ + size + = AARCH64_ROUND_UP (type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode), + UNITS_PER_WORD); + allocate_ncrn = (type) ? !(FLOAT_TYPE_P (type)) : !FLOAT_MODE_P (mode); allocate_nvrn = aarch64_vfp_is_call_candidate (pcum_v, mode, @@ -1561,9 +1567,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, enum machine_mode mode, } ncrn = pcum->aapcs_ncrn; - nregs = ((type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode)) - + UNITS_PER_WORD - 1) / UNITS_PER_WORD; - + nregs = size / UNITS_PER_WORD; /* C6 - C9. though the sign and zero extension semantics are handled elsewhere. This is the case where the argument fits @@ -1612,13 +1616,12 @@ aarch64_layout_arg (cumulative_args_t pcum_v, enum machine_mode mode, pcum->aapcs_nextncrn = NUM_ARG_REGS; /* The argument is passed on stack; record the needed number of words for - this argument (we can re-use NREGS) and align the total size if - necessary. */ + this argument and align the total size if necessary. */ on_stack: - pcum->aapcs_stack_words = nregs; + pcum->aapcs_stack_words = size / UNITS_PER_WORD; if (aarch64_function_arg_alignment (mode, type) == 16 * BITS_PER_UNIT) pcum->aapcs_stack_size = AARCH64_ROUND_UP (pcum->aapcs_stack_size, - 16 / UNITS_PER_WORD) + 1; + 16 / UNITS_PER_WORD); return; } @@ -7251,7 +7254,8 @@ aarch64_vector_mode_supported_p (enum machine_mode mode) || mode == V16QImode || mode == V2DImode || mode == V2SImode || mode == V4HImode || mode == V8QImode || mode == V2SFmode - || mode == V4SFmode || mode == V2DFmode)) + || mode == V4SFmode || mode == V2DFmode + || mode == V1DFmode)) return true; return false; diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index a191162daf8..b95365a6eca 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -35,6 +35,9 @@ if (TARGET_SIMD) \ builtin_define ("__ARM_NEON"); \ \ + if (TARGET_CRC32) \ + builtin_define ("__ARM_FEATURE_CRC32"); \ + \ switch (aarch64_cmodel) \ { \ case AARCH64_CMODEL_TINY: \ @@ -188,6 +191,9 @@ extern unsigned long aarch64_tune_flags; /* Crypto is an optional extension to AdvSIMD. */ #define TARGET_CRYPTO (TARGET_SIMD && AARCH64_ISA_CRYPTO) +/* CRC instructions that can be enabled through +crc arch extension. */ +#define TARGET_CRC32 (AARCH64_ISA_CRC) + /* Standard register usage. */ /* 31 64-bit general purpose registers R0-R30: diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 662d26aa407..a4d88878d9b 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -68,6 +68,14 @@ (define_c_enum "unspec" [ UNSPEC_CASESI UNSPEC_CLS + UNSPEC_CRC32B + UNSPEC_CRC32CB + UNSPEC_CRC32CH + UNSPEC_CRC32CW + UNSPEC_CRC32CX + UNSPEC_CRC32H + UNSPEC_CRC32W + UNSPEC_CRC32X UNSPEC_FRECPE UNSPEC_FRECPS UNSPEC_FRECPX @@ -2481,6 +2489,23 @@ } ) + +;; CRC32 instructions. +(define_insn "aarch64_<crc_variant>" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "register_operand" "r") + (match_operand:<crc_mode> 2 "register_operand" "r")] + CRC))] + "TARGET_CRC32" + { + if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64) + return "<crc_variant>\\t%w0, %w1, %x2"; + else + return "<crc_variant>\\t%w0, %w1, %w2"; + } + [(set_attr "type" "crc")] +) + (define_insn "*csinc2<mode>_insn" [(set (match_operand:GPI 0 "register_operand" "=r") (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator" diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h new file mode 100644 index 00000000000..2e74696e204 --- /dev/null +++ b/gcc/config/aarch64/arm_acle.h @@ -0,0 +1,90 @@ +/* AArch64 Non-NEON ACLE intrinsics include file. + + Copyright (C) 2014 Free Software Foundation, Inc. + Contributed by ARM Ltd. + + 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 _GCC_ARM_ACLE_H +#define _GCC_ARM_ACLE_H + +#include <stdint.h> +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __ARM_FEATURE_CRC32 +__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +__crc32b (uint32_t __a, uint8_t __b) +{ + return __builtin_aarch64_crc32b (__a, __b); +} + +__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +__crc32cb (uint32_t __a, uint8_t __b) +{ + return __builtin_aarch64_crc32cb (__a, __b); +} + +__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +__crc32ch (uint32_t __a, uint16_t __b) +{ + return __builtin_aarch64_crc32ch (__a, __b); +} + +__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +__crc32cw (uint32_t __a, uint32_t __b) +{ + return __builtin_aarch64_crc32cw (__a, __b); +} + +__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +__crc32cd (uint32_t __a, uint64_t __b) +{ + return __builtin_aarch64_crc32cx (__a, __b); +} + +__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +__crc32h (uint32_t __a, uint16_t __b) +{ + return __builtin_aarch64_crc32h (__a, __b); +} + +__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +__crc32w (uint32_t __a, uint32_t __b) +{ + return __builtin_aarch64_crc32w (__a, __b); +} + +__extension__ static __inline uint32_t __attribute__ ((__always_inline__)) +__crc32d (uint32_t __a, uint64_t __b) +{ + return __builtin_aarch64_crc32x (__a, __b); +} + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h index e1c27f76a60..b1b78f9d4b9 100644 --- a/gcc/config/aarch64/arm_neon.h +++ b/gcc/config/aarch64/arm_neon.h @@ -7164,18 +7164,6 @@ vmlaq_n_f32 (float32x4_t a, float32x4_t b, float32_t c) return result; } -__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -vmlaq_n_f64 (float64x2_t a, float64x2_t b, float64_t c) -{ - float64x2_t result; - float64x2_t t1; - __asm__ ("fmul %1.2d, %3.2d, %4.d[0]; fadd %0.2d, %0.2d, %1.2d" - : "=w"(result), "=w"(t1) - : "0"(a), "w"(b), "w"(c) - : /* No clobbers */); - return result; -} - __extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) vmlaq_n_s16 (int16x8_t a, int16x8_t b, int16_t c) { @@ -7864,18 +7852,6 @@ vmlsq_n_f32 (float32x4_t a, float32x4_t b, float32_t c) return result; } -__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -vmlsq_n_f64 (float64x2_t a, float64x2_t b, float64_t c) -{ - float64x2_t result; - 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), "x"(c) - : /* No clobbers */); - return result; -} - __extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) vmlsq_n_s16 (int16x8_t a, int16x8_t b, int16_t c) { @@ -10854,17 +10830,6 @@ vrsqrtss_f32 (float32_t a, float32_t b) return result; } -__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -vrsrtsq_f64 (float64x2_t a, float64x2_t b) -{ - float64x2_t result; - __asm__ ("frsqrts %0.2d,%1.2d,%2.2d" - : "=w"(result) - : "w"(a), "w"(b) - : /* No clobbers */); - return result; -} - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) vrsubhn_high_s16 (int8x8_t a, int16x8_t b, int16x8_t c) { @@ -14315,13 +14280,6 @@ vcge_f64 (float64x1_t __a, float64x1_t __b) } __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -vcge_p8 (poly8x8_t __a, poly8x8_t __b) -{ - return (uint8x8_t) __builtin_aarch64_cmgev8qi ((int8x8_t) __a, - (int8x8_t) __b); -} - -__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) vcge_s8 (int8x8_t __a, int8x8_t __b) { return (uint8x8_t) __builtin_aarch64_cmgev8qi (__a, __b); @@ -14385,13 +14343,6 @@ vcgeq_f64 (float64x2_t __a, float64x2_t __b) } __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -vcgeq_p8 (poly8x16_t __a, poly8x16_t __b) -{ - return (uint8x16_t) __builtin_aarch64_cmgev16qi ((int8x16_t) __a, - (int8x16_t) __b); -} - -__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) vcgeq_s8 (int8x16_t __a, int8x16_t __b) { return (uint8x16_t) __builtin_aarch64_cmgev16qi (__a, __b); @@ -14485,14 +14436,6 @@ vcgez_f64 (float64x1_t __a) } __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -vcgez_p8 (poly8x8_t __a) -{ - poly8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; - return (uint8x8_t) __builtin_aarch64_cmgev8qi ((int8x8_t) __a, - (int8x8_t) __b); -} - -__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) vcgez_s8 (int8x8_t __a) { int8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -14519,36 +14462,6 @@ vcgez_s64 (int64x1_t __a) return __a >= 0ll ? -1ll : 0ll; } -__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -vcgez_u8 (uint8x8_t __a) -{ - uint8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; - return (uint8x8_t) __builtin_aarch64_cmgeuv8qi ((int8x8_t) __a, - (int8x8_t) __b); -} - -__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -vcgez_u16 (uint16x4_t __a) -{ - uint16x4_t __b = {0, 0, 0, 0}; - return (uint16x4_t) __builtin_aarch64_cmgeuv4hi ((int16x4_t) __a, - (int16x4_t) __b); -} - -__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -vcgez_u32 (uint32x2_t __a) -{ - uint32x2_t __b = {0, 0}; - return (uint32x2_t) __builtin_aarch64_cmgeuv2si ((int32x2_t) __a, - (int32x2_t) __b); -} - -__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -vcgez_u64 (uint64x1_t __a) -{ - return __a >= 0ll ? -1ll : 0ll; -} - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) vcgezq_f32 (float32x4_t __a) { @@ -14564,15 +14477,6 @@ vcgezq_f64 (float64x2_t __a) } __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -vcgezq_p8 (poly8x16_t __a) -{ - poly8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; - return (uint8x16_t) __builtin_aarch64_cmgev16qi ((int8x16_t) __a, - (int8x16_t) __b); -} - -__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) vcgezq_s8 (int8x16_t __a) { int8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, @@ -14601,39 +14505,6 @@ vcgezq_s64 (int64x2_t __a) return (uint64x2_t) __builtin_aarch64_cmgev2di (__a, __b); } -__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -vcgezq_u8 (uint8x16_t __a) -{ - uint8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; - return (uint8x16_t) __builtin_aarch64_cmgeuv16qi ((int8x16_t) __a, - (int8x16_t) __b); -} - -__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -vcgezq_u16 (uint16x8_t __a) -{ - uint16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; - return (uint16x8_t) __builtin_aarch64_cmgeuv8hi ((int16x8_t) __a, - (int16x8_t) __b); -} - -__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -vcgezq_u32 (uint32x4_t __a) -{ - uint32x4_t __b = {0, 0, 0, 0}; - return (uint32x4_t) __builtin_aarch64_cmgeuv4si ((int32x4_t) __a, - (int32x4_t) __b); -} - -__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -vcgezq_u64 (uint64x2_t __a) -{ - uint64x2_t __b = {0, 0}; - return (uint64x2_t) __builtin_aarch64_cmgeuv2di ((int64x2_t) __a, - (int64x2_t) __b); -} - /* vcgez - scalar. */ __extension__ static __inline uint32_t __attribute__ ((__always_inline__)) @@ -14648,12 +14519,6 @@ vcgezd_s64 (int64x1_t __a) return __a >= 0 ? -1ll : 0ll; } -__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -vcgezd_u64 (int64x1_t __a) -{ - return __a >= 0 ? -1ll : 0ll; -} - __extension__ static __inline uint64_t __attribute__ ((__always_inline__)) vcgezd_f64 (float64_t __a) { @@ -14675,13 +14540,6 @@ vcgt_f64 (float64x1_t __a, float64x1_t __b) } __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -vcgt_p8 (poly8x8_t __a, poly8x8_t __b) -{ - return (uint8x8_t) __builtin_aarch64_cmgtv8qi ((int8x8_t) __a, - (int8x8_t) __b); -} - -__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) vcgt_s8 (int8x8_t __a, int8x8_t __b) { return (uint8x8_t) __builtin_aarch64_cmgtv8qi (__a, __b); @@ -14745,13 +14603,6 @@ vcgtq_f64 (float64x2_t __a, float64x2_t __b) } __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -vcgtq_p8 (poly8x16_t __a, poly8x16_t __b) -{ - return (uint8x16_t) __builtin_aarch64_cmgtv16qi ((int8x16_t) __a, - (int8x16_t) __b); -} - -__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) vcgtq_s8 (int8x16_t __a, int8x16_t __b) { return (uint8x16_t) __builtin_aarch64_cmgtv16qi (__a, __b); @@ -14845,14 +14696,6 @@ vcgtz_f64 (float64x1_t __a) } __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -vcgtz_p8 (poly8x8_t __a) -{ - poly8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; - return (uint8x8_t) __builtin_aarch64_cmgtv8qi ((int8x8_t) __a, - (int8x8_t) __b); -} - -__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) vcgtz_s8 (int8x8_t __a) { int8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -14879,36 +14722,6 @@ vcgtz_s64 (int64x1_t __a) return __a > 0ll ? -1ll : 0ll; } -__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -vcgtz_u8 (uint8x8_t __a) -{ - uint8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; - return (uint8x8_t) __builtin_aarch64_cmgtuv8qi ((int8x8_t) __a, - (int8x8_t) __b); -} - -__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -vcgtz_u16 (uint16x4_t __a) -{ - uint16x4_t __b = {0, 0, 0, 0}; - return (uint16x4_t) __builtin_aarch64_cmgtuv4hi ((int16x4_t) __a, - (int16x4_t) __b); -} - -__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -vcgtz_u32 (uint32x2_t __a) -{ - uint32x2_t __b = {0, 0}; - return (uint32x2_t) __builtin_aarch64_cmgtuv2si ((int32x2_t) __a, - (int32x2_t) __b); -} - -__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -vcgtz_u64 (uint64x1_t __a) -{ - return __a > 0ll ? -1ll : 0ll; -} - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) vcgtzq_f32 (float32x4_t __a) { @@ -14924,15 +14737,6 @@ vcgtzq_f64 (float64x2_t __a) } __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -vcgtzq_p8 (poly8x16_t __a) -{ - poly8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; - return (uint8x16_t) __builtin_aarch64_cmgtv16qi ((int8x16_t) __a, - (int8x16_t) __b); -} - -__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) vcgtzq_s8 (int8x16_t __a) { int8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, @@ -14961,39 +14765,6 @@ vcgtzq_s64 (int64x2_t __a) return (uint64x2_t) __builtin_aarch64_cmgtv2di (__a, __b); } -__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -vcgtzq_u8 (uint8x16_t __a) -{ - uint8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; - return (uint8x16_t) __builtin_aarch64_cmgtuv16qi ((int8x16_t) __a, - (int8x16_t) __b); -} - -__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -vcgtzq_u16 (uint16x8_t __a) -{ - uint16x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; - return (uint16x8_t) __builtin_aarch64_cmgtuv8hi ((int16x8_t) __a, - (int16x8_t) __b); -} - -__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -vcgtzq_u32 (uint32x4_t __a) -{ - uint32x4_t __b = {0, 0, 0, 0}; - return (uint32x4_t) __builtin_aarch64_cmgtuv4si ((int32x4_t) __a, - (int32x4_t) __b); -} - -__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -vcgtzq_u64 (uint64x2_t __a) -{ - uint64x2_t __b = {0, 0}; - return (uint64x2_t) __builtin_aarch64_cmgtuv2di ((int64x2_t) __a, - (int64x2_t) __b); -} - /* vcgtz - scalar. */ __extension__ static __inline uint32_t __attribute__ ((__always_inline__)) @@ -15008,12 +14779,6 @@ vcgtzd_s64 (int64x1_t __a) return __a > 0 ? -1ll : 0ll; } -__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -vcgtzd_u64 (int64x1_t __a) -{ - return __a > 0 ? -1ll : 0ll; -} - __extension__ static __inline uint64_t __attribute__ ((__always_inline__)) vcgtzd_f64 (float64_t __a) { @@ -15035,13 +14800,6 @@ vcle_f64 (float64x1_t __a, float64x1_t __b) } __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -vcle_p8 (poly8x8_t __a, poly8x8_t __b) -{ - return (uint8x8_t) __builtin_aarch64_cmgev8qi ((int8x8_t) __b, - (int8x8_t) __a); -} - -__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) vcle_s8 (int8x8_t __a, int8x8_t __b) { return (uint8x8_t) __builtin_aarch64_cmgev8qi (__b, __a); @@ -15105,13 +14863,6 @@ vcleq_f64 (float64x2_t __a, float64x2_t __b) } __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -vcleq_p8 (poly8x16_t __a, poly8x16_t __b) -{ - return (uint8x16_t) __builtin_aarch64_cmgev16qi ((int8x16_t) __b, - (int8x16_t) __a); -} - -__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) vcleq_s8 (int8x16_t __a, int8x16_t __b) { return (uint8x16_t) __builtin_aarch64_cmgev16qi (__b, __a); @@ -15205,14 +14956,6 @@ vclez_f64 (float64x1_t __a) } __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -vclez_p8 (poly8x8_t __a) -{ - poly8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; - return (uint8x8_t) __builtin_aarch64_cmlev8qi ((int8x8_t) __a, - (int8x8_t) __b); -} - -__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) vclez_s8 (int8x8_t __a) { int8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -15239,12 +14982,6 @@ vclez_s64 (int64x1_t __a) return __a <= 0ll ? -1ll : 0ll; } -__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -vclez_u64 (uint64x1_t __a) -{ - return __a <= 0ll ? -1ll : 0ll; -} - __extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) vclezq_f32 (float32x4_t __a) { @@ -15260,15 +14997,6 @@ vclezq_f64 (float64x2_t __a) } __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -vclezq_p8 (poly8x16_t __a) -{ - poly8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; - return (uint8x16_t) __builtin_aarch64_cmlev16qi ((int8x16_t) __a, - (int8x16_t) __b); -} - -__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) vclezq_s8 (int8x16_t __a) { int8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, @@ -15311,12 +15039,6 @@ vclezd_s64 (int64x1_t __a) return __a <= 0 ? -1ll : 0ll; } -__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -vclezd_u64 (int64x1_t __a) -{ - return __a <= 0 ? -1ll : 0ll; -} - __extension__ static __inline uint64_t __attribute__ ((__always_inline__)) vclezd_f64 (float64_t __a) { @@ -15338,13 +15060,6 @@ vclt_f64 (float64x1_t __a, float64x1_t __b) } __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -vclt_p8 (poly8x8_t __a, poly8x8_t __b) -{ - return (uint8x8_t) __builtin_aarch64_cmgtv8qi ((int8x8_t) __b, - (int8x8_t) __a); -} - -__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) vclt_s8 (int8x8_t __a, int8x8_t __b) { return (uint8x8_t) __builtin_aarch64_cmgtv8qi (__b, __a); @@ -15408,13 +15123,6 @@ vcltq_f64 (float64x2_t __a, float64x2_t __b) } __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -vcltq_p8 (poly8x16_t __a, poly8x16_t __b) -{ - return (uint8x16_t) __builtin_aarch64_cmgtv16qi ((int8x16_t) __b, - (int8x16_t) __a); -} - -__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) vcltq_s8 (int8x16_t __a, int8x16_t __b) { return (uint8x16_t) __builtin_aarch64_cmgtv16qi (__b, __a); @@ -15508,14 +15216,6 @@ vcltz_f64 (float64x1_t __a) } __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -vcltz_p8 (poly8x8_t __a) -{ - poly8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; - return (uint8x8_t) __builtin_aarch64_cmltv8qi ((int8x8_t) __a, - (int8x8_t) __b); -} - -__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) vcltz_s8 (int8x8_t __a) { int8x8_t __b = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -15557,15 +15257,6 @@ vcltzq_f64 (float64x2_t __a) } __extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -vcltzq_p8 (poly8x16_t __a) -{ - poly8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0}; - return (uint8x16_t) __builtin_aarch64_cmltv16qi ((int8x16_t) __a, - (int8x16_t) __b); -} - -__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) vcltzq_s8 (int8x16_t __a) { int8x16_t __b = {0, 0, 0, 0, 0, 0, 0, 0, @@ -15608,12 +15299,6 @@ vcltzd_s64 (int64x1_t __a) return __a < 0 ? -1ll : 0ll; } -__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -vcltzd_u64 (int64x1_t __a) -{ - return __a < 0 ? -1ll : 0ll; -} - __extension__ static __inline uint64_t __attribute__ ((__always_inline__)) vcltzd_f64 (float64_t __a) { diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 05c4f7ea543..bf7b6830e00 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -910,6 +910,10 @@ (define_int_iterator FRECP [UNSPEC_FRECPE UNSPEC_FRECPX]) +(define_int_iterator CRC [UNSPEC_CRC32B UNSPEC_CRC32H UNSPEC_CRC32W + UNSPEC_CRC32X UNSPEC_CRC32CB UNSPEC_CRC32CH + UNSPEC_CRC32CW UNSPEC_CRC32CX]) + (define_int_iterator CRYPTO_AES [UNSPEC_AESE UNSPEC_AESD]) (define_int_iterator CRYPTO_AESMC [UNSPEC_AESMC UNSPEC_AESIMC]) @@ -1038,6 +1042,16 @@ (define_int_attr frecp_suffix [(UNSPEC_FRECPE "e") (UNSPEC_FRECPX "x")]) +(define_int_attr crc_variant [(UNSPEC_CRC32B "crc32b") (UNSPEC_CRC32H "crc32h") + (UNSPEC_CRC32W "crc32w") (UNSPEC_CRC32X "crc32x") + (UNSPEC_CRC32CB "crc32cb") (UNSPEC_CRC32CH "crc32ch") + (UNSPEC_CRC32CW "crc32cw") (UNSPEC_CRC32CX "crc32cx")]) + +(define_int_attr crc_mode [(UNSPEC_CRC32B "QI") (UNSPEC_CRC32H "HI") + (UNSPEC_CRC32W "SI") (UNSPEC_CRC32X "DI") + (UNSPEC_CRC32CB "QI") (UNSPEC_CRC32CH "HI") + (UNSPEC_CRC32CW "SI") (UNSPEC_CRC32CX "DI")]) + (define_int_attr aes_op [(UNSPEC_AESE "e") (UNSPEC_AESD "d")]) (define_int_attr aesmc_op [(UNSPEC_AESMC "mc") (UNSPEC_AESIMC "imc")]) diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 77ba003add5..b06a5aafa6d 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -682,7 +682,7 @@ alpha_in_small_data_p (const_tree exp) if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp)) { - const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp)); + const char *section = DECL_SECTION_NAME (exp); if (strcmp (section, ".sdata") == 0 || strcmp (section, ".sbss") == 0) return true; diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index 0aa43c2ce2e..6e558cb76bc 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -6277,7 +6277,7 @@ arc_in_small_data_p (const_tree decl) const char *name; /* Reject anything that isn't in a known small-data section. */ - name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); + name = DECL_SECTION_NAME (decl); if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0) return false; diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index c68d888028f..85d2114826c 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -24762,7 +24762,7 @@ arm_init_builtins (void) if (TARGET_CRC32) arm_init_crc32_builtins (); - if (TARGET_VFP) + if (TARGET_VFP && TARGET_HARD_FLOAT) { tree ftype_set_fpscr = build_function_type_list (void_type_node, unsigned_type_node, NULL); @@ -31454,8 +31454,8 @@ arm_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update) tree new_fenv_var, reload_fenv, restore_fnenv; tree update_call, atomic_feraiseexcept, hold_fnclex; - if (!TARGET_VFP) - return; + if (!TARGET_VFP || !TARGET_HARD_FLOAT) + return default_atomic_assign_expand_fenv (hold, clear, update); /* Generate the equivalent of : unsigned int fenv_var; diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index f58a79bc44b..6ae240e8b6e 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -437,18 +437,6 @@ " ) -(define_insn "*thumb1_adddi3" - [(set (match_operand:DI 0 "register_operand" "=l") - (plus:DI (match_operand:DI 1 "register_operand" "%0") - (match_operand:DI 2 "register_operand" "l"))) - (clobber (reg:CC CC_REGNUM)) - ] - "TARGET_THUMB1" - "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2" - [(set_attr "length" "4") - (set_attr "type" "multiple")] -) - (define_insn_and_split "*arm_adddi3" [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r") (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r") @@ -613,71 +601,6 @@ ] ) -(define_insn_and_split "*thumb1_addsi3" - [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,k,l,l,l") - (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,k,k,0,l,k") - (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,M,O,Pa,Pb,Pc")))] - "TARGET_THUMB1" - "* - static const char * const asms[] = - { - \"add\\t%0, %0, %2\", - \"sub\\t%0, %0, #%n2\", - \"add\\t%0, %1, %2\", - \"add\\t%0, %0, %2\", - \"add\\t%0, %0, %2\", - \"add\\t%0, %1, %2\", - \"add\\t%0, %1, %2\", - \"#\", - \"#\", - \"#\" - }; - if ((which_alternative == 2 || which_alternative == 6) - && CONST_INT_P (operands[2]) - && INTVAL (operands[2]) < 0) - return \"sub\\t%0, %1, #%n2\"; - return asms[which_alternative]; - " - "&& reload_completed && CONST_INT_P (operands[2]) - && ((operands[1] != stack_pointer_rtx - && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255)) - || (operands[1] == stack_pointer_rtx - && INTVAL (operands[2]) > 1020))" - [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))] - { - HOST_WIDE_INT offset = INTVAL (operands[2]); - if (operands[1] == stack_pointer_rtx) - offset -= 1020; - else - { - if (offset > 255) - offset = 255; - else if (offset < -255) - offset = -255; - } - 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 "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 -;; sometimes cause this optimization to be missed. -(define_peephole2 - [(set (match_operand:SI 0 "arm_general_register_operand" "") - (match_operand:SI 1 "const_int_operand" "")) - (set (match_dup 0) - (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))] - "TARGET_THUMB1 - && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024 - && (INTVAL (operands[1]) & 3) == 0" - [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))] - "" -) - (define_insn "addsi3_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV @@ -1090,17 +1013,6 @@ (set_attr "type" "multiple")] ) -(define_insn "*thumb_subdi3" - [(set (match_operand:DI 0 "register_operand" "=l") - (minus:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:DI 2 "register_operand" "l"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_THUMB1" - "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2" - [(set_attr "length" "4") - (set_attr "type" "multiple")] -) - (define_insn_and_split "*subdi_di_zesidi" [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") (minus:DI (match_operand:DI 1 "s_register_operand" "0,r") @@ -1256,17 +1168,6 @@ " ) -(define_insn "thumb1_subsi3_insn" - [(set (match_operand:SI 0 "register_operand" "=l") - (minus:SI (match_operand:SI 1 "register_operand" "l") - (match_operand:SI 2 "reg_or_int_operand" "lPd")))] - "TARGET_THUMB1" - "sub\\t%0, %1, %2" - [(set_attr "length" "2") - (set_attr "conds" "set") - (set_attr "type" "alus_reg")] -) - ; ??? Check Thumb-2 split length (define_insn_and_split "*arm_subsi3_insn" [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r ,r,r,rk,r") @@ -1408,39 +1309,6 @@ (set_attr "predicable_short_it" "yes,yes,no")] ) -; Unfortunately with the Thumb the '&'/'0' trick can fails when operands -; 1 and 2; are the same, because reload will make operand 0 match -; operand 1 without realizing that this conflicts with operand 2. We fix -; this by adding another alternative to match this case, and then `reload' -; it ourselves. This alternative must come first. -(define_insn "*thumb_mulsi3" - [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l") - (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0") - (match_operand:SI 2 "register_operand" "l,l,l")))] - "TARGET_THUMB1 && !arm_arch6" - "* - if (which_alternative < 2) - return \"mov\\t%0, %1\;mul\\t%0, %2\"; - else - return \"mul\\t%0, %2\"; - " - [(set_attr "length" "4,4,2") - (set_attr "type" "muls")] -) - -(define_insn "*thumb_mulsi3_v6" - [(set (match_operand:SI 0 "register_operand" "=l,l,l") - (mult:SI (match_operand:SI 1 "register_operand" "0,l,0") - (match_operand:SI 2 "register_operand" "l,0,0")))] - "TARGET_THUMB1 && arm_arch6" - "@ - mul\\t%0, %2 - mul\\t%0, %1 - mul\\t%0, %1" - [(set_attr "length" "2") - (set_attr "type" "muls")] -) - (define_insn "*mulsi3_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV (mult:SI @@ -2295,16 +2163,6 @@ (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")] ) -(define_insn "*thumb1_andsi3_insn" - [(set (match_operand:SI 0 "register_operand" "=l") - (and:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "register_operand" "l")))] - "TARGET_THUMB1" - "and\\t%0, %2" - [(set_attr "length" "2") - (set_attr "type" "logic_imm") - (set_attr "conds" "set")]) - (define_insn "*andsi3_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV @@ -2493,23 +2351,6 @@ (set_attr "type" "multiple")] ) -(define_split - [(set (match_operand:SI 0 "s_register_operand" "") - (zero_extract:SI (match_operand:SI 1 "s_register_operand" "") - (match_operand:SI 2 "const_int_operand" "") - (match_operand:SI 3 "const_int_operand" ""))) - (clobber (match_operand:SI 4 "s_register_operand" ""))] - "TARGET_THUMB1" - [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))] - "{ - HOST_WIDE_INT temp = INTVAL (operands[2]); - - operands[2] = GEN_INT (32 - temp - INTVAL (operands[3])); - operands[3] = GEN_INT (32 - temp); - }" -) - ;; ??? Use Thumb-2 has bitfield insert/extract instructions. (define_split [(set (match_operand:SI 0 "s_register_operand" "") @@ -2535,22 +2376,6 @@ (define_split [(set (match_operand:SI 0 "s_register_operand" "") - (sign_extract:SI (match_operand:SI 1 "s_register_operand" "") - (match_operand:SI 2 "const_int_operand" "") - (match_operand:SI 3 "const_int_operand" "")))] - "TARGET_THUMB1" - [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))] - "{ - HOST_WIDE_INT temp = INTVAL (operands[2]); - - operands[2] = GEN_INT (32 - temp - INTVAL (operands[3])); - operands[3] = GEN_INT (32 - temp); - }" -) - -(define_split - [(set (match_operand:SI 0 "s_register_operand" "") (match_operator:SI 1 "shiftable_operator" [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "") (match_operand:SI 3 "const_int_operand" "") @@ -2921,17 +2746,6 @@ (set_attr "type" "logic_reg")] ) -(define_insn "thumb1_bicsi3" - [(set (match_operand:SI 0 "register_operand" "=l") - (and:SI (not:SI (match_operand:SI 1 "register_operand" "l")) - (match_operand:SI 2 "register_operand" "0")))] - "TARGET_THUMB1" - "bic\\t%0, %1" - [(set_attr "length" "2") - (set_attr "conds" "set") - (set_attr "type" "logics_reg")] -) - (define_insn "andsi_not_shiftsi_si" [(set (match_operand:SI 0 "s_register_operand" "=r") (and:SI (not:SI (match_operator:SI 4 "shift_operator" @@ -3111,16 +2925,6 @@ (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")] ) -(define_insn "*thumb1_iorsi3_insn" - [(set (match_operand:SI 0 "register_operand" "=l") - (ior:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "register_operand" "l")))] - "TARGET_THUMB1" - "orr\\t%0, %2" - [(set_attr "length" "2") - (set_attr "conds" "set") - (set_attr "type" "logics_reg")]) - (define_peephole2 [(match_scratch:SI 3 "r") (set (match_operand:SI 0 "arm_general_register_operand" "") @@ -3287,17 +3091,6 @@ (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")] ) -(define_insn "*thumb1_xorsi3_insn" - [(set (match_operand:SI 0 "register_operand" "=l") - (xor:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "register_operand" "l")))] - "TARGET_THUMB1" - "eor\\t%0, %2" - [(set_attr "length" "2") - (set_attr "conds" "set") - (set_attr "type" "logics_reg")] -) - (define_insn "*xorsi3_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r") @@ -3903,16 +3696,6 @@ " ) -(define_insn "*thumb1_ashlsi3" - [(set (match_operand:SI 0 "register_operand" "=l,l") - (ashift:SI (match_operand:SI 1 "register_operand" "l,0") - (match_operand:SI 2 "nonmemory_operand" "N,l")))] - "TARGET_THUMB1" - "lsl\\t%0, %1, %2" - [(set_attr "length" "2") - (set_attr "type" "shift_imm,shift_reg") - (set_attr "conds" "set")]) - (define_expand "ashrdi3" [(set (match_operand:DI 0 "s_register_operand" "") (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "") @@ -3984,16 +3767,6 @@ " ) -(define_insn "*thumb1_ashrsi3" - [(set (match_operand:SI 0 "register_operand" "=l,l") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0") - (match_operand:SI 2 "nonmemory_operand" "N,l")))] - "TARGET_THUMB1" - "asr\\t%0, %1, %2" - [(set_attr "length" "2") - (set_attr "type" "shift_imm,shift_reg") - (set_attr "conds" "set")]) - (define_expand "lshrdi3" [(set (match_operand:DI 0 "s_register_operand" "") (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "") @@ -4068,16 +3841,6 @@ " ) -(define_insn "*thumb1_lshrsi3" - [(set (match_operand:SI 0 "register_operand" "=l,l") - (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0") - (match_operand:SI 2 "nonmemory_operand" "N,l")))] - "TARGET_THUMB1" - "lsr\\t%0, %1, %2" - [(set_attr "length" "2") - (set_attr "type" "shift_imm,shift_reg") - (set_attr "conds" "set")]) - (define_expand "rotlsi3" [(set (match_operand:SI 0 "s_register_operand" "") (rotatert:SI (match_operand:SI 1 "s_register_operand" "") @@ -4115,16 +3878,6 @@ " ) -(define_insn "*thumb1_rotrsi3" - [(set (match_operand:SI 0 "register_operand" "=l") - (rotatert:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "register_operand" "l")))] - "TARGET_THUMB1" - "ror\\t%0, %0, %2" - [(set_attr "type" "shift_reg") - (set_attr "length" "2")] -) - (define_insn "*arm_shiftsi3" [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r") (match_operator:SI 3 "shift_operator" @@ -4592,16 +4345,6 @@ (set_attr "type" "multiple")] ) -(define_insn "*thumb1_negdi2" - [(set (match_operand:DI 0 "register_operand" "=&l") - (neg:DI (match_operand:DI 1 "register_operand" "l"))) - (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 "type" "multiple")] -) - (define_expand "negsi2" [(set (match_operand:SI 0 "s_register_operand" "") (neg:SI (match_operand:SI 1 "s_register_operand" "")))] @@ -4621,15 +4364,6 @@ (set_attr "type" "alu_reg")] ) -(define_insn "*thumb1_negsi2" - [(set (match_operand:SI 0 "register_operand" "=l") - (neg:SI (match_operand:SI 1 "register_operand" "l")))] - "TARGET_THUMB1" - "neg\\t%0, %1" - [(set_attr "length" "2") - (set_attr "type" "alu_imm")] -) - (define_expand "negsf2" [(set (match_operand:SF 0 "s_register_operand" "") (neg:SF (match_operand:SF 1 "s_register_operand" "")))] @@ -4843,21 +4577,6 @@ (set_attr "type" "multiple")] ) -(define_insn_and_split "*thumb1_abssi2" - [(set (match_operand:SI 0 "s_register_operand" "=l") - (abs:SI (match_operand:SI 1 "s_register_operand" "l"))) - (clobber (match_scratch:SI 2 "=&l"))] - "TARGET_THUMB1" - "#" - "TARGET_THUMB1 && reload_completed" - [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31))) - (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 "type" "multiple")] -) - (define_insn_and_split "*arm_neg_abssi2" [(set (match_operand:SI 0 "s_register_operand" "=r,&r") (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))) @@ -4915,21 +4634,6 @@ (set_attr "type" "multiple")] ) -(define_insn_and_split "*thumb1_neg_abssi2" - [(set (match_operand:SI 0 "s_register_operand" "=l") - (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "l")))) - (clobber (match_scratch:SI 2 "=&l"))] - "TARGET_THUMB1" - "#" - "TARGET_THUMB1 && reload_completed" - [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31))) - (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 "type" "multiple")] -) - (define_expand "abssf2" [(set (match_operand:SF 0 "s_register_operand" "") (abs:SF (match_operand:SF 1 "s_register_operand" "")))] @@ -4999,15 +4703,6 @@ (set_attr "type" "mvn_reg")] ) -(define_insn "*thumb1_one_cmplsi2" - [(set (match_operand:SI 0 "register_operand" "=l") - (not:SI (match_operand:SI 1 "register_operand" "l")))] - "TARGET_THUMB1" - "mvn\\t%0, %1" - [(set_attr "length" "2") - (set_attr "type" "mvn_reg")] -) - (define_insn "*notsi_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r")) @@ -5251,49 +4946,6 @@ operands[2] = gen_lowpart (SImode, operands[1]); }) -(define_insn "*thumb1_zero_extendhisi2" - [(set (match_operand:SI 0 "register_operand" "=l,l") - (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))] - "TARGET_THUMB1" -{ - rtx mem; - - if (which_alternative == 0 && arm_arch6) - return "uxth\t%0, %1"; - if (which_alternative == 0) - return "#"; - - mem = XEXP (operands[1], 0); - - if (GET_CODE (mem) == CONST) - mem = XEXP (mem, 0); - - if (GET_CODE (mem) == PLUS) - { - rtx a = XEXP (mem, 0); - - /* This can happen due to bugs in reload. */ - if (REG_P (a) && REGNO (a) == SP_REGNUM) - { - rtx ops[2]; - ops[0] = operands[0]; - ops[1] = a; - - output_asm_insn ("mov\t%0, %1", ops); - - XEXP (mem, 0) = operands[0]; - } - } - - return "ldrh\t%0, %1"; -} - [(set_attr_alternative "length" - [(if_then_else (eq_attr "is_arch6" "yes") - (const_int 2) (const_int 4)) - (const_int 4)]) - (set_attr "type" "extend,load_byte")] -) - (define_insn "*arm_zero_extendhisi2" [(set (match_operand:SI 0 "s_register_operand" "=r,r") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] @@ -5364,29 +5016,6 @@ } }) -(define_insn "*thumb1_zero_extendqisi2" - [(set (match_operand:SI 0 "register_operand" "=l,l") - (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))] - "TARGET_THUMB1 && !arm_arch6" - "@ - # - ldrb\\t%0, %1" - [(set_attr "length" "4,2") - (set_attr "type" "alu_shift_reg,load_byte") - (set_attr "pool_range" "*,32")] -) - -(define_insn "*thumb1_zero_extendqisi2_v6" - [(set (match_operand:SI 0 "register_operand" "=l,l") - (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))] - "TARGET_THUMB1 && arm_arch6" - "@ - uxtb\\t%0, %1 - ldrb\\t%0, %1" - [(set_attr "length" "2") - (set_attr "type" "extend,load_byte")] -) - (define_insn "*arm_zero_extendqisi2" [(set (match_operand:SI 0 "s_register_operand" "=r,r") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] @@ -5512,80 +5141,6 @@ operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0); }) -;; We used to have an early-clobber on the scratch register here. -;; However, there's a bug somewhere in reload which means that this -;; can be partially ignored during spill allocation if the memory -;; address also needs reloading; this causes us to die later on when -;; we try to verify the operands. Fortunately, we don't really need -;; the early-clobber: we can always use operand 0 if operand 2 -;; overlaps the address. -(define_insn "thumb1_extendhisi2" - [(set (match_operand:SI 0 "register_operand" "=l,l") - (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m"))) - (clobber (match_scratch:SI 2 "=X,l"))] - "TARGET_THUMB1" - "* - { - rtx ops[4]; - rtx mem; - - if (which_alternative == 0 && !arm_arch6) - return \"#\"; - if (which_alternative == 0) - return \"sxth\\t%0, %1\"; - - mem = XEXP (operands[1], 0); - - /* This code used to try to use 'V', and fix the address only if it was - offsettable, but this fails for e.g. REG+48 because 48 is outside the - range of QImode offsets, and offsettable_address_p does a QImode - address check. */ - - if (GET_CODE (mem) == CONST) - mem = XEXP (mem, 0); - - if (GET_CODE (mem) == LABEL_REF) - return \"ldr\\t%0, %1\"; - - if (GET_CODE (mem) == PLUS) - { - rtx a = XEXP (mem, 0); - rtx b = XEXP (mem, 1); - - if (GET_CODE (a) == LABEL_REF - && CONST_INT_P (b)) - return \"ldr\\t%0, %1\"; - - if (REG_P (b)) - return \"ldrsh\\t%0, %1\"; - - ops[1] = a; - ops[2] = b; - } - else - { - ops[1] = mem; - ops[2] = const0_rtx; - } - - gcc_assert (REG_P (ops[1])); - - ops[0] = operands[0]; - if (reg_mentioned_p (operands[2], ops[1])) - ops[3] = ops[0]; - else - ops[3] = operands[2]; - output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops); - return \"\"; - }" - [(set_attr_alternative "length" - [(if_then_else (eq_attr "is_arch6" "yes") - (const_int 2) (const_int 4)) - (const_int 4)]) - (set_attr "type" "extend,load_byte") - (set_attr "pool_range" "*,1018")] -) - ;; This pattern will only be used when ldsh is not available (define_expand "extendhisi2_mem" [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" ""))) @@ -5774,105 +5329,6 @@ (set_attr "predicable_short_it" "no")] ) -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (sign_extend:SI (match_operand:QI 1 "memory_operand" "")))] - "TARGET_THUMB1 && reload_completed" - [(set (match_dup 0) (match_dup 2)) - (set (match_dup 0) (sign_extend:SI (match_dup 3)))] -{ - rtx addr = XEXP (operands[1], 0); - - if (GET_CODE (addr) == CONST) - addr = XEXP (addr, 0); - - if (GET_CODE (addr) == PLUS - && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1))) - /* No split necessary. */ - FAIL; - - if (GET_CODE (addr) == PLUS - && !REG_P (XEXP (addr, 0)) && !REG_P (XEXP (addr, 1))) - FAIL; - - if (reg_overlap_mentioned_p (operands[0], addr)) - { - rtx t = gen_lowpart (QImode, operands[0]); - emit_move_insn (t, operands[1]); - emit_insn (gen_thumb1_extendqisi2 (operands[0], t)); - DONE; - } - - if (REG_P (addr)) - { - addr = gen_rtx_PLUS (Pmode, addr, operands[0]); - operands[2] = const0_rtx; - } - else if (GET_CODE (addr) != PLUS) - FAIL; - else if (REG_P (XEXP (addr, 0))) - { - operands[2] = XEXP (addr, 1); - addr = gen_rtx_PLUS (Pmode, XEXP (addr, 0), operands[0]); - } - else - { - operands[2] = XEXP (addr, 0); - addr = gen_rtx_PLUS (Pmode, XEXP (addr, 1), operands[0]); - } - - operands[3] = change_address (operands[1], QImode, addr); -}) - -(define_peephole2 - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_dup 0) (match_operand 1 "const_int_operand"))) - (set (match_operand:SI 2 "register_operand" "") (const_int 0)) - (set (match_operand:SI 3 "register_operand" "") - (sign_extend:SI (match_operand:QI 4 "memory_operand" "")))] - "TARGET_THUMB1 - && GET_CODE (XEXP (operands[4], 0)) == PLUS - && rtx_equal_p (operands[0], XEXP (XEXP (operands[4], 0), 0)) - && rtx_equal_p (operands[2], XEXP (XEXP (operands[4], 0), 1)) - && (peep2_reg_dead_p (3, operands[0]) - || rtx_equal_p (operands[0], operands[3])) - && (peep2_reg_dead_p (3, operands[2]) - || rtx_equal_p (operands[2], operands[3]))" - [(set (match_dup 2) (match_dup 1)) - (set (match_dup 3) (sign_extend:SI (match_dup 4)))] -{ - rtx addr = gen_rtx_PLUS (Pmode, operands[0], operands[2]); - operands[4] = change_address (operands[4], QImode, addr); -}) - -(define_insn "thumb1_extendqisi2" - [(set (match_operand:SI 0 "register_operand" "=l,l,l") - (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))] - "TARGET_THUMB1" -{ - rtx addr; - - if (which_alternative == 0 && arm_arch6) - return "sxtb\\t%0, %1"; - if (which_alternative == 0) - return "#"; - - addr = XEXP (operands[1], 0); - if (GET_CODE (addr) == PLUS - && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1))) - return "ldrsb\\t%0, %1"; - - return "#"; -} - [(set_attr_alternative "length" - [(if_then_else (eq_attr "is_arch6" "yes") - (const_int 2) (const_int 4)) - (const_int 2) - (if_then_else (eq_attr "is_arch6" "yes") - (const_int 4) (const_int 6))]) - (set_attr "type" "extend,load_byte,load_byte")] -) - (define_expand "extendsfdf2" [(set (match_operand:DF 0 "s_register_operand" "") (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))] @@ -6087,52 +5543,6 @@ " ) -;;; ??? This should have alternatives for constants. -;;; ??? This was originally identical to the movdf_insn pattern. -;;; ??? The 'i' constraint looks funny, but it should always be replaced by -;;; thumb_reorg with a memory reference. -(define_insn "*thumb1_movdi_insn" - [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r") - (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))] - "TARGET_THUMB1 - && ( register_operand (operands[0], DImode) - || register_operand (operands[1], DImode))" - "* - { - switch (which_alternative) - { - default: - case 0: - if (REGNO (operands[1]) == REGNO (operands[0]) + 1) - return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\"; - return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\"; - case 1: - return \"mov\\t%Q0, %1\;mov\\t%R0, #0\"; - case 2: - operands[1] = GEN_INT (- INTVAL (operands[1])); - return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\"; - case 3: - return \"ldmia\\t%1, {%0, %H0}\"; - case 4: - return \"stmia\\t%0, {%1, %H1}\"; - case 5: - return thumb_load_double_from_address (operands); - case 6: - operands[2] = gen_rtx_MEM (SImode, - plus_constant (Pmode, XEXP (operands[0], 0), 4)); - output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands); - return \"\"; - case 7: - if (REGNO (operands[1]) == REGNO (operands[0]) + 1) - return \"mov\\t%0, %1\;mov\\t%H0, %H1\"; - return \"mov\\t%H0, %H1\;mov\\t%0, %1\"; - } - }" - [(set_attr "length" "4,4,6,2,2,6,4,4") - (set_attr "type" "multiple,multiple,multiple,load2,store2,load2,store2,multiple") - (set_attr "pool_range" "*,*,*,*,*,1018,*,*")] -) - (define_expand "movsi" [(set (match_operand:SI 0 "general_operand" "") (match_operand:SI 1 "general_operand" ""))] @@ -6324,81 +5734,6 @@ DONE; }) -(define_insn "*thumb1_movsi_insn" - [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*l*h*k") - (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*l*h*k"))] - "TARGET_THUMB1 - && ( register_operand (operands[0], SImode) - || register_operand (operands[1], SImode))" - "@ - mov %0, %1 - mov %0, %1 - # - # - ldmia\\t%1, {%0} - stmia\\t%0, {%1} - ldr\\t%0, %1 - str\\t%1, %0 - mov\\t%0, %1" - [(set_attr "length" "2,2,4,4,2,2,2,2,2") - (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")]) - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "const_int_operand" ""))] - "TARGET_THUMB1 && satisfies_constraint_J (operands[1])" - [(set (match_dup 2) (match_dup 1)) - (set (match_dup 0) (neg:SI (match_dup 2)))] - " - { - operands[1] = GEN_INT (- INTVAL (operands[1])); - operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0]; - }" -) - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "const_int_operand" ""))] - "TARGET_THUMB1 && satisfies_constraint_K (operands[1])" - [(set (match_dup 2) (match_dup 1)) - (set (match_dup 0) (ashift:SI (match_dup 2) (match_dup 3)))] - " - { - unsigned HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffffffffu; - unsigned HOST_WIDE_INT mask = 0xff; - int i; - - for (i = 0; i < 25; i++) - if ((val & (mask << i)) == val) - break; - - /* Don't split if the shift is zero. */ - if (i == 0) - FAIL; - - operands[1] = GEN_INT (val >> i); - operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0]; - operands[3] = GEN_INT (i); - }" -) - -;; For thumb1 split imm move [256-510] into mov [1-255] and add #255 -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "const_int_operand" ""))] - "TARGET_THUMB1 && satisfies_constraint_Pe (operands[1])" - [(set (match_dup 2) (match_dup 1)) - (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 3)))] - " - { - operands[1] = GEN_INT (INTVAL (operands[1]) - 255); - operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0]; - operands[3] = GEN_INT (255); - }" -) - ;; When generating pic, we need to load the symbol offset into a register. ;; So that the optimizer does not confuse this with a normal symbol load ;; we use an unspec. The offset will be loaded from a constant pool entry, @@ -6903,44 +6238,6 @@ " ) -(define_insn "*thumb1_movhi_insn" - [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l") - (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))] - "TARGET_THUMB1 - && ( register_operand (operands[0], HImode) - || register_operand (operands[1], HImode))" - "* - switch (which_alternative) - { - case 0: return \"add %0, %1, #0\"; - case 2: return \"strh %1, %0\"; - case 3: return \"mov %0, %1\"; - case 4: return \"mov %0, %1\"; - case 5: return \"mov %0, %1\"; - default: gcc_unreachable (); - case 1: - /* The stack pointer can end up being taken as an index register. - Catch this case here and deal with it. */ - if (GET_CODE (XEXP (operands[1], 0)) == PLUS - && REG_P (XEXP (XEXP (operands[1], 0), 0)) - && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM) - { - rtx ops[2]; - ops[0] = operands[0]; - ops[1] = XEXP (XEXP (operands[1], 0), 0); - - output_asm_insn (\"mov %0, %1\", ops); - - XEXP (XEXP (operands[1], 0), 0) = operands[0]; - - } - return \"ldrh %0, %1\"; - }" - [(set_attr "length" "2,4,2,2,2,2") - (set_attr "type" "alus_imm,load1,store1,mov_reg,mov_reg,mov_imm") - (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")]) - - (define_expand "movhi_bytes" [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" ""))) (set (match_dup 3) @@ -7027,23 +6324,6 @@ [(set_attr "predicable" "yes") (set_attr "type" "mov_imm,mov_reg,mvn_imm")] ) - -(define_expand "thumb_movhi_clobber" - [(set (match_operand:HI 0 "memory_operand" "") - (match_operand:HI 1 "register_operand" "")) - (clobber (match_operand:DI 2 "register_operand" ""))] - "TARGET_THUMB1" - " - if (strict_memory_address_p (HImode, XEXP (operands[0], 0)) - && REGNO (operands[1]) <= LAST_LO_REGNUM) - { - emit_insn (gen_movhi (operands[0], operands[1])); - DONE; - } - /* XXX Fixme, need to handle other cases here as well. */ - gcc_unreachable (); - " -) ;; We use a DImode scratch because we may occasionally need an additional ;; temporary if the address isn't offsettable -- push_reload doesn't seem @@ -7171,24 +6451,6 @@ (set_attr "length" "2,4,4,2,4,2,2,4,4")] ) -(define_insn "*thumb1_movqi_insn" - [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l") - (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))] - "TARGET_THUMB1 - && ( register_operand (operands[0], QImode) - || register_operand (operands[1], QImode))" - "@ - add\\t%0, %1, #0 - ldrb\\t%0, %1 - strb\\t%1, %0 - mov\\t%0, %1 - mov\\t%0, %1 - mov\\t%0, %1" - [(set_attr "length" "2") - (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")]) - ;; HFmode moves (define_expand "movhf" [(set (match_operand:HF 0 "general_operand" "") @@ -7255,40 +6517,6 @@ (set_attr "predicable" "yes")] ) -(define_insn "*thumb1_movhf" - [(set (match_operand:HF 0 "nonimmediate_operand" "=l,l,m,*r,*h") - (match_operand:HF 1 "general_operand" "l,mF,l,*h,*r"))] - "TARGET_THUMB1 - && ( s_register_operand (operands[0], HFmode) - || s_register_operand (operands[1], HFmode))" - "* - switch (which_alternative) - { - case 1: - { - rtx addr; - gcc_assert (MEM_P (operands[1])); - addr = XEXP (operands[1], 0); - if (GET_CODE (addr) == LABEL_REF - || (GET_CODE (addr) == CONST - && GET_CODE (XEXP (addr, 0)) == PLUS - && GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF - && CONST_INT_P (XEXP (XEXP (addr, 0), 1)))) - { - /* Constant pool entry. */ - return \"ldr\\t%0, %1\"; - } - return \"ldrh\\t%0, %1\"; - } - case 2: return \"strh\\t%1, %0\"; - default: return \"mov\\t%0, %1\"; - } - " - [(set_attr "length" "2") - (set_attr "type" "mov_reg,load1,store1,mov_reg,mov_reg") - (set_attr "pool_range" "*,1018,*,*,*") - (set_attr "conds" "clob,nocond,nocond,nocond,nocond")]) - (define_expand "movsf" [(set (match_operand:SF 0 "general_operand" "") (match_operand:SF 1 "general_operand" ""))] @@ -7347,27 +6575,6 @@ (set_attr "thumb2_neg_pool_range" "*,0,*")] ) -;;; ??? This should have alternatives for constants. -(define_insn "*thumb1_movsf_insn" - [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h") - (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))] - "TARGET_THUMB1 - && ( register_operand (operands[0], SFmode) - || register_operand (operands[1], SFmode))" - "@ - add\\t%0, %1, #0 - ldmia\\t%1, {%0} - stmia\\t%0, {%1} - ldr\\t%0, %1 - str\\t%1, %0 - mov\\t%0, %1 - mov\\t%0, %1" - [(set_attr "length" "2") - (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")] -) - (define_expand "movdf" [(set (match_operand:DF 0 "general_operand" "") (match_operand:DF 1 "general_operand" ""))] @@ -7457,47 +6664,6 @@ (set_attr "arm_neg_pool_range" "*,*,*,1004,*") (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")] ) - -;;; ??? This should have alternatives for constants. -;;; ??? This was originally identical to the movdi_insn pattern. -;;; ??? The 'F' constraint looks funny, but it should always be replaced by -;;; thumb_reorg with a memory reference. -(define_insn "*thumb_movdf_insn" - [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r") - (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))] - "TARGET_THUMB1 - && ( register_operand (operands[0], DFmode) - || register_operand (operands[1], DFmode))" - "* - switch (which_alternative) - { - default: - case 0: - if (REGNO (operands[1]) == REGNO (operands[0]) + 1) - return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\"; - return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\"; - case 1: - return \"ldmia\\t%1, {%0, %H0}\"; - case 2: - return \"stmia\\t%0, {%1, %H1}\"; - case 3: - return thumb_load_double_from_address (operands); - case 4: - operands[2] = gen_rtx_MEM (SImode, - plus_constant (Pmode, - XEXP (operands[0], 0), 4)); - output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands); - return \"\"; - case 5: - if (REGNO (operands[1]) == REGNO (operands[0]) + 1) - return \"mov\\t%0, %1\;mov\\t%H0, %H1\"; - return \"mov\\t%H0, %H1\;mov\\t%0, %1\"; - } - " - [(set_attr "length" "4,2,2,6,4,4") - (set_attr "type" "multiple,load2,store2,load2,store2,multiple") - (set_attr "pool_range" "*,*,*,1018,*,*")] -) ;; load- and store-multiple insns @@ -7591,50 +6757,6 @@ } " ) - -;; Thumb block-move insns - -(define_insn "movmem12b" - [(set (mem:SI (match_operand:SI 2 "register_operand" "0")) - (mem:SI (match_operand:SI 3 "register_operand" "1"))) - (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) - (mem:SI (plus:SI (match_dup 3) (const_int 4)))) - (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) - (mem:SI (plus:SI (match_dup 3) (const_int 8)))) - (set (match_operand:SI 0 "register_operand" "=l") - (plus:SI (match_dup 2) (const_int 12))) - (set (match_operand:SI 1 "register_operand" "=l") - (plus:SI (match_dup 3) (const_int 12))) - (clobber (match_scratch:SI 4 "=&l")) - (clobber (match_scratch:SI 5 "=&l")) - (clobber (match_scratch:SI 6 "=&l"))] - "TARGET_THUMB1" - "* return thumb_output_move_mem_multiple (3, operands);" - [(set_attr "length" "4") - ; This isn't entirely accurate... It loads as well, but in terms of - ; scheduling the following insn it is better to consider it as a store - (set_attr "type" "store3")] -) - -(define_insn "movmem8b" - [(set (mem:SI (match_operand:SI 2 "register_operand" "0")) - (mem:SI (match_operand:SI 3 "register_operand" "1"))) - (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) - (mem:SI (plus:SI (match_dup 3) (const_int 4)))) - (set (match_operand:SI 0 "register_operand" "=l") - (plus:SI (match_dup 2) (const_int 8))) - (set (match_operand:SI 1 "register_operand" "=l") - (plus:SI (match_dup 3) (const_int 8))) - (clobber (match_scratch:SI 4 "=&l")) - (clobber (match_scratch:SI 5 "=&l"))] - "TARGET_THUMB1" - "* return thumb_output_move_mem_multiple (2, operands);" - [(set_attr "length" "4") - ; This isn't entirely accurate... It loads as well, but in terms of - ; scheduling the following insn it is better to consider it as a store - (set_attr "type" "store2")] -) - ;; Compare & branch insns @@ -7681,30 +6803,6 @@ operands[2] = force_reg (SImode, operands[2]); ") -;; A pattern to recognize a special situation and optimize for it. -;; On the thumb, zero-extension from memory is preferrable to sign-extension -;; due to the available addressing modes. Hence, convert a signed comparison -;; with zero into an unsigned comparison with 127 if possible. -(define_expand "cbranchqi4" - [(set (pc) (if_then_else - (match_operator 0 "lt_ge_comparison_operator" - [(match_operand:QI 1 "memory_operand" "") - (match_operand:QI 2 "const0_operand" "")]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "TARGET_THUMB1" -{ - rtx xops[4]; - xops[1] = gen_reg_rtx (SImode); - emit_insn (gen_zero_extendqisi2 (xops[1], operands[1])); - xops[2] = GEN_INT (127); - xops[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]) == GE ? LEU : GTU, - VOIDmode, xops[1], xops[2]); - xops[3] = operands[3]; - emit_insn (gen_cbranchsi4 (xops[0], xops[1], xops[2], xops[3])); - DONE; -}) - (define_expand "cbranchsf4" [(set (pc) (if_then_else (match_operator 0 "expandable_comparison_operator" @@ -7746,524 +6844,6 @@ }" ) -(define_insn "cbranchsi4_insn" - [(set (pc) (if_then_else - (match_operator 0 "arm_comparison_operator" - [(match_operand:SI 1 "s_register_operand" "l,l*h") - (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "TARGET_THUMB1" -{ - rtx t = cfun->machine->thumb1_cc_insn; - if (t != NULL_RTX) - { - if (!rtx_equal_p (cfun->machine->thumb1_cc_op0, operands[1]) - || !rtx_equal_p (cfun->machine->thumb1_cc_op1, operands[2])) - t = NULL_RTX; - if (cfun->machine->thumb1_cc_mode == CC_NOOVmode) - { - if (!noov_comparison_operator (operands[0], VOIDmode)) - t = NULL_RTX; - } - else if (cfun->machine->thumb1_cc_mode != CCmode) - t = NULL_RTX; - } - if (t == NULL_RTX) - { - output_asm_insn ("cmp\t%1, %2", operands); - cfun->machine->thumb1_cc_insn = insn; - cfun->machine->thumb1_cc_op0 = operands[1]; - cfun->machine->thumb1_cc_op1 = operands[2]; - cfun->machine->thumb1_cc_mode = CCmode; - } - else - /* Ensure we emit the right type of condition code on the jump. */ - XEXP (operands[0], 0) = gen_rtx_REG (cfun->machine->thumb1_cc_mode, - CC_REGNUM); - - switch (get_attr_length (insn)) - { - case 4: return \"b%d0\\t%l3\"; - case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } -} - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (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)))) - (set_attr "type" "multiple")] -) - -(define_insn "cbranchsi4_scratch" - [(set (pc) (if_then_else - (match_operator 4 "arm_comparison_operator" - [(match_operand:SI 1 "s_register_operand" "l,0") - (match_operand:SI 2 "thumb1_cmpneg_operand" "L,J")]) - (label_ref (match_operand 3 "" "")) - (pc))) - (clobber (match_scratch:SI 0 "=l,l"))] - "TARGET_THUMB1" - "* - output_asm_insn (\"add\\t%0, %1, #%n2\", operands); - - switch (get_attr_length (insn)) - { - case 4: return \"b%d4\\t%l3\"; - case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } - " - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (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)))) - (set_attr "type" "multiple")] -) - -(define_insn "*negated_cbranchsi4" - [(set (pc) - (if_then_else - (match_operator 0 "equality_operator" - [(match_operand:SI 1 "s_register_operand" "l") - (neg:SI (match_operand:SI 2 "s_register_operand" "l"))]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "TARGET_THUMB1" - "* - output_asm_insn (\"cmn\\t%1, %2\", operands); - switch (get_attr_length (insn)) - { - case 4: return \"b%d0\\t%l3\"; - case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } - " - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (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)))) - (set_attr "type" "multiple")] -) - -(define_insn "*tbit_cbranch" - [(set (pc) - (if_then_else - (match_operator 0 "equality_operator" - [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l") - (const_int 1) - (match_operand:SI 2 "const_int_operand" "i")) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc))) - (clobber (match_scratch:SI 4 "=l"))] - "TARGET_THUMB1" - "* - { - rtx op[3]; - op[0] = operands[4]; - op[1] = operands[1]; - op[2] = GEN_INT (32 - 1 - INTVAL (operands[2])); - - output_asm_insn (\"lsl\\t%0, %1, %2\", op); - switch (get_attr_length (insn)) - { - case 4: return \"b%d0\\t%l3\"; - case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } - }" - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (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)))) - (set_attr "type" "multiple")] -) - -(define_insn "*tlobits_cbranch" - [(set (pc) - (if_then_else - (match_operator 0 "equality_operator" - [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l") - (match_operand:SI 2 "const_int_operand" "i") - (const_int 0)) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc))) - (clobber (match_scratch:SI 4 "=l"))] - "TARGET_THUMB1" - "* - { - rtx op[3]; - op[0] = operands[4]; - op[1] = operands[1]; - op[2] = GEN_INT (32 - INTVAL (operands[2])); - - output_asm_insn (\"lsl\\t%0, %1, %2\", op); - switch (get_attr_length (insn)) - { - case 4: return \"b%d0\\t%l3\"; - case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; - } - }" - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 3) (pc)) (const_int -250)) - (le (minus (match_dup 3) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (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)))) - (set_attr "type" "multiple")] -) - -(define_insn "*tstsi3_cbranch" - [(set (pc) - (if_then_else - (match_operator 3 "equality_operator" - [(and:SI (match_operand:SI 0 "s_register_operand" "%l") - (match_operand:SI 1 "s_register_operand" "l")) - (const_int 0)]) - (label_ref (match_operand 2 "" "")) - (pc)))] - "TARGET_THUMB1" - "* - { - output_asm_insn (\"tst\\t%0, %1\", operands); - switch (get_attr_length (insn)) - { - case 4: return \"b%d3\\t%l2\"; - case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\"; - default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\"; - } - }" - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 2) (pc)) (const_int -250)) - (le (minus (match_dup 2) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (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)))) - (set_attr "type" "multiple")] -) - -(define_insn "*cbranchne_decr1" - [(set (pc) - (if_then_else (match_operator 3 "equality_operator" - [(match_operand:SI 2 "s_register_operand" "l,l,1,l") - (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc))) - (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m") - (plus:SI (match_dup 2) (const_int -1))) - (clobber (match_scratch:SI 1 "=X,l,&l,&l"))] - "TARGET_THUMB1" - "* - { - rtx cond[2]; - cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE - ? GEU : LTU), - VOIDmode, operands[2], const1_rtx); - cond[1] = operands[4]; - - if (which_alternative == 0) - output_asm_insn (\"sub\\t%0, %2, #1\", operands); - else if (which_alternative == 1) - { - /* We must provide an alternative for a hi reg because reload - cannot handle output reloads on a jump instruction, but we - can't subtract into that. Fortunately a mov from lo to hi - does not clobber the condition codes. */ - output_asm_insn (\"sub\\t%1, %2, #1\", operands); - output_asm_insn (\"mov\\t%0, %1\", operands); - } - else - { - /* Similarly, but the target is memory. */ - output_asm_insn (\"sub\\t%1, %2, #1\", operands); - output_asm_insn (\"str\\t%1, %0\", operands); - } - - switch (get_attr_length (insn) - (which_alternative ? 2 : 0)) - { - case 4: - output_asm_insn (\"b%d0\\t%l1\", cond); - return \"\"; - case 6: - output_asm_insn (\"b%D0\\t.LCB%=\", cond); - return \"b\\t%l4\\t%@long jump\\n.LCB%=:\"; - default: - output_asm_insn (\"b%D0\\t.LCB%=\", cond); - return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\"; - } - } - " - [(set (attr "far_jump") - (if_then_else - (ior (and (eq (symbol_ref ("which_alternative")) - (const_int 0)) - (eq_attr "length" "8")) - (eq_attr "length" "10")) - (const_string "yes") - (const_string "no"))) - (set_attr_alternative "length" - [ - ;; Alternative 0 - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -250)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (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))) - ;; Alternative 1 - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -248)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (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))) - ;; Alternative 2 - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -248)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (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))) - ;; Alternative 3 - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -248)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (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)))]) - (set_attr "type" "multiple")] -) - -(define_insn "*addsi3_cbranch" - [(set (pc) - (if_then_else - (match_operator 4 "arm_comparison_operator" - [(plus:SI - (match_operand:SI 2 "s_register_operand" "%0,l,*l,1,1,1") - (match_operand:SI 3 "reg_or_int_operand" "IJ,lL,*l,lIJ,lIJ,lIJ")) - (const_int 0)]) - (label_ref (match_operand 5 "" "")) - (pc))) - (set - (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m") - (plus:SI (match_dup 2) (match_dup 3))) - (clobber (match_scratch:SI 1 "=X,X,l,l,&l,&l"))] - "TARGET_THUMB1 - && (GET_CODE (operands[4]) == EQ - || GET_CODE (operands[4]) == NE - || GET_CODE (operands[4]) == GE - || GET_CODE (operands[4]) == LT)" - "* - { - rtx cond[3]; - - cond[0] = (which_alternative < 2) ? operands[0] : operands[1]; - cond[1] = operands[2]; - cond[2] = operands[3]; - - if (CONST_INT_P (cond[2]) && INTVAL (cond[2]) < 0) - output_asm_insn (\"sub\\t%0, %1, #%n2\", cond); - else - output_asm_insn (\"add\\t%0, %1, %2\", cond); - - if (which_alternative >= 2 - && which_alternative < 4) - output_asm_insn (\"mov\\t%0, %1\", operands); - else if (which_alternative >= 4) - output_asm_insn (\"str\\t%1, %0\", operands); - - switch (get_attr_length (insn) - ((which_alternative >= 2) ? 2 : 0)) - { - case 4: - return \"b%d4\\t%l5\"; - case 6: - return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\"; - default: - return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\"; - } - } - " - [(set (attr "far_jump") - (if_then_else - (ior (and (lt (symbol_ref ("which_alternative")) - (const_int 2)) - (eq_attr "length" "8")) - (eq_attr "length" "10")) - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (lt (symbol_ref ("which_alternative")) - (const_int 2)) - (if_then_else - (and (ge (minus (match_dup 5) (pc)) (const_int -250)) - (le (minus (match_dup 5) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (and (ge (minus (match_dup 5) (pc)) (const_int -2040)) - (le (minus (match_dup 5) (pc)) (const_int 2048))) - (const_int 6) - (const_int 8))) - (if_then_else - (and (ge (minus (match_dup 5) (pc)) (const_int -248)) - (le (minus (match_dup 5) (pc)) (const_int 256))) - (const_int 6) - (if_then_else - (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))))) - (set_attr "type" "multiple")] -) - -(define_insn "*addsi3_cbranch_scratch" - [(set (pc) - (if_then_else - (match_operator 3 "arm_comparison_operator" - [(plus:SI - (match_operand:SI 1 "s_register_operand" "%l,l,l,0") - (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ")) - (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc))) - (clobber (match_scratch:SI 0 "=X,X,l,l"))] - "TARGET_THUMB1 - && (GET_CODE (operands[3]) == EQ - || GET_CODE (operands[3]) == NE - || GET_CODE (operands[3]) == GE - || GET_CODE (operands[3]) == LT)" - "* - { - switch (which_alternative) - { - case 0: - output_asm_insn (\"cmp\t%1, #%n2\", operands); - break; - case 1: - output_asm_insn (\"cmn\t%1, %2\", operands); - break; - case 2: - if (INTVAL (operands[2]) < 0) - output_asm_insn (\"sub\t%0, %1, %2\", operands); - else - output_asm_insn (\"add\t%0, %1, %2\", operands); - break; - case 3: - if (INTVAL (operands[2]) < 0) - output_asm_insn (\"sub\t%0, %0, %2\", operands); - else - output_asm_insn (\"add\t%0, %0, %2\", operands); - break; - } - - switch (get_attr_length (insn)) - { - case 4: - return \"b%d3\\t%l4\"; - case 6: - return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\"; - default: - return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\"; - } - } - " - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "8") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (and (ge (minus (match_dup 4) (pc)) (const_int -250)) - (le (minus (match_dup 4) (pc)) (const_int 256))) - (const_int 4) - (if_then_else - (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)))) - (set_attr "type" "multiple")] -) - - ;; Comparison and test insns (define_insn "*arm_cmpsi_insn" @@ -8409,18 +6989,6 @@ (set_attr "type" "logics_reg")] ) -(define_insn "*thumb_cmpdi_zero" - [(set (reg:CC_Z CC_REGNUM) - (compare:CC_Z (match_operand:DI 0 "s_register_operand" "l") - (const_int 0))) - (clobber (match_scratch:SI 1 "=l"))] - "TARGET_THUMB1" - "orr\\t%1, %Q0, %R0" - [(set_attr "conds" "set") - (set_attr "length" "2") - (set_attr "type" "logics_reg")] -) - ; This insn allows redundant compares to be removed by cse, nothing should ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that ; is deleted later on. The match_dup will match the mode here, so that @@ -8750,88 +7318,6 @@ }" ) -(define_expand "cstoresi_eq0_thumb1" - [(parallel - [(set (match_operand:SI 0 "s_register_operand" "") - (eq:SI (match_operand:SI 1 "s_register_operand" "") - (const_int 0))) - (clobber (match_dup:SI 2))])] - "TARGET_THUMB1" - "operands[2] = gen_reg_rtx (SImode);" -) - -(define_expand "cstoresi_ne0_thumb1" - [(parallel - [(set (match_operand:SI 0 "s_register_operand" "") - (ne:SI (match_operand:SI 1 "s_register_operand" "") - (const_int 0))) - (clobber (match_dup:SI 2))])] - "TARGET_THUMB1" - "operands[2] = gen_reg_rtx (SImode);" -) - -(define_insn "*cstoresi_eq0_thumb1_insn" - [(set (match_operand:SI 0 "s_register_operand" "=&l,l") - (eq:SI (match_operand:SI 1 "s_register_operand" "l,0") - (const_int 0))) - (clobber (match_operand:SI 2 "s_register_operand" "=X,l"))] - "TARGET_THUMB1" - "@ - neg\\t%0, %1\;adc\\t%0, %0, %1 - neg\\t%2, %1\;adc\\t%0, %1, %2" - [(set_attr "length" "4") - (set_attr "type" "multiple")] -) - -(define_insn "*cstoresi_ne0_thumb1_insn" - [(set (match_operand:SI 0 "s_register_operand" "=l") - (ne:SI (match_operand:SI 1 "s_register_operand" "0") - (const_int 0))) - (clobber (match_operand:SI 2 "s_register_operand" "=l"))] - "TARGET_THUMB1" - "sub\\t%2, %1, #1\;sbc\\t%0, %1, %2" - [(set_attr "length" "4")] -) - -;; Used as part of the expansion of thumb ltu and gtu sequences -(define_insn "cstoresi_nltu_thumb1" - [(set (match_operand:SI 0 "s_register_operand" "=l,l") - (neg:SI (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h") - (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 "type" "multiple")] -) - -(define_insn_and_split "cstoresi_ltu_thumb1" - [(set (match_operand:SI 0 "s_register_operand" "=l,l") - (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h") - (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")))] - "TARGET_THUMB1" - "#" - "TARGET_THUMB1" - [(set (match_dup 3) - (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 "type" "multiple")] -) - -;; Used as part of the expansion of thumb les sequence. -(define_insn "thumb1_addsi3_addgeu" - [(set (match_operand:SI 0 "s_register_operand" "=l") - (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") - (match_operand:SI 2 "s_register_operand" "l")) - (geu:SI (match_operand:SI 3 "s_register_operand" "l") - (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 "type" "multiple")] -) - ;; Conditional move insns @@ -9051,29 +7537,6 @@ (set_attr "type" "branch")] ) -(define_insn "*thumb_jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "TARGET_THUMB1" - "* - if (get_attr_length (insn) == 2) - return \"b\\t%l0\"; - return \"bl\\t%l0\\t%@ far jump\"; - " - [(set (attr "far_jump") - (if_then_else - (eq_attr "length" "4") - (const_string "yes") - (const_string "no"))) - (set (attr "length") - (if_then_else - (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))) - (set_attr "type" "branch")] -) - (define_expand "call" [(parallel [(call (match_operand 0 "memory_operand" "") (match_operand 1 "general_operand" "")) @@ -9151,37 +7614,6 @@ (set_attr "type" "call")] ) -(define_insn "*call_reg_thumb1_v5" - [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r")) - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (clobber (reg:SI LR_REGNUM))] - "TARGET_THUMB1 && arm_arch5 && !SIBLING_CALL_P (insn)" - "blx\\t%0" - [(set_attr "length" "2") - (set_attr "type" "call")] -) - -(define_insn "*call_reg_thumb1" - [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r")) - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (clobber (reg:SI LR_REGNUM))] - "TARGET_THUMB1 && !arm_arch5 && !SIBLING_CALL_P (insn)" - "* - { - if (!TARGET_CALLER_INTERWORKING) - return thumb_call_via_reg (operands[0]); - else if (operands[1] == const0_rtx) - return \"bl\\t%__interwork_call_via_%0\"; - else if (frame_pointer_needed) - return \"bl\\t%__interwork_r7_call_via_%0\"; - else - return \"bl\\t%__interwork_r11_call_via_%0\"; - }" - [(set_attr "type" "call")] -) - (define_expand "call_value" [(parallel [(set (match_operand 0 "" "") (call (match_operand 1 "memory_operand" "") @@ -9262,39 +7694,6 @@ (set_attr "type" "call")] ) -(define_insn "*call_value_reg_thumb1_v5" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:SI 1 "register_operand" "l*r")) - (match_operand 2 "" ""))) - (use (match_operand 3 "" "")) - (clobber (reg:SI LR_REGNUM))] - "TARGET_THUMB1 && arm_arch5" - "blx\\t%1" - [(set_attr "length" "2") - (set_attr "type" "call")] -) - -(define_insn "*call_value_reg_thumb1" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:SI 1 "register_operand" "l*r")) - (match_operand 2 "" ""))) - (use (match_operand 3 "" "")) - (clobber (reg:SI LR_REGNUM))] - "TARGET_THUMB1 && !arm_arch5" - "* - { - if (!TARGET_CALLER_INTERWORKING) - return thumb_call_via_reg (operands[1]); - else if (operands[2] == const0_rtx) - return \"bl\\t%__interwork_call_via_%1\"; - else if (frame_pointer_needed) - return \"bl\\t%__interwork_r7_call_via_%1\"; - else - return \"bl\\t%__interwork_r11_call_via_%1\"; - }" - [(set_attr "type" "call")] -) - ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output. @@ -9331,33 +7730,6 @@ [(set_attr "type" "call")] ) -(define_insn "*call_insn" - [(call (mem:SI (match_operand:SI 0 "" "")) - (match_operand:SI 1 "" "")) - (use (match_operand 2 "" "")) - (clobber (reg:SI LR_REGNUM))] - "TARGET_THUMB1 - && GET_CODE (operands[0]) == SYMBOL_REF - && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))" - "bl\\t%a0" - [(set_attr "length" "4") - (set_attr "type" "call")] -) - -(define_insn "*call_value_insn" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "" "")) - (match_operand 2 "" ""))) - (use (match_operand 3 "" "")) - (clobber (reg:SI LR_REGNUM))] - "TARGET_THUMB1 - && GET_CODE (operands[1]) == SYMBOL_REF - && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))" - "bl\\t%a1" - [(set_attr "length" "4") - (set_attr "type" "call")] -) - ;; We may also be able to do sibcalls for Thumb, but it's much harder... (define_expand "sibcall" [(parallel [(call (match_operand 0 "memory_operand" "") @@ -9755,38 +8127,6 @@ (set_attr "type" "multiple")] ) -(define_expand "thumb1_casesi_internal_pic" - [(match_operand:SI 0 "s_register_operand" "") - (match_operand:SI 1 "thumb1_cmp_operand" "") - (match_operand 2 "" "") - (match_operand 3 "" "")] - "TARGET_THUMB1" - { - rtx reg0; - rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[1]); - emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[1], - operands[3])); - reg0 = gen_rtx_REG (SImode, 0); - emit_move_insn (reg0, operands[0]); - emit_jump_insn (gen_thumb1_casesi_dispatch (operands[2]/*, operands[3]*/)); - DONE; - } -) - -(define_insn "thumb1_casesi_dispatch" - [(parallel [(set (pc) (unspec [(reg:SI 0) - (label_ref (match_operand 0 "" "")) -;; (label_ref (match_operand 1 "" "")) -] - UNSPEC_THUMB1_CASESI)) - (clobber (reg:SI IP_REGNUM)) - (clobber (reg:SI LR_REGNUM))])] - "TARGET_THUMB1" - "* return thumb1_output_casesi(operands);" - [(set_attr "length" "4") - (set_attr "type" "multiple")] -) - (define_expand "indirect_jump" [(set (pc) (match_operand:SI 0 "s_register_operand" ""))] @@ -9825,17 +8165,6 @@ (set_attr "predicable" "yes")] ) -;; NB Never uses BX. -(define_insn "*thumb1_indirect_jump" - [(set (pc) - (match_operand:SI 0 "register_operand" "l*r"))] - "TARGET_THUMB1" - "mov\\tpc, %0" - [(set_attr "conds" "clob") - (set_attr "length" "2") - (set_attr "type" "branch")] -) - ;; Misc insns @@ -11792,14 +10121,6 @@ " ) -(define_insn "prologue_thumb1_interwork" - [(unspec_volatile [(const_int 0)] VUNSPEC_THUMB1_INTERWORK)] - "TARGET_THUMB1" - "* return thumb1_output_interwork ();" - [(set_attr "length" "8") - (set_attr "type" "multiple")] -) - ;; Note - although unspec_volatile's USE all hard registers, ;; USEs are ignored after relaod has completed. Thus we need ;; to add an unspec of the link register to ensure that flow @@ -11815,21 +10136,6 @@ " ) -(define_insn "*epilogue_insns" - [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)] - "TARGET_THUMB1" - "* - return thumb1_unexpanded_epilogue (); - " - ; Length is absolute worst case - [(set_attr "length" "44") - (set_attr "type" "block") - ;; We don't clobber the conditions, but the potential length of this - ;; operation is sufficient to make conditionalizing the sequence - ;; unlikely to be profitable. - (set_attr "conds" "clob")] -) - (define_expand "eh_epilogue" [(use (match_operand:SI 0 "register_operand" "")) (use (match_operand:SI 1 "register_operand" "")) @@ -12240,33 +10546,6 @@ [(set_attr "type" "no_insn")] ) -(define_insn "consttable_1" - [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)] - "TARGET_THUMB1" - "* - making_const_table = TRUE; - assemble_integer (operands[0], 1, BITS_PER_WORD, 1); - assemble_zeros (3); - return \"\"; - " - [(set_attr "length" "4") - (set_attr "type" "no_insn")] -) - -(define_insn "consttable_2" - [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)] - "TARGET_THUMB1" - "* - making_const_table = TRUE; - gcc_assert (GET_MODE_CLASS (GET_MODE (operands[0])) != MODE_FLOAT); - assemble_integer (operands[0], 2, BITS_PER_WORD, 1); - assemble_zeros (2); - return \"\"; - " - [(set_attr "length" "4") - (set_attr "type" "no_insn")] -) - (define_insn "consttable_4" [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)] "TARGET_EITHER" @@ -12354,35 +10633,6 @@ (set_attr "type" "no_insn")] ) -;; Miscellaneous Thumb patterns - -(define_expand "tablejump" - [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "")) - (use (label_ref (match_operand 1 "" "")))])] - "TARGET_THUMB1" - " - if (flag_pic) - { - /* Hopefully, CSE will eliminate this copy. */ - rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1])); - rtx reg2 = gen_reg_rtx (SImode); - - emit_insn (gen_addsi3 (reg2, operands[0], reg1)); - operands[0] = reg2; - } - " -) - -;; NB never uses BX. -(define_insn "*thumb1_tablejump" - [(set (pc) (match_operand:SI 0 "register_operand" "l*r")) - (use (label_ref (match_operand 1 "" "")))] - "TARGET_THUMB1" - "mov\\t%|pc, %0" - [(set_attr "length" "2") - (set_attr "type" "no_insn")] -) - ;; V5 Instructions, (define_insn "clzsi2" @@ -12477,22 +10727,6 @@ }" ) -(define_insn_and_split "thumb_eh_return" - [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")] - VUNSPEC_EH_RETURN) - (clobber (match_scratch:SI 1 "=&l"))] - "TARGET_THUMB1" - "#" - "&& reload_completed" - [(const_int 0)] - " - { - thumb_set_return_address (operands[0], operands[1]); - DONE; - }" - [(set_attr "type" "mov_reg")] -) - ;; TLS support @@ -12878,6 +11112,8 @@ (include "iwmmxt.md") ;; Load the VFP co-processor patterns (include "vfp.md") +;; Thumb-1 patterns +(include "thumb1.md") ;; Thumb-2 patterns (include "thumb2.md") ;; Neon patterns diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md new file mode 100644 index 00000000000..379e14c9d92 --- /dev/null +++ b/gcc/config/arm/thumb1.md @@ -0,0 +1,1789 @@ +;; ARM Thumb-1 Machine Description +;; Copyright (C) 2007-2014 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/>. */ + + +;;--------------------------------------------------------------------------- +;; Insn patterns +;; + +(define_insn "*thumb1_adddi3" + [(set (match_operand:DI 0 "register_operand" "=l") + (plus:DI (match_operand:DI 1 "register_operand" "%0") + (match_operand:DI 2 "register_operand" "l"))) + (clobber (reg:CC CC_REGNUM)) + ] + "TARGET_THUMB1" + "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2" + [(set_attr "length" "4") + (set_attr "type" "multiple")] +) + +(define_insn_and_split "*thumb1_addsi3" + [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,k,l,l,l") + (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,k,k,0,l,k") + (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,M,O,Pa,Pb,Pc")))] + "TARGET_THUMB1" + "* + static const char * const asms[] = + { + \"add\\t%0, %0, %2\", + \"sub\\t%0, %0, #%n2\", + \"add\\t%0, %1, %2\", + \"add\\t%0, %0, %2\", + \"add\\t%0, %0, %2\", + \"add\\t%0, %1, %2\", + \"add\\t%0, %1, %2\", + \"#\", + \"#\", + \"#\" + }; + if ((which_alternative == 2 || which_alternative == 6) + && CONST_INT_P (operands[2]) + && INTVAL (operands[2]) < 0) + return \"sub\\t%0, %1, #%n2\"; + return asms[which_alternative]; + " + "&& reload_completed && CONST_INT_P (operands[2]) + && ((operands[1] != stack_pointer_rtx + && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255)) + || (operands[1] == stack_pointer_rtx + && INTVAL (operands[2]) > 1020))" + [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2))) + (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))] + { + HOST_WIDE_INT offset = INTVAL (operands[2]); + if (operands[1] == stack_pointer_rtx) + offset -= 1020; + else + { + if (offset > 255) + offset = 255; + else if (offset < -255) + offset = -255; + } + 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 "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 +;; sometimes cause this optimization to be missed. +(define_peephole2 + [(set (match_operand:SI 0 "arm_general_register_operand" "") + (match_operand:SI 1 "const_int_operand" "")) + (set (match_dup 0) + (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))] + "TARGET_THUMB1 + && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024 + && (INTVAL (operands[1]) & 3) == 0" + [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))] + "" +) + +(define_insn "*thumb_subdi3" + [(set (match_operand:DI 0 "register_operand" "=l") + (minus:DI (match_operand:DI 1 "register_operand" "0") + (match_operand:DI 2 "register_operand" "l"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_THUMB1" + "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2" + [(set_attr "length" "4") + (set_attr "type" "multiple")] +) + +(define_insn "thumb1_subsi3_insn" + [(set (match_operand:SI 0 "register_operand" "=l") + (minus:SI (match_operand:SI 1 "register_operand" "l") + (match_operand:SI 2 "reg_or_int_operand" "lPd")))] + "TARGET_THUMB1" + "sub\\t%0, %1, %2" + [(set_attr "length" "2") + (set_attr "conds" "set") + (set_attr "type" "alus_reg")] +) + +; Unfortunately with the Thumb the '&'/'0' trick can fails when operands +; 1 and 2; are the same, because reload will make operand 0 match +; operand 1 without realizing that this conflicts with operand 2. We fix +; this by adding another alternative to match this case, and then `reload' +; it ourselves. This alternative must come first. +(define_insn "*thumb_mulsi3" + [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l") + (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0") + (match_operand:SI 2 "register_operand" "l,l,l")))] + "TARGET_THUMB1 && !arm_arch6" + "* + if (which_alternative < 2) + return \"mov\\t%0, %1\;mul\\t%0, %2\"; + else + return \"mul\\t%0, %2\"; + " + [(set_attr "length" "4,4,2") + (set_attr "type" "muls")] +) + +(define_insn "*thumb_mulsi3_v6" + [(set (match_operand:SI 0 "register_operand" "=l,l,l") + (mult:SI (match_operand:SI 1 "register_operand" "0,l,0") + (match_operand:SI 2 "register_operand" "l,0,0")))] + "TARGET_THUMB1 && arm_arch6" + "@ + mul\\t%0, %2 + mul\\t%0, %1 + mul\\t%0, %1" + [(set_attr "length" "2") + (set_attr "type" "muls")] +) + +(define_insn "*thumb1_andsi3_insn" + [(set (match_operand:SI 0 "register_operand" "=l") + (and:SI (match_operand:SI 1 "register_operand" "%0") + (match_operand:SI 2 "register_operand" "l")))] + "TARGET_THUMB1" + "and\\t%0, %2" + [(set_attr "length" "2") + (set_attr "type" "logic_imm") + (set_attr "conds" "set")]) + +(define_split + [(set (match_operand:SI 0 "s_register_operand" "") + (zero_extract:SI (match_operand:SI 1 "s_register_operand" "") + (match_operand:SI 2 "const_int_operand" "") + (match_operand:SI 3 "const_int_operand" ""))) + (clobber (match_operand:SI 4 "s_register_operand" ""))] + "TARGET_THUMB1" + [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2))) + (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))] + "{ + HOST_WIDE_INT temp = INTVAL (operands[2]); + + operands[2] = GEN_INT (32 - temp - INTVAL (operands[3])); + operands[3] = GEN_INT (32 - temp); + }" +) + +(define_split + [(set (match_operand:SI 0 "s_register_operand" "") + (sign_extract:SI (match_operand:SI 1 "s_register_operand" "") + (match_operand:SI 2 "const_int_operand" "") + (match_operand:SI 3 "const_int_operand" "")))] + "TARGET_THUMB1" + [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2))) + (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))] + "{ + HOST_WIDE_INT temp = INTVAL (operands[2]); + + operands[2] = GEN_INT (32 - temp - INTVAL (operands[3])); + operands[3] = GEN_INT (32 - temp); + }" +) + +(define_insn "thumb1_bicsi3" + [(set (match_operand:SI 0 "register_operand" "=l") + (and:SI (not:SI (match_operand:SI 1 "register_operand" "l")) + (match_operand:SI 2 "register_operand" "0")))] + "TARGET_THUMB1" + "bic\\t%0, %1" + [(set_attr "length" "2") + (set_attr "conds" "set") + (set_attr "type" "logics_reg")] +) + +(define_insn "*thumb1_iorsi3_insn" + [(set (match_operand:SI 0 "register_operand" "=l") + (ior:SI (match_operand:SI 1 "register_operand" "%0") + (match_operand:SI 2 "register_operand" "l")))] + "TARGET_THUMB1" + "orr\\t%0, %2" + [(set_attr "length" "2") + (set_attr "conds" "set") + (set_attr "type" "logics_reg")]) + +(define_insn "*thumb1_xorsi3_insn" + [(set (match_operand:SI 0 "register_operand" "=l") + (xor:SI (match_operand:SI 1 "register_operand" "%0") + (match_operand:SI 2 "register_operand" "l")))] + "TARGET_THUMB1" + "eor\\t%0, %2" + [(set_attr "length" "2") + (set_attr "conds" "set") + (set_attr "type" "logics_reg")] +) + +(define_insn "*thumb1_ashlsi3" + [(set (match_operand:SI 0 "register_operand" "=l,l") + (ashift:SI (match_operand:SI 1 "register_operand" "l,0") + (match_operand:SI 2 "nonmemory_operand" "N,l")))] + "TARGET_THUMB1" + "lsl\\t%0, %1, %2" + [(set_attr "length" "2") + (set_attr "type" "shift_imm,shift_reg") + (set_attr "conds" "set")]) + +(define_insn "*thumb1_ashrsi3" + [(set (match_operand:SI 0 "register_operand" "=l,l") + (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0") + (match_operand:SI 2 "nonmemory_operand" "N,l")))] + "TARGET_THUMB1" + "asr\\t%0, %1, %2" + [(set_attr "length" "2") + (set_attr "type" "shift_imm,shift_reg") + (set_attr "conds" "set")]) + +(define_insn "*thumb1_lshrsi3" + [(set (match_operand:SI 0 "register_operand" "=l,l") + (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0") + (match_operand:SI 2 "nonmemory_operand" "N,l")))] + "TARGET_THUMB1" + "lsr\\t%0, %1, %2" + [(set_attr "length" "2") + (set_attr "type" "shift_imm,shift_reg") + (set_attr "conds" "set")]) + +(define_insn "*thumb1_rotrsi3" + [(set (match_operand:SI 0 "register_operand" "=l") + (rotatert:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "register_operand" "l")))] + "TARGET_THUMB1" + "ror\\t%0, %0, %2" + [(set_attr "type" "shift_reg") + (set_attr "length" "2")] +) + +(define_insn "*thumb1_negdi2" + [(set (match_operand:DI 0 "register_operand" "=&l") + (neg:DI (match_operand:DI 1 "register_operand" "l"))) + (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 "type" "multiple")] +) + +(define_insn "*thumb1_negsi2" + [(set (match_operand:SI 0 "register_operand" "=l") + (neg:SI (match_operand:SI 1 "register_operand" "l")))] + "TARGET_THUMB1" + "neg\\t%0, %1" + [(set_attr "length" "2") + (set_attr "type" "alu_imm")] +) + +(define_insn_and_split "*thumb1_abssi2" + [(set (match_operand:SI 0 "s_register_operand" "=l") + (abs:SI (match_operand:SI 1 "s_register_operand" "l"))) + (clobber (match_scratch:SI 2 "=&l"))] + "TARGET_THUMB1" + "#" + "TARGET_THUMB1 && reload_completed" + [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31))) + (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 "type" "multiple")] +) + +(define_insn_and_split "*thumb1_neg_abssi2" + [(set (match_operand:SI 0 "s_register_operand" "=l") + (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "l")))) + (clobber (match_scratch:SI 2 "=&l"))] + "TARGET_THUMB1" + "#" + "TARGET_THUMB1 && reload_completed" + [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31))) + (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 "type" "multiple")] +) + +(define_insn "*thumb1_one_cmplsi2" + [(set (match_operand:SI 0 "register_operand" "=l") + (not:SI (match_operand:SI 1 "register_operand" "l")))] + "TARGET_THUMB1" + "mvn\\t%0, %1" + [(set_attr "length" "2") + (set_attr "type" "mvn_reg")] +) + +(define_insn "*thumb1_zero_extendhisi2" + [(set (match_operand:SI 0 "register_operand" "=l,l") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))] + "TARGET_THUMB1" +{ + rtx mem; + + if (which_alternative == 0 && arm_arch6) + return "uxth\t%0, %1"; + if (which_alternative == 0) + return "#"; + + mem = XEXP (operands[1], 0); + + if (GET_CODE (mem) == CONST) + mem = XEXP (mem, 0); + + if (GET_CODE (mem) == PLUS) + { + rtx a = XEXP (mem, 0); + + /* This can happen due to bugs in reload. */ + if (REG_P (a) && REGNO (a) == SP_REGNUM) + { + rtx ops[2]; + ops[0] = operands[0]; + ops[1] = a; + + output_asm_insn ("mov\t%0, %1", ops); + + XEXP (mem, 0) = operands[0]; + } + } + + return "ldrh\t%0, %1"; +} + [(set_attr_alternative "length" + [(if_then_else (eq_attr "is_arch6" "yes") + (const_int 2) (const_int 4)) + (const_int 4)]) + (set_attr "type" "extend,load_byte")] +) + +(define_insn "*thumb1_zero_extendqisi2" + [(set (match_operand:SI 0 "register_operand" "=l,l") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))] + "TARGET_THUMB1 && !arm_arch6" + "@ + # + ldrb\\t%0, %1" + [(set_attr "length" "4,2") + (set_attr "type" "alu_shift_reg,load_byte") + (set_attr "pool_range" "*,32")] +) + +(define_insn "*thumb1_zero_extendqisi2_v6" + [(set (match_operand:SI 0 "register_operand" "=l,l") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))] + "TARGET_THUMB1 && arm_arch6" + "@ + uxtb\\t%0, %1 + ldrb\\t%0, %1" + [(set_attr "length" "2") + (set_attr "type" "extend,load_byte")] +) + +;; We used to have an early-clobber on the scratch register here. +;; However, there's a bug somewhere in reload which means that this +;; can be partially ignored during spill allocation if the memory +;; address also needs reloading; this causes us to die later on when +;; we try to verify the operands. Fortunately, we don't really need +;; the early-clobber: we can always use operand 0 if operand 2 +;; overlaps the address. +(define_insn "thumb1_extendhisi2" + [(set (match_operand:SI 0 "register_operand" "=l,l") + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m"))) + (clobber (match_scratch:SI 2 "=X,l"))] + "TARGET_THUMB1" + "* + { + rtx ops[4]; + rtx mem; + + if (which_alternative == 0 && !arm_arch6) + return \"#\"; + if (which_alternative == 0) + return \"sxth\\t%0, %1\"; + + mem = XEXP (operands[1], 0); + + /* This code used to try to use 'V', and fix the address only if it was + offsettable, but this fails for e.g. REG+48 because 48 is outside the + range of QImode offsets, and offsettable_address_p does a QImode + address check. */ + + if (GET_CODE (mem) == CONST) + mem = XEXP (mem, 0); + + if (GET_CODE (mem) == LABEL_REF) + return \"ldr\\t%0, %1\"; + + if (GET_CODE (mem) == PLUS) + { + rtx a = XEXP (mem, 0); + rtx b = XEXP (mem, 1); + + if (GET_CODE (a) == LABEL_REF + && CONST_INT_P (b)) + return \"ldr\\t%0, %1\"; + + if (REG_P (b)) + return \"ldrsh\\t%0, %1\"; + + ops[1] = a; + ops[2] = b; + } + else + { + ops[1] = mem; + ops[2] = const0_rtx; + } + + gcc_assert (REG_P (ops[1])); + + ops[0] = operands[0]; + if (reg_mentioned_p (operands[2], ops[1])) + ops[3] = ops[0]; + else + ops[3] = operands[2]; + output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops); + return \"\"; + }" + [(set_attr_alternative "length" + [(if_then_else (eq_attr "is_arch6" "yes") + (const_int 2) (const_int 4)) + (const_int 4)]) + (set_attr "type" "extend,load_byte") + (set_attr "pool_range" "*,1018")] +) + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (sign_extend:SI (match_operand:QI 1 "memory_operand" "")))] + "TARGET_THUMB1 && reload_completed" + [(set (match_dup 0) (match_dup 2)) + (set (match_dup 0) (sign_extend:SI (match_dup 3)))] +{ + rtx addr = XEXP (operands[1], 0); + + if (GET_CODE (addr) == CONST) + addr = XEXP (addr, 0); + + if (GET_CODE (addr) == PLUS + && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1))) + /* No split necessary. */ + FAIL; + + if (GET_CODE (addr) == PLUS + && !REG_P (XEXP (addr, 0)) && !REG_P (XEXP (addr, 1))) + FAIL; + + if (reg_overlap_mentioned_p (operands[0], addr)) + { + rtx t = gen_lowpart (QImode, operands[0]); + emit_move_insn (t, operands[1]); + emit_insn (gen_thumb1_extendqisi2 (operands[0], t)); + DONE; + } + + if (REG_P (addr)) + { + addr = gen_rtx_PLUS (Pmode, addr, operands[0]); + operands[2] = const0_rtx; + } + else if (GET_CODE (addr) != PLUS) + FAIL; + else if (REG_P (XEXP (addr, 0))) + { + operands[2] = XEXP (addr, 1); + addr = gen_rtx_PLUS (Pmode, XEXP (addr, 0), operands[0]); + } + else + { + operands[2] = XEXP (addr, 0); + addr = gen_rtx_PLUS (Pmode, XEXP (addr, 1), operands[0]); + } + + operands[3] = change_address (operands[1], QImode, addr); +}) + +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (plus:SI (match_dup 0) (match_operand 1 "const_int_operand"))) + (set (match_operand:SI 2 "register_operand" "") (const_int 0)) + (set (match_operand:SI 3 "register_operand" "") + (sign_extend:SI (match_operand:QI 4 "memory_operand" "")))] + "TARGET_THUMB1 + && GET_CODE (XEXP (operands[4], 0)) == PLUS + && rtx_equal_p (operands[0], XEXP (XEXP (operands[4], 0), 0)) + && rtx_equal_p (operands[2], XEXP (XEXP (operands[4], 0), 1)) + && (peep2_reg_dead_p (3, operands[0]) + || rtx_equal_p (operands[0], operands[3])) + && (peep2_reg_dead_p (3, operands[2]) + || rtx_equal_p (operands[2], operands[3]))" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 3) (sign_extend:SI (match_dup 4)))] +{ + rtx addr = gen_rtx_PLUS (Pmode, operands[0], operands[2]); + operands[4] = change_address (operands[4], QImode, addr); +}) + +(define_insn "thumb1_extendqisi2" + [(set (match_operand:SI 0 "register_operand" "=l,l,l") + (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))] + "TARGET_THUMB1" +{ + rtx addr; + + if (which_alternative == 0 && arm_arch6) + return "sxtb\\t%0, %1"; + if (which_alternative == 0) + return "#"; + + addr = XEXP (operands[1], 0); + if (GET_CODE (addr) == PLUS + && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1))) + return "ldrsb\\t%0, %1"; + + return "#"; +} + [(set_attr_alternative "length" + [(if_then_else (eq_attr "is_arch6" "yes") + (const_int 2) (const_int 4)) + (const_int 2) + (if_then_else (eq_attr "is_arch6" "yes") + (const_int 4) (const_int 6))]) + (set_attr "type" "extend,load_byte,load_byte")] +) + +;;; ??? This should have alternatives for constants. +;;; ??? This was originally identical to the movdf_insn pattern. +;;; ??? The 'i' constraint looks funny, but it should always be replaced by +;;; thumb_reorg with a memory reference. +(define_insn "*thumb1_movdi_insn" + [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r") + (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))] + "TARGET_THUMB1 + && ( register_operand (operands[0], DImode) + || register_operand (operands[1], DImode))" + "* + { + switch (which_alternative) + { + default: + case 0: + if (REGNO (operands[1]) == REGNO (operands[0]) + 1) + return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\"; + return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\"; + case 1: + return \"mov\\t%Q0, %1\;mov\\t%R0, #0\"; + case 2: + operands[1] = GEN_INT (- INTVAL (operands[1])); + return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\"; + case 3: + return \"ldmia\\t%1, {%0, %H0}\"; + case 4: + return \"stmia\\t%0, {%1, %H1}\"; + case 5: + return thumb_load_double_from_address (operands); + case 6: + operands[2] = gen_rtx_MEM (SImode, + plus_constant (Pmode, XEXP (operands[0], 0), 4)); + output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands); + return \"\"; + case 7: + if (REGNO (operands[1]) == REGNO (operands[0]) + 1) + return \"mov\\t%0, %1\;mov\\t%H0, %H1\"; + return \"mov\\t%H0, %H1\;mov\\t%0, %1\"; + } + }" + [(set_attr "length" "4,4,6,2,2,6,4,4") + (set_attr "type" "multiple,multiple,multiple,load2,store2,load2,store2,multiple") + (set_attr "pool_range" "*,*,*,*,*,1018,*,*")] +) + +(define_insn "*thumb1_movsi_insn" + [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*l*h*k") + (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*l*h*k"))] + "TARGET_THUMB1 + && ( register_operand (operands[0], SImode) + || register_operand (operands[1], SImode))" + "@ + mov %0, %1 + mov %0, %1 + # + # + ldmia\\t%1, {%0} + stmia\\t%0, {%1} + ldr\\t%0, %1 + str\\t%1, %0 + mov\\t%0, %1" + [(set_attr "length" "2,2,4,4,2,2,2,2,2") + (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")]) + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "const_int_operand" ""))] + "TARGET_THUMB1 && satisfies_constraint_J (operands[1])" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 0) (neg:SI (match_dup 2)))] + " + { + operands[1] = GEN_INT (- INTVAL (operands[1])); + operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0]; + }" +) + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "const_int_operand" ""))] + "TARGET_THUMB1 && satisfies_constraint_K (operands[1])" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 0) (ashift:SI (match_dup 2) (match_dup 3)))] + " + { + unsigned HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffffffffu; + unsigned HOST_WIDE_INT mask = 0xff; + int i; + + for (i = 0; i < 25; i++) + if ((val & (mask << i)) == val) + break; + + /* Don't split if the shift is zero. */ + if (i == 0) + FAIL; + + operands[1] = GEN_INT (val >> i); + operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0]; + operands[3] = GEN_INT (i); + }" +) + +;; For thumb1 split imm move [256-510] into mov [1-255] and add #255 +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "const_int_operand" ""))] + "TARGET_THUMB1 && satisfies_constraint_Pe (operands[1])" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 3)))] + " + { + operands[1] = GEN_INT (INTVAL (operands[1]) - 255); + operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0]; + operands[3] = GEN_INT (255); + }" +) + +(define_insn "*thumb1_movhi_insn" + [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l") + (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))] + "TARGET_THUMB1 + && ( register_operand (operands[0], HImode) + || register_operand (operands[1], HImode))" + "* + switch (which_alternative) + { + case 0: return \"add %0, %1, #0\"; + case 2: return \"strh %1, %0\"; + case 3: return \"mov %0, %1\"; + case 4: return \"mov %0, %1\"; + case 5: return \"mov %0, %1\"; + default: gcc_unreachable (); + case 1: + /* The stack pointer can end up being taken as an index register. + Catch this case here and deal with it. */ + if (GET_CODE (XEXP (operands[1], 0)) == PLUS + && REG_P (XEXP (XEXP (operands[1], 0), 0)) + && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM) + { + rtx ops[2]; + ops[0] = operands[0]; + ops[1] = XEXP (XEXP (operands[1], 0), 0); + + output_asm_insn (\"mov %0, %1\", ops); + + XEXP (XEXP (operands[1], 0), 0) = operands[0]; + + } + return \"ldrh %0, %1\"; + }" + [(set_attr "length" "2,4,2,2,2,2") + (set_attr "type" "alus_imm,load1,store1,mov_reg,mov_reg,mov_imm") + (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")]) + +(define_expand "thumb_movhi_clobber" + [(set (match_operand:HI 0 "memory_operand" "") + (match_operand:HI 1 "register_operand" "")) + (clobber (match_operand:DI 2 "register_operand" ""))] + "TARGET_THUMB1" + " + if (strict_memory_address_p (HImode, XEXP (operands[0], 0)) + && REGNO (operands[1]) <= LAST_LO_REGNUM) + { + emit_insn (gen_movhi (operands[0], operands[1])); + DONE; + } + /* XXX Fixme, need to handle other cases here as well. */ + gcc_unreachable (); + " +) + +(define_insn "*thumb1_movqi_insn" + [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l") + (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))] + "TARGET_THUMB1 + && ( register_operand (operands[0], QImode) + || register_operand (operands[1], QImode))" + "@ + add\\t%0, %1, #0 + ldrb\\t%0, %1 + strb\\t%1, %0 + mov\\t%0, %1 + mov\\t%0, %1 + mov\\t%0, %1" + [(set_attr "length" "2") + (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")]) + +(define_insn "*thumb1_movhf" + [(set (match_operand:HF 0 "nonimmediate_operand" "=l,l,m,*r,*h") + (match_operand:HF 1 "general_operand" "l,mF,l,*h,*r"))] + "TARGET_THUMB1 + && ( s_register_operand (operands[0], HFmode) + || s_register_operand (operands[1], HFmode))" + "* + switch (which_alternative) + { + case 1: + { + rtx addr; + gcc_assert (MEM_P (operands[1])); + addr = XEXP (operands[1], 0); + if (GET_CODE (addr) == LABEL_REF + || (GET_CODE (addr) == CONST + && GET_CODE (XEXP (addr, 0)) == PLUS + && GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF + && CONST_INT_P (XEXP (XEXP (addr, 0), 1)))) + { + /* Constant pool entry. */ + return \"ldr\\t%0, %1\"; + } + return \"ldrh\\t%0, %1\"; + } + case 2: return \"strh\\t%1, %0\"; + default: return \"mov\\t%0, %1\"; + } + " + [(set_attr "length" "2") + (set_attr "type" "mov_reg,load1,store1,mov_reg,mov_reg") + (set_attr "pool_range" "*,1018,*,*,*") + (set_attr "conds" "clob,nocond,nocond,nocond,nocond")]) +;;; ??? This should have alternatives for constants. +(define_insn "*thumb1_movsf_insn" + [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h") + (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))] + "TARGET_THUMB1 + && ( register_operand (operands[0], SFmode) + || register_operand (operands[1], SFmode))" + "@ + add\\t%0, %1, #0 + ldmia\\t%1, {%0} + stmia\\t%0, {%1} + ldr\\t%0, %1 + str\\t%1, %0 + mov\\t%0, %1 + mov\\t%0, %1" + [(set_attr "length" "2") + (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")] +) + +;;; ??? This should have alternatives for constants. +;;; ??? This was originally identical to the movdi_insn pattern. +;;; ??? The 'F' constraint looks funny, but it should always be replaced by +;;; thumb_reorg with a memory reference. +(define_insn "*thumb_movdf_insn" + [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r") + (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))] + "TARGET_THUMB1 + && ( register_operand (operands[0], DFmode) + || register_operand (operands[1], DFmode))" + "* + switch (which_alternative) + { + default: + case 0: + if (REGNO (operands[1]) == REGNO (operands[0]) + 1) + return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\"; + return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\"; + case 1: + return \"ldmia\\t%1, {%0, %H0}\"; + case 2: + return \"stmia\\t%0, {%1, %H1}\"; + case 3: + return thumb_load_double_from_address (operands); + case 4: + operands[2] = gen_rtx_MEM (SImode, + plus_constant (Pmode, + XEXP (operands[0], 0), 4)); + output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands); + return \"\"; + case 5: + if (REGNO (operands[1]) == REGNO (operands[0]) + 1) + return \"mov\\t%0, %1\;mov\\t%H0, %H1\"; + return \"mov\\t%H0, %H1\;mov\\t%0, %1\"; + } + " + [(set_attr "length" "4,2,2,6,4,4") + (set_attr "type" "multiple,load2,store2,load2,store2,multiple") + (set_attr "pool_range" "*,*,*,1018,*,*")] +) + + +;; Thumb block-move insns + +(define_insn "movmem12b" + [(set (mem:SI (match_operand:SI 2 "register_operand" "0")) + (mem:SI (match_operand:SI 3 "register_operand" "1"))) + (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) + (mem:SI (plus:SI (match_dup 3) (const_int 4)))) + (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) + (mem:SI (plus:SI (match_dup 3) (const_int 8)))) + (set (match_operand:SI 0 "register_operand" "=l") + (plus:SI (match_dup 2) (const_int 12))) + (set (match_operand:SI 1 "register_operand" "=l") + (plus:SI (match_dup 3) (const_int 12))) + (clobber (match_scratch:SI 4 "=&l")) + (clobber (match_scratch:SI 5 "=&l")) + (clobber (match_scratch:SI 6 "=&l"))] + "TARGET_THUMB1" + "* return thumb_output_move_mem_multiple (3, operands);" + [(set_attr "length" "4") + ; This isn't entirely accurate... It loads as well, but in terms of + ; scheduling the following insn it is better to consider it as a store + (set_attr "type" "store3")] +) + +(define_insn "movmem8b" + [(set (mem:SI (match_operand:SI 2 "register_operand" "0")) + (mem:SI (match_operand:SI 3 "register_operand" "1"))) + (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) + (mem:SI (plus:SI (match_dup 3) (const_int 4)))) + (set (match_operand:SI 0 "register_operand" "=l") + (plus:SI (match_dup 2) (const_int 8))) + (set (match_operand:SI 1 "register_operand" "=l") + (plus:SI (match_dup 3) (const_int 8))) + (clobber (match_scratch:SI 4 "=&l")) + (clobber (match_scratch:SI 5 "=&l"))] + "TARGET_THUMB1" + "* return thumb_output_move_mem_multiple (2, operands);" + [(set_attr "length" "4") + ; This isn't entirely accurate... It loads as well, but in terms of + ; scheduling the following insn it is better to consider it as a store + (set_attr "type" "store2")] +) + + +;; A pattern to recognize a special situation and optimize for it. +;; On the thumb, zero-extension from memory is preferrable to sign-extension +;; due to the available addressing modes. Hence, convert a signed comparison +;; with zero into an unsigned comparison with 127 if possible. +(define_expand "cbranchqi4" + [(set (pc) (if_then_else + (match_operator 0 "lt_ge_comparison_operator" + [(match_operand:QI 1 "memory_operand" "") + (match_operand:QI 2 "const0_operand" "")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "TARGET_THUMB1" +{ + rtx xops[4]; + xops[1] = gen_reg_rtx (SImode); + emit_insn (gen_zero_extendqisi2 (xops[1], operands[1])); + xops[2] = GEN_INT (127); + xops[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]) == GE ? LEU : GTU, + VOIDmode, xops[1], xops[2]); + xops[3] = operands[3]; + emit_insn (gen_cbranchsi4 (xops[0], xops[1], xops[2], xops[3])); + DONE; +}) + +(define_insn "cbranchsi4_insn" + [(set (pc) (if_then_else + (match_operator 0 "arm_comparison_operator" + [(match_operand:SI 1 "s_register_operand" "l,l*h") + (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "TARGET_THUMB1" +{ + rtx t = cfun->machine->thumb1_cc_insn; + if (t != NULL_RTX) + { + if (!rtx_equal_p (cfun->machine->thumb1_cc_op0, operands[1]) + || !rtx_equal_p (cfun->machine->thumb1_cc_op1, operands[2])) + t = NULL_RTX; + if (cfun->machine->thumb1_cc_mode == CC_NOOVmode) + { + if (!noov_comparison_operator (operands[0], VOIDmode)) + t = NULL_RTX; + } + else if (cfun->machine->thumb1_cc_mode != CCmode) + t = NULL_RTX; + } + if (t == NULL_RTX) + { + output_asm_insn ("cmp\t%1, %2", operands); + cfun->machine->thumb1_cc_insn = insn; + cfun->machine->thumb1_cc_op0 = operands[1]; + cfun->machine->thumb1_cc_op1 = operands[2]; + cfun->machine->thumb1_cc_mode = CCmode; + } + else + /* Ensure we emit the right type of condition code on the jump. */ + XEXP (operands[0], 0) = gen_rtx_REG (cfun->machine->thumb1_cc_mode, + CC_REGNUM); + + switch (get_attr_length (insn)) + { + case 4: return \"b%d0\\t%l3\"; + case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; + default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; + } +} + [(set (attr "far_jump") + (if_then_else + (eq_attr "length" "8") + (const_string "yes") + (const_string "no"))) + (set (attr "length") + (if_then_else + (and (ge (minus (match_dup 3) (pc)) (const_int -250)) + (le (minus (match_dup 3) (pc)) (const_int 256))) + (const_int 4) + (if_then_else + (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)))) + (set_attr "type" "multiple")] +) + +(define_insn "cbranchsi4_scratch" + [(set (pc) (if_then_else + (match_operator 4 "arm_comparison_operator" + [(match_operand:SI 1 "s_register_operand" "l,0") + (match_operand:SI 2 "thumb1_cmpneg_operand" "L,J")]) + (label_ref (match_operand 3 "" "")) + (pc))) + (clobber (match_scratch:SI 0 "=l,l"))] + "TARGET_THUMB1" + "* + output_asm_insn (\"add\\t%0, %1, #%n2\", operands); + + switch (get_attr_length (insn)) + { + case 4: return \"b%d4\\t%l3\"; + case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; + default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; + } + " + [(set (attr "far_jump") + (if_then_else + (eq_attr "length" "8") + (const_string "yes") + (const_string "no"))) + (set (attr "length") + (if_then_else + (and (ge (minus (match_dup 3) (pc)) (const_int -250)) + (le (minus (match_dup 3) (pc)) (const_int 256))) + (const_int 4) + (if_then_else + (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)))) + (set_attr "type" "multiple")] +) + +(define_insn "*negated_cbranchsi4" + [(set (pc) + (if_then_else + (match_operator 0 "equality_operator" + [(match_operand:SI 1 "s_register_operand" "l") + (neg:SI (match_operand:SI 2 "s_register_operand" "l"))]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "TARGET_THUMB1" + "* + output_asm_insn (\"cmn\\t%1, %2\", operands); + switch (get_attr_length (insn)) + { + case 4: return \"b%d0\\t%l3\"; + case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; + default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; + } + " + [(set (attr "far_jump") + (if_then_else + (eq_attr "length" "8") + (const_string "yes") + (const_string "no"))) + (set (attr "length") + (if_then_else + (and (ge (minus (match_dup 3) (pc)) (const_int -250)) + (le (minus (match_dup 3) (pc)) (const_int 256))) + (const_int 4) + (if_then_else + (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)))) + (set_attr "type" "multiple")] +) + +(define_insn "*tbit_cbranch" + [(set (pc) + (if_then_else + (match_operator 0 "equality_operator" + [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l") + (const_int 1) + (match_operand:SI 2 "const_int_operand" "i")) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc))) + (clobber (match_scratch:SI 4 "=l"))] + "TARGET_THUMB1" + "* + { + rtx op[3]; + op[0] = operands[4]; + op[1] = operands[1]; + op[2] = GEN_INT (32 - 1 - INTVAL (operands[2])); + + output_asm_insn (\"lsl\\t%0, %1, %2\", op); + switch (get_attr_length (insn)) + { + case 4: return \"b%d0\\t%l3\"; + case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; + default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; + } + }" + [(set (attr "far_jump") + (if_then_else + (eq_attr "length" "8") + (const_string "yes") + (const_string "no"))) + (set (attr "length") + (if_then_else + (and (ge (minus (match_dup 3) (pc)) (const_int -250)) + (le (minus (match_dup 3) (pc)) (const_int 256))) + (const_int 4) + (if_then_else + (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)))) + (set_attr "type" "multiple")] +) + +(define_insn "*tlobits_cbranch" + [(set (pc) + (if_then_else + (match_operator 0 "equality_operator" + [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l") + (match_operand:SI 2 "const_int_operand" "i") + (const_int 0)) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc))) + (clobber (match_scratch:SI 4 "=l"))] + "TARGET_THUMB1" + "* + { + rtx op[3]; + op[0] = operands[4]; + op[1] = operands[1]; + op[2] = GEN_INT (32 - INTVAL (operands[2])); + + output_asm_insn (\"lsl\\t%0, %1, %2\", op); + switch (get_attr_length (insn)) + { + case 4: return \"b%d0\\t%l3\"; + case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; + default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; + } + }" + [(set (attr "far_jump") + (if_then_else + (eq_attr "length" "8") + (const_string "yes") + (const_string "no"))) + (set (attr "length") + (if_then_else + (and (ge (minus (match_dup 3) (pc)) (const_int -250)) + (le (minus (match_dup 3) (pc)) (const_int 256))) + (const_int 4) + (if_then_else + (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)))) + (set_attr "type" "multiple")] +) + +(define_insn "*tstsi3_cbranch" + [(set (pc) + (if_then_else + (match_operator 3 "equality_operator" + [(and:SI (match_operand:SI 0 "s_register_operand" "%l") + (match_operand:SI 1 "s_register_operand" "l")) + (const_int 0)]) + (label_ref (match_operand 2 "" "")) + (pc)))] + "TARGET_THUMB1" + "* + { + output_asm_insn (\"tst\\t%0, %1\", operands); + switch (get_attr_length (insn)) + { + case 4: return \"b%d3\\t%l2\"; + case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\"; + default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\"; + } + }" + [(set (attr "far_jump") + (if_then_else + (eq_attr "length" "8") + (const_string "yes") + (const_string "no"))) + (set (attr "length") + (if_then_else + (and (ge (minus (match_dup 2) (pc)) (const_int -250)) + (le (minus (match_dup 2) (pc)) (const_int 256))) + (const_int 4) + (if_then_else + (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)))) + (set_attr "type" "multiple")] +) + +(define_insn "*cbranchne_decr1" + [(set (pc) + (if_then_else (match_operator 3 "equality_operator" + [(match_operand:SI 2 "s_register_operand" "l,l,1,l") + (const_int 0)]) + (label_ref (match_operand 4 "" "")) + (pc))) + (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m") + (plus:SI (match_dup 2) (const_int -1))) + (clobber (match_scratch:SI 1 "=X,l,&l,&l"))] + "TARGET_THUMB1" + "* + { + rtx cond[2]; + cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE + ? GEU : LTU), + VOIDmode, operands[2], const1_rtx); + cond[1] = operands[4]; + + if (which_alternative == 0) + output_asm_insn (\"sub\\t%0, %2, #1\", operands); + else if (which_alternative == 1) + { + /* We must provide an alternative for a hi reg because reload + cannot handle output reloads on a jump instruction, but we + can't subtract into that. Fortunately a mov from lo to hi + does not clobber the condition codes. */ + output_asm_insn (\"sub\\t%1, %2, #1\", operands); + output_asm_insn (\"mov\\t%0, %1\", operands); + } + else + { + /* Similarly, but the target is memory. */ + output_asm_insn (\"sub\\t%1, %2, #1\", operands); + output_asm_insn (\"str\\t%1, %0\", operands); + } + + switch (get_attr_length (insn) - (which_alternative ? 2 : 0)) + { + case 4: + output_asm_insn (\"b%d0\\t%l1\", cond); + return \"\"; + case 6: + output_asm_insn (\"b%D0\\t.LCB%=\", cond); + return \"b\\t%l4\\t%@long jump\\n.LCB%=:\"; + default: + output_asm_insn (\"b%D0\\t.LCB%=\", cond); + return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\"; + } + } + " + [(set (attr "far_jump") + (if_then_else + (ior (and (eq (symbol_ref ("which_alternative")) + (const_int 0)) + (eq_attr "length" "8")) + (eq_attr "length" "10")) + (const_string "yes") + (const_string "no"))) + (set_attr_alternative "length" + [ + ;; Alternative 0 + (if_then_else + (and (ge (minus (match_dup 4) (pc)) (const_int -250)) + (le (minus (match_dup 4) (pc)) (const_int 256))) + (const_int 4) + (if_then_else + (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))) + ;; Alternative 1 + (if_then_else + (and (ge (minus (match_dup 4) (pc)) (const_int -248)) + (le (minus (match_dup 4) (pc)) (const_int 256))) + (const_int 6) + (if_then_else + (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))) + ;; Alternative 2 + (if_then_else + (and (ge (minus (match_dup 4) (pc)) (const_int -248)) + (le (minus (match_dup 4) (pc)) (const_int 256))) + (const_int 6) + (if_then_else + (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))) + ;; Alternative 3 + (if_then_else + (and (ge (minus (match_dup 4) (pc)) (const_int -248)) + (le (minus (match_dup 4) (pc)) (const_int 256))) + (const_int 6) + (if_then_else + (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)))]) + (set_attr "type" "multiple")] +) + +(define_insn "*addsi3_cbranch" + [(set (pc) + (if_then_else + (match_operator 4 "arm_comparison_operator" + [(plus:SI + (match_operand:SI 2 "s_register_operand" "%0,l,*l,1,1,1") + (match_operand:SI 3 "reg_or_int_operand" "IJ,lL,*l,lIJ,lIJ,lIJ")) + (const_int 0)]) + (label_ref (match_operand 5 "" "")) + (pc))) + (set + (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m") + (plus:SI (match_dup 2) (match_dup 3))) + (clobber (match_scratch:SI 1 "=X,X,l,l,&l,&l"))] + "TARGET_THUMB1 + && (GET_CODE (operands[4]) == EQ + || GET_CODE (operands[4]) == NE + || GET_CODE (operands[4]) == GE + || GET_CODE (operands[4]) == LT)" + "* + { + rtx cond[3]; + + cond[0] = (which_alternative < 2) ? operands[0] : operands[1]; + cond[1] = operands[2]; + cond[2] = operands[3]; + + if (CONST_INT_P (cond[2]) && INTVAL (cond[2]) < 0) + output_asm_insn (\"sub\\t%0, %1, #%n2\", cond); + else + output_asm_insn (\"add\\t%0, %1, %2\", cond); + + if (which_alternative >= 2 + && which_alternative < 4) + output_asm_insn (\"mov\\t%0, %1\", operands); + else if (which_alternative >= 4) + output_asm_insn (\"str\\t%1, %0\", operands); + + switch (get_attr_length (insn) - ((which_alternative >= 2) ? 2 : 0)) + { + case 4: + return \"b%d4\\t%l5\"; + case 6: + return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\"; + default: + return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\"; + } + } + " + [(set (attr "far_jump") + (if_then_else + (ior (and (lt (symbol_ref ("which_alternative")) + (const_int 2)) + (eq_attr "length" "8")) + (eq_attr "length" "10")) + (const_string "yes") + (const_string "no"))) + (set (attr "length") + (if_then_else + (lt (symbol_ref ("which_alternative")) + (const_int 2)) + (if_then_else + (and (ge (minus (match_dup 5) (pc)) (const_int -250)) + (le (minus (match_dup 5) (pc)) (const_int 256))) + (const_int 4) + (if_then_else + (and (ge (minus (match_dup 5) (pc)) (const_int -2040)) + (le (minus (match_dup 5) (pc)) (const_int 2048))) + (const_int 6) + (const_int 8))) + (if_then_else + (and (ge (minus (match_dup 5) (pc)) (const_int -248)) + (le (minus (match_dup 5) (pc)) (const_int 256))) + (const_int 6) + (if_then_else + (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))))) + (set_attr "type" "multiple")] +) + +(define_insn "*addsi3_cbranch_scratch" + [(set (pc) + (if_then_else + (match_operator 3 "arm_comparison_operator" + [(plus:SI + (match_operand:SI 1 "s_register_operand" "%l,l,l,0") + (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ")) + (const_int 0)]) + (label_ref (match_operand 4 "" "")) + (pc))) + (clobber (match_scratch:SI 0 "=X,X,l,l"))] + "TARGET_THUMB1 + && (GET_CODE (operands[3]) == EQ + || GET_CODE (operands[3]) == NE + || GET_CODE (operands[3]) == GE + || GET_CODE (operands[3]) == LT)" + "* + { + switch (which_alternative) + { + case 0: + output_asm_insn (\"cmp\t%1, #%n2\", operands); + break; + case 1: + output_asm_insn (\"cmn\t%1, %2\", operands); + break; + case 2: + if (INTVAL (operands[2]) < 0) + output_asm_insn (\"sub\t%0, %1, %2\", operands); + else + output_asm_insn (\"add\t%0, %1, %2\", operands); + break; + case 3: + if (INTVAL (operands[2]) < 0) + output_asm_insn (\"sub\t%0, %0, %2\", operands); + else + output_asm_insn (\"add\t%0, %0, %2\", operands); + break; + } + + switch (get_attr_length (insn)) + { + case 4: + return \"b%d3\\t%l4\"; + case 6: + return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\"; + default: + return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\"; + } + } + " + [(set (attr "far_jump") + (if_then_else + (eq_attr "length" "8") + (const_string "yes") + (const_string "no"))) + (set (attr "length") + (if_then_else + (and (ge (minus (match_dup 4) (pc)) (const_int -250)) + (le (minus (match_dup 4) (pc)) (const_int 256))) + (const_int 4) + (if_then_else + (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)))) + (set_attr "type" "multiple")] +) + +(define_insn "*thumb_cmpdi_zero" + [(set (reg:CC_Z CC_REGNUM) + (compare:CC_Z (match_operand:DI 0 "s_register_operand" "l") + (const_int 0))) + (clobber (match_scratch:SI 1 "=l"))] + "TARGET_THUMB1" + "orr\\t%1, %Q0, %R0" + [(set_attr "conds" "set") + (set_attr "length" "2") + (set_attr "type" "logics_reg")] +) + +(define_expand "cstoresi_eq0_thumb1" + [(parallel + [(set (match_operand:SI 0 "s_register_operand" "") + (eq:SI (match_operand:SI 1 "s_register_operand" "") + (const_int 0))) + (clobber (match_dup:SI 2))])] + "TARGET_THUMB1" + "operands[2] = gen_reg_rtx (SImode);" +) + +(define_expand "cstoresi_ne0_thumb1" + [(parallel + [(set (match_operand:SI 0 "s_register_operand" "") + (ne:SI (match_operand:SI 1 "s_register_operand" "") + (const_int 0))) + (clobber (match_dup:SI 2))])] + "TARGET_THUMB1" + "operands[2] = gen_reg_rtx (SImode);" +) + +(define_insn "*cstoresi_eq0_thumb1_insn" + [(set (match_operand:SI 0 "s_register_operand" "=&l,l") + (eq:SI (match_operand:SI 1 "s_register_operand" "l,0") + (const_int 0))) + (clobber (match_operand:SI 2 "s_register_operand" "=X,l"))] + "TARGET_THUMB1" + "@ + neg\\t%0, %1\;adc\\t%0, %0, %1 + neg\\t%2, %1\;adc\\t%0, %1, %2" + [(set_attr "length" "4") + (set_attr "type" "multiple")] +) + +(define_insn "*cstoresi_ne0_thumb1_insn" + [(set (match_operand:SI 0 "s_register_operand" "=l") + (ne:SI (match_operand:SI 1 "s_register_operand" "0") + (const_int 0))) + (clobber (match_operand:SI 2 "s_register_operand" "=l"))] + "TARGET_THUMB1" + "sub\\t%2, %1, #1\;sbc\\t%0, %1, %2" + [(set_attr "length" "4")] +) + +;; Used as part of the expansion of thumb ltu and gtu sequences +(define_insn "cstoresi_nltu_thumb1" + [(set (match_operand:SI 0 "s_register_operand" "=l,l") + (neg:SI (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h") + (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 "type" "multiple")] +) + +(define_insn_and_split "cstoresi_ltu_thumb1" + [(set (match_operand:SI 0 "s_register_operand" "=l,l") + (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h") + (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")))] + "TARGET_THUMB1" + "#" + "TARGET_THUMB1" + [(set (match_dup 3) + (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 "type" "multiple")] +) + +;; Used as part of the expansion of thumb les sequence. +(define_insn "thumb1_addsi3_addgeu" + [(set (match_operand:SI 0 "s_register_operand" "=l") + (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") + (match_operand:SI 2 "s_register_operand" "l")) + (geu:SI (match_operand:SI 3 "s_register_operand" "l") + (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 "type" "multiple")] +) + + +(define_insn "*thumb_jump" + [(set (pc) + (label_ref (match_operand 0 "" "")))] + "TARGET_THUMB1" + "* + if (get_attr_length (insn) == 2) + return \"b\\t%l0\"; + return \"bl\\t%l0\\t%@ far jump\"; + " + [(set (attr "far_jump") + (if_then_else + (eq_attr "length" "4") + (const_string "yes") + (const_string "no"))) + (set (attr "length") + (if_then_else + (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))) + (set_attr "type" "branch")] +) + +(define_insn "*call_reg_thumb1_v5" + [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r")) + (match_operand 1 "" "")) + (use (match_operand 2 "" "")) + (clobber (reg:SI LR_REGNUM))] + "TARGET_THUMB1 && arm_arch5 && !SIBLING_CALL_P (insn)" + "blx\\t%0" + [(set_attr "length" "2") + (set_attr "type" "call")] +) + +(define_insn "*call_reg_thumb1" + [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r")) + (match_operand 1 "" "")) + (use (match_operand 2 "" "")) + (clobber (reg:SI LR_REGNUM))] + "TARGET_THUMB1 && !arm_arch5 && !SIBLING_CALL_P (insn)" + "* + { + if (!TARGET_CALLER_INTERWORKING) + return thumb_call_via_reg (operands[0]); + else if (operands[1] == const0_rtx) + return \"bl\\t%__interwork_call_via_%0\"; + else if (frame_pointer_needed) + return \"bl\\t%__interwork_r7_call_via_%0\"; + else + return \"bl\\t%__interwork_r11_call_via_%0\"; + }" + [(set_attr "type" "call")] +) + +(define_insn "*call_value_reg_thumb1_v5" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:SI 1 "register_operand" "l*r")) + (match_operand 2 "" ""))) + (use (match_operand 3 "" "")) + (clobber (reg:SI LR_REGNUM))] + "TARGET_THUMB1 && arm_arch5" + "blx\\t%1" + [(set_attr "length" "2") + (set_attr "type" "call")] +) + +(define_insn "*call_value_reg_thumb1" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:SI 1 "register_operand" "l*r")) + (match_operand 2 "" ""))) + (use (match_operand 3 "" "")) + (clobber (reg:SI LR_REGNUM))] + "TARGET_THUMB1 && !arm_arch5" + "* + { + if (!TARGET_CALLER_INTERWORKING) + return thumb_call_via_reg (operands[1]); + else if (operands[2] == const0_rtx) + return \"bl\\t%__interwork_call_via_%1\"; + else if (frame_pointer_needed) + return \"bl\\t%__interwork_r7_call_via_%1\"; + else + return \"bl\\t%__interwork_r11_call_via_%1\"; + }" + [(set_attr "type" "call")] +) + +(define_insn "*call_insn" + [(call (mem:SI (match_operand:SI 0 "" "")) + (match_operand:SI 1 "" "")) + (use (match_operand 2 "" "")) + (clobber (reg:SI LR_REGNUM))] + "TARGET_THUMB1 + && GET_CODE (operands[0]) == SYMBOL_REF + && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))" + "bl\\t%a0" + [(set_attr "length" "4") + (set_attr "type" "call")] +) + +(define_insn "*call_value_insn" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand 1 "" "")) + (match_operand 2 "" ""))) + (use (match_operand 3 "" "")) + (clobber (reg:SI LR_REGNUM))] + "TARGET_THUMB1 + && GET_CODE (operands[1]) == SYMBOL_REF + && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))" + "bl\\t%a1" + [(set_attr "length" "4") + (set_attr "type" "call")] +) + +(define_expand "thumb1_casesi_internal_pic" + [(match_operand:SI 0 "s_register_operand" "") + (match_operand:SI 1 "thumb1_cmp_operand" "") + (match_operand 2 "" "") + (match_operand 3 "" "")] + "TARGET_THUMB1" + { + rtx reg0; + rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[1]); + emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[1], + operands[3])); + reg0 = gen_rtx_REG (SImode, 0); + emit_move_insn (reg0, operands[0]); + emit_jump_insn (gen_thumb1_casesi_dispatch (operands[2]/*, operands[3]*/)); + DONE; + } +) + +(define_insn "thumb1_casesi_dispatch" + [(parallel [(set (pc) (unspec [(reg:SI 0) + (label_ref (match_operand 0 "" "")) +;; (label_ref (match_operand 1 "" "")) +] + UNSPEC_THUMB1_CASESI)) + (clobber (reg:SI IP_REGNUM)) + (clobber (reg:SI LR_REGNUM))])] + "TARGET_THUMB1" + "* return thumb1_output_casesi(operands);" + [(set_attr "length" "4") + (set_attr "type" "multiple")] +) + +;; NB Never uses BX. +(define_insn "*thumb1_indirect_jump" + [(set (pc) + (match_operand:SI 0 "register_operand" "l*r"))] + "TARGET_THUMB1" + "mov\\tpc, %0" + [(set_attr "conds" "clob") + (set_attr "length" "2") + (set_attr "type" "branch")] +) + + +(define_insn "prologue_thumb1_interwork" + [(unspec_volatile [(const_int 0)] VUNSPEC_THUMB1_INTERWORK)] + "TARGET_THUMB1" + "* return thumb1_output_interwork ();" + [(set_attr "length" "8") + (set_attr "type" "multiple")] +) + +(define_insn "*epilogue_insns" + [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)] + "TARGET_THUMB1" + "* + return thumb1_unexpanded_epilogue (); + " + ; Length is absolute worst case + [(set_attr "length" "44") + (set_attr "type" "block") + ;; We don't clobber the conditions, but the potential length of this + ;; operation is sufficient to make conditionalizing the sequence + ;; unlikely to be profitable. + (set_attr "conds" "clob")] +) + +(define_insn "consttable_1" + [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)] + "TARGET_THUMB1" + "* + making_const_table = TRUE; + assemble_integer (operands[0], 1, BITS_PER_WORD, 1); + assemble_zeros (3); + return \"\"; + " + [(set_attr "length" "4") + (set_attr "type" "no_insn")] +) + +(define_insn "consttable_2" + [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)] + "TARGET_THUMB1" + "* + making_const_table = TRUE; + gcc_assert (GET_MODE_CLASS (GET_MODE (operands[0])) != MODE_FLOAT); + assemble_integer (operands[0], 2, BITS_PER_WORD, 1); + assemble_zeros (2); + return \"\"; + " + [(set_attr "length" "4") + (set_attr "type" "no_insn")] +) + +;; Miscellaneous Thumb patterns +(define_expand "tablejump" + [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "")) + (use (label_ref (match_operand 1 "" "")))])] + "TARGET_THUMB1" + " + if (flag_pic) + { + /* Hopefully, CSE will eliminate this copy. */ + rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1])); + rtx reg2 = gen_reg_rtx (SImode); + + emit_insn (gen_addsi3 (reg2, operands[0], reg1)); + operands[0] = reg2; + } + " +) + +;; NB never uses BX. +(define_insn "*thumb1_tablejump" + [(set (pc) (match_operand:SI 0 "register_operand" "l*r")) + (use (label_ref (match_operand 1 "" "")))] + "TARGET_THUMB1" + "mov\\t%|pc, %0" + [(set_attr "length" "2") + (set_attr "type" "no_insn")] +) + +(define_insn_and_split "thumb_eh_return" + [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")] + VUNSPEC_EH_RETURN) + (clobber (match_scratch:SI 1 "=&l"))] + "TARGET_THUMB1" + "#" + "&& reload_completed" + [(const_int 0)] + " + { + thumb_set_return_address (operands[0], operands[1]); + DONE; + }" + [(set_attr "type" "mov_reg")] +) + diff --git a/gcc/config/arm/unknown-elf.h b/gcc/config/arm/unknown-elf.h index ec6f9a48894..56aa166272f 100644 --- a/gcc/config/arm/unknown-elf.h +++ b/gcc/config/arm/unknown-elf.h @@ -50,7 +50,7 @@ /* Return a nonzero value if DECL has a section attribute. */ #define IN_NAMED_SECTION_P(DECL) \ ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \ - && DECL_SECTION_NAME (DECL) != NULL_TREE) + && DECL_SECTION_NAME (DECL) != NULL) #undef ASM_OUTPUT_ALIGNED_BSS #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md index a8b27bcf986..9962bd3ba97 100644 --- a/gcc/config/arm/vfp.md +++ b/gcc/config/arm/vfp.md @@ -1325,7 +1325,7 @@ ;; Write Floating-point Status and Control Register. (define_insn "set_fpscr" [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_SET_FPSCR)] - "TARGET_VFP" + "TARGET_VFP && TARGET_HARD_FLOAT" "mcr\\tp10, 7, %0, cr1, cr0, 0\\t @SET_FPSCR" [(set_attr "type" "mrs")]) @@ -1333,7 +1333,7 @@ (define_insn "get_fpscr" [(set (match_operand:SI 0 "register_operand" "=r") (unspec_volatile:SI [(const_int 0)] VUNSPEC_GET_FPSCR))] - "TARGET_VFP" + "TARGET_VFP && TARGET_HARD_FLOAT" "mrc\\tp10, 7, %0, cr1, cr0, 0\\t @GET_FPSCR" [(set_attr "type" "mrs")]) diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 2c59bf3f93b..3bb2a914a33 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -368,6 +368,15 @@ "" { int i; + + // Avoid (subreg (mem)) for non-generic address spaces below. Because + // of the poor addressing capabilities of these spaces it's better to + // load them in one chunk. And it avoids PR61443. + + if (MEM_P (operands[0]) + && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[0]))) + operands[0] = copy_to_mode_reg (<MODE>mode, operands[0]); + for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i) { rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i); diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 3c6ed7b9a11..35bbace4c07 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -4760,8 +4760,8 @@ bfin_handle_l1_text_attribute (tree *node, tree name, tree ARG_UNUSED (args), /* The decl may have already been given a section attribute from a previous declaration. Ensure they match. */ - else if (DECL_SECTION_NAME (decl) != NULL_TREE - && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)), + else if (DECL_SECTION_NAME (decl) != NULL + && strcmp (DECL_SECTION_NAME (decl), ".l1.text") != 0) { error ("section of %q+D conflicts with previous declaration", @@ -4769,7 +4769,7 @@ bfin_handle_l1_text_attribute (tree *node, tree name, tree ARG_UNUSED (args), *no_add_attrs = true; } else - set_decl_section_name (decl, build_string (9, ".l1.text")); + set_decl_section_name (decl, ".l1.text"); return NULL_TREE; } @@ -4811,8 +4811,8 @@ bfin_handle_l1_data_attribute (tree *node, tree name, tree ARG_UNUSED (args), /* The decl may have already been given a section attribute from a previous declaration. Ensure they match. */ - if (DECL_SECTION_NAME (decl) != NULL_TREE - && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)), + if (DECL_SECTION_NAME (decl) != NULL + && strcmp (DECL_SECTION_NAME (decl), section_name) != 0) { error ("section of %q+D conflicts with previous declaration", @@ -4820,8 +4820,7 @@ bfin_handle_l1_data_attribute (tree *node, tree name, tree ARG_UNUSED (args), *no_add_attrs = true; } else - DECL_SECTION_NAME (decl) - = build_string (strlen (section_name) + 1, section_name); + set_decl_section_name (decl, section_name); } return NULL_TREE; @@ -4838,8 +4837,8 @@ bfin_handle_l2_attribute (tree *node, tree ARG_UNUSED (name), if (TREE_CODE (decl) == FUNCTION_DECL) { - if (DECL_SECTION_NAME (decl) != NULL_TREE - && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)), + if (DECL_SECTION_NAME (decl) != NULL + && strcmp (DECL_SECTION_NAME (decl), ".l2.text") != 0) { error ("section of %q+D conflicts with previous declaration", @@ -4847,12 +4846,12 @@ bfin_handle_l2_attribute (tree *node, tree ARG_UNUSED (name), *no_add_attrs = true; } else - set_decl_section_name (decl, build_string (9, ".l2.text")); + set_decl_section_name (decl, ".l2.text"); } else if (TREE_CODE (decl) == VAR_DECL) { - if (DECL_SECTION_NAME (decl) != NULL_TREE - && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)), + if (DECL_SECTION_NAME (decl) != NULL + && strcmp (DECL_SECTION_NAME (decl), ".l2.data") != 0) { error ("section of %q+D conflicts with previous declaration", @@ -4860,7 +4859,7 @@ bfin_handle_l2_attribute (tree *node, tree ARG_UNUSED (name), *no_add_attrs = true; } else - set_decl_section_name (decl, build_string (9, ".l2.data")); + set_decl_section_name (decl, ".l2.data"); } return NULL_TREE; diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c index 90a37481290..7fa60b96e1d 100644 --- a/gcc/config/c6x/c6x.c +++ b/gcc/config/c6x/c6x.c @@ -868,7 +868,7 @@ c6x_in_small_data_p (const_tree exp) if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp)) { - const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp)); + const char *section = DECL_SECTION_NAME (exp); if (strcmp (section, ".neardata") == 0 || strncmp (section, ".neardata.", 10) == 0 @@ -1060,7 +1060,7 @@ c6x_elf_unique_section (tree decl, int reloc) string = ACONCAT ((linkonce, prefix, ".", name, NULL)); - set_decl_section_name (decl, build_string (strlen (string), string)); + set_decl_section_name (decl, string); return; } default_unique_section (decl, reloc); diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index a2c87491d21..d13983ce811 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -3604,7 +3604,7 @@ darwin_function_section (tree decl, enum node_frequency freq, /* If there is a specified section name, we should not be trying to override. */ - if (decl && DECL_SECTION_NAME (decl) != NULL_TREE) + if (decl && DECL_SECTION_NAME (decl) != NULL) return get_named_section (decl, NULL, 0); /* We always put unlikely executed stuff in the cold section. */ diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index 98992b29db8..98a5336a995 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -263,7 +263,7 @@ static frv_stack_t *frv_stack_cache = (frv_stack_t *)0; static void frv_option_override (void); static bool frv_legitimate_address_p (enum machine_mode, rtx, bool); static int frv_default_flags_for_cpu (void); -static int frv_string_begins_with (const_tree, const char *); +static int frv_string_begins_with (const char *, const char *); static FRV_INLINE bool frv_small_data_reloc_p (rtx, int); static void frv_print_operand (FILE *, rtx, int); static void frv_print_operand_address (FILE *, rtx); @@ -773,13 +773,12 @@ frv_option_override (void) /* Return true if NAME (a STRING_CST node) begins with PREFIX. */ static int -frv_string_begins_with (const_tree name, const char *prefix) +frv_string_begins_with (const char *name, const char *prefix) { const int prefix_len = strlen (prefix); /* Remember: NAME's length includes the null terminator. */ - return (TREE_STRING_LENGTH (name) > prefix_len - && strncmp (TREE_STRING_POINTER (name), prefix, prefix_len) == 0); + return (strncmp (name, prefix, prefix_len) == 0); } /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */ @@ -9475,7 +9474,7 @@ static bool frv_in_small_data_p (const_tree decl) { HOST_WIDE_INT size; - const_tree section_name; + const char *section_name; /* Don't apply the -G flag to internal compiler structures. We should leave such structures in the main data section, partly diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index 3c90340aaed..998afd510be 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -5461,7 +5461,7 @@ h8300_handle_eightbit_data_attribute (tree *node, tree name, if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) { - set_decl_section_name (decl, build_string (7, ".eight")); + set_decl_section_name (decl, ".eight"); } else { @@ -5485,7 +5485,7 @@ h8300_handle_tiny_data_attribute (tree *node, tree name, if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) { - set_decl_section_name (decl, build_string (6, ".tiny")); + set_decl_section_name (decl, ".tiny"); } else { diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 2050aaf005c..77d54e5bcb7 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5028,7 +5028,7 @@ ix86_in_large_data_p (tree exp) if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp)) { - const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp)); + const char *section = DECL_SECTION_NAME (exp); if (strcmp (section, ".ldata") == 0 || strcmp (section, ".lbss") == 0) return true; @@ -5193,7 +5193,7 @@ x86_64_elf_unique_section (tree decl, int reloc) string = ACONCAT ((linkonce, prefix, ".", name, NULL)); - set_decl_section_name (decl, build_string (strlen (string), string)); + set_decl_section_name (decl, string); return; } } @@ -17764,8 +17764,7 @@ ix86_emit_cfi () static unsigned int increase_distance (rtx prev, rtx next, unsigned int distance) { - df_ref *use_rec; - df_ref *def_rec; + df_ref def, use; if (!prev || !next) return distance + (distance & 1) + 2; @@ -17773,10 +17772,10 @@ increase_distance (rtx prev, rtx next, unsigned int distance) if (!DF_INSN_USES (next) || !DF_INSN_DEFS (prev)) return distance + 1; - for (use_rec = DF_INSN_USES (next); *use_rec; use_rec++) - for (def_rec = DF_INSN_DEFS (prev); *def_rec; def_rec++) - if (!DF_REF_IS_ARTIFICIAL (*def_rec) - && DF_REF_REGNO (*use_rec) == DF_REF_REGNO (*def_rec)) + FOR_EACH_INSN_USE (use, next) + FOR_EACH_INSN_DEF (def, prev) + if (!DF_REF_IS_ARTIFICIAL (def) + && DF_REF_REGNO (use) == DF_REF_REGNO (def)) return distance + (distance & 1) + 2; return distance + 1; @@ -17789,16 +17788,14 @@ static bool insn_defines_reg (unsigned int regno1, unsigned int regno2, rtx insn) { - df_ref *def_rec; + df_ref def; - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - if (DF_REF_REG_DEF_P (*def_rec) - && !DF_REF_IS_ARTIFICIAL (*def_rec) - && (regno1 == DF_REF_REGNO (*def_rec) - || regno2 == DF_REF_REGNO (*def_rec))) - { - return true; - } + FOR_EACH_INSN_DEF (def, insn) + if (DF_REF_REG_DEF_P (def) + && !DF_REF_IS_ARTIFICIAL (def) + && (regno1 == DF_REF_REGNO (def) + || regno2 == DF_REF_REGNO (def))) + return true; return false; } @@ -17809,10 +17806,10 @@ insn_defines_reg (unsigned int regno1, unsigned int regno2, static bool insn_uses_reg_mem (unsigned int regno, rtx insn) { - df_ref *use_rec; + df_ref use; - for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) - if (DF_REF_REG_MEM_P (*use_rec) && regno == DF_REF_REGNO (*use_rec)) + FOR_EACH_INSN_USE (use, insn) + if (DF_REF_REG_MEM_P (use) && regno == DF_REF_REGNO (use)) return true; return false; @@ -18144,15 +18141,15 @@ static bool ix86_ok_to_clobber_flags (rtx insn) { basic_block bb = BLOCK_FOR_INSN (insn); - df_ref *use; + df_ref use; bitmap live; while (insn) { if (NONDEBUG_INSN_P (insn)) { - for (use = DF_INSN_USES (insn); *use; use++) - if (DF_REF_REG_USE_P (*use) && DF_REF_REGNO (*use) == FLAGS_REG) + FOR_EACH_INSN_USE (use, insn) + if (DF_REF_REG_USE_P (use) && DF_REF_REGNO (use) == FLAGS_REG) return false; if (insn_defines_reg (FLAGS_REG, INVALID_REGNUM, insn)) @@ -23835,7 +23832,7 @@ decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT expected_size, { const struct stringop_algs * algs; bool optimize_for_speed; - int max = -1; + int max = 0; const struct processor_costs *cost; int i; bool any_alg_usable_p = false; @@ -23873,7 +23870,7 @@ decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT expected_size, /* If expected size is not known but max size is small enough so inline version is a win, set expected size into the range. */ - if (max > 1 && (unsigned HOST_WIDE_INT) max >= max_size + if (((max > 1 && (unsigned HOST_WIDE_INT) max >= max_size) || max == -1) && expected_size == -1) expected_size = min_size / 2 + max_size / 2; @@ -23962,7 +23959,7 @@ decide_alg (HOST_WIDE_INT count, HOST_WIDE_INT expected_size, *dynamic_check = 128; return loop_1_byte; } - if (max == -1) + if (max <= 0) max = 4096; alg = decide_alg (count, max / 2, min_size, max_size, memset, zero_memset, dynamic_check, noalign); @@ -45282,8 +45279,13 @@ ix86_expand_sse2_mulvxdi3 (rtx op0, rtx op1, rtx op2) /* t4: ((B*E)+(A*F))<<32, ((D*G)+(C*H))<<32 */ emit_insn (gen_ashlv2di3 (t4, t3, GEN_INT (32))); - /* op0: (((B*E)+(A*F))<<32)+(B*F), (((D*G)+(C*H))<<32)+(D*H) */ - emit_insn (gen_xop_pmacsdql (op0, op1, op2, t4)); + /* Multiply lower parts and add all */ + t5 = gen_reg_rtx (V2DImode); + emit_insn (gen_vec_widen_umult_even_v4si (t5, + gen_lowpart (V4SImode, op1), + gen_lowpart (V4SImode, op2))); + op0 = expand_binop (mode, add_optab, t5, t4, op0, 1, OPTAB_DIRECT); + } else { @@ -46502,7 +46504,7 @@ ix86_spill_class (reg_class_t rclass, enum machine_mode mode) { if (TARGET_SSE && TARGET_GENERAL_REGS_SSE_SPILL && ! TARGET_MMX && (mode == SImode || (TARGET_64BIT && mode == DImode)) - && INTEGER_CLASS_P (rclass)) + && rclass != NO_REGS && INTEGER_CLASS_P (rclass)) return ALL_SSE_REGS; return NO_REGS; } diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index ee22375c227..10c0b003f8d 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -438,7 +438,7 @@ i386_pe_unique_section (tree decl, int reloc) string = XALLOCAVEC (char, len + 1); sprintf (string, "%s%s", prefix, name); - set_decl_section_name (decl, build_string (len, string)); + set_decl_section_name (decl, string); } /* Local and global relocs can be placed always into readonly memory for diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index cb9a9ca8af8..de486c6dfac 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -9893,7 +9893,7 @@ ia64_in_small_data_p (const_tree exp) if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp)) { - const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp)); + const char *section = DECL_SECTION_NAME (exp); if (strcmp (section, ".sdata") == 0 || strncmp (section, ".sdata.", 7) == 0 diff --git a/gcc/config/lm32/lm32.c b/gcc/config/lm32/lm32.c index fe3dcf4057f..bfba0489974 100644 --- a/gcc/config/lm32/lm32.c +++ b/gcc/config/lm32/lm32.c @@ -791,7 +791,7 @@ lm32_in_small_data_p (const_tree exp) if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp)) { - const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp)); + const char *section = DECL_SECTION_NAME (exp); if (strcmp (section, ".sdata") == 0 || strcmp (section, ".sbss") == 0) return true; } diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index 0d7dcee1bc9..69b9c55e534 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -854,7 +854,7 @@ m32c_cannot_change_mode_class (enum machine_mode from, #define A0_OR_PSEUDO(x) (IS_REG(x, A0_REGNO) || REGNO (x) >= FIRST_PSEUDO_REGISTER) -/* Implements EXTRA_CONSTRAINT_STR (see next function too). 'S' is +/* Implements matching for constraints (see next function too). 'S' is for memory constraints, plus "Rpa" for PARALLEL rtx's we use for call return values. */ bool diff --git a/gcc/config/m32c/t-m32c b/gcc/config/m32c/t-m32c index 36e6a6312f8..00162e9a89a 100644 --- a/gcc/config/m32c/t-m32c +++ b/gcc/config/m32c/t-m32c @@ -20,7 +20,7 @@ # target-specific files -md_file = md +md_file = $(srcdir)/common.md md MD_FILES = m32c constraints predicates addsub bitops blkmov cond jump minmax mov muldiv prologue shift diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c index 2286a857439..35c136edb99 100644 --- a/gcc/config/m32r/m32r.c +++ b/gcc/config/m32r/m32r.c @@ -463,7 +463,7 @@ m32r_encode_section_info (tree decl, rtx rtl, int first) static bool m32r_in_small_data_p (const_tree decl) { - const_tree section; + const char *section; if (TREE_CODE (decl) != VAR_DECL) return false; @@ -474,8 +474,7 @@ m32r_in_small_data_p (const_tree decl) section = DECL_SECTION_NAME (decl); if (section) { - const char *const name = TREE_STRING_POINTER (section); - if (strcmp (name, ".sdata") == 0 || strcmp (name, ".sbss") == 0) + if (strcmp (section, ".sdata") == 0 || strcmp (section, ".sbss") == 0) return true; } else diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c index f9af66b5b59..5ff8daf015e 100644 --- a/gcc/config/mcore/mcore.c +++ b/gcc/config/mcore/mcore.c @@ -3089,7 +3089,7 @@ mcore_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED) sprintf (string, "%s%s", prefix, name); - set_decl_section_name (decl, build_string (len, string)); + set_decl_section_name (decl, string); } int diff --git a/gcc/config/mep/mep.c b/gcc/config/mep/mep.c index 2f2d0faee27..853821c8771 100644 --- a/gcc/config/mep/mep.c +++ b/gcc/config/mep/mep.c @@ -4658,7 +4658,7 @@ mep_unique_section (tree decl, int reloc) sprintf (string, "%s%s", prefix, name); - set_decl_section_name (decl, build_string (len, string)); + set_decl_section_name (decl, string); } /* Given a decl, a section name, and whether the decl initializer diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c index cf2dc74cccc..0c2aec84ac2 100644 --- a/gcc/config/microblaze/microblaze.c +++ b/gcc/config/microblaze/microblaze.c @@ -3067,7 +3067,7 @@ microblaze_elf_in_small_data_p (const_tree decl) if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl)) { - const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); + const char *section = DECL_SECTION_NAME (decl); if (strcmp (section, ".sdata") == 0 || strcmp (section, ".sdata2") == 0 || strcmp (section, ".sbss") == 0 diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 0b8125a3e21..0b32a70251c 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -232,7 +232,6 @@ extern bool mips_use_pic_fn_addr_reg_p (const_rtx); extern rtx mips_expand_call (enum mips_call_type, rtx, rtx, rtx, rtx, bool); extern void mips_split_call (rtx, rtx); extern bool mips_get_pic_call_symbol (rtx *, int); -extern void mips_expand_fcc_reload (rtx, rtx, rtx); extern void mips_set_return_address (rtx, rtx); extern bool mips_move_by_pieces_p (unsigned HOST_WIDE_INT, unsigned int); extern bool mips_store_by_pieces_p (unsigned HOST_WIDE_INT, unsigned int); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 73b6963ba65..cff1d3817c7 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -6618,7 +6618,7 @@ mips16_build_function_stub (void) stubdecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, get_identifier (stubname), build_function_type_list (void_type_node, NULL_TREE)); - set_decl_section_name (stubdecl, build_string (strlen (secname), secname)); + set_decl_section_name (stubdecl, secname); DECL_RESULT (stubdecl) = build_decl (BUILTINS_LOCATION, RESULT_DECL, NULL_TREE, void_type_node); @@ -6872,7 +6872,7 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code) FUNCTION_DECL, stubid, build_function_type_list (void_type_node, NULL_TREE)); - set_decl_section_name (stubdecl, build_string (strlen (secname), secname)); + set_decl_section_name (stubdecl, secname); DECL_RESULT (stubdecl) = build_decl (BUILTINS_LOCATION, RESULT_DECL, NULL_TREE, void_type_node); @@ -7195,35 +7195,6 @@ mips_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) return true; } -/* Emit code to move general operand SRC into condition-code - register DEST given that SCRATCH is a scratch TFmode FPR. - The sequence is: - - FP1 = SRC - FP2 = 0.0f - DEST = FP2 < FP1 - - where FP1 and FP2 are single-precision FPRs taken from SCRATCH. */ - -void -mips_expand_fcc_reload (rtx dest, rtx src, rtx scratch) -{ - rtx fp1, fp2; - - /* Change the source to SFmode. */ - if (MEM_P (src)) - src = adjust_address (src, SFmode, 0); - else if (REG_P (src) || GET_CODE (src) == SUBREG) - src = gen_rtx_REG (SFmode, true_regnum (src)); - - fp1 = gen_rtx_REG (SFmode, REGNO (scratch)); - fp2 = gen_rtx_REG (SFmode, REGNO (scratch) + MAX_FPRS_PER_FMT); - - mips_emit_move (copy_rtx (fp1), src); - mips_emit_move (copy_rtx (fp2), CONST0_RTX (SFmode)); - emit_insn (gen_slt_sf (dest, fp2, fp1)); -} - /* Implement MOVE_BY_PIECES_P. */ bool @@ -8490,7 +8461,7 @@ mips_function_rodata_section (tree decl) if (decl && DECL_SECTION_NAME (decl)) { - const char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); + const char *name = DECL_SECTION_NAME (decl); if (DECL_COMDAT_GROUP (decl) && strncmp (name, ".gnu.linkonce.t.", 16) == 0) { char *rname = ASTRDUP (name); @@ -8530,7 +8501,7 @@ mips_in_small_data_p (const_tree decl) const char *name; /* Reject anything that isn't in a known small-data section. */ - name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); + name = DECL_SECTION_NAME (decl); if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0) return false; @@ -12044,10 +12015,6 @@ mips_move_to_gpr_cost (enum machine_mode mode ATTRIBUTE_UNUSED, /* MFC1, etc. */ return 4; - case ST_REGS: - /* LUI followed by MOVF. */ - return 4; - case COP0_REGS: case COP2_REGS: case COP3_REGS: @@ -12081,11 +12048,6 @@ mips_move_from_gpr_cost (enum machine_mode mode, reg_class_t to) /* MTC1, etc. */ return 4; - case ST_REGS: - /* A secondary reload through an FPR scratch. */ - return (mips_register_move_cost (mode, GENERAL_REGS, FP_REGS) - + mips_register_move_cost (mode, FP_REGS, ST_REGS)); - case COP0_REGS: case COP2_REGS: case COP3_REGS: @@ -12117,9 +12079,6 @@ mips_register_move_cost (enum machine_mode mode, if (to == FP_REGS && mips_mode_ok_for_mov_fmt_p (mode)) /* MOV.FMT. */ return 4; - if (to == ST_REGS) - /* The sequence generated by mips_expand_fcc_reload. */ - return 8; } /* Handle cases in which only one class deviates from the ideal. */ @@ -12184,23 +12143,6 @@ mips_secondary_reload_class (enum reg_class rclass, if (ACC_REG_P (regno)) return reg_class_subset_p (rclass, GR_REGS) ? NO_REGS : GR_REGS; - /* We can only copy a value to a condition code register from a - floating-point register, and even then we require a scratch - floating-point register. We can only copy a value out of a - condition-code register into a general register. */ - if (reg_class_subset_p (rclass, ST_REGS)) - { - if (in_p) - return FP_REGS; - return GP_REG_P (regno) ? NO_REGS : GR_REGS; - } - if (ST_REG_P (regno)) - { - if (!in_p) - return FP_REGS; - return reg_class_subset_p (rclass, GR_REGS) ? NO_REGS : GR_REGS; - } - if (reg_class_subset_p (rclass, FP_REGS)) { if (MEM_P (x) diff --git a/gcc/config/mmix/mmix-protos.h b/gcc/config/mmix/mmix-protos.h index 32d53f559c5..62604dfeaf5 100644 --- a/gcc/config/mmix/mmix-protos.h +++ b/gcc/config/mmix/mmix-protos.h @@ -28,7 +28,6 @@ extern int mmix_reversible_cc_mode (enum machine_mode); extern const char *mmix_text_section_asm_op (void); extern const char *mmix_data_section_asm_op (void); extern void mmix_output_quoted_string (FILE *, const char *, int); -extern void mmix_asm_output_source_line (FILE *, int); extern void mmix_asm_output_ascii (FILE *, const char *, int); extern void mmix_asm_output_label (FILE *, const char *); extern void mmix_asm_output_internal_label (FILE *, const char *); diff --git a/gcc/config/msp430/msp430.md b/gcc/config/msp430/msp430.md index d2cc0d63170..ed4eea652f9 100644 --- a/gcc/config/msp430/msp430.md +++ b/gcc/config/msp430/msp430.md @@ -1423,9 +1423,9 @@ "optimize > 2 && msp430_hwmult_type != NONE" "* if (msp430_use_f5_series_hwmult ()) - return \"PUSH.W sr { DINT { MOV.W %1, &0x04C2 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0 { POP.W sr\"; + return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x04C2 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0 { POP.W sr\"; else - return \"PUSH.W sr { DINT { MOV.W %1, &0x0132 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0 { POP.W sr\"; + return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x0132 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0 { POP.W sr\"; " ) @@ -1436,9 +1436,9 @@ "optimize > 2 && msp430_hwmult_type != NONE" "* if (msp430_use_f5_series_hwmult ()) - return \"PUSH.W sr { DINT { MOV.W %1, &0x04C0 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0 { POP.W sr\"; + return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x04C0 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0 { POP.W sr\"; else - return \"PUSH.W sr { DINT { MOV.W %1, &0x0130 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0 { POP.W sr\"; + return \"PUSH.W sr { DINT { NOP { MOV.W %1, &0x0130 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0 { POP.W sr\"; " ) @@ -1449,9 +1449,9 @@ "optimize > 2 && msp430_hwmult_type != NONE" "* if (msp430_use_f5_series_hwmult ()) - return \"PUSH.W sr { DINT { MOV.W %L1, &0x04D4 { MOV.W %H1, &0x04D6 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0 { POP.W sr\"; + return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x04D4 { MOV.W %H1, &0x04D6 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0 { POP.W sr\"; else - return \"PUSH.W sr { DINT { MOV.W %L1, &0x0144 { MOV.W %H1, &0x0146 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0 { POP.W sr\"; + return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x0144 { MOV.W %H1, &0x0146 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0 { POP.W sr\"; " ) @@ -1462,8 +1462,8 @@ "optimize > 2 && msp430_hwmult_type != NONE" "* if (msp430_use_f5_series_hwmult ()) - return \"PUSH.W sr { DINT { MOV.W %L1, &0x04D0 { MOV.W %H1, &0x04D2 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0 { POP.W sr\"; + return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x04D0 { MOV.W %H1, &0x04D2 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0 { POP.W sr\"; else - return \"PUSH.W sr { DINT { MOV.W %L1, &0x0140 { MOV.W %H1, &0x0142 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0 { POP.W sr\"; + return \"PUSH.W sr { DINT { NOP { MOV.W %L1, &0x0140 { MOV.W %H1, &0x0142 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0 { POP.W sr\"; " ) diff --git a/gcc/config/nios2/nios2.c b/gcc/config/nios2/nios2.c index ff3536d1c21..354e3d9a6e6 100644 --- a/gcc/config/nios2/nios2.c +++ b/gcc/config/nios2/nios2.c @@ -1628,7 +1628,7 @@ nios2_in_small_data_p (const_tree exp) { if (DECL_SECTION_NAME (exp)) { - const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp)); + const char *section = DECL_SECTION_NAME (exp); if (nios2_section_threshold > 0 && nios2_small_section_name_p (section)) return true; diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index fe3881e8092..e13674143fe 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -10262,10 +10262,10 @@ pa_function_section (tree decl, enum node_frequency freq, /* Force nested functions into the same section as the containing function. */ if (decl - && DECL_SECTION_NAME (decl) == NULL_TREE + && DECL_SECTION_NAME (decl) == NULL && DECL_CONTEXT (decl) != NULL_TREE && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL - && DECL_SECTION_NAME (DECL_CONTEXT (decl)) == NULL_TREE) + && DECL_SECTION_NAME (DECL_CONTEXT (decl)) == NULL) return function_section (DECL_CONTEXT (decl)); /* Otherwise, use the default function section. */ diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index ac3f0ebe74e..3f9f06bb6f2 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -955,7 +955,7 @@ do { \ /* Return a nonzero value if DECL has a section attribute. */ #define IN_NAMED_SECTION_P(DECL) \ ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \ - && DECL_SECTION_NAME (DECL) != NULL_TREE) + && DECL_SECTION_NAME (DECL) != NULL) /* Define this macro if references to a symbol must be treated differently depending on something about the variable or diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index 8e15bdf1619..220d1e97065 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -622,19 +622,12 @@ | RS6000_BTC_TERNARY), \ CODE_FOR_ ## ICODE) /* ICODE */ -/* Miscellaneous builtins. */ -#define BU_MISC_1(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_" NAME, /* NAME */ \ - RS6000_BTM_HARD_FLOAT, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_UNARY), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_MISC_2(ENUM, NAME, ATTR, ICODE) \ +/* 128-bit long double floating point builtins. */ +#define BU_LDBL128_2(ENUM, NAME, ATTR, ICODE) \ RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ "__builtin_" NAME, /* NAME */ \ - RS6000_BTM_HARD_FLOAT, /* MASK */ \ + (RS6000_BTM_HARD_FLOAT /* MASK */ \ + | RS6000_BTM_LDBL128), \ (RS6000_BTC_ ## ATTR /* ATTR */ \ | RS6000_BTC_BINARY), \ CODE_FOR_ ## ICODE) /* ICODE */ @@ -1593,10 +1586,8 @@ BU_P8V_MISC_3 (BCDSUB_OV, "bcdsub_ov", CONST, bcdsub_unordered) BU_DFP_MISC_2 (PACK_TD, "pack_dec128", CONST, packtd) BU_DFP_MISC_2 (UNPACK_TD, "unpack_dec128", CONST, unpacktd) -BU_MISC_2 (PACK_TF, "pack_longdouble", CONST, packtf) -BU_MISC_2 (UNPACK_TF, "unpack_longdouble", CONST, unpacktf) -BU_MISC_1 (UNPACK_TF_0, "longdouble_dw0", CONST, unpacktf_0) -BU_MISC_1 (UNPACK_TF_1, "longdouble_dw1", CONST, unpacktf_1) +BU_LDBL128_2 (PACK_TF, "pack_longdouble", CONST, packtf) +BU_LDBL128_2 (UNPACK_TF, "unpack_longdouble", CONST, unpacktf) BU_P7_MISC_2 (PACK_V1TI, "pack_vector_int128", CONST, packv1ti) BU_P7_MISC_2 (UNPACK_V1TI, "unpack_vector_int128", CONST, unpackv1ti) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 3e3a4878428..5711a03d097 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -3041,7 +3041,8 @@ rs6000_builtin_mask_calculate (void) | ((TARGET_CRYPTO) ? RS6000_BTM_CRYPTO : 0) | ((TARGET_HTM) ? RS6000_BTM_HTM : 0) | ((TARGET_DFP) ? RS6000_BTM_DFP : 0) - | ((TARGET_HARD_FLOAT) ? RS6000_BTM_HARD_FLOAT : 0)); + | ((TARGET_HARD_FLOAT) ? RS6000_BTM_HARD_FLOAT : 0) + | ((TARGET_LONG_DOUBLE_128) ? RS6000_BTM_LDBL128 : 0)); } /* Override command line options. Mostly we process the processor type and @@ -13589,11 +13590,15 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode) else if ((fnmask & (RS6000_BTM_DFP | RS6000_BTM_P8_VECTOR)) == (RS6000_BTM_DFP | RS6000_BTM_P8_VECTOR)) error ("Builtin function %s requires the -mhard-dfp and" - "-mpower8-vector options", name); + " -mpower8-vector options", name); else if ((fnmask & RS6000_BTM_DFP) != 0) error ("Builtin function %s requires the -mhard-dfp option", name); else if ((fnmask & RS6000_BTM_P8_VECTOR) != 0) error ("Builtin function %s requires the -mpower8-vector option", name); + else if ((fnmask & (RS6000_BTM_HARD_FLOAT | RS6000_BTM_LDBL128)) + == (RS6000_BTM_HARD_FLOAT | RS6000_BTM_LDBL128)) + error ("Builtin function %s requires the -mhard-float and" + " -mlong-double-128 options", name); else if ((fnmask & RS6000_BTM_HARD_FLOAT) != 0) error ("Builtin function %s requires the -mhard-float option", name); else @@ -28508,7 +28513,7 @@ rs6000_elf_in_small_data_p (const_tree decl) if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl)) { - const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); + const char *section = DECL_SECTION_NAME (decl); if (compare_section_name (section, ".sdata") || compare_section_name (section, ".sdata2") || compare_section_name (section, ".gnu.linkonce.s") @@ -29277,7 +29282,7 @@ rs6000_xcoff_asm_named_section (const char *name, unsigned int flags, #define IN_NAMED_SECTION(DECL) \ ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \ - && DECL_SECTION_NAME (DECL) != NULL_TREE) + && DECL_SECTION_NAME (DECL) != NULL) static section * rs6000_xcoff_select_section (tree decl, int reloc, @@ -29342,7 +29347,7 @@ rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED) name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); name = (*targetm.strip_name_encoding) (name); - set_decl_section_name (decl, build_string (strlen (name), name)); + set_decl_section_name (decl, name); } /* Select section for constant in constant pool. @@ -31413,6 +31418,7 @@ static struct rs6000_opt_mask const rs6000_builtin_mask_names[] = { "htm", RS6000_BTM_HTM, false, false }, { "hard-dfp", RS6000_BTM_DFP, false, false }, { "hard-float", RS6000_BTM_HARD_FLOAT, false, false }, + { "long-double-128", RS6000_BTM_LDBL128, false, false }, }; /* Option variables that we want to support inside attribute((target)) and diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index f01143ce21e..3bd01047688 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2508,8 +2508,8 @@ extern int frame_pointer_needed; #define RS6000_BTC_SAT RS6000_BTC_MISC /* saturate sets VSCR. */ /* Builtin targets. For now, we reuse the masks for those options that are in - target flags, and pick two random bits for SPE and paired which aren't in - target_flags. */ + target flags, and pick three random bits for SPE, paired and ldbl128 which + aren't in target_flags. */ #define RS6000_BTM_ALWAYS 0 /* Always enabled. */ #define RS6000_BTM_ALTIVEC MASK_ALTIVEC /* VMX/altivec vectors. */ #define RS6000_BTM_VSX MASK_VSX /* VSX (vector/scalar). */ @@ -2526,6 +2526,7 @@ extern int frame_pointer_needed; #define RS6000_BTM_CELL MASK_FPRND /* Target is cell powerpc. */ #define RS6000_BTM_DFP MASK_DFP /* Decimal floating point. */ #define RS6000_BTM_HARD_FLOAT MASK_SOFT_FLOAT /* Hardware floating point. */ +#define RS6000_BTM_LDBL128 MASK_MULTIPLE /* 128-bit long double. */ #define RS6000_BTM_COMMON (RS6000_BTM_ALTIVEC \ | RS6000_BTM_VSX \ @@ -2539,7 +2540,8 @@ extern int frame_pointer_needed; | RS6000_BTM_POPCNTD \ | RS6000_BTM_CELL \ | RS6000_BTM_DFP \ - | RS6000_BTM_HARD_FLOAT) + | RS6000_BTM_HARD_FLOAT \ + | RS6000_BTM_LDBL128) /* Define builtin enum index. */ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index f74d313610c..c6e85b3cd49 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -15704,26 +15704,6 @@ "" "") -;; The Advance Toolchain 7.0-3 added private builtins: __builtin_longdouble_dw0 -;; and __builtin_longdouble_dw1 to optimize glibc. Add support for these -;; builtins here. - -(define_expand "unpacktf_0" - [(set (match_operand:DF 0 "nonimmediate_operand" "") - (unspec:DF [(match_operand:TF 1 "register_operand" "") - (const_int 0)] - UNSPEC_UNPACK_128BIT))] - "" - "") - -(define_expand "unpacktf_1" - [(set (match_operand:DF 0 "nonimmediate_operand" "") - (unspec:DF [(match_operand:TF 1 "register_operand" "") - (const_int 1)] - UNSPEC_UNPACK_128BIT))] - "" - "") - (define_insn_and_split "unpack<mode>_dm" [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m") (unspec:<FP128_64> diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c index 9f834481b4f..3fc2847ac60 100644 --- a/gcc/config/rx/rx.c +++ b/gcc/config/rx/rx.c @@ -2219,7 +2219,7 @@ static bool rx_in_small_data (const_tree decl) { int size; - const_tree section; + const char * section; if (rx_small_data_limit == 0) return false; @@ -2238,11 +2238,7 @@ rx_in_small_data (const_tree decl) section = DECL_SECTION_NAME (decl); if (section) - { - const char * const name = TREE_STRING_POINTER (section); - - return (strcmp (name, "D_2") == 0) || (strcmp (name, "B_2") == 0); - } + return (strcmp (section, "D_2") == 0) || (strcmp (section, "B_2") == 0); size = int_size_in_bytes (TREE_TYPE (decl)); @@ -2792,11 +2788,11 @@ rx_option_override (void) rx_override_options_after_change (); if (align_jumps == 0 && ! optimize_size) - align_jumps = 3; + align_jumps = ((rx_cpu_type == RX100 || rx_cpu_type == RX200) ? 2 : 3); if (align_loops == 0 && ! optimize_size) - align_loops = 3; + align_loops = ((rx_cpu_type == RX100 || rx_cpu_type == RX200) ? 2 : 3); if (align_labels == 0 && ! optimize_size) - align_labels = 3; + align_labels = ((rx_cpu_type == RX100 || rx_cpu_type == RX200) ? 2 : 3); } @@ -3201,7 +3197,11 @@ rx_align_for_label (rtx lab, int uses_threshold) if (LABEL_P (lab) && LABEL_NUSES (lab) < uses_threshold) return 0; - return optimize_size ? 1 : 3; + if (optimize_size) + return 0; + if (rx_cpu_type == RX100 || rx_cpu_type == RX200) + return 2; + return 2; } static int @@ -3210,6 +3210,9 @@ rx_max_skip_for_label (rtx lab) int opsize; rtx op; + if (optimize_size) + return 0; + if (lab == NULL_RTX) return 0; diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h index d99b19ad202..050ac68dc8e 100644 --- a/gcc/config/rx/rx.h +++ b/gcc/config/rx/rx.h @@ -142,7 +142,7 @@ /* RX load/store instructions can handle unaligned addresses. */ #define STRICT_ALIGNMENT 0 -#define FUNCTION_BOUNDARY 8 +#define FUNCTION_BOUNDARY ((rx_cpu_type == RX100 || rx_cpu_type == RX200) ? 4 : 8) #define BIGGEST_ALIGNMENT 32 #define STACK_BOUNDARY 32 #define PARM_BOUNDARY 8 @@ -433,9 +433,9 @@ typedef unsigned int CUMULATIVE_ARGS; /* Compute the alignment needed for label X in various situations. If the user has specified an alignment then honour that, otherwise use rx_align_for_label. */ -#define JUMP_ALIGN(x) (align_jumps ? align_jumps : rx_align_for_label (x, 0)) -#define LABEL_ALIGN(x) (align_labels ? align_labels : rx_align_for_label (x, 3)) -#define LOOP_ALIGN(x) (align_loops ? align_loops : rx_align_for_label (x, 2)) +#define JUMP_ALIGN(x) (align_jumps > 1 ? align_jumps_log : rx_align_for_label (x, 0)) +#define LABEL_ALIGN(x) (align_labels > 1 ? align_labels_log : rx_align_for_label (x, 3)) +#define LOOP_ALIGN(x) (align_loops > 1 ? align_loops_log : rx_align_for_label (x, 2)) #define LABEL_ALIGN_AFTER_BARRIER(x) rx_align_for_label (x, 0) #define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM, LOG, MAX_SKIP) \ diff --git a/gcc/config/s390/constraints.md b/gcc/config/s390/constraints.md index 404424d9431..6af3dc80e8b 100644 --- a/gcc/config/s390/constraints.md +++ b/gcc/config/s390/constraints.md @@ -406,14 +406,6 @@ && s390_check_symref_alignment (XEXP (op, 0), GET_MODE_SIZE (GET_MODE (op)))")) -(define_memory_constraint "e" - "Matches all memory references available on the current architecture -level. This constraint will never be used and using it in an inline -assembly is *always* a bug since there is no instruction accepting all -those addresses. It just serves as a placeholder for a generic memory -constraint." - (match_test "strict_memory_address_p (GET_MODE (op), op)")) - ; This defines 'm' as normal memory constraint. This is only possible ; since the standard memory constraint is re-defined in s390.h using ; the TARGET_MEM_CONSTRAINT macro. diff --git a/gcc/config/score/score.c b/gcc/config/score/score.c index 576a2a0cde9..d65684c45e4 100644 --- a/gcc/config/score/score.c +++ b/gcc/config/score/score.c @@ -668,7 +668,7 @@ score_in_small_data_p (const_tree decl) if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0) { const char *name; - name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); + name = DECL_SECTION_NAME (decl); if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0) return true; diff --git a/gcc/config/sparc/constraints.md b/gcc/config/sparc/constraints.md index 6295be0ef03..587bf371b4f 100644 --- a/gcc/config/sparc/constraints.md +++ b/gcc/config/sparc/constraints.md @@ -171,7 +171,7 @@ ;; define_register_constraint would. This currently means that we cannot ;; use LRA on Sparc, since the constraint processing of LRA really depends ;; upon whether an extra constraint is for registers or not. It uses -;; REG_CLASS_FROM_CONSTRAINT, and checks it against NO_REGS. +;; reg_class_for_constraint, and checks it against NO_REGS. (define_constraint "U" "Pseudo-register or hard even-numbered integer register" (and (match_test "TARGET_ARCH32") diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c index 070a5cbd7d1..f736c44bae8 100644 --- a/gcc/config/v850/v850.c +++ b/gcc/config/v850/v850.c @@ -2190,7 +2190,7 @@ v850_encode_data_area (tree decl, rtx symbol) { if (DECL_SECTION_NAME (decl)) { - const char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); + const char *name = DECL_SECTION_NAME (decl); if (streq (name, ".zdata") || streq (name, ".zbss")) v850_set_data_area (decl, DATA_AREA_ZDA); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6b2068868b5..5a8c01dad66 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,102 @@ +2014-06-15 Jason Merrill <jason@redhat.com> + + PR c++/61488 + * pt.c (check_valid_ptrmem_cst_expr): Fix for template context. + + PR c++/61500 + * tree.c (lvalue_kind): Handle MEMBER_REF and DOTSTAR_EXPR. + +2014-06-15 Jan Hubicka <hubicka@ucw.cz> + + * decl.c (grokvardecl): Fix pasto in previous patch. + +2014-06-15 Jan Hubicka <hubicka@ucw.cz> + + * decl.c (duplicate_decls): Use set_decl_tls_model. + (grokdeclarator): Likewise. + * semantics.c (finish_id_expression): Check TLS only for + static variables. + (finish_omp_threadprivate): Use decl_default_tls_model. + * decl2.c (get_guard): Likewise. + * call.c (make_temporary_var_for_ref_to_temp): Likewise. + +2014-06-14 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/33101 + * decl.c (grokparms): Improve error message about void parameters. + * error.c (type_to_string): Fix aka cut off code. + +2014-06-12 Jason Merrill <jason@redhat.com> + + * call.c (convert_arg_to_ellipsis): Use abi_version_crosses. + * cvt.c (type_promotes_to): Likewise. + * mangle.c (write_type, write_expression): Likewise. + (write_name, write_template_arg): Likewise. + (mangle_decl): Make alias based on flag_abi_compat_version. + Emit -Wabi warning here. + (finish_mangling_internal): Not here. Drop warn parm. + (finish_mangling_get_identifier, finish_mangling): Adjust. + (mangle_type_string, mangle_special_for_type): Adjust. + (mangle_ctor_vtbl_for_type, mangle_thunk): Adjust. + (mangle_guard_variable, mangle_tls_init_fn): Adjust. + (mangle_tls_wrapper_fn, mangle_ref_init_variable): Adjust. + + * call.c (build_operator_new_call): Remove -fabi-version=1 support. + * class.c (walk_subobject_offsets, include_empty_classes): Likewise. + (layout_nonempty_base_or_field, end_of_class): Likewise. + (layout_empty_base, build_base_field, layout_class_type): Likewise. + (is_empty_class, add_vcall_offset_vtbl_entries_1): Likewise. + (layout_virtual_bases): Likewise. + * decl.c (compute_array_index_type): Likewise. + * mangle.c (write_mangled_name, write_prefix): Likewise. + (write_template_prefix, write_integer_cst, write_expression): Likewise. + (write_template_arg, write_array_type): Likewise. + * method.c (lazily_declare_fn): Likewise. + * rtti.c (get_pseudo_ti_index): Likewise. + * typeck.c (comp_array_types): Likewise. + +2014-06-11 Jan Hubicka <hubicka@ucw.cz> + + * vtable-class-hierarchy.c: Update handling for section names + that are no longer trees. + * decl.c (duplicate_decls): Likewise. + +2014-06-11 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/19200 + * parser.c (cp_parser_init_declarator): Actually pass friend_p + to cp_parser_declarator. + +2014-06-11 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/60265 + * parser.c (cp_parser_using_declaration): Handle unscoped enums. + * name-lookup.c (validate_nonmember_using_decl): Adjust error + message. + +2014-06-11 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/19200 + * parser.c (cp_parser_declarator): Add bool parameter. + (cp_parser_direct_declarator): Likewise, use it. + (cp_parser_member_declaration): Pass friend_p to cp_parser_declarator. + (cp_parser_condition, cp_parser_explicit_instantiation, + cp_parser_init_declarator, cp_parser_type_id_1, + cp_parser_parameter_declaration, cp_parser_exception_declaration, + cp_parser_cache_defarg, cp_parser_objc_class_ivars, + cp_parser_objc_struct_declaration, cp_parser_omp_for_loop_init): + Adjust. + * decl.c (grokdeclarator): Fix handling of friend declared in + namespace scope (g++.dg/parse/friend10.C). + +2014-06-10 Jan Hubicka <hubicka@ucw.cz> + + * vtable-class-hierarchy.c: Use symtab_get_node (var_decl) + ->implicit_section. + * optimize.c (cdtor_comdat_group): Fix handling of aliases. + (maybe_clone_body): Move symbol across comdat groups. + * method.c (use_thunk): Copy implicit section flag. + 2014-06-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/22556 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 75a6a4acc29..1d4c4f99e2f 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4130,29 +4130,17 @@ build_operator_new_call (tree fnname, vec<tree, va_gc> **args, if (*cookie_size) { bool use_cookie = true; - if (!abi_version_at_least (2)) - { - /* In G++ 3.2, the check was implemented incorrectly; it - looked at the placement expression, rather than the - type of the function. */ - if ((*args)->length () == 2 - && same_type_p (TREE_TYPE ((**args)[1]), ptr_type_node)) - use_cookie = false; - } - else - { - tree arg_types; - - arg_types = TYPE_ARG_TYPES (TREE_TYPE (cand->fn)); - /* Skip the size_t parameter. */ - arg_types = TREE_CHAIN (arg_types); - /* Check the remaining parameters (if any). */ - if (arg_types - && TREE_CHAIN (arg_types) == void_list_node - && same_type_p (TREE_VALUE (arg_types), - ptr_type_node)) - use_cookie = false; - } + tree arg_types; + + arg_types = TYPE_ARG_TYPES (TREE_TYPE (cand->fn)); + /* Skip the size_t parameter. */ + arg_types = TREE_CHAIN (arg_types); + /* Check the remaining parameters (if any). */ + if (arg_types + && TREE_CHAIN (arg_types) == void_list_node + && same_type_p (TREE_VALUE (arg_types), + ptr_type_node)) + use_cookie = false; /* If we need a cookie, adjust the number of bytes allocated. */ if (use_cookie) { @@ -6520,14 +6508,22 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain) arg = null_pointer_node; else if (INTEGRAL_OR_ENUMERATION_TYPE_P (arg_type)) { - if (SCOPED_ENUM_P (arg_type) && !abi_version_at_least (6)) + if (SCOPED_ENUM_P (arg_type)) { - if (complain & tf_warning) - warning_at (loc, OPT_Wabi, "scoped enum %qT will not promote to an " - "integral type in a future version of GCC", arg_type); - arg = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg, complain); + tree prom = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg, + complain); + prom = cp_perform_integral_promotions (prom, complain); + if (abi_version_crosses (6) + && TYPE_MODE (TREE_TYPE (prom)) != TYPE_MODE (arg_type) + && (complain & tf_warning)) + warning_at (loc, OPT_Wabi, "scoped enum %qT passed through ... as " + "%qT before -fabi-version=6, %qT after", arg_type, + TREE_TYPE (prom), ENUM_UNDERLYING_TYPE (arg_type)); + if (!abi_version_at_least (6)) + arg = prom; } - arg = cp_perform_integral_promotions (arg, complain); + else + arg = cp_perform_integral_promotions (arg, complain); } arg = require_complete_type_sfinae (arg, complain); @@ -9391,7 +9387,7 @@ make_temporary_var_for_ref_to_temp (tree decl, tree type) tree name; TREE_STATIC (var) = TREE_STATIC (decl); - DECL_TLS_MODEL (var) = DECL_TLS_MODEL (decl); + set_decl_tls_model (var, DECL_TLS_MODEL (decl)); name = mangle_ref_init_variable (decl); DECL_NAME (var) = name; SET_DECL_ASSEMBLER_NAME (var, name); diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 25fc89bc013..a96b3602786 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3820,8 +3820,7 @@ walk_subobject_offsets (tree type, if (!TYPE_P (type)) { - if (abi_version_at_least (2)) - type_binfo = type; + type_binfo = type; type = BINFO_TYPE (type); } @@ -3847,43 +3846,29 @@ walk_subobject_offsets (tree type, { tree binfo_offset; - if (abi_version_at_least (2) - && BINFO_VIRTUAL_P (binfo)) + if (BINFO_VIRTUAL_P (binfo)) continue; - if (!vbases_p - && BINFO_VIRTUAL_P (binfo) - && !BINFO_PRIMARY_P (binfo)) - continue; - - if (!abi_version_at_least (2)) - binfo_offset = size_binop (PLUS_EXPR, - offset, - BINFO_OFFSET (binfo)); - else - { - tree orig_binfo; - /* We cannot rely on BINFO_OFFSET being set for the base - class yet, but the offsets for direct non-virtual - bases can be calculated by going back to the TYPE. */ - orig_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), i); - binfo_offset = size_binop (PLUS_EXPR, - offset, - BINFO_OFFSET (orig_binfo)); - } + tree orig_binfo; + /* We cannot rely on BINFO_OFFSET being set for the base + class yet, but the offsets for direct non-virtual + bases can be calculated by going back to the TYPE. */ + orig_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), i); + binfo_offset = size_binop (PLUS_EXPR, + offset, + BINFO_OFFSET (orig_binfo)); r = walk_subobject_offsets (binfo, f, binfo_offset, offsets, max_offset, - (abi_version_at_least (2) - ? /*vbases_p=*/0 : vbases_p)); + /*vbases_p=*/0); if (r) return r; } - if (abi_version_at_least (2) && CLASSTYPE_VBASECLASSES (type)) + if (CLASSTYPE_VBASECLASSES (type)) { unsigned ix; vec<tree, va_gc> *vbases; @@ -3936,11 +3921,7 @@ walk_subobject_offsets (tree type, { tree field_offset; - if (abi_version_at_least (2)) - field_offset = byte_position (field); - else - /* In G++ 3.2, DECL_FIELD_OFFSET was used. */ - field_offset = DECL_FIELD_OFFSET (field); + field_offset = byte_position (field); r = walk_subobject_offsets (TREE_TYPE (field), f, @@ -3967,10 +3948,7 @@ walk_subobject_offsets (tree type, /* Step through each of the elements in the array. */ for (index = size_zero_node; - /* G++ 3.2 had an off-by-one error here. */ - (abi_version_at_least (2) - ? !tree_int_cst_lt (TYPE_MAX_VALUE (domain), index) - : tree_int_cst_lt (index, TYPE_MAX_VALUE (domain))); + !tree_int_cst_lt (TYPE_MAX_VALUE (domain), index); index = size_binop (PLUS_EXPR, index, size_one_node)) { r = walk_subobject_offsets (TREE_TYPE (type), @@ -4114,10 +4092,6 @@ layout_nonempty_base_or_field (record_layout_info rli, offset zero. */ if (TREE_CODE (rli->t) == UNION_TYPE) break; - /* G++ 3.2 did not check for overlaps when placing a non-empty - virtual base. */ - if (!abi_version_at_least (2) && binfo && BINFO_VIRTUAL_P (binfo)) - break; if (layout_conflict_p (field_p ? type : binfo, offset, offsets, field_p)) { @@ -4182,17 +4156,9 @@ layout_empty_base (record_layout_info rli, tree binfo, alignment = ssize_int (CLASSTYPE_ALIGN_UNIT (basetype)); if (!integer_zerop (BINFO_OFFSET (binfo))) - { - if (abi_version_at_least (2)) - propagate_binfo_offsets - (binfo, size_diffop_loc (input_location, + propagate_binfo_offsets + (binfo, size_diffop_loc (input_location, size_zero_node, BINFO_OFFSET (binfo))); - else - warning (OPT_Wabi, - "offset of empty base %qT may not be ABI-compliant and may" - "change in a future version of GCC", - BINFO_TYPE (binfo)); - } /* This is an empty base class. We first try to put it at offset zero. */ @@ -4311,14 +4277,7 @@ build_base_field (record_layout_info rli, tree binfo, /*offsets=*/NULL, /*max_offset=*/NULL_TREE, /*vbases_p=*/true)) - { - if (abi_version_at_least (2)) - CLASSTYPE_NEARLY_EMPTY_P (t) = 0; - else - warning (OPT_Wabi, - "class %qT will be considered nearly empty in a " - "future version of GCC", t); - } + CLASSTYPE_NEARLY_EMPTY_P (t) = 0; } /* We do not create a FIELD_DECL for empty base classes because @@ -5808,27 +5767,11 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets) { tree vbase; tree t = rli->t; - bool first_vbase = true; tree *next_field; if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) == 0) return; - if (!abi_version_at_least(2)) - { - /* In G++ 3.2, we incorrectly rounded the size before laying out - the virtual bases. */ - finish_record_layout (rli, /*free_p=*/false); -#ifdef STRUCTURE_SIZE_BOUNDARY - /* Packed structures don't need to have minimum size. */ - if (! TYPE_PACKED (t)) - TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), (unsigned) STRUCTURE_SIZE_BOUNDARY); -#endif - rli->offset = TYPE_SIZE_UNIT (t); - rli->bitpos = bitsize_zero_node; - rli->record_align = TYPE_ALIGN (t); - } - /* Find the last field. The artificial fields created for virtual bases will go after the last extant field to date. */ next_field = &TYPE_FIELDS (t); @@ -5845,35 +5788,10 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets) if (!BINFO_PRIMARY_P (vbase)) { - tree basetype = TREE_TYPE (vbase); - /* This virtual base is not a primary base of any class in the hierarchy, so we have to add space for it. */ next_field = build_base_field (rli, vbase, offsets, next_field); - - /* If the first virtual base might have been placed at a - lower address, had we started from CLASSTYPE_SIZE, rather - than TYPE_SIZE, issue a warning. There can be both false - positives and false negatives from this warning in rare - cases; to deal with all the possibilities would probably - require performing both layout algorithms and comparing - the results which is not particularly tractable. */ - if (warn_abi - && first_vbase - && (tree_int_cst_lt - (size_binop (CEIL_DIV_EXPR, - round_up_loc (input_location, - CLASSTYPE_SIZE (t), - CLASSTYPE_ALIGN (basetype)), - bitsize_unit_node), - BINFO_OFFSET (vbase)))) - warning (OPT_Wabi, - "offset of virtual base %qT is not ABI-compliant and " - "may change in a future version of GCC", - basetype); - - first_vbase = false; } } } @@ -5927,8 +5845,7 @@ end_of_class (tree t, int include_virtuals_p) result = offset; } - /* G++ 3.2 did not check indirect virtual bases. */ - if (abi_version_at_least (2) && include_virtuals_p) + if (include_virtuals_p) for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0; vec_safe_iterate (vbases, i, &base_binfo); i++) { @@ -6015,17 +5932,9 @@ include_empty_classes (record_layout_info rli) if (TREE_CODE (rli_size) == INTEGER_CST && tree_int_cst_lt (rli_size, eoc)) { - if (!abi_version_at_least (2)) - /* In version 1 of the ABI, the size of a class that ends with - a bitfield was not rounded up to a whole multiple of a - byte. Because rli_size_unit_so_far returns only the number - of fully allocated bytes, any extra bits were not included - in the size. */ - rli->bitpos = round_down (rli->bitpos, BITS_PER_UNIT); - else - /* The size should have been rounded to a whole byte. */ - gcc_assert (tree_int_cst_equal - (rli->bitpos, round_down (rli->bitpos, BITS_PER_UNIT))); + /* The size should have been rounded to a whole byte. */ + gcc_assert (tree_int_cst_equal + (rli->bitpos, round_down (rli->bitpos, BITS_PER_UNIT))); rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, @@ -6155,26 +6064,16 @@ layout_class_type (tree t, tree *virtuals_p) integer_type = integer_types[itk]; } while (itk > 0 && integer_type == NULL_TREE); - /* Figure out how much additional padding is required. GCC - 3.2 always created a padding field, even if it had zero - width. */ - if (!abi_version_at_least (2) - || tree_int_cst_lt (TYPE_SIZE (integer_type), DECL_SIZE (field))) + /* Figure out how much additional padding is required. */ + if (tree_int_cst_lt (TYPE_SIZE (integer_type), DECL_SIZE (field))) { - if (abi_version_at_least (2) && TREE_CODE (t) == UNION_TYPE) + if (TREE_CODE (t) == UNION_TYPE) /* In a union, the padding field must have the full width of the bit-field; all fields start at offset zero. */ padding = DECL_SIZE (field); else - { - if (TREE_CODE (t) == UNION_TYPE) - warning (OPT_Wabi, "size assigned to %qT may not be " - "ABI-compliant and may change in a future " - "version of GCC", - t); - padding = size_binop (MINUS_EXPR, DECL_SIZE (field), - TYPE_SIZE (integer_type)); - } + padding = size_binop (MINUS_EXPR, DECL_SIZE (field), + TYPE_SIZE (integer_type)); } #ifdef PCC_BITFIELD_TYPE_MATTERS /* An unnamed bitfield does not normally affect the @@ -6201,26 +6100,17 @@ layout_class_type (tree t, tree *virtuals_p) field is effectively invisible. */ DECL_SIZE (field) = TYPE_SIZE (type); /* We must also reset the DECL_MODE of the field. */ - if (abi_version_at_least (2)) - DECL_MODE (field) = TYPE_MODE (type); - else if (warn_abi - && DECL_MODE (field) != TYPE_MODE (type)) - /* Versions of G++ before G++ 3.4 did not reset the - DECL_MODE. */ - warning (OPT_Wabi, - "the offset of %qD may not be ABI-compliant and may " - "change in a future version of GCC", field); + DECL_MODE (field) = TYPE_MODE (type); } else layout_nonempty_base_or_field (rli, field, NULL_TREE, empty_base_offsets); /* Remember the location of any empty classes in FIELD. */ - if (abi_version_at_least (2)) - record_subobject_offsets (TREE_TYPE (field), - byte_position(field), - empty_base_offsets, - /*is_data_member=*/true); + record_subobject_offsets (TREE_TYPE (field), + byte_position(field), + empty_base_offsets, + /*is_data_member=*/true); /* If a bit-field does not immediately follow another bit-field, and yet it starts in the middle of a byte, we have failed to @@ -6239,17 +6129,6 @@ layout_class_type (tree t, tree *virtuals_p) warning (OPT_Wabi, "offset of %q+D is not ABI-compliant and may " "change in a future version of GCC", field); - /* G++ used to use DECL_FIELD_OFFSET as if it were the byte - offset of the field. */ - if (warn_abi - && !abi_version_at_least (2) - && !tree_int_cst_equal (DECL_FIELD_OFFSET (field), - byte_position (field)) - && contains_empty_class_p (TREE_TYPE (field))) - warning (OPT_Wabi, "%q+D contains empty classes which may cause base " - "classes to be placed at different locations in a " - "future version of GCC", field); - /* The middle end uses the type of expressions to determine the possible range of expression values. In order to optimize "x.i > 7" to "false" for a 2-bit bitfield "i", the middle end @@ -6300,7 +6179,7 @@ layout_class_type (tree t, tree *virtuals_p) last_field_was_bitfield = DECL_C_BIT_FIELD (field); } - if (abi_version_at_least (2) && !integer_zerop (rli->bitpos)) + if (!integer_zerop (rli->bitpos)) { /* Make sure that we are on a byte boundary so that the size of the class without virtual bases will always be a round number @@ -6309,11 +6188,6 @@ layout_class_type (tree t, tree *virtuals_p) normalize_rli (rli); } - /* G++ 3.2 does not allow virtual bases to be overlaid with tail - padding. */ - if (!abi_version_at_least (2)) - include_empty_classes(rli); - /* Delete all zero-width bit-fields from the list of fields. Now that the type is laid out they are no longer important. */ remove_zero_width_bit_fields (t); @@ -6325,45 +6199,30 @@ layout_class_type (tree t, tree *virtuals_p) { base_t = make_node (TREE_CODE (t)); - /* Set the size and alignment for the new type. In G++ 3.2, all - empty classes were considered to have size zero when used as - base classes. */ - if (!abi_version_at_least (2) && CLASSTYPE_EMPTY_P (t)) - { - TYPE_SIZE (base_t) = bitsize_zero_node; - TYPE_SIZE_UNIT (base_t) = size_zero_node; - if (warn_abi && !integer_zerop (rli_size_unit_so_far (rli))) - warning (OPT_Wabi, - "layout of classes derived from empty class %qT " - "may change in a future version of GCC", - t); - } - else - { - tree eoc; - - /* If the ABI version is not at least two, and the last - field was a bit-field, RLI may not be on a byte - boundary. In particular, rli_size_unit_so_far might - indicate the last complete byte, while rli_size_so_far - indicates the total number of bits used. Therefore, - rli_size_so_far, rather than rli_size_unit_so_far, is - used to compute TYPE_SIZE_UNIT. */ - eoc = end_of_class (t, /*include_virtuals_p=*/0); - TYPE_SIZE_UNIT (base_t) - = size_binop (MAX_EXPR, - convert (sizetype, - size_binop (CEIL_DIV_EXPR, - rli_size_so_far (rli), - bitsize_int (BITS_PER_UNIT))), - eoc); - TYPE_SIZE (base_t) - = size_binop (MAX_EXPR, - rli_size_so_far (rli), - size_binop (MULT_EXPR, - convert (bitsizetype, eoc), - bitsize_int (BITS_PER_UNIT))); - } + /* Set the size and alignment for the new type. */ + tree eoc; + + /* If the ABI version is not at least two, and the last + field was a bit-field, RLI may not be on a byte + boundary. In particular, rli_size_unit_so_far might + indicate the last complete byte, while rli_size_so_far + indicates the total number of bits used. Therefore, + rli_size_so_far, rather than rli_size_unit_so_far, is + used to compute TYPE_SIZE_UNIT. */ + eoc = end_of_class (t, /*include_virtuals_p=*/0); + TYPE_SIZE_UNIT (base_t) + = size_binop (MAX_EXPR, + convert (sizetype, + size_binop (CEIL_DIV_EXPR, + rli_size_so_far (rli), + bitsize_int (BITS_PER_UNIT))), + eoc); + TYPE_SIZE (base_t) + = size_binop (MAX_EXPR, + rli_size_so_far (rli), + size_binop (MULT_EXPR, + convert (bitsizetype, eoc), + bitsize_int (BITS_PER_UNIT))); TYPE_ALIGN (base_t) = rli->record_align; TYPE_USER_ALIGN (base_t) = TYPE_USER_ALIGN (t); @@ -7908,12 +7767,7 @@ is_empty_class (tree type) if (! CLASS_TYPE_P (type)) return 0; - /* In G++ 3.2, whether or not a class was empty was determined by - looking at its size. */ - if (abi_version_at_least (2)) - return CLASSTYPE_EMPTY_P (type); - else - return integer_zerop (CLASSTYPE_SIZE (type)); + return CLASSTYPE_EMPTY_P (type); } /* Returns true if TYPE contains an empty class. */ @@ -9278,83 +9132,15 @@ static void add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid) { /* Make entries for the rest of the virtuals. */ - if (abi_version_at_least (2)) - { - tree orig_fn; - - /* The ABI requires that the methods be processed in declaration - order. G++ 3.2 used the order in the vtable. */ - for (orig_fn = TYPE_METHODS (BINFO_TYPE (binfo)); - orig_fn; - orig_fn = DECL_CHAIN (orig_fn)) - if (DECL_VINDEX (orig_fn)) - add_vcall_offset (orig_fn, binfo, vid); - } - else - { - tree derived_virtuals; - tree base_virtuals; - tree orig_virtuals; - /* If BINFO is a primary base, the most derived class which has - BINFO as a primary base; otherwise, just BINFO. */ - tree non_primary_binfo; - - /* We might be a primary base class. Go up the inheritance hierarchy - until we find the most derived class of which we are a primary base: - it is the BINFO_VIRTUALS there that we need to consider. */ - non_primary_binfo = binfo; - while (BINFO_INHERITANCE_CHAIN (non_primary_binfo)) - { - tree b; - - /* If we have reached a virtual base, then it must be vid->vbase, - because we ignore other virtual bases in - add_vcall_offset_vtbl_entries_r. In turn, it must be a primary - base (possibly multi-level) of vid->binfo, or we wouldn't - have called build_vcall_and_vbase_vtbl_entries for it. But it - might be a lost primary, so just skip down to vid->binfo. */ - if (BINFO_VIRTUAL_P (non_primary_binfo)) - { - gcc_assert (non_primary_binfo == vid->vbase); - non_primary_binfo = vid->binfo; - break; - } - - b = BINFO_INHERITANCE_CHAIN (non_primary_binfo); - if (get_primary_binfo (b) != non_primary_binfo) - break; - non_primary_binfo = b; - } - - if (vid->ctor_vtbl_p) - /* For a ctor vtable we need the equivalent binfo within the hierarchy - where rtti_binfo is the most derived type. */ - non_primary_binfo - = original_binfo (non_primary_binfo, vid->rtti_binfo); - - for (base_virtuals = BINFO_VIRTUALS (binfo), - derived_virtuals = BINFO_VIRTUALS (non_primary_binfo), - orig_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo))); - base_virtuals; - base_virtuals = TREE_CHAIN (base_virtuals), - derived_virtuals = TREE_CHAIN (derived_virtuals), - orig_virtuals = TREE_CHAIN (orig_virtuals)) - { - tree orig_fn; - - /* Find the declaration that originally caused this function to - be present in BINFO_TYPE (binfo). */ - orig_fn = BV_FN (orig_virtuals); - - /* When processing BINFO, we only want to generate vcall slots for - function slots introduced in BINFO. So don't try to generate - one if the function isn't even defined in BINFO. */ - if (!SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), DECL_CONTEXT (orig_fn))) - continue; - - add_vcall_offset (orig_fn, binfo, vid); - } - } + tree orig_fn; + + /* The ABI requires that the methods be processed in declaration + order. */ + for (orig_fn = TYPE_METHODS (BINFO_TYPE (binfo)); + orig_fn; + orig_fn = DECL_CHAIN (orig_fn)) + if (DECL_VINDEX (orig_fn)) + add_vcall_offset (orig_fn, binfo, vid); } /* Add a vcall offset entry for ORIG_FN to the vtable. */ diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 2a827237f28..1dec9cc7f0e 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -1701,13 +1701,9 @@ type_promotes_to (tree type) if (TREE_CODE (type) == BOOLEAN_TYPE) type = integer_type_node; - /* Scoped enums don't promote, but pretend they do for backward ABI bug - compatibility wrt varargs. */ - else if (SCOPED_ENUM_P (type) && abi_version_at_least (6)) - ; - /* Normally convert enums to int, but convert wide enums to something - wider. */ + wider. Scoped enums don't promote, but pretend they do for backward + ABI bug compatibility wrt varargs. */ else if (TREE_CODE (type) == ENUMERAL_TYPE || type == char16_type_node || type == char32_type_node @@ -1716,16 +1712,26 @@ type_promotes_to (tree type) int precision = MAX (TYPE_PRECISION (type), TYPE_PRECISION (integer_type_node)); tree totype = c_common_type_for_size (precision, 0); + tree prom = type; + if (TREE_CODE (prom) == ENUMERAL_TYPE) + prom = ENUM_UNDERLYING_TYPE (prom); + if (TYPE_UNSIGNED (prom) + && ! int_fits_type_p (TYPE_MAX_VALUE (prom), totype)) + prom = c_common_type_for_size (precision, 1); + else + prom = totype; if (SCOPED_ENUM_P (type)) - warning (OPT_Wabi, "scoped enum %qT will not promote to an integral " - "type in a future version of GCC", type); - if (TREE_CODE (type) == ENUMERAL_TYPE) - type = ENUM_UNDERLYING_TYPE (type); - if (TYPE_UNSIGNED (type) - && ! int_fits_type_p (TYPE_MAX_VALUE (type), totype)) - type = c_common_type_for_size (precision, 1); + { + if (abi_version_crosses (6) + && TYPE_MODE (prom) != TYPE_MODE (type)) + warning (OPT_Wabi, "scoped enum %qT passed through ... as " + "%qT before -fabi-version=6, %qT after", + type, prom, ENUM_UNDERLYING_TYPE (type)); + if (!abi_version_at_least (6)) + type = prom; + } else - type = totype; + type = prom; } else if (c_promoting_integer_type_p (type)) { diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 13b5d0b3431..a76980f928a 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1952,7 +1952,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) if (!DECL_LANG_SPECIFIC (newdecl)) retrofit_lang_decl (newdecl); - DECL_TLS_MODEL (newdecl) = DECL_TLS_MODEL (olddecl); + set_decl_tls_model (newdecl, DECL_TLS_MODEL (olddecl)); CP_DECL_THREADPRIVATE_P (newdecl) = 1; } } @@ -2020,8 +2020,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) done later in decl_attributes since we are called before attributes are assigned. */ if ((DECL_EXTERNAL (olddecl) || TREE_PUBLIC (olddecl) || TREE_STATIC (olddecl)) - && DECL_SECTION_NAME (newdecl) == NULL_TREE - && DECL_SECTION_NAME (olddecl) != NULL_TREE) + && DECL_SECTION_NAME (newdecl) == NULL + && DECL_SECTION_NAME (olddecl) != NULL) set_decl_section_name (newdecl, DECL_SECTION_NAME (olddecl)); if (TREE_CODE (newdecl) == FUNCTION_DECL) @@ -8016,7 +8016,8 @@ grokvardecl (tree type, if (decl_spec_seq_has_spec_p (declspecs, ds_thread)) { - DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); + if (DECL_EXTERNAL (decl) || TREE_STATIC (decl)) + set_decl_tls_model (decl, decl_default_tls_model (decl)); if (declspecs->gnu_thread_keyword_p) DECL_GNU_TLS_P (decl) = true; } @@ -8268,7 +8269,6 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) { tree itype; tree osize = size; - tree abi_1_itype = NULL_TREE; if (error_operand_p (size)) return error_mark_node; @@ -8305,9 +8305,6 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) if (size == error_mark_node) return error_mark_node; type = TREE_TYPE (size); - /* We didn't support this case in GCC 3.2, so don't bother - trying to model it now in ABI v1. */ - abi_1_itype = error_mark_node; } if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type)) @@ -8354,17 +8351,6 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) return itype; } - if (!abi_version_at_least (2) && processing_template_decl - && abi_1_itype == NULL_TREE) - /* For abi-1, we handled all instances in templates the same way, - even when they were non-dependent. This affects the manglings - produced. So, we do the normal checking for non-dependent - sizes, but at the end we'll return the same type that abi-1 - would have, but with TYPE_CANONICAL set to the "right" - value that the current ABI would provide. */ - abi_1_itype = build_index_type (build_min (MINUS_EXPR, sizetype, - osize, integer_one_node)); - /* Normally, the array-bound will be a constant. */ if (TREE_CODE (size) == INTEGER_CST) { @@ -8510,14 +8496,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) } /* Create and return the appropriate index type. */ - if (abi_1_itype && abi_1_itype != error_mark_node) - { - tree t = build_index_type (itype); - TYPE_CANONICAL (abi_1_itype) = TYPE_CANONICAL (t); - itype = abi_1_itype; - } - else - itype = build_index_type (itype); + itype = build_index_type (itype); /* If the index type were dependent, we would have returned early, so remember that it isn't. */ @@ -9686,7 +9665,7 @@ grokdeclarator (const cp_declarator *declarator, if (ctype == NULL_TREE && decl_context == FIELD && funcdecl_p - && (friendp == 0 || dname == current_class_name)) + && friendp == 0) ctype = current_class_type; if (ctype && (sfk == sfk_constructor @@ -10721,7 +10700,7 @@ grokdeclarator (const cp_declarator *declarator, if (thread_p) { - DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); + set_decl_tls_model (decl, decl_default_tls_model (decl)); if (declspecs->gnu_thread_keyword_p) DECL_GNU_TLS_P (decl) = true; } @@ -11159,12 +11138,24 @@ grokparms (tree parmlist, tree *parms) type = TREE_TYPE (decl); if (VOID_TYPE_P (type)) { - if (same_type_p (type, void_type_node) - && DECL_SELF_REFERENCE_P (type) - && !DECL_NAME (decl) && !result && TREE_CHAIN (parm) == void_list_node) + if (type == void_type_node + && !init + && !DECL_NAME (decl) && !result + && TREE_CHAIN (parm) == void_list_node) /* this is a parmlist of `(void)', which is ok. */ break; - cxx_incomplete_type_error (decl, type); + else if (typedef_variant_p (type)) + error_at (DECL_SOURCE_LOCATION (decl), + "invalid use of typedef-name %qT in " + "parameter declaration", type); + else if (cv_qualified_p (type)) + error_at (DECL_SOURCE_LOCATION (decl), + "invalid use of cv-qualified type %qT in " + "parameter declaration", type); + else + error_at (DECL_SOURCE_LOCATION (decl), + "invalid use of type %<void%> in parameter " + "declaration"); /* It's not a good idea to actually create parameters of type `void'; other parts of the compiler assume that a void type terminates the parameter list. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 602a0c55759..99ea582f958 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2939,7 +2939,7 @@ get_guard (tree decl) TREE_STATIC (guard) = TREE_STATIC (decl); DECL_COMMON (guard) = DECL_COMMON (decl); DECL_COMDAT (guard) = DECL_COMDAT (decl); - DECL_TLS_MODEL (guard) = DECL_TLS_MODEL (decl); + set_decl_tls_model (guard, DECL_TLS_MODEL (decl)); if (DECL_ONE_ONLY (decl)) make_decl_one_only (guard, cxx_comdat_group (guard)); if (TREE_PUBLIC (decl)) @@ -4212,7 +4212,7 @@ handle_tls_init (void) DECL_ARTIFICIAL (guard) = true; DECL_IGNORED_P (guard) = true; TREE_USED (guard) = true; - DECL_TLS_MODEL (guard) = decl_default_tls_model (guard); + set_decl_tls_model (guard, decl_default_tls_model (guard)); pushdecl_top_level_and_finish (guard, NULL_TREE); tree fn = get_local_tls_init_fn (); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index b3b5bbb0971..27a167a001a 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2922,7 +2922,7 @@ type_to_string (tree typ, int verbose) if (typ && TYPE_P (typ) && typ != TYPE_CANONICAL (typ) && !uses_template_parms (typ)) { - int aka_start; char *p; + int aka_start, aka_len; char *p; struct obstack *ob = pp_buffer (cxx_pp)->obstack; /* Remember the end of the initial dump. */ int len = obstack_object_size (ob); @@ -2932,10 +2932,11 @@ type_to_string (tree typ, int verbose) /* And remember the start of the aka dump. */ aka_start = obstack_object_size (ob); dump_type (cxx_pp, aka, flags); + aka_len = obstack_object_size (ob) - aka_start; pp_right_brace (cxx_pp); p = (char*)obstack_base (ob); /* If they are identical, cut off the aka with a NUL. */ - if (memcmp (p, p+aka_start, len) == 0) + if (len == aka_len && memcmp (p, p+aka_start, len) == 0) p[len] = '\0'; } return pp_ggc_formatted_text (cxx_pp); diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 1b2c2cd7944..ac1c1da9730 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -225,7 +225,6 @@ static int local_class_index (tree); /* Control functions. */ static inline void start_mangling (const tree); -static inline const char *finish_mangling (const bool); static tree mangle_special_for_type (const tree, const char *); /* Foreign language functions. */ @@ -663,10 +662,7 @@ write_mangled_name (const tree decl, bool top_level) <source-name> without a type." We cannot write overloaded operators that way though, because it contains characters invalid in assembler. */ - if (abi_version_at_least (2)) - write_string ("_Z"); - else - G.need_abi_warning = true; + write_string ("_Z"); write_source_name (DECL_NAME (decl)); } } @@ -677,17 +673,10 @@ write_mangled_name (const tree decl, bool top_level) /* And neither are `extern "C"' variables. */ || DECL_EXTERN_C_P (decl))) { - if (top_level || abi_version_at_least (2)) - goto unmangled_name; - else - { - G.need_abi_warning = true; - goto mangled_name; - } + goto unmangled_name; } else { - mangled_name:; write_string ("_Z"); write_encoding (decl); } @@ -796,6 +785,11 @@ write_name (tree decl, const int ignore_local_scope) gcc_assert (context != NULL_TREE); + if (abi_version_crosses (7) + && ignore_local_scope + && TREE_CODE (context) == PARM_DECL) + G.need_abi_warning = 1; + /* A decl in :: or ::std scope is treated specially. The former is mangled using <unscoped-name> or <unscoped-template-name>, the latter with a special substitution. Also, a name that is @@ -1020,13 +1014,7 @@ write_prefix (const tree node) template_info = TYPE_TEMPLATE_INFO (node); } - /* In G++ 3.2, the name of the template parameter was used. */ - if (TREE_CODE (node) == TEMPLATE_TYPE_PARM - && !abi_version_at_least (2)) - G.need_abi_warning = true; - - if (TREE_CODE (node) == TEMPLATE_TYPE_PARM - && abi_version_at_least (2)) + if (TREE_CODE (node) == TEMPLATE_TYPE_PARM) write_template_param (node); else if (template_info != NULL) /* Templated. */ @@ -1124,15 +1112,8 @@ write_template_prefix (const tree node) if (find_substitution (substitution)) return; - /* In G++ 3.2, the name of the template template parameter was used. */ if (TREE_TYPE (templ) - && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM - && !abi_version_at_least (2)) - G.need_abi_warning = true; - - if (TREE_TYPE (templ) - && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM - && abi_version_at_least (2)) + && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM) write_template_param (TREE_TYPE (templ)); else { @@ -1597,45 +1578,29 @@ write_integer_cst (const tree cst) static void write_real_cst (const tree value) { - if (abi_version_at_least (2)) - { - long target_real[4]; /* largest supported float */ - char buffer[9]; /* eight hex digits in a 32-bit number */ - int i, limit, dir; + long target_real[4]; /* largest supported float */ + char buffer[9]; /* eight hex digits in a 32-bit number */ + int i, limit, dir; - tree type = TREE_TYPE (value); - int words = GET_MODE_BITSIZE (TYPE_MODE (type)) / 32; + tree type = TREE_TYPE (value); + int words = GET_MODE_BITSIZE (TYPE_MODE (type)) / 32; - real_to_target (target_real, &TREE_REAL_CST (value), - TYPE_MODE (type)); - - /* The value in target_real is in the target word order, - so we must write it out backward if that happens to be - little-endian. write_number cannot be used, it will - produce uppercase. */ - if (FLOAT_WORDS_BIG_ENDIAN) - i = 0, limit = words, dir = 1; - else - i = words - 1, limit = -1, dir = -1; + real_to_target (target_real, &TREE_REAL_CST (value), + TYPE_MODE (type)); - for (; i != limit; i += dir) - { - sprintf (buffer, "%08lx", (unsigned long) target_real[i]); - write_chars (buffer, 8); - } - } + /* The value in target_real is in the target word order, + so we must write it out backward if that happens to be + little-endian. write_number cannot be used, it will + produce uppercase. */ + if (FLOAT_WORDS_BIG_ENDIAN) + i = 0, limit = words, dir = 1; else + i = words - 1, limit = -1, dir = -1; + + for (; i != limit; i += dir) { - /* In G++ 3.3 and before the REAL_VALUE_TYPE was written out - literally. Note that compatibility with 3.2 is impossible, - because the old floating-point emulator used a different - format for REAL_VALUE_TYPE. */ - size_t i; - for (i = 0; i < sizeof (TREE_REAL_CST (value)); ++i) - write_number (((unsigned char *) &TREE_REAL_CST (value))[i], - /*unsigned_p*/ 1, - /*base*/ 16); - G.need_abi_warning = 1; + sprintf (buffer, "%08lx", (unsigned long) target_real[i]); + write_chars (buffer, 8); } } @@ -1904,6 +1869,8 @@ write_type (tree type) write_function_type (t); else write_type (t); + if (abi_version_crosses (8)) + G.need_abi_warning = 1; } else write_type (t); @@ -2009,9 +1976,14 @@ write_type (tree type) a typedef or template argument can have function type with function-cv-quals (that use the same representation), but you can't have a pointer/reference to such a type. */ - if (abi_version_at_least (5) - && TREE_CODE (target) == FUNCTION_TYPE) - target = build_qualified_type (target, TYPE_UNQUALIFIED); + if (TREE_CODE (target) == FUNCTION_TYPE) + { + if (abi_version_crosses (5) + && TYPE_QUALS (target) != TYPE_UNQUALIFIED) + G.need_abi_warning = 1; + if (abi_version_at_least (5)) + target = build_qualified_type (target, TYPE_UNQUALIFIED); + } write_type (target); } break; @@ -2051,10 +2023,9 @@ write_type (tree type) write_char ('_'); } else - { - G.need_abi_warning = 1; - write_string ("U8__vector"); - } + write_string ("U8__vector"); + if (abi_version_crosses (4)) + G.need_abi_warning = 1; write_type (TREE_TYPE (type)); break; @@ -2069,8 +2040,7 @@ write_type (tree type) && !DECLTYPE_FOR_LAMBDA_PROXY (type)); /* In ABI <5, we stripped decltype of a plain decl. */ - if (!abi_version_at_least (5) - && DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type)) + if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type)) { tree expr = DECLTYPE_TYPE_EXPR (type); tree etype = NULL_TREE; @@ -2091,9 +2061,13 @@ write_type (tree type) if (etype && !type_uses_auto (etype)) { - G.need_abi_warning = 1; - write_type (etype); - return; + if (abi_version_crosses (5)) + G.need_abi_warning = 1; + if (!abi_version_at_least (5)) + { + write_type (etype); + return; + } } } @@ -2112,6 +2086,8 @@ write_type (tree type) write_string ("Dn"); if (abi_version_at_least (7)) ++is_builtin_type; + if (abi_version_crosses (7)) + G.need_abi_warning = 1; break; case TYPEOF_TYPE: @@ -2631,7 +2607,7 @@ write_expression (tree expr) write_template_param (expr); /* Handle literals. */ else if (TREE_CODE_CLASS (code) == tcc_constant - || (abi_version_at_least (2) && code == CONST_DECL)) + || code == CONST_DECL) write_template_arg_literal (expr); else if (code == PARM_DECL && DECL_ARTIFICIAL (expr)) { @@ -2660,7 +2636,7 @@ write_expression (tree expr) write_char ('L'); write_unsigned_number (delta - 1); } - else + if (abi_version_crosses (5)) G.need_abi_warning = true; } write_char ('p'); @@ -2668,10 +2644,6 @@ write_expression (tree expr) } else if (DECL_P (expr)) { - /* G++ 3.2 incorrectly mangled non-type template arguments of - enumeration type using their names. */ - if (code == CONST_DECL) - G.need_abi_warning = 1; write_char ('L'); write_mangled_name (expr, false); write_char ('E'); @@ -2709,22 +2681,12 @@ write_expression (tree expr) member = BASELINK_FUNCTIONS (expr); } - if (!abi_version_at_least (2) && DECL_P (member)) - { - write_string ("sr"); - write_type (scope); - /* G++ 3.2 incorrectly put out both the "sr" code and - the nested name of the qualified name. */ - G.need_abi_warning = 1; - write_encoding (member); - } - /* If the MEMBER is a real declaration, then the qualifying scope was not dependent. Ideally, we would not have a SCOPE_REF in those cases, but sometimes we do. If the second argument is a DECL, then the name must not have been dependent. */ - else if (DECL_P (member)) + if (DECL_P (member)) write_expression (member); else { @@ -2906,12 +2868,13 @@ write_expression (tree expr) name = operator_name_info[(int) code].mangled_name; /* We used to mangle const_cast and static_cast like a C cast. */ - if (!abi_version_at_least (6) - && (code == CONST_CAST_EXPR - || code == STATIC_CAST_EXPR)) + if (code == CONST_CAST_EXPR + || code == STATIC_CAST_EXPR) { - name = operator_name_info[CAST_EXPR].mangled_name; - G.need_abi_warning = 1; + if (abi_version_crosses (6)) + G.need_abi_warning = 1; + if (!abi_version_at_least (6)) + name = operator_name_info[CAST_EXPR].mangled_name; } if (name == NULL) @@ -2982,7 +2945,7 @@ write_expression (tree expr) case PREDECREMENT_EXPR: if (abi_version_at_least (6)) write_char ('_'); - else + if (abi_version_crosses (6)) G.need_abi_warning = 1; /* Fall through. */ @@ -3109,10 +3072,7 @@ write_template_arg (tree node) internal consistency, such arguments use a conversion from address of object to reference type. */ gcc_assert (TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR); - if (abi_version_at_least (2)) - node = TREE_OPERAND (TREE_OPERAND (node, 0), 0); - else - G.need_abi_warning = 1; + node = TREE_OPERAND (TREE_OPERAND (node, 0), 0); } if (TREE_CODE (node) == BASELINK @@ -3120,7 +3080,7 @@ write_template_arg (tree node) { if (abi_version_at_least (6)) node = BASELINK_FUNCTIONS (node); - else + if (abi_version_crosses (6)) /* We wrongly wrapped a class-scope function in X/E. */ G.need_abi_warning = 1; } @@ -3133,10 +3093,9 @@ write_template_arg (tree node) if (abi_version_at_least (6)) write_char ('J'); else - { - write_char ('I'); - G.need_abi_warning = 1; - } + write_char ('I'); + if (abi_version_crosses (6)) + G.need_abi_warning = 1; for (i = 0; i < length; ++i) write_template_arg (TREE_VEC_ELT (args, i)); write_char ('E'); @@ -3147,25 +3106,20 @@ write_template_arg (tree node) /* A template appearing as a template arg is a template template arg. */ write_template_template_arg (node); else if ((TREE_CODE_CLASS (code) == tcc_constant && code != PTRMEM_CST) - || (abi_version_at_least (2) && code == CONST_DECL) + || code == CONST_DECL || null_member_pointer_value_p (node)) write_template_arg_literal (node); else if (DECL_P (node)) { - /* Until ABI version 2, non-type template arguments of - enumeration type were mangled using their names. */ - if (code == CONST_DECL && !abi_version_at_least (2)) - G.need_abi_warning = 1; write_char ('L'); /* Until ABI version 3, the underscore before the mangled name was incorrectly omitted. */ if (!abi_version_at_least (3)) - { - G.need_abi_warning = 1; - write_char ('Z'); - } + write_char ('Z'); else write_string ("_Z"); + if (abi_version_crosses (3)) + G.need_abi_warning = 1; write_encoding (node); write_char ('E'); } @@ -3230,15 +3184,6 @@ write_array_type (const tree type) else { max = TREE_OPERAND (max, 0); - if (!abi_version_at_least (2)) - { - /* value_dependent_expression_p presumes nothing is - dependent when PROCESSING_TEMPLATE_DECL is zero. */ - ++processing_template_decl; - if (!value_dependent_expression_p (max)) - G.need_abi_warning = 1; - --processing_template_decl; - } write_expression (max); } @@ -3355,13 +3300,8 @@ start_mangling (const tree entity) warning. */ static void -finish_mangling_internal (const bool warn) +finish_mangling_internal (void) { - if (warn_abi && warn && G.need_abi_warning) - warning (OPT_Wabi, "the mangled name of %qD will change in a future " - "version of GCC", - G.entity); - /* Clear all the substitutions. */ vec_safe_truncate (G.substitutions, 0); @@ -3373,18 +3313,18 @@ finish_mangling_internal (const bool warn) /* Like finish_mangling_internal, but return the mangled string. */ static inline const char * -finish_mangling (const bool warn) +finish_mangling (void) { - finish_mangling_internal (warn); + finish_mangling_internal (); return (const char *) obstack_finish (mangle_obstack); } /* Like finish_mangling_internal, but return an identifier. */ static tree -finish_mangling_get_identifier (const bool warn) +finish_mangling_get_identifier (void) { - finish_mangling_internal (warn); + finish_mangling_internal (); /* Don't obstack_finish here, and the next start_mangling will remove the identifier. */ return get_identifier ((const char *) obstack_base (mangle_obstack)); @@ -3442,7 +3382,7 @@ mangle_decl_string (const tree decl) else write_mangled_name (decl, true); - result = finish_mangling_get_identifier (/*warn=*/true); + result = finish_mangling_get_identifier (); if (DEBUG_MANGLE) fprintf (stderr, "mangle_decl_string = '%s'\n\n", IDENTIFIER_POINTER (result)); @@ -3494,26 +3434,47 @@ mangle_decl (const tree decl) && !DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)) { -#ifdef ASM_OUTPUT_DEF /* If the mangling will change in the future, emit an alias with the future mangled name for forward-compatibility. */ int save_ver; - tree id2, alias; -#endif + tree id2; SET_IDENTIFIER_GLOBAL_VALUE (id, decl); if (IDENTIFIER_GLOBAL_VALUE (id) != decl) - inform (DECL_SOURCE_LOCATION (decl), "-fabi-version=6 (or =0) " + inform (DECL_SOURCE_LOCATION (decl), "a later -fabi-version= (or =0) " "avoids this error with a change in mangling"); -#ifdef ASM_OUTPUT_DEF save_ver = flag_abi_version; - flag_abi_version = 0; + flag_abi_version = flag_abi_compat_version; id2 = mangle_decl_string (decl); id2 = targetm.mangle_decl_assembler_name (decl, id2); flag_abi_version = save_ver; - alias = make_alias_for (decl, id2); + if (id2 == id) + return; + + if (warn_abi) + { + if (flag_abi_compat_version != 0 + && abi_version_at_least (flag_abi_compat_version)) + warning (OPT_Wabi, "the mangled name of %q+D changed between " + "-fabi-version=%d (%D) and -fabi-version=%d (%D)", + G.entity, flag_abi_compat_version, id2, + flag_abi_version, id); + else + warning (OPT_Wabi, "the mangled name of %q+D changes between " + "-fabi-version=%d (%D) and -fabi-version=%d (%D)", + G.entity, flag_abi_version, id, + flag_abi_compat_version, id2); + } + +#ifdef ASM_OUTPUT_DEF + if (flag_abi_compat_version != 0 + && IDENTIFIER_GLOBAL_VALUE (id2)) + return; + + tree alias = make_alias_for (decl, id2); + SET_IDENTIFIER_GLOBAL_VALUE (id2, alias); DECL_IGNORED_P (alias) = 1; TREE_PUBLIC (alias) = TREE_PUBLIC (decl); DECL_VISIBILITY (alias) = DECL_VISIBILITY (decl); @@ -3540,7 +3501,7 @@ mangle_type_string (const tree type) start_mangling (type); write_type (type); - result = finish_mangling (/*warn=*/false); + result = finish_mangling (); if (DEBUG_MANGLE) fprintf (stderr, "mangle_type_string = '%s'\n\n", result); return result; @@ -3565,7 +3526,7 @@ mangle_special_for_type (const tree type, const char *code) /* Add the type. */ write_type (type); - result = finish_mangling_get_identifier (/*warn=*/false); + result = finish_mangling_get_identifier (); if (DEBUG_MANGLE) fprintf (stderr, "mangle_special_for_type = %s\n\n", @@ -3636,7 +3597,7 @@ mangle_ctor_vtbl_for_type (const tree type, const tree binfo) write_char ('_'); write_type (BINFO_TYPE (binfo)); - result = finish_mangling_get_identifier (/*warn=*/false); + result = finish_mangling_get_identifier (); if (DEBUG_MANGLE) fprintf (stderr, "mangle_ctor_vtbl_for_type = %s\n\n", IDENTIFIER_POINTER (result)); @@ -3715,7 +3676,7 @@ mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset, /* Scoped name. */ write_encoding (fn_decl); - result = finish_mangling_get_identifier (/*warn=*/false); + result = finish_mangling_get_identifier (); if (DEBUG_MANGLE) fprintf (stderr, "mangle_thunk = %s\n\n", IDENTIFIER_POINTER (result)); return result; @@ -3808,7 +3769,7 @@ mangle_guard_variable (const tree variable) start_mangling (variable); write_string ("_ZGV"); write_guarded_var_name (variable); - return finish_mangling_get_identifier (/*warn=*/false); + return finish_mangling_get_identifier (); } /* Return an identifier for the name of a thread_local initialization @@ -3820,7 +3781,7 @@ mangle_tls_init_fn (const tree variable) start_mangling (variable); write_string ("_ZTH"); write_guarded_var_name (variable); - return finish_mangling_get_identifier (/*warn=*/false); + return finish_mangling_get_identifier (); } /* Return an identifier for the name of a thread_local wrapper @@ -3834,7 +3795,7 @@ mangle_tls_wrapper_fn (const tree variable) start_mangling (variable); write_string (TLS_WRAPPER_PREFIX); write_guarded_var_name (variable); - return finish_mangling_get_identifier (/*warn=*/false); + return finish_mangling_get_identifier (); } /* Return true iff FN is a thread_local wrapper function. */ @@ -3864,7 +3825,7 @@ mangle_ref_init_variable (const tree variable) /* Avoid name clashes with aggregate initialization of multiple references at once. */ write_unsigned_number (temp_count++); - return finish_mangling_get_identifier (/*warn=*/false); + return finish_mangling_get_identifier (); } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 0ae190ab52d..4d8aac1dfbb 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -356,14 +356,27 @@ use_thunk (tree thunk_fndecl, bool emit_p) if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function) && targetm_common.have_named_sections) { - resolve_unique_section (function, 0, flag_function_sections); + tree fn = function; + struct symtab_node *symbol; - if (DECL_SECTION_NAME (function) != NULL && DECL_ONE_ONLY (function)) + if ((symbol = symtab_get_node (function)) + && symbol->alias) + { + if (symbol->analyzed) + fn = symtab_alias_ultimate_target (symtab_get_node (function))->decl; + else + fn = symtab_get_node (function)->alias_target; + } + resolve_unique_section (fn, 0, flag_function_sections); + + if (DECL_SECTION_NAME (fn) != NULL && DECL_ONE_ONLY (fn)) { resolve_unique_section (thunk_fndecl, 0, flag_function_sections); /* Output the thunk into the same section as function. */ - set_decl_section_name (thunk_fndecl, DECL_SECTION_NAME (function)); + set_decl_section_name (thunk_fndecl, DECL_SECTION_NAME (fn)); + symtab_get_node (thunk_fndecl)->implicit_section + = symtab_get_node (fn)->implicit_section; } } @@ -2054,21 +2067,12 @@ lazily_declare_fn (special_function_kind sfk, tree type) add_method (type, fn, NULL_TREE); /* Add it to TYPE_METHODS. */ if (sfk == sfk_destructor - && DECL_VIRTUAL_P (fn) - && abi_version_at_least (2)) + && DECL_VIRTUAL_P (fn)) /* The ABI requires that a virtual destructor go at the end of the vtable. */ TYPE_METHODS (type) = chainon (TYPE_METHODS (type), fn); else { - /* G++ 3.2 put the implicit destructor at the *beginning* of the - TYPE_METHODS list, which cause the destructor to be emitted - in an incorrect location in the vtable. */ - if (warn_abi && sfk == sfk_destructor && DECL_VIRTUAL_P (fn)) - warning (OPT_Wabi, "vtable layout for class %qT may not be ABI-compliant" - "and may change in a future version of GCC due to " - "implicit virtual destructor", - type); DECL_CHAIN (fn) = TYPE_METHODS (type); TYPE_METHODS (type) = fn; } diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 90f51083915..75b46ac9c7d 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -2487,7 +2487,7 @@ validate_nonmember_using_decl (tree decl, tree scope, tree name) member-declaration. */ if (TYPE_P (scope)) { - error ("%qT is not a namespace", scope); + error ("%qT is not a namespace or unscoped enum", scope); return NULL_TREE; } else if (scope == error_mark_node) diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index ffa5258cba6..c16e163826e 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -191,7 +191,7 @@ cdtor_comdat_group (tree complete, tree base) diff_seen = true; } grp_name[idx] = '\0'; - gcc_assert (diff_seen); + gcc_assert (diff_seen || symtab_get_node (complete)->alias); return get_identifier (grp_name); } @@ -553,6 +553,8 @@ maybe_clone_body (tree fn) *[CD][12]*. */ comdat_group = cdtor_comdat_group (fns[1], fns[0]); cgraph_get_create_node (fns[0])->set_comdat_group (comdat_group); + if (symtab_get_node (clone)->same_comdat_group) + symtab_remove_from_same_comdat_group (symtab_get_node (clone)); symtab_add_to_same_comdat_group (symtab_get_node (clone), symtab_get_node (fns[0])); } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7d574d0d3f1..1079832cec2 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2078,9 +2078,9 @@ static tree cp_parser_decltype static tree cp_parser_init_declarator (cp_parser *, cp_decl_specifier_seq *, vec<deferred_access_check, va_gc> *, bool, bool, int, bool *, tree *); static cp_declarator *cp_parser_declarator - (cp_parser *, cp_parser_declarator_kind, int *, bool *, bool); + (cp_parser *, cp_parser_declarator_kind, int *, bool *, bool, bool); static cp_declarator *cp_parser_direct_declarator - (cp_parser *, cp_parser_declarator_kind, int *, bool); + (cp_parser *, cp_parser_declarator_kind, int *, bool, bool); static enum tree_code cp_parser_ptr_operator (cp_parser *, tree *, cp_cv_quals *, tree *); static cp_cv_quals cp_parser_cv_qualifier_seq_opt @@ -10014,7 +10014,8 @@ cp_parser_condition (cp_parser* parser) declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, /*ctor_dtor_or_conv_p=*/NULL, /*parenthesized_p=*/NULL, - /*member_p=*/false); + /*member_p=*/false, + /*friend_p=*/false); /* Parse the attributes. */ attributes = cp_parser_attributes_opt (parser); /* Parse the asm-specification. */ @@ -14160,7 +14161,8 @@ cp_parser_explicit_instantiation (cp_parser* parser) = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, /*ctor_dtor_or_conv_p=*/NULL, /*parenthesized_p=*/NULL, - /*member_p=*/false); + /*member_p=*/false, + /*friend_p=*/false); if (declares_class_or_enum & 2) cp_parser_check_for_definition_in_return_type (declarator, decl_specifiers.type, @@ -16020,6 +16022,8 @@ cp_parser_using_declaration (cp_parser* parser, /*is_declaration=*/true); if (!qscope) qscope = global_namespace; + else if (UNSCOPED_ENUM_P (qscope)) + qscope = CP_TYPE_CONTEXT (qscope); if (access_declaration_p && cp_parser_error_occurred (parser)) /* Something has already gone wrong; there's no need to parse @@ -16541,7 +16545,7 @@ cp_parser_init_declarator (cp_parser* parser, bool is_direct_init = false; bool is_non_constant_init; int ctor_dtor_or_conv_p; - bool friend_p; + bool friend_p = cp_parser_friend_p (decl_specifiers); tree pushed_scope = NULL_TREE; bool range_for_decl_p = false; bool saved_default_arg_ok_p = parser->default_arg_ok_p; @@ -16570,7 +16574,7 @@ cp_parser_init_declarator (cp_parser* parser, = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, &ctor_dtor_or_conv_p, /*parenthesized_p=*/NULL, - member_p); + member_p, friend_p); /* Gather up the deferred checks. */ stop_deferring_access_checks (); @@ -16742,9 +16746,6 @@ cp_parser_init_declarator (cp_parser* parser, decl_specifiers->type = integer_type_node; } - /* Check to see whether or not this declaration is a friend. */ - friend_p = cp_parser_friend_p (decl_specifiers); - /* Enter the newly declared entry in the symbol table. If we're processing a declaration in a class-specifier, we wait until after processing the initializer. */ @@ -16958,14 +16959,16 @@ cp_parser_init_declarator (cp_parser* parser, If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to true iff the declarator is a direct-declarator of the form "(...)". - MEMBER_P is true iff this declarator is a member-declarator. */ + MEMBER_P is true iff this declarator is a member-declarator. + + FRIEND_P is true iff this declarator is a friend. */ static cp_declarator * cp_parser_declarator (cp_parser* parser, cp_parser_declarator_kind dcl_kind, int* ctor_dtor_or_conv_p, bool* parenthesized_p, - bool member_p) + bool member_p, bool friend_p) { cp_declarator *declarator; enum tree_code code; @@ -17005,7 +17008,8 @@ cp_parser_declarator (cp_parser* parser, declarator = cp_parser_declarator (parser, dcl_kind, /*ctor_dtor_or_conv_p=*/NULL, /*parenthesized_p=*/NULL, - /*member_p=*/false); + /*member_p=*/false, + friend_p); /* If we are parsing an abstract-declarator, we must handle the case where the dependent declarator is absent. */ @@ -17024,7 +17028,7 @@ cp_parser_declarator (cp_parser* parser, CPP_OPEN_PAREN); declarator = cp_parser_direct_declarator (parser, dcl_kind, ctor_dtor_or_conv_p, - member_p); + member_p, friend_p); } if (gnu_attributes && declarator && declarator != cp_error_declarator) @@ -17058,14 +17062,14 @@ cp_parser_declarator (cp_parser* parser, we are parsing a direct-declarator. It is CP_PARSER_DECLARATOR_EITHER, if we can accept either - in the case of ambiguity we prefer an abstract declarator, as per - [dcl.ambig.res]. CTOR_DTOR_OR_CONV_P and MEMBER_P are as for - cp_parser_declarator. */ + [dcl.ambig.res]. CTOR_DTOR_OR_CONV_P, MEMBER_P, and FRIEND_P are + as for cp_parser_declarator. */ static cp_declarator * cp_parser_direct_declarator (cp_parser* parser, cp_parser_declarator_kind dcl_kind, int* ctor_dtor_or_conv_p, - bool member_p) + bool member_p, bool friend_p) { cp_token *token; cp_declarator *declarator = NULL; @@ -17246,7 +17250,7 @@ cp_parser_direct_declarator (cp_parser* parser, declarator = cp_parser_declarator (parser, dcl_kind, ctor_dtor_or_conv_p, /*parenthesized_p=*/NULL, - member_p); + member_p, friend_p); parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p; first = false; /* Expect a `)'. */ @@ -17492,6 +17496,24 @@ cp_parser_direct_declarator (cp_parser* parser, for an anonymous type, even if the type got a name for linkage purposes. */ !TYPE_WAS_ANONYMOUS (class_type) + /* Handle correctly (c++/19200): + + struct S { + struct T{}; + friend void S(T); + }; + + and also: + + namespace N { + void S(); + } + + struct S { + friend void N::S(); + }; */ + && !(friend_p + && class_type != qualifying_scope) && constructor_name_p (unqualified_name, class_type)) { @@ -18035,7 +18057,8 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg, abstract_declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_ABSTRACT, NULL, /*parenthesized_p=*/NULL, - /*member_p=*/false); + /*member_p=*/false, + /*friend_p=*/false); /* Check to see if there really was a declarator. */ if (!cp_parser_parse_definitely (parser)) abstract_declarator = NULL; @@ -18610,7 +18633,8 @@ cp_parser_parameter_declaration (cp_parser *parser, CP_PARSER_DECLARATOR_EITHER, /*ctor_dtor_or_conv_p=*/NULL, parenthesized_p, - /*member_p=*/false); + /*member_p=*/false, + /*friend_p=*/false); parser->default_arg_ok_p = saved_default_arg_ok_p; /* After the declarator, allow more attributes. */ decl_specifiers.attributes @@ -20446,7 +20470,8 @@ cp_parser_member_declaration (cp_parser* parser) = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, &ctor_dtor_or_conv_p, /*parenthesized_p=*/NULL, - /*member_p=*/true); + /*member_p=*/true, + friend_p); /* If something went wrong parsing the declarator, make sure that we at least consume some tokens. */ @@ -21274,7 +21299,8 @@ cp_parser_exception_declaration (cp_parser* parser) declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_EITHER, /*ctor_dtor_or_conv_p=*/NULL, /*parenthesized_p=*/NULL, - /*member_p=*/false); + /*member_p=*/false, + /*friend_p=*/false); /* Restore the saved message. */ parser->type_definition_forbidden_message = saved_message; @@ -24820,7 +24846,8 @@ cp_parser_cache_defarg (cp_parser *parser, bool nsdmi) cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, &ctor_dtor_or_conv_p, /*parenthesized_p=*/NULL, - /*member_p=*/true); + /*member_p=*/true, + /*friend_p=*/false); } else { @@ -26106,7 +26133,8 @@ cp_parser_objc_class_ivars (cp_parser* parser) = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, &ctor_dtor_or_conv_p, /*parenthesized_p=*/NULL, - /*member_p=*/false); + /*member_p=*/false, + /*friend_p=*/false); } /* Look for attributes that apply to the ivar. */ @@ -26657,7 +26685,7 @@ cp_parser_objc_struct_declaration (cp_parser *parser) /* Parse the declarator. */ declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, - NULL, NULL, false); + NULL, NULL, false, false); /* Look for attributes that apply to the ivar. */ attributes = cp_parser_attributes_opt (parser); @@ -29170,7 +29198,8 @@ cp_parser_omp_for_loop_init (cp_parser *parser, CP_PARSER_DECLARATOR_NAMED, /*ctor_dtor_or_conv_p=*/NULL, /*parenthesized_p=*/NULL, - /*member_p=*/false); + /*member_p=*/false, + /*friend_p=*/false); attributes = cp_parser_attributes_opt (parser); asm_specification = cp_parser_asm_specification_opt (parser); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 88589089066..df57293d03d 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5350,6 +5350,10 @@ check_valid_ptrmem_cst_expr (tree type, tree expr, return true; if (cxx_dialect >= cxx11 && null_member_pointer_value_p (expr)) return true; + if (processing_template_decl + && TREE_CODE (expr) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (expr, 0)) == OFFSET_REF) + return true; if (complain & tf_error) { error ("%qE is not a valid template argument for type %qT", diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index b665a8d245f..10cc168faf6 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -1331,14 +1331,8 @@ get_pseudo_ti_index (tree type) /* already created. */ break; - /* Create the array of __base_class_type_info entries. - G++ 3.2 allocated an array that had one too many - entries, and then filled that extra entries with - zeros. */ - if (abi_version_at_least (2)) - array_domain = build_index_type (size_int (num_bases - 1)); - else - array_domain = build_index_type (size_int (num_bases)); + /* Create the array of __base_class_type_info entries. */ + array_domain = build_index_type (size_int (num_bases - 1)); base_array = build_array_type ((*tinfo_descs)[TK_BASE_TYPE].type, array_domain); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index ca0c34bf6f2..ec510c96fed 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3493,6 +3493,7 @@ finish_id_expression (tree id_expression, tree wrap; if (VAR_P (decl) && !cp_unevaluated_operand + && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) && DECL_THREAD_LOCAL_P (decl) && (wrap = get_tls_wrapper_fn (decl))) { @@ -5956,7 +5957,7 @@ finish_omp_threadprivate (tree vars) if (! DECL_THREAD_LOCAL_P (v)) { - DECL_TLS_MODEL (v) = decl_default_tls_model (v); + set_decl_tls_model (v, decl_default_tls_model (v)); /* If rtl has been already set for this var, call make_decl_rtl once again, so that encode_section_info has a chance to look at the new decl flags. */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 587ae80bcc1..36166052d08 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -102,6 +102,16 @@ lvalue_kind (const_tree ref) case IMAGPART_EXPR: return lvalue_kind (TREE_OPERAND (ref, 0)); + case MEMBER_REF: + case DOTSTAR_EXPR: + if (TREE_CODE (ref) == MEMBER_REF) + op1_lvalue_kind = clk_ordinary; + else + op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0)); + if (TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (ref, 1)))) + op1_lvalue_kind = clk_none; + return op1_lvalue_kind; + case COMPONENT_REF: op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0)); /* Look at the member designator. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index fa904751325..65dccf7a1b3 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1114,17 +1114,6 @@ comp_array_types (const_tree t1, const_tree t2, bool allow_redeclaration) return false; max1 = TYPE_MAX_VALUE (d1); max2 = TYPE_MAX_VALUE (d2); - if (processing_template_decl && !abi_version_at_least (2) - && !value_dependent_expression_p (max1) - && !value_dependent_expression_p (max2)) - { - /* With abi-1 we do not fold non-dependent array bounds, (and - consequently mangle them incorrectly). We must therefore - fold them here, to verify the domains have the same - value. */ - max1 = fold (max1); - max2 = fold (max2); - } if (!cp_tree_equal (max1, max2)) return false; diff --git a/gcc/cp/vtable-class-hierarchy.c b/gcc/cp/vtable-class-hierarchy.c index 3963d733805..b481273ae85 100644 --- a/gcc/cp/vtable-class-hierarchy.c +++ b/gcc/cp/vtable-class-hierarchy.c @@ -1247,9 +1247,8 @@ vtable_find_or_create_map_decl (tree base_type) /* Put these mmap variables in thr .vtable_map_vars section, so we can find and protect them. */ - set_decl_section_name (var_decl, build_string (strlen (".vtable_map_vars"), - ".vtable_map_vars")); - DECL_HAS_IMPLICIT_SECTION_NAME_P (var_decl) = true; + set_decl_section_name (var_decl, ".vtable_map_vars"); + symtab_get_node (var_decl)->implicit_section = true; DECL_INITIAL (var_decl) = initial_value; comdat_linkage (var_decl); diff --git a/gcc/cprop.c b/gcc/cprop.c index aef3ee85c71..d07bf31e7e2 100644 --- a/gcc/cprop.c +++ b/gcc/cprop.c @@ -374,11 +374,10 @@ dump_hash_table (FILE *file, const char *name, struct hash_table_d *table) static void make_set_regs_unavailable (rtx insn) { - struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); - df_ref *def_rec; + df_ref def; - for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++) - SET_REGNO_REG_SET (reg_set_bitmap, DF_REF_REGNO (*def_rec)); + FOR_EACH_INSN_DEF (def, insn) + SET_REGNO_REG_SET (reg_set_bitmap, DF_REF_REGNO (def)); } /* Top level function to create an assignment hash table. @@ -533,11 +532,10 @@ reg_not_set_p (const_rtx x, const_rtx insn ATTRIBUTE_UNUSED) static void mark_oprs_set (rtx insn) { - struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); - df_ref *def_rec; + df_ref def; - for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++) - SET_REGNO_REG_SET (reg_set_bitmap, DF_REF_REGNO (*def_rec)); + FOR_EACH_INSN_DEF (def, insn) + SET_REGNO_REG_SET (reg_set_bitmap, DF_REF_REGNO (def)); } /* Compute copy/constant propagation working variables. */ diff --git a/gcc/cse.c b/gcc/cse.c index 3ca8e179757..147e3e372d1 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -6406,14 +6406,11 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data) edge pointing to that bb. */ if (bb_has_eh_pred (bb)) { - df_ref *def_rec; + df_ref def; - for (def_rec = df_get_artificial_defs (bb->index); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) - invalidate (DF_REF_REG (def), GET_MODE (DF_REF_REG (def))); - } + FOR_EACH_ARTIFICIAL_DEF (def, bb->index) + if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) + invalidate (DF_REF_REG (def), GET_MODE (DF_REF_REG (def))); } optimize_this_for_speed_p = optimize_bb_for_speed_p (bb); diff --git a/gcc/dce.c b/gcc/dce.c index 0e245779fcd..a11a4d8ea5a 100644 --- a/gcc/dce.c +++ b/gcc/dce.c @@ -96,6 +96,7 @@ deletable_insn_p (rtx insn, bool fast, bitmap arg_stores) { rtx body, x; int i; + df_ref def; if (CALL_P (insn) /* We cannot delete calls inside of the recursive dce because @@ -121,9 +122,9 @@ deletable_insn_p (rtx insn, bool fast, bitmap arg_stores) return false; /* If INSN sets a global_reg, leave it untouched. */ - for (df_ref *def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - if (HARD_REGISTER_NUM_P (DF_REF_REGNO (*def_rec)) - && global_regs[DF_REF_REGNO (*def_rec)]) + FOR_EACH_INSN_DEF (def, insn) + if (HARD_REGISTER_NUM_P (DF_REF_REGNO (def)) + && global_regs[DF_REF_REGNO (def)]) return false; body = PATTERN (insn); @@ -305,18 +306,18 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast, sp + offset. */ if (!fast) { - df_ref *use_rec; + df_ref use; struct df_link *defs; rtx set; - for (use_rec = DF_INSN_USES (call_insn); *use_rec; use_rec++) - if (rtx_equal_p (addr, DF_REF_REG (*use_rec))) + FOR_EACH_INSN_USE (use, call_insn) + if (rtx_equal_p (addr, DF_REF_REG (use))) break; - if (*use_rec == NULL) + if (use == NULL) return false; - for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next) + for (defs = DF_REF_CHAIN (use); defs; defs = defs->next) if (! DF_REF_IS_ARTIFICIAL (defs->ref)) break; @@ -364,15 +365,15 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast, } if (addr != stack_pointer_rtx) { - df_ref *use_rec; + df_ref use; struct df_link *defs; rtx set; - for (use_rec = DF_INSN_USES (call_insn); *use_rec; use_rec++) - if (rtx_equal_p (addr, DF_REF_REG (*use_rec))) + FOR_EACH_INSN_USE (use, call_insn) + if (rtx_equal_p (addr, DF_REF_REG (use))) break; - for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next) + for (defs = DF_REF_CHAIN (use); defs; defs = defs->next) if (! DF_REF_IS_ARTIFICIAL (defs->ref)) break; @@ -429,18 +430,18 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast, break; if (!fast) { - df_ref *use_rec; + df_ref use; struct df_link *defs; rtx set; - for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) - if (rtx_equal_p (addr, DF_REF_REG (*use_rec))) + FOR_EACH_INSN_USE (use, insn) + if (rtx_equal_p (addr, DF_REF_REG (use))) break; - if (*use_rec == NULL) + if (use == NULL) break; - for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next) + for (defs = DF_REF_CHAIN (use); defs; defs = defs->next) if (! DF_REF_IS_ARTIFICIAL (defs->ref)) break; @@ -496,10 +497,10 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast, static void remove_reg_equal_equiv_notes_for_defs (rtx insn) { - df_ref *def_rec; + df_ref def; - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - remove_reg_equal_equiv_notes_for_regno (DF_REF_REGNO (*def_rec)); + FOR_EACH_INSN_DEF (def, insn) + remove_reg_equal_equiv_notes_for_regno (DF_REF_REGNO (def)); } /* Scan all BBs for debug insns and reset those that reference values @@ -515,11 +516,10 @@ reset_unmarked_insns_debug_uses (void) FOR_BB_INSNS_REVERSE_SAFE (bb, insn, next) if (DEBUG_INSN_P (insn)) { - df_ref *use_rec; + df_ref use; - for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) + FOR_EACH_INSN_USE (use, insn) { - df_ref use = *use_rec; struct df_link *defs; for (defs = DF_REF_CHAIN (use); defs; defs = defs->next) { @@ -661,16 +661,13 @@ mark_artificial_uses (void) { basic_block bb; struct df_link *defs; - df_ref *use_rec; + df_ref use; FOR_ALL_BB_FN (bb, cfun) - { - for (use_rec = df_get_artificial_uses (bb->index); - *use_rec; use_rec++) - for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next) - if (! DF_REF_IS_ARTIFICIAL (defs->ref)) - mark_insn (DF_REF_INSN (defs->ref), false); - } + FOR_EACH_ARTIFICIAL_USE (use, bb->index) + for (defs = DF_REF_CHAIN (use); defs; defs = defs->next) + if (!DF_REF_IS_ARTIFICIAL (defs->ref)) + mark_insn (DF_REF_INSN (defs->ref), false); } @@ -680,14 +677,13 @@ static void mark_reg_dependencies (rtx insn) { struct df_link *defs; - df_ref *use_rec; + df_ref use; if (DEBUG_INSN_P (insn)) return; - for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) + FOR_EACH_INSN_USE (use, insn) { - df_ref use = *use_rec; if (dump_file) { fprintf (dump_file, "Processing use of "); @@ -868,14 +864,14 @@ word_dce_process_block (basic_block bb, bool redo_out, FOR_BB_INSNS_REVERSE (bb, insn) if (DEBUG_INSN_P (insn)) { - df_ref *use_rec; - for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) - if (DF_REF_REGNO (*use_rec) >= FIRST_PSEUDO_REGISTER - && (GET_MODE_SIZE (GET_MODE (DF_REF_REAL_REG (*use_rec))) + df_ref use; + FOR_EACH_INSN_USE (use, insn) + if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER + && (GET_MODE_SIZE (GET_MODE (DF_REF_REAL_REG (use))) == 2 * UNITS_PER_WORD) - && !bitmap_bit_p (local_live, 2 * DF_REF_REGNO (*use_rec)) - && !bitmap_bit_p (local_live, 2 * DF_REF_REGNO (*use_rec) + 1)) - dead_debug_add (&debug, *use_rec, DF_REF_REGNO (*use_rec)); + && !bitmap_bit_p (local_live, 2 * DF_REF_REGNO (use)) + && !bitmap_bit_p (local_live, 2 * DF_REF_REGNO (use) + 1)) + dead_debug_add (&debug, use, DF_REF_REGNO (use)); } else if (INSN_P (insn)) { @@ -898,10 +894,10 @@ word_dce_process_block (basic_block bb, bool redo_out, death. */ if (debug.used && !bitmap_empty_p (debug.used)) { - df_ref *def_rec; + df_ref def; - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - dead_debug_insert_temp (&debug, DF_REF_REGNO (*def_rec), insn, + FOR_EACH_INSN_DEF (def, insn) + dead_debug_insert_temp (&debug, DF_REF_REGNO (def), insn, marked_insn_p (insn) && !control_flow_insn_p (insn) ? DEBUG_TEMP_AFTER_WITH_REG_FORCE @@ -939,7 +935,7 @@ dce_process_block (basic_block bb, bool redo_out, bitmap au, bitmap local_live = BITMAP_ALLOC (&dce_tmp_bitmap_obstack); rtx insn; bool block_changed; - df_ref *def_rec; + df_ref def; struct dead_debug_local debug; if (redo_out) @@ -969,11 +965,11 @@ dce_process_block (basic_block bb, bool redo_out, bitmap au, FOR_BB_INSNS_REVERSE (bb, insn) if (DEBUG_INSN_P (insn)) { - df_ref *use_rec; - for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) - if (!bitmap_bit_p (local_live, DF_REF_REGNO (*use_rec)) - && !bitmap_bit_p (au, DF_REF_REGNO (*use_rec))) - dead_debug_add (&debug, *use_rec, DF_REF_REGNO (*use_rec)); + df_ref use; + FOR_EACH_INSN_USE (use, insn) + if (!bitmap_bit_p (local_live, DF_REF_REGNO (use)) + && !bitmap_bit_p (au, DF_REF_REGNO (use))) + dead_debug_add (&debug, use, DF_REF_REGNO (use)); } else if (INSN_P (insn)) { @@ -981,9 +977,9 @@ dce_process_block (basic_block bb, bool redo_out, bitmap au, /* The insn is needed if there is someone who uses the output. */ if (!needed) - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - if (bitmap_bit_p (local_live, DF_REF_REGNO (*def_rec)) - || bitmap_bit_p (au, DF_REF_REGNO (*def_rec))) + FOR_EACH_INSN_DEF (def, insn) + if (bitmap_bit_p (local_live, DF_REF_REGNO (def)) + || bitmap_bit_p (au, DF_REF_REGNO (def))) { needed = true; mark_insn (insn, true); @@ -1004,8 +1000,8 @@ dce_process_block (basic_block bb, bool redo_out, bitmap au, was marked, in case the debug use was after the point of death. */ if (debug.used && !bitmap_empty_p (debug.used)) - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - dead_debug_insert_temp (&debug, DF_REF_REGNO (*def_rec), insn, + FOR_EACH_INSN_DEF (def, insn) + dead_debug_insert_temp (&debug, DF_REF_REGNO (def), insn, needed && !control_flow_insn_p (insn) ? DEBUG_TEMP_AFTER_WITH_REG_FORCE : DEBUG_TEMP_BEFORE_WITH_VALUE); diff --git a/gcc/ddg.c b/gcc/ddg.c index d6ee0c2e69b..7ba6831647d 100644 --- a/gcc/ddg.c +++ b/gcc/ddg.c @@ -169,11 +169,11 @@ autoinc_var_is_used_p (rtx def_insn, rtx use_insn) static bool def_has_ccmode_p (rtx insn) { - df_ref *def; + df_ref def; - for (def = DF_INSN_DEFS (insn); *def; def++) + FOR_EACH_INSN_DEF (def, insn) { - enum machine_mode mode = GET_MODE (DF_REF_REG (*def)); + enum machine_mode mode = GET_MODE (DF_REF_REG (def)); if (GET_MODE_CLASS (mode) == MODE_CC) return true; diff --git a/gcc/df-core.c b/gcc/df-core.c index 9fdf601071c..074b320b399 100644 --- a/gcc/df-core.c +++ b/gcc/df-core.c @@ -1947,21 +1947,16 @@ df_ref df_bb_regno_first_def_find (basic_block bb, unsigned int regno) { rtx insn; - df_ref *def_rec; - unsigned int uid; + df_ref def; FOR_BB_INSNS (bb, insn) { if (!INSN_P (insn)) continue; - uid = INSN_UID (insn); - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (DF_REF_REGNO (def) == regno) - return def; - } + FOR_EACH_INSN_DEF (def, insn) + if (DF_REF_REGNO (def) == regno) + return def; } return NULL; } @@ -1973,21 +1968,16 @@ df_ref df_bb_regno_last_def_find (basic_block bb, unsigned int regno) { rtx insn; - df_ref *def_rec; - unsigned int uid; + df_ref def; FOR_BB_INSNS_REVERSE (bb, insn) { if (!INSN_P (insn)) continue; - uid = INSN_UID (insn); - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (DF_REF_REGNO (def) == regno) - return def; - } + FOR_EACH_INSN_DEF (def, insn) + if (DF_REF_REGNO (def) == regno) + return def; } return NULL; @@ -1999,20 +1989,15 @@ df_bb_regno_last_def_find (basic_block bb, unsigned int regno) df_ref df_find_def (rtx insn, rtx reg) { - unsigned int uid; - df_ref *def_rec; + df_ref def; if (GET_CODE (reg) == SUBREG) reg = SUBREG_REG (reg); gcc_assert (REG_P (reg)); - uid = INSN_UID (insn); - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (DF_REF_REGNO (def) == REGNO (reg)) - return def; - } + FOR_EACH_INSN_DEF (def, insn) + if (DF_REF_REGNO (def) == REGNO (reg)) + return def; return NULL; } @@ -2033,27 +2018,20 @@ df_reg_defined (rtx insn, rtx reg) df_ref df_find_use (rtx insn, rtx reg) { - unsigned int uid; - df_ref *use_rec; + df_ref use; if (GET_CODE (reg) == SUBREG) reg = SUBREG_REG (reg); gcc_assert (REG_P (reg)); - uid = INSN_UID (insn); - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) - { - df_ref use = *use_rec; + df_insn_info *insn_info = DF_INSN_INFO_GET (insn); + FOR_EACH_INSN_INFO_USE (use, insn_info) + if (DF_REF_REGNO (use) == REGNO (reg)) + return use; + if (df->changeable_flags & DF_EQ_NOTES) + FOR_EACH_INSN_INFO_EQ_USE (use, insn_info) if (DF_REF_REGNO (use) == REGNO (reg)) return use; - } - if (df->changeable_flags & DF_EQ_NOTES) - for (use_rec = DF_INSN_UID_EQ_USES (uid); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if (DF_REF_REGNO (use) == REGNO (reg)) - return use; - } return NULL; } @@ -2341,16 +2319,14 @@ df_ref_dump (df_ref ref, FILE *file) } void -df_refs_chain_dump (df_ref *ref_rec, bool follow_chain, FILE *file) +df_refs_chain_dump (df_ref ref, bool follow_chain, FILE *file) { fprintf (file, "{ "); - while (*ref_rec) + for (; ref; ref = DF_REF_NEXT_LOC (ref)) { - df_ref ref = *ref_rec; df_ref_dump (ref, file); if (follow_chain) df_chain_dump (DF_REF_CHAIN (ref), file); - ref_rec++; } fprintf (file, "}"); } @@ -2372,15 +2348,12 @@ df_regs_chain_dump (df_ref ref, FILE *file) static void -df_mws_dump (struct df_mw_hardreg **mws, FILE *file) +df_mws_dump (struct df_mw_hardreg *mws, FILE *file) { - while (*mws) - { - fprintf (file, "mw %c r[%d..%d]\n", - (DF_MWS_REG_DEF_P (*mws)) ? 'd' : 'u', - (*mws)->start_regno, (*mws)->end_regno); - mws++; - } + for (; mws; mws = DF_MWS_NEXT (mws)) + fprintf (file, "mw %c r[%d..%d]\n", + DF_MWS_REG_DEF_P (mws) ? 'd' : 'u', + mws->start_regno, mws->end_regno); } diff --git a/gcc/df-problems.c b/gcc/df-problems.c index 77f8c9922b4..e8248659a77 100644 --- a/gcc/df-problems.c +++ b/gcc/df-problems.c @@ -245,20 +245,17 @@ void df_rd_simulate_artificial_defs_at_top (basic_block bb, bitmap local_rd) { int bb_index = bb->index; - df_ref *def_rec; - for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) - { - unsigned int dregno = DF_REF_REGNO (def); - if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) - bitmap_clear_range (local_rd, - DF_DEFS_BEGIN (dregno), - DF_DEFS_COUNT (dregno)); - bitmap_set_bit (local_rd, DF_REF_ID (def)); - } - } + df_ref def; + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) + if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) + { + unsigned int dregno = DF_REF_REGNO (def); + if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) + bitmap_clear_range (local_rd, + DF_DEFS_BEGIN (dregno), + DF_DEFS_COUNT (dregno)); + bitmap_set_bit (local_rd, DF_REF_ID (def)); + } } /* Add the effect of the defs of INSN to the reaching definitions bitmap @@ -268,12 +265,10 @@ void df_rd_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx insn, bitmap local_rd) { - unsigned uid = INSN_UID (insn); - df_ref *def_rec; + df_ref def; - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + FOR_EACH_INSN_DEF (def, insn) { - df_ref def = *def_rec; unsigned int dregno = DF_REF_REGNO (def); if ((!(df->changeable_flags & DF_NO_HARD_REGS)) || (dregno >= FIRST_PSEUDO_REGISTER)) @@ -296,12 +291,11 @@ df_rd_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx insn, static void df_rd_bb_local_compute_process_def (struct df_rd_bb_info *bb_info, - df_ref *def_rec, + df_ref def, int top_flag) { - while (*def_rec) + for (; def; def = DF_REF_NEXT_LOC (def)) { - df_ref def = *def_rec; if (top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP)) { unsigned int regno = DF_REF_REGNO (def); @@ -344,7 +338,6 @@ df_rd_bb_local_compute_process_def (struct df_rd_bb_info *bb_info, } } } - def_rec++; } } @@ -836,81 +829,61 @@ df_lr_bb_local_compute (unsigned int bb_index) basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index); struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index); rtx insn; - df_ref *def_rec; - df_ref *use_rec; + df_ref def, use; /* Process the registers set in an exception handler. */ - for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0) - { - unsigned int dregno = DF_REF_REGNO (def); - bitmap_set_bit (&bb_info->def, dregno); - bitmap_clear_bit (&bb_info->use, dregno); - } - } + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) + if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0) + { + unsigned int dregno = DF_REF_REGNO (def); + bitmap_set_bit (&bb_info->def, dregno); + bitmap_clear_bit (&bb_info->use, dregno); + } /* Process the hardware registers that are always live. */ - for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++) - { - df_ref use = *use_rec; - /* Add use to set of uses in this BB. */ - if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) - bitmap_set_bit (&bb_info->use, DF_REF_REGNO (use)); - } + FOR_EACH_ARTIFICIAL_USE (use, bb_index) + /* Add use to set of uses in this BB. */ + if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) + bitmap_set_bit (&bb_info->use, DF_REF_REGNO (use)); FOR_BB_INSNS_REVERSE (bb, insn) { - unsigned int uid = INSN_UID (insn); - if (!NONDEBUG_INSN_P (insn)) continue; - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) - { - df_ref def = *def_rec; - /* If the def is to only part of the reg, it does - not kill the other defs that reach here. */ - if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) - { - unsigned int dregno = DF_REF_REGNO (def); - bitmap_set_bit (&bb_info->def, dregno); - bitmap_clear_bit (&bb_info->use, dregno); - } - } + df_insn_info *insn_info = DF_INSN_INFO_GET (insn); + FOR_EACH_INSN_INFO_DEF (def, insn_info) + /* If the def is to only part of the reg, it does + not kill the other defs that reach here. */ + if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) + { + unsigned int dregno = DF_REF_REGNO (def); + bitmap_set_bit (&bb_info->def, dregno); + bitmap_clear_bit (&bb_info->use, dregno); + } - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) - { - df_ref use = *use_rec; - /* Add use to set of uses in this BB. */ - bitmap_set_bit (&bb_info->use, DF_REF_REGNO (use)); - } + FOR_EACH_INSN_INFO_USE (use, insn_info) + /* Add use to set of uses in this BB. */ + bitmap_set_bit (&bb_info->use, DF_REF_REGNO (use)); } /* Process the registers set in an exception handler or the hard frame pointer if this block is the target of a non local goto. */ - for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) - { - unsigned int dregno = DF_REF_REGNO (def); - bitmap_set_bit (&bb_info->def, dregno); - bitmap_clear_bit (&bb_info->use, dregno); - } - } + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) + if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) + { + unsigned int dregno = DF_REF_REGNO (def); + bitmap_set_bit (&bb_info->def, dregno); + bitmap_clear_bit (&bb_info->use, dregno); + } #ifdef EH_USES /* Process the uses that are live into an exception handler. */ - for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++) - { - df_ref use = *use_rec; - /* Add use to set of uses in this BB. */ - if (DF_REF_FLAGS (use) & DF_REF_AT_TOP) - bitmap_set_bit (&bb_info->use, DF_REF_REGNO (use)); - } + FOR_EACH_ARTIFICIAL_USE (use, bb_index) + /* Add use to set of uses in this BB. */ + if (DF_REF_FLAGS (use) & DF_REF_AT_TOP) + bitmap_set_bit (&bb_info->use, DF_REF_REGNO (use)); #endif /* If the df_live problem is not defined, such as at -O0 and -O1, we @@ -1463,7 +1436,7 @@ df_live_bb_local_compute (unsigned int bb_index) basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index); struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index); rtx insn; - df_ref *def_rec; + df_ref def; int luid = 0; FOR_BB_INSNS (bb, insn) @@ -1484,9 +1457,8 @@ df_live_bb_local_compute (unsigned int bb_index) continue; luid++; - for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++) + FOR_EACH_INSN_INFO_DEF (def, insn_info) { - df_ref def = *def_rec; unsigned int regno = DF_REF_REGNO (def); if (DF_REF_FLAGS_IS_SET (def, @@ -1503,11 +1475,8 @@ df_live_bb_local_compute (unsigned int bb_index) } } - for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) - { - df_ref def = *def_rec; - bitmap_set_bit (&bb_info->gen, DF_REF_REGNO (def)); - } + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) + bitmap_set_bit (&bb_info->gen, DF_REF_REGNO (def)); } @@ -1983,35 +1952,31 @@ df_chain_remove_problem (void) EXECUTE_IF_SET_IN_BITMAP (df_chain->out_of_date_transfer_functions, 0, bb_index, bi) { rtx insn; - df_ref *def_rec; - df_ref *use_rec; + df_ref def, use; basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index); if (df_chain_problem_p (DF_DU_CHAIN)) - for (def_rec = df_get_artificial_defs (bb->index); *def_rec; def_rec++) - DF_REF_CHAIN (*def_rec) = NULL; + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) + DF_REF_CHAIN (def) = NULL; if (df_chain_problem_p (DF_UD_CHAIN)) - for (use_rec = df_get_artificial_uses (bb->index); *use_rec; use_rec++) - DF_REF_CHAIN (*use_rec) = NULL; + FOR_EACH_ARTIFICIAL_USE (use, bb_index) + DF_REF_CHAIN (use) = NULL; FOR_BB_INSNS (bb, insn) - { - unsigned int uid = INSN_UID (insn); - - if (INSN_P (insn)) - { - if (df_chain_problem_p (DF_DU_CHAIN)) - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) - DF_REF_CHAIN (*def_rec) = NULL; - if (df_chain_problem_p (DF_UD_CHAIN)) - { - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) - DF_REF_CHAIN (*use_rec) = NULL; - for (use_rec = DF_INSN_UID_EQ_USES (uid); *use_rec; use_rec++) - DF_REF_CHAIN (*use_rec) = NULL; - } - } - } + if (INSN_P (insn)) + { + df_insn_info *insn_info = DF_INSN_INFO_GET (insn); + if (df_chain_problem_p (DF_DU_CHAIN)) + FOR_EACH_INSN_INFO_DEF (def, insn_info) + DF_REF_CHAIN (def) = NULL; + if (df_chain_problem_p (DF_UD_CHAIN)) + { + FOR_EACH_INSN_INFO_USE (use, insn_info) + DF_REF_CHAIN (use) = NULL; + FOR_EACH_INSN_INFO_EQ_USE (use, insn_info) + DF_REF_CHAIN (use) = NULL; + } + } } bitmap_clear (df_chain->out_of_date_transfer_functions); @@ -2055,15 +2020,14 @@ df_chain_reset (bitmap blocks_to_clear ATTRIBUTE_UNUSED) static void df_chain_create_bb_process_use (bitmap local_rd, - df_ref *use_rec, + df_ref use, int top_flag) { bitmap_iterator bi; unsigned int def_index; - while (*use_rec) + for (; use; use = DF_REF_NEXT_LOC (use)) { - df_ref use = *use_rec; unsigned int uregno = DF_REF_REGNO (use); if ((!(df->changeable_flags & DF_NO_HARD_REGS)) || (uregno >= FIRST_PSEUDO_REGISTER)) @@ -2092,8 +2056,6 @@ df_chain_create_bb_process_use (bitmap local_rd, } } } - - use_rec++; } } @@ -2191,48 +2153,35 @@ df_chain_bb_dump (basic_block bb, FILE *file, bool top) return; if (df_chain_problem_p (DF_UD_CHAIN)) { + df_ref use; + fprintf (file, ";; UD chains for artificial uses at %s\n", top ? "top" : "bottom"); - df_ref *use_rec = df_get_artificial_uses (bb->index); - if (*use_rec) - { - while (*use_rec) - { - df_ref use = *use_rec; - if ((top && (DF_REF_FLAGS (use) & DF_REF_AT_TOP)) - || (!top && !(DF_REF_FLAGS (use) & DF_REF_AT_TOP))) - { - fprintf (file, ";; reg %d ", DF_REF_REGNO (use)); - df_chain_dump (DF_REF_CHAIN (use), file); - fprintf (file, "\n"); - } - use_rec++; - } - } + FOR_EACH_ARTIFICIAL_USE (use, bb->index) + if ((top && (DF_REF_FLAGS (use) & DF_REF_AT_TOP)) + || (!top && !(DF_REF_FLAGS (use) & DF_REF_AT_TOP))) + { + fprintf (file, ";; reg %d ", DF_REF_REGNO (use)); + df_chain_dump (DF_REF_CHAIN (use), file); + fprintf (file, "\n"); + } } if (df_chain_problem_p (DF_DU_CHAIN)) { + df_ref def; + fprintf (file, ";; DU chains for artificial defs at %s\n", top ? "top" : "bottom"); - df_ref *def_rec = df_get_artificial_defs (bb->index); - if (*def_rec) - { - while (*def_rec) - { - df_ref def = *def_rec; - - if ((top && (DF_REF_FLAGS (def) & DF_REF_AT_TOP)) - || (!top && !(DF_REF_FLAGS (def) & DF_REF_AT_TOP))) - { - fprintf (file, ";; reg %d ", DF_REF_REGNO (def)); - df_chain_dump (DF_REF_CHAIN (def), file); - fprintf (file, "\n"); - } - def_rec++; - } - } + FOR_EACH_ARTIFICIAL_DEF (def, bb->index) + if ((top && (DF_REF_FLAGS (def) & DF_REF_AT_TOP)) + || (!top && !(DF_REF_FLAGS (def) & DF_REF_AT_TOP))) + { + fprintf (file, ";; reg %d ", DF_REF_REGNO (def)); + df_chain_dump (DF_REF_CHAIN (def), file); + fprintf (file, "\n"); + } } } @@ -2254,39 +2203,28 @@ df_chain_insn_top_dump (const_rtx insn, FILE *file) if (df_chain_problem_p (DF_UD_CHAIN) && INSN_P (insn)) { struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); - df_ref *use_rec = DF_INSN_INFO_USES (insn_info); - df_ref *eq_use_rec = DF_INSN_INFO_EQ_USES (insn_info); + df_ref use; + fprintf (file, ";; UD chains for insn luid %d uid %d\n", DF_INSN_INFO_LUID (insn_info), INSN_UID (insn)); - if (*use_rec || *eq_use_rec) - { - while (*use_rec) - { - df_ref use = *use_rec; - if (! HARD_REGISTER_NUM_P (DF_REF_REGNO (use)) - || !(df->changeable_flags & DF_NO_HARD_REGS)) - { - fprintf (file, ";; reg %d ", DF_REF_REGNO (use)); - if (DF_REF_FLAGS (use) & DF_REF_READ_WRITE) - fprintf (file, "read/write "); - df_chain_dump (DF_REF_CHAIN (use), file); - fprintf (file, "\n"); - } - use_rec++; - } - while (*eq_use_rec) - { - df_ref use = *eq_use_rec; - if (! HARD_REGISTER_NUM_P (DF_REF_REGNO (use)) - || !(df->changeable_flags & DF_NO_HARD_REGS)) - { - fprintf (file, ";; eq_note reg %d ", DF_REF_REGNO (use)); - df_chain_dump (DF_REF_CHAIN (use), file); - fprintf (file, "\n"); - } - eq_use_rec++; - } - } + FOR_EACH_INSN_INFO_USE (use, insn_info) + if (!HARD_REGISTER_NUM_P (DF_REF_REGNO (use)) + || !(df->changeable_flags & DF_NO_HARD_REGS)) + { + fprintf (file, ";; reg %d ", DF_REF_REGNO (use)); + if (DF_REF_FLAGS (use) & DF_REF_READ_WRITE) + fprintf (file, "read/write "); + df_chain_dump (DF_REF_CHAIN (use), file); + fprintf (file, "\n"); + } + FOR_EACH_INSN_INFO_EQ_USE (use, insn_info) + if (!HARD_REGISTER_NUM_P (DF_REF_REGNO (use)) + || !(df->changeable_flags & DF_NO_HARD_REGS)) + { + fprintf (file, ";; eq_note reg %d ", DF_REF_REGNO (use)); + df_chain_dump (DF_REF_CHAIN (use), file); + fprintf (file, "\n"); + } } } @@ -2296,26 +2234,19 @@ df_chain_insn_bottom_dump (const_rtx insn, FILE *file) if (df_chain_problem_p (DF_DU_CHAIN) && INSN_P (insn)) { struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); - df_ref *def_rec = DF_INSN_INFO_DEFS (insn_info); + df_ref def; fprintf (file, ";; DU chains for insn luid %d uid %d\n", DF_INSN_INFO_LUID (insn_info), INSN_UID (insn)); - if (*def_rec) - { - while (*def_rec) - { - df_ref def = *def_rec; - if (! HARD_REGISTER_NUM_P (DF_REF_REGNO (def)) - || !(df->changeable_flags & DF_NO_HARD_REGS)) - { - fprintf (file, ";; reg %d ", DF_REF_REGNO (def)); - if (DF_REF_FLAGS (def) & DF_REF_READ_WRITE) - fprintf (file, "read/write "); - df_chain_dump (DF_REF_CHAIN (def), file); - fprintf (file, "\n"); - } - def_rec++; - } - } + FOR_EACH_INSN_INFO_DEF (def, insn_info) + if (!HARD_REGISTER_NUM_P (DF_REF_REGNO (def)) + || !(df->changeable_flags & DF_NO_HARD_REGS)) + { + fprintf (file, ";; reg %d ", DF_REF_REGNO (def)); + if (DF_REF_FLAGS (def) & DF_REF_READ_WRITE) + fprintf (file, "read/write "); + df_chain_dump (DF_REF_CHAIN (def), file); + fprintf (file, "\n"); + } fprintf (file, "\n"); } } @@ -2532,44 +2463,31 @@ df_word_lr_bb_local_compute (unsigned int bb_index) basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index); struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index); rtx insn; - df_ref *def_rec; - df_ref *use_rec; + df_ref def, use; /* Ensure that artificial refs don't contain references to pseudos. */ - for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) - { - df_ref def = *def_rec; - gcc_assert (DF_REF_REGNO (def) < FIRST_PSEUDO_REGISTER); - } + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) + gcc_assert (DF_REF_REGNO (def) < FIRST_PSEUDO_REGISTER); - for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++) - { - df_ref use = *use_rec; - gcc_assert (DF_REF_REGNO (use) < FIRST_PSEUDO_REGISTER); - } + FOR_EACH_ARTIFICIAL_USE (use, bb_index) + gcc_assert (DF_REF_REGNO (use) < FIRST_PSEUDO_REGISTER); FOR_BB_INSNS_REVERSE (bb, insn) { - unsigned int uid = INSN_UID (insn); - if (!NONDEBUG_INSN_P (insn)) continue; - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) - { - df_ref def = *def_rec; - /* If the def is to only part of the reg, it does - not kill the other defs that reach here. */ - if (!(DF_REF_FLAGS (def) & (DF_REF_CONDITIONAL))) - { - df_word_lr_mark_ref (def, true, &bb_info->def); - df_word_lr_mark_ref (def, false, &bb_info->use); - } - } - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) - { - df_ref use = *use_rec; - df_word_lr_mark_ref (use, true, &bb_info->use); - } + + df_insn_info *insn_info = DF_INSN_INFO_GET (insn); + FOR_EACH_INSN_INFO_DEF (def, insn_info) + /* If the def is to only part of the reg, it does + not kill the other defs that reach here. */ + if (!(DF_REF_FLAGS (def) & (DF_REF_CONDITIONAL))) + { + df_word_lr_mark_ref (def, true, &bb_info->def); + df_word_lr_mark_ref (def, false, &bb_info->use); + } + FOR_EACH_INSN_INFO_USE (use, insn_info) + df_word_lr_mark_ref (use, true, &bb_info->use); } } @@ -2753,17 +2671,13 @@ bool df_word_lr_simulate_defs (rtx insn, bitmap live) { bool changed = false; - df_ref *def_rec; - unsigned int uid = INSN_UID (insn); + df_ref def; - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (DF_REF_FLAGS (def) & DF_REF_CONDITIONAL) - changed = true; - else - changed |= df_word_lr_mark_ref (*def_rec, false, live); - } + FOR_EACH_INSN_DEF (def, insn) + if (DF_REF_FLAGS (def) & DF_REF_CONDITIONAL) + changed = true; + else + changed |= df_word_lr_mark_ref (def, false, live); return changed; } @@ -2773,11 +2687,10 @@ df_word_lr_simulate_defs (rtx insn, bitmap live) void df_word_lr_simulate_uses (rtx insn, bitmap live) { - df_ref *use_rec; - unsigned int uid = INSN_UID (insn); + df_ref use; - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) - df_word_lr_mark_ref (*use_rec, true, live); + FOR_EACH_INSN_USE (use, insn) + df_word_lr_mark_ref (use, true, live); } /*---------------------------------------------------------------------------- @@ -2899,22 +2812,19 @@ df_remove_dead_eq_notes (rtx insn, bitmap live) one REG_EQUAL/EQUIV note, all of EQ_USES will refer to this note so we need to purge the complete EQ_USES vector when removing the note using df_notes_rescan. */ - df_ref *use_rec; + df_ref use; bool deleted = false; - for (use_rec = DF_INSN_EQ_USES (insn); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if (DF_REF_REGNO (use) > FIRST_PSEUDO_REGISTER - && DF_REF_LOC (use) - && (DF_REF_FLAGS (use) & DF_REF_IN_NOTE) - && ! bitmap_bit_p (live, DF_REF_REGNO (use)) - && loc_mentioned_in_p (DF_REF_LOC (use), XEXP (link, 0))) - { - deleted = true; - break; - } - } + FOR_EACH_INSN_EQ_USE (use, insn) + if (DF_REF_REGNO (use) > FIRST_PSEUDO_REGISTER + && DF_REF_LOC (use) + && (DF_REF_FLAGS (use) & DF_REF_IN_NOTE) + && !bitmap_bit_p (live, DF_REF_REGNO (use)) + && loc_mentioned_in_p (DF_REF_LOC (use), XEXP (link, 0))) + { + deleted = true; + break; + } if (deleted) { rtx next; @@ -3154,8 +3064,7 @@ df_note_bb_compute (unsigned int bb_index, { basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index); rtx insn; - df_ref *def_rec; - df_ref *use_rec; + df_ref def, use; struct dead_debug_local debug; dead_debug_local_init (&debug, NULL, NULL); @@ -3171,10 +3080,8 @@ df_note_bb_compute (unsigned int bb_index, /* Process the artificial defs and uses at the bottom of the block to begin processing. */ - for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) { - df_ref def = *def_rec; - if (REG_DEAD_DEBUGGING && dump_file) fprintf (dump_file, "artificial def %d\n", DF_REF_REGNO (def)); @@ -3182,19 +3089,16 @@ df_note_bb_compute (unsigned int bb_index, bitmap_clear_bit (live, DF_REF_REGNO (def)); } - for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) - { - unsigned int regno = DF_REF_REGNO (use); - bitmap_set_bit (live, regno); + FOR_EACH_ARTIFICIAL_USE (use, bb_index) + if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) + { + unsigned int regno = DF_REF_REGNO (use); + bitmap_set_bit (live, regno); - /* Notes are not generated for any of the artificial registers - at the bottom of the block. */ - bitmap_set_bit (artificial_uses, regno); - } - } + /* Notes are not generated for any of the artificial registers + at the bottom of the block. */ + bitmap_set_bit (artificial_uses, regno); + } if (REG_DEAD_DEBUGGING && dump_file) { @@ -3204,8 +3108,8 @@ df_note_bb_compute (unsigned int bb_index, FOR_BB_INSNS_REVERSE (bb, insn) { - unsigned int uid = INSN_UID (insn); - struct df_mw_hardreg **mws_rec; + df_insn_info *insn_info = DF_INSN_INFO_GET (insn); + df_mw_hardreg *mw; int debug_insn; if (!INSN_P (insn)) @@ -3221,29 +3125,23 @@ df_note_bb_compute (unsigned int bb_index, { if (REG_DEAD_DEBUGGING && dump_file) { - fprintf (dump_file, "processing call %d\n live =", INSN_UID (insn)); + fprintf (dump_file, "processing call %d\n live =", + INSN_UID (insn)); df_print_regset (dump_file, live); } /* We only care about real sets for calls. Clobbers cannot be depended on to really die. */ - mws_rec = DF_INSN_UID_MWS (uid); - while (*mws_rec) - { - struct df_mw_hardreg *mws = *mws_rec; - if ((DF_MWS_REG_DEF_P (mws)) - && !df_ignore_stack_reg (mws->start_regno)) - df_set_unused_notes_for_mw (insn, - mws, live, do_not_gen, + FOR_EACH_INSN_INFO_MW (mw, insn_info) + if ((DF_MWS_REG_DEF_P (mw)) + && !df_ignore_stack_reg (mw->start_regno)) + df_set_unused_notes_for_mw (insn, mw, live, do_not_gen, artificial_uses, &debug); - mws_rec++; - } /* All of the defs except the return value are some sort of clobber. This code is for the return. */ - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + FOR_EACH_INSN_INFO_DEF (def, insn_info) { - df_ref def = *def_rec; unsigned int dregno = DF_REF_REGNO (def); if (!DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)) { @@ -3259,20 +3157,13 @@ df_note_bb_compute (unsigned int bb_index, else { /* Regular insn. */ - mws_rec = DF_INSN_UID_MWS (uid); - while (*mws_rec) - { - struct df_mw_hardreg *mws = *mws_rec; - if (DF_MWS_REG_DEF_P (mws)) - df_set_unused_notes_for_mw (insn, - mws, live, do_not_gen, - artificial_uses, &debug); - mws_rec++; - } + FOR_EACH_INSN_INFO_MW (mw, insn_info) + if (DF_MWS_REG_DEF_P (mw)) + df_set_unused_notes_for_mw (insn, mw, live, do_not_gen, + artificial_uses, &debug); - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + FOR_EACH_INSN_INFO_DEF (def, insn_info) { - df_ref def = *def_rec; unsigned int dregno = DF_REF_REGNO (def); df_create_unused_note (insn, def, live, artificial_uses, &debug); @@ -3286,29 +3177,22 @@ df_note_bb_compute (unsigned int bb_index, } /* Process the uses. */ - mws_rec = DF_INSN_UID_MWS (uid); - while (*mws_rec) - { - struct df_mw_hardreg *mws = *mws_rec; - if (DF_MWS_REG_USE_P (mws) - && !df_ignore_stack_reg (mws->start_regno)) - { - bool really_add_notes = debug_insn != 0; + FOR_EACH_INSN_INFO_MW (mw, insn_info) + if (DF_MWS_REG_USE_P (mw) + && !df_ignore_stack_reg (mw->start_regno)) + { + bool really_add_notes = debug_insn != 0; - df_set_dead_notes_for_mw (insn, - mws, live, do_not_gen, - artificial_uses, - &really_add_notes); + df_set_dead_notes_for_mw (insn, mw, live, do_not_gen, + artificial_uses, + &really_add_notes); - if (really_add_notes) - debug_insn = -1; - } - mws_rec++; - } + if (really_add_notes) + debug_insn = -1; + } - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) + FOR_EACH_INSN_INFO_USE (use, insn_info) { - df_ref use = *use_rec; unsigned int uregno = DF_REF_REGNO (use); if (REG_DEAD_DEBUGGING && dump_file && !debug_insn) @@ -3475,14 +3359,10 @@ df_note_add_problem (void) void df_simulate_find_defs (rtx insn, bitmap defs) { - df_ref *def_rec; - unsigned int uid = INSN_UID (insn); + df_ref def; - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) - { - df_ref def = *def_rec; - bitmap_set_bit (defs, DF_REF_REGNO (def)); - } + FOR_EACH_INSN_DEF (def, insn) + bitmap_set_bit (defs, DF_REF_REGNO (def)); } /* Find the set of uses for INSN. This includes partial defs. */ @@ -3490,20 +3370,14 @@ df_simulate_find_defs (rtx insn, bitmap defs) static void df_simulate_find_uses (rtx insn, bitmap uses) { - df_ref *rec; - unsigned int uid = INSN_UID (insn); + df_ref def, use; + struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); - for (rec = DF_INSN_UID_DEFS (uid); *rec; rec++) - { - df_ref def = *rec; - if (DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)) - bitmap_set_bit (uses, DF_REF_REGNO (def)); - } - for (rec = DF_INSN_UID_USES (uid); *rec; rec++) - { - df_ref use = *rec; - bitmap_set_bit (uses, DF_REF_REGNO (use)); - } + FOR_EACH_INSN_INFO_DEF (def, insn_info) + if (DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)) + bitmap_set_bit (uses, DF_REF_REGNO (def)); + FOR_EACH_INSN_INFO_USE (use, insn_info) + bitmap_set_bit (uses, DF_REF_REGNO (use)); } /* Find the set of real DEFs, which are not clobbers, for INSN. */ @@ -3511,15 +3385,11 @@ df_simulate_find_uses (rtx insn, bitmap uses) void df_simulate_find_noclobber_defs (rtx insn, bitmap defs) { - df_ref *def_rec; - unsigned int uid = INSN_UID (insn); + df_ref def; - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))) - bitmap_set_bit (defs, DF_REF_REGNO (def)); - } + FOR_EACH_INSN_DEF (def, insn) + if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))) + bitmap_set_bit (defs, DF_REF_REGNO (def)); } @@ -3528,12 +3398,10 @@ df_simulate_find_noclobber_defs (rtx insn, bitmap defs) void df_simulate_defs (rtx insn, bitmap live) { - df_ref *def_rec; - unsigned int uid = INSN_UID (insn); + df_ref def; - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + FOR_EACH_INSN_DEF (def, insn) { - df_ref def = *def_rec; unsigned int dregno = DF_REF_REGNO (def); /* If the def is to only part of the reg, it does @@ -3549,18 +3417,14 @@ df_simulate_defs (rtx insn, bitmap live) void df_simulate_uses (rtx insn, bitmap live) { - df_ref *use_rec; - unsigned int uid = INSN_UID (insn); + df_ref use; if (DEBUG_INSN_P (insn)) return; - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) - { - df_ref use = *use_rec; - /* Add use to set of uses in this BB. */ - bitmap_set_bit (live, DF_REF_REGNO (use)); - } + FOR_EACH_INSN_USE (use, insn) + /* Add use to set of uses in this BB. */ + bitmap_set_bit (live, DF_REF_REGNO (use)); } @@ -3596,23 +3460,16 @@ df_simulate_fixup_sets (basic_block bb, bitmap live) void df_simulate_initialize_backwards (basic_block bb, bitmap live) { - df_ref *def_rec; - df_ref *use_rec; + df_ref def, use; int bb_index = bb->index; - for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0) - bitmap_clear_bit (live, DF_REF_REGNO (def)); - } + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) + if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0) + bitmap_clear_bit (live, DF_REF_REGNO (def)); - for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) - bitmap_set_bit (live, DF_REF_REGNO (use)); - } + FOR_EACH_ARTIFICIAL_USE (use, bb_index) + if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) + bitmap_set_bit (live, DF_REF_REGNO (use)); } @@ -3636,26 +3493,20 @@ df_simulate_one_insn_backwards (basic_block bb, rtx insn, bitmap live) void df_simulate_finalize_backwards (basic_block bb, bitmap live) { - df_ref *def_rec; + df_ref def; #ifdef EH_USES - df_ref *use_rec; + df_ref use; #endif int bb_index = bb->index; - for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) - bitmap_clear_bit (live, DF_REF_REGNO (def)); - } + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) + if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) + bitmap_clear_bit (live, DF_REF_REGNO (def)); #ifdef EH_USES - for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if (DF_REF_FLAGS (use) & DF_REF_AT_TOP) - bitmap_set_bit (live, DF_REF_REGNO (use)); - } + FOR_EACH_ARTIFICIAL_USE (use, bb_index) + if (DF_REF_FLAGS (use) & DF_REF_AT_TOP) + bitmap_set_bit (live, DF_REF_REGNO (use)); #endif } /*---------------------------------------------------------------------------- @@ -3677,15 +3528,12 @@ df_simulate_finalize_backwards (basic_block bb, bitmap live) void df_simulate_initialize_forwards (basic_block bb, bitmap live) { - df_ref *def_rec; + df_ref def; int bb_index = bb->index; - for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) - bitmap_set_bit (live, DF_REF_REGNO (def)); - } + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) + if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) + bitmap_set_bit (live, DF_REF_REGNO (def)); } /* Simulate the forwards effects of INSN on the bitmap LIVE. */ @@ -4184,20 +4032,17 @@ void df_md_simulate_artificial_defs_at_top (basic_block bb, bitmap local_md) { int bb_index = bb->index; - df_ref *def_rec; - for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) - { - unsigned int dregno = DF_REF_REGNO (def); - if (DF_REF_FLAGS (def) - & (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER)) - bitmap_set_bit (local_md, dregno); - else - bitmap_clear_bit (local_md, dregno); - } - } + df_ref def; + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) + if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) + { + unsigned int dregno = DF_REF_REGNO (def); + if (DF_REF_FLAGS (def) + & (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER)) + bitmap_set_bit (local_md, dregno); + else + bitmap_clear_bit (local_md, dregno); + } } @@ -4206,14 +4051,12 @@ df_md_simulate_artificial_defs_at_top (basic_block bb, bitmap local_md) void df_md_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx insn, - bitmap local_md) + bitmap local_md) { - unsigned uid = INSN_UID (insn); - df_ref *def_rec; + df_ref def; - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + FOR_EACH_INSN_DEF (def, insn) { - df_ref def = *def_rec; unsigned int dregno = DF_REF_REGNO (def); if ((!(df->changeable_flags & DF_NO_HARD_REGS)) || (dregno >= FIRST_PSEUDO_REGISTER)) @@ -4229,13 +4072,12 @@ df_md_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx insn, static void df_md_bb_local_compute_process_def (struct df_md_bb_info *bb_info, - df_ref *def_rec, + df_ref def, int top_flag) { - df_ref def; bitmap_clear (&seen_in_insn); - while ((def = *def_rec++) != NULL) + for (; def; def = DF_REF_NEXT_LOC (def)) { unsigned int dregno = DF_REF_REGNO (def); if (((!(df->changeable_flags & DF_NO_HARD_REGS)) diff --git a/gcc/df-scan.c b/gcc/df-scan.c index 992d0aff414..f1ba808c258 100644 --- a/gcc/df-scan.c +++ b/gcc/df-scan.c @@ -62,21 +62,6 @@ typedef struct df_mw_hardreg *df_mw_hardreg_ptr; #define EPILOGUE_USES(REGNO) 0 #endif -/* The following two macros free the vecs that hold either the refs or - the mw refs. They are a little tricky because the vec has 0 - elements is special and is not to be freed. */ -#define df_scan_free_ref_vec(V) \ - do { \ - if (V && *V) \ - free (V); \ - } while (0) - -#define df_scan_free_mws_vec(V) \ - do { \ - if (V && *V) \ - free (V); \ - } while (0) - /* The set of hard registers in eliminables[i].from. */ static HARD_REG_SET elim_reg_set; @@ -92,9 +77,6 @@ struct df_collection_rec auto_vec<df_mw_hardreg_ptr, 32> mw_vec; }; -static df_ref df_null_ref_rec[1]; -static struct df_mw_hardreg * df_null_mw_rec[1]; - static void df_ref_record (enum df_ref_class, struct df_collection_rec *, rtx, rtx *, basic_block, struct df_insn_info *, @@ -111,10 +93,6 @@ static void df_uses_record (struct df_collection_rec *, int ref_flags); static void df_install_ref_incremental (df_ref); -static df_ref df_ref_create_structure (enum df_ref_class, - struct df_collection_rec *, rtx, rtx *, - basic_block, struct df_insn_info *, - enum df_ref_type, int ref_flags); static void df_insn_refs_collect (struct df_collection_rec*, basic_block, struct df_insn_info *); static void df_canonize_collection_rec (struct df_collection_rec *); @@ -127,8 +105,8 @@ static void df_record_exit_block_uses (bitmap); static void df_get_exit_block_use_set (bitmap); static void df_get_entry_block_def_set (bitmap); static void df_grow_ref_info (struct df_ref_info *, unsigned int); -static void df_ref_chain_delete_du_chain (df_ref *); -static void df_ref_chain_delete (df_ref *); +static void df_ref_chain_delete_du_chain (df_ref); +static void df_ref_chain_delete (df_ref); static void df_refs_add_to_chains (struct df_collection_rec *, basic_block, rtx, unsigned int); @@ -139,8 +117,10 @@ static void df_exit_block_uses_collect (struct df_collection_rec *, bitmap); static void df_install_ref (df_ref, struct df_reg_info *, struct df_ref_info *, bool); -static int df_ref_compare (const void *, const void *); -static int df_mw_compare (const void *, const void *); +static int df_ref_compare (df_ref, df_ref); +static int df_ref_ptr_compare (const void *, const void *); +static int df_mw_compare (const df_mw_hardreg *, const df_mw_hardreg *); +static int df_mw_ptr_compare (const void *, const void *); static void df_insn_info_delete (unsigned int); @@ -193,36 +173,6 @@ df_scan_free_internal (void) { struct df_scan_problem_data *problem_data = (struct df_scan_problem_data *) df_scan->problem_data; - unsigned int i; - basic_block bb; - - /* The vectors that hold the refs are not pool allocated because - they come in many sizes. This makes them impossible to delete - all at once. */ - for (i = 0; i < DF_INSN_SIZE (); i++) - { - struct df_insn_info *insn_info = DF_INSN_UID_GET (i); - /* Skip the insns that have no insn_info or have been - deleted. */ - if (insn_info) - { - df_scan_free_ref_vec (insn_info->defs); - df_scan_free_ref_vec (insn_info->uses); - df_scan_free_ref_vec (insn_info->eq_uses); - df_scan_free_mws_vec (insn_info->mw_hardregs); - } - } - - FOR_ALL_BB_FN (bb, cfun) - { - unsigned int bb_index = bb->index; - struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb_index); - if (bb_info) - { - df_scan_free_ref_vec (bb_info->artificial_defs); - df_scan_free_ref_vec (bb_info->artificial_uses); - } - } free (df->def_info.refs); free (df->def_info.begin); @@ -279,31 +229,22 @@ df_scan_free_bb_info (basic_block bb, void *vbb_info) { struct df_scan_bb_info *bb_info = (struct df_scan_bb_info *) vbb_info; unsigned int bb_index = bb->index; + rtx insn; - /* See if bb_info is initialized. */ - if (bb_info->artificial_defs) - { - rtx insn; - FOR_BB_INSNS (bb, insn) - { - if (INSN_P (insn)) - df_insn_info_delete (INSN_UID (insn)); - } - - if (bb_index < df_scan->block_info_size) - bb_info = df_scan_get_bb_info (bb_index); - - /* Get rid of any artificial uses or defs. */ - if (bb_info->artificial_defs) - { - df_ref_chain_delete_du_chain (bb_info->artificial_defs); - df_ref_chain_delete_du_chain (bb_info->artificial_uses); - df_ref_chain_delete (bb_info->artificial_defs); - df_ref_chain_delete (bb_info->artificial_uses); - bb_info->artificial_defs = NULL; - bb_info->artificial_uses = NULL; - } - } + FOR_BB_INSNS (bb, insn) + if (INSN_P (insn)) + df_insn_info_delete (INSN_UID (insn)); + + if (bb_index < df_scan->block_info_size) + bb_info = df_scan_get_bb_info (bb_index); + + /* Get rid of any artificial uses or defs. */ + df_ref_chain_delete_du_chain (bb_info->artificial_defs); + df_ref_chain_delete_du_chain (bb_info->artificial_uses); + df_ref_chain_delete (bb_info->artificial_defs); + df_ref_chain_delete (bb_info->artificial_uses); + bb_info->artificial_defs = NULL; + bb_info->artificial_uses = NULL; } @@ -694,40 +635,12 @@ df_uses_create (rtx *loc, rtx insn, int ref_flags) ref_flags); } -/* Create a new ref of type DF_REF_TYPE for register REG at address - LOC within INSN of BB. This function is only used externally. */ - -df_ref -df_ref_create (rtx reg, rtx *loc, rtx insn, - basic_block bb, - enum df_ref_type ref_type, - int ref_flags) -{ - enum df_ref_class cl; - - df_grow_reg_info (); - - /* You cannot hack artificial refs. */ - gcc_assert (insn); - - if (loc) - cl = DF_REF_REGULAR; - else - cl = DF_REF_BASE; - - return df_ref_create_structure (cl, NULL, reg, loc, bb, - DF_INSN_INFO_GET (insn), - ref_type, ref_flags); -} - static void df_install_ref_incremental (df_ref ref) { struct df_reg_info **reg_info; struct df_ref_info *ref_info; - df_ref *ref_rec; - df_ref **ref_rec_ptr; - unsigned int count = 0; + df_ref *ref_ptr; bool add_to_table; rtx insn = DF_REF_INSN (ref); @@ -737,14 +650,14 @@ df_install_ref_incremental (df_ref ref) { reg_info = df->def_regs; ref_info = &df->def_info; - ref_rec_ptr = &DF_INSN_DEFS (insn); + ref_ptr = &DF_INSN_DEFS (insn); add_to_table = ref_info->ref_order != DF_REF_ORDER_NO_TABLE; } else if (DF_REF_FLAGS (ref) & DF_REF_IN_NOTE) { reg_info = df->eq_use_regs; ref_info = &df->use_info; - ref_rec_ptr = &DF_INSN_EQ_USES (insn); + ref_ptr = &DF_INSN_EQ_USES (insn); switch (ref_info->ref_order) { case DF_REF_ORDER_UNORDERED_WITH_NOTES: @@ -761,7 +674,7 @@ df_install_ref_incremental (df_ref ref) { reg_info = df->use_regs; ref_info = &df->use_info; - ref_rec_ptr = &DF_INSN_USES (insn); + ref_ptr = &DF_INSN_USES (insn); add_to_table = ref_info->ref_order != DF_REF_ORDER_NO_TABLE; } @@ -784,29 +697,11 @@ df_install_ref_incremental (df_ref ref) break; } - ref_rec = *ref_rec_ptr; - while (*ref_rec) - { - count++; - ref_rec++; - } + while (*ref_ptr && df_ref_compare (*ref_ptr, ref) < 0) + ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr); - ref_rec = *ref_rec_ptr; - if (count) - { - ref_rec = XRESIZEVEC (df_ref, ref_rec, count+2); - *ref_rec_ptr = ref_rec; - ref_rec[count] = ref; - ref_rec[count+1] = NULL; - qsort (ref_rec, count + 1, sizeof (df_ref), df_ref_compare); - } - else - { - df_ref *ref_rec = XNEWVEC (df_ref, 2); - ref_rec[0] = ref; - ref_rec[1] = NULL; - *ref_rec_ptr = ref_rec; - } + DF_REF_NEXT_LOC (ref) = *ref_ptr; + *ref_ptr = ref; #if 0 if (dump_file) @@ -934,89 +829,6 @@ df_reg_chain_unlink (df_ref ref) } -/* Remove REF from VEC. */ - -static void -df_ref_compress_rec (df_ref **vec_ptr, df_ref ref) -{ - df_ref *vec = *vec_ptr; - - if (vec[1]) - { - while (*vec && *vec != ref) - vec++; - - while (*vec) - { - *vec = *(vec+1); - vec++; - } - } - else - { - free (vec); - *vec_ptr = df_null_ref_rec; - } -} - - -/* Unlink REF from all def-use/use-def chains, etc. */ - -void -df_ref_remove (df_ref ref) -{ -#if 0 - if (dump_file) - { - fprintf (dump_file, "removing ref "); - df_ref_debug (ref, dump_file); - } -#endif - - if (DF_REF_REG_DEF_P (ref)) - { - if (DF_REF_IS_ARTIFICIAL (ref)) - { - struct df_scan_bb_info *bb_info - = df_scan_get_bb_info (DF_REF_BBNO (ref)); - df_ref_compress_rec (&bb_info->artificial_defs, ref); - } - else - { - unsigned int uid = DF_REF_INSN_UID (ref); - struct df_insn_info *insn_rec = DF_INSN_UID_GET (uid); - df_ref_compress_rec (&insn_rec->defs, ref); - } - } - else - { - if (DF_REF_IS_ARTIFICIAL (ref)) - { - struct df_scan_bb_info *bb_info - = df_scan_get_bb_info (DF_REF_BBNO (ref)); - df_ref_compress_rec (&bb_info->artificial_uses, ref); - } - else - { - unsigned int uid = DF_REF_INSN_UID (ref); - struct df_insn_info *insn_rec = DF_INSN_UID_GET (uid); - - if (DF_REF_FLAGS (ref) & DF_REF_IN_NOTE) - df_ref_compress_rec (&insn_rec->eq_uses, ref); - else - df_ref_compress_rec (&insn_rec->uses, ref); - } - } - - /* By deleting the ref directly, df_insn_rescan my not find any - differences even though the block will have changed. So we need - to mark the block dirty ourselves. */ - if (!DEBUG_INSN_P (DF_REF_INSN (ref))) - df_set_bb_dirty (DF_REF_BB (ref)); - df_reg_chain_unlink (ref); -} - - /* Create the insn record for INSN. If there was one there, zero it out. */ @@ -1043,55 +855,43 @@ df_insn_create_insn_record (rtx insn) /* Delete all du chain (DF_REF_CHAIN()) of all refs in the ref chain. */ static void -df_ref_chain_delete_du_chain (df_ref *ref_rec) +df_ref_chain_delete_du_chain (df_ref ref) { - while (*ref_rec) - { - df_ref ref = *ref_rec; - /* CHAIN is allocated by DF_CHAIN. So make sure to - pass df_scan instance for the problem. */ - if (DF_REF_CHAIN (ref)) - df_chain_unlink (ref); - ref_rec++; - } + for (; ref; ref = DF_REF_NEXT_LOC (ref)) + /* CHAIN is allocated by DF_CHAIN. So make sure to + pass df_scan instance for the problem. */ + if (DF_REF_CHAIN (ref)) + df_chain_unlink (ref); } /* Delete all refs in the ref chain. */ static void -df_ref_chain_delete (df_ref *ref_rec) +df_ref_chain_delete (df_ref ref) { - df_ref *start = ref_rec; - while (*ref_rec) + df_ref next; + for (; ref; ref = next) { - df_reg_chain_unlink (*ref_rec); - ref_rec++; + next = DF_REF_NEXT_LOC (ref); + df_reg_chain_unlink (ref); } - - /* If the list is empty, it has a special shared element that is not - to be deleted. */ - if (*start) - free (start); } /* Delete the hardreg chain. */ static void -df_mw_hardreg_chain_delete (struct df_mw_hardreg **hardregs) +df_mw_hardreg_chain_delete (struct df_mw_hardreg *hardregs) { - struct df_scan_problem_data *problem_data; - - if (!hardregs) - return; - - problem_data = (struct df_scan_problem_data *) df_scan->problem_data; + struct df_scan_problem_data *problem_data + = (struct df_scan_problem_data *) df_scan->problem_data; + df_mw_hardreg *next; - while (*hardregs) + for (; hardregs; hardregs = next) { - pool_free (problem_data->mw_reg_pool, *hardregs); - hardregs++; + next = DF_MWS_NEXT (hardregs); + pool_free (problem_data->mw_reg_pool, hardregs); } } @@ -1119,22 +919,19 @@ df_insn_info_delete (unsigned int uid) to notes. How clever. So we cannot just check if it is a valid insn before short circuiting this code, we need to see if we actually initialized it. */ - if (insn_info->defs) + df_mw_hardreg_chain_delete (insn_info->mw_hardregs); + + if (df_chain) { - df_mw_hardreg_chain_delete (insn_info->mw_hardregs); + df_ref_chain_delete_du_chain (insn_info->defs); + df_ref_chain_delete_du_chain (insn_info->uses); + df_ref_chain_delete_du_chain (insn_info->eq_uses); + } - if (df_chain) - { - df_ref_chain_delete_du_chain (insn_info->defs); - df_ref_chain_delete_du_chain (insn_info->uses); - df_ref_chain_delete_du_chain (insn_info->eq_uses); - } + df_ref_chain_delete (insn_info->defs); + df_ref_chain_delete (insn_info->uses); + df_ref_chain_delete (insn_info->eq_uses); - df_ref_chain_delete (insn_info->defs); - df_ref_chain_delete (insn_info->uses); - df_ref_chain_delete (insn_info->eq_uses); - df_scan_free_mws_vec (insn_info->mw_hardregs); - } pool_free (problem_data->insn_pool, insn_info); DF_INSN_UID_SET (uid, NULL); } @@ -1262,10 +1059,10 @@ df_insn_rescan (rtx insn) if (!insn_info) { insn_info = df_insn_create_insn_record (insn); - insn_info->defs = df_null_ref_rec; - insn_info->uses = df_null_ref_rec; - insn_info->eq_uses = df_null_ref_rec; - insn_info->mw_hardregs = df_null_mw_rec; + insn_info->defs = 0; + insn_info->uses = 0; + insn_info->eq_uses = 0; + insn_info->mw_hardregs = 0; } if (dump_file) fprintf (dump_file, "deferring rescan insn with uid = %d.\n", uid); @@ -1342,13 +1139,10 @@ df_insn_rescan_debug_internal (rtx insn) bitmap_clear_bit (&df->insns_to_rescan, uid); bitmap_clear_bit (&df->insns_to_notes_rescan, uid); - if (!insn_info->defs) - return false; - - if (insn_info->defs == df_null_ref_rec - && insn_info->uses == df_null_ref_rec - && insn_info->eq_uses == df_null_ref_rec - && insn_info->mw_hardregs == df_null_mw_rec) + if (insn_info->defs == 0 + && insn_info->uses == 0 + && insn_info->eq_uses == 0 + && insn_info->mw_hardregs == 0) return false; df_mw_hardreg_chain_delete (insn_info->mw_hardregs); @@ -1363,12 +1157,11 @@ df_insn_rescan_debug_internal (rtx insn) df_ref_chain_delete (insn_info->defs); df_ref_chain_delete (insn_info->uses); df_ref_chain_delete (insn_info->eq_uses); - df_scan_free_mws_vec (insn_info->mw_hardregs); - insn_info->defs = df_null_ref_rec; - insn_info->uses = df_null_ref_rec; - insn_info->eq_uses = df_null_ref_rec; - insn_info->mw_hardregs = df_null_mw_rec; + insn_info->defs = 0; + insn_info->uses = 0; + insn_info->eq_uses = 0; + insn_info->mw_hardregs = 0; return true; } @@ -1639,18 +1432,18 @@ df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info, { basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index); rtx insn; - df_ref *ref_rec; + df_ref def, use; if (include_defs) - for (ref_rec = df_get_artificial_defs (bb_index); *ref_rec; ref_rec++) + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) { - unsigned int regno = DF_REF_REGNO (*ref_rec); + unsigned int regno = DF_REF_REGNO (def); ref_info->count[regno]++; } if (include_uses) - for (ref_rec = df_get_artificial_uses (bb_index); *ref_rec; ref_rec++) + FOR_EACH_ARTIFICIAL_USE (use, bb_index) { - unsigned int regno = DF_REF_REGNO (*ref_rec); + unsigned int regno = DF_REF_REGNO (use); ref_info->count[regno]++; } @@ -1658,24 +1451,24 @@ df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info, { if (INSN_P (insn)) { - unsigned int uid = INSN_UID (insn); + struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); if (include_defs) - for (ref_rec = DF_INSN_UID_DEFS (uid); *ref_rec; ref_rec++) + FOR_EACH_INSN_INFO_DEF (def, insn_info) { - unsigned int regno = DF_REF_REGNO (*ref_rec); + unsigned int regno = DF_REF_REGNO (def); ref_info->count[regno]++; } if (include_uses) - for (ref_rec = DF_INSN_UID_USES (uid); *ref_rec; ref_rec++) + FOR_EACH_INSN_INFO_USE (use, insn_info) { - unsigned int regno = DF_REF_REGNO (*ref_rec); + unsigned int regno = DF_REF_REGNO (use); ref_info->count[regno]++; } if (include_eq_uses) - for (ref_rec = DF_INSN_UID_EQ_USES (uid); *ref_rec; ref_rec++) + FOR_EACH_INSN_INFO_EQ_USE (use, insn_info) { - unsigned int regno = DF_REF_REGNO (*ref_rec); + unsigned int regno = DF_REF_REGNO (use); ref_info->count[regno]++; } } @@ -1693,32 +1486,30 @@ df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info, { basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index); rtx insn; - df_ref *ref_rec; + df_ref def, use; if (include_defs) - for (ref_rec = df_get_artificial_defs (bb_index); *ref_rec; ref_rec++) + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) { - df_ref ref = *ref_rec; - unsigned int regno = DF_REF_REGNO (ref); + unsigned int regno = DF_REF_REGNO (def); if (regno >= start) { unsigned int id = ref_info->begin[regno] + ref_info->count[regno]++; - DF_REF_ID (ref) = id; - ref_info->refs[id] = ref; + DF_REF_ID (def) = id; + ref_info->refs[id] = def; } } if (include_uses) - for (ref_rec = df_get_artificial_uses (bb_index); *ref_rec; ref_rec++) + FOR_EACH_ARTIFICIAL_USE (use, bb_index) { - df_ref ref = *ref_rec; - unsigned int regno = DF_REF_REGNO (ref); + unsigned int regno = DF_REF_REGNO (def); if (regno >= start) { unsigned int id = ref_info->begin[regno] + ref_info->count[regno]++; - DF_REF_ID (ref) = id; - ref_info->refs[id] = ref; + DF_REF_ID (use) = id; + ref_info->refs[id] = use; } } @@ -1726,45 +1517,42 @@ df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info, { if (INSN_P (insn)) { - unsigned int uid = INSN_UID (insn); + struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); if (include_defs) - for (ref_rec = DF_INSN_UID_DEFS (uid); *ref_rec; ref_rec++) + FOR_EACH_INSN_INFO_DEF (def, insn_info) { - df_ref ref = *ref_rec; - unsigned int regno = DF_REF_REGNO (ref); + unsigned int regno = DF_REF_REGNO (def); if (regno >= start) { unsigned int id = ref_info->begin[regno] + ref_info->count[regno]++; - DF_REF_ID (ref) = id; - ref_info->refs[id] = ref; + DF_REF_ID (def) = id; + ref_info->refs[id] = def; } } if (include_uses) - for (ref_rec = DF_INSN_UID_USES (uid); *ref_rec; ref_rec++) + FOR_EACH_INSN_INFO_USE (use, insn_info) { - df_ref ref = *ref_rec; - unsigned int regno = DF_REF_REGNO (ref); + unsigned int regno = DF_REF_REGNO (use); if (regno >= start) { unsigned int id = ref_info->begin[regno] + ref_info->count[regno]++; - DF_REF_ID (ref) = id; - ref_info->refs[id] = ref; + DF_REF_ID (use) = id; + ref_info->refs[id] = use; } } if (include_eq_uses) - for (ref_rec = DF_INSN_UID_EQ_USES (uid); *ref_rec; ref_rec++) + FOR_EACH_INSN_INFO_EQ_USE (use, insn_info) { - df_ref ref = *ref_rec; - unsigned int regno = DF_REF_REGNO (ref); + unsigned int regno = DF_REF_REGNO (use); if (regno >= start) { unsigned int id = ref_info->begin[regno] + ref_info->count[regno]++; - DF_REF_ID (ref) = id; - ref_info->refs[id] = ref; + DF_REF_ID (use) = id; + ref_info->refs[id] = use; } } } @@ -1800,19 +1588,15 @@ df_reorganize_refs_by_reg (struct df_ref_info *ref_info, static unsigned int df_add_refs_to_table (unsigned int offset, struct df_ref_info *ref_info, - df_ref *ref_vec) + df_ref ref) { - while (*ref_vec) - { - df_ref ref = *ref_vec; - if ((!(df->changeable_flags & DF_NO_HARD_REGS)) - || (DF_REF_REGNO (ref) >= FIRST_PSEUDO_REGISTER)) - { - ref_info->refs[offset] = ref; - DF_REF_ID (*ref_vec) = offset++; - } - ref_vec++; - } + for (; ref; ref = DF_REF_NEXT_LOC (ref)) + if (!(df->changeable_flags & DF_NO_HARD_REGS) + || (DF_REF_REGNO (ref) >= FIRST_PSEUDO_REGISTER)) + { + ref_info->refs[offset] = ref; + DF_REF_ID (ref) = offset++; + } return offset; } @@ -2039,9 +1823,8 @@ df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df, { df_ref next_ref = DF_REF_NEXT_REG (the_ref); df_ref prev_ref = DF_REF_PREV_REG (the_ref); - df_ref *ref_vec, *ref_vec_t; + df_ref *ref_ptr; struct df_insn_info *insn_info = DF_REF_INSN_INFO (the_ref); - unsigned int count = 0; DF_REF_REGNO (the_ref) = new_regno; DF_REF_REG (the_ref) = regno_reg_rtx[new_regno]; @@ -2068,23 +1851,42 @@ df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df, /* Need to sort the record again that the ref was in because the regno is a sorting key. First, find the right record. */ - if (DF_REF_FLAGS (the_ref) & DF_REF_IN_NOTE) - ref_vec = insn_info->eq_uses; + if (DF_REF_REG_DEF_P (the_ref)) + ref_ptr = &insn_info->defs; + else if (DF_REF_FLAGS (the_ref) & DF_REF_IN_NOTE) + ref_ptr = &insn_info->eq_uses; else - ref_vec = insn_info->uses; + ref_ptr = &insn_info->uses; if (dump_file) fprintf (dump_file, "changing reg in insn %d\n", DF_REF_INSN_UID (the_ref)); - ref_vec_t = ref_vec; - - /* Find the length. */ - while (*ref_vec_t) + /* Stop if we find the current reference or where the reference + needs to be. */ + while (*ref_ptr != the_ref && df_ref_compare (*ref_ptr, the_ref) < 0) + ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr); + if (*ref_ptr != the_ref) { - count++; - ref_vec_t++; + /* The reference needs to be promoted up the list. */ + df_ref next = DF_REF_NEXT_LOC (the_ref); + DF_REF_NEXT_LOC (the_ref) = *ref_ptr; + *ref_ptr = the_ref; + do + ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr); + while (*ref_ptr != the_ref); + *ref_ptr = next; + } + else if (DF_REF_NEXT_LOC (the_ref) + && df_ref_compare (the_ref, DF_REF_NEXT_LOC (the_ref)) > 0) + { + /* The reference needs to be demoted down the list. */ + *ref_ptr = DF_REF_NEXT_LOC (the_ref); + do + ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr); + while (*ref_ptr && df_ref_compare (the_ref, *ref_ptr) > 0); + DF_REF_NEXT_LOC (the_ref) = *ref_ptr; + *ref_ptr = the_ref; } - qsort (ref_vec, count, sizeof (df_ref ), df_ref_compare); the_ref = next_ref; } @@ -2118,51 +1920,24 @@ df_ref_change_reg_with_loc (int old_regno, int new_regno, rtx loc) /* Delete the mw_hardregs that point into the eq_notes. */ -static unsigned int +static void df_mw_hardreg_chain_delete_eq_uses (struct df_insn_info *insn_info) { - struct df_mw_hardreg **mw_vec = insn_info->mw_hardregs; - unsigned int deleted = 0; - unsigned int count = 0; + struct df_mw_hardreg **mw_ptr = &insn_info->mw_hardregs; struct df_scan_problem_data *problem_data = (struct df_scan_problem_data *) df_scan->problem_data; - if (!*mw_vec) - return 0; - - while (*mw_vec) + while (*mw_ptr) { - if ((*mw_vec)->flags & DF_REF_IN_NOTE) + df_mw_hardreg *mw = *mw_ptr; + if (mw->flags & DF_REF_IN_NOTE) { - struct df_mw_hardreg **temp_vec = mw_vec; - - pool_free (problem_data->mw_reg_pool, *mw_vec); - temp_vec = mw_vec; - /* Shove the remaining ones down one to fill the gap. While - this looks n**2, it is highly unusual to have any mw regs - in eq_notes and the chances of more than one are almost - non existent. */ - while (*temp_vec) - { - *temp_vec = *(temp_vec + 1); - temp_vec++; - } - deleted++; + *mw_ptr = DF_MWS_NEXT (mw); + pool_free (problem_data->mw_reg_pool, mw); } else - { - mw_vec++; - count++; - } + mw_ptr = &DF_MWS_NEXT (mw); } - - if (count == 0) - { - df_scan_free_mws_vec (insn_info->mw_hardregs); - insn_info->mw_hardregs = df_null_mw_rec; - return 0; - } - return deleted; } @@ -2196,10 +1971,10 @@ df_notes_rescan (rtx insn) if (!insn_info) { insn_info = df_insn_create_insn_record (insn); - insn_info->defs = df_null_ref_rec; - insn_info->uses = df_null_ref_rec; - insn_info->eq_uses = df_null_ref_rec; - insn_info->mw_hardregs = df_null_mw_rec; + insn_info->defs = 0; + insn_info->uses = 0; + insn_info->eq_uses = 0; + insn_info->mw_hardregs = 0; } bitmap_clear_bit (&df->insns_to_delete, uid); @@ -2218,10 +1993,9 @@ df_notes_rescan (rtx insn) basic_block bb = BLOCK_FOR_INSN (insn); rtx note; struct df_collection_rec collection_rec; - unsigned int num_deleted; - unsigned int mw_len; + unsigned int i; - num_deleted = df_mw_hardreg_chain_delete_eq_uses (insn_info); + df_mw_hardreg_chain_delete_eq_uses (insn_info); df_ref_chain_delete (insn_info->eq_uses); insn_info->eq_uses = NULL; @@ -2243,45 +2017,14 @@ df_notes_rescan (rtx insn) /* Find some place to put any new mw_hardregs. */ df_canonize_collection_rec (&collection_rec); - mw_len = collection_rec.mw_vec.length (); - if (mw_len) + struct df_mw_hardreg **mw_ptr = &insn_info->mw_hardregs, *mw; + FOR_EACH_VEC_ELT (collection_rec.mw_vec, i, mw) { - unsigned int count = 0; - struct df_mw_hardreg **mw_rec = insn_info->mw_hardregs; - while (*mw_rec) - { - count++; - mw_rec++; - } - - if (count) - { - /* Append to the end of the existing record after - expanding it if necessary. */ - if (mw_len > num_deleted) - { - insn_info->mw_hardregs = - XRESIZEVEC (struct df_mw_hardreg *, - insn_info->mw_hardregs, - count + 1 + mw_len); - } - memcpy (&insn_info->mw_hardregs[count], - collection_rec.mw_vec.address (), - mw_len * sizeof (struct df_mw_hardreg *)); - insn_info->mw_hardregs[count + mw_len] = NULL; - qsort (insn_info->mw_hardregs, count + mw_len, - sizeof (struct df_mw_hardreg *), df_mw_compare); - } - else - { - /* No vector there. */ - insn_info->mw_hardregs - = XNEWVEC (struct df_mw_hardreg*, 1 + mw_len); - memcpy (insn_info->mw_hardregs, - collection_rec.mw_vec.address (), - mw_len * sizeof (struct df_mw_hardreg *)); - insn_info->mw_hardregs[mw_len] = NULL; - } + while (*mw_ptr && df_mw_compare (*mw_ptr, mw) < 0) + mw_ptr = &DF_MWS_NEXT (*mw_ptr); + DF_MWS_NEXT (mw) = *mw_ptr; + *mw_ptr = mw; + mw_ptr = &DF_MWS_NEXT (mw); } df_refs_add_to_chains (&collection_rec, bb, insn, copy_eq_uses); } @@ -2340,14 +2083,8 @@ df_ref_equal_p (df_ref ref1, df_ref ref2) have the same bb. So these fields are not checked. */ static int -df_ref_compare (const void *r1, const void *r2) +df_ref_compare (df_ref ref1, df_ref ref2) { - const df_ref ref1 = *(const df_ref *)r1; - const df_ref ref2 = *(const df_ref *)r2; - - if (ref1 == ref2) - return 0; - if (DF_REF_CLASS (ref1) != DF_REF_CLASS (ref2)) return (int)DF_REF_CLASS (ref1) - (int)DF_REF_CLASS (ref2); @@ -2382,6 +2119,14 @@ df_ref_compare (const void *r1, const void *r2) return (int)DF_REF_ORDER (ref1) - (int)DF_REF_ORDER (ref2); } +/* Like df_ref_compare, but compare two df_ref* pointers R1 and R2. */ + +static int +df_ref_ptr_compare (const void *r1, const void *r2) +{ + return df_ref_compare (*(const df_ref *) r1, *(const df_ref *) r2); +} + static void df_swap_refs (vec<df_ref, va_heap> *ref_vec, int i, int j) { @@ -2408,7 +2153,7 @@ df_sort_and_compress_refs (vec<df_ref, va_heap> *ref_vec) { df_ref r0 = (*ref_vec)[0]; df_ref r1 = (*ref_vec)[1]; - if (df_ref_compare (&r0, &r1) > 0) + if (df_ref_compare (r0, r1) > 0) df_swap_refs (ref_vec, 0, 1); } else @@ -2417,7 +2162,7 @@ df_sort_and_compress_refs (vec<df_ref, va_heap> *ref_vec) { df_ref r0 = (*ref_vec)[i]; df_ref r1 = (*ref_vec)[i + 1]; - if (df_ref_compare (&r0, &r1) >= 0) + if (df_ref_compare (r0, r1) >= 0) break; } /* If the array is already strictly ordered, @@ -2429,7 +2174,7 @@ df_sort_and_compress_refs (vec<df_ref, va_heap> *ref_vec) of DF_REF_COMPARE. */ if (i == count - 1) return; - ref_vec->qsort (df_ref_compare); + ref_vec->qsort (df_ref_ptr_compare); } for (i=0; i<count-dist; i++) @@ -2472,14 +2217,8 @@ df_mw_equal_p (struct df_mw_hardreg *mw1, struct df_mw_hardreg *mw2) /* Compare MW1 and MW2 for sorting. */ static int -df_mw_compare (const void *m1, const void *m2) +df_mw_compare (const df_mw_hardreg *mw1, const df_mw_hardreg *mw2) { - const struct df_mw_hardreg *const mw1 = *(const struct df_mw_hardreg *const*)m1; - const struct df_mw_hardreg *const mw2 = *(const struct df_mw_hardreg *const*)m2; - - if (mw1 == mw2) - return 0; - if (mw1->type != mw2->type) return mw1->type - mw2->type; @@ -2498,6 +2237,14 @@ df_mw_compare (const void *m1, const void *m2) return 0; } +/* Like df_mw_compare, but compare two df_mw_hardreg** pointers R1 and R2. */ + +static int +df_mw_ptr_compare (const void *m1, const void *m2) +{ + return df_mw_compare (*(const df_mw_hardreg *const *) m1, + *(const df_mw_hardreg *const *) m2); +} /* Sort and compress a set of refs. */ @@ -2517,7 +2264,7 @@ df_sort_and_compress_mws (vec<df_mw_hardreg_ptr, va_heap> *mw_vec) { struct df_mw_hardreg *m0 = (*mw_vec)[0]; struct df_mw_hardreg *m1 = (*mw_vec)[1]; - if (df_mw_compare (&m0, &m1) > 0) + if (df_mw_compare (m0, m1) > 0) { struct df_mw_hardreg *tmp = (*mw_vec)[0]; (*mw_vec)[0] = (*mw_vec)[1]; @@ -2525,7 +2272,7 @@ df_sort_and_compress_mws (vec<df_mw_hardreg_ptr, va_heap> *mw_vec) } } else - mw_vec->qsort (df_mw_compare); + mw_vec->qsort (df_mw_ptr_compare); for (i=0; i<count-dist; i++) { @@ -2611,7 +2358,7 @@ df_install_ref (df_ref this_ref, eq_uses) and installs the entire group into the insn. It also adds each of these refs into the appropriate chains. */ -static df_ref * +static df_ref df_install_refs (basic_block bb, const vec<df_ref, va_heap> *old_vec, struct df_reg_info **reg_info, @@ -2621,7 +2368,6 @@ df_install_refs (basic_block bb, unsigned int count = old_vec->length (); if (count) { - df_ref *new_vec = XNEWVEC (df_ref, count + 1); bool add_to_table; df_ref this_ref; unsigned int ix; @@ -2651,37 +2397,35 @@ df_install_refs (basic_block bb, FOR_EACH_VEC_ELT (*old_vec, ix, this_ref) { - new_vec[ix] = this_ref; + DF_REF_NEXT_LOC (this_ref) = (ix + 1 < old_vec->length () + ? (*old_vec)[ix + 1] + : NULL); df_install_ref (this_ref, reg_info[DF_REF_REGNO (this_ref)], ref_info, add_to_table); } - - new_vec[count] = NULL; - return new_vec; + return (*old_vec)[0]; } else - return df_null_ref_rec; + return 0; } /* This function takes the mws installs the entire group into the insn. */ -static struct df_mw_hardreg ** +static struct df_mw_hardreg * df_install_mws (const vec<df_mw_hardreg_ptr, va_heap> *old_vec) { unsigned int count = old_vec->length (); if (count) { - struct df_mw_hardreg **new_vec - = XNEWVEC (struct df_mw_hardreg*, count + 1); - memcpy (new_vec, old_vec->address (), - sizeof (struct df_mw_hardreg*) * count); - new_vec[count] = NULL; - return new_vec; + for (unsigned int i = 0; i < count - 1; i++) + DF_MWS_NEXT ((*old_vec)[i]) = (*old_vec)[i + 1]; + DF_MWS_NEXT ((*old_vec)[count - 1]) = 0; + return (*old_vec)[0]; } else - return df_null_mw_rec; + return 0; } @@ -2700,7 +2444,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, chain specially. */ if (flags & copy_defs) { - df_scan_free_ref_vec (insn_rec->defs); + gcc_checking_assert (!insn_rec->defs); insn_rec->defs = df_install_refs (bb, &collection_rec->def_vec, df->def_regs, @@ -2708,7 +2452,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, } if (flags & copy_uses) { - df_scan_free_ref_vec (insn_rec->uses); + gcc_checking_assert (!insn_rec->uses); insn_rec->uses = df_install_refs (bb, &collection_rec->use_vec, df->use_regs, @@ -2716,7 +2460,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, } if (flags & copy_eq_uses) { - df_scan_free_ref_vec (insn_rec->eq_uses); + gcc_checking_assert (!insn_rec->eq_uses); insn_rec->eq_uses = df_install_refs (bb, &collection_rec->eq_use_vec, df->eq_use_regs, @@ -2724,7 +2468,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, } if (flags & copy_mw) { - df_scan_free_mws_vec (insn_rec->mw_hardregs); + gcc_checking_assert (!insn_rec->mw_hardregs); insn_rec->mw_hardregs = df_install_mws (&collection_rec->mw_vec); } @@ -2733,12 +2477,12 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec, { struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index); - df_scan_free_ref_vec (bb_info->artificial_defs); + gcc_checking_assert (!bb_info->artificial_defs); bb_info->artificial_defs = df_install_refs (bb, &collection_rec->def_vec, df->def_regs, &df->def_info, false); - df_scan_free_ref_vec (bb_info->artificial_uses); + gcc_checking_assert (!bb_info->artificial_uses); bb_info->artificial_uses = df_install_refs (bb, &collection_rec->use_vec, df->use_regs, @@ -4312,7 +4056,7 @@ df_reg_chain_verify_unmarked (df_ref refs) /* Verify that NEW_REC and OLD_REC have exactly the same members. */ static bool -df_refs_verify (const vec<df_ref, va_heap> *new_rec, df_ref *old_rec, +df_refs_verify (const vec<df_ref, va_heap> *new_rec, df_ref old_rec, bool abort_if_fail) { unsigned int ix; @@ -4320,7 +4064,7 @@ df_refs_verify (const vec<df_ref, va_heap> *new_rec, df_ref *old_rec, FOR_EACH_VEC_ELT (*new_rec, ix, new_ref) { - if (*old_rec == NULL || !df_ref_equal_p (new_ref, *old_rec)) + if (old_rec == NULL || !df_ref_equal_p (new_ref, old_rec)) { if (abort_if_fail) gcc_assert (0); @@ -4332,17 +4076,17 @@ df_refs_verify (const vec<df_ref, va_heap> *new_rec, df_ref *old_rec, that is the context, mark this reg as being seem. */ if (abort_if_fail) { - gcc_assert (DF_REF_IS_REG_MARKED (*old_rec)); - DF_REF_REG_UNMARK (*old_rec); + gcc_assert (DF_REF_IS_REG_MARKED (old_rec)); + DF_REF_REG_UNMARK (old_rec); } - old_rec++; + old_rec = DF_REF_NEXT_LOC (old_rec); } if (abort_if_fail) - gcc_assert (*old_rec == NULL); + gcc_assert (old_rec == NULL); else - return *old_rec == NULL; + return old_rec == NULL; return false; } @@ -4351,7 +4095,7 @@ df_refs_verify (const vec<df_ref, va_heap> *new_rec, df_ref *old_rec, static bool df_mws_verify (const vec<df_mw_hardreg_ptr, va_heap> *new_rec, - struct df_mw_hardreg **old_rec, + struct df_mw_hardreg *old_rec, bool abort_if_fail) { unsigned int ix; @@ -4359,20 +4103,20 @@ df_mws_verify (const vec<df_mw_hardreg_ptr, va_heap> *new_rec, FOR_EACH_VEC_ELT (*new_rec, ix, new_reg) { - if (*old_rec == NULL || !df_mw_equal_p (new_reg, *old_rec)) + if (old_rec == NULL || !df_mw_equal_p (new_reg, old_rec)) { if (abort_if_fail) gcc_assert (0); else return false; } - old_rec++; + old_rec = DF_MWS_NEXT (old_rec); } if (abort_if_fail) - gcc_assert (*old_rec == NULL); + gcc_assert (old_rec == NULL); else - return *old_rec == NULL; + return old_rec == NULL; return false; } @@ -4400,15 +4144,6 @@ df_insn_refs_verify (struct df_collection_rec *collection_rec, df_insn_refs_collect (collection_rec, bb, insn_info); - if (!DF_INSN_UID_DEFS (uid)) - { - /* The insn_rec was created but it was never filled out. */ - if (abort_if_fail) - gcc_assert (0); - else - return false; - } - /* Unfortunately we cannot opt out early if one of these is not right because the marks will not get cleared. */ ret1 = df_refs_verify (&collection_rec->def_vec, DF_INSN_UID_DEFS (uid), @@ -339,6 +339,7 @@ struct dataflow REG_UNUSED notes. */ struct df_mw_hardreg { + df_mw_hardreg *next; /* Next entry for this instruction. */ rtx mw_reg; /* The multiword hardreg. */ /* These two bitfields are intentionally oversized, in the hope that accesses to 16-bit fields will usually be quicker. */ @@ -365,6 +366,7 @@ struct df_base_ref int flags : 16; /* Various df_ref_flags. */ unsigned int regno; /* The register number referenced. */ rtx reg; /* The register referenced. */ + union df_ref_d *next_loc; /* Next ref for same insn or bb. */ struct df_link *chain; /* Head of def-use, use-def. */ /* Pointer to the insn info of the containing instruction. FIXME! Currently this is NULL for artificial refs but this will be used @@ -420,11 +422,11 @@ typedef union df_ref_d *df_ref; struct df_insn_info { rtx insn; /* The insn this info comes from. */ - df_ref *defs; /* Head of insn-def chain. */ - df_ref *uses; /* Head of insn-use chain. */ + df_ref defs; /* Head of insn-def chain. */ + df_ref uses; /* Head of insn-use chain. */ /* Head of insn-use chain for uses in REG_EQUAL/EQUIV notes. */ - df_ref *eq_uses; - struct df_mw_hardreg **mw_hardregs; + df_ref eq_uses; + struct df_mw_hardreg *mw_hardregs; /* The logical uid of the insn in the basic block. This is valid after any call to df_analyze but may rot after insns are added, deleted or moved. */ @@ -665,6 +667,7 @@ struct df_d #define DF_REF_REG_MARK(REF) (DF_REF_FLAGS_SET ((REF),DF_REF_REG_MARKER)) #define DF_REF_REG_UNMARK(REF) (DF_REF_FLAGS_CLEAR ((REF),DF_REF_REG_MARKER)) #define DF_REF_IS_REG_MARKED(REF) (DF_REF_FLAGS_IS_SET ((REF),DF_REF_REG_MARKER)) +#define DF_REF_NEXT_LOC(REF) ((REF)->base.next_loc) #define DF_REF_NEXT_REG(REF) ((REF)->base.next_reg) #define DF_REF_PREV_REG(REF) ((REF)->base.prev_reg) /* The following two macros may only be applied if one of @@ -675,14 +678,15 @@ struct df_d /* Macros to determine the reference type. */ #define DF_REF_REG_DEF_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_DEF) -#define DF_REF_REG_USE_P(REF) ((REF) && !DF_REF_REG_DEF_P (REF)) +#define DF_REF_REG_USE_P(REF) (!DF_REF_REG_DEF_P (REF)) #define DF_REF_REG_MEM_STORE_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_MEM_STORE) #define DF_REF_REG_MEM_LOAD_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_MEM_LOAD) #define DF_REF_REG_MEM_P(REF) (DF_REF_REG_MEM_STORE_P (REF) \ || DF_REF_REG_MEM_LOAD_P (REF)) #define DF_MWS_REG_DEF_P(MREF) (DF_MWS_TYPE (MREF) == DF_REF_REG_DEF) -#define DF_MWS_REG_USE_P(MREF) ((MREF) && !DF_MWS_REG_DEF_P (MREF)) +#define DF_MWS_REG_USE_P(MREF) (!DF_MWS_REG_DEF_P (MREF)) +#define DF_MWS_NEXT(MREF) ((MREF)->next) #define DF_MWS_TYPE(MREF) ((MREF)->type) /* Macros to get the refs out of def_info or use_info refs table. If @@ -736,6 +740,7 @@ struct df_d #define DF_INSN_INFO_DEFS(II) ((II)->defs) #define DF_INSN_INFO_USES(II) ((II)->uses) #define DF_INSN_INFO_EQ_USES(II) ((II)->eq_uses) +#define DF_INSN_INFO_MWS(II) ((II)->mw_hardregs) #define DF_INSN_LUID(INSN) (DF_INSN_INFO_LUID (DF_INSN_INFO_GET (INSN))) #define DF_INSN_DEFS(INSN) (DF_INSN_INFO_DEFS (DF_INSN_INFO_GET (INSN))) @@ -753,6 +758,35 @@ struct df_d #define DF_INSN_UID_EQ_USES(INSN) (DF_INSN_UID_GET (INSN)->eq_uses) #define DF_INSN_UID_MWS(INSN) (DF_INSN_UID_GET (INSN)->mw_hardregs) +#define FOR_EACH_INSN_INFO_DEF(ITER, INSN) \ + for (ITER = DF_INSN_INFO_DEFS (INSN); ITER; ITER = DF_REF_NEXT_LOC (ITER)) + +#define FOR_EACH_INSN_INFO_USE(ITER, INSN) \ + for (ITER = DF_INSN_INFO_USES (INSN); ITER; ITER = DF_REF_NEXT_LOC (ITER)) + +#define FOR_EACH_INSN_INFO_EQ_USE(ITER, INSN) \ + for (ITER = DF_INSN_INFO_EQ_USES (INSN); ITER; ITER = DF_REF_NEXT_LOC (ITER)) + +#define FOR_EACH_INSN_INFO_MW(ITER, INSN) \ + for (ITER = DF_INSN_INFO_MWS (INSN); ITER; ITER = DF_MWS_NEXT (ITER)) + +#define FOR_EACH_INSN_DEF(ITER, INSN) \ + FOR_EACH_INSN_INFO_DEF(ITER, DF_INSN_INFO_GET (INSN)) + +#define FOR_EACH_INSN_USE(ITER, INSN) \ + FOR_EACH_INSN_INFO_USE(ITER, DF_INSN_INFO_GET (INSN)) + +#define FOR_EACH_INSN_EQ_USE(ITER, INSN) \ + FOR_EACH_INSN_INFO_EQ_USE(ITER, DF_INSN_INFO_GET (INSN)) + +#define FOR_EACH_ARTIFICIAL_USE(ITER, BB_INDEX) \ + for (ITER = df_get_artificial_uses (BB_INDEX); ITER; \ + ITER = DF_REF_NEXT_LOC (ITER)) + +#define FOR_EACH_ARTIFICIAL_DEF(ITER, BB_INDEX) \ + for (ITER = df_get_artificial_defs (BB_INDEX); ITER; \ + ITER = DF_REF_NEXT_LOC (ITER)) + /* An obstack for bitmap not related to specific dataflow problems. This obstack should e.g. be used for bitmaps with a short life time such as temporary bitmaps. This obstack is declared in df-core.c. */ @@ -772,13 +806,13 @@ struct df_scan_bb_info Blocks that are the targets of non-local goto's have the hard frame pointer defined at the top of the block. */ - df_ref *artificial_defs; + df_ref artificial_defs; /* Blocks that are targets of exception edges may have some artificial uses. These are logically at the top of the block. Most blocks have artificial uses at the bottom of the block. */ - df_ref *artificial_uses; + df_ref artificial_uses; }; @@ -933,7 +967,7 @@ extern void df_dump_top (basic_block, FILE *); extern void df_dump_bottom (basic_block, FILE *); extern void df_dump_insn_top (const_rtx, FILE *); extern void df_dump_insn_bottom (const_rtx, FILE *); -extern void df_refs_chain_dump (df_ref *, bool, FILE *); +extern void df_refs_chain_dump (df_ref, bool, FILE *); extern void df_regs_chain_dump (df_ref, FILE *); extern void df_insn_debug (rtx, bool, FILE *); extern void df_insn_debug_regno (rtx, FILE *); @@ -993,10 +1027,7 @@ extern void df_scan_add_problem (void); extern void df_grow_reg_info (void); extern void df_grow_insn_info (void); extern void df_scan_blocks (void); -extern df_ref df_ref_create (rtx, rtx *, rtx,basic_block, - enum df_ref_type, int ref_flags); extern void df_uses_create (rtx *, rtx, int); -extern void df_ref_remove (df_ref); extern struct df_insn_info * df_insn_create_insn_record (rtx); extern void df_insn_delete (rtx); extern void df_bb_refs_record (int, bool); @@ -1116,7 +1147,7 @@ df_get_live_in (basic_block bb) /* Get basic block info. */ /* Get the artificial defs for a basic block. */ -static inline df_ref * +static inline df_ref df_get_artificial_defs (unsigned int bb_index) { return df_scan_get_bb_info (bb_index)->artificial_defs; @@ -1125,12 +1156,31 @@ df_get_artificial_defs (unsigned int bb_index) /* Get the artificial uses for a basic block. */ -static inline df_ref * +static inline df_ref df_get_artificial_uses (unsigned int bb_index) { return df_scan_get_bb_info (bb_index)->artificial_uses; } +/* If INSN defines exactly one register, return the associated reference, + otherwise return null. */ + +static inline df_ref +df_single_def (const df_insn_info *info) +{ + df_ref defs = DF_INSN_INFO_DEFS (info); + return defs && !DF_REF_NEXT_LOC (defs) ? defs : NULL; +} + +/* If INSN uses exactly one register, return the associated reference, + otherwise return null. */ + +static inline df_ref +df_single_use (const df_insn_info *info) +{ + df_ref uses = DF_INSN_INFO_USES (info); + return uses && !DF_REF_NEXT_LOC (uses) ? uses : NULL; +} /* web */ diff --git a/gcc/doc/aarch64-acle-intrinsics.texi b/gcc/doc/aarch64-acle-intrinsics.texi new file mode 100644 index 00000000000..3194511a8d6 --- /dev/null +++ b/gcc/doc/aarch64-acle-intrinsics.texi @@ -0,0 +1,55 @@ +@c Copyright (C) 2014 Free Software Foundation, Inc. +@c This is part of the GCC manual. +@c For copying conditions, see the file gcc.texi. + +@subsubsection CRC32 intrinsics + +These intrinsics are available when the CRC32 architecture extension is +specified, e.g. when the @option{-march=armv8-a+crc} switch is used, or when +the target processor specified with @option{-mcpu} supports it. + +@itemize @bullet +@item uint32_t __crc32b (uint32_t, uint8_t) +@*@emph{Form of expected instruction(s):} @code{crc32b @var{w0}, @var{w1}, @var{w2}} +@end itemize + + +@itemize @bullet +@item uint32_t __crc32h (uint32_t, uint16_t) +@*@emph{Form of expected instruction(s):} @code{crc32h @var{w0}, @var{w1}, @var{w2}} +@end itemize + + +@itemize @bullet +@item uint32_t __crc32w (uint32_t, uint32_t) +@*@emph{Form of expected instruction(s):} @code{crc32w @var{w0}, @var{w1}, @var{w2}} +@end itemize + + +@itemize @bullet +@item uint32_t __crc32d (uint32_t, uint64_t) +@*@emph{Form of expected instruction(s):} @code{crc32x @var{w0}, @var{w1}, @var{x2}} +@end itemize + +@itemize @bullet +@item uint32_t __crc32cb (uint32_t, uint8_t) +@*@emph{Form of expected instruction(s):} @code{crc32cb @var{w0}, @var{w1}, @var{w2}} +@end itemize + + +@itemize @bullet +@item uint32_t __crc32ch (uint32_t, uint16_t) +@*@emph{Form of expected instruction(s):} @code{crc32ch @var{w0}, @var{w1}, @var{w2}} +@end itemize + + +@itemize @bullet +@item uint32_t __crc32cw (uint32_t, uint32_t) +@*@emph{Form of expected instruction(s):} @code{crc32cw @var{w0}, @var{w1}, @var{w2}} +@end itemize + + +@itemize @bullet +@item uint32_t __crc32cd (uint32_t, uint64_t) +@*@emph{Form of expected instruction(s):} @code{crc32cx @var{w0}, @var{w1}, @var{x2}} +@end itemize diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index a79dbbfbade..f83a8d70b05 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -9697,6 +9697,7 @@ instructions, but allow the compiler to schedule those calls. @menu * AArch64 Built-in Functions:: +* AArch64 intrinsics:: * Alpha Built-in Functions:: * Altera Nios II Built-in Functions:: * ARC Built-in Functions:: @@ -9742,6 +9743,11 @@ unsigned int __builtin_aarch64_get_fpsr () void __builtin_aarch64_set_fpsr (unsigned int) @end smallexample +@node AArch64 intrinsics +@subsection ACLE Intrinsics for AArch64 + +@include aarch64-acle-intrinsics.texi + @node Alpha Built-in Functions @subsection Alpha Built-in Functions @@ -13410,8 +13416,6 @@ double __builtin_rsqrt (double); uint64_t __builtin_ppc_get_timebase (); unsigned long __builtin_ppc_mftb (); double __builtin_unpack_longdouble (long double, int); -double __builtin_longdouble_dw0 (long double); -double __builtin_longdouble_dw1 (long double); long double __builtin_pack_longdouble (double, double); @end smallexample diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 7851b0061b3..c66217548e2 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -1780,6 +1780,25 @@ GLIBC 2.11 or above, otherwise disabled. Enable support for link-time optimization (LTO). This is enabled by default, and may be disabled using @option{--disable-lto}. +@item --enable-linker-plugin-configure-flags=FLAGS +@itemx --enable-linker-plugin-flags=FLAGS +By default, linker plugins (such as the LTO plugin) are built for the +host system architecture. For the case that the linker has a +different (but run-time compatible) architecture, these flags can be +specified to build plugins that are compatible to the linker. For +example, if you are building GCC for a 64-bit x86_64 +(@samp{x86_64-unknown-linux-gnu}) host system, but have a 32-bit x86 +GNU/Linux (@samp{i686-pc-linux-gnu}) linker executable (which is +executable on the former system), you can configure GCC as follows for +getting compatible linker plugins: + +@smallexample +% @var{srcdir}/configure \ + --host=x86_64-unknown-linux-gnu \ + --enable-linker-plugin-configure-flags=--host=i686-pc-linux-gnu \ + --enable-linker-plugin-flags='CC=gcc\ -m32\ -Wl,-rpath,[...]/i686-pc-linux-gnu/lib' +@end smallexample + @item --with-plugin-ld=@var{pathname} Enable an alternate linker to be used at link-time optimization (LTO) link time when @option{-fuse-linker-plugin} is enabled. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 76d8a2fb597..9a34f1cb977 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -195,7 +195,7 @@ in the following sections. -fvtv-counts -fvtv-debug @gol -fvisibility-ms-compat @gol -fext-numeric-literals @gol --Wabi -Wconversion-null -Wctor-dtor-privacy @gol +-Wabi=@var{n} -Wconversion-null -Wctor-dtor-privacy @gol -Wdelete-non-virtual-dtor -Wliteral-suffix -Wnarrowing @gol -Wnoexcept -Wnon-virtual-dtor -Wreorder @gol -Weffc++ -Wstrict-null-sentinel @gol @@ -2023,7 +2023,7 @@ Here is a list of options that are @emph{only} for compiling C++ programs: @item -fabi-version=@var{n} @opindex fabi-version -Use version @var{n} of the C++ ABI@. The default is version 2. +Use version @var{n} of the C++ ABI@. The default is version 0. Version 0 refers to the version conforming most closely to the C++ ABI specification. Therefore, the ABI obtained using version 0 @@ -2031,7 +2031,8 @@ will change in different versions of G++ as ABI bugs are fixed. Version 1 is the version of the C++ ABI that first appeared in G++ 3.2. -Version 2 is the version of the C++ ABI that first appeared in G++ 3.4. +Version 2 is the version of the C++ ABI that first appeared in G++ +3.4, and was the default through G++ 4.9. Version 3 corrects an error in mangling a constant address as a template argument. @@ -2049,8 +2050,27 @@ behavior of C++11 scoped enums and the mangling of template argument packs, const/static_cast, prefix ++ and --, and a class scope function used as a template argument. +Version 7, which first appeared in G++ 4.8, that treats nullptr_t as a +builtin type and corrects the mangling of lambdas in default argument +scope. + +Version 8, which first appeared in G++ 4.9, corrects the substitution +behavior of function types with function-cv-qualifiers. + See also @option{-Wabi}. +@item -fabi-compat-version=@var{n} +@opindex fabi-compat-version +Starting with GCC 4.5, on targets that support strong aliases, G++ +works around mangling changes by creating an alias with the correct +mangled name when defining a symbol with an incorrect mangled name. +This switch specifies which ABI version to use for the alias. + +With @option{-fabi-version=0} (the default), this defaults to 2. If +another ABI version is explicitly selected, this defaults to 0. + +The compatibility version is also set by @option{-Wabi=@var{n}}. + @item -fno-access-control @opindex fno-access-control Turn off all access checking. This switch is mainly useful for working @@ -2445,8 +2465,15 @@ have meanings only for C++ programs: @item -Wabi @r{(C, Objective-C, C++ and Objective-C++ only)} @opindex Wabi @opindex Wno-abi -Warn when G++ generates code that is probably not compatible with the -vendor-neutral C++ ABI@. Although an effort has been made to warn about +When an explicit @option{-fabi-version=@var{n}} option is used, causes +G++ to warn when it generates code that is probably not compatible with the +vendor-neutral C++ ABI@. Since G++ now defaults to +@option{-fabi-version=0}, @option{-Wabi} has no effect unless either +an older ABI version is selected (with @option{-fabi-version=@var{n}}) +or an older compatibility version is selected (with +@option{-Wabi=@var{n}} or @option{-fabi-compat-version=@var{n}}). + +Although an effort has been made to warn about all such cases, there are probably some cases that are not warned about, even though G++ is generating incompatible code. There may also be cases where warnings are emitted even though the code that is generated @@ -2456,12 +2483,19 @@ You should rewrite your code to avoid these warnings if you are concerned about the fact that code generated by G++ may not be binary compatible with code generated by other compilers. -The known incompatibilities in @option{-fabi-version=2} (the default) include: +@option{-Wabi} can also be used with an explicit version number to +warn about compatibility with a particular @option{-fabi-version} +level, e.g. @option{-Wabi=2} to warn about changes relative to +@option{-fabi-version=2}. Specifying a version number also sets +@option{-fabi-compat-version=@var{n}}. + +The known incompatibilities in @option{-fabi-version=2} (which was the +default from GCC 3.4 to 4.9) include: @itemize @bullet @item -A template with a non-type template parameter of reference type is +A template with a non-type template parameter of reference type was mangled incorrectly: @smallexample extern int N; @@ -2469,100 +2503,45 @@ template <int &> struct S @{@}; void n (S<N>) @{2@} @end smallexample -This is fixed in @option{-fabi-version=3}. +This was fixed in @option{-fabi-version=3}. @item -SIMD vector types declared using @code{__attribute ((vector_size))} are +SIMD vector types declared using @code{__attribute ((vector_size))} were mangled in a non-standard way that does not allow for overloading of functions taking vectors of different sizes. -The mangling is changed in @option{-fabi-version=4}. -@end itemize - -The known incompatibilities in @option{-fabi-version=1} include: - -@itemize @bullet +The mangling was changed in @option{-fabi-version=4}. @item -Incorrect handling of tail-padding for bit-fields. G++ may attempt to -pack data into the same byte as a base class. For example: - -@smallexample -struct A @{ virtual void f(); int f1 : 1; @}; -struct B : public A @{ int f2 : 1; @}; -@end smallexample - -@noindent -In this case, G++ places @code{B::f2} into the same byte -as @code{A::f1}; other compilers do not. You can avoid this problem -by explicitly padding @code{A} so that its size is a multiple of the -byte size on your platform; that causes G++ and other compilers to -lay out @code{B} identically. - -@item -Incorrect handling of tail-padding for virtual bases. G++ does not use -tail padding when laying out virtual bases. For example: - -@smallexample -struct A @{ virtual void f(); char c1; @}; -struct B @{ B(); char c2; @}; -struct C : public A, public virtual B @{@}; -@end smallexample +@code{__attribute ((const))} and @code{noreturn} were mangled as type +qualifiers, and @code{decltype} of a plain declaration was folded away. -@noindent -In this case, G++ does not place @code{B} into the tail-padding for -@code{A}; other compilers do. You can avoid this problem by -explicitly padding @code{A} so that its size is a multiple of its -alignment (ignoring virtual base classes); that causes G++ and other -compilers to lay out @code{C} identically. +These mangling issues were fixed in @option{-fabi-version=5}. @item -Incorrect handling of bit-fields with declared widths greater than that -of their underlying types, when the bit-fields appear in a union. For -example: +Scoped enumerators passed as arguments to a variadic function are +promoted like unscoped enumerators, causing @samp{va_arg} to complain. +On most targets this does not actually affect the parameter passing +ABI, as there is no way to pass an argument smaller than @samp{int}. -@smallexample -union U @{ int i : 4096; @}; -@end smallexample +Also, the ABI changed the mangling of template argument packs, +@code{const_cast}, @code{static_cast}, prefix increment/decrement, and +a class scope function used as a template argument. -@noindent -Assuming that an @code{int} does not have 4096 bits, G++ makes the -union too small by the number of bits in an @code{int}. +These issues were corrected in @option{-fabi-version=6}. @item -Empty classes can be placed at incorrect offsets. For example: +Lambdas in default argument scope were mangled incorrectly, and the +ABI changed the mangling of nullptr_t. -@smallexample -struct A @{@}; - -struct B @{ - A a; - virtual void f (); -@}; - -struct C : public B, public A @{@}; -@end smallexample - -@noindent -G++ places the @code{A} base class of @code{C} at a nonzero offset; -it should be placed at offset zero. G++ mistakenly believes that the -@code{A} data member of @code{B} is already at offset zero. +These issues were corrected in @option{-fabi-version=7}. @item -Names of template functions whose types involve @code{typename} or -template template parameters can be mangled incorrectly. - -@smallexample -template <typename Q> -void f(typename Q::X) @{@} - -template <template <typename> class Q> -void f(typename Q<int>::X) @{@} -@end smallexample - -@noindent -Instantiations of these templates may be mangled incorrectly. +When mangling a function type with function-cv-qualifiers, the +un-qualified function type was incorrectly treated as a substitution +candidate. +This was fixed in @option{-fabi-version=8}. @end itemize It also warns about psABI-related changes. The known psABI changes at this @@ -10265,6 +10244,12 @@ is enabled by default when using @option{-fsanitize=address} option. To disable use-after-return detection use @option{--param asan-use-after-return=0}. +@item asan-instrumentation-with-call-threshold +Once number of memory accesses in function becomes greater +or equal than this number, use callbacks instead of +generating inline code. E.g. to disable inline code use +@option{--param asan-instrumentation-with-call-threshold=0}. + @end table @end table diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 7c3d7142aa1..e17ffca01af 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -4355,16 +4355,8 @@ Use this for constraints that should not appear in @code{asm} statements. It is occasionally useful to test a constraint from C code rather than implicitly via the constraint string in a @code{match_operand}. The generated file @file{tm_p.h} declares a few interfaces for working -with machine-specific constraints. None of these interfaces work with -the generic constraints described in @ref{Simple Constraints}. This -may change in the future. - -@strong{Warning:} @file{tm_p.h} may declare other functions that -operate on constraints, besides the ones documented here. Do not use -those functions from machine-dependent code. They exist to implement -the old constraint interface that machine-independent components of -the compiler still expect. They will change or disappear in the -future. +with constraints. At present these are defined for all constraints +except @code{g} (which is equivalent to @code{general_operand}). Some valid constraint names are not valid C identifiers, so there is a mangling scheme for referring to them from C@. Constraint names that @@ -4391,17 +4383,14 @@ the variable @var{m} is a mangled constraint name (usually as part of a larger identifier). @deftp Enum constraint_num -For each machine-specific constraint, there is a corresponding +For each constraint except @code{g}, there is a corresponding enumeration constant: @samp{CONSTRAINT_} plus the mangled name of the constraint. Functions that take an @code{enum constraint_num} as an argument expect one of these constants. - -Machine-independent constraints do not have associated constants. -This may change in the future. @end deftp @deftypefun {inline bool} satisfies_constraint_@var{m} (rtx @var{exp}) -For each machine-specific, non-register constraint @var{m}, there is +For each non-register constraint @var{m} except @code{g}, there is one of these functions; it returns @code{true} if @var{exp} satisfies the constraint. These functions are only visible if @file{rtl.h} was included before @file{tm_p.h}. @@ -4414,7 +4403,7 @@ specifies a register constraint, this function will always return @code{false}. @end deftypefun -@deftypefun {enum reg_class} regclass_for_constraint (enum constraint_num @var{c}) +@deftypefun {enum reg_class} reg_class_for_constraint (enum constraint_num @var{c}) Returns the register class associated with @var{c}. If @var{c} is not a register constraint, or those registers are not available for the currently selected subtarget, returns @code{NO_REGS}. diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 7438980f08e..39152df272a 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -1295,6 +1295,9 @@ Target has 64-bit @code{double}. @item double64plus Target has @code{double} that is 64 bits or longer. +@item longdouble128 +Target has 128-bit @code{long double}. + @item int32plus Target has @code{int} that is at 32 bits or longer. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index b38243f91d5..933ec62c3db 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -13614,15 +13614,9 @@ secname_for_decl (const_tree decl) if (VAR_OR_FUNCTION_DECL_P (decl) && (DECL_EXTERNAL (decl) || TREE_PUBLIC (decl) || TREE_STATIC (decl)) && DECL_SECTION_NAME (decl)) - { - tree sectree = DECL_SECTION_NAME (decl); - secname = TREE_STRING_POINTER (sectree); - } + secname = DECL_SECTION_NAME (decl); else if (current_function_decl && DECL_SECTION_NAME (current_function_decl)) - { - tree sectree = DECL_SECTION_NAME (current_function_decl); - secname = TREE_STRING_POINTER (sectree); - } + secname = DECL_SECTION_NAME (current_function_decl); else if (cfun && in_cold_section_p) secname = crtl->subsections.cold_section_label; else @@ -16798,10 +16792,9 @@ add_src_coords_attributes (dw_die_ref die, tree decl) static void add_linkage_name (dw_die_ref die, tree decl) { - if (debug_info_level > DINFO_LEVEL_TERSE + if (debug_info_level > DINFO_LEVEL_NONE && (TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL) && TREE_PUBLIC (decl) - && !DECL_ABSTRACT (decl) && !(TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)) && die->die_tag != DW_TAG_member) { diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 24daaa32ce3..978b854a99c 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -14859,8 +14859,6 @@ fold_checksum_tree (const_tree expr, struct md5_ctx *ctx, fold_checksum_tree (DECL_ABSTRACT_ORIGIN (expr), ctx, ht); fold_checksum_tree (DECL_ATTRIBUTES (expr), ctx, ht); } - if (CODE_CONTAINS_STRUCT (TREE_CODE (expr), TS_DECL_WITH_VIS)) - fold_checksum_tree (DECL_SECTION_NAME (expr), ctx, ht); if (CODE_CONTAINS_STRUCT (TREE_CODE (expr), TS_DECL_NON_COMMON)) { diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index bdc102b4b54..e795de6767b 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,35 @@ +2014-06-15 Jan Hubicka <hubicka@ucw.cz> + + * trans-common.c (build_common_decl): Use + set_decl_tls_model. + * trans-decl.c (gfc_finish_var_decl): Likewise. + (get_proc_pointer_decl): Likewise. + +2014-06-15 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + + PR fortran/28484 + PR fortran/61429 + * check.c (gfc_check_system_clock): Improve checking of arguments. + * intrinsic.texi: Update doc of SYSTEM_CLOCK. + * iresolve.c (gfc_resolve_system_clock): Choose library function + used depending on argument kinds. + * trans-decl.c (gfc_build_intrinsic_function_decls): Build + decls for system_clock_4 and system_clock_8. + * trans-intrinsic.c (conv_intrinsic_system_clock): New function. + (gfc_conv_intrinsic_subroutine): Call conv_intrinsic_system_clock. + * trans.h (gfor_fndecl_system_clock4, gfor_fndecl_system_clock8): + New variables. + +2014-06-12 Tobias Burnus <burnus@net-b.de> + + * gfortran.h (gfc_copy_formal_args_intr): Update prototype. + * symbol.c (gfc_copy_formal_args_intr): Handle the case + that absent optional arguments should be ignored. + * trans-intrinsic.c (gfc_get_symbol_for_expr): Ditto. + (gfc_conv_intrinsic_funcall, + conv_generic_with_optional_char_arg): Update call. + * resolve.c (gfc_resolve_intrinsic): Ditto. + 2014-06-10 Dominique d'Humieres <dominiq@lps.ens.fr> Mikael Morin <mikael@gcc.gnu.org> diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index 20af75feb44..caf3b6cbb4e 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -5206,8 +5206,10 @@ gfc_check_second_sub (gfc_expr *time) } -/* The arguments of SYSTEM_CLOCK are scalar, integer variables. Note, - count, count_rate, and count_max are all optional arguments */ +/* COUNT and COUNT_MAX of SYSTEM_CLOCK are scalar, default-kind integer + variables in Fortran 95. In Fortran 2003 and later, they can be of any + kind, and COUNT_RATE can be of type real. Note, count, count_rate, and + count_max are all optional arguments */ bool gfc_check_system_clock (gfc_expr *count, gfc_expr *count_rate, @@ -5221,6 +5223,12 @@ gfc_check_system_clock (gfc_expr *count, gfc_expr *count_rate, if (!type_check (count, 0, BT_INTEGER)) return false; + if (count->ts.kind != gfc_default_integer_kind + && !gfc_notify_std (GFC_STD_F2003, "COUNT argument to " + "SYSTEM_CLOCK at %L has non-default kind", + &count->where)) + return false; + if (!variable_check (count, 0, false)) return false; } @@ -5230,15 +5238,26 @@ gfc_check_system_clock (gfc_expr *count, gfc_expr *count_rate, if (!scalar_check (count_rate, 1)) return false; - if (!type_check (count_rate, 1, BT_INTEGER)) - return false; - if (!variable_check (count_rate, 1, false)) return false; - if (count != NULL - && !same_type_check (count, 0, count_rate, 1)) - return false; + if (count_rate->ts.type == BT_REAL) + { + if (!gfc_notify_std (GFC_STD_F2003, "Real COUNT_RATE argument to " + "SYSTEM_CLOCK at %L", &count_rate->where)) + return false; + } + else + { + if (!type_check (count_rate, 1, BT_INTEGER)) + return false; + + if (count_rate->ts.kind != gfc_default_integer_kind + && !gfc_notify_std (GFC_STD_F2003, "COUNT_RATE argument to " + "SYSTEM_CLOCK at %L has non-default kind", + &count_rate->where)) + return false; + } } @@ -5250,15 +5269,13 @@ gfc_check_system_clock (gfc_expr *count, gfc_expr *count_rate, if (!type_check (count_max, 2, BT_INTEGER)) return false; - if (!variable_check (count_max, 2, false)) - return false; - - if (count != NULL - && !same_type_check (count, 0, count_max, 2)) + if (count_max->ts.kind != gfc_default_integer_kind + && !gfc_notify_std (GFC_STD_F2003, "COUNT_MAX argument to " + "SYSTEM_CLOCK at %L has non-default kind", + &count_max->where)) return false; - if (count_rate != NULL - && !same_type_check (count_rate, 1, count_max, 2)) + if (!variable_check (count_max, 2, false)) return false; } diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 7ff8a34f18a..1df79fdbe05 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -2785,7 +2785,8 @@ gfc_symbol* gfc_get_ultimate_derived_super_type (gfc_symbol*); bool gfc_type_is_extension_of (gfc_symbol *, gfc_symbol *); bool gfc_type_compatible (gfc_typespec *, gfc_typespec *); -void gfc_copy_formal_args_intr (gfc_symbol *, gfc_intrinsic_sym *); +void gfc_copy_formal_args_intr (gfc_symbol *, gfc_intrinsic_sym *, + gfc_actual_arglist *); void gfc_free_finalizer (gfc_finalizer *el); /* Needed in resolve.c, too */ diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index 5c66aab4b8a..ed4ecaa8838 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -12259,15 +12259,16 @@ clock implementation, provide up to nanosecond resolution. If a monotonic clock is not available, the implementation falls back to a realtime clock. -@var{COUNT_RATE} is system dependent and can vary depending on the -kind of the arguments. For @var{kind=4} arguments, @var{COUNT} -represents milliseconds, while for @var{kind=8} arguments, @var{COUNT} -typically represents micro- or nanoseconds depending on resolution of -the underlying platform clock. @var{COUNT_MAX} usually equals -@code{HUGE(COUNT_MAX)}. Note that the millisecond resolution of the -@var{kind=4} version implies that the @var{COUNT} will wrap around in -roughly 25 days. In order to avoid issues with the wrap around and for -more precise timing, please use the @var{kind=8} version. +@var{COUNT_RATE} is system dependent and can vary depending on the kind of +the arguments. For @var{kind=4} arguments (and smaller integer kinds), +@var{COUNT} represents milliseconds, while for @var{kind=8} arguments (and +larger integer kinds), @var{COUNT} typically represents micro- or +nanoseconds depending on resolution of the underlying platform clock. +@var{COUNT_MAX} usually equals @code{HUGE(COUNT_MAX)}. Note that the +millisecond resolution of the @var{kind=4} version implies that the +@var{COUNT} will wrap around in roughly 25 days. In order to avoid issues +with the wrap around and for more precise timing, please use the +@var{kind=8} version. If there is no clock, or querying the clock fails, @var{COUNT} is set to @code{-HUGE(COUNT)}, and @var{COUNT_RATE} and @var{COUNT_MAX} are @@ -12299,7 +12300,7 @@ Subroutine @item @var{COUNT} @tab (Optional) shall be a scalar of type @code{INTEGER} with @code{INTENT(OUT)}. @item @var{COUNT_RATE} @tab (Optional) shall be a scalar of type -@code{INTEGER} with @code{INTENT(OUT)}. +@code{INTEGER} or @code{REAL}, with @code{INTENT(OUT)}. @item @var{COUNT_MAX} @tab (Optional) shall be a scalar of type @code{INTEGER} with @code{INTENT(OUT)}. @end multitable diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c index d029f720a8d..f9a69feaeef 100644 --- a/gcc/fortran/iresolve.c +++ b/gcc/fortran/iresolve.c @@ -3293,13 +3293,14 @@ gfc_resolve_system_clock (gfc_code *c) { const char *name; int kind; - - if (c->ext.actual->expr != NULL) - kind = c->ext.actual->expr->ts.kind; - else if (c->ext.actual->next->expr != NULL) - kind = c->ext.actual->next->expr->ts.kind; - else if (c->ext.actual->next->next->expr != NULL) - kind = c->ext.actual->next->next->expr->ts.kind; + gfc_expr *count = c->ext.actual->expr; + gfc_expr *count_max = c->ext.actual->next->next->expr; + + /* The INTEGER(8) version has higher precision, it is used if both COUNT + and COUNT_MAX can hold 64-bit values, or are absent. */ + if ((!count || count->ts.kind >= 8) + && (!count_max || count_max->ts.kind >= 8)) + kind = 8; else kind = gfc_default_integer_kind; diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 0e4c1812372..bc2db7deb58 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -1674,7 +1674,7 @@ gfc_resolve_intrinsic (gfc_symbol *sym, locus *loc) return false; } - gfc_copy_formal_args_intr (sym, isym); + gfc_copy_formal_args_intr (sym, isym, NULL); sym->attr.pure = isym->pure; sym->attr.elemental = isym->elemental; diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c index a0995b51cce..922b421b5e1 100644 --- a/gcc/fortran/symbol.c +++ b/gcc/fortran/symbol.c @@ -4042,16 +4042,21 @@ add_proc_interface (gfc_symbol *sym, ifsrc source, gfc_formal_arglist *formal) each arg is set according to the existing ones. This function is used when creating procedure declaration variables from a procedure declaration statement (see match_proc_decl()) to create the formal - args based on the args of a given named interface. */ + args based on the args of a given named interface. + + When an actual argument list is provided, skip the absent arguments. + To be used together with gfc_se->ignore_optional. */ void -gfc_copy_formal_args_intr (gfc_symbol *dest, gfc_intrinsic_sym *src) +gfc_copy_formal_args_intr (gfc_symbol *dest, gfc_intrinsic_sym *src, + gfc_actual_arglist *actual) { gfc_formal_arglist *head = NULL; gfc_formal_arglist *tail = NULL; gfc_formal_arglist *formal_arg = NULL; gfc_intrinsic_arg *curr_arg = NULL; gfc_formal_arglist *formal_prev = NULL; + gfc_actual_arglist *act_arg = actual; /* Save current namespace so we can change it for formal args. */ gfc_namespace *parent_ns = gfc_current_ns; @@ -4062,6 +4067,17 @@ gfc_copy_formal_args_intr (gfc_symbol *dest, gfc_intrinsic_sym *src) for (curr_arg = src->formal; curr_arg; curr_arg = curr_arg->next) { + /* Skip absent arguments. */ + if (actual) + { + gcc_assert (act_arg != NULL); + if (act_arg->expr == NULL) + { + act_arg = act_arg->next; + continue; + } + act_arg = act_arg->next; + } formal_arg = gfc_get_formal_arglist (); gfc_get_symbol (curr_arg->name, gfc_current_ns, &(formal_arg->sym)); diff --git a/gcc/fortran/trans-common.c b/gcc/fortran/trans-common.c index 7132a080ff2..023a55e2560 100644 --- a/gcc/fortran/trans-common.c +++ b/gcc/fortran/trans-common.c @@ -454,7 +454,7 @@ build_common_decl (gfc_common_head *com, tree union_type, bool is_init) gfc_set_decl_location (decl, &com->where); if (com->threadprivate) - DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); + set_decl_tls_model (decl, decl_default_tls_model (decl)); /* Place the back end declaration for this common block in GLOBAL_BINDING_LEVEL. */ diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index f57f87108d7..8755f3af0a2 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -116,6 +116,8 @@ tree gfor_fndecl_ttynam; tree gfor_fndecl_in_pack; tree gfor_fndecl_in_unpack; tree gfor_fndecl_associated; +tree gfor_fndecl_system_clock4; +tree gfor_fndecl_system_clock8; /* Coarray run-time library function decls. */ @@ -629,7 +631,7 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym) /* Handle threadprivate variables. */ if (sym->attr.threadprivate && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) - DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); + set_decl_tls_model (decl, decl_default_tls_model (decl)); gfc_finish_decl_attrs (decl, &sym->attr); } @@ -1645,7 +1647,7 @@ get_proc_pointer_decl (gfc_symbol *sym) /* Handle threadprivate procedure pointers. */ if (sym->attr.threadprivate && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) - DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); + set_decl_tls_model (decl, decl_default_tls_model (decl)); attributes = add_attributes_to_decl (sym->attr, NULL_TREE); decl_attributes (&decl, attributes, 0); @@ -2824,7 +2826,9 @@ static void gfc_build_intrinsic_function_decls (void) { tree gfc_int4_type_node = gfc_get_int_type (4); + tree gfc_pint4_type_node = build_pointer_type (gfc_int4_type_node); tree gfc_int8_type_node = gfc_get_int_type (8); + tree gfc_pint8_type_node = build_pointer_type (gfc_int8_type_node); tree gfc_int16_type_node = gfc_get_int_type (16); tree gfc_logical4_type_node = gfc_get_logical_type (4); tree pchar1_type_node = gfc_get_pchar_type (1); @@ -3023,6 +3027,16 @@ gfc_build_intrinsic_function_decls (void) DECL_PURE_P (gfor_fndecl_sr_kind) = 1; TREE_NOTHROW (gfor_fndecl_sr_kind) = 1; + gfor_fndecl_system_clock4 = gfc_build_library_function_decl ( + get_identifier (PREFIX("system_clock_4")), + void_type_node, 3, gfc_pint4_type_node, gfc_pint4_type_node, + gfc_pint4_type_node); + + gfor_fndecl_system_clock8 = gfc_build_library_function_decl ( + get_identifier (PREFIX("system_clock_8")), + void_type_node, 3, gfc_pint8_type_node, gfc_pint8_type_node, + gfc_pint8_type_node); + /* Power functions. */ { tree ctype, rtype, itype, jtype; diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index 6e732a4d0aa..1a76d5530e7 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -2154,6 +2154,96 @@ gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr) } +/* Call the SYSTEM_CLOCK library functions, handling the type and kind + conversions. */ + +static tree +conv_intrinsic_system_clock (gfc_code *code) +{ + stmtblock_t block; + gfc_se count_se, count_rate_se, count_max_se; + tree arg1 = NULL_TREE, arg2 = NULL_TREE, arg3 = NULL_TREE; + tree type, tmp; + int kind; + + gfc_expr *count = code->ext.actual->expr; + gfc_expr *count_rate = code->ext.actual->next->expr; + gfc_expr *count_max = code->ext.actual->next->next->expr; + + /* The INTEGER(8) version has higher precision, it is used if both COUNT + and COUNT_MAX can hold 64-bit values, or are absent. */ + if ((!count || count->ts.kind >= 8) + && (!count_max || count_max->ts.kind >= 8)) + kind = 8; + else + kind = gfc_default_integer_kind; + type = gfc_get_int_type (kind); + + /* Evaluate our arguments. */ + if (count) + { + gfc_init_se (&count_se, NULL); + gfc_conv_expr (&count_se, count); + } + + if (count_rate) + { + gfc_init_se (&count_rate_se, NULL); + gfc_conv_expr (&count_rate_se, count_rate); + } + + if (count_max) + { + gfc_init_se (&count_max_se, NULL); + gfc_conv_expr (&count_max_se, count_max); + } + + /* Prepare temporary variables if we need them. */ + if (count && count->ts.kind != kind) + arg1 = gfc_create_var (type, "count"); + else if (count) + arg1 = count_se.expr; + + if (count_rate && (count_rate->ts.kind != kind + || count_rate->ts.type != BT_INTEGER)) + arg2 = gfc_create_var (type, "count_rate"); + else if (count_rate) + arg2 = count_rate_se.expr; + + if (count_max && count_max->ts.kind != kind) + arg3 = gfc_create_var (type, "count_max"); + else if (count_max) + arg3 = count_max_se.expr; + + /* Make the function call. */ + gfc_init_block (&block); + tmp = build_call_expr_loc (input_location, + kind == 4 ? gfor_fndecl_system_clock4 + : gfor_fndecl_system_clock8, + 3, + arg1 ? gfc_build_addr_expr (NULL_TREE, arg1) + : null_pointer_node, + arg2 ? gfc_build_addr_expr (NULL_TREE, arg2) + : null_pointer_node, + arg3 ? gfc_build_addr_expr (NULL_TREE, arg3) + : null_pointer_node); + gfc_add_expr_to_block (&block, tmp); + + /* And store values back if needed. */ + if (arg1 && arg1 != count_se.expr) + gfc_add_modify (&block, count_se.expr, + fold_convert (TREE_TYPE (count_se.expr), arg1)); + if (arg2 && arg2 != count_rate_se.expr) + gfc_add_modify (&block, count_rate_se.expr, + fold_convert (TREE_TYPE (count_rate_se.expr), arg2)); + if (arg3 && arg3 != count_max_se.expr) + gfc_add_modify (&block, count_max_se.expr, + fold_convert (TREE_TYPE (count_max_se.expr), arg3)); + + return gfc_finish_block (&block); +} + + /* Return a character string containing the tty name. */ static void @@ -2342,7 +2432,7 @@ gfc_conv_intrinsic_minmax_char (gfc_se * se, gfc_expr * expr, int op) has the generic name. */ static gfc_symbol * -gfc_get_symbol_for_expr (gfc_expr * expr) +gfc_get_symbol_for_expr (gfc_expr * expr, bool ignore_optional) { gfc_symbol *sym; @@ -2365,7 +2455,9 @@ gfc_get_symbol_for_expr (gfc_expr * expr) sym->as->rank = expr->rank; } - gfc_copy_formal_args_intr (sym, expr->value.function.isym); + gfc_copy_formal_args_intr (sym, expr->value.function.isym, + ignore_optional ? expr->value.function.actual + : NULL); return sym; } @@ -2384,7 +2476,7 @@ gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr) else gcc_assert (expr->rank == 0); - sym = gfc_get_symbol_for_expr (expr); + sym = gfc_get_symbol_for_expr (expr, se->ignore_optional); /* Calls to libgfortran_matmul need to be appended special arguments, to be able to call the BLAS ?gemm functions if required and possible. */ @@ -4555,7 +4647,8 @@ conv_generic_with_optional_char_arg (gfc_se* se, gfc_expr* expr, } /* Build the call itself. */ - sym = gfc_get_symbol_for_expr (expr); + gcc_assert (!se->ignore_optional); + sym = gfc_get_symbol_for_expr (expr, false); gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr, append_args); gfc_free_symbol (sym); @@ -8028,6 +8121,10 @@ gfc_conv_intrinsic_subroutine (gfc_code *code) res = conv_co_minmaxsum (code); break; + case GFC_ISYM_SYSTEM_CLOCK: + res = conv_intrinsic_system_clock (code); + break; + default: res = NULL_TREE; break; diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index c484299495d..c02064f3d32 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -702,6 +702,8 @@ extern GTY(()) tree gfor_fndecl_fdate; extern GTY(()) tree gfor_fndecl_in_pack; extern GTY(()) tree gfor_fndecl_in_unpack; extern GTY(()) tree gfor_fndecl_associated; +extern GTY(()) tree gfor_fndecl_system_clock4; +extern GTY(()) tree gfor_fndecl_system_clock8; /* Coarray run-time library function decls. */ diff --git a/gcc/fwprop.c b/gcc/fwprop.c index 0179bf1a578..a0b9c8b02ca 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -146,10 +146,9 @@ get_def_for_use (df_ref use) (DF_REF_PARTIAL | DF_REF_CONDITIONAL | DF_REF_MAY_CLOBBER) static void -process_defs (df_ref *def_rec, int top_flag) +process_defs (df_ref def, int top_flag) { - df_ref def; - while ((def = *def_rec++) != NULL) + for (; def; def = DF_REF_NEXT_LOC (def)) { df_ref curr_def = reg_defs[DF_REF_REGNO (def)]; unsigned int dregno; @@ -191,10 +190,9 @@ process_defs (df_ref *def_rec, int top_flag) is an artificial use vector. */ static void -process_uses (df_ref *use_rec, int top_flag) +process_uses (df_ref use, int top_flag) { - df_ref use; - while ((use = *use_rec++) != NULL) + for (; use; use = DF_REF_NEXT_LOC (use)) if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == top_flag) { unsigned int uregno = DF_REF_REGNO (use); @@ -700,16 +698,13 @@ local_ref_killed_between_p (df_ref ref, rtx from, rtx to) for (insn = from; insn != to; insn = NEXT_INSN (insn)) { - df_ref *def_rec; + df_ref def; if (!INSN_P (insn)) continue; - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (DF_REF_REGNO (ref) == DF_REF_REGNO (def)) - return true; - } + FOR_EACH_INSN_DEF (def, insn) + if (DF_REF_REGNO (ref) == DF_REF_REGNO (def)) + return true; } return false; } @@ -790,7 +785,7 @@ use_killed_between (df_ref use, rtx def_insn, rtx target_insn) static bool all_uses_available_at (rtx def_insn, rtx target_insn) { - df_ref *use_rec; + df_ref use; struct df_insn_info *insn_info = DF_INSN_INFO_GET (def_insn); rtx def_set = single_set (def_insn); rtx next; @@ -809,18 +804,12 @@ all_uses_available_at (rtx def_insn, rtx target_insn) /* If the insn uses the reg that it defines, the substitution is invalid. */ - for (use_rec = DF_INSN_INFO_USES (insn_info); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if (rtx_equal_p (DF_REF_REG (use), def_reg)) - return false; - } - for (use_rec = DF_INSN_INFO_EQ_USES (insn_info); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if (rtx_equal_p (DF_REF_REG (use), def_reg)) - return false; - } + FOR_EACH_INSN_INFO_USE (use, insn_info) + if (rtx_equal_p (DF_REF_REG (use), def_reg)) + return false; + FOR_EACH_INSN_INFO_EQ_USE (use, insn_info) + if (rtx_equal_p (DF_REF_REG (use), def_reg)) + return false; } else { @@ -828,17 +817,15 @@ all_uses_available_at (rtx def_insn, rtx target_insn) /* Look at all the uses of DEF_INSN, and see if they are not killed between DEF_INSN and TARGET_INSN. */ - for (use_rec = DF_INSN_INFO_USES (insn_info); *use_rec; use_rec++) + FOR_EACH_INSN_INFO_USE (use, insn_info) { - df_ref use = *use_rec; if (def_reg && rtx_equal_p (DF_REF_REG (use), def_reg)) return false; if (use_killed_between (use, def_insn, target_insn)) return false; } - for (use_rec = DF_INSN_INFO_EQ_USES (insn_info); *use_rec; use_rec++) + FOR_EACH_INSN_INFO_EQ_USE (use, insn_info) { - df_ref use = *use_rec; if (def_reg && rtx_equal_p (DF_REF_REG (use), def_reg)) return false; if (use_killed_between (use, def_insn, target_insn)) @@ -860,11 +847,10 @@ static sparseset active_defs_check; too, for checking purposes. */ static void -register_active_defs (df_ref *use_rec) +register_active_defs (df_ref use) { - while (*use_rec) + for (; use; use = DF_REF_NEXT_LOC (use)) { - df_ref use = *use_rec++; df_ref def = get_def_for_use (use); int regno = DF_REF_REGNO (use); @@ -898,11 +884,10 @@ update_df_init (rtx def_insn, rtx insn) in the ACTIVE_DEFS array to match pseudos to their def. */ static inline void -update_uses (df_ref *use_rec) +update_uses (df_ref use) { - while (*use_rec) + for (; use; use = DF_REF_NEXT_LOC (use)) { - df_ref use = *use_rec++; int regno = DF_REF_REGNO (use); /* Set up the use-def chain. */ @@ -1034,8 +1019,7 @@ static bool free_load_extend (rtx src, rtx insn) { rtx reg; - df_ref *use_vec; - df_ref use = 0, def; + df_ref def, use; reg = XEXP (src, 0); #ifdef LOAD_EXTEND_OP @@ -1043,15 +1027,11 @@ free_load_extend (rtx src, rtx insn) #endif return false; - for (use_vec = DF_INSN_USES (insn); *use_vec; use_vec++) - { - use = *use_vec; - - if (!DF_REF_IS_ARTIFICIAL (use) - && DF_REF_TYPE (use) == DF_REF_REG_USE - && DF_REF_REG (use) == reg) - break; - } + FOR_EACH_INSN_USE (use, insn) + if (!DF_REF_IS_ARTIFICIAL (use) + && DF_REF_TYPE (use) == DF_REF_REG_USE + && DF_REF_REG (use) == reg) + break; if (!use) return false; @@ -1151,7 +1131,7 @@ forward_propagate_asm (df_ref use, rtx def_insn, rtx def_set, rtx reg) { rtx use_insn = DF_REF_INSN (use), src, use_pat, asm_operands, new_rtx, *loc; int speed_p, i; - df_ref *use_vec; + df_ref uses; gcc_assert ((DF_REF_FLAGS (use) & DF_REF_IN_NOTE) == 0); @@ -1160,8 +1140,8 @@ forward_propagate_asm (df_ref use, rtx def_insn, rtx def_set, rtx reg) /* In __asm don't replace if src might need more registers than reg, as that could increase register pressure on the __asm. */ - use_vec = DF_INSN_USES (def_insn); - if (use_vec[0] && use_vec[1]) + uses = DF_INSN_USES (def_insn); + if (uses && DF_REF_NEXT_LOC (uses)) return false; update_df_init (def_insn, use_insn); diff --git a/gcc/gcse.c b/gcc/gcse.c index a49cc65b7bf..8de596d2fac 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -2961,16 +2961,16 @@ update_bb_reg_pressure (basic_block bb, rtx from) { rtx dreg, insn; basic_block succ_bb; - df_ref *op, op_ref; + df_ref use, op_ref; edge succ; edge_iterator ei; int decreased_pressure = 0; int nregs; enum reg_class pressure_class; - - for (op = DF_INSN_USES (from); *op; op++) + + FOR_EACH_INSN_USE (use, from) { - dreg = DF_REF_REAL_REG (*op); + dreg = DF_REF_REAL_REG (use); /* The live range of register is shrunk only if it isn't: 1. referred on any path from the end of this block to EXIT, or 2. referred by insns other than FROM in this block. */ @@ -3593,17 +3593,17 @@ calculate_bb_reg_pressure (void) { rtx dreg; int regno; - df_ref *def_rec, *use_rec; + df_ref def, use; if (! NONDEBUG_INSN_P (insn)) continue; - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) + FOR_EACH_INSN_DEF (def, insn) { - dreg = DF_REF_REAL_REG (*def_rec); + dreg = DF_REF_REAL_REG (def); gcc_assert (REG_P (dreg)); regno = REGNO (dreg); - if (!(DF_REF_FLAGS (*def_rec) + if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) { if (bitmap_clear_bit (curr_regs_live, regno)) @@ -3611,9 +3611,9 @@ calculate_bb_reg_pressure (void) } } - for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) + FOR_EACH_INSN_USE (use, insn) { - dreg = DF_REF_REAL_REG (*use_rec); + dreg = DF_REF_REAL_REG (use); gcc_assert (REG_P (dreg)); regno = REGNO (dreg); if (bitmap_set_bit (curr_regs_live, regno)) diff --git a/gcc/genopinit.c b/gcc/genopinit.c index 77932ad3545..ef7f674d09b 100644 --- a/gcc/genopinit.c +++ b/gcc/genopinit.c @@ -357,8 +357,7 @@ main (int argc, char **argv) } /* Sort the collected patterns. */ - qsort (patterns.address (), patterns.length (), - sizeof (pattern), pattern_cmp); + patterns.qsort (pattern_cmp); /* Now that we've handled the "extra" patterns, eliminate them from the optabs array. That way they don't get in the way below. */ diff --git a/gcc/genoutput.c b/gcc/genoutput.c index cdd722d43aa..7489d383bbc 100644 --- a/gcc/genoutput.c +++ b/gcc/genoutput.c @@ -98,6 +98,8 @@ along with GCC; see the file COPYING3. If not see #define MAX_MAX_OPERANDS 40 +static char general_mem[] = { TARGET_MEM_CONSTRAINT, 0 }; + static int n_occurrences (int, const char *); static const char *strip_whitespace (const char *); @@ -205,10 +207,9 @@ struct constraint_data const char name[1]; }; -/* This is a complete list (unlike the one in genpreds.c) of constraint - letters and modifiers with machine-independent meaning. The only - omission is digits, as these are handled specially. */ -static const char indep_constraints[] = ",=+%*?!#&<>EFVXgimnoprs"; +/* All machine-independent constraint characters (except digits) that + are handled outside the define*_constraint mechanism. */ +static const char indep_constraints[] = ",=+%*?!#&g"; static struct constraint_data * constraints_by_letter_table[1 << CHAR_BIT]; @@ -1151,13 +1152,13 @@ static void note_constraint (rtx exp, int lineno) { const char *name = XSTR (exp, 0); - unsigned int namelen = strlen (name); struct constraint_data **iter, **slot, *new_cdata; - /* The 'm' constraint is special here since that constraint letter - can be overridden by the back end by defining the - TARGET_MEM_CONSTRAINT macro. */ - if (strchr (indep_constraints, name[0]) && name[0] != 'm') + if (strcmp (name, "TARGET_MEM_CONSTRAINT") == 0) + name = general_mem; + unsigned int namelen = strlen (name); + + if (strchr (indep_constraints, name[0])) { if (name[1] == '\0') error_with_line (lineno, "constraint letter '%s' cannot be " diff --git a/gcc/genpreds.c b/gcc/genpreds.c index 1fcf611f9c7..b14a4ac104b 100644 --- a/gcc/genpreds.c +++ b/gcc/genpreds.c @@ -30,6 +30,8 @@ along with GCC; see the file COPYING3. If not see #include "read-md.h" #include "gensupport.h" +static char general_mem[] = { TARGET_MEM_CONSTRAINT, 0 }; + /* Given a predicate expression EXP, from form NAME at line LINENO, verify that it does not contain any RTL constructs which are not valid in predicate definitions. Returns true if EXP is @@ -659,12 +661,9 @@ static struct constraint_data **last_constraint_ptr = &first_constraint; #define FOR_ALL_CONSTRAINTS(iter_) \ for (iter_ = first_constraint; iter_; iter_ = iter_->next_textual) -/* These letters, and all names beginning with them, are reserved for - generic constraints. - The 'm' constraint is not mentioned here since that constraint - letter can be overridden by the back end by defining the - TARGET_MEM_CONSTRAINT macro. */ -static const char generic_constraint_letters[] = "EFVXginoprs"; +/* Contraint letters that have a special meaning and that cannot be used + in define*_constraints. */ +static const char generic_constraint_letters[] = "g"; /* Machine-independent code expects that constraints with these (initial) letters will allow only (a subset of all) CONST_INTs. */ @@ -684,7 +683,14 @@ static bool have_memory_constraints; static bool have_address_constraints; static bool have_extra_constraints; static bool have_const_int_constraints; -static bool have_const_dbl_constraints; +static unsigned int num_constraints; + +static const constraint_data **enum_order; +static unsigned int register_start, register_end; +static unsigned int satisfied_start; +static unsigned int const_int_start, const_int_end; +static unsigned int memory_start, memory_end; +static unsigned int address_start, address_end; /* Convert NAME, which contains angle brackets and/or underscores, to a string that can be used as part of a C identifier. The string @@ -728,19 +734,12 @@ add_constraint (const char *name, const char *regclass, bool is_const_dbl; size_t namelen; + if (strcmp (name, "TARGET_MEM_CONSTRAINT") == 0) + name = general_mem; + if (exp && validate_exp (exp, name, lineno)) return; - if (!ISALPHA (name[0]) && name[0] != '_') - { - if (name[1] == '\0') - error_with_line (lineno, "constraint name '%s' is not " - "a letter or underscore", name); - else - error_with_line (lineno, "constraint name '%s' does not begin " - "with a letter or underscore", name); - return; - } for (p = name; *p; p++) if (!ISALNUM (*p)) { @@ -880,10 +879,10 @@ add_constraint (const char *name, const char *regclass, constraint_max_namelen = MAX (constraint_max_namelen, strlen (name)); have_register_constraints |= c->is_register; have_const_int_constraints |= c->is_const_int; - have_const_dbl_constraints |= c->is_const_dbl; have_extra_constraints |= c->is_extra; have_memory_constraints |= c->is_memory; have_address_constraints |= c->is_address; + num_constraints += 1; } /* Process a DEFINE_CONSTRAINT, DEFINE_MEMORY_CONSTRAINT, or @@ -904,30 +903,71 @@ process_define_register_constraint (rtx c, int lineno) add_constraint (XSTR (c, 0), XSTR (c, 1), 0, false, false, lineno); } +/* Put the constraints into enum order. We want to keep constraints + of the same type together so that query functions can be simple + range checks. */ +static void +choose_enum_order (void) +{ + struct constraint_data *c; + + enum_order = XNEWVEC (const constraint_data *, num_constraints); + unsigned int next = 0; + + register_start = next; + FOR_ALL_CONSTRAINTS (c) + if (c->is_register) + enum_order[next++] = c; + register_end = next; + + satisfied_start = next; + + const_int_start = next; + FOR_ALL_CONSTRAINTS (c) + if (c->is_const_int) + enum_order[next++] = c; + const_int_end = next; + + memory_start = next; + FOR_ALL_CONSTRAINTS (c) + if (c->is_memory) + enum_order[next++] = c; + memory_end = next; + + address_start = next; + FOR_ALL_CONSTRAINTS (c) + if (c->is_address) + enum_order[next++] = c; + address_end = next; + + FOR_ALL_CONSTRAINTS (c) + if (!c->is_register && !c->is_const_int && !c->is_memory && !c->is_address) + enum_order[next++] = c; + gcc_assert (next == num_constraints); +} + /* Write out an enumeration with one entry per machine-specific constraint. */ static void write_enum_constraint_num (void) { - struct constraint_data *c; - fputs ("#define CONSTRAINT_NUM_DEFINED_P 1\n", stdout); fputs ("enum constraint_num\n" "{\n" " CONSTRAINT__UNKNOWN = 0", stdout); - FOR_ALL_CONSTRAINTS (c) - printf (",\n CONSTRAINT_%s", c->c_name); + for (unsigned int i = 0; i < num_constraints; ++i) + printf (",\n CONSTRAINT_%s", enum_order[i]->c_name); puts (",\n CONSTRAINT__LIMIT\n};\n"); } /* Write out a function which looks at a string and determines what constraint name, if any, it begins with. */ static void -write_lookup_constraint (void) +write_lookup_constraint_1 (void) { unsigned int i; puts ("enum constraint_num\n" - "lookup_constraint (const char *str)\n" + "lookup_constraint_1 (const char *str)\n" "{\n" " switch (str[0])\n" " {"); @@ -962,6 +1002,29 @@ write_lookup_constraint (void) "}\n"); } +/* Write out an array that maps single-letter characters to their + constraints (if that fits in a character) or 255 if lookup_constraint_1 + must be called. */ +static void +write_lookup_constraint_array (void) +{ + unsigned int i; + printf ("const unsigned char lookup_constraint_array[] = {\n "); + for (i = 0; i < ARRAY_SIZE (constraints_by_letter_table); i++) + { + if (i != 0) + printf (",\n "); + struct constraint_data *c = constraints_by_letter_table[i]; + if (!c) + printf ("CONSTRAINT__UNKNOWN"); + else if (c->namelen == 1) + printf ("MIN ((int) CONSTRAINT_%s, (int) UCHAR_MAX)", c->c_name); + else + printf ("UCHAR_MAX"); + } + printf ("\n};\n\n"); +} + /* Write out a function which looks at a string and determines what the constraint name length is. */ static void @@ -1010,12 +1073,12 @@ write_insn_constraint_len (void) /* Write out the function which computes the register class corresponding to a register constraint. */ static void -write_regclass_for_constraint (void) +write_reg_class_for_constraint_1 (void) { struct constraint_data *c; puts ("enum reg_class\n" - "regclass_for_constraint (enum constraint_num c)\n" + "reg_class_for_constraint_1 (enum constraint_num c)\n" "{\n" " switch (c)\n" " {"); @@ -1100,26 +1163,19 @@ write_tm_constrs_h (void) a CONSTRAINT_xxx constant to one of the predicate functions generated above. */ static void -write_constraint_satisfied_p (void) +write_constraint_satisfied_p_array (void) { - struct constraint_data *c; - - puts ("bool\n" - "constraint_satisfied_p (rtx op, enum constraint_num c)\n" - "{\n" - " switch (c)\n" - " {"); - - FOR_ALL_CONSTRAINTS (c) - if (!c->is_register) - printf (" case CONSTRAINT_%s: " - "return satisfies_constraint_%s (op);\n", - c->c_name, c->c_name); + if (satisfied_start == num_constraints) + return; - puts (" default: break;\n" - " }\n" - " return false;\n" - "}\n"); + printf ("bool (*constraint_satisfied_p_array[]) (rtx) = {\n "); + for (unsigned int i = satisfied_start; i < num_constraints; ++i) + { + if (i != satisfied_start) + printf (",\n "); + printf ("satisfies_constraint_%s", enum_order[i]->c_name); + } + printf ("\n};\n\n"); } /* Write out the function which computes whether a given value matches @@ -1153,55 +1209,53 @@ write_insn_const_int_ok_for_constraint (void) " return false;\n" "}\n"); } - - -/* Write out the function which computes whether a given constraint is - a memory constraint. */ + +/* Write a definition for a function NAME that returns true if a given + constraint_num is in the range [START, END). */ static void -write_insn_extra_memory_constraint (void) +write_range_function (const char *name, unsigned int start, unsigned int end) { - struct constraint_data *c; - - puts ("bool\n" - "insn_extra_memory_constraint (enum constraint_num c)\n" - "{\n" - " switch (c)\n" - " {"); - - FOR_ALL_CONSTRAINTS (c) - if (c->is_memory) - printf (" case CONSTRAINT_%s:\n return true;\n\n", c->c_name); - - puts (" default: break;\n" - " }\n" - " return false;\n" - "}\n"); + printf ("static inline bool\n"); + if (start != end) + printf ("%s (enum constraint_num c)\n" + "{\n" + " return c >= CONSTRAINT_%s && c <= CONSTRAINT_%s;\n" + "}\n\n", + name, enum_order[start]->c_name, enum_order[end - 1]->c_name); + else + printf ("%s (enum constraint_num)\n" + "{\n" + " return false;\n" + "}\n\n", name); } -/* Write out the function which computes whether a given constraint is - an address constraint. */ +/* VEC is a list of key/value pairs, with the keys being lower bounds + of a range. Output a decision tree that handles the keys covered by + [VEC[START], VEC[END]), returning FALLBACK for keys lower then VEC[START]'s. + INDENT is the number of spaces to indent the code. */ static void -write_insn_extra_address_constraint (void) +print_type_tree (const vec <std::pair <unsigned int, const char *> > &vec, + unsigned int start, unsigned int end, const char *fallback, + unsigned int indent) { - struct constraint_data *c; - - puts ("bool\n" - "insn_extra_address_constraint (enum constraint_num c)\n" - "{\n" - " switch (c)\n" - " {"); - - FOR_ALL_CONSTRAINTS (c) - if (c->is_address) - printf (" case CONSTRAINT_%s:\n return true;\n\n", c->c_name); - - puts (" default: break;\n" - " }\n" - " return false;\n" - "}\n"); + while (start < end) + { + unsigned int mid = (start + end) / 2; + printf ("%*sif (c >= CONSTRAINT_%s)\n", + indent, "", enum_order[vec[mid].first]->c_name); + if (mid + 1 == end) + print_type_tree (vec, mid + 1, end, vec[mid].second, indent + 2); + else + { + printf ("%*s{\n", indent + 2, ""); + print_type_tree (vec, mid + 1, end, vec[mid].second, indent + 4); + printf ("%*s}\n", indent + 2, ""); + } + end = mid; + } + printf ("%*sreturn %s;\n", indent, "", fallback); } - /* Write tm-preds.h. Unfortunately, it is impossible to forward-declare an enumeration in portable C, so we have to condition all these prototypes on HAVE_MACHINE_MODES. */ @@ -1228,8 +1282,50 @@ write_tm_preds_h (void) if (constraint_max_namelen > 0) { write_enum_constraint_num (); - puts ("extern enum constraint_num lookup_constraint (const char *);\n" - "extern bool constraint_satisfied_p (rtx, enum constraint_num);\n"); + puts ("extern enum constraint_num lookup_constraint_1 (const char *);\n" + "extern const unsigned char lookup_constraint_array[];\n" + "\n" + "/* Return the constraint at the beginning of P, or" + " CONSTRAINT__UNKNOWN if it\n" + " isn't recognized. */\n" + "\n" + "static inline enum constraint_num\n" + "lookup_constraint (const char *p)\n" + "{\n" + " unsigned int index = lookup_constraint_array" + "[(unsigned char) *p];\n" + " return (index == UCHAR_MAX\n" + " ? lookup_constraint_1 (p)\n" + " : (enum constraint_num) index);\n" + "}\n"); + if (satisfied_start == num_constraints) + puts ("/* Return true if X satisfies constraint C. */\n" + "\n" + "static inline bool\n" + "constraint_satisfied_p (rtx, enum constraint_num)\n" + "{\n" + " return false;\n" + "}\n"); + else + printf ("extern bool (*constraint_satisfied_p_array[]) (rtx);\n" + "\n" + "/* Return true if X satisfies constraint C. */\n" + "\n" + "static inline bool\n" + "constraint_satisfied_p (rtx x, enum constraint_num c)\n" + "{\n" + " int i = (int) c - (int) CONSTRAINT_%s;\n" + " return i >= 0 && constraint_satisfied_p_array[i] (x);\n" + "}\n" + "\n", + enum_order[satisfied_start]->name); + + write_range_function ("insn_extra_register_constraint", + register_start, register_end); + write_range_function ("insn_extra_memory_constraint", + memory_start, memory_end); + write_range_function ("insn_extra_address_constraint", + address_start, address_end); if (constraint_max_namelen > 1) { @@ -1240,44 +1336,59 @@ write_tm_preds_h (void) else puts ("#define CONSTRAINT_LEN(c_,s_) 1\n"); if (have_register_constraints) - puts ("extern enum reg_class regclass_for_constraint " + puts ("extern enum reg_class reg_class_for_constraint_1 " "(enum constraint_num);\n" - "#define REG_CLASS_FROM_CONSTRAINT(c_,s_) \\\n" - " regclass_for_constraint (lookup_constraint (s_))\n" - "#define REG_CLASS_FOR_CONSTRAINT(x_) \\\n" - " regclass_for_constraint (x_)\n"); + "\n" + "static inline enum reg_class\n" + "reg_class_for_constraint (enum constraint_num c)\n" + "{\n" + " if (insn_extra_register_constraint (c))\n" + " return reg_class_for_constraint_1 (c);\n" + " return NO_REGS;\n" + "}\n"); else - puts ("#define REG_CLASS_FROM_CONSTRAINT(c_,s_) NO_REGS\n" - "#define REG_CLASS_FOR_CONSTRAINT(x_) \\\n" - " NO_REGS\n"); + puts ("static inline enum reg_class\n" + "reg_class_for_constraint (enum constraint_num)\n" + "{\n" + " return NO_REGS;\n" + "}\n"); if (have_const_int_constraints) puts ("extern bool insn_const_int_ok_for_constraint " "(HOST_WIDE_INT, enum constraint_num);\n" "#define CONST_OK_FOR_CONSTRAINT_P(v_,c_,s_) \\\n" " insn_const_int_ok_for_constraint (v_, " "lookup_constraint (s_))\n"); - if (have_const_dbl_constraints) - puts ("#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(v_,c_,s_) \\\n" - " constraint_satisfied_p (v_, lookup_constraint (s_))\n"); - else - puts ("#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(v_,c_,s_) 0\n"); - if (have_extra_constraints) - puts ("#define EXTRA_CONSTRAINT_STR(v_,c_,s_) \\\n" - " constraint_satisfied_p (v_, lookup_constraint (s_))\n"); - if (have_memory_constraints) - puts ("extern bool " - "insn_extra_memory_constraint (enum constraint_num);\n" - "#define EXTRA_MEMORY_CONSTRAINT(c_,s_) " - "insn_extra_memory_constraint (lookup_constraint (s_))\n"); else - puts ("#define EXTRA_MEMORY_CONSTRAINT(c_,s_) false\n"); - if (have_address_constraints) - puts ("extern bool " - "insn_extra_address_constraint (enum constraint_num);\n" - "#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) " - "insn_extra_address_constraint (lookup_constraint (s_))\n"); - else - puts ("#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) false\n"); + puts ("static inline bool\n" + "insn_const_int_ok_for_constraint (HOST_WIDE_INT," + " enum constraint_num)\n" + "{\n" + " return false;\n" + "}\n"); + + puts ("enum constraint_type\n" + "{\n" + " CT_REGISTER,\n" + " CT_CONST_INT,\n" + " CT_MEMORY,\n" + " CT_ADDRESS,\n" + " CT_FIXED_FORM\n" + "};\n" + "\n" + "static inline enum constraint_type\n" + "get_constraint_type (enum constraint_num c)\n" + "{"); + auto_vec <std::pair <unsigned int, const char *>, 4> values; + if (const_int_start != const_int_end) + values.safe_push (std::make_pair (const_int_start, "CT_CONST_INT")); + if (memory_start != memory_end) + values.safe_push (std::make_pair (memory_start, "CT_MEMORY")); + if (address_start != address_end) + values.safe_push (std::make_pair (address_start, "CT_ADDRESS")); + if (address_end != num_constraints) + values.safe_push (std::make_pair (address_end, "CT_FIXED_FORM")); + print_type_tree (values, 0, values.length (), "CT_REGISTER", 2); + puts ("}"); } puts ("#endif /* tm-preds.h */"); @@ -1328,18 +1439,14 @@ write_insn_preds_c (void) if (constraint_max_namelen > 0) { - write_lookup_constraint (); + write_lookup_constraint_1 (); + write_lookup_constraint_array (); if (have_register_constraints) - write_regclass_for_constraint (); - write_constraint_satisfied_p (); + write_reg_class_for_constraint_1 (); + write_constraint_satisfied_p_array (); if (have_const_int_constraints) write_insn_const_int_ok_for_constraint (); - - if (have_memory_constraints) - write_insn_extra_memory_constraint (); - if (have_address_constraints) - write_insn_extra_address_constraint (); } } @@ -1399,6 +1506,8 @@ main (int argc, char **argv) break; } + choose_enum_order (); + if (gen_header) write_tm_preds_h (); else if (gen_constrs) diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 1635b96cd69..10f8ac6d0e0 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -139,6 +139,7 @@ struct gimplify_omp_ctx enum omp_clause_default_kind default_kind; enum omp_region_type region_type; bool combined_loop; + bool distribute; }; static struct gimplify_ctx *gimplify_ctxp; @@ -6359,7 +6360,11 @@ gimplify_adjust_omp_clauses (tree *list_p) if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0) { - int flags = GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE; + int flags = GOVD_FIRSTPRIVATE; + /* #pragma omp distribute does not allow + lastprivate clause. */ + if (!ctx->outer_context->distribute) + flags |= GOVD_LASTPRIVATE; if (n == NULL) omp_add_variable (ctx->outer_context, decl, flags | GOVD_SEEN); @@ -6640,6 +6645,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) || TREE_CODE (for_stmt) == CILK_SIMD); gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, simd ? ORT_SIMD : ORT_WORKSHARE); + if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE) + gimplify_omp_ctxp->distribute = true; /* Handle OMP_FOR_INIT. */ for_pre_body = NULL; diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 6d61c75f59c..6b535851d6d 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,15 @@ +2014-06-13 Ian Lance Taylor <iant@google.com> + + PR go/61496 + * gospec.c (lang_specific_driver): On Solaris, when not using GNU + ld, add -t option to avoid warning about common symbol changing + size. + +2014-06-10 Jan Hubicka <hubicka@ucw.cz> + + * go/go-gcc.cc (Gcc_backend::global_variable_set_init): Use + symtab_get_node(var_decl)->implicit_section. + 2014-06-07 Jan Hubicka <hubicka@ucw.cz> * go-gcc.cc (global_variable_set_init): Use diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 7e67eed6af6..0c9cb70a655 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -2374,7 +2374,8 @@ Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr) // If this variable goes in a unique section, it may need to go into // a different one now that DECL_INITIAL is set. - if (DECL_HAS_IMPLICIT_SECTION_NAME_P (var_decl)) + if (symtab_get_node(var_decl) + && symtab_get_node(var_decl)->implicit_section) { set_decl_section_name (var_decl, NULL); resolve_unique_section (var_decl, diff --git a/gcc/go/gospec.c b/gcc/go/gospec.c index 02d5842352f..8b2d8afda72 100644 --- a/gcc/go/gospec.c +++ b/gcc/go/gospec.c @@ -395,6 +395,15 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, } #endif +#if defined(TARGET_SOLARIS) && !defined(USE_GLD) + /* We use a common symbol for go$zerovalue. On Solaris, when not + using the GNU linker, the Solaris linker needs an option to not + warn about this. Everything works without this option, but you + get unsightly warnings at link time. */ + generate_option (OPT_Wl_, "-t", 1, CL_DRIVER, &new_decoded_options[j]); + j++; +#endif + *in_decoded_options_count = j; *in_decoded_options = new_decoded_options; *in_added_libraries = added_libraries; diff --git a/gcc/hw-doloop.c b/gcc/hw-doloop.c index d18276103b4..9ab7e65db5f 100644 --- a/gcc/hw-doloop.c +++ b/gcc/hw-doloop.c @@ -119,7 +119,7 @@ scan_loop (hwloop_info loop) insn != NEXT_INSN (BB_END (bb)); insn = NEXT_INSN (insn)) { - df_ref *def_rec; + df_ref def; HARD_REG_SET set_this_insn; if (!NONDEBUG_INSN_P (insn)) @@ -131,9 +131,9 @@ scan_loop (hwloop_info loop) loop->has_asm = true; CLEAR_HARD_REG_SET (set_this_insn); - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) + FOR_EACH_INSN_DEF (def, insn) { - rtx dreg = DF_REF_REG (*def_rec); + rtx dreg = DF_REF_REG (def); if (!REG_P (dreg)) continue; diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 2ca2278709d..816cdaa2a07 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -4279,22 +4279,16 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, FOR_BB_INSNS_REVERSE (new_dest, insn) if (NONDEBUG_INSN_P (insn)) { - df_ref *def_rec; - unsigned int uid = INSN_UID (insn); - - /* If this insn sets any reg in return_regs.. */ - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) - { - df_ref def = *def_rec; - unsigned r = DF_REF_REGNO (def); - - if (bitmap_bit_p (return_regs, r)) + df_ref def; + + /* If this insn sets any reg in return_regs, add all + reg uses to the set of regs we're interested in. */ + FOR_EACH_INSN_DEF (def, insn) + if (bitmap_bit_p (return_regs, DF_REF_REGNO (def))) + { + df_simulate_uses (insn, return_regs); break; - } - /* ..then add all reg uses to the set of regs - we're interested in. */ - if (*def_rec) - df_simulate_uses (insn, return_regs); + } } if (bitmap_intersect_p (merge_set, return_regs)) { diff --git a/gcc/init-regs.c b/gcc/init-regs.c index 59c5bc91004..4080d0f91f3 100644 --- a/gcc/init-regs.c +++ b/gcc/init-regs.c @@ -68,14 +68,12 @@ initialize_uninitialized_regs (void) FOR_BB_INSNS (bb, insn) { - unsigned int uid = INSN_UID (insn); - df_ref *use_rec; + df_ref use; if (!NONDEBUG_INSN_P (insn)) continue; - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) + FOR_EACH_INSN_USE (use, insn) { - df_ref use = *use_rec; unsigned int regno = DF_REF_REGNO (use); /* Only do this for the pseudos. */ @@ -109,7 +107,8 @@ initialize_uninitialized_regs (void) if (dump_file) fprintf (dump_file, "adding initialization in %s of reg %d at in block %d for insn %d.\n", - current_function_name (), regno, bb->index, uid); + current_function_name (), regno, bb->index, + INSN_UID (insn)); } } } diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index d733461f34a..a90d1dcd736 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -1603,6 +1603,8 @@ possible_polymorphic_call_targets (tree otr_type, { if (completep) *completep = false; + if (cache_token) + *cache_token = NULL; if (nonconstruction_targetsp) *nonconstruction_targetsp = 0; return nodes; @@ -1613,6 +1615,8 @@ possible_polymorphic_call_targets (tree otr_type, { if (completep) *completep = true; + if (cache_token) + *cache_token = NULL; if (nonconstruction_targetsp) *nonconstruction_targetsp = 0; return nodes; @@ -1626,6 +1630,8 @@ possible_polymorphic_call_targets (tree otr_type, { if (completep) *completep = false; + if (cache_token) + *cache_token = NULL; if (nonconstruction_targetsp) *nonconstruction_targetsp = 0; return nodes; diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index d02093a00f4..b67deedd777 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -2673,13 +2673,19 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target) if (dump_enabled_p ()) { - location_t loc = gimple_location (ie->call_stmt); - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, - "discovered direct call to non-function in %s/%i, " - "making it __builtin_unreachable\n", - ie->caller->name (), - ie->caller->order); + const char *fmt = "discovered direct call to non-function in %s/%i, " + "making it __builtin_unreachable\n"; + + if (ie->call_stmt) + { + location_t loc = gimple_location (ie->call_stmt); + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, fmt, + ie->caller->name (), ie->caller->order); + } + else if (dump_file) + fprintf (dump_file, fmt, ie->caller->name (), ie->caller->order); } + target = builtin_decl_implicit (BUILT_IN_UNREACHABLE); callee = cgraph_get_create_node (target); unreachable = true; @@ -2739,10 +2745,18 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target) } if (dump_enabled_p ()) { - location_t loc = gimple_location (ie->call_stmt); - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, - "converting indirect call in %s to direct call to %s\n", - ie->caller->name (), callee->name ()); + const char *fmt = "converting indirect call in %s to direct call to %s\n"; + + if (ie->call_stmt) + { + location_t loc = gimple_location (ie->call_stmt); + + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, fmt, + ie->caller->name (), callee->name ()); + + } + else if (dump_file) + fprintf (dump_file, fmt, ie->caller->name (), callee->name ()); } ie = cgraph_make_edge_direct (ie, callee); es = inline_edge_summary (ie); diff --git a/gcc/ipa-visibility.c b/gcc/ipa-visibility.c index 039b756b39a..4e0fd9e0b40 100644 --- a/gcc/ipa-visibility.c +++ b/gcc/ipa-visibility.c @@ -512,7 +512,8 @@ function_and_variable_visibility (bool whole_program) next = next->same_comdat_group) { next->set_comdat_group (NULL); - next->set_section (NULL); + if (!next->alias) + next->set_section (NULL); symtab_make_decl_local (next->decl); next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY || next->unique_name @@ -527,7 +528,7 @@ function_and_variable_visibility (bool whole_program) } if (TREE_PUBLIC (node->decl)) node->set_comdat_group (NULL); - if (DECL_COMDAT (node->decl)) + if (DECL_COMDAT (node->decl) && !node->alias) node->set_section (NULL); symtab_make_decl_local (node->decl); } @@ -646,7 +647,8 @@ function_and_variable_visibility (bool whole_program) next = next->same_comdat_group) { next->set_comdat_group (NULL); - next->set_section (NULL); + if (!next->alias) + next->set_section (NULL); symtab_make_decl_local (next->decl); next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY || next->unique_name @@ -657,16 +659,19 @@ function_and_variable_visibility (bool whole_program) } if (TREE_PUBLIC (vnode->decl)) vnode->set_comdat_group (NULL); - if (DECL_COMDAT (vnode->decl)) + if (DECL_COMDAT (vnode->decl) && !vnode->alias) vnode->set_section (NULL); symtab_make_decl_local (vnode->decl); vnode->resolution = LDPR_PREVAILING_DEF_IRONLY; } update_visibility_by_resolution_info (vnode); - /* Update virutal tables to point to local aliases where possible. */ + /* Update virtual tables to point to local aliases where possible. */ if (DECL_VIRTUAL_P (vnode->decl) - && !DECL_EXTERNAL (vnode->decl)) + && !DECL_EXTERNAL (vnode->decl) + /* FIXME: currently this optimization breaks on AIX. Disable it for targets + without comdat support for now. */ + && SUPPORTS_ONE_ONLY) { int i; struct ipa_ref *ref; diff --git a/gcc/ipa.c b/gcc/ipa.c index 07f6c15592b..5128b4dbd2e 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -281,9 +281,6 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) struct pointer_set_t *reachable_call_targets = pointer_set_create (); timevar_push (TV_IPA_UNREACHABLE); -#ifdef ENABLE_CHECKING - verify_symtab (); -#endif if (optimize && flag_devirtualize) build_type_inheritance_graph (); if (file) diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index 4ecf75f124d..5716c2a22d9 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -645,8 +645,6 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, { switch (c) { - case ',': - break; case '*': /* Ignore the next letter for this pass. */ c = *++p; @@ -654,92 +652,6 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, case '?': alt_cost += 2; - case '!': case '#': case '&': - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - break; - - case 'p': - allows_addr = 1; - win = address_operand (op, GET_MODE (op)); - /* We know this operand is an address, so we want it - to be allocated to a register that can be the - base of an address, i.e. BASE_REG_CLASS. */ - classes[i] - = ira_reg_class_subunion[classes[i]] - [base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, - ADDRESS, SCRATCH)]; - break; - - case 'm': case 'o': case 'V': - /* It doesn't seem worth distinguishing between - offsettable and non-offsettable addresses - here. */ - insn_allows_mem[i] = allows_mem[i] = 1; - if (MEM_P (op)) - win = 1; - break; - - case '<': - if (MEM_P (op) - && (GET_CODE (XEXP (op, 0)) == PRE_DEC - || GET_CODE (XEXP (op, 0)) == POST_DEC)) - win = 1; - break; - - case '>': - if (MEM_P (op) - && (GET_CODE (XEXP (op, 0)) == PRE_INC - || GET_CODE (XEXP (op, 0)) == POST_INC)) - win = 1; - break; - - case 'E': - case 'F': - if (CONST_DOUBLE_AS_FLOAT_P (op) - || (GET_CODE (op) == CONST_VECTOR - && (GET_MODE_CLASS (GET_MODE (op)) - == MODE_VECTOR_FLOAT))) - win = 1; - break; - - case 'G': - case 'H': - if (CONST_DOUBLE_AS_FLOAT_P (op) - && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, p)) - win = 1; - break; - - case 's': - if (CONST_SCALAR_INT_P (op)) - break; - - case 'i': - if (CONSTANT_P (op) - && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))) - win = 1; - break; - - case 'n': - if (CONST_SCALAR_INT_P (op)) - win = 1; - break; - - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - if (CONST_INT_P (op) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, p)) - win = 1; - break; - - case 'X': - win = 1; break; case 'g': @@ -748,30 +660,38 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)))) win = 1; insn_allows_mem[i] = allows_mem[i] = 1; - case 'r': classes[i] = ira_reg_class_subunion[classes[i]][GENERAL_REGS]; break; default: - if (REG_CLASS_FROM_CONSTRAINT (c, p) != NO_REGS) - classes[i] = ira_reg_class_subunion[classes[i]] - [REG_CLASS_FROM_CONSTRAINT (c, p)]; -#ifdef EXTRA_CONSTRAINT_STR - else if (EXTRA_CONSTRAINT_STR (op, c, p)) - win = 1; - - if (EXTRA_MEMORY_CONSTRAINT (c, p)) + enum constraint_num cn = lookup_constraint (p); + enum reg_class cl; + switch (get_constraint_type (cn)) { + case CT_REGISTER: + cl = reg_class_for_constraint (cn); + if (cl != NO_REGS) + classes[i] = ira_reg_class_subunion[classes[i]][cl]; + break; + + case CT_CONST_INT: + if (CONST_INT_P (op) + && insn_const_int_ok_for_constraint (INTVAL (op), cn)) + win = 1; + break; + + case CT_MEMORY: /* Every MEM can be reloaded to fit. */ insn_allows_mem[i] = allows_mem[i] = 1; if (MEM_P (op)) win = 1; - } - if (EXTRA_ADDRESS_CONSTRAINT (c, p)) - { + break; + + case CT_ADDRESS: /* Every address can be reloaded to fit. */ allows_addr = 1; - if (address_operand (op, GET_MODE (op))) + if (address_operand (op, GET_MODE (op)) + || constraint_satisfied_p (op, cn)) win = 1; /* We know this operand is an address, so we want it to be allocated to a hard register @@ -781,8 +701,13 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, = ira_reg_class_subunion[classes[i]] [base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH)]; + break; + + case CT_FIXED_FORM: + if (constraint_satisfied_p (op, cn)) + win = 1; + break; } -#endif break; } p += CONSTRAINT_LEN (c, p); @@ -1275,8 +1200,8 @@ record_operand_costs (rtx insn, enum reg_class *pref) XEXP (recog_data.operand[i], 0), 0, MEM, SCRATCH, frequency * 2); else if (constraints[i][0] == 'p' - || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], - constraints[i])) + || (insn_extra_address_constraint + (lookup_constraint (constraints[i])))) record_address_regs (VOIDmode, ADDR_SPACE_GENERIC, recog_data.operand[i], 0, ADDRESS, SCRATCH, frequency * 2); diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index bb03967225b..ec8f679bcee 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -725,13 +725,13 @@ make_early_clobber_and_input_conflicts (void) static bool mark_hard_reg_early_clobbers (rtx insn, bool live_p) { - df_ref *def_rec; + df_ref def; bool set_p = false; - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - if (DF_REF_FLAGS_IS_SET (*def_rec, DF_REF_MUST_CLOBBER)) + FOR_EACH_INSN_DEF (def, insn) + if (DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER)) { - rtx dreg = DF_REF_REG (*def_rec); + rtx dreg = DF_REF_REG (def); if (GET_CODE (dreg) == SUBREG) dreg = SUBREG_REG (dreg); @@ -742,9 +742,9 @@ mark_hard_reg_early_clobbers (rtx insn, bool live_p) because there is no way to say that non-operand hard register clobbers are not early ones. */ if (live_p) - mark_ref_live (*def_rec); + mark_ref_live (def); else - mark_ref_dead (*def_rec); + mark_ref_dead (def); set_p = true; } @@ -759,6 +759,7 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const) { int c; enum reg_class cl, next_cl; + enum constraint_num cn; cl = NO_REGS; alternative_mask enabled = recog_data.enabled_alternatives; @@ -770,99 +771,21 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const) else if (enabled & 1) switch (c) { - case ' ': - case '\t': - case '=': - case '+': - case '*': - case '&': - case '%': - case '!': - case '?': - break; - case 'i': - if (CONSTANT_P (op) - || (equiv_const != NULL_RTX && CONSTANT_P (equiv_const))) - return NO_REGS; - break; - - case 'n': - if (CONST_SCALAR_INT_P (op) - || (equiv_const != NULL_RTX && CONST_SCALAR_INT_P (equiv_const))) - return NO_REGS; - break; - - case 's': - if ((CONSTANT_P (op) && !CONST_SCALAR_INT_P (op)) - || (equiv_const != NULL_RTX - && CONSTANT_P (equiv_const) - && !CONST_SCALAR_INT_P (equiv_const))) - return NO_REGS; - break; - - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - if ((CONST_INT_P (op) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, constraints)) - || (equiv_const != NULL_RTX - && CONST_INT_P (equiv_const) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (equiv_const), - c, constraints))) - return NO_REGS; - break; - - case 'E': - case 'F': - if (CONST_DOUBLE_AS_FLOAT_P (op) - || (GET_CODE (op) == CONST_VECTOR - && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT) - || (equiv_const != NULL_RTX - && (CONST_DOUBLE_AS_FLOAT_P (equiv_const) - || (GET_CODE (equiv_const) == CONST_VECTOR - && (GET_MODE_CLASS (GET_MODE (equiv_const)) - == MODE_VECTOR_FLOAT))))) - return NO_REGS; - break; - - case 'G': - case 'H': - if ((CONST_DOUBLE_AS_FLOAT_P (op) - && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, constraints)) - || (equiv_const != NULL_RTX - && CONST_DOUBLE_AS_FLOAT_P (equiv_const) - && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (equiv_const, - c, constraints))) - return NO_REGS; - break; + case 'g': + return NO_REGS; - case 'r': - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - case 'h': case 'j': case 'k': case 'l': - case 'q': case 't': case 'u': - case 'v': case 'w': case 'x': case 'y': case 'z': - case 'A': case 'B': case 'C': case 'D': - case 'Q': case 'R': case 'S': case 'T': case 'U': - case 'W': case 'Y': case 'Z': -#ifdef EXTRA_CONSTRAINT_STR + default: /* ??? Is this the best way to handle memory constraints? */ - if (EXTRA_MEMORY_CONSTRAINT (c, constraints) - || EXTRA_ADDRESS_CONSTRAINT (c, constraints)) + cn = lookup_constraint (constraints); + if (insn_extra_memory_constraint (cn) + || insn_extra_address_constraint (cn)) return NO_REGS; - if (EXTRA_CONSTRAINT_STR (op, c, constraints) + if (constraint_satisfied_p (op, cn) || (equiv_const != NULL_RTX && CONSTANT_P (equiv_const) - && EXTRA_CONSTRAINT_STR (equiv_const, c, constraints))) + && constraint_satisfied_p (equiv_const, cn))) return NO_REGS; -#endif - next_cl = (c == 'r' - ? GENERAL_REGS - : REG_CLASS_FROM_CONSTRAINT (c, constraints)); + next_cl = reg_class_for_constraint (cn); if (next_cl == NO_REGS) break; if (cl == NO_REGS @@ -885,9 +808,6 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const) return NO_REGS; cl = next_cl; break; - - default: - return NO_REGS; } return cl; } @@ -938,29 +858,17 @@ ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set) else if (c == ',') enabled >>= 1; else if (enabled & 1) - switch (c) - { - case 'r': - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - case 'h': case 'j': case 'k': case 'l': - case 'q': case 't': case 'u': - case 'v': case 'w': case 'x': case 'y': case 'z': - case 'A': case 'B': case 'C': case 'D': - case 'Q': case 'R': case 'S': case 'T': case 'U': - case 'W': case 'Y': case 'Z': - cl = (c == 'r' - ? GENERAL_REGS - : REG_CLASS_FROM_CONSTRAINT (c, p)); - if (cl != NO_REGS) - { - /* There is no register pressure problem if all of the - regs in this class are fixed. */ - int regno = ira_class_singleton[cl][mode]; - if (regno >= 0) - add_to_hard_reg_set (set, mode, regno); - } - break; - } + { + cl = reg_class_for_constraint (lookup_constraint (p)); + if (cl != NO_REGS) + { + /* There is no register pressure problem if all of the + regs in this class are fixed. */ + int regno = ira_class_singleton[cl][mode]; + if (regno >= 0) + add_to_hard_reg_set (set, mode, regno); + } + } } } } @@ -1206,7 +1114,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) pessimistic, but it probably doesn't matter much in practice. */ FOR_BB_INSNS_REVERSE (bb, insn) { - df_ref *def_rec, *use_rec; + df_ref def, use; bool call_p; if (!NONDEBUG_INSN_P (insn)) @@ -1227,9 +1135,9 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) live would stop us from allocating it to a call-crossing allocno. */ call_p = CALL_P (insn); - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - if (!call_p || !DF_REF_FLAGS_IS_SET (*def_rec, DF_REF_MAY_CLOBBER)) - mark_ref_live (*def_rec); + FOR_EACH_INSN_DEF (def, insn) + if (!call_p || !DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER)) + mark_ref_live (def); /* If INSN has multiple outputs, then any value used in one of the outputs conflicts with the other outputs. Model this @@ -1243,12 +1151,12 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) to the same hard register as an unused output we could set the hard register before the output reload insn. */ if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn)) - for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) + FOR_EACH_INSN_USE (use, insn) { int i; rtx reg; - reg = DF_REF_REG (*use_rec); + reg = DF_REF_REG (use); for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--) { rtx set; @@ -1259,7 +1167,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) { /* After the previous loop, this is a no-op if REG is contained within SET_DEST (SET). */ - mark_ref_live (*use_rec); + mark_ref_live (use); break; } } @@ -1270,9 +1178,9 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) process_single_reg_class_operands (false, freq); /* See which defined values die here. */ - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - if (!call_p || !DF_REF_FLAGS_IS_SET (*def_rec, DF_REF_MAY_CLOBBER)) - mark_ref_dead (*def_rec); + FOR_EACH_INSN_DEF (def, insn) + if (!call_p || !DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER)) + mark_ref_dead (def); if (call_p) { @@ -1341,8 +1249,8 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) curr_point++; /* Mark each used value as live. */ - for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) - mark_ref_live (*use_rec); + FOR_EACH_INSN_USE (use, insn) + mark_ref_live (use); process_single_reg_class_operands (true, freq); @@ -1355,16 +1263,16 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) /* Mark each hard reg as live again. For example, a hard register can be in clobber and in an insn input. */ - for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) + FOR_EACH_INSN_USE (use, insn) { - rtx ureg = DF_REF_REG (*use_rec); + rtx ureg = DF_REF_REG (use); if (GET_CODE (ureg) == SUBREG) ureg = SUBREG_REG (ureg); if (! REG_P (ureg) || REGNO (ureg) >= FIRST_PSEUDO_REGISTER) continue; - mark_ref_live (*use_rec); + mark_ref_live (use); } } diff --git a/gcc/ira.c b/gcc/ira.c index 6ee1c140f13..41988fde9f6 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -1835,9 +1835,6 @@ ira_setup_alts (rtx insn, HARD_REG_SET &alts) len = 0; break; - case '?': case '!': case '*': case '=': case '+': - break; - case '%': /* We only support one commutative marker, the first one. We already set commutative @@ -1846,100 +1843,41 @@ ira_setup_alts (rtx insn, HARD_REG_SET &alts) commutative = nop; break; - case '&': - break; - case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': goto op_success; break; - case 'p': case 'g': - case 'X': - case TARGET_MEM_CONSTRAINT: - goto op_success; - break; - - case '<': - if (MEM_P (op) - && (GET_CODE (XEXP (op, 0)) == PRE_DEC - || GET_CODE (XEXP (op, 0)) == POST_DEC)) - goto op_success; - break; - - case '>': - if (MEM_P (op) - && (GET_CODE (XEXP (op, 0)) == PRE_INC - || GET_CODE (XEXP (op, 0)) == POST_INC)) - goto op_success; - break; - - case 'E': - case 'F': - if (CONST_DOUBLE_AS_FLOAT_P (op) - || (GET_CODE (op) == CONST_VECTOR - && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT)) - goto op_success; - break; - - case 'G': - case 'H': - if (CONST_DOUBLE_AS_FLOAT_P (op) - && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, p)) - goto op_success; - break; - - case 's': - if (CONST_SCALAR_INT_P (op)) - break; - case 'i': - if (CONSTANT_P (op)) - goto op_success; - break; - - case 'n': - if (CONST_SCALAR_INT_P (op)) - goto op_success; - break; - - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - if (CONST_INT_P (op) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, p)) - goto op_success; - break; - - case 'V': - if (MEM_P (op) && ! offsettable_memref_p (op)) - goto op_success; - break; - - case 'o': goto op_success; break; default: { - enum reg_class cl; - - cl = (c == 'r' ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, p)); - if (cl != NO_REGS) - goto op_success; -#ifdef EXTRA_CONSTRAINT_STR - else if (EXTRA_CONSTRAINT_STR (op, c, p)) - goto op_success; - else if (EXTRA_MEMORY_CONSTRAINT (c, p)) - goto op_success; - else if (EXTRA_ADDRESS_CONSTRAINT (c, p)) - goto op_success; -#endif + enum constraint_num cn = lookup_constraint (p); + switch (get_constraint_type (cn)) + { + case CT_REGISTER: + if (reg_class_for_constraint (cn) != NO_REGS) + goto op_success; + break; + + case CT_CONST_INT: + if (CONST_INT_P (op) + && (insn_const_int_ok_for_constraint + (INTVAL (op), cn))) + goto op_success; + break; + + case CT_ADDRESS: + case CT_MEMORY: + goto op_success; + + case CT_FIXED_FORM: + if (constraint_satisfied_p (op, cn)) + goto op_success; + break; + } break; } } @@ -1972,9 +1910,6 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts) int curr_alt, c, original, dup; bool ignore_p, use_commut_op_p; const char *str; -#ifdef EXTRA_CONSTRAINT_STR - rtx op; -#endif if (op_num < 0 || recog_data.n_alternatives == 0) return -1; @@ -1985,9 +1920,7 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts) use_commut_op_p = false; for (;;) { -#ifdef EXTRA_CONSTRAINT_STR - op = recog_data.operand[op_num]; -#endif + rtx op = recog_data.operand[op_num]; for (curr_alt = 0, ignore_p = !TEST_HARD_REG_BIT (alts, curr_alt), original = -1;;) @@ -2005,32 +1938,17 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts) else if (! ignore_p) switch (c) { - case 'X': - case 'p': case 'g': goto fail; - case 'r': - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - case 'h': case 'j': case 'k': case 'l': - case 'q': case 't': case 'u': - case 'v': case 'w': case 'x': case 'y': case 'z': - case 'A': case 'B': case 'C': case 'D': - case 'Q': case 'R': case 'S': case 'T': case 'U': - case 'W': case 'Y': case 'Z': + default: { - enum reg_class cl; - - cl = (c == 'r' - ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, str)); - if (cl != NO_REGS) - { - if (! targetm.class_likely_spilled_p (cl)) - goto fail; - } -#ifdef EXTRA_CONSTRAINT_STR - else if (EXTRA_CONSTRAINT_STR (op, c, str)) + enum constraint_num cn = lookup_constraint (str); + enum reg_class cl = reg_class_for_constraint (cn); + if (cl != NO_REGS + && !targetm.class_likely_spilled_p (cl)) + goto fail; + if (constraint_satisfied_p (op, cn)) goto fail; -#endif break; } @@ -2333,12 +2251,11 @@ compute_regs_asm_clobbered (void) rtx insn; FOR_BB_INSNS_REVERSE (bb, insn) { - df_ref *def_rec; + df_ref def; if (insn_contains_asm (insn)) - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) + FOR_EACH_INSN_DEF (def, insn) { - df_ref def = *def_rec; unsigned int dregno = DF_REF_REGNO (def); if (HARD_REGISTER_NUM_P (dregno)) add_to_hard_reg_set (&crtl->asm_clobbers, @@ -4123,9 +4040,8 @@ build_insn_chain (void) { if (!NOTE_P (insn) && !BARRIER_P (insn)) { - unsigned int uid = INSN_UID (insn); - df_ref *def_rec; - df_ref *use_rec; + struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); + df_ref def, use; c = new_insn_chain (); c->next = next; @@ -4137,9 +4053,8 @@ build_insn_chain (void) c->block = bb->index; if (NONDEBUG_INSN_P (insn)) - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + FOR_EACH_INSN_INFO_DEF (def, insn_info) { - df_ref def = *def_rec; unsigned int regno = DF_REF_REGNO (def); /* Ignore may clobbers because these are generated @@ -4228,9 +4143,8 @@ build_insn_chain (void) bitmap_copy (&c->live_throughout, live_relevant_regs); if (NONDEBUG_INSN_P (insn)) - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) + FOR_EACH_INSN_INFO_USE (use, insn_info) { - df_ref use = *use_rec; unsigned int regno = DF_REF_REGNO (use); rtx reg = DF_REF_REG (use); @@ -4522,41 +4436,40 @@ find_moveable_pseudos (void) FOR_BB_INSNS (bb, insn) if (NONDEBUG_INSN_P (insn)) { - df_ref *u_rec, *d_rec; + df_insn_info *insn_info = DF_INSN_INFO_GET (insn); + df_ref def, use; uid_luid[INSN_UID (insn)] = i++; - u_rec = DF_INSN_USES (insn); - d_rec = DF_INSN_DEFS (insn); - if (d_rec[0] != NULL && d_rec[1] == NULL - && u_rec[0] != NULL && u_rec[1] == NULL - && DF_REF_REGNO (*u_rec) == DF_REF_REGNO (*d_rec) - && !bitmap_bit_p (&set, DF_REF_REGNO (*u_rec)) + def = df_single_def (insn_info); + use = df_single_use (insn_info); + if (use + && def + && DF_REF_REGNO (use) == DF_REF_REGNO (def) + && !bitmap_bit_p (&set, DF_REF_REGNO (use)) && rtx_moveable_p (&PATTERN (insn), OP_IN)) { - unsigned regno = DF_REF_REGNO (*u_rec); + unsigned regno = DF_REF_REGNO (use); bitmap_set_bit (moveable, regno); bitmap_set_bit (&set, regno); bitmap_set_bit (&used, regno); bitmap_clear_bit (transp, regno); continue; } - while (*u_rec) + FOR_EACH_INSN_INFO_USE (use, insn_info) { - unsigned regno = DF_REF_REGNO (*u_rec); + unsigned regno = DF_REF_REGNO (use); bitmap_set_bit (&used, regno); if (bitmap_clear_bit (moveable, regno)) bitmap_clear_bit (transp, regno); - u_rec++; } - while (*d_rec) + FOR_EACH_INSN_INFO_DEF (def, insn_info) { - unsigned regno = DF_REF_REGNO (*d_rec); + unsigned regno = DF_REF_REGNO (def); bitmap_set_bit (&set, regno); bitmap_clear_bit (transp, regno); bitmap_clear_bit (moveable, regno); - d_rec++; } } } @@ -4573,16 +4486,16 @@ find_moveable_pseudos (void) FOR_BB_INSNS (bb, insn) if (NONDEBUG_INSN_P (insn)) { + df_insn_info *insn_info = DF_INSN_INFO_GET (insn); rtx def_insn, closest_use, note; - df_ref *def_rec, def, use; + df_ref def, use; unsigned regno; bool all_dominated, all_local; enum machine_mode mode; - def_rec = DF_INSN_DEFS (insn); + def = df_single_def (insn_info); /* There must be exactly one def in this insn. */ - def = *def_rec; - if (!def || def_rec[1] || !single_set (insn)) + if (!def || !single_set (insn)) continue; /* This must be the only definition of the reg. We also limit which modes we deal with so that we can assume we can generate @@ -4694,7 +4607,7 @@ find_moveable_pseudos (void) bitmap def_bb_transp = bb_transp_live + def_block->index; bool local_to_bb_p = bitmap_bit_p (def_bb_local, i); rtx use_insn = closest_uses[i]; - df_ref *def_insn_use_rec = DF_INSN_USES (def_insn); + df_ref use; bool all_ok = true; bool all_transp = true; @@ -4725,9 +4638,8 @@ find_moveable_pseudos (void) if (dump_file) fprintf (dump_file, "Examining insn %d, def for %d\n", INSN_UID (def_insn), i); - while (*def_insn_use_rec != NULL) + FOR_EACH_INSN_USE (use, def_insn) { - df_ref use = *def_insn_use_rec; unsigned regno = DF_REF_REGNO (use); if (bitmap_bit_p (&unusable_as_input, regno)) { @@ -4770,8 +4682,6 @@ find_moveable_pseudos (void) else all_transp = false; } - - def_insn_use_rec++; } if (!all_ok) continue; diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 55210830645..09e7978d942 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,9 @@ +2014-06-11 Jan Hubicka <hubicka@ucw.cz> + + * java/class.c (build_utf8_ref): Update handling for section names + that are no longer trees. + (emit_register_classes_in_jcr_section): Update. + 2014-06-07 Jan Hubicka <hubicka@ucw.cz> * class.c (build_utf8_ref): Use set_decl_section_name. diff --git a/gcc/java/class.c b/gcc/java/class.c index fb0c0d45b45..dae321890f8 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -991,7 +991,7 @@ build_utf8_ref (tree name) | SECTION_MERGE | (SECTION_ENTSIZE & decl_size)); sprintf (buf, ".rodata.jutf8.%d", decl_size); switch_to_section (get_section (buf, flags, NULL)); - set_decl_section_name (decl, build_string (strlen (buf), buf)); + set_decl_section_name (decl, buf); } } @@ -2815,8 +2815,7 @@ emit_register_classes_in_jcr_section (void) DECL_ARTIFICIAL (cdecl) = 1; DECL_IGNORED_P (cdecl) = 1; DECL_PRESERVE_P (cdecl) = 1; - set_decl_section_name (cdecl, build_string (strlen (JCR_SECTION_NAME), - JCR_SECTION_NAME)); + set_decl_section_name (cdecl, JCR_SECTION_NAME); pushdecl_top_level (cdecl); relayout_decl (cdecl); rest_of_decl_compilation (cdecl, 1, 0); diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index 100a2c1b7ff..898a431af2c 100644 --- a/gcc/loop-invariant.c +++ b/gcc/loop-invariant.c @@ -826,14 +826,14 @@ static bool check_dependencies (rtx insn, bitmap depends_on) { struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); - df_ref *use_rec; + df_ref use; basic_block bb = BLOCK_FOR_INSN (insn); - for (use_rec = DF_INSN_INFO_USES (insn_info); *use_rec; use_rec++) - if (!check_dependency (bb, *use_rec, depends_on)) + FOR_EACH_INSN_INFO_USE (use, insn_info) + if (!check_dependency (bb, use, depends_on)) return false; - for (use_rec = DF_INSN_INFO_EQ_USES (insn_info); *use_rec; use_rec++) - if (!check_dependency (bb, *use_rec, depends_on)) + FOR_EACH_INSN_INFO_EQ_USE (use, insn_info) + if (!check_dependency (bb, use, depends_on)) return false; return true; @@ -909,19 +909,17 @@ static void record_uses (rtx insn) { struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); - df_ref *use_rec; + df_ref use; struct invariant *inv; - for (use_rec = DF_INSN_INFO_USES (insn_info); *use_rec; use_rec++) + FOR_EACH_INSN_INFO_USE (use, insn_info) { - df_ref use = *use_rec; inv = invariant_for_use (use); if (inv) record_use (inv->def, use); } - for (use_rec = DF_INSN_INFO_EQ_USES (insn_info); *use_rec; use_rec++) + FOR_EACH_INSN_INFO_EQ_USE (use, insn_info) { - df_ref use = *use_rec; inv = invariant_for_use (use); if (inv) record_use (inv->def, use); diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c index 03c2506d826..83795bac49a 100644 --- a/gcc/lra-assigns.c +++ b/gcc/lra-assigns.c @@ -1420,6 +1420,32 @@ assign_by_spills (void) alternatives of insns containing the pseudo. */ bitmap_set_bit (&changed_pseudo_bitmap, regno); } + else + { + enum reg_class rclass = lra_get_allocno_class (regno); + enum reg_class spill_class; + + if (targetm.spill_class == NULL + || lra_reg_info[regno].restore_regno < 0 + || ! bitmap_bit_p (&lra_inheritance_pseudos, regno) + || (spill_class + = ((enum reg_class) + targetm.spill_class + ((reg_class_t) rclass, + PSEUDO_REGNO_MODE (regno)))) == NO_REGS) + continue; + regno_allocno_class_array[regno] = spill_class; + hard_regno = find_hard_regno_for (regno, &cost, -1, false); + if (hard_regno < 0) + regno_allocno_class_array[regno] = rclass; + else + { + setup_reg_classes + (regno, spill_class, spill_class, spill_class); + assign_hard_regno (hard_regno, regno); + bitmap_set_bit (&changed_pseudo_bitmap, regno); + } + } } } free (update_hard_regno_preference_check); diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 08716fe698a..b1904e1bf65 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -394,40 +394,38 @@ valid_address_p (struct address_info *ad) return valid_address_p (ad->mode, *ad->outer, ad->as); } -#ifdef EXTRA_CONSTRAINT_STR /* Return true if the eliminated form of memory reference OP satisfies extra memory constraint CONSTRAINT. */ static bool -satisfies_memory_constraint_p (rtx op, const char *constraint) +satisfies_memory_constraint_p (rtx op, enum constraint_num constraint) { struct address_info ad; decompose_mem_address (&ad, op); address_eliminator eliminator (&ad); - return EXTRA_CONSTRAINT_STR (op, *constraint, constraint); + return constraint_satisfied_p (op, constraint); } /* Return true if the eliminated form of address AD satisfies extra address constraint CONSTRAINT. */ static bool satisfies_address_constraint_p (struct address_info *ad, - const char *constraint) + enum constraint_num constraint) { address_eliminator eliminator (ad); - return EXTRA_CONSTRAINT_STR (*ad->outer, *constraint, constraint); + return constraint_satisfied_p (*ad->outer, constraint); } /* Return true if the eliminated form of address OP satisfies extra address constraint CONSTRAINT. */ static bool -satisfies_address_constraint_p (rtx op, const char *constraint) +satisfies_address_constraint_p (rtx op, enum constraint_num constraint) { struct address_info ad; decompose_lea_address (&ad, &op); return satisfies_address_constraint_p (&ad, constraint); } -#endif /* Initiate equivalences for LRA. As we keep original equivalences before any elimination, we need to make copies otherwise any change @@ -970,33 +968,25 @@ reg_class_from_constraints (const char *p) case ',': return op_class; - case 'p': - op_class = (reg_class_subunion - [op_class][base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, - ADDRESS, SCRATCH)]); - break; - case 'g': - case 'r': op_class = reg_class_subunion[op_class][GENERAL_REGS]; break; default: - if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS) + enum constraint_num cn = lookup_constraint (p); + enum reg_class cl = reg_class_for_constraint (cn); + if (cl == NO_REGS) { -#ifdef EXTRA_CONSTRAINT_STR - if (EXTRA_ADDRESS_CONSTRAINT (c, p)) + if (insn_extra_address_constraint (cn)) op_class = (reg_class_subunion [op_class][base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH)]); -#endif break; } - op_class - = reg_class_subunion[op_class][REG_CLASS_FROM_CONSTRAINT (c, p)]; - break; + op_class = reg_class_subunion[op_class][cl]; + break; } while ((p += len), c); return op_class; @@ -1343,6 +1333,8 @@ insert_move_for_subreg (rtx *before, rtx *after, rtx origreg, rtx newreg) } } +static int valid_address_p (enum machine_mode mode, rtx addr, addr_space_t as); + /* Make reloads for subreg in operand NOP with internal subreg mode REG_MODE, add new reloads for further processing. Return true if any reload was generated. */ @@ -1373,10 +1365,26 @@ simplify_operand_subreg (int nop, enum machine_mode reg_mode) equivalences in function lra_constraints) and because for spilled pseudos we allocate stack memory enough for the biggest corresponding paradoxical subreg. */ - if ((MEM_P (reg) - && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (reg)) - || MEM_ALIGN (reg) >= GET_MODE_ALIGNMENT (mode))) - || (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER)) + if (MEM_P (reg) + && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (reg)) + || MEM_ALIGN (reg) >= GET_MODE_ALIGNMENT (mode))) + { + rtx subst, old = *curr_id->operand_loc[nop]; + + alter_subreg (curr_id->operand_loc[nop], false); + subst = *curr_id->operand_loc[nop]; + lra_assert (MEM_P (subst)); + if (! valid_address_p (GET_MODE (reg), XEXP (reg, 0), + MEM_ADDR_SPACE (reg)) + || valid_address_p (GET_MODE (subst), XEXP (subst, 0), + MEM_ADDR_SPACE (subst))) + return true; + /* If the address was valid and became invalid, prefer to reload + the memory. Typical case is when the index scale should + correspond the memory. */ + *curr_id->operand_loc[nop] = old; + } + else if (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER) { alter_subreg (curr_id->operand_loc[nop], false); return true; @@ -1712,6 +1720,7 @@ process_alt_operands (int only_alternative) bool this_alternative_offmemok; bool scratch_p; enum machine_mode mode; + enum constraint_num cn; opalt_num = nalt * n_operands + nop; if (curr_static_id->operand_alternative[opalt_num].anything_ok) @@ -1770,15 +1779,6 @@ process_alt_operands (int only_alternative) c = '\0'; break; - case '=': case '+': case '?': case '*': case '!': - case ' ': case '\t': - break; - - case '%': - /* We only support one commutative marker, the first - one. We already set commutative above. */ - break; - case '&': early_clobber_p = true; break; @@ -1911,195 +1911,66 @@ process_alt_operands (int only_alternative) break; } - case 'p': - cl = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, - ADDRESS, SCRATCH); - this_alternative = reg_class_subunion[this_alternative][cl]; - IOR_HARD_REG_SET (this_alternative_set, - reg_class_contents[cl]); - if (costly_p) - { - this_costly_alternative - = reg_class_subunion[this_costly_alternative][cl]; - IOR_HARD_REG_SET (this_costly_alternative_set, - reg_class_contents[cl]); - } - win = true; - badop = false; - break; - - case TARGET_MEM_CONSTRAINT: - if (MEM_P (op) || spilled_pseudo_p (op)) - win = true; - /* We can put constant or pseudo value into memory - to satisfy the constraint. */ - if (CONST_POOL_OK_P (mode, op) || REG_P (op)) - badop = false; - constmemok = true; - break; - - case '<': - if (MEM_P (op) - && (GET_CODE (XEXP (op, 0)) == PRE_DEC - || GET_CODE (XEXP (op, 0)) == POST_DEC)) - win = true; - break; - - case '>': - if (MEM_P (op) - && (GET_CODE (XEXP (op, 0)) == PRE_INC - || GET_CODE (XEXP (op, 0)) == POST_INC)) - win = true; - break; - - /* Memory op whose address is not offsettable. */ - case 'V': - if (MEM_P (op) - && ! offsettable_nonstrict_memref_p (op)) - win = true; - break; - - /* Memory operand whose address is offsettable. */ - case 'o': - if ((MEM_P (op) - && offsettable_nonstrict_memref_p (op)) - || spilled_pseudo_p (op)) - win = true; - /* We can put constant or pseudo value into memory - or make memory address offsetable to satisfy the - constraint. */ - if (CONST_POOL_OK_P (mode, op) || MEM_P (op) || REG_P (op)) - badop = false; - constmemok = true; - offmemok = true; - break; - - case 'E': - case 'F': - if (GET_CODE (op) == CONST_DOUBLE - || (GET_CODE (op) == CONST_VECTOR - && (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT))) - win = true; - break; - - case 'G': - case 'H': - if (CONST_DOUBLE_AS_FLOAT_P (op) - && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, p)) - win = true; - break; - - case 's': - if (CONST_SCALAR_INT_P (op)) - break; - - case 'i': - if (general_constant_p (op)) - win = true; - break; - - case 'n': - if (CONST_SCALAR_INT_P (op)) - win = true; - break; - - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - if (CONST_INT_P (op) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, p)) - win = true; - break; - - case 'X': - /* This constraint should be excluded by the fast - track. */ - gcc_unreachable (); - break; - case 'g': if (MEM_P (op) || general_constant_p (op) || spilled_pseudo_p (op)) win = true; - /* Drop through into 'r' case. */ - - case 'r': - this_alternative - = reg_class_subunion[this_alternative][GENERAL_REGS]; - IOR_HARD_REG_SET (this_alternative_set, - reg_class_contents[GENERAL_REGS]); - if (costly_p) - { - this_costly_alternative - = (reg_class_subunion - [this_costly_alternative][GENERAL_REGS]); - IOR_HARD_REG_SET (this_costly_alternative_set, - reg_class_contents[GENERAL_REGS]); - } + cl = GENERAL_REGS; goto reg; default: - if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS) + cn = lookup_constraint (p); + switch (get_constraint_type (cn)) { -#ifdef EXTRA_CONSTRAINT_STR - if (EXTRA_MEMORY_CONSTRAINT (c, p)) - { - if (MEM_P (op) - && satisfies_memory_constraint_p (op, p)) - win = true; - else if (spilled_pseudo_p (op)) - win = true; - - /* If we didn't already win, we can reload - constants via force_const_mem or put the - pseudo value into memory, or make other - memory by reloading the address like for - 'o'. */ - if (CONST_POOL_OK_P (mode, op) - || MEM_P (op) || REG_P (op)) - badop = false; - constmemok = true; - offmemok = true; - break; - } - if (EXTRA_ADDRESS_CONSTRAINT (c, p)) - { - if (satisfies_address_constraint_p (op, p)) - win = true; - - /* If we didn't already win, we can reload - the address into a base register. */ - cl = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, - ADDRESS, SCRATCH); - this_alternative - = reg_class_subunion[this_alternative][cl]; - IOR_HARD_REG_SET (this_alternative_set, - reg_class_contents[cl]); - if (costly_p) - { - this_costly_alternative - = (reg_class_subunion - [this_costly_alternative][cl]); - IOR_HARD_REG_SET (this_costly_alternative_set, - reg_class_contents[cl]); - } - badop = false; - break; - } + case CT_REGISTER: + cl = reg_class_for_constraint (cn); + if (cl != NO_REGS) + goto reg; + break; - if (EXTRA_CONSTRAINT_STR (op, c, p)) + case CT_CONST_INT: + if (CONST_INT_P (op) + && insn_const_int_ok_for_constraint (INTVAL (op), cn)) + win = true; + break; + + case CT_MEMORY: + if (MEM_P (op) + && satisfies_memory_constraint_p (op, cn)) + win = true; + else if (spilled_pseudo_p (op)) + win = true; + + /* If we didn't already win, we can reload constants + via force_const_mem or put the pseudo value into + memory, or make other memory by reloading the + address like for 'o'. */ + if (CONST_POOL_OK_P (mode, op) + || MEM_P (op) || REG_P (op)) + badop = false; + constmemok = true; + offmemok = true; + break; + + case CT_ADDRESS: + /* If we didn't already win, we can reload the address + into a base register. */ + if (satisfies_address_constraint_p (op, cn)) + win = true; + cl = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH); + badop = false; + goto reg; + + case CT_FIXED_FORM: + if (constraint_satisfied_p (op, cn)) win = true; -#endif break; } + break; - cl = REG_CLASS_FROM_CONSTRAINT (c, p); + reg: this_alternative = reg_class_subunion[this_alternative][cl]; IOR_HARD_REG_SET (this_alternative_set, reg_class_contents[cl]); @@ -2110,7 +1981,6 @@ process_alt_operands (int only_alternative) IOR_HARD_REG_SET (this_costly_alternative_set, reg_class_contents[cl]); } - reg: if (mode == BLKmode) break; winreg = true; @@ -2856,10 +2726,10 @@ process_address_1 (int nop, rtx *before, rtx *after) rtx new_reg; rtx op = *curr_id->operand_loc[nop]; const char *constraint = curr_static_id->operand[nop].constraint; + enum constraint_num cn = lookup_constraint (constraint); bool change_p; - if (constraint[0] == 'p' - || EXTRA_ADDRESS_CONSTRAINT (constraint[0], constraint)) + if (insn_extra_address_constraint (cn)) decompose_lea_address (&ad, curr_id->operand_loc[nop]); else if (MEM_P (op)) decompose_mem_address (&ad, op); @@ -2888,14 +2758,11 @@ process_address_1 (int nop, rtx *before, rtx *after) && process_addr_reg (ad.index_term, before, NULL, INDEX_REG_CLASS)) change_p = true; -#ifdef EXTRA_CONSTRAINT_STR - /* Target hooks sometimes reject extra constraint addresses -- use - EXTRA_CONSTRAINT_STR for the validation. */ - if (constraint[0] != 'p' - && EXTRA_ADDRESS_CONSTRAINT (constraint[0], constraint) - && satisfies_address_constraint_p (&ad, constraint)) + /* Target hooks sometimes don't treat extra-constraint addresses as + legitimate address_operands, so handle them specially. */ + if (insn_extra_address_constraint (cn) + && satisfies_address_constraint_p (&ad, cn)) return change_p; -#endif /* There are three cases where the shape of *AD.INNER may now be invalid: @@ -3615,13 +3482,10 @@ curr_insn_transform (void) (c = *constraint) && c != ',' && c != '#'; constraint += CONSTRAINT_LEN (c, constraint)) { - if (c == TARGET_MEM_CONSTRAINT || c == 'o') - break; -#ifdef EXTRA_CONSTRAINT_STR - if (EXTRA_MEMORY_CONSTRAINT (c, constraint) - && satisfies_memory_constraint_p (tem, constraint)) + enum constraint_num cn = lookup_constraint (constraint); + if (insn_extra_memory_constraint (cn) + && satisfies_memory_constraint_p (tem, cn)) break; -#endif } if (c == '\0' || c == ',' || c == '#') continue; diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index 26ba0d259c0..1e7bb59678e 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -558,7 +558,11 @@ process_bb_lives (basic_block bb, int &curr_point) /* It might be 'inheritance pseudo <- reload pseudo'. */ || (src_regno >= lra_constraint_new_regno_start && ((int) REGNO (SET_DEST (set)) - >= lra_constraint_new_regno_start)))) + >= lra_constraint_new_regno_start) + /* Remember to skip special cases where src/dest regnos are + the same, e.g. insn SET pattern has matching constraints + like =r,0. */ + && src_regno != (int) REGNO (SET_DEST (set))))) { int hard_regno = -1, regno = -1; diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index a19197ded53..6c6896cb0f8 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -501,12 +501,9 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, streamer_write_hwi_stream (ob->main_stream, ref); } - group = node->get_section (); - if (group) - section = TREE_STRING_POINTER (group); - else + section = node->get_section (); + if (!section) section = ""; - lto_output_data_stream (ob->main_stream, section, strlen (section) + 1); streamer_write_hwi_stream (ob->main_stream, node->tp_first_run); @@ -521,6 +518,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, bp_pack_value (&bp, node->forced_by_abi, 1); bp_pack_value (&bp, node->unique_name, 1); bp_pack_value (&bp, node->body_removed, 1); + bp_pack_value (&bp, node->implicit_section, 1); bp_pack_value (&bp, node->address_taken, 1); bp_pack_value (&bp, tag == LTO_symtab_analyzed_node && symtab_get_symbol_partitioning_class (node) == SYMBOL_PARTITION @@ -547,6 +545,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, bp_pack_enum (&bp, ld_plugin_symbol_resolution, LDPR_NUM_KNOWN, node->resolution); streamer_write_bitpack (&bp); + lto_output_data_stream (ob->main_stream, section, strlen (section) + 1); if (node->thunk.thunk_p && !boundary_p) { @@ -585,6 +584,7 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node, bp_pack_value (&bp, node->forced_by_abi, 1); bp_pack_value (&bp, node->unique_name, 1); bp_pack_value (&bp, node->body_removed, 1); + bp_pack_value (&bp, node->implicit_section, 1); bp_pack_value (&bp, node->writeonly, 1); bp_pack_value (&bp, node->definition, 1); alias_p = node->alias && (!boundary_p || node->weakref); @@ -609,6 +609,7 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node, && boundary_p && !DECL_EXTERNAL (node->decl), 1); /* in_other_partition. */ } + bp_pack_value (&bp, node->tls_model, 3); streamer_write_bitpack (&bp); group = node->get_comdat_group (); @@ -631,10 +632,8 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node, streamer_write_hwi_stream (ob->main_stream, ref); } - group = node->get_section (); - if (group) - section = TREE_STRING_POINTER (group); - else + section = node->get_section (); + if (!section) section = ""; lto_output_data_stream (ob->main_stream, section, strlen (section) + 1); @@ -1008,13 +1007,13 @@ read_identifier (struct lto_input_block *ib) return id; } -/* Return identifier encoded in IB as a plain string. */ +/* Return string encoded in IB, NULL if string is empty. */ -static tree -read_string_cst (struct lto_input_block *ib) +static const char * +read_string (struct lto_input_block *ib) { unsigned int len = strnlen (ib->data + ib->p, ib->len - ib->p - 1); - tree id; + const char *str; if (ib->data[ib->p + len]) lto_section_overrun (ib); @@ -1023,9 +1022,9 @@ read_string_cst (struct lto_input_block *ib) ib->p++; return NULL; } - id = build_string (len, ib->data + ib->p); + str = ib->data + ib->p; ib->p += len + 1; - return id; + return str; } /* Overwrite the information in NODE based on FILE_DATA, TAG, FLAGS, @@ -1054,6 +1053,7 @@ input_overwrite_node (struct lto_file_decl_data *file_data, node->forced_by_abi = bp_unpack_value (bp, 1); node->unique_name = bp_unpack_value (bp, 1); node->body_removed = bp_unpack_value (bp, 1); + node->implicit_section = bp_unpack_value (bp, 1); node->address_taken = bp_unpack_value (bp, 1); node->used_from_other_partition = bp_unpack_value (bp, 1); node->lowered = bp_unpack_value (bp, 1); @@ -1117,7 +1117,7 @@ input_node (struct lto_file_decl_data *file_data, int order; int i, count; tree group; - tree section; + const char *section; order = streamer_read_hwi (ib) + order_base; clone_ref = streamer_read_hwi (ib); @@ -1166,7 +1166,6 @@ input_node (struct lto_file_decl_data *file_data, group = read_identifier (ib); if (group) ref2 = streamer_read_hwi (ib); - section = read_string_cst (ib); /* Make sure that we have not read this node before. Nodes that have already been read will have their tag stored in the 'aux' @@ -1193,8 +1192,9 @@ input_node (struct lto_file_decl_data *file_data, } else node->same_comdat_group = (symtab_node *) (intptr_t) LCC_NOT_FOUND; + section = read_string (ib); if (section) - node->set_section (section); + node->set_section_for_node (section); if (node->thunk.thunk_p) { @@ -1227,7 +1227,7 @@ input_varpool_node (struct lto_file_decl_data *file_data, int ref = LCC_NOT_FOUND; int order; tree group; - tree section; + const char *section; order = streamer_read_hwi (ib) + order_base; decl_index = streamer_read_uhwi (ib); @@ -1251,6 +1251,7 @@ input_varpool_node (struct lto_file_decl_data *file_data, node->forced_by_abi = bp_unpack_value (&bp, 1); node->unique_name = bp_unpack_value (&bp, 1); node->body_removed = bp_unpack_value (&bp, 1); + node->implicit_section = bp_unpack_value (&bp, 1); node->writeonly = bp_unpack_value (&bp, 1); node->definition = bp_unpack_value (&bp, 1); node->alias = bp_unpack_value (&bp, 1); @@ -1265,6 +1266,7 @@ input_varpool_node (struct lto_file_decl_data *file_data, } if (node->alias && !node->analyzed && node->weakref) node->alias_target = get_alias_symbol (node->decl); + node->tls_model = (enum tls_model)bp_unpack_value (&bp, 3); group = read_identifier (ib); if (group) { @@ -1275,9 +1277,9 @@ input_varpool_node (struct lto_file_decl_data *file_data, } else node->same_comdat_group = (symtab_node *) (intptr_t) LCC_NOT_FOUND; - section = read_string_cst (ib); + section = read_string (ib); if (section) - node->set_section (section); + node->set_section_for_node (section); node->resolution = streamer_read_enum (ib, ld_plugin_symbol_resolution, LDPR_NUM_KNOWN); gcc_assert (flag_ltrans diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index ece0d3f1458..14d3623a1be 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -821,7 +821,6 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t) v = iterative_hash_host_wide_int (DECL_HARD_REGISTER (t) | (DECL_IN_CONSTANT_POOL (t) << 1), v); - v = iterative_hash_host_wide_int (DECL_TLS_MODEL (t), v); } if (TREE_CODE (t) == FUNCTION_DECL) v = iterative_hash_host_wide_int (DECL_FINAL_P (t) diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 3edd6bab91f..9c45cc6071c 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,12 @@ +2014-06-15 Jan Hubicka <hubicka@ucw.cz> + + * lto.c (compare_tree_sccs_1): Do not compare DECL_TLS_MODEL. + +2014-06-10 Jan Hubicka <hubicka@ucw.cz> + + * lto.c (read_cgraph_and_symbols): Remove unreachable symbols. + (do_whole_program_analysis): Use verify_symtab. + 2014-06-07 Jan Hubicka <hubicka@ucw.cz> * lto.c (mentions_vars_p_decl_with_vis, compare_tree_sccs_1, diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 9db7845889e..015eaf0c1a0 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -1299,7 +1299,6 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map) compare_values (DECL_HARD_REGISTER); /* DECL_IN_TEXT_SECTION is set during final asm output only. */ compare_values (DECL_IN_CONSTANT_POOL); - compare_values (DECL_TLS_MODEL); } if (VAR_OR_FUNCTION_DECL_P (t1)) compare_values (DECL_INIT_PRIORITY); @@ -3090,6 +3089,10 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames) dump_symtab (cgraph_dump_file); } lto_symtab_merge_symbols (); + /* Removal of unreacable symbols is needed to make verify_symtab to pass; + we are still having duplicated comdat groups containing local statics. + We could also just remove them while merging. */ + symtab_remove_unreachable_nodes (false, dump_file); ggc_collect (); cgraph_state = CGRAPH_STATE_IPA_SSA; @@ -3261,7 +3264,7 @@ do_whole_program_analysis (void) dump_symtab (cgraph_dump_file); } #ifdef ENABLE_CHECKING - verify_cgraph (); + verify_symtab (); #endif bitmap_obstack_release (NULL); diff --git a/gcc/omp-low.c b/gcc/omp-low.c index ddb049d3ea1..67254cc5bdf 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -1509,11 +1509,19 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) break; case OMP_CLAUSE_SHARED: + decl = OMP_CLAUSE_DECL (c); /* Ignore shared directives in teams construct. */ if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS) - break; + { + /* Global variables don't need to be copied, + the receiver side will use them directly. */ + tree odecl = maybe_lookup_decl_in_outer_ctx (decl, ctx); + if (is_global_var (odecl)) + break; + insert_decl_map (&ctx->cb, decl, odecl); + break; + } gcc_assert (is_taskreg_ctx (ctx)); - decl = OMP_CLAUSE_DECL (c); gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl)) || !is_variable_sized (decl)); /* Global variables don't need to be copied, diff --git a/gcc/params.def b/gcc/params.def index c3a8797f26b..28ef79a0650 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -1090,6 +1090,12 @@ DEFPARAM (PARAM_ASAN_USE_AFTER_RETURN, "Enable asan builtin functions protection", 1, 0, 1) +DEFPARAM (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD, + "asan-instrumentation-with-call-threshold", + "Use callbacks instead of inline code once number of accesses " + " in function becomes greater or equal than this threshold", + 10000, 0, INT_MAX) + DEFPARAM (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS, "uninit-control-dep-attempts", "Maximum number of nested calls to search for control dependencies " diff --git a/gcc/params.h b/gcc/params.h index 0d6daa205c0..d488e32ebfe 100644 --- a/gcc/params.h +++ b/gcc/params.h @@ -232,5 +232,7 @@ extern void init_param_values (int *params); PARAM_VALUE (PARAM_ASAN_MEMINTRIN) #define ASAN_USE_AFTER_RETURN \ PARAM_VALUE (PARAM_ASAN_USE_AFTER_RETURN) +#define ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD \ + PARAM_VALUE (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD) #endif /* ! GCC_PARAMS_H */ diff --git a/gcc/passes.def b/gcc/passes.def index f9e0b2a821c..f305c608c1d 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -73,7 +73,6 @@ along with GCC; see the file COPYING3. If not see execute TODO_rebuild_alias at this point. */ NEXT_PASS (pass_build_ealias); NEXT_PASS (pass_fre); - NEXT_PASS (pass_copy_prop); NEXT_PASS (pass_merge_phi); NEXT_PASS (pass_cd_dce); NEXT_PASS (pass_early_ipa_sra); @@ -149,12 +148,12 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_build_alias); NEXT_PASS (pass_return_slot); NEXT_PASS (pass_fre); - NEXT_PASS (pass_copy_prop); NEXT_PASS (pass_merge_phi); NEXT_PASS (pass_vrp); NEXT_PASS (pass_dce); NEXT_PASS (pass_call_cdce); NEXT_PASS (pass_cselim); + NEXT_PASS (pass_copy_prop); NEXT_PASS (pass_tree_ifcombine); NEXT_PASS (pass_phiopt); NEXT_PASS (pass_tail_recursion); diff --git a/gcc/postreload.c b/gcc/postreload.c index 29ba81b41d5..9d716498be4 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -553,29 +553,15 @@ reload_cse_simplify_operands (rtx insn, rtx testreg) switch (c) { - case '=': case '+': case '?': - case '#': case '&': case '!': - case '*': case '%': - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '<': case '>': case 'V': case 'o': - case 'E': case 'F': case 'G': case 'H': - case 's': case 'i': case 'n': - case 'I': case 'J': case 'K': case 'L': - case 'M': case 'N': case 'O': case 'P': - case 'p': case 'X': case TARGET_MEM_CONSTRAINT: - /* These don't say anything we care about. */ - break; - - case 'g': case 'r': - rclass = reg_class_subunion[(int) rclass][(int) GENERAL_REGS]; + case 'g': + rclass = reg_class_subunion[rclass][GENERAL_REGS]; break; default: rclass = (reg_class_subunion - [(int) rclass] - [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]); + [rclass] + [reg_class_for_constraint (lookup_constraint (p))]); break; case ',': case '\0': diff --git a/gcc/recog.c b/gcc/recog.c index 0a5d82e1a80..21bce78f8a0 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -1729,6 +1729,7 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints) while (*constraint) { + enum constraint_num cn; char c = *constraint; int len; switch (c) @@ -1736,15 +1737,6 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints) case ',': constraint++; continue; - case '=': - case '+': - case '*': - case '%': - case '!': - case '#': - case '&': - case '?': - break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': @@ -1773,156 +1765,70 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints) } continue; - case 'p': - if (address_operand (op, VOIDmode)) - result = 1; - break; - - case TARGET_MEM_CONSTRAINT: - case 'V': /* non-offsettable */ - if (memory_operand (op, VOIDmode)) - result = 1; - break; + /* The rest of the compiler assumes that reloading the address + of a MEM into a register will make it fit an 'o' constraint. + That is, if it sees a MEM operand for an 'o' constraint, + it assumes that (mem (base-reg)) will fit. + That assumption fails on targets that don't have offsettable + addresses at all. We therefore need to treat 'o' asm + constraints as a special case and only accept operands that + are already offsettable, thus proving that at least one + offsettable address exists. */ case 'o': /* offsettable */ if (offsettable_nonstrict_memref_p (op)) result = 1; break; - case '<': - /* ??? Before auto-inc-dec, auto inc/dec insns are not supposed to exist, - excepting those that expand_call created. Further, on some - machines which do not have generalized auto inc/dec, an inc/dec - is not a memory_operand. - - Match any memory and hope things are resolved after reload. */ - - if (MEM_P (op) - && (1 - || GET_CODE (XEXP (op, 0)) == PRE_DEC - || GET_CODE (XEXP (op, 0)) == POST_DEC)) + case 'g': + if (general_operand (op, VOIDmode)) result = 1; -#ifdef AUTO_INC_DEC - incdec_ok = true; -#endif break; - case '>': - if (MEM_P (op) - && (1 - || GET_CODE (XEXP (op, 0)) == PRE_INC - || GET_CODE (XEXP (op, 0)) == POST_INC)) - result = 1; #ifdef AUTO_INC_DEC + case '<': + case '>': + /* ??? Before auto-inc-dec, auto inc/dec insns are not supposed + to exist, excepting those that expand_call created. Further, + on some machines which do not have generalized auto inc/dec, + an inc/dec is not a memory_operand. + + Match any memory and hope things are resolved after reload. */ incdec_ok = true; #endif - break; - - case 'E': - case 'F': - if (CONST_DOUBLE_AS_FLOAT_P (op) - || (GET_CODE (op) == CONST_VECTOR - && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT)) - result = 1; - break; - - case 'G': - if (CONST_DOUBLE_AS_FLOAT_P (op) - && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, 'G', constraint)) - result = 1; - break; - case 'H': - if (CONST_DOUBLE_AS_FLOAT_P (op) - && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, 'H', constraint)) - result = 1; - break; - - case 's': - if (CONST_SCALAR_INT_P (op)) - break; - /* Fall through. */ - - case 'i': - if (CONSTANT_P (op) && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))) - result = 1; - break; - - case 'n': - if (CONST_SCALAR_INT_P (op)) - result = 1; - break; + default: + cn = lookup_constraint (constraint); + switch (get_constraint_type (cn)) + { + case CT_REGISTER: + if (!result + && reg_class_for_constraint (cn) != NO_REGS + && GET_MODE (op) != BLKmode + && register_operand (op, VOIDmode)) + result = 1; + break; - case 'I': - if (CONST_INT_P (op) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'I', constraint)) - result = 1; - break; - case 'J': - if (CONST_INT_P (op) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'J', constraint)) - result = 1; - break; - case 'K': - if (CONST_INT_P (op) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'K', constraint)) - result = 1; - break; - case 'L': - if (CONST_INT_P (op) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'L', constraint)) - result = 1; - break; - case 'M': - if (CONST_INT_P (op) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'M', constraint)) - result = 1; - break; - case 'N': - if (CONST_INT_P (op) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'N', constraint)) - result = 1; - break; - case 'O': - if (CONST_INT_P (op) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'O', constraint)) - result = 1; - break; - case 'P': - if (CONST_INT_P (op) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'P', constraint)) - result = 1; - break; + case CT_CONST_INT: + if (!result + && CONST_INT_P (op) + && insn_const_int_ok_for_constraint (INTVAL (op), cn)) + result = 1; + break; - case 'X': - result = 1; - break; + case CT_MEMORY: + /* Every memory operand can be reloaded to fit. */ + result = result || memory_operand (op, VOIDmode); + break; - case 'g': - if (general_operand (op, VOIDmode)) - result = 1; - break; + case CT_ADDRESS: + /* Every address operand can be reloaded to fit. */ + result = result || address_operand (op, VOIDmode); + break; - default: - /* For all other letters, we first check for a register class, - otherwise it is an EXTRA_CONSTRAINT. */ - if (REG_CLASS_FROM_CONSTRAINT (c, constraint) != NO_REGS) - { - case 'r': - if (GET_MODE (op) == BLKmode) - break; - if (register_operand (op, VOIDmode)) - result = 1; + case CT_FIXED_FORM: + result = result || constraint_satisfied_p (op, cn); + break; } -#ifdef EXTRA_CONSTRAINT_STR - else if (EXTRA_MEMORY_CONSTRAINT (c, constraint)) - /* Every memory operand can be reloaded to fit. */ - result = result || memory_operand (op, VOIDmode); - else if (EXTRA_ADDRESS_CONSTRAINT (c, constraint)) - /* Every address operand can be reloaded to fit. */ - result = result || address_operand (op, VOIDmode); - else if (EXTRA_CONSTRAINT_STR (op, c, constraint)) - result = 1; -#endif break; } len = CONSTRAINT_LEN (c, constraint); @@ -2373,14 +2279,6 @@ preprocess_constraints (int n_operands, int n_alternatives, switch (c) { - case '=': case '+': case '*': case '%': - case 'E': case 'F': case 'G': case 'H': - case 's': case 'i': case 'n': - case 'I': case 'J': case 'K': case 'L': - case 'M': case 'N': case 'O': case 'P': - /* These don't say anything we care about. */ - break; - case '?': op_alt[i].reject += 6; break; @@ -2401,46 +2299,34 @@ preprocess_constraints (int n_operands, int n_alternatives, } continue; - case TARGET_MEM_CONSTRAINT: - op_alt[i].memory_ok = 1; - break; - case '<': - op_alt[i].decmem_ok = 1; - break; - case '>': - op_alt[i].incmem_ok = 1; - break; - case 'V': - op_alt[i].nonoffmem_ok = 1; - break; - case 'o': - op_alt[i].offmem_ok = 1; - break; case 'X': op_alt[i].anything_ok = 1; break; - case 'p': - op_alt[i].is_address = 1; - op_alt[i].cl = reg_class_subunion[(int) op_alt[i].cl] - [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, - ADDRESS, SCRATCH)]; - break; - case 'g': - case 'r': op_alt[i].cl = reg_class_subunion[(int) op_alt[i].cl][(int) GENERAL_REGS]; break; default: - if (EXTRA_MEMORY_CONSTRAINT (c, p)) + enum constraint_num cn = lookup_constraint (p); + enum reg_class cl; + switch (get_constraint_type (cn)) { + case CT_REGISTER: + cl = reg_class_for_constraint (cn); + if (cl != NO_REGS) + op_alt[i].cl = reg_class_subunion[op_alt[i].cl][cl]; + break; + + case CT_CONST_INT: + break; + + case CT_MEMORY: op_alt[i].memory_ok = 1; break; - } - if (EXTRA_ADDRESS_CONSTRAINT (c, p)) - { + + case CT_ADDRESS: op_alt[i].is_address = 1; op_alt[i].cl = (reg_class_subunion @@ -2448,12 +2334,10 @@ preprocess_constraints (int n_operands, int n_alternatives, [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH)]); break; - } - op_alt[i].cl - = (reg_class_subunion - [(int) op_alt[i].cl] - [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]); + case CT_FIXED_FORM: + break; + } break; } p += CONSTRAINT_LEN (c, p); @@ -2629,10 +2513,6 @@ constrain_operands (int strict) c = '\0'; break; - case '?': case '!': case '*': case '%': - case '=': case '+': - break; - case '#': /* Ignore rest of this alternative as far as constraint checking is concerned. */ @@ -2732,123 +2612,10 @@ constrain_operands (int strict) win = 1; break; - case 'X': - /* This is used for a MATCH_SCRATCH in the cases when - we don't actually need anything. So anything goes - any time. */ - win = 1; - break; - - case TARGET_MEM_CONSTRAINT: - /* Memory operands must be valid, to the extent - required by STRICT. */ - if (MEM_P (op)) - { - if (strict > 0 - && !strict_memory_address_addr_space_p - (GET_MODE (op), XEXP (op, 0), - MEM_ADDR_SPACE (op))) - break; - if (strict == 0 - && !memory_address_addr_space_p - (GET_MODE (op), XEXP (op, 0), - MEM_ADDR_SPACE (op))) - break; - win = 1; - } - /* Before reload, accept what reload can turn into mem. */ - else if (strict < 0 && CONSTANT_P (op)) - win = 1; - /* During reload, accept a pseudo */ - else if (reload_in_progress && REG_P (op) - && REGNO (op) >= FIRST_PSEUDO_REGISTER) - win = 1; - break; - - case '<': - if (MEM_P (op) - && (GET_CODE (XEXP (op, 0)) == PRE_DEC - || GET_CODE (XEXP (op, 0)) == POST_DEC)) - win = 1; - break; - - case '>': - if (MEM_P (op) - && (GET_CODE (XEXP (op, 0)) == PRE_INC - || GET_CODE (XEXP (op, 0)) == POST_INC)) - win = 1; - break; - - case 'E': - case 'F': - if (CONST_DOUBLE_AS_FLOAT_P (op) - || (GET_CODE (op) == CONST_VECTOR - && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT)) - win = 1; - break; - - case 'G': - case 'H': - if (CONST_DOUBLE_AS_FLOAT_P (op) - && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, p)) - win = 1; - break; - - case 's': - if (CONST_SCALAR_INT_P (op)) - break; - case 'i': - if (CONSTANT_P (op)) - win = 1; - break; - - case 'n': - if (CONST_SCALAR_INT_P (op)) - win = 1; - break; - - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - if (CONST_INT_P (op) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, p)) - win = 1; - break; - - case 'V': - if (MEM_P (op) - && ((strict > 0 && ! offsettable_memref_p (op)) - || (strict < 0 - && !(CONSTANT_P (op) || MEM_P (op))) - || (reload_in_progress - && !(REG_P (op) - && REGNO (op) >= FIRST_PSEUDO_REGISTER)))) - win = 1; - break; - - case 'o': - if ((strict > 0 && offsettable_memref_p (op)) - || (strict == 0 && offsettable_nonstrict_memref_p (op)) - /* Before reload, accept what reload can handle. */ - || (strict < 0 - && (CONSTANT_P (op) || MEM_P (op))) - /* During reload, accept a pseudo */ - || (reload_in_progress && REG_P (op) - && REGNO (op) >= FIRST_PSEUDO_REGISTER)) - win = 1; - break; - default: { - enum reg_class cl; - - cl = (c == 'r' - ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, p)); + enum constraint_num cn = lookup_constraint (p); + enum reg_class cl = reg_class_for_constraint (cn); if (cl != NO_REGS) { if (strict < 0 @@ -2860,11 +2627,11 @@ constrain_operands (int strict) && reg_fits_class_p (op, cl, offset, mode))) win = 1; } -#ifdef EXTRA_CONSTRAINT_STR - else if (EXTRA_CONSTRAINT_STR (op, c, p)) + + else if (constraint_satisfied_p (op, cn)) win = 1; - else if (EXTRA_MEMORY_CONSTRAINT (c, p) + else if (insn_extra_memory_constraint (cn) /* Every memory operand can be reloaded to fit. */ && ((strict < 0 && MEM_P (op)) /* Before reload, accept what reload can turn @@ -2874,7 +2641,7 @@ constrain_operands (int strict) || (reload_in_progress && REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER))) win = 1; - else if (EXTRA_ADDRESS_CONSTRAINT (c, p) + else if (insn_extra_address_constraint (cn) /* Every address operand can be reloaded to fit. */ && strict < 0) win = 1; @@ -2885,10 +2652,9 @@ constrain_operands (int strict) && REGNO (op) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (op)] < 0 && reg_equiv_mem (REGNO (op)) != 0 - && EXTRA_CONSTRAINT_STR - (reg_equiv_mem (REGNO (op)), c, p)) + && constraint_satisfied_p + (reg_equiv_mem (REGNO (op)), cn)) win = 1; -#endif break; } } @@ -3258,7 +3024,7 @@ peep2_find_free_register (int from, int to, const char *class_str, { enum reg_class cl; HARD_REG_SET live; - df_ref *def_rec; + df_ref def; int i; gcc_assert (from < MAX_INSNS_PER_PEEP2 + 1); @@ -3275,15 +3041,13 @@ peep2_find_free_register (int from, int to, const char *class_str, gcc_assert (peep2_insn_data[from].insn != NULL_RTX); /* Don't use registers set or clobbered by the insn. */ - for (def_rec = DF_INSN_DEFS (peep2_insn_data[from].insn); - *def_rec; def_rec++) - SET_HARD_REG_BIT (live, DF_REF_REGNO (*def_rec)); + FOR_EACH_INSN_DEF (def, peep2_insn_data[from].insn) + SET_HARD_REG_BIT (live, DF_REF_REGNO (def)); from = peep2_buf_position (from + 1); } - cl = (class_str[0] == 'r' ? GENERAL_REGS - : REG_CLASS_FROM_CONSTRAINT (class_str[0], class_str)); + cl = reg_class_for_constraint (lookup_constraint (class_str)); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { diff --git a/gcc/recog.h b/gcc/recog.h index 2017c85a498..3008b1d4dac 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -60,25 +60,17 @@ struct operand_alternative int matched : 8; /* Nonzero if '&' was found in the constraint string. */ - unsigned int earlyclobber:1; + unsigned int earlyclobber : 1; /* Nonzero if TARGET_MEM_CONSTRAINT was found in the constraint string. */ - unsigned int memory_ok:1; - /* Nonzero if 'o' was found in the constraint string. */ - unsigned int offmem_ok:1; - /* Nonzero if 'V' was found in the constraint string. */ - unsigned int nonoffmem_ok:1; - /* Nonzero if '<' was found in the constraint string. */ - unsigned int decmem_ok:1; - /* Nonzero if '>' was found in the constraint string. */ - unsigned int incmem_ok:1; + unsigned int memory_ok : 1; /* Nonzero if 'p' was found in the constraint string. */ - unsigned int is_address:1; + unsigned int is_address : 1; /* Nonzero if 'X' was found in the constraint string, or if the constraint string for this alternative was empty. */ - unsigned int anything_ok:1; + unsigned int anything_ok : 1; - unsigned int unused : 8; + unsigned int unused : 12; }; /* Return the class for operand I of alternative ALT, taking matching diff --git a/gcc/ree.c b/gcc/ree.c index ade413e8bed..f5d521b0ddd 100644 --- a/gcc/ree.c +++ b/gcc/ree.c @@ -431,23 +431,20 @@ transform_ifelse (ext_cand *cand, rtx def_insn) static struct df_link * get_defs (rtx insn, rtx reg, vec<rtx> *dest) { - df_ref reg_info, *uses; + df_ref use; struct df_link *ref_chain, *ref_link; - reg_info = NULL; - - for (uses = DF_INSN_USES (insn); *uses; uses++) + FOR_EACH_INSN_USE (use, insn) { - reg_info = *uses; - if (GET_CODE (DF_REF_REG (reg_info)) == SUBREG) + if (GET_CODE (DF_REF_REG (use)) == SUBREG) return NULL; - if (REGNO (DF_REF_REG (reg_info)) == REGNO (reg)) - break; + if (REGNO (DF_REF_REG (use)) == REGNO (reg)) + break; } - gcc_assert (reg_info != NULL && uses != NULL); + gcc_assert (use != NULL); - ref_chain = DF_REF_CHAIN (reg_info); + ref_chain = DF_REF_CHAIN (use); for (ref_link = ref_chain; ref_link; ref_link = ref_link->next) { @@ -787,13 +784,16 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state) generated more than one insn. This generates garbage since we throw away the insn when we're - done, only to recreate it later if this test was successful. */ + done, only to recreate it later if this test was successful. + + Make sure to get the mode from the extension (cand->insn). This + is different than in the code to emit the copy as we have not + modified the defining insn yet. */ start_sequence (); - rtx sub_rtx = *get_sub_rtx (def_insn); rtx pat = PATTERN (cand->insn); - rtx new_dst = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)), + rtx new_dst = gen_rtx_REG (GET_MODE (SET_DEST (pat)), REGNO (XEXP (SET_SRC (pat), 0))); - rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)), + rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (pat)), REGNO (SET_DEST (pat))); emit_move_insn (new_dst, new_src); diff --git a/gcc/regrename.c b/gcc/regrename.c index 20f0baa62d7..e46da019eb3 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -533,7 +533,7 @@ static void init_rename_info (struct bb_rename_info *p, basic_block bb) { int i; - df_ref *def_rec; + df_ref def; HARD_REG_SET start_chains_set; p->bb = bb; @@ -545,12 +545,9 @@ init_rename_info (struct bb_rename_info *p, basic_block bb) CLEAR_HARD_REG_SET (live_in_chains); REG_SET_TO_HARD_REG_SET (live_hard_regs, df_get_live_in (bb)); - for (def_rec = df_get_artificial_defs (bb->index); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) - SET_HARD_REG_BIT (live_hard_regs, DF_REF_REGNO (def)); - } + FOR_EACH_ARTIFICIAL_DEF (def, bb->index) + if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) + SET_HARD_REG_BIT (live_hard_regs, DF_REF_REGNO (def)); /* Open chains based on information from (at least one) predecessor block. This gives us a chance later on to combine chains across diff --git a/gcc/regstat.c b/gcc/regstat.c index 75d9cb446ba..9dff2680c46 100644 --- a/gcc/regstat.c +++ b/gcc/regstat.c @@ -122,8 +122,7 @@ regstat_bb_compute_ri (unsigned int bb_index, { basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index); rtx insn; - df_ref *def_rec; - df_ref *use_rec; + df_ref def, use; int luid = 0; bitmap_iterator bi; unsigned int regno; @@ -138,29 +137,23 @@ regstat_bb_compute_ri (unsigned int bb_index, /* Process the artificial defs and uses at the bottom of the block to begin processing. */ - for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0) - bitmap_clear_bit (live, DF_REF_REGNO (def)); - } + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) + if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0) + bitmap_clear_bit (live, DF_REF_REGNO (def)); - for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) - { - regno = DF_REF_REGNO (use); - bitmap_set_bit (live, regno); - bitmap_set_bit (artificial_uses, regno); - } - } + FOR_EACH_ARTIFICIAL_USE (use, bb_index) + if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) + { + regno = DF_REF_REGNO (use); + bitmap_set_bit (live, regno); + bitmap_set_bit (artificial_uses, regno); + } FOR_BB_INSNS_REVERSE (bb, insn) { - unsigned int uid = INSN_UID (insn); + struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); bitmap_iterator bi; - struct df_mw_hardreg **mws_rec; + df_mw_hardreg *mw; rtx link; if (!NONDEBUG_INSN_P (insn)) @@ -209,35 +202,31 @@ regstat_bb_compute_ri (unsigned int bb_index, /* We only care about real sets for calls. Clobbers cannot be depended on. Only do this if the value is totally dead. */ - for (mws_rec = DF_INSN_UID_MWS (uid); *mws_rec; mws_rec++) - { - struct df_mw_hardreg *mws = *mws_rec; - if (DF_MWS_REG_DEF_P (mws)) - { - bool all_dead = true; - unsigned int r; - - for (r = mws->start_regno; r <= mws->end_regno; r++) - if (bitmap_bit_p (artificial_uses, r) - || bitmap_bit_p (live, r)) - { - all_dead = false; - break; - } - - if (all_dead) + FOR_EACH_INSN_INFO_MW (mw, insn_info) + if (DF_MWS_REG_DEF_P (mw)) + { + bool all_dead = true; + unsigned int r; + + for (r = mw->start_regno; r <= mw->end_regno; r++) + if (bitmap_bit_p (artificial_uses, r) + || bitmap_bit_p (live, r)) { - regno = mws->start_regno; - REG_LIVE_LENGTH (regno)++; + all_dead = false; + break; } - } - } + + if (all_dead) + { + regno = mw->start_regno; + REG_LIVE_LENGTH (regno)++; + } + } /* All of the defs except the return value are some sort of clobber. This code is for the return. */ - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + FOR_EACH_INSN_INFO_DEF (def, insn_info) { - df_ref def = *def_rec; if ((!CALL_P (insn)) || (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))) { @@ -301,9 +290,8 @@ regstat_bb_compute_ri (unsigned int bb_index, } } - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) + FOR_EACH_INSN_INFO_USE (use, insn_info) { - df_ref use = *use_rec; unsigned int uregno = DF_REF_REGNO (use); if (uregno >= FIRST_PSEUDO_REGISTER) @@ -442,30 +430,23 @@ regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live) { basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index); rtx insn; - df_ref *def_rec; - df_ref *use_rec; + df_ref def, use; bitmap_copy (live, df_get_live_out (bb)); /* Process the artificial defs and uses at the bottom of the block to begin processing. */ - for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0) - bitmap_clear_bit (live, DF_REF_REGNO (def)); - } + FOR_EACH_ARTIFICIAL_DEF (def, bb_index) + if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0) + bitmap_clear_bit (live, DF_REF_REGNO (def)); - for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) - bitmap_set_bit (live, DF_REF_REGNO (use)); - } + FOR_EACH_ARTIFICIAL_USE (use, bb_index) + if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) + bitmap_set_bit (live, DF_REF_REGNO (use)); FOR_BB_INSNS_REVERSE (bb, insn) { - unsigned int uid = INSN_UID (insn); + struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); unsigned int regno; if (!INSN_P (insn)) @@ -486,9 +467,8 @@ regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live) /* All of the defs except the return value are some sort of clobber. This code is for the return. */ - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) + FOR_EACH_INSN_INFO_DEF (def, insn_info) { - df_ref def = *def_rec; if ((!CALL_P (insn)) || (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))) { @@ -498,11 +478,8 @@ regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live) } } - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) - { - df_ref use = *use_rec; - bitmap_set_bit (live, DF_REF_REGNO (use)); - } + FOR_EACH_INSN_INFO_USE (use, insn_info) + bitmap_set_bit (live, DF_REF_REGNO (use)); } } diff --git a/gcc/reload.c b/gcc/reload.c index 87c453c85b8..e55968e4882 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -328,7 +328,6 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional, enum reload_type secondary_type; int s_reload, t_reload = -1; const char *scratch_constraint; - char letter; secondary_reload_info sri; if (type == RELOAD_FOR_INPUT_ADDRESS @@ -399,10 +398,8 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional, scratch_constraint++; if (*scratch_constraint == '&') scratch_constraint++; - letter = *scratch_constraint; - scratch_class = (letter == 'r' ? GENERAL_REGS - : REG_CLASS_FROM_CONSTRAINT ((unsigned char) letter, - scratch_constraint)); + scratch_class = (reg_class_for_constraint + (lookup_constraint (scratch_constraint))); rclass = scratch_class; mode = insn_data[(int) icode].operand[2].mode; @@ -548,7 +545,6 @@ enum reg_class scratch_reload_class (enum insn_code icode) { const char *scratch_constraint; - char scratch_letter; enum reg_class rclass; gcc_assert (insn_data[(int) icode].n_operands == 3); @@ -557,11 +553,7 @@ scratch_reload_class (enum insn_code icode) scratch_constraint++; if (*scratch_constraint == '&') scratch_constraint++; - scratch_letter = *scratch_constraint; - if (scratch_letter == 'r') - return GENERAL_REGS; - rclass = REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter, - scratch_constraint); + rclass = reg_class_for_constraint (lookup_constraint (scratch_constraint)); gcc_assert (rclass != NO_REGS); return rclass; } @@ -2851,8 +2843,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, if (*constraints[i] == 0) /* Ignore things like match_operator operands. */ ; - else if (constraints[i][0] == 'p' - || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i])) + else if (insn_extra_address_constraint + (lookup_constraint (constraints[i]))) { address_operand_reloaded[i] = find_reloads_address (recog_data.operand_mode[i], (rtx*) 0, @@ -3094,6 +3086,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, operand. */ int constmemok = 0; int earlyclobber = 0; + enum constraint_num cn; + enum reg_class cl; /* If the predicate accepts a unary operator, it means that we need to reload the operand, but do not do this for @@ -3207,14 +3201,6 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, c = '\0'; break; - case '=': case '+': case '*': - break; - - case '%': - /* We only support one commutative marker, the first - one. We already set commutative above. */ - break; - case '?': reject += 6; break; @@ -3423,49 +3409,6 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, earlyclobber = 1, this_earlyclobber = 1; break; - case 'E': - case 'F': - if (CONST_DOUBLE_AS_FLOAT_P (operand) - || (GET_CODE (operand) == CONST_VECTOR - && (GET_MODE_CLASS (GET_MODE (operand)) - == MODE_VECTOR_FLOAT))) - win = 1; - break; - - case 'G': - case 'H': - if (CONST_DOUBLE_AS_FLOAT_P (operand) - && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (operand, c, p)) - win = 1; - break; - - case 's': - if (CONST_SCALAR_INT_P (operand)) - break; - case 'i': - if (CONSTANT_P (operand) - && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (operand))) - win = 1; - break; - - case 'n': - if (CONST_SCALAR_INT_P (operand)) - win = 1; - break; - - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - if (CONST_INT_P (operand) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operand), c, p)) - win = 1; - break; - case 'X': force_reload = 0; win = 1; @@ -3486,74 +3429,81 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, || (REGNO (operand) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (operand)] < 0))) win = 1; - /* Drop through into 'r' case. */ - - case 'r': - this_alternative[i] - = reg_class_subunion[this_alternative[i]][(int) GENERAL_REGS]; + cl = GENERAL_REGS; goto reg; default: - if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS) + cn = lookup_constraint (p); + switch (get_constraint_type (cn)) { -#ifdef EXTRA_CONSTRAINT_STR - if (EXTRA_MEMORY_CONSTRAINT (c, p)) - { - if (force_reload) - break; - if (EXTRA_CONSTRAINT_STR (operand, c, p)) - win = 1; - /* If the address was already reloaded, - we win as well. */ - else if (MEM_P (operand) - && address_reloaded[i] == 1) - win = 1; - /* Likewise if the address will be reloaded because - reg_equiv_address is nonzero. For reg_equiv_mem - we have to check. */ - else if (REG_P (operand) - && REGNO (operand) >= FIRST_PSEUDO_REGISTER - && reg_renumber[REGNO (operand)] < 0 - && ((reg_equiv_mem (REGNO (operand)) != 0 - && EXTRA_CONSTRAINT_STR (reg_equiv_mem (REGNO (operand)), c, p)) - || (reg_equiv_address (REGNO (operand)) != 0))) - win = 1; - - /* If we didn't already win, we can reload - constants via force_const_mem, and other - MEMs by reloading the address like for 'o'. */ - if (CONST_POOL_OK_P (operand_mode[i], operand) - || MEM_P (operand)) - badop = 0; - constmemok = 1; - offmemok = 1; - break; - } - if (EXTRA_ADDRESS_CONSTRAINT (c, p)) - { - if (EXTRA_CONSTRAINT_STR (operand, c, p)) - win = 1; - - /* If we didn't already win, we can reload - the address into a base register. */ - this_alternative[i] - = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, - ADDRESS, SCRATCH); - badop = 0; - break; - } + case CT_REGISTER: + cl = reg_class_for_constraint (cn); + if (cl != NO_REGS) + goto reg; + break; + + case CT_CONST_INT: + if (CONST_INT_P (operand) + && (insn_const_int_ok_for_constraint + (INTVAL (operand), cn))) + win = true; + break; - if (EXTRA_CONSTRAINT_STR (operand, c, p)) + case CT_MEMORY: + if (force_reload) + break; + if (constraint_satisfied_p (operand, cn)) + win = 1; + /* If the address was already reloaded, + we win as well. */ + else if (MEM_P (operand) && address_reloaded[i] == 1) + win = 1; + /* Likewise if the address will be reloaded because + reg_equiv_address is nonzero. For reg_equiv_mem + we have to check. */ + else if (REG_P (operand) + && REGNO (operand) >= FIRST_PSEUDO_REGISTER + && reg_renumber[REGNO (operand)] < 0 + && ((reg_equiv_mem (REGNO (operand)) != 0 + && (constraint_satisfied_p + (reg_equiv_mem (REGNO (operand)), + cn))) + || (reg_equiv_address (REGNO (operand)) + != 0))) + win = 1; + + /* If we didn't already win, we can reload + constants via force_const_mem, and other + MEMs by reloading the address like for 'o'. */ + if (CONST_POOL_OK_P (operand_mode[i], operand) + || MEM_P (operand)) + badop = 0; + constmemok = 1; + offmemok = 1; + break; + + case CT_ADDRESS: + if (constraint_satisfied_p (operand, cn)) + win = 1; + + /* If we didn't already win, we can reload + the address into a base register. */ + this_alternative[i] + = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH); + badop = 0; + break; + + case CT_FIXED_FORM: + if (constraint_satisfied_p (operand, cn)) win = 1; -#endif break; } + break; - this_alternative[i] - = (reg_class_subunion - [this_alternative[i]] - [(int) REG_CLASS_FROM_CONSTRAINT (c, p)]); reg: + this_alternative[i] + = reg_class_subunion[this_alternative[i]][cl]; if (GET_MODE (operand) == BLKmode) break; winreg = 1; @@ -4685,13 +4635,10 @@ alternative_allows_const_pool_ref (rtx mem ATTRIBUTE_UNUSED, for (; (c = *constraint) && c != ',' && c != '#'; constraint += CONSTRAINT_LEN (c, constraint)) { - if (c == TARGET_MEM_CONSTRAINT || c == 'o') + enum constraint_num cn = lookup_constraint (constraint); + if (insn_extra_memory_constraint (cn) + && (mem == NULL || constraint_satisfied_p (mem, cn))) return true; -#ifdef EXTRA_CONSTRAINT_STR - if (EXTRA_MEMORY_CONSTRAINT (c, constraint) - && (mem == NULL || EXTRA_CONSTRAINT_STR (mem, c, constraint))) - return true; -#endif } return false; } diff --git a/gcc/reload1.c b/gcc/reload1.c index 9daafa45097..25adf446e1d 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1417,33 +1417,20 @@ maybe_fix_stack_asms (void) switch (c) { - case '=': case '+': case '*': case '%': case '?': case '!': - case '0': case '1': case '2': case '3': case '4': case '<': - case '>': case 'V': case 'o': case '&': case 'E': case 'F': - case 's': case 'i': case 'n': case 'X': case 'I': case 'J': - case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': - case TARGET_MEM_CONSTRAINT: - break; - - case 'p': - cls = (int) reg_class_subunion[cls] - [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, - ADDRESS, SCRATCH)]; - break; - case 'g': - case 'r': cls = (int) reg_class_subunion[cls][(int) GENERAL_REGS]; break; default: - if (EXTRA_ADDRESS_CONSTRAINT (c, p)) + enum constraint_num cn = lookup_constraint (p); + if (insn_extra_address_constraint (cn)) cls = (int) reg_class_subunion[cls] [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH)]; else cls = (int) reg_class_subunion[cls] - [(int) REG_CLASS_FROM_CONSTRAINT (c, p)]; + [reg_class_for_constraint (cn)]; + break; } p += CONSTRAINT_LEN (c, p); } diff --git a/gcc/sanitizer.def b/gcc/sanitizer.def index 4016fc534cd..b4af1649258 100644 --- a/gcc/sanitizer.def +++ b/gcc/sanitizer.def @@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see /* Address Sanitizer */ DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init_v3", BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST) -/* Do not reorder the BUILT_IN_ASAN_REPORT* builtins, e.g. cfgcleanup.c +/* Do not reorder the BUILT_IN_ASAN_{REPORT,CHECK}* builtins, e.g. cfgcleanup.c relies on this order. */ DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD1, "__asan_report_load1", BT_FN_VOID_PTR, ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST) @@ -57,6 +57,30 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE16, "__asan_report_store16", DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE_N, "__asan_report_store_n", BT_FN_VOID_PTR_PTRMODE, ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD1, "__asan_load1", + BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD2, "__asan_load2", + BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD4, "__asan_load4", + BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD8, "__asan_load8", + BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD16, "__asan_load16", + BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOADN, "__asan_loadN", + BT_FN_VOID_PTR_PTRMODE, ATTR_TMPURE_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE1, "__asan_store1", + BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE2, "__asan_store2", + BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE4, "__asan_store4", + BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE8, "__asan_store8", + BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE16, "__asan_store16", + BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STOREN, "__asan_storeN", + BT_FN_VOID_PTR_PTRMODE, ATTR_TMPURE_NOTHROW_LEAF_LIST) DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REGISTER_GLOBALS, "__asan_register_globals", BT_FN_VOID_PTR_PTRMODE, ATTR_NOTHROW_LEAF_LIST) diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 019ec2f9532..7cafc8bb00b 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -4725,7 +4725,7 @@ find_inc (struct mem_inc_info *mii, bool backwards) if (parse_add_or_inc (mii, inc_cand, backwards)) { struct dep_replacement *desc; - df_ref *def_rec; + df_ref def; rtx newaddr, newmem; if (sched_verbose >= 5) @@ -4734,18 +4734,15 @@ find_inc (struct mem_inc_info *mii, bool backwards) /* Need to assure that none of the operands of the inc instruction are assigned to by the mem insn. */ - for (def_rec = DF_INSN_DEFS (mii->mem_insn); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (reg_overlap_mentioned_p (DF_REF_REG (def), mii->inc_input) - || reg_overlap_mentioned_p (DF_REF_REG (def), mii->mem_reg0)) - { - if (sched_verbose >= 5) - fprintf (sched_dump, - "inc conflicts with store failure.\n"); - goto next; - } - } + FOR_EACH_INSN_DEF (def, mii->mem_insn) + if (reg_overlap_mentioned_p (DF_REF_REG (def), mii->inc_input) + || reg_overlap_mentioned_p (DF_REF_REG (def), mii->mem_reg0)) + { + if (sched_verbose >= 5) + fprintf (sched_dump, + "inc conflicts with store failure.\n"); + goto next; + } newaddr = mii->inc_input; if (mii->mem_index != NULL_RTX) newaddr = gen_rtx_PLUS (GET_MODE (newaddr), newaddr, @@ -4820,22 +4817,19 @@ find_mem (struct mem_inc_info *mii, rtx *address_of_x) } if (REG_P (reg0)) { - df_ref *def_rec; + df_ref use; int occurrences = 0; /* Make sure this reg appears only once in this insn. Can't use count_occurrences since that only works for pseudos. */ - for (def_rec = DF_INSN_USES (mii->mem_insn); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (reg_overlap_mentioned_p (reg0, DF_REF_REG (def))) - if (++occurrences > 1) - { - if (sched_verbose >= 5) - fprintf (sched_dump, "mem count failure\n"); - return false; - } - } + FOR_EACH_INSN_USE (use, mii->mem_insn) + if (reg_overlap_mentioned_p (reg0, DF_REF_REG (use))) + if (++occurrences > 1) + { + if (sched_verbose >= 5) + fprintf (sched_dump, "mem count failure\n"); + return false; + } mii->mem_reg0 = reg0; return find_inc (mii, true) || find_inc (mii, false); diff --git a/gcc/sdbout.c b/gcc/sdbout.c index b07824bbe90..144caa96a7d 100644 --- a/gcc/sdbout.c +++ b/gcc/sdbout.c @@ -1017,7 +1017,7 @@ static void sdbout_one_type (tree type) { if (current_function_decl != NULL_TREE - && DECL_SECTION_NAME (current_function_decl) != NULL_TREE) + && DECL_SECTION_NAME (current_function_decl) != NULL) ; /* Don't change section amid function. */ else switch_to_section (current_function_section ()); diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index 3cba326e897..0399efa5c7c 100644 --- a/gcc/sel-sched-ir.c +++ b/gcc/sel-sched-ir.c @@ -2613,8 +2613,7 @@ static void maybe_downgrade_id_to_use (idata_t id, insn_t insn) { bool must_be_use = false; - unsigned uid = INSN_UID (insn); - df_ref *rec; + df_ref def; rtx lhs = IDATA_LHS (id); rtx rhs = IDATA_RHS (id); @@ -2628,10 +2627,8 @@ maybe_downgrade_id_to_use (idata_t id, insn_t insn) return; } - for (rec = DF_INSN_UID_DEFS (uid); *rec; rec++) + FOR_EACH_INSN_DEF (def, insn) { - df_ref def = *rec; - if (DF_REF_INSN (def) && DF_REF_FLAGS_IS_SET (def, DF_REF_PRE_POST_MODIFY) && loc_mentioned_in_p (DF_REF_LOC (def), IDATA_RHS (id))) @@ -2659,13 +2656,12 @@ maybe_downgrade_id_to_use (idata_t id, insn_t insn) static void setup_id_reg_sets (idata_t id, insn_t insn) { - unsigned uid = INSN_UID (insn); - df_ref *rec; + struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); + df_ref def, use; regset tmp = get_clear_regset_from_pool (); - for (rec = DF_INSN_UID_DEFS (uid); *rec; rec++) + FOR_EACH_INSN_INFO_DEF (def, insn_info) { - df_ref def = *rec; unsigned int regno = DF_REF_REGNO (def); /* Post modifies are treated like clobbers by sched-deps.c. */ @@ -2689,9 +2685,8 @@ setup_id_reg_sets (idata_t id, insn_t insn) bitmap_set_bit (tmp, regno); } - for (rec = DF_INSN_UID_USES (uid); *rec; rec++) + FOR_EACH_INSN_INFO_USE (use, insn_info) { - df_ref use = *rec; unsigned int regno = DF_REF_REGNO (use); /* When these refs are met for the first time, skip them, as diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c index 7d9c6e715db..5c34fee39f9 100644 --- a/gcc/shrink-wrap.c +++ b/gcc/shrink-wrap.c @@ -64,7 +64,7 @@ bool requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used, HARD_REG_SET set_up_by_prologue) { - df_ref *df_rec; + df_ref def, use; HARD_REG_SET hardregs; unsigned regno; @@ -76,9 +76,9 @@ requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used, return true; CLEAR_HARD_REG_SET (hardregs); - for (df_rec = DF_INSN_DEFS (insn); *df_rec; df_rec++) + FOR_EACH_INSN_DEF (def, insn) { - rtx dreg = DF_REF_REG (*df_rec); + rtx dreg = DF_REF_REG (def); if (!REG_P (dreg)) continue; @@ -94,9 +94,9 @@ requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used, && df_regs_ever_live_p (regno)) return true; - for (df_rec = DF_INSN_USES (insn); *df_rec; df_rec++) + FOR_EACH_INSN_USE (use, insn) { - rtx reg = DF_REF_REG (*df_rec); + rtx reg = DF_REF_REG (use); if (!REG_P (reg)) continue; @@ -333,7 +333,7 @@ prepare_shrink_wrap (basic_block entry_block) { rtx insn, curr, x; HARD_REG_SET uses, defs; - df_ref *ref; + df_ref def, use; bool split_p = false; if (JUMP_P (BB_END (entry_block))) @@ -353,17 +353,17 @@ prepare_shrink_wrap (basic_block entry_block) &split_p)) { /* Add all defined registers to DEFs. */ - for (ref = DF_INSN_DEFS (insn); *ref; ref++) + FOR_EACH_INSN_DEF (def, insn) { - x = DF_REF_REG (*ref); + x = DF_REF_REG (def); if (REG_P (x) && HARD_REGISTER_P (x)) SET_HARD_REG_BIT (defs, REGNO (x)); } /* Add all used registers to USESs. */ - for (ref = DF_INSN_USES (insn); *ref; ref++) + FOR_EACH_INSN_USE (use, insn) { - x = DF_REF_REG (*ref); + x = DF_REF_REG (use); if (REG_P (x) && HARD_REGISTER_P (x)) SET_HARD_REG_BIT (uses, REGNO (x)); } diff --git a/gcc/stmt.c b/gcc/stmt.c index 7c1ea5d5cb9..0aae085aa89 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -286,10 +286,6 @@ parse_output_constraint (const char **constraint_p, int operand_num, } break; - case 'V': case TARGET_MEM_CONSTRAINT: case 'o': - *allows_mem = true; - break; - case '?': case '!': case '*': case '&': case '#': case 'E': case 'F': case 'G': case 'H': case 's': case 'i': case 'n': @@ -315,19 +311,14 @@ parse_output_constraint (const char **constraint_p, int operand_num, *allows_mem = true; break; - case 'p': case 'r': - *allows_reg = true; - break; - default: if (!ISALPHA (*p)) break; - if (REG_CLASS_FROM_CONSTRAINT (*p, p) != NO_REGS) + enum constraint_num cn = lookup_constraint (p); + if (reg_class_for_constraint (cn) != NO_REGS + || insn_extra_address_constraint (cn)) *allows_reg = true; -#ifdef EXTRA_CONSTRAINT_STR - else if (EXTRA_ADDRESS_CONSTRAINT (*p, p)) - *allows_reg = true; - else if (EXTRA_MEMORY_CONSTRAINT (*p, p)) + else if (insn_extra_memory_constraint (cn)) *allows_mem = true; else { @@ -337,7 +328,6 @@ parse_output_constraint (const char **constraint_p, int operand_num, *allows_reg = true; *allows_mem = true; } -#endif break; } @@ -385,10 +375,6 @@ parse_input_constraint (const char **constraint_p, int input_num, } break; - case 'V': case TARGET_MEM_CONSTRAINT: case 'o': - *allows_mem = true; - break; - case '<': case '>': case '?': case '!': case '*': case '#': case 'E': case 'F': case 'G': case 'H': @@ -439,10 +425,6 @@ parse_input_constraint (const char **constraint_p, int input_num, } /* Fall through. */ - case 'p': case 'r': - *allows_reg = true; - break; - case 'g': case 'X': *allows_reg = true; *allows_mem = true; @@ -454,13 +436,11 @@ parse_input_constraint (const char **constraint_p, int input_num, error ("invalid punctuation %qc in constraint", constraint[j]); return false; } - if (REG_CLASS_FROM_CONSTRAINT (constraint[j], constraint + j) - != NO_REGS) + enum constraint_num cn = lookup_constraint (constraint + j); + if (reg_class_for_constraint (cn) != NO_REGS + || insn_extra_address_constraint (cn)) *allows_reg = true; -#ifdef EXTRA_CONSTRAINT_STR - else if (EXTRA_ADDRESS_CONSTRAINT (constraint[j], constraint + j)) - *allows_reg = true; - else if (EXTRA_MEMORY_CONSTRAINT (constraint[j], constraint + j)) + else if (insn_extra_memory_constraint (cn)) *allows_mem = true; else { @@ -470,7 +450,6 @@ parse_input_constraint (const char **constraint_p, int input_num, *allows_reg = true; *allows_mem = true; } -#endif break; } diff --git a/gcc/store-motion.c b/gcc/store-motion.c index b3e58900b39..18ba518eb9a 100644 --- a/gcc/store-motion.c +++ b/gcc/store-motion.c @@ -645,7 +645,7 @@ compute_store_table (void) unsigned regno; #endif rtx insn, tmp; - df_ref *def_rec; + df_ref def; int *last_set_in, *already_set; struct st_expr * ptr, **prev_next_ptr_ptr; unsigned int max_gcse_regno = max_reg_num (); @@ -665,8 +665,8 @@ compute_store_table (void) if (! NONDEBUG_INSN_P (insn)) continue; - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - last_set_in[DF_REF_REGNO (*def_rec)] = INSN_UID (insn); + FOR_EACH_INSN_DEF (def, insn) + last_set_in[DF_REF_REGNO (def)] = INSN_UID (insn); } /* Now find the stores. */ @@ -676,16 +676,16 @@ compute_store_table (void) if (! NONDEBUG_INSN_P (insn)) continue; - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - already_set[DF_REF_REGNO (*def_rec)] = INSN_UID (insn); + FOR_EACH_INSN_DEF (def, insn) + already_set[DF_REF_REGNO (def)] = INSN_UID (insn); /* Now that we've marked regs, look for stores. */ find_moveable_store (insn, already_set, last_set_in); /* Unmark regs that are no longer set. */ - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - if (last_set_in[DF_REF_REGNO (*def_rec)] == INSN_UID (insn)) - last_set_in[DF_REF_REGNO (*def_rec)] = 0; + FOR_EACH_INSN_DEF (def, insn) + if (last_set_in[DF_REF_REGNO (def)] == INSN_UID (insn)) + last_set_in[DF_REF_REGNO (def)] = 0; } #ifdef ENABLE_CHECKING @@ -1068,12 +1068,12 @@ build_store_vectors (void) FOR_BB_INSNS (bb, insn) if (NONDEBUG_INSN_P (insn)) { - df_ref *def_rec; - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) + df_ref def; + FOR_EACH_INSN_DEF (def, insn) { - unsigned int ref_regno = DF_REF_REGNO (*def_rec); + unsigned int ref_regno = DF_REF_REGNO (def); if (ref_regno < max_gcse_regno) - regs_set_in_block[DF_REF_REGNO (*def_rec)] = 1; + regs_set_in_block[DF_REF_REGNO (def)] = 1; } } diff --git a/gcc/symtab.c b/gcc/symtab.c index 8265b4e1eb3..8158acc5bda 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -57,6 +57,10 @@ const char * const ld_plugin_symbol_resolution_names[]= "prevailing_def_ironly_exp" }; + +/* Hash table used to hold sectoons. */ +static GTY((param_is (section_hash_entry))) htab_t section_hash; + /* Hash table used to convert assembler names into nodes. */ static GTY((param_is (symtab_node))) htab_t assembler_name_hash; @@ -307,6 +311,9 @@ symtab_unregister_node (symtab_node *node) ipa_remove_all_references (&node->ref_list); ipa_remove_all_referring (&node->ref_list); + /* Remove reference to section. */ + node->set_section_for_node (NULL); + symtab_remove_from_same_comdat_group (node); if (node->previous) @@ -565,7 +572,9 @@ dump_symtab_base (FILE *f, symtab_node *node) fprintf (f, " one_only"); if (node->get_section ()) fprintf (f, " section:%s", - TREE_STRING_POINTER (node->get_section ())); + node->get_section ()); + if (node->implicit_section) + fprintf (f," (implicit_section)"); if (DECL_VISIBILITY_SPECIFIED (node->decl)) fprintf (f, " visibility_specified"); if (DECL_VISIBILITY (node->decl)) @@ -791,6 +800,7 @@ verify_symtab_base (symtab_node *node) { struct ipa_ref_list *refs = &node->ref_list; struct ipa_ref *ref; + for (int i = 0; ipa_ref_list_referring_iterate (refs, i, ref); ++i) { if (!symtab_in_same_comdat_p (ref->referring, node)) @@ -803,6 +813,38 @@ verify_symtab_base (symtab_node *node) } } } + if (node->implicit_section && !node->get_section ()) + { + error ("implicit_section flag is set but section isn't"); + error_found = true; + } + if (node->get_section () && node->get_comdat_group () + && !node->implicit_section) + { + error ("Both section and comdat group is set"); + error_found = true; + } + /* TODO: Add string table for sections, so we do not keep holding duplicated + strings. */ + if (node->alias && node->definition + && node->get_section () != symtab_alias_target (node)->get_section () + && (!node->get_section() + || !symtab_alias_target (node)->get_section () + || strcmp (node->get_section(), + symtab_alias_target (node)->get_section ()))) + { + error ("Alias and target's section differs"); + dump_symtab_node (stderr, symtab_alias_target (node)); + error_found = true; + } + if (node->alias && node->definition + && node->get_comdat_group () != symtab_alias_target (node)->get_comdat_group ()) + { + error ("Alias and target's comdat groups differs"); + dump_symtab_node (stderr, symtab_alias_target (node)); + error_found = true; + } + return error_found; } @@ -832,8 +874,30 @@ DEBUG_FUNCTION void verify_symtab (void) { symtab_node *node; + pointer_map<symtab_node *> comdat_head_map; + FOR_EACH_SYMBOL (node) - verify_symtab_node (node); + { + verify_symtab_node (node); + if (node->get_comdat_group ()) + { + symtab_node **entry, *s; + bool existed; + + entry = comdat_head_map.insert (node->get_comdat_group (), &existed); + if (!existed) + *entry = node; + else + for (s = (*entry)->same_comdat_group; s != NULL && s != node; s = s->same_comdat_group) + if (!s || s == *entry) + { + error ("Two symbols with same comdat_group are not linked by the same_comdat_group list."); + dump_symtab_node (stderr, *entry); + dump_symtab_node (stderr, s); + internal_error ("verify_symtab failed"); + } + } + } } /* Return true when RESOLUTION indicate that linker will use @@ -1024,6 +1088,103 @@ fixup_same_cpp_alias_visibility (symtab_node *node, symtab_node *target) node->externally_visible = target->externally_visible; } +/* Hash sections by their names. */ + +static hashval_t +hash_section_hash_entry (const void *p) +{ + const section_hash_entry *n = (const section_hash_entry *) p; + return htab_hash_string (n->name); +} + +/* Return true if section P1 name equals to P2. */ + +static int +eq_sections (const void *p1, const void *p2) +{ + const section_hash_entry *n1 = (const section_hash_entry *) p1; + const char *name = (const char *)p2; + return n1->name == name || !strcmp (n1->name, name); +} + +/* Set section, do not recurse into aliases. + When one wants to change section of symbol and its aliases, + use set_section */ + +void +symtab_node::set_section_for_node (const char *section) +{ + const char *current = get_section (); + void **slot; + + if (current == section + || (current && section + && !strcmp (current, section))) + return; + + if (current) + { + x_section->ref_count--; + if (!x_section->ref_count) + { + slot = htab_find_slot_with_hash (section_hash, x_section->name, + htab_hash_string (x_section->name), + INSERT); + ggc_free (x_section); + htab_clear_slot (section_hash, slot); + } + x_section = NULL; + } + if (!section) + { + implicit_section = false; + return; + } + if (!section_hash) + section_hash = htab_create_ggc (10, hash_section_hash_entry, + eq_sections, NULL); + slot = htab_find_slot_with_hash (section_hash, section, + htab_hash_string (section), + INSERT); + if (*slot) + x_section = (section_hash_entry *)*slot; + else + { + int len = strlen (section); + *slot = x_section = ggc_cleared_alloc<section_hash_entry> (); + x_section->name = ggc_vec_alloc<char> (len + 1); + memcpy (x_section->name, section, len + 1); + } + x_section->ref_count++; +} + +/* Worker for set_section. */ + +static bool +set_section_1 (struct symtab_node *n, void *s) +{ + n->set_section_for_node ((char *)s); + return false; +} + +/* Set section of symbol and its aliases. */ + +void +symtab_node::set_section (const char *section) +{ + gcc_assert (!this->alias); + symtab_for_node_and_aliases (this, set_section_1, const_cast<char *>(section), true); +} + +/* Worker for symtab_resolve_alias. */ + +static bool +set_implicit_section (struct symtab_node *n, void *data ATTRIBUTE_UNUSED) +{ + n->implicit_section = true; + return false; +} + /* Add reference recording that NODE is alias of TARGET. The function can fail in the case of aliasing cycles; in this case it returns false. */ @@ -1058,6 +1219,26 @@ symtab_resolve_alias (symtab_node *node, symtab_node *target) node->analyzed = true; ipa_record_reference (node, target, IPA_REF_ALIAS, NULL); + /* Add alias into the comdat group of its target unless it is already there. */ + if (node->same_comdat_group) + symtab_remove_from_same_comdat_group (node); + node->set_comdat_group (NULL); + if (target->get_comdat_group ()) + symtab_add_to_same_comdat_group (node, target); + + if ((node->get_section () != target->get_section () + || target->get_comdat_group ()) + && node->get_section () && !node->implicit_section) + { + error ("section of alias %q+D must match section of its target", + node->decl); + } + symtab_for_node_and_aliases (node, set_section_1, + const_cast<char *>(target->get_section ()), true); + if (target->implicit_section) + symtab_for_node_and_aliases (node, + set_implicit_section, NULL, true); + /* Alias targets become redundant after alias is resolved into an reference. We do not want to keep it around or we would have to mind updating them when renaming symbols. */ diff --git a/gcc/system.h b/gcc/system.h index 51b90676de3..29da7974ced 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -930,7 +930,10 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; GO_IF_MODE_DEPENDENT_ADDRESS DELAY_SLOTS_FOR_EPILOGUE \ ELIGIBLE_FOR_EPILOGUE_DELAY TARGET_C99_FUNCTIONS TARGET_HAS_SINCOS \ REG_CLASS_FROM_LETTER CONST_OK_FOR_LETTER_P \ - CONST_DOUBLE_OK_FOR_LETTER_P EXTRA_CONSTRAINT + CONST_DOUBLE_OK_FOR_LETTER_P EXTRA_CONSTRAINT \ + REG_CLASS_FROM_CONSTRAINT REG_CLASS_FOR_CONSTRAINT \ + EXTRA_CONSTRAINT_STR EXTRA_MEMORY_CONSTRAINT \ + EXTRA_ADDRESS_CONSTRAINT CONST_DOUBLE_OK_FOR_CONSTRAINT_P /* Hooks that are no longer used. */ #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \ diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 61d058a539e..0f27a5a6176 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -919,7 +919,6 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, else if (icode != CODE_FOR_nothing) { const char *insn_constraint, *scratch_constraint; - char insn_letter, scratch_letter; enum reg_class insn_class, scratch_class; gcc_assert (insn_data[(int) icode].n_operands == 3); @@ -933,11 +932,8 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, gcc_assert (*insn_constraint == '='); insn_constraint++; } - insn_letter = *insn_constraint; - insn_class - = (insn_letter == 'r' ? GENERAL_REGS - : REG_CLASS_FROM_CONSTRAINT ((unsigned char) insn_letter, - insn_constraint)); + insn_class = (reg_class_for_constraint + (lookup_constraint (insn_constraint))); gcc_assert (insn_class != NO_REGS); } @@ -951,11 +947,8 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, scratch_constraint++; if (*scratch_constraint == '&') scratch_constraint++; - scratch_letter = *scratch_constraint; - scratch_class - = (scratch_letter == 'r' ? GENERAL_REGS - : REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter, - scratch_constraint)); + scratch_class = (reg_class_for_constraint + (lookup_constraint (scratch_constraint))); if (reg_class_subset_p (reload_class, insn_class)) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 53b613426c1..543fa01b30c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,186 @@ +2014-06-17 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + PR target/61533 + * gcc.target/i386/fuse-caller-save.c: Add -fomit-frame-pointer to + dg-options. + +2014-06-17 Uros Bizjak <ubizjak@gmail.com> + + * gfortran.dg/pr61335.f90 (cp_unit_create): Initialize + unit_id and kind_id to zero. + +2014-06-17 Yufeng Zhang <yufeng.zhang@arm.com> + + PR target/61483 + * gcc.target/aarch64/aapcs64/type-def.h (struct hfa_fx2_t): New type. + * gcc.target/aarch64/aapcs64/va_arg-13.c: New test. + * gcc.target/aarch64/aapcs64/va_arg-14.c: Ditto. + * gcc.target/aarch64/aapcs64/va_arg-15.c: Ditto. + +2014-06-17 Richard Biener <rguenther@suse.de> + + PR lto/61012 + * gcc.dg/lto/pr61526_0.c: New testcase. + * gcc.dg/lto/pr61526_1.c: Likewise. + +2014-06-17 Richard Biener <rguenther@suse.de> + + * gcc.dg/tree-ssa/20041122-1.c: Adjust. + * gcc.dg/tree-ssa/forwprop-21.c: Likewise. + * gcc.dg/tree-ssa/vrp35.c: Revert previous adjustments. + * gcc.dg/tree-ssa/vrp36.c: Likewise. + * gcc.dg/vect/nodump-forwprop-22.c: Adjust. + +2014-06-17 Richard Biener <rguenther@suse.de> + + * gcc.dg/tree-ssa/ssa-lim-12.c: New testcase. + +2014-06-16 Richard Biener <rguenther@suse.de> + + PR tree-optimization/61482 + * g++.dg/torture/pr61482.C: New testcase. + +2014-06-16 Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com> + + * gcc.target/i386/xop-imul64-vector.c: Remove the check for + vpmacsdql instruction. + +2014-06-16 Yury Gribov <y.gribov@samsung.com> + + * c-c++-common/asan/instrument-with-calls-1.c: New test. + * c-c++-common/asan/instrument-with-calls-2.c: Likewise. + * c-c++-common/asan/instrument-with-calls-3.c: Likewise. + * c-c++-common/asan/no-redundant-instrumentation-1.c: Update + test patterns. + * c-c++-common/asan/no-redundant-instrumentation-2.c: Likewise. + * c-c++-common/asan/no-redundant-instrumentation-4.c: Likewise. + * c-c++-common/asan/no-redundant-instrumentation-5.c: Likewise. + * c-c++-common/asan/no-redundant-instrumentation-6.c: Likewise. + * c-c++-common/asan/no-redundant-instrumentation-7.c: Likewise. + * c-c++-common/asan/no-redundant-instrumentation-8.c: Likewise. + +2014-06-15 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + + PR fortran/28484 + PR fortran/61429 + * gfortran.dg/system_clock_1.f90: New file. + * gfortran.dg/system_clock_2.f90: New file. + +2014-06-14 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/33101 + * g++.dg/other/void3.C: New. + * g++.dg/conversion/err-recover1.C: Update. + +2014-06-13 Peter Bergner <bergner@vnet.ibm.com> + + PR target/61415 + * lib/target-supports.exp (check_effective_target_longdouble128): New. + * gcc.target/powerpc/pack02.c: Use it. + * gcc.target/powerpc/tfmode_off.c: Likewise. + +2014-06-13 Ilya Enkovich <ilya.enkovich@intel.com> + + PR rtl-optimization/61094 + PR rtl-optimization/61446 + * gcc.target/i386/pr61446.c : New. + +2014-06-13 Dehao Chen <dehao@google.com> + + * g++.dg/debug/dwarf2/cdtor-1.C: Update test result. + +2014-06-13 Alan Lawrence <alan.lawrence@arm.com> + + * gcc.dg/vect/vect-singleton_1.c: Remove duplicate of test body. + +2014-06-13 Richard Biener <rguenther@suse.de> + + * c-c++-common/pr46562-2.c: Adjust. + * g++.dg/tree-ssa/pr8781.C: Likewise. + * gcc.dg/tree-ssa/ssa-fre-24.c: Likewise. + * gcc.dg/tree-ssa/ssa-fre-25.c: Likewise. + * gcc.dg/tree-ssa/ssa-fre-32.c: Likewise. + * gcc.dg/tree-ssa/ssa-fre-39.c: Likewise. + * gcc.dg/tree-ssa/ssa-pre-16.c: Likewise. + +2014-06-13 Thomas Preud'homme <thomas.preudhomme@arm.com> + + PR tree-optimization/61375 + * gcc.c-torture/execute/pr61375-1.c: New test. + +2014-06-12 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/61486 + * c-c++-common/gomp/pr61486-1.c: New test. + * c-c++-common/gomp/pr61486-2.c: New test. + +2014-06-10 Alan Lawrence <alan.lawrence@arm.com> + + PR target/59843 + * gcc.dg/vect/vect-singleton_1.c: New file. + +2014-06-12 Georg-Johann Lay <avr@gjlay.de> + + PR target/61443 + * gcc.target/avr/torture/pr61443.c: New test. + +2014-06-11 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/19200 + * g++.dg/parse/friend11.C: New. + +2014-06-11 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/60265 + * g++.dg/cpp0x/using-enum-1.C: New. + * g++.dg/cpp0x/using-enum-2.C: Likewise. + +2014-06-11 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/19200 + * g++.dg/parse/friend9.C: New. + * g++.dg/parse/friend10.C: Likewise. + * g++.dg/parse/friend7.C: Adjust. + +2014-06-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/61452 + * gcc.dg/torture/pr61452.c: New testcase. + +2014-06-11 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/34049 + * g++.dg/parse/pr34049.C: New. + +2014-06-11 Thomas Preud'homme <thomas.preudhomme@arm.com> + + * gcc.c-torture/execute/pr61306-1.c: New test. + * gcc.c-torture/execute/pr61306-2.c: Likewise. + * gcc.c-torture/execute/pr61306-3.c: Likewise. + +2014-06-11 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * gcc.target/aarch64/acle/acle.exp: New. + * gcc.target/aarch64/acle/crc32b.c: New test. + * gcc.target/aarch64/acle/crc32cb.c: Likewise. + * gcc.target/aarch64/acle/crc32cd.c: Likewise. + * gcc.target/aarch64/acle/crc32ch.c: Likewise. + * gcc.target/aarch64/acle/crc32cw.c: Likewise. + * gcc.target/aarch64/acle/crc32d.c: Likewise. + * gcc.target/aarch64/acle/crc32h.c: Likewise. + * gcc.target/aarch64/acle/crc32w.c: Likewise. + +2014-06-11 Evgeny Stupachenko <evstupac@gmail.com> + + PR tree-optimization/52252 + * gcc.dg/vect/pr52252-st.c: Test on stores group of size 3. + +2014-06-11 Richard Biener <rguenther@suse.de> + + PR middle-end/61437 + * gcc.dg/torture/20140610-1.c: New testcase. + * gcc.dg/torture/20140610-2.c: Likewise. + 2014-06-10 Richard Biener <rguenther@suse.de> PR tree-optimization/61438 @@ -186,8 +369,8 @@ * gcc.target/i386/avx512f-vpmuldq-2.c: Ditto. * gcc.target/i386/avx512f-vrndscalepd-2.c: Ditto. * gcc.target/i386/i386.exp: Ditto. - * gcc.target/i386/avx512cd-vpbroadcastmb2q-2.c: Add static void for CALC, - void for TEST instead of static void, initialize variables. + * gcc.target/i386/avx512cd-vpbroadcastmb2q-2.c: Add static void for + CALC, void for TEST instead of static void, initialize variables. * gcc.target/i386/avx512cd-vpbroadcastmw2d-2.c: Ditto. * gcc.target/i386/avx512cd-vpconflictd-2.c: Void for TEST instead of static void. @@ -337,8 +520,8 @@ * gcc.target/i386/avx512f-vpmovusqd-2.c: Ditto. * gcc.target/i386/avx512f-vpmovusqw-2.c: Ditto. * gcc.target/i386/avx512f-vpmaxud-2.c: Add static void for CALC, - void for TEST instead of static void, change parameters for UNION_CHECK, - UNION_TYPE, MASK_MERGE and MASK_ZERO. + void for TEST instead of static void, change parameters for + UNION_CHECK, UNION_TYPE, MASK_MERGE and MASK_ZERO. * gcc.target/i386/avx512f-vpmaxuq-2.c: Ditto. * gcc.target/i386/avx512f-vpminud-2.c: Ditto. * gcc.target/i386/avx512f-vpminuq-2.c: Ditto. @@ -381,7 +564,8 @@ 2014-06-09 Alan Lawrence <alan.lawrence@arm.com> PR target/61062 - * gcc.target/arm/pr48252.c (main): Expect same result as endian-neutral. + * gcc.target/arm/pr48252.c (main): Expect same result + as endian-neutral. 2014-06-09 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> @@ -514,8 +698,7 @@ 2014-06-05 Julian Brown <julian@codesourcery.com> Sandra Loosemore <sandra@codesourcery.com> - * gcc.target/arm/pr45094.c: Remove -mcpu=cortex-a8, dg-skip-if - options. + * gcc.target/arm/pr45094.c: Remove -mcpu=cortex-a8, dg-skip-if options. 2014-06-05 Richard Biener <rguenther@suse.de> @@ -2287,7 +2470,7 @@ 2014-04-24 Dinar Temirbulatov <dtemirbulatov@gmail.com> PR c++/57958 - * testsuite/g++.dg/cpp0x/pr57958.C: New test. + * g++.dg/cpp0x/pr57958.C: New test. 2014-04-24 Alan Lawrence <alan.lawrence@arm.com> @@ -2977,7 +3160,7 @@ 2014-04-02 Jan Hubicka <hubicka@ucw.cz> PR ipa/60659 - * testsuite/g++.dg/torture/pr60659.C: New testcase. + * g++.dg/torture/pr60659.C: New testcase. 2014-04-02 Bill Schmidt <wschmidt@linux.vnet.ibm.com> @@ -3882,7 +4065,7 @@ 2014-03-02 Jan Hubicka <hubicka@ucw.cz> PR ipa/60306 - * testsuite/g++.dg/ipa/devirt-29.C: New testcase + * g++.dg/ipa/devirt-29.C: New testcase 2014-03-02 Bernd Edlinger <bernd.edlinger@hotmail.de> diff --git a/gcc/testsuite/c-c++-common/abi-bf.c b/gcc/testsuite/c-c++-common/abi-bf.c deleted file mode 100644 index 05b898609c2..00000000000 --- a/gcc/testsuite/c-c++-common/abi-bf.c +++ /dev/null @@ -1,3 +0,0 @@ -/* { dg-warning "incompatible" } */ -/* { dg-do compile } */ -/* { dg-options "-fstrict-volatile-bitfields -fabi-version=1" } */ diff --git a/gcc/testsuite/c-c++-common/asan/instrument-with-calls-1.c b/gcc/testsuite/c-c++-common/asan/instrument-with-calls-1.c new file mode 100644 index 00000000000..80f76205760 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/instrument-with-calls-1.c @@ -0,0 +1,10 @@ +/* { dg-do assemble } */ +/* { dg-options "--param asan-instrumentation-with-call-threshold=0 -save-temps" } */ + +void f(char *a, int *b) { + *b = *a; +} + +/* { dg-final { scan-assembler "__asan_load1" } } */ +/* { dg-final { scan-assembler "__asan_store4" } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c b/gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c new file mode 100644 index 00000000000..570f796ea6f --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c @@ -0,0 +1,16 @@ +/* { dg-do assemble } */ +/* { dg-options "--param asan-instrumentation-with-call-threshold=1 -save-temps" } */ + +int x; + +void f(int *a, int *b) { + *a = 0; + asm volatile ("" ::: "memory"); + x = *b; +} + +/* { dg-final { scan-assembler-not "__asan_store4" } } */ +/* { dg-final { scan-assembler "__asan_report_store4" } } */ +/* { dg-final { scan-assembler "__asan_load4" } } */ +/* { dg-final { scan-assembler-not "__asan_report_load4" } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/c-c++-common/asan/instrument-with-calls-3.c b/gcc/testsuite/c-c++-common/asan/instrument-with-calls-3.c new file mode 100644 index 00000000000..3712c7a56aa --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/instrument-with-calls-3.c @@ -0,0 +1,15 @@ +/* { dg-do assemble } */ +/* { dg-options "--param asan-instrumentation-with-call-threshold=0 -save-temps" } */ + +struct A { + char x[7]; +}; + +void f(struct A *x, struct A *y) { + *x = *y; +} + +/* { dg-final { scan-assembler "__asan_loadN" } } */ +/* { dg-final { scan-assembler "__asan_storeN" } } */ +/* { dg-final { cleanup-saved-temps } } */ + diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c index fa52e0ca85d..c7c594ea070 100644 --- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c +++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c @@ -16,12 +16,11 @@ test0 () tab[0] = 1; tab[1] = 2; - /* __builtin___asan_report_load1 called 1 time for the store - below. */ - char t0 = tab[1]; - /* This load should not be instrumented because it is to the same memory location as above. */ + char t0 = tab[1]; + + /* Likewise. */ char t1 = tab[1]; return t0 + t1; @@ -36,7 +35,7 @@ test1 (int i) the initialization. */ foo[i] = 1; - /*__builtin___asan_report_store1 called 2 times here to instrument + /*__builtin___asan_report_store_n called once here to instrument the store to the memory region of tab. */ __builtin_memset (tab, 3, sizeof (tab)); @@ -44,8 +43,8 @@ test1 (int i) __builtin_memset (tab, 4, sizeof (tab)); __builtin_memset (tab, 5, sizeof (tab)); - /* There are 2 calls to __builtin___asan_report_store1 and 2 calls - to __builtin___asan_report_load1 to instrument the store to + /* There is a call to __builtin___asan_report_store_n and a call + to __builtin___asan_report_load_n to instrument the store to (subset of) the memory region of tab. */ __builtin_memcpy (&tab[1], foo + i, 3); @@ -53,7 +52,7 @@ test1 (int i) the reference to tab[1] has been already instrumented above. */ return tab[1]; - /* So for these function, there should be 7 calls to + /* So for these functions, there should be 3 calls to __builtin___asan_report_store1. */ } @@ -63,6 +62,7 @@ main () return test0 () && test1 (0); } -/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 7 "asan0" } } */ -/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 2 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 3 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 1 "asan0" } } */ /* { dg-final { cleanup-tree-dump "asan0" } } */ diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c index 28525e0ff0d..143312fb2f6 100644 --- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c +++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c @@ -20,6 +20,7 @@ main () __builtin_memset (tab, 1, 3); } -/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 3 "asan0" } } */ -/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 3 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "& 7" 3 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 2 "asan0" } } */ /* { dg-final { cleanup-tree-dump "asan0" } } */ diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c index b2e72841b35..da91cd53ff4 100644 --- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c +++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c @@ -5,9 +5,13 @@ void foo (int *a, char *b, char *c) { + /* One check for c[0], one check for a[], one check for c, two checks for b. */ __builtin_memmove (c, b, a[c[0]]); + /* For a total of 5 checks. */ } -/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 3 "asan0" } } */ -/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 1 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */ /* { dg-final { cleanup-tree-dump "asan0" } } */ diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c index ead3f582330..134be664a8c 100644 --- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c +++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c @@ -5,9 +5,14 @@ void foo (int *a, char *b, char *c) { + /* One check for b[0], one check for a[], 2 checks for c and one checks for b. */ __builtin_memmove (c, b, a[b[0]]); + /* For a total of 5 checks. */ } -/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 2 "asan0" } } */ -/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 2 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */ /* { dg-final { cleanup-tree-dump "asan0" } } */ diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c index e4691bc4734..55c8ee376b5 100644 --- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c +++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c @@ -5,10 +5,16 @@ void foo (int *a, char *b, char *c) { + /* One check for c[0], one check for a[], one check for c and 2 checks for b. */ __builtin_memmove (c, b, a[c[0]]); + /* One check for a[], one check for c and one check for b. */ __builtin_memmove (c, b, a[b[0]]); + /* For a total of 8 checks. */ } -/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 5 "asan0" } } */ -/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 2 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "& 7" 8 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 2 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 2 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */ /* { dg-final { cleanup-tree-dump "asan0" } } */ diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c index bf40a037679..a04956d7ceb 100644 --- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c +++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c @@ -13,11 +13,15 @@ struct S int foo (int *a, char *b, char *c) { + /* 2 checks for s.a, 2 checks for e. */ int d = __builtin_memcmp (s.a, e, 100); + /* One check for s.a and one check for e. */ d += __builtin_memcmp (s.a, e, 200); + /* For a total of 6 checks. */ return d; } -/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 6 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "& 7" 6 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 4 "asan0" } } */ /* { dg-final { scan-tree-dump-not "__builtin___asan_report_store" "asan0" } } */ /* { dg-final { cleanup-tree-dump "asan0" } } */ diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c index 38ea7a21d1e..308a133dbf9 100644 --- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c +++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c @@ -5,10 +5,16 @@ char foo (int *a, char *b, char *c) { + /* One check for b[0], one check for a[], two checks for c and one check for b. */ __builtin_memmove (c, b, a[b[0]]); + /* No checks here. */ return c[0] + b[0]; + /* For a total of 5 checks. */ } -/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 3 "asan0" } } */ -/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 2 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */ +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */ /* { dg-final { cleanup-tree-dump "asan0" } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/pr61486-1.c b/gcc/testsuite/c-c++-common/gomp/pr61486-1.c new file mode 100644 index 00000000000..9ada58c8ccf --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr61486-1.c @@ -0,0 +1,13 @@ +/* PR middle-end/61486 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +int +foo (int *a) +{ + int i, j = 0; + #pragma omp target teams distribute simd linear(i, j) map(a[:10]) + for (i = 0; i < 10; i++) + a[i] = j++; + return i + j; +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr61486-2.c b/gcc/testsuite/c-c++-common/gomp/pr61486-2.c new file mode 100644 index 00000000000..729438101e2 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr61486-2.c @@ -0,0 +1,458 @@ +/* PR middle-end/61486 */ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +#pragma omp declare target +void dosomething (int *a, int n, int m); +#pragma omp end declare target + +void +test (int n, int o, int p, int q, int r, int s, int *pp) +{ + int a[o], i, j; + #pragma omp target data device (n + 1) if (n != 6) map (tofrom: n, r) + { + #pragma omp target device (n + 1) if (n != 6) map (from: n) map (alloc: a[2:o-2]) + dosomething (a, n, 0); + #pragma omp target teams device (n + 1) num_teams (n + 4) thread_limit (n * 2) \ + if (n != 6)map (from: n) map (alloc: a[2:o-2]) default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + } + #pragma omp target teams distribute device (n + 1) num_teams (n + 4) collapse (2) \ + if (n != 6)map (from: n) map (alloc: a[2:o-2]) default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + } + #pragma omp target teams distribute device (n + 1) num_teams (n + 4) \ + if (n != 6)map (from: n) map (alloc: a[2:o-2]) default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + } + #pragma omp target teams distribute parallel for device (n + 1) num_teams (n + 4) \ + if (n != 6)map (from: n) map (alloc: a[2:o-2]) default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) collapse (2) \ + num_threads (n + 4) proc_bind (spread) lastprivate (s) \ + ordered schedule (static, 8) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + #pragma omp ordered + p = q; + s = i * 10 + j; + } + #pragma omp target teams distribute parallel for device (n + 1) num_teams (n + 4) \ + if (n != 6)map (from: n) map (alloc: a[2:o-2]) default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) num_threads (n + 4) \ + proc_bind (master) lastprivate (s) ordered schedule (static, 8) + for (i = 0; i < 10; i++) + { + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + } + #pragma omp ordered + p = q; + s = i * 10; + } + #pragma omp target teams distribute parallel for simd device (n + 1) \ + if (n != 6)map (from: n) map (alloc: a[2:o-2]) default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) collapse (2) \ + num_threads (n + 4) proc_bind (spread) lastprivate (s) \ + schedule (static, 8) num_teams (n + 4) safelen(8) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + a[2+i*10+j] = p + q; + s = i * 10 + j; + } + #pragma omp target teams distribute parallel for simd device (n + 1) \ + if (n != 6)map (from: n) map (alloc: a[2:o-2]) default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) num_threads (n + 4) \ + proc_bind (master) lastprivate (s) schedule (static, 8) \ + num_teams (n + 4) safelen(16) linear(i:1) aligned (pp:4) + for (i = 0; i < 10; i++) + { + r = r + 1; + p = q; + a[2+i] = p + q; + s = i * 10; + } + #pragma omp target teams distribute simd device (n + 1) \ + if (n != 6)map (from: n) map (alloc: a[2:o-2]) default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) collapse (2) \ + lastprivate (s) num_teams (n + 4) safelen(8) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + a[2+i*10+j] = p + q; + s = i * 10 + j; + } + #pragma omp target teams distribute simd device (n + 1) \ + if (n != 6)map (from: n) map (alloc: a[2:o-2]) default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) lastprivate (s) \ + num_teams (n + 4) safelen(16) linear(i:1) aligned (pp:4) + for (i = 0; i < 10; i++) + { + r = r + 1; + p = q; + a[2+i] = p + q; + s = i * 10; + } + #pragma omp target device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) + #pragma omp teams num_teams (n + 4) thread_limit (n * 2) default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + } + #pragma omp target device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) + #pragma omp teams distribute num_teams (n + 4) collapse (2) default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + } + #pragma omp target device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) + #pragma omp teams distribute num_teams (n + 4) default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + } + #pragma omp target device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) + #pragma omp teams distribute parallel for num_teams (n + 4) if (n != 6) \ + default(shared) private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) collapse (2) \ + num_threads (n + 4) proc_bind (spread) lastprivate (s) \ + ordered schedule (static, 8) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + #pragma omp ordered + p = q; + s = i * 10 + j; + } + #pragma omp target device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) + #pragma omp teams distribute parallel for num_teams (n + 4) if (n != 6) \ + default(shared) private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) num_threads (n + 4) \ + proc_bind (master) lastprivate (s) ordered schedule (static, 8) + for (i = 0; i < 10; i++) + { + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + } + #pragma omp ordered + p = q; + s = i * 10; + } + #pragma omp target device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) + #pragma omp teams distribute parallel for simd if (n != 6)default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) collapse (2) \ + num_threads (n + 4) proc_bind (spread) lastprivate (s) \ + schedule (static, 8) num_teams (n + 4) safelen(8) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + a[2+i*10+j] = p + q; + s = i * 10 + j; + } + #pragma omp target device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) + #pragma omp teams distribute parallel for simd if (n != 6)default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) num_threads (n + 4) \ + proc_bind (master) lastprivate (s) schedule (static, 8) \ + num_teams (n + 4) safelen(16) linear(i:1) aligned (pp:4) + for (i = 0; i < 10; i++) + { + r = r + 1; + p = q; + a[2+i] = p + q; + s = i * 10; + } + #pragma omp target device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) + #pragma omp teams distribute simd default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) collapse (2) \ + lastprivate (s) num_teams (n + 4) safelen(8) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + a[2+i*10+j] = p + q; + s = i * 10 + j; + } + #pragma omp target device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) + #pragma omp teams distribute simd default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + thread_limit (n * 2) dist_schedule (static, 4) lastprivate (s) \ + num_teams (n + 4) safelen(16) linear(i:1) aligned (pp:4) + for (i = 0; i < 10; i++) + { + r = r + 1; + p = q; + a[2+i] = p + q; + s = i * 10; + } + #pragma omp target teams device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) \ + num_teams (n + 4) thread_limit (n * 2)default(shared) shared(n) \ + private (p) reduction (+: r) + #pragma omp distribute collapse (2) dist_schedule (static, 4) firstprivate (q) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + } + #pragma omp target teams device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) \ + num_teams (n + 4) thread_limit (n * 2) shared(n) private(p) reduction (+ : r) \ + default(shared) + #pragma omp distribute dist_schedule (static, 4) firstprivate (q) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + } + #pragma omp target teams device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) \ + num_teams (n + 4) thread_limit (n * 2) + #pragma omp distribute parallel for if (n != 6) \ + default(shared) private (p) firstprivate (q) shared (n) reduction (+: r) \ + collapse (2) dist_schedule (static, 4) \ + num_threads (n + 4) proc_bind (spread) lastprivate (s) \ + ordered schedule (static, 8) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + #pragma omp ordered + p = q; + s = i * 10 + j; + } + #pragma omp target teams device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) \ + num_teams (n + 4) thread_limit (n * 2) + #pragma omp distribute parallel for if (n != 6) \ + default(shared) private (p) firstprivate (q) shared (n) reduction (+: r) \ + num_threads (n + 4) dist_schedule (static, 4) \ + proc_bind (master) lastprivate (s) ordered schedule (static, 8) + for (i = 0; i < 10; i++) + { + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + } + #pragma omp ordered + p = q; + s = i * 10; + } + #pragma omp target teams device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) \ + num_teams (n + 4) thread_limit (n * 2) + #pragma omp distribute parallel for simd if (n != 6)default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + collapse (2) dist_schedule (static, 4) \ + num_threads (n + 4) proc_bind (spread) lastprivate (s) \ + schedule (static, 8) safelen(8) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + a[2+i*10+j] = p + q; + s = i * 10 + j; + } + #pragma omp target teams device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) \ + num_teams (n + 4) thread_limit (n * 2) + #pragma omp distribute parallel for simd if (n != 6)default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + num_threads (n + 4) dist_schedule (static, 4) \ + proc_bind (master) lastprivate (s) schedule (static, 8) \ + safelen(16) linear(i:1) aligned (pp:4) + for (i = 0; i < 10; i++) + { + r = r + 1; + p = q; + a[2+i] = p + q; + s = i * 10; + } + #pragma omp target teams device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) \ + num_teams (n + 4) thread_limit (n * 2) default(shared) shared(n) private(p) \ + reduction(+:r) + #pragma omp distribute simd private (p) firstprivate (q) reduction (+: r) \ + collapse (2) dist_schedule (static, 4) lastprivate (s) safelen(8) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + a[2+i*10+j] = p + q; + s = i * 10 + j; + } + #pragma omp target teams device (n + 1) if (n != 6)map(from:n) map(alloc:a[2:o-2]) \ + num_teams (n + 4) thread_limit (n * 2) default(shared) shared(n) private(p) \ + reduction(+:r) + #pragma omp distribute simd private (p) firstprivate (q) reduction (+: r) \ + lastprivate (s) dist_schedule (static, 4) safelen(16) linear(i:1) aligned (pp:4) + for (i = 0; i < 10; i++) + { + r = r + 1; + p = q; + a[2+i] = p + q; + s = i * 10; + } + } +} + +int q, i, j; + +void +test2 (int n, int o, int p, int r, int s, int *pp) +{ + int a[o]; + #pragma omp distribute collapse (2) dist_schedule (static, 4) firstprivate (q) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + } + #pragma omp distribute dist_schedule (static, 4) firstprivate (q) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + } + #pragma omp distribute parallel for if (n != 6) \ + default(shared) private (p) firstprivate (q) shared (n) reduction (+: r) \ + collapse (2) dist_schedule (static, 4) \ + num_threads (n + 4) proc_bind (spread) lastprivate (s) \ + ordered schedule (static, 8) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + #pragma omp ordered + p = q; + s = i * 10 + j; + } + #pragma omp distribute parallel for if (n != 6) \ + default(shared) private (p) firstprivate (q) shared (n) reduction (+: r) \ + num_threads (n + 4) dist_schedule (static, 4) \ + proc_bind (master) lastprivate (s) ordered schedule (static, 8) + for (i = 0; i < 10; i++) + { + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + dosomething (a, n, p + q); + } + #pragma omp ordered + p = q; + s = i * 10; + } + #pragma omp distribute parallel for simd if (n != 6)default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + collapse (2) dist_schedule (static, 4) \ + num_threads (n + 4) proc_bind (spread) lastprivate (s) \ + schedule (static, 8) safelen(8) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + a[2+i*10+j] = p + q; + s = i * 10 + j; + } + #pragma omp distribute parallel for simd if (n != 6)default(shared) \ + private (p) firstprivate (q) shared (n) reduction (+: r) \ + num_threads (n + 4) dist_schedule (static, 4) \ + proc_bind (master) lastprivate (s) schedule (static, 8) \ + safelen(16) linear(i:1) aligned (pp:4) + for (i = 0; i < 10; i++) + { + r = r + 1; + p = q; + a[2+i] = p + q; + s = i * 10; + } + #pragma omp distribute simd private (p) firstprivate (q) reduction (+: r) \ + collapse (2) dist_schedule (static, 4) lastprivate (s) safelen(8) + for (i = 0; i < 10; i++) + for (j = 0; j < 10; j++) + { + r = r + 1; + p = q; + a[2+i*10+j] = p + q; + s = i * 10 + j; + } + #pragma omp distribute simd private (p) firstprivate (q) reduction (+: r) \ + lastprivate (s) dist_schedule (static, 4) safelen(16) linear(i:1) aligned (pp:4) + for (i = 0; i < 10; i++) + { + r = r + 1; + p = q; + a[2+i] = p + q; + s = i * 10; + } +} diff --git a/gcc/testsuite/c-c++-common/pr46562-2.c b/gcc/testsuite/c-c++-common/pr46562-2.c index 45bf5cf7195..e64432c27df 100644 --- a/gcc/testsuite/c-c++-common/pr46562-2.c +++ b/gcc/testsuite/c-c++-common/pr46562-2.c @@ -9,5 +9,5 @@ int foo(void) return *p; } -/* { dg-final { scan-tree-dump "= 0;" "fre1" } } */ +/* { dg-final { scan-tree-dump "return 0;" "fre1" } } */ /* { dg-final { cleanup-tree-dump "fre1" } } */ diff --git a/gcc/testsuite/g++.dg/abi/bitfield12.C b/gcc/testsuite/g++.dg/abi/bitfield12.C deleted file mode 100644 index 6cfda5d47df..00000000000 --- a/gcc/testsuite/g++.dg/abi/bitfield12.C +++ /dev/null @@ -1,5 +0,0 @@ -// { dg-options "-Wabi -fabi-version=1" } - -struct S { // { dg-warning "ABI" } - char c : 1024; // { dg-warning "width" } -}; diff --git a/gcc/testsuite/g++.dg/abi/bitfield5.C b/gcc/testsuite/g++.dg/abi/bitfield5.C deleted file mode 100644 index 53131401434..00000000000 --- a/gcc/testsuite/g++.dg/abi/bitfield5.C +++ /dev/null @@ -1,15 +0,0 @@ -// { dg-do compile } -// { dg-options "-Wabi -fabi-version=1" } -// { dg-options "-Wabi -fabi-version=1 -mno-ms-bitfields" { target i?86-*-* x86_64-*-* } } - -struct A { - virtual void f(); - int f1 : 1; -}; - -struct B : public A { - int f2 : 1; // { dg-warning "ABI" } - int : 0; - int f3 : 4; - int f4 : 3; -}; diff --git a/gcc/testsuite/g++.dg/abi/bitfield7.C b/gcc/testsuite/g++.dg/abi/bitfield7.C deleted file mode 100644 index b5b656ffa47..00000000000 --- a/gcc/testsuite/g++.dg/abi/bitfield7.C +++ /dev/null @@ -1,7 +0,0 @@ -// { dg-do compile } -// { dg-options "-Wabi -fabi-version=1" } - -union U { // { dg-warning "ABI" } - int i: 4096; // { dg-warning "exceeds" } -}; - diff --git a/gcc/testsuite/g++.dg/abi/cookie2.C b/gcc/testsuite/g++.dg/abi/cookie2.C deleted file mode 100644 index dc180453b70..00000000000 --- a/gcc/testsuite/g++.dg/abi/cookie2.C +++ /dev/null @@ -1,16 +0,0 @@ -// { dg-options "-fabi-version=1" } - -void *operator new[](__SIZE_TYPE__, void *); - -struct A { - ~A(){} -}; - -int main() -{ - A * a = (A*) new char[20]; - A * b = new(a) A[3]; - // In the 3.2 ABI, a cookie was allocated in this case. - if (a == b) - return 1; -} diff --git a/gcc/testsuite/g++.dg/abi/dtor2.C b/gcc/testsuite/g++.dg/abi/dtor2.C deleted file mode 100644 index 6b89cc8eae0..00000000000 --- a/gcc/testsuite/g++.dg/abi/dtor2.C +++ /dev/null @@ -1,14 +0,0 @@ -// { dg-do compile } -// { dg-options "-Wabi -fabi-version=1" } - -struct A { - virtual void a (); -}; - -struct B { - virtual ~B (); -}; - -struct C : public A, public B { // { dg-warning "virtual" } - virtual void c (); -}; diff --git a/gcc/testsuite/g++.dg/abi/empty6.C b/gcc/testsuite/g++.dg/abi/empty6.C deleted file mode 100644 index 1b14a6d03be..00000000000 --- a/gcc/testsuite/g++.dg/abi/empty6.C +++ /dev/null @@ -1,14 +0,0 @@ -// { dg-options "-Wabi -fabi-version=1" } - -struct A {}; - -struct B { - A a; // { dg-warning "empty" "" { xfail mmix-*-* } } - virtual void f () {} -} __attribute__((aligned(2 * sizeof (void *)))); -/* The preceding attribute is necessary on targets with - BIGGEST_ALIGNMENT <= POINTER_SIZE to trigger the warning, as - otherwise the offset of 'a' (i.e. POINTER_SIZE) is split into a - non-zero DECL_FIELD_OFFSET and a zero DECL_FIELD_BIT_OFFSET, - and then there is no discrepancy between DECL_FIELD_OFFSET and - byte_position to warn about. */ diff --git a/gcc/testsuite/g++.dg/abi/layout4.C b/gcc/testsuite/g++.dg/abi/layout4.C deleted file mode 100644 index da3c2f5d8c7..00000000000 --- a/gcc/testsuite/g++.dg/abi/layout4.C +++ /dev/null @@ -1,19 +0,0 @@ -// { dg-do run { target i?86-*-* x86_64-*-* } } -// { dg-require-effective-target ilp32 } -// { dg-options "-fabi-version=1" } - -struct C4 -{ - int b:30; - C4(){}; -}; - -struct C1: virtual C4 -{ - int i; -}; - -int main() { - if (sizeof (C1) != 12) - return 1; -} diff --git a/gcc/testsuite/g++.dg/abi/macro1.C b/gcc/testsuite/g++.dg/abi/macro1.C deleted file mode 100644 index 871208da3ad..00000000000 --- a/gcc/testsuite/g++.dg/abi/macro1.C +++ /dev/null @@ -1,5 +0,0 @@ -// { dg-options "-fabi-version=1" } - -#if __GXX_ABI_VERSION != 102 -#error "Incorrect value of __GXX_ABI_VERSION" -#endif diff --git a/gcc/testsuite/g++.dg/abi/mangle11.C b/gcc/testsuite/g++.dg/abi/mangle11.C deleted file mode 100644 index 722d43c85a8..00000000000 --- a/gcc/testsuite/g++.dg/abi/mangle11.C +++ /dev/null @@ -1,10 +0,0 @@ -// { dg-options "-Wabi -fabi-version=1" } - -template <typename Q> -void f (typename Q::X) {} // { dg-warning "mangle" } - -struct S { - typedef int X; -}; - -template void f<S> (int); // { dg-message "required" } diff --git a/gcc/testsuite/g++.dg/abi/mangle12.C b/gcc/testsuite/g++.dg/abi/mangle12.C deleted file mode 100644 index 92f49c22fdf..00000000000 --- a/gcc/testsuite/g++.dg/abi/mangle12.C +++ /dev/null @@ -1,11 +0,0 @@ -// { dg-options "-Wabi -fabi-version=1" } - -template <template <typename> class Q> -void f (typename Q<int>::X) {} // { dg-warning "mangle" } - -template <typename Q> -struct S { - typedef int X; -}; - -template void f<S> (int); // { dg-message "required" } diff --git a/gcc/testsuite/g++.dg/abi/mangle14.C b/gcc/testsuite/g++.dg/abi/mangle14.C deleted file mode 100644 index 2b38255ac0a..00000000000 --- a/gcc/testsuite/g++.dg/abi/mangle14.C +++ /dev/null @@ -1,13 +0,0 @@ -// { dg-do compile } -// { dg-options "-Wabi -fabi-version=1" } -// { dg-final { scan-assembler "_Z1g1SIXadsr1ANS0_1fIiEEivEE" } } - -struct A { - template <typename T> int f (); -}; - -typedef int (A::*P)(); - -template <P> struct S {}; - -void g (S<&A::f<int> >) {} // { dg-warning "mangle" } diff --git a/gcc/testsuite/g++.dg/abi/mangle17.C b/gcc/testsuite/g++.dg/abi/mangle17.C deleted file mode 100644 index f98e2717d84..00000000000 --- a/gcc/testsuite/g++.dg/abi/mangle17.C +++ /dev/null @@ -1,11 +0,0 @@ -// { dg-options "-Wabi -fabi-version=1" } - -enum E { e = 3 }; - -template <int I> struct S {}; - -template <int I> void f (S<I + e + int (3.7)>) {} // { dg-warning "mangle" } -template void f<7>(S<7 + e + int (3.7)>); // { dg-message "required" } - -template <int I> void g (S<I + e + int (3.7)>) {} // { dg-warning "mangle" } -template void g<7>(S<7 + e + int (3.7)>); // { dg-message "required" } diff --git a/gcc/testsuite/g++.dg/abi/mangle18-2.C b/gcc/testsuite/g++.dg/abi/mangle18-2.C deleted file mode 100644 index a231d495fef..00000000000 --- a/gcc/testsuite/g++.dg/abi/mangle18-2.C +++ /dev/null @@ -1,23 +0,0 @@ -// { dg-do compile } -// { dg-options "-fabi-version=1 -Wabi" } - -// Copyright (C) 2003 Free Software Foundation, Inc. -// Contributed by Nathan Sidwell 30 Nov 2003 <nathan@codesourcery.com> - -// PR 13241 -// mangled template arguments that are external objects incorrectly - -extern "C" void Foo (); -namespace NMS -{ - extern "C" int V; -} - -template <void (*)()> struct S {}; -template <int *> struct T {}; - -void f (S<Foo>){} // { dg-warning "mangled name" } -// { dg-final { scan-assembler "\n_?_Z1f1SIXadL3FooEEE\[: \t\n\]" } } - -void g (T<&NMS::V>){} // { dg-warning "mangled name" } -// { dg-final { scan-assembler "\n_?_Z1g1TIXadL_ZN3NMS1VEEEE\[: \t\n\]" } } diff --git a/gcc/testsuite/g++.dg/abi/mangle19-1.C b/gcc/testsuite/g++.dg/abi/mangle19-1.C index 1463d03f31d..a888173304b 100644 --- a/gcc/testsuite/g++.dg/abi/mangle19-1.C +++ b/gcc/testsuite/g++.dg/abi/mangle19-1.C @@ -1,5 +1,5 @@ // { dg-do compile } -// { dg-options "-fabi-version=2 -Wno-abi" } +// { dg-options "-fabi-version=2 -Wabi" } // Copyright (C) 2003 Free Software Foundation, Inc. // Contributed by Nathan Sidwell 15 Dec 2003 <nathan@codesourcery.com> @@ -9,5 +9,5 @@ extern int N; template <int &> struct S {}; -void n (S<N>) {} +void n (S<N>) {} // { dg-warning "mangle" } // { dg-final { scan-assembler "\n_?_Z1n1SILZ1NEE\[: \t\n\]" } } diff --git a/gcc/testsuite/g++.dg/abi/mangle19-2.C b/gcc/testsuite/g++.dg/abi/mangle19-2.C deleted file mode 100644 index f0855e69d34..00000000000 --- a/gcc/testsuite/g++.dg/abi/mangle19-2.C +++ /dev/null @@ -1,13 +0,0 @@ -// { dg-do compile } -// { dg-options "-fabi-version=1 -Wabi" } - -// Copyright (C) 2003 Free Software Foundation, Inc. -// Contributed by Nathan Sidwell 15 Dec 2003 <nathan@codesourcery.com> - -// PR 13242 -// mangled template arguments that are external objects incorrectly - -extern int N; -template <int &> struct S {}; -void n (S<N>) {} // { dg-warning "mangled name" } -// { dg-final { scan-assembler "\n_?_Z1n1SIXadL_Z1NEEE\[: \t\n\]" } } diff --git a/gcc/testsuite/g++.dg/abi/mangle20-2.C b/gcc/testsuite/g++.dg/abi/mangle20-2.C deleted file mode 100644 index 5ba6bac03a6..00000000000 --- a/gcc/testsuite/g++.dg/abi/mangle20-2.C +++ /dev/null @@ -1,16 +0,0 @@ -// { dg-do compile } -// { dg-options "-fabi-version=1 -Wabi" } - -// Copyright (C) 2003 Free Software Foundation, Inc. -// Contributed by Nathan Sidwell 15 Dec 2003 <nathan@codesourcery.com> - -// PR 9043 -// mangled array types in templates - -template <int I> void f(int (*)[2]) {} // { dg-warning "mangled name" } -template <int I> void g(int (*)[I+2]) {} - -template void f<1>(int (*)[2]); // { dg-message "required" } -// { dg-final { scan-assembler "\n_?_Z1fILi1EEvPALi2E_i\[: \t\n\]" } } -template void g<1>(int (*)[3]); -// { dg-final { scan-assembler "\n_?_Z1gILi1EEvPAplT_Li2E_i\[: \t\n\]" } } diff --git a/gcc/testsuite/g++.dg/abi/mangle3-2.C b/gcc/testsuite/g++.dg/abi/mangle3-2.C index ac85fb04569..538c5cbfae2 100644 --- a/gcc/testsuite/g++.dg/abi/mangle3-2.C +++ b/gcc/testsuite/g++.dg/abi/mangle3-2.C @@ -1,12 +1,12 @@ // Test mangling of type casts -// { dg-options "-fabi-version=0" } +// { dg-options "-fabi-version=0 -Wabi=5" } // { dg-do compile } template<int i> class A {}; template<bool b> class B {}; template<int i> void f(A<i> &, B<bool(i)> &) {} -template<int i> void g(A<i> &, B<static_cast<bool>(i)> &) {} +template<int i> void g(A<i> &, B<static_cast<bool>(i)> &) {} // { dg-warning "mangle" } int main() { diff --git a/gcc/testsuite/g++.dg/abi/mangle3.C b/gcc/testsuite/g++.dg/abi/mangle3.C index 5f44f767732..42f8deac537 100644 --- a/gcc/testsuite/g++.dg/abi/mangle3.C +++ b/gcc/testsuite/g++.dg/abi/mangle3.C @@ -1,12 +1,12 @@ // Test mangling of type casts -// { dg-options "-fabi-version=2" } +// { dg-options "-fabi-version=2 -Wabi" } // { dg-do compile } template<int i> class A {}; template<bool b> class B {}; template<int i> void f(A<i> &, B<bool(i)> &) {} -template<int i> void g(A<i> &, B<static_cast<bool>(i)> &) {} +template<int i> void g(A<i> &, B<static_cast<bool>(i)> &) {} // { dg-warning "mangle" } int main() { diff --git a/gcc/testsuite/g++.dg/abi/mangle45.C b/gcc/testsuite/g++.dg/abi/mangle45.C index 5e202a2f52b..bdedb0ab3b3 100644 --- a/gcc/testsuite/g++.dg/abi/mangle45.C +++ b/gcc/testsuite/g++.dg/abi/mangle45.C @@ -1,26 +1,26 @@ // Testcase for mangling of parameters used other than in a trailing return type // { dg-do compile { target c++11 } } -// { dg-options "-fabi-version=5" } +// { dg-options "-fabi-version=5 -Wabi=4" } -template<class T> void f(T p, decltype(p)) { } // L = 1 -template<class T> void g(T p, decltype(p) (*)()) { } // L = 1 +template<class T> void f(T p, decltype(p)) { } // L = 1 { dg-warning "mangle" } +template<class T> void g(T p, decltype(p) (*)()) { } // L = 1 { dg-warning "mangle" } // G++ incorrectly rejects these currently. // template<class T> void h(T p, auto (*)()->decltype(p)); // L = 1 // template<class T> void i(T p, auto (*)(T q)->decltype(q)); // L = 0 // template<class T> void j(T p, auto (*)(decltype(p))->T); // L = 2 -template<class T> void k(T p, int (*(*)(T* p))[sizeof(p)]) {} // L = 1 +template<class T> void k(T p, int (*(*)(T* p))[sizeof(p)]) {} // L = 1 { dg-warning "mangle" } int garg(); int (*karg (int*))[sizeof(int)]; int main() { - // { dg-final { scan-assembler "_Z1fIiEvT_DtfL0p_E" } } + // { dg-final { scan-assembler "\n_?_Z1fIiEvT_DtfL0p_E\[: \t\n\]" } } f (1,0); - // { dg-final { scan-assembler "_Z1gIiEvT_PFDtfL0p_EvE" } } + // { dg-final { scan-assembler "\n_?_Z1gIiEvT_PFDtfL0p_EvE\[: \t\n\]" } } g (1,garg); // h (1,0); // i (1,0); // j (1,0); - // { dg-final { scan-assembler "_Z1kIiEvT_PFPAszfL0p__iPS0_E" } } + // { dg-final { scan-assembler "\n_?_Z1kIiEvT_PFPAszfL0p__iPS0_E\[: \t\n\]" } } k (1,karg); } diff --git a/gcc/testsuite/g++.dg/abi/mangle49.C b/gcc/testsuite/g++.dg/abi/mangle49.C index 3795c556d0a..fae013a2635 100644 --- a/gcc/testsuite/g++.dg/abi/mangle49.C +++ b/gcc/testsuite/g++.dg/abi/mangle49.C @@ -1,10 +1,10 @@ // PR c++/49932 // { dg-do compile { target c++11 } } -// { dg-options "-fabi-version=0" } +// { dg-options "-fabi-version=0 -Wabi=2" } template < typename T > auto -f1( T x ) // ICE on here +f1( T x ) // { dg-warning "mangle" } -> typename decltype( x )::type {} template < typename T > @@ -19,5 +19,5 @@ void g() f2( S() ); } -// { dg-final { scan-assembler "_Z2f1I1SENDtfp_E4typeET_" } } -// { dg-final { scan-assembler "_Z2f2I1SENDTcvT__EE4typeES1_" } } +// { dg-final { scan-assembler "\n_?_Z2f1I1SENDtfp_E4typeET_\[: \t\n\]" } } +// { dg-final { scan-assembler "\n_?_Z2f2I1SENDTcvT__EE4typeES1_\[: \t\n\]" } } diff --git a/gcc/testsuite/g++.dg/abi/mangle52.C b/gcc/testsuite/g++.dg/abi/mangle52.C index 2c463415f1f..0b9a72fd217 100644 --- a/gcc/testsuite/g++.dg/abi/mangle52.C +++ b/gcc/testsuite/g++.dg/abi/mangle52.C @@ -1,13 +1,13 @@ -// { dg-options "-fabi-version=0" } +// { dg-options "-fabi-version=0 -Wabi=2" } template <unsigned int> struct helper {}; -// { dg-final { scan-assembler "_Z6check1IiEvP6helperIXszscT_Li1EEE" } } -template <class T> void check1( helper<sizeof(static_cast<T>(1))> * ) { } -// { dg-final { scan-assembler "_Z6check2IiXadL_Z1iEEEvP6helperIXszccPT_T0_EE" } } -template <class T, T* p> void check2( helper<sizeof(const_cast<T*>(p))> * ) { } -// { dg-final { scan-assembler "_Z6check3IiEvP6helperIXszrcPT_Li0EEE" } } +// { dg-final { scan-assembler "\n_?_Z6check1IiEvP6helperIXszscT_Li1EEE\[: \t\n\]" } } +template <class T> void check1( helper<sizeof(static_cast<T>(1))> * ) { } // { dg-warning "mangle" } +// { dg-final { scan-assembler "\n_?_Z6check2IiXadL_Z1iEEEvP6helperIXszccPT_T0_EE\[: \t\n\]" } } +template <class T, T* p> void check2( helper<sizeof(const_cast<T*>(p))> * ) { } // { dg-warning "mangle" } +// { dg-final { scan-assembler "\n_?_Z6check3IiEvP6helperIXszrcPT_Li0EEE\[: \t\n\]" } } template <class T> void check3( helper<sizeof(reinterpret_cast<T*>(0))> * ) { } -// { dg-final { scan-assembler "_Z6check4I1AXadL_Z1aEEEvP6helperIXszdcPT_T0_EE" } } +// { dg-final { scan-assembler "\n_?_Z6check4I1AXadL_Z1aEEEvP6helperIXszdcPT_T0_EE\[: \t\n\]" } } template <class T, T* p> void check4( helper<sizeof(dynamic_cast<T*>(p))> * ) { } struct A{} a; diff --git a/gcc/testsuite/g++.dg/abi/mangle54.C b/gcc/testsuite/g++.dg/abi/mangle54.C index 926275c8cbb..ba1d3bc3182 100644 --- a/gcc/testsuite/g++.dg/abi/mangle54.C +++ b/gcc/testsuite/g++.dg/abi/mangle54.C @@ -1,15 +1,15 @@ // { dg-do compile { target c++11 } } -// { dg-options "-fabi-version=0" } +// { dg-options "-fabi-version=0 -Wabi=2" } int i; // { dg-final { scan-assembler "_Z2f1IiEDTppfp_ET_" } } template <class T> auto f1 (T t) -> decltype(t++) { return i; } // { dg-final { scan-assembler "_Z2f2IiEDTpp_fp_ET_" } } -template <class T> auto f2 (T t) -> decltype(++t) { return i; } +template <class T> auto f2 (T t) -> decltype(++t) { return i; } // { dg-warning "mangle" } // { dg-final { scan-assembler "_Z2f3IiEDTmmfp_ET_" } } template <class T> auto f3 (T t) -> decltype(t--) { return i; } // { dg-final { scan-assembler "_Z2f4IiEDTmm_fp_ET_" } } -template <class T> auto f4 (T t) -> decltype(--t) { return i; } +template <class T> auto f4 (T t) -> decltype(--t) { return i; } // { dg-warning "mangle" } int main() { diff --git a/gcc/testsuite/g++.dg/abi/mangle57.C b/gcc/testsuite/g++.dg/abi/mangle57.C index cd59cb87b1e..46cf377ebc7 100644 --- a/gcc/testsuite/g++.dg/abi/mangle57.C +++ b/gcc/testsuite/g++.dg/abi/mangle57.C @@ -1,13 +1,13 @@ // { dg-do compile { target c++11 } } -// { dg-options "-fabi-version=0" } +// { dg-options "-fabi-version=0 -Wabi=2" } template<typename T> int cmp1(T a, T b); int cmp2(char a, char b); template<typename T, int (*cmp)(T, T)> struct A { }; -// { dg-final { scan-assembler "_Z1fIcEvR1AIT_X4cmp1EE" } } -template <typename T> void f (A<T,cmp1> &); -// { dg-final { scan-assembler "_Z1fIcEvR1AIT_L_Z4cmp2ccEE" } } -template <typename T> void f (A<T,cmp2> &); +// { dg-final { scan-assembler "\n_?_Z1fIcEvR1AIT_X4cmp1EE\[: \t\n\]" } } +template <typename T> void f (A<T,cmp1> &) {} +// { dg-final { scan-assembler "\n_?_Z1fIcEvR1AIT_L_Z4cmp2ccEE\[: \t\n\]" } } +template <typename T> void f (A<T,cmp2> &) {} // { dg-warning "mangle" } void g() { A<char,cmp1> a; diff --git a/gcc/testsuite/g++.dg/abi/mangle58.C b/gcc/testsuite/g++.dg/abi/mangle58.C index abcb3ca47ac..f9aadc2a900 100644 --- a/gcc/testsuite/g++.dg/abi/mangle58.C +++ b/gcc/testsuite/g++.dg/abi/mangle58.C @@ -1,5 +1,5 @@ // { dg-do compile { target c++11 } } -// { dg-options "-fabi-version=0" } +// { dg-options "-fabi-version=0 -Wabi=2" } template<typename T, int (*cmp)(T, T)> struct A { }; struct B { @@ -10,9 +10,9 @@ struct B { // { dg-final { scan-assembler "_ZN1B1gIcEEvR1AIT_XsrS_4cmp1EE" } } template <typename T> static void g (A<T,B::cmp1> &); // { dg-final { scan-assembler "_ZN1B1fIcEEvR1AIT_L_ZNS_4cmp2EccEE" } } - template <typename T> static void f (A<T,cmp2> &); + template <typename T> static void f (A<T,cmp2> &); // { dg-warning "mangle" } // { dg-final { scan-assembler "_ZN1B1gIcEEvR1AIT_L_ZNS_4cmp2EccEE" } } - template <typename T> static void g (A<T,B::cmp2> &); + template <typename T> static void g (A<T,B::cmp2> &); // { dg-warning "mangle" } }; void g() diff --git a/gcc/testsuite/g++.dg/abi/mangle62.C b/gcc/testsuite/g++.dg/abi/mangle62.C index 6dbfd7865cf..db541ca1902 100644 --- a/gcc/testsuite/g++.dg/abi/mangle62.C +++ b/gcc/testsuite/g++.dg/abi/mangle62.C @@ -2,10 +2,10 @@ // as a substitution candidate for a function type with function-cv-quals. // Test for the conformant behavior. -// { dg-options -fabi-version=0 } +// { dg-options "-fabi-version=0 -Wabi=7" } template <class T, class U> struct A { }; -// { dg-final { scan-assembler "_Z1fP1AIKFvvEFvvEE" } } -void f (A<void()const, void()> *){} -// { dg-final { scan-assembler "_Z1gP1AIFvvEKFvvEE" } } -void g (A<void(), void()const> *){} +// { dg-final { scan-assembler "\n_?_Z1fP1AIKFvvEFvvEE\[: \t\n\]" } } +void f (A<void()const, void()> *){} // { dg-warning "mangled name" } +// { dg-final { scan-assembler "\n_?_Z1gP1AIFvvEKFvvEE\[: \t\n\]" } } +void g (A<void(), void()const> *){} // { dg-warning "mangled name" } diff --git a/gcc/testsuite/g++.dg/abi/mangle62a.C b/gcc/testsuite/g++.dg/abi/mangle62a.C index fca1cb6c436..a48efd07ae7 100644 --- a/gcc/testsuite/g++.dg/abi/mangle62a.C +++ b/gcc/testsuite/g++.dg/abi/mangle62a.C @@ -2,10 +2,10 @@ // as a substitution candidate for a function type with function-cv-quals. // Test for that for backward compatibility. -// { dg-options -fabi-version=7 } +// { dg-options "-fabi-version=7 -Wabi" } template <class T, class U> struct A { }; -// { dg-final { scan-assembler "_Z1fP1AIKFvvES0_E" } } -void f (A<void()const, void()> *){} -// { dg-final { scan-assembler "_Z1gP1AIFvvEKS0_E" } } -void g (A<void(), void()const> *){} +// { dg-final { scan-assembler "\n_?_Z1fP1AIKFvvES0_E\[: \t\n\]" } } +void f (A<void()const, void()> *){} // { dg-warning "mangle" } +// { dg-final { scan-assembler "\n_?_Z1gP1AIFvvEKS0_E\[: \t\n\]" } } +void g (A<void(), void()const> *){} // { dg-warning "mangle" } diff --git a/gcc/testsuite/g++.dg/abi/scoped1.C b/gcc/testsuite/g++.dg/abi/scoped1.C new file mode 100644 index 00000000000..7589ed44066 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/scoped1.C @@ -0,0 +1,23 @@ +// { dg-do run { target c++11 } } +// { dg-options "-fabi-version=0 -Wabi=2" } + +enum class A: short { a1, a2, a3 }; +void f(int i, ...) +{ + __builtin_va_list ap; + __builtin_va_start (ap, i); + if (__builtin_va_arg (ap, A) != A::a1) __builtin_abort(); // { dg-warning "passed" } + if (__builtin_va_arg (ap, A) != A::a2) __builtin_abort(); // { dg-warning "passed" } + if (__builtin_va_arg (ap, A) != A::a3) __builtin_abort(); // { dg-warning "passed" } + if (__builtin_va_arg (ap, A) != A::a1) __builtin_abort(); // { dg-warning "passed" } + if (__builtin_va_arg (ap, A) != A::a2) __builtin_abort(); // { dg-warning "passed" } + if (__builtin_va_arg (ap, A) != A::a3) __builtin_abort(); // { dg-warning "passed" } + if (__builtin_va_arg (ap, A) != A::a1) __builtin_abort(); // { dg-warning "passed" } + if (__builtin_va_arg (ap, A) != A::a2) __builtin_abort(); // { dg-warning "passed" } + if (__builtin_va_arg (ap, A) != A::a3) __builtin_abort(); // { dg-warning "passed" } +} + +int main() +{ + f(9, A::a1, A::a2, A::a3, A::a1, A::a2, A::a3, A::a1, A::a2, A::a3); // { dg-warning "passed" } +} diff --git a/gcc/testsuite/g++.dg/abi/vbase10.C b/gcc/testsuite/g++.dg/abi/vbase10.C deleted file mode 100644 index b6e7f88fcaa..00000000000 --- a/gcc/testsuite/g++.dg/abi/vbase10.C +++ /dev/null @@ -1,14 +0,0 @@ -// { dg-do compile } -// -fpack-struct is necessary because the code below assumes the initial -// packing is larger than 1, which cannot ge guaranteed for all targets. -// { dg-options "-Wabi -fabi-version=1 -fpack-struct=8" } -// On ARM processors, the alignment of B will be 4 even though it -// contains only a single "char". That would avoids the situation -// that the warning below is designed to catch. We therefore -// explicitly set the default structure alignment to 1. -// { dg-options "-Wabi -fabi-version=1 -mstructure-size-boundary=8" { target arm*-*-* } } - -struct A { virtual void f(); char c1; }; -struct B { B(); char c2; }; -struct C : public A, public virtual B {}; // { dg-warning "ABI" } - diff --git a/gcc/testsuite/g++.dg/abi/vbase14.C b/gcc/testsuite/g++.dg/abi/vbase14.C deleted file mode 100644 index 320d5ba77dc..00000000000 --- a/gcc/testsuite/g++.dg/abi/vbase14.C +++ /dev/null @@ -1,6 +0,0 @@ -// { dg-options "-Wabi -fabi-version=1" } - -struct E1 {}; -struct E2 : public E1 {}; // { dg-warning "layout" } -struct E : public E1, public E2 {}; // { dg-warning "layout|ambiguity" } -struct N : public E { virtual void f () {} }; // { dg-warning "nearly" } diff --git a/gcc/testsuite/g++.dg/conversion/err-recover1.C b/gcc/testsuite/g++.dg/conversion/err-recover1.C index 97237893dc7..4773b1faebe 100644 --- a/gcc/testsuite/g++.dg/conversion/err-recover1.C +++ b/gcc/testsuite/g++.dg/conversion/err-recover1.C @@ -1,6 +1,6 @@ // PR c++/42219 -void foo(const void); // { dg-error "incomplete|const" } +void foo(const void); // { dg-error "invalid use of cv-qualified" } void bar() { diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-abi1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-abi1.C deleted file mode 100644 index 418a2029951..00000000000 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-abi1.C +++ /dev/null @@ -1,17 +0,0 @@ -// PR c++/47301 -// { dg-do compile { target c++11 } } -// { dg-options "-fabi-version=1" } - -struct A -{ - constexpr operator int () - { - return 1; - } -}; - -template < int > struct B -{ - static constexpr A a = A(); - int ar[a]; -}; diff --git a/gcc/testsuite/g++.dg/cpp0x/enum13.C b/gcc/testsuite/g++.dg/cpp0x/enum13.C index 5e4a532ce78..8335fadd78e 100644 --- a/gcc/testsuite/g++.dg/cpp0x/enum13.C +++ b/gcc/testsuite/g++.dg/cpp0x/enum13.C @@ -10,12 +10,10 @@ enum struct A : short { X }; void foo(int x, ...) { va_list vl; __builtin_va_start(vl, x); - enum A t = __builtin_va_arg(vl, enum A); // { dg-warning "promote" } + enum A t = __builtin_va_arg(vl, enum A); // { dg-warning "scoped|promote" } __builtin_va_end(vl); } int main() { - foo(0, A::X); // { dg-warning "will not promote" } + foo(0, A::X); // { dg-warning "scoped" } } - -// { dg-prune-output "note" } diff --git a/gcc/testsuite/g++.dg/cpp0x/using-enum-1.C b/gcc/testsuite/g++.dg/cpp0x/using-enum-1.C new file mode 100644 index 00000000000..9904d59aaaa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/using-enum-1.C @@ -0,0 +1,20 @@ +// PR c++/60265 +// { dg-do compile { target c++11 } } + +namespace A +{ + enum E { V }; + + using E::V; +} + +void foo() +{ + using A::E::V; +} + +using A::E::V; + +enum F { U }; + +using F::U; diff --git a/gcc/testsuite/g++.dg/cpp0x/using-enum-2.C b/gcc/testsuite/g++.dg/cpp0x/using-enum-2.C new file mode 100644 index 00000000000..0738c802b34 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/using-enum-2.C @@ -0,0 +1,20 @@ +// PR c++/60265 +// { dg-do compile { target c++11 } } + +namespace A +{ + enum class E { V }; + + using E::V; // { dg-error "not a namespace or unscoped enum" } +} + +void foo() +{ + using A::E::V; // { dg-error "not a namespace or unscoped enum" } +} + +using A::E::V; // { dg-error "not a namespace or unscoped enum" } + +enum class F { U }; + +using F::U; // { dg-error "not a namespace or unscoped enum" } diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/cdtor-1.C b/gcc/testsuite/g++.dg/debug/dwarf2/cdtor-1.C index e3bddab0e99..bfa5d9292f4 100644 --- a/gcc/testsuite/g++.dg/debug/dwarf2/cdtor-1.C +++ b/gcc/testsuite/g++.dg/debug/dwarf2/cdtor-1.C @@ -14,4 +14,4 @@ main() K k; } -// { dg-final {scan-assembler-times " DW_AT_\[MIPS_\]*linkage_name" 2 } } +// { dg-final {scan-assembler-times " DW_AT_\[MIPS_\]*linkage_name" 4 } } diff --git a/gcc/testsuite/g++.dg/other/void3.C b/gcc/testsuite/g++.dg/other/void3.C new file mode 100644 index 00000000000..3494d2aefdb --- /dev/null +++ b/gcc/testsuite/g++.dg/other/void3.C @@ -0,0 +1,4 @@ +// PR c++/33101 + +typedef void v; +typedef v (*pf)(v); // { dg-error "invalid use of typedef-name" } diff --git a/gcc/testsuite/g++.dg/parse/friend10.C b/gcc/testsuite/g++.dg/parse/friend10.C new file mode 100644 index 00000000000..16c2e0a7f36 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/friend10.C @@ -0,0 +1,9 @@ +// PR c++/19200 + +namespace N { + void S(); +} + +struct S { + friend void N::S(); +}; diff --git a/gcc/testsuite/g++.dg/parse/friend11.C b/gcc/testsuite/g++.dg/parse/friend11.C new file mode 100644 index 00000000000..61aae4ed63b --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/friend11.C @@ -0,0 +1,6 @@ +// PR c++/19200 + +struct S { + struct T{}; + template<typename> friend void S(T); +}; diff --git a/gcc/testsuite/g++.dg/parse/friend7.C b/gcc/testsuite/g++.dg/parse/friend7.C index 668fd35d37c..72ab430ef1b 100644 --- a/gcc/testsuite/g++.dg/parse/friend7.C +++ b/gcc/testsuite/g++.dg/parse/friend7.C @@ -17,16 +17,16 @@ struct B struct C { - friend int C (); // { dg-error "return type|in friend decl" } + friend int C (); friend int ~C (); // { dg-error "return type|in friend decl" } - friend int C (const C &); // { dg-error "return type|in friend decl" } + friend int C (const C &); }; struct D { - friend int D () {} // { dg-error "return type|in friend decl" } + friend int D () {} friend int ~D () {} // { dg-error "return type|in friend decl" } - friend int D (const D &) {} // { dg-error "return type|in friend decl" } + friend int D (const D &) {} }; struct E diff --git a/gcc/testsuite/g++.dg/parse/friend9.C b/gcc/testsuite/g++.dg/parse/friend9.C new file mode 100644 index 00000000000..dd6729f17a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/friend9.C @@ -0,0 +1,6 @@ +// PR c++/19200 + +struct S { + struct T{}; + friend void S(T); +}; diff --git a/gcc/testsuite/g++.dg/parse/pr34049.C b/gcc/testsuite/g++.dg/parse/pr34049.C new file mode 100644 index 00000000000..701a119ba13 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr34049.C @@ -0,0 +1,12 @@ +// PR c++/34049 + +struct foo +{ + int operator[](int) const { return 0; } +}; + +int main() +{ + (foo()[0]); + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/anonunion1.C b/gcc/testsuite/g++.dg/template/anonunion1.C index 89a8c5bec9c..ea17e5d5f90 100644 --- a/gcc/testsuite/g++.dg/template/anonunion1.C +++ b/gcc/testsuite/g++.dg/template/anonunion1.C @@ -1,6 +1,6 @@ // PR c++/47303 // { dg-do compile } -// { dg-options "-fabi-version=1" } + struct Z { diff --git a/gcc/testsuite/g++.dg/template/array1-1.C b/gcc/testsuite/g++.dg/template/array1-1.C deleted file mode 100644 index 97fe7cde25d..00000000000 --- a/gcc/testsuite/g++.dg/template/array1-1.C +++ /dev/null @@ -1,32 +0,0 @@ -// { dg-do compile } -// { dg-options "-fabi-version=1" } - -// Contributed by Nathan Sidwell 22 Dec 2003 <nathan@codesourcery.com> -// Origin: Roger Sayle <roger@eyesopen.com> - -// PR c++/12774 Array domains compared unequal - -void Foo(double r[3][3]) -{ -} - -void Baz() -{ - double m[3][3]; - Foo(m); -} - -template <class T> -void Bar() -{ - double m[3][3]; - Foo(m); -} - -int main() -{ - Baz(); - Bar<int>(); - return 0; -} - diff --git a/gcc/testsuite/g++.dg/template/array2-1.C b/gcc/testsuite/g++.dg/template/array2-1.C deleted file mode 100644 index 2980a1fd186..00000000000 --- a/gcc/testsuite/g++.dg/template/array2-1.C +++ /dev/null @@ -1,14 +0,0 @@ -// { dg-do compile } -// { dg-options "-fabi-version=1" } - -// Copyright (C) 2003 Free Software Foundation, Inc. -// Contributed by Nathan Sidwell 29 Dec 2003 <nathan@codesourcery.com> - -// PR c++/13494. ICE - -template<typename T> -int foo(int d[][4]) -{ - return d[0][0]; -} - diff --git a/gcc/testsuite/g++.dg/template/conv8.C b/gcc/testsuite/g++.dg/template/conv8.C deleted file mode 100644 index 01d415b3edd..00000000000 --- a/gcc/testsuite/g++.dg/template/conv8.C +++ /dev/null @@ -1,12 +0,0 @@ -// { dg-options "-fabi-version=1 -Wno-abi" } - -template <typename T> struct S { - struct I{}; - operator I* (); -}; - -template <typename T> struct S2 : S<T> { - operator typename S<T>::I* (); -}; - -template struct S2<int>; diff --git a/gcc/testsuite/g++.dg/template/ptrmem27.C b/gcc/testsuite/g++.dg/template/ptrmem27.C new file mode 100644 index 00000000000..8c63f9c2974 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem27.C @@ -0,0 +1,22 @@ +// PR c++/61500 + +struct X { + int i; + int j; + + int foo(int X::* ptr); + + template <int X::* ptr> + int bar(); +}; + +int X::foo(int X::* ptr) { + int* p = &(this->*ptr); // OK. + return *p; +} + +template <int X::* ptr> +int X::bar() { + int* p = &(this->*ptr); // gcc 4.9.0: OK in C++98 mode, fails in C++11 mode. + return *p; +} diff --git a/gcc/testsuite/g++.dg/template/ptrmem28.C b/gcc/testsuite/g++.dg/template/ptrmem28.C new file mode 100644 index 00000000000..037996087b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem28.C @@ -0,0 +1,10 @@ +// PR c++/61488 + +struct A { + typedef int (A::*cont_func)(); + template <A::cont_func> void wait(int); + int notify(); + + void fix() { wait<&A::notify>(0); } // OK + template <int> void repair() { wait<&A::notify>(0); } +}; diff --git a/gcc/testsuite/g++.dg/template/qualttp17.C b/gcc/testsuite/g++.dg/template/qualttp17.C index f492ced8c85..fea8b3df955 100644 --- a/gcc/testsuite/g++.dg/template/qualttp17.C +++ b/gcc/testsuite/g++.dg/template/qualttp17.C @@ -1,7 +1,7 @@ // Copyright (C) 2001 Free Software Foundation // Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> // { dg-do compile } -// { dg-options "-fno-inline -fabi-version=1 -Wno-abi" } +// { dg-options "-fno-inline" } struct A { @@ -22,4 +22,4 @@ int main() f<A>(x); } -// { dg-final { scan-assembler "\n_?_Z1fI1AEv1XIN1T1BEE\[: \t\n\]" } } +// { dg-final { scan-assembler "\n_?_Z1fI1AEv1XINT_1BEE\[: \t\n\]" } } diff --git a/gcc/testsuite/g++.dg/torture/pr61482.C b/gcc/testsuite/g++.dg/torture/pr61482.C new file mode 100644 index 00000000000..1e186cc5ed6 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr61482.C @@ -0,0 +1,29 @@ +// { dg-do compile } + +class A +{ +public: + int m_fn1 (); +}; +class B +{ + void m_fn2 (const int &p1); + A mThebesLayerDataStack; +}; +int b, c; +void B::m_fn2 (const int &p1) +{ + if (c && b) + { + int i; + i = mThebesLayerDataStack.m_fn1 (); + for (; i >= 0;) + { + ++i; + break; + } + --i; + for (; i >= 0; --i) + mThebesLayerDataStack.m_fn1 (); + } +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr8781.C b/gcc/testsuite/g++.dg/tree-ssa/pr8781.C index bf754137232..19549c4f737 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr8781.C +++ b/gcc/testsuite/g++.dg/tree-ssa/pr8781.C @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O -fno-tree-sra -fdump-tree-fre1-details" } */ +/* { dg-options "-O -fno-tree-sra -fdump-tree-fre1" } */ int f(); @@ -24,5 +24,5 @@ int x() /* We should optimize this to a direct call. */ -/* { dg-final { scan-tree-dump "converting indirect call to function int f()" "fre1" } } */ +/* { dg-final { scan-tree-dump-times "= f \\(\\);" 1 "fre1" } } */ /* { dg-final { cleanup-tree-dump "fre1" } } */ diff --git a/gcc/testsuite/gcc.c-torture/execute/pr61306-1.c b/gcc/testsuite/gcc.c-torture/execute/pr61306-1.c new file mode 100644 index 00000000000..ebc90a32f98 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr61306-1.c @@ -0,0 +1,39 @@ +#ifdef __INT32_TYPE__ +typedef __INT32_TYPE__ int32_t; +#else +typedef int int32_t; +#endif + +#ifdef __UINT32_TYPE__ +typedef __UINT32_TYPE__ uint32_t; +#else +typedef unsigned uint32_t; +#endif + +#define __fake_const_swab32(x) ((uint32_t)( \ + (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ + (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ + (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ + (( (int32_t)(x) & (int32_t)0xff000000UL) >> 24))) + +/* Previous version of bswap optimization failed to consider sign extension + and as a result would replace an expression *not* doing a bswap by a + bswap. */ + +__attribute__ ((noinline, noclone)) uint32_t +fake_bswap32 (uint32_t in) +{ + return __fake_const_swab32 (in); +} + +int +main(void) +{ + if (sizeof (int32_t) * __CHAR_BIT__ != 32) + return 0; + if (sizeof (uint32_t) * __CHAR_BIT__ != 32) + return 0; + if (fake_bswap32 (0x87654321) != 0xffffff87) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr61306-2.c b/gcc/testsuite/gcc.c-torture/execute/pr61306-2.c new file mode 100644 index 00000000000..886ecfd29da --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr61306-2.c @@ -0,0 +1,40 @@ +#ifdef __INT16_TYPE__ +typedef __INT16_TYPE__ int16_t; +#else +typedef short int16_t; +#endif + +#ifdef __UINT32_TYPE__ +typedef __UINT32_TYPE__ uint32_t; +#else +typedef unsigned uint32_t; +#endif + +#define __fake_const_swab32(x) ((uint32_t)( \ + (((uint32_t) (x) & (uint32_t)0x000000ffUL) << 24) | \ + (((uint32_t)(int16_t)(x) & (uint32_t)0x00ffff00UL) << 8) | \ + (((uint32_t) (x) & (uint32_t)0x00ff0000UL) >> 8) | \ + (((uint32_t) (x) & (uint32_t)0xff000000UL) >> 24))) + + +/* Previous version of bswap optimization failed to consider sign extension + and as a result would replace an expression *not* doing a bswap by a + bswap. */ + +__attribute__ ((noinline, noclone)) uint32_t +fake_bswap32 (uint32_t in) +{ + return __fake_const_swab32 (in); +} + +int +main(void) +{ + if (sizeof (uint32_t) * __CHAR_BIT__ != 32) + return 0; + if (sizeof (int16_t) * __CHAR_BIT__ != 16) + return 0; + if (fake_bswap32 (0x81828384) != 0xff838281) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr61306-3.c b/gcc/testsuite/gcc.c-torture/execute/pr61306-3.c new file mode 100644 index 00000000000..6086e278627 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr61306-3.c @@ -0,0 +1,13 @@ +short a = -1; +int b; +char c; + +int +main () +{ + c = a; + b = a | c; + if (b != -1) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr61375.c b/gcc/testsuite/gcc.c-torture/execute/pr61375.c new file mode 100644 index 00000000000..89302b2a1d6 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr61375.c @@ -0,0 +1,35 @@ +#ifdef __UINT64_TYPE__ +typedef __UINT64_TYPE__ uint64_t; +#else +typedef unsigned long long uint64_t; +#endif + +#ifndef __SIZEOF_INT128__ +#define __int128 long long +#endif + +/* Some version of bswap optimization would ICE when analyzing a mask constant + too big for an uint64_t variable (PR210931). */ + +__attribute__ ((noinline, noclone)) uint64_t +uint128_central_bitsi_ior (unsigned __int128 in1, uint64_t in2) +{ + __int128 mask = (__int128)0xffff << 56; + return ((in1 & mask) >> 56) | in2; +} + +int +main(int argc) +{ + __int128 in = 1; +#ifdef __SIZEOF_INT128__ + in <<= 64; +#endif + if (sizeof (uint64_t) * __CHAR_BIT__ != 64) + return 0; + if (sizeof (unsigned __int128) * __CHAR_BIT__ != 128) + return 0; + if (uint128_central_bitsi_ior (in, 2) != 0x102) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/lto/pr61526_0.c b/gcc/testsuite/gcc.dg/lto/pr61526_0.c new file mode 100644 index 00000000000..6324c8c5bda --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr61526_0.c @@ -0,0 +1,6 @@ +/* { dg-lto-do link } */ +/* { dg-lto-options { { -fPIC -flto -flto-partition=1to1 } } } */ +/* { dg-extra-ld-options { -shared } } */ + +static void *master; +void *foo () { return master; } diff --git a/gcc/testsuite/gcc.dg/lto/pr61526_1.c b/gcc/testsuite/gcc.dg/lto/pr61526_1.c new file mode 100644 index 00000000000..bb2893b738d --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr61526_1.c @@ -0,0 +1,2 @@ +extern void *master; +void *bar () { return master; } diff --git a/gcc/testsuite/gcc.dg/torture/20140610-1.c b/gcc/testsuite/gcc.dg/torture/20140610-1.c new file mode 100644 index 00000000000..67cf8cd8de8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/20140610-1.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-additional-sources "20140610-2.c" } */ + +extern int a; +extern int *p; + +void test (void); + +int main () +{ + *p = 0; + a = 1; + test (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/20140610-2.c b/gcc/testsuite/gcc.dg/torture/20140610-2.c new file mode 100644 index 00000000000..766e5f23ea3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/20140610-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +extern void abort (void); + +int a; +int *p = &a; + +void test (void) +{ + if (a != 1) + abort (); +} diff --git a/gcc/testsuite/gcc.dg/torture/pr61452.c b/gcc/testsuite/gcc.dg/torture/pr61452.c new file mode 100644 index 00000000000..a62de30fd84 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr61452.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ + +int a, b; +short c, d; +char e, f; + +int +fn1 (int p1, char p2) +{ + return p1 || p2 ? 0 : p2; +} + +void +fn2 () +{ + for (; a;) + { + int g; + g = c = e; + for (; a;) + b = fn1 (g = d = e, g); + f = g; + } +} + +int +main () +{ + fn2 (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c index 5e6828b6f4f..80068b86de7 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -fstrict-aliasing -fdump-tree-fre1" } */ +/* { dg-options "-O1 -fstrict-aliasing -fdump-tree-cddce1" } */ __extension__ typedef __SIZE_TYPE__ size_t; extern void *xmalloc (size_t) __attribute__ ((__malloc__)); @@ -34,5 +34,5 @@ find_unreachable_blocks (void) able to determine that modifying e->dest->flags does not modify e or e->dest if we can assert strict-aliasing rules. The net result is that we only need one load of e->dest. */ -/* { dg-final { scan-tree-dump-times "->dest" 1 "fre1" } } */ -/* { dg-final { cleanup-tree-dump "fre1" } } */ +/* { dg-final { scan-tree-dump-times "->dest" 1 "cddce1" } } */ +/* { dg-final { cleanup-tree-dump "cddce1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c index d92b9b33afb..e6133325f40 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O -fdump-tree-copyprop1" } */ +/* { dg-options "-O -fdump-tree-cddce1 -fno-tree-fre" } */ typedef int v4si __attribute__ ((vector_size (4 * sizeof(int)))); int @@ -10,7 +10,7 @@ test (v4si *x, v4si *y) return z[2]; } -/* Optimization in forwprop1, cleanup in copyprop1. */ +/* Optimization in forwprop1, cleanup in cddce1. */ -/* { dg-final { scan-tree-dump-not "VEC_PERM_EXPR" "copyprop1" } } */ -/* { dg-final { cleanup-tree-dump "copyprop1" } } */ +/* { dg-final { scan-tree-dump-not "VEC_PERM_EXPR" "cddce1" } } */ +/* { dg-final { cleanup-tree-dump "cddce1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-24.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-24.c index c683218799d..833a1b99d38 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-24.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-24.c @@ -30,5 +30,5 @@ int bazzoo (void) return b.i; } -/* { dg-final { scan-tree-dump-times "= 0;" 5 "fre1" } } */ +/* { dg-final { scan-tree-dump-times "return 0;" 4 "fre1" } } */ /* { dg-final { cleanup-tree-dump "fre1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-25.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-25.c index e7723f9bc35..5317a18c5f6 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-25.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-25.c @@ -14,5 +14,5 @@ int foo (struct X *p) /* We should optimize this to return 0. */ -/* { dg-final { scan-tree-dump "= 0;" "fre1" } } */ +/* { dg-final { scan-tree-dump "return 0;" "fre1" } } */ /* { dg-final { cleanup-tree-dump "fre1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c index 537fd5a6bcb..ad4f1d08607 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c @@ -23,6 +23,6 @@ bar (_Complex float x) return z; } -/* We should CSE all the way to replace the final assignment to z with x. */ -/* { dg-final { scan-tree-dump-times "with x_1\\\(D\\\) in z" 3 "fre1" } } */ +/* We should CSE all the way to replace the return value with x. */ +/* { dg-final { scan-tree-dump-times "return x_\\d\+\\(D\\);" 2 "fre1" } } */ /* { dg-final { cleanup-tree-dump "fre1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-39.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-39.c index a30926caccd..4c5ed0b7895 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-39.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-39.c @@ -15,5 +15,5 @@ int foo (int i) /* We should be able to value-number the final assignment to k to 1. */ -/* { dg-final { scan-tree-dump "k_. = 1;" "fre1" } } */ +/* { dg-final { scan-tree-dump "return 1;" "fre1" } } */ /* { dg-final { cleanup-tree-dump "fre1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-12.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-12.c new file mode 100644 index 00000000000..e0d93a993d2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-12.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-lim1" } */ + +int a[1024]; + +void foo (int x, int z) +{ + int i; + int y = -x; + for (i = 0; i < 1024; ++i) + a[i] = x ? y : z; +} + +void bar (int x, int z) +{ + int j; + for (j = 0; j < 1024; ++j) + { + int i; + int y = -j + z; + for (i = 0; i < 1024; ++i) + a[i] = x ? y : j; + } +} + +/* { dg-final { scan-tree-dump-times "!= 0 ? " 2 "lim1" } } */ +/* { dg-final { cleanup-tree-dump "lim1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-16.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-16.c index b087dc1b45c..7bc1dd3aab7 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-16.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-16.c @@ -11,5 +11,5 @@ int foo(int k, int *x) } while (++j<k); return res; } -/* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "pre"} } */ +/* { dg-final { scan-tree-dump-times "Eliminated: 2" 1 "pre"} } */ /* { dg-final { cleanup-tree-dump "pre" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp35.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp35.c index 6402f4d2228..06b567d43e3 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp35.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp35.c @@ -11,5 +11,5 @@ int test1(int i, int k) return 1; } -/* { dg-final { scan-tree-dump-not "j_.* == 10" "vrp1" } } */ +/* { dg-final { scan-tree-dump "Folding predicate j_.* == 10 to 0" "vrp1" } } */ /* { dg-final { cleanup-tree-dump "vrp1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp36.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp36.c index de300d7276b..9d61960c7ae 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp36.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp36.c @@ -8,5 +8,5 @@ int foo(int i) return 1; } -/* { dg-final { scan-tree-dump-not "i_.* == 1" "vrp1" } } */ +/* { dg-final { scan-tree-dump "Folding predicate i_.* == 1 to 0" "vrp1" } } */ /* { dg-final { cleanup-tree-dump "vrp1" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/nodump-forwprop-22.c b/gcc/testsuite/gcc.dg/vect/nodump-forwprop-22.c index 526e70b1b88..6d33f006a73 100644 --- a/gcc/testsuite/gcc.dg/vect/nodump-forwprop-22.c +++ b/gcc/testsuite/gcc.dg/vect/nodump-forwprop-22.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ /* { dg-require-effective-target vect_double } */ /* { dg-require-effective-target vect_perm } */ -/* { dg-additional-options "-fdump-tree-copyprop1" } */ +/* { dg-additional-options "-fdump-tree-cddce1 -fno-tree-fre" } */ typedef double vec __attribute__((vector_size (2 * sizeof (double)))); void f (vec *px, vec *y, vec *z) @@ -13,8 +13,8 @@ void f (vec *px, vec *y, vec *z) *z = t2; } -/* Optimization in forwprop1, cleanup in copyprop1. */ +/* Optimization in forwprop1, cleanup in cddce1. */ -/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 1 "copyprop1" } } */ -/* { dg-final { scan-tree-dump-not "BIT_FIELD_REF" "copyprop1" } } */ -/* { dg-final { cleanup-tree-dump "copyprop1" } } */ +/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 1 "cddce1" } } */ +/* { dg-final { scan-tree-dump-not "BIT_FIELD_REF" "cddce1" } } */ +/* { dg-final { cleanup-tree-dump "cddce1" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr52252-st.c b/gcc/testsuite/gcc.dg/vect/pr52252-st.c new file mode 100644 index 00000000000..e7161f73f86 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr52252-st.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-mssse3" { target { i?86-*-* x86_64-*-* } } } */ + +#define byte unsigned char + +void +matrix_mul (byte *in, byte *out, int size) +{ + int i; + for (i = 0; i < size; i++) + { + out[0] = in[0] + in[1] + in[3]; + out[1] = in[0] + in[2] + in[4]; + out[2] = in[1] + in[2] + in[4]; + in += 4; + out += 3; + } +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-singleton_1.c b/gcc/testsuite/gcc.dg/vect/vect-singleton_1.c new file mode 100644 index 00000000000..6c2ff49cdab --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-singleton_1.c @@ -0,0 +1,38 @@ +/* PR target/59843 ICE on function taking/returning vector of one float64_t. */ + +/* { dg-do compile } */ +/* { dg-options "-Warray-bounds -O2 -fno-inline -std=c99" } */ + +#define TEST(BASETYPE, VECTYPE, SUFFIX) \ + typedef BASETYPE VECTYPE \ + __attribute__ ((__vector_size__ (sizeof (BASETYPE)))); \ + VECTYPE \ + test_vadd_##SUFFIX (VECTYPE a, VECTYPE b) \ + { \ + return a + b; \ + } \ + \ + void \ + test_##SUFFIX (BASETYPE val) \ + { \ + VECTYPE var = { val }; \ + BASETYPE v0 = var[0]; \ + BASETYPE v1 = var[1]; /* { dg-warning "index value is out of bound" } */ \ + } + +TEST (double, float64x1_t, f64) + +/* Original bug was for above type; + in a nod to completeness, test other types too. */ + +TEST (long long, int64x1_t, s64) + +TEST (float, float32x1_t, f32) + +TEST (long, longx1_t, l) + +TEST (int, intx1_t, i) + +TEST (short, int16x1_t, s16) + +TEST (char, int8x1_t, s8) diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/type-def.h b/gcc/testsuite/gcc.target/aarch64/aapcs64/type-def.h index a95d06aa2ed..07e56fff857 100644 --- a/gcc/testsuite/gcc.target/aarch64/aapcs64/type-def.h +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/type-def.h @@ -34,6 +34,13 @@ struct hfa_fx2_t float b; }; +struct hfa_fx3_t +{ + float a; + float b; + float c; +}; + struct hfa_dx2_t { double a; diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-13.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-13.c new file mode 100644 index 00000000000..ae1e3ec45cf --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-13.c @@ -0,0 +1,59 @@ +/* Test AAPCS64 layout and __builtin_va_start. + + Pass named HFA/HVA argument on stack. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#ifndef IN_FRAMEWORK +#define AAPCS64_TEST_STDARG +#define TESTFILE "va_arg-13.c" + +struct float_float_t +{ + float a; + float b; +} float_float; + +union float_int_t +{ + float b8; + int b5; +} float_int; + +#define HAS_DATA_INIT_FUNC +void +init_data () +{ + float_float.a = 1.2f; + float_float.b = 2.2f; + + float_int.b8 = 4983.80f; +} + +#include "abitest.h" +#else + ARG (float, 1.0f, S0, 0) + ARG (float, 2.0f, S1, 1) + ARG (float, 3.0f, S2, 2) + ARG (float, 4.0f, S3, 3) + ARG (float, 5.0f, S4, 4) + ARG (float, 6.0f, S5, 5) + ARG (float, 7.0f, S6, 6) + ARG (struct float_float_t, float_float, STACK, 7) + ARG (int, 9, W0, 8) + ARG (int, 10, W1, 9) + ARG (int, 11, W2, 10) + ARG (int, 12, W3, 11) + ARG (int, 13, W4, 12) + ARG (int, 14, W5, 13) + ARG (int, 15, W6, LAST_NAMED_ARG_ID) + DOTS + /* Note on the reason of using 'X7' instead of 'W7' here: + Using 'X7' makes sure the test works in the big-endian mode. + According to PCS rules B.4 and C.10, the size of float_int is rounded + to 8 bytes and prepared in the register X7 as if loaded via LDR from + the memory, with the content of the other 4 bytes unspecified. The + test framework will only compare the 4 relavent bytes. */ + ANON (union float_int_t, float_int, X7, 15) + LAST_ANON (long long, 12683143434LL, STACK + 8, 16) +#endif diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-14.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-14.c new file mode 100644 index 00000000000..91080d5afa4 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-14.c @@ -0,0 +1,35 @@ +/* Test AAPCS64 layout and __builtin_va_start. + + Pass named HFA/HVA argument on stack. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#ifndef IN_FRAMEWORK +#define AAPCS64_TEST_STDARG +#define TESTFILE "va_arg-14.c" +#include "type-def.h" + +struct hfa_fx2_t hfa_fx2 = {1.2f, 2.2f}; +struct hfa_fx3_t hfa_fx3 = {3.2f, 4.2f, 5.2f}; +vf4_t float32x4 = {6.2f, 7.2f, 8.2f, 9.2f}; +vf4_t float32x4_2 = {10.2f, 11.2f, 12.2f, 13.2f}; + +#include "abitest.h" +#else + ARG (float, 1.0f, S0, 0) + ARG (float, 2.0f, S1, 1) + ARG (float, 3.0f, S2, 2) + ARG (float, 4.0f, S3, 3) + ARG (float, 5.0f, S4, 4) + ARG (float, 6.0f, S5, 5) + ARG (float, 7.0f, S6, 6) + ARG (struct hfa_fx3_t, hfa_fx3, STACK, 7) + /* Previous argument size has been rounded up to the nearest multiple of + 8 bytes. */ + ARG (struct hfa_fx2_t, hfa_fx2, STACK + 16, 8) + /* NSAA is rounded up to the nearest natural alignment of float32x4. */ + ARG (vf4_t, float32x4, STACK + 32, 9) + ARG (vf4_t, float32x4_2, STACK + 48, LAST_NAMED_ARG_ID) + DOTS + LAST_ANON (double, 123456789.987, STACK + 64, 11) +#endif diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-15.c b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-15.c new file mode 100644 index 00000000000..d8fdb322b2f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/va_arg-15.c @@ -0,0 +1,39 @@ +/* Test AAPCS64 layout and __builtin_va_start. + + Pass named __128int argument on stack. */ + +/* { dg-do run { target aarch64*-*-* } } */ + +#ifndef IN_FRAMEWORK +#define AAPCS64_TEST_STDARG +#define TESTFILE "va_arg-15.c" +#include "type-def.h" + +union int128_t qword; + +#define HAS_DATA_INIT_FUNC +void +init_data () +{ + /* Init signed quad-word integer. */ + qword.l64 = 0xfdb9753102468aceLL; + qword.h64 = 0xeca8642013579bdfLL; +} + +#include "abitest.h" +#else + ARG (int, 1, W0, 0) + ARG (int, 2, W1, 1) + ARG (int, 3, W2, 2) + ARG (int, 4, W3, 3) + ARG (int, 5, W4, 4) + ARG (int, 6, W5, 5) + ARG (int, 7, W6, 6) + ARG (__int128, qword.i, STACK, LAST_NAMED_ARG_ID) + DOTS +#ifndef __AAPCS64_BIG_ENDIAN__ + LAST_ANON (int, 8, STACK + 16, 8) +#else + LAST_ANON (int, 8, STACK + 20, 8) +#endif +#endif diff --git a/gcc/testsuite/gcc.target/aarch64/acle/acle.exp b/gcc/testsuite/gcc.target/aarch64/acle/acle.exp new file mode 100644 index 00000000000..e820f6c8c4d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/acle.exp @@ -0,0 +1,35 @@ +# Copyright (C) 2014 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 AArch64 target. +if ![istarget aarch64*-*-*] then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \ + "" "" + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.target/aarch64/acle/crc32b.c b/gcc/testsuite/gcc.target/aarch64/acle/crc32b.c new file mode 100644 index 00000000000..bf9a3d82a73 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/crc32b.c @@ -0,0 +1,15 @@ +/* Test the crc32b ACLE intrinsic. */ + +/* { dg-do assemble } */ +/* { dg-options "-save-temps -O2 -march=armv8-a+crc" } */ + +#include "arm_acle.h" + +uint32_t +test_crc32b (uint32_t arg0, uint8_t arg1) +{ + return __crc32b (arg0, arg1); +} + +/* { dg-final { scan-assembler "crc32b\tw..?, w..?, w..?\n" } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/acle/crc32cb.c b/gcc/testsuite/gcc.target/aarch64/acle/crc32cb.c new file mode 100644 index 00000000000..a5a39b139dc --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/crc32cb.c @@ -0,0 +1,15 @@ +/* Test the crc32cb ACLE intrinsic. */ + +/* { dg-do assemble } */ +/* { dg-options "-save-temps -O2 -march=armv8-a+crc" } */ + +#include "arm_acle.h" + +uint32_t +test_crc32cb (uint32_t arg0, uint8_t arg1) +{ + return __crc32cb (arg0, arg1); +} + +/* { dg-final { scan-assembler "crc32cb\tw..?, w..?, w..?\n" } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/acle/crc32cd.c b/gcc/testsuite/gcc.target/aarch64/acle/crc32cd.c new file mode 100644 index 00000000000..b50097a20d0 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/crc32cd.c @@ -0,0 +1,15 @@ +/* Test the crc32cd ACLE intrinsic. */ + +/* { dg-do assemble } */ +/* { dg-options "-save-temps -O2 -march=armv8-a+crc" } */ + +#include "arm_acle.h" + +uint32_t +test_crc32cd (uint32_t arg0, uint64_t arg1) +{ + return __crc32cd (arg0, arg1); +} + +/* { dg-final { scan-assembler "crc32cx\tw..?, w..?, x..?\n" } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/acle/crc32ch.c b/gcc/testsuite/gcc.target/aarch64/acle/crc32ch.c new file mode 100644 index 00000000000..523faa25be9 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/crc32ch.c @@ -0,0 +1,15 @@ +/* Test the crc32ch ACLE intrinsic. */ + +/* { dg-do assemble } */ +/* { dg-options "-save-temps -O2 -march=armv8-a+crc" } */ + +#include "arm_acle.h" + +uint32_t +test_crc32ch (uint32_t arg0, uint16_t arg1) +{ + return __crc32ch (arg0, arg1); +} + +/* { dg-final { scan-assembler "crc32ch\tw..?, w..?, w..?\n" } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/acle/crc32cw.c b/gcc/testsuite/gcc.target/aarch64/acle/crc32cw.c new file mode 100644 index 00000000000..531e6043209 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/crc32cw.c @@ -0,0 +1,15 @@ +/* Test the crc32cw ACLE intrinsic. */ + +/* { dg-do assemble } */ +/* { dg-options "-save-temps -O2 -march=armv8-a+crc" } */ + +#include "arm_acle.h" + +uint32_t +test_crc32cw (uint32_t arg0, uint32_t arg1) +{ + return __crc32cw (arg0, arg1); +} + +/* { dg-final { scan-assembler "crc32cw\tw..?, w..?, w..?\n" } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/acle/crc32d.c b/gcc/testsuite/gcc.target/aarch64/acle/crc32d.c new file mode 100644 index 00000000000..14fa627ba91 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/crc32d.c @@ -0,0 +1,15 @@ +/* Test the crc32d ACLE intrinsic. */ + +/* { dg-do assemble } */ +/* { dg-options "-save-temps -O2 -march=armv8-a+crc" } */ + +#include "arm_acle.h" + +uint32_t +test_crc32d (uint32_t arg0, uint64_t arg1) +{ + return __crc32d (arg0, arg1); +} + +/* { dg-final { scan-assembler "crc32x\tw..?, w..?, x..?\n" } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/acle/crc32h.c b/gcc/testsuite/gcc.target/aarch64/acle/crc32h.c new file mode 100644 index 00000000000..90819e615cb --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/crc32h.c @@ -0,0 +1,15 @@ +/* Test the crc32h ACLE intrinsic. */ + +/* { dg-do assemble } */ +/* { dg-options "-save-temps -O2 -march=armv8-a+crc" } */ + +#include "arm_acle.h" + +uint32_t +test_crc32h (uint32_t arg0, uint16_t arg1) +{ + return __crc32h (arg0, arg1); +} + +/* { dg-final { scan-assembler "crc32h\tw..?, w..?, w..?\n" } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/acle/crc32w.c b/gcc/testsuite/gcc.target/aarch64/acle/crc32w.c new file mode 100644 index 00000000000..006f17635b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/crc32w.c @@ -0,0 +1,15 @@ +/* Test the crc32w ACLE intrinsic. */ + +/* { dg-do assemble } */ +/* { dg-options "-save-temps -O2 -march=armv8-a+crc" } */ + +#include "arm_acle.h" + +uint32_t +test_crc32w (uint32_t arg0, uint32_t arg1) +{ + return __crc32w (arg0, arg1); +} + +/* { dg-final { scan-assembler "crc32w\tw..?, w..?, w..?\n" } } */ +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/avr/torture/pr61443.c b/gcc/testsuite/gcc.target/avr/torture/pr61443.c new file mode 100644 index 00000000000..12c6bca6663 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr61443.c @@ -0,0 +1,134 @@ +/* { dg-do run } */ +/* { dg-options "-std=gnu99" } */ + +#include <stdlib.h> +#include <stdarg.h> + +#define NC __attribute__((noinline,noclone)) + +void NC vfun (char n, ...) +{ + va_list ap; + + va_start (ap, n); + + switch (n) + { + default: + abort(); + case 1: + if (11 != va_arg (ap, int)) + abort(); + break; + case 2: + if (2222 != va_arg (ap, int)) + abort(); + break; + case 3: + if (333333 != va_arg (ap, __int24)) + abort(); + break; + case 4: + if (44444444 != va_arg (ap, long)) + abort(); + break; + case 8: + if (8888888888888888 != va_arg (ap, long long)) + abort(); + break; + } + + va_end (ap); +} + + +void NC boo_qi (const __flash char *p) +{ + vfun (1, *p); +} + +void NC boox_qi (const __memx char *p) +{ + vfun (1, *p); +} + +void NC boo_hi (const __flash int *p) +{ + vfun (2, *p); +} + +void NC boox_hi (const __memx int *p) +{ + vfun (2, *p); +} + +void NC boo_psi (const __flash __int24 *p) +{ + vfun (3, *p); +} + +void NC boox_psi (const __memx __int24 *p) +{ + vfun (3, *p); +} + +void NC boo_si (const __flash long *p) +{ + vfun (4, *p); +} + +void NC boox_si (const __memx long *p) +{ + vfun (4, *p); +} + +void NC boo_di (const __flash long long *p) +{ + vfun (8, *p); +} + +void NC boox_di (const __memx long long *p) +{ + vfun (8, *p); +} + +const __flash char f_qi = 11; +const __flash int f_hi = 2222; +const __flash __int24 f_psi = 333333; +const __flash long f_si = 44444444; +const __flash long long f_di = 8888888888888888; + +const __memx char x_qi = 11; +const __memx int x_hi = 2222; +const __memx __int24 x_psi = 333333; +const __memx long x_si = 44444444; +const __memx long long x_di = 8888888888888888; + +char r_qi = 11; +int r_hi = 2222; +__int24 r_psi = 333333; +long r_si = 44444444; +long long r_di = 8888888888888888; + +int main (void) +{ + boo_qi (&f_qi); + boo_hi (&f_hi); + boo_psi (&f_psi); + boo_si (&f_si); + boo_di (&f_di); + + boox_qi (&x_qi); + boox_hi (&x_hi); + boox_psi (&x_psi); + boox_si (&x_si); + boox_di (&x_di); + + boox_qi (&r_qi); + boox_hi (&r_hi); + boox_psi (&r_psi); + boox_si (&r_si); + boox_di (&r_di); + + exit (0); +} diff --git a/gcc/testsuite/gcc.target/i386/fuse-caller-save.c b/gcc/testsuite/gcc.target/i386/fuse-caller-save.c index 8618409c78a..4ec49952b27 100644 --- a/gcc/testsuite/gcc.target/i386/fuse-caller-save.c +++ b/gcc/testsuite/gcc.target/i386/fuse-caller-save.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fuse-caller-save" } */ +/* { dg-options "-O2 -fuse-caller-save -fomit-frame-pointer" } */ /* { dg-additional-options "-mregparm=1" { target ia32 } } */ /* Testing -fuse-caller-save optimization option. */ diff --git a/gcc/testsuite/gcc.target/i386/pr61446.c b/gcc/testsuite/gcc.target/i386/pr61446.c new file mode 100644 index 00000000000..fc32f63ee69 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr61446.c @@ -0,0 +1,14 @@ +/* PR rtl-optimization/61446 */ + +/* { dg-do compile { target { ia32 } } } */ +/* { dg-options "-O2 -march=corei7 -mfpmath=387" } */ + +unsigned long long +foo (float a) +{ + const double dfa = a; + const unsigned int hi = dfa / 0x1p32f; + const unsigned int lo = dfa - (double) hi * 0x1p32f; + + return ((unsigned long long) hi << (4 * (8))) | lo; +} diff --git a/gcc/testsuite/gcc.target/i386/xop-imul64-vector.c b/gcc/testsuite/gcc.target/i386/xop-imul64-vector.c index fbf605f31ec..fc8c8806f78 100644 --- a/gcc/testsuite/gcc.target/i386/xop-imul64-vector.c +++ b/gcc/testsuite/gcc.target/i386/xop-imul64-vector.c @@ -33,4 +33,3 @@ int main () /* { dg-final { scan-assembler "vpmulld" } } */ /* { dg-final { scan-assembler "vphadddq" } } */ -/* { dg-final { scan-assembler "vpmacsdql" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pack02.c b/gcc/testsuite/gcc.target/powerpc/pack02.c index 584d6c29205..f85d3ff00b0 100644 --- a/gcc/testsuite/gcc.target/powerpc/pack02.c +++ b/gcc/testsuite/gcc.target/powerpc/pack02.c @@ -2,6 +2,7 @@ /* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ /* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */ /* { dg-require-effective-target powerpc_fprs } */ +/* { dg-require-effective-target longdouble128 } */ /* { dg-options "-O2 -mhard-float" } */ #include <stddef.h> diff --git a/gcc/testsuite/gcc.target/powerpc/tfmode_off.c b/gcc/testsuite/gcc.target/powerpc/tfmode_off.c index e6578ef31a8..ea703f0ee0a 100644 --- a/gcc/testsuite/gcc.target/powerpc/tfmode_off.c +++ b/gcc/testsuite/gcc.target/powerpc/tfmode_off.c @@ -1,6 +1,7 @@ /* { dg-do assemble } */ /* { dg-skip-if "" { powerpc-ibm-aix* } { "*" } { "" } } */ /* { dg-skip-if "no TFmode" { powerpc-*-eabi* } { "*" } { "" } } */ +/* { dg-require-effective-target longdouble128 } */ /* { dg-options "-O2 -fno-align-functions -mtraceback=no -save-temps" } */ typedef float TFmode __attribute__ ((mode (TF))); diff --git a/gcc/testsuite/gfortran.dg/pr61335.f90 b/gcc/testsuite/gfortran.dg/pr61335.f90 index 7961f270515..c1dff97c9a5 100644 --- a/gcc/testsuite/gfortran.dg/pr61335.f90 +++ b/gcc/testsuite/gfortran.dg/pr61335.f90 @@ -45,8 +45,8 @@ CONTAINS LOGICAL :: failure failure=.FALSE. - unit_id=cp_units_none - kind_id=cp_ukind_none + unit_id=0 + kind_id=0 power=0 i_low=1 i_high=1 diff --git a/gcc/testsuite/gfortran.dg/system_clock_1.f90 b/gcc/testsuite/gfortran.dg/system_clock_1.f90 new file mode 100644 index 00000000000..41027deb28f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/system_clock_1.f90 @@ -0,0 +1,35 @@ +! { dg-do run } + + integer :: i, j, k + integer(kind=8) :: i8, j8, k8 + real :: x + double precision :: z + + call system_clock(i, j, k) + call system_clock(i, j, k8) + call system_clock(i, j8, k) + call system_clock(i, j8, k8) + call system_clock(i8, j, k) + call system_clock(i8, j, k8) + call system_clock(i8, j8, k) + call system_clock(i8, j8, k8) + + call system_clock(i, x, k) + call system_clock(i, x, k8) + call system_clock(i, x, k) + call system_clock(i, x, k8) + call system_clock(i8, x, k) + call system_clock(i8, x, k8) + call system_clock(i8, x, k) + call system_clock(i8, x, k8) + + call system_clock(i, z, k) + call system_clock(i, z, k8) + call system_clock(i, z, k) + call system_clock(i, z, k8) + call system_clock(i8, z, k) + call system_clock(i8, z, k8) + call system_clock(i8, z, k) + call system_clock(i8, z, k8) + + end diff --git a/gcc/testsuite/gfortran.dg/system_clock_2.f90 b/gcc/testsuite/gfortran.dg/system_clock_2.f90 new file mode 100644 index 00000000000..f7399afe2d1 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/system_clock_2.f90 @@ -0,0 +1,18 @@ +! { dg-do compile } +! { dg-options "-std=f95" } + + integer :: i, j, k + integer(kind=8) :: i8, j8, k8 + real :: x + double precision :: z + + call system_clock(i, j, k) + call system_clock(i, j, k8) ! { dg-error "has non-default kind" } + call system_clock(i, j8, k) ! { dg-error "has non-default kind" } + call system_clock(i8, j, k) ! { dg-error "has non-default kind" } + + call system_clock(i, x, k) ! { dg-error "Real COUNT_RATE argument" } + + call system_clock(i, z, k) ! { dg-error "Real COUNT_RATE argument" } + + end diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 5ec16088355..03ddab425f2 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -1862,6 +1862,15 @@ proc check_effective_target_large_double { } { }] } +# Return 1 if the target supports long double of 128 bits, +# 0 otherwise. + +proc check_effective_target_longdouble128 { } { + return [check_no_compiler_messages longdouble128 object { + int dummy[sizeof(long double) == 16 ? 1 : -1]; + }] +} + # Return 1 if the target supports double of 64 bits, # 0 otherwise. diff --git a/gcc/toplev.c b/gcc/toplev.c index fa4c74ef31f..fcd0e43fcd9 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1290,11 +1290,11 @@ process_options (void) flag_ira_region = optimize_size || !optimize ? IRA_REGION_ONE : IRA_REGION_MIXED; - if (flag_strict_volatile_bitfields > 0 && !abi_version_at_least (2)) + if (!abi_version_at_least (2)) { - warning (0, "-fstrict-volatile-bitfields disabled; " - "it is incompatible with ABI versions < 2"); - flag_strict_volatile_bitfields = 0; + /* -fabi-version=1 support was removed after GCC 4.9. */ + error ("%<-fabi-version=1%> is no longer supported"); + flag_abi_version = 2; } /* Unrolling all loops implies that standard loop unrolling must also diff --git a/gcc/tree-core.h b/gcc/tree-core.h index b1bc0cef9f0..aa7498b90e0 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -1012,7 +1012,7 @@ struct GTY(()) tree_base { SSA_NAME_IN_FREELIST in SSA_NAME - VAR_DECL_NONALIASED in + DECL_NONALIASED in VAR_DECL deprecated_flag: @@ -1452,15 +1452,12 @@ struct GTY(()) tree_decl_with_vis { unsigned dllimport_flag : 1; /* Don't belong to VAR_DECL exclusively. */ unsigned weak_flag : 1; - /* When SECTION_NAME is implied by -ffunction-section. */ - unsigned implicit_section_name_p : 1; unsigned seen_in_bind_expr : 1; unsigned comdat_flag : 1; + /* Used for FUNCTION_DECL, VAR_DECL and in C++ for TYPE_DECL. */ ENUM_BITFIELD(symbol_visibility) visibility : 2; unsigned visibility_specified : 1; - /* Belongs to VAR_DECL exclusively. */ - ENUM_BITFIELD(tls_model) tls_model : 3; /* Belong to FUNCTION_DECL exclusively. */ unsigned init_priority_p : 1; @@ -1472,7 +1469,7 @@ struct GTY(()) tree_decl_with_vis { unsigned cxx_destructor : 1; /* Belong to FUNCTION_DECL exclusively. */ unsigned final : 1; - /* 11 unused bits. */ + /* 15 unused bits. */ }; struct GTY(()) tree_var_decl { diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c index d7969bc266c..fe1e85d9014 100644 --- a/gcc/tree-emutls.c +++ b/gcc/tree-emutls.c @@ -250,10 +250,10 @@ get_emutls_init_templ_addr (tree decl) DECL_WEAK (to) = DECL_WEAK (decl); if (DECL_ONE_ONLY (decl)) { - make_decl_one_only (to, DECL_ASSEMBLER_NAME (to)); TREE_STATIC (to) = TREE_STATIC (decl); TREE_PUBLIC (to) = TREE_PUBLIC (decl); DECL_VISIBILITY (to) = DECL_VISIBILITY (decl); + make_decl_one_only (to, DECL_ASSEMBLER_NAME (to)); } else TREE_STATIC (to) = 1; @@ -263,12 +263,7 @@ get_emutls_init_templ_addr (tree decl) DECL_INITIAL (decl) = NULL; if (targetm.emutls.tmpl_section) - { - set_decl_section_name - (to, - build_string (strlen (targetm.emutls.tmpl_section), - targetm.emutls.tmpl_section)); - } + set_decl_section_name (to, targetm.emutls.tmpl_section); else set_decl_section_name (to, DECL_SECTION_NAME (decl)); @@ -295,7 +290,6 @@ new_emutls_decl (tree decl, tree alias_of) SET_DECL_ASSEMBLER_NAME (to, DECL_NAME (to)); - DECL_TLS_MODEL (to) = TLS_MODEL_EMULATED; DECL_ARTIFICIAL (to) = 1; DECL_IGNORED_P (to) = 1; TREE_READONLY (to) = 0; @@ -317,6 +311,8 @@ new_emutls_decl (tree decl, tree alias_of) if (DECL_ONE_ONLY (decl)) make_decl_one_only (to, DECL_ASSEMBLER_NAME (to)); + set_decl_tls_model (to, TLS_MODEL_EMULATED); + /* If we're not allowed to change the proxy object's alignment, pretend it has been set by the user. */ if (targetm.emutls.var_align_fixed) @@ -325,10 +321,7 @@ new_emutls_decl (tree decl, tree alias_of) /* If the target wants the control variables grouped, do so. */ if (!DECL_COMMON (to) && targetm.emutls.var_section) { - set_decl_section_name - (to, - build_string (strlen (targetm.emutls.var_section), - targetm.emutls.var_section)); + set_decl_section_name (to, targetm.emutls.var_section); } /* If this variable is defined locally, then we need to initialize the diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index deefa8b992a..e0de24cd0e2 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.c @@ -110,8 +110,7 @@ init_ic_make_global_vars (void) DECL_ARTIFICIAL (ic_void_ptr_var) = 1; DECL_INITIAL (ic_void_ptr_var) = NULL; if (targetm.have_tls) - DECL_TLS_MODEL (ic_void_ptr_var) = - decl_default_tls_model (ic_void_ptr_var); + set_decl_tls_model (ic_void_ptr_var, decl_default_tls_model (ic_void_ptr_var)); varpool_finalize_decl (ic_void_ptr_var); @@ -141,8 +140,7 @@ init_ic_make_global_vars (void) DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1; DECL_INITIAL (ic_gcov_type_ptr_var) = NULL; if (targetm.have_tls) - DECL_TLS_MODEL (ic_gcov_type_ptr_var) = - decl_default_tls_model (ic_gcov_type_ptr_var); + set_decl_tls_model (ic_gcov_type_ptr_var, decl_default_tls_model (ic_gcov_type_ptr_var)); varpool_finalize_decl (ic_gcov_type_ptr_var); } diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index e957f921141..6569c0664d2 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -729,14 +729,21 @@ determine_max_movement (gimple stmt, bool must_preserve_exec) } if (!add_dependency (val, lim_data, loop, false)) return false; - def_data = get_lim_data (SSA_NAME_DEF_STMT (val)); - if (def_data) + + gimple def_stmt = SSA_NAME_DEF_STMT (val); + if (gimple_bb (def_stmt) + && gimple_bb (def_stmt)->loop_father == loop) { - min_cost = MIN (min_cost, def_data->cost); - total_cost += def_data->cost; + def_data = get_lim_data (def_stmt); + if (def_data) + { + min_cost = MIN (min_cost, def_data->cost); + total_cost += def_data->cost; + } } } + min_cost = MIN (min_cost, total_cost); lim_data->cost += min_cost; if (gimple_phi_num_args (stmt) > 1) diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 73376bc8e75..36d68a884bb 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -3144,8 +3144,7 @@ discover_iteration_bound_by_body_walk (struct loop *loop) fprintf (dump_file, " Trying to walk loop body to reduce the bound.\n"); /* Sort the bounds in decreasing order. */ - qsort (bounds.address (), bounds.length (), - sizeof (widest_int), wide_int_cmp); + bounds.qsort (wide_int_cmp); /* For every basic block record the lowest bound that is guaranteed to terminate the loop. */ diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 1f011a6f937..066548d85be 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -1622,7 +1622,7 @@ make_pass_cse_sincos (gcc::context *ctxt) struct symbolic_number { uint64_t n; - int size; + tree type; tree base_addr; tree offset; HOST_WIDE_INT bytepos; @@ -1652,13 +1652,15 @@ do_shift_rotate (enum tree_code code, struct symbolic_number *n, int count) { + int bitsize = TYPE_PRECISION (n->type); + if (count % 8 != 0) return false; /* Zero out the extra bits of N in order to avoid them being shifted into the significant bits. */ - if (n->size < (int)sizeof (int64_t)) - n->n &= ((uint64_t)1 << (n->size * BITS_PER_UNIT)) - 1; + if (bitsize < 8 * (int)sizeof (int64_t)) + n->n &= ((uint64_t)1 << bitsize) - 1; switch (code) { @@ -1666,20 +1668,23 @@ do_shift_rotate (enum tree_code code, n->n <<= count; break; case RSHIFT_EXPR: + /* Arithmetic shift of signed type: result is dependent on the value. */ + if (!TYPE_UNSIGNED (n->type) && (n->n & (0xff << (bitsize - 8)))) + return false; n->n >>= count; break; case LROTATE_EXPR: - n->n = (n->n << count) | (n->n >> ((n->size * BITS_PER_UNIT) - count)); + n->n = (n->n << count) | (n->n >> (bitsize - count)); break; case RROTATE_EXPR: - n->n = (n->n >> count) | (n->n << ((n->size * BITS_PER_UNIT) - count)); + n->n = (n->n >> count) | (n->n << (bitsize - count)); break; default: return false; } /* Zero unused bits for size. */ - if (n->size < (int)sizeof (int64_t)) - n->n &= ((uint64_t)1 << (n->size * BITS_PER_UNIT)) - 1; + if (bitsize < 8 * (int)sizeof (int64_t)) + n->n &= ((uint64_t)1 << bitsize) - 1; return true; } @@ -1696,7 +1701,7 @@ verify_symbolic_number_p (struct symbolic_number *n, gimple stmt) if (TREE_CODE (lhs_type) != INTEGER_TYPE) return false; - if (TYPE_PRECISION (lhs_type) != n->size * BITS_PER_UNIT) + if (TYPE_PRECISION (lhs_type) != TYPE_PRECISION (n->type)) return false; return true; @@ -1708,20 +1713,25 @@ verify_symbolic_number_p (struct symbolic_number *n, gimple stmt) static bool init_symbolic_number (struct symbolic_number *n, tree src) { + int size; + n->base_addr = n->offset = n->alias_set = n->vuse = NULL_TREE; /* Set up the symbolic number N by setting each byte to a value between 1 and the byte size of rhs1. The highest order byte is set to n->size and the lowest order byte to 1. */ - n->size = TYPE_PRECISION (TREE_TYPE (src)); - if (n->size % BITS_PER_UNIT != 0) + n->type = TREE_TYPE (src); + size = TYPE_PRECISION (n->type); + if (size % BITS_PER_UNIT != 0) + return false; + size /= BITS_PER_UNIT; + if (size > (int)sizeof (uint64_t)) return false; - n->size /= BITS_PER_UNIT; - n->range = n->size; + n->range = size; n->n = CMPNOP; - if (n->size < (int)sizeof (int64_t)) - n->n &= ((uint64_t)1 << (n->size * BITS_PER_UNIT)) - 1; + if (size < (int)sizeof (int64_t)) + n->n &= ((uint64_t)1 << (size * BITS_PER_UNIT)) - 1; return true; } @@ -1858,12 +1868,12 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit) { case BIT_AND_EXPR: { - int i; + int i, size = TYPE_PRECISION (n->type) / BITS_PER_UNIT; uint64_t val = int_cst_value (rhs2); uint64_t tmp = val; /* Only constants masking full bytes are allowed. */ - for (i = 0; i < n->size; i++, tmp >>= BITS_PER_UNIT) + for (i = 0; i < size; i++, tmp >>= BITS_PER_UNIT) if ((tmp & 0xff) != 0 && (tmp & 0xff) != 0xff) return NULL_TREE; @@ -1879,11 +1889,22 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit) break; CASE_CONVERT: { - int type_size; + int type_size, old_type_size; + tree type; - type_size = TYPE_PRECISION (gimple_expr_type (stmt)); + type = gimple_expr_type (stmt); + type_size = TYPE_PRECISION (type); if (type_size % BITS_PER_UNIT != 0) return NULL_TREE; + if (type_size > (int)sizeof (uint64_t) * 8) + return NULL_TREE; + + /* Sign extension: result is dependent on the value. */ + old_type_size = TYPE_PRECISION (n->type); + if (!TYPE_UNSIGNED (n->type) + && type_size > old_type_size + && n->n & (0xff << (old_type_size - 8))) + return NULL_TREE; if (type_size / BITS_PER_UNIT < (int)(sizeof (int64_t))) { @@ -1891,9 +1912,9 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit) belonging to the target type. */ n->n &= ((uint64_t)1 << type_size) - 1; } - n->size = type_size / BITS_PER_UNIT; + n->type = type; if (!n->base_addr) - n->range = n->size; + n->range = type_size / BITS_PER_UNIT; } break; default: @@ -1906,7 +1927,7 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit) if (rhs_class == GIMPLE_BINARY_RHS) { - int i; + int i, size; struct symbolic_number n1, n2; uint64_t mask; tree source_expr2; @@ -1932,7 +1953,7 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit) if (!source_expr2) return NULL_TREE; - if (n1.size != n2.size) + if (TYPE_PRECISION (n1.type) != TYPE_PRECISION (n2.type)) return NULL_TREE; if (!n1.vuse != !n2.vuse || @@ -1998,8 +2019,9 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit) n->base_addr = n1.base_addr; n->offset = n1.offset; n->bytepos = n1.bytepos; - n->size = n1.size; - for (i = 0, mask = 0xff; i < n->size; i++, mask <<= BITS_PER_UNIT) + n->type = n1.type; + size = TYPE_PRECISION (n->type) / BITS_PER_UNIT; + for (i = 0, mask = 0xff; i < size; i++, mask <<= BITS_PER_UNIT) { uint64_t masked1, masked2; diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 89e94e93fdf..bca95ddb9bf 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -4012,120 +4012,93 @@ eliminate_dom_walker::before_dom_children (basic_block b) /* Mark new bb. */ el_avail_stack.safe_push (NULL_TREE); - /* If this block is not reachable do nothing. */ - edge_iterator ei; - edge e; - FOR_EACH_EDGE (e, ei, b->preds) - if (e->flags & EDGE_EXECUTABLE) - break; - if (!e) - return; + /* ??? If we do nothing for unreachable blocks then this will confuse + tailmerging. Eventually we can reduce its reliance on SCCVN now + that we fully copy/constant-propagate (most) things. */ for (gsi = gsi_start_phis (b); !gsi_end_p (gsi);) { - gimple stmt, phi = gsi_stmt (gsi); - tree sprime = NULL_TREE, res = PHI_RESULT (phi); - gimple_stmt_iterator gsi2; - - /* We want to perform redundant PHI elimination. Do so by - replacing the PHI with a single copy if possible. - Do not touch inserted, single-argument or virtual PHIs. */ - if (gimple_phi_num_args (phi) == 1 - || virtual_operand_p (res)) - { - gsi_next (&gsi); - continue; - } + gimple phi = gsi_stmt (gsi); + tree res = PHI_RESULT (phi); - sprime = eliminate_avail (res); - if (!sprime - || sprime == res) + if (virtual_operand_p (res)) { - eliminate_push_avail (res); gsi_next (&gsi); continue; } - else if (is_gimple_min_invariant (sprime)) - { - if (!useless_type_conversion_p (TREE_TYPE (res), - TREE_TYPE (sprime))) - sprime = fold_convert (TREE_TYPE (res), sprime); - } - if (dump_file && (dump_flags & TDF_DETAILS)) + tree sprime = eliminate_avail (res); + if (sprime + && sprime != res) { - fprintf (dump_file, "Replaced redundant PHI node defining "); - print_generic_expr (dump_file, res, 0); - fprintf (dump_file, " with "); - print_generic_expr (dump_file, sprime, 0); - fprintf (dump_file, "\n"); - } - - remove_phi_node (&gsi, false); + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Replaced redundant PHI node defining "); + print_generic_expr (dump_file, res, 0); + fprintf (dump_file, " with "); + print_generic_expr (dump_file, sprime, 0); + fprintf (dump_file, "\n"); + } - if (inserted_exprs - && !bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res)) - && TREE_CODE (sprime) == SSA_NAME) - gimple_set_plf (SSA_NAME_DEF_STMT (sprime), NECESSARY, true); - - if (!useless_type_conversion_p (TREE_TYPE (res), TREE_TYPE (sprime))) - sprime = fold_convert (TREE_TYPE (res), sprime); - stmt = gimple_build_assign (res, sprime); - gimple_set_plf (stmt, NECESSARY, gimple_plf (phi, NECESSARY)); - - gsi2 = gsi_after_labels (b); - gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT); - /* Queue the copy for eventual removal. */ - el_to_remove.safe_push (stmt); - /* If we inserted this PHI node ourself, it's not an elimination. */ - if (inserted_exprs - && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res))) - pre_stats.phis--; - else - pre_stats.eliminations++; - } + /* If we inserted this PHI node ourself, it's not an elimination. */ + if (inserted_exprs + && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res))) + pre_stats.phis--; + else + pre_stats.eliminations++; - for (gsi = gsi_start_bb (b); !gsi_end_p (gsi); gsi_next (&gsi)) - { - tree lhs = NULL_TREE; - tree rhs = NULL_TREE; + /* If we will propagate into all uses don't bother to do + anything. */ + if (may_propagate_copy (res, sprime)) + { + /* Mark the PHI for removal. */ + el_to_remove.safe_push (phi); + gsi_next (&gsi); + continue; + } - stmt = gsi_stmt (gsi); + remove_phi_node (&gsi, false); - if (gimple_has_lhs (stmt)) - lhs = gimple_get_lhs (stmt); + if (inserted_exprs + && !bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res)) + && TREE_CODE (sprime) == SSA_NAME) + gimple_set_plf (SSA_NAME_DEF_STMT (sprime), NECESSARY, true); - if (gimple_assign_single_p (stmt)) - rhs = gimple_assign_rhs1 (stmt); + if (!useless_type_conversion_p (TREE_TYPE (res), TREE_TYPE (sprime))) + sprime = fold_convert (TREE_TYPE (res), sprime); + gimple stmt = gimple_build_assign (res, sprime); + /* ??? It cannot yet be necessary (DOM walk). */ + gimple_set_plf (stmt, NECESSARY, gimple_plf (phi, NECESSARY)); - /* Lookup the RHS of the expression, see if we have an - available computation for it. If so, replace the RHS with - the available computation. */ - if (gimple_has_lhs (stmt) - && TREE_CODE (lhs) == SSA_NAME - && !gimple_has_volatile_ops (stmt)) - { - tree sprime; - gimple orig_stmt = stmt; + gimple_stmt_iterator gsi2 = gsi_after_labels (b); + gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT); + continue; + } - sprime = eliminate_avail (lhs); - /* If there is no usable leader mark lhs as leader for its value. */ - if (!sprime) - eliminate_push_avail (lhs); + eliminate_push_avail (res); + gsi_next (&gsi); + } + for (gsi = gsi_start_bb (b); !gsi_end_p (gsi); gsi_next (&gsi)) + { + tree sprime = NULL_TREE; + stmt = gsi_stmt (gsi); + tree lhs = gimple_get_lhs (stmt); + if (lhs && TREE_CODE (lhs) == SSA_NAME + && !gimple_has_volatile_ops (stmt) /* See PR43491. Do not replace a global register variable when it is a the RHS of an assignment. Do replace local register variables since gcc does not guarantee a local variable will be allocated in register. - Do not perform copy propagation or undo constant propagation. */ - if (gimple_assign_single_p (stmt) - && (TREE_CODE (rhs) == SSA_NAME - || is_gimple_min_invariant (rhs) - || (TREE_CODE (rhs) == VAR_DECL - && is_global_var (rhs) - && DECL_HARD_REGISTER (rhs)))) - continue; - + ??? The fix isn't effective here. This should instead + be ensured by not value-numbering them the same but treating + them like volatiles? */ + && !(gimple_assign_single_p (stmt) + && (TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL + && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt)) + && is_global_var (gimple_assign_rhs1 (stmt))))) + { + sprime = eliminate_avail (lhs); if (!sprime) { /* If there is no existing usable leader but SCCVN thinks @@ -4139,107 +4112,127 @@ eliminate_dom_walker::before_dom_children (basic_block b) && (sprime = eliminate_insert (&gsi, val)) != NULL_TREE) eliminate_push_avail (sprime); } - else if (is_gimple_min_invariant (sprime)) - { - /* If there is no existing leader but SCCVN knows this - value is constant, use that constant. */ - if (!useless_type_conversion_p (TREE_TYPE (lhs), - TREE_TYPE (sprime))) - sprime = fold_convert (TREE_TYPE (lhs), sprime); - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Replaced "); - print_gimple_expr (dump_file, stmt, 0, 0); - fprintf (dump_file, " with "); - print_generic_expr (dump_file, sprime, 0); - fprintf (dump_file, " in "); - print_gimple_stmt (dump_file, stmt, 0, 0); - } - pre_stats.eliminations++; - - tree vdef = gimple_vdef (stmt); - tree vuse = gimple_vuse (stmt); - propagate_tree_value_into_stmt (&gsi, sprime); - stmt = gsi_stmt (gsi); - update_stmt (stmt); - if (vdef != gimple_vdef (stmt)) - VN_INFO (vdef)->valnum = vuse; - - /* If we removed EH side-effects from the statement, clean - its EH information. */ - if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt)) + /* If this now constitutes a copy duplicate points-to + and range info appropriately. This is especially + important for inserted code. See tree-ssa-copy.c + for similar code. */ + if (sprime + && TREE_CODE (sprime) == SSA_NAME) + { + basic_block sprime_b = gimple_bb (SSA_NAME_DEF_STMT (sprime)); + if (POINTER_TYPE_P (TREE_TYPE (lhs)) + && SSA_NAME_PTR_INFO (lhs) + && !SSA_NAME_PTR_INFO (sprime)) { - bitmap_set_bit (need_eh_cleanup, - gimple_bb (stmt)->index); - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " Removed EH side-effects.\n"); + duplicate_ssa_name_ptr_info (sprime, + SSA_NAME_PTR_INFO (lhs)); + if (b != sprime_b) + mark_ptr_info_alignment_unknown + (SSA_NAME_PTR_INFO (sprime)); } - continue; + else if (!POINTER_TYPE_P (TREE_TYPE (lhs)) + && SSA_NAME_RANGE_INFO (lhs) + && !SSA_NAME_RANGE_INFO (sprime) + && b == sprime_b) + duplicate_ssa_name_range_info (sprime, + SSA_NAME_RANGE_TYPE (lhs), + SSA_NAME_RANGE_INFO (lhs)); } + /* Inhibit the use of an inserted PHI on a loop header when + the address of the memory reference is a simple induction + variable. In other cases the vectorizer won't do anything + anyway (either it's loop invariant or a complicated + expression). */ if (sprime - && sprime != lhs - && (rhs == NULL_TREE - || TREE_CODE (rhs) != SSA_NAME - || may_propagate_copy (rhs, sprime))) + && TREE_CODE (sprime) == SSA_NAME + && do_pre + && flag_tree_loop_vectorize + && loop_outer (b->loop_father) + && has_zero_uses (sprime) + && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime)) + && gimple_assign_load_p (stmt)) { - bool can_make_abnormal_goto - = is_gimple_call (stmt) - && stmt_can_make_abnormal_goto (stmt); - - gcc_assert (sprime != rhs); - - /* Inhibit the use of an inserted PHI on a loop header when - the address of the memory reference is a simple induction - variable. In other cases the vectorizer won't do anything - anyway (either it's loop invariant or a complicated - expression). */ - if (do_pre - && flag_tree_loop_vectorize - && gimple_assign_single_p (stmt) - && TREE_CODE (sprime) == SSA_NAME - && loop_outer (b->loop_father)) + gimple def_stmt = SSA_NAME_DEF_STMT (sprime); + basic_block def_bb = gimple_bb (def_stmt); + if (gimple_code (def_stmt) == GIMPLE_PHI + && b->loop_father->header == def_bb) { - gimple def_stmt = SSA_NAME_DEF_STMT (sprime); - basic_block def_bb = gimple_bb (def_stmt); - if (gimple_code (def_stmt) == GIMPLE_PHI - && b->loop_father->header == def_bb - && has_zero_uses (sprime)) + ssa_op_iter iter; + tree op; + bool found = false; + FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE) { - ssa_op_iter iter; - tree op; - bool found = false; - FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE) + affine_iv iv; + def_bb = gimple_bb (SSA_NAME_DEF_STMT (op)); + if (def_bb + && flow_bb_inside_loop_p (b->loop_father, def_bb) + && simple_iv (b->loop_father, + b->loop_father, op, &iv, true)) { - affine_iv iv; - def_bb = gimple_bb (SSA_NAME_DEF_STMT (op)); - if (def_bb - && flow_bb_inside_loop_p (b->loop_father, - def_bb) - && simple_iv (b->loop_father, - b->loop_father, op, &iv, true)) - { - found = true; - break; - } + found = true; + break; } - if (found) + } + if (found) + { + if (dump_file && (dump_flags & TDF_DETAILS)) { - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Not replacing "); - print_gimple_expr (dump_file, stmt, 0, 0); - fprintf (dump_file, " with "); - print_generic_expr (dump_file, sprime, 0); - fprintf (dump_file, " which would add a loop" - " carried dependence to loop %d\n", - b->loop_father->num); - } - continue; + fprintf (dump_file, "Not replacing "); + print_gimple_expr (dump_file, stmt, 0, 0); + fprintf (dump_file, " with "); + print_generic_expr (dump_file, sprime, 0); + fprintf (dump_file, " which would add a loop" + " carried dependence to loop %d\n", + b->loop_father->num); } + /* Don't keep sprime available. */ + sprime = NULL_TREE; } } + } + + if (sprime) + { + /* If we can propagate the value computed for LHS into + all uses don't bother doing anything with this stmt. */ + if (may_propagate_copy (lhs, sprime)) + { + /* Mark it for removal. */ + el_to_remove.safe_push (stmt); + + /* ??? Don't count copy/constant propagations. */ + if (gimple_assign_single_p (stmt) + && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME + || gimple_assign_rhs1 (stmt) == sprime)) + continue; + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Replaced "); + print_gimple_expr (dump_file, stmt, 0, 0); + fprintf (dump_file, " with "); + print_generic_expr (dump_file, sprime, 0); + fprintf (dump_file, " in all uses of "); + print_gimple_stmt (dump_file, stmt, 0, 0); + } + + pre_stats.eliminations++; + continue; + } + + /* If this is an assignment from our leader (which + happens in the case the value-number is a constant) + then there is nothing to do. */ + if (gimple_assign_single_p (stmt) + && sprime == gimple_assign_rhs1 (stmt)) + continue; + + /* Else replace its RHS. */ + bool can_make_abnormal_goto + = is_gimple_call (stmt) + && stmt_can_make_abnormal_goto (stmt); if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -4254,16 +4247,12 @@ eliminate_dom_walker::before_dom_children (basic_block b) if (TREE_CODE (sprime) == SSA_NAME) gimple_set_plf (SSA_NAME_DEF_STMT (sprime), NECESSARY, true); - /* We need to make sure the new and old types actually match, - which may require adding a simple cast, which fold_convert - will do for us. */ - if ((!rhs || TREE_CODE (rhs) != SSA_NAME) - && !useless_type_conversion_p (gimple_expr_type (stmt), - TREE_TYPE (sprime))) - sprime = fold_convert (gimple_expr_type (stmt), sprime); pre_stats.eliminations++; - + gimple orig_stmt = stmt; + if (!useless_type_conversion_p (TREE_TYPE (lhs), + TREE_TYPE (sprime))) + sprime = fold_convert (TREE_TYPE (lhs), sprime); tree vdef = gimple_vdef (stmt); tree vuse = gimple_vuse (stmt); propagate_tree_value_into_stmt (&gsi, sprime); @@ -4291,135 +4280,184 @@ eliminate_dom_walker::before_dom_children (basic_block b) if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, " Removed AB side-effects.\n"); } + + continue; } } + /* If the statement is a scalar store, see if the expression - has the same value number as its rhs. If so, the store is - dead. */ - else if (gimple_assign_single_p (stmt) - && !gimple_has_volatile_ops (stmt) - && !is_gimple_reg (gimple_assign_lhs (stmt)) - && (TREE_CODE (rhs) == SSA_NAME - || is_gimple_min_invariant (rhs))) - { - tree val; - val = vn_reference_lookup (gimple_assign_lhs (stmt), - gimple_vuse (stmt), VN_WALK, NULL); - if (TREE_CODE (rhs) == SSA_NAME) - rhs = VN_INFO (rhs)->valnum; - if (val - && operand_equal_p (val, rhs, 0)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Deleted redundant store "); - print_gimple_stmt (dump_file, stmt, 0, 0); - } + has the same value number as its rhs. If so, the store is + dead. */ + if (gimple_assign_single_p (stmt) + && !gimple_has_volatile_ops (stmt) + && !is_gimple_reg (gimple_assign_lhs (stmt)) + && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME + || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))) + { + tree val; + tree rhs = gimple_assign_rhs1 (stmt); + val = vn_reference_lookup (gimple_assign_lhs (stmt), + gimple_vuse (stmt), VN_WALK, NULL); + if (TREE_CODE (rhs) == SSA_NAME) + rhs = VN_INFO (rhs)->valnum; + if (val + && operand_equal_p (val, rhs, 0)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Deleted redundant store "); + print_gimple_stmt (dump_file, stmt, 0, 0); + } + + /* Queue stmt for removal. */ + el_to_remove.safe_push (stmt); + continue; + } + } - /* Queue stmt for removal. */ - el_to_remove.safe_push (stmt); - } - } - /* Visit COND_EXPRs and fold the comparison with the - available value-numbers. */ - else if (gimple_code (stmt) == GIMPLE_COND) + bool can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt); + bool was_noreturn = (is_gimple_call (stmt) + && gimple_call_noreturn_p (stmt)); + tree vdef = gimple_vdef (stmt); + tree vuse = gimple_vuse (stmt); + + /* If we didn't replace the whole stmt (or propagate the result + into all uses), replace all uses on this stmt with their + leaders. */ + use_operand_p use_p; + ssa_op_iter iter; + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE) { - tree op0 = gimple_cond_lhs (stmt); - tree op1 = gimple_cond_rhs (stmt); - tree result; - - if (TREE_CODE (op0) == SSA_NAME) - op0 = VN_INFO (op0)->valnum; - if (TREE_CODE (op1) == SSA_NAME) - op1 = VN_INFO (op1)->valnum; - result = fold_binary (gimple_cond_code (stmt), boolean_type_node, - op0, op1); - if (result && TREE_CODE (result) == INTEGER_CST) + tree use = USE_FROM_PTR (use_p); + /* ??? The call code above leaves stmt operands un-updated. */ + if (TREE_CODE (use) != SSA_NAME) + continue; + tree sprime = eliminate_avail (use); + if (sprime && sprime != use + && may_propagate_copy (use, sprime) + /* We substitute into debug stmts to avoid excessive + debug temporaries created by removed stmts, but we need + to avoid doing so for inserted sprimes as we never want + to create debug temporaries for them. */ + && (!inserted_exprs + || TREE_CODE (sprime) != SSA_NAME + || !is_gimple_debug (stmt) + || !bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime)))) { - if (integer_zerop (result)) - gimple_cond_make_false (stmt); - else - gimple_cond_make_true (stmt); - update_stmt (stmt); - el_todo = TODO_cleanup_cfg; + propagate_value (use_p, sprime); + gimple_set_modified (stmt, true); + if (TREE_CODE (sprime) == SSA_NAME + && !is_gimple_debug (stmt)) + gimple_set_plf (SSA_NAME_DEF_STMT (sprime), + NECESSARY, true); } } + /* Visit indirect calls and turn them into direct calls if - possible. */ + possible using the devirtualization machinery. */ if (is_gimple_call (stmt)) { - tree orig_fn = gimple_call_fn (stmt); - tree fn; - if (!orig_fn) - continue; - if (TREE_CODE (orig_fn) == SSA_NAME) - fn = VN_INFO (orig_fn)->valnum; - else if (TREE_CODE (orig_fn) == OBJ_TYPE_REF - && TREE_CODE (OBJ_TYPE_REF_EXPR (orig_fn)) == SSA_NAME) + tree fn = gimple_call_fn (stmt); + if (fn + && TREE_CODE (fn) == OBJ_TYPE_REF + && TREE_CODE (OBJ_TYPE_REF_EXPR (fn)) == SSA_NAME) { - fn = VN_INFO (OBJ_TYPE_REF_EXPR (orig_fn))->valnum; - if (!gimple_call_addr_fndecl (fn)) + fn = ipa_intraprocedural_devirtualization (stmt); + if (fn && dbg_cnt (devirt)) { - fn = ipa_intraprocedural_devirtualization (stmt); - if (fn) - fn = build_fold_addr_expr (fn); + if (dump_enabled_p ()) + { + location_t loc = gimple_location (stmt); + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, + "converting indirect call to " + "function %s\n", + cgraph_get_node (fn)->name ()); + } + gimple_call_set_fndecl (stmt, fn); + gimple_set_modified (stmt, true); } } - else - continue; - if (gimple_call_addr_fndecl (fn) != NULL_TREE - && useless_type_conversion_p (TREE_TYPE (orig_fn), - TREE_TYPE (fn)) - && dbg_cnt (devirt)) - { - bool can_make_abnormal_goto - = stmt_can_make_abnormal_goto (stmt); - bool was_noreturn = gimple_call_noreturn_p (stmt); - - if (dump_enabled_p ()) - { - location_t loc = gimple_location (stmt); - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, - "converting indirect call to function %s\n", - cgraph_get_node (gimple_call_addr_fndecl (fn))->name ()); - } - - gimple_call_set_fn (stmt, fn); - tree vdef = gimple_vdef (stmt); - tree vuse = gimple_vuse (stmt); - update_stmt (stmt); - if (vdef != gimple_vdef (stmt)) - VN_INFO (vdef)->valnum = vuse; + } + if (gimple_modified_p (stmt)) + { + /* If a formerly non-invariant ADDR_EXPR is turned into an + invariant one it was on a separate stmt. */ + if (gimple_assign_single_p (stmt) + && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR) + recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt)); + gimple old_stmt = stmt; + if (is_gimple_call (stmt)) + { + /* ??? Only fold calls inplace for now, this may create new + SSA names which in turn will confuse free_scc_vn SSA name + release code. */ + fold_stmt_inplace (&gsi); /* When changing a call into a noreturn call, cfg cleanup is needed to fix up the noreturn call. */ if (!was_noreturn && gimple_call_noreturn_p (stmt)) el_todo |= TODO_cleanup_cfg; + } + else + { + fold_stmt (&gsi); + stmt = gsi_stmt (gsi); + if ((gimple_code (stmt) == GIMPLE_COND + && (gimple_cond_true_p (stmt) + || gimple_cond_false_p (stmt))) + || (gimple_code (stmt) == GIMPLE_SWITCH + && TREE_CODE (gimple_switch_index (stmt)) == INTEGER_CST)) + el_todo |= TODO_cleanup_cfg; + } + /* If we removed EH side-effects from the statement, clean + its EH information. */ + if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)) + { + bitmap_set_bit (need_eh_cleanup, + gimple_bb (stmt)->index); + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Removed EH side-effects.\n"); + } + /* Likewise for AB side-effects. */ + if (can_make_abnormal_goto + && !stmt_can_make_abnormal_goto (stmt)) + { + bitmap_set_bit (need_ab_cleanup, + gimple_bb (stmt)->index); + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Removed AB side-effects.\n"); + } + update_stmt (stmt); + if (vdef != gimple_vdef (stmt)) + VN_INFO (vdef)->valnum = vuse; + } - /* If we removed EH side-effects from the statement, clean - its EH information. */ - if (maybe_clean_or_replace_eh_stmt (stmt, stmt)) - { - bitmap_set_bit (need_eh_cleanup, - gimple_bb (stmt)->index); - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " Removed EH side-effects.\n"); - } - - /* Likewise for AB side-effects. */ - if (can_make_abnormal_goto - && !stmt_can_make_abnormal_goto (stmt)) - { - bitmap_set_bit (need_ab_cleanup, - gimple_bb (stmt)->index); - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " Removed AB side-effects.\n"); - } + /* Make new values available - for fully redundant LHS we + continue with the next stmt above and skip this. */ + def_operand_p defp; + FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF) + eliminate_push_avail (DEF_FROM_PTR (defp)); + } - /* Changing an indirect call to a direct call may - have exposed different semantics. This may - require an SSA update. */ - el_todo |= TODO_update_ssa_only_virtuals; + /* Replace destination PHI arguments. */ + edge_iterator ei; + edge e; + FOR_EACH_EDGE (e, ei, b->succs) + { + for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple phi = gsi_stmt (gsi); + use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e); + tree arg = USE_FROM_PTR (use_p); + if (TREE_CODE (arg) != SSA_NAME + || virtual_operand_p (arg)) + continue; + tree sprime = eliminate_avail (arg); + if (sprime && may_propagate_copy (arg, sprime)) + { + propagate_value (use_p, sprime); + if (TREE_CODE (sprime) == SSA_NAME) + gimple_set_plf (SSA_NAME_DEF_STMT (sprime), NECESSARY, true); } } } @@ -4442,7 +4480,6 @@ eliminate (bool do_pre) { gimple_stmt_iterator gsi; gimple stmt; - unsigned i; need_eh_cleanup = BITMAP_ALLOC (NULL); need_ab_cleanup = BITMAP_ALLOC (NULL); @@ -4460,41 +4497,41 @@ eliminate (bool do_pre) /* We cannot remove stmts during BB walk, especially not release SSA names there as this confuses the VN machinery. The stmts ending - up in el_to_remove are either stores or simple copies. */ - FOR_EACH_VEC_ELT (el_to_remove, i, stmt) + up in el_to_remove are either stores or simple copies. + Remove stmts in reverse order to make debug stmt creation possible. */ + while (!el_to_remove.is_empty ()) { - tree lhs = gimple_assign_lhs (stmt); - tree rhs = gimple_assign_rhs1 (stmt); - use_operand_p use_p; - gimple use_stmt; - - /* If there is a single use only, propagate the equivalency - instead of keeping the copy. */ - if (TREE_CODE (lhs) == SSA_NAME - && TREE_CODE (rhs) == SSA_NAME - && single_imm_use (lhs, &use_p, &use_stmt) - && may_propagate_copy (USE_FROM_PTR (use_p), rhs)) + stmt = el_to_remove.pop (); + + if (dump_file && (dump_flags & TDF_DETAILS)) { - SET_USE (use_p, rhs); - update_stmt (use_stmt); - if (inserted_exprs - && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (lhs)) - && TREE_CODE (rhs) == SSA_NAME) - gimple_set_plf (SSA_NAME_DEF_STMT (rhs), NECESSARY, true); + fprintf (dump_file, "Removing dead stmt "); + print_gimple_stmt (dump_file, stmt, 0, 0); } - /* If this is a store or a now unused copy, remove it. */ - if (TREE_CODE (lhs) != SSA_NAME - || has_zero_uses (lhs)) + tree lhs; + if (gimple_code (stmt) == GIMPLE_PHI) + lhs = gimple_phi_result (stmt); + else + lhs = gimple_get_lhs (stmt); + + if (inserted_exprs + && TREE_CODE (lhs) == SSA_NAME) + bitmap_clear_bit (inserted_exprs, SSA_NAME_VERSION (lhs)); + + gsi = gsi_for_stmt (stmt); + if (gimple_code (stmt) == GIMPLE_PHI) + { + remove_phi_node (&gsi, true); + /* Removing a PHI node in a block may expose a forwarder block. */ + el_todo |= TODO_cleanup_cfg; + } + else { basic_block bb = gimple_bb (stmt); - gsi = gsi_for_stmt (stmt); unlink_stmt_vdef (stmt); if (gsi_remove (&gsi, true)) bitmap_set_bit (need_eh_cleanup, bb->index); - if (inserted_exprs - && TREE_CODE (lhs) == SSA_NAME) - bitmap_clear_bit (inserted_exprs, SSA_NAME_VERSION (lhs)); release_defs (stmt); } } diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index 1988835aa32..cdc9f6ad39b 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -49,6 +49,7 @@ #include "tree-ssa-propagate.h" #include "langhooks.h" #include "value-prof.h" +#include "domwalk.h" /* This file implements a generic value propagation engine based on the same propagation used by the SSA-CCP algorithm [1]. @@ -1017,225 +1018,218 @@ replace_phi_args_in (gimple phi, ssa_prop_get_value_fn get_value) } -/* Perform final substitution and folding of propagated values. - - PROP_VALUE[I] contains the single value that should be substituted - at every use of SSA name N_I. If PROP_VALUE is NULL, no values are - substituted. - - If FOLD_FN is non-NULL the function will be invoked on all statements - before propagating values for pass specific simplification. - - DO_DCE is true if trivially dead stmts can be removed. - - If DO_DCE is true, the statements within a BB are walked from - last to first element. Otherwise we scan from first to last element. - - Return TRUE when something changed. */ - -bool -substitute_and_fold (ssa_prop_get_value_fn get_value_fn, - ssa_prop_fold_stmt_fn fold_fn, - bool do_dce) +class substitute_and_fold_dom_walker : public dom_walker { - basic_block bb; - bool something_changed = false; - unsigned i; +public: + substitute_and_fold_dom_walker (cdi_direction direction, + ssa_prop_get_value_fn get_value_fn_, + ssa_prop_fold_stmt_fn fold_fn_, + bool do_dce_) + : dom_walker (direction), get_value_fn (get_value_fn_), + fold_fn (fold_fn_), do_dce (do_dce_), something_changed (false) + { + stmts_to_remove.create (0); + } + ~substitute_and_fold_dom_walker () { stmts_to_remove.release (); } - if (!get_value_fn && !fold_fn) - return false; + virtual void before_dom_children (basic_block); + virtual void after_dom_children (basic_block) {} - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "\nSubstituting values and folding statements\n\n"); + ssa_prop_get_value_fn get_value_fn; + ssa_prop_fold_stmt_fn fold_fn; + bool do_dce; + bool something_changed; + vec<gimple> stmts_to_remove; +}; - memset (&prop_stats, 0, sizeof (prop_stats)); +void +substitute_and_fold_dom_walker::before_dom_children (basic_block bb) +{ + gimple_stmt_iterator i; - /* Substitute lattice values at definition sites. */ - if (get_value_fn) - for (i = 1; i < num_ssa_names; ++i) - { - tree name = ssa_name (i); - tree val; - gimple def_stmt; - gimple_stmt_iterator gsi; - - if (!name - || virtual_operand_p (name)) - continue; - - def_stmt = SSA_NAME_DEF_STMT (name); - if (gimple_nop_p (def_stmt) - /* Do not substitute ASSERT_EXPR rhs, this will confuse VRP. */ - || (gimple_assign_single_p (def_stmt) - && gimple_assign_rhs_code (def_stmt) == ASSERT_EXPR) - || !(val = (*get_value_fn) (name)) - || !may_propagate_copy (name, val)) - continue; - - gsi = gsi_for_stmt (def_stmt); - if (is_gimple_assign (def_stmt)) - { - gimple_assign_set_rhs_with_ops (&gsi, TREE_CODE (val), - val, NULL_TREE); - gcc_assert (gsi_stmt (gsi) == def_stmt); - if (maybe_clean_eh_stmt (def_stmt)) - gimple_purge_dead_eh_edges (gimple_bb (def_stmt)); - update_stmt (def_stmt); - } - else if (is_gimple_call (def_stmt)) - { - int flags = gimple_call_flags (def_stmt); - - /* Don't optimize away calls that have side-effects. */ - if ((flags & (ECF_CONST|ECF_PURE)) == 0 - || (flags & ECF_LOOPING_CONST_OR_PURE)) + /* Propagate known values into PHI nodes. */ + for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i)) + { + gimple phi = gsi_stmt (i); + tree res = gimple_phi_result (phi); + if (virtual_operand_p (res)) + continue; + if (do_dce + && res && TREE_CODE (res) == SSA_NAME) + { + tree sprime = get_value_fn (res); + if (sprime + && sprime != res + && may_propagate_copy (res, sprime)) + { + stmts_to_remove.safe_push (phi); continue; - if (update_call_from_tree (&gsi, val) - && maybe_clean_or_replace_eh_stmt (def_stmt, gsi_stmt (gsi))) - gimple_purge_dead_eh_edges (gimple_bb (gsi_stmt (gsi))); - } - else if (gimple_code (def_stmt) == GIMPLE_PHI) - { - gimple new_stmt = gimple_build_assign (name, val); - gimple_stmt_iterator gsi2; - gsi2 = gsi_after_labels (gimple_bb (def_stmt)); - gsi_insert_before (&gsi2, new_stmt, GSI_SAME_STMT); - remove_phi_node (&gsi, false); - } - - something_changed = true; - } - - /* Propagate into all uses and fold. */ - FOR_EACH_BB_FN (bb, cfun) + } + } + replace_phi_args_in (phi, get_value_fn); + } + + /* Propagate known values into stmts. In some case it exposes + more trivially deletable stmts to walk backward. */ + for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i)) { - gimple_stmt_iterator i; + bool did_replace; + gimple stmt = gsi_stmt (i); + gimple old_stmt; + enum gimple_code code = gimple_code (stmt); - /* Propagate known values into PHI nodes. */ - if (get_value_fn) - for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i)) - replace_phi_args_in (gsi_stmt (i), get_value_fn); + /* Ignore ASSERT_EXPRs. They are used by VRP to generate + range information for names and they are discarded + afterwards. */ - /* Propagate known values into stmts. Do a backward walk if - do_dce is true. In some case it exposes - more trivially deletable stmts to walk backward. */ - for (i = (do_dce ? gsi_last_bb (bb) : gsi_start_bb (bb)); !gsi_end_p (i);) + if (code == GIMPLE_ASSIGN + && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR) + continue; + + /* No point propagating into a stmt we have a value for we + can propagate into all uses. Mark it for removal instead. */ + tree lhs = gimple_get_lhs (stmt); + if (do_dce + && lhs && TREE_CODE (lhs) == SSA_NAME) { - bool did_replace; - gimple stmt = gsi_stmt (i); - gimple old_stmt; - enum gimple_code code = gimple_code (stmt); - gimple_stmt_iterator oldi; - - oldi = i; - if (do_dce) - gsi_prev (&i); - else - gsi_next (&i); - - /* Ignore ASSERT_EXPRs. They are used by VRP to generate - range information for names and they are discarded - afterwards. */ - - if (code == GIMPLE_ASSIGN - && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR) - continue; - - /* No point propagating into a stmt whose result is not used, - but instead we might be able to remove a trivially dead stmt. - Don't do this when called from VRP, since the SSA_NAME which - is going to be released could be still referenced in VRP - ranges. */ - if (do_dce - && gimple_get_lhs (stmt) - && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME - && has_zero_uses (gimple_get_lhs (stmt)) + tree sprime = get_value_fn (lhs); + if (sprime + && sprime != lhs + && may_propagate_copy (lhs, sprime) && !stmt_could_throw_p (stmt) && !gimple_has_side_effects (stmt)) { - gimple_stmt_iterator i2; - - if (dump_file && dump_flags & TDF_DETAILS) - { - fprintf (dump_file, "Removing dead stmt "); - print_gimple_stmt (dump_file, stmt, 0, 0); - fprintf (dump_file, "\n"); - } - prop_stats.num_dce++; - i2 = gsi_for_stmt (stmt); - gsi_remove (&i2, true); - release_defs (stmt); + stmts_to_remove.safe_push (stmt); continue; } + } + + /* Replace the statement with its folded version and mark it + folded. */ + did_replace = false; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Folding statement: "); + print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + } + + old_stmt = stmt; - /* Replace the statement with its folded version and mark it - folded. */ - did_replace = false; - if (dump_file && (dump_flags & TDF_DETAILS)) + /* Some statements may be simplified using propagator + specific information. Do this before propagating + into the stmt to not disturb pass specific information. */ + if (fold_fn + && (*fold_fn)(&i)) + { + did_replace = true; + prop_stats.num_stmts_folded++; + stmt = gsi_stmt (i); + update_stmt (stmt); + } + + /* Replace real uses in the statement. */ + did_replace |= replace_uses_in (stmt, get_value_fn); + + /* If we made a replacement, fold the statement. */ + if (did_replace) + fold_stmt (&i); + + /* Now cleanup. */ + if (did_replace) + { + stmt = gsi_stmt (i); + + /* If we cleaned up EH information from the statement, + remove EH edges. */ + if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)) + gimple_purge_dead_eh_edges (bb); + + if (is_gimple_assign (stmt) + && (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) + == GIMPLE_SINGLE_RHS)) { - fprintf (dump_file, "Folding statement: "); - print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + tree rhs = gimple_assign_rhs1 (stmt); + + if (TREE_CODE (rhs) == ADDR_EXPR) + recompute_tree_invariant_for_addr_expr (rhs); } - old_stmt = stmt; + /* Determine what needs to be done to update the SSA form. */ + update_stmt (stmt); + if (!is_gimple_debug (stmt)) + something_changed = true; + } - /* Some statements may be simplified using propagator - specific information. Do this before propagating - into the stmt to not disturb pass specific information. */ - if (fold_fn - && (*fold_fn)(&oldi)) + if (dump_file && (dump_flags & TDF_DETAILS)) + { + if (did_replace) { - did_replace = true; - prop_stats.num_stmts_folded++; - stmt = gsi_stmt (oldi); - update_stmt (stmt); + fprintf (dump_file, "Folded into: "); + print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + fprintf (dump_file, "\n"); } + else + fprintf (dump_file, "Not folded\n"); + } + } +} - /* Replace real uses in the statement. */ - if (get_value_fn) - did_replace |= replace_uses_in (stmt, get_value_fn); - /* If we made a replacement, fold the statement. */ - if (did_replace) - fold_stmt (&oldi); - /* Now cleanup. */ - if (did_replace) - { - stmt = gsi_stmt (oldi); +/* Perform final substitution and folding of propagated values. - /* If we cleaned up EH information from the statement, - remove EH edges. */ - if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)) - gimple_purge_dead_eh_edges (bb); + PROP_VALUE[I] contains the single value that should be substituted + at every use of SSA name N_I. If PROP_VALUE is NULL, no values are + substituted. - if (is_gimple_assign (stmt) - && (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) - == GIMPLE_SINGLE_RHS)) - { - tree rhs = gimple_assign_rhs1 (stmt); + If FOLD_FN is non-NULL the function will be invoked on all statements + before propagating values for pass specific simplification. - if (TREE_CODE (rhs) == ADDR_EXPR) - recompute_tree_invariant_for_addr_expr (rhs); - } + DO_DCE is true if trivially dead stmts can be removed. - /* Determine what needs to be done to update the SSA form. */ - update_stmt (stmt); - if (!is_gimple_debug (stmt)) - something_changed = true; - } + If DO_DCE is true, the statements within a BB are walked from + last to first element. Otherwise we scan from first to last element. - if (dump_file && (dump_flags & TDF_DETAILS)) - { - if (did_replace) - { - fprintf (dump_file, "Folded into: "); - print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); - fprintf (dump_file, "\n"); - } - else - fprintf (dump_file, "Not folded\n"); - } + Return TRUE when something changed. */ + +bool +substitute_and_fold (ssa_prop_get_value_fn get_value_fn, + ssa_prop_fold_stmt_fn fold_fn, + bool do_dce) +{ + gcc_assert (get_value_fn); + + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "\nSubstituting values and folding statements\n\n"); + + memset (&prop_stats, 0, sizeof (prop_stats)); + + calculate_dominance_info (CDI_DOMINATORS); + substitute_and_fold_dom_walker walker(CDI_DOMINATORS, + get_value_fn, fold_fn, do_dce); + walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun)); + + /* We cannot remove stmts during the BB walk, especially not release + SSA names there as that destroys the lattice of our callers. + Remove stmts in reverse order to make debug stmt creation possible. */ + while (!walker.stmts_to_remove.is_empty ()) + { + gimple stmt = walker.stmts_to_remove.pop (); + if (dump_file && dump_flags & TDF_DETAILS) + { + fprintf (dump_file, "Removing dead stmt "); + print_gimple_stmt (dump_file, stmt, 0, 0); + fprintf (dump_file, "\n"); + } + prop_stats.num_dce++; + gimple_stmt_iterator gsi = gsi_for_stmt (stmt); + if (gimple_code (stmt) == GIMPLE_PHI) + remove_phi_node (&gsi, true); + else + { + unlink_stmt_vdef (stmt); + gsi_remove (&gsi, true); + release_defs (stmt); } } @@ -1247,7 +1241,8 @@ substitute_and_fold (ssa_prop_get_value_fn get_value_fn, prop_stats.num_stmts_folded); statistics_counter_event (cfun, "Statements deleted", prop_stats.num_dce); - return something_changed; + + return walker.something_changed; } @@ -1410,11 +1405,6 @@ replace_exp (use_operand_p op_p, tree val) void propagate_tree_value (tree *op_p, tree val) { - gcc_checking_assert (!(TREE_CODE (val) == SSA_NAME - && *op_p - && TREE_CODE (*op_p) == SSA_NAME - && !may_propagate_copy (*op_p, val))); - if (TREE_CODE (val) == SSA_NAME) *op_p = val; else diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 2583375f32b..b949bfa725d 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -3140,35 +3140,12 @@ visit_phi (gimple phi) /* If all value numbered to the same value, the phi node has that value. */ if (allsame) - { - if (is_gimple_min_invariant (sameval)) - { - VN_INFO (PHI_RESULT (phi))->has_constants = true; - if (sameval != VN_TOP) - VN_INFO (PHI_RESULT (phi))->expr = sameval; - } - else - { - VN_INFO (PHI_RESULT (phi))->has_constants = false; - if (sameval != VN_TOP) - VN_INFO (PHI_RESULT (phi))->expr = sameval; - } - - if (TREE_CODE (sameval) == SSA_NAME) - return visit_copy (PHI_RESULT (phi), sameval); - - return set_ssa_val_to (PHI_RESULT (phi), sameval); - } + return set_ssa_val_to (PHI_RESULT (phi), sameval); /* Otherwise, see if it is equivalent to a phi node in this block. */ result = vn_phi_lookup (phi); if (result) - { - if (TREE_CODE (result) == SSA_NAME) - changed = visit_copy (PHI_RESULT (phi), result); - else - changed = set_ssa_val_to (PHI_RESULT (phi), result); - } + changed = set_ssa_val_to (PHI_RESULT (phi), result); else { vn_phi_insert (phi, PHI_RESULT (phi)); @@ -3262,24 +3239,18 @@ simplify_binary_expression (gimple stmt) catch those with constants. The goal here is to simultaneously combine constants between expressions, but avoid infinite expansion of expressions during simplification. */ - if (TREE_CODE (op0) == SSA_NAME) - { - if (VN_INFO (op0)->has_constants + op0 = vn_valueize (op0); + if (TREE_CODE (op0) == SSA_NAME + && (VN_INFO (op0)->has_constants || TREE_CODE_CLASS (code) == tcc_comparison - || code == COMPLEX_EXPR) - op0 = vn_get_expr_for (op0); - else - op0 = vn_valueize (op0); - } + || code == COMPLEX_EXPR)) + op0 = vn_get_expr_for (op0); - if (TREE_CODE (op1) == SSA_NAME) - { - if (VN_INFO (op1)->has_constants - || code == COMPLEX_EXPR) - op1 = vn_get_expr_for (op1); - else - op1 = vn_valueize (op1); - } + op1 = vn_valueize (op1); + if (TREE_CODE (op1) == SSA_NAME + && (VN_INFO (op1)->has_constants + || code == COMPLEX_EXPR)) + op1 = vn_get_expr_for (op1); /* Pointer plus constant can be represented as invariant address. Do so to allow further propatation, see also tree forwprop. */ @@ -3333,28 +3304,29 @@ simplify_unary_expression (gimple stmt) || code == BIT_FIELD_REF) op0 = TREE_OPERAND (op0, 0); - if (TREE_CODE (op0) != SSA_NAME) - return NULL_TREE; - orig_op0 = op0; - if (VN_INFO (op0)->has_constants) - op0 = vn_get_expr_for (op0); - else if (CONVERT_EXPR_CODE_P (code) - || code == REALPART_EXPR - || code == IMAGPART_EXPR - || code == VIEW_CONVERT_EXPR - || code == BIT_FIELD_REF) + op0 = vn_valueize (op0); + if (TREE_CODE (op0) == SSA_NAME) { - /* We want to do tree-combining on conversion-like expressions. - Make sure we feed only SSA_NAMEs or constants to fold though. */ - tree tem = vn_get_expr_for (op0); - if (UNARY_CLASS_P (tem) - || BINARY_CLASS_P (tem) - || TREE_CODE (tem) == VIEW_CONVERT_EXPR - || TREE_CODE (tem) == SSA_NAME - || TREE_CODE (tem) == CONSTRUCTOR - || is_gimple_min_invariant (tem)) - op0 = tem; + if (VN_INFO (op0)->has_constants) + op0 = vn_get_expr_for (op0); + else if (CONVERT_EXPR_CODE_P (code) + || code == REALPART_EXPR + || code == IMAGPART_EXPR + || code == VIEW_CONVERT_EXPR + || code == BIT_FIELD_REF) + { + /* We want to do tree-combining on conversion-like expressions. + Make sure we feed only SSA_NAMEs or constants to fold though. */ + tree tem = vn_get_expr_for (op0); + if (UNARY_CLASS_P (tem) + || BINARY_CLASS_P (tem) + || TREE_CODE (tem) == VIEW_CONVERT_EXPR + || TREE_CODE (tem) == SSA_NAME + || TREE_CODE (tem) == CONSTRUCTOR + || is_gimple_min_invariant (tem)) + op0 = tem; + } } /* Avoid folding if nothing changed, but remember the expression. */ diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index ba9e1fe30f4..a76a7ce6587 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -948,9 +948,12 @@ thread_through_normal_block (edge e, if (*backedge_seen_p) simplify = dummy_simplify; - /* PHIs create temporary equivalences. */ + /* PHIs create temporary equivalences. + Note that if we found a PHI that made the block non-threadable, then + we need to bubble that up to our caller in the same manner we do + when we prematurely stop processing statements below. */ if (!record_temporary_equivalences_from_phis (e, stack)) - return 0; + return -1; /* Now walk each statement recording any context sensitive temporary equivalences we can detect. */ diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c index 8b3adebc6f3..1ab9d9f7d05 100644 --- a/gcc/tree-streamer-in.c +++ b/gcc/tree-streamer-in.c @@ -280,7 +280,6 @@ unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr) { DECL_HARD_REGISTER (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_IN_CONSTANT_POOL (expr) = (unsigned) bp_unpack_value (bp, 1); - DECL_TLS_MODEL (expr) = (enum tls_model) bp_unpack_value (bp, 3); } if (TREE_CODE (expr) == FUNCTION_DECL) diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c index dd148fa7080..c65214c83b6 100644 --- a/gcc/tree-streamer-out.c +++ b/gcc/tree-streamer-out.c @@ -248,7 +248,6 @@ pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr) bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1); /* DECL_IN_TEXT_SECTION is set during final asm output only. */ bp_pack_value (bp, DECL_IN_CONSTANT_POOL (expr), 1); - bp_pack_value (bp, DECL_TLS_MODEL (expr), 3); } if (TREE_CODE (expr) == FUNCTION_DECL) diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index 9789b619ee2..f6e3eb3ebd2 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -640,15 +640,16 @@ collect_switch_conv_info (gimple swtch, struct switch_conv_info *info) info->other_count += e->count; /* See if there is one common successor block for all branch - targets. If it exists, record it in FINAL_BB. */ - FOR_EACH_EDGE (e, ei, info->switch_bb->succs) - { - if (! single_pred_p (e->dest)) - { - info->final_bb = e->dest; - break; - } - } + targets. If it exists, record it in FINAL_BB. + Start with the destination of the default case as guess + or its destination in case it is a forwarder block. */ + if (! single_pred_p (e_default->dest)) + info->final_bb = e_default->dest; + else if (single_succ_p (e_default->dest) + && ! single_pred_p (single_succ (e_default->dest))) + info->final_bb = single_succ (e_default->dest); + /* Require that all switch destinations are either that common + FINAL_BB or a forwarder to it. */ if (info->final_bb) FOR_EACH_EDGE (e, ei, info->switch_bb->succs) { diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index e6be42ad32e..b2b629c03c6 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see #include "expr.h" #include "optabs.h" #include "builtins.h" +#include "varasm.h" /* Return true if load- or store-lanes optab OPTAB is implemented for COUNT vectors of type VECTYPE. NAME is the name of OPTAB. */ @@ -2507,8 +2508,7 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) linear. Don't modify the original vector's order, it is needed for determining what dependencies are reversed. */ vec<data_reference_p> datarefs_copy = datarefs.copy (); - qsort (datarefs_copy.address (), datarefs_copy.length (), - sizeof (data_reference_p), dr_group_sort_cmp); + datarefs_copy.qsort (dr_group_sort_cmp); /* Build the interleaving chains. */ for (i = 0; i < datarefs_copy.length () - 1;) @@ -4364,13 +4364,14 @@ vect_grouped_store_supported (tree vectype, unsigned HOST_WIDE_INT count) { enum machine_mode mode = TYPE_MODE (vectype); - /* vect_permute_store_chain requires the group size to be a power of two. */ - if (exact_log2 (count) == -1) + /* vect_permute_store_chain requires the group size to be equal to 3 or + be a power of two. */ + if (count != 3 && exact_log2 (count) == -1) { 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\n"); + "the size of the group of accesses" + " is not a power of 2 or not eqaul to 3\n"); return false; } @@ -4379,23 +4380,76 @@ vect_grouped_store_supported (tree vectype, unsigned HOST_WIDE_INT count) { unsigned int i, nelt = GET_MODE_NUNITS (mode); unsigned char *sel = XALLOCAVEC (unsigned char, nelt); - for (i = 0; i < nelt / 2; i++) + + if (count == 3) { - sel[i * 2] = i; - sel[i * 2 + 1] = i + nelt; + unsigned int j0 = 0, j1 = 0, j2 = 0; + unsigned int i, j; + + for (j = 0; j < 3; j++) + { + int nelt0 = ((3 - j) * nelt) % 3; + int nelt1 = ((3 - j) * nelt + 1) % 3; + int nelt2 = ((3 - j) * nelt + 2) % 3; + for (i = 0; i < nelt; i++) + { + if (3 * i + nelt0 < nelt) + sel[3 * i + nelt0] = j0++; + if (3 * i + nelt1 < nelt) + sel[3 * i + nelt1] = nelt + j1++; + if (3 * i + nelt2 < nelt) + sel[3 * i + nelt2] = 0; + } + if (!can_vec_perm_p (mode, false, sel)) + { + if (dump_enabled_p ()) + dump_printf (MSG_MISSED_OPTIMIZATION, + "permutaion op not supported by target.\n"); + return false; + } + + for (i = 0; i < nelt; i++) + { + if (3 * i + nelt0 < nelt) + sel[3 * i + nelt0] = 3 * i + nelt0; + if (3 * i + nelt1 < nelt) + sel[3 * i + nelt1] = 3 * i + nelt1; + if (3 * i + nelt2 < nelt) + sel[3 * i + nelt2] = nelt + j2++; + } + if (!can_vec_perm_p (mode, false, sel)) + { + if (dump_enabled_p ()) + dump_printf (MSG_MISSED_OPTIMIZATION, + "permutaion op not supported by target.\n"); + return false; + } + } + return true; } - if (can_vec_perm_p (mode, false, sel)) + else { - for (i = 0; i < nelt; i++) - sel[i] += nelt / 2; - if (can_vec_perm_p (mode, false, sel)) - return true; + /* If length is not equal to 3 then only power of 2 is supported. */ + gcc_assert (exact_log2 (count) != -1); + + for (i = 0; i < nelt / 2; i++) + { + sel[i * 2] = i; + sel[i * 2 + 1] = i + nelt; + } + if (can_vec_perm_p (mode, false, sel)) + { + for (i = 0; i < nelt; i++) + sel[i] += nelt / 2; + if (can_vec_perm_p (mode, false, sel)) + return true; + } } } if (dump_enabled_p ()) dump_printf (MSG_MISSED_OPTIMIZATION, - "interleave op not supported by target.\n"); + "permutaion op not supported by target.\n"); return false; } @@ -4415,9 +4469,9 @@ vect_store_lanes_supported (tree vectype, unsigned HOST_WIDE_INT count) /* Function vect_permute_store_chain. Given a chain of interleaved stores in DR_CHAIN of LENGTH that must be - a power of 2, generate interleave_high/low stmts to reorder the data - correctly for the stores. Return the final references for stores in - RESULT_CHAIN. + a power of 2 or equal to 3, generate interleave_high/low stmts to reorder + the data correctly for the stores. Return the final references for stores + in RESULT_CHAIN. E.g., LENGTH is 4 and the scalar type is short, i.e., VF is 8. The input is 4 vectors each containing 8 elements. We assign a number to @@ -4484,7 +4538,9 @@ vect_permute_store_chain (vec<tree> dr_chain, gimple perm_stmt; tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt)); tree perm_mask_low, perm_mask_high; - unsigned int i, n; + tree data_ref; + tree perm3_mask_low, perm3_mask_high; + unsigned int i, n, log_length = exact_log2 (length); unsigned int j, nelt = TYPE_VECTOR_SUBPARTS (vectype); unsigned char *sel = XALLOCAVEC (unsigned char, nelt); @@ -4492,47 +4548,116 @@ vect_permute_store_chain (vec<tree> dr_chain, memcpy (result_chain->address (), dr_chain.address (), length * sizeof (tree)); - for (i = 0, n = nelt / 2; i < n; i++) + if (length == 3) { - sel[i * 2] = i; - sel[i * 2 + 1] = i + nelt; - } - perm_mask_high = vect_gen_perm_mask (vectype, sel); - gcc_assert (perm_mask_high != NULL); + unsigned int j0 = 0, j1 = 0, j2 = 0; - for (i = 0; i < nelt; i++) - sel[i] += nelt / 2; - perm_mask_low = vect_gen_perm_mask (vectype, sel); - gcc_assert (perm_mask_low != NULL); + for (j = 0; j < 3; j++) + { + int nelt0 = ((3 - j) * nelt) % 3; + int nelt1 = ((3 - j) * nelt + 1) % 3; + int nelt2 = ((3 - j) * nelt + 2) % 3; - for (i = 0, n = exact_log2 (length); i < n; i++) - { - for (j = 0; j < length/2; j++) - { - vect1 = dr_chain[j]; - vect2 = dr_chain[j+length/2]; + for (i = 0; i < nelt; i++) + { + if (3 * i + nelt0 < nelt) + sel[3 * i + nelt0] = j0++; + if (3 * i + nelt1 < nelt) + sel[3 * i + nelt1] = nelt + j1++; + if (3 * i + nelt2 < nelt) + sel[3 * i + nelt2] = 0; + } + perm3_mask_low = vect_gen_perm_mask (vectype, sel); + gcc_assert (perm3_mask_low != NULL); + + for (i = 0; i < nelt; i++) + { + if (3 * i + nelt0 < nelt) + sel[3 * i + nelt0] = 3 * i + nelt0; + if (3 * i + nelt1 < nelt) + sel[3 * i + nelt1] = 3 * i + nelt1; + if (3 * i + nelt2 < nelt) + sel[3 * i + nelt2] = nelt + j2++; + } + perm3_mask_high = vect_gen_perm_mask (vectype, sel); + gcc_assert (perm3_mask_high != NULL); + + vect1 = dr_chain[0]; + vect2 = dr_chain[1]; /* Create interleaving stmt: - high = VEC_PERM_EXPR <vect1, vect2, {0, nelt, 1, nelt+1, ...}> */ - high = make_temp_ssa_name (vectype, NULL, "vect_inter_high"); - perm_stmt - = gimple_build_assign_with_ops (VEC_PERM_EXPR, high, - vect1, vect2, perm_mask_high); + low = VEC_PERM_EXPR <vect1, vect2, + {j, nelt, *, j + 1, nelt + j + 1, *, + j + 2, nelt + j + 2, *, ...}> */ + data_ref = make_temp_ssa_name (vectype, NULL, "vect_shuffle3_low"); + perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref, + vect1, vect2, + perm3_mask_low); vect_finish_stmt_generation (stmt, perm_stmt, gsi); - (*result_chain)[2*j] = high; + vect1 = data_ref; + vect2 = dr_chain[2]; /* Create interleaving stmt: - low = VEC_PERM_EXPR <vect1, vect2, {nelt/2, nelt*3/2, nelt/2+1, - nelt*3/2+1, ...}> */ - low = make_temp_ssa_name (vectype, NULL, "vect_inter_low"); - perm_stmt - = gimple_build_assign_with_ops (VEC_PERM_EXPR, low, - vect1, vect2, perm_mask_low); + low = VEC_PERM_EXPR <vect1, vect2, + {0, 1, nelt + j, 3, 4, nelt + j + 1, + 6, 7, nelt + j + 2, ...}> */ + data_ref = make_temp_ssa_name (vectype, NULL, "vect_shuffle3_high"); + perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref, + vect1, vect2, + perm3_mask_high); vect_finish_stmt_generation (stmt, perm_stmt, gsi); - (*result_chain)[2*j+1] = low; + (*result_chain)[j] = data_ref; } - memcpy (dr_chain.address (), result_chain->address (), - length * sizeof (tree)); + } + else + { + /* If length is not equal to 3 then only power of 2 is supported. */ + gcc_assert (exact_log2 (length) != -1); + + for (i = 0, n = nelt / 2; i < n; i++) + { + sel[i * 2] = i; + sel[i * 2 + 1] = i + nelt; + } + perm_mask_high = vect_gen_perm_mask (vectype, sel); + gcc_assert (perm_mask_high != NULL); + + for (i = 0; i < nelt; i++) + sel[i] += nelt / 2; + perm_mask_low = vect_gen_perm_mask (vectype, sel); + gcc_assert (perm_mask_low != NULL); + + for (i = 0, n = log_length; i < n; i++) + { + for (j = 0; j < length/2; j++) + { + vect1 = dr_chain[j]; + vect2 = dr_chain[j+length/2]; + + /* Create interleaving stmt: + high = VEC_PERM_EXPR <vect1, vect2, {0, nelt, 1, nelt+1, + ...}> */ + high = make_temp_ssa_name (vectype, NULL, "vect_inter_high"); + perm_stmt + = gimple_build_assign_with_ops (VEC_PERM_EXPR, high, + vect1, vect2, perm_mask_high); + vect_finish_stmt_generation (stmt, perm_stmt, gsi); + (*result_chain)[2*j] = high; + + /* Create interleaving stmt: + low = VEC_PERM_EXPR <vect1, vect2, + {nelt/2, nelt*3/2, nelt/2+1, nelt*3/2+1, + ...}> */ + low = make_temp_ssa_name (vectype, NULL, "vect_inter_low"); + perm_stmt + = gimple_build_assign_with_ops (VEC_PERM_EXPR, low, + vect1, vect2, perm_mask_low); + vect_finish_stmt_generation (stmt, perm_stmt, gsi); + (*result_chain)[2*j+1] = low; + } + memcpy (dr_chain.address (), result_chain->address (), + length * sizeof (tree)); + } } } @@ -5191,20 +5316,33 @@ vect_can_force_dr_alignment_p (const_tree decl, unsigned int alignment) if (TREE_CODE (decl) != VAR_DECL) return false; - /* We cannot change alignment of common or external symbols as another - translation unit may contain a definition with lower alignment. - The rules of common symbol linking mean that the definition - will override the common symbol. The same is true for constant - pool entries which may be shared and are not properly merged - by LTO. */ - if (DECL_EXTERNAL (decl) - || DECL_COMMON (decl) - || DECL_IN_CONSTANT_POOL (decl)) + /* With -fno-toplevel-reorder we may have already output the constant. */ + if (TREE_ASM_WRITTEN (decl)) return false; - if (TREE_ASM_WRITTEN (decl)) + /* Constant pool entries may be shared and not properly merged by LTO. */ + if (DECL_IN_CONSTANT_POOL (decl)) return false; + if (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl)) + { + symtab_node *snode; + + /* We cannot change alignment of symbols that may bind to symbols + in other translation unit that may contain a definition with lower + alignment. */ + if (!decl_binds_to_current_def_p (decl)) + return false; + + /* When compiling partition, be sure the symbol is not output by other + partition. */ + snode = symtab_get_node (decl); + if (flag_ltrans + && (snode->in_other_partition + || symtab_get_symbol_partitioning_class (snode) == SYMBOL_DUPLICATE)) + return false; + } + /* Do not override the alignment as specified by the ABI when the used attribute is set. */ if (DECL_PRESERVE_P (decl)) @@ -5214,10 +5352,22 @@ vect_can_force_dr_alignment_p (const_tree decl, unsigned int alignment) section name is also used. This is a common idiom used by many software projects. */ if (TREE_STATIC (decl) - && DECL_SECTION_NAME (decl) != NULL_TREE - && !DECL_HAS_IMPLICIT_SECTION_NAME_P (decl)) + && DECL_SECTION_NAME (decl) != NULL + && !symtab_get_node (decl)->implicit_section) return false; + /* If symbol is an alias, we need to check that target is OK. */ + if (TREE_STATIC (decl)) + { + tree target = symtab_alias_ultimate_target (symtab_get_node (decl))->decl; + if (target != decl) + { + if (DECL_PRESERVE_P (target)) + return false; + decl = target; + } + } + if (TREE_STATIC (decl)) return (alignment <= MAX_OFILE_ALIGNMENT); else diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 8c61775897d..9c77b65f48e 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -975,9 +975,9 @@ vect_model_store_cost (stmt_vec_info stmt_info, int ncopies, include the cost of the permutes. */ if (!store_lanes_p && group_size > 1) { - /* Uses a high and low interleave operation for each needed permute. */ - - int nstmts = ncopies * exact_log2 (group_size) * group_size; + /* Uses a high and low interleave or shuffle operations for each + needed permute. */ + int nstmts = ncopies * ceil_log2 (group_size) * group_size; inside_cost = record_stmt_cost (body_cost_vec, nstmts, vec_perm, stmt_info, 0, vect_body); diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index 8f5f2d66251..e2939b18ffc 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -686,6 +686,12 @@ increase_alignment (void) { DECL_ALIGN (decl) = TYPE_ALIGN (vectype); DECL_USER_ALIGN (decl) = 1; + if (TREE_STATIC (decl)) + { + tree target = symtab_alias_ultimate_target (symtab_get_node (decl))->decl; + DECL_ALIGN (target) = TYPE_ALIGN (vectype); + DECL_USER_ALIGN (target) = 1; + } dump_printf (MSG_NOTE, "Increasing alignment of decl: "); dump_generic_expr (MSG_NOTE, TDF_SLIM, decl); dump_printf (MSG_NOTE, "\n"); diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 428e622a217..b657546a3d7 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -3892,15 +3892,6 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, max = init; else min = init; - - /* If we would create an invalid range, then just assume we - know absolutely nothing. This may be over-conservative, - but it's clearly safe, and should happen only in unreachable - parts of code, or for invalid programs. */ - if (compare_values (min, max) == 1) - return; - - set_value_range (vr, VR_RANGE, min, max, vr->equiv); } else if (vr->type == VR_RANGE) { @@ -3933,16 +3924,20 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, || compare_values (tmax, max) == -1) max = tmax; } + } + else + return; - /* If we just created an invalid range with the minimum - greater than the maximum, we fail conservatively. - This should happen only in unreachable - parts of code, or for invalid programs. */ - if (compare_values (min, max) == 1) - return; + /* If we just created an invalid range with the minimum + greater than the maximum, we fail conservatively. + This should happen only in unreachable + parts of code, or for invalid programs. */ + if (compare_values (min, max) == 1 + || (is_negative_overflow_infinity (min) + && is_positive_overflow_infinity (max))) + return; - set_value_range (vr, VR_RANGE, min, max, vr->equiv); - } + set_value_range (vr, VR_RANGE, min, max, vr->equiv); } diff --git a/gcc/tree.c b/gcc/tree.c index 7c1dbd59aeb..559e7581ef8 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -628,7 +628,7 @@ decl_comdat_group_id (const_tree node) /* When the target supports named section, return its name as IDENTIFIER_NODE or NULL if it is in no section. */ -tree +const char * decl_section_name (const_tree node) { struct symtab_node *snode = symtab_get_node (node); @@ -640,7 +640,7 @@ decl_section_name (const_tree node) /* Set section section name of NODE to VALUE (that is expected to be identifier node) */ void -set_decl_section_name (tree node, tree value) +set_decl_section_name (tree node, const char *value) { struct symtab_node *snode; @@ -657,6 +657,33 @@ set_decl_section_name (tree node, tree value) snode->set_section (value); } +/* Return TLS model of a variable NODE. */ +enum tls_model +decl_tls_model (const_tree node) +{ + struct varpool_node *snode = varpool_get_node (node); + if (!snode) + return TLS_MODEL_NONE; + return snode->tls_model; +} + +/* Set TLS model of variable NODE to MODEL. */ +void +set_decl_tls_model (tree node, enum tls_model model) +{ + struct varpool_node *vnode; + + if (model == TLS_MODEL_NONE) + { + vnode = varpool_get_node (node); + if (!vnode) + return; + } + else + vnode = varpool_node_for_decl (node); + vnode->tls_model = model; +} + /* Compute the number of bytes occupied by a tree with code CODE. This function cannot be used for nodes that have variable sizes, including TREE_VEC, INTEGER_CST, STRING_CST, and CALL_EXPR. */ diff --git a/gcc/tree.h b/gcc/tree.h index 0abf9fd116a..4a29aa2776d 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2386,12 +2386,12 @@ extern void decl_value_expr_insert (tree, tree); /* In a VAR_DECL, the model to use if the data should be allocated from thread-local storage. */ -#define DECL_TLS_MODEL(NODE) (VAR_DECL_CHECK (NODE)->decl_with_vis.tls_model) +#define DECL_TLS_MODEL(NODE) decl_tls_model (NODE) /* In a VAR_DECL, nonzero if the data should be allocated from thread-local storage. */ #define DECL_THREAD_LOCAL_P(NODE) \ - (VAR_DECL_CHECK (NODE)->decl_with_vis.tls_model >= TLS_MODEL_REAL) + ((TREE_STATIC (NODE) || DECL_EXTERNAL (NODE)) && decl_tls_model (NODE) >= TLS_MODEL_REAL) /* In a non-local VAR_DECL with static storage duration, true if the variable has an initialization priority. If false, the variable @@ -2399,11 +2399,6 @@ extern void decl_value_expr_insert (tree, tree); #define DECL_HAS_INIT_PRIORITY_P(NODE) \ (VAR_DECL_CHECK (NODE)->decl_with_vis.init_priority_p) -/* Specify whether the section name was set by user or by - compiler via -ffunction-sections. */ -#define DECL_HAS_IMPLICIT_SECTION_NAME_P(NODE) \ - (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.implicit_section_name_p) - extern tree decl_debug_expr_lookup (tree); extern void decl_debug_expr_insert (tree, tree); @@ -3432,8 +3427,10 @@ tree_operand_check_code (const_tree __t, enum tree_code __code, int __i, extern tree decl_assembler_name (tree); extern tree decl_comdat_group (const_tree); extern tree decl_comdat_group_id (const_tree); -extern tree decl_section_name (const_tree); -extern void set_decl_section_name (tree, tree); +extern const char *decl_section_name (const_tree); +extern void set_decl_section_name (tree, const char *); +extern enum tls_model decl_tls_model (const_tree); +extern void set_decl_tls_model (tree, enum tls_model); /* Compute the number of bytes occupied by 'node'. This routine only looks at TREE_CODE and, if the code is TREE_VEC, TREE_VEC_LENGTH. */ @@ -4529,7 +4526,9 @@ static inline bool may_be_aliased (const_tree var) { return (TREE_CODE (var) != CONST_DECL - && TREE_ADDRESSABLE (var) + && (TREE_PUBLIC (var) + || DECL_EXTERNAL (var) + || TREE_ADDRESSABLE (var)) && !((TREE_STATIC (var) || TREE_PUBLIC (var) || DECL_EXTERNAL (var)) && ((TREE_READONLY (var) && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (var))) diff --git a/gcc/varasm.c b/gcc/varasm.c index 028e7409588..7be56f1e1ee 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -173,7 +173,7 @@ static GTY(()) section *unnamed_sections; /* Return a nonzero value if DECL has a section attribute. */ #define IN_NAMED_SECTION(DECL) \ ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \ - && DECL_SECTION_NAME (DECL) != NULL_TREE) + && DECL_SECTION_NAME (DECL) != NULL) /* Hash table of named sections. */ static GTY((param_is (section))) htab_t section_htab; @@ -411,26 +411,37 @@ get_named_section (tree decl, const char *name, int reloc) if (name == NULL) { gcc_assert (decl && DECL_P (decl) && DECL_SECTION_NAME (decl)); - name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); + name = DECL_SECTION_NAME (decl); } flags = targetm.section_type_flags (decl, name, reloc); return get_section (name, flags, decl); } +/* Worker for resolve_unique_section. */ + +static bool +set_implicit_section (struct symtab_node *n, void *data ATTRIBUTE_UNUSED) +{ + n->implicit_section = true; + return false; +} + /* If required, set DECL_SECTION_NAME to a unique name. */ void resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED, int flag_function_or_data_sections) { - if (DECL_SECTION_NAME (decl) == NULL_TREE + if (DECL_SECTION_NAME (decl) == NULL && targetm_common.have_named_sections && (flag_function_or_data_sections || DECL_COMDAT_GROUP (decl))) { targetm.asm_out.unique_section (decl, reloc); - DECL_HAS_IMPLICIT_SECTION_NAME_P (decl) = true; + if (DECL_SECTION_NAME (decl)) + symtab_for_node_and_aliases (symtab_get_node (decl), + set_implicit_section, NULL, true); } } @@ -472,7 +483,7 @@ static section * hot_function_section (tree decl) { if (decl != NULL_TREE - && DECL_SECTION_NAME (decl) != NULL_TREE + && DECL_SECTION_NAME (decl) != NULL && targetm_common.have_named_sections) return get_named_section (decl, NULL, 0); else @@ -497,20 +508,20 @@ get_named_text_section (tree decl, { if (named_section_suffix) { - tree dsn = DECL_SECTION_NAME (decl); + const char *dsn = DECL_SECTION_NAME (decl); const char *stripped_name; char *name, *buffer; - name = (char *) alloca (TREE_STRING_LENGTH (dsn) + 1); - memcpy (name, TREE_STRING_POINTER (dsn), - TREE_STRING_LENGTH (dsn) + 1); + name = (char *) alloca (strlen (dsn) + 1); + memcpy (name, dsn, + strlen (dsn) + 1); stripped_name = targetm.strip_name_encoding (name); buffer = ACONCAT ((stripped_name, named_section_suffix, NULL)); return get_named_section (decl, buffer, 0); } - else if (DECL_HAS_IMPLICIT_SECTION_NAME_P (decl)) + else if (symtab_get_node (decl)->implicit_section) { const char *name; @@ -539,8 +550,7 @@ default_function_section (tree decl, enum node_frequency freq, /* Old GNU linkers have buggy --gc-section support, which sometimes results in .gcc_except_table* sections being garbage collected. */ if (decl - && DECL_SECTION_NAME (decl) - && DECL_HAS_IMPLICIT_SECTION_NAME_P (decl)) + && symtab_get_node (decl)->implicit_section) return NULL; #endif @@ -610,7 +620,7 @@ function_section_1 (tree decl, bool force_cold) #ifdef USE_SELECT_SECTION_FOR_FUNCTIONS if (decl != NULL_TREE - && DECL_SECTION_NAME (decl) != NULL_TREE) + && DECL_SECTION_NAME (decl) != NULL) { if (targetm.asm_out.function_section) section = targetm.asm_out.function_section (decl, freq, @@ -684,7 +694,7 @@ default_function_rodata_section (tree decl) { if (decl != NULL_TREE && DECL_SECTION_NAME (decl)) { - const char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); + const char *name = DECL_SECTION_NAME (decl); if (DECL_COMDAT_GROUP (decl) && HAVE_COMDAT_GROUP) { @@ -1370,7 +1380,7 @@ make_decl_rtl (tree decl) we take care of recomputing the DECL_RTL after visibility is changed. */ if (TREE_CODE (decl) == VAR_DECL && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)) - && DECL_SECTION_NAME (decl) != NULL_TREE + && DECL_SECTION_NAME (decl) != NULL && DECL_INITIAL (decl) == NULL_TREE && DECL_COMMON (decl)) DECL_COMMON (decl) = 0; @@ -6461,7 +6471,7 @@ default_unique_section (tree decl, int reloc) string = ACONCAT ((linkonce, prefix, ".", name, NULL)); - set_decl_section_name (decl, build_string (strlen (string), string)); + set_decl_section_name (decl, string); } /* Like compute_reloc_for_constant, except for an RTX. The return value @@ -6764,7 +6774,7 @@ default_binds_local_p_1 (const_tree exp, int shlib) definition from different object file) and when resolution info is available we simply use the knowledge passed to us by linker plugin. */ bool -decl_binds_to_current_def_p (tree decl) +decl_binds_to_current_def_p (const_tree decl) { gcc_assert (DECL_P (decl)); if (!targetm.binds_local_p (decl)) diff --git a/gcc/varasm.h b/gcc/varasm.h index 01b0850eb2c..aa9d47a5a65 100644 --- a/gcc/varasm.h +++ b/gcc/varasm.h @@ -32,7 +32,7 @@ extern void notice_global_symbol (tree); extern void set_user_assembler_name (tree, const char *); extern void process_pending_assemble_externals (void); extern bool decl_replaceable_p (tree); -extern bool decl_binds_to_current_def_p (tree); +extern bool decl_binds_to_current_def_p (const_tree); extern enum tls_model decl_default_tls_model (const_tree); /* Declare DECL to be a weak symbol. */ diff --git a/gcc/web.c b/gcc/web.c index 2c038f2bb81..0e9f5da5db5 100644 --- a/gcc/web.c +++ b/gcc/web.c @@ -93,8 +93,8 @@ union_match_dups (rtx insn, struct web_entry *def_entry, bool (*fun) (struct web_entry *, struct web_entry *)) { struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); - df_ref *use_link = DF_INSN_INFO_USES (insn_info); - df_ref *def_link = DF_INSN_INFO_DEFS (insn_info); + df_ref use_link = DF_INSN_INFO_USES (insn_info); + df_ref def_link = DF_INSN_INFO_DEFS (insn_info); struct web_entry *dup_entry; int i; @@ -104,18 +104,19 @@ union_match_dups (rtx insn, struct web_entry *def_entry, { int op = recog_data.dup_num[i]; enum op_type type = recog_data.operand_type[op]; - df_ref *ref, *dupref; + df_ref ref, dupref; struct web_entry *entry; - for (dup_entry = use_entry, dupref = use_link; *dupref; dupref++) - if (DF_REF_LOC (*dupref) == recog_data.dup_loc[i]) + dup_entry = use_entry; + for (dupref = use_link; dupref; dupref = DF_REF_NEXT_LOC (dupref)) + if (DF_REF_LOC (dupref) == recog_data.dup_loc[i]) break; - if (*dupref == NULL && type == OP_INOUT) + if (dupref == NULL && type == OP_INOUT) { - - for (dup_entry = def_entry, dupref = def_link; *dupref; dupref++) - if (DF_REF_LOC (*dupref) == recog_data.dup_loc[i]) + dup_entry = def_entry; + for (dupref = def_link; dupref; dupref = DF_REF_NEXT_LOC (dupref)) + if (DF_REF_LOC (dupref) == recog_data.dup_loc[i]) break; } /* ??? *DUPREF can still be zero, because when an operand matches @@ -125,35 +126,36 @@ union_match_dups (rtx insn, struct web_entry *def_entry, even though it is there. Example: i686-pc-linux-gnu gcc.c-torture/compile/950607-1.c -O3 -fomit-frame-pointer -funroll-loops */ - if (*dupref == NULL - || DF_REF_REGNO (*dupref) < FIRST_PSEUDO_REGISTER) + if (dupref == NULL + || DF_REF_REGNO (dupref) < FIRST_PSEUDO_REGISTER) continue; ref = type == OP_IN ? use_link : def_link; entry = type == OP_IN ? use_entry : def_entry; - for (; *ref; ref++) + for (; ref; ref = DF_REF_NEXT_LOC (ref)) { - rtx *l = DF_REF_LOC (*ref); + rtx *l = DF_REF_LOC (ref); if (l == recog_data.operand_loc[op]) break; - if (l && DF_REF_REAL_LOC (*ref) == recog_data.operand_loc[op]) + if (l && DF_REF_REAL_LOC (ref) == recog_data.operand_loc[op]) break; } - if (!*ref && type == OP_INOUT) + if (!ref && type == OP_INOUT) { - for (ref = use_link, entry = use_entry; *ref; ref++) + entry = use_entry; + for (ref = use_link; ref; ref = DF_REF_NEXT_LOC (ref)) { - rtx *l = DF_REF_LOC (*ref); + rtx *l = DF_REF_LOC (ref); if (l == recog_data.operand_loc[op]) break; - if (l && DF_REF_REAL_LOC (*ref) == recog_data.operand_loc[op]) + if (l && DF_REF_REAL_LOC (ref) == recog_data.operand_loc[op]) break; } } - gcc_assert (*ref); - (*fun) (dup_entry + DF_REF_ID (*dupref), entry + DF_REF_ID (*ref)); + gcc_assert (ref); + (*fun) (dup_entry + DF_REF_ID (dupref), entry + DF_REF_ID (ref)); } } @@ -173,51 +175,34 @@ union_defs (df_ref use, struct web_entry *def_entry, { struct df_insn_info *insn_info = DF_REF_INSN_INFO (use); struct df_link *link = DF_REF_CHAIN (use); - df_ref *eq_use_link; - df_ref *def_link; rtx set; if (insn_info) { - rtx insn = insn_info->insn; - eq_use_link = DF_INSN_INFO_EQ_USES (insn_info); - def_link = DF_INSN_INFO_DEFS (insn_info); - set = single_set (insn); + df_ref eq_use; + + set = single_set (insn_info->insn); + FOR_EACH_INSN_INFO_EQ_USE (eq_use, insn_info) + if (use != eq_use + && DF_REF_REAL_REG (use) == DF_REF_REAL_REG (eq_use)) + (*fun) (use_entry + DF_REF_ID (use), use_entry + DF_REF_ID (eq_use)); } else - { - /* An artificial use. It links up with nothing. */ - eq_use_link = NULL; - def_link = NULL; - set = NULL; - } + set = NULL; /* Union all occurrences of the same register in reg notes. */ - if (eq_use_link) - while (*eq_use_link) - { - if (use != *eq_use_link - && DF_REF_REAL_REG (use) == DF_REF_REAL_REG (*eq_use_link)) - (*fun) (use_entry + DF_REF_ID (use), - use_entry + DF_REF_ID (*eq_use_link)); - eq_use_link++; - } - /* Recognize trivial noop moves and attempt to keep them as noop. */ if (set && SET_SRC (set) == DF_REF_REG (use) && SET_SRC (set) == SET_DEST (set)) { - if (def_link) - while (*def_link) - { - if (DF_REF_REAL_REG (use) == DF_REF_REAL_REG (*def_link)) - (*fun) (use_entry + DF_REF_ID (use), - def_entry + DF_REF_ID (*def_link)); - def_link++; - } + df_ref def; + + FOR_EACH_INSN_INFO_DEF (def, insn_info) + if (DF_REF_REAL_REG (use) == DF_REF_REAL_REG (def)) + (*fun) (use_entry + DF_REF_ID (use), def_entry + DF_REF_ID (def)); } /* UD chains of uninitialized REGs are empty. Keeping all uses of @@ -248,23 +233,14 @@ union_defs (df_ref use, struct web_entry *def_entry, /* A READ_WRITE use requires the corresponding def to be in the same register. Find it and union. */ if (DF_REF_FLAGS (use) & DF_REF_READ_WRITE) - { - df_ref *link; + if (insn_info) + { + df_ref def; - if (insn_info) - link = DF_INSN_INFO_DEFS (insn_info); - else - link = NULL; - - if (link) - while (*link) - { - if (DF_REF_REAL_REG (*link) == DF_REF_REAL_REG (use)) - (*fun) (use_entry + DF_REF_ID (use), - def_entry + DF_REF_ID (*link)); - link++; - } - } + FOR_EACH_INSN_INFO_DEF (def, insn_info) + if (DF_REF_REAL_REG (use) == DF_REF_REAL_REG (def)) + (*fun) (use_entry + DF_REF_ID (use), def_entry + DF_REF_ID (def)); + } } /* Find the corresponding register for the given entry. */ @@ -375,22 +351,16 @@ pass_web::execute (function *fun) FOR_ALL_BB_FN (bb, fun) FOR_BB_INSNS (bb, insn) { - unsigned int uid = INSN_UID (insn); if (NONDEBUG_INSN_P (insn)) { - df_ref *use_rec; - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) - DF_REF_ID (use) = uses_num++; - } - for (use_rec = DF_INSN_UID_EQ_USES (uid); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) - DF_REF_ID (use) = uses_num++; - } + struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); + df_ref use; + FOR_EACH_INSN_INFO_USE (use, insn_info) + if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) + DF_REF_ID (use) = uses_num++; + FOR_EACH_INSN_INFO_EQ_USE (use, insn_info) + if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) + DF_REF_ID (use) = uses_num++; } } @@ -402,34 +372,23 @@ pass_web::execute (function *fun) /* Produce the web. */ FOR_ALL_BB_FN (bb, fun) FOR_BB_INSNS (bb, insn) - { - unsigned int uid = INSN_UID (insn); if (NONDEBUG_INSN_P (insn)) { - df_ref *use_rec; + struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); + df_ref use; union_match_dups (insn, def_entry, use_entry, unionfind_union); - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) - union_defs (use, def_entry, used, use_entry, unionfind_union); - } - for (use_rec = DF_INSN_UID_EQ_USES (uid); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) - union_defs (use, def_entry, used, use_entry, unionfind_union); - } + FOR_EACH_INSN_INFO_USE (use, insn_info) + if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) + union_defs (use, def_entry, used, use_entry, unionfind_union); + FOR_EACH_INSN_INFO_EQ_USE (use, insn_info) + if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) + union_defs (use, def_entry, used, use_entry, unionfind_union); } - } /* Update the instruction stream, allocating new registers for split pseudos in progress. */ FOR_ALL_BB_FN (bb, fun) FOR_BB_INSNS (bb, insn) - { - unsigned int uid = INSN_UID (insn); - if (NONDEBUG_INSN_P (insn) /* Ignore naked clobber. For example, reg 134 in the second insn of the following sequence will not be replaced. @@ -441,28 +400,21 @@ pass_web::execute (function *fun) Thus the later passes can optimize them away. */ && GET_CODE (PATTERN (insn)) != CLOBBER) { - df_ref *use_rec; - df_ref *def_rec; - for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) - replace_ref (use, entry_register (use_entry + DF_REF_ID (use), use, used)); - } - for (use_rec = DF_INSN_UID_EQ_USES (uid); *use_rec; use_rec++) - { - df_ref use = *use_rec; - if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) - replace_ref (use, entry_register (use_entry + DF_REF_ID (use), use, used)); - } - for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++) - { - df_ref def = *def_rec; - if (DF_REF_REGNO (def) >= FIRST_PSEUDO_REGISTER) - replace_ref (def, entry_register (def_entry + DF_REF_ID (def), def, used)); - } + struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); + df_ref def, use; + FOR_EACH_INSN_INFO_USE (use, insn_info) + if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) + replace_ref (use, entry_register (use_entry + DF_REF_ID (use), + use, used)); + FOR_EACH_INSN_INFO_EQ_USE (use, insn_info) + if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER) + replace_ref (use, entry_register (use_entry + DF_REF_ID (use), + use, used)); + FOR_EACH_INSN_INFO_DEF (def, insn_info) + if (DF_REF_REGNO (def) >= FIRST_PSEUDO_REGISTER) + replace_ref (def, entry_register (def_entry + DF_REF_ID (def), + def, used)); } - } free (def_entry); free (use_entry); |