OSDN Git Service

* function.c (assign_parm_setup_block): Revert 11-13 change to
[pf3gnuchains/gcc-fork.git] / gcc / except.c
index b09ff83..c399eb1 100644 (file)
@@ -265,9 +265,6 @@ static void remove_fixup_regions (void);
 static void remove_unreachable_regions (rtx);
 static void convert_from_eh_region_ranges_1 (rtx *, int *, int);
 
-static struct eh_region *duplicate_eh_region_1 (struct eh_region *,
-                                               struct inline_remap *);
-static void duplicate_eh_region_2 (struct eh_region *, struct eh_region **);
 static int ttypes_filter_eq (const void *, const void *);
 static hashval_t ttypes_filter_hash (const void *);
 static int ehspec_filter_eq (const void *, const void *);
@@ -1065,150 +1062,6 @@ current_function_has_exception_handlers (void)
   return false;
 }
 \f
-static struct eh_region *
-duplicate_eh_region_1 (struct eh_region *o, struct inline_remap *map)
-{
-  struct eh_region *n = ggc_alloc_cleared (sizeof (struct eh_region));
-
-  n->region_number = o->region_number + cfun->eh->last_region_number;
-  n->type = o->type;
-
-  switch (n->type)
-    {
-    case ERT_CLEANUP:
-    case ERT_MUST_NOT_THROW:
-      break;
-
-    case ERT_TRY:
-      if (o->u.try.continue_label)
-       n->u.try.continue_label
-         = get_label_from_map (map,
-                               CODE_LABEL_NUMBER (o->u.try.continue_label));
-      break;
-
-    case ERT_CATCH:
-      n->u.catch.type_list = o->u.catch.type_list;
-      break;
-
-    case ERT_ALLOWED_EXCEPTIONS:
-      n->u.allowed.type_list = o->u.allowed.type_list;
-      break;
-
-    case ERT_THROW:
-      n->u.throw.type = o->u.throw.type;
-
-    default:
-      gcc_unreachable ();
-    }
-
-  if (o->label)
-    n->label = get_label_from_map (map, CODE_LABEL_NUMBER (o->label));
-  if (o->resume)
-    {
-      n->resume = map->insn_map[INSN_UID (o->resume)];
-      gcc_assert (n->resume);
-    }
-
-  return n;
-}
-
-static void
-duplicate_eh_region_2 (struct eh_region *o, struct eh_region **n_array)
-{
-  struct eh_region *n = n_array[o->region_number];
-
-  switch (n->type)
-    {
-    case ERT_TRY:
-      n->u.try.catch = n_array[o->u.try.catch->region_number];
-      n->u.try.last_catch = n_array[o->u.try.last_catch->region_number];
-      break;
-
-    case ERT_CATCH:
-      if (o->u.catch.next_catch)
-       n->u.catch.next_catch = n_array[o->u.catch.next_catch->region_number];
-      if (o->u.catch.prev_catch)
-       n->u.catch.prev_catch = n_array[o->u.catch.prev_catch->region_number];
-      break;
-
-    default:
-      break;
-    }
-
-  if (o->outer)
-    n->outer = n_array[o->outer->region_number];
-  if (o->inner)
-    n->inner = n_array[o->inner->region_number];
-  if (o->next_peer)
-    n->next_peer = n_array[o->next_peer->region_number];
-}
-
-int
-duplicate_eh_regions (struct function *ifun, struct inline_remap *map)
-{
-  int ifun_last_region_number = ifun->eh->last_region_number;
-  struct eh_region **n_array, *root, *cur;
-  int i;
-
-  if (ifun_last_region_number == 0)
-    return 0;
-
-  n_array = xcalloc (ifun_last_region_number + 1, sizeof (*n_array));
-
-  for (i = 1; i <= ifun_last_region_number; ++i)
-    {
-      cur = ifun->eh->region_array[i];
-      if (!cur || cur->region_number != i)
-       continue;
-      n_array[i] = duplicate_eh_region_1 (cur, map);
-    }
-  for (i = 1; i <= ifun_last_region_number; ++i)
-    {
-      cur = ifun->eh->region_array[i];
-      if (!cur || cur->region_number != i)
-       continue;
-      duplicate_eh_region_2 (cur, n_array);
-    }
-
-  root = n_array[ifun->eh->region_tree->region_number];
-  cur = cfun->eh->cur_region;
-  if (cur)
-    {
-      struct eh_region *p = cur->inner;
-      if (p)
-       {
-         while (p->next_peer)
-           p = p->next_peer;
-         p->next_peer = root;
-       }
-      else
-       cur->inner = root;
-
-      for (i = 1; i <= ifun_last_region_number; ++i)
-       if (n_array[i] && n_array[i]->outer == NULL)
-         n_array[i]->outer = cur;
-    }
-  else
-    {
-      struct eh_region *p = cfun->eh->region_tree;
-      if (p)
-       {
-         while (p->next_peer)
-           p = p->next_peer;
-         p->next_peer = root;
-       }
-      else
-       cfun->eh->region_tree = root;
-    }
-
-  free (n_array);
-
-  i = cfun->eh->last_region_number;
-  cfun->eh->last_region_number = i + ifun_last_region_number;
-  return i;
-}
-
-\f
 static int
 t2r_eq (const void *pentry, const void *pdata)
 {
@@ -1449,13 +1302,16 @@ emit_to_new_bb_before (rtx seq, rtx insn)
   rtx last;
   basic_block bb;
   edge e;
+  edge_iterator ei;
 
-  /* If there happens to be an fallthru edge (possibly created by cleanup_cfg
+  /* If there happens to be a fallthru edge (possibly created by cleanup_cfg
      call), we don't want it to go into newly created landing pad or other EH 
      construct.  */
-  for (e = BLOCK_FOR_INSN (insn)->pred; e; e = e->pred_next)
+  for (ei = ei_start (BLOCK_FOR_INSN (insn)->preds); (e = ei_safe_edge (ei)); )
     if (e->flags & EDGE_FALLTHRU)
       force_nonfallthru (e);
+    else
+      ei_next (&ei);
   last = emit_insn_before (seq, insn);
   if (BARRIER_P (last))
     last = PREV_INSN (last);
@@ -1623,8 +1479,8 @@ connect_post_landing_pads (void)
          emit_jump (outer->post_landing_pad);
          src = BLOCK_FOR_INSN (region->resume);
          dest = BLOCK_FOR_INSN (outer->post_landing_pad);
-         while (src->succ)
-           remove_edge (src->succ);
+         while (EDGE_COUNT (src->succs) > 0)
+           remove_edge (EDGE_SUCC (src, 0));
          e = make_edge (src, dest, 0);
          e->probability = REG_BR_PROB_BASE;
          e->count = src->count;
@@ -1991,10 +1847,10 @@ sjlj_emit_function_enter (rtx dispatch_label)
            || NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_BASIC_BLOCK))
       break;
   if (NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
-    insert_insn_on_edge (seq, ENTRY_BLOCK_PTR->succ);
+    insert_insn_on_edge (seq, EDGE_SUCC (ENTRY_BLOCK_PTR, 0));
   else
     {
-      rtx last = BB_END (ENTRY_BLOCK_PTR->succ->dest);
+      rtx last = BB_END (EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->dest);
       for (; ; fn_begin = NEXT_INSN (fn_begin))
        if ((NOTE_P (fn_begin)
             && NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
@@ -2018,6 +1874,7 @@ sjlj_emit_function_exit (void)
 {
   rtx seq;
   edge e;
+  edge_iterator ei;
 
   start_sequence ();
 
@@ -2031,7 +1888,7 @@ sjlj_emit_function_exit (void)
      post-dominates all can_throw_internal instructions.  This is
      the last possible moment.  */
 
-  for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
+  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
     if (e->flags & EDGE_FALLTHRU)
       break;
   if (e)
@@ -2042,18 +1899,19 @@ sjlj_emit_function_exit (void)
          is inside the last basic block or after it.  In the other case
          we need to emit to edge.  */
       gcc_assert (e->src->next_bb == EXIT_BLOCK_PTR);
-      for (insn = NEXT_INSN (BB_END (e->src)); insn; insn = NEXT_INSN (insn))
-       if (insn == cfun->eh->sjlj_exit_after)
-         break;
-      if (insn)
-       insert_insn_on_edge (seq, e);
-      else
+      for (insn = BB_HEAD (e->src); ; insn = NEXT_INSN (insn))
        {
-         insn = cfun->eh->sjlj_exit_after;
-         if (LABEL_P (insn))
-           insn = NEXT_INSN (insn);
-         emit_insn_after (seq, insn);
+         if (insn == cfun->eh->sjlj_exit_after)
+           {
+             if (LABEL_P (insn))
+               insn = NEXT_INSN (insn);
+             emit_insn_after (seq, insn);
+             return;
+           }
+         if (insn == BB_END (e->src))
+           break;
        }
+      insert_insn_on_edge (seq, e);
     }
 }
 
@@ -2197,16 +2055,18 @@ finish_eh_generation (void)
     commit_edge_insertions ();
   FOR_EACH_BB (bb)
     {
-      edge e, next;
+      edge e;
+      edge_iterator ei;
       bool eh = false;
-      for (e = bb->succ; e; e = next)
+      for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
        {
-         next = e->succ_next;
          if (e->flags & EDGE_EH)
            {
              remove_edge (e);
              eh = true;
            }
+         else
+           ei_next (&ei);
        }
       if (eh)
        rtl_make_eh_edge (NULL, bb, BB_END (bb));
@@ -2272,9 +2132,13 @@ remove_eh_handler (struct eh_region *region)
   cfun->eh->region_array[region->region_number] = outer;
   if (region->aka)
     {
-      int i;
-      EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i,
-       { cfun->eh->region_array[i] = outer; });
+      unsigned i;
+      bitmap_iterator bi;
+
+      EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i, bi)
+       {
+         cfun->eh->region_array[i] = outer;
+       }
     }
 
   if (outer)
@@ -2282,7 +2146,7 @@ remove_eh_handler (struct eh_region *region)
       if (!outer->aka)
         outer->aka = BITMAP_GGC_ALLOC ();
       if (region->aka)
-       bitmap_a_or_b (outer->aka, outer->aka, region->aka);
+       bitmap_ior_into (outer->aka, region->aka);
       bitmap_set_bit (outer->aka, region->region_number);
     }
 
@@ -2920,7 +2784,7 @@ expand_builtin_eh_return_data_regno (tree arglist)
 
   if (TREE_CODE (which) != INTEGER_CST)
     {
-      error ("argument of `__builtin_eh_return_regno' must be constant");
+      error ("argument of %<__builtin_eh_return_regno%> must be constant");
       return constm1_rtx;
     }
 
@@ -3476,8 +3340,6 @@ sjlj_size_of_call_site_table (void)
 static void
 dw2_output_call_site_table (void)
 {
-  const char *const function_start_lab
-    = IDENTIFIER_POINTER (current_function_func_begin_label);
   int n = cfun->eh->call_site_data_used;
   int i;
 
@@ -3500,21 +3362,25 @@ dw2_output_call_site_table (void)
       /* ??? Perhaps use attr_length to choose data1 or data2 instead of
         data4 if the function is small enough.  */
 #ifdef HAVE_AS_LEB128
-      dw2_asm_output_delta_uleb128 (reg_start_lab, function_start_lab,
+      dw2_asm_output_delta_uleb128 (reg_start_lab,
+                                   current_function_func_begin_label,
                                    "region %d start", i);
       dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab,
                                    "length");
       if (cs->landing_pad)
-       dw2_asm_output_delta_uleb128 (landing_pad_lab, function_start_lab,
+       dw2_asm_output_delta_uleb128 (landing_pad_lab,
+                                     current_function_func_begin_label,
                                      "landing pad");
       else
        dw2_asm_output_data_uleb128 (0, "landing pad");
 #else
-      dw2_asm_output_delta (4, reg_start_lab, function_start_lab,
+      dw2_asm_output_delta (4, reg_start_lab,
+                           current_function_func_begin_label,
                            "region %d start", i);
       dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length");
       if (cs->landing_pad)
-       dw2_asm_output_delta (4, landing_pad_lab, function_start_lab,
+       dw2_asm_output_delta (4, landing_pad_lab,
+                             current_function_func_begin_label,
                              "landing pad");
       else
        dw2_asm_output_data (4, 0, "landing pad");