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 arch OVERRIDE_OPTIONS fix


It looks like gcc is now padding the .text sections on all object files to
a multiple of 256 bytes for the SH architecture. Here's a demonstration:

[tm@localhost gcc]$ cat test.c

int func(int a)

{
}

[tm@localhost gcc]$ ./xgcc -B./ -O2 -m4 -c test.c
[tm@localhost gcc]$ sh-elf-objdump --section-headers test.o

test.o:     file format elf32-sh

Sections:
  Idx Name Size VMA LMA File off Algn
  0 .text         00000100  00000000  00000000  00000100  2**8

                  *** ^ 256 bytes ***

                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00000000  00000000  00000200  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000200  2**0
                  ALLOC
  3 .comment      00000028  00000000  00000000  00000200  2**0
                  CONTENTS, READONLY

Thsi is obviously bad for libc since every single function is compiled
into a separate object file, and every object file now has a .text segment
which is a multiple of 256 bytes.

This causes code bloat problems.

        .file   "test.c"
        .text
        .text
        .align 1
        .align 8			<- 256 byte alignment
        .global _func
        .type   _func, @function
_func:
        mov.l   r14,@-r15
        mov     r15,r14
        mov     r14,r15
        rts
        mov.l   @r15+,r14
        .size   _func, .-_func
        .ident  "GCC: (GNU) 3.3 20020906 (experimental)"

It looks like align_functions is being set incorrectly:

(xxgdb) print align_functions
$1 = 256
(xxgdb) 

The last time I checked the object code sizes was on 7/17/2002, so some
change between 7/17/2002 and 9/6/2002 seems to be causing the problem.

The culprit appears to be this code in config/sh.h:

  /* Allocation boundary (in *bits*) for the code of a function.        \
     SH1: 32 bit alignment is faster, because instructions are always   \
     fetched as a pair from a longword boundary.                        \
     SH2 .. SH5 : align to cache line start.  */                        \
  if (align_functions == 0)                                             \
    align_functions                                                     \
      = TARGET_SMALLCODE ? FUNCTION_BOUNDARY : (1 << CACHE_LOG) * 8;    \

...and this code was introduced by this change:

Wed Aug 28 15:35:17 2002  J"orn Rennecke <joern.rennecke@superh.com>

        ...
        * sh.h (OVERRIDE_OPTIONS): If align_function isn't set, set it
        appropriately.
        (FUNCTION_BOUNDARY): Specify only the minimum alignment required
        by the ABI.
        ...

This comment:

  /* Allocation boundary (in *bits*) for the code of a function.        \

appears to be incorrect. The other usages of align_functions appear to
assume the value is in bytes, for example, in toplev.c, line 4846:

  if (optimize < 2 || optimize_size)
    {
      align_loops = 1;
      align_jumps = 1;
      align_labels = 1;
      align_functions = 1;
...

Therefore, I propose something like the following:

2002-09-06  Toshiyasu Morita  <toshiyasu.morita@hsa.hitachi.com>

	* config/sh/sh.c (OVERRIDE_OPTIONS): align_functions is in bytes,
	not bits.

*** sh.h.bak	Fri Sep  6 17:30:51 2002
--- sh.h	Fri Sep  6 17:31:12 2002
*************** do {									\
*** 476,488 ****
       to the pressure on R0.  */						\
    flag_schedule_insns = 0;						\
  									\
!   /* Allocation boundary (in *bits*) for the code of a function.	\
       SH1: 32 bit alignment is faster, because instructions are always	\
       fetched as a pair from a longword boundary.			\
       SH2 .. SH5 : align to cache line start.  */			\
    if (align_functions == 0)						\
      align_functions							\
!       = TARGET_SMALLCODE ? FUNCTION_BOUNDARY : (1 << CACHE_LOG) * 8;	\
  } while (0)
  
  /* Target machine storage layout.  */
--- 476,488 ----
       to the pressure on R0.  */						\
    flag_schedule_insns = 0;						\
  									\
!   /* Allocation boundary (in *bytes*) for the code of a function.	\
       SH1: 32 bit alignment is faster, because instructions are always	\
       fetched as a pair from a longword boundary.			\
       SH2 .. SH5 : align to cache line start.  */			\
    if (align_functions == 0)						\
      align_functions							\
!       = TARGET_SMALLCODE ? FUNCTION_BOUNDARY : (1 << CACHE_LOG);	\
  } while (0)
  
  /* Target machine storage layout.  */


With this patch I see the following resuilt:

[tm@localhost gcc]$ cat test.c

int func(int a)

{
}

[tm@localhost gcc]$ ./xgcc -B./ -O2 -m4 -c test.c
[tm@localhost gcc]$ sh-elf-objdump --section-headers test.o

test.o:     file format elf32-sh

Sections:
Idx Name          Size      VMA               LMA               File off
Algn
  0 .text         00000020  00000000  00000000  00000040  2**5
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00000000  00000000  00000060  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000060  2**0
                  ALLOC
  3 .comment      00000028  00000000  00000000  00000060  2**0
                  CONTENTS, READONLY

Also, examination of the generated assembly file reveals:

        .file   "test.c"
        .text
        .text
        .align 1
        .align 5		<- back to 32 byte alignment
        .global _func
        .type   _func, @function
_func:
        mov.l   r14,@-r15
        mov     r15,r14
        mov     r14,r15
        rts
        mov.l   @r15+,r14
        .size   _func, .-_func
        .ident  "GCC: (GNU) 3.3 20020906 (experimental)"


Toshi


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