Skip to content

Commit 3ce2a7d

Browse files
authored
[flang][OpenMP] Support parallel loop construct. (llvm#127588)
Extends support for the `loop` directive by adding support for `parallel loop` combined directive. Parent PR: llvm#127489. Only the latest commit is relevant.
1 parent 34167f9 commit 3ce2a7d

File tree

4 files changed

+70
-39
lines changed

4 files changed

+70
-39
lines changed

flang/lib/Optimizer/OpenMP/GenericLoopConversion.cpp

+4-23
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ class GenericLoopConversionPattern
5252
rewriteStandaloneLoop(loopOp, rewriter);
5353
break;
5454
case GenericLoopCombinedInfo::ParallelLoop:
55-
llvm_unreachable(
56-
"not yet implemented: Combined `parallel loop` directive");
55+
rewriteToWsloop(loopOp, rewriter);
5756
break;
5857
case GenericLoopCombinedInfo::TeamsLoop:
5958
if (teamsLoopCanBeParallelFor(loopOp))
@@ -69,31 +68,12 @@ class GenericLoopConversionPattern
6968

7069
static mlir::LogicalResult
7170
checkLoopConversionSupportStatus(mlir::omp::LoopOp loopOp) {
72-
GenericLoopCombinedInfo combinedInfo = findGenericLoopCombineInfo(loopOp);
73-
74-
switch (combinedInfo) {
75-
case GenericLoopCombinedInfo::Standalone:
76-
break;
77-
case GenericLoopCombinedInfo::ParallelLoop:
78-
return loopOp.emitError(
79-
"not yet implemented: Combined `parallel loop` directive");
80-
case GenericLoopCombinedInfo::TeamsLoop:
81-
break;
82-
}
83-
8471
auto todo = [&loopOp](mlir::StringRef clauseName) {
8572
return loopOp.emitError()
8673
<< "not yet implemented: Unhandled clause " << clauseName << " in "
8774
<< loopOp->getName() << " operation";
8875
};
8976

90-
// For `loop` and `teams loop` directives, `bind` is supported.
91-
// Additionally, for `teams loop`, semantic checking verifies that the
92-
// `bind` clause modifier is `teams`, so no need to check this here again.
93-
if (combinedInfo == GenericLoopCombinedInfo::ParallelLoop &&
94-
loopOp.getBindKind())
95-
return todo("bind");
96-
9777
if (loopOp.getOrder())
9878
return todo("order");
9979

@@ -147,8 +127,9 @@ class GenericLoopConversionPattern
147127
mlir::omp::ClauseBindKind::Parallel)
148128
return mlir::WalkResult::interrupt();
149129

150-
// TODO check for combined `parallel loop` when we support
151-
// it.
130+
if (combinedInfo == GenericLoopCombinedInfo::ParallelLoop)
131+
return mlir::WalkResult::interrupt();
132+
152133
} else if (auto callOp =
153134
mlir::dyn_cast<mlir::CallOpInterface>(nestedOp)) {
154135
// Calls to non-OpenMP API runtime functions inhibits

flang/test/Lower/OpenMP/loop-directive.f90

+33
Original file line numberDiff line numberDiff line change
@@ -261,3 +261,36 @@ subroutine teams_loop_can_be_parallel_for
261261
tid = omp_get_thread_num()
262262
END DO
263263
end subroutine
264+
265+
! CHECK-LABEL: func.func @_QPteams_loop_cannot_be_parallel_for_4
266+
subroutine teams_loop_cannot_be_parallel_for_4
267+
implicit none
268+
integer :: iter, iter2, tid, val(20)
269+
270+
! CHECK: omp.teams {
271+
272+
! Verify the outer `loop` directive was mapped to only `distribute`.
273+
! CHECK-NOT: omp.parallel {{.*}}
274+
! CHECK: omp.distribute {{.*}} {
275+
! CHECK-NEXT: omp.loop_nest {{.*}} {
276+
277+
! Verify the inner `loop` directive was mapped to a worksharing loop.
278+
! CHECK: omp.wsloop {{.*}} {
279+
! CHECK: omp.loop_nest {{.*}} {
280+
! CHECK: }
281+
! CHECK: }
282+
283+
! CHECK: }
284+
! CHECK: }
285+
286+
! CHECK: }
287+
!$omp target teams loop map(tofrom:val)
288+
DO iter = 1, 5
289+
!$omp parallel
290+
!$omp loop
291+
DO iter2 = 1, 5
292+
val(iter+iter2) = iter+iter2
293+
END DO
294+
!$omp end parallel
295+
END DO
296+
end subroutine

flang/test/Transforms/generic-loop-rewriting-todo.mlir

-16
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,5 @@
11
// RUN: fir-opt --omp-generic-loop-conversion -verify-diagnostics %s
22

3-
func.func @_QPparallel_loop() {
4-
omp.parallel {
5-
%c0 = arith.constant 0 : i32
6-
%c10 = arith.constant 10 : i32
7-
%c1 = arith.constant 1 : i32
8-
// expected-error@below {{not yet implemented: Combined `parallel loop` directive}}
9-
omp.loop {
10-
omp.loop_nest (%arg3) : i32 = (%c0) to (%c10) inclusive step (%c1) {
11-
omp.yield
12-
}
13-
}
14-
omp.terminator
15-
}
16-
return
17-
}
18-
193
omp.declare_reduction @add_reduction_i32 : i32 init {
204
^bb0(%arg0: i32):
215
%c0_i32 = arith.constant 0 : i32

flang/test/Transforms/generic-loop-rewriting.mlir

+33
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,36 @@ func.func @_QPteams_loop() {
4545
// CHECK: }
4646
// CHECK: }
4747
// CHECK: }
48+
49+
func.func @_QPparallel_loop() {
50+
%i = fir.alloca i32
51+
omp.parallel {
52+
%c0 = arith.constant 0 : i32
53+
%c10 = arith.constant 10 : i32
54+
%c1 = arith.constant 1 : i32
55+
omp.loop private(@_QFteams_loopEi_private_i32 %i -> %arg2 : !fir.ref<i32>) {
56+
omp.loop_nest (%arg3) : i32 = (%c0) to (%c10) inclusive step (%c1) {
57+
fir.store %arg3 to %arg2 : !fir.ref<i32>
58+
omp.yield
59+
}
60+
}
61+
omp.terminator
62+
}
63+
return
64+
}
65+
66+
// CHECK-LABEL: func.func @_QPparallel_loop
67+
// CHECK: %[[I:.*]] = fir.alloca i32
68+
// CHECK: omp.parallel {
69+
70+
// CHECK: %[[LB:.*]] = arith.constant 0 : i32
71+
// CHECK: %[[UB:.*]] = arith.constant 10 : i32
72+
// CHECK: %[[STEP:.*]] = arith.constant 1 : i32
73+
// CHECK: omp.wsloop private(@{{.*}} %[[I]]
74+
// CHECK-SAME: -> %[[I_PRIV_ARG:[^[:space:]]+]] : !fir.ref<i32>) {
75+
// CHECK: omp.loop_nest (%{{.*}}) : i32 =
76+
// CHECK-SAME: (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
77+
// CHECK: fir.store %{{.*}} to %[[I_PRIV_ARG]] : !fir.ref<i32>
78+
// CHECK: }
79+
// CHECK: }
80+
// CHECK: }

0 commit comments

Comments
 (0)