Skip to content

Commit

Permalink
[Flang][OpenMP] Fix loop index privatisation with HLFIR
Browse files Browse the repository at this point in the history
Loop index variables are privatised for a worksharing loop.
The alloca ops of the privatised index are hoisted to the
entry block of the outlineable region or parent function.
With HLFIR, the hlfir.declare should be created in the same
place as the alloca op. To achieve this the alloc and the
hflir.declare should be created in the same place. A new
function is created in OpenMP.cpp for this purpose.

Reviewed By: tblah

Differential Revision: https://reviews.llvm.org/D156719
  • Loading branch information
kiranchandramohan committed Aug 1, 2023
1 parent 1684406 commit 980808d
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 9 deletions.
31 changes: 24 additions & 7 deletions flang/lib/Lower/OpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1934,6 +1934,27 @@ static void resetBeforeTerminator(fir::FirOpBuilder &firOpBuilder,
firOpBuilder.setInsertionPointToStart(&block);
}

static mlir::Operation *
createAndSetPrivatizedLoopVar(Fortran::lower::AbstractConverter &converter,
mlir::Location loc, mlir::Type loopVarType,
mlir::Value indexVal,
const Fortran::semantics::Symbol *sym) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
mlir::OpBuilder::InsertPoint insPt = firOpBuilder.saveInsertionPoint();
firOpBuilder.setInsertionPointToStart(firOpBuilder.getAllocaBlock());

mlir::Value temp = firOpBuilder.create<fir::AllocaOp>(
loc, loopVarType, /*pinned=*/true, /*lengthParams=*/mlir::ValueRange{},
/*shapeParams*/ mlir::ValueRange{},
llvm::ArrayRef<mlir::NamedAttribute>{
Fortran::lower::getAdaptToByRefAttr(firOpBuilder)});
converter.bindSymbol(*sym, temp);
firOpBuilder.restoreInsertionPoint(insPt);
mlir::Operation *storeOp = firOpBuilder.create<fir::StoreOp>(
loc, indexVal, converter.getSymbolAddress(*sym));
return storeOp;
}

/// Create the body (block) for an OpenMP Operation.
///
/// \param [in] op - the operation the body belongs to.
Expand Down Expand Up @@ -1974,14 +1995,10 @@ static void createBodyOfOp(
// The argument is not currently in memory, so make a temporary for the
// argument, and store it there, then bind that location to the argument.
for (const Fortran::semantics::Symbol *arg : args) {
mlir::Value val =
mlir::Value indexVal =
fir::getBase(op.getRegion().front().getArgument(argIndex));
mlir::Value temp = firOpBuilder.createTemporary(
loc, loopVarType,
llvm::ArrayRef<mlir::NamedAttribute>{
Fortran::lower::getAdaptToByRefAttr(firOpBuilder)});
storeOp = firOpBuilder.create<fir::StoreOp>(loc, val, temp);
converter.bindSymbol(*arg, temp);
storeOp = createAndSetPrivatizedLoopVar(converter, loc, loopVarType,
indexVal, arg);
argIndex++;
}
} else {
Expand Down
27 changes: 27 additions & 0 deletions flang/test/Lower/OpenMP/hlfir-wsloop.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
! This test checks lowering of OpenMP DO Directive with HLFIR.

! RUN: bbc -hlfir -fopenmp -emit-fir %s -o - | FileCheck %s
! RUN: %flang_fc1 -emit-fir -flang-experimental-hlfir -fopenmp %s -o - | FileCheck %s

!CHECK-LABEL: func @_QPsimple_loop()
subroutine simple_loop
integer :: i
! CHECK-DAG: %[[WS_ST:.*]] = arith.constant 1 : i32
! CHECK-DAG: %[[WS_END:.*]] = arith.constant 9 : i32
! CHECK: omp.parallel
!$OMP PARALLEL
! CHECK-DAG: %[[ALLOCA_IV:.*]] = fir.alloca i32 {{{.*}}, pinned}
! CHECK: %[[IV:.*]] = fir.declare %[[ALLOCA_IV]] {uniq_name = "_QFsimple_loopEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
! CHECK: omp.wsloop for (%[[I:.*]]) : i32 = (%[[WS_ST]]) to (%[[WS_END]]) inclusive step (%[[WS_ST]])
!$OMP DO
do i=1, 9
! CHECK: fir.store %[[I]] to %[[IV:.*]] : !fir.ref<i32>
! CHECK: %[[LOAD_IV:.*]] = fir.load %[[IV]] : !fir.ref<i32>
! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LOAD_IV]]) {{.*}}: (!fir.ref<i8>, i32) -> i1
print*, i
end do
! CHECK: omp.yield
!$OMP END DO
! CHECK: omp.terminator
!$OMP END PARALLEL
end subroutine
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/lastprivate-commonblock.f90
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
! RUN: %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s

!CHECK: func.func @_QPlastprivate_common() {
!CHECK: %[[val_0:.*]] = fir.alloca i32 {adapt.valuebyref}
!CHECK: %[[val_0:.*]] = fir.alloca i32 {adapt.valuebyref, pinned}
!CHECK: %[[val_1:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFlastprivate_commonEi"}
!CHECK: %[[val_2:.*]] = fir.address_of(@_QCc) : !fir.ref<!fir.array<8xi8>>
!CHECK: %[[val_3:.*]] = fir.convert %[[val_2]] : (!fir.ref<!fir.array<8xi8>>) -> !fir.ref<!fir.array<?xi8>>
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/stop-stmt-in-region.f90
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ subroutine test_stop_in_region3()
end

! CHECK-LABEL: func.func @_QPtest_stop_in_region4() {
! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {adapt.valuebyref}
! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {adapt.valuebyref, pinned}
! CHECK: %[[VAL_1:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_stop_in_region4Ei"}
! CHECK: %[[VAL_2:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFtest_stop_in_region4Ex"}
! CHECK: %[[VAL_3:.*]] = arith.constant 1 : i32
Expand Down

0 comments on commit 980808d

Please sign in to comment.