summaryrefslogtreecommitdiffstats
path: root/gcc/varasm.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r--gcc/varasm.c71
1 files changed, 63 insertions, 8 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 707ad4bbe65..c35c9b7773e 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -49,6 +49,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "debug.h"
#include "target.h"
#include "cgraph.h"
+#include "cfglayout.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data
@@ -100,6 +101,14 @@ int size_directive_output;
tree last_assemble_variable_decl;
+/* The following global variable indicates if the section label for the
+ "cold" section of code has been output yet to the assembler. The
+ label is useful when running gdb. This is part of the optimization that
+ partitions hot and cold basic blocks into separate sections of the .o
+ file. */
+
+bool unlikely_section_label_printed = false;
+
/* RTX_UNCHANGING_P in a MEM can mean it is stored into, for initialization.
So giving constant the alias set for the type will allow such
initializations to appear to conflict with the load of the constant. We
@@ -145,7 +154,8 @@ static bool asm_emit_uninitialised (tree, const char*,
unsigned HOST_WIDE_INT);
static void mark_weak (tree);
-enum in_section { no_section, in_text, in_data, in_named
+enum in_section { no_section, in_text, in_unlikely_executed_text, in_data,
+ in_named
#ifdef BSS_SECTION_ASM_OP
, in_bss
#endif
@@ -198,7 +208,34 @@ text_section (void)
if (in_section != in_text)
{
in_section = in_text;
- fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
+ fprintf (asm_out_file, SECTION_FORMAT_STRING, NORMAL_TEXT_SECTION_NAME);
+ }
+}
+
+/* Tell assembler to switch to unlikely-to-be-executed text section. */
+
+void
+unlikely_text_section (void)
+{
+ if ((in_section != in_unlikely_executed_text)
+ && (in_section != in_named
+ || strcmp (in_named_name, UNLIKELY_EXECUTED_TEXT_SECTION_NAME) != 0))
+ {
+#ifdef TARGET_ASM_NAMED_SECTION
+
+ named_section (NULL_TREE, UNLIKELY_EXECUTED_TEXT_SECTION_NAME, 0);
+
+#else
+ in_section = in_unlikely_executed_text;
+ fprintf (asm_out_file, SECTION_FORMAT_STRING,
+ UNLIKELY_EXECUTED_TEXT_SECTION_NAME);
+#endif /* ifdef TARGET_ASM_NAMED_SECTION */
+ if (!unlikely_section_label_printed)
+ {
+ fprintf (asm_out_file, "__%s_unlikely_section:\n",
+ current_function_name ());
+ unlikely_section_label_printed = true;
+ }
}
}
@@ -244,6 +281,14 @@ in_text_section (void)
return in_section == in_text;
}
+/* Determine if we're in the unlikely-to-be-executed text section. */
+
+int
+in_unlikely_text_section (void)
+{
+ return in_section == in_unlikely_executed_text;
+}
+
/* Determine if we're in the data section. */
int
@@ -483,11 +528,16 @@ asm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
void
function_section (tree decl)
{
- if (decl != NULL_TREE
- && DECL_SECTION_NAME (decl) != NULL_TREE)
- named_section (decl, (char *) 0, 0);
+ if (scan_ahead_for_unlikely_executed_note (get_insns()))
+ unlikely_text_section ();
else
- text_section ();
+ {
+ if (decl != NULL_TREE
+ && DECL_SECTION_NAME (decl) != NULL_TREE)
+ named_section (decl, (char *) 0, 0);
+ else
+ text_section ();
+ }
}
/* Switch to section for variable DECL. RELOC is the same as the
@@ -1030,6 +1080,8 @@ assemble_start_function (tree decl, const char *fnname)
{
int align;
+ unlikely_section_label_printed = false;
+
/* The following code does not need preprocessing in the assembler. */
app_disable ();
@@ -1117,7 +1169,8 @@ assemble_zeros (unsigned HOST_WIDE_INT size)
#ifdef ASM_NO_SKIP_IN_TEXT
/* The `space' pseudo in the text section outputs nop insns rather than 0s,
so we must output 0s explicitly in the text section. */
- if (ASM_NO_SKIP_IN_TEXT && in_text_section ())
+ if ((ASM_NO_SKIP_IN_TEXT && in_text_section ())
+ || (ASM_NO_SKIP_IN_TEXT && in_unlikely_text_section ()))
{
unsigned HOST_WIDE_INT i;
for (i = 0; i < size; i++)
@@ -1479,7 +1532,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
variable_section (decl, reloc);
/* dbxout.c needs to know this. */
- if (in_text_section ())
+ if (in_text_section () || in_unlikely_text_section ())
DECL_IN_TEXT_SECTION (decl) = 1;
/* Output the alignment of this data. */
@@ -4328,6 +4381,8 @@ 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 (strcmp (name, UNLIKELY_EXECUTED_TEXT_SECTION_NAME) == 0)
+ flags = SECTION_CODE;
else
flags = SECTION_WRITE;
OpenPOWER on IntegriCloud