[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