On Thu, Mar 24, 2011 at 06:08:01PM +0100, Jason Merrill wrote: > This ought to cut down on the number of cases we have to handle in > all the different places in dwarf2out that deal with this stuff. > > Does that make sense to you?
Here is updated patch, it is quite larger than the last one, because I found a few more broken things, in particular in both DW_AT_frame_base location list and variable location lists we'd for -freorder-blocks-and-partition happily have a range starting in one of the partitions and ending in the other partition. If the second partition ends up being linked after the first one, it just means the range covers also lots of unrelated stuff, but if second partition is linked first, we end up with a range with start being above end. Ok for trunk if it passes bootstrap/regtest? 2011-03-25 Jakub Jelinek <ja...@redhat.com> PR debug/48253 * dwarf2out.c (struct dw_fde_struct): Remove dw_fde_hot_section_label, dw_fde_hot_section_end_label, dw_fde_unlikely_section_label, dw_fde_unlikely_section_end_label, cold_in_std_section and dw_fde_switched_cold_to_hot fields. Add dw_fde_second_begin, dw_fde_second_end and second_in_std_section fields. (output_fde): Use dw_fde_second_{begin,end} if second is true, otherwise dw_fde_{begin,end}. (dwarf2out_begin_prologue): Stop initializing removed dw_fde_struct fields, initialize new fields. Initialize in_std_section unconditionally from the first partition. (dwarf2out_end_epilogue): Don't override dw_fde_end when dw_fde_switched_sections. (dwarf2out_switch_text_section): Stop initializing removed dw_fde_struct fields, initialize new fields, initialize also dw_fde_end here. Set dw_fde_switch_cfi even when dwarf2out_do_cfi_asm (). Call var_location_switch_text_section. (struct var_loc_list_def): Add last_before_switch field. (arange_table, arange_table_allocated, arange_table_in_use, ARANGE_TABLE_INCREMENT, add_arange): Removed. (size_of_aranges): Count !in_std_section and !second_in_std_section hunks in fdes, instead of looking at arange_table_in_use. (output_aranges): Add aranges_length argument, don't call size_of_aranges here. Instead of using aranges_table* emit ranges for fdes when !in_std_section resp. !second_in_std_section. (dw_loc_list): Break ranges crossing section switch. (convert_cfa_to_fb_loc_list): Likewise. If switched sections, use dw_fde_second_end instead of dw_fde_end as end of last range. (gen_subprogram_die): Don't call add_arange. Use dw_fde_{begin,end} for first partition and if switched section dw_fde_second_{begin,end} for the second. !fde->dw_fde_switched_cold_to_hot instead of fde->in_std_section. (var_location_switch_text_section_1, var_location_switch_text_section): New functions. (dwarf2out_begin_function): Initialize cold_text_section even when function_section () isn't text_section. (prune_unused_types): Don't walk arange_table. (dwarf2out_finish): Don't needlessly test flag_reorder_blocks_and_partition when testing cold_text_section_used. If info_section_emitted, call size_of_aranges and if it indicates non-empty .debug_aranges, call output_aranges with the computed size. Stop using removed dw_fde_struct fields, use dw_fde_{begin,end} for first partition and dw_fde_second_{begin,end} for second. --- gcc/dwarf2out.c.jj 2011-03-25 11:24:06.000000000 +0100 +++ gcc/dwarf2out.c 2011-03-25 15:19:00.000000000 +0100 @@ -302,10 +302,8 @@ typedef struct GTY(()) dw_fde_struct { const char *dw_fde_end; const char *dw_fde_vms_end_prologue; const char *dw_fde_vms_begin_epilogue; - const char *dw_fde_hot_section_label; - const char *dw_fde_hot_section_end_label; - const char *dw_fde_unlikely_section_label; - const char *dw_fde_unlikely_section_end_label; + const char *dw_fde_second_begin; + const char *dw_fde_second_end; dw_cfi_ref dw_fde_cfi; dw_cfi_ref dw_fde_switch_cfi; /* Last CFI before switching sections. */ HOST_WIDE_INT stack_realignment; @@ -324,13 +322,11 @@ typedef struct GTY(()) dw_fde_struct { unsigned drap_reg_saved: 1; /* True iff dw_fde_begin label is in text_section or cold_text_section. */ unsigned in_std_section : 1; - /* True iff dw_fde_unlikely_section_label is in text_section or + /* True iff dw_fde_second_begin label is in text_section or cold_text_section. */ - unsigned cold_in_std_section : 1; + unsigned second_in_std_section : 1; /* True iff switched sections. */ unsigned dw_fde_switched_sections : 1; - /* True iff switching from cold to hot section. */ - unsigned dw_fde_switched_cold_to_hot : 1; } dw_fde_node; @@ -3628,28 +3624,8 @@ output_fde (dw_fde_ref fde, bool for_eh, dw2_asm_output_offset (DWARF_OFFSET_SIZE, section_start_label, debug_frame_section, "FDE CIE offset"); - if (!fde->dw_fde_switched_sections) - { - begin = fde->dw_fde_begin; - end = fde->dw_fde_end; - } - else - { - /* For the first section, prefer dw_fde_begin over - dw_fde_{hot,cold}_section_label, as the latter - might be separated from the real start of the - function by alignment padding. */ - if (!second) - begin = fde->dw_fde_begin; - else if (fde->dw_fde_switched_cold_to_hot) - begin = fde->dw_fde_hot_section_label; - else - begin = fde->dw_fde_unlikely_section_label; - if (second ^ fde->dw_fde_switched_cold_to_hot) - end = fde->dw_fde_unlikely_section_end_label; - else - end = fde->dw_fde_hot_section_end_label; - } + begin = second ? fde->dw_fde_second_begin : fde->dw_fde_begin; + end = second ? fde->dw_fde_second_end : fde->dw_fde_end; if (for_eh) { @@ -4107,14 +4083,11 @@ dwarf2out_begin_prologue (unsigned int l fde = &fde_table[fde_table_in_use++]; fde->decl = current_function_decl; fde->dw_fde_begin = dup_label; + fde->dw_fde_end = NULL; fde->dw_fde_current_label = dup_label; - fde->dw_fde_hot_section_label = NULL; - fde->dw_fde_hot_section_end_label = NULL; - fde->dw_fde_unlikely_section_label = NULL; - fde->dw_fde_unlikely_section_end_label = NULL; + fde->dw_fde_second_begin = NULL; + fde->dw_fde_second_end = NULL; fde->dw_fde_switched_sections = 0; - fde->dw_fde_switched_cold_to_hot = 0; - fde->dw_fde_end = NULL; fde->dw_fde_vms_end_prologue = NULL; fde->dw_fde_vms_begin_epilogue = NULL; fde->dw_fde_cfi = NULL; @@ -4125,27 +4098,9 @@ dwarf2out_begin_prologue (unsigned int l fde->nothrow = crtl->nothrow; fde->drap_reg = INVALID_REGNUM; fde->vdrap_reg = INVALID_REGNUM; - if (flag_reorder_blocks_and_partition) - { - section *unlikelysec; - if (first_function_block_is_cold) - fde->in_std_section = 1; - else - fde->in_std_section - = (fnsec == text_section - || (cold_text_section && fnsec == cold_text_section)); - unlikelysec = unlikely_text_section (); - fde->cold_in_std_section - = (unlikelysec == text_section - || (cold_text_section && unlikelysec == cold_text_section)); - } - else - { - fde->in_std_section - = (fnsec == text_section - || (cold_text_section && fnsec == cold_text_section)); - fde->cold_in_std_section = 0; - } + fde->in_std_section = (fnsec == text_section + || (cold_text_section && fnsec == cold_text_section)); + fde->second_in_std_section = 0; args_size = old_args_size = 0; @@ -4241,7 +4196,8 @@ dwarf2out_end_epilogue (unsigned int lin ASM_OUTPUT_LABEL (asm_out_file, label); fde = current_fde (); gcc_assert (fde != NULL); - fde->dw_fde_end = xstrdup (label); + if (!fde->dw_fde_switched_sections) + fde->dw_fde_end = xstrdup (label); } void @@ -4288,20 +4244,31 @@ dwarf2out_note_section_used (void) cold_text_section_used = true; } +static void var_location_switch_text_section (void); + void dwarf2out_switch_text_section (void) { + section *sect; dw_fde_ref fde = current_fde (); + dw_cfi_ref cfi; gcc_assert (cfun && fde && !fde->dw_fde_switched_sections); fde->dw_fde_switched_sections = 1; - fde->dw_fde_switched_cold_to_hot = !in_cold_section_p; - fde->dw_fde_hot_section_label = crtl->subsections.hot_section_label; - fde->dw_fde_hot_section_end_label = crtl->subsections.hot_section_end_label; - fde->dw_fde_unlikely_section_label = crtl->subsections.cold_section_label; - fde->dw_fde_unlikely_section_end_label = crtl->subsections.cold_section_end_label; + if (!in_cold_section_p) + { + fde->dw_fde_end = crtl->subsections.cold_section_end_label; + fde->dw_fde_second_begin = crtl->subsections.hot_section_label; + fde->dw_fde_second_end = crtl->subsections.hot_section_end_label; + } + else + { + fde->dw_fde_end = crtl->subsections.hot_section_end_label; + fde->dw_fde_second_begin = crtl->subsections.cold_section_label; + fde->dw_fde_second_end = crtl->subsections.cold_section_end_label; + } have_multiple_function_sections = true; /* Reset the current label on switching text sections, so that we @@ -4316,7 +4283,12 @@ dwarf2out_switch_text_section (void) fprintf (asm_out_file, "\t.cfi_endproc\n"); /* Now do the real section switch. */ - switch_to_section (current_function_section ()); + sect = current_function_section (); + switch_to_section (sect); + + fde->second_in_std_section + = (sect == text_section + || (cold_text_section && sect == cold_text_section)); if (dwarf2out_do_cfi_asm ()) { @@ -4325,16 +4297,12 @@ dwarf2out_switch_text_section (void) again. */ output_cfis (fde->dw_fde_cfi, true, fde, true); } - else - { - dw_cfi_ref cfi = fde->dw_fde_cfi; - - cfi = fde->dw_fde_cfi; - if (cfi) - while (cfi->dw_cfi_next != NULL) - cfi = cfi->dw_cfi_next; - fde->dw_fde_switch_cfi = cfi; - } + cfi = fde->dw_fde_cfi; + if (cfi) + while (cfi->dw_cfi_next != NULL) + cfi = cfi->dw_cfi_next; + fde->dw_fde_switch_cfi = cfi; + var_location_switch_text_section (); } /* And now, the subset of the debugging information support code necessary @@ -6122,6 +6090,11 @@ struct GTY (()) var_loc_list_def { Do not mark it for GC because it is marked through the chain. */ struct var_loc_node * GTY ((skip ("%h"))) last; + /* Pointer to the last element before section switch, + if NULL, either sections weren't switched or first + is after section switch. */ + struct var_loc_node * GTY ((skip ("%h"))) last_before_switch; + /* DECL_UID of the variable decl. */ unsigned int decl_id; }; @@ -6212,19 +6185,6 @@ static GTY (()) VEC (pubname_entry, gc) defines/undefines (and file start/end markers). */ static GTY (()) VEC (macinfo_entry, gc) * macinfo_table; -/* Array of dies for which we should generate .debug_arange info. */ -static GTY((length ("arange_table_allocated"))) dw_die_ref *arange_table; - -/* Number of elements currently allocated for arange_table. */ -static GTY(()) unsigned arange_table_allocated; - -/* Number of elements in arange_table currently in use. */ -static GTY(()) unsigned arange_table_in_use; - -/* Size (in elements) of increments by which we may expand the - arange_table. */ -#define ARANGE_TABLE_INCREMENT 64 - /* Array of dies for which we should generate .debug_ranges info. */ static GTY ((length ("ranges_table_allocated"))) dw_ranges_ref ranges_table; @@ -6432,8 +6392,7 @@ static void add_pubname (tree, dw_die_re static void add_pubname_string (const char *, dw_die_ref); static void add_pubtype (tree, dw_die_ref); static void output_pubnames (VEC (pubname_entry,gc) *); -static void add_arange (tree, dw_die_ref); -static void output_aranges (void); +static void output_aranges (unsigned long); static unsigned int add_ranges_num (int); static unsigned int add_ranges (const_tree); static void add_ranges_by_labels (dw_die_ref, const char *, const char *, @@ -10881,7 +10840,20 @@ size_of_aranges (void) size += 2 * DWARF2_ADDR_SIZE; if (cold_text_section_used) size += 2 * DWARF2_ADDR_SIZE; - size += 2 * DWARF2_ADDR_SIZE * arange_table_in_use; + if (have_multiple_function_sections) + { + unsigned fde_idx = 0; + + for (fde_idx = 0; fde_idx < fde_table_in_use; fde_idx++) + { + dw_fde_ref fde = &fde_table[fde_idx]; + + if (!fde->in_std_section) + size += 2 * DWARF2_ADDR_SIZE; + if (fde->dw_fde_switched_sections && !fde->second_in_std_section) + size += 2 * DWARF2_ADDR_SIZE; + } + } /* Count the two zero words used to terminated the address range table. */ size += 2 * DWARF2_ADDR_SIZE; @@ -11712,35 +11684,14 @@ output_pubnames (VEC (pubname_entry, gc) dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, NULL); } -/* Add a new entry to .debug_aranges if appropriate. */ - -static void -add_arange (tree decl, dw_die_ref die) -{ - if (! DECL_SECTION_NAME (decl)) - return; - - if (arange_table_in_use == arange_table_allocated) - { - arange_table_allocated += ARANGE_TABLE_INCREMENT; - arange_table = GGC_RESIZEVEC (dw_die_ref, arange_table, - arange_table_allocated); - memset (arange_table + arange_table_in_use, 0, - ARANGE_TABLE_INCREMENT * sizeof (dw_die_ref)); - } - - arange_table[arange_table_in_use++] = die; -} - /* Output the information that goes into the .debug_aranges table. Namely, define the beginning and ending address range of the text section generated for this compilation unit. */ static void -output_aranges (void) +output_aranges (unsigned long aranges_length) { unsigned i; - unsigned long aranges_length = size_of_aranges (); if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4) dw2_asm_output_data (4, 0xffffffff, @@ -11785,38 +11736,28 @@ output_aranges (void) cold_text_section_label, "Length"); } - for (i = 0; i < arange_table_in_use; i++) + if (have_multiple_function_sections) { - dw_die_ref die = arange_table[i]; - - /* We shouldn't see aranges for DIEs outside of the main CU. */ - gcc_assert (die->die_mark); + unsigned fde_idx = 0; - if (die->die_tag == DW_TAG_subprogram) - { - dw2_asm_output_addr (DWARF2_ADDR_SIZE, get_AT_low_pc (die), - "Address"); - dw2_asm_output_delta (DWARF2_ADDR_SIZE, get_AT_hi_pc (die), - get_AT_low_pc (die), "Length"); - } - else + for (fde_idx = 0; fde_idx < fde_table_in_use; fde_idx++) { - /* A static variable; extract the symbol from DW_AT_location. - Note that this code isn't currently hit, as we only emit - aranges for functions (jason 9/23/99). */ - dw_attr_ref a = get_AT (die, DW_AT_location); - dw_loc_descr_ref loc; - - gcc_assert (a && AT_class (a) == dw_val_class_loc); - - loc = AT_loc (a); - gcc_assert (loc->dw_loc_opc == DW_OP_addr); + dw_fde_ref fde = &fde_table[fde_idx]; - dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE, - loc->dw_loc_oprnd1.v.val_addr, "Address"); - dw2_asm_output_data (DWARF2_ADDR_SIZE, - get_AT_unsigned (die, DW_AT_byte_size), - "Length"); + if (!fde->in_std_section) + { + dw2_asm_output_addr (DWARF2_ADDR_SIZE, fde->dw_fde_begin, + "Address"); + dw2_asm_output_delta (DWARF2_ADDR_SIZE, fde->dw_fde_end, + fde->dw_fde_begin, "Length"); + } + if (fde->dw_fde_switched_sections && !fde->second_in_std_section) + { + dw2_asm_output_addr (DWARF2_ADDR_SIZE, fde->dw_fde_second_begin, + "Address"); + dw2_asm_output_delta (DWARF2_ADDR_SIZE, fde->dw_fde_second_end, + fde->dw_fde_second_begin, "Length"); + } } } @@ -15132,9 +15073,19 @@ dw_loc_list (var_loc_list *loc_list, tre } if (descr) { + /* If section switch happens in between node->label + and node->next->label (or end of function) and + we can't emit it as a single entry list, + emit two ranges, first one ending at the end + of first partition and second one starting at the + beginning of second partition. */ + if (node == loc_list->last_before_switch + && (node != loc_list->first || loc_list->first->next) + && current_function_decl) + endname = current_fde ()->dw_fde_end; /* The variable has a location between NODE->LABEL and NODE->NEXT->LABEL. */ - if (node->next) + else if (node->next) endname = node->next->label; /* If the variable has a location at the last label it keeps its location until the end of function. */ @@ -15149,6 +15100,32 @@ dw_loc_list (var_loc_list *loc_list, tre *listp = new_loc_list (descr, node->label, endname, secname); listp = &(*listp)->dw_loc_next; + + if (node == loc_list->last_before_switch + && (node != loc_list->first || loc_list->first->next) + && current_function_decl) + { + if (GET_CODE (node->loc) == EXPR_LIST) + descr = dw_sra_loc_expr (decl, node->loc); + else + { + initialized = NOTE_VAR_LOCATION_STATUS (node->loc); + varloc = NOTE_VAR_LOCATION (node->loc); + descr = dw_loc_list_1 (decl, varloc, want_address, + initialized); + } + gcc_assert (descr); + /* The variable has a location between NODE->LABEL and + NODE->NEXT->LABEL. */ + if (node->next) + endname = node->next->label; + else + endname = current_fde ()->dw_fde_second_end; + *listp = new_loc_list (descr, + current_fde ()->dw_fde_second_begin, + endname, secname); + listp = &(*listp)->dw_loc_next; + } } } @@ -17225,6 +17202,8 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_IN remember = next_cfa; start_label = fde->dw_fde_begin; + if (fde->dw_fde_switched_sections && fde->dw_fde_switch_cfi == NULL) + start_label = fde->dw_fde_second_begin; /* ??? Bald assumption that the CIE opcode list does not contain advance opcodes. */ @@ -17235,32 +17214,50 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_IN last_label = start_label; for (cfi = fde->dw_fde_cfi; cfi; cfi = cfi->dw_cfi_next) - switch (cfi->dw_cfi_opc) - { - case DW_CFA_set_loc: - case DW_CFA_advance_loc1: - case DW_CFA_advance_loc2: - case DW_CFA_advance_loc4: - if (!cfa_equal_p (&last_cfa, &next_cfa)) - { - *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset), - start_label, last_label, section); + { + switch (cfi->dw_cfi_opc) + { + case DW_CFA_set_loc: + case DW_CFA_advance_loc1: + case DW_CFA_advance_loc2: + case DW_CFA_advance_loc4: + if (!cfa_equal_p (&last_cfa, &next_cfa)) + { + *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset), + start_label, last_label, section); - list_tail = &(*list_tail)->dw_loc_next; - last_cfa = next_cfa; - start_label = last_label; - } - last_label = cfi->dw_cfi_oprnd1.dw_cfi_addr; - break; + list_tail = &(*list_tail)->dw_loc_next; + last_cfa = next_cfa; + start_label = last_label; + } + last_label = cfi->dw_cfi_oprnd1.dw_cfi_addr; + break; - case DW_CFA_advance_loc: - /* The encoding is complex enough that we should never emit this. */ - gcc_unreachable (); + case DW_CFA_advance_loc: + /* The encoding is complex enough that we should never emit this. */ + gcc_unreachable (); - default: - lookup_cfa_1 (cfi, &next_cfa, &remember); - break; - } + default: + lookup_cfa_1 (cfi, &next_cfa, &remember); + break; + } + if (cfi == fde->dw_fde_switch_cfi) + { + if (!cfa_equal_p (&last_cfa, &next_cfa)) + { + *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset), + start_label, last_label, section); + + list_tail = &(*list_tail)->dw_loc_next; + last_cfa = next_cfa; + start_label = last_label; + } + *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset), + start_label, fde->dw_fde_end, section); + list_tail = &(*list_tail)->dw_loc_next; + start_label = last_label = fde->dw_fde_second_begin; + } + } if (!cfa_equal_p (&last_cfa, &next_cfa)) { @@ -17271,7 +17268,10 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_IN } *list_tail = new_loc_list (build_cfa_loc (&next_cfa, offset), - start_label, fde->dw_fde_end, section); + start_label, + fde->dw_fde_switched_sections + ? fde->dw_fde_second_end : fde->dw_fde_end, + section); if (list && list->dw_loc_next) gen_llsym (list); @@ -19196,7 +19196,6 @@ gen_subprogram_die (tree decl, dw_die_re #endif add_pubname (decl, subr_die); - add_arange (decl, subr_die); } else { /* Generate pubnames entries for the split function code @@ -19212,28 +19211,11 @@ gen_subprogram_die (tree decl, dw_die_re section, since the HOT/COLD labels might precede an alignment offset. */ bool range_list_added = false; - if (fde->in_std_section) - { - add_ranges_by_labels (subr_die, - fde->dw_fde_begin, - fde->dw_fde_end, - &range_list_added); - add_ranges_by_labels (subr_die, - fde->dw_fde_unlikely_section_label, - fde->dw_fde_unlikely_section_end_label, - &range_list_added); - } - else - { - add_ranges_by_labels (subr_die, - fde->dw_fde_begin, - fde->dw_fde_end, - &range_list_added); - add_ranges_by_labels (subr_die, - fde->dw_fde_hot_section_label, - fde->dw_fde_hot_section_end_label, - &range_list_added); - } + add_ranges_by_labels (subr_die, fde->dw_fde_begin, + fde->dw_fde_end, &range_list_added); + add_ranges_by_labels (subr_die, fde->dw_fde_second_begin, + fde->dw_fde_second_end, + &range_list_added); add_pubname (decl, subr_die); if (range_list_added) add_ranges (NULL); @@ -19258,7 +19240,6 @@ gen_subprogram_die (tree decl, dw_die_re fde->dw_fde_end); /* Add it. */ add_pubname (decl, subr_die); - add_arange (decl, subr_die); /* Build a minimal DIE for the secondary section. */ seg_die = new_die (DW_TAG_subprogram, @@ -19276,30 +19257,18 @@ gen_subprogram_die (tree decl, dw_die_re add_linkage_name (seg_die, decl); } - gcc_assert (name!=NULL); + gcc_assert (name != NULL); add_pure_or_virtual_attribute (seg_die, decl); if (DECL_ARTIFICIAL (decl)) add_AT_flag (seg_die, DW_AT_artificial, 1); - if (fde->in_std_section) - { - name = concat ("__cold_sect_of_", name, NULL); - add_AT_lbl_id (seg_die, DW_AT_low_pc, - fde->dw_fde_unlikely_section_label); - add_AT_lbl_id (seg_die, DW_AT_high_pc, - fde->dw_fde_unlikely_section_end_label); - } - else - { - name = concat ("__hot_sect_of_", name, NULL); - add_AT_lbl_id (seg_die, DW_AT_low_pc, - fde->dw_fde_hot_section_label); - add_AT_lbl_id (seg_die, DW_AT_high_pc, - fde->dw_fde_hot_section_end_label); - } + name = concat ("__second_sect_of_", name, NULL); + add_AT_lbl_id (seg_die, DW_AT_low_pc, + fde->dw_fde_second_begin); + add_AT_lbl_id (seg_die, DW_AT_high_pc, + fde->dw_fde_second_end); add_name_attribute (seg_die, name); add_pubname_string (name, seg_die); - add_arange (decl, seg_die); } } else @@ -19307,7 +19276,6 @@ gen_subprogram_die (tree decl, dw_die_re add_AT_lbl_id (subr_die, DW_AT_low_pc, fde->dw_fde_begin); add_AT_lbl_id (subr_die, DW_AT_high_pc, fde->dw_fde_end); add_pubname (decl, subr_die); - add_arange (decl, subr_die); } } @@ -22034,6 +22002,29 @@ dwarf2out_var_location (rtx loc_note) last_in_cold_section_p = in_cold_section_p; } +/* Note in one location list that text section has changed. */ + +static int +var_location_switch_text_section_1 (void **slot, void *data ATTRIBUTE_UNUSED) +{ + var_loc_list *list = (var_loc_list *) *slot; + if (list->first) + list->last_before_switch + = list->last->next ? list->last->next : list->last; + return 1; +} + +/* Note in all location lists that text section has changed. */ + +static void +var_location_switch_text_section (void) +{ + if (decl_loc_table == NULL) + return; + + htab_traverse (decl_loc_table, var_location_switch_text_section_1, NULL); +} + /* We need to reset the locations at the beginning of each function. We can't do this in the end_function hook, because the declarations that use the locations won't have been output when @@ -22044,7 +22035,7 @@ dwarf2out_begin_function (tree fun) { if (function_section (fun) != text_section) have_multiple_function_sections = true; - else if (flag_reorder_blocks_and_partition && !cold_text_section) + if (flag_reorder_blocks_and_partition && !cold_text_section) { gcc_assert (current_function_decl == fun); cold_text_section = unlikely_text_section (); @@ -22754,11 +22745,9 @@ prune_unused_types (void) } /* Also set the mark on nodes referenced from the - pubname_table or arange_table. */ + pubname_table. */ FOR_EACH_VEC_ELT (pubname_entry, pubname_table, i, pub) prune_unused_types_mark (pub->die, 1); - for (i = 0; i < arange_table_in_use; i++) - prune_unused_types_mark (arange_table[i], 1); /* Get rid of nodes that aren't marked; and update the string counts. */ if (debug_str_hash && debug_str_hash_forced) @@ -23556,7 +23545,7 @@ dwarf2out_finish (const char *filename) if (text_section_used) add_ranges_by_labels (comp_unit_die (), text_section_label, text_end_label, &range_list_added); - if (flag_reorder_blocks_and_partition && cold_text_section_used) + if (cold_text_section_used) add_ranges_by_labels (comp_unit_die (), cold_text_section_label, cold_end_label, &range_list_added); @@ -23564,22 +23553,12 @@ dwarf2out_finish (const char *filename) { dw_fde_ref fde = &fde_table[fde_idx]; - if (fde->dw_fde_switched_sections) - { - if (!fde->in_std_section) - add_ranges_by_labels (comp_unit_die (), - fde->dw_fde_hot_section_label, - fde->dw_fde_hot_section_end_label, - &range_list_added); - if (!fde->cold_in_std_section) - add_ranges_by_labels (comp_unit_die (), - fde->dw_fde_unlikely_section_label, - fde->dw_fde_unlikely_section_end_label, - &range_list_added); - } - else if (!fde->in_std_section) + if (!fde->in_std_section) add_ranges_by_labels (comp_unit_die (), fde->dw_fde_begin, fde->dw_fde_end, &range_list_added); + if (fde->dw_fde_switched_sections && !fde->second_in_std_section) + add_ranges_by_labels (comp_unit_die (), fde->dw_fde_second_begin, + fde->dw_fde_second_end, &range_list_added); } if (range_list_added) @@ -23679,13 +23658,21 @@ dwarf2out_finish (const char *filename) } } - /* Output the address range information. We only put functions in the arange - table, so don't write it out if we don't have any. */ - if ((text_section_used || cold_text_section_used || arange_table_in_use) - && info_section_emitted) - { - switch_to_section (debug_aranges_section); - output_aranges (); + /* Output the address range information. We only put functions in the + arange table, so don't write it out if we don't have any. */ + if (info_section_emitted) + { + unsigned long aranges_length = size_of_aranges (); + + /* Empty .debug_aranges would contain just header and + terminating 0,0. */ + if (aranges_length + != (unsigned long) (DWARF_ARANGES_HEADER_SIZE + + 2 * DWARF2_ADDR_SIZE)) + { + switch_to_section (debug_aranges_section); + output_aranges (aranges_length); + } } /* Output ranges section if necessary. */ Jakub