diff options
Diffstat (limited to 'gcc/dwarf2cfi.c')
-rw-r--r-- | gcc/dwarf2cfi.c | 144 |
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); } |