/* Implements exception handling.
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
Contributed by Mike Stump <mrs@cygnus.com>.
This file is part of GCC.
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
+#include "alias.h"
+#include "symtab.h"
#include "tree.h"
+#include "fold-const.h"
#include "stringpool.h"
#include "stor-layout.h"
#include "flags.h"
+#include "hard-reg-set.h"
#include "function.h"
+#include "insn-codes.h"
+#include "optabs.h"
+#include "insn-config.h"
+#include "expmed.h"
+#include "dojump.h"
+#include "explow.h"
+#include "calls.h"
+#include "emit-rtl.h"
+#include "varasm.h"
+#include "stmt.h"
#include "expr.h"
#include "libfuncs.h"
-#include "insn-config.h"
#include "except.h"
-#include "hard-reg-set.h"
#include "output.h"
#include "dwarf2asm.h"
#include "dwarf2out.h"
#include "dwarf2.h"
#include "toplev.h"
-#include "hash-table.h"
#include "intl.h"
#include "tm_p.h"
#include "target.h"
#include "common/common-target.h"
#include "langhooks.h"
+#include "predict.h"
+#include "dominance.h"
+#include "cfg.h"
+#include "cfgrtl.h"
+#include "basic-block.h"
#include "cgraph.h"
#include "diagnostic.h"
#include "tree-pretty-print.h"
#include "tree-pass.h"
-#include "pointer-set.h"
#include "cfgloop.h"
#include "builtins.h"
-
-/* Provide defaults for stuff that may not be defined when using
- sjlj exceptions. */
-#ifndef EH_RETURN_DATA_REGNO
-#define EH_RETURN_DATA_REGNO(N) INVALID_REGNUM
-#endif
+#include "tree-hash-traits.h"
static GTY(()) int call_site_base;
-static GTY ((param_is (union tree_node)))
- htab_t type_to_runtime_map;
+
+static GTY (()) hash_map<tree_hash, tree> *type_to_runtime_map;
/* Describe the SjLj_Function_Context structure. */
static GTY(()) tree sjlj_fc_type_node;
/* Hashtable helpers. */
-struct action_record_hasher : typed_free_remove <action_record>
+struct action_record_hasher : free_ptr_hash <action_record>
{
- typedef action_record value_type;
- typedef action_record compare_type;
- static inline hashval_t hash (const value_type *);
- static inline bool equal (const value_type *, const compare_type *);
+ static inline hashval_t hash (const action_record *);
+ static inline bool equal (const action_record *, const action_record *);
};
inline hashval_t
-action_record_hasher::hash (const value_type *entry)
+action_record_hasher::hash (const action_record *entry)
{
return entry->next * 1009 + entry->filter;
}
inline bool
-action_record_hasher::equal (const value_type *entry, const compare_type *data)
+action_record_hasher::equal (const action_record *entry,
+ const action_record *data)
{
return entry->filter == data->filter && entry->next == data->next;
}
static bool get_eh_region_and_lp_from_rtx (const_rtx, eh_region *,
eh_landing_pad *);
-static int t2r_eq (const void *, const void *);
-static hashval_t t2r_hash (const void *);
-
static void dw2_build_landing_pads (void);
static int collect_one_action_chain (action_hash_type *, eh_region);
if (! flag_exceptions)
return;
- type_to_runtime_map = htab_create_ggc (31, t2r_hash, t2r_eq, NULL);
+ type_to_runtime_map = hash_map<tree_hash, tree>::create_ggc (31);
/* Create the SjLj_Function_Context structure. This should match
the definition in unwind-sjlj.c. */
{
duplicate_eh_regions_map label_map;
void *label_map_data;
- struct pointer_map_t *eh_map;
+ hash_map<void *, void *> *eh_map;
};
static void
{
eh_landing_pad old_lp, new_lp;
eh_region new_r;
- void **slot;
new_r = gen_eh_region (old_r->type, outer);
- slot = pointer_map_insert (data->eh_map, (void *)old_r);
- gcc_assert (*slot == NULL);
- *slot = (void *)new_r;
+ gcc_assert (!data->eh_map->put (old_r, new_r));
switch (old_r->type)
{
continue;
new_lp = gen_eh_landing_pad (new_r);
- slot = pointer_map_insert (data->eh_map, (void *)old_lp);
- gcc_assert (*slot == NULL);
- *slot = (void *)new_lp;
+ gcc_assert (!data->eh_map->put (old_lp, new_lp));
new_lp->post_landing_pad
= data->label_map (old_lp->post_landing_pad, data->label_map_data);
that allows the caller to remap uses of both EH regions and
EH landing pads. */
-struct pointer_map_t *
+hash_map<void *, void *> *
duplicate_eh_regions (struct function *ifun,
eh_region copy_region, int outer_lp,
duplicate_eh_regions_map map, void *map_data)
data.label_map = map;
data.label_map_data = map_data;
- data.eh_map = pointer_map_create ();
+ data.eh_map = new hash_map<void *, void *>;
- outer_region = get_eh_region_from_lp_number (outer_lp);
+ outer_region = get_eh_region_from_lp_number_fn (cfun, outer_lp);
/* Copy all the regions in the subtree. */
if (copy_region)
return region_a;
}
\f
-static int
-t2r_eq (const void *pentry, const void *pdata)
-{
- const_tree const entry = (const_tree) pentry;
- const_tree const data = (const_tree) pdata;
-
- return TREE_PURPOSE (entry) == data;
-}
-
-static hashval_t
-t2r_hash (const void *pentry)
-{
- const_tree const entry = (const_tree) pentry;
- return TREE_HASH (TREE_PURPOSE (entry));
-}
-
void
add_type_for_runtime (tree type)
{
- tree *slot;
-
/* If TYPE is NOP_EXPR, it means that it already is a runtime type. */
if (TREE_CODE (type) == NOP_EXPR)
return;
- slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
- TREE_HASH (type), INSERT);
- if (*slot == NULL)
- {
- tree runtime = lang_hooks.eh_runtime_type (type);
- *slot = tree_cons (type, runtime, NULL_TREE);
- }
+ bool existed = false;
+ tree *slot = &type_to_runtime_map->get_or_insert (type, &existed);
+ if (!existed)
+ *slot = lang_hooks.eh_runtime_type (type);
}
tree
lookup_type_for_runtime (tree type)
{
- tree *slot;
-
/* If TYPE is NOP_EXPR, it means that it already is a runtime type. */
if (TREE_CODE (type) == NOP_EXPR)
return type;
- slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
- TREE_HASH (type), NO_INSERT);
-
/* We should have always inserted the data earlier. */
- return TREE_VALUE (*slot);
+ return *type_to_runtime_map->get (type);
}
\f
/* Helper for ttypes_filter hashing. */
-struct ttypes_filter_hasher : typed_free_remove <ttypes_filter>
+struct ttypes_filter_hasher : free_ptr_hash <ttypes_filter>
{
- typedef ttypes_filter value_type;
- typedef tree_node compare_type;
- static inline hashval_t hash (const value_type *);
- static inline bool equal (const value_type *, const compare_type *);
+ typedef tree_node *compare_type;
+ static inline hashval_t hash (const ttypes_filter *);
+ static inline bool equal (const ttypes_filter *, const tree_node *);
};
/* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
(a tree) for a @TTypes type node we are thinking about adding. */
inline bool
-ttypes_filter_hasher::equal (const value_type *entry, const compare_type *data)
+ttypes_filter_hasher::equal (const ttypes_filter *entry, const tree_node *data)
{
return entry->t == data;
}
inline hashval_t
-ttypes_filter_hasher::hash (const value_type *entry)
+ttypes_filter_hasher::hash (const ttypes_filter *entry)
{
return TREE_HASH (entry->t);
}
/* Helper for ehspec hashing. */
-struct ehspec_hasher : typed_free_remove <ttypes_filter>
+struct ehspec_hasher : free_ptr_hash <ttypes_filter>
{
- typedef ttypes_filter value_type;
- typedef ttypes_filter compare_type;
- static inline hashval_t hash (const value_type *);
- static inline bool equal (const value_type *, const compare_type *);
+ static inline hashval_t hash (const ttypes_filter *);
+ static inline bool equal (const ttypes_filter *, const ttypes_filter *);
};
/* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
should put these in some canonical order. */
inline bool
-ehspec_hasher::equal (const value_type *entry, const compare_type *data)
+ehspec_hasher::equal (const ttypes_filter *entry, const ttypes_filter *data)
{
return type_list_equal (entry->t, data->t);
}
/* Hash function for exception specification lists. */
inline hashval_t
-ehspec_hasher::hash (const value_type *entry)
+ehspec_hasher::hash (const ttypes_filter *entry)
{
hashval_t h = 0;
tree list;
first instruction of some existing BB and return the newly
produced block. */
static basic_block
-emit_to_new_bb_before (rtx seq, rtx insn)
+emit_to_new_bb_before (rtx_insn *seq, rtx insn)
{
- rtx last;
+ rtx_insn *last;
basic_block bb;
edge e;
edge_iterator ei;
for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
{
basic_block bb;
- rtx seq;
+ rtx_insn *seq;
edge e;
if (lp == NULL || lp->post_landing_pad == NULL)
sjlj_mark_call_sites (void)
{
int last_call_site = -2;
- rtx insn, mem;
+ rtx_insn *insn;
+ rtx mem;
for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
{
eh_region r;
bool nothrow;
int this_call_site;
- rtx before, p;
+ rtx_insn *before, *p;
/* Reset value tracking at extended basic block boundaries. */
if (LABEL_P (insn))
last_call_site = -2;
+ /* If the function allocates dynamic stack space, the context must
+ be updated after every allocation/deallocation accordingly. */
+ if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_UPDATE_SJLJ_CONTEXT)
+ {
+ rtx buf_addr;
+
+ start_sequence ();
+ buf_addr = plus_constant (Pmode, XEXP (crtl->eh.sjlj_fc, 0),
+ sjlj_fc_jbuf_ofs);
+ expand_builtin_update_setjmp_buf (buf_addr);
+ p = get_insns ();
+ end_sequence ();
+ emit_insn_before (p, insn);
+ }
+
if (! INSN_P (insn))
continue;
/* Don't separate a call from it's argument loads. */
before = insn;
if (CALL_P (insn))
- before = find_first_parameter_load (insn, NULL_RTX);
+ before = find_first_parameter_load (insn, NULL);
start_sequence ();
mem = adjust_address (crtl->eh.sjlj_fc, TYPE_MODE (integer_type_node),
/* Construct the SjLj_Function_Context. */
static void
-sjlj_emit_function_enter (rtx dispatch_label)
+sjlj_emit_function_enter (rtx_code_label *dispatch_label)
{
- rtx fn_begin, fc, mem, seq;
+ rtx_insn *fn_begin, *seq;
+ rtx fc, mem;
bool fn_begin_outside_block;
rtx personality = get_personality_function (current_function_decl);
the call to unwind_sjlj_unregister_libfunc if needed. */
void
-sjlj_emit_function_exit_after (rtx after)
+sjlj_emit_function_exit_after (rtx_insn *after)
{
crtl->eh.sjlj_exit_after = after;
}
static void
sjlj_emit_function_exit (void)
{
- rtx seq, insn;
+ rtx_insn *seq, *insn;
start_sequence ();
}
static void
-sjlj_emit_dispatch_table (rtx dispatch_label, int num_dispatch)
+sjlj_emit_dispatch_table (rtx_code_label *dispatch_label, int num_dispatch)
{
- enum machine_mode unwind_word_mode = targetm.unwind_word_mode ();
- enum machine_mode filter_mode = targetm.eh_return_filter_mode ();
+ machine_mode unwind_word_mode = targetm.unwind_word_mode ();
+ machine_mode filter_mode = targetm.eh_return_filter_mode ();
eh_landing_pad lp;
- rtx mem, seq, fc, before, exc_ptr_reg, filter_reg;
- rtx first_reachable_label;
+ rtx mem, fc, exc_ptr_reg, filter_reg;
+ rtx_insn *seq;
basic_block bb;
eh_region r;
edge e;
CFG edges more exactly, we can use the forced_labels list instead. */
LABEL_PRESERVE_P (dispatch_label) = 1;
forced_labels
- = gen_rtx_EXPR_LIST (VOIDmode, dispatch_label, forced_labels);
+ = gen_rtx_INSN_LIST (VOIDmode, dispatch_label, forced_labels);
#endif
/* Load up exc_ptr and filter values from the function context. */
/* Jump to one of the directly reachable regions. */
disp_index = 0;
- first_reachable_label = NULL;
+ rtx_code_label *first_reachable_label = NULL;
/* If there's exactly one call site in the function, don't bother
generating a switch statement. */
for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
if (lp && lp->post_landing_pad)
{
- rtx seq2, label;
+ rtx_insn *seq2;
+ rtx_code_label *label;
start_sequence ();
t = build_int_cst (integer_type_node, disp_index);
case_elt = build_case_label (t, NULL, t_label);
dispatch_labels.quick_push (case_elt);
- label = label_rtx (t_label);
+ label = jump_target_rtx (t_label);
}
else
label = gen_label_rtx ();
seq2 = get_insns ();
end_sequence ();
- before = label_rtx (lp->post_landing_pad);
+ rtx_insn *before = label_rtx (lp->post_landing_pad);
bb = emit_to_new_bb_before (seq2, before);
e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
e->count = bb->count;
{
for (loop = bb->loop_father;
loop_outer (loop); loop = loop_outer (loop))
- {
- loop->header = NULL;
- loop->latch = NULL;
- }
+ mark_loop_for_removal (loop);
}
}
num_dispatch = sjlj_assign_call_site_values ();
if (num_dispatch > 0)
{
- rtx dispatch_label = gen_label_rtx ();
+ rtx_code_label *dispatch_label = gen_label_rtx ();
int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node,
TYPE_MODE (sjlj_fc_type_node),
TYPE_ALIGN (sjlj_fc_type_node));
align);
sjlj_mark_call_sites ();
- sjlj_emit_function_enter (NULL_RTX);
+ sjlj_emit_function_enter (NULL);
sjlj_emit_function_exit ();
}
sjlj_lp_call_site_index.release ();
}
+/* Update the sjlj function context. This function should be called
+ whenever we allocate or deallocate dynamic stack space. */
+
+void
+update_sjlj_context (void)
+{
+ if (!flag_exceptions)
+ return;
+
+ emit_note (NOTE_INSN_UPDATE_SJLJ_CONTEXT);
+}
+
/* After initial rtl generation, call back to finish generating
exception support code. */
{
if (lp)
{
- rtx lab = lp->landing_pad;
+ rtx_code_label *lab = lp->landing_pad;
if (lab && LABEL_P (lab))
(*callback) (lab);
}
direct call cases) and just pull the data out of the trees. */
void
-make_reg_eh_region_note (rtx insn, int ecf_flags, int lp_nr)
+make_reg_eh_region_note (rtx_insn *insn, int ecf_flags, int lp_nr)
{
rtx value;
if (ecf_flags & ECF_NOTHROW)
already exists. */
void
-make_reg_eh_region_note_nothrow_nononlocal (rtx insn)
+make_reg_eh_region_note_nothrow_nononlocal (rtx_insn *insn)
{
rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
rtx intmin = GEN_INT (INT_MIN);
to look for a note, or the note itself. */
void
-copy_reg_eh_region_note_forward (rtx note_or_insn, rtx first, rtx last)
+copy_reg_eh_region_note_forward (rtx note_or_insn, rtx_insn *first, rtx last)
{
- rtx insn, note = note_or_insn;
+ rtx_insn *insn;
+ rtx note = note_or_insn;
if (INSN_P (note_or_insn))
{
/* Likewise, but iterate backward. */
void
-copy_reg_eh_region_note_backward (rtx note_or_insn, rtx last, rtx first)
+copy_reg_eh_region_note_backward (rtx note_or_insn, rtx_insn *last, rtx first)
{
- rtx insn, note = note_or_insn;
+ rtx_insn *insn;
+ rtx note = note_or_insn;
if (INSN_P (note_or_insn))
{
if (NONJUMP_INSN_P (insn)
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
{
- rtx seq = PATTERN (insn);
- int i, n = XVECLEN (seq, 0);
+ rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn));
+ int i, n = seq->len ();
for (i = 0; i < n; i++)
- if (can_throw_external (XVECEXP (seq, 0, i)))
+ if (can_throw_external (seq->element (i)))
return true;
return false;
if (NONJUMP_INSN_P (insn)
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
{
- rtx seq = PATTERN (insn);
- int i, n = XVECLEN (seq, 0);
+ rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn));
+ int i, n = seq->len ();
for (i = 0; i < n; i++)
- if (!insn_nothrow_p (XVECEXP (seq, 0, i)))
+ if (!insn_nothrow_p (seq->element (i)))
return false;
return true;
/* ??? This test is here in this file because it (ab)uses REG_EH_REGION. */
bool
-can_nonlocal_goto (const_rtx insn)
+can_nonlocal_goto (const rtx_insn *insn)
{
if (nonlocal_goto_handler_labels && CALL_P (insn))
{
static unsigned int
set_nothrow_function_flags (void)
{
- rtx insn;
+ rtx_insn *insn;
crtl->nothrow = 1;
}
if (crtl->nothrow
- && (cgraph_function_body_availability (cgraph_get_node
- (current_function_decl))
+ && (cgraph_node::get (current_function_decl)->get_availability ()
>= AVAIL_AVAILABLE))
{
- struct cgraph_node *node = cgraph_get_node (current_function_decl);
+ struct cgraph_node *node = cgraph_node::get (current_function_decl);
struct cgraph_edge *e;
for (e = node->callers; e; e = e->next_caller)
e->can_throw_external = false;
- cgraph_set_nothrow_flag (node, true);
+ node->set_nothrow_flag (true);
if (dump_file)
fprintf (dump_file, "Marking function nothrow: %s\n\n",
RTL_PASS, /* type */
"nothrow", /* name */
OPTGROUP_NONE, /* optinfo_flags */
- true, /* has_execute */
TV_NONE, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
= expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
eh_region src
= expand_builtin_eh_common (CALL_EXPR_ARG (exp, 1));
- enum machine_mode fmode = targetm.eh_return_filter_mode ();
+ machine_mode fmode = targetm.eh_return_filter_mode ();
if (dst->exc_ptr_reg == NULL)
dst->exc_ptr_reg = gen_reg_rtx (ptr_mode);
}
/* First mask out any unwanted bits. */
-#ifdef MASK_RETURN_ADDR
- expand_and (Pmode, addr, MASK_RETURN_ADDR, addr);
-#endif
+ rtx mask = MASK_RETURN_ADDR;
+ if (mask)
+ expand_and (Pmode, addr, mask, addr);
/* Then adjust to find the real return address. */
-#if defined (RETURN_ADDR_OFFSET)
- addr = plus_constant (Pmode, addr, RETURN_ADDR_OFFSET);
-#endif
+ if (RETURN_ADDR_OFFSET)
+ addr = plus_constant (Pmode, addr, RETURN_ADDR_OFFSET);
return addr;
}
addr = convert_memory_address (Pmode, addr);
-#ifdef RETURN_ADDR_OFFSET
- addr = force_reg (Pmode, addr);
- addr = plus_constant (Pmode, addr, -RETURN_ADDR_OFFSET);
-#endif
+ if (RETURN_ADDR_OFFSET)
+ {
+ addr = force_reg (Pmode, addr);
+ addr = plus_constant (Pmode, addr, -RETURN_ADDR_OFFSET);
+ }
return addr;
}
void
expand_eh_return (void)
{
- rtx around_label;
+ rtx_code_label *around_label;
if (! crtl->eh.ehr_label)
return;
return call_site_base + crtl->eh.call_site_record_v[section]->length () - 1;
}
+static rtx_note *
+emit_note_eh_region_end (rtx_insn *insn)
+{
+ rtx_insn *next = NEXT_INSN (insn);
+
+ /* Make sure we do not split a call and its corresponding
+ CALL_ARG_LOCATION note. */
+ if (next && NOTE_P (next)
+ && NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION)
+ insn = next;
+
+ return emit_note_after (NOTE_INSN_EH_REGION_END, insn);
+}
+
/* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
The new note numbers will not refer to region numbers, but
instead to call site entries. */
static unsigned int
convert_to_eh_region_ranges (void)
{
- rtx insn, iter, note;
+ rtx insn;
+ rtx_insn *iter;
+ rtx_note *note;
action_hash_type ar_hash (31);
int last_action = -3;
- rtx last_action_insn = NULL_RTX;
+ rtx_insn *last_action_insn = NULL;
rtx last_landing_pad = NULL_RTX;
- rtx first_no_action_insn = NULL_RTX;
+ rtx_insn *first_no_action_insn = NULL;
int call_site = 0;
int cur_sec = 0;
- rtx section_switch_note = NULL_RTX;
- rtx first_no_action_insn_before_switch = NULL_RTX;
- rtx last_no_action_insn_before_switch = NULL_RTX;
+ rtx_insn *section_switch_note = NULL;
+ rtx_insn *first_no_action_insn_before_switch = NULL;
+ rtx_insn *last_no_action_insn_before_switch = NULL;
int saved_call_site_base = call_site_base;
vec_alloc (crtl->eh.action_record_data, 64);
eh_region region;
bool nothrow;
int this_action;
- rtx this_landing_pad;
+ rtx_code_label *this_landing_pad;
insn = iter;
if (NONJUMP_INSN_P (insn)
if (this_action >= 0)
this_landing_pad = lp->landing_pad;
else
- this_landing_pad = NULL_RTX;
+ this_landing_pad = NULL;
/* Differing actions or landing pads implies a change in call-site
info, which implies some EH_REGION note should be emitted. */
note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
first_no_action_insn_before_switch);
NOTE_EH_HANDLER (note) = call_site;
- note = emit_note_after (NOTE_INSN_EH_REGION_END,
- last_no_action_insn_before_switch);
+ note
+ = emit_note_eh_region_end (last_no_action_insn_before_switch);
NOTE_EH_HANDLER (note) = call_site;
gcc_assert (last_action != -3
|| (last_action_insn
== last_no_action_insn_before_switch));
- first_no_action_insn_before_switch = NULL_RTX;
- last_no_action_insn_before_switch = NULL_RTX;
+ first_no_action_insn_before_switch = NULL;
+ last_no_action_insn_before_switch = NULL;
call_site_base++;
}
/* If we'd not seen a previous action (-3) or the previous
note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
first_no_action_insn);
NOTE_EH_HANDLER (note) = call_site;
- first_no_action_insn = NULL_RTX;
+ first_no_action_insn = NULL;
}
- note = emit_note_after (NOTE_INSN_EH_REGION_END,
- last_action_insn);
+ note = emit_note_eh_region_end (last_action_insn);
NOTE_EH_HANDLER (note) = call_site;
}
{
first_no_action_insn_before_switch = first_no_action_insn;
last_no_action_insn_before_switch = last_action_insn;
- first_no_action_insn = NULL_RTX;
+ first_no_action_insn = NULL;
gcc_assert (last_action == -1);
last_action = -3;
}
if (last_action >= -1 && ! first_no_action_insn)
{
- note = emit_note_after (NOTE_INSN_EH_REGION_END, last_action_insn);
+ note = emit_note_eh_region_end (last_action_insn);
NOTE_EH_HANDLER (note) = call_site;
}
RTL_PASS, /* type */
"eh_ranges", /* name */
OPTGROUP_NONE, /* optinfo_flags */
- true, /* has_execute */
TV_NONE, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
}
void
-set_eh_throw_stmt_table (struct function *fun, struct htab *table)
+set_eh_throw_stmt_table (function *fun, hash_map<gimple, int> *table)
{
fun->eh->throw_stmt_table = table;
}
-htab_t
+hash_map<gimple, int> *
get_eh_throw_stmt_table (struct function *fun)
{
return fun->eh->throw_stmt_table;
fprintf (out, "(nil),");
if (lp->post_landing_pad)
{
- rtx lab = label_rtx (lp->post_landing_pad);
+ rtx_insn *lab = label_rtx (lp->post_landing_pad);
fprintf (out, "%i%s}", INSN_UID (lab),
NOTE_P (lab) ? "(del)" : "");
}