Re: Automatically transform or expand do loop in a subroutine
- From: yaqi <yaqiwang@xxxxxxxxx>
- Date: Thu, 31 Jan 2008 13:48:22 -0800 (PST)
On Jan 31, 2:10 pm, Thomas Koenig <tkoe...@xxxxxxxxxxxxx> wrote:
On 2008-01-31, yaqi <yaqiw...@xxxxxxxxx> wrote:
***, are you sure compilers can handle this case?
I modified your program by making the function internal (which
makes inlining much easier), then feeding ito to gfortran.
Here's the modified program (I had to add the I/O statements
to avoid optimizing the whole program away :-)
program main
integer :: e, c
read (*,*) c
e = ad(c, 10)
print *,e
stop
contains
integer function ad(c,d)
implicit none
integer :: c
integer :: d
integer :: i
do i=1,d
c = c + i
end do
ad = c
return
end function ad
end program main
Here's what "gfortran -O3 -fdump-tree-optimized" made of it:
main ()
{
integer(kind=4) c_lsm.57;
integer(kind=4) c_lsm.56;
struct __st_parameter_dt dt_parm.2;
struct __st_parameter_dt dt_parm.1;
static integer(kind=4) options.0[7] = {68, 127, 0, 0, 0, 1, 0};
integer(kind=4) e;
integer(kind=4) c;
<bb 2>:
_gfortran_set_options (7, &options.0);
dt_parm.1.common.filename = &"foo.f90"[1]{lb: 1 sz: 1};
dt_parm.1.common.line = 3;
dt_parm.1.common.flags = 128;
dt_parm.1.common.unit = 5;
_gfortran_st_read (&dt_parm.1);
_gfortran_transfer_integer (&dt_parm.1, &c, 4);
_gfortran_st_read_done (&dt_parm.1);
c_lsm.56 = c;
c_lsm.57 = c_lsm.56 + 55;
c = c_lsm.57;
e = c_lsm.57;
dt_parm.2.common.filename = &"foo.f90"[1]{lb: 1 sz: 1};
dt_parm.2.common.line = 5;
dt_parm.2.common.flags = 128;
dt_parm.2.common.unit = 6;
_gfortran_st_write (&dt_parm.2);
_gfortran_transfer_integer (&dt_parm.2, &e, 4);
_gfortran_st_write_done (&dt_parm.2);
_gfortran_stop_numeric (-1);
}
The loop is optimized into an addition, which isn't bad. This
doesn't work for non-constant d, though.
I tried following modified program:
-----------------------------------------
program main
implicit none
integer :: e, c, ad, i
real :: t1, t2
integer, parameter :: mloop = 100000000
c = 0
call cpu_time(t1)
do i = 1, mloop
e = ad(c,10)
end do
call cpu_time(t2)
print *, 'Time cost with function call:', t2-t1
print *, e
c = 0
call cpu_time(t1)
do i = 1, mloop
c = c + 55
e = c
end do
call cpu_time(t2)
print *, 'Time cost with function call:', t2-t1
print *, e
stop
end program
integer function ad(c,d)
implicit none
integer :: c
integer :: d
integer :: i
do i=1,d
c = c + i
end do
ad = c
return
end function ad
--------------------------------
And compiled with 'gfortran -O5 -fdump-tree-optimized'. The generated
pseudo-code is:
--------------------------------
;; Function ad (ad_)
Analyzing Edge Insertions.
ad (c, d)
{
<unnamed type> D.1138;
<unnamed type> D.1139;
int4 D.1140;
int4 c__lsm.34;
int4 pretmp.33;
logical4 D.1067;
int4 D.1064;
int4 __result_ad;
int4 i;
int4 D.1073;
int4 D.1072;
int4 D.1071;
<bb 0>:
D.1064 = *d;
if (D.1064 > 0) goto <L12>; else goto <L4>;
<L12>:;
c__lsm.34 = *c;
i = 1;
<L10>:;
c__lsm.34 = i + c__lsm.34;
i = i + 1;
if (i == (int4) ((<unnamed type>) D.1064 + 1)) goto <L16>; else goto
<L10>;
<L16>:;
*c = c__lsm.34;
<L4>:;
return *c;
}
;; Function MAIN__ (MAIN__)
Analyzing Edge Insertions.
MAIN__ ()
{
real4 t2.80;
real4 t1.79;
real4 temp.78;
int4 c_lsm.77;
<unnamed type> ivtmp.69;
int4 c_lsm.68;
int4 e_lsm.67;
int4 pretmp.66;
int4 pretmp.65;
int4 C.1039 = 10;
struct __st_parameter_dt dt_parm.3;
real4 D.1049;
struct __st_parameter_dt dt_parm.2;
logical4 D.1047;
struct __st_parameter_dt dt_parm.1;
real4 D.1043;
struct __st_parameter_dt dt_parm.0;
logical4 D.1041;
real4 t1;
real4 t2;
int4 e;
int4 i;
int4 c;
int4 D.1058;
int4 c.6;
real4 D.1055;
real4 t1.5;
real4 t2.4;
int4 D.1052;
<bb 0>:
_gfortran_set_std (70, 127, 0);
c = 0;
_gfortran_cpu_time_4 (&t1);
i = 1;
<L0>:;
D.1052 = ad (&c, &C.1039);
e = D.1052;
i = i + 1;
if (i == 100000001) goto <L4>; else goto <L0>;
<L4>:;
_gfortran_cpu_time_4 (&t2);
dt_parm.0.common.filename = "a.f90";
dt_parm.0.common.line = 13;
dt_parm.0.common.unit = 6;
dt_parm.0.common.flags = 128;
_gfortran_st_write (&dt_parm.0);
_gfortran_transfer_character (&dt_parm.0, "Time cost with function
call:", 29\
);
D.1043 = t2 - t1;
_gfortran_transfer_real (&dt_parm.0, &D.1043, 4);
_gfortran_st_write_done (&dt_parm.0);
dt_parm.1.common.filename = "a.f90";
dt_parm.1.common.line = 14;
dt_parm.1.common.unit = 6;
dt_parm.1.common.flags = 128;
_gfortran_st_write (&dt_parm.1);
_gfortran_transfer_integer (&dt_parm.1, &e, 4);
_gfortran_st_write_done (&dt_parm.1);
c = 0;
_gfortran_cpu_time_4 (&t1);
c_lsm.68 = c;
e = c_lsm.68 + 047d35700;
c = c_lsm.68 + 047d35700;
_gfortran_cpu_time_4 (&t2);
dt_parm.2.common.filename = "a.f90";
dt_parm.2.common.line = 23;
dt_parm.2.common.unit = 6;
dt_parm.2.common.flags = 128;
_gfortran_st_write (&dt_parm.2);
_gfortran_transfer_character (&dt_parm.2, "Time cost with function
call:", 29\
);
D.1049 = t2 - t1;
_gfortran_transfer_real (&dt_parm.2, &D.1049, 4);
_gfortran_st_write_done (&dt_parm.2);
dt_parm.3.common.filename = "a.f90";
dt_parm.3.common.line = 24;
dt_parm.3.common.unit = 6;
dt_parm.3.common.flags = 128;
_gfortran_st_write (&dt_parm.3);
_gfortran_transfer_integer (&dt_parm.3, &e, 4);
_gfortran_st_write_done (&dt_parm.3);
_gfortran_stop_numeric (-1);
}
---------------------------------
gfortran does not incline the function call. What happened?
Yaqi
.
- Follow-Ups:
- Re: Automatically transform or expand do loop in a subroutine
- From: Steven G. Kargl
- Re: Automatically transform or expand do loop in a subroutine
- References:
- Automatically transform or expand do loop in a subroutine
- From: yaqi
- Re: Automatically transform or expand do loop in a subroutine
- From: *** Hendrickson
- Re: Automatically transform or expand do loop in a subroutine
- From: yaqi
- Re: Automatically transform or expand do loop in a subroutine
- From: Thomas Koenig
- Automatically transform or expand do loop in a subroutine
- Prev by Date: Re: Type specification and initialization expressions
- Next by Date: Re: Automatically transform or expand do loop in a subroutine
- Previous by thread: Re: Automatically transform or expand do loop in a subroutine
- Next by thread: Re: Automatically transform or expand do loop in a subroutine
- Index(es):