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