This is the mail archive of the gcc@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]

Improving code with no offset addressing


Hi there.  The architecture I'm working on porting gcc to has indirect
addressing but no constant offset or register offset versions.  Code
like this:

void fill(int* p)
{
  p[0] = 0;
  p[1] = 0;
  p[2] = 0;
  p[3] = 0;

Turns into:
 X = p
 *X = 0
 X = X + 4
 *X = 0
 X = p
 X = X + 8
 *X = 0
 X = p
 X = X + 12
 *X = 0

at both -O and -O2.  Note that the first step recognises that X
contains p and correctly increases it instead of rebuilding it.

I'd like to generate the following code instead:
 X = p
 *X = 0
 X = X + 4
 *X = 0
 X = X + 4
 *X = 0
 X = p
 X = X + 4
 *X = 0

What is the best way to approach this?  It seems to be common across
ports (see the note on ia64 and ARM Thumb below).  Is there a cost
function I can change?  Will changing LEGITIMIZE_ADDRESS fix it?  Is
there some type of value tracking that could be turned on/added?

I've checked the ia64, which also only has indirect addressing, and
ARM Thumb which has limited offsets.  ia64 generates the same reload
base/add offset as mine:

	mov r14 = r32
	;;
	st4 [r14] = r0, 4
	;;
	st4 [r14] = r0
	adds r14 = 8, r32
	;;
	st4 [r14] = r0
	adds r14 = 12, r32
	;;
	st4 [r14] = r0
	adds r14 = 16, r32

ARM Thumb does the same when the offset is large (p[70] and p[71] in this case):

	str	r3, [r0] ; p[0]
	str	r3, [r0, #4] ; p[1]
	str	r3, [r0, #8] ; p[2]
	str	r3, [r0, #12] ; p[3]
	mov	r2, #140
	mov	r3, #0
	lsl	r2, r2, #1
	str	r3, [r0, r2] ; p[70]
	mov	r2, #142
	lsl	r2, r2, #1
	str	r3, [r0, r2] ; p[71]

Thanks for any pointers,

-- Michael


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