This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Improving code with no offset addressing
- From: Michael Hope <michaelh at juju dot net dot nz>
- To: gcc at gcc dot gnu dot org
- Date: Tue, 20 Oct 2009 10:09:15 +1300
- Subject: 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