SUBREG givs - no success yet, sigh.
Toon Moene
toon@moene.indiv.nluug.nl
Sat Sep 20 07:02:00 GMT 1997
Do you want to speed up serious Fortran code as compiled with g77
by a factor of two on Alpha's ?
I knew you would ;-)
OK, now that I have your attention, let me explain the way to get there:
Consider the following simple Fortran subroutine:
subroutine daxpy(n,da,dx,dy)
double precision dx(n),dy(n),da
integer i,n
do i = 1, n
dy(i) = dy(i) + da*dx(i)
enddo
end
Compiling with -O2 will lead to no strength reduction at all on an
Alpha. On my m68k, strength reduction will remove all index
calculations, leaving only post-incremented address registers, as
expected.
The reason is the following difference in generated code before
loop optimisation (I'm just showing a single address computation):
===== On Alpha:
(insn 36 33 37 (set (subreg:DI (reg:SI 79) 0)
(plus:DI (reg/v:DI 72)
(const_int -1))) -1 (nil)
(nil))
(insn 37 36 40 (set (reg:DI 80)
(sign_extend:DI (reg:SI 79))) -1 (nil)
(nil))
(insn 40 37 41 (set (reg:DI 82)
(ashift:DI (reg:DI 80)
(const_int 3))) -1 (nil)
(expr_list:REG_EQUAL (mult:DI (reg:DI 80)
(const_int 8))
(nil)))
(insn 41 40 43 (set (reg:DI 83)
(plus:DI (reg/v/u:DI 71)
(reg:DI 82))) -1 (nil)
(nil))
===== On m68k:
(insn 43 41 46 (set (reg:SI 42)
(plus:SI (reg/v:SI 40)
(const_int -1))) -1 (nil)
(nil))
(insn 46 43 47 (set (reg:SI 44)
(ashift:SI (reg:SI 42)
(const_int 3))) -1 (nil)
(expr_list:REG_EQUAL (mult:SI (reg:SI 42)
(const_int 8))
(nil)))
(insn 47 46 57 (set (reg:SI 45)
(plus:SI (reg/v/u:SI 31)
(reg:SI 44))) -1 (nil)
(nil))
On the Alpha it is register 72 that's a BIV, on the m68k it is
register 40. On the Alpha, strength reduction is ineffective,
because either simplify_giv_expr or general_induction_var cannot
detect that (set (reg) (plus (reg) (const)), and (set (subreg) (plus
(reg) (const)) followed by (set (reg) (sign_extend (subreg)) are
basically equivalent.
I set out to solve this myself, but after a couple of hours looking
into this problem and re-re-re-compiling loop.c with different
trial code [on a machine six time zones away from me], I give up -
apparently, it's too hard for me. (What I basically did was
"generalising" the code in basic_induction_var for recognising
promoted_mode subregs into simplify_giv_expr and
geneal_induction_var - without any observable effect).
However, if anyone on this list has a good idea that I can try out
I'm certainly willing to give it another shot.
Thanks in advance,
Toon.
More information about the Gcc
mailing list