This is the mail archive of the 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: [PATCH] ARM. Optimize some frame-pointer return cases

I said:
> One of the consequences of the patch that Nathan and I prepared to fix
>  problems with stack discipline on ARM was that there was a noticeable
>  increase in code size from the extra instruction needed.  
> On platforms that require 8-byte stack
> alignment the reduction is  approximately half that, but there are
> more tricks that I might yet be  able to apply (once I've worked out
> the logic). 

This patch implements the additional case I referred to.  Sadly, it turned 
out to be more complex than I expected, because ideally it would use a 
form of the ldm instruction for which there is a StrongARM SA110 errata 
(and my original implementation hit this while testing).

To avoid tripping the bug we only use an ldmib instruction if compiling 
for architecture v5 or later. On earlier architectures we pop a scratch 
register instead, which adds an extra cycle to the return, but is still at 
least as fast as the old way, but takes less code space.  The tricky case 
turns out to be supporting this for tail-calls: in that situation r3 might 
be live, so we need to check for that, and if it might be a problem we 
emit the stack-adjustment insn as before.

Bootstrapped and reg-tested on arm-netbsdelf.  Testing shows that it saves 
about 4k of code in cc1 (0.1%) for this platform, and shaved about 3 
minutes (0.4%) off the bootstrap time.

I've installed this on the trunk because it fixes a code size regression 
introduced by the original frame-pointer patch.


2003-11-20  Richard Earnshaw  <>

	* arm.c (use_return_insn): New argument, SIBLING.  Support returning
	with a single instruction if the stack has been decremented by 4
	and we have a frame pointer.  Update all callers.
	(output_return_instruction): Likewise.
	(arm_output_epilogue): Change argument to SIBLING.  Calculate
	really_return from the new argument.  Update all callers.
	* arm.h (USE_RETURN_INSN): Pass NULL for the sibling.
	* (sibcall_epilogue): Call use_return_insn directly, and
	pass the sibling call.
	* arm-protos.h (use_return_insn, arm_output_epilogue): Update

Attachment: frame-ib.patch
Description: frame-ib.patch

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