This patch implements support for the VECTOR ALWAYS directive, which forces vectorization to occurr when possible regardless of a decision by the cost model. This is done by adding an attribute to the branch into the loop in LLVM to indicate that the loop should always be vectorized. This patch only implements this directive on plan structured do loops without labels. Support for unstructured loops and array expressions is planned for future patches.
98 lines
4.4 KiB
Markdown
98 lines
4.4 KiB
Markdown
<!--===- docs/Directives.md
|
|
|
|
Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
See https://llvm.org/LICENSE.txt for license information.
|
|
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
-->
|
|
|
|
# Compiler directives supported by Flang
|
|
|
|
A list of non-standard directives supported by Flang
|
|
|
|
* `!dir$ fixed` and `!dir$ free` select Fortran source forms. Their effect
|
|
persists to the end of the current source file.
|
|
* `!dir$ ignore_tkr [[(TKRDMAC)] dummy-arg-name]...` in an interface definition
|
|
disables some semantic checks at call sites for the actual arguments that
|
|
correspond to some named dummy arguments (or all of them, by default).
|
|
The directive allow actual arguments that would otherwise be diagnosed
|
|
as incompatible in type (T), kind (K), rank (R), CUDA device (D), or
|
|
managed (M) status. The letter (A) is a shorthand for all of these,
|
|
and is the default when no letters appear. The letter (C) checks for
|
|
contiguity for example allowing an element of an assumed-shape array to be
|
|
passed as a dummy argument. For example, if one wanted to call a "set all
|
|
bytes to zero" utility that could be applied to arrays of any type or rank:
|
|
```
|
|
interface
|
|
subroutine clear(arr,bytes)
|
|
!dir$ ignore_tkr arr
|
|
integer(1), intent(out) :: arr(bytes)
|
|
end
|
|
end interface
|
|
```
|
|
* `!dir$ assume_aligned desginator:alignment`, where designator is a variable,
|
|
maybe with array indices, and alignment is what the compiler should assume the
|
|
alignment to be. E.g A:64 or B(1,1,1):128. The alignment should be a power of 2,
|
|
and is limited to 256.
|
|
[This directive is currently recognised by the parser, but not
|
|
handled by the other parts of the compiler].
|
|
* `!dir$ vector always` forces vectorization on the following loop regardless
|
|
of cost model decisions. The loop must still be vectorizable.
|
|
[This directive currently only works on plain do loops without labels].
|
|
|
|
# Directive Details
|
|
|
|
## Introduction
|
|
Directives are commonly used in Fortran programs to specify additional actions
|
|
to be performed by the compiler. The directives are always specified with the
|
|
`!dir$` or `cdir$` prefix.
|
|
|
|
## Loop Directives
|
|
Some directives are associated with the following construct, for example loop
|
|
directives. Directives on loops are used to specify additional transformation to
|
|
be performed by the compiler like enabling vectorisation, unrolling, interchange
|
|
etc.
|
|
|
|
Currently loop directives are not accepted in the presence of OpenMP or OpenACC
|
|
constructs on the loop. This should be implemented as it is used in some
|
|
applications.
|
|
|
|
### Array Expressions
|
|
It is to be decided whether loop directives should also be able to be associated
|
|
with array expressions.
|
|
|
|
## Semantics
|
|
Directives that are associated with constructs must appear in the same section
|
|
as the construct they are associated with, for example loop directives must
|
|
appear in the executable section as the loops appear there. To facilitate this
|
|
the parse tree is corrected to move such directives that appear in the
|
|
specification part into the execution part.
|
|
|
|
When a directive that must be associated with a construct appears, a search
|
|
forward from that directive to the next non-directive construct is performed to
|
|
check that that construct matches the expected construct for the directive.
|
|
Skipping other intermediate directives allows multiple directives to appear on
|
|
the same construct.
|
|
|
|
## Lowering
|
|
Evaluation is extended with a new field called dirs for representing directives
|
|
associated with that Evaluation. When lowering loop directives, the associated
|
|
Do Loop's evaluation is found and the directive is added to it. This information
|
|
is used only during the lowering of the loop.
|
|
|
|
### Representation in LLVM
|
|
The `llvm.loop` metadata is used in LLVM to provide information to the optimizer
|
|
about the loop. For example, the `llvm.loop.vectorize.enable` metadata informs
|
|
the optimizer that a loop can be vectorized without considering its cost-model.
|
|
This attribute is added to the loop condition branch.
|
|
|
|
### Representation in MLIR
|
|
The MLIR LLVM dialect models this by an attribute called LoopAnnotation
|
|
Attribute. The attribute can be added to the latch of the loop in the cf
|
|
dialect and is then carried through lowering to the LLVM dialect.
|
|
|
|
## Testing
|
|
Since directives must maintain a flow from source to LLVM IR, an integration
|
|
test is provided that tests the `vector always` directive, as well as individual
|
|
lit tests for each of the parsing, semantics and lowering stages.
|