diff options
author | Caroline Tice <ctice@apple.com> | 2005-04-27 21:35:20 +0000 |
---|---|---|
committer | Caroline Tice <ctice@gcc.gnu.org> | 2005-04-27 14:35:20 -0700 |
commit | c7466deed4c713f843bf5256ffddbeca135d1371 (patch) | |
tree | 25224a7ffa0ad51eb003a772afe847c2781c56d4 | |
parent | 32cf6a3bfe9f7512312a377648f13a437bb1a0c7 (diff) | |
download | gcc-c7466deed4c713f843bf5256ffddbeca135d1371.zip gcc-c7466deed4c713f843bf5256ffddbeca135d1371.tar.gz gcc-c7466deed4c713f843bf5256ffddbeca135d1371.tar.bz2 |
Correct fixes for various hot/cold partitioning concerns.
2005-04-27 Caroline Tice <ctice@apple.com>
* bb-reorder.c (find_rarely_executed_basic_blocks_and_crossing_edges):
Remove targetm.have_named_sections test.
(fix_edges_for_rarely_executed_code): Likewise.
(insert_section_boundary_note): Likewise.
(reorder_basic_blocks): Check partitioning flag before calling
verify_hot_cold_block_grouping.
* dbxout.c (dbxout_function_end): Get hot/cold section labels from
the function struct rather than global variables.
* dwarf2out.c (COLD_TEXT_SECTION_LABEL): New macro.
(COLD_END_LABEL): Likewise
(cold_text_section_label): New static global variable.
(cold_end_label): Likewise.
(dwarf2out_switch_text_section): Get hot/cold section labels from
the function struct rather than global variables; test to make sure
cfun is defined.
(output_aranges): Use cold_text_section_label and cold_end_label;
check partitioning flag before putting out delta.
(output_ranges): Remove incorrect code attempting to use
hot/cold labels.
(output_line_info): Get cold section label from function struct; test
to make sure cfun is defined.
(add_location_or_const_value_attribute): Likewise.
(dwarf2out_var_location): Likewise.
(dwarf2out_init): Generate cold_text_section_label and cold_end_label;
write out cold_text_section_label if partition flag is set.
(dwarf2out_finish): Write out cold_end_label if partition flag is set;
* function.h (struct function): Add new fields to point to hot/cold
section labels: hot_section_label, cold_section_label,
hot_section_end_label and cold_section_end_label; also add new field
for cold text section name, unlikely_text_section_name.
* opts.c (decode_options): Turn off partitioning flag if
!targetm.have_named_sections.
* output.h (hot_section_label): Remove.
(hot_section_end_label): Remove.
(cold_section_end_label): Remove.
(unlikely_section_label): Remove.
(unlikely_text_section_name): Remove.
* passes.c (rest_of_handle_final): Remove extra blank line.
* varasm.c (unlikely_section_label): Remove.
(hot_section_label): Remove.
(hot_section_end_label): Remove.
(cold_section_end_label): Remove.
(unlikely_text_section_name): Remove.
(initialize_cold_section_name): Modify to call
targetm.strip_name_encoding; to store cold section name in current
function struct, if it exists; and to only use the decl_section_name
if flag_named_sections is true.
(unlikely_text_section): Modify to get section name out of current
function struct, if there is one; otherwise build it from
UNLIKELY_EXECUTED_TEXT_SECTION_NAME.
(in_unlikely_text_section): Likewise.
(named_section): Modify to get/put cold section name in current function
struct, if there is one.
(function_section): Change 'bool unlikely' to 'int reloc'; check
targetm.have_named_sections before calling named_section.
(current_function_section): Likewise.
(assemble_start_function): Modify to get/put unlikely_text_section_name
in current function struct; modify to get hot/cold section labels
from function struct; initialize labels using
ASM_GENERATE_INTERNAL_LABEL;
test partitioning flag before writing out hot section label.
(assemble_end_function): Test partitioning flag before writing out
hot/cold section labels.
(default_section_type_flags_1): Get cold text section name from
function struct if there is one; Set flags correctly for
cold text section if there is not a current function struct.
From-SVN: r98885
-rw-r--r-- | gcc/ChangeLog | 69 | ||||
-rw-r--r-- | gcc/bb-reorder.c | 87 | ||||
-rw-r--r-- | gcc/dbxout.c | 7 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 103 | ||||
-rw-r--r-- | gcc/function.h | 14 | ||||
-rw-r--r-- | gcc/opts.c | 9 | ||||
-rw-r--r-- | gcc/output.h | 5 | ||||
-rw-r--r-- | gcc/passes.c | 1 | ||||
-rw-r--r-- | gcc/varasm.c | 201 |
9 files changed, 302 insertions, 194 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f9e205a..947e032 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,72 @@ +2005-04-27 Caroline Tice <ctice@apple.com> + + * bb-reorder.c (find_rarely_executed_basic_blocks_and_crossing_edges): + Remove targetm.have_named_sections test. + (fix_edges_for_rarely_executed_code): Likewise. + (insert_section_boundary_note): Likewise. + (reorder_basic_blocks): Check partitioning flag before calling + verify_hot_cold_block_grouping. + * dbxout.c (dbxout_function_end): Get hot/cold section labels from + the function struct rather than global variables. + * dwarf2out.c (COLD_TEXT_SECTION_LABEL): New macro. + (COLD_END_LABEL): Likewise + (cold_text_section_label): New static global variable. + (cold_end_label): Likewise. + (dwarf2out_switch_text_section): Get hot/cold section labels from + the function struct rather than global variables; test to make sure + cfun is defined. + (output_aranges): Use cold_text_section_label and cold_end_label; + check partitioning flag before putting out delta. + (output_ranges): Remove incorrect code attempting to use + hot/cold labels. + (output_line_info): Get cold section label from function struct; test + to make sure cfun is defined. + (add_location_or_const_value_attribute): Likewise. + (dwarf2out_var_location): Likewise. + (dwarf2out_init): Generate cold_text_section_label and cold_end_label; + write out cold_text_section_label if partition flag is set. + (dwarf2out_finish): Write out cold_end_label if partition flag is set; + * function.h (struct function): Add new fields to point to hot/cold + section labels: hot_section_label, cold_section_label, + hot_section_end_label and cold_section_end_label; also add new field + for cold text section name, unlikely_text_section_name. + * opts.c (decode_options): Turn off partitioning flag if + !targetm.have_named_sections. + * output.h (hot_section_label): Remove. + (hot_section_end_label): Remove. + (cold_section_end_label): Remove. + (unlikely_section_label): Remove. + (unlikely_text_section_name): Remove. + * passes.c (rest_of_handle_final): Remove extra blank line. + * varasm.c (unlikely_section_label): Remove. + (hot_section_label): Remove. + (hot_section_end_label): Remove. + (cold_section_end_label): Remove. + (unlikely_text_section_name): Remove. + (initialize_cold_section_name): Modify to call + targetm.strip_name_encoding; to store cold section name in current + function struct, if it exists; and to only use the decl_section_name + if flag_named_sections is true. + (unlikely_text_section): Modify to get section name out of current + function struct, if there is one; otherwise build it from + UNLIKELY_EXECUTED_TEXT_SECTION_NAME. + (in_unlikely_text_section): Likewise. + (named_section): Modify to get/put cold section name in current function + struct, if there is one. + (function_section): Change 'bool unlikely' to 'int reloc'; check + targetm.have_named_sections before calling named_section. + (current_function_section): Likewise. + (assemble_start_function): Modify to get/put unlikely_text_section_name + in current function struct; modify to get hot/cold section labels + from function struct; initialize labels using + ASM_GENERATE_INTERNAL_LABEL; + test partitioning flag before writing out hot section label. + (assemble_end_function): Test partitioning flag before writing out + hot/cold section labels. + (default_section_type_flags_1): Get cold text section name from + function struct if there is one; Set flags correctly for + cold text section if there is not a current function struct. + 2005-04-27 Richard Guenther <rguenth@gcc.gnu.org> * tree-ssa-propagate.c (set_rhs): Revert last change. diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c index cc0844e..cbb4932 100644 --- a/gcc/bb-reorder.c +++ b/gcc/bb-reorder.c @@ -1237,27 +1237,24 @@ find_rarely_executed_basic_blocks_and_crossing_edges (edge *crossing_edges, /* Mark every edge that crosses between sections. */ i = 0; - if (targetm.have_named_sections) + FOR_EACH_BB (bb) + FOR_EACH_EDGE (e, ei, bb->succs) { - FOR_EACH_BB (bb) - FOR_EACH_EDGE (e, ei, bb->succs) - { - if (e->src != ENTRY_BLOCK_PTR - && e->dest != EXIT_BLOCK_PTR - && BB_PARTITION (e->src) != BB_PARTITION (e->dest)) - { - e->flags |= EDGE_CROSSING; - if (i == *max_idx) - { - *max_idx *= 2; - crossing_edges = xrealloc (crossing_edges, - (*max_idx) * sizeof (edge)); - } - crossing_edges[i++] = e; - } - else - e->flags &= ~EDGE_CROSSING; - } + if (e->src != ENTRY_BLOCK_PTR + && e->dest != EXIT_BLOCK_PTR + && BB_PARTITION (e->src) != BB_PARTITION (e->dest)) + { + e->flags |= EDGE_CROSSING; + if (i == *max_idx) + { + *max_idx *= 2; + crossing_edges = xrealloc (crossing_edges, + (*max_idx) * sizeof (edge)); + } + crossing_edges[i++] = e; + } + else + e->flags &= ~EDGE_CROSSING; } *n_crossing_edges = i; } @@ -1821,36 +1818,26 @@ fix_edges_for_rarely_executed_code (edge *crossing_edges, fix_up_fall_thru_edges (); - /* Only do the parts necessary for writing separate sections if - the target architecture has the ability to write separate sections - (i.e. it has named sections). Otherwise, the hot/cold partitioning - information will be used when reordering blocks to try to put all - the hot blocks together, then all the cold blocks, but no actual - section partitioning will be done. */ - - if (targetm.have_named_sections) - { - /* If the architecture does not have conditional branches that can - span all of memory, convert crossing conditional branches into - crossing unconditional branches. */ + /* If the architecture does not have conditional branches that can + span all of memory, convert crossing conditional branches into + crossing unconditional branches. */ - if (!HAS_LONG_COND_BRANCH) - fix_crossing_conditional_branches (); + if (!HAS_LONG_COND_BRANCH) + fix_crossing_conditional_branches (); - /* If the architecture does not have unconditional branches that - can span all of memory, convert crossing unconditional branches - into indirect jumps. Since adding an indirect jump also adds - a new register usage, update the register usage information as - well. */ - - if (!HAS_LONG_UNCOND_BRANCH) - { - fix_crossing_unconditional_branches (); - reg_scan (get_insns(), max_reg_num ()); - } - - add_reg_crossing_jump_notes (); + /* If the architecture does not have unconditional branches that + can span all of memory, convert crossing unconditional branches + into indirect jumps. Since adding an indirect jump also adds + a new register usage, update the register usage information as + well. */ + + if (!HAS_LONG_UNCOND_BRANCH) + { + fix_crossing_unconditional_branches (); + reg_scan (get_insns(), max_reg_num ()); } + + add_reg_crossing_jump_notes (); } /* Verify, in the basic block chain, that there is at most one switch @@ -1942,7 +1929,8 @@ reorder_basic_blocks (unsigned int flags) dump_flow_info (dump_file); cfg_layout_finalize (); - verify_hot_cold_block_grouping (); + if (flag_reorder_blocks_and_partition) + verify_hot_cold_block_grouping (); timevar_pop (TV_REORDER_BLOCKS); } @@ -1962,8 +1950,7 @@ insert_section_boundary_note (void) rtx new_note; int first_partition = 0; - if (flag_reorder_blocks_and_partition - && targetm.have_named_sections) + if (flag_reorder_blocks_and_partition) FOR_EACH_BB (bb) { if (!first_partition) diff --git a/gcc/dbxout.c b/gcc/dbxout.c index 586ed87..e25dd3c 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -939,10 +939,11 @@ dbxout_function_end (tree decl) if (flag_reorder_blocks_and_partition) { dbxout_begin_empty_stabs (N_FUN); - dbxout_stab_value_label_diff (hot_section_end_label, hot_section_label); + dbxout_stab_value_label_diff (cfun->hot_section_end_label, + cfun->hot_section_label); dbxout_begin_empty_stabs (N_FUN); - dbxout_stab_value_label_diff (cold_section_end_label, - unlikely_section_label); + dbxout_stab_value_label_diff (cfun->cold_section_end_label, + cfun->cold_section_label); } else { diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index a1ff63f..d44822c 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -4122,6 +4122,9 @@ static int maybe_emit_file (int); #ifndef TEXT_SECTION_LABEL #define TEXT_SECTION_LABEL "Ltext" #endif +#ifndef COLD_TEXT_SECTION_LABEL +#define COLD_TEXT_SECTION_LABEL "Ltext_cold" +#endif #ifndef DEBUG_LINE_SECTION_LABEL #define DEBUG_LINE_SECTION_LABEL "Ldebug_line" #endif @@ -4149,6 +4152,8 @@ static int maybe_emit_file (int); static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char text_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; +static char cold_text_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; +static char cold_end_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char abbrev_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char debug_info_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char debug_line_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; @@ -4159,6 +4164,9 @@ static char ranges_section_label[2 * MAX_ARTIFICIAL_LABEL_BYTES]; #ifndef TEXT_END_LABEL #define TEXT_END_LABEL "Letext" #endif +#ifndef COLD_END_LABEL +#define COLD_END_LABEL "Letext_cold" +#endif #ifndef BLOCK_BEGIN_LABEL #define BLOCK_BEGIN_LABEL "LBB" #endif @@ -6800,12 +6808,15 @@ dwarf2out_switch_text_section (void) { dw_fde_ref fde; + if (!cfun) + internal_error ("Attempt to switch text sections without any code."); + fde = &fde_table[fde_table_in_use - 1]; fde->dw_fde_switched_sections = true; - fde->dw_fde_hot_section_label = xstrdup (hot_section_label); - fde->dw_fde_hot_section_end_label = xstrdup (hot_section_end_label); - fde->dw_fde_unlikely_section_label = xstrdup (unlikely_section_label); - fde->dw_fde_unlikely_section_end_label = xstrdup (cold_section_end_label); + fde->dw_fde_hot_section_label = cfun->hot_section_label; + fde->dw_fde_hot_section_end_label = cfun->hot_section_end_label; + fde->dw_fde_unlikely_section_label = cfun->cold_section_label; + fde->dw_fde_unlikely_section_end_label = cfun->cold_section_end_label; separate_line_info_table_in_use++; } @@ -7235,14 +7246,15 @@ output_aranges (void) } dw2_asm_output_addr (DWARF2_ADDR_SIZE, text_section_label, "Address"); - if (last_text_section == in_unlikely_executed_text - || (last_text_section == in_named - && last_text_section_name == unlikely_text_section_name)) - dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label, - unlikely_section_label, "Length"); - else - dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label, - text_section_label, "Length"); + dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label, + text_section_label, "Length"); + if (flag_reorder_blocks_and_partition) + { + dw2_asm_output_addr (DWARF2_ADDR_SIZE, cold_text_section_label, + "Address"); + dw2_asm_output_delta (DWARF2_ADDR_SIZE, cold_end_label, + cold_text_section_label, "Length"); + } for (i = 0; i < arange_table_in_use; i++) { @@ -7332,24 +7344,11 @@ output_ranges (void) base of the text section. */ if (separate_line_info_table_in_use == 0) { - if (last_text_section == in_unlikely_executed_text - || (last_text_section == in_named - && last_text_section_name == unlikely_text_section_name)) - { - dw2_asm_output_delta (DWARF2_ADDR_SIZE, blabel, - unlikely_section_label, - fmt, i * 2 * DWARF2_ADDR_SIZE); - dw2_asm_output_delta (DWARF2_ADDR_SIZE, elabel, - unlikely_section_label, NULL); - } - else - { - dw2_asm_output_delta (DWARF2_ADDR_SIZE, blabel, - text_section_label, - fmt, i * 2 * DWARF2_ADDR_SIZE); - dw2_asm_output_delta (DWARF2_ADDR_SIZE, elabel, - text_section_label, NULL); - } + dw2_asm_output_delta (DWARF2_ADDR_SIZE, blabel, + text_section_label, + fmt, i * 2 * DWARF2_ADDR_SIZE); + dw2_asm_output_delta (DWARF2_ADDR_SIZE, elabel, + text_section_label, NULL); } /* Otherwise, we add a DW_AT_entry_pc attribute to force the @@ -7734,11 +7733,12 @@ output_line_info (void) a series of state machine operations. */ current_file = 1; current_line = 1; - - if (last_text_section == in_unlikely_executed_text - || (last_text_section == in_named - && last_text_section_name == unlikely_text_section_name)) - strcpy (prev_line_label, unlikely_section_label); + + if (cfun + && (last_text_section == in_unlikely_executed_text + || (last_text_section == in_named + && last_text_section_name == cfun->unlikely_text_section_name))) + strcpy (prev_line_label, cfun->cold_section_label); else strcpy (prev_line_label, text_section_label); for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index) @@ -10112,7 +10112,6 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, dw_loc_list_ref list; rtx varloc; - /* We need to figure out what section we should use as the base for the address ranges where a given location is valid. 1. If this particular DECL has a section associated with it, @@ -10134,10 +10133,12 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, tree sectree = DECL_SECTION_NAME (current_function_decl); secname = TREE_STRING_POINTER (sectree); } - else if (last_text_section == in_unlikely_executed_text - || (last_text_section == in_named - && last_text_section_name == unlikely_text_section_name)) - secname = unlikely_section_label; + else if (cfun + && (last_text_section == in_unlikely_executed_text + || (last_text_section == in_named + && last_text_section_name == + cfun->unlikely_text_section_name))) + secname = cfun->cold_section_label; else secname = text_section_label; @@ -13260,10 +13261,11 @@ dwarf2out_var_location (rtx loc_note) newloc->var_loc_note = loc_note; newloc->next = NULL; - if (last_text_section == in_unlikely_executed_text - || (last_text_section == in_named - && last_text_section_name == unlikely_text_section_name)) - newloc->section_label = unlikely_section_label; + if (cfun + && (last_text_section == in_unlikely_executed_text + || (last_text_section == in_named + && last_text_section_name == cfun->unlikely_text_section_name))) + newloc->section_label = cfun->cold_section_label; else newloc->section_label = text_section_label; @@ -13501,6 +13503,9 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED) ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label, DEBUG_ABBREV_SECTION_LABEL, 0); ASM_GENERATE_INTERNAL_LABEL (text_section_label, TEXT_SECTION_LABEL, 0); + ASM_GENERATE_INTERNAL_LABEL (cold_text_section_label, + COLD_TEXT_SECTION_LABEL, 0); + ASM_GENERATE_INTERNAL_LABEL (cold_end_label, COLD_END_LABEL, 0); ASM_GENERATE_INTERNAL_LABEL (debug_info_section_label, DEBUG_INFO_SECTION_LABEL, 0); @@ -13525,6 +13530,11 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED) text_section (); ASM_OUTPUT_LABEL (asm_out_file, text_section_label); + if (flag_reorder_blocks_and_partition) + { + unlikely_text_section (); + ASM_OUTPUT_LABEL (asm_out_file, cold_text_section_label); + } } /* A helper function for dwarf2out_finish called through @@ -13856,6 +13866,11 @@ dwarf2out_finish (const char *filename) /* Output a terminator label for the .text section. */ text_section (); targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0); + if (flag_reorder_blocks_and_partition) + { + unlikely_text_section (); + targetm.asm_out.internal_label (asm_out_file, COLD_END_LABEL, 0); + } /* Output the source line correspondence table. We must do this even if there is no line information. Otherwise, on an empty diff --git a/gcc/function.h b/gcc/function.h index f12452d..4f6181a 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -352,6 +352,20 @@ struct function GTY(()) /* The variables unexpanded so far. */ tree unexpanded_var_list; + /* Assembly labels for the hot and cold text sections, to + be used by debugger functions for determining the size of text + sections. */ + + const char * hot_section_label; + const char * cold_section_label; + const char * hot_section_end_label; + const char * cold_section_end_label; + + /* String to be used for name of cold text sections, via + targetm.asm_out.named_section. */ + + const char *unlikely_text_section_name; + /* Collected bit flags. */ /* Nonzero if function being compiled needs to be given an address @@ -678,6 +678,15 @@ decode_options (unsigned int argc, const char **argv) flag_reorder_blocks_and_partition = 0; flag_reorder_blocks = 1; } + + if (flag_reorder_blocks_and_partition + && !targetm.have_named_sections) + { + inform + ("-freorder-blocks-and-partition does not work on this architecture."); + flag_reorder_blocks_and_partition = 0; + flag_reorder_blocks = 1; + } } /* Handle target- and language-independent options. Return zero to diff --git a/gcc/output.h b/gcc/output.h index d7b8139..7c7c1d8 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -453,11 +453,6 @@ enum in_section { no_section, in_text, in_unlikely_executed_text, in_data, #endif }; -extern char *unlikely_section_label; -extern char *hot_section_label; -extern char *hot_section_end_label; -extern char *cold_section_end_label; -extern char *unlikely_text_section_name; extern const char *last_text_section_name; extern enum in_section last_text_section; extern bool first_function_block_is_cold; diff --git a/gcc/passes.c b/gcc/passes.c index 7f1a9b3..b51d7c7 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -328,7 +328,6 @@ rest_of_handle_final (void) timevar_push (TV_SYMOUT); (*debug_hooks->function_decl) (current_function_decl); - timevar_pop (TV_SYMOUT); ggc_collect (); diff --git a/gcc/varasm.c b/gcc/varasm.c index 78de840..f0799e1 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -101,40 +101,6 @@ tree last_assemble_variable_decl; bool first_function_block_is_cold; -/* The following global variable indicates the label name to be put at - the start of the first cold section within each function, when - partitioning basic blocks into hot and cold sections. Used for - debug info. */ - -char *unlikely_section_label; - -/* The following global variable indicates the label name to be put at - the start of the first hot section within each function, when - partitioning basic blocks into hot and cold sections. Used for - debug info. */ - -char *hot_section_label; - -/* The following global variable indicates the label name to be put at - the end of the last hot section within each function, when - partitioning basic blocks into hot and cold sections. Used for - debug info. */ - -char *hot_section_end_label; - -/* The following global variable indicates the label name to be put at - the end of the last cold section within each function, when - partitioning basic blocks into hot and cold sections. Used for - debug info.*/ - -char *cold_section_end_label; - -/* The following global variable indicates the section name to be used - for the current cold section, when partitioning hot and cold basic - blocks into separate sections. */ - -char *unlikely_text_section_name; - /* We give all constants their own alias set. Perhaps redundant with MEM_READONLY_P, but pre-dates it. */ @@ -211,28 +177,36 @@ static void initialize_cold_section_name (void) { const char *name; + const char *stripped_name; + char *buffer; int len; - if (! unlikely_text_section_name) + if (cfun + && current_function_decl) { - if (DECL_SECTION_NAME (current_function_decl) - && (strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME - (current_function_decl)), - HOT_TEXT_SECTION_NAME) != 0) - && (strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME - (current_function_decl)), - UNLIKELY_EXECUTED_TEXT_SECTION_NAME) != 0)) + if (!cfun->unlikely_text_section_name) { - name = TREE_STRING_POINTER (DECL_SECTION_NAME - (current_function_decl)); - len = strlen (name); - unlikely_text_section_name = xmalloc (len + 10); - sprintf (unlikely_text_section_name, "%s%s", name, "_unlikely"); + if (flag_function_sections + && DECL_SECTION_NAME (current_function_decl)) + { + name = xstrdup (TREE_STRING_POINTER (DECL_SECTION_NAME + (current_function_decl))); + stripped_name = targetm.strip_name_encoding (name); + len = strlen (stripped_name); + buffer = (char *) xmalloc (len + 10); + sprintf (buffer, "%s%s", stripped_name, "_unlikely"); + cfun->unlikely_text_section_name = ggc_strdup (buffer); + free (buffer); + free ((char *) name); + } + else + cfun->unlikely_text_section_name = + UNLIKELY_EXECUTED_TEXT_SECTION_NAME; } - else - unlikely_text_section_name = - xstrdup (UNLIKELY_EXECUTED_TEXT_SECTION_NAME); } + else + internal_error + ("initialize_cold_section_name called without valid current_function_decl."); } /* Tell assembler to switch to text section. */ @@ -253,14 +227,23 @@ text_section (void) void unlikely_text_section (void) { - if (! unlikely_text_section_name) - initialize_cold_section_name (); + if (cfun) + { + if (!cfun->unlikely_text_section_name) + initialize_cold_section_name (); - if ((in_section != in_unlikely_executed_text) - && (in_section != in_named - || strcmp (in_named_name, unlikely_text_section_name) != 0)) + if ((in_section != in_unlikely_executed_text) + && (in_section != in_named + || strcmp (in_named_name, cfun->unlikely_text_section_name) != 0)) + { + named_section (NULL_TREE, cfun->unlikely_text_section_name, 0); + in_section = in_unlikely_executed_text; + last_text_section = in_unlikely_executed_text; + } + } + else { - named_section (NULL_TREE, unlikely_text_section_name, 0); + named_section (NULL_TREE, UNLIKELY_EXECUTED_TEXT_SECTION_NAME, 0); in_section = in_unlikely_executed_text; last_text_section = in_unlikely_executed_text; } @@ -315,10 +298,21 @@ in_unlikely_text_section (void) { bool ret_val; - ret_val = ((in_section == in_unlikely_executed_text) - || (in_section == in_named - && unlikely_text_section_name - && strcmp (in_named_name, unlikely_text_section_name) == 0)); + if (cfun) + { + ret_val = ((in_section == in_unlikely_executed_text) + || (in_section == in_named + && cfun->unlikely_text_section_name + && strcmp (in_named_name, + cfun->unlikely_text_section_name) == 0)); + } + else + { + ret_val = ((in_section == in_unlikely_executed_text) + || (in_section == in_named + && strcmp (in_named_name, + UNLIKELY_EXECUTED_TEXT_SECTION_NAME) == 0)); + } return ret_val; } @@ -463,9 +457,9 @@ named_section (tree decl, const char *name, int reloc) name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); if (strcmp (name, UNLIKELY_EXECUTED_TEXT_SECTION_NAME) == 0 - && !unlikely_text_section_name) - unlikely_text_section_name = - xstrdup (UNLIKELY_EXECUTED_TEXT_SECTION_NAME); + && cfun + && ! cfun->unlikely_text_section_name) + cfun->unlikely_text_section_name = UNLIKELY_EXECUTED_TEXT_SECTION_NAME; flags = targetm.section_type_flags (decl, name, reloc); @@ -574,16 +568,17 @@ asm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED, void function_section (tree decl) { - bool unlikely = false; + int reloc = 0; if (first_function_block_is_cold) - unlikely = true; + reloc = 1; #ifdef USE_SELECT_SECTION_FOR_FUNCTIONS - targetm.asm_out.select_section (decl, unlikely, DECL_ALIGN (decl)); + targetm.asm_out.select_section (decl, reloc, DECL_ALIGN (decl)); #else if (decl != NULL_TREE - && DECL_SECTION_NAME (decl) != NULL_TREE) + && DECL_SECTION_NAME (decl) != NULL_TREE + && targetm.have_named_sections) named_section (decl, (char *) 0, 0); else text_section (); @@ -594,16 +589,20 @@ void current_function_section (tree decl) { #ifdef USE_SELECT_SECTION_FOR_FUNCTIONS - bool unlikely = (in_unlikely_text_section () - || (last_text_section == in_unlikely_executed_text)); - - targetm.asm_out.select_section (decl, unlikely, DECL_ALIGN (decl)); + int reloc = 0; + + if (in_unlikely_text_section () + || last_text_section == in_unlikely_executed_text) + reloc = 1; + + targetm.asm_out.select_section (decl, reloc, DECL_ALIGN (decl)); #else if (last_text_section == in_unlikely_executed_text) unlikely_text_section (); else if (last_text_section == in_text) text_section (); - else if (last_text_section == in_named) + else if (last_text_section == in_named + && targetm.have_named_sections) named_section (NULL_TREE, last_text_section_name, 0); else function_section (decl); @@ -1224,18 +1223,31 @@ void assemble_start_function (tree decl, const char *fnname) { int align; + char tmp_label[100]; bool hot_label_written = false; - unlikely_text_section_name = NULL; - + cfun->unlikely_text_section_name = NULL; + first_function_block_is_cold = false; - hot_section_label = reconcat (hot_section_label, fnname, ".hot_section", NULL); - unlikely_section_label = reconcat (unlikely_section_label, - fnname, ".unlikely_section", NULL); - hot_section_end_label = reconcat (hot_section_end_label, - fnname, ".end", NULL); - cold_section_end_label = reconcat (cold_section_end_label, - fnname, ".end.cold", NULL); + if (flag_reorder_blocks_and_partition) + { + ASM_GENERATE_INTERNAL_LABEL (tmp_label, "HOTB", const_labelno); + cfun->hot_section_label = ggc_strdup (tmp_label); + ASM_GENERATE_INTERNAL_LABEL (tmp_label, "COLDB", const_labelno); + cfun->cold_section_label = ggc_strdup (tmp_label); + ASM_GENERATE_INTERNAL_LABEL (tmp_label, "HOTE", const_labelno); + cfun->hot_section_end_label = ggc_strdup (tmp_label); + ASM_GENERATE_INTERNAL_LABEL (tmp_label, "COLDE", const_labelno); + cfun->cold_section_end_label = ggc_strdup (tmp_label); + const_labelno++; + } + else + { + cfun->hot_section_label = NULL; + cfun->cold_section_label = NULL; + cfun->hot_section_end_label = NULL; + cfun->cold_section_end_label = NULL; + } /* The following code does not need preprocessing in the assembler. */ @@ -1253,7 +1265,7 @@ assemble_start_function (tree decl, const char *fnname) { unlikely_text_section (); assemble_align (FUNCTION_BOUNDARY); - ASM_OUTPUT_LABEL (asm_out_file, unlikely_section_label); + ASM_OUTPUT_LABEL (asm_out_file, cfun->cold_section_label); if (BB_PARTITION (ENTRY_BLOCK_PTR->next_bb) == BB_COLD_PARTITION) { /* Since the function starts with a cold section, we need to @@ -1261,7 +1273,7 @@ assemble_start_function (tree decl, const char *fnname) section label. */ text_section (); assemble_align (FUNCTION_BOUNDARY); - ASM_OUTPUT_LABEL (asm_out_file, hot_section_label); + ASM_OUTPUT_LABEL (asm_out_file, cfun->hot_section_label); hot_label_written = true; first_function_block_is_cold = true; } @@ -1291,8 +1303,8 @@ assemble_start_function (tree decl, const char *fnname) s[i] = (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)))[i]; s[len] = '\0'; - if (unlikely_text_section_name - && (strcmp (s, unlikely_text_section_name) == 0)) + if (cfun->unlikely_text_section_name + && (strcmp (s, cfun->unlikely_text_section_name) == 0)) first_function_block_is_cold = true; } @@ -1304,7 +1316,7 @@ assemble_start_function (tree decl, const char *fnname) function_section (decl); if (flag_reorder_blocks_and_partition && !hot_label_written) - ASM_OUTPUT_LABEL (asm_out_file, hot_section_label); + ASM_OUTPUT_LABEL (asm_out_file, cfun->hot_section_label); /* Tell assembler to move to target machine's alignment for functions. */ align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT); @@ -1366,7 +1378,6 @@ assemble_start_function (tree decl, const char *fnname) void assemble_end_function (tree decl, const char *fnname) { - enum in_section save_text_section; #ifdef ASM_DECLARE_FUNCTION_SIZE ASM_DECLARE_FUNCTION_SIZE (asm_out_file, fnname, decl); #endif @@ -1379,11 +1390,13 @@ assemble_end_function (tree decl, const char *fnname) debug info.) */ if (flag_reorder_blocks_and_partition) { + enum in_section save_text_section; + save_text_section = in_section; unlikely_text_section (); - ASM_OUTPUT_LABEL (asm_out_file, cold_section_end_label); + ASM_OUTPUT_LABEL (asm_out_file, cfun->cold_section_end_label); text_section (); - ASM_OUTPUT_LABEL (asm_out_file, hot_section_end_label); + ASM_OUTPUT_LABEL (asm_out_file, cfun->hot_section_end_label); if (save_text_section == in_unlikely_executed_text) unlikely_text_section (); } @@ -4780,9 +4793,15 @@ default_section_type_flags_1 (tree decl, const char *name, int reloc, flags = SECTION_CODE; else if (decl && decl_readonly_section_1 (decl, reloc, shlib)) flags = 0; - else if (unlikely_text_section_name - && strcmp (name, unlikely_text_section_name) == 0) + else if (current_function_decl + && cfun + && cfun->unlikely_text_section_name + && strcmp (name, cfun->unlikely_text_section_name) == 0) flags = SECTION_CODE; + else if (!decl + && (!current_function_decl || !cfun) + && strcmp (name, UNLIKELY_EXECUTED_TEXT_SECTION_NAME) == 0) + flags = SECTION_CODE; else flags = SECTION_WRITE; |