gcc-patches@gcc.gnu.org
[Top] [All Lists]

[pretty-ipa] Ignore must_not_throw landing pads for inlining

Subject: [pretty-ipa] Ignore must_not_throw landing pads for inlining
From: Jan Hubicka
Date: Sun, 29 Mar 2009 14:12:07 +0200
Hi,
as it turns out, we introduce a lot of noise by MUST_NOT_THROW landing
pads that are kept alive until inlining decisions are fixed.  It is
better to ignore them completely because was majority of them deads
(before inlining on tramp we have 3000 MUST_NOT_THROW landing pads,
after inlining 60) with crossjumping we would have at most one
MUST_NOT_THROW per function so we don't miss much of accuracy
even for -Os.

Honza

        * ipa-inline.c: Include except.h
        (estimate_function_body_sizes): Ignore MUST_NOT_THROW blocks
        * except.c (must_not_throw_labels): New function.
        * except.h (must_not_throw_labels): Declare.
Index: ipa-inline.c
===================================================================
*** ipa-inline.c        (revision 145223)
--- ipa-inline.c        (working copy)
*************** along with GCC; see the file COPYING3.  
*** 138,143 ****
--- 138,144 ----
  #include "tree-flow.h"
  #include "rtl.h"
  #include "ipa-prop.h"
+ #include "except.h"
  
  #define MAX_TIME 1000000000
  
*************** estimate_function_body_sizes (struct cgr
*** 1702,1707 ****
--- 1703,1709 ----
    tree arg;
    int freq;
    tree funtype = TREE_TYPE (node->decl);
+   bitmap must_not_throw = must_not_throw_labels ();
  
    if (dump_file)
      {
*************** estimate_function_body_sizes (struct cgr
*** 1716,1721 ****
--- 1718,1741 ----
        {
          int this_size = estimate_num_insns (gsi_stmt (bsi), 
&eni_size_weights);
          int this_time = estimate_num_insns (gsi_stmt (bsi), 
&eni_time_weights);
+ 
+         /* MUST_NOT_THROW is usually handled by runtime calling terminate and 
stopping
+            stacking unwinding.  However when there is local cleanup that can 
resume
+            to MUST_NOT_THROW then we generate explicit handler containing
+            std::terminate () call.
+            
+            Because inlining of function can introduce new cleanup region, 
prior
+            inlining we keep std::terinate () calls for every MUST_NOT_THROW 
containing
+            function call.  Wast majority of these will be eliminated after 
inlining
+            and crossjumping will inify possible duplicated calls.  So ignore
+            the handlers for function body estimates.  */
+         if (gimple_code (gsi_stmt (bsi)) == GIMPLE_LABEL
+             && bitmap_bit_p (must_not_throw, 
+                              LABEL_DECL_UID (gimple_label_label (gsi_stmt 
(bsi)))))
+           {
+             if (dump_file)
+               fprintf (dump_file, "  MUST_NOT_THROW landing pad.  Ignoring 
whole BB.\n");
+           }
          if (dump_file)
            {
              fprintf (dump_file, "  freq:%6i size:%3i time:%3i ", freq, 
this_size, this_time);
*************** estimate_function_body_sizes (struct cgr
*** 1772,1777 ****
--- 1792,1798 ----
      }
    inline_summary (node)->time_inlining_benefit = time_inlining_benefit;
    inline_summary (node)->size_inlining_benefit = size_inlining_benefit;
+   BITMAP_FREE (must_not_throw);
  }
  
  /* Compute parameters of functions used by inliner.  */
Index: except.c
===================================================================
*** except.c    (revision 145223)
--- except.c    (working copy)
*************** remove_unreachable_regions (rtx insns)
*** 705,710 ****
--- 705,747 ----
    free (uid_region_num);
  }
  
+ /* Return bitmap of all labels that are handlers of must not throw regions.  
*/
+ 
+ bitmap
+ must_not_throw_labels (void)
+ {
+   struct eh_region *i;
+   bitmap labels = BITMAP_ALLOC (NULL);
+ 
+   i = cfun->eh->region_tree;
+   if (! i)
+     return labels;
+ 
+   while (1)
+     {
+       if (i->type == ERT_MUST_NOT_THROW && i->tree_label
+           && LABEL_DECL_UID (i->tree_label) >= 0)
+         bitmap_set_bit (labels, LABEL_DECL_UID (i->tree_label));
+ 
+       /* If there are sub-regions, process them.  */
+       if (i->inner)
+       i = i->inner;
+       /* If there are peers, process them.  */
+       else if (i->next_peer)
+       i = i->next_peer;
+       /* Otherwise, step back up the tree to the next peer.  */
+       else
+       {
+         do {
+           i = i->outer;
+           if (i == NULL)
+             return labels;
+         } while (i->next_peer == NULL);
+         i = i->next_peer;
+       }
+     }
+ }
+ 
  /* Set up EH labels for RTL.  */
  
  void
Index: except.h
===================================================================
*** except.h    (revision 145223)
--- except.h    (working copy)
*************** struct throw_stmt_node GTY(())
*** 175,177 ****
--- 175,178 ----
  
  extern struct htab *get_eh_throw_stmt_table (struct function *);
  extern void set_eh_throw_stmt_table (struct function *, struct htab *);
+ bitmap must_not_throw_labels (void);

<Prev in Thread] Current Thread [Next in Thread>
  • [pretty-ipa] Ignore must_not_throw landing pads for inlining, Jan Hubicka <=