diff mbox

Do not produce empty try-finally statements

Message ID 20140129154707.GA23362@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka Jan. 29, 2014, 3:47 p.m. UTC
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.
diff mbox

Patch

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)