@@ -758,15 +758,33 @@ genBodyOfTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
758
758
llvm::ArrayRef<const semantics::Symbol *> mapSyms,
759
759
llvm::ArrayRef<mlir::Location> mapSymLocs,
760
760
llvm::ArrayRef<mlir::Type> mapSymTypes,
761
+ DataSharingProcessor &dsp,
761
762
const mlir::Location ¤tLocation,
762
763
const ConstructQueue &queue, ConstructQueue::iterator item) {
763
764
assert (mapSymTypes.size () == mapSymLocs.size ());
764
765
765
766
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
766
767
mlir::Region ®ion = targetOp.getRegion ();
767
-
768
- auto *regionBlock =
769
- firOpBuilder.createBlock (®ion, {}, mapSymTypes, mapSymLocs);
768
+ mlir::OperandRange privateVars = targetOp.getPrivateVars ();
769
+
770
+ llvm::SmallVector<mlir::Type> allRegionArgTypes;
771
+ allRegionArgTypes.reserve (mapSymTypes.size () +
772
+ targetOp.getPrivateVars ().size ());
773
+ llvm::transform (mapSymTypes, std::back_inserter (allRegionArgTypes),
774
+ [](mlir::Type t) { return t; });
775
+ llvm::transform (privateVars, std::back_inserter (allRegionArgTypes),
776
+ [](mlir::Value v) { return v.getType (); });
777
+
778
+ llvm::SmallVector<mlir::Location> allRegionArgLocs;
779
+ allRegionArgTypes.reserve (mapSymTypes.size () +
780
+ targetOp.getPrivateVars ().size ());
781
+ llvm::transform (mapSymLocs, std::back_inserter (allRegionArgLocs),
782
+ [](mlir::Location l) { return l; });
783
+ llvm::transform (privateVars, std::back_inserter (allRegionArgLocs),
784
+ [](mlir::Value v) { return v.getLoc (); });
785
+
786
+ auto *regionBlock = firOpBuilder.createBlock (®ion, {}, allRegionArgTypes,
787
+ allRegionArgLocs);
770
788
771
789
// Clones the `bounds` placing them inside the target region and returns them.
772
790
auto cloneBound = [&](mlir::Value bound) {
@@ -830,6 +848,20 @@ genBodyOfTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
830
848
});
831
849
}
832
850
851
+ for (auto [argIndex, argSymbol] :
852
+ llvm::enumerate (dsp.getAllSymbolsToPrivatize ())) {
853
+ argIndex = mapSyms.size () + argIndex;
854
+
855
+ const mlir::BlockArgument &arg = region.getArgument (argIndex);
856
+ converter.bindSymbol (*argSymbol,
857
+ hlfir::translateToExtendedValue (
858
+ currentLocation, firOpBuilder, hlfir::Entity{arg},
859
+ /* contiguousHint=*/
860
+ evaluate::IsSimplyContiguous (
861
+ *argSymbol, converter.getFoldingContext ()))
862
+ .first );
863
+ }
864
+
833
865
// Check if cloning the bounds introduced any dependency on the outer region.
834
866
// If so, then either clone them as well if they are MemoryEffectFree, or else
835
867
// copy them to a new temporary and add them to the map and block_argument
@@ -907,6 +939,8 @@ genBodyOfTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
907
939
} else {
908
940
genNestedEvaluations (converter, eval);
909
941
}
942
+
943
+ dsp.processStep2 (targetOp, /* isLoop=*/ false );
910
944
}
911
945
912
946
template <typename OpTy, typename ... Args>
@@ -1048,15 +1082,18 @@ static void genTargetClauses(
1048
1082
devicePtrSyms);
1049
1083
cp.processMap (loc, stmtCtx, clauseOps, &mapSyms, &mapLocs, &mapTypes);
1050
1084
cp.processThreadLimit (stmtCtx, clauseOps);
1051
- // TODO Support delayed privatization.
1052
1085
1053
1086
if (processHostOnlyClauses)
1054
1087
cp.processNowait (clauseOps);
1055
1088
1056
1089
cp.processTODO <clause::Allocate, clause::Defaultmap, clause::Firstprivate,
1057
- clause::InReduction, clause::Private, clause:: Reduction,
1090
+ clause::InReduction, clause::Reduction,
1058
1091
clause::UsesAllocators>(loc,
1059
1092
llvm::omp::Directive::OMPD_target);
1093
+
1094
+ // `target private(..)` is only supported in delayed privatization mode.
1095
+ if (!enableDelayedPrivatization)
1096
+ cp.processTODO <clause::Private>(loc, llvm::omp::Directive::OMPD_target);
1060
1097
}
1061
1098
1062
1099
static void genTargetDataClauses (
@@ -1289,7 +1326,6 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
1289
1326
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
1290
1327
lower::StatementContext stmtCtx;
1291
1328
mlir::omp::ParallelClauseOps clauseOps;
1292
- llvm::SmallVector<const semantics::Symbol *> privateSyms;
1293
1329
llvm::SmallVector<mlir::Type> reductionTypes;
1294
1330
llvm::SmallVector<const semantics::Symbol *> reductionSyms;
1295
1331
genParallelClauses (converter, semaCtx, stmtCtx, item->clauses , loc,
@@ -1319,7 +1355,7 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
1319
1355
/* useDelayedPrivatization=*/ true , &symTable);
1320
1356
1321
1357
if (privatize)
1322
- dsp.processStep1 (&clauseOps, &privateSyms );
1358
+ dsp.processStep1 (&clauseOps);
1323
1359
1324
1360
auto genRegionEntryCB = [&](mlir::Operation *op) {
1325
1361
auto parallelOp = llvm::cast<mlir::omp::ParallelOp>(op);
@@ -1344,9 +1380,10 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
1344
1380
privateVarLocs);
1345
1381
1346
1382
llvm::SmallVector<const semantics::Symbol *> allSymbols = reductionSyms;
1347
- allSymbols.append (privateSyms);
1383
+ allSymbols.append (dsp.getAllSymbolsToPrivatize ().begin (),
1384
+ dsp.getAllSymbolsToPrivatize ().end ());
1385
+
1348
1386
for (auto [arg, prv] : llvm::zip_equal (allSymbols, region.getArguments ())) {
1349
- fir::ExtendedValue hostExV = converter.getSymbolExtendedValue (*arg);
1350
1387
converter.bindSymbol (*arg, hlfir::translateToExtendedValue (
1351
1388
loc, firOpBuilder, hlfir::Entity{prv},
1352
1389
/* contiguousHint=*/
@@ -1541,11 +1578,22 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
1541
1578
deviceAddrLocs, deviceAddrTypes, devicePtrSyms,
1542
1579
devicePtrLocs, devicePtrTypes);
1543
1580
1581
+ llvm::SmallVector<const semantics::Symbol *> privateSyms;
1582
+ DataSharingProcessor dsp (converter, semaCtx, item->clauses , eval,
1583
+ /* shouldCollectPreDeterminedSymbols=*/
1584
+ lower::omp::isLastItemInQueue (item, queue),
1585
+ /* useDelayedPrivatization=*/ true , &symTable);
1586
+ dsp.processStep1 (&clauseOps);
1587
+
1544
1588
// 5.8.1 Implicit Data-Mapping Attribute Rules
1545
1589
// The following code follows the implicit data-mapping rules to map all the
1546
- // symbols used inside the region that have not been explicitly mapped using
1547
- // the map clause.
1590
+ // symbols used inside the region that do not have explicit data-environment
1591
+ // attribute clauses (neither data-sharing; e.g. `private`, nor `map`
1592
+ // clauses).
1548
1593
auto captureImplicitMap = [&](const semantics::Symbol &sym) {
1594
+ if (dsp.getAllSymbolsToPrivatize ().contains (&sym))
1595
+ return ;
1596
+
1549
1597
if (llvm::find (mapSyms, &sym) == mapSyms.end ()) {
1550
1598
mlir::Value baseOp = converter.getSymbolAddress (sym);
1551
1599
if (!baseOp)
@@ -1632,7 +1680,7 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
1632
1680
1633
1681
auto targetOp = firOpBuilder.create <mlir::omp::TargetOp>(loc, clauseOps);
1634
1682
genBodyOfTargetOp (converter, symTable, semaCtx, eval, targetOp, mapSyms,
1635
- mapLocs, mapTypes, loc, queue, item);
1683
+ mapLocs, mapTypes, dsp, loc, queue, item);
1636
1684
return targetOp;
1637
1685
}
1638
1686
0 commit comments