OSDN Git Service

.:
[pf3gnuchains/gcc-fork.git] / gcc / except.c
index 21ade90..c67a982 100644 (file)
@@ -260,8 +260,6 @@ static hashval_t t2r_hash (const void *);
 static void add_type_for_runtime (tree);
 static tree lookup_type_for_runtime (tree);
 
-static struct eh_region *expand_eh_region_end (void);
-
 static void resolve_fixup_regions (void);
 static void remove_fixup_regions (void);
 static void remove_unreachable_regions (rtx);
@@ -378,7 +376,7 @@ init_eh (void)
                         integer_type_node);
       DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node;
 
-      tmp = build_index_type (build_int_2 (4 - 1, 0));
+      tmp = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
       tmp = build_array_type (lang_hooks.types.type_for_mode (word_mode, 1),
                              tmp);
       f_data = build_decl (FIELD_DECL, get_identifier ("__data"), tmp);
@@ -394,17 +392,17 @@ init_eh (void)
 
 #ifdef DONT_USE_BUILTIN_SETJMP
 #ifdef JMP_BUF_SIZE
-      tmp = build_int_2 (JMP_BUF_SIZE - 1, 0);
+      tmp = build_int_cst (NULL_TREE, JMP_BUF_SIZE - 1);
 #else
       /* Should be large enough for most systems, if it is not,
         JMP_BUF_SIZE should be defined with the proper value.  It will
         also tend to be larger than necessary for most systems, a more
         optimal port will define JMP_BUF_SIZE.  */
-      tmp = build_int_2 (FIRST_PSEUDO_REGISTER + 2 - 1, 0);
+      tmp = build_int_cst (NULL_TREE, FIRST_PSEUDO_REGISTER + 2 - 1);
 #endif
 #else
       /* builtin_setjmp takes a pointer to 5 words.  */
-      tmp = build_int_2 (5 * BITS_PER_WORD / POINTER_SIZE - 1, 0);
+      tmp = build_int_cst (NULL_TREE, 5 * BITS_PER_WORD / POINTER_SIZE - 1);
 #endif
       tmp = build_index_type (tmp);
       tmp = build_array_type (ptr_type_node, tmp);
@@ -462,8 +460,7 @@ gen_eh_region (enum eh_region_type type, struct eh_region *outer)
   struct eh_region *new;
 
 #ifdef ENABLE_CHECKING
-  if (! doing_eh (0))
-    abort ();
+  gcc_assert (doing_eh (0));
 #endif
 
   /* Insert a new blank region as a leaf in the tree.  */
@@ -574,141 +571,6 @@ set_eh_region_tree_label (struct eh_region *region, tree lab)
   region->tree_label = lab;
 }
 \f
-/* Start an exception handling region.  All instructions emitted
-   after this point are considered to be part of the region until
-   expand_eh_region_end is invoked.  */
-
-void
-expand_eh_region_start (void)
-{
-  struct eh_region *new;
-  rtx note;
-
-  if (! doing_eh (0))
-    return;
-
-  new = gen_eh_region (ERT_UNKNOWN, cfun->eh->cur_region);
-  cfun->eh->cur_region = new;
-
-  /* Create a note marking the start of this region.  */
-  note = emit_note (NOTE_INSN_EH_REGION_BEG);
-  NOTE_EH_HANDLER (note) = new->region_number;
-}
-
-/* Common code to end a region.  Returns the region just ended.  */
-
-static struct eh_region *
-expand_eh_region_end (void)
-{
-  struct eh_region *cur_region = cfun->eh->cur_region;
-  rtx note;
-
-  /* Create a note marking the end of this region.  */
-  note = emit_note (NOTE_INSN_EH_REGION_END);
-  NOTE_EH_HANDLER (note) = cur_region->region_number;
-
-  /* Pop.  */
-  cfun->eh->cur_region = cur_region->outer;
-
-  return cur_region;
-}
-
-/* Expand HANDLER, which is the operand 1 of a TRY_CATCH_EXPR.  Catch
-   blocks and C++ exception-specifications are handled specially.  */
-
-void
-expand_eh_handler (tree handler)
-{
-  tree inner = expr_first (handler);
-
-  switch (TREE_CODE (inner))
-    {
-    case CATCH_EXPR:
-      expand_start_all_catch ();
-      expand_expr (handler, const0_rtx, VOIDmode, 0);
-      expand_end_all_catch ();
-      break;
-
-    case EH_FILTER_EXPR:
-      if (EH_FILTER_MUST_NOT_THROW (handler))
-       expand_eh_region_end_must_not_throw (EH_FILTER_FAILURE (handler));
-      else
-       expand_eh_region_end_allowed (EH_FILTER_TYPES (handler),
-                                     EH_FILTER_FAILURE (handler));
-      break;
-
-    default:
-      expand_eh_region_end_cleanup (handler);
-      break;
-    }
-}
-
-/* End an exception handling region for a cleanup.  HANDLER is an
-   expression to expand for the cleanup.  */
-
-void
-expand_eh_region_end_cleanup (tree handler)
-{
-  struct eh_region *region;
-  tree protect_cleanup_actions;
-  rtx around_label;
-  rtx data_save[2];
-
-  if (! doing_eh (0))
-    return;
-
-  region = expand_eh_region_end ();
-  region->type = ERT_CLEANUP;
-  region->label = gen_label_rtx ();
-  region->u.cleanup.exp = handler;
-  region->u.cleanup.prev_try = cfun->eh->try_region;
-
-  around_label = gen_label_rtx ();
-  emit_jump (around_label);
-
-  emit_label (region->label);
-
-  if (flag_non_call_exceptions || region->may_contain_throw)
-    {
-      /* Give the language a chance to specify an action to be taken if an
-        exception is thrown that would propagate out of the HANDLER.  */
-      protect_cleanup_actions
-       = (lang_protect_cleanup_actions
-          ? (*lang_protect_cleanup_actions) ()
-          : NULL_TREE);
-
-      if (protect_cleanup_actions)
-       expand_eh_region_start ();
-
-      /* In case this cleanup involves an inline destructor with a try block in
-        it, we need to save the EH return data registers around it.  */
-      data_save[0] = gen_reg_rtx (ptr_mode);
-      emit_move_insn (data_save[0], get_exception_pointer (cfun));
-      data_save[1] = gen_reg_rtx (word_mode);
-      emit_move_insn (data_save[1], get_exception_filter (cfun));
-
-      expand_expr (handler, const0_rtx, VOIDmode, 0);
-
-      emit_move_insn (cfun->eh->exc_ptr, data_save[0]);
-      emit_move_insn (cfun->eh->filter, data_save[1]);
-
-      if (protect_cleanup_actions)
-       expand_eh_region_end_must_not_throw (protect_cleanup_actions);
-
-      /* We need any stack adjustment complete before the around_label.  */
-      do_pending_stack_adjust ();
-    }
-
-  /* We delay the generation of the _Unwind_Resume until we generate
-     landing pads.  We emit a marker here so as to get good control
-     flow data in the meantime.  */
-  region->resume
-    = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
-  emit_barrier ();
-
-  emit_label (around_label);
-}
-
 void
 expand_resx_expr (tree exp)
 {
@@ -719,197 +581,6 @@ expand_resx_expr (tree exp)
   emit_barrier ();
 }
 
-/* End an exception handling region for a try block, and prepares
-   for subsequent calls to expand_start_catch.  */
-
-void
-expand_start_all_catch (void)
-{
-  struct eh_region *region;
-
-  if (! doing_eh (1))
-    return;
-
-  region = expand_eh_region_end ();
-  region->type = ERT_TRY;
-  region->u.try.prev_try = cfun->eh->try_region;
-  region->u.try.continue_label = gen_label_rtx ();
-
-  cfun->eh->try_region = region;
-
-  emit_jump (region->u.try.continue_label);
-}
-
-/* Begin a catch clause.  TYPE is the type caught, a list of such
-   types, (in the case of Java) an ADDR_EXPR which points to the
-   runtime type to match, or null if this is a catch-all
-   clause. Providing a type list enables to associate the catch region
-   with potentially several exception types, which is useful e.g. for
-   Ada.  */
-
-void
-expand_start_catch (tree type_or_list)
-{
-  struct eh_region *c;
-  rtx note;
-
-  if (! doing_eh (0))
-    return;
-
-  c = gen_eh_region_catch (cfun->eh->try_region, type_or_list);
-  cfun->eh->cur_region = c;
-
-  c->label = gen_label_rtx ();
-  emit_label (c->label);
-
-  note = emit_note (NOTE_INSN_EH_REGION_BEG);
-  NOTE_EH_HANDLER (note) = c->region_number;
-}
-
-/* End a catch clause.  Control will resume after the try/catch block.  */
-
-void
-expand_end_catch (void)
-{
-  if (! doing_eh (0))
-    return;
-
-  expand_eh_region_end ();
-  emit_jump (cfun->eh->try_region->u.try.continue_label);
-}
-
-/* End a sequence of catch handlers for a try block.  */
-
-void
-expand_end_all_catch (void)
-{
-  struct eh_region *try_region;
-
-  if (! doing_eh (0))
-    return;
-
-  try_region = cfun->eh->try_region;
-  cfun->eh->try_region = try_region->u.try.prev_try;
-
-  emit_label (try_region->u.try.continue_label);
-}
-
-/* End an exception region for an exception type filter.  ALLOWED is a
-   TREE_LIST of types to be matched by the runtime.  FAILURE is an
-   expression to invoke if a mismatch occurs.
-
-   ??? We could use these semantics for calls to rethrow, too; if we can
-   see the surrounding catch clause, we know that the exception we're
-   rethrowing satisfies the "filter" of the catch type.  */
-
-void
-expand_eh_region_end_allowed (tree allowed, tree failure)
-{
-  struct eh_region *region;
-  rtx around_label;
-
-  if (! doing_eh (0))
-    return;
-
-  region = expand_eh_region_end ();
-  region->type = ERT_ALLOWED_EXCEPTIONS;
-  region->u.allowed.type_list = allowed;
-  region->label = gen_label_rtx ();
-
-  for (; allowed ; allowed = TREE_CHAIN (allowed))
-    add_type_for_runtime (TREE_VALUE (allowed));
-
-  /* We must emit the call to FAILURE here, so that if this function
-     throws a different exception, that it will be processed by the
-     correct region.  */
-
-  around_label = gen_label_rtx ();
-  emit_jump (around_label);
-
-  emit_label (region->label);
-  expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL);
-  /* We must adjust the stack before we reach the AROUND_LABEL because
-     the call to FAILURE does not occur on all paths to the
-     AROUND_LABEL.  */
-  do_pending_stack_adjust ();
-
-  emit_label (around_label);
-}
-
-/* End an exception region for a must-not-throw filter.  FAILURE is an
-   expression invoke if an uncaught exception propagates this far.
-
-   This is conceptually identical to expand_eh_region_end_allowed with
-   an empty allowed list (if you passed "std::terminate" instead of
-   "__cxa_call_unexpected"), but they are represented differently in
-   the C++ LSDA.  */
-
-void
-expand_eh_region_end_must_not_throw (tree failure)
-{
-  struct eh_region *region;
-  rtx around_label;
-
-  if (! doing_eh (0))
-    return;
-
-  region = expand_eh_region_end ();
-  region->type = ERT_MUST_NOT_THROW;
-  region->label = gen_label_rtx ();
-
-  /* We must emit the call to FAILURE here, so that if this function
-     throws a different exception, that it will be processed by the
-     correct region.  */
-
-  around_label = gen_label_rtx ();
-  emit_jump (around_label);
-
-  emit_label (region->label);
-  expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL);
-
-  emit_label (around_label);
-}
-
-/* End an exception region for a throw.  No handling goes on here,
-   but it's the easiest way for the front-end to indicate what type
-   is being thrown.  */
-
-void
-expand_eh_region_end_throw (tree type)
-{
-  struct eh_region *region;
-
-  if (! doing_eh (0))
-    return;
-
-  region = expand_eh_region_end ();
-  region->type = ERT_THROW;
-  region->u.throw.type = type;
-}
-
-/* End a fixup region.  Within this region the cleanups for the immediately
-   enclosing region are _not_ run.  This is used for goto cleanup to avoid
-   destroying an object twice.
-
-   This would be an extraordinarily simple prospect, were it not for the
-   fact that we don't actually know what the immediately enclosing region
-   is.  This surprising fact is because expand_cleanups is currently
-   generating a sequence that it will insert somewhere else.  We collect
-   the proper notion of "enclosing" in convert_from_eh_region_ranges.  */
-
-void
-expand_eh_region_end_fixup (tree handler)
-{
-  struct eh_region *fixup;
-
-  if (! doing_eh (0))
-    return;
-
-  fixup = expand_eh_region_end ();
-  fixup->type = ERT_FIXUP;
-  fixup->u.fixup.cleanup_exp = handler;
-}
-
 /* Note that the current EH region (if any) may contain a throw, or a
    call to a function which itself may contain a throw.  */
 
@@ -954,7 +625,7 @@ get_exception_filter (struct function *fun)
   rtx filter = fun->eh->filter;
   if (fun == cfun && ! filter)
     {
-      filter = gen_reg_rtx (word_mode);
+      filter = gen_reg_rtx (targetm.eh_return_filter_mode ());
       fun->eh->filter = filter;
     }
   return filter;
@@ -962,9 +633,7 @@ get_exception_filter (struct function *fun)
 \f
 /* This section is for the exception handling specific optimization pass.  */
 
-/* Random access the exception region tree.  It's just as simple to
-   collect the regions this way as in expand_eh_region_start, but
-   without having to realloc memory.  */
+/* Random access the exception region tree.  */
 
 void
 collect_eh_region_array (void)
@@ -1018,8 +687,7 @@ resolve_one_fixup_region (struct eh_region *fixup)
          && cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp)
        break;
     }
-  if (j > n)
-    abort ();
+  gcc_assert (j <= n);
 
   real = cleanup->outer;
   if (real && real->type == ERT_FIXUP)
@@ -1141,14 +809,12 @@ remove_unreachable_regions (rtx insns)
 
       if (r->resume)
        {
-         if (uid_region_num[INSN_UID (r->resume)])
-           abort ();
+         gcc_assert (!uid_region_num[INSN_UID (r->resume)]);
          uid_region_num[INSN_UID (r->resume)] = i;
        }
       if (r->label)
        {
-         if (uid_region_num[INSN_UID (r->label)])
-           abort ();
+         gcc_assert (!uid_region_num[INSN_UID (r->label)]);
          uid_region_num[INSN_UID (r->label)] = i;
        }
     }
@@ -1217,7 +883,7 @@ convert_from_eh_region_ranges_1 (rtx *pinsns, int *orig_sp, int cur)
   for (insn = *pinsns; insn ; insn = next)
     {
       next = NEXT_INSN (insn);
-      if (GET_CODE (insn) == NOTE)
+      if (NOTE_P (insn))
        {
          int kind = NOTE_LINE_NUMBER (insn);
          if (kind == NOTE_INSN_EH_REGION_BEG
@@ -1258,7 +924,7 @@ convert_from_eh_region_ranges_1 (rtx *pinsns, int *orig_sp, int cur)
              /* Calls can always potentially throw exceptions, unless
                 they have a REG_EH_REGION note with a value of 0 or less.
                 Which should be the only possible kind so far.  */
-             && (GET_CODE (insn) == CALL_INSN
+             && (CALL_P (insn)
                  /* If we wanted exceptions for non-call insns, then
                     any may_trap_p instruction could throw.  */
                  || (flag_non_call_exceptions
@@ -1272,8 +938,7 @@ convert_from_eh_region_ranges_1 (rtx *pinsns, int *orig_sp, int cur)
        }
     }
 
-  if (sp != orig_sp)
-    abort ();
+  gcc_assert (sp == orig_sp);
 }
 
 static void
@@ -1336,8 +1001,7 @@ add_ehl_entry (rtx label, struct eh_region *region)
      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.  */
-  if (*slot && !cfun->eh->built_landing_pads)
-    abort ();
+  gcc_assert (!*slot || cfun->eh->built_landing_pads);
 
   *slot = entry;
 }
@@ -1434,7 +1098,7 @@ duplicate_eh_region_1 (struct eh_region *o, struct inline_remap *map)
       n->u.throw.type = o->u.throw.type;
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   if (o->label)
@@ -1442,8 +1106,7 @@ duplicate_eh_region_1 (struct eh_region *o, struct inline_remap *map)
   if (o->resume)
     {
       n->resume = map->insn_map[INSN_UID (o->resume)];
-      if (n->resume == NULL)
-       abort ();
+      gcc_assert (n->resume);
     }
 
   return n;
@@ -1744,7 +1407,7 @@ assign_filter_values (void)
              for (;tp_node; tp_node = TREE_CHAIN (tp_node))
                {
                  int flt = add_ttypes_entry (ttypes, TREE_VALUE (tp_node));
-                 tree flt_node = build_int_2 (flt, 0);
+                 tree flt_node = build_int_cst (NULL_TREE, flt);
 
                  r->u.catch.filter_list
                    = tree_cons (NULL_TREE, flt_node, r->u.catch.filter_list);
@@ -1755,7 +1418,7 @@ assign_filter_values (void)
              /* Get a filter value for the NULL list also since it will need
                 an action record anyway.  */
              int flt = add_ttypes_entry (ttypes, NULL);
-             tree flt_node = build_int_2 (flt, 0);
+             tree flt_node = build_int_cst (NULL_TREE, flt);
 
              r->u.catch.filter_list
                = tree_cons (NULL_TREE, flt_node, r->u.catch.filter_list);
@@ -1786,15 +1449,18 @@ 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
      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 (GET_CODE (last) == BARRIER)
+  if (BARRIER_P (last))
     last = PREV_INSN (last);
   bb = create_basic_block (seq, last, BLOCK_FOR_INSN (insn)->prev_bb);
   update_bb_for_insn (bb);
@@ -1856,7 +1522,8 @@ build_post_landing_pads (void)
                        emit_cmp_and_jump_insns
                          (cfun->eh->filter,
                           GEN_INT (tree_low_cst (TREE_VALUE (flt_node), 0)),
-                          EQ, NULL_RTX, word_mode, 0, c->label);
+                          EQ, NULL_RTX, 
+                          targetm.eh_return_filter_mode (), 0, c->label);
 
                        tp_node = TREE_CHAIN (tp_node);
                        flt_node = TREE_CHAIN (flt_node);
@@ -1888,7 +1555,8 @@ build_post_landing_pads (void)
 
          emit_cmp_and_jump_insns (cfun->eh->filter,
                                   GEN_INT (region->u.allowed.filter),
-                                  EQ, NULL_RTX, word_mode, 0, region->label);
+                                  EQ, NULL_RTX, 
+                                  targetm.eh_return_filter_mode (), 0, region->label);
 
          /* We delay the generation of the _Unwind_Resume until we generate
             landing pads.  We emit a marker here so as to get good control
@@ -1914,7 +1582,7 @@ build_post_landing_pads (void)
          break;
 
        default:
-         abort ();
+         gcc_unreachable ();
        }
     }
 }
@@ -1958,8 +1626,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;
@@ -1985,8 +1653,7 @@ connect_post_landing_pads (void)
       end_sequence ();
       barrier = emit_insn_before (seq, region->resume);
       /* Avoid duplicate barrier.  */
-      if (GET_CODE (barrier) != BARRIER)
-       abort ();
+      gcc_assert (BARRIER_P (barrier));
       delete_insn (barrier);
       delete_insn (region->resume);
 
@@ -2066,7 +1733,8 @@ dw2_build_landing_pads (void)
       emit_move_insn (cfun->eh->exc_ptr,
                      gen_rtx_REG (ptr_mode, EH_RETURN_DATA_REGNO (0)));
       emit_move_insn (cfun->eh->filter,
-                     gen_rtx_REG (word_mode, EH_RETURN_DATA_REGNO (1)));
+                     gen_rtx_REG (targetm.eh_return_filter_mode (), 
+                                  EH_RETURN_DATA_REGNO (1)));
 
       seq = get_insns ();
       end_sequence ();
@@ -2210,7 +1878,7 @@ sjlj_mark_call_sites (struct sjlj_lp_info *lp_info)
       rtx note, before, p;
 
       /* Reset value tracking at extended basic block boundaries.  */
-      if (GET_CODE (insn) == CODE_LABEL)
+      if (LABEL_P (insn))
        last_call_site = -2;
 
       if (! INSN_P (insn))
@@ -2222,7 +1890,7 @@ sjlj_mark_call_sites (struct sjlj_lp_info *lp_info)
          /* Calls (and trapping insns) without notes are outside any
             exception handling region in this function.  Mark them as
             no action.  */
-         if (GET_CODE (insn) == CALL_INSN
+         if (CALL_P (insn)
              || (flag_non_call_exceptions
                  && may_trap_p (PATTERN (insn))))
            this_call_site = -1;
@@ -2244,7 +1912,7 @@ sjlj_mark_call_sites (struct sjlj_lp_info *lp_info)
 
       /* Don't separate a call from it's argument loads.  */
       before = insn;
-      if (GET_CODE (insn) == CALL_INSN)
+      if (CALL_P (insn))
        before = find_first_parameter_load (insn, NULL_RTX);
 
       start_sequence ();
@@ -2321,17 +1989,17 @@ sjlj_emit_function_enter (rtx dispatch_label)
      can_throw_internal instructions.  */
 
   for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
-    if (GET_CODE (fn_begin) == NOTE
+    if (NOTE_P (fn_begin)
        && (NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG
            || 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 ((GET_CODE (fn_begin) == NOTE
+       if ((NOTE_P (fn_begin)
             && NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
            || fn_begin == last)
          break;
@@ -2353,6 +2021,7 @@ sjlj_emit_function_exit (void)
 {
   rtx seq;
   edge e;
+  edge_iterator ei;
 
   start_sequence ();
 
@@ -2366,7 +2035,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)
@@ -2376,20 +2045,20 @@ sjlj_emit_function_exit (void)
       /* Figure out whether the place we are supposed to insert libcall
          is inside the last basic block or after it.  In the other case
          we need to emit to edge.  */
-      if (e->src->next_bb != EXIT_BLOCK_PTR)
-       abort ();
-      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
+      gcc_assert (e->src->next_bb == EXIT_BLOCK_PTR);
+      for (insn = BB_HEAD (e->src); ; insn = NEXT_INSN (insn))
        {
-         insn = cfun->eh->sjlj_exit_after;
-         if (GET_CODE (insn) == CODE_LABEL)
-           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);
     }
 }
 
@@ -2509,8 +2178,6 @@ finish_eh_generation (void)
      connect many of the handlers, and then type information will not
      be effective.  Still, this is a win over previous implementations.  */
 
-  cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL);
-
   /* These registers are used by the landing pads.  Make sure they
      have been generated.  */
   get_exception_pointer (cfun);
@@ -2535,21 +2202,22 @@ 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));
     }
-  cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL);
 }
 \f
 static hashval_t
@@ -2588,8 +2256,7 @@ remove_exception_handler_label (rtx label)
   tmp.label = label;
   slot = (struct ehl_map_entry **)
     htab_find_slot (cfun->eh->exception_handler_label_map, &tmp, NO_INSERT);
-  if (! slot)
-    abort ();
+  gcc_assert (slot);
 
   htab_clear_slot (cfun->eh->exception_handler_label_map, (void **) slot);
 }
@@ -2612,9 +2279,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)
@@ -2622,7 +2293,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);
     }
 
@@ -2660,8 +2331,7 @@ remove_eh_handler (struct eh_region *region)
           try->type == ERT_CATCH;
           try = try->next_peer)
        continue;
-      if (try->type != ERT_TRY)
-       abort ();
+      gcc_assert (try->type == ERT_TRY);
 
       next = region->u.catch.next_catch;
       prev = region->u.catch.prev_catch;
@@ -2972,10 +2642,11 @@ reachable_next_level (struct eh_region *region, tree type_thrown,
     case ERT_FIXUP:
     case ERT_UNKNOWN:
       /* Shouldn't see these here.  */
+      gcc_unreachable ();
       break;
+    default:
+      gcc_unreachable ();
     }
-
-  abort ();
 }
 
 /* Invoke CALLBACK on each region reachable from REGION_NUMBER.  */
@@ -3050,7 +2721,7 @@ reachable_handlers (rtx insn)
   rtx handlers = NULL;
   int region_number;
 
-  if (GET_CODE (insn) == JUMP_INSN
+  if (JUMP_P (insn)
       && GET_CODE (PATTERN (insn)) == RESX)
     {
       region_number = XINT (PATTERN (insn), 0);
@@ -3114,12 +2785,12 @@ can_throw_internal (rtx insn)
   if (! INSN_P (insn))
     return false;
 
-  if (GET_CODE (insn) == JUMP_INSN
+  if (JUMP_P (insn)
       && GET_CODE (PATTERN (insn)) == RESX
       && XINT (PATTERN (insn), 0) > 0)
     return can_throw_internal_1 (XINT (PATTERN (insn), 0));
 
-  if (GET_CODE (insn) == INSN
+  if (NONJUMP_INSN_P (insn)
       && GET_CODE (PATTERN (insn)) == SEQUENCE)
     insn = XVECEXP (PATTERN (insn), 0, 0);
 
@@ -3166,7 +2837,7 @@ can_throw_external (rtx insn)
   if (! INSN_P (insn))
     return false;
 
-  if (GET_CODE (insn) == INSN
+  if (NONJUMP_INSN_P (insn)
       && GET_CODE (PATTERN (insn)) == SEQUENCE)
     insn = XVECEXP (PATTERN (insn), 0, 0);
 
@@ -3178,7 +2849,7 @@ can_throw_external (rtx insn)
         assume it might throw.  Given that the front end and middle
         ends mark known NOTHROW functions, this isn't so wildly
         inaccurate.  */
-      return (GET_CODE (insn) == CALL_INSN
+      return (CALL_P (insn)
              || (flag_non_call_exceptions
                  && may_trap_p (PATTERN (insn))));
     }
@@ -3188,14 +2859,14 @@ can_throw_external (rtx insn)
   return can_throw_external_1 (INTVAL (XEXP (note, 0)));
 }
 
-/* Set current_function_nothrow and cfun->all_throwers_are_sibcalls.  */
+/* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls.  */
 
 void
 set_nothrow_function_flags (void)
 {
   rtx insn;
 
-  current_function_nothrow = 1;
+  TREE_NOTHROW (current_function_decl) = 1;
 
   /* Assume cfun->all_throwers_are_sibcalls until we encounter
      something that can throw an exception.  We specifically exempt
@@ -3211,9 +2882,9 @@ set_nothrow_function_flags (void)
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
     if (can_throw_external (insn))
       {
-       current_function_nothrow = 0;
+        TREE_NOTHROW (current_function_decl) = 0;
 
-       if (GET_CODE (insn) != CALL_INSN || !SIBLING_CALL_P (insn))
+       if (!CALL_P (insn) || !SIBLING_CALL_P (insn))
          {
            cfun->all_throwers_are_sibcalls = 0;
            return;
@@ -3224,9 +2895,9 @@ set_nothrow_function_flags (void)
        insn = XEXP (insn, 1))
     if (can_throw_external (insn))
       {
-       current_function_nothrow = 0;
+        TREE_NOTHROW (current_function_decl) = 0;
 
-       if (GET_CODE (insn) != CALL_INSN || !SIBLING_CALL_P (insn))
+       if (!CALL_P (insn) || !SIBLING_CALL_P (insn))
          {
            cfun->all_throwers_are_sibcalls = 0;
            return;
@@ -3260,7 +2931,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;
     }
 
@@ -3589,7 +3260,7 @@ collect_one_action_chain (htab_t ar_hash, struct eh_region *region)
       return collect_one_action_chain (ar_hash, region->outer);
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }
 
@@ -3646,14 +3317,14 @@ convert_to_eh_region_ranges (void)
        rtx this_landing_pad;
 
        insn = iter;
-       if (GET_CODE (insn) == INSN
+       if (NONJUMP_INSN_P (insn)
            && GET_CODE (PATTERN (insn)) == SEQUENCE)
          insn = XVECEXP (PATTERN (insn), 0, 0);
 
        note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
        if (!note)
          {
-           if (! (GET_CODE (insn) == CALL_INSN
+           if (! (CALL_P (insn)
                   || (flag_non_call_exceptions
                       && may_trap_p (PATTERN (insn)))))
              continue;
@@ -3816,8 +3487,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;
 
@@ -3840,21 +3509,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");
@@ -3928,7 +3601,8 @@ output_function_exception_table (void)
   if (! cfun->uses_eh_lsda)
     return;
 
-#ifdef IA64_UNWIND_INFO
+#ifdef TARGET_UNWIND_INFO
+  /* TODO: Move this into target file.  */
   fputs ("\t.personality\t", asm_out_file);
   output_addr_const (asm_out_file, eh_personality_libfunc);
   fputs ("\n\t.handlerdata\n", asm_out_file);
@@ -4092,8 +3766,8 @@ output_function_exception_table (void)
                    cgraph_varpool_mark_needed_node (node);
                }
            }
-         else if (TREE_CODE (type) != INTEGER_CST)
-           abort ();
+         else
+           gcc_assert (TREE_CODE (type) == INTEGER_CST);
        }
 
       if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)