mirror of
https://github.com/intel/llvm.git
synced 2026-01-22 23:49:22 +08:00
[Flang][OpenMP][MLIR] Lowering of reduction,inreduction, nogroup and lastprivate clause to MLIR (#166751)
This patch add MLIR lowering support for nogroup, reduction, inreduction and lastprivate clauses of taskloop directive.
This commit is contained in:
committed by
GitHub
parent
8346a772bc
commit
eb614cda37
@@ -406,6 +406,11 @@ bool ClauseProcessor::processMergeable(
|
||||
return markClauseOccurrence<omp::clause::Mergeable>(result.mergeable);
|
||||
}
|
||||
|
||||
bool ClauseProcessor::processNogroup(
|
||||
mlir::omp::NogroupClauseOps &result) const {
|
||||
return markClauseOccurrence<omp::clause::Nogroup>(result.nogroup);
|
||||
}
|
||||
|
||||
bool ClauseProcessor::processNowait(mlir::omp::NowaitClauseOps &result) const {
|
||||
return markClauseOccurrence<omp::clause::Nowait>(result.nowait);
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ public:
|
||||
bool processInclusive(mlir::Location currentLocation,
|
||||
mlir::omp::InclusiveClauseOps &result) const;
|
||||
bool processMergeable(mlir::omp::MergeableClauseOps &result) const;
|
||||
bool processNogroup(mlir::omp::NogroupClauseOps &result) const;
|
||||
bool processNowait(mlir::omp::NowaitClauseOps &result) const;
|
||||
bool processNumTasks(lower::StatementContext &stmtCtx,
|
||||
mlir::omp::NumTasksClauseOps &result) const;
|
||||
|
||||
@@ -342,7 +342,8 @@ void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) {
|
||||
if (!hasLastPrivate)
|
||||
return;
|
||||
|
||||
if (mlir::isa<mlir::omp::WsloopOp>(op) || mlir::isa<mlir::omp::SimdOp>(op)) {
|
||||
if (mlir::isa<mlir::omp::WsloopOp>(op) || mlir::isa<mlir::omp::SimdOp>(op) ||
|
||||
mlir::isa<mlir::omp::TaskloopOp>(op)) {
|
||||
mlir::omp::LoopRelatedClauseOps result;
|
||||
llvm::SmallVector<const semantics::Symbol *> iv;
|
||||
collectLoopRelatedInfo(converter, converter.getCurrentLocation(), eval,
|
||||
@@ -408,7 +409,7 @@ void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) {
|
||||
} else {
|
||||
TODO(converter.getCurrentLocation(),
|
||||
"lastprivate clause in constructs other than "
|
||||
"simd/worksharing-loop");
|
||||
"simd/worksharing-loop/taskloop");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1762,25 +1762,27 @@ static void genTaskgroupClauses(
|
||||
cp.processTaskReduction(loc, clauseOps, taskReductionSyms);
|
||||
}
|
||||
|
||||
static void genTaskloopClauses(lower::AbstractConverter &converter,
|
||||
semantics::SemanticsContext &semaCtx,
|
||||
lower::StatementContext &stmtCtx,
|
||||
const List<Clause> &clauses, mlir::Location loc,
|
||||
mlir::omp::TaskloopOperands &clauseOps) {
|
||||
static void genTaskloopClauses(
|
||||
lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
|
||||
lower::StatementContext &stmtCtx, const List<Clause> &clauses,
|
||||
mlir::Location loc, mlir::omp::TaskloopOperands &clauseOps,
|
||||
llvm::SmallVectorImpl<const semantics::Symbol *> &reductionSyms,
|
||||
llvm::SmallVectorImpl<const semantics::Symbol *> &inReductionSyms) {
|
||||
|
||||
ClauseProcessor cp(converter, semaCtx, clauses);
|
||||
cp.processAllocate(clauseOps);
|
||||
cp.processFinal(stmtCtx, clauseOps);
|
||||
cp.processGrainsize(stmtCtx, clauseOps);
|
||||
cp.processIf(llvm::omp::Directive::OMPD_taskloop, clauseOps);
|
||||
cp.processInReduction(loc, clauseOps, inReductionSyms);
|
||||
cp.processMergeable(clauseOps);
|
||||
cp.processNogroup(clauseOps);
|
||||
cp.processNumTasks(stmtCtx, clauseOps);
|
||||
cp.processPriority(stmtCtx, clauseOps);
|
||||
cp.processReduction(loc, clauseOps, reductionSyms);
|
||||
cp.processUntied(clauseOps);
|
||||
|
||||
cp.processTODO<clause::Collapse, clause::InReduction, clause::Lastprivate,
|
||||
clause::Nogroup, clause::Reduction>(
|
||||
loc, llvm::omp::Directive::OMPD_taskloop);
|
||||
cp.processTODO<clause::Collapse>(loc, llvm::omp::Directive::OMPD_taskloop);
|
||||
}
|
||||
|
||||
static void genTaskwaitClauses(lower::AbstractConverter &converter,
|
||||
@@ -2982,8 +2984,11 @@ static mlir::omp::TaskloopOp genStandaloneTaskloop(
|
||||
lower::pft::Evaluation &eval, mlir::Location loc,
|
||||
const ConstructQueue &queue, ConstructQueue::const_iterator item) {
|
||||
mlir::omp::TaskloopOperands taskloopClauseOps;
|
||||
llvm::SmallVector<const semantics::Symbol *> reductionSyms;
|
||||
llvm::SmallVector<const semantics::Symbol *> inReductionSyms;
|
||||
|
||||
genTaskloopClauses(converter, semaCtx, stmtCtx, item->clauses, loc,
|
||||
taskloopClauseOps);
|
||||
taskloopClauseOps, reductionSyms, inReductionSyms);
|
||||
DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval,
|
||||
/*shouldCollectPreDeterminedSymbols=*/true,
|
||||
enableDelayedPrivatization, symTable);
|
||||
@@ -2997,6 +3002,10 @@ static mlir::omp::TaskloopOp genStandaloneTaskloop(
|
||||
EntryBlockArgs taskloopArgs;
|
||||
taskloopArgs.priv.syms = dsp.getDelayedPrivSymbols();
|
||||
taskloopArgs.priv.vars = taskloopClauseOps.privateVars;
|
||||
taskloopArgs.reduction.syms = reductionSyms;
|
||||
taskloopArgs.reduction.vars = taskloopClauseOps.reductionVars;
|
||||
taskloopArgs.inReduction.syms = inReductionSyms;
|
||||
taskloopArgs.inReduction.vars = taskloopClauseOps.inReductionVars;
|
||||
|
||||
auto taskLoopOp = genWrapperOp<mlir::omp::TaskloopOp>(
|
||||
converter, loc, taskloopClauseOps, taskloopArgs);
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
|
||||
! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
|
||||
|
||||
! CHECK: not yet implemented: Unhandled clause IN_REDUCTION in TASKLOOP construct
|
||||
subroutine omp_taskloop_inreduction()
|
||||
integer x
|
||||
x = 0
|
||||
!$omp taskloop in_reduction(+:x)
|
||||
do i = 1, 100
|
||||
x = x + 1
|
||||
end do
|
||||
!$omp end taskloop
|
||||
end subroutine omp_taskloop_inreduction
|
||||
@@ -1,13 +0,0 @@
|
||||
! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
|
||||
! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
|
||||
|
||||
! CHECK: not yet implemented: Unhandled clause LASTPRIVATE in TASKLOOP construct
|
||||
subroutine omp_taskloop_lastprivate()
|
||||
integer x
|
||||
x = 0
|
||||
!$omp taskloop lastprivate(x)
|
||||
do i = 1, 100
|
||||
x = x + 1
|
||||
end do
|
||||
!$omp end taskloop
|
||||
end subroutine omp_taskloop_lastprivate
|
||||
@@ -1,13 +0,0 @@
|
||||
! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
|
||||
! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
|
||||
|
||||
! CHECK: not yet implemented: Unhandled clause NOGROUP in TASKLOOP construct
|
||||
subroutine omp_taskloop_nogroup()
|
||||
integer x
|
||||
x = 0
|
||||
!$omp taskloop nogroup
|
||||
do i = 1, 100
|
||||
x = x + 1
|
||||
end do
|
||||
!$omp end taskloop
|
||||
end subroutine omp_taskloop_nogroup
|
||||
@@ -1,13 +0,0 @@
|
||||
! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
|
||||
! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
|
||||
|
||||
! CHECK: not yet implemented: Unhandled clause REDUCTION in TASKLOOP construct
|
||||
subroutine omp_taskloop_reduction()
|
||||
integer x
|
||||
x = 0
|
||||
!$omp taskloop reduction(+:x)
|
||||
do i = 1, 100
|
||||
x = x + 1
|
||||
end do
|
||||
!$omp end taskloop
|
||||
end subroutine omp_taskloop_reduction
|
||||
@@ -2,6 +2,15 @@
|
||||
! RUN: bbc -emit-hlfir %openmp_flags -o - %s 2>&1 | FileCheck %s
|
||||
! RUN: %flang_fc1 -emit-hlfir %openmp_flags -o - %s 2>&1 | FileCheck %s
|
||||
|
||||
! CHECK-LABEL: omp.private
|
||||
! CHECK-SAME: {type = private} @[[LAST_PRIVATE_I:.*]] : i32
|
||||
|
||||
! CHECK-LABEL: omp.private
|
||||
! CHECK-SAME: {type = private} @[[LAST_PRIVATE_X:.*]] : i32
|
||||
|
||||
! CHECK-LABEL: omp.private
|
||||
! CHECK-SAME: {type = private} @[[QFOMP_TASKLOOP_NOGROUPEI_PRIVATE_I32:.*]] : i32
|
||||
|
||||
! CHECK-LABEL: omp.private
|
||||
! CHECK-SAME: {type = private} @[[OMP_TASKLOOP_UNTIEDEI_PRIVATE_I32:.*]] : i32
|
||||
|
||||
@@ -195,3 +204,46 @@ subroutine omp_taskloop_untied()
|
||||
end do
|
||||
!$omp end taskloop
|
||||
end subroutine
|
||||
|
||||
!===============================================================================
|
||||
! `nogroup` clause
|
||||
!===============================================================================
|
||||
|
||||
subroutine omp_taskloop_nogroup()
|
||||
! CHECK: omp.taskloop nogroup
|
||||
!$omp taskloop nogroup
|
||||
do i = 1, 10
|
||||
call foo()
|
||||
end do
|
||||
!$omp end taskloop
|
||||
end subroutine
|
||||
|
||||
!===============================================================================
|
||||
! `lastprivate` clause
|
||||
!===============================================================================
|
||||
|
||||
! CHECK-LABEL: func.func @_QPomp_taskloop_lastprivate
|
||||
! CHECK: %[[ALLOCA_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomp_taskloop_lastprivateEi"}
|
||||
! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOCA_I]] {uniq_name = "_QFomp_taskloop_lastprivateEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
||||
! CHECK: %[[ALLOCA_X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFomp_taskloop_lastprivateEx"}
|
||||
! CHECK: %[[DECL_X:.*]]:2 = hlfir.declare %[[ALLOCA_X]] {uniq_name = "_QFomp_taskloop_lastprivateEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
||||
subroutine omp_taskloop_lastprivate()
|
||||
integer x
|
||||
x = 0
|
||||
! CHECK: omp.taskloop private(@[[LAST_PRIVATE_X]] %[[DECL_X]]#0 -> %[[ARG0]], @[[LAST_PRIVATE_I]] %[[DECL_I]]#0 -> %[[ARG1]] : !fir.ref<i32>, !fir.ref<i32>) {
|
||||
!$omp taskloop lastprivate(x)
|
||||
do i = 1, 100
|
||||
! CHECK: %[[DECL_ARG0:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFomp_taskloop_lastprivateEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
||||
! CHECK: %[[LOAD_ARG0:.*]] = fir.load %[[DECL_ARG0]]#0 : !fir.ref<i32>
|
||||
! CHECK: %[[RES_ADD:.*]] = arith.addi %[[LOAD_ARG0]], %{{.*}} : i32
|
||||
! CHECK: hlfir.assign %[[RES_ADD]] to %[[DECL_ARG0]]#0 : i32, !fir.ref<i32>
|
||||
x = x + 1
|
||||
! CHECK: %[[SELCT_RESULT:.*]] = arith.select %{{.*}}, %{{.*}}, %{{.*}} : i1
|
||||
! CHECK: fir.if %[[SELCT_RESULT]] {
|
||||
! CHECK: %[[LOADED_SUM:.*]] = fir.load %[[DECL_ARG0]]#0 : !fir.ref<i32>
|
||||
! CHECK: hlfir.assign %[[LOADED_SUM]] to %[[DECL_X]]#0 : i32, !fir.ref<i32>
|
||||
! CHECK: }
|
||||
! CHECK: omp.yield
|
||||
end do
|
||||
!$omp end taskloop
|
||||
end subroutine omp_taskloop_lastprivate
|
||||
|
||||
40
flang/test/Lower/taskloop-inreduction.f90
Normal file
40
flang/test/Lower/taskloop-inreduction.f90
Normal file
@@ -0,0 +1,40 @@
|
||||
! RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
|
||||
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
|
||||
|
||||
! CHECK-LABEL: omp.private
|
||||
! CHECK-SAME: {type = private} @[[PRIVATE_I:.*]] : i32
|
||||
|
||||
! CHECK-LABEL: omp.declare_reduction
|
||||
! CHECK-SAME: @[[ADD_RED_I32:.*]] : i32 init {
|
||||
! CHECK: ^bb0(%{{.*}}: i32):
|
||||
! CHECK: %[[C0_I32:.*]] = arith.constant 0 : i32
|
||||
! CHECK: omp.yield(%[[C0_I32]] : i32)
|
||||
! CHECK: } combiner {
|
||||
! CHECK: ^bb0(%{{.*}}: i32, %{{.*}}: i32):
|
||||
! CHECK: %[[RES:.*]] = arith.addi %{{.*}}, %{{.*}} : i32
|
||||
! CHECK: omp.yield(%[[RES]] : i32)
|
||||
! CHECK: }
|
||||
|
||||
! CHECK-LABEL: func.func @_QPomp_taskloop_inreduction
|
||||
! CHECK: %[[ALLOCA_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomp_taskloop_inreductionEi"}
|
||||
! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOCA_I]] {uniq_name = "_QFomp_taskloop_inreductionEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
||||
! CHECK: %[[ALLOCA_X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFomp_taskloop_inreductionEx"}
|
||||
! CHECK: %[[DECL_X:.*]]:2 = hlfir.declare %[[ALLOCA_X]] {uniq_name = "_QFomp_taskloop_inreductionEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
||||
! CHECK: %[[INIT_X:.*]] = arith.constant 0 : i32
|
||||
! CHECK: hlfir.assign %[[INIT_X]] to %[[DECL_X]]#0 : i32, !fir.ref<i32>
|
||||
subroutine omp_taskloop_inreduction()
|
||||
integer x
|
||||
x = 0
|
||||
! CHECK: omp.taskloop in_reduction(@[[ADD_RED_I32]]
|
||||
! CHECK: %[[DECL_X]]#0 -> %[[ARG0:.*]] : !fir.ref<i32>) private(@[[PRIVATE_I]] %[[DECL_I]]#0 -> %[[ARG1:.*]] : !fir.ref<i32>) {
|
||||
! CHECK: %[[VAL_ARG1:.*]]:2 = hlfir.declare %[[ARG0]]
|
||||
! CHECK-SAME: {uniq_name = "_QFomp_taskloop_inreductionEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
||||
!$omp taskloop in_reduction(+:x)
|
||||
do i = 1, 100
|
||||
! CHECK: %[[X_VAL:.*]] = fir.load %[[VAL_ARG1]]#0 : !fir.ref<i32>
|
||||
! CHECK: %[[ADD_VAL:.*]] = arith.addi %[[X_VAL]], %{{.*}} : i32
|
||||
x = x + 1
|
||||
! CHECK: hlfir.assign %[[ADD_VAL]] to %[[VAL_ARG1]]#0 : i32, !fir.ref<i32>
|
||||
end do
|
||||
!$omp end taskloop
|
||||
end subroutine omp_taskloop_inreduction
|
||||
39
flang/test/Lower/taskloop-reduction.f90
Normal file
39
flang/test/Lower/taskloop-reduction.f90
Normal file
@@ -0,0 +1,39 @@
|
||||
! RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
|
||||
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s
|
||||
|
||||
! CHECK-LABEL: omp.private
|
||||
! CHECK-SAME: {type = private} @[[PRIVATE_I:.*]] : i32
|
||||
|
||||
! CHECK-LABEL: omp.declare_reduction
|
||||
! CHECK-SAME: @[[ADD_RED_I32:.*]] : i32 init {
|
||||
! CHECK: ^bb0(%{{.*}}: i32):
|
||||
! CHECK: %[[C0_I32:.*]] = arith.constant 0 : i32
|
||||
! CHECK: omp.yield(%[[C0_I32]] : i32)
|
||||
! CHECK: } combiner {
|
||||
! CHECK: ^bb0(%{{.*}}: i32, %{{.*}}: i32):
|
||||
! CHECK: %[[RES:.*]] = arith.addi %{{.*}}, %{{.*}} : i32
|
||||
! CHECK: omp.yield(%[[RES]] : i32)
|
||||
! CHECK: }
|
||||
|
||||
! CHECK-LABEL: func.func @_QPomp_taskloop_reduction
|
||||
! CHECK: %[[ALLOCA_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomp_taskloop_reductionEi"}
|
||||
! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOCA_I]] {uniq_name = "_QFomp_taskloop_reductionEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
||||
! CHECK: %[[ALLOCA_X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFomp_taskloop_reductionEx"}
|
||||
! CHECK: %[[DECL_X:.*]]:2 = hlfir.declare %[[ALLOCA_X]] {uniq_name = "_QFomp_taskloop_reductionEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
||||
! CHECK: %[[INIT_X:.*]] = arith.constant 0 : i32
|
||||
! CHECK: hlfir.assign %[[INIT_X]] to %[[DECL_X]]#0 : i32, !fir.ref<i32>
|
||||
subroutine omp_taskloop_reduction()
|
||||
integer x
|
||||
x = 0
|
||||
! CHECK: omp.taskloop private(@[[PRIVATE_I]]
|
||||
! CHECK-SAME: %[[DECL_I]]#0 -> %[[ARG0:.*]] : !fir.ref<i32>) reduction(@[[ADD_RED_I32]] %[[DECL_X]]#0 -> %[[ARG1:.*]] : !fir.ref<i32>) {
|
||||
! CHECK: %[[VAL_ARG1:.*]]:2 = hlfir.declare %[[ARG1]]
|
||||
!$omp taskloop reduction(+:x)
|
||||
do i = 1, 100
|
||||
! CHECK: %[[X_VAL:.*]] = fir.load %[[VAL_ARG1]]#0 : !fir.ref<i32>
|
||||
! CHECK: %[[ADD_VAL:.*]] = arith.addi %[[X_VAL]], %{{.*}} : i32
|
||||
x = x + 1
|
||||
! CHECK: hlfir.assign %[[ADD_VAL]] to %[[VAL_ARG1]]#0 : i32, !fir.ref<i32>
|
||||
end do
|
||||
!$omp end taskloop
|
||||
end subroutine omp_taskloop_reduction
|
||||
Reference in New Issue
Block a user