diff options
author | Martin Liska <mliska@suse.cz> | 2022-07-12 13:23:53 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-07-12 13:23:53 +0200 |
commit | b9dc4e9c94877b52037f2bd4eb01b5d179e41a43 (patch) | |
tree | 11152b01244ee927fbf5460e08a200e03be0fdf5 /gcc | |
parent | c9de7a601878148247a44c4b04f550daa27cd556 (diff) | |
parent | 220bef460153a0296e947f16492d35e67b1b5b22 (diff) | |
download | gcc-b9dc4e9c94877b52037f2bd4eb01b5d179e41a43.zip gcc-b9dc4e9c94877b52037f2bd4eb01b5d179e41a43.tar.gz gcc-b9dc4e9c94877b52037f2bd4eb01b5d179e41a43.tar.bz2 |
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc')
36 files changed, 942 insertions, 376 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fa3578e..3db624b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,184 @@ +2022-07-11 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/106234 + * gimple-range-cache.cc (ranger_cache::range_from_dom): Check dominator + cache value before recursively resolving it. + +2022-07-11 Roger Sayle <roger@nextmovesoftware.com> + + * config/i386/i386-features.h (scalar_chain): Add fields + insns_conv, n_sse_to_integer and n_integer_to_sse to this + parent class, moved from general_scalar_chain. + (scalar_chain::convert_compare): Protected method moved + from general_scalar_chain. + (mark_dual_mode_def): Make protected, not private virtual. + (scalar_chain:convert_op): New private virtual method. + (general_scalar_chain::general_scalar_chain): Simplify constructor. + (general_scalar_chain::~general_scalar_chain): Delete destructor. + (general_scalar_chain): Move insns_conv, n_sse_to_integer and + n_integer_to_sse fields to parent class, scalar_chain. + (general_scalar_chain::mark_dual_mode_def): Delete prototype. + (general_scalar_chain::convert_compare): Delete prototype. + (timode_scalar_chain::compute_convert_gain): Remove simplistic + implementation, convert to a method prototype. + (timode_scalar_chain::mark_dual_mode_def): Delete prototype. + (timode_scalar_chain::convert_op): Prototype new virtual method. + * config/i386/i386-features.cc (scalar_chain::scalar_chain): + Allocate insns_conv and initialize n_sse_to_integer and + n_integer_to_sse fields in constructor. + (scalar_chain::scalar_chain): Free insns_conv in destructor. + (general_scalar_chain::general_scalar_chain): Delete + constructor, now defined in the class declaration. + (general_scalar_chain::~general_scalar_chain): Delete destructor. + (scalar_chain::mark_dual_mode_def): Renamed from + general_scalar_chain::mark_dual_mode_def. + (timode_scalar_chain::mark_dual_mode_def): Delete. + (scalar_chain::convert_compare): Renamed from + general_scalar_chain::convert_compare. + (timode_scalar_chain::compute_convert_gain): New method to + determine the gain from converting a TImode chain to V1TImode. + (timode_scalar_chain::convert_op): New method to convert an + operand from TImode to V1TImode. + (timode_scalar_chain::convert_insn) <case REG>: Only PUT_MODE + on REG_EQUAL notes that were originally TImode (not CONST_INT). + Handle AND, ANDN, XOR, IOR, NOT and COMPARE. + (timode_mem_p): Helper predicate to check where operand is + memory reference with sufficient alignment for TImode STV. + (timode_scalar_to_vector_candidate_p): Use convertible_comparison_p + to check whether COMPARE is convertible. Handle SET_DESTs that + that are REG_P or MEM_P and SET_SRCs that are REG, CONST_INT, + CONST_WIDE_INT, MEM, AND, ANDN, IOR, XOR or NOT. + +2022-07-11 Richard Sandiford <richard.sandiford@arm.com> + + PR tree-optimization/106250 + * tree-vect-loop.cc (vectorizable_reduction): Reinstate final + argument to directly_supported_p. + +2022-07-11 Richard Biener <rguenther@suse.de> + + * tree-into-ssa.cc (update_ssa): Do not forcefully + re-compute dominance fast queries for TODO_update_ssa_no_phi. + +2022-07-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/106228 + * tree-vect-data-refs.cc (vect_setup_realignment): Adjust + VUSE compute for the non-loop case. + +2022-07-11 Richard Biener <rguenther@suse.de> + + * tree-into-ssa.cc (rewrite_mode::REWRITE_UPDATE_REGION): New. + (rewrite_update_dom_walker::rewrite_update_dom_walker): Update. + (rewrite_update_dom_walker::m_in_region_flag): New. + (rewrite_update_dom_walker::before_dom_children): If the region + to update is marked, STOP at exits. + (rewrite_blocks): For REWRITE_UPDATE_REGION mark the region + to be updated. + (dump_update_ssa): Use bitmap_empty_p. + (update_ssa): Likewise. Use REWRITE_UPDATE_REGION when + TODO_update_ssa_no_phi. + * tree-cfgcleanup.cc (cleanup_tree_cfg_noloop): Account + pending update_ssa to the caller. + +2022-07-11 Richard Biener <rguenthert@suse.de> + + PR target/105459 + * config/i386/i386-options.cc (ix86_set_current_function): + Rebuild the target optimization node whenever necessary, + not only when the optimization node didn't change. + +2022-07-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/106228 + * tree-vect-data-refs.cc (vect_setup_realignment): Properly + set a VUSE operand on the emitted load. + +2022-07-11 Aldy Hernandez <aldyh@redhat.com> + + * gimple-range.cc (gimple_ranger::export_global_ranges): Remove + verification against legacy value_range. + (gimple_ranger::register_inferred_ranges): Same. + (gimple_ranger::export_global_ranges): Rename update_global_range + to set_range_info. + * tree-core.h (struct range_info_def): Remove. + (struct irange_storage_slot): New. + (struct tree_base): Remove SSA_NAME_ANTI_RANGE_P documentation. + (struct tree_ssa_name): Add vrange_storage support. + * tree-ssanames.cc (range_info_p): New. + (range_info_fits_p): New. + (range_info_alloc): New. + (range_info_free): New. + (range_info_get_range): New. + (range_info_set_range): New. + (set_range_info_raw): Remove. + (set_range_info): Adjust to use vrange_storage. + (set_nonzero_bits): Same. + (get_nonzero_bits): Same. + (duplicate_ssa_name_range_info): Remove overload taking + value_range_kind. + Rewrite tree overload to use vrange_storage. + (duplicate_ssa_name_fn): Adjust to use vrange_storage. + * tree-ssanames.h (struct range_info_def): Remove. + (set_range_info): Adjust prototype to take vrange. + * tree-vrp.cc (vrp_asserts::remove_range_assertions): Call + duplicate_ssa_name_range_info. + * tree.h (SSA_NAME_ANTI_RANGE_P): Remove. + (SSA_NAME_RANGE_TYPE): Remove. + * value-query.cc (get_ssa_name_range_info): Adjust to use + vrange_storage. + (update_global_range): Remove. + (get_range_global): Remove as_a<irange>. + * value-query.h (update_global_range): Remove. + * tree-ssa-dom.cc (set_global_ranges_from_unreachable_edges): + Rename update_global_range to set_range_info. + * value-range-storage.cc (vrange_storage::alloc_slot): Remove + gcc_unreachable. + +2022-07-10 Aldy Hernandez <aldyh@redhat.com> + + * value-range.cc (irange::operator=): Call verify_range. + (irange::irange_set): Normalize kind after everything else has + been set. + (irange::irange_set_anti_range): Same. + (irange::set): Same. + (irange::verify_range): Disallow nonzero masks for VARYING. + (irange::irange_union): Call verify_range. + Handle nonzero masks better. + (irange::irange_intersect): Same. + (irange::set_nonzero_bits): Calculate mask if either range has an + explicit mask. + (irange::intersect_nonzero_bits): Same. + (irange::union_nonzero_bits): Same. + (range_tests_nonzero_bits): New. + (range_tests): Call range_tests_nonzero_bits. + * value-range.h (class irange): Remove set_nonzero_bits method + with trees. + (irange::varying_compatible_p): Set nonzero mask. + +2022-07-10 Xi Ruoyao <xry111@xry111.site> + + * config/loongarch/loongarch.md (<any_div>di3_fake): Describe + the sign-extend of result in the RTL template. + (<any_div><mode>3): Adjust for <any_div>di3_fake change. + +2022-07-10 Xi Ruoyao <xry111@xry111.site> + + * config/loongarch/loongarch.cc (loongarch_check_zero_div_p): + Remove static, for use in the machine description file. + * config/loongarch/loongarch-protos.h: + (loongarch_check_zero_div_p): Add prototype. + * config/loongarch/loongarch.md (enabled): New attr. + (*<optab><mode>3): Add (=r,r,r) and (=&r,0,r) alternatives for + idiv. Conditionally enable the alternatives using + loongarch_check_zero_div_p. + (<optab>di3_fake): Likewise. + +2022-07-10 Xi Ruoyao <xry111@xry111.site> + + * config/loongarch/loongarch.md (mulsidi3_64bit): Use mulw.d.w + instead of mul.d. + 2022-07-09 Aldy Hernandez <aldyh@redhat.com> * value-range.cc (irange::irange_single_pair_union): Set diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 6de1e01..40dba6d 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20220710 +20220712 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index e16014f..d46eb18 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2022-07-11 Lewis Hyatt <lhyatt@gmail.com> + + PR preprocessor/106252 + * c-pragma.cc (handle_pragma_diagnostic_impl): Don't look up the + option argument prior to verifying the option was found. + 2022-07-07 David Malcolm <dmalcolm@redhat.com> * c-format.cc (range_label_for_format_type_mismatch::get_text): diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc index 62bce2e..789719e 100644 --- a/gcc/c-family/c-pragma.cc +++ b/gcc/c-family/c-pragma.cc @@ -1009,10 +1009,6 @@ handle_pragma_diagnostic_impl () if (early && !c_option_is_from_cpp_diagnostics (option_index)) return; - const char *arg = NULL; - if (cl_options[option_index].flags & CL_JOINED) - arg = data.option_str + 1 + cl_options[option_index].opt_len; - if (option_index == OPT_SPECIAL_unknown) { if (want_diagnostics) @@ -1052,6 +1048,10 @@ handle_pragma_diagnostic_impl () return; } + const char *arg = NULL; + if (cl_options[option_index].flags & CL_JOINED) + arg = data.option_str + 1 + cl_options[option_index].opt_len; + struct cl_option_handlers handlers; set_default_handlers (&handlers, NULL); /* FIXME: input_location isn't the best location here, but it is diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 989f293..3aa672b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2022-07-10 Lewis Hyatt <lhyatt@gmail.com> + + PR preprocessor/97498 + * c-parser.cc (c_parser_pragma): Set input_location to the + location of the pragma, rather than the start of the line. + 2022-07-04 Tobias Burnus <tobias@codesourcery.com> Chung-Lin Tang <cltang@codesourcery.com> Thomas Schwinge <thomas@codesourcery.com> diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 9c02141..92049d1 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -12397,6 +12397,7 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p) unsigned int id; const char *construct = NULL; + input_location = c_parser_peek_token (parser)->location; id = c_parser_peek_token (parser)->pragma_kind; gcc_assert (id != PRAGMA_NONE); diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index a7bd172..f1b03c3 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -291,7 +291,11 @@ scalar_chain::scalar_chain (enum machine_mode smode_, enum machine_mode vmode_) insns = BITMAP_ALLOC (NULL); defs = BITMAP_ALLOC (NULL); defs_conv = BITMAP_ALLOC (NULL); + insns_conv = BITMAP_ALLOC (NULL); queue = NULL; + + n_sse_to_integer = 0; + n_integer_to_sse = 0; } /* Free chain's data. */ @@ -301,6 +305,7 @@ scalar_chain::~scalar_chain () BITMAP_FREE (insns); BITMAP_FREE (defs); BITMAP_FREE (defs_conv); + BITMAP_FREE (insns_conv); bitmap_obstack_release (NULL); } @@ -319,25 +324,11 @@ scalar_chain::add_to_queue (unsigned insn_uid) bitmap_set_bit (queue, insn_uid); } -general_scalar_chain::general_scalar_chain (enum machine_mode smode_, - enum machine_mode vmode_) - : scalar_chain (smode_, vmode_) -{ - insns_conv = BITMAP_ALLOC (NULL); - n_sse_to_integer = 0; - n_integer_to_sse = 0; -} - -general_scalar_chain::~general_scalar_chain () -{ - BITMAP_FREE (insns_conv); -} - /* For DImode conversion, mark register defined by DEF as requiring conversion. */ void -general_scalar_chain::mark_dual_mode_def (df_ref def) +scalar_chain::mark_dual_mode_def (df_ref def) { gcc_assert (DF_REF_REG_DEF_P (def)); @@ -364,14 +355,6 @@ general_scalar_chain::mark_dual_mode_def (df_ref def) DF_REF_REGNO (def), DF_REF_INSN_UID (def), chain_id); } -/* For TImode conversion, it is unused. */ - -void -timode_scalar_chain::mark_dual_mode_def (df_ref) -{ - gcc_unreachable (); -} - /* Check REF's chain to add new insns into a queue and find registers requiring conversion. */ @@ -934,7 +917,7 @@ general_scalar_chain::convert_op (rtx *op, rtx_insn *insn) /* Convert COMPARE to vector mode. */ rtx -general_scalar_chain::convert_compare (rtx op1, rtx op2, rtx_insn *insn) +scalar_chain::convert_compare (rtx op1, rtx op2, rtx_insn *insn) { rtx tmp = gen_reg_rtx (vmode); rtx src; @@ -1068,7 +1051,7 @@ general_scalar_chain::convert_insn (rtx_insn *insn) emit_conversion_insns (gen_move_insn (dst, tmp), insn); dst = gen_rtx_SUBREG (vmode, tmp, 0); } - else if (REG_P (dst)) + else if (REG_P (dst) && GET_MODE (dst) == smode) { /* Replace the definition with a SUBREG to the definition we use inside the chain. */ @@ -1173,6 +1156,83 @@ general_scalar_chain::convert_insn (rtx_insn *insn) df_insn_rescan (insn); } +/* Compute a gain for chain conversion. */ + +int +timode_scalar_chain::compute_convert_gain () +{ + /* Assume that if we have to move TImode values between units, + then transforming this chain isn't worth it. */ + if (n_sse_to_integer || n_integer_to_sse) + return -1; + + bitmap_iterator bi; + unsigned insn_uid; + + /* Split ties to prefer V1TImode when not optimizing for size. */ + int gain = optimize_size ? 0 : 1; + + if (dump_file) + fprintf (dump_file, "Computing gain for chain #%d...\n", chain_id); + + EXECUTE_IF_SET_IN_BITMAP (insns, 0, insn_uid, bi) + { + rtx_insn *insn = DF_INSN_UID_GET (insn_uid)->insn; + rtx def_set = single_set (insn); + rtx src = SET_SRC (def_set); + rtx dst = SET_DEST (def_set); + int igain = 0; + + switch (GET_CODE (src)) + { + case REG: + if (optimize_insn_for_size_p ()) + igain = MEM_P (dst) ? COSTS_N_BYTES (6) : COSTS_N_BYTES (3); + else + igain = COSTS_N_INSNS (1); + break; + + case MEM: + igain = optimize_insn_for_size_p () ? COSTS_N_BYTES (7) + : COSTS_N_INSNS (1); + break; + + case CONST_INT: + if (MEM_P (dst) + && standard_sse_constant_p (src, V1TImode)) + igain = optimize_insn_for_size_p() ? COSTS_N_BYTES (11) : 1; + break; + + case NOT: + if (MEM_P (dst)) + igain = -COSTS_N_INSNS (1); + break; + + case AND: + case XOR: + case IOR: + if (!MEM_P (dst)) + igain = COSTS_N_INSNS (1); + break; + + default: + break; + } + + if (igain != 0 && dump_file) + { + fprintf (dump_file, " Instruction gain %d for ", igain); + dump_insn_slim (dump_file, insn); + } + gain += igain; + } + + if (dump_file) + fprintf (dump_file, " Total gain: %d\n", gain); + + return gain; +} + /* Fix uses of converted REG in debug insns. */ void @@ -1211,6 +1271,61 @@ timode_scalar_chain::fix_debug_reg_uses (rtx reg) } } +/* Convert operand OP in INSN from TImode to V1TImode. */ + +void +timode_scalar_chain::convert_op (rtx *op, rtx_insn *insn) +{ + *op = copy_rtx_if_shared (*op); + + if (REG_P (*op)) + *op = gen_rtx_SUBREG (V1TImode, *op, 0); + else if (MEM_P (*op)) + { + rtx tmp = gen_reg_rtx (V1TImode); + emit_insn_before (gen_rtx_SET (gen_rtx_SUBREG (V1TImode, tmp, 0), + gen_gpr_to_xmm_move_src (V1TImode, *op)), + insn); + *op = gen_rtx_SUBREG (V1TImode, tmp, 0); + + if (dump_file) + fprintf (dump_file, " Preloading operand for insn %d into r%d\n", + INSN_UID (insn), REGNO (tmp)); + } + else if (CONST_INT_P (*op)) + { + rtx vec_cst; + rtx tmp = gen_rtx_SUBREG (V1TImode, gen_reg_rtx (TImode), 0); + + /* Prefer all ones vector in case of -1. */ + if (constm1_operand (*op, TImode)) + vec_cst = CONSTM1_RTX (V1TImode); + else + { + rtx *v = XALLOCAVEC (rtx, 1); + v[0] = *op; + vec_cst = gen_rtx_CONST_VECTOR (V1TImode, gen_rtvec_v (1, v)); + } + + if (!standard_sse_constant_p (vec_cst, V1TImode)) + { + start_sequence (); + vec_cst = validize_mem (force_const_mem (V1TImode, vec_cst)); + rtx_insn *seq = get_insns (); + end_sequence (); + emit_insn_before (seq, insn); + } + + emit_insn_before (gen_move_insn (copy_rtx (tmp), vec_cst), insn); + *op = tmp; + } + else + { + gcc_assert (SUBREG_P (*op)); + gcc_assert (GET_MODE (*op) == vmode); + } +} + /* Convert INSN from TImode to V1T1mode. */ void @@ -1219,17 +1334,24 @@ timode_scalar_chain::convert_insn (rtx_insn *insn) rtx def_set = single_set (insn); rtx src = SET_SRC (def_set); rtx dst = SET_DEST (def_set); + rtx tmp; + if (MEM_P (dst) && !REG_P (src)) + { + /* There are no scalar integer instructions and therefore + temporary register usage is required. */ + } switch (GET_CODE (dst)) { case REG: - { - rtx tmp = find_reg_equal_equiv_note (insn); - if (tmp) - PUT_MODE (XEXP (tmp, 0), V1TImode); - PUT_MODE (dst, V1TImode); - fix_debug_reg_uses (dst); - } + if (GET_MODE (dst) == TImode) + { + tmp = find_reg_equal_equiv_note (insn); + if (tmp && GET_MODE (XEXP (tmp, 0)) == TImode) + PUT_MODE (XEXP (tmp, 0), V1TImode); + PUT_MODE (dst, V1TImode); + fix_debug_reg_uses (dst); + } break; case MEM: PUT_MODE (dst, V1TImode); @@ -1257,7 +1379,6 @@ timode_scalar_chain::convert_insn (rtx_insn *insn) { /* Since there are no instructions to store 128-bit constant, temporary register usage is required. */ - rtx tmp = gen_reg_rtx (V1TImode); start_sequence (); src = gen_rtx_CONST_VECTOR (V1TImode, gen_rtvec (1, src)); src = validize_mem (force_const_mem (V1TImode, src)); @@ -1265,8 +1386,12 @@ timode_scalar_chain::convert_insn (rtx_insn *insn) end_sequence (); if (seq) emit_insn_before (seq, insn); - emit_conversion_insns (gen_rtx_SET (dst, tmp), insn); - dst = tmp; + if (MEM_P (dst)) + { + tmp = gen_reg_rtx (V1TImode); + emit_insn_before (gen_rtx_SET (tmp, src), insn); + src = tmp; + } } break; @@ -1282,16 +1407,57 @@ timode_scalar_chain::convert_insn (rtx_insn *insn) default: gcc_unreachable (); } - if (NONDEBUG_INSN_P (insn)) + if (MEM_P (dst)) + { + tmp = gen_reg_rtx (V1TImode); + emit_insn_before (gen_rtx_SET (tmp, src), insn); + src = tmp; + } + break; + + case AND: + if (GET_CODE (XEXP (src, 0)) == NOT) + { + convert_op (&XEXP (XEXP (src, 0), 0), insn); + convert_op (&XEXP (src, 1), insn); + PUT_MODE (XEXP (src, 0), V1TImode); + PUT_MODE (src, V1TImode); + break; + } + /* FALLTHRU */ + + case XOR: + case IOR: + convert_op (&XEXP (src, 0), insn); + convert_op (&XEXP (src, 1), insn); + PUT_MODE (src, V1TImode); + if (MEM_P (dst)) { - rtx tmp = gen_reg_rtx (V1TImode); - /* Since there are no instructions to store standard SSE - constant, temporary register usage is required. */ - emit_conversion_insns (gen_rtx_SET (dst, tmp), insn); - dst = tmp; + tmp = gen_reg_rtx (V1TImode); + emit_insn_before (gen_rtx_SET (tmp, src), insn); + src = tmp; } break; + case NOT: + src = XEXP (src, 0); + convert_op (&src, insn); + tmp = gen_reg_rtx (V1TImode); + emit_insn_before (gen_move_insn (tmp, CONSTM1_RTX (V1TImode)), insn); + src = gen_rtx_XOR (V1TImode, src, tmp); + if (MEM_P (dst)) + { + tmp = gen_reg_rtx (V1TImode); + emit_insn_before (gen_rtx_SET (tmp, src), insn); + src = tmp; + } + break; + + case COMPARE: + dst = gen_rtx_REG (CCmode, FLAGS_REG); + src = convert_compare (XEXP (src, 0), XEXP (src, 1), insn); + break; + default: gcc_unreachable (); } @@ -1551,6 +1717,16 @@ general_scalar_to_vector_candidate_p (rtx_insn *insn, enum machine_mode mode) return true; } +/* Check for a suitable TImode memory operand. */ + +static bool +timode_mem_p (rtx x) +{ + return MEM_P (x) + && (TARGET_SSE_UNALIGNED_LOAD_OPTIMAL + || !misaligned_operand (x, TImode)); +} + /* The TImode version of scalar_to_vector_candidate_p. */ static bool @@ -1564,45 +1740,59 @@ timode_scalar_to_vector_candidate_p (rtx_insn *insn) rtx src = SET_SRC (def_set); rtx dst = SET_DEST (def_set); - /* Only TImode load and store are allowed. */ - if (GET_MODE (dst) != TImode) + if (GET_CODE (src) == COMPARE) + return convertible_comparison_p (insn, TImode); + + if (GET_MODE (dst) != TImode + || (GET_MODE (src) != TImode + && !CONST_SCALAR_INT_P (src))) return false; - if (MEM_P (dst)) - { - /* Check for store. Memory must be aligned or unaligned store - is optimal. Only support store from register, standard SSE - constant or CONST_WIDE_INT generated from piecewise store. + if (!REG_P (dst) && !MEM_P (dst)) + return false; - ??? Verify performance impact before enabling CONST_INT for - __int128 store. */ - if (misaligned_operand (dst, TImode) - && !TARGET_SSE_UNALIGNED_STORE_OPTIMAL) - return false; + if (MEM_P (dst) + && misaligned_operand (dst, TImode) + && !TARGET_SSE_UNALIGNED_STORE_OPTIMAL) + return false; - switch (GET_CODE (src)) - { - default: - return false; + switch (GET_CODE (src)) + { + case REG: + case CONST_WIDE_INT: + return true; - case REG: - case CONST_WIDE_INT: - return true; + case CONST_INT: + /* ??? Verify performance impact before enabling CONST_INT for + __int128 store. */ + return standard_sse_constant_p (src, TImode); - case CONST_INT: - return standard_sse_constant_p (src, TImode); - } - } - else if (MEM_P (src)) - { - /* Check for load. Memory must be aligned or unaligned load is - optimal. */ + case MEM: + /* Memory must be aligned or unaligned load is optimal. */ return (REG_P (dst) && (!misaligned_operand (src, TImode) || TARGET_SSE_UNALIGNED_LOAD_OPTIMAL)); - } - return false; + case AND: + if (!MEM_P (dst) + && GET_CODE (XEXP (src, 0)) == NOT + && REG_P (XEXP (XEXP (src, 0), 0)) + && (REG_P (XEXP (src, 1)) || timode_mem_p (XEXP (src, 1)))) + return true; + return REG_P (XEXP (src, 0)) + && (REG_P (XEXP (src, 1)) || timode_mem_p (XEXP (src, 1))); + + case IOR: + case XOR: + return REG_P (XEXP (src, 0)) + && (REG_P (XEXP (src, 1)) || timode_mem_p (XEXP (src, 1))); + + case NOT: + return REG_P (XEXP (src, 0)) || timode_mem_p (XEXP (src, 0)); + + default: + return false; + } } /* For a register REGNO, scan instructions for its defs and uses. diff --git a/gcc/config/i386/i386-features.h b/gcc/config/i386/i386-features.h index 839b63c..88b222d 100644 --- a/gcc/config/i386/i386-features.h +++ b/gcc/config/i386/i386-features.h @@ -148,6 +148,10 @@ class scalar_chain /* Registers used in both vector and sclar modes. */ bitmap defs_conv; + bitmap insns_conv; + unsigned n_sse_to_integer; + unsigned n_integer_to_sse; + void build (bitmap candidates, unsigned insn_uid); virtual int compute_convert_gain () = 0; int convert (); @@ -155,33 +159,31 @@ class scalar_chain protected: void add_to_queue (unsigned insn_uid); void emit_conversion_insns (rtx insns, rtx_insn *pos); + rtx convert_compare (rtx op1, rtx op2, rtx_insn *insn); + void mark_dual_mode_def (df_ref def); private: void add_insn (bitmap candidates, unsigned insn_uid); void analyze_register_chain (bitmap candidates, df_ref ref); - virtual void mark_dual_mode_def (df_ref def) = 0; virtual void convert_insn (rtx_insn *insn) = 0; virtual void convert_registers () = 0; + virtual void convert_op (rtx *op, rtx_insn *insn) = 0; }; class general_scalar_chain : public scalar_chain { public: - general_scalar_chain (enum machine_mode smode_, enum machine_mode vmode_); - ~general_scalar_chain (); + general_scalar_chain (enum machine_mode smode_, enum machine_mode vmode_) + : scalar_chain (smode_, vmode_) {} int compute_convert_gain () final override; + private: hash_map<rtx, rtx> defs_map; - bitmap insns_conv; - unsigned n_sse_to_integer; - unsigned n_integer_to_sse; - void mark_dual_mode_def (df_ref def) final override; void convert_insn (rtx_insn *insn) final override; - void convert_op (rtx *op, rtx_insn *insn); void convert_reg (rtx_insn *insn, rtx dst, rtx src); + void convert_op (rtx *op, rtx_insn *insn); void make_vector_copies (rtx_insn *, rtx); void convert_registers () final override; - rtx convert_compare (rtx op1, rtx op2, rtx_insn *insn); int vector_const_cost (rtx exp); }; @@ -189,21 +191,20 @@ class timode_scalar_chain : public scalar_chain { public: timode_scalar_chain () : scalar_chain (TImode, V1TImode) {} - - /* Convert from TImode to V1TImode is always faster. */ - int compute_convert_gain () final override { return 1; } + int compute_convert_gain () final override; private: - void mark_dual_mode_def (df_ref def) final override; void fix_debug_reg_uses (rtx reg); void convert_insn (rtx_insn *insn) final override; - /* We don't convert registers to difference size. */ + void convert_op (rtx *op, rtx_insn *insn); + /* We don't convert registers to different size. */ void convert_registers () final override {} }; } // anon namespace -bool ix86_save_reg (unsigned int regno, bool maybe_eh_return, bool ignore_outlined); +bool ix86_save_reg (unsigned int regno, bool maybe_eh_return, + bool ignore_outlined); int ix86_compare_version_priority (tree decl1, tree decl2); tree ix86_generate_version_dispatcher_body (void *node_p); tree ix86_get_function_versions_dispatcher (void *decl); diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index e11f681..acb2291 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -3232,28 +3232,22 @@ ix86_set_current_function (tree fndecl) if (new_tree == NULL_TREE) new_tree = target_option_default_node; - if (old_tree != new_tree) + bool fp_flag_change + = (flag_unsafe_math_optimizations + != TREE_TARGET_OPTION (new_tree)->x_ix86_unsafe_math_optimizations + || (flag_excess_precision + != TREE_TARGET_OPTION (new_tree)->x_ix86_excess_precision)); + if (old_tree != new_tree || fp_flag_change) { cl_target_option_restore (&global_options, &global_options_set, TREE_TARGET_OPTION (new_tree)); - if (TREE_TARGET_GLOBALS (new_tree)) - restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); - else if (new_tree == target_option_default_node) - restore_target_globals (&default_target_globals); - else - TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts (); - } - else if (flag_unsafe_math_optimizations - != TREE_TARGET_OPTION (new_tree)->x_ix86_unsafe_math_optimizations - || (flag_excess_precision - != TREE_TARGET_OPTION (new_tree)->x_ix86_excess_precision)) - { - cl_target_option_restore (&global_options, &global_options_set, - TREE_TARGET_OPTION (new_tree)); - ix86_excess_precision = flag_excess_precision; - ix86_unsafe_math_optimizations = flag_unsafe_math_optimizations; - DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_tree - = build_target_option_node (&global_options, &global_options_set); + if (fp_flag_change) + { + ix86_excess_precision = flag_excess_precision; + ix86_unsafe_math_optimizations = flag_unsafe_math_optimizations; + DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_tree + = build_target_option_node (&global_options, &global_options_set); + } if (TREE_TARGET_GLOBALS (new_tree)) restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); else if (new_tree == target_option_default_node) diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 9be8bc6..da7b805 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -1359,10 +1359,11 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb, m_workback.quick_push (prev_bb); else if (mode == RFD_FILL) { - // Multiple incoming edges, so recursively satisfy this block, - // store the range, then calculate the incoming range for PREV_BB. - if (def_bb != bb) + // Multiple incoming edges, so recursively satisfy this block + // if it doesn't already have a value, and store the range. + if (!m_on_entry.bb_range_p (name, bb) && def_bb != bb) { + // If the dominator has not been set, look it up. range_from_dom (r, name, bb, RFD_FILL); // If the range can't be store, don't try to accumulate // the range in PREV_BB due to excessive recalculations. diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index 3a9f0b0..7ac4830 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -468,22 +468,12 @@ gimple_ranger::register_inferred_ranges (gimple *s) { Value_Range tmp (TREE_TYPE (lhs)); if (range_of_stmt (tmp, s, lhs) && !tmp.varying_p () - && update_global_range (tmp, lhs) && dump_file) + && set_range_info (lhs, tmp) && dump_file) { - // ?? This section should be adjusted when non-iranges can - // be exported. For now, the only way update_global_range - // above can succeed is with an irange so this is safe. - value_range vr = as_a <irange> (tmp); fprintf (dump_file, "Global Exported: "); print_generic_expr (dump_file, lhs, TDF_SLIM); fprintf (dump_file, " = "); - vr.dump (dump_file); - int_range_max same = vr; - if (same != as_a <irange> (tmp)) - { - fprintf (dump_file, " ... irange was : "); - tmp.dump (dump_file); - } + tmp.dump (dump_file); fputc ('\n', dump_file); } } @@ -509,7 +499,7 @@ gimple_ranger::export_global_ranges () && m_cache.get_global_range (r, name) && !r.varying_p()) { - bool updated = update_global_range (r, name); + bool updated = set_range_info (name, r); if (!updated || !dump_file) continue; @@ -522,22 +512,10 @@ gimple_ranger::export_global_ranges () print_header = false; } - if (!irange::supports_p (TREE_TYPE (name))) - continue; - - vrange &v = r; - value_range vr = as_a <irange> (v); print_generic_expr (dump_file, name , TDF_SLIM); fprintf (dump_file, " : "); - vr.dump (dump_file); + r.dump (dump_file); fprintf (dump_file, "\n"); - int_range_max same = vr; - if (same != as_a <irange> (v)) - { - fprintf (dump_file, " irange : "); - r.dump (dump_file); - fprintf (dump_file, "\n"); - } } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2030900..7b95680 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,55 @@ +2022-07-11 Roger Sayle <roger@nextmovesoftware.com> + + * gcc.target/i386/sse4_1-stv-2.c: New test case, pand. + * gcc.target/i386/sse4_1-stv-3.c: New test case, por. + * gcc.target/i386/sse4_1-stv-4.c: New test case, pxor. + * gcc.target/i386/sse4_1-stv-5.c: New test case, pandn. + * gcc.target/i386/sse4_1-stv-6.c: New test case, ptest. + +2022-07-11 Richard Sandiford <richard.sandiford@arm.com> + + PR tree-optimization/106250 + * gcc.dg/vect/pr106250.c: New file. + +2022-07-11 Thomas Schwinge <thomas@codesourcery.com> + + * c-c++-common/gomp/pragma-3.c: Enhance '_Pragma' diagnostics + verification. + * c-c++-common/gomp/pragma-5.c: Likewise. + +2022-07-11 Richard Biener <rguenthert@suse.de> + + PR target/105459 + * gcc.dg/lto/pr105459_0.c: New testcase. + +2022-07-10 Lewis Hyatt <lhyatt@gmail.com> + + PR preprocessor/97498 + * c-c++-common/pr97498.c: New test. + * c-c++-common/gomp/pragma-3.c: Adapt for improved warning locations. + * c-c++-common/gomp/pragma-5.c: Likewise. + * gcc.dg/pragma-message.c: Likewise. + +2022-07-10 Dimitar Dimitrov <dimitar@dinux.eu> + + PR tree-optimization/106063 + * gcc.dg/pr106063.c: Require effective target int128. + +2022-07-10 Xi Ruoyao <xry111@xry111.site> + + * gcc.target/loongarch/div-4.c: New test. + +2022-07-10 Xi Ruoyao <xry111@xry111.site> + + * gcc.target/loongarch/div-1.c: New test. + * gcc.target/loongarch/div-2.c: New test. + * gcc.target/loongarch/div-3.c: New test. + +2022-07-10 Xi Ruoyao <xry111@xry111.site> + + * gcc.target/loongarch/mulw_d_w.c: New test. + * gcc.c-torture/execute/mul-sext.c: New test. + 2022-07-09 Vit Kabele <vit.kabele@sysgo.com> * c-c++-common/Wpadded.c: New test. diff --git a/gcc/testsuite/c-c++-common/gomp/pragma-3.c b/gcc/testsuite/c-c++-common/gomp/pragma-3.c index c1dee1b..3e1b211 100644 --- a/gcc/testsuite/c-c++-common/gomp/pragma-3.c +++ b/gcc/testsuite/c-c++-common/gomp/pragma-3.c @@ -1,13 +1,16 @@ /* { dg-additional-options "-fdump-tree-original" } */ /* PR preprocessor/103165 */ -#define inner(...) #__VA_ARGS__ ; _Pragma("omp error severity(warning) message (\"Test\") at(compilation)") -#define outer(...) inner(__VA_ARGS__) +#define inner(...) #__VA_ARGS__ ; _Pragma("omp error severity(warning) message (\"Test\") at(compilation)") /* { dg-line inner_location } */ +#define outer(...) inner(__VA_ARGS__) /* { dg-line outer_location } */ void f (void) { - const char *str = outer(inner(1,2)); /* { dg-warning "'pragma omp error' encountered: Test" } */ + const char *str = outer(inner(1,2)); /* { dg-line str_location } */ + /* { dg-warning "35:'pragma omp error' encountered: Test" "" { target *-*-* } inner_location } + { dg-note "20:in expansion of macro 'inner'" "" { target *-*-* } outer_location } + { dg-note "21:in expansion of macro 'outer'" "" { target *-*-* } str_location } */ } #if 0 diff --git a/gcc/testsuite/c-c++-common/gomp/pragma-5.c b/gcc/testsuite/c-c++-common/gomp/pragma-5.c index af54b68..173c25e 100644 --- a/gcc/testsuite/c-c++-common/gomp/pragma-5.c +++ b/gcc/testsuite/c-c++-common/gomp/pragma-5.c @@ -1,13 +1,16 @@ /* { dg-additional-options "-fdump-tree-original" } */ /* PR preprocessor/103165 */ -#define inner(...) #__VA_ARGS__ ; _Pragma ( " omp error severity (warning) message (\"Test\") at(compilation)" ) -#define outer(...) inner(__VA_ARGS__) +#define inner(...) #__VA_ARGS__ ; _Pragma ( " omp error severity (warning) message (\"Test\") at(compilation)" ) /* { dg-line inner_location } */ +#define outer(...) inner(__VA_ARGS__) /* { dg-line outer_location } */ void f (void) { - const char *str = outer(inner(1,2)); /* { dg-warning "'pragma omp error' encountered: Test" } */ + const char *str = outer(inner(1,2)); /* { dg-line str_location } */ + /* { dg-warning "35:'pragma omp error' encountered: Test" "" { target *-*-* } inner_location } + { dg-note "20:in expansion of macro 'inner'" "" { target *-*-* } outer_location } + { dg-note "21:in expansion of macro 'outer'" "" { target *-*-* } str_location } */ } #if 0 diff --git a/gcc/testsuite/c-c++-common/pr97498.c b/gcc/testsuite/c-c++-common/pr97498.c new file mode 100644 index 0000000..f5fa420 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr97498.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-Wunused-function" } */ +#pragma GCC diagnostic ignored "-Wunused-function" +static void f() {} _Pragma("GCC diagnostic error \"-Wunused-function\"") /* { dg-bogus "-Wunused-function" } */ diff --git a/gcc/testsuite/gcc.dg/lto/pr105459_0.c b/gcc/testsuite/gcc.dg/lto/pr105459_0.c new file mode 100644 index 0000000..c799e6e --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr105459_0.c @@ -0,0 +1,35 @@ +/* { dg-lto-do link } */ +/* { dg-lto-options { { -flto -O1 } } } */ + +double m; +int n; + +__attribute__ ((optimize ("-funsafe-math-optimizations"))) +void +bar (int x) +{ + n = x; + m = n; +} + +__attribute__ ((flatten)) +void +foo (int x) +{ + bar (x); +} + +void +quux (void) +{ + ++n; +} + +int +main (void) +{ + foo (0); + quux (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pragma-message.c b/gcc/testsuite/gcc.dg/pragma-message.c index 2f44b61..1b7cf09 100644 --- a/gcc/testsuite/gcc.dg/pragma-message.c +++ b/gcc/testsuite/gcc.dg/pragma-message.c @@ -42,9 +42,11 @@ #pragma message ("Okay " THREE) /* { dg-message "Okay 3" } */ /* Create a TODO() that prints a message on compilation. */ -#define DO_PRAGMA(x) _Pragma (#x) -#define TODO(x) DO_PRAGMA(message ("TODO - " #x)) -TODO(Okay 4) /* { dg-message "TODO - Okay 4" } */ +#define DO_PRAGMA(x) _Pragma (#x) /* { dg-line pragma_loc1 } */ +#define TODO(x) DO_PRAGMA(message ("TODO - " #x)) /* { dg-line pragma_loc2 } */ +TODO(Okay 4) /* { dg-message "in expansion of macro 'TODO'" } */ +/* { dg-message "TODO - Okay 4" "test4.1" { target *-*-* } pragma_loc1 } */ +/* { dg-message "in expansion of macro 'DO_PRAGMA'" "test4.2" { target *-*-* } pragma_loc2 } */ #if 0 #pragma message ("Not printed") diff --git a/gcc/testsuite/gcc.dg/vect/pr106250.c b/gcc/testsuite/gcc.dg/vect/pr106250.c new file mode 100644 index 0000000..7f25f55 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr106250.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +int +foo (unsigned long int x, int y, int z) +{ + int ret = 0; + + while (y < 1) + { + x *= 2; + ret = x == z; + z = y; + ++y; + } + + return ret; +} diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-stv-2.c b/gcc/testsuite/gcc.target/i386/sse4_1-stv-2.c new file mode 100644 index 0000000..e637927 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-stv-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -msse4.1 -mstv -mno-stackrealign" } */ + +__int128 a[16]; +__int128 b[16]; +__int128 c[16]; + +void foo() +{ + for (unsigned int i=0; i<16; i++) + a[i] = b[i] & c[i]; +} + +/* { dg-final { scan-assembler "pand" } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-stv-3.c b/gcc/testsuite/gcc.target/i386/sse4_1-stv-3.c new file mode 100644 index 0000000..bdc0bac --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-stv-3.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -msse4.1 -mstv -mno-stackrealign" } */ + +__int128 a[16]; +__int128 b[16]; +__int128 c[16]; + +void foo() +{ + for (unsigned int i=0; i<16; i++) + a[i] = b[i] | c[i]; +} + +/* { dg-final { scan-assembler "por" } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-stv-4.c b/gcc/testsuite/gcc.target/i386/sse4_1-stv-4.c new file mode 100644 index 0000000..a9ef619 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-stv-4.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -msse4.1 -mstv -mno-stackrealign" } */ + +__int128 a[16]; +__int128 b[16]; +__int128 c[16]; + +void foo() +{ + for (unsigned int i=0; i<16; i++) + a[i] = b[i] ^ c[i]; +} + +/* { dg-final { scan-assembler "pxor" } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-stv-5.c b/gcc/testsuite/gcc.target/i386/sse4_1-stv-5.c new file mode 100644 index 0000000..7eff3c1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-stv-5.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -msse4.1 -mstv -mno-stackrealign" } */ + +__int128 a[16]; +__int128 b[16]; +__int128 c[16]; + +void foo() +{ + for (unsigned int i=0; i<16; i++) + a[i] = b[i] & ~c[i]; +} + +/* { dg-final { scan-assembler "pandn" } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-stv-6.c b/gcc/testsuite/gcc.target/i386/sse4_1-stv-6.c new file mode 100644 index 0000000..407bc55 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-stv-6.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -msse4.1 -mstv -mno-stackrealign" } */ + +__int128 a[16]; +__int128 b[16]; + +int foo() +{ + for (unsigned int i=0; i<16; i++) + if (a[i] == b[i]) + return i; + return -1; +} + +/* { dg-final { scan-assembler "ptest" } } */ diff --git a/gcc/tree-cfgcleanup.cc b/gcc/tree-cfgcleanup.cc index b9ff689..3535a7e 100644 --- a/gcc/tree-cfgcleanup.cc +++ b/gcc/tree-cfgcleanup.cc @@ -1095,7 +1095,11 @@ cleanup_tree_cfg_noloop (unsigned ssa_update_flags) /* After doing the above SSA form should be valid (or an update SSA should be required). */ if (ssa_update_flags) - update_ssa (ssa_update_flags); + { + timevar_pop (TV_TREE_CLEANUP_CFG); + update_ssa (ssa_update_flags); + timevar_push (TV_TREE_CLEANUP_CFG); + } /* Compute dominator info which we need for the iterative process below. */ if (!dom_info_available_p (CDI_DOMINATORS)) diff --git a/gcc/tree-core.h b/gcc/tree-core.h index ab5fa01..ea9f281 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -33,7 +33,7 @@ struct function; struct real_value; struct fixed_value; struct ptr_info_def; -struct range_info_def; +struct irange_storage_slot; struct die_struct; @@ -1194,9 +1194,6 @@ struct GTY(()) tree_base { TRANSACTION_EXPR_OUTER in TRANSACTION_EXPR - SSA_NAME_ANTI_RANGE_P in - SSA_NAME - MUST_TAIL_CALL in CALL_EXPR @@ -1594,8 +1591,12 @@ struct GTY(()) tree_ssa_name { union ssa_name_info_type { /* Pointer attributes used for alias analysis. */ struct GTY ((tag ("0"))) ptr_info_def *ptr_info; - /* Value range attributes used for zero/sign extension elimination. */ - struct GTY ((tag ("1"))) range_info_def *range_info; + /* This holds any range info supported by ranger (except ptr_info + above) and is managed by vrange_storage. */ + void * GTY ((skip)) range_info; + /* GTY tag when the range in the range_info slot above satisfies + irange::supports_type_p. */ + struct GTY ((tag ("1"))) irange_storage_slot *irange_info; } GTY ((desc ("%1.typed.type ?" \ "!POINTER_TYPE_P (TREE_TYPE ((tree)&%1)) : 2"))) info; diff --git a/gcc/tree-into-ssa.cc b/gcc/tree-into-ssa.cc index 9f45e62..d13fb72 100644 --- a/gcc/tree-into-ssa.cc +++ b/gcc/tree-into-ssa.cc @@ -240,7 +240,8 @@ enum rewrite_mode { /* Incrementally update the SSA web by replacing existing SSA names with new ones. See update_ssa for details. */ - REWRITE_UPDATE + REWRITE_UPDATE, + REWRITE_UPDATE_REGION }; /* The set of symbols we ought to re-write into SSA form in update_ssa. */ @@ -2155,11 +2156,14 @@ rewrite_update_phi_arguments (basic_block bb) class rewrite_update_dom_walker : public dom_walker { public: - rewrite_update_dom_walker (cdi_direction direction) - : dom_walker (direction, ALL_BLOCKS, (int *)(uintptr_t)-1) {} + rewrite_update_dom_walker (cdi_direction direction, int in_region_flag = -1) + : dom_walker (direction, ALL_BLOCKS, (int *)(uintptr_t)-1), + m_in_region_flag (in_region_flag) {} edge before_dom_children (basic_block) final override; void after_dom_children (basic_block) final override; + + int m_in_region_flag; }; /* Initialization of block data structures for the incremental SSA @@ -2179,6 +2183,10 @@ rewrite_update_dom_walker::before_dom_children (basic_block bb) /* Mark the unwind point for this block. */ block_defs_stack.safe_push (NULL_TREE); + if (m_in_region_flag != -1 + && !(bb->flags & m_in_region_flag)) + return STOP; + if (!bitmap_bit_p (blocks_to_update, bb->index)) return NULL; @@ -2270,8 +2278,8 @@ rewrite_update_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED) WHAT indicates what actions will be taken by the renamer (see enum rewrite_mode). - BLOCKS are the set of interesting blocks for the dominator walker - to process. If this set is NULL, then all the nodes dominated + REGION is a SEME region of interesting blocks for the dominator walker + to process. If this set is invalid, then all the nodes dominated by ENTRY are walked. Otherwise, blocks dominated by ENTRY that are not present in BLOCKS are ignored. */ @@ -2283,9 +2291,71 @@ rewrite_blocks (basic_block entry, enum rewrite_mode what) /* Recursively walk the dominator tree rewriting each statement in each basic block. */ if (what == REWRITE_ALL) - rewrite_dom_walker (CDI_DOMINATORS).walk (entry); + rewrite_dom_walker (CDI_DOMINATORS).walk (entry); else if (what == REWRITE_UPDATE) - rewrite_update_dom_walker (CDI_DOMINATORS).walk (entry); + rewrite_update_dom_walker (CDI_DOMINATORS).walk (entry); + else if (what == REWRITE_UPDATE_REGION) + { + /* First mark all blocks in the SEME region dominated by + entry and exited by blocks not backwards reachable from + blocks_to_update. Optimize for dense blocks_to_update + so instead of seeding the worklist with a copy of + blocks_to_update treat those blocks explicit. */ + auto_bb_flag in_region (cfun); + auto_vec<basic_block, 64> extra_rgn; + bitmap_iterator bi; + unsigned int idx; + EXECUTE_IF_SET_IN_BITMAP (blocks_to_update, 0, idx, bi) + { + basic_block bb = BASIC_BLOCK_FOR_FN (cfun, idx); + bb->flags |= in_region; + } + auto_bitmap worklist; + EXECUTE_IF_SET_IN_BITMAP (blocks_to_update, 0, idx, bi) + { + basic_block bb = BASIC_BLOCK_FOR_FN (cfun, idx); + if (bb != entry) + { + edge_iterator ei; + edge e; + FOR_EACH_EDGE (e, ei, bb->preds) + { + if ((e->src->flags & in_region) + || dominated_by_p (CDI_DOMINATORS, e->src, bb)) + continue; + bitmap_set_bit (worklist, e->src->index); + } + } + } + while (!bitmap_empty_p (worklist)) + { + int idx = bitmap_first_set_bit (worklist); + bitmap_clear_bit (worklist, idx); + basic_block bb = BASIC_BLOCK_FOR_FN (cfun, idx); + bb->flags |= in_region; + extra_rgn.safe_push (bb); + if (bb != entry) + { + edge_iterator ei; + edge e; + FOR_EACH_EDGE (e, ei, bb->preds) + { + if ((e->src->flags & in_region) + || dominated_by_p (CDI_DOMINATORS, e->src, bb)) + continue; + bitmap_set_bit (worklist, e->src->index); + } + } + } + rewrite_update_dom_walker (CDI_DOMINATORS, in_region).walk (entry); + EXECUTE_IF_SET_IN_BITMAP (blocks_to_update, 0, idx, bi) + { + basic_block bb = BASIC_BLOCK_FOR_FN (cfun, idx); + bb->flags &= ~in_region; + } + for (auto bb : extra_rgn) + bb->flags &= ~in_region; + } else gcc_unreachable (); @@ -2879,7 +2949,7 @@ dump_update_ssa (FILE *file) if (!need_ssa_update_p (cfun)) return; - if (new_ssa_names && bitmap_first_set_bit (new_ssa_names) >= 0) + if (new_ssa_names && !bitmap_empty_p (new_ssa_names)) { sbitmap_iterator sbi; @@ -3381,15 +3451,17 @@ update_ssa (unsigned update_flags) phis_to_rewrite.create (last_basic_block_for_fn (cfun) + 1); blocks_to_update = BITMAP_ALLOC (NULL); - /* Ensure that the dominance information is up-to-date. */ - calculate_dominance_info (CDI_DOMINATORS); - insert_phi_p = (update_flags != TODO_update_ssa_no_phi); + /* Ensure that the dominance information is up-to-date and when we + are going to compute dominance frontiers fast queries are possible. */ + if (insert_phi_p || dom_info_state (CDI_DOMINATORS) == DOM_NONE) + calculate_dominance_info (CDI_DOMINATORS); + /* If there are names defined in the replacement table, prepare definition and use sites for all the names in NEW_SSA_NAMES and OLD_SSA_NAMES. */ - if (bitmap_first_set_bit (new_ssa_names) >= 0) + if (!bitmap_empty_p (new_ssa_names)) { statistics_counter_event (cfun, "Incremental SSA update", 1); @@ -3398,7 +3470,7 @@ update_ssa (unsigned update_flags) /* If all the names in NEW_SSA_NAMES had been marked for removal, and there are no symbols to rename, then there's nothing else to do. */ - if (bitmap_first_set_bit (new_ssa_names) < 0 + if (bitmap_empty_p (new_ssa_names) && !cfun->gimple_df->ssa_renaming_needed) goto done; } @@ -3503,8 +3575,11 @@ update_ssa (unsigned update_flags) FOR_EACH_VEC_ELT (symbols_to_rename, i, sym) get_var_info (sym)->info.current_def = NULL_TREE; - /* Now start the renaming process at START_BB. */ - rewrite_blocks (start_bb, REWRITE_UPDATE); + /* Now start the renaming process at START_BB. When not inserting PHIs + and thus we are avoiding work on all blocks, try to confine the + rewriting domwalk to the affected region, otherwise it's not worth it. */ + rewrite_blocks (start_bb, + insert_phi_p ? REWRITE_UPDATE : REWRITE_UPDATE_REGION); /* Debugging dumps. */ if (dump_file) diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc index 2bc2c3d..43acc75 100644 --- a/gcc/tree-ssa-dom.cc +++ b/gcc/tree-ssa-dom.cc @@ -1255,7 +1255,7 @@ dom_opt_dom_walker::set_global_ranges_from_unreachable_edges (basic_block bb) && !r.varying_p () && !r.undefined_p ()) { - update_global_range (r, name); + set_range_info (name, r); maybe_set_nonzero_bits (pred_e, name); } } diff --git a/gcc/tree-ssanames.cc b/gcc/tree-ssanames.cc index bc22ece..9389454 100644 --- a/gcc/tree-ssanames.cc +++ b/gcc/tree-ssanames.cc @@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "tree-scalar-evolution.h" #include "value-query.h" +#include "value-range-storage.h" /* Rewriting a function into SSA form can create a huge number of SSA_NAMEs, many of which may be thrown away shortly after their creation if jumps @@ -71,6 +72,74 @@ unsigned int ssa_name_nodes_created; #define FREE_SSANAMES(fun) (fun)->gimple_df->free_ssanames #define FREE_SSANAMES_QUEUE(fun) (fun)->gimple_df->free_ssanames_queue +static ggc_vrange_allocator ggc_allocator; +static vrange_storage vstore (&ggc_allocator); + +/* Return TRUE if NAME has global range info. */ + +inline bool +range_info_p (const_tree name) +{ + return SSA_NAME_RANGE_INFO (name); +} + +/* Return TRUE if R fits in the global range of NAME. */ + +inline bool +range_info_fits_p (tree name, const vrange &r) +{ + gcc_checking_assert (range_info_p (name)); + void *mem = SSA_NAME_RANGE_INFO (name); + return vrange_storage::fits_p (mem, r); +} + +/* Allocate a new global range for NAME and set it to R. Return the + allocation slot. */ + +inline void * +range_info_alloc (tree name, const vrange &r) +{ + void *mem = vstore.alloc_slot (r); + SSA_NAME_RANGE_INFO (name) = mem; + return mem; +} + +/* Free storage allocated for the global range for NAME. */ + +inline void +range_info_free (tree name) +{ + void *mem = SSA_NAME_RANGE_INFO (name); + vstore.free (mem); +} + +/* Return the global range for NAME in R. */ + +inline void +range_info_get_range (tree name, vrange &r) +{ + vstore.get_vrange (SSA_NAME_RANGE_INFO (name), r, TREE_TYPE (name)); +} + +/* Set the global range for NAME from R. Return TRUE if successfull, + or FALSE if we can't set a range of NAME's type. */ + +inline bool +range_info_set_range (tree name, const vrange &r) +{ + if (!range_info_p (name) || !range_info_fits_p (name, r)) + { + if (range_info_p (name)) + range_info_free (name); + + return range_info_alloc (name, r); + } + else + { + vstore.set_vrange (SSA_NAME_RANGE_INFO (name), r); + return true; + } +} /* Initialize management of SSA_NAMEs to default SIZE. If SIZE is zero use default. */ @@ -343,94 +412,38 @@ make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, return t; } -/* Helper function for set_range_info. - - Store range information RANGE_TYPE, MIN, and MAX to tree ssa_name - NAME. */ - -void -set_range_info_raw (tree name, enum value_range_kind range_type, - const wide_int_ref &min, const wide_int_ref &max) -{ - gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); - gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE); - range_info_def *ri = SSA_NAME_RANGE_INFO (name); - unsigned int precision = TYPE_PRECISION (TREE_TYPE (name)); - - /* Allocate if not available. */ - if (ri == NULL) - { - size_t size = (sizeof (range_info_def) - + trailing_wide_ints <3>::extra_size (precision)); - ri = static_cast<range_info_def *> (ggc_internal_alloc (size)); - ri->ints.set_precision (precision); - SSA_NAME_RANGE_INFO (name) = ri; - ri->set_nonzero_bits (wi::shwi (-1, precision)); - } - - /* Record the range type. */ - if (SSA_NAME_RANGE_TYPE (name) != range_type) - SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE); +/* Update the range information for NAME, intersecting into an existing + range if applicable. Return TRUE if the range was updated. */ - /* Set the values. */ - ri->set_min (min); - ri->set_max (max); - - /* If it is a range, try to improve nonzero_bits from the min/max. */ - if (range_type == VR_RANGE) - { - wide_int xorv = ri->get_min () ^ ri->get_max (); - if (xorv != 0) - xorv = wi::mask (precision - wi::clz (xorv), false, precision); - ri->set_nonzero_bits (ri->get_nonzero_bits () & (ri->get_min () | xorv)); - } -} - -/* Store range information RANGE_TYPE, MIN, and MAX to tree ssa_name - NAME while making sure we don't store useless range info. */ - -static void -set_range_info (tree name, enum value_range_kind range_type, - const wide_int_ref &min, const wide_int_ref &max) +bool +set_range_info (tree name, const vrange &r) { - gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); + if (r.undefined_p () || r.varying_p ()) + return false; tree type = TREE_TYPE (name); - if (range_type == VR_VARYING) + if (POINTER_TYPE_P (type)) { - /* SSA_NAME_RANGE_TYPE can only hold a VR_RANGE or - VR_ANTI_RANGE. Denormalize VR_VARYING to VR_RANGE. */ - range_type = VR_RANGE; - gcc_checking_assert (min == wi::min_value (type)); - gcc_checking_assert (max == wi::max_value (type)); - } - - /* A range of the entire domain is really no range at all. */ - if (min == wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type)) - && max == wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type))) - { - range_info_def *ri = SSA_NAME_RANGE_INFO (name); - if (ri == NULL) - return; - if (ri->get_nonzero_bits () == -1) + if (r.nonzero_p ()) { - ggc_free (ri); - SSA_NAME_RANGE_INFO (name) = NULL; - return; + set_ptr_nonnull (name); + return true; } + return false; } - set_range_info_raw (name, range_type, min, max); -} - -/* Store range information for NAME from a value_range. */ + /* If a global range already exists, incorporate it. */ + if (range_info_p (name)) + { + Value_Range tmp (type); + range_info_get_range (name, tmp); + tmp.intersect (r); + if (tmp.undefined_p ()) + return false; -void -set_range_info (tree name, const value_range &vr) -{ - wide_int min = wi::to_wide (vr.min ()); - wide_int max = wi::to_wide (vr.max ()); - set_range_info (name, vr.kind (), min, max); + return range_info_set_range (name, tmp); + } + return range_info_set_range (name, r); } /* Set nonnull attribute to pointer NAME. */ @@ -443,22 +456,16 @@ set_ptr_nonnull (tree name) pi->pt.null = 0; } -/* Change non-zero bits bitmask of NAME. */ +/* Update the non-zero bits bitmask of NAME. */ void set_nonzero_bits (tree name, const wide_int_ref &mask) { gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); - if (SSA_NAME_RANGE_INFO (name) == NULL) - { - if (mask == -1) - return; - set_range_info_raw (name, VR_RANGE, - wi::to_wide (TYPE_MIN_VALUE (TREE_TYPE (name))), - wi::to_wide (TYPE_MAX_VALUE (TREE_TYPE (name)))); - } - range_info_def *ri = SSA_NAME_RANGE_INFO (name); - ri->set_nonzero_bits (mask); + + int_range<2> r (TREE_TYPE (name)); + r.set_nonzero_bits (mask); + set_range_info (name, r); } /* Return a widest_int with potentially non-zero bits in SSA_NAME @@ -482,10 +489,15 @@ get_nonzero_bits (const_tree name) return wi::shwi (-1, precision); } - range_info_def *ri = SSA_NAME_RANGE_INFO (name); - if (!ri) + if (!range_info_p (name)) return wi::shwi (-1, precision); + /* Optimization to get at the nonzero bits because we know the + storage type. This saves us measurable time compared to going + through vrange_storage. */ + gcc_checking_assert (irange::supports_p (TREE_TYPE (name))); + irange_storage_slot *ri + = static_cast <irange_storage_slot *> (SSA_NAME_RANGE_INFO (name)); return ri->get_nonzero_bits (); } @@ -727,38 +739,18 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info) SSA_NAME_PTR_INFO (name) = new_ptr_info; } -/* Creates a duplicate of the range_info_def at RANGE_INFO of type - RANGE_TYPE for use by the SSA name NAME. */ -static void -duplicate_ssa_name_range_info (tree name, enum value_range_kind range_type, - struct range_info_def *range_info) -{ - struct range_info_def *new_range_info; - - gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); - gcc_assert (!SSA_NAME_RANGE_INFO (name)); - - if (!range_info) - return; - - unsigned int precision = TYPE_PRECISION (TREE_TYPE (name)); - size_t size = (sizeof (range_info_def) - + trailing_wide_ints <3>::extra_size (precision)); - new_range_info = static_cast<range_info_def *> (ggc_internal_alloc (size)); - memcpy (new_range_info, range_info, size); - - gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE); - SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE); - SSA_NAME_RANGE_INFO (name) = new_range_info; -} - void duplicate_ssa_name_range_info (tree name, tree src) { gcc_checking_assert (!POINTER_TYPE_P (TREE_TYPE (src))); - duplicate_ssa_name_range_info (name, - SSA_NAME_RANGE_TYPE (src), - SSA_NAME_RANGE_INFO (src)); + gcc_checking_assert (!range_info_p (name)); + + if (range_info_p (src)) + { + Value_Range src_range (TREE_TYPE (src)); + range_info_get_range (src, src_range); + range_info_set_range (name, src_range); + } } @@ -776,14 +768,8 @@ duplicate_ssa_name_fn (struct function *fn, tree name, gimple *stmt) if (old_ptr_info) duplicate_ssa_name_ptr_info (new_name, old_ptr_info); } - else - { - struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name); - - if (old_range_info) - duplicate_ssa_name_range_info (new_name, SSA_NAME_RANGE_TYPE (name), - old_range_info); - } + else if (range_info_p (name)) + duplicate_ssa_name_range_info (new_name, name); return new_name; } diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h index 8c419b1..ce10af9 100644 --- a/gcc/tree-ssanames.h +++ b/gcc/tree-ssanames.h @@ -45,16 +45,6 @@ struct GTY(()) ptr_info_def unsigned int misalign; }; -/* Value range information for SSA_NAMEs representing non-pointer variables. */ - -struct GTY ((variable_size)) range_info_def { - /* Minimum, maximum and nonzero bits. */ - TRAILING_WIDE_INT_ACCESSOR (min, ints, 0) - TRAILING_WIDE_INT_ACCESSOR (max, ints, 1) - TRAILING_WIDE_INT_ACCESSOR (nonzero_bits, ints, 2) - trailing_wide_ints <3> ints; -}; - #define SSANAMES(fun) (fun)->gimple_df->ssa_names #define DEFAULT_DEFS(fun) (fun)->gimple_df->default_defs @@ -67,7 +57,7 @@ struct GTY ((variable_size)) range_info_def { if (VAR) /* Sets the value range to SSA. */ -extern void set_range_info (tree, const value_range &); +extern bool set_range_info (tree, const vrange &); extern void set_nonzero_bits (tree, const wide_int_ref &); extern wide_int get_nonzero_bits (const_tree); extern bool ssa_name_has_boolean_range (tree); diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc index d20a10a..609cacc 100644 --- a/gcc/tree-vect-data-refs.cc +++ b/gcc/tree-vect-data-refs.cc @@ -5777,8 +5777,15 @@ vect_setup_realignment (vec_info *vinfo, stmt_vec_info stmt_info, if (at_loop) *at_loop = loop_for_initial_load; + tree vuse = NULL_TREE; if (loop_for_initial_load) - pe = loop_preheader_edge (loop_for_initial_load); + { + pe = loop_preheader_edge (loop_for_initial_load); + if (gphi *vphi = get_virtual_phi (loop_for_initial_load->header)) + vuse = PHI_ARG_DEF_FROM_EDGE (vphi, pe); + } + if (!vuse) + vuse = gimple_vuse (gsi_stmt (*gsi)); /* 3. For the case of the optimized realignment, create the first vector load at the loop preheader. */ @@ -5813,6 +5820,7 @@ vect_setup_realignment (vec_info *vinfo, stmt_vec_info stmt_info, new_stmt = gimple_build_assign (vec_dest, data_ref); new_temp = make_ssa_name (vec_dest, new_stmt); gimple_assign_set_lhs (new_stmt, new_temp); + gimple_set_vuse (new_stmt, vuse); if (pe) { new_bb = gsi_insert_on_edge_immediate (pe, new_stmt); diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 3a70c15..2257b29 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -7369,7 +7369,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo, dot-products. */ machine_mode vec_mode = TYPE_MODE (vectype_in); if (!lane_reduc_code_p - && !directly_supported_p (op.code, vectype_in)) + && !directly_supported_p (op.code, vectype_in, optab_vector)) { if (dump_enabled_p ()) dump_printf (MSG_NOTE, "op not supported by target.\n"); diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc index ed881be..c3030a1 100644 --- a/gcc/tree-vrp.cc +++ b/gcc/tree-vrp.cc @@ -3739,16 +3739,18 @@ vrp_asserts::remove_range_assertions () && all_imm_uses_in_stmt_or_feed_cond (var, stmt, single_pred (bb))) { - /* We could use duplicate_ssa_name_range_info here - instead of peeking inside SSA_NAME_RANGE_INFO, - but the aforementioned asserts that the - destination has no global range. This is - slated for removal anyhow. */ - value_range r (TREE_TYPE (lhs), - SSA_NAME_RANGE_INFO (lhs)->get_min (), - SSA_NAME_RANGE_INFO (lhs)->get_max (), - SSA_NAME_RANGE_TYPE (lhs)); - set_range_info (var, r); + if (SSA_NAME_RANGE_INFO (var)) + { + /* ?? This is a minor wart exposing the + internals of SSA_NAME_RANGE_INFO in order + to maintain existing behavior. This is + because duplicate_ssa_name_range_info below + needs a NULL destination range. This is + all slated for removal... */ + ggc_free (SSA_NAME_RANGE_INFO (var)); + SSA_NAME_RANGE_INFO (var) = NULL; + } + duplicate_ssa_name_range_info (var, lhs); maybe_set_nonzero_bits (single_pred_edge (bb), var); } } @@ -2030,14 +2030,6 @@ class auto_suppress_location_wrappers #define SSA_NAME_PTR_INFO(N) \ SSA_NAME_CHECK (N)->ssa_name.info.ptr_info -/* True if SSA_NAME_RANGE_INFO describes an anti-range. */ -#define SSA_NAME_ANTI_RANGE_P(N) \ - SSA_NAME_CHECK (N)->base.static_flag - -/* The type of range described by SSA_NAME_RANGE_INFO. */ -#define SSA_NAME_RANGE_TYPE(N) \ - (SSA_NAME_ANTI_RANGE_P (N) ? VR_ANTI_RANGE : VR_RANGE) - /* Value range info attributes for SSA_NAMEs of non pointer-type variables. */ #define SSA_NAME_RANGE_INFO(N) \ SSA_NAME_CHECK (N)->ssa_name.info.range_info diff --git a/gcc/value-query.cc b/gcc/value-query.cc index 1d7541c..51911bd 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "value-query.h" #include "alloc-pool.h" #include "gimple-range.h" +#include "value-range-storage.h" // value_query default methods. @@ -271,13 +272,13 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt) // Return the range for NAME from SSA_NAME_RANGE_INFO. static inline void -get_ssa_name_range_info (irange &r, const_tree name) +get_ssa_name_range_info (vrange &r, const_tree name) { tree type = TREE_TYPE (name); gcc_checking_assert (!POINTER_TYPE_P (type)); gcc_checking_assert (TREE_CODE (name) == SSA_NAME); - range_info_def *ri = SSA_NAME_RANGE_INFO (name); + void *ri = SSA_NAME_RANGE_INFO (name); // Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs // with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision. @@ -285,9 +286,10 @@ get_ssa_name_range_info (irange &r, const_tree name) > 2 * HOST_BITS_PER_WIDE_INT)) r.set_varying (type); else - r.set (wide_int_to_tree (type, ri->get_min ()), - wide_int_to_tree (type, ri->get_max ()), - SSA_NAME_RANGE_TYPE (name)); + { + vrange_storage vstore (NULL); + vstore.get_vrange (ri, r, TREE_TYPE (name)); + } } // Return nonnull attribute of pointer NAME from SSA_NAME_PTR_INFO. @@ -311,43 +313,6 @@ get_ssa_name_ptr_info_nonnull (const_tree name) } // Update the global range for NAME into the SSA_RANGE_NAME_INFO and -// SSA_NAME_PTR_INFO fields. Return TRUE if the range for NAME was -// updated. - -bool -update_global_range (vrange &r, tree name) -{ - tree type = TREE_TYPE (name); - - if (r.undefined_p () || r.varying_p ()) - return false; - - if (INTEGRAL_TYPE_P (type)) - { - // If a global range already exists, incorporate it. - if (SSA_NAME_RANGE_INFO (name)) - { - value_range glob; - get_ssa_name_range_info (glob, name); - r.intersect (glob); - } - if (r.undefined_p ()) - return false; - - set_range_info (name, as_a <irange> (r)); - return true; - } - else if (POINTER_TYPE_P (type)) - { - if (r.nonzero_p ()) - { - set_ptr_nonnull (name); - return true; - } - } - return false; -} - // Return the legacy global range for NAME if it has one, otherwise // return VARYING. @@ -372,7 +337,7 @@ get_range_global (vrange &r, tree name) r.set_nonzero (type); else if (INTEGRAL_TYPE_P (type)) { - get_ssa_name_range_info (as_a <irange> (r), name); + get_ssa_name_range_info (r, name); if (r.undefined_p ()) r.set_varying (type); } @@ -387,8 +352,7 @@ get_range_global (vrange &r, tree name) } else if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name)) { - gcc_checking_assert (irange::supports_p (TREE_TYPE (name))); - get_ssa_name_range_info (as_a <irange> (r), name); + get_ssa_name_range_info (r, name); if (r.undefined_p ()) r.set_varying (type); } diff --git a/gcc/value-query.h b/gcc/value-query.h index 280e47e..fc638eb 100644 --- a/gcc/value-query.h +++ b/gcc/value-query.h @@ -144,6 +144,5 @@ get_range_query (const struct function *fun) } extern void gimple_range_global (vrange &v, tree name); -extern bool update_global_range (vrange &v, tree name); #endif // GCC_QUERY_H diff --git a/gcc/value-range-storage.cc b/gcc/value-range-storage.cc index ac62bfa..8b5ab54 100644 --- a/gcc/value-range-storage.cc +++ b/gcc/value-range-storage.cc @@ -30,7 +30,8 @@ along with GCC; see the file COPYING3. If not see #include "gimple-range.h" #include "value-range-storage.h" -// Return a newly allocated slot holding R. +// Return a newly allocated slot holding R, or NULL if storing a range +// of R's type is not supported. void * vrange_storage::alloc_slot (const vrange &r) @@ -40,7 +41,6 @@ vrange_storage::alloc_slot (const vrange &r) if (is_a <irange> (r)) return irange_storage_slot::alloc_slot (*m_alloc, as_a <irange> (r)); - gcc_unreachable (); return NULL; } |