Skip to content

Commit dc820bb

Browse files
committed
Support pointers
The copy region codegen hasn't changed as a result of this patch series. However I think there is a bug in the copy region generated in equivalence.f90. This patch series is already too big so I won't change the copy region here.
1 parent 2eb72ce commit dc820bb

File tree

5 files changed

+52
-34
lines changed

5 files changed

+52
-34
lines changed

flang/lib/Lower/OpenMP/DataSharingProcessor.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -504,14 +504,16 @@ void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym,
504504
assert(hsb && "Host symbol box not found");
505505

506506
mlir::Value privVal = hsb.getAddr();
507-
mlir::Type allocType = fir::unwrapRefType(privVal.getType());
507+
mlir::Type allocType;
508+
if (mlir::isa<fir::PointerType>(privVal.getType()))
509+
allocType = privVal.getType();
510+
else
511+
allocType = fir::unwrapRefType(privVal.getType());
512+
508513
mlir::Location symLoc = hsb.getAddr().getLoc();
509514
std::string privatizerName = sym->name().ToString() + ".privatizer";
510515
bool isFirstPrivate = sym->test(semantics::Symbol::Flag::OmpFirstPrivate);
511516

512-
if (mlir::isa<fir::PointerType>(hsb.getAddr().getType()))
513-
TODO(symLoc, "Privatization of pointers");
514-
515517
if (auto poly = mlir::dyn_cast<fir::ClassType>(allocType)) {
516518
if (!mlir::isa<fir::PointerType>(poly.getEleTy()) && isFirstPrivate)
517519
TODO(symLoc, "create polymorphic host associated copy");
@@ -580,7 +582,7 @@ void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym,
580582
populateByRefInitAndCleanupRegions(
581583
firOpBuilder, symLoc, argType, /*scalarInitValue=*/nullptr, initBlock,
582584
result.getInitPrivateArg(), result.getInitMoldArg(),
583-
result.getDeallocRegion());
585+
result.getDeallocRegion(), /*isPrivate=*/true);
584586
}
585587

586588
// Populate the `copy` region if this is a `firstprivate`.

flang/lib/Lower/OpenMP/PrivateReductionUtils.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
119119
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type argType,
120120
mlir::Value scalarInitValue, mlir::Block *initBlock,
121121
mlir::Value allocatedPrivVarArg, mlir::Value moldArg,
122-
mlir::Region &cleanupRegion) {
122+
mlir::Region &cleanupRegion, bool isPrivate) {
123123
mlir::Type ty = fir::unwrapRefType(argType);
124124
builder.setInsertionPointToEnd(initBlock);
125125
auto yield = [&](mlir::Value ret) {
@@ -147,11 +147,10 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
147147
// fir.store %something to %box_alloca
148148
// }
149149
// omp.yield %box_alloca
150-
moldArg = builder.loadIfRef(loc, moldArg);
151150
mlir::SmallVector<mlir::Value> lenParams;
152-
hlfir::genLengthParameters(loc, builder, hlfir::Entity{moldArg}, lenParams);
153-
auto handleNullAllocatable = [&](mlir::Value boxAlloca) -> fir::IfOp {
154-
mlir::Value addr = builder.create<fir::BoxAddrOp>(loc, moldArg);
151+
auto handleNullAllocatable = [&](mlir::Value boxAlloca,
152+
mlir::Value loadedMold) -> fir::IfOp {
153+
mlir::Value addr = builder.create<fir::BoxAddrOp>(loc, loadedMold);
155154
mlir::Value isNotAllocated = builder.genIsNullAddr(loc, addr);
156155
fir::IfOp ifOp = builder.create<fir::IfOp>(loc, isNotAllocated,
157156
/*withElseRegion=*/true);
@@ -171,6 +170,21 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
171170

172171
builder.setInsertionPointToEnd(initBlock);
173172
mlir::Value boxAlloca = allocatedPrivVarArg;
173+
174+
// The initial state of a private pointer is undefined so we don't need to
175+
// match the mold argument (OpenMP 5.2 end of page 106).
176+
if (isPrivate && mlir::isa<fir::PointerType>(boxTy.getEleTy())) {
177+
// Just incase, do initialize the box with a null value
178+
mlir::Value null = builder.createNullConstant(loc, boxTy.getEleTy());
179+
mlir::Value nullBox = builder.create<fir::EmboxOp>(loc, boxTy, null);
180+
builder.create<fir::StoreOp>(loc, nullBox, boxAlloca);
181+
yield(boxAlloca);
182+
return;
183+
}
184+
185+
moldArg = builder.loadIfRef(loc, moldArg);
186+
hlfir::genLengthParameters(loc, builder, hlfir::Entity{moldArg}, lenParams);
187+
174188
mlir::Type innerTy = fir::unwrapRefType(boxTy.getEleTy());
175189
bool isChar = fir::isa_char(innerTy);
176190
if (fir::isa_trivial(innerTy) || isChar) {
@@ -179,7 +193,7 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
179193
TODO(loc,
180194
"Reduction/Privatization of non-allocatable trivial typed box");
181195

182-
fir::IfOp ifUnallocated = handleNullAllocatable(boxAlloca);
196+
fir::IfOp ifUnallocated = handleNullAllocatable(boxAlloca, moldArg);
183197

184198
builder.setInsertionPointToStart(&ifUnallocated.getElseRegion().front());
185199
mlir::Value valAlloc = builder.createHeapTemporary(
@@ -200,9 +214,12 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
200214
if (!innerTy || !mlir::isa<fir::SequenceType>(innerTy))
201215
TODO(loc, "Unsupported boxed type for reduction/privatization");
202216

217+
moldArg = builder.loadIfRef(loc, moldArg);
218+
hlfir::genLengthParameters(loc, builder, hlfir::Entity{moldArg}, lenParams);
219+
203220
fir::IfOp ifUnallocated{nullptr};
204221
if (isAllocatableOrPointer) {
205-
ifUnallocated = handleNullAllocatable(boxAlloca);
222+
ifUnallocated = handleNullAllocatable(boxAlloca, moldArg);
206223
builder.setInsertionPointToStart(&ifUnallocated.getElseRegion().front());
207224
}
208225

flang/lib/Lower/OpenMP/PrivateReductionUtils.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,13 @@ namespace omp {
3131

3232
/// Generate init and cleanup regions suitable for reduction or privatizer
3333
/// declarations. `scalarInitValue` may be nullptr if there is no default
34-
/// initialization (for privatization).
35-
void populateByRefInitAndCleanupRegions(fir::FirOpBuilder &builder,
36-
mlir::Location loc, mlir::Type argType,
37-
mlir::Value scalarInitValue,
38-
mlir::Block *initBlock,
39-
mlir::Value allocatedPrivVarArg,
40-
mlir::Value moldArg,
41-
mlir::Region &cleanupRegion);
34+
/// initialization (for privatization). If this is for a privatizer, set
35+
/// `isPrivate` to `true`.
36+
void populateByRefInitAndCleanupRegions(
37+
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type argType,
38+
mlir::Value scalarInitValue, mlir::Block *initBlock,
39+
mlir::Value allocatedPrivVarArg, mlir::Value moldArg,
40+
mlir::Region &cleanupRegion, bool isPrivate = false);
4241

4342
/// Generate a fir::ShapeShift op describing the provided boxed array.
4443
fir::ShapeShiftOp getShapeShift(fir::FirOpBuilder &builder, mlir::Location loc,

flang/test/Lower/OpenMP/DelayedPrivatization/equivalence.f90

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ subroutine private_common
1313
!$omp end parallel
1414
end subroutine
1515

16-
! CHECK: omp.private {type = firstprivate} @[[X_PRIVATIZER:.*]] : ![[X_TYPE:fir.ptr<f32>]] alloc {
17-
! CHECK: ^bb0(%{{.*}}: ![[X_TYPE]]):
18-
! CHECK: %[[PRIV_ALLOC:.*]] = fir.alloca f32 {bindc_name = "x", {{.*}}}
19-
! CHECK: %[[PRIV_DECL:.*]]:2 = hlfir.declare %[[PRIV_ALLOC]] {{{.*}}} : (![[PRIV_TYPE:fir.ref<f32>]]) -> ({{.*}})
20-
! CHECK: %[[PRIV_CONV:.*]] = fir.convert %[[PRIV_DECL]]#0 : (![[PRIV_TYPE]]) -> ![[X_TYPE]]
21-
! CHECK: omp.yield(%[[PRIV_CONV]] : ![[X_TYPE]])
22-
! CHECK: } copy {
16+
! TODO: the copy region for pointers is incorrect. OpenMP 5.2 says
17+
!
18+
! > If the original list item has the POINTER attribute, the new list items
19+
! > receive the same association status as the original list item
20+
!
21+
! Currently the original pointer is unconditionally loaded, which is undefined
22+
! behavior if that pointer is not associated.
23+
24+
! CHECK: omp.private {type = firstprivate} @[[X_PRIVATIZER:.*]] : ![[X_TYPE:fir.ptr<f32>]] copy {
2325
! CHECK: ^bb0(%[[ORIG_PTR:.*]]: ![[X_TYPE]], %[[PRIV_REF:.*]]: ![[X_TYPE]]):
2426
! CHECK: %[[ORIG_VAL:.*]] = fir.load %[[ORIG_PTR]] : !fir.ptr<f32>
2527
! CHECK: hlfir.assign %[[ORIG_VAL]] to %[[PRIV_REF]] : f32, ![[X_TYPE]]

flang/test/Lower/OpenMP/delayed-privatization-pointer.f90

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,18 @@ subroutine delayed_privatization_pointer
1515
end subroutine
1616

1717
! CHECK-LABEL: omp.private {type = firstprivate}
18-
! CHECK-SAME: @[[PRIVATIZER_SYM:.*]] : [[TYPE:!fir.ref<!fir.box<!fir.ptr<i32>>>]] alloc {
18+
! CHECK-SAME: @[[PRIVATIZER_SYM:.*]] : [[TYPE:!fir.box<!fir.ptr<i32>>]] init {
1919

20-
! CHECK-NEXT: ^bb0(%[[PRIV_ARG:.*]]: [[TYPE]]):
20+
! CHECK-NEXT: ^bb0(%[[PRIV_ARG:.*]]: !fir.ref<[[TYPE]]>, %[[PRIV_ALLOC:.*]]: !fir.ref<[[TYPE]]>):
2121

22-
! CHECK-NEXT: %[[PRIV_ALLOC:.*]] = fir.alloca !fir.box<!fir.ptr<i32>> {bindc_name = "var1", pinned, uniq_name = "_QFdelayed_privatization_pointerEvar1"}
2322
! CHECK-NEXT: %[[NULL:.*]] = fir.zero_bits !fir.ptr<i32>
2423
! CHECK-NEXT: %[[INIT:.*]] = fir.embox %[[NULL]] : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>>
2524
! CHECK-NEXT: fir.store %[[INIT]] to %[[PRIV_ALLOC]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
26-
! CHECK-NEXT: %[[PRIV_DECL:.*]]:2 = hlfir.declare %[[PRIV_ALLOC]]
27-
! CHECK-NEXT: omp.yield(%[[PRIV_DECL]]#0 : [[TYPE]])
25+
! CHECK-NEXT: omp.yield(%[[PRIV_ALLOC]] : !fir.ref<[[TYPE]]>)
2826

2927
! CHECK-NEXT: } copy {
30-
! CHECK: ^bb0(%[[PRIV_ORIG_ARG:.*]]: [[TYPE]], %[[PRIV_PRIV_ARG:.*]]: [[TYPE]]):
28+
! CHECK: ^bb0(%[[PRIV_ORIG_ARG:.*]]: !fir.ref<[[TYPE]]>, %[[PRIV_PRIV_ARG:.*]]: !fir.ref<[[TYPE]]>):
3129
! CHECK-NEXT: %[[ORIG_BASE_VAL:.*]] = fir.load %[[PRIV_ORIG_ARG]]
3230
! CHECK-NEXT: fir.store %[[ORIG_BASE_VAL]] to %[[PRIV_PRIV_ARG]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
33-
! CHECK-NEXT: omp.yield(%[[PRIV_PRIV_ARG]] : [[TYPE]])
31+
! CHECK-NEXT: omp.yield(%[[PRIV_PRIV_ARG]] : !fir.ref<[[TYPE]]>)
3432
! CHECK-NEXT: }

0 commit comments

Comments
 (0)