@@ -169,12 +169,15 @@ class DataSharingProcessor {
169
169
void collectSymbolsForPrivatization ();
170
170
void insertBarrier ();
171
171
void collectDefaultSymbols ();
172
- void privatize ();
172
+ void
173
+ privatize (llvm::SetVector<mlir::omp::PrivateClauseOp> *privateInitializers);
173
174
void defaultPrivatize ();
174
175
void copyLastPrivatize (mlir::Operation *op);
175
176
void insertLastPrivateCompare (mlir::Operation *op);
176
- void cloneSymbol (const Fortran::semantics::Symbol *sym);
177
- void copyFirstPrivateSymbol (const Fortran::semantics::Symbol *sym);
177
+ void cloneSymbol (const Fortran::semantics::Symbol *sym,
178
+ Fortran::lower::SymMap *symMap = nullptr );
179
+ void copyFirstPrivateSymbol (const Fortran::semantics::Symbol *sym,
180
+ Fortran::lower::SymMap *symMap);
178
181
void copyLastPrivateSymbol (const Fortran::semantics::Symbol *sym,
179
182
mlir::OpBuilder::InsertPoint *lastPrivIP);
180
183
void insertDeallocs ();
@@ -197,7 +200,8 @@ class DataSharingProcessor {
197
200
// Step2 performs the copying for lastprivates and requires knowledge of the
198
201
// MLIR operation to insert the last private update. Step2 adds
199
202
// dealocation code as well.
200
- void processStep1 ();
203
+ void processStep1 (llvm::SetVector<mlir::omp::PrivateClauseOp>
204
+ *privateInitializers = nullptr );
201
205
void processStep2 (mlir::Operation *op, bool isLoop);
202
206
203
207
void setLoopIV (mlir::Value iv) {
@@ -206,10 +210,11 @@ class DataSharingProcessor {
206
210
}
207
211
};
208
212
209
- void DataSharingProcessor::processStep1 () {
213
+ void DataSharingProcessor::processStep1 (
214
+ llvm::SetVector<mlir::omp::PrivateClauseOp> *privateInitializers) {
210
215
collectSymbolsForPrivatization ();
211
216
collectDefaultSymbols ();
212
- privatize ();
217
+ privatize (privateInitializers );
213
218
defaultPrivatize ();
214
219
insertBarrier ();
215
220
}
@@ -239,20 +244,23 @@ void DataSharingProcessor::insertDeallocs() {
239
244
}
240
245
}
241
246
242
- void DataSharingProcessor::cloneSymbol (const Fortran::semantics::Symbol *sym) {
247
+ void DataSharingProcessor::cloneSymbol (const Fortran::semantics::Symbol *sym,
248
+ Fortran::lower::SymMap *symMap) {
243
249
// Privatization for symbols which are pre-determined (like loop index
244
250
// variables) happen separately, for everything else privatize here.
245
251
if (sym->test (Fortran::semantics::Symbol::Flag::OmpPreDetermined))
246
252
return ;
247
- bool success = converter.createHostAssociateVarClone (*sym);
253
+ bool success = converter.createHostAssociateVarClone (*sym, symMap );
248
254
(void )success;
249
255
assert (success && " Privatization failed due to existing binding" );
250
256
}
251
257
252
258
void DataSharingProcessor::copyFirstPrivateSymbol (
253
- const Fortran::semantics::Symbol *sym) {
254
- if (sym->test (Fortran::semantics::Symbol::Flag::OmpFirstPrivate))
255
- converter.copyHostAssociateVar (*sym);
259
+ const Fortran::semantics::Symbol *sym,
260
+ Fortran::lower::SymMap *symMap = nullptr ) {
261
+ if (sym->test (Fortran::semantics::Symbol::Flag::OmpFirstPrivate)) {
262
+ converter.copyHostAssociateVar (*sym, nullptr , symMap);
263
+ }
256
264
}
257
265
258
266
void DataSharingProcessor::copyLastPrivateSymbol (
@@ -487,15 +495,54 @@ void DataSharingProcessor::collectDefaultSymbols() {
487
495
}
488
496
}
489
497
490
- void DataSharingProcessor::privatize () {
498
+ void DataSharingProcessor::privatize (
499
+ llvm::SetVector<mlir::omp::PrivateClauseOp> *privateInitializers) {
500
+
491
501
for (const Fortran::semantics::Symbol *sym : privatizedSymbols) {
502
+
492
503
if (const auto *commonDet =
493
504
sym->detailsIf <Fortran::semantics::CommonBlockDetails>()) {
494
505
for (const auto &mem : commonDet->objects ()) {
495
506
cloneSymbol (&*mem);
496
507
copyFirstPrivateSymbol (&*mem);
497
508
}
498
509
} else {
510
+ if (privateInitializers != nullptr ) {
511
+ auto ip = firOpBuilder.saveInsertionPoint ();
512
+
513
+ auto moduleOp = firOpBuilder.getInsertionBlock ()
514
+ ->getParentOp ()
515
+ ->getParentOfType <mlir::ModuleOp>();
516
+
517
+ firOpBuilder.setInsertionPoint (&moduleOp.getBodyRegion ().front (),
518
+ moduleOp.getBodyRegion ().front ().end ());
519
+
520
+ Fortran::lower::SymbolBox hsb = converter.lookupOneLevelUpSymbol (*sym);
521
+ assert (hsb && " Host symbol box not found" );
522
+
523
+ auto privatizerOp = firOpBuilder.create <mlir::omp::PrivateClauseOp>(
524
+ hsb.getAddr ().getLoc (), hsb.getAddr ().getType (),
525
+ sym->name ().ToString ());
526
+ firOpBuilder.setInsertionPointToEnd (&privatizerOp.getBody ().front ());
527
+
528
+ Fortran::semantics::Symbol cp = *sym;
529
+ Fortran::lower::SymMap privatizerSymbolMap;
530
+ privatizerSymbolMap.addSymbol (cp, privatizerOp.getArgument (0 ));
531
+ privatizerSymbolMap.pushScope ();
532
+
533
+ cloneSymbol (&cp, &privatizerSymbolMap);
534
+ copyFirstPrivateSymbol (&cp, &privatizerSymbolMap);
535
+
536
+ firOpBuilder.create <mlir::omp::YieldOp>(
537
+ hsb.getAddr ().getLoc (),
538
+ privatizerSymbolMap.shallowLookupSymbol (cp).getAddr ());
539
+
540
+ firOpBuilder.restoreInsertionPoint (ip);
541
+ }
542
+
543
+ // TODO: This will eventually be an else to the `if` above it. For now, I
544
+ // emit both the outlined privatizer AND directly emitted cloning and
545
+ // copying ops while I am testing.
499
546
cloneSymbol (sym);
500
547
copyFirstPrivateSymbol (sym);
501
548
}
@@ -2272,6 +2319,7 @@ static void createBodyOfOp(
2272
2319
llvm::SmallVector<mlir::Type> tiv (args.size (), loopVarType);
2273
2320
llvm::SmallVector<mlir::Location> locs (args.size (), loc);
2274
2321
firOpBuilder.createBlock (&op.getRegion (), {}, tiv, locs);
2322
+
2275
2323
// The argument is not currently in memory, so make a temporary for the
2276
2324
// argument, and store it there, then bind that location to the argument.
2277
2325
mlir::Operation *storeOp = nullptr ;
@@ -2291,10 +2339,11 @@ static void createBodyOfOp(
2291
2339
2292
2340
// If it is an unstructured region and is not the outer region of a combined
2293
2341
// construct, create empty blocks for all evaluations.
2294
- if (eval.lowerAsUnstructured () && !outerCombined)
2342
+ if (eval.lowerAsUnstructured () && !outerCombined) {
2295
2343
Fortran::lower::createEmptyRegionBlocks<mlir::omp::TerminatorOp,
2296
2344
mlir::omp::YieldOp>(
2297
2345
firOpBuilder, eval.getNestedEvaluations ());
2346
+ }
2298
2347
2299
2348
// Start with privatization, so that the lowering of the nested
2300
2349
// code will use the right symbols.
@@ -2307,12 +2356,14 @@ static void createBodyOfOp(
2307
2356
if (privatize) {
2308
2357
if (!dsp) {
2309
2358
tempDsp.emplace (converter, *clauses, eval);
2310
- tempDsp->processStep1 ();
2359
+ llvm::SetVector<mlir::omp::PrivateClauseOp> privateInitializers;
2360
+ tempDsp->processStep1 (&privateInitializers);
2311
2361
}
2312
2362
}
2313
2363
2314
2364
if constexpr (std::is_same_v<Op, mlir::omp::ParallelOp>) {
2315
2365
threadPrivatizeVars (converter, eval);
2366
+
2316
2367
if (clauses) {
2317
2368
firOpBuilder.setInsertionPoint (marker);
2318
2369
ClauseProcessor (converter, *clauses).processCopyin ();
@@ -2361,6 +2412,7 @@ static void createBodyOfOp(
2361
2412
if (exits.size () == 1 )
2362
2413
return exits[0 ];
2363
2414
mlir::Block *exit = firOpBuilder.createBlock (®ion);
2415
+
2364
2416
for (mlir::Block *b : exits) {
2365
2417
firOpBuilder.setInsertionPointToEnd (b);
2366
2418
firOpBuilder.create <mlir::cf::BranchOp>(loc, exit );
@@ -2382,8 +2434,9 @@ static void createBodyOfOp(
2382
2434
assert (tempDsp.has_value ());
2383
2435
tempDsp->processStep2 (op, isLoop);
2384
2436
} else {
2385
- if (isLoop && args.size () > 0 )
2437
+ if (isLoop && args.size () > 0 ) {
2386
2438
dsp->setLoopIV (converter.getSymbolAddress (*args[0 ]));
2439
+ }
2387
2440
dsp->processStep2 (op, isLoop);
2388
2441
}
2389
2442
}
0 commit comments