* ipa-inline-analysis.c (clobber_only_eh_bb_p): New function.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 29 Jan 2014 22:50:22 +0000 (22:50 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 29 Jan 2014 22:50:22 +0000 (22:50 +0000)
(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
gcc/ipa-inline-analysis.c

index 71fd8e6..5dba715 100644 (file)
@@ -1,3 +1,8 @@
+2014-01-29  Jan Hubicka  <jh@suse.cz>
+
+       * ipa-inline-analysis.c (clobber_only_eh_bb_p): New function.
+       (estimate_function_body_sizes): Use it.
+
 2014-01-29  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/58561
index 488251b..9a4c6df 100644 (file)
@@ -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)