Hi! This patch optimizes away clobber stmts that immediately precede GIMPLE_RETURN or GIMPLE_RESX that throws externally, which allows doing EH cleanups. For both libstdc++.so.6 and go1 this results in slight reduction of .gcc_except_table size: $ readelf -WS obj96[24]/x86*/libstdc*/src/.libs/libstdc++.so.6 | grep gcc_except_table [16] .gcc_except_table PROGBITS 00000000000e4714 0e4714 004d1c 00 A 0 0 4 [16] .gcc_except_table PROGBITS 00000000000e425c 0e425c 004964 00 A 0 0 4 $ readelf -WS obj96[24]/gcc/go1 | grep gcc_except_table [17] .gcc_except_table PROGBITS 000000000160c7fc 120c7fc 003d75 00 A 0 0 4 [17] .gcc_except_table PROGBITS 000000000160c914 120c914 0039be 00 A 0 0 4
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2011-12-08 Jakub Jelinek <ja...@redhat.com> Andrew Pinski <apin...@cavium.com> PR tree-optimization/51117 * tree-eh.c (optimize_clobbers): New function. (execute_lower_eh_dispatch): Call it. --- gcc/tree-eh.c.jj 2011-12-01 11:45:06.000000000 +0100 +++ gcc/tree-eh.c 2011-12-08 17:48:58.009908793 +0100 @@ -3173,6 +3173,30 @@ struct gimple_opt_pass pass_lower_resx = } }; +/* Try to optimize var = {v} {CLOBBER} stmts followed just by return + or external throw. */ + +static void +optimize_clobbers (basic_block bb) +{ + gimple_stmt_iterator gsi = gsi_last_bb (bb); + for (gsi_prev (&gsi); !gsi_end_p (gsi);) + { + gimple stmt = gsi_stmt (gsi); + if (is_gimple_debug (stmt)) + { + gsi_prev (&gsi); + continue; + } + if (!gimple_assign_single_p (stmt) + || TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME + || !TREE_CLOBBER_P (gimple_assign_rhs1 (stmt))) + return; + unlink_stmt_vdef (stmt); + gsi_remove (&gsi, true); + release_defs (stmt); + } +} /* At the end of inlining, we can lower EH_DISPATCH. Return true when we have found some duplicate labels and removed some edges. */ @@ -3337,11 +3361,17 @@ execute_lower_eh_dispatch (void) FOR_EACH_BB (bb) { gimple last = last_stmt (bb); - if (last && gimple_code (last) == GIMPLE_EH_DISPATCH) + if (last == NULL) + continue; + if (gimple_code (last) == GIMPLE_EH_DISPATCH) { redirected |= lower_eh_dispatch (bb, last); any_rewritten = true; } + else if (gimple_code (last) == GIMPLE_RETURN + || (gimple_code (last) == GIMPLE_RESX + && stmt_can_throw_external (last))) + optimize_clobbers (bb); } if (redirected) Jakub