http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49103

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-05-23 
07:35:48 UTC ---
Ugh, the problem is that first cunrolli unrolls the loop, so we get among other
things parm.9 initialized for printing fgrades_35, then
_gfortran_transfer_array_write from parm.9, then parm.11 initialized for
printing fbasegrades_19, then _gfortran_transfer_array_write from parm.11, then
again parm.9 initialized to the same values again,
_gfortran_transfer_array_write from it, parm.11 to the same values and
_gfortran_transfer_array_write from it.
Additionally, _gfortran_transfer_array_write uses ".wr" "fn spec" attribute.
Next comes fre (2nd), which sees the ".wr" fn spec and removes the second
identical initialization of parm.9 and parm.11, so parm.9 is no longer live in
two separate ranges, but also across the parm.11 initialization and
_gfortran_transfer_array_write call from it.  And during expansion, we figure
out that parm.9 and parm.11 are in different, non-overlapping blocks and thus
decide to share the stack slot for both.

Appart from the ".wr" "fn spec" attribute I think there is nothing fortran
specific and with
struct S { largish struct };
for (int i = 0; i < 2; i++)
  {
    {
      struct S a;
      initialize a;
      use a;
    }
    {
      struct S b;
      initialize b;
      use b;
    }
  }
we could achieve similar effect (though, if e.g. use is a pure function, the
second call would be deleted).  So, I'm not convinced reverting my patch is the
right fix.  Not sure how to allow expansion to notice that unrolling made it
impossible to share the stack slots though.  Ideas?

Reply via email to