This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran 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]

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.

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