diff options
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r-- | gcc/varasm.c | 201 |
1 files changed, 110 insertions, 91 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c index 78de840ce56..f0799e1dfc1 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; |