diff --git a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h index 0020e1ab21a56..d7f8f87ccb8bf 100644 --- a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h +++ b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h @@ -65,6 +65,7 @@ struct GlobalVariableModel : public mlir::acc::GlobalVariableOpInterface::ExternalModel< GlobalVariableModel, fir::GlobalOp> { bool isConstant(mlir::Operation *op) const; + mlir::Region *getInitRegion(mlir::Operation *op) const; }; template diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp index 902a2ecdec35f..e4d02e93b041f 100644 --- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp +++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp @@ -71,6 +71,11 @@ bool GlobalVariableModel::isConstant(mlir::Operation *op) const { return globalOp.getConstant().has_value(); } +mlir::Region *GlobalVariableModel::getInitRegion(mlir::Operation *op) const { + auto globalOp = mlir::cast(op); + return globalOp.hasInitializationBody() ? &globalOp.getRegion() : nullptr; +} + // Helper to recursively process address-of operations in derived type // descriptors and collect all needed fir.globals. static void processAddrOfOpInDerivedTypeDescriptor( diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td index ec41826b2bbc8..d958006d58bad 100644 --- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td @@ -72,6 +72,8 @@ def GlobalVariableOpInterface : OpInterface<"GlobalVariableOpInterface"> { "isConstant", (ins), [{ return false; }]>, + InterfaceMethod<"Get the initialization region (returns nullptr if none)", + "::mlir::Region*", "getInitRegion", (ins)>, ]; } diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp index 9b9d2b9e18ca6..841d1d781f1a1 100644 --- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp +++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp @@ -227,6 +227,11 @@ struct MemrefGlobalVariableModel auto globalOp = cast(op); return globalOp.getConstant(); } + + Region *getInitRegion(Operation *op) const { + // GlobalOp uses attributes for initialization, not regions + return nullptr; + } }; /// Helper function for any of the times we need to modify an ArrayAttr based on diff --git a/mlir/unittests/Dialect/OpenACC/OpenACCOpsInterfacesTest.cpp b/mlir/unittests/Dialect/OpenACC/OpenACCOpsInterfacesTest.cpp index 261f5c513ea24..7d52ef31b21ed 100644 --- a/mlir/unittests/Dialect/OpenACC/OpenACCOpsInterfacesTest.cpp +++ b/mlir/unittests/Dialect/OpenACC/OpenACCOpsInterfacesTest.cpp @@ -75,6 +75,28 @@ TEST_F(OpenACCOpsInterfacesTest, GlobalVariableOpInterfaceConstant) { EXPECT_TRUE(globalVarIface.isConstant()); } +TEST_F(OpenACCOpsInterfacesTest, GlobalVariableOpInterfaceInitRegion) { + // Test that memref::GlobalOp returns nullptr for getInitRegion() + // since it uses attributes for initialization, not regions + + auto memrefType = MemRefType::get({10}, builder.getF32Type()); + OwningOpRef globalOp = memref::GlobalOp::create( + builder, loc, + /*sym_name=*/builder.getStringAttr("test_global"), + /*sym_visibility=*/builder.getStringAttr("private"), + /*type=*/TypeAttr::get(memrefType), + /*initial_value=*/Attribute(), + /*constant=*/UnitAttr(), + /*alignment=*/IntegerAttr()); + + auto globalVarIface = + dyn_cast(globalOp->getOperation()); + ASSERT_TRUE(globalVarIface != nullptr); + + // memref::GlobalOp doesn't have regions for initialization + EXPECT_EQ(globalVarIface.getInitRegion(), nullptr); +} + //===----------------------------------------------------------------------===// // AddressOfGlobalOpInterface Tests //===----------------------------------------------------------------------===//