@@ -1250,23 +1250,32 @@ static void addOperand(llvm::SmallVectorImpl<mlir::Value> &operands,
1250
1250
}
1251
1251
1252
1252
template <typename Op, typename Terminator>
1253
- static Op
1254
- createRegionOp (fir::FirOpBuilder &builder, mlir::Location loc,
1255
- const llvm::SmallVectorImpl<mlir::Value> &operands,
1256
- const llvm::SmallVectorImpl<int32_t > &operandSegments) {
1253
+ static Op createRegionOp (fir::FirOpBuilder &builder, mlir::Location loc,
1254
+ Fortran::lower::pft::Evaluation &eval,
1255
+ const llvm::SmallVectorImpl<mlir::Value> &operands,
1256
+ const llvm::SmallVectorImpl<int32_t > &operandSegments,
1257
+ bool outerCombined = false ) {
1257
1258
llvm::ArrayRef<mlir::Type> argTy;
1258
1259
Op op = builder.create <Op>(loc, argTy, operands);
1259
1260
builder.createBlock (&op.getRegion ());
1260
1261
mlir::Block &block = op.getRegion ().back ();
1261
1262
builder.setInsertionPointToStart (&block);
1262
- builder.create <Terminator>(loc);
1263
1263
1264
1264
op->setAttr (Op::getOperandSegmentSizeAttr (),
1265
1265
builder.getDenseI32ArrayAttr (operandSegments));
1266
1266
1267
1267
// Place the insertion point to the start of the first block.
1268
1268
builder.setInsertionPointToStart (&block);
1269
1269
1270
+ // If it is an unstructured region and is not the outer region of a combined
1271
+ // construct, create empty blocks for all evaluations.
1272
+ if (eval.lowerAsUnstructured () && !outerCombined)
1273
+ Fortran::lower::createEmptyRegionBlocks<mlir::acc::TerminatorOp,
1274
+ mlir::acc::YieldOp>(
1275
+ builder, eval.getNestedEvaluations ());
1276
+
1277
+ builder.create <Terminator>(loc);
1278
+ builder.setInsertionPointToStart (&block);
1270
1279
return op;
1271
1280
}
1272
1281
@@ -1347,6 +1356,7 @@ static void genWaitClause(Fortran::lower::AbstractConverter &converter,
1347
1356
static mlir::acc::LoopOp
1348
1357
createLoopOp (Fortran::lower::AbstractConverter &converter,
1349
1358
mlir::Location currentLocation,
1359
+ Fortran::lower::pft::Evaluation &eval,
1350
1360
Fortran::semantics::SemanticsContext &semanticsContext,
1351
1361
Fortran::lower::StatementContext &stmtCtx,
1352
1362
const Fortran::parser::AccClauseList &accClauseList) {
@@ -1455,7 +1465,7 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
1455
1465
addOperands (operands, operandSegments, cacheOperands);
1456
1466
1457
1467
auto loopOp = createRegionOp<mlir::acc::LoopOp, mlir::acc::YieldOp>(
1458
- builder, currentLocation, operands, operandSegments);
1468
+ builder, currentLocation, eval, operands, operandSegments);
1459
1469
1460
1470
if (hasGang)
1461
1471
loopOp.setHasGangAttr (builder.getUnitAttr ());
@@ -1504,6 +1514,7 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
1504
1514
1505
1515
static void genACC (Fortran::lower::AbstractConverter &converter,
1506
1516
Fortran::semantics::SemanticsContext &semanticsContext,
1517
+ Fortran::lower::pft::Evaluation &eval,
1507
1518
const Fortran::parser::OpenACCLoopConstruct &loopConstruct) {
1508
1519
1509
1520
const auto &beginLoopDirective =
@@ -1518,7 +1529,7 @@ static void genACC(Fortran::lower::AbstractConverter &converter,
1518
1529
if (loopDirective.v == llvm::acc::ACCD_loop) {
1519
1530
const auto &accClauseList =
1520
1531
std::get<Fortran::parser::AccClauseList>(beginLoopDirective.t );
1521
- createLoopOp (converter, currentLocation, semanticsContext, stmtCtx,
1532
+ createLoopOp (converter, currentLocation, eval, semanticsContext, stmtCtx,
1522
1533
accClauseList);
1523
1534
}
1524
1535
}
@@ -1551,9 +1562,11 @@ template <typename Op>
1551
1562
static Op
1552
1563
createComputeOp (Fortran::lower::AbstractConverter &converter,
1553
1564
mlir::Location currentLocation,
1565
+ Fortran::lower::pft::Evaluation &eval,
1554
1566
Fortran::semantics::SemanticsContext &semanticsContext,
1555
1567
Fortran::lower::StatementContext &stmtCtx,
1556
- const Fortran::parser::AccClauseList &accClauseList) {
1568
+ const Fortran::parser::AccClauseList &accClauseList,
1569
+ bool outerCombined = false ) {
1557
1570
1558
1571
// Parallel operation operands
1559
1572
mlir::Value async;
@@ -1769,10 +1782,12 @@ createComputeOp(Fortran::lower::AbstractConverter &converter,
1769
1782
Op computeOp;
1770
1783
if constexpr (std::is_same_v<Op, mlir::acc::KernelsOp>)
1771
1784
computeOp = createRegionOp<Op, mlir::acc::TerminatorOp>(
1772
- builder, currentLocation, operands, operandSegments);
1785
+ builder, currentLocation, eval, operands, operandSegments,
1786
+ outerCombined);
1773
1787
else
1774
1788
computeOp = createRegionOp<Op, mlir::acc::YieldOp>(
1775
- builder, currentLocation, operands, operandSegments);
1789
+ builder, currentLocation, eval, operands, operandSegments,
1790
+ outerCombined);
1776
1791
1777
1792
if (addAsyncAttr)
1778
1793
computeOp.setAsyncAttrAttr (builder.getUnitAttr ());
@@ -1817,6 +1832,7 @@ createComputeOp(Fortran::lower::AbstractConverter &converter,
1817
1832
1818
1833
static void genACCDataOp (Fortran::lower::AbstractConverter &converter,
1819
1834
mlir::Location currentLocation,
1835
+ Fortran::lower::pft::Evaluation &eval,
1820
1836
Fortran::semantics::SemanticsContext &semanticsContext,
1821
1837
Fortran::lower::StatementContext &stmtCtx,
1822
1838
const Fortran::parser::AccClauseList &accClauseList) {
@@ -1942,7 +1958,7 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter,
1942
1958
return ;
1943
1959
1944
1960
auto dataOp = createRegionOp<mlir::acc::DataOp, mlir::acc::TerminatorOp>(
1945
- builder, currentLocation, operands, operandSegments);
1961
+ builder, currentLocation, eval, operands, operandSegments);
1946
1962
1947
1963
dataOp.setAsyncAttr (addAsyncAttr);
1948
1964
dataOp.setWaitAttr (addWaitAttr);
@@ -1971,6 +1987,7 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter,
1971
1987
static void
1972
1988
genACCHostDataOp (Fortran::lower::AbstractConverter &converter,
1973
1989
mlir::Location currentLocation,
1990
+ Fortran::lower::pft::Evaluation &eval,
1974
1991
Fortran::semantics::SemanticsContext &semanticsContext,
1975
1992
Fortran::lower::StatementContext &stmtCtx,
1976
1993
const Fortran::parser::AccClauseList &accClauseList) {
@@ -2020,7 +2037,7 @@ genACCHostDataOp(Fortran::lower::AbstractConverter &converter,
2020
2037
2021
2038
auto hostDataOp =
2022
2039
createRegionOp<mlir::acc::HostDataOp, mlir::acc::TerminatorOp>(
2023
- builder, currentLocation, operands, operandSegments);
2040
+ builder, currentLocation, eval, operands, operandSegments);
2024
2041
2025
2042
if (addIfPresentAttr)
2026
2043
hostDataOp.setIfPresentAttr (builder.getUnitAttr ());
@@ -2029,6 +2046,7 @@ genACCHostDataOp(Fortran::lower::AbstractConverter &converter,
2029
2046
static void
2030
2047
genACC (Fortran::lower::AbstractConverter &converter,
2031
2048
Fortran::semantics::SemanticsContext &semanticsContext,
2049
+ Fortran::lower::pft::Evaluation &eval,
2032
2050
const Fortran::parser::OpenACCBlockConstruct &blockConstruct) {
2033
2051
const auto &beginBlockDirective =
2034
2052
std::get<Fortran::parser::AccBeginBlockDirective>(blockConstruct.t );
@@ -2041,26 +2059,30 @@ genACC(Fortran::lower::AbstractConverter &converter,
2041
2059
Fortran::lower::StatementContext stmtCtx;
2042
2060
2043
2061
if (blockDirective.v == llvm::acc::ACCD_parallel) {
2044
- createComputeOp<mlir::acc::ParallelOp>(
2045
- converter, currentLocation, semanticsContext, stmtCtx, accClauseList);
2062
+ createComputeOp<mlir::acc::ParallelOp>(converter, currentLocation, eval,
2063
+ semanticsContext, stmtCtx,
2064
+ accClauseList);
2046
2065
} else if (blockDirective.v == llvm::acc::ACCD_data) {
2047
- genACCDataOp (converter, currentLocation, semanticsContext, stmtCtx,
2066
+ genACCDataOp (converter, currentLocation, eval, semanticsContext, stmtCtx,
2048
2067
accClauseList);
2049
2068
} else if (blockDirective.v == llvm::acc::ACCD_serial) {
2050
- createComputeOp<mlir::acc::SerialOp>(
2051
- converter, currentLocation, semanticsContext, stmtCtx, accClauseList);
2069
+ createComputeOp<mlir::acc::SerialOp>(converter, currentLocation, eval,
2070
+ semanticsContext, stmtCtx,
2071
+ accClauseList);
2052
2072
} else if (blockDirective.v == llvm::acc::ACCD_kernels) {
2053
- createComputeOp<mlir::acc::KernelsOp>(
2054
- converter, currentLocation, semanticsContext, stmtCtx, accClauseList);
2073
+ createComputeOp<mlir::acc::KernelsOp>(converter, currentLocation, eval,
2074
+ semanticsContext, stmtCtx,
2075
+ accClauseList);
2055
2076
} else if (blockDirective.v == llvm::acc::ACCD_host_data) {
2056
- genACCHostDataOp (converter, currentLocation, semanticsContext, stmtCtx ,
2057
- accClauseList);
2077
+ genACCHostDataOp (converter, currentLocation, eval, semanticsContext ,
2078
+ stmtCtx, accClauseList);
2058
2079
}
2059
2080
}
2060
2081
2061
2082
static void
2062
2083
genACC (Fortran::lower::AbstractConverter &converter,
2063
2084
Fortran::semantics::SemanticsContext &semanticsContext,
2085
+ Fortran::lower::pft::Evaluation &eval,
2064
2086
const Fortran::parser::OpenACCCombinedConstruct &combinedConstruct) {
2065
2087
const auto &beginCombinedDirective =
2066
2088
std::get<Fortran::parser::AccBeginCombinedDirective>(combinedConstruct.t );
@@ -2075,18 +2097,21 @@ genACC(Fortran::lower::AbstractConverter &converter,
2075
2097
2076
2098
if (combinedDirective.v == llvm::acc::ACCD_kernels_loop) {
2077
2099
createComputeOp<mlir::acc::KernelsOp>(
2078
- converter, currentLocation, semanticsContext, stmtCtx, accClauseList);
2079
- createLoopOp (converter, currentLocation, semanticsContext, stmtCtx,
2100
+ converter, currentLocation, eval, semanticsContext, stmtCtx,
2101
+ accClauseList, /* outerCombined=*/ true );
2102
+ createLoopOp (converter, currentLocation, eval, semanticsContext, stmtCtx,
2080
2103
accClauseList);
2081
2104
} else if (combinedDirective.v == llvm::acc::ACCD_parallel_loop) {
2082
2105
createComputeOp<mlir::acc::ParallelOp>(
2083
- converter, currentLocation, semanticsContext, stmtCtx, accClauseList);
2084
- createLoopOp (converter, currentLocation, semanticsContext, stmtCtx,
2106
+ converter, currentLocation, eval, semanticsContext, stmtCtx,
2107
+ accClauseList, /* outerCombined=*/ true );
2108
+ createLoopOp (converter, currentLocation, eval, semanticsContext, stmtCtx,
2085
2109
accClauseList);
2086
2110
} else if (combinedDirective.v == llvm::acc::ACCD_serial_loop) {
2087
- createComputeOp<mlir::acc::SerialOp>(
2088
- converter, currentLocation, semanticsContext, stmtCtx, accClauseList);
2089
- createLoopOp (converter, currentLocation, semanticsContext, stmtCtx,
2111
+ createComputeOp<mlir::acc::SerialOp>(converter, currentLocation, eval,
2112
+ semanticsContext, stmtCtx,
2113
+ accClauseList, /* outerCombined=*/ true );
2114
+ createLoopOp (converter, currentLocation, eval, semanticsContext, stmtCtx,
2090
2115
accClauseList);
2091
2116
} else {
2092
2117
llvm::report_fatal_error (" Unknown combined construct encountered" );
@@ -3169,14 +3194,14 @@ void Fortran::lower::genOpenACCConstruct(
3169
3194
std::visit (
3170
3195
common::visitors{
3171
3196
[&](const Fortran::parser::OpenACCBlockConstruct &blockConstruct) {
3172
- genACC (converter, semanticsContext, blockConstruct);
3197
+ genACC (converter, semanticsContext, eval, blockConstruct);
3173
3198
},
3174
3199
[&](const Fortran::parser::OpenACCCombinedConstruct
3175
3200
&combinedConstruct) {
3176
- genACC (converter, semanticsContext, combinedConstruct);
3201
+ genACC (converter, semanticsContext, eval, combinedConstruct);
3177
3202
},
3178
3203
[&](const Fortran::parser::OpenACCLoopConstruct &loopConstruct) {
3179
- genACC (converter, semanticsContext, loopConstruct);
3204
+ genACC (converter, semanticsContext, eval, loopConstruct);
3180
3205
},
3181
3206
[&](const Fortran::parser::OpenACCStandaloneConstruct
3182
3207
&standaloneConstruct) {
0 commit comments