From d342c045c5b3b2e3a47814d5bd5894513bda12f1 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 1 Jun 2009 21:43:24 +0200 Subject: [PATCH] dwarf2out.c (dwarf2out_cfi_label): Add FORCE argument... * dwarf2out.c (dwarf2out_cfi_label): Add FORCE argument, if true, force output of the label even for dwarf2out_do_cfi_asm. (add_fde_cfi): If -g2 and above and cfi might change CFA, force creation of CFI label and chain DW_CFA_set_loc jumping to it for convert_cfa_to_fb_loc_list. Adjust other dwarf2out_cfi_label caller. (dwarf2out_stack_adjust, dwarf2out_frame_debug, dwarf2out_begin_epilogue, dwarf2out_frame_debug_restore_state): Adjust dwarf2out_cfi_label callers. * tree.h (dwarf2out_cfi_label): Adjust prototype. * config/arm/arm.c (thumb_pushpop, thumb1_output_function_prologue): Adjust dwarf2out_cfi_label callers. * config/vax/vax.c (vax_output_function_prologue): Likewise. From-SVN: r148066 --- gcc/config/arm/arm.c | 6 ++-- gcc/config/vax/vax.c | 2 +- gcc/dwarf2out.c | 71 +++++++++++++++++++++++++++++++++++++------- gcc/tree.h | 2 +- 4 files changed, 65 insertions(+), 16 deletions(-) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index eda5ceaace9c..8ae8dab2914c 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -16984,7 +16984,7 @@ thumb_pushpop (FILE *f, unsigned long mask, int push, int *cfa_offset, if (push && pushed_words && dwarf2out_do_frame ()) { - char *l = dwarf2out_cfi_label (); + char *l = dwarf2out_cfi_label (false); int pushed_mask = real_regs; *cfa_offset += pushed_words * 4; @@ -17880,7 +17880,7 @@ thumb1_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED) the stack pointer. */ if (dwarf2out_do_frame ()) { - char *l = dwarf2out_cfi_label (); + char *l = dwarf2out_cfi_label (false); cfa_offset = cfa_offset + crtl->args.pretend_args_size; dwarf2out_def_cfa (l, SP_REGNUM, cfa_offset); @@ -17929,7 +17929,7 @@ thumb1_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED) if (dwarf2out_do_frame ()) { - char *l = dwarf2out_cfi_label (); + char *l = dwarf2out_cfi_label (false); cfa_offset = cfa_offset + 16; dwarf2out_def_cfa (l, SP_REGNUM, cfa_offset); diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index f0f6a936407c..a783b6f71317 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -133,7 +133,7 @@ vax_output_function_prologue (FILE * file, HOST_WIDE_INT size) if (dwarf2out_do_frame ()) { - const char *label = dwarf2out_cfi_label (); + const char *label = dwarf2out_cfi_label (false); int offset = 0; for (regno = FIRST_PSEUDO_REGISTER-1; regno >= 0; --regno) diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 3c853d466ad7..c23344430c98 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -693,14 +693,15 @@ add_cfi (dw_cfi_ref *list_head, dw_cfi_ref cfi) *p = cfi; } -/* Generate a new label for the CFI info to refer to. */ +/* Generate a new label for the CFI info to refer to. FORCE is true + if a label needs to be output even when using .cfi_* directives. */ char * -dwarf2out_cfi_label (void) +dwarf2out_cfi_label (bool force) { static char label[20]; - if (dwarf2out_do_cfi_asm ()) + if (!force && dwarf2out_do_cfi_asm ()) { /* In this case, we will be emitting the asm directive instead of the label, so just return a placeholder to keep the rest of the @@ -728,11 +729,59 @@ add_fde_cfi (const char *label, dw_cfi_ref cfi) { if (label) { - output_cfi_directive (cfi); + dw_fde_ref fde = current_fde (); + + gcc_assert (fde != NULL); /* We still have to add the cfi to the list so that - lookup_cfa works later on. */ - list_head = ¤t_fde ()->dw_fde_cfi; + lookup_cfa works later on. When -g2 and above we + even need to force emitting of CFI labels and + add to list a DW_CFA_set_loc for convert_cfa_to_fb_loc_list + purposes. */ + switch (cfi->dw_cfi_opc) + { + case DW_CFA_def_cfa_offset: + case DW_CFA_def_cfa_offset_sf: + case DW_CFA_def_cfa_register: + case DW_CFA_def_cfa: + case DW_CFA_def_cfa_sf: + case DW_CFA_def_cfa_expression: + case DW_CFA_restore_state: + if (write_symbols != DWARF2_DEBUG + && write_symbols != VMS_AND_DWARF2_DEBUG) + break; + if (debug_info_level <= DINFO_LEVEL_TERSE) + break; + + if (*label == 0 || strcmp (label, "") == 0) + label = dwarf2out_cfi_label (true); + + if (fde->dw_fde_current_label == NULL + || strcmp (label, fde->dw_fde_current_label) != 0) + { + dw_cfi_ref xcfi; + + label = xstrdup (label); + + /* Set the location counter to the new label. */ + xcfi = new_cfi (); + /* It doesn't metter whether DW_CFA_set_loc + or DW_CFA_advance_loc4 is added here, those aren't + emitted into assembly, only looked up by + convert_cfa_to_fb_loc_list. */ + xcfi->dw_cfi_opc = DW_CFA_set_loc; + xcfi->dw_cfi_oprnd1.dw_cfi_addr = label; + add_cfi (&fde->dw_fde_cfi, xcfi); + fde->dw_fde_current_label = label; + } + break; + default: + break; + } + + output_cfi_directive (cfi); + + list_head = &fde->dw_fde_cfi; } /* ??? If this is a CFI for the CIE, we don't emit. This assumes that the standard CIE contents that the assembler @@ -747,7 +796,7 @@ add_fde_cfi (const char *label, dw_cfi_ref cfi) gcc_assert (fde != NULL); if (*label == 0) - label = dwarf2out_cfi_label (); + label = dwarf2out_cfi_label (false); if (fde->dw_fde_current_label == NULL || strcmp (label, fde->dw_fde_current_label) != 0) @@ -1477,7 +1526,7 @@ dwarf2out_stack_adjust (rtx insn, bool after_p) if (offset == 0) return; - label = dwarf2out_cfi_label (); + label = dwarf2out_cfi_label (false); dwarf2out_args_size_adjust (offset, label); } @@ -2580,7 +2629,7 @@ dwarf2out_frame_debug (rtx insn, bool after_p) return; } - label = dwarf2out_cfi_label (); + label = dwarf2out_cfi_label (false); for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) switch (REG_NOTE_KIND (note)) @@ -2709,7 +2758,7 @@ dwarf2out_begin_epilogue (rtx insn) /* Emit the state save. */ cfi = new_cfi (); cfi->dw_cfi_opc = DW_CFA_remember_state; - add_fde_cfi (dwarf2out_cfi_label (), cfi); + add_fde_cfi (dwarf2out_cfi_label (false), cfi); /* And emulate the state save. */ gcc_assert (!cfa_remember.in_use); @@ -2723,7 +2772,7 @@ void dwarf2out_frame_debug_restore_state (void) { dw_cfi_ref cfi = new_cfi (); - const char *label = dwarf2out_cfi_label (); + const char *label = dwarf2out_cfi_label (false); cfi->dw_cfi_opc = DW_CFA_restore_state; add_fde_cfi (label, cfi); diff --git a/gcc/tree.h b/gcc/tree.h index 5853d762afd7..d88d85f18c04 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5025,7 +5025,7 @@ extern tree tree_overlaps_hard_reg_set (tree, HARD_REG_SET *); /* Generate a new label for the CFI info to refer to. */ -extern char *dwarf2out_cfi_label (void); +extern char *dwarf2out_cfi_label (bool); /* Entry point to update the canonical frame address (CFA). */ -- 2.43.5