@@ -336,7 +336,7 @@ static void genDeclareDataOperandOperationsWithModifier(
336
336
template <typename EntryOp, typename ExitOp>
337
337
static void genDataExitOperations (fir::FirOpBuilder &builder,
338
338
llvm::SmallVector<mlir::Value> operands,
339
- bool structured, bool implicit ) {
339
+ bool structured) {
340
340
for (mlir::Value operand : operands) {
341
341
auto entryOp = mlir::dyn_cast_or_null<EntryOp>(operand.getDefiningOp ());
342
342
assert (entryOp && " data entry op expected" );
@@ -346,7 +346,7 @@ static void genDataExitOperations(fir::FirOpBuilder &builder,
346
346
varPtr = entryOp.getVarPtr ();
347
347
builder.create <ExitOp>(entryOp.getLoc (), entryOp.getAccPtr (), varPtr,
348
348
entryOp.getBounds (), entryOp.getDataClause (),
349
- structured, implicit ,
349
+ structured, entryOp. getImplicit () ,
350
350
builder.getStringAttr (*entryOp.getName ()));
351
351
}
352
352
}
@@ -1872,9 +1872,24 @@ createComputeOp(Fortran::lower::AbstractConverter &converter,
1872
1872
} else if (const auto *reductionClause =
1873
1873
std::get_if<Fortran::parser::AccClause::Reduction>(
1874
1874
&clause.u )) {
1875
- if (!outerCombined)
1875
+ // A reduction clause on a combined construct is treated as if it appeared
1876
+ // on the loop construct. So don't generate a reduction clause when it is
1877
+ // combined - delay it to the loop. However, a reduction clause on a
1878
+ // combined construct implies a copy clause so issue an implicit copy
1879
+ // instead.
1880
+ if (!outerCombined) {
1876
1881
genReductions (reductionClause->v , converter, semanticsContext, stmtCtx,
1877
1882
reductionOperands, reductionRecipes);
1883
+ } else {
1884
+ auto crtDataStart = dataClauseOperands.size ();
1885
+ genDataOperandOperations<mlir::acc::CopyinOp>(
1886
+ std::get<Fortran::parser::AccObjectList>(reductionClause->v .t ),
1887
+ converter, semanticsContext, stmtCtx, dataClauseOperands,
1888
+ mlir::acc::DataClause::acc_reduction,
1889
+ /* structured=*/ true , /* implicit=*/ true );
1890
+ copyEntryOperands.append (dataClauseOperands.begin () + crtDataStart,
1891
+ dataClauseOperands.end ());
1892
+ }
1878
1893
} else if (const auto *defaultClause =
1879
1894
std::get_if<Fortran::parser::AccClause::Default>(
1880
1895
&clause.u )) {
@@ -1944,13 +1959,13 @@ createComputeOp(Fortran::lower::AbstractConverter &converter,
1944
1959
1945
1960
// Create the exit operations after the region.
1946
1961
genDataExitOperations<mlir::acc::CopyinOp, mlir::acc::CopyoutOp>(
1947
- builder, copyEntryOperands, /* structured=*/ true , /* implicit= */ false );
1962
+ builder, copyEntryOperands, /* structured=*/ true );
1948
1963
genDataExitOperations<mlir::acc::CreateOp, mlir::acc::CopyoutOp>(
1949
- builder, copyoutEntryOperands, /* structured=*/ true , /* implicit= */ false );
1964
+ builder, copyoutEntryOperands, /* structured=*/ true );
1950
1965
genDataExitOperations<mlir::acc::AttachOp, mlir::acc::DetachOp>(
1951
- builder, attachEntryOperands, /* structured=*/ true , /* implicit= */ false );
1966
+ builder, attachEntryOperands, /* structured=*/ true );
1952
1967
genDataExitOperations<mlir::acc::CreateOp, mlir::acc::DeleteOp>(
1953
- builder, createEntryOperands, /* structured=*/ true , /* implicit= */ false );
1968
+ builder, createEntryOperands, /* structured=*/ true );
1954
1969
1955
1970
builder.restoreInsertionPoint (insPt);
1956
1971
return computeOp;
@@ -2099,13 +2114,13 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter,
2099
2114
2100
2115
// Create the exit operations after the region.
2101
2116
genDataExitOperations<mlir::acc::CopyinOp, mlir::acc::CopyoutOp>(
2102
- builder, copyEntryOperands, /* structured=*/ true , /* implicit= */ false );
2117
+ builder, copyEntryOperands, /* structured=*/ true );
2103
2118
genDataExitOperations<mlir::acc::CreateOp, mlir::acc::CopyoutOp>(
2104
- builder, copyoutEntryOperands, /* structured=*/ true , /* implicit= */ false );
2119
+ builder, copyoutEntryOperands, /* structured=*/ true );
2105
2120
genDataExitOperations<mlir::acc::AttachOp, mlir::acc::DetachOp>(
2106
- builder, attachEntryOperands, /* structured=*/ true , /* implicit= */ false );
2121
+ builder, attachEntryOperands, /* structured=*/ true );
2107
2122
genDataExitOperations<mlir::acc::CreateOp, mlir::acc::DeleteOp>(
2108
- builder, createEntryOperands, /* structured=*/ true , /* implicit= */ false );
2123
+ builder, createEntryOperands, /* structured=*/ true );
2109
2124
2110
2125
builder.restoreInsertionPoint (insPt);
2111
2126
}
@@ -2415,11 +2430,11 @@ genACCExitDataOp(Fortran::lower::AbstractConverter &converter,
2415
2430
exitDataOp.setFinalizeAttr (builder.getUnitAttr ());
2416
2431
2417
2432
genDataExitOperations<mlir::acc::GetDevicePtrOp, mlir::acc::CopyoutOp>(
2418
- builder, copyoutOperands, /* structured=*/ false , /* implicit= */ false );
2433
+ builder, copyoutOperands, /* structured=*/ false );
2419
2434
genDataExitOperations<mlir::acc::GetDevicePtrOp, mlir::acc::DeleteOp>(
2420
- builder, deleteOperands, /* structured=*/ false , /* implicit= */ false );
2435
+ builder, deleteOperands, /* structured=*/ false );
2421
2436
genDataExitOperations<mlir::acc::GetDevicePtrOp, mlir::acc::DetachOp>(
2422
- builder, detachOperands, /* structured=*/ false , /* implicit= */ false );
2437
+ builder, detachOperands, /* structured=*/ false );
2423
2438
}
2424
2439
2425
2440
template <typename Op>
@@ -2594,7 +2609,7 @@ genACCUpdateOp(Fortran::lower::AbstractConverter &converter,
2594
2609
builder, currentLocation, operands, operandSegments);
2595
2610
2596
2611
genDataExitOperations<mlir::acc::GetDevicePtrOp, mlir::acc::UpdateHostOp>(
2597
- builder, updateHostOperands, /* structured=*/ false , /* implicit= */ false );
2612
+ builder, updateHostOperands, /* structured=*/ false );
2598
2613
2599
2614
if (addAsyncAttr)
2600
2615
updateOp.setAsyncAttr (builder.getUnitAttr ());
@@ -3054,17 +3069,14 @@ genDeclareInFunction(Fortran::lower::AbstractConverter &converter,
3054
3069
builder.setInsertionPointAfter (declareOp);
3055
3070
}
3056
3071
genDataExitOperations<mlir::acc::CreateOp, mlir::acc::DeleteOp>(
3057
- builder, createEntryOperands, /* structured=*/ true ,
3058
- /* implicit=*/ false );
3072
+ builder, createEntryOperands, /* structured=*/ true );
3059
3073
genDataExitOperations<mlir::acc::DeclareDeviceResidentOp,
3060
3074
mlir::acc::DeleteOp>(
3061
- builder, deviceResidentEntryOperands, /* structured=*/ true ,
3062
- /* implicit=*/ false );
3075
+ builder, deviceResidentEntryOperands, /* structured=*/ true );
3063
3076
genDataExitOperations<mlir::acc::CopyinOp, mlir::acc::CopyoutOp>(
3064
- builder, copyEntryOperands, /* structured=*/ true , /* implicit= */ false );
3077
+ builder, copyEntryOperands, /* structured=*/ true );
3065
3078
genDataExitOperations<mlir::acc::CreateOp, mlir::acc::CopyoutOp>(
3066
- builder, copyoutEntryOperands, /* structured=*/ true ,
3067
- /* implicit=*/ false );
3079
+ builder, copyoutEntryOperands, /* structured=*/ true );
3068
3080
});
3069
3081
}
3070
3082
0 commit comments