Hi, I tested the following patch. It makes inliner to ignore empty EH clenaup regions regadless they are internal or external in anticipation they will be removed. It also make tree-eh to not do any cleanups pre-inline. This is independent change, but I wanted to stress the code bit more.
Here are stats of tramp3d compilation: Mainline: einline: 27894 inlined calls Inlined 31427 calls, eliminated 6496 functions text data bss dec hex 575081 40 1082 576203 8cacb Patch to avoid EH regions with clobbers (the one I started thread with): einline: 27954 inlined calls Inlined 31512 calls, eliminated 6496 functions text data bss dec hex 572117 40 1082 573239 8bf37 New patch: einline: 27954 inlined calls Inlined 31502 calls, eliminated 6494 functions text data bss dec hex 579248 40 1082 580370 8db12 No exceptions: einline: 25528 inlined calls Inlined 29194 calls, eliminated 6527 functions text data bss dec hex 551555 40 1082 552677 86ee5 It seems tha tthis patch still does bit worse than the original (wrong) proposed patch, but it gets things better than mainline. I wonder what other kinds of cleanups we are missing. Note that the number of inlines in no-exception case is lower probably because quite few inlines are dtors in EH cleanups. Also the text size includes EH tables, as usual for size. Bootrstrapped/regtested x86_64-linux. I plan to commit the ipa-inline-analysis.c change if there are no complains. Does the tree-eh change look resonable based on this thread? I agree WRT eh cleanup and -O0. Shall I make a patch? * tree-eh.c (optimize_clobbers): Do nothing before inlining * ipa-inline-analysis.c (clobber_only_eh_bb_p): New function. (estimate_function_body_sizes): Use it. Index: tree-eh.c =================================================================== --- tree-eh.c (revision 206946) +++ tree-eh.c (working copy) @@ -3381,6 +3381,11 @@ edge_iterator ei; edge e; + /* Before inlining we do not want to optimize away clobbers that may become + internal when inlined. */ + if (optimize && !cfun->after_inlining) + return; + /* Only optimize anything if the bb contains at least one clobber, ends with resx (checked by caller), optionally contains some debug stmts or labels, or at most one __builtin_stack_restore Index: ipa-inline-analysis.c =================================================================== --- ipa-inline-analysis.c (revision 206946) +++ ipa-inline-analysis.c (working copy) @@ -2347,6 +2347,56 @@ 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; + + if (!need_eh) + debug_bb (bb); + 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 +2460,14 @@ { 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)