When the argument is a parent component the box needs to
be updated to reflect the correct type. Use `updateBoxForParentComponent`
to update the argument accordingly.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D145907
A handful of I/O statements (OPEN, CLOSE, positioning) are not allowed
on units during child I/O; catch violations and report errors.
Also finesse error handling during FORMAT runtime parsing of DT
derived type edit descriptors, and ensure that formatted child
I/O is nonadvancing.
Differential Revision: https://reviews.llvm.org/D145751
Non-DEFERRED procedure binding checking can't blindly accept
all procedures defined in modules -- they can't be ABSTRACT
interfaces. And GetUltimate() must be used rather than
FindSubprogram(); the latter will resolve to a procedure's
interface in the case of "procedure(interface) :: external",
not "external".
Differential Revision: https://reviews.llvm.org/D145749
As a near-universal extension, Fortran compilers permit forward references
to dummy arguments and variables in COMMON blocks from specification expressions
before an explicit type-declaration-stmt appears for those variables
under IMPLICIT NONE, so long as those variables are later explicitly typed
with the types that regular implicit typing rules would have given them
(usually default INTEGER).
F18 implemented this extension for dummy arguments, but not variables in
COMMON blocks. Extend the extension to also accept variables in COMMON.
Differential Revision: https://reviews.llvm.org/D145743
When a parameterized derived type has FINAL subroutines, only
those FINAL subroutines whose dummy argument's type matches the
type parameter values of a particular instantiation are relevant
to that instantiation.
Differential Revision: https://reviews.llvm.org/D145741
When a substring appears as the MOLD= argument to TRANSFER(),
it's possible for the compiler to assert if it can't figure
out a constant length for the substring. Fix.
Differential Revision: https://reviews.llvm.org/D145740
Thin and full LTO modes use different pre-link pipelines compared to
regular compilation. This patch adds support for calling those pipelines.
This patch closely mimics Clang's implementation with the exception that I
changed the codegen option name from `PrepareForLTO` to `PrepareForFullLTO`
to be more precise.
With this patch:
- Compilation for full LTO should be as we expect (except possibly
missing optimizations enabled by module summaries which we do not
produce yet).
- thinLTO uses the correct prelink pipeline but will use the postlink
backend for fullLTO due to missing metadata and summary in the llvm
module. I have added a warning regarding this: `flang-new: warning: the
option '-flto=thin' is a work in progress`.
Differential Revision: https://reviews.llvm.org/D142420
Change-Id: I6b94b775b5b8e93340e520c5cd4bf60834b2e209
fir.if currently isn't treated as a 'proper' conditional, so passes are unable to determine which regions are executed at times.
This patch gives fir.if this interface, which shouldn't do too much on its own but should allow future changes to take advantage
for various purposes
Reviewed By: vzakhari
Differential Revision: https://reviews.llvm.org/D145165
Adds the -fopenmp-is-device flag to bbc and Flang's -fc1 (but not flang-new) and in addition adds an omp.is_device attribute onto the module when fopenmp is passed, this is a boolean attribute that is set to false or true dependent on if fopenmp-is-device is specified alongside the fopenmp flag on the commandline when invoking flang or bbc.
Reviewers:
awarzynski
kiranchandramohan
Differential Revision: https://reviews.llvm.org/D144864
Optional character function arguments were not being lowered
properly. As they are passed as a tuple, containing the (boxed)
function address and the character length, it is not possible for
fir.absent to handle it directly. Instead, a tuple needs to be
created and filled with an absent function address and a dummy
character length.
Fixes#60225
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D144743
Intrinsic module procedures are a bit different from intrinsic
procedures: they are defined in intrinsic module files, but their
signature and representation in semantics is the same as user
procedures.
The code to lower them in lowering (when they are not implemented in
Fortran) is the same as for intrinsic procedures
(Optimizer/Builder/IntrinsicCall.cpp).
The dispatching in in HLFIR procedure reference lowering must be
slightly modified so that these evaluate::ProcRef that have a
semantics::Symbol instead of an evaluate::SpecificIntrinsic can
be dispatched as evaluate::SpecificIntrinsic:
- move isIntrinsicModuleProcedure to detect them
- in the helpers dealing with intrinsics, make evaluate::SpecificIntrinsic
a pointer argument that can be null for intrinsic module procedures.
- add getProcedureName() to call context to avoid relying on the
evaluate::SpecificIntrinsic when it is not know to be null.
Differential Revision: https://reviews.llvm.org/D145360
- use AssignExplicitLengthCharacter for assignment to whole allocatable
character with assumed or explicit length.
- use AssignPolymorphic for assignment to whole allocatable
polymorphic.
Differential Revision: https://reviews.llvm.org/D145363
Make use of the new runtime entry point for assignment to
LHS allocatable polymorphic.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D145324
When a global procedure has no explicit interface, emit warnings
when its references are inconsistent implicit procedure interfaces.
Differential Revision: https://reviews.llvm.org/D145097
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
The Fortran standard's various restrictions on the use of BIND(C)
often depend more on the presence or absence of an explicit NAME=
specification rather than on its value, but semantics and module
file generation aren't making distinctions between explicit NAME=
specifications that happen to match the default name and declarations
that don't have NAME=. Tweak semantics and module file generation
to conform, and also complain when named BIND(C) attributes are
erroneously applied to entities that can't support them, like
ABSTRACT interfaces.
Differential Revision: https://reviews.llvm.org/D145107
The test for compatible function results needs to be nearly strict
equality of their types, not the usual actual/dummy type compatibility
test used in other situations. The exceptional case is that assumed
length CHARACTER function results are compatible with explicit length
results of the same kind. In particular, a function returning a
polymorphic pointer is not compatible with a function returning a
monomorphic pointer even of the same declared type.
Differential Revision: https://reviews.llvm.org/D145094
Relax a bit the condition added in D144417 and allow scalar polymorphic entities
and boxed scalar record type.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D145058
Update move_alloc to carry over the dyanmic type of `from` to `to`
and reset the dynamic type of `from` to its declared type when it
is polymorphic.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D144997
A block construct is an execution control construct that supports
declaration scopes contained within a parent subprogram scope or another
block scope. (blocks may be nested.) This is implemented by applying
basic scope processing to the block level.
Name uniquing/mangling is extended to support this. The term "block" is
heavily overloaded in Fortran standards. Prior name uniquing used tag `B`
for common block objects. Existing tag choices were modified to free up `B`
for block construct entities, and `C` for common blocks, and resolve
additional issues with other tags. The "old tag -> new tag" changes can
be summarized as:
-> B -- block construct -> new
B -> C -- common block
C -> YI -- intrinsic type descriptor; not currently generated
CT -> Y -- nonintrinsic type descriptor; not currently generated
G -> N -- namelist group
L -> -- block data; not needed -> deleted
Existing name uniquing components consist of a tag followed by a name
from user source code, such as a module, subprogram, or variable name.
Block constructs are different in that they may be anonymous. (Like other
constructs, a block may have a `block-construct-name` that can be used
in exit statements, but this name is optional.) So blocks are given a
numeric compiler-generated preorder index starting with `B1`, `B2`,
and so on, on a per-procedure basis.
Name uniquing is also modified to include component names for all
containing procedures rather than for just the immediate host. This
fixes an existing name clash bug with same-named entities in same-named
host subprograms contained in different-named containing subprograms,
and variations of the bug involving modules and submodules.
F18 clause 9.7.3.1 (Deallocation of allocatable variables) paragraph 1
has a requirement that an allocated, unsaved allocatable local variable
must be deallocated on procedure exit. The following paragraph 2 states:
When a BLOCK construct terminates, any unsaved allocated allocatable
local variable of the construct is deallocated.
Similarly, F18 clause 7.5.6.3 (When finalization occurs) paragraph 3
has a requirement that a nonpointer, nonallocatable object must be
finalized on procedure exit. The following paragraph 4 states:
A nonpointer nonallocatable local variable of a BLOCK construct
is finalized immediately before it would become undefined due to
termination of the BLOCK construct.
These deallocation and finalization requirements, along with stack
restoration requirements, require knowledge of block exits. In addition
to normal block termination at an end-block-stmt, a block may be
terminated by executing a branching statement that targets a statement
outside of the block. This includes
Single-target branch statements:
- goto
- exit
- cycle
- return
Bounded multiple-target branch statements:
- arithmetic goto
- IO statement with END, EOR, or ERR specifiers
Unbounded multiple-target branch statements:
- call with alternate return specs
- computed goto
- assigned goto
Lowering code is extended to determine if one of these branches exits
one or more relevant blocks or other constructs, and adds a mechanism to
insert any necessary deallocation, finalization, or stack restoration
code at the source of the branch. For a single-target branch it suffices
to generate the exit code just prior to taking the indicated branch.
Each target of a multiple-target branch must be analyzed individually.
Where necessary, the code must first branch to an intermediate basic
block that contains exit code, followed by a branch to the original target
statement.
This patch implements an `activeConstructStack` construct exit mechanism
that queries a new `activeConstruct` PFT bit to insert stack restoration
code at block exits. It ties in to existing code in ConvertVariable.cpp
routine `instantiateLocal` which has code for finalization, making block
exit finalization on par with subprogram exit finalization. Deallocation
is as yet unimplemented for subprograms or blocks. This may result in
memory leaks for affected objects at either the subprogram or block level.
Deallocation cases can be addressed uniformly for both scopes in a future
patch, presumably with code insertion in routine `instantiateLocal`.
The exit code mechanism is not limited to block construct exits. It is
also available for use with other constructs. In particular, it is used
to replace custom deallocation code for a select case construct character
selector expression where applicable. This functionality is also added
to select type and associate constructs. It is available for use with
other constructs, such as select rank and image control constructs,
if that turns out to be necessary.
Overlapping nonfunctional changes include eliminating "FIR" from some
routine names and eliminating obsolete spaces in comments.
Add a HLFIR operation for the TRANSPOSE transformational intrinsic,
according to the design set out in flang/doc/HighLevelFIR.md
Differential Revision: https://reviews.llvm.org/D144880
In Fortran, it is possible to refer to the "parent part" of a derived
type as if it were a component:
```Fortran
type t1
integer :: i
end type
type t2
integer :: j
end type
type(t2) :: a
print *, a%t1%i ! "inner" parent component reference
print *, a%t1 ! "leaf" parent component reference
end
```
Inner parent component references can be dropped on the floor in
lowering: "a%t1%i" is equivalent to "a%i".
Leaf parent component references, however, must be taken care of. For
scalars, "a%t1" is a simple addressc ast to "t1", for arrays, however,
this creates an array section that must be represented with a descriptor
(fir.box).
hlfir.designate could have been extended to deal with this, but I think
it would make hlfir.designate too complex and hard to manipulate.
This patch adds an hlfir.parent_comp op that represents and implements
leaf parent component references.
Differential Revision: https://reviews.llvm.org/D144946
Lower the cases that require runtime support to deal
with the allocation, reallocation, or copy of ac-values to
the array constructor storage.
Differential Revision: https://reviews.llvm.org/D144513
The current code was replacing inquiry to array constructor whose
ac-value shape depends on ac-implied-do-index with an expression
using the ac-implied-do-index without the implied-do (folding the
first case added in the test as in the second case with a regular
symbol).
Differential Revision: https://reviews.llvm.org/D144655
By default evaluate::GetShape(expr) may return a compiler generated expression
using symbols that are part of function interfaces if there are function
references in "expr".
It is not right to replace an inquiry of "expr" with such compiler
generated expression since the call context would be lost, along with
the meaning of the inquiry expression.
Inquiry folding uses GetContextFreeShape(expr) that sets-up
useResultSymbolShape_ in GetShapeHelper to prevent such bad rewrites. But this did not
work properly with array constructor: GetShapeHelper made a call to
GetShape, ignoring and losing the "useResultSymbolShape_" instruction.
Differential Revision: https://reviews.llvm.org/D144512
This change silences a compiler warning: `base class should be explictily initialized in the copy constructor`.
Differential Revision: https://reviews.llvm.org/D144556
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
Add a HLFIR operation for the MATMUL transformational intrinsic,
according to the design set out in flang/doc/HighLevelFIR.md
Differential Revision: https://reviews.llvm.org/D144094
This is the first and biggest chunk that introduces support for
array constructor to HLFIR.
This patch:
- adds a new ConvertArrayConstructor.cpp that centralizes the
code dealing with array constructor lowering.
- introduces a framework to lower array constructor according to
different strategies: A common analysis of the array constructor is
done, and based on that, a lowering startegy is selected and driven
through the ac-values of the array constructor. See
ConvertArrayConstructor.cpp comments for more details.
- implements the first strategy that creates a temporary inlined and
updates it with inlined code. This strategy can only be used if the
temporary can be pre-allocated (i.e: the extents and length parameters
can be pre-computed without evaluating any ac-values), and if all the
ac-value expressions are scalars.
For the sake of simplicity, characters and derived type will be enabled
once all the strategies are added.
Reviewed By: clementval, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D144102
This patch adds parser suppert for the device_type clause used by the Declare Target directive.
Differential Revision: https://reviews.llvm.org/D143671
This patch updates the code added in D143888 to avoid
overwriting some part of the types when updating it
for unlimited polymorphic types.
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D143995
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
MLIR loads dialects lazily so if a hlfir type (or operation) is found
before any fir type (or operation), the fir dialect will not have been
loaded when the hlfir thing is verified. Verification of some hlfir
operations does depend on fir types (e.g. hlfir.sum needs
fir::SequenceType).
Tablegen change recommended by jeanPerier
Differential Revision: https://reviews.llvm.org/D143930
Every component of a BIND(C) interoperable derived type must have an
interoperable type. Semantics was checking components with derived types,
but not components with intrinsic types.
Differential Revision: https://reviews.llvm.org/D143832
When a DATA statement initializes a substring with a character constant
of the wrong length, do the right thing with blank padding or truncation,
and emit a warning. Current code is crashing due to an unhandled error
reported from the low-level data image initialization framework.
Differential Revision: https://reviews.llvm.org/D143819
The recent code that uses an iterative rather than recursive walk
over the parse tree when processing expressions needs to allow for
the rare case in which an intrinsic operator (e.g., +) is extended
by a generic interface in the program.
Differential Revision: https://reviews.llvm.org/D143818
Add an HLFIR operation for the SUM transformational intrinsic, according
to the design set out in flang/doc/HighLevelFIR.md.
I decided to make hlfir.sum very lenient about the form of its
arguments. This allows the sum intrinsic to be lowered to only this HLFIR
operation, without needing several operations to convert and box
arguments. Having only one operation generated for the intrinsic
invocation should make optimisation passes on HLFIR simpler.
Differential Revision: https://reviews.llvm.org/D142897
The intrinsic function DIM can overflow when its second argument
is negative. Detect this case for real and integer arguments and
emit a warning when necessary.
Differential Revision: https://reviews.llvm.org/D143798
In some circumstances, such as in compile-time array shape analysis,
clients of the utility function ResolveAssociations() don't really
want it to drill all of the way down to an assumed-rank dummy argument.
Add a variation, ResolveAssociationsExceptSelectRank(), that
will return a specific rank case's AssocEntity symbol instead.
This fixes a crash in subscript validation checking that stemmed from
deducing an incorrect number of lower and upper bound expressions
from a specific rank case association entity.
Differential Revision: https://reviews.llvm.org/D143778