[flang-commits] [flang] dc8e837 - [mlir][openacc] Add isCompilerGenerated to GlobalVariableOpInterface (#221096)

via flang-commits flang-commits at lists.llvm.org
Thu Sep 3 17:55:45 PDT 2026


Author: Valentin Clement (バレンタイン クレメン)
Date: 2026-09-03T17:55:38-07:00
New Revision: dc8e837e6a6c4ff86dc09ba6957270335acefb85

URL: https://github.com/llvm/llvm-project/commit/dc8e837e6a6c4ff86dc09ba6957270335acefb85
DIFF: https://github.com/llvm/llvm-project/commit/dc8e837e6a6c4ff86dc09ba6957270335acefb85.diff

LOG: [mlir][openacc] Add isCompilerGenerated to GlobalVariableOpInterface (#221096)

This function is used to determine if a global is compiler generated or
coming from user variables. This is useful when determining the handling
of globals for unified memory mode.

Added: 
    

Modified: 
    flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h
    flang/include/flang/Optimizer/Support/InternalNames.h
    flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp
    flang/lib/Optimizer/Support/InternalNames.cpp
    flang/unittests/Optimizer/InternalNamesTest.cpp
    mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td
    mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h
index f5307c6b4f046..c9ed3cfe9a013 100644
--- a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h
+++ b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h
@@ -71,6 +71,7 @@ struct GlobalVariableModel
   bool hasInitializer(mlir::Operation *op) const;
   mlir::Region *getInitRegion(mlir::Operation *op) const;
   bool isDeviceData(mlir::Operation *op) const;
+  bool isCompilerGenerated(mlir::Operation *op) const;
 };
 
 template <typename Op>

diff  --git a/flang/include/flang/Optimizer/Support/InternalNames.h b/flang/include/flang/Optimizer/Support/InternalNames.h
index 105c51e43aff2..dfb8166726164 100644
--- a/flang/include/flang/Optimizer/Support/InternalNames.h
+++ b/flang/include/flang/Optimizer/Support/InternalNames.h
@@ -195,6 +195,9 @@ struct NameUniquer {
   /// symbol generated for derived type description).
   static bool isSpecialSymbol(llvm::StringRef name);
 
+  /// Returns true if the passed name denotes a compiler generated name.
+  static bool isCompilerGenerated(llvm::StringRef name);
+
 private:
   static std::string intAsString(std::int64_t i);
   static std::string doKind(std::int64_t kind);

diff  --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp
index 5826886f00194..1c714f0675745 100644
--- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp
+++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp
@@ -137,6 +137,11 @@ bool GlobalVariableModel::isDeviceData(mlir::Operation *op) const {
   return false;
 }
 
+bool GlobalVariableModel::isCompilerGenerated(mlir::Operation *op) const {
+  auto globalOp = mlir::cast<fir::GlobalOp>(op);
+  return fir::NameUniquer::isCompilerGenerated(globalOp.getSymName());
+}
+
 bool OutlineRematerializationModel<
     fir::ConvertOp>::isRematerializationCandidate(mlir::Operation *op) const {
   auto convertOp = mlir::cast<fir::ConvertOp>(op);

diff  --git a/flang/lib/Optimizer/Support/InternalNames.cpp b/flang/lib/Optimizer/Support/InternalNames.cpp
index 8e795b6a5bc7c..da7155c6c692e 100644
--- a/flang/lib/Optimizer/Support/InternalNames.cpp
+++ b/flang/lib/Optimizer/Support/InternalNames.cpp
@@ -440,3 +440,23 @@ std::string fir::NameUniquer::replaceSpecialSymbols(const std::string &name) {
 bool fir::NameUniquer::isSpecialSymbol(llvm::StringRef name) {
   return !name.empty() && (name[0] == '.' || name[0] == 'X');
 }
+
+bool fir::NameUniquer::isCompilerGenerated(llvm::StringRef name) {
+  auto [nameKind, deconstructed] = fir::NameUniquer::deconstruct(name);
+
+  // Names that are not mangled by flang belong to the user (e.g. BIND(C)
+  // entities) or come from another language.
+  if (nameKind == fir::NameUniquer::NameKind::NOT_UNIQUED)
+    return false;
+
+  // Anything in the compiler-generated namespace (_QQ...): string literals,
+  // read-only array constants, runtime tables, etc.
+  if (nameKind == fir::NameUniquer::NameKind::GENERATED)
+    return true;
+
+  // Runtime type information is mangled as ordinary variables whose parse name
+  // starts with one of the separator markers, e.g. _QMmod1E.dt.struct or
+  // _QFE.n.member. The '.' becomes 'X' once
+  // CompilerGeneratedNamesConversionPass has run.
+  return fir::NameUniquer::isSpecialSymbol(deconstructed.name);
+}

diff  --git a/flang/unittests/Optimizer/InternalNamesTest.cpp b/flang/unittests/Optimizer/InternalNamesTest.cpp
index 611fd8d571e27..49fd7ba3c3d22 100644
--- a/flang/unittests/Optimizer/InternalNamesTest.cpp
+++ b/flang/unittests/Optimizer/InternalNamesTest.cpp
@@ -270,4 +270,31 @@ TEST(InternalNamesTest, getTypeDescriptorBindingTableName) {
       fir::NameUniquer::getTypeDescriptorBindingTableName("_QMdispatch1Pp1"));
 }
 
+TEST(InternalNamesTest, isCompilerGenerated) {
+  // Test normal compiler genereated names
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QFE.n.member"));
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QFE.n.struct"));
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QFE.c.struct"));
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QFE.dt.struct"));
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QMmod1E.n.member"));
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QMmod1E.n.struct"));
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QMmod1E.c.struct"));
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QMmod1E.dt.struct"));
+  // Test names after CompilerGeneratedNamesConversionPass has run
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QFEXnXmember"));
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QFEXnXstruct"));
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QFEXcXstruct"));
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QFEXdtXstruct"));
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QMmod1EXnXmember"));
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QMmod1EXnXstruct"));
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QMmod1EXcXstruct"));
+  ASSERT_TRUE(NameUniquer::isCompilerGenerated("_QMmod1EXdtXstruct"));
+  // Test false cases
+  ASSERT_FALSE(NameUniquer::isCompilerGenerated("_QMmod1Eintvar"));
+  ASSERT_FALSE(NameUniquer::isCompilerGenerated("_QMmod1Epi"));
+  ASSERT_FALSE(NameUniquer::isCompilerGenerated("_QMmod1Emytype"));
+  ASSERT_FALSE(NameUniquer::isCompilerGenerated("_QMmod1EmytypeK4KN6"));
+  ASSERT_FALSE(NameUniquer::isCompilerGenerated("_QMmod1EmytypeK4KN6"));
+}
+
 // main() from gtest_main

diff  --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td
index eddd21a7e917b..7cc849c38a1c9 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td
@@ -83,6 +83,10 @@ def GlobalVariableOpInterface : OpInterface<"GlobalVariableOpInterface"> {
       "bool", "isDeviceData", (ins), [{
         return false;
       }]>,
+    InterfaceMethod<"Check if the global variable is compiler generated", "bool",
+      "isCompilerGenerated", (ins), [{
+        return false;
+      }]>,
   ];
 }
 

diff  --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index edef98c504d2c..e8860ae462819 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -410,6 +410,8 @@ struct MemrefGlobalVariableModel
     Attribute memSpace = globalOp.getType().getMemorySpace();
     return isa_and_nonnull<gpu::AddressSpaceAttr>(memSpace);
   }
+
+  bool isCompilerGenerated(Operation *op) const { return false; }
 };
 
 struct GPULaunchOffloadRegionModel


        


More information about the flang-commits mailing list