This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
Re: [PATCH] Fix fortran creating a huge number of io transfer structs
On Wed, 22 Feb 2006, François-Xavier Coudert wrote:
> > PROGRAM test
> > WRITE(*,*) 'hello'
> > WRITE(*,*) 'world'
> > END
> >
> > gfortran creates two struct __st_parameter_dt, one for each I/O operation.
> > This causes a _huge_ regression in compile time if we ever start to create
> > SFTs for those structs
>
> Hum, could we have a pointer to what SFT is? (a google "sft gcc" lead
> me to info page
> http://gcc.gnu.org/onlinedocs/gccint/Alias-analysis.html, but that's
> still not completely obvious to my simple mind...)
Yes, SFT is a structure field tag. We create them do disambiguate
structure elements for aliasing. In the -fdump-tree-alias-vops dump
you can see them used/clobbered like so:
<bb 2>:
# SFT.1_25 = V_MAY_DEF <SFT.1_7>;
# SFT.2_26 = V_MAY_DEF <SFT.2_8>;
# SFT.3_27 = V_MAY_DEF <SFT.3_9>;
# SFT.4_28 = V_MAY_DEF <SFT.4_10>;
# SFT.5_29 = V_MAY_DEF <SFT.5_11>;
# SFT.6_30 = V_MAY_DEF <SFT.6_12>;
# SFT.7_31 = V_MAY_DEF <SFT.7_13>;
# SFT.8_32 = V_MAY_DEF <SFT.8_14>;
# SFT.9_33 = V_MAY_DEF <SFT.9_15>;
# SFT.10_34 = V_MAY_DEF <SFT.10_16>;
# SFT.11_35 = V_MAY_DEF <SFT.11_17>;
# SFT.12_36 = V_MAY_DEF <SFT.12_18>;
# SFT.13_37 = V_MAY_DEF <SFT.13_19>;
# SFT.14_38 = V_MAY_DEF <SFT.14_20>;
# SFT.15_39 = V_MAY_DEF <SFT.15_21>;
# SFT.16_40 = V_MAY_DEF <SFT.16_22>;
# SFT.17_41 = V_MAY_DEF <SFT.17_23>;
# SFT.18_42 = V_MAY_DEF <SFT.18_24>;
# SFT.19_43 = V_MAY_DEF <SFT.19_1>;
# SFT.20_44 = V_MAY_DEF <SFT.20_3>;
_gfortran_set_std (70, 127, 0);
# SFT.19_2 = V_MUST_DEF <SFT.19_43>;
dt_parm.0.common.unit = 6;
# SFT.20_4 = V_MUST_DEF <SFT.20_44>;
dt_parm.0.common.flags = 128;
# SFT.1_45 = V_MAY_DEF <SFT.1_25>;
# SFT.2_46 = V_MAY_DEF <SFT.2_26>;
# SFT.3_47 = V_MAY_DEF <SFT.3_27>;
# SFT.4_48 = V_MAY_DEF <SFT.4_28>;
# SFT.5_49 = V_MAY_DEF <SFT.5_29>;
# SFT.6_50 = V_MAY_DEF <SFT.6_30>;
# SFT.7_51 = V_MAY_DEF <SFT.7_31>;
# SFT.8_52 = V_MAY_DEF <SFT.8_32>;
# SFT.9_53 = V_MAY_DEF <SFT.9_33>;
# SFT.10_54 = V_MAY_DEF <SFT.10_34>;
# SFT.11_55 = V_MAY_DEF <SFT.11_35>;
# SFT.12_56 = V_MAY_DEF <SFT.12_36>;
# SFT.13_57 = V_MAY_DEF <SFT.13_37>;
# SFT.14_58 = V_MAY_DEF <SFT.14_38>;
# SFT.15_59 = V_MAY_DEF <SFT.15_39>;
# SFT.16_60 = V_MAY_DEF <SFT.16_40>;
# SFT.17_61 = V_MAY_DEF <SFT.17_41>;
# SFT.18_62 = V_MAY_DEF <SFT.18_42>;
# SFT.19_63 = V_MAY_DEF <SFT.19_2>;
# SFT.20_64 = V_MAY_DEF <SFT.20_4>;
_gfortran_st_write (&dt_parm.0);
# SFT.1_65 = V_MAY_DEF <SFT.1_45>;
# SFT.2_66 = V_MAY_DEF <SFT.2_46>;
# SFT.3_67 = V_MAY_DEF <SFT.3_47>;
# SFT.4_68 = V_MAY_DEF <SFT.4_48>;
# SFT.5_69 = V_MAY_DEF <SFT.5_49>;
# SFT.6_70 = V_MAY_DEF <SFT.6_50>;
# SFT.7_71 = V_MAY_DEF <SFT.7_51>;
# SFT.8_72 = V_MAY_DEF <SFT.8_52>;
# SFT.9_73 = V_MAY_DEF <SFT.9_53>;
# SFT.10_74 = V_MAY_DEF <SFT.10_54>;
# SFT.11_75 = V_MAY_DEF <SFT.11_55>;
# SFT.12_76 = V_MAY_DEF <SFT.12_56>;
# SFT.13_77 = V_MAY_DEF <SFT.13_57>;
# SFT.14_78 = V_MAY_DEF <SFT.14_58>;
# SFT.15_79 = V_MAY_DEF <SFT.15_59>;
# SFT.16_80 = V_MAY_DEF <SFT.16_60>;
# SFT.17_81 = V_MAY_DEF <SFT.17_61>;
# SFT.18_82 = V_MAY_DEF <SFT.18_62>;
# SFT.19_83 = V_MAY_DEF <SFT.19_63>;
# SFT.20_84 = V_MAY_DEF <SFT.20_64>;
_gfortran_transfer_character (&dt_parm.0, "hello", 5);
note that one problem is that for call clobbering we do not seem to be
able to disambiguate &dt_parm.0 and &dt_parm.1, so we build up huge
chains of (useless) clobbers here. You can see this also in 4.1, though
we never create SFTs for the dt_parms here because it contains an array:
<bb 0>:
# dt_parm.0_2 = V_MAY_DEF <dt_parm.0_1>;
dt_parm.0.common.filename = "t.f";
# dt_parm.0_3 = V_MAY_DEF <dt_parm.0_2>;
dt_parm.0.common.line = 2;
# dt_parm.0_4 = V_MAY_DEF <dt_parm.0_3>;
dt_parm.0.common.unit = 6;
# dt_parm.0_5 = V_MAY_DEF <dt_parm.0_4>;
dt_parm.0.common.flags = 128;
# dt_parm.0_11 = V_MAY_DEF <dt_parm.0_5>;
# dt_parm.1_12 = V_MAY_DEF <dt_parm.1_6>;
_gfortran_st_write (&dt_parm.0);
# dt_parm.0_13 = V_MAY_DEF <dt_parm.0_11>;
# dt_parm.1_14 = V_MAY_DEF <dt_parm.1_12>;
_gfortran_transfer_character (&dt_parm.0, "hello", 5);
# dt_parm.0_15 = V_MAY_DEF <dt_parm.0_13>;
# dt_parm.1_16 = V_MAY_DEF <dt_parm.1_14>;
_gfortran_st_write_done (&dt_parm.0);
# dt_parm.1_7 = V_MAY_DEF <dt_parm.1_16>;
dt_parm.1.common.filename = "t.f";
# dt_parm.1_8 = V_MAY_DEF <dt_parm.1_7>;
dt_parm.1.common.line = 3;
# dt_parm.1_9 = V_MAY_DEF <dt_parm.1_8>;
dt_parm.1.common.unit = 6;
dt_parm.1.common.unit = 6;
# dt_parm.1_10 = V_MAY_DEF <dt_parm.1_9>;
dt_parm.1.common.flags = 128;
# dt_parm.0_17 = V_MAY_DEF <dt_parm.0_15>;
# dt_parm.1_18 = V_MAY_DEF <dt_parm.1_10>;
_gfortran_st_write (&dt_parm.1);
# dt_parm.0_19 = V_MAY_DEF <dt_parm.0_17>;
# dt_parm.1_20 = V_MAY_DEF <dt_parm.1_18>;
_gfortran_transfer_character (&dt_parm.1, "world", 5);
# dt_parm.0_21 = V_MAY_DEF <dt_parm.0_19>;
# dt_parm.1_22 = V_MAY_DEF <dt_parm.1_20>;
_gfortran_st_write_done (&dt_parm.1);
>
> > but there's no reason why gfortran cannot share one struct
> > __st_parameter_dt per function or at least one per sequence of I/O
> > operations.
>
> I wonder how that does interact with the fact asynchronous I/O
> (although it's not implemented yet, we still have to think about it).
Hmm, ok - for async I/O we probably cannot share the dt_parm type
(without copying it in the I/O routines). Maybe we can instead fix
some of the aliasing stupidities.
Richard.