* tree-eh.c (cleanup_eh): When not optimizing, do not try EH merging.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Apr 2009 15:13:01 +0000 (15:13 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Apr 2009 15:13:01 +0000 (15:13 +0000)
* function.h (rtl_eh): Remove exception_handler_label_map.
* except.c (ehl_hash, ehl_eq, add_ehl_entry,
remove_exception_handler_label, for_each_eh_label_1): Remove.
(rtl_remove_unreachable_regions): Remove.
(convert_from_eh_region_ranges): Do not remove unreachable regions.
(find_exception_handler_labels): Don't build the hashtable.
(maybe_remove_eh_handler): Remove.
(for_each_eh_label): Rewrite to walk the tree.
(rest_of_handle_eh): Do not cleanup cfg prior EH construction.
* except.h (maybe_remove_eh_handler): Remove.
* passes.c (init_optimization_passes): Schedule second EH cleanup
before out-of-ssa.
* cfgrtl.c (rtl_delete_block, rtl_merge_blocks,
cfg_layout_merge_blocks): Do not call maybe_remove_eh_handler.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145747 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cfgcleanup.c
gcc/cfgrtl.c
gcc/except.c
gcc/except.h
gcc/function.h
gcc/passes.c
gcc/tree-eh.c

index 4f3d18d..c6ec14d 100644 (file)
@@ -1,3 +1,21 @@
+2009-04-08  Jan Hubicka  <jh@suse.cz>
+
+       * tree-eh.c (cleanup_eh): When not optimizing, do not try EH merging.
+       * function.h (rtl_eh): Remove exception_handler_label_map.
+       * except.c (ehl_hash, ehl_eq, add_ehl_entry,
+       remove_exception_handler_label, for_each_eh_label_1): Remove.
+       (rtl_remove_unreachable_regions): Remove.
+       (convert_from_eh_region_ranges): Do not remove unreachable regions.
+       (find_exception_handler_labels): Don't build the hashtable.
+       (maybe_remove_eh_handler): Remove.
+       (for_each_eh_label): Rewrite to walk the tree.
+       (rest_of_handle_eh): Do not cleanup cfg prior EH construction.
+       * except.h (maybe_remove_eh_handler): Remove.
+       * passes.c (init_optimization_passes): Schedule second EH cleanup
+       before out-of-ssa.
+       * cfgrtl.c (rtl_delete_block, rtl_merge_blocks,
+       cfg_layout_merge_blocks): Do not call maybe_remove_eh_handler.
+
 2009-04-08  Paolo Bonzini  <bonzini@gnu.org>
 
        * genoutput.c (validate_optab_operands): New.
index 190bde6..39aae8c 100644 (file)
@@ -2198,8 +2198,6 @@ cleanup_cfg (int mode)
 static unsigned int
 rest_of_handle_jump (void)
 {
-  delete_unreachable_blocks ();
-
   if (crtl->tail_call_emit)
     fixup_tail_calls ();
   return 0;
index a7dc507..95d28ac 100644 (file)
@@ -379,8 +379,6 @@ rtl_delete_block (basic_block b)
      label for an exception handler which can't be reached.  We need
      to remove the label from the exception_handler_label list.  */
   insn = BB_HEAD (b);
-  if (LABEL_P (insn))
-    maybe_remove_eh_handler (insn);
 
   end = get_last_bb_insn (b);
 
@@ -572,10 +570,6 @@ rtl_merge_blocks (basic_block a, basic_block b)
   /* If there was a CODE_LABEL beginning B, delete it.  */
   if (LABEL_P (b_head))
     {
-      /* This might have been an EH label that no longer has incoming
-        EH edges.  Update data structures to match.  */
-      maybe_remove_eh_handler (b_head);
-
       /* Detect basic blocks with nothing but a label.  This can happen
         in particular at the end of a function.  */
       if (b_head == b_end)
@@ -2598,10 +2592,6 @@ cfg_layout_merge_blocks (basic_block a, basic_block b)
   /* If there was a CODE_LABEL beginning B, delete it.  */
   if (LABEL_P (BB_HEAD (b)))
     {
-      /* This might have been an EH label that no longer has incoming
-        EH edges.  Update data structures to match.  */
-      maybe_remove_eh_handler (BB_HEAD (b));
-
       delete_insn (BB_HEAD (b));
     }
 
index e92b827..7e89e06 100644 (file)
@@ -248,14 +248,9 @@ static void sjlj_emit_function_exit (void);
 static void sjlj_emit_dispatch_table (rtx, struct sjlj_lp_info *);
 static void sjlj_build_landing_pads (void);
 
-static hashval_t ehl_hash (const void *);
-static int ehl_eq (const void *, const void *);
-static void add_ehl_entry (rtx, struct eh_region *);
-static void remove_exception_handler_label (rtx);
 static void remove_eh_handler (struct eh_region *);
 static void remove_eh_handler_and_replace (struct eh_region *,
                                           struct eh_region *);
-static int for_each_eh_label_1 (void **, void *);
 
 /* The return value of reachable_next_level.  */
 enum reachable_code
@@ -895,53 +890,11 @@ num_eh_regions (void)
   return cfun->eh->last_region_number + 1;
 }
 
-/* Remove all regions whose labels are not reachable from insns.  */
-
-static void
-rtl_remove_unreachable_regions (rtx insns)
-{
-  int i, *uid_region_num;
-  sbitmap reachable;
-  struct eh_region *r;
-  rtx insn;
-
-  uid_region_num = XCNEWVEC (int, get_max_uid ());
-  reachable = sbitmap_alloc (cfun->eh->last_region_number + 1);
-  sbitmap_zero (reachable);
-
-  for (i = cfun->eh->last_region_number; i > 0; --i)
-    {
-      r = VEC_index (eh_region, cfun->eh->region_array, i);
-      if (!r || r->region_number != i)
-       continue;
-
-      if (r->resume)
-       {
-         gcc_assert (!uid_region_num[INSN_UID (r->resume)]);
-         uid_region_num[INSN_UID (r->resume)] = i;
-       }
-      if (r->label)
-       {
-         gcc_assert (!uid_region_num[INSN_UID (r->label)]);
-         uid_region_num[INSN_UID (r->label)] = i;
-       }
-    }
-
-  for (insn = insns; insn; insn = NEXT_INSN (insn))
-    SET_BIT (reachable, uid_region_num[INSN_UID (insn)]);
-
-  remove_unreachable_regions (reachable, NULL);
-
-  sbitmap_free (reachable);
-  free (uid_region_num);
-}
-
 /* Set up EH labels for RTL.  */
 
 void
 convert_from_eh_region_ranges (void)
 {
-  rtx insns = get_insns ();
   int i, n = cfun->eh->last_region_number;
 
   /* Most of the work is already done at the tree level.  All we need to
@@ -956,31 +909,6 @@ convert_from_eh_region_ranges (void)
       if (region && region->tree_label)
        region->label = DECL_RTL_IF_SET (region->tree_label);
     }
-
-  rtl_remove_unreachable_regions (insns);
-}
-
-static void
-add_ehl_entry (rtx label, struct eh_region *region)
-{
-  struct ehl_map_entry **slot, *entry;
-
-  LABEL_PRESERVE_P (label) = 1;
-
-  entry = GGC_NEW (struct ehl_map_entry);
-  entry->label = label;
-  entry->region = region;
-
-  slot = (struct ehl_map_entry **)
-    htab_find_slot (crtl->eh.exception_handler_label_map, entry, INSERT);
-
-  /* Before landing pad creation, each exception handler has its own
-     label.  After landing pad creation, the exception handlers may
-     share landing pads.  This is ok, since maybe_remove_eh_handler
-     only requires the 1-1 mapping before landing pad creation.  */
-  gcc_assert (!*slot || crtl->eh.built_landing_pads);
-
-  *slot = entry;
 }
 
 void
@@ -988,17 +916,6 @@ find_exception_handler_labels (void)
 {
   int i;
 
-  if (crtl->eh.exception_handler_label_map)
-    htab_empty (crtl->eh.exception_handler_label_map);
-  else
-    {
-      /* ??? The expansion factor here (3/2) must be greater than the htab
-        occupancy factor (4/3) to avoid unnecessary resizing.  */
-      crtl->eh.exception_handler_label_map
-        = htab_create_ggc (cfun->eh->last_region_number * 3 / 2,
-                          ehl_hash, ehl_eq, NULL);
-    }
-
   if (cfun->eh->region_tree == NULL)
     return;
 
@@ -1014,15 +931,7 @@ find_exception_handler_labels (void)
        lab = region->landing_pad;
       else
        lab = region->label;
-
-      if (lab)
-       add_ehl_entry (lab, region);
     }
-
-  /* For sjlj exceptions, need the return label to remain live until
-     after landing pad generation.  */
-  if (USING_SJLJ_EXCEPTIONS && ! crtl->eh.built_landing_pads)
-    add_ehl_entry (return_label, NULL);
 }
 
 /* Returns true if the current function has exception handling regions.  */
@@ -2387,50 +2296,8 @@ finish_eh_generation (void)
     }
 }
 \f
-static hashval_t
-ehl_hash (const void *pentry)
-{
-  const struct ehl_map_entry *const entry
-    = (const struct ehl_map_entry *) pentry;
-
-  /* 2^32 * ((sqrt(5) - 1) / 2) */
-  const hashval_t scaled_golden_ratio = 0x9e3779b9;
-  return CODE_LABEL_NUMBER (entry->label) * scaled_golden_ratio;
-}
-
-static int
-ehl_eq (const void *pentry, const void *pdata)
-{
-  const struct ehl_map_entry *const entry
-    = (const struct ehl_map_entry *) pentry;
-  const struct ehl_map_entry *const data
-    = (const struct ehl_map_entry *) pdata;
-
-  return entry->label == data->label;
-}
-
 /* This section handles removing dead code for flow.  */
 
-/* Remove LABEL from exception_handler_label_map.  */
-
-static void
-remove_exception_handler_label (rtx label)
-{
-  struct ehl_map_entry **slot, tmp;
-
-  /* If exception_handler_label_map was not built yet,
-     there is nothing to do.  */
-  if (crtl->eh.exception_handler_label_map == NULL)
-    return;
-
-  tmp.label = label;
-  slot = (struct ehl_map_entry **)
-    htab_find_slot (crtl->eh.exception_handler_label_map, &tmp, NO_INSERT);
-  gcc_assert (slot);
-
-  htab_clear_slot (crtl->eh.exception_handler_label_map, (void **) slot);
-}
-
 /* Splice REGION from the region tree and replace it by REPLACE etc.  */
 
 static void
@@ -2473,9 +2340,6 @@ remove_eh_handler_and_replace (struct eh_region *region,
     lab = region->landing_pad;
   else
     lab = region->label;
-  if (lab)
-    remove_exception_handler_label (lab);
-
   if (outer)
     pp_start = &outer->inner;
   else
@@ -2536,45 +2400,6 @@ remove_eh_handler (struct eh_region *region)
   remove_eh_handler_and_replace (region, region->outer);
 }
 
-/* LABEL heads a basic block that is about to be deleted.  If this
-   label corresponds to an exception region, we may be able to
-   delete the region.  */
-
-void
-maybe_remove_eh_handler (rtx label)
-{
-  struct ehl_map_entry **slot, tmp;
-  struct eh_region *region;
-
-  /* ??? After generating landing pads, it's not so simple to determine
-     if the region data is completely unused.  One must examine the
-     landing pad and the post landing pad, and whether an inner try block
-     is referencing the catch handlers directly.  */
-  if (crtl->eh.built_landing_pads)
-    return;
-
-  tmp.label = label;
-  slot = (struct ehl_map_entry **)
-    htab_find_slot (crtl->eh.exception_handler_label_map, &tmp, NO_INSERT);
-  if (! slot)
-    return;
-  region = (*slot)->region;
-  if (! region)
-    return;
-
-  /* Flow will want to remove MUST_NOT_THROW regions as unreachable
-     because there is no path to the fallback call to terminate.
-     But the region continues to affect call-site data until there
-     are no more contained calls, which we don't see here.  */
-  if (region->type == ERT_MUST_NOT_THROW)
-    {
-      htab_clear_slot (crtl->eh.exception_handler_label_map, (void **) slot);
-      region->label = NULL_RTX;
-    }
-  else
-    remove_eh_handler (region);
-}
-
 /* Remove Eh region R that has turned out to have no code in its handler.  */
 
 void
@@ -2592,18 +2417,14 @@ remove_eh_region (int r)
 void
 for_each_eh_label (void (*callback) (rtx))
 {
-  htab_traverse (crtl->eh.exception_handler_label_map, for_each_eh_label_1,
-                (void *) &callback);
-}
-
-static int
-for_each_eh_label_1 (void **pentry, void *data)
-{
-  struct ehl_map_entry *entry = *(struct ehl_map_entry **)pentry;
-  void (*callback) (rtx) = *(void (**) (rtx)) data;
-
-  (*callback) (entry->label);
-  return 1;
+  int i;
+  for (i = 0; i < cfun->eh->last_region_number; i++)
+    {
+      struct eh_region *r = VEC_index (eh_region, cfun->eh->region_array, i);
+      if (r && r->region_number == i && r->label
+          && GET_CODE (r->label) == CODE_LABEL)
+       (*callback) (r->label);
+    }
 }
 
 /* Invoke CALLBACK for every exception region in the current function.  */
@@ -4333,7 +4154,6 @@ gate_handle_eh (void)
 static unsigned int
 rest_of_handle_eh (void)
 {
-  cleanup_cfg (CLEANUP_NO_INSN_DEL);
   finish_eh_generation ();
   cleanup_cfg (CLEANUP_NO_INSN_DEL);
   return 0;
index 741c654..24611a5 100644 (file)
@@ -62,7 +62,6 @@ extern void init_eh (void);
 extern void init_eh_for_function (void);
 
 extern rtx reachable_handlers (rtx);
-extern void maybe_remove_eh_handler (rtx);
 void remove_eh_region (int);
 
 extern void convert_from_eh_region_ranges (void);
index 7079797..5bee64b 100644 (file)
@@ -156,8 +156,6 @@ struct rtl_eh GTY(())
   rtx sjlj_fc;
   rtx sjlj_exit_after;
 
-  htab_t GTY ((param_is (struct ehl_map_entry))) exception_handler_label_map;
-
   VEC(tree,gc) *ttype_data;
   varray_type ehspec_data;
   varray_type action_record_data;
index f19b8dd..f3f43d4 100644 (file)
@@ -706,6 +706,7 @@ init_optimization_passes (void)
       NEXT_PASS (pass_uncprop);
       NEXT_PASS (pass_local_pure_const);
     }
+  NEXT_PASS (pass_cleanup_eh);
   NEXT_PASS (pass_del_ssa);
   NEXT_PASS (pass_nrv);
   NEXT_PASS (pass_mark_used_blocks);
index 7f04068..bc93ee1 100644 (file)
@@ -3121,23 +3121,26 @@ cleanup_eh (void)
       dump_eh_tree (dump_file, cfun);
     }
 
-  dominance_info_invalidated = false;
-  /* We cannot use FOR_EACH_BB, since the basic blocks may get removed.  */
-  for (i = NUM_FIXED_BLOCKS; i < last_basic_block; i++)
+  if (optimize)
     {
-      bb = BASIC_BLOCK (i);
-      if (bb)
-       changed |= cleanup_empty_eh (bb);
-    }
-  if (dominance_info_invalidated)
-    {
-      free_dominance_info (CDI_DOMINATORS);
-      free_dominance_info (CDI_POST_DOMINATORS);
-    }
+      dominance_info_invalidated = false;
+      /* We cannot use FOR_EACH_BB, since the basic blocks may get removed.  */
+      for (i = NUM_FIXED_BLOCKS; i < last_basic_block; i++)
+       {
+         bb = BASIC_BLOCK (i);
+         if (bb)
+           changed |= cleanup_empty_eh (bb);
+       }
+      if (dominance_info_invalidated)
+       {
+         free_dominance_info (CDI_DOMINATORS);
+         free_dominance_info (CDI_POST_DOMINATORS);
+       }
 
-  /* Removing contained cleanup can render MUST_NOT_THROW regions empty.  */
-  if (changed)
-    delete_unreachable_blocks ();
+      /* Removing contained cleanup can render MUST_NOT_THROW regions empty.  */
+      if (changed)
+       delete_unreachable_blocks ();
+    }
 
   tree_remove_unreachable_handlers ();
   if (dump_file)