[flang-commits] [flang] [flang] Move reduction name mangling code to Semantics/tools (PR #232352)

Krzysztof Parzyszek via flang-commits flang-commits at lists.llvm.org
Thu Oct 15 07:48:16 PDT 2026


https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/232352

Gather all the mangling/demangling code in one place.

Also remove MangledIntrinsicOperatorReductionName that was only there
to expose MakeNameFromOperator, whose declaration was not in include/.

One remaining issue is emitting a diagnostic specific to DECLARE
REDUCTION in MakeNameFromOperator.

---

<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>

>From 04535b8c80832266a845d965bedf4e877f8a0b19 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 15 Oct 2026 07:27:44 -0500
Subject: [PATCH] [flang] Move reduction name mangling code to Semantics/tools

Gather all the mangling/demangling code in one place.

Also remove MangledIntrinsicOperatorReductionName that was only there
to expose MakeNameFromOperator, whose declaration was not in include/.

One remaining issue is emitting a diagnostic specific to DECLARE
REDUCTION in MakeNameFromOperator.
---
 .../flang/Lower/Support/ReductionProcessor.h  |  7 +-
 flang/include/flang/Semantics/openmp-utils.h  |  7 --
 flang/include/flang/Semantics/tools.h         | 12 +++
 flang/lib/Lower/OpenMP/OpenMP.cpp             |  4 +-
 .../lib/Lower/Support/ReductionProcessor.cpp  |  5 +-
 flang/lib/Semantics/openmp-utils.cpp          |  5 --
 flang/lib/Semantics/resolve-names-utils.cpp   | 34 ---------
 flang/lib/Semantics/resolve-names-utils.h     | 12 ---
 flang/lib/Semantics/resolve-names.cpp         | 42 -----------
 flang/lib/Semantics/tools.cpp                 | 75 +++++++++++++++++++
 10 files changed, 94 insertions(+), 109 deletions(-)

diff --git a/flang/include/flang/Lower/Support/ReductionProcessor.h b/flang/include/flang/Lower/Support/ReductionProcessor.h
index bc6e86a7296042..b78583b2a229de 100644
--- a/flang/include/flang/Lower/Support/ReductionProcessor.h
+++ b/flang/include/flang/Lower/Support/ReductionProcessor.h
@@ -81,10 +81,9 @@ class ReductionProcessor {
   getReductionType(omp::clause::DefinedOperator::IntrinsicOperator intrinsicOp);
 
   /// Map a clause-level intrinsic operator to the parser-level one, so callers
-  /// can build the operator's mangled reduction name
-  /// (MangledIntrinsicOperatorReductionName) that semantics stores a
-  /// user-defined intrinsic-operator reduction under. Only the operators a user
-  /// reduction may use are handled.
+  /// can build the operator's mangled reduction name (MakeNameFromOperator)
+  /// that semantics stores a user-defined intrinsic-operator reduction under.
+  /// Only the operators a user reduction may use are handled.
   static parser::DefinedOperator::IntrinsicOperator
   toParserIntrinsicOperator(omp::clause::DefinedOperator::IntrinsicOperator op);
 
diff --git a/flang/include/flang/Semantics/openmp-utils.h b/flang/include/flang/Semantics/openmp-utils.h
index c31459f256f622..f5708b9a76600e 100644
--- a/flang/include/flang/Semantics/openmp-utils.h
+++ b/flang/include/flang/Semantics/openmp-utils.h
@@ -145,13 +145,6 @@ const Symbol *FindUserReductionSymbol(const Scope &scope,
 const Symbol *FindOperatorUserReductionSymbol(const Scope &scope,
     const Symbol &operatorSym, const DeclTypeSpec *type = nullptr);
 
-// Mangled reduction name ("op.+", "op.*", "op.AND", ...) that semantics stores
-// an intrinsic-operator user reduction under, produced by the same
-// MakeNameFromOperator the reduction-declaration semantics use so a clause-side
-// lookup matches byte-for-byte.
-parser::CharBlock MangledIntrinsicOperatorReductionName(
-    parser::DefinedOperator::IntrinsicOperator op, SemanticsContext &context);
-
 bool IsMapEnteringType(parser::OmpMapType::Value type);
 bool IsMapExitingType(parser::OmpMapType::Value type);
 
diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h
index d91a7d11a38c94..bd2cb0780de9bd 100644
--- a/flang/include/flang/Semantics/tools.h
+++ b/flang/include/flang/Semantics/tools.h
@@ -790,5 +790,17 @@ bool HadUseError(SemanticsContext &, SourceName at, const Symbol *);
 
 bool AreSameModuleSymbol(const Symbol &, const Symbol &);
 
+parser::CharBlock MakeNameFromOperator(
+    const parser::DefinedOperator::IntrinsicOperator &op,
+    SemanticsContext &context);
+parser::CharBlock MangleSpecialFunctions(parser::CharBlock name);
+std::string MangleDefinedOperator(parser::CharBlock name);
+
+// Map a mangled declare reduction name (e.g., "op.+", "op.combine.",
+// "op.max") back to the Fortran identifier used as the scope key for the
+// corresponding operator or procedure (e.g., "operator(+)", ".combine.",
+// "max"). Non-mangled names (procedure designators) are returned as-is.
+std::string GetReductionFortranId(parser::CharBlock mangledName);
+
 } // namespace Fortran::semantics
 #endif // FORTRAN_SEMANTICS_TOOLS_H_
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 57978826c5d014..7aa11e3bc776ad 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -6675,8 +6675,8 @@ static void genOpenMPDeclareReductionImpl(
                         // name the op identically.
                         const semantics::Symbol *redSymPtr = symOpt;
                         if (!redSymPtr) {
-                          parser::CharBlock mangledOpName = semantics::omp::
-                              MangledIntrinsicOperatorReductionName(
+                          parser::CharBlock mangledOpName =
+                              semantics::MakeNameFromOperator(
                                   ReductionProcessor::toParserIntrinsicOperator(
                                       intrOp),
                                   semaCtx);
diff --git a/flang/lib/Lower/Support/ReductionProcessor.cpp b/flang/lib/Lower/Support/ReductionProcessor.cpp
index ae483128fe7df7..55f24c937d8b5f 100644
--- a/flang/lib/Lower/Support/ReductionProcessor.cpp
+++ b/flang/lib/Lower/Support/ReductionProcessor.cpp
@@ -1205,9 +1205,8 @@ bool ReductionProcessor::processReductionArguments(
         if (semaCtx) {
           const semantics::DeclTypeSpec *opVarType =
               reductionSymbols[idx]->GetUltimate().GetType();
-          parser::CharBlock mangledOpName =
-              semantics::omp::MangledIntrinsicOperatorReductionName(
-                  toParserIntrinsicOperator(intrinsicOp), *semaCtx);
+          parser::CharBlock mangledOpName = semantics::MakeNameFromOperator(
+              toParserIntrinsicOperator(intrinsicOp), *semaCtx);
           if (const semantics::Symbol *userSym =
                   semantics::omp::FindUserReductionSymbol(
                       converter.getCurrentScope(), mangledOpName, opVarType)) {
diff --git a/flang/lib/Semantics/openmp-utils.cpp b/flang/lib/Semantics/openmp-utils.cpp
index 16c265ce39690d..893eb49ff90b0d 100644
--- a/flang/lib/Semantics/openmp-utils.cpp
+++ b/flang/lib/Semantics/openmp-utils.cpp
@@ -3218,9 +3218,4 @@ const Symbol *FindOperatorUserReductionSymbol(
   return FindUserReductionSymbol(
       scope, MangleDefinedOperator(operatorSym.name()), type);
 }
-
-parser::CharBlock MangledIntrinsicOperatorReductionName(
-    parser::DefinedOperator::IntrinsicOperator op, SemanticsContext &context) {
-  return MakeNameFromOperator(op, context);
-}
 } // namespace Fortran::semantics::omp
diff --git a/flang/lib/Semantics/resolve-names-utils.cpp b/flang/lib/Semantics/resolve-names-utils.cpp
index 6580c7e31abdb0..10a7940762e28e 100644
--- a/flang/lib/Semantics/resolve-names-utils.cpp
+++ b/flang/lib/Semantics/resolve-names-utils.cpp
@@ -1207,38 +1207,4 @@ void MapSubprogramToNewSymbols(const Symbol &oldSymbol, Symbol &newSymbol,
   newScope.InstantiateDerivedTypes();
 }
 
-std::string GetReductionFortranId(const parser::CharBlock &mangledName) {
-  llvm::StringRef name{mangledName.begin(), mangledName.size()};
-  if (!name.starts_with("op.")) {
-    return name.str();
-  }
-  llvm::StringRef suffix{name.drop_front(3)};
-  // Intrinsic arithmetic operators: op.+ -> operator(+)
-  if (suffix == "+" || suffix == "-" || suffix == "*") {
-    return ("operator(" + suffix + ")").str();
-  }
-  // Intrinsic logical operators (mangled uppercase, scope uses lowercase)
-  if (suffix == "AND") {
-    return "operator(.and.)";
-  }
-  if (suffix == "OR") {
-    return "operator(.or.)";
-  }
-  if (suffix == "EQV") {
-    return "operator(.eqv.)";
-  }
-  if (suffix == "NEQV") {
-    return "operator(.neqv.)";
-  }
-  // Defined operators: op.combine. -> .combine.
-  // MangleDefinedOperator prepends "op" to the operator name (e.g.,
-  // ".combine.") so after stripping "op.", the suffix ends with '.' for defined
-  // operators.
-  if (!suffix.empty() && suffix.back() == '.') {
-    return ("." + suffix).str();
-  }
-  // Named functions: op.max -> max
-  return suffix.str();
-}
-
 } // namespace Fortran::semantics
diff --git a/flang/lib/Semantics/resolve-names-utils.h b/flang/lib/Semantics/resolve-names-utils.h
index ae81feb1427eb6..6d1ee359feb8ff 100644
--- a/flang/lib/Semantics/resolve-names-utils.h
+++ b/flang/lib/Semantics/resolve-names-utils.h
@@ -150,17 +150,5 @@ struct SymbolAndTypeMappings;
 void MapSubprogramToNewSymbols(const Symbol &oldSymbol, Symbol &newSymbol,
     Scope &newScope, SymbolAndTypeMappings * = nullptr);
 
-parser::CharBlock MakeNameFromOperator(
-    const parser::DefinedOperator::IntrinsicOperator &op,
-    SemanticsContext &context);
-parser::CharBlock MangleSpecialFunctions(const parser::CharBlock &name);
-std::string MangleDefinedOperator(const parser::CharBlock &name);
-
-// Map a mangled declare reduction name (e.g., "op.+", "op.combine.",
-// "op.max") back to the Fortran identifier used as the scope key for the
-// corresponding operator or procedure (e.g., "operator(+)", ".combine.",
-// "max"). Non-mangled names (procedure designators) are returned as-is.
-std::string GetReductionFortranId(const parser::CharBlock &mangledName);
-
 } // namespace Fortran::semantics
 #endif // FORTRAN_SEMANTICS_RESOLVE_NAMES_H_
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index d0964294d10c03..f67f567578e906 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -44,7 +44,6 @@
 #include "flang/Support/default-kinds.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/raw_ostream.h"
 #include <list>
 #include <map>
@@ -2159,47 +2158,6 @@ void OmpVisitor::ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
   PopScope();
 }
 
-parser::CharBlock MakeNameFromOperator(
-    const parser::DefinedOperator::IntrinsicOperator &op,
-    SemanticsContext &context) {
-  switch (op) {
-  case parser::DefinedOperator::IntrinsicOperator::Multiply:
-    return parser::CharBlock{"op.*", 4};
-  case parser::DefinedOperator::IntrinsicOperator::Add:
-    return parser::CharBlock{"op.+", 4};
-  case parser::DefinedOperator::IntrinsicOperator::Subtract:
-    return parser::CharBlock{"op.-", 4};
-
-  case parser::DefinedOperator::IntrinsicOperator::AND:
-    return parser::CharBlock{"op.AND", 6};
-  case parser::DefinedOperator::IntrinsicOperator::OR:
-    return parser::CharBlock{"op.OR", 5};
-  case parser::DefinedOperator::IntrinsicOperator::EQV:
-    return parser::CharBlock{"op.EQV", 6};
-  case parser::DefinedOperator::IntrinsicOperator::NEQV:
-    return parser::CharBlock{"op.NEQV", 7};
-
-  default:
-    context.Say("Unsupported operator in DECLARE REDUCTION"_err_en_US);
-    return parser::CharBlock{"op.?", 4};
-  }
-}
-
-parser::CharBlock MangleSpecialFunctions(const parser::CharBlock &name) {
-  return llvm::StringSwitch<parser::CharBlock>(name.ToString())
-      .Case("max", {"op.max", 6})
-      .Case("min", {"op.min", 6})
-      .Case("iand", {"op.iand", 7})
-      .Case("ior", {"op.ior", 6})
-      .Case("ieor", {"op.ieor", 7})
-      .Default(name);
-}
-
-std::string MangleDefinedOperator(const parser::CharBlock &name) {
-  CHECK(name[0] == '.' && name[name.size() - 1] == '.');
-  return "op" + name.ToString();
-}
-
 void OmpVisitor::ProcessReductionSpecifier(
     const parser::OmpReductionSpecifier &spec,
     const parser::OmpClauseList &clauses) {
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index 48ff27f214649d..ce5c72a481c78b 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -18,6 +18,7 @@
 #include "flang/Semantics/tools.h"
 #include "flang/Semantics/type.h"
 #include "flang/Support/Fortran.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <set>
@@ -1992,4 +1993,78 @@ bool AreSameModuleSymbol(const Symbol &symbol, const Symbol &other) {
       other.owner().IsModule() && symbol.owner().GetName() &&
       symbol.owner().GetName() == other.owner().GetName();
 }
+
+parser::CharBlock MakeNameFromOperator(
+    const parser::DefinedOperator::IntrinsicOperator &op,
+    SemanticsContext &context) {
+  switch (op) {
+  case parser::DefinedOperator::IntrinsicOperator::Multiply:
+    return parser::CharBlock{"op.*", 4};
+  case parser::DefinedOperator::IntrinsicOperator::Add:
+    return parser::CharBlock{"op.+", 4};
+  case parser::DefinedOperator::IntrinsicOperator::Subtract:
+    return parser::CharBlock{"op.-", 4};
+
+  case parser::DefinedOperator::IntrinsicOperator::AND:
+    return parser::CharBlock{"op.AND", 6};
+  case parser::DefinedOperator::IntrinsicOperator::OR:
+    return parser::CharBlock{"op.OR", 5};
+  case parser::DefinedOperator::IntrinsicOperator::EQV:
+    return parser::CharBlock{"op.EQV", 6};
+  case parser::DefinedOperator::IntrinsicOperator::NEQV:
+    return parser::CharBlock{"op.NEQV", 7};
+
+  default:
+    context.Say("Unsupported operator in DECLARE REDUCTION"_err_en_US);
+    return parser::CharBlock{"op.?", 4};
+  }
+}
+
+parser::CharBlock MangleSpecialFunctions(parser::CharBlock name) {
+  return llvm::StringSwitch<parser::CharBlock>(name.ToString())
+      .Case("max", {"op.max", 6})
+      .Case("min", {"op.min", 6})
+      .Case("iand", {"op.iand", 7})
+      .Case("ior", {"op.ior", 6})
+      .Case("ieor", {"op.ieor", 7})
+      .Default(name);
+}
+
+std::string MangleDefinedOperator(parser::CharBlock name) {
+  CHECK(name[0] == '.' && name[name.size() - 1] == '.');
+  return "op" + name.ToString();
+}
+
+std::string GetReductionFortranId(parser::CharBlock mangledName) {
+  if (!mangledName.starts_with("op.")) {
+    return mangledName.str();
+  }
+  llvm::StringRef suffix{mangledName.drop_front(3)};
+  // Intrinsic arithmetic operators: op.+ -> operator(+)
+  if (suffix == "+" || suffix == "-" || suffix == "*") {
+    return ("operator(" + suffix + ")").str();
+  }
+  // Intrinsic logical operators (mangled uppercase, scope uses lowercase)
+  if (suffix == "AND") {
+    return "operator(.and.)";
+  }
+  if (suffix == "OR") {
+    return "operator(.or.)";
+  }
+  if (suffix == "EQV") {
+    return "operator(.eqv.)";
+  }
+  if (suffix == "NEQV") {
+    return "operator(.neqv.)";
+  }
+  // Defined operators: op.combine. -> .combine.
+  // MangleDefinedOperator prepends "op" to the operator name (e.g.,
+  // ".combine.") so after stripping "op.", the suffix ends with '.' for defined
+  // operators.
+  if (!suffix.empty() && suffix.back() == '.') {
+    return ("." + suffix).str();
+  }
+  // Named functions: op.max -> max
+  return suffix.str();
+}
 } // namespace Fortran::semantics



More information about the flang-commits mailing list