[flang-commits] [flang] [flang][OpenMP] Improve reduction of Scalar ArrayElement types (PR #163940)

Krzysztof Parzyszek via flang-commits flang-commits at lists.llvm.org
Mon Oct 20 06:09:02 PDT 2025


================
@@ -492,10 +572,468 @@ void RewriteMutator::Post(parser::WriteStmt &x) {
   FixMisparsedUntaggedNamelistName(x);
 }
 
+void ReplacementTemp::createTempSymbol(
+    SourceName &source, Scope &scope, SemanticsContext &context) {
+  replacementTempSymbol_ =
+      const_cast<Scope &>(originalName_.symbol->owner()).FindSymbol(source);
+  replacementTempSymbol_->set_scope(
+      &const_cast<Scope &>(originalName_.symbol->owner()));
+  DeclTypeSpec *tempType = originalName_.symbol->GetUltimate().GetType();
+  replacementTempSymbol_->get<ObjectEntityDetails>().set_type(*tempType);
+  replacementTempSymbol_->flags().set(Symbol::Flag::CompilerCreated);
+}
+
+void ReplacementTemp::setOriginalSubscriptInt(
+    std::list<parser::SectionSubscript> &sectionSubscript) {
+  bool setSubscript{false};
+  auto visitLiteralConstant = [&](parser::LiteralConstant &literalConstant) {
+    std::visit(llvm::makeVisitor(
+                   [&](parser::IntLiteralConstant &intLiteralConstant) {
+                     originalSubscriptCharBlock_ =
+                         std::get<parser::CharBlock>(intLiteralConstant.t);
+                     setSubscript = true;
+                   },
+                   [&](auto &) {}),
+        literalConstant.u);
+  };
+  auto visitIntExpr = [&](parser::IntExpr &intExpr) {
+    parser::Expr &expr = intExpr.thing.value();
+    std::visit(llvm::makeVisitor(
+                   [&](parser::LiteralConstant &literalConstant) {
+                     visitLiteralConstant(literalConstant);
+                   },
+                   [&](auto &) {}),
+        expr.u);
+  };
+  for (parser::SectionSubscript &subscript : sectionSubscript) {
+    std::visit(llvm::makeVisitor(
+                   [&](parser::IntExpr &intExpr) { visitIntExpr(intExpr); },
+                   [&](parser::SubscriptTriplet &triplet) {
+                     isSectionTriplet_ = true;
+                     setSubscript = true;
+                   },
+                   [&](auto &) {}),
+        subscript.u);
+    if (setSubscript) {
+      break;
+    }
+  }
+}
+
+void RewriteOmpReductionArrayElements::rewriteReductionArrayElementToTemp(
+    parser::Block &block) {
+  if (block.empty()) {
+    return;
+  }
+
+  auto visitOpenMPLoopConstruct = [&](parser::OpenMPLoopConstruct &ompLoop,
+                                      parser::Block::iterator &it) {
+    ReplacementTemp temp;
+    if (!rewriteArrayElementToTemp(it, ompLoop, block, temp)) {
+      return;
+    }
+    auto &NestedConstruct =
+        std::get<std::optional<parser::NestedConstruct>>(ompLoop.t);
+    if (!NestedConstruct.has_value()) {
+      return;
+    }
+    if (parser::DoConstruct *
+        doConst{std::get_if<parser::DoConstruct>(&NestedConstruct.value())}) {
+      block_ = █
+      parser::Block &doBlock{std::get<parser::Block>(doConst->t)};
+      parser::Walk(doBlock, *this);
+      // Reset the current temp value so future
+      // iterations use their own version.
+      resetCurrentTemp();
+    }
+  };
+  auto visitOpenMPConstruct = [&](parser::OpenMPConstruct &ompConstruct,
+                                  parser::Block::iterator &it) {
+    std::visit(llvm::makeVisitor(
+                   [&](parser::OpenMPLoopConstruct &ompLoop) {
+                     visitOpenMPLoopConstruct(ompLoop, it);
+                   },
+                   [&](auto &) {}),
+        ompConstruct.u);
+  };
+  auto visitExecutableConstruct = [&](parser::ExecutableConstruct
+                                          &execConstruct,
+                                      parser::Block::iterator &it) {
+    std::visit(
+        llvm::makeVisitor(
+            [&](common::Indirection<parser::OpenMPConstruct> &ompConstruct) {
+              visitOpenMPConstruct(ompConstruct.value(), it);
+            },
+            [&](auto &) {}),
+        execConstruct.u);
+  };
+  for (auto it{block.begin()}; it != block.end(); ++it) {
+    std::visit(llvm::makeVisitor(
+                   [&](parser::ExecutableConstruct &execConstruct) {
+                     visitExecutableConstruct(execConstruct, it);
+                   },
+                   [&](auto &) {}),
+        it->u);
+  }
+}
+
+bool RewriteOmpReductionArrayElements::isMatchingArrayElement(
+    parser::Designator &existingDesignator) {
+  bool matchesArrayElement{false};
+  std::list<parser::SectionSubscript> *subscripts{nullptr};
+
+  auto visitName = [&](parser::Name &name, parser::ArrayElement &arrayElement) {
+    if (name.symbol->GetUltimate() ==
+        currentTemp_->getOriginalName().symbol->GetUltimate()) {
+      matchesArrayElement = true;
+      if (!currentTemp_->isArrayElementReassigned()) {
+        reassignTempValueToArrayElement(arrayElement);
+      }
+    }
+  };
+  auto visitArratElement = [&](parser::ArrayElement &arrayElement) {
----------------
kparzysz wrote:

Typo: arrat

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


More information about the flang-commits mailing list