Skip to content

Commit 3424d57

Browse files
ergawyronlieb
authored andcommitted
[flang][do concurent] Correctly generate omp.map.bounds ops for allocatables
1 parent 556d3f7 commit 3424d57

File tree

2 files changed

+89
-70
lines changed

2 files changed

+89
-70
lines changed

flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp

Lines changed: 60 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -584,12 +584,16 @@ class DoConcurrentConversion : public mlir::OpConversionPattern<fir::DoLoopOp> {
584584
isTargetDevice ? nullptr : &targetClauseOps);
585585

586586
LiveInShapeInfoMap liveInShapeInfoMap;
587-
// The outermost loop will contain all the live-in values in all nested
588-
// loops since live-in values are collected recursively for all nested
589-
// ops.
590-
for (mlir::Value liveIn : loopNestLiveIns)
591-
targetClauseOps.mapVars.push_back(genMapInfoOpForLiveIn(
592-
rewriter, liveIn, liveInShapeInfoMap[liveIn]));
587+
fir::FirOpBuilder builder(
588+
rewriter,
589+
fir::getKindMapping(doLoop->getParentOfType<mlir::ModuleOp>()));
590+
591+
for (mlir::Value liveIn : loopNestLiveIns) {
592+
targetClauseOps.mapVars.push_back(
593+
genMapInfoOpForLiveIn(builder, liveIn));
594+
liveInShapeInfoMap.insert(
595+
{liveIn, TargetDeclareShapeCreationInfo(liveIn)});
596+
}
593597

594598
targetOp =
595599
genTargetOp(doLoop.getLoc(), rewriter, mapper, loopNestLiveIns,
@@ -639,6 +643,37 @@ class DoConcurrentConversion : public mlir::OpConversionPattern<fir::DoLoopOp> {
639643
std::vector<mlir::Value> startIndices{};
640644
std::vector<mlir::Value> extents{};
641645

646+
TargetDeclareShapeCreationInfo(mlir::Value liveIn) {
647+
mlir::Value shape = nullptr;
648+
mlir::Operation *liveInDefiningOp = liveIn.getDefiningOp();
649+
auto declareOp =
650+
mlir::dyn_cast_if_present<hlfir::DeclareOp>(liveInDefiningOp);
651+
652+
if (declareOp != nullptr)
653+
shape = declareOp.getShape();
654+
655+
if (shape == nullptr)
656+
return;
657+
658+
auto shapeOp =
659+
mlir::dyn_cast_if_present<fir::ShapeOp>(shape.getDefiningOp());
660+
auto shapeShiftOp =
661+
mlir::dyn_cast_if_present<fir::ShapeShiftOp>(shape.getDefiningOp());
662+
663+
if (shapeOp == nullptr && shapeShiftOp == nullptr)
664+
TODO(liveIn.getLoc(),
665+
"Shapes not defined by `fir.shape` or `fir.shape_shift` op's are "
666+
"not supported yet.");
667+
668+
if (shapeShiftOp != nullptr)
669+
startIndices = shapeShiftOp.getOrigins();
670+
671+
extents = shapeOp != nullptr
672+
? std::vector<mlir::Value>(shapeOp.getExtents().begin(),
673+
shapeOp.getExtents().end())
674+
: shapeShiftOp.getExtents();
675+
}
676+
642677
bool isShapedValue() const { return !extents.empty(); }
643678
bool isShapeShiftedValue() const { return !startIndices.empty(); }
644679
};
@@ -744,66 +779,26 @@ class DoConcurrentConversion : public mlir::OpConversionPattern<fir::DoLoopOp> {
744779
return loopNestOp;
745780
}
746781

747-
void
748-
genBoundsOps(mlir::ConversionPatternRewriter &rewriter, mlir::Location loc,
749-
mlir::Value shape, llvm::SmallVectorImpl<mlir::Value> &boundsOps,
750-
TargetDeclareShapeCreationInfo &targetShapeCreationInfo) const {
751-
if (shape == nullptr) {
752-
return;
753-
}
754-
755-
auto shapeOp =
756-
mlir::dyn_cast_if_present<fir::ShapeOp>(shape.getDefiningOp());
757-
auto shapeShiftOp =
758-
mlir::dyn_cast_if_present<fir::ShapeShiftOp>(shape.getDefiningOp());
759-
760-
if (shapeOp == nullptr && shapeShiftOp == nullptr)
761-
TODO(loc,
762-
"Shapes not defined by `fir.shape` or `fir.shape_shift` op's are "
763-
"not supported yet.");
764-
765-
auto extents = shapeOp != nullptr
766-
? std::vector<mlir::Value>(shapeOp.getExtents().begin(),
767-
shapeOp.getExtents().end())
768-
: shapeShiftOp.getExtents();
769-
770-
mlir::Type idxType = extents.front().getType();
771-
772-
auto one = rewriter.create<mlir::arith::ConstantOp>(
773-
loc, idxType, rewriter.getIntegerAttr(idxType, 1));
774-
// For non-shifted values, that starting index is the default Fortran
775-
// value: 1.
776-
std::vector<mlir::Value> startIndices =
777-
shapeOp != nullptr ? std::vector<mlir::Value>(extents.size(), one)
778-
: shapeShiftOp.getOrigins();
779-
780-
auto genBoundsOp = [&](mlir::Value startIndex, mlir::Value extent) {
781-
// We map the entire range of data by default, therefore, we always map
782-
// from the start.
783-
auto normalizedLB = rewriter.create<mlir::arith::ConstantOp>(
784-
loc, idxType, rewriter.getIntegerAttr(idxType, 0));
785-
786-
mlir::Value ub = rewriter.create<mlir::arith::SubIOp>(loc, extent, one);
787-
788-
return rewriter.create<mlir::omp::MapBoundsOp>(
789-
loc, rewriter.getType<mlir::omp::MapBoundsType>(), normalizedLB, ub,
790-
extent,
791-
/*stride=*/mlir::Value{}, /*stride_in_bytes=*/false, startIndex);
792-
};
793-
794-
for (auto [startIndex, extent] : llvm::zip_equal(startIndices, extents))
795-
boundsOps.push_back(genBoundsOp(startIndex, extent));
796-
797-
if (shapeShiftOp != nullptr)
798-
targetShapeCreationInfo.startIndices = std::move(startIndices);
799-
targetShapeCreationInfo.extents = std::move(extents);
782+
void genBoundsOps(fir::FirOpBuilder &builder, mlir::Value liveIn,
783+
mlir::Value rawAddr,
784+
llvm::SmallVectorImpl<mlir::Value> &boundsOps) const {
785+
fir::ExtendedValue extVal =
786+
hlfir::translateToExtendedValue(rawAddr.getLoc(), builder,
787+
hlfir::Entity{liveIn},
788+
/*contiguousHint=*/
789+
true)
790+
.first;
791+
fir::factory::AddrAndBoundsInfo info = fir::factory::getDataOperandBaseAddr(
792+
builder, rawAddr, /*isOptional=*/false, rawAddr.getLoc());
793+
boundsOps = fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
794+
mlir::omp::MapBoundsType>(
795+
builder, info, extVal,
796+
/*dataExvIsAssumedSize=*/false, rawAddr.getLoc());
800797
}
801798

802-
mlir::omp::MapInfoOp genMapInfoOpForLiveIn(
803-
mlir::ConversionPatternRewriter &rewriter, mlir::Value liveIn,
804-
TargetDeclareShapeCreationInfo &targetShapeCreationInfo) const {
799+
mlir::omp::MapInfoOp genMapInfoOpForLiveIn(fir::FirOpBuilder &builder,
800+
mlir::Value liveIn) const {
805801
mlir::Value rawAddr = liveIn;
806-
mlir::Value shape = nullptr;
807802
llvm::StringRef name;
808803

809804
mlir::Operation *liveInDefiningOp = liveIn.getDefiningOp();
@@ -815,14 +810,10 @@ class DoConcurrentConversion : public mlir::OpConversionPattern<fir::DoLoopOp> {
815810
// possible. Put differently, if we have access to the direct value memory
816811
// reference/address, we use it.
817812
rawAddr = declareOp.getOriginalBase();
818-
shape = declareOp.getShape();
819813
name = declareOp.getUniqName();
820814
}
821815

822816
if (!llvm::isa<mlir::omp::PointerLikeType>(rawAddr.getType())) {
823-
fir::FirOpBuilder builder(
824-
rewriter, fir::getKindMapping(
825-
liveInDefiningOp->getParentOfType<mlir::ModuleOp>()));
826817
builder.setInsertionPointAfter(liveInDefiningOp);
827818
auto copyVal = builder.createTemporary(liveIn.getLoc(), liveIn.getType());
828819
builder.createStoreWithConvert(copyVal.getLoc(), liveIn, copyVal);
@@ -847,11 +838,10 @@ class DoConcurrentConversion : public mlir::OpConversionPattern<fir::DoLoopOp> {
847838
}
848839

849840
llvm::SmallVector<mlir::Value> boundsOps;
850-
genBoundsOps(rewriter, liveIn.getLoc(), shape, boundsOps,
851-
targetShapeCreationInfo);
841+
genBoundsOps(builder, liveIn, rawAddr, boundsOps);
852842

853843
return Fortran::lower::omp::internal::createMapInfoOp(
854-
rewriter, liveIn.getLoc(), rawAddr,
844+
builder, liveIn.getLoc(), rawAddr,
855845
/*varPtrPtr=*/{}, name.str(), boundsOps,
856846
/*members=*/{},
857847
/*membersIndex=*/mlir::ArrayAttr{},
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
! Verifies that proper `omp.map.bounds` ops are emitted when an allocatable is
2+
! implicitly mapped by a `do concurrent` loop.
3+
4+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fdo-concurrent-to-openmp=device %s -o - \
5+
! RUN: | FileCheck %s
6+
program main
7+
implicit none
8+
9+
integer,parameter :: n = 1000000
10+
real, allocatable, dimension(:) :: y
11+
integer :: i
12+
13+
allocate(y(1:n))
14+
15+
do concurrent(i=1:n)
16+
y(i) = 42
17+
end do
18+
19+
deallocate(y)
20+
end program main
21+
22+
! CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEy"}
23+
! CHECK: %[[Y_VAL:.*]] = fir.load %[[Y_DECL]]#0
24+
! CHECK: %[[Y_DIM0:.*]]:3 = fir.box_dims %[[Y_VAL]], %{{c0_.*}}
25+
! CHECK: %[[Y_LB:.*]] = arith.constant 0 : index
26+
! CHECK: %[[Y_UB:.*]] = arith.subi %[[Y_DIM0]]#1, %{{c1_.*}} : index
27+
! CHECK: %[[Y_BOUNDS:.*]] = omp.map.bounds lower_bound(%[[Y_LB]] : index) upper_bound(%[[Y_UB]] : index) extent(%[[Y_DIM0]]#1 : index)
28+
! CHECK: %[[MEM_MAP:.*]] = omp.map.info {{.*}} bounds(%[[Y_BOUNDS]])
29+
! CHECK: omp.map.info var_ptr(%[[Y_DECL]]#1 : {{.*}}) {{.*}} members(%[[MEM_MAP]] : {{.*}})

0 commit comments

Comments
 (0)