Skip to content

Commit 8658dc4

Browse files
committed
Add documentation for change in Directives.md
Other misc fixes for review
1 parent 5592699 commit 8658dc4

File tree

9 files changed

+68
-18
lines changed

9 files changed

+68
-18
lines changed

flang/docs/Directives.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,46 @@ A list of non-standard directives supported by Flang
3636
and is limited to 256.
3737
[This directive is currently recognised by the parser, but not
3838
handled by the other parts of the compiler].
39-
* `!dir$ vector always` forces vectorization on the following loop regardless
39+
* `!dir$ vector always` forces vectorization on the following loop regardless
4040
of cost model decisions. The loop must still be vectorizable.
4141
[This directive currently only works on plain do loops without labels].
42+
43+
# Directive Details
44+
45+
## Introduction
46+
Directives are commonly used in Fortran programs to specify additional actions
47+
to be performed by the compiler. The directives are always specified with the
48+
`!dir$` or `cdir$` prefix.
49+
50+
## Loop Directives
51+
Some directives are associated with the following construct, for example loop
52+
directives. Directives on loops are used to specify additional transformation to
53+
be performed by the compiler like enabling vectorisation, unrolling, interchange
54+
etc.
55+
56+
### Array Expressions
57+
It is to be decided whether loop directives should also be able to be associated
58+
with array expressions.
59+
60+
## Semantics
61+
Dirctives that are associated with constructs must appear in the same section as
62+
the construct they are associated with, for example loop directives must appear
63+
in the executable section as the loops appear there. To facilitate this the
64+
parse tree is corrected to move such directives that appear in the specification
65+
part into the execution part.
66+
When a directive that must be associated with a construct appears, a search
67+
forward from that directive to the next non-directive construct is performed to
68+
check that that construct matches the expected construct for the directive.
69+
Skipping other intermediate directives allows multiple directives to appear on
70+
the same construct.
71+
72+
## Lowering
73+
Evaluation is extended with a new field called dirs for representing directives
74+
associated with that Evaluation. When lowering loop directives, the associated
75+
Do Loop's evaluation is found and the directive is added to it. This information
76+
is used only during the lowering of the loop.
77+
78+
## Testing
79+
Since directives must maintain a flow from source to LLVM IR, an integration
80+
test is provided that tests the `vector always` directive, as well as individual
81+
lit tests for each of the parsing, semantics and lowering stages.

flang/include/flang/Optimizer/Dialect/FIROps.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2161,7 +2161,7 @@ def fir_DoLoopOp : region_Op<"do_loop", [AttrSizedOperandSegments,
21612161
OptionalAttr<UnitAttr>:$unordered,
21622162
OptionalAttr<UnitAttr>:$finalValue,
21632163
OptionalAttr<ArrayAttr>:$reduceAttrs,
2164-
OptionalAttr<LoopAnnotationAttr>:$loop_annotation
2164+
OptionalAttr<LoopAnnotationAttr>:$loopAnnotation
21652165
);
21662166
let results = (outs Variadic<AnyType>:$results);
21672167
let regions = (region SizedRegion<1>:$region);

flang/lib/Lower/Bridge.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2598,7 +2598,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
25982598
}
25992599

26002600
void attachDirectiveToLoop(const Fortran::parser::CompilerDirective &dir,
2601-
Fortran::lower::pft::Evaluation *e) {
2601+
Fortran::lower::pft::Evaluation *e) {
26022602
while (e->isDirective())
26032603
e = e->lexicalSuccessor;
26042604

flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,9 @@ class CfgLoopConv : public mlir::OpRewritePattern<fir::DoLoopOp> {
136136
loc, comparison, firstBlock, llvm::ArrayRef<mlir::Value>(), endBlock,
137137
llvm::ArrayRef<mlir::Value>());
138138

139-
if (auto ann = loop.getLoopAnnotation()) {
139+
// Copy loop annotations from the do loop to the loop entry condition.
140+
if (auto ann = loop.getLoopAnnotation())
140141
cond->setAttr("loop_annotation", *ann);
141-
}
142142

143143
// The result of the loop operation is the values of the condition block
144144
// arguments except the induction variable on the last iteration.

flang/lib/Semantics/canonicalize-directives.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
//===-- lib/Semantics/check-directives.cpp --------------------------------===//
1+
//===-- lib/Semantics/canonicalize-directives.cpp
2+
//--------------------------===//
23
//
34
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45
// See https://llvm.org/LICENSE.txt for license information.
@@ -13,7 +14,9 @@ namespace Fortran::semantics {
1314

1415
using namespace parser::literals;
1516

16-
// Check that directives are associated with the correct constructs
17+
// Check that directives are associated with the correct constructs.
18+
// Directives that need to be associated with other constructs in the execution
19+
// part are moved to the execution part so they can be checked there.
1720
class CanonicalizationOfDirectives {
1821
public:
1922
CanonicalizationOfDirectives(parser::Messages &messages)
@@ -107,7 +110,7 @@ void CanonicalizationOfDirectives::CheckLoopDirective(
107110
}
108111

109112
void CanonicalizationOfDirectives::Post(parser::Block &block) {
110-
for (auto it = block.begin(); it != block.end(); ++it) {
113+
for (auto it{block.begin()}; it != block.end(); ++it) {
111114
if (auto *dir{GetConstructIf<parser::CompilerDirective>(*it)}) {
112115
std::visit(
113116
common::visitors{[&](parser::CompilerDirective::VectorAlways &) {
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
//===-- lib/Semantics/check-directives.h ------------------------*- C++ -*-===//
1+
//===-- lib/Semantics/canonicalize-directives.h ------------------*- C++
2+
//-*-===//
23
//
34
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45
// See https://llvm.org/LICENSE.txt for license information.
56
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67
//
78
//===----------------------------------------------------------------------===//
89

9-
#ifndef FORTRAN_SEMANTICS_CHECK_DIRECTIVES_H_
10-
#define FORTRAN_SEMANTICS_CHECK_DIRECTIVES_H_
10+
#ifndef FORTRAN_SEMANTICS_CANONICALIZE_DIRECTIVES_H_
11+
#define FORTRAN_SEMANTICS_CANONICALIZE_DIRECTIVES_H_
1112

1213
namespace Fortran::parser {
1314
struct Program;
@@ -19,4 +20,4 @@ bool CanonicalizeDirectives(
1920
parser::Messages &messages, parser::Program &program);
2021
}
2122

22-
#endif // FORTRAN_SEMANTICS_CHECK_DIRECTIVES_H_
23+
#endif // FORTRAN_SEMANTICS_CANONICALIZE_DIRECTIVES_H_

flang/test/Fir/vector-always.fir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ func.func @_QPvector_always() -> i32 {
1818
fir.result %c1, %c1_i32 : index, i32
1919
}
2020
return %8#1 : i32
21-
}
21+
}

flang/test/Lower/vector-always.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
! RUN: %flang_fc1 -emit-fir -o - %s | FileCheck %s
1+
! RUN: %flang_fc1 -emit-hlfir -o - %s | FileCheck %s
22

33
! CHECK: #access_group = #llvm.access_group<id = distinct[0]<>>
44
! CHECK: #access_group1 = #llvm.access_group<id = distinct[1]<>>
Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
! RUN: %python %S/test_errors.py %s %flang
22

3-
program empty
3+
subroutine empty
44
! ERROR: A DO loop must follow the VECTOR ALWAYS directive
55
!dir$ vector always
6-
end program empty
6+
end subroutine empty
77

8-
program non_do
8+
subroutine non_do
99
! ERROR: A DO loop must follow the VECTOR ALWAYS directive
1010
!dir$ vector always
1111
a = 1
12-
end program non_do
12+
end subroutine non_do
1313

14+
subroutine execution_part
15+
do i=1,10
16+
! ERROR: A DO loop must follow the VECTOR ALWAYS directive
17+
!dir$ vector always
18+
end do
19+
end subroutine execution_part

0 commit comments

Comments
 (0)