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]

Re: ARM: allow factorization of constants into addressing insns whenoptimizing for space


Nicolas Pitre wrote:
If optimizing for space, we currently let the compiler synthesize constants
only if they need one insn, otherwise a load from memory is performed.

This patch allows the compiler to synthesize constants with up to 2 insns,
which uses the same space as a load from memory (the ldr insn and the pool
entry) so worse case is the same. HOwever, this gives the opportunity to
take even less space when different offsets can be factorized and combined
into multiple pre-indexed loads or stores.

Testing shows varying degree of text size reduction depending on code patern. No increase of code space has been noted.

This patch also restructure related code a bit with some more comments to
make things clearer but with no other operational changes.


<date> Nicolas Pitre <nico@cam.org>


	* config/arm/arm.c (arm_override_options): Set arm_constant_limit
	to 2 instead of 1 when optimize_size is true.  Gather code based on
	optimize_size together.  Add comment about XScale load latency.


Sorry for the late answer, but I think it is not an effective solution for size. The following example shows the problem about synthesizing constants with up to 2 insns:

c source code:

int a,b;

int f(int);
int proc ();

void foo()
{
         a += f (257);

         // Do something which modifies r0 reg
         if (proc ()) b += 1;

         a += f (257);
}

When we don't synthesize constants the arm asm code will be
the following:

foo:
	mov	ip, sp
	stmfd	sp!, {r4, fp, ip, lr, pc}
	sub	fp, ip, #4
	ldr	r0, .L3                    @ <-- 257
	bl	f
	ldr	r4, .L3+4
	ldr	r3, [r4, #0]
	add	r3, r3, r0
	str	r3, [r4, #0]
	bl	proc
	ldr	r2, .L3+8
	cmp	r0, #0
	ldrne	r3, [r2, #0]
	addne	r3, r3, #1
	strne	r3, [r2, #0]
	ldr	r0, .L3                    @ <-- 257
	bl	f
	ldr	r3, [r4, #0]
	add	r3, r3, r0
	str	r3, [r4, #0]
	sub	sp,fp,#16
	ldmfd	sp, {r4, fp, sp, pc}
.L4:
	.align	2
.L3:
	.word	257                        @ <-- 257
	.word	a
	.word	b
	.size	foo, .-foo
	.comm	a,4,4
	.comm	b,4,4
	.ident	"GCC: (GNU) 3.4 20031021 (experimental)"

When we synthesize constants with up to 2 insns the arm asm code will be
the following:

foo:
	mov	ip, sp
	stmfd	sp!, {r4, fp, ip, lr, pc}
	sub	fp, ip, #4
	mov	r0, #256                        @ <-- 257
	add	r0, r0, #1                      @ <-- 257
	bl	f
	ldr	r4, .L3
	ldr	r3, [r4, #0]
	add	r3, r3, r0
	str	r3, [r4, #0]
	bl	proc
	ldr	r2, .L3+4
	cmp	r0, #0
	ldrne	r3, [r2, #0]
	addne	r3, r3, #1
	strne	r3, [r2, #0]
	mov	r0, #256                        @ <-- 257
	add	r0, r0, #1                      @ <-- 257
	bl	f
	ldr	r3, [r4, #0]
	add	r3, r3, r0
	str	r3, [r4, #0]
	sub	sp,fp,#16
	ldmfd	sp, {r4, fp, sp, pc}
.L4:
	.align	2
.L3:
	.word	a
	.word	b
	.size	foo, .-foo
	.comm	a,4,4
	.comm	b,4,4
	.ident	"GCC: (GNU) 3.4 20031021 (experimental)"

When we don't synthesize constants the use of constant #257 needs
12 bytes, but for the other case the use of constant #257 needs 16
bytes.

In other words, this problem occurs in each case when a constant is
loaded more than once and between the loads the register which holds
the constant is modified. And this is a really common use of constants.

See the CSiBE measurements results at http://sed.inf.u-szeged.hu/CSiBE
There is a code size increase of about 0,4% from the 20th to the 21st,
which was caused by allow factorization of constants.

I suggest using CSiBE for measuring code size effects. There is a
downloadable version of CSiBE, you can check it out at
http://sed.inf.u-szeged.hu/CSiBE/download.php

The following patch disables synthesizing constants for ARM when
optimizing for size.

Regards,
         Gábor Lóki



2003-10-22 Gábor Lóki <alga@rgai.hu>

	* config/arm/arm.c (arm_override_options): disables
	synthesizing constants when optimizing for size

Index: gcc/gcc/config/arm/arm.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.301
diff -c -3 -p -r1.301 arm.c
*** gcc/gcc/config/arm/arm.c	21 Oct 2003 01:56:49 -0000	1.301
--- gcc/gcc/config/arm/arm.c	22 Oct 2003 09:21:29 -0000
*************** arm_override_options (void)
*** 847,857 ****
  
    if (optimize_size)
      {
!       /* If optimizing for space, we let the compiler synthesize constants
!          with up to 2 insns, which uses the same space as a load from memory.
!          This gives the opportunity to take even less space when different
!          offsets can be factorized into multiple pre-indexed loads or stores. */
!       arm_constant_limit = 2;
  
        /* If optimizing for size, bump the number of instructions that we
           are prepared to conditionally execute (even on a StrongARM). */
--- 847,854 ----
  
    if (optimize_size)
      {
!       /* If optimizing for space, don't synthesize constants.  */
!       arm_constant_limit = 1;
  
        /* If optimizing for size, bump the number of instructions that we
           are prepared to conditionally execute (even on a StrongARM). */








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