aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/sparc/sysv4.h3
-rw-r--r--gcc/dbxout.c25
-rw-r--r--gcc/flags.h5
-rw-r--r--gcc/toplev.c24
-rw-r--r--gcc/varasm.c26
5 files changed, 81 insertions, 2 deletions
diff --git a/gcc/config/sparc/sysv4.h b/gcc/config/sparc/sysv4.h
index bc27b0c..1c69dd5 100644
--- a/gcc/config/sparc/sysv4.h
+++ b/gcc/config/sparc/sysv4.h
@@ -185,7 +185,8 @@ do { ASM_OUTPUT_ALIGN ((FILE), Pmode == SImode ? 2 : 3); \
#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME) \
do { \
if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \
- fprintf (FILE, ".section\t\"%s\",#alloc,#execinstr\n", (NAME)); \
+ fprintf (FILE, ".section\t\"%s%s\",#alloc,#execinstr\n", \
+ flag_function_sections ? ".text%" : "", (NAME)); \
else if ((DECL) && TREE_READONLY (DECL)) \
fprintf (FILE, ".section\t\"%s\",#alloc\n", (NAME)); \
else \
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index cc6b9ca..9831cdd 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -438,6 +438,27 @@ abspath (rel_filename)
}
#endif /* 0 */
+static int scope_labelno = 0;
+static void
+dbxout_function_end ()
+{
+ char lscope_label_name[100];
+ /* Convert Ltext into the appropriate format for local labels in case
+ the system doesn't insert underscores in front of user generated
+ labels. */
+ ASM_GENERATE_INTERNAL_LABEL (lscope_label_name, "Lscope", scope_labelno);
+ ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Lscope", scope_labelno);
+ scope_labelno++;
+
+ /* By convention, GCC will mark the end of a function with an N_FUN
+ symbol and an empty string. */
+ fprintf (asmfile, "%s \"\",%d,0,0,", ASM_STABS_OP, N_FUN);
+ assemble_name (asmfile, lscope_label_name);
+ fputc ('-', asmfile);
+ assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
+ fprintf (asmfile, "-1\n");
+}
+
/* At the beginning of compilation, start writing the symbol table.
Initialize `typevec' and output the standard data types of C. */
@@ -2670,5 +2691,9 @@ dbxout_function (decl)
#ifdef DBX_OUTPUT_FUNCTION_END
DBX_OUTPUT_FUNCTION_END (asmfile, decl);
#endif
+#ifdef ASM_OUTPUT_SECTION_NAME
+ if (flag_function_sections && use_gnu_debug_info_extensions)
+ dbxout_function_end ();
+#endif
}
#endif /* DBX_DEBUGGING_INFO */
diff --git a/gcc/flags.h b/gcc/flags.h
index ed1cf57..60528ab 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -325,6 +325,11 @@ extern int flag_no_common;
needed for crtstuff.c on other systems. */
extern int flag_inhibit_size_directive;
+/* Nonzero means place each function into its own section on those platforms
+ which support arbitrary section names and unlimited numbers of sections. */
+
+extern int flag_function_sections;
+
/* -fverbose-asm causes extra commentary information to be produced in
the generated assembly code (to make it more readable). This option
is generally only of use to those who actually need to read the
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 4d866cd..2c8f9a2 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -403,6 +403,11 @@ int flag_no_function_cse = 0;
int flag_omit_frame_pointer = 0;
+/* Nonzero means place each function into its own section on those platforms
+ which support arbitrary section names and unlimited numbers of sections. */
+
+int flag_function_sections = 0;
+
/* Nonzero to inhibit use of define_optimization peephole opts. */
int flag_no_peephole = 0;
@@ -564,6 +569,7 @@ struct { char *string; int *variable; int on_value;} f_options[] =
{"fast-math", &flag_fast_math, 1},
{"common", &flag_no_common, 0},
{"inhibit-size-directive", &flag_inhibit_size_directive, 1},
+ {"function-sections", &flag_function_sections, 1},
{"verbose-asm", &flag_verbose_asm, 1},
{"gnu-linker", &flag_gnu_linker, 1},
{"pack-struct", &flag_pack_struct, 1},
@@ -2187,6 +2193,24 @@ compile_file (name)
ASM_IDENTIFY_LANGUAGE (asm_out_file);
#endif
+#ifndef ASM_OUTPUT_SECTION_NAME
+ if (flag_function_sections)
+ {
+ warning ("-ffunction-sections not supported for this target.");
+ flag_function_sections = 0;
+ }
+#endif
+
+ if (flag_function_sections
+ && (profile_flag || profile_block_flag))
+ {
+ warning ("-ffunction-sections disabled; it makes profiling impossible.");
+ flag_function_sections = 0;
+ }
+
+ if (flag_function_sections && write_symbols != NO_DEBUG)
+ warning ("-ffunction-sections may affect debugging on some targets.");
+
if (output_bytecode)
{
if (profile_flag || profile_block_flag)
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 9b83110..cc60f03 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -255,7 +255,8 @@ named_section (decl, name)
if (in_section != in_named || strcmp (name, in_named_name))
{
- in_named_name = name;
+ in_named_name = obstack_alloc (&permanent_obstack, strlen (name) + 1);
+ strcpy (in_named_name, name);
in_section = in_named;
#ifdef ASM_OUTPUT_SECTION_NAME
@@ -349,6 +350,29 @@ void
function_section (decl)
tree decl;
{
+
+#ifdef ASM_OUTPUT_SECTION_NAME
+ /* If we are placing functions into their own sections, and this
+ function doesn't already have a section specified, set it now. */
+ if (flag_function_sections
+ && decl != NULL_TREE
+ && DECL_SECTION_NAME (decl) == NULL_TREE)
+ {
+ int len;
+ char *string;
+
+ len = IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl)) + 1;
+ string = alloca (len);
+ strcpy (string, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
+
+ /* Strip off any encoding in fnname. */
+ STRIP_NAME_ENCODING (string, string);
+
+ /* Set DECL_SECTION_NAME. */
+ DECL_SECTION_NAME (decl) = build_string (len, string);
+ }
+#endif
+
if (decl != NULL_TREE
&& DECL_SECTION_NAME (decl) != NULL_TREE)
named_section (decl, (char *) 0);