Skip to content

Commit 2c3ded6

Browse files
committed
[flang][OpenMP] Support for common block in copyin clause
This patch adds lowering support for threadprivate variables encapsulated in a common block and marked inside a copyin clause. Reviewed By: kiranchandramohan Differential Revision: https://reviews.llvm.org/D157083
1 parent 41e71f5 commit 2c3ded6

File tree

2 files changed

+121
-5
lines changed

2 files changed

+121
-5
lines changed

flang/lib/Lower/OpenMP.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,22 +1525,31 @@ bool ClauseProcessor::processCopyin() const {
15251525
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
15261526
mlir::OpBuilder::InsertPoint insPt = firOpBuilder.saveInsertionPoint();
15271527
firOpBuilder.setInsertionPointToStart(firOpBuilder.getAllocaBlock());
1528-
1528+
auto checkAndCopyHostAssociateVar =
1529+
[&](Fortran::semantics::Symbol *sym,
1530+
mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr) {
1531+
assert(sym->has<Fortran::semantics::HostAssocDetails>() &&
1532+
"No host-association found");
1533+
converter.copyHostAssociateVar(*sym, copyAssignIP);
1534+
};
15291535
bool hasCopyin = findRepeatableClause<ClauseTy::Copyin>(
15301536
[&](const ClauseTy::Copyin *copyinClause,
15311537
const Fortran::parser::CharBlock &) {
15321538
const Fortran::parser::OmpObjectList &ompObjectList = copyinClause->v;
15331539
for (const Fortran::parser::OmpObject &ompObject : ompObjectList.v) {
15341540
Fortran::semantics::Symbol *sym = getOmpObjectSymbol(ompObject);
1535-
if (sym->has<Fortran::semantics::CommonBlockDetails>())
1536-
TODO(converter.getCurrentLocation(),
1537-
"common block in Copyin clause");
1541+
if (const auto *commonDetails =
1542+
sym->detailsIf<Fortran::semantics::CommonBlockDetails>()) {
1543+
for (const auto &mem : commonDetails->objects())
1544+
checkAndCopyHostAssociateVar(&*mem, &insPt);
1545+
break;
1546+
}
15381547
if (Fortran::semantics::IsAllocatableOrPointer(sym->GetUltimate()))
15391548
TODO(converter.getCurrentLocation(),
15401549
"pointer or allocatable variables in Copyin clause");
15411550
assert(sym->has<Fortran::semantics::HostAssocDetails>() &&
15421551
"No host-association found");
1543-
converter.copyHostAssociateVar(*sym);
1552+
checkAndCopyHostAssociateVar(sym);
15441553
}
15451554
});
15461555

flang/test/Lower/OpenMP/copyin.f90

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,110 @@ subroutine combined_parallel_sections()
204204
!$omp end parallel sections
205205

206206
end
207+
208+
209+
!CHECK: func.func @_QPcommon_1() {
210+
!CHECK: %[[val_0:.*]] = fir.address_of(@_QCc) : !fir.ref<!fir.array<4xi8>>
211+
!CHECK: %[[val_1:.*]] = omp.threadprivate %[[val_0]] : !fir.ref<!fir.array<4xi8>> -> !fir.ref<!fir.array<4xi8>>
212+
!CHECK: %[[val_2:.*]] = fir.convert %[[val_1]] : (!fir.ref<!fir.array<4xi8>>) -> !fir.ref<!fir.array<?xi8>>
213+
!CHECK: %[[val_c0:.*]] = arith.constant 0 : index
214+
!CHECK: %[[val_3:.*]] = fir.coordinate_of %[[val_2]], %[[val_c0]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
215+
!CHECK: %[[val_4:.*]] = fir.convert %[[val_3]] : (!fir.ref<i8>) -> !fir.ref<i32>
216+
!CHECK: %[[val_5:.*]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFcommon_1Ey"}
217+
!CHECK: omp.parallel {
218+
!CHECK: %[[val_6:.*]] = omp.threadprivate %[[val_0]] : !fir.ref<!fir.array<4xi8>> -> !fir.ref<!fir.array<4xi8>>
219+
!CHECK: %[[val_7:.*]] = fir.convert %[[val_6]] : (!fir.ref<!fir.array<4xi8>>) -> !fir.ref<!fir.array<?xi8>>
220+
!CHECK: %[[val_c0_0:.*]] = arith.constant 0 : index
221+
!CHECK: %[[val_8:.*]] = fir.coordinate_of %[[val_7]], %[[val_c0_0]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
222+
!CHECK: %[[val_9:.*]] = fir.convert %[[val_8]] : (!fir.ref<i8>) -> !fir.ref<i32>
223+
!CHECK: %[[val_10:.*]] = fir.load %[[val_4]] : !fir.ref<i32>
224+
!CHECK: fir.store %[[val_10]] to %[[val_9]] : !fir.ref<i32>
225+
!CHECK: omp.barrier
226+
!CHECK: omp.sections {
227+
!CHECK: omp.section {
228+
!CHECK: %[[val_11:.*]] = fir.load %[[val_9]] : !fir.ref<i32>
229+
!CHECK: %[[val_c1_i32:.*]] = arith.constant 1 : i32
230+
!CHECK: %[[val_12:.*]] = arith.addi %[[val_11]], %[[val_c1_i32]] : i32
231+
!CHECK: fir.store %[[val_12]] to %[[val_5]] : !fir.ref<i32>
232+
!CHECK: omp.terminator
233+
!CHECK: }
234+
!CHECK: omp.section {
235+
!CHECK: %[[val_11:.*]] = fir.load %[[val_5]] : !fir.ref<i32>
236+
!CHECK: %[[val_12:.*]] = fir.load %[[val_5]] : !fir.ref<i32>
237+
!CHECK: %[[val_13:.*]] = arith.muli %[[val_11]], %[[val_12]] : i32
238+
!CHECK: fir.store %[[val_13]] to %[[val_9]] : !fir.ref<i32>
239+
!CHECK: omp.terminator
240+
!CHECK: }
241+
!CHECK: omp.terminator
242+
!CHECK: }
243+
!CHECK: return
244+
!CHECK: }
245+
subroutine common_1()
246+
integer :: x
247+
integer :: y
248+
common /c/ x
249+
!$omp threadprivate(/c/)
250+
251+
!$omp parallel sections copyin(/c/)
252+
!$omp section
253+
y = x + 1
254+
!$omp section
255+
x = y * y
256+
!$omp end parallel sections
257+
end subroutine
258+
259+
!CHECK: func.func @_QPcommon_2() {
260+
!CHECK: %[[val_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFcommon_2Ei"}
261+
!CHECK: %[[val_1:.*]] = fir.address_of(@_QCd) : !fir.ref<!fir.array<8xi8>>
262+
!CHECK: %[[val_2:.*]] = omp.threadprivate %[[val_1]] : !fir.ref<!fir.array<8xi8>> -> !fir.ref<!fir.array<8xi8>>
263+
!CHECK: %[[val_3:.*]] = fir.convert %[[val_2]] : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
264+
!CHECK: %[[val_c0:.*]] = arith.constant 0 : index
265+
!CHECK: %[[val_4:.*]] = fir.coordinate_of %[[val_3]], %[[val_c0]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
266+
!CHECK: %[[val_5:.*]] = fir.convert %[[val_4]] : (!fir.ref<i8>) -> !fir.ref<i32>
267+
!CHECK: %[[val_6:.*]] = fir.convert %[[val_2]] : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
268+
!CHECK: %[[val_c4:.*]] = arith.constant 4 : index
269+
!CHECK: %[[val_7:.*]] = fir.coordinate_of %[[val_6]], %[[val_c4]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
270+
!CHECK: %[[val_8:.*]] = fir.convert %[[val_7]] : (!fir.ref<i8>) -> !fir.ref<i32>
271+
!CHECK: omp.parallel {
272+
!CHECK: %[[val_9:.*]] = fir.alloca i32 {adapt.valuebyref, pinned}
273+
!CHECK: %[[val_10:.*]] = omp.threadprivate %[[val_1]] : !fir.ref<!fir.array<8xi8>> -> !fir.ref<!fir.array<8xi8>>
274+
!CHECK: %[[val_11:.*]] = fir.convert %[[val_10]] : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
275+
!CHECK: %[[val_c0_0:.*]] = arith.constant 0 : index
276+
!CHECK: %[[val_12:.*]] = fir.coordinate_of %[[val_11]], %[[val_c0_0]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
277+
!CHECK: %[[val_13:.*]] = fir.convert %[[val_12]] : (!fir.ref<i8>) -> !fir.ref<i32>
278+
!CHECK: %[[val_14:.*]] = fir.convert %[[val_10]] : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
279+
!CHECK: %[[val_c4_1:.*]] = arith.constant 4 : index
280+
!CHECK: %[[val_15:.*]] = fir.coordinate_of %[[val_14]], %[[val_c4_1]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
281+
!CHECK: %[[val_16:.*]] = fir.convert %[[val_15]] : (!fir.ref<i8>) -> !fir.ref<i32>
282+
!CHECK: %[[val_17:.*]] = fir.load %[[val_5]] : !fir.ref<i32>
283+
!CHECK: fir.store %[[val_17]] to %[[val_13]] : !fir.ref<i32>
284+
!CHECK: %[[val_18:.*]] = fir.load %[[val_8]] : !fir.ref<i32>
285+
!CHECK: fir.store %[[val_18]] to %[[val_16]] : !fir.ref<i32>
286+
!CHECK: omp.barrier
287+
!CHECK: %[[val_c1_i32:.*]] = arith.constant 1 : i32
288+
!CHECK: %[[val_19:.*]] = fir.load %[[val_13]] : !fir.ref<i32>
289+
!CHECK: %[[val_c1_i32_2:.*]] = arith.constant 1 : i32
290+
!CHECK: omp.wsloop for (%[[arg:.*]]) : i32 = (%[[val_c1_i32]]) to (%[[val_19]]) inclusive step (%[[val_c1_i32_2]]) {
291+
!CHECK: fir.store %[[arg]] to %[[val_9]] : !fir.ref<i32>
292+
!CHECK: %[[val_20:.*]] = fir.load %[[val_16]] : !fir.ref<i32>
293+
!CHECK: %[[val_21:.*]] = fir.load %[[val_9]] : !fir.ref<i32>
294+
!CHECK: %[[val_22:.*]] = arith.addi %[[val_20]], %[[val_21]] : i32
295+
!CHECK: fir.store %[[val_22]] to %[[val_16]] : !fir.ref<i32>
296+
!CHECK: omp.yield
297+
!CHECK: }
298+
!CHECK: omp.terminator
299+
!CHECK: }
300+
!CHECK: return
301+
!CHECK: }
302+
subroutine common_2()
303+
integer :: x
304+
integer :: y
305+
common /d/ x, y
306+
!$omp threadprivate(/d/)
307+
308+
!$omp parallel do copyin(/d/)
309+
do i = 1, x
310+
y = y + i
311+
end do
312+
!$omp end parallel do
313+
end subroutine

0 commit comments

Comments
 (0)