Skip to content

Commit 24f5fc7

Browse files
authored
[flang][MLIR][OpenMP] Extend delayed privatization for arrays and characters (#85023)
1 parent c7910ee commit 24f5fc7

File tree

8 files changed

+336
-17
lines changed

8 files changed

+336
-17
lines changed

flang/include/flang/Optimizer/Builder/HLFIRTools.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ class EntityWithAttributes : public Entity {
223223
using CleanupFunction = std::function<void()>;
224224
std::pair<fir::ExtendedValue, std::optional<CleanupFunction>>
225225
translateToExtendedValue(mlir::Location loc, fir::FirOpBuilder &builder,
226-
Entity entity);
226+
Entity entity, bool contiguousHint = false);
227227

228228
/// Function to translate FortranVariableOpInterface to fir::ExtendedValue.
229229
/// It may generates IR to unbox fir.boxchar, but has otherwise no side effects

flang/lib/Lower/OpenMP/DataSharingProcessor.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "Utils.h"
1616
#include "flang/Lower/PFTBuilder.h"
1717
#include "flang/Lower/SymbolMap.h"
18+
#include "flang/Optimizer/Builder/HLFIRTools.h"
1819
#include "flang/Optimizer/Builder/Todo.h"
1920
#include "flang/Semantics/tools.h"
2021

@@ -438,8 +439,16 @@ void DataSharingProcessor::doPrivatize(
438439
&allocRegion, /*insertPt=*/{}, symType, symLoc);
439440

440441
firOpBuilder.setInsertionPointToEnd(allocEntryBlock);
441-
symTable->addSymbol(*sym,
442-
fir::substBase(symExV, allocRegion.getArgument(0)));
442+
443+
fir::ExtendedValue localExV =
444+
hlfir::translateToExtendedValue(
445+
symLoc, firOpBuilder, hlfir::Entity{allocRegion.getArgument(0)},
446+
/*contiguousHint=*/
447+
Fortran::evaluate::IsSimplyContiguous(
448+
*sym, converter.getFoldingContext()))
449+
.first;
450+
451+
symTable->addSymbol(*sym, localExV);
443452
symTable->pushScope();
444453
cloneSymbol(sym);
445454
firOpBuilder.create<mlir::omp::YieldOp>(
@@ -456,12 +465,23 @@ void DataSharingProcessor::doPrivatize(
456465
mlir::Block *copyEntryBlock = firOpBuilder.createBlock(
457466
&copyRegion, /*insertPt=*/{}, {symType, symType}, {symLoc, symLoc});
458467
firOpBuilder.setInsertionPointToEnd(copyEntryBlock);
459-
symTable->addSymbol(*sym,
460-
fir::substBase(symExV, copyRegion.getArgument(0)),
461-
/*force=*/true);
468+
469+
auto addSymbol = [&](unsigned argIdx, bool force = false) {
470+
symExV.match(
471+
[&](const fir::MutableBoxValue &box) {
472+
symTable->addSymbol(
473+
*sym, fir::substBase(box, copyRegion.getArgument(argIdx)),
474+
force);
475+
},
476+
[&](const auto &box) {
477+
symTable->addSymbol(*sym, copyRegion.getArgument(argIdx), force);
478+
});
479+
};
480+
481+
addSymbol(0, true);
462482
symTable->pushScope();
463-
symTable->addSymbol(*sym,
464-
fir::substBase(symExV, copyRegion.getArgument(1)));
483+
addSymbol(1);
484+
465485
auto ip = firOpBuilder.saveInsertionPoint();
466486
copyFirstPrivateSymbol(sym, &ip);
467487

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,13 +1439,18 @@ genParallelOp(Fortran::lower::AbstractConverter &converter,
14391439
reductionSyms;
14401440
allSymbols.append(privateSyms);
14411441
for (auto [arg, prv] : llvm::zip_equal(allSymbols, region.getArguments())) {
1442-
converter.bindSymbol(*arg, prv);
1442+
fir::ExtendedValue hostExV = converter.getSymbolExtendedValue(*arg);
1443+
converter.bindSymbol(*arg, hlfir::translateToExtendedValue(
1444+
loc, firOpBuilder, hlfir::Entity{prv},
1445+
/*contiguousHint=*/
1446+
Fortran::evaluate::IsSimplyContiguous(
1447+
*arg, converter.getFoldingContext()))
1448+
.first);
14431449
}
14441450

14451451
return allSymbols;
14461452
};
14471453

1448-
// TODO Merge with the reduction CB.
14491454
genInfo.setGenRegionEntryCb(genRegionEntryCB).setDataSharingProcessor(&dsp);
14501455
return genOpWithBody<mlir::omp::ParallelOp>(genInfo, clauseOps);
14511456
}

flang/lib/Optimizer/Builder/HLFIRTools.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -844,10 +844,9 @@ hlfir::LoopNest hlfir::genLoopNest(mlir::Location loc,
844844
return loopNest;
845845
}
846846

847-
static fir::ExtendedValue
848-
translateVariableToExtendedValue(mlir::Location loc, fir::FirOpBuilder &builder,
849-
hlfir::Entity variable,
850-
bool forceHlfirBase = false) {
847+
static fir::ExtendedValue translateVariableToExtendedValue(
848+
mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity variable,
849+
bool forceHlfirBase = false, bool contiguousHint = false) {
851850
assert(variable.isVariable() && "must be a variable");
852851
/// When going towards FIR, use the original base value to avoid
853852
/// introducing descriptors at runtime when they are not required.
@@ -858,7 +857,8 @@ translateVariableToExtendedValue(mlir::Location loc, fir::FirOpBuilder &builder,
858857
fir::MutableProperties{});
859858

860859
if (mlir::isa<fir::BaseBoxType>(base.getType())) {
861-
if (!variable.isSimplyContiguous() || variable.isPolymorphic() ||
860+
bool contiguous = variable.isSimplyContiguous() || contiguousHint;
861+
if (!contiguous || variable.isPolymorphic() ||
862862
variable.isDerivedWithLengthParameters() || variable.isOptional()) {
863863
llvm::SmallVector<mlir::Value> nonDefaultLbounds =
864864
getNonDefaultLowerBounds(loc, builder, variable);
@@ -907,9 +907,10 @@ hlfir::translateToExtendedValue(mlir::Location loc, fir::FirOpBuilder &builder,
907907

908908
std::pair<fir::ExtendedValue, std::optional<hlfir::CleanupFunction>>
909909
hlfir::translateToExtendedValue(mlir::Location loc, fir::FirOpBuilder &builder,
910-
hlfir::Entity entity) {
910+
hlfir::Entity entity, bool contiguousHint) {
911911
if (entity.isVariable())
912-
return {translateVariableToExtendedValue(loc, builder, entity),
912+
return {translateVariableToExtendedValue(loc, builder, entity, false,
913+
contiguousHint),
913914
std::nullopt};
914915

915916
if (entity.isProcedure()) {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
! Test delayed privatization for allocatable arrays.
2+
3+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --openmp-enable-delayed-privatization \
4+
! RUN: -o - %s 2>&1 | FileCheck %s
5+
! RUN: bbc -emit-hlfir -fopenmp --openmp-enable-delayed-privatization -o - %s 2>&1 |\
6+
! RUN: FileCheck %s
7+
8+
subroutine delayed_privatization_private(var1, l1)
9+
implicit none
10+
integer(8):: l1
11+
integer, allocatable, dimension(:) :: var1
12+
13+
!$omp parallel firstprivate(var1)
14+
var1(l1 + 1) = 10
15+
!$omp end parallel
16+
end subroutine
17+
18+
! CHECK-LABEL: omp.private {type = firstprivate}
19+
! CHECK-SAME: @[[PRIVATIZER_SYM:.*]] : [[TYPE:!fir.ref<!fir.box<!fir.heap<!fir.array<\?xi32>>>>]] alloc {
20+
21+
! CHECK-NEXT: ^bb0(%[[PRIV_ARG:.*]]: [[TYPE]]):
22+
! CHECK-NEXT: %[[PRIV_ALLOC:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<{{\?}}xi32>>> {bindc_name = "var1", pinned, uniq_name = "_QFdelayed_privatization_privateEvar1"}
23+
24+
! CHECK-NEXT: %[[PRIV_ARG_VAL:.*]] = fir.load %[[PRIV_ARG]]
25+
! CHECK-NEXT: %[[PRIV_ARG_BOX:.*]] = fir.box_addr %[[PRIV_ARG_VAL]]
26+
! CHECK-NEXT: %[[PRIV_ARG_ADDR:.*]] = fir.convert %[[PRIV_ARG_BOX]]
27+
! CHECK-NEXT: %[[C0:.*]] = arith.constant 0 : i64
28+
! CHECK-NEXT: %[[ALLOC_COND:.*]] = arith.cmpi ne, %[[PRIV_ARG_ADDR]], %[[C0]] : i64
29+
30+
! CHECK-NEXT: fir.if %[[ALLOC_COND]] {
31+
! CHECK-NEXT: %[[PRIV_ARG_VAL:.*]] = fir.load %[[PRIV_ARG]] : [[TYPE]]
32+
! CHECK-NEXT: %[[C0:.*]] = arith.constant 0 : index
33+
! CHECK-NEXT: %[[DIMS:.*]]:3 = fir.box_dims %[[PRIV_ARG_VAL]], %[[C0]]
34+
! CHECK-NEXT: fir.box_addr %[[PRIV_ARG_VAL]]
35+
! CHECK-NEXT: %[[C0_2:.*]] = arith.constant 0 : index
36+
! CHECK-NEXT: %[[CMP:.*]] = arith.cmpi sgt, %[[DIMS]]#1, %[[C0_2]] : index
37+
! CHECK-NEXT: %[[SELECT:.*]] = arith.select %[[CMP]], %[[DIMS]]#1, %[[C0_2]] : index
38+
! CHECK-NEXT: %[[MEM:.*]] = fir.allocmem !fir.array<?xi32>, %[[SELECT]]
39+
! CHECK-NEXT: %[[SHAPE_SHIFT:.*]] = fir.shape_shift %[[DIMS]]#0, %[[SELECT]] : (index, index) -> !fir.shapeshift<1>
40+
! CHECK-NEXT: %[[EMBOX:.*]] = fir.embox %[[MEM]](%[[SHAPE_SHIFT]])
41+
! CHECK-NEXT: fir.store %[[EMBOX]] to %[[PRIV_ALLOC]]
42+
! CHECK-NEXT: } else {
43+
! CHECK-NEXT: %[[ZEROS:.*]] = fir.zero_bits
44+
! CHECK-NEXT: %[[C0_3:.*]] = arith.constant 0 : index
45+
! CHECK-NEXT: %[[SHAPE:.*]] = fir.shape %[[C0_3]] : (index) -> !fir.shape<1>
46+
! CHECK-NEXT: %[[EMBOX_2:.*]] = fir.embox %[[ZEROS]](%[[SHAPE]])
47+
! CHECK-NEXT: fir.store %[[EMBOX_2]] to %[[PRIV_ALLOC]]
48+
! CHECK-NEXT: }
49+
50+
! CHECK-NEXT: hlfir.declare
51+
! CHECK-NEXT: omp.yield
52+
53+
! CHECK-NEXT: } copy {
54+
! CHECK-NEXT: ^bb0(%[[PRIV_ORIG_ARG:.*]]: [[TYPE]], %[[PRIV_PRIV_ARG:.*]]: [[TYPE]]):
55+
! CHECK-NEXT: %[[PRIV_BASE_VAL:.*]] = fir.load %[[PRIV_PRIV_ARG]]
56+
! CHECK-NEXT: %[[PRIV_BASE_BOX:.*]] = fir.box_addr %[[PRIV_BASE_VAL]]
57+
! CHECK-NEXT: %[[PRIV_BASE_ADDR:.*]] = fir.convert %[[PRIV_BASE_BOX]]
58+
! CHECK-NEXT: %[[C0:.*]] = arith.constant 0 : i64
59+
! CHECK-NEXT: %[[COPY_COND:.*]] = arith.cmpi ne, %[[PRIV_BASE_ADDR]], %[[C0]] : i64
60+
61+
62+
! CHECK-NEXT: fir.if %[[COPY_COND]] {
63+
! CHECK-NEXT: %[[PRIV_ORIG_ARG_VAL:.*]] = fir.load %[[PRIV_ORIG_ARG]]
64+
! CHECK-NEXT: hlfir.assign %[[PRIV_ORIG_ARG_VAL]] to %[[PRIV_BASE_VAL]] temporary_lhs
65+
! CHECK-NEXT: }
66+
! CHECK-NEXT: omp.yield
67+
! CHECK-NEXT: }
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
! Test delayed privatization for arrays.
2+
3+
! RUN: split-file %s %t
4+
5+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --openmp-enable-delayed-privatization \
6+
! RUN: -o - %t/one_dim_array.f90 2>&1 | FileCheck %s --check-prefix=ONE_DIM
7+
! RUN: bbc -emit-hlfir -fopenmp --openmp-enable-delayed-privatization -o - \
8+
! RUN: %t/one_dim_array.f90 2>&1 | FileCheck %s --check-prefix=ONE_DIM
9+
10+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --openmp-enable-delayed-privatization \
11+
! RUN: -o - %t/two_dim_array.f90 2>&1 | FileCheck %s --check-prefix=TWO_DIM
12+
! RUN: bbc -emit-hlfir -fopenmp --openmp-enable-delayed-privatization -o - \
13+
! RUN: %t/two_dim_array.f90 2>&1 | FileCheck %s --check-prefix=TWO_DIM
14+
15+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --openmp-enable-delayed-privatization \
16+
! RUN: -o - %t/one_dim_array_default_lb.f90 2>&1 | FileCheck %s --check-prefix=ONE_DIM_DEFAULT_LB
17+
! RUN: bbc -emit-hlfir -fopenmp --openmp-enable-delayed-privatization -o - \
18+
! RUN: %t/one_dim_array_default_lb.f90 2>&1 | FileCheck %s --check-prefix=ONE_DIM_DEFAULT_LB
19+
20+
!--- one_dim_array.f90
21+
subroutine delayed_privatization_private_1d(var1, l1, u1)
22+
implicit none
23+
integer(8):: l1, u1
24+
integer, dimension(l1:u1) :: var1
25+
26+
!$omp parallel firstprivate(var1)
27+
var1(l1 + 1) = 10
28+
!$omp end parallel
29+
end subroutine
30+
31+
! ONE_DIM-LABEL: omp.private {type = firstprivate}
32+
! ONE_DIM-SAME: @[[PRIVATIZER_SYM:.*]] : [[TYPE:!fir.box<!fir.array<\?xi32>>]] alloc {
33+
34+
! ONE_DIM-NEXT: ^bb0(%[[PRIV_ARG:.*]]: [[TYPE]]):
35+
36+
! ONE_DIM: %[[C0:.*]] = arith.constant 0 : index
37+
! ONE_DIM-NEXT: %[[DIMS:.*]]:3 = fir.box_dims %[[PRIV_ARG]], %[[C0]] : ([[TYPE]], index) -> (index, index, index)
38+
! ONE_DIM: %[[PRIV_ALLOCA:.*]] = fir.alloca !fir.array<{{\?}}xi32>
39+
! ONE_DIM-NEXT: %[[SHAPE_SHIFT:.*]] = fir.shape_shift %[[DIMS]]#0, %[[DIMS]]#1 : (index, index) -> !fir.shapeshift<1>
40+
! ONE_DIM-NEXT: %[[PRIV_DECL:.*]]:2 = hlfir.declare %[[PRIV_ALLOCA]](%[[SHAPE_SHIFT]]) {uniq_name = "_QFdelayed_privatization_private_1dEvar1"}
41+
! ONE_DIM-NEXT: omp.yield(%[[PRIV_DECL]]#0 : [[TYPE]])
42+
43+
! ONE_DIM-NEXT: } copy {
44+
! ONE_DIM-NEXT: ^bb0(%[[PRIV_ORIG_ARG:.*]]: [[TYPE]], %[[PRIV_PRIV_ARG:.*]]: [[TYPE]]):
45+
! ONE_DIM-NEXT: hlfir.assign %[[PRIV_ORIG_ARG]] to %[[PRIV_PRIV_ARG]] temporary_lhs
46+
! ONE_DIM-NEXT: omp.yield(%[[PRIV_PRIV_ARG]] : [[TYPE]])
47+
! ONE_DIM-NEXT: }
48+
49+
!--- two_dim_array.f90
50+
subroutine delayed_privatization_private_2d(var1, l1, u1, l2, u2)
51+
implicit none
52+
integer(8):: l1, u1, l2, u2
53+
integer, dimension(l1:u1, l2:u2) :: var1
54+
55+
!$omp parallel firstprivate(var1)
56+
var1(l1 + 1, u2) = 10
57+
!$omp end parallel
58+
end subroutine
59+
60+
! TWO_DIM-LABEL: omp.private {type = firstprivate}
61+
! TWO_DIM-SAME: @[[PRIVATIZER_SYM:.*]] : [[TYPE:!fir.box<!fir.array<\?x\?xi32>>]] alloc {
62+
63+
! TWO_DIM-NEXT: ^bb0(%[[PRIV_ARG:.*]]: [[TYPE]]):
64+
! TWO_DIM: %[[C0:.*]] = arith.constant 0 : index
65+
! TWO_DIM-NEXT: %[[DIMS0:.*]]:3 = fir.box_dims %[[PRIV_ARG]], %[[C0]] : ([[TYPE]], index) -> (index, index, index)
66+
67+
! TWO_DIM-NEXT: %[[C1:.*]] = arith.constant 1 : index
68+
! TWO_DIM-NEXT: %[[DIMS1:.*]]:3 = fir.box_dims %[[PRIV_ARG]], %[[C1]] : ([[TYPE]], index) -> (index, index, index)
69+
70+
! TWO_DIM-NEXT: %[[PRIV_ALLOCA:.*]] = fir.alloca !fir.array<{{\?}}x{{\?}}xi32>, %[[DIMS0]]#1, %[[DIMS1]]#1 {bindc_name = "var1", pinned, uniq_name = "_QFdelayed_privatization_private_2dEvar1"}
71+
! TWO_DIM-NEXT: %[[SHAPE_SHIFT:.*]] = fir.shape_shift %[[DIMS0]]#0, %[[DIMS0]]#1, %[[DIMS1]]#0, %[[DIMS1]]#1 : (index, index, index, index) -> !fir.shapeshift<2>
72+
73+
! TWO_DIM-NEXT: %[[PRIV_DECL:.*]]:2 = hlfir.declare %[[PRIV_ALLOCA]](%[[SHAPE_SHIFT]]) {uniq_name = "_QFdelayed_privatization_private_2dEvar1"}
74+
! TWO_DIM-NEXT: omp.yield(%[[PRIV_DECL]]#0 : [[TYPE]])
75+
76+
! TWO_DIM-NEXT: } copy {
77+
! TWO_DIM-NEXT: ^bb0(%[[PRIV_ORIG_ARG:.*]]: [[TYPE]], %[[PRIV_PRIV_ARG:.*]]: [[TYPE]]):
78+
! TWO_DIM-NEXT: hlfir.assign %[[PRIV_ORIG_ARG]] to %[[PRIV_PRIV_ARG]] temporary_lhs
79+
! TWO_DIM-NEXT: omp.yield(%[[PRIV_PRIV_ARG]] : [[TYPE]])
80+
! TWO_DIM-NEXT: }
81+
82+
!--- one_dim_array_default_lb.f90
83+
program main
84+
implicit none
85+
integer, dimension(10) :: var1
86+
87+
!$omp parallel private(var1)
88+
var1(1) = 10
89+
!$omp end parallel
90+
end program
91+
92+
! ONE_DIM_DEFAULT_LB-LABEL: omp.private {type = private}
93+
! ONE_DIM_DEFAULT_LB-SAME: @[[PRIVATIZER_SYM:.*]] : [[TYPE:!fir.ref<!fir.array<10xi32>>]] alloc {
94+
95+
! ONE_DIM_DEFAULT_LB-NEXT: ^bb0(%[[PRIV_ARG:.*]]: [[TYPE]]):
96+
97+
! ONE_DIM_DEFAULT_LB: %[[C10:.*]] = arith.constant 10 : index
98+
! ONE_DIM_DEFAULT_LB: %[[PRIV_ALLOCA:.*]] = fir.alloca !fir.array<10xi32>
99+
! ONE_DIM_DEFAULT_LB: %[[SHAPE:.*]] = fir.shape %[[C10]] : (index) -> !fir.shape<1>
100+
! ONE_DIM_DEFAULT_LB: hlfir.declare %[[PRIV_ALLOCA]](%[[SHAPE]])
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
! Test delayed privatization for the `CHARACTER` array type.
2+
3+
! RUN: split-file %s %t
4+
5+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --openmp-enable-delayed-privatization \
6+
! RUN: -o - %t/static_len.f90 2>&1 | FileCheck %s --check-prefix=STATIC_LEN
7+
! RUN: bbc -emit-hlfir -fopenmp --openmp-enable-delayed-privatization -o - %t/static_len.f90 2>&1 \
8+
! RUN: | FileCheck %s --check-prefix=STATIC_LEN
9+
10+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --openmp-enable-delayed-privatization \
11+
! RUN: -o - %t/dyn_len.f90 2>&1 | FileCheck %s --check-prefix=DYN_LEN
12+
! RUN: bbc -emit-hlfir -fopenmp --openmp-enable-delayed-privatization -o - %t/dyn_len.f90 2>&1 \
13+
! RUN: | FileCheck %s --check-prefix=DYN_LEN
14+
15+
!--- static_len.f90
16+
subroutine delayed_privatization_character_array_static_len(var1)
17+
implicit none
18+
character(len = 10) :: var1(5)
19+
20+
!$omp parallel firstprivate(var1)
21+
var1(1) = "test"
22+
!$omp end parallel
23+
end subroutine
24+
25+
! STATIC_LEN-LABEL: omp.private {type = firstprivate}
26+
! STATIC_LEN-SAME: @[[PRIVATIZER_SYM:.*]] : [[TYPE:!fir.ref<!fir.array<5x!fir.char<1,10>>>]] alloc {
27+
28+
! STATIC_LEN-NEXT: ^bb0(%[[PRIV_ARG:.*]]: [[TYPE]]):
29+
! STATIC_LEN-DAG: %[[C5:.*]] = arith.constant 5 : index
30+
! STATIC_LEN-DAG: %[[C10:.*]] = arith.constant 10 : index
31+
! STATIC_LEN-NEXT: %[[PRIV_ALLOC:.*]] = fir.alloca !fir.array<5x!fir.char<1,10>>
32+
! STATIC_LEN-NEXT: %[[ARRAY_SHAPE:.*]] = fir.shape %[[C5]]
33+
! STATIC_LEN-NEXT: %[[PRIV_DECL:.*]]:2 = hlfir.declare %[[PRIV_ALLOC]](%[[ARRAY_SHAPE]]) typeparams %[[C10]]
34+
! STATIC_LEN-NEXT: omp.yield(%[[PRIV_DECL]]#0
35+
36+
! STATIC_LEN-NEXT: } copy {
37+
! STATIC_LEN-NEXT: ^bb0(%[[PRIV_ORIG_ARG:.*]]: [[TYPE]], %[[PRIV_PRIV_ARG:.*]]: [[TYPE]]):
38+
! STATIC_LEN-NEXT: hlfir.assign %[[PRIV_ORIG_ARG]] to %[[PRIV_PRIV_ARG]]
39+
40+
! STATIC_LEN-NEXT: omp.yield(%[[PRIV_PRIV_ARG]]
41+
! STATIC_LEN-NEXT: }
42+
43+
!--- dyn_len.f90
44+
subroutine delayed_privatization_character_array_dynamic_len(var1, char_len, array_len)
45+
implicit none
46+
integer(8):: char_len
47+
integer(8):: array_len
48+
character(len = char_len) :: var1(array_len)
49+
50+
!$omp parallel private(var1)
51+
var1(1) = "test"
52+
!$omp end parallel
53+
end subroutine
54+
55+
! DYN_LEN-LABEL: omp.private {type = private}
56+
! DYN_LEN-SAME: @[[PRIVATIZER_SYM:.*]] : [[TYPE:!fir.box<!fir.array<\?x!fir.char<1,\?>>>]] alloc {
57+
58+
! DYN_LEN-NEXT: ^bb0(%[[PRIV_ARG:.*]]: [[TYPE]]):
59+
60+
! DYN_LEN: %[[C0:.*]] = arith.constant 0 : index
61+
! DYN_LEN-NEXT: %[[BOX_DIM:.*]]:3 = fir.box_dims %[[PRIV_ARG]], %[[C0]]
62+
! DYN_LEN: %[[CHAR_LEN:.*]] = fir.box_elesize %[[PRIV_ARG]]
63+
! DYN_LEN-NEXT: %[[PRIV_ALLOC:.*]] = fir.alloca !fir.array<?x!fir.char<1,?>>(%[[CHAR_LEN]] : index)
64+
! DYN_LEN-NEXT: %[[ARRAY_SHAPE:.*]] = fir.shape
65+
! DYN_LEN-NEXT: %[[PRIV_DECL:.*]]:2 = hlfir.declare %[[PRIV_ALLOC]](%[[ARRAY_SHAPE]]) typeparams %[[CHAR_LEN]]
66+
67+
! DYN_LEN-NEXT: omp.yield(%[[PRIV_DECL]]#0

0 commit comments

Comments
 (0)