Skip to content

Commit eb614cd

Browse files
authored
[Flang][OpenMP][MLIR] Lowering of reduction,inreduction, nogroup and lastprivate clause to MLIR (llvm#166751)
This patch add MLIR lowering support for nogroup, reduction, inreduction and lastprivate clauses of taskloop directive.
1 parent 8346a77 commit eb614cd

File tree

11 files changed

+158
-63
lines changed

11 files changed

+158
-63
lines changed

flang/lib/Lower/OpenMP/ClauseProcessor.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,11 @@ bool ClauseProcessor::processMergeable(
406406
return markClauseOccurrence<omp::clause::Mergeable>(result.mergeable);
407407
}
408408

409+
bool ClauseProcessor::processNogroup(
410+
mlir::omp::NogroupClauseOps &result) const {
411+
return markClauseOccurrence<omp::clause::Nogroup>(result.nogroup);
412+
}
413+
409414
bool ClauseProcessor::processNowait(mlir::omp::NowaitClauseOps &result) const {
410415
return markClauseOccurrence<omp::clause::Nowait>(result.nowait);
411416
}

flang/lib/Lower/OpenMP/ClauseProcessor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class ClauseProcessor {
8989
bool processInclusive(mlir::Location currentLocation,
9090
mlir::omp::InclusiveClauseOps &result) const;
9191
bool processMergeable(mlir::omp::MergeableClauseOps &result) const;
92+
bool processNogroup(mlir::omp::NogroupClauseOps &result) const;
9293
bool processNowait(mlir::omp::NowaitClauseOps &result) const;
9394
bool processNumTasks(lower::StatementContext &stmtCtx,
9495
mlir::omp::NumTasksClauseOps &result) const;

flang/lib/Lower/OpenMP/DataSharingProcessor.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,8 @@ void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) {
342342
if (!hasLastPrivate)
343343
return;
344344

345-
if (mlir::isa<mlir::omp::WsloopOp>(op) || mlir::isa<mlir::omp::SimdOp>(op)) {
345+
if (mlir::isa<mlir::omp::WsloopOp>(op) || mlir::isa<mlir::omp::SimdOp>(op) ||
346+
mlir::isa<mlir::omp::TaskloopOp>(op)) {
346347
mlir::omp::LoopRelatedClauseOps result;
347348
llvm::SmallVector<const semantics::Symbol *> iv;
348349
collectLoopRelatedInfo(converter, converter.getCurrentLocation(), eval,
@@ -408,7 +409,7 @@ void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) {
408409
} else {
409410
TODO(converter.getCurrentLocation(),
410411
"lastprivate clause in constructs other than "
411-
"simd/worksharing-loop");
412+
"simd/worksharing-loop/taskloop");
412413
}
413414
}
414415

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,25 +1762,27 @@ static void genTaskgroupClauses(
17621762
cp.processTaskReduction(loc, clauseOps, taskReductionSyms);
17631763
}
17641764

1765-
static void genTaskloopClauses(lower::AbstractConverter &converter,
1766-
semantics::SemanticsContext &semaCtx,
1767-
lower::StatementContext &stmtCtx,
1768-
const List<Clause> &clauses, mlir::Location loc,
1769-
mlir::omp::TaskloopOperands &clauseOps) {
1765+
static void genTaskloopClauses(
1766+
lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
1767+
lower::StatementContext &stmtCtx, const List<Clause> &clauses,
1768+
mlir::Location loc, mlir::omp::TaskloopOperands &clauseOps,
1769+
llvm::SmallVectorImpl<const semantics::Symbol *> &reductionSyms,
1770+
llvm::SmallVectorImpl<const semantics::Symbol *> &inReductionSyms) {
17701771

17711772
ClauseProcessor cp(converter, semaCtx, clauses);
17721773
cp.processAllocate(clauseOps);
17731774
cp.processFinal(stmtCtx, clauseOps);
17741775
cp.processGrainsize(stmtCtx, clauseOps);
17751776
cp.processIf(llvm::omp::Directive::OMPD_taskloop, clauseOps);
1777+
cp.processInReduction(loc, clauseOps, inReductionSyms);
17761778
cp.processMergeable(clauseOps);
1779+
cp.processNogroup(clauseOps);
17771780
cp.processNumTasks(stmtCtx, clauseOps);
17781781
cp.processPriority(stmtCtx, clauseOps);
1782+
cp.processReduction(loc, clauseOps, reductionSyms);
17791783
cp.processUntied(clauseOps);
17801784

1781-
cp.processTODO<clause::Collapse, clause::InReduction, clause::Lastprivate,
1782-
clause::Nogroup, clause::Reduction>(
1783-
loc, llvm::omp::Directive::OMPD_taskloop);
1785+
cp.processTODO<clause::Collapse>(loc, llvm::omp::Directive::OMPD_taskloop);
17841786
}
17851787

17861788
static void genTaskwaitClauses(lower::AbstractConverter &converter,
@@ -2982,8 +2984,11 @@ static mlir::omp::TaskloopOp genStandaloneTaskloop(
29822984
lower::pft::Evaluation &eval, mlir::Location loc,
29832985
const ConstructQueue &queue, ConstructQueue::const_iterator item) {
29842986
mlir::omp::TaskloopOperands taskloopClauseOps;
2987+
llvm::SmallVector<const semantics::Symbol *> reductionSyms;
2988+
llvm::SmallVector<const semantics::Symbol *> inReductionSyms;
2989+
29852990
genTaskloopClauses(converter, semaCtx, stmtCtx, item->clauses, loc,
2986-
taskloopClauseOps);
2991+
taskloopClauseOps, reductionSyms, inReductionSyms);
29872992
DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval,
29882993
/*shouldCollectPreDeterminedSymbols=*/true,
29892994
enableDelayedPrivatization, symTable);
@@ -2997,6 +3002,10 @@ static mlir::omp::TaskloopOp genStandaloneTaskloop(
29973002
EntryBlockArgs taskloopArgs;
29983003
taskloopArgs.priv.syms = dsp.getDelayedPrivSymbols();
29993004
taskloopArgs.priv.vars = taskloopClauseOps.privateVars;
3005+
taskloopArgs.reduction.syms = reductionSyms;
3006+
taskloopArgs.reduction.vars = taskloopClauseOps.reductionVars;
3007+
taskloopArgs.inReduction.syms = inReductionSyms;
3008+
taskloopArgs.inReduction.vars = taskloopClauseOps.inReductionVars;
30003009

30013010
auto taskLoopOp = genWrapperOp<mlir::omp::TaskloopOp>(
30023011
converter, loc, taskloopClauseOps, taskloopArgs);

flang/test/Lower/OpenMP/Todo/taskloop-inreduction.f90

Lines changed: 0 additions & 13 deletions
This file was deleted.

flang/test/Lower/OpenMP/Todo/taskloop-lastprivate.f90

Lines changed: 0 additions & 13 deletions
This file was deleted.

flang/test/Lower/OpenMP/Todo/taskloop-nogroup.f90

Lines changed: 0 additions & 13 deletions
This file was deleted.

flang/test/Lower/OpenMP/Todo/taskloop-reduction.f90

Lines changed: 0 additions & 13 deletions
This file was deleted.

flang/test/Lower/OpenMP/taskloop.f90

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
! RUN: bbc -emit-hlfir %openmp_flags -o - %s 2>&1 | FileCheck %s
33
! RUN: %flang_fc1 -emit-hlfir %openmp_flags -o - %s 2>&1 | FileCheck %s
44

5+
! CHECK-LABEL: omp.private
6+
! CHECK-SAME: {type = private} @[[LAST_PRIVATE_I:.*]] : i32
7+
8+
! CHECK-LABEL: omp.private
9+
! CHECK-SAME: {type = private} @[[LAST_PRIVATE_X:.*]] : i32
10+
11+
! CHECK-LABEL: omp.private
12+
! CHECK-SAME: {type = private} @[[QFOMP_TASKLOOP_NOGROUPEI_PRIVATE_I32:.*]] : i32
13+
514
! CHECK-LABEL: omp.private
615
! CHECK-SAME: {type = private} @[[OMP_TASKLOOP_UNTIEDEI_PRIVATE_I32:.*]] : i32
716

@@ -195,3 +204,46 @@ subroutine omp_taskloop_untied()
195204
end do
196205
!$omp end taskloop
197206
end subroutine
207+
208+
!===============================================================================
209+
! `nogroup` clause
210+
!===============================================================================
211+
212+
subroutine omp_taskloop_nogroup()
213+
! CHECK: omp.taskloop nogroup
214+
!$omp taskloop nogroup
215+
do i = 1, 10
216+
call foo()
217+
end do
218+
!$omp end taskloop
219+
end subroutine
220+
221+
!===============================================================================
222+
! `lastprivate` clause
223+
!===============================================================================
224+
225+
! CHECK-LABEL: func.func @_QPomp_taskloop_lastprivate
226+
! CHECK: %[[ALLOCA_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomp_taskloop_lastprivateEi"}
227+
! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOCA_I]] {uniq_name = "_QFomp_taskloop_lastprivateEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
228+
! CHECK: %[[ALLOCA_X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFomp_taskloop_lastprivateEx"}
229+
! CHECK: %[[DECL_X:.*]]:2 = hlfir.declare %[[ALLOCA_X]] {uniq_name = "_QFomp_taskloop_lastprivateEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
230+
subroutine omp_taskloop_lastprivate()
231+
integer x
232+
x = 0
233+
! CHECK: omp.taskloop private(@[[LAST_PRIVATE_X]] %[[DECL_X]]#0 -> %[[ARG0]], @[[LAST_PRIVATE_I]] %[[DECL_I]]#0 -> %[[ARG1]] : !fir.ref<i32>, !fir.ref<i32>) {
234+
!$omp taskloop lastprivate(x)
235+
do i = 1, 100
236+
! CHECK: %[[DECL_ARG0:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFomp_taskloop_lastprivateEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
237+
! CHECK: %[[LOAD_ARG0:.*]] = fir.load %[[DECL_ARG0]]#0 : !fir.ref<i32>
238+
! CHECK: %[[RES_ADD:.*]] = arith.addi %[[LOAD_ARG0]], %{{.*}} : i32
239+
! CHECK: hlfir.assign %[[RES_ADD]] to %[[DECL_ARG0]]#0 : i32, !fir.ref<i32>
240+
x = x + 1
241+
! CHECK: %[[SELCT_RESULT:.*]] = arith.select %{{.*}}, %{{.*}}, %{{.*}} : i1
242+
! CHECK: fir.if %[[SELCT_RESULT]] {
243+
! CHECK: %[[LOADED_SUM:.*]] = fir.load %[[DECL_ARG0]]#0 : !fir.ref<i32>
244+
! CHECK: hlfir.assign %[[LOADED_SUM]] to %[[DECL_X]]#0 : i32, !fir.ref<i32>
245+
! CHECK: }
246+
! CHECK: omp.yield
247+
end do
248+
!$omp end taskloop
249+
end subroutine omp_taskloop_lastprivate
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
! RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
2+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
3+
4+
! CHECK-LABEL: omp.private
5+
! CHECK-SAME: {type = private} @[[PRIVATE_I:.*]] : i32
6+
7+
! CHECK-LABEL: omp.declare_reduction
8+
! CHECK-SAME: @[[ADD_RED_I32:.*]] : i32 init {
9+
! CHECK: ^bb0(%{{.*}}: i32):
10+
! CHECK: %[[C0_I32:.*]] = arith.constant 0 : i32
11+
! CHECK: omp.yield(%[[C0_I32]] : i32)
12+
! CHECK: } combiner {
13+
! CHECK: ^bb0(%{{.*}}: i32, %{{.*}}: i32):
14+
! CHECK: %[[RES:.*]] = arith.addi %{{.*}}, %{{.*}} : i32
15+
! CHECK: omp.yield(%[[RES]] : i32)
16+
! CHECK: }
17+
18+
! CHECK-LABEL: func.func @_QPomp_taskloop_inreduction
19+
! CHECK: %[[ALLOCA_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomp_taskloop_inreductionEi"}
20+
! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOCA_I]] {uniq_name = "_QFomp_taskloop_inreductionEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
21+
! CHECK: %[[ALLOCA_X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFomp_taskloop_inreductionEx"}
22+
! CHECK: %[[DECL_X:.*]]:2 = hlfir.declare %[[ALLOCA_X]] {uniq_name = "_QFomp_taskloop_inreductionEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
23+
! CHECK: %[[INIT_X:.*]] = arith.constant 0 : i32
24+
! CHECK: hlfir.assign %[[INIT_X]] to %[[DECL_X]]#0 : i32, !fir.ref<i32>
25+
subroutine omp_taskloop_inreduction()
26+
integer x
27+
x = 0
28+
! CHECK: omp.taskloop in_reduction(@[[ADD_RED_I32]]
29+
! CHECK: %[[DECL_X]]#0 -> %[[ARG0:.*]] : !fir.ref<i32>) private(@[[PRIVATE_I]] %[[DECL_I]]#0 -> %[[ARG1:.*]] : !fir.ref<i32>) {
30+
! CHECK: %[[VAL_ARG1:.*]]:2 = hlfir.declare %[[ARG0]]
31+
! CHECK-SAME: {uniq_name = "_QFomp_taskloop_inreductionEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
32+
!$omp taskloop in_reduction(+:x)
33+
do i = 1, 100
34+
! CHECK: %[[X_VAL:.*]] = fir.load %[[VAL_ARG1]]#0 : !fir.ref<i32>
35+
! CHECK: %[[ADD_VAL:.*]] = arith.addi %[[X_VAL]], %{{.*}} : i32
36+
x = x + 1
37+
! CHECK: hlfir.assign %[[ADD_VAL]] to %[[VAL_ARG1]]#0 : i32, !fir.ref<i32>
38+
end do
39+
!$omp end taskloop
40+
end subroutine omp_taskloop_inreduction

0 commit comments

Comments
 (0)