[clang] [CIR] Add PointerLikeType interface support for cir::PointerType (PR #139768)
via cfe-commits
cfe-commits at lists.llvm.org
Tue May 13 10:11:47 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: Andy Kaylor (andykaylor)
<details>
<summary>Changes</summary>
This adds code to attach the OpenACC PointerLikeType interface to cir::PointerType, along with a unit test for the interface.
---
Full diff: https://github.com/llvm/llvm-project/pull/139768.diff
11 Files Affected:
- (added) clang/include/clang/CIR/Dialect/OpenACC/CIROpenACCTypeInterfaces.h (+36)
- (added) clang/include/clang/CIR/Dialect/OpenACC/RegisterOpenACCExtensions.h (+22)
- (modified) clang/lib/CIR/CodeGen/CIRGenerator.cpp (+7)
- (modified) clang/lib/CIR/CodeGen/CMakeLists.txt (+1)
- (modified) clang/lib/CIR/Dialect/CMakeLists.txt (+1)
- (added) clang/lib/CIR/Dialect/OpenACC/CIROpenACCTypeInterfaces.cpp (+41)
- (added) clang/lib/CIR/Dialect/OpenACC/CMakeLists.txt (+10)
- (added) clang/lib/CIR/Dialect/OpenACC/RegisterOpenACCExtensions.cpp (+27)
- (added) clang/unittests/CIR/CMakeLists.txt (+11)
- (added) clang/unittests/CIR/PointerLikeTest.cpp (+160)
- (modified) clang/unittests/CMakeLists.txt (+10-1)
``````````diff
diff --git a/clang/include/clang/CIR/Dialect/OpenACC/CIROpenACCTypeInterfaces.h b/clang/include/clang/CIR/Dialect/OpenACC/CIROpenACCTypeInterfaces.h
new file mode 100644
index 0000000000000..eccb6838a491f
--- /dev/null
+++ b/clang/include/clang/CIR/Dialect/OpenACC/CIROpenACCTypeInterfaces.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 external dialect interfaces for CIR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CIR_DIALECT_OPENACC_CIROPENACCTYPEINTERFACES_H
+#define CLANG_CIR_DIALECT_OPENACC_CIROPENACCTYPEINTERFACES_H
+
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "clang/CIR/Dialect/IR/CIRTypes.h"
+
+namespace cir::acc {
+
+template <typename T>
+struct OpenACCPointerLikeModel
+ : public mlir::acc::PointerLikeType::ExternalModel<
+ OpenACCPointerLikeModel<T>, T> {
+ mlir::Type getElementType(mlir::Type pointer) const {
+ return mlir::cast<T>(pointer).getPointee();
+ }
+ mlir::acc::VariableTypeCategory
+ getPointeeTypeCategory(mlir::Type pointer,
+ mlir::TypedValue<mlir::acc::PointerLikeType> varPtr,
+ mlir::Type varType) const;
+};
+
+} // namespace cir::acc
+
+#endif // CLANG_CIR_DIALECT_OPENACC_CIROPENACCTYPEINTERFACES_H
diff --git a/clang/include/clang/CIR/Dialect/OpenACC/RegisterOpenACCExtensions.h b/clang/include/clang/CIR/Dialect/OpenACC/RegisterOpenACCExtensions.h
new file mode 100644
index 0000000000000..13780a01ea1bb
--- /dev/null
+++ b/clang/include/clang/CIR/Dialect/OpenACC/RegisterOpenACCExtensions.h
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CIR_DIALECT_OPENACC_REGISTEROPENACCEXTENSIONS_H
+#define CLANG_CIR_DIALECT_OPENACC_REGISTEROPENACCEXTENSIONS_H
+
+namespace mlir {
+class DialectRegistry;
+} // namespace mlir
+
+namespace cir::acc {
+
+void registerOpenACCExtensions(mlir::DialectRegistry ®istry);
+
+} // namespace cir::acc
+
+#endif // CLANG_CIR_DIALECT_OPENACC_REGISTEROPENACCEXTENSIONS_H
diff --git a/clang/lib/CIR/CodeGen/CIRGenerator.cpp b/clang/lib/CIR/CodeGen/CIRGenerator.cpp
index aa3864deb733c..40252ffecfba1 100644
--- a/clang/lib/CIR/CodeGen/CIRGenerator.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenerator.cpp
@@ -18,6 +18,7 @@
#include "clang/AST/DeclGroup.h"
#include "clang/CIR/CIRGenerator.h"
#include "clang/CIR/Dialect/IR/CIRDialect.h"
+#include "clang/CIR/Dialect/OpenACC/RegisterOpenACCExtensions.h"
using namespace cir;
using namespace clang;
@@ -38,6 +39,12 @@ void CIRGenerator::Initialize(ASTContext &astContext) {
mlirContext = std::make_unique<mlir::MLIRContext>();
mlirContext->loadDialect<cir::CIRDialect>();
mlirContext->getOrLoadDialect<mlir::acc::OpenACCDialect>();
+
+ // Register extensions to integrate CIR types with OpenACC.
+ mlir::DialectRegistry registry;
+ cir::acc::registerOpenACCExtensions(registry);
+ mlirContext->appendDialectRegistry(registry);
+
cgm = std::make_unique<clang::CIRGen::CIRGenModule>(
*mlirContext.get(), astContext, codeGenOpts, diags);
}
diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt b/clang/lib/CIR/CodeGen/CMakeLists.txt
index 7a701c3c0b82b..8f5796e59d3bb 100644
--- a/clang/lib/CIR/CodeGen/CMakeLists.txt
+++ b/clang/lib/CIR/CodeGen/CMakeLists.txt
@@ -35,6 +35,7 @@ add_clang_library(clangCIR
clangBasic
clangLex
${dialect_libs}
+ CIROpenACCSupport
MLIRCIR
MLIRCIRInterfaces
)
diff --git a/clang/lib/CIR/Dialect/CMakeLists.txt b/clang/lib/CIR/Dialect/CMakeLists.txt
index 9f57627c321fb..c825a61b2779b 100644
--- a/clang/lib/CIR/Dialect/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/CMakeLists.txt
@@ -1,2 +1,3 @@
add_subdirectory(IR)
+add_subdirectory(OpenACC)
add_subdirectory(Transforms)
diff --git a/clang/lib/CIR/Dialect/OpenACC/CIROpenACCTypeInterfaces.cpp b/clang/lib/CIR/Dialect/OpenACC/CIROpenACCTypeInterfaces.cpp
new file mode 100644
index 0000000000000..ea563ecdfb3bb
--- /dev/null
+++ b/clang/lib/CIR/Dialect/OpenACC/CIROpenACCTypeInterfaces.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of external dialect interfaces for CIR.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CIR/Dialect/OpenACC/CIROpenACCTypeInterfaces.h"
+
+namespace cir::acc {
+
+template <>
+mlir::acc::VariableTypeCategory
+OpenACCPointerLikeModel<cir::PointerType>::getPointeeTypeCategory(
+ mlir::Type pointer, mlir::TypedValue<mlir::acc::PointerLikeType> varPtr,
+ mlir::Type varType) const {
+ mlir::Type eleTy = mlir::cast<cir::PointerType>(pointer).getPointee();
+
+ if (auto mappableTy = mlir::dyn_cast<mlir::acc::MappableType>(eleTy))
+ return mappableTy.getTypeCategory(varPtr);
+
+ if (isAnyIntegerOrFloatingPointType(eleTy) ||
+ mlir::isa<cir::BoolType>(eleTy) || mlir::isa<cir::PointerType>(eleTy))
+ return mlir::acc::VariableTypeCategory::scalar;
+ if (mlir::isa<cir::ArrayType>(eleTy))
+ return mlir::acc::VariableTypeCategory::array;
+ if (mlir::isa<cir::RecordType>(eleTy))
+ return mlir::acc::VariableTypeCategory::composite;
+ if (mlir::isa<cir::FuncType>(eleTy) || mlir::isa<cir::VectorType>(eleTy))
+ return mlir::acc::VariableTypeCategory::nonscalar;
+
+ // Without further checking, this type cannot be categorized.
+ return mlir::acc::VariableTypeCategory::uncategorized;
+}
+
+} // namespace cir::acc
diff --git a/clang/lib/CIR/Dialect/OpenACC/CMakeLists.txt b/clang/lib/CIR/Dialect/OpenACC/CMakeLists.txt
new file mode 100644
index 0000000000000..5b0a1620a1bff
--- /dev/null
+++ b/clang/lib/CIR/Dialect/OpenACC/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_clang_library(CIROpenACCSupport
+ CIROpenACCTypeInterfaces.cpp
+ RegisterOpenACCExtensions.cpp
+
+ DEPENDS
+ MLIRCIRTypeConstraintsIncGen
+
+ LINK_LIBS PUBLIC
+ MLIRIR
+ )
diff --git a/clang/lib/CIR/Dialect/OpenACC/RegisterOpenACCExtensions.cpp b/clang/lib/CIR/Dialect/OpenACC/RegisterOpenACCExtensions.cpp
new file mode 100644
index 0000000000000..3dfe7aeb6b1d6
--- /dev/null
+++ b/clang/lib/CIR/Dialect/OpenACC/RegisterOpenACCExtensions.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Registration for OpenACC extensions as applied to CIR dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CIR/Dialect/OpenACC/RegisterOpenACCExtensions.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+#include "clang/CIR/Dialect/IR/CIRTypes.h"
+#include "clang/CIR/Dialect/OpenACC/CIROpenACCTypeInterfaces.h"
+
+namespace cir::acc {
+
+void registerOpenACCExtensions(mlir::DialectRegistry ®istry) {
+ registry.addExtension(+[](mlir::MLIRContext *ctx, cir::CIRDialect *dialect) {
+ cir::PointerType::attachInterface<
+ OpenACCPointerLikeModel<cir::PointerType>>(*ctx);
+ });
+}
+
+} // namespace cir::acc
diff --git a/clang/unittests/CIR/CMakeLists.txt b/clang/unittests/CIR/CMakeLists.txt
new file mode 100644
index 0000000000000..171201b7beb23
--- /dev/null
+++ b/clang/unittests/CIR/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_clang_unittest(CIRUnitTests
+ PointerLikeTest.cpp
+ LLVM_COMPONENTS
+ Core
+
+ LINK_LIBS
+ MLIRCIR
+ CIROpenACCSupport
+ MLIRIR
+ MLIROpenACCDialect
+ )
diff --git a/clang/unittests/CIR/PointerLikeTest.cpp b/clang/unittests/CIR/PointerLikeTest.cpp
new file mode 100644
index 0000000000000..af8f32d237e71
--- /dev/null
+++ b/clang/unittests/CIR/PointerLikeTest.cpp
@@ -0,0 +1,160 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Unit tests for CIR implementation of OpenACC's PointertLikeType interface
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/Diagnostics.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/Value.h"
+#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+#include "clang/CIR/Dialect/IR/CIRTypes.h"
+#include "clang/CIR/Dialect/OpenACC/CIROpenACCTypeInterfaces.h"
+#include "clang/CIR/Dialect/OpenACC/RegisterOpenACCExtensions.h"
+#include "gtest/gtest.h"
+
+using namespace mlir;
+using namespace cir;
+
+//===----------------------------------------------------------------------===//
+// Test Fixture
+//===----------------------------------------------------------------------===//
+
+class CIROpenACCPointerLikeTest : public ::testing::Test {
+protected:
+ CIROpenACCPointerLikeTest() : b(&context), loc(UnknownLoc::get(&context)) {
+ context.loadDialect<cir::CIRDialect>();
+ context.loadDialect<mlir::acc::OpenACCDialect>();
+
+ // Register extension to integrate CIR types with OpenACC.
+ mlir::DialectRegistry registry;
+ cir::acc::registerOpenACCExtensions(registry);
+ context.appendDialectRegistry(registry);
+ }
+
+ MLIRContext context;
+ OpBuilder b;
+ Location loc;
+
+ mlir::IntegerAttr getSizeFromCharUnits(mlir::MLIRContext *ctx,
+ clang::CharUnits size) {
+ // Note that mlir::IntegerType is used instead of cir::IntType here
+ // because we don't need sign information for this to be useful, so keep
+ // it simple.
+ return mlir::IntegerAttr::get(mlir::IntegerType::get(ctx, 64),
+ size.getQuantity());
+ }
+
+ // General handler for types without a specific test
+ void testElementType(mlir::Type ty) {
+ mlir::Type ptrTy = cir::PointerType::get(ty);
+
+ // cir::PointerType should be castable to acc::PointerLikeType
+ auto pltTy = dyn_cast_if_present<mlir::acc::PointerLikeType>(ptrTy);
+ ASSERT_NE(pltTy, nullptr);
+
+ EXPECT_EQ(pltTy.getElementType(), ty);
+
+ OwningOpRef<cir::AllocaOp> varPtrOp = b.create<cir::AllocaOp>(
+ loc, ptrTy, ty, "",
+ getSizeFromCharUnits(&context, clang::CharUnits::One()));
+
+ mlir::Value val = varPtrOp.get();
+ mlir::acc::VariableTypeCategory typeCategory = pltTy.getPointeeTypeCategory(
+ cast<TypedValue<mlir::acc::PointerLikeType>>(val),
+ mlir::acc::getVarType(varPtrOp.get()));
+
+ if (isAnyIntegerOrFloatingPointType(ty) ||
+ mlir::isa<cir::PointerType>(ty) || mlir::isa<cir::BoolType>(ty)) {
+ EXPECT_EQ(typeCategory, mlir::acc::VariableTypeCategory::scalar);
+ } else if (mlir::isa<cir::ArrayType>(ty)) {
+ EXPECT_EQ(typeCategory, mlir::acc::VariableTypeCategory::array);
+ } else if (mlir::isa<cir::RecordType>(ty)) {
+ EXPECT_EQ(typeCategory, mlir::acc::VariableTypeCategory::composite);
+ } else if (mlir::isa<cir::FuncType, cir::VectorType>(ty)) {
+ EXPECT_EQ(typeCategory, mlir::acc::VariableTypeCategory::nonscalar);
+ } else if (mlir::isa<cir::VoidType>(ty)) {
+ EXPECT_EQ(typeCategory, mlir::acc::VariableTypeCategory::uncategorized);
+ } else {
+ EXPECT_EQ(typeCategory, mlir::acc::VariableTypeCategory::uncategorized);
+ // If we hit this, we need to add support for a new type.
+ ASSERT_TRUE(false);
+ }
+ }
+};
+
+TEST_F(CIROpenACCPointerLikeTest, testPointerToInt) {
+ // Test various scalar types.
+ testElementType(cir::IntType::get(&context, 8, true));
+ testElementType(cir::IntType::get(&context, 8, false));
+ testElementType(cir::IntType::get(&context, 16, true));
+ testElementType(cir::IntType::get(&context, 16, false));
+ testElementType(cir::IntType::get(&context, 32, true));
+ testElementType(cir::IntType::get(&context, 32, false));
+ testElementType(cir::IntType::get(&context, 64, true));
+ testElementType(cir::IntType::get(&context, 64, false));
+ testElementType(cir::IntType::get(&context, 128, true));
+ testElementType(cir::IntType::get(&context, 128, false));
+}
+
+TEST_F(CIROpenACCPointerLikeTest, testPointerToBool) {
+ testElementType(cir::BoolType::get(&context));
+}
+
+TEST_F(CIROpenACCPointerLikeTest, testPointerToFloat) {
+ testElementType(cir::SingleType::get(&context));
+ testElementType(cir::DoubleType::get(&context));
+}
+
+TEST_F(CIROpenACCPointerLikeTest, testPointerToPointer) {
+ mlir::Type i32Ty = cir::IntType::get(&context, 32, true);
+ mlir::Type ptrTy = cir::PointerType::get(i32Ty);
+ testElementType(ptrTy);
+}
+
+TEST_F(CIROpenACCPointerLikeTest, testPointerToArray) {
+ // Test an array type.
+ mlir::Type i32Ty = cir::IntType::get(&context, 32, true);
+ testElementType(cir::ArrayType::get(i32Ty, 10));
+}
+
+TEST_F(CIROpenACCPointerLikeTest, testPointerToStruct) {
+ // Test a struct type.
+ mlir::Type i32Ty = cir::IntType::get(&context, 32, true);
+ llvm::ArrayRef<mlir::Type> fields = {i32Ty, i32Ty};
+ cir::RecordType structTy = cir::RecordType::get(
+ &context, b.getStringAttr("S"), cir::RecordType::RecordKind::Struct);
+ structTy.complete(fields, false, false);
+ testElementType(structTy);
+
+ // Test a union type.
+ cir::RecordType unionTy = cir::RecordType::get(
+ &context, b.getStringAttr("U"), cir::RecordType::RecordKind::Union);
+ unionTy.complete(fields, false, false);
+ testElementType(unionTy);
+}
+
+TEST_F(CIROpenACCPointerLikeTest, testPointerToFunction) {
+ mlir::Type i32Ty = cir::IntType::get(&context, 32, true);
+ cir::FuncType::get(SmallVector<mlir::Type, 2>{i32Ty, i32Ty}, i32Ty);
+}
+
+TEST_F(CIROpenACCPointerLikeTest, testPointerToVector) {
+ mlir::Type i32Ty = cir::IntType::get(&context, 32, true);
+ mlir::Type vecTy = cir::VectorType::get(i32Ty, 4);
+ testElementType(vecTy);
+}
+
+TEST_F(CIROpenACCPointerLikeTest, testPointerToVoid) {
+ mlir::Type voidTy = cir::VoidType::get(&context);
+ testElementType(voidTy);
+}
diff --git a/clang/unittests/CMakeLists.txt b/clang/unittests/CMakeLists.txt
index b4114d419b75c..2a84607aa0937 100644
--- a/clang/unittests/CMakeLists.txt
+++ b/clang/unittests/CMakeLists.txt
@@ -105,7 +105,9 @@ add_subdirectory(Index)
add_subdirectory(InstallAPI)
add_subdirectory(Serialization)
add_subdirectory(Support)
-
+if (CLANG_ENABLE_CIR)
+ add_subdirectory(CIR)
+endif()
# If we're doing a single merged clang unit test binary, add that target after
# all the previous subdirectories have been processed.
@@ -127,3 +129,10 @@ add_distinct_clang_unittest(AllClangUnitTests
# the merged clang unit test binary, we can update the include paths and make
# this the default.
include_directories(Tooling)
+
+if (CLANG_ENABLE_CIR)
+ set(MLIR_INCLUDE_DIR ${LLVM_MAIN_SRC_DIR}/../mlir/include )
+ set(MLIR_TABLEGEN_OUTPUT_DIR ${CMAKE_BINARY_DIR}/tools/mlir/include)
+ include_directories(SYSTEM ${MLIR_INCLUDE_DIR})
+ include_directories(${MLIR_TABLEGEN_OUTPUT_DIR})
+endif()
``````````
</details>
https://github.com/llvm/llvm-project/pull/139768
More information about the cfe-commits
mailing list