28
28
#include " flang/Semantics/tools.h"
29
29
#include " mlir/Dialect/OpenMP/OpenMPDialect.h"
30
30
#include " mlir/Dialect/SCF/IR/SCF.h"
31
+ #include " mlir/Transforms/RegionUtils.h"
31
32
#include " llvm/Frontend/OpenMP/OMPConstants.h"
32
33
#include " llvm/Support/CommandLine.h"
33
34
@@ -1709,26 +1710,22 @@ static mlir::omp::MapInfoOp
1709
1710
createMapInfoOp (fir::FirOpBuilder &builder, mlir::Location loc,
1710
1711
mlir::Value baseAddr, std::stringstream &name,
1711
1712
mlir::SmallVector<mlir::Value> bounds, uint64_t mapType,
1712
- mlir::omp::VariableCaptureKind mapCaptureType, mlir::Type retTy,
1713
- bool isVal = false ) {
1714
- mlir::Value val, varPtr, varPtrPtr;
1713
+ mlir::omp::VariableCaptureKind mapCaptureType,
1714
+ mlir::Type retTy ) {
1715
+ mlir::Value varPtr, varPtrPtr;
1715
1716
mlir::TypeAttr varType;
1716
1717
1717
1718
if (auto boxTy = baseAddr.getType ().dyn_cast <fir::BaseBoxType>()) {
1718
1719
baseAddr = builder.create <fir::BoxAddrOp>(loc, baseAddr);
1719
1720
retTy = baseAddr.getType ();
1720
1721
}
1721
1722
1722
- if (isVal)
1723
- val = baseAddr;
1724
- else
1725
- varPtr = baseAddr;
1726
-
1727
- if (auto ptrType = llvm::dyn_cast<mlir::omp::PointerLikeType>(retTy))
1728
- varType = mlir::TypeAttr::get (ptrType.getElementType ());
1723
+ varPtr = baseAddr;
1724
+ varType = mlir::TypeAttr::get (
1725
+ llvm::cast<mlir::omp::PointerLikeType>(retTy).getElementType ());
1729
1726
1730
1727
mlir::omp::MapInfoOp op = builder.create <mlir::omp::MapInfoOp>(
1731
- loc, retTy, val, varPtr, varType, varPtrPtr, bounds,
1728
+ loc, retTy, varPtr, varType, varPtrPtr, bounds,
1732
1729
builder.getIntegerAttr (builder.getIntegerType (64 , false ), mapType),
1733
1730
builder.getAttr <mlir::omp::VariableCaptureKindAttr>(mapCaptureType),
1734
1731
builder.getStringAttr (name.str ()));
@@ -2489,21 +2486,27 @@ static void genBodyOfTargetOp(
2489
2486
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
2490
2487
mlir::Region ®ion = targetOp.getRegion ();
2491
2488
2492
- firOpBuilder.createBlock (®ion, {}, mapSymTypes, mapSymLocs);
2489
+ auto *regionBlock =
2490
+ firOpBuilder.createBlock (®ion, {}, mapSymTypes, mapSymLocs);
2493
2491
2494
2492
unsigned argIndex = 0 ;
2495
- unsigned blockArgsIndex = mapSymbols.size ();
2496
-
2497
- // The block arguments contain the map_operands followed by the bounds in
2498
- // order. This returns a vector containing the next 'n' block arguments for
2499
- // the bounds.
2500
- auto extractBoundArgs = [&](auto n) {
2501
- llvm::SmallVector<mlir::Value> argExtents;
2502
- while (n--) {
2503
- argExtents.push_back (fir::getBase (region.getArgument (blockArgsIndex)));
2504
- blockArgsIndex++;
2493
+
2494
+ // Clones the `bounds` placing them inside the target region and returns them.
2495
+ auto cloneBound = [&](mlir::Value bound) {
2496
+ if (mlir::isMemoryEffectFree (bound.getDefiningOp ())) {
2497
+ mlir::Operation *clonedOp = bound.getDefiningOp ()->clone ();
2498
+ regionBlock->push_back (clonedOp);
2499
+ return clonedOp->getResult (0 );
2505
2500
}
2506
- return argExtents;
2501
+ TODO (converter.getCurrentLocation (),
2502
+ " target map clause operand unsupported bound type" );
2503
+ };
2504
+
2505
+ auto cloneBounds = [cloneBound](llvm::ArrayRef<mlir::Value> bounds) {
2506
+ llvm::SmallVector<mlir::Value> clonedBounds;
2507
+ for (mlir::Value bound : bounds)
2508
+ clonedBounds.emplace_back (cloneBound (bound));
2509
+ return clonedBounds;
2507
2510
};
2508
2511
2509
2512
// Bind the symbols to their corresponding block arguments.
@@ -2512,34 +2515,31 @@ static void genBodyOfTargetOp(
2512
2515
fir::ExtendedValue extVal = converter.getSymbolExtendedValue (*sym);
2513
2516
extVal.match (
2514
2517
[&](const fir::BoxValue &v) {
2515
- converter.bindSymbol (
2516
- *sym ,
2517
- fir::BoxValue (arg, extractBoundArgs (v. getLBounds (). size () ),
2518
- v. getExplicitParameters (), v.getExplicitExtents ()));
2518
+ converter.bindSymbol (*sym,
2519
+ fir::BoxValue (arg, cloneBounds (v. getLBounds ()) ,
2520
+ v. getExplicitParameters ( ),
2521
+ v.getExplicitExtents ()));
2519
2522
},
2520
2523
[&](const fir::MutableBoxValue &v) {
2521
2524
converter.bindSymbol (
2522
- *sym,
2523
- fir::MutableBoxValue (arg, extractBoundArgs (v.getLBounds ().size ()),
2524
- v.getMutableProperties ()));
2525
+ *sym, fir::MutableBoxValue (arg, cloneBounds (v.getLBounds ()),
2526
+ v.getMutableProperties ()));
2525
2527
},
2526
2528
[&](const fir::ArrayBoxValue &v) {
2527
2529
converter.bindSymbol (
2528
- *sym,
2529
- fir::ArrayBoxValue (arg, extractBoundArgs (v.getExtents ().size ()),
2530
- extractBoundArgs (v.getLBounds ().size ()),
2531
- v.getSourceBox ()));
2530
+ *sym, fir::ArrayBoxValue (arg, cloneBounds (v.getExtents ()),
2531
+ cloneBounds (v.getLBounds ()),
2532
+ v.getSourceBox ()));
2532
2533
},
2533
2534
[&](const fir::CharArrayBoxValue &v) {
2534
2535
converter.bindSymbol (
2535
- *sym,
2536
- fir::CharArrayBoxValue (arg, extractBoundArgs (1 ).front (),
2537
- extractBoundArgs (v.getExtents ().size ()),
2538
- extractBoundArgs (v.getLBounds ().size ())));
2536
+ *sym, fir::CharArrayBoxValue (arg, cloneBound (v.getLen ()),
2537
+ cloneBounds (v.getExtents ()),
2538
+ cloneBounds (v.getLBounds ())));
2539
2539
},
2540
2540
[&](const fir::CharBoxValue &v) {
2541
- converter.bindSymbol (
2542
- *sym, fir::CharBoxValue (arg, extractBoundArgs ( 1 ). front ( )));
2541
+ converter.bindSymbol (*sym,
2542
+ fir::CharBoxValue (arg, cloneBound (v. getLen () )));
2543
2543
},
2544
2544
[&](const fir::UnboxedValue &v) { converter.bindSymbol (*sym, arg); },
2545
2545
[&](const auto &) {
@@ -2549,6 +2549,55 @@ static void genBodyOfTargetOp(
2549
2549
argIndex++;
2550
2550
}
2551
2551
2552
+ // Check if cloning the bounds introduced any dependency on the outer region.
2553
+ // If so, then either clone them as well if they are MemoryEffectFree, or else
2554
+ // copy them to a new temporary and add them to the map and block_argument
2555
+ // lists and replace their uses with the new temporary.
2556
+ llvm::SetVector<mlir::Value> valuesDefinedAbove;
2557
+ mlir::getUsedValuesDefinedAbove (region, valuesDefinedAbove);
2558
+ while (!valuesDefinedAbove.empty ()) {
2559
+ for (mlir::Value val : valuesDefinedAbove) {
2560
+ mlir::Operation *valOp = val.getDefiningOp ();
2561
+ if (mlir::isMemoryEffectFree (valOp)) {
2562
+ mlir::Operation *clonedOp = valOp->clone ();
2563
+ regionBlock->push_front (clonedOp);
2564
+ val.replaceUsesWithIf (
2565
+ clonedOp->getResult (0 ), [regionBlock](mlir::OpOperand &use) {
2566
+ return use.getOwner ()->getBlock () == regionBlock;
2567
+ });
2568
+ } else {
2569
+ auto savedIP = firOpBuilder.getInsertionPoint ();
2570
+ firOpBuilder.setInsertionPointAfter (valOp);
2571
+ auto copyVal =
2572
+ firOpBuilder.createTemporary (val.getLoc (), val.getType ());
2573
+ firOpBuilder.createStoreWithConvert (copyVal.getLoc (), val, copyVal);
2574
+
2575
+ llvm::SmallVector<mlir::Value> bounds;
2576
+ std::stringstream name;
2577
+ firOpBuilder.setInsertionPoint (targetOp);
2578
+ mlir::Value mapOp = createMapInfoOp (
2579
+ firOpBuilder, copyVal.getLoc (), copyVal, name, bounds,
2580
+ static_cast <
2581
+ std::underlying_type_t <llvm::omp::OpenMPOffloadMappingFlags>>(
2582
+ llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT),
2583
+ mlir::omp::VariableCaptureKind::ByCopy, copyVal.getType ());
2584
+ targetOp.getMapOperandsMutable ().append (mapOp);
2585
+ mlir::Value clonedValArg =
2586
+ region.addArgument (copyVal.getType (), copyVal.getLoc ());
2587
+ firOpBuilder.setInsertionPointToStart (regionBlock);
2588
+ auto loadOp = firOpBuilder.create <fir::LoadOp>(clonedValArg.getLoc (),
2589
+ clonedValArg);
2590
+ val.replaceUsesWithIf (
2591
+ loadOp->getResult (0 ), [regionBlock](mlir::OpOperand &use) {
2592
+ return use.getOwner ()->getBlock () == regionBlock;
2593
+ });
2594
+ firOpBuilder.setInsertionPoint (regionBlock, savedIP);
2595
+ }
2596
+ }
2597
+ valuesDefinedAbove.clear ();
2598
+ mlir::getUsedValuesDefinedAbove (region, valuesDefinedAbove);
2599
+ }
2600
+
2552
2601
// Insert dummy instruction to remember the insertion position. The
2553
2602
// marker will be deleted since there are not uses.
2554
2603
// In the HLFIR flow there are hlfir.declares inserted above while
@@ -2671,53 +2720,6 @@ genTargetOp(Fortran::lower::AbstractConverter &converter,
2671
2720
};
2672
2721
Fortran::lower::pft::visitAllSymbols (eval, captureImplicitMap);
2673
2722
2674
- // Add the bounds and extents for box values to mapOperands
2675
- auto addMapInfoForBounds = [&](const auto &bounds) {
2676
- for (auto &val : bounds) {
2677
- mapSymLocs.push_back (val.getLoc ());
2678
- mapSymTypes.push_back (val.getType ());
2679
-
2680
- llvm::SmallVector<mlir::Value> bounds;
2681
- std::stringstream name;
2682
-
2683
- mlir::Value mapOp = createMapInfoOp (
2684
- converter.getFirOpBuilder (), val.getLoc (), val, name, bounds,
2685
- static_cast <
2686
- std::underlying_type_t <llvm::omp::OpenMPOffloadMappingFlags>>(
2687
- llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT),
2688
- mlir::omp::VariableCaptureKind::ByCopy, val.getType (), true );
2689
- mapOperands.push_back (mapOp);
2690
- }
2691
- };
2692
-
2693
- for (const Fortran::semantics::Symbol *sym : mapSymbols) {
2694
- fir::ExtendedValue extVal = converter.getSymbolExtendedValue (*sym);
2695
- extVal.match (
2696
- [&](const fir::BoxValue &v) { addMapInfoForBounds (v.getLBounds ()); },
2697
- [&](const fir::MutableBoxValue &v) {
2698
- addMapInfoForBounds (v.getLBounds ());
2699
- },
2700
- [&](const fir::ArrayBoxValue &v) {
2701
- addMapInfoForBounds (v.getExtents ());
2702
- addMapInfoForBounds (v.getLBounds ());
2703
- },
2704
- [&](const fir::CharArrayBoxValue &v) {
2705
- llvm::SmallVector<mlir::Value> len;
2706
- len.push_back (v.getLen ());
2707
- addMapInfoForBounds (len);
2708
- addMapInfoForBounds (v.getExtents ());
2709
- addMapInfoForBounds (v.getLBounds ());
2710
- },
2711
- [&](const fir::CharBoxValue &v) {
2712
- llvm::SmallVector<mlir::Value> len;
2713
- len.push_back (v.getLen ());
2714
- addMapInfoForBounds (len);
2715
- },
2716
- [&](const auto &) {
2717
- // Nothing to do for non-box values.
2718
- });
2719
- }
2720
-
2721
2723
auto targetOp = converter.getFirOpBuilder ().create <mlir::omp::TargetOp>(
2722
2724
currentLocation, ifClauseOperand, deviceOperand, threadLimitOperand,
2723
2725
nowaitAttr, mapOperands);
0 commit comments