[flang-commits] [flang] [RFC][flang] Replace special symbols in uniqued global names. (PR #104859)

via flang-commits flang-commits at lists.llvm.org
Mon Aug 19 14:10:35 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-driver

Author: Slava Zakharin (vzakhari)

<details>
<summary>Changes</summary>

This change addresses more "issues" as the one resolved in #<!-- -->71338.
Some targets (e.g. NVPTX) do not accept global names containing
`.`. In particular, the global variables created to represent
the runtime information of derived types use `.` in their names.
A derived type's descriptor object may be used in the device code,
e.g. to initialize a descriptor of a variable of this type.
Thus, the runtime type info objects may need to be compiled
for the device.

Moreover, at least the derived types' descriptor objects
may need to be registered (think of `omp declare target`)
for the host-device association so that the addendum pointer
can be properly mapped to the device for descriptors using
a derived type's descriptor as their addendum pointer.
The registration implies knowing the name of the global variable
in the device image so that proper host code can be created.
So it is better to name the globals the same way for the host
and the device.

CompilerGeneratedNamesConversion pass renames all uniqued globals
such that the special symbols (currently `.`) are replaced
with `X`. The pass is supposed to be run for the host and the device.

An option is added to FIR-to-LLVM conversion pass to indicate
whether the new pass has been run before or not. This setting
affects how the codegen computes the names of the derived types'
descriptors for FIR derived types.

fir::NameUniquer now allows `X` to be part of a name, because
the name deconstruction may be applied to the mangled names
after CompilerGeneratedNamesConversion pass.


---

Patch is 42.09 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/104859.diff


20 Files Affected:

- (modified) flang/include/flang/Optimizer/CodeGen/CGPasses.td (+5-1) 
- (modified) flang/include/flang/Optimizer/CodeGen/CodeGen.h (+10) 
- (modified) flang/include/flang/Optimizer/Support/InternalNames.h (+20-5) 
- (modified) flang/include/flang/Optimizer/Transforms/Passes.h (+1) 
- (modified) flang/include/flang/Optimizer/Transforms/Passes.td (+18) 
- (modified) flang/include/flang/Tools/CLOptions.inc (+10) 
- (modified) flang/lib/Optimizer/CodeGen/CodeGen.cpp (+11-2) 
- (modified) flang/lib/Optimizer/Support/InternalNames.cpp (+23-8) 
- (modified) flang/lib/Optimizer/Transforms/CMakeLists.txt (+1) 
- (added) flang/lib/Optimizer/Transforms/CompilerGeneratedNames.cpp (+80) 
- (modified) flang/lib/Semantics/runtime-type-info.cpp (+41-24) 
- (modified) flang/test/Driver/mlir-debug-pass-pipeline.f90 (+1) 
- (modified) flang/test/Driver/mlir-pass-pipeline.f90 (+1) 
- (modified) flang/test/Fir/basic-program.fir (+1) 
- (modified) flang/test/Fir/convert-to-llvm.fir (+1-1) 
- (added) flang/test/Fir/convert-type-desc-to-llvm.fir (+29) 
- (modified) flang/test/Fir/polymorphic.fir (+2-2) 
- (modified) flang/test/Fir/type-descriptor.fir (+2-2) 
- (modified) flang/test/Lower/allocatable-polymorphic.f90 (+7-7) 
- (modified) flang/test/Lower/dense-array-any-rank.f90 (+3-3) 


``````````diff
diff --git a/flang/include/flang/Optimizer/CodeGen/CGPasses.td b/flang/include/flang/Optimizer/CodeGen/CGPasses.td
index 989e3943882a19..e9e303df09eeba 100644
--- a/flang/include/flang/Optimizer/CodeGen/CGPasses.td
+++ b/flang/include/flang/Optimizer/CodeGen/CGPasses.td
@@ -36,7 +36,11 @@ def FIRToLLVMLowering : Pass<"fir-to-llvm-ir", "mlir::ModuleOp"> {
     Option<"forcedTargetFeatures", "target-features", "std::string",
            /*default=*/"", "Override module's target features.">,
     Option<"applyTBAA", "apply-tbaa", "bool", /*default=*/"false",
-           "Attach TBAA tags to memory accessing operations.">
+           "Attach TBAA tags to memory accessing operations.">,
+    Option<"typeDescriptorsRenamedForAssembly",
+           "type-descriptors-renamed-for-assembly", "bool", /*default=*/"false",
+           "Global variables created to describe derived types "
+           "have been renamed to avoid special symbols in their names.">
   ];
 }
 
diff --git a/flang/include/flang/Optimizer/CodeGen/CodeGen.h b/flang/include/flang/Optimizer/CodeGen/CodeGen.h
index 06961819bb19c8..390f00e1ac77c2 100644
--- a/flang/include/flang/Optimizer/CodeGen/CodeGen.h
+++ b/flang/include/flang/Optimizer/CodeGen/CodeGen.h
@@ -44,6 +44,16 @@ struct FIRToLLVMPassOptions {
 
   // Force the usage of a unified tbaa tree in TBAABuilder.
   bool forceUnifiedTBAATree = false;
+
+  // If set to true, then the global variables created
+  // for the derived types have been renamed to avoid usage
+  // of special symbols that may not be supported by all targets.
+  // The renaming is done by the CompilerGeneratedNamesConversion pass.
+  // If it is true, FIR-to-LLVM pass has to use
+  // fir::NameUniquer::getTypeDescriptorAssemblyName() to take
+  // the name of the global variable corresponding to a derived
+  // type's descriptor.
+  bool typeDescriptorsRenamedForAssembly = false;
 };
 
 /// Convert FIR to the LLVM IR dialect with default options.
diff --git a/flang/include/flang/Optimizer/Support/InternalNames.h b/flang/include/flang/Optimizer/Support/InternalNames.h
index 9e13b4a7668b7a..67ab36cf8da7ff 100644
--- a/flang/include/flang/Optimizer/Support/InternalNames.h
+++ b/flang/include/flang/Optimizer/Support/InternalNames.h
@@ -14,13 +14,23 @@
 #include <cstdint>
 #include <optional>
 
-static constexpr llvm::StringRef typeDescriptorSeparator = ".dt.";
-static constexpr llvm::StringRef componentInitSeparator = ".di.";
-static constexpr llvm::StringRef bindingTableSeparator = ".v.";
-static constexpr llvm::StringRef boxprocSuffix = "UnboxProc";
-
 namespace fir {
 
+static constexpr llvm::StringRef kNameSeparator = ".";
+static constexpr llvm::StringRef kBoundsSeparator = ".b.";
+static constexpr llvm::StringRef kComponentSeparator = ".c.";
+static constexpr llvm::StringRef kComponentInitSeparator = ".di.";
+static constexpr llvm::StringRef kDataPtrInitSeparator = ".dp.";
+static constexpr llvm::StringRef kTypeDescriptorSeparator = ".dt.";
+static constexpr llvm::StringRef kKindParameterSeparator = ".kp.";
+static constexpr llvm::StringRef kLenKindSeparator = ".lpk.";
+static constexpr llvm::StringRef kLenParameterSeparator = ".lv.";
+static constexpr llvm::StringRef kNameStringSeparator = ".n.";
+static constexpr llvm::StringRef kProcPtrSeparator = ".p.";
+static constexpr llvm::StringRef kSpecialBindingSeparator = ".s.";
+static constexpr llvm::StringRef kBindingTableSeparator = ".v.";
+static constexpr llvm::StringRef boxprocSuffix = "UnboxProc";
+
 /// Internal name mangling of identifiers
 ///
 /// In order to generate symbolically referencable artifacts in a ModuleOp,
@@ -150,6 +160,9 @@ struct NameUniquer {
   /// not a valid mangled derived type name.
   static std::string getTypeDescriptorName(llvm::StringRef mangledTypeName);
 
+  static std::string
+  getTypeDescriptorAssemblyName(llvm::StringRef mangledTypeName);
+
   /// Given a mangled derived type name, get the name of the related binding
   /// table object. Returns an empty string if \p mangledTypeName is not a valid
   /// mangled derived type name.
@@ -169,6 +182,8 @@ struct NameUniquer {
   static llvm::StringRef
   dropTypeConversionMarkers(llvm::StringRef mangledTypeName);
 
+  static std::string replaceSpecialSymbols(const std::string &name);
+
 private:
   static std::string intAsString(std::int64_t i);
   static std::string doKind(std::int64_t kind);
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h
index 96b0e9714b95af..6f98e3a25ec125 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.h
+++ b/flang/include/flang/Optimizer/Transforms/Passes.h
@@ -59,6 +59,7 @@ namespace fir {
 #define GEN_PASS_DECL_VSCALEATTR
 #define GEN_PASS_DECL_FUNCTIONATTR
 #define GEN_PASS_DECL_CONSTANTARGUMENTGLOBALISATIONOPT
+#define GEN_PASS_DECL_COMPILERGENERATEDNAMESCONVERSION
 
 #include "flang/Optimizer/Transforms/Passes.h.inc"
 
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index c703a62c03b7d9..a0211384667ed1 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -170,6 +170,24 @@ def ExternalNameConversion : Pass<"external-name-interop", "mlir::ModuleOp"> {
   ];
 }
 
+def CompilerGeneratedNamesConversion : Pass<"compiler-generated-names",
+    "mlir::ModuleOp"> {
+  let summary = "Convert names of compiler generated globals";
+  let description = [{
+    Transforms names of compiler generated globals to avoid
+    characters that might be unsupported by some target toolchains.
+    All special symbols are replaced with a predefined 'X' character.
+    This is only done for uniqued names that are not externally facing.
+    The uniqued names always use '_Q' prefix, and the user entity names
+    are always lower cased, so using 'X' instead of the special symbols
+    will guarantee that the converted name will not conflict with the user
+    space. This pass does not affect the externally facing names,
+    because the expectation is that the compiler will not generate
+    externally facing names on its own, and these names cannot use
+    special symbols.
+  }];
+}
+
 def MemRefDataFlowOpt : Pass<"fir-memref-dataflow-opt", "::mlir::func::FuncOp"> {
   let summary =
     "Perform store/load forwarding and potentially removing dead stores.";
diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc
index 7df50449494631..57b90017d052e4 100644
--- a/flang/include/flang/Tools/CLOptions.inc
+++ b/flang/include/flang/Tools/CLOptions.inc
@@ -93,6 +93,8 @@ DisableOption(ExternalNameConversion, "external-name-interop",
     "convert names with external convention");
 EnableOption(ConstantArgumentGlobalisation, "constant-argument-globalisation",
     "the local constant argument to global constant conversion");
+DisableOption(CompilerGeneratedNamesConversion, "compiler-generated-names",
+    "replace special symbols in compiler generated names");
 
 using PassConstructor = std::unique_ptr<mlir::Pass>();
 
@@ -222,6 +224,8 @@ inline void addFIRToLLVMPass(
   options.ignoreMissingTypeDescriptors = ignoreMissingTypeDescriptors;
   options.applyTBAA = config.AliasAnalysis;
   options.forceUnifiedTBAATree = useOldAliasTags;
+  options.typeDescriptorsRenamedForAssembly =
+      !disableCompilerGeneratedNamesConversion;
   addPassConditionally(pm, disableFirToLlvmIr,
       [&]() { return fir::createFIRToLLVMPass(options); });
   // The dialect conversion framework may leave dead unrealized_conversion_cast
@@ -248,6 +252,11 @@ inline void addExternalNameConversionPass(
       [&]() { return fir::createExternalNameConversion({appendUnderscore}); });
 }
 
+inline void addCompilerGeneratedNamesConversionPass(mlir::PassManager &pm) {
+  addPassConditionally(pm, disableCompilerGeneratedNamesConversion,
+      [&]() { return fir::createCompilerGeneratedNamesConversion(); });
+}
+
 // Use inliner extension point callback to register the default inliner pass.
 inline void registerDefaultInlinerPass(MLIRToLLVMPassPipelineConfig &config) {
   config.registerFIRInlinerCallback(
@@ -379,6 +388,7 @@ inline void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
   fir::addCodeGenRewritePass(
       pm, (config.DebugInfo != llvm::codegenoptions::NoDebugInfo));
   fir::addTargetRewritePass(pm);
+  fir::addCompilerGeneratedNamesConversionPass(pm);
   fir::addExternalNameConversionPass(pm, config.Underscoring);
   fir::createDebugPasses(pm, config.DebugInfo, config.OptLevel, inputFilename);
 
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 1713cf98a8b961..e419b261252995 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -1201,7 +1201,9 @@ struct EmboxCommonConversion : public fir::FIROpConversion<OP> {
                                 mlir::Location loc,
                                 fir::RecordType recType) const {
     std::string name =
-        fir::NameUniquer::getTypeDescriptorName(recType.getName());
+        this->options.typeDescriptorsRenamedForAssembly
+            ? fir::NameUniquer::getTypeDescriptorAssemblyName(recType.getName())
+            : fir::NameUniquer::getTypeDescriptorName(recType.getName());
     mlir::Type llvmPtrTy = ::getLlvmPtrType(mod.getContext());
     if (auto global = mod.template lookupSymbol<fir::GlobalOp>(name)) {
       return rewriter.create<mlir::LLVM::AddressOfOp>(loc, llvmPtrTy,
@@ -2704,7 +2706,10 @@ struct TypeDescOpConversion : public fir::FIROpConversion<fir::TypeDescOp> {
     auto recordType = mlir::dyn_cast<fir::RecordType>(inTy);
     auto module = typeDescOp.getOperation()->getParentOfType<mlir::ModuleOp>();
     std::string typeDescName =
-        fir::NameUniquer::getTypeDescriptorName(recordType.getName());
+        this->options.typeDescriptorsRenamedForAssembly
+            ? fir::NameUniquer::getTypeDescriptorAssemblyName(
+                  recordType.getName())
+            : fir::NameUniquer::getTypeDescriptorName(recordType.getName());
     auto llvmPtrTy = ::getLlvmPtrType(typeDescOp.getContext());
     if (auto global = module.lookupSymbol<mlir::LLVM::GlobalOp>(typeDescName)) {
       rewriter.replaceOpWithNewOp<mlir::LLVM::AddressOfOp>(
@@ -3653,6 +3658,10 @@ class FIRToLLVMLowering
     if (!forcedTargetFeatures.empty())
       fir::setTargetFeatures(mod, forcedTargetFeatures);
 
+    if (typeDescriptorsRenamedForAssembly)
+      options.typeDescriptorsRenamedForAssembly =
+          typeDescriptorsRenamedForAssembly;
+
     // Run dynamic pass pipeline for converting Math dialect
     // operations into other dialects (llvm, func, etc.).
     // Some conversions of Math operations cannot be done
diff --git a/flang/lib/Optimizer/Support/InternalNames.cpp b/flang/lib/Optimizer/Support/InternalNames.cpp
index b2e2cd38f48e60..58a5da5de79720 100644
--- a/flang/lib/Optimizer/Support/InternalNames.cpp
+++ b/flang/lib/Optimizer/Support/InternalNames.cpp
@@ -16,6 +16,7 @@
 #include "mlir/IR/Diagnostics.h"
 #include "llvm/Support/CommandLine.h"
 #include <optional>
+#include <regex>
 
 static llvm::cl::opt<std::string> mainEntryName(
     "main-entry-name",
@@ -59,7 +60,11 @@ convertToStringRef(const std::optional<std::string> &from) {
 
 static std::string readName(llvm::StringRef uniq, std::size_t &i,
                             std::size_t init, std::size_t end) {
-  for (i = init; i < end && (uniq[i] < 'A' || uniq[i] > 'Z'); ++i) {
+  // Allow 'X' to be part of the mangled name, which
+  // can happen after the special symbols are replaced
+  // in the mangled names by CompilerGeneratedNamesConversionPass.
+  for (i = init; i < end && (uniq[i] < 'A' || uniq[i] > 'Z' || uniq[i] == 'X');
+       ++i) {
     // do nothing
   }
   return uniq.substr(init, i - init).str();
@@ -348,7 +353,7 @@ mangleTypeDescriptorKinds(llvm::ArrayRef<std::int64_t> kinds) {
     return "";
   std::string result;
   for (std::int64_t kind : kinds)
-    result += "." + std::to_string(kind);
+    result += (fir::kNameSeparator + std::to_string(kind)).str();
   return result;
 }
 
@@ -373,12 +378,18 @@ static std::string getDerivedTypeObjectName(llvm::StringRef mangledTypeName,
 
 std::string
 fir::NameUniquer::getTypeDescriptorName(llvm::StringRef mangledTypeName) {
-  return getDerivedTypeObjectName(mangledTypeName, typeDescriptorSeparator);
+  return getDerivedTypeObjectName(mangledTypeName,
+                                  fir::kTypeDescriptorSeparator);
+}
+
+std::string fir::NameUniquer::getTypeDescriptorAssemblyName(
+    llvm::StringRef mangledTypeName) {
+  return replaceSpecialSymbols(getTypeDescriptorName(mangledTypeName));
 }
 
 std::string fir::NameUniquer::getTypeDescriptorBindingTableName(
     llvm::StringRef mangledTypeName) {
-  return getDerivedTypeObjectName(mangledTypeName, bindingTableSeparator);
+  return getDerivedTypeObjectName(mangledTypeName, fir::kBindingTableSeparator);
 }
 
 std::string
@@ -386,13 +397,17 @@ fir::NameUniquer::getComponentInitName(llvm::StringRef mangledTypeName,
                                        llvm::StringRef componentName) {
 
   std::string prefix =
-      getDerivedTypeObjectName(mangledTypeName, componentInitSeparator);
-  return prefix + "." + componentName.str();
+      getDerivedTypeObjectName(mangledTypeName, fir::kComponentInitSeparator);
+  return (prefix + fir::kNameSeparator + componentName).str();
 }
 
 llvm::StringRef
 fir::NameUniquer::dropTypeConversionMarkers(llvm::StringRef mangledTypeName) {
-  if (mangledTypeName.ends_with(boxprocSuffix))
-    return mangledTypeName.drop_back(boxprocSuffix.size());
+  if (mangledTypeName.ends_with(fir::boxprocSuffix))
+    return mangledTypeName.drop_back(fir::boxprocSuffix.size());
   return mangledTypeName;
 }
+
+std::string fir::NameUniquer::replaceSpecialSymbols(const std::string &name) {
+  return std::regex_replace(name, std::regex{"\\."}, "X");
+}
diff --git a/flang/lib/Optimizer/Transforms/CMakeLists.txt b/flang/lib/Optimizer/Transforms/CMakeLists.txt
index 3869633bd98e02..bf0a8d14d95df6 100644
--- a/flang/lib/Optimizer/Transforms/CMakeLists.txt
+++ b/flang/lib/Optimizer/Transforms/CMakeLists.txt
@@ -6,6 +6,7 @@ add_flang_library(FIRTransforms
   AnnotateConstant.cpp
   AssumedRankOpConversion.cpp
   CharacterConversion.cpp
+  CompilerGeneratedNames.cpp
   ConstantArgumentGlobalisation.cpp
   ControlFlowConverter.cpp
   CufOpConversion.cpp
diff --git a/flang/lib/Optimizer/Transforms/CompilerGeneratedNames.cpp b/flang/lib/Optimizer/Transforms/CompilerGeneratedNames.cpp
new file mode 100644
index 00000000000000..7f2cc41275e593
--- /dev/null
+++ b/flang/lib/Optimizer/Transforms/CompilerGeneratedNames.cpp
@@ -0,0 +1,80 @@
+//=== CompilerGeneratedNames.cpp - convert special symbols in global names ===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/FIROpsSupport.h"
+#include "flang/Optimizer/Support/InternalNames.h"
+#include "flang/Optimizer/Transforms/Passes.h"
+#include "mlir/IR/Attributes.h"
+#include "mlir/IR/SymbolTable.h"
+#include "mlir/Pass/Pass.h"
+
+namespace fir {
+#define GEN_PASS_DEF_COMPILERGENERATEDNAMESCONVERSION
+#include "flang/Optimizer/Transforms/Passes.h.inc"
+} // namespace fir
+
+using namespace mlir;
+
+namespace {
+
+class CompilerGeneratedNamesConversionPass
+    : public fir::impl::CompilerGeneratedNamesConversionBase<
+          CompilerGeneratedNamesConversionPass> {
+public:
+  using CompilerGeneratedNamesConversionBase<
+      CompilerGeneratedNamesConversionPass>::
+      CompilerGeneratedNamesConversionBase;
+
+  mlir::ModuleOp getModule() { return getOperation(); }
+  void runOnOperation() override;
+};
+} // namespace
+
+void CompilerGeneratedNamesConversionPass::runOnOperation() {
+  auto op = getOperation();
+  auto *context = &getContext();
+
+  llvm::DenseMap<mlir::StringAttr, mlir::FlatSymbolRefAttr> remappings;
+  for (auto &funcOrGlobal : op->getRegion(0).front()) {
+    if (llvm::isa<mlir::func::FuncOp>(funcOrGlobal) ||
+        llvm::isa<fir::GlobalOp>(funcOrGlobal)) {
+      auto symName = funcOrGlobal.getAttrOfType<mlir::StringAttr>(
+          mlir::SymbolTable::getSymbolAttrName());
+      auto deconstructedName = fir::NameUniquer::deconstruct(symName);
+      if (deconstructedName.first != fir::NameUniquer::NameKind::NOT_UNIQUED &&
+          !fir::NameUniquer::isExternalFacingUniquedName(deconstructedName)) {
+        std::string newName =
+            fir::NameUniquer::replaceSpecialSymbols(symName.getValue().str());
+        if (newName != symName) {
+          auto newAttr = mlir::StringAttr::get(context, newName);
+          mlir::SymbolTable::setSymbolName(&funcOrGlobal, newAttr);
+          auto newSymRef = mlir::FlatSymbolRefAttr::get(newAttr);
+          remappings.try_emplace(symName, newSymRef);
+        }
+      }
+    }
+  }
+
+  if (remappings.empty())
+    return;
+
+  // Update all uses of the functions and globals that have been renamed.
+  op.walk([&remappings](mlir::Operation *nestedOp) {
+    llvm::SmallVector<std::pair<mlir::StringAttr, mlir::SymbolRefAttr>> updates;
+    for (const mlir::NamedAttribute &attr : nestedOp->getAttrDictionary())
+      if (auto symRef = llvm::dyn_cast<mlir::SymbolRefAttr>(attr.getValue()))
+        if (auto remap = remappings.find(symRef.getRootReference());
+            remap != remappings.end())
+          updates.emplace_back(std::pair<mlir::StringAttr, mlir::SymbolRefAttr>{
+              attr.getName(), mlir::SymbolRefAttr(remap->second)});
+    for (auto update : updates)
+      nestedOp->setAttr(update.first, update.second);
+  });
+}
diff --git a/flang/lib/Semantics/runtime-type-info.cpp b/flang/lib/Semantics/runtime-type-info.cpp
index 66909241966735..4d1308d84889f6 100644
--- a/flang/lib/Semantics/runtime-type-info.cpp
+++ b/flang/lib/Semantics/runtime-type-info.cpp
@@ -12,6 +12,7 @@
 #include "flang/Evaluate/fold.h"
 #include "flang/Evaluate/tools.h"
 #include "flang/Evaluate/type.h"
+#include "flang/Optimizer/Support/InternalNames.h"
 #include "flang/Semantics/scope.h"
 #include "flang/Semantics/tools.h"
 #include <functional>
@@ -377,9 +378,12 @@ static std::optional<std::string> GetSuffixIfTypeKindParameters(
           if (pv->GetExplicit()) {
             if (auto instantiatedValue{evaluate::ToInt64(*pv->GetExplicit())}) {
               if (suffix.has_value()) {
-                *suffix += "."s + std::to_string(*instantiatedValue);
+                *suffix +=
+                    (fir::kNameSeparator + llvm::Twine(*instantiatedValue))
+                        .str();
               } else {
-                suffix = "."s + std::to_string(*instantiatedValue);
+                suffix = (fir::kNameSeparator + llvm::Twine(*instantiatedValue))
+                             .str();
               }
             }
           }
@@ -448,7 +452,7 @@ const Symbol *RuntimeTableBuilder::DescribeType(Scope &dtScope) {
   } else if (isPDTDefinitionWithKindParameters) {
     return nullptr;
   }
-  std::string dtDescName{".dt."s + distinctName};
+  std::string dtDescName{(fir::kTypeDescriptorSeparator + distinctName).str()};
   Scope *dtSymbolScope{const_cast<Scope *>(dtSymbol->scope())};
   Scope &scope{
       GetContainingNonDerivedScope(dtSymbolScope ? *dtSymbolScope : dtScope)};
@@ -518,11 +522,13 @@ const Symbol *RuntimeTableBuilder::DescribeType(Scope &dtScope) {
     }
   }
   AddValue(dtValues, derivedTypeSchema_, "kindparameter"s,
-      SaveNumericPointerTarget<Int8>(
-          scope, SaveObjectName(".kp."s + distinctName), std::move(kinds)));
+      SaveNumericPointerTarget<Int8>(scope,
+          SaveObjectName((fir::kKindParameterSeparator + distinctName).str()),
+          std::move(kinds)));
   AddValue(dtValues, derivedTypeSchema_, "lenparameterkind"s,
-      SaveNumericPointerTarget<Int1>(
-          scope, SaveObjectName(".lpk."s + distinctName), std::move(lenKinds)));
+      SaveNumericPointerTarget<Int1>(scope,
+          SaveObjectName((fir::kLenKindSeparator + distinctN...
[truncated]

``````````

</details>


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


More information about the flang-commits mailing list