[Mlir-commits] [mlir] 0a96b24 - [mlir][acc][flang] Introduce OpenACC interfaces for globals (#168614)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Nov 18 16:04:15 PST 2025


Author: Razvan Lupusoru
Date: 2025-11-18T16:04:11-08:00
New Revision: 0a96b240fcb715c082ab9b4cab6fddae02065602

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

LOG: [mlir][acc][flang] Introduce OpenACC interfaces for globals (#168614)

Introduce two new OpenACC operation interfaces for identifying global
variables and their address computations:

- `GlobalVariableOpInterface`: Identifies operations that define global
variables. Provides an `isConstant()` method to query whether the global
is constant.

- `AddressOfGlobalOpInterface`: Identifies operations that compute the
address of a global variable. Provides a `getSymbol()` method to
retrieve the symbol reference.

This is being done in preparation for `ACCImplicitDeclare` pass which
will automatically ensure that `acc declare` is applied to globals when
needed.

The following operations now implement these interfaces:
- `memref::GlobalOp` implements `GlobalVariableOpInterface`
- `memref::GetGlobalOp` implements `AddressOfGlobalOpInterface`
- `fir::GlobalOp` implements `GlobalVariableOpInterface`
- `fir::AddrOfOp` implements `AddressOfGlobalOpInterface`

Added: 
    mlir/unittests/Dialect/OpenACC/OpenACCOpsInterfacesTest.cpp

Modified: 
    flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h
    flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp
    flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp
    mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td
    mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
    mlir/unittests/Dialect/OpenACC/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h
index 7afe97aac57e8..bf87654979cc9 100644
--- a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h
+++ b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h
@@ -16,7 +16,9 @@
 #include "mlir/Dialect/OpenACC/OpenACC.h"
 
 namespace fir {
+class AddrOfOp;
 class DeclareOp;
+class GlobalOp;
 } // namespace fir
 
 namespace hlfir {
@@ -53,6 +55,18 @@ struct PartialEntityAccessModel<hlfir::DeclareOp>
   bool isCompleteView(mlir::Operation *op) const;
 };
 
+struct AddressOfGlobalModel
+    : public mlir::acc::AddressOfGlobalOpInterface::ExternalModel<
+          AddressOfGlobalModel, fir::AddrOfOp> {
+  mlir::SymbolRefAttr getSymbol(mlir::Operation *op) const;
+};
+
+struct GlobalVariableModel
+    : public mlir::acc::GlobalVariableOpInterface::ExternalModel<
+          GlobalVariableModel, fir::GlobalOp> {
+  bool isConstant(mlir::Operation *op) const;
+};
+
 } // namespace fir::acc
 
 #endif // FLANG_OPTIMIZER_OPENACC_FIROPENACC_OPS_INTERFACES_H_

diff  --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp
index c1734be5185f4..11fbaf2dc2bb8 100644
--- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp
+++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp
@@ -59,4 +59,13 @@ bool PartialEntityAccessModel<hlfir::DeclareOp>::isCompleteView(
   return !getBaseEntity(op);
 }
 
+mlir::SymbolRefAttr AddressOfGlobalModel::getSymbol(mlir::Operation *op) const {
+  return mlir::cast<fir::AddrOfOp>(op).getSymbolAttr();
+}
+
+bool GlobalVariableModel::isConstant(mlir::Operation *op) const {
+  auto globalOp = mlir::cast<fir::GlobalOp>(op);
+  return globalOp.getConstant().has_value();
+}
+
 } // namespace fir::acc

diff  --git a/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp b/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp
index d71c40dfac03c..5c7f9985d41ca 100644
--- a/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp
+++ b/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp
@@ -49,6 +49,9 @@ void registerOpenACCExtensions(mlir::DialectRegistry &registry) {
         PartialEntityAccessModel<fir::CoordinateOp>>(*ctx);
     fir::DeclareOp::attachInterface<PartialEntityAccessModel<fir::DeclareOp>>(
         *ctx);
+
+    fir::AddrOfOp::attachInterface<AddressOfGlobalModel>(*ctx);
+    fir::GlobalOp::attachInterface<GlobalVariableModel>(*ctx);
   });
 
   // Register HLFIR operation interfaces

diff  --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td
index 054c13a88a552..6b0c84d31d1ba 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td
@@ -44,4 +44,35 @@ def PartialEntityAccessOpInterface : OpInterface<"PartialEntityAccessOpInterface
   ];
 }
 
+def AddressOfGlobalOpInterface : OpInterface<"AddressOfGlobalOpInterface"> {
+  let cppNamespace = "::mlir::acc";
+
+  let description = [{
+    An interface for operations that compute the address of a global variable
+    or symbol.
+  }];
+
+  let methods = [
+    InterfaceMethod<"Get the symbol reference to the global", "::mlir::SymbolRefAttr",
+      "getSymbol", (ins)>,
+  ];
+}
+
+def GlobalVariableOpInterface : OpInterface<"GlobalVariableOpInterface"> {
+  let cppNamespace = "::mlir::acc";
+
+  let description = [{
+    An interface for operations that define global variables. This interface
+    provides a uniform way to query properties of global variables across
+    
diff erent dialects.
+  }];
+
+  let methods = [
+    InterfaceMethod<"Check if the global variable is constant", "bool",
+      "isConstant", (ins), [{
+        return false;
+      }]>,
+  ];
+}
+
 #endif // OPENACC_OPS_INTERFACES

diff  --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index 8c9c137b8aebb..5749e6ded73ba 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -211,6 +211,24 @@ struct LLVMPointerPointerLikeModel
   Type getElementType(Type pointer) const { return Type(); }
 };
 
+struct MemrefAddressOfGlobalModel
+    : public AddressOfGlobalOpInterface::ExternalModel<
+          MemrefAddressOfGlobalModel, memref::GetGlobalOp> {
+  SymbolRefAttr getSymbol(Operation *op) const {
+    auto getGlobalOp = cast<memref::GetGlobalOp>(op);
+    return getGlobalOp.getNameAttr();
+  }
+};
+
+struct MemrefGlobalVariableModel
+    : public GlobalVariableOpInterface::ExternalModel<MemrefGlobalVariableModel,
+                                                      memref::GlobalOp> {
+  bool isConstant(Operation *op) const {
+    auto globalOp = cast<memref::GlobalOp>(op);
+    return globalOp.getConstant();
+  }
+};
+
 /// Helper function for any of the times we need to modify an ArrayAttr based on
 /// a device type list.  Returns a new ArrayAttr with all of the
 /// existingDeviceTypes, plus the effective new ones(or an added none if hte new
@@ -302,6 +320,11 @@ void OpenACCDialect::initialize() {
       MemRefPointerLikeModel<UnrankedMemRefType>>(*getContext());
   LLVM::LLVMPointerType::attachInterface<LLVMPointerPointerLikeModel>(
       *getContext());
+
+  // Attach operation interfaces
+  memref::GetGlobalOp::attachInterface<MemrefAddressOfGlobalModel>(
+      *getContext());
+  memref::GlobalOp::attachInterface<MemrefGlobalVariableModel>(*getContext());
 }
 
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/unittests/Dialect/OpenACC/CMakeLists.txt b/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
index 177c8680b0040..c8c2bb96b0539 100644
--- a/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
+++ b/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
@@ -1,5 +1,6 @@
 add_mlir_unittest(MLIROpenACCTests
   OpenACCOpsTest.cpp
+  OpenACCOpsInterfacesTest.cpp
   OpenACCUtilsTest.cpp
 )
 mlir_target_link_libraries(MLIROpenACCTests

diff  --git a/mlir/unittests/Dialect/OpenACC/OpenACCOpsInterfacesTest.cpp b/mlir/unittests/Dialect/OpenACC/OpenACCOpsInterfacesTest.cpp
new file mode 100644
index 0000000000000..261f5c513ea24
--- /dev/null
+++ b/mlir/unittests/Dialect/OpenACC/OpenACCOpsInterfacesTest.cpp
@@ -0,0 +1,95 @@
+//===- OpenACCOpsInterfacesTest.cpp - Unit tests for OpenACC interfaces --===//
+//
+// 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 "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/OwningOpRef.h"
+#include "gtest/gtest.h"
+
+using namespace mlir;
+using namespace mlir::acc;
+
+//===----------------------------------------------------------------------===//
+// Test Fixture
+//===----------------------------------------------------------------------===//
+
+class OpenACCOpsInterfacesTest : public ::testing::Test {
+protected:
+  OpenACCOpsInterfacesTest()
+      : context(), builder(&context), loc(UnknownLoc::get(&context)) {
+    context.loadDialect<acc::OpenACCDialect, memref::MemRefDialect>();
+  }
+
+  MLIRContext context;
+  OpBuilder builder;
+  Location loc;
+};
+
+//===----------------------------------------------------------------------===//
+// GlobalVariableOpInterface Tests
+//===----------------------------------------------------------------------===//
+
+TEST_F(OpenACCOpsInterfacesTest, GlobalVariableOpInterfaceNonConstant) {
+  // Test that a non-constant global returns false for isConstant()
+
+  auto memrefType = MemRefType::get({10}, builder.getF32Type());
+  OwningOpRef<memref::GlobalOp> globalOp = memref::GlobalOp::create(
+      builder, loc,
+      /*sym_name=*/builder.getStringAttr("mutable_global"),
+      /*sym_visibility=*/builder.getStringAttr("private"),
+      /*type=*/TypeAttr::get(memrefType),
+      /*initial_value=*/Attribute(),
+      /*constant=*/UnitAttr(),
+      /*alignment=*/IntegerAttr());
+
+  auto globalVarIface =
+      dyn_cast<GlobalVariableOpInterface>(globalOp->getOperation());
+  ASSERT_TRUE(globalVarIface != nullptr);
+  EXPECT_FALSE(globalVarIface.isConstant());
+}
+
+TEST_F(OpenACCOpsInterfacesTest, GlobalVariableOpInterfaceConstant) {
+  // Test that a constant global returns true for isConstant()
+
+  auto memrefType = MemRefType::get({5}, builder.getI32Type());
+  OwningOpRef<memref::GlobalOp> constantGlobalOp = memref::GlobalOp::create(
+      builder, loc,
+      /*sym_name=*/builder.getStringAttr("constant_global"),
+      /*sym_visibility=*/builder.getStringAttr("public"),
+      /*type=*/TypeAttr::get(memrefType),
+      /*initial_value=*/Attribute(),
+      /*constant=*/builder.getUnitAttr(),
+      /*alignment=*/IntegerAttr());
+
+  auto globalVarIface =
+      dyn_cast<GlobalVariableOpInterface>(constantGlobalOp->getOperation());
+  ASSERT_TRUE(globalVarIface != nullptr);
+  EXPECT_TRUE(globalVarIface.isConstant());
+}
+
+//===----------------------------------------------------------------------===//
+// AddressOfGlobalOpInterface Tests
+//===----------------------------------------------------------------------===//
+
+TEST_F(OpenACCOpsInterfacesTest, AddressOfGlobalOpInterfaceGetSymbol) {
+  // Test that getSymbol() returns the correct symbol reference
+
+  auto memrefType = MemRefType::get({5}, builder.getI32Type());
+  const auto *symbolName = "test_global_symbol";
+
+  OwningOpRef<memref::GetGlobalOp> getGlobalOp = memref::GetGlobalOp::create(
+      builder, loc, memrefType, FlatSymbolRefAttr::get(&context, symbolName));
+
+  auto addrOfGlobalIface =
+      dyn_cast<AddressOfGlobalOpInterface>(getGlobalOp->getOperation());
+  ASSERT_TRUE(addrOfGlobalIface != nullptr);
+  EXPECT_EQ(addrOfGlobalIface.getSymbol().getLeafReference(), symbolName);
+}


        


More information about the Mlir-commits mailing list