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);
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);
#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);
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. */
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)
{
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. */
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;
\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)
&& 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)
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;
}
}
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
/* 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
}
}
- if (sp != orig_sp)
- abort ();
+ gcc_assert (sp == orig_sp);
}
static void
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;
}
n->u.throw.type = o->u.throw.type;
default:
- abort ();
+ gcc_unreachable ();
}
if (o->label)
if (o->resume)
{
n->resume = map->insn_map[INSN_UID (o->resume)];
- if (n->resume == NULL)
- abort ();
+ gcc_assert (n->resume);
}
return n;
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);
/* 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);
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);
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);
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
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
}
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;
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);
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 ();
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))
/* 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;
/* 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 ();
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;
{
rtx seq;
edge e;
+ edge_iterator ei;
start_sequence ();
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)
/* 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);
}
}
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);
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
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);
}
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)
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);
}
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;
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. */
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);
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);
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);
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))));
}
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
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;
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;
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;
}
return collect_one_action_chain (ar_hash, region->outer);
default:
- abort ();
+ gcc_unreachable ();
}
}
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;
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;
/* ??? 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");
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);
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)