[flang-commits] [flang] [flang][OpenMP] Enable delayed privatization for `omp parallel` by default (PR #90945)

Kareem Ergawy via flang-commits flang-commits at lists.llvm.org
Wed Jun 12 02:55:38 PDT 2024


ergawy wrote:

> Are these issues fixed by #92430?

Unfortunately not. So far I found 3 issues from Fujitsu tests.

#### Cloning `omp.private` without a parent module

This is what causes the sample test Leandro mentioned above. A fix for this would be:
```diff
@@ -1275,7 +1275,11 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
           // region. The privatizer is processed in-place (see below) before it
           // gets inlined in the parallel region and therefore processing the
           // original op is dangerous.
-          return {privVar, privatizer.clone()};
+
+          mlir::IRRewriter opCloner(&moduleTranslation.getContext());
+          opCloner.setInsertionPoint(privatizer);
+          return {privVar, llvm::cast<mlir::omp::PrivateClauseOp>(
+                               opCloner.clone(*privatizer))};
```

#### Properly mapping common blocks

This resulted in yet another test failing. This would be fixed by something like:
```diff
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 6b391e11beb4..41806f045f82 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1406,12 +1406,23 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
                       dsp.getAllSymbolsToPrivatize().end());
 
     for (auto [arg, prv] : llvm::zip_equal(allSymbols, region.getArguments())) {
-      converter.bindSymbol(*arg, hlfir::translateToExtendedValue(
-                                     loc, firOpBuilder, hlfir::Entity{prv},
-                                     /*contiguousHint=*/
-                                     evaluate::IsSimplyContiguous(
-                                         *arg, converter.getFoldingContext()))
-                                     .first);
+      mlir::BlockArgument blockArg = prv;
+      auto bind = [&](const semantics::Symbol *sym) {
+        converter.bindSymbol(*sym,
+                             hlfir::translateToExtendedValue(
+                                 loc, firOpBuilder, hlfir::Entity{blockArg},
+                                 /*contiguousHint=*/
+                                 evaluate::IsSimplyContiguous(
+                                     *sym, converter.getFoldingContext()))
+                                 .first);
+      };
+
+      if (const auto *commonDet =
+              arg->detailsIf<semantics::CommonBlockDetails>()) {
+        for (const auto &mem : commonDet->objects())
+          bind(&*mem);
+      } else
+        bind(arg);
     }
```

#### Properly handling common block when some of their items have `equivalence` with other variables

For example, input like this:
```fortran
subroutine private_common
  common /c/ x
  real x, y
  equivalence (x,y)
  !$omp parallel firstprivate(/c/)
    !x = 3.14
    !y = 2.71
  !$omp end parallel
end subroutine
```

Currently produces `omp.private` ops that fail verficiation because the yielded type is not consistent with the symbol type:
```mlir
  omp.private {type = firstprivate} @_QFprivate_commonEx_firstprivate_ptr_f32 : !fir.ptr<f32> alloc {
  ^bb0(%arg0: !fir.ptr<f32>):
    %0 = fir.alloca f32 {bindc_name = "x", pinned, uniq_name = "_QFprivate_commonEx"}
    %1:2 = hlfir.declare %0 {uniq_name = "_QFprivate_commonEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
    omp.yield(%1#0 : !fir.ref<f32>)
  } copy {
  ^bb0(%arg0: !fir.ptr<f32>, %arg1: !fir.ref<f32>):
    %0 = fir.load %arg0 : !fir.ptr<f32>
    hlfir.assign %0 to %arg1 temporary_lhs : f32, !fir.ref<f32>
    omp.yield(%arg1 : !fir.ref<f32>)
  }
```

Still working on a proper fix for this.

https://github.com/llvm/llvm-project/pull/90945


More information about the flang-commits mailing list