- 
                Notifications
    
You must be signed in to change notification settings  - Fork 15.1k
 
          [flang] Extend localization support for do concurrent (init regions)
          #142564
        
          New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| 
          
 @llvm/pr-subscribers-flang-fir-hlfir Author: Kareem Ergawy (ergawy) ChangesExtends support for locality specifiers in  This further unifies the paths taken by the compiler for OpenMP privatization clauses and  Patch is 58.62 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/142564.diff 11 Files Affected: 
 diff --git a/flang/lib/Lower/OpenMP/PrivateReductionUtils.h b/flang/include/flang/Lower/Support/PrivateReductionUtils.h
similarity index 90%
rename from flang/lib/Lower/OpenMP/PrivateReductionUtils.h
rename to flang/include/flang/Lower/Support/PrivateReductionUtils.h
index 9f8c9aee4d8ec..5e7f4e11d5a53 100644
--- a/flang/lib/Lower/OpenMP/PrivateReductionUtils.h
+++ b/flang/include/flang/Lower/Support/PrivateReductionUtils.h
@@ -37,10 +37,14 @@ class AbstractConverter;
 
 namespace omp {
 
-enum class DeclOperationKind { Private, FirstPrivate, Reduction };
+enum class DeclOperationKind {
+  PrivateOrLocal,
+  FirstPrivateOrLocalInit,
+  Reduction
+};
 inline bool isPrivatization(DeclOperationKind kind) {
-  return (kind == DeclOperationKind::FirstPrivate) ||
-         (kind == DeclOperationKind::Private);
+  return (kind == DeclOperationKind::FirstPrivateOrLocalInit) ||
+         (kind == DeclOperationKind::PrivateOrLocal);
 }
 inline bool isReduction(DeclOperationKind kind) {
   return kind == DeclOperationKind::Reduction;
@@ -56,7 +60,7 @@ void populateByRefInitAndCleanupRegions(
     mlir::Value allocatedPrivVarArg, mlir::Value moldArg,
     mlir::Region &cleanupRegion, DeclOperationKind kind,
     const Fortran::semantics::Symbol *sym = nullptr,
-    bool cannotHaveNonDefaultLowerBounds = false);
+    bool cannotHaveNonDefaultLowerBounds = false, bool isDoConcurrent = false);
 
 /// Generate a fir::ShapeShift op describing the provided boxed array.
 /// `cannotHaveNonDefaultLowerBounds` should be set if `box` is known to have
diff --git a/flang/include/flang/Lower/Support/Utils.h b/flang/include/flang/Lower/Support/Utils.h
index 8ad3a903beee9..e544542e2ff71 100644
--- a/flang/include/flang/Lower/Support/Utils.h
+++ b/flang/include/flang/Lower/Support/Utils.h
@@ -20,6 +20,7 @@
 #include "mlir/Dialect/Arith/IR/Arith.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
 #include "mlir/IR/BuiltinAttributes.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringRef.h"
 
 namespace Fortran::lower {
@@ -98,8 +99,9 @@ bool isEqual(const Fortran::lower::ExplicitIterSpace::ArrayBases &x,
 template <typename OpType, typename OperandsStructType>
 void privatizeSymbol(
     lower::AbstractConverter &converter, fir::FirOpBuilder &firOpBuilder,
-    lower::SymMap &symTable, std::function<void(OpType, mlir::Type)> initGen,
+    lower::SymMap &symTable,
     llvm::SetVector<const semantics::Symbol *> &allPrivatizedSymbols,
+    llvm::SmallSet<const semantics::Symbol *, 16> &mightHaveReadHostSym,
     const semantics::Symbol *symToPrivatize, OperandsStructType *clauseOps);
 
 } // end namespace Fortran::lower
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 4e6db3eaa990d..2ea838673dd21 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -12,7 +12,6 @@
 
 #include "flang/Lower/Bridge.h"
 
-#include "OpenMP/DataSharingProcessor.h"
 #include "flang/Lower/Allocatable.h"
 #include "flang/Lower/CallInterface.h"
 #include "flang/Lower/Coarray.h"
@@ -2038,44 +2037,38 @@ class FirConverter : public Fortran::lower::AbstractConverter {
     bool useDelayedPriv =
         enableDelayedPrivatizationStaging && doConcurrentLoopOp;
     llvm::SetVector<const Fortran::semantics::Symbol *> allPrivatizedSymbols;
+    llvm::SmallSet<const Fortran::semantics::Symbol *, 16> mightHaveReadHostSym;
 
-    for (const Fortran::semantics::Symbol *sym : info.localSymList) {
+    for (const Fortran::semantics::Symbol *symToPrivatize : info.localSymList) {
       if (useDelayedPriv) {
         Fortran::lower::privatizeSymbol<fir::LocalitySpecifierOp>(
-            *this, this->getFirOpBuilder(), localSymbols,
-            [this](fir::LocalitySpecifierOp result, mlir::Type argType) {
-              TODO(this->toLocation(),
-                   "Localizers that need init regions are not supported yet.");
-            },
-            allPrivatizedSymbols, sym, &privateClauseOps);
+            *this, this->getFirOpBuilder(), localSymbols, allPrivatizedSymbols,
+            mightHaveReadHostSym, symToPrivatize, &privateClauseOps);
         continue;
       }
 
-      createHostAssociateVarClone(*sym, /*skipDefaultInit=*/false);
+      createHostAssociateVarClone(*symToPrivatize, /*skipDefaultInit=*/false);
     }
 
-    for (const Fortran::semantics::Symbol *sym : info.localInitSymList) {
+    for (const Fortran::semantics::Symbol *symToPrivatize :
+         info.localInitSymList) {
       if (useDelayedPriv) {
         Fortran::lower::privatizeSymbol<fir::LocalitySpecifierOp>(
-            *this, this->getFirOpBuilder(), localSymbols,
-            [this](fir::LocalitySpecifierOp result, mlir::Type argType) {
-              TODO(this->toLocation(),
-                   "Localizers that need init regions are not supported yet.");
-            },
-            allPrivatizedSymbols, sym, &privateClauseOps);
+            *this, this->getFirOpBuilder(), localSymbols, allPrivatizedSymbols,
+            mightHaveReadHostSym, symToPrivatize, &privateClauseOps);
         continue;
       }
 
-      createHostAssociateVarClone(*sym, /*skipDefaultInit=*/true);
+      createHostAssociateVarClone(*symToPrivatize, /*skipDefaultInit=*/true);
       const auto *hostDetails =
-          sym->detailsIf<Fortran::semantics::HostAssocDetails>();
+          symToPrivatize->detailsIf<Fortran::semantics::HostAssocDetails>();
       assert(hostDetails && "missing locality spec host symbol");
       const Fortran::semantics::Symbol *hostSym = &hostDetails->symbol();
       Fortran::evaluate::ExpressionAnalyzer ea{semanticsContext};
       Fortran::evaluate::Assignment assign{
-          ea.Designate(Fortran::evaluate::DataRef{*sym}).value(),
+          ea.Designate(Fortran::evaluate::DataRef{*symToPrivatize}).value(),
           ea.Designate(Fortran::evaluate::DataRef{*hostSym}).value()};
-      if (Fortran::semantics::IsPointer(*sym))
+      if (Fortran::semantics::IsPointer(*symToPrivatize))
         assign.u = Fortran::evaluate::Assignment::BoundsSpec{};
       genAssignment(assign);
     }
diff --git a/flang/lib/Lower/CMakeLists.txt b/flang/lib/Lower/CMakeLists.txt
index bc817ff8f1f3e..9c5db2b126510 100644
--- a/flang/lib/Lower/CMakeLists.txt
+++ b/flang/lib/Lower/CMakeLists.txt
@@ -28,11 +28,11 @@ add_flang_library(FortranLower
   OpenMP/DataSharingProcessor.cpp
   OpenMP/Decomposer.cpp
   OpenMP/OpenMP.cpp
-  OpenMP/PrivateReductionUtils.cpp
   OpenMP/ReductionProcessor.cpp
   OpenMP/Utils.cpp
   PFTBuilder.cpp
   Runtime.cpp
+  Support/PrivateReductionUtils.cpp
   Support/Utils.cpp
   SymbolMap.cpp
   VectorSubscripts.cpp
diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
index 03109c82a976a..8b334d7a392ac 100644
--- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
@@ -12,10 +12,10 @@
 
 #include "DataSharingProcessor.h"
 
-#include "PrivateReductionUtils.h"
 #include "Utils.h"
 #include "flang/Lower/ConvertVariable.h"
 #include "flang/Lower/PFTBuilder.h"
+#include "flang/Lower/Support/PrivateReductionUtils.h"
 #include "flang/Lower/Support/Utils.h"
 #include "flang/Lower/SymbolMap.h"
 #include "flang/Optimizer/Builder/BoxValue.h"
@@ -537,38 +537,10 @@ void DataSharingProcessor::privatizeSymbol(
     return;
   }
 
-  auto initGen = [&](mlir::omp::PrivateClauseOp result, mlir::Type argType) {
-    lower::SymbolBox hsb = converter.lookupOneLevelUpSymbol(*symToPrivatize);
-    assert(hsb && "Host symbol box not found");
-    hlfir::Entity entity{hsb.getAddr()};
-    bool cannotHaveNonDefaultLowerBounds =
-        !entity.mayHaveNonDefaultLowerBounds();
-
-    mlir::Region &initRegion = result.getInitRegion();
-    mlir::Location symLoc = hsb.getAddr().getLoc();
-    mlir::Block *initBlock = firOpBuilder.createBlock(
-        &initRegion, /*insertPt=*/{}, {argType, argType}, {symLoc, symLoc});
-
-    bool emitCopyRegion =
-        symToPrivatize->test(semantics::Symbol::Flag::OmpFirstPrivate);
-
-    populateByRefInitAndCleanupRegions(
-        converter, symLoc, argType, /*scalarInitValue=*/nullptr, initBlock,
-        result.getInitPrivateArg(), result.getInitMoldArg(),
-        result.getDeallocRegion(),
-        emitCopyRegion ? omp::DeclOperationKind::FirstPrivate
-                       : omp::DeclOperationKind::Private,
-        symToPrivatize, cannotHaveNonDefaultLowerBounds);
-    // TODO: currently there are false positives from dead uses of the mold
-    // arg
-    if (result.initReadsFromMold())
-      mightHaveReadHostSym.insert(symToPrivatize);
-  };
-
   Fortran::lower::privatizeSymbol<mlir::omp::PrivateClauseOp,
                                   mlir::omp::PrivateClauseOps>(
-      converter, firOpBuilder, symTable, initGen, allPrivatizedSymbols,
-      symToPrivatize, clauseOps);
+      converter, firOpBuilder, symTable, allPrivatizedSymbols,
+      mightHaveReadHostSym, symToPrivatize, clauseOps);
 }
 } // namespace omp
 } // namespace lower
diff --git a/flang/lib/Lower/OpenMP/PrivateReductionUtils.cpp b/flang/lib/Lower/OpenMP/PrivateReductionUtils.cpp
index 268c7828ab56f..ea1c78fb0320e 100644
--- a/flang/lib/Lower/OpenMP/PrivateReductionUtils.cpp
+++ b/flang/lib/Lower/OpenMP/PrivateReductionUtils.cpp
@@ -10,8 +10,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "PrivateReductionUtils.h"
-
+#include "flang/Lower/Support/PrivateReductionUtils.h"
 #include "flang/Lower/AbstractConverter.h"
 #include "flang/Lower/Allocatable.h"
 #include "flang/Lower/ConvertVariable.h"
@@ -42,7 +41,8 @@ static bool hasFinalization(const Fortran::semantics::Symbol &sym) {
 static void createCleanupRegion(Fortran::lower::AbstractConverter &converter,
                                 mlir::Location loc, mlir::Type argType,
                                 mlir::Region &cleanupRegion,
-                                const Fortran::semantics::Symbol *sym) {
+                                const Fortran::semantics::Symbol *sym,
+                                bool isDoConcurrent) {
   fir::FirOpBuilder &builder = converter.getFirOpBuilder();
   assert(cleanupRegion.empty());
   mlir::Block *block = builder.createBlock(&cleanupRegion, cleanupRegion.end(),
@@ -72,7 +72,10 @@ static void createCleanupRegion(Fortran::lower::AbstractConverter &converter,
         fir::MutableBoxValue mutableBox{converted, /*lenParameters=*/{},
                                         /*mutableProperties=*/{}};
         Fortran::lower::genDeallocateIfAllocated(converter, mutableBox, loc);
-        builder.create<mlir::omp::YieldOp>(loc);
+        if (isDoConcurrent)
+          builder.create<fir::YieldOp>(loc);
+        else
+          builder.create<mlir::omp::YieldOp>(loc);
         return;
       }
     }
@@ -100,7 +103,10 @@ static void createCleanupRegion(Fortran::lower::AbstractConverter &converter,
     builder.create<fir::FreeMemOp>(loc, cast);
 
     builder.setInsertionPointAfter(ifOp);
-    builder.create<mlir::omp::YieldOp>(loc);
+    if (isDoConcurrent)
+      builder.create<fir::YieldOp>(loc);
+    else
+      builder.create<mlir::omp::YieldOp>(loc);
     return;
   }
 
@@ -115,7 +121,11 @@ static void createCleanupRegion(Fortran::lower::AbstractConverter &converter,
     addr = builder.createConvert(loc, heapTy, addr);
 
     builder.create<fir::FreeMemOp>(loc, addr);
-    builder.create<mlir::omp::YieldOp>(loc);
+    if (isDoConcurrent)
+      builder.create<fir::YieldOp>(loc);
+    else
+      builder.create<mlir::omp::YieldOp>(loc);
+
     return;
   }
 
@@ -273,12 +283,13 @@ class PopulateInitAndCleanupRegionsHelper {
       mlir::Value allocatedPrivVarArg, mlir::Value moldArg,
       mlir::Block *initBlock, mlir::Region &cleanupRegion,
       DeclOperationKind kind, const Fortran::semantics::Symbol *sym,
-      bool cannotHaveLowerBounds)
+      bool cannotHaveLowerBounds, bool isDoConcurrent)
       : converter{converter}, builder{converter.getFirOpBuilder()}, loc{loc},
         argType{argType}, scalarInitValue{scalarInitValue},
         allocatedPrivVarArg{allocatedPrivVarArg}, moldArg{moldArg},
         initBlock{initBlock}, cleanupRegion{cleanupRegion}, kind{kind},
-        sym{sym}, cannotHaveNonDefaultLowerBounds{cannotHaveLowerBounds} {
+        sym{sym}, cannotHaveNonDefaultLowerBounds{cannotHaveLowerBounds},
+        isDoConcurrent{isDoConcurrent} {
     valType = fir::unwrapRefType(argType);
   }
 
@@ -324,8 +335,13 @@ class PopulateInitAndCleanupRegionsHelper {
   /// lower bounds then we don't need to generate code to read them.
   bool cannotHaveNonDefaultLowerBounds;
 
+  bool isDoConcurrent;
+
   void createYield(mlir::Value ret) {
-    builder.create<mlir::omp::YieldOp>(loc, ret);
+    if (isDoConcurrent)
+      builder.create<fir::YieldOp>(loc, ret);
+    else
+      builder.create<mlir::omp::YieldOp>(loc, ret);
   }
 
   void initTrivialType() {
@@ -429,11 +445,12 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedScalar(
       /*slice=*/mlir::Value{}, lenParams);
   initializeIfDerivedTypeBox(
       builder, loc, box, getLoadedMoldArg(), needsInitialization,
-      /*isFirstPrivate=*/kind == DeclOperationKind::FirstPrivate);
+      /*isFirstPrivate=*/kind == DeclOperationKind::FirstPrivateOrLocalInit);
   fir::StoreOp lastOp =
       builder.create<fir::StoreOp>(loc, box, allocatedPrivVarArg);
 
-  createCleanupRegion(converter, loc, argType, cleanupRegion, sym);
+  createCleanupRegion(converter, loc, argType, cleanupRegion, sym,
+                      isDoConcurrent);
 
   if (ifUnallocated)
     builder.setInsertionPointAfter(ifUnallocated);
@@ -470,13 +487,14 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedArray(
                                                         allocatedArray, shape);
     initializeIfDerivedTypeBox(
         builder, loc, firClass, source, needsInitialization,
-        /*isFirstprivate=*/kind == DeclOperationKind::FirstPrivate);
+        /*isFirstprivate=*/kind == DeclOperationKind::FirstPrivateOrLocalInit);
     builder.create<fir::StoreOp>(loc, firClass, allocatedPrivVarArg);
     if (ifUnallocated)
       builder.setInsertionPointAfter(ifUnallocated);
     createYield(allocatedPrivVarArg);
     mlir::OpBuilder::InsertionGuard guard(builder);
-    createCleanupRegion(converter, loc, argType, cleanupRegion, sym);
+    createCleanupRegion(converter, loc, argType, cleanupRegion, sym,
+                        isDoConcurrent);
     return;
   }
 
@@ -492,7 +510,8 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedArray(
          "createTempFromMold decides this statically");
   if (cstNeedsDealloc.has_value() && *cstNeedsDealloc != false) {
     mlir::OpBuilder::InsertionGuard guard(builder);
-    createCleanupRegion(converter, loc, argType, cleanupRegion, sym);
+    createCleanupRegion(converter, loc, argType, cleanupRegion, sym,
+                        isDoConcurrent);
   } else {
     assert(!isAllocatableOrPointer &&
            "Pointer-like arrays must be heap allocated");
@@ -520,7 +539,7 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedArray(
 
   initializeIfDerivedTypeBox(
       builder, loc, box, getLoadedMoldArg(), needsInitialization,
-      /*isFirstPrivate=*/kind == DeclOperationKind::FirstPrivate);
+      /*isFirstPrivate=*/kind == DeclOperationKind::FirstPrivateOrLocalInit);
 
   builder.create<fir::StoreOp>(loc, box, allocatedPrivVarArg);
   if (ifUnallocated)
@@ -548,7 +567,8 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxchar(
       loc, eleTy, /*name=*/{}, /*shape=*/{}, /*lenParams=*/len);
   mlir::Value boxChar = charExprHelper.createEmboxChar(privateAddr, len);
 
-  createCleanupRegion(converter, loc, argType, cleanupRegion, sym);
+  createCleanupRegion(converter, loc, argType, cleanupRegion, sym,
+                      isDoConcurrent);
 
   builder.setInsertionPointToEnd(initBlock);
   createYield(boxChar);
@@ -563,10 +583,11 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupUnboxedDerivedType(
   mlir::Value moldBox = builder.create<fir::EmboxOp>(loc, boxedTy, moldArg);
   initializeIfDerivedTypeBox(builder, loc, newBox, moldBox, needsInitialization,
                              /*isFirstPrivate=*/kind ==
-                                 DeclOperationKind::FirstPrivate);
+                                 DeclOperationKind::FirstPrivateOrLocalInit);
 
   if (sym && hasFinalization(*sym))
-    createCleanupRegion(converter, loc, argType, cleanupRegion, sym);
+    createCleanupRegion(converter, loc, argType, cleanupRegion, sym,
+                        isDoConcurrent);
 
   builder.setInsertionPointToEnd(initBlock);
   createYield(allocatedPrivVarArg);
@@ -637,10 +658,12 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
     mlir::Type argType, mlir::Value scalarInitValue, mlir::Block *initBlock,
     mlir::Value allocatedPrivVarArg, mlir::Value moldArg,
     mlir::Region &cleanupRegion, DeclOperationKind kind,
-    const Fortran::semantics::Symbol *sym, bool cannotHaveLowerBounds) {
+    const Fortran::semantics::Symbol *sym, bool cannotHaveLowerBounds,
+    bool isDoConcurrent) {
   PopulateInitAndCleanupRegionsHelper helper(
       converter, loc, argType, scalarInitValue, allocatedPrivVarArg, moldArg,
-      initBlock, cleanupRegion, kind, sym, cannotHaveLowerBounds);
+      initBlock, cleanupRegion, kind, sym, cannotHaveLowerBounds,
+      isDoConcurrent);
   helper.populateByRefInitAndCleanupRegions();
 
   // Often we load moldArg to check something (e.g. length parameters, shape)
diff --git a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp
index 7ef0f2a0ef7c5..d7f520e86e532 100644
--- a/flang/lib/Lower/OpenMP/ReductionProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ReductionProcessor.cpp
@@ -12,9 +12,9 @@
 
 #include "ReductionProcessor.h"
 
-#include "PrivateReductionUtils.h"
 #include "flang/Lower/AbstractConverter.h"
 #include "flang/Lower/ConvertType.h"
+#include "flang/Lower/Support/PrivateReductionUtils.h"
 #include "flang/Lower/SymbolMap.h"
 #include "flang/Optimizer/Builder/Complex.h"
 #include "flang/Optimizer/Builder/HLFIRTools.h"
diff --git a/flang/lib/Lower/Support/PrivateReductionUtils.cpp b/flang/lib/Lower/Support/PrivateReductionUtils.cpp
new file mode 100644
index 0000000000000..3753b77d6327f
--- /dev/null
+++ b/flang/lib/Lower/Support/PrivateReductionUtils.cpp
@@ -0,0 +1,681 @@
+//===-- PrivateReductionUtils.cpp -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Lower/Support/PrivateReductionUtils.h"
+
+#include "flang/Lower/AbstractConverter.h"
+#include "flang/Lower/Allocatable.h"
+#include "flang/Lower/ConvertVariable.h"
+#include "flang/Optimizer/Builder/BoxValue.h"
+#include "flang/Optimizer/Builder/Character.h"
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/HLFIRTools.h"
+#include "flang/Optimizer/Builder/Runtime/Derived.h"
+#include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
+#include "flang/Optimizer/HLFIR/HLFIROps.h"
+#include "flang/Optimizer/Support/FatalError.h"
+#include "flang/Semantics/symbol.h"
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/IR/Location.h"
+
+static bool hasFinalization(const Fortran::semantics::Symbol &sym) {
+  if (sym.has<Fortran::semantics::ObjectEntityDetails>())
+    if (const Fortran::semantics::DeclTypeSpec *declTypeSpec = sym.GetType())
+      if (const Fortran::semantics::DerivedTypeSpec *derivedTypeSpec =
+              declTypeSpec->AsDerived())
+        return Fortran::semantics::IsFinalizable(*derivedTypeSpec);
+  return false;
+}
+
+static void createCleanupRegion(Fortran::lower::AbstractConverter &converter,
+                                mlir::Location loc, mlir::Type argType,
+                                mlir::Region &cl...
[truncated]
 | 
    
39a1fcb    to
    8f5a70a      
    Compare
  
    There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but it's better to wait for the approval of another reviewer, since I've not been following do concurrent patches closely.
8f5a70a    to
    8c8d15a      
    Compare
  
    There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, thanks!
8c8d15a    to
    1632048      
    Compare
  
    Extends support for locality specifiers in `do concurrent` by supporting data types that need `init` regions. This further unifies the paths taken by the compiler for OpenMP privatization clauses and `do concurrent` locality specifiers.
ba6ac8f    to
    148fdcf      
    Compare
  
    breaks 535.weather ref. timeout bac4aa4 - [flang] Extend localization support for `do concurrent` (`init` regions) (llvm#142564) (3 days ago) <Kareem Ergawy>
…ns) (llvm#142564) Extends support for locality specifiers in `do concurrent` by supporting data types that need `init` regions. This further unifies the paths taken by the compiler for OpenMP privatization clauses and `do concurrent` locality specifiers.
…rrent` (`init` regions) (llvm#3015)
Extends support for locality specifiers in
do concurrentby supporting data types that needinitregions.This further unifies the paths taken by the compiler for OpenMP privatization clauses and
do concurrentlocality specifiers.