Skip to content

Commit 6bb9b27

Browse files
committed
[flang][OpenMP] Add basic support to lower loop to MLIR
Adds initial support for lowering the `loop` directive to MLIR. So far, we only support `private` and `collpase` clauses. Other clauses will be enabled and tested in later PRs.
1 parent 312ce29 commit 6bb9b27

File tree

6 files changed

+111
-17
lines changed

6 files changed

+111
-17
lines changed

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2023,6 +2023,45 @@ static void genStandaloneDo(lower::AbstractConverter &converter,
20232023
llvm::omp::Directive::OMPD_do, dsp);
20242024
}
20252025

2026+
static void genLoopClauses(lower::AbstractConverter &converter,
2027+
semantics::SemanticsContext &semaCtx,
2028+
const List<Clause> &clauses, mlir::Location loc,
2029+
mlir::omp::LoopOperands &clauseOps) {
2030+
ClauseProcessor cp(converter, semaCtx, clauses);
2031+
cp.processTODO<clause::Bind, clause::Lastprivate, clause::Order,
2032+
clause::Reduction>(loc, llvm::omp::Directive::OMPD_loop);
2033+
}
2034+
2035+
static void genLoopOp(lower::AbstractConverter &converter,
2036+
lower::SymMap &symTable,
2037+
semantics::SemanticsContext &semaCtx,
2038+
lower::pft::Evaluation &eval, mlir::Location loc,
2039+
const ConstructQueue &queue,
2040+
ConstructQueue::const_iterator item) {
2041+
mlir::omp::LoopOperands loopClauseOps;
2042+
genLoopClauses(converter, semaCtx, item->clauses, loc, loopClauseOps);
2043+
2044+
DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval,
2045+
/*shouldCollectPreDeterminedSymbols=*/true,
2046+
/*useDelayedPrivatization=*/true, &symTable);
2047+
dsp.processStep1(&loopClauseOps);
2048+
2049+
mlir::omp::LoopNestOperands loopNestClauseOps;
2050+
llvm::SmallVector<const semantics::Symbol *> iv;
2051+
genLoopNestClauses(converter, semaCtx, eval, item->clauses, loc,
2052+
loopNestClauseOps, iv);
2053+
2054+
EntryBlockArgs loopArgs;
2055+
loopArgs.priv.syms = dsp.getDelayedPrivSymbols();
2056+
loopArgs.priv.vars = loopClauseOps.privateVars;
2057+
2058+
auto loopOp =
2059+
genWrapperOp<mlir::omp::LoopOp>(converter, loc, loopClauseOps, loopArgs);
2060+
genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, item,
2061+
loopNestClauseOps, iv, {{loopOp, loopArgs}},
2062+
llvm::omp::Directive::OMPD_loop, dsp);
2063+
}
2064+
20262065
static void genStandaloneParallel(lower::AbstractConverter &converter,
20272066
lower::SymMap &symTable,
20282067
semantics::SemanticsContext &semaCtx,
@@ -2459,7 +2498,7 @@ static void genOMPDispatch(lower::AbstractConverter &converter,
24592498
genStandaloneDo(converter, symTable, semaCtx, eval, loc, queue, item);
24602499
break;
24612500
case llvm::omp::Directive::OMPD_loop:
2462-
TODO(loc, "Unhandled directive " + llvm::omp::getOpenMPDirectiveName(dir));
2501+
genLoopOp(converter, symTable, semaCtx, eval, loc, queue, item);
24632502
break;
24642503
case llvm::omp::Directive::OMPD_masked:
24652504
genMaskedOp(converter, symTable, semaCtx, eval, loc, queue, item);

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

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
! This test checks lowering of OpenMP loop Directive.
2+
3+
! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
4+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
5+
6+
! CHECK: omp.private {type = private} @[[DUMMY_PRIV:.*test_privateEdummy_private.*]] : !fir.ref<i32>
7+
! CHECK: omp.private {type = private} @[[I_PRIV:.*test_no_clausesEi.*]] : !fir.ref<i32>
8+
9+
! CHECK-LABEL: func.func @_QPtest_no_clauses
10+
subroutine test_no_clauses()
11+
integer :: i, j, dummy = 1
12+
13+
! CHECK: omp.loop private(@[[I_PRIV]] %{{.*}}#0 -> %[[ARG:.*]] : !fir.ref<i32>) {
14+
! CHECK: omp.loop_nest (%[[IV:.*]]) : i32 = (%{{.*}}) to (%{{.*}}) {{.*}} {
15+
! CHECK: %[[ARG_DECL:.*]]:2 = hlfir.declare %[[ARG]]
16+
! CHECK: fir.store %[[IV]] to %[[ARG_DECL]]#1 : !fir.ref<i32>
17+
! CHECK: }
18+
! CHECK: }
19+
!$omp loop
20+
do i=1,10
21+
dummy = dummy + 1
22+
end do
23+
!$omp end loop
24+
end subroutine
25+
26+
! CHECK-LABEL: func.func @_QPtest_collapse
27+
subroutine test_collapse()
28+
integer :: i, j, dummy = 1
29+
! CHECK: omp.loop private(@{{.*}} %{{.*}}#0 -> %{{.*}}, @{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) {
30+
! CHECK: omp.loop_nest (%{{.*}}, %{{.*}}) : i32 {{.*}} {
31+
! CHECK: }
32+
! CHECK: }
33+
!$omp loop collapse(2)
34+
do i=1,10
35+
do j=2,20
36+
dummy = dummy + 1
37+
end do
38+
end do
39+
!$omp end loop
40+
end subroutine
41+
42+
! CHECK-LABEL: func.func @_QPtest_private
43+
subroutine test_private()
44+
integer :: i, dummy = 1
45+
! CHECK: omp.loop private(@[[DUMMY_PRIV]] %{{.*}}#0 -> %{{.*}}, @{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) {
46+
! CHECK: omp.loop_nest (%{{.*}}) : i32 = (%{{.*}}) to (%{{.*}}) {{.*}} {
47+
! CHECK: }
48+
! CHECK: }
49+
!$omp loop private(dummy)
50+
do i=1,10
51+
dummy = dummy + 1
52+
end do
53+
!$omp end loop
54+
end subroutine

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,10 @@ def LoopOp : OpenMP_Op<"loop", traits = [
422422
$reduction_syms) attr-dict
423423
}];
424424

425+
let builders = [
426+
OpBuilder<(ins CArg<"const LoopOperands &">:$clauses)>
427+
];
428+
425429
let hasVerifier = 1;
426430
let hasRegionVerifier = 1;
427431
}

mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ void mlir::configureOpenMPToLLVMConversionLegality(
238238
omp::ParallelOp, omp::PrivateClauseOp, omp::SectionOp, omp::SectionsOp,
239239
omp::SimdOp, omp::SingleOp, omp::TargetDataOp, omp::TargetOp,
240240
omp::TaskgroupOp, omp::TaskloopOp, omp::TaskOp, omp::TeamsOp,
241-
omp::WsloopOp>([&](Operation *op) {
241+
omp::WsloopOp, omp::LoopOp>([&](Operation *op) {
242242
return std::all_of(op->getRegions().begin(), op->getRegions().end(),
243243
[&](Region &region) {
244244
return typeConverter.isLegal(&region);
@@ -284,6 +284,7 @@ void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter,
284284
RegionOpConversion<omp::TargetOp>, RegionOpConversion<omp::TaskgroupOp>,
285285
RegionOpConversion<omp::TaskloopOp>, RegionOpConversion<omp::TaskOp>,
286286
RegionOpConversion<omp::TeamsOp>, RegionOpConversion<omp::WsloopOp>,
287+
RegionOpConversion<omp::LoopOp>,
287288
RegionOpWithVarOperandsConversion<omp::AtomicUpdateOp>>(converter);
288289
}
289290

mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1952,6 +1952,17 @@ LogicalResult LoopWrapperInterface::verifyImpl() {
19521952
// LoopOp
19531953
//===----------------------------------------------------------------------===//
19541954

1955+
void LoopOp::build(OpBuilder &builder, OperationState &state,
1956+
const LoopOperands &clauses) {
1957+
MLIRContext *ctx = builder.getContext();
1958+
1959+
LoopOp::build(builder, state, clauses.bindKind, clauses.privateVars,
1960+
makeArrayAttr(ctx, clauses.privateSyms), clauses.order,
1961+
clauses.orderMod, clauses.reductionVars,
1962+
makeDenseBoolArrayAttr(ctx, clauses.reductionByref),
1963+
makeArrayAttr(ctx, clauses.reductionSyms));
1964+
}
1965+
19551966
LogicalResult LoopOp::verify() {
19561967
return verifyReductionVarList(*this, getReductionSyms(), getReductionVars(),
19571968
getReductionByref());

0 commit comments

Comments
 (0)