summaryrefslogtreecommitdiff
path: root/gcc/dwarf2cfi.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/dwarf2cfi.c')
-rw-r--r--gcc/dwarf2cfi.c144
1 files changed, 64 insertions, 80 deletions
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 7c531603557..3454b1da10a 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -78,8 +78,6 @@ typedef struct GTY(()) reg_saved_in_data_struct {
rtx saved_in_reg;
} reg_saved_in_data;
-DEF_VEC_O (reg_saved_in_data);
-DEF_VEC_ALLOC_O (reg_saved_in_data, heap);
/* Since we no longer have a proper CFG, we're going to create a facsimile
of one on the fly while processing the frame-related insns.
@@ -141,7 +139,7 @@ typedef struct
implemented as a flat array because it normally contains zero or 1
entry, depending on the target. IA-64 is the big spender here, using
a maximum of 5 entries. */
- VEC(reg_saved_in_data, heap) *regs_saved_in_regs;
+ vec<reg_saved_in_data> regs_saved_in_regs;
/* An identifier for this trace. Used only for debugging dumps. */
unsigned id;
@@ -153,17 +151,13 @@ typedef struct
bool args_size_undefined;
} dw_trace_info;
-DEF_VEC_O (dw_trace_info);
-DEF_VEC_ALLOC_O (dw_trace_info, heap);
typedef dw_trace_info *dw_trace_info_ref;
-DEF_VEC_P (dw_trace_info_ref);
-DEF_VEC_ALLOC_P (dw_trace_info_ref, heap);
/* The variables making up the pseudo-cfg, as described above. */
-static VEC (dw_trace_info, heap) *trace_info;
-static VEC (dw_trace_info_ref, heap) *trace_work_list;
+static vec<dw_trace_info> trace_info;
+static vec<dw_trace_info_ref> trace_work_list;
static htab_t trace_index;
/* A vector of call frame insns for the CIE. */
@@ -203,10 +197,8 @@ typedef struct {
HOST_WIDE_INT cfa_offset;
} queued_reg_save;
-DEF_VEC_O (queued_reg_save);
-DEF_VEC_ALLOC_O (queued_reg_save, heap);
-static VEC(queued_reg_save, heap) *queued_reg_saves;
+static vec<queued_reg_save> queued_reg_saves;
/* True if any CFI directives were emitted at the current insn. */
static bool any_cfis_emitted;
@@ -383,7 +375,7 @@ copy_cfi_row (dw_cfi_row *src)
dw_cfi_row *dst = ggc_alloc_dw_cfi_row ();
*dst = *src;
- dst->reg_save = VEC_copy (dw_cfi_ref, gc, src->reg_save);
+ dst->reg_save = vec_safe_copy (src->reg_save);
return dst;
}
@@ -415,7 +407,7 @@ add_cfi (dw_cfi_ref cfi)
}
if (add_cfi_vec != NULL)
- VEC_safe_push (dw_cfi_ref, gc, *add_cfi_vec, cfi);
+ vec_safe_push (*add_cfi_vec, cfi);
}
static void
@@ -450,9 +442,9 @@ add_cfi_restore (unsigned reg)
static void
update_row_reg_save (dw_cfi_row *row, unsigned column, dw_cfi_ref cfi)
{
- if (VEC_length (dw_cfi_ref, row->reg_save) <= column)
- VEC_safe_grow_cleared (dw_cfi_ref, gc, row->reg_save, column + 1);
- VEC_replace (dw_cfi_ref, row->reg_save, column, cfi);
+ if (vec_safe_length (row->reg_save) <= column)
+ vec_safe_grow_cleared (row->reg_save, column + 1);
+ (*row->reg_save)[column] = cfi;
}
/* This function fills in aa dw_cfa_location structure from a dwarf location
@@ -677,8 +669,8 @@ cfi_row_equal_p (dw_cfi_row *a, dw_cfi_row *b)
else if (!cfa_equal_p (&a->cfa, &b->cfa))
return false;
- n_a = VEC_length (dw_cfi_ref, a->reg_save);
- n_b = VEC_length (dw_cfi_ref, b->reg_save);
+ n_a = vec_safe_length (a->reg_save);
+ n_b = vec_safe_length (b->reg_save);
n_max = MAX (n_a, n_b);
for (i = 0; i < n_max; ++i)
@@ -686,9 +678,9 @@ cfi_row_equal_p (dw_cfi_row *a, dw_cfi_row *b)
dw_cfi_ref r_a = NULL, r_b = NULL;
if (i < n_a)
- r_a = VEC_index (dw_cfi_ref, a->reg_save, i);
+ r_a = (*a->reg_save)[i];
if (i < n_b)
- r_b = VEC_index (dw_cfi_ref, b->reg_save, i);
+ r_b = (*b->reg_save)[i];
if (!cfi_equal_p (r_a, r_b))
return false;
@@ -927,12 +919,11 @@ record_reg_saved_in_reg (rtx dest, rtx src)
reg_saved_in_data *elt;
size_t i;
- FOR_EACH_VEC_ELT (reg_saved_in_data, cur_trace->regs_saved_in_regs, i, elt)
+ FOR_EACH_VEC_ELT (cur_trace->regs_saved_in_regs, i, elt)
if (compare_reg_or_pc (elt->orig_reg, src))
{
if (dest == NULL)
- VEC_unordered_remove (reg_saved_in_data,
- cur_trace->regs_saved_in_regs, i);
+ cur_trace->regs_saved_in_regs.unordered_remove (i);
else
elt->saved_in_reg = dest;
return;
@@ -942,7 +933,7 @@ record_reg_saved_in_reg (rtx dest, rtx src)
return;
reg_saved_in_data e = {src, dest};
- VEC_safe_push (reg_saved_in_data, heap, cur_trace->regs_saved_in_regs, e);
+ cur_trace->regs_saved_in_regs.safe_push (e);
}
/* Add an entry to QUEUED_REG_SAVES saying that REG is now saved at
@@ -957,14 +948,14 @@ queue_reg_save (rtx reg, rtx sreg, HOST_WIDE_INT offset)
/* Duplicates waste space, but it's also necessary to remove them
for correctness, since the queue gets output in reverse order. */
- FOR_EACH_VEC_ELT (queued_reg_save, queued_reg_saves, i, q)
+ FOR_EACH_VEC_ELT (queued_reg_saves, i, q)
if (compare_reg_or_pc (q->reg, reg))
{
*q = e;
return;
}
- VEC_safe_push (queued_reg_save, heap, queued_reg_saves, e);
+ queued_reg_saves.safe_push (e);
}
/* Output all the entries in QUEUED_REG_SAVES. */
@@ -975,7 +966,7 @@ dwarf2out_flush_queued_reg_saves (void)
queued_reg_save *q;
size_t i;
- FOR_EACH_VEC_ELT (queued_reg_save, queued_reg_saves, i, q)
+ FOR_EACH_VEC_ELT (queued_reg_saves, i, q)
{
unsigned int reg, sreg;
@@ -992,7 +983,7 @@ dwarf2out_flush_queued_reg_saves (void)
reg_save (reg, sreg, q->cfa_offset);
}
- VEC_truncate (queued_reg_save, queued_reg_saves, 0);
+ queued_reg_saves.truncate (0);
}
/* Does INSN clobber any register which QUEUED_REG_SAVES lists a saved
@@ -1006,7 +997,7 @@ clobbers_queued_reg_save (const_rtx insn)
queued_reg_save *q;
size_t iq;
- FOR_EACH_VEC_ELT (queued_reg_save, queued_reg_saves, iq, q)
+ FOR_EACH_VEC_ELT (queued_reg_saves, iq, q)
{
size_t ir;
reg_saved_in_data *rir;
@@ -1014,8 +1005,7 @@ clobbers_queued_reg_save (const_rtx insn)
if (modified_in_p (q->reg, insn))
return true;
- FOR_EACH_VEC_ELT (reg_saved_in_data,
- cur_trace->regs_saved_in_regs, ir, rir)
+ FOR_EACH_VEC_ELT (cur_trace->regs_saved_in_regs, ir, rir)
if (compare_reg_or_pc (q->reg, rir->orig_reg)
&& modified_in_p (rir->saved_in_reg, insn))
return true;
@@ -1034,11 +1024,11 @@ reg_saved_in (rtx reg)
reg_saved_in_data *rir;
size_t i;
- FOR_EACH_VEC_ELT (queued_reg_save, queued_reg_saves, i, q)
+ FOR_EACH_VEC_ELT (queued_reg_saves, i, q)
if (q->saved_reg && regn == REGNO (q->saved_reg))
return q->reg;
- FOR_EACH_VEC_ELT (reg_saved_in_data, cur_trace->regs_saved_in_regs, i, rir)
+ FOR_EACH_VEC_ELT (cur_trace->regs_saved_in_regs, i, rir)
if (regn == REGNO (rir->saved_in_reg))
return rir->orig_reg;
@@ -2049,8 +2039,8 @@ change_cfi_row (dw_cfi_row *old_row, dw_cfi_row *new_row)
add_cfi (cfi);
}
- n_old = VEC_length (dw_cfi_ref, old_row->reg_save);
- n_new = VEC_length (dw_cfi_ref, new_row->reg_save);
+ n_old = vec_safe_length (old_row->reg_save);
+ n_new = vec_safe_length (new_row->reg_save);
n_max = MAX (n_old, n_new);
for (i = 0; i < n_max; ++i)
@@ -2058,9 +2048,9 @@ change_cfi_row (dw_cfi_row *old_row, dw_cfi_row *new_row)
dw_cfi_ref r_old = NULL, r_new = NULL;
if (i < n_old)
- r_old = VEC_index (dw_cfi_ref, old_row->reg_save, i);
+ r_old = (*old_row->reg_save)[i];
if (i < n_new)
- r_new = VEC_index (dw_cfi_ref, new_row->reg_save, i);
+ r_new = (*new_row->reg_save)[i];
if (r_old == r_new)
;
@@ -2124,8 +2114,7 @@ add_cfis_to_fde (void)
if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
{
- fde->dw_fde_switch_cfi_index
- = VEC_length (dw_cfi_ref, fde->dw_fde_cfi);
+ fde->dw_fde_switch_cfi_index = vec_safe_length (fde->dw_fde_cfi);
/* Don't attempt to advance_loc4 between labels
in different sections. */
first = true;
@@ -2158,7 +2147,7 @@ add_cfis_to_fde (void)
xcfi->dw_cfi_opc = (first ? DW_CFA_set_loc
: DW_CFA_advance_loc4);
xcfi->dw_cfi_oprnd1.dw_cfi_addr = label;
- VEC_safe_push (dw_cfi_ref, gc, fde->dw_fde_cfi, xcfi);
+ vec_safe_push (fde->dw_fde_cfi, xcfi);
tmp = emit_note_before (NOTE_INSN_CFI_LABEL, insn);
NOTE_LABEL_NUMBER (tmp) = num;
@@ -2167,8 +2156,7 @@ add_cfis_to_fde (void)
do
{
if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_CFI)
- VEC_safe_push (dw_cfi_ref, gc, fde->dw_fde_cfi,
- NOTE_CFI (insn));
+ vec_safe_push (fde->dw_fde_cfi, NOTE_CFI (insn));
insn = NEXT_INSN (insn);
}
while (insn != next);
@@ -2207,10 +2195,9 @@ maybe_record_trace_start (rtx start, rtx origin)
ti->cfa_store = cur_trace->cfa_store;
ti->cfa_temp = cur_trace->cfa_temp;
- ti->regs_saved_in_regs = VEC_copy (reg_saved_in_data, heap,
- cur_trace->regs_saved_in_regs);
+ ti->regs_saved_in_regs = cur_trace->regs_saved_in_regs.copy ();
- VEC_safe_push (dw_trace_info_ref, heap, trace_work_list, ti);
+ trace_work_list.safe_push (ti);
if (dump_file)
fprintf (dump_file, "\tpush trace %u to worklist\n", ti->id);
@@ -2391,7 +2378,7 @@ scan_trace (dw_trace_info *trace)
if (BARRIER_P (insn))
{
/* Don't bother saving the unneeded queued registers at all. */
- VEC_truncate (queued_reg_save, queued_reg_saves, 0);
+ queued_reg_saves.truncate (0);
break;
}
if (save_point_p (insn))
@@ -2438,13 +2425,12 @@ scan_trace (dw_trace_info *trace)
add_cfi_insn = NULL;
restore_args_size = cur_trace->end_true_args_size;
cur_cfa = &cur_row->cfa;
- save_row_reg_save
- = VEC_copy (dw_cfi_ref, gc, cur_row->reg_save);
+ save_row_reg_save = vec_safe_copy (cur_row->reg_save);
scan_insn_after (elt);
/* ??? Should we instead save the entire row state? */
- gcc_assert (!VEC_length (queued_reg_save, queued_reg_saves));
+ gcc_assert (!queued_reg_saves.length ());
create_trace_edges (control);
@@ -2543,21 +2529,21 @@ create_cfi_notes (void)
{
dw_trace_info *ti;
- gcc_checking_assert (queued_reg_saves == NULL);
- gcc_checking_assert (trace_work_list == NULL);
+ gcc_checking_assert (!queued_reg_saves.exists ());
+ gcc_checking_assert (!trace_work_list.exists ());
/* Always begin at the entry trace. */
- ti = &VEC_index (dw_trace_info, trace_info, 0);
+ ti = &trace_info[0];
scan_trace (ti);
- while (!VEC_empty (dw_trace_info_ref, trace_work_list))
+ while (!trace_work_list.is_empty ())
{
- ti = VEC_pop (dw_trace_info_ref, trace_work_list);
+ ti = trace_work_list.pop ();
scan_trace (ti);
}
- VEC_free (queued_reg_save, heap, queued_reg_saves);
- VEC_free (dw_trace_info_ref, heap, trace_work_list);
+ queued_reg_saves.release ();
+ trace_work_list.release ();
}
/* Return the insn before the first NOTE_INSN_CFI after START. */
@@ -2581,7 +2567,7 @@ before_next_cfi_note (rtx start)
static void
connect_traces (void)
{
- unsigned i, n = VEC_length (dw_trace_info, trace_info);
+ unsigned i, n = trace_info.length ();
dw_trace_info *prev_ti, *ti;
/* ??? Ideally, we should have both queued and processed every trace.
@@ -2594,10 +2580,10 @@ connect_traces (void)
/* Remove all unprocessed traces from the list. */
for (i = n - 1; i > 0; --i)
{
- ti = &VEC_index (dw_trace_info, trace_info, i);
+ ti = &trace_info[i];
if (ti->beg_row == NULL)
{
- VEC_ordered_remove (dw_trace_info, trace_info, i);
+ trace_info.ordered_remove (i);
n -= 1;
}
else
@@ -2606,13 +2592,13 @@ connect_traces (void)
/* Work from the end back to the beginning. This lets us easily insert
remember/restore_state notes in the correct order wrt other notes. */
- prev_ti = &VEC_index (dw_trace_info, trace_info, n - 1);
+ prev_ti = &trace_info[n - 1];
for (i = n - 1; i > 0; --i)
{
dw_cfi_row *old_row;
ti = prev_ti;
- prev_ti = &VEC_index (dw_trace_info, trace_info, i - 1);
+ prev_ti = &trace_info[i - 1];
add_cfi_insn = ti->head;
@@ -2677,13 +2663,13 @@ connect_traces (void)
}
/* Connect args_size between traces that have can_throw_internal insns. */
- if (cfun->eh->lp_array != NULL)
+ if (cfun->eh->lp_array)
{
HOST_WIDE_INT prev_args_size = 0;
for (i = 0; i < n; ++i)
{
- ti = &VEC_index (dw_trace_info, trace_info, i);
+ ti = &trace_info[i];
if (ti->switch_sections)
prev_args_size = 0;
@@ -2716,17 +2702,16 @@ create_pseudo_cfg (void)
/* The first trace begins at the start of the function,
and begins with the CIE row state. */
- trace_info = VEC_alloc (dw_trace_info, heap, 16);
+ trace_info.create (16);
memset (&ti, 0, sizeof (ti));
ti.head = get_insns ();
ti.beg_row = cie_cfi_row;
ti.cfa_store = cie_cfi_row->cfa;
ti.cfa_temp.reg = INVALID_REGNUM;
- VEC_quick_push (dw_trace_info, trace_info, ti);
+ trace_info.quick_push (ti);
if (cie_return_save)
- VEC_safe_push (reg_saved_in_data, heap,
- ti.regs_saved_in_regs, *cie_return_save);
+ ti.regs_saved_in_regs.safe_push (*cie_return_save);
/* Walk all the insns, collecting start of trace locations. */
saw_barrier = false;
@@ -2751,8 +2736,8 @@ create_pseudo_cfg (void)
memset (&ti, 0, sizeof (ti));
ti.head = insn;
ti.switch_sections = switch_sections;
- ti.id = VEC_length (dw_trace_info, trace_info) - 1;
- VEC_safe_push (dw_trace_info, heap, trace_info, ti);
+ ti.id = trace_info.length () - 1;
+ trace_info.safe_push (ti);
saw_barrier = false;
switch_sections = false;
@@ -2761,10 +2746,10 @@ create_pseudo_cfg (void)
/* Create the trace index after we've finished building trace_info,
avoiding stale pointer problems due to reallocation. */
- trace_index = htab_create (VEC_length (dw_trace_info, trace_info),
+ trace_index = htab_create (trace_info.length (),
dw_trace_info_hash, dw_trace_info_eq, NULL);
dw_trace_info *tp;
- FOR_EACH_VEC_ELT (dw_trace_info, trace_info, i, tp)
+ FOR_EACH_VEC_ELT (trace_info, i, tp)
{
void **slot;
@@ -2876,15 +2861,14 @@ create_cie_data (void)
the DW_CFA_offset against the return column, not the intermediate
save register. Save the contents of regs_saved_in_regs so that
we can re-initialize it at the start of each function. */
- switch (VEC_length (reg_saved_in_data, cie_trace.regs_saved_in_regs))
+ switch (cie_trace.regs_saved_in_regs.length ())
{
case 0:
break;
case 1:
cie_return_save = ggc_alloc_reg_saved_in_data ();
- *cie_return_save = VEC_index (reg_saved_in_data,
- cie_trace.regs_saved_in_regs, 0);
- VEC_free (reg_saved_in_data, heap, cie_trace.regs_saved_in_regs);
+ *cie_return_save = cie_trace.regs_saved_in_regs[0];
+ cie_trace.regs_saved_in_regs.release ();
break;
default:
gcc_unreachable ();
@@ -2921,10 +2905,10 @@ execute_dwarf2_frame (void)
size_t i;
dw_trace_info *ti;
- FOR_EACH_VEC_ELT (dw_trace_info, trace_info, i, ti)
- VEC_free (reg_saved_in_data, heap, ti->regs_saved_in_regs);
+ FOR_EACH_VEC_ELT (trace_info, i, ti)
+ ti->regs_saved_in_regs.release ();
}
- VEC_free (dw_trace_info, heap, trace_info);
+ trace_info.release ();
htab_delete (trace_index);
trace_index = NULL;
@@ -3286,7 +3270,7 @@ dump_cfi_row (FILE *f, dw_cfi_row *row)
}
output_cfi_directive (f, cfi);
- FOR_EACH_VEC_ELT (dw_cfi_ref, row->reg_save, i, cfi)
+ FOR_EACH_VEC_SAFE_ELT (row->reg_save, i, cfi)
if (cfi)
output_cfi_directive (f, cfi);
}