From fb768529d28e74ceca93efdd2e0a6ada3bb141fe Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 8 Jan 2020 14:30:44 +0000 Subject: re PR tree-optimization/93199 (Compile time hog in sink_clobbers) 2020-01-08 Richard Biener PR middle-end/93199 * tree-eh.c (sink_clobbers): Update virtual operands for the first and last stmt only. Add a dry-run capability. (pass_lower_eh_dispatch::execute): Perform clobber sinking after CFG manipulations and in RPO order to catch all secondary opportunities reliably. From-SVN: r280006 --- gcc/tree-eh.c | 85 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 28 deletions(-) (limited to 'gcc/tree-eh.c') diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 21ae24f..f25d2de8 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -3550,10 +3550,11 @@ optimize_clobbers (basic_block bb) } /* Try to sink var = {v} {CLOBBER} stmts followed just by - internal throw to successor BB. */ + internal throw to successor BB. If FOUND_OPPORTUNITY is not NULL + then do not perform the optimization but set *FOUND_OPPORTUNITY to true. */ static int -sink_clobbers (basic_block bb) +sink_clobbers (basic_block bb, bool *found_opportunity = NULL) { edge e; edge_iterator ei; @@ -3591,13 +3592,19 @@ sink_clobbers (basic_block bb) if (!any_clobbers) return 0; + /* If this was a dry run, tell it we found clobbers to sink. */ + if (found_opportunity) + { + *found_opportunity = true; + return 0; + } + edge succe = single_succ_edge (bb); succbb = succe->dest; /* See if there is a virtual PHI node to take an updated virtual operand from. */ gphi *vphi = NULL; - tree vuse = NULL_TREE; for (gphi_iterator gpi = gsi_start_phis (succbb); !gsi_end_p (gpi); gsi_next (&gpi)) { @@ -3605,11 +3612,12 @@ sink_clobbers (basic_block bb) if (virtual_operand_p (res)) { vphi = gpi.phi (); - vuse = res; break; } } + gimple *first_sunk = NULL; + gimple *last_sunk = NULL; dgsi = gsi_after_labels (succbb); gsi = gsi_last_bb (bb); for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi)) @@ -3641,36 +3649,37 @@ sink_clobbers (basic_block bb) forwarder edge we can keep virtual operands in place. */ gsi_remove (&gsi, false); gsi_insert_before (&dgsi, stmt, GSI_NEW_STMT); - - /* But adjust virtual operands if we sunk across a PHI node. */ - if (vuse) + if (!first_sunk) + first_sunk = stmt; + last_sunk = stmt; + } + if (first_sunk) + { + /* Adjust virtual operands if we sunk across a virtual PHI. */ + if (vphi) { - gimple *use_stmt; imm_use_iterator iter; use_operand_p use_p; - FOR_EACH_IMM_USE_STMT (use_stmt, iter, vuse) + gimple *use_stmt; + tree phi_def = gimple_phi_result (vphi); + FOR_EACH_IMM_USE_STMT (use_stmt, iter, phi_def) FOR_EACH_IMM_USE_ON_STMT (use_p, iter) - SET_USE (use_p, gimple_vdef (stmt)); - if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vuse)) + SET_USE (use_p, gimple_vdef (first_sunk)); + if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (phi_def)) { - SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_vdef (stmt)) = 1; - SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vuse) = 0; + SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_vdef (first_sunk)) = 1; + SSA_NAME_OCCURS_IN_ABNORMAL_PHI (phi_def) = 0; } - /* Adjust the incoming virtual operand. */ - SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (vphi, succe), gimple_vuse (stmt)); - SET_USE (gimple_vuse_op (stmt), vuse); + SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (vphi, succe), + gimple_vuse (last_sunk)); + SET_USE (gimple_vuse_op (last_sunk), phi_def); } /* If there isn't a single predecessor but no virtual PHI node arrange for virtual operands to be renamed. */ - else if (gimple_vuse_op (stmt) != NULL_USE_OPERAND_P - && !single_pred_p (succbb)) + else if (!single_pred_p (succbb) + && TREE_CODE (gimple_vuse (last_sunk)) == SSA_NAME) { - /* In this case there will be no use of the VDEF of this stmt. - ??? Unless this is a secondary opportunity and we have not - removed unreachable blocks yet, so we cannot assert this. - Which also means we will end up renaming too many times. */ - SET_USE (gimple_vuse_op (stmt), gimple_vop (cfun)); - mark_virtual_operands_for_renaming (cfun); + mark_virtual_operand_for_renaming (gimple_vuse (last_sunk)); todo |= TODO_update_ssa_only_virtuals; } } @@ -3863,6 +3872,7 @@ pass_lower_eh_dispatch::execute (function *fun) basic_block bb; int flags = 0; bool redirected = false; + bool any_resx_to_process = false; assign_filter_values (); @@ -3879,18 +3889,37 @@ pass_lower_eh_dispatch::execute (function *fun) } else if (gimple_code (last) == GIMPLE_RESX) { - if (stmt_can_throw_external (cfun, last)) + if (stmt_can_throw_external (fun, last)) optimize_clobbers (bb); - else - flags |= sink_clobbers (bb); + else if (!any_resx_to_process) + sink_clobbers (bb, &any_resx_to_process); } } - if (redirected) { free_dominance_info (CDI_DOMINATORS); delete_unreachable_blocks (); } + + if (any_resx_to_process) + { + /* Make sure to catch all secondary sinking opportunities by processing + blocks in RPO order and after all CFG modifications from lowering + and unreachable block removal. */ + int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun)); + int rpo_n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false); + for (int i = 0; i < rpo_n; ++i) + { + bb = BASIC_BLOCK_FOR_FN (fun, rpo[i]); + gimple *last = last_stmt (bb); + if (last + && gimple_code (last) == GIMPLE_RESX + && !stmt_can_throw_external (fun, last)) + flags |= sink_clobbers (bb); + } + free (rpo); + } + return flags; } -- cgit v1.1 From 5eaf0c498f718f60591b06fa81fc51ace6a16c01 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 10 Jan 2020 10:49:57 +0000 Subject: re PR tree-optimization/93199 (Compile time hog in sink_clobbers) 2020-01-10 Richard Biener PR middle-end/93199 * tree-eh.c (redirect_eh_edge_1): Avoid some work if possible. (cleanup_all_empty_eh): Walk landing pads in reverse order to avoid quadraticness. From-SVN: r280101 --- gcc/tree-eh.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'gcc/tree-eh.c') diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index f25d2de8..408ff48 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -2310,7 +2310,7 @@ redirect_eh_edge_1 (edge edge_in, basic_block new_bb, bool change_region) old_lp = get_eh_landing_pad_from_number (old_lp_nr); throw_stmt = last_stmt (edge_in->src); - gcc_assert (lookup_stmt_eh_lp (throw_stmt) == old_lp_nr); + gcc_checking_assert (lookup_stmt_eh_lp (throw_stmt) == old_lp_nr); new_label = gimple_block_label (new_bb); @@ -4307,9 +4307,10 @@ cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb, | | EH <..> which CFG verification would choke on. See PR45172 and PR51089. */ - FOR_EACH_EDGE (e, ei, old_bb->preds) - if (find_edge (e->src, new_bb)) - return false; + if (!single_pred_p (new_bb)) + FOR_EACH_EDGE (e, ei, old_bb->preds) + if (find_edge (e->src, new_bb)) + return false; FOR_EACH_EDGE (e, ei, old_bb->preds) redirect_edge_var_map_clear (e); @@ -4698,9 +4699,15 @@ cleanup_all_empty_eh (void) eh_landing_pad lp; int i; - for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i) - if (lp) - changed |= cleanup_empty_eh (lp); + /* Ideally we'd walk the region tree and process LPs inner to outer + to avoid quadraticness in EH redirection. Walking the LP array + in reverse seems to be an approximation of that. */ + for (i = vec_safe_length (cfun->eh->lp_array) - 1; i >= 1; --i) + { + lp = (*cfun->eh->lp_array)[i]; + if (lp) + changed |= cleanup_empty_eh (lp); + } return changed; } -- cgit v1.1 From 734efcdda91645d6425f584b39362cf0c3af2587 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 10 Jan 2020 11:23:53 +0000 Subject: re PR tree-optimization/93199 (Compile time hog in sink_clobbers) 2020-01-10 Richard Biener PR middle-end/93199 * tree-eh.c (sink_clobbers): Move clobbers to out-of-IL sequences to avoid walking them again for secondary opportunities. (pass_lower_eh_dispatch::execute): Instead actually insert them here. From-SVN: r280102 --- gcc/tree-eh.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'gcc/tree-eh.c') diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 408ff48..dc80f57 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -3550,11 +3550,15 @@ optimize_clobbers (basic_block bb) } /* Try to sink var = {v} {CLOBBER} stmts followed just by - internal throw to successor BB. If FOUND_OPPORTUNITY is not NULL - then do not perform the optimization but set *FOUND_OPPORTUNITY to true. */ + internal throw to successor BB. + SUNK, if not NULL, is an array of sequences indexed by basic-block + index to sink to and to pick up sinking opportunities from. + If FOUND_OPPORTUNITY is not NULL then do not perform the optimization + but set *FOUND_OPPORTUNITY to true. */ static int -sink_clobbers (basic_block bb, bool *found_opportunity = NULL) +sink_clobbers (basic_block bb, + gimple_seq *sunk = NULL, bool *found_opportunity = NULL) { edge e; edge_iterator ei; @@ -3589,7 +3593,7 @@ sink_clobbers (basic_block bb, bool *found_opportunity = NULL) return 0; any_clobbers = true; } - if (!any_clobbers) + if (!any_clobbers && (!sunk || gimple_seq_empty_p (sunk[bb->index]))) return 0; /* If this was a dry run, tell it we found clobbers to sink. */ @@ -3618,7 +3622,10 @@ sink_clobbers (basic_block bb, bool *found_opportunity = NULL) gimple *first_sunk = NULL; gimple *last_sunk = NULL; - dgsi = gsi_after_labels (succbb); + if (sunk) + dgsi = gsi_start (sunk[succbb->index]); + else + dgsi = gsi_after_labels (succbb); gsi = gsi_last_bb (bb); for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi)) { @@ -3653,6 +3660,15 @@ sink_clobbers (basic_block bb, bool *found_opportunity = NULL) first_sunk = stmt; last_sunk = stmt; } + if (sunk && !gimple_seq_empty_p (sunk[bb->index])) + { + if (!first_sunk) + first_sunk = gsi_stmt (gsi_last (sunk[bb->index])); + last_sunk = gsi_stmt (gsi_start (sunk[bb->index])); + gsi_insert_seq_before_without_update (&dgsi, + sunk[bb->index], GSI_NEW_STMT); + sunk[bb->index] = NULL; + } if (first_sunk) { /* Adjust virtual operands if we sunk across a virtual PHI. */ @@ -3892,7 +3908,7 @@ pass_lower_eh_dispatch::execute (function *fun) if (stmt_can_throw_external (fun, last)) optimize_clobbers (bb); else if (!any_resx_to_process) - sink_clobbers (bb, &any_resx_to_process); + sink_clobbers (bb, NULL, &any_resx_to_process); } } if (redirected) @@ -3908,6 +3924,7 @@ pass_lower_eh_dispatch::execute (function *fun) and unreachable block removal. */ int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun)); int rpo_n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false); + gimple_seq *sunk = XCNEWVEC (gimple_seq, last_basic_block_for_fn (fun)); for (int i = 0; i < rpo_n; ++i) { bb = BASIC_BLOCK_FOR_FN (fun, rpo[i]); @@ -3915,9 +3932,17 @@ pass_lower_eh_dispatch::execute (function *fun) if (last && gimple_code (last) == GIMPLE_RESX && !stmt_can_throw_external (fun, last)) - flags |= sink_clobbers (bb); + flags |= sink_clobbers (bb, sunk); + /* If there were any clobbers sunk into this BB, insert them now. */ + if (!gimple_seq_empty_p (sunk[bb->index])) + { + gimple_stmt_iterator gsi = gsi_after_labels (bb); + gsi_insert_seq_before (&gsi, sunk[bb->index], GSI_NEW_STMT); + sunk[bb->index] = NULL; + } } free (rpo); + free (sunk); } return flags; -- cgit v1.1 From 37e27de43133b87ceb529d863f0d1f54d87cf2d8 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 15 Jan 2020 13:29:25 +0100 Subject: middle-end/93273 - fix sinking clobbers across backedges The previous work to fix PR93199 didn't take into account backedges when defering insertion. The following simply avoids to defer in that case since we know we'll not take secondary opportunities there. 2020-01-15 Richard Biener PR middle-end/93273 * tree-eh.c (sink_clobbers): If we already visited the destination block do not defer insertion. (pass_lower_eh_dispatch::execute): Maintain BB_VISITED for the purpose of defered insertion. * g++.dg/torture/pr93273.C: New testcase. --- gcc/tree-eh.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gcc/tree-eh.c') diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index dc80f57..454b22c 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -3622,7 +3622,7 @@ sink_clobbers (basic_block bb, gimple *first_sunk = NULL; gimple *last_sunk = NULL; - if (sunk) + if (sunk && !(succbb->flags & BB_VISITED)) dgsi = gsi_start (sunk[succbb->index]); else dgsi = gsi_after_labels (succbb); @@ -3910,6 +3910,7 @@ pass_lower_eh_dispatch::execute (function *fun) else if (!any_resx_to_process) sink_clobbers (bb, NULL, &any_resx_to_process); } + bb->flags &= ~BB_VISITED; } if (redirected) { @@ -3940,6 +3941,7 @@ pass_lower_eh_dispatch::execute (function *fun) gsi_insert_seq_before (&gsi, sunk[bb->index], GSI_NEW_STMT); sunk[bb->index] = NULL; } + bb->flags |= BB_VISITED; } free (rpo); free (sunk); -- cgit v1.1 From 92ce93c743b3c81f6911bc3d06056099369e9191 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 20 Jan 2020 11:10:30 +0100 Subject: Record outer non-cleanup region in TREE EH. PR tree-optimization/93199 * tree-eh.c (struct leh_state): Add new field outer_non_cleanup. (cleanup_is_dead_in): Pass leh_state instead of eh_region. Add a checking that state->outer_non_cleanup points to outer non-clean up region. (lower_try_finally): Record outer_non_cleanup for this_state. (lower_catch): Likewise. (lower_eh_filter): Likewise. (lower_eh_must_not_throw): Likewise. (lower_cleanup): Likewise. --- gcc/tree-eh.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'gcc/tree-eh.c') diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 454b22c..2a409dc 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -356,6 +356,9 @@ struct leh_state split out into a separate structure so that we don't have to copy so much when processing other nodes. */ struct leh_tf_state *tf; + + /* Outer non-clean up region. */ + eh_region outer_non_cleanup; }; struct leh_tf_state @@ -1624,7 +1627,8 @@ decide_copy_try_finally (int ndests, bool may_throw, gimple_seq finally) return f_estimate < 40 || f_estimate * 2 < sw_estimate * 3; } -/* REG is the enclosing region for a possible cleanup region, or the region +/* REG is current region of a LEH state. + is the enclosing region for a possible cleanup region, or the region itself. Returns TRUE if such a region would be unreachable. Cleanup regions within a must-not-throw region aren't actually reachable @@ -1632,10 +1636,18 @@ decide_copy_try_finally (int ndests, bool may_throw, gimple_seq finally) routine will call terminate before unwinding. */ static bool -cleanup_is_dead_in (eh_region reg) +cleanup_is_dead_in (leh_state *state) { - while (reg && reg->type == ERT_CLEANUP) - reg = reg->outer; + if (flag_checking) + { + eh_region reg = state->cur_region; + while (reg && reg->type == ERT_CLEANUP) + reg = reg->outer; + + gcc_assert (reg == state->outer_non_cleanup); + } + + eh_region reg = state->outer_non_cleanup; return (reg && reg->type == ERT_MUST_NOT_THROW); } @@ -1658,7 +1670,7 @@ lower_try_finally (struct leh_state *state, gtry *tp) this_tf.try_finally_expr = tp; this_tf.top_p = tp; this_tf.outer = state; - if (using_eh_for_cleanups_p () && !cleanup_is_dead_in (state->cur_region)) + if (using_eh_for_cleanups_p () && !cleanup_is_dead_in (state)) { this_tf.region = gen_eh_region_cleanup (state->cur_region); this_state.cur_region = this_tf.region; @@ -1669,6 +1681,7 @@ lower_try_finally (struct leh_state *state, gtry *tp) this_state.cur_region = state->cur_region; } + this_state.outer_non_cleanup = state->outer_non_cleanup; this_state.ehp_region = state->ehp_region; this_state.tf = &this_tf; @@ -1768,6 +1781,7 @@ lower_catch (struct leh_state *state, gtry *tp) { try_region = gen_eh_region_try (state->cur_region); this_state.cur_region = try_region; + this_state.outer_non_cleanup = this_state.cur_region; } lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp)); @@ -1781,6 +1795,7 @@ lower_catch (struct leh_state *state, gtry *tp) emit_resx (&new_seq, try_region); this_state.cur_region = state->cur_region; + this_state.outer_non_cleanup = state->outer_non_cleanup; this_state.ehp_region = try_region; /* Add eh_seq from lowering EH in the cleanup sequence after the cleanup @@ -1857,6 +1872,7 @@ lower_eh_filter (struct leh_state *state, gtry *tp) this_region = gen_eh_region_allowed (state->cur_region, gimple_eh_filter_types (inner)); this_state.cur_region = this_region; + this_state.outer_non_cleanup = this_state.cur_region; } lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp)); @@ -1912,6 +1928,7 @@ lower_eh_must_not_throw (struct leh_state *state, gtry *tp) TREE_USED (this_region->u.must_not_throw.failure_decl) = 1; this_state.cur_region = this_region; + this_state.outer_non_cleanup = this_state.cur_region; } lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp)); @@ -1929,12 +1946,13 @@ lower_cleanup (struct leh_state *state, gtry *tp) eh_region this_region = NULL; struct leh_tf_state fake_tf; gimple_seq result; - bool cleanup_dead = cleanup_is_dead_in (state->cur_region); + bool cleanup_dead = cleanup_is_dead_in (state); if (flag_exceptions && !cleanup_dead) { this_region = gen_eh_region_cleanup (state->cur_region); this_state.cur_region = this_region; + this_state.outer_non_cleanup = state->outer_non_cleanup; } lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp)); -- cgit v1.1 From eb72dc663e9070b281be83a80f6f838a3a878822 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 22 Apr 2020 10:40:51 +0200 Subject: extend DECL_GIMPLE_REG_P to all types This extends DECL_GIMPLE_REG_P to all types so we can clear TREE_ADDRESSABLE even for integers with partial defs, not just complex and vector variables. To make that transition easier the patch inverts DECL_GIMPLE_REG_P to DECL_NOT_GIMPLE_REG_P since that makes the default the current state for all other types besides complex and vectors. For the testcase in PR94703 we're able to expand the partial def'ed local integer to a register then, producing a single movl rather than going through the stack. On i?86 this execute FAILs gcc.dg/torture/pr71522.c because we now expand a round-trip through a long double automatic var to a register fld/fst which normalizes the value. For that during RTL expansion we're looking for problematic punnings of decls and avoid pseudos for those - I chose integer or BLKmode accesses on decls with modes where precision doesn't match bitsize which covers the XFmode case. 2020-05-07 Richard Biener PR middle-end/94703 * tree-core.h (tree_decl_common::gimple_reg_flag): Rename ... (tree_decl_common::not_gimple_reg_flag): ... to this. * tree.h (DECL_GIMPLE_REG_P): Rename ... (DECL_NOT_GIMPLE_REG_P): ... to this. * gimple-expr.c (copy_var_decl): Copy DECL_NOT_GIMPLE_REG_P. (create_tmp_reg): Simplify. (create_tmp_reg_fn): Likewise. (is_gimple_reg): Check DECL_NOT_GIMPLE_REG_P for all regs. * gimplify.c (create_tmp_from_val): Simplify. (gimplify_bind_expr): Likewise. (gimplify_compound_literal_expr): Likewise. (gimplify_function_tree): Likewise. (prepare_gimple_addressable): Set DECL_NOT_GIMPLE_REG_P. * asan.c (create_odr_indicator): Do not clear DECL_GIMPLE_REG_P. (asan_add_global): Copy it. * cgraphunit.c (cgraph_node::expand_thunk): Force args to be GIMPLE regs. * function.c (gimplify_parameters): Copy DECL_NOT_GIMPLE_REG_P. * ipa-param-manipulation.c (ipa_param_body_adjustments::common_initialization): Simplify. (ipa_param_body_adjustments::reset_debug_stmts): Copy DECL_NOT_GIMPLE_REG_P. * omp-low.c (lower_omp_for_scan): Do not set DECL_GIMPLE_REG_P. * sanopt.c (sanitize_rewrite_addressable_params): Likewise. * tree-cfg.c (make_blocks_1): Simplify. (verify_address): Do not verify DECL_GIMPLE_REG_P setting. * tree-eh.c (lower_eh_constructs_2): Simplify. * tree-inline.c (declare_return_variable): Adjust and generalize. (copy_decl_to_var): Copy DECL_NOT_GIMPLE_REG_P. (copy_result_decl_to_var): Likewise. * tree-into-ssa.c (pass_build_ssa::execute): Adjust comment. * tree-nested.c (create_tmp_var_for): Simplify. * tree-parloops.c (separate_decls_in_region_name): Copy DECL_NOT_GIMPLE_REG_P. * tree-sra.c (create_access_replacement): Adjust and generalize partial def support. * tree-ssa-forwprop.c (pass_forwprop::execute): Set DECL_NOT_GIMPLE_REG_P on decls we introduce partial defs on. * tree-ssa.c (maybe_optimize_var): Handle clearing of TREE_ADDRESSABLE and setting/clearing DECL_NOT_GIMPLE_REG_P independently. * lto-streamer-out.c (hash_tree): Hash DECL_NOT_GIMPLE_REG_P. * tree-streamer-out.c (pack_ts_decl_common_value_fields): Stream DECL_NOT_GIMPLE_REG_P. * tree-streamer-in.c (unpack_ts_decl_common_value_fields): Likewise. * cfgexpand.c (avoid_type_punning_on_regs): New. (discover_nonconstant_array_refs): Call avoid_type_punning_on_regs to avoid unsupported mode punning. lto/ * lto-common.c (compare_tree_sccs_1): Compare DECL_NOT_GIMPLE_REG_P. c/ * gimple-parser.c (c_parser_parse_ssa_name): Do not set DECL_GIMPLE_REG_P. cp/ * optimize.c (update_cloned_parm): Copy DECL_NOT_GIMPLE_REG_P. * gcc.dg/tree-ssa/pr94703.c: New testcase. --- gcc/tree-eh.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'gcc/tree-eh.c') diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 2a409dc..10ef2e3 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -2072,9 +2072,6 @@ lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi) gimple_set_location (s, gimple_location (stmt)); gimple_set_block (s, gimple_block (stmt)); gimple_set_lhs (stmt, tmp); - if (TREE_CODE (TREE_TYPE (tmp)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (tmp)) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (tmp) = 1; gsi_insert_after (gsi, s, GSI_SAME_STMT); } /* Look for things that can throw exceptions, and record them. */ -- cgit v1.1 From 1980ffec48c6fa41396bea66366f2e591798e1e1 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Thu, 4 Jun 2020 17:03:27 +0200 Subject: ipa-sra: Do not remove statements necessary because of non-call EH (PR 95113) PR 95113 revealed that when reasoning about which parameters are dead, IPA-SRA does not perform the same check related to non-call exceptions as tree DCE. It most certainly should and so this patch moves the condition used in tree-ssa-dce.c into a separate predicate (in tree-eh.c) and uses it from both places. gcc/ChangeLog: 2020-05-27 Martin Jambor PR ipa/95113 * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Move non-call exceptions check to... * tree-eh.c (stmt_unremovable_because_of_non_call_eh_p): ...this new function. * tree-eh.h (stmt_unremovable_because_of_non_call_eh_p): Declare it. * ipa-sra.c (isra_track_scalar_value_uses): Use it. New parameter fun. gcc/testsuite/ChangeLog: 2020-05-27 Martin Jambor PR ipa/95113 * gcc.dg/ipa/pr95113.c: New test. --- gcc/tree-eh.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'gcc/tree-eh.c') diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 10ef2e3..4246dca 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -2936,6 +2936,16 @@ stmt_could_throw_p (function *fun, gimple *stmt) } } +/* Return true if STMT in function FUN must be assumed necessary because of + non-call exceptions. */ + +bool +stmt_unremovable_because_of_non_call_eh_p (function *fun, gimple *stmt) +{ + return (fun->can_throw_non_call_exceptions + && !fun->can_delete_dead_exceptions + && stmt_could_throw_p (fun, stmt)); +} /* Return true if expression T could throw an exception. */ -- cgit v1.1