This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] SH : Add target specific option -msort-data for SH-ELF target


Hi,

Please find below a patch for SH (ELF) target, which generate separate
sections for variables with different data types. Arrays are also
treated same way. This is done for initialized global variables and read
only (const) data.

This patch will reduce padding (memory gaps) between variables with
different data types. Since characters will be 1 byte aligned, short
integers will be 2 byte aligned and long integers will be 4 byte aligned
and all will be placed in different sections. This will help in reducing
RAM as well as ROM size.

All characters will go in .d_char section, short integers in .d_short
section, long integers in .d_long section, read only characters will go
in .rod_char section, read only short integers will go in .rod_short
section and read only long integers will go in .rod_long section.

The default is not to sort variables as per data type.

We could not build complete tool chain. While building Newlib,
segmentation fault occurred. 
Due to this, executable test cases could not be tested in regression. 
In compiler related test cases, no difference in result is observed with
and without patch.

Custom linker script may need to be modified like following,
.rodata : 
{
 *(.rodata)
 *(.rodata.*)
 *(.rod_char)
 *(.rod_long)
 *(.rod_short)
 _erodata = .;
} > rom

.data : AT (_mdata) { 
_data = .;
*(.data) 
*(.d_char)
*(.d_long)
*(.d_short)
_edata = .; 
} > ram

========================Start Of Patch==================================
ChangeLog
2005-06-15  Anil Paranjpe <anilp1@kpitcummins.com>
	* config/sh/sh.c (sh_select_section): New function.
	* config/sh/elf.h : Define EXTRA_SECTIONS,
EXTRA_SECTION_FUNCTIONS,
	CHAR_DATA_SECTION_FUNCTION, SHORT_DATA_SECTION_FUNCTION,
LONG_DATA_SECTION_FUNCTION,
	CHAR_RODATA_SECTION_FUNCTION, SHORT_RODATA_SECTION_FUNCTION,
LONG_RODATA_SECTION_FUNCTION,
	TARGET_ASM_SELECT_SECTION, CHAR_DATA_SECTION_ASM_OP,
SHORT_DATA_SECTION_ASM_OP,
	LONG_DATA_SECTION_ASM_OP, CHAR_RODATA_SECTION_ASM_OP,
SHORT_RODATA_SECTION_ASM_OP,
	LONG_RODATA_SECTION_ASM_OP.
	* config/sh/sh.opt (TARGET_SWITCHES): Add "sort-data" to create
separate sections
	for variables with different data types.
	* doc/invoke.texi (SH Options): Document "msort-data" option.

========================================================================
--- gcc-4.1-20050611/gcc/config/sh/sh.c.orig	2005-06-13
16:21:11.000000000 +0530
+++ gcc-4.1-20050611/gcc/config/sh/sh.c	2005-06-13 16:32:25.000000000
+0530
@@ -295,6 +295,14 @@ static int sh_arg_partial_bytes (CUMULAT
 			         tree, bool);
 static int sh_dwarf_calling_convention (tree);
 static int hard_regs_intersect_p (HARD_REG_SET *, HARD_REG_SET *);
+static void sh_select_section (tree, int, unsigned HOST_WIDE_INT)
+     ATTRIBUTE_UNUSED;
+void char_data_section(void);
+void short_data_section(void);
+void long_data_section(void);
+void char_rodata_section(void);
+void short_rodata_section(void);
+void long_rodata_section(void);
 
 
 /* Initialize the GCC target structure.  */
@@ -10481,5 +10489,76 @@ enum sh_divide_strategy_e sh_div_strateg
 const char * boardtype = "7750p2";
 const char * osruntime = "bare";
 #endif
+/*
+  This function creates separate sections for variables with different
data types.
+  Arrays are also treated in same way.
+*/
+static void
+sh_select_section (tree decl, int reloc,
+	 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
+{
+  if (TARGET_SORT_DATA)
+  {
+      if (TREE_CODE(TREE_TYPE(decl)) == ARRAY_TYPE && 
+          TYPE_MODE(TREE_TYPE(TREE_TYPE(decl))) == QImode) 
+      {
+	  if(TYPE_READONLY(TREE_TYPE(TREE_TYPE(decl))))
+	  	char_rodata_section ();
+	  else 
+                char_data_section ();
+      }
+      else if (TREE_CODE(TREE_TYPE(decl)) == ARRAY_TYPE && 
+               TYPE_MODE(TREE_TYPE(TREE_TYPE(decl))) == HImode) 
+      {
+	  if(TYPE_READONLY(TREE_TYPE(TREE_TYPE(decl))))
+	  	short_rodata_section ();
+	  else 
+                short_data_section ();
+      }	
+      else if (TREE_CODE(TREE_TYPE(decl)) == ARRAY_TYPE && 
+	       (TYPE_MODE(TREE_TYPE(TREE_TYPE(decl))) == SImode ||
+	        TYPE_MODE(TREE_TYPE(TREE_TYPE(decl))) == DImode) )
+      {
+	  if(TYPE_READONLY(TREE_TYPE(TREE_TYPE(decl))))
+	  	long_rodata_section ();
+	  else 
+                long_data_section ();
+      }
+      else if (TYPE_MODE(TREE_TYPE(decl)) == QImode)
+      {
+      	  if (TYPE_READONLY(TREE_TYPE(decl)))
+      	  	char_rodata_section ();
+          else
+	        char_data_section ();
+      }
+      else if (TYPE_MODE(TREE_TYPE(decl)) == HImode)
+      {
+      	  if (TYPE_READONLY(TREE_TYPE(decl)))
+      	  	short_rodata_section ();
+          else
+	        short_data_section ();
+      }
+      else if (TYPE_MODE(TREE_TYPE(decl)) == SImode ||
+	       TYPE_MODE(TREE_TYPE(decl)) == DImode )
+      {
+      	  if (TYPE_READONLY(TREE_TYPE(decl)))
+      	  	long_rodata_section ();
+          else
+	        long_data_section ();
+      }
+      else
+  	  goto def_sel;
+  }
+ else
+  {
+def_sel:
+#if __ELF__
+           default_elf_select_section (decl, reloc, align);
+#else
+	   default_select_section (decl, reloc, align);
+#endif
+  }
+}
+			
 #include "gt-sh.h"
--- gcc-4.1-20050611/gcc/config/sh/elf.h.orig	2005-06-13
16:37:26.000000000 +0530
+++ gcc-4.1-20050611/gcc/config/sh/elf.h	2005-06-13
16:53:28.000000000 +0530
@@ -41,7 +41,101 @@ Boston, MA 02111-1307, USA.  */
    
 #undef WCHAR_TYPE_SIZE
 #define WCHAR_TYPE_SIZE 32
+#undef  TARGET_ASM_SELECT_SECTION
+#define TARGET_ASM_SELECT_SECTION  sh_select_section
+ 
+#define CHAR_DATA_SECTION_ASM_OP	"\t.section\t.d_char,\"aw\""
+#define SHORT_DATA_SECTION_ASM_OP   	"\t.section\t.d_short,\"aw\""
+#define LONG_DATA_SECTION_ASM_OP        "\t.section\t.d_long,\"aw\""
+#define CHAR_RODATA_SECTION_ASM_OP	"\t.section\t.rod_char,\"ax\""
+#define SHORT_RODATA_SECTION_ASM_OP   	"\t.section\t.rod_short,\"ax\""
+#define LONG_RODATA_SECTION_ASM_OP      "\t.section\t.rod_long,\"ax\""
+
+#define EXTRA_SECTIONS in_char_data, in_short_data, in_long_data,
in_char_rodata, in_short_rodata, in_long_rodata
+
+extern void char_data_section(void);
+extern void short_data_section(void);
+extern void long_data_section(void);
+extern void char_rodata_section(void);
+extern void short_rodata_section(void);
+extern void long_rodata_section(void);
+
+#define EXTRA_SECTION_FUNCTIONS
\
+     CHAR_DATA_SECTION_FUNCTION
\
+     SHORT_DATA_SECTION_FUNCTION
\
+     LONG_DATA_SECTION_FUNCTION
\
+     CHAR_RODATA_SECTION_FUNCTION
\
+     SHORT_RODATA_SECTION_FUNCTION
\
+     LONG_RODATA_SECTION_FUNCTION
+
+
+#define CHAR_DATA_SECTION_FUNCTION
\
+void
\
+char_data_section ()
\
+{
\
+  if (in_section != in_char_data)
\
+    {
\
+      fprintf (asm_out_file, "%s\n", CHAR_DATA_SECTION_ASM_OP);
\
+      in_section = in_char_data;
\
+    }
\
+}
+
+#define SHORT_DATA_SECTION_FUNCTION
\
+void
\
+short_data_section ()
\
+{
\
+  if (in_section != in_short_data)
\
+    {
\
+      fprintf (asm_out_file, "%s\n", SHORT_DATA_SECTION_ASM_OP);
\
+      in_section = in_short_data;
\
+    }
\
+}
+
+#define LONG_DATA_SECTION_FUNCTION
\
+void
\
+long_data_section ()
\
+{
\
+  if (in_section != in_long_data)
\
+    {
\
+      fprintf (asm_out_file, "%s\n", LONG_DATA_SECTION_ASM_OP);
\
+      in_section = in_long_data;
\
+    }
\
+}
+	
+#define CHAR_RODATA_SECTION_FUNCTION
\
+void
\
+char_rodata_section ()
\
+{
\
+  if (in_section != in_char_rodata)
\
+    {
\
+      fprintf (asm_out_file, "%s\n", CHAR_RODATA_SECTION_ASM_OP);
\
+      in_section = in_char_rodata;
\
+    }
\
+}
+
+#define SHORT_RODATA_SECTION_FUNCTION
\
+void
\
+short_rodata_section ()
\
+{
\
+  if (in_section != in_short_rodata)
\
+    {
\
+      fprintf (asm_out_file, "%s\n", SHORT_RODATA_SECTION_ASM_OP);
\
+      in_section = in_short_rodata;
\
+    }
\
+}
+
+#define LONG_RODATA_SECTION_FUNCTION
\
+void
\
+long_rodata_section ()
\
+{
\
+  if (in_section != in_long_rodata)
\
+    {
\
+      fprintf (asm_out_file, "%s\n", LONG_RODATA_SECTION_ASM_OP);
\
+      in_section = in_long_rodata;
\
+    }
\
+}
+

 
 /* The prefix to add to user-visible assembler symbols.  */
 
--- gcc-4.1-20050611/gcc/config/sh/sh.opt.orig	2005-06-13
16:34:46.000000000 +0530
+++ gcc-4.1-20050611/gcc/config/sh/sh.opt	2005-06-13
16:35:19.000000000 +0530
@@ -232,3 +232,7 @@ Cost to assume for a multiply insn
 musermode
 Target Report RejectNegative Mask(USERMODE)
 Generate library function call to invalidate instruction cache entries
after fixing trampoline
+
+msort-data
+Target RejectNegative Mask(SORT_DATA)
+Generate separate sections for variables with different data types
--- gcc-4.1-20050611/gcc/doc/invoke.texi.orig	2005-06-13
18:41:07.000000000 +0530
+++ gcc-4.1-20050611/gcc/doc/invoke.texi	2005-06-13
19:05:02.000000000 +0530
@@ -667,7 +667,7 @@ See RS/6000 and PowerPC Options.
 -mb  -ml  -mdalign  -mrelax @gol
 -mbigtable  -mfmovd  -mhitachi -mrenesas -mno-renesas -mnomacsave @gol
 -mieee  -misize  -mpadstruct  -mspace @gol
--mprefergot  -musermode -multcost=@var{number} -mdiv=@var{strategy}
@gol
+-mprefergot  -musermode -msort-data -multcost=@var{number}
-mdiv=@var{strategy} @gol
 -mdivsi3_libfunc=@var{name}  @gol
 -madjust-unroll -mindexed-addressing -mgettrcost=@var{number}
-mpt-fixed @gol
  -minvalid-symbols}
@@ -11596,6 +11596,13 @@ entries, after fixing up a trampoline.  
 doesn't assume it can write to the whole memory address space.  This
 is the default when the target is @code{sh-*-linux*}.
 
+@item -msort-data
+@opindex msort-data
+Generate separate sections for variables with different data types.
+Arrays are also treated same way. All characters will go in .d_char
section, 
+short integers in .d_short section, long integers in .d_long section,
read only
+characters will go in .rod_char section, read only short integers will
go in
+.rod_short section and read only long integers will go in .rod_long
section.
+The default is not to sort variables as per data type.
+
 @item -multcost=@var{number}
 @opindex multcost=@var{number}
 Set the cost to assume for a multiply insn.

==============================End Of Patch==============================

Regards,
Anil Paranjpe
KPIT Cummins InfoSystems Ltd.
Pune, India

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Free download of GNU based tool-chains for Renesas' SH and H8 Series.
The following site also offers free technical support to its users. 
Visit http://www.kpitgnutools.com for details. 
Latest versions of KPIT GNU tools were released on June 1, 2005.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]