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 &registry);
+
+} // 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 &registry) {
+  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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to