Skip to content

Commit e9cba3c

Browse files
authored
[flang][OpenMP] use attribute for delayed privatization barrier (llvm#140092)
Fixes llvm#136357 The barrier needs to go between the copying into firstprivate variables and the initialization call for the OpenMP construct (e.g. wsloop). There is no way of expressing this in MLIR because for delayed privatization that is all implicit (added in MLIR->LLVMIR conversion). The previous approach put the barrier immediately before the wsloop (or similar). For delayed privatization, the firstprivate copy code would then be inserted after that, opening the possibility for the race observed in the bug report. This patch solves the issue by instead setting an attribute on the mlir operation, which will instruct openmp dialect to llvm ir conversion to insert a barrier in the correct place.
1 parent b048f3f commit e9cba3c

File tree

5 files changed

+16
-9
lines changed

5 files changed

+16
-9
lines changed

flang/lib/Lower/OpenMP/DataSharingProcessor.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ void DataSharingProcessor::processStep1(
6262

6363
privatize(clauseOps);
6464

65-
insertBarrier();
65+
insertBarrier(clauseOps);
6666
}
6767

6868
void DataSharingProcessor::processStep2(mlir::Operation *op, bool isLoop) {
@@ -231,9 +231,18 @@ bool DataSharingProcessor::needBarrier() {
231231
return false;
232232
}
233233

234-
void DataSharingProcessor::insertBarrier() {
235-
if (needBarrier())
234+
void DataSharingProcessor::insertBarrier(
235+
mlir::omp::PrivateClauseOps *clauseOps) {
236+
if (!needBarrier())
237+
return;
238+
239+
if (useDelayedPrivatization) {
240+
if (clauseOps)
241+
clauseOps->privateNeedsBarrier =
242+
mlir::UnitAttr::get(&converter.getMLIRContext());
243+
} else {
236244
firOpBuilder.create<mlir::omp::BarrierOp>(converter.getCurrentLocation());
245+
}
237246
}
238247

239248
void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) {

flang/lib/Lower/OpenMP/DataSharingProcessor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class DataSharingProcessor {
100100
const omp::ObjectList &objects,
101101
llvm::SetVector<const semantics::Symbol *> &symbolSet);
102102
void collectSymbolsForPrivatization();
103-
void insertBarrier();
103+
void insertBarrier(mlir::omp::PrivateClauseOps *clauseOps);
104104
void collectDefaultSymbols();
105105
void collectImplicitSymbols();
106106
void collectPreDeterminedSymbols();

flang/test/Lower/OpenMP/lastprivate-allocatable.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
! CHECK: fir.store %[[VAL_2]] to %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
99
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] {fortran_attrs = {{.*}}<allocatable>, uniq_name = "_QFEa"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)
1010
! CHECK: omp.parallel {
11-
! CHECK: omp.wsloop private(@{{.*}} %{{.*}} -> %{{.*}}, @{{.*}} %{{.*}} -> %[[VAL_17:.*]] : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<i32>) {
11+
! CHECK: omp.wsloop private(@{{.*}} %{{.*}} -> %{{.*}}, @{{.*}} %{{.*}} -> %[[VAL_17:.*]] : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<i32>) private_barrier {
1212
! CHECK: omp.loop_nest
1313
! CHECK: %[[VAL_16:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = {{.*}}<allocatable>, uniq_name = "_QFEa"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)
1414
! CHECK: %[[VAL_18:.*]]:2 = hlfir.declare %[[VAL_17]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)

flang/test/Lower/OpenMP/parallel-lastprivate-clause-scalar.f90

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,7 @@ subroutine firstpriv_lastpriv_int(arg1, arg2)
226226
! Firstprivate update
227227

228228

229-
!CHECK-NEXT: omp.barrier
230-
!CHECK: omp.wsloop private(@{{.*}} %{{.*}}#0 -> %[[CLONE1:.*]], @{{.*}} %{{.*}}#0 -> %[[IV:.*]] : !fir.ref<i32>, !fir.ref<i32>) {
229+
!CHECK: omp.wsloop private(@{{.*}} %{{.*}}#0 -> %[[CLONE1:.*]], @{{.*}} %{{.*}}#0 -> %[[IV:.*]] : !fir.ref<i32>, !fir.ref<i32>) private_barrier {
231230
!CHECK-NEXT: omp.loop_nest (%[[INDX_WS:.*]]) : {{.*}} {
232231
!CHECK: %[[CLONE1_DECL:.*]]:2 = hlfir.declare %[[CLONE1]] {uniq_name = "_QFfirstpriv_lastpriv_int2Earg1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
233232

flang/test/Lower/OpenMP/same_var_first_lastprivate.f90

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ subroutine first_and_lastprivate
2020
! CHECK: func.func @{{.*}}first_and_lastprivate()
2121
! CHECK: %[[ORIG_VAR_DECL:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "{{.*}}Evar"}
2222
! CHECK: omp.parallel {
23-
! CHECK: omp.barrier
24-
! CHECK: omp.wsloop private(@{{.*}}var_firstprivate_i32 {{.*}}) {
23+
! CHECK: omp.wsloop private(@{{.*}}var_firstprivate_i32 {{.*}}) private_barrier {
2524
! CHECK: omp.loop_nest {{.*}} {
2625
! CHECK: %[[PRIV_VAR_DECL:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "{{.*}}Evar"}
2726
! CHECK: fir.if %{{.*}} {

0 commit comments

Comments
 (0)