From 4c54368f43d619465a0effbe2fe5ea8b0530c122 Mon Sep 17 00:00:00 2001 From: hubicka Date: Wed, 29 Jan 2014 22:50:22 +0000 Subject: [PATCH] * ipa-inline-analysis.c (clobber_only_eh_bb_p): New function. (estimate_function_body_sizes): Use it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@207287 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 +++++ gcc/ipa-inline-analysis.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 71fd8e6..5dba715 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2014-01-29 Jan Hubicka + + * ipa-inline-analysis.c (clobber_only_eh_bb_p): New function. + (estimate_function_body_sizes): Use it. + 2014-01-29 Paolo Carlini PR c++/58561 diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 488251b..9a4c6df 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -2347,6 +2347,54 @@ find_foldable_builtin_expect (basic_block bb) return NULL; } +/* Return true when the basic blocks contains only clobbers followed by RESX. + Such BBs are kept around to make removal of dead stores possible with + presence of EH and will be optimized out by optimize_clobbers later in the + game. + + NEED_EH is used to recurse in case the clobber has non-EH predecestors + that can be clobber only, too.. When it is false, the RESX is not necessary + on the end of basic block. */ + +static bool +clobber_only_eh_bb_p (basic_block bb, bool need_eh = true) +{ + gimple_stmt_iterator gsi = gsi_last_bb (bb); + edge_iterator ei; + edge e; + + if (need_eh) + { + if (gsi_end_p (gsi)) + return false; + if (gimple_code (gsi_stmt (gsi)) != GIMPLE_RESX) + return false; + gsi_prev (&gsi); + } + else if (!single_succ_p (bb)) + return false; + + for (; !gsi_end_p (gsi); gsi_prev (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + if (is_gimple_debug (stmt)) + continue; + if (gimple_clobber_p (stmt)) + continue; + if (gimple_code (stmt) == GIMPLE_LABEL) + break; + return false; + } + + /* See if all predecestors are either throws or clobber only BBs. */ + FOR_EACH_EDGE (e, ei, bb->preds) + if (!(e->flags & EDGE_EH) + && !clobber_only_eh_bb_p (e->src, false)) + return false; + + return true; +} + /* Compute function body size parameters for NODE. When EARLY is true, we compute only simple summaries without non-trivial predicates to drive the early inliner. */ @@ -2410,6 +2458,14 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) { bb = BASIC_BLOCK_FOR_FN (cfun, order[n]); freq = compute_call_stmt_bb_frequency (node->decl, bb); + if (clobber_only_eh_bb_p (bb)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "\n Ignoring BB %i;" + " it will be optimized away by cleanup_clobbers\n", + bb->index); + continue; + } /* TODO: Obviously predicates can be propagated down across CFG. */ if (parms_info) -- 2.7.4