@@ -277,7 +277,8 @@ class PopulateInitAndCleanupRegionsHelper {
277
277
// / allocatedPrivVarArg: The allocation for the private
278
278
// / variable.
279
279
// / moldArg: The original variable.
280
- // / loadedMoldArg: The original variable, loaded.
280
+ // / loadedMoldArg: The original variable, loaded. Access via
281
+ // / getLoadedMoldArg().
281
282
mlir::Value scalarInitValue, allocatedPrivVarArg, moldArg, loadedMoldArg;
282
283
283
284
// / The first block in the init region.
@@ -321,6 +322,14 @@ class PopulateInitAndCleanupRegionsHelper {
321
322
void initAndCleanupUnboxedDerivedType (bool needsInitialization);
322
323
323
324
fir::IfOp handleNullAllocatable ();
325
+
326
+ // Do this lazily so that we don't load it when it is not used.
327
+ inline mlir::Value getLoadedMoldArg () {
328
+ if (loadedMoldArg)
329
+ return loadedMoldArg;
330
+ loadedMoldArg = builder.loadIfRef (loc, moldArg);
331
+ return loadedMoldArg;
332
+ }
324
333
};
325
334
326
335
} // namespace
@@ -333,7 +342,7 @@ void PopulateInitAndCleanupRegionsHelper::initBoxedPrivatePointer(
333
342
// we need a shape with the right rank so that the embox op is lowered
334
343
// to an llvm struct of the right type. This returns nullptr if the types
335
344
// aren't right.
336
- mlir::Value shape = generateZeroShapeForRank (builder, loc, loadedMoldArg );
345
+ mlir::Value shape = generateZeroShapeForRank (builder, loc, moldArg );
337
346
// Just incase, do initialize the box with a null value
338
347
mlir::Value null = builder.createNullConstant (loc, boxTy.getEleTy ());
339
348
mlir::Value nullBox;
@@ -355,7 +364,7 @@ void PopulateInitAndCleanupRegionsHelper::initBoxedPrivatePointer(
355
364
// / }
356
365
// / omp.yield %box_alloca
357
366
fir::IfOp PopulateInitAndCleanupRegionsHelper::handleNullAllocatable () {
358
- mlir::Value addr = builder.create <fir::BoxAddrOp>(loc, loadedMoldArg );
367
+ mlir::Value addr = builder.create <fir::BoxAddrOp>(loc, getLoadedMoldArg () );
359
368
mlir::Value isNotAllocated = builder.genIsNullAddr (loc, addr);
360
369
fir::IfOp ifOp = builder.create <fir::IfOp>(loc, isNotAllocated,
361
370
/* withElseRegion=*/ true );
@@ -391,7 +400,7 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedScalar(
391
400
loc, valType, valAlloc, /* shape=*/ mlir::Value{},
392
401
/* slice=*/ mlir::Value{}, lenParams);
393
402
initializeIfDerivedTypeBox (
394
- builder, loc, box, loadedMoldArg , needsInitialization,
403
+ builder, loc, box, getLoadedMoldArg () , needsInitialization,
395
404
/* isFirstPrivate=*/ kind == DeclOperationKind::FirstPrivate);
396
405
fir::StoreOp lastOp =
397
406
builder.create <fir::StoreOp>(loc, box, allocatedPrivVarArg);
@@ -410,7 +419,7 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedArray(
410
419
fir::BaseBoxType boxTy, bool needsInitialization) {
411
420
bool isAllocatableOrPointer =
412
421
mlir::isa<fir::HeapType, fir::PointerType>(boxTy.getEleTy ());
413
- getLengthParameters (builder, loc, loadedMoldArg , lenParams);
422
+ getLengthParameters (builder, loc, getLoadedMoldArg () , lenParams);
414
423
415
424
fir::IfOp ifUnallocated{nullptr };
416
425
if (isAllocatableOrPointer) {
@@ -419,7 +428,7 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedArray(
419
428
}
420
429
421
430
// Create the private copy from the initial fir.box:
422
- hlfir::Entity source = hlfir::Entity{loadedMoldArg };
431
+ hlfir::Entity source = hlfir::Entity{getLoadedMoldArg () };
423
432
424
433
// Special case for (possibly allocatable) arrays of polymorphic types
425
434
// e.g. !fir.class<!fir.heap<!fir.array<?x!fir.type<>>>>
@@ -463,8 +472,9 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedArray(
463
472
// Put the temporary inside of a box:
464
473
// hlfir::genVariableBox doesn't handle non-default lower bounds
465
474
mlir::Value box;
466
- fir::ShapeShiftOp shapeShift = getShapeShift (builder, loc, loadedMoldArg);
467
- mlir::Type boxType = loadedMoldArg.getType ();
475
+ fir::ShapeShiftOp shapeShift =
476
+ getShapeShift (builder, loc, getLoadedMoldArg ());
477
+ mlir::Type boxType = getLoadedMoldArg ().getType ();
468
478
if (mlir::isa<fir::BaseBoxType>(temp.getType ()))
469
479
// the box created by the declare form createTempFromMold is missing
470
480
// lower bounds info
@@ -480,7 +490,7 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedArray(
480
490
builder.create <hlfir::AssignOp>(loc, scalarInitValue, box);
481
491
482
492
initializeIfDerivedTypeBox (
483
- builder, loc, box, loadedMoldArg , needsInitialization,
493
+ builder, loc, box, getLoadedMoldArg () , needsInitialization,
484
494
/* isFirstPrivate=*/ kind == DeclOperationKind::FirstPrivate);
485
495
486
496
builder.create <fir::StoreOp>(loc, box, allocatedPrivVarArg);
@@ -553,8 +563,7 @@ void PopulateInitAndCleanupRegionsHelper::populateByRefInitAndCleanupRegions() {
553
563
builder.setInsertionPointToEnd (initBlock);
554
564
555
565
// TODO: don't do this unless it is needed
556
- loadedMoldArg = builder.loadIfRef (loc, moldArg);
557
- getLengthParameters (builder, loc, loadedMoldArg, lenParams);
566
+ getLengthParameters (builder, loc, getLoadedMoldArg (), lenParams);
558
567
559
568
if (isPrivatization (kind) &&
560
569
mlir::isa<fir::PointerType>(boxTy.getEleTy ())) {
@@ -604,4 +613,16 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
604
613
converter, loc, argType, scalarInitValue, allocatedPrivVarArg, moldArg,
605
614
initBlock, cleanupRegion, kind, sym);
606
615
helper.populateByRefInitAndCleanupRegions ();
616
+
617
+ // Often we load moldArg to check something (e.g. length parameters, shape)
618
+ // but then those answers can be gotten statically without accessing the
619
+ // runtime value and so the only remaining use is a dead load. These loads can
620
+ // force us to insert additional barriers and so should be avoided where
621
+ // possible.
622
+ if (moldArg.hasOneUse ()) {
623
+ mlir::Operation *user = *moldArg.getUsers ().begin ();
624
+ if (auto load = mlir::dyn_cast<fir::LoadOp>(user))
625
+ if (load.use_empty ())
626
+ load.erase ();
627
+ }
607
628
}
0 commit comments