[Mlir-commits] [mlir] f3599e5 - [mlir][acc] Add OpenACCSupport for extensible dialect handling (#164510)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Oct 22 08:26:25 PDT 2025
Author: Razvan Lupusoru
Date: 2025-10-22T08:26:21-07:00
New Revision: f3599e55d12de7535cf5697a73fb0e1d74e037a2
URL: https://github.com/llvm/llvm-project/commit/f3599e55d12de7535cf5697a73fb0e1d74e037a2
DIFF: https://github.com/llvm/llvm-project/commit/f3599e55d12de7535cf5697a73fb0e1d74e037a2.diff
LOG: [mlir][acc] Add OpenACCSupport for extensible dialect handling (#164510)
The OpenACC dialect must coexist with source language dialects (FIR,
CIR, etc.) to enable offloading. While type interfaces
(`PointerLikeType` and `MappableType`) provide the primary contract for
variable mapping, some scenarios require pipeline-specific customization
or need to express information that cannot be adequately captured
through operation and type interfaces alone.
This commit introduces the `OpenACCSupport` analysis, which provides
extensible support APIs that can be customized per-pipeline. The
analysis follows the Concept-Model pattern used in MLIR's
`AliasAnalysis` and is never invalidated, persisting throughout the pass
pipeline.
The initial API, `getVariableName(Value) -> string`, retrieves variable
names from MLIR values by:
- Checking for `acc.var_name` attributes
- Extracting names from ACC data clause operations (e.g., `acc.copyin`)
- Walking through `ViewLikeOpInterface` operations to find the source
This will be used in the implicit data mapping pass to automatically
generate device mappings with correct user-visible variable names.
Usage: Passes call `getAnalysis<OpenACCSupport>()` to get a cached
instance with either the default or a previously- registered custom
implementation. Custom implementations can be registered in a setup pass
by calling `setImplementation()` before the consumer pass runs.
Added:
mlir/include/mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h
mlir/lib/Dialect/OpenACC/Analysis/CMakeLists.txt
mlir/lib/Dialect/OpenACC/Analysis/OpenACCSupport.cpp
mlir/test/Dialect/OpenACC/support-analysis-varname.mlir
mlir/test/lib/Dialect/OpenACC/TestOpenACCSupport.cpp
Modified:
mlir/include/mlir/Dialect/OpenACC/OpenACCUtils.h
mlir/lib/Dialect/OpenACC/CMakeLists.txt
mlir/lib/Dialect/OpenACC/Utils/OpenACCUtils.cpp
mlir/test/lib/Dialect/OpenACC/CMakeLists.txt
mlir/test/lib/Dialect/OpenACC/TestOpenACC.cpp
mlir/unittests/Dialect/OpenACC/OpenACCUtilsTest.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h b/mlir/include/mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h
new file mode 100644
index 0000000000000..0833462ea0509
--- /dev/null
+++ b/mlir/include/mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h
@@ -0,0 +1,135 @@
+//===- OpenACCSupport.h - OpenACC Support Interface -------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the OpenACCSupport analysis interface, which provides
+// extensible support for OpenACC passes. Custom implementations
+// can be registered to provide pipeline and dialect-specific information
+// that cannot be adequately expressed through type or operation interfaces
+// alone.
+//
+// Usage Pattern:
+// ==============
+//
+// A pass that needs this functionality should call
+// getAnalysis<OpenACCSupport>(), which will provide either:
+// - A cached version if previously initialized, OR
+// - A default implementation if not previously initialized
+//
+// This analysis is never invalidated (isInvalidated returns false), so it only
+// needs to be initialized once and will persist throughout the pass pipeline.
+//
+// Registering a Custom Implementation:
+// =====================================
+//
+// If a custom implementation is needed, create a pass that runs BEFORE the pass
+// that needs the analysis. In this setup pass, use
+// getAnalysis<OpenACCSupport>() followed by setImplementation() to register
+// your custom implementation. The custom implementation will need to provide
+// implementation for all methods defined in the `OpenACCSupportTraits::Concept`
+// class.
+//
+// Example:
+// void MySetupPass::runOnOperation() {
+// OpenACCSupport &support = getAnalysis<OpenACCSupport>();
+// support.setImplementation(MyCustomImpl());
+// }
+//
+// void MyAnalysisConsumerPass::runOnOperation() {
+// OpenACCSupport &support = getAnalysis<OpenACCSupport>();
+// std::string name = support.getVariableName(someValue);
+// // ... use the analysis results
+// }
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_OPENACC_ANALYSIS_OPENACCSUPPORT_H
+#define MLIR_DIALECT_OPENACC_ANALYSIS_OPENACCSUPPORT_H
+
+#include "mlir/IR/Value.h"
+#include "mlir/Pass/AnalysisManager.h"
+#include <memory>
+#include <string>
+
+namespace mlir {
+namespace acc {
+
+namespace detail {
+/// This class contains internal trait classes used by OpenACCSupport.
+/// It follows the Concept-Model pattern used throughout MLIR (e.g., in
+/// AliasAnalysis and interface definitions).
+struct OpenACCSupportTraits {
+ class Concept {
+ public:
+ virtual ~Concept() = default;
+
+ /// Get the variable name for a given MLIR value.
+ virtual std::string getVariableName(Value v) = 0;
+ };
+
+ /// This class wraps a concrete OpenACCSupport implementation and forwards
+ /// interface calls to it. This provides type erasure, allowing
diff erent
+ /// implementation types to be used interchangeably without inheritance.
+ template <typename ImplT>
+ class Model final : public Concept {
+ public:
+ explicit Model(ImplT &&impl) : impl(std::forward<ImplT>(impl)) {}
+ ~Model() override = default;
+
+ std::string getVariableName(Value v) final {
+ return impl.getVariableName(v);
+ }
+
+ private:
+ ImplT impl;
+ };
+};
+} // namespace detail
+
+//===----------------------------------------------------------------------===//
+// OpenACCSupport
+//===----------------------------------------------------------------------===//
+
+class OpenACCSupport {
+ using Concept = detail::OpenACCSupportTraits::Concept;
+ template <typename ImplT>
+ using Model = detail::OpenACCSupportTraits::Model<ImplT>;
+
+public:
+ OpenACCSupport() = default;
+ OpenACCSupport(Operation *op) {}
+
+ /// Register a custom OpenACCSupport implementation. Only one implementation
+ /// can be registered at a time; calling this replaces any existing
+ /// implementation.
+ template <typename AnalysisT>
+ void setImplementation(AnalysisT &&analysis) {
+ impl =
+ std::make_unique<Model<AnalysisT>>(std::forward<AnalysisT>(analysis));
+ }
+
+ /// Get the variable name for a given value.
+ ///
+ /// \param v The MLIR value to get the variable name for.
+ /// \return The variable name, or an empty string if unavailable.
+ std::string getVariableName(Value v);
+
+ /// Signal that this analysis should always be preserved so that
+ /// underlying implementation registration is not lost.
+ bool isInvalidated(const AnalysisManager::PreservedAnalyses &pa) {
+ return false;
+ }
+
+private:
+ /// The registered custom implementation (if any).
+ std::unique_ptr<Concept> impl;
+};
+
+} // namespace acc
+} // namespace mlir
+
+#endif // MLIR_DIALECT_OPENACC_ANALYSIS_OPENACCSUPPORT_H
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCUtils.h b/mlir/include/mlir/Dialect/OpenACC/OpenACCUtils.h
index 378f4348f2cf1..0ee88c6f47b67 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCUtils.h
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCUtils.h
@@ -38,6 +38,11 @@ std::optional<ClauseDefaultValue> getDefaultAttr(mlir::Operation *op);
/// Get the type category of an OpenACC variable.
mlir::acc::VariableTypeCategory getTypeCategory(mlir::Value var);
+/// Attempts to extract the variable name from a value by walking through
+/// view-like operations until an `acc.var_name` attribute is found. Returns
+/// empty string if no name is found.
+std::string getVariableName(mlir::Value v);
+
} // namespace acc
} // namespace mlir
diff --git a/mlir/lib/Dialect/OpenACC/Analysis/CMakeLists.txt b/mlir/lib/Dialect/OpenACC/Analysis/CMakeLists.txt
new file mode 100644
index 0000000000000..f305068e1b3bc
--- /dev/null
+++ b/mlir/lib/Dialect/OpenACC/Analysis/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_mlir_dialect_library(MLIROpenACCAnalysis
+ OpenACCSupport.cpp
+
+ ADDITIONAL_HEADER_DIRS
+ ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/OpenACC
+
+ LINK_LIBS PUBLIC
+ MLIRIR
+ MLIROpenACCDialect
+ MLIROpenACCUtils
+ MLIRSupport
+)
+
diff --git a/mlir/lib/Dialect/OpenACC/Analysis/OpenACCSupport.cpp b/mlir/lib/Dialect/OpenACC/Analysis/OpenACCSupport.cpp
new file mode 100644
index 0000000000000..f6b4534794eaf
--- /dev/null
+++ b/mlir/lib/Dialect/OpenACC/Analysis/OpenACCSupport.cpp
@@ -0,0 +1,26 @@
+//===- OpenACCSupport.cpp - OpenACCSupport Implementation -----------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the OpenACCSupport analysis interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h"
+#include "mlir/Dialect/OpenACC/OpenACCUtils.h"
+
+namespace mlir {
+namespace acc {
+
+std::string OpenACCSupport::getVariableName(Value v) {
+ if (impl)
+ return impl->getVariableName(v);
+ return acc::getVariableName(v);
+}
+
+} // namespace acc
+} // namespace mlir
diff --git a/mlir/lib/Dialect/OpenACC/CMakeLists.txt b/mlir/lib/Dialect/OpenACC/CMakeLists.txt
index 7117520599fa6..e8a916e824d71 100644
--- a/mlir/lib/Dialect/OpenACC/CMakeLists.txt
+++ b/mlir/lib/Dialect/OpenACC/CMakeLists.txt
@@ -1,3 +1,4 @@
+add_subdirectory(Analysis)
add_subdirectory(IR)
add_subdirectory(Utils)
add_subdirectory(Transforms)
diff --git a/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtils.cpp b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtils.cpp
index 12233254f3fb4..89adda82646e6 100644
--- a/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtils.cpp
+++ b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtils.cpp
@@ -9,6 +9,7 @@
#include "mlir/Dialect/OpenACC/OpenACCUtils.h"
#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/Interfaces/ViewLikeInterface.h"
#include "llvm/ADT/TypeSwitch.h"
mlir::Operation *mlir::acc::getEnclosingComputeOp(mlir::Region ®ion) {
@@ -78,3 +79,30 @@ mlir::acc::VariableTypeCategory mlir::acc::getTypeCategory(mlir::Value var) {
pointerLikeTy.getElementType());
return typeCategory;
}
+
+std::string mlir::acc::getVariableName(mlir::Value v) {
+ Value current = v;
+
+ // Walk through view operations until a name is found or can't go further
+ while (Operation *definingOp = current.getDefiningOp()) {
+ // Check for `acc.var_name` attribute
+ if (auto varNameAttr =
+ definingOp->getAttrOfType<VarNameAttr>(getVarNameAttrName()))
+ return varNameAttr.getName().str();
+
+ // If it is a data entry operation, get name via getVarName
+ if (isa<ACC_DATA_ENTRY_OPS>(definingOp))
+ if (auto name = acc::getVarName(definingOp))
+ return name->str();
+
+ // If it's a view operation, continue to the source
+ if (auto viewOp = dyn_cast<ViewLikeOpInterface>(definingOp)) {
+ current = viewOp.getViewSource();
+ continue;
+ }
+
+ break;
+ }
+
+ return "";
+}
diff --git a/mlir/test/Dialect/OpenACC/support-analysis-varname.mlir b/mlir/test/Dialect/OpenACC/support-analysis-varname.mlir
new file mode 100644
index 0000000000000..af52befb156e4
--- /dev/null
+++ b/mlir/test/Dialect/OpenACC/support-analysis-varname.mlir
@@ -0,0 +1,88 @@
+// RUN: mlir-opt %s -split-input-file -test-acc-support | FileCheck %s
+
+// Test with direct variable names
+func.func @test_direct_var_name() {
+ // Create a memref with acc.var_name attribute
+ %0 = memref.alloca() {acc.var_name = #acc.var_name<"my_variable">} : memref<10xi32>
+
+ %1 = memref.cast %0 {test.var_name} : memref<10xi32> to memref<10xi32>
+
+ // CHECK: op=%{{.*}} = memref.cast %{{.*}} {test.var_name} : memref<10xi32> to memref<10xi32>
+ // CHECK-NEXT: getVariableName="my_variable"
+
+ return
+}
+
+// -----
+
+// Test through memref.cast
+func.func @test_through_cast() {
+ // Create a 5x2 memref with acc.var_name attribute
+ %0 = memref.alloca() {acc.var_name = #acc.var_name<"casted_variable">} : memref<5x2xi32>
+
+ // Cast to dynamic dimensions
+ %1 = memref.cast %0 : memref<5x2xi32> to memref<?x?xi32>
+
+ // Mark with test attribute - should find name through cast
+ %2 = memref.cast %1 {test.var_name} : memref<?x?xi32> to memref<5x2xi32>
+
+ // CHECK: op=%{{.*}} = memref.cast %{{.*}} {test.var_name} : memref<?x?xi32> to memref<5x2xi32>
+ // CHECK-NEXT: getVariableName="casted_variable"
+
+ return
+}
+
+// -----
+
+// Test with no variable name
+func.func @test_no_var_name() {
+ // Create a memref without acc.var_name attribute
+ %0 = memref.alloca() : memref<10xi32>
+
+ // Mark with test attribute - should find empty string
+ %1 = memref.cast %0 {test.var_name} : memref<10xi32> to memref<10xi32>
+
+ // CHECK: op=%{{.*}} = memref.cast %{{.*}} {test.var_name} : memref<10xi32> to memref<10xi32>
+ // CHECK-NEXT: getVariableName=""
+
+ return
+}
+
+// -----
+
+// Test through multiple casts
+func.func @test_multiple_casts() {
+ // Create a memref with acc.var_name attribute
+ %0 = memref.alloca() {acc.var_name = #acc.var_name<"multi_cast">} : memref<10xi32>
+
+ // Multiple casts
+ %1 = memref.cast %0 : memref<10xi32> to memref<?xi32>
+ %2 = memref.cast %1 : memref<?xi32> to memref<10xi32>
+
+ // Mark with test attribute - should find name through multiple casts
+ %3 = memref.cast %2 {test.var_name} : memref<10xi32> to memref<10xi32>
+
+ // CHECK: op=%{{.*}} = memref.cast %{{.*}} {test.var_name} : memref<10xi32> to memref<10xi32>
+ // CHECK-NEXT: getVariableName="multi_cast"
+
+ return
+}
+
+// -----
+
+// Test with acc.copyin operation
+func.func @test_copyin_name() {
+ // Create a memref
+ %0 = memref.alloca() : memref<10xf32>
+
+ // Create an acc.copyin operation with a name
+ %1 = acc.copyin varPtr(%0 : memref<10xf32>) -> memref<10xf32> {name = "input_data"}
+
+ // Mark with test attribute - should find name from copyin operation
+ %2 = memref.cast %1 {test.var_name} : memref<10xf32> to memref<?xf32>
+
+ // CHECK: op=%{{.*}} = memref.cast %{{.*}} {test.var_name} : memref<10xf32> to memref<?xf32>
+ // CHECK-NEXT: getVariableName="input_data"
+
+ return
+}
diff --git a/mlir/test/lib/Dialect/OpenACC/CMakeLists.txt b/mlir/test/lib/Dialect/OpenACC/CMakeLists.txt
index 1e593389ec683..a54b642d4db42 100644
--- a/mlir/test/lib/Dialect/OpenACC/CMakeLists.txt
+++ b/mlir/test/lib/Dialect/OpenACC/CMakeLists.txt
@@ -2,6 +2,7 @@ add_mlir_library(MLIROpenACCTestPasses
TestOpenACC.cpp
TestPointerLikeTypeInterface.cpp
TestRecipePopulate.cpp
+ TestOpenACCSupport.cpp
EXCLUDE_FROM_LIBMLIR
)
@@ -11,6 +12,7 @@ mlir_target_link_libraries(MLIROpenACCTestPasses PUBLIC
MLIRFuncDialect
MLIRMemRefDialect
MLIROpenACCDialect
+ MLIROpenACCAnalysis
MLIRPass
MLIRSupport
)
diff --git a/mlir/test/lib/Dialect/OpenACC/TestOpenACC.cpp b/mlir/test/lib/Dialect/OpenACC/TestOpenACC.cpp
index bea21b9827f7e..e59d77777ee40 100644
--- a/mlir/test/lib/Dialect/OpenACC/TestOpenACC.cpp
+++ b/mlir/test/lib/Dialect/OpenACC/TestOpenACC.cpp
@@ -16,11 +16,13 @@ namespace test {
// Forward declarations of individual test pass registration functions
void registerTestPointerLikeTypeInterfacePass();
void registerTestRecipePopulatePass();
+void registerTestOpenACCSupportPass();
// Unified registration function for all OpenACC tests
void registerTestOpenACC() {
registerTestPointerLikeTypeInterfacePass();
registerTestRecipePopulatePass();
+ registerTestOpenACCSupportPass();
}
} // namespace test
diff --git a/mlir/test/lib/Dialect/OpenACC/TestOpenACCSupport.cpp b/mlir/test/lib/Dialect/OpenACC/TestOpenACCSupport.cpp
new file mode 100644
index 0000000000000..8bf984bdc2632
--- /dev/null
+++ b/mlir/test/lib/Dialect/OpenACC/TestOpenACCSupport.cpp
@@ -0,0 +1,73 @@
+//===- TestOpenACCSupport.cpp - Test OpenACCSupport Analysis -------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains test passes for testing the OpenACCSupport analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/Pass/Pass.h"
+
+using namespace mlir;
+using namespace mlir::acc;
+
+namespace {
+
+struct TestOpenACCSupportPass
+ : public PassWrapper<TestOpenACCSupportPass, OperationPass<func::FuncOp>> {
+ MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestOpenACCSupportPass)
+
+ StringRef getArgument() const override { return "test-acc-support"; }
+
+ StringRef getDescription() const override {
+ return "Test OpenACCSupport analysis";
+ }
+
+ void runOnOperation() override;
+
+ void getDependentDialects(DialectRegistry ®istry) const override {
+ registry.insert<acc::OpenACCDialect>();
+ registry.insert<memref::MemRefDialect>();
+ }
+};
+
+void TestOpenACCSupportPass::runOnOperation() {
+ auto func = getOperation();
+
+ // Get the OpenACCSupport analysis
+ OpenACCSupport &support = getAnalysis<OpenACCSupport>();
+
+ // Walk through operations looking for test attributes
+ func.walk([&](Operation *op) {
+ // Check for test.var_name attribute. This is the marker used to identify
+ // the operations that need to be tested for getVariableName.
+ if (op->hasAttr("test.var_name")) {
+ // For each result of this operation, try to get the variable name
+ for (auto result : op->getResults()) {
+ std::string foundName = support.getVariableName(result);
+ llvm::outs() << "op=" << *op << "\n\tgetVariableName=\"" << foundName
+ << "\"\n";
+ }
+ }
+ });
+}
+
+} // namespace
+
+namespace mlir {
+namespace test {
+
+void registerTestOpenACCSupportPass() {
+ PassRegistration<TestOpenACCSupportPass>();
+}
+
+} // namespace test
+} // namespace mlir
diff --git a/mlir/unittests/Dialect/OpenACC/OpenACCUtilsTest.cpp b/mlir/unittests/Dialect/OpenACC/OpenACCUtilsTest.cpp
index ab817b640edb3..3fbbcc90a67c9 100644
--- a/mlir/unittests/Dialect/OpenACC/OpenACCUtilsTest.cpp
+++ b/mlir/unittests/Dialect/OpenACC/OpenACCUtilsTest.cpp
@@ -410,3 +410,78 @@ TEST_F(OpenACCUtilsTest, getTypeCategoryArray) {
VariableTypeCategory category = getTypeCategory(varPtr);
EXPECT_EQ(category, VariableTypeCategory::array);
}
+
+//===----------------------------------------------------------------------===//
+// getVariableName Tests
+//===----------------------------------------------------------------------===//
+
+TEST_F(OpenACCUtilsTest, getVariableNameDirect) {
+ // Create a memref with acc.var_name attribute
+ auto memrefTy = MemRefType::get({10}, b.getI32Type());
+ OwningOpRef<memref::AllocaOp> allocOp =
+ memref::AllocaOp::create(b, loc, memrefTy);
+
+ // Set the acc.var_name attribute
+ auto varNameAttr = VarNameAttr::get(&context, "my_variable");
+ allocOp.get()->setAttr(getVarNameAttrName(), varNameAttr);
+
+ Value varPtr = allocOp->getResult();
+
+ // Test that getVariableName returns the variable name
+ std::string varName = getVariableName(varPtr);
+ EXPECT_EQ(varName, "my_variable");
+}
+
+TEST_F(OpenACCUtilsTest, getVariableNameThroughCast) {
+ // Create a 5x2 memref with acc.var_name attribute
+ auto memrefTy = MemRefType::get({5, 2}, b.getI32Type());
+ OwningOpRef<memref::AllocaOp> allocOp =
+ memref::AllocaOp::create(b, loc, memrefTy);
+
+ // Set the acc.var_name attribute on the alloca
+ auto varNameAttr = VarNameAttr::get(&context, "casted_variable");
+ allocOp.get()->setAttr(getVarNameAttrName(), varNameAttr);
+
+ Value allocResult = allocOp->getResult();
+
+ // Create a memref.cast operation to a flattened 10-element array
+ auto castedMemrefTy = MemRefType::get({10}, b.getI32Type());
+ OwningOpRef<memref::CastOp> castOp =
+ memref::CastOp::create(b, loc, castedMemrefTy, allocResult);
+
+ Value castedPtr = castOp->getResult();
+
+ // Test that getVariableName walks through the cast to find the variable name
+ std::string varName = getVariableName(castedPtr);
+ EXPECT_EQ(varName, "casted_variable");
+}
+
+TEST_F(OpenACCUtilsTest, getVariableNameNotFound) {
+ // Create a memref without acc.var_name attribute
+ auto memrefTy = MemRefType::get({10}, b.getI32Type());
+ OwningOpRef<memref::AllocaOp> allocOp =
+ memref::AllocaOp::create(b, loc, memrefTy);
+
+ Value varPtr = allocOp->getResult();
+
+ // Test that getVariableName returns empty string when no name is found
+ std::string varName = getVariableName(varPtr);
+ EXPECT_EQ(varName, "");
+}
+
+TEST_F(OpenACCUtilsTest, getVariableNameFromCopyin) {
+ // Create a memref
+ auto memrefTy = MemRefType::get({10}, b.getI32Type());
+ OwningOpRef<memref::AllocaOp> allocOp =
+ memref::AllocaOp::create(b, loc, memrefTy);
+
+ Value varPtr = allocOp->getResult();
+ StringRef name = "data_array";
+ OwningOpRef<CopyinOp> copyinOp =
+ CopyinOp::create(b, loc, varPtr, /*structured=*/true, /*implicit=*/true,
+ /*name=*/name);
+
+ // Test that getVariableName extracts the name from the copyin operation
+ std::string varName = getVariableName(copyinOp->getAccVar());
+ EXPECT_EQ(varName, name);
+}
More information about the Mlir-commits
mailing list