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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits