38 Commits

Author SHA1 Message Date
Valentin Clement
42be165dde Reland '[flang][cuda] Specialize entry point for scalar to desc data transfer' 2024-11-15 19:13:55 -08:00
Valentin Clement (バレンタイン クレメン)
70b9440c88
Revert "[flang][cuda] Specialize entry point for scalar to desc data transfer" (#116458)
Reverts llvm/llvm-project#116457
2024-11-15 17:44:48 -08:00
Valentin Clement (バレンタイン クレメン)
43cb424a54
[flang][cuda] Specialize entry point for scalar to desc data transfer (#116457)
The runtime Assign function is not meant to initialize an array from a
scalar. For that we need to use DoAssignFromSource. Update the data
transfer from scalar to descriptor to use a new entry point that use
this function underneath.
2024-11-15 17:41:23 -08:00
Peter Klausler
07e053fb95
[flang][runtime] Fix finalization case in assignment (#113611)
There were two bugs in derived type array assignment processing that
caused finalization to fail to occur for a test case. The first bug was
an off-by-one error in address overlap testing that caused a false
positive result for the test, whose left-hand side's allocatable's
descriptor was immediately adjacent in memory to the right-hand side's
array's data.
The second bug was that in such overlap cases (even when legitimate)
finalization would fail due to the LHS's descriptor having been copied
to a temporary for deferred deallocation and then nullified.

This patch corrects the overlap analysis for this test, and also
properly finalizes the LHS when overlap does exist. Some nearby dead
code was removed to avoid future confusion.

Fixes https://github.com/llvm/llvm-project/issues/113375.
2024-11-05 13:17:56 -08:00
Valentin Clement (バレンタイン クレメン)
7792dbe29a
Reland '[flang][runtime] Allow different memmov function in assign' (#114587)
Reland #114301
2024-11-01 11:26:39 -07:00
Valentin Clement (バレンタイン クレメン)
c5a254cdd7
Revert "[flang][runtime][NFC] Allow different memmove function in assign" (#114581)
Reverts llvm/llvm-project#114301
2024-11-01 10:40:10 -07:00
Valentin Clement (バレンタイン クレメン)
b278fe3297
[flang][runtime][NFC] Allow different memmove function in assign (#114301)
- Add a parameter to the `Assign` function to be able to use a different
`memmove` function. This is preparatory work to be able to use the
`Assign` function between host and device data.
- Expose the `Assign` function so it can be used from different files. 

- The new `memmoveFct` is not used in `BlankPadCharacterAssignment` yet
since it is not clear if there is a need. It will be updated in case it
is needed.
2024-11-01 10:34:03 -07:00
Philip Reames
050f785e2c Revert "[flang][runtime] Fix odd "invalid descriptor" runtime crash (#107785)"
This reverts commit 15106c26662a573df31e8dfdd9350c313b8bfd84.  Commit does
not pass check-flang on x86 host.
2024-09-11 07:40:22 -07:00
Peter Klausler
15106c2666
[flang][runtime] Fix odd "invalid descriptor" runtime crash (#107785)
A defined assignment generic interface for a given LHS/RHS type & rank
combination may have a specific procedure with LHS dummy argument that
is neither allocatable nor pointer, or specific procedure(s) whose LHS
dummy arguments are allocatable or pointer. It is possible to have two
specific procedures if one's LHS dummy argument is allocatable and the
other's is pointer.

However, the runtime doesn't work with LHS dummy arguments that are
allocatable, and will crash with a mysterious "invalid descriptor" error
message.

Extend the list of special bindings to include
ScalarAllocatableAssignment and ScalarPointerAssignment, use them when
appropriate in the runtime type information tables, and handle them in
Assign() in the runtime support library.
2024-09-10 14:14:08 -07:00
Leandro Lupori
797f01198e
[flang][OpenMP] Make lastprivate work with reallocated variables (#106559)
Fixes https://github.com/llvm/llvm-project/issues/100951
2024-09-05 14:55:01 -03:00
jeanPerier
9f44d5d9d0
[flang] Simplify copy-in copy-out runtime API (#95822)
The runtime API for copy-in copy-out currently only has an entry only
for the copy-out. This entry has a "skipInit" boolean that is never set
to false by lowering and it does not deal with the deallocation of the
temporary.

The generated code was a mix of inline code and runtime calls This is not a big deal,
but this is unneeded compiler and generated code complexity.
With assumed-rank, it is also more cumbersome to establish a
temporary descriptor.

Instead, this patch:
- Adds a CopyInAssignment API that deals with establishing the temporary
descriptor and does the copy.
- Removes unused arg to CopyOutAssign, and pushes
destruction/deallocation responsibility inside it.

Note that this runtime API are still not responsible for deciding the
need of copying-in and out. This is kept as a separate runtime call to
IsContiguous, which is easier to inline/replace by inline code with the
hope of removing the copy-in/out calls after user function inlining.
@vzakhari has already shown that always inlining all the copy part
increase Fortran compilation time due to loop optimization attempts for
loops that are known to have little optimization profitability (the
variable being copied from and to is not contiguous).
2024-06-18 12:04:04 +02:00
jeanPerier
5f6e0f35f9
[flang][runtime] Destroy nested allocatable components (#81117)
The runtime was currently only deallocating the direct allocatable
components, which caused leaks when there are allocatable components
nested in the direct components.

Update Destroy to recursively destroy components.

Also call Destroy from Assign to deallocate nested allocatable
components before doing the assignment as required by F2018 9.7.3.2
point 7.

This lack of deallocation was visible if the nested components had user
defined assignment "observing" the allocation state.
2024-02-15 09:04:42 +01:00
Peter Klausler
887783e0ca
[flang][runtime] Invert component/element loops in assignment (#78341)
The general implementation of intrinsic assignment of derived types in
the runtime support library has a doubly-nested loop: an outer loop that
traverses the components and inner loops than traverse the array
elements. It's done this way to amortize the per-component overhead.
However, this turns out to be wrong when the program cares about the
order in which defined assignment subroutines are called; the Fortran
standard allows less latitude here than we need to invert the ordering
in this way when any component is itself an array. So invert the two
loops: traverse the array elements, and for each element, traverse its
components.
2024-01-25 14:05:36 -08:00
Slava Zakharin
f92309a3a5
[flang][runtime] Workaround cuda-11.8 compilation issue. (#68459)
cuda-11.8 nvcc cannot handle brace initialization of the lambda
object. 12.1 works okay, but I would like to have an option
to use 11.8.
2023-10-09 16:26:06 -07:00
Slava Zakharin
8b953fdd6b
[flang][runtime] Added Assign runtime to CUDA build closure. (#68171) 2023-10-04 08:21:46 -07:00
Peter Klausler
b21c24c308
[flang][runtime] Recognize and handle FINAL subroutines with contiguous dummy arrays when data are not so
When a FINAL subroutine is being invoked for a discontiguous array, which can
happen for INTENT(OUT) dummy arguments and for some left-hand side variables
in intrinsic assignment statements, it may be the case that the subroutine
being called was defined with a dummy argument that requires contiguous data.

Extend the derived type descriptions used by the runtime to signify when
a special procedure binding requires contiguity; set the flags accordingly;
check them in the runtime support library, and, when necessary, use a
temporary shallow copy of the finalized array data in the call to the
final subroutine.

Differential Revision: https://reviews.llvm.org/D156760
2023-08-01 13:46:45 -07:00
Slava Zakharin
c78b528f99 [flang][runtime] Handle conflicts for derived types with dynamic components.
When creating a temporary for conflicting LHS and RHS we have to deep copy
the dynamic (allocatable, automatic) components from RHS to the temp.
Otherwise, the conflict may still be present between LHS and temp.

gfortran/regression/alloc_comp_assign_1.f90 is an example where the current
runtime code produces wrong result:
7b5b5dcbf9/Fortran/gfortran/regression/alloc_comp_assign_1.f90 (L50)

Reviewed By: klausler, tblah

Differential Revision: https://reviews.llvm.org/D156364
2023-07-27 13:56:13 -07:00
Slava Zakharin
3a4e9f7ae5 [flang][hlfir] Do not dereference unallocated entities in structure constructor.
Component-by-component assignment must be able to handle unallocated
allocatable values in structure constructor. F2018 7.5.10 p. 7 states
that the component must have unallocated status as a result of such
construction. The structure constructor temporary is initialized
such that all the allocatable components are unallocated, so we just
need to make sure not to do the component assignment if RHS is deallocated.

Depends on D152482  (the same LIT test is affected)

Reviewed By: jeanPerier, tblah

Differential Revision: https://reviews.llvm.org/D152493
2023-06-27 14:08:35 -07:00
Slava Zakharin
6e4984a9d5 [flang][hlfir] Enable assignments with allocatable components.
The TODO was left there to verify that Assign() runtime handles
overlaps of allocatable components. It did not, and this change-set
fixes it. Note that the same Assign() issue can be reproduced
without HLFIR. In the following example the LHS would be reallocated
before value of RHS (essentially, the same memory) is read:
```
program main
  type t1
     integer, allocatable :: a(:)
  end type t1
  type(t1) :: x, y
  allocate(x%a(10))
  do i =1,10
     x%a(i) = 2*i
  end do
  x = x
  print *, x%a
  deallocate(x%a)
end program main
```

The test's output would be incorrect (though, this depends on the memory
reuse by malloc):
0 0 0 0 10 12 14 16 18 20

It is very hard to add a Flang unittest exploiting derived types.

Reviewed By: klausler

Differential Revision: https://reviews.llvm.org/D152306
2023-06-06 20:25:07 -07:00
Slava Zakharin
da60b9e7dc [flang] Fixed managing copy-in/copy-out temps.
There are several observations regarding the copy-in/copy-out:
  * Actual argument associated with INTENT(OUT) dummy argument that
    requires finalization (7.5.6.3 p. 7) may be read by the finalization
    function, so a copy-in is required.
  * A temporary created for the copy-in/copy-out must be destroyed
    without finalization after the call (or after the corresponding copy-out),
    otherwise, memory leaks may occur.
  * The copy-out assignment must not perform finalization for the LHS.
  * The copy-out assignment from the temporary to the actual argument
    may or may not need to initialize the LHS.

This change-set introduces new runtime methods: CopyOutAssign and
DestroyWithoutFinalization. They are called by the compiler generated
code to match the behavior described above.

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D151135
2023-05-23 09:35:17 -07:00
Slava Zakharin
bf53645634 [flang][runtime] Fixed memory leak in Assign().
The temporary descriptor must be either Pointer or Allocatable,
otherwise its memory will not be freed.

Reviewed By: klausler

Differential Revision: https://reviews.llvm.org/D150534
2023-05-15 10:48:46 -07:00
Slava Zakharin
7c7ffa7bab [flang][runtime] Fixed dimension offset computation for MayAlias.
Reviewed By: klausler

Differential Revision: https://reviews.llvm.org/D150533
2023-05-15 10:48:45 -07:00
Slava Zakharin
1aff61ecbf [flang][runtime] Initialize LHS temporary in AssignTemporary.
If LHS is of derived type that needs initialization, then it must be
initialized before doing the assignment. Otherwise, the assignment
might behave incorrectly based on uninitialized components that are
descriptors themselves.

Differential Revision: https://reviews.llvm.org/D149681
2023-05-03 09:19:35 -07:00
Jean Perier
1ac31a0bfa [flang][runtime] Fix padding in CHARACTER(4) assignments.
One piece of pointer arithmetic was adding the number of bytes instead
of the number of characters. This caused failures in CHARACTER(KIND>1)
that required padding.
This was caught using HLFIR that currently uses the runtime for array
assignment where the current lowering does everything inline.

Reviewed By: vzakhari, klausler

Differential Revision: https://reviews.llvm.org/D149062
2023-04-25 09:05:46 +02:00
Valentin Clement
3acdd596c0
[flang] Handle correctly user defined assignment for allocatable component
In the Fortran standard 2018 section 10.2.1.3 (13), it is mentioned
that all noncoarray allocatable component must follow this sequence of
operations:

1) If the component of the variable is allocated, it is deallocated.
2) If the component of the value of expr is allocated, the corresponding
   component of the variable is allocated with the same dynamic type and
   type parameters as the component of the value of expr. If it is an
   array, it is allocated with the same bounds. The value of the
   component of the value of expr is then assigned to the corresponding
   component of the variable using defined assignment if the declared type
   of the component has a type-bound defined assignment consistent with the
   component, and intrinsic assignment for the dynamic type of that component
   otherwise.

This patch updates the code to make use of the user defined assignment for
allocatable component and make sure the component is allocated correctly.

Reviewed By: klausler

Differential Revision: https://reviews.llvm.org/D147797
2023-04-07 11:47:54 -07:00
Peter Klausler
9c3550f69a [flang][runtime] Use Descriptor::Establish() in elemental derived type defined assignment calls
The code in DoElementalDefinedAssignment() needs to establish its
to & from per-element descriptors with Establish() rather than
copying an array's descriptor and then setting its rank to zero;
the current technique loses the information in the addendum.

Differential Revision: https://reviews.llvm.org/D145753
2023-03-10 10:26:22 -08:00
Peter Klausler
8489f17713 [flang][runtime] Handle explicit-length character padding & truncation in Assign()
When the left-hand side of an allocatable assignment has an explicit character length,
rather than a deferred length that might imply reallocation, handle any discrepancy
in lengths via truncation or blank padding.

Differential Revision: https://reviews.llvm.org/D145111
2023-03-02 10:33:59 -08:00
Jean Perier
5226f8a943 [flang][runtime] Add API to help with the difficult array constructor cases
This runtime API can be used to lower any flavor of array constructors,
but is mainly intended to be used with:

- array constructors for which the extent or length parameters cannot
 be computed without lowering some ac-value or ac-implied-do-control
 that cannot be pre-evaluated.

- array constructors of a derived type with allocatable component where
 copy is not trivial or PDTS.

Example of use cases:
 - `[((i+j,i=1, ifoo()), j=1,n)]` where ifoo() is not pure.
 - `[return_allocatable_array(), return_allocatable_array()]`

Differential Revision: https://reviews.llvm.org/D144411
2023-02-22 09:16:09 +01:00
Valentin Clement
5c988cba4a
[flang] Use derivedType from toAddedum to get updated components
When the rhs is polymorphic and allocated during assignment, the
derivedType might have change from the one set in `toDerived`.
Use the one set in the addendum so it is always up to date.

This can happen in cases like the one shown below:

```
type :: t1
end type t1

type, extends(t1) :: t2
  integer, allocatable :: i(:)
end type

subroutine assign(t)
  class(t2), intent(in) :: t
  class(t1), allocatable :: cp

  cp = t
end subroutine
```

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D144171
2023-02-16 14:54:14 +01:00
Peter Klausler
74a5d7471f [flang][runtime] MayAlias() must be false for unallocated descriptors
When either descriptor argument to MayAlias() is not allocated, the
result must be false by definition, since the values of the extents
in the dimensional information may be uninitialized.

Differential Revision: https://reviews.llvm.org/D144134
2023-02-15 13:25:16 -08:00
Peter Klausler
114ce273d8 [flang][runtime] Fix typo in assign.cpp
Variable name 'y' needs to be used in the declaration of 'yDesc'.

Differential Revision: https://reviews.llvm.org/D144117
2023-02-15 10:12:43 -08:00
Peter Klausler
755535b5eb [flang][runtime] Handle aliasing in Assign()
Detect and handle LHS/RHS aliasing when effecting intrinsic
assignments via the Assign() runtime function.

Also: don't apply special handling for allocatable LHS when calling
a user-defined type-bound ASSIGNMENT(=) generic procedure for a
polymorphic type, and refactor some code into utility functions to
make Assign() more comprehensible.

Differential Revision: https://reviews.llvm.org/D144026
2023-02-14 09:54:08 -08:00
Valentin Clement
da3e477088
[flang] Avoid double finalization in Assign
First call to Assign is issuing finalization for the
LHS and its components. Avoid calling finalization for components
again when doing the component by component assignment.

Reviewed By: klausler

Differential Revision: https://reviews.llvm.org/D143187
2023-02-02 18:03:19 +01:00
Peixin Qiao
f783c9bbbe [flang] Support allocate array from scalar source in runtime
As Fortran 2018 9.7.1.2(7), the value of each element of allocate object
becomes the value of source when the allocate object is array and the
source is scalar.

Fix #60090.

Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D142112
2023-02-01 21:09:02 +08:00
Peixin Qiao
8c77c011c1 [flang] Initial support of allocate statement with source
Support allocate statement with source in runtime version. The source
expression is evaluated only once for each allocate statement. When the
source expression has shape-spec, uses it for bounds. Otherwise, get
the bounds from the source expression. Get the length if the source
expression has deferred length parameter.

Reviewed By: clementval, jeanPerier

Differential Revision: https://reviews.llvm.org/D137812
2023-01-13 20:40:51 +08:00
peter klausler
6d44387e21 [flang] Make subscript list argument a nullable pointer
Component::CreatePointerDescriptor unconditionally expects a
vector of subscripts to be passed as an argument, but is called
from NAMELIST input with a null pointer.  Make that argument
a nullable pointer, move it to the end of the argument list,
and give it a default value of nullptr.

Differential Revision: https://reviews.llvm.org/D113312
2021-11-08 11:53:13 -08:00
Peter Klausler
830c0b9023 [flang] Move runtime API headers to flang/include/flang/Runtime
Move the closure of the subset of flang/runtime/*.h header files that
are referenced by source files outside flang/runtime (apart from unit tests)
into a new directory (flang/include/flang/Runtime) so that relative
include paths into ../runtime need not be used.

flang/runtime/pgmath.h.inc is moved to flang/include/flang/Evaluate;
it's not used by the runtime.

Differential Revision: https://reviews.llvm.org/D109107
2021-09-03 11:08:34 -07:00
peter klausler
65f5290432 [flang] Implement runtime Assign()
Define an API for, and implement, runtime support for arbitrary
assignment of one descriptor's data to another, with full support for
(re)allocation of allocatables with finalization when necessary,
user-defined derived type assignment TBP calls, and intrinsic (default)
componentwise assignment of derived type instances with allocation of
automatic components.  Also clean up API and implementation of
finalization/destruction using knowledge gained while studying
edge cases for assignment in the 2018 standard.

The look-up procedure for special procedure bindings in derived
types has been optimized from O(N) to O(1) since it will probably
matter more.  This required some analysis in runtime derived type
description table construction in semantics and some changes to the
table schemata.

Executable Fortran tests have been developed; they'll be added
to the test base once they can be lowered and run by f18.

Differential Revision: https://reviews.llvm.org/D107678
2021-08-09 09:31:32 -07:00