Hi Harald,

I try to explain why I think my patch although solving the issue for this case,
does not do so in every case:

My patch lets dependency analysis figure that the two objects can not have any
dependencies on each other or memory they are pointing to when the types are
different. Lets assume a simple list with a head node:

type node
  type(node), pointer :: prev, next
end type

type head
  type(node), pointer :: first, last
end type

(Just as an example; this might not be correct Fortran). Setting up a node

  type(head) :: h
  type(node), allocatable, target :: n

  allocate(n)
  n%prev = n%next = NULL()
  h%first => n
  h%last => n

The patched dependency analysis will deem `h%first => n` operands to be
independent of each other based on both having different types. Note,
dependency analysis looks at the object's type first, i.e. `head` vs. `node`
where I patched it!

While the patch may be correct for the example, it may not be for every case.
Just look one ref further: `h%first`'s type is `node` this would be deemed
having (potentially) a dependency on the type of the target `n`, because both
are of type `node`. Just having the same type is enough here!

So much just for the consequences of my change. Now let me try to explain, why
I think the patch is insufficient:

Assume a type (again pseudo-Fortran):

type T
  type(T), pointer :: n(:,:)
end type

Now doing something like

type(T) :: v1, v2

v1%n(n:m, m:n) => v2%n(m:n, n:m)

The types on lhs and rhs need to be the same. Then even the patched dependency
analysis concludes that in a `forall` a temporary is needed, because the
pointer assignment may overlap (trans-stmt.cc:5411):

need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);

The indexes don't really matter here. They just need to be complicated, i.e.not
just a AR_FULL or AR_ELEMENT. Now `gfc_trans_pointer_assign_need_temp()` is
chosen. That routine in line trans-stmt.cc:5072 converts the lhs into a
descriptor. But because of the non-full/complicated array addressing (note, the
non-contiguous indexes !) `gfc_conv_expr_descriptor()` creates a `parm.12` (in
my case) temporary descriptor. That temporary descriptor, hence the name, is
usually used as actual argument to call a function. But the next line in
`gfc_trans_pointer_assign_need_temp` just assigns the rhs` temporary to that
`parm.12` (I have omitted only some casts, but in the code generated there are
*no* member-references):

parm.12 = lhs-temp

This leads to the gimplification error, because the types of the rhs
temporary and the temporary `parm.12` are not compatible. Furthermore is
the assignment as it is done there non-sense in my eyes, because it is literally
`parm.12 = rhs-temp`. I.e. in the code generated just before that, `parm.12` is
constructed an initialized laboriously and then shall be overwritten completely.
I assume that we would rather need something like (pseudo-pseudo code):

for (n = 1: #elem(rhs-temp))
  parm.12.data[i] = rhs-temp.data[i]
end for

But I have no clue how to easily accomplish that. I tried putting the rhs-temp
into the se of the `gfc_conv_expr_descriptor()` and setting `se.direct_byref =
1`, but that does it the wrong way around, i.e. rhs = lhs (Side note: having a
routine doing an assignment, that is otherwise just delivering a descriptor, is
some odd design decision). So I am at a loss here.

I hope to not have confused everyone. The possibility that I am mislead or
overlooking something or even thinking to complicated here is very likely.
So please correct me!

Therefore let's discuss this a bit more. I hold the patch back until we come to
a conclusion, that it is worth merging w/o breaking too much (which could be
possible, because that dependency analysis is used in many locations).

Regards,
        Andre


On Wed, 5 Mar 2025 20:53:37 +0100
Harald Anlauf <anl...@gmx.de> wrote:

> Hi Andre,
>
> Jerry already OK'ed your patch, but:
>
> Am 05.03.25 um 15:34 schrieb Andre Vehreschild:
> > This fixes the PR, but not really the problem, because when say a
> > obj(i)%arr(2:5) => obj(i)%arr(1:4) is done we run into the same issue. I
> > don't have a solution for that error. It might  be needed to prevent
> > generating the parm.NN variable for the lhs, because that is mostly useless
> > there. (Or I don't understand (yet) how to use it).
>
> can you explain where you do see an issue here?
>
> A pointer assignment in the way you describe seems perfectly legal
> Fortran and works here.
>
> If we are missing anything, would you please open a PR with more
> details?
>
> Thanks,
> Harald
>


--
Andre Vehreschild * Email: vehre ad gmx dot de

Reply via email to