The structure is
- OmpBeginDirective (aka OmpDirectiveSpecification)
- Block
- optional<OmpEndDirective> (aka optional<OmpDirectiveSpecification>)
The OmpBeginDirective and OmpEndDirective are effectively different
names for OmpDirectiveSpecification. They exist to allow the semantic
analyses to distinguish between the beginning and the ending of a block
construct without maintaining additional context.
The actual changes are in the parser: parse-tree.h and openmp-parser.cpp
in particular. The rest is simply changing the way the directive/clause
information is accessed (typically for the simpler).
All standalone and block constructs now use OmpDirectiveSpecification to
store the directive/clause information.
When blank tokens arise from macro replacement in token sequences with
token pasting (##), the preprocessor is producing some bogus tokens
(e.g., "name(") that can lead to subtle bugs later when macro names are
not recognized as such.
The fix is to not paste tokens together when the result would not be a
valid Fortran or C token in the preprocessing context.
Name resolution defers the analysis of all object pointer initializers
to the end of a specification part, including the default initializers
of derived type data pointer components. This deferment allows object
pointer initializers to contain forward references to objects whose
declarations appear later.
However, this deferment has the unfortunate effect of causing NULL
default initialization of such object pointer components when they do
not appear in structure constructors that are used as default
initializers, and their default initializers are required. So handle
object pointer default initializers of components as they appear, as
before.
Both the declare mapper directive argument, and the iterator modifier
can contain declaration-type-spec, so make sure that the processing of
one ends before processing of the other begins in semantic analysis.
Although taskgroup is a privatizing construct, because of
task_reduction clause, a new scope was not being created for it.
This could cause an extra privatization of variables when
taskgroup was lowered, because its scope would be the same as of
the parent privatizing construct.
This fixes regressions in tests 1052_0201 and 1052_0205, from
Fujitsu testsuite.
This issue didn't happen before because implicit symbols were
being created in a different way before #142154.
`SetImplicitCUDADevice` looks for `symbol.has<ObjectEntityDetails>()` to
set the device attribute before symbols inside block constructs are
converted to ObjectEntity. Fix is to move the call to
`SetImplicitCUDADevice` after those symbols are converted.
The parser will accept a wide variety of illegal attempts at forming an
ATOMIC construct, leaving it to the semantic analysis to diagnose any
issues. This consolidates the analysis into one place and allows us to
produce more informative diagnostics.
The parser's outcome will be parser::OpenMPAtomicConstruct object
holding the directive, parser::Body, and an optional end-directive. The
prior variety of OmpAtomicXyz classes, as well as OmpAtomicClause have
been removed. READ, WRITE, etc. are now proper clauses.
The semantic analysis consistently operates on "evaluation"
representations, mainly evaluate::Expr (as SomeExpr) and
evaluate::Assignment. The results of the semantic analysis are stored in
a mutable member of the OpenMPAtomicConstruct node. This follows a
precedent of having `typedExpr` member in parser::Expr, for example.
This allows the lowering code to avoid duplicated handling of AST nodes.
Using a BLOCK construct containing multiple statements for an ATOMIC
construct that requires multiple statements is now allowed. In fact, any
nesting of such BLOCK constructs is allowed.
This implementation will parse, and perform semantic checks for both
conditional-update and conditional-update-capture, although no MLIR will
be generated for those. Instead, a TODO error will be issues prior to
lowering.
The allowed forms of the ATOMIC construct were based on the OpenMP 6.0
spec.
According to the OpenMP standard, variables with static storage duration
are predetermined as shared.
Add a check when creating implicit symbols for OpenMP to fix them
erroneously getting set to firstprivate.
Fixes llvm#140732.
---------
Signed-off-by: Kajetan Puchalski <kajetan.puchalski@arm.com>
This adds another puzzle piece for the support of OpenMP DECLARE
REDUCTION functionality.
This adds support for operators with derived types, as well as declaring
multiple different types with the same name or operator.
A new detail class for UserReductionDetials is introduced to hold the
list of types supported for a given reduction declaration.
Tests for parsing and symbol generation added.
Declare reduction is still not supported to lowering, it will generate a
"Not yet implemented" fatal error.
Fixes#141306Fixes#97241Fixes#92832Fixes#66453
---------
Co-authored-by: Mats Petersson <mats.petersson@arm.com>
DeclareSimdConstruct (and other declarative constructs) can currently
implicitly declare variables regardless of whether the source code
contains "implicit none" or not. This causes semantic analysis issues if
the implicit type does not match the declared type. To solve it, skip
implicit typing for OpenMPDeclarativeConstruct. Fixes issue #140754.
---------
Signed-off-by: Kajetan Puchalski <kajetan.puchalski@arm.com>
Add a visitor for OmpClause::Uniform to resolve its parameter names.
Add Symbol::Flag::OmpUniform to attach it to the resolved symbols.
Fixes issue #140741.
---------
Signed-off-by: Kajetan Puchalski <kajetan.puchalski@arm.com>
A dummy argument with an explicit INTEGER type of non-default kind can
be forward-referenced from a specification expression in many Fortran
compilers. Handle by adding type declaration statements to the initial
pass over a specification part's declaration constructs. Emit an
optional warning under -pedantic.
Fixes https://github.com/llvm/llvm-project/issues/140941.
The current semantic check in place is incorrect, this patch fixes this.
Up to 1 **'default'** named mapper should be allowed for each derived
type.
The current semantic check only allows up to 1 **'default'** named
mapper across all derived types.
This also makes sure that declare mappers follow proper scoping rules
for both default and named mappers.
Co-authored-by: Raghu Maddhipatla <Raghu.Maddhipatla@amd.com>
Support is added for parsing. Basic semantics support is added to
forward the code to Lowering. Lowering will emit a TODO error. Detailed
semantics checks and lowering is further work.
This PR:
- makes Cray pointer declarations shadow previous bindings instead of
modifying them,
- errors when the pointee of a cray pointee has the SAVE attribute, and
- adds a missing newline after dumping the list of cray pointers in a
scope.
Closes#135579
The output of a compilation with the -fdebug-unparse-with-modules option
comprises its normal unparsed output along with the regenerated contents
of any modules that were required from module files. This is handy for
producing stand-alone test cases.
The modules' contents are generated by the same code that writes module
files, so they can contain some USE associations to private entities in
other modules that are necessary to complete local declarations, usually
initializers. Such USE associations to private entities are not flagged
as fatal errors when modules are read from module files, but they
currently are caught when the output produced by this option is being
read back in to the compiler.
Handle this case by softening the error to a warning when one module
uses a private entity from another with an alias containing the
non-conforming '$' character. (I could have omitted the message
altogether, but there are other valid warnings that will occur due to
undefined function result variables; further, I didn't want to provide a
general hole around the protection of private names.)
A function or subroutine can allow an object of the same name to appear
in its scope, so long as the name is not used. This is similar to the
case of a name being imported from multiple distinct modules, and
implemented by the same representation.
It's not clear whether this is conforming behavior or a common
extension.
Hi,
This patch implements support for the following directives :
- `!DIR$ NOUNROLL_AND_JAM` to disable unrolling and jamming on a DO
LOOP.
- `!DIR$ NOUNROLL` to disable unrolling on a DO LOOP.
- `!DIR$ NOVECTOR` to disable vectorization on a DO LOOP.
The `OmpDirectiveSpecification` contains directive name, the list of
arguments, and the list of clauses. It was introduced to store the
directive specification in METADIRECTIVE, and could be reused everywhere
a directive representation is needed.
In the long term this would unify the handling of common directive
properties, as well as creating actual constructs from METADIRECTIVE by
linking the contained directive specification with any associated user
code.
…UCTION
This patch allows better parsing of the reduction and initializer
components, including supporting derived types in both those places.
There is more work needed here, but this is a definite improvement in
what can be handled through parser and semantics.
Note that declare reduction is still not supported in lowering, so any
attempt to compile DECLARE REDUCTION code will end with a TODO aka "Not
yet implemented" abort in the compiler.
Note that this version of the code does not cover declaring multiple
reductions using the same name with different types. This is will be
fixed in a future patch. [This was also the case before this change].
One existing test modified to actually compile (as it didn't in the
original form).
Then use this in the Flang compiler for parsing the OpenMP declare
reduction.
This has no real functional change to the existing code, it's only
moving the declaration itself around.
A few tests has been updated, to reflect the new type names.
Previously, nested scopes for implied DO loops with DATA statements were
disallowed, which meant that the following code couldn't compile due to
re-use of `j` loop variable name:
DATA (a(i),(b(i,j),j=1,3),(c(i,j),j=1,3),i=0,4)/
This change allows nested scopes implied DO loops, which allows the code
above to compile.
Tests modified to in accordance with this change:
Semantics/resolve40.f90, Semantics/symbol09.f90
Refine handling of NULL(...) in semantics to properly distinguish
NULL(), NULL(objectPointer), NULL(procPointer), and NULL(allocatable)
from each other in relevant contexts.
Add IsNullAllocatable() and IsNullPointerOrAllocatable() utility
functions. IsNullAllocatable() is true only for NULL(allocatable); it is
false for a bare NULL(), which can be detected independently with
IsBareNullPointer().
IsNullPointer() now returns false for NULL(allocatable).
ALLOCATED(NULL(allocatable)) now works, and folds to .FALSE.
These utilities were modified to accept const pointer arguments rather
than const references; I usually prefer this style when the result
should clearly be false for a null argument (in the C sense), and it
helped me find all of their use sites in the code.
The DECLARE REDUCTION allows the initialization part to be either an
expression or a call to a subroutine.
This modifies the parsing and semantic analysis to allow the use of the
subroutine, in addition to the simple expression that was already
supported.
New tests in parser and semantics sections check that the generated
structure is as expected.
DECLARE REDUCTION lowering is not yet implemented, so will end in a
TODO. A new test with an init subroutine is added, that checks that this
variant also ends with a "Not yet implemented" message.
A few bits of semantic checking need a variant of the
ResolveAssociations utility function that stops when hitting a construct
entity for a type or class guard. This is necessary for cases like the
bug below where the analysis is concerned with the type of the name in
context, rather than its shape or storage or whatever. So add a flag to
ResolveAssociations and GetAssociationRoot to make this happen, and use
it at the appropriate call sites.
Fixes https://github.com/llvm/llvm-project/issues/128608.
A derived type with a component of the same name as the type is not
extensible... unless the extension occurs in another module where the
conflicting component is inaccessible.
Fixes https://github.com/llvm/llvm-project/issues/126114.
This patch implements support for the UNROLL_AND_JAM directive to enable
or disable unrolling and jamming on a `DO LOOP`.
It must be placed immediately before a `DO LOOP` and applies only to the
loop that follows. N is an integer that specifying the unrolling factor.
This is done by adding an attribute to the branch into the loop in LLVM
to indicate that the loop should unrolled and jammed.
Part of the DECLARE REDUCTION was already supported by the parser, but
the semantics to add the reduction identifier wasn't implemented.
The semantics would not accept the name given by the reduction, so a few
lines added to support that.
Some tests were in place but not quite working, so fixed those up too.
Adding new tests for unparsing and parse-tree, as well as checking the
symbolic name being generated.
Lowering of DECLARE REDUCTION is not supported in this patch, and a test
that it hits the relevant TODO is in this patch (most of this was
already existing, but not actually testing the TODO message).
Move non-common files from FortranCommon to FortranSupport (analogous to
LLVMSupport) such that
* declarations and definitions that are only used by the Flang compiler,
but not by the runtime, are moved to FortranSupport
* declarations and definitions that are used by both ("common"), the
compiler and the runtime, remain in FortranCommon
* generic STL-like/ADT/utility classes and algorithms remain in
FortranCommon
This allows a for cleaner separation between compiler and runtime
components, which are compiled differently. For instance, runtime
sources must not use STL's `<optional>` which causes problems with CUDA
support. Instead, the surrogate header `flang/Common/optional.h` must be
used. This PR fixes this for `fast-int-sel.h`.
Declarations in include/Runtime are also used by both, but are
header-only. `ISO_Fortran_binding_wrapper.h`, a header used by compiler
and runtime, is also moved into FortranCommon.
When -fimplicit-none-ext is passed, flang behaves as if "implicit
none(external)" was specified for all relevant constructs in Fortran
source file.
Note: implicit17.f90 was based on implicit07.f90 with `implicit
none(external)` removed and `-fimplicit-none-ext` added.
Implement parsing and symbol resolution for directives that take
arguments. There are a few, and most of them take objects. Special
handling is needed for two that take more specialized arguments: DECLARE
MAPPER and DECLARE REDUCTION.
This only affects directives in METADIRECTIVE's WHEN and OTHERWISE
clauses. Parsing and semantic checks of other cases is unaffected.
Some errors aren't being caught, such as the case in the linked bug
where the PAD= argument to RESHAPE() didn't have the same declared type
as the ARRAY=; this led to a crash in lowering. Refine the "same type"
testing logic for intrinsic procedures, and add a better test.
Fixes https://github.com/llvm/llvm-project/issues/124976.
A USE statement within a submodule (possibly in a nested scope) is not
allowed to USE the submodule's ancestor module directly, but it is
permissible to USE that ancestor module indirectly via another unrelated
module. Don't emit "already present in scope" errors for this case.
Fixes https://github.com/llvm/llvm-project/issues/124731.
This patch implements support for the UNROLL directive to control how
many times a loop should be unrolled.
It must be placed immediately before a `DO LOOP` and applies only to the
loop that follows. N is an integer that specifying the unrolling factor.
This is done by adding an attribute to the branch into the loop in LLVM
to indicate that the loop should unrolled.
The code pushed to support the directive `VECTOR ALWAYS` has been
modified to take account of the fact that several directives can be used
before a `DO LOOP`.
Catch and report multiple initializations of the same procedure pointer
rather than assuming that control wouldn't reach a given point in name
resolution in that case.
Fixes https://github.com/llvm/llvm-project/issues/123538.