Skip to content

Commit fb20992

Browse files
authored
[flang][OpenMP] Set isNewBlock directly on OpenMP constructs (#144593)
When the PFT builder decides that an evaluation needs a new block it checks if the evaluation has nested evaluations. In such case it sets the flag on the first nested evaluation. This works under the assuption that such an evaluation only serves as a container, and does not, by itself, generate any code. This fails for OpenMP constructs that contain nested evaluations because the top-level evaluation does generate code that wraps the code from the nested evaluations. In such cases, the code for the top-level evaluation may be emitted in a wrong place. When setting the `isNewBlock` flag, recognize OpenMP directives, and treat them accordingly. This fixes #139071
1 parent 9a6a87d commit fb20992

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

flang/include/flang/Lower/PFTBuilder.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ static constexpr bool isExecutableDirective{common::HasMember<
184184
A, std::tuple<parser::CompilerDirective, parser::OpenACCConstruct,
185185
parser::OpenMPConstruct, parser::CUFKernelDoConstruct>>};
186186

187+
template <typename A>
188+
static constexpr bool isOpenMPDirective{
189+
common::HasMember<A, std::tuple<parser::OpenMPConstruct,
190+
parser::OpenMPDeclarativeConstruct>>};
191+
187192
template <typename A>
188193
static constexpr bool isFunctionLike{common::HasMember<
189194
A, std::tuple<parser::MainProgram, parser::FunctionSubprogram,
@@ -267,6 +272,11 @@ struct Evaluation : EvaluationVariant {
267272
return pft::isExecutableDirective<std::decay_t<decltype(r)>>;
268273
}});
269274
}
275+
constexpr bool isOpenMPDirective() const {
276+
return visit(common::visitors{[](auto &r) {
277+
return pft::isOpenMPDirective<std::decay_t<decltype(r)>>;
278+
}});
279+
}
270280

271281
/// Return the predicate: "This is a non-initial, non-terminal construct
272282
/// statement." For an IfConstruct, this is ElseIfStmt and ElseStmt.

flang/lib/Lower/PFTBuilder.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1096,7 +1096,9 @@ class PFTBuilder {
10961096

10971097
// The first executable statement in the subprogram is preceded by a
10981098
// branch to the entry point, so it starts a new block.
1099-
if (initialEval->hasNestedEvaluations())
1099+
// OpenMP directives can generate code around the nested evaluations.
1100+
if (initialEval->hasNestedEvaluations() &&
1101+
!initialEval->isOpenMPDirective())
11001102
initialEval = &initialEval->getFirstNestedEvaluation();
11011103
else if (initialEval->isA<Fortran::parser::EntryStmt>())
11021104
initialEval = initialEval->lexicalSuccessor;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
2+
3+
! Check the first entry point
4+
!CHECK: func.func @_QPprocess_a
5+
!CHECK: omp.parallel
6+
!CHECK: omp.wsloop
7+
!CHECK: %[[V0:[0-9]+]] = fir.load %{{[0-9]+}} : !fir.ref<f32>
8+
!CHECK: %[[V1:[a-z_0-9]+]] = arith.constant 2.000000e+00 : f32
9+
!CHECK: = arith.mulf %[[V0]], %[[V1]] fastmath<contract> : f32
10+
!CHECK: omp.terminator
11+
!CHECK-NOT: omp
12+
!CHECK: return
13+
14+
! Check the second entry point
15+
!CHECK: func.func @_QPprocess_b
16+
!CHECK: omp.parallel
17+
!CHECK: fir.do_loop
18+
!CHECK: %[[V3:[0-9]+]] = fir.load %[[V2:[0-9]+]]#0 : !fir.ref<i32>
19+
!CHECK: %[[V4:[0-9]+]] = fir.load %[[V2]]#0 : !fir.ref<i32>
20+
!CHECK: = arith.muli %[[V3]], %[[V4]] : i32
21+
!CHECK: omp.terminator
22+
!CHECK-NOT: omp
23+
!CHECK: return
24+
25+
subroutine process_a(n, a)
26+
integer, intent(in) :: n
27+
real, intent(inout) :: a(n)
28+
integer :: i
29+
30+
!$omp parallel do
31+
do i = 1, n
32+
a(i) = a(i) * 2.0
33+
end do
34+
!$omp end parallel do
35+
36+
return
37+
38+
entry process_b(n, b)
39+
40+
!$omp parallel
41+
do i = 1, n
42+
a(i) = i * i
43+
end do
44+
!$omp end parallel
45+
46+
end subroutine process_a

0 commit comments

Comments
 (0)